@nextclaw/kernel 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -888,6 +888,7 @@ declare class NextclawNcpToolRegistry implements NcpToolRegistry {
888
888
  private buildToolExecutionContext;
889
889
  private registerDefaultTools;
890
890
  private registerMessagingTools;
891
+ private resolveMessageChannels;
891
892
  private registerExtensionTools;
892
893
  private registerTool;
893
894
  private registerAdditionalTools;
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { n as getUnsignedUpdateManifest, r as serializeUnsignedUpdateManifest, t
2
2
  import { AgentRouteResolver, CONTEXT_COMPACTION_METADATA_KEY, ChannelManager, ChannelManager as ChannelManager$1, CommandRegistry, ContextBuilder, ContextCompactionService, ContextWindowBudgetService, CronService, CronTool, DEFAULT_SESSION_SEARCH_LIMIT, DisposableStore, EditFileTool, ExecTool, ExtensionToolAdapter, GatewayTool, InputBudgetPruner, LLMProvider, ListDirTool, LiteLLMProvider, MAX_SESSION_SEARCH_LIMIT, MemoryGetTool, MemorySearchTool, MessageBus, MessageTool, ProviderRegistry, ReadFileTool, RequestedSkillsMetadataReader, SessionManager, SessionRequestManager, SessionSearchManager, SessionsHistoryTool, SessionsListTool, Tool, ToolRegistry, WebFetchTool, WebSearchTool, WriteFileTool, buildCompressingCompactionCheckpoint, buildContextWindowSnapshot, buildMinimalSystemExecutionPrompt, buildReloadPlan, buildToolCatalogEntries, createAssistantStreamDeltaControlMessage, createAssistantStreamResetControlMessage, createToolExecutionContext, createTypingStopControlMessage, diffConfigPaths, ensureDir, expandHome, findEffectiveAgentProfile, getConfigPath, getDataDir, getSessionsPath, getWorkspacePath, loadConfig, parseAgentScopedSessionKey, parseThinkingLevel, readCompressedContextCompactionCheckpoint, readParentSessionId, readSessionProjectRoot, resolveConfigSecrets, resolveDefaultAgentProfileId, resolveProviderRuntime, resolveSessionWorkspacePath, resolveThinkingLevel, toDisposable } from "@nextclaw/core";
3
3
  import { EventBus, Ingress, createAppEventKey, createTypedKey, eventKeys } from "@nextclaw/shared";
4
4
  import { DefaultNcpAgentRuntime, LocalAssetStore, buildAssetContentPath, buildNcpUserContent, buildOpenAiFunctionTool } from "@nextclaw/ncp-agent-runtime";
5
- import { NcpEventType, readAssistantReasoningNormalizationMode, readAssistantReasoningNormalizationModeFromMetadata, sanitizeAssistantReplyTags, writeAssistantReasoningNormalizationModeToMetadata } from "@nextclaw/ncp";
5
+ import { NcpEventType, consumeNcpRunHandle, createNcpRunHandle, readAssistantReasoningNormalizationMode, readAssistantReasoningNormalizationModeFromMetadata, sanitizeAssistantReplyTags, writeAssistantReasoningNormalizationModeToMetadata } from "@nextclaw/ncp";
6
6
  import { DefaultNcpAgentBackend, DefaultNcpAgentConversationStateManager, createAgentClientFromServer } from "@nextclaw/ncp-toolkit";
7
7
  import { basename, delimiter, dirname, join, resolve } from "node:path";
8
8
  import { access, appendFile, mkdir, readFile, readdir, unlink, writeFile } from "node:fs/promises";
@@ -2611,7 +2611,7 @@ var NextclawNcpToolRegistry = class {
2611
2611
  registerMessagingTools = (context) => {
2612
2612
  const { channel, chatId, metadata } = context;
2613
2613
  const accountId = readMetadataAccountId(metadata, {});
2614
- const messageTool = new MessageTool((message) => this.options.bus.publishOutbound(message));
2614
+ const messageTool = new MessageTool((message) => this.options.bus.publishOutbound(message), { resolveChannels: this.resolveMessageChannels });
2615
2615
  messageTool.setContext(channel, chatId, accountId ?? null);
2616
2616
  this.registerTool(messageTool);
2617
2617
  if (this.options.cronService) {
@@ -2620,6 +2620,10 @@ var NextclawNcpToolRegistry = class {
2620
2620
  this.registerTool(cronTool);
2621
2621
  }
2622
2622
  };
2623
+ resolveMessageChannels = () => {
2624
+ const channels = (this.options.getExtensionRegistry?.())?.channels ?? [];
2625
+ return [...new Set(channels.map((registration) => registration.channel.id.trim()).filter(Boolean))].sort();
2626
+ };
2623
2627
  registerExtensionTools = (context) => {
2624
2628
  const extensionRegistry = this.options.getExtensionRegistry?.();
2625
2629
  if (!extensionRegistry || extensionRegistry.tools.length === 0) return;
@@ -3383,35 +3387,39 @@ var AgentRuntimeManager = class {
3383
3387
  }
3384
3388
  };
3385
3389
  };
3386
- createMaterializingAgentClientEndpoint = (backend) => ({
3387
- get manifest() {
3388
- return backend.manifest;
3389
- },
3390
- start: backend.start,
3391
- stop: backend.stop,
3392
- subscribe: backend.subscribe,
3393
- stream: async (payload) => {
3394
- await consumeAgentEvents(backend.stream(payload));
3395
- },
3396
- abort: backend.abort,
3397
- send: async (envelope) => {
3398
- await consumeAgentEvents(backend.send(this.materializeAgentSendEnvelope(envelope)));
3399
- },
3400
- emit: async (event) => {
3401
- switch (event.type) {
3402
- case NcpEventType.MessageRequest:
3403
- await consumeAgentEvents(backend.send(this.materializeAgentSendEnvelope(event.payload)));
3404
- return;
3405
- case NcpEventType.MessageStreamRequest:
3406
- await consumeAgentEvents(backend.stream(event.payload));
3407
- return;
3408
- case NcpEventType.MessageAbort:
3409
- await backend.abort(event.payload);
3410
- return;
3411
- default: await backend.emit(event);
3390
+ createMaterializingAgentClientEndpoint = (backend) => {
3391
+ const send = async (envelope) => {
3392
+ const requestEnvelope = this.materializeAgentSendEnvelope(envelope);
3393
+ return await consumeNcpRunHandle(backend.send(requestEnvelope), createNcpRunHandle(requestEnvelope));
3394
+ };
3395
+ return {
3396
+ get manifest() {
3397
+ return backend.manifest;
3398
+ },
3399
+ start: backend.start,
3400
+ stop: backend.stop,
3401
+ subscribe: backend.subscribe,
3402
+ stream: async (payload) => {
3403
+ await consumeAgentEvents(backend.stream(payload));
3404
+ },
3405
+ abort: backend.abort,
3406
+ send,
3407
+ emit: async (event) => {
3408
+ switch (event.type) {
3409
+ case NcpEventType.MessageRequest:
3410
+ await send(event.payload);
3411
+ return;
3412
+ case NcpEventType.MessageStreamRequest:
3413
+ await consumeAgentEvents(backend.stream(event.payload));
3414
+ return;
3415
+ case NcpEventType.MessageAbort:
3416
+ await backend.abort(event.payload);
3417
+ return;
3418
+ default: await backend.emit(event);
3419
+ }
3412
3420
  }
3413
- }
3414
- });
3421
+ };
3422
+ };
3415
3423
  warmDerivedCapabilities = async () => {
3416
3424
  this.assertNotDisposed();
3417
3425
  this.warmupPromise ??= this.runDerivedCapabilityWarmup();
@@ -4349,21 +4357,6 @@ var NcpAgentLegacySessionStore = class {
4349
4357
  metadata: structuredClone(session.metadata)
4350
4358
  };
4351
4359
  };
4352
- getSessionSummary = (sessionId) => {
4353
- const session = this.getSession(sessionId);
4354
- if (!session) return null;
4355
- const lastMessageAt = session.messages.at(-1)?.timestamp;
4356
- return {
4357
- sessionId: session.sessionId,
4358
- ...session.agentId ? { agentId: session.agentId } : {},
4359
- messageCount: session.messages.length,
4360
- createdAt: session.createdAt,
4361
- updatedAt: session.updatedAt,
4362
- ...lastMessageAt ? { lastMessageAt } : {},
4363
- status: "idle",
4364
- metadata: session.metadata
4365
- };
4366
- };
4367
4360
  listSessionMessages = (sessionId) => this.getSession(sessionId)?.messages ?? [];
4368
4361
  listSessionSummaries = () => this.sessionManager.listSessions().map((record) => ({
4369
4362
  sessionId: record.key,
@@ -4429,7 +4422,6 @@ var NcpAgentSessionStoreAdapter = class {
4429
4422
  };
4430
4423
  }
4431
4424
  getSession = async (sessionId) => await this.options.journalStore?.getSession(sessionId) ?? this.legacyStore.getSession(sessionId);
4432
- getSessionSummary = async (sessionId) => await this.options.journalStore?.getSessionSummary(sessionId) ?? this.legacyStore.getSessionSummary(sessionId);
4433
4425
  listSessionMessages = async (sessionId) => {
4434
4426
  const journalStore = this.options.journalStore;
4435
4427
  return journalStore && await journalStore.hasSession(sessionId) ? await journalStore.listSessionMessages(sessionId) : this.legacyStore.listSessionMessages(sessionId);
@@ -4561,10 +4553,19 @@ function upsertNcpAgentSessionSummaryEvent(params) {
4561
4553
  }
4562
4554
  async function replayNcpAgentSessionEvents(events) {
4563
4555
  const stateManager = new DefaultNcpAgentConversationStateManager();
4564
- for (const event of events) await stateManager.dispatch(event.type === NcpEventType.MessageCompleted ? createCompletedMessageEvent(event) : structuredClone(event));
4556
+ for (const event of events) await stateManager.dispatch(createReplayEvent(event));
4565
4557
  const snapshot = stateManager.getSnapshot();
4566
4558
  return [...snapshot.messages.map((message) => structuredClone(message)), ...snapshot.streamingMessage ? [structuredClone(snapshot.streamingMessage)] : []];
4567
4559
  }
4560
+ function createReplayEvent(event) {
4561
+ const replayEvent = structuredClone(event);
4562
+ if (replayEvent.type === NcpEventType.MessageCompleted) return {
4563
+ type: NcpEventType.MessageSent,
4564
+ payload: replayEvent.payload
4565
+ };
4566
+ if (replayEvent.type === NcpEventType.MessageSent && replayEvent.payload.message.role === "assistant" && (replayEvent.payload.message.status === "pending" || replayEvent.payload.message.status === "streaming")) replayEvent.payload.message.status = "final";
4567
+ return replayEvent;
4568
+ }
4568
4569
  function readNcpSessionSummaryActivityAt(summary) {
4569
4570
  return summary.lastMessageAt ?? summary.createdAt ?? summary.updatedAt;
4570
4571
  }
@@ -4602,19 +4603,14 @@ function readSummaryLabelFromEvent(event) {
4602
4603
  if (message?.role !== "user") return null;
4603
4604
  return resolveAutoSessionLabel([message]);
4604
4605
  }
4605
- function createCompletedMessageEvent(event) {
4606
- return {
4607
- type: NcpEventType.MessageSent,
4608
- payload: {
4609
- sessionId: event.payload.sessionId,
4610
- message: structuredClone(event.payload.message),
4611
- ...event.payload.correlationId ? { correlationId: event.payload.correlationId } : {},
4612
- metadata: event.payload.metadata
4613
- }
4614
- };
4615
- }
4616
4606
  //#endregion
4617
4607
  //#region src/stores/ncp-agent-session-journal.store.ts
4608
+ function serializeJournalEntry(entry) {
4609
+ const serialized = JSON.stringify(entry);
4610
+ if (!serialized) throw new Error("ncp agent session journal entry serialization produced empty output");
4611
+ if (!isRecord$1(JSON.parse(serialized))) throw new Error("ncp agent session journal entry serialization produced a non-object entry");
4612
+ return serialized;
4613
+ }
4618
4614
  var NcpAgentSessionJournalStore = class {
4619
4615
  sessions = /* @__PURE__ */ new Map();
4620
4616
  nextSeqBySession = /* @__PURE__ */ new Map();
@@ -4646,14 +4642,6 @@ var NcpAgentSessionJournalStore = class {
4646
4642
  this.sessions.set(normalizedSessionId, loaded);
4647
4643
  return structuredClone(loaded.record);
4648
4644
  };
4649
- getSessionSummary = async (sessionId) => {
4650
- const normalizedSessionId = normalizeNcpSessionId(sessionId);
4651
- if (!normalizedSessionId) return null;
4652
- const indexed = (await this.loadSummaryIndex()).get(normalizedSessionId);
4653
- if (indexed) return structuredClone(indexed);
4654
- const record = await this.getSession(normalizedSessionId);
4655
- return record ? createNcpAgentSessionSummary(record) : null;
4656
- };
4657
4645
  listSessionSummaries = async () => {
4658
4646
  return [...(await this.loadSummaryIndex()).values()].map((summary) => structuredClone(summary)).sort((left, right) => readNcpSessionSummaryActivityAt(right).localeCompare(readNcpSessionSummaryActivityAt(left)));
4659
4647
  };
@@ -4682,7 +4670,7 @@ var NcpAgentSessionJournalStore = class {
4682
4670
  }
4683
4671
  }
4684
4672
  }))];
4685
- await writeFile(this.sessionPath(sessionId), `${entries.map((entry) => JSON.stringify(entry)).join("\n")}\n`, "utf-8");
4673
+ await writeFile(this.sessionPath(sessionId), `${entries.map(serializeJournalEntry).join("\n")}\n`, "utf-8");
4686
4674
  const nextSeq = nextRecord.messages.length + 1;
4687
4675
  this.sessions.set(sessionId, {
4688
4676
  record: nextRecord,
@@ -4716,7 +4704,7 @@ var NcpAgentSessionJournalStore = class {
4716
4704
  const hasJournal = Boolean(existing) || this.nextSeqBySession.has(sessionId);
4717
4705
  const nextSeq = this.nextSeqBySession.get(sessionId) ?? existing?.nextSeq ?? 1;
4718
4706
  const path = this.sessionPath(sessionId);
4719
- if (!hasJournal) await appendFile(path, `${JSON.stringify(createNcpAgentSessionJournalMetadataEntry(session))}\n`, "utf-8");
4707
+ if (!hasJournal) await this.appendJournalEntry(path, createNcpAgentSessionJournalMetadataEntry(session));
4720
4708
  const entry = {
4721
4709
  _type: "event",
4722
4710
  version: 1,
@@ -4724,7 +4712,7 @@ var NcpAgentSessionJournalStore = class {
4724
4712
  timestamp: updatedAt,
4725
4713
  event: structuredClone(event)
4726
4714
  };
4727
- await appendFile(path, `${JSON.stringify(entry)}\n`, "utf-8");
4715
+ await this.appendJournalEntry(path, entry);
4728
4716
  this.nextSeqBySession.set(sessionId, nextSeq + 1);
4729
4717
  this.sessions.delete(sessionId);
4730
4718
  await this.upsertSummaryIndexForEvent({
@@ -4763,9 +4751,15 @@ var NcpAgentSessionJournalStore = class {
4763
4751
  let updatedAt = createdAt;
4764
4752
  let nextSeq = 1;
4765
4753
  const events = [];
4766
- for (const line of raw.split("\n")) {
4754
+ for (const [index, line] of raw.split("\n").entries()) {
4767
4755
  if (!line.trim()) continue;
4768
- const parsed = JSON.parse(line);
4756
+ let parsed;
4757
+ try {
4758
+ parsed = JSON.parse(line);
4759
+ } catch (error) {
4760
+ console.warn(`[ncp-agent-session-journal] skipped corrupted journal line ${index + 1}: ${error instanceof Error ? error.message : String(error)}`);
4761
+ continue;
4762
+ }
4769
4763
  if (!isRecord$1(parsed)) continue;
4770
4764
  if (parsed._type === "metadata") {
4771
4765
  metadata = isRecord$1(parsed.metadata) ? structuredClone(parsed.metadata) : {};
@@ -4790,6 +4784,9 @@ var NcpAgentSessionJournalStore = class {
4790
4784
  events
4791
4785
  };
4792
4786
  };
4787
+ appendJournalEntry = async (path, entry) => {
4788
+ await appendFile(path, `${serializeJournalEntry(entry)}\n`, "utf-8");
4789
+ };
4793
4790
  loadSummaryIndex = async () => {
4794
4791
  if (this.summaryIndex) return this.summaryIndex;
4795
4792
  try {
@@ -4858,6 +4855,116 @@ var NcpAgentSessionJournalStore = class {
4858
4855
  indexPath = () => resolve(this.journalDir, NCP_AGENT_SESSION_JOURNAL_INDEX_FILE);
4859
4856
  };
4860
4857
  //#endregion
4858
+ //#region src/contributions/session-context-window/index.ts
4859
+ const STREAM_REFRESH_DELAY_MS = 1500;
4860
+ function formatBackgroundError$1(error) {
4861
+ if (error instanceof Error) return error.stack ?? error.message;
4862
+ return String(error);
4863
+ }
4864
+ function readEventSessionId(event) {
4865
+ const payload = "payload" in event ? event.payload : null;
4866
+ if (!payload || typeof payload !== "object") return null;
4867
+ return "sessionId" in payload && typeof payload.sessionId === "string" ? payload.sessionId.trim() || null : null;
4868
+ }
4869
+ function isContextWindow(value) {
4870
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4871
+ }
4872
+ function createSignature(value) {
4873
+ return JSON.stringify(value);
4874
+ }
4875
+ function shouldRefreshDuringStream(event) {
4876
+ switch (event.type) {
4877
+ case NcpEventType.MessageTextDelta:
4878
+ case NcpEventType.MessageReasoningDelta:
4879
+ case NcpEventType.MessageToolCallArgsDelta:
4880
+ case NcpEventType.MessageToolCallResult: return true;
4881
+ default: return false;
4882
+ }
4883
+ }
4884
+ function shouldRefreshImmediately(event) {
4885
+ switch (event.type) {
4886
+ case NcpEventType.MessageCompleted:
4887
+ case NcpEventType.MessageFailed:
4888
+ case NcpEventType.MessageAbort:
4889
+ case NcpEventType.RunFinished:
4890
+ case NcpEventType.RunError: return true;
4891
+ default: return false;
4892
+ }
4893
+ }
4894
+ var SessionContextWindowContribution = class {
4895
+ unsubscribeNcpEvent = null;
4896
+ stopped = true;
4897
+ pendingTimers = /* @__PURE__ */ new Map();
4898
+ lastPublishedSignatureBySession = /* @__PURE__ */ new Map();
4899
+ constructor(kernel) {
4900
+ this.kernel = kernel;
4901
+ }
4902
+ start = () => {
4903
+ if (this.unsubscribeNcpEvent) return;
4904
+ this.stopped = false;
4905
+ this.unsubscribeNcpEvent = this.kernel.eventBus.on(eventKeys.ncpEvent, this.handleNcpEvent);
4906
+ };
4907
+ dispose = () => {
4908
+ this.unsubscribeNcpEvent?.();
4909
+ this.unsubscribeNcpEvent = null;
4910
+ this.stopped = true;
4911
+ for (const timer of this.pendingTimers.values()) clearTimeout(timer);
4912
+ this.pendingTimers.clear();
4913
+ this.lastPublishedSignatureBySession.clear();
4914
+ };
4915
+ handleNcpEvent = (event) => {
4916
+ const sessionId = readEventSessionId(event);
4917
+ if (!sessionId) return;
4918
+ if (event.type === NcpEventType.ContextWindowUpdated) {
4919
+ this.rememberPublishedContextWindow(sessionId, event.payload.contextWindow);
4920
+ return;
4921
+ }
4922
+ if (shouldRefreshImmediately(event)) {
4923
+ this.refreshNow(sessionId);
4924
+ return;
4925
+ }
4926
+ if (shouldRefreshDuringStream(event)) this.refreshSoon(sessionId);
4927
+ };
4928
+ refreshSoon = (sessionId) => {
4929
+ if (this.pendingTimers.has(sessionId)) return;
4930
+ const timer = setTimeout(() => {
4931
+ this.pendingTimers.delete(sessionId);
4932
+ this.refreshNow(sessionId);
4933
+ }, STREAM_REFRESH_DELAY_MS);
4934
+ this.pendingTimers.set(sessionId, timer);
4935
+ };
4936
+ refreshNow = (sessionId) => {
4937
+ const timer = this.pendingTimers.get(sessionId);
4938
+ if (timer) {
4939
+ clearTimeout(timer);
4940
+ this.pendingTimers.delete(sessionId);
4941
+ }
4942
+ this.publishContextWindow(sessionId).catch((error) => {
4943
+ console.error(`[session-context-window] failed to refresh ${sessionId}: ${formatBackgroundError$1(error)}`);
4944
+ });
4945
+ };
4946
+ publishContextWindow = async (sessionId) => {
4947
+ if (this.stopped) return;
4948
+ const contextWindow = (await this.kernel.ncpSessionApi.getSession(sessionId))?.contextWindow;
4949
+ if (!isContextWindow(contextWindow) || this.stopped) return;
4950
+ const endpoint = this.kernel.agentRuntimeManager.currentHandle?.agentClientEndpoint;
4951
+ if (!endpoint) return;
4952
+ const signature = createSignature(contextWindow);
4953
+ if (this.lastPublishedSignatureBySession.get(sessionId) === signature) return;
4954
+ this.lastPublishedSignatureBySession.set(sessionId, signature);
4955
+ await endpoint.emit({
4956
+ type: NcpEventType.ContextWindowUpdated,
4957
+ payload: {
4958
+ sessionId,
4959
+ contextWindow
4960
+ }
4961
+ });
4962
+ };
4963
+ rememberPublishedContextWindow = (sessionId, contextWindow) => {
4964
+ this.lastPublishedSignatureBySession.set(sessionId, createSignature(contextWindow));
4965
+ };
4966
+ };
4967
+ //#endregion
4861
4968
  //#region src/contributions/session-activity-preview/utils/session-activity-preview-ncp-event.utils.ts
4862
4969
  const PREVIEW_TEXT_MAX_LENGTH = 160;
4863
4970
  function readSessionId(value) {
@@ -5159,7 +5266,7 @@ var NextclawKernel = class {
5159
5266
  sessionRequester: this.sessionRequests,
5160
5267
  resolveLearningLoopConfig: () => readLearningLoopRuntimeConfig(this.configManager.loadConfig())
5161
5268
  });
5162
- this.contributions = [new SessionActivityPreviewContribution(this)];
5269
+ this.contributions = [new SessionActivityPreviewContribution(this), new SessionContextWindowContribution(this)];
5163
5270
  }
5164
5271
  start = async () => {
5165
5272
  this.ncpSessionApi.start();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/kernel",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "private": false,
5
5
  "description": "NextClaw product kernel skeleton for agents, tasks, sessions, context, tools, skills, providers, automation, and channels.",
6
6
  "type": "module",
@@ -20,19 +20,19 @@
20
20
  "dist"
21
21
  ],
22
22
  "dependencies": {
23
- "@nextclaw/core": "0.12.17",
24
- "@nextclaw/mcp": "0.1.82",
25
- "@nextclaw/ncp-agent-runtime": "0.3.20",
26
- "@nextclaw/ncp-http-agent-server": "0.3.22",
27
- "@nextclaw/nextclaw-hermes-acp-bridge": "0.1.9",
28
- "@nextclaw/ncp-toolkit": "0.5.15",
29
- "@nextclaw/nextclaw-ncp-runtime-http-client": "0.1.9",
30
- "@nextclaw/openclaw-compat": "1.0.17",
31
- "@nextclaw/runtime": "0.2.49",
32
- "@nextclaw/nextclaw-ncp-runtime-stdio-client": "0.1.10",
33
- "@nextclaw/shared": "0.1.4",
34
- "@nextclaw/ncp": "0.5.10",
35
- "@nextclaw/ncp-mcp": "0.1.84"
23
+ "@nextclaw/core": "0.12.18",
24
+ "@nextclaw/ncp-http-agent-server": "0.3.23",
25
+ "@nextclaw/mcp": "0.1.83",
26
+ "@nextclaw/ncp-agent-runtime": "0.3.21",
27
+ "@nextclaw/ncp-mcp": "0.1.85",
28
+ "@nextclaw/ncp-toolkit": "0.5.16",
29
+ "@nextclaw/nextclaw-hermes-acp-bridge": "0.1.10",
30
+ "@nextclaw/nextclaw-ncp-runtime-stdio-client": "0.1.11",
31
+ "@nextclaw/ncp": "0.5.11",
32
+ "@nextclaw/openclaw-compat": "1.0.18",
33
+ "@nextclaw/runtime": "0.2.50",
34
+ "@nextclaw/shared": "0.1.5",
35
+ "@nextclaw/nextclaw-ncp-runtime-http-client": "0.1.10"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/node": "^20.17.6",