@linzumi/cli 0.0.100-beta → 0.0.102-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 +58 -5
- package/package.json +2 -2
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -3361,7 +3361,8 @@ async function connectPhoenixClient(baseUrl, token, socketFactory = (url, protoc
|
|
|
3361
3361
|
resolveReady: void 0,
|
|
3362
3362
|
rejectReady: void 0,
|
|
3363
3363
|
reconnectTimer: void 0,
|
|
3364
|
-
reconnectAttempts: 0
|
|
3364
|
+
reconnectAttempts: 0,
|
|
3365
|
+
heartbeatTimer: void 0
|
|
3365
3366
|
};
|
|
3366
3367
|
const pushTimeoutMs = options.pushTimeoutMs ?? defaultPushTimeoutMs;
|
|
3367
3368
|
const controlCursorStore = options.controlCursorStore;
|
|
@@ -3751,6 +3752,7 @@ async function connectPhoenixClient(baseUrl, token, socketFactory = (url, protoc
|
|
|
3751
3752
|
state.connected = false;
|
|
3752
3753
|
const websocket = state.websocket;
|
|
3753
3754
|
state.websocket = void 0;
|
|
3755
|
+
stopHeartbeat();
|
|
3754
3756
|
if (websocket !== void 0 && (websocket.readyState === WebSocket.CONNECTING || websocket.readyState === WebSocket.OPEN)) {
|
|
3755
3757
|
try {
|
|
3756
3758
|
websocket.close();
|
|
@@ -3768,6 +3770,29 @@ async function connectPhoenixClient(baseUrl, token, socketFactory = (url, protoc
|
|
|
3768
3770
|
});
|
|
3769
3771
|
}
|
|
3770
3772
|
};
|
|
3773
|
+
const HEARTBEAT_INTERVAL_MS = 3e4;
|
|
3774
|
+
const stopHeartbeat = () => {
|
|
3775
|
+
if (state.heartbeatTimer !== void 0) {
|
|
3776
|
+
clearInterval(state.heartbeatTimer);
|
|
3777
|
+
state.heartbeatTimer = void 0;
|
|
3778
|
+
}
|
|
3779
|
+
};
|
|
3780
|
+
const startHeartbeat = () => {
|
|
3781
|
+
stopHeartbeat();
|
|
3782
|
+
state.heartbeatTimer = setInterval(() => {
|
|
3783
|
+
const websocket = state.websocket;
|
|
3784
|
+
if (websocket === void 0 || websocket.readyState !== WebSocket.OPEN) {
|
|
3785
|
+
return;
|
|
3786
|
+
}
|
|
3787
|
+
const ref = String(state.nextRef);
|
|
3788
|
+
state.nextRef += 1;
|
|
3789
|
+
try {
|
|
3790
|
+
websocket.send(JSON.stringify([null, ref, "phoenix", "heartbeat", {}]));
|
|
3791
|
+
} catch {
|
|
3792
|
+
}
|
|
3793
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
3794
|
+
state.heartbeatTimer.unref?.();
|
|
3795
|
+
};
|
|
3771
3796
|
const openSocket = async () => {
|
|
3772
3797
|
if (state.closed) {
|
|
3773
3798
|
return;
|
|
@@ -3803,6 +3828,7 @@ async function connectPhoenixClient(baseUrl, token, socketFactory = (url, protoc
|
|
|
3803
3828
|
state.connected = true;
|
|
3804
3829
|
state.hasEverConnected = true;
|
|
3805
3830
|
state.reconnectAttempts = 0;
|
|
3831
|
+
startHeartbeat();
|
|
3806
3832
|
markReady();
|
|
3807
3833
|
if (state.connectionGeneration > 1) {
|
|
3808
3834
|
reconnectCallbacks.forEach((callback) => {
|
|
@@ -19803,7 +19829,7 @@ var linzumiCliVersion, linzumiCliVersionText;
|
|
|
19803
19829
|
var init_version = __esm({
|
|
19804
19830
|
"src/version.ts"() {
|
|
19805
19831
|
"use strict";
|
|
19806
|
-
linzumiCliVersion = "0.0.
|
|
19832
|
+
linzumiCliVersion = "0.0.102-beta";
|
|
19807
19833
|
linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
|
|
19808
19834
|
}
|
|
19809
19835
|
});
|
|
@@ -21076,6 +21102,8 @@ function rateLimitSummaryKey(summary) {
|
|
|
21076
21102
|
}
|
|
21077
21103
|
function formatRunnerConsoleEvent(event, payload) {
|
|
21078
21104
|
switch (event) {
|
|
21105
|
+
case "runner.starting":
|
|
21106
|
+
return runnerWelcomeLine;
|
|
21079
21107
|
case "runner.instance_started":
|
|
21080
21108
|
return connectedRunnerMessage(payload);
|
|
21081
21109
|
case "runner.replaced":
|
|
@@ -22017,11 +22045,12 @@ function stringValue5(value) {
|
|
|
22017
22045
|
function numberValue(value) {
|
|
22018
22046
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
22019
22047
|
}
|
|
22020
|
-
var dashboardState, maxRawLines, escapeKey, ctrlCKey, enterKey, upKey, downKey, dashboardTableColumns, runnerWelcomeHeaderLines, runnerWelcomeCompactHeaderLines, minimumVisibleTuiTableRows, redrawScreen, keyboardState, tickerState, tuiState;
|
|
22048
|
+
var dashboardState, maxRawLines, escapeKey, ctrlCKey, enterKey, upKey, downKey, dashboardTableColumns, runnerWelcomeLine, runnerWelcomeHeaderLines, runnerWelcomeCompactHeaderLines, minimumVisibleTuiTableRows, redrawScreen, keyboardState, tickerState, tuiState;
|
|
22021
22049
|
var init_runnerConsoleReporter = __esm({
|
|
22022
22050
|
"src/runnerConsoleReporter.ts"() {
|
|
22023
22051
|
"use strict";
|
|
22024
22052
|
init_blessedTputSetulcShim();
|
|
22053
|
+
init_version();
|
|
22025
22054
|
dashboardState = {
|
|
22026
22055
|
jobs: /* @__PURE__ */ new Map(),
|
|
22027
22056
|
discovery: /* @__PURE__ */ new Map(),
|
|
@@ -22055,6 +22084,7 @@ var init_runnerConsoleReporter = __esm({
|
|
|
22055
22084
|
{ width: 12 },
|
|
22056
22085
|
{ width: 24 }
|
|
22057
22086
|
];
|
|
22087
|
+
runnerWelcomeLine = `Welcome to the Linzumi runner (version ${linzumiCliVersion}).`;
|
|
22058
22088
|
runnerWelcomeHeaderLines = [
|
|
22059
22089
|
"\u2593\u2593\u2557 \u2593\u2593\u2557\u2593\u2593\u2593\u2557 \u2593\u2593\u2557\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2557\u2593\u2593\u2557 \u2593\u2593\u2557\u2593\u2593\u2593\u2557 \u2593\u2593\u2593\u2557\u2593\u2593\u2557",
|
|
22060
22090
|
"\u2593\u2593\u2551 \u2593\u2593\u2551\u2593\u2593\u2593\u2593\u2557 \u2593\u2593\u2551\u255A\u2550\u2550\u2593\u2593\u2593\u2554\u255D\u2593\u2593\u2551 \u2593\u2593\u2551\u2593\u2593\u2593\u2593\u2557 \u2593\u2593\u2593\u2593\u2551\u2593\u2593\u2551",
|
|
@@ -22071,7 +22101,7 @@ var init_runnerConsoleReporter = __esm({
|
|
|
22071
22101
|
" \u2551\u2551 \"/` ___ ;_________\u2551\u2551_.'",
|
|
22072
22102
|
" \u2551\u2551 ` ^^ ^^ \u2551\u2551",
|
|
22073
22103
|
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2568\u2568\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\xB7\xB7\u2500\u2500\u2500\u2500\xB7\xB7\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2568\u2568\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
22074
|
-
|
|
22104
|
+
runnerWelcomeLine,
|
|
22075
22105
|
"Codex is running on this computer and connected to Linzumi.",
|
|
22076
22106
|
"Active Codex and Claude Code jobs appear below as they run.",
|
|
22077
22107
|
"You can return to the Linzumi app now."
|
|
@@ -22080,7 +22110,7 @@ var init_runnerConsoleReporter = __esm({
|
|
|
22080
22110
|
"\u2593\u2593\u2557 LINZUMI RUNNER \u2593\u2593\u2557",
|
|
22081
22111
|
"\u2551\u2551 ()-().----. \u2551\u2551",
|
|
22082
22112
|
"\u2568\u2568\u2500\u2500 connected to Codex and Linzumi \u2500\u2500\u2568\u2568",
|
|
22083
|
-
|
|
22113
|
+
runnerWelcomeLine,
|
|
22084
22114
|
"Codex is running on this computer and connected to Linzumi.",
|
|
22085
22115
|
"Active Codex and Claude Code jobs appear below as they run.",
|
|
22086
22116
|
"You can return to the Linzumi app now."
|
|
@@ -24730,6 +24760,7 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
24730
24760
|
);
|
|
24731
24761
|
threadRunnerProcesses.clear();
|
|
24732
24762
|
});
|
|
24763
|
+
const threadModelProviderBindings = /* @__PURE__ */ new Map();
|
|
24733
24764
|
const threadRebuildSerializer = createThreadRebuildSerializer();
|
|
24734
24765
|
const evictStaleDynamicChannelSession = async (codexThreadId, expectClient) => {
|
|
24735
24766
|
const session = dynamicChannelSessions.get(codexThreadId);
|
|
@@ -24817,6 +24848,16 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
24817
24848
|
rebuildArgs.codexThreadId
|
|
24818
24849
|
);
|
|
24819
24850
|
let rebuilt = false;
|
|
24851
|
+
const rebuildProviderBinding = threadModelProviderBindings.get(
|
|
24852
|
+
rebuildArgs.kandanThreadId
|
|
24853
|
+
) ?? // Belt-and-suspenders: if the persisted map missed this thread
|
|
24854
|
+
// but the in-scope establishing `control` still carries the
|
|
24855
|
+
// provider (the server now re-injects it on reconnect_thread),
|
|
24856
|
+
// forward that directly so the rebuild never strands a wafer turn.
|
|
24857
|
+
(control.modelProvider !== void 0 || control.llmProxy !== void 0 ? {
|
|
24858
|
+
...control.modelProvider === void 0 ? {} : { modelProvider: control.modelProvider },
|
|
24859
|
+
...control.llmProxy === void 0 ? {} : { llmProxy: control.llmProxy }
|
|
24860
|
+
} : void 0);
|
|
24820
24861
|
for (const message of rebuildArgs.pendingMessages) {
|
|
24821
24862
|
const reconnectControl = {
|
|
24822
24863
|
type: "reconnect_thread",
|
|
@@ -24831,6 +24872,12 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
24831
24872
|
// control built above at channelSession.linzumiContext).
|
|
24832
24873
|
...control.linzumiContext === void 0 ? {} : { linzumiContext: control.linzumiContext },
|
|
24833
24874
|
...integerValue(control.rootSeq) === void 0 ? {} : { rootSeq: integerValue(control.rootSeq) },
|
|
24875
|
+
// RESUME-CRITICAL: replay the persisted model-provider binding
|
|
24876
|
+
// (the in-scope `control` is a reconnect_thread that no longer
|
|
24877
|
+
// carries it) so the respawned wafer/GLM worker can load the
|
|
24878
|
+
// `linzumi` provider and resume instead of stranding the turn.
|
|
24879
|
+
...rebuildProviderBinding?.modelProvider === void 0 ? {} : { modelProvider: rebuildProviderBinding.modelProvider },
|
|
24880
|
+
...rebuildProviderBinding?.llmProxy === void 0 ? {} : { llmProxy: rebuildProviderBinding.llmProxy },
|
|
24834
24881
|
sourceSeq: message.seq,
|
|
24835
24882
|
workDescription: message.body,
|
|
24836
24883
|
...runtimeSettings.model === void 0 ? {} : { model: runtimeSettings.model },
|
|
@@ -25092,6 +25139,12 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
25092
25139
|
return void 0;
|
|
25093
25140
|
}
|
|
25094
25141
|
const providerResolution = resolveControlCodexModelProvider(control);
|
|
25142
|
+
if (control.modelProvider !== void 0 || control.llmProxy !== void 0) {
|
|
25143
|
+
threadModelProviderBindings.set(kandanThreadId, {
|
|
25144
|
+
...control.modelProvider === void 0 ? {} : { modelProvider: control.modelProvider },
|
|
25145
|
+
...control.llmProxy === void 0 ? {} : { llmProxy: control.llmProxy }
|
|
25146
|
+
});
|
|
25147
|
+
}
|
|
25095
25148
|
const providerResolutionError = codexModelProviderResolutionError(providerResolution);
|
|
25096
25149
|
if (providerResolutionError !== void 0) {
|
|
25097
25150
|
return {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linzumi/cli",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Linzumi CLI
|
|
3
|
+
"version": "0.0.102-beta",
|
|
4
|
+
"description": "Linzumi CLI \u2014 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": {
|
|
7
7
|
"linzumi": "bin/linzumi.js"
|