@linzumi/cli 0.0.110-beta → 0.0.111-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 +307 -20
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -5863,6 +5863,9 @@ function handleEvent(state, event, deps, effects) {
|
|
|
5863
5863
|
}
|
|
5864
5864
|
handleCodexNotification(state, event, deps, effects);
|
|
5865
5865
|
}
|
|
5866
|
+
function modelInteractionMethod(method) {
|
|
5867
|
+
return modelInteractionMethods.has(method);
|
|
5868
|
+
}
|
|
5866
5869
|
function handleCodexNotification(state, event, deps, effects) {
|
|
5867
5870
|
const method = event.notification.method;
|
|
5868
5871
|
const params = event.notification.params ?? {};
|
|
@@ -5879,9 +5882,7 @@ function handleCodexNotification(state, event, deps, effects) {
|
|
|
5879
5882
|
const explicitTurnId = notificationTurnId(params);
|
|
5880
5883
|
const turnId = explicitTurnId ?? singleActiveTurnId(state);
|
|
5881
5884
|
if (turnId === void 0) {
|
|
5882
|
-
effects.push(
|
|
5883
|
-
log("pipeline.loop.notification_without_turn", { method })
|
|
5884
|
-
);
|
|
5885
|
+
effects.push(log("pipeline.loop.notification_without_turn", { method }));
|
|
5885
5886
|
return;
|
|
5886
5887
|
}
|
|
5887
5888
|
if (state.terminalTurnIds.has(turnId)) {
|
|
@@ -5902,6 +5903,10 @@ function handleCodexNotification(state, event, deps, effects) {
|
|
|
5902
5903
|
}
|
|
5903
5904
|
turn = createTurn(state, turnId, sourceSeq);
|
|
5904
5905
|
}
|
|
5906
|
+
turn.notificationCount += 1;
|
|
5907
|
+
if (modelInteractionMethod(method)) {
|
|
5908
|
+
turn.modelInteractionSeen = true;
|
|
5909
|
+
}
|
|
5905
5910
|
if (method === "turn/started") {
|
|
5906
5911
|
return;
|
|
5907
5912
|
}
|
|
@@ -5915,6 +5920,7 @@ function handleCodexNotification(state, event, deps, effects) {
|
|
|
5915
5920
|
return;
|
|
5916
5921
|
}
|
|
5917
5922
|
if (method === "error") {
|
|
5923
|
+
turn.errorNotificationCount += 1;
|
|
5918
5924
|
const upstreamReason = upstreamErrorReason(params);
|
|
5919
5925
|
if (upstreamReason !== void 0) {
|
|
5920
5926
|
turn.lastUpstreamErrorReason = upstreamReason;
|
|
@@ -5924,6 +5930,17 @@ function handleCodexNotification(state, event, deps, effects) {
|
|
|
5924
5930
|
reason: upstreamReason
|
|
5925
5931
|
})
|
|
5926
5932
|
);
|
|
5933
|
+
} else {
|
|
5934
|
+
const diagnosticText = errorDiagnosticText(params);
|
|
5935
|
+
if (diagnosticText !== void 0) {
|
|
5936
|
+
turn.lastErrorDiagnosticText = diagnosticText;
|
|
5937
|
+
effects.push(
|
|
5938
|
+
log("codex.error_without_http_status_captured", {
|
|
5939
|
+
turn_id: turn.turnId,
|
|
5940
|
+
diagnostic_text: diagnosticText
|
|
5941
|
+
})
|
|
5942
|
+
);
|
|
5943
|
+
}
|
|
5927
5944
|
}
|
|
5928
5945
|
return;
|
|
5929
5946
|
}
|
|
@@ -5978,6 +5995,10 @@ function createTurn(state, turnId, sourceSeq) {
|
|
|
5978
5995
|
phase: "active",
|
|
5979
5996
|
protocolFailureReason: void 0,
|
|
5980
5997
|
lastUpstreamErrorReason: void 0,
|
|
5998
|
+
lastErrorDiagnosticText: void 0,
|
|
5999
|
+
errorNotificationCount: 0,
|
|
6000
|
+
notificationCount: 0,
|
|
6001
|
+
modelInteractionSeen: false,
|
|
5981
6002
|
items: []
|
|
5982
6003
|
};
|
|
5983
6004
|
state.turns.set(turnId, turn);
|
|
@@ -6144,7 +6165,11 @@ function handleItemCompleted(turn, params, deps, effects) {
|
|
|
6144
6165
|
);
|
|
6145
6166
|
}
|
|
6146
6167
|
function emitRowUpdate(turn, item, deltaIndex, streamState, deps, effects) {
|
|
6147
|
-
const rendered = renderPipelineItem(
|
|
6168
|
+
const rendered = renderPipelineItem(
|
|
6169
|
+
item.wireItemKey,
|
|
6170
|
+
item.content,
|
|
6171
|
+
streamState
|
|
6172
|
+
);
|
|
6148
6173
|
if (!item.posted) {
|
|
6149
6174
|
if (rendered.body.trim() === "") {
|
|
6150
6175
|
return;
|
|
@@ -6238,9 +6263,7 @@ function createItem(turn, streamKind, itemId, deps) {
|
|
|
6238
6263
|
}
|
|
6239
6264
|
function handleSnapshot(state, turnId, snapshot, deps, effects) {
|
|
6240
6265
|
if (state.terminalTurnIds.has(turnId)) {
|
|
6241
|
-
effects.push(
|
|
6242
|
-
log("pipeline.loop.duplicate_snapshot", { turn_id: turnId })
|
|
6243
|
-
);
|
|
6266
|
+
effects.push(log("pipeline.loop.duplicate_snapshot", { turn_id: turnId }));
|
|
6244
6267
|
return;
|
|
6245
6268
|
}
|
|
6246
6269
|
const turn = state.turns.get(turnId);
|
|
@@ -6363,7 +6386,9 @@ function handleSnapshot(state, turnId, snapshot, deps, effects) {
|
|
|
6363
6386
|
const assistantResponseSeen = turn.items.some(
|
|
6364
6387
|
(item) => item.identity.streamKind === "assistant" && item.posted
|
|
6365
6388
|
) || projected.some((proj) => proj.streamKind === "assistant");
|
|
6366
|
-
const
|
|
6389
|
+
const emptyTurnDiagnostic = !assistantResponseSeen && turn.protocolFailureReason === void 0 && turn.lastUpstreamErrorReason === void 0 ? classifyEmptyTurn(turn, projected.length) : void 0;
|
|
6390
|
+
const baseNoOutputReason = turn.lastUpstreamErrorReason ?? (emptyTurnDiagnostic === void 0 ? completedWithoutAssistantOutputReason : `${completedWithoutAssistantOutputReason} [${emptyTurnDiagnostic.cause}]`);
|
|
6391
|
+
const terminalFailureReason = turn.protocolFailureReason ?? (assistantResponseSeen ? void 0 : baseNoOutputReason);
|
|
6367
6392
|
if (turn.protocolFailureReason !== void 0) {
|
|
6368
6393
|
effects.push(
|
|
6369
6394
|
log("codex.turn_completed_with_protocol_failure", {
|
|
@@ -6381,7 +6406,19 @@ function handleSnapshot(state, turnId, snapshot, deps, effects) {
|
|
|
6381
6406
|
turn_id: turn.turnId,
|
|
6382
6407
|
source_seq: turn.sourceSeq,
|
|
6383
6408
|
streamed_item_count: turn.items.length,
|
|
6384
|
-
snapshot_item_count: projected.length
|
|
6409
|
+
snapshot_item_count: projected.length,
|
|
6410
|
+
// LAUNCH-LIVE self-diagnosing fields: tell apart "codex never called the
|
|
6411
|
+
// model" from "model returned empty" from "error without HTTP status".
|
|
6412
|
+
notification_count: turn.notificationCount,
|
|
6413
|
+
error_notification_count: turn.errorNotificationCount,
|
|
6414
|
+
model_interaction_seen: turn.modelInteractionSeen,
|
|
6415
|
+
last_error_diagnostic_text: turn.lastErrorDiagnosticText ?? null,
|
|
6416
|
+
last_upstream_error_reason: turn.lastUpstreamErrorReason ?? null,
|
|
6417
|
+
empty_turn_cause: emptyTurnDiagnostic?.cause ?? null,
|
|
6418
|
+
// True iff the surfaced failure is the safe, retryable empty/no-response
|
|
6419
|
+
// terminal (no output produced, no real upstream error) - the signal
|
|
6420
|
+
// the client uses to offer a one-click retry (PART B, loud affordance).
|
|
6421
|
+
retryable_empty_turn: emptyTurnDiagnostic !== void 0
|
|
6385
6422
|
})
|
|
6386
6423
|
);
|
|
6387
6424
|
}
|
|
@@ -6394,7 +6431,13 @@ function handleSnapshot(state, turnId, snapshot, deps, effects) {
|
|
|
6394
6431
|
seq: turn.sourceSeq,
|
|
6395
6432
|
...terminalFailureReason === void 0 ? { status: "processed" } : {
|
|
6396
6433
|
status: "failed",
|
|
6397
|
-
reason: terminalFailureReason
|
|
6434
|
+
reason: terminalFailureReason,
|
|
6435
|
+
// PART B (loud retry affordance): mark the safe empty/no-response
|
|
6436
|
+
// terminal as retryable so the client can offer a one-click retry.
|
|
6437
|
+
// Additive optional field; older servers ignore it. Only the empty
|
|
6438
|
+
// terminal is retryable - real upstream errors (402/429/gateway,
|
|
6439
|
+
// protocol failures) carry their own handling and are NOT flagged.
|
|
6440
|
+
...emptyTurnDiagnostic !== void 0 ? { retryable: true } : {}
|
|
6398
6441
|
}
|
|
6399
6442
|
},
|
|
6400
6443
|
resolution: "must_ack"
|
|
@@ -6483,7 +6526,9 @@ function failureReason(params) {
|
|
|
6483
6526
|
return stringValue(params.reason) ?? stringValue(params.message) ?? stringValue(objectValue(params.error)?.message) ?? stringValue(params.error) ?? "codex_turn_aborted";
|
|
6484
6527
|
}
|
|
6485
6528
|
function upstreamErrorReason(params) {
|
|
6486
|
-
const summaryRaw = stringValue(params.diagnostic_summary) ?? stringValue(
|
|
6529
|
+
const summaryRaw = stringValue(params.diagnostic_summary) ?? stringValue(
|
|
6530
|
+
objectValue(objectValue(params.diagnostic_payload)?.error)?.message
|
|
6531
|
+
);
|
|
6487
6532
|
if (summaryRaw === void 0) {
|
|
6488
6533
|
return void 0;
|
|
6489
6534
|
}
|
|
@@ -6501,10 +6546,33 @@ function upstreamErrorHttpStatus(params) {
|
|
|
6501
6546
|
const code = disconnected?.httpStatusCode;
|
|
6502
6547
|
return typeof code === "number" ? code : void 0;
|
|
6503
6548
|
}
|
|
6549
|
+
function errorDiagnosticText(params) {
|
|
6550
|
+
const raw = stringValue(params.message) ?? stringValue(params.reason) ?? stringValue(objectValue(params.error)?.message) ?? stringValue(params.error) ?? stringValue(params.diagnostic);
|
|
6551
|
+
if (raw === void 0) {
|
|
6552
|
+
return void 0;
|
|
6553
|
+
}
|
|
6554
|
+
const cleaned = raw.replace(/<[^>]*>/g, " ").replace(/data:[^"' )]+/g, "").replace(/\s+/g, " ").trim().slice(0, 180);
|
|
6555
|
+
return cleaned.length === 0 ? void 0 : cleaned;
|
|
6556
|
+
}
|
|
6557
|
+
function classifyEmptyTurn(turn, snapshotItemCount) {
|
|
6558
|
+
if (turn.lastErrorDiagnosticText !== void 0) {
|
|
6559
|
+
return {
|
|
6560
|
+
cause: `codex error without HTTP status: ${turn.lastErrorDiagnosticText}`
|
|
6561
|
+
};
|
|
6562
|
+
}
|
|
6563
|
+
if (!turn.modelInteractionSeen) {
|
|
6564
|
+
return {
|
|
6565
|
+
cause: `codex never called the model: 0 model interactions, ${turn.notificationCount} notifications, ${turn.errorNotificationCount} errors`
|
|
6566
|
+
};
|
|
6567
|
+
}
|
|
6568
|
+
return {
|
|
6569
|
+
cause: `model returned no assistant output: ${turn.items.length} streamed items, ${snapshotItemCount} snapshot items`
|
|
6570
|
+
};
|
|
6571
|
+
}
|
|
6504
6572
|
function log(event, fields) {
|
|
6505
6573
|
return { type: "log", event, fields };
|
|
6506
6574
|
}
|
|
6507
|
-
var terminalRowStreamStates, turnMappingReadyMethod, turnMappingFailedMethod, maxTerminalTurnIds, completedWithoutAssistantOutputReason, unsupportedCodexToolCallReasonPrefix, turnTerminalFailureMethods, handledNotificationMethods;
|
|
6575
|
+
var terminalRowStreamStates, turnMappingReadyMethod, turnMappingFailedMethod, maxTerminalTurnIds, completedWithoutAssistantOutputReason, unsupportedCodexToolCallReasonPrefix, turnTerminalFailureMethods, handledNotificationMethods, modelInteractionMethods;
|
|
6508
6576
|
var init_transition = __esm({
|
|
6509
6577
|
"src/pipeline/transition.ts"() {
|
|
6510
6578
|
"use strict";
|
|
@@ -6545,6 +6613,17 @@ var init_transition = __esm({
|
|
|
6545
6613
|
"item/completed",
|
|
6546
6614
|
"response_item"
|
|
6547
6615
|
]);
|
|
6616
|
+
modelInteractionMethods = /* @__PURE__ */ new Set([
|
|
6617
|
+
"item/agentMessage/delta",
|
|
6618
|
+
"item/reasoning/textDelta",
|
|
6619
|
+
"item/commandExecution/outputDelta",
|
|
6620
|
+
"command/exec/outputDelta",
|
|
6621
|
+
"item/fileChange/outputDelta",
|
|
6622
|
+
"item/commandExecution/terminalInteraction",
|
|
6623
|
+
"item/started",
|
|
6624
|
+
"item/completed",
|
|
6625
|
+
"response_item"
|
|
6626
|
+
]);
|
|
6548
6627
|
}
|
|
6549
6628
|
});
|
|
6550
6629
|
|
|
@@ -20078,7 +20157,7 @@ var linzumiCliVersion, linzumiCliVersionText;
|
|
|
20078
20157
|
var init_version = __esm({
|
|
20079
20158
|
"src/version.ts"() {
|
|
20080
20159
|
"use strict";
|
|
20081
|
-
linzumiCliVersion = "0.0.
|
|
20160
|
+
linzumiCliVersion = "0.0.111-beta";
|
|
20082
20161
|
linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
|
|
20083
20162
|
}
|
|
20084
20163
|
});
|
|
@@ -23176,6 +23255,172 @@ var init_threadCodexWorkerIpc = __esm({
|
|
|
23176
23255
|
}
|
|
23177
23256
|
});
|
|
23178
23257
|
|
|
23258
|
+
// src/signupTaskSuggestionsProgress.ts
|
|
23259
|
+
function basenameOf(rawPath) {
|
|
23260
|
+
const trimmed = rawPath.trim();
|
|
23261
|
+
if (trimmed === "") {
|
|
23262
|
+
return void 0;
|
|
23263
|
+
}
|
|
23264
|
+
const withoutTrailing = trimmed.replace(/[/\\]+$/, "");
|
|
23265
|
+
const segments = withoutTrailing.split(/[/\\]+/);
|
|
23266
|
+
const last = segments[segments.length - 1];
|
|
23267
|
+
if (last === void 0 || last === "" || last === "." || last === "..") {
|
|
23268
|
+
return void 0;
|
|
23269
|
+
}
|
|
23270
|
+
if (last.length > MAX_BASENAME_LENGTH) {
|
|
23271
|
+
return `${last.slice(0, MAX_BASENAME_LENGTH - 1)}\u2026`;
|
|
23272
|
+
}
|
|
23273
|
+
return last;
|
|
23274
|
+
}
|
|
23275
|
+
function lookingAtFileLabel(rawPath) {
|
|
23276
|
+
if (typeof rawPath !== "string") {
|
|
23277
|
+
return void 0;
|
|
23278
|
+
}
|
|
23279
|
+
const basename10 = basenameOf(rawPath);
|
|
23280
|
+
return basename10 === void 0 ? void 0 : `Looking at ${basename10}...`;
|
|
23281
|
+
}
|
|
23282
|
+
function commandLabel2(command) {
|
|
23283
|
+
let head;
|
|
23284
|
+
let target;
|
|
23285
|
+
if (Array.isArray(command)) {
|
|
23286
|
+
const parts = command.filter((part) => typeof part === "string");
|
|
23287
|
+
const meaningful = parts.filter(
|
|
23288
|
+
(part) => part !== "bash" && part !== "sh" && part !== "-lc" && part !== "-c"
|
|
23289
|
+
);
|
|
23290
|
+
head = meaningful[0];
|
|
23291
|
+
target = meaningful.slice(1).find((part) => !part.startsWith("-"));
|
|
23292
|
+
} else if (typeof command === "string") {
|
|
23293
|
+
const tokens = command.trim().split(/\s+/);
|
|
23294
|
+
head = tokens[0];
|
|
23295
|
+
target = tokens.slice(1).find((part) => !part.startsWith("-"));
|
|
23296
|
+
} else {
|
|
23297
|
+
return void 0;
|
|
23298
|
+
}
|
|
23299
|
+
if (head === void 0) {
|
|
23300
|
+
return void 0;
|
|
23301
|
+
}
|
|
23302
|
+
const baseCommand = basenameOf(head) ?? head;
|
|
23303
|
+
if (!READ_COMMAND_PREFIXES.includes(baseCommand)) {
|
|
23304
|
+
return READING_REPO;
|
|
23305
|
+
}
|
|
23306
|
+
const fileLabel = target === void 0 ? void 0 : lookingAtFileLabel(target);
|
|
23307
|
+
return fileLabel ?? READING_REPO;
|
|
23308
|
+
}
|
|
23309
|
+
function progressLabelForCodexEvent(event) {
|
|
23310
|
+
if (typeof event !== "object" || event === null || Array.isArray(event)) {
|
|
23311
|
+
return void 0;
|
|
23312
|
+
}
|
|
23313
|
+
const record = event;
|
|
23314
|
+
const item = record["item"];
|
|
23315
|
+
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
23316
|
+
const itemRecord = item;
|
|
23317
|
+
const itemType = itemRecord["item_type"] ?? itemRecord["type"];
|
|
23318
|
+
switch (itemType) {
|
|
23319
|
+
case "reasoning":
|
|
23320
|
+
return READING_REPO;
|
|
23321
|
+
case "command_execution":
|
|
23322
|
+
case "local_shell_call":
|
|
23323
|
+
return commandLabel2(itemRecord["command"] ?? itemRecord["argv"]) ?? READING_REPO;
|
|
23324
|
+
case "file_change":
|
|
23325
|
+
case "file_read":
|
|
23326
|
+
return lookingAtFileLabel(itemRecord["path"]) ?? READING_REPO;
|
|
23327
|
+
case "agent_message":
|
|
23328
|
+
case "assistant_message":
|
|
23329
|
+
return DRAFTING_TASKS;
|
|
23330
|
+
default:
|
|
23331
|
+
return void 0;
|
|
23332
|
+
}
|
|
23333
|
+
}
|
|
23334
|
+
const msg = record["msg"];
|
|
23335
|
+
const msgRecord = typeof msg === "object" && msg !== null && !Array.isArray(msg) ? msg : record;
|
|
23336
|
+
const msgType = msgRecord["type"] ?? record["type"];
|
|
23337
|
+
switch (msgType) {
|
|
23338
|
+
case "task_started":
|
|
23339
|
+
case "agent_reasoning":
|
|
23340
|
+
case "agent_reasoning_delta":
|
|
23341
|
+
case "agent_reasoning_section_break":
|
|
23342
|
+
return READING_REPO;
|
|
23343
|
+
case "exec_command_begin":
|
|
23344
|
+
case "exec_command_end":
|
|
23345
|
+
return commandLabel2(msgRecord["command"]) ?? READING_REPO;
|
|
23346
|
+
case "agent_message":
|
|
23347
|
+
case "agent_message_delta":
|
|
23348
|
+
return DRAFTING_TASKS;
|
|
23349
|
+
default:
|
|
23350
|
+
return void 0;
|
|
23351
|
+
}
|
|
23352
|
+
}
|
|
23353
|
+
function createTaskSuggestionProgressParser(onLabel) {
|
|
23354
|
+
let buffer = "";
|
|
23355
|
+
let lastLabel;
|
|
23356
|
+
const emit = (label) => {
|
|
23357
|
+
if (label === void 0 || label === lastLabel) {
|
|
23358
|
+
return;
|
|
23359
|
+
}
|
|
23360
|
+
lastLabel = label;
|
|
23361
|
+
try {
|
|
23362
|
+
onLabel(label);
|
|
23363
|
+
} catch {
|
|
23364
|
+
}
|
|
23365
|
+
};
|
|
23366
|
+
const consumeLine = (line) => {
|
|
23367
|
+
const trimmed = line.trim();
|
|
23368
|
+
if (trimmed === "" || trimmed[0] !== "{") {
|
|
23369
|
+
return;
|
|
23370
|
+
}
|
|
23371
|
+
let parsed;
|
|
23372
|
+
try {
|
|
23373
|
+
parsed = JSON.parse(trimmed);
|
|
23374
|
+
} catch {
|
|
23375
|
+
return;
|
|
23376
|
+
}
|
|
23377
|
+
emit(progressLabelForCodexEvent(parsed));
|
|
23378
|
+
};
|
|
23379
|
+
return {
|
|
23380
|
+
push: (chunk) => {
|
|
23381
|
+
buffer += chunk;
|
|
23382
|
+
let newlineIndex = buffer.indexOf("\n");
|
|
23383
|
+
while (newlineIndex !== -1) {
|
|
23384
|
+
const line = buffer.slice(0, newlineIndex);
|
|
23385
|
+
buffer = buffer.slice(newlineIndex + 1);
|
|
23386
|
+
consumeLine(line);
|
|
23387
|
+
newlineIndex = buffer.indexOf("\n");
|
|
23388
|
+
}
|
|
23389
|
+
},
|
|
23390
|
+
flush: () => {
|
|
23391
|
+
if (buffer.trim() !== "") {
|
|
23392
|
+
consumeLine(buffer);
|
|
23393
|
+
buffer = "";
|
|
23394
|
+
}
|
|
23395
|
+
}
|
|
23396
|
+
};
|
|
23397
|
+
}
|
|
23398
|
+
var READING_REPO, DRAFTING_TASKS, MAX_BASENAME_LENGTH, READ_COMMAND_PREFIXES;
|
|
23399
|
+
var init_signupTaskSuggestionsProgress = __esm({
|
|
23400
|
+
"src/signupTaskSuggestionsProgress.ts"() {
|
|
23401
|
+
"use strict";
|
|
23402
|
+
READING_REPO = "Reading your repository...";
|
|
23403
|
+
DRAFTING_TASKS = "Drafting tasks...";
|
|
23404
|
+
MAX_BASENAME_LENGTH = 60;
|
|
23405
|
+
READ_COMMAND_PREFIXES = [
|
|
23406
|
+
"ls",
|
|
23407
|
+
"cat",
|
|
23408
|
+
"head",
|
|
23409
|
+
"tail",
|
|
23410
|
+
"find",
|
|
23411
|
+
"rg",
|
|
23412
|
+
"grep",
|
|
23413
|
+
"tree",
|
|
23414
|
+
"wc",
|
|
23415
|
+
"sed",
|
|
23416
|
+
"awk",
|
|
23417
|
+
"pwd",
|
|
23418
|
+
"stat",
|
|
23419
|
+
"file"
|
|
23420
|
+
];
|
|
23421
|
+
}
|
|
23422
|
+
});
|
|
23423
|
+
|
|
23179
23424
|
// src/signupTaskSuggestions.ts
|
|
23180
23425
|
import { spawn as spawn7 } from "node:child_process";
|
|
23181
23426
|
import { mkdtempSync as mkdtempSync3, readFileSync as readFileSync16, rmSync as rmSync4, writeFileSync as writeFileSync11 } from "node:fs";
|
|
@@ -23200,7 +23445,8 @@ async function suggestSignupTasksWithCodex(args) {
|
|
|
23200
23445
|
model,
|
|
23201
23446
|
modelProvider: args.modelProvider,
|
|
23202
23447
|
previousResponse,
|
|
23203
|
-
timeoutMs: remaining
|
|
23448
|
+
timeoutMs: remaining,
|
|
23449
|
+
onProgress: args.onProgress
|
|
23204
23450
|
});
|
|
23205
23451
|
} catch (error) {
|
|
23206
23452
|
throw error instanceof Error ? error : new Error(String(error));
|
|
@@ -23251,7 +23497,8 @@ async function runCodexTaskSuggestion(args) {
|
|
|
23251
23497
|
outputPath,
|
|
23252
23498
|
prompt,
|
|
23253
23499
|
timeoutMs: args.timeoutMs
|
|
23254
|
-
})
|
|
23500
|
+
}),
|
|
23501
|
+
args.onProgress
|
|
23255
23502
|
);
|
|
23256
23503
|
return readFileSync16(outputPath, "utf8");
|
|
23257
23504
|
} finally {
|
|
@@ -23288,6 +23535,14 @@ function codexTaskSuggestionProcess(args) {
|
|
|
23288
23535
|
args.schemaPath,
|
|
23289
23536
|
"--output-last-message",
|
|
23290
23537
|
args.outputPath,
|
|
23538
|
+
// LIVE PROGRESS: stream the agentic turn as JSONL events on stdout so we
|
|
23539
|
+
// can parse privacy-safe step labels ("Reading your repository...",
|
|
23540
|
+
// "Looking at <file>...", "Drafting tasks...") and relay them to the
|
|
23541
|
+
// onboarding wizard while the (up to ~150s) turn runs. The final task
|
|
23542
|
+
// JSON still comes from --output-last-message, so this is purely additive
|
|
23543
|
+
// - if a codex build ignores or changes --json, we simply get no progress
|
|
23544
|
+
// and the suggestion result is unaffected.
|
|
23545
|
+
"--json",
|
|
23291
23546
|
"--color",
|
|
23292
23547
|
"never",
|
|
23293
23548
|
"-"
|
|
@@ -23381,15 +23636,28 @@ function parseTaskSuggestionResponse(response) {
|
|
|
23381
23636
|
return void 0;
|
|
23382
23637
|
}
|
|
23383
23638
|
}
|
|
23384
|
-
function runProcess2(args) {
|
|
23639
|
+
function runProcess2(args, onProgress) {
|
|
23385
23640
|
return new Promise((resolveProcess, rejectProcess) => {
|
|
23386
23641
|
const child = spawn7(args.command, [...args.args], {
|
|
23387
23642
|
cwd: args.cwd,
|
|
23388
23643
|
// Inherit the runner env (codex auth, PATH, etc.) and layer the wafer
|
|
23389
23644
|
// proxy credential (LINZUMI_LLM_PROXY_TOKEN) on top when wafer-routed.
|
|
23390
23645
|
...args.env === void 0 ? {} : { env: { ...process.env, ...args.env } },
|
|
23391
|
-
|
|
23646
|
+
// LIVE PROGRESS: capture stdout (the `--json` JSONL event stream) only
|
|
23647
|
+
// when a progress callback is supplied; otherwise discard it as before.
|
|
23648
|
+
// We never depend on stdout for the result (that's --output-last-message),
|
|
23649
|
+
// so stdout parsing is purely a best-effort enhancement.
|
|
23650
|
+
stdio: ["pipe", onProgress === void 0 ? "ignore" : "pipe", "pipe"]
|
|
23392
23651
|
});
|
|
23652
|
+
const progress = onProgress === void 0 ? void 0 : createTaskSuggestionProgressParser(onProgress);
|
|
23653
|
+
if (progress !== void 0) {
|
|
23654
|
+
child.stdout?.on("data", (chunk) => {
|
|
23655
|
+
try {
|
|
23656
|
+
progress.push(String(chunk));
|
|
23657
|
+
} catch {
|
|
23658
|
+
}
|
|
23659
|
+
});
|
|
23660
|
+
}
|
|
23393
23661
|
let stderr = "";
|
|
23394
23662
|
let settled = false;
|
|
23395
23663
|
const timeout = setTimeout(() => {
|
|
@@ -23402,6 +23670,10 @@ function runProcess2(args) {
|
|
|
23402
23670
|
}
|
|
23403
23671
|
settled = true;
|
|
23404
23672
|
clearTimeout(timeout);
|
|
23673
|
+
try {
|
|
23674
|
+
progress?.flush();
|
|
23675
|
+
} catch {
|
|
23676
|
+
}
|
|
23405
23677
|
if (error === void 0) {
|
|
23406
23678
|
resolveProcess();
|
|
23407
23679
|
return;
|
|
@@ -23433,6 +23705,7 @@ var init_signupTaskSuggestions = __esm({
|
|
|
23433
23705
|
"src/signupTaskSuggestions.ts"() {
|
|
23434
23706
|
"use strict";
|
|
23435
23707
|
init_codexAppServer();
|
|
23708
|
+
init_signupTaskSuggestionsProgress();
|
|
23436
23709
|
DEFAULT_CODEX_AUTH_SUGGESTION_MODEL = "gpt-5.4-mini";
|
|
23437
23710
|
DEFAULT_WAFER_SUGGESTION_MODEL = "GLM-5.2";
|
|
23438
23711
|
SUGGESTION_TIMEOUT_MS = 15e4;
|
|
@@ -29596,7 +29869,10 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
|
|
|
29596
29869
|
return createRunnerProject(control, options, allowedCwds);
|
|
29597
29870
|
}
|
|
29598
29871
|
case "suggest_tasks": {
|
|
29599
|
-
return suggestRunnerTasks(control, options, allowedCwds.value
|
|
29872
|
+
return suggestRunnerTasks(control, options, allowedCwds.value, {
|
|
29873
|
+
kandan,
|
|
29874
|
+
topic
|
|
29875
|
+
});
|
|
29600
29876
|
}
|
|
29601
29877
|
case "remote_codex_exec": {
|
|
29602
29878
|
return await applyRemoteCodexExecControl(
|
|
@@ -33553,7 +33829,7 @@ function resolveSuggestTasksModelProvider(control) {
|
|
|
33553
33829
|
env: codexModelProviderAppServerEnv(runtime)
|
|
33554
33830
|
};
|
|
33555
33831
|
}
|
|
33556
|
-
async function suggestRunnerTasks(control, options, allowedCwds) {
|
|
33832
|
+
async function suggestRunnerTasks(control, options, allowedCwds, progressSink) {
|
|
33557
33833
|
const requestId = stringValue(control.requestId) ?? null;
|
|
33558
33834
|
const cwd = resolveAllowedCwd(control.cwd, allowedCwds);
|
|
33559
33835
|
if (!cwd.ok) {
|
|
@@ -33567,12 +33843,23 @@ async function suggestRunnerTasks(control, options, allowedCwds) {
|
|
|
33567
33843
|
}
|
|
33568
33844
|
const modelProvider = resolveSuggestTasksModelProvider(control);
|
|
33569
33845
|
const model = stringValue(control.model)?.trim();
|
|
33846
|
+
const workspaceSlug = stringValue(control.workspace)?.trim();
|
|
33847
|
+
const onProgress = progressSink === void 0 || requestId === null ? void 0 : (label) => {
|
|
33848
|
+
void progressSink.kandan.pushIfConnected(progressSink.topic, "suggest_tasks_progress", {
|
|
33849
|
+
instanceId: options.runnerId,
|
|
33850
|
+
controlType: control.type,
|
|
33851
|
+
requestId,
|
|
33852
|
+
...workspaceSlug === void 0 || workspaceSlug === "" ? {} : { workspace: workspaceSlug },
|
|
33853
|
+
label
|
|
33854
|
+
}).catch(() => void 0);
|
|
33855
|
+
};
|
|
33570
33856
|
try {
|
|
33571
33857
|
const tasks = await suggestSignupTasksWithCodex({
|
|
33572
33858
|
projectPath: cwd.cwd,
|
|
33573
33859
|
codexBin: options.codexBin,
|
|
33574
33860
|
...model === void 0 || model === "" ? {} : { model },
|
|
33575
|
-
...modelProvider === void 0 ? {} : { modelProvider }
|
|
33861
|
+
...modelProvider === void 0 ? {} : { modelProvider },
|
|
33862
|
+
...onProgress === void 0 ? {} : { onProgress }
|
|
33576
33863
|
});
|
|
33577
33864
|
return {
|
|
33578
33865
|
instanceId: options.runnerId,
|
package/package.json
CHANGED