coding-tool-x 3.8.8 → 3.8.10

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.
Files changed (134) hide show
  1. package/README.md +56 -388
  2. package/dist/web/assets/AgentsDrawer-Bam7kBjG.js +1 -0
  3. package/dist/web/assets/Analytics-D5dUWXEa.js +1 -0
  4. package/dist/web/assets/AssetPathField-CLqalYv-.js +1 -0
  5. package/dist/web/assets/{ChatHistoryDrawer-CrfS0KYV.js → ChatHistoryDrawer-C1At65O3.js} +1 -1
  6. package/dist/web/assets/{CollapseItem-ClMsJuUu.js → CollapseItem-CVWojShK.js} +1 -1
  7. package/dist/web/assets/CommandsDrawer-BEoypGBf.js +1 -0
  8. package/dist/web/assets/ConfigExportDrawer-DBvFDDWK.js +1 -0
  9. package/dist/web/assets/ConfigTemplates-BpaWG-iC.js +1 -0
  10. package/dist/web/assets/{ConfigTemplatesDrawer-BqM32Im7.js → ConfigTemplatesDrawer-C2lvyKMf.js} +1 -1
  11. package/dist/web/assets/ConfigTemplatesPanel-CorOY7kY.js +1 -0
  12. package/dist/web/assets/{Divider-DsdbkHrG.js → Divider-BLLhMTSt.js} +1 -1
  13. package/dist/web/assets/FavoritesDrawer-uW88N6te.js +1 -0
  14. package/dist/web/assets/GatewayConvertDrawer-i5Wt9Dd9.js +1 -0
  15. package/dist/web/assets/Home-BIxWvm29.js +1 -0
  16. package/dist/web/assets/{MarkdownEditor-BMMUufSc.js → MarkdownEditor-Ul0bSGj-.js} +1 -1
  17. package/dist/web/assets/McpDrawer-Cc2xq77I.js +1 -0
  18. package/dist/web/assets/McpFormDrawer-DLHX_nrI.js +1 -0
  19. package/dist/web/assets/{PluginManager-C4kJlpVX.js → PluginManager-BGQ0xF2F.js} +1 -1
  20. package/dist/web/assets/{PluginsDrawer-05R4k15x.js → PluginsDrawer-STwHEqiF.js} +1 -1
  21. package/dist/web/assets/PluginsPanel-1zuNP7da.js +1 -0
  22. package/dist/web/assets/ProjectList-VbIYSHbH.css +1 -0
  23. package/dist/web/assets/ProjectList-_pe2nk9c.js +1 -0
  24. package/dist/web/assets/PromptsDrawer-CJN1xZk7.js +1 -0
  25. package/dist/web/assets/RecentSessionsDrawer-DX1HI8Nm.js +1 -0
  26. package/dist/web/assets/SessionCard-Op6PHvi0.js +1 -0
  27. package/dist/web/assets/SessionList-Da_TAEYr.js +1 -0
  28. package/dist/web/assets/SettingsDrawer-DKLd4Sjy.js +1 -0
  29. package/dist/web/assets/{SkillManager-D9jkNuRM.js → SkillManager-PcAa5EbF.js} +1 -1
  30. package/dist/web/assets/{SkillsDrawer-0Z4IefxC.js → SkillsDrawer-DPdU4p6C.js} +1 -1
  31. package/dist/web/assets/SkillsPanel-B9qzRqjd.js +1 -0
  32. package/dist/web/assets/Upload-e1M9Yp5z.js +1 -0
  33. package/dist/web/assets/{WorkspaceDrawer-eujtWpoq.js → WorkspaceDrawer-oS6mB1VZ.js} +1 -1
  34. package/dist/web/assets/{WorkspaceManager-CQ-8Ej68.js → WorkspaceManager-6VvRWe3r.js} +1 -1
  35. package/dist/web/assets/WorkspacePanel-CYq0Z8iY.js +1 -0
  36. package/dist/web/assets/client-BgcNg4Bt.js +1 -0
  37. package/dist/web/assets/headers-DbowkmZJ.js +1 -0
  38. package/dist/web/assets/{icons-DmFe4b5j.js → icons-B-AzZoeE.js} +1 -1
  39. package/dist/web/assets/index-BlUXw84U.js +2 -0
  40. package/dist/web/assets/index-Bn8BUnwP.css +1 -0
  41. package/dist/web/assets/{light-0eavxNvt.js → light-C2X7hegj.js} +1 -1
  42. package/dist/web/assets/platforms-DrzAtnjY.js +1 -0
  43. package/dist/web/assets/platforms-mqqe_82d.js +1 -0
  44. package/dist/web/assets/project-config-BVt5s-pH.js +1 -0
  45. package/dist/web/assets/sessions-53-Fr68H.js +1 -0
  46. package/dist/web/assets/{sessions-D4yQtfKb.js → sessions-CaWUaysM.js} +1 -1
  47. package/dist/web/assets/use-message-DBsCm7FJ.js +1 -0
  48. package/dist/web/assets/{useResponsiveDrawer-DZd5rNk5.js → useResponsiveDrawer-ChHZrTfl.js} +1 -1
  49. package/dist/web/assets/{workspaces-mjyPVGS8.js → workspaces-DQuZd4qw.js} +1 -1
  50. package/dist/web/index.html +8 -8
  51. package/package.json +4 -2
  52. package/src/commands/daemon.js +27 -4
  53. package/src/commands/export-config.js +17 -211
  54. package/src/config/model-metadata.json +180 -16
  55. package/src/platforms/channel-auth-registry.js +36 -6
  56. package/src/platforms/channel-auth-service.js +13 -3
  57. package/src/platforms/commands-service.js +28 -0
  58. package/src/platforms/driver-registry.js +1 -0
  59. package/src/platforms/drivers/claude/channels-implementation.js +79 -90
  60. package/src/platforms/drivers/claude/native-config-implementation.js +3 -4
  61. package/src/platforms/drivers/codex/channels-implementation.js +34 -49
  62. package/src/platforms/drivers/codex/native-config-implementation.js +3 -51
  63. package/src/platforms/drivers/dsh/api-operations.js +1 -1
  64. package/src/platforms/drivers/dsh/channels-implementation.js +28 -8
  65. package/src/platforms/drivers/dsh/channels.js +0 -18
  66. package/src/platforms/drivers/dsh/common.js +7 -0
  67. package/src/platforms/drivers/dsh/native-config.js +7 -2
  68. package/src/platforms/drivers/gemini/channels-implementation.js +47 -55
  69. package/src/platforms/drivers/gemini/native-config-implementation.js +8 -20
  70. package/src/platforms/drivers/generic-native-config.js +20 -0
  71. package/src/platforms/drivers/native-config-snapshot.js +30 -4
  72. package/src/platforms/drivers/omp/channels-implementation.js +51 -17
  73. package/src/platforms/drivers/omp/native-config-implementation.js +10 -17
  74. package/src/platforms/drivers/omp/prompts.js +58 -2
  75. package/src/platforms/drivers/omp/proxy-implementation.js +25 -1
  76. package/src/platforms/drivers/opencode/channels-implementation.js +31 -22
  77. package/src/platforms/drivers/opencode/channels.js +6 -1
  78. package/src/platforms/drivers/opencode/native-config-implementation.js +3 -67
  79. package/src/platforms/manifest-schema.js +35 -2
  80. package/src/platforms/manifests/claude.json +0 -8
  81. package/src/platforms/manifests/codex.json +0 -8
  82. package/src/platforms/manifests/dsh.json +6 -9
  83. package/src/platforms/manifests/gemini.json +0 -8
  84. package/src/platforms/manifests/omp.json +2 -9
  85. package/src/platforms/manifests/opencode.json +28 -8
  86. package/src/platforms/native-oauth-adapters.js +351 -51
  87. package/src/platforms/oauth-credentials-service.js +344 -13
  88. package/src/server/index.js +37 -1
  89. package/src/server/services/bounded-content.js +60 -0
  90. package/src/server/services/channel-balance.js +10 -4
  91. package/src/server/services/config-export-service.js +2 -2
  92. package/src/server/services/config-templates-service.js +5 -1
  93. package/src/server/services/plugins-service.js +162 -85
  94. package/src/server/services/session-history-maintenance-worker.js +71 -0
  95. package/src/server/services/session-history-maintenance.js +166 -0
  96. package/src/server/services/skill-service.js +23 -3
  97. package/src/server/services/speed-test.js +0 -72
  98. package/src/shared/channel-driver.js +16 -0
  99. package/src/shared/driver-factories/api.js +1 -0
  100. package/src/utils/native-config-patcher.js +474 -0
  101. package/dist/web/assets/AgentsDrawer-DRQuwi0m.js +0 -1
  102. package/dist/web/assets/Analytics-Cf5KwEdj.js +0 -1
  103. package/dist/web/assets/AssetPathField-DyniM0pF.js +0 -1
  104. package/dist/web/assets/CommandsDrawer-CzHelf56.js +0 -1
  105. package/dist/web/assets/ConfigExportDrawer-BEZ8wTby.js +0 -1
  106. package/dist/web/assets/ConfigTemplates-Crg3xWe5.js +0 -1
  107. package/dist/web/assets/ConfigTemplatesPanel-lTdutC8H.js +0 -1
  108. package/dist/web/assets/FavoritesDrawer-DDyWUBJR.js +0 -1
  109. package/dist/web/assets/GatewayConvertDrawer-Rigtt_5J.js +0 -1
  110. package/dist/web/assets/Home-tCSKmSHV.js +0 -1
  111. package/dist/web/assets/McpDrawer-CmE-d7VW.js +0 -1
  112. package/dist/web/assets/McpFormDrawer-ByvS18od.js +0 -1
  113. package/dist/web/assets/PluginsPanel-BCoEs7Og.js +0 -1
  114. package/dist/web/assets/ProjectList-BJt1OIaI.js +0 -1
  115. package/dist/web/assets/ProjectList-DG3yu8xZ.css +0 -1
  116. package/dist/web/assets/PromptsDrawer-DnwBf_oW.js +0 -1
  117. package/dist/web/assets/RecentSessionsDrawer-B7d-38wH.js +0 -1
  118. package/dist/web/assets/SessionCard-BUgjHQwX.js +0 -1
  119. package/dist/web/assets/SessionList-B-bXZRFk.js +0 -1
  120. package/dist/web/assets/SettingsDrawer-BITzjQLl.js +0 -1
  121. package/dist/web/assets/SkillsPanel-BKIVOj7n.js +0 -1
  122. package/dist/web/assets/SpeedTestDrawer-Bx1bYf5i.js +0 -1
  123. package/dist/web/assets/SpeedTestDrawer-Dc0WToJ_.css +0 -1
  124. package/dist/web/assets/Upload-CzC4rGI4.js +0 -1
  125. package/dist/web/assets/WorkspacePanel-Cql5qE2R.js +0 -1
  126. package/dist/web/assets/client-UDwXBP9i.js +0 -1
  127. package/dist/web/assets/headers-BqDmkMjy.js +0 -1
  128. package/dist/web/assets/index-Cmmwj3Fx.js +0 -2
  129. package/dist/web/assets/index-Cnbe696C.css +0 -1
  130. package/dist/web/assets/platforms-BmzzwnSw.js +0 -1
  131. package/dist/web/assets/platforms-DWXgmy2w.js +0 -1
  132. package/dist/web/assets/project-config-B2baPzYL.js +0 -1
  133. package/dist/web/assets/sessions-DqlbocLJ.js +0 -1
  134. package/dist/web/assets/use-message-DqCwefG6.js +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "source": "models.dev",
3
3
  "sourceUrl": "https://models.dev/api.json",
4
- "lastUpdated": "2026-09-15",
4
+ "lastUpdated": "2026-09-24",
5
5
  "defaultModels": {
6
6
  "claude": [
7
7
  "claude-opus-4-7",
@@ -17,7 +17,8 @@
17
17
  "claude-opus-4-8",
18
18
  "claude-opus-4-5",
19
19
  "claude-haiku-4-5",
20
- "claude-sonnet-4-5"
20
+ "claude-sonnet-4-5",
21
+ "claude-opus-5-5"
21
22
  ],
22
23
  "codex": [
23
24
  "gpt-5.5",
@@ -53,7 +54,9 @@
53
54
  "gpt-4o",
54
55
  "gpt-4o-2024-08-06",
55
56
  "gpt-4o-mini",
56
- "gpt-6-astra"
57
+ "gpt-6-astra",
58
+ "gpt-6-luna",
59
+ "gpt-6-sol"
57
60
  ],
58
61
  "gemini": [
59
62
  "gemini-3.1-pro-preview",
@@ -106,6 +109,7 @@
106
109
  "glm-4.5v": "zai/glm-4.5v",
107
110
  "glm-4.6": "zai/glm-4.6",
108
111
  "glm-4.6v": "zai/glm-4.6v",
112
+ "glm-4.6v-flash": "zai/glm-4.6v-flash",
109
113
  "glm-4.7": "zai/glm-4.7",
110
114
  "glm-4.7-flash": "zai/glm-4.7-flash",
111
115
  "glm-4.7-flashx": "zai/glm-4.7-flashx",
@@ -115,12 +119,14 @@
115
119
  "glm-5.2": "zai/glm-5.2",
116
120
  "glm-5.3": "zai/glm-5.3",
117
121
  "glm-5.3-flash": "zai/glm-5.3-flash",
122
+ "glm-5.3-flashx": "zai/glm-5.3-flashx",
118
123
  "glm-5v-turbo": "zai/glm-5v-turbo",
119
124
  "grok-4.20-0309-non-reasoning": "xai/grok-4.20-0309-non-reasoning",
120
125
  "grok-4.20-0309-reasoning": "xai/grok-4.20-0309-reasoning",
121
126
  "grok-4.3": "xai/grok-4.3",
122
127
  "grok-4.5": "xai/grok-4.5",
123
128
  "grok-4.6": "xai/grok-4.6",
129
+ "grok-4.7": "xai/grok-4.7",
124
130
  "grok-build-0.1": "xai/grok-build-0.1",
125
131
  "kimi-k2-0711-preview": "moonshotai/kimi-k2-0711-preview",
126
132
  "kimi-k2-0905-preview": "moonshotai/kimi-k2-0905-preview",
@@ -1214,7 +1220,7 @@
1214
1220
  ],
1215
1221
  "limit": {
1216
1222
  "context": 1000000,
1217
- "output": 65536
1223
+ "output": 131072
1218
1224
  },
1219
1225
  "name": "Qwen3.7 Max",
1220
1226
  "pricing": {
@@ -1240,7 +1246,7 @@
1240
1246
  ],
1241
1247
  "limit": {
1242
1248
  "context": 1000000,
1243
- "output": 65536
1249
+ "output": 131072
1244
1250
  },
1245
1251
  "name": "Qwen3.7 Plus",
1246
1252
  "pricing": {
@@ -1580,6 +1586,33 @@
1580
1586
  "omp"
1581
1587
  ]
1582
1588
  },
1589
+ "claude-opus-5-5": {
1590
+ "id": "claude-opus-5-5",
1591
+ "input": [
1592
+ "text",
1593
+ "image"
1594
+ ],
1595
+ "limit": {
1596
+ "context": 1000000,
1597
+ "output": 128000
1598
+ },
1599
+ "name": "Claude Opus 5.5",
1600
+ "pricing": {
1601
+ "cacheCreation": 5,
1602
+ "cacheRead": 0.2,
1603
+ "input": 4,
1604
+ "output": 20
1605
+ },
1606
+ "provider": "anthropic",
1607
+ "reasoning": true,
1608
+ "sourceId": "anthropic/claude-opus-5-5",
1609
+ "supportsTools": true,
1610
+ "toolTypes": [
1611
+ "claude",
1612
+ "opencode",
1613
+ "omp"
1614
+ ]
1615
+ },
1583
1616
  "claude-sonnet-4-5": {
1584
1617
  "id": "claude-sonnet-4-5",
1585
1618
  "input": [
@@ -1696,7 +1729,7 @@
1696
1729
  ],
1697
1730
  "limit": {
1698
1731
  "context": 1000000,
1699
- "output": 384000
1732
+ "output": 393216
1700
1733
  },
1701
1734
  "name": "DeepSeek V4.1 Flash",
1702
1735
  "pricing": {
@@ -1721,7 +1754,7 @@
1721
1754
  ],
1722
1755
  "limit": {
1723
1756
  "context": 1000000,
1724
- "output": 384000
1757
+ "output": 393216
1725
1758
  },
1726
1759
  "name": "DeepSeek V4 Flash",
1727
1760
  "pricing": {
@@ -1746,7 +1779,7 @@
1746
1779
  ],
1747
1780
  "limit": {
1748
1781
  "context": 1000000,
1749
- "output": 384000
1782
+ "output": 393216
1750
1783
  },
1751
1784
  "name": "DeepSeek V4 Flash Vision Exp",
1752
1785
  "pricing": {
@@ -1770,7 +1803,7 @@
1770
1803
  ],
1771
1804
  "limit": {
1772
1805
  "context": 1000000,
1773
- "output": 384000
1806
+ "output": 393216
1774
1807
  },
1775
1808
  "name": "DeepSeek V4 Pro",
1776
1809
  "pricing": {
@@ -1794,8 +1827,8 @@
1794
1827
  "image"
1795
1828
  ],
1796
1829
  "limit": {
1797
- "context": 131072,
1798
- "output": 65536
1830
+ "context": 128000,
1831
+ "output": 64000
1799
1832
  },
1800
1833
  "name": "Gemini 2.5 Computer Use Preview 10-2025",
1801
1834
  "pricing": {
@@ -1961,7 +1994,7 @@
1961
1994
  ],
1962
1995
  "limit": {
1963
1996
  "context": 65536,
1964
- "output": 65536
1997
+ "output": 4096
1965
1998
  },
1966
1999
  "name": "Nano Banana 2 Lite",
1967
2000
  "pricing": {
@@ -3012,6 +3045,60 @@
3012
3045
  "omp"
3013
3046
  ]
3014
3047
  },
3048
+ "gpt-6-luna": {
3049
+ "id": "gpt-6-luna",
3050
+ "input": [
3051
+ "text",
3052
+ "image"
3053
+ ],
3054
+ "limit": {
3055
+ "context": 1050000,
3056
+ "output": 128000
3057
+ },
3058
+ "name": "GPT-6 Luna",
3059
+ "pricing": {
3060
+ "cacheCreation": 0.125,
3061
+ "cacheRead": 0.01,
3062
+ "input": 0.1,
3063
+ "output": 0.5
3064
+ },
3065
+ "provider": "openai",
3066
+ "reasoning": true,
3067
+ "sourceId": "openai/gpt-6-luna",
3068
+ "supportsTools": true,
3069
+ "toolTypes": [
3070
+ "codex",
3071
+ "opencode",
3072
+ "omp"
3073
+ ]
3074
+ },
3075
+ "gpt-6-sol": {
3076
+ "id": "gpt-6-sol",
3077
+ "input": [
3078
+ "text",
3079
+ "image"
3080
+ ],
3081
+ "limit": {
3082
+ "context": 1050000,
3083
+ "output": 128000
3084
+ },
3085
+ "name": "GPT-6 Sol",
3086
+ "pricing": {
3087
+ "cacheCreation": 2.5,
3088
+ "cacheRead": 0.2,
3089
+ "input": 2,
3090
+ "output": 10
3091
+ },
3092
+ "provider": "openai",
3093
+ "reasoning": true,
3094
+ "sourceId": "openai/gpt-6-sol",
3095
+ "supportsTools": true,
3096
+ "toolTypes": [
3097
+ "codex",
3098
+ "opencode",
3099
+ "omp"
3100
+ ]
3101
+ },
3015
3102
  "gpt-realtime-2.1": {
3016
3103
  "id": "gpt-realtime-2.1",
3017
3104
  "input": [
@@ -3551,7 +3638,7 @@
3551
3638
  ],
3552
3639
  "limit": {
3553
3640
  "context": 1048576,
3554
- "output": 131072
3641
+ "output": 1048576
3555
3642
  },
3556
3643
  "name": "Kimi K3",
3557
3644
  "pricing": {
@@ -3744,6 +3831,31 @@
3744
3831
  "omp"
3745
3832
  ]
3746
3833
  },
3834
+ "xai/grok-4.7": {
3835
+ "id": "xai/grok-4.7",
3836
+ "input": [
3837
+ "text",
3838
+ "image"
3839
+ ],
3840
+ "limit": {
3841
+ "context": 500000,
3842
+ "output": 500000
3843
+ },
3844
+ "name": "Grok 4.7",
3845
+ "pricing": {
3846
+ "cacheRead": 0.5,
3847
+ "input": 2,
3848
+ "output": 6
3849
+ },
3850
+ "provider": "xai",
3851
+ "reasoning": true,
3852
+ "sourceId": "xai/grok-4.7",
3853
+ "supportsTools": true,
3854
+ "toolTypes": [
3855
+ "opencode",
3856
+ "omp"
3857
+ ]
3858
+ },
3747
3859
  "xai/grok-build-0.1": {
3748
3860
  "id": "xai/grok-build-0.1",
3749
3861
  "input": [
@@ -3917,6 +4029,32 @@
3917
4029
  "omp"
3918
4030
  ]
3919
4031
  },
4032
+ "zai/glm-4.6v-flash": {
4033
+ "id": "zai/glm-4.6v-flash",
4034
+ "input": [
4035
+ "text",
4036
+ "image"
4037
+ ],
4038
+ "limit": {
4039
+ "context": 128000,
4040
+ "output": 32768
4041
+ },
4042
+ "name": "GLM-4.6V-Flash",
4043
+ "pricing": {
4044
+ "cacheCreation": 0,
4045
+ "cacheRead": 0,
4046
+ "input": 0,
4047
+ "output": 0
4048
+ },
4049
+ "provider": "zai",
4050
+ "reasoning": true,
4051
+ "sourceId": "zai/glm-4.6v-flash",
4052
+ "supportsTools": true,
4053
+ "toolTypes": [
4054
+ "opencode",
4055
+ "omp"
4056
+ ]
4057
+ },
3920
4058
  "zai/glm-4.7": {
3921
4059
  "id": "zai/glm-4.7",
3922
4060
  "input": [
@@ -4130,9 +4268,9 @@
4130
4268
  "name": "GLM-5.3-Flash",
4131
4269
  "pricing": {
4132
4270
  "cacheCreation": 0,
4133
- "cacheRead": 0.015,
4134
- "input": 0.075,
4135
- "output": 0.25
4271
+ "cacheRead": 0.03,
4272
+ "input": 0.15,
4273
+ "output": 0.5
4136
4274
  },
4137
4275
  "provider": "zai",
4138
4276
  "reasoning": true,
@@ -4143,6 +4281,32 @@
4143
4281
  "omp"
4144
4282
  ]
4145
4283
  },
4284
+ "zai/glm-5.3-flashx": {
4285
+ "id": "zai/glm-5.3-flashx",
4286
+ "input": [
4287
+ "text",
4288
+ "image"
4289
+ ],
4290
+ "limit": {
4291
+ "context": 1000000,
4292
+ "output": 131072
4293
+ },
4294
+ "name": "GLM-5.3-FlashX",
4295
+ "pricing": {
4296
+ "cacheCreation": 0,
4297
+ "cacheRead": 0.075,
4298
+ "input": 0.37,
4299
+ "output": 1.25
4300
+ },
4301
+ "provider": "zai",
4302
+ "reasoning": true,
4303
+ "sourceId": "zai/glm-5.3-flashx",
4304
+ "supportsTools": true,
4305
+ "toolTypes": [
4306
+ "opencode",
4307
+ "omp"
4308
+ ]
4309
+ },
4146
4310
  "zai/glm-5v-turbo": {
4147
4311
  "id": "zai/glm-5v-turbo",
4148
4312
  "input": [
@@ -58,10 +58,32 @@ function scanNative(adapter) {
58
58
  }
59
59
 
60
60
  function scanOmp() {
61
- const snapshot = getOmpAuthProviderSnapshot({ forceRefresh: true, accountCheck: true });
61
+ const snapshot = getOmpAuthProviderSnapshot({ forceRefresh: true, accountCheck: true }) || {};
62
62
  const hasAccounts = (snapshot.providers || []).some(provider => (
63
63
  provider.loggedIn === true && Array.isArray(provider.accounts) && provider.accounts.length > 0
64
64
  ));
65
+ if (!hasAccounts) {
66
+ const native = readAllNativeOAuth('omp') || [];
67
+ let synced = null;
68
+ if (native.length) {
69
+ try {
70
+ synced = oauthStore.syncLocalCredential('omp');
71
+ } catch {
72
+ synced = null;
73
+ }
74
+ }
75
+ const credentials = synced?.credentials || [];
76
+ const candidates = native.map((metadata, index) => nativeCandidate('omp', metadata, credentials[index]));
77
+ return {
78
+ candidates,
79
+ nativeState: {
80
+ available: snapshot.available === true || candidates.length > 0,
81
+ providers: snapshot.providers || [],
82
+ checkedAt: snapshot.checkedAt
83
+ },
84
+ warnings: candidates.length ? [] : [snapshot.reason || 'omp: unavailable: no logged-in local provider']
85
+ };
86
+ }
65
87
  let synced = null;
66
88
  if (hasAccounts) {
67
89
  try {
@@ -81,13 +103,14 @@ function scanOmp() {
81
103
  const credential = credentials.find(item => (
82
104
  item.providerId === provider.id
83
105
  && (item.accountId === String(accountId || '') || item.accountEmail === String(accountEmail || ''))
84
- ));
106
+ )) || credentials
107
+ .filter(item => item.providerId === provider.id)[Number(accountId) - 1] || null;
85
108
  const ref = safeRef({
86
109
  credentialId: credential?.id,
87
110
  providerId: provider.id,
88
- accountId,
89
- identityKey,
90
- accountEmail
111
+ accountId: credential?.accountId || accountId,
112
+ identityKey: credential?.identityKey || identityKey,
113
+ accountEmail: credential?.accountEmail || accountEmail
91
114
  });
92
115
  if (!ref.accountId && !ref.identityKey && (provider.accounts || []).length > 1) continue;
93
116
  candidates.push({
@@ -132,8 +155,15 @@ const adapters = Object.freeze({
132
155
  },
133
156
  omp: {
134
157
  scan: scanOmp,
135
- quota: async () => ({ status: 'unavailable', error: 'OMP native OAuth quota is unavailable' }),
158
+ usage: (ref) => oauthStore.fetchCredentialUsage('omp', ref.credentialId),
159
+ quota: (ref) => oauthStore.fetchCredentialUsage('omp', ref.credentialId),
136
160
  channelServicePath: './drivers/omp/channels-implementation'
161
+ },
162
+ opencode: {
163
+ scan: () => scanNative('opencode'),
164
+ usage: (ref) => oauthStore.fetchCredentialUsage('opencode', ref.credentialId),
165
+ quota: (ref) => oauthStore.fetchCredentialUsage('opencode', ref.credentialId),
166
+ channelServicePath: './drivers/opencode/channels-implementation'
137
167
  }
138
168
  });
139
169
 
@@ -3,7 +3,7 @@
3
3
  const { getChannelAuthAdapter, listChannelAuthPlatforms, safeRef } = require('./channel-auth-registry');
4
4
 
5
5
  const quotaCache = new Map();
6
- const QUOTA_TTL_MS = 5 * 60 * 1000;
6
+ const QUOTA_TTL_MS = 60 * 1000;
7
7
 
8
8
  function getAdapter(platform) {
9
9
  const adapter = getChannelAuthAdapter(platform);
@@ -37,11 +37,21 @@ function resolveChannelAuthRef(adapter, channel) {
37
37
  const matched = candidates.find(candidate => matchChannel(channel, candidate));
38
38
  if (matched) return safeRef(matched.authRef);
39
39
 
40
+ // A channel may retain an old account ID after the local OAuth store rotates
41
+ // credentials. When there is exactly one account for the same provider, it
42
+ // is safe to rebind the stale reference for quota lookup.
43
+ const soleCandidate = candidates.length === 1 ? candidates[0] : null;
44
+ const soleRef = safeRef(soleCandidate?.authRef);
45
+ const providerId = current.providerId || String(channel?.oauthProviderId || '').trim();
46
+ if (soleCandidate && providerId && soleRef.providerId === providerId) {
47
+ return soleRef;
48
+ }
49
+
40
50
  // A channel created before OAuth credentials were synced can have no stable
41
51
  // reference. Only auto-select when the local scan found exactly one account.
42
52
  if (!current.credentialId && !current.providerId && !current.accountId
43
- && !current.identityKey && !current.accountEmail && candidates.length === 1) {
44
- return safeRef(candidates[0].authRef);
53
+ && !current.identityKey && !current.accountEmail && soleCandidate) {
54
+ return soleRef;
45
55
  }
46
56
 
47
57
  return current;
@@ -600,6 +600,34 @@ class CommandsService {
600
600
  return { ...detail, name: safeName, namespace: safeNamespace || null, scope, path: relativePath };
601
601
  }
602
602
 
603
+ /**
604
+ * Read an existing command by its scanned relative path.
605
+ * Existing files may predate the current command-name rules, so reading
606
+ * them must not re-validate the filename as if it were a new command.
607
+ */
608
+ getCommandByPath(commandPath, scope = 'user', projectPath = null) {
609
+ const baseDir = this._getBaseDir(scope, projectPath);
610
+ const relativePath = normalizeSafeRelativePath(commandPath, 'command path');
611
+ const extension = getCommandFileExtension(this.platform);
612
+ if (!relativePath.toLowerCase().endsWith(extension)) {
613
+ throw new Error('Invalid command path');
614
+ }
615
+
616
+ const detail = this._getLocalIndex(scope, projectPath)?.getSync(relativePath);
617
+ if (!detail) return null;
618
+
619
+ const name = path.posix.basename(relativePath, extension);
620
+ const namespace = path.posix.dirname(relativePath);
621
+ return {
622
+ ...detail,
623
+ name,
624
+ namespace: namespace === '.' ? null : namespace,
625
+ scope,
626
+ path: relativePath,
627
+ fullPath: path.join(baseDir, relativePath)
628
+ };
629
+ }
630
+
603
631
  /** 创建命令 */
604
632
  createCommand({ name, scope, projectPath, namespace, description, allowedTools, argumentHint, agent, model, subtask, body }) {
605
633
  const safeName = normalizeCommandName(name);
@@ -47,6 +47,7 @@ function getDriverRegistry() {
47
47
  'generic-openai-compatible': createGenericOpenAICompatibleDriver,
48
48
  'generic-mcp': createGenericMcpDriver,
49
49
  'generic-prompt': createGenericPromptDriver,
50
+ 'generic-native-config': require('./drivers/generic-native-config').createDriver,
50
51
  'opencode-conversion': require('./drivers/opencode/conversion').createDriver,
51
52
  'claude-health': require('./drivers/claude/health').createDriver,
52
53
  'dsh-api': require('./drivers/dsh/api-operations').createDriver,