@linzumi/cli 0.0.52-beta → 0.0.53-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.
- package/README.md +7 -1
- package/dist/index.js +35 -114
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ Install the CLI or run it with `npx`:
|
|
|
62
62
|
```bash
|
|
63
63
|
npm install -g @linzumi/cli@latest
|
|
64
64
|
npx -y @linzumi/cli@latest signup
|
|
65
|
-
npx -y @linzumi/cli@0.0.
|
|
65
|
+
npx -y @linzumi/cli@0.0.53-beta --version
|
|
66
66
|
linzumi --version
|
|
67
67
|
```
|
|
68
68
|
|
|
@@ -79,6 +79,12 @@ For explicit runner roots, pass a comma-separated allowlist:
|
|
|
79
79
|
linzumi start ~/code/my-app --allowed-cwd <paths>
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
+
For non-production Linzumi servers, `connect` accepts either API URL flag:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
linzumi connect --linzumi-url ws://127.0.0.1:4140 --workspace default --allow-port-forwarding-by-default
|
|
86
|
+
```
|
|
87
|
+
|
|
82
88
|
## Agent-first launch path
|
|
83
89
|
|
|
84
90
|
The fastest path is the `npx -y @linzumi/cli@latest signup` command
|
package/dist/index.js
CHANGED
|
@@ -10456,7 +10456,7 @@ function realpathOrResolved(pathValue) {
|
|
|
10456
10456
|
}
|
|
10457
10457
|
|
|
10458
10458
|
// src/version.ts
|
|
10459
|
-
var linzumiCliVersion = "0.0.
|
|
10459
|
+
var linzumiCliVersion = "0.0.53-beta";
|
|
10460
10460
|
var linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
|
|
10461
10461
|
|
|
10462
10462
|
// src/runnerLock.ts
|
|
@@ -11240,13 +11240,7 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
11240
11240
|
const codex = await connectCodexAppServer(codexUrl);
|
|
11241
11241
|
cleanup.actions.push(() => codex.close());
|
|
11242
11242
|
const seq = { value: 0 };
|
|
11243
|
-
const
|
|
11244
|
-
log("kandan.codex_threads_startup_discovery_failed", {
|
|
11245
|
-
message: error instanceof Error ? error.message : String(error)
|
|
11246
|
-
});
|
|
11247
|
-
return [];
|
|
11248
|
-
}) : [];
|
|
11249
|
-
const discoveredCodexThreads = { value: codexThreads };
|
|
11243
|
+
const discoveredCodexThreads = { value: [] };
|
|
11250
11244
|
const runtimeDefaults = runnerRuntimeDefaults(options);
|
|
11251
11245
|
const instancePayload = {
|
|
11252
11246
|
instanceId,
|
|
@@ -11255,7 +11249,7 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
11255
11249
|
tuiLaunched: options.launchTui,
|
|
11256
11250
|
cwd: options.cwd,
|
|
11257
11251
|
hostname: runnerHost,
|
|
11258
|
-
codexThreads,
|
|
11252
|
+
codexThreads: discoveredCodexThreads.value,
|
|
11259
11253
|
workspace: runnerWorkspaceSlug(options) ?? null,
|
|
11260
11254
|
channel: options.channelSession?.channelSlug ?? null,
|
|
11261
11255
|
model: runtimeDefaults.model ?? null,
|
|
@@ -11399,19 +11393,11 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
11399
11393
|
message: error instanceof Error ? error.message : String(error)
|
|
11400
11394
|
});
|
|
11401
11395
|
});
|
|
11402
|
-
const refreshDiscoveredCodexThreads = () => discoverCodexThreads(codex, options.cwd).then((threads) => {
|
|
11403
|
-
discoveredCodexThreads.value = threads;
|
|
11404
|
-
return kandan.push(topic, "heartbeat", heartbeatPayload());
|
|
11405
|
-
}).catch((error) => {
|
|
11406
|
-
log("kandan.codex_threads_refresh_failed", {
|
|
11407
|
-
message: error instanceof Error ? error.message : String(error)
|
|
11408
|
-
});
|
|
11409
|
-
});
|
|
11410
11396
|
const heartbeatInterval = setInterval(() => {
|
|
11411
|
-
|
|
11397
|
+
pushHeartbeat();
|
|
11412
11398
|
}, 15000);
|
|
11413
11399
|
cleanup.actions.push(() => clearInterval(heartbeatInterval));
|
|
11414
|
-
kandan.onReconnect(() =>
|
|
11400
|
+
kandan.onReconnect(() => pushHeartbeat().then(() => {
|
|
11415
11401
|
return;
|
|
11416
11402
|
}));
|
|
11417
11403
|
pushHeartbeat();
|
|
@@ -11681,96 +11667,6 @@ async function closeCleanupStack(cleanup) {
|
|
|
11681
11667
|
})();
|
|
11682
11668
|
return cleanup.closePromise;
|
|
11683
11669
|
}
|
|
11684
|
-
async function discoverCodexThreads(codex, _cwd) {
|
|
11685
|
-
const rowsById = new Map;
|
|
11686
|
-
const archivedModes = [false, true];
|
|
11687
|
-
const sourcePasses = [
|
|
11688
|
-
undefined,
|
|
11689
|
-
[
|
|
11690
|
-
"exec",
|
|
11691
|
-
"appServer",
|
|
11692
|
-
"subAgent",
|
|
11693
|
-
"subAgentReview",
|
|
11694
|
-
"subAgentCompact",
|
|
11695
|
-
"subAgentThreadSpawn",
|
|
11696
|
-
"subAgentOther",
|
|
11697
|
-
"unknown"
|
|
11698
|
-
]
|
|
11699
|
-
];
|
|
11700
|
-
for (const archived of archivedModes) {
|
|
11701
|
-
for (const sourceKinds of sourcePasses) {
|
|
11702
|
-
let cursor;
|
|
11703
|
-
while (true) {
|
|
11704
|
-
const response = await codex.request("thread/list", {
|
|
11705
|
-
limit: 50,
|
|
11706
|
-
sortKey: "updated_at",
|
|
11707
|
-
sortDirection: "desc",
|
|
11708
|
-
archived,
|
|
11709
|
-
useStateDbOnly: true,
|
|
11710
|
-
...cursor === undefined ? {} : { cursor },
|
|
11711
|
-
...sourceKinds === undefined ? {} : { sourceKinds }
|
|
11712
|
-
});
|
|
11713
|
-
if ("error" in response) {
|
|
11714
|
-
throw new Error(`thread/list failed: ${response.error.message}`);
|
|
11715
|
-
}
|
|
11716
|
-
const result = objectValue(response.result);
|
|
11717
|
-
const data = arrayValue(result?.data)?.filter(isJsonObject) ?? [];
|
|
11718
|
-
for (const thread of data) {
|
|
11719
|
-
const row = codexThreadHistoryRow(thread, archived);
|
|
11720
|
-
const id = stringValue(objectValue(row)?.id);
|
|
11721
|
-
if (id !== undefined && id !== "" && !rowsById.has(id)) {
|
|
11722
|
-
rowsById.set(id, row);
|
|
11723
|
-
}
|
|
11724
|
-
}
|
|
11725
|
-
const nextCursor = stringValue(result?.nextCursor);
|
|
11726
|
-
if (nextCursor === undefined || nextCursor === "" || data.length === 0) {
|
|
11727
|
-
break;
|
|
11728
|
-
}
|
|
11729
|
-
cursor = nextCursor;
|
|
11730
|
-
}
|
|
11731
|
-
}
|
|
11732
|
-
}
|
|
11733
|
-
return Array.from(rowsById.values()).sort(compareCodexThreadHistoryRows);
|
|
11734
|
-
}
|
|
11735
|
-
function codexThreadHistoryRow(thread, archived) {
|
|
11736
|
-
const gitInfo = objectValue(thread.gitInfo);
|
|
11737
|
-
const preview = stringValue(thread.preview) ?? "";
|
|
11738
|
-
const name = stringValue(thread.name) ?? "";
|
|
11739
|
-
const title = stringValue(thread.title) ?? (name === "" ? preview : name);
|
|
11740
|
-
const description = stringValue(thread.description) ?? stringValue(thread.summary) ?? preview;
|
|
11741
|
-
return {
|
|
11742
|
-
id: stringValue(thread.id) ?? "",
|
|
11743
|
-
title: title ?? "",
|
|
11744
|
-
description: description ?? "",
|
|
11745
|
-
preview: preview.replace(/\s+/g, " ").trim(),
|
|
11746
|
-
cwd: stringValue(thread.cwd) ?? "",
|
|
11747
|
-
source: stringValue(thread.source) ?? "",
|
|
11748
|
-
createdAt: codexTimestamp(thread.createdAt),
|
|
11749
|
-
updatedAt: codexTimestamp(thread.updatedAt),
|
|
11750
|
-
archived,
|
|
11751
|
-
modelProvider: stringValue(thread.modelProvider) ?? "",
|
|
11752
|
-
cliVersion: stringValue(thread.cliVersion) ?? "",
|
|
11753
|
-
gitBranch: stringValue(gitInfo?.branch) ?? "",
|
|
11754
|
-
gitOriginUrl: stringValue(gitInfo?.originUrl) ?? "",
|
|
11755
|
-
path: stringValue(thread.path) ?? ""
|
|
11756
|
-
};
|
|
11757
|
-
}
|
|
11758
|
-
function codexTimestamp(value) {
|
|
11759
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
11760
|
-
return new Date(value * 1000).toISOString();
|
|
11761
|
-
}
|
|
11762
|
-
return stringValue(value) ?? "";
|
|
11763
|
-
}
|
|
11764
|
-
function compareCodexThreadHistoryRows(left, right) {
|
|
11765
|
-
const leftRow = objectValue(left);
|
|
11766
|
-
const rightRow = objectValue(right);
|
|
11767
|
-
const leftTime = Date.parse(stringValue(leftRow?.createdAt) ?? stringValue(leftRow?.updatedAt) ?? "");
|
|
11768
|
-
const rightTime = Date.parse(stringValue(rightRow?.createdAt) ?? stringValue(rightRow?.updatedAt) ?? "");
|
|
11769
|
-
return safeComparableTime(leftTime) - safeComparableTime(rightTime);
|
|
11770
|
-
}
|
|
11771
|
-
function safeComparableTime(value) {
|
|
11772
|
-
return Number.isFinite(value) ? value : Number.MAX_SAFE_INTEGER;
|
|
11773
|
-
}
|
|
11774
11670
|
function extractStartedThreadId(response) {
|
|
11775
11671
|
if ("error" in response) {
|
|
11776
11672
|
throw new Error(`thread/start failed: ${response.error.message}`);
|
|
@@ -18340,6 +18236,7 @@ async function waitForFileChangeOrTimeout(path, deadline, now, ready2 = () => fa
|
|
|
18340
18236
|
var flagDefinitions = new Map([
|
|
18341
18237
|
["version", { kind: "boolean" }],
|
|
18342
18238
|
["api-url", { kind: "value" }],
|
|
18239
|
+
["linzumi-url", { kind: "value" }],
|
|
18343
18240
|
["token", { kind: "value" }],
|
|
18344
18241
|
["runner-id", { kind: "value" }],
|
|
18345
18242
|
["cwd", { kind: "value" }],
|
|
@@ -18354,6 +18251,7 @@ var flagDefinitions = new Map([
|
|
|
18354
18251
|
["reasoning-effort", { kind: "value" }],
|
|
18355
18252
|
["sandbox", { kind: "value" }],
|
|
18356
18253
|
["approval-policy", { kind: "value" }],
|
|
18254
|
+
["allow-port-forwarding-by-default", { kind: "boolean" }],
|
|
18357
18255
|
["stream-flush-ms", { kind: "value" }],
|
|
18358
18256
|
["allowed-cwd", { kind: "value" }],
|
|
18359
18257
|
["forward-port", { kind: "value" }],
|
|
@@ -18733,7 +18631,7 @@ async function runAuthCommand(args) {
|
|
|
18733
18631
|
process.stdout.write(helpText());
|
|
18734
18632
|
return;
|
|
18735
18633
|
}
|
|
18736
|
-
const kandanUrl =
|
|
18634
|
+
const kandanUrl = requiredKandanUrl(values);
|
|
18737
18635
|
const target = parseOptionalChannelTarget(values);
|
|
18738
18636
|
const token = await acquireLocalRunnerTokenDetails({
|
|
18739
18637
|
kandanUrl,
|
|
@@ -18764,7 +18662,7 @@ async function parseStartRunnerArgs(args, deps = {
|
|
|
18764
18662
|
process.exit(0);
|
|
18765
18663
|
}
|
|
18766
18664
|
rejectStartTargetingFlags(values);
|
|
18767
|
-
const kandanUrl =
|
|
18665
|
+
const kandanUrl = kandanUrlValue(values) ?? defaultLinzumiWebSocketUrl;
|
|
18768
18666
|
const requestedCwd = resolveUserPath(cwdArg ?? process.cwd());
|
|
18769
18667
|
const cwd = assertConfiguredAllowedCwds([requestedCwd])[0] ?? requestedCwd;
|
|
18770
18668
|
const explicitAllowedCwds = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(parseAllowedCwdList(stringValue4(values, "allowed-cwd"))) : [];
|
|
@@ -18848,6 +18746,7 @@ async function parseStartRunnerArgs(args, deps = {
|
|
|
18848
18746
|
reasoningEffort: stringValue4(values, "reasoning-effort"),
|
|
18849
18747
|
sandbox: stringValue4(values, "sandbox"),
|
|
18850
18748
|
approvalPolicy: stringValue4(values, "approval-policy"),
|
|
18749
|
+
allowPortForwardingByDefault: booleanFlagValue(values, "allow-port-forwarding-by-default"),
|
|
18851
18750
|
streamFlushMs: positiveIntegerValue2(values, "stream-flush-ms")
|
|
18852
18751
|
}
|
|
18853
18752
|
};
|
|
@@ -18880,9 +18779,10 @@ async function parseAgentRunnerArgs(args, deps = {
|
|
|
18880
18779
|
reasoningEffort: stringValue4(values, "reasoning-effort"),
|
|
18881
18780
|
sandbox: stringValue4(values, "sandbox"),
|
|
18882
18781
|
approvalPolicy: stringValue4(values, "approval-policy"),
|
|
18782
|
+
allowPortForwardingByDefault: booleanFlagValue(values, "allow-port-forwarding-by-default"),
|
|
18883
18783
|
streamFlushMs: positiveIntegerValue2(values, "stream-flush-ms")
|
|
18884
18784
|
};
|
|
18885
|
-
const kandanUrl =
|
|
18785
|
+
const kandanUrl = kandanUrlValue(values) ?? agentApiUrlToKandanUrl(tokenFile.apiUrl);
|
|
18886
18786
|
const requestedCwdValue = cwdArg ?? stringValue4(values, "cwd");
|
|
18887
18787
|
const requestedCwd = resolveUserPath(requestedCwdValue ?? process.cwd());
|
|
18888
18788
|
const configuredAllowedCwds2 = requestedCwdValue === undefined && !values.has("allowed-cwd") ? readConfiguredAllowedCwdDetailsForLinzumiUrl(kandanUrl) : { allowedCwds: [], missingAllowedCwds: [] };
|
|
@@ -19014,7 +18914,7 @@ async function parseRunnerArgs(args, deps = {
|
|
|
19014
18914
|
}
|
|
19015
18915
|
rejectConnectChannelFlags(values);
|
|
19016
18916
|
const workspaceSlug = stringValue4(values, "workspace");
|
|
19017
|
-
const kandanUrl =
|
|
18917
|
+
const kandanUrl = kandanUrlValue(values) ?? defaultLinzumiWebSocketUrl;
|
|
19018
18918
|
const cwd = stringValue4(values, "cwd") ?? process.cwd();
|
|
19019
18919
|
const cwdAllowedCwds = assertConfiguredAllowedCwds([cwd]);
|
|
19020
18920
|
const localConfiguredAllowedCwds = values.has("allowed-cwd") ? { allowedCwds: [], missingAllowedCwds: [] } : readConfiguredAllowedCwdDetailsForLinzumiUrl(kandanUrl);
|
|
@@ -19073,9 +18973,27 @@ function runnerRuntimeDefaultsFromValues(values) {
|
|
|
19073
18973
|
reasoningEffort: stringValue4(values, "reasoning-effort"),
|
|
19074
18974
|
approvalPolicy: stringValue4(values, "approval-policy"),
|
|
19075
18975
|
sandbox: stringValue4(values, "sandbox"),
|
|
19076
|
-
allowPortForwardingByDefault:
|
|
18976
|
+
allowPortForwardingByDefault: booleanFlagValue(values, "allow-port-forwarding-by-default")
|
|
19077
18977
|
};
|
|
19078
18978
|
}
|
|
18979
|
+
function kandanUrlValue(values) {
|
|
18980
|
+
const apiUrl = stringValue4(values, "api-url");
|
|
18981
|
+
const linzumiUrl = stringValue4(values, "linzumi-url");
|
|
18982
|
+
if (apiUrl !== undefined && linzumiUrl !== undefined && apiUrl !== linzumiUrl) {
|
|
18983
|
+
throw new Error("use only one of --api-url or --linzumi-url");
|
|
18984
|
+
}
|
|
18985
|
+
return apiUrl ?? linzumiUrl;
|
|
18986
|
+
}
|
|
18987
|
+
function requiredKandanUrl(values) {
|
|
18988
|
+
const value = kandanUrlValue(values);
|
|
18989
|
+
if (value === undefined) {
|
|
18990
|
+
throw new Error("missing required flag: --api-url or --linzumi-url");
|
|
18991
|
+
}
|
|
18992
|
+
return value;
|
|
18993
|
+
}
|
|
18994
|
+
function booleanFlagValue(values, key) {
|
|
18995
|
+
return values.get(key) === true ? true : undefined;
|
|
18996
|
+
}
|
|
19079
18997
|
function strictFlagValues(args, definitions = flagDefinitions) {
|
|
19080
18998
|
const values = new Map;
|
|
19081
18999
|
for (let index = 0;index < args.length; index += 1) {
|
|
@@ -19282,6 +19200,7 @@ Usage:
|
|
|
19282
19200
|
|
|
19283
19201
|
Connection:
|
|
19284
19202
|
--api-url <url> Linzumi API URL, default ${defaultLinzumiWebSocketUrl}
|
|
19203
|
+
--linzumi-url <url> Alias for --api-url
|
|
19285
19204
|
--token <jwt> Optional override token. Otherwise ~/.linzumi/auth.json is validated or OAuth opens.
|
|
19286
19205
|
--auth-file <path> Auth cache path, default ~/.linzumi/auth.json
|
|
19287
19206
|
--oauth-callback-host <ip> Callback host reachable by your browser
|
|
@@ -19298,6 +19217,8 @@ Codex:
|
|
|
19298
19217
|
--reasoning-effort <value> Reasoning effort requested for Codex and shown in Linzumi
|
|
19299
19218
|
--sandbox <value> Sandbox metadata shown in Linzumi
|
|
19300
19219
|
--approval-policy <value> Approval-policy metadata shown in Linzumi
|
|
19220
|
+
--allow-port-forwarding-by-default
|
|
19221
|
+
Auto-approve detected port-forward candidates for started sessions
|
|
19301
19222
|
--stream-flush-ms <ms> Batch live Codex deltas before Linzumi persistence, default 150
|
|
19302
19223
|
--fast Mark this runner as low-latency/fast in the availability message
|
|
19303
19224
|
--log-file <path> JSONL event log path, default <cwd>/.linzumi-runner.log
|
package/package.json
CHANGED