@vendian/cli 0.0.30 → 0.0.31
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/cli-wrapper.mjs +111 -83
- package/package.json +1 -1
package/cli-wrapper.mjs
CHANGED
|
@@ -1107,7 +1107,7 @@ import path8 from "node:path";
|
|
|
1107
1107
|
import readlinePromises from "node:readline/promises";
|
|
1108
1108
|
|
|
1109
1109
|
// src/version.js
|
|
1110
|
-
var CLI_VERSION = true ? "0.0.
|
|
1110
|
+
var CLI_VERSION = true ? "0.0.31" : process.env.npm_package_version || "0.0.0-dev";
|
|
1111
1111
|
|
|
1112
1112
|
// src/npm-update.js
|
|
1113
1113
|
var NPM_CHECK_INTERVAL_MS = 30 * 60 * 1e3;
|
|
@@ -2398,6 +2398,7 @@ async function loadTerm() {
|
|
|
2398
2398
|
term = tk.default.terminal;
|
|
2399
2399
|
}
|
|
2400
2400
|
var HEADER_ROWS_BASE = 7;
|
|
2401
|
+
var HEADER_ROWS_SERVE = 8;
|
|
2401
2402
|
var SERVE_CONTENT_ROW = 10;
|
|
2402
2403
|
function clampListIndex(index, count) {
|
|
2403
2404
|
if (!Number.isFinite(count) || count <= 0) return 0;
|
|
@@ -2988,6 +2989,7 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId }) {
|
|
|
2988
2989
|
let child = null;
|
|
2989
2990
|
let startupError = "";
|
|
2990
2991
|
let overlayActive = false;
|
|
2992
|
+
let overlayRedraw = null;
|
|
2991
2993
|
let ctrlCArmed = false;
|
|
2992
2994
|
let ctrlCArmTimer = null;
|
|
2993
2995
|
let dashboardClosed = false;
|
|
@@ -3005,7 +3007,8 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId }) {
|
|
|
3005
3007
|
const status = friendlyStatus(rt.status);
|
|
3006
3008
|
const path_ = agent.relativePath || ".";
|
|
3007
3009
|
const runst = state.agentRunState[path_];
|
|
3008
|
-
const
|
|
3010
|
+
const rawErr = runst?.errorMessage || (rt.status === "error" ? "Something went wrong" : null);
|
|
3011
|
+
const errMsg2 = rawErr ? typeof rawErr === "string" ? rawErr : rawErr.message || JSON.stringify(rawErr) : null;
|
|
3009
3012
|
return { num: i + 1, name, status, errMsg: errMsg2, path: path_ };
|
|
3010
3013
|
});
|
|
3011
3014
|
}
|
|
@@ -3024,55 +3027,62 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId }) {
|
|
|
3024
3027
|
}
|
|
3025
3028
|
function redraw() {
|
|
3026
3029
|
if (dashboardClosed || overlayActive) return;
|
|
3030
|
+
const W = term.width || 80;
|
|
3031
|
+
const H = term.height || 24;
|
|
3027
3032
|
const agents = agentDisplayList();
|
|
3028
3033
|
const activity = recentActivityLines();
|
|
3029
3034
|
const diagnostics = daemonDebugLines();
|
|
3030
3035
|
const viewport = computeServeDashboardViewport({
|
|
3031
|
-
termHeight:
|
|
3036
|
+
termHeight: H,
|
|
3032
3037
|
agentCount: agents.length,
|
|
3033
3038
|
selectedIdx,
|
|
3034
3039
|
activityCount: activity.length,
|
|
3035
3040
|
diagnosticsCount: diagnostics.length
|
|
3036
3041
|
});
|
|
3037
3042
|
selectedIdx = viewport.selectedIdx;
|
|
3038
|
-
|
|
3039
|
-
term.moveTo(1, SERVE_CONTENT_ROW);
|
|
3040
|
-
term.eraseDisplayBelow();
|
|
3043
|
+
term.clear();
|
|
3041
3044
|
agentRowMap.clear();
|
|
3045
|
+
drawHeader({ env, platform, serveState: state });
|
|
3046
|
+
term("\n");
|
|
3047
|
+
let currentRow = HEADER_ROWS_SERVE + 2;
|
|
3042
3048
|
if (startupError) {
|
|
3043
|
-
term.red(` ${fig.cross} ${clip(startupError,
|
|
3049
|
+
term.red(` ${fig.cross} ${clip(startupError, W - 6)}
|
|
3044
3050
|
`);
|
|
3045
3051
|
} else if (stopRequested) {
|
|
3046
|
-
term.yellow(` ${fig.warning} ${clip(state.activity || "Stopping your agents\u2026",
|
|
3052
|
+
term.yellow(` ${fig.warning} ${clip(state.activity || "Stopping your agents\u2026", W - 6)}
|
|
3047
3053
|
`);
|
|
3048
3054
|
} else if (state.stopped) {
|
|
3049
3055
|
term.yellow(` ${fig.warning} Your agents have stopped.
|
|
3050
3056
|
`);
|
|
3051
3057
|
} else if (state.connected) {
|
|
3052
3058
|
term.green(` ${fig.dot} `);
|
|
3053
|
-
term.gray(`${clip(state.activity || "Your agents are running",
|
|
3059
|
+
term.gray(`${clip(state.activity || "Your agents are running", W - 10)}
|
|
3054
3060
|
`);
|
|
3055
3061
|
} else {
|
|
3056
3062
|
term.cyan(` ${fig.dotEmpty} `);
|
|
3057
|
-
term.gray(`${clip(state.activity || "Starting up\u2026",
|
|
3063
|
+
term.gray(`${clip(state.activity || "Starting up\u2026", W - 10)}
|
|
3058
3064
|
`);
|
|
3059
3065
|
}
|
|
3066
|
+
currentRow++;
|
|
3060
3067
|
if (agents.length > 0) {
|
|
3061
|
-
if (viewport.showBlankAfterStatus)
|
|
3068
|
+
if (viewport.showBlankAfterStatus) {
|
|
3069
|
+
term("\n");
|
|
3070
|
+
currentRow++;
|
|
3071
|
+
}
|
|
3062
3072
|
term.bold.gray(" Your agents:\n");
|
|
3063
|
-
|
|
3073
|
+
currentRow++;
|
|
3064
3074
|
const visibleAgents = agents.slice(
|
|
3065
3075
|
viewport.agentWindowStart,
|
|
3066
3076
|
viewport.agentWindowStart + viewport.visibleAgentCount
|
|
3067
3077
|
);
|
|
3068
3078
|
for (const ag of visibleAgents) {
|
|
3069
3079
|
const isSelected = ag.num - 1 === selectedIdx;
|
|
3070
|
-
agentRowMap.set(
|
|
3080
|
+
agentRowMap.set(currentRow, ag.num - 1);
|
|
3071
3081
|
const numStr = String(ag.num).padStart(2);
|
|
3072
3082
|
const nameStr = clip(ag.name, 28).padEnd(28);
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
else {
|
|
3083
|
+
if (isSelected) {
|
|
3084
|
+
term.bgCyan.black.bold(` ${numStr} ${ag.status.icon} ${nameStr} ${ag.status.text}`);
|
|
3085
|
+
} else {
|
|
3076
3086
|
term(` ${numStr} `);
|
|
3077
3087
|
switch (ag.status.color) {
|
|
3078
3088
|
case "green":
|
|
@@ -3115,11 +3125,11 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId }) {
|
|
|
3115
3125
|
}
|
|
3116
3126
|
}
|
|
3117
3127
|
term("\n");
|
|
3118
|
-
|
|
3128
|
+
currentRow++;
|
|
3119
3129
|
if (viewport.showInlineErrors && isSelected && ag.errMsg) {
|
|
3120
|
-
term.red(` \u2514\u2500 ${clip(ag.errMsg,
|
|
3130
|
+
term.red(` \u2514\u2500 ${clip(ag.errMsg, W - 14)}
|
|
3121
3131
|
`);
|
|
3122
|
-
|
|
3132
|
+
currentRow++;
|
|
3123
3133
|
}
|
|
3124
3134
|
}
|
|
3125
3135
|
if (viewport.showAgentRange) {
|
|
@@ -3127,24 +3137,31 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId }) {
|
|
|
3127
3137
|
const last = viewport.agentWindowStart + visibleAgents.length;
|
|
3128
3138
|
term.gray(` Showing agents ${first}\u2013${last} of ${agents.length}
|
|
3129
3139
|
`);
|
|
3140
|
+
currentRow++;
|
|
3130
3141
|
}
|
|
3131
3142
|
if (viewport.showAgentHint) {
|
|
3132
3143
|
term.gray(` Click an agent or use \u2191\u2193 + Enter to see its activity log
|
|
3133
3144
|
`);
|
|
3145
|
+
currentRow++;
|
|
3134
3146
|
}
|
|
3135
3147
|
} else {
|
|
3136
|
-
if (viewport.showBlankAfterStatus)
|
|
3148
|
+
if (viewport.showBlankAfterStatus) {
|
|
3149
|
+
term("\n");
|
|
3150
|
+
currentRow++;
|
|
3151
|
+
}
|
|
3137
3152
|
term.gray(" Looking for your agents\u2026\n");
|
|
3153
|
+
currentRow++;
|
|
3138
3154
|
}
|
|
3139
3155
|
if (viewport.showActivityHeader) {
|
|
3140
3156
|
const visibleActivity = activity.slice(-viewport.visibleActivityCount);
|
|
3141
|
-
const divW = Math.min(
|
|
3157
|
+
const divW = Math.min(W - 4, 60);
|
|
3142
3158
|
term.gray(` ${"\u2500".repeat(3)} Recent activity ${"\u2500".repeat(Math.max(0, divW - 18))}
|
|
3143
3159
|
`);
|
|
3160
|
+
currentRow++;
|
|
3144
3161
|
for (const e of visibleActivity) {
|
|
3145
3162
|
const t = formatLogTime(e.timestamp);
|
|
3146
3163
|
const name = clip(e._agentName || "Agent", 20);
|
|
3147
|
-
const msg = clip(friendlyActivityLine(e),
|
|
3164
|
+
const msg = clip(friendlyActivityLine(e), W - 32);
|
|
3148
3165
|
if (e.level === "error" || e.eventType === "completion" && e.success === false) {
|
|
3149
3166
|
term.gray(` ${t} `);
|
|
3150
3167
|
term.red(`${name} \u2014 ${msg}
|
|
@@ -3161,31 +3178,32 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId }) {
|
|
|
3161
3178
|
term.gray(` ${t} ${name} \u2014 ${msg}
|
|
3162
3179
|
`);
|
|
3163
3180
|
}
|
|
3181
|
+
currentRow++;
|
|
3164
3182
|
}
|
|
3165
3183
|
}
|
|
3166
3184
|
if (viewport.showDiagnosticsHeader) {
|
|
3167
3185
|
const visibleDiagnostics = diagnostics.slice(-viewport.visibleDiagnosticsCount);
|
|
3168
|
-
const divW = Math.min(
|
|
3186
|
+
const divW = Math.min(W - 4, 72);
|
|
3169
3187
|
term.gray(` ${"\u2500".repeat(3)} Daemon diagnostics ${"\u2500".repeat(Math.max(0, divW - 23))}
|
|
3170
3188
|
`);
|
|
3189
|
+
currentRow++;
|
|
3171
3190
|
for (const entry of visibleDiagnostics) {
|
|
3172
3191
|
const t = formatLogTime(entry.timestamp);
|
|
3173
|
-
const type = clip(entry.eventType || "event",
|
|
3174
|
-
const msg = clip(entry.message || "",
|
|
3192
|
+
const type = clip(entry.eventType || "event", 22).padEnd(22);
|
|
3193
|
+
const msg = clip(entry.message || "", W - 36);
|
|
3175
3194
|
term.gray(` ${t} `);
|
|
3176
|
-
if (entry.level === "error") {
|
|
3177
|
-
term.red(`${type} ${msg}
|
|
3195
|
+
if (entry.level === "error") term.red(`${type} ${msg}
|
|
3178
3196
|
`);
|
|
3179
|
-
|
|
3180
|
-
term.yellow(`${type} ${msg}
|
|
3197
|
+
else if (entry.level === "warn") term.yellow(`${type} ${msg}
|
|
3181
3198
|
`);
|
|
3182
|
-
|
|
3183
|
-
term.gray(`${type} ${msg}
|
|
3199
|
+
else term.gray(`${type} ${msg}
|
|
3184
3200
|
`);
|
|
3185
|
-
|
|
3201
|
+
currentRow++;
|
|
3186
3202
|
}
|
|
3187
3203
|
}
|
|
3188
|
-
|
|
3204
|
+
const footerRow = Math.max(currentRow + 1, H - 1);
|
|
3205
|
+
if (footerRow < H) term.moveTo(1, footerRow);
|
|
3206
|
+
else term("\n");
|
|
3189
3207
|
if (ctrlCArmed) {
|
|
3190
3208
|
term.yellow.bold(" Press Ctrl+C again to exit.\n");
|
|
3191
3209
|
} else if (stopRequested) {
|
|
@@ -3202,7 +3220,7 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId }) {
|
|
|
3202
3220
|
}
|
|
3203
3221
|
term.clear();
|
|
3204
3222
|
drawHeader({ env, platform, serveState: state });
|
|
3205
|
-
term
|
|
3223
|
+
term("\n");
|
|
3206
3224
|
term.cyan(` ${fig.dotEmpty} Getting your agents ready\u2026
|
|
3207
3225
|
`);
|
|
3208
3226
|
try {
|
|
@@ -3233,12 +3251,14 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId }) {
|
|
|
3233
3251
|
(updater) => {
|
|
3234
3252
|
if (dashboardClosed) return;
|
|
3235
3253
|
state = updater(state);
|
|
3236
|
-
|
|
3254
|
+
if (overlayActive && typeof overlayRedraw === "function") overlayRedraw();
|
|
3255
|
+
else redraw();
|
|
3237
3256
|
},
|
|
3238
3257
|
({ message } = {}) => {
|
|
3239
3258
|
if (dashboardClosed) return;
|
|
3240
3259
|
if (!state.stopped) state = { ...state, stopped: true, activity: message || "Stopped" };
|
|
3241
|
-
|
|
3260
|
+
if (overlayActive && typeof overlayRedraw === "function") overlayRedraw();
|
|
3261
|
+
else redraw();
|
|
3242
3262
|
},
|
|
3243
3263
|
logStore
|
|
3244
3264
|
);
|
|
@@ -3252,10 +3272,20 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId }) {
|
|
|
3252
3272
|
const clampedIdx = clampListIndex(idx, agents.length);
|
|
3253
3273
|
if (dashboardClosed || exitPromptActive || agents.length === 0 || idx !== clampedIdx) return;
|
|
3254
3274
|
overlayActive = true;
|
|
3275
|
+
overlayRedraw = null;
|
|
3255
3276
|
const ag = agents[clampedIdx];
|
|
3256
|
-
showAgentLog({
|
|
3277
|
+
showAgentLog({
|
|
3278
|
+
agent: ag,
|
|
3279
|
+
getState: () => state,
|
|
3280
|
+
onAttachLiveUpdates: (redrawFn) => {
|
|
3281
|
+
overlayRedraw = redrawFn;
|
|
3282
|
+
},
|
|
3283
|
+
env,
|
|
3284
|
+
platform
|
|
3285
|
+
}).then(() => {
|
|
3257
3286
|
if (dashboardClosed) return;
|
|
3258
3287
|
overlayActive = false;
|
|
3288
|
+
overlayRedraw = null;
|
|
3259
3289
|
term.clear();
|
|
3260
3290
|
redraw();
|
|
3261
3291
|
});
|
|
@@ -3411,57 +3441,57 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId }) {
|
|
|
3411
3441
|
}
|
|
3412
3442
|
});
|
|
3413
3443
|
}
|
|
3414
|
-
async function showAgentLog({ agent, getState, env, platform }) {
|
|
3444
|
+
async function showAgentLog({ agent, getState, onAttachLiveUpdates, env, platform }) {
|
|
3415
3445
|
const liveState = typeof getState === "function" ? getState : () => getState;
|
|
3446
|
+
const H = term.height || 24;
|
|
3447
|
+
const visibleCount = Math.max(4, H - 14);
|
|
3416
3448
|
let scrollOffset = 0;
|
|
3417
3449
|
let autoScroll = true;
|
|
3418
|
-
|
|
3450
|
+
let done = false;
|
|
3419
3451
|
function currentLogs() {
|
|
3420
3452
|
return agentLogEntries(liveState().agentLogs, agent.path);
|
|
3421
3453
|
}
|
|
3422
3454
|
function draw() {
|
|
3423
|
-
|
|
3455
|
+
if (done) return;
|
|
3456
|
+
const curState = liveState();
|
|
3424
3457
|
const logs = currentLogs();
|
|
3425
|
-
const agentObj =
|
|
3426
|
-
const runtime = agentObj ? agentRuntimeStatus(agentObj,
|
|
3458
|
+
const agentObj = curState.agents.find((a) => (a.relativePath || ".") === agent.path);
|
|
3459
|
+
const runtime = agentObj ? agentRuntimeStatus(agentObj, curState.agentRunState) : { status: "unknown", label: "offline" };
|
|
3427
3460
|
const status = friendlyStatus(runtime.status);
|
|
3428
|
-
|
|
3461
|
+
const W = term.width || 80;
|
|
3462
|
+
if (autoScroll || scrollOffset > Math.max(0, logs.length - visibleCount)) {
|
|
3429
3463
|
scrollOffset = Math.max(0, logs.length - visibleCount);
|
|
3464
|
+
autoScroll = logs.length > 0;
|
|
3430
3465
|
}
|
|
3431
3466
|
term.clear();
|
|
3432
|
-
drawHeader({ env, platform, serveState:
|
|
3467
|
+
drawHeader({ env, platform, serveState: curState });
|
|
3433
3468
|
term("\n");
|
|
3434
3469
|
term.bold(` ${agent.name}
|
|
3435
3470
|
`);
|
|
3436
|
-
term.gray(
|
|
3471
|
+
term.gray(" ");
|
|
3437
3472
|
switch (status.color) {
|
|
3438
3473
|
case "green":
|
|
3439
|
-
term.green(`${status.icon} ${status.text}
|
|
3440
|
-
`);
|
|
3474
|
+
term.green(`${status.icon} ${status.text}`);
|
|
3441
3475
|
break;
|
|
3442
3476
|
case "brightBlue":
|
|
3443
|
-
term.brightBlue(`${status.icon} ${status.text}
|
|
3444
|
-
`);
|
|
3477
|
+
term.brightBlue(`${status.icon} ${status.text}`);
|
|
3445
3478
|
break;
|
|
3446
3479
|
case "yellow":
|
|
3447
|
-
term.yellow(`${status.icon} ${status.text}
|
|
3448
|
-
`);
|
|
3480
|
+
term.yellow(`${status.icon} ${status.text}`);
|
|
3449
3481
|
break;
|
|
3450
3482
|
case "red":
|
|
3451
|
-
term.red(`${status.icon} ${status.text}
|
|
3452
|
-
`);
|
|
3483
|
+
term.red(`${status.icon} ${status.text}`);
|
|
3453
3484
|
break;
|
|
3454
3485
|
default:
|
|
3455
|
-
term.gray(`${status.icon} ${status.text}
|
|
3456
|
-
`);
|
|
3486
|
+
term.gray(`${status.icon} ${status.text}`);
|
|
3457
3487
|
}
|
|
3458
|
-
term("\n");
|
|
3488
|
+
term("\n\n");
|
|
3459
3489
|
if (logs.length === 0) {
|
|
3460
|
-
term.gray(" No activity
|
|
3490
|
+
term.gray(" No activity yet \u2014 logs appear here as the agent runs.\n");
|
|
3461
3491
|
} else {
|
|
3462
|
-
const eff = scrollOffset
|
|
3492
|
+
const eff = Math.min(scrollOffset, Math.max(0, logs.length - visibleCount));
|
|
3463
3493
|
const visible = logs.slice(eff, eff + visibleCount);
|
|
3464
|
-
const msgW = Math.max(
|
|
3494
|
+
const msgW = Math.max(30, W - 16);
|
|
3465
3495
|
for (const entry of visible) {
|
|
3466
3496
|
const t = formatLogTime(entry.timestamp);
|
|
3467
3497
|
const text = clip(formatAgentLogEntry(entry), msgW);
|
|
@@ -3474,6 +3504,9 @@ async function showAgentLog({ agent, getState, env, platform }) {
|
|
|
3474
3504
|
`);
|
|
3475
3505
|
} else if (entry.eventType === "job_started") {
|
|
3476
3506
|
term.brightBlue(`\u25B6 ${text}
|
|
3507
|
+
`);
|
|
3508
|
+
} else if (entry.eventType === "progress") {
|
|
3509
|
+
term.cyan(`\u2192 ${text}
|
|
3477
3510
|
`);
|
|
3478
3511
|
} else {
|
|
3479
3512
|
term.gray(`\u2014 ${text}
|
|
@@ -3481,42 +3514,36 @@ async function showAgentLog({ agent, getState, env, platform }) {
|
|
|
3481
3514
|
}
|
|
3482
3515
|
}
|
|
3483
3516
|
if (logs.length > visibleCount) {
|
|
3517
|
+
const eff2 = Math.min(eff, Math.max(0, logs.length - visibleCount));
|
|
3484
3518
|
term.gray(`
|
|
3485
|
-
|
|
3486
|
-
|
|
3519
|
+
${eff2 + 1}\u2013${eff2 + visible.length} of ${logs.length}`);
|
|
3520
|
+
if (autoScroll) term.cyan(" \u2193 live");
|
|
3521
|
+
term("\n");
|
|
3487
3522
|
}
|
|
3488
3523
|
}
|
|
3489
|
-
term(
|
|
3524
|
+
term.moveTo(1, Math.max(H - 1, 6));
|
|
3490
3525
|
term.gray(" ");
|
|
3491
3526
|
term.brightBlue.bold("\u2191\u2193");
|
|
3492
|
-
term.gray(" scroll ");
|
|
3493
|
-
|
|
3494
|
-
term.gray(" page ");
|
|
3495
|
-
if (autoScroll) {
|
|
3496
|
-
term.brightBlue.bold("Esc");
|
|
3497
|
-
term.gray(" back ");
|
|
3498
|
-
term.cyan("\u2193 live\n");
|
|
3499
|
-
} else {
|
|
3500
|
-
term.brightBlue.bold("Esc");
|
|
3501
|
-
term.gray(" back ");
|
|
3502
|
-
term.gray("\u2193 ");
|
|
3527
|
+
term.gray("/PgUp/PgDn scroll ");
|
|
3528
|
+
if (!autoScroll) {
|
|
3503
3529
|
term.brightBlue.bold("End");
|
|
3504
|
-
term.gray(" resume live
|
|
3530
|
+
term.gray(" resume live ");
|
|
3505
3531
|
}
|
|
3532
|
+
term.brightBlue.bold("Esc");
|
|
3533
|
+
term.gray(" back\n");
|
|
3534
|
+
}
|
|
3535
|
+
if (typeof onAttachLiveUpdates === "function") {
|
|
3536
|
+
onAttachLiveUpdates(() => draw());
|
|
3506
3537
|
}
|
|
3507
3538
|
draw();
|
|
3508
|
-
let overlayDone = false;
|
|
3509
|
-
const redrawInterval = setInterval(() => {
|
|
3510
|
-
if (!overlayDone) draw();
|
|
3511
|
-
}, 500);
|
|
3512
3539
|
await new Promise((resolve) => {
|
|
3513
3540
|
function handler(name) {
|
|
3541
|
+
if (done) return;
|
|
3514
3542
|
const logs = currentLogs();
|
|
3515
3543
|
const maxOff = Math.max(0, logs.length - visibleCount);
|
|
3516
3544
|
if (name === "ESCAPE") {
|
|
3545
|
+
done = true;
|
|
3517
3546
|
term.off("key", handler);
|
|
3518
|
-
overlayDone = true;
|
|
3519
|
-
clearInterval(redrawInterval);
|
|
3520
3547
|
resolve();
|
|
3521
3548
|
} else if (name === "UP") {
|
|
3522
3549
|
autoScroll = false;
|
|
@@ -3528,14 +3555,15 @@ async function showAgentLog({ agent, getState, env, platform }) {
|
|
|
3528
3555
|
draw();
|
|
3529
3556
|
} else if (name === "PAGE_UP") {
|
|
3530
3557
|
autoScroll = false;
|
|
3531
|
-
scrollOffset = Math.max(0, scrollOffset - visibleCount);
|
|
3558
|
+
scrollOffset = Math.max(0, scrollOffset - Math.max(1, visibleCount - 1));
|
|
3532
3559
|
draw();
|
|
3533
3560
|
} else if (name === "PAGE_DOWN") {
|
|
3534
|
-
scrollOffset = Math.min(maxOff, scrollOffset + visibleCount);
|
|
3561
|
+
scrollOffset = Math.min(maxOff, scrollOffset + Math.max(1, visibleCount - 1));
|
|
3535
3562
|
if (scrollOffset >= maxOff) autoScroll = true;
|
|
3536
3563
|
draw();
|
|
3537
|
-
} else if (name === "END") {
|
|
3564
|
+
} else if (name === "END" || name === "g") {
|
|
3538
3565
|
autoScroll = true;
|
|
3566
|
+
scrollOffset = maxOff;
|
|
3539
3567
|
draw();
|
|
3540
3568
|
}
|
|
3541
3569
|
}
|