@nextclaw/server 0.12.5 → 0.12.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +62 -1
- package/dist/index.js +294 -34
- package/package.json +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -349,6 +349,37 @@ declare class UiAuthService {
|
|
|
349
349
|
};
|
|
350
350
|
}
|
|
351
351
|
//#endregion
|
|
352
|
+
//#region src/ui/runtime-control.types.d.ts
|
|
353
|
+
type RuntimeControlEnvironment = "desktop-embedded" | "managed-local-service" | "self-hosted-web" | "shared-web";
|
|
354
|
+
type RuntimeLifecycleState = "healthy" | "starting-service" | "restarting-service" | "stopping-service" | "restarting-app" | "recovering" | "unavailable" | "failed";
|
|
355
|
+
type RuntimeActionImpact = "none" | "brief-ui-disconnect" | "full-app-relaunch";
|
|
356
|
+
type RuntimeActionCapability = {
|
|
357
|
+
available: boolean;
|
|
358
|
+
requiresConfirmation: boolean;
|
|
359
|
+
impact: RuntimeActionImpact;
|
|
360
|
+
reasonIfUnavailable?: string;
|
|
361
|
+
};
|
|
362
|
+
type RuntimeServiceState = "running" | "stopped" | "starting" | "stopping" | "restarting" | "unknown";
|
|
363
|
+
type RuntimeControlView = {
|
|
364
|
+
environment: RuntimeControlEnvironment;
|
|
365
|
+
lifecycle: RuntimeLifecycleState;
|
|
366
|
+
serviceState: RuntimeServiceState;
|
|
367
|
+
canStartService: RuntimeActionCapability;
|
|
368
|
+
canRestartService: RuntimeActionCapability;
|
|
369
|
+
canStopService: RuntimeActionCapability;
|
|
370
|
+
canRestartApp: RuntimeActionCapability;
|
|
371
|
+
ownerLabel?: string;
|
|
372
|
+
managementHint?: string;
|
|
373
|
+
message?: string;
|
|
374
|
+
};
|
|
375
|
+
type RuntimeControlAction = "start-service" | "restart-service" | "stop-service" | "restart-app";
|
|
376
|
+
type RuntimeControlActionResult = {
|
|
377
|
+
accepted: boolean;
|
|
378
|
+
action: RuntimeControlAction;
|
|
379
|
+
lifecycle: RuntimeLifecycleState;
|
|
380
|
+
message: string;
|
|
381
|
+
};
|
|
382
|
+
//#endregion
|
|
352
383
|
//#region src/ui/ui-routes/types.d.ts
|
|
353
384
|
type UiRouterOptions = {
|
|
354
385
|
configPath: string;
|
|
@@ -362,6 +393,7 @@ type UiRouterOptions = {
|
|
|
362
393
|
ncpSessionService?: UiNcpSessionService;
|
|
363
394
|
authService?: UiAuthService;
|
|
364
395
|
remoteAccess?: UiRemoteAccessHost;
|
|
396
|
+
runtimeControl?: UiRuntimeControlHost;
|
|
365
397
|
getBootstrapStatus?: () => BootstrapStatusView;
|
|
366
398
|
getPluginChannelBindings?: () => PluginChannelBinding[];
|
|
367
399
|
getPluginUiMetadata?: () => PluginUiMetadata[];
|
|
@@ -377,6 +409,12 @@ type UiRemoteAccessHost = {
|
|
|
377
409
|
runDoctor: () => Promise<RemoteDoctorView>;
|
|
378
410
|
controlService: (action: RemoteServiceAction) => Promise<RemoteServiceActionResult>;
|
|
379
411
|
};
|
|
412
|
+
type UiRuntimeControlHost = {
|
|
413
|
+
getControl: () => Promise<RuntimeControlView> | RuntimeControlView;
|
|
414
|
+
startService: () => Promise<RuntimeControlActionResult> | RuntimeControlActionResult;
|
|
415
|
+
restartService: () => Promise<RuntimeControlActionResult> | RuntimeControlActionResult;
|
|
416
|
+
stopService: () => Promise<RuntimeControlActionResult> | RuntimeControlActionResult;
|
|
417
|
+
};
|
|
380
418
|
//#endregion
|
|
381
419
|
//#region src/ui/chat-session-type.types.d.ts
|
|
382
420
|
type ChatSessionTypeCtaView = {
|
|
@@ -760,6 +798,12 @@ type AgentBindingView = {
|
|
|
760
798
|
type SessionConfigView = {
|
|
761
799
|
dmScope?: "main" | "per-peer" | "per-channel-peer" | "per-account-channel-peer";
|
|
762
800
|
};
|
|
801
|
+
type RuntimeEntryView = {
|
|
802
|
+
enabled?: boolean;
|
|
803
|
+
label?: string;
|
|
804
|
+
type: string;
|
|
805
|
+
config?: Record<string, unknown>;
|
|
806
|
+
};
|
|
763
807
|
type SessionEntryView = {
|
|
764
808
|
key: string;
|
|
765
809
|
createdAt: string;
|
|
@@ -808,6 +852,7 @@ type SessionPatchUpdate = {
|
|
|
808
852
|
preferredThinking?: ThinkingLevel | null;
|
|
809
853
|
sessionType?: string | null;
|
|
810
854
|
projectRoot?: string | null;
|
|
855
|
+
uiReadAt?: string | null;
|
|
811
856
|
clearHistory?: boolean;
|
|
812
857
|
};
|
|
813
858
|
type SessionSkillEntryView = {
|
|
@@ -843,6 +888,15 @@ type ServerPathBrowseView = {
|
|
|
843
888
|
breadcrumbs: ServerPathBreadcrumbView[];
|
|
844
889
|
entries: ServerPathEntryView[];
|
|
845
890
|
};
|
|
891
|
+
type ServerPathReadView = {
|
|
892
|
+
requestedPath: string;
|
|
893
|
+
resolvedPath: string;
|
|
894
|
+
kind: "text" | "markdown" | "binary";
|
|
895
|
+
sizeBytes: number;
|
|
896
|
+
truncated: boolean;
|
|
897
|
+
text?: string;
|
|
898
|
+
languageHint?: string | null;
|
|
899
|
+
};
|
|
846
900
|
type CronScheduleView = {
|
|
847
901
|
kind: "at";
|
|
848
902
|
atMs?: number | null;
|
|
@@ -913,6 +967,9 @@ type RuntimeConfigUpdate = {
|
|
|
913
967
|
engine?: string;
|
|
914
968
|
engineConfig?: Record<string, unknown>;
|
|
915
969
|
};
|
|
970
|
+
runtimes?: {
|
|
971
|
+
entries?: Record<string, RuntimeEntryView> | null;
|
|
972
|
+
};
|
|
916
973
|
list?: AgentProfileView[];
|
|
917
974
|
};
|
|
918
975
|
bindings?: AgentBindingView[];
|
|
@@ -1001,6 +1058,9 @@ type ConfigView = {
|
|
|
1001
1058
|
contextTokens?: number;
|
|
1002
1059
|
maxToolIterations?: number;
|
|
1003
1060
|
};
|
|
1061
|
+
runtimes?: {
|
|
1062
|
+
entries?: Record<string, RuntimeEntryView>;
|
|
1063
|
+
};
|
|
1004
1064
|
list?: AgentProfileView[];
|
|
1005
1065
|
context?: {
|
|
1006
1066
|
bootstrap?: {
|
|
@@ -1208,6 +1268,7 @@ type UiServerOptions = {
|
|
|
1208
1268
|
ncpAgent?: UiNcpAgent;
|
|
1209
1269
|
ncpSessionService?: UiNcpSessionService;
|
|
1210
1270
|
remoteAccess?: UiRemoteAccessHost;
|
|
1271
|
+
runtimeControl?: UiRuntimeControlHost;
|
|
1211
1272
|
getBootstrapStatus?: () => BootstrapStatusView;
|
|
1212
1273
|
getPluginChannelBindings?: () => PluginChannelBinding[];
|
|
1213
1274
|
getPluginUiMetadata?: () => PluginUiMetadata[];
|
|
@@ -1287,4 +1348,4 @@ declare function getUiBridgeSecretPath(): string;
|
|
|
1287
1348
|
declare function readUiBridgeSecret(): string | null;
|
|
1288
1349
|
declare function ensureUiBridgeSecret(): string;
|
|
1289
1350
|
//#endregion
|
|
1290
|
-
export { AgentBindingView, AgentCreateRequest, AgentDeleteResult, AgentProfileView, AgentUpdateRequest, ApiError, ApiResponse, AppMetaView, AuthEnabledUpdateRequest, AuthLoginRequest, AuthPasswordUpdateRequest, AuthSetupRequest, AuthStatusView, BindingPeerView, BochaFreshnessValue, BootstrapPhase, BootstrapRemoteState, BootstrapStageState, BootstrapStatusView, ChannelAuthPollRequest, ChannelAuthPollResult, ChannelAuthStartRequest, ChannelAuthStartResult, ChannelSpecView, type ChatSessionTypeCtaView, type ChatSessionTypeOptionView, type ChatSessionTypesView, ConfigActionExecuteRequest, ConfigActionExecuteResult, ConfigActionManifest, ConfigActionType, ConfigMetaView, ConfigSchemaResponse, ConfigUiHint, ConfigUiHints, ConfigView, CronActionResult, CronCreateRequest, CronCreateResult, CronEnableRequest, CronJobStateView, CronJobView, CronListView, CronPayloadView, CronRunRequest, CronScheduleView, DEFAULT_SESSION_TYPE, MarketplaceApiConfig, MarketplaceInstallKind, MarketplaceInstallSkillParams, MarketplaceInstallSpec, MarketplaceInstalledRecord, MarketplaceInstalledView, MarketplaceInstaller, MarketplaceItemSummary, MarketplaceItemType, MarketplaceItemView, MarketplaceListView, MarketplaceLocalizedTextMap, MarketplaceMcpContentView, MarketplaceMcpDoctorResult, MarketplaceMcpInstallKind, MarketplaceMcpInstallRequest, MarketplaceMcpInstallResult, MarketplaceMcpInstallSpec, MarketplaceMcpManageAction, MarketplaceMcpManageRequest, MarketplaceMcpManageResult, MarketplaceMcpTemplateInput, MarketplacePluginContentView, MarketplacePluginInstallKind, MarketplacePluginInstallRequest, MarketplacePluginInstallResult, MarketplacePluginManageAction, MarketplacePluginManageRequest, MarketplacePluginManageResult, MarketplaceRecommendationView, MarketplaceSkillContentView, MarketplaceSkillInstallKind, MarketplaceSkillInstallRequest, MarketplaceSkillInstallResult, MarketplaceSkillManageAction, MarketplaceSkillManageRequest, MarketplaceSkillManageResult, MarketplaceSort, NcpSessionSkillsView, ProviderAuthImportResult, ProviderAuthPollRequest, ProviderAuthPollResult, ProviderAuthStartRequest, ProviderAuthStartResult, ProviderConfigUpdate, ProviderConfigView, ProviderConnectionTestRequest, ProviderConnectionTestResult, ProviderCreateRequest, ProviderCreateResult, ProviderDeleteResult, ProviderSpecView, RemoteAccessView, RemoteAccountProfileUpdateRequest, RemoteAccountView, RemoteBrowserAuthPollRequest, RemoteBrowserAuthPollResult, RemoteBrowserAuthStartRequest, RemoteBrowserAuthStartResult, RemoteDoctorCheckView, RemoteDoctorView, RemoteLoginRequest, RemoteRuntimeView, RemoteServiceAction, RemoteServiceActionResult, RemoteServiceView, RemoteSettingsUpdateRequest, RemoteSettingsView, RuntimeConfigUpdate, SearchConfigUpdate, SearchConfigView, SearchProviderConfigView, SearchProviderName, SearchProviderSpecView, SecretProviderEnvView, SecretProviderExecView, SecretProviderFileView, SecretProviderView, SecretRefView, SecretSourceView, SecretsConfigUpdate, SecretsView, ServerPathBreadcrumbView, ServerPathBrowseView, ServerPathEntryView, SessionConfigView, SessionEntryView, SessionEventView, SessionHistoryView, SessionMessageView, SessionPatchUpdate, SessionPatchValidationError, SessionSkillEntryView, SessionTypeDescribeParams, SessionsListView, TavilySearchDepthValue, UiNcpAgent, UiNcpAssetPutView, UiNcpAssetView, UiNcpSessionListView, UiNcpSessionMessagesView, UiNcpSessionService, UiNcpStoredAssetRecord, type UiRemoteAccessHost, UiServerEvent, UiServerHandle, UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createCustomProvider, createUiRouter, deleteCustomProvider, deleteSession, ensureUiBridgeSecret, executeConfigAction, getSessionHistory, getUiBridgeSecretPath, listSessions, loadConfigOrDefault, patchSession, readUiBridgeSecret, startUiServer, testProviderConnection, updateChannel, updateModel, updateProvider, updateRuntime, updateSearch, updateSecrets };
|
|
1351
|
+
export { AgentBindingView, AgentCreateRequest, AgentDeleteResult, AgentProfileView, AgentUpdateRequest, ApiError, ApiResponse, AppMetaView, AuthEnabledUpdateRequest, AuthLoginRequest, AuthPasswordUpdateRequest, AuthSetupRequest, AuthStatusView, BindingPeerView, BochaFreshnessValue, BootstrapPhase, BootstrapRemoteState, BootstrapStageState, BootstrapStatusView, ChannelAuthPollRequest, ChannelAuthPollResult, ChannelAuthStartRequest, ChannelAuthStartResult, ChannelSpecView, type ChatSessionTypeCtaView, type ChatSessionTypeOptionView, type ChatSessionTypesView, ConfigActionExecuteRequest, ConfigActionExecuteResult, ConfigActionManifest, ConfigActionType, ConfigMetaView, ConfigSchemaResponse, ConfigUiHint, ConfigUiHints, ConfigView, CronActionResult, CronCreateRequest, CronCreateResult, CronEnableRequest, CronJobStateView, CronJobView, CronListView, CronPayloadView, CronRunRequest, CronScheduleView, DEFAULT_SESSION_TYPE, MarketplaceApiConfig, MarketplaceInstallKind, MarketplaceInstallSkillParams, MarketplaceInstallSpec, MarketplaceInstalledRecord, MarketplaceInstalledView, MarketplaceInstaller, MarketplaceItemSummary, MarketplaceItemType, MarketplaceItemView, MarketplaceListView, MarketplaceLocalizedTextMap, MarketplaceMcpContentView, MarketplaceMcpDoctorResult, MarketplaceMcpInstallKind, MarketplaceMcpInstallRequest, MarketplaceMcpInstallResult, MarketplaceMcpInstallSpec, MarketplaceMcpManageAction, MarketplaceMcpManageRequest, MarketplaceMcpManageResult, MarketplaceMcpTemplateInput, MarketplacePluginContentView, MarketplacePluginInstallKind, MarketplacePluginInstallRequest, MarketplacePluginInstallResult, MarketplacePluginManageAction, MarketplacePluginManageRequest, MarketplacePluginManageResult, MarketplaceRecommendationView, MarketplaceSkillContentView, MarketplaceSkillInstallKind, MarketplaceSkillInstallRequest, MarketplaceSkillInstallResult, MarketplaceSkillManageAction, MarketplaceSkillManageRequest, MarketplaceSkillManageResult, MarketplaceSort, NcpSessionSkillsView, ProviderAuthImportResult, ProviderAuthPollRequest, ProviderAuthPollResult, ProviderAuthStartRequest, ProviderAuthStartResult, ProviderConfigUpdate, ProviderConfigView, ProviderConnectionTestRequest, ProviderConnectionTestResult, ProviderCreateRequest, ProviderCreateResult, ProviderDeleteResult, ProviderSpecView, RemoteAccessView, RemoteAccountProfileUpdateRequest, RemoteAccountView, RemoteBrowserAuthPollRequest, RemoteBrowserAuthPollResult, RemoteBrowserAuthStartRequest, RemoteBrowserAuthStartResult, RemoteDoctorCheckView, RemoteDoctorView, RemoteLoginRequest, RemoteRuntimeView, RemoteServiceAction, RemoteServiceActionResult, RemoteServiceView, RemoteSettingsUpdateRequest, RemoteSettingsView, RuntimeActionCapability, RuntimeActionImpact, RuntimeConfigUpdate, RuntimeControlAction, RuntimeControlActionResult, RuntimeControlEnvironment, RuntimeControlView, RuntimeEntryView, RuntimeLifecycleState, RuntimeServiceState, SearchConfigUpdate, SearchConfigView, SearchProviderConfigView, SearchProviderName, SearchProviderSpecView, SecretProviderEnvView, SecretProviderExecView, SecretProviderFileView, SecretProviderView, SecretRefView, SecretSourceView, SecretsConfigUpdate, SecretsView, ServerPathBreadcrumbView, ServerPathBrowseView, ServerPathEntryView, ServerPathReadView, SessionConfigView, SessionEntryView, SessionEventView, SessionHistoryView, SessionMessageView, SessionPatchUpdate, SessionPatchValidationError, SessionSkillEntryView, SessionTypeDescribeParams, SessionsListView, TavilySearchDepthValue, UiNcpAgent, UiNcpAssetPutView, UiNcpAssetView, UiNcpSessionListView, UiNcpSessionMessagesView, UiNcpSessionService, UiNcpStoredAssetRecord, type UiRemoteAccessHost, type UiRuntimeControlHost, UiServerEvent, UiServerHandle, UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createCustomProvider, createUiRouter, deleteCustomProvider, deleteSession, ensureUiBridgeSecret, executeConfigAction, getSessionHistory, getUiBridgeSecretPath, listSessions, loadConfigOrDefault, patchSession, readUiBridgeSecret, startUiServer, testProviderConnection, updateChannel, updateModel, updateProvider, updateRuntime, updateSearch, updateSecrets };
|
package/dist/index.js
CHANGED
|
@@ -3,8 +3,8 @@ import { compress } from "hono/compress";
|
|
|
3
3
|
import { serve } from "@hono/node-server";
|
|
4
4
|
import { WebSocket, WebSocketServer } from "ws";
|
|
5
5
|
import fs, { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
6
|
-
import { readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
7
|
-
import path, { dirname, isAbsolute, join, parse, resolve } from "node:path";
|
|
6
|
+
import { open, readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
7
|
+
import path, { dirname, extname, isAbsolute, join, parse, resolve } from "node:path";
|
|
8
8
|
import * as NextclawCore from "@nextclaw/core";
|
|
9
9
|
import { ConfigSchema, DEFAULT_WORKSPACE_PATH, LiteLLMProvider, SessionManager, buildConfigSchema, createAgentProfile, expandHome, findEffectiveAgentProfile, getDataDir, getPackageVersion, getProviderName, getWorkspacePathFromConfig, hasSecretRef, isSensitiveConfigPath, loadConfig, normalizeThinkingLevels, parseThinkingLevel, probeFeishu, readAgentAvatarContent, removeAgentProfile, resolveEffectiveAgentProfiles, saveConfig, updateAgentProfile } from "@nextclaw/core";
|
|
10
10
|
import { createHash, randomBytes, randomUUID, scryptSync, timingSafeEqual } from "node:crypto";
|
|
@@ -1331,7 +1331,7 @@ function buildConfigView(config, options) {
|
|
|
1331
1331
|
const providers = {};
|
|
1332
1332
|
for (const [name, provider] of Object.entries(config.providers)) providers[name] = toProviderView(config, provider, name, uiHints, findServerBuiltinProviderByName(name));
|
|
1333
1333
|
return {
|
|
1334
|
-
agents: config.agents,
|
|
1334
|
+
agents: sanitizePublicConfigValue(config.agents, "agents", uiHints),
|
|
1335
1335
|
providers,
|
|
1336
1336
|
search: buildSearchView(config),
|
|
1337
1337
|
channels: sanitizePublicConfigValue(projectedChannels, "channels", uiHints),
|
|
@@ -1348,6 +1348,40 @@ function buildConfigView(config, options) {
|
|
|
1348
1348
|
}
|
|
1349
1349
|
};
|
|
1350
1350
|
}
|
|
1351
|
+
function normalizeRuntimeEntries(entries) {
|
|
1352
|
+
if (!entries || typeof entries !== "object" || Array.isArray(entries)) return {};
|
|
1353
|
+
const normalized = {};
|
|
1354
|
+
for (const [rawId, rawEntry] of Object.entries(entries)) {
|
|
1355
|
+
const id = rawId.trim();
|
|
1356
|
+
if (!id || !rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) continue;
|
|
1357
|
+
const entry = rawEntry;
|
|
1358
|
+
const type = normalizeOptionalString(entry.type);
|
|
1359
|
+
if (!type) continue;
|
|
1360
|
+
normalized[id] = {
|
|
1361
|
+
enabled: typeof entry.enabled === "boolean" ? entry.enabled : true,
|
|
1362
|
+
...normalizeOptionalString(entry.label) ? { label: normalizeOptionalString(entry.label) ?? void 0 } : {},
|
|
1363
|
+
type,
|
|
1364
|
+
config: normalizeRuntimeEntryConfig(type, entry.config && typeof entry.config === "object" && !Array.isArray(entry.config) ? entry.config : {})
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
return normalized;
|
|
1368
|
+
}
|
|
1369
|
+
function normalizeRuntimeEntryConfig(type, config) {
|
|
1370
|
+
if (type !== "narp-stdio") return { ...config };
|
|
1371
|
+
const command = normalizeOptionalString(config.command);
|
|
1372
|
+
const cwd = normalizeOptionalString(config.cwd);
|
|
1373
|
+
return {
|
|
1374
|
+
wireDialect: normalizeOptionalString(config.wireDialect) ?? "acp",
|
|
1375
|
+
processScope: normalizeOptionalString(config.processScope) ?? "per-session",
|
|
1376
|
+
...command ? { command } : {},
|
|
1377
|
+
...normalizeStringArray(config.args) ? { args: normalizeStringArray(config.args) } : {},
|
|
1378
|
+
env: normalizeUnknownStringRecord(config.env) ?? {},
|
|
1379
|
+
...cwd ? { cwd } : {},
|
|
1380
|
+
startupTimeoutMs: normalizePositiveInteger(config.startupTimeoutMs) ?? 8e3,
|
|
1381
|
+
probeTimeoutMs: normalizePositiveInteger(config.probeTimeoutMs) ?? 3e3,
|
|
1382
|
+
requestTimeoutMs: normalizePositiveInteger(config.requestTimeoutMs) ?? 12e4
|
|
1383
|
+
};
|
|
1384
|
+
}
|
|
1351
1385
|
function clearSecretRef(config, path) {
|
|
1352
1386
|
if (config.secrets.refs[path]) delete config.secrets.refs[path];
|
|
1353
1387
|
}
|
|
@@ -1545,6 +1579,22 @@ function normalizeOptionalString(value) {
|
|
|
1545
1579
|
const trimmed = value.trim();
|
|
1546
1580
|
return trimmed.length > 0 ? trimmed : null;
|
|
1547
1581
|
}
|
|
1582
|
+
function normalizePositiveInteger(value) {
|
|
1583
|
+
const parsed = typeof value === "number" ? value : typeof value === "string" ? Number.parseInt(value, 10) : NaN;
|
|
1584
|
+
if (!Number.isFinite(parsed)) return null;
|
|
1585
|
+
const normalized = Math.trunc(parsed);
|
|
1586
|
+
return normalized > 0 ? normalized : null;
|
|
1587
|
+
}
|
|
1588
|
+
function normalizeStringArray(value) {
|
|
1589
|
+
if (!Array.isArray(value)) return null;
|
|
1590
|
+
const entries = value.map((entry) => normalizeOptionalString(entry)).filter((entry) => Boolean(entry));
|
|
1591
|
+
return entries.length > 0 ? entries : null;
|
|
1592
|
+
}
|
|
1593
|
+
function normalizeUnknownStringRecord(value) {
|
|
1594
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
1595
|
+
const entries = Object.entries(value).map(([key, entryValue]) => [key.trim(), normalizeOptionalString(entryValue)]).filter(([key, entryValue]) => key.length > 0 && Boolean(entryValue));
|
|
1596
|
+
return entries.length > 0 ? Object.fromEntries(entries) : null;
|
|
1597
|
+
}
|
|
1548
1598
|
function normalizeHeaders(input) {
|
|
1549
1599
|
if (!input) return null;
|
|
1550
1600
|
const entries = Object.entries(input).map(([key, value]) => [key.trim(), String(value ?? "").trim()]).filter(([key, value]) => key.length > 0 && value.length > 0);
|
|
@@ -1858,6 +1908,7 @@ function updateRuntime(configPath, patch) {
|
|
|
1858
1908
|
...hasEngineConfig ? { engineConfig: { ...entry.engineConfig } } : {}
|
|
1859
1909
|
};
|
|
1860
1910
|
});
|
|
1911
|
+
if (patch.agents?.runtimes && Object.prototype.hasOwnProperty.call(patch.agents.runtimes, "entries")) config.agents.runtimes.entries = normalizeRuntimeEntries(patch.agents.runtimes.entries);
|
|
1861
1912
|
if (Object.prototype.hasOwnProperty.call(patch, "bindings")) config.bindings = patch.bindings ?? [];
|
|
1862
1913
|
if (patch.session) config.session = {
|
|
1863
1914
|
...config.session,
|
|
@@ -2591,6 +2642,7 @@ var ConfigRoutesController = class {
|
|
|
2591
2642
|
if (body.data.agents?.defaults && Object.prototype.hasOwnProperty.call(body.data.agents.defaults, "contextTokens")) changedPaths.push("agents.defaults.contextTokens");
|
|
2592
2643
|
if (body.data.agents?.defaults && Object.prototype.hasOwnProperty.call(body.data.agents.defaults, "engine")) changedPaths.push("agents.defaults.engine");
|
|
2593
2644
|
if (body.data.agents?.defaults && Object.prototype.hasOwnProperty.call(body.data.agents.defaults, "engineConfig")) changedPaths.push("agents.defaults.engineConfig");
|
|
2645
|
+
if (body.data.agents?.runtimes && Object.prototype.hasOwnProperty.call(body.data.agents.runtimes, "entries")) changedPaths.push("agents.runtimes.entries");
|
|
2594
2646
|
changedPaths.push("agents.list", "bindings", "session");
|
|
2595
2647
|
await this.publishConfigUpdates(changedPaths);
|
|
2596
2648
|
return c.json(ok(result));
|
|
@@ -2988,6 +3040,16 @@ function applySessionTypePatch(metadata, patch) {
|
|
|
2988
3040
|
delete metadata.session_type;
|
|
2989
3041
|
delete metadata.sessionType;
|
|
2990
3042
|
}
|
|
3043
|
+
function applyUiReadAtPatch(metadata, patch) {
|
|
3044
|
+
if (!Object.prototype.hasOwnProperty.call(patch, "uiReadAt")) return metadata;
|
|
3045
|
+
const uiReadAt = typeof patch.uiReadAt === "string" ? patch.uiReadAt.trim() : "";
|
|
3046
|
+
if (uiReadAt) return {
|
|
3047
|
+
...metadata,
|
|
3048
|
+
ui_last_read_at: uiReadAt
|
|
3049
|
+
};
|
|
3050
|
+
const { ui_last_read_at: _removed, ...nextMetadata } = metadata;
|
|
3051
|
+
return nextMetadata;
|
|
3052
|
+
}
|
|
2991
3053
|
async function applyProjectRootPatch(metadata, patch) {
|
|
2992
3054
|
if (!Object.prototype.hasOwnProperty.call(patch, "projectRoot")) return;
|
|
2993
3055
|
const projectRoot = await normalizeSessionProjectRoot(patch.projectRoot);
|
|
@@ -3000,14 +3062,16 @@ async function applyProjectRootPatch(metadata, patch) {
|
|
|
3000
3062
|
delete metadata.projectRoot;
|
|
3001
3063
|
}
|
|
3002
3064
|
async function buildPatchedSessionMetadata(params) {
|
|
3065
|
+
const { metadata, patch } = params;
|
|
3003
3066
|
const nextMetadata = applySessionPreferencePatch({
|
|
3004
|
-
metadata: structuredClone(
|
|
3005
|
-
patch
|
|
3067
|
+
metadata: structuredClone(metadata),
|
|
3068
|
+
patch,
|
|
3006
3069
|
createInvalidThinkingError: () => /* @__PURE__ */ new Error("PREFERRED_THINKING_INVALID")
|
|
3007
3070
|
});
|
|
3008
|
-
applySessionTypePatch(nextMetadata,
|
|
3009
|
-
|
|
3010
|
-
|
|
3071
|
+
applySessionTypePatch(nextMetadata, patch);
|
|
3072
|
+
const nextMetadataWithReadAt = applyUiReadAtPatch(nextMetadata, patch);
|
|
3073
|
+
await applyProjectRootPatch(nextMetadataWithReadAt, patch);
|
|
3074
|
+
return nextMetadataWithReadAt;
|
|
3011
3075
|
}
|
|
3012
3076
|
var NcpSessionRoutesController = class {
|
|
3013
3077
|
sessionSkillsViewBuilder;
|
|
@@ -4343,6 +4407,41 @@ var RemoteRoutesController = class {
|
|
|
4343
4407
|
};
|
|
4344
4408
|
};
|
|
4345
4409
|
//#endregion
|
|
4410
|
+
//#region src/ui/ui-routes/runtime-control.controller.ts
|
|
4411
|
+
var RuntimeControlRoutesController = class {
|
|
4412
|
+
constructor(host) {
|
|
4413
|
+
this.host = host;
|
|
4414
|
+
}
|
|
4415
|
+
getControl = async (c) => {
|
|
4416
|
+
try {
|
|
4417
|
+
return c.json(ok(await this.host.getControl()));
|
|
4418
|
+
} catch (error) {
|
|
4419
|
+
return c.json(err("RUNTIME_CONTROL_FAILED", formatUserFacingError(error)), 500);
|
|
4420
|
+
}
|
|
4421
|
+
};
|
|
4422
|
+
restartService = async (c) => {
|
|
4423
|
+
try {
|
|
4424
|
+
return c.json(ok(await this.host.restartService()));
|
|
4425
|
+
} catch (error) {
|
|
4426
|
+
return c.json(err("RUNTIME_RESTART_FAILED", formatUserFacingError(error)), 400);
|
|
4427
|
+
}
|
|
4428
|
+
};
|
|
4429
|
+
startService = async (c) => {
|
|
4430
|
+
try {
|
|
4431
|
+
return c.json(ok(await this.host.startService()));
|
|
4432
|
+
} catch (error) {
|
|
4433
|
+
return c.json(err("RUNTIME_START_FAILED", formatUserFacingError(error)), 400);
|
|
4434
|
+
}
|
|
4435
|
+
};
|
|
4436
|
+
stopService = async (c) => {
|
|
4437
|
+
try {
|
|
4438
|
+
return c.json(ok(await this.host.stopService()));
|
|
4439
|
+
} catch (error) {
|
|
4440
|
+
return c.json(err("RUNTIME_STOP_FAILED", formatUserFacingError(error)), 400);
|
|
4441
|
+
}
|
|
4442
|
+
};
|
|
4443
|
+
};
|
|
4444
|
+
//#endregion
|
|
4346
4445
|
//#region src/ui/server-path/server-path-browse.utils.ts
|
|
4347
4446
|
var ServerPathBrowseError = class extends Error {
|
|
4348
4447
|
constructor(code, message) {
|
|
@@ -4429,6 +4528,139 @@ function isServerPathBrowseError(error) {
|
|
|
4429
4528
|
return error instanceof ServerPathBrowseError;
|
|
4430
4529
|
}
|
|
4431
4530
|
//#endregion
|
|
4531
|
+
//#region src/ui/server-path/server-path-read.utils.ts
|
|
4532
|
+
const DEFAULT_PREVIEW_MAX_BYTES = 2e5;
|
|
4533
|
+
const MARKDOWN_EXTENSIONS = new Set([
|
|
4534
|
+
".md",
|
|
4535
|
+
".mdx",
|
|
4536
|
+
".markdown"
|
|
4537
|
+
]);
|
|
4538
|
+
const TEXT_EXTENSIONS = new Set([
|
|
4539
|
+
".c",
|
|
4540
|
+
".cc",
|
|
4541
|
+
".conf",
|
|
4542
|
+
".cpp",
|
|
4543
|
+
".css",
|
|
4544
|
+
".csv",
|
|
4545
|
+
".env",
|
|
4546
|
+
".go",
|
|
4547
|
+
".graphql",
|
|
4548
|
+
".h",
|
|
4549
|
+
".hpp",
|
|
4550
|
+
".html",
|
|
4551
|
+
".ini",
|
|
4552
|
+
".java",
|
|
4553
|
+
".js",
|
|
4554
|
+
".json",
|
|
4555
|
+
".jsx",
|
|
4556
|
+
".log",
|
|
4557
|
+
".mjs",
|
|
4558
|
+
".py",
|
|
4559
|
+
".rb",
|
|
4560
|
+
".rs",
|
|
4561
|
+
".sh",
|
|
4562
|
+
".sql",
|
|
4563
|
+
".svg",
|
|
4564
|
+
".toml",
|
|
4565
|
+
".ts",
|
|
4566
|
+
".tsx",
|
|
4567
|
+
".txt",
|
|
4568
|
+
".xml",
|
|
4569
|
+
".yaml",
|
|
4570
|
+
".yml"
|
|
4571
|
+
]);
|
|
4572
|
+
var ServerPathReadError = class extends Error {
|
|
4573
|
+
constructor(code, message) {
|
|
4574
|
+
super(message);
|
|
4575
|
+
this.code = code;
|
|
4576
|
+
this.name = "ServerPathReadError";
|
|
4577
|
+
}
|
|
4578
|
+
};
|
|
4579
|
+
function normalizeReadPath(params) {
|
|
4580
|
+
const { basePath, path } = params;
|
|
4581
|
+
const rawPath = typeof path === "string" ? path.trim() : "";
|
|
4582
|
+
const normalizedBasePath = typeof basePath === "string" ? basePath.trim() : "";
|
|
4583
|
+
if (!rawPath) return resolve(expandHome(normalizedBasePath || homedir()));
|
|
4584
|
+
const expandedPath = expandHome(rawPath);
|
|
4585
|
+
if (expandedPath.startsWith("/")) return resolve(expandedPath);
|
|
4586
|
+
if (!normalizedBasePath) throw new ServerPathReadError("SERVER_PATH_BASE_REQUIRED", "relative server path requires a base path");
|
|
4587
|
+
return resolve(expandHome(normalizedBasePath), expandedPath);
|
|
4588
|
+
}
|
|
4589
|
+
function inferPreviewKind(path) {
|
|
4590
|
+
const extension = extname(path).toLowerCase();
|
|
4591
|
+
if (MARKDOWN_EXTENSIONS.has(extension)) return "markdown";
|
|
4592
|
+
if (TEXT_EXTENSIONS.has(extension)) return "text";
|
|
4593
|
+
return "binary";
|
|
4594
|
+
}
|
|
4595
|
+
function isLikelyTextBuffer(buffer) {
|
|
4596
|
+
for (const byte of buffer) if (byte === 0) return false;
|
|
4597
|
+
return true;
|
|
4598
|
+
}
|
|
4599
|
+
function readLanguageHint(path) {
|
|
4600
|
+
const extension = extname(path).toLowerCase();
|
|
4601
|
+
if (!extension) return null;
|
|
4602
|
+
if (MARKDOWN_EXTENSIONS.has(extension)) return "markdown";
|
|
4603
|
+
return extension.slice(1) || null;
|
|
4604
|
+
}
|
|
4605
|
+
async function readFilePreviewBytes(params) {
|
|
4606
|
+
const { maxBytes, resolvedPath, sizeBytes } = params;
|
|
4607
|
+
const bytesToRead = Math.min(sizeBytes, maxBytes);
|
|
4608
|
+
const fileHandle = await open(resolvedPath, "r");
|
|
4609
|
+
try {
|
|
4610
|
+
const buffer = Buffer.alloc(bytesToRead);
|
|
4611
|
+
const { bytesRead } = await fileHandle.read(buffer, 0, bytesToRead, 0);
|
|
4612
|
+
return {
|
|
4613
|
+
buffer: buffer.subarray(0, bytesRead),
|
|
4614
|
+
truncated: sizeBytes > maxBytes
|
|
4615
|
+
};
|
|
4616
|
+
} finally {
|
|
4617
|
+
await fileHandle.close();
|
|
4618
|
+
}
|
|
4619
|
+
}
|
|
4620
|
+
async function readServerPath(options = {}) {
|
|
4621
|
+
const requestedPath = typeof options.path === "string" ? options.path.trim() : "";
|
|
4622
|
+
const resolvedPath = normalizeReadPath(options);
|
|
4623
|
+
let resolvedStats;
|
|
4624
|
+
try {
|
|
4625
|
+
resolvedStats = await stat(resolvedPath);
|
|
4626
|
+
} catch {
|
|
4627
|
+
throw new ServerPathReadError("SERVER_PATH_NOT_FOUND", "server path does not exist");
|
|
4628
|
+
}
|
|
4629
|
+
if (!resolvedStats.isFile()) throw new ServerPathReadError("SERVER_PATH_NOT_FILE", "server path must point to a file");
|
|
4630
|
+
let previewBytes;
|
|
4631
|
+
try {
|
|
4632
|
+
previewBytes = await readFilePreviewBytes({
|
|
4633
|
+
resolvedPath,
|
|
4634
|
+
sizeBytes: resolvedStats.size,
|
|
4635
|
+
maxBytes: options.maxBytes ?? DEFAULT_PREVIEW_MAX_BYTES
|
|
4636
|
+
});
|
|
4637
|
+
} catch {
|
|
4638
|
+
throw new ServerPathReadError("SERVER_PATH_NOT_READABLE", "server path is not readable");
|
|
4639
|
+
}
|
|
4640
|
+
const inferredKind = inferPreviewKind(resolvedPath);
|
|
4641
|
+
const resolvedKind = inferredKind === "binary" && isLikelyTextBuffer(previewBytes.buffer) ? "text" : inferredKind;
|
|
4642
|
+
if (resolvedKind === "binary") return {
|
|
4643
|
+
requestedPath: requestedPath || resolvedPath,
|
|
4644
|
+
resolvedPath,
|
|
4645
|
+
kind: "binary",
|
|
4646
|
+
sizeBytes: resolvedStats.size,
|
|
4647
|
+
truncated: previewBytes.truncated,
|
|
4648
|
+
languageHint: readLanguageHint(resolvedPath)
|
|
4649
|
+
};
|
|
4650
|
+
return {
|
|
4651
|
+
requestedPath: requestedPath || resolvedPath,
|
|
4652
|
+
resolvedPath,
|
|
4653
|
+
kind: resolvedKind,
|
|
4654
|
+
sizeBytes: resolvedStats.size,
|
|
4655
|
+
truncated: previewBytes.truncated,
|
|
4656
|
+
text: previewBytes.buffer.toString("utf8"),
|
|
4657
|
+
languageHint: readLanguageHint(resolvedPath)
|
|
4658
|
+
};
|
|
4659
|
+
}
|
|
4660
|
+
function isServerPathReadError(error) {
|
|
4661
|
+
return error instanceof ServerPathReadError;
|
|
4662
|
+
}
|
|
4663
|
+
//#endregion
|
|
4432
4664
|
//#region src/ui/ui-routes/server-path.controller.ts
|
|
4433
4665
|
function readIncludeFilesFlag(value) {
|
|
4434
4666
|
return value === "1" || value === "true";
|
|
@@ -4446,6 +4678,18 @@ var ServerPathRoutesController = class {
|
|
|
4446
4678
|
throw error;
|
|
4447
4679
|
}
|
|
4448
4680
|
};
|
|
4681
|
+
read = async (c) => {
|
|
4682
|
+
try {
|
|
4683
|
+
const payload = await readServerPath({
|
|
4684
|
+
path: c.req.query("path"),
|
|
4685
|
+
basePath: c.req.query("basePath")
|
|
4686
|
+
});
|
|
4687
|
+
return c.json(ok(payload));
|
|
4688
|
+
} catch (error) {
|
|
4689
|
+
if (isServerPathReadError(error)) return c.json(err(error.code, error.message), 400);
|
|
4690
|
+
throw error;
|
|
4691
|
+
}
|
|
4692
|
+
};
|
|
4449
4693
|
};
|
|
4450
4694
|
//#endregion
|
|
4451
4695
|
//#region src/ui/router.ts
|
|
@@ -4496,6 +4740,7 @@ function registerNcpSessionRoutes(app, ncpSessionController) {
|
|
|
4496
4740
|
}
|
|
4497
4741
|
function registerServerPathRoutes(app, serverPathController) {
|
|
4498
4742
|
app.get("/api/server-paths/browse", serverPathController.browse);
|
|
4743
|
+
app.get("/api/server-paths/read", serverPathController.read);
|
|
4499
4744
|
}
|
|
4500
4745
|
function registerNcpRuntimeRoutes(app, options, ncpAssetController) {
|
|
4501
4746
|
if (!options.ncpAgent) return;
|
|
@@ -4526,22 +4771,35 @@ function registerRemoteRoutes(app, remoteController) {
|
|
|
4526
4771
|
app.put("/api/remote/settings", remoteController.updateSettings);
|
|
4527
4772
|
app.post("/api/remote/service/:action", remoteController.controlService);
|
|
4528
4773
|
}
|
|
4774
|
+
function registerRuntimeControlRoutes(app, runtimeControlController) {
|
|
4775
|
+
if (!runtimeControlController) return;
|
|
4776
|
+
app.get("/api/runtime/control", runtimeControlController.getControl);
|
|
4777
|
+
app.post("/api/runtime/control/start-service", runtimeControlController.startService);
|
|
4778
|
+
app.post("/api/runtime/control/restart-service", runtimeControlController.restartService);
|
|
4779
|
+
app.post("/api/runtime/control/stop-service", runtimeControlController.stopService);
|
|
4780
|
+
}
|
|
4781
|
+
function createUiRouteControllers(options, authService, marketplaceBaseUrl) {
|
|
4782
|
+
return {
|
|
4783
|
+
app: new AppRoutesController(options),
|
|
4784
|
+
agents: new AgentsRoutesController(options),
|
|
4785
|
+
auth: new AuthRoutesController(authService),
|
|
4786
|
+
config: new ConfigRoutesController(options),
|
|
4787
|
+
cron: new CronRoutesController(options),
|
|
4788
|
+
ncpSession: new NcpSessionRoutesController(options),
|
|
4789
|
+
ncpAsset: new NcpAssetRoutesController(options),
|
|
4790
|
+
serverPath: new ServerPathRoutesController(),
|
|
4791
|
+
remote: options.remoteAccess ? new RemoteRoutesController(options.remoteAccess) : null,
|
|
4792
|
+
runtimeControl: options.runtimeControl ? new RuntimeControlRoutesController(options.runtimeControl) : null,
|
|
4793
|
+
pluginMarketplace: new PluginMarketplaceController(options, marketplaceBaseUrl),
|
|
4794
|
+
skillMarketplace: new SkillMarketplaceController(options, marketplaceBaseUrl),
|
|
4795
|
+
mcpMarketplace: new McpMarketplaceController(options, marketplaceBaseUrl)
|
|
4796
|
+
};
|
|
4797
|
+
}
|
|
4529
4798
|
function createUiRouter(options) {
|
|
4530
4799
|
const app = new Hono();
|
|
4531
4800
|
const marketplaceBaseUrl = normalizeMarketplaceBaseUrl(options);
|
|
4532
4801
|
const authService = options.authService ?? new UiAuthService(options.configPath);
|
|
4533
|
-
const
|
|
4534
|
-
const agentsController = new AgentsRoutesController(options);
|
|
4535
|
-
const authController = new AuthRoutesController(authService);
|
|
4536
|
-
const configController = new ConfigRoutesController(options);
|
|
4537
|
-
const cronController = new CronRoutesController(options);
|
|
4538
|
-
const ncpSessionController = new NcpSessionRoutesController(options);
|
|
4539
|
-
const ncpAssetController = new NcpAssetRoutesController(options);
|
|
4540
|
-
const serverPathController = new ServerPathRoutesController();
|
|
4541
|
-
const remoteController = options.remoteAccess ? new RemoteRoutesController(options.remoteAccess) : null;
|
|
4542
|
-
const pluginMarketplaceController = new PluginMarketplaceController(options, marketplaceBaseUrl);
|
|
4543
|
-
const skillMarketplaceController = new SkillMarketplaceController(options, marketplaceBaseUrl);
|
|
4544
|
-
const mcpMarketplaceController = new McpMarketplaceController(options, marketplaceBaseUrl);
|
|
4802
|
+
const controllers = createUiRouteControllers(options, authService, marketplaceBaseUrl);
|
|
4545
4803
|
app.notFound((c) => c.json(err("NOT_FOUND", "endpoint not found"), 404));
|
|
4546
4804
|
app.use("/api/*", async (c, next) => {
|
|
4547
4805
|
const path = c.req.path;
|
|
@@ -4556,21 +4814,22 @@ function createUiRouter(options) {
|
|
|
4556
4814
|
c.status(401);
|
|
4557
4815
|
return c.json(err("UNAUTHORIZED", "Authentication required."), 401);
|
|
4558
4816
|
});
|
|
4559
|
-
app.get("/api/health",
|
|
4560
|
-
app.get("/api/app/meta",
|
|
4561
|
-
app.get("/api/runtime/bootstrap-status",
|
|
4562
|
-
registerAuthRoutes(app,
|
|
4563
|
-
registerAgentRoutes(app,
|
|
4564
|
-
registerConfigRoutes(app,
|
|
4565
|
-
registerNcpSessionRoutes(app,
|
|
4566
|
-
registerServerPathRoutes(app,
|
|
4567
|
-
registerNcpRuntimeRoutes(app, options,
|
|
4568
|
-
registerCronRoutes(app,
|
|
4569
|
-
registerRemoteRoutes(app,
|
|
4817
|
+
app.get("/api/health", controllers.app.health);
|
|
4818
|
+
app.get("/api/app/meta", controllers.app.appMeta);
|
|
4819
|
+
app.get("/api/runtime/bootstrap-status", controllers.app.bootstrapStatus);
|
|
4820
|
+
registerAuthRoutes(app, controllers.auth);
|
|
4821
|
+
registerAgentRoutes(app, controllers.agents);
|
|
4822
|
+
registerConfigRoutes(app, controllers.config);
|
|
4823
|
+
registerNcpSessionRoutes(app, controllers.ncpSession);
|
|
4824
|
+
registerServerPathRoutes(app, controllers.serverPath);
|
|
4825
|
+
registerNcpRuntimeRoutes(app, options, controllers.ncpAsset);
|
|
4826
|
+
registerCronRoutes(app, controllers.cron);
|
|
4827
|
+
registerRemoteRoutes(app, controllers.remote);
|
|
4828
|
+
registerRuntimeControlRoutes(app, controllers.runtimeControl);
|
|
4570
4829
|
mountMarketplaceRoutes(app, {
|
|
4571
|
-
plugin:
|
|
4572
|
-
skill:
|
|
4573
|
-
mcp:
|
|
4830
|
+
plugin: controllers.pluginMarketplace,
|
|
4831
|
+
skill: controllers.skillMarketplace,
|
|
4832
|
+
mcp: controllers.mcpMarketplace
|
|
4574
4833
|
});
|
|
4575
4834
|
return app;
|
|
4576
4835
|
}
|
|
@@ -4656,6 +4915,7 @@ function startUiServer(options) {
|
|
|
4656
4915
|
ncpSessionService: options.ncpSessionService,
|
|
4657
4916
|
authService,
|
|
4658
4917
|
remoteAccess: options.remoteAccess,
|
|
4918
|
+
runtimeControl: options.runtimeControl,
|
|
4659
4919
|
getBootstrapStatus: options.getBootstrapStatus,
|
|
4660
4920
|
getPluginChannelBindings: options.getPluginChannelBindings,
|
|
4661
4921
|
getPluginUiMetadata: options.getPluginUiMetadata
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/server",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Nextclaw UI/API server.",
|
|
6
6
|
"type": "module",
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
"@hono/node-server": "^1.13.3",
|
|
19
19
|
"hono": "^4.6.2",
|
|
20
20
|
"ws": "^8.18.0",
|
|
21
|
-
"@nextclaw/core": "0.12.
|
|
22
|
-
"@nextclaw/
|
|
23
|
-
"@nextclaw/ncp
|
|
24
|
-
"@nextclaw/ncp": "0.
|
|
25
|
-
"@nextclaw/
|
|
26
|
-
"@nextclaw/runtime": "0.2.
|
|
21
|
+
"@nextclaw/core": "0.12.7",
|
|
22
|
+
"@nextclaw/openclaw-compat": "1.0.7",
|
|
23
|
+
"@nextclaw/ncp": "0.5.2",
|
|
24
|
+
"@nextclaw/ncp-http-agent-server": "0.3.14",
|
|
25
|
+
"@nextclaw/mcp": "0.1.72",
|
|
26
|
+
"@nextclaw/runtime": "0.2.39"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^20.17.6",
|