skydive-cli 0.5.0-beta.23 → 0.5.0-beta.24
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/dist/js/bin.mjs +7 -7
- package/dist/js/{boot-D4Ov5CWq.mjs → boot-BPzsuEQF.mjs} +194 -25
- package/dist/js/{daemon-Cggp7WiN.mjs → daemon-BBeAB5SM.mjs} +1 -1
- package/dist/js/{daemon-OY-PnbML.mjs → daemon-BM8EJU8-.mjs} +1 -1
- package/dist/js/{daemon-client-BKBisL3m.mjs → daemon-client-CJrRjvat.mjs} +1 -1
- package/dist/js/daemon-client-DXXLCfAg.mjs +7 -0
- package/dist/js/{profiler-C4n2dBYm.mjs → profiler-DxmQ_Xqv.mjs} +1 -1
- package/package.json +1 -1
- package/dist/js/daemon-client-QBkMkgyS.mjs +0 -7
package/dist/js/bin.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { A as takenAliasNames, B as name, D as dedupeAliasName, E as aliasActivationHint, F as getActiveWorkspaceId, I as getSessionIdentity, L as listWorkspaces, M as defaultInstallEnv, N as detectShell, O as installAgentAlias, P as ensureActiveOrganization, R as resolveWorkspaceId, S as themes, T as machineOsFromPlatform, V as version, a as installCrashHandler, j as SUPPORTED_SHELLS, k as slugifyAliasName, t as maybeStartProfiling, u as brandHelpArt, w as buildImportSeedPrompt, z as setActiveWorkspace } from "./profiler-
|
|
2
|
+
import { A as takenAliasNames, B as name, D as dedupeAliasName, E as aliasActivationHint, F as getActiveWorkspaceId, I as getSessionIdentity, L as listWorkspaces, M as defaultInstallEnv, N as detectShell, O as installAgentAlias, P as ensureActiveOrganization, R as resolveWorkspaceId, S as themes, T as machineOsFromPlatform, V as version, a as installCrashHandler, j as SUPPORTED_SHELLS, k as slugifyAliasName, t as maybeStartProfiling, u as brandHelpArt, w as buildImportSeedPrompt, z as setActiveWorkspace } from "./profiler-DxmQ_Xqv.mjs";
|
|
3
3
|
import { A as getStoredApiKeyId, B as saveConfig, C as getDefaultAgent, E as getPromptHistoryPath, F as resolveChatAuth, I as resolveConfig, L as resolveManagementAuth, M as getUpdateCheckDisabled, P as resolveAppUrl, R as resolveSession, S as getConfigPath, T as getPreference, U as setLastSeenVersion, V as saveSession, _ as API_KEY_PREFIX, b as PREFERENCES, g as API_KEY_FAMILY_PREFIX, h as API_KEYS_URL, i as resolveAgent$1, j as getStoredApiKeyWorkspaceName, k as getShareMachineDefault, v as DEFAULT_API_URL, w as getLastSeenVersion, x as deleteConfig } from "./print-DQtIEVHh.mjs";
|
|
4
4
|
import { n as printError, r as printTable, t as output } from "./output-DYzzdXYV.mjs";
|
|
5
5
|
import { t as HttpError } from "./http-error-DzyrsLAZ.mjs";
|
|
6
6
|
import { t as createRestClient } from "./rest-Dx6b-Nq_.mjs";
|
|
7
7
|
import "./billing-blocked-2wju4gC_.mjs";
|
|
8
8
|
import { r as resolveMachineIdentity } from "./client-DbqRBquD.mjs";
|
|
9
|
-
import { i as queryDaemonStatus, l as PORTAL_DAEMON_FLAG, n as ensureDaemonRunning, s as stopDaemon, u as daemonPaths } from "./daemon-
|
|
9
|
+
import { i as queryDaemonStatus, l as PORTAL_DAEMON_FLAG, n as ensureDaemonRunning, s as stopDaemon, u as daemonPaths } from "./daemon-BBeAB5SM.mjs";
|
|
10
10
|
import { i as grantPortalAccess, n as fetchPortalDevices, o as registerPortalDevice, r as findThisDevice, s as revokePortalAccess } from "./api-DG5W6iwx.mjs";
|
|
11
11
|
import { t as SandboxStream } from "./client-c4c5MmgN.mjs";
|
|
12
12
|
import { hideBin } from "yargs/helpers";
|
|
@@ -1584,7 +1584,7 @@ const importCommand = {
|
|
|
1584
1584
|
process.exit(1);
|
|
1585
1585
|
}
|
|
1586
1586
|
}
|
|
1587
|
-
const { runChat } = await import("./boot-
|
|
1587
|
+
const { runChat } = await import("./boot-BPzsuEQF.mjs");
|
|
1588
1588
|
await runChat({
|
|
1589
1589
|
appUrl,
|
|
1590
1590
|
sessionToken: session.value.sessionToken,
|
|
@@ -2029,7 +2029,7 @@ const chatCommand = {
|
|
|
2029
2029
|
sessionToken: auth.value.token,
|
|
2030
2030
|
agentSelector: argv.agent ?? null
|
|
2031
2031
|
});
|
|
2032
|
-
const { runChat } = await import("./boot-
|
|
2032
|
+
const { runChat } = await import("./boot-BPzsuEQF.mjs");
|
|
2033
2033
|
await runChat({
|
|
2034
2034
|
appUrl: auth.value.appUrl,
|
|
2035
2035
|
sessionToken: auth.value.token,
|
|
@@ -2411,7 +2411,7 @@ const switchCommand = {
|
|
|
2411
2411
|
printError("The workspace picker needs the Bun runtime and it could not be set up automatically. Pass a workspace slug instead, or install Bun and retry.");
|
|
2412
2412
|
process.exit(1);
|
|
2413
2413
|
}
|
|
2414
|
-
const { runWorkspacePicker } = await import("./boot-
|
|
2414
|
+
const { runWorkspacePicker } = await import("./boot-BPzsuEQF.mjs");
|
|
2415
2415
|
await runWorkspacePicker(session);
|
|
2416
2416
|
return;
|
|
2417
2417
|
}
|
|
@@ -2490,7 +2490,7 @@ const openCommand = {
|
|
|
2490
2490
|
const agent = argv.agent ? resolveAgent$1((await fetchPortalDevices(session)).agents, argv.agent) : null;
|
|
2491
2491
|
const cwd = argv.cwd ? path.resolve(argv.cwd) : process.cwd();
|
|
2492
2492
|
const { machineName } = await resolveMachineIdentity(null);
|
|
2493
|
-
const { PortalDaemonClient } = await import("./daemon-client-
|
|
2493
|
+
const { PortalDaemonClient } = await import("./daemon-client-DXXLCfAg.mjs");
|
|
2494
2494
|
let lastLine = "";
|
|
2495
2495
|
let signalConnected;
|
|
2496
2496
|
const connected = new Promise((resolve) => {
|
|
@@ -4336,7 +4336,7 @@ if (process.argv.includes(UPDATE_WORKER_FLAG)) {
|
|
|
4336
4336
|
process.exit(0);
|
|
4337
4337
|
}
|
|
4338
4338
|
if (process.argv.includes(PORTAL_DAEMON_FLAG)) {
|
|
4339
|
-
const { runPortalDaemon } = await import("./daemon-
|
|
4339
|
+
const { runPortalDaemon } = await import("./daemon-BM8EJU8-.mjs");
|
|
4340
4340
|
runPortalDaemon(process.argv);
|
|
4341
4341
|
} else runCli();
|
|
4342
4342
|
function runCli() {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { A as takenAliasNames, C as themesForMode, D as dedupeAliasName, E as aliasActivationHint, F as getActiveWorkspaceId, L as listWorkspaces, N as detectShell, O as installAgentAlias, T as machineOsFromPlatform, _ as theme, a as installCrashHandler, b as themeModeFromColorFgBg, c as MARK_CELLS, d as splashFitsWidth, f as DEFAULT_THEME_ID, g as noColorRequested, h as monoTheme, i as writeArtifact, k as slugifyAliasName, l as WORDMARK, m as findTheme, n as profilingEnabled, o as buildCrashReport, p as applyTheme, r as record, s as writeCrashReport, v as themeForMode, x as themeVersion, y as themeMode, z as setActiveWorkspace } from "./profiler-
|
|
2
|
+
import { A as takenAliasNames, C as themesForMode, D as dedupeAliasName, E as aliasActivationHint, F as getActiveWorkspaceId, L as listWorkspaces, N as detectShell, O as installAgentAlias, T as machineOsFromPlatform, _ as theme, a as installCrashHandler, b as themeModeFromColorFgBg, c as MARK_CELLS, d as splashFitsWidth, f as DEFAULT_THEME_ID, g as noColorRequested, h as monoTheme, i as writeArtifact, k as slugifyAliasName, l as WORDMARK, m as findTheme, n as profilingEnabled, o as buildCrashReport, p as applyTheme, r as record, s as writeCrashReport, v as themeForMode, x as themeVersion, y as themeMode, z as setActiveWorkspace } from "./profiler-DxmQ_Xqv.mjs";
|
|
3
3
|
import { D as getReviewStateDir, H as saveTheme, N as recordDefaultAgent, O as getSavedTheme, S as getConfigPath, c as cardActionErrorMessage, d as reconcileMaskedInput, f as resolveConnectUrl, i as resolveAgent, l as parseExternalOauthConnectParams, m as specKeyFor, p as parseConnectCard, s as MASK_CHAR, u as parseOauthConnectParams, v as DEFAULT_API_URL, y as DEFAULT_APP_URL, z as resolveWebUrl } from "./print-DQtIEVHh.mjs";
|
|
4
4
|
import { t as HttpError } from "./http-error-DzyrsLAZ.mjs";
|
|
5
5
|
import { a as isRecord, i as errorMessage, n as errorDetail, r as sendErrorMessage, t as createRestClient } from "./rest-Dx6b-Nq_.mjs";
|
|
6
6
|
import { i as billingBlockedOutcomeFromSendResponse } from "./billing-blocked-2wju4gC_.mjs";
|
|
7
7
|
import { t as PortalClient } from "./client-DbqRBquD.mjs";
|
|
8
|
-
import "./daemon-
|
|
8
|
+
import "./daemon-BBeAB5SM.mjs";
|
|
9
9
|
import "./api-DG5W6iwx.mjs";
|
|
10
10
|
import { t as SandboxStream } from "./client-c4c5MmgN.mjs";
|
|
11
|
-
import { t as PortalDaemonClient } from "./daemon-client-
|
|
11
|
+
import { t as PortalDaemonClient } from "./daemon-client-CJrRjvat.mjs";
|
|
12
12
|
import { t as runRawPtyPassthrough } from "./raw-pty-DY4KelZW.mjs";
|
|
13
13
|
import * as os$1 from "node:os";
|
|
14
14
|
import { homedir, platform, release, tmpdir } from "node:os";
|
|
@@ -5111,6 +5111,14 @@ function shouldPollComputer(opts) {
|
|
|
5111
5111
|
* The command run in the sandbox to collect the snapshot. `sh`-portable, reads
|
|
5112
5112
|
* only `/proc` and `df`. Each metric is one `key<TAB>value` line so the parser
|
|
5113
5113
|
* never has to positionally align anything.
|
|
5114
|
+
*
|
|
5115
|
+
* The `port` lines enumerate LISTEN sockets the sandbox user's own processes
|
|
5116
|
+
* hold: one awk pass maps socket inodes from /proc/net/tcp{,6} to pids via
|
|
5117
|
+
* /proc/<pid>/fd, then a shell loop attaches each pid's cmdline. Platform
|
|
5118
|
+
* daemons run as root, so their /proc/<pid>/fd is unreadable here and they
|
|
5119
|
+
* never emit a line — the "user's servers only" filter falls out of
|
|
5120
|
+
* permissions rather than a curated list. Hex address:port is left for the
|
|
5121
|
+
* parser to decode (strtonum is gawk-only).
|
|
5114
5122
|
*/
|
|
5115
5123
|
const SANDBOX_STATS_COMMAND = [
|
|
5116
5124
|
`printf '${SANDBOX_STATS_SENTINEL}\\n'`,
|
|
@@ -5120,9 +5128,97 @@ const SANDBOX_STATS_COMMAND = [
|
|
|
5120
5128
|
`awk '/^MemTotal:/{t=$2}/^MemAvailable:/{a=$2}END{printf "mem_total_kb\\t%d\\nmem_avail_kb\\t%d\\n",t,a}' /proc/meminfo`,
|
|
5121
5129
|
`awk '/^SwapTotal:/{t=$2}/^SwapFree:/{f=$2}END{printf "swap_total_kb\\t%d\\nswap_free_kb\\t%d\\n",t,f}' /proc/meminfo`,
|
|
5122
5130
|
`df -Pk / | awk 'NR==2{printf "disk_total_kb\\t%d\\ndisk_used_kb\\t%d\\n",$2,$3}'`,
|
|
5123
|
-
`printf 'procs\\t%s\\n' "$(ls -1 /proc 2>/dev/null | grep -c '^[0-9]\\+$')"
|
|
5131
|
+
`printf 'procs\\t%s\\n' "$(ls -1 /proc 2>/dev/null | grep -c '^[0-9]\\+$')"`,
|
|
5132
|
+
`ls -l /proc/[0-9]*/fd 2>/dev/null | awk 'BEGIN { while ((getline l < "/proc/net/tcp") > 0) { split(l,f," "); if (f[4]=="0A") want[f[10]]=f[2] } close("/proc/net/tcp"); while ((getline l < "/proc/net/tcp6") > 0) { split(l,f," "); if (f[4]=="0A") want[f[10]]=f[2] } close("/proc/net/tcp6") } $0 ~ "^/proc/[0-9]+/fd:$" { pid=substr($0,7,length($0)-10) } match($0, /socket:\\[[0-9]+\\]/) { ino=substr($0,RSTART+8,RLENGTH-9); if (ino in want && !(ino in done)) { done[ino]=1; print want[ino] "\\t" pid } }' | while read addr pid; do cl=$(head -c 200 "/proc/$pid/cmdline" 2>/dev/null | tr "\\0" " "); printf 'port\\t%s\\t%s\\t%s\\n' "$addr" "$pid" "$cl"; done`
|
|
5124
5133
|
].join(" ; ");
|
|
5125
5134
|
const KB = 1024;
|
|
5135
|
+
const HIDDEN_PORTS = new Set([
|
|
5136
|
+
38994,
|
|
5137
|
+
49983,
|
|
5138
|
+
38996
|
|
5139
|
+
]);
|
|
5140
|
+
const V6_LOOPBACK_HEX = "00000000000000000000000001000000";
|
|
5141
|
+
/**
|
|
5142
|
+
* Whether a /proc/net/tcp{,6} local-address hex field is a loopback bind.
|
|
5143
|
+
* v4 words are little-endian, so 127.0.0.1 is `0100007F` — the first octet
|
|
5144
|
+
* (127) is the LAST byte pair. Covers v4-mapped v6 (`::ffff:127.x.y.z`) via
|
|
5145
|
+
* the same tail check.
|
|
5146
|
+
*/
|
|
5147
|
+
function isLoopbackHex(addrHex) {
|
|
5148
|
+
const hex = addrHex.toUpperCase();
|
|
5149
|
+
if (hex.length === 8) return hex.slice(6) === "7F";
|
|
5150
|
+
if (hex.length === 32) {
|
|
5151
|
+
if (hex === V6_LOOPBACK_HEX) return true;
|
|
5152
|
+
return hex.startsWith("0000000000000000FFFF0000") && hex.slice(30) === "7F";
|
|
5153
|
+
}
|
|
5154
|
+
return false;
|
|
5155
|
+
}
|
|
5156
|
+
const RUNTIME_NAMES = new Set([
|
|
5157
|
+
"node",
|
|
5158
|
+
"bun",
|
|
5159
|
+
"deno",
|
|
5160
|
+
"python",
|
|
5161
|
+
"python3",
|
|
5162
|
+
"sh",
|
|
5163
|
+
"bash"
|
|
5164
|
+
]);
|
|
5165
|
+
const FLAGS_WITH_VALUE = new Set([
|
|
5166
|
+
"--require",
|
|
5167
|
+
"-r",
|
|
5168
|
+
"--import",
|
|
5169
|
+
"--loader",
|
|
5170
|
+
"--experimental-loader"
|
|
5171
|
+
]);
|
|
5172
|
+
/**
|
|
5173
|
+
* A short display name from a raw cmdline: basename of argv[0], plus — when
|
|
5174
|
+
* argv[0] is a bare runtime — the basename of the first non-flag argument with
|
|
5175
|
+
* its extension dropped (`node …/vite/bin/vite.js` → `node vite`).
|
|
5176
|
+
*/
|
|
5177
|
+
function processDisplayName(cmdline) {
|
|
5178
|
+
const argv = cmdline.trim().split(/\s+/).filter(Boolean);
|
|
5179
|
+
const first = argv[0];
|
|
5180
|
+
if (first === void 0) return null;
|
|
5181
|
+
const base = (p) => p.split("/").pop() ?? p;
|
|
5182
|
+
const name = base(first);
|
|
5183
|
+
if (!RUNTIME_NAMES.has(name)) return name;
|
|
5184
|
+
let script;
|
|
5185
|
+
for (let i = 1; i < argv.length; i += 1) {
|
|
5186
|
+
const arg = argv[i];
|
|
5187
|
+
if (arg === void 0) break;
|
|
5188
|
+
if (FLAGS_WITH_VALUE.has(arg)) {
|
|
5189
|
+
i += 1;
|
|
5190
|
+
continue;
|
|
5191
|
+
}
|
|
5192
|
+
if (arg.startsWith("-")) continue;
|
|
5193
|
+
script = arg;
|
|
5194
|
+
break;
|
|
5195
|
+
}
|
|
5196
|
+
if (!script) return name;
|
|
5197
|
+
return `${name} ${base(script).replace(/\.(?:mjs|cjs|js|ts|tsx|py)$/, "")}`;
|
|
5198
|
+
}
|
|
5199
|
+
/**
|
|
5200
|
+
* Fold the collector's `port` lines (one per listen socket) into one entry
|
|
5201
|
+
* per port: v4/v6 binds of the same server dedupe, `loopbackOnly` only when
|
|
5202
|
+
* every bind is loopback, and the hidden platform ports drop out.
|
|
5203
|
+
*/
|
|
5204
|
+
function parsePortLines(lines) {
|
|
5205
|
+
const byPort = /* @__PURE__ */ new Map();
|
|
5206
|
+
for (const line of lines) {
|
|
5207
|
+
const port = Number.parseInt(line.portHex, 16);
|
|
5208
|
+
if (!Number.isFinite(port) || port <= 0 || HIDDEN_PORTS.has(port)) continue;
|
|
5209
|
+
const entry = byPort.get(port);
|
|
5210
|
+
if (entry) entry.loopback.push(isLoopbackHex(line.addrHex));
|
|
5211
|
+
else byPort.set(port, {
|
|
5212
|
+
loopback: [isLoopbackHex(line.addrHex)],
|
|
5213
|
+
cmdline: line.cmdline
|
|
5214
|
+
});
|
|
5215
|
+
}
|
|
5216
|
+
return [...byPort.entries()].map(([port, entry]) => ({
|
|
5217
|
+
port,
|
|
5218
|
+
loopbackOnly: entry.loopback.every(Boolean),
|
|
5219
|
+
process: entry.cmdline ? processDisplayName(entry.cmdline) : null
|
|
5220
|
+
})).sort((a, b) => a.port - b.port);
|
|
5221
|
+
}
|
|
5126
5222
|
/**
|
|
5127
5223
|
* Parse the collector's output into `SandboxStats`, or return null when the
|
|
5128
5224
|
* block is absent or malformed (so the caller can show the raw output as an
|
|
@@ -5134,10 +5230,22 @@ function parseSandboxStats(raw) {
|
|
|
5134
5230
|
const start = raw.indexOf(SANDBOX_STATS_SENTINEL);
|
|
5135
5231
|
if (start === -1) return null;
|
|
5136
5232
|
const fields = /* @__PURE__ */ new Map();
|
|
5233
|
+
const portLines = [];
|
|
5137
5234
|
for (const line of raw.slice(start).split("\n")) {
|
|
5138
5235
|
const tab = line.indexOf(" ");
|
|
5139
5236
|
if (tab === -1) continue;
|
|
5140
|
-
|
|
5237
|
+
const key = line.slice(0, tab).trim();
|
|
5238
|
+
if (key === "port") {
|
|
5239
|
+
const parts = line.split(" ");
|
|
5240
|
+
const [addrHex = "", portHex = ""] = (parts[1] ?? "").split(":");
|
|
5241
|
+
if (addrHex && portHex) portLines.push({
|
|
5242
|
+
addrHex,
|
|
5243
|
+
portHex,
|
|
5244
|
+
cmdline: parts.slice(3).join(" ").trim()
|
|
5245
|
+
});
|
|
5246
|
+
continue;
|
|
5247
|
+
}
|
|
5248
|
+
fields.set(key, line.slice(tab + 1).trim());
|
|
5141
5249
|
}
|
|
5142
5250
|
const num = (key) => {
|
|
5143
5251
|
const v = fields.get(key);
|
|
@@ -5169,7 +5277,8 @@ function parseSandboxStats(raw) {
|
|
|
5169
5277
|
swapFreeBytes: (num("swap_free_kb") ?? 0) * KB,
|
|
5170
5278
|
diskTotalBytes: diskTotal * KB,
|
|
5171
5279
|
diskUsedBytes: diskUsed * KB,
|
|
5172
|
-
procs: Math.round(procs)
|
|
5280
|
+
procs: Math.round(procs),
|
|
5281
|
+
ports: parsePortLines(portLines)
|
|
5173
5282
|
};
|
|
5174
5283
|
}
|
|
5175
5284
|
function severityFor(fraction) {
|
|
@@ -5262,6 +5371,22 @@ function renderBar(fraction, width) {
|
|
|
5262
5371
|
const filled = "█".repeat(Math.min(full, cells)) + partial;
|
|
5263
5372
|
return (filled + "░".repeat(Math.max(0, cells - filled.length))).slice(0, cells);
|
|
5264
5373
|
}
|
|
5374
|
+
/** How many port rows the card draws before folding the rest into `+N more`. */
|
|
5375
|
+
const MAX_PORT_ROWS = 8;
|
|
5376
|
+
const WELL_KNOWN_PORTS = new Map([[3e3, "agent harness"], [3001, "agent webserver"]]);
|
|
5377
|
+
/**
|
|
5378
|
+
* Reduce the snapshot's ports to drawable rows. The well-known note wins over
|
|
5379
|
+
* `local only` — a loopback-bound 3001 being unreachable is a distinct problem
|
|
5380
|
+
* the gauges' error path already surfaces, and one annotation per row keeps
|
|
5381
|
+
* the table scannable.
|
|
5382
|
+
*/
|
|
5383
|
+
function toPortRows(ports) {
|
|
5384
|
+
return ports.map((p) => ({
|
|
5385
|
+
port: p.port,
|
|
5386
|
+
process: p.process ?? "?",
|
|
5387
|
+
note: WELL_KNOWN_PORTS.get(p.port) ?? (p.loopbackOnly ? "local only" : null)
|
|
5388
|
+
}));
|
|
5389
|
+
}
|
|
5265
5390
|
|
|
5266
5391
|
//#endregion
|
|
5267
5392
|
//#region src/chat/tui/chunks/computer.tsx
|
|
@@ -5326,26 +5451,34 @@ function ComputerItem({ item }) {
|
|
|
5326
5451
|
children: ["couldn't read sandbox stats", error ? `: ${error}` : ""]
|
|
5327
5452
|
}) });
|
|
5328
5453
|
const gauges = toGauges(stats);
|
|
5329
|
-
const
|
|
5454
|
+
const portRows = toPortRows(stats.ports);
|
|
5455
|
+
const labelWidth = Math.max(5, ...gauges.map((g) => g.label.length));
|
|
5330
5456
|
const barWidth = 24;
|
|
5331
|
-
return /* @__PURE__ */ jsxs(Shell, { children: [
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5457
|
+
return /* @__PURE__ */ jsxs(Shell, { children: [
|
|
5458
|
+
gauges.map((g) => /* @__PURE__ */ jsx(GaugeRow, {
|
|
5459
|
+
gauge: g,
|
|
5460
|
+
labelWidth,
|
|
5461
|
+
barWidth
|
|
5462
|
+
}, g.label)),
|
|
5463
|
+
/* @__PURE__ */ jsx(PortsSection, {
|
|
5464
|
+
rows: portRows,
|
|
5465
|
+
labelWidth
|
|
5466
|
+
}),
|
|
5467
|
+
/* @__PURE__ */ jsxs("text", {
|
|
5468
|
+
fg: theme.dim,
|
|
5469
|
+
children: [
|
|
5470
|
+
`${"uptime".padEnd(labelWidth)} `,
|
|
5471
|
+
/* @__PURE__ */ jsx("span", {
|
|
5472
|
+
fg: theme.muted,
|
|
5473
|
+
children: formatUptime(stats.uptimeSeconds)
|
|
5474
|
+
}),
|
|
5475
|
+
/* @__PURE__ */ jsx("span", {
|
|
5476
|
+
fg: theme.dim,
|
|
5477
|
+
children: ` · ${stats.procs} processes`
|
|
5478
|
+
})
|
|
5479
|
+
]
|
|
5480
|
+
})
|
|
5481
|
+
] });
|
|
5349
5482
|
}
|
|
5350
5483
|
/** The card frame: a bold `computer` title over the graph rows. */
|
|
5351
5484
|
function Shell({ children }) {
|
|
@@ -5393,6 +5526,42 @@ function GaugeRow({ gauge, labelWidth, barWidth }) {
|
|
|
5393
5526
|
})
|
|
5394
5527
|
] });
|
|
5395
5528
|
}
|
|
5529
|
+
/**
|
|
5530
|
+
* The listening-ports table: one row per port the sandbox user's processes
|
|
5531
|
+
* hold, first row carrying the `ports` gutter label to line up with the
|
|
5532
|
+
* gauges. Folds past MAX_PORT_ROWS into a `+N more` line so a busy box can't
|
|
5533
|
+
* flood the transcript.
|
|
5534
|
+
*/
|
|
5535
|
+
function PortsSection({ rows, labelWidth }) {
|
|
5536
|
+
if (rows.length === 0) return null;
|
|
5537
|
+
const shown = rows.slice(0, MAX_PORT_ROWS);
|
|
5538
|
+
const folded = rows.length - shown.length;
|
|
5539
|
+
const gutter = " ".repeat(labelWidth);
|
|
5540
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [shown.map((row, i) => /* @__PURE__ */ jsxs("text", { children: [
|
|
5541
|
+
/* @__PURE__ */ jsx("span", {
|
|
5542
|
+
fg: theme.muted,
|
|
5543
|
+
children: `${i === 0 ? "ports".padEnd(labelWidth) : gutter} `
|
|
5544
|
+
}),
|
|
5545
|
+
/* @__PURE__ */ jsx("span", {
|
|
5546
|
+
fg: theme.fg,
|
|
5547
|
+
children: String(row.port).padStart(5)
|
|
5548
|
+
}),
|
|
5549
|
+
/* @__PURE__ */ jsx("span", {
|
|
5550
|
+
fg: theme.muted,
|
|
5551
|
+
children: ` ${row.process}`
|
|
5552
|
+
}),
|
|
5553
|
+
row.note ? /* @__PURE__ */ jsx("span", {
|
|
5554
|
+
fg: theme.dim,
|
|
5555
|
+
children: ` · ${row.note}`
|
|
5556
|
+
}) : null
|
|
5557
|
+
] }, row.port)), folded > 0 ? /* @__PURE__ */ jsxs("text", { children: [/* @__PURE__ */ jsx("span", {
|
|
5558
|
+
fg: theme.muted,
|
|
5559
|
+
children: `${gutter} `
|
|
5560
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
5561
|
+
fg: theme.dim,
|
|
5562
|
+
children: `+${folded} more`
|
|
5563
|
+
})] }) : null] });
|
|
5564
|
+
}
|
|
5396
5565
|
|
|
5397
5566
|
//#endregion
|
|
5398
5567
|
//#region src/chat/tui/chunks/index.tsx
|
|
@@ -20,7 +20,7 @@ import { access, appendFile, mkdir, readFile, unlink, writeFile } from "node:fs/
|
|
|
20
20
|
* the commit time of the built tree is one monotonic clock they share.
|
|
21
21
|
*/
|
|
22
22
|
function portalDaemonBuild() {
|
|
23
|
-
return "
|
|
23
|
+
return "1786727732";
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Whether a client carrying `mine` should replace a running daemon carrying
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "./client-DbqRBquD.mjs";
|
|
3
|
-
import { a as runPortalDaemon, i as queryDaemonStatus, n as ensureDaemonRunning, o as startPortalDaemon, r as isDaemonListening, s as stopDaemon, t as PortalDaemon } from "./daemon-
|
|
3
|
+
import { a as runPortalDaemon, i as queryDaemonStatus, n as ensureDaemonRunning, o as startPortalDaemon, r as isDaemonListening, s as stopDaemon, t as PortalDaemon } from "./daemon-BBeAB5SM.mjs";
|
|
4
4
|
import "./api-DG5W6iwx.mjs";
|
|
5
5
|
|
|
6
6
|
export { runPortalDaemon };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { c as LOCAL_PROTOCOL_VERSION, d as encodeLine, f as makeLineParser, n as ensureDaemonRunning, p as parseDaemonMessage, u as daemonPaths } from "./daemon-
|
|
2
|
+
import { c as LOCAL_PROTOCOL_VERSION, d as encodeLine, f as makeLineParser, n as ensureDaemonRunning, p as parseDaemonMessage, u as daemonPaths } from "./daemon-BBeAB5SM.mjs";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { connect } from "node:net";
|
|
5
5
|
|
package/package.json
CHANGED