@nextclaw/server 0.9.4 → 0.10.0

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +296 -179
  2. package/dist/index.js +334 -28
  3. package/package.json +5 -4
package/dist/index.d.ts CHANGED
@@ -5,6 +5,284 @@ import { NcpHttpAgentStreamProvider } from '@nextclaw/ncp-http-agent-server';
5
5
  import { Hono } from 'hono';
6
6
  import { IncomingMessage } from 'node:http';
7
7
 
8
+ type MarketplaceItemType = "plugin" | "skill" | "mcp";
9
+ type MarketplaceSort = "relevance" | "updated";
10
+ type MarketplacePluginInstallKind = "npm";
11
+ type MarketplaceSkillInstallKind = "builtin" | "marketplace";
12
+ type MarketplaceMcpInstallKind = "template";
13
+ type MarketplaceInstallKind = MarketplacePluginInstallKind | MarketplaceSkillInstallKind | MarketplaceMcpInstallKind;
14
+ type MarketplaceInstallSpec = {
15
+ kind: MarketplaceInstallKind;
16
+ spec: string;
17
+ command: string;
18
+ };
19
+ type MarketplaceMcpTemplateInput = {
20
+ id: string;
21
+ label: string;
22
+ description?: string;
23
+ required?: boolean;
24
+ secret?: boolean;
25
+ defaultValue?: string;
26
+ };
27
+ type MarketplaceMcpInstallSpec = MarketplaceInstallSpec & {
28
+ kind: "template";
29
+ defaultName: string;
30
+ transportTypes: Array<"stdio" | "http" | "sse">;
31
+ template: Record<string, unknown>;
32
+ inputs: MarketplaceMcpTemplateInput[];
33
+ };
34
+ type MarketplaceLocalizedTextMap = Record<string, string>;
35
+ type MarketplaceItemSummary = {
36
+ id: string;
37
+ slug: string;
38
+ type: MarketplaceItemType;
39
+ name: string;
40
+ summary: string;
41
+ summaryI18n: MarketplaceLocalizedTextMap;
42
+ tags: string[];
43
+ author: string;
44
+ install: MarketplaceInstallSpec;
45
+ updatedAt: string;
46
+ };
47
+ type MarketplaceItemView = MarketplaceItemSummary & {
48
+ description?: string;
49
+ descriptionI18n?: MarketplaceLocalizedTextMap;
50
+ sourceRepo?: string;
51
+ homepage?: string;
52
+ publishedAt: string;
53
+ };
54
+ type MarketplaceSkillContentView = {
55
+ type: "skill";
56
+ slug: string;
57
+ name: string;
58
+ install: MarketplaceInstallSpec;
59
+ source: "builtin" | "marketplace" | "remote";
60
+ raw: string;
61
+ metadataRaw?: string;
62
+ bodyRaw: string;
63
+ sourceUrl?: string;
64
+ };
65
+ type MarketplacePluginContentView = {
66
+ type: "plugin";
67
+ slug: string;
68
+ name: string;
69
+ install: MarketplaceInstallSpec;
70
+ source: "npm" | "repo" | "remote";
71
+ raw?: string;
72
+ bodyRaw?: string;
73
+ metadataRaw?: string;
74
+ sourceUrl?: string;
75
+ };
76
+ type MarketplaceMcpContentView = {
77
+ type: "mcp";
78
+ slug: string;
79
+ name: string;
80
+ install: MarketplaceMcpInstallSpec;
81
+ source: "marketplace" | "remote";
82
+ raw: string;
83
+ metadataRaw?: string;
84
+ bodyRaw: string;
85
+ sourceUrl?: string;
86
+ };
87
+ type MarketplaceListView = {
88
+ total: number;
89
+ page: number;
90
+ pageSize: number;
91
+ totalPages: number;
92
+ sort: MarketplaceSort;
93
+ query?: string;
94
+ items: MarketplaceItemSummary[];
95
+ };
96
+ type MarketplaceRecommendationView = {
97
+ type: MarketplaceItemType;
98
+ sceneId: string;
99
+ title: string;
100
+ description?: string;
101
+ total: number;
102
+ items: MarketplaceItemSummary[];
103
+ };
104
+ type MarketplaceInstalledRecord = {
105
+ type: MarketplaceItemType;
106
+ id?: string;
107
+ spec: string;
108
+ label?: string;
109
+ description?: string;
110
+ descriptionZh?: string;
111
+ source?: string;
112
+ installedAt?: string;
113
+ enabled?: boolean;
114
+ runtimeStatus?: string;
115
+ origin?: string;
116
+ installPath?: string;
117
+ transport?: "stdio" | "http" | "sse";
118
+ scope?: {
119
+ allAgents: boolean;
120
+ agents: string[];
121
+ };
122
+ catalogSlug?: string;
123
+ vendor?: string;
124
+ docsUrl?: string;
125
+ homepage?: string;
126
+ trustLevel?: "official" | "verified" | "community";
127
+ toolCount?: number;
128
+ accessible?: boolean;
129
+ lastReadyAt?: string;
130
+ lastDoctorAt?: string;
131
+ lastError?: string;
132
+ };
133
+ type MarketplaceInstalledView = {
134
+ type: MarketplaceItemType;
135
+ total: number;
136
+ specs: string[];
137
+ records: MarketplaceInstalledRecord[];
138
+ };
139
+ type MarketplaceInstallSkillParams = {
140
+ slug: string;
141
+ kind?: MarketplaceSkillInstallKind;
142
+ skill?: string;
143
+ installPath?: string;
144
+ force?: boolean;
145
+ };
146
+ type MarketplacePluginInstallRequest = {
147
+ type?: "plugin";
148
+ spec: string;
149
+ };
150
+ type MarketplaceSkillInstallRequest = {
151
+ type?: "skill";
152
+ spec: string;
153
+ kind?: MarketplaceSkillInstallKind;
154
+ skill?: string;
155
+ installPath?: string;
156
+ force?: boolean;
157
+ };
158
+ type MarketplaceMcpInstallRequest = {
159
+ type?: "mcp";
160
+ spec: string;
161
+ name?: string;
162
+ enabled?: boolean;
163
+ allAgents?: boolean;
164
+ agents?: string[];
165
+ inputs?: Record<string, string>;
166
+ template?: MarketplaceMcpInstallSpec;
167
+ };
168
+ type MarketplacePluginInstallResult = {
169
+ type: "plugin";
170
+ spec: string;
171
+ message: string;
172
+ output?: string;
173
+ };
174
+ type MarketplaceSkillInstallResult = {
175
+ type: "skill";
176
+ spec: string;
177
+ message: string;
178
+ output?: string;
179
+ };
180
+ type MarketplaceMcpInstallResult = {
181
+ type: "mcp";
182
+ spec: string;
183
+ name: string;
184
+ message: string;
185
+ output?: string;
186
+ };
187
+ type MarketplacePluginManageAction = "enable" | "disable" | "uninstall";
188
+ type MarketplaceSkillManageAction = "uninstall";
189
+ type MarketplaceMcpManageAction = "enable" | "disable" | "remove";
190
+ type MarketplacePluginManageRequest = {
191
+ type?: "plugin";
192
+ action: MarketplacePluginManageAction;
193
+ id?: string;
194
+ spec?: string;
195
+ };
196
+ type MarketplaceSkillManageRequest = {
197
+ type?: "skill";
198
+ action: MarketplaceSkillManageAction;
199
+ id?: string;
200
+ spec?: string;
201
+ };
202
+ type MarketplaceMcpManageRequest = {
203
+ type?: "mcp";
204
+ action: MarketplaceMcpManageAction;
205
+ id?: string;
206
+ spec?: string;
207
+ };
208
+ type MarketplacePluginManageResult = {
209
+ type: "plugin";
210
+ action: MarketplacePluginManageAction;
211
+ id: string;
212
+ message: string;
213
+ output?: string;
214
+ };
215
+ type MarketplaceSkillManageResult = {
216
+ type: "skill";
217
+ action: MarketplaceSkillManageAction;
218
+ id: string;
219
+ message: string;
220
+ output?: string;
221
+ };
222
+ type MarketplaceMcpManageResult = {
223
+ type: "mcp";
224
+ action: MarketplaceMcpManageAction;
225
+ id: string;
226
+ message: string;
227
+ output?: string;
228
+ };
229
+ type MarketplaceMcpDoctorResult = {
230
+ name: string;
231
+ enabled: boolean;
232
+ transport: "stdio" | "http" | "sse";
233
+ accessible: boolean;
234
+ toolCount: number;
235
+ error?: string;
236
+ };
237
+ type MarketplaceInstaller = {
238
+ installPlugin?: (spec: string) => Promise<{
239
+ message: string;
240
+ output?: string;
241
+ }>;
242
+ installSkill?: (params: MarketplaceInstallSkillParams) => Promise<{
243
+ message: string;
244
+ output?: string;
245
+ }>;
246
+ enablePlugin?: (id: string) => Promise<{
247
+ message: string;
248
+ output?: string;
249
+ }>;
250
+ disablePlugin?: (id: string) => Promise<{
251
+ message: string;
252
+ output?: string;
253
+ }>;
254
+ uninstallPlugin?: (id: string) => Promise<{
255
+ message: string;
256
+ output?: string;
257
+ }>;
258
+ uninstallSkill?: (slug: string) => Promise<{
259
+ message: string;
260
+ output?: string;
261
+ }>;
262
+ installMcp?: (params: MarketplaceMcpInstallRequest) => Promise<{
263
+ name: string;
264
+ message: string;
265
+ output?: string;
266
+ }>;
267
+ enableMcp?: (name: string) => Promise<{
268
+ message: string;
269
+ output?: string;
270
+ }>;
271
+ disableMcp?: (name: string) => Promise<{
272
+ message: string;
273
+ output?: string;
274
+ }>;
275
+ removeMcp?: (name: string) => Promise<{
276
+ message: string;
277
+ output?: string;
278
+ }>;
279
+ doctorMcp?: (name: string) => Promise<MarketplaceMcpDoctorResult>;
280
+ };
281
+ type MarketplaceApiConfig = {
282
+ apiBaseUrl?: string;
283
+ installer?: MarketplaceInstaller;
284
+ };
285
+
8
286
  type ApiError = {
9
287
  code: string;
10
288
  message: string;
@@ -190,6 +468,7 @@ type SessionEntryView = {
190
468
  updatedAt: string;
191
469
  label?: string;
192
470
  preferredModel?: string;
471
+ preferredThinking?: ThinkingLevel | null;
193
472
  sessionType: string;
194
473
  sessionTypeMutable: boolean;
195
474
  messageCount: number;
@@ -379,9 +658,20 @@ type ChatCapabilitiesView = {
379
658
  stopSupported: boolean;
380
659
  stopReason?: string;
381
660
  };
661
+ type ChatSessionTypeCtaView = {
662
+ kind: string;
663
+ label?: string;
664
+ href?: string;
665
+ };
382
666
  type ChatSessionTypeOptionView = {
383
667
  value: string;
384
668
  label: string;
669
+ ready?: boolean;
670
+ reason?: string | null;
671
+ reasonMessage?: string | null;
672
+ supportedModels?: string[];
673
+ recommendedModel?: string | null;
674
+ cta?: ChatSessionTypeCtaView | null;
385
675
  };
386
676
  type ChatSessionTypesView = {
387
677
  defaultType: string;
@@ -634,184 +924,6 @@ type ConfigActionExecuteResult = {
634
924
  patch?: Record<string, unknown>;
635
925
  nextActions?: string[];
636
926
  };
637
- type MarketplaceItemType = "plugin" | "skill";
638
- type MarketplaceSort = "relevance" | "updated";
639
- type MarketplacePluginInstallKind = "npm";
640
- type MarketplaceSkillInstallKind = "builtin" | "marketplace";
641
- type MarketplaceInstallKind = MarketplacePluginInstallKind | MarketplaceSkillInstallKind;
642
- type MarketplaceInstallSpec = {
643
- kind: MarketplaceInstallKind;
644
- spec: string;
645
- command: string;
646
- };
647
- type MarketplaceLocalizedTextMap = Record<string, string>;
648
- type MarketplaceItemSummary = {
649
- id: string;
650
- slug: string;
651
- type: MarketplaceItemType;
652
- name: string;
653
- summary: string;
654
- summaryI18n: MarketplaceLocalizedTextMap;
655
- tags: string[];
656
- author: string;
657
- install: MarketplaceInstallSpec;
658
- updatedAt: string;
659
- };
660
- type MarketplaceItemView = MarketplaceItemSummary & {
661
- description?: string;
662
- descriptionI18n?: MarketplaceLocalizedTextMap;
663
- sourceRepo?: string;
664
- homepage?: string;
665
- publishedAt: string;
666
- };
667
- type MarketplaceSkillContentView = {
668
- type: "skill";
669
- slug: string;
670
- name: string;
671
- install: MarketplaceInstallSpec;
672
- source: "builtin" | "marketplace" | "remote";
673
- raw: string;
674
- metadataRaw?: string;
675
- bodyRaw: string;
676
- sourceUrl?: string;
677
- };
678
- type MarketplacePluginContentView = {
679
- type: "plugin";
680
- slug: string;
681
- name: string;
682
- install: MarketplaceInstallSpec;
683
- source: "npm" | "repo" | "remote";
684
- raw?: string;
685
- bodyRaw?: string;
686
- metadataRaw?: string;
687
- sourceUrl?: string;
688
- };
689
- type MarketplaceListView = {
690
- total: number;
691
- page: number;
692
- pageSize: number;
693
- totalPages: number;
694
- sort: MarketplaceSort;
695
- query?: string;
696
- items: MarketplaceItemSummary[];
697
- };
698
- type MarketplaceRecommendationView = {
699
- type: MarketplaceItemType;
700
- sceneId: string;
701
- title: string;
702
- description?: string;
703
- total: number;
704
- items: MarketplaceItemSummary[];
705
- };
706
- type MarketplaceInstalledRecord = {
707
- type: MarketplaceItemType;
708
- id?: string;
709
- spec: string;
710
- label?: string;
711
- description?: string;
712
- descriptionZh?: string;
713
- source?: string;
714
- installedAt?: string;
715
- enabled?: boolean;
716
- runtimeStatus?: string;
717
- origin?: string;
718
- installPath?: string;
719
- };
720
- type MarketplaceInstalledView = {
721
- type: MarketplaceItemType;
722
- total: number;
723
- specs: string[];
724
- records: MarketplaceInstalledRecord[];
725
- };
726
- type MarketplaceInstallSkillParams = {
727
- slug: string;
728
- kind?: MarketplaceSkillInstallKind;
729
- skill?: string;
730
- installPath?: string;
731
- force?: boolean;
732
- };
733
- type MarketplacePluginInstallRequest = {
734
- type?: "plugin";
735
- spec: string;
736
- };
737
- type MarketplaceSkillInstallRequest = {
738
- type?: "skill";
739
- spec: string;
740
- kind?: MarketplaceSkillInstallKind;
741
- skill?: string;
742
- installPath?: string;
743
- force?: boolean;
744
- };
745
- type MarketplacePluginInstallResult = {
746
- type: "plugin";
747
- spec: string;
748
- message: string;
749
- output?: string;
750
- };
751
- type MarketplaceSkillInstallResult = {
752
- type: "skill";
753
- spec: string;
754
- message: string;
755
- output?: string;
756
- };
757
- type MarketplacePluginManageAction = "enable" | "disable" | "uninstall";
758
- type MarketplaceSkillManageAction = "uninstall";
759
- type MarketplacePluginManageRequest = {
760
- type?: "plugin";
761
- action: MarketplacePluginManageAction;
762
- id?: string;
763
- spec?: string;
764
- };
765
- type MarketplaceSkillManageRequest = {
766
- type?: "skill";
767
- action: MarketplaceSkillManageAction;
768
- id?: string;
769
- spec?: string;
770
- };
771
- type MarketplacePluginManageResult = {
772
- type: "plugin";
773
- action: MarketplacePluginManageAction;
774
- id: string;
775
- message: string;
776
- output?: string;
777
- };
778
- type MarketplaceSkillManageResult = {
779
- type: "skill";
780
- action: MarketplaceSkillManageAction;
781
- id: string;
782
- message: string;
783
- output?: string;
784
- };
785
- type MarketplaceInstaller = {
786
- installPlugin?: (spec: string) => Promise<{
787
- message: string;
788
- output?: string;
789
- }>;
790
- installSkill?: (params: MarketplaceInstallSkillParams) => Promise<{
791
- message: string;
792
- output?: string;
793
- }>;
794
- enablePlugin?: (id: string) => Promise<{
795
- message: string;
796
- output?: string;
797
- }>;
798
- disablePlugin?: (id: string) => Promise<{
799
- message: string;
800
- output?: string;
801
- }>;
802
- uninstallPlugin?: (id: string) => Promise<{
803
- message: string;
804
- output?: string;
805
- }>;
806
- uninstallSkill?: (slug: string) => Promise<{
807
- message: string;
808
- output?: string;
809
- }>;
810
- };
811
- type MarketplaceApiConfig = {
812
- apiBaseUrl?: string;
813
- installer?: MarketplaceInstaller;
814
- };
815
927
  type UiServerEvent = {
816
928
  type: "config.updated";
817
929
  payload: {
@@ -879,6 +991,7 @@ declare class UiAuthService {
879
991
  private clearAllSessions;
880
992
  private deleteRequestSession;
881
993
  private buildLoginCookie;
994
+ buildTrustedRequestCookieHeader(): string | null;
882
995
  buildLogoutCookie(request: Request): string;
883
996
  setup(request: Request, payload: AuthSetupRequest): {
884
997
  status: AuthStatusView;
@@ -956,4 +1069,8 @@ declare function deleteSession(configPath: string, key: string): boolean;
956
1069
  declare function updateRuntime(configPath: string, patch: RuntimeConfigUpdate): Pick<ConfigView, "agents" | "bindings" | "session">;
957
1070
  declare function updateSecrets(configPath: string, patch: SecretsConfigUpdate): SecretsView;
958
1071
 
959
- 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 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 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, executeConfigAction, getSessionHistory, listSessions, loadConfigOrDefault, patchSession, startUiServer, testProviderConnection, updateChannel, updateModel, updateProvider, updateRuntime, updateSearch, updateSecrets };
1072
+ declare function getUiBridgeSecretPath(): string;
1073
+ declare function readUiBridgeSecret(): string | null;
1074
+ declare function ensureUiBridgeSecret(): string;
1075
+
1076
+ 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 };
package/dist/index.js CHANGED
@@ -4,9 +4,9 @@ import { compress } from "hono/compress";
4
4
  import { cors } from "hono/cors";
5
5
  import { serve } from "@hono/node-server";
6
6
  import { WebSocketServer, WebSocket } from "ws";
7
- import { existsSync, readFileSync } from "fs";
7
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
8
8
  import { readFile as readFile2, stat } from "fs/promises";
9
- import { join } from "path";
9
+ import { join as join2 } from "path";
10
10
 
11
11
  // src/ui/auth.service.ts
12
12
  import { ConfigSchema, loadConfig, saveConfig } from "@nextclaw/core";
@@ -179,6 +179,18 @@ var UiAuthService = class {
179
179
  secure: resolveSecureRequest(request.url, request.headers.get("x-forwarded-proto"))
180
180
  });
181
181
  }
182
+ buildTrustedRequestCookieHeader() {
183
+ const auth = this.readAuthConfig();
184
+ if (!auth.enabled || !this.isConfigured(auth)) {
185
+ return null;
186
+ }
187
+ const username = normalizeUsername(auth.username);
188
+ if (!username) {
189
+ return null;
190
+ }
191
+ const sessionId = this.createSession(username);
192
+ return `${SESSION_COOKIE_NAME}=${encodeURIComponent(sessionId)}`;
193
+ }
182
194
  buildLogoutCookie(request) {
183
195
  return buildSetCookie({
184
196
  value: "",
@@ -393,6 +405,39 @@ var AppRoutesController = class {
393
405
  appMeta = (c) => c.json(ok(buildAppMetaView(this.options)));
394
406
  };
395
407
 
408
+ // src/ui/auth-bridge.ts
409
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
410
+ import { join } from "path";
411
+ import { randomBytes as randomBytes2 } from "crypto";
412
+ import { getDataDir } from "@nextclaw/core";
413
+ var REMOTE_BRIDGE_DIR = join(getDataDir(), "remote");
414
+ var REMOTE_BRIDGE_SECRET_PATH = join(REMOTE_BRIDGE_DIR, "ui-bridge-secret");
415
+ function getUiBridgeSecretPath() {
416
+ return REMOTE_BRIDGE_SECRET_PATH;
417
+ }
418
+ function readUiBridgeSecret() {
419
+ if (!existsSync(REMOTE_BRIDGE_SECRET_PATH)) {
420
+ return null;
421
+ }
422
+ try {
423
+ const raw = readFileSync(REMOTE_BRIDGE_SECRET_PATH, "utf-8").trim();
424
+ return raw.length > 0 ? raw : null;
425
+ } catch {
426
+ return null;
427
+ }
428
+ }
429
+ function ensureUiBridgeSecret() {
430
+ const existing = readUiBridgeSecret();
431
+ if (existing) {
432
+ return existing;
433
+ }
434
+ mkdirSync(REMOTE_BRIDGE_DIR, { recursive: true });
435
+ const secret = randomBytes2(24).toString("hex");
436
+ writeFileSync(REMOTE_BRIDGE_SECRET_PATH, `${secret}
437
+ `, "utf-8");
438
+ return secret;
439
+ }
440
+
396
441
  // src/ui/router/auth.controller.ts
397
442
  function isAuthenticationRequiredError(message) {
398
443
  return message === "Authentication required.";
@@ -492,6 +537,16 @@ var AuthRoutesController = class {
492
537
  return c.json(err(code, message), status);
493
538
  }
494
539
  };
540
+ issueBridgeSession = (c) => {
541
+ const providedSecret = c.req.header("x-nextclaw-ui-bridge-secret")?.trim();
542
+ const expectedSecret = ensureUiBridgeSecret();
543
+ if (!providedSecret || providedSecret !== expectedSecret) {
544
+ return c.json(err("FORBIDDEN", "Invalid bridge secret."), 403);
545
+ }
546
+ return c.json(ok({
547
+ cookie: this.authService.buildTrustedRequestCookieHeader()
548
+ }));
549
+ };
495
550
  };
496
551
 
497
552
  // src/ui/router/chat.controller.ts
@@ -512,7 +567,7 @@ import {
512
567
  SessionManager,
513
568
  getWorkspacePathFromConfig,
514
569
  normalizeThinkingLevels,
515
- parseThinkingLevel as parseThinkingLevel2
570
+ parseThinkingLevel as parseThinkingLevel3
516
571
  } from "@nextclaw/core";
517
572
 
518
573
  // src/ui/provider-overrides.ts
@@ -639,6 +694,18 @@ function applySessionPreferencePatch(params) {
639
694
  return nextMetadata;
640
695
  }
641
696
 
697
+ // src/ui/session-list-metadata.ts
698
+ import { parseThinkingLevel as parseThinkingLevel2 } from "@nextclaw/core";
699
+ function readSessionListMetadata(metadata) {
700
+ const rawLabel = typeof metadata.label === "string" ? metadata.label.trim() : "";
701
+ const rawPreferredModel = typeof metadata.preferred_model === "string" ? metadata.preferred_model.trim() : "";
702
+ return {
703
+ label: rawLabel || void 0,
704
+ preferredModel: rawPreferredModel || void 0,
705
+ preferredThinking: parseThinkingLevel2(metadata.preferred_thinking) ?? null
706
+ };
707
+ }
708
+
642
709
  // src/ui/config.ts
643
710
  var MASK_MIN_LENGTH = 8;
644
711
  var EXTRA_SENSITIVE_PATH_PATTERNS = [/authorization/i, /cookie/i, /session/i, /bearer/i];
@@ -991,7 +1058,7 @@ function normalizeModelThinkingConfig(input) {
991
1058
  if (supported.length === 0) {
992
1059
  continue;
993
1060
  }
994
- const defaultLevel = parseThinkingLevel2(rawValue.default);
1061
+ const defaultLevel = parseThinkingLevel3(rawValue.default);
995
1062
  if (defaultLevel && supported.includes(defaultLevel)) {
996
1063
  normalized[model] = { supported, default: defaultLevel };
997
1064
  } else {
@@ -1578,8 +1645,7 @@ function listSessions(configPath, query) {
1578
1645
  const messages = session?.messages ?? [];
1579
1646
  const lastMessage = messages.length > 0 ? messages[messages.length - 1] : null;
1580
1647
  const metadata = item.metadata && typeof item.metadata === "object" ? item.metadata : {};
1581
- const label = typeof metadata.label === "string" ? metadata.label.trim() : "";
1582
- const preferredModel = typeof metadata.preferred_model === "string" ? metadata.preferred_model.trim() : "";
1648
+ const { label, preferredModel, preferredThinking } = readSessionListMetadata(metadata);
1583
1649
  const createdAt = typeof item.created_at === "string" ? item.created_at : (/* @__PURE__ */ new Date(0)).toISOString();
1584
1650
  const updatedAt = typeof item.updated_at === "string" ? item.updated_at : createdAt;
1585
1651
  const sessionType = readSessionType({
@@ -1594,8 +1660,9 @@ function listSessions(configPath, query) {
1594
1660
  key,
1595
1661
  createdAt,
1596
1662
  updatedAt,
1597
- label: label || void 0,
1598
- preferredModel: preferredModel || void 0,
1663
+ label,
1664
+ preferredModel,
1665
+ preferredThinking,
1599
1666
  sessionType,
1600
1667
  sessionTypeMutable,
1601
1668
  messageCount: messages.length,
@@ -2429,7 +2496,7 @@ var ChatRoutesController = class {
2429
2496
  };
2430
2497
 
2431
2498
  // src/ui/provider-auth.ts
2432
- import { createHash, randomBytes as randomBytes2, randomUUID as randomUUID2 } from "crypto";
2499
+ import { createHash, randomBytes as randomBytes3, randomUUID as randomUUID2 } from "crypto";
2433
2500
  import { readFile } from "fs/promises";
2434
2501
  import { homedir } from "os";
2435
2502
  import { isAbsolute, resolve } from "path";
@@ -2457,7 +2524,7 @@ function toBase64Url(buffer) {
2457
2524
  return buffer.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
2458
2525
  }
2459
2526
  function buildPkce() {
2460
- const verifier = toBase64Url(randomBytes2(48));
2527
+ const verifier = toBase64Url(randomBytes3(48));
2461
2528
  const challenge = toBase64Url(createHash("sha256").update(verifier).digest());
2462
2529
  return { verifier, challenge };
2463
2530
  }
@@ -2674,7 +2741,7 @@ async function startProviderAuth(configPath, providerName, options) {
2674
2741
  if (!pkce) {
2675
2742
  throw new Error("MiniMax OAuth requires PKCE");
2676
2743
  }
2677
- const state = toBase64Url(randomBytes2(16));
2744
+ const state = toBase64Url(randomBytes3(16));
2678
2745
  const body = new URLSearchParams({
2679
2746
  response_type: "code",
2680
2747
  client_id: resolvedMethod.clientId,
@@ -3708,6 +3775,13 @@ async function fetchAllSkillMarketplaceItems(params) {
3708
3775
  query: params.query
3709
3776
  });
3710
3777
  }
3778
+ async function fetchAllMcpMarketplaceItems(params) {
3779
+ return fetchAllMarketplaceItems({
3780
+ baseUrl: params.baseUrl,
3781
+ path: "/api/v1/mcp/items",
3782
+ query: params.query
3783
+ });
3784
+ }
3711
3785
  function sanitizeMarketplaceListItems(items) {
3712
3786
  return items.map((item) => sanitizeMarketplaceItem(item));
3713
3787
  }
@@ -3715,6 +3789,216 @@ function sanitizeMarketplaceItemView(item) {
3715
3789
  return sanitizeMarketplaceItem(item);
3716
3790
  }
3717
3791
 
3792
+ // src/ui/router/marketplace/mcp.controller.ts
3793
+ import { McpInstalledViewService } from "@nextclaw/mcp";
3794
+ var McpMarketplaceController = class {
3795
+ constructor(options, marketplaceBaseUrl) {
3796
+ this.options = options;
3797
+ this.marketplaceBaseUrl = marketplaceBaseUrl;
3798
+ }
3799
+ getInstalled = (c) => {
3800
+ const service = new McpInstalledViewService({
3801
+ getConfig: () => loadConfigOrDefault(this.options.configPath)
3802
+ });
3803
+ const records = service.listInstalled().map((record) => ({
3804
+ type: "mcp",
3805
+ id: record.name,
3806
+ spec: record.catalogSlug ?? record.name,
3807
+ label: record.displayName ?? record.name,
3808
+ enabled: record.enabled,
3809
+ runtimeStatus: record.enabled ? "enabled" : "disabled",
3810
+ transport: record.transport,
3811
+ scope: record.scope,
3812
+ catalogSlug: record.catalogSlug,
3813
+ vendor: record.vendor,
3814
+ docsUrl: record.docsUrl,
3815
+ homepage: record.homepage,
3816
+ trustLevel: record.trustLevel,
3817
+ source: record.source,
3818
+ installedAt: record.installedAt,
3819
+ toolCount: record.toolCount,
3820
+ accessible: record.accessible,
3821
+ lastReadyAt: record.lastReadyAt,
3822
+ lastDoctorAt: record.lastReadyAt,
3823
+ lastError: record.lastError
3824
+ }));
3825
+ return c.json(ok({
3826
+ type: "mcp",
3827
+ total: records.length,
3828
+ specs: records.map((record) => record.spec),
3829
+ records
3830
+ }));
3831
+ };
3832
+ listItems = async (c) => {
3833
+ const query = c.req.query();
3834
+ const result = await fetchAllMcpMarketplaceItems({
3835
+ baseUrl: this.marketplaceBaseUrl,
3836
+ query: {
3837
+ q: query.q,
3838
+ tag: query.tag,
3839
+ sort: query.sort,
3840
+ page: query.page,
3841
+ pageSize: query.pageSize
3842
+ }
3843
+ });
3844
+ if (!result.ok) {
3845
+ return c.json(err("MARKETPLACE_UNAVAILABLE", result.message), result.status);
3846
+ }
3847
+ const items = sanitizeMarketplaceListItems(result.data.items).map((item) => normalizeMarketplaceItemForUi(item));
3848
+ const pageSize = Math.min(100, toPositiveInt(query.pageSize, 20));
3849
+ const requestedPage = toPositiveInt(query.page, 1);
3850
+ const totalPages = items.length === 0 ? 0 : Math.ceil(items.length / pageSize);
3851
+ const currentPage = totalPages === 0 ? 1 : Math.min(requestedPage, totalPages);
3852
+ return c.json(ok({
3853
+ total: items.length,
3854
+ page: currentPage,
3855
+ pageSize,
3856
+ totalPages,
3857
+ sort: result.data.sort,
3858
+ query: result.data.query,
3859
+ items: items.slice((currentPage - 1) * pageSize, currentPage * pageSize)
3860
+ }));
3861
+ };
3862
+ getItem = async (c) => {
3863
+ const slug = encodeURIComponent(c.req.param("slug"));
3864
+ const result = await fetchMarketplaceData({
3865
+ baseUrl: this.marketplaceBaseUrl,
3866
+ path: `/api/v1/mcp/items/${slug}`
3867
+ });
3868
+ if (!result.ok) {
3869
+ return c.json(err("MARKETPLACE_UNAVAILABLE", result.message), result.status);
3870
+ }
3871
+ return c.json(ok(normalizeMarketplaceItemForUi(sanitizeMarketplaceItemView(result.data))));
3872
+ };
3873
+ getItemContent = async (c) => {
3874
+ const slug = encodeURIComponent(c.req.param("slug"));
3875
+ const result = await fetchMarketplaceData({
3876
+ baseUrl: this.marketplaceBaseUrl,
3877
+ path: `/api/v1/mcp/items/${slug}/content`
3878
+ });
3879
+ if (!result.ok) {
3880
+ return c.json(err("MARKETPLACE_UNAVAILABLE", result.message), result.status);
3881
+ }
3882
+ return c.json(ok(result.data));
3883
+ };
3884
+ install = async (c) => {
3885
+ const body = await readJson(c.req.raw);
3886
+ if (!body.ok || !body.data || typeof body.data !== "object") {
3887
+ return c.json(err("INVALID_BODY", "invalid json body"), 400);
3888
+ }
3889
+ if (body.data.type && body.data.type !== "mcp") {
3890
+ return c.json(err("INVALID_BODY", "body.type does not match route type"), 400);
3891
+ }
3892
+ const slug = typeof body.data.spec === "string" ? body.data.spec.trim() : "";
3893
+ if (!slug) {
3894
+ return c.json(err("INVALID_BODY", "non-empty spec is required"), 400);
3895
+ }
3896
+ const installer = this.options.marketplace?.installer;
3897
+ if (!installer?.installMcp) {
3898
+ return c.json(err("NOT_AVAILABLE", "mcp installer is not configured"), 503);
3899
+ }
3900
+ const itemResult = await fetchMarketplaceData({
3901
+ baseUrl: this.marketplaceBaseUrl,
3902
+ path: `/api/v1/mcp/items/${encodeURIComponent(slug)}`
3903
+ });
3904
+ if (!itemResult.ok) {
3905
+ return c.json(err("MARKETPLACE_UNAVAILABLE", itemResult.message), itemResult.status);
3906
+ }
3907
+ const template = itemResult.data.install;
3908
+ if (template.kind !== "template") {
3909
+ return c.json(err("MARKETPLACE_CONTRACT_MISMATCH", `unsupported mcp install kind: ${template.kind}`), 502);
3910
+ }
3911
+ try {
3912
+ const result = await installer.installMcp({
3913
+ ...body.data,
3914
+ template
3915
+ });
3916
+ this.options.publish({ type: "config.updated", payload: { path: "mcp" } });
3917
+ return c.json(ok({
3918
+ type: "mcp",
3919
+ spec: slug,
3920
+ name: result.name,
3921
+ message: result.message,
3922
+ output: result.output
3923
+ }));
3924
+ } catch (error) {
3925
+ return c.json(err("INSTALL_FAILED", error instanceof Error ? error.message : String(error)), 400);
3926
+ }
3927
+ };
3928
+ manage = async (c) => {
3929
+ const body = await readJson(c.req.raw);
3930
+ if (!body.ok || !body.data || typeof body.data !== "object") {
3931
+ return c.json(err("INVALID_BODY", "invalid json body"), 400);
3932
+ }
3933
+ if (body.data.type && body.data.type !== "mcp") {
3934
+ return c.json(err("INVALID_BODY", "body.type does not match route type"), 400);
3935
+ }
3936
+ const target = typeof body.data.id === "string" && body.data.id.trim().length > 0 ? body.data.id.trim() : typeof body.data.spec === "string" && body.data.spec.trim().length > 0 ? body.data.spec.trim() : "";
3937
+ if (!target) {
3938
+ return c.json(err("INVALID_BODY", "non-empty id/spec is required"), 400);
3939
+ }
3940
+ const installer = this.options.marketplace?.installer;
3941
+ if (!installer) {
3942
+ return c.json(err("NOT_AVAILABLE", "marketplace installer is not configured"), 503);
3943
+ }
3944
+ try {
3945
+ const action = body.data.action;
3946
+ const result = action === "enable" ? await installer.enableMcp?.(target) : action === "disable" ? await installer.disableMcp?.(target) : await installer.removeMcp?.(target);
3947
+ if (!result) {
3948
+ return c.json(err("NOT_AVAILABLE", `mcp ${action} is not configured`), 503);
3949
+ }
3950
+ this.options.publish({ type: "config.updated", payload: { path: "mcp" } });
3951
+ return c.json(ok({
3952
+ type: "mcp",
3953
+ action,
3954
+ id: target,
3955
+ message: result.message,
3956
+ output: result.output
3957
+ }));
3958
+ } catch (error) {
3959
+ return c.json(err("MANAGE_FAILED", error instanceof Error ? error.message : String(error)), 400);
3960
+ }
3961
+ };
3962
+ doctor = async (c) => {
3963
+ const body = await readJson(c.req.raw);
3964
+ if (!body.ok || !body.data || typeof body.data !== "object") {
3965
+ return c.json(err("INVALID_BODY", "invalid json body"), 400);
3966
+ }
3967
+ const target = typeof body.data.name === "string" && body.data.name.trim().length > 0 ? body.data.name.trim() : typeof body.data.id === "string" && body.data.id.trim().length > 0 ? body.data.id.trim() : typeof body.data.spec === "string" && body.data.spec.trim().length > 0 ? body.data.spec.trim() : "";
3968
+ if (!target) {
3969
+ return c.json(err("INVALID_BODY", "name/id/spec is required"), 400);
3970
+ }
3971
+ const installer = this.options.marketplace?.installer;
3972
+ if (!installer?.doctorMcp) {
3973
+ return c.json(err("NOT_AVAILABLE", "mcp doctor is not configured"), 503);
3974
+ }
3975
+ try {
3976
+ const result = await installer.doctorMcp(target);
3977
+ return c.json(ok(result));
3978
+ } catch (error) {
3979
+ return c.json(err("DOCTOR_FAILED", error instanceof Error ? error.message : String(error)), 400);
3980
+ }
3981
+ };
3982
+ getRecommendations = async (c) => {
3983
+ const query = c.req.query();
3984
+ const result = await fetchMarketplaceData({
3985
+ baseUrl: this.marketplaceBaseUrl,
3986
+ path: "/api/v1/mcp/recommendations",
3987
+ query: {
3988
+ scene: query.scene,
3989
+ limit: query.limit
3990
+ }
3991
+ });
3992
+ if (!result.ok) {
3993
+ return c.json(err("MARKETPLACE_UNAVAILABLE", result.message), result.status);
3994
+ }
3995
+ return c.json(ok({
3996
+ ...result.data,
3997
+ items: sanitizeMarketplaceListItems(result.data.items).map((item) => normalizeMarketplaceItemForUi(item))
3998
+ }));
3999
+ };
4000
+ };
4001
+
3718
4002
  // src/ui/router/marketplace/installed.ts
3719
4003
  import * as NextclawCore3 from "@nextclaw/core";
3720
4004
  import { buildPluginStatusReport } from "@nextclaw/openclaw-compat";
@@ -4313,6 +4597,32 @@ var PluginMarketplaceController = class {
4313
4597
  };
4314
4598
  };
4315
4599
 
4600
+ // src/ui/router/marketplace/routes.ts
4601
+ function mountMarketplaceRoutes(app, controllers) {
4602
+ app.get("/api/marketplace/plugins/installed", controllers.plugin.getInstalled);
4603
+ app.get("/api/marketplace/plugins/items", controllers.plugin.listItems);
4604
+ app.get("/api/marketplace/plugins/items/:slug", controllers.plugin.getItem);
4605
+ app.get("/api/marketplace/plugins/items/:slug/content", controllers.plugin.getItemContent);
4606
+ app.post("/api/marketplace/plugins/install", controllers.plugin.install);
4607
+ app.post("/api/marketplace/plugins/manage", controllers.plugin.manage);
4608
+ app.get("/api/marketplace/plugins/recommendations", controllers.plugin.getRecommendations);
4609
+ app.get("/api/marketplace/skills/installed", controllers.skill.getInstalled);
4610
+ app.get("/api/marketplace/skills/items", controllers.skill.listItems);
4611
+ app.get("/api/marketplace/skills/items/:slug", controllers.skill.getItem);
4612
+ app.get("/api/marketplace/skills/items/:slug/content", controllers.skill.getItemContent);
4613
+ app.post("/api/marketplace/skills/install", controllers.skill.install);
4614
+ app.post("/api/marketplace/skills/manage", controllers.skill.manage);
4615
+ app.get("/api/marketplace/skills/recommendations", controllers.skill.getRecommendations);
4616
+ app.get("/api/marketplace/mcp/installed", controllers.mcp.getInstalled);
4617
+ app.get("/api/marketplace/mcp/items", controllers.mcp.listItems);
4618
+ app.get("/api/marketplace/mcp/items/:slug", controllers.mcp.getItem);
4619
+ app.get("/api/marketplace/mcp/items/:slug/content", controllers.mcp.getItemContent);
4620
+ app.post("/api/marketplace/mcp/install", controllers.mcp.install);
4621
+ app.post("/api/marketplace/mcp/manage", controllers.mcp.manage);
4622
+ app.post("/api/marketplace/mcp/doctor", controllers.mcp.doctor);
4623
+ app.get("/api/marketplace/mcp/recommendations", controllers.mcp.getRecommendations);
4624
+ }
4625
+
4316
4626
  // src/ui/router/marketplace/skill.controller.ts
4317
4627
  async function installMarketplaceSkill(params) {
4318
4628
  const spec = typeof params.body.spec === "string" ? params.body.spec.trim() : "";
@@ -4620,6 +4930,7 @@ function createUiRouter(options) {
4620
4930
  const ncpSessionController = new NcpSessionRoutesController(options);
4621
4931
  const pluginMarketplaceController = new PluginMarketplaceController(options, marketplaceBaseUrl);
4622
4932
  const skillMarketplaceController = new SkillMarketplaceController(options, marketplaceBaseUrl);
4933
+ const mcpMarketplaceController = new McpMarketplaceController(options, marketplaceBaseUrl);
4623
4934
  app.notFound((c) => c.json(err("NOT_FOUND", "endpoint not found"), 404));
4624
4935
  app.use("/api/*", async (c, next) => {
4625
4936
  const path = c.req.path;
@@ -4642,6 +4953,7 @@ function createUiRouter(options) {
4642
4953
  app.post("/api/auth/logout", authController.logout);
4643
4954
  app.put("/api/auth/password", authController.updatePassword);
4644
4955
  app.put("/api/auth/enabled", authController.updateEnabled);
4956
+ app.post("/api/auth/bridge", authController.issueBridgeSession);
4645
4957
  app.get("/api/config", configController.getConfig);
4646
4958
  app.get("/api/config/meta", configController.getConfigMeta);
4647
4959
  app.get("/api/config/schema", configController.getConfigSchema);
@@ -4688,20 +5000,11 @@ function createUiRouter(options) {
4688
5000
  app.delete("/api/cron/:id", cronController.deleteJob);
4689
5001
  app.put("/api/cron/:id/enable", cronController.enableJob);
4690
5002
  app.post("/api/cron/:id/run", cronController.runJob);
4691
- app.get("/api/marketplace/plugins/installed", pluginMarketplaceController.getInstalled);
4692
- app.get("/api/marketplace/plugins/items", pluginMarketplaceController.listItems);
4693
- app.get("/api/marketplace/plugins/items/:slug", pluginMarketplaceController.getItem);
4694
- app.get("/api/marketplace/plugins/items/:slug/content", pluginMarketplaceController.getItemContent);
4695
- app.post("/api/marketplace/plugins/install", pluginMarketplaceController.install);
4696
- app.post("/api/marketplace/plugins/manage", pluginMarketplaceController.manage);
4697
- app.get("/api/marketplace/plugins/recommendations", pluginMarketplaceController.getRecommendations);
4698
- app.get("/api/marketplace/skills/installed", skillMarketplaceController.getInstalled);
4699
- app.get("/api/marketplace/skills/items", skillMarketplaceController.listItems);
4700
- app.get("/api/marketplace/skills/items/:slug", skillMarketplaceController.getItem);
4701
- app.get("/api/marketplace/skills/items/:slug/content", skillMarketplaceController.getItemContent);
4702
- app.post("/api/marketplace/skills/install", skillMarketplaceController.install);
4703
- app.post("/api/marketplace/skills/manage", skillMarketplaceController.manage);
4704
- app.get("/api/marketplace/skills/recommendations", skillMarketplaceController.getRecommendations);
5003
+ mountMarketplaceRoutes(app, {
5004
+ plugin: pluginMarketplaceController,
5005
+ skill: skillMarketplaceController,
5006
+ mcp: mcpMarketplaceController
5007
+ });
4705
5008
  return app;
4706
5009
  }
4707
5010
 
@@ -4745,13 +5048,13 @@ function startUiServer(options) {
4745
5048
  })
4746
5049
  );
4747
5050
  const staticDir = options.staticDir;
4748
- if (staticDir && existsSync(join(staticDir, "index.html"))) {
4749
- const indexHtml = readFileSync(join(staticDir, "index.html"), "utf-8");
5051
+ if (staticDir && existsSync2(join2(staticDir, "index.html"))) {
5052
+ const indexHtml = readFileSync2(join2(staticDir, "index.html"), "utf-8");
4750
5053
  app.use(
4751
5054
  "/*",
4752
5055
  serveStatic({
4753
5056
  root: staticDir,
4754
- join,
5057
+ join: join2,
4755
5058
  getContent: async (path) => {
4756
5059
  try {
4757
5060
  return await readFile2(path);
@@ -4826,11 +5129,14 @@ export {
4826
5129
  createUiRouter,
4827
5130
  deleteCustomProvider,
4828
5131
  deleteSession,
5132
+ ensureUiBridgeSecret,
4829
5133
  executeConfigAction,
4830
5134
  getSessionHistory,
5135
+ getUiBridgeSecretPath,
4831
5136
  listSessions,
4832
5137
  loadConfigOrDefault,
4833
5138
  patchSession,
5139
+ readUiBridgeSecret,
4834
5140
  startUiServer,
4835
5141
  testProviderConnection,
4836
5142
  updateChannel,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/server",
3
- "version": "0.9.4",
3
+ "version": "0.10.0",
4
4
  "private": false,
5
5
  "description": "Nextclaw UI/API server.",
6
6
  "type": "module",
@@ -18,11 +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.9.2",
21
22
  "@nextclaw/ncp-http-agent-server": "0.3.1",
22
- "@nextclaw/runtime": "0.2.2",
23
+ "@nextclaw/mcp": "0.1.1",
24
+ "@nextclaw/ncp": "0.3.1",
23
25
  "@nextclaw/openclaw-compat": "0.3.5",
24
- "@nextclaw/core": "0.9.2",
25
- "@nextclaw/ncp": "0.3.1"
26
+ "@nextclaw/runtime": "0.2.2"
26
27
  },
27
28
  "devDependencies": {
28
29
  "@types/node": "^20.17.6",