@nuvin/nuvin-core 1.7.1 → 1.8.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/VERSION CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "version": "1.7.1",
3
- "commit": "c220b68"
2
+ "version": "1.8.0",
3
+ "commit": "da28f44"
4
4
  }
package/dist/index.d.ts CHANGED
@@ -1905,6 +1905,54 @@ declare function okJson<T extends Record<string, unknown> | unknown[], M extends
1905
1905
  };
1906
1906
  declare function err(result: string, metadata?: Record<string, unknown>, errorReason?: ErrorReason): ExecResultError;
1907
1907
 
1908
+ type CommandSource = 'global' | 'profile' | 'local';
1909
+ interface CustomCommandTemplate {
1910
+ id: string;
1911
+ description: string;
1912
+ prompt: string;
1913
+ enabled?: boolean;
1914
+ source: CommandSource;
1915
+ filePath?: string;
1916
+ }
1917
+ interface CompleteCustomCommand extends CustomCommandTemplate {
1918
+ id: string;
1919
+ description: string;
1920
+ prompt: string;
1921
+ enabled: boolean;
1922
+ source: CommandSource;
1923
+ filePath: string;
1924
+ shadowedBy?: CommandSource;
1925
+ }
1926
+ interface CustomCommandFrontmatter {
1927
+ description: string;
1928
+ enabled?: boolean;
1929
+ }
1930
+ declare function isValidCommandId(id: string): boolean;
1931
+ declare function sanitizeCommandId(name: string): string;
1932
+
1933
+ interface CommandFilePersistenceOptions {
1934
+ globalDir: string;
1935
+ profileDir?: string;
1936
+ localDir: string;
1937
+ }
1938
+ declare class CommandFilePersistence {
1939
+ private globalDir;
1940
+ private profileDir?;
1941
+ private localDir;
1942
+ constructor(options: CommandFilePersistenceOptions);
1943
+ setProfileDir(profileDir: string | undefined): void;
1944
+ getDir(source: CommandSource): string;
1945
+ private ensureDir;
1946
+ loadAll(): Promise<CustomCommandTemplate[]>;
1947
+ private loadFromDir;
1948
+ load(filename: string, source: CommandSource): Promise<CustomCommandTemplate | null>;
1949
+ save(command: CustomCommandTemplate): Promise<void>;
1950
+ delete(commandId: string, source: CommandSource): Promise<void>;
1951
+ exists(commandId: string, source: CommandSource): boolean;
1952
+ private parseFrontmatter;
1953
+ private buildMarkdown;
1954
+ }
1955
+
1908
1956
  /**
1909
1957
  * Sub-agent related types
1910
1958
  * These types track the state and execution of delegated specialist agents
@@ -2216,6 +2264,9 @@ declare class MCPToolPort implements ToolPort {
2216
2264
  executeToolCalls(calls: ToolInvocation[], _context?: Record<string, unknown>, maxConcurrent?: number, signal?: AbortSignal): Promise<ToolExecutionResult[]>;
2217
2265
  }
2218
2266
 
2267
+ /**
2268
+ * @deprecated Use MCPServerConfig from nuvin-cli/config/types.ts instead
2269
+ */
2219
2270
  type MCPServerConfig = {
2220
2271
  command?: string;
2221
2272
  args?: string[];
@@ -2225,11 +2276,14 @@ type MCPServerConfig = {
2225
2276
  headers?: Record<string, string>;
2226
2277
  prefix?: string;
2227
2278
  timeoutMs?: number;
2279
+ enabled?: boolean;
2228
2280
  };
2281
+ /**
2282
+ * @deprecated MCP config is now part of main CLI config under mcp.servers
2283
+ */
2229
2284
  type MCPConfig = {
2230
2285
  mcpServers: Record<string, MCPServerConfig>;
2231
2286
  };
2232
- declare function loadMCPConfig(filePath?: string): Promise<MCPConfig | null>;
2233
2287
 
2234
2288
  declare class PersistingConsoleEventPort implements EventPort {
2235
2289
  private memory;
@@ -2249,4 +2303,4 @@ declare function resolveBackspaces(s: string): string;
2249
2303
  declare function stripAnsiAndControls(s: string): string;
2250
2304
  declare function canonicalizeTerminalPaste(raw: string): string;
2251
2305
 
2252
- export { AGENT_CREATOR_SYSTEM_PROMPT, AbortError, type AgentAwareToolPort, type AgentCatalog, type AgentConfig, type AgentEvent, AgentEventTypes, AgentFilePersistence, AgentManager, AgentManagerCommandRunner, AgentOrchestrator, AgentRegistry, type AgentTemplate, AnthropicAISDKLLM, type AssignErrorResult, type AssignParams, type AssignResult, type AssignSuccessResult$1 as AssignSuccessResult, type AssignTaskArgs, type AssignTaskMetadata, type BaseLLMOptions, type BashErrorResult, type BashParams, type BashResult, type BashSuccessResult$1 as BashSuccessResult, BashTool, type BashToolArgs, type BashToolMetadata, type CommandMetadata, type CompleteAgent, CompositeToolPort, type Conversation, ConversationContext, type ConversationMetadata, type ConversationSnapshot, ConversationStore, CoreMCPClient, DEFAULT_RETRY_CONFIG, DefaultDelegationPolicy, DefaultDelegationResultFormatter, DefaultDelegationService, DefaultSpecialistAgentFactory, type DelegationMetadata, type DelegationService, type DelegationServiceConfig, DelegationServiceFactory, type DirEntry, type DirLsArgs, type DirLsMetadata, type DirLsParams, type DirLsResult, type DirLsSuccessResult$1 as DirLsSuccessResult, type ErrorMetadata, ErrorReason, type ExecResult, type ExecResultError, type ExecResultSuccess, type FileEditArgs, type FileEditMetadata, type FileEditResult, type FileEditSuccessResult$1 as FileEditSuccessResult, type FileMetadata, type FileNewArgs, type FileNewMetadata, type FileNewParams, type FileNewResult, type FileNewSuccessResult$1 as FileNewSuccessResult, type FileReadArgs, type FileReadErrorResult, type FileReadMetadata, type FileReadParams, type FileReadResult, type FileReadSuccessResult$1 as FileReadSuccessResult, type FolderTreeOptions, type FunctionTool, GithubLLM, InMemoryMemory, InMemoryMetadata, InMemoryMetricsPort, JsonFileMemoryPersistence, type LLMConfig, LLMError, type LLMFactory, type LLMOptions, type LLMPort, LLMResolver, type LineRangeMetadata, type MCPConfig, type MCPServerConfig, MCPToolPort, type MemoryPort, MemoryPortMetadataAdapter, type Message, type MessageContent, type MessageContentPart, type MetadataPort, type MetricsChangeHandler, type MetricsPort, type MetricsSnapshot, type ModelInfo, type ModelLimits, NoopMetricsPort, NoopReminders, type OrchestratorAwareToolPort, type ParseResult, PersistedMemory, PersistingConsoleEventPort, type RetryConfig, RetryTransport, RuntimeEnv, type SendMessageOptions, SimpleContextBuilder, SimpleCost, SimpleId, type SpecialistAgentConfig, type SpecialistAgentResult, type SubAgentState, type SubAgentToolCall, SystemClock, type TodoWriteArgs, type TodoWriteMetadata, type TodoWriteResult, type TodoWriteSuccessResult$1 as TodoWriteSuccessResult, type ToolApprovalDecision, type ToolArguments, type ToolCall, type ToolCallValidation, type ToolErrorMetadata, type ToolExecutionContext, type ToolExecutionResult, type ToolMetadataMap, type ToolName, type ToolParameterMap, type ToolPort, ToolRegistry, type ToolValidator, type TypedToolInvocation, type UsageData, type UserAttachment, type UserMessagePayload, type ValidationResult, type WebFetchArgs, type WebFetchMetadata, type WebFetchParams, type WebFetchResult, type WebFetchSuccessResult$1 as WebFetchSuccessResult, type WebSearchArgs, type WebSearchMetadata, type WebSearchParams, type WebSearchResult, type WebSearchSuccessResult$1 as WebSearchSuccessResult, type WebSearchToolResult, buildAgentCreationPrompt, buildInjectedSystem, canonicalizeTerminalPaste, convertToolCall, convertToolCalls, createEmptySnapshot, createLLM, deduplicateModels, err, generateFolderTree, getAvailableProviders, getFallbackLimits, getProviderLabel, isAssignResult, isAssignSuccess, isAssignTaskArgs, isBashResult, isBashSuccess, isBashToolArgs, isDirLsArgs, isDirLsResult, isDirLsSuccess, isError, isFileEditArgs, isFileEditResult, isFileEditSuccess, isFileNewArgs, isFileNewResult, isFileNewSuccess, isFileReadArgs, isFileReadResult, isFileReadSuccess, isJsonResult, isRetryableError, isRetryableStatusCode, isSuccess, isSuccessJson, isSuccessText, isTextResult, isTodoWriteArgs, isTodoWriteResult, isTodoWriteSuccess, isWebFetchArgs, isWebFetchResult, isWebFetchSuccess, isWebSearchArgs, isWebSearchResult, isWebSearchSuccess, loadMCPConfig, normalizeModelInfo, normalizeModelLimits, normalizeNewlines, okJson, okText, parseJSON, parseSubAgentToolCallArguments, parseToolArguments, renderTemplate, resolveBackspaces, resolveCarriageReturns, stripAnsiAndControls, supportsGetModels, toolValidators };
2306
+ export { AGENT_CREATOR_SYSTEM_PROMPT, AbortError, type AgentAwareToolPort, type AgentCatalog, type AgentConfig, type AgentEvent, AgentEventTypes, AgentFilePersistence, AgentManager, AgentManagerCommandRunner, AgentOrchestrator, AgentRegistry, type AgentTemplate, AnthropicAISDKLLM, type AssignErrorResult, type AssignParams, type AssignResult, type AssignSuccessResult$1 as AssignSuccessResult, type AssignTaskArgs, type AssignTaskMetadata, type BaseLLMOptions, type BashErrorResult, type BashParams, type BashResult, type BashSuccessResult$1 as BashSuccessResult, BashTool, type BashToolArgs, type BashToolMetadata, CommandFilePersistence, type CommandMetadata, type CommandSource, type CompleteAgent, type CompleteCustomCommand, CompositeToolPort, type Conversation, ConversationContext, type ConversationMetadata, type ConversationSnapshot, ConversationStore, CoreMCPClient, type CustomCommandFrontmatter, type CustomCommandTemplate, DEFAULT_RETRY_CONFIG, DefaultDelegationPolicy, DefaultDelegationResultFormatter, DefaultDelegationService, DefaultSpecialistAgentFactory, type DelegationMetadata, type DelegationService, type DelegationServiceConfig, DelegationServiceFactory, type DirEntry, type DirLsArgs, type DirLsMetadata, type DirLsParams, type DirLsResult, type DirLsSuccessResult$1 as DirLsSuccessResult, type ErrorMetadata, ErrorReason, type ExecResult, type ExecResultError, type ExecResultSuccess, type FileEditArgs, type FileEditMetadata, type FileEditResult, type FileEditSuccessResult$1 as FileEditSuccessResult, type FileMetadata, type FileNewArgs, type FileNewMetadata, type FileNewParams, type FileNewResult, type FileNewSuccessResult$1 as FileNewSuccessResult, type FileReadArgs, type FileReadErrorResult, type FileReadMetadata, type FileReadParams, type FileReadResult, type FileReadSuccessResult$1 as FileReadSuccessResult, type FolderTreeOptions, type FunctionTool, GithubLLM, InMemoryMemory, InMemoryMetadata, InMemoryMetricsPort, JsonFileMemoryPersistence, type LLMConfig, LLMError, type LLMFactory, type LLMOptions, type LLMPort, LLMResolver, type LineRangeMetadata, type MCPConfig, type MCPServerConfig, MCPToolPort, type MemoryPort, MemoryPortMetadataAdapter, type Message, type MessageContent, type MessageContentPart, type MetadataPort, type MetricsChangeHandler, type MetricsPort, type MetricsSnapshot, type ModelInfo, type ModelLimits, NoopMetricsPort, NoopReminders, type OrchestratorAwareToolPort, type ParseResult, PersistedMemory, PersistingConsoleEventPort, type RetryConfig, RetryTransport, RuntimeEnv, type SendMessageOptions, SimpleContextBuilder, SimpleCost, SimpleId, type SpecialistAgentConfig, type SpecialistAgentResult, type SubAgentState, type SubAgentToolCall, SystemClock, type TodoWriteArgs, type TodoWriteMetadata, type TodoWriteResult, type TodoWriteSuccessResult$1 as TodoWriteSuccessResult, type ToolApprovalDecision, type ToolArguments, type ToolCall, type ToolCallValidation, type ToolErrorMetadata, type ToolExecutionContext, type ToolExecutionResult, type ToolMetadataMap, type ToolName, type ToolParameterMap, type ToolPort, ToolRegistry, type ToolValidator, type TypedToolInvocation, type UsageData, type UserAttachment, type UserMessagePayload, type ValidationResult, type WebFetchArgs, type WebFetchMetadata, type WebFetchParams, type WebFetchResult, type WebFetchSuccessResult$1 as WebFetchSuccessResult, type WebSearchArgs, type WebSearchMetadata, type WebSearchParams, type WebSearchResult, type WebSearchSuccessResult$1 as WebSearchSuccessResult, type WebSearchToolResult, buildAgentCreationPrompt, buildInjectedSystem, canonicalizeTerminalPaste, convertToolCall, convertToolCalls, createEmptySnapshot, createLLM, deduplicateModels, err, generateFolderTree, getAvailableProviders, getFallbackLimits, getProviderLabel, isAssignResult, isAssignSuccess, isAssignTaskArgs, isBashResult, isBashSuccess, isBashToolArgs, isDirLsArgs, isDirLsResult, isDirLsSuccess, isError, isFileEditArgs, isFileEditResult, isFileEditSuccess, isFileNewArgs, isFileNewResult, isFileNewSuccess, isFileReadArgs, isFileReadResult, isFileReadSuccess, isJsonResult, isRetryableError, isRetryableStatusCode, isSuccess, isSuccessJson, isSuccessText, isTextResult, isTodoWriteArgs, isTodoWriteResult, isTodoWriteSuccess, isValidCommandId, isWebFetchArgs, isWebFetchResult, isWebFetchSuccess, isWebSearchArgs, isWebSearchResult, isWebSearchSuccess, normalizeModelInfo, normalizeModelLimits, normalizeNewlines, okJson, okText, parseJSON, parseSubAgentToolCallArguments, parseToolArguments, renderTemplate, resolveBackspaces, resolveCarriageReturns, sanitizeCommandId, stripAnsiAndControls, supportsGetModels, toolValidators };
package/dist/index.js CHANGED
@@ -1361,8 +1361,8 @@ var AgentOrchestrator = class {
1361
1361
  }
1362
1362
  async waitForToolApproval(toolCalls, conversationId, messageId) {
1363
1363
  const approvalId = this.ids.uuid();
1364
- return new Promise((resolve6, reject) => {
1365
- this.pendingApprovals.set(approvalId, { resolve: resolve6, reject });
1364
+ return new Promise((resolve5, reject) => {
1365
+ this.pendingApprovals.set(approvalId, { resolve: resolve5, reject });
1366
1366
  this.events?.emit({
1367
1367
  type: AgentEventTypes.ToolApprovalRequired,
1368
1368
  conversationId,
@@ -3344,14 +3344,14 @@ var AgentRegistry = class {
3344
3344
  * Load agents from both persistence and files
3345
3345
  */
3346
3346
  async loadAgents() {
3347
- const promises2 = [];
3347
+ const promises = [];
3348
3348
  if (this.persistence) {
3349
- promises2.push(this.loadFromPersistence());
3349
+ promises.push(this.loadFromPersistence());
3350
3350
  }
3351
3351
  if (this.filePersistence) {
3352
- promises2.push(this.loadFromFiles());
3352
+ promises.push(this.loadFromFiles());
3353
3353
  }
3354
- await Promise.all(promises2);
3354
+ await Promise.all(promises);
3355
3355
  }
3356
3356
  /**
3357
3357
  * Wait for all agents to finish loading
@@ -4581,6 +4581,175 @@ var AgentFilePersistence = class {
4581
4581
  }
4582
4582
  };
4583
4583
 
4584
+ // src/command-file-persistence.ts
4585
+ import * as fs9 from "fs";
4586
+ import * as path8 from "path";
4587
+ import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
4588
+
4589
+ // src/command-types.ts
4590
+ function isValidCommandId(id) {
4591
+ return /^[a-z][a-z0-9-]*$/.test(id);
4592
+ }
4593
+ function sanitizeCommandId(name) {
4594
+ return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
4595
+ }
4596
+
4597
+ // src/command-file-persistence.ts
4598
+ var CommandFilePersistence = class {
4599
+ globalDir;
4600
+ profileDir;
4601
+ localDir;
4602
+ constructor(options) {
4603
+ this.globalDir = options.globalDir;
4604
+ this.profileDir = options.profileDir;
4605
+ this.localDir = options.localDir;
4606
+ }
4607
+ setProfileDir(profileDir) {
4608
+ this.profileDir = profileDir;
4609
+ }
4610
+ getDir(source) {
4611
+ switch (source) {
4612
+ case "global":
4613
+ return this.globalDir;
4614
+ case "profile":
4615
+ if (!this.profileDir) {
4616
+ throw new Error("Profile directory not set");
4617
+ }
4618
+ return this.profileDir;
4619
+ case "local":
4620
+ return this.localDir;
4621
+ }
4622
+ }
4623
+ ensureDir(dir) {
4624
+ if (!fs9.existsSync(dir)) {
4625
+ fs9.mkdirSync(dir, { recursive: true });
4626
+ }
4627
+ }
4628
+ async loadAll() {
4629
+ const commands = [];
4630
+ const sources = ["global", "local"];
4631
+ if (this.profileDir) {
4632
+ sources.splice(1, 0, "profile");
4633
+ }
4634
+ for (const source of sources) {
4635
+ try {
4636
+ const dir = this.getDir(source);
4637
+ const loaded = await this.loadFromDir(dir, source);
4638
+ commands.push(...loaded);
4639
+ } catch {
4640
+ }
4641
+ }
4642
+ return commands;
4643
+ }
4644
+ async loadFromDir(dir, source) {
4645
+ const commands = [];
4646
+ if (!fs9.existsSync(dir)) {
4647
+ return commands;
4648
+ }
4649
+ const files = fs9.readdirSync(dir);
4650
+ const mdFiles = files.filter((f) => f.endsWith(".md"));
4651
+ for (const file of mdFiles) {
4652
+ try {
4653
+ const command = await this.load(file, source);
4654
+ if (command) {
4655
+ commands.push(command);
4656
+ }
4657
+ } catch (error) {
4658
+ console.warn(`Failed to load command from ${file}:`, error);
4659
+ }
4660
+ }
4661
+ return commands;
4662
+ }
4663
+ async load(filename, source) {
4664
+ try {
4665
+ const dir = this.getDir(source);
4666
+ const filePath = path8.join(dir, filename);
4667
+ const content = fs9.readFileSync(filePath, "utf8");
4668
+ const { frontmatter, body } = this.parseFrontmatter(content);
4669
+ if (!frontmatter.description) {
4670
+ console.warn(`Invalid command template in ${filename}: missing description`);
4671
+ return null;
4672
+ }
4673
+ const id = path8.basename(filename, ".md");
4674
+ return {
4675
+ id,
4676
+ description: frontmatter.description,
4677
+ prompt: body.trim(),
4678
+ enabled: frontmatter.enabled ?? true,
4679
+ source,
4680
+ filePath
4681
+ };
4682
+ } catch (error) {
4683
+ console.warn(`Failed to load command from ${filename}:`, error);
4684
+ return null;
4685
+ }
4686
+ }
4687
+ async save(command) {
4688
+ const dir = this.getDir(command.source);
4689
+ this.ensureDir(dir);
4690
+ const id = sanitizeCommandId(command.id);
4691
+ const filename = `${id}.md`;
4692
+ const filePath = path8.join(dir, filename);
4693
+ const frontmatter = {
4694
+ description: command.description
4695
+ };
4696
+ if (command.enabled === false) {
4697
+ frontmatter.enabled = false;
4698
+ }
4699
+ const content = this.buildMarkdown(frontmatter, command.prompt);
4700
+ fs9.writeFileSync(filePath, content, "utf8");
4701
+ }
4702
+ async delete(commandId, source) {
4703
+ const dir = this.getDir(source);
4704
+ const filename = `${sanitizeCommandId(commandId)}.md`;
4705
+ const filePath = path8.join(dir, filename);
4706
+ if (fs9.existsSync(filePath)) {
4707
+ fs9.unlinkSync(filePath);
4708
+ }
4709
+ }
4710
+ exists(commandId, source) {
4711
+ try {
4712
+ const dir = this.getDir(source);
4713
+ const filename = `${sanitizeCommandId(commandId)}.md`;
4714
+ const filePath = path8.join(dir, filename);
4715
+ return fs9.existsSync(filePath);
4716
+ } catch {
4717
+ return false;
4718
+ }
4719
+ }
4720
+ parseFrontmatter(content) {
4721
+ const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;
4722
+ const match = content.match(frontmatterRegex);
4723
+ if (!match) {
4724
+ return {
4725
+ frontmatter: {},
4726
+ body: content
4727
+ };
4728
+ }
4729
+ try {
4730
+ const frontmatter = parseYaml(match[1] || "");
4731
+ return {
4732
+ frontmatter: frontmatter || {},
4733
+ body: match[2] || ""
4734
+ };
4735
+ } catch {
4736
+ return {
4737
+ frontmatter: {},
4738
+ body: content
4739
+ };
4740
+ }
4741
+ }
4742
+ buildMarkdown(frontmatter, body) {
4743
+ const yamlContent = stringifyYaml(frontmatter, { lineWidth: 0 }).trim();
4744
+ return `---
4745
+ ${yamlContent}
4746
+ ---
4747
+
4748
+ ${body}
4749
+ `;
4750
+ }
4751
+ };
4752
+
4584
4753
  // src/sub-agent-types.ts
4585
4754
  function parseSubAgentToolCallArguments(argsString) {
4586
4755
  if (!argsString) return {};
@@ -5354,12 +5523,12 @@ var AbortError = class _AbortError extends Error {
5354
5523
  }
5355
5524
  };
5356
5525
  var sleep = (ms, signal) => {
5357
- return new Promise((resolve6, reject) => {
5526
+ return new Promise((resolve5, reject) => {
5358
5527
  if (signal?.aborted) {
5359
5528
  reject(new AbortError("Operation aborted"));
5360
5529
  return;
5361
5530
  }
5362
- const timeout = setTimeout(resolve6, ms);
5531
+ const timeout = setTimeout(resolve5, ms);
5363
5532
  signal?.addEventListener(
5364
5533
  "abort",
5365
5534
  () => {
@@ -6730,71 +6899,6 @@ var MCPToolPort = class {
6730
6899
  return results;
6731
6900
  }
6732
6901
  };
6733
-
6734
- // src/config.ts
6735
- import * as fs9 from "fs";
6736
- import * as path8 from "path";
6737
- import { parse as parseYaml } from "yaml";
6738
- async function loadMCPConfig(filePath = ".nuvin_mcp.json") {
6739
- try {
6740
- const resolvedPath = path8.resolve(filePath);
6741
- if (!fs9.existsSync(resolvedPath)) {
6742
- return null;
6743
- }
6744
- const raw = await fs9.promises.readFile(resolvedPath, "utf-8");
6745
- if (!raw.trim()) {
6746
- return null;
6747
- }
6748
- const ext = path8.extname(resolvedPath).toLowerCase();
6749
- let data;
6750
- if (ext === ".yaml" || ext === ".yml") {
6751
- data = parseYaml(raw);
6752
- } else {
6753
- data = JSON.parse(raw);
6754
- }
6755
- return normalizeMCPConfig(data);
6756
- } catch (error) {
6757
- console.warn(`Failed to load MCP config from ${filePath}:`, error);
6758
- return null;
6759
- }
6760
- }
6761
- function normalizeMCPConfig(raw) {
6762
- if (!raw || typeof raw !== "object") {
6763
- return null;
6764
- }
6765
- const asRecord = raw;
6766
- if (isValidConfig(asRecord)) {
6767
- const servers = asRecord.mcpServers;
6768
- if (servers && typeof servers === "object" && !Array.isArray(servers)) {
6769
- return { mcpServers: servers };
6770
- }
6771
- }
6772
- if ("config" in asRecord && asRecord.config && typeof asRecord.config === "object") {
6773
- const nested = asRecord.config;
6774
- if (isValidConfig(nested)) {
6775
- const servers = nested.mcpServers;
6776
- if (servers && typeof servers === "object" && !Array.isArray(servers)) {
6777
- return { mcpServers: servers };
6778
- }
6779
- }
6780
- }
6781
- return null;
6782
- }
6783
- function isValidConfig(value) {
6784
- if (!("mcpServers" in value)) {
6785
- return false;
6786
- }
6787
- const servers = value.mcpServers;
6788
- if (!servers || typeof servers !== "object" || Array.isArray(servers)) {
6789
- return false;
6790
- }
6791
- for (const server of Object.values(servers)) {
6792
- if (!server || typeof server !== "object" || Array.isArray(server)) {
6793
- return false;
6794
- }
6795
- }
6796
- return true;
6797
- }
6798
6902
  export {
6799
6903
  AGENT_CREATOR_SYSTEM_PROMPT,
6800
6904
  AbortError,
@@ -6806,6 +6910,7 @@ export {
6806
6910
  AgentRegistry,
6807
6911
  AnthropicAISDKLLM,
6808
6912
  BashTool,
6913
+ CommandFilePersistence,
6809
6914
  CompositeToolPort,
6810
6915
  ConversationContext,
6811
6916
  ConversationStore,
@@ -6879,13 +6984,13 @@ export {
6879
6984
  isTodoWriteArgs,
6880
6985
  isTodoWriteResult,
6881
6986
  isTodoWriteSuccess,
6987
+ isValidCommandId,
6882
6988
  isWebFetchArgs,
6883
6989
  isWebFetchResult,
6884
6990
  isWebFetchSuccess,
6885
6991
  isWebSearchArgs,
6886
6992
  isWebSearchResult,
6887
6993
  isWebSearchSuccess,
6888
- loadMCPConfig,
6889
6994
  normalizeModelInfo,
6890
6995
  normalizeModelLimits,
6891
6996
  normalizeNewlines,
@@ -6897,6 +7002,7 @@ export {
6897
7002
  renderTemplate,
6898
7003
  resolveBackspaces,
6899
7004
  resolveCarriageReturns,
7005
+ sanitizeCommandId,
6900
7006
  stripAnsiAndControls,
6901
7007
  supportsGetModels,
6902
7008
  toolValidators
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuvin/nuvin-core",
3
- "version": "1.7.1",
3
+ "version": "1.8.0",
4
4
  "description": "",
5
5
  "private": false,
6
6
  "main": "dist/index.js",