@nordbyte/nordrelay 0.5.0 → 0.5.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.
- package/.env.example +2 -0
- package/README.md +23 -14
- package/dist/access-control.js +2 -0
- package/dist/agent-updates.js +61 -10
- package/dist/bot-ui.js +1 -0
- package/dist/bot.js +142 -1065
- package/dist/channel-actions.js +8 -8
- package/dist/codex-cli.js +1 -1
- package/dist/config-metadata.js +2 -0
- package/dist/operations.js +233 -122
- package/dist/relay-artifact-service.js +126 -0
- package/dist/relay-external-activity-monitor.js +216 -0
- package/dist/relay-queue-service.js +66 -0
- package/dist/relay-runtime-types.js +1 -0
- package/dist/relay-runtime.js +119 -371
- package/dist/state-backend.js +3 -0
- package/dist/support-bundle.js +221 -0
- package/dist/telegram-agent-commands.js +212 -0
- package/dist/telegram-artifact-commands.js +139 -0
- package/dist/telegram-command-menu.js +1 -0
- package/dist/telegram-command-types.js +1 -0
- package/dist/telegram-diagnostics-command.js +102 -0
- package/dist/telegram-general-commands.js +52 -0
- package/dist/telegram-operational-commands.js +153 -0
- package/dist/telegram-preference-commands.js +198 -0
- package/dist/telegram-queue-commands.js +278 -0
- package/dist/telegram-support-command.js +53 -0
- package/dist/telegram-update-commands.js +6 -1
- package/dist/web-api-contract.js +79 -31
- package/dist/web-api-types.js +1 -0
- package/dist/web-dashboard-access-routes.js +163 -0
- package/dist/web-dashboard-artifact-routes.js +65 -0
- package/dist/web-dashboard-assets.js +2 -0
- package/dist/web-dashboard-http.js +143 -0
- package/dist/web-dashboard-pages.js +257 -0
- package/dist/web-dashboard-runtime-routes.js +92 -0
- package/dist/web-dashboard-session-routes.js +209 -0
- package/dist/web-dashboard.js +44 -882
- package/dist/webui-assets/dashboard.css +74 -4
- package/dist/webui-assets/dashboard.js +163 -24
- package/dist/zip-writer.js +83 -0
- package/package.json +10 -4
- package/plugins/nordrelay/.codex-plugin/plugin.json +1 -1
- package/plugins/nordrelay/scripts/nordrelay.mjs +258 -5
package/.env.example
CHANGED
|
@@ -209,6 +209,8 @@ NORDRELAY_AUDIT_MAX_EVENTS=1000
|
|
|
209
209
|
NORDRELAY_SESSION_LOCK_TTL_MS=1800000
|
|
210
210
|
# NPM version cache TTL.
|
|
211
211
|
NORDRELAY_VERSION_CACHE_TTL_MS=3600000
|
|
212
|
+
# Installed agent CLI version cache TTL.
|
|
213
|
+
NORDRELAY_CLI_VERSION_CACHE_TTL_MS=60000
|
|
212
214
|
|
|
213
215
|
# Voice
|
|
214
216
|
# Optional voice transcription settings.
|
package/README.md
CHANGED
|
@@ -37,6 +37,7 @@ Session control:
|
|
|
37
37
|
- `/tasks` and `/progress` show the current turn status, queue length, active tool, elapsed time, and last error.
|
|
38
38
|
- `/activity` shows a compact timeline of recent rollout events for the active thread, with filters and export.
|
|
39
39
|
- `/diagnostics` reports redacted runtime, config, user/group authorization, Telegram rate-limit, mirror, voice, session, queue, and progress details.
|
|
40
|
+
- `/support` exports a redacted diagnostics ZIP with config, health, versions, agent paths, recent logs, audit events, update jobs, state backend, and OS/Node/npm info.
|
|
40
41
|
- `/lock`, `/unlock`, and `/locks` provide a team write-lock for shared sessions so one user can operate while others watch.
|
|
41
42
|
- `/audit` shows recent prompt, queue, lock, command, authentication, permission-denied, user, group, Telegram-link, Telegram-chat, and web-session audit events for admins.
|
|
42
43
|
|
|
@@ -182,10 +183,10 @@ Authentication and safety:
|
|
|
182
183
|
Operations:
|
|
183
184
|
|
|
184
185
|
- Plugin command/skill starts, stops, restarts, and inspects the connector process.
|
|
185
|
-
- Manual process commands support `start`, `stop`, `restart`, `status`, and `foreground`.
|
|
186
|
-
- Telegram admin commands support `/logs`, `/diagnostics`, `/restart`, and `/update` for NordRelay and agent CLIs.
|
|
187
|
-
- `/update
|
|
188
|
-
- `/update agents`, `/update <agent>`, `/update jobs`, `/update log <id>`, `/update cancel <id>`, and `/update input <id> <text>` manage Codex, Pi, Hermes, OpenClaw, and Claude Code updater jobs from Telegram.
|
|
186
|
+
- Manual process commands support `start`, `stop`, `restart`, `status`, `update`, and `foreground`.
|
|
187
|
+
- Telegram admin commands support `/logs`, `/diagnostics`, `/support`, `/restart`, and `/update` for NordRelay and agent CLIs.
|
|
188
|
+
- `nordrelay update`, `/update`, and the WebUI update button detect the install type: npm installs update with `npm install -g @nordbyte/nordrelay@latest`; source checkouts pull `origin/main`, install dependencies, run check, tests, and build, then restart if the connector is running.
|
|
189
|
+
- `/update agents`, `/update <agent>`, `/update install <agent>`, `/update jobs`, `/update log <id>`, `/update cancel <id>`, and `/update input <id> <text>` manage Codex, Pi, Hermes, OpenClaw, and Claude Code updater or installer jobs from Telegram.
|
|
189
190
|
- `/logs` renders redacted connector, NordRelay update, and agent update logs with local-time timestamps, levels, file path, last-modified time, and highlighted warnings/errors.
|
|
190
191
|
- Logs can be emitted as timestamped plain text or JSON records with `CONNECTOR_LOG_FORMAT`.
|
|
191
192
|
- Telegram sends/edits/documents are routed through a rate-limit queue that honors Telegram retry-after responses.
|
|
@@ -195,12 +196,12 @@ Operations:
|
|
|
195
196
|
- `nordrelay init` creates a private runtime config, `nordrelay doctor` validates host prerequisites, and `nordrelay web` starts the connector plus a full local WebUI dashboard.
|
|
196
197
|
- The WebUI has responsive header/sidebar/footer navigation, live chat streaming, session controls, queue/artifact/log/diagnostic views, and settings management.
|
|
197
198
|
- The WebUI supports light and dark themes, tabbed settings groups, paginated session browsing, and chat uploads for images, documents, and audio transcription.
|
|
198
|
-
- The WebUI exposes REST and SSE endpoints for chat streaming, sessions, settings, queue, artifacts, logs, health, and diagnostics.
|
|
199
|
+
- The WebUI exposes REST and SSE endpoints for chat streaming, sessions, settings, queue, artifacts, logs, health, diagnostics, and redacted diagnostics bundle export.
|
|
199
200
|
- The dashboard can bind to `127.0.0.1` or `0.0.0.0`; user login and session cookies are mandatory in both modes.
|
|
200
201
|
- Telegram can run with long polling or an HTTP webhook via `TELEGRAM_TRANSPORT=webhook`.
|
|
201
|
-
- Version freshness checks are cached with `NORDRELAY_VERSION_CACHE_TTL_MS` to keep `/version` responsive.
|
|
202
|
-
- CI
|
|
203
|
-
- `npm run dev`, `npm run build`, `npm run check`, `npm test`, `npm start`, `npm stop`, and `npm run status` are available.
|
|
202
|
+
- Version freshness checks are cached with `NORDRELAY_VERSION_CACHE_TTL_MS`, and installed agent CLI version checks are cached with `NORDRELAY_CLI_VERSION_CACHE_TTL_MS`, to keep `/version` and adapter health responsive.
|
|
203
|
+
- CI runs on Ubuntu, Windows, and macOS with typecheck, Vitest, Playwright WebUI browser tests, package dry run, npm audit, and a separate secret-scan workflow.
|
|
204
|
+
- `npm run dev`, `npm run build`, `npm run check`, `npm test`, `npm run test:e2e`, `npm start`, `npm stop`, and `npm run status` are available.
|
|
204
205
|
- Dockerfile and `docker-compose.yml` are included for containerized operation.
|
|
205
206
|
- A `launchd/start.sh` helper is included for host-managed startup.
|
|
206
207
|
|
|
@@ -355,6 +356,7 @@ nordrelay init
|
|
|
355
356
|
nordrelay doctor
|
|
356
357
|
nordrelay start
|
|
357
358
|
nordrelay status
|
|
359
|
+
nordrelay update
|
|
358
360
|
nordrelay restart
|
|
359
361
|
nordrelay stop
|
|
360
362
|
nordrelay foreground
|
|
@@ -366,6 +368,7 @@ Source checkout process commands:
|
|
|
366
368
|
```bash
|
|
367
369
|
node plugins/nordrelay/scripts/nordrelay.mjs start
|
|
368
370
|
node plugins/nordrelay/scripts/nordrelay.mjs status
|
|
371
|
+
node plugins/nordrelay/scripts/nordrelay.mjs update
|
|
369
372
|
node plugins/nordrelay/scripts/nordrelay.mjs restart
|
|
370
373
|
node plugins/nordrelay/scripts/nordrelay.mjs stop
|
|
371
374
|
node plugins/nordrelay/scripts/nordrelay.mjs foreground
|
|
@@ -424,7 +427,7 @@ The dashboard is a second NordRelay client next to Telegram. It can:
|
|
|
424
427
|
- Edit all supported runtime settings from tabbed Settings groups with option selects, validation feedback, and restart actions.
|
|
425
428
|
- View filtered connector/update/agent-update logs, structured diagnostics, enabled channels, and agent adapters.
|
|
426
429
|
- Inspect a per-agent capability matrix showing model, reasoning, launch, fast mode, attachments, activity, usage, auth, login/logout, and handback support.
|
|
427
|
-
- Check NordRelay and agent CLI versions, then start Codex, Pi, Hermes, OpenClaw, or Claude Code updates from outdated
|
|
430
|
+
- Check NordRelay and agent CLI versions, then start Codex, Pi, Hermes, OpenClaw, or Claude Code updates from outdated rows or installs from not-installed rows with live output, cancel, delete-log, and stdin response controls.
|
|
428
431
|
- Build dashboard CSS and client JavaScript from modular source assets through esbuild, then serve them as authenticated static assets instead of inline HTML.
|
|
429
432
|
|
|
430
433
|
Dashboard API endpoints are served under `/api/*`. Streaming uses `GET /api/events`.
|
|
@@ -515,10 +518,11 @@ Run NordRelay behind your reverse proxy so the public URL forwards to `http://12
|
|
|
515
518
|
- `/logs update [lines]` shows the self-update log. Requires `logs.read`.
|
|
516
519
|
- `/logs agent [lines]` shows the aggregate agent updater log. Requires `logs.read`.
|
|
517
520
|
- `/logs all [lines]` shows connector, self-update, and agent update logs together. Requires `logs.read`.
|
|
518
|
-
- `/diagnostics` shows redacted connector diagnostics. Requires `
|
|
521
|
+
- `/diagnostics` shows redacted connector diagnostics. Requires `diagnostics.read`.
|
|
522
|
+
- `/support` exports a redacted diagnostics ZIP. Requires `diagnostics.read`.
|
|
519
523
|
- `/restart` restarts the connector process. Requires `system.restart`.
|
|
520
524
|
- `/update` updates through npm or git depending on the detected install type, then restarts only on success. Requires `updates.run`.
|
|
521
|
-
- `/update agents`, `/update <agent>`, `/update jobs`, `/update log <id>`, `/update cancel <id>`, and `/update input <id> <text>` manage agent CLI update jobs. Requires `updates.run`.
|
|
525
|
+
- `/update agents`, `/update <agent>`, `/update install <agent>`, `/update jobs`, `/update log <id>`, `/update cancel <id>`, and `/update input <id> <text>` manage agent CLI update and install jobs. Requires `updates.run`.
|
|
522
526
|
|
|
523
527
|
## Command Examples
|
|
524
528
|
|
|
@@ -735,6 +739,7 @@ Agent selection:
|
|
|
735
739
|
- `NORDRELAY_AUDIT_MAX_EVENTS`: maximum audit events retained. Defaults to `1000`.
|
|
736
740
|
- `NORDRELAY_SESSION_LOCK_TTL_MS`: session write-lock TTL. Defaults to `1800000`.
|
|
737
741
|
- `NORDRELAY_VERSION_CACHE_TTL_MS`: npm version freshness cache TTL. Defaults to `3600000`; set `0` to disable.
|
|
742
|
+
- `NORDRELAY_CLI_VERSION_CACHE_TTL_MS`: installed agent CLI version cache TTL. Defaults to `60000`; set `0` to disable.
|
|
738
743
|
|
|
739
744
|
Dashboard:
|
|
740
745
|
|
|
@@ -835,8 +840,8 @@ NordRelay wrapper:
|
|
|
835
840
|
|
|
836
841
|
- `NORDRELAY_HOME`: config/state/log directory override. Defaults to `~/.nordrelay`.
|
|
837
842
|
- `NORDRELAY_SOURCE_ROOT`: runtime source root override. Useful when the plugin is launched from Codex cache.
|
|
838
|
-
- `NORDRELAY_UPDATE_METHOD`: optional `auto`, `npm`, or `git` self-update method override. Auto uses git when the runtime root has a `.git` directory and npm otherwise.
|
|
839
|
-
- Agent updates from the dashboard and Telegram use each agent's native updater where possible: `codex update`, `pi update pi`, `hermes update --yes`, `openclaw update --yes`, and `claude update`.
|
|
843
|
+
- `NORDRELAY_UPDATE_METHOD`: optional `auto`, `npm`, or `git` self-update method override used by `nordrelay update`, `/update`, and the WebUI update button. Auto uses git when the runtime root has a `.git` directory and npm otherwise.
|
|
844
|
+
- Agent updates from the dashboard and Telegram use each agent's native updater where possible: `codex update`, `pi update pi`, `hermes update --yes`, `openclaw update --yes`, and `claude update`. Not-installed agents can be installed from the dashboard or with `/update install <agent>` using npm global installs.
|
|
840
845
|
- `NORDRELAY_KEEP_PENDING_UPDATES`: set true to avoid dropping pending Telegram updates on start.
|
|
841
846
|
- `NORDRELAY_FORWARD_TOOL_OUTPUT`: backward-compatible alias that sets `TOOL_VERBOSITY=all` when `TOOL_VERBOSITY` is unset.
|
|
842
847
|
- `NORDRELAY_STATE_FILE`: internal state-file path passed by the wrapper.
|
|
@@ -1041,9 +1046,13 @@ npm run build
|
|
|
1041
1046
|
- `plugins/nordrelay/scripts/nordrelay.mjs`: process manager for `start`, `stop`, `restart`, `status`, and `foreground`.
|
|
1042
1047
|
- `src/index.ts`: runtime entrypoint, config load, auth check, state-file writes, polling lifecycle, shutdown.
|
|
1043
1048
|
- `src/bot.ts`: Telegram prompt/session runtime, streaming, file/photo/voice handling, artifacts, and error handling.
|
|
1044
|
-
- `src/telegram-access-commands.ts`, `src/telegram-update-commands.ts`, and `src/telegram-command-menu.ts`: focused Telegram command groups for access linking, update jobs, and command menu registration.
|
|
1049
|
+
- `src/telegram-general-commands.ts`, `src/telegram-agent-commands.ts`, `src/telegram-preference-commands.ts`, `src/telegram-access-commands.ts`, `src/telegram-diagnostics-command.ts`, `src/telegram-update-commands.ts`, `src/telegram-support-command.ts`, and `src/telegram-command-menu.ts`: focused Telegram command groups for start/help/adapters, agent/auth controls, per-chat preferences, access linking, diagnostics/log/version commands, update jobs, diagnostics bundle export, and command menu registration.
|
|
1045
1050
|
- `src/channel-adapter.ts`, `src/channel-runtime.ts`, and `src/channel-actions.ts`: channel descriptors, generic command routing, outbound delivery contracts, and channel-neutral command responses.
|
|
1046
1051
|
- `src/config-metadata.ts`: shared setting metadata used by the WebUI settings page and generated `.env.example`.
|
|
1052
|
+
- `src/support-bundle.ts` and `src/zip-writer.ts`: redacted diagnostics bundle creation with a dependency-free ZIP writer.
|
|
1053
|
+
- `src/relay-queue-service.ts`, `src/relay-artifact-service.ts`, and `src/relay-external-activity-monitor.ts`: Web runtime queue operations, artifact preview/export/persistence, and external CLI activity mirroring.
|
|
1054
|
+
- `src/relay-runtime-types.ts`: shared Runtime/WebUI DTO types used by runtime, API contracts, and dashboard code.
|
|
1055
|
+
- `src/web-dashboard-http.ts`, `src/web-dashboard-pages.ts`, and `src/web-dashboard-runtime-routes.ts`: dashboard HTTP helpers, HTML shell rendering, and operational runtime API routes.
|
|
1047
1056
|
- `src/webui/`: focused WebUI source assets for core runtime state/API helpers, overview rendering, live events, chat/session workflows, admin pages, and CSS sections.
|
|
1048
1057
|
- `src/bot-preferences.ts`: per-context mirror, notification, quiet-hour, and voice preference persistence.
|
|
1049
1058
|
- `src/telegram-rate-limit.ts`: centralized Telegram API send/edit/document rate limiting and retry-after tracking.
|
package/dist/access-control.js
CHANGED
|
@@ -79,6 +79,8 @@ const COMMAND_PERMISSIONS = new Map([
|
|
|
79
79
|
["voice", "inspect"],
|
|
80
80
|
["whoami", "inspect"],
|
|
81
81
|
["diagnostics", "diagnostics.read"],
|
|
82
|
+
["support", "diagnostics.read"],
|
|
83
|
+
["diagnostics_bundle", "diagnostics.read"],
|
|
82
84
|
["logs", "logs.read"],
|
|
83
85
|
["audit", "audit.read"],
|
|
84
86
|
["restart", "system.restart"],
|
package/dist/agent-updates.js
CHANGED
|
@@ -7,9 +7,16 @@ import { resolveClaudeCodeCli } from "./claude-code-cli.js";
|
|
|
7
7
|
import { resolveCodexCli } from "./codex-cli.js";
|
|
8
8
|
import { resolveHermesCli } from "./hermes-cli.js";
|
|
9
9
|
import { resolveOpenClawCli } from "./openclaw-cli.js";
|
|
10
|
-
import { getAgentUpdateLogPath, getConnectorHome } from "./operations.js";
|
|
10
|
+
import { getAgentUpdateLogPath, getConnectorHome, resolveNpmSpawnCommand } from "./operations.js";
|
|
11
11
|
import { resolvePiCli } from "./pi-cli.js";
|
|
12
12
|
import { redactText } from "./redaction.js";
|
|
13
|
+
const AGENT_INSTALL_PACKAGES = {
|
|
14
|
+
codex: "@openai/codex",
|
|
15
|
+
pi: "@earendil-works/pi-coding-agent",
|
|
16
|
+
hermes: "hermes-agent",
|
|
17
|
+
openclaw: "openclaw",
|
|
18
|
+
"claude-code": "@anthropic-ai/claude-code",
|
|
19
|
+
};
|
|
13
20
|
export class AgentUpdateManager {
|
|
14
21
|
options;
|
|
15
22
|
jobs = new Map();
|
|
@@ -58,12 +65,12 @@ export class AgentUpdateManager {
|
|
|
58
65
|
this.persistJobs();
|
|
59
66
|
return snapshot;
|
|
60
67
|
}
|
|
61
|
-
start(agentId, context = {}) {
|
|
68
|
+
start(agentId, context = {}, operation = "update") {
|
|
62
69
|
const running = [...this.jobs.values()].find((job) => job.agentId === agentId && job.status === "running");
|
|
63
70
|
if (running) {
|
|
64
|
-
throw new Error(`${agentLabel(agentId)} update is already running.`);
|
|
71
|
+
throw new Error(`${agentLabel(agentId)} update/install job is already running.`);
|
|
65
72
|
}
|
|
66
|
-
const plan = resolveAgentUpdatePlan(agentId, { ...context, env: context.env ?? this.options.env });
|
|
73
|
+
const plan = resolveAgentUpdatePlan(agentId, { ...context, env: context.env ?? this.options.env }, operation);
|
|
67
74
|
const now = new Date().toISOString();
|
|
68
75
|
const id = `${agentId.replace(/[^a-z0-9]/gi, "")}-${Date.now().toString(36)}`;
|
|
69
76
|
const logPath = path.join(this.home, "updates", `${id}.log`);
|
|
@@ -72,6 +79,7 @@ export class AgentUpdateManager {
|
|
|
72
79
|
id,
|
|
73
80
|
agentId,
|
|
74
81
|
agentLabel: plan.agentLabel,
|
|
82
|
+
operation,
|
|
75
83
|
status: "running",
|
|
76
84
|
method: plan.method,
|
|
77
85
|
command: plan.command,
|
|
@@ -91,16 +99,17 @@ export class AgentUpdateManager {
|
|
|
91
99
|
this.jobs.set(id, job);
|
|
92
100
|
this.persistJobs();
|
|
93
101
|
this.append(job, [
|
|
94
|
-
`[${now}] Starting ${job.agentLabel}
|
|
102
|
+
`[${now}] Starting ${job.agentLabel} ${job.operation}`,
|
|
95
103
|
`Method: ${job.method}`,
|
|
96
104
|
`Command: ${[job.command, ...job.args].join(" ")}`,
|
|
97
105
|
`Working directory: ${job.cwd}`,
|
|
98
106
|
"",
|
|
99
107
|
].join("\n"));
|
|
100
|
-
const
|
|
108
|
+
const useShell = process.platform === "win32";
|
|
109
|
+
const child = spawn(useShell ? formatShellCommand(plan.command, plan.args) : plan.command, useShell ? [] : plan.args, {
|
|
101
110
|
cwd: plan.cwd,
|
|
102
111
|
env: { ...process.env, ...(this.options.env ?? {}), ...(context.env ?? {}) },
|
|
103
|
-
shell:
|
|
112
|
+
shell: useShell,
|
|
104
113
|
windowsHide: true,
|
|
105
114
|
stdio: "pipe",
|
|
106
115
|
});
|
|
@@ -115,7 +124,7 @@ export class AgentUpdateManager {
|
|
|
115
124
|
if (job.status !== "running") {
|
|
116
125
|
return;
|
|
117
126
|
}
|
|
118
|
-
this.finish(job, code === 0 ? "completed" : "failed", code, signal, code === 0 ? undefined :
|
|
127
|
+
this.finish(job, code === 0 ? "completed" : "failed", code, signal, code === 0 ? undefined : `${capitalize(job.operation)} exited with code ${code ?? "unknown"}`);
|
|
119
128
|
});
|
|
120
129
|
this.emit(job);
|
|
121
130
|
return this.snapshot(job);
|
|
@@ -178,7 +187,7 @@ export class AgentUpdateManager {
|
|
|
178
187
|
job.finishedAt = new Date().toISOString();
|
|
179
188
|
job.updatedAt = job.finishedAt;
|
|
180
189
|
job.child = undefined;
|
|
181
|
-
this.append(job, `\n[${job.finishedAt}] ${job.agentLabel}
|
|
190
|
+
this.append(job, `\n[${job.finishedAt}] ${job.agentLabel} ${job.operation} ${status}${error ? `: ${job.error}` : ""}\n`);
|
|
182
191
|
}
|
|
183
192
|
emit(job) {
|
|
184
193
|
this.options.onUpdate?.(this.snapshot(job));
|
|
@@ -205,6 +214,7 @@ export class AgentUpdateManager {
|
|
|
205
214
|
}
|
|
206
215
|
const job = {
|
|
207
216
|
...snapshot,
|
|
217
|
+
operation: snapshot.operation ?? "update",
|
|
208
218
|
status: staleRunning ? "failed" : snapshot.status,
|
|
209
219
|
canInput: false,
|
|
210
220
|
needsInput: false,
|
|
@@ -254,7 +264,10 @@ function isProcessRunning(pid) {
|
|
|
254
264
|
return false;
|
|
255
265
|
}
|
|
256
266
|
}
|
|
257
|
-
export function resolveAgentUpdatePlan(agentId, context = {}) {
|
|
267
|
+
export function resolveAgentUpdatePlan(agentId, context = {}, operation = "update") {
|
|
268
|
+
if (operation === "install") {
|
|
269
|
+
return resolveAgentInstallPlan(agentId, context);
|
|
270
|
+
}
|
|
258
271
|
const env = context.env ?? process.env;
|
|
259
272
|
switch (agentId) {
|
|
260
273
|
case "codex": {
|
|
@@ -294,10 +307,30 @@ export function resolveAgentUpdatePlan(agentId, context = {}) {
|
|
|
294
307
|
}
|
|
295
308
|
}
|
|
296
309
|
}
|
|
310
|
+
function resolveAgentInstallPlan(agentId, context = {}) {
|
|
311
|
+
const env = context.env ?? process.env;
|
|
312
|
+
const npm = resolveNpmSpawnCommand(env);
|
|
313
|
+
if (!npm) {
|
|
314
|
+
throw new Error(`Cannot install ${agentLabel(agentId)} because npm was not found on PATH.`);
|
|
315
|
+
}
|
|
316
|
+
const packageName = AGENT_INSTALL_PACKAGES[agentId];
|
|
317
|
+
return {
|
|
318
|
+
agentId,
|
|
319
|
+
agentLabel: agentLabel(agentId),
|
|
320
|
+
operation: "install",
|
|
321
|
+
method: `npm install -g ${packageName}@latest`,
|
|
322
|
+
command: npm.command,
|
|
323
|
+
args: [...npm.argsPrefix, "install", "-g", `${packageName}@latest`],
|
|
324
|
+
cwd: env.HOME || os.homedir(),
|
|
325
|
+
summary: `Installs the latest ${agentLabel(agentId)} CLI with npm. Restart NordRelay after installation if the agent was previously unavailable.`,
|
|
326
|
+
interactive: true,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
297
329
|
function plan(agentId, method, command, args, summary, env) {
|
|
298
330
|
return {
|
|
299
331
|
agentId,
|
|
300
332
|
agentLabel: agentLabel(agentId),
|
|
333
|
+
operation: "update",
|
|
301
334
|
method,
|
|
302
335
|
command,
|
|
303
336
|
args,
|
|
@@ -310,3 +343,21 @@ function looksLikePrompt(text) {
|
|
|
310
343
|
const tail = text.split(/\r?\n/).slice(-4).join("\n");
|
|
311
344
|
return /\b(y\/n|yes\/no|continue|proceed|confirm|password|passphrase|token|api key|enter|select)\b|[?>]\s*$/i.test(tail);
|
|
312
345
|
}
|
|
346
|
+
function formatShellCommand(command, args) {
|
|
347
|
+
return [command, ...args].map(quoteWindowsCmdArg).join(" ");
|
|
348
|
+
}
|
|
349
|
+
function quoteWindowsCmdArg(value) {
|
|
350
|
+
if (value.length === 0) {
|
|
351
|
+
return "\"\"";
|
|
352
|
+
}
|
|
353
|
+
if (!/[\s"&|<>()^%]/.test(value)) {
|
|
354
|
+
return value;
|
|
355
|
+
}
|
|
356
|
+
return `"${value
|
|
357
|
+
.replace(/%/g, "%%")
|
|
358
|
+
.replace(/(\\*)"/g, '$1$1\\"')
|
|
359
|
+
.replace(/(\\+)$/g, "$1$1")}"`;
|
|
360
|
+
}
|
|
361
|
+
function capitalize(value) {
|
|
362
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
363
|
+
}
|
package/dist/bot-ui.js
CHANGED
|
@@ -67,6 +67,7 @@ export function renderHelpMessage() {
|
|
|
67
67
|
commands: [
|
|
68
68
|
["/logs", "Show connector log tail"],
|
|
69
69
|
["/diagnostics", "Connector diagnostics"],
|
|
70
|
+
["/support", "Export diagnostics bundle"],
|
|
70
71
|
["/lock", "Lock session writes to you"],
|
|
71
72
|
["/unlock", "Release session write lock"],
|
|
72
73
|
["/locks", "List active write locks"],
|