@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,85 @@
|
|
|
1
|
+
//#region src/shared/services/session/service-deferred-ncp-agent.service.ts
|
|
2
|
+
const DEFAULT_BASE_PATH = "/api/ncp/agent";
|
|
3
|
+
const DEFERRED_NCP_AGENT_UNAVAILABLE = "ncp agent unavailable during startup";
|
|
4
|
+
function createUnavailableError() {
|
|
5
|
+
return new Error(DEFERRED_NCP_AGENT_UNAVAILABLE);
|
|
6
|
+
}
|
|
7
|
+
var DeferredUiNcpAgentControllerOwner = class {
|
|
8
|
+
agent;
|
|
9
|
+
activeAgent = null;
|
|
10
|
+
endpoint = {
|
|
11
|
+
manifest: {
|
|
12
|
+
endpointKind: "agent",
|
|
13
|
+
endpointId: "nextclaw-ui-agent-deferred",
|
|
14
|
+
version: "0.0.0",
|
|
15
|
+
supportsStreaming: true,
|
|
16
|
+
supportsAbort: true,
|
|
17
|
+
supportsProactiveMessages: false,
|
|
18
|
+
supportsLiveSessionStream: true,
|
|
19
|
+
supportedPartTypes: ["text"],
|
|
20
|
+
expectedLatency: "seconds",
|
|
21
|
+
metadata: { deferred: true }
|
|
22
|
+
},
|
|
23
|
+
start: async () => {
|
|
24
|
+
await this.activeAgent?.agentClientEndpoint.start();
|
|
25
|
+
},
|
|
26
|
+
stop: async () => {
|
|
27
|
+
await this.activeAgent?.agentClientEndpoint.stop();
|
|
28
|
+
},
|
|
29
|
+
emit: async (event) => {
|
|
30
|
+
if (!this.activeAgent) throw createUnavailableError();
|
|
31
|
+
await this.activeAgent.agentClientEndpoint.emit(event);
|
|
32
|
+
},
|
|
33
|
+
subscribe: (listener) => {
|
|
34
|
+
if (!this.activeAgent) return () => void 0;
|
|
35
|
+
return this.activeAgent.agentClientEndpoint.subscribe(listener);
|
|
36
|
+
},
|
|
37
|
+
send: async (envelope) => {
|
|
38
|
+
if (!this.activeAgent) throw createUnavailableError();
|
|
39
|
+
await this.activeAgent.agentClientEndpoint.send(envelope);
|
|
40
|
+
},
|
|
41
|
+
stream: async (payload) => {
|
|
42
|
+
if (!this.activeAgent) throw createUnavailableError();
|
|
43
|
+
await this.activeAgent.agentClientEndpoint.stream(payload);
|
|
44
|
+
},
|
|
45
|
+
abort: async (payload) => {
|
|
46
|
+
if (!this.activeAgent) throw createUnavailableError();
|
|
47
|
+
await this.activeAgent.agentClientEndpoint.abort(payload);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
constructor(basePath) {
|
|
51
|
+
this.basePath = basePath;
|
|
52
|
+
this.agent = {
|
|
53
|
+
basePath,
|
|
54
|
+
agentClientEndpoint: this.endpoint
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
activate = (nextAgent) => {
|
|
58
|
+
this.activeAgent = nextAgent;
|
|
59
|
+
this.agent.basePath = nextAgent.basePath ?? this.basePath;
|
|
60
|
+
this.agent.streamProvider = nextAgent.streamProvider;
|
|
61
|
+
this.agent.listSessionTypes = nextAgent.listSessionTypes;
|
|
62
|
+
this.agent.assetApi = nextAgent.assetApi;
|
|
63
|
+
};
|
|
64
|
+
clear = () => {
|
|
65
|
+
this.activeAgent = null;
|
|
66
|
+
this.agent.basePath = this.basePath;
|
|
67
|
+
this.agent.streamProvider = void 0;
|
|
68
|
+
this.agent.listSessionTypes = void 0;
|
|
69
|
+
this.agent.assetApi = void 0;
|
|
70
|
+
};
|
|
71
|
+
close = async () => {
|
|
72
|
+
const current = this.activeAgent;
|
|
73
|
+
this.clear();
|
|
74
|
+
await current?.agentClientEndpoint.stop();
|
|
75
|
+
await current?.dispose?.();
|
|
76
|
+
};
|
|
77
|
+
isReady = () => {
|
|
78
|
+
return this.activeAgent !== null;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
function createDeferredUiNcpAgent(basePath = DEFAULT_BASE_PATH) {
|
|
82
|
+
return new DeferredUiNcpAgentControllerOwner(basePath);
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
export { createDeferredUiNcpAgent };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { LocalUiDiscoveryService } from "./local-ui-discovery.service.js";
|
|
2
|
+
import { CompanionRuntimeState, CompanionRuntimeStore } from "../../stores/companion-runtime.store.js";
|
|
3
|
+
import { Config } from "@nextclaw/core";
|
|
4
|
+
|
|
5
|
+
//#region src/shared/services/ui/companion-runtime.service.d.ts
|
|
6
|
+
declare class CompanionRuntimeService {
|
|
7
|
+
private readonly runtimeStore;
|
|
8
|
+
private readonly uiDiscoveryService;
|
|
9
|
+
constructor(runtimeStore?: CompanionRuntimeStore, uiDiscoveryService?: LocalUiDiscoveryService);
|
|
10
|
+
readonly getRunningState: () => CompanionRuntimeState | null;
|
|
11
|
+
readonly resolveDiscoveredBaseUrl: () => string | null;
|
|
12
|
+
readonly applyConfig: (config: Config) => Promise<void>;
|
|
13
|
+
readonly updateEnabled: (enabled: boolean, options?: {
|
|
14
|
+
baseUrl?: string;
|
|
15
|
+
}) => Promise<Config>;
|
|
16
|
+
readonly ensureStarted: (options: {
|
|
17
|
+
baseUrl: string;
|
|
18
|
+
}) => Promise<CompanionRuntimeState>;
|
|
19
|
+
readonly ensureStopped: (options?: {
|
|
20
|
+
force?: boolean;
|
|
21
|
+
}) => Promise<boolean>;
|
|
22
|
+
readonly printStatus: (options?: {
|
|
23
|
+
json?: boolean;
|
|
24
|
+
}) => void;
|
|
25
|
+
readonly printStarted: (state: CompanionRuntimeState) => void;
|
|
26
|
+
readonly printStopped: (stopped: boolean) => void;
|
|
27
|
+
private readonly killProcess;
|
|
28
|
+
private readonly resolveLaunchSpec;
|
|
29
|
+
private readonly waitForRunningState;
|
|
30
|
+
}
|
|
31
|
+
declare const companionRuntimeService: CompanionRuntimeService;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { CompanionRuntimeService, companionRuntimeService };
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { isProcessRunning } from "../../utils/cli.utils.js";
|
|
2
|
+
import { companionRuntimeStore } from "../../stores/companion-runtime.store.js";
|
|
3
|
+
import { localUiDiscoveryService } from "./local-ui-discovery.service.js";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { spawn } from "node:child_process";
|
|
6
|
+
import { dirname, resolve } from "node:path";
|
|
7
|
+
import { APP_NAME, getConfigPath, loadConfig, saveConfig } from "@nextclaw/core";
|
|
8
|
+
import { existsSync } from "node:fs";
|
|
9
|
+
//#region src/shared/services/ui/companion-runtime.service.ts
|
|
10
|
+
const require = createRequire(import.meta.url);
|
|
11
|
+
var CompanionRuntimeService = class {
|
|
12
|
+
constructor(runtimeStore = companionRuntimeStore, uiDiscoveryService = localUiDiscoveryService) {
|
|
13
|
+
this.runtimeStore = runtimeStore;
|
|
14
|
+
this.uiDiscoveryService = uiDiscoveryService;
|
|
15
|
+
}
|
|
16
|
+
getRunningState = () => {
|
|
17
|
+
const state = this.runtimeStore.read();
|
|
18
|
+
if (!state) return null;
|
|
19
|
+
if (!isProcessRunning(state.pid)) {
|
|
20
|
+
this.runtimeStore.clear();
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return state;
|
|
24
|
+
};
|
|
25
|
+
resolveDiscoveredBaseUrl = () => {
|
|
26
|
+
return this.uiDiscoveryService.resolveApiBase();
|
|
27
|
+
};
|
|
28
|
+
applyConfig = async (config) => {
|
|
29
|
+
if (!config.companion.enabled) {
|
|
30
|
+
await this.ensureStopped();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
await this.ensureStarted({ baseUrl: this.uiDiscoveryService.resolveLocalOrigin(config) });
|
|
34
|
+
};
|
|
35
|
+
updateEnabled = async (enabled, options = {}) => {
|
|
36
|
+
const config = loadConfig(getConfigPath());
|
|
37
|
+
const next = {
|
|
38
|
+
...config,
|
|
39
|
+
companion: {
|
|
40
|
+
...config.companion,
|
|
41
|
+
enabled
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
saveConfig(next, getConfigPath());
|
|
45
|
+
if (enabled) {
|
|
46
|
+
const explicitBaseUrl = options.baseUrl?.trim();
|
|
47
|
+
if (explicitBaseUrl) {
|
|
48
|
+
await this.ensureStarted({ baseUrl: explicitBaseUrl });
|
|
49
|
+
return next;
|
|
50
|
+
}
|
|
51
|
+
const discoveredBaseUrl = this.uiDiscoveryService.resolveApiBase();
|
|
52
|
+
if (discoveredBaseUrl) await this.ensureStarted({ baseUrl: discoveredBaseUrl });
|
|
53
|
+
return next;
|
|
54
|
+
}
|
|
55
|
+
await this.ensureStopped();
|
|
56
|
+
return next;
|
|
57
|
+
};
|
|
58
|
+
ensureStarted = async (options) => {
|
|
59
|
+
const baseUrl = options.baseUrl.trim().replace(/\/+$/, "");
|
|
60
|
+
const runningState = this.getRunningState();
|
|
61
|
+
if (runningState?.baseUrl === baseUrl) return runningState;
|
|
62
|
+
if (runningState) {
|
|
63
|
+
this.killProcess(runningState.pid, false);
|
|
64
|
+
this.runtimeStore.clear();
|
|
65
|
+
}
|
|
66
|
+
const launchSpec = this.resolveLaunchSpec();
|
|
67
|
+
const child = spawn(launchSpec.command, [
|
|
68
|
+
...launchSpec.args,
|
|
69
|
+
"--base-url",
|
|
70
|
+
baseUrl
|
|
71
|
+
], {
|
|
72
|
+
detached: true,
|
|
73
|
+
stdio: "ignore",
|
|
74
|
+
env: {
|
|
75
|
+
...process.env,
|
|
76
|
+
NEXTCLAW_COMPANION_RUNTIME_STATE_PATH: this.runtimeStore.path
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
child.unref();
|
|
80
|
+
return await this.waitForRunningState(baseUrl, child.pid ?? -1);
|
|
81
|
+
};
|
|
82
|
+
ensureStopped = async (options = {}) => {
|
|
83
|
+
const state = this.runtimeStore.read();
|
|
84
|
+
if (!state) return false;
|
|
85
|
+
if (!isProcessRunning(state.pid)) {
|
|
86
|
+
this.runtimeStore.clear();
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
this.killProcess(state.pid, options.force === true);
|
|
90
|
+
this.runtimeStore.clear();
|
|
91
|
+
return true;
|
|
92
|
+
};
|
|
93
|
+
printStatus = (options = {}) => {
|
|
94
|
+
const runningState = this.getRunningState();
|
|
95
|
+
const config = loadConfig(getConfigPath());
|
|
96
|
+
const view = runningState ? {
|
|
97
|
+
configuredEnabled: config.companion.enabled,
|
|
98
|
+
running: true,
|
|
99
|
+
...runningState
|
|
100
|
+
} : {
|
|
101
|
+
configuredEnabled: config.companion.enabled,
|
|
102
|
+
running: false
|
|
103
|
+
};
|
|
104
|
+
if (options.json) {
|
|
105
|
+
console.log(JSON.stringify(view, null, 2));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (!runningState) {
|
|
109
|
+
console.log(config.companion.enabled ? "Companion is enabled in config but is not running." : "Companion is disabled and not running.");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
console.log(`Companion is running (pid ${runningState.pid}) at ${runningState.baseUrl}. Configured enabled: ${config.companion.enabled ? "yes" : "no"}.`);
|
|
113
|
+
};
|
|
114
|
+
printStarted = (state) => {
|
|
115
|
+
console.log(`Started ${APP_NAME} companion (pid ${state.pid}) using ${state.baseUrl}.`);
|
|
116
|
+
};
|
|
117
|
+
printStopped = (stopped) => {
|
|
118
|
+
console.log(stopped ? "Stopped companion process." : "Companion is not running.");
|
|
119
|
+
};
|
|
120
|
+
killProcess = (pid, force) => {
|
|
121
|
+
process.kill(pid, force ? "SIGKILL" : "SIGTERM");
|
|
122
|
+
};
|
|
123
|
+
resolveLaunchSpec = () => {
|
|
124
|
+
const packageJsonPath = require.resolve("@nextclaw/companion/package.json");
|
|
125
|
+
const packageRoot = dirname(packageJsonPath);
|
|
126
|
+
const mainPath = resolve(packageRoot, "dist", "src", "main.js");
|
|
127
|
+
if (!existsSync(mainPath)) throw new Error(`Companion app build is missing at ${mainPath}. Build @nextclaw/companion first.`);
|
|
128
|
+
return {
|
|
129
|
+
command: createRequire(packageJsonPath)("electron"),
|
|
130
|
+
args: [packageRoot]
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
waitForRunningState = async (baseUrl, fallbackPid) => {
|
|
134
|
+
const timeoutAt = Date.now() + 5e3;
|
|
135
|
+
while (Date.now() < timeoutAt) {
|
|
136
|
+
const state = this.getRunningState();
|
|
137
|
+
if (state?.baseUrl === baseUrl) return state;
|
|
138
|
+
await new Promise((resolvePromise) => setTimeout(resolvePromise, 100));
|
|
139
|
+
}
|
|
140
|
+
throw new Error(fallbackPid > 0 ? `Companion started but did not report a live runtime state (launcher pid ${fallbackPid}).` : "Companion started but did not report a live runtime state.");
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
const companionRuntimeService = new CompanionRuntimeService();
|
|
144
|
+
//#endregion
|
|
145
|
+
export { CompanionRuntimeService, companionRuntimeService };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ManagedServiceState, ManagedServiceStateStore } from "../../stores/managed-service-state.store.js";
|
|
2
|
+
import { LocalUiRuntimeState, LocalUiRuntimeStore } from "../../stores/local-ui-runtime.store.js";
|
|
3
|
+
import { Config } from "@nextclaw/core";
|
|
4
|
+
|
|
5
|
+
//#region src/shared/services/ui/local-ui-discovery.service.d.ts
|
|
6
|
+
type DiscoveredLocalUiState = LocalUiRuntimeState | ManagedServiceState;
|
|
7
|
+
declare class LocalUiDiscoveryService {
|
|
8
|
+
private readonly localUiStore;
|
|
9
|
+
private readonly managedServiceStore;
|
|
10
|
+
private readonly isProcessRunningFn;
|
|
11
|
+
constructor(localUiStore?: LocalUiRuntimeStore, managedServiceStore?: ManagedServiceStateStore, isProcessRunningFn?: (pid: number) => boolean);
|
|
12
|
+
private readonly readRunningState;
|
|
13
|
+
readonly readRunningRuntimeState: () => DiscoveredLocalUiState | null;
|
|
14
|
+
readonly resolveApiBase: () => string | null;
|
|
15
|
+
readonly resolveLocalOrigin: (config: Config) => string;
|
|
16
|
+
}
|
|
17
|
+
declare const localUiDiscoveryService: LocalUiDiscoveryService;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { LocalUiDiscoveryService, localUiDiscoveryService };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { isProcessRunning } from "../../utils/cli.utils.js";
|
|
2
|
+
import { localUiRuntimeStore } from "../../stores/local-ui-runtime.store.js";
|
|
3
|
+
import { managedServiceStateStore } from "../../stores/managed-service-state.store.js";
|
|
4
|
+
import { resolveLocalUiBaseUrl } from "@nextclaw/core";
|
|
5
|
+
//#region src/shared/services/ui/local-ui-discovery.service.ts
|
|
6
|
+
var LocalUiDiscoveryService = class {
|
|
7
|
+
constructor(localUiStore = localUiRuntimeStore, managedServiceStore = managedServiceStateStore, isProcessRunningFn = (pid) => isProcessRunning(pid)) {
|
|
8
|
+
this.localUiStore = localUiStore;
|
|
9
|
+
this.managedServiceStore = managedServiceStore;
|
|
10
|
+
this.isProcessRunningFn = isProcessRunningFn;
|
|
11
|
+
}
|
|
12
|
+
readRunningState = (state) => {
|
|
13
|
+
if (!state || !this.isProcessRunningFn(state.pid)) return null;
|
|
14
|
+
return state;
|
|
15
|
+
};
|
|
16
|
+
readRunningRuntimeState = () => {
|
|
17
|
+
return this.readRunningState(this.localUiStore.read()) ?? this.readRunningState(this.managedServiceStore.read());
|
|
18
|
+
};
|
|
19
|
+
resolveApiBase = () => {
|
|
20
|
+
const state = this.readRunningRuntimeState();
|
|
21
|
+
if (!state) return null;
|
|
22
|
+
if (typeof state.uiUrl === "string" && state.uiUrl.trim().length > 0) return state.uiUrl.replace(/\/+$/, "");
|
|
23
|
+
if (typeof state.apiUrl === "string" && state.apiUrl.trim().length > 0) return state.apiUrl.replace(/\/api\/?$/, "").replace(/\/+$/, "");
|
|
24
|
+
return null;
|
|
25
|
+
};
|
|
26
|
+
resolveLocalOrigin = (config) => {
|
|
27
|
+
const state = this.readRunningRuntimeState();
|
|
28
|
+
const runtimePort = state && typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : null;
|
|
29
|
+
if (runtimePort !== null) return resolveLocalUiBaseUrl({
|
|
30
|
+
host: "0.0.0.0",
|
|
31
|
+
port: runtimePort
|
|
32
|
+
});
|
|
33
|
+
return resolveLocalUiBaseUrl({
|
|
34
|
+
host: "0.0.0.0",
|
|
35
|
+
port: typeof config.ui.port === "number" && Number.isFinite(config.ui.port) ? config.ui.port : 55667
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
const localUiDiscoveryService = new LocalUiDiscoveryService();
|
|
40
|
+
//#endregion
|
|
41
|
+
export { LocalUiDiscoveryService, localUiDiscoveryService };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { RequestRestartParams } from "../../types/cli.types.js";
|
|
2
|
+
import { Config } from "@nextclaw/core";
|
|
3
|
+
import { UiRuntimeUpdateHost } from "@nextclaw/server";
|
|
4
|
+
import { EventBus, UpdatePreferences, UpdateSnapshot } from "@nextclaw/shared";
|
|
5
|
+
|
|
6
|
+
//#region src/shared/services/ui/npm-runtime-update-host.service.d.ts
|
|
7
|
+
type NpmRuntimeUpdateHostDeps = {
|
|
8
|
+
eventBus: EventBus;
|
|
9
|
+
requestRestart: (params: RequestRestartParams) => Promise<void>;
|
|
10
|
+
uiConfig: Pick<Config["ui"], "port">;
|
|
11
|
+
applyRestartMode: "managed-service-restart" | "manual-process-restart";
|
|
12
|
+
};
|
|
13
|
+
declare class NpmRuntimeUpdateHost implements UiRuntimeUpdateHost {
|
|
14
|
+
private readonly deps;
|
|
15
|
+
private readonly source;
|
|
16
|
+
private readonly layout;
|
|
17
|
+
private readonly launcherVersion;
|
|
18
|
+
private readonly stateStore;
|
|
19
|
+
private readonly bundleService;
|
|
20
|
+
private readonly updateService;
|
|
21
|
+
private snapshot;
|
|
22
|
+
private activeTask;
|
|
23
|
+
private automaticSyncStarted;
|
|
24
|
+
constructor(deps: NpmRuntimeUpdateHostDeps);
|
|
25
|
+
getState: () => Promise<UpdateSnapshot>;
|
|
26
|
+
checkForUpdates: () => Promise<UpdateSnapshot>;
|
|
27
|
+
downloadUpdate: () => Promise<UpdateSnapshot>;
|
|
28
|
+
applyDownloadedUpdate: () => Promise<UpdateSnapshot>;
|
|
29
|
+
updatePreferences: (preferences: Partial<UpdatePreferences>) => Promise<UpdateSnapshot>;
|
|
30
|
+
updateChannel: (channel: UpdateSnapshot["channel"]) => Promise<UpdateSnapshot>;
|
|
31
|
+
private startAutomaticSync;
|
|
32
|
+
private startCheck;
|
|
33
|
+
private startDownload;
|
|
34
|
+
private runDownloadTask;
|
|
35
|
+
private createManager;
|
|
36
|
+
private toFailedSnapshot;
|
|
37
|
+
private setSnapshot;
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { NpmRuntimeUpdateHost };
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { NpmRuntimeBundleLayoutStore } from "../../../launcher/npm-runtime-bundle-layout.store.js";
|
|
2
|
+
import { NpmRuntimeBundleService } from "../../../launcher/npm-runtime-bundle.service.js";
|
|
3
|
+
import { NpmRuntimeUpdateSourceService } from "../../../launcher/npm-runtime-update-source.service.js";
|
|
4
|
+
import { NpmRuntimeUpdateStateStore } from "../../../launcher/npm-runtime-update-state.store.js";
|
|
5
|
+
import { getPackageVersion } from "../../utils/package/package-manifest.utils.js";
|
|
6
|
+
import "../../utils/cli.utils.js";
|
|
7
|
+
import { NpmRuntimeUpdateManager } from "../../../launcher/npm-runtime-update.manager.js";
|
|
8
|
+
import { NpmRuntimeUpdateService } from "../../../launcher/npm-runtime-update.service.js";
|
|
9
|
+
import { requestManagedServiceRestart } from "./service-remote-access.service.js";
|
|
10
|
+
import { eventKeys } from "@nextclaw/shared";
|
|
11
|
+
//#region src/shared/services/ui/npm-runtime-update-host.service.ts
|
|
12
|
+
const INITIAL_DOWNLOAD_PROGRESS = {
|
|
13
|
+
downloadedBytes: 0,
|
|
14
|
+
totalBytes: null,
|
|
15
|
+
percent: null
|
|
16
|
+
};
|
|
17
|
+
var NpmRuntimeUpdateHost = class {
|
|
18
|
+
source = new NpmRuntimeUpdateSourceService();
|
|
19
|
+
layout = new NpmRuntimeBundleLayoutStore();
|
|
20
|
+
launcherVersion = getPackageVersion();
|
|
21
|
+
stateStore = new NpmRuntimeUpdateStateStore(this.layout.getStatePath(), { defaultChannel: this.source.resolveChannel(void 0, this.launcherVersion) });
|
|
22
|
+
bundleService = new NpmRuntimeBundleService({
|
|
23
|
+
layout: this.layout,
|
|
24
|
+
stateStore: this.stateStore,
|
|
25
|
+
launcherVersion: this.launcherVersion
|
|
26
|
+
});
|
|
27
|
+
updateService = new NpmRuntimeUpdateService({
|
|
28
|
+
layout: this.layout,
|
|
29
|
+
bundleService: this.bundleService,
|
|
30
|
+
launcherVersion: this.launcherVersion,
|
|
31
|
+
bundlePublicKey: this.source.resolveBundlePublicKey() ?? void 0
|
|
32
|
+
});
|
|
33
|
+
snapshot;
|
|
34
|
+
activeTask = null;
|
|
35
|
+
automaticSyncStarted = false;
|
|
36
|
+
constructor(deps) {
|
|
37
|
+
this.deps = deps;
|
|
38
|
+
this.snapshot = this.createManager().getSnapshot();
|
|
39
|
+
this.startAutomaticSync();
|
|
40
|
+
}
|
|
41
|
+
getState = async () => {
|
|
42
|
+
this.startAutomaticSync();
|
|
43
|
+
return this.snapshot;
|
|
44
|
+
};
|
|
45
|
+
checkForUpdates = async () => {
|
|
46
|
+
return this.startCheck({ autoDownload: false });
|
|
47
|
+
};
|
|
48
|
+
downloadUpdate = async () => {
|
|
49
|
+
return this.startDownload();
|
|
50
|
+
};
|
|
51
|
+
applyDownloadedUpdate = async () => {
|
|
52
|
+
if (this.activeTask) return this.snapshot;
|
|
53
|
+
this.setSnapshot({
|
|
54
|
+
...this.snapshot,
|
|
55
|
+
status: "applying",
|
|
56
|
+
progress: null,
|
|
57
|
+
errorMessage: null
|
|
58
|
+
});
|
|
59
|
+
try {
|
|
60
|
+
const snapshot = this.createManager().applyDownloadedUpdate();
|
|
61
|
+
this.setSnapshot(this.deps.applyRestartMode === "managed-service-restart" ? snapshot : {
|
|
62
|
+
...snapshot,
|
|
63
|
+
recoveryCommand: "Restart this NextClaw process to launch the downloaded runtime."
|
|
64
|
+
});
|
|
65
|
+
if (this.deps.applyRestartMode === "managed-service-restart") await requestManagedServiceRestart(this.deps.requestRestart, {
|
|
66
|
+
reason: "runtime update apply",
|
|
67
|
+
uiPort: this.deps.uiConfig.port
|
|
68
|
+
});
|
|
69
|
+
return this.snapshot;
|
|
70
|
+
} catch (error) {
|
|
71
|
+
this.setSnapshot(this.toFailedSnapshot(error));
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
updatePreferences = async (preferences) => {
|
|
76
|
+
const nextState = this.stateStore.update((current) => ({
|
|
77
|
+
...current,
|
|
78
|
+
updatePreferences: {
|
|
79
|
+
...current.updatePreferences,
|
|
80
|
+
...preferences
|
|
81
|
+
}
|
|
82
|
+
}));
|
|
83
|
+
this.setSnapshot(this.createManager(nextState.channel).getSnapshot());
|
|
84
|
+
if (nextState.updatePreferences.automaticChecks) this.startAutomaticSync({ force: true });
|
|
85
|
+
return this.snapshot;
|
|
86
|
+
};
|
|
87
|
+
updateChannel = async (channel) => {
|
|
88
|
+
const nextState = this.stateStore.update((current) => ({
|
|
89
|
+
...current,
|
|
90
|
+
channel
|
|
91
|
+
}));
|
|
92
|
+
this.setSnapshot(this.createManager(nextState.channel).getSnapshot());
|
|
93
|
+
if (nextState.updatePreferences.automaticChecks) return this.startCheck({ autoDownload: nextState.updatePreferences.autoDownload });
|
|
94
|
+
return this.snapshot;
|
|
95
|
+
};
|
|
96
|
+
startAutomaticSync = (options = {}) => {
|
|
97
|
+
if (this.activeTask) return;
|
|
98
|
+
if (this.automaticSyncStarted && !options.force) return;
|
|
99
|
+
this.automaticSyncStarted = true;
|
|
100
|
+
const state = this.stateStore.read();
|
|
101
|
+
if (!state.updatePreferences.automaticChecks || state.downloadedVersion) return;
|
|
102
|
+
this.startCheck({ autoDownload: state.updatePreferences.autoDownload });
|
|
103
|
+
};
|
|
104
|
+
startCheck = async (options) => {
|
|
105
|
+
if (this.activeTask) return this.snapshot;
|
|
106
|
+
this.setSnapshot({
|
|
107
|
+
...this.createManager().getSnapshot(),
|
|
108
|
+
status: "checking",
|
|
109
|
+
progress: null,
|
|
110
|
+
errorMessage: null
|
|
111
|
+
});
|
|
112
|
+
this.activeTask = (async () => {
|
|
113
|
+
try {
|
|
114
|
+
const checkedSnapshot = await this.createManager().checkForUpdate();
|
|
115
|
+
this.setSnapshot(checkedSnapshot);
|
|
116
|
+
if (options.autoDownload && checkedSnapshot.status === "update-available") await this.runDownloadTask();
|
|
117
|
+
} catch (error) {
|
|
118
|
+
this.setSnapshot(this.toFailedSnapshot(error));
|
|
119
|
+
} finally {
|
|
120
|
+
this.activeTask = null;
|
|
121
|
+
}
|
|
122
|
+
})();
|
|
123
|
+
return this.snapshot;
|
|
124
|
+
};
|
|
125
|
+
startDownload = async () => {
|
|
126
|
+
if (this.activeTask) return this.snapshot;
|
|
127
|
+
this.setSnapshot({
|
|
128
|
+
...this.createManager().getSnapshot(),
|
|
129
|
+
status: "downloading",
|
|
130
|
+
progress: INITIAL_DOWNLOAD_PROGRESS,
|
|
131
|
+
errorMessage: null
|
|
132
|
+
});
|
|
133
|
+
this.activeTask = (async () => {
|
|
134
|
+
try {
|
|
135
|
+
await this.runDownloadTask();
|
|
136
|
+
} catch (error) {
|
|
137
|
+
this.setSnapshot(this.toFailedSnapshot(error));
|
|
138
|
+
} finally {
|
|
139
|
+
this.activeTask = null;
|
|
140
|
+
}
|
|
141
|
+
})();
|
|
142
|
+
return this.snapshot;
|
|
143
|
+
};
|
|
144
|
+
runDownloadTask = async () => {
|
|
145
|
+
const downloadedSnapshot = await this.createManager().downloadUpdate((progress) => {
|
|
146
|
+
this.setSnapshot({
|
|
147
|
+
...this.snapshot,
|
|
148
|
+
status: "downloading",
|
|
149
|
+
progress,
|
|
150
|
+
errorMessage: null
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
this.setSnapshot(downloadedSnapshot);
|
|
154
|
+
};
|
|
155
|
+
createManager = (channel = this.stateStore.read().channel) => {
|
|
156
|
+
return new NpmRuntimeUpdateManager({
|
|
157
|
+
layout: this.layout,
|
|
158
|
+
stateStore: this.stateStore,
|
|
159
|
+
bundleService: this.bundleService,
|
|
160
|
+
updateService: this.updateService,
|
|
161
|
+
resolveManifestUrl: (resolvedChannel) => this.source.resolveManifestUrl(resolvedChannel),
|
|
162
|
+
launcherVersion: this.launcherVersion,
|
|
163
|
+
channel
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
toFailedSnapshot = (error) => {
|
|
167
|
+
return {
|
|
168
|
+
...this.createManager().getSnapshot(),
|
|
169
|
+
status: "failed",
|
|
170
|
+
progress: null,
|
|
171
|
+
errorMessage: error instanceof Error ? error.message : String(error ?? "Unknown error")
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
setSnapshot = (snapshot) => {
|
|
175
|
+
this.snapshot = snapshot;
|
|
176
|
+
this.deps.eventBus.emit(eventKeys.runtimeUpdateSnapshot, snapshot, { source: "backend" });
|
|
177
|
+
return snapshot;
|
|
178
|
+
};
|
|
179
|
+
};
|
|
180
|
+
//#endregion
|
|
181
|
+
export { NpmRuntimeUpdateHost };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { RequestRestartParams } from "../../types/cli.types.js";
|
|
2
|
+
import { Config } from "@nextclaw/core";
|
|
3
|
+
import { RuntimeControlActionResult, RuntimeControlView, UiRuntimeControlHost } from "@nextclaw/server";
|
|
4
|
+
|
|
5
|
+
//#region src/shared/services/ui/runtime-control-host.service.d.ts
|
|
6
|
+
type RuntimeControlHostDeps = {
|
|
7
|
+
serviceCommands: {
|
|
8
|
+
startService: (options: {
|
|
9
|
+
uiOverrides: Record<string, unknown>;
|
|
10
|
+
open: boolean;
|
|
11
|
+
}) => Promise<void>;
|
|
12
|
+
stopService: () => Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
requestRestart: (params: RequestRestartParams) => Promise<void>;
|
|
15
|
+
uiConfig: Pick<Config["ui"], "host" | "port">;
|
|
16
|
+
};
|
|
17
|
+
declare class RuntimeControlHost implements UiRuntimeControlHost {
|
|
18
|
+
private readonly deps;
|
|
19
|
+
constructor(deps: RuntimeControlHostDeps);
|
|
20
|
+
getControl: () => RuntimeControlView;
|
|
21
|
+
startService: () => Promise<RuntimeControlActionResult>;
|
|
22
|
+
restartService: () => Promise<RuntimeControlActionResult>;
|
|
23
|
+
stopService: () => Promise<RuntimeControlActionResult>;
|
|
24
|
+
private createServiceControlDeps;
|
|
25
|
+
}
|
|
26
|
+
declare function createRuntimeControlHost(params: RuntimeControlHostDeps): RuntimeControlHost;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { RuntimeControlHost, createRuntimeControlHost };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { pendingRestartStore } from "../../stores/pending-restart.store.js";
|
|
2
|
+
import { controlRemoteService, resolveRemoteServiceView } from "../../../commands/remote/services/remote-service-control.service.js";
|
|
3
|
+
import { requestManagedServiceRestart } from "./service-remote-access.service.js";
|
|
4
|
+
//#region src/shared/services/ui/runtime-control-host.service.ts
|
|
5
|
+
const MANAGED_SERVICE_OWNER_LABEL = "Managed local service";
|
|
6
|
+
const DESKTOP_APP_ONLY_REASON = "App restart is only available in the desktop shell.";
|
|
7
|
+
const RUNNING_PAGE_START_REASON = "This page is already hosted by the running local service.";
|
|
8
|
+
var RuntimeControlHost = class {
|
|
9
|
+
constructor(deps) {
|
|
10
|
+
this.deps = deps;
|
|
11
|
+
}
|
|
12
|
+
getControl = () => {
|
|
13
|
+
const service = resolveRemoteServiceView(this.deps.uiConfig);
|
|
14
|
+
const serviceRunning = service.running;
|
|
15
|
+
const pendingRestart = pendingRestartStore.read();
|
|
16
|
+
return {
|
|
17
|
+
environment: "managed-local-service",
|
|
18
|
+
lifecycle: serviceRunning ? "healthy" : "unavailable",
|
|
19
|
+
serviceState: serviceRunning ? "running" : "stopped",
|
|
20
|
+
canStartService: {
|
|
21
|
+
available: !serviceRunning,
|
|
22
|
+
requiresConfirmation: false,
|
|
23
|
+
impact: "brief-ui-disconnect",
|
|
24
|
+
...serviceRunning ? { reasonIfUnavailable: RUNNING_PAGE_START_REASON } : {}
|
|
25
|
+
},
|
|
26
|
+
canRestartService: {
|
|
27
|
+
available: serviceRunning,
|
|
28
|
+
requiresConfirmation: false,
|
|
29
|
+
impact: "brief-ui-disconnect",
|
|
30
|
+
...!serviceRunning ? { reasonIfUnavailable: "The local service is not running." } : {}
|
|
31
|
+
},
|
|
32
|
+
canStopService: {
|
|
33
|
+
available: serviceRunning,
|
|
34
|
+
requiresConfirmation: true,
|
|
35
|
+
impact: "brief-ui-disconnect",
|
|
36
|
+
...!serviceRunning ? { reasonIfUnavailable: "The local service is already stopped." } : {}
|
|
37
|
+
},
|
|
38
|
+
canRestartApp: {
|
|
39
|
+
available: false,
|
|
40
|
+
requiresConfirmation: true,
|
|
41
|
+
impact: "full-app-relaunch",
|
|
42
|
+
reasonIfUnavailable: DESKTOP_APP_ONLY_REASON
|
|
43
|
+
},
|
|
44
|
+
pendingRestart,
|
|
45
|
+
ownerLabel: MANAGED_SERVICE_OWNER_LABEL,
|
|
46
|
+
managementHint: service.currentProcess ? "This page is served by the running local service. Closing the browser does not stop it." : "Manage the local NextClaw service from this page without tying service lifecycle to the browser tab.",
|
|
47
|
+
message: "Use this page to manage the local NextClaw service. Closing the browser does not stop the service."
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
startService = async () => {
|
|
51
|
+
const result = await controlRemoteService("start", this.createServiceControlDeps());
|
|
52
|
+
return {
|
|
53
|
+
accepted: result.accepted,
|
|
54
|
+
action: "start-service",
|
|
55
|
+
lifecycle: "starting-service",
|
|
56
|
+
message: result.message
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
restartService = async () => {
|
|
60
|
+
const result = await controlRemoteService("restart", this.createServiceControlDeps());
|
|
61
|
+
return {
|
|
62
|
+
accepted: result.accepted,
|
|
63
|
+
action: "restart-service",
|
|
64
|
+
lifecycle: "restarting-service",
|
|
65
|
+
message: result.message
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
stopService = async () => {
|
|
69
|
+
const result = await controlRemoteService("stop", this.createServiceControlDeps());
|
|
70
|
+
return {
|
|
71
|
+
accepted: result.accepted,
|
|
72
|
+
action: "stop-service",
|
|
73
|
+
lifecycle: "stopping-service",
|
|
74
|
+
message: result.message
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
createServiceControlDeps = () => {
|
|
78
|
+
return {
|
|
79
|
+
serviceCommands: this.deps.serviceCommands,
|
|
80
|
+
requestManagedServiceRestart: () => requestManagedServiceRestart(this.deps.requestRestart, { uiPort: this.deps.uiConfig.port }),
|
|
81
|
+
currentUi: this.deps.uiConfig
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
function createRuntimeControlHost(params) {
|
|
86
|
+
return new RuntimeControlHost(params);
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
export { RuntimeControlHost, createRuntimeControlHost };
|