@nextclaw/service 0.1.1
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/LICENSE +21 -0
- package/dist/cli/commands/agent/agent-runtime.utils.d.ts +15 -0
- package/dist/cli/commands/agent/agent-runtime.utils.js +85 -0
- package/dist/cli/commands/agent/cli-agent-runner.utils.d.ts +21 -0
- package/dist/cli/commands/agent/cli-agent-runner.utils.js +89 -0
- package/dist/cli/commands/agent/index.d.ts +3 -0
- package/dist/cli/commands/agent/index.js +3 -0
- package/dist/cli/commands/agent/services/agent-commands.service.d.ts +17 -0
- package/dist/cli/commands/agent/services/agent-commands.service.js +112 -0
- package/dist/cli/commands/companion/index.d.ts +15 -0
- package/dist/cli/commands/companion/index.js +24 -0
- package/dist/cli/commands/companion/services/companion-process.service.d.ts +17 -0
- package/dist/cli/commands/companion/services/companion-process.service.js +49 -0
- package/dist/cli/commands/config/index.d.ts +2 -0
- package/dist/cli/commands/config/index.js +2 -0
- package/dist/cli/commands/config/services/config-commands.service.d.ts +18 -0
- package/dist/cli/commands/config/services/config-commands.service.js +133 -0
- package/dist/cli/commands/cron/index.d.ts +2 -0
- package/dist/cli/commands/cron/index.js +2 -0
- package/dist/cli/commands/cron/services/cron-commands.service.d.ts +22 -0
- package/dist/cli/commands/cron/services/cron-commands.service.js +107 -0
- package/dist/cli/commands/cron/services/cron-local.service.d.ts +25 -0
- package/dist/cli/commands/cron/services/cron-local.service.js +95 -0
- package/dist/cli/commands/cron/utils/cron-job.utils.d.ts +31 -0
- package/dist/cli/commands/cron/utils/cron-job.utils.js +15 -0
- package/dist/cli/commands/diagnostics/index.d.ts +2 -0
- package/dist/cli/commands/diagnostics/index.js +2 -0
- package/dist/cli/commands/diagnostics/services/diagnostics-commands.service.d.ts +22 -0
- package/dist/cli/commands/diagnostics/services/diagnostics-commands.service.js +319 -0
- package/dist/cli/commands/diagnostics/utils/diagnostics-render.utils.d.ts +23 -0
- package/dist/cli/commands/diagnostics/utils/diagnostics-render.utils.js +66 -0
- package/dist/cli/commands/gateway/index.d.ts +14 -0
- package/dist/cli/commands/gateway/index.js +15 -0
- package/dist/cli/commands/logs/index.d.ts +12 -0
- package/dist/cli/commands/logs/index.js +29 -0
- package/dist/cli/commands/mcp/index.d.ts +14 -0
- package/dist/cli/commands/mcp/index.js +193 -0
- package/dist/cli/commands/restart/index.d.ts +20 -0
- package/dist/cli/commands/restart/index.js +88 -0
- package/dist/cli/commands/secrets/index.d.ts +22 -0
- package/dist/cli/commands/secrets/index.js +280 -0
- package/dist/cli/commands/serve/index.d.ts +14 -0
- package/dist/cli/commands/serve/index.js +19 -0
- package/dist/cli/commands/skills/index.d.ts +26 -0
- package/dist/cli/commands/skills/index.js +147 -0
- package/dist/cli/commands/skills/marketplace-client.d.ts +31 -0
- package/dist/cli/commands/skills/marketplace-client.js +84 -0
- package/dist/cli/commands/skills/marketplace-command-options.utils.d.ts +25 -0
- package/dist/cli/commands/skills/marketplace-command-options.utils.js +31 -0
- package/dist/cli/commands/skills/marketplace-identity.utils.d.ts +14 -0
- package/dist/cli/commands/skills/marketplace-identity.utils.js +77 -0
- package/dist/cli/commands/skills/marketplace-network-retry.d.ts +4 -0
- package/dist/cli/commands/skills/marketplace-network-retry.js +32 -0
- package/dist/cli/commands/skills/marketplace.metadata.d.ts +29 -0
- package/dist/cli/commands/skills/marketplace.metadata.js +158 -0
- package/dist/cli/commands/skills/marketplace.service.d.ts +46 -0
- package/dist/cli/commands/skills/marketplace.service.js +238 -0
- package/dist/cli/commands/skills/skills-query.service.d.ts +141 -0
- package/dist/cli/commands/skills/skills-query.service.js +212 -0
- package/dist/cli/commands/start/index.d.ts +18 -0
- package/dist/cli/commands/start/index.js +25 -0
- package/dist/cli/commands/stop/index.d.ts +12 -0
- package/dist/cli/commands/stop/index.js +11 -0
- package/dist/cli/commands/ui/index.d.ts +14 -0
- package/dist/cli/commands/ui/index.js +17 -0
- package/dist/cli/commands/usage/index.d.ts +2 -0
- package/dist/cli/commands/usage/index.js +2 -0
- package/dist/cli/commands/usage/services/llm-usage-command.service.d.ts +22 -0
- package/dist/cli/commands/usage/services/llm-usage-command.service.js +160 -0
- package/dist/cli/commands/usage/services/llm-usage-query.service.d.ts +43 -0
- package/dist/cli/commands/usage/services/llm-usage-query.service.js +85 -0
- package/dist/commands/channel/channel-config-view.d.ts +7 -0
- package/dist/commands/channel/channel-config-view.js +7 -0
- package/dist/commands/channel/index.d.ts +28 -0
- package/dist/commands/channel/index.js +224 -0
- package/dist/commands/platform-auth/index.d.ts +2 -0
- package/dist/commands/platform-auth/index.js +2 -0
- package/dist/commands/platform-auth/services/account-status.service.d.ts +18 -0
- package/dist/commands/platform-auth/services/account-status.service.js +34 -0
- package/dist/commands/platform-auth/services/platform-auth-commands.service.d.ts +77 -0
- package/dist/commands/platform-auth/services/platform-auth-commands.service.js +295 -0
- package/dist/commands/platform-auth/utils/payload.utils.d.ts +28 -0
- package/dist/commands/platform-auth/utils/payload.utils.js +87 -0
- package/dist/commands/plugin/development-source/dev-plugin-overrides.utils.d.ts +18 -0
- package/dist/commands/plugin/development-source/dev-plugin-overrides.utils.js +111 -0
- package/dist/commands/plugin/development-source/first-party-plugin-load-paths.d.ts +9 -0
- package/dist/commands/plugin/development-source/first-party-plugin-load-paths.js +183 -0
- package/dist/commands/plugin/index.d.ts +30 -0
- package/dist/commands/plugin/index.js +266 -0
- package/dist/commands/plugin/plugin-command-utils.d.ts +13 -0
- package/dist/commands/plugin/plugin-command-utils.js +37 -0
- package/dist/commands/plugin/plugin-extension-registry.d.ts +10 -0
- package/dist/commands/plugin/plugin-extension-registry.js +35 -0
- package/dist/commands/plugin/plugin-mutation-actions.d.ts +15 -0
- package/dist/commands/plugin/plugin-mutation-actions.js +162 -0
- package/dist/commands/plugin/plugin-registry-loader.d.ts +15 -0
- package/dist/commands/plugin/plugin-registry-loader.js +43 -0
- package/dist/commands/plugin/plugin-reload.d.ts +13 -0
- package/dist/commands/plugin/plugin-reload.js +42 -0
- package/dist/commands/remote/index.d.ts +47 -0
- package/dist/commands/remote/index.js +174 -0
- package/dist/commands/remote/services/remote-access-host.service.d.ts +41 -0
- package/dist/commands/remote/services/remote-access-host.service.js +126 -0
- package/dist/commands/remote/services/remote-runtime-support.service.d.ts +15 -0
- package/dist/commands/remote/services/remote-runtime-support.service.js +79 -0
- package/dist/commands/remote/services/remote-service-control.service.d.ts +33 -0
- package/dist/commands/remote/services/remote-service-control.service.js +188 -0
- package/dist/commands/remote/utils/platform-api-base.utils.d.ts +14 -0
- package/dist/commands/remote/utils/platform-api-base.utils.js +39 -0
- package/dist/commands/service/index.d.ts +16 -0
- package/dist/commands/service/index.js +31 -0
- package/dist/commands/service/services/autostart/host-autostart-command.service.d.ts +29 -0
- package/dist/commands/service/services/autostart/host-autostart-command.service.js +158 -0
- package/dist/commands/service/services/autostart/host-autostart-runtime.service.d.ts +23 -0
- package/dist/commands/service/services/autostart/host-autostart-runtime.service.js +53 -0
- package/dist/commands/service/services/autostart/host-autostart.service.d.ts +41 -0
- package/dist/commands/service/services/autostart/host-autostart.service.js +48 -0
- package/dist/commands/service/services/autostart/linux-systemd-autostart.service.d.ts +48 -0
- package/dist/commands/service/services/autostart/linux-systemd-autostart.service.js +433 -0
- package/dist/commands/service/services/autostart/macos-launch-agent-autostart.service.d.ts +54 -0
- package/dist/commands/service/services/autostart/macos-launch-agent-autostart.service.js +405 -0
- package/dist/commands/service/services/autostart/windows-task-autostart.service.d.ts +54 -0
- package/dist/commands/service/services/autostart/windows-task-autostart.service.js +403 -0
- package/dist/commands/service/types/autostart/host-autostart.types.d.ts +64 -0
- package/dist/commands/service/types/autostart/host-autostart.types.js +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/launcher/npm-runtime-bundle-layout.store.d.ts +23 -0
- package/dist/launcher/npm-runtime-bundle-layout.store.js +37 -0
- package/dist/launcher/npm-runtime-bundle-manifest.service.d.ts +9 -0
- package/dist/launcher/npm-runtime-bundle-manifest.service.js +39 -0
- package/dist/launcher/npm-runtime-bundle.service.d.ts +47 -0
- package/dist/launcher/npm-runtime-bundle.service.js +150 -0
- package/dist/launcher/npm-runtime-bundle.types.d.ts +49 -0
- package/dist/launcher/npm-runtime-bundle.types.js +1 -0
- package/dist/launcher/npm-runtime-launcher.service.d.ts +19 -0
- package/dist/launcher/npm-runtime-launcher.service.js +57 -0
- package/dist/launcher/npm-runtime-update-command.service.d.ts +12 -0
- package/dist/launcher/npm-runtime-update-command.service.js +87 -0
- package/dist/launcher/npm-runtime-update-source.service.d.ts +19 -0
- package/dist/launcher/npm-runtime-update-source.service.js +57 -0
- package/dist/launcher/npm-runtime-update-state.store.d.ts +17 -0
- package/dist/launcher/npm-runtime-update-state.store.js +92 -0
- package/dist/launcher/npm-runtime-update.manager.d.ts +42 -0
- package/dist/launcher/npm-runtime-update.manager.js +179 -0
- package/dist/launcher/npm-runtime-update.service.d.ts +54 -0
- package/dist/launcher/npm-runtime-update.service.js +183 -0
- package/dist/service-runtime.service.d.ts +91 -0
- package/dist/service-runtime.service.js +392 -0
- package/dist/shared/controllers/gateway.controller.d.ts +61 -0
- package/dist/shared/controllers/gateway.controller.js +318 -0
- package/dist/shared/services/extensions/extension-lifecycle.service.d.ts +56 -0
- package/dist/shared/services/extensions/extension-lifecycle.service.js +143 -0
- package/dist/shared/services/extensions/service-extension-runtime.service.d.ts +51 -0
- package/dist/shared/services/extensions/service-extension-runtime.service.js +338 -0
- package/dist/shared/services/gateway/cron-job-handler.service.d.ts +26 -0
- package/dist/shared/services/gateway/cron-job-handler.service.js +100 -0
- package/dist/shared/services/gateway/gateway-restart-wake.service.d.ts +12 -0
- package/dist/shared/services/gateway/gateway-restart-wake.service.js +91 -0
- package/dist/shared/services/gateway/managers/gateway-plugin.manager.d.ts +37 -0
- package/dist/shared/services/gateway/managers/gateway-plugin.manager.js +218 -0
- package/dist/shared/services/gateway/managers/gateway-remote.manager.d.ts +20 -0
- package/dist/shared/services/gateway/managers/gateway-remote.manager.js +25 -0
- package/dist/shared/services/gateway/nextclaw-app.service.d.ts +22 -0
- package/dist/shared/services/gateway/nextclaw-app.service.js +53 -0
- package/dist/shared/services/gateway/nextclaw-gateway-runtime.service.d.ts +89 -0
- package/dist/shared/services/gateway/nextclaw-gateway-runtime.service.js +337 -0
- package/dist/shared/services/gateway/service-bootstrap-status.d.ts +33 -0
- package/dist/shared/services/gateway/service-bootstrap-status.js +152 -0
- package/dist/shared/services/gateway/service-startup-support.service.d.ts +42 -0
- package/dist/shared/services/gateway/service-startup-support.service.js +96 -0
- package/dist/shared/services/gateway/utils/gateway-runtime-lifecycle.utils.d.ts +9 -0
- package/dist/shared/services/gateway/utils/gateway-runtime-lifecycle.utils.js +10 -0
- package/dist/shared/services/marketplace/service-marketplace-installer.service.d.ts +31 -0
- package/dist/shared/services/marketplace/service-marketplace-installer.service.js +99 -0
- package/dist/shared/services/marketplace/service-mcp-marketplace-ops.d.ts +39 -0
- package/dist/shared/services/marketplace/service-mcp-marketplace-ops.js +67 -0
- package/dist/shared/services/plugin/utils/plugin-dev-hot-reload.utils.d.ts +24 -0
- package/dist/shared/services/plugin/utils/plugin-dev-hot-reload.utils.js +117 -0
- package/dist/shared/services/plugin/utils/plugin-runtime-bridge.utils.d.ts +6 -0
- package/dist/shared/services/plugin/utils/plugin-runtime-bridge.utils.js +96 -0
- package/dist/shared/services/restart/restart-coordinator.service.d.ts +30 -0
- package/dist/shared/services/restart/restart-coordinator.service.js +51 -0
- package/dist/shared/services/restart/restart-sentinel.service.d.ts +39 -0
- package/dist/shared/services/restart/restart-sentinel.service.js +88 -0
- package/dist/shared/services/restart/runtime-restart-request.service.d.ts +24 -0
- package/dist/shared/services/restart/runtime-restart-request.service.js +42 -0
- package/dist/shared/services/runtime/runtime-command.service.d.ts +37 -0
- package/dist/shared/services/runtime/runtime-command.service.js +163 -0
- package/dist/shared/services/runtime/runtime-config-init.service.d.ts +4 -0
- package/dist/shared/services/runtime/runtime-config-init.service.js +10 -0
- package/dist/shared/services/runtime/service-managed-startup.service.d.ts +146 -0
- package/dist/shared/services/runtime/service-managed-startup.service.js +426 -0
- package/dist/shared/services/runtime/service-remote-runtime.service.d.ts +53 -0
- package/dist/shared/services/runtime/service-remote-runtime.service.js +173 -0
- package/dist/shared/services/runtime/utils/skills-loader.utils.d.ts +12 -0
- package/dist/shared/services/runtime/utils/skills-loader.utils.js +9 -0
- package/dist/shared/services/session/service-deferred-ncp-agent.service.d.ts +14 -0
- package/dist/shared/services/session/service-deferred-ncp-agent.service.js +85 -0
- package/dist/shared/services/ui/companion-runtime.service.d.ts +33 -0
- package/dist/shared/services/ui/companion-runtime.service.js +145 -0
- package/dist/shared/services/ui/local-ui-discovery.service.d.ts +19 -0
- package/dist/shared/services/ui/local-ui-discovery.service.js +41 -0
- package/dist/shared/services/ui/npm-runtime-update-host.service.d.ts +40 -0
- package/dist/shared/services/ui/npm-runtime-update-host.service.js +181 -0
- package/dist/shared/services/ui/runtime-control-host.service.d.ts +28 -0
- package/dist/shared/services/ui/runtime-control-host.service.js +89 -0
- package/dist/shared/services/ui/service-remote-access.service.d.ts +25 -0
- package/dist/shared/services/ui/service-remote-access.service.js +38 -0
- package/dist/shared/services/ui/ui-bridge-api.service.d.ts +16 -0
- package/dist/shared/services/ui/ui-bridge-api.service.js +43 -0
- package/dist/shared/services/workspace/workspace-manager.service.d.ts +19 -0
- package/dist/shared/services/workspace/workspace-manager.service.js +135 -0
- package/dist/shared/stores/companion-runtime.store.d.ts +15 -0
- package/dist/shared/stores/companion-runtime.store.js +27 -0
- package/dist/shared/stores/local-ui-runtime.store.d.ts +25 -0
- package/dist/shared/stores/local-ui-runtime.store.js +54 -0
- package/dist/shared/stores/managed-service-state.store.d.ts +28 -0
- package/dist/shared/stores/managed-service-state.store.js +38 -0
- package/dist/shared/stores/pending-restart.store.d.ts +21 -0
- package/dist/shared/stores/pending-restart.store.js +35 -0
- package/dist/shared/types/cli.types.d.ts +295 -0
- package/dist/shared/types/cli.types.js +1 -0
- package/dist/shared/utils/cli.utils.d.ts +34 -0
- package/dist/shared/utils/cli.utils.js +262 -0
- package/dist/shared/utils/config-path.d.ts +15 -0
- package/dist/shared/utils/config-path.js +167 -0
- package/dist/shared/utils/marketplace/cli-subcommand-launch.utils.d.ts +16 -0
- package/dist/shared/utils/marketplace/cli-subcommand-launch.utils.js +46 -0
- package/dist/shared/utils/marketplace/service-marketplace-helpers.utils.d.ts +9 -0
- package/dist/shared/utils/marketplace/service-marketplace-helpers.utils.js +33 -0
- package/dist/shared/utils/package/package-manifest.utils.d.ts +8 -0
- package/dist/shared/utils/package/package-manifest.utils.js +48 -0
- package/dist/shared/utils/runtime-helpers.d.ts +14 -0
- package/dist/shared/utils/runtime-helpers.js +26 -0
- package/dist/shared/utils/service-port-probe.utils.d.ts +41 -0
- package/dist/shared/utils/service-port-probe.utils.js +164 -0
- package/dist/shared/utils/startup-trace.d.ts +7 -0
- package/dist/shared/utils/startup-trace.js +37 -0
- package/dist/shared/utils/top-level-nextclaw-command-env.utils.d.ts +4 -0
- package/dist/shared/utils/top-level-nextclaw-command-env.utils.js +10 -0
- package/package.json +68 -0
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { openBrowser, prompt } from "../../../shared/utils/cli.utils.js";
|
|
2
|
+
import { buildPlatformApiBaseErrorMessage, resolvePlatformApiBase } from "../../remote/utils/platform-api-base.utils.js";
|
|
3
|
+
import "../../remote/index.js";
|
|
4
|
+
import { readBrowserAuthPollPayload, readBrowserAuthStartPayload, readLoginPayload, readPlatformAuthResultPayload, readPlatformErrorMessage, readPlatformUserPayload } from "../utils/payload.utils.js";
|
|
5
|
+
import { printAccountStatus, printUsernameUpdated, toAccountStatusView } from "./account-status.service.js";
|
|
6
|
+
import { getConfigPath, loadConfig, saveConfig } from "@nextclaw/core";
|
|
7
|
+
import { createInterface } from "node:readline";
|
|
8
|
+
//#region src/commands/platform-auth/services/platform-auth-commands.service.ts
|
|
9
|
+
function resolveProviderConfig(opts) {
|
|
10
|
+
const configPath = getConfigPath();
|
|
11
|
+
const config = loadConfig(configPath);
|
|
12
|
+
const providers = config.providers;
|
|
13
|
+
const nextclawProvider = providers.nextclaw ?? {
|
|
14
|
+
displayName: "",
|
|
15
|
+
apiKey: "",
|
|
16
|
+
apiBase: null,
|
|
17
|
+
extraHeaders: null,
|
|
18
|
+
wireApi: "auto",
|
|
19
|
+
models: []
|
|
20
|
+
};
|
|
21
|
+
const configuredApiBase = typeof nextclawProvider.apiBase === "string" && nextclawProvider.apiBase.trim().length > 0 ? nextclawProvider.apiBase.trim() : "https://ai-gateway-api.nextclaw.io/v1";
|
|
22
|
+
const { platformBase, v1Base, inputApiBase } = resolvePlatformApiBase({
|
|
23
|
+
explicitApiBase: typeof opts.apiBase === "string" && opts.apiBase.trim().length > 0 ? opts.apiBase.trim() : configuredApiBase,
|
|
24
|
+
fallbackApiBase: "https://ai-gateway-api.nextclaw.io/v1"
|
|
25
|
+
});
|
|
26
|
+
return {
|
|
27
|
+
configPath,
|
|
28
|
+
config,
|
|
29
|
+
providers,
|
|
30
|
+
nextclawProvider,
|
|
31
|
+
platformBase,
|
|
32
|
+
v1Base,
|
|
33
|
+
inputApiBase
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async function resolveCredentials(opts) {
|
|
37
|
+
let email = typeof opts.email === "string" ? opts.email.trim() : "";
|
|
38
|
+
let password = typeof opts.password === "string" ? opts.password : "";
|
|
39
|
+
if (email && password) return {
|
|
40
|
+
email,
|
|
41
|
+
password
|
|
42
|
+
};
|
|
43
|
+
const rl = createInterface({
|
|
44
|
+
input: process.stdin,
|
|
45
|
+
output: process.stdout
|
|
46
|
+
});
|
|
47
|
+
try {
|
|
48
|
+
if (!email) email = (await prompt(rl, "Email: ")).trim();
|
|
49
|
+
if (!password) password = await prompt(rl, "Password: ");
|
|
50
|
+
} finally {
|
|
51
|
+
rl.close();
|
|
52
|
+
}
|
|
53
|
+
if (!email || !password) throw new Error("Email and password are required.");
|
|
54
|
+
return {
|
|
55
|
+
email,
|
|
56
|
+
password
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function persistPlatformToken(params) {
|
|
60
|
+
const { configPath, config, providers, nextclawProvider, v1Base, token } = params;
|
|
61
|
+
nextclawProvider.apiBase = v1Base;
|
|
62
|
+
nextclawProvider.apiKey = token;
|
|
63
|
+
providers.nextclaw = nextclawProvider;
|
|
64
|
+
saveConfig(config, configPath);
|
|
65
|
+
}
|
|
66
|
+
var PlatformAuthCommands = class {
|
|
67
|
+
shouldUseBrowserLogin = (opts) => {
|
|
68
|
+
const email = typeof opts.email === "string" ? opts.email.trim() : "";
|
|
69
|
+
const password = typeof opts.password === "string" ? opts.password : "";
|
|
70
|
+
return !email && !password;
|
|
71
|
+
};
|
|
72
|
+
waitFor = async (delayMs) => {
|
|
73
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
74
|
+
};
|
|
75
|
+
formatLoginDeadline = (expiresAt) => {
|
|
76
|
+
const value = Date.parse(expiresAt);
|
|
77
|
+
return Number.isNaN(value) ? expiresAt : new Date(value).toLocaleString();
|
|
78
|
+
};
|
|
79
|
+
printLoginSuccess = (result) => {
|
|
80
|
+
console.log(`✓ Logged in to NextClaw platform (${result.platformBase})`);
|
|
81
|
+
console.log(`✓ Account: ${result.email} (${result.role})`);
|
|
82
|
+
console.log("✓ Token saved into providers.nextclaw.apiKey");
|
|
83
|
+
};
|
|
84
|
+
printBrowserLoginIntro = (params) => {
|
|
85
|
+
const { expiresAt, open, openedBrowser, verificationUri } = params;
|
|
86
|
+
const expiresText = this.formatLoginDeadline(expiresAt);
|
|
87
|
+
console.log("NextClaw browser sign-in");
|
|
88
|
+
console.log(`Open this link to continue: ${verificationUri}`);
|
|
89
|
+
if (open) if (openedBrowser) console.log("✓ Opened the default browser. Finish sign-in there and this terminal will complete automatically.");
|
|
90
|
+
else console.log("Browser did not open automatically. Open the link above in any browser to continue.");
|
|
91
|
+
else console.log("Automatic browser opening is disabled. Open the link above in any browser to continue.");
|
|
92
|
+
console.log("This link can be opened on this machine or on another device if your CLI is running remotely.");
|
|
93
|
+
console.log(`Waiting for authorization until ${expiresText}...`);
|
|
94
|
+
};
|
|
95
|
+
waitForBrowserLoginResult = async (params) => {
|
|
96
|
+
while (true) {
|
|
97
|
+
const result = await this.pollBrowserAuth({
|
|
98
|
+
apiBase: params.apiBase,
|
|
99
|
+
sessionId: params.sessionId
|
|
100
|
+
});
|
|
101
|
+
if (result.status === "pending") {
|
|
102
|
+
await this.waitFor(result.nextPollMs);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (result.status === "expired") throw new Error(`${result.message} Run \`nextclaw login\` again to generate a new sign-in link.`);
|
|
106
|
+
return {
|
|
107
|
+
token: result.token,
|
|
108
|
+
role: result.role,
|
|
109
|
+
email: result.email,
|
|
110
|
+
platformBase: result.platformBase,
|
|
111
|
+
v1Base: result.v1Base
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
loginWithBrowserResult = async (opts = {}) => {
|
|
116
|
+
const startResult = await this.startBrowserAuth({ apiBase: opts.apiBase });
|
|
117
|
+
const shouldOpenBrowser = opts.open !== false;
|
|
118
|
+
const openedBrowser = shouldOpenBrowser ? openBrowser(startResult.verificationUri) : false;
|
|
119
|
+
this.printBrowserLoginIntro({
|
|
120
|
+
verificationUri: startResult.verificationUri,
|
|
121
|
+
expiresAt: startResult.expiresAt,
|
|
122
|
+
open: shouldOpenBrowser,
|
|
123
|
+
openedBrowser
|
|
124
|
+
});
|
|
125
|
+
const result = await this.waitForBrowserLoginResult({
|
|
126
|
+
apiBase: opts.apiBase,
|
|
127
|
+
sessionId: startResult.sessionId
|
|
128
|
+
});
|
|
129
|
+
console.log("✓ Browser authorization completed.");
|
|
130
|
+
return result;
|
|
131
|
+
};
|
|
132
|
+
readStoredToken = (params = {}) => {
|
|
133
|
+
const resolved = resolveProviderConfig({ apiBase: params.apiBase });
|
|
134
|
+
const token = resolved.nextclawProvider.apiKey?.trim() ?? "";
|
|
135
|
+
if (!token) throw new Error("Not logged in. Run `nextclaw login` first.");
|
|
136
|
+
return {
|
|
137
|
+
...resolved,
|
|
138
|
+
token
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
loginResult = async (opts = {}) => {
|
|
142
|
+
const { configPath, config, providers, nextclawProvider, platformBase, v1Base, inputApiBase } = resolveProviderConfig(opts);
|
|
143
|
+
const { email, password } = await resolveCredentials(opts);
|
|
144
|
+
const response = await fetch(`${platformBase}/platform/auth/login`, {
|
|
145
|
+
method: "POST",
|
|
146
|
+
headers: { "Content-Type": "application/json" },
|
|
147
|
+
body: JSON.stringify({
|
|
148
|
+
email,
|
|
149
|
+
password
|
|
150
|
+
})
|
|
151
|
+
});
|
|
152
|
+
const raw = await response.text();
|
|
153
|
+
if (!response.ok) throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, readPlatformErrorMessage(raw, response.status)));
|
|
154
|
+
const { token, role } = readLoginPayload(raw);
|
|
155
|
+
persistPlatformToken({
|
|
156
|
+
configPath,
|
|
157
|
+
config,
|
|
158
|
+
providers,
|
|
159
|
+
nextclawProvider,
|
|
160
|
+
v1Base,
|
|
161
|
+
token
|
|
162
|
+
});
|
|
163
|
+
return {
|
|
164
|
+
token,
|
|
165
|
+
role,
|
|
166
|
+
email,
|
|
167
|
+
platformBase,
|
|
168
|
+
v1Base
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
startBrowserAuth = async (opts = {}) => {
|
|
172
|
+
const { platformBase, v1Base, inputApiBase } = resolveProviderConfig(opts);
|
|
173
|
+
const response = await fetch(`${platformBase}/platform/auth/browser/start`, {
|
|
174
|
+
method: "POST",
|
|
175
|
+
headers: { "Content-Type": "application/json" },
|
|
176
|
+
body: JSON.stringify({})
|
|
177
|
+
});
|
|
178
|
+
const raw = await response.text();
|
|
179
|
+
if (!response.ok) throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, readPlatformErrorMessage(raw, response.status)));
|
|
180
|
+
return {
|
|
181
|
+
...readBrowserAuthStartPayload(raw),
|
|
182
|
+
platformBase,
|
|
183
|
+
v1Base
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
pollBrowserAuth = async (params) => {
|
|
187
|
+
const { configPath, config, providers, nextclawProvider, platformBase, v1Base, inputApiBase } = resolveProviderConfig({ apiBase: params.apiBase });
|
|
188
|
+
const response = await fetch(`${platformBase}/platform/auth/browser/poll`, {
|
|
189
|
+
method: "POST",
|
|
190
|
+
headers: { "Content-Type": "application/json" },
|
|
191
|
+
body: JSON.stringify({ sessionId: params.sessionId })
|
|
192
|
+
});
|
|
193
|
+
const raw = await response.text();
|
|
194
|
+
if (!response.ok) throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, readPlatformErrorMessage(raw, response.status)));
|
|
195
|
+
const result = readBrowserAuthPollPayload(raw);
|
|
196
|
+
if (result.status === "pending") return {
|
|
197
|
+
status: "pending",
|
|
198
|
+
nextPollMs: result.nextPollMs ?? 1500
|
|
199
|
+
};
|
|
200
|
+
if (result.status === "expired") return {
|
|
201
|
+
status: "expired",
|
|
202
|
+
message: result.message ?? "Authorization session expired."
|
|
203
|
+
};
|
|
204
|
+
persistPlatformToken({
|
|
205
|
+
configPath,
|
|
206
|
+
config,
|
|
207
|
+
providers,
|
|
208
|
+
nextclawProvider,
|
|
209
|
+
v1Base,
|
|
210
|
+
token: result.token ?? ""
|
|
211
|
+
});
|
|
212
|
+
return {
|
|
213
|
+
status: "authorized",
|
|
214
|
+
token: result.token ?? "",
|
|
215
|
+
role: result.role ?? "user",
|
|
216
|
+
email: result.email ?? "",
|
|
217
|
+
platformBase,
|
|
218
|
+
v1Base
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
login = async (opts = {}) => {
|
|
222
|
+
const result = this.shouldUseBrowserLogin(opts) ? await this.loginWithBrowserResult(opts) : await this.loginResult(opts);
|
|
223
|
+
this.printLoginSuccess(result);
|
|
224
|
+
};
|
|
225
|
+
me = async (params = {}) => {
|
|
226
|
+
const { platformBase, v1Base, inputApiBase, token } = this.readStoredToken(params);
|
|
227
|
+
const response = await fetch(`${platformBase}/platform/auth/me`, { headers: { Authorization: `Bearer ${token}` } });
|
|
228
|
+
const raw = await response.text();
|
|
229
|
+
if (!response.ok) throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, readPlatformErrorMessage(raw, response.status)));
|
|
230
|
+
return {
|
|
231
|
+
user: readPlatformUserPayload(raw),
|
|
232
|
+
token,
|
|
233
|
+
platformBase,
|
|
234
|
+
v1Base
|
|
235
|
+
};
|
|
236
|
+
};
|
|
237
|
+
updateProfile = async (params) => {
|
|
238
|
+
const { configPath, config, providers, nextclawProvider, platformBase, v1Base, inputApiBase, token } = this.readStoredToken(params);
|
|
239
|
+
const response = await fetch(`${platformBase}/platform/auth/profile`, {
|
|
240
|
+
method: "PATCH",
|
|
241
|
+
headers: {
|
|
242
|
+
Authorization: `Bearer ${token}`,
|
|
243
|
+
"Content-Type": "application/json"
|
|
244
|
+
},
|
|
245
|
+
body: JSON.stringify({ username: params.username })
|
|
246
|
+
});
|
|
247
|
+
const raw = await response.text();
|
|
248
|
+
if (!response.ok) throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, readPlatformErrorMessage(raw, response.status)));
|
|
249
|
+
const result = readPlatformAuthResultPayload(raw);
|
|
250
|
+
persistPlatformToken({
|
|
251
|
+
configPath,
|
|
252
|
+
config,
|
|
253
|
+
providers,
|
|
254
|
+
nextclawProvider,
|
|
255
|
+
v1Base,
|
|
256
|
+
token: result.token
|
|
257
|
+
});
|
|
258
|
+
return {
|
|
259
|
+
user: result.user,
|
|
260
|
+
token: result.token,
|
|
261
|
+
platformBase,
|
|
262
|
+
v1Base
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
logout = () => {
|
|
266
|
+
const { configPath, config, providers, nextclawProvider } = resolveProviderConfig({});
|
|
267
|
+
const cleared = Boolean(nextclawProvider.apiKey?.trim());
|
|
268
|
+
nextclawProvider.apiKey = "";
|
|
269
|
+
providers.nextclaw = nextclawProvider;
|
|
270
|
+
saveConfig(config, configPath);
|
|
271
|
+
return { cleared };
|
|
272
|
+
};
|
|
273
|
+
accountStatus = async (opts = {}) => {
|
|
274
|
+
const view = toAccountStatusView(await this.me({ apiBase: opts.apiBase }));
|
|
275
|
+
if (opts.json) {
|
|
276
|
+
console.log(JSON.stringify(view, null, 2));
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
printAccountStatus(view);
|
|
280
|
+
};
|
|
281
|
+
accountSetUsername = async (opts) => {
|
|
282
|
+
const view = toAccountStatusView(await this.updateProfile({
|
|
283
|
+
apiBase: opts.apiBase,
|
|
284
|
+
username: opts.username
|
|
285
|
+
}));
|
|
286
|
+
if (opts.json) {
|
|
287
|
+
console.log(JSON.stringify(view, null, 2));
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
printUsernameUpdated(view);
|
|
291
|
+
printAccountStatus(view);
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
//#endregion
|
|
295
|
+
export { PlatformAuthCommands };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { PlatformUserView } from "../services/platform-auth-commands.service.js";
|
|
2
|
+
//#region src/commands/platform-auth/utils/payload.utils.d.ts
|
|
3
|
+
declare function readLoginPayload(raw: string): {
|
|
4
|
+
token: string;
|
|
5
|
+
role: string;
|
|
6
|
+
};
|
|
7
|
+
declare function readPlatformUserPayload(raw: string): PlatformUserView;
|
|
8
|
+
declare function readPlatformAuthResultPayload(raw: string): {
|
|
9
|
+
token: string;
|
|
10
|
+
user: PlatformUserView;
|
|
11
|
+
};
|
|
12
|
+
declare function readPlatformErrorMessage(raw: string, fallbackStatus: number): string;
|
|
13
|
+
declare function readBrowserAuthStartPayload(raw: string): {
|
|
14
|
+
sessionId: string;
|
|
15
|
+
verificationUri: string;
|
|
16
|
+
expiresAt: string;
|
|
17
|
+
intervalMs: number;
|
|
18
|
+
};
|
|
19
|
+
declare function readBrowserAuthPollPayload(raw: string): {
|
|
20
|
+
status: "pending" | "authorized" | "expired";
|
|
21
|
+
nextPollMs?: number;
|
|
22
|
+
token?: string;
|
|
23
|
+
role?: string;
|
|
24
|
+
email?: string;
|
|
25
|
+
message?: string;
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { readBrowserAuthPollPayload, readBrowserAuthStartPayload, readLoginPayload, readPlatformAuthResultPayload, readPlatformErrorMessage, readPlatformUserPayload };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
//#region src/commands/platform-auth/utils/payload.utils.ts
|
|
2
|
+
function readLoginPayload(raw) {
|
|
3
|
+
const authResult = readPlatformAuthResultPayload(raw);
|
|
4
|
+
return {
|
|
5
|
+
token: authResult.token,
|
|
6
|
+
role: authResult.user.role
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
function readPlatformUserPayload(raw) {
|
|
10
|
+
const parsed = parseJsonText(raw);
|
|
11
|
+
const data = typeof parsed === "object" && parsed && "data" in parsed ? parsed.data : null;
|
|
12
|
+
const user = typeof data?.user === "object" && data.user ? data.user : null;
|
|
13
|
+
const id = typeof user?.id === "string" ? user.id.trim() : "";
|
|
14
|
+
const email = typeof user?.email === "string" ? user.email.trim() : "";
|
|
15
|
+
const role = typeof user?.role === "string" ? user.role.trim() : "user";
|
|
16
|
+
const username = typeof user?.username === "string" ? user.username.trim() : user?.username === null ? null : null;
|
|
17
|
+
if (!id || !email) throw new Error("Platform user payload is incomplete.");
|
|
18
|
+
return {
|
|
19
|
+
id,
|
|
20
|
+
email,
|
|
21
|
+
username: username && username.length > 0 ? username : null,
|
|
22
|
+
role
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function readPlatformAuthResultPayload(raw) {
|
|
26
|
+
const parsed = parseJsonText(raw);
|
|
27
|
+
const token = typeof parsed === "object" && parsed && "data" in parsed && typeof parsed.data?.token === "string" ? parsed.data.token : "";
|
|
28
|
+
const user = readPlatformUserPayload(raw);
|
|
29
|
+
if (!token) throw new Error("Login succeeded but token is missing.");
|
|
30
|
+
return {
|
|
31
|
+
token,
|
|
32
|
+
user
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function readPlatformErrorMessage(raw, fallbackStatus) {
|
|
36
|
+
const parsed = parseJsonText(raw);
|
|
37
|
+
return typeof parsed === "object" && parsed && "error" in parsed && typeof parsed.error?.message === "string" ? parsed.error.message : raw || `Request failed (${fallbackStatus})`;
|
|
38
|
+
}
|
|
39
|
+
function readBrowserAuthStartPayload(raw) {
|
|
40
|
+
const parsed = parseJsonText(raw);
|
|
41
|
+
const data = typeof parsed === "object" && parsed && "data" in parsed ? parsed.data : null;
|
|
42
|
+
const sessionId = typeof data?.sessionId === "string" ? data.sessionId.trim() : "";
|
|
43
|
+
const verificationUri = typeof data?.verificationUri === "string" ? data.verificationUri.trim() : "";
|
|
44
|
+
const expiresAt = typeof data?.expiresAt === "string" ? data.expiresAt.trim() : "";
|
|
45
|
+
const intervalMs = typeof data?.intervalMs === "number" && Number.isFinite(data.intervalMs) ? Math.max(1e3, Math.trunc(data.intervalMs)) : 1500;
|
|
46
|
+
if (!sessionId || !verificationUri || !expiresAt) throw new Error("Browser authorization session payload is incomplete.");
|
|
47
|
+
return {
|
|
48
|
+
sessionId,
|
|
49
|
+
verificationUri,
|
|
50
|
+
expiresAt,
|
|
51
|
+
intervalMs
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function readBrowserAuthPollPayload(raw) {
|
|
55
|
+
const parsed = parseJsonText(raw);
|
|
56
|
+
const data = typeof parsed === "object" && parsed && "data" in parsed ? parsed.data : null;
|
|
57
|
+
const status = typeof data?.status === "string" ? data.status.trim() : "";
|
|
58
|
+
if (status === "pending") return {
|
|
59
|
+
status,
|
|
60
|
+
nextPollMs: typeof data?.nextPollMs === "number" && Number.isFinite(data.nextPollMs) ? Math.max(1e3, Math.trunc(data.nextPollMs)) : 1500
|
|
61
|
+
};
|
|
62
|
+
if (status === "expired") return {
|
|
63
|
+
status,
|
|
64
|
+
message: typeof data?.message === "string" && data.message.trim() ? data.message.trim() : "Authorization session expired."
|
|
65
|
+
};
|
|
66
|
+
if (status !== "authorized") throw new Error("Unexpected browser authorization status.");
|
|
67
|
+
const token = typeof data?.token === "string" ? data.token.trim() : "";
|
|
68
|
+
const user = typeof data?.user === "object" && data.user ? data.user : null;
|
|
69
|
+
const role = typeof user?.role === "string" ? user.role.trim() : "user";
|
|
70
|
+
const email = typeof user?.email === "string" ? user.email.trim() : "";
|
|
71
|
+
if (!token || !email) throw new Error("Authorized browser login payload is incomplete.");
|
|
72
|
+
return {
|
|
73
|
+
status,
|
|
74
|
+
token,
|
|
75
|
+
role,
|
|
76
|
+
email
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function parseJsonText(raw) {
|
|
80
|
+
try {
|
|
81
|
+
return JSON.parse(raw);
|
|
82
|
+
} catch {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
export { readBrowserAuthPollPayload, readBrowserAuthStartPayload, readLoginPayload, readPlatformAuthResultPayload, readPlatformErrorMessage, readPlatformUserPayload };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Config } from "@nextclaw/core";
|
|
2
|
+
|
|
3
|
+
//#region src/commands/plugin/development-source/dev-plugin-overrides.utils.d.ts
|
|
4
|
+
declare const DEV_PLUGIN_OVERRIDES_ENV = "NEXTCLAW_DEV_PLUGIN_OVERRIDES";
|
|
5
|
+
type PluginEntrySource = "production" | "development";
|
|
6
|
+
type DevPluginOverride = {
|
|
7
|
+
pluginId: string;
|
|
8
|
+
pluginPath: string;
|
|
9
|
+
source: PluginEntrySource;
|
|
10
|
+
};
|
|
11
|
+
declare function resolveDevPluginOverrides(rawEnv?: string | undefined): DevPluginOverride[];
|
|
12
|
+
declare function resolveDevPluginLoadingContext(config: Config, workspaceExtensionsDir: string | undefined, rawOverridesEnv?: string | undefined): {
|
|
13
|
+
configWithDevPluginOverrides: Config;
|
|
14
|
+
excludedRoots: string[];
|
|
15
|
+
overrides: DevPluginOverride[];
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
export { DEV_PLUGIN_OVERRIDES_ENV, DevPluginOverride, resolveDevPluginLoadingContext, resolveDevPluginOverrides };
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { applyDevFirstPartyPluginLoadPaths, resolveDevFirstPartyPluginInstallRoots } from "./first-party-plugin-load-paths.js";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import { getPackageManifestExtensions, loadPluginManifest } from "@nextclaw/openclaw-compat";
|
|
5
|
+
//#region src/commands/plugin/development-source/dev-plugin-overrides.utils.ts
|
|
6
|
+
const DEV_PLUGIN_OVERRIDES_ENV = "NEXTCLAW_DEV_PLUGIN_OVERRIDES";
|
|
7
|
+
function isRecord(value) {
|
|
8
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
9
|
+
}
|
|
10
|
+
function readOptionalString(value) {
|
|
11
|
+
if (typeof value !== "string") return;
|
|
12
|
+
return value.trim() || void 0;
|
|
13
|
+
}
|
|
14
|
+
function readPackageManifest(pluginPath) {
|
|
15
|
+
const packageJsonPath = path.join(pluginPath, "package.json");
|
|
16
|
+
if (!fs.existsSync(packageJsonPath)) return null;
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
19
|
+
} catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function assertOverridePluginReadable(override) {
|
|
24
|
+
if (!fs.existsSync(override.pluginPath)) throw new Error(`[dev-plugin-override] plugin path does not exist for "${override.pluginId}": ${override.pluginPath}`);
|
|
25
|
+
const packageManifest = readPackageManifest(override.pluginPath);
|
|
26
|
+
if (!packageManifest) throw new Error(`[dev-plugin-override] package.json is missing or invalid for "${override.pluginId}": ${override.pluginPath}`);
|
|
27
|
+
const pluginManifest = loadPluginManifest(override.pluginPath);
|
|
28
|
+
if (!pluginManifest.ok) throw new Error(`[dev-plugin-override] ${pluginManifest.error} for "${override.pluginId}": ${override.pluginPath}`);
|
|
29
|
+
if (pluginManifest.manifest.id !== override.pluginId) throw new Error(`[dev-plugin-override] plugin id mismatch: expected "${override.pluginId}" but found "${pluginManifest.manifest.id}" at ${override.pluginPath}`);
|
|
30
|
+
if (getPackageManifestExtensions(packageManifest, override.source).length === 0) {
|
|
31
|
+
const missingEntry = override.source === "development" ? "openclaw.development.extensions" : "openclaw.extensions";
|
|
32
|
+
throw new Error(`[dev-plugin-override] ${missingEntry} is missing for "${override.pluginId}" at ${override.pluginPath}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function readOverrideRecord(value, index) {
|
|
36
|
+
if (!isRecord(value)) throw new Error(`[dev-plugin-override] override[${index}] must be an object`);
|
|
37
|
+
const pluginId = readOptionalString(value.pluginId);
|
|
38
|
+
const pluginPath = readOptionalString(value.pluginPath);
|
|
39
|
+
const source = value.source === "development" ? "development" : "production";
|
|
40
|
+
if (!pluginId || !pluginPath) throw new Error(`[dev-plugin-override] override[${index}] requires pluginId and pluginPath`);
|
|
41
|
+
const normalized = {
|
|
42
|
+
pluginId,
|
|
43
|
+
pluginPath: path.resolve(pluginPath),
|
|
44
|
+
source
|
|
45
|
+
};
|
|
46
|
+
assertOverridePluginReadable(normalized);
|
|
47
|
+
return normalized;
|
|
48
|
+
}
|
|
49
|
+
function resolveDevPluginOverrides(rawEnv = process.env[DEV_PLUGIN_OVERRIDES_ENV]) {
|
|
50
|
+
if (typeof rawEnv !== "string" || rawEnv.trim().length === 0) return [];
|
|
51
|
+
let parsed;
|
|
52
|
+
try {
|
|
53
|
+
parsed = JSON.parse(rawEnv);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
throw new Error(`[dev-plugin-override] failed to parse ${DEV_PLUGIN_OVERRIDES_ENV}: ${error instanceof Error ? error.message : String(error)}`);
|
|
56
|
+
}
|
|
57
|
+
if (!Array.isArray(parsed)) throw new Error(`[dev-plugin-override] ${DEV_PLUGIN_OVERRIDES_ENV} must be a JSON array`);
|
|
58
|
+
const seenPluginIds = /* @__PURE__ */ new Set();
|
|
59
|
+
const overrides = parsed.map((entry, index) => readOverrideRecord(entry, index));
|
|
60
|
+
for (const entry of overrides) {
|
|
61
|
+
if (seenPluginIds.has(entry.pluginId)) throw new Error(`[dev-plugin-override] duplicate plugin override for "${entry.pluginId}"`);
|
|
62
|
+
seenPluginIds.add(entry.pluginId);
|
|
63
|
+
}
|
|
64
|
+
return overrides;
|
|
65
|
+
}
|
|
66
|
+
function mergeLoadPaths(existingLoadPaths, overrideLoadPaths) {
|
|
67
|
+
const merged = [...overrideLoadPaths];
|
|
68
|
+
for (const entry of existingLoadPaths) if (!merged.includes(entry)) merged.push(entry);
|
|
69
|
+
return merged;
|
|
70
|
+
}
|
|
71
|
+
function applyExplicitDevPluginOverrides(config, overrides) {
|
|
72
|
+
if (overrides.length === 0) return config;
|
|
73
|
+
const nextEntries = { ...config.plugins.entries ?? {} };
|
|
74
|
+
for (const override of overrides) nextEntries[override.pluginId] = {
|
|
75
|
+
...nextEntries[override.pluginId] ?? {},
|
|
76
|
+
source: override.source
|
|
77
|
+
};
|
|
78
|
+
const existingLoadPaths = Array.isArray(config.plugins.load?.paths) ? config.plugins.load.paths.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
|
|
79
|
+
return {
|
|
80
|
+
...config,
|
|
81
|
+
plugins: {
|
|
82
|
+
...config.plugins,
|
|
83
|
+
entries: nextEntries,
|
|
84
|
+
load: {
|
|
85
|
+
...config.plugins.load,
|
|
86
|
+
paths: mergeLoadPaths(existingLoadPaths, overrides.map((entry) => entry.pluginPath))
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function resolveDevPluginOverrideInstallRoots(config, overrides) {
|
|
92
|
+
const installRoots = [];
|
|
93
|
+
for (const override of overrides) {
|
|
94
|
+
const installRecord = config.plugins.installs?.[override.pluginId];
|
|
95
|
+
const installPath = readOptionalString(installRecord?.installPath);
|
|
96
|
+
if (!installPath || installRoots.includes(installPath)) continue;
|
|
97
|
+
installRoots.push(installPath);
|
|
98
|
+
}
|
|
99
|
+
return installRoots;
|
|
100
|
+
}
|
|
101
|
+
function resolveDevPluginLoadingContext(config, workspaceExtensionsDir, rawOverridesEnv = process.env[DEV_PLUGIN_OVERRIDES_ENV]) {
|
|
102
|
+
const configWithFirstPartyOverrides = applyDevFirstPartyPluginLoadPaths(config, workspaceExtensionsDir);
|
|
103
|
+
const overrides = resolveDevPluginOverrides(rawOverridesEnv);
|
|
104
|
+
return {
|
|
105
|
+
configWithDevPluginOverrides: applyExplicitDevPluginOverrides(configWithFirstPartyOverrides, overrides),
|
|
106
|
+
excludedRoots: [...resolveDevFirstPartyPluginInstallRoots(config, workspaceExtensionsDir), ...resolveDevPluginOverrideInstallRoots(config, overrides)].filter((entry, index, list) => list.indexOf(entry) === index),
|
|
107
|
+
overrides
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
111
|
+
export { DEV_PLUGIN_OVERRIDES_ENV, resolveDevPluginLoadingContext, resolveDevPluginOverrides };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Config } from "@nextclaw/core";
|
|
2
|
+
|
|
3
|
+
//#region src/commands/plugin/development-source/first-party-plugin-load-paths.d.ts
|
|
4
|
+
declare const resolveDevFirstPartyPluginDir: (explicitDir: string | undefined, moduleDir?: string) => string | undefined;
|
|
5
|
+
declare const resolveDevFirstPartyPluginLoadPaths: (config: Config, workspaceExtensionsDir: string | undefined) => string[];
|
|
6
|
+
declare const resolveDevFirstPartyPluginInstallRoots: (config: Config, workspaceExtensionsDir: string | undefined) => string[];
|
|
7
|
+
declare const applyDevFirstPartyPluginLoadPaths: (config: Config, workspaceExtensionsDir: string | undefined) => Config;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { applyDevFirstPartyPluginLoadPaths, resolveDevFirstPartyPluginDir, resolveDevFirstPartyPluginInstallRoots, resolveDevFirstPartyPluginLoadPaths };
|