@linzumi/cli 0.0.28-beta → 0.0.30-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 +2 -2
- package/dist/index.js +85 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ codex \
|
|
|
26
26
|
-c sandbox_workspace_write.network_access=true \
|
|
27
27
|
--ask-for-approval never \
|
|
28
28
|
--sandbox danger-full-access \
|
|
29
|
-
-- 'Follow https://linzumi.com/agents.md to get me "wow"'
|
|
29
|
+
-- 'Follow https://linzumi.com/agents.md to get me to "wow"'
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
That's the launch path: the first Codex is only the bootstrapper. It
|
|
@@ -293,7 +293,7 @@ intentionally. Every action is auditable from the thread.
|
|
|
293
293
|
## Pinning a version
|
|
294
294
|
|
|
295
295
|
```bash
|
|
296
|
-
npm install -g @linzumi/cli@0.0.
|
|
296
|
+
npm install -g @linzumi/cli@0.0.30-beta
|
|
297
297
|
linzumi --version
|
|
298
298
|
```
|
|
299
299
|
|
package/dist/index.js
CHANGED
|
@@ -6622,6 +6622,60 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
6622
6622
|
cleanup.actions.push(() => channelSession.close());
|
|
6623
6623
|
kandan.onReconnect(() => channelSession.handleKandanReconnect());
|
|
6624
6624
|
}
|
|
6625
|
+
const dynamicChannelSessions = new Map;
|
|
6626
|
+
cleanup.actions.push(async () => {
|
|
6627
|
+
await Promise.all(Array.from(dynamicChannelSessions.values(), (session) => session.close()));
|
|
6628
|
+
dynamicChannelSessions.clear();
|
|
6629
|
+
});
|
|
6630
|
+
const attachStartedThreadSession = async (control, cwd) => {
|
|
6631
|
+
const workspaceSlug = normalizedWorkDescription(control.workspace);
|
|
6632
|
+
const channelSlug = normalizedWorkDescription(control.channel);
|
|
6633
|
+
const kandanThreadId = normalizedWorkDescription(control.threadId);
|
|
6634
|
+
if (workspaceSlug === undefined || channelSlug === undefined || kandanThreadId === undefined || dynamicChannelSessions.has(kandanThreadId)) {
|
|
6635
|
+
return;
|
|
6636
|
+
}
|
|
6637
|
+
const listenUser = options.channelSession?.listenUser ?? identityFromAccessToken(options.token).actorUsername;
|
|
6638
|
+
if (listenUser === undefined) {
|
|
6639
|
+
throw new Error("missing listen user for Commander-started Codex session");
|
|
6640
|
+
}
|
|
6641
|
+
const session = await attachChannelSession({
|
|
6642
|
+
kandan,
|
|
6643
|
+
codex,
|
|
6644
|
+
topic,
|
|
6645
|
+
instanceId,
|
|
6646
|
+
options: {
|
|
6647
|
+
token: options.token,
|
|
6648
|
+
runnerId: options.runnerId,
|
|
6649
|
+
cwd,
|
|
6650
|
+
codexBin: options.codexBin,
|
|
6651
|
+
fast: control.fast ?? options.fast,
|
|
6652
|
+
launchTui: false,
|
|
6653
|
+
enablePortForwardWatch: true,
|
|
6654
|
+
initialForwardPorts: allowedForwardPorts,
|
|
6655
|
+
suppressedForwardPorts: () => Array.from(managedForwardPorts),
|
|
6656
|
+
onForwardPortApproved: (port) => {
|
|
6657
|
+
liveForwardPorts.add(port);
|
|
6658
|
+
return capabilitiesPayload();
|
|
6659
|
+
},
|
|
6660
|
+
onForwardPortRevoked: (port) => {
|
|
6661
|
+
liveForwardPorts.delete(port);
|
|
6662
|
+
return capabilitiesPayload();
|
|
6663
|
+
},
|
|
6664
|
+
channelSession: {
|
|
6665
|
+
workspaceSlug,
|
|
6666
|
+
channelSlug,
|
|
6667
|
+
kandanThreadId,
|
|
6668
|
+
listenUser,
|
|
6669
|
+
model: control.model,
|
|
6670
|
+
reasoningEffort: control.reasoningEffort,
|
|
6671
|
+
sandbox: control.sandbox,
|
|
6672
|
+
approvalPolicy: control.approvalPolicy
|
|
6673
|
+
}
|
|
6674
|
+
},
|
|
6675
|
+
log
|
|
6676
|
+
});
|
|
6677
|
+
dynamicChannelSessions.set(kandanThreadId, session);
|
|
6678
|
+
};
|
|
6625
6679
|
const heartbeatPayload = () => ({
|
|
6626
6680
|
instanceId,
|
|
6627
6681
|
codexUrl,
|
|
@@ -6684,6 +6738,9 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
6684
6738
|
metadata
|
|
6685
6739
|
});
|
|
6686
6740
|
channelSession?.handleCodexNotification(notification.method, params);
|
|
6741
|
+
for (const session of dynamicChannelSessions.values()) {
|
|
6742
|
+
session.handleCodexNotification(notification.method, params);
|
|
6743
|
+
}
|
|
6687
6744
|
});
|
|
6688
6745
|
const handleControl = (control) => {
|
|
6689
6746
|
log("kandan.control", { control });
|
|
@@ -6777,11 +6834,11 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
6777
6834
|
pushHeartbeat();
|
|
6778
6835
|
return;
|
|
6779
6836
|
}
|
|
6780
|
-
(channelSession
|
|
6837
|
+
resolveSessionControl(channelSession, dynamicChannelSessions, control).then((handled) => {
|
|
6781
6838
|
if (handled !== undefined) {
|
|
6782
6839
|
return handled;
|
|
6783
6840
|
}
|
|
6784
|
-
return applyControl(codex, kandan, topic, instanceId, options, allowedCwds.value, control);
|
|
6841
|
+
return applyControl(codex, kandan, topic, instanceId, options, allowedCwds.value, control, attachStartedThreadSession);
|
|
6785
6842
|
}).then((response) => {
|
|
6786
6843
|
return kandan.push(topic, "codex_response", response);
|
|
6787
6844
|
}).catch((error) => {
|
|
@@ -6802,6 +6859,19 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
6802
6859
|
function controlTargetsInstance(control, instanceId) {
|
|
6803
6860
|
return control.instanceId === undefined || control.instanceId === instanceId;
|
|
6804
6861
|
}
|
|
6862
|
+
async function resolveSessionControl(channelSession, dynamicChannelSessions, control) {
|
|
6863
|
+
const primaryHandled = await (channelSession?.handleControl(control) ?? Promise.resolve(undefined));
|
|
6864
|
+
if (primaryHandled !== undefined) {
|
|
6865
|
+
return primaryHandled;
|
|
6866
|
+
}
|
|
6867
|
+
for (const session of dynamicChannelSessions.values()) {
|
|
6868
|
+
const handled = await session.handleControl(control);
|
|
6869
|
+
if (handled !== undefined) {
|
|
6870
|
+
return handled;
|
|
6871
|
+
}
|
|
6872
|
+
}
|
|
6873
|
+
return;
|
|
6874
|
+
}
|
|
6805
6875
|
async function closeCleanupStack(cleanup) {
|
|
6806
6876
|
if (cleanup.closePromise !== undefined) {
|
|
6807
6877
|
return cleanup.closePromise;
|
|
@@ -6916,7 +6986,7 @@ async function prepareCodexThreadForTuiResume(codex, codexThreadId) {
|
|
|
6916
6986
|
throw new Error(`failed to verify Codex TUI resume: ${verified.error.message}`);
|
|
6917
6987
|
}
|
|
6918
6988
|
}
|
|
6919
|
-
async function applyControl(codex, kandan, topic, instanceId, options, allowedCwds, control) {
|
|
6989
|
+
async function applyControl(codex, kandan, topic, instanceId, options, allowedCwds, control, onStartedThread) {
|
|
6920
6990
|
switch (control.type) {
|
|
6921
6991
|
case "start_instance": {
|
|
6922
6992
|
const cwd = resolveAllowedCwd(control.cwd, allowedCwds);
|
|
@@ -6949,7 +7019,10 @@ async function applyControl(codex, kandan, topic, instanceId, options, allowedCw
|
|
|
6949
7019
|
const codexThreadId = extractStartedThreadId(response);
|
|
6950
7020
|
const workDescription = normalizedWorkDescription(control.workDescription);
|
|
6951
7021
|
if (codexThreadId !== undefined && developerPrompt !== undefined) {
|
|
6952
|
-
await postVisibleDeveloperPrompt(kandan, topic, control, developerPrompt);
|
|
7022
|
+
await postVisibleDeveloperPrompt(kandan, topic, control, developerPrompt, codexThreadId);
|
|
7023
|
+
}
|
|
7024
|
+
if (codexThreadId !== undefined && onStartedThread !== undefined) {
|
|
7025
|
+
await onStartedThread(control, cwd.cwd);
|
|
6953
7026
|
}
|
|
6954
7027
|
if (codexThreadId !== undefined && workDescription !== undefined) {
|
|
6955
7028
|
await codex.request("turn/start", {
|
|
@@ -7078,7 +7151,7 @@ work in the approved project folder, keep preview servers reachable through the
|
|
|
7078
7151
|
secure tunnel, and keep the Linzumi thread truthful.
|
|
7079
7152
|
</task_reminder>`;
|
|
7080
7153
|
}
|
|
7081
|
-
async function postVisibleDeveloperPrompt(kandan, topic, control, developerPrompt) {
|
|
7154
|
+
async function postVisibleDeveloperPrompt(kandan, topic, control, developerPrompt, codexThreadId) {
|
|
7082
7155
|
const workspace = normalizedWorkDescription(control.workspace);
|
|
7083
7156
|
const channel = normalizedWorkDescription(control.channel);
|
|
7084
7157
|
const threadId = normalizedWorkDescription(control.threadId);
|
|
@@ -7093,8 +7166,11 @@ async function postVisibleDeveloperPrompt(kandan, topic, control, developerPromp
|
|
|
7093
7166
|
|
|
7094
7167
|
${developerPrompt}`,
|
|
7095
7168
|
payload: {
|
|
7096
|
-
|
|
7097
|
-
|
|
7169
|
+
metadata: {
|
|
7170
|
+
local_codex_runner: {
|
|
7171
|
+
event_type: "codex_start_instructions",
|
|
7172
|
+
codex_thread_id: codexThreadId
|
|
7173
|
+
}
|
|
7098
7174
|
}
|
|
7099
7175
|
},
|
|
7100
7176
|
client_message_id: `codex-start-instructions-${threadId}`
|
|
@@ -8836,7 +8912,7 @@ async function main(args) {
|
|
|
8836
8912
|
process.stdout.write(connectGuideText());
|
|
8837
8913
|
return;
|
|
8838
8914
|
case "version":
|
|
8839
|
-
process.stdout.write(`linzumi 0.0.
|
|
8915
|
+
process.stdout.write(`linzumi 0.0.30-beta
|
|
8840
8916
|
`);
|
|
8841
8917
|
return;
|
|
8842
8918
|
case "auth":
|
|
@@ -9343,7 +9419,7 @@ async function parseRunnerArgs(args, deps = {
|
|
|
9343
9419
|
process.exit(0);
|
|
9344
9420
|
}
|
|
9345
9421
|
if (values.get("version") === true) {
|
|
9346
|
-
process.stdout.write(`linzumi 0.0.
|
|
9422
|
+
process.stdout.write(`linzumi 0.0.30-beta
|
|
9347
9423
|
`);
|
|
9348
9424
|
process.exit(0);
|
|
9349
9425
|
}
|
package/package.json
CHANGED