@nextclaw/server 0.12.2 → 0.12.4
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 +6 -1
- package/dist/index.js +73 -45
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -372,6 +372,7 @@ type UiRemoteAccessHost = {
|
|
|
372
372
|
startBrowserAuth: (input: RemoteBrowserAuthStartRequest) => Promise<RemoteBrowserAuthStartResult>;
|
|
373
373
|
pollBrowserAuth: (input: RemoteBrowserAuthPollRequest) => Promise<RemoteBrowserAuthPollResult>;
|
|
374
374
|
logout: () => Promise<RemoteAccessView> | RemoteAccessView;
|
|
375
|
+
updateProfile: (input: RemoteAccountProfileUpdateRequest) => Promise<RemoteAccessView> | RemoteAccessView;
|
|
375
376
|
updateSettings: (input: RemoteSettingsUpdateRequest) => Promise<RemoteAccessView> | RemoteAccessView;
|
|
376
377
|
runDoctor: () => Promise<RemoteDoctorView>;
|
|
377
378
|
controlService: (action: RemoteServiceAction) => Promise<RemoteServiceActionResult>;
|
|
@@ -615,10 +616,14 @@ type AuthEnabledUpdateRequest = {
|
|
|
615
616
|
type RemoteAccountView = {
|
|
616
617
|
loggedIn: boolean;
|
|
617
618
|
email?: string;
|
|
619
|
+
username?: string | null;
|
|
618
620
|
role?: string;
|
|
619
621
|
platformBase?: string | null;
|
|
620
622
|
apiBase?: string | null;
|
|
621
623
|
};
|
|
624
|
+
type RemoteAccountProfileUpdateRequest = {
|
|
625
|
+
username: string;
|
|
626
|
+
};
|
|
622
627
|
type RemoteRuntimeView = {
|
|
623
628
|
enabled: boolean;
|
|
624
629
|
mode: "service" | "foreground";
|
|
@@ -1282,4 +1287,4 @@ declare function getUiBridgeSecretPath(): string;
|
|
|
1282
1287
|
declare function readUiBridgeSecret(): string | null;
|
|
1283
1288
|
declare function ensureUiBridgeSecret(): string;
|
|
1284
1289
|
//#endregion
|
|
1285
|
-
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, 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 };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -2,9 +2,9 @@ import { Hono } from "hono";
|
|
|
2
2
|
import { compress } from "hono/compress";
|
|
3
3
|
import { serve } from "@hono/node-server";
|
|
4
4
|
import { WebSocket, WebSocketServer } from "ws";
|
|
5
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
|
+
import fs, { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
7
|
-
import { dirname, isAbsolute, join, parse, resolve } from "node:path";
|
|
7
|
+
import path, { dirname, 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";
|
|
@@ -1077,6 +1077,7 @@ const PREFERRED_PROVIDER_ORDER_INDEX = new Map([
|
|
|
1077
1077
|
"deepseek",
|
|
1078
1078
|
"minimax",
|
|
1079
1079
|
"moonshot",
|
|
1080
|
+
"kimi-coding",
|
|
1080
1081
|
"zhipu"
|
|
1081
1082
|
].map((name, index) => [name, index]));
|
|
1082
1083
|
const BUILTIN_PROVIDERS = listServerBuiltinProviders();
|
|
@@ -2796,7 +2797,6 @@ var NcpAssetRoutesController = class {
|
|
|
2796
2797
|
if (!record || !contentPath) return c.json(err("NOT_FOUND", `asset not found: ${uri}`), 404);
|
|
2797
2798
|
const body = await readFile(contentPath);
|
|
2798
2799
|
return new Response(body, { headers: {
|
|
2799
|
-
"content-length": String(body.byteLength),
|
|
2800
2800
|
"content-type": record.mimeType || "application/octet-stream",
|
|
2801
2801
|
"content-disposition": `inline; filename*=UTF-8''${encodeContentDispositionFileName(record.fileName)}`
|
|
2802
2802
|
} });
|
|
@@ -3492,6 +3492,21 @@ var McpMarketplaceController = class {
|
|
|
3492
3492
|
};
|
|
3493
3493
|
//#endregion
|
|
3494
3494
|
//#region src/ui/ui-routes/marketplace/spec.ts
|
|
3495
|
+
function readPluginPackageNameFromSource(source) {
|
|
3496
|
+
const trimmed = source?.trim();
|
|
3497
|
+
if (!trimmed) return;
|
|
3498
|
+
let cursor = path.dirname(path.resolve(trimmed));
|
|
3499
|
+
for (let index = 0; index < 8; index += 1) {
|
|
3500
|
+
try {
|
|
3501
|
+
const manifestPath = path.join(cursor, "package.json");
|
|
3502
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
3503
|
+
if (typeof manifest.name === "string" && manifest.name.trim().length > 0) return manifest.name.trim();
|
|
3504
|
+
} catch {}
|
|
3505
|
+
const parent = path.dirname(cursor);
|
|
3506
|
+
if (parent === cursor) break;
|
|
3507
|
+
cursor = parent;
|
|
3508
|
+
}
|
|
3509
|
+
}
|
|
3495
3510
|
function normalizePluginNpmSpec(rawSpec) {
|
|
3496
3511
|
const spec = rawSpec.trim();
|
|
3497
3512
|
if (!spec.startsWith("@")) return spec;
|
|
@@ -3513,6 +3528,12 @@ function resolvePluginCanonicalSpec(params) {
|
|
|
3513
3528
|
}
|
|
3514
3529
|
return params.pluginId;
|
|
3515
3530
|
}
|
|
3531
|
+
function resolveDiscoveredPluginCanonicalSpec(params) {
|
|
3532
|
+
return resolvePluginCanonicalSpec({
|
|
3533
|
+
pluginId: params.pluginId,
|
|
3534
|
+
installSpec: params.installSpec ?? readPluginPackageNameFromSource(params.source)
|
|
3535
|
+
});
|
|
3536
|
+
}
|
|
3516
3537
|
function readPluginRuntimeStatusPriority(status) {
|
|
3517
3538
|
if (status === "loaded") return 400;
|
|
3518
3539
|
if (status === "disabled") return 300;
|
|
@@ -3607,36 +3628,32 @@ function buildDiscoveredPluginMap(params) {
|
|
|
3607
3628
|
}
|
|
3608
3629
|
return discoveredById;
|
|
3609
3630
|
}
|
|
3610
|
-
function
|
|
3611
|
-
|
|
3631
|
+
function collectDiscoveredPluginRecords(params) {
|
|
3632
|
+
return Array.from(params.discoveredById.values()).map((plugin) => {
|
|
3612
3633
|
const installRecord = params.pluginRecordsMap[plugin.id];
|
|
3613
3634
|
const entry = params.pluginEntries[plugin.id];
|
|
3614
|
-
|
|
3615
|
-
pluginId: plugin.id,
|
|
3616
|
-
installSpec: installRecord?.spec
|
|
3617
|
-
});
|
|
3618
|
-
const enabled = entry?.enabled === false ? false : plugin.enabled;
|
|
3619
|
-
const runtimeStatus = entry?.enabled === false ? "disabled" : plugin.status;
|
|
3620
|
-
params.pluginRecords.push({
|
|
3635
|
+
return {
|
|
3621
3636
|
type: "plugin",
|
|
3622
3637
|
id: plugin.id,
|
|
3623
|
-
spec:
|
|
3638
|
+
spec: resolveDiscoveredPluginCanonicalSpec({
|
|
3639
|
+
pluginId: plugin.id,
|
|
3640
|
+
installSpec: installRecord?.spec,
|
|
3641
|
+
source: plugin.source
|
|
3642
|
+
}),
|
|
3624
3643
|
label: plugin.name && plugin.name.trim().length > 0 ? plugin.name : plugin.id,
|
|
3625
3644
|
source: plugin.source,
|
|
3626
3645
|
installedAt: installRecord?.installedAt,
|
|
3627
|
-
enabled,
|
|
3628
|
-
runtimeStatus,
|
|
3646
|
+
enabled: entry?.enabled === false ? false : plugin.enabled,
|
|
3647
|
+
runtimeStatus: entry?.enabled === false ? "disabled" : plugin.status,
|
|
3629
3648
|
origin: plugin.origin,
|
|
3630
3649
|
installPath: installRecord?.installPath
|
|
3631
|
-
}
|
|
3632
|
-
|
|
3633
|
-
}
|
|
3650
|
+
};
|
|
3651
|
+
});
|
|
3634
3652
|
}
|
|
3635
|
-
function
|
|
3636
|
-
|
|
3637
|
-
if (params.seenPluginIds.has(pluginId)) continue;
|
|
3653
|
+
function collectInstalledOnlyPluginRecords(params) {
|
|
3654
|
+
return Object.entries(params.pluginRecordsMap).filter(([pluginId]) => !params.seenPluginIds.has(pluginId)).map(([pluginId, installRecord]) => {
|
|
3638
3655
|
const entry = params.pluginEntries[pluginId];
|
|
3639
|
-
|
|
3656
|
+
return {
|
|
3640
3657
|
type: "plugin",
|
|
3641
3658
|
id: pluginId,
|
|
3642
3659
|
spec: resolvePluginCanonicalSpec({
|
|
@@ -3649,14 +3666,12 @@ function appendInstalledOnlyPluginRecords(params) {
|
|
|
3649
3666
|
enabled: entry?.enabled !== false,
|
|
3650
3667
|
runtimeStatus: entry?.enabled === false ? "disabled" : "unresolved",
|
|
3651
3668
|
installPath: installRecord.installPath
|
|
3652
|
-
}
|
|
3653
|
-
|
|
3654
|
-
}
|
|
3669
|
+
};
|
|
3670
|
+
});
|
|
3655
3671
|
}
|
|
3656
|
-
function
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
params.pluginRecords.push({
|
|
3672
|
+
function collectConfigOnlyPluginRecords(params) {
|
|
3673
|
+
return Object.entries(params.pluginEntries).filter(([pluginId]) => !params.seenPluginIds.has(pluginId)).map(([pluginId, entry]) => {
|
|
3674
|
+
return {
|
|
3660
3675
|
type: "plugin",
|
|
3661
3676
|
id: pluginId,
|
|
3662
3677
|
spec: resolvePluginCanonicalSpec({ pluginId }),
|
|
@@ -3664,9 +3679,8 @@ function appendConfigOnlyPluginRecords(params) {
|
|
|
3664
3679
|
source: "config",
|
|
3665
3680
|
enabled: entry?.enabled !== false,
|
|
3666
3681
|
runtimeStatus: entry?.enabled === false ? "disabled" : "unresolved"
|
|
3667
|
-
}
|
|
3668
|
-
|
|
3669
|
-
}
|
|
3682
|
+
};
|
|
3683
|
+
});
|
|
3670
3684
|
}
|
|
3671
3685
|
function findPluginIdByExactId(pluginRecords, lowerTargetId) {
|
|
3672
3686
|
for (const record of pluginRecords) {
|
|
@@ -3682,12 +3696,13 @@ function findPluginIdByNormalizedSpec(pluginRecords, normalizedSpec) {
|
|
|
3682
3696
|
if (normalizePluginNpmSpec(record.spec).toLowerCase() === normalizedSpec) return recordId;
|
|
3683
3697
|
}
|
|
3684
3698
|
}
|
|
3699
|
+
function collectDefinedRecordIds(records) {
|
|
3700
|
+
return new Set(records.map((record) => readNonEmptyString(record.id)).filter((recordId) => Boolean(recordId)));
|
|
3701
|
+
}
|
|
3685
3702
|
function collectInstalledPluginRecords(options) {
|
|
3686
3703
|
const config = loadConfigOrDefault(options.configPath);
|
|
3687
3704
|
const pluginRecordsMap = config.plugins.installs ?? {};
|
|
3688
3705
|
const pluginEntries = config.plugins.entries ?? {};
|
|
3689
|
-
const pluginRecords = [];
|
|
3690
|
-
const seenPluginIds = /* @__PURE__ */ new Set();
|
|
3691
3706
|
const installedPluginIds = new Set(Object.keys(pluginRecordsMap));
|
|
3692
3707
|
let discoveredPlugins = [];
|
|
3693
3708
|
try {
|
|
@@ -3698,28 +3713,29 @@ function collectInstalledPluginRecords(options) {
|
|
|
3698
3713
|
} catch {
|
|
3699
3714
|
discoveredPlugins = [];
|
|
3700
3715
|
}
|
|
3701
|
-
|
|
3716
|
+
const discoveredRecords = collectDiscoveredPluginRecords({
|
|
3702
3717
|
discoveredById: buildDiscoveredPluginMap({
|
|
3703
3718
|
discoveredPlugins,
|
|
3704
3719
|
installedPluginIds
|
|
3705
3720
|
}),
|
|
3706
3721
|
pluginRecordsMap,
|
|
3707
|
-
pluginEntries
|
|
3708
|
-
pluginRecords,
|
|
3709
|
-
seenPluginIds
|
|
3722
|
+
pluginEntries
|
|
3710
3723
|
});
|
|
3711
|
-
|
|
3724
|
+
const seenDiscoveredPluginIds = collectDefinedRecordIds(discoveredRecords);
|
|
3725
|
+
const installedOnlyRecords = collectInstalledOnlyPluginRecords({
|
|
3712
3726
|
pluginRecordsMap,
|
|
3713
3727
|
pluginEntries,
|
|
3714
|
-
|
|
3715
|
-
seenPluginIds
|
|
3728
|
+
seenPluginIds: seenDiscoveredPluginIds
|
|
3716
3729
|
});
|
|
3717
|
-
|
|
3730
|
+
const configOnlyRecords = collectConfigOnlyPluginRecords({
|
|
3718
3731
|
pluginEntries,
|
|
3719
|
-
|
|
3720
|
-
seenPluginIds
|
|
3732
|
+
seenPluginIds: new Set([...seenDiscoveredPluginIds, ...collectDefinedRecordIds(installedOnlyRecords)])
|
|
3721
3733
|
});
|
|
3722
|
-
const dedupedPluginRecords = dedupeInstalledPluginRecordsByCanonicalSpec(
|
|
3734
|
+
const dedupedPluginRecords = dedupeInstalledPluginRecordsByCanonicalSpec([
|
|
3735
|
+
...discoveredRecords,
|
|
3736
|
+
...installedOnlyRecords,
|
|
3737
|
+
...configOnlyRecords
|
|
3738
|
+
]);
|
|
3723
3739
|
dedupedPluginRecords.sort((left, right) => {
|
|
3724
3740
|
return left.spec.localeCompare(right.spec);
|
|
3725
3741
|
});
|
|
@@ -4292,6 +4308,17 @@ var RemoteRoutesController = class {
|
|
|
4292
4308
|
return c.json(err("REMOTE_LOGOUT_FAILED", formatUserFacingError(error)), 500);
|
|
4293
4309
|
}
|
|
4294
4310
|
};
|
|
4311
|
+
updateProfile = async (c) => {
|
|
4312
|
+
const body = await readJson(c.req.raw);
|
|
4313
|
+
if (!body.ok) return c.json(err("INVALID_BODY", "invalid json body"), 400);
|
|
4314
|
+
const username = readNonEmptyString(body.data.username);
|
|
4315
|
+
if (!username) return c.json(err("INVALID_BODY", "username is required"), 400);
|
|
4316
|
+
try {
|
|
4317
|
+
return c.json(ok(await this.host.updateProfile({ username })));
|
|
4318
|
+
} catch (error) {
|
|
4319
|
+
return c.json(err("REMOTE_PROFILE_UPDATE_FAILED", formatUserFacingError(error)), 400);
|
|
4320
|
+
}
|
|
4321
|
+
};
|
|
4295
4322
|
updateSettings = async (c) => {
|
|
4296
4323
|
const body = await readJson(c.req.raw);
|
|
4297
4324
|
if (!body.ok) return c.json(err("INVALID_BODY", "invalid json body"), 400);
|
|
@@ -4495,6 +4522,7 @@ function registerRemoteRoutes(app, remoteController) {
|
|
|
4495
4522
|
app.post("/api/remote/auth/start", remoteController.startBrowserAuth);
|
|
4496
4523
|
app.post("/api/remote/auth/poll", remoteController.pollBrowserAuth);
|
|
4497
4524
|
app.post("/api/remote/logout", remoteController.logout);
|
|
4525
|
+
app.put("/api/remote/account/profile", remoteController.updateProfile);
|
|
4498
4526
|
app.put("/api/remote/settings", remoteController.updateSettings);
|
|
4499
4527
|
app.post("/api/remote/service/:action", remoteController.controlService);
|
|
4500
4528
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/server",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.4",
|
|
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/mcp": "0.1.
|
|
21
|
+
"@nextclaw/core": "0.12.4",
|
|
22
|
+
"@nextclaw/mcp": "0.1.69",
|
|
23
23
|
"@nextclaw/ncp": "0.5.0",
|
|
24
24
|
"@nextclaw/ncp-http-agent-server": "0.3.12",
|
|
25
|
-
"@nextclaw/openclaw-compat": "1.0.
|
|
26
|
-
"@nextclaw/runtime": "0.2.
|
|
25
|
+
"@nextclaw/openclaw-compat": "1.0.4",
|
|
26
|
+
"@nextclaw/runtime": "0.2.36"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^20.17.6",
|