nolo-cli 0.75.0-alpha.3 → 0.75.0-alpha.5

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-UPR5N3UO.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;
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-ARZU224Q.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-EGTGFPH4.js");
878
+ const { startTuiWorkspace } = await import("./readlineWorkspace-Y27LK4KJ.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.3",
3
+ "version": "0.75.0-alpha.5",
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-UPR5N3UO.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") };
@@ -8526,6 +8618,8 @@ function createTuiRender(host) {
8526
8618
  // packages/cli/tui/tuiScrollAnimation.ts
8527
8619
  var SCROLL_ANIMATION_TICK_MS = 16;
8528
8620
  var DEFAULT_SCROLL_MAX_LINES_PER_TICK = 6;
8621
+ var ADAPTIVE_STEP_CAP = 20;
8622
+ var EXPLICIT_STEP_CAP = 100;
8529
8623
  function readPositiveInt(raw, fallback, max) {
8530
8624
  if (raw === void 0 || raw.trim() === "") return fallback;
8531
8625
  const parsed = Number.parseInt(raw, 10);
@@ -8533,15 +8627,20 @@ function readPositiveInt(raw, fallback, max) {
8533
8627
  return Math.min(parsed, max);
8534
8628
  }
8535
8629
  function resolveScrollTuning(env = process.env) {
8630
+ const rawStep = env.NOLO_TUI_SCROLL_MAX_STEP;
8631
+ const explicit = parseExplicitStep(rawStep);
8536
8632
  return {
8537
8633
  wheelLines: readPositiveInt(env.NOLO_TUI_WHEEL_LINES, WHEEL_SCROLL_LINES, 50),
8538
- maxLinesPerTick: readPositiveInt(
8539
- env.NOLO_TUI_SCROLL_MAX_STEP,
8540
- DEFAULT_SCROLL_MAX_LINES_PER_TICK,
8541
- 100
8542
- )
8634
+ maxLinesPerTick: explicit ?? DEFAULT_SCROLL_MAX_LINES_PER_TICK,
8635
+ adaptiveStep: explicit === null
8543
8636
  };
8544
8637
  }
8638
+ function parseExplicitStep(raw) {
8639
+ if (raw === void 0 || raw.trim() === "") return null;
8640
+ const parsed = Number.parseInt(raw, 10);
8641
+ if (!Number.isFinite(parsed) || parsed < 1) return null;
8642
+ return Math.min(parsed, EXPLICIT_STEP_CAP);
8643
+ }
8545
8644
  var defaultTickTimer = {
8546
8645
  every(ms, fn) {
8547
8646
  const handle = setInterval(fn, ms);
@@ -8550,9 +8649,10 @@ var defaultTickTimer = {
8550
8649
  }
8551
8650
  };
8552
8651
  function createScrollAnimator(deps) {
8553
- const { wheelLines, maxLinesPerTick } = resolveScrollTuning(
8652
+ const { wheelLines, maxLinesPerTick, adaptiveStep } = resolveScrollTuning(
8554
8653
  deps.env ?? process.env
8555
8654
  );
8655
+ const stepCap = adaptiveStep ? Math.max(ADAPTIVE_STEP_CAP, wheelLines) : maxLinesPerTick;
8556
8656
  const timer = deps.tickTimer ?? defaultTickTimer;
8557
8657
  const history = deps.history;
8558
8658
  let goal = null;
@@ -8590,7 +8690,17 @@ function createScrollAnimator(deps) {
8590
8690
  settle(maxScrollTop);
8591
8691
  return;
8592
8692
  }
8593
- const step = Math.sign(delta) * Math.min(Math.abs(delta), maxLinesPerTick);
8693
+ const backlog = Math.abs(delta);
8694
+ const limit = adaptiveStep ? Math.min(
8695
+ backlog,
8696
+ Math.max(
8697
+ DEFAULT_SCROLL_MAX_LINES_PER_TICK,
8698
+ wheelLines,
8699
+ Math.ceil(backlog / 4)
8700
+ ),
8701
+ stepCap
8702
+ ) : Math.min(backlog, maxLinesPerTick);
8703
+ const step = Math.sign(delta) * limit;
8594
8704
  history.scrollTop += step;
8595
8705
  deps.onPaint();
8596
8706
  if (history.scrollTop === goal) {
@@ -9744,6 +9854,8 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
9744
9854
  persistExplicitAgentSwitch,
9745
9855
  persistAgentSelection: persistAgentSelection2,
9746
9856
  writeClipboard: writeClipboard2,
9857
+ readAndApplyClipboard,
9858
+ bumpDraftEpoch,
9747
9859
  selfUpdater,
9748
9860
  spawnRunner,
9749
9861
  installAltScreenRestoreHandlers: installAltScreenRestoreHandlers2
@@ -9752,9 +9864,12 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
9752
9864
  const previousAgentKey = host.state.agentKey;
9753
9865
  host.state = result.nextState;
9754
9866
  const interactive = isInteractiveInput(input);
9867
+ const isChatAction = result.action?.type === "chat";
9755
9868
  if (result.action?.type !== "exit" && result.output) {
9756
- const shouldEmit = result.action?.type !== "chat" || !interactive;
9757
- if (shouldEmit) emitCommandOutput(result.output, interactive ? line.trim() : "");
9869
+ emitCommandOutput(
9870
+ result.output,
9871
+ interactive && !isChatAction ? line.trim() : ""
9872
+ );
9758
9873
  }
9759
9874
  if (host.state.agentKey !== previousAgentKey) {
9760
9875
  persistExplicitAgentSwitch(previousAgentKey);
@@ -9785,6 +9900,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
9785
9900
  }
9786
9901
  }
9787
9902
  clearCollapsedPasteStore(pasteStore);
9903
+ bumpDraftEpoch();
9788
9904
  host.state = {
9789
9905
  ...host.state,
9790
9906
  turnTokens: void 0,
@@ -10045,6 +10161,9 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
10045
10161
  }
10046
10162
  }
10047
10163
  }
10164
+ if (result.action?.type === "paste-clipboard") {
10165
+ await readAndApplyClipboard("slash");
10166
+ }
10048
10167
  if (result.action?.type === "pick-dialog") {
10049
10168
  const interactivePicker = isInteractiveInput(input);
10050
10169
  try {
@@ -10087,6 +10206,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
10087
10206
  };
10088
10207
  seedDialogCreditsBase(pickResult.dialog.id, pickResult.dialog.dbKey);
10089
10208
  clearCollapsedPasteStore(pasteStore);
10209
+ bumpDraftEpoch();
10090
10210
  emitCommandOutput(
10091
10211
  `${t("resumedDialogPrefix")}: ${pickResult.dialog.title} (${pickResult.dialog.id})`
10092
10212
  );
@@ -10326,7 +10446,7 @@ var WELCOME_ANIM_MAX_FRAME = 8;
10326
10446
  var WELCOME_ANIM_INTERVAL_MS = 70;
10327
10447
  function isClipboardImageFallbackEligible(error) {
10328
10448
  const code = error instanceof ClipboardImageError ? error.code : typeof error === "object" && error !== null && "code" in error ? String(error.code) : void 0;
10329
- return code === "empty-clipboard" || code === "binary-missing" || code === "unsupported-platform";
10449
+ return isTextFallbackEligibleCode(code);
10330
10450
  }
10331
10451
  async function runTuiWorkspace(options) {
10332
10452
  const startupThemeMode = resolveTuiThemeMode(
@@ -10649,6 +10769,10 @@ async function runTuiWorkspace(options) {
10649
10769
  state = { ...state, sessionCredits: (state.sessionCredits ?? 0) + credits };
10650
10770
  };
10651
10771
  let composerDecoderDrain = null;
10772
+ let draftEpoch = 0;
10773
+ const bumpDraftEpoch = () => {
10774
+ draftEpoch += 1;
10775
+ };
10652
10776
  const emitCommandOutput = (text, command = "") => {
10653
10777
  if (!text) return;
10654
10778
  if (!isInteractiveInput(input)) {
@@ -10661,6 +10785,53 @@ async function runTuiWorkspace(options) {
10661
10785
  renderHistoryToOutput();
10662
10786
  if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
10663
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
+ };
10664
10835
  let chatQueueBinding = null;
10665
10836
  let turnInjectionInbox = null;
10666
10837
  const turnCtx = {
@@ -10783,6 +10954,8 @@ async function runTuiWorkspace(options) {
10783
10954
  persistExplicitAgentSwitch,
10784
10955
  persistAgentSelection,
10785
10956
  writeClipboard: writeClipboard2,
10957
+ readAndApplyClipboard,
10958
+ bumpDraftEpoch,
10786
10959
  selfUpdater,
10787
10960
  spawnRunner,
10788
10961
  installAltScreenRestoreHandlers
@@ -11091,6 +11264,7 @@ ${err.message}` : ""}`
11091
11264
  clearSelection();
11092
11265
  }
11093
11266
  if (buffer.length > 0) {
11267
+ bumpDraftEpoch();
11094
11268
  buffer = "";
11095
11269
  cursorPos = 0;
11096
11270
  if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
@@ -11108,11 +11282,16 @@ ${err.message}` : ""}`
11108
11282
  };
11109
11283
  const handleBusyLocalSlash = async (submittedText, busySlashCommand) => {
11110
11284
  releaseCollapsedPasteReferences(submittedText, pasteStore);
11285
+ bumpDraftEpoch();
11111
11286
  buffer = "";
11112
11287
  cursorPos = 0;
11113
11288
  if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
11114
11289
  const beforeAgentKey = state.agentKey;
11115
11290
  const res = handleTuiInput(submittedText, state);
11291
+ if (res.action?.type === "paste-clipboard") {
11292
+ await readAndApplyClipboard("slash");
11293
+ return;
11294
+ }
11116
11295
  if (res.action?.type === "theme-refresh") {
11117
11296
  state = res.nextState;
11118
11297
  const detected = await detectTerminalBackground({
@@ -11341,45 +11520,10 @@ ${merged}` : merged;
11341
11520
  return;
11342
11521
  }
11343
11522
  const isPasteToken = sequence.startsWith(PASTE_TOKEN_PREFIX);
11344
- 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;
11345
11525
  if (isPasteShortcut) {
11346
- try {
11347
- const image = await readImage({
11348
- env: options.env ?? process.env
11349
- });
11350
- state = {
11351
- ...state,
11352
- attachedImages: mergeAttachedImages(state.attachedImages, [image])
11353
- };
11354
- emitCommandOutput(summarizeAttachment(image));
11355
- } catch (error) {
11356
- if (isClipboardImageFallbackEligible(error)) {
11357
- let clipboardText = "";
11358
- try {
11359
- clipboardText = await readClipboardText();
11360
- } catch {
11361
- clipboardText = "";
11362
- }
11363
- if (clipboardText.length > 0) {
11364
- const pasteResult = applyTuiInputKey(
11365
- buffer,
11366
- `${PASTE_TOKEN_PREFIX}${clipboardText}`,
11367
- {},
11368
- cursorPos,
11369
- { pasteStore, cwd: state.cwd }
11370
- );
11371
- buffer = pasteResult.buffer;
11372
- cursorPos = pasteResult.cursorPos;
11373
- if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
11374
- return;
11375
- }
11376
- }
11377
- const msg = error instanceof Error ? error.message : String(error);
11378
- emitCommandOutput(
11379
- themeText(`[nolo] ${msg}`, "warning", resolveCliColorEnabled())
11380
- );
11381
- }
11382
- if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
11526
+ await readAndApplyClipboard(isEmptyBracketedPaste ? "bracketed-empty" : "key");
11383
11527
  return;
11384
11528
  }
11385
11529
  if (isBackspaceSequence(sequence, {}) && buffer === "" && state.attachedImages.length > 0) {
@@ -11418,7 +11562,7 @@ ${merged}` : merged;
11418
11562
  if (busyLock) {
11419
11563
  const trimmedText = submittedText.trim();
11420
11564
  const busySlashCommand = trimmedText.split(/\s+/)[0]?.toLowerCase();
11421
- 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";
11422
11566
  if (isBusyLocalSlash) {
11423
11567
  await handleBusyLocalSlash(submittedText, busySlashCommand);
11424
11568
  return;
@@ -11447,11 +11591,13 @@ ${merged}` : merged;
11447
11591
  if (drainedText !== null) {
11448
11592
  buffer = "";
11449
11593
  cursorPos = 0;
11594
+ bumpDraftEpoch();
11450
11595
  await runIdleTextTurn(drainedText);
11451
11596
  return;
11452
11597
  }
11453
11598
  }
11454
11599
  busy = startsChatTurn;
11600
+ bumpDraftEpoch();
11455
11601
  buffer = "";
11456
11602
  cursorPos = 0;
11457
11603
  fixedInput.enterOutputMode(submittedText);