nolo-cli 0.105.0-alpha.1 → 0.105.0-alpha.2

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-V7E4PXQD.js";
9
9
  import {
10
10
  runAgentCreateCommand
11
- } from "./chunk-S6JLBH6Z.js";
12
- import "./chunk-RJ4QOQDA.js";
11
+ } from "./chunk-HVP6P5FV.js";
12
+ import "./chunk-OWS6OYF4.js";
13
13
  import "./chunk-53HEEOTT.js";
14
14
  import "./chunk-EADNWBAZ.js";
15
15
  import "./chunk-SH43IESU.js";
@@ -91,7 +91,7 @@ async function defaultExecuteCli(provider, prompt, options) {
91
91
  return executeCli(provider, prompt, options);
92
92
  }
93
93
  async function forwardConnectorRunMessage(machine, message, pushMessage, executeCli, env, fetchImpl) {
94
- const { handleConnectorRunMessage } = await import("./machineWsRunDispatch-D2NHL3P7.js");
94
+ const { handleConnectorRunMessage } = await import("./machineWsRunDispatch-OVA3G76V.js");
95
95
  return handleConnectorRunMessage(message, pushMessage, executeCli, env, fetchImpl);
96
96
  }
97
97
  async function detectLaunchableMachineInfo() {
@@ -2,8 +2,8 @@ import {
2
2
  runAgentCreateCommand,
3
3
  runAgentReadCommand,
4
4
  runAgentUpdateCommand
5
- } from "./chunk-S6JLBH6Z.js";
6
- import "./chunk-RJ4QOQDA.js";
5
+ } from "./chunk-HVP6P5FV.js";
6
+ import "./chunk-OWS6OYF4.js";
7
7
  import "./chunk-53HEEOTT.js";
8
8
  import "./chunk-EADNWBAZ.js";
9
9
  import "./chunk-SH43IESU.js";
@@ -8,12 +8,12 @@ import {
8
8
  resolveRunSettlementNote,
9
9
  resolveWorkflowReference,
10
10
  runAgentRunCommand
11
- } from "./chunk-O7EBSHZR.js";
11
+ } from "./chunk-U7ISRJQO.js";
12
12
  import "./chunk-S7Z2HMCN.js";
13
13
  import {
14
14
  parseAgentRunArgs
15
15
  } from "./chunk-V7E4PXQD.js";
16
- import "./chunk-RJ4QOQDA.js";
16
+ import "./chunk-OWS6OYF4.js";
17
17
  import "./chunk-53HEEOTT.js";
18
18
  import "./chunk-EADNWBAZ.js";
19
19
  import "./chunk-SH43IESU.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  clearCliLocalRuntimePreparedAgentCache
3
- } from "./chunk-RJ4QOQDA.js";
3
+ } from "./chunk-OWS6OYF4.js";
4
4
  import {
5
5
  getReadableCliDb
6
6
  } from "./chunk-LS2ZANRJ.js";
@@ -1066,6 +1066,18 @@ var STRINGS = {
1066
1066
  en: "Unknown command: {0}\n\n",
1067
1067
  zh: "\u672A\u77E5\u547D\u4EE4\uFF1A{0}\n\n"
1068
1068
  },
1069
+ noConversationLinks: {
1070
+ en: "No links in this conversation yet.",
1071
+ zh: "\u672C\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u51FA\u73B0\u94FE\u63A5\u3002"
1072
+ },
1073
+ conversationLinksCopyHint: {
1074
+ en: "Open one by copying its URL (Cmd/Ctrl + click, or select and copy).",
1075
+ zh: "\u590D\u5236\u5BF9\u5E94 URL \u5373\u53EF\u6253\u5F00\uFF08Cmd/Ctrl + \u70B9\u51FB\uFF0C\u6216\u9009\u4E2D\u590D\u5236\uFF09\u3002"
1076
+ },
1077
+ conversationLinksShowing: {
1078
+ en: "Links in this conversation (showing first {0} of {1}):",
1079
+ zh: "\u672C\u4F1A\u8BDD\u51FA\u73B0\u7684\u94FE\u63A5\uFF08\u663E\u793A\u524D {0} \u4E2A\uFF0C\u5171 {1} \u4E2A\uFF09\uFF1A"
1080
+ },
1069
1081
  runtimeUsage: { en: "Usage: /runtime <auto|local|server>", zh: "\u7528\u6CD5\uFF1A/runtime <auto|local|server>" },
1070
1082
  runtimeSet: { en: "Runtime: {0}", zh: "\u8FD0\u884C\u6A21\u5F0F\uFF1A{0}" },
1071
1083
  displayFixedHint: {
@@ -27,7 +27,7 @@ import {
27
27
  resolveLocalUserId,
28
28
  t,
29
29
  toolLabel
30
- } from "./chunk-RJ4QOQDA.js";
30
+ } from "./chunk-OWS6OYF4.js";
31
31
  import {
32
32
  createRunActivityTracker,
33
33
  popSingleQueueMessage,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createCliLocalRuntimeAdapter,
3
3
  summarizeEndpoint
4
- } from "./chunk-RJ4QOQDA.js";
4
+ } from "./chunk-OWS6OYF4.js";
5
5
  import {
6
6
  clipMultilineText
7
7
  } from "./chunk-H66KLASO.js";
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-7VTYZY3Q.js");
130
+ const { runAgentRunCommand } = await import("./agentRunCommand-AVBWVTAJ.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-JY4IWSSQ.js");
146
+ const { runAgentCreateCommand } = await import("./agentRecordCommands-UOF6YM5M.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) => {
@@ -159,7 +159,7 @@ function getAgentInternalCommandEntries() {
159
159
  return runAgentPullCommand(args2, deps);
160
160
  }),
161
161
  createEnvCommand(["agent", "read"], "Read a single agent", async (args2, deps) => {
162
- const { runAgentReadCommand } = await import("./agentRecordCommands-JY4IWSSQ.js");
162
+ const { runAgentReadCommand } = await import("./agentRecordCommands-UOF6YM5M.js");
163
163
  return runAgentReadCommand(args2, deps);
164
164
  }),
165
165
  createAgentRunCommand(["agent", "run"], "Run an agent"),
@@ -188,26 +188,26 @@ function getAgentInternalCommandEntries() {
188
188
  return runSetupOfflineMarxistsAgentCommand(args2, deps);
189
189
  }),
190
190
  createEnvCommand(["agent", "update"], "Update agent fields", async (args2, deps) => {
191
- const { runAgentUpdateCommand } = await import("./agentRecordCommands-JY4IWSSQ.js");
191
+ const { runAgentUpdateCommand } = await import("./agentRecordCommands-UOF6YM5M.js");
192
192
  return runAgentUpdateCommand(args2, deps);
193
193
  }),
194
194
  createEnvCommand(["agent", "email", "provision"], "Provision a controlled inbox for an agent", async (args2, deps) => {
195
- const { runAgentEmailProvisionCommand } = await import("./agentEmailCommands-AQZVMNLR.js");
195
+ const { runAgentEmailProvisionCommand } = await import("./agentEmailCommands-J6YBHL42.js");
196
196
  return runAgentEmailProvisionCommand(args2, deps);
197
197
  }),
198
198
  createEnvCommand(["agent", "email", "bind"], "Bind an existing email address to an agent", async (args2, deps) => {
199
- const { runAgentEmailBindCommand } = await import("./agentEmailCommands-AQZVMNLR.js");
199
+ const { runAgentEmailBindCommand } = await import("./agentEmailCommands-J6YBHL42.js");
200
200
  return runAgentEmailBindCommand(args2, deps);
201
201
  }),
202
202
  createEnvCommand(["agent", "email", "transfer"], "Transfer an email identity from one agent to another (cross-account)", async (args2, deps) => {
203
- const { runAgentEmailTransferCommand } = await import("./agentEmailCommands-AQZVMNLR.js");
203
+ const { runAgentEmailTransferCommand } = await import("./agentEmailCommands-J6YBHL42.js");
204
204
  return runAgentEmailTransferCommand(args2, deps);
205
205
  }),
206
206
  createEnvCommand(
207
207
  ["agent", "email", "create-and-provision"],
208
208
  "Create an agent and provision its controlled inbox",
209
209
  async (args2, deps) => {
210
- const { runAgentEmailCreateAndProvisionCommand } = await import("./agentEmailCommands-AQZVMNLR.js");
210
+ const { runAgentEmailCreateAndProvisionCommand } = await import("./agentEmailCommands-J6YBHL42.js");
211
211
  return runAgentEmailCreateAndProvisionCommand(args2, deps);
212
212
  }
213
213
  ),
@@ -228,15 +228,15 @@ function getAgentInternalCommandEntries() {
228
228
  return runAgentRevokeGrantCommand(args2, deps);
229
229
  }),
230
230
  createEnvCommand(["agent", "bind-current"], "Bind an agent to this machine", async (args2, deps) => {
231
- const { runAgentBindCurrentCommand } = await import("./agentMachineCommands-R5AVYYN3.js");
231
+ const { runAgentBindCurrentCommand } = await import("./agentMachineCommands-2RWGEBA3.js");
232
232
  return runAgentBindCurrentCommand(args2, deps);
233
233
  }),
234
234
  createEnvCommand(["agent", "smoke-current"], "Smoke test a bound agent through this machine", async (args2, deps) => {
235
- const { runAgentSmokeCurrentCommand } = await import("./agentMachineCommands-R5AVYYN3.js");
235
+ const { runAgentSmokeCurrentCommand } = await import("./agentMachineCommands-2RWGEBA3.js");
236
236
  return runAgentSmokeCurrentCommand(args2, deps);
237
237
  }),
238
238
  createEnvCommand(["agent", "runtime-doctor"], "Diagnose current machine runtime compatibility", async (args2, deps) => {
239
- const { runAgentRuntimeDoctorCommand } = await import("./agentMachineCommands-R5AVYYN3.js");
239
+ const { runAgentRuntimeDoctorCommand } = await import("./agentMachineCommands-2RWGEBA3.js");
240
240
  return runAgentRuntimeDoctorCommand(args2, deps);
241
241
  }),
242
242
  createAgentRunCommand(["agent", "chat"], "Chat with an agent")
@@ -488,15 +488,15 @@ function getSystemInternalCommandEntries(renderHelpText2) {
488
488
  return runWhoamiCommand({ args: args2, env: ctx.env });
489
489
  }),
490
490
  createEntrypointEnvCommand(["connect"], "Send machine heartbeats or hold a connector websocket", async (args2, deps) => {
491
- const { runMachineConnectCommand } = await import("./machineCommands-7DEUPY32.js");
491
+ const { runMachineConnectCommand } = await import("./machineCommands-ERCXIPJC.js");
492
492
  return runMachineConnectCommand(args2, deps);
493
493
  }),
494
494
  createDaemonShortcutCommand(["daemon"], "Run the connector daemon shortcut", async (args2, deps) => {
495
- const { runMachineConnectCommand } = await import("./machineCommands-7DEUPY32.js");
495
+ const { runMachineConnectCommand } = await import("./machineCommands-ERCXIPJC.js");
496
496
  return runMachineConnectCommand(args2, deps);
497
497
  }),
498
498
  createEnvCommand(["machine", "status"], "List machines registered to the current profile", async (args2, deps) => {
499
- const { runMachineStatusCommand } = await import("./machineCommands-7DEUPY32.js");
499
+ const { runMachineStatusCommand } = await import("./machineCommands-ERCXIPJC.js");
500
500
  return runMachineStatusCommand(args2, deps);
501
501
  }),
502
502
  createEnvCommand(["doctor", "runtime"], "Diagnose local-first agent runtime selection", async (args2, deps) => {
@@ -892,7 +892,7 @@ async function runScript(script, forwardedArgs, env) {
892
892
  return proc.exited;
893
893
  }
894
894
  async function launchTuiWorkspace(args2) {
895
- const { startTuiWorkspace } = await import("./readlineWorkspace-JP2AOALW.js");
895
+ const { startTuiWorkspace } = await import("./readlineWorkspace-PXATJOED.js");
896
896
  const { createTuiSummaryLlmCaller } = await import("./tuiSummaryLlmCaller-WFRWERGK.js");
897
897
  return startTuiWorkspace({
898
898
  ...args2,
@@ -2,13 +2,13 @@ import {
2
2
  buildMachinePermissionPromptBlock,
3
3
  handleConnectorRunMessage,
4
4
  resolveMachineRunPermissionPolicy
5
- } from "./chunk-VLI5LVL5.js";
5
+ } from "./chunk-XPVRVN4U.js";
6
6
  import {
7
7
  isConnectorWebSocketAuthError,
8
8
  isConnectorWebSocketRetryableError,
9
9
  resolveConnectorWebSocketTarget
10
10
  } from "./chunk-ALXHV7NK.js";
11
- import "./chunk-RJ4QOQDA.js";
11
+ import "./chunk-OWS6OYF4.js";
12
12
  import "./chunk-53HEEOTT.js";
13
13
  import "./chunk-EADNWBAZ.js";
14
14
  import "./chunk-SH43IESU.js";
@@ -11,8 +11,8 @@ import {
11
11
  runtimeWorkspacePermissionPolicy,
12
12
  scopePermissionPolicyToRuntimeWorkspace,
13
13
  summarizeAgentConfigForLogs
14
- } from "./chunk-VLI5LVL5.js";
15
- import "./chunk-RJ4QOQDA.js";
14
+ } from "./chunk-XPVRVN4U.js";
15
+ import "./chunk-OWS6OYF4.js";
16
16
  import "./chunk-53HEEOTT.js";
17
17
  import "./chunk-EADNWBAZ.js";
18
18
  import "./chunk-SH43IESU.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nolo-cli",
3
- "version": "0.105.0-alpha.1",
3
+ "version": "0.105.0-alpha.2",
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-O7EBSHZR.js";
75
+ } from "./chunk-U7ISRJQO.js";
76
76
  import "./chunk-S7Z2HMCN.js";
77
77
  import "./chunk-V7E4PXQD.js";
78
78
  import {
@@ -97,7 +97,7 @@ import {
97
97
  readTimestamp,
98
98
  setCliLocale,
99
99
  t
100
- } from "./chunk-RJ4QOQDA.js";
100
+ } from "./chunk-OWS6OYF4.js";
101
101
  import "./chunk-53HEEOTT.js";
102
102
  import "./chunk-EADNWBAZ.js";
103
103
  import "./chunk-SH43IESU.js";
@@ -5737,6 +5737,7 @@ var SLASH_COMMANDS = [
5737
5737
  "/context",
5738
5738
  "/ctx",
5739
5739
  "/credits",
5740
+ "/links",
5740
5741
  "/cd",
5741
5742
  "/runtime",
5742
5743
  "/auto",
@@ -5838,6 +5839,58 @@ function stripImageTokens(input, hints) {
5838
5839
  return compactWhitespace(out);
5839
5840
  }
5840
5841
 
5842
+ // packages/cli/tui/conversationLinks.ts
5843
+ var URL_PATTERN = /https?:\/\/[^\s<>"'`]+/gi;
5844
+ function trimUrl(raw) {
5845
+ const CLOSERS = { ")": "(", "]": "[", "}": "{" };
5846
+ let out = raw.replace(/[.,;:!?]+$/, "");
5847
+ while (out) {
5848
+ const last = out[out.length - 1];
5849
+ const opener = CLOSERS[last];
5850
+ if (!opener) break;
5851
+ const openCount = out.split(opener).length - 1;
5852
+ const closeCount = out.split(last).length - 1;
5853
+ if (closeCount > openCount) {
5854
+ out = out.slice(0, -1);
5855
+ continue;
5856
+ }
5857
+ break;
5858
+ }
5859
+ return out;
5860
+ }
5861
+ function extractConversationLinks(turns, options = {}) {
5862
+ const limit = options.limit ?? 20;
5863
+ const seen = /* @__PURE__ */ new Map();
5864
+ let total = 0;
5865
+ for (const turn of turns) {
5866
+ const content = typeof turn?.content === "string" ? turn.content : "";
5867
+ if (!content) continue;
5868
+ if (turn?.role === "local") continue;
5869
+ const role = turn?.role === "user" ? "user" : "assistant";
5870
+ const pattern = new RegExp(URL_PATTERN.source, "gi");
5871
+ let match;
5872
+ while ((match = pattern.exec(content)) !== null) {
5873
+ const url = trimUrl(match[0]);
5874
+ if (!url || seen.has(url)) continue;
5875
+ if (seen.size < limit) {
5876
+ seen.set(url, { url, role, index: seen.size + 1 });
5877
+ }
5878
+ total += 1;
5879
+ }
5880
+ }
5881
+ return { links: [...seen.values()], total, hasMore: total > seen.size };
5882
+ }
5883
+ function renderConversationLinks(extracted, t2) {
5884
+ const { links, total } = extracted;
5885
+ if (links.length === 0) return t2("noConversationLinks");
5886
+ const lines = links.map((link) => {
5887
+ const who = link.role === "user" ? "you" : "assistant";
5888
+ return ` ${String(link.index).padStart(2)} [${who}] ${link.url}`;
5889
+ });
5890
+ const heading = t2("conversationLinksShowing", links.length, total);
5891
+ return [heading, ...lines, "", t2("conversationLinksCopyHint")].join("\n");
5892
+ }
5893
+
5841
5894
  // packages/cli/tui/sessionDispatch.ts
5842
5895
  import { statSync as statSync3 } from "node:fs";
5843
5896
  import { homedir as homedir3 } from "node:os";
@@ -6084,7 +6137,7 @@ function formatAttachedSkillLine(skillRef) {
6084
6137
  const name = themeText(skillRef, "chrome", true);
6085
6138
  return `${bullet} ${label} ${name}`;
6086
6139
  }
6087
- function handleTuiInput(input, state) {
6140
+ function handleTuiInput(input, state, historyTurns) {
6088
6141
  const trimmed = input.trim();
6089
6142
  if (!trimmed) {
6090
6143
  return { nextState: state, output: "" };
@@ -6227,6 +6280,14 @@ ${t("cdUsage")}`
6227
6280
  case "/context":
6228
6281
  case "/ctx":
6229
6282
  return { nextState: state, output: renderContextPanel(state) };
6283
+ case "/links": {
6284
+ const extracted = extractConversationLinks(historyTurns ?? []);
6285
+ return {
6286
+ nextState: state,
6287
+ output: `${renderConversationLinks(extracted, t)}
6288
+ `
6289
+ };
6290
+ }
6230
6291
  case "/credits":
6231
6292
  return { nextState: state, output: renderCreditsDebug(state) };
6232
6293
  case "/runtime": {
@@ -10037,7 +10098,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
10037
10098
  spawnRunner,
10038
10099
  installAltScreenRestoreHandlers: installAltScreenRestoreHandlers2
10039
10100
  } = host;
10040
- const result = handleTuiInput(line, host.state);
10101
+ const result = handleTuiInput(line, host.state, host.history.turns);
10041
10102
  const previousAgentKey = host.state.agentKey;
10042
10103
  host.state = result.nextState;
10043
10104
  const interactive = isInteractiveInput(input);
@@ -11502,7 +11563,7 @@ ${err.message}` : ""}`
11502
11563
  cursorPos = 0;
11503
11564
  if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
11504
11565
  const beforeAgentKey = state.agentKey;
11505
- const res = handleTuiInput(submittedText, state);
11566
+ const res = handleTuiInput(submittedText, state, history.turns);
11506
11567
  if (res.action?.type === "paste-clipboard") {
11507
11568
  await readAndApplyClipboard("slash");
11508
11569
  return;
@@ -11777,7 +11838,7 @@ ${merged}` : merged;
11777
11838
  if (busyLock) {
11778
11839
  const trimmedText = submittedText.trim();
11779
11840
  const busySlashCommand = trimmedText.split(/\s+/)[0]?.toLowerCase();
11780
- 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";
11841
+ 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" || busySlashCommand === "/links";
11781
11842
  if (isBusyLocalSlash) {
11782
11843
  await handleBusyLocalSlash(submittedText, busySlashCommand);
11783
11844
  return;