@corbat-tech/coco 2.24.2 → 2.25.1

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
@@ -580,6 +580,15 @@ declare const CocoConfigSchema: z.ZodObject<{
580
580
  enabled: z.ZodDefault<z.ZodBoolean>;
581
581
  description: z.ZodOptional<z.ZodString>;
582
582
  }, z.core.$strip>>>;
583
+ defaultTimeout: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
584
+ autoDiscover: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
585
+ logLevel: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
586
+ error: "error";
587
+ info: "info";
588
+ debug: "debug";
589
+ warn: "warn";
590
+ }>>>;
591
+ customServersPath: z.ZodOptional<z.ZodString>;
583
592
  }, z.core.$strip>>;
584
593
  tools: z.ZodOptional<z.ZodObject<{
585
594
  webSearch: z.ZodOptional<z.ZodObject<{
@@ -621,7 +630,9 @@ declare const CocoConfigSchema: z.ZodObject<{
621
630
  skills: z.ZodOptional<z.ZodObject<{
622
631
  enabled: z.ZodDefault<z.ZodBoolean>;
623
632
  globalDir: z.ZodOptional<z.ZodString>;
633
+ globalDirs: z.ZodOptional<z.ZodArray<z.ZodString>>;
624
634
  projectDir: z.ZodOptional<z.ZodString>;
635
+ projectDirs: z.ZodOptional<z.ZodArray<z.ZodString>>;
625
636
  autoActivate: z.ZodDefault<z.ZodBoolean>;
626
637
  maxActiveSkills: z.ZodDefault<z.ZodNumber>;
627
638
  disabled: z.ZodDefault<z.ZodArray<z.ZodString>>;
package/dist/index.js CHANGED
@@ -625,7 +625,15 @@ var init_schema = __esm({
625
625
  enabled: z.boolean().default(true),
626
626
  configFile: z.string().optional(),
627
627
  // Path to external MCP config file
628
- servers: z.array(MCPServerConfigEntrySchema).default([])
628
+ servers: z.array(MCPServerConfigEntrySchema).default([]),
629
+ /** Default timeout for MCP requests in milliseconds */
630
+ defaultTimeout: z.number().min(1e3).default(6e4).optional(),
631
+ /** Auto-discover MCP servers from well-known locations */
632
+ autoDiscover: z.boolean().default(true).optional(),
633
+ /** Log level for MCP operations */
634
+ logLevel: z.enum(["debug", "info", "warn", "error"]).default("info").optional(),
635
+ /** Path to custom servers directory */
636
+ customServersPath: z.string().optional()
629
637
  });
630
638
  ToolsConfigSchema = z.object({
631
639
  webSearch: z.object({
@@ -668,8 +676,12 @@ var init_schema = __esm({
668
676
  enabled: z.boolean().default(true),
669
677
  /** Override global skills directory */
670
678
  globalDir: z.string().optional(),
679
+ /** Override global skills directories (preferred over globalDir) */
680
+ globalDirs: z.array(z.string()).optional(),
671
681
  /** Override project skills directory */
672
682
  projectDir: z.string().optional(),
683
+ /** Override project skills directories (preferred over projectDir) */
684
+ projectDirs: z.array(z.string()).optional(),
673
685
  /** Auto-activate skills based on user messages */
674
686
  autoActivate: z.boolean().default(true),
675
687
  /** Maximum concurrent active markdown skills */
@@ -739,11 +751,15 @@ var init_paths = __esm({
739
751
  /** Search index directory: ~/.coco/search-index/ */
740
752
  searchIndex: join(COCO_HOME, "search-index"),
741
753
  /** Global skills directory: ~/.coco/skills/ */
742
- skills: join(COCO_HOME, "skills")
754
+ skills: join(COCO_HOME, "skills"),
755
+ /** MCP server registry: ~/.coco/mcp.json */
756
+ mcpRegistry: join(COCO_HOME, "mcp.json")
743
757
  };
744
758
  ({
745
759
  /** Old config location */
746
- oldConfig: join(homedir(), ".config", "corbat-coco")
760
+ oldConfig: join(homedir(), ".config", "corbat-coco"),
761
+ /** Old MCP config directory (pre-unification) */
762
+ oldMcpDir: join(homedir(), ".config", "coco", "mcp")
747
763
  });
748
764
  }
749
765
  });
@@ -14248,7 +14264,9 @@ var OpenAIProvider = class {
14248
14264
  break;
14249
14265
  case "response.completed":
14250
14266
  {
14267
+ const emittedCallIds = /* @__PURE__ */ new Set();
14251
14268
  for (const toolCall of toolCallAssembler.finalizeAll(this.name)) {
14269
+ if (toolCall.id) emittedCallIds.add(toolCall.id);
14252
14270
  yield {
14253
14271
  type: "tool_use_end",
14254
14272
  toolCall: {
@@ -14258,9 +14276,20 @@ var OpenAIProvider = class {
14258
14276
  }
14259
14277
  };
14260
14278
  }
14261
- const hasToolCalls = event.response.output.some(
14262
- (i) => i.type === "function_call"
14263
- );
14279
+ const outputItems = event.response?.output ?? [];
14280
+ for (const item of outputItems) {
14281
+ if (item.type !== "function_call" || !item.call_id || !item.name) continue;
14282
+ if (emittedCallIds.has(item.call_id)) continue;
14283
+ yield {
14284
+ type: "tool_use_end",
14285
+ toolCall: {
14286
+ id: item.call_id,
14287
+ name: item.name,
14288
+ input: parseToolCallArguments(item.arguments ?? "{}", this.name)
14289
+ }
14290
+ };
14291
+ }
14292
+ const hasToolCalls = outputItems.some((i) => i.type === "function_call");
14264
14293
  yield {
14265
14294
  type: "done",
14266
14295
  stopReason: hasToolCalls ? "tool_use" : "end_turn"
@@ -14874,6 +14903,8 @@ var CodexProvider = class {
14874
14903
  const decoder = new TextDecoder();
14875
14904
  let buffer = "";
14876
14905
  const toolCallAssembler = new ResponsesToolCallAssembler();
14906
+ const emittedToolCallIds = /* @__PURE__ */ new Set();
14907
+ const emittedToolCallSignatures = /* @__PURE__ */ new Set();
14877
14908
  let lastActivityTime = Date.now();
14878
14909
  const timeoutController = new AbortController();
14879
14910
  const timeoutInterval = setInterval(() => {
@@ -14936,6 +14967,9 @@ var CodexProvider = class {
14936
14967
  this.name
14937
14968
  );
14938
14969
  if (toolCall) {
14970
+ if (toolCall.id) emittedToolCallIds.add(toolCall.id);
14971
+ const signature = `${toolCall.name}:${JSON.stringify(toolCall.input ?? {})}`;
14972
+ emittedToolCallSignatures.add(signature);
14939
14973
  yield {
14940
14974
  type: "tool_use_end",
14941
14975
  toolCall: {
@@ -14949,6 +14983,9 @@ var CodexProvider = class {
14949
14983
  }
14950
14984
  case "response.completed": {
14951
14985
  for (const toolCall of toolCallAssembler.finalizeAll(this.name)) {
14986
+ if (toolCall.id) emittedToolCallIds.add(toolCall.id);
14987
+ const signature = `${toolCall.name}:${JSON.stringify(toolCall.input ?? {})}`;
14988
+ emittedToolCallSignatures.add(signature);
14952
14989
  yield {
14953
14990
  type: "tool_use_end",
14954
14991
  toolCall: {
@@ -14958,8 +14995,26 @@ var CodexProvider = class {
14958
14995
  }
14959
14996
  };
14960
14997
  }
14961
- const resp = event.response;
14962
- const output = resp?.output ?? [];
14998
+ const responsePayload = event.response;
14999
+ const output = responsePayload?.output ?? [];
15000
+ for (const item of output) {
15001
+ if (item.type !== "function_call" || !item.call_id || !item.name) continue;
15002
+ const parsedInput = parseToolCallArguments(item.arguments ?? "{}", this.name);
15003
+ const signature = `${item.name}:${JSON.stringify(parsedInput ?? {})}`;
15004
+ if (emittedToolCallIds.has(item.call_id) || emittedToolCallSignatures.has(signature)) {
15005
+ continue;
15006
+ }
15007
+ emittedToolCallIds.add(item.call_id);
15008
+ emittedToolCallSignatures.add(signature);
15009
+ yield {
15010
+ type: "tool_use_end",
15011
+ toolCall: {
15012
+ id: item.call_id,
15013
+ name: item.name,
15014
+ input: parsedInput
15015
+ }
15016
+ };
15017
+ }
14963
15018
  const hasToolCalls = output.some((i) => i.type === "function_call");
14964
15019
  yield {
14965
15020
  type: "done",