nolo-cli 0.75.0-alpha.4 → 0.75.0-alpha.6

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.
@@ -8,8 +8,8 @@ import {
8
8
  } from "./chunk-JYYZCK2Z.js";
9
9
  import {
10
10
  runAgentCreateCommand
11
- } from "./chunk-VC5CX46C.js";
12
- import "./chunk-VBXDAIEC.js";
11
+ } from "./chunk-Q2DNZQEZ.js";
12
+ import "./chunk-CIHSMPAW.js";
13
13
  import "./chunk-GBPZKFYK.js";
14
14
  import "./chunk-QCZX4FTW.js";
15
15
  import "./chunk-EADNWBAZ.js";
@@ -89,7 +89,7 @@ async function defaultExecuteCli(provider, prompt, options) {
89
89
  return executeCli(provider, prompt, options);
90
90
  }
91
91
  async function forwardConnectorRunMessage(machine, message, pushMessage, executeCli, env, fetchImpl) {
92
- const { handleConnectorRunMessage } = await import("./machineWsRunDispatch-U2IEF5OK.js");
92
+ const { handleConnectorRunMessage } = await import("./machineWsRunDispatch-43YGAXOP.js");
93
93
  return handleConnectorRunMessage(message, pushMessage, executeCli, env, fetchImpl);
94
94
  }
95
95
  async function detectLaunchableMachineInfo() {
@@ -2,8 +2,8 @@ import {
2
2
  runAgentCreateCommand,
3
3
  runAgentReadCommand,
4
4
  runAgentUpdateCommand
5
- } from "./chunk-VC5CX46C.js";
6
- import "./chunk-VBXDAIEC.js";
5
+ } from "./chunk-Q2DNZQEZ.js";
6
+ import "./chunk-CIHSMPAW.js";
7
7
  import "./chunk-GBPZKFYK.js";
8
8
  import "./chunk-QCZX4FTW.js";
9
9
  import "./chunk-EADNWBAZ.js";
@@ -8,12 +8,12 @@ import {
8
8
  resolveRunSettlementNote,
9
9
  resolveWorkflowReference,
10
10
  runAgentRunCommand
11
- } from "./chunk-AMDSZQCT.js";
11
+ } from "./chunk-RL5PTRUQ.js";
12
12
  import "./chunk-S7Z2HMCN.js";
13
13
  import {
14
14
  parseAgentRunArgs
15
15
  } from "./chunk-JYYZCK2Z.js";
16
- import "./chunk-VBXDAIEC.js";
16
+ import "./chunk-CIHSMPAW.js";
17
17
  import "./chunk-GBPZKFYK.js";
18
18
  import "./chunk-QCZX4FTW.js";
19
19
  import "./chunk-EADNWBAZ.js";
@@ -389,17 +389,17 @@ function newlineHint(platform = process.platform) {
389
389
  var WELCOME_TIPS = {
390
390
  en: [
391
391
  `Tip: ${newlineHint()} for a newline; /help lists all commands.`,
392
- "Tip: paste a screenshot or drag an image into the terminal \u2014 nolo can see it.",
392
+ "Tip: drag an image file into the terminal \u2014 nolo sees it. A plain path works too.",
393
393
  "Tip: /doc attach <doc> brings a doc into this conversation's context.",
394
394
  "Tip: /theme switches colors; terminal mode follows your terminal's day/night.",
395
395
  "Tip: /history resumes a recent dialog; /agents lists your agents."
396
396
  ],
397
397
  zh: [
398
398
  `\u63D0\u793A\uFF1A${newlineHint()} \u6362\u884C\uFF1B/help \u5217\u51FA\u5168\u90E8\u547D\u4EE4\u3002`,
399
- "\u63D0\u793A\uFF1A\u76F4\u63A5\u7C98\u8D34\u622A\u56FE\u6216\u628A\u56FE\u7247\u62D6\u8FDB\u7EC8\u7AEF\uFF0Cnolo \u770B\u5F97\u61C2\u3002",
400
- "\u63D0\u793A\uFF1A/doc attach <doc> \u628A\u6587\u6863\u6302\u8FDB\u5F53\u524D\u5BF9\u8BDD\u7684\u4E0A\u4E0B\u6587\u3002",
401
- "\u63D0\u793A\uFF1A/theme \u5207\u6362\u914D\u8272\uFF1Bterminal \u6A21\u5F0F\u8DDF\u968F\u7EC8\u7AEF\u7684\u65E5\u591C\u4E3B\u9898\u3002",
402
- "\u63D0\u793A\uFF1A/history \u56DE\u5230\u6700\u8FD1\u5BF9\u8BDD\uFF1B/agents \u67E5\u770B\u53EF\u7528 Agent\u3002"
399
+ "\u63D0\u793A\uFF1A\u628A\u56FE\u7247\u6587\u4EF6\u62D6\u8FDB\u7EC8\u7AEF\u6700\u7701\u4E8B\uFF1B\u4E5F\u80FD\u76F4\u63A5\u8F93\u5165\u56FE\u7247\u8DEF\u5F84\u3002",
400
+ "\u63D0\u793A\uFF1A/doc attach <doc> \u628A\u6587\u6863\u6302\u8FDB\u5F53\u524D\u5BF9\u8BDD\u4E0A\u4E0B\u6587\u3002",
401
+ "\u63D0\u793A\uFF1A/theme \u5207\u6362\u914D\u8272\uFF1B\u65E5\u591C\u95F4\u8DDF\u968F\u7EC8\u7AEF\u4E3B\u9898\u3002",
402
+ "\u63D0\u793A\uFF1A/history \u6062\u590D\u6700\u8FD1\u5BF9\u8BDD\uFF1B/agents \u5217\u51FA\u4F60\u7684\u667A\u80FD\u4F53\u3002"
403
403
  ]
404
404
  };
405
405
  function dailyWelcomeTip(now = Date.now()) {
@@ -916,6 +916,23 @@ var STRINGS = {
916
916
  en: "Agents:",
917
917
  zh: "\u667A\u80FD\u4F53\uFF1A"
918
918
  },
919
+ // --- Paste / clipboard ------------------------------------------------
920
+ pasteUsage: {
921
+ en: "Usage: /paste (no arguments). Reads your clipboard now: an image becomes an attachment, text lands in the draft. Tip: dragging an image file onto the terminal is the most reliable way to attach a picture.",
922
+ zh: "\u7528\u6CD5\uFF1A/paste\uFF08\u65E0\u53C2\u6570\uFF09\u3002\u7ACB\u5373\u8BFB\u53D6\u526A\u8D34\u677F\uFF1A\u56FE\u7247\u53D8\u9644\u4EF6\uFF0C\u6587\u672C\u8FDB\u8349\u7A3F\u3002\u63D0\u793A\uFF1A\u628A\u56FE\u7247\u6587\u4EF6\u62D6\u8FDB\u7EC8\u7AEF\u662F\u9644\u4E0A\u56FE\u7247\u6700\u53EF\u9760\u7684\u65B9\u5F0F\u3002"
923
+ },
924
+ pasteTextInserted: {
925
+ en: "Pasted {0} characters from the clipboard into the draft.",
926
+ zh: "\u5DF2\u4ECE\u526A\u8D34\u677F\u7C98\u8D34 {0} \u4E2A\u5B57\u7B26\u5230\u8349\u7A3F\u3002"
927
+ },
928
+ pasteStaleDropped: {
929
+ en: "[nolo] Discarded a clipboard read that finished after the draft changed.",
930
+ zh: "[nolo] \u526A\u8D34\u677F\u8BFB\u53D6\u5B8C\u6210\u65F6\u8349\u7A3F\u5DF2\u53D8\u5316\uFF0C\u7ED3\u679C\u5DF2\u4E22\u5F03\u3002"
931
+ },
932
+ pasteFilePathHint: {
933
+ en: "file reference (path only, content not read): {0}",
934
+ zh: "\u6587\u4EF6\u5F15\u7528\uFF08\u4EC5\u8DEF\u5F84\uFF0C\u672A\u8BFB\u53D6\u5185\u5BB9\uFF09\uFF1A{0}"
935
+ },
919
936
  agentsTip: {
920
937
  en: "Tip: run /switch for the full picker, or /switch list for your private agents too.",
921
938
  zh: "\u63D0\u793A\uFF1A\u7528 /switch \u6253\u5F00\u5B8C\u6574\u9009\u62E9\u5668\uFF0C\u6216 /switch list \u8FDE\u4F60\u7684\u79C1\u6709\u667A\u80FD\u4F53\u4E00\u8D77\u5217\u51FA\u3002"
@@ -937,6 +954,9 @@ var STRINGS = {
937
954
  " /resume <dialogId> Resume a dialog directly by id",
938
955
  " /lang <zh|en> Switch interface language",
939
956
  ' /copy [all] Copy the last reply (or the full conversation with "all") to the clipboard',
957
+ " /paste Read the clipboard now (image \u2192 attachment, text \u2192 draft)",
958
+ " Drag a file in Drop an image file on the terminal to attach it; other files stay paths",
959
+ " Shift+Enter / Ctrl+J Insert a newline in the draft",
940
960
  " /mouse <on|off> Toggle mouse mode (off = drag to select text)",
941
961
  " /auto <on|off> Toggle permission auto-approve (skip destructive-shell, external-file & file-write confirms)",
942
962
  " /math <on|off> Toggle math formula rendering (Unicode transcription)",
@@ -975,6 +995,9 @@ var STRINGS = {
975
995
  " /resume <dialogId> \u6309 id \u76F4\u63A5\u6062\u590D\u5BF9\u8BDD",
976
996
  " /lang <zh|en> \u5207\u6362\u754C\u9762\u8BED\u8A00",
977
997
  " /copy [all] \u590D\u5236\u6700\u540E\u4E00\u6761\u56DE\u590D\u5230\u526A\u8D34\u677F\uFF08\u52A0 all \u590D\u5236\u5B8C\u6574\u5BF9\u8BDD\uFF09",
998
+ " /paste \u7ACB\u5373\u8BFB\u526A\u8D34\u677F\uFF08\u56FE\u7247\u2192\u9644\u4EF6\uFF0C\u6587\u672C\u2192\u8349\u7A3F\uFF09",
999
+ " \u62D6\u5165\u6587\u4EF6 \u628A\u56FE\u7247\u6587\u4EF6\u62D6\u8FDB\u7EC8\u7AEF\u5373\u6210\u4E3A\u9644\u4EF6\uFF1B\u5176\u4ED6\u6587\u4EF6\u53EA\u7559\u8DEF\u5F84",
1000
+ " Shift+Enter / Ctrl+J \u5728\u8349\u7A3F\u91CC\u6362\u884C",
978
1001
  " /mouse <on|off> \u5207\u6362\u9F20\u6807\u6A21\u5F0F\uFF08off \u540E\u53EF\u76F4\u63A5\u62D6\u9009\u6587\u672C\uFF09",
979
1002
  " /auto <on|off> \u5207\u6362\u6743\u9650\u81EA\u52A8\u5316\uFF08\u81EA\u52A8\u653E\u884C\u7834\u574F\u6027 shell\u3001\u5916\u90E8\u6587\u4EF6\u4E0E\u5199\u6587\u4EF6\u786E\u8BA4\uFF09",
980
1003
  " /math <on|off> \u5207\u6362\u6570\u5B66\u516C\u5F0F\u6E32\u67D3\uFF08Unicode \u8F6C\u5199\uFF09",
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createCliLocalRuntimeAdapter,
3
3
  summarizeEndpoint
4
- } from "./chunk-VBXDAIEC.js";
4
+ } from "./chunk-CIHSMPAW.js";
5
5
  import {
6
6
  clipMultilineText
7
7
  } from "./chunk-QH6NK22I.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  clearCliLocalRuntimePreparedAgentCache
3
- } from "./chunk-VBXDAIEC.js";
3
+ } from "./chunk-CIHSMPAW.js";
4
4
  import {
5
5
  getReadableCliDb
6
6
  } from "./chunk-RXX4GDIH.js";
@@ -27,7 +27,7 @@ import {
27
27
  resolveLocalUserId,
28
28
  t,
29
29
  toolLabel
30
- } from "./chunk-VBXDAIEC.js";
30
+ } from "./chunk-CIHSMPAW.js";
31
31
  import {
32
32
  createRunActivityTracker,
33
33
  popSingleQueueMessage,
@@ -411,7 +411,7 @@ var fullwidthMaximumCodePoint = 65510;
411
411
  var fullwidthRanges = [12288, 12288, 65281, 65376, 65504, 65510];
412
412
  var wideMinimalCodePoint = 4352;
413
413
  var wideMaximumCodePoint = 262141;
414
- var wideRanges = [4352, 4447, 8986, 8987, 9001, 9002, 9193, 9196, 9200, 9200, 9203, 9203, 9725, 9726, 9748, 9749, 9776, 9783, 9800, 9811, 9855, 9855, 9866, 9871, 9875, 9875, 9889, 9889, 9898, 9899, 9917, 9918, 9924, 9925, 9934, 9934, 9940, 9940, 9962, 9962, 9970, 9971, 9973, 9973, 9978, 9978, 9981, 9981, 9989, 9989, 9994, 9995, 10024, 10024, 10060, 10060, 10062, 10062, 10067, 10069, 10071, 10071, 10133, 10135, 10160, 10160, 10175, 10175, 11035, 11036, 11088, 11088, 11093, 11093, 11904, 11929, 11931, 12019, 12032, 12245, 12272, 12287, 12289, 12350, 12353, 12438, 12441, 12543, 12549, 12591, 12593, 12686, 12688, 12773, 12783, 12830, 12832, 12871, 12880, 42124, 42128, 42182, 43360, 43388, 44032, 55203, 63744, 64255, 65040, 65049, 65072, 65106, 65108, 65126, 65128, 65131, 94176, 94180, 94192, 94198, 94208, 101589, 101631, 101662, 101760, 101874, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110951, 110960, 111355, 119552, 119638, 119648, 119670, 126980, 126980, 127183, 127183, 127374, 127374, 127377, 127386, 127488, 127490, 127504, 127547, 127552, 127560, 127568, 127569, 127584, 127589, 127744, 127776, 127789, 127797, 127799, 127868, 127870, 127891, 127904, 127946, 127951, 127955, 127968, 127984, 127988, 127988, 127992, 128062, 128064, 128064, 128066, 128252, 128255, 128317, 128331, 128334, 128336, 128359, 128378, 128378, 128405, 128406, 128420, 128420, 128507, 128591, 128640, 128709, 128716, 128716, 128720, 128722, 128725, 128728, 128732, 128735, 128747, 128748, 128756, 128764, 128992, 129003, 129008, 129008, 129292, 129338, 129340, 129349, 129351, 129535, 129648, 129660, 129664, 129674, 129678, 129734, 129736, 129736, 129741, 129756, 129759, 129770, 129775, 129784, 131072, 196605, 196608, 262141];
414
+ var wideRanges = [4352, 4447, 8986, 8987, 9001, 9002, 9193, 9196, 9200, 9200, 9203, 9203, 9725, 9726, 9748, 9749, 9776, 9783, 9800, 9811, 9855, 9855, 9866, 9871, 9875, 9875, 9889, 9889, 9898, 9899, 9917, 9918, 9924, 9925, 9934, 9934, 9940, 9940, 9962, 9962, 9970, 9971, 9973, 9973, 9978, 9978, 9981, 9981, 9989, 9989, 9994, 9995, 10024, 10024, 10060, 10060, 10062, 10062, 10067, 10069, 10071, 10071, 10133, 10135, 10160, 10160, 10175, 10175, 11035, 11036, 11088, 11088, 11093, 11093, 11904, 11929, 11931, 12019, 12032, 12245, 12272, 12287, 12289, 12350, 12353, 12438, 12441, 12543, 12549, 12591, 12593, 12686, 12688, 12773, 12783, 12830, 12832, 12871, 12880, 42124, 42128, 42182, 43360, 43388, 44032, 55203, 63744, 64255, 65040, 65049, 65072, 65106, 65108, 65126, 65128, 65131, 94176, 94180, 94192, 94198, 94208, 101594, 101631, 101664, 101760, 101874, 101888, 102801, 102816, 102866, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110888, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110952, 110960, 111355, 119552, 119638, 119648, 119670, 126980, 126980, 127183, 127183, 127374, 127374, 127377, 127386, 127406, 127406, 127488, 127490, 127504, 127547, 127552, 127560, 127568, 127569, 127584, 127589, 127744, 127776, 127789, 127797, 127799, 127868, 127870, 127891, 127904, 127946, 127951, 127955, 127968, 127984, 127988, 127988, 127992, 128062, 128064, 128064, 128066, 128252, 128255, 128317, 128331, 128334, 128336, 128359, 128378, 128378, 128405, 128406, 128420, 128420, 128507, 128591, 128640, 128709, 128716, 128716, 128720, 128722, 128725, 128729, 128732, 128735, 128747, 128748, 128756, 128764, 128986, 128986, 128992, 129003, 129008, 129008, 129292, 129338, 129340, 129349, 129351, 129535, 129648, 129660, 129664, 129734, 129736, 129736, 129740, 129757, 129759, 129771, 129775, 129786, 131072, 196605, 196608, 262141];
415
415
 
416
416
  // node_modules/get-east-asian-width/utilities.js
417
417
  var isInRange = (ranges, codePoint) => {
@@ -456,7 +456,7 @@ var isAmbiguous = (codePoint) => {
456
456
  }
457
457
  return isInRange(ambiguousRanges, codePoint);
458
458
  };
459
- var isFullWidth = (codePoint) => {
459
+ var isFullwidth = (codePoint) => {
460
460
  if (codePoint < fullwidthMinimalCodePoint || codePoint > fullwidthMaximumCodePoint) {
461
461
  return false;
462
462
  }
@@ -480,7 +480,7 @@ function validate(codePoint) {
480
480
  }
481
481
  function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
482
482
  validate(codePoint);
483
- if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) {
483
+ if (isFullwidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) {
484
484
  return 2;
485
485
  }
486
486
  return 1;
@@ -1324,15 +1324,18 @@ function resolveTuiBrightnessSignal(env = process.env) {
1324
1324
  if (explicit === "dark") return "dark";
1325
1325
  if (activeThemeMode !== "terminal") return activeThemeMode;
1326
1326
  if (resolvedBrightness) return resolvedBrightness;
1327
- const colorfgbg = env.COLORFGBG ?? "";
1328
- if (colorfgbg) {
1329
- const parts = colorfgbg.split(";");
1330
- const bg = parts.length > 1 ? Number.parseInt(parts[1] ?? "", 10) : NaN;
1331
- if (!Number.isNaN(bg) && bg >= 0 && bg <= 6) return "dark";
1332
- if (!Number.isNaN(bg) && bg >= 7 && bg <= 15) return "light";
1333
- }
1327
+ const colorFgBgBrightness = detectColorFgBgBrightness(env);
1328
+ if (colorFgBgBrightness) return colorFgBgBrightness;
1334
1329
  return detectSystemBrightnessFromEnv(env);
1335
1330
  }
1331
+ function detectColorFgBgBrightness(env) {
1332
+ const parts = (env.COLORFGBG ?? "").split(";");
1333
+ const bg = Number.parseInt(parts.at(-1) ?? "", 10);
1334
+ if (Number.isNaN(bg)) return null;
1335
+ if (bg >= 0 && bg <= 6) return "dark";
1336
+ if (bg >= 7 && bg <= 15) return "light";
1337
+ return null;
1338
+ }
1336
1339
  function resolveTuiThemeMode(env = process.env, fallback = activeThemeMode) {
1337
1340
  const explicit = (env.NOLO_TUI_THEME ?? "").trim().toLowerCase();
1338
1341
  if (explicit === "light" || explicit === "dark") return explicit;
@@ -1489,6 +1492,9 @@ function surfaceBackgroundSequence(env = process.env, brightness = resolveTuiBri
1489
1492
  }
1490
1493
  function userSurfaceBackgroundSequence(env = process.env, brightness = resolveTuiBrightness(env)) {
1491
1494
  if (!supportsTruecolor(env)) return "";
1495
+ if (resolveTuiThemeMode(env) === "terminal" && activeTerminalBaseHex === null && detectColorFgBgBrightness(env) === null) {
1496
+ return "";
1497
+ }
1492
1498
  const palette = THEME_PALETTES[activeThemeName] ?? THEME_PALETTES.trail;
1493
1499
  const surfaceHex = brightness === "light" ? palette.light.chrome.hex : palette.dark.accent.hex;
1494
1500
  const weight = brightness === "dark" ? 0.3 : 0.08;
package/index.js CHANGED
@@ -127,7 +127,7 @@ function createDaemonShortcutCommand(path, description, command2) {
127
127
  // packages/cli/agentInternalCommandEntries.ts
128
128
  function getAgentInternalCommandEntries() {
129
129
  const createAgentRunCommand = (path, description) => createContextCommand(path, description, async (args2, ctx) => {
130
- const { runAgentRunCommand } = await import("./agentRunCommand-775H4KKG.js");
130
+ const { runAgentRunCommand } = await import("./agentRunCommand-CDRQIDLW.js");
131
131
  return runAgentRunCommand(args2, {
132
132
  env: ctx.env,
133
133
  scriptDir: ctx.scriptDir,
@@ -143,7 +143,7 @@ function getAgentInternalCommandEntries() {
143
143
  return runAgentListCommand(args2, deps);
144
144
  }),
145
145
  createEnvCommand(["agent", "create"], "Create a new agent", async (args2, deps) => {
146
- const { runAgentCreateCommand } = await import("./agentRecordCommands-24JJOYM5.js");
146
+ const { runAgentCreateCommand } = await import("./agentRecordCommands-4RQKVPNP.js");
147
147
  return runAgentCreateCommand(args2, deps);
148
148
  }),
149
149
  createEnvCommand(["agent", "models"], "List models available on an OpenAI-compatible provider", async (args2, deps) => {
@@ -155,7 +155,7 @@ function getAgentInternalCommandEntries() {
155
155
  return runAgentPullCommand(args2, deps);
156
156
  }),
157
157
  createEnvCommand(["agent", "read"], "Read a single agent", async (args2, deps) => {
158
- const { runAgentReadCommand } = await import("./agentRecordCommands-24JJOYM5.js");
158
+ const { runAgentReadCommand } = await import("./agentRecordCommands-4RQKVPNP.js");
159
159
  return runAgentReadCommand(args2, deps);
160
160
  }),
161
161
  createAgentRunCommand(["agent", "run"], "Run an agent"),
@@ -184,26 +184,26 @@ function getAgentInternalCommandEntries() {
184
184
  return runSetupOfflineMarxistsAgentCommand(args2, deps);
185
185
  }),
186
186
  createEnvCommand(["agent", "update"], "Update agent fields", async (args2, deps) => {
187
- const { runAgentUpdateCommand } = await import("./agentRecordCommands-24JJOYM5.js");
187
+ const { runAgentUpdateCommand } = await import("./agentRecordCommands-4RQKVPNP.js");
188
188
  return runAgentUpdateCommand(args2, deps);
189
189
  }),
190
190
  createEnvCommand(["agent", "email", "provision"], "Provision a controlled inbox for an agent", async (args2, deps) => {
191
- const { runAgentEmailProvisionCommand } = await import("./agentEmailCommands-CS3MWA2L.js");
191
+ const { runAgentEmailProvisionCommand } = await import("./agentEmailCommands-QRVMJZ4C.js");
192
192
  return runAgentEmailProvisionCommand(args2, deps);
193
193
  }),
194
194
  createEnvCommand(["agent", "email", "bind"], "Bind an existing email address to an agent", async (args2, deps) => {
195
- const { runAgentEmailBindCommand } = await import("./agentEmailCommands-CS3MWA2L.js");
195
+ const { runAgentEmailBindCommand } = await import("./agentEmailCommands-QRVMJZ4C.js");
196
196
  return runAgentEmailBindCommand(args2, deps);
197
197
  }),
198
198
  createEnvCommand(["agent", "email", "transfer"], "Transfer an email identity from one agent to another (cross-account)", async (args2, deps) => {
199
- const { runAgentEmailTransferCommand } = await import("./agentEmailCommands-CS3MWA2L.js");
199
+ const { runAgentEmailTransferCommand } = await import("./agentEmailCommands-QRVMJZ4C.js");
200
200
  return runAgentEmailTransferCommand(args2, deps);
201
201
  }),
202
202
  createEnvCommand(
203
203
  ["agent", "email", "create-and-provision"],
204
204
  "Create an agent and provision its controlled inbox",
205
205
  async (args2, deps) => {
206
- const { runAgentEmailCreateAndProvisionCommand } = await import("./agentEmailCommands-CS3MWA2L.js");
206
+ const { runAgentEmailCreateAndProvisionCommand } = await import("./agentEmailCommands-QRVMJZ4C.js");
207
207
  return runAgentEmailCreateAndProvisionCommand(args2, deps);
208
208
  }
209
209
  ),
@@ -224,15 +224,15 @@ function getAgentInternalCommandEntries() {
224
224
  return runAgentRevokeGrantCommand(args2, deps);
225
225
  }),
226
226
  createEnvCommand(["agent", "bind-current"], "Bind an agent to this machine", async (args2, deps) => {
227
- const { runAgentBindCurrentCommand } = await import("./agentMachineCommands-XGM4IGGG.js");
227
+ const { runAgentBindCurrentCommand } = await import("./agentMachineCommands-BLILYHBN.js");
228
228
  return runAgentBindCurrentCommand(args2, deps);
229
229
  }),
230
230
  createEnvCommand(["agent", "smoke-current"], "Smoke test a bound agent through this machine", async (args2, deps) => {
231
- const { runAgentSmokeCurrentCommand } = await import("./agentMachineCommands-XGM4IGGG.js");
231
+ const { runAgentSmokeCurrentCommand } = await import("./agentMachineCommands-BLILYHBN.js");
232
232
  return runAgentSmokeCurrentCommand(args2, deps);
233
233
  }),
234
234
  createEnvCommand(["agent", "runtime-doctor"], "Diagnose current machine runtime compatibility", async (args2, deps) => {
235
- const { runAgentRuntimeDoctorCommand } = await import("./agentMachineCommands-XGM4IGGG.js");
235
+ const { runAgentRuntimeDoctorCommand } = await import("./agentMachineCommands-BLILYHBN.js");
236
236
  return runAgentRuntimeDoctorCommand(args2, deps);
237
237
  }),
238
238
  createAgentRunCommand(["agent", "chat"], "Chat with an agent")
@@ -472,15 +472,15 @@ function getSystemInternalCommandEntries(renderHelpText2) {
472
472
  return runWhoamiCommand({ args: args2, env: ctx.env });
473
473
  }),
474
474
  createEntrypointEnvCommand(["connect"], "Send machine heartbeats or hold a connector websocket", async (args2, deps) => {
475
- const { runMachineConnectCommand } = await import("./machineCommands-OBL7PFG5.js");
475
+ const { runMachineConnectCommand } = await import("./machineCommands-BR3OIZHN.js");
476
476
  return runMachineConnectCommand(args2, deps);
477
477
  }),
478
478
  createDaemonShortcutCommand(["daemon"], "Run the connector daemon shortcut", async (args2, deps) => {
479
- const { runMachineConnectCommand } = await import("./machineCommands-OBL7PFG5.js");
479
+ const { runMachineConnectCommand } = await import("./machineCommands-BR3OIZHN.js");
480
480
  return runMachineConnectCommand(args2, deps);
481
481
  }),
482
482
  createEnvCommand(["machine", "status"], "List machines registered to the current profile", async (args2, deps) => {
483
- const { runMachineStatusCommand } = await import("./machineCommands-OBL7PFG5.js");
483
+ const { runMachineStatusCommand } = await import("./machineCommands-BR3OIZHN.js");
484
484
  return runMachineStatusCommand(args2, deps);
485
485
  }),
486
486
  createEnvCommand(["doctor", "runtime"], "Diagnose local-first agent runtime selection", async (args2, deps) => {
@@ -875,7 +875,7 @@ async function runScript(script, forwardedArgs, env) {
875
875
  return proc.exited;
876
876
  }
877
877
  async function launchTuiWorkspace(args2) {
878
- const { startTuiWorkspace } = await import("./readlineWorkspace-TM6BQGNJ.js");
878
+ const { startTuiWorkspace } = await import("./readlineWorkspace-RFSDCOKK.js");
879
879
  const { createTuiSummaryLlmCaller } = await import("./tuiSummaryLlmCaller-3Z24VUWM.js");
880
880
  return startTuiWorkspace({
881
881
  ...args2,
@@ -2,13 +2,13 @@ import {
2
2
  buildMachinePermissionPromptBlock,
3
3
  handleConnectorRunMessage,
4
4
  resolveMachineRunPermissionPolicy
5
- } from "./chunk-HPF7DTOE.js";
5
+ } from "./chunk-JFXQDXYJ.js";
6
6
  import {
7
7
  isConnectorWebSocketAuthError,
8
8
  isConnectorWebSocketRetryableError,
9
9
  resolveConnectorWebSocketTarget
10
10
  } from "./chunk-ALXHV7NK.js";
11
- import "./chunk-VBXDAIEC.js";
11
+ import "./chunk-CIHSMPAW.js";
12
12
  import "./chunk-GBPZKFYK.js";
13
13
  import "./chunk-QCZX4FTW.js";
14
14
  import "./chunk-EADNWBAZ.js";
@@ -11,8 +11,8 @@ import {
11
11
  runtimeWorkspacePermissionPolicy,
12
12
  scopePermissionPolicyToRuntimeWorkspace,
13
13
  summarizeAgentConfigForLogs
14
- } from "./chunk-HPF7DTOE.js";
15
- import "./chunk-VBXDAIEC.js";
14
+ } from "./chunk-JFXQDXYJ.js";
15
+ import "./chunk-CIHSMPAW.js";
16
16
  import "./chunk-GBPZKFYK.js";
17
17
  import "./chunk-QCZX4FTW.js";
18
18
  import "./chunk-EADNWBAZ.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nolo-cli",
3
- "version": "0.75.0-alpha.4",
3
+ "version": "0.75.0-alpha.6",
4
4
  "type": "module",
5
5
  "description": "Agent-first terminal workspace for Nolo",
6
6
  "bin": {
@@ -72,7 +72,7 @@ import {
72
72
  wrapTextToLines,
73
73
  wrapTranscriptLine,
74
74
  wrapTranscriptLineWithLayout
75
- } from "./chunk-AMDSZQCT.js";
75
+ } from "./chunk-RL5PTRUQ.js";
76
76
  import "./chunk-S7Z2HMCN.js";
77
77
  import {
78
78
  listFavoriteAgentIdsAcrossServers,
@@ -96,7 +96,7 @@ import {
96
96
  readTimestamp,
97
97
  setCliLocale,
98
98
  t
99
- } from "./chunk-VBXDAIEC.js";
99
+ } from "./chunk-CIHSMPAW.js";
100
100
  import "./chunk-GBPZKFYK.js";
101
101
  import "./chunk-QCZX4FTW.js";
102
102
  import "./chunk-EADNWBAZ.js";
@@ -4503,6 +4503,36 @@ function detectImagePaths(line, cwd, opts = {}) {
4503
4503
  }
4504
4504
  return out;
4505
4505
  }
4506
+ function detectFileReferences(line, cwd, opts = {}) {
4507
+ const wsl = opts.wsl ?? isWslEnvironment();
4508
+ const excluded = new Set(opts.exclude ?? []);
4509
+ const out = [];
4510
+ const seen = /* @__PURE__ */ new Set();
4511
+ for (const token of tokenizePasteLine(line)) {
4512
+ if (!token.raw || excluded.has(token.raw)) continue;
4513
+ let candidate = token.decoded;
4514
+ const uriPath = fileUriToPath(candidate);
4515
+ if (uriPath !== null) candidate = uriPath;
4516
+ if (wsl) candidate = mapWindowsPathToWsl(candidate);
4517
+ if (candidate.startsWith("~")) candidate = resolveImageSource(candidate, cwd);
4518
+ const looksLikePath = /[/\\]/.test(candidate) || candidate.startsWith("~") || /^[a-zA-Z]:/.test(candidate);
4519
+ if (!looksLikePath) continue;
4520
+ const ext = extnameOf(candidate);
4521
+ if (!/^[a-z0-9]{1,8}$/.test(ext)) continue;
4522
+ if (IMAGE_EXTENSION_SET.has(ext)) continue;
4523
+ const resolved = resolveImageSource(candidate, cwd);
4524
+ if (excluded.has(resolved) || seen.has(resolved)) continue;
4525
+ if (!isReadableFilePath(resolved)) continue;
4526
+ try {
4527
+ if (!statSync(resolved).isFile()) continue;
4528
+ } catch {
4529
+ continue;
4530
+ }
4531
+ seen.add(resolved);
4532
+ out.push({ raw: token.raw, resolvedPath: resolved });
4533
+ }
4534
+ return out;
4535
+ }
4506
4536
  function tokenizePasteLine(line) {
4507
4537
  const tokens = [];
4508
4538
  let rawBuf = "";
@@ -5005,6 +5035,52 @@ async function readClipboardImage(deps = {}) {
5005
5035
  });
5006
5036
  }
5007
5037
 
5038
+ // packages/cli/tui/pasteFlow.ts
5039
+ function isTextFallbackEligibleCode(code) {
5040
+ return code === "empty-clipboard" || code === "binary-missing" || code === "unsupported-platform";
5041
+ }
5042
+ function errorCodeOf(error) {
5043
+ if (typeof error !== "object" || error === null) return void 0;
5044
+ const code = error.code;
5045
+ return code === void 0 || code === null ? void 0 : String(code);
5046
+ }
5047
+ function messageOf(error) {
5048
+ return error instanceof Error ? error.message : String(error);
5049
+ }
5050
+ async function resolveClipboardPaste(deps) {
5051
+ try {
5052
+ const image = await deps.readImage();
5053
+ return { kind: "image", image };
5054
+ } catch (imageError) {
5055
+ const code = errorCodeOf(imageError);
5056
+ if (!isTextFallbackEligibleCode(code)) {
5057
+ return {
5058
+ kind: "error",
5059
+ code: code ?? "read-failed",
5060
+ message: messageOf(imageError)
5061
+ };
5062
+ }
5063
+ let text;
5064
+ try {
5065
+ text = await deps.readText();
5066
+ } catch (textError) {
5067
+ return {
5068
+ kind: "error",
5069
+ code: "text-read-failed",
5070
+ message: `${messageOf(textError)} (${messageOf(imageError)})`
5071
+ };
5072
+ }
5073
+ if (text.length > 0) {
5074
+ return { kind: "text", text };
5075
+ }
5076
+ return { kind: "empty", message: messageOf(imageError) };
5077
+ }
5078
+ }
5079
+ function shouldApplyPastedResult(snapshot, current) {
5080
+ if (current.sessionEnded) return false;
5081
+ return snapshot.epoch === current.epoch;
5082
+ }
5083
+
5008
5084
  // packages/cli/tui/clipboard.ts
5009
5085
  function osc52SetClipboard(text, output) {
5010
5086
  const payload = Buffer.from(text, "utf8").toString("base64");
@@ -5634,6 +5710,7 @@ var SLASH_COMMANDS = [
5634
5710
  "/resume",
5635
5711
  "/lang",
5636
5712
  "/copy",
5713
+ "/paste",
5637
5714
  "/mouse",
5638
5715
  "/math",
5639
5716
  "/doc",
@@ -5990,12 +6067,18 @@ function handleTuiInput(input, state) {
5990
6067
  const stripped = stripImageTokens(trimmed, readableHints);
5991
6068
  const finalMessage = stripped.length > 0 ? stripped : trimmed;
5992
6069
  const imagePaths = readableHints.map((hint) => hint.resolvedPath);
5993
- const preview = hints.length > 0 ? hints.map(
5994
- (hint) => hint.unreadable ? `image path unreadable: ${hint.resolvedPath}` : `found image: ${hint.resolvedPath}`
5995
- ).join("\n") : "";
6070
+ const fileRefs = detectFileReferences(trimmed, state.cwd, {
6071
+ exclude: hints.map((hint) => hint.resolvedPath)
6072
+ });
6073
+ const previewLines = [
6074
+ ...hints.map(
6075
+ (hint) => hint.unreadable ? `image path unreadable: ${hint.resolvedPath}` : `found image: ${hint.resolvedPath}`
6076
+ ),
6077
+ ...fileRefs.map((ref) => t("pasteFilePathHint", ref.resolvedPath))
6078
+ ];
5996
6079
  return {
5997
6080
  nextState: state,
5998
- output: preview,
6081
+ output: previewLines.join("\n"),
5999
6082
  action: {
6000
6083
  type: "chat",
6001
6084
  message: finalMessage,
@@ -6342,6 +6425,15 @@ ${t("autoUsage")}`
6342
6425
  }
6343
6426
  return { nextState: state, output: t("copyUsage") };
6344
6427
  }
6428
+ case "/paste":
6429
+ if (argText) {
6430
+ return { nextState: state, output: t("pasteUsage") };
6431
+ }
6432
+ return {
6433
+ nextState: state,
6434
+ output: "",
6435
+ action: { type: "paste-clipboard" }
6436
+ };
6345
6437
  case "/mouse": {
6346
6438
  if (argText !== "on" && argText !== "off") {
6347
6439
  return { nextState: state, output: t("mouseUsage") };
@@ -9762,6 +9854,8 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
9762
9854
  persistExplicitAgentSwitch,
9763
9855
  persistAgentSelection: persistAgentSelection2,
9764
9856
  writeClipboard: writeClipboard2,
9857
+ readAndApplyClipboard,
9858
+ bumpDraftEpoch,
9765
9859
  selfUpdater,
9766
9860
  spawnRunner,
9767
9861
  installAltScreenRestoreHandlers: installAltScreenRestoreHandlers2
@@ -9770,9 +9864,12 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
9770
9864
  const previousAgentKey = host.state.agentKey;
9771
9865
  host.state = result.nextState;
9772
9866
  const interactive = isInteractiveInput(input);
9867
+ const isChatAction = result.action?.type === "chat";
9773
9868
  if (result.action?.type !== "exit" && result.output) {
9774
- const shouldEmit = result.action?.type !== "chat" || !interactive;
9775
- if (shouldEmit) emitCommandOutput(result.output, interactive ? line.trim() : "");
9869
+ emitCommandOutput(
9870
+ result.output,
9871
+ interactive && !isChatAction ? line.trim() : ""
9872
+ );
9776
9873
  }
9777
9874
  if (host.state.agentKey !== previousAgentKey) {
9778
9875
  persistExplicitAgentSwitch(previousAgentKey);
@@ -9803,6 +9900,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
9803
9900
  }
9804
9901
  }
9805
9902
  clearCollapsedPasteStore(pasteStore);
9903
+ bumpDraftEpoch();
9806
9904
  host.state = {
9807
9905
  ...host.state,
9808
9906
  turnTokens: void 0,
@@ -10063,6 +10161,9 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
10063
10161
  }
10064
10162
  }
10065
10163
  }
10164
+ if (result.action?.type === "paste-clipboard") {
10165
+ await readAndApplyClipboard("slash");
10166
+ }
10066
10167
  if (result.action?.type === "pick-dialog") {
10067
10168
  const interactivePicker = isInteractiveInput(input);
10068
10169
  try {
@@ -10105,6 +10206,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
10105
10206
  };
10106
10207
  seedDialogCreditsBase(pickResult.dialog.id, pickResult.dialog.dbKey);
10107
10208
  clearCollapsedPasteStore(pasteStore);
10209
+ bumpDraftEpoch();
10108
10210
  emitCommandOutput(
10109
10211
  `${t("resumedDialogPrefix")}: ${pickResult.dialog.title} (${pickResult.dialog.id})`
10110
10212
  );
@@ -10344,7 +10446,7 @@ var WELCOME_ANIM_MAX_FRAME = 8;
10344
10446
  var WELCOME_ANIM_INTERVAL_MS = 70;
10345
10447
  function isClipboardImageFallbackEligible(error) {
10346
10448
  const code = error instanceof ClipboardImageError ? error.code : typeof error === "object" && error !== null && "code" in error ? String(error.code) : void 0;
10347
- return code === "empty-clipboard" || code === "binary-missing" || code === "unsupported-platform";
10449
+ return isTextFallbackEligibleCode(code);
10348
10450
  }
10349
10451
  async function runTuiWorkspace(options) {
10350
10452
  const startupThemeMode = resolveTuiThemeMode(
@@ -10667,6 +10769,10 @@ async function runTuiWorkspace(options) {
10667
10769
  state = { ...state, sessionCredits: (state.sessionCredits ?? 0) + credits };
10668
10770
  };
10669
10771
  let composerDecoderDrain = null;
10772
+ let draftEpoch = 0;
10773
+ const bumpDraftEpoch = () => {
10774
+ draftEpoch += 1;
10775
+ };
10670
10776
  const emitCommandOutput = (text, command = "") => {
10671
10777
  if (!text) return;
10672
10778
  if (!isInteractiveInput(input)) {
@@ -10679,6 +10785,53 @@ async function runTuiWorkspace(options) {
10679
10785
  renderHistoryToOutput();
10680
10786
  if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
10681
10787
  };
10788
+ const applyClipboardPasteResult = (outcome, source) => {
10789
+ const colorEnabled = resolveCliColorEnabled();
10790
+ if (outcome.kind === "image") {
10791
+ state = {
10792
+ ...state,
10793
+ attachedImages: mergeAttachedImages(state.attachedImages, [outcome.image])
10794
+ };
10795
+ emitCommandOutput(summarizeAttachment(outcome.image));
10796
+ if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
10797
+ return;
10798
+ }
10799
+ if (outcome.kind === "text") {
10800
+ const pasteResult = applyTuiInputKey(
10801
+ buffer,
10802
+ `${PASTE_TOKEN_PREFIX}${outcome.text}`,
10803
+ {},
10804
+ cursorPos,
10805
+ { pasteStore, cwd: state.cwd }
10806
+ );
10807
+ buffer = pasteResult.buffer;
10808
+ cursorPos = pasteResult.cursorPos ?? buffer.length;
10809
+ if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
10810
+ if (source === "slash") {
10811
+ emitCommandOutput(t("pasteTextInserted", String(outcome.text.length)));
10812
+ }
10813
+ return;
10814
+ }
10815
+ emitCommandOutput(
10816
+ themeText(`[nolo] ${outcome.message}`, "warning", colorEnabled)
10817
+ );
10818
+ if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
10819
+ };
10820
+ const readAndApplyClipboard = async (source) => {
10821
+ const snapshot = { epoch: draftEpoch, sessionEnded };
10822
+ const outcome = await resolveClipboardPaste({
10823
+ readImage: () => readImage({ env: options.env ?? process.env }),
10824
+ readText: () => readClipboardText()
10825
+ });
10826
+ if (!shouldApplyPastedResult(snapshot, { epoch: draftEpoch, sessionEnded })) {
10827
+ if (!sessionEnded) {
10828
+ emitCommandOutput(t("pasteStaleDropped"));
10829
+ }
10830
+ return false;
10831
+ }
10832
+ applyClipboardPasteResult(outcome, source);
10833
+ return true;
10834
+ };
10682
10835
  let chatQueueBinding = null;
10683
10836
  let turnInjectionInbox = null;
10684
10837
  const turnCtx = {
@@ -10801,6 +10954,8 @@ async function runTuiWorkspace(options) {
10801
10954
  persistExplicitAgentSwitch,
10802
10955
  persistAgentSelection,
10803
10956
  writeClipboard: writeClipboard2,
10957
+ readAndApplyClipboard,
10958
+ bumpDraftEpoch,
10804
10959
  selfUpdater,
10805
10960
  spawnRunner,
10806
10961
  installAltScreenRestoreHandlers
@@ -11109,6 +11264,7 @@ ${err.message}` : ""}`
11109
11264
  clearSelection();
11110
11265
  }
11111
11266
  if (buffer.length > 0) {
11267
+ bumpDraftEpoch();
11112
11268
  buffer = "";
11113
11269
  cursorPos = 0;
11114
11270
  if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
@@ -11126,11 +11282,16 @@ ${err.message}` : ""}`
11126
11282
  };
11127
11283
  const handleBusyLocalSlash = async (submittedText, busySlashCommand) => {
11128
11284
  releaseCollapsedPasteReferences(submittedText, pasteStore);
11285
+ bumpDraftEpoch();
11129
11286
  buffer = "";
11130
11287
  cursorPos = 0;
11131
11288
  if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
11132
11289
  const beforeAgentKey = state.agentKey;
11133
11290
  const res = handleTuiInput(submittedText, state);
11291
+ if (res.action?.type === "paste-clipboard") {
11292
+ await readAndApplyClipboard("slash");
11293
+ return;
11294
+ }
11134
11295
  if (res.action?.type === "theme-refresh") {
11135
11296
  state = res.nextState;
11136
11297
  const detected = await detectTerminalBackground({
@@ -11359,45 +11520,10 @@ ${merged}` : merged;
11359
11520
  return;
11360
11521
  }
11361
11522
  const isPasteToken = sequence.startsWith(PASTE_TOKEN_PREFIX);
11362
- const isPasteShortcut = sequence === "" || isPasteToken && sequence.slice(PASTE_TOKEN_PREFIX.length).trim() === "";
11523
+ const isEmptyBracketedPaste = isPasteToken && sequence.slice(PASTE_TOKEN_PREFIX.length).trim() === "";
11524
+ const isPasteShortcut = sequence === "" || isEmptyBracketedPaste;
11363
11525
  if (isPasteShortcut) {
11364
- try {
11365
- const image = await readImage({
11366
- env: options.env ?? process.env
11367
- });
11368
- state = {
11369
- ...state,
11370
- attachedImages: mergeAttachedImages(state.attachedImages, [image])
11371
- };
11372
- emitCommandOutput(summarizeAttachment(image));
11373
- } catch (error) {
11374
- if (isClipboardImageFallbackEligible(error)) {
11375
- let clipboardText = "";
11376
- try {
11377
- clipboardText = await readClipboardText();
11378
- } catch {
11379
- clipboardText = "";
11380
- }
11381
- if (clipboardText.length > 0) {
11382
- const pasteResult = applyTuiInputKey(
11383
- buffer,
11384
- `${PASTE_TOKEN_PREFIX}${clipboardText}`,
11385
- {},
11386
- cursorPos,
11387
- { pasteStore, cwd: state.cwd }
11388
- );
11389
- buffer = pasteResult.buffer;
11390
- cursorPos = pasteResult.cursorPos;
11391
- if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
11392
- return;
11393
- }
11394
- }
11395
- const msg = error instanceof Error ? error.message : String(error);
11396
- emitCommandOutput(
11397
- themeText(`[nolo] ${msg}`, "warning", resolveCliColorEnabled())
11398
- );
11399
- }
11400
- if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
11526
+ await readAndApplyClipboard(isEmptyBracketedPaste ? "bracketed-empty" : "key");
11401
11527
  return;
11402
11528
  }
11403
11529
  if (isBackspaceSequence(sequence, {}) && buffer === "" && state.attachedImages.length > 0) {
@@ -11436,7 +11562,7 @@ ${merged}` : merged;
11436
11562
  if (busyLock) {
11437
11563
  const trimmedText = submittedText.trim();
11438
11564
  const busySlashCommand = trimmedText.split(/\s+/)[0]?.toLowerCase();
11439
- const isBusyLocalSlash = busySlashCommand === "/context" || busySlashCommand === "/ctx" || busySlashCommand === "/cd" || busySlashCommand === "/switch" || busySlashCommand === "/theme" || busySlashCommand === "/runtime" || busySlashCommand === "/tools" || busySlashCommand === "/thinking" || busySlashCommand === "/auto" || busySlashCommand === "/tasks" || busySlashCommand === "/jobs" || busySlashCommand === "/procs" || busySlashCommand === "/agents" || busySlashCommand === "/doc" || busySlashCommand === "/skill" || busySlashCommand === "/customize" || busySlashCommand === "/login" || busySlashCommand === "/profile" || busySlashCommand === "/version";
11565
+ const isBusyLocalSlash = busySlashCommand === "/context" || busySlashCommand === "/ctx" || busySlashCommand === "/cd" || busySlashCommand === "/switch" || busySlashCommand === "/theme" || busySlashCommand === "/runtime" || busySlashCommand === "/tools" || busySlashCommand === "/thinking" || busySlashCommand === "/auto" || busySlashCommand === "/tasks" || busySlashCommand === "/jobs" || busySlashCommand === "/procs" || busySlashCommand === "/agents" || busySlashCommand === "/doc" || busySlashCommand === "/skill" || busySlashCommand === "/customize" || busySlashCommand === "/login" || busySlashCommand === "/profile" || busySlashCommand === "/paste" || busySlashCommand === "/version";
11440
11566
  if (isBusyLocalSlash) {
11441
11567
  await handleBusyLocalSlash(submittedText, busySlashCommand);
11442
11568
  return;
@@ -11465,11 +11591,13 @@ ${merged}` : merged;
11465
11591
  if (drainedText !== null) {
11466
11592
  buffer = "";
11467
11593
  cursorPos = 0;
11594
+ bumpDraftEpoch();
11468
11595
  await runIdleTextTurn(drainedText);
11469
11596
  return;
11470
11597
  }
11471
11598
  }
11472
11599
  busy = startsChatTurn;
11600
+ bumpDraftEpoch();
11473
11601
  buffer = "";
11474
11602
  cursorPos = 0;
11475
11603
  fixedInput.enterOutputMode(submittedText);