@linzumi/cli 0.0.46-beta → 0.0.47-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 CHANGED
@@ -63,7 +63,7 @@ Install the CLI or run it with `npx`:
63
63
 
64
64
  ```bash
65
65
  npm install -g @linzumi/cli@latest
66
- npx -y @linzumi/cli@0.0.46-beta --version
66
+ npx -y @linzumi/cli@0.0.47-beta --version
67
67
  linzumi --version
68
68
  ```
69
69
 
package/dist/index.js CHANGED
@@ -937,6 +937,44 @@ function fuseQueuedMessages(selected) {
937
937
  };
938
938
  }
939
939
 
940
+ // src/linzumiContext.ts
941
+ function parseLinzumiConversationContext(value, warn = console.warn) {
942
+ if (value === undefined) {
943
+ return;
944
+ }
945
+ const context = objectValue(value);
946
+ if (context === undefined) {
947
+ return invalidLinzumiContext("linzumiContext must be an object", warn);
948
+ }
949
+ const threadId = stringValue(context.threadId);
950
+ const creatorUserId = stringValue(context.creatorUserId) ?? integerValue(context.creatorUserId)?.toString();
951
+ const creatorUsername = stringValue(context.creatorUsername);
952
+ const conversationUrl = stringValue(context.conversationUrl);
953
+ if (threadId === undefined || creatorUserId === undefined || creatorUsername === undefined || conversationUrl === undefined) {
954
+ return invalidLinzumiContext("linzumiContext must include threadId, creatorUserId, creatorUsername, and conversationUrl", warn);
955
+ }
956
+ return { threadId, creatorUserId, creatorUsername, conversationUrl };
957
+ }
958
+ function formatLinzumiConversationContextForPrompt(context) {
959
+ return `<linzumi_context>
960
+ <linzumi_thread_id>${escapeXmlText(context.threadId)}</linzumi_thread_id>
961
+ <linzumi_creator_user_id>${escapeXmlText(context.creatorUserId)}</linzumi_creator_user_id>
962
+ <linzumi_creator_username>${escapeXmlText(context.creatorUsername)}</linzumi_creator_username>
963
+ <linzumi_conversation_url>${escapeXmlText(context.conversationUrl)}</linzumi_conversation_url>
964
+ </linzumi_context>
965
+
966
+ <linzumi_pr_footer_instruction>
967
+ For any GitHub pull request you open from this session, include this Markdown footer link in the PR description: [Continue this on Linzumi](${context.conversationUrl})
968
+ </linzumi_pr_footer_instruction>`;
969
+ }
970
+ function invalidLinzumiContext(reason, warn) {
971
+ warn(`Ignoring invalid linzumiContext: ${reason}`);
972
+ return;
973
+ }
974
+ function escapeXmlText(value) {
975
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
976
+ }
977
+
940
978
  // src/reconnectContext.ts
941
979
  var recentVerbatimMessageCount = 5;
942
980
  var reconnectContextModel = "openai/gpt-oss-120b";
@@ -975,7 +1013,7 @@ function filterReconnectContextMessages(messages) {
975
1013
  return true;
976
1014
  });
977
1015
  }
978
- async function buildReconnectContextInjection(messages, summarizer = createConfiguredReconnectContextSummarizer()) {
1016
+ async function buildReconnectContextInjection(messages, summarizer = createConfiguredReconnectContextSummarizer(), linzumiContext) {
979
1017
  const filtered = filterReconnectContextMessages(messages);
980
1018
  if (filtered.length === 0) {
981
1019
  throw new Error("durable Linzumi thread history did not include user-visible context");
@@ -988,6 +1026,7 @@ async function buildReconnectContextInjection(messages, summarizer = createConfi
988
1026
  "",
989
1027
  "The local Codex app-server thread was restarted, so this durable Linzumi thread history is being injected before retrying the latest user message.",
990
1028
  "",
1029
+ ...linzumiContext === undefined ? [] : [formatLinzumiConversationContextForPrompt(linzumiContext), ""],
991
1030
  ...summary === undefined ? [] : ["Summary of earlier messages:", summary, ""],
992
1031
  "Last five user-visible messages verbatim:",
993
1032
  recent.map(formatReconnectContextMessage).join(`
@@ -2655,6 +2694,7 @@ function initialChannelSessionState(cursor, rootSeq, kandanThreadId, codexThread
2655
2694
  portForwardWatcher: undefined,
2656
2695
  activeProcessingState: undefined,
2657
2696
  pendingReconnectContextInjection: undefined,
2697
+ linzumiContext: parseLinzumiConversationContext(options.channelSession.linzumiContext),
2658
2698
  terminalInputForwardChain: Promise.resolve(),
2659
2699
  webSearchProgressForwardChain: Promise.resolve(),
2660
2700
  typingHeartbeat: undefined,
@@ -3686,7 +3726,7 @@ async function fetchReconnectContextInjection(args, state) {
3686
3726
  });
3687
3727
  const messages = parseReconnectContextMessages(reply.messages);
3688
3728
  const summarizer = args.options.reconnectContextSummarizer ?? createConfiguredReconnectContextSummarizer();
3689
- const injection = await buildReconnectContextInjection(messages, summarizer);
3729
+ const injection = await buildReconnectContextInjection(messages, summarizer, state.linzumiContext);
3690
3730
  args.log("codex.thread_reconnect_context_prepared", {
3691
3731
  codex_thread_id: state.codexThreadId ?? null,
3692
3732
  kandan_thread_id: state.kandanThreadId,
@@ -5060,7 +5100,7 @@ async function downloadQueuedKandanAttachments(args, message) {
5060
5100
  }
5061
5101
  const fileName = safeAttachmentFileName(attachment.fileName ?? attachment.id ?? `attachment-${index + 1}`, index);
5062
5102
  const localPath = join(directory, fileName);
5063
- const response = await fetch(resolveKandanAttachmentUrl(args.options.kandanUrl, url), {
5103
+ const response = await (args.options.fetch ?? globalThis.fetch)(resolveKandanAttachmentUrl(args.options.kandanUrl, url), {
5064
5104
  headers: {
5065
5105
  authorization: `Bearer ${args.options.token}`
5066
5106
  }
@@ -5178,7 +5218,7 @@ async function uploadedFileIdsForCodexOutput(args, body, structured) {
5178
5218
  }
5179
5219
  const bytes = await readFile(file.path);
5180
5220
  const uploadBody = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
5181
- const response = await fetch(resolveKandanAttachmentUrl(args.options.kandanUrl, uploadUrl), {
5221
+ const response = await (args.options.fetch ?? globalThis.fetch)(resolveKandanAttachmentUrl(args.options.kandanUrl, uploadUrl), {
5182
5222
  method: uploadMethod,
5183
5223
  headers: { "content-type": file.contentType },
5184
5224
  body: uploadBody
@@ -8460,7 +8500,7 @@ function realpathOrResolved(pathValue) {
8460
8500
  }
8461
8501
 
8462
8502
  // src/version.ts
8463
- var linzumiCliVersion = "0.0.46-beta";
8503
+ var linzumiCliVersion = "0.0.47-beta";
8464
8504
  var linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
8465
8505
 
8466
8506
  // src/runnerLock.ts
@@ -9258,10 +9298,12 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
9258
9298
  topic,
9259
9299
  instanceId,
9260
9300
  options: {
9301
+ kandanUrl: options.kandanUrl,
9261
9302
  token: options.token,
9262
9303
  runnerId: options.runnerId,
9263
9304
  cwd: options.cwd,
9264
9305
  codexBin: options.codexBin,
9306
+ fetch: options.fetch,
9265
9307
  fast: options.fast,
9266
9308
  launchTui: options.launchTui,
9267
9309
  enablePortForwardWatch: true,
@@ -9313,10 +9355,12 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
9313
9355
  topic,
9314
9356
  instanceId,
9315
9357
  options: {
9358
+ kandanUrl: options.kandanUrl,
9316
9359
  token: options.token,
9317
9360
  runnerId: options.runnerId,
9318
9361
  cwd,
9319
9362
  codexBin: options.codexBin,
9363
+ fetch: options.fetch,
9320
9364
  fast: control.fast ?? options.fast,
9321
9365
  launchTui: false,
9322
9366
  enablePortForwardWatch: true,
@@ -9338,6 +9382,7 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
9338
9382
  kandanThreadId,
9339
9383
  rootSeq: integerValue(control.rootSeq),
9340
9384
  codexThreadId,
9385
+ linzumiContext: control.linzumiContext,
9341
9386
  listenUser,
9342
9387
  model: runtimeSettings.model,
9343
9388
  reasoningEffort: runtimeSettings.reasoningEffort,
@@ -9846,6 +9891,7 @@ async function applyControl(codex, kandan, topic, instanceId, options, allowedCw
9846
9891
  }
9847
9892
  startupStage = "starting_codex_session";
9848
9893
  const developerPrompt = normalizedWorkDescription(control.developerPrompt);
9894
+ const linzumiContext = parseLinzumiConversationContext(control.linzumiContext);
9849
9895
  const runtimeSettings = startInstanceRuntimeSettings(options, control);
9850
9896
  const response = await codex.request("thread/start", {
9851
9897
  cwd: cwd.cwd,
@@ -9853,7 +9899,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, allowedCw
9853
9899
  personality: "pragmatic",
9854
9900
  developerInstructions: commanderDeveloperInstructions({
9855
9901
  cwd: cwd.cwd,
9856
- developerPrompt
9902
+ developerPrompt,
9903
+ linzumiContext
9857
9904
  }),
9858
9905
  ...runtimeSettings.model === undefined ? {} : { model: runtimeSettings.model },
9859
9906
  ...runtimeSettings.reasoningEffort === undefined ? {} : { reasoningEffort: runtimeSettings.reasoningEffort },
@@ -10045,6 +10092,9 @@ function commanderDeveloperInstructions(args) {
10045
10092
  <invoker_developer_prompt>
10046
10093
  ${args.developerPrompt}
10047
10094
  </invoker_developer_prompt>
10095
+ `;
10096
+ const linzumiContext = args.linzumiContext === undefined ? "" : `
10097
+ ${formatLinzumiConversationContextForPrompt(args.linzumiContext)}
10048
10098
  `;
10049
10099
  return `<context>
10050
10100
  You are a Linzumi Codex session launched by the Linzumi Commander.
@@ -10088,6 +10138,7 @@ fails.
10088
10138
  GOOD preview command: npm run dev -- --host 0.0.0.0 --port 8787
10089
10139
  BAD preview command: npm run dev -- --host 127.0.0.1
10090
10140
  </examples>
10141
+ ${linzumiContext}
10091
10142
  ${customPrompt}
10092
10143
  <task_reminder>
10093
10144
  You are the Commander-launched Linzumi Codex session. Do the implementation
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linzumi/cli",
3
- "version": "0.0.46-beta",
3
+ "version": "0.0.47-beta",
4
4
  "description": "Linzumi CLI — 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": {