nolo-cli 0.33.0-alpha.17 → 0.33.0-alpha.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{agentEmailCommands-VAZMNKEB.js → agentEmailCommands-W4RJ323L.js} +2 -2
- package/{agentMachineCommands-EJBEFNZL.js → agentMachineCommands-PZZH5H5U.js} +1 -1
- package/{agentRecordCommands-D2WA5AUO.js → agentRecordCommands-5QROGD2I.js} +2 -2
- package/{agentRunCommand-VUUNH3YL.js → agentRunCommand-KUXEU2C3.js} +2 -2
- package/{chunk-HZKZP7QH.js → chunk-5ZOD4E7E.js} +1 -1
- package/{chunk-7QJGS6K6.js → chunk-JALRRIVE.js} +48 -10
- package/{chunk-SIMPRWQ7.js → chunk-WAFMSVUX.js} +1 -1
- package/{chunk-QSGZ2QGY.js → chunk-ZOQTWQOA.js} +1 -1
- package/index.js +15 -15
- package/{machineCommands-NCNUR7QK.js → machineCommands-HKV467DU.js} +2 -2
- package/{machineWsRunDispatch-R7MHM75C.js → machineWsRunDispatch-3R7MOVIQ.js} +2 -2
- package/package.json +1 -1
- package/{readlineWorkspace-ZA2HSCJI.js → readlineWorkspace-ZBBCDHJG.js} +241 -115
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-FV63ICZC.js";
|
|
5
5
|
import {
|
|
6
6
|
runAgentCreateCommand
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-WAFMSVUX.js";
|
|
8
8
|
import {
|
|
9
9
|
positionalArgs,
|
|
10
10
|
readFlagValue
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
fetchWithTransportFallback,
|
|
17
17
|
resolveAgentRecordFromHybridStore
|
|
18
18
|
} from "./chunk-YDTYDA5W.js";
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-JALRRIVE.js";
|
|
20
20
|
import "./chunk-IEHZHWN7.js";
|
|
21
21
|
import "./chunk-X2DAEZ3X.js";
|
|
22
22
|
import {
|
|
@@ -83,7 +83,7 @@ async function defaultExecuteCli(provider, prompt, options) {
|
|
|
83
83
|
return executeCli(provider, prompt, options);
|
|
84
84
|
}
|
|
85
85
|
async function forwardConnectorRunMessage(machine, message, pushMessage, executeCli, env, fetchImpl) {
|
|
86
|
-
const { handleConnectorRunMessage } = await import("./machineWsRunDispatch-
|
|
86
|
+
const { handleConnectorRunMessage } = await import("./machineWsRunDispatch-3R7MOVIQ.js");
|
|
87
87
|
return handleConnectorRunMessage(message, pushMessage, executeCli, env, fetchImpl);
|
|
88
88
|
}
|
|
89
89
|
async function detectLaunchableMachineInfo() {
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
runAgentCreateCommand,
|
|
3
3
|
runAgentReadCommand,
|
|
4
4
|
runAgentUpdateCommand
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-WAFMSVUX.js";
|
|
6
6
|
import "./chunk-UNHKVD2N.js";
|
|
7
7
|
import "./chunk-YDTYDA5W.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-JALRRIVE.js";
|
|
9
9
|
import "./chunk-IEHZHWN7.js";
|
|
10
10
|
import "./chunk-X2DAEZ3X.js";
|
|
11
11
|
import "./chunk-EKLRRZIN.js";
|
|
@@ -7,13 +7,13 @@ import {
|
|
|
7
7
|
prependSubjectDialogMarker,
|
|
8
8
|
resolveWorkflowReference,
|
|
9
9
|
runAgentRunCommand
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5ZOD4E7E.js";
|
|
11
11
|
import {
|
|
12
12
|
parseAgentRunArgs
|
|
13
13
|
} from "./chunk-ZHYK3N56.js";
|
|
14
14
|
import "./chunk-UNHKVD2N.js";
|
|
15
15
|
import "./chunk-YDTYDA5W.js";
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-JALRRIVE.js";
|
|
17
17
|
import "./chunk-IEHZHWN7.js";
|
|
18
18
|
import "./chunk-X2DAEZ3X.js";
|
|
19
19
|
import "./chunk-EKLRRZIN.js";
|
|
@@ -423,8 +423,16 @@ var STRINGS = {
|
|
|
423
423
|
zh: "\u5F53\u524D\u73AF\u5883\u6CA1\u6709\u53EF\u7528\u7684\u526A\u8D34\u677F\u3002\u6700\u540E\u4E00\u6761\u56DE\u590D\u5DF2\u6253\u5370\u5728\u4E0A\u65B9\uFF0C\u53EF\u624B\u52A8\u590D\u5236\u3002"
|
|
424
424
|
},
|
|
425
425
|
copyUsage: {
|
|
426
|
-
en: "Usage: /copy",
|
|
427
|
-
zh: "\u7528\u6CD5\uFF1A/copy"
|
|
426
|
+
en: "Usage: /copy or /copy view",
|
|
427
|
+
zh: "\u7528\u6CD5\uFF1A/copy \u6216 /copy view"
|
|
428
|
+
},
|
|
429
|
+
copyViewTitle: {
|
|
430
|
+
en: "Copy view \u2014 conversation history",
|
|
431
|
+
zh: "\u590D\u5236\u89C6\u56FE \u2014 \u5BF9\u8BDD\u5386\u53F2"
|
|
432
|
+
},
|
|
433
|
+
copyViewHint: {
|
|
434
|
+
en: "Drag to select. Use PageUp/PageDown, Home/End, or the mouse wheel to scroll. Press Esc or Enter to return.",
|
|
435
|
+
zh: "\u76F4\u63A5\u62D6\u9009\u3002\u53EF\u7528 PageUp/PageDown\u3001Home/End \u6216\u9F20\u6807\u6EDA\u8F6E\u6EDA\u52A8\u3002\u6309 Esc \u6216 Enter \u8FD4\u56DE\u3002"
|
|
428
436
|
},
|
|
429
437
|
historyNoToken: {
|
|
430
438
|
en: "History requires an auth token. Run `nolo login` or set AUTH_TOKEN.",
|
|
@@ -706,8 +714,10 @@ var STRINGS = {
|
|
|
706
714
|
" /resume <dialogId> Resume a dialog directly by id",
|
|
707
715
|
" /lang <zh|en> Switch interface language",
|
|
708
716
|
" /copy Copy the last reply to the clipboard",
|
|
717
|
+
" /copy view Open native scrollback for partial selection (Ctrl+O)",
|
|
709
718
|
" /mouse <on|off> Toggle mouse mode (off = drag to select text)",
|
|
710
719
|
" /altscreen <on|off> Toggle the terminal alternate screen (default on; off shares shell scrollback)",
|
|
720
|
+
" Shift+drag Select text natively even while mouse mode is on (terminal bypass)",
|
|
711
721
|
" /doc List attached docs",
|
|
712
722
|
" /doc attach <doc> Attach a doc to this workspace",
|
|
713
723
|
" /skill List attached skills",
|
|
@@ -741,8 +751,10 @@ var STRINGS = {
|
|
|
741
751
|
" /resume <dialogId> \u6309 id \u76F4\u63A5\u6062\u590D\u5BF9\u8BDD",
|
|
742
752
|
" /lang <zh|en> \u5207\u6362\u754C\u9762\u8BED\u8A00",
|
|
743
753
|
" /copy \u590D\u5236\u6700\u540E\u4E00\u6761\u56DE\u590D\u5230\u526A\u8D34\u677F",
|
|
754
|
+
" /copy view \u6253\u5F00\u539F\u751F\u56DE\u6EDA\u8FDB\u884C\u8DE8\u5C4F\u62D6\u9009\uFF08Ctrl+O\uFF09",
|
|
744
755
|
" /mouse <on|off> \u5207\u6362\u9F20\u6807\u6A21\u5F0F\uFF08off \u540E\u53EF\u76F4\u63A5\u62D6\u9009\u6587\u672C\uFF09",
|
|
745
756
|
" /altscreen <on|off> \u5207\u6362\u7EC8\u7AEF\u5907\u7528\u5C4F\uFF08\u9ED8\u8BA4 on\uFF1Boff \u6539\u4E3A\u4E0E shell \u5171\u7528\u56DE\u6EDA\uFF09",
|
|
757
|
+
" Shift+\u62D6\u62FD \u9F20\u6807\u6A21\u5F0F\u5F00\u542F\u65F6\u4E5F\u53EF\u539F\u751F\u9009\u4E2D\u6587\u672C\uFF08\u7EC8\u7AEF\u7ED5\u8FC7\u4FEE\u9970\u952E\uFF09",
|
|
746
758
|
" /doc \u5217\u51FA\u5DF2\u6302\u8F7D\u7684\u6587\u6863",
|
|
747
759
|
" /doc attach <doc> \u6302\u8F7D\u6587\u6863\u5230\u5F53\u524D\u5DE5\u4F5C\u533A",
|
|
748
760
|
" /skill \u5217\u51FA\u5DF2\u6302\u8F7D\u7684\u6280\u80FD",
|
|
@@ -11231,12 +11243,16 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
11231
11243
|
}
|
|
11232
11244
|
} : void 0;
|
|
11233
11245
|
if (isAntigravityOAuthAgent(agentConfig)) {
|
|
11234
|
-
const
|
|
11235
|
-
|
|
11236
|
-
|
|
11237
|
-
|
|
11238
|
-
|
|
11239
|
-
|
|
11246
|
+
const resolveAccessToken = async () => {
|
|
11247
|
+
const accessToken = await apiKeyRefResolver("antigravity");
|
|
11248
|
+
if (!accessToken) {
|
|
11249
|
+
throw new Error(
|
|
11250
|
+
'OAuth credential for "antigravity" not found locally. Run `nolo auth antigravity`.'
|
|
11251
|
+
);
|
|
11252
|
+
}
|
|
11253
|
+
return accessToken;
|
|
11254
|
+
};
|
|
11255
|
+
await resolveAccessToken();
|
|
11240
11256
|
const credential = readOAuthCredential("antigravity");
|
|
11241
11257
|
const { requestedToolNames: requestedToolNames2, tools: tools2 } = resolveProviderOpenAiToolBundle(
|
|
11242
11258
|
agentConfig,
|
|
@@ -11272,9 +11288,10 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
11272
11288
|
requestedToolNames: requestedToolNames2,
|
|
11273
11289
|
openAiToolNames: summarizeOpenAiToolNames(tools2)
|
|
11274
11290
|
});
|
|
11275
|
-
const
|
|
11291
|
+
const accessToken = await resolveAccessToken();
|
|
11292
|
+
const sendCcaRequest = (token) => fetchAntigravityCloudCodeCompletion({
|
|
11276
11293
|
agentConfig,
|
|
11277
|
-
accessToken,
|
|
11294
|
+
accessToken: token,
|
|
11278
11295
|
metadata: credential?.metadata ?? null,
|
|
11279
11296
|
openAiBody,
|
|
11280
11297
|
signal: options?.signal,
|
|
@@ -11285,6 +11302,27 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
11285
11302
|
loopbackRequest
|
|
11286
11303
|
})
|
|
11287
11304
|
});
|
|
11305
|
+
let result = await sendCcaRequest(accessToken);
|
|
11306
|
+
if (result.status === 401) {
|
|
11307
|
+
try {
|
|
11308
|
+
const refreshed = await apiKeyRefResolver("antigravity", {
|
|
11309
|
+
force: true
|
|
11310
|
+
});
|
|
11311
|
+
if (refreshed && refreshed !== accessToken) {
|
|
11312
|
+
logLocalRuntimeDiagnostic("provider.request.auth_retry", {
|
|
11313
|
+
agentKey: agentConfig.key,
|
|
11314
|
+
transport: "antigravity-cloud-code"
|
|
11315
|
+
});
|
|
11316
|
+
result = await sendCcaRequest(refreshed);
|
|
11317
|
+
}
|
|
11318
|
+
} catch (error) {
|
|
11319
|
+
logLocalRuntimeDiagnostic("provider.request.auth_retry_failed", {
|
|
11320
|
+
agentKey: agentConfig.key,
|
|
11321
|
+
transport: "antigravity-cloud-code",
|
|
11322
|
+
error: toErrorMessage(error)
|
|
11323
|
+
});
|
|
11324
|
+
}
|
|
11325
|
+
}
|
|
11288
11326
|
await recordLocalAvailability(result.status, result.body);
|
|
11289
11327
|
if (result.status < 200 || result.status >= 300) {
|
|
11290
11328
|
const errMsg = result.body && typeof result.body === "object" && result.body.error && typeof result.body.error.message === "string" ? result.body.error.message : JSON.stringify(result.body);
|
package/index.js
CHANGED
|
@@ -126,7 +126,7 @@ function createDaemonShortcutCommand(path, description, command2) {
|
|
|
126
126
|
// packages/cli/agentInternalCommandEntries.ts
|
|
127
127
|
function getAgentInternalCommandEntries() {
|
|
128
128
|
const createAgentRunCommand = (path, description) => createContextCommand(path, description, async (args2, ctx) => {
|
|
129
|
-
const { runAgentRunCommand } = await import("./agentRunCommand-
|
|
129
|
+
const { runAgentRunCommand } = await import("./agentRunCommand-KUXEU2C3.js");
|
|
130
130
|
return runAgentRunCommand(args2, {
|
|
131
131
|
env: ctx.env,
|
|
132
132
|
scriptDir: ctx.scriptDir,
|
|
@@ -142,7 +142,7 @@ function getAgentInternalCommandEntries() {
|
|
|
142
142
|
return runAgentListCommand(args2, deps);
|
|
143
143
|
}),
|
|
144
144
|
createEnvCommand(["agent", "create"], "Create a new agent", async (args2, deps) => {
|
|
145
|
-
const { runAgentCreateCommand } = await import("./agentRecordCommands-
|
|
145
|
+
const { runAgentCreateCommand } = await import("./agentRecordCommands-5QROGD2I.js");
|
|
146
146
|
return runAgentCreateCommand(args2, deps);
|
|
147
147
|
}),
|
|
148
148
|
createEnvCommand(["agent", "pull"], "Cache an agent for local runs", async (args2, deps) => {
|
|
@@ -150,7 +150,7 @@ function getAgentInternalCommandEntries() {
|
|
|
150
150
|
return runAgentPullCommand(args2, deps);
|
|
151
151
|
}),
|
|
152
152
|
createEnvCommand(["agent", "read"], "Read a single agent", async (args2, deps) => {
|
|
153
|
-
const { runAgentReadCommand } = await import("./agentRecordCommands-
|
|
153
|
+
const { runAgentReadCommand } = await import("./agentRecordCommands-5QROGD2I.js");
|
|
154
154
|
return runAgentReadCommand(args2, deps);
|
|
155
155
|
}),
|
|
156
156
|
createAgentRunCommand(["agent", "run"], "Run an agent"),
|
|
@@ -179,26 +179,26 @@ function getAgentInternalCommandEntries() {
|
|
|
179
179
|
return runSetupOfflineMarxistsAgentCommand(args2, deps);
|
|
180
180
|
}),
|
|
181
181
|
createEnvCommand(["agent", "update"], "Update agent fields", async (args2, deps) => {
|
|
182
|
-
const { runAgentUpdateCommand } = await import("./agentRecordCommands-
|
|
182
|
+
const { runAgentUpdateCommand } = await import("./agentRecordCommands-5QROGD2I.js");
|
|
183
183
|
return runAgentUpdateCommand(args2, deps);
|
|
184
184
|
}),
|
|
185
185
|
createEnvCommand(["agent", "email", "provision"], "Provision a controlled inbox for an agent", async (args2, deps) => {
|
|
186
|
-
const { runAgentEmailProvisionCommand } = await import("./agentEmailCommands-
|
|
186
|
+
const { runAgentEmailProvisionCommand } = await import("./agentEmailCommands-W4RJ323L.js");
|
|
187
187
|
return runAgentEmailProvisionCommand(args2, deps);
|
|
188
188
|
}),
|
|
189
189
|
createEnvCommand(["agent", "email", "bind"], "Bind an existing email address to an agent", async (args2, deps) => {
|
|
190
|
-
const { runAgentEmailBindCommand } = await import("./agentEmailCommands-
|
|
190
|
+
const { runAgentEmailBindCommand } = await import("./agentEmailCommands-W4RJ323L.js");
|
|
191
191
|
return runAgentEmailBindCommand(args2, deps);
|
|
192
192
|
}),
|
|
193
193
|
createEnvCommand(["agent", "email", "transfer"], "Transfer an email identity from one agent to another (cross-account)", async (args2, deps) => {
|
|
194
|
-
const { runAgentEmailTransferCommand } = await import("./agentEmailCommands-
|
|
194
|
+
const { runAgentEmailTransferCommand } = await import("./agentEmailCommands-W4RJ323L.js");
|
|
195
195
|
return runAgentEmailTransferCommand(args2, deps);
|
|
196
196
|
}),
|
|
197
197
|
createEnvCommand(
|
|
198
198
|
["agent", "email", "create-and-provision"],
|
|
199
199
|
"Create an agent and provision its controlled inbox",
|
|
200
200
|
async (args2, deps) => {
|
|
201
|
-
const { runAgentEmailCreateAndProvisionCommand } = await import("./agentEmailCommands-
|
|
201
|
+
const { runAgentEmailCreateAndProvisionCommand } = await import("./agentEmailCommands-W4RJ323L.js");
|
|
202
202
|
return runAgentEmailCreateAndProvisionCommand(args2, deps);
|
|
203
203
|
}
|
|
204
204
|
),
|
|
@@ -219,15 +219,15 @@ function getAgentInternalCommandEntries() {
|
|
|
219
219
|
return runAgentRevokeGrantCommand(args2, deps);
|
|
220
220
|
}),
|
|
221
221
|
createEnvCommand(["agent", "bind-current"], "Bind an agent to this machine", async (args2, deps) => {
|
|
222
|
-
const { runAgentBindCurrentCommand } = await import("./agentMachineCommands-
|
|
222
|
+
const { runAgentBindCurrentCommand } = await import("./agentMachineCommands-PZZH5H5U.js");
|
|
223
223
|
return runAgentBindCurrentCommand(args2, deps);
|
|
224
224
|
}),
|
|
225
225
|
createEnvCommand(["agent", "smoke-current"], "Smoke test a bound agent through this machine", async (args2, deps) => {
|
|
226
|
-
const { runAgentSmokeCurrentCommand } = await import("./agentMachineCommands-
|
|
226
|
+
const { runAgentSmokeCurrentCommand } = await import("./agentMachineCommands-PZZH5H5U.js");
|
|
227
227
|
return runAgentSmokeCurrentCommand(args2, deps);
|
|
228
228
|
}),
|
|
229
229
|
createEnvCommand(["agent", "runtime-doctor"], "Diagnose current machine runtime compatibility", async (args2, deps) => {
|
|
230
|
-
const { runAgentRuntimeDoctorCommand } = await import("./agentMachineCommands-
|
|
230
|
+
const { runAgentRuntimeDoctorCommand } = await import("./agentMachineCommands-PZZH5H5U.js");
|
|
231
231
|
return runAgentRuntimeDoctorCommand(args2, deps);
|
|
232
232
|
}),
|
|
233
233
|
createAgentRunCommand(["agent", "chat"], "Chat with an agent")
|
|
@@ -408,15 +408,15 @@ function getSystemInternalCommandEntries(renderHelpText2) {
|
|
|
408
408
|
return runWhoamiCommand({ args: args2, env: ctx.env });
|
|
409
409
|
}),
|
|
410
410
|
createEntrypointEnvCommand(["connect"], "Send machine heartbeats or hold a connector websocket", async (args2, deps) => {
|
|
411
|
-
const { runMachineConnectCommand } = await import("./machineCommands-
|
|
411
|
+
const { runMachineConnectCommand } = await import("./machineCommands-HKV467DU.js");
|
|
412
412
|
return runMachineConnectCommand(args2, deps);
|
|
413
413
|
}),
|
|
414
414
|
createDaemonShortcutCommand(["daemon"], "Run the connector daemon shortcut", async (args2, deps) => {
|
|
415
|
-
const { runMachineConnectCommand } = await import("./machineCommands-
|
|
415
|
+
const { runMachineConnectCommand } = await import("./machineCommands-HKV467DU.js");
|
|
416
416
|
return runMachineConnectCommand(args2, deps);
|
|
417
417
|
}),
|
|
418
418
|
createEnvCommand(["machine", "status"], "List machines registered to the current profile", async (args2, deps) => {
|
|
419
|
-
const { runMachineStatusCommand } = await import("./machineCommands-
|
|
419
|
+
const { runMachineStatusCommand } = await import("./machineCommands-HKV467DU.js");
|
|
420
420
|
return runMachineStatusCommand(args2, deps);
|
|
421
421
|
}),
|
|
422
422
|
createEnvCommand(["doctor", "runtime"], "Diagnose local-first agent runtime selection", async (args2, deps) => {
|
|
@@ -796,7 +796,7 @@ async function runScript(script, forwardedArgs, env) {
|
|
|
796
796
|
return proc.exited;
|
|
797
797
|
}
|
|
798
798
|
async function launchTuiWorkspace(args2) {
|
|
799
|
-
const { startTuiWorkspace } = await import("./readlineWorkspace-
|
|
799
|
+
const { startTuiWorkspace } = await import("./readlineWorkspace-ZBBCDHJG.js");
|
|
800
800
|
const { createTuiSummaryLlmCaller } = await import("./tuiSummaryLlmCaller-WUVAOIYU.js");
|
|
801
801
|
return startTuiWorkspace({
|
|
802
802
|
...args2,
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
buildMachinePermissionPromptBlock,
|
|
8
8
|
handleConnectorRunMessage,
|
|
9
9
|
resolveMachineRunPermissionPolicy
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-ZOQTWQOA.js";
|
|
11
|
+
import "./chunk-JALRRIVE.js";
|
|
12
12
|
import "./chunk-IEHZHWN7.js";
|
|
13
13
|
import "./chunk-X2DAEZ3X.js";
|
|
14
14
|
import "./chunk-EKLRRZIN.js";
|
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
runtimeWorkspacePermissionPolicy,
|
|
12
12
|
scopePermissionPolicyToRuntimeWorkspace,
|
|
13
13
|
summarizeAgentConfigForLogs
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-ZOQTWQOA.js";
|
|
15
|
+
import "./chunk-JALRRIVE.js";
|
|
16
16
|
import "./chunk-IEHZHWN7.js";
|
|
17
17
|
import "./chunk-X2DAEZ3X.js";
|
|
18
18
|
import "./chunk-EKLRRZIN.js";
|
package/package.json
CHANGED
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
visibleWidth,
|
|
71
71
|
wrapTextToLines,
|
|
72
72
|
wrapTranscriptLine
|
|
73
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-5ZOD4E7E.js";
|
|
74
74
|
import "./chunk-ZHYK3N56.js";
|
|
75
75
|
import {
|
|
76
76
|
getReadableCliDb
|
|
@@ -87,7 +87,7 @@ import {
|
|
|
87
87
|
readTimestamp,
|
|
88
88
|
setCliLocale,
|
|
89
89
|
t
|
|
90
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-JALRRIVE.js";
|
|
91
91
|
import "./chunk-IEHZHWN7.js";
|
|
92
92
|
import "./chunk-X2DAEZ3X.js";
|
|
93
93
|
import {
|
|
@@ -726,6 +726,24 @@ function parseScrollAction(sequence) {
|
|
|
726
726
|
return null;
|
|
727
727
|
}
|
|
728
728
|
}
|
|
729
|
+
var WHEEL_SCROLL_LINES = 3;
|
|
730
|
+
function renderScrollbarRow(rowIndex, visibleHeight, totalLines, scrollTop) {
|
|
731
|
+
if (totalLines <= visibleHeight) return " ";
|
|
732
|
+
const trackHeight = visibleHeight;
|
|
733
|
+
const thumbSize = Math.max(
|
|
734
|
+
1,
|
|
735
|
+
Math.floor(visibleHeight * visibleHeight / totalLines)
|
|
736
|
+
);
|
|
737
|
+
const maxScrollTop = totalLines - visibleHeight;
|
|
738
|
+
const thumbTop = Math.floor(
|
|
739
|
+
scrollTop / maxScrollTop * (trackHeight - thumbSize)
|
|
740
|
+
);
|
|
741
|
+
const thumbBottom = thumbTop + thumbSize;
|
|
742
|
+
if (rowIndex >= thumbTop && rowIndex < thumbBottom) {
|
|
743
|
+
return "\u2588";
|
|
744
|
+
}
|
|
745
|
+
return "\u2502";
|
|
746
|
+
}
|
|
729
747
|
|
|
730
748
|
// packages/cli/tui/selectDialog.ts
|
|
731
749
|
var CSI_ARROW_UP = "\x1B[A";
|
|
@@ -1971,6 +1989,26 @@ function buildTurnOffsets(history, contentWidth) {
|
|
|
1971
1989
|
function currentTurnSeparator(history, density) {
|
|
1972
1990
|
return density === "spacious" && (history.turns.length > 0 || history.currentRole === "user") ? 1 : 0;
|
|
1973
1991
|
}
|
|
1992
|
+
function buildCopyViewLines(history) {
|
|
1993
|
+
const turns = [...history.turns];
|
|
1994
|
+
if (history.currentRole !== null) {
|
|
1995
|
+
turns.push({ role: history.currentRole, content: history.currentContent });
|
|
1996
|
+
}
|
|
1997
|
+
const lines = [];
|
|
1998
|
+
for (const [index, turn] of turns.entries()) {
|
|
1999
|
+
if (index > 0) lines.push("");
|
|
2000
|
+
const normalized = stripAnsi(turn.content).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
2001
|
+
if (turn.role === "local") {
|
|
2002
|
+
if (turn.command) {
|
|
2003
|
+
lines.push(`\u203A ${stripAnsi(turn.command)}`);
|
|
2004
|
+
}
|
|
2005
|
+
lines.push(...normalized.split("\n"));
|
|
2006
|
+
} else {
|
|
2007
|
+
lines.push(...normalized.split("\n"));
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
return lines;
|
|
2011
|
+
}
|
|
1974
2012
|
function renderHistory(output, history, inputLines) {
|
|
1975
2013
|
const tty = output;
|
|
1976
2014
|
if (!tty.isTTY) return;
|
|
@@ -2070,8 +2108,11 @@ function renderHistory(output, history, inputLines) {
|
|
|
2070
2108
|
let frame = "";
|
|
2071
2109
|
for (let i = 0; i < visibleHeight; i++) {
|
|
2072
2110
|
const line = visibleLines[i] ?? "";
|
|
2073
|
-
const padded = padOrTruncateToWidth(line,
|
|
2074
|
-
const
|
|
2111
|
+
const padded = padOrTruncateToWidth(line, contentWidth);
|
|
2112
|
+
const thumb = renderScrollbarRow(i, visibleHeight, totalLines, history.scrollTop);
|
|
2113
|
+
const scrollbarPrefix = colorEnabled ? themeColorSequence("chrome") : "";
|
|
2114
|
+
const scrollbarSuffix = colorEnabled ? "\x1B[39m" : "";
|
|
2115
|
+
const rowContent = `${padded}\x1B[${columns}G${scrollbarPrefix}${thumb}${scrollbarSuffix}`;
|
|
2075
2116
|
nextLines[i] = rowContent;
|
|
2076
2117
|
if (!prevLines || prevLines[i] !== rowContent) {
|
|
2077
2118
|
frame += `\x1B[${i + 1};1H\x1B[2K${rowContent}`;
|
|
@@ -2106,35 +2147,50 @@ function createHistoryOutputStream(history, onUpdate) {
|
|
|
2106
2147
|
}
|
|
2107
2148
|
};
|
|
2108
2149
|
}
|
|
2109
|
-
function
|
|
2110
|
-
return {
|
|
2111
|
-
isTTY: true,
|
|
2112
|
-
write(chunk) {
|
|
2113
|
-
const text = typeof chunk === "string" ? chunk : chunk.toString();
|
|
2114
|
-
applyOutputChunkToCurrentTurn(history, text);
|
|
2115
|
-
terminalOutput.write(text);
|
|
2116
|
-
return true;
|
|
2117
|
-
}
|
|
2118
|
-
};
|
|
2119
|
-
}
|
|
2120
|
-
function formatTurnLines(turn, contentWidth, colorEnabled = resolveCliColorEnabled()) {
|
|
2121
|
-
return renderTurnBlock(
|
|
2122
|
-
turn.role,
|
|
2123
|
-
turn.content,
|
|
2124
|
-
contentWidth,
|
|
2125
|
-
colorEnabled,
|
|
2126
|
-
turn.command
|
|
2127
|
-
);
|
|
2128
|
-
}
|
|
2129
|
-
function commitTurnToTerminal(output, turn, options) {
|
|
2150
|
+
function applyScrollAction(history, action, output, inputLines) {
|
|
2130
2151
|
const tty = output;
|
|
2131
|
-
const
|
|
2132
|
-
const
|
|
2133
|
-
const
|
|
2134
|
-
|
|
2135
|
-
const
|
|
2136
|
-
|
|
2137
|
-
|
|
2152
|
+
const rows = tty.rows ?? 24;
|
|
2153
|
+
const columns = tty.columns ?? 80;
|
|
2154
|
+
const visibleHeight = Math.max(1, rows - inputLines);
|
|
2155
|
+
const contentWidth = Math.max(1, columns - 1);
|
|
2156
|
+
const { totalLines: finalizedLines } = buildTurnOffsets(history, contentWidth);
|
|
2157
|
+
let totalLines = finalizedLines;
|
|
2158
|
+
if (history.currentRole !== null && history.currentContent) {
|
|
2159
|
+
totalLines += currentTurnSeparator(history, getActiveDensity()) + countTurnLines(history.currentRole, history.currentContent, contentWidth);
|
|
2160
|
+
}
|
|
2161
|
+
const maxScrollTop = Math.max(0, totalLines - visibleHeight);
|
|
2162
|
+
history.followBottom = false;
|
|
2163
|
+
switch (action) {
|
|
2164
|
+
case "page-up":
|
|
2165
|
+
history.scrollTop = Math.max(0, history.scrollTop - visibleHeight);
|
|
2166
|
+
break;
|
|
2167
|
+
case "page-down":
|
|
2168
|
+
history.scrollTop = Math.min(maxScrollTop, history.scrollTop + visibleHeight);
|
|
2169
|
+
break;
|
|
2170
|
+
case "half-page-up":
|
|
2171
|
+
history.scrollTop = Math.max(0, history.scrollTop - Math.floor(visibleHeight / 2));
|
|
2172
|
+
break;
|
|
2173
|
+
case "half-page-down":
|
|
2174
|
+
history.scrollTop = Math.min(
|
|
2175
|
+
maxScrollTop,
|
|
2176
|
+
history.scrollTop + Math.floor(visibleHeight / 2)
|
|
2177
|
+
);
|
|
2178
|
+
break;
|
|
2179
|
+
case "wheel-up":
|
|
2180
|
+
history.scrollTop = Math.max(0, history.scrollTop - WHEEL_SCROLL_LINES);
|
|
2181
|
+
break;
|
|
2182
|
+
case "wheel-down":
|
|
2183
|
+
history.scrollTop = Math.min(maxScrollTop, history.scrollTop + WHEEL_SCROLL_LINES);
|
|
2184
|
+
if (history.scrollTop >= maxScrollTop) history.followBottom = true;
|
|
2185
|
+
break;
|
|
2186
|
+
case "top":
|
|
2187
|
+
history.scrollTop = 0;
|
|
2188
|
+
break;
|
|
2189
|
+
case "bottom":
|
|
2190
|
+
history.scrollTop = maxScrollTop;
|
|
2191
|
+
history.followBottom = true;
|
|
2192
|
+
break;
|
|
2193
|
+
}
|
|
2138
2194
|
}
|
|
2139
2195
|
|
|
2140
2196
|
// packages/cli/tui/dialogHost.ts
|
|
@@ -3889,6 +3945,9 @@ function applyTuiInputKey(buffer, sequence, key = {}, cursorPos, options) {
|
|
|
3889
3945
|
if (seq === "" || key.ctrl && key.name === "c") {
|
|
3890
3946
|
return { buffer, cursorPos: curPos, abort: true };
|
|
3891
3947
|
}
|
|
3948
|
+
if (seq === "" || key.ctrl && key.name === "o") {
|
|
3949
|
+
return { buffer, cursorPos: curPos, copyView: true };
|
|
3950
|
+
}
|
|
3892
3951
|
if (seq === "\f" || key.ctrl && key.name === "l") {
|
|
3893
3952
|
return { buffer, cursorPos: curPos, redraw: true };
|
|
3894
3953
|
}
|
|
@@ -3973,7 +4032,7 @@ function applyTuiInputKey(buffer, sequence, key = {}, cursorPos, options) {
|
|
|
3973
4032
|
const completed = completeSlashPrefix(buffer) ?? buffer;
|
|
3974
4033
|
return { buffer: completed, cursorPos: completed.length };
|
|
3975
4034
|
}
|
|
3976
|
-
if (!seq || key.ctrl || key.meta || seq.startsWith("\x1B")
|
|
4035
|
+
if (!seq || key.ctrl || key.meta || seq.startsWith("\x1B")) {
|
|
3977
4036
|
return { buffer, cursorPos: curPos };
|
|
3978
4037
|
}
|
|
3979
4038
|
const insertAt = snapCursorOutsidePasteChip(buffer, curPos);
|
|
@@ -4538,6 +4597,13 @@ function handleTuiInput(input, state) {
|
|
|
4538
4597
|
action: { type: "pick-dialog" }
|
|
4539
4598
|
};
|
|
4540
4599
|
case "/copy":
|
|
4600
|
+
if (argText === "view") {
|
|
4601
|
+
return {
|
|
4602
|
+
nextState: state,
|
|
4603
|
+
output: "",
|
|
4604
|
+
action: { type: "copy-view" }
|
|
4605
|
+
};
|
|
4606
|
+
}
|
|
4541
4607
|
if (argText) {
|
|
4542
4608
|
return { nextState: state, output: t("copyUsage") };
|
|
4543
4609
|
}
|
|
@@ -5078,7 +5144,6 @@ function createFixedInput(output, config) {
|
|
|
5078
5144
|
};
|
|
5079
5145
|
let lastScrollBottom = -1;
|
|
5080
5146
|
const setScrollRegion = (lines, force = false) => {
|
|
5081
|
-
if (!isAltScreenOn(output)) return;
|
|
5082
5147
|
const bottom = Math.max(1, getRows() - lines);
|
|
5083
5148
|
if (force || lastScrollBottom !== bottom) {
|
|
5084
5149
|
write(`\x1B[1;${bottom}r`);
|
|
@@ -5087,11 +5152,10 @@ function createFixedInput(output, config) {
|
|
|
5087
5152
|
};
|
|
5088
5153
|
const saveCursor = () => write("\x1B7");
|
|
5089
5154
|
const resetScrollRegion = () => {
|
|
5090
|
-
if (!isAltScreenOn(output)) return;
|
|
5091
5155
|
lastScrollBottom = -1;
|
|
5092
5156
|
write("\x1B[r");
|
|
5093
5157
|
};
|
|
5094
|
-
let mouseEnabled =
|
|
5158
|
+
let mouseEnabled = true;
|
|
5095
5159
|
const enableMouse = () => {
|
|
5096
5160
|
if (mouseEnabled) write("\x1B[?1006h\x1B[?1000h");
|
|
5097
5161
|
};
|
|
@@ -5558,12 +5622,7 @@ var SIGNAL_EXIT_CODE = {
|
|
|
5558
5622
|
};
|
|
5559
5623
|
var restoreAltScreen = () => {
|
|
5560
5624
|
try {
|
|
5561
|
-
if (altScreenRestoreOutput)
|
|
5562
|
-
leaveAltScreen(altScreenRestoreOutput);
|
|
5563
|
-
if (altScreenRestoreOutput.isTTY) {
|
|
5564
|
-
altScreenRestoreOutput.write("\x1B[r\x1B[?2004l\x1B[?25h");
|
|
5565
|
-
}
|
|
5566
|
-
}
|
|
5625
|
+
if (altScreenRestoreOutput) leaveAltScreen(altScreenRestoreOutput);
|
|
5567
5626
|
} catch {
|
|
5568
5627
|
}
|
|
5569
5628
|
};
|
|
@@ -5986,14 +6045,10 @@ async function startTuiWorkspace(options) {
|
|
|
5986
6045
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
5987
6046
|
const spawnRunner = options.spawnRunner ?? spawnProcess;
|
|
5988
6047
|
const selfUpdater = options.selfUpdater ?? ((target) => runSelfUpdate({ output: target }));
|
|
5989
|
-
const env = options.env ?? process.env;
|
|
5990
|
-
const startInAltScreen = (env.NOLO_TUI_ALTSCREEN ?? "").trim() === "1";
|
|
5991
6048
|
if (output.isTTY) {
|
|
5992
|
-
|
|
5993
|
-
enterAltScreen(output);
|
|
5994
|
-
output.write("\x1B[2J\x1B[H");
|
|
5995
|
-
}
|
|
6049
|
+
enterAltScreen(output);
|
|
5996
6050
|
installAltScreenRestoreHandlers(output);
|
|
6051
|
+
output.write("\x1B[2J\x1B[H");
|
|
5997
6052
|
}
|
|
5998
6053
|
const detected = await detectTerminalBackground({
|
|
5999
6054
|
stdin: input,
|
|
@@ -6019,8 +6074,8 @@ async function startTuiWorkspace(options) {
|
|
|
6019
6074
|
let lastSentTitle = null;
|
|
6020
6075
|
const syncWindowTitle = () => {
|
|
6021
6076
|
if (!output.isTTY) return;
|
|
6022
|
-
const
|
|
6023
|
-
const rawSetting = (
|
|
6077
|
+
const env = options.env ?? process.env;
|
|
6078
|
+
const rawSetting = (env.NOLO_TUI_TITLE ?? "").trim().toLowerCase();
|
|
6024
6079
|
if (rawSetting === "0" || rawSetting === "false") return;
|
|
6025
6080
|
const currentTitle = state.dialogLabel?.trim() ?? "";
|
|
6026
6081
|
if (currentTitle === lastSentTitle) return;
|
|
@@ -6068,6 +6123,9 @@ async function startTuiWorkspace(options) {
|
|
|
6068
6123
|
reconcile: (runId) => checkStaleRun(runId, { env: process.env }),
|
|
6069
6124
|
onRecordsPolled: (records) => runCompletionWatcher.observe(records)
|
|
6070
6125
|
});
|
|
6126
|
+
let copyViewExitResolver = null;
|
|
6127
|
+
let copyViewRender = null;
|
|
6128
|
+
let copyViewScrollTop = 0;
|
|
6071
6129
|
const history = createTurnHistory();
|
|
6072
6130
|
const dialogHost = createDialogHost({
|
|
6073
6131
|
composer: {
|
|
@@ -6100,9 +6158,7 @@ async function startTuiWorkspace(options) {
|
|
|
6100
6158
|
if (fixedInput.isPaused()) return;
|
|
6101
6159
|
output.write("\x1B[?2026h\x1B[?25l");
|
|
6102
6160
|
try {
|
|
6103
|
-
|
|
6104
|
-
renderHistory(output, history, fixedInput.getInputLines());
|
|
6105
|
-
}
|
|
6161
|
+
renderHistory(output, history, fixedInput.getInputLines());
|
|
6106
6162
|
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
6107
6163
|
} finally {
|
|
6108
6164
|
output.write("\x1B[?25h\x1B[?2026l");
|
|
@@ -6164,7 +6220,6 @@ async function startTuiWorkspace(options) {
|
|
|
6164
6220
|
const renderHistoryToOutput = () => {
|
|
6165
6221
|
if (fixedInput.isPaused()) return;
|
|
6166
6222
|
if (syncingLayout) return;
|
|
6167
|
-
if (!isAltScreenOn(output)) return;
|
|
6168
6223
|
syncingLayout = true;
|
|
6169
6224
|
try {
|
|
6170
6225
|
renderHistory(output, history, fixedInput.getInputLines());
|
|
@@ -6177,6 +6232,53 @@ async function startTuiWorkspace(options) {
|
|
|
6177
6232
|
const text = lastReply ? stripAnsi(lastReply).trim() : "";
|
|
6178
6233
|
return text || null;
|
|
6179
6234
|
};
|
|
6235
|
+
const openCopyView = async () => {
|
|
6236
|
+
const lines = buildCopyViewLines(history);
|
|
6237
|
+
if (lines.length === 0) return false;
|
|
6238
|
+
if (!isInteractiveInput(input)) {
|
|
6239
|
+
output.write(`${lines.join("\n")}
|
|
6240
|
+
`);
|
|
6241
|
+
return true;
|
|
6242
|
+
}
|
|
6243
|
+
const tty = output;
|
|
6244
|
+
const renderCopyView = () => {
|
|
6245
|
+
const rows = Math.max(1, tty.rows ?? 24);
|
|
6246
|
+
const columns = Math.max(1, tty.columns ?? 80);
|
|
6247
|
+
const copyLines = buildCopyViewLines(history);
|
|
6248
|
+
const visibleHeight = Math.max(1, rows - 3);
|
|
6249
|
+
const maxScrollTop = Math.max(0, copyLines.length - visibleHeight);
|
|
6250
|
+
copyViewScrollTop = Math.max(0, Math.min(copyViewScrollTop, maxScrollTop));
|
|
6251
|
+
let frame = "\x1B[2J\x1B[H";
|
|
6252
|
+
frame += `${t("copyViewTitle")}
|
|
6253
|
+
`;
|
|
6254
|
+
for (let index = 0; index < visibleHeight; index++) {
|
|
6255
|
+
frame += `${fitAnsiLine(copyLines[copyViewScrollTop + index] ?? "", columns)}
|
|
6256
|
+
`;
|
|
6257
|
+
}
|
|
6258
|
+
frame += `${t("copyViewHint")}
|
|
6259
|
+
`;
|
|
6260
|
+
output.write(frame);
|
|
6261
|
+
};
|
|
6262
|
+
fixedInput.pause();
|
|
6263
|
+
copyViewScrollTop = 0;
|
|
6264
|
+
copyViewRender = renderCopyView;
|
|
6265
|
+
try {
|
|
6266
|
+
renderCopyView();
|
|
6267
|
+
await new Promise((resolve2) => {
|
|
6268
|
+
copyViewExitResolver = resolve2;
|
|
6269
|
+
});
|
|
6270
|
+
} finally {
|
|
6271
|
+
copyViewExitResolver = null;
|
|
6272
|
+
copyViewRender = null;
|
|
6273
|
+
output.write("\x1B[2J\x1B[H");
|
|
6274
|
+
resetHistoryFrameDiffCache(output);
|
|
6275
|
+
fixedInput.resumeFromDialog();
|
|
6276
|
+
flushPendingRender();
|
|
6277
|
+
renderHistoryToOutput();
|
|
6278
|
+
fixedInput.repaint(buffer, cursorPos);
|
|
6279
|
+
}
|
|
6280
|
+
return true;
|
|
6281
|
+
};
|
|
6180
6282
|
let modalOwnsKeyboard = false;
|
|
6181
6283
|
let rawActionGateTokenHandler = null;
|
|
6182
6284
|
const AUTO_THEME_POLL_MS = 3e4;
|
|
@@ -6247,27 +6349,18 @@ async function startTuiWorkspace(options) {
|
|
|
6247
6349
|
history.followBottom = true;
|
|
6248
6350
|
const isInternalEvent = req.event.kind !== "user";
|
|
6249
6351
|
const transcriptText = req.event.kind === "child-run-completed" ? req.event.displayText ?? req.event.text : message;
|
|
6250
|
-
const userTurnContent = isInternalEvent ? dimCliText(transcriptText, resolveCliColorEnabled()) : transcriptText;
|
|
6251
6352
|
startTurn(history, isInternalEvent ? "assistant" : "user");
|
|
6252
|
-
appendToCurrentTurn(
|
|
6353
|
+
appendToCurrentTurn(
|
|
6354
|
+
history,
|
|
6355
|
+
isInternalEvent ? dimCliText(transcriptText, resolveCliColorEnabled()) : transcriptText
|
|
6356
|
+
);
|
|
6253
6357
|
finalizeCurrentTurn(history);
|
|
6254
|
-
|
|
6255
|
-
commitTurnToTerminal(
|
|
6256
|
-
output,
|
|
6257
|
-
{
|
|
6258
|
-
role: isInternalEvent ? "assistant" : "user",
|
|
6259
|
-
content: userTurnContent
|
|
6260
|
-
},
|
|
6261
|
-
{ addBlankSeparator: true }
|
|
6262
|
-
);
|
|
6263
|
-
} else {
|
|
6264
|
-
renderHistoryToOutput();
|
|
6265
|
-
}
|
|
6358
|
+
renderHistoryToOutput();
|
|
6266
6359
|
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
6267
6360
|
startTurn(history, "assistant");
|
|
6268
|
-
const agentOutput = isInteractiveInput(input) ?
|
|
6361
|
+
const agentOutput = isInteractiveInput(input) ? createHistoryOutputStream(history, () => {
|
|
6269
6362
|
scheduleRender();
|
|
6270
|
-
}) :
|
|
6363
|
+
}) : output;
|
|
6271
6364
|
const requestUserChoice = isInteractiveInput(input) && dialogHost ? async (req2) => {
|
|
6272
6365
|
modalOwnsKeyboard = true;
|
|
6273
6366
|
try {
|
|
@@ -6345,11 +6438,7 @@ async function startTuiWorkspace(options) {
|
|
|
6345
6438
|
if (isInteractiveInput(input)) {
|
|
6346
6439
|
finalizeCurrentTurn(history);
|
|
6347
6440
|
flushPendingRender();
|
|
6348
|
-
|
|
6349
|
-
renderHistoryToOutput();
|
|
6350
|
-
} else {
|
|
6351
|
-
output.write("\n");
|
|
6352
|
-
}
|
|
6441
|
+
renderHistoryToOutput();
|
|
6353
6442
|
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
6354
6443
|
}
|
|
6355
6444
|
if (wasAborted) {
|
|
@@ -6418,19 +6507,7 @@ async function startTuiWorkspace(options) {
|
|
|
6418
6507
|
}
|
|
6419
6508
|
history.followBottom = true;
|
|
6420
6509
|
appendLocalTurn(history, command, text);
|
|
6421
|
-
|
|
6422
|
-
commitTurnToTerminal(
|
|
6423
|
-
output,
|
|
6424
|
-
{
|
|
6425
|
-
role: "local",
|
|
6426
|
-
content: text,
|
|
6427
|
-
command
|
|
6428
|
-
},
|
|
6429
|
-
{ addBlankSeparator: true }
|
|
6430
|
-
);
|
|
6431
|
-
} else {
|
|
6432
|
-
renderHistoryToOutput();
|
|
6433
|
-
}
|
|
6510
|
+
renderHistoryToOutput();
|
|
6434
6511
|
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
6435
6512
|
};
|
|
6436
6513
|
const persistExplicitAgentSwitch = (previousAgentKey) => {
|
|
@@ -6673,6 +6750,10 @@ async function startTuiWorkspace(options) {
|
|
|
6673
6750
|
renderHistoryToOutput();
|
|
6674
6751
|
fixedInput.repaint(buffer, cursorPos);
|
|
6675
6752
|
}
|
|
6753
|
+
if (result.action?.type === "copy-view") {
|
|
6754
|
+
const opened = await openCopyView();
|
|
6755
|
+
if (!opened) emitCommandOutput(t("copyNothing"));
|
|
6756
|
+
}
|
|
6676
6757
|
if (result.action?.type === "copy-last") {
|
|
6677
6758
|
const text = readLatestAssistantReply() ?? "";
|
|
6678
6759
|
if (!text) {
|
|
@@ -6719,11 +6800,6 @@ async function startTuiWorkspace(options) {
|
|
|
6719
6800
|
history.currentContent = "";
|
|
6720
6801
|
history.scrollTop = 0;
|
|
6721
6802
|
history.followBottom = true;
|
|
6722
|
-
if (!isAltScreenOn(output)) {
|
|
6723
|
-
for (const turn of restored) {
|
|
6724
|
-
commitTurnToTerminal(output, turn, { addBlankSeparator: true });
|
|
6725
|
-
}
|
|
6726
|
-
}
|
|
6727
6803
|
state = {
|
|
6728
6804
|
...state,
|
|
6729
6805
|
dialogId: pickResult.dialog.id,
|
|
@@ -6897,10 +6973,12 @@ ${err.message}` : ""}`
|
|
|
6897
6973
|
};
|
|
6898
6974
|
const onResize = () => {
|
|
6899
6975
|
if (done) return;
|
|
6976
|
+
if (copyViewExitResolver) {
|
|
6977
|
+
copyViewRender?.();
|
|
6978
|
+
return;
|
|
6979
|
+
}
|
|
6900
6980
|
if (fixedInput.isPaused()) {
|
|
6901
|
-
|
|
6902
|
-
renderHistory(output, history, fixedInput.getInputLines());
|
|
6903
|
-
}
|
|
6981
|
+
renderHistory(output, history, fixedInput.getInputLines());
|
|
6904
6982
|
fixedInput.repaint(buffer, cursorPos);
|
|
6905
6983
|
return;
|
|
6906
6984
|
}
|
|
@@ -6991,7 +7069,7 @@ ${err.message}` : ""}`
|
|
|
6991
7069
|
};
|
|
6992
7070
|
runWakeHandler = (event) => {
|
|
6993
7071
|
if (done) return;
|
|
6994
|
-
if (busy || fixedInput.isPaused()) {
|
|
7072
|
+
if (busy || fixedInput.isPaused() || copyViewExitResolver) {
|
|
6995
7073
|
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
6996
7074
|
ensureChatQueueBinding(actionGateHandler, confirmDestructiveAction).enqueue(event);
|
|
6997
7075
|
if (fixedInput.active && !fixedInput.isPaused()) {
|
|
@@ -7008,6 +7086,49 @@ ${err.message}` : ""}`
|
|
|
7008
7086
|
};
|
|
7009
7087
|
const handleInputToken = async (sequence) => {
|
|
7010
7088
|
if (done) return;
|
|
7089
|
+
if (copyViewExitResolver) {
|
|
7090
|
+
const tty = output;
|
|
7091
|
+
const visibleHeight = Math.max(1, (tty.rows ?? 24) - 3);
|
|
7092
|
+
const lines = buildCopyViewLines(history);
|
|
7093
|
+
const maxScrollTop = Math.max(0, lines.length - visibleHeight);
|
|
7094
|
+
const scrollAction2 = parseScrollAction(sequence);
|
|
7095
|
+
if (scrollAction2) {
|
|
7096
|
+
switch (scrollAction2) {
|
|
7097
|
+
case "page-up":
|
|
7098
|
+
copyViewScrollTop = Math.max(0, copyViewScrollTop - visibleHeight);
|
|
7099
|
+
break;
|
|
7100
|
+
case "page-down":
|
|
7101
|
+
copyViewScrollTop = Math.min(maxScrollTop, copyViewScrollTop + visibleHeight);
|
|
7102
|
+
break;
|
|
7103
|
+
case "half-page-up":
|
|
7104
|
+
copyViewScrollTop = Math.max(0, copyViewScrollTop - Math.max(1, Math.floor(visibleHeight / 2)));
|
|
7105
|
+
break;
|
|
7106
|
+
case "wheel-up":
|
|
7107
|
+
copyViewScrollTop = Math.max(0, copyViewScrollTop - WHEEL_SCROLL_LINES);
|
|
7108
|
+
break;
|
|
7109
|
+
case "half-page-down":
|
|
7110
|
+
copyViewScrollTop = Math.min(maxScrollTop, copyViewScrollTop + Math.max(1, Math.floor(visibleHeight / 2)));
|
|
7111
|
+
break;
|
|
7112
|
+
case "wheel-down":
|
|
7113
|
+
copyViewScrollTop = Math.min(maxScrollTop, copyViewScrollTop + WHEEL_SCROLL_LINES);
|
|
7114
|
+
break;
|
|
7115
|
+
case "top":
|
|
7116
|
+
copyViewScrollTop = 0;
|
|
7117
|
+
break;
|
|
7118
|
+
case "bottom":
|
|
7119
|
+
copyViewScrollTop = maxScrollTop;
|
|
7120
|
+
break;
|
|
7121
|
+
}
|
|
7122
|
+
copyViewRender?.();
|
|
7123
|
+
return;
|
|
7124
|
+
}
|
|
7125
|
+
if (sequence === "\x1B" || sequence === "\r" || sequence === "\n" || sequence === "") {
|
|
7126
|
+
const exitCopyView = copyViewExitResolver;
|
|
7127
|
+
copyViewExitResolver = null;
|
|
7128
|
+
exitCopyView();
|
|
7129
|
+
}
|
|
7130
|
+
return;
|
|
7131
|
+
}
|
|
7011
7132
|
if (modalOwnsKeyboard) {
|
|
7012
7133
|
rawActionGateTokenHandler?.(sequence);
|
|
7013
7134
|
return;
|
|
@@ -7037,6 +7158,13 @@ ${merged}` : merged;
|
|
|
7037
7158
|
return handleInputToken("\r");
|
|
7038
7159
|
}
|
|
7039
7160
|
const busyLock = busy;
|
|
7161
|
+
const scrollAction = parseScrollAction(sequence);
|
|
7162
|
+
if (scrollAction) {
|
|
7163
|
+
if (fixedInput.isPaused()) return;
|
|
7164
|
+
applyScrollAction(history, scrollAction, output, fixedInput.getInputLines());
|
|
7165
|
+
paintFrame(buffer);
|
|
7166
|
+
return;
|
|
7167
|
+
}
|
|
7040
7168
|
if (busyLock && sequence === "\x1B" && activeTurnAbort) {
|
|
7041
7169
|
if (activityIndicator.isStopping()) {
|
|
7042
7170
|
forcedStop = true;
|
|
@@ -7063,27 +7191,23 @@ ${merged}` : merged;
|
|
|
7063
7191
|
const result = applyTuiInputKey(buffer, sequence, {}, cursorPos, {
|
|
7064
7192
|
pasteStore
|
|
7065
7193
|
});
|
|
7066
|
-
if (result.
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
output,
|
|
7075
|
-
{ role: history.currentRole, content: history.currentContent },
|
|
7076
|
-
{ addBlankSeparator: true }
|
|
7077
|
-
);
|
|
7078
|
-
}
|
|
7079
|
-
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos, true);
|
|
7080
|
-
} else {
|
|
7081
|
-
resetHistoryFrameDiffCache(output);
|
|
7082
|
-
renderHistoryToOutput();
|
|
7083
|
-
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos, true);
|
|
7194
|
+
if (result.copyView) {
|
|
7195
|
+
const opened = await openCopyView();
|
|
7196
|
+
if (!opened) {
|
|
7197
|
+
history.followBottom = true;
|
|
7198
|
+
startTurn(history, "assistant");
|
|
7199
|
+
appendToCurrentTurn(history, t("copyNothing"));
|
|
7200
|
+
finalizeCurrentTurn(history);
|
|
7201
|
+
paintFrame(buffer);
|
|
7084
7202
|
}
|
|
7085
7203
|
return;
|
|
7086
7204
|
}
|
|
7205
|
+
if (result.redraw) {
|
|
7206
|
+
resetHistoryFrameDiffCache(output);
|
|
7207
|
+
renderHistoryToOutput();
|
|
7208
|
+
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos, true);
|
|
7209
|
+
return;
|
|
7210
|
+
}
|
|
7087
7211
|
if (result.abort) {
|
|
7088
7212
|
fixedInput.disable();
|
|
7089
7213
|
finish();
|
|
@@ -7266,6 +7390,7 @@ export {
|
|
|
7266
7390
|
appendLocalTurn,
|
|
7267
7391
|
appendToCurrentTurn,
|
|
7268
7392
|
applyOutputChunkToCurrentTurn,
|
|
7393
|
+
applyScrollAction,
|
|
7269
7394
|
applyTerminalOutputToText,
|
|
7270
7395
|
buildWindowTitle,
|
|
7271
7396
|
countPhysicalLines,
|
|
@@ -7282,6 +7407,7 @@ export {
|
|
|
7282
7407
|
isAltScreenOn,
|
|
7283
7408
|
leaveAltScreen,
|
|
7284
7409
|
padOrTruncateToWidth,
|
|
7410
|
+
parseScrollAction,
|
|
7285
7411
|
renderHistory,
|
|
7286
7412
|
renderPinnedAgentNotice,
|
|
7287
7413
|
resetHistoryFrameDiffCache,
|