@linzumi/cli 0.0.94-beta → 0.0.95-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 +1 -1
- package/dist/index.js +143 -30
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -112,6 +112,14 @@ import { spawnSync } from "node:child_process";
|
|
|
112
112
|
import { homedir } from "node:os";
|
|
113
113
|
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
114
114
|
import { basename, dirname, join } from "node:path";
|
|
115
|
+
function projectScanBudgetMs() {
|
|
116
|
+
const raw = process.env.LINZUMI_ONBOARDING_PROJECT_SCAN_BUDGET_MS?.trim();
|
|
117
|
+
if (raw === void 0 || raw === "") {
|
|
118
|
+
return defaultProjectScanBudgetMs;
|
|
119
|
+
}
|
|
120
|
+
const parsed = Number.parseInt(raw, 10);
|
|
121
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultProjectScanBudgetMs;
|
|
122
|
+
}
|
|
115
123
|
function discoverCurrentGitProject(args) {
|
|
116
124
|
const startedAtMs = args.nowMs ?? Date.now();
|
|
117
125
|
const responsiveness = args.placeResponsiveness;
|
|
@@ -136,7 +144,19 @@ function discoverCurrentGitProject(args) {
|
|
|
136
144
|
});
|
|
137
145
|
const sourceRoots = args.sourceRoots ?? defaultLocalProjectSourceRoots(args.cwd);
|
|
138
146
|
let placesSearched = 1;
|
|
147
|
+
const scanBudgetMs = projectScanBudgetMs();
|
|
139
148
|
for (const sourceRoot of sourceRoots) {
|
|
149
|
+
if (Date.now() - startedAtMs >= scanBudgetMs) {
|
|
150
|
+
searchStats.push({
|
|
151
|
+
place: sourceRoot,
|
|
152
|
+
source: "git",
|
|
153
|
+
duration_ms: 0,
|
|
154
|
+
result_count: 0,
|
|
155
|
+
skipped_scan_budget_exceeded: true
|
|
156
|
+
});
|
|
157
|
+
placesSearched += 1;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
140
160
|
const sourceRootStartedAtMs = Date.now();
|
|
141
161
|
const rootResponsive = isPlaceResponsive(sourceRoot, responsiveness);
|
|
142
162
|
if (!rootResponsive) {
|
|
@@ -296,6 +316,9 @@ function isGitWorktreeRoot(path2) {
|
|
|
296
316
|
return existsSync(join(path2, ".git"));
|
|
297
317
|
}
|
|
298
318
|
function defaultLocalProjectSourceRoots(cwd) {
|
|
319
|
+
if (cwd === dirname(cwd)) {
|
|
320
|
+
return [];
|
|
321
|
+
}
|
|
299
322
|
return uniqueStrings([
|
|
300
323
|
...ancestorSourceRoots(cwd),
|
|
301
324
|
...homeSourceRoots(),
|
|
@@ -409,13 +432,14 @@ function compactJsonObject(value) {
|
|
|
409
432
|
})
|
|
410
433
|
);
|
|
411
434
|
}
|
|
412
|
-
var worktreePathSampleLimit, gitSpawnTimeoutMs;
|
|
435
|
+
var worktreePathSampleLimit, gitSpawnTimeoutMs, defaultProjectScanBudgetMs;
|
|
413
436
|
var init_onboardingProjectDiscovery = __esm({
|
|
414
437
|
"src/onboardingProjectDiscovery.ts"() {
|
|
415
438
|
"use strict";
|
|
416
439
|
init_onboardingPlaceResponsiveness();
|
|
417
440
|
worktreePathSampleLimit = 25;
|
|
418
441
|
gitSpawnTimeoutMs = 4e3;
|
|
442
|
+
defaultProjectScanBudgetMs = 2e4;
|
|
419
443
|
}
|
|
420
444
|
});
|
|
421
445
|
|
|
@@ -8437,6 +8461,38 @@ var init_userFacingErrors = __esm({
|
|
|
8437
8461
|
|
|
8438
8462
|
// src/channelSession.ts
|
|
8439
8463
|
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
8464
|
+
function codexStartRequestTimeoutMs() {
|
|
8465
|
+
const raw = process.env.LINZUMI_CODEX_START_REQUEST_TIMEOUT_MS?.trim();
|
|
8466
|
+
if (raw === void 0 || raw === "") {
|
|
8467
|
+
return CODEX_START_REQUEST_TIMEOUT_MS;
|
|
8468
|
+
}
|
|
8469
|
+
const parsed = Number.parseInt(raw, 10);
|
|
8470
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : CODEX_START_REQUEST_TIMEOUT_MS;
|
|
8471
|
+
}
|
|
8472
|
+
function isCodexStartRequestTimeoutError(error) {
|
|
8473
|
+
return error instanceof CodexStartRequestTimeoutError;
|
|
8474
|
+
}
|
|
8475
|
+
function withCodexStartRequestTimeout(method, request, timeoutMs = codexStartRequestTimeoutMs()) {
|
|
8476
|
+
if (!(timeoutMs > 0)) {
|
|
8477
|
+
return request;
|
|
8478
|
+
}
|
|
8479
|
+
return new Promise((resolve12, reject) => {
|
|
8480
|
+
const timer = setTimeout(() => {
|
|
8481
|
+
reject(new CodexStartRequestTimeoutError(method, timeoutMs));
|
|
8482
|
+
}, timeoutMs);
|
|
8483
|
+
timer.unref?.();
|
|
8484
|
+
request.then(
|
|
8485
|
+
(value) => {
|
|
8486
|
+
clearTimeout(timer);
|
|
8487
|
+
resolve12(value);
|
|
8488
|
+
},
|
|
8489
|
+
(error) => {
|
|
8490
|
+
clearTimeout(timer);
|
|
8491
|
+
reject(error);
|
|
8492
|
+
}
|
|
8493
|
+
);
|
|
8494
|
+
});
|
|
8495
|
+
}
|
|
8440
8496
|
async function attachChannelSession(args) {
|
|
8441
8497
|
const session = args.options.channelSession;
|
|
8442
8498
|
const chatTopic = `chat:${session.workspaceSlug}:${session.channelSlug}`;
|
|
@@ -8941,6 +8997,7 @@ function initialChannelSessionState(cursor, rootSeq, kandanThreadId, codexThread
|
|
|
8941
8997
|
failedSeqs: /* @__PURE__ */ new Map(),
|
|
8942
8998
|
drainInFlight: false,
|
|
8943
8999
|
drainRequested: false,
|
|
9000
|
+
boundStartTimeout: false,
|
|
8944
9001
|
fusedQueuedSeqs: /* @__PURE__ */ new Map(),
|
|
8945
9002
|
reconnectRetryTimer: void 0,
|
|
8946
9003
|
reconnectRetryAttempts: 0,
|
|
@@ -10295,6 +10352,9 @@ async function startThreadMessageTurn(args, state, payloadContext, message) {
|
|
|
10295
10352
|
if (state.kandanThreadId === void 0 || state.codexThreadId === void 0) {
|
|
10296
10353
|
throw new Error("cannot start a local Codex turn before thread binding");
|
|
10297
10354
|
}
|
|
10355
|
+
if (message.boundStartTimeout === true) {
|
|
10356
|
+
state.boundStartTimeout = true;
|
|
10357
|
+
}
|
|
10298
10358
|
const queued = {
|
|
10299
10359
|
seq: message.seq,
|
|
10300
10360
|
actorSlug: message.actorSlug,
|
|
@@ -10558,7 +10618,9 @@ async function drainKandanMessageQueueOnce(args, state, payloadContext) {
|
|
|
10558
10618
|
if (state.kandanThreadId !== void 0) {
|
|
10559
10619
|
startCodexTypingHeartbeat(args, state, state.kandanThreadId);
|
|
10560
10620
|
}
|
|
10561
|
-
const
|
|
10621
|
+
const boundStartTimeout = state.boundStartTimeout;
|
|
10622
|
+
state.boundStartTimeout = false;
|
|
10623
|
+
const turnStartRequest = args.codex.request("turn/start", {
|
|
10562
10624
|
threadId: codexThreadId,
|
|
10563
10625
|
input: await codexInputItemsForQueuedKandanMessage(
|
|
10564
10626
|
args,
|
|
@@ -10569,6 +10631,7 @@ async function drainKandanMessageQueueOnce(args, state, payloadContext) {
|
|
|
10569
10631
|
runtimeOptionsForSettings(args.options, state.runtimeSettings)
|
|
10570
10632
|
)
|
|
10571
10633
|
});
|
|
10634
|
+
const started = boundStartTimeout ? await withCodexStartRequestTimeout("turn/start", turnStartRequest) : await turnStartRequest;
|
|
10572
10635
|
const turnId = extractTurnIdFromResponse(started);
|
|
10573
10636
|
state.pendingReconnectContextInjection = void 0;
|
|
10574
10637
|
const interruptAfterStart = state.turn.status === "starting" && state.turn.interruptAfterStart;
|
|
@@ -10641,6 +10704,9 @@ async function drainKandanMessageQueueOnce(args, state, payloadContext) {
|
|
|
10641
10704
|
queued_seq: next.seq,
|
|
10642
10705
|
message: error instanceof Error ? error.message : String(error)
|
|
10643
10706
|
});
|
|
10707
|
+
if (isCodexStartRequestTimeoutError(error)) {
|
|
10708
|
+
throw error;
|
|
10709
|
+
}
|
|
10644
10710
|
}
|
|
10645
10711
|
}
|
|
10646
10712
|
function drainKandanMessageQueueBlocked(args, state) {
|
|
@@ -11654,7 +11720,7 @@ async function pushOptional(kandan, topic, event, payload, log2) {
|
|
|
11654
11720
|
});
|
|
11655
11721
|
}
|
|
11656
11722
|
}
|
|
11657
|
-
var codexTypingHeartbeatMs, maxTrackedFailedChatEventSeqs, maxChatEventFailureAttempts, maxForwardedTurnIds, maxClaimedKandanMessageKeys, claimedKandanMessageKeys, nextChatJoinRegistrationSerial, defaultReconnectHandlingRetryDelaysMs, defaultTuiInputMirrorRetryDelaysMs, pipelineCloseTimeoutMs;
|
|
11723
|
+
var codexTypingHeartbeatMs, CODEX_START_REQUEST_TIMEOUT_MS, CodexStartRequestTimeoutError, maxTrackedFailedChatEventSeqs, maxChatEventFailureAttempts, maxForwardedTurnIds, maxClaimedKandanMessageKeys, claimedKandanMessageKeys, nextChatJoinRegistrationSerial, defaultReconnectHandlingRetryDelaysMs, defaultTuiInputMirrorRetryDelaysMs, pipelineCloseTimeoutMs;
|
|
11658
11724
|
var init_channelSession = __esm({
|
|
11659
11725
|
"src/channelSession.ts"() {
|
|
11660
11726
|
"use strict";
|
|
@@ -11679,6 +11745,15 @@ var init_channelSession = __esm({
|
|
|
11679
11745
|
init_processNameCatalog();
|
|
11680
11746
|
init_userFacingErrors();
|
|
11681
11747
|
codexTypingHeartbeatMs = 5e3;
|
|
11748
|
+
CODEX_START_REQUEST_TIMEOUT_MS = 12e4;
|
|
11749
|
+
CodexStartRequestTimeoutError = class extends Error {
|
|
11750
|
+
constructor(method, timeoutMs) {
|
|
11751
|
+
super(
|
|
11752
|
+
`Codex ${method} did not reply within ${timeoutMs}ms (start request timed out)`
|
|
11753
|
+
);
|
|
11754
|
+
this.name = "CodexStartRequestTimeoutError";
|
|
11755
|
+
}
|
|
11756
|
+
};
|
|
11682
11757
|
maxTrackedFailedChatEventSeqs = 256;
|
|
11683
11758
|
maxChatEventFailureAttempts = 5;
|
|
11684
11759
|
maxForwardedTurnIds = 64;
|
|
@@ -19376,7 +19451,7 @@ var linzumiCliVersion, linzumiCliVersionText;
|
|
|
19376
19451
|
var init_version = __esm({
|
|
19377
19452
|
"src/version.ts"() {
|
|
19378
19453
|
"use strict";
|
|
19379
|
-
linzumiCliVersion = "0.0.
|
|
19454
|
+
linzumiCliVersion = "0.0.95-beta";
|
|
19380
19455
|
linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
|
|
19381
19456
|
}
|
|
19382
19457
|
});
|
|
@@ -23035,6 +23110,34 @@ async function runThreadCodexWorker(options) {
|
|
|
23035
23110
|
async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
23036
23111
|
const agentProviders = availableRunnerAgentProviders(options);
|
|
23037
23112
|
const localCodexAppServerAvailable = hasLocalCodexAppServerCapability(options);
|
|
23113
|
+
const dependencyStatusRef = {
|
|
23114
|
+
value: options.dependencyStatus
|
|
23115
|
+
};
|
|
23116
|
+
const refreshDependencyStatus = async () => {
|
|
23117
|
+
if (dependencyStatusRef.value === void 0) {
|
|
23118
|
+
return;
|
|
23119
|
+
}
|
|
23120
|
+
try {
|
|
23121
|
+
const refreshed = await buildRunnerDependencyStatus({
|
|
23122
|
+
cwd: options.cwd,
|
|
23123
|
+
codexBin: options.codexBin,
|
|
23124
|
+
codeServerBin: options.codeServerBin,
|
|
23125
|
+
editorRuntime: dependencyStatusRef.value?.editorRuntime
|
|
23126
|
+
});
|
|
23127
|
+
const previousCodexAvailable = dependencyStatusRef.value?.codex.available;
|
|
23128
|
+
dependencyStatusRef.value = refreshed;
|
|
23129
|
+
log2("runner.dependency_status_reprobed", {
|
|
23130
|
+
runnerId: options.runnerId,
|
|
23131
|
+
codex_available: refreshed.codex.available,
|
|
23132
|
+
codex_available_changed: previousCodexAvailable !== refreshed.codex.available
|
|
23133
|
+
});
|
|
23134
|
+
} catch (error) {
|
|
23135
|
+
log2("runner.dependency_status_reprobe_failed", {
|
|
23136
|
+
runnerId: options.runnerId,
|
|
23137
|
+
message: error instanceof Error ? error.message : String(error)
|
|
23138
|
+
});
|
|
23139
|
+
}
|
|
23140
|
+
};
|
|
23038
23141
|
const allowedForwardPorts = options.allowedForwardPorts ?? [];
|
|
23039
23142
|
const liveForwardPorts = new Set(allowedForwardPorts);
|
|
23040
23143
|
const managedForwardPorts = /* @__PURE__ */ new Set();
|
|
@@ -23207,8 +23310,8 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
23207
23310
|
),
|
|
23208
23311
|
forwardedPortAttributions: buildForwardPortAttributionPayload(),
|
|
23209
23312
|
pendingEditorForwardPortRequests: pendingEditorForwardPortRequests(),
|
|
23210
|
-
toolStatus:
|
|
23211
|
-
editorRuntime:
|
|
23313
|
+
toolStatus: dependencyStatusRef.value === void 0 ? null : dependencyStatusPayload(dependencyStatusRef.value),
|
|
23314
|
+
editorRuntime: dependencyStatusRef.value?.editorRuntime === void 0 ? null : dependencyStatusPayload(dependencyStatusRef.value).editorRuntime,
|
|
23212
23315
|
...localEditorCapabilities(
|
|
23213
23316
|
options.editorRuntime,
|
|
23214
23317
|
allowedCwds.value,
|
|
@@ -25071,14 +25174,15 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
25071
25174
|
log2,
|
|
25072
25175
|
pendingControls,
|
|
25073
25176
|
controlDispatcher,
|
|
25074
|
-
dispatchControl
|
|
25177
|
+
dispatchControl,
|
|
25178
|
+
refreshDependencyStatus
|
|
25075
25179
|
);
|
|
25076
25180
|
return { instanceId, codexUrl, close };
|
|
25077
25181
|
}
|
|
25078
|
-
function finishRunnerStartup(options, log2, pendingControls, controlDispatcher, dispatchControl) {
|
|
25182
|
+
function finishRunnerStartup(options, log2, pendingControls, controlDispatcher, dispatchControl, onOnboardingDiscoveryComplete) {
|
|
25079
25183
|
controlDispatcher.value = dispatchControl;
|
|
25080
25184
|
pendingControls.splice(0).forEach(({ control, ack }) => dispatchControl(control, ack));
|
|
25081
|
-
startOnboardingDiscoveryAgents(options, log2);
|
|
25185
|
+
startOnboardingDiscoveryAgents(options, log2, onOnboardingDiscoveryComplete);
|
|
25082
25186
|
}
|
|
25083
25187
|
function commanderOutboxPersistDir() {
|
|
25084
25188
|
const override = process.env.LINZUMI_COMMANDER_OUTBOX_DIR?.trim();
|
|
@@ -27175,22 +27279,25 @@ async function startCodexProviderInstance(args) {
|
|
|
27175
27279
|
args.options,
|
|
27176
27280
|
args.control
|
|
27177
27281
|
);
|
|
27178
|
-
const response = await
|
|
27179
|
-
|
|
27180
|
-
|
|
27181
|
-
personality: "pragmatic",
|
|
27182
|
-
developerInstructions: commanderDeveloperInstructions({
|
|
27282
|
+
const response = await withCodexStartRequestTimeout(
|
|
27283
|
+
"thread/start",
|
|
27284
|
+
args.codex.request("thread/start", {
|
|
27183
27285
|
cwd: args.cwd,
|
|
27184
|
-
|
|
27185
|
-
|
|
27186
|
-
|
|
27187
|
-
|
|
27188
|
-
|
|
27189
|
-
|
|
27190
|
-
|
|
27191
|
-
|
|
27192
|
-
|
|
27193
|
-
|
|
27286
|
+
serviceName: "kandan-local-runner",
|
|
27287
|
+
personality: "pragmatic",
|
|
27288
|
+
developerInstructions: commanderDeveloperInstructions({
|
|
27289
|
+
cwd: args.cwd,
|
|
27290
|
+
planTool: "linzumi-mcp",
|
|
27291
|
+
developerPrompt,
|
|
27292
|
+
linzumiContext
|
|
27293
|
+
}),
|
|
27294
|
+
...runtimeSettings.model === void 0 ? {} : { model: runtimeSettings.model },
|
|
27295
|
+
...runtimeSettings.reasoningEffort === void 0 ? {} : { reasoningEffort: runtimeSettings.reasoningEffort },
|
|
27296
|
+
...runtimeSettings.approvalPolicy === void 0 ? {} : { approvalPolicy: runtimeSettings.approvalPolicy },
|
|
27297
|
+
...runtimeSettings.sandbox === void 0 ? {} : { sandbox: runtimeSettings.sandbox },
|
|
27298
|
+
...runtimeSettings.fast === true ? { serviceTier: "fast" } : {}
|
|
27299
|
+
})
|
|
27300
|
+
);
|
|
27194
27301
|
const codexThreadId = extractStartedThreadId(response);
|
|
27195
27302
|
args.setStartedCodexThreadId(codexThreadId);
|
|
27196
27303
|
const workDescription = normalizedWorkDescription(
|
|
@@ -27224,13 +27331,17 @@ async function startCodexProviderInstance(args) {
|
|
|
27224
27331
|
seq: sourceSeq,
|
|
27225
27332
|
body: workDescription,
|
|
27226
27333
|
actorSlug: identity.actorUsername,
|
|
27227
|
-
actorUserId: identity.actorUserId
|
|
27334
|
+
actorUserId: identity.actorUserId,
|
|
27335
|
+
boundStartTimeout: true
|
|
27228
27336
|
});
|
|
27229
27337
|
} else {
|
|
27230
|
-
await
|
|
27231
|
-
|
|
27232
|
-
|
|
27233
|
-
|
|
27338
|
+
await withCodexStartRequestTimeout(
|
|
27339
|
+
"turn/start",
|
|
27340
|
+
args.codex.request("turn/start", {
|
|
27341
|
+
threadId: codexThreadId,
|
|
27342
|
+
input: [{ type: "text", text: workDescription }]
|
|
27343
|
+
})
|
|
27344
|
+
);
|
|
27234
27345
|
}
|
|
27235
27346
|
}
|
|
27236
27347
|
return {
|
|
@@ -29130,9 +29241,10 @@ function redactedThreadRunnerCliArgs(args) {
|
|
|
29130
29241
|
function optionalCliValue(flag, value) {
|
|
29131
29242
|
return value === void 0 || value === "" ? [] : [flag, value];
|
|
29132
29243
|
}
|
|
29133
|
-
function startOnboardingDiscoveryAgents(options, log2) {
|
|
29244
|
+
function startOnboardingDiscoveryAgents(options, log2, onOnboardingDiscoveryComplete) {
|
|
29134
29245
|
const workspaceSlug = runnerWorkspaceSlug(options);
|
|
29135
29246
|
if (!shouldStartOnboardingDiscoveryAgents(options, workspaceSlug)) {
|
|
29247
|
+
void onOnboardingDiscoveryComplete?.();
|
|
29136
29248
|
return;
|
|
29137
29249
|
}
|
|
29138
29250
|
const startKey = onboardingDiscoveryAgentStartKey(options, workspaceSlug);
|
|
@@ -29190,6 +29302,7 @@ function startOnboardingDiscoveryAgents(options, log2) {
|
|
|
29190
29302
|
workers_completed: 2,
|
|
29191
29303
|
successful_write_count: successfulWriteCount
|
|
29192
29304
|
});
|
|
29305
|
+
await onOnboardingDiscoveryComplete?.();
|
|
29193
29306
|
});
|
|
29194
29307
|
}
|
|
29195
29308
|
function withSuccessfulWriteCount(report, successfulPostStartWriteCount) {
|
package/package.json
CHANGED