@nextclaw/server 0.10.8 → 0.10.10
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 +154 -52
- package/dist/index.js +189 -44
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import * as NextclawCore from '@nextclaw/core';
|
|
|
2
2
|
import { ThinkingLevel, CronService, Config, ConfigActionExecuteRequest as ConfigActionExecuteRequest$1, ConfigActionExecuteResult as ConfigActionExecuteResult$1 } from '@nextclaw/core';
|
|
3
3
|
import { NcpAgentClientEndpoint, NcpSessionApi, NcpSessionSummary, NcpMessage } from '@nextclaw/ncp';
|
|
4
4
|
import { NcpHttpAgentStreamProvider } from '@nextclaw/ncp-http-agent-server';
|
|
5
|
-
import { Hono } from 'hono';
|
|
6
5
|
import { IncomingMessage } from 'node:http';
|
|
6
|
+
import { Hono } from 'hono';
|
|
7
7
|
|
|
8
8
|
type MarketplaceItemType = "plugin" | "skill" | "mcp";
|
|
9
9
|
type MarketplaceSort = "relevance" | "updated";
|
|
@@ -283,6 +283,67 @@ type MarketplaceApiConfig = {
|
|
|
283
283
|
installer?: MarketplaceInstaller;
|
|
284
284
|
};
|
|
285
285
|
|
|
286
|
+
declare class UiAuthService {
|
|
287
|
+
private readonly configPath;
|
|
288
|
+
private readonly sessions;
|
|
289
|
+
constructor(configPath: string);
|
|
290
|
+
private loadCurrentConfig;
|
|
291
|
+
private saveCurrentConfig;
|
|
292
|
+
private readAuthConfig;
|
|
293
|
+
private isConfigured;
|
|
294
|
+
isProtectionEnabled(): boolean;
|
|
295
|
+
private getSessionIdFromCookieHeader;
|
|
296
|
+
private getValidSession;
|
|
297
|
+
isRequestAuthenticated(request: Request): boolean;
|
|
298
|
+
isSocketAuthenticated(request: IncomingMessage): boolean;
|
|
299
|
+
getStatus(request: Request): AuthStatusView;
|
|
300
|
+
private createSession;
|
|
301
|
+
private clearAllSessions;
|
|
302
|
+
private deleteRequestSession;
|
|
303
|
+
private buildLoginCookie;
|
|
304
|
+
buildTrustedRequestCookieHeader(): string | null;
|
|
305
|
+
buildLogoutCookie(request: Request): string;
|
|
306
|
+
setup(request: Request, payload: AuthSetupRequest): {
|
|
307
|
+
status: AuthStatusView;
|
|
308
|
+
cookie: string;
|
|
309
|
+
};
|
|
310
|
+
login(request: Request, payload: AuthLoginRequest): {
|
|
311
|
+
status: AuthStatusView;
|
|
312
|
+
cookie: string;
|
|
313
|
+
};
|
|
314
|
+
logout(request: Request): void;
|
|
315
|
+
updatePassword(request: Request, payload: AuthPasswordUpdateRequest): {
|
|
316
|
+
status: AuthStatusView;
|
|
317
|
+
cookie?: string;
|
|
318
|
+
};
|
|
319
|
+
updateEnabled(request: Request, payload: AuthEnabledUpdateRequest): {
|
|
320
|
+
status: AuthStatusView;
|
|
321
|
+
cookie?: string;
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
type UiRouterOptions = {
|
|
326
|
+
configPath: string;
|
|
327
|
+
productVersion?: string;
|
|
328
|
+
publish: (event: UiServerEvent) => void;
|
|
329
|
+
marketplace?: MarketplaceApiConfig;
|
|
330
|
+
cronService?: InstanceType<typeof NextclawCore.CronService>;
|
|
331
|
+
chatRuntime?: UiChatRuntime;
|
|
332
|
+
ncpAgent?: UiNcpAgent;
|
|
333
|
+
authService?: UiAuthService;
|
|
334
|
+
remoteAccess?: UiRemoteAccessHost;
|
|
335
|
+
};
|
|
336
|
+
type UiRemoteAccessHost = {
|
|
337
|
+
getStatus: () => Promise<RemoteAccessView> | RemoteAccessView;
|
|
338
|
+
login: (input: RemoteLoginRequest) => Promise<RemoteAccessView>;
|
|
339
|
+
startBrowserAuth: (input: RemoteBrowserAuthStartRequest) => Promise<RemoteBrowserAuthStartResult>;
|
|
340
|
+
pollBrowserAuth: (input: RemoteBrowserAuthPollRequest) => Promise<RemoteBrowserAuthPollResult>;
|
|
341
|
+
logout: () => Promise<RemoteAccessView> | RemoteAccessView;
|
|
342
|
+
updateSettings: (input: RemoteSettingsUpdateRequest) => Promise<RemoteAccessView> | RemoteAccessView;
|
|
343
|
+
runDoctor: () => Promise<RemoteDoctorView>;
|
|
344
|
+
controlService: (action: RemoteServiceAction) => Promise<RemoteServiceActionResult>;
|
|
345
|
+
};
|
|
346
|
+
|
|
286
347
|
type ChatSessionTypeCtaView = {
|
|
287
348
|
kind: string;
|
|
288
349
|
label?: string;
|
|
@@ -454,6 +515,96 @@ type AuthPasswordUpdateRequest = {
|
|
|
454
515
|
type AuthEnabledUpdateRequest = {
|
|
455
516
|
enabled: boolean;
|
|
456
517
|
};
|
|
518
|
+
type RemoteAccountView = {
|
|
519
|
+
loggedIn: boolean;
|
|
520
|
+
email?: string;
|
|
521
|
+
role?: string;
|
|
522
|
+
platformBase?: string | null;
|
|
523
|
+
apiBase?: string | null;
|
|
524
|
+
};
|
|
525
|
+
type RemoteRuntimeView = {
|
|
526
|
+
enabled: boolean;
|
|
527
|
+
mode: "service" | "foreground";
|
|
528
|
+
state: "disabled" | "connecting" | "connected" | "disconnected" | "error";
|
|
529
|
+
deviceId?: string;
|
|
530
|
+
deviceName?: string;
|
|
531
|
+
platformBase?: string;
|
|
532
|
+
localOrigin?: string;
|
|
533
|
+
lastConnectedAt?: string | null;
|
|
534
|
+
lastError?: string | null;
|
|
535
|
+
updatedAt: string;
|
|
536
|
+
};
|
|
537
|
+
type RemoteServiceView = {
|
|
538
|
+
running: boolean;
|
|
539
|
+
pid?: number;
|
|
540
|
+
uiUrl?: string;
|
|
541
|
+
uiPort?: number;
|
|
542
|
+
currentProcess: boolean;
|
|
543
|
+
};
|
|
544
|
+
type RemoteSettingsView = {
|
|
545
|
+
enabled: boolean;
|
|
546
|
+
deviceName: string;
|
|
547
|
+
platformApiBase: string;
|
|
548
|
+
};
|
|
549
|
+
type RemoteAccessView = {
|
|
550
|
+
account: RemoteAccountView;
|
|
551
|
+
settings: RemoteSettingsView;
|
|
552
|
+
service: RemoteServiceView;
|
|
553
|
+
localOrigin: string;
|
|
554
|
+
configuredEnabled: boolean;
|
|
555
|
+
platformBase?: string | null;
|
|
556
|
+
runtime: RemoteRuntimeView | null;
|
|
557
|
+
};
|
|
558
|
+
type RemoteDoctorCheckView = {
|
|
559
|
+
name: string;
|
|
560
|
+
ok: boolean;
|
|
561
|
+
detail: string;
|
|
562
|
+
};
|
|
563
|
+
type RemoteDoctorView = {
|
|
564
|
+
generatedAt: string;
|
|
565
|
+
checks: RemoteDoctorCheckView[];
|
|
566
|
+
snapshot: {
|
|
567
|
+
configuredEnabled: boolean;
|
|
568
|
+
runtime: RemoteRuntimeView | null;
|
|
569
|
+
};
|
|
570
|
+
};
|
|
571
|
+
type RemoteLoginRequest = {
|
|
572
|
+
email: string;
|
|
573
|
+
password: string;
|
|
574
|
+
apiBase?: string;
|
|
575
|
+
register?: boolean;
|
|
576
|
+
};
|
|
577
|
+
type RemoteBrowserAuthStartRequest = {
|
|
578
|
+
apiBase?: string;
|
|
579
|
+
};
|
|
580
|
+
type RemoteBrowserAuthStartResult = {
|
|
581
|
+
sessionId: string;
|
|
582
|
+
verificationUri: string;
|
|
583
|
+
expiresAt: string;
|
|
584
|
+
intervalMs: number;
|
|
585
|
+
};
|
|
586
|
+
type RemoteBrowserAuthPollRequest = {
|
|
587
|
+
sessionId: string;
|
|
588
|
+
apiBase?: string;
|
|
589
|
+
};
|
|
590
|
+
type RemoteBrowserAuthPollResult = {
|
|
591
|
+
status: "pending" | "authorized" | "expired";
|
|
592
|
+
message?: string;
|
|
593
|
+
nextPollMs?: number;
|
|
594
|
+
email?: string;
|
|
595
|
+
role?: string;
|
|
596
|
+
};
|
|
597
|
+
type RemoteSettingsUpdateRequest = {
|
|
598
|
+
enabled?: boolean;
|
|
599
|
+
deviceName?: string;
|
|
600
|
+
platformApiBase?: string;
|
|
601
|
+
};
|
|
602
|
+
type RemoteServiceAction = "start" | "restart" | "stop";
|
|
603
|
+
type RemoteServiceActionResult = {
|
|
604
|
+
accepted: boolean;
|
|
605
|
+
action: RemoteServiceAction;
|
|
606
|
+
message: string;
|
|
607
|
+
};
|
|
457
608
|
type AgentProfileView = {
|
|
458
609
|
id: string;
|
|
459
610
|
default?: boolean;
|
|
@@ -965,6 +1116,7 @@ type UiServerOptions = {
|
|
|
965
1116
|
cronService?: CronService;
|
|
966
1117
|
chatRuntime?: UiChatRuntime;
|
|
967
1118
|
ncpAgent?: UiNcpAgent;
|
|
1119
|
+
remoteAccess?: UiRemoteAccessHost;
|
|
968
1120
|
};
|
|
969
1121
|
type UiServerHandle = {
|
|
970
1122
|
host: string;
|
|
@@ -975,56 +1127,6 @@ type UiServerHandle = {
|
|
|
975
1127
|
|
|
976
1128
|
declare function startUiServer(options: UiServerOptions): UiServerHandle;
|
|
977
1129
|
|
|
978
|
-
declare class UiAuthService {
|
|
979
|
-
private readonly configPath;
|
|
980
|
-
private readonly sessions;
|
|
981
|
-
constructor(configPath: string);
|
|
982
|
-
private loadCurrentConfig;
|
|
983
|
-
private saveCurrentConfig;
|
|
984
|
-
private readAuthConfig;
|
|
985
|
-
private isConfigured;
|
|
986
|
-
isProtectionEnabled(): boolean;
|
|
987
|
-
private getSessionIdFromCookieHeader;
|
|
988
|
-
private getValidSession;
|
|
989
|
-
isRequestAuthenticated(request: Request): boolean;
|
|
990
|
-
isSocketAuthenticated(request: IncomingMessage): boolean;
|
|
991
|
-
getStatus(request: Request): AuthStatusView;
|
|
992
|
-
private createSession;
|
|
993
|
-
private clearAllSessions;
|
|
994
|
-
private deleteRequestSession;
|
|
995
|
-
private buildLoginCookie;
|
|
996
|
-
buildTrustedRequestCookieHeader(): string | null;
|
|
997
|
-
buildLogoutCookie(request: Request): string;
|
|
998
|
-
setup(request: Request, payload: AuthSetupRequest): {
|
|
999
|
-
status: AuthStatusView;
|
|
1000
|
-
cookie: string;
|
|
1001
|
-
};
|
|
1002
|
-
login(request: Request, payload: AuthLoginRequest): {
|
|
1003
|
-
status: AuthStatusView;
|
|
1004
|
-
cookie: string;
|
|
1005
|
-
};
|
|
1006
|
-
logout(request: Request): void;
|
|
1007
|
-
updatePassword(request: Request, payload: AuthPasswordUpdateRequest): {
|
|
1008
|
-
status: AuthStatusView;
|
|
1009
|
-
cookie?: string;
|
|
1010
|
-
};
|
|
1011
|
-
updateEnabled(request: Request, payload: AuthEnabledUpdateRequest): {
|
|
1012
|
-
status: AuthStatusView;
|
|
1013
|
-
cookie?: string;
|
|
1014
|
-
};
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
type UiRouterOptions = {
|
|
1018
|
-
configPath: string;
|
|
1019
|
-
productVersion?: string;
|
|
1020
|
-
publish: (event: UiServerEvent) => void;
|
|
1021
|
-
marketplace?: MarketplaceApiConfig;
|
|
1022
|
-
cronService?: InstanceType<typeof NextclawCore.CronService>;
|
|
1023
|
-
chatRuntime?: UiChatRuntime;
|
|
1024
|
-
ncpAgent?: UiNcpAgent;
|
|
1025
|
-
authService?: UiAuthService;
|
|
1026
|
-
};
|
|
1027
|
-
|
|
1028
1130
|
declare function createUiRouter(options: UiRouterOptions): Hono;
|
|
1029
1131
|
|
|
1030
1132
|
type ExecuteActionResult = {
|
|
@@ -1075,4 +1177,4 @@ declare function getUiBridgeSecretPath(): string;
|
|
|
1075
1177
|
declare function readUiBridgeSecret(): string | null;
|
|
1076
1178
|
declare function ensureUiBridgeSecret(): string;
|
|
1077
1179
|
|
|
1078
|
-
export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type AppMetaView, type AuthEnabledUpdateRequest, type AuthLoginRequest, type AuthPasswordUpdateRequest, type AuthSetupRequest, type AuthStatusView, type BindingPeerView, type BochaFreshnessValue, type ChannelSpecView, type ChatCapabilitiesView, type ChatCommandOptionView, type ChatCommandView, type ChatCommandsView, type ChatRunListView, type ChatRunState, type ChatRunView, type ChatSessionTypeCtaView, type ChatSessionTypeOptionView, type ChatSessionTypesView, type ChatTurnRequest, type ChatTurnResult, type ChatTurnStopRequest, type ChatTurnStopResult, type ChatTurnStreamEvent, type ChatTurnView, type ConfigActionExecuteRequest, type ConfigActionExecuteResult, type ConfigActionManifest, type ConfigActionType, type ConfigMetaView, type ConfigSchemaResponse, type ConfigUiHint, type ConfigUiHints, type ConfigView, type CronActionResult, type CronEnableRequest, type CronJobStateView, type CronJobView, type CronListView, type CronPayloadView, type CronRunRequest, type CronScheduleView, DEFAULT_SESSION_TYPE, type MarketplaceApiConfig, type MarketplaceInstallKind, type MarketplaceInstallSkillParams, type MarketplaceInstallSpec, type MarketplaceInstalledRecord, type MarketplaceInstalledView, type MarketplaceInstaller, type MarketplaceItemSummary, type MarketplaceItemType, type MarketplaceItemView, type MarketplaceListView, type MarketplaceLocalizedTextMap, type MarketplaceMcpContentView, type MarketplaceMcpDoctorResult, type MarketplaceMcpInstallKind, type MarketplaceMcpInstallRequest, type MarketplaceMcpInstallResult, type MarketplaceMcpInstallSpec, type MarketplaceMcpManageAction, type MarketplaceMcpManageRequest, type MarketplaceMcpManageResult, type MarketplaceMcpTemplateInput, type MarketplacePluginContentView, type MarketplacePluginInstallKind, type MarketplacePluginInstallRequest, type MarketplacePluginInstallResult, type MarketplacePluginManageAction, type MarketplacePluginManageRequest, type MarketplacePluginManageResult, type MarketplaceRecommendationView, type MarketplaceSkillContentView, type MarketplaceSkillInstallKind, type MarketplaceSkillInstallRequest, type MarketplaceSkillInstallResult, type MarketplaceSkillManageAction, type MarketplaceSkillManageRequest, type MarketplaceSkillManageResult, type MarketplaceSort, type ProviderAuthImportResult, type ProviderAuthPollRequest, type ProviderAuthPollResult, type ProviderAuthStartRequest, type ProviderAuthStartResult, type ProviderConfigUpdate, type ProviderConfigView, type ProviderConnectionTestRequest, type ProviderConnectionTestResult, type ProviderCreateRequest, type ProviderCreateResult, type ProviderDeleteResult, type ProviderSpecView, type RuntimeConfigUpdate, type SearchConfigUpdate, type SearchConfigView, type SearchProviderConfigView, type SearchProviderName, type SearchProviderSpecView, type SecretProviderEnvView, type SecretProviderExecView, type SecretProviderFileView, type SecretProviderView, type SecretRefView, type SecretSourceView, type SecretsConfigUpdate, type SecretsView, type SessionConfigView, type SessionEntryView, type SessionEventView, type SessionHistoryView, type SessionMessageView, type SessionPatchUpdate, SessionPatchValidationError, type SessionsListView, type UiChatRuntime, type UiNcpAgent, type UiNcpSessionListView, type UiNcpSessionMessagesView, type UiServerEvent, type UiServerHandle, type UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createCustomProvider, createUiRouter, deleteCustomProvider, deleteSession, ensureUiBridgeSecret, executeConfigAction, getSessionHistory, getUiBridgeSecretPath, listSessions, loadConfigOrDefault, patchSession, readUiBridgeSecret, startUiServer, testProviderConnection, updateChannel, updateModel, updateProvider, updateRuntime, updateSearch, updateSecrets };
|
|
1180
|
+
export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type AppMetaView, type AuthEnabledUpdateRequest, type AuthLoginRequest, type AuthPasswordUpdateRequest, type AuthSetupRequest, type AuthStatusView, type BindingPeerView, type BochaFreshnessValue, type ChannelSpecView, type ChatCapabilitiesView, type ChatCommandOptionView, type ChatCommandView, type ChatCommandsView, type ChatRunListView, type ChatRunState, type ChatRunView, type ChatSessionTypeCtaView, type ChatSessionTypeOptionView, type ChatSessionTypesView, type ChatTurnRequest, type ChatTurnResult, type ChatTurnStopRequest, type ChatTurnStopResult, type ChatTurnStreamEvent, type ChatTurnView, type ConfigActionExecuteRequest, type ConfigActionExecuteResult, type ConfigActionManifest, type ConfigActionType, type ConfigMetaView, type ConfigSchemaResponse, type ConfigUiHint, type ConfigUiHints, type ConfigView, type CronActionResult, type CronEnableRequest, type CronJobStateView, type CronJobView, type CronListView, type CronPayloadView, type CronRunRequest, type CronScheduleView, DEFAULT_SESSION_TYPE, type MarketplaceApiConfig, type MarketplaceInstallKind, type MarketplaceInstallSkillParams, type MarketplaceInstallSpec, type MarketplaceInstalledRecord, type MarketplaceInstalledView, type MarketplaceInstaller, type MarketplaceItemSummary, type MarketplaceItemType, type MarketplaceItemView, type MarketplaceListView, type MarketplaceLocalizedTextMap, type MarketplaceMcpContentView, type MarketplaceMcpDoctorResult, type MarketplaceMcpInstallKind, type MarketplaceMcpInstallRequest, type MarketplaceMcpInstallResult, type MarketplaceMcpInstallSpec, type MarketplaceMcpManageAction, type MarketplaceMcpManageRequest, type MarketplaceMcpManageResult, type MarketplaceMcpTemplateInput, type MarketplacePluginContentView, type MarketplacePluginInstallKind, type MarketplacePluginInstallRequest, type MarketplacePluginInstallResult, type MarketplacePluginManageAction, type MarketplacePluginManageRequest, type MarketplacePluginManageResult, type MarketplaceRecommendationView, type MarketplaceSkillContentView, type MarketplaceSkillInstallKind, type MarketplaceSkillInstallRequest, type MarketplaceSkillInstallResult, type MarketplaceSkillManageAction, type MarketplaceSkillManageRequest, type MarketplaceSkillManageResult, type MarketplaceSort, type ProviderAuthImportResult, type ProviderAuthPollRequest, type ProviderAuthPollResult, type ProviderAuthStartRequest, type ProviderAuthStartResult, type ProviderConfigUpdate, type ProviderConfigView, type ProviderConnectionTestRequest, type ProviderConnectionTestResult, type ProviderCreateRequest, type ProviderCreateResult, type ProviderDeleteResult, type ProviderSpecView, type RemoteAccessView, type RemoteAccountView, type RemoteBrowserAuthPollRequest, type RemoteBrowserAuthPollResult, type RemoteBrowserAuthStartRequest, type RemoteBrowserAuthStartResult, type RemoteDoctorCheckView, type RemoteDoctorView, type RemoteLoginRequest, type RemoteRuntimeView, type RemoteServiceAction, type RemoteServiceActionResult, type RemoteServiceView, type RemoteSettingsUpdateRequest, type RemoteSettingsView, type RuntimeConfigUpdate, type SearchConfigUpdate, type SearchConfigView, type SearchProviderConfigView, type SearchProviderName, type SearchProviderSpecView, type SecretProviderEnvView, type SecretProviderExecView, type SecretProviderFileView, type SecretProviderView, type SecretRefView, type SecretSourceView, type SecretsConfigUpdate, type SecretsView, type SessionConfigView, type SessionEntryView, type SessionEventView, type SessionHistoryView, type SessionMessageView, type SessionPatchUpdate, SessionPatchValidationError, type SessionsListView, type UiChatRuntime, type UiNcpAgent, type UiNcpSessionListView, type UiNcpSessionMessagesView, type UiRemoteAccessHost, type UiServerEvent, type UiServerHandle, type 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
|
@@ -4847,6 +4847,119 @@ var SkillMarketplaceController = class {
|
|
|
4847
4847
|
};
|
|
4848
4848
|
};
|
|
4849
4849
|
|
|
4850
|
+
// src/ui/router/remote.controller.ts
|
|
4851
|
+
var REMOTE_SERVICE_ACTIONS = /* @__PURE__ */ new Set(["start", "restart", "stop"]);
|
|
4852
|
+
function readBoolean(value) {
|
|
4853
|
+
return typeof value === "boolean" ? value : void 0;
|
|
4854
|
+
}
|
|
4855
|
+
function readTrimmedString(value) {
|
|
4856
|
+
return typeof value === "string" ? value.trim() : void 0;
|
|
4857
|
+
}
|
|
4858
|
+
var RemoteRoutesController = class {
|
|
4859
|
+
constructor(host) {
|
|
4860
|
+
this.host = host;
|
|
4861
|
+
}
|
|
4862
|
+
getStatus = async (c) => {
|
|
4863
|
+
try {
|
|
4864
|
+
return c.json(ok(await this.host.getStatus()));
|
|
4865
|
+
} catch (error) {
|
|
4866
|
+
return c.json(err("REMOTE_STATUS_FAILED", formatUserFacingError(error)), 500);
|
|
4867
|
+
}
|
|
4868
|
+
};
|
|
4869
|
+
getDoctor = async (c) => {
|
|
4870
|
+
try {
|
|
4871
|
+
return c.json(ok(await this.host.runDoctor()));
|
|
4872
|
+
} catch (error) {
|
|
4873
|
+
return c.json(err("REMOTE_DOCTOR_FAILED", formatUserFacingError(error)), 500);
|
|
4874
|
+
}
|
|
4875
|
+
};
|
|
4876
|
+
login = async (c) => {
|
|
4877
|
+
const body = await readJson(c.req.raw);
|
|
4878
|
+
if (!body.ok) {
|
|
4879
|
+
return c.json(err("INVALID_BODY", "invalid json body"), 400);
|
|
4880
|
+
}
|
|
4881
|
+
const email = readNonEmptyString(body.data.email);
|
|
4882
|
+
const password = readNonEmptyString(body.data.password);
|
|
4883
|
+
if (!email || !password) {
|
|
4884
|
+
return c.json(err("INVALID_BODY", "email and password are required"), 400);
|
|
4885
|
+
}
|
|
4886
|
+
try {
|
|
4887
|
+
return c.json(ok(await this.host.login({
|
|
4888
|
+
email,
|
|
4889
|
+
password,
|
|
4890
|
+
apiBase: readTrimmedString(body.data.apiBase),
|
|
4891
|
+
register: readBoolean(body.data.register)
|
|
4892
|
+
})));
|
|
4893
|
+
} catch (error) {
|
|
4894
|
+
return c.json(err("REMOTE_LOGIN_FAILED", formatUserFacingError(error)), 400);
|
|
4895
|
+
}
|
|
4896
|
+
};
|
|
4897
|
+
startBrowserAuth = async (c) => {
|
|
4898
|
+
const body = await readJson(c.req.raw);
|
|
4899
|
+
if (!body.ok) {
|
|
4900
|
+
return c.json(err("INVALID_BODY", "invalid json body"), 400);
|
|
4901
|
+
}
|
|
4902
|
+
try {
|
|
4903
|
+
return c.json(ok(await this.host.startBrowserAuth({
|
|
4904
|
+
apiBase: readTrimmedString(body.data.apiBase)
|
|
4905
|
+
})));
|
|
4906
|
+
} catch (error) {
|
|
4907
|
+
return c.json(err("REMOTE_BROWSER_AUTH_START_FAILED", formatUserFacingError(error)), 400);
|
|
4908
|
+
}
|
|
4909
|
+
};
|
|
4910
|
+
pollBrowserAuth = async (c) => {
|
|
4911
|
+
const body = await readJson(c.req.raw);
|
|
4912
|
+
if (!body.ok) {
|
|
4913
|
+
return c.json(err("INVALID_BODY", "invalid json body"), 400);
|
|
4914
|
+
}
|
|
4915
|
+
const sessionId = readNonEmptyString(body.data.sessionId);
|
|
4916
|
+
if (!sessionId) {
|
|
4917
|
+
return c.json(err("INVALID_BODY", "sessionId is required"), 400);
|
|
4918
|
+
}
|
|
4919
|
+
try {
|
|
4920
|
+
return c.json(ok(await this.host.pollBrowserAuth({
|
|
4921
|
+
sessionId,
|
|
4922
|
+
apiBase: readTrimmedString(body.data.apiBase)
|
|
4923
|
+
})));
|
|
4924
|
+
} catch (error) {
|
|
4925
|
+
return c.json(err("REMOTE_BROWSER_AUTH_POLL_FAILED", formatUserFacingError(error)), 400);
|
|
4926
|
+
}
|
|
4927
|
+
};
|
|
4928
|
+
logout = async (c) => {
|
|
4929
|
+
try {
|
|
4930
|
+
return c.json(ok(await this.host.logout()));
|
|
4931
|
+
} catch (error) {
|
|
4932
|
+
return c.json(err("REMOTE_LOGOUT_FAILED", formatUserFacingError(error)), 500);
|
|
4933
|
+
}
|
|
4934
|
+
};
|
|
4935
|
+
updateSettings = async (c) => {
|
|
4936
|
+
const body = await readJson(c.req.raw);
|
|
4937
|
+
if (!body.ok) {
|
|
4938
|
+
return c.json(err("INVALID_BODY", "invalid json body"), 400);
|
|
4939
|
+
}
|
|
4940
|
+
try {
|
|
4941
|
+
return c.json(ok(await this.host.updateSettings({
|
|
4942
|
+
enabled: readBoolean(body.data.enabled),
|
|
4943
|
+
deviceName: readTrimmedString(body.data.deviceName),
|
|
4944
|
+
platformApiBase: readTrimmedString(body.data.platformApiBase)
|
|
4945
|
+
})));
|
|
4946
|
+
} catch (error) {
|
|
4947
|
+
return c.json(err("REMOTE_SETTINGS_FAILED", formatUserFacingError(error)), 400);
|
|
4948
|
+
}
|
|
4949
|
+
};
|
|
4950
|
+
controlService = async (c) => {
|
|
4951
|
+
const action = c.req.param("action");
|
|
4952
|
+
if (!REMOTE_SERVICE_ACTIONS.has(action)) {
|
|
4953
|
+
return c.json(err("INVALID_ACTION", "unsupported remote service action"), 400);
|
|
4954
|
+
}
|
|
4955
|
+
try {
|
|
4956
|
+
return c.json(ok(await this.host.controlService(action)));
|
|
4957
|
+
} catch (error) {
|
|
4958
|
+
return c.json(err("REMOTE_SERVICE_FAILED", formatUserFacingError(error)), 400);
|
|
4959
|
+
}
|
|
4960
|
+
};
|
|
4961
|
+
};
|
|
4962
|
+
|
|
4850
4963
|
// src/ui/router/session.controller.ts
|
|
4851
4964
|
var SessionRoutesController = class {
|
|
4852
4965
|
constructor(options) {
|
|
@@ -4926,37 +5039,7 @@ function registerAuthRoutes(app, authController) {
|
|
|
4926
5039
|
app.put("/api/auth/enabled", authController.updateEnabled);
|
|
4927
5040
|
app.post("/api/auth/bridge", authController.issueBridgeSession);
|
|
4928
5041
|
}
|
|
4929
|
-
function
|
|
4930
|
-
const app = new Hono();
|
|
4931
|
-
const marketplaceBaseUrl = normalizeMarketplaceBaseUrl(options);
|
|
4932
|
-
const authService = options.authService ?? new UiAuthService(options.configPath);
|
|
4933
|
-
const appController = new AppRoutesController(options);
|
|
4934
|
-
const authController = new AuthRoutesController(authService);
|
|
4935
|
-
const configController = new ConfigRoutesController(options);
|
|
4936
|
-
const chatController = new ChatRoutesController(options);
|
|
4937
|
-
const sessionController = new SessionRoutesController(options);
|
|
4938
|
-
const cronController = new CronRoutesController(options);
|
|
4939
|
-
const ncpSessionController = new NcpSessionRoutesController(options);
|
|
4940
|
-
const pluginMarketplaceController = new PluginMarketplaceController(options, marketplaceBaseUrl);
|
|
4941
|
-
const skillMarketplaceController = new SkillMarketplaceController(options, marketplaceBaseUrl);
|
|
4942
|
-
const mcpMarketplaceController = new McpMarketplaceController(options, marketplaceBaseUrl);
|
|
4943
|
-
app.notFound((c) => c.json(err("NOT_FOUND", "endpoint not found"), 404));
|
|
4944
|
-
app.use("/api/*", async (c, next) => {
|
|
4945
|
-
const path = c.req.path;
|
|
4946
|
-
if (path === "/api/health" || path.startsWith("/api/auth/")) {
|
|
4947
|
-
await next();
|
|
4948
|
-
return;
|
|
4949
|
-
}
|
|
4950
|
-
if (!authService.isProtectionEnabled() || authService.isRequestAuthenticated(c.req.raw)) {
|
|
4951
|
-
await next();
|
|
4952
|
-
return;
|
|
4953
|
-
}
|
|
4954
|
-
c.status(401);
|
|
4955
|
-
return c.json(err("UNAUTHORIZED", "Authentication required."), 401);
|
|
4956
|
-
});
|
|
4957
|
-
app.get("/api/health", appController.health);
|
|
4958
|
-
app.get("/api/app/meta", appController.appMeta);
|
|
4959
|
-
registerAuthRoutes(app, authController);
|
|
5042
|
+
function registerConfigRoutes(app, configController) {
|
|
4960
5043
|
app.get("/api/config", configController.getConfig);
|
|
4961
5044
|
app.get("/api/config/meta", configController.getConfigMeta);
|
|
4962
5045
|
app.get("/api/config/schema", configController.getConfigSchema);
|
|
@@ -4973,6 +5056,8 @@ function createUiRouter(options) {
|
|
|
4973
5056
|
app.put("/api/config/secrets", configController.updateSecrets);
|
|
4974
5057
|
app.put("/api/config/runtime", configController.updateRuntime);
|
|
4975
5058
|
app.post("/api/config/actions/:actionId/execute", configController.executeAction);
|
|
5059
|
+
}
|
|
5060
|
+
function registerChatRoutes(app, chatController) {
|
|
4976
5061
|
app.get("/api/chat/capabilities", chatController.getCapabilities);
|
|
4977
5062
|
app.get("/api/chat/session-types", chatController.getSessionTypes);
|
|
4978
5063
|
app.get("/api/chat/commands", chatController.getCommands);
|
|
@@ -4982,27 +5067,86 @@ function createUiRouter(options) {
|
|
|
4982
5067
|
app.get("/api/chat/runs", chatController.listRuns);
|
|
4983
5068
|
app.get("/api/chat/runs/:runId", chatController.getRun);
|
|
4984
5069
|
app.get("/api/chat/runs/:runId/stream", chatController.streamRun);
|
|
5070
|
+
}
|
|
5071
|
+
function registerSessionRoutes(app, sessionController) {
|
|
4985
5072
|
app.get("/api/sessions", sessionController.listSessions);
|
|
4986
5073
|
app.get("/api/sessions/:key/history", sessionController.getSessionHistory);
|
|
4987
5074
|
app.put("/api/sessions/:key", sessionController.patchSession);
|
|
4988
5075
|
app.delete("/api/sessions/:key", sessionController.deleteSession);
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
streamProvider: options.ncpAgent.streamProvider
|
|
4994
|
-
});
|
|
4995
|
-
app.get("/api/ncp/session-types", ncpSessionController.getSessionTypes);
|
|
4996
|
-
app.get("/api/ncp/sessions", ncpSessionController.listSessions);
|
|
4997
|
-
app.get("/api/ncp/sessions/:sessionId", ncpSessionController.getSession);
|
|
4998
|
-
app.put("/api/ncp/sessions/:sessionId", ncpSessionController.patchSession);
|
|
4999
|
-
app.get("/api/ncp/sessions/:sessionId/messages", ncpSessionController.listSessionMessages);
|
|
5000
|
-
app.delete("/api/ncp/sessions/:sessionId", ncpSessionController.deleteSession);
|
|
5076
|
+
}
|
|
5077
|
+
function registerNcpRoutes(app, options, ncpSessionController) {
|
|
5078
|
+
if (!options.ncpAgent) {
|
|
5079
|
+
return;
|
|
5001
5080
|
}
|
|
5081
|
+
mountNcpHttpAgentRoutes(app, {
|
|
5082
|
+
basePath: options.ncpAgent.basePath ?? "/api/ncp/agent",
|
|
5083
|
+
agentClientEndpoint: options.ncpAgent.agentClientEndpoint,
|
|
5084
|
+
streamProvider: options.ncpAgent.streamProvider
|
|
5085
|
+
});
|
|
5086
|
+
app.get("/api/ncp/session-types", ncpSessionController.getSessionTypes);
|
|
5087
|
+
app.get("/api/ncp/sessions", ncpSessionController.listSessions);
|
|
5088
|
+
app.get("/api/ncp/sessions/:sessionId", ncpSessionController.getSession);
|
|
5089
|
+
app.put("/api/ncp/sessions/:sessionId", ncpSessionController.patchSession);
|
|
5090
|
+
app.get("/api/ncp/sessions/:sessionId/messages", ncpSessionController.listSessionMessages);
|
|
5091
|
+
app.delete("/api/ncp/sessions/:sessionId", ncpSessionController.deleteSession);
|
|
5092
|
+
}
|
|
5093
|
+
function registerCronRoutes(app, cronController) {
|
|
5002
5094
|
app.get("/api/cron", cronController.listJobs);
|
|
5003
5095
|
app.delete("/api/cron/:id", cronController.deleteJob);
|
|
5004
5096
|
app.put("/api/cron/:id/enable", cronController.enableJob);
|
|
5005
5097
|
app.post("/api/cron/:id/run", cronController.runJob);
|
|
5098
|
+
}
|
|
5099
|
+
function registerRemoteRoutes(app, remoteController) {
|
|
5100
|
+
if (!remoteController) {
|
|
5101
|
+
return;
|
|
5102
|
+
}
|
|
5103
|
+
app.get("/api/remote/status", remoteController.getStatus);
|
|
5104
|
+
app.get("/api/remote/doctor", remoteController.getDoctor);
|
|
5105
|
+
app.post("/api/remote/login", remoteController.login);
|
|
5106
|
+
app.post("/api/remote/auth/start", remoteController.startBrowserAuth);
|
|
5107
|
+
app.post("/api/remote/auth/poll", remoteController.pollBrowserAuth);
|
|
5108
|
+
app.post("/api/remote/logout", remoteController.logout);
|
|
5109
|
+
app.put("/api/remote/settings", remoteController.updateSettings);
|
|
5110
|
+
app.post("/api/remote/service/:action", remoteController.controlService);
|
|
5111
|
+
}
|
|
5112
|
+
function createUiRouter(options) {
|
|
5113
|
+
const app = new Hono();
|
|
5114
|
+
const marketplaceBaseUrl = normalizeMarketplaceBaseUrl(options);
|
|
5115
|
+
const authService = options.authService ?? new UiAuthService(options.configPath);
|
|
5116
|
+
const appController = new AppRoutesController(options);
|
|
5117
|
+
const authController = new AuthRoutesController(authService);
|
|
5118
|
+
const configController = new ConfigRoutesController(options);
|
|
5119
|
+
const chatController = new ChatRoutesController(options);
|
|
5120
|
+
const sessionController = new SessionRoutesController(options);
|
|
5121
|
+
const cronController = new CronRoutesController(options);
|
|
5122
|
+
const ncpSessionController = new NcpSessionRoutesController(options);
|
|
5123
|
+
const remoteController = options.remoteAccess ? new RemoteRoutesController(options.remoteAccess) : null;
|
|
5124
|
+
const pluginMarketplaceController = new PluginMarketplaceController(options, marketplaceBaseUrl);
|
|
5125
|
+
const skillMarketplaceController = new SkillMarketplaceController(options, marketplaceBaseUrl);
|
|
5126
|
+
const mcpMarketplaceController = new McpMarketplaceController(options, marketplaceBaseUrl);
|
|
5127
|
+
app.notFound((c) => c.json(err("NOT_FOUND", "endpoint not found"), 404));
|
|
5128
|
+
app.use("/api/*", async (c, next) => {
|
|
5129
|
+
const path = c.req.path;
|
|
5130
|
+
if (path === "/api/health" || path.startsWith("/api/auth/")) {
|
|
5131
|
+
await next();
|
|
5132
|
+
return;
|
|
5133
|
+
}
|
|
5134
|
+
if (!authService.isProtectionEnabled() || authService.isRequestAuthenticated(c.req.raw)) {
|
|
5135
|
+
await next();
|
|
5136
|
+
return;
|
|
5137
|
+
}
|
|
5138
|
+
c.status(401);
|
|
5139
|
+
return c.json(err("UNAUTHORIZED", "Authentication required."), 401);
|
|
5140
|
+
});
|
|
5141
|
+
app.get("/api/health", appController.health);
|
|
5142
|
+
app.get("/api/app/meta", appController.appMeta);
|
|
5143
|
+
registerAuthRoutes(app, authController);
|
|
5144
|
+
registerConfigRoutes(app, configController);
|
|
5145
|
+
registerChatRoutes(app, chatController);
|
|
5146
|
+
registerSessionRoutes(app, sessionController);
|
|
5147
|
+
registerNcpRoutes(app, options, ncpSessionController);
|
|
5148
|
+
registerCronRoutes(app, cronController);
|
|
5149
|
+
registerRemoteRoutes(app, remoteController);
|
|
5006
5150
|
mountMarketplaceRoutes(app, {
|
|
5007
5151
|
plugin: pluginMarketplaceController,
|
|
5008
5152
|
skill: skillMarketplaceController,
|
|
@@ -5047,7 +5191,8 @@ function startUiServer(options) {
|
|
|
5047
5191
|
cronService: options.cronService,
|
|
5048
5192
|
chatRuntime: options.chatRuntime,
|
|
5049
5193
|
ncpAgent: options.ncpAgent,
|
|
5050
|
-
authService
|
|
5194
|
+
authService,
|
|
5195
|
+
remoteAccess: options.remoteAccess
|
|
5051
5196
|
})
|
|
5052
5197
|
);
|
|
5053
5198
|
const staticDir = options.staticDir;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/server",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.10",
|
|
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/mcp": "0.1.10",
|
|
21
22
|
"@nextclaw/ncp": "0.3.1",
|
|
22
23
|
"@nextclaw/openclaw-compat": "0.3.8",
|
|
23
|
-
"@nextclaw/ncp-http-agent-server": "0.3.1",
|
|
24
|
-
"@nextclaw/runtime": "0.2.5",
|
|
25
24
|
"@nextclaw/core": "0.9.5",
|
|
26
|
-
"@nextclaw/
|
|
25
|
+
"@nextclaw/ncp-http-agent-server": "0.3.1",
|
|
26
|
+
"@nextclaw/runtime": "0.2.5"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^20.17.6",
|