@nextclaw/server 0.11.24 → 0.12.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.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  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 { PluginChannelBinding, PluginUiMetadata } from '@nextclaw/openclaw-compat';
4
- import { NcpAgentClientEndpoint, NcpSessionSummary, NcpMessage, NcpSessionApi } from '@nextclaw/ncp';
4
+ import { NcpAgentClientEndpoint, NcpSessionSummary, NcpSessionStatus, NcpMessage, NcpSessionApi } from '@nextclaw/ncp';
5
5
  import { NcpHttpAgentStreamProvider } from '@nextclaw/ncp-http-agent-server';
6
6
  import { IncomingMessage } from 'node:http';
7
7
  import { Hono } from 'hono';
@@ -351,6 +351,7 @@ type UiRouterOptions = {
351
351
  productVersion?: string;
352
352
  publish: (event: UiServerEvent) => void;
353
353
  applyLiveConfigReload?: () => Promise<void>;
354
+ initializeAgentHomeDirectory?: (homeDirectory: string) => void;
354
355
  marketplace?: MarketplaceApiConfig;
355
356
  cronService?: InstanceType<typeof NextclawCore.CronService>;
356
357
  ncpAgent?: UiNcpAgent;
@@ -687,12 +688,28 @@ type RemoteServiceActionResult = {
687
688
  type AgentProfileView = {
688
689
  id: string;
689
690
  default?: boolean;
691
+ displayName?: string;
692
+ description?: string;
693
+ avatar?: string;
694
+ avatarUrl?: string;
690
695
  workspace?: string;
691
696
  model?: string;
692
697
  engine?: string;
693
698
  engineConfig?: Record<string, unknown>;
694
699
  contextTokens?: number;
695
700
  maxToolIterations?: number;
701
+ builtIn?: boolean;
702
+ };
703
+ type AgentCreateRequest = {
704
+ id: string;
705
+ displayName?: string;
706
+ description?: string;
707
+ avatar?: string;
708
+ home?: string;
709
+ };
710
+ type AgentDeleteResult = {
711
+ deleted: boolean;
712
+ agentId: string;
696
713
  };
697
714
  type BindingPeerView = {
698
715
  kind: "direct" | "group" | "channel";
@@ -767,8 +784,8 @@ type SessionSkillEntryView = {
767
784
  ref: string;
768
785
  name: string;
769
786
  path: string;
770
- scope: "project" | "workspace";
771
- source: "project" | "workspace";
787
+ scope: "builtin" | "project" | "workspace";
788
+ source: "builtin" | "project" | "workspace";
772
789
  available: boolean;
773
790
  description?: string;
774
791
  descriptionZh?: string;
@@ -906,6 +923,7 @@ type UiNcpSessionListView = {
906
923
  };
907
924
  type UiNcpSessionMessagesView = {
908
925
  sessionId: string;
926
+ status: NcpSessionStatus;
909
927
  messages: NcpMessage[];
910
928
  total: number;
911
929
  };
@@ -1140,6 +1158,7 @@ type UiServerOptions = {
1140
1158
  productVersion?: string;
1141
1159
  corsOrigins?: string[] | "*";
1142
1160
  staticDir?: string;
1161
+ initializeAgentHomeDirectory?: (homeDirectory: string) => void;
1143
1162
  marketplace?: MarketplaceApiConfig;
1144
1163
  cronService?: CronService;
1145
1164
  ncpAgent?: UiNcpAgent;
@@ -1217,4 +1236,4 @@ declare function getUiBridgeSecretPath(): string;
1217
1236
  declare function readUiBridgeSecret(): string | null;
1218
1237
  declare function ensureUiBridgeSecret(): string;
1219
1238
 
1220
- 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 BootstrapPhase, type BootstrapRemoteState, type BootstrapStageState, type BootstrapStatusView, type ChannelAuthPollRequest, type ChannelAuthPollResult, type ChannelAuthStartRequest, type ChannelAuthStartResult, type ChannelSpecView, type ChatSessionTypeCtaView, type ChatSessionTypeOptionView, type ChatSessionTypesView, 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 NcpSessionSkillsView, 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 ServerPathBreadcrumbView, type ServerPathBrowseView, type ServerPathEntryView, type SessionConfigView, type SessionEntryView, type SessionEventView, type SessionHistoryView, type SessionMessageView, type SessionPatchUpdate, SessionPatchValidationError, type SessionSkillEntryView, type SessionTypeDescribeParams, type SessionsListView, type UiNcpAgent, type UiNcpAssetPutView, type UiNcpAssetView, type UiNcpSessionListView, type UiNcpSessionMessagesView, type UiNcpSessionService, type UiNcpStoredAssetRecord, 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 };
1239
+ export { type AgentBindingView, type AgentCreateRequest, type AgentDeleteResult, type AgentProfileView, type ApiError, type ApiResponse, type AppMetaView, type AuthEnabledUpdateRequest, type AuthLoginRequest, type AuthPasswordUpdateRequest, type AuthSetupRequest, type AuthStatusView, type BindingPeerView, type BochaFreshnessValue, type BootstrapPhase, type BootstrapRemoteState, type BootstrapStageState, type BootstrapStatusView, type ChannelAuthPollRequest, type ChannelAuthPollResult, type ChannelAuthStartRequest, type ChannelAuthStartResult, type ChannelSpecView, type ChatSessionTypeCtaView, type ChatSessionTypeOptionView, type ChatSessionTypesView, 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 NcpSessionSkillsView, 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 ServerPathBreadcrumbView, type ServerPathBrowseView, type ServerPathEntryView, type SessionConfigView, type SessionEntryView, type SessionEventView, type SessionHistoryView, type SessionMessageView, type SessionPatchUpdate, SessionPatchValidationError, type SessionSkillEntryView, type SessionTypeDescribeParams, type SessionsListView, type UiNcpAgent, type UiNcpAssetPutView, type UiNcpAssetView, type UiNcpSessionListView, type UiNcpSessionMessagesView, type UiNcpSessionService, type UiNcpStoredAssetRecord, 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
@@ -333,7 +333,86 @@ var UiAuthService = class {
333
333
  import { Hono } from "hono";
334
334
  import { mountNcpHttpAgentRoutes } from "@nextclaw/ncp-http-agent-server";
335
335
 
336
- // src/ui/router/response.ts
336
+ // src/ui/agents.ts
337
+ import {
338
+ createAgentProfile,
339
+ findEffectiveAgentProfile,
340
+ loadConfig as loadConfig2,
341
+ readAgentAvatarContent,
342
+ removeAgentProfile,
343
+ resolveEffectiveAgentProfiles
344
+ } from "@nextclaw/core";
345
+ function listAgents(configPath) {
346
+ const config = loadConfig2(configPath);
347
+ return resolveEffectiveAgentProfiles(config).map((profile) => toAgentProfileView(config, profile.id));
348
+ }
349
+ function createAgent(configPath, input, options = {}) {
350
+ const created = createAgentProfile(
351
+ {
352
+ id: input.id,
353
+ displayName: input.displayName,
354
+ description: input.description,
355
+ avatar: input.avatar,
356
+ home: input.home
357
+ },
358
+ {
359
+ configPath,
360
+ initializeHomeDirectory: options.initializeAgentHomeDirectory
361
+ }
362
+ );
363
+ const config = loadConfig2(configPath);
364
+ return toAgentProfileView(config, created.id);
365
+ }
366
+ function deleteAgent(configPath, agentId) {
367
+ const deleted = removeAgentProfile(agentId, { configPath });
368
+ if (!deleted) {
369
+ return null;
370
+ }
371
+ return {
372
+ deleted: true,
373
+ agentId: agentId.trim().toLowerCase()
374
+ };
375
+ }
376
+ function readAgentAvatar(configPath, agentId) {
377
+ const config = loadConfig2(configPath);
378
+ return readAgentAvatarContent({ config, agentId });
379
+ }
380
+ function toAgentProfileView(config, agentId) {
381
+ const profile = findEffectiveAgentProfile(config, agentId);
382
+ if (!profile) {
383
+ throw new Error(`unknown agent: ${agentId}`);
384
+ }
385
+ return {
386
+ id: profile.id,
387
+ default: profile.default,
388
+ displayName: profile.displayName,
389
+ description: profile.description,
390
+ avatar: profile.avatar,
391
+ avatarUrl: buildAgentAvatarUrl(profile.id, profile.avatar),
392
+ workspace: profile.workspace,
393
+ model: profile.model,
394
+ engine: profile.engine,
395
+ engineConfig: profile.engineConfig,
396
+ contextTokens: profile.contextTokens,
397
+ maxToolIterations: profile.maxToolIterations,
398
+ builtIn: profile.builtIn === true
399
+ };
400
+ }
401
+ function buildAgentAvatarUrl(agentId, avatar) {
402
+ const normalized = typeof avatar === "string" ? avatar.trim() : "";
403
+ if (!normalized) {
404
+ return void 0;
405
+ }
406
+ if (normalized.startsWith("http://") || normalized.startsWith("https://")) {
407
+ return normalized;
408
+ }
409
+ if (normalized.startsWith("home://")) {
410
+ return `/api/agents/${encodeURIComponent(agentId)}/avatar`;
411
+ }
412
+ return void 0;
413
+ }
414
+
415
+ // src/ui/ui-routes/response.ts
337
416
  function ok(data) {
338
417
  return { ok: true, data };
339
418
  }
@@ -380,7 +459,68 @@ function formatUserFacingError(error, maxChars = 320) {
380
459
  return `${normalized.slice(0, Math.max(0, maxChars - 3)).trimEnd()}...`;
381
460
  }
382
461
 
383
- // src/ui/router/app.controller.ts
462
+ // src/ui/ui-routes/agents.controller.ts
463
+ var AgentsRoutesController = class {
464
+ constructor(options) {
465
+ this.options = options;
466
+ }
467
+ publishAgentUpdates = async (paths) => {
468
+ for (const path of paths) {
469
+ this.options.publish({ type: "config.updated", payload: { path } });
470
+ }
471
+ await this.options.applyLiveConfigReload?.();
472
+ };
473
+ listAgents = (c) => {
474
+ return c.json(ok({ agents: listAgents(this.options.configPath) }));
475
+ };
476
+ createAgent = async (c) => {
477
+ const body = await readJson(c.req.raw);
478
+ if (!body.ok) {
479
+ return c.json(err("INVALID_BODY", "invalid json body"), 400);
480
+ }
481
+ try {
482
+ const agent = createAgent(this.options.configPath, body.data, {
483
+ initializeAgentHomeDirectory: this.options.initializeAgentHomeDirectory
484
+ });
485
+ await this.publishAgentUpdates(["agents.list"]);
486
+ return c.json(ok(agent));
487
+ } catch (error) {
488
+ return c.json(err("AGENT_CREATE_FAILED", error instanceof Error ? error.message : String(error)), 400);
489
+ }
490
+ };
491
+ deleteAgent = async (c) => {
492
+ const agentId = c.req.param("agentId");
493
+ try {
494
+ const result = deleteAgent(this.options.configPath, agentId);
495
+ if (!result) {
496
+ return c.json(err("NOT_FOUND", `agent not found: ${agentId}`), 404);
497
+ }
498
+ await this.publishAgentUpdates(["agents.list"]);
499
+ return c.json(ok(result));
500
+ } catch (error) {
501
+ return c.json(err("AGENT_DELETE_FAILED", error instanceof Error ? error.message : String(error)), 400);
502
+ }
503
+ };
504
+ getAgentAvatar = (c) => {
505
+ const agentId = c.req.param("agentId");
506
+ try {
507
+ const avatar = readAgentAvatar(this.options.configPath, agentId);
508
+ if (!avatar) {
509
+ return c.json(err("NOT_FOUND", `avatar not found for agent: ${agentId}`), 404);
510
+ }
511
+ return new Response(avatar.bytes, {
512
+ headers: {
513
+ "content-type": avatar.mimeType,
514
+ "cache-control": "public, max-age=300"
515
+ }
516
+ });
517
+ } catch (error) {
518
+ return c.json(err("AGENT_AVATAR_FAILED", error instanceof Error ? error.message : String(error)), 400);
519
+ }
520
+ };
521
+ };
522
+
523
+ // src/ui/ui-routes/app.controller.ts
384
524
  function buildAppMetaView(options) {
385
525
  const productVersion = options.productVersion?.trim();
386
526
  return {
@@ -455,7 +595,7 @@ function ensureUiBridgeSecret() {
455
595
  return secret;
456
596
  }
457
597
 
458
- // src/ui/router/auth.controller.ts
598
+ // src/ui/ui-routes/auth.controller.ts
459
599
  function isAuthenticationRequiredError(message) {
460
600
  return message === "Authentication required.";
461
601
  }
@@ -568,7 +708,7 @@ var AuthRoutesController = class {
568
708
 
569
709
  // src/ui/config.ts
570
710
  import {
571
- loadConfig as loadConfig2,
711
+ loadConfig as loadConfig3,
572
712
  saveConfig as saveConfig2,
573
713
  ConfigSchema as ConfigSchema2,
574
714
  DEFAULT_WORKSPACE_PATH,
@@ -1409,7 +1549,7 @@ async function executeConfigAction(configPath, actionId, request) {
1409
1549
  };
1410
1550
  }
1411
1551
  function loadConfigOrDefault(configPath) {
1412
- return loadConfig2(configPath);
1552
+ return loadConfig3(configPath);
1413
1553
  }
1414
1554
  function updateModel(configPath, patch) {
1415
1555
  const config = loadConfigOrDefault(configPath);
@@ -2129,7 +2269,7 @@ import { homedir } from "os";
2129
2269
  import { isAbsolute, resolve } from "path";
2130
2270
  import {
2131
2271
  ConfigSchema as ConfigSchema3,
2132
- loadConfig as loadConfig3,
2272
+ loadConfig as loadConfig4,
2133
2273
  saveConfig as saveConfig4
2134
2274
  } from "@nextclaw/core";
2135
2275
  var authSessions = /* @__PURE__ */ new Map();
@@ -2324,7 +2464,7 @@ function readFieldAsString(source, fieldName) {
2324
2464
  return trimmed.length > 0 ? trimmed : null;
2325
2465
  }
2326
2466
  function setProviderApiKey(params) {
2327
- const config = loadConfig3(params.configPath);
2467
+ const config = loadConfig4(params.configPath);
2328
2468
  const providers = config.providers;
2329
2469
  if (!providers[params.provider]) {
2330
2470
  providers[params.provider] = createDefaultProviderConfig();
@@ -2655,7 +2795,7 @@ async function importProviderAuthFromCli(configPath, providerName) {
2655
2795
  };
2656
2796
  }
2657
2797
 
2658
- // src/ui/router/config.controller.ts
2798
+ // src/ui/ui-routes/config.controller.ts
2659
2799
  var ConfigRoutesController = class {
2660
2800
  constructor(options) {
2661
2801
  this.options = options;
@@ -2947,7 +3087,7 @@ var ConfigRoutesController = class {
2947
3087
  };
2948
3088
  };
2949
3089
 
2950
- // src/ui/router/cron.controller.ts
3090
+ // src/ui/ui-routes/cron.controller.ts
2951
3091
  function toIsoTime(value) {
2952
3092
  if (typeof value !== "number" || !Number.isFinite(value)) {
2953
3093
  return null;
@@ -3047,7 +3187,7 @@ var CronRoutesController = class {
3047
3187
  };
3048
3188
  };
3049
3189
 
3050
- // src/ui/router/ncp-attachment.controller.ts
3190
+ // src/ui/ui-routes/ncp-attachment.controller.ts
3051
3191
  import { readFile as readFile2 } from "fs/promises";
3052
3192
  var ASSET_CONTENT_BASE_PATH = "/api/ncp/assets/content";
3053
3193
  function buildAssetContentUrl(assetUri) {
@@ -3182,7 +3322,7 @@ function isSessionProjectRootValidationError(error) {
3182
3322
  // src/ui/session-project/session-skills.ts
3183
3323
  import * as NextclawCore from "@nextclaw/core";
3184
3324
 
3185
- // src/ui/router/marketplace/constants.ts
3325
+ // src/ui/ui-routes/marketplace/constants.ts
3186
3326
  var DEFAULT_MARKETPLACE_API_BASE = "https://marketplace-api.nextclaw.io";
3187
3327
  var NEXTCLAW_PLUGIN_NPM_PREFIX = "@nextclaw/channel-plugin-";
3188
3328
  var BUILTIN_CHANNEL_PLUGIN_ID_PREFIX = "builtin-channel-";
@@ -3266,7 +3406,8 @@ var MARKETPLACE_ZH_COPY_BY_SLUG = {
3266
3406
  // src/ui/session-project/session-skills.ts
3267
3407
  var SCOPE_SORT_ORDER = {
3268
3408
  project: 0,
3269
- workspace: 1
3409
+ workspace: 1,
3410
+ builtin: 2
3270
3411
  };
3271
3412
  var SessionSkillsViewBuilder = class {
3272
3413
  constructor(options) {
@@ -3321,7 +3462,7 @@ var SessionSkillsViewBuilder = class {
3321
3462
  };
3322
3463
  };
3323
3464
 
3324
- // src/ui/router/ncp-session.controller.ts
3465
+ // src/ui/ui-routes/ncp-session.controller.ts
3325
3466
  function readPositiveInt(value) {
3326
3467
  if (typeof value !== "string") {
3327
3468
  return void 0;
@@ -3429,6 +3570,7 @@ var NcpSessionRoutesController = class {
3429
3570
  });
3430
3571
  const payload = {
3431
3572
  sessionId,
3573
+ status: session.status ?? "idle",
3432
3574
  messages,
3433
3575
  total: messages.length
3434
3576
  };
@@ -3519,7 +3661,7 @@ var NcpSessionRoutesController = class {
3519
3661
  };
3520
3662
  };
3521
3663
 
3522
- // src/ui/router/marketplace/marketplace-network-retry.ts
3664
+ // src/ui/ui-routes/marketplace/marketplace-network-retry.ts
3523
3665
  var MARKETPLACE_NETWORK_RETRY_ATTEMPTS = 5;
3524
3666
  var MARKETPLACE_NETWORK_RETRY_BASE_MS = 350;
3525
3667
  function sleepMs(ms) {
@@ -3562,7 +3704,7 @@ async function runWithMarketplaceNetworkRetry(action) {
3562
3704
  throw lastError;
3563
3705
  }
3564
3706
 
3565
- // src/ui/router/marketplace/catalog.ts
3707
+ // src/ui/ui-routes/marketplace/catalog.ts
3566
3708
  function normalizeMarketplaceBaseUrl(options) {
3567
3709
  const configured = options.marketplace?.apiBaseUrl?.trim();
3568
3710
  if (!configured) {
@@ -3777,7 +3919,7 @@ function sanitizeMarketplaceItemView(item) {
3777
3919
  return sanitizeMarketplaceItem(item);
3778
3920
  }
3779
3921
 
3780
- // src/ui/router/marketplace/mcp.controller.ts
3922
+ // src/ui/ui-routes/marketplace/mcp.controller.ts
3781
3923
  import { McpInstalledViewService } from "@nextclaw/mcp";
3782
3924
  var McpMarketplaceController = class {
3783
3925
  constructor(options, marketplaceBaseUrl) {
@@ -3987,11 +4129,11 @@ var McpMarketplaceController = class {
3987
4129
  };
3988
4130
  };
3989
4131
 
3990
- // src/ui/router/marketplace/installed.ts
4132
+ // src/ui/ui-routes/marketplace/installed.ts
3991
4133
  import * as NextclawCore2 from "@nextclaw/core";
3992
4134
  import { discoverPluginStatusReport } from "@nextclaw/openclaw-compat";
3993
4135
 
3994
- // src/ui/router/marketplace/spec.ts
4136
+ // src/ui/ui-routes/marketplace/spec.ts
3995
4137
  function normalizePluginNpmSpec(rawSpec) {
3996
4138
  const spec = rawSpec.trim();
3997
4139
  if (!spec.startsWith("@")) {
@@ -4094,7 +4236,7 @@ function dedupeInstalledPluginRecordsByCanonicalSpec(records) {
4094
4236
  return Array.from(deduped.values());
4095
4237
  }
4096
4238
 
4097
- // src/ui/router/marketplace/installed.ts
4239
+ // src/ui/ui-routes/marketplace/installed.ts
4098
4240
  var getWorkspacePathFromConfig4 = NextclawCore2.getWorkspacePathFromConfig;
4099
4241
  function createSkillsLoader(workspace) {
4100
4242
  const ctor = NextclawCore2.SkillsLoader;
@@ -4296,7 +4438,7 @@ function collectInstalledSkillRecords(options) {
4296
4438
  const listedSkills = skillsLoader?.listSkills(false) ?? [];
4297
4439
  const records = listedSkills.map((skill) => {
4298
4440
  const enabled = availableSkillSet.has(skill.name);
4299
- const metadata = skillsLoader?.getSkillMetadata?.(skill.name);
4441
+ const metadata = skillsLoader?.getSkillMetadata?.(skill);
4300
4442
  const description = readNonEmptyString(metadata?.description);
4301
4443
  const descriptionZh = readNonEmptyString(metadata?.description_zh) ?? readNonEmptyString(metadata?.descriptionZh) ?? readNonEmptyString(MARKETPLACE_ZH_COPY_BY_SLUG[skill.name]?.description);
4302
4444
  return {
@@ -4387,7 +4529,7 @@ function findUnsupportedSkillInstallKind(items) {
4387
4529
  return null;
4388
4530
  }
4389
4531
 
4390
- // src/ui/router/marketplace/plugin.controller.ts
4532
+ // src/ui/ui-routes/marketplace/plugin.controller.ts
4391
4533
  async function loadPluginReadmeFromNpm(spec) {
4392
4534
  const encodedSpec = encodeURIComponent(spec);
4393
4535
  const registryUrl = `https://registry.npmjs.org/${encodedSpec}`;
@@ -4650,7 +4792,7 @@ var PluginMarketplaceController = class {
4650
4792
  };
4651
4793
  };
4652
4794
 
4653
- // src/ui/router/marketplace/routes.ts
4795
+ // src/ui/ui-routes/marketplace/routes.ts
4654
4796
  function mountMarketplaceRoutes(app, controllers) {
4655
4797
  app.get("/api/marketplace/plugins/installed", controllers.plugin.getInstalled);
4656
4798
  app.get("/api/marketplace/plugins/items", controllers.plugin.listItems);
@@ -4676,7 +4818,7 @@ function mountMarketplaceRoutes(app, controllers) {
4676
4818
  app.get("/api/marketplace/mcp/recommendations", controllers.mcp.getRecommendations);
4677
4819
  }
4678
4820
 
4679
- // src/ui/router/marketplace/skill.controller.ts
4821
+ // src/ui/ui-routes/marketplace/skill.controller.ts
4680
4822
  async function installMarketplaceSkill(params) {
4681
4823
  const spec = typeof params.body.spec === "string" ? params.body.spec.trim() : "";
4682
4824
  if (!spec) {
@@ -4900,7 +5042,7 @@ var SkillMarketplaceController = class {
4900
5042
  };
4901
5043
  };
4902
5044
 
4903
- // src/ui/router/remote.controller.ts
5045
+ // src/ui/ui-routes/remote.controller.ts
4904
5046
  var REMOTE_SERVICE_ACTIONS = /* @__PURE__ */ new Set(["start", "restart", "stop"]);
4905
5047
  function readTrimmedString(value) {
4906
5048
  return typeof value === "string" ? value.trim() : void 0;
@@ -5121,7 +5263,7 @@ function isServerPathBrowseError(error) {
5121
5263
  return error instanceof ServerPathBrowseError;
5122
5264
  }
5123
5265
 
5124
- // src/ui/router/server-path.controller.ts
5266
+ // src/ui/ui-routes/server-path.controller.ts
5125
5267
  function readIncludeFilesFlag(value) {
5126
5268
  return value === "1" || value === "true";
5127
5269
  }
@@ -5152,6 +5294,12 @@ function registerAuthRoutes(app, authController) {
5152
5294
  app.put("/api/auth/enabled", authController.updateEnabled);
5153
5295
  app.post("/api/auth/bridge", authController.issueBridgeSession);
5154
5296
  }
5297
+ function registerAgentRoutes(app, agentsController) {
5298
+ app.get("/api/agents", agentsController.listAgents);
5299
+ app.post("/api/agents", agentsController.createAgent);
5300
+ app.delete("/api/agents/:agentId", agentsController.deleteAgent);
5301
+ app.get("/api/agents/:agentId/avatar", agentsController.getAgentAvatar);
5302
+ }
5155
5303
  function registerConfigRoutes(app, configController) {
5156
5304
  app.get("/api/config", configController.getConfig);
5157
5305
  app.get("/api/config/meta", configController.getConfigMeta);
@@ -5220,6 +5368,7 @@ function createUiRouter(options) {
5220
5368
  const marketplaceBaseUrl = normalizeMarketplaceBaseUrl(options);
5221
5369
  const authService = options.authService ?? new UiAuthService(options.configPath);
5222
5370
  const appController = new AppRoutesController(options);
5371
+ const agentsController = new AgentsRoutesController(options);
5223
5372
  const authController = new AuthRoutesController(authService);
5224
5373
  const configController = new ConfigRoutesController(options);
5225
5374
  const cronController = new CronRoutesController(options);
@@ -5248,6 +5397,7 @@ function createUiRouter(options) {
5248
5397
  app.get("/api/app/meta", appController.appMeta);
5249
5398
  app.get("/api/runtime/bootstrap-status", appController.bootstrapStatus);
5250
5399
  registerAuthRoutes(app, authController);
5400
+ registerAgentRoutes(app, agentsController);
5251
5401
  registerConfigRoutes(app, configController);
5252
5402
  registerNcpSessionRoutes(app, ncpSessionController);
5253
5403
  registerServerPathRoutes(app, serverPathController);
@@ -5358,6 +5508,7 @@ function startUiServer(options) {
5358
5508
  productVersion: options.productVersion,
5359
5509
  publish,
5360
5510
  applyLiveConfigReload: options.applyLiveConfigReload,
5511
+ initializeAgentHomeDirectory: options.initializeAgentHomeDirectory,
5361
5512
  marketplace: options.marketplace,
5362
5513
  cronService: options.cronService,
5363
5514
  ncpAgent: options.ncpAgent,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/server",
3
- "version": "0.11.24",
3
+ "version": "0.12.0",
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.11.17",
22
- "@nextclaw/ncp-http-agent-server": "0.3.11",
23
- "@nextclaw/ncp": "0.4.6",
24
- "@nextclaw/openclaw-compat": "0.3.58",
25
- "@nextclaw/mcp": "0.1.64",
26
- "@nextclaw/runtime": "0.2.31"
21
+ "@nextclaw/core": "0.12.0",
22
+ "@nextclaw/mcp": "0.1.65",
23
+ "@nextclaw/ncp": "0.5.0",
24
+ "@nextclaw/ncp-http-agent-server": "0.3.12",
25
+ "@nextclaw/openclaw-compat": "1.0.0",
26
+ "@nextclaw/runtime": "0.2.32"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/node": "^20.17.6",