@poolzin/pool-bot 2026.2.23 → 2026.2.25
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/CHANGELOG.md +29 -0
- package/dist/acp/client.js +207 -18
- package/dist/acp/secret-file.js +22 -0
- package/dist/agents/agent-scope.js +10 -0
- package/dist/agents/bash-process-registry.test-helpers.js +29 -0
- package/dist/agents/bash-tools.exec-approval-request.js +20 -0
- package/dist/agents/bash-tools.exec-host-gateway.js +230 -0
- package/dist/agents/bash-tools.exec-host-node.js +235 -0
- package/dist/agents/bash-tools.exec-types.js +1 -0
- package/dist/agents/bash-tools.process.js +224 -218
- package/dist/agents/content-blocks.js +16 -0
- package/dist/agents/model-fallback.js +96 -101
- package/dist/agents/models-config.providers.js +299 -182
- package/dist/agents/pi-embedded-payloads.js +1 -0
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.fixture.js +34 -0
- package/dist/agents/skills.test-helpers.js +13 -0
- package/dist/agents/stable-stringify.js +12 -0
- package/dist/agents/subagent-registry.mocks.shared.js +12 -0
- package/dist/agents/test-helpers/assistant-message-fixtures.js +29 -0
- package/dist/agents/test-helpers/pi-tools-sandbox-context.js +27 -0
- package/dist/agents/tool-policy-shared.js +108 -0
- package/dist/agents/tools/browser-tool.js +160 -54
- package/dist/agents/tools/cron-tool.test-helpers.js +12 -0
- package/dist/agents/tools/discord-actions-moderation-shared.js +27 -0
- package/dist/agents/tools/image-tool.js +214 -99
- package/dist/agents/tools/sessions-history-tool.js +140 -108
- package/dist/agents/workspace.js +222 -46
- package/dist/auto-reply/commands-registry.js +15 -18
- package/dist/auto-reply/fallback-state.js +114 -0
- package/dist/auto-reply/model-runtime.js +68 -0
- package/dist/auto-reply/reply/agent-runner-execution.js +36 -4
- package/dist/auto-reply/reply/agent-runner.js +165 -39
- package/dist/auto-reply/reply/commands-setunset-standard.js +13 -0
- package/dist/browser/config.js +26 -0
- package/dist/browser/navigation-guard.js +31 -0
- package/dist/browser/routes/agent.act.js +431 -424
- package/dist/browser/routes/agent.shared.js +47 -3
- package/dist/browser/routes/agent.snapshot.js +122 -116
- package/dist/browser/routes/agent.storage.js +303 -297
- package/dist/browser/routes/tabs.js +154 -100
- package/dist/browser/server-lifecycle.js +37 -0
- package/dist/build-info.json +3 -3
- package/dist/channels/allow-from.js +25 -0
- package/dist/channels/plugins/account-action-gate.js +13 -0
- package/dist/channels/plugins/message-actions.js +10 -0
- package/dist/channels/telegram/api.js +18 -0
- package/dist/cli/argv.js +84 -21
- package/dist/cli/banner.js +2 -1
- package/dist/cli/exec-approvals-cli.js +92 -124
- package/dist/cli/memory-cli.js +158 -61
- package/dist/cli/nodes-cli/register.push.js +63 -0
- package/dist/cli/nodes-media-utils.js +21 -0
- package/dist/cli/plugins-cli.js +245 -61
- package/dist/cli/program/build-program.js +3 -1
- package/dist/cli/program/command-registry.js +223 -136
- package/dist/cli/program/help.js +43 -12
- package/dist/cli/route.js +1 -1
- package/dist/cli/test-runtime-capture.js +24 -0
- package/dist/commands/agent.js +163 -87
- package/dist/commands/channels.mock-harness.js +23 -0
- package/dist/commands/daemon-install-runtime-warning.js +11 -0
- package/dist/commands/onboard-helpers.js +4 -4
- package/dist/commands/sessions.test-helpers.js +61 -0
- package/dist/compat/legacy-names.js +2 -2
- package/dist/config/commands.js +3 -0
- package/dist/config/config.js +1 -1
- package/dist/config/env-substitution.js +62 -34
- package/dist/config/env-vars.js +9 -0
- package/dist/config/io.js +571 -171
- package/dist/config/merge-patch.js +50 -4
- package/dist/config/redact-snapshot.js +404 -76
- package/dist/config/schema.js +58 -570
- package/dist/config/validation.js +140 -85
- package/dist/config/zod-schema.hooks.js +40 -11
- package/dist/config/zod-schema.installs.js +20 -0
- package/dist/config/zod-schema.js +8 -7
- package/dist/control-ui/assets/{index-HRr1grwl.js → index-Dvkl4Xlx.js} +2 -1
- package/dist/control-ui/assets/{index-HRr1grwl.js.map → index-Dvkl4Xlx.js.map} +1 -1
- package/dist/control-ui/index.html +1 -1
- package/dist/daemon/cmd-argv.js +21 -0
- package/dist/daemon/cmd-set.js +58 -0
- package/dist/daemon/service-types.js +1 -0
- package/dist/discord/monitor/exec-approvals.js +357 -162
- package/dist/gateway/auth.js +38 -3
- package/dist/gateway/call.js +149 -68
- package/dist/gateway/canvas-capability.js +75 -0
- package/dist/gateway/control-plane-audit.js +28 -0
- package/dist/gateway/control-plane-rate-limit.js +53 -0
- package/dist/gateway/events.js +1 -0
- package/dist/gateway/hooks.js +109 -54
- package/dist/gateway/http-common.js +22 -0
- package/dist/gateway/method-scopes.js +169 -0
- package/dist/gateway/net.js +23 -0
- package/dist/gateway/openresponses-http.js +120 -110
- package/dist/gateway/probe-auth.js +2 -0
- package/dist/gateway/protocol/index.js +3 -2
- package/dist/gateway/protocol/schema/protocol-schemas.js +2 -0
- package/dist/gateway/protocol/schema/push.js +18 -0
- package/dist/gateway/protocol/schema.js +1 -0
- package/dist/gateway/server-http.js +236 -52
- package/dist/gateway/server-methods/agent.js +162 -24
- package/dist/gateway/server-methods/chat.js +461 -130
- package/dist/gateway/server-methods/config.js +193 -150
- package/dist/gateway/server-methods/nodes.helpers.js +12 -0
- package/dist/gateway/server-methods/nodes.js +251 -69
- package/dist/gateway/server-methods/push.js +53 -0
- package/dist/gateway/server-reload-handlers.js +2 -3
- package/dist/gateway/server-runtime-config.js +5 -0
- package/dist/gateway/server-runtime-state.js +2 -0
- package/dist/gateway/server-ws-runtime.js +1 -0
- package/dist/gateway/server.impl.js +296 -139
- package/dist/gateway/session-preview.test-helpers.js +11 -0
- package/dist/gateway/startup-auth.js +126 -0
- package/dist/gateway/test-helpers.agent-results.js +15 -0
- package/dist/gateway/test-helpers.mocks.js +37 -14
- package/dist/gateway/test-helpers.server.js +161 -77
- package/dist/hooks/bundled/session-memory/handler.js +165 -34
- package/dist/hooks/gmail-watcher-lifecycle.js +23 -0
- package/dist/infra/archive-path.js +49 -0
- package/dist/infra/device-pairing.js +148 -167
- package/dist/infra/exec-approvals-allowlist.js +19 -70
- package/dist/infra/exec-approvals-analysis.js +44 -17
- package/dist/infra/exec-safe-bin-policy.js +269 -0
- package/dist/infra/fixed-window-rate-limit.js +33 -0
- package/dist/infra/git-root.js +61 -0
- package/dist/infra/heartbeat-active-hours.js +2 -2
- package/dist/infra/heartbeat-reason.js +40 -0
- package/dist/infra/heartbeat-runner.js +72 -32
- package/dist/infra/install-source-utils.js +91 -7
- package/dist/infra/node-pairing.js +50 -105
- package/dist/infra/npm-integrity.js +45 -0
- package/dist/infra/npm-pack-install.js +40 -0
- package/dist/infra/outbound/channel-adapters.js +20 -7
- package/dist/infra/outbound/message-action-runner.js +107 -327
- package/dist/infra/outbound/message.js +59 -36
- package/dist/infra/outbound/outbound-policy.js +52 -25
- package/dist/infra/outbound/outbound-send-service.js +58 -71
- package/dist/infra/pairing-files.js +10 -0
- package/dist/infra/plain-object.js +9 -0
- package/dist/infra/push-apns.js +365 -0
- package/dist/infra/restart-sentinel.js +16 -1
- package/dist/infra/restart.js +229 -26
- package/dist/infra/scp-host.js +54 -0
- package/dist/infra/update-startup.js +86 -9
- package/dist/media/inbound-path-policy.js +114 -0
- package/dist/media/input-files.js +16 -0
- package/dist/memory/test-manager.js +8 -0
- package/dist/plugin-sdk/temp-path.js +47 -0
- package/dist/plugins/discovery.js +217 -23
- package/dist/plugins/hook-runner-global.js +16 -0
- package/dist/plugins/loader.js +192 -26
- package/dist/plugins/logger.js +8 -0
- package/dist/plugins/manifest-registry.js +3 -0
- package/dist/plugins/path-safety.js +34 -0
- package/dist/plugins/registry.js +5 -2
- package/dist/plugins/runtime/index.js +271 -206
- package/dist/providers/github-copilot-models.js +4 -1
- package/dist/security/audit-channel.js +8 -19
- package/dist/security/audit-extra.async.js +354 -182
- package/dist/security/audit-extra.js +11 -1
- package/dist/security/audit-extra.sync.js +340 -33
- package/dist/security/audit-fs.js +31 -13
- package/dist/security/audit.js +145 -371
- package/dist/security/dm-policy-shared.js +24 -0
- package/dist/security/external-content.js +20 -8
- package/dist/security/fix.js +49 -85
- package/dist/security/scan-paths.js +20 -0
- package/dist/security/secret-equal.js +3 -7
- package/dist/security/windows-acl.js +30 -15
- package/dist/shared/node-list-parse.js +13 -0
- package/dist/shared/operator-scope-compat.js +37 -0
- package/dist/shared/text-chunking.js +29 -0
- package/dist/slack/blocks.test-helpers.js +31 -0
- package/dist/slack/monitor/mrkdwn.js +8 -0
- package/dist/telegram/bot-message-dispatch.js +366 -164
- package/dist/telegram/draft-stream.js +30 -7
- package/dist/telegram/reasoning-lane-coordinator.js +128 -0
- package/dist/terminal/prompt-select-styled.js +9 -0
- package/dist/test-utils/command-runner.js +6 -0
- package/dist/test-utils/internal-hook-event-payload.js +10 -0
- package/dist/test-utils/model-auth-mock.js +12 -0
- package/dist/test-utils/provider-usage-fetch.js +14 -0
- package/dist/test-utils/temp-home.js +33 -0
- package/dist/tui/components/chat-log.js +9 -0
- package/dist/tui/tui-command-handlers.js +36 -27
- package/dist/tui/tui-event-handlers.js +122 -32
- package/dist/tui/tui.js +181 -45
- package/dist/utils/mask-api-key.js +10 -0
- package/dist/utils/run-with-concurrency.js +39 -0
- package/dist/web/media.js +4 -0
- package/docs/tools/slash-commands.md +5 -1
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- package/extensions/feishu/src/external-keys.ts +19 -0
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/lobster/src/windows-spawn.ts +193 -0
- package/extensions/matrix/CHANGELOG.md +5 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/matrix/src/matrix/actions/limits.ts +6 -0
- package/extensions/mattermost/package.json +1 -1
- package/extensions/mattermost/src/mattermost/reactions.test-helpers.ts +83 -0
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +5 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +5 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai-codex-auth/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +5 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +5 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +5 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +5 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
package/dist/cli/plugins-cli.js
CHANGED
|
@@ -1,17 +1,48 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { loadConfig, writeConfigFile } from "../config/config.js";
|
|
5
|
+
import { resolveStateDir } from "../config/paths.js";
|
|
4
6
|
import { resolveArchiveKind } from "../infra/archive.js";
|
|
5
7
|
import { installPluginFromNpmSpec, installPluginFromPath } from "../plugins/install.js";
|
|
6
8
|
import { recordPluginInstall } from "../plugins/installs.js";
|
|
9
|
+
import { clearPluginManifestRegistryCache } from "../plugins/manifest-registry.js";
|
|
7
10
|
import { applyExclusiveSlotSelection } from "../plugins/slots.js";
|
|
11
|
+
import { resolvePluginSourceRoots, formatPluginSourceForTable } from "../plugins/source-display.js";
|
|
8
12
|
import { buildPluginStatusReport } from "../plugins/status.js";
|
|
13
|
+
import { resolveUninstallDirectoryTarget, uninstallPlugin } from "../plugins/uninstall.js";
|
|
9
14
|
import { updateNpmInstalledPlugins } from "../plugins/update.js";
|
|
10
15
|
import { defaultRuntime } from "../runtime.js";
|
|
11
16
|
import { formatDocsLink } from "../terminal/links.js";
|
|
12
17
|
import { renderTable } from "../terminal/table.js";
|
|
13
18
|
import { theme } from "../terminal/theme.js";
|
|
14
19
|
import { resolveUserPath, shortenHomeInString, shortenHomePath } from "../utils.js";
|
|
20
|
+
import { promptYesNo } from "./prompt.js";
|
|
21
|
+
function resolveFileNpmSpecToLocalPath(raw) {
|
|
22
|
+
const trimmed = raw.trim();
|
|
23
|
+
if (!trimmed.toLowerCase().startsWith("file:")) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const rest = trimmed.slice("file:".length);
|
|
27
|
+
if (!rest) {
|
|
28
|
+
return { ok: false, error: "unsupported file: spec: missing path" };
|
|
29
|
+
}
|
|
30
|
+
if (rest.startsWith("///")) {
|
|
31
|
+
// file:///abs/path -> /abs/path
|
|
32
|
+
return { ok: true, path: rest.slice(2) };
|
|
33
|
+
}
|
|
34
|
+
if (rest.startsWith("//localhost/")) {
|
|
35
|
+
// file://localhost/abs/path -> /abs/path
|
|
36
|
+
return { ok: true, path: rest.slice("//localhost".length) };
|
|
37
|
+
}
|
|
38
|
+
if (rest.startsWith("//")) {
|
|
39
|
+
return {
|
|
40
|
+
ok: false,
|
|
41
|
+
error: 'unsupported file: URL host (expected "file:<path>" or "file:///abs/path")',
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return { ok: true, path: rest };
|
|
45
|
+
}
|
|
15
46
|
function formatPluginLine(plugin, verbose = false) {
|
|
16
47
|
const status = plugin.status === "loaded"
|
|
17
48
|
? theme.success("loaded")
|
|
@@ -33,13 +64,15 @@ function formatPluginLine(plugin, verbose = false) {
|
|
|
33
64
|
` source: ${theme.muted(shortenHomeInString(plugin.source))}`,
|
|
34
65
|
` origin: ${plugin.origin}`,
|
|
35
66
|
];
|
|
36
|
-
if (plugin.version)
|
|
67
|
+
if (plugin.version) {
|
|
37
68
|
parts.push(` version: ${plugin.version}`);
|
|
69
|
+
}
|
|
38
70
|
if (plugin.providerIds.length > 0) {
|
|
39
71
|
parts.push(` providers: ${plugin.providerIds.join(", ")}`);
|
|
40
72
|
}
|
|
41
|
-
if (plugin.error)
|
|
73
|
+
if (plugin.error) {
|
|
42
74
|
parts.push(theme.error(` error: ${plugin.error}`));
|
|
75
|
+
}
|
|
43
76
|
return parts.join("\n");
|
|
44
77
|
}
|
|
45
78
|
function applySlotSelectionForPlugin(config, pluginId) {
|
|
@@ -56,9 +89,31 @@ function applySlotSelectionForPlugin(config, pluginId) {
|
|
|
56
89
|
});
|
|
57
90
|
return { config: result.config, warnings: result.warnings };
|
|
58
91
|
}
|
|
92
|
+
function createPluginInstallLogger() {
|
|
93
|
+
return {
|
|
94
|
+
info: (msg) => defaultRuntime.log(msg),
|
|
95
|
+
warn: (msg) => defaultRuntime.log(theme.warn(msg)),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function enablePluginInConfig(config, pluginId) {
|
|
99
|
+
return {
|
|
100
|
+
...config,
|
|
101
|
+
plugins: {
|
|
102
|
+
...config.plugins,
|
|
103
|
+
entries: {
|
|
104
|
+
...config.plugins?.entries,
|
|
105
|
+
[pluginId]: {
|
|
106
|
+
...config.plugins?.entries?.[pluginId],
|
|
107
|
+
enabled: true,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
59
113
|
function logSlotWarnings(warnings) {
|
|
60
|
-
if (warnings.length === 0)
|
|
114
|
+
if (warnings.length === 0) {
|
|
61
115
|
return;
|
|
116
|
+
}
|
|
62
117
|
for (const warning of warnings) {
|
|
63
118
|
defaultRuntime.log(theme.warn(warning));
|
|
64
119
|
}
|
|
@@ -66,8 +121,8 @@ function logSlotWarnings(warnings) {
|
|
|
66
121
|
export function registerPluginsCli(program) {
|
|
67
122
|
const plugins = program
|
|
68
123
|
.command("plugins")
|
|
69
|
-
.description("Manage
|
|
70
|
-
.addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/plugins", "docs.
|
|
124
|
+
.description("Manage Pool Bot plugins and extensions")
|
|
125
|
+
.addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/plugins", "docs.poolbot.ai/cli/plugins")}\n`);
|
|
71
126
|
plugins
|
|
72
127
|
.command("list")
|
|
73
128
|
.description("List discovered plugins")
|
|
@@ -96,9 +151,17 @@ export function registerPluginsCli(program) {
|
|
|
96
151
|
defaultRuntime.log(`${theme.heading("Plugins")} ${theme.muted(`(${loaded}/${list.length} loaded)`)}`);
|
|
97
152
|
if (!opts.verbose) {
|
|
98
153
|
const tableWidth = Math.max(60, (process.stdout.columns ?? 120) - 1);
|
|
154
|
+
const sourceRoots = resolvePluginSourceRoots({
|
|
155
|
+
workspaceDir: report.workspaceDir,
|
|
156
|
+
});
|
|
157
|
+
const usedRoots = new Set();
|
|
99
158
|
const rows = list.map((plugin) => {
|
|
100
159
|
const desc = plugin.description ? theme.muted(plugin.description) : "";
|
|
101
|
-
const
|
|
160
|
+
const formattedSource = formatPluginSourceForTable(plugin, sourceRoots);
|
|
161
|
+
if (formattedSource.rootKey) {
|
|
162
|
+
usedRoots.add(formattedSource.rootKey);
|
|
163
|
+
}
|
|
164
|
+
const sourceLine = desc ? `${formattedSource.value}\n${desc}` : formattedSource.value;
|
|
102
165
|
return {
|
|
103
166
|
Name: plugin.name || plugin.id,
|
|
104
167
|
ID: plugin.name && plugin.name !== plugin.id ? plugin.id : "",
|
|
@@ -111,6 +174,20 @@ export function registerPluginsCli(program) {
|
|
|
111
174
|
Version: plugin.version ?? "",
|
|
112
175
|
};
|
|
113
176
|
});
|
|
177
|
+
if (usedRoots.size > 0) {
|
|
178
|
+
defaultRuntime.log(theme.muted("Source roots:"));
|
|
179
|
+
for (const key of ["stock", "workspace", "global"]) {
|
|
180
|
+
if (!usedRoots.has(key)) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const dir = sourceRoots[key];
|
|
184
|
+
if (!dir) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
defaultRuntime.log(` ${theme.command(`${key}:`)} ${theme.muted(dir)}`);
|
|
188
|
+
}
|
|
189
|
+
defaultRuntime.log("");
|
|
190
|
+
}
|
|
114
191
|
defaultRuntime.log(renderTable({
|
|
115
192
|
width: tableWidth,
|
|
116
193
|
columns: [
|
|
@@ -154,14 +231,16 @@ export function registerPluginsCli(program) {
|
|
|
154
231
|
if (plugin.name && plugin.name !== plugin.id) {
|
|
155
232
|
lines.push(theme.muted(`id: ${plugin.id}`));
|
|
156
233
|
}
|
|
157
|
-
if (plugin.description)
|
|
234
|
+
if (plugin.description) {
|
|
158
235
|
lines.push(plugin.description);
|
|
236
|
+
}
|
|
159
237
|
lines.push("");
|
|
160
238
|
lines.push(`${theme.muted("Status:")} ${plugin.status}`);
|
|
161
239
|
lines.push(`${theme.muted("Source:")} ${shortenHomeInString(plugin.source)}`);
|
|
162
240
|
lines.push(`${theme.muted("Origin:")} ${plugin.origin}`);
|
|
163
|
-
if (plugin.version)
|
|
241
|
+
if (plugin.version) {
|
|
164
242
|
lines.push(`${theme.muted("Version:")} ${plugin.version}`);
|
|
243
|
+
}
|
|
165
244
|
if (plugin.toolNames.length > 0) {
|
|
166
245
|
lines.push(`${theme.muted("Tools:")} ${plugin.toolNames.join(", ")}`);
|
|
167
246
|
}
|
|
@@ -180,21 +259,27 @@ export function registerPluginsCli(program) {
|
|
|
180
259
|
if (plugin.services.length > 0) {
|
|
181
260
|
lines.push(`${theme.muted("Services:")} ${plugin.services.join(", ")}`);
|
|
182
261
|
}
|
|
183
|
-
if (plugin.error)
|
|
262
|
+
if (plugin.error) {
|
|
184
263
|
lines.push(`${theme.error("Error:")} ${plugin.error}`);
|
|
264
|
+
}
|
|
185
265
|
if (install) {
|
|
186
266
|
lines.push("");
|
|
187
267
|
lines.push(`${theme.muted("Install:")} ${install.source}`);
|
|
188
|
-
if (install.spec)
|
|
268
|
+
if (install.spec) {
|
|
189
269
|
lines.push(`${theme.muted("Spec:")} ${install.spec}`);
|
|
190
|
-
|
|
270
|
+
}
|
|
271
|
+
if (install.sourcePath) {
|
|
191
272
|
lines.push(`${theme.muted("Source path:")} ${shortenHomePath(install.sourcePath)}`);
|
|
192
|
-
|
|
273
|
+
}
|
|
274
|
+
if (install.installPath) {
|
|
193
275
|
lines.push(`${theme.muted("Install path:")} ${shortenHomePath(install.installPath)}`);
|
|
194
|
-
|
|
276
|
+
}
|
|
277
|
+
if (install.version) {
|
|
195
278
|
lines.push(`${theme.muted("Recorded version:")} ${install.version}`);
|
|
196
|
-
|
|
279
|
+
}
|
|
280
|
+
if (install.installedAt) {
|
|
197
281
|
lines.push(`${theme.muted("Installed at:")} ${install.installedAt}`);
|
|
282
|
+
}
|
|
198
283
|
}
|
|
199
284
|
defaultRuntime.log(lines.join("\n"));
|
|
200
285
|
});
|
|
@@ -245,13 +330,133 @@ export function registerPluginsCli(program) {
|
|
|
245
330
|
await writeConfigFile(next);
|
|
246
331
|
defaultRuntime.log(`Disabled plugin "${id}". Restart the gateway to apply.`);
|
|
247
332
|
});
|
|
333
|
+
plugins
|
|
334
|
+
.command("uninstall")
|
|
335
|
+
.description("Uninstall a plugin")
|
|
336
|
+
.argument("<id>", "Plugin id")
|
|
337
|
+
.option("--keep-files", "Keep installed files on disk", false)
|
|
338
|
+
.option("--keep-config", "Deprecated alias for --keep-files", false)
|
|
339
|
+
.option("--force", "Skip confirmation prompt", false)
|
|
340
|
+
.option("--dry-run", "Show what would be removed without making changes", false)
|
|
341
|
+
.action(async (id, opts) => {
|
|
342
|
+
const cfg = loadConfig();
|
|
343
|
+
const report = buildPluginStatusReport({ config: cfg });
|
|
344
|
+
const extensionsDir = path.join(resolveStateDir(process.env, os.homedir), "extensions");
|
|
345
|
+
const keepFiles = Boolean(opts.keepFiles || opts.keepConfig);
|
|
346
|
+
if (opts.keepConfig) {
|
|
347
|
+
defaultRuntime.log(theme.warn("`--keep-config` is deprecated, use `--keep-files`."));
|
|
348
|
+
}
|
|
349
|
+
// Find plugin by id or name
|
|
350
|
+
const plugin = report.plugins.find((p) => p.id === id || p.name === id);
|
|
351
|
+
const pluginId = plugin?.id ?? id;
|
|
352
|
+
// Check if plugin exists in config
|
|
353
|
+
const hasEntry = pluginId in (cfg.plugins?.entries ?? {});
|
|
354
|
+
const hasInstall = pluginId in (cfg.plugins?.installs ?? {});
|
|
355
|
+
if (!hasEntry && !hasInstall) {
|
|
356
|
+
if (plugin) {
|
|
357
|
+
defaultRuntime.error(`Plugin "${pluginId}" is not managed by plugins config/install records and cannot be uninstalled.`);
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
defaultRuntime.error(`Plugin not found: ${id}`);
|
|
361
|
+
}
|
|
362
|
+
process.exit(1);
|
|
363
|
+
}
|
|
364
|
+
const install = cfg.plugins?.installs?.[pluginId];
|
|
365
|
+
const isLinked = install?.source === "path";
|
|
366
|
+
// Build preview of what will be removed
|
|
367
|
+
const preview = [];
|
|
368
|
+
if (hasEntry) {
|
|
369
|
+
preview.push("config entry");
|
|
370
|
+
}
|
|
371
|
+
if (hasInstall) {
|
|
372
|
+
preview.push("install record");
|
|
373
|
+
}
|
|
374
|
+
if (cfg.plugins?.allow?.includes(pluginId)) {
|
|
375
|
+
preview.push("allowlist entry");
|
|
376
|
+
}
|
|
377
|
+
if (isLinked &&
|
|
378
|
+
install?.sourcePath &&
|
|
379
|
+
cfg.plugins?.load?.paths?.includes(install.sourcePath)) {
|
|
380
|
+
preview.push("load path");
|
|
381
|
+
}
|
|
382
|
+
if (cfg.plugins?.slots?.memory === pluginId) {
|
|
383
|
+
preview.push(`memory slot (will reset to "memory-core")`);
|
|
384
|
+
}
|
|
385
|
+
const deleteTarget = !keepFiles
|
|
386
|
+
? resolveUninstallDirectoryTarget({
|
|
387
|
+
pluginId,
|
|
388
|
+
hasInstall,
|
|
389
|
+
installRecord: install,
|
|
390
|
+
extensionsDir,
|
|
391
|
+
})
|
|
392
|
+
: null;
|
|
393
|
+
if (deleteTarget) {
|
|
394
|
+
preview.push(`directory: ${shortenHomePath(deleteTarget)}`);
|
|
395
|
+
}
|
|
396
|
+
const pluginName = plugin?.name || pluginId;
|
|
397
|
+
defaultRuntime.log(`Plugin: ${theme.command(pluginName)}${pluginName !== pluginId ? theme.muted(` (${pluginId})`) : ""}`);
|
|
398
|
+
defaultRuntime.log(`Will remove: ${preview.length > 0 ? preview.join(", ") : "(nothing)"}`);
|
|
399
|
+
if (opts.dryRun) {
|
|
400
|
+
defaultRuntime.log(theme.muted("Dry run, no changes made."));
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
if (!opts.force) {
|
|
404
|
+
const confirmed = await promptYesNo(`Uninstall plugin "${pluginId}"?`);
|
|
405
|
+
if (!confirmed) {
|
|
406
|
+
defaultRuntime.log("Cancelled.");
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
const result = await uninstallPlugin({
|
|
411
|
+
config: cfg,
|
|
412
|
+
pluginId,
|
|
413
|
+
deleteFiles: !keepFiles,
|
|
414
|
+
extensionsDir,
|
|
415
|
+
});
|
|
416
|
+
if (!result.ok) {
|
|
417
|
+
defaultRuntime.error(result.error);
|
|
418
|
+
process.exit(1);
|
|
419
|
+
}
|
|
420
|
+
for (const warning of result.warnings) {
|
|
421
|
+
defaultRuntime.log(theme.warn(warning));
|
|
422
|
+
}
|
|
423
|
+
await writeConfigFile(result.config);
|
|
424
|
+
const removed = [];
|
|
425
|
+
if (result.actions.entry) {
|
|
426
|
+
removed.push("config entry");
|
|
427
|
+
}
|
|
428
|
+
if (result.actions.install) {
|
|
429
|
+
removed.push("install record");
|
|
430
|
+
}
|
|
431
|
+
if (result.actions.allowlist) {
|
|
432
|
+
removed.push("allowlist");
|
|
433
|
+
}
|
|
434
|
+
if (result.actions.loadPath) {
|
|
435
|
+
removed.push("load path");
|
|
436
|
+
}
|
|
437
|
+
if (result.actions.memorySlot) {
|
|
438
|
+
removed.push("memory slot");
|
|
439
|
+
}
|
|
440
|
+
if (result.actions.directory) {
|
|
441
|
+
removed.push("directory");
|
|
442
|
+
}
|
|
443
|
+
defaultRuntime.log(`Uninstalled plugin "${pluginId}". Removed: ${removed.length > 0 ? removed.join(", ") : "nothing"}.`);
|
|
444
|
+
defaultRuntime.log("Restart the gateway to apply changes.");
|
|
445
|
+
});
|
|
248
446
|
plugins
|
|
249
447
|
.command("install")
|
|
250
448
|
.description("Install a plugin (path, archive, or npm spec)")
|
|
251
449
|
.argument("<path-or-spec>", "Path (.ts/.js/.zip/.tgz/.tar.gz) or an npm package spec")
|
|
252
450
|
.option("-l, --link", "Link a local path instead of copying", false)
|
|
451
|
+
.option("--pin", "Record npm installs as exact resolved <name>@<version>", false)
|
|
253
452
|
.action(async (raw, opts) => {
|
|
254
|
-
const
|
|
453
|
+
const fileSpec = resolveFileNpmSpecToLocalPath(raw);
|
|
454
|
+
if (fileSpec && !fileSpec.ok) {
|
|
455
|
+
defaultRuntime.error(fileSpec.error);
|
|
456
|
+
process.exit(1);
|
|
457
|
+
}
|
|
458
|
+
const normalized = fileSpec && fileSpec.ok ? fileSpec.path : raw;
|
|
459
|
+
const resolved = resolveUserPath(normalized);
|
|
255
460
|
const cfg = loadConfig();
|
|
256
461
|
if (fs.existsSync(resolved)) {
|
|
257
462
|
if (opts.link) {
|
|
@@ -262,7 +467,7 @@ export function registerPluginsCli(program) {
|
|
|
262
467
|
defaultRuntime.error(probe.error);
|
|
263
468
|
process.exit(1);
|
|
264
469
|
}
|
|
265
|
-
let next = {
|
|
470
|
+
let next = enablePluginInConfig({
|
|
266
471
|
...cfg,
|
|
267
472
|
plugins: {
|
|
268
473
|
...cfg.plugins,
|
|
@@ -270,15 +475,8 @@ export function registerPluginsCli(program) {
|
|
|
270
475
|
...cfg.plugins?.load,
|
|
271
476
|
paths: merged,
|
|
272
477
|
},
|
|
273
|
-
entries: {
|
|
274
|
-
...cfg.plugins?.entries,
|
|
275
|
-
[probe.pluginId]: {
|
|
276
|
-
...cfg.plugins?.entries?.[probe.pluginId],
|
|
277
|
-
enabled: true,
|
|
278
|
-
},
|
|
279
|
-
},
|
|
280
478
|
},
|
|
281
|
-
};
|
|
479
|
+
}, probe.pluginId);
|
|
282
480
|
next = recordPluginInstall(next, {
|
|
283
481
|
pluginId: probe.pluginId,
|
|
284
482
|
source: "path",
|
|
@@ -296,28 +494,16 @@ export function registerPluginsCli(program) {
|
|
|
296
494
|
}
|
|
297
495
|
const result = await installPluginFromPath({
|
|
298
496
|
path: resolved,
|
|
299
|
-
logger:
|
|
300
|
-
info: (msg) => defaultRuntime.log(msg),
|
|
301
|
-
warn: (msg) => defaultRuntime.log(theme.warn(msg)),
|
|
302
|
-
},
|
|
497
|
+
logger: createPluginInstallLogger(),
|
|
303
498
|
});
|
|
304
499
|
if (!result.ok) {
|
|
305
500
|
defaultRuntime.error(result.error);
|
|
306
501
|
process.exit(1);
|
|
307
502
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
entries: {
|
|
313
|
-
...cfg.plugins?.entries,
|
|
314
|
-
[result.pluginId]: {
|
|
315
|
-
...cfg.plugins?.entries?.[result.pluginId],
|
|
316
|
-
enabled: true,
|
|
317
|
-
},
|
|
318
|
-
},
|
|
319
|
-
},
|
|
320
|
-
};
|
|
503
|
+
// Plugin CLI registrars may have warmed the manifest registry cache before install;
|
|
504
|
+
// force a rescan so config validation sees the freshly installed plugin.
|
|
505
|
+
clearPluginManifestRegistryCache();
|
|
506
|
+
let next = enablePluginInConfig(cfg, result.pluginId);
|
|
321
507
|
const source = resolveArchiveKind(resolved) ? "archive" : "path";
|
|
322
508
|
next = recordPluginInstall(next, {
|
|
323
509
|
pluginId: result.pluginId,
|
|
@@ -355,32 +541,28 @@ export function registerPluginsCli(program) {
|
|
|
355
541
|
}
|
|
356
542
|
const result = await installPluginFromNpmSpec({
|
|
357
543
|
spec: raw,
|
|
358
|
-
logger:
|
|
359
|
-
info: (msg) => defaultRuntime.log(msg),
|
|
360
|
-
warn: (msg) => defaultRuntime.log(theme.warn(msg)),
|
|
361
|
-
},
|
|
544
|
+
logger: createPluginInstallLogger(),
|
|
362
545
|
});
|
|
363
546
|
if (!result.ok) {
|
|
364
547
|
defaultRuntime.error(result.error);
|
|
365
548
|
process.exit(1);
|
|
366
549
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
};
|
|
550
|
+
// Ensure config validation sees newly installed plugin(s) even if the cache was warmed at startup.
|
|
551
|
+
clearPluginManifestRegistryCache();
|
|
552
|
+
let next = enablePluginInConfig(cfg, result.pluginId);
|
|
553
|
+
// PB's installPluginFromNpmSpec does not return npmResolution metadata yet;
|
|
554
|
+
// record what we can (version from manifest) and store the raw spec.
|
|
555
|
+
const recordSpec = opts.pin && result.version ? `${result.pluginId}@${result.version}` : raw;
|
|
556
|
+
if (opts.pin && !result.version) {
|
|
557
|
+
defaultRuntime.log(theme.warn("Could not resolve exact npm version for --pin; storing original npm spec."));
|
|
558
|
+
}
|
|
559
|
+
if (opts.pin && result.version) {
|
|
560
|
+
defaultRuntime.log(`Pinned npm install record to ${result.pluginId}@${result.version}.`);
|
|
561
|
+
}
|
|
380
562
|
next = recordPluginInstall(next, {
|
|
381
563
|
pluginId: result.pluginId,
|
|
382
564
|
source: "npm",
|
|
383
|
-
spec:
|
|
565
|
+
spec: recordSpec,
|
|
384
566
|
installPath: result.targetDir,
|
|
385
567
|
version: result.version,
|
|
386
568
|
});
|
|
@@ -417,6 +599,7 @@ export function registerPluginsCli(program) {
|
|
|
417
599
|
info: (msg) => defaultRuntime.log(msg),
|
|
418
600
|
warn: (msg) => defaultRuntime.log(theme.warn(msg)),
|
|
419
601
|
},
|
|
602
|
+
// NOTE: onIntegrityDrift is available in OC but not yet ported to PB's update module.
|
|
420
603
|
});
|
|
421
604
|
for (const outcome of result.outcomes) {
|
|
422
605
|
if (outcome.status === "error") {
|
|
@@ -453,15 +636,16 @@ export function registerPluginsCli(program) {
|
|
|
453
636
|
}
|
|
454
637
|
}
|
|
455
638
|
if (diags.length > 0) {
|
|
456
|
-
if (lines.length > 0)
|
|
639
|
+
if (lines.length > 0) {
|
|
457
640
|
lines.push("");
|
|
641
|
+
}
|
|
458
642
|
lines.push(theme.warn("Diagnostics:"));
|
|
459
643
|
for (const diag of diags) {
|
|
460
644
|
const target = diag.pluginId ? `${diag.pluginId}: ` : "";
|
|
461
645
|
lines.push(`- ${target}${diag.message}`);
|
|
462
646
|
}
|
|
463
647
|
}
|
|
464
|
-
const docs = formatDocsLink("/plugin", "docs.
|
|
648
|
+
const docs = formatDocsLink("/plugin", "docs.poolbot.ai/plugin");
|
|
465
649
|
lines.push("");
|
|
466
650
|
lines.push(`${theme.muted("Docs:")} ${docs}`);
|
|
467
651
|
defaultRuntime.log(lines.join("\n"));
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import { createProgramContext } from "./context.js";
|
|
3
2
|
import { registerProgramCommands } from "./command-registry.js";
|
|
3
|
+
import { createProgramContext } from "./context.js";
|
|
4
4
|
import { configureProgramHelp } from "./help.js";
|
|
5
5
|
import { registerPreActionHooks } from "./preaction.js";
|
|
6
|
+
import { setProgramContext } from "./program-context.js";
|
|
6
7
|
export function buildProgram() {
|
|
7
8
|
const program = new Command();
|
|
8
9
|
const ctx = createProgramContext();
|
|
9
10
|
const argv = process.argv;
|
|
11
|
+
setProgramContext(program, ctx);
|
|
10
12
|
configureProgramHelp(program, ctx);
|
|
11
13
|
registerPreActionHooks(program, ctx.programVersion);
|
|
12
14
|
registerProgramCommands(program, ctx, argv);
|