@zvec/zvec-grep 0.1.4 → 0.1.6

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 (356) hide show
  1. package/README.md +86 -162
  2. package/README_CN.md +80 -162
  3. package/dist/authorization/index.d.ts +7 -0
  4. package/dist/authorization/index.js +7 -0
  5. package/dist/authorization/index.js.map +1 -0
  6. package/dist/authorization/manager.d.ts +8 -0
  7. package/dist/authorization/manager.js +19 -0
  8. package/dist/authorization/manager.js.map +1 -0
  9. package/dist/authorization/operation.d.ts +7 -0
  10. package/dist/authorization/operation.js +50 -0
  11. package/dist/authorization/operation.js.map +1 -0
  12. package/dist/authorization/planner.d.ts +21 -0
  13. package/dist/authorization/planner.js +97 -0
  14. package/dist/authorization/planner.js.map +1 -0
  15. package/dist/authorization/prompt.d.ts +11 -0
  16. package/dist/authorization/prompt.js +62 -0
  17. package/dist/authorization/prompt.js.map +1 -0
  18. package/dist/authorization/store.d.ts +20 -0
  19. package/dist/authorization/store.js +251 -0
  20. package/dist/authorization/store.js.map +1 -0
  21. package/dist/authorization/target.d.ts +15 -0
  22. package/dist/authorization/target.js +49 -0
  23. package/dist/authorization/target.js.map +1 -0
  24. package/dist/authorization/types.d.ts +61 -0
  25. package/dist/authorization/types.js +2 -0
  26. package/dist/authorization/types.js.map +1 -0
  27. package/dist/cli/args.d.ts +3 -0
  28. package/dist/cli/args.js +749 -201
  29. package/dist/cli/args.js.map +1 -1
  30. package/dist/cli/auth.d.ts +21 -0
  31. package/dist/cli/auth.js +212 -0
  32. package/dist/cli/auth.js.map +1 -0
  33. package/dist/cli/commands.d.ts +3 -1
  34. package/dist/cli/commands.js +529 -180
  35. package/dist/cli/commands.js.map +1 -1
  36. package/dist/cli/errors.js +7 -6
  37. package/dist/cli/errors.js.map +1 -1
  38. package/dist/cli/format/context.d.ts +1 -0
  39. package/dist/cli/format/context.js +270 -70
  40. package/dist/cli/format/context.js.map +1 -1
  41. package/dist/cli/format/debug.js +14 -16
  42. package/dist/cli/format/debug.js.map +1 -1
  43. package/dist/cli/format/highlight.js.map +1 -1
  44. package/dist/cli/format/progress.d.ts +4 -0
  45. package/dist/cli/format/progress.js +222 -44
  46. package/dist/cli/format/progress.js.map +1 -1
  47. package/dist/cli/format/range.js.map +1 -1
  48. package/dist/cli/format/status.d.ts +77 -6
  49. package/dist/cli/format/status.js +343 -114
  50. package/dist/cli/format/status.js.map +1 -1
  51. package/dist/cli/help.d.ts +1 -1
  52. package/dist/cli/help.js +368 -84
  53. package/dist/cli/help.js.map +1 -1
  54. package/dist/cli/index.js +4 -4
  55. package/dist/cli/index.js.map +1 -1
  56. package/dist/cli/install.d.ts +4 -0
  57. package/dist/cli/install.js +845 -0
  58. package/dist/cli/install.js.map +1 -0
  59. package/dist/cli/managed-rg.d.ts +10 -0
  60. package/dist/cli/managed-rg.js +329 -0
  61. package/dist/cli/managed-rg.js.map +1 -0
  62. package/dist/cli/types.d.ts +40 -13
  63. package/dist/cli/types.js.map +1 -1
  64. package/dist/cli/version.js +3 -1
  65. package/dist/cli/version.js.map +1 -1
  66. package/dist/client/daemon-client.d.ts +19 -0
  67. package/dist/client/daemon-client.js +180 -0
  68. package/dist/client/daemon-client.js.map +1 -0
  69. package/dist/client/mode-router.d.ts +9 -0
  70. package/dist/client/mode-router.js +28 -0
  71. package/dist/client/mode-router.js.map +1 -0
  72. package/dist/client/search-policy.d.ts +11 -0
  73. package/dist/client/search-policy.js +15 -0
  74. package/dist/client/search-policy.js.map +1 -0
  75. package/dist/daemon/backend.d.ts +76 -0
  76. package/dist/daemon/backend.js +1049 -0
  77. package/dist/daemon/backend.js.map +1 -0
  78. package/dist/daemon/change-set.d.ts +25 -0
  79. package/dist/daemon/change-set.js +101 -0
  80. package/dist/daemon/change-set.js.map +1 -0
  81. package/dist/daemon/config.d.ts +24 -0
  82. package/dist/daemon/config.js +88 -0
  83. package/dist/daemon/config.js.map +1 -0
  84. package/dist/daemon/errors.d.ts +5 -0
  85. package/dist/daemon/errors.js +11 -0
  86. package/dist/daemon/errors.js.map +1 -0
  87. package/dist/daemon/http-server.d.ts +30 -0
  88. package/dist/daemon/http-server.js +287 -0
  89. package/dist/daemon/http-server.js.map +1 -0
  90. package/dist/daemon/index-coordinator.d.ts +23 -0
  91. package/dist/daemon/index-coordinator.js +68 -0
  92. package/dist/daemon/index-coordinator.js.map +1 -0
  93. package/dist/daemon/job-scheduler.d.ts +70 -0
  94. package/dist/daemon/job-scheduler.js +366 -0
  95. package/dist/daemon/job-scheduler.js.map +1 -0
  96. package/dist/daemon/logger.d.ts +9 -0
  97. package/dist/daemon/logger.js +53 -0
  98. package/dist/daemon/logger.js.map +1 -0
  99. package/dist/daemon/model-pool.d.ts +45 -0
  100. package/dist/daemon/model-pool.js +187 -0
  101. package/dist/daemon/model-pool.js.map +1 -0
  102. package/dist/daemon/root-lease.d.ts +14 -0
  103. package/dist/daemon/root-lease.js +188 -0
  104. package/dist/daemon/root-lease.js.map +1 -0
  105. package/dist/daemon/root-runtime.d.ts +78 -0
  106. package/dist/daemon/root-runtime.js +333 -0
  107. package/dist/daemon/root-runtime.js.map +1 -0
  108. package/dist/daemon/runtime-manager.d.ts +45 -0
  109. package/dist/daemon/runtime-manager.js +243 -0
  110. package/dist/daemon/runtime-manager.js.map +1 -0
  111. package/dist/daemon/runtime.d.ts +12 -0
  112. package/dist/daemon/runtime.js +102 -0
  113. package/dist/daemon/runtime.js.map +1 -0
  114. package/dist/daemon/server-controller.d.ts +39 -0
  115. package/dist/daemon/server-controller.js +203 -0
  116. package/dist/daemon/server-controller.js.map +1 -0
  117. package/dist/daemon/watch-manager.d.ts +50 -0
  118. package/dist/daemon/watch-manager.js +293 -0
  119. package/dist/daemon/watch-manager.js.map +1 -0
  120. package/dist/daemon/workspace-read-session-cache.d.ts +31 -0
  121. package/dist/daemon/workspace-read-session-cache.js +115 -0
  122. package/dist/daemon/workspace-read-session-cache.js.map +1 -0
  123. package/dist/engine/config.d.ts +50 -0
  124. package/dist/engine/config.js +321 -0
  125. package/dist/engine/config.js.map +1 -0
  126. package/dist/engine/{errors/index.d.ts → errors.d.ts} +6 -1
  127. package/dist/engine/{errors/details.js → errors.js} +17 -4
  128. package/dist/engine/errors.js.map +1 -0
  129. package/dist/engine/extraction/code/adapter.d.ts +1 -1
  130. package/dist/engine/extraction/code/adapter.js.map +1 -1
  131. package/dist/engine/extraction/code/extractor.d.ts +5 -11
  132. package/dist/engine/extraction/code/extractor.js +184 -109
  133. package/dist/engine/extraction/code/extractor.js.map +1 -1
  134. package/dist/engine/extraction/code/families/c-family.js +13 -7
  135. package/dist/engine/extraction/code/families/c-family.js.map +1 -1
  136. package/dist/engine/extraction/code/families/js-ts.d.ts +1 -1
  137. package/dist/engine/extraction/code/families/js-ts.js +24 -18
  138. package/dist/engine/extraction/code/families/js-ts.js.map +1 -1
  139. package/dist/engine/extraction/code/families/metadata.d.ts +1 -1
  140. package/dist/engine/extraction/code/families/metadata.js +11 -8
  141. package/dist/engine/extraction/code/families/metadata.js.map +1 -1
  142. package/dist/engine/extraction/code/families/name-field.js +5 -5
  143. package/dist/engine/extraction/code/families/name-field.js.map +1 -1
  144. package/dist/engine/extraction/code/languages/c.js +1 -4
  145. package/dist/engine/extraction/code/languages/c.js.map +1 -1
  146. package/dist/engine/extraction/code/languages/cpp.js.map +1 -1
  147. package/dist/engine/extraction/code/languages/go.js +1 -3
  148. package/dist/engine/extraction/code/languages/go.js.map +1 -1
  149. package/dist/engine/extraction/code/languages/java.js.map +1 -1
  150. package/dist/engine/extraction/code/languages/javascript.js +1 -3
  151. package/dist/engine/extraction/code/languages/javascript.js.map +1 -1
  152. package/dist/engine/extraction/code/languages/python.js +5 -6
  153. package/dist/engine/extraction/code/languages/python.js.map +1 -1
  154. package/dist/engine/extraction/code/languages/rust.js +1 -5
  155. package/dist/engine/extraction/code/languages/rust.js.map +1 -1
  156. package/dist/engine/extraction/code/languages/typescript.js.map +1 -1
  157. package/dist/engine/extraction/code/tree-sitter/grammar.js.map +1 -0
  158. package/dist/engine/extraction/{tree-sitter → code/tree-sitter}/nodes.js +2 -1
  159. package/dist/engine/extraction/code/tree-sitter/nodes.js.map +1 -0
  160. package/dist/engine/extraction/code/tree-sitter/parser.js.map +1 -0
  161. package/dist/engine/extraction/ids.js.map +1 -1
  162. package/dist/engine/extraction/image/extractor.d.ts +5 -0
  163. package/dist/engine/extraction/image/extractor.js +35 -0
  164. package/dist/engine/extraction/image/extractor.js.map +1 -0
  165. package/dist/engine/extraction/index.d.ts +3 -44
  166. package/dist/engine/extraction/index.js +1 -280
  167. package/dist/engine/extraction/index.js.map +1 -1
  168. package/dist/engine/extraction/markdown/extractor.d.ts +5 -11
  169. package/dist/engine/extraction/markdown/extractor.js +37 -16
  170. package/dist/engine/extraction/markdown/extractor.js.map +1 -1
  171. package/dist/engine/extraction/runtime.d.ts +4 -0
  172. package/dist/engine/extraction/runtime.js +26 -0
  173. package/dist/engine/extraction/runtime.js.map +1 -0
  174. package/dist/engine/extraction/source.d.ts +18 -0
  175. package/dist/engine/extraction/source.js +22 -0
  176. package/dist/engine/extraction/source.js.map +1 -0
  177. package/dist/engine/extraction/text/extractor.d.ts +7 -0
  178. package/dist/engine/extraction/text/extractor.js +168 -0
  179. package/dist/engine/extraction/text/extractor.js.map +1 -0
  180. package/dist/engine/extraction/types.d.ts +4 -0
  181. package/dist/engine/{models → extraction}/types.js.map +1 -1
  182. package/dist/engine/{files/file-type.d.ts → file-type.d.ts} +1 -1
  183. package/dist/engine/file-type.js.map +1 -0
  184. package/dist/engine/index-status.d.ts +9 -0
  185. package/dist/engine/index-status.js +38 -0
  186. package/dist/engine/index-status.js.map +1 -0
  187. package/dist/engine/manifest.d.ts +12 -0
  188. package/dist/engine/manifest.js +120 -0
  189. package/dist/engine/manifest.js.map +1 -0
  190. package/dist/engine/models/{providers/llama-cpp/embedding.d.ts → backends/llama-cpp.d.ts} +25 -20
  191. package/dist/engine/models/{providers/llama-cpp/embedding.js → backends/llama-cpp.js} +165 -113
  192. package/dist/engine/models/backends/llama-cpp.js.map +1 -0
  193. package/dist/engine/models/backends/model2vec.d.ts +57 -0
  194. package/dist/engine/models/backends/model2vec.js +332 -0
  195. package/dist/engine/models/backends/model2vec.js.map +1 -0
  196. package/dist/engine/models/backends/qwen.d.ts +44 -0
  197. package/dist/engine/models/{providers/qwen/embedding.js → backends/qwen.js} +168 -102
  198. package/dist/engine/models/backends/qwen.js.map +1 -0
  199. package/dist/engine/models/backends/transformers-js.d.ts +87 -0
  200. package/dist/engine/models/backends/transformers-js.js +316 -0
  201. package/dist/engine/models/backends/transformers-js.js.map +1 -0
  202. package/dist/engine/models/catalog.d.ts +188 -23
  203. package/dist/engine/models/catalog.js +172 -41
  204. package/dist/engine/models/catalog.js.map +1 -1
  205. package/dist/engine/models/download-progress.d.ts +15 -0
  206. package/dist/engine/models/download-progress.js +48 -0
  207. package/dist/engine/models/download-progress.js.map +1 -0
  208. package/dist/engine/models/embeddings.d.ts +58 -18
  209. package/dist/engine/models/embeddings.js +53 -29
  210. package/dist/engine/models/embeddings.js.map +1 -1
  211. package/dist/engine/models/factory.d.ts +2 -5
  212. package/dist/engine/models/factory.js +41 -56
  213. package/dist/engine/models/factory.js.map +1 -1
  214. package/dist/engine/models/index.d.ts +4 -6
  215. package/dist/engine/models/index.js +4 -4
  216. package/dist/engine/models/index.js.map +1 -1
  217. package/dist/engine/models/ranking.d.ts +7 -3
  218. package/dist/engine/models/resolution.d.ts +8 -0
  219. package/dist/engine/models/resolution.js +22 -0
  220. package/dist/engine/models/resolution.js.map +1 -0
  221. package/dist/engine/pipeline/indexing/index.d.ts +9 -7
  222. package/dist/engine/pipeline/indexing/index.js +399 -147
  223. package/dist/engine/pipeline/indexing/index.js.map +1 -1
  224. package/dist/engine/pipeline/indexing/root-paths.js +16 -19
  225. package/dist/engine/pipeline/indexing/root-paths.js.map +1 -1
  226. package/dist/engine/pipeline/indexing/scanner/index.d.ts +6 -1
  227. package/dist/engine/pipeline/indexing/scanner/index.js +318 -66
  228. package/dist/engine/pipeline/indexing/scanner/index.js.map +1 -1
  229. package/dist/engine/pipeline/search/index.d.ts +6 -6
  230. package/dist/engine/pipeline/search/index.js +76 -34
  231. package/dist/engine/pipeline/search/index.js.map +1 -1
  232. package/dist/engine/service/index.d.ts +3 -2
  233. package/dist/engine/service/index.js +1 -1
  234. package/dist/engine/service/index.js.map +1 -1
  235. package/dist/engine/service/lexical.d.ts +14 -15
  236. package/dist/engine/service/lexical.js +78 -119
  237. package/dist/engine/service/lexical.js.map +1 -1
  238. package/dist/engine/service/root.d.ts +13 -12
  239. package/dist/engine/service/root.js +35 -24
  240. package/dist/engine/service/root.js.map +1 -1
  241. package/dist/engine/service/structure-enrichment.js +29 -25
  242. package/dist/engine/service/structure-enrichment.js.map +1 -1
  243. package/dist/engine/service/types.d.ts +61 -35
  244. package/dist/engine/service/workspace-index.d.ts +24 -0
  245. package/dist/engine/service/workspace-index.js +151 -0
  246. package/dist/engine/service/workspace-index.js.map +1 -0
  247. package/dist/engine/service/zvec-grep.d.ts +12 -1
  248. package/dist/engine/service/zvec-grep.js +878 -544
  249. package/dist/engine/service/zvec-grep.js.map +1 -1
  250. package/dist/engine/storage/index.d.ts +8 -4
  251. package/dist/engine/storage/index.js +1 -1
  252. package/dist/engine/storage/index.js.map +1 -1
  253. package/dist/engine/storage/zvec.d.ts +10 -33
  254. package/dist/engine/storage/zvec.js +110 -49
  255. package/dist/engine/storage/zvec.js.map +1 -1
  256. package/dist/engine/types.d.ts +29 -23
  257. package/dist/engine/types.js +1 -1
  258. package/dist/engine/types.js.map +1 -1
  259. package/dist/engine/utils/daemon-lease.d.ts +17 -0
  260. package/dist/engine/utils/daemon-lease.js +175 -0
  261. package/dist/engine/utils/daemon-lease.js.map +1 -0
  262. package/dist/engine/utils/file-selection.d.ts +10 -0
  263. package/dist/engine/utils/file-selection.js +157 -0
  264. package/dist/engine/utils/file-selection.js.map +1 -0
  265. package/dist/engine/utils/glob.d.ts +3 -0
  266. package/dist/engine/utils/glob.js +116 -18
  267. package/dist/engine/utils/glob.js.map +1 -1
  268. package/dist/engine/utils/hash.js.map +1 -1
  269. package/dist/engine/utils/json.d.ts +6 -2
  270. package/dist/engine/utils/json.js +50 -12
  271. package/dist/engine/utils/json.js.map +1 -1
  272. package/dist/engine/utils/lock.js +7 -7
  273. package/dist/engine/utils/lock.js.map +1 -1
  274. package/dist/engine/utils/path.js +2 -2
  275. package/dist/engine/utils/path.js.map +1 -1
  276. package/dist/engine/utils/timing.js.map +1 -1
  277. package/dist/index-progress.d.ts +10 -0
  278. package/dist/index-progress.js +159 -0
  279. package/dist/index-progress.js.map +1 -0
  280. package/dist/index.d.ts +6 -6
  281. package/dist/index.js +3 -3
  282. package/dist/index.js.map +1 -1
  283. package/dist/mcp/http-transport.d.ts +27 -0
  284. package/dist/mcp/http-transport.js +182 -0
  285. package/dist/mcp/http-transport.js.map +1 -0
  286. package/dist/mcp/input-normalization.d.ts +38 -0
  287. package/dist/mcp/input-normalization.js +95 -0
  288. package/dist/mcp/input-normalization.js.map +1 -0
  289. package/dist/mcp/progress-heartbeat.d.ts +17 -0
  290. package/dist/mcp/progress-heartbeat.js +46 -0
  291. package/dist/mcp/progress-heartbeat.js.map +1 -0
  292. package/dist/mcp/request-metadata.d.ts +2 -0
  293. package/dist/mcp/request-metadata.js +11 -0
  294. package/dist/mcp/request-metadata.js.map +1 -0
  295. package/dist/mcp/request-state.d.ts +40 -0
  296. package/dist/mcp/request-state.js +210 -0
  297. package/dist/mcp/request-state.js.map +1 -0
  298. package/dist/mcp/result-format.d.ts +13 -0
  299. package/dist/mcp/result-format.js +75 -0
  300. package/dist/mcp/result-format.js.map +1 -0
  301. package/dist/mcp/schemas.d.ts +430 -0
  302. package/dist/mcp/schemas.js +447 -0
  303. package/dist/mcp/schemas.js.map +1 -0
  304. package/dist/mcp/tools.d.ts +150 -0
  305. package/dist/mcp/tools.js +448 -0
  306. package/dist/mcp/tools.js.map +1 -0
  307. package/dist/mcp/toolset.d.ts +5 -0
  308. package/dist/mcp/toolset.js +12 -0
  309. package/dist/mcp/toolset.js.map +1 -0
  310. package/dist/observability/trace-context.d.ts +11 -0
  311. package/dist/observability/trace-context.js +138 -0
  312. package/dist/observability/trace-context.js.map +1 -0
  313. package/docs/01-agents.md +111 -0
  314. package/docs/02-cli.md +229 -0
  315. package/docs/03-mcp.md +167 -0
  316. package/docs/04-pipeline.md +218 -0
  317. package/docs/05-architecture.md +86 -0
  318. package/docs/06-server.md +210 -0
  319. package/docs/07-embedding.md +179 -0
  320. package/docs/08-roadmap.md +85 -0
  321. package/docs/README.md +53 -0
  322. package/package.json +43 -7
  323. package/skills/zvec-grep/SKILL.md +43 -123
  324. package/skills/zvec-grep/agents/openai.yaml +2 -2
  325. package/skills/zvec-grep/references/cli-fallback.md +85 -0
  326. package/dist/engine/collection/index.d.ts +0 -55
  327. package/dist/engine/collection/index.js +0 -710
  328. package/dist/engine/collection/index.js.map +0 -1
  329. package/dist/engine/errors/details.d.ts +0 -6
  330. package/dist/engine/errors/details.js.map +0 -1
  331. package/dist/engine/errors/index.js +0 -16
  332. package/dist/engine/errors/index.js.map +0 -1
  333. package/dist/engine/extraction/tree-sitter/grammar.js.map +0 -1
  334. package/dist/engine/extraction/tree-sitter/nodes.js.map +0 -1
  335. package/dist/engine/extraction/tree-sitter/parser.js.map +0 -1
  336. package/dist/engine/files/file-type.js.map +0 -1
  337. package/dist/engine/models/providers/index.d.ts +0 -2
  338. package/dist/engine/models/providers/index.js +0 -3
  339. package/dist/engine/models/providers/index.js.map +0 -1
  340. package/dist/engine/models/providers/llama-cpp/embedding.js.map +0 -1
  341. package/dist/engine/models/providers/llama-cpp/index.d.ts +0 -1
  342. package/dist/engine/models/providers/llama-cpp/index.js +0 -2
  343. package/dist/engine/models/providers/llama-cpp/index.js.map +0 -1
  344. package/dist/engine/models/providers/qwen/embedding.d.ts +0 -42
  345. package/dist/engine/models/providers/qwen/embedding.js.map +0 -1
  346. package/dist/engine/models/providers/qwen/index.d.ts +0 -1
  347. package/dist/engine/models/providers/qwen/index.js +0 -2
  348. package/dist/engine/models/providers/qwen/index.js.map +0 -1
  349. package/dist/engine/models/types.d.ts +0 -30
  350. /package/dist/engine/extraction/{tree-sitter → code/tree-sitter}/grammar.d.ts +0 -0
  351. /package/dist/engine/extraction/{tree-sitter → code/tree-sitter}/grammar.js +0 -0
  352. /package/dist/engine/extraction/{tree-sitter → code/tree-sitter}/nodes.d.ts +0 -0
  353. /package/dist/engine/extraction/{tree-sitter → code/tree-sitter}/parser.d.ts +0 -0
  354. /package/dist/engine/extraction/{tree-sitter → code/tree-sitter}/parser.js +0 -0
  355. /package/dist/engine/{models → extraction}/types.js +0 -0
  356. /package/dist/engine/{files/file-type.js → file-type.js} +0 -0
package/dist/cli/args.js CHANGED
@@ -1,27 +1,45 @@
1
1
  import { VALID_SYMBOL_TYPES } from "./types.js";
2
+ import { parseMcpToolset } from "../mcp/toolset.js";
2
3
  const RG_OPTIONS_WITH_VALUE = new Set([
4
+ "--dfa-size-limit",
3
5
  "--encoding",
4
6
  "--engine",
5
- "--ignore-file",
6
- "--max-depth",
7
- "--type",
8
- "--type-not",
7
+ "--max-columns",
8
+ "--max-count",
9
+ "--regex-size-limit",
10
+ "--threads",
9
11
  ]);
10
12
  const RG_OPTIONS_WITHOUT_VALUE = new Set([
11
13
  "--auto-hybrid-regex",
12
14
  "--case-sensitive",
13
- "--glob-case-insensitive",
15
+ "--binary",
16
+ "--crlf",
17
+ "--invert-match",
18
+ "--line-regexp",
19
+ "--mmap",
14
20
  "--multiline",
15
21
  "--multiline-dotall",
22
+ "--no-crlf",
23
+ "--no-fixed-strings",
16
24
  "--no-ignore",
17
25
  "--no-ignore-dot",
18
26
  "--no-ignore-files",
19
27
  "--no-ignore-global",
20
28
  "--no-ignore-parent",
21
29
  "--no-ignore-vcs",
30
+ "--no-config",
31
+ "--no-mmap",
32
+ "--no-multiline",
33
+ "--no-search-zip",
22
34
  "--pcre2",
35
+ "--one-file-system",
23
36
  "--search-zip",
24
37
  "--smart-case",
38
+ "--stop-on-nonmatch",
39
+ "--text",
40
+ "--unicode",
41
+ "--no-unicode",
42
+ "--glob-case-insensitive",
25
43
  ]);
26
44
  const MANAGED_RG_OUTPUT_OPTIONS = new Set([
27
45
  "--count",
@@ -29,18 +47,76 @@ const MANAGED_RG_OUTPUT_OPTIONS = new Set([
29
47
  "--files",
30
48
  "--files-with-matches",
31
49
  "--files-without-match",
50
+ "--column",
51
+ "--byte-offset",
52
+ "--no-column",
53
+ "--colors",
54
+ "--context-separator",
55
+ "--field-context-separator",
56
+ "--field-match-separator",
32
57
  "--json",
58
+ "--heading",
59
+ "--no-heading",
60
+ "--no-filename",
61
+ "--no-line-number",
33
62
  "--only-matching",
63
+ "--passthru",
64
+ "--path-separator",
65
+ "--quiet",
66
+ "--pretty",
34
67
  "--replace",
68
+ "--stats",
69
+ "--trim",
35
70
  "--vimgrep",
36
71
  "-c",
72
+ "-b",
73
+ "-I",
37
74
  "-l",
75
+ "-N",
38
76
  "-o",
77
+ "-p",
78
+ "-q",
79
+ "-r",
39
80
  ]);
40
81
  export function parseArgs(args) {
82
+ const commandInput = parseCommand(args);
83
+ if (commandInput.command === "help" || commandInput.command === "version") {
84
+ return {
85
+ command: commandInput.command,
86
+ options: {},
87
+ positionals: [],
88
+ ...(commandInput.helpTopic ? { helpTopic: commandInput.helpTopic } : {}),
89
+ };
90
+ }
41
91
  const options = {};
42
92
  const positionals = [];
43
- for (let index = 0; index < args.length; index++) {
93
+ let startIndex = 1;
94
+ if (commandInput.command === "config") {
95
+ if (args[1] === "model" && args[2] === "set") {
96
+ options.configAction = "model-set";
97
+ startIndex = 3;
98
+ }
99
+ else if (args[1] === "provider" && args[2] === "set") {
100
+ options.configAction = "provider-set";
101
+ startIndex = 3;
102
+ }
103
+ }
104
+ else if (commandInput.command === "auth") {
105
+ if (args[1] === "grant" || args[1] === "status" || args[1] === "revoke") {
106
+ options.authAction = args[1];
107
+ startIndex = 2;
108
+ }
109
+ }
110
+ else if (commandInput.command === "server") {
111
+ if (args[1] === "on" ||
112
+ args[1] === "off" ||
113
+ args[1] === "status" ||
114
+ args[1] === "run") {
115
+ options.serverAction = args[1];
116
+ startIndex = 2;
117
+ }
118
+ }
119
+ for (let index = startIndex; index < args.length; index++) {
44
120
  const arg = args[index];
45
121
  if (arg === "--") {
46
122
  positionals.push(...args.slice(index + 1));
@@ -51,22 +127,85 @@ export function parseArgs(args) {
51
127
  continue;
52
128
  }
53
129
  if (arg === "--help" || arg === "-h") {
54
- options.help = true;
130
+ return {
131
+ command: "help",
132
+ options: {},
133
+ positionals: [],
134
+ helpTopic: commandInput.command,
135
+ };
136
+ }
137
+ else if (arg === "--version") {
138
+ throw new Error(`${arg} must be used without a command`);
139
+ }
140
+ else if (isLongOptionWithValue(arg, "--mode")) {
141
+ options.mode = parseClientMode(valueFromLongOption(arg));
142
+ }
143
+ else if (arg === "--mode") {
144
+ options.mode = parseClientMode(readOptionValue(args, ++index, arg));
145
+ }
146
+ else if (arg === "--force-direct") {
147
+ options.forceDirect = true;
148
+ }
149
+ else if (isLongOptionWithValue(arg, "--mcp-toolset")) {
150
+ options.mcpToolset = parseMcpToolset(valueFromLongOption(arg));
151
+ }
152
+ else if (arg === "--mcp-toolset") {
153
+ options.mcpToolset = parseMcpToolset(readOptionValue(args, ++index, arg));
154
+ }
155
+ else if (isLongOptionWithValue(arg, "--listen")) {
156
+ options.listen = valueFromLongOption(arg);
157
+ }
158
+ else if (arg === "--listen") {
159
+ options.listen = readOptionValue(args, ++index, arg);
160
+ }
161
+ else if (isLongOptionWithValue(arg, "--token-file")) {
162
+ options.serverTokenFile = valueFromLongOption(arg);
163
+ }
164
+ else if (arg === "--token-file") {
165
+ options.serverTokenFile = readOptionValue(args, ++index, arg);
166
+ }
167
+ else if (isLongOptionWithValue(arg, "--target")) {
168
+ options.installTargets = appendInstallTargets(options.installTargets, valueFromLongOption(arg));
55
169
  }
56
- else if (arg === "--version" || arg === "-v") {
57
- options.version = true;
170
+ else if (arg === "--target") {
171
+ options.installTargets = appendInstallTargets(options.installTargets, readOptionValue(args, ++index, arg));
58
172
  }
59
- else if (arg === "--index") {
60
- options.index = true;
173
+ else if (isLongOptionWithValue(arg, "--mcp-tool-timeout")) {
174
+ options.installMcpToolTimeoutSeconds = parsePositiveInteger(valueFromLongOption(arg), "--mcp-tool-timeout");
61
175
  }
62
- else if (arg === "--disable-index") {
63
- options.disableIndex = true;
176
+ else if (arg === "--mcp-tool-timeout") {
177
+ options.installMcpToolTimeoutSeconds = parsePositiveInteger(readOptionValue(args, ++index, arg), arg);
64
178
  }
65
- else if (arg === "--status") {
66
- options.status = true;
179
+ else if (isLongOptionWithValue(arg, "--mcp-token-env")) {
180
+ options.installMcpTokenEnv = parseEnvironmentVariable(valueFromLongOption(arg), "--mcp-token-env");
67
181
  }
68
- else if (arg === "--collections") {
69
- options.collections = true;
182
+ else if (arg === "--mcp-token-env") {
183
+ options.installMcpTokenEnv = parseEnvironmentVariable(readOptionValue(args, ++index, arg), arg);
184
+ }
185
+ else if (arg === "--yes") {
186
+ options.yes = true;
187
+ }
188
+ else if (isLongOptionWithValue(arg, "--allow-remote")) {
189
+ throw allowRemoteValueError();
190
+ }
191
+ else if (arg === "--allow-remote") {
192
+ const legacyScope = args[index + 1];
193
+ if (legacyScope === "once" || legacyScope === "workspace") {
194
+ throw allowRemoteValueError();
195
+ }
196
+ options.allowRemote = true;
197
+ }
198
+ else if (isLongOptionWithValue(arg, "--capability")) {
199
+ options.authorizationCapability = parseAuthorizationCapability(valueFromLongOption(arg));
200
+ }
201
+ else if (arg === "--capability") {
202
+ options.authorizationCapability = parseAuthorizationCapability(readOptionValue(args, ++index, arg));
203
+ }
204
+ else if (isLongOptionWithValue(arg, "--scope")) {
205
+ options.authorizationScope = parseAuthorizationScope(valueFromLongOption(arg));
206
+ }
207
+ else if (arg === "--scope") {
208
+ options.authorizationScope = parseAuthorizationScope(readOptionValue(args, ++index, arg));
70
209
  }
71
210
  else if (arg === "--rg") {
72
211
  options.rg = true;
@@ -80,6 +219,9 @@ export function parseArgs(args) {
80
219
  else if (arg === "--human") {
81
220
  options.human = true;
82
221
  }
222
+ else if (arg === "--check-ready") {
223
+ options.checkReady = true;
224
+ }
83
225
  else if (isLongOptionWithValue(arg, "--preview")) {
84
226
  options.preview = parsePreviewMode(valueFromLongOption(arg));
85
227
  }
@@ -95,21 +237,27 @@ export function parseArgs(args) {
95
237
  else if (arg === "--rebuild") {
96
238
  options.rebuild = true;
97
239
  }
240
+ else if (arg === "--drop") {
241
+ options.drop = true;
242
+ }
243
+ else if (arg === "--force") {
244
+ options.force = true;
245
+ }
98
246
  else if (arg === "--reset-paths") {
99
247
  options.resetPaths = true;
100
248
  }
101
- else if (arg === "--no-fallback") {
102
- options.noFallback = true;
249
+ else if (arg === "--default") {
250
+ options.defaultModel = true;
251
+ }
252
+ else if (isLongOptionWithValue(arg, "--refresh")) {
253
+ options.refresh = parseQueryRefreshMode(valueFromLongOption(arg));
103
254
  }
104
- else if (arg === "--no-auto-update") {
105
- options.noAutoUpdate = true;
255
+ else if (arg === "--refresh") {
256
+ options.refresh = parseQueryRefreshMode(readOptionValue(args, ++index, arg));
106
257
  }
107
258
  else if (arg === "--prefer-symbol") {
108
259
  options.preferSymbol = true;
109
260
  }
110
- else if (arg === "--collection") {
111
- options.collection = readOptionValue(args, ++index, arg);
112
- }
113
261
  else if (arg === "--home") {
114
262
  options.home = readOptionValue(args, ++index, arg);
115
263
  }
@@ -119,17 +267,8 @@ export function parseArgs(args) {
119
267
  else if (arg === "--model-cache") {
120
268
  options.modelCacheDir = readOptionValue(args, ++index, arg);
121
269
  }
122
- else if (arg === "--gpu") {
123
- options.llamaGpu = "auto";
124
- }
125
- else if (arg === "--no-gpu") {
126
- options.llamaGpu = false;
127
- }
128
- else if (arg === "--llama-gpu") {
129
- options.llamaGpu = parseLlamaGpu(readOptionValue(args, ++index, arg));
130
- }
131
- else if (arg === "--embedding-parallelism") {
132
- options.embeddingParallelism = parsePositiveInteger(readOptionValue(args, ++index, arg), arg);
270
+ else if (arg === "--device") {
271
+ options.device = parseDevice(readOptionValue(args, ++index, arg));
133
272
  }
134
273
  else if (arg === "--api-key") {
135
274
  options.apiKey = readOptionValue(args, ++index, arg);
@@ -143,57 +282,99 @@ export function parseArgs(args) {
143
282
  else if (arg === "--embedding-concurrency") {
144
283
  options.embeddingConcurrency = parsePositiveInteger(readOptionValue(args, ++index, arg), arg);
145
284
  }
285
+ else if (isLongOptionWithValue(arg, "--hybrid")) {
286
+ options.hybridQueries = appendQuery(options.hybridQueries, valueFromLongOption(arg), "--hybrid");
287
+ }
288
+ else if (arg === "--hybrid") {
289
+ options.hybridQueries = appendQuery(options.hybridQueries, readOptionValue(args, ++index, arg), arg);
290
+ }
291
+ else if (isLongOptionWithValue(arg, "--fts")) {
292
+ options.routes = appendRoute(options.routes, "fts", valueFromLongOption(arg), "--fts");
293
+ }
146
294
  else if (arg === "--fts") {
147
- const routeValues = readRouteOptionValues(args, index + 1, arg);
148
- options.routes = appendRoutes(options.routes, "fts", routeValues.values);
149
- index = routeValues.nextIndex - 1;
295
+ options.routes = appendRoute(options.routes, "fts", readOptionValue(args, ++index, arg), arg);
296
+ }
297
+ else if (isLongOptionWithValue(arg, "--vector")) {
298
+ options.routes = appendRoute(options.routes, "vector", valueFromLongOption(arg), "--vector");
150
299
  }
151
300
  else if (arg === "--vector") {
152
- const routeValues = readRouteOptionValues(args, index + 1, arg);
153
- options.routes = appendRoutes(options.routes, "vector", routeValues.values);
154
- index = routeValues.nextIndex - 1;
301
+ options.routes = appendRoute(options.routes, "vector", readOptionValue(args, ++index, arg), arg);
302
+ }
303
+ else if (arg === "--fuse") {
304
+ options.fuse = true;
155
305
  }
156
306
  else if (arg === "--color") {
157
307
  options.color = parseColorMode(readOptionValue(args, ++index, arg));
158
308
  }
159
- else if (isLongOptionWithValue(arg, "--include")) {
160
- options.includePaths = appendPathFilters(options.includePaths, valueFromLongOption(arg));
309
+ else if (isLongOptionWithValue(arg, "--glob")) {
310
+ options.globs = appendValue(options.globs, valueFromLongOption(arg), "--glob");
311
+ }
312
+ else if (arg === "--glob" || arg === "-g") {
313
+ options.globs = appendValue(options.globs, readOptionValue(args, ++index, arg), arg);
161
314
  }
162
- else if (arg === "--include") {
163
- options.includePaths = appendPathFilters(options.includePaths, readOptionValue(args, ++index, arg));
315
+ else if (isLongOptionWithValue(arg, "--iglob")) {
316
+ options.insensitiveGlobs = appendValue(options.insensitiveGlobs, valueFromLongOption(arg), "--iglob");
164
317
  }
165
- else if (isLongOptionWithValue(arg, "--exclude")) {
166
- options.excludePaths = appendPathFilters(options.excludePaths, valueFromLongOption(arg));
318
+ else if (arg === "--iglob") {
319
+ options.insensitiveGlobs = appendValue(options.insensitiveGlobs, readOptionValue(args, ++index, arg), arg);
167
320
  }
168
- else if (arg === "--exclude") {
169
- options.excludePaths = appendPathFilters(options.excludePaths, readOptionValue(args, ++index, arg));
321
+ else if (isLongOptionWithValue(arg, "--type")) {
322
+ options.fileTypes = appendValue(options.fileTypes, valueFromLongOption(arg), "--type");
323
+ }
324
+ else if (arg === "--type" || arg === "-t") {
325
+ options.fileTypes = appendValue(options.fileTypes, readOptionValue(args, ++index, arg), arg);
326
+ }
327
+ else if (isLongOptionWithValue(arg, "--type-not")) {
328
+ options.excludedFileTypes = appendValue(options.excludedFileTypes, valueFromLongOption(arg), "--type-not");
329
+ }
330
+ else if (arg === "--type-not" || arg === "-T") {
331
+ options.excludedFileTypes = appendValue(options.excludedFileTypes, readOptionValue(args, ++index, arg), arg);
332
+ }
333
+ else if (arg === "--hidden") {
334
+ options.hidden = true;
335
+ }
336
+ else if (arg === "--no-ignore") {
337
+ options.noIgnore = true;
338
+ }
339
+ else if (isLongOptionWithValue(arg, "--ignore-file")) {
340
+ options.ignoreFiles = appendValue(options.ignoreFiles, valueFromLongOption(arg), "--ignore-file");
341
+ }
342
+ else if (arg === "--ignore-file") {
343
+ options.ignoreFiles = appendValue(options.ignoreFiles, readOptionValue(args, ++index, arg), arg);
344
+ }
345
+ else if (isLongOptionWithValue(arg, "--max-depth")) {
346
+ options.maxDepth = parseNonNegativeInteger(valueFromLongOption(arg), "--max-depth");
347
+ }
348
+ else if (arg === "--max-depth") {
349
+ options.maxDepth = parseNonNegativeInteger(readOptionValue(args, ++index, arg), arg);
350
+ }
351
+ else if (isLongOptionWithValue(arg, "--max-filesize")) {
352
+ options.maxFileSizeBytes = parseByteSize(valueFromLongOption(arg), "--max-filesize");
353
+ }
354
+ else if (arg === "--max-filesize") {
355
+ options.maxFileSizeBytes = parseByteSize(readOptionValue(args, ++index, arg), arg);
356
+ }
357
+ else if (arg === "--follow" || arg === "-L") {
358
+ options.follow = true;
170
359
  }
171
360
  else if (arg === "--ignore-case") {
172
- options.rgOptions = {
173
- ...(options.rgOptions ?? {}),
174
- ignoreCase: true,
175
- };
361
+ options.rgOptions = appendRgExtraArgs(options.rgOptions, [arg]);
176
362
  markRgCompatibilityOption(options, arg);
177
363
  }
178
364
  else if (arg === "--word-regexp") {
179
- options.rgOptions = {
180
- ...(options.rgOptions ?? {}),
181
- wordRegexp: true,
182
- };
365
+ options.rgOptions = appendRgExtraArgs(options.rgOptions, [arg]);
183
366
  markRgCompatibilityOption(options, arg);
184
367
  }
185
368
  else if (arg === "--fixed-strings") {
186
- options.rgOptions = {
187
- ...(options.rgOptions ?? {}),
188
- fixedStrings: true,
189
- };
369
+ options.rgOptions = appendRgExtraArgs(options.rgOptions, [arg]);
190
370
  markRgCompatibilityOption(options, arg);
191
371
  }
192
- else if (arg === "--hidden") {
193
- options.rgOptions = {
194
- ...(options.rgOptions ?? {}),
195
- hidden: true,
196
- };
372
+ else if (isLongOptionWithValue(arg, "--file")) {
373
+ options.rgOptions = appendRgPatternFile(options.rgOptions, valueFromLongOption(arg), "--file");
374
+ markRgCompatibilityOption(options, "--file");
375
+ }
376
+ else if (arg === "--file") {
377
+ options.rgOptions = appendRgPatternFile(options.rgOptions, readOptionValue(args, ++index, arg), arg);
197
378
  markRgCompatibilityOption(options, arg);
198
379
  }
199
380
  else if (isRgFlagWithValue(arg)) {
@@ -215,7 +396,9 @@ export function parseArgs(args) {
215
396
  options.rgOptions = appendRgExtraArgs(options.rgOptions, [arg]);
216
397
  markRgCompatibilityOption(options, arg);
217
398
  }
218
- else if (arg === "--recursive" || arg === "--line-number" || arg === "--with-filename") {
399
+ else if (arg === "--recursive" ||
400
+ arg === "--line-number" ||
401
+ arg === "--with-filename") {
219
402
  markRgCompatibilityOption(options, arg);
220
403
  }
221
404
  else if (isLongOptionWithValue(arg, "--regexp")) {
@@ -250,18 +433,6 @@ export function parseArgs(args) {
250
433
  options.rgOptions = setRgContext(options.rgOptions, "after", readOptionValue(args, ++index, arg), arg);
251
434
  markRgCompatibilityOption(options, arg);
252
435
  }
253
- else if (isLongOptionWithValue(arg, "--glob")) {
254
- appendRgGlobFilter(options, valueFromLongOption(arg));
255
- markRgCompatibilityOption(options, "--glob");
256
- }
257
- else if (arg === "--glob") {
258
- appendRgGlobFilter(options, readOptionValue(args, ++index, arg));
259
- markRgCompatibilityOption(options, arg);
260
- }
261
- else if (arg === "-g") {
262
- appendRgGlobFilter(options, readOptionValue(args, ++index, arg));
263
- markRgCompatibilityOption(options, arg);
264
- }
265
436
  else if (isManagedRgOutputOption(arg)) {
266
437
  throw new Error(`${arg} changes rg output and cannot be used with managed --rg`);
267
438
  }
@@ -275,83 +446,357 @@ export function parseArgs(args) {
275
446
  options.modifiedBefore = parseModifiedTime(readOptionValue(args, ++index, arg), arg);
276
447
  }
277
448
  else if (arg === "--symbol-type") {
278
- options.symbolTypes = [...(options.symbolTypes ?? []), parseSymbolType(readOptionValue(args, ++index, arg))];
449
+ options.symbolTypes = [
450
+ ...(options.symbolTypes ?? []),
451
+ parseSymbolType(readOptionValue(args, ++index, arg)),
452
+ ];
279
453
  }
280
454
  else {
281
455
  throw new Error(`Unknown option: ${arg}`);
282
456
  }
283
457
  }
284
- validateCliShape(options);
285
- return { options, positionals };
458
+ validateCliShape(commandInput.command, options, positionals);
459
+ return { command: commandInput.command, options, positionals };
286
460
  }
287
- function validateCliShape(options) {
288
- if (options.index && options.collections) {
289
- throw new Error("--index and --collections cannot be used together");
461
+ function parseCommand(args) {
462
+ const [first, ...rest] = args;
463
+ if (first === undefined ||
464
+ first === "help" ||
465
+ first === "-h" ||
466
+ first === "--help") {
467
+ if (first !== "help" && rest.length > 0) {
468
+ throw new Error(`${first} does not accept arguments`);
469
+ }
470
+ if (first === "help" && rest.length > 1) {
471
+ throw new Error("zg help accepts at most one command or topic");
472
+ }
473
+ return {
474
+ command: "help",
475
+ ...(first === "help" && rest[0] ? { helpTopic: rest[0] } : {}),
476
+ };
290
477
  }
291
- if (options.disableIndex && options.collections) {
292
- throw new Error("--disable-index and --collections cannot be used together");
478
+ if (first === "version" || first === "-v" || first === "--version") {
479
+ const acceptsVersionFlag = first === "version" &&
480
+ rest.length === 1 &&
481
+ (rest[0] === "-v" || rest[0] === "--version");
482
+ if (rest.length > 0 && !acceptsVersionFlag) {
483
+ throw new Error(`${first} does not accept arguments`);
484
+ }
485
+ return { command: "version" };
293
486
  }
294
- if (options.disableIndex && options.index) {
295
- throw new Error("--disable-index and --index cannot be used together");
487
+ if (first === "query" ||
488
+ first === "index" ||
489
+ first === "status" ||
490
+ first === "install" ||
491
+ first === "uninstall" ||
492
+ first === "config" ||
493
+ first === "auth" ||
494
+ first === "server") {
495
+ return { command: first };
296
496
  }
297
- if (options.disableIndex && options.status) {
298
- throw new Error("--disable-index and --status cannot be used together");
497
+ if (first === "serve") {
498
+ throw new Error("zg serve has been removed; use zg server on and Streamable HTTP MCP");
299
499
  }
300
- if (options.status && options.collections) {
301
- throw new Error("--status and --collections cannot be used together");
500
+ throw new Error(`Unknown command: ${first}`);
501
+ }
502
+ function validateCliShape(command, options, positionals) {
503
+ if (command === "auth") {
504
+ if (!options.authAction) {
505
+ throw new Error("zg auth requires grant, status, or revoke");
506
+ }
507
+ if (positionals.length > 1) {
508
+ throw new Error(`zg auth ${options.authAction} accepts at most one root`);
509
+ }
510
+ if (options.authAction !== "grant" &&
511
+ (options.authorizationCapability || options.authorizationScope)) {
512
+ throw new Error(`--capability and --scope can only be used with zg auth grant`);
513
+ }
302
514
  }
303
- if (options.status && options.index) {
304
- throw new Error("--status and --index cannot be used together");
515
+ else if (options.authorizationCapability || options.authorizationScope) {
516
+ throw new Error("--capability and --scope can only be used with zg auth");
305
517
  }
306
- if (options.status && options.collection) {
307
- throw new Error("--status does not accept --collection; use --collections info <name>");
518
+ if (options.allowRemote && command !== "query" && command !== "index") {
519
+ throw new Error("--allow-remote can only be used with query or index commands");
308
520
  }
309
- if (options.index && options.collection) {
310
- throw new Error("--index does not accept --collection");
521
+ const queryOnly = firstEnabledOption([
522
+ [options.rg, "--rg"],
523
+ [options.hybridQueries?.length, "--hybrid"],
524
+ [options.routes?.length, "--fts/--vector"],
525
+ [options.fuse, "--fuse"],
526
+ [options.debug, "--debug"],
527
+ [options.trace, "--trace"],
528
+ [options.human, "--human"],
529
+ [options.preview, "--preview"],
530
+ [options.limit, "--limit"],
531
+ [options.refresh, "--refresh"],
532
+ [options.preferSymbol, "--prefer-symbol"],
533
+ [options.symbolTypes?.length, "--symbol-type"],
534
+ [options.modifiedAfter, "--modified-after"],
535
+ [options.modifiedBefore, "--modified-before"],
536
+ [options.rgCompatibilityOptions?.length, "ripgrep options"],
537
+ ]);
538
+ if (command !== "query" && queryOnly) {
539
+ throw new Error(`${queryOnly} can only be used with zg query`);
311
540
  }
312
- if (options.disableIndex && options.collection) {
313
- throw new Error("--disable-index does not accept --collection");
541
+ const sharedSelection = firstEnabledOption([
542
+ [options.globs?.length, "--glob"],
543
+ [options.insensitiveGlobs?.length, "--iglob"],
544
+ [options.fileTypes?.length, "--type"],
545
+ [options.excludedFileTypes?.length, "--type-not"],
546
+ ]);
547
+ if (sharedSelection && command !== "query" && command !== "index") {
548
+ throw new Error(`${sharedSelection} can only be used with query or index commands`);
314
549
  }
315
- if (options.rg && options.collection) {
316
- throw new Error("--rg does not accept --collection");
550
+ const discoveryOption = firstEnabledOption([
551
+ [options.hidden, "--hidden"],
552
+ [options.noIgnore, "--no-ignore"],
553
+ [options.ignoreFiles?.length, "--ignore-file"],
554
+ [options.maxDepth, "--max-depth"],
555
+ [options.maxFileSizeBytes, "--max-filesize"],
556
+ [options.follow, "--follow"],
557
+ ]);
558
+ if (discoveryOption &&
559
+ command !== "index" &&
560
+ !(command === "query" && options.rg)) {
561
+ throw new Error(`${discoveryOption} can only be used with index commands or zg query --rg`);
317
562
  }
318
- if (options.collections && options.collection) {
319
- throw new Error("--collections and --collection cannot be used together");
563
+ if (command === "config") {
564
+ if (!options.configAction) {
565
+ throw new Error("zg config requires provider set or model set");
566
+ }
567
+ const unsupported = firstEnabledOption([
568
+ [options.installTargets?.length, "--target"],
569
+ [options.installMcpToolTimeoutSeconds, "--mcp-tool-timeout"],
570
+ [options.installMcpTokenEnv, "--mcp-token-env"],
571
+ [options.yes, "--yes"],
572
+ [options.rg, "--rg"],
573
+ [options.home, "--home"],
574
+ [options.embedding, "--embedding"],
575
+ [
576
+ options.configAction === "model-set" ? options.apiKey : undefined,
577
+ "--api-key",
578
+ ],
579
+ [
580
+ options.configAction === "provider-set" ? options.endpoint : undefined,
581
+ "--endpoint",
582
+ ],
583
+ [
584
+ options.configAction === "provider-set" ? options.device : undefined,
585
+ "--device",
586
+ ],
587
+ [
588
+ options.configAction === "provider-set"
589
+ ? options.defaultModel
590
+ : undefined,
591
+ "--default",
592
+ ],
593
+ [options.mode, "--mode"],
594
+ [options.listen, "--listen"],
595
+ [options.serverTokenFile, "--token-file"],
596
+ ]);
597
+ if (unsupported) {
598
+ throw new Error(`zg config ${options.configAction === "model-set" ? "model" : "provider"} set does not accept ${unsupported}`);
599
+ }
320
600
  }
321
- if ((options.index || options.disableIndex || options.status || options.collections) && hasExplicitRoutes(options)) {
322
- throw new Error("--fts and --vector can only be used with query commands");
601
+ else if (options.defaultModel) {
602
+ throw new Error("--default can only be used with zg config model set");
323
603
  }
324
- if ((options.index || options.disableIndex || options.status || options.collections) && options.rg) {
325
- throw new Error("--rg can only be used with query commands");
604
+ if (command === "server") {
605
+ if (!options.serverAction) {
606
+ throw new Error("zg server requires on, off, status, or run");
607
+ }
608
+ if (options.listen !== undefined &&
609
+ options.serverAction !== "run" &&
610
+ options.serverAction !== "on") {
611
+ throw new Error("--listen can only be used with zg server on or run");
612
+ }
613
+ if (options.serverTokenFile !== undefined &&
614
+ options.serverAction === "status") {
615
+ throw new Error("--token-file cannot be used with zg server status");
616
+ }
617
+ if (options.mcpToolset !== undefined &&
618
+ options.serverAction !== "on" &&
619
+ options.serverAction !== "run") {
620
+ throw new Error("--mcp-toolset can only be used with zg server on or run");
621
+ }
622
+ }
623
+ else if (options.mcpToolset !== undefined) {
624
+ throw new Error("--mcp-toolset can only be used with zg server on or run");
326
625
  }
327
- if ((options.index || options.disableIndex || options.status || options.collections) && options.preview) {
328
- throw new Error("--preview can only be used with query commands");
626
+ if (options.rg &&
627
+ (hasExplicitRoutes(options) || options.hybridQueries?.length)) {
628
+ throw new Error("--rg cannot be combined with --hybrid, --fts, or --vector");
329
629
  }
330
- if ((options.index || options.disableIndex || options.status || options.collections) && options.noAutoUpdate) {
331
- throw new Error("--no-auto-update can only be used with query commands");
630
+ if (options.rg && options.fuse) {
631
+ throw new Error("--rg cannot be combined with --fuse");
332
632
  }
333
- if (options.rg && hasExplicitRoutes(options)) {
334
- throw new Error("--rg cannot be combined with --fts or --vector");
633
+ if (options.forceDirect && options.mode !== "direct") {
634
+ throw new Error("--force-direct requires --mode direct");
335
635
  }
336
636
  if (options.rg && options.preview) {
337
637
  throw new Error("--preview is not supported with --rg; use -A/-B/-C for rg context");
338
638
  }
339
- if (options.rg && options.noFallback) {
340
- throw new Error("--rg cannot be combined with --no-fallback");
341
- }
342
639
  if (options.rg && options.trace) {
343
640
  throw new Error("--rg cannot be combined with --trace");
344
641
  }
345
642
  if (options.rg && (options.preferSymbol || options.symbolTypes?.length)) {
346
643
  throw new Error("--rg cannot be combined with indexed symbol options");
347
644
  }
348
- if (options.resetPaths && !options.index && !options.collections) {
349
- throw new Error("--reset-paths can only be used with --index or --collections index");
645
+ if (options.rg &&
646
+ (options.refresh || options.embeddingConcurrency !== undefined)) {
647
+ throw new Error("--rg cannot be combined with indexed refresh options");
350
648
  }
351
649
  if (!options.rg && (options.rgCompatibilityOptions?.length ?? 0) > 0) {
352
650
  const [option] = options.rgCompatibilityOptions;
353
651
  throw new Error(`${option} can only be used with --rg`);
354
652
  }
653
+ if (options.mode !== undefined &&
654
+ command !== "query" &&
655
+ command !== "index" &&
656
+ command !== "status") {
657
+ throw new Error("--mode can only be used with query, index, or status");
658
+ }
659
+ if (options.checkReady &&
660
+ command !== "status" &&
661
+ !(command === "server" && options.serverAction === "status")) {
662
+ throw new Error("--check-ready can only be used with zg status or zg server status");
663
+ }
664
+ if (options.listen !== undefined && command !== "server") {
665
+ throw new Error("--listen can only be used with zg server on or run");
666
+ }
667
+ if (options.serverTokenFile !== undefined && command !== "server") {
668
+ throw new Error("--token-file can only be used with zg server");
669
+ }
670
+ if (options.installTargets?.length &&
671
+ command !== "install" &&
672
+ command !== "uninstall") {
673
+ throw new Error("--target can only be used with zg install or zg uninstall");
674
+ }
675
+ if (options.installMcpToolTimeoutSeconds !== undefined &&
676
+ command !== "install") {
677
+ throw new Error("--mcp-tool-timeout can only be used with zg install");
678
+ }
679
+ if (options.installMcpTokenEnv !== undefined && command !== "install") {
680
+ throw new Error("--mcp-token-env can only be used with zg install");
681
+ }
682
+ if (options.force && command !== "install") {
683
+ throw new Error("--force can only be used with zg install");
684
+ }
685
+ if (command === "install" || command === "uninstall") {
686
+ const unsupported = firstEnabledOption([
687
+ [options.color, "--color"],
688
+ [options.home, "--home"],
689
+ [options.embedding, "--embedding"],
690
+ [options.modelCacheDir, "--model-cache"],
691
+ [options.device, "--device"],
692
+ [options.apiKey, "--api-key"],
693
+ [options.endpoint, "--endpoint"],
694
+ [options.rebuild, "--rebuild"],
695
+ [options.drop, "--drop"],
696
+ [options.resetPaths, "--reset-paths"],
697
+ [options.globs?.length, "--glob"],
698
+ [options.insensitiveGlobs?.length, "--iglob"],
699
+ [options.fileTypes?.length, "--type"],
700
+ [options.excludedFileTypes?.length, "--type-not"],
701
+ [options.hidden, "--hidden"],
702
+ [options.noIgnore, "--no-ignore"],
703
+ [options.ignoreFiles?.length, "--ignore-file"],
704
+ [options.maxDepth, "--max-depth"],
705
+ [options.maxFileSizeBytes, "--max-filesize"],
706
+ [options.follow, "--follow"],
707
+ [options.embeddingConcurrency, "--embedding-concurrency"],
708
+ ]);
709
+ if (unsupported) {
710
+ throw new Error(`${unsupported} is not supported with zg ${command}`);
711
+ }
712
+ }
713
+ if (options.yes &&
714
+ command !== "install" &&
715
+ command !== "uninstall" &&
716
+ !(command === "index" && options.drop)) {
717
+ throw new Error("--yes is only valid for install, uninstall, or index --drop");
718
+ }
719
+ if (options.drop && command !== "index") {
720
+ throw new Error("--drop can only be used with zg index");
721
+ }
722
+ if (options.rebuild && command !== "index") {
723
+ throw new Error("--rebuild can only be used with zg index");
724
+ }
725
+ if (options.resetPaths && command !== "index") {
726
+ throw new Error("--reset-paths can only be used with zg index");
727
+ }
728
+ if (options.drop &&
729
+ (options.rebuild ||
730
+ options.resetPaths ||
731
+ options.home ||
732
+ options.embedding ||
733
+ options.modelCacheDir ||
734
+ options.device !== undefined ||
735
+ options.apiKey ||
736
+ options.endpoint ||
737
+ options.globs?.length ||
738
+ options.insensitiveGlobs?.length ||
739
+ options.fileTypes?.length ||
740
+ options.excludedFileTypes?.length ||
741
+ options.hidden ||
742
+ options.noIgnore ||
743
+ options.ignoreFiles?.length ||
744
+ options.maxDepth !== undefined ||
745
+ options.maxFileSizeBytes !== undefined ||
746
+ options.follow ||
747
+ options.embeddingConcurrency)) {
748
+ throw new Error("zg index --drop cannot be combined with indexing options");
749
+ }
750
+ if (command === "query") {
751
+ const unsupported = firstEnabledOption([
752
+ [options.embedding, "--embedding"],
753
+ [options.endpoint, "--endpoint"],
754
+ [options.embeddingConcurrency, "--embedding-concurrency"],
755
+ ]);
756
+ if (unsupported) {
757
+ throw new Error(`${unsupported} is not supported with zg query`);
758
+ }
759
+ }
760
+ if (command === "query" && !options.rg) {
761
+ const queryCount = positionals.length +
762
+ (options.hybridQueries?.length ?? 0) +
763
+ (options.routes?.length ?? 0);
764
+ if (queryCount === 0) {
765
+ throw new Error("zg query requires a query or --hybrid/--fts/--vector route");
766
+ }
767
+ }
768
+ }
769
+ function firstEnabledOption(candidates) {
770
+ return candidates.find(([value]) => Array.isArray(value) ? value.length > 0 : value !== undefined)?.[1];
771
+ }
772
+ function parseClientMode(value) {
773
+ if (value === "direct" || value === "server" || value === "auto")
774
+ return value;
775
+ throw new Error("--mode must be direct, server, or auto");
776
+ }
777
+ function parseQueryRefreshMode(value) {
778
+ if (value === "background" || value === "wait" || value === "off") {
779
+ return value;
780
+ }
781
+ throw new Error("--refresh must be background, wait, or off");
782
+ }
783
+ function allowRemoteValueError() {
784
+ return new Error([
785
+ "--allow-remote does not accept a value.",
786
+ "It authorizes Remote Embedding for the current command only.",
787
+ "For persistent authorization, use:",
788
+ " zg auth grant --capability embedding --scope workspace",
789
+ ].join("\n"));
790
+ }
791
+ function parseAuthorizationCapability(value) {
792
+ if (value === "embedding")
793
+ return value;
794
+ throw new Error("--capability currently supports only embedding");
795
+ }
796
+ function parseAuthorizationScope(value) {
797
+ if (value === "workspace")
798
+ return value;
799
+ throw new Error("zg auth supports only workspace scope");
355
800
  }
356
801
  function readOptionValue(args, index, option) {
357
802
  const value = args[index];
@@ -380,9 +825,7 @@ function isManagedRgOutputOption(arg) {
380
825
  return MANAGED_RG_OUTPUT_OPTIONS.has(option);
381
826
  }
382
827
  function isShortRgOptionGroup(arg) {
383
- return /^-[A-Za-z].*$/.test(arg)
384
- && arg !== "-h"
385
- && arg !== "-v";
828
+ return /^-[A-Za-z].*$/.test(arg) && arg !== "-h";
386
829
  }
387
830
  function parseShortRgOptionGroup(args, index, options) {
388
831
  const arg = args[index];
@@ -395,35 +838,32 @@ function parseShortRgOptionGroup(args, index, options) {
395
838
  markRgCompatibilityOption(options, flag);
396
839
  break;
397
840
  case "F":
398
- options.rgOptions = {
399
- ...(options.rgOptions ?? {}),
400
- fixedStrings: true,
401
- };
841
+ options.rgOptions = appendRgExtraArgs(options.rgOptions, [flag]);
402
842
  markRgCompatibilityOption(options, flag);
403
843
  break;
404
844
  case "i":
405
- options.rgOptions = {
406
- ...(options.rgOptions ?? {}),
407
- ignoreCase: true,
408
- };
845
+ options.rgOptions = appendRgExtraArgs(options.rgOptions, [flag]);
409
846
  markRgCompatibilityOption(options, flag);
410
847
  break;
411
848
  case "w":
412
- options.rgOptions = {
413
- ...(options.rgOptions ?? {}),
414
- wordRegexp: true,
415
- };
849
+ options.rgOptions = appendRgExtraArgs(options.rgOptions, [flag]);
416
850
  markRgCompatibilityOption(options, flag);
417
851
  break;
418
852
  case "P":
419
853
  case "S":
420
854
  case "s":
855
+ case "a":
421
856
  case "u":
422
857
  case "U":
858
+ case "v":
859
+ case "x":
423
860
  case "z":
424
861
  options.rgOptions = appendRgExtraArgs(options.rgOptions, [flag]);
425
862
  markRgCompatibilityOption(options, flag);
426
863
  break;
864
+ case "L":
865
+ options.follow = true;
866
+ break;
427
867
  case "e": {
428
868
  const value = readShortOptionValue(args, index, offset, arg, flag);
429
869
  options.rgOptions = appendRgPattern(options.rgOptions, value.value);
@@ -432,15 +872,52 @@ function parseShortRgOptionGroup(args, index, options) {
432
872
  }
433
873
  case "g": {
434
874
  const value = readShortOptionValue(args, index, offset, arg, flag);
435
- appendRgGlobFilter(options, value.value);
875
+ options.globs = appendValue(options.globs, value.value, flag);
876
+ return value.nextIndex;
877
+ }
878
+ case "E": {
879
+ const value = readShortOptionValue(args, index, offset, arg, flag);
880
+ options.rgOptions = appendRgExtraArgs(options.rgOptions, [
881
+ flag,
882
+ value.value,
883
+ ]);
436
884
  markRgCompatibilityOption(options, flag);
437
885
  return value.nextIndex;
438
886
  }
439
887
  case "t":
440
- case "T":
441
- case "E": {
888
+ case "T": {
889
+ const value = readShortOptionValue(args, index, offset, arg, flag);
890
+ if (option === "t") {
891
+ options.fileTypes = appendValue(options.fileTypes, value.value, flag);
892
+ }
893
+ else {
894
+ options.excludedFileTypes = appendValue(options.excludedFileTypes, value.value, flag);
895
+ }
896
+ return value.nextIndex;
897
+ }
898
+ case "f": {
899
+ const value = readShortOptionValue(args, index, offset, arg, flag);
900
+ options.rgOptions = appendRgPatternFile(options.rgOptions, value.value, flag);
901
+ markRgCompatibilityOption(options, flag);
902
+ return value.nextIndex;
903
+ }
904
+ case "m": {
905
+ const value = readShortOptionValue(args, index, offset, arg, flag);
906
+ parseNonNegativeInteger(value.value, flag);
907
+ options.rgOptions = appendRgExtraArgs(options.rgOptions, [
908
+ flag,
909
+ value.value,
910
+ ]);
911
+ markRgCompatibilityOption(options, flag);
912
+ return value.nextIndex;
913
+ }
914
+ case "j": {
442
915
  const value = readShortOptionValue(args, index, offset, arg, flag);
443
- options.rgOptions = appendRgExtraArgs(options.rgOptions, [flag, value.value]);
916
+ parseNonNegativeInteger(value.value, flag);
917
+ options.rgOptions = appendRgExtraArgs(options.rgOptions, [
918
+ flag,
919
+ value.value,
920
+ ]);
444
921
  markRgCompatibilityOption(options, flag);
445
922
  return value.nextIndex;
446
923
  }
@@ -448,11 +925,7 @@ function parseShortRgOptionGroup(args, index, options) {
448
925
  case "B":
449
926
  case "C": {
450
927
  const value = readShortOptionValue(args, index, offset, arg, flag);
451
- const direction = option === "A"
452
- ? "after"
453
- : option === "B"
454
- ? "before"
455
- : "both";
928
+ const direction = option === "A" ? "after" : option === "B" ? "before" : "both";
456
929
  options.rgOptions = setRgContext(options.rgOptions, direction, value.value, flag);
457
930
  markRgCompatibilityOption(options, flag);
458
931
  return value.nextIndex;
@@ -488,12 +961,25 @@ function markRgCompatibilityOption(options, option) {
488
961
  function appendRgPattern(existing, value) {
489
962
  return {
490
963
  ...(existing ?? {}),
491
- patterns: [
492
- ...(existing?.patterns ?? []),
493
- value,
494
- ],
964
+ patterns: [...(existing?.patterns ?? []), value],
495
965
  };
496
966
  }
967
+ function appendRgPatternFile(existing, value, option) {
968
+ return {
969
+ ...(existing ?? {}),
970
+ patternFiles: appendValue(existing?.patternFiles, value, option),
971
+ };
972
+ }
973
+ function appendInstallTargets(existing, value) {
974
+ const targets = value
975
+ .split(/[,\s]+/)
976
+ .map((target) => target.trim())
977
+ .filter((target) => target.length > 0);
978
+ if (targets.length === 0) {
979
+ throw new Error("--target requires at least one agent name");
980
+ }
981
+ return [...(existing ?? []), ...targets];
982
+ }
497
983
  function setRgContext(existing, direction, value, option) {
498
984
  const parsed = parseNonNegativeInteger(value, option);
499
985
  return {
@@ -509,47 +995,53 @@ function setRgContext(existing, direction, value, option) {
509
995
  function appendRgExtraArgs(existing, args) {
510
996
  return {
511
997
  ...(existing ?? {}),
512
- extraArgs: [
513
- ...(existing?.extraArgs ?? []),
514
- ...args,
515
- ],
998
+ extraArgs: [...(existing?.extraArgs ?? []), ...args],
516
999
  };
517
1000
  }
518
- function appendRgGlobFilter(options, value) {
519
- if (value.startsWith("!")) {
520
- options.excludePaths = appendPathFilters(options.excludePaths, value.slice(1));
521
- return;
1001
+ function parsePositiveInteger(value, option) {
1002
+ if (!/^\d+$/.test(value)) {
1003
+ throw new Error(`${option} requires a positive integer`);
522
1004
  }
523
- options.includePaths = appendPathFilters(options.includePaths, value);
524
- }
525
- function readRouteOptionValues(args, index, option) {
526
- const values = [];
527
- let nextIndex = index;
528
- while (nextIndex < args.length) {
529
- const value = args[nextIndex];
530
- if (value.startsWith("-") && value !== "-") {
531
- break;
532
- }
533
- if (value.trim().length > 0) {
534
- values.push(value);
535
- }
536
- nextIndex++;
1005
+ const parsed = Number(value);
1006
+ if (!Number.isSafeInteger(parsed) || parsed < 1) {
1007
+ throw new Error(`${option} requires a positive integer`);
537
1008
  }
538
- if (values.length === 0) {
539
- throw new Error(`${option} requires at least one query`);
1009
+ return parsed;
1010
+ }
1011
+ function parseEnvironmentVariable(value, option) {
1012
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value)) {
1013
+ throw new Error(`${option} requires a valid environment variable name`);
540
1014
  }
541
- return { values, nextIndex };
1015
+ return value;
542
1016
  }
543
- function parsePositiveInteger(value, option) {
544
- const parsed = Number.parseInt(value, 10);
545
- if (!Number.isInteger(parsed) || parsed < 1) {
546
- throw new Error(`${option} requires a positive integer`);
1017
+ function parseByteSize(value, option) {
1018
+ const match = value.trim().match(/^(\d+)([KMGT])?$/i);
1019
+ if (!match) {
1020
+ throw new Error(`${option} requires bytes or an integer K/M/G/T size`);
547
1021
  }
548
- return parsed;
1022
+ const amount = Number.parseInt(match[1], 10);
1023
+ const suffix = match[2]?.toUpperCase();
1024
+ const multiplier = suffix === "K"
1025
+ ? 1024
1026
+ : suffix === "M"
1027
+ ? 1024 ** 2
1028
+ : suffix === "G"
1029
+ ? 1024 ** 3
1030
+ : suffix === "T"
1031
+ ? 1024 ** 4
1032
+ : 1;
1033
+ const bytes = amount * multiplier;
1034
+ if (!Number.isSafeInteger(bytes)) {
1035
+ throw new Error(`${option} is too large`);
1036
+ }
1037
+ return bytes;
549
1038
  }
550
1039
  function parseNonNegativeInteger(value, option) {
551
- const parsed = Number.parseInt(value, 10);
552
- if (!Number.isInteger(parsed) || parsed < 0) {
1040
+ if (!/^\d+$/.test(value)) {
1041
+ throw new Error(`${option} requires a non-negative integer`);
1042
+ }
1043
+ const parsed = Number(value);
1044
+ if (!Number.isSafeInteger(parsed)) {
553
1045
  throw new Error(`${option} requires a non-negative integer`);
554
1046
  }
555
1047
  return parsed;
@@ -566,24 +1058,33 @@ function parsePreviewMode(value) {
566
1058
  }
567
1059
  throw new Error(`Unsupported preview mode: ${value}`);
568
1060
  }
569
- function parseLlamaGpu(value) {
1061
+ export function parseDevice(value) {
570
1062
  const normalized = value.trim().toLowerCase();
571
- if (normalized === "auto" || normalized === "metal" || normalized === "vulkan" || normalized === "cuda") {
1063
+ if (normalized === "auto" ||
1064
+ normalized === "cpu" ||
1065
+ normalized === "metal" ||
1066
+ normalized === "vulkan" ||
1067
+ normalized === "cuda") {
572
1068
  return normalized;
573
1069
  }
574
- if (["false", "off", "none", "disable", "disabled", "0"].includes(normalized)) {
575
- return false;
576
- }
577
- throw new Error(`Unsupported llama GPU mode: ${value}`);
1070
+ throw new Error(`Unsupported device: ${value}`);
578
1071
  }
579
1072
  function hasExplicitRoutes(options) {
580
1073
  return (options.routes?.length ?? 0) > 0;
581
1074
  }
582
- function appendRoutes(existing, mode, queries) {
583
- return [
584
- ...(existing ?? []),
585
- ...queries.map((query) => ({ mode, query })),
586
- ];
1075
+ function appendRoute(existing, mode, query, option) {
1076
+ const normalized = query.trim();
1077
+ if (!normalized) {
1078
+ throw new Error(`${option} requires a non-empty query`);
1079
+ }
1080
+ return [...(existing ?? []), { mode, query: normalized }];
1081
+ }
1082
+ function appendQuery(existing, query, option) {
1083
+ const normalized = query.trim();
1084
+ if (!normalized) {
1085
+ throw new Error(`${option} requires a non-empty query`);
1086
+ }
1087
+ return [...(existing ?? []), normalized];
587
1088
  }
588
1089
  function parseSymbolType(value) {
589
1090
  if (VALID_SYMBOL_TYPES.has(value)) {
@@ -591,14 +1092,61 @@ function parseSymbolType(value) {
591
1092
  }
592
1093
  throw new Error(`Unsupported symbol type: ${value}`);
593
1094
  }
594
- function appendPathFilters(existing, value) {
595
- const values = value
596
- .split(",")
597
- .map((item) => item.trim())
598
- .filter((item) => item.length > 0);
599
- return [...(existing ?? []), ...values];
1095
+ export function splitPathFilters(value) {
1096
+ const filters = [];
1097
+ let start = 0;
1098
+ let braceDepth = 0;
1099
+ let bracketDepth = 0;
1100
+ let escaped = false;
1101
+ for (let index = 0; index < value.length; index += 1) {
1102
+ const character = value[index];
1103
+ if (escaped) {
1104
+ escaped = false;
1105
+ continue;
1106
+ }
1107
+ if (character === "\\") {
1108
+ escaped = true;
1109
+ continue;
1110
+ }
1111
+ if (character === "[") {
1112
+ bracketDepth += 1;
1113
+ continue;
1114
+ }
1115
+ if (character === "]" && bracketDepth > 0) {
1116
+ bracketDepth -= 1;
1117
+ continue;
1118
+ }
1119
+ if (bracketDepth === 0 && character === "{") {
1120
+ braceDepth += 1;
1121
+ continue;
1122
+ }
1123
+ if (bracketDepth === 0 && character === "}" && braceDepth > 0) {
1124
+ braceDepth -= 1;
1125
+ continue;
1126
+ }
1127
+ if (character !== "," || braceDepth > 0 || bracketDepth > 0) {
1128
+ continue;
1129
+ }
1130
+ const filter = value.slice(start, index).trim();
1131
+ if (filter.length > 0) {
1132
+ filters.push(filter);
1133
+ }
1134
+ start = index + 1;
1135
+ }
1136
+ const finalFilter = value.slice(start).trim();
1137
+ if (finalFilter.length > 0) {
1138
+ filters.push(finalFilter);
1139
+ }
1140
+ return filters;
1141
+ }
1142
+ function appendValue(existing, value, option) {
1143
+ const normalized = value.trim();
1144
+ if (!normalized) {
1145
+ throw new Error(`${option} requires a non-empty value`);
1146
+ }
1147
+ return [...(existing ?? []), normalized];
600
1148
  }
601
- function parseModifiedTime(value, option) {
1149
+ export function parseModifiedTime(value, option) {
602
1150
  if (/^\d+$/.test(value)) {
603
1151
  const parsed = Number.parseInt(value, 10);
604
1152
  if (Number.isSafeInteger(parsed) && parsed >= 0) {
@@ -611,9 +1159,9 @@ function parseModifiedTime(value, option) {
611
1159
  const month = Number.parseInt(dateOnly[2], 10);
612
1160
  const day = Number.parseInt(dateOnly[3], 10);
613
1161
  const date = new Date(year, month - 1, day);
614
- if (date.getFullYear() === year
615
- && date.getMonth() === month - 1
616
- && date.getDate() === day) {
1162
+ if (date.getFullYear() === year &&
1163
+ date.getMonth() === month - 1 &&
1164
+ date.getDate() === day) {
617
1165
  return date.getTime();
618
1166
  }
619
1167
  }