@linzumi/cli 0.0.55-beta → 0.0.56-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 +185 -327
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -18203,8 +18203,8 @@ function pathLooksAbsolute(pathValue) {
|
|
|
18203
18203
|
}
|
|
18204
18204
|
|
|
18205
18205
|
// src/localForwarding.ts
|
|
18206
|
+
import { connect as connectTcp } from "node:net";
|
|
18206
18207
|
import { gzipSync } from "node:zlib";
|
|
18207
|
-
import NodeWebSocket from "ws";
|
|
18208
18208
|
var maxForwardBodyBytes = 64 * 1024 * 1024;
|
|
18209
18209
|
var gzipForwardThresholdBytes = 32 * 1024;
|
|
18210
18210
|
async function handleForwardHttpRequest(control, allowedPorts) {
|
|
@@ -18261,21 +18261,21 @@ async function handleForwardHttpRequest(control, allowedPorts) {
|
|
|
18261
18261
|
function isForwardHttpRequestControl(control) {
|
|
18262
18262
|
return control.type === "forward_http_request";
|
|
18263
18263
|
}
|
|
18264
|
-
function
|
|
18265
|
-
return control.type === "
|
|
18264
|
+
function isForwardTcpControl(control) {
|
|
18265
|
+
return control.type === "forward_tcp_open" || control.type === "forward_tcp_send" || control.type === "forward_tcp_close";
|
|
18266
18266
|
}
|
|
18267
|
-
function
|
|
18267
|
+
function createForwardTcpManager(kandan, topic, allowedPorts, socketFactory = defaultForwardTcpFactory) {
|
|
18268
18268
|
const sockets = /* @__PURE__ */ new Map();
|
|
18269
|
-
const pushEvent = (payload) => kandan.push(topic, "forward:
|
|
18269
|
+
const pushEvent = (payload) => kandan.push(topic, "forward:tcp_event", payload).catch(() => void 0);
|
|
18270
18270
|
const closeSocket = (socketId) => {
|
|
18271
18271
|
const stream = sockets.get(socketId);
|
|
18272
18272
|
sockets.delete(socketId);
|
|
18273
|
-
stream?.socket.
|
|
18273
|
+
stream?.socket.end();
|
|
18274
18274
|
};
|
|
18275
18275
|
return {
|
|
18276
18276
|
handle: (control) => {
|
|
18277
18277
|
switch (control.type) {
|
|
18278
|
-
case "
|
|
18278
|
+
case "forward_tcp_open": {
|
|
18279
18279
|
if (!allowedPorts().includes(control.port)) {
|
|
18280
18280
|
void pushEvent({
|
|
18281
18281
|
socketId: control.socketId,
|
|
@@ -18284,32 +18284,70 @@ function createForwardWebSocketManager(kandan, topic, allowedPorts, socketFactor
|
|
|
18284
18284
|
});
|
|
18285
18285
|
return;
|
|
18286
18286
|
}
|
|
18287
|
-
|
|
18287
|
+
const previous = sockets.get(control.socketId);
|
|
18288
|
+
previous?.socket.destroy();
|
|
18289
|
+
const socket = socketFactory(control.port);
|
|
18290
|
+
sockets.set(control.socketId, { socket });
|
|
18291
|
+
socket.on("connect", () => {
|
|
18292
|
+
if (!currentTcpSocket(sockets, control.socketId, socket)) {
|
|
18293
|
+
return;
|
|
18294
|
+
}
|
|
18295
|
+
void pushEvent({ socketId: control.socketId, type: "open" });
|
|
18296
|
+
});
|
|
18297
|
+
socket.on("data", (data) => {
|
|
18298
|
+
if (!currentTcpSocket(sockets, control.socketId, socket) || !(data instanceof Uint8Array)) {
|
|
18299
|
+
return;
|
|
18300
|
+
}
|
|
18301
|
+
void pushEvent({
|
|
18302
|
+
socketId: control.socketId,
|
|
18303
|
+
type: "data",
|
|
18304
|
+
bodyBase64: Buffer.from(data).toString("base64")
|
|
18305
|
+
});
|
|
18306
|
+
});
|
|
18307
|
+
socket.on("close", () => {
|
|
18308
|
+
if (!currentTcpSocket(sockets, control.socketId, socket)) {
|
|
18309
|
+
return;
|
|
18310
|
+
}
|
|
18311
|
+
sockets.delete(control.socketId);
|
|
18312
|
+
void pushEvent({ socketId: control.socketId, type: "close" });
|
|
18313
|
+
});
|
|
18314
|
+
socket.on("error", () => {
|
|
18315
|
+
if (!currentTcpSocket(sockets, control.socketId, socket)) {
|
|
18316
|
+
return;
|
|
18317
|
+
}
|
|
18318
|
+
sockets.delete(control.socketId);
|
|
18319
|
+
void pushEvent({
|
|
18320
|
+
socketId: control.socketId,
|
|
18321
|
+
type: "error",
|
|
18322
|
+
error: "forward_target_unavailable"
|
|
18323
|
+
});
|
|
18324
|
+
socket.destroy();
|
|
18325
|
+
});
|
|
18288
18326
|
return;
|
|
18289
18327
|
}
|
|
18290
|
-
case "
|
|
18328
|
+
case "forward_tcp_send": {
|
|
18291
18329
|
const stream = sockets.get(control.socketId);
|
|
18292
|
-
|
|
18330
|
+
const body = decodeBase64Body(control.bodyBase64);
|
|
18331
|
+
if (body === void 0) {
|
|
18293
18332
|
void pushEvent({
|
|
18294
18333
|
socketId: control.socketId,
|
|
18295
18334
|
type: "error",
|
|
18296
|
-
error: "
|
|
18335
|
+
error: "invalid_forward_request"
|
|
18297
18336
|
});
|
|
18298
18337
|
return;
|
|
18299
18338
|
}
|
|
18300
|
-
|
|
18301
|
-
|
|
18302
|
-
|
|
18303
|
-
|
|
18304
|
-
|
|
18305
|
-
|
|
18306
|
-
|
|
18307
|
-
case "pong":
|
|
18308
|
-
stream.socket.send(body);
|
|
18309
|
-
return;
|
|
18339
|
+
if (stream === void 0 || stream.socket.destroyed === true || stream.socket.writable === false) {
|
|
18340
|
+
void pushEvent({
|
|
18341
|
+
socketId: control.socketId,
|
|
18342
|
+
type: "error",
|
|
18343
|
+
error: "tcp_socket_not_open"
|
|
18344
|
+
});
|
|
18345
|
+
return;
|
|
18310
18346
|
}
|
|
18347
|
+
stream.socket.write(body);
|
|
18348
|
+
return;
|
|
18311
18349
|
}
|
|
18312
|
-
case "
|
|
18350
|
+
case "forward_tcp_close":
|
|
18313
18351
|
closeSocket(control.socketId);
|
|
18314
18352
|
return;
|
|
18315
18353
|
}
|
|
@@ -18321,105 +18359,11 @@ function createForwardWebSocketManager(kandan, topic, allowedPorts, socketFactor
|
|
|
18321
18359
|
}
|
|
18322
18360
|
};
|
|
18323
18361
|
}
|
|
18324
|
-
function
|
|
18325
|
-
let opened = false;
|
|
18326
|
-
const url = localForwardWebSocketUrl(
|
|
18327
|
-
scheme,
|
|
18328
|
-
control.port,
|
|
18329
|
-
control.path,
|
|
18330
|
-
control.queryString
|
|
18331
|
-
);
|
|
18332
|
-
const protocols = webSocketProtocols(control.headers);
|
|
18333
|
-
const headers = webSocketHeaders(control.headers);
|
|
18334
|
-
const websocket = socketFactory(url, protocols, headers);
|
|
18335
|
-
websocket.binaryType = "arraybuffer";
|
|
18336
|
-
const previousStream = sockets.get(control.socketId);
|
|
18337
|
-
previousStream?.socket.close();
|
|
18338
|
-
sockets.set(control.socketId, { socket: websocket });
|
|
18339
|
-
websocket.addEventListener("open", () => {
|
|
18340
|
-
if (!currentWebSocket(sockets, control.socketId, websocket)) {
|
|
18341
|
-
return;
|
|
18342
|
-
}
|
|
18343
|
-
opened = true;
|
|
18344
|
-
void pushEvent({ socketId: control.socketId, type: "open" });
|
|
18345
|
-
});
|
|
18346
|
-
websocket.addEventListener("message", (event) => {
|
|
18347
|
-
if (!currentWebSocket(sockets, control.socketId, websocket)) {
|
|
18348
|
-
return;
|
|
18349
|
-
}
|
|
18350
|
-
const body = typeof event.data === "string" ? Buffer.from(event.data) : Buffer.from(event.data);
|
|
18351
|
-
void pushEvent({
|
|
18352
|
-
socketId: control.socketId,
|
|
18353
|
-
type: "message",
|
|
18354
|
-
opcode: typeof event.data === "string" ? "text" : "binary",
|
|
18355
|
-
bodyBase64: body.toString("base64")
|
|
18356
|
-
});
|
|
18357
|
-
});
|
|
18358
|
-
websocket.addEventListener("close", (event) => {
|
|
18359
|
-
if (!currentWebSocket(sockets, control.socketId, websocket)) {
|
|
18360
|
-
return;
|
|
18361
|
-
}
|
|
18362
|
-
sockets.delete(control.socketId);
|
|
18363
|
-
void pushEvent({
|
|
18364
|
-
socketId: control.socketId,
|
|
18365
|
-
type: "close",
|
|
18366
|
-
code: event.code,
|
|
18367
|
-
reason: event.reason
|
|
18368
|
-
});
|
|
18369
|
-
});
|
|
18370
|
-
websocket.addEventListener("error", () => {
|
|
18371
|
-
if (!currentWebSocket(sockets, control.socketId, websocket)) {
|
|
18372
|
-
return;
|
|
18373
|
-
}
|
|
18374
|
-
sockets.delete(control.socketId);
|
|
18375
|
-
if (!opened && scheme === "ws") {
|
|
18376
|
-
openLocalWebSocket(control, sockets, pushEvent, socketFactory, "wss");
|
|
18377
|
-
return;
|
|
18378
|
-
}
|
|
18379
|
-
void pushEvent({
|
|
18380
|
-
socketId: control.socketId,
|
|
18381
|
-
type: "error",
|
|
18382
|
-
error: "websocket_error",
|
|
18383
|
-
attemptedScheme: scheme
|
|
18384
|
-
});
|
|
18385
|
-
});
|
|
18386
|
-
}
|
|
18387
|
-
function defaultForwardWebSocketFactory(url, protocols, headers) {
|
|
18388
|
-
if (headers === void 0) {
|
|
18389
|
-
return protocols === void 0 ? new WebSocket(url) : new WebSocket(url, protocols);
|
|
18390
|
-
}
|
|
18391
|
-
const options = { headers };
|
|
18392
|
-
return protocols === void 0 ? new NodeWebSocket(url, options) : new NodeWebSocket(url, protocols, options);
|
|
18393
|
-
}
|
|
18394
|
-
function currentWebSocket(sockets, socketId, socket) {
|
|
18362
|
+
function currentTcpSocket(sockets, socketId, socket) {
|
|
18395
18363
|
return sockets.get(socketId)?.socket === socket;
|
|
18396
18364
|
}
|
|
18397
|
-
function
|
|
18398
|
-
|
|
18399
|
-
return void 0;
|
|
18400
|
-
}
|
|
18401
|
-
const protocols = headers.flatMap((header) => {
|
|
18402
|
-
if (!isWireHeader(header) || header.name.toLowerCase() !== "sec-websocket-protocol") {
|
|
18403
|
-
return [];
|
|
18404
|
-
}
|
|
18405
|
-
return header.value.split(",").map((protocol) => protocol.trim()).filter((protocol) => protocol !== "");
|
|
18406
|
-
});
|
|
18407
|
-
return protocols.length === 0 ? void 0 : protocols;
|
|
18408
|
-
}
|
|
18409
|
-
function webSocketHeaders(headers) {
|
|
18410
|
-
if (!Array.isArray(headers)) {
|
|
18411
|
-
return void 0;
|
|
18412
|
-
}
|
|
18413
|
-
const forwarded = headers.reduce((acc, header) => {
|
|
18414
|
-
if (isOctWebSocketHeader(header)) {
|
|
18415
|
-
acc[header.name] = header.value;
|
|
18416
|
-
}
|
|
18417
|
-
return acc;
|
|
18418
|
-
}, {});
|
|
18419
|
-
return Object.keys(forwarded).length === 0 ? void 0 : forwarded;
|
|
18420
|
-
}
|
|
18421
|
-
function isOctWebSocketHeader(value) {
|
|
18422
|
-
return isHeader(value) && value.name.toLowerCase().startsWith("x-oct-");
|
|
18365
|
+
function defaultForwardTcpFactory(port) {
|
|
18366
|
+
return connectTcp({ host: "127.0.0.1", port });
|
|
18423
18367
|
}
|
|
18424
18368
|
function localForwardUrl(scheme, port, path2, queryString) {
|
|
18425
18369
|
const normalizedPath = path2.startsWith("/") ? path2 : `/${path2}`;
|
|
@@ -18429,12 +18373,6 @@ function localForwardUrl(scheme, port, path2, queryString) {
|
|
|
18429
18373
|
}
|
|
18430
18374
|
return url.toString();
|
|
18431
18375
|
}
|
|
18432
|
-
function localForwardWebSocketUrl(scheme, port, path2, queryString) {
|
|
18433
|
-
const httpScheme = scheme === "ws" ? "http" : "https";
|
|
18434
|
-
const url = new URL(localForwardUrl(httpScheme, port, path2, queryString));
|
|
18435
|
-
url.protocol = `${scheme}:`;
|
|
18436
|
-
return url.toString();
|
|
18437
|
-
}
|
|
18438
18376
|
async function fetchWithHttpsFallback(port, path2, queryString, request) {
|
|
18439
18377
|
try {
|
|
18440
18378
|
return await fetch(
|
|
@@ -21159,7 +21097,7 @@ function realpathOrResolved(pathValue) {
|
|
|
21159
21097
|
}
|
|
21160
21098
|
|
|
21161
21099
|
// src/version.ts
|
|
21162
|
-
var linzumiCliVersion = "0.0.
|
|
21100
|
+
var linzumiCliVersion = "0.0.56-beta";
|
|
21163
21101
|
var linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
|
|
21164
21102
|
|
|
21165
21103
|
// src/runnerLock.ts
|
|
@@ -21665,6 +21603,7 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
21665
21603
|
allowedCwds.value
|
|
21666
21604
|
),
|
|
21667
21605
|
portForwarding: liveForwardPorts.size > 0,
|
|
21606
|
+
tcpForwarding: true,
|
|
21668
21607
|
allowedPorts: Array.from(liveForwardPorts).sort(
|
|
21669
21608
|
(left, right) => left - right
|
|
21670
21609
|
),
|
|
@@ -22013,64 +21952,6 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
22013
21952
|
cleanup.actions.push(() => codex.close());
|
|
22014
21953
|
const seq = { value: 0 };
|
|
22015
21954
|
const discoveredCodexThreads = { value: [] };
|
|
22016
|
-
const lastReportedDiscoveryFailure = { value: void 0 };
|
|
22017
|
-
const reportClientError = async (args) => {
|
|
22018
|
-
await kandan.push(topic, "client_error_report", {
|
|
22019
|
-
id: `client-error-${randomUUID3()}`,
|
|
22020
|
-
severity: args.severity ?? "error",
|
|
22021
|
-
code: args.code,
|
|
22022
|
-
operation: args.operation,
|
|
22023
|
-
message: args.message,
|
|
22024
|
-
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22025
|
-
instanceId,
|
|
22026
|
-
clientId,
|
|
22027
|
-
runnerId: options.runnerId,
|
|
22028
|
-
hostname: runnerHost,
|
|
22029
|
-
cwd: options.cwd,
|
|
22030
|
-
codexUrl,
|
|
22031
|
-
workspace: runnerWorkspaceSlug(options) ?? null,
|
|
22032
|
-
channel: options.channelSession?.channelSlug ?? null,
|
|
22033
|
-
cliVersion: linzumiCliVersion,
|
|
22034
|
-
details: args.details ?? {}
|
|
22035
|
-
}).catch((error) => {
|
|
22036
|
-
log("kandan.client_error_report_push_failed", {
|
|
22037
|
-
code: args.code,
|
|
22038
|
-
operation: args.operation,
|
|
22039
|
-
message: error instanceof Error ? error.message : String(error)
|
|
22040
|
-
});
|
|
22041
|
-
});
|
|
22042
|
-
};
|
|
22043
|
-
const loadDiscoveredCodexThreads = async (phase) => {
|
|
22044
|
-
try {
|
|
22045
|
-
const threads = await discoverCodexThreads(codex, options.cwd);
|
|
22046
|
-
lastReportedDiscoveryFailure.value = void 0;
|
|
22047
|
-
return threads;
|
|
22048
|
-
} catch (error) {
|
|
22049
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
22050
|
-
const signature = `codex_thread_discovery_failed:${message}`;
|
|
22051
|
-
log("codex.thread_discovery_failed", {
|
|
22052
|
-
phase,
|
|
22053
|
-
message
|
|
22054
|
-
});
|
|
22055
|
-
if (lastReportedDiscoveryFailure.value !== signature) {
|
|
22056
|
-
lastReportedDiscoveryFailure.value = signature;
|
|
22057
|
-
await reportClientError({
|
|
22058
|
-
code: "codex_thread_discovery_failed",
|
|
22059
|
-
operation: "codex_thread_discovery",
|
|
22060
|
-
message,
|
|
22061
|
-
details: {
|
|
22062
|
-
phase,
|
|
22063
|
-
codexUrl,
|
|
22064
|
-
cwd: options.cwd
|
|
22065
|
-
}
|
|
22066
|
-
});
|
|
22067
|
-
}
|
|
22068
|
-
return discoveredCodexThreads.value;
|
|
22069
|
-
}
|
|
22070
|
-
};
|
|
22071
|
-
if (options.channelSession === void 0) {
|
|
22072
|
-
discoveredCodexThreads.value = await loadDiscoveredCodexThreads("initial");
|
|
22073
|
-
}
|
|
22074
21955
|
const runtimeDefaults = runnerRuntimeDefaults(options);
|
|
22075
21956
|
const instancePayload = {
|
|
22076
21957
|
instanceId,
|
|
@@ -22229,24 +22110,18 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
22229
22110
|
message: error instanceof Error ? error.message : String(error)
|
|
22230
22111
|
});
|
|
22231
22112
|
});
|
|
22232
|
-
const refreshDiscoveredCodexThreads = async (phase) => {
|
|
22233
|
-
discoveredCodexThreads.value = await loadDiscoveredCodexThreads(phase);
|
|
22234
|
-
await pushHeartbeat();
|
|
22235
|
-
};
|
|
22236
22113
|
const heartbeatInterval = setInterval(() => {
|
|
22237
|
-
void
|
|
22114
|
+
void pushHeartbeat();
|
|
22238
22115
|
}, 15e3);
|
|
22239
22116
|
cleanup.actions.push(() => clearInterval(heartbeatInterval));
|
|
22240
|
-
kandan.onReconnect(
|
|
22241
|
-
() => channelSession === void 0 ? refreshDiscoveredCodexThreads("reconnect").then(() => void 0) : pushHeartbeat().then(() => void 0)
|
|
22242
|
-
);
|
|
22117
|
+
kandan.onReconnect(() => pushHeartbeat().then(() => void 0));
|
|
22243
22118
|
void pushHeartbeat();
|
|
22244
|
-
const
|
|
22119
|
+
const forwardTcp = createForwardTcpManager(
|
|
22245
22120
|
kandan,
|
|
22246
22121
|
topic,
|
|
22247
22122
|
() => Array.from(liveForwardPorts)
|
|
22248
22123
|
);
|
|
22249
|
-
cleanup.actions.push(() =>
|
|
22124
|
+
cleanup.actions.push(() => forwardTcp.close());
|
|
22250
22125
|
const channelCodexThreadId = channelSession?.currentCodexThreadId();
|
|
22251
22126
|
if (options.launchTui && channelCodexThreadId !== void 0) {
|
|
22252
22127
|
await prepareCodexThreadForTuiResume(codex, channelCodexThreadId);
|
|
@@ -22282,9 +22157,6 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
22282
22157
|
});
|
|
22283
22158
|
});
|
|
22284
22159
|
}
|
|
22285
|
-
if (channelSession === void 0 && notification.method === "thread/started") {
|
|
22286
|
-
void refreshDiscoveredCodexThreads("thread_started");
|
|
22287
|
-
}
|
|
22288
22160
|
log("codex.notification", {
|
|
22289
22161
|
method: notification.method,
|
|
22290
22162
|
metadata
|
|
@@ -22343,8 +22215,8 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
22343
22215
|
});
|
|
22344
22216
|
return;
|
|
22345
22217
|
}
|
|
22346
|
-
if (
|
|
22347
|
-
|
|
22218
|
+
if (isForwardTcpControl(control)) {
|
|
22219
|
+
forwardTcp.handle(control);
|
|
22348
22220
|
return;
|
|
22349
22221
|
}
|
|
22350
22222
|
if (isStartLocalEditorControl(control)) {
|
|
@@ -22548,99 +22420,6 @@ async function closeCleanupStack(cleanup) {
|
|
|
22548
22420
|
})();
|
|
22549
22421
|
return cleanup.closePromise;
|
|
22550
22422
|
}
|
|
22551
|
-
async function discoverCodexThreads(codex, _cwd) {
|
|
22552
|
-
const response = await codex.request("thread/list", {
|
|
22553
|
-
limit: CODEX_THREAD_DISCOVERY_LIMIT,
|
|
22554
|
-
sortKey: "updated_at",
|
|
22555
|
-
sortDirection: "desc",
|
|
22556
|
-
archived: false,
|
|
22557
|
-
useStateDbOnly: true
|
|
22558
|
-
});
|
|
22559
|
-
if ("error" in response) {
|
|
22560
|
-
throw new Error(`thread/list failed: ${response.error.message}`);
|
|
22561
|
-
}
|
|
22562
|
-
const result = objectValue(response.result);
|
|
22563
|
-
const data = arrayValue(result?.data)?.filter(isJsonObject) ?? [];
|
|
22564
|
-
const rowsById = /* @__PURE__ */ new Map();
|
|
22565
|
-
for (const thread of data.slice(0, CODEX_THREAD_DISCOVERY_LIMIT)) {
|
|
22566
|
-
const row = codexThreadHistoryRow(thread, false);
|
|
22567
|
-
const id = stringValue(objectValue(row)?.id);
|
|
22568
|
-
if (id !== void 0 && id !== "" && !rowsById.has(id)) {
|
|
22569
|
-
rowsById.set(id, row);
|
|
22570
|
-
}
|
|
22571
|
-
}
|
|
22572
|
-
return Array.from(rowsById.values()).sort(compareCodexThreadHistoryRows);
|
|
22573
|
-
}
|
|
22574
|
-
var CODEX_THREAD_DISCOVERY_LIMIT = 50;
|
|
22575
|
-
var CODEX_THREAD_TITLE_FIELD_LIMIT = 500;
|
|
22576
|
-
var CODEX_THREAD_TEXT_FIELD_LIMIT = 2e3;
|
|
22577
|
-
var CODEX_THREAD_PATH_FIELD_LIMIT = 1e3;
|
|
22578
|
-
function codexThreadHistoryRow(thread, archived) {
|
|
22579
|
-
const gitInfo = objectValue(thread.gitInfo);
|
|
22580
|
-
const preview = codexThreadText(thread.preview, CODEX_THREAD_TEXT_FIELD_LIMIT).replace(/\s+/g, " ").trim();
|
|
22581
|
-
const name = codexThreadText(thread.name, CODEX_THREAD_TITLE_FIELD_LIMIT);
|
|
22582
|
-
const directTitle = codexThreadText(
|
|
22583
|
-
thread.title,
|
|
22584
|
-
CODEX_THREAD_TITLE_FIELD_LIMIT
|
|
22585
|
-
);
|
|
22586
|
-
const title = directTitle === "" ? name === "" ? preview : name : directTitle;
|
|
22587
|
-
const description = codexThreadText(thread.description, CODEX_THREAD_TEXT_FIELD_LIMIT) || codexThreadText(thread.summary, CODEX_THREAD_TEXT_FIELD_LIMIT) || preview;
|
|
22588
|
-
return {
|
|
22589
|
-
id: codexThreadText(thread.id, CODEX_THREAD_PATH_FIELD_LIMIT),
|
|
22590
|
-
title: title ?? "",
|
|
22591
|
-
description: description ?? "",
|
|
22592
|
-
preview,
|
|
22593
|
-
cwd: codexThreadText(thread.cwd, CODEX_THREAD_PATH_FIELD_LIMIT),
|
|
22594
|
-
source: codexThreadText(thread.source, CODEX_THREAD_TITLE_FIELD_LIMIT),
|
|
22595
|
-
createdAt: codexTimestamp(thread.createdAt),
|
|
22596
|
-
updatedAt: codexTimestamp(thread.updatedAt),
|
|
22597
|
-
archived,
|
|
22598
|
-
modelProvider: codexThreadText(
|
|
22599
|
-
thread.modelProvider,
|
|
22600
|
-
CODEX_THREAD_TITLE_FIELD_LIMIT
|
|
22601
|
-
),
|
|
22602
|
-
cliVersion: codexThreadText(
|
|
22603
|
-
thread.cliVersion,
|
|
22604
|
-
CODEX_THREAD_TITLE_FIELD_LIMIT
|
|
22605
|
-
),
|
|
22606
|
-
gitBranch: codexThreadText(
|
|
22607
|
-
gitInfo?.branch,
|
|
22608
|
-
CODEX_THREAD_TITLE_FIELD_LIMIT
|
|
22609
|
-
),
|
|
22610
|
-
gitOriginUrl: codexThreadText(
|
|
22611
|
-
gitInfo?.originUrl,
|
|
22612
|
-
CODEX_THREAD_PATH_FIELD_LIMIT
|
|
22613
|
-
),
|
|
22614
|
-
path: codexThreadText(thread.path, CODEX_THREAD_PATH_FIELD_LIMIT)
|
|
22615
|
-
};
|
|
22616
|
-
}
|
|
22617
|
-
function codexThreadText(value, maxLength) {
|
|
22618
|
-
const text2 = stringValue(value) ?? "";
|
|
22619
|
-
if (text2.length <= maxLength) {
|
|
22620
|
-
return text2;
|
|
22621
|
-
}
|
|
22622
|
-
return `${text2.slice(0, Math.max(0, maxLength - 3))}...`;
|
|
22623
|
-
}
|
|
22624
|
-
function codexTimestamp(value) {
|
|
22625
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
22626
|
-
return new Date(value * 1e3).toISOString();
|
|
22627
|
-
}
|
|
22628
|
-
return stringValue(value) ?? "";
|
|
22629
|
-
}
|
|
22630
|
-
function compareCodexThreadHistoryRows(left, right) {
|
|
22631
|
-
const leftRow = objectValue(left);
|
|
22632
|
-
const rightRow = objectValue(right);
|
|
22633
|
-
const leftTime = Date.parse(
|
|
22634
|
-
stringValue(leftRow?.createdAt) ?? stringValue(leftRow?.updatedAt) ?? ""
|
|
22635
|
-
);
|
|
22636
|
-
const rightTime = Date.parse(
|
|
22637
|
-
stringValue(rightRow?.createdAt) ?? stringValue(rightRow?.updatedAt) ?? ""
|
|
22638
|
-
);
|
|
22639
|
-
return safeComparableTime(leftTime) - safeComparableTime(rightTime);
|
|
22640
|
-
}
|
|
22641
|
-
function safeComparableTime(value) {
|
|
22642
|
-
return Number.isFinite(value) ? value : Number.MAX_SAFE_INTEGER;
|
|
22643
|
-
}
|
|
22644
22423
|
function extractStartedThreadId(response) {
|
|
22645
22424
|
if ("error" in response) {
|
|
22646
22425
|
throw new Error(`thread/start failed: ${response.error.message}`);
|
|
@@ -23023,9 +22802,9 @@ async function applyControl(codex, kandan, topic, instanceId, options, allowedCw
|
|
|
23023
22802
|
case "update_session_settings":
|
|
23024
22803
|
case "set_port_forward_enabled":
|
|
23025
22804
|
case "forward_http_request":
|
|
23026
|
-
case "
|
|
23027
|
-
case "
|
|
23028
|
-
case "
|
|
22805
|
+
case "forward_tcp_open":
|
|
22806
|
+
case "forward_tcp_send":
|
|
22807
|
+
case "forward_tcp_close":
|
|
23029
22808
|
case "start_local_editor":
|
|
23030
22809
|
case "update_runner_config":
|
|
23031
22810
|
return { instanceId, controlType: control.type, skipped: true };
|
|
@@ -27278,6 +27057,16 @@ import { stdin as defaultStdin, stdout as defaultStdout } from "node:process";
|
|
|
27278
27057
|
import { emitKeypressEvents } from "node:readline";
|
|
27279
27058
|
|
|
27280
27059
|
// src/signupServerClient.ts
|
|
27060
|
+
var SignupServerError = class extends Error {
|
|
27061
|
+
status;
|
|
27062
|
+
code;
|
|
27063
|
+
constructor(args) {
|
|
27064
|
+
super(args.message);
|
|
27065
|
+
this.name = "SignupServerError";
|
|
27066
|
+
this.status = args.status;
|
|
27067
|
+
this.code = args.code;
|
|
27068
|
+
}
|
|
27069
|
+
};
|
|
27281
27070
|
function createSignupServerClient(args) {
|
|
27282
27071
|
const serviceUrl = args.serviceUrl ?? defaultLinzumiHttpUrl;
|
|
27283
27072
|
const fetchImpl = args.fetchImpl ?? fetch;
|
|
@@ -27368,9 +27157,7 @@ async function signupJsonRequest(args) {
|
|
|
27368
27157
|
});
|
|
27369
27158
|
const responseText = await response.text();
|
|
27370
27159
|
if (!response.ok) {
|
|
27371
|
-
throw
|
|
27372
|
-
`Linzumi signup request failed with HTTP ${response.status}${errorResponseDetail(responseText)}`
|
|
27373
|
-
);
|
|
27160
|
+
throw signupResponseError(response.status, responseText);
|
|
27374
27161
|
}
|
|
27375
27162
|
const body = parseJsonResponse(responseText, "Linzumi signup response");
|
|
27376
27163
|
return args.render(body);
|
|
@@ -27389,6 +27176,38 @@ function errorResponseDetail(text2) {
|
|
|
27389
27176
|
}
|
|
27390
27177
|
return `: ${trimmed.slice(0, 240)}`;
|
|
27391
27178
|
}
|
|
27179
|
+
function signupResponseError(status, text2) {
|
|
27180
|
+
const code = signupErrorCodeFromResponseText(text2);
|
|
27181
|
+
if (code !== void 0) {
|
|
27182
|
+
return new SignupServerError({
|
|
27183
|
+
status,
|
|
27184
|
+
code,
|
|
27185
|
+
message: code
|
|
27186
|
+
});
|
|
27187
|
+
}
|
|
27188
|
+
return new Error(
|
|
27189
|
+
`Linzumi signup request failed with HTTP ${status}${errorResponseDetail(text2)}`
|
|
27190
|
+
);
|
|
27191
|
+
}
|
|
27192
|
+
function signupErrorCodeFromResponseText(text2) {
|
|
27193
|
+
const trimmed = text2.trim();
|
|
27194
|
+
if (trimmed === "") {
|
|
27195
|
+
return void 0;
|
|
27196
|
+
}
|
|
27197
|
+
try {
|
|
27198
|
+
const value = JSON.parse(trimmed);
|
|
27199
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
27200
|
+
return void 0;
|
|
27201
|
+
}
|
|
27202
|
+
const error = value.error;
|
|
27203
|
+
if (typeof error === "string" && error.trim() !== "") {
|
|
27204
|
+
return error;
|
|
27205
|
+
}
|
|
27206
|
+
return void 0;
|
|
27207
|
+
} catch (_error) {
|
|
27208
|
+
return void 0;
|
|
27209
|
+
}
|
|
27210
|
+
}
|
|
27392
27211
|
function renderEmailCodeStart(value) {
|
|
27393
27212
|
const body = objectRecord(value, "signup email-code start response");
|
|
27394
27213
|
return {
|
|
@@ -27576,6 +27395,7 @@ function booleanValue(record, key) {
|
|
|
27576
27395
|
}
|
|
27577
27396
|
|
|
27578
27397
|
// src/signupFlow.ts
|
|
27398
|
+
var maxSignupVerificationCodeAttempts = 3;
|
|
27579
27399
|
var blue = (value) => `\x1B[38;5;75m${value}\x1B[0m`;
|
|
27580
27400
|
var green = (value) => `\x1B[38;5;114m${value}\x1B[0m`;
|
|
27581
27401
|
var red = (value) => `\x1B[38;5;203m${value}\x1B[0m`;
|
|
@@ -28108,22 +27928,19 @@ async function runSignupFlow(deps = {}) {
|
|
|
28108
27928
|
writeDebugLaunchPayload(output, state, debugLaunchPayload);
|
|
28109
27929
|
return;
|
|
28110
27930
|
}
|
|
28111
|
-
|
|
28112
|
-
|
|
28113
|
-
|
|
28114
|
-
|
|
28115
|
-
});
|
|
28116
|
-
const verifyResult = signupServerClient === void 0 ? void 0 : await verifyEmailCodeForSignup(signupServerClient, {
|
|
27931
|
+
const verificationResult = await promptForVerifiedEmailCode({
|
|
27932
|
+
prompts,
|
|
27933
|
+
output,
|
|
27934
|
+
signupServerClient,
|
|
28117
27935
|
pendingId: codeRequest.request.pendingId,
|
|
28118
|
-
|
|
27936
|
+
email: codeRequest.request.email
|
|
28119
27937
|
});
|
|
28120
|
-
if (
|
|
27938
|
+
if (verificationResult.type === "failed") {
|
|
28121
27939
|
state = updateSignupState(state, {
|
|
28122
27940
|
currentStep: "launch",
|
|
28123
|
-
verificationCode: code,
|
|
28124
|
-
launchFailure:
|
|
27941
|
+
verificationCode: verificationResult.code,
|
|
27942
|
+
launchFailure: verificationResult.message
|
|
28125
27943
|
});
|
|
28126
|
-
writeCodeEntry(output, code);
|
|
28127
27944
|
writeSignupScreen(output, state);
|
|
28128
27945
|
writePreflightSummary(output, state);
|
|
28129
27946
|
writeSelectedProjectsSummary(output, state);
|
|
@@ -28132,14 +27949,13 @@ async function runSignupFlow(deps = {}) {
|
|
|
28132
27949
|
writeDebugLaunchPayload(output, state, debugLaunchPayload);
|
|
28133
27950
|
return;
|
|
28134
27951
|
}
|
|
28135
|
-
verifiedAuth =
|
|
27952
|
+
verifiedAuth = verificationResult.verifiedAuth;
|
|
28136
27953
|
const storedSignupAuth = verifiedAuth === void 0 ? writeSignupAuth({ email }) : signupAuthFromVerification(verifiedAuth, serviceUrl);
|
|
28137
27954
|
state = updateSignupState(state, {
|
|
28138
27955
|
currentStep: "launch",
|
|
28139
27956
|
storedSignupAuth,
|
|
28140
|
-
verificationCode: code
|
|
27957
|
+
verificationCode: verificationResult.code
|
|
28141
27958
|
});
|
|
28142
|
-
writeCodeEntry(output, code);
|
|
28143
27959
|
}
|
|
28144
27960
|
if (signupServerClient !== void 0 && verifiedAuth !== void 0) {
|
|
28145
27961
|
const defaultWorkspaceName = verifiedAuth.privateWorkspaceDefault.name || defaultWorkspaceNameForEmail(
|
|
@@ -28335,7 +28151,8 @@ async function verifyEmailCodeForSignup(signupServerClient, args) {
|
|
|
28335
28151
|
message: signupServerFailureMessage(
|
|
28336
28152
|
"We couldn't verify your Linzumi email code",
|
|
28337
28153
|
error
|
|
28338
|
-
)
|
|
28154
|
+
),
|
|
28155
|
+
code: signupServerFailureCode(error)
|
|
28339
28156
|
};
|
|
28340
28157
|
}
|
|
28341
28158
|
}
|
|
@@ -28343,6 +28160,43 @@ function signupServerFailureMessage(prefix, error) {
|
|
|
28343
28160
|
const message = error instanceof Error ? error.message : String(error);
|
|
28344
28161
|
return `${prefix}: ${message}`;
|
|
28345
28162
|
}
|
|
28163
|
+
function signupServerFailureCode(error) {
|
|
28164
|
+
if (error instanceof SignupServerError) {
|
|
28165
|
+
return error.code;
|
|
28166
|
+
}
|
|
28167
|
+
if (error instanceof Error && error.message === "invalid_signup_code") {
|
|
28168
|
+
return "invalid_signup_code";
|
|
28169
|
+
}
|
|
28170
|
+
return void 0;
|
|
28171
|
+
}
|
|
28172
|
+
async function promptForVerifiedEmailCode(args) {
|
|
28173
|
+
writeVerificationPrompt(args.output, args.email);
|
|
28174
|
+
return verifyPromptAttempt(args, 1);
|
|
28175
|
+
}
|
|
28176
|
+
async function verifyPromptAttempt(args, attempt) {
|
|
28177
|
+
const code = await args.prompts.input({
|
|
28178
|
+
message: "Enter your Linzumi verification code",
|
|
28179
|
+
defaultValue: args.signupServerClient === void 0 ? "482931" : ""
|
|
28180
|
+
});
|
|
28181
|
+
const verifyResult = args.signupServerClient === void 0 ? void 0 : await verifyEmailCodeForSignup(args.signupServerClient, {
|
|
28182
|
+
pendingId: args.pendingId,
|
|
28183
|
+
code
|
|
28184
|
+
});
|
|
28185
|
+
writeCodeEntry(args.output, code);
|
|
28186
|
+
if (verifyResult?.type === "failed") {
|
|
28187
|
+
if (verifyResult.code === "invalid_signup_code" && attempt < maxSignupVerificationCodeAttempts) {
|
|
28188
|
+
writeBoundedLine(
|
|
28189
|
+
args.output,
|
|
28190
|
+
muted(
|
|
28191
|
+
" That code was not valid. Enter the newest 6-digit code from your email."
|
|
28192
|
+
)
|
|
28193
|
+
);
|
|
28194
|
+
return verifyPromptAttempt(args, attempt + 1);
|
|
28195
|
+
}
|
|
28196
|
+
return { type: "failed", message: verifyResult.message, code };
|
|
28197
|
+
}
|
|
28198
|
+
return verifyResult === void 0 ? { type: "completed", code } : { type: "completed", code, verifiedAuth: verifyResult.auth };
|
|
28199
|
+
}
|
|
28346
28200
|
async function refreshExistingSignupAuth(prompts, output, auth, writeSignupAuth, signupServerClient, serviceUrl) {
|
|
28347
28201
|
output.write(
|
|
28348
28202
|
`${green("\u2713")} You're already logged in!
|
|
@@ -28361,25 +28215,29 @@ ${muted(
|
|
|
28361
28215
|
if (codeRequest.type === "failed") {
|
|
28362
28216
|
return codeRequest;
|
|
28363
28217
|
}
|
|
28364
|
-
|
|
28365
|
-
|
|
28366
|
-
|
|
28367
|
-
|
|
28368
|
-
});
|
|
28369
|
-
const verifyResult = signupServerClient === void 0 ? void 0 : await verifyEmailCodeForSignup(signupServerClient, {
|
|
28218
|
+
const verificationResult = await promptForVerifiedEmailCode({
|
|
28219
|
+
prompts,
|
|
28220
|
+
output,
|
|
28221
|
+
signupServerClient,
|
|
28370
28222
|
pendingId: codeRequest.request.pendingId,
|
|
28371
|
-
|
|
28223
|
+
email: codeRequest.request.email
|
|
28372
28224
|
});
|
|
28373
|
-
if (
|
|
28374
|
-
writeCodeEntry(output, code);
|
|
28225
|
+
if (verificationResult.type === "failed") {
|
|
28375
28226
|
output.write("\n");
|
|
28376
|
-
return
|
|
28227
|
+
return {
|
|
28228
|
+
type: "failed",
|
|
28229
|
+
message: verificationResult.message
|
|
28230
|
+
};
|
|
28377
28231
|
}
|
|
28378
|
-
const verifiedAuth =
|
|
28232
|
+
const verifiedAuth = verificationResult.verifiedAuth;
|
|
28379
28233
|
const refreshedAuth = verifiedAuth === void 0 ? writeSignupAuth({ email: auth.email }) : signupAuthFromVerification(verifiedAuth, serviceUrl);
|
|
28380
|
-
writeCodeEntry(output, code);
|
|
28381
28234
|
output.write("\n");
|
|
28382
|
-
return {
|
|
28235
|
+
return {
|
|
28236
|
+
type: "completed",
|
|
28237
|
+
auth: refreshedAuth,
|
|
28238
|
+
code: verificationResult.code,
|
|
28239
|
+
verifiedAuth
|
|
28240
|
+
};
|
|
28383
28241
|
}
|
|
28384
28242
|
async function validateExistingSignupAuth(signupServerClient, auth, retryPolicy) {
|
|
28385
28243
|
if (signupServerClient === void 0 || auth.accessToken === void 0) {
|
|
@@ -30251,7 +30109,7 @@ function runProcessCapture(args) {
|
|
|
30251
30109
|
child.on("error", () => {
|
|
30252
30110
|
finish("");
|
|
30253
30111
|
});
|
|
30254
|
-
child.on("
|
|
30112
|
+
child.on("close", (code) => {
|
|
30255
30113
|
finish(code === 0 ? stdout : "");
|
|
30256
30114
|
});
|
|
30257
30115
|
});
|
package/package.json
CHANGED