@corbat-tech/coco 2.34.0 → 2.35.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.js CHANGED
@@ -44,8 +44,13 @@ import yaml from 'highlight.js/lib/languages/yaml';
44
44
 
45
45
  var __defProp = Object.defineProperty;
46
46
  var __getOwnPropNames = Object.getOwnPropertyNames;
47
- var __esm = (fn, res) => function __init() {
48
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
47
+ var __esm = (fn, res, err) => function __init() {
48
+ if (err) throw err[0];
49
+ try {
50
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
51
+ } catch (e) {
52
+ throw err = [e], e;
53
+ }
49
54
  };
50
55
  var __export = (target, all) => {
51
56
  for (var name in all)
@@ -253,6 +258,793 @@ var init_logger = __esm({
253
258
  globalLogger = null;
254
259
  }
255
260
  });
261
+
262
+ // src/providers/catalog.ts
263
+ function model(entry) {
264
+ return {
265
+ ...entry,
266
+ source: entry.source ?? SOURCES.providerDocs
267
+ };
268
+ }
269
+ function getProviderCatalogEntry(provider) {
270
+ return PROVIDER_CATALOG[provider];
271
+ }
272
+ function getCatalogDefaultModel(provider) {
273
+ return getProviderCatalogEntry(provider).defaultModel;
274
+ }
275
+ function getCatalogModel(provider, modelId) {
276
+ return getProviderCatalogEntry(provider).models.find((modelEntry) => modelEntry.id === modelId);
277
+ }
278
+ function getCatalogContextWindow(provider, modelId, fallback) {
279
+ if (!modelId) return fallback;
280
+ const exact = getCatalogModel(provider, modelId);
281
+ if (exact) return exact.contextWindow;
282
+ return fallback;
283
+ }
284
+ function getCatalogModelPricingMap() {
285
+ const pricing = {};
286
+ for (const provider of Object.values(PROVIDER_CATALOG)) {
287
+ for (const modelEntry of provider.models) {
288
+ if (!modelEntry.pricing) continue;
289
+ pricing[modelEntry.id] = {
290
+ ...modelEntry.pricing,
291
+ contextWindow: modelEntry.contextWindow
292
+ };
293
+ }
294
+ }
295
+ return pricing;
296
+ }
297
+ var VERIFIED_AT, SOURCES, PROVIDER_CATALOG;
298
+ var init_catalog = __esm({
299
+ "src/providers/catalog.ts"() {
300
+ VERIFIED_AT = "2026-06-18";
301
+ SOURCES = {
302
+ openaiModels: {
303
+ name: "OpenAI models",
304
+ url: "https://developers.openai.com/api/docs/models",
305
+ verifiedAt: VERIFIED_AT
306
+ },
307
+ openaiAllModels: {
308
+ name: "OpenAI all models",
309
+ url: "https://developers.openai.com/api/docs/models/all",
310
+ verifiedAt: VERIFIED_AT
311
+ },
312
+ codexModels: {
313
+ name: "OpenAI Codex models",
314
+ url: "https://developers.openai.com/codex/models",
315
+ verifiedAt: VERIFIED_AT
316
+ },
317
+ anthropicModels: {
318
+ name: "Anthropic models overview",
319
+ url: "https://docs.anthropic.com/en/docs/about-claude/models/overview",
320
+ verifiedAt: VERIFIED_AT
321
+ },
322
+ anthropicDeprecations: {
323
+ name: "Anthropic model deprecations",
324
+ url: "https://docs.anthropic.com/en/docs/about-claude/model-deprecations",
325
+ verifiedAt: VERIFIED_AT
326
+ },
327
+ geminiModels: {
328
+ name: "Gemini API models",
329
+ url: "https://ai.google.dev/gemini-api/docs/models",
330
+ verifiedAt: VERIFIED_AT
331
+ },
332
+ geminiGuide: {
333
+ name: "Gemini 3 developer guide",
334
+ url: "https://ai.google.dev/gemini-api/docs/gemini-3",
335
+ verifiedAt: VERIFIED_AT
336
+ },
337
+ githubCopilotModels: {
338
+ name: "GitHub Copilot supported models",
339
+ url: "https://docs.github.com/copilot/reference/ai-models/supported-models",
340
+ verifiedAt: VERIFIED_AT
341
+ },
342
+ githubCopilotComparison: {
343
+ name: "GitHub Copilot model comparison",
344
+ url: "https://docs.github.com/en/copilot/reference/ai-models/model-comparison",
345
+ verifiedAt: VERIFIED_AT
346
+ },
347
+ moonshotDocs: {
348
+ name: "Moonshot AI docs",
349
+ url: "https://platform.moonshot.ai/docs",
350
+ verifiedAt: VERIFIED_AT
351
+ },
352
+ qwenDocs: {
353
+ name: "Alibaba Cloud Model Studio docs",
354
+ url: "https://www.alibabacloud.com/help/en/model-studio/",
355
+ verifiedAt: VERIFIED_AT
356
+ },
357
+ providerDocs: {
358
+ name: "Provider API documentation",
359
+ url: "https://github.com/corbat/corbat-coco/blob/main/docs/guides/PROVIDERS.md",
360
+ verifiedAt: VERIFIED_AT
361
+ }
362
+ };
363
+ PROVIDER_CATALOG = {
364
+ anthropic: {
365
+ id: "anthropic",
366
+ defaultModel: "claude-sonnet-4-6",
367
+ models: [
368
+ model({
369
+ id: "claude-opus-4-8",
370
+ name: "Claude Opus 4.8",
371
+ description: "Most capable Opus-tier model for complex agentic work",
372
+ contextWindow: 2e5,
373
+ maxOutputTokens: 128e3,
374
+ status: "current",
375
+ capabilities: [
376
+ "streaming",
377
+ "tool-use",
378
+ "vision",
379
+ "adaptive-thinking",
380
+ "reasoning-effort",
381
+ "anthropic-messages"
382
+ ],
383
+ source: SOURCES.anthropicModels
384
+ }),
385
+ model({
386
+ id: "claude-sonnet-4-6",
387
+ name: "Claude Sonnet 4.6",
388
+ description: "Balanced default for coding, tool use, and long-running tasks",
389
+ contextWindow: 2e5,
390
+ maxOutputTokens: 128e3,
391
+ recommended: true,
392
+ status: "current",
393
+ capabilities: [
394
+ "streaming",
395
+ "tool-use",
396
+ "vision",
397
+ "adaptive-thinking",
398
+ "reasoning-effort",
399
+ "anthropic-messages"
400
+ ],
401
+ pricing: { inputPerMillion: 3, outputPerMillion: 15 },
402
+ source: SOURCES.anthropicModels
403
+ }),
404
+ model({
405
+ id: "claude-opus-4-6",
406
+ name: "Claude Opus 4.6",
407
+ description: "Legacy Opus option; prefer Opus 4.8 for new configurations",
408
+ contextWindow: 2e5,
409
+ maxOutputTokens: 128e3,
410
+ status: "legacy",
411
+ capabilities: [
412
+ "streaming",
413
+ "tool-use",
414
+ "vision",
415
+ "adaptive-thinking",
416
+ "reasoning-effort",
417
+ "anthropic-messages"
418
+ ],
419
+ pricing: { inputPerMillion: 5, outputPerMillion: 25 },
420
+ source: SOURCES.anthropicModels
421
+ }),
422
+ model({
423
+ id: "claude-haiku-4-5-20251001",
424
+ name: "Claude Haiku 4.5",
425
+ description: "Fast low-cost Claude model",
426
+ contextWindow: 2e5,
427
+ maxOutputTokens: 64e3,
428
+ status: "current",
429
+ capabilities: ["streaming", "tool-use", "vision", "anthropic-messages"],
430
+ pricing: { inputPerMillion: 1, outputPerMillion: 5 },
431
+ source: SOURCES.anthropicModels
432
+ }),
433
+ model({
434
+ id: "claude-sonnet-4-20250514",
435
+ name: "Claude Sonnet 4",
436
+ description: "Retired on the Claude API; kept for config migration warnings",
437
+ contextWindow: 2e5,
438
+ maxOutputTokens: 64e3,
439
+ status: "deprecated",
440
+ capabilities: ["streaming", "tool-use", "vision", "thinking-budget", "anthropic-messages"],
441
+ pricing: { inputPerMillion: 3, outputPerMillion: 15 },
442
+ source: SOURCES.anthropicDeprecations
443
+ }),
444
+ model({
445
+ id: "claude-opus-4-20250514",
446
+ name: "Claude Opus 4",
447
+ description: "Retired on the Claude API; kept for config migration warnings",
448
+ contextWindow: 2e5,
449
+ maxOutputTokens: 64e3,
450
+ status: "deprecated",
451
+ capabilities: ["streaming", "tool-use", "vision", "thinking-budget", "anthropic-messages"],
452
+ pricing: { inputPerMillion: 15, outputPerMillion: 75 },
453
+ source: SOURCES.anthropicDeprecations
454
+ })
455
+ ]
456
+ },
457
+ openai: {
458
+ id: "openai",
459
+ defaultModel: "gpt-5.5",
460
+ models: [
461
+ model({
462
+ id: "gpt-5.5",
463
+ name: "GPT-5.5",
464
+ description: "Default for complex coding, agentic workflows, and tool-heavy tasks",
465
+ contextWindow: 1e6,
466
+ maxOutputTokens: 128e3,
467
+ recommended: true,
468
+ status: "current",
469
+ capabilities: ["streaming", "tool-use", "vision", "reasoning-effort", "openai-responses"],
470
+ pricing: { inputPerMillion: 5, outputPerMillion: 30 },
471
+ source: SOURCES.openaiModels
472
+ }),
473
+ model({
474
+ id: "gpt-5.4",
475
+ name: "GPT-5.4",
476
+ description: "Affordable model for coding and professional work",
477
+ contextWindow: 1e6,
478
+ maxOutputTokens: 128e3,
479
+ status: "current",
480
+ capabilities: ["streaming", "tool-use", "vision", "reasoning-effort", "openai-responses"],
481
+ source: SOURCES.openaiAllModels
482
+ }),
483
+ model({
484
+ id: "gpt-5.4-mini",
485
+ name: "GPT-5.4 mini",
486
+ description: "Fast model for lighter coding tasks and subagents",
487
+ contextWindow: 1e6,
488
+ maxOutputTokens: 128e3,
489
+ status: "current",
490
+ capabilities: ["streaming", "tool-use", "vision", "reasoning-effort", "openai-responses"],
491
+ source: SOURCES.openaiAllModels
492
+ }),
493
+ model({
494
+ id: "gpt-5.3-codex",
495
+ name: "GPT-5.3 Codex",
496
+ description: "Agentic coding model; keep separate from older ChatGPT-only aliases",
497
+ contextWindow: 4e5,
498
+ maxOutputTokens: 128e3,
499
+ status: "current",
500
+ capabilities: ["streaming", "tool-use", "reasoning-effort", "openai-responses"],
501
+ source: SOURCES.openaiAllModels
502
+ }),
503
+ model({
504
+ id: "gpt-5.2-codex",
505
+ name: "GPT-5.2 Codex",
506
+ description: "Deprecated Codex model retained for existing configs",
507
+ contextWindow: 4e5,
508
+ maxOutputTokens: 128e3,
509
+ status: "deprecated",
510
+ capabilities: ["streaming", "tool-use", "reasoning-effort", "openai-responses"],
511
+ source: SOURCES.openaiAllModels
512
+ }),
513
+ model({
514
+ id: "gpt-4.1",
515
+ name: "GPT-4.1",
516
+ description: "Legacy long-context non-reasoning model",
517
+ contextWindow: 1048576,
518
+ maxOutputTokens: 32768,
519
+ status: "legacy",
520
+ capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
521
+ pricing: { inputPerMillion: 2, outputPerMillion: 8 },
522
+ source: SOURCES.openaiAllModels
523
+ })
524
+ ]
525
+ },
526
+ codex: {
527
+ id: "codex",
528
+ defaultModel: "gpt-5.5",
529
+ models: [
530
+ model({
531
+ id: "gpt-5.5",
532
+ name: "GPT-5.5",
533
+ description: "Recommended Codex model for complex coding work",
534
+ contextWindow: 1e6,
535
+ maxOutputTokens: 128e3,
536
+ recommended: true,
537
+ status: "current",
538
+ capabilities: ["streaming", "tool-use", "reasoning-effort", "openai-responses"],
539
+ source: SOURCES.codexModels
540
+ }),
541
+ model({
542
+ id: "gpt-5.4-mini",
543
+ name: "GPT-5.4 mini",
544
+ description: "Faster Codex option for lighter work and subagents",
545
+ contextWindow: 1e6,
546
+ maxOutputTokens: 128e3,
547
+ status: "current",
548
+ capabilities: ["streaming", "tool-use", "reasoning-effort", "openai-responses"],
549
+ source: SOURCES.codexModels
550
+ }),
551
+ model({
552
+ id: "gpt-5.3-codex-spark",
553
+ name: "GPT-5.3 Codex Spark",
554
+ description: "Research preview for near-instant coding iteration",
555
+ contextWindow: 4e5,
556
+ maxOutputTokens: 128e3,
557
+ status: "experimental",
558
+ capabilities: ["streaming", "tool-use", "reasoning-effort", "openai-responses"],
559
+ source: SOURCES.codexModels
560
+ }),
561
+ model({
562
+ id: "codex-mini-latest",
563
+ name: "Codex mini latest",
564
+ description: "Deprecated fast Codex CLI model retained for existing configs",
565
+ contextWindow: 128e3,
566
+ maxOutputTokens: 32e3,
567
+ status: "deprecated",
568
+ capabilities: ["streaming", "tool-use", "reasoning-effort", "openai-responses"],
569
+ source: SOURCES.openaiAllModels
570
+ })
571
+ ]
572
+ },
573
+ copilot: {
574
+ id: "copilot",
575
+ defaultModel: "claude-sonnet-4.6",
576
+ models: [
577
+ model({
578
+ id: "claude-sonnet-4.6",
579
+ name: "Claude Sonnet 4.6",
580
+ description: "Reliable Copilot default for coding and review",
581
+ contextWindow: 168e3,
582
+ maxOutputTokens: 64e3,
583
+ recommended: true,
584
+ status: "current",
585
+ capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
586
+ source: SOURCES.githubCopilotComparison
587
+ }),
588
+ model({
589
+ id: "gpt-5.5",
590
+ name: "GPT-5.5",
591
+ description: "Copilot model for complex reasoning and technical decisions",
592
+ contextWindow: 1e6,
593
+ maxOutputTokens: 128e3,
594
+ status: "current",
595
+ capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
596
+ source: SOURCES.githubCopilotComparison
597
+ }),
598
+ model({
599
+ id: "gpt-5.4",
600
+ name: "GPT-5.4",
601
+ description: "Copilot coding model",
602
+ contextWindow: 1e6,
603
+ maxOutputTokens: 128e3,
604
+ status: "current",
605
+ capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
606
+ source: SOURCES.githubCopilotModels
607
+ }),
608
+ model({
609
+ id: "gpt-5.4-mini",
610
+ name: "GPT-5.4 mini",
611
+ description: "Fast Copilot model for interactive coding",
612
+ contextWindow: 1e6,
613
+ maxOutputTokens: 128e3,
614
+ status: "current",
615
+ capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
616
+ source: SOURCES.githubCopilotModels
617
+ }),
618
+ model({
619
+ id: "gpt-5.3-codex",
620
+ name: "GPT-5.3 Codex",
621
+ description: "Copilot agentic coding model",
622
+ contextWindow: 4e5,
623
+ maxOutputTokens: 128e3,
624
+ status: "current",
625
+ capabilities: ["streaming", "tool-use", "openai-chat"],
626
+ source: SOURCES.githubCopilotModels
627
+ }),
628
+ model({
629
+ id: "claude-opus-4.8",
630
+ name: "Claude Opus 4.8",
631
+ description: "Most capable Anthropic model exposed by Copilot when available",
632
+ contextWindow: 168e3,
633
+ maxOutputTokens: 64e3,
634
+ status: "current",
635
+ capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
636
+ source: SOURCES.githubCopilotModels
637
+ }),
638
+ model({
639
+ id: "gemini-3.1-pro",
640
+ name: "Gemini 3.1 Pro",
641
+ description: "Gemini model exposed by Copilot",
642
+ contextWindow: 1e6,
643
+ maxOutputTokens: 64e3,
644
+ status: "current",
645
+ capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
646
+ source: SOURCES.githubCopilotModels
647
+ }),
648
+ model({
649
+ id: "gemini-3.5-flash",
650
+ name: "Gemini 3.5 Flash",
651
+ description: "Fast Gemini model exposed by Copilot",
652
+ contextWindow: 1e6,
653
+ maxOutputTokens: 64e3,
654
+ status: "current",
655
+ capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
656
+ source: SOURCES.githubCopilotModels
657
+ })
658
+ ]
659
+ },
660
+ gemini: {
661
+ id: "gemini",
662
+ defaultModel: "gemini-3.1-pro-preview",
663
+ models: [
664
+ model({
665
+ id: "gemini-3.1-pro-preview",
666
+ name: "Gemini 3.1 Pro Preview",
667
+ description: "Most capable Gemini 3 model for agentic and coding workflows",
668
+ contextWindow: 1e6,
669
+ maxOutputTokens: 64e3,
670
+ recommended: true,
671
+ status: "experimental",
672
+ capabilities: [
673
+ "streaming",
674
+ "tool-use",
675
+ "vision",
676
+ "thinking-budget",
677
+ "gemini-generate-content"
678
+ ],
679
+ source: SOURCES.geminiGuide
680
+ }),
681
+ model({
682
+ id: "gemini-3-flash-preview",
683
+ name: "Gemini 3 Flash Preview",
684
+ description: "Fast Gemini 3 preview model",
685
+ contextWindow: 1e6,
686
+ maxOutputTokens: 64e3,
687
+ status: "experimental",
688
+ capabilities: [
689
+ "streaming",
690
+ "tool-use",
691
+ "vision",
692
+ "thinking-budget",
693
+ "gemini-generate-content"
694
+ ],
695
+ source: SOURCES.geminiGuide
696
+ }),
697
+ model({
698
+ id: "gemini-2.5-pro",
699
+ name: "Gemini 2.5 Pro",
700
+ description: "Stable Gemini Pro model",
701
+ contextWindow: 1048576,
702
+ maxOutputTokens: 65536,
703
+ status: "current",
704
+ capabilities: [
705
+ "streaming",
706
+ "tool-use",
707
+ "vision",
708
+ "thinking-budget",
709
+ "gemini-generate-content"
710
+ ],
711
+ source: SOURCES.geminiModels
712
+ }),
713
+ model({
714
+ id: "gemini-2.5-flash",
715
+ name: "Gemini 2.5 Flash",
716
+ description: "Stable fast Gemini model",
717
+ contextWindow: 1048576,
718
+ maxOutputTokens: 65536,
719
+ status: "current",
720
+ capabilities: [
721
+ "streaming",
722
+ "tool-use",
723
+ "vision",
724
+ "thinking-budget",
725
+ "gemini-generate-content"
726
+ ],
727
+ source: SOURCES.geminiModels
728
+ }),
729
+ model({
730
+ id: "gemini-2.5-flash-lite",
731
+ name: "Gemini 2.5 Flash-Lite",
732
+ description: "Lowest-cost stable Gemini option",
733
+ contextWindow: 1048576,
734
+ maxOutputTokens: 65536,
735
+ status: "current",
736
+ capabilities: [
737
+ "streaming",
738
+ "tool-use",
739
+ "vision",
740
+ "thinking-budget",
741
+ "gemini-generate-content"
742
+ ],
743
+ source: SOURCES.geminiModels
744
+ })
745
+ ]
746
+ },
747
+ vertex: {
748
+ id: "vertex",
749
+ defaultModel: "gemini-2.5-pro",
750
+ models: [
751
+ model({
752
+ id: "gemini-2.5-pro",
753
+ name: "Gemini 2.5 Pro",
754
+ description: "Stable Vertex model for coding and complex reasoning",
755
+ contextWindow: 1048576,
756
+ maxOutputTokens: 65536,
757
+ recommended: true,
758
+ status: "current",
759
+ capabilities: [
760
+ "streaming",
761
+ "tool-use",
762
+ "vision",
763
+ "thinking-budget",
764
+ "gemini-generate-content"
765
+ ],
766
+ source: SOURCES.geminiModels
767
+ }),
768
+ model({
769
+ id: "gemini-3-pro-preview",
770
+ name: "Gemini 3 Pro Preview",
771
+ description: "Preview Vertex Gemini 3 model",
772
+ contextWindow: 1048576,
773
+ maxOutputTokens: 65536,
774
+ status: "experimental",
775
+ capabilities: [
776
+ "streaming",
777
+ "tool-use",
778
+ "vision",
779
+ "thinking-budget",
780
+ "gemini-generate-content"
781
+ ],
782
+ source: SOURCES.geminiGuide
783
+ }),
784
+ model({
785
+ id: "gemini-3-flash-preview",
786
+ name: "Gemini 3 Flash Preview",
787
+ description: "Fast preview Vertex Gemini 3 model",
788
+ contextWindow: 1048576,
789
+ maxOutputTokens: 65536,
790
+ status: "experimental",
791
+ capabilities: [
792
+ "streaming",
793
+ "tool-use",
794
+ "vision",
795
+ "thinking-budget",
796
+ "gemini-generate-content"
797
+ ],
798
+ source: SOURCES.geminiGuide
799
+ }),
800
+ model({
801
+ id: "gemini-2.5-flash",
802
+ name: "Gemini 2.5 Flash",
803
+ description: "Fast stable Vertex Gemini model",
804
+ contextWindow: 1048576,
805
+ maxOutputTokens: 65536,
806
+ status: "current",
807
+ capabilities: [
808
+ "streaming",
809
+ "tool-use",
810
+ "vision",
811
+ "thinking-budget",
812
+ "gemini-generate-content"
813
+ ],
814
+ source: SOURCES.geminiModels
815
+ })
816
+ ]
817
+ },
818
+ kimi: {
819
+ id: "kimi",
820
+ defaultModel: "kimi-k2.5",
821
+ models: [
822
+ model({
823
+ id: "kimi-k2.5",
824
+ name: "Kimi K2.5",
825
+ description: "Moonshot model for coding and agentic work",
826
+ contextWindow: 262144,
827
+ maxOutputTokens: 32e3,
828
+ recommended: true,
829
+ status: "current",
830
+ capabilities: ["streaming", "tool-use", "openai-chat"],
831
+ source: SOURCES.moonshotDocs
832
+ }),
833
+ model({
834
+ id: "kimi-k2-thinking",
835
+ name: "Kimi K2 Thinking",
836
+ description: "Reasoning variant",
837
+ contextWindow: 262144,
838
+ maxOutputTokens: 32e3,
839
+ status: "current",
840
+ capabilities: ["streaming", "tool-use", "openai-chat"],
841
+ source: SOURCES.moonshotDocs
842
+ }),
843
+ model({
844
+ id: "moonshot-v1-128k",
845
+ name: "Moonshot v1 128K",
846
+ description: "Legacy long-context Moonshot model",
847
+ contextWindow: 131072,
848
+ maxOutputTokens: 8192,
849
+ status: "legacy",
850
+ capabilities: ["streaming", "tool-use", "openai-chat"],
851
+ pricing: { inputPerMillion: 6, outputPerMillion: 6 },
852
+ source: SOURCES.moonshotDocs
853
+ })
854
+ ]
855
+ },
856
+ "kimi-code": {
857
+ id: "kimi-code",
858
+ defaultModel: "kimi-for-coding",
859
+ models: [
860
+ model({
861
+ id: "kimi-for-coding",
862
+ name: "Kimi for Coding",
863
+ description: "Anthropic-compatible Kimi coding endpoint",
864
+ contextWindow: 131072,
865
+ maxOutputTokens: 32e3,
866
+ recommended: true,
867
+ status: "current",
868
+ capabilities: ["streaming", "tool-use", "anthropic-messages"],
869
+ source: SOURCES.moonshotDocs
870
+ })
871
+ ]
872
+ },
873
+ lmstudio: {
874
+ id: "lmstudio",
875
+ defaultModel: "local-model",
876
+ models: [
877
+ model({
878
+ id: "local-model",
879
+ name: "Local model",
880
+ description: "Model selected in LM Studio",
881
+ contextWindow: 32768,
882
+ maxOutputTokens: 8192,
883
+ recommended: true,
884
+ status: "current",
885
+ capabilities: ["streaming", "tool-use", "openai-chat"]
886
+ })
887
+ ]
888
+ },
889
+ ollama: {
890
+ id: "ollama",
891
+ defaultModel: "llama3.2",
892
+ models: [
893
+ model({
894
+ id: "llama3.2",
895
+ name: "Llama 3.2",
896
+ description: "Default local Ollama model",
897
+ contextWindow: 128e3,
898
+ maxOutputTokens: 8192,
899
+ recommended: true,
900
+ status: "current",
901
+ capabilities: ["streaming", "tool-use", "openai-chat"]
902
+ }),
903
+ model({
904
+ id: "qwen2.5-coder:14b",
905
+ name: "Qwen2.5 Coder 14B",
906
+ description: "Local coding model",
907
+ contextWindow: 32768,
908
+ maxOutputTokens: 8192,
909
+ status: "legacy",
910
+ capabilities: ["streaming", "tool-use", "openai-chat"]
911
+ })
912
+ ]
913
+ },
914
+ groq: {
915
+ id: "groq",
916
+ defaultModel: "llama-3.3-70b-versatile",
917
+ models: [
918
+ model({
919
+ id: "llama-3.3-70b-versatile",
920
+ name: "Llama 3.3 70B Versatile",
921
+ contextWindow: 128e3,
922
+ maxOutputTokens: 8192,
923
+ recommended: true,
924
+ status: "current",
925
+ capabilities: ["streaming", "tool-use", "openai-chat"]
926
+ })
927
+ ]
928
+ },
929
+ openrouter: {
930
+ id: "openrouter",
931
+ defaultModel: "anthropic/claude-sonnet-4.6",
932
+ models: [
933
+ model({
934
+ id: "anthropic/claude-sonnet-4.6",
935
+ name: "Claude Sonnet 4.6 via OpenRouter",
936
+ contextWindow: 2e5,
937
+ maxOutputTokens: 64e3,
938
+ recommended: true,
939
+ status: "current",
940
+ capabilities: ["streaming", "tool-use", "vision", "openai-chat"]
941
+ })
942
+ ]
943
+ },
944
+ mistral: {
945
+ id: "mistral",
946
+ defaultModel: "mistral-large-latest",
947
+ models: [
948
+ model({
949
+ id: "mistral-large-latest",
950
+ name: "Mistral Large latest",
951
+ contextWindow: 131072,
952
+ maxOutputTokens: 8192,
953
+ recommended: true,
954
+ status: "current",
955
+ capabilities: ["streaming", "tool-use", "openai-chat"]
956
+ }),
957
+ model({
958
+ id: "codestral-latest",
959
+ name: "Codestral latest",
960
+ contextWindow: 32768,
961
+ maxOutputTokens: 8192,
962
+ status: "current",
963
+ capabilities: ["streaming", "tool-use", "openai-chat"]
964
+ })
965
+ ]
966
+ },
967
+ deepseek: {
968
+ id: "deepseek",
969
+ defaultModel: "deepseek-chat",
970
+ models: [
971
+ model({
972
+ id: "deepseek-chat",
973
+ name: "DeepSeek Chat",
974
+ contextWindow: 65536,
975
+ maxOutputTokens: 8192,
976
+ recommended: true,
977
+ status: "current",
978
+ capabilities: ["streaming", "tool-use", "openai-chat"]
979
+ }),
980
+ model({
981
+ id: "deepseek-reasoner",
982
+ name: "DeepSeek Reasoner",
983
+ contextWindow: 65536,
984
+ maxOutputTokens: 8192,
985
+ status: "current",
986
+ capabilities: ["streaming", "tool-use", "openai-chat"]
987
+ })
988
+ ]
989
+ },
990
+ together: {
991
+ id: "together",
992
+ defaultModel: "meta-llama/Llama-3.3-70B-Instruct-Turbo",
993
+ models: [
994
+ model({
995
+ id: "meta-llama/Llama-3.3-70B-Instruct-Turbo",
996
+ name: "Llama 3.3 70B Instruct Turbo",
997
+ contextWindow: 128e3,
998
+ maxOutputTokens: 8192,
999
+ recommended: true,
1000
+ status: "current",
1001
+ capabilities: ["streaming", "tool-use", "openai-chat"]
1002
+ })
1003
+ ]
1004
+ },
1005
+ huggingface: {
1006
+ id: "huggingface",
1007
+ defaultModel: "meta-llama/Llama-3.1-70B-Instruct",
1008
+ models: [
1009
+ model({
1010
+ id: "meta-llama/Llama-3.1-70B-Instruct",
1011
+ name: "Llama 3.1 70B Instruct",
1012
+ contextWindow: 128e3,
1013
+ maxOutputTokens: 8192,
1014
+ recommended: true,
1015
+ status: "legacy",
1016
+ capabilities: ["streaming", "openai-chat"]
1017
+ })
1018
+ ]
1019
+ },
1020
+ qwen: {
1021
+ id: "qwen",
1022
+ defaultModel: "qwen-coder-plus",
1023
+ models: [
1024
+ model({
1025
+ id: "qwen-coder-plus",
1026
+ name: "Qwen Coder Plus",
1027
+ contextWindow: 131072,
1028
+ maxOutputTokens: 8192,
1029
+ recommended: true,
1030
+ status: "current",
1031
+ capabilities: ["streaming", "tool-use", "openai-chat"],
1032
+ source: SOURCES.qwenDocs
1033
+ }),
1034
+ model({
1035
+ id: "qwen-max",
1036
+ name: "Qwen Max",
1037
+ contextWindow: 131072,
1038
+ maxOutputTokens: 8192,
1039
+ status: "current",
1040
+ capabilities: ["streaming", "tool-use", "openai-chat"],
1041
+ source: SOURCES.qwenDocs
1042
+ })
1043
+ ]
1044
+ }
1045
+ };
1046
+ }
1047
+ });
256
1048
  async function refreshAccessToken(provider, refreshToken) {
257
1049
  const config = OAUTH_CONFIGS[provider];
258
1050
  if (!config) {
@@ -939,6 +1731,7 @@ var init_copilot = __esm({
939
1731
  this.permanent = permanent;
940
1732
  this.name = "CopilotAuthError";
941
1733
  }
1734
+ permanent;
942
1735
  };
943
1736
  CopilotCredentialsSchema = z.object({
944
1737
  githubToken: z.string().min(1),
@@ -1514,8 +2307,8 @@ async function configExists(configPath, scope = "any") {
1514
2307
  }
1515
2308
  return false;
1516
2309
  }
1517
- function getConfigValue(config, path42) {
1518
- const keys = path42.split(".");
2310
+ function getConfigValue(config, path44) {
2311
+ const keys = path44.split(".");
1519
2312
  let current = config;
1520
2313
  for (const key of keys) {
1521
2314
  if (current === null || current === void 0 || typeof current !== "object") {
@@ -1663,41 +2456,41 @@ function getBaseUrl(provider) {
1663
2456
  function getDefaultModel(provider) {
1664
2457
  switch (provider) {
1665
2458
  case "anthropic":
1666
- return process.env["ANTHROPIC_MODEL"] ?? "claude-opus-4-6";
2459
+ return process.env["ANTHROPIC_MODEL"] ?? getCatalogDefaultModel(provider);
1667
2460
  case "openai":
1668
- return process.env["OPENAI_MODEL"] ?? "gpt-5.3-codex";
2461
+ return process.env["OPENAI_MODEL"] ?? getCatalogDefaultModel(provider);
1669
2462
  case "gemini":
1670
- return process.env["GEMINI_MODEL"] ?? "gemini-3.1-pro-preview";
2463
+ return process.env["GEMINI_MODEL"] ?? getCatalogDefaultModel(provider);
1671
2464
  case "vertex":
1672
- return process.env["VERTEX_MODEL"] ?? "gemini-2.5-pro";
2465
+ return process.env["VERTEX_MODEL"] ?? getCatalogDefaultModel(provider);
1673
2466
  case "kimi":
1674
- return process.env["KIMI_MODEL"] ?? "kimi-k2.5";
2467
+ return process.env["KIMI_MODEL"] ?? getCatalogDefaultModel(provider);
1675
2468
  case "kimi-code":
1676
- return process.env["KIMI_CODE_MODEL"] ?? "kimi-for-coding";
2469
+ return process.env["KIMI_CODE_MODEL"] ?? getCatalogDefaultModel(provider);
1677
2470
  case "lmstudio":
1678
- return process.env["LMSTUDIO_MODEL"] ?? "local-model";
2471
+ return process.env["LMSTUDIO_MODEL"] ?? getCatalogDefaultModel(provider);
1679
2472
  case "ollama":
1680
- return process.env["OLLAMA_MODEL"] ?? "llama3.2";
2473
+ return process.env["OLLAMA_MODEL"] ?? getCatalogDefaultModel(provider);
1681
2474
  case "codex":
1682
- return process.env["CODEX_MODEL"] ?? "codex-mini-latest";
2475
+ return process.env["CODEX_MODEL"] ?? getCatalogDefaultModel(provider);
1683
2476
  case "copilot":
1684
- return process.env["COPILOT_MODEL"] ?? "claude-sonnet-4.6";
2477
+ return process.env["COPILOT_MODEL"] ?? getCatalogDefaultModel(provider);
1685
2478
  case "groq":
1686
- return process.env["GROQ_MODEL"] ?? "llama-3.3-70b-versatile";
2479
+ return process.env["GROQ_MODEL"] ?? getCatalogDefaultModel(provider);
1687
2480
  case "openrouter":
1688
- return process.env["OPENROUTER_MODEL"] ?? "anthropic/claude-3.5-sonnet";
2481
+ return process.env["OPENROUTER_MODEL"] ?? getCatalogDefaultModel(provider);
1689
2482
  case "mistral":
1690
- return process.env["MISTRAL_MODEL"] ?? "mistral-large-latest";
2483
+ return process.env["MISTRAL_MODEL"] ?? getCatalogDefaultModel(provider);
1691
2484
  case "deepseek":
1692
- return process.env["DEEPSEEK_MODEL"] ?? "deepseek-chat";
2485
+ return process.env["DEEPSEEK_MODEL"] ?? getCatalogDefaultModel(provider);
1693
2486
  case "together":
1694
- return process.env["TOGETHER_MODEL"] ?? "meta-llama/Llama-3.3-70B-Instruct-Turbo";
2487
+ return process.env["TOGETHER_MODEL"] ?? getCatalogDefaultModel(provider);
1695
2488
  case "huggingface":
1696
- return process.env["HF_MODEL"] ?? "meta-llama/Llama-3.1-70B-Instruct";
2489
+ return process.env["HF_MODEL"] ?? getCatalogDefaultModel(provider);
1697
2490
  case "qwen":
1698
- return process.env["QWEN_MODEL"] ?? "qwen-max";
2491
+ return process.env["QWEN_MODEL"] ?? getCatalogDefaultModel(provider);
1699
2492
  default:
1700
- return "claude-sonnet-4-6";
2493
+ return getCatalogDefaultModel("anthropic");
1701
2494
  }
1702
2495
  }
1703
2496
  function getDefaultProvider() {
@@ -1724,6 +2517,7 @@ var init_env = __esm({
1724
2517
  "src/config/env.ts"() {
1725
2518
  init_loader();
1726
2519
  init_paths();
2520
+ init_catalog();
1727
2521
  loadGlobalCocoEnv();
1728
2522
  VALID_PROVIDERS = [
1729
2523
  "anthropic",
@@ -2060,9 +2854,9 @@ async function migrateGlobalConfig(oldDir, newConfigPath) {
2060
2854
  );
2061
2855
  }
2062
2856
  }
2063
- async function fileExists3(path42) {
2857
+ async function fileExists3(path44) {
2064
2858
  try {
2065
- await access(path42);
2859
+ await access(path44);
2066
2860
  return true;
2067
2861
  } catch {
2068
2862
  return false;
@@ -3095,10 +3889,10 @@ function inferTargetUsers(session) {
3095
3889
  /(?:for|by)\s+(developers?|users?|administrators?|customers?)/gi,
3096
3890
  /(developers?|users?|administrators?|customers?)\s+(?:can|will|should)/gi
3097
3891
  ];
3098
- const text = session.requirements.map((r) => r.description).join(" ");
3892
+ const text2 = session.requirements.map((r) => r.description).join(" ");
3099
3893
  for (const pattern of userPatterns) {
3100
3894
  let match;
3101
- while ((match = pattern.exec(text)) !== null) {
3895
+ while ((match = pattern.exec(text2)) !== null) {
3102
3896
  const user = match[1]?.toLowerCase();
3103
3897
  if (user && !users.includes(user)) {
3104
3898
  users.push(user);
@@ -3111,13 +3905,13 @@ function inferTargetUsers(session) {
3111
3905
  return users;
3112
3906
  }
3113
3907
  function inferProjectType(session) {
3114
- const text = session.initialInput.toLowerCase();
3115
- if (text.includes("cli") || text.includes("command line")) return "cli";
3116
- if (text.includes("api") || text.includes("rest") || text.includes("graphql")) return "api";
3117
- if (text.includes("web app") || text.includes("frontend")) return "web_app";
3118
- if (text.includes("library") || text.includes("package")) return "library";
3119
- if (text.includes("service") || text.includes("daemon")) return "service";
3120
- if (text.includes("full stack") || text.includes("fullstack")) return "full_stack";
3908
+ const text2 = session.initialInput.toLowerCase();
3909
+ if (text2.includes("cli") || text2.includes("command line")) return "cli";
3910
+ if (text2.includes("api") || text2.includes("rest") || text2.includes("graphql")) return "api";
3911
+ if (text2.includes("web app") || text2.includes("frontend")) return "web_app";
3912
+ if (text2.includes("library") || text2.includes("package")) return "library";
3913
+ if (text2.includes("service") || text2.includes("daemon")) return "service";
3914
+ if (text2.includes("full stack") || text2.includes("fullstack")) return "full_stack";
3121
3915
  return "unknown";
3122
3916
  }
3123
3917
  function assessComplexity(session) {
@@ -4663,14 +5457,14 @@ function generateArchitectureMarkdown(doc) {
4663
5457
  if (doc.dataModels.length > 0) {
4664
5458
  sections.push("## Data Models");
4665
5459
  sections.push("");
4666
- for (const model of doc.dataModels) {
4667
- sections.push(`### ${model.name}`);
5460
+ for (const model2 of doc.dataModels) {
5461
+ sections.push(`### ${model2.name}`);
4668
5462
  sections.push("");
4669
- sections.push(model.description);
5463
+ sections.push(model2.description);
4670
5464
  sections.push("");
4671
5465
  sections.push("| Field | Type | Required |");
4672
5466
  sections.push("|-------|------|----------|");
4673
- for (const field of model.fields) {
5467
+ for (const field of model2.fields) {
4674
5468
  sections.push(`| ${field.name} | ${field.type} | ${field.required ? "Yes" : "No"} |`);
4675
5469
  }
4676
5470
  sections.push("");
@@ -5894,6 +6688,7 @@ var CoverageAnalyzer = class {
5894
6688
  constructor(projectPath) {
5895
6689
  this.projectPath = projectPath;
5896
6690
  }
6691
+ projectPath;
5897
6692
  /**
5898
6693
  * Analyze coverage by running tests with coverage enabled
5899
6694
  */
@@ -6236,6 +7031,7 @@ var SnykSecurityScanner = class {
6236
7031
  constructor(projectPath) {
6237
7032
  this.projectPath = projectPath;
6238
7033
  }
7034
+ projectPath;
6239
7035
  /**
6240
7036
  * Scan project with Snyk (requires authentication)
6241
7037
  */
@@ -6447,6 +7243,8 @@ var ComplexityAnalyzer = class {
6447
7243
  this.projectPath = projectPath;
6448
7244
  this.threshold = threshold;
6449
7245
  }
7246
+ projectPath;
7247
+ threshold;
6450
7248
  /**
6451
7249
  * Analyze complexity of project files
6452
7250
  */
@@ -6532,6 +7330,8 @@ var DuplicationAnalyzer = class {
6532
7330
  this.projectPath = projectPath;
6533
7331
  this.minLines = minLines;
6534
7332
  }
7333
+ projectPath;
7334
+ minLines;
6535
7335
  /**
6536
7336
  * Detect code duplication
6537
7337
  */
@@ -6900,6 +7700,7 @@ var CorrectnessAnalyzer = class {
6900
7700
  this.projectPath = projectPath;
6901
7701
  this.buildVerifier = new BuildVerifier(projectPath);
6902
7702
  }
7703
+ projectPath;
6903
7704
  buildVerifier;
6904
7705
  /**
6905
7706
  * Analyze correctness by running tests and verifying build
@@ -7032,6 +7833,7 @@ var CompletenessAnalyzer = class {
7032
7833
  constructor(projectPath) {
7033
7834
  this.projectPath = projectPath;
7034
7835
  }
7836
+ projectPath;
7035
7837
  /**
7036
7838
  * Analyze project completeness
7037
7839
  */
@@ -7265,6 +8067,7 @@ var RobustnessAnalyzer = class {
7265
8067
  constructor(projectPath) {
7266
8068
  this.projectPath = projectPath;
7267
8069
  }
8070
+ projectPath;
7268
8071
  /**
7269
8072
  * Analyze robustness of project files
7270
8073
  */
@@ -7422,6 +8225,7 @@ var TestQualityAnalyzer = class {
7422
8225
  constructor(projectPath) {
7423
8226
  this.projectPath = projectPath;
7424
8227
  }
8228
+ projectPath;
7425
8229
  /**
7426
8230
  * Analyze test quality across the project
7427
8231
  */
@@ -7551,6 +8355,7 @@ var DocumentationAnalyzer = class {
7551
8355
  constructor(projectPath) {
7552
8356
  this.projectPath = projectPath;
7553
8357
  }
8358
+ projectPath;
7554
8359
  /**
7555
8360
  * Analyze documentation quality
7556
8361
  */
@@ -7705,6 +8510,7 @@ var StyleAnalyzer = class {
7705
8510
  constructor(projectPath) {
7706
8511
  this.projectPath = projectPath;
7707
8512
  }
8513
+ projectPath;
7708
8514
  /**
7709
8515
  * Analyze style/linting quality
7710
8516
  */
@@ -7914,6 +8720,7 @@ var ReadabilityAnalyzer = class {
7914
8720
  constructor(projectPath) {
7915
8721
  this.projectPath = projectPath;
7916
8722
  }
8723
+ projectPath;
7917
8724
  /**
7918
8725
  * Analyze readability of project files
7919
8726
  */
@@ -8051,6 +8858,7 @@ var MaintainabilityAnalyzer = class {
8051
8858
  constructor(projectPath) {
8052
8859
  this.projectPath = projectPath;
8053
8860
  }
8861
+ projectPath;
8054
8862
  /**
8055
8863
  * Analyze maintainability of project files
8056
8864
  */
@@ -8418,6 +9226,7 @@ var JavaComplexityAnalyzer = class {
8418
9226
  constructor(projectPath) {
8419
9227
  this.projectPath = projectPath;
8420
9228
  }
9229
+ projectPath;
8421
9230
  async analyze(files) {
8422
9231
  const javaFiles = files ?? await findJavaFiles(this.projectPath);
8423
9232
  if (!javaFiles.length) {
@@ -8557,6 +9366,7 @@ var JavaSecurityAnalyzer = class {
8557
9366
  constructor(projectPath) {
8558
9367
  this.projectPath = projectPath;
8559
9368
  }
9369
+ projectPath;
8560
9370
  async analyze(files) {
8561
9371
  const javaFiles = files ?? await findJavaFiles(this.projectPath, { includeTests: false });
8562
9372
  if (!javaFiles.length) {
@@ -8621,6 +9431,7 @@ var JavaStyleAnalyzer = class {
8621
9431
  constructor(projectPath) {
8622
9432
  this.projectPath = projectPath;
8623
9433
  }
9434
+ projectPath;
8624
9435
  async analyze(files) {
8625
9436
  const javaFiles = files ?? await findJavaFiles(this.projectPath);
8626
9437
  if (!javaFiles.length) return { score: 100, violations: [] };
@@ -8719,6 +9530,7 @@ var JavaDocumentationAnalyzer = class {
8719
9530
  constructor(projectPath) {
8720
9531
  this.projectPath = projectPath;
8721
9532
  }
9533
+ projectPath;
8722
9534
  async analyze(files) {
8723
9535
  const javaFiles = files ?? await findJavaFiles(this.projectPath, { srcPattern: "src/main/**/*.java" });
8724
9536
  if (!javaFiles.length) {
@@ -8796,6 +9608,7 @@ var JavaCoverageAnalyzer = class {
8796
9608
  constructor(projectPath) {
8797
9609
  this.projectPath = projectPath;
8798
9610
  }
9611
+ projectPath;
8799
9612
  async analyze() {
8800
9613
  for (const reportPath of JACOCO_REPORT_PATHS) {
8801
9614
  try {
@@ -8927,6 +9740,7 @@ var ReactComponentAnalyzer = class {
8927
9740
  constructor(projectPath) {
8928
9741
  this.projectPath = projectPath;
8929
9742
  }
9743
+ projectPath;
8930
9744
  async analyze(files) {
8931
9745
  const reactFiles = files ?? await findReactFiles(this.projectPath);
8932
9746
  if (!reactFiles.length) return { score: 100, totalComponents: 0, issues: [] };
@@ -9026,6 +9840,7 @@ var ReactA11yAnalyzer = class {
9026
9840
  constructor(projectPath) {
9027
9841
  this.projectPath = projectPath;
9028
9842
  }
9843
+ projectPath;
9029
9844
  async analyze(files) {
9030
9845
  const reactFiles = files ?? await findReactFiles(this.projectPath);
9031
9846
  if (!reactFiles.length) return { score: 100, violations: [] };
@@ -9118,6 +9933,7 @@ var ReactHookAnalyzer = class {
9118
9933
  constructor(projectPath) {
9119
9934
  this.projectPath = projectPath;
9120
9935
  }
9936
+ projectPath;
9121
9937
  async analyze(files) {
9122
9938
  const reactFiles = files ?? await findReactFiles(this.projectPath, "**/*.{tsx,jsx,ts,js}");
9123
9939
  if (!reactFiles.length) return { score: 100, violations: [] };
@@ -9531,6 +10347,8 @@ var QualityEvaluator = class {
9531
10347
  this.readabilityAnalyzer = new ReadabilityAnalyzer(projectPath);
9532
10348
  this.maintainabilityAnalyzer = new MaintainabilityAnalyzer(projectPath);
9533
10349
  }
10350
+ projectPath;
10351
+ registry;
9534
10352
  coverageAnalyzer;
9535
10353
  securityScanner;
9536
10354
  complexityAnalyzer;
@@ -10148,12 +10966,12 @@ function humanizeError(message, toolName) {
10148
10966
  return msg;
10149
10967
  }
10150
10968
  if (/ENOENT/i.test(msg)) {
10151
- const path42 = extractQuotedPath(msg);
10152
- return path42 ? `File or directory not found: ${path42}` : "File or directory not found";
10969
+ const path44 = extractQuotedPath(msg);
10970
+ return path44 ? `File or directory not found: ${path44}` : "File or directory not found";
10153
10971
  }
10154
10972
  if (/EACCES/i.test(msg)) {
10155
- const path42 = extractQuotedPath(msg);
10156
- return path42 ? `Permission denied: ${path42}` : "Permission denied \u2014 check file permissions";
10973
+ const path44 = extractQuotedPath(msg);
10974
+ return path44 ? `Permission denied: ${path44}` : "Permission denied \u2014 check file permissions";
10157
10975
  }
10158
10976
  if (/EISDIR/i.test(msg)) {
10159
10977
  return "Expected a file but found a directory at the specified path";
@@ -11561,8 +12379,8 @@ function createLLMAdapter2(context) {
11561
12379
  type: "done"
11562
12380
  };
11563
12381
  },
11564
- countTokens(text) {
11565
- return Math.ceil(text.length / 4);
12382
+ countTokens(text2) {
12383
+ return Math.ceil(text2.length / 4);
11566
12384
  },
11567
12385
  getContextWindow() {
11568
12386
  return 2e5;
@@ -13630,30 +14448,110 @@ var GEMINI_BUDGET = {
13630
14448
  medium: 8e3,
13631
14449
  high: 16e3
13632
14450
  };
13633
- function isAnthropicThinkingModel(model) {
13634
- const m = model.toLowerCase();
14451
+ function isAnthropicThinkingModel(model2) {
14452
+ const m = model2.toLowerCase();
13635
14453
  if (m === "kimi-for-coding") return false;
13636
14454
  return m.includes("claude-3-7") || m.includes("claude-opus-4") || m.includes("claude-sonnet-4") || m.includes("claude-haiku-4-5") || m.includes("claude-4");
13637
14455
  }
13638
- function isOpenAIReasoningModel(model) {
13639
- const m = model.toLowerCase();
14456
+ function isAnthropicAdaptiveThinkingModel(model2) {
14457
+ const m = model2.toLowerCase();
14458
+ return m.includes("claude-opus-4-8") || m.includes("claude-opus-4-7") || m.includes("claude-opus-4-6") || m.includes("claude-sonnet-4-6");
14459
+ }
14460
+ function isOpenAIReasoningModel(model2) {
14461
+ const m = model2.toLowerCase();
13640
14462
  return m.startsWith("o1") || m.startsWith("o3") || m.startsWith("o4") || m.startsWith("gpt-5") || m.includes("codex");
13641
14463
  }
13642
- function isGeminiThinkingModel(model) {
13643
- const m = model.toLowerCase();
13644
- return m.includes("gemini-2.5-pro") || m.includes("gemini-2.5-flash") || m.includes("gemini-3") && !m.includes("flash-lite") || m.includes("gemini-2.0-flash-thinking");
14464
+ function isGeminiThinkingModel(model2) {
14465
+ const m = model2.toLowerCase();
14466
+ return m.includes("gemini-2.5-pro") || m.includes("gemini-2.5-flash") || m.includes("gemini-3") || m.includes("gemini-2.0-flash-thinking");
13645
14467
  }
13646
- function isKimiThinkingModel(model) {
13647
- const m = model.toLowerCase();
14468
+ function isGeminiLevelThinkingModel(model2) {
14469
+ return model2.toLowerCase().includes("gemini-3");
14470
+ }
14471
+ function isKimiThinkingModel(model2) {
14472
+ const m = model2.toLowerCase();
13648
14473
  return m.includes("kimi-k2") || m === "kimi-latest";
13649
14474
  }
14475
+ var UNSUPPORTED = {
14476
+ supported: false,
14477
+ kinds: [],
14478
+ levels: ["off"],
14479
+ defaultMode: "off"
14480
+ };
13650
14481
  var ANTHROPIC_CAPABILITY = {
13651
- budgetRange: { min: 1024, max: 64e3, default: ANTHROPIC_BUDGET.medium }};
14482
+ supported: true,
14483
+ kinds: ["budget"],
14484
+ levels: ["off", "auto", "low", "medium", "high"],
14485
+ budgetRange: { min: 1024, max: 64e3, default: ANTHROPIC_BUDGET.medium },
14486
+ defaultMode: "off"
14487
+ };
14488
+ var ANTHROPIC_ADAPTIVE_CAPABILITY = {
14489
+ supported: true,
14490
+ kinds: ["effort"],
14491
+ levels: ["off", "auto", "low", "medium", "high"],
14492
+ defaultMode: "off"
14493
+ };
14494
+ var OPENAI_CAPABILITY = {
14495
+ supported: true,
14496
+ kinds: ["effort"],
14497
+ levels: ["off", "auto", "low", "medium", "high"],
14498
+ defaultMode: "medium"
14499
+ };
13652
14500
  var GEMINI_CAPABILITY = {
13653
- budgetRange: { min: 0, max: 32e3}};
13654
- function mapToAnthropic(mode, model) {
14501
+ supported: true,
14502
+ kinds: ["budget"],
14503
+ levels: ["off", "auto", "low", "medium", "high"],
14504
+ budgetRange: { min: 0, max: 32e3, default: GEMINI_BUDGET.medium },
14505
+ defaultMode: "auto"
14506
+ };
14507
+ var GEMINI_LEVEL_CAPABILITY = {
14508
+ supported: true,
14509
+ kinds: ["effort"],
14510
+ levels: ["auto", "low", "medium", "high"],
14511
+ defaultMode: "auto"
14512
+ };
14513
+ var KIMI_CAPABILITY = {
14514
+ supported: true,
14515
+ kinds: ["effort"],
14516
+ levels: ["off", "auto"],
14517
+ defaultMode: "off"
14518
+ };
14519
+ function getThinkingCapability(provider, model2) {
14520
+ switch (provider) {
14521
+ case "anthropic":
14522
+ case "kimi-code":
14523
+ if (isAnthropicAdaptiveThinkingModel(model2)) return ANTHROPIC_ADAPTIVE_CAPABILITY;
14524
+ return isAnthropicThinkingModel(model2) ? ANTHROPIC_CAPABILITY : UNSUPPORTED;
14525
+ case "openai":
14526
+ return isOpenAIReasoningModel(model2) ? OPENAI_CAPABILITY : UNSUPPORTED;
14527
+ case "kimi":
14528
+ return isKimiThinkingModel(model2) ? KIMI_CAPABILITY : UNSUPPORTED;
14529
+ case "gemini":
14530
+ case "vertex":
14531
+ if (isGeminiLevelThinkingModel(model2)) return GEMINI_LEVEL_CAPABILITY;
14532
+ return isGeminiThinkingModel(model2) ? GEMINI_CAPABILITY : UNSUPPORTED;
14533
+ case "copilot":
14534
+ case "groq":
14535
+ case "openrouter":
14536
+ case "mistral":
14537
+ case "deepseek":
14538
+ case "together":
14539
+ case "huggingface":
14540
+ case "qwen":
14541
+ case "lmstudio":
14542
+ case "ollama":
14543
+ case "codex":
14544
+ return UNSUPPORTED;
14545
+ default:
14546
+ return UNSUPPORTED;
14547
+ }
14548
+ }
14549
+ function mapToAnthropic(mode, model2) {
13655
14550
  if (!mode || mode === "off") return void 0;
13656
- if (!isAnthropicThinkingModel(model)) return void 0;
14551
+ if (!isAnthropicThinkingModel(model2)) return void 0;
14552
+ if (isAnthropicAdaptiveThinkingModel(model2)) {
14553
+ return { type: "adaptive" };
14554
+ }
13657
14555
  const cap = ANTHROPIC_CAPABILITY;
13658
14556
  const { min, max } = cap.budgetRange;
13659
14557
  if (typeof mode === "object") {
@@ -13669,9 +14567,20 @@ function mapToAnthropic(mode, model) {
13669
14567
  if (budget === void 0) return void 0;
13670
14568
  return { type: "enabled", budget_tokens: budget };
13671
14569
  }
13672
- function mapToOpenAIEffort(mode, model) {
14570
+ function mapToAnthropicEffort(mode, model2) {
14571
+ if (!mode || mode === "off" || mode === "auto") return void 0;
14572
+ if (!isAnthropicAdaptiveThinkingModel(model2)) return void 0;
14573
+ if (typeof mode === "object") {
14574
+ if (mode.budget <= 2048) return "low";
14575
+ if (mode.budget <= 8e3) return "medium";
14576
+ return "high";
14577
+ }
14578
+ if (mode === "low" || mode === "medium" || mode === "high") return mode;
14579
+ return void 0;
14580
+ }
14581
+ function mapToOpenAIEffort(mode, model2) {
13673
14582
  if (!mode || mode === "off") return void 0;
13674
- if (!isOpenAIReasoningModel(model)) return void 0;
14583
+ if (!isOpenAIReasoningModel(model2)) return void 0;
13675
14584
  if (typeof mode === "object") {
13676
14585
  const { budget } = mode;
13677
14586
  if (budget <= 2048) return "low";
@@ -13682,8 +14591,9 @@ function mapToOpenAIEffort(mode, model) {
13682
14591
  if (mode === "low" || mode === "medium" || mode === "high") return mode;
13683
14592
  return void 0;
13684
14593
  }
13685
- function mapToGeminiBudget(mode, model) {
13686
- if (!isGeminiThinkingModel(model)) return void 0;
14594
+ function mapToGeminiBudget(mode, model2) {
14595
+ if (isGeminiLevelThinkingModel(model2)) return void 0;
14596
+ if (!isGeminiThinkingModel(model2)) return void 0;
13687
14597
  if (!mode) return void 0;
13688
14598
  if (mode === "off") return 0;
13689
14599
  if (mode === "auto") return -1;
@@ -13698,15 +14608,33 @@ function mapToGeminiBudget(mode, model) {
13698
14608
  };
13699
14609
  return budgetMap[mode];
13700
14610
  }
13701
- function mapToKimiExtraBody(mode, model) {
13702
- if (!isKimiThinkingModel(model)) return void 0;
14611
+ function mapToGeminiThinkingConfig(mode, model2) {
14612
+ if (isGeminiLevelThinkingModel(model2)) {
14613
+ if (!mode || mode === "auto") return void 0;
14614
+ if (mode === "off") return { thinkingLevel: "low" };
14615
+ if (mode === "low" || mode === "medium" || mode === "high") {
14616
+ return { thinkingLevel: mode };
14617
+ }
14618
+ if (typeof mode === "object") {
14619
+ if (mode.budget <= 2048) return { thinkingLevel: "low" };
14620
+ if (mode.budget <= 8e3) return { thinkingLevel: "medium" };
14621
+ return { thinkingLevel: "high" };
14622
+ }
14623
+ return void 0;
14624
+ }
14625
+ const thinkingBudget = mapToGeminiBudget(mode, model2);
14626
+ return thinkingBudget !== void 0 ? { thinkingBudget } : void 0;
14627
+ }
14628
+ function mapToKimiExtraBody(mode, model2) {
14629
+ if (!isKimiThinkingModel(model2)) return void 0;
13703
14630
  const effectiveMode = mode ?? "off";
13704
14631
  const enabled = effectiveMode !== "off";
13705
14632
  return { thinking: { type: enabled ? "enabled" : "disabled" } };
13706
14633
  }
13707
14634
 
13708
14635
  // src/providers/anthropic.ts
13709
- var DEFAULT_MODEL = "claude-opus-4-6";
14636
+ init_catalog();
14637
+ var DEFAULT_MODEL = getCatalogDefaultModel("anthropic");
13710
14638
  var CONTEXT_WINDOWS = {
13711
14639
  // Kimi Code model (Anthropic-compatible endpoint)
13712
14640
  "kimi-for-coding": 131072,
@@ -13732,6 +14660,20 @@ var CONTEXT_WINDOWS = {
13732
14660
  "claude-3-sonnet-20240229": 2e5,
13733
14661
  "claude-3-haiku-20240307": 2e5
13734
14662
  };
14663
+ function getAnthropicMaxTokens(baseMaxTokens, thinkingParam) {
14664
+ if (thinkingParam?.type === "enabled") {
14665
+ return Math.max(baseMaxTokens, thinkingParam.budget_tokens + 1024);
14666
+ }
14667
+ return baseMaxTokens;
14668
+ }
14669
+ function getAnthropicTemperature(thinkingParam, configuredTemperature) {
14670
+ if (thinkingParam?.type === "enabled") return 1;
14671
+ return configuredTemperature;
14672
+ }
14673
+ function getAnthropicOutputConfig(mode, model2) {
14674
+ const effort = mapToAnthropicEffort(mode, model2);
14675
+ return effort ? { effort } : void 0;
14676
+ }
13735
14677
  var AnthropicProvider = class {
13736
14678
  id;
13737
14679
  name;
@@ -13766,19 +14708,22 @@ var AnthropicProvider = class {
13766
14708
  this.ensureInitialized();
13767
14709
  return withRetry(async () => {
13768
14710
  try {
13769
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL;
13770
- const thinkingParam = mapToAnthropic(options?.thinking, model);
14711
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL;
14712
+ const thinkingParam = mapToAnthropic(options?.thinking, model2);
14713
+ const outputConfig = getAnthropicOutputConfig(options?.thinking, model2);
13771
14714
  const baseMaxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
13772
14715
  const response = await this.client.messages.create({
13773
- model,
13774
- // Anthropic requires max_tokens > budget_tokens
13775
- max_tokens: thinkingParam ? Math.max(baseMaxTokens, thinkingParam.budget_tokens + 1024) : baseMaxTokens,
13776
- // Anthropic requires temperature=1 when thinking is enabled
13777
- temperature: thinkingParam ? 1 : options?.temperature ?? this.config.temperature ?? 0,
14716
+ model: model2,
14717
+ max_tokens: getAnthropicMaxTokens(baseMaxTokens, thinkingParam),
14718
+ temperature: getAnthropicTemperature(
14719
+ thinkingParam,
14720
+ options?.temperature ?? this.config.temperature ?? 0
14721
+ ),
13778
14722
  system: this.extractSystem(messages, options?.system),
13779
14723
  messages: this.convertMessages(messages),
13780
14724
  stop_sequences: options?.stopSequences,
13781
- ...thinkingParam && { thinking: thinkingParam }
14725
+ ...thinkingParam && { thinking: thinkingParam },
14726
+ ...outputConfig && { output_config: outputConfig }
13782
14727
  });
13783
14728
  return {
13784
14729
  id: response.id,
@@ -13802,18 +14747,23 @@ var AnthropicProvider = class {
13802
14747
  this.ensureInitialized();
13803
14748
  return withRetry(async () => {
13804
14749
  try {
13805
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL;
13806
- const thinkingParam = mapToAnthropic(options?.thinking, model);
14750
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL;
14751
+ const thinkingParam = mapToAnthropic(options?.thinking, model2);
14752
+ const outputConfig = getAnthropicOutputConfig(options?.thinking, model2);
13807
14753
  const baseMaxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
13808
14754
  const response = await this.client.messages.create({
13809
- model,
13810
- max_tokens: thinkingParam ? Math.max(baseMaxTokens, thinkingParam.budget_tokens + 1024) : baseMaxTokens,
13811
- temperature: thinkingParam ? 1 : options?.temperature ?? this.config.temperature ?? 0,
14755
+ model: model2,
14756
+ max_tokens: getAnthropicMaxTokens(baseMaxTokens, thinkingParam),
14757
+ temperature: getAnthropicTemperature(
14758
+ thinkingParam,
14759
+ options?.temperature ?? this.config.temperature ?? 0
14760
+ ),
13812
14761
  system: this.extractSystem(messages, options?.system),
13813
14762
  messages: this.convertMessages(messages),
13814
14763
  tools: this.convertTools(options.tools),
13815
14764
  tool_choice: options.toolChoice ? this.convertToolChoice(options.toolChoice) : void 0,
13816
- ...thinkingParam && { thinking: thinkingParam }
14765
+ ...thinkingParam && { thinking: thinkingParam },
14766
+ ...outputConfig && { output_config: outputConfig }
13817
14767
  });
13818
14768
  const toolCalls = this.extractToolCalls(response.content);
13819
14769
  return {
@@ -13839,17 +14789,22 @@ var AnthropicProvider = class {
13839
14789
  this.ensureInitialized();
13840
14790
  let timeoutTriggered = false;
13841
14791
  try {
13842
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL;
13843
- const thinkingParam = mapToAnthropic(options?.thinking, model);
14792
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL;
14793
+ const thinkingParam = mapToAnthropic(options?.thinking, model2);
14794
+ const outputConfig = getAnthropicOutputConfig(options?.thinking, model2);
13844
14795
  const baseMaxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
13845
14796
  const stream = await this.client.messages.stream(
13846
14797
  {
13847
- model,
13848
- max_tokens: thinkingParam ? Math.max(baseMaxTokens, thinkingParam.budget_tokens + 1024) : baseMaxTokens,
13849
- temperature: thinkingParam ? 1 : options?.temperature ?? this.config.temperature ?? 0,
14798
+ model: model2,
14799
+ max_tokens: getAnthropicMaxTokens(baseMaxTokens, thinkingParam),
14800
+ temperature: getAnthropicTemperature(
14801
+ thinkingParam,
14802
+ options?.temperature ?? this.config.temperature ?? 0
14803
+ ),
13850
14804
  system: this.extractSystem(messages, options?.system),
13851
14805
  messages: this.convertMessages(messages),
13852
- ...thinkingParam && { thinking: thinkingParam }
14806
+ ...thinkingParam && { thinking: thinkingParam },
14807
+ ...outputConfig && { output_config: outputConfig }
13853
14808
  },
13854
14809
  { signal: options?.signal }
13855
14810
  );
@@ -13905,19 +14860,24 @@ var AnthropicProvider = class {
13905
14860
  this.ensureInitialized();
13906
14861
  let timeoutTriggered = false;
13907
14862
  try {
13908
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL;
13909
- const thinkingParam = mapToAnthropic(options?.thinking, model);
14863
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL;
14864
+ const thinkingParam = mapToAnthropic(options?.thinking, model2);
14865
+ const outputConfig = getAnthropicOutputConfig(options?.thinking, model2);
13910
14866
  const baseMaxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
13911
14867
  const stream = await this.client.messages.stream(
13912
14868
  {
13913
- model,
13914
- max_tokens: thinkingParam ? Math.max(baseMaxTokens, thinkingParam.budget_tokens + 1024) : baseMaxTokens,
13915
- temperature: thinkingParam ? 1 : options?.temperature ?? this.config.temperature ?? 0,
14869
+ model: model2,
14870
+ max_tokens: getAnthropicMaxTokens(baseMaxTokens, thinkingParam),
14871
+ temperature: getAnthropicTemperature(
14872
+ thinkingParam,
14873
+ options?.temperature ?? this.config.temperature ?? 0
14874
+ ),
13916
14875
  system: this.extractSystem(messages, options?.system),
13917
14876
  messages: this.convertMessages(messages),
13918
14877
  tools: this.convertTools(options.tools),
13919
14878
  tool_choice: options.toolChoice ? this.convertToolChoice(options.toolChoice) : void 0,
13920
- ...thinkingParam && { thinking: thinkingParam }
14879
+ ...thinkingParam && { thinking: thinkingParam },
14880
+ ...outputConfig && { output_config: outputConfig }
13921
14881
  },
13922
14882
  { signal: options?.signal }
13923
14883
  );
@@ -14042,33 +15002,38 @@ var AnthropicProvider = class {
14042
15002
  *
14043
15003
  * This heuristic analyzes the text to provide a better estimate.
14044
15004
  */
14045
- countTokens(text) {
14046
- if (!text) return 0;
15005
+ countTokens(text2) {
15006
+ if (!text2) return 0;
14047
15007
  const codePatterns = /[{}[\]();=<>!&|+\-*/]/g;
14048
15008
  const whitespacePattern = /\s/g;
14049
15009
  const wordPattern = /\b\w+\b/g;
14050
- const codeChars = (text.match(codePatterns) || []).length;
14051
- const whitespace = (text.match(whitespacePattern) || []).length;
14052
- const words = (text.match(wordPattern) || []).length;
14053
- const isCodeLike = codeChars > text.length * 0.05;
15010
+ const codeChars = (text2.match(codePatterns) || []).length;
15011
+ const whitespace = (text2.match(whitespacePattern) || []).length;
15012
+ const words = (text2.match(wordPattern) || []).length;
15013
+ const isCodeLike = codeChars > text2.length * 0.05;
14054
15014
  let charsPerToken;
14055
15015
  if (isCodeLike) {
14056
15016
  charsPerToken = 3.5;
14057
- } else if (whitespace > text.length * 0.3) {
15017
+ } else if (whitespace > text2.length * 0.3) {
14058
15018
  charsPerToken = 5;
14059
15019
  } else {
14060
15020
  charsPerToken = 4.5;
14061
15021
  }
14062
15022
  const wordBasedEstimate = words * 1.3;
14063
- const charBasedEstimate = text.length / charsPerToken;
15023
+ const charBasedEstimate = text2.length / charsPerToken;
14064
15024
  return Math.ceil((wordBasedEstimate + charBasedEstimate) / 2);
14065
15025
  }
14066
15026
  /**
14067
15027
  * Get context window size
14068
15028
  */
14069
15029
  getContextWindow() {
14070
- const model = this.config.model ?? DEFAULT_MODEL;
14071
- return CONTEXT_WINDOWS[model] ?? 2e5;
15030
+ const model2 = this.config.model ?? DEFAULT_MODEL;
15031
+ const provider = this.id === "kimi-code" ? "kimi-code" : "anthropic";
15032
+ const catalogWindow = getCatalogContextWindow(provider, model2, 0);
15033
+ if (catalogWindow > 0) {
15034
+ return catalogWindow;
15035
+ }
15036
+ return CONTEXT_WINDOWS[model2] ?? 2e5;
14072
15037
  }
14073
15038
  /**
14074
15039
  * Check if provider is available
@@ -14109,8 +15074,8 @@ var AnthropicProvider = class {
14109
15074
  const systemMsg = messages.find((m) => m.role === "system");
14110
15075
  if (!systemMsg) return void 0;
14111
15076
  if (typeof systemMsg.content === "string") return systemMsg.content;
14112
- const text = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
14113
- return text || void 0;
15077
+ const text2 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
15078
+ return text2 || void 0;
14114
15079
  }
14115
15080
  /**
14116
15081
  * Convert messages to Anthropic format
@@ -14318,15 +15283,15 @@ var ChatToolCallAssembler = class {
14318
15283
  if (delta.function?.name) {
14319
15284
  builder.name = delta.function.name;
14320
15285
  }
14321
- const text = delta.function?.arguments ?? "";
14322
- if (!text) return { started };
14323
- builder.arguments += text;
15286
+ const text2 = delta.function?.arguments ?? "";
15287
+ if (!text2) return { started };
15288
+ builder.arguments += text2;
14324
15289
  return {
14325
15290
  started,
14326
15291
  argumentDelta: {
14327
15292
  id: builder.id,
14328
15293
  name: builder.name,
14329
- text
15294
+ text: text2
14330
15295
  }
14331
15296
  };
14332
15297
  }
@@ -14503,45 +15468,46 @@ var EVAL_TIERS = [
14503
15468
  { prefix: "raptor", tier: "mini" },
14504
15469
  { prefix: "goldeneye", tier: "standard" }
14505
15470
  ];
14506
- function matchTier(model, table) {
14507
- const lower = model.toLowerCase();
15471
+ function matchTier(model2, table) {
15472
+ const lower = model2.toLowerCase();
14508
15473
  const sorted = [...table].sort((a, b) => b.prefix.length - a.prefix.length);
14509
15474
  for (const { prefix, tier } of sorted) {
14510
15475
  if (lower.startsWith(prefix.toLowerCase())) return tier;
14511
15476
  }
14512
15477
  return null;
14513
15478
  }
14514
- function getModelTier(provider, model) {
14515
- if (!model) return "standard";
15479
+ function getModelTier(provider, model2) {
15480
+ if (!model2) return "standard";
14516
15481
  const p5 = provider.toLowerCase();
14517
15482
  if (p5 === "anthropic") {
14518
- return matchTier(model, ANTHROPIC_TIERS) ?? "standard";
15483
+ return matchTier(model2, ANTHROPIC_TIERS) ?? "standard";
14519
15484
  }
14520
15485
  if (p5 === "kimi-code") {
14521
- return matchTier(model, KIMI_TIERS) ?? matchTier(model, ANTHROPIC_TIERS) ?? "standard";
15486
+ return matchTier(model2, KIMI_TIERS) ?? matchTier(model2, ANTHROPIC_TIERS) ?? "standard";
14522
15487
  }
14523
15488
  if (p5 === "openai" || p5 === "copilot" || p5 === "codex") {
14524
- if (model.startsWith("claude-")) {
14525
- return matchTier(model, ANTHROPIC_TIERS) ?? "standard";
15489
+ if (model2.startsWith("claude-")) {
15490
+ return matchTier(model2, ANTHROPIC_TIERS) ?? "standard";
14526
15491
  }
14527
- const evalMatch = matchTier(model, EVAL_TIERS);
15492
+ const evalMatch = matchTier(model2, EVAL_TIERS);
14528
15493
  if (evalMatch) return evalMatch;
14529
- return matchTier(model, OPENAI_TIERS) ?? "standard";
15494
+ return matchTier(model2, OPENAI_TIERS) ?? "standard";
14530
15495
  }
14531
15496
  if (p5 === "gemini" || p5 === "vertex") {
14532
- return matchTier(model, GEMINI_TIERS) ?? "standard";
15497
+ return matchTier(model2, GEMINI_TIERS) ?? "standard";
14533
15498
  }
14534
15499
  if (p5 === "kimi" || p5 === "moonshot") {
14535
- return matchTier(model, KIMI_TIERS) ?? "standard";
15500
+ return matchTier(model2, KIMI_TIERS) ?? "standard";
14536
15501
  }
14537
15502
  return "standard";
14538
15503
  }
14539
- function getTierConfig(provider, model) {
14540
- return TIER_CONFIGS[getModelTier(provider, model)];
15504
+ function getTierConfig(provider, model2) {
15505
+ return TIER_CONFIGS[getModelTier(provider, model2)];
14541
15506
  }
14542
15507
 
14543
15508
  // src/providers/openai.ts
14544
- var DEFAULT_MODEL2 = "gpt-5.3-codex";
15509
+ init_catalog();
15510
+ var DEFAULT_MODEL2 = getCatalogDefaultModel("openai");
14545
15511
  var CONTEXT_WINDOWS2 = {
14546
15512
  // OpenAI models
14547
15513
  "gpt-4o": 128e3,
@@ -14652,14 +15618,14 @@ var LOCAL_MODEL_PATTERNS = [
14652
15618
  "starcoder"
14653
15619
  ];
14654
15620
  var MODELS_WITH_THINKING_MODE = ["kimi-k2.5", "kimi-k2-0324", "kimi-latest"];
14655
- function needsResponsesApi(model) {
14656
- return model.includes("codex") || model.startsWith("gpt-5") || model.startsWith("o4-") || model === "o3";
15621
+ function needsResponsesApi(model2) {
15622
+ return model2.includes("codex") || model2.startsWith("gpt-5") || model2.startsWith("o4-") || model2 === "o3";
14657
15623
  }
14658
- function needsMaxCompletionTokens(model) {
14659
- return model.startsWith("o1") || model.startsWith("o3") || model.startsWith("o4") || model.startsWith("gpt-4o") || model.startsWith("gpt-4.1") || model.startsWith("gpt-5") || model.startsWith("chatgpt-4o");
15624
+ function needsMaxCompletionTokens(model2) {
15625
+ return model2.startsWith("o1") || model2.startsWith("o3") || model2.startsWith("o4") || model2.startsWith("gpt-4o") || model2.startsWith("gpt-4.1") || model2.startsWith("gpt-5") || model2.startsWith("chatgpt-4o");
14660
15626
  }
14661
- function buildMaxTokensParam(model, maxTokens) {
14662
- if (needsMaxCompletionTokens(model)) {
15627
+ function buildMaxTokensParam(model2, maxTokens) {
15628
+ if (needsMaxCompletionTokens(model2)) {
14663
15629
  return { max_completion_tokens: maxTokens };
14664
15630
  }
14665
15631
  return { max_tokens: maxTokens };
@@ -14701,26 +15667,45 @@ var OpenAIProvider = class {
14701
15667
  /**
14702
15668
  * Check if a model supports temperature parameter
14703
15669
  */
14704
- supportsTemperature(model) {
14705
- return !MODELS_WITHOUT_TEMPERATURE.some((m) => model.toLowerCase().includes(m.toLowerCase()));
15670
+ supportsTemperature(model2) {
15671
+ return !MODELS_WITHOUT_TEMPERATURE.some((m) => model2.toLowerCase().includes(m.toLowerCase()));
14706
15672
  }
14707
15673
  /**
14708
15674
  * Whether this provider instance supports the Responses API for the given model.
14709
15675
  * Subclasses (e.g. CopilotProvider) can override to force Chat Completions
14710
15676
  * when their endpoint does not expose /v1/responses.
14711
15677
  */
14712
- modelNeedsResponsesApi(model) {
14713
- return needsResponsesApi(model);
15678
+ modelNeedsResponsesApi(model2) {
15679
+ return this.id === "openai" && needsResponsesApi(model2);
15680
+ }
15681
+ /**
15682
+ * Map thinking mode to Chat Completions reasoning_effort.
15683
+ * Subclasses can override when an OpenAI-compatible endpoint exposes GPT-5
15684
+ * models but cannot safely combine reasoning_effort with tool calls.
15685
+ */
15686
+ getChatCompletionsReasoningEffort(model2, thinking, _hasTools) {
15687
+ const capability = getThinkingCapability(this.id, model2);
15688
+ if (!capability.supported || !capability.kinds.includes("effort")) {
15689
+ return void 0;
15690
+ }
15691
+ return mapToOpenAIEffort(thinking, model2);
15692
+ }
15693
+ getResponsesReasoningEffort(model2, thinking) {
15694
+ const capability = getThinkingCapability(this.id, model2);
15695
+ if (!capability.supported || !capability.kinds.includes("effort")) {
15696
+ return void 0;
15697
+ }
15698
+ return mapToOpenAIEffort(thinking, model2);
14714
15699
  }
14715
15700
  /**
14716
15701
  * Get extra body parameters for API calls.
14717
15702
  * Honors the user's ThinkingMode for Kimi models; defaults to disabled
14718
15703
  * (preserving existing behavior) when no mode is specified.
14719
15704
  */
14720
- getExtraBody(model, thinking) {
14721
- const kimiBody = mapToKimiExtraBody(thinking, model);
15705
+ getExtraBody(model2, thinking) {
15706
+ const kimiBody = mapToKimiExtraBody(thinking, model2);
14722
15707
  if (kimiBody) return kimiBody;
14723
- if (MODELS_WITH_THINKING_MODE.some((m) => model.toLowerCase().includes(m.toLowerCase()))) {
15708
+ if (MODELS_WITH_THINKING_MODE.some((m) => model2.toLowerCase().includes(m.toLowerCase()))) {
14724
15709
  return { thinking: { type: "disabled" } };
14725
15710
  }
14726
15711
  return void 0;
@@ -14730,18 +15715,22 @@ var OpenAIProvider = class {
14730
15715
  */
14731
15716
  async chat(messages, options) {
14732
15717
  this.ensureInitialized();
14733
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
14734
- if (this.modelNeedsResponsesApi(model)) {
15718
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
15719
+ if (this.modelNeedsResponsesApi(model2)) {
14735
15720
  return this.chatViaResponses(messages, options);
14736
15721
  }
14737
15722
  return withRetry(async () => {
14738
15723
  try {
14739
- const supportsTemp = this.supportsTemperature(model);
15724
+ const supportsTemp = this.supportsTemperature(model2);
14740
15725
  const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
14741
- const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
15726
+ const reasoningEffort = this.getChatCompletionsReasoningEffort(
15727
+ model2,
15728
+ options?.thinking,
15729
+ false
15730
+ );
14742
15731
  const response = await this.client.chat.completions.create({
14743
- model,
14744
- ...buildMaxTokensParam(model, maxTokens),
15732
+ model: model2,
15733
+ ...buildMaxTokensParam(model2, maxTokens),
14745
15734
  messages: this.convertMessages(messages, options?.system),
14746
15735
  stop: options?.stopSequences,
14747
15736
  ...supportsTemp && {
@@ -14770,21 +15759,25 @@ var OpenAIProvider = class {
14770
15759
  */
14771
15760
  async chatWithTools(messages, options) {
14772
15761
  this.ensureInitialized();
14773
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
14774
- if (this.modelNeedsResponsesApi(model)) {
15762
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
15763
+ if (this.modelNeedsResponsesApi(model2)) {
14775
15764
  return this.chatWithToolsViaResponses(messages, options);
14776
15765
  }
14777
- const tierCfg = getTierConfig(this.id, model);
15766
+ const tierCfg = getTierConfig(this.id, model2);
14778
15767
  return withRetry(async () => {
14779
15768
  try {
14780
- const supportsTemp = this.supportsTemperature(model);
14781
- const extraBody = this.getExtraBody(model, options?.thinking);
14782
- const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
15769
+ const supportsTemp = this.supportsTemperature(model2);
15770
+ const extraBody = this.getExtraBody(model2, options?.thinking);
15771
+ const reasoningEffort = this.getChatCompletionsReasoningEffort(
15772
+ model2,
15773
+ options?.thinking,
15774
+ true
15775
+ );
14783
15776
  const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
14784
15777
  const tools = this.limitTools(options.tools, tierCfg.maxTools);
14785
15778
  const requestParams = {
14786
- model,
14787
- ...buildMaxTokensParam(model, maxTokens),
15779
+ model: model2,
15780
+ ...buildMaxTokensParam(model2, maxTokens),
14788
15781
  messages: this.convertMessages(messages, options?.system),
14789
15782
  tools: this.convertTools(tools),
14790
15783
  tool_choice: this.convertToolChoice(options.toolChoice),
@@ -14825,18 +15818,22 @@ var OpenAIProvider = class {
14825
15818
  */
14826
15819
  async *stream(messages, options) {
14827
15820
  this.ensureInitialized();
14828
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
14829
- if (this.modelNeedsResponsesApi(model)) {
15821
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
15822
+ if (this.modelNeedsResponsesApi(model2)) {
14830
15823
  yield* this.streamViaResponses(messages, options);
14831
15824
  return;
14832
15825
  }
14833
15826
  try {
14834
- const supportsTemp = this.supportsTemperature(model);
15827
+ const supportsTemp = this.supportsTemperature(model2);
14835
15828
  const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
14836
- const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
15829
+ const reasoningEffort = this.getChatCompletionsReasoningEffort(
15830
+ model2,
15831
+ options?.thinking,
15832
+ false
15833
+ );
14837
15834
  const stream = await this.client.chat.completions.create({
14838
- model,
14839
- ...buildMaxTokensParam(model, maxTokens),
15835
+ model: model2,
15836
+ ...buildMaxTokensParam(model2, maxTokens),
14840
15837
  messages: this.convertMessages(messages, options?.system),
14841
15838
  stream: true,
14842
15839
  ...supportsTemp && { temperature: options?.temperature ?? this.config.temperature ?? 0 },
@@ -14863,22 +15860,26 @@ var OpenAIProvider = class {
14863
15860
  */
14864
15861
  async *streamWithTools(messages, options) {
14865
15862
  this.ensureInitialized();
14866
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
14867
- if (this.modelNeedsResponsesApi(model)) {
15863
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
15864
+ if (this.modelNeedsResponsesApi(model2)) {
14868
15865
  yield* this.streamWithToolsViaResponses(messages, options);
14869
15866
  return;
14870
15867
  }
14871
- const tierCfg = getTierConfig(this.id, model);
15868
+ const tierCfg = getTierConfig(this.id, model2);
14872
15869
  let timeoutTriggered = false;
14873
15870
  try {
14874
- const supportsTemp = this.supportsTemperature(model);
14875
- const extraBody = this.getExtraBody(model, options?.thinking);
14876
- const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
15871
+ const supportsTemp = this.supportsTemperature(model2);
15872
+ const extraBody = this.getExtraBody(model2, options?.thinking);
15873
+ const reasoningEffort = this.getChatCompletionsReasoningEffort(
15874
+ model2,
15875
+ options?.thinking,
15876
+ true
15877
+ );
14877
15878
  const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
14878
15879
  const tools = this.limitTools(options.tools, tierCfg.maxTools);
14879
15880
  const requestParams = {
14880
- model,
14881
- ...buildMaxTokensParam(model, maxTokens),
15881
+ model: model2,
15882
+ ...buildMaxTokensParam(model2, maxTokens),
14882
15883
  messages: this.convertMessages(messages, options?.system),
14883
15884
  tools: this.convertTools(tools),
14884
15885
  tool_choice: this.convertToolChoice(options.toolChoice),
@@ -14999,13 +16000,13 @@ var OpenAIProvider = class {
14999
16000
  * Check if current model is a local model (LM Studio, Ollama, etc.)
15000
16001
  */
15001
16002
  isLocalModel() {
15002
- const model = (this.config.model ?? "").toLowerCase();
16003
+ const model2 = (this.config.model ?? "").toLowerCase();
15003
16004
  const baseUrl = (this.config.baseUrl ?? "").toLowerCase();
15004
16005
  if (baseUrl.includes("localhost") || baseUrl.includes("127.0.0.1") || baseUrl.includes(":1234") || // LM Studio default
15005
16006
  baseUrl.includes(":11434")) {
15006
16007
  return true;
15007
16008
  }
15008
- return LOCAL_MODEL_PATTERNS.some((pattern) => model.includes(pattern));
16009
+ return LOCAL_MODEL_PATTERNS.some((pattern) => model2.includes(pattern));
15009
16010
  }
15010
16011
  /**
15011
16012
  * Count tokens (improved heuristic for OpenAI and local models)
@@ -15025,23 +16026,23 @@ var OpenAIProvider = class {
15025
16026
  * For accurate counting, use the model's native tokenizer.
15026
16027
  * This heuristic provides a reasonable estimate without dependencies.
15027
16028
  */
15028
- countTokens(text) {
15029
- if (!text) return 0;
16029
+ countTokens(text2) {
16030
+ if (!text2) return 0;
15030
16031
  const codePatterns = /[{}[\]();=<>!&|+\-*/]/g;
15031
16032
  const whitespacePattern = /\s/g;
15032
16033
  const wordPattern = /\b\w+\b/g;
15033
16034
  const nonAsciiPattern = /[^\x00-\x7F]/g;
15034
- const codeChars = (text.match(codePatterns) || []).length;
15035
- const whitespace = (text.match(whitespacePattern) || []).length;
15036
- const words = (text.match(wordPattern) || []).length;
15037
- const nonAscii = (text.match(nonAsciiPattern) || []).length;
15038
- const isCodeLike = codeChars > text.length * 0.05;
16035
+ const codeChars = (text2.match(codePatterns) || []).length;
16036
+ const whitespace = (text2.match(whitespacePattern) || []).length;
16037
+ const words = (text2.match(wordPattern) || []).length;
16038
+ const nonAscii = (text2.match(nonAsciiPattern) || []).length;
16039
+ const isCodeLike = codeChars > text2.length * 0.05;
15039
16040
  const isLocal = this.isLocalModel();
15040
16041
  let charsPerToken;
15041
16042
  if (isLocal) {
15042
16043
  if (isCodeLike) {
15043
16044
  charsPerToken = 3.2;
15044
- } else if (nonAscii > text.length * 0.1) {
16045
+ } else if (nonAscii > text2.length * 0.1) {
15045
16046
  charsPerToken = 2;
15046
16047
  } else {
15047
16048
  charsPerToken = 3.5;
@@ -15049,7 +16050,7 @@ var OpenAIProvider = class {
15049
16050
  } else {
15050
16051
  if (isCodeLike) {
15051
16052
  charsPerToken = 3.3;
15052
- } else if (whitespace > text.length * 0.3) {
16053
+ } else if (whitespace > text2.length * 0.3) {
15053
16054
  charsPerToken = 4.5;
15054
16055
  } else {
15055
16056
  charsPerToken = 4;
@@ -15057,7 +16058,7 @@ var OpenAIProvider = class {
15057
16058
  }
15058
16059
  const tokensPerWord = isLocal ? 1.4 : 1.3;
15059
16060
  const wordBasedEstimate = words * tokensPerWord;
15060
- const charBasedEstimate = text.length / charsPerToken;
16061
+ const charBasedEstimate = text2.length / charsPerToken;
15061
16062
  const weight = isCodeLike ? 0.7 : 0.5;
15062
16063
  return Math.ceil(charBasedEstimate * weight + wordBasedEstimate * (1 - weight));
15063
16064
  }
@@ -15069,11 +16070,15 @@ var OpenAIProvider = class {
15069
16070
  * conventions (e.g., "qwen3-coder-8b" vs "qwen3-coder-8b-instruct").
15070
16071
  */
15071
16072
  getContextWindow() {
15072
- const model = this.config.model ?? DEFAULT_MODEL2;
15073
- if (CONTEXT_WINDOWS2[model]) {
15074
- return CONTEXT_WINDOWS2[model];
16073
+ const model2 = this.config.model ?? DEFAULT_MODEL2;
16074
+ if (CONTEXT_WINDOWS2[model2]) {
16075
+ return CONTEXT_WINDOWS2[model2];
16076
+ }
16077
+ const catalogWindow = getCatalogContextWindow(this.id, model2, 0);
16078
+ if (catalogWindow > 0) {
16079
+ return catalogWindow;
15075
16080
  }
15076
- const modelLower = model.toLowerCase();
16081
+ const modelLower = model2.toLowerCase();
15077
16082
  for (const [key, value] of Object.entries(CONTEXT_WINDOWS2)) {
15078
16083
  if (modelLower.includes(key.toLowerCase()) || key.toLowerCase().includes(modelLower)) {
15079
16084
  return value;
@@ -15118,19 +16123,19 @@ var OpenAIProvider = class {
15118
16123
  return true;
15119
16124
  } catch {
15120
16125
  try {
15121
- const model = this.config.model || DEFAULT_MODEL2;
15122
- if (this.modelNeedsResponsesApi(model)) {
16126
+ const model2 = this.config.model || DEFAULT_MODEL2;
16127
+ if (this.modelNeedsResponsesApi(model2)) {
15123
16128
  await this.client.responses.create({
15124
- model,
16129
+ model: model2,
15125
16130
  input: [{ role: "user", content: [{ type: "input_text", text: "Hi" }] }],
15126
16131
  max_output_tokens: 1,
15127
16132
  store: false
15128
16133
  });
15129
16134
  } else {
15130
16135
  await this.client.chat.completions.create({
15131
- model,
16136
+ model: model2,
15132
16137
  messages: [{ role: "user", content: "Hi" }],
15133
- ...buildMaxTokensParam(model, 1)
16138
+ ...buildMaxTokensParam(model2, 1)
15134
16139
  });
15135
16140
  }
15136
16141
  return true;
@@ -15367,12 +16372,12 @@ var OpenAIProvider = class {
15367
16372
  this.ensureInitialized();
15368
16373
  return withRetry(async () => {
15369
16374
  try {
15370
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
16375
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
15371
16376
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
15372
- const supportsTemp = this.supportsTemperature(model);
15373
- const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
16377
+ const supportsTemp = this.supportsTemperature(model2);
16378
+ const reasoningEffort = this.getResponsesReasoningEffort(model2, options?.thinking);
15374
16379
  const response = await this.client.responses.create({
15375
- model,
16380
+ model: model2,
15376
16381
  input,
15377
16382
  instructions: instructions ?? void 0,
15378
16383
  max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
@@ -15405,16 +16410,16 @@ var OpenAIProvider = class {
15405
16410
  this.ensureInitialized();
15406
16411
  return withRetry(async () => {
15407
16412
  try {
15408
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
15409
- const tierCfg = getTierConfig(this.id, model);
16413
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
16414
+ const tierCfg = getTierConfig(this.id, model2);
15410
16415
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
15411
16416
  const tools = this.convertToolsForResponses(
15412
16417
  this.limitTools(options.tools, tierCfg.maxTools)
15413
16418
  );
15414
- const supportsTemp = this.supportsTemperature(model);
15415
- const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
16419
+ const supportsTemp = this.supportsTemperature(model2);
16420
+ const reasoningEffort = this.getResponsesReasoningEffort(model2, options?.thinking);
15416
16421
  const response = await this.client.responses.create({
15417
- model,
16422
+ model: model2,
15418
16423
  input,
15419
16424
  instructions: instructions ?? void 0,
15420
16425
  tools,
@@ -15465,12 +16470,12 @@ var OpenAIProvider = class {
15465
16470
  this.ensureInitialized();
15466
16471
  let timeoutTriggered = false;
15467
16472
  try {
15468
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
16473
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
15469
16474
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
15470
- const supportsTemp = this.supportsTemperature(model);
15471
- const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
16475
+ const supportsTemp = this.supportsTemperature(model2);
16476
+ const reasoningEffort = this.getResponsesReasoningEffort(model2, options?.thinking);
15472
16477
  const stream = await this.client.responses.create({
15473
- model,
16478
+ model: model2,
15474
16479
  input,
15475
16480
  instructions: instructions ?? void 0,
15476
16481
  max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
@@ -15529,15 +16534,15 @@ var OpenAIProvider = class {
15529
16534
  this.ensureInitialized();
15530
16535
  let timeoutTriggered = false;
15531
16536
  try {
15532
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
15533
- const tierCfg = getTierConfig(this.id, model);
16537
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
16538
+ const tierCfg = getTierConfig(this.id, model2);
15534
16539
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
15535
16540
  const limitedTools = this.limitTools(options.tools, tierCfg.maxTools);
15536
16541
  const tools = limitedTools.length > 0 ? this.convertToolsForResponses(limitedTools) : void 0;
15537
- const supportsTemp = this.supportsTemperature(model);
15538
- const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
16542
+ const supportsTemp = this.supportsTemperature(model2);
16543
+ const reasoningEffort = this.getResponsesReasoningEffort(model2, options?.thinking);
15539
16544
  const requestParams = {
15540
- model,
16545
+ model: model2,
15541
16546
  input,
15542
16547
  instructions: instructions ?? void 0,
15543
16548
  max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
@@ -15792,8 +16797,9 @@ function createKimiProvider(config) {
15792
16797
  // src/providers/codex.ts
15793
16798
  init_errors();
15794
16799
  init_auth();
16800
+ init_catalog();
15795
16801
  var CODEX_API_ENDPOINT = "https://chatgpt.com/backend-api/codex/responses";
15796
- var DEFAULT_MODEL3 = "gpt-5.3-codex";
16802
+ var DEFAULT_MODEL3 = getCatalogDefaultModel("codex");
15797
16803
  var CONTEXT_WINDOWS3 = {
15798
16804
  "gpt-5.4-codex": 2e5,
15799
16805
  "gpt-5.3-codex": 2e5,
@@ -15860,16 +16866,23 @@ var CodexProvider = class {
15860
16866
  /**
15861
16867
  * Get context window size for a model
15862
16868
  */
15863
- getContextWindow(model) {
15864
- const m = model ?? this.config.model ?? DEFAULT_MODEL3;
15865
- return CONTEXT_WINDOWS3[m] ?? 128e3;
16869
+ getContextWindow(model2) {
16870
+ const m = model2 ?? this.config.model ?? DEFAULT_MODEL3;
16871
+ if (CONTEXT_WINDOWS3[m]) {
16872
+ return CONTEXT_WINDOWS3[m];
16873
+ }
16874
+ const catalogWindow = getCatalogContextWindow("codex", m, 0);
16875
+ if (catalogWindow > 0) {
16876
+ return catalogWindow;
16877
+ }
16878
+ return 128e3;
15866
16879
  }
15867
16880
  /**
15868
16881
  * Count tokens in text (approximate)
15869
16882
  * Uses GPT-4 approximation: ~4 chars per token
15870
16883
  */
15871
- countTokens(text) {
15872
- return Math.ceil(text.length / 4);
16884
+ countTokens(text2) {
16885
+ return Math.ceil(text2.length / 4);
15873
16886
  }
15874
16887
  /**
15875
16888
  * Check if provider is available (has valid OAuth tokens)
@@ -15997,9 +17010,9 @@ var CodexProvider = class {
15997
17010
  /**
15998
17011
  * Build the request body for the Codex Responses API
15999
17012
  */
16000
- buildRequestBody(model, input, instructions, options) {
17013
+ buildRequestBody(model2, input, instructions, options) {
16001
17014
  const body = {
16002
- model,
17015
+ model: model2,
16003
17016
  input,
16004
17017
  instructions: instructions ?? "You are a helpful coding assistant.",
16005
17018
  store: false,
@@ -16064,9 +17077,9 @@ var CodexProvider = class {
16064
17077
  */
16065
17078
  async chat(messages, options) {
16066
17079
  return withRetry(async () => {
16067
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL3;
17080
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL3;
16068
17081
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
16069
- const body = this.buildRequestBody(model, input, instructions, {
17082
+ const body = this.buildRequestBody(model2, input, instructions, {
16070
17083
  maxTokens: options?.maxTokens,
16071
17084
  temperature: options?.temperature
16072
17085
  });
@@ -16097,7 +17110,7 @@ var CodexProvider = class {
16097
17110
  id: responseId,
16098
17111
  content,
16099
17112
  stopReason,
16100
- model,
17113
+ model: model2,
16101
17114
  usage: { inputTokens, outputTokens }
16102
17115
  };
16103
17116
  }, this.retryConfig);
@@ -16107,9 +17120,9 @@ var CodexProvider = class {
16107
17120
  */
16108
17121
  async chatWithTools(messages, options) {
16109
17122
  return withRetry(async () => {
16110
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL3;
17123
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL3;
16111
17124
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
16112
- const body = this.buildRequestBody(model, input, instructions, {
17125
+ const body = this.buildRequestBody(model2, input, instructions, {
16113
17126
  tools: options.tools,
16114
17127
  maxTokens: options?.maxTokens
16115
17128
  });
@@ -16184,7 +17197,7 @@ var CodexProvider = class {
16184
17197
  id: responseId,
16185
17198
  content,
16186
17199
  stopReason: toolCalls.length > 0 ? "tool_use" : "end_turn",
16187
- model,
17200
+ model: model2,
16188
17201
  usage: { inputTokens, outputTokens },
16189
17202
  toolCalls
16190
17203
  };
@@ -16194,9 +17207,9 @@ var CodexProvider = class {
16194
17207
  * Stream a chat response (no tools)
16195
17208
  */
16196
17209
  async *stream(messages, options) {
16197
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL3;
17210
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL3;
16198
17211
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
16199
- const body = this.buildRequestBody(model, input, instructions, {
17212
+ const body = this.buildRequestBody(model2, input, instructions, {
16200
17213
  maxTokens: options?.maxTokens
16201
17214
  });
16202
17215
  const response = await this.makeRequest(body);
@@ -16256,9 +17269,9 @@ var CodexProvider = class {
16256
17269
  * item_id which references the output item's id field, not call_id.
16257
17270
  */
16258
17271
  async *streamWithTools(messages, options) {
16259
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL3;
17272
+ const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL3;
16260
17273
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
16261
- const body = this.buildRequestBody(model, input, instructions, {
17274
+ const body = this.buildRequestBody(model2, input, instructions, {
16262
17275
  tools: options.tools,
16263
17276
  maxTokens: options?.maxTokens
16264
17277
  });
@@ -16407,6 +17420,7 @@ var CodexProvider = class {
16407
17420
  // src/providers/copilot.ts
16408
17421
  init_errors();
16409
17422
  init_copilot();
17423
+ init_catalog();
16410
17424
  var CONTEXT_WINDOWS4 = {
16411
17425
  // Claude models — Copilot API caps these at 168 000 (not 200 000 like Anthropic direct)
16412
17426
  "claude-sonnet-4.6": 168e3,
@@ -16440,10 +17454,10 @@ var CONTEXT_WINDOWS4 = {
16440
17454
  "raptor-mini": 4e5,
16441
17455
  goldeneye: 4e5
16442
17456
  };
16443
- var DEFAULT_MODEL4 = "claude-sonnet-4.6";
16444
- function normalizeModel(model) {
16445
- if (typeof model !== "string") return void 0;
16446
- const trimmed = model.trim();
17457
+ var DEFAULT_MODEL4 = getCatalogDefaultModel("copilot");
17458
+ function normalizeModel(model2) {
17459
+ if (typeof model2 !== "string") return void 0;
17460
+ const trimmed = model2.trim();
16447
17461
  return trimmed.length > 0 ? trimmed : void 0;
16448
17462
  }
16449
17463
  var COPILOT_HEADERS = {
@@ -16550,16 +17564,31 @@ var CopilotProvider = class extends OpenAIProvider {
16550
17564
  modelNeedsResponsesApi(_model) {
16551
17565
  return false;
16552
17566
  }
16553
- countTokens(text) {
16554
- if (!text) return 0;
16555
- return Math.ceil(text.length / 3.5);
17567
+ /**
17568
+ * Copilot's OpenAI-compatible endpoint currently routes through
17569
+ * Chat Completions. For GPT-5.x models, combining function tools with
17570
+ * reasoning_effort is rejected by the upstream API. Keep tools working by
17571
+ * omitting reasoning_effort on tool calls instead of advertising a broken
17572
+ * combination.
17573
+ */
17574
+ getChatCompletionsReasoningEffort(_model, _thinking, hasTools) {
17575
+ if (hasTools) return void 0;
17576
+ return void 0;
17577
+ }
17578
+ countTokens(text2) {
17579
+ if (!text2) return 0;
17580
+ return Math.ceil(text2.length / 3.5);
16556
17581
  }
16557
17582
  /**
16558
17583
  * Get context window for the current model
16559
17584
  */
16560
17585
  getContextWindow() {
16561
- const model = this.config.model ?? DEFAULT_MODEL4;
16562
- return CONTEXT_WINDOWS4[model] ?? 128e3;
17586
+ const model2 = this.config.model ?? DEFAULT_MODEL4;
17587
+ const catalogWindow = getCatalogContextWindow("copilot", model2, 0);
17588
+ if (catalogWindow > 0) {
17589
+ return catalogWindow;
17590
+ }
17591
+ return CONTEXT_WINDOWS4[model2] ?? 128e3;
16563
17592
  }
16564
17593
  /**
16565
17594
  * Check if Copilot credentials are available
@@ -16576,7 +17605,8 @@ var CopilotProvider = class extends OpenAIProvider {
16576
17605
 
16577
17606
  // src/providers/gemini.ts
16578
17607
  init_errors();
16579
- var DEFAULT_MODEL5 = "gemini-3.1-pro-preview";
17608
+ init_catalog();
17609
+ var DEFAULT_MODEL5 = getCatalogDefaultModel("gemini");
16580
17610
  var SKIP_THOUGHT_SIGNATURE_VALIDATOR = "skip_thought_signature_validator";
16581
17611
  var CONTEXT_WINDOWS5 = {
16582
17612
  "gemini-3.1-pro-preview": 1e6,
@@ -16640,9 +17670,9 @@ var GeminiProvider = class {
16640
17670
  });
16641
17671
  let streamStopReason = "end_turn";
16642
17672
  for await (const chunk of stream) {
16643
- const text = chunk.text;
16644
- if (text) {
16645
- yield { type: "text", text };
17673
+ const text2 = chunk.text;
17674
+ if (text2) {
17675
+ yield { type: "text", text: text2 };
16646
17676
  }
16647
17677
  const finishReason = chunk.candidates?.[0]?.finishReason;
16648
17678
  if (finishReason) {
@@ -16666,9 +17696,9 @@ var GeminiProvider = class {
16666
17696
  let fallbackToolCounter = 0;
16667
17697
  const emittedToolIds = /* @__PURE__ */ new Set();
16668
17698
  for await (const chunk of stream) {
16669
- const text = chunk.text;
16670
- if (text) {
16671
- yield { type: "text", text };
17699
+ const text2 = chunk.text;
17700
+ if (text2) {
17701
+ yield { type: "text", text: text2 };
16672
17702
  }
16673
17703
  const toolCalls = this.extractToolCalls(chunk, { includeLegacyFunctionCalls: true });
16674
17704
  for (const toolCall of toolCalls) {
@@ -16703,13 +17733,17 @@ var GeminiProvider = class {
16703
17733
  throw this.handleError(error);
16704
17734
  }
16705
17735
  }
16706
- countTokens(text) {
16707
- if (!text) return 0;
16708
- return Math.ceil(text.length / 3.5);
17736
+ countTokens(text2) {
17737
+ if (!text2) return 0;
17738
+ return Math.ceil(text2.length / 3.5);
16709
17739
  }
16710
17740
  getContextWindow() {
16711
- const model = this.config.model ?? DEFAULT_MODEL5;
16712
- return CONTEXT_WINDOWS5[model] ?? 1e6;
17741
+ const model2 = this.config.model ?? DEFAULT_MODEL5;
17742
+ const catalogWindow = getCatalogContextWindow("gemini", model2, 0);
17743
+ if (catalogWindow > 0) {
17744
+ return catalogWindow;
17745
+ }
17746
+ return CONTEXT_WINDOWS5[model2] ?? 1e6;
16713
17747
  }
16714
17748
  async isAvailable() {
16715
17749
  if (!this.client) return false;
@@ -16730,20 +17764,20 @@ var GeminiProvider = class {
16730
17764
  });
16731
17765
  }
16732
17766
  }
16733
- getModel(model) {
16734
- return model ?? this.config.model ?? DEFAULT_MODEL5;
17767
+ getModel(model2) {
17768
+ return model2 ?? this.config.model ?? DEFAULT_MODEL5;
16735
17769
  }
16736
17770
  buildConfig(messages, options, tools, toolChoice) {
16737
- const model = this.getModel(options?.model);
16738
- const thinkingBudget = mapToGeminiBudget(options?.thinking, model);
17771
+ const model2 = this.getModel(options?.model);
17772
+ const thinkingConfig = mapToGeminiThinkingConfig(options?.thinking, model2);
16739
17773
  const config = {
16740
17774
  maxOutputTokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
16741
17775
  temperature: options?.temperature ?? this.config.temperature ?? 0,
16742
17776
  stopSequences: options?.stopSequences,
16743
17777
  systemInstruction: this.extractSystem(messages, options?.system)
16744
17778
  };
16745
- if (thinkingBudget !== void 0) {
16746
- config.thinkingConfig = { thinkingBudget };
17779
+ if (thinkingConfig !== void 0) {
17780
+ config.thinkingConfig = thinkingConfig;
16747
17781
  }
16748
17782
  if (tools && tools.length > 0) {
16749
17783
  config.tools = [{ functionDeclarations: this.convertTools(tools) }];
@@ -16758,8 +17792,8 @@ var GeminiProvider = class {
16758
17792
  const systemMsg = messages.find((m) => m.role === "system");
16759
17793
  if (!systemMsg) return void 0;
16760
17794
  if (typeof systemMsg.content === "string") return systemMsg.content;
16761
- const text = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
16762
- return text || void 0;
17795
+ const text2 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
17796
+ return text2 || void 0;
16763
17797
  }
16764
17798
  convertContents(messages) {
16765
17799
  const toolNameByUseId = this.buildToolUseNameMap(messages);
@@ -16882,7 +17916,7 @@ var GeminiProvider = class {
16882
17916
  })
16883
17917
  }));
16884
17918
  }
16885
- parseResponse(response, model) {
17919
+ parseResponse(response, model2) {
16886
17920
  const usage = response.usageMetadata;
16887
17921
  return {
16888
17922
  id: `gemini-${Date.now()}`,
@@ -16892,10 +17926,10 @@ var GeminiProvider = class {
16892
17926
  inputTokens: usage?.promptTokenCount ?? 0,
16893
17927
  outputTokens: usage?.candidatesTokenCount ?? 0
16894
17928
  },
16895
- model: this.getModel(model)
17929
+ model: this.getModel(model2)
16896
17930
  };
16897
17931
  }
16898
- parseResponseWithTools(response, model) {
17932
+ parseResponseWithTools(response, model2) {
16899
17933
  const usage = response.usageMetadata;
16900
17934
  const toolCalls = this.extractToolCalls(response, { includeLegacyFunctionCalls: true });
16901
17935
  return {
@@ -16906,7 +17940,7 @@ var GeminiProvider = class {
16906
17940
  inputTokens: usage?.promptTokenCount ?? 0,
16907
17941
  outputTokens: usage?.candidatesTokenCount ?? 0
16908
17942
  },
16909
- model: this.getModel(model),
17943
+ model: this.getModel(model2),
16910
17944
  toolCalls
16911
17945
  };
16912
17946
  }
@@ -16945,7 +17979,8 @@ var GeminiProvider = class {
16945
17979
  // src/providers/vertex.ts
16946
17980
  init_errors();
16947
17981
  init_gcloud();
16948
- var DEFAULT_MODEL6 = "gemini-2.5-pro";
17982
+ init_catalog();
17983
+ var DEFAULT_MODEL6 = getCatalogDefaultModel("vertex");
16949
17984
  var DEFAULT_BASE_URL = "https://aiplatform.googleapis.com/v1";
16950
17985
  var DEFAULT_LOCATION = "global";
16951
17986
  var CONTEXT_WINDOWS6 = {
@@ -17091,11 +18126,16 @@ var VertexProvider = class {
17091
18126
  }
17092
18127
  yield { type: "done", stopReason };
17093
18128
  }
17094
- countTokens(text) {
17095
- return Math.ceil(text.length / 4);
18129
+ countTokens(text2) {
18130
+ return Math.ceil(text2.length / 4);
17096
18131
  }
17097
18132
  getContextWindow() {
17098
- return CONTEXT_WINDOWS6[this.config.model ?? DEFAULT_MODEL6] ?? 1048576;
18133
+ const model2 = this.config.model ?? DEFAULT_MODEL6;
18134
+ const catalogWindow = getCatalogContextWindow("vertex", model2, 0);
18135
+ if (catalogWindow > 0) {
18136
+ return catalogWindow;
18137
+ }
18138
+ return CONTEXT_WINDOWS6[model2] ?? 1048576;
17099
18139
  }
17100
18140
  async isAvailable() {
17101
18141
  try {
@@ -17112,8 +18152,8 @@ var VertexProvider = class {
17112
18152
  });
17113
18153
  }
17114
18154
  }
17115
- getModel(model) {
17116
- return model ?? this.config.model ?? DEFAULT_MODEL6;
18155
+ getModel(model2) {
18156
+ return model2 ?? this.config.model ?? DEFAULT_MODEL6;
17117
18157
  }
17118
18158
  getResolvedBaseUrl() {
17119
18159
  if (this.config.baseUrl && this.config.baseUrl.trim()) {
@@ -17124,9 +18164,9 @@ var VertexProvider = class {
17124
18164
  }
17125
18165
  return `https://${encodeURIComponent(this.location)}-aiplatform.googleapis.com/v1`;
17126
18166
  }
17127
- buildEndpoint(model, stream = false) {
18167
+ buildEndpoint(model2, stream = false) {
17128
18168
  const action = stream ? "streamGenerateContent?alt=sse" : "generateContent";
17129
- return `${this.getResolvedBaseUrl()}/projects/${encodeURIComponent(this.project)}/locations/${encodeURIComponent(this.location)}/publishers/google/models/${encodeURIComponent(this.getModel(model))}:${action}`;
18169
+ return `${this.getResolvedBaseUrl()}/projects/${encodeURIComponent(this.project)}/locations/${encodeURIComponent(this.location)}/publishers/google/models/${encodeURIComponent(this.getModel(model2))}:${action}`;
17130
18170
  }
17131
18171
  async getHeaders() {
17132
18172
  if (this.apiKey?.trim()) {
@@ -17154,8 +18194,8 @@ var VertexProvider = class {
17154
18194
  const systemMsg = messages.find((m) => m.role === "system");
17155
18195
  if (!systemMsg) return void 0;
17156
18196
  if (typeof systemMsg.content === "string") return systemMsg.content;
17157
- const text = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
17158
- return text || void 0;
18197
+ const text2 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
18198
+ return text2 || void 0;
17159
18199
  }
17160
18200
  buildToolUseNameMap(messages) {
17161
18201
  const map = /* @__PURE__ */ new Map();
@@ -17338,21 +18378,21 @@ var VertexProvider = class {
17338
18378
  }
17339
18379
  }
17340
18380
  }
17341
- parseResponse(response, model) {
18381
+ parseResponse(response, model2) {
17342
18382
  const candidate = response.candidates?.[0];
17343
- const text = (candidate?.content?.parts ?? []).filter((part) => part.text).map((part) => part.text).join("");
18383
+ const text2 = (candidate?.content?.parts ?? []).filter((part) => part.text).map((part) => part.text).join("");
17344
18384
  return {
17345
18385
  id: `vertex-${Date.now()}`,
17346
- content: text,
18386
+ content: text2,
17347
18387
  stopReason: this.mapFinishReason(candidate?.finishReason),
17348
18388
  usage: {
17349
18389
  inputTokens: response.usageMetadata?.promptTokenCount ?? 0,
17350
18390
  outputTokens: response.usageMetadata?.candidatesTokenCount ?? 0
17351
18391
  },
17352
- model: this.getModel(model)
18392
+ model: this.getModel(model2)
17353
18393
  };
17354
18394
  }
17355
- parseResponseWithTools(response, model) {
18395
+ parseResponseWithTools(response, model2) {
17356
18396
  const candidate = response.candidates?.[0];
17357
18397
  const parts = candidate?.content?.parts ?? [];
17358
18398
  const toolCalls = [];
@@ -17380,7 +18420,7 @@ var VertexProvider = class {
17380
18420
  inputTokens: response.usageMetadata?.promptTokenCount ?? 0,
17381
18421
  outputTokens: response.usageMetadata?.candidatesTokenCount ?? 0
17382
18422
  },
17383
- model: this.getModel(model),
18423
+ model: this.getModel(model2),
17384
18424
  toolCalls
17385
18425
  };
17386
18426
  }
@@ -17409,6 +18449,10 @@ var VertexProvider = class {
17409
18449
  }
17410
18450
  };
17411
18451
 
18452
+ // src/providers/pricing.ts
18453
+ init_catalog();
18454
+ getCatalogModelPricingMap();
18455
+
17412
18456
  // src/providers/circuit-breaker.ts
17413
18457
  init_errors();
17414
18458
  var DEFAULT_CIRCUIT_BREAKER_CONFIG = {
@@ -17614,8 +18658,8 @@ var ResilientProvider = class {
17614
18658
  async *streamWithTools(messages, options) {
17615
18659
  yield* this.streamWithPolicy(() => this.provider.streamWithTools(messages, options));
17616
18660
  }
17617
- countTokens(text) {
17618
- return this.provider.countTokens(text);
18661
+ countTokens(text2) {
18662
+ return this.provider.countTokens(text2);
17619
18663
  }
17620
18664
  getContextWindow() {
17621
18665
  return this.provider.getContextWindow();
@@ -17701,13 +18745,16 @@ function createResilientProvider(provider, config) {
17701
18745
  return new ResilientProvider(provider, getDefaultResilienceConfig(provider.id));
17702
18746
  }
17703
18747
 
18748
+ // src/providers/runtime-capabilities.ts
18749
+ init_catalog();
18750
+
17704
18751
  // src/providers/index.ts
17705
18752
  init_copilot();
17706
18753
  init_errors();
17707
18754
  init_env();
17708
- function normalizeProviderModel(model) {
17709
- if (typeof model !== "string") return void 0;
17710
- const trimmed = model.trim();
18755
+ function normalizeProviderModel(model2) {
18756
+ if (typeof model2 !== "string") return void 0;
18757
+ const trimmed = model2.trim();
17711
18758
  return trimmed.length > 0 ? trimmed : void 0;
17712
18759
  }
17713
18760
  function normalizeOptional(value) {
@@ -17916,9 +18963,9 @@ function createInitialState(config) {
17916
18963
  }
17917
18964
  async function loadExistingState(projectPath) {
17918
18965
  try {
17919
- const fs39 = await import('fs/promises');
18966
+ const fs41 = await import('fs/promises');
17920
18967
  const statePath = `${projectPath}/.coco/state/project.json`;
17921
- const content = await fs39.readFile(statePath, "utf-8");
18968
+ const content = await fs41.readFile(statePath, "utf-8");
17922
18969
  const data = JSON.parse(content);
17923
18970
  data.createdAt = new Date(data.createdAt);
17924
18971
  data.updatedAt = new Date(data.updatedAt);
@@ -17928,13 +18975,13 @@ async function loadExistingState(projectPath) {
17928
18975
  }
17929
18976
  }
17930
18977
  async function saveState(state) {
17931
- const fs39 = await import('fs/promises');
18978
+ const fs41 = await import('fs/promises');
17932
18979
  const statePath = `${state.path}/.coco/state`;
17933
- await fs39.mkdir(statePath, { recursive: true });
18980
+ await fs41.mkdir(statePath, { recursive: true });
17934
18981
  const filePath = `${statePath}/project.json`;
17935
18982
  const tmpPath = `${filePath}.tmp.${Date.now()}`;
17936
- await fs39.writeFile(tmpPath, JSON.stringify(state, null, 2), "utf-8");
17937
- await fs39.rename(tmpPath, filePath);
18983
+ await fs41.writeFile(tmpPath, JSON.stringify(state, null, 2), "utf-8");
18984
+ await fs41.rename(tmpPath, filePath);
17938
18985
  }
17939
18986
  function getPhaseExecutor(phase) {
17940
18987
  switch (phase) {
@@ -17993,35 +19040,35 @@ async function createPhaseContext(config, state) {
17993
19040
  };
17994
19041
  const tools = {
17995
19042
  file: {
17996
- async read(path42) {
17997
- const fs39 = await import('fs/promises');
17998
- return fs39.readFile(path42, "utf-8");
19043
+ async read(path44) {
19044
+ const fs41 = await import('fs/promises');
19045
+ return fs41.readFile(path44, "utf-8");
17999
19046
  },
18000
- async write(path42, content) {
18001
- const fs39 = await import('fs/promises');
19047
+ async write(path44, content) {
19048
+ const fs41 = await import('fs/promises');
18002
19049
  const nodePath = await import('path');
18003
- await fs39.mkdir(nodePath.dirname(path42), { recursive: true });
18004
- await fs39.writeFile(path42, content, "utf-8");
19050
+ await fs41.mkdir(nodePath.dirname(path44), { recursive: true });
19051
+ await fs41.writeFile(path44, content, "utf-8");
18005
19052
  },
18006
- async exists(path42) {
18007
- const fs39 = await import('fs/promises');
19053
+ async exists(path44) {
19054
+ const fs41 = await import('fs/promises');
18008
19055
  try {
18009
- await fs39.access(path42);
19056
+ await fs41.access(path44);
18010
19057
  return true;
18011
19058
  } catch {
18012
19059
  return false;
18013
19060
  }
18014
19061
  },
18015
19062
  async glob(pattern) {
18016
- const { glob: glob17 } = await import('glob');
18017
- return glob17(pattern, { cwd: state.path });
19063
+ const { glob: glob18 } = await import('glob');
19064
+ return glob18(pattern, { cwd: state.path });
18018
19065
  }
18019
19066
  },
18020
19067
  bash: {
18021
19068
  async exec(command, options = {}) {
18022
- const { execa: execa11 } = await import('execa');
19069
+ const { execa: execa12 } = await import('execa');
18023
19070
  try {
18024
- const result = await execa11(command, {
19071
+ const result = await execa12(command, {
18025
19072
  shell: true,
18026
19073
  cwd: options.cwd || state.path,
18027
19074
  timeout: options.timeout,
@@ -18044,8 +19091,8 @@ async function createPhaseContext(config, state) {
18044
19091
  },
18045
19092
  git: {
18046
19093
  async status() {
18047
- const { execa: execa11 } = await import('execa');
18048
- const result = await execa11("git", ["status", "--porcelain", "-b"], { cwd: state.path });
19094
+ const { execa: execa12 } = await import('execa');
19095
+ const result = await execa12("git", ["status", "--porcelain", "-b"], { cwd: state.path });
18049
19096
  const lines = result.stdout.split("\n");
18050
19097
  const branchLine = lines[0] || "";
18051
19098
  const branch = branchLine.replace("## ", "").split("...")[0] || "main";
@@ -18058,24 +19105,24 @@ async function createPhaseContext(config, state) {
18058
19105
  };
18059
19106
  },
18060
19107
  async commit(message, files) {
18061
- const { execa: execa11 } = await import('execa');
19108
+ const { execa: execa12 } = await import('execa');
18062
19109
  if (files && files.length > 0) {
18063
- await execa11("git", ["add", ...files], { cwd: state.path });
19110
+ await execa12("git", ["add", ...files], { cwd: state.path });
18064
19111
  }
18065
- await execa11("git", ["commit", "-m", message], { cwd: state.path });
19112
+ await execa12("git", ["commit", "-m", message], { cwd: state.path });
18066
19113
  },
18067
19114
  async push() {
18068
- const { execa: execa11 } = await import('execa');
18069
- await execa11("git", ["push"], { cwd: state.path });
19115
+ const { execa: execa12 } = await import('execa');
19116
+ await execa12("git", ["push"], { cwd: state.path });
18070
19117
  }
18071
19118
  },
18072
19119
  test: {
18073
19120
  async run(pattern) {
18074
- const { execa: execa11 } = await import('execa');
19121
+ const { execa: execa12 } = await import('execa');
18075
19122
  try {
18076
19123
  const args = ["test", "--reporter=json"];
18077
19124
  if (pattern) args.push(pattern);
18078
- await execa11("pnpm", args, { cwd: state.path });
19125
+ await execa12("pnpm", args, { cwd: state.path });
18079
19126
  return {
18080
19127
  passed: 0,
18081
19128
  failed: 0,
@@ -18155,9 +19202,9 @@ async function createSnapshot(state) {
18155
19202
  var MAX_CHECKPOINT_VERSIONS = 5;
18156
19203
  async function getCheckpointFiles(state, phase) {
18157
19204
  try {
18158
- const fs39 = await import('fs/promises');
19205
+ const fs41 = await import('fs/promises');
18159
19206
  const checkpointDir = `${state.path}/.coco/checkpoints`;
18160
- const files = await fs39.readdir(checkpointDir);
19207
+ const files = await fs41.readdir(checkpointDir);
18161
19208
  const phaseFiles = files.filter((f) => f.startsWith(`snapshot-pre-${phase}-`) && f.endsWith(".json")).sort((a, b) => {
18162
19209
  const tsA = parseInt(a.split("-").pop()?.replace(".json", "") ?? "0", 10);
18163
19210
  const tsB = parseInt(b.split("-").pop()?.replace(".json", "") ?? "0", 10);
@@ -18170,11 +19217,11 @@ async function getCheckpointFiles(state, phase) {
18170
19217
  }
18171
19218
  async function cleanupOldCheckpoints(state, phase) {
18172
19219
  try {
18173
- const fs39 = await import('fs/promises');
19220
+ const fs41 = await import('fs/promises');
18174
19221
  const files = await getCheckpointFiles(state, phase);
18175
19222
  if (files.length > MAX_CHECKPOINT_VERSIONS) {
18176
19223
  const filesToDelete = files.slice(MAX_CHECKPOINT_VERSIONS);
18177
- await Promise.all(filesToDelete.map((f) => fs39.unlink(f).catch(() => {
19224
+ await Promise.all(filesToDelete.map((f) => fs41.unlink(f).catch(() => {
18178
19225
  })));
18179
19226
  }
18180
19227
  } catch {
@@ -18182,13 +19229,13 @@ async function cleanupOldCheckpoints(state, phase) {
18182
19229
  }
18183
19230
  async function saveSnapshot(state, snapshotId) {
18184
19231
  try {
18185
- const fs39 = await import('fs/promises');
19232
+ const fs41 = await import('fs/promises');
18186
19233
  const snapshotPath = `${state.path}/.coco/checkpoints/snapshot-${snapshotId}.json`;
18187
19234
  const snapshotDir = `${state.path}/.coco/checkpoints`;
18188
- await fs39.mkdir(snapshotDir, { recursive: true });
19235
+ await fs41.mkdir(snapshotDir, { recursive: true });
18189
19236
  const createdAt = state.createdAt instanceof Date ? state.createdAt.toISOString() : String(state.createdAt);
18190
19237
  const updatedAt = state.updatedAt instanceof Date ? state.updatedAt.toISOString() : String(state.updatedAt);
18191
- await fs39.writeFile(
19238
+ await fs41.writeFile(
18192
19239
  snapshotPath,
18193
19240
  JSON.stringify(
18194
19241
  {
@@ -19395,15 +20442,15 @@ ${message}
19395
20442
  let stdoutBuffer = "";
19396
20443
  let stderrBuffer = "";
19397
20444
  subprocess.stdout?.on("data", (chunk) => {
19398
- const text = chunk.toString();
19399
- stdoutBuffer += text;
19400
- process.stdout.write(text);
20445
+ const text2 = chunk.toString();
20446
+ stdoutBuffer += text2;
20447
+ process.stdout.write(text2);
19401
20448
  heartbeat.activity();
19402
20449
  });
19403
20450
  subprocess.stderr?.on("data", (chunk) => {
19404
- const text = chunk.toString();
19405
- stderrBuffer += text;
19406
- process.stderr.write(text);
20451
+ const text2 = chunk.toString();
20452
+ stderrBuffer += text2;
20453
+ process.stderr.write(text2);
19407
20454
  heartbeat.activity();
19408
20455
  });
19409
20456
  const result = await subprocess;
@@ -20888,7 +21935,7 @@ Examples:
20888
21935
  }
20889
21936
  });
20890
21937
  async function findSourceFiles(cwd) {
20891
- const { glob: glob17 } = await import('glob');
21938
+ const { glob: glob18 } = await import('glob');
20892
21939
  let isJava = false;
20893
21940
  try {
20894
21941
  await fs16__default.access(path17__default.join(cwd, "pom.xml"));
@@ -20906,12 +21953,12 @@ async function findSourceFiles(cwd) {
20906
21953
  }
20907
21954
  }
20908
21955
  if (isJava) {
20909
- return glob17("src/main/java/**/*.java", {
21956
+ return glob18("src/main/java/**/*.java", {
20910
21957
  cwd,
20911
21958
  absolute: true
20912
21959
  });
20913
21960
  }
20914
- return glob17("src/**/*.{ts,js,tsx,jsx}", {
21961
+ return glob18("src/**/*.{ts,js,tsx,jsx}", {
20915
21962
  cwd,
20916
21963
  absolute: true,
20917
21964
  ignore: ["**/*.test.*", "**/*.spec.*", "**/node_modules/**"]
@@ -21424,15 +22471,15 @@ ${message}
21424
22471
  let stdoutBuffer = "";
21425
22472
  let stderrBuffer = "";
21426
22473
  subprocess.stdout?.on("data", (chunk) => {
21427
- const text = chunk.toString();
21428
- stdoutBuffer += text;
21429
- process.stdout.write(text);
22474
+ const text2 = chunk.toString();
22475
+ stdoutBuffer += text2;
22476
+ process.stdout.write(text2);
21430
22477
  heartbeat.activity();
21431
22478
  });
21432
22479
  subprocess.stderr?.on("data", (chunk) => {
21433
- const text = chunk.toString();
21434
- stderrBuffer += text;
21435
- process.stderr.write(text);
22480
+ const text2 = chunk.toString();
22481
+ stderrBuffer += text2;
22482
+ process.stderr.write(text2);
21436
22483
  heartbeat.activity();
21437
22484
  });
21438
22485
  const result = await subprocess;
@@ -21549,15 +22596,15 @@ ${message}
21549
22596
  let stdoutBuffer = "";
21550
22597
  let stderrBuffer = "";
21551
22598
  subprocess.stdout?.on("data", (chunk) => {
21552
- const text = chunk.toString();
21553
- stdoutBuffer += text;
21554
- process.stdout.write(text);
22599
+ const text2 = chunk.toString();
22600
+ stdoutBuffer += text2;
22601
+ process.stdout.write(text2);
21555
22602
  heartbeat.activity();
21556
22603
  });
21557
22604
  subprocess.stderr?.on("data", (chunk) => {
21558
- const text = chunk.toString();
21559
- stderrBuffer += text;
21560
- process.stderr.write(text);
22605
+ const text2 = chunk.toString();
22606
+ stderrBuffer += text2;
22607
+ process.stderr.write(text2);
21561
22608
  heartbeat.activity();
21562
22609
  });
21563
22610
  const result = await subprocess;
@@ -21651,15 +22698,15 @@ ${message}
21651
22698
  let stdoutBuffer = "";
21652
22699
  let stderrBuffer = "";
21653
22700
  subprocess.stdout?.on("data", (chunk) => {
21654
- const text = chunk.toString();
21655
- stdoutBuffer += text;
21656
- process.stdout.write(text);
22701
+ const text2 = chunk.toString();
22702
+ stdoutBuffer += text2;
22703
+ process.stdout.write(text2);
21657
22704
  heartbeat.activity();
21658
22705
  });
21659
22706
  subprocess.stderr?.on("data", (chunk) => {
21660
- const text = chunk.toString();
21661
- stderrBuffer += text;
21662
- process.stderr.write(text);
22707
+ const text2 = chunk.toString();
22708
+ stderrBuffer += text2;
22709
+ process.stderr.write(text2);
21663
22710
  heartbeat.activity();
21664
22711
  });
21665
22712
  const result = await subprocess;
@@ -21754,15 +22801,15 @@ ${message}
21754
22801
  let stdoutBuffer = "";
21755
22802
  let stderrBuffer = "";
21756
22803
  subprocess.stdout?.on("data", (chunk) => {
21757
- const text = chunk.toString();
21758
- stdoutBuffer += text;
21759
- process.stdout.write(text);
22804
+ const text2 = chunk.toString();
22805
+ stdoutBuffer += text2;
22806
+ process.stdout.write(text2);
21760
22807
  heartbeat.activity();
21761
22808
  });
21762
22809
  subprocess.stderr?.on("data", (chunk) => {
21763
- const text = chunk.toString();
21764
- stderrBuffer += text;
21765
- process.stderr.write(text);
22810
+ const text2 = chunk.toString();
22811
+ stderrBuffer += text2;
22812
+ process.stderr.write(text2);
21766
22813
  heartbeat.activity();
21767
22814
  });
21768
22815
  const result = await subprocess;
@@ -21858,15 +22905,15 @@ ${message}
21858
22905
  let stdoutBuffer = "";
21859
22906
  let stderrBuffer = "";
21860
22907
  subprocess.stdout?.on("data", (chunk) => {
21861
- const text = chunk.toString();
21862
- stdoutBuffer += text;
21863
- process.stdout.write(text);
22908
+ const text2 = chunk.toString();
22909
+ stdoutBuffer += text2;
22910
+ process.stdout.write(text2);
21864
22911
  heartbeat.activity();
21865
22912
  });
21866
22913
  subprocess.stderr?.on("data", (chunk) => {
21867
- const text = chunk.toString();
21868
- stderrBuffer += text;
21869
- process.stderr.write(text);
22914
+ const text2 = chunk.toString();
22915
+ stderrBuffer += text2;
22916
+ process.stderr.write(text2);
21870
22917
  heartbeat.activity();
21871
22918
  });
21872
22919
  const result = await subprocess;
@@ -21945,15 +22992,15 @@ ${message}
21945
22992
  let stdoutBuffer = "";
21946
22993
  let stderrBuffer = "";
21947
22994
  subprocess.stdout?.on("data", (chunk) => {
21948
- const text = chunk.toString();
21949
- stdoutBuffer += text;
21950
- process.stdout.write(text);
22995
+ const text2 = chunk.toString();
22996
+ stdoutBuffer += text2;
22997
+ process.stdout.write(text2);
21951
22998
  heartbeat.activity();
21952
22999
  });
21953
23000
  subprocess.stderr?.on("data", (chunk) => {
21954
- const text = chunk.toString();
21955
- stderrBuffer += text;
21956
- process.stderr.write(text);
23001
+ const text2 = chunk.toString();
23002
+ stderrBuffer += text2;
23003
+ process.stderr.write(text2);
21957
23004
  heartbeat.activity();
21958
23005
  });
21959
23006
  const result = await subprocess;
@@ -22012,6 +23059,12 @@ z.object({
22012
23059
  "allowed-tools": z.union([z.string(), z.array(z.string())]).optional(),
22013
23060
  "argument-hint": z.string().optional(),
22014
23061
  compatibility: z.string().max(500).optional(),
23062
+ triggers: z.union([z.string(), z.array(z.string())]).optional(),
23063
+ risk: z.enum(["read-only", "write", "network", "destructive", "secrets-sensitive"]).optional(),
23064
+ "supported-agents": z.union([
23065
+ z.enum(["coco", "claude", "codex", "gemini", "opencode"]),
23066
+ z.array(z.enum(["coco", "claude", "codex", "gemini", "opencode"]))
23067
+ ]).optional(),
22015
23068
  model: z.string().optional(),
22016
23069
  context: z.enum(["fork", "agent", "inline"]).optional(),
22017
23070
  // Top-level tags/author (skills.sh style) — also accepted inside metadata
@@ -22814,16 +23867,16 @@ function htmlToMarkdown(html) {
22814
23867
  const prefix = "#".repeat(i);
22815
23868
  const regex = new RegExp(`<h${i}[^>]*>([\\s\\S]*?)<\\/h${i}>`, "gi");
22816
23869
  md = md.replace(regex, (_, content) => {
22817
- const text = content.replace(/<[^>]*>/g, "").trim();
22818
- return text ? `
23870
+ const text2 = content.replace(/<[^>]*>/g, "").trim();
23871
+ return text2 ? `
22819
23872
 
22820
- ${prefix} ${text}
23873
+ ${prefix} ${text2}
22821
23874
 
22822
23875
  ` : "";
22823
23876
  });
22824
23877
  }
22825
- md = md.replace(/<a\s+[^>]*href=["']([^"']+)["'][^>]*>([\s\S]*?)<\/a>/gi, (_, href, text) => {
22826
- const cleanText = text.replace(/<[^>]*>/g, "").trim();
23878
+ md = md.replace(/<a\s+[^>]*href=["']([^"']+)["'][^>]*>([\s\S]*?)<\/a>/gi, (_, href, text2) => {
23879
+ const cleanText = text2.replace(/<[^>]*>/g, "").trim();
22827
23880
  if (!cleanText) return "";
22828
23881
  if (href.startsWith("#") || href.startsWith("javascript:")) return cleanText;
22829
23882
  return `[${cleanText}](${href})`;
@@ -22850,8 +23903,8 @@ ${decoded.trim()}
22850
23903
  });
22851
23904
  md = md.replace(/<ul[^>]*>([\s\S]*?)<\/ul>/gi, (_, items) => {
22852
23905
  return "\n" + items.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, (_2, item) => {
22853
- const text = item.replace(/<[^>]*>/g, "").trim();
22854
- return text ? `- ${text}
23906
+ const text2 = item.replace(/<[^>]*>/g, "").trim();
23907
+ return text2 ? `- ${text2}
22855
23908
  ` : "";
22856
23909
  }) + "\n";
22857
23910
  });
@@ -22859,29 +23912,29 @@ ${decoded.trim()}
22859
23912
  let counter = 0;
22860
23913
  return "\n" + items.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, (_2, item) => {
22861
23914
  counter++;
22862
- const text = item.replace(/<[^>]*>/g, "").trim();
22863
- return text ? `${counter}. ${text}
23915
+ const text2 = item.replace(/<[^>]*>/g, "").trim();
23916
+ return text2 ? `${counter}. ${text2}
22864
23917
  ` : "";
22865
23918
  }) + "\n";
22866
23919
  });
22867
23920
  md = md.replace(/<blockquote[^>]*>([\s\S]*?)<\/blockquote>/gi, (_, content) => {
22868
- const text = content.replace(/<[^>]*>/g, "").trim();
22869
- return text ? "\n" + text.split("\n").map((line) => `> ${line.trim()}`).join("\n") + "\n" : "";
23921
+ const text2 = content.replace(/<[^>]*>/g, "").trim();
23922
+ return text2 ? "\n" + text2.split("\n").map((line) => `> ${line.trim()}`).join("\n") + "\n" : "";
22870
23923
  });
22871
23924
  md = md.replace(/<p[^>]*>([\s\S]*?)<\/p>/gi, (_, content) => {
22872
- const text = content.replace(/<[^>]*>/g, "").trim();
22873
- return text ? `
23925
+ const text2 = content.replace(/<[^>]*>/g, "").trim();
23926
+ return text2 ? `
22874
23927
 
22875
- ${text}
23928
+ ${text2}
22876
23929
 
22877
23930
  ` : "";
22878
23931
  });
22879
23932
  md = md.replace(/<br\s*\/?>/gi, "\n");
22880
23933
  md = md.replace(
22881
23934
  /<(?:strong|b)[^>]*>([\s\S]*?)<\/(?:strong|b)>/gi,
22882
- (_, text) => `**${text.trim()}**`
23935
+ (_, text2) => `**${text2.trim()}**`
22883
23936
  );
22884
- md = md.replace(/<(?:em|i)[^>]*>([\s\S]*?)<\/(?:em|i)>/gi, (_, text) => `*${text.trim()}*`);
23937
+ md = md.replace(/<(?:em|i)[^>]*>([\s\S]*?)<\/(?:em|i)>/gi, (_, text2) => `*${text2.trim()}*`);
22885
23938
  md = md.replace(/<hr\s*\/?>/gi, "\n---\n");
22886
23939
  md = md.replace(/<table[^>]*>([\s\S]*?)<\/table>/gi, (_, tableContent) => {
22887
23940
  const rows = [];
@@ -23563,9 +24616,9 @@ async function fileExists(filePath) {
23563
24616
  return false;
23564
24617
  }
23565
24618
  }
23566
- async function fileExists2(path42) {
24619
+ async function fileExists2(path44) {
23567
24620
  try {
23568
- await access(path42);
24621
+ await access(path44);
23569
24622
  return true;
23570
24623
  } catch {
23571
24624
  return false;
@@ -23655,7 +24708,7 @@ async function detectMaturity(cwd) {
23655
24708
  if (!hasLintConfig && hasPackageJson) {
23656
24709
  try {
23657
24710
  const pkgRaw = await import('fs/promises').then(
23658
- (fs39) => fs39.readFile(join(cwd, "package.json"), "utf-8")
24711
+ (fs41) => fs41.readFile(join(cwd, "package.json"), "utf-8")
23659
24712
  );
23660
24713
  const pkg = JSON.parse(pkgRaw);
23661
24714
  if (pkg.scripts?.lint || pkg.scripts?.["lint:fix"]) {
@@ -24499,9 +25552,10 @@ Examples:
24499
25552
  exclude: z.array(z.string()).optional().describe("Additional patterns to exclude"),
24500
25553
  languages: z.array(z.enum(["typescript", "javascript", "python", "java", "go", "rust"])).optional().describe("Languages to parse (auto-detected if not specified)"),
24501
25554
  maxFiles: z.number().min(1).max(1e3).optional().default(DEFAULT_MAX_FILES).describe("Maximum files to process"),
24502
- depth: z.enum(["overview", "detailed"]).optional().default("overview").describe("Level of detail")
25555
+ depth: z.enum(["overview", "detailed"]).optional().default("overview").describe("Level of detail"),
25556
+ includeTests: z.boolean().optional().default(false).describe("Include test/spec files in the map")
24503
25557
  }),
24504
- async execute({ path: rootPath, include, exclude, languages, maxFiles, depth }) {
25558
+ async execute({ path: rootPath, include, exclude, languages, maxFiles, depth, includeTests }) {
24505
25559
  const startTime = performance.now();
24506
25560
  const absPath = path27.resolve(rootPath);
24507
25561
  try {
@@ -24529,7 +25583,12 @@ Examples:
24529
25583
  const allExts = Object.values(LANGUAGE_EXTENSIONS).flat();
24530
25584
  pattern = `**/*{${allExts.join(",")}}`;
24531
25585
  }
24532
- const excludePatterns = [...DEFAULT_EXCLUDES, ...exclude ?? []];
25586
+ const excludePatterns = [
25587
+ ...DEFAULT_EXCLUDES.filter(
25588
+ (pattern2) => includeTests ? !pattern2.includes("*.test.") && !pattern2.includes("*.spec.") : true
25589
+ ),
25590
+ ...exclude ?? []
25591
+ ];
24533
25592
  const files = await glob14(pattern, {
24534
25593
  cwd: absPath,
24535
25594
  ignore: excludePatterns,
@@ -25027,10 +26086,10 @@ function chunkContent(content, chunkSize) {
25027
26086
  const chunks = [];
25028
26087
  for (let i = 0; i < lines.length; i += chunkSize) {
25029
26088
  const chunkLines = lines.slice(i, Math.min(i + chunkSize, lines.length));
25030
- const text = chunkLines.join("\n").trim();
25031
- if (text.length > 10) {
26089
+ const text2 = chunkLines.join("\n").trim();
26090
+ if (text2.length > 10) {
25032
26091
  chunks.push({
25033
- text,
26092
+ text: text2,
25034
26093
  startLine: i + 1,
25035
26094
  endLine: Math.min(i + chunkSize, lines.length)
25036
26095
  });
@@ -25038,8 +26097,8 @@ function chunkContent(content, chunkSize) {
25038
26097
  }
25039
26098
  return chunks;
25040
26099
  }
25041
- function simpleEmbedding(text) {
25042
- const words = text.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter((w) => w.length > 1);
26100
+ function simpleEmbedding(text2) {
26101
+ const words = text2.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter((w) => w.length > 1);
25043
26102
  const freq = /* @__PURE__ */ new Map();
25044
26103
  for (const word of words) {
25045
26104
  freq.set(word, (freq.get(word) ?? 0) + 1);
@@ -25065,7 +26124,7 @@ function simpleEmbedding(text) {
25065
26124
  }
25066
26125
  var embedFn = null;
25067
26126
  var usingFallbackEmbedding = false;
25068
- async function getEmbedding(text) {
26127
+ async function getEmbedding(text2) {
25069
26128
  if (!embedFn) {
25070
26129
  try {
25071
26130
  const transformers = await import('@xenova/transformers');
@@ -25082,7 +26141,7 @@ async function getEmbedding(text) {
25082
26141
  usingFallbackEmbedding = true;
25083
26142
  }
25084
26143
  }
25085
- return embedFn(text);
26144
+ return embedFn(text2);
25086
26145
  }
25087
26146
  async function loadIndex2(indexDir) {
25088
26147
  try {
@@ -25629,23 +26688,23 @@ Examples:
25629
26688
  const pdfData = await pdfParse.default(dataBuffer, {
25630
26689
  max: maxPages
25631
26690
  });
25632
- let text = pdfData.text;
26691
+ let text2 = pdfData.text;
25633
26692
  let truncated = false;
25634
26693
  const totalPages = pdfData.numpages;
25635
26694
  if (pages) {
25636
26695
  const range = parsePageRange(pages, totalPages);
25637
- const pageTexts = text.split(/\f/);
26696
+ const pageTexts = text2.split(/\f/);
25638
26697
  if (pageTexts.length > 1) {
25639
26698
  const selectedPages = pageTexts.slice(range.start - 1, range.end);
25640
- text = selectedPages.join("\n\n--- Page Break ---\n\n");
26699
+ text2 = selectedPages.join("\n\n--- Page Break ---\n\n");
25641
26700
  }
25642
26701
  }
25643
- if (text.length > 5e5) {
25644
- text = text.slice(0, 5e5);
26702
+ if (text2.length > 5e5) {
26703
+ text2 = text2.slice(0, 5e5);
25645
26704
  truncated = true;
25646
26705
  }
25647
26706
  return {
25648
- text,
26707
+ text: text2,
25649
26708
  pages: totalPages,
25650
26709
  metadata: {
25651
26710
  title: pdfData.info?.Title,
@@ -25744,14 +26803,14 @@ Examples:
25744
26803
  const mimeType = MIME_TYPES[ext] ?? "image/png";
25745
26804
  const selectedProvider = provider ?? "anthropic";
25746
26805
  let description;
25747
- let model;
26806
+ let model2;
25748
26807
  try {
25749
26808
  if (selectedProvider === "anthropic") {
25750
- model = "claude-sonnet-4-20250514";
26809
+ model2 = "claude-sonnet-4-20250514";
25751
26810
  const { default: Anthropic2 } = await import('@anthropic-ai/sdk');
25752
26811
  const client = new Anthropic2();
25753
26812
  const response = await client.messages.create({
25754
- model,
26813
+ model: model2,
25755
26814
  max_tokens: 4096,
25756
26815
  messages: [
25757
26816
  {
@@ -25775,7 +26834,7 @@ Examples:
25775
26834
  });
25776
26835
  description = response.content.filter((block) => block.type === "text").map((block) => block.text).join("\n") || "No description generated";
25777
26836
  } else if (selectedProvider === "openai") {
25778
- model = "gpt-4o";
26837
+ model2 = "gpt-4o";
25779
26838
  const { default: OpenAI3 } = await import('openai');
25780
26839
  const client = new OpenAI3();
25781
26840
  const openaiMessages = [
@@ -25796,13 +26855,13 @@ Examples:
25796
26855
  }
25797
26856
  ];
25798
26857
  const response = await client.chat.completions.create({
25799
- model,
26858
+ model: model2,
25800
26859
  max_tokens: 4096,
25801
26860
  messages: openaiMessages
25802
26861
  });
25803
26862
  description = response.choices[0]?.message?.content ?? "No description generated";
25804
26863
  } else if (selectedProvider === "gemini") {
25805
- model = "gemini-2.0-flash";
26864
+ model2 = "gemini-2.0-flash";
25806
26865
  const { GoogleGenAI: GoogleGenAI2 } = await import('@google/genai');
25807
26866
  const apiKey = process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;
25808
26867
  if (!apiKey) {
@@ -25813,7 +26872,7 @@ Examples:
25813
26872
  }
25814
26873
  const genAI = new GoogleGenAI2({ apiKey });
25815
26874
  const result = await genAI.models.generateContent({
25816
- model,
26875
+ model: model2,
25817
26876
  contents: [
25818
26877
  {
25819
26878
  role: "user",
@@ -25856,7 +26915,7 @@ Examples:
25856
26915
  return {
25857
26916
  description,
25858
26917
  provider: selectedProvider,
25859
- model,
26918
+ model: model2,
25860
26919
  duration: performance.now() - startTime,
25861
26920
  imageSize: imageBuffer.length,
25862
26921
  format: ext.slice(1)
@@ -26136,8 +27195,8 @@ async function analyzeFile(filePath, includeAst = false) {
26136
27195
  };
26137
27196
  }
26138
27197
  async function analyzeDirectory(dirPath) {
26139
- const { glob: glob17 } = await import('glob');
26140
- const files = await glob17("**/*.{ts,tsx,js,jsx}", {
27198
+ const { glob: glob18 } = await import('glob');
27199
+ const files = await glob18("**/*.{ts,tsx,js,jsx}", {
26141
27200
  cwd: dirPath,
26142
27201
  ignore: ["**/node_modules/**", "**/dist/**", "**/build/**"],
26143
27202
  absolute: true
@@ -26209,6 +27268,329 @@ var analyzeDirectoryTool = defineTool({
26209
27268
  }
26210
27269
  });
26211
27270
  var codeAnalyzerTools = [analyzeFileTool, analyzeDirectoryTool];
27271
+ var SOURCE_GLOBS = ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "**/*.mjs", "**/*.cjs"];
27272
+ var DEFAULT_EXCLUDES3 = [
27273
+ "**/node_modules/**",
27274
+ "**/.git/**",
27275
+ "**/dist/**",
27276
+ "**/build/**",
27277
+ "**/coverage/**",
27278
+ "**/*.d.ts"
27279
+ ];
27280
+ async function commandAvailable(command) {
27281
+ try {
27282
+ await execa(command, ["--version"], { timeout: 3e3 });
27283
+ return true;
27284
+ } catch {
27285
+ return false;
27286
+ }
27287
+ }
27288
+ async function getSourceFiles(root, maxFiles) {
27289
+ const files = await glob(SOURCE_GLOBS, {
27290
+ cwd: root,
27291
+ absolute: false,
27292
+ ignore: DEFAULT_EXCLUDES3,
27293
+ nodir: true
27294
+ });
27295
+ return files.slice(0, maxFiles);
27296
+ }
27297
+ async function getFileSymbols(filePath) {
27298
+ const absolutePath = path17__default.resolve(filePath);
27299
+ const content = await fs16__default.readFile(absolutePath, "utf-8");
27300
+ const language = detectLanguage3(absolutePath);
27301
+ if (language !== "typescript" && language !== "javascript") {
27302
+ return [];
27303
+ }
27304
+ return parseTypeScript(content).definitions.map((definition) => ({
27305
+ file: filePath,
27306
+ name: definition.name,
27307
+ type: definition.type,
27308
+ line: definition.line,
27309
+ exported: definition.exported,
27310
+ signature: definition.signature
27311
+ }));
27312
+ }
27313
+ var lspStatusTool = defineTool({
27314
+ name: "lsp_status",
27315
+ description: "Check optional language-server availability. Use before LSP-style navigation when you need to know whether Coco is using static fallbacks.",
27316
+ category: "search",
27317
+ parameters: z.object({}),
27318
+ async execute() {
27319
+ return {
27320
+ languageServers: [
27321
+ {
27322
+ name: "typescript-language-server",
27323
+ available: await commandAvailable("typescript-language-server")
27324
+ },
27325
+ { name: "tsserver", available: await commandAvailable("tsserver") }
27326
+ ],
27327
+ fallbackMode: "static-analysis"
27328
+ };
27329
+ }
27330
+ });
27331
+ var lspDocumentSymbolsTool = defineTool({
27332
+ name: "lsp_document_symbols",
27333
+ description: "Return LSP-style document symbols for a TypeScript/JavaScript file using static analysis fallback.",
27334
+ category: "search",
27335
+ parameters: z.object({
27336
+ file: z.string().describe("File path to inspect")
27337
+ }),
27338
+ async execute({ file }) {
27339
+ return { symbols: await getFileSymbols(file) };
27340
+ }
27341
+ });
27342
+ var lspWorkspaceSymbolsTool = defineTool({
27343
+ name: "lsp_workspace_symbols",
27344
+ description: "Find LSP-style workspace symbols by name across TypeScript/JavaScript files using static analysis fallback.",
27345
+ category: "search",
27346
+ parameters: z.object({
27347
+ query: z.string().describe("Symbol name or substring to find"),
27348
+ path: z.string().optional().describe("Workspace directory, defaults to cwd"),
27349
+ maxFiles: z.number().optional().default(300),
27350
+ maxResults: z.number().optional().default(100)
27351
+ }),
27352
+ async execute({ query, path: workspacePath, maxFiles = 300, maxResults = 100 }) {
27353
+ const root = path17__default.resolve(workspacePath ?? process.cwd());
27354
+ const files = await getSourceFiles(root, maxFiles);
27355
+ const lowerQuery = query.toLowerCase();
27356
+ const symbols = [];
27357
+ for (const file of files) {
27358
+ const fileSymbols = await getFileSymbols(path17__default.join(root, file));
27359
+ for (const symbol of fileSymbols) {
27360
+ if (!symbol.name.toLowerCase().includes(lowerQuery)) continue;
27361
+ symbols.push({ ...symbol, file });
27362
+ if (symbols.length >= maxResults) {
27363
+ return { symbols, searchedFiles: files.length, truncated: true };
27364
+ }
27365
+ }
27366
+ }
27367
+ return { symbols, searchedFiles: files.length, truncated: false };
27368
+ }
27369
+ });
27370
+ var lspDefinitionTool = defineTool({
27371
+ name: "lsp_definition",
27372
+ description: "Find the likely definition of a symbol using exported symbols first, then local definitions.",
27373
+ category: "search",
27374
+ parameters: z.object({
27375
+ symbol: z.string().describe("Exact symbol name to locate"),
27376
+ path: z.string().optional().describe("Workspace directory, defaults to cwd"),
27377
+ maxFiles: z.number().optional().default(300)
27378
+ }),
27379
+ async execute({ symbol, path: workspacePath, maxFiles = 300 }) {
27380
+ const root = path17__default.resolve(workspacePath ?? process.cwd());
27381
+ const files = await getSourceFiles(root, maxFiles);
27382
+ const candidates = [];
27383
+ for (const file of files) {
27384
+ const fileSymbols = await getFileSymbols(path17__default.join(root, file));
27385
+ for (const candidate of fileSymbols) {
27386
+ if (candidate.name !== symbol) continue;
27387
+ candidates.push({ ...candidate, file });
27388
+ }
27389
+ }
27390
+ const definition = candidates.find((candidate) => candidate.exported) ?? candidates[0];
27391
+ return { definition, candidates };
27392
+ }
27393
+ });
27394
+ var lspReferencesTool = defineTool({
27395
+ name: "lsp_references",
27396
+ description: "Find likely references to a symbol across TypeScript/JavaScript files using whole-word text search.",
27397
+ category: "search",
27398
+ parameters: z.object({
27399
+ symbol: z.string().describe("Symbol name to find"),
27400
+ path: z.string().optional().describe("Workspace directory, defaults to cwd"),
27401
+ maxFiles: z.number().optional().default(300),
27402
+ maxResults: z.number().optional().default(100)
27403
+ }),
27404
+ async execute({ symbol, path: workspacePath, maxFiles = 300, maxResults = 100 }) {
27405
+ const root = path17__default.resolve(workspacePath ?? process.cwd());
27406
+ const files = await getSourceFiles(root, maxFiles);
27407
+ const pattern = new RegExp(`\\b${escapeRegExp(symbol)}\\b`);
27408
+ const references = [];
27409
+ for (const file of files) {
27410
+ const absolutePath = path17__default.join(root, file);
27411
+ const content = await fs16__default.readFile(absolutePath, "utf-8");
27412
+ const lines = content.split("\n");
27413
+ for (let index = 0; index < lines.length; index++) {
27414
+ const line = lines[index] ?? "";
27415
+ const match = pattern.exec(line);
27416
+ if (!match) continue;
27417
+ references.push({
27418
+ file,
27419
+ line: index + 1,
27420
+ column: match.index + 1,
27421
+ content: line.trim()
27422
+ });
27423
+ if (references.length >= maxResults) {
27424
+ return { references, searchedFiles: files.length, truncated: true };
27425
+ }
27426
+ }
27427
+ }
27428
+ return { references, searchedFiles: files.length, truncated: false };
27429
+ }
27430
+ });
27431
+ function escapeRegExp(value) {
27432
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
27433
+ }
27434
+ var lspTools = [
27435
+ lspStatusTool,
27436
+ lspDocumentSymbolsTool,
27437
+ lspWorkspaceSymbolsTool,
27438
+ lspDefinitionTool,
27439
+ lspReferencesTool
27440
+ ];
27441
+ var fs34 = await import('fs/promises');
27442
+ var path36 = await import('path');
27443
+ function cachePath(root) {
27444
+ return path36.join(root, ".coco", "cache", "repo-index.json");
27445
+ }
27446
+ function normalizeText(value) {
27447
+ return value.toLowerCase().replace(/[^a-z0-9_./:-]+/g, " ");
27448
+ }
27449
+ function queryTerms(query) {
27450
+ return [
27451
+ ...new Set(
27452
+ normalizeText(query).split(/\s+/).filter((term) => term.length >= 2)
27453
+ )
27454
+ ];
27455
+ }
27456
+ function importTargetToPath(importTarget) {
27457
+ return importTarget.replace(/^\.\//, "").replace(/\.(js|ts|tsx|jsx|mjs|cjs)$/, "");
27458
+ }
27459
+ function buildGraph(root, map) {
27460
+ const inbound = /* @__PURE__ */ new Map();
27461
+ const files = new Set(map.files.map((file) => file.path.replace(/\.[^.]+$/, "")));
27462
+ for (const file of map.files) {
27463
+ for (const importTarget of file.imports) {
27464
+ const normalized = importTargetToPath(importTarget);
27465
+ for (const candidate of files) {
27466
+ if (candidate.endsWith(normalized) || normalized.endsWith(candidate)) {
27467
+ inbound.set(candidate, (inbound.get(candidate) ?? 0) + 1);
27468
+ }
27469
+ }
27470
+ }
27471
+ }
27472
+ return {
27473
+ root,
27474
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
27475
+ files: map.files.map((file) => {
27476
+ const withoutExt = file.path.replace(/\.[^.]+$/, "");
27477
+ return {
27478
+ ...file,
27479
+ inboundImports: inbound.get(withoutExt) ?? 0,
27480
+ testRelated: /(?:^|[/.-])(test|spec|__tests__)(?:[/.-]|$)/i.test(file.path)
27481
+ };
27482
+ }),
27483
+ summary: map.summary
27484
+ };
27485
+ }
27486
+ async function readCachedGraph(root) {
27487
+ try {
27488
+ const raw = await fs34.readFile(cachePath(root), "utf-8");
27489
+ return JSON.parse(raw);
27490
+ } catch {
27491
+ return null;
27492
+ }
27493
+ }
27494
+ async function writeCachedGraph(root, graph) {
27495
+ const file = cachePath(root);
27496
+ await fs34.mkdir(path36.dirname(file), { recursive: true });
27497
+ await fs34.writeFile(file, JSON.stringify(graph, null, 2) + "\n", "utf-8");
27498
+ }
27499
+ async function loadGraph(root, refresh) {
27500
+ if (!refresh) {
27501
+ const cached = await readCachedGraph(root);
27502
+ if (cached) return cached;
27503
+ }
27504
+ const map = await codebaseMapTool.execute({
27505
+ path: root,
27506
+ maxFiles: 500,
27507
+ depth: "detailed",
27508
+ includeTests: true
27509
+ });
27510
+ const graph = buildGraph(root, map);
27511
+ await writeCachedGraph(root, graph);
27512
+ return graph;
27513
+ }
27514
+ function scoreFile(file, terms, mode, changedFiles) {
27515
+ let score = 0;
27516
+ const reasons = [];
27517
+ const pathText = normalizeText(file.path);
27518
+ const symbolText = normalizeText(file.definitions.map((def) => def.name).join(" "));
27519
+ const importText = normalizeText([...file.imports, ...file.exports].join(" "));
27520
+ for (const term of terms) {
27521
+ if (pathText.includes(term)) {
27522
+ score += 8;
27523
+ reasons.push(`path:${term}`);
27524
+ }
27525
+ if (symbolText.includes(term)) {
27526
+ score += 6;
27527
+ reasons.push(`symbol:${term}`);
27528
+ }
27529
+ if (importText.includes(term)) {
27530
+ score += 3;
27531
+ reasons.push(`import/export:${term}`);
27532
+ }
27533
+ }
27534
+ if (changedFiles.has(file.path)) {
27535
+ score += 10;
27536
+ reasons.push("changed-file");
27537
+ }
27538
+ if (file.inboundImports > 0) {
27539
+ score += Math.min(6, file.inboundImports);
27540
+ reasons.push(`centrality:${file.inboundImports}`);
27541
+ }
27542
+ if ((mode === "debug" || mode === "review") && file.testRelated) {
27543
+ score += 4;
27544
+ reasons.push("test-related");
27545
+ }
27546
+ if (file.exports.length > 0) {
27547
+ score += 1;
27548
+ }
27549
+ return {
27550
+ path: file.path,
27551
+ score,
27552
+ reasons: [...new Set(reasons)],
27553
+ language: file.language,
27554
+ lineCount: file.lineCount,
27555
+ definitions: file.definitions.slice(0, 20),
27556
+ imports: file.imports.slice(0, 20),
27557
+ exports: file.exports.slice(0, 20)
27558
+ };
27559
+ }
27560
+ async function getRepoContext(request) {
27561
+ const root = path36.resolve(request.path ?? ".");
27562
+ const budget = request.budget ?? 12;
27563
+ const graph = await loadGraph(root, request.refresh ?? false);
27564
+ const terms = queryTerms(request.query);
27565
+ const changedFiles = new Set(request.changedFiles ?? []);
27566
+ const items = graph.files.map((file) => scoreFile(file, terms, request.mode, changedFiles)).filter((item) => item.score > 0).sort((a, b) => b.score - a.score || a.path.localeCompare(b.path)).slice(0, budget);
27567
+ return {
27568
+ graph: {
27569
+ root: graph.root,
27570
+ generatedAt: graph.generatedAt,
27571
+ totalFiles: graph.summary.totalFiles,
27572
+ totalDefinitions: graph.summary.totalDefinitions
27573
+ },
27574
+ query: request.query,
27575
+ budget,
27576
+ items
27577
+ };
27578
+ }
27579
+ var repoContextTool = defineTool({
27580
+ name: "repo_context",
27581
+ description: "Return ranked, token-efficient repository context for a task using symbols, imports, tests, and centrality.",
27582
+ category: "search",
27583
+ parameters: z.object({
27584
+ path: z.string().optional().default(".").describe("Repository root"),
27585
+ query: z.string().min(1).describe("Task or search query to rank files against"),
27586
+ budget: z.number().min(1).max(50).optional().default(12).describe("Maximum files to return"),
27587
+ mode: z.enum(["ask", "plan", "build", "debug", "review", "architect"]).optional().describe("Agent mode to bias ranking"),
27588
+ changedFiles: z.array(z.string()).optional().describe("Files already changed or selected"),
27589
+ refresh: z.boolean().optional().default(false).describe("Refresh persistent repo index cache")
27590
+ }),
27591
+ execute: getRepoContext
27592
+ });
27593
+ var repoIntelligenceTools = [repoContextTool];
26212
27594
  var AgentTaskQueue = class {
26213
27595
  tasks = /* @__PURE__ */ new Map();
26214
27596
  completionOrder = [];
@@ -26517,15 +27899,15 @@ ${completed.map((r) => `- ${r.agentId}: Success`).join("\n")}`;
26517
27899
  }
26518
27900
  });
26519
27901
  var agentCoordinatorTools = [createAgentPlanTool, delegateTaskTool, aggregateResultsTool];
26520
- var fs33 = await import('fs/promises');
27902
+ var fs35 = await import('fs/promises');
26521
27903
  var SuggestImprovementsSchema = z.object({
26522
27904
  filePath: z.string().describe("File to analyze for improvement suggestions"),
26523
27905
  context: z.string().optional().describe("Additional context about the code")
26524
27906
  });
26525
27907
  async function analyzeAndSuggest(filePath, _context) {
26526
- let rawContent = await fs33.readFile(filePath, "utf-8");
27908
+ let rawContent = await fs35.readFile(filePath, "utf-8");
26527
27909
  if (typeof rawContent !== "string") {
26528
- const defaultReadFile = fs33.default?.readFile;
27910
+ const defaultReadFile = fs35.default?.readFile;
26529
27911
  if (typeof defaultReadFile === "function") {
26530
27912
  rawContent = await defaultReadFile(filePath, "utf-8");
26531
27913
  }
@@ -26622,7 +28004,7 @@ async function analyzeAndSuggest(filePath, _context) {
26622
28004
  if (filePath.endsWith(".ts") && !filePath.includes("test") && !filePath.includes(".d.ts") && line.includes("export ")) {
26623
28005
  const testPath = filePath.replace(".ts", ".test.ts");
26624
28006
  try {
26625
- await fs33.access(testPath);
28007
+ await fs35.access(testPath);
26626
28008
  } catch {
26627
28009
  suggestions.push({
26628
28010
  type: "testing",
@@ -26679,7 +28061,7 @@ var calculateCodeScoreTool = defineTool({
26679
28061
  async execute(input) {
26680
28062
  const { filePath } = input;
26681
28063
  const suggestions = await analyzeAndSuggest(filePath);
26682
- const content = await fs33.readFile(filePath, "utf-8");
28064
+ const content = await fs35.readFile(filePath, "utf-8");
26683
28065
  const lines = content.split("\n");
26684
28066
  const nonEmptyLines = lines.filter((l) => l.trim()).length;
26685
28067
  let score = 100;
@@ -26713,8 +28095,8 @@ var calculateCodeScoreTool = defineTool({
26713
28095
  }
26714
28096
  });
26715
28097
  var smartSuggestionsTools = [suggestImprovementsTool, calculateCodeScoreTool];
26716
- var fs34 = await import('fs/promises');
26717
- var path35 = await import('path');
28098
+ var fs36 = await import('fs/promises');
28099
+ var path37 = await import('path');
26718
28100
  var ContextMemoryStore = class {
26719
28101
  items = /* @__PURE__ */ new Map();
26720
28102
  learnings = /* @__PURE__ */ new Map();
@@ -26726,7 +28108,7 @@ var ContextMemoryStore = class {
26726
28108
  }
26727
28109
  async load() {
26728
28110
  try {
26729
- const content = await fs34.readFile(this.storePath, "utf-8");
28111
+ const content = await fs36.readFile(this.storePath, "utf-8");
26730
28112
  const data = JSON.parse(content);
26731
28113
  this.items = new Map(Object.entries(data.items || {}));
26732
28114
  this.learnings = new Map(Object.entries(data.learnings || {}));
@@ -26734,15 +28116,15 @@ var ContextMemoryStore = class {
26734
28116
  }
26735
28117
  }
26736
28118
  async save() {
26737
- const dir = path35.dirname(this.storePath);
26738
- await fs34.mkdir(dir, { recursive: true });
28119
+ const dir = path37.dirname(this.storePath);
28120
+ await fs36.mkdir(dir, { recursive: true });
26739
28121
  const data = {
26740
28122
  sessionId: this.sessionId,
26741
28123
  items: Object.fromEntries(this.items),
26742
28124
  learnings: Object.fromEntries(this.learnings),
26743
28125
  savedAt: Date.now()
26744
28126
  };
26745
- await fs34.writeFile(this.storePath, JSON.stringify(data, null, 2));
28127
+ await fs36.writeFile(this.storePath, JSON.stringify(data, null, 2));
26746
28128
  }
26747
28129
  addContext(id, item) {
26748
28130
  this.items.set(id, item);
@@ -26907,11 +28289,11 @@ var contextEnhancerTools = [
26907
28289
  recordLearningTool,
26908
28290
  getLearnedPatternsTool
26909
28291
  ];
26910
- var fs35 = await import('fs/promises');
26911
- var path36 = await import('path');
28292
+ var fs37 = await import('fs/promises');
28293
+ var path38 = await import('path');
26912
28294
  async function discoverSkills(skillsDir) {
26913
28295
  try {
26914
- const files = await fs35.readdir(skillsDir);
28296
+ const files = await fs37.readdir(skillsDir);
26915
28297
  return files.filter((f) => f.endsWith(".ts") || f.endsWith(".js"));
26916
28298
  } catch {
26917
28299
  return [];
@@ -26919,12 +28301,12 @@ async function discoverSkills(skillsDir) {
26919
28301
  }
26920
28302
  async function loadSkillMetadata(skillPath) {
26921
28303
  try {
26922
- const content = await fs35.readFile(skillPath, "utf-8");
28304
+ const content = await fs37.readFile(skillPath, "utf-8");
26923
28305
  const nameMatch = content.match(/@name\s+(\S+)/);
26924
28306
  const descMatch = content.match(/@description\s+(.+)/);
26925
28307
  const versionMatch = content.match(/@version\s+(\S+)/);
26926
28308
  return {
26927
- name: nameMatch?.[1] || path36.basename(skillPath, path36.extname(skillPath)),
28309
+ name: nameMatch?.[1] || path38.basename(skillPath, path38.extname(skillPath)),
26928
28310
  description: descMatch?.[1] || "No description",
26929
28311
  version: versionMatch?.[1] || "1.0.0",
26930
28312
  dependencies: []
@@ -26968,7 +28350,7 @@ var discoverSkillsTool = defineTool({
26968
28350
  const { skillsDir } = input;
26969
28351
  const skills = await discoverSkills(skillsDir);
26970
28352
  const metadata = await Promise.all(
26971
- skills.map((s) => loadSkillMetadata(path36.join(skillsDir, s)))
28353
+ skills.map((s) => loadSkillMetadata(path38.join(skillsDir, s)))
26972
28354
  );
26973
28355
  return {
26974
28356
  skillsDir,
@@ -27708,8 +29090,8 @@ var MCPRegistryImpl = class {
27708
29090
  /**
27709
29091
  * Ensure directory exists
27710
29092
  */
27711
- async ensureDir(path42) {
27712
- await mkdir(dirname(path42), { recursive: true });
29093
+ async ensureDir(path44) {
29094
+ await mkdir(dirname(path44), { recursive: true });
27713
29095
  }
27714
29096
  };
27715
29097
 
@@ -27725,6 +29107,8 @@ var MCPClientImpl = class {
27725
29107
  this.requestTimeout = requestTimeout;
27726
29108
  this.setupTransportHandlers();
27727
29109
  }
29110
+ transport;
29111
+ requestTimeout;
27728
29112
  requestId = 0;
27729
29113
  pendingRequests = /* @__PURE__ */ new Map();
27730
29114
  initialized = false;
@@ -27896,6 +29280,7 @@ var StdioTransport = class {
27896
29280
  constructor(config) {
27897
29281
  this.config = config;
27898
29282
  }
29283
+ config;
27899
29284
  process = null;
27900
29285
  messageCallback = null;
27901
29286
  errorCallback = null;
@@ -28435,6 +29820,7 @@ var HTTPTransport = class {
28435
29820
  this.config.timeout = config.timeout ?? 6e4;
28436
29821
  this.config.retries = config.retries ?? 3;
28437
29822
  }
29823
+ config;
28438
29824
  messageCallback = null;
28439
29825
  errorCallback = null;
28440
29826
  // Used to report transport errors to the client
@@ -29503,6 +30889,8 @@ function registerAllTools(registry) {
29503
30889
  ...databaseTools,
29504
30890
  ...astValidatorTools,
29505
30891
  ...codeAnalyzerTools,
30892
+ ...lspTools,
30893
+ ...repoIntelligenceTools,
29506
30894
  ...agentCoordinatorTools,
29507
30895
  ...smartSuggestionsTools,
29508
30896
  ...contextEnhancerTools,