@zvec/zvec-grep 0.1.5 → 0.1.7
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/README.md +154 -236
- package/README_CN.md +142 -233
- package/dist/authorization/index.d.ts +7 -0
- package/dist/authorization/index.js +7 -0
- package/dist/authorization/index.js.map +1 -0
- package/dist/authorization/manager.d.ts +8 -0
- package/dist/authorization/manager.js +19 -0
- package/dist/authorization/manager.js.map +1 -0
- package/dist/authorization/operation.d.ts +7 -0
- package/dist/authorization/operation.js +50 -0
- package/dist/authorization/operation.js.map +1 -0
- package/dist/authorization/planner.d.ts +21 -0
- package/dist/authorization/planner.js +97 -0
- package/dist/authorization/planner.js.map +1 -0
- package/dist/authorization/prompt.d.ts +11 -0
- package/dist/authorization/prompt.js +62 -0
- package/dist/authorization/prompt.js.map +1 -0
- package/dist/authorization/store.d.ts +20 -0
- package/dist/authorization/store.js +251 -0
- package/dist/authorization/store.js.map +1 -0
- package/dist/authorization/target.d.ts +15 -0
- package/dist/authorization/target.js +49 -0
- package/dist/authorization/target.js.map +1 -0
- package/dist/authorization/types.d.ts +61 -0
- package/dist/authorization/types.js +2 -0
- package/dist/authorization/types.js.map +1 -0
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.js +338 -55
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth.d.ts +21 -0
- package/dist/cli/auth.js +209 -0
- package/dist/cli/auth.js.map +1 -0
- package/dist/cli/commands.js +469 -625
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/errors.js +2 -2
- package/dist/cli/errors.js.map +1 -1
- package/dist/cli/format/context.d.ts +4 -0
- package/dist/cli/format/context.js +311 -44
- package/dist/cli/format/context.js.map +1 -1
- package/dist/cli/format/debug.js +12 -6
- package/dist/cli/format/debug.js.map +1 -1
- package/dist/cli/format/progress.d.ts +4 -0
- package/dist/cli/format/progress.js +219 -46
- package/dist/cli/format/progress.js.map +1 -1
- package/dist/cli/format/status.d.ts +79 -6
- package/dist/cli/format/status.js +341 -111
- package/dist/cli/format/status.js.map +1 -1
- package/dist/cli/help.js +395 -63
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/install.d.ts +4 -0
- package/dist/cli/install.js +963 -0
- package/dist/cli/install.js.map +1 -0
- package/dist/cli/managed-rg.d.ts +10 -0
- package/dist/cli/managed-rg.js +329 -0
- package/dist/cli/managed-rg.js.map +1 -0
- package/dist/cli/server-search.d.ts +3 -0
- package/dist/cli/server-search.js +12 -0
- package/dist/cli/server-search.js.map +1 -0
- package/dist/cli/types.d.ts +23 -6
- package/dist/cli/types.js.map +1 -1
- package/dist/client/daemon-client.d.ts +31 -0
- package/dist/client/daemon-client.js +203 -0
- package/dist/client/daemon-client.js.map +1 -0
- package/dist/client/mode-router.d.ts +9 -0
- package/dist/client/mode-router.js +28 -0
- package/dist/client/mode-router.js.map +1 -0
- package/dist/client/search-policy.d.ts +11 -0
- package/dist/client/search-policy.js +15 -0
- package/dist/client/search-policy.js.map +1 -0
- package/dist/daemon/backend.d.ts +77 -0
- package/dist/daemon/backend.js +1087 -0
- package/dist/daemon/backend.js.map +1 -0
- package/dist/daemon/change-set.d.ts +25 -0
- package/dist/daemon/change-set.js +101 -0
- package/dist/daemon/change-set.js.map +1 -0
- package/dist/daemon/config.d.ts +24 -0
- package/dist/daemon/config.js +88 -0
- package/dist/daemon/config.js.map +1 -0
- package/dist/daemon/errors.d.ts +5 -0
- package/dist/daemon/errors.js +11 -0
- package/dist/daemon/errors.js.map +1 -0
- package/dist/daemon/http-server.d.ts +30 -0
- package/dist/daemon/http-server.js +288 -0
- package/dist/daemon/http-server.js.map +1 -0
- package/dist/daemon/index-coordinator.d.ts +24 -0
- package/dist/daemon/index-coordinator.js +68 -0
- package/dist/daemon/index-coordinator.js.map +1 -0
- package/dist/daemon/job-scheduler.d.ts +70 -0
- package/dist/daemon/job-scheduler.js +366 -0
- package/dist/daemon/job-scheduler.js.map +1 -0
- package/dist/daemon/logger.d.ts +9 -0
- package/dist/daemon/logger.js +53 -0
- package/dist/daemon/logger.js.map +1 -0
- package/dist/daemon/model-pool.d.ts +45 -0
- package/dist/daemon/model-pool.js +187 -0
- package/dist/daemon/model-pool.js.map +1 -0
- package/dist/daemon/root-lease.d.ts +14 -0
- package/dist/daemon/root-lease.js +188 -0
- package/dist/daemon/root-lease.js.map +1 -0
- package/dist/daemon/root-runtime.d.ts +78 -0
- package/dist/daemon/root-runtime.js +333 -0
- package/dist/daemon/root-runtime.js.map +1 -0
- package/dist/daemon/runtime-manager.d.ts +46 -0
- package/dist/daemon/runtime-manager.js +246 -0
- package/dist/daemon/runtime-manager.js.map +1 -0
- package/dist/daemon/runtime.d.ts +12 -0
- package/dist/daemon/runtime.js +102 -0
- package/dist/daemon/runtime.js.map +1 -0
- package/dist/daemon/server-controller.d.ts +39 -0
- package/dist/daemon/server-controller.js +254 -0
- package/dist/daemon/server-controller.js.map +1 -0
- package/dist/daemon/watch-manager.d.ts +50 -0
- package/dist/daemon/watch-manager.js +293 -0
- package/dist/daemon/watch-manager.js.map +1 -0
- package/dist/daemon/workspace-read-session-cache.d.ts +31 -0
- package/dist/daemon/workspace-read-session-cache.js +115 -0
- package/dist/daemon/workspace-read-session-cache.js.map +1 -0
- package/dist/engine/code-formats.d.ts +3 -0
- package/dist/engine/code-formats.js +14 -0
- package/dist/engine/code-formats.js.map +1 -0
- package/dist/engine/config.d.ts +30 -8
- package/dist/engine/config.js +171 -45
- package/dist/engine/config.js.map +1 -1
- package/dist/engine/{errors/index.d.ts → errors.d.ts} +6 -1
- package/dist/engine/{errors/details.js → errors.js} +17 -4
- package/dist/engine/errors.js.map +1 -0
- package/dist/engine/extraction/code/adapter.d.ts +1 -1
- package/dist/engine/extraction/code/adapter.js +1 -1
- package/dist/engine/extraction/code/adapter.js.map +1 -1
- package/dist/engine/extraction/code/extractor.d.ts +5 -11
- package/dist/engine/extraction/code/extractor.js +116 -48
- package/dist/engine/extraction/code/extractor.js.map +1 -1
- package/dist/engine/extraction/code/families/c-family.js +1 -1
- package/dist/engine/extraction/code/families/c-family.js.map +1 -1
- package/dist/engine/extraction/code/families/js-ts.d.ts +1 -1
- package/dist/engine/extraction/code/families/metadata.d.ts +1 -1
- package/dist/engine/extraction/code/tree-sitter/grammar.js.map +1 -0
- package/dist/engine/extraction/code/tree-sitter/nodes.js.map +1 -0
- package/dist/engine/extraction/code/tree-sitter/parser.js.map +1 -0
- package/dist/engine/extraction/image/extractor.d.ts +5 -0
- package/dist/engine/extraction/image/extractor.js +35 -0
- package/dist/engine/extraction/image/extractor.js.map +1 -0
- package/dist/engine/extraction/index.d.ts +4 -44
- package/dist/engine/extraction/index.js +2 -280
- package/dist/engine/extraction/index.js.map +1 -1
- package/dist/engine/extraction/markdown/extractor.d.ts +5 -11
- package/dist/engine/extraction/markdown/extractor.js +38 -17
- package/dist/engine/extraction/markdown/extractor.js.map +1 -1
- package/dist/engine/extraction/runtime.d.ts +4 -0
- package/dist/engine/extraction/runtime.js +26 -0
- package/dist/engine/extraction/runtime.js.map +1 -0
- package/dist/engine/extraction/source.d.ts +18 -0
- package/dist/engine/extraction/source.js +22 -0
- package/dist/engine/extraction/source.js.map +1 -0
- package/dist/engine/extraction/text/extractor.d.ts +7 -0
- package/dist/engine/extraction/text/extractor.js +168 -0
- package/dist/engine/extraction/text/extractor.js.map +1 -0
- package/dist/engine/extraction/types.d.ts +4 -0
- package/dist/engine/{models → extraction}/types.js.map +1 -1
- package/dist/engine/extraction/vector-content.d.ts +5 -0
- package/dist/engine/extraction/vector-content.js +95 -0
- package/dist/engine/extraction/vector-content.js.map +1 -0
- package/dist/engine/file-size-policy.d.ts +6 -0
- package/dist/engine/file-size-policy.js +20 -0
- package/dist/engine/file-size-policy.js.map +1 -0
- package/dist/engine/file-type.d.ts +15 -0
- package/dist/engine/file-type.js +152 -0
- package/dist/engine/file-type.js.map +1 -0
- package/dist/engine/index-status.d.ts +9 -0
- package/dist/engine/index-status.js +38 -0
- package/dist/engine/index-status.js.map +1 -0
- package/dist/engine/manifest.d.ts +13 -0
- package/dist/engine/manifest.js +124 -0
- package/dist/engine/manifest.js.map +1 -0
- package/dist/engine/models/{providers/llama-cpp/embedding.d.ts → backends/llama-cpp.d.ts} +25 -20
- package/dist/engine/models/{providers/llama-cpp/embedding.js → backends/llama-cpp.js} +127 -106
- package/dist/engine/models/backends/llama-cpp.js.map +1 -0
- package/dist/engine/models/backends/model2vec-runtime.d.ts +63 -0
- package/dist/engine/models/backends/model2vec-runtime.js +112 -0
- package/dist/engine/models/backends/model2vec-runtime.js.map +1 -0
- package/dist/engine/models/backends/model2vec-tokenizer.d.ts +2 -0
- package/dist/engine/models/backends/model2vec-tokenizer.js +42 -0
- package/dist/engine/models/backends/model2vec-tokenizer.js.map +1 -0
- package/dist/engine/models/backends/model2vec-worker-pool.d.ts +25 -0
- package/dist/engine/models/backends/model2vec-worker-pool.js +264 -0
- package/dist/engine/models/backends/model2vec-worker-pool.js.map +1 -0
- package/dist/engine/models/backends/model2vec-worker.d.ts +1 -0
- package/dist/engine/models/backends/model2vec-worker.js +41 -0
- package/dist/engine/models/backends/model2vec-worker.js.map +1 -0
- package/dist/engine/models/backends/model2vec.d.ts +40 -0
- package/dist/engine/models/backends/model2vec.js +311 -0
- package/dist/engine/models/backends/model2vec.js.map +1 -0
- package/dist/engine/models/backends/qwen.d.ts +44 -0
- package/dist/engine/models/{providers/qwen/embedding.js → backends/qwen.js} +155 -94
- package/dist/engine/models/backends/qwen.js.map +1 -0
- package/dist/engine/models/backends/transformers-js.d.ts +87 -0
- package/dist/engine/models/backends/transformers-js.js +316 -0
- package/dist/engine/models/backends/transformers-js.js.map +1 -0
- package/dist/engine/models/catalog.d.ts +207 -23
- package/dist/engine/models/catalog.js +191 -25
- package/dist/engine/models/catalog.js.map +1 -1
- package/dist/engine/models/download-progress.d.ts +15 -0
- package/dist/engine/models/download-progress.js +48 -0
- package/dist/engine/models/download-progress.js.map +1 -0
- package/dist/engine/models/embeddings.d.ts +59 -18
- package/dist/engine/models/embeddings.js +52 -28
- package/dist/engine/models/embeddings.js.map +1 -1
- package/dist/engine/models/factory.d.ts +2 -5
- package/dist/engine/models/factory.js +41 -56
- package/dist/engine/models/factory.js.map +1 -1
- package/dist/engine/models/index.d.ts +4 -6
- package/dist/engine/models/index.js +4 -4
- package/dist/engine/models/index.js.map +1 -1
- package/dist/engine/models/ranking.d.ts +7 -3
- package/dist/engine/models/resolution.d.ts +8 -0
- package/dist/engine/models/resolution.js +22 -0
- package/dist/engine/models/resolution.js.map +1 -0
- package/dist/engine/pipeline/indexing/index.d.ts +9 -7
- package/dist/engine/pipeline/indexing/index.js +409 -165
- package/dist/engine/pipeline/indexing/index.js.map +1 -1
- package/dist/engine/pipeline/indexing/input-budget.d.ts +2 -0
- package/dist/engine/pipeline/indexing/input-budget.js +51 -0
- package/dist/engine/pipeline/indexing/input-budget.js.map +1 -0
- package/dist/engine/pipeline/indexing/root-paths.js +6 -6
- package/dist/engine/pipeline/indexing/root-paths.js.map +1 -1
- package/dist/engine/pipeline/indexing/scanner/index.d.ts +9 -2
- package/dist/engine/pipeline/indexing/scanner/index.js +291 -35
- package/dist/engine/pipeline/indexing/scanner/index.js.map +1 -1
- package/dist/engine/pipeline/search/index.d.ts +6 -6
- package/dist/engine/pipeline/search/index.js +8 -10
- package/dist/engine/pipeline/search/index.js.map +1 -1
- package/dist/engine/service/index.d.ts +3 -2
- package/dist/engine/service/index.js +1 -1
- package/dist/engine/service/index.js.map +1 -1
- package/dist/engine/service/root.d.ts +10 -12
- package/dist/engine/service/root.js +29 -25
- package/dist/engine/service/root.js.map +1 -1
- package/dist/engine/service/structure-enrichment.d.ts +1 -1
- package/dist/engine/service/structure-enrichment.js +20 -22
- package/dist/engine/service/structure-enrichment.js.map +1 -1
- package/dist/engine/service/types.d.ts +40 -38
- package/dist/engine/service/workspace-index.d.ts +26 -0
- package/dist/engine/service/workspace-index.js +157 -0
- package/dist/engine/service/workspace-index.js.map +1 -0
- package/dist/engine/service/zvec-grep.d.ts +12 -1
- package/dist/engine/service/zvec-grep.js +698 -489
- package/dist/engine/service/zvec-grep.js.map +1 -1
- package/dist/engine/storage/index.d.ts +30 -20
- package/dist/engine/storage/index.js +2 -1
- package/dist/engine/storage/index.js.map +1 -1
- package/dist/engine/storage/layout.d.ts +10 -0
- package/dist/engine/storage/layout.js +29 -0
- package/dist/engine/storage/layout.js.map +1 -0
- package/dist/engine/storage/zvec.d.ts +4 -67
- package/dist/engine/storage/zvec.js +115 -85
- package/dist/engine/storage/zvec.js.map +1 -1
- package/dist/engine/types.d.ts +29 -23
- package/dist/engine/types.js +1 -1
- package/dist/engine/types.js.map +1 -1
- package/dist/engine/utils/daemon-lease.d.ts +17 -0
- package/dist/engine/utils/daemon-lease.js +175 -0
- package/dist/engine/utils/daemon-lease.js.map +1 -0
- package/dist/engine/utils/file-selection.js +38 -1
- package/dist/engine/utils/file-selection.js.map +1 -1
- package/dist/engine/utils/lock.js +1 -1
- package/dist/engine/utils/lock.js.map +1 -1
- package/dist/index-progress.d.ts +10 -0
- package/dist/index-progress.js +159 -0
- package/dist/index-progress.js.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/http-transport.d.ts +27 -0
- package/dist/mcp/http-transport.js +182 -0
- package/dist/mcp/http-transport.js.map +1 -0
- package/dist/mcp/input-normalization.d.ts +38 -0
- package/dist/mcp/input-normalization.js +104 -0
- package/dist/mcp/input-normalization.js.map +1 -0
- package/dist/mcp/progress-heartbeat.d.ts +17 -0
- package/dist/mcp/progress-heartbeat.js +46 -0
- package/dist/mcp/progress-heartbeat.js.map +1 -0
- package/dist/mcp/request-metadata.d.ts +2 -0
- package/dist/mcp/request-metadata.js +11 -0
- package/dist/mcp/request-metadata.js.map +1 -0
- package/dist/mcp/request-state.d.ts +40 -0
- package/dist/mcp/request-state.js +210 -0
- package/dist/mcp/request-state.js.map +1 -0
- package/dist/mcp/result-format.d.ts +13 -0
- package/dist/mcp/result-format.js +75 -0
- package/dist/mcp/result-format.js.map +1 -0
- package/dist/mcp/schemas.d.ts +672 -0
- package/dist/mcp/schemas.js +506 -0
- package/dist/mcp/schemas.js.map +1 -0
- package/dist/mcp/stdio-bridge.d.ts +9 -0
- package/dist/mcp/stdio-bridge.js +131 -0
- package/dist/mcp/stdio-bridge.js.map +1 -0
- package/dist/mcp/tools.d.ts +153 -0
- package/dist/mcp/tools.js +482 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/toolset.d.ts +5 -0
- package/dist/mcp/toolset.js +12 -0
- package/dist/mcp/toolset.js.map +1 -0
- package/dist/observability/trace-context.d.ts +11 -0
- package/dist/observability/trace-context.js +138 -0
- package/dist/observability/trace-context.js.map +1 -0
- package/dist/prompts/zvec-grep-guidance.d.ts +2 -0
- package/dist/prompts/zvec-grep-guidance.js +9 -0
- package/dist/prompts/zvec-grep-guidance.js.map +1 -0
- package/docs/01-agents.md +132 -0
- package/docs/02-cli.md +239 -0
- package/docs/03-mcp.md +185 -0
- package/docs/04-pipeline.md +226 -0
- package/docs/05-architecture.md +86 -0
- package/docs/06-server.md +215 -0
- package/docs/07-embedding.md +182 -0
- package/docs/08-roadmap.md +85 -0
- package/docs/README.md +53 -0
- package/package.json +20 -11
- package/dist/cli/mcp.d.ts +0 -2
- package/dist/cli/mcp.js +0 -354
- package/dist/cli/mcp.js.map +0 -1
- package/dist/engine/collection/index.d.ts +0 -55
- package/dist/engine/collection/index.js +0 -710
- package/dist/engine/collection/index.js.map +0 -1
- package/dist/engine/errors/details.d.ts +0 -6
- package/dist/engine/errors/details.js.map +0 -1
- package/dist/engine/errors/index.js +0 -16
- package/dist/engine/errors/index.js.map +0 -1
- package/dist/engine/extraction/tree-sitter/grammar.js.map +0 -1
- package/dist/engine/extraction/tree-sitter/nodes.js.map +0 -1
- package/dist/engine/extraction/tree-sitter/parser.js.map +0 -1
- package/dist/engine/files/file-type.d.ts +0 -5
- package/dist/engine/files/file-type.js +0 -119
- package/dist/engine/files/file-type.js.map +0 -1
- package/dist/engine/models/providers/index.d.ts +0 -2
- package/dist/engine/models/providers/index.js +0 -3
- package/dist/engine/models/providers/index.js.map +0 -1
- package/dist/engine/models/providers/llama-cpp/embedding.js.map +0 -1
- package/dist/engine/models/providers/llama-cpp/index.d.ts +0 -1
- package/dist/engine/models/providers/llama-cpp/index.js +0 -2
- package/dist/engine/models/providers/llama-cpp/index.js.map +0 -1
- package/dist/engine/models/providers/qwen/embedding.d.ts +0 -42
- package/dist/engine/models/providers/qwen/embedding.js.map +0 -1
- package/dist/engine/models/providers/qwen/index.d.ts +0 -1
- package/dist/engine/models/providers/qwen/index.js +0 -2
- package/dist/engine/models/providers/qwen/index.js.map +0 -1
- package/dist/engine/models/types.d.ts +0 -30
- package/skills/zvec-grep/SKILL.md +0 -151
- package/skills/zvec-grep/agents/openai.yaml +0 -4
- /package/dist/engine/extraction/{tree-sitter → code/tree-sitter}/grammar.d.ts +0 -0
- /package/dist/engine/extraction/{tree-sitter → code/tree-sitter}/grammar.js +0 -0
- /package/dist/engine/extraction/{tree-sitter → code/tree-sitter}/nodes.d.ts +0 -0
- /package/dist/engine/extraction/{tree-sitter → code/tree-sitter}/nodes.js +0 -0
- /package/dist/engine/extraction/{tree-sitter → code/tree-sitter}/parser.d.ts +0 -0
- /package/dist/engine/extraction/{tree-sitter → code/tree-sitter}/parser.js +0 -0
- /package/dist/engine/{models → extraction}/types.js +0 -0
package/dist/cli/commands.js
CHANGED
|
@@ -1,29 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { chmod, lstat, mkdir, open, readFile, readlink, rename, stat, unlink, } from "node:fs/promises";
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
|
-
import { dirname, resolve } from "node:path";
|
|
1
|
+
import { resolve } from "node:path";
|
|
5
2
|
import { createInterface } from "node:readline/promises";
|
|
6
3
|
import { createZvecGrep, } from "../index.js";
|
|
7
|
-
import { globalConfigPath,
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
4
|
+
import { globalConfigPath, updateGlobalConfig } from "../engine/config.js";
|
|
5
|
+
import { listEmbeddingModels } from "../engine/models/index.js";
|
|
6
|
+
import { DaemonClient } from "../client/daemon-client.js";
|
|
7
|
+
import { resolveDirectSearchPolicy, resolveServerSearchPolicy, } from "../client/search-policy.js";
|
|
8
|
+
import { resolveClientMode, resolveServerUrl, routeByMode, } from "../client/mode-router.js";
|
|
9
|
+
import { serverStatus } from "../daemon/server-controller.js";
|
|
10
|
+
import { findNearestWorkspace } from "../engine/service/root.js";
|
|
11
|
+
import { contextWarningLines, printCliContextResult, } from "./format/context.js";
|
|
10
12
|
import { printDebug } from "./format/debug.js";
|
|
11
13
|
import { createIndexProgressReporter } from "./format/progress.js";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
},
|
|
21
|
-
];
|
|
22
|
-
const ZVEC_GREP_CONFIG_START = "# ZVEC_GREP_START";
|
|
23
|
-
const ZVEC_GREP_CONFIG_END = "# ZVEC_GREP_END";
|
|
24
|
-
const ZVEC_GREP_AGENTS_START = "<!-- ZVEC_GREP_START -->";
|
|
25
|
-
const ZVEC_GREP_AGENTS_END = "<!-- ZVEC_GREP_END -->";
|
|
26
|
-
const DEFAULT_MCP_TOOL_TIMEOUT_SECONDS = 600;
|
|
14
|
+
import { printWorkspaceInfo, printIndexPathFilterTip, printIndexResult, printIndexScanDiagnostics, printNoIndexableFilesTip, printServerIndexInfo, } from "./format/status.js";
|
|
15
|
+
import { planRemoteIndexAuthorization, planRemoteSearchAuthorization, } from "../authorization/index.js";
|
|
16
|
+
import { indexCompletionFromStatus, indexStatusNeedsRefresh, } from "../engine/index-status.js";
|
|
17
|
+
import { indexProgressFromMessage } from "../index-progress.js";
|
|
18
|
+
import { normalizeManagedRgInput } from "./managed-rg.js";
|
|
19
|
+
import { INCOMPATIBLE_SERVER_SEARCH_MESSAGE, parseServerSearchResponse, } from "./server-search.js";
|
|
20
|
+
import { runInstall, runUninstall } from "./install.js";
|
|
21
|
+
import { runAuth, authorizationStore, authorizeCliPlan, resolveAuthorizationSchema, embeddingModelInfo, configuredEmbeddingReference, workspaceRuntimeFromInfo, assertEmbeddingModelCompatible, assertRequestedEndpointCompatible, requireEmbeddingModelCatalogEntry, unsupportedRemoteEmbeddingProvider, withRemoteEmbeddingOperationPermit, } from "./auth.js";
|
|
27
22
|
export async function runParsedCommand(parsed) {
|
|
28
23
|
switch (parsed.command) {
|
|
29
24
|
case "query":
|
|
@@ -35,174 +30,107 @@ export async function runParsedCommand(parsed) {
|
|
|
35
30
|
case "status":
|
|
36
31
|
await runStatus(parsed);
|
|
37
32
|
return;
|
|
38
|
-
case "collections":
|
|
39
|
-
await runCollections(parsed);
|
|
40
|
-
return;
|
|
41
33
|
case "install":
|
|
42
34
|
await runInstall(parsed);
|
|
43
35
|
return;
|
|
44
36
|
case "uninstall":
|
|
45
37
|
await runUninstall(parsed);
|
|
46
38
|
return;
|
|
47
|
-
case "
|
|
48
|
-
await
|
|
39
|
+
case "config":
|
|
40
|
+
await runConfig(parsed);
|
|
41
|
+
return;
|
|
42
|
+
case "auth":
|
|
43
|
+
await runAuth(parsed);
|
|
44
|
+
return;
|
|
45
|
+
case "server":
|
|
46
|
+
await runServer(parsed);
|
|
49
47
|
return;
|
|
50
48
|
case "help":
|
|
51
49
|
case "version":
|
|
52
50
|
throw new Error(`${parsed.command} must be handled before dispatch`);
|
|
53
51
|
}
|
|
54
52
|
}
|
|
55
|
-
async function
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
console.log("No agents selected.");
|
|
59
|
-
return;
|
|
53
|
+
async function runConfig(parsed) {
|
|
54
|
+
if (parsed.positionals.length !== 1) {
|
|
55
|
+
throw new Error(`zg config ${parsed.options.configAction === "provider-set" ? "provider" : "model"} set requires exactly one reference`);
|
|
60
56
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
mcpToolTimeoutSeconds: parsed.options.installMcpToolTimeoutSeconds ??
|
|
66
|
-
DEFAULT_MCP_TOOL_TIMEOUT_SECONDS,
|
|
67
|
-
});
|
|
68
|
-
console.log(`Installed ${installer.label}:`);
|
|
69
|
-
for (const file of result.files) {
|
|
70
|
-
console.log(` ${file}`);
|
|
57
|
+
const reference = parsed.positionals[0];
|
|
58
|
+
if (parsed.options.configAction === "provider-set") {
|
|
59
|
+
if (!/^[a-z][a-z0-9_-]*$/.test(reference)) {
|
|
60
|
+
throw unsupportedRemoteEmbeddingProvider(reference, "Invalid embedding provider");
|
|
71
61
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
async function runUninstall(parsed) {
|
|
79
|
-
const installers = await resolveInstallers(parsed, "uninstall");
|
|
80
|
-
if (installers.length === 0) {
|
|
81
|
-
console.log("No agents selected.");
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
console.log(`Removing zvec-grep from: ${installers.map((installer) => installer.label).join(", ")}`);
|
|
85
|
-
for (const installer of installers) {
|
|
86
|
-
const result = await installer.uninstall();
|
|
87
|
-
console.log(`Removed ${installer.label} integration:`);
|
|
88
|
-
for (const file of result.files) {
|
|
89
|
-
console.log(` ${file}`);
|
|
62
|
+
if (reference === "local" ||
|
|
63
|
+
!listEmbeddingModels().some((entry) => entry.provider === reference)) {
|
|
64
|
+
throw unsupportedRemoteEmbeddingProvider(reference);
|
|
65
|
+
}
|
|
66
|
+
if (parsed.options.apiKey === undefined) {
|
|
67
|
+
throw new Error("zg config provider set requires --api-key");
|
|
90
68
|
}
|
|
69
|
+
updateGlobalConfig({
|
|
70
|
+
providers: {
|
|
71
|
+
[reference]: {
|
|
72
|
+
apiKey: parsed.options.apiKey,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
console.log(`Provider config: ${reference}`);
|
|
77
|
+
console.log(`Global config: ${globalConfigPath()}`);
|
|
78
|
+
return;
|
|
91
79
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
80
|
+
if (parsed.options.configAction !== "model-set") {
|
|
81
|
+
throw new Error("zg config requires provider set or model set");
|
|
82
|
+
}
|
|
83
|
+
const catalogEntry = requireEmbeddingModelCatalogEntry(reference);
|
|
84
|
+
if (parsed.options.endpoint === undefined &&
|
|
85
|
+
parsed.options.device === undefined &&
|
|
86
|
+
!parsed.options.defaultModel) {
|
|
87
|
+
throw new Error("zg config model set requires --endpoint, --device, or --default");
|
|
88
|
+
}
|
|
89
|
+
if (catalogEntry.provider === "local" &&
|
|
90
|
+
parsed.options.endpoint !== undefined) {
|
|
91
|
+
throw new Error("--endpoint is only supported for remote embedding models");
|
|
92
|
+
}
|
|
93
|
+
if (catalogEntry.provider !== "local" &&
|
|
94
|
+
parsed.options.device !== undefined) {
|
|
95
|
+
throw new Error("--device is only supported for local embedding models");
|
|
96
|
+
}
|
|
97
|
+
if (parsed.options.endpoint !== undefined) {
|
|
98
|
+
assertHttpEndpoint(parsed.options.endpoint);
|
|
99
|
+
}
|
|
100
|
+
updateGlobalConfig({
|
|
101
|
+
...(parsed.options.endpoint !== undefined ||
|
|
102
|
+
parsed.options.device !== undefined
|
|
103
|
+
? {
|
|
104
|
+
models: {
|
|
105
|
+
[reference]: {
|
|
106
|
+
...(parsed.options.endpoint !== undefined
|
|
107
|
+
? { endpoint: parsed.options.endpoint }
|
|
108
|
+
: {}),
|
|
109
|
+
...(parsed.options.device !== undefined
|
|
110
|
+
? { device: parsed.options.device }
|
|
111
|
+
: {}),
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
: {}),
|
|
116
|
+
...(parsed.options.defaultModel
|
|
117
|
+
? { defaults: { embedding: reference } }
|
|
118
|
+
: {}),
|
|
130
119
|
});
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
async function resolveInstallers(parsed, action) {
|
|
134
|
-
const targetTokens = [
|
|
135
|
-
...(parsed.options.installTargets ?? []),
|
|
136
|
-
...parsed.positionals,
|
|
137
|
-
];
|
|
138
|
-
if (targetTokens.length > 0) {
|
|
139
|
-
return installersFromTokens(targetTokens);
|
|
140
|
-
}
|
|
141
|
-
if (parsed.options.yes === true ||
|
|
142
|
-
!process.stdin.isTTY ||
|
|
143
|
-
!process.stdout.isTTY) {
|
|
144
|
-
return installersFromTokens(["auto"]);
|
|
145
|
-
}
|
|
146
|
-
return promptInstallers(action);
|
|
120
|
+
console.log(`Model config: ${reference}`);
|
|
121
|
+
console.log(`Global config: ${globalConfigPath()}`);
|
|
147
122
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
AGENT_INSTALLERS.forEach((installer, index) => {
|
|
151
|
-
console.log(` ${index + 1}. ${installer.label} - ${installer.description}`);
|
|
152
|
-
});
|
|
153
|
-
console.log(" all. All supported agents");
|
|
154
|
-
console.log(" none. Cancel");
|
|
155
|
-
const readline = createInterface({
|
|
156
|
-
input: process.stdin,
|
|
157
|
-
output: process.stdout,
|
|
158
|
-
});
|
|
123
|
+
function assertHttpEndpoint(endpoint) {
|
|
124
|
+
let parsed;
|
|
159
125
|
try {
|
|
160
|
-
|
|
161
|
-
const normalized = answer.trim();
|
|
162
|
-
return installersFromTokens(normalized.length > 0 ? splitTargetTokens(normalized) : ["codex"]);
|
|
126
|
+
parsed = new URL(endpoint);
|
|
163
127
|
}
|
|
164
|
-
|
|
165
|
-
|
|
128
|
+
catch {
|
|
129
|
+
throw new Error("--endpoint must be a valid HTTP(S) URL");
|
|
166
130
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const normalized = tokens.flatMap(splitTargetTokens);
|
|
170
|
-
if (normalized.length === 0) {
|
|
171
|
-
return installersFromTokens(["auto"]);
|
|
172
|
-
}
|
|
173
|
-
const selected = new Map();
|
|
174
|
-
for (const token of normalized) {
|
|
175
|
-
const lower = token.toLowerCase();
|
|
176
|
-
if (lower === "none") {
|
|
177
|
-
return [];
|
|
178
|
-
}
|
|
179
|
-
if (lower === "auto" || lower === "all") {
|
|
180
|
-
for (const installer of AGENT_INSTALLERS) {
|
|
181
|
-
selected.set(installer.id, installer);
|
|
182
|
-
}
|
|
183
|
-
continue;
|
|
184
|
-
}
|
|
185
|
-
const numbered = /^\d+$/.test(lower) ? Number(lower) : Number.NaN;
|
|
186
|
-
if (Number.isInteger(numbered) &&
|
|
187
|
-
numbered >= 1 &&
|
|
188
|
-
numbered <= AGENT_INSTALLERS.length) {
|
|
189
|
-
const installer = AGENT_INSTALLERS[numbered - 1];
|
|
190
|
-
selected.set(installer.id, installer);
|
|
191
|
-
continue;
|
|
192
|
-
}
|
|
193
|
-
const installer = AGENT_INSTALLERS.find((candidate) => candidate.id === lower || candidate.label.toLowerCase() === lower);
|
|
194
|
-
if (!installer) {
|
|
195
|
-
throw new Error(`Unknown install target: ${token}`);
|
|
196
|
-
}
|
|
197
|
-
selected.set(installer.id, installer);
|
|
131
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
132
|
+
throw new Error("--endpoint must be a valid HTTP(S) URL");
|
|
198
133
|
}
|
|
199
|
-
return [...selected.values()];
|
|
200
|
-
}
|
|
201
|
-
function splitTargetTokens(value) {
|
|
202
|
-
return value
|
|
203
|
-
.split(/[,\s]+/)
|
|
204
|
-
.map((target) => target.trim())
|
|
205
|
-
.filter((target) => target.length > 0);
|
|
206
134
|
}
|
|
207
135
|
async function runIndex(parsed) {
|
|
208
136
|
const explicitRoot = parsed.positionals.length > 0;
|
|
@@ -215,11 +143,125 @@ async function runIndex(parsed) {
|
|
|
215
143
|
await runDropIndex(parsed, rootPath.absolutePath);
|
|
216
144
|
return;
|
|
217
145
|
}
|
|
218
|
-
|
|
219
|
-
|
|
146
|
+
if (parsed.options.embedding) {
|
|
147
|
+
requireEmbeddingModelCatalogEntry(parsed.options.embedding);
|
|
148
|
+
}
|
|
149
|
+
const mode = resolveClientMode(parsed.options.mode);
|
|
150
|
+
await routeByMode({
|
|
151
|
+
mode,
|
|
152
|
+
serverAvailable: () => daemonIsReady(parsed.options.home),
|
|
153
|
+
server: async () => {
|
|
154
|
+
const client = daemonClient(parsed.options);
|
|
155
|
+
const progress = createIndexProgressReporter({
|
|
156
|
+
color: parsed.options.color,
|
|
157
|
+
});
|
|
158
|
+
let result;
|
|
159
|
+
try {
|
|
160
|
+
result = await client.callTool("zvec_grep_index", {
|
|
161
|
+
root: rootPath.absolutePath,
|
|
162
|
+
embedding: parsed.options.embedding,
|
|
163
|
+
apiKey: parsed.options.apiKey,
|
|
164
|
+
endpoint: parsed.options.endpoint,
|
|
165
|
+
device: parsed.options.device,
|
|
166
|
+
rebuild: parsed.options.rebuild,
|
|
167
|
+
resetPaths: parsed.options.resetPaths,
|
|
168
|
+
globs: parsed.options.globs,
|
|
169
|
+
insensitiveGlobs: parsed.options.insensitiveGlobs,
|
|
170
|
+
fileTypes: parsed.options.fileTypes,
|
|
171
|
+
excludedFileTypes: parsed.options.excludedFileTypes,
|
|
172
|
+
hidden: parsed.options.hidden,
|
|
173
|
+
noIgnore: parsed.options.noIgnore,
|
|
174
|
+
ignoreFiles: parsed.options.ignoreFiles,
|
|
175
|
+
maxDepth: parsed.options.maxDepth,
|
|
176
|
+
maxFileSizeBytes: parsed.options.maxFileSizeBytes,
|
|
177
|
+
follow: parsed.options.follow,
|
|
178
|
+
embeddingConcurrency: parsed.options.embeddingConcurrency,
|
|
179
|
+
debug: parsed.options.debug,
|
|
180
|
+
wait: true,
|
|
181
|
+
}, {
|
|
182
|
+
onProgress: (event) => {
|
|
183
|
+
const update = indexProgressFromMessage(event.message);
|
|
184
|
+
if (update) {
|
|
185
|
+
progress.report(update.progress);
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
embeddingEnvironment: process.env.ZVEC_GREP_EMBEDDING?.trim(),
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
progress.finish();
|
|
193
|
+
}
|
|
194
|
+
console.log(`Workspace index: ${String(result.state ?? "submitted")}`);
|
|
195
|
+
console.log(`Root: ${String(result.root ?? rootPath.absolutePath)}`);
|
|
196
|
+
console.log(`Job: ${String(result.job_id ?? "unknown")}`);
|
|
197
|
+
if (parsed.options.debug) {
|
|
198
|
+
printIndexScanDiagnostics(result.scan_diagnostics);
|
|
199
|
+
}
|
|
200
|
+
if (result.state === "failed") {
|
|
201
|
+
throw new Error(serverIndexFailureMessage(result));
|
|
202
|
+
}
|
|
203
|
+
if (result.state === "succeeded") {
|
|
204
|
+
const status = (await client
|
|
205
|
+
.callTool("zvec_grep_index_status", {
|
|
206
|
+
root: rootPath.absolutePath,
|
|
207
|
+
})
|
|
208
|
+
.catch(() => undefined));
|
|
209
|
+
if (status?.persistent.files?.scanned === 0) {
|
|
210
|
+
printNoIndexableFilesTip(parsed.options);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
direct: () => runDirectIndex(parsed, rootPath, explicitRoot),
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
function serverIndexFailureMessage(result) {
|
|
218
|
+
const error = result.error;
|
|
219
|
+
if (error && typeof error === "object") {
|
|
220
|
+
const code = error.code;
|
|
221
|
+
const message = error.message;
|
|
222
|
+
if (typeof message === "string" && message.length > 0) {
|
|
223
|
+
if (typeof code !== "string" ||
|
|
224
|
+
code.length === 0 ||
|
|
225
|
+
message.includes(`[${code}]`)) {
|
|
226
|
+
return message;
|
|
227
|
+
}
|
|
228
|
+
return `[${code}] ${message}`;
|
|
229
|
+
}
|
|
230
|
+
if (typeof code === "string" && code.length > 0) {
|
|
231
|
+
return `[${code}] Index job failed.`;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return `Index job ${String(result.job_id ?? "unknown")} failed. Run zg status --mode server for details.`;
|
|
235
|
+
}
|
|
236
|
+
async function runDirectIndex(parsed, rootPath, explicitRoot) {
|
|
237
|
+
const serviceOptions = createServiceOptions(parsed.options, rootPath.absolutePath);
|
|
238
|
+
const zvecGrep = await createZvecGrep(serviceOptions);
|
|
239
|
+
const progress = createIndexProgressReporter({ color: parsed.options.color });
|
|
220
240
|
try {
|
|
241
|
+
const infoBefore = await zvecGrep.info({
|
|
242
|
+
root: rootPath.absolutePath,
|
|
243
|
+
includeStatus: parsed.options.rebuild !== true,
|
|
244
|
+
});
|
|
245
|
+
const schema = resolveAuthorizationSchema(configuredEmbeddingReference(parsed.options, infoBefore.workspaceIndex?.embedding), infoBefore.workspaceIndex?.embedding);
|
|
246
|
+
assertEmbeddingModelCompatible(infoBefore.workspaceIndex?.embedding, schema, parsed.options.rebuild === true);
|
|
247
|
+
const workspaceRuntime = workspaceRuntimeFromInfo(infoBefore);
|
|
248
|
+
assertRequestedEndpointCompatible(infoBefore, workspaceRuntime, parsed.options.endpoint, parsed.options.rebuild === true);
|
|
249
|
+
const modelInfo = schema?.provider === "qwen"
|
|
250
|
+
? await embeddingModelInfo(schema, serviceOptions, workspaceRuntime)
|
|
251
|
+
: undefined;
|
|
252
|
+
const plan = modelInfo
|
|
253
|
+
? await planRemoteIndexAuthorization({
|
|
254
|
+
info: infoBefore,
|
|
255
|
+
model: modelInfo,
|
|
256
|
+
rebuild: parsed.options.rebuild,
|
|
257
|
+
store: authorizationStore(parsed.options),
|
|
258
|
+
})
|
|
259
|
+
: undefined;
|
|
260
|
+
const authorizationResolution = plan
|
|
261
|
+
? await authorizeCliPlan(plan, parsed.options)
|
|
262
|
+
: {};
|
|
221
263
|
printIndexPathFilterTip(parsed.options);
|
|
222
|
-
const result = await zvecGrep.index({
|
|
264
|
+
const result = await withRemoteEmbeddingOperationPermit(authorizationResolution.authorization, () => zvecGrep.index({
|
|
223
265
|
root: rootPath.absolutePath,
|
|
224
266
|
rootPaths: explicitRoot ? [rootPath] : undefined,
|
|
225
267
|
rebuild: parsed.options.rebuild,
|
|
@@ -236,11 +278,10 @@ async function runIndex(parsed) {
|
|
|
236
278
|
follow: parsed.options.follow,
|
|
237
279
|
embeddingConcurrency: parsed.options.embeddingConcurrency,
|
|
238
280
|
onProgress: progress.report,
|
|
239
|
-
});
|
|
281
|
+
}));
|
|
240
282
|
progress.finish();
|
|
241
283
|
const info = await zvecGrep.info({ root: rootPath.absolutePath });
|
|
242
|
-
printIndexResult("
|
|
243
|
-
persistExplicitGlobalConfig(parsed.options, info.collection?.embedding?.provider);
|
|
284
|
+
printIndexResult("Workspace index", result, parsed.options, info.workspaceIndex?.rootPaths);
|
|
244
285
|
}
|
|
245
286
|
catch (error) {
|
|
246
287
|
progress.finish();
|
|
@@ -255,14 +296,26 @@ async function runDropIndex(parsed, root) {
|
|
|
255
296
|
console.log("Index drop cancelled.");
|
|
256
297
|
return;
|
|
257
298
|
}
|
|
258
|
-
const
|
|
259
|
-
try {
|
|
260
|
-
const removed = await zvecGrep.dropIndex({ root });
|
|
299
|
+
const printResult = (removed) => {
|
|
261
300
|
console.log(removed ? `Dropped index for ${root}` : `No index found for ${root}`);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
301
|
+
};
|
|
302
|
+
await routeByMode({
|
|
303
|
+
mode: resolveClientMode(parsed.options.mode),
|
|
304
|
+
serverAvailable: () => daemonIsReady(parsed.options.home),
|
|
305
|
+
server: async () => {
|
|
306
|
+
const result = await daemonClient(parsed.options).callTool("zvec_grep_index_drop", { root });
|
|
307
|
+
printResult(result.removed === true);
|
|
308
|
+
},
|
|
309
|
+
direct: async () => {
|
|
310
|
+
const zvecGrep = await createZvecGrep(createServiceOptions(parsed.options, root));
|
|
311
|
+
try {
|
|
312
|
+
printResult(await zvecGrep.dropIndex({ root }));
|
|
313
|
+
}
|
|
314
|
+
finally {
|
|
315
|
+
await zvecGrep.close();
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
});
|
|
266
319
|
}
|
|
267
320
|
async function confirmIndexDrop(root, accepted) {
|
|
268
321
|
if (accepted) {
|
|
@@ -283,163 +336,89 @@ async function confirmIndexDrop(root, accepted) {
|
|
|
283
336
|
readline.close();
|
|
284
337
|
}
|
|
285
338
|
}
|
|
286
|
-
async function
|
|
339
|
+
async function runServer(parsed) {
|
|
287
340
|
if (parsed.positionals.length > 0) {
|
|
288
|
-
throw new Error(
|
|
341
|
+
throw new Error(`zg server ${parsed.options.serverStdio ? "--stdio" : parsed.options.serverAction} does not accept positional arguments`);
|
|
342
|
+
}
|
|
343
|
+
const { readPackageVersion } = await import("./version.js");
|
|
344
|
+
if (parsed.options.serverStdio) {
|
|
345
|
+
const { runStdioBootstrapBridge } = await import("../mcp/stdio-bridge.js");
|
|
346
|
+
await runStdioBootstrapBridge({
|
|
347
|
+
cliPath: process.argv[1],
|
|
348
|
+
version: readPackageVersion(),
|
|
349
|
+
home: parsed.options.home,
|
|
350
|
+
tokenFile: parsed.options.serverTokenFile,
|
|
351
|
+
listen: parsed.options.listen,
|
|
352
|
+
mcpToolset: parsed.options.mcpToolset,
|
|
353
|
+
});
|
|
354
|
+
return;
|
|
289
355
|
}
|
|
290
|
-
|
|
291
|
-
|
|
356
|
+
if (parsed.options.serverAction === "on") {
|
|
357
|
+
const { startServer } = await import("../daemon/server-controller.js");
|
|
358
|
+
const status = await startServer({
|
|
359
|
+
cliPath: process.argv[1],
|
|
360
|
+
listen: parsed.options.listen,
|
|
361
|
+
tokenFile: parsed.options.serverTokenFile,
|
|
362
|
+
home: parsed.options.home,
|
|
363
|
+
mcpToolset: parsed.options.mcpToolset,
|
|
364
|
+
});
|
|
365
|
+
printServerControlStatus(status);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
if (parsed.options.serverAction === "off") {
|
|
369
|
+
const { stopServer } = await import("../daemon/server-controller.js");
|
|
370
|
+
printServerControlStatus(await stopServer(parsed.options.home, 30_000, parsed.options.serverTokenFile));
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
if (parsed.options.serverAction === "status") {
|
|
374
|
+
const status = await serverStatus(parsed.options.home);
|
|
375
|
+
printServerControlStatus(status);
|
|
376
|
+
if (parsed.options.checkReady && !status.ready) {
|
|
377
|
+
throw new Error("zvec-grep server is not ready");
|
|
378
|
+
}
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const { runDaemonForeground } = await import("../daemon/runtime.js");
|
|
382
|
+
await runDaemonForeground({
|
|
383
|
+
version: readPackageVersion(),
|
|
384
|
+
listen: parsed.options.listen,
|
|
385
|
+
tokenFile: parsed.options.serverTokenFile,
|
|
386
|
+
home: parsed.options.home,
|
|
387
|
+
mcpToolset: parsed.options.mcpToolset,
|
|
388
|
+
serviceOptions: createServiceOptions(parsed.options, process.cwd()),
|
|
389
|
+
});
|
|
292
390
|
}
|
|
293
391
|
async function runStatus(parsed) {
|
|
294
392
|
const root = parsed.positionals[0] ?? process.cwd();
|
|
295
393
|
if (parsed.positionals.length > 1) {
|
|
296
394
|
throw new Error("zg status accepts at most one root path");
|
|
297
395
|
}
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const [action = "list", name, root] = parsed.positionals;
|
|
309
|
-
validateCollectionArguments(action, parsed.positionals);
|
|
310
|
-
const indexOption = collectionIndexOption(parsed.options);
|
|
311
|
-
if (action !== "index" && indexOption) {
|
|
312
|
-
throw new Error(`${indexOption} can only be used with zg collections index`);
|
|
313
|
-
}
|
|
314
|
-
const zvecGrep = await createZvecGrep(createServiceOptions(parsed.options, undefined));
|
|
315
|
-
try {
|
|
316
|
-
if (action === "list") {
|
|
317
|
-
if (parsed.options.resetPaths) {
|
|
318
|
-
throw new Error("--reset-paths can only be used with zg collections index");
|
|
319
|
-
}
|
|
320
|
-
printCollectionList(await zvecGrep.collections.list(), parsed.options);
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
if (action === "info") {
|
|
324
|
-
if (parsed.options.resetPaths) {
|
|
325
|
-
throw new Error("--reset-paths can only be used with zg collections index");
|
|
326
|
-
}
|
|
327
|
-
if (!name) {
|
|
328
|
-
throw new Error("zg collections info requires <name>");
|
|
329
|
-
}
|
|
330
|
-
const [info, status] = await Promise.all([
|
|
331
|
-
zvecGrep.collections.info(name),
|
|
332
|
-
zvecGrep.collections.status(name),
|
|
333
|
-
]);
|
|
334
|
-
if (!info) {
|
|
335
|
-
throw new Error(`Collection not found: ${name}`);
|
|
336
|
-
}
|
|
337
|
-
printCollectionInfo(info, status, parsed.options);
|
|
338
|
-
return;
|
|
339
|
-
}
|
|
340
|
-
if (action === "index") {
|
|
341
|
-
if (!name) {
|
|
342
|
-
throw new Error("zg collections index requires <name>");
|
|
343
|
-
}
|
|
344
|
-
const explicitRoot = root !== undefined;
|
|
345
|
-
const rootPath = indexRootPath(root ?? process.cwd(), parsed.options);
|
|
346
|
-
const rootPaths = explicitRoot ? rootPath : undefined;
|
|
347
|
-
const progress = createIndexProgressReporter();
|
|
396
|
+
const mode = resolveClientMode(parsed.options.mode);
|
|
397
|
+
const state = await routeByMode({
|
|
398
|
+
mode,
|
|
399
|
+
serverAvailable: () => daemonIsReady(parsed.options.home),
|
|
400
|
+
server: async () => {
|
|
401
|
+
const result = await daemonClient(parsed.options).callTool("zvec_grep_index_status", { root: resolve(root) });
|
|
402
|
+
return printServerIndexInfo(result, parsed.options);
|
|
403
|
+
},
|
|
404
|
+
direct: async () => {
|
|
405
|
+
const zvecGrep = await createZvecGrep(createServiceOptions(parsed.options, root));
|
|
348
406
|
try {
|
|
349
|
-
|
|
350
|
-
rebuild: parsed.options.rebuild,
|
|
351
|
-
resetPaths: parsed.options.resetPaths,
|
|
352
|
-
globs: parsed.options.globs,
|
|
353
|
-
insensitiveGlobs: parsed.options.insensitiveGlobs,
|
|
354
|
-
fileTypes: parsed.options.fileTypes,
|
|
355
|
-
excludedFileTypes: parsed.options.excludedFileTypes,
|
|
356
|
-
hidden: parsed.options.hidden,
|
|
357
|
-
noIgnore: parsed.options.noIgnore,
|
|
358
|
-
ignoreFiles: parsed.options.ignoreFiles,
|
|
359
|
-
maxDepth: parsed.options.maxDepth,
|
|
360
|
-
maxFileSizeBytes: parsed.options.maxFileSizeBytes,
|
|
361
|
-
follow: parsed.options.follow,
|
|
362
|
-
embeddingConcurrency: parsed.options.embeddingConcurrency,
|
|
363
|
-
onProgress: progress.report,
|
|
364
|
-
});
|
|
365
|
-
progress.finish();
|
|
366
|
-
const info = await zvecGrep.collections.info(name);
|
|
367
|
-
printIndexResult(`Indexed collection ${name}`, result, parsed.options, info?.rootPaths);
|
|
368
|
-
persistExplicitGlobalConfig(parsed.options, info?.embedding?.provider);
|
|
407
|
+
return printWorkspaceInfo(await zvecGrep.info({ root }), parsed.options);
|
|
369
408
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
throw error;
|
|
373
|
-
}
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
if (action === "remove") {
|
|
377
|
-
if (parsed.options.resetPaths) {
|
|
378
|
-
throw new Error("--reset-paths can only be used with zg collections index");
|
|
409
|
+
finally {
|
|
410
|
+
await zvecGrep.close();
|
|
379
411
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
printCollectionRemoveResult(name, removed, parsed.options);
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
if (parsed.options.resetPaths) {
|
|
388
|
-
throw new Error("--reset-paths can only be used with zg collections index");
|
|
389
|
-
}
|
|
390
|
-
throw new Error(`Unknown collections action: ${action}`);
|
|
391
|
-
}
|
|
392
|
-
finally {
|
|
393
|
-
await zvecGrep.close();
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
function validateCollectionArguments(action, positionals) {
|
|
397
|
-
if (action === "list") {
|
|
398
|
-
if (positionals.length > 1) {
|
|
399
|
-
throw new Error("zg collections list does not accept arguments");
|
|
400
|
-
}
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
if (action === "info" || action === "remove") {
|
|
404
|
-
if (positionals.length > 2) {
|
|
405
|
-
throw new Error(`zg collections ${action} accepts only <name>`);
|
|
406
|
-
}
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
if (action === "index") {
|
|
410
|
-
if (positionals.length > 3) {
|
|
411
|
-
throw new Error("zg collections index accepts only <name> and [root]");
|
|
412
|
-
}
|
|
413
|
-
return;
|
|
412
|
+
},
|
|
413
|
+
});
|
|
414
|
+
if (parsed.options.checkReady && state !== "ready") {
|
|
415
|
+
throw new Error(`Workspace index is not ready (state: ${state})`);
|
|
414
416
|
}
|
|
415
|
-
throw new Error(`Unknown collections action: ${action}`);
|
|
416
|
-
}
|
|
417
|
-
function collectionIndexOption(options) {
|
|
418
|
-
const candidates = [
|
|
419
|
-
[options.rebuild, "--rebuild"],
|
|
420
|
-
[options.resetPaths, "--reset-paths"],
|
|
421
|
-
[options.embedding, "--embedding"],
|
|
422
|
-
[options.modelCacheDir, "--model-cache"],
|
|
423
|
-
[options.llamaGpu, "--llama-gpu"],
|
|
424
|
-
[options.embeddingParallelism, "--embedding-parallelism"],
|
|
425
|
-
[options.apiKey, "--api-key"],
|
|
426
|
-
[options.endpoint, "--endpoint"],
|
|
427
|
-
[options.embeddingConcurrency, "--embedding-concurrency"],
|
|
428
|
-
[options.globs?.length, "--glob"],
|
|
429
|
-
[options.insensitiveGlobs?.length, "--iglob"],
|
|
430
|
-
[options.fileTypes?.length, "--type"],
|
|
431
|
-
[options.excludedFileTypes?.length, "--type-not"],
|
|
432
|
-
[options.hidden, "--hidden"],
|
|
433
|
-
[options.noIgnore, "--no-ignore"],
|
|
434
|
-
[options.ignoreFiles?.length, "--ignore-file"],
|
|
435
|
-
[options.maxDepth, "--max-depth"],
|
|
436
|
-
[options.maxFileSizeBytes, "--max-filesize"],
|
|
437
|
-
[options.follow, "--follow"],
|
|
438
|
-
];
|
|
439
|
-
return candidates.find(([value]) => Array.isArray(value) ? value.length > 0 : value !== undefined)?.[1];
|
|
440
417
|
}
|
|
441
418
|
async function runQuery(parsed) {
|
|
442
|
-
const rgInput = parsed.options.rg
|
|
419
|
+
const rgInput = parsed.options.rg
|
|
420
|
+
? normalizeManagedRgInput(parsed)
|
|
421
|
+
: undefined;
|
|
443
422
|
const commandOptions = rgInput?.options ?? parsed.options;
|
|
444
423
|
const queries = (rgInput?.queries ?? [
|
|
445
424
|
...parsed.positionals,
|
|
@@ -455,24 +434,64 @@ async function runQuery(parsed) {
|
|
|
455
434
|
? "zg query --rg requires a pattern. Use zg help query for examples."
|
|
456
435
|
: "zg query requires text or --hybrid/--fts/--vector routes. Use zg help query for examples.");
|
|
457
436
|
}
|
|
458
|
-
|
|
459
|
-
|
|
437
|
+
if (!commandOptions.rg) {
|
|
438
|
+
const mode = resolveClientMode(commandOptions.mode);
|
|
439
|
+
if (mode !== "direct") {
|
|
440
|
+
await routeByMode({
|
|
441
|
+
mode,
|
|
442
|
+
serverAvailable: () => daemonIsReady(commandOptions.home),
|
|
443
|
+
server: () => runServerQuery(commandOptions, queries, routes),
|
|
444
|
+
direct: () => runDirectQuery(commandOptions, queries),
|
|
445
|
+
});
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
await runDirectQuery(commandOptions, queries);
|
|
450
|
+
}
|
|
451
|
+
async function runDirectQuery(commandOptions, queries) {
|
|
452
|
+
if (commandOptions.refresh === "background") {
|
|
453
|
+
console.error("warning: --refresh background requires Server mode; Direct mode uses --refresh off");
|
|
454
|
+
}
|
|
455
|
+
const serviceOptions = createServiceOptions(commandOptions, undefined);
|
|
456
|
+
const zvecGrep = await createZvecGrep(serviceOptions);
|
|
457
|
+
const progress = createIndexProgressReporter({
|
|
458
|
+
color: commandOptions.color,
|
|
459
|
+
});
|
|
460
460
|
try {
|
|
461
|
-
const
|
|
462
|
-
if (progressEvent.phase !== "done")
|
|
461
|
+
const contextRequest = contextOptions(commandOptions, queries, (progressEvent) => {
|
|
462
|
+
if (progressEvent.phase !== "done")
|
|
463
463
|
progress.report(progressEvent);
|
|
464
|
-
|
|
465
|
-
|
|
464
|
+
});
|
|
465
|
+
const info = await directQueryInfo(zvecGrep);
|
|
466
|
+
const schema = info.workspaceIndex?.embedding;
|
|
467
|
+
const workspaceRuntime = workspaceRuntimeFromInfo(info);
|
|
468
|
+
const modelInfo = !commandOptions.rg && schema?.provider === "qwen"
|
|
469
|
+
? await embeddingModelInfo(schema, createServiceOptions(commandOptions, info.root), workspaceRuntime)
|
|
470
|
+
: undefined;
|
|
471
|
+
const plan = modelInfo
|
|
472
|
+
? await planRemoteSearchAuthorization({
|
|
473
|
+
info,
|
|
474
|
+
model: modelInfo,
|
|
475
|
+
search: normalizedDirectSearchInput(commandOptions, queries, info.root),
|
|
476
|
+
store: authorizationStore(commandOptions),
|
|
477
|
+
})
|
|
478
|
+
: undefined;
|
|
479
|
+
const authorizationResolution = plan
|
|
480
|
+
? await authorizeCliPlan(plan, commandOptions, "local_search")
|
|
481
|
+
: {};
|
|
482
|
+
const effectiveContextRequest = authorizationResolution.alternative === "local_search"
|
|
483
|
+
? ftsFallbackContextRequest(contextRequest)
|
|
484
|
+
: contextRequest;
|
|
485
|
+
const result = await withRemoteEmbeddingOperationPermit(authorizationResolution.authorization, () => zvecGrep.context(effectiveContextRequest));
|
|
466
486
|
progress.finish();
|
|
467
|
-
|
|
468
|
-
printHumanContextResult(result, commandOptions);
|
|
469
|
-
}
|
|
470
|
-
else {
|
|
471
|
-
printAgentContextResult(result, commandOptions);
|
|
472
|
-
}
|
|
487
|
+
printCliContextResult(result, commandOptions);
|
|
473
488
|
for (const line of contextWarningLines(result)) {
|
|
474
489
|
console.error(line);
|
|
475
490
|
}
|
|
491
|
+
if (effectiveContextRequest.autoUpdate !== true &&
|
|
492
|
+
indexStatusNeedsRefresh(info.status)) {
|
|
493
|
+
printStaleIndexStatus("idle", indexCompletionFromStatus(info.status));
|
|
494
|
+
}
|
|
476
495
|
if (commandOptions.debug) {
|
|
477
496
|
printDebug(result, {
|
|
478
497
|
trace: commandOptions.trace === true,
|
|
@@ -487,7 +506,113 @@ async function runQuery(parsed) {
|
|
|
487
506
|
await zvecGrep.close();
|
|
488
507
|
}
|
|
489
508
|
}
|
|
509
|
+
async function runServerQuery(options, queries, routes) {
|
|
510
|
+
const searchPolicy = resolveServerSearchPolicy(options);
|
|
511
|
+
const structuredContent = await daemonClient(options).callTool("zvec_grep_search", {
|
|
512
|
+
root: resolve(process.cwd()),
|
|
513
|
+
apiKey: options.apiKey,
|
|
514
|
+
device: options.device,
|
|
515
|
+
queries: queries.length ? queries : undefined,
|
|
516
|
+
routes: routes.length ? routes : undefined,
|
|
517
|
+
fuse: options.fuse,
|
|
518
|
+
limit: options.limit,
|
|
519
|
+
trace: options.trace,
|
|
520
|
+
preferSymbol: options.preferSymbol,
|
|
521
|
+
symbolTypes: options.symbolTypes,
|
|
522
|
+
globs: options.globs,
|
|
523
|
+
insensitiveGlobs: options.insensitiveGlobs,
|
|
524
|
+
fileTypes: options.fileTypes,
|
|
525
|
+
excludedFileTypes: options.excludedFileTypes,
|
|
526
|
+
hidden: options.hidden,
|
|
527
|
+
noIgnore: options.noIgnore,
|
|
528
|
+
ignoreFiles: options.ignoreFiles,
|
|
529
|
+
maxDepth: options.maxDepth,
|
|
530
|
+
maxFileSizeBytes: options.maxFileSizeBytes,
|
|
531
|
+
follow: options.follow,
|
|
532
|
+
embeddingConcurrency: options.embeddingConcurrency,
|
|
533
|
+
modifiedAfter: options.modifiedAfter,
|
|
534
|
+
modifiedBefore: options.modifiedBefore,
|
|
535
|
+
freshness: searchPolicy.freshness,
|
|
536
|
+
autoUpdate: searchPolicy.autoUpdate,
|
|
537
|
+
}, {
|
|
538
|
+
toolContract: {
|
|
539
|
+
inputProperties: ["routes"],
|
|
540
|
+
outputProperties: ["result"],
|
|
541
|
+
errorMessage: INCOMPATIBLE_SERVER_SEARCH_MESSAGE,
|
|
542
|
+
},
|
|
543
|
+
});
|
|
544
|
+
const response = parseServerSearchResponse(structuredContent);
|
|
545
|
+
printCliContextResult(response.result, options);
|
|
546
|
+
for (const line of contextWarningLines(response.result)) {
|
|
547
|
+
console.error(line);
|
|
548
|
+
}
|
|
549
|
+
if (response.freshness === "possibly_stale") {
|
|
550
|
+
printStaleIndexStatus(response.indexing?.state, response.indexing);
|
|
551
|
+
}
|
|
552
|
+
if (options.debug) {
|
|
553
|
+
printDebug(response.result, { trace: options.trace === true });
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
function printStaleIndexStatus(state, completion) {
|
|
557
|
+
console.error("status: possibly_stale");
|
|
558
|
+
if (!state)
|
|
559
|
+
return;
|
|
560
|
+
const progress = completion?.completed === undefined || completion.total === undefined
|
|
561
|
+
? ""
|
|
562
|
+
: ` (${completion.completed}/${completion.total})`;
|
|
563
|
+
console.error("results: served_from_current_index");
|
|
564
|
+
console.error(`background_refresh: ${state}${progress}`);
|
|
565
|
+
}
|
|
566
|
+
function daemonClient(options) {
|
|
567
|
+
return new DaemonClient({
|
|
568
|
+
serverUrl: resolveServerUrl(),
|
|
569
|
+
home: options.home,
|
|
570
|
+
tokenFile: options.serverTokenFile,
|
|
571
|
+
allowRemote: options.allowRemote,
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
function ftsFallbackContextRequest(request) {
|
|
575
|
+
const queries = [
|
|
576
|
+
...(request.queries ?? []),
|
|
577
|
+
...(request.query ? [request.query] : []),
|
|
578
|
+
...(request.routes ?? []).map((route) => route.query),
|
|
579
|
+
];
|
|
580
|
+
return {
|
|
581
|
+
...request,
|
|
582
|
+
query: undefined,
|
|
583
|
+
queries: undefined,
|
|
584
|
+
routes: queries.map((query) => ({ mode: "fts", query })),
|
|
585
|
+
autoUpdate: false,
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
async function directQueryInfo(service) {
|
|
589
|
+
return await service.info({ root: process.cwd() });
|
|
590
|
+
}
|
|
591
|
+
function normalizedDirectSearchInput(options, queries, root) {
|
|
592
|
+
const policy = resolveDirectSearchPolicy(options);
|
|
593
|
+
return {
|
|
594
|
+
root,
|
|
595
|
+
apiKey: options.apiKey,
|
|
596
|
+
device: options.device,
|
|
597
|
+
queries: !options.rg && queries.length > 0 ? [...queries] : undefined,
|
|
598
|
+
routes: [...(options.routes ?? [])],
|
|
599
|
+
...policy,
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
async function daemonIsReady(home) {
|
|
603
|
+
return (await serverStatus(home)).ready;
|
|
604
|
+
}
|
|
605
|
+
function printServerControlStatus(status) {
|
|
606
|
+
console.log(`Server: ${status.running ? (status.ready ? "ready" : "starting") : "stopped"}`);
|
|
607
|
+
if (status.pid)
|
|
608
|
+
console.log(`PID: ${status.pid}`);
|
|
609
|
+
if (status.serverUrl)
|
|
610
|
+
console.log(`URL: ${status.serverUrl}`);
|
|
611
|
+
if (status.mcpToolset)
|
|
612
|
+
console.log(`MCP toolset: ${status.mcpToolset}`);
|
|
613
|
+
}
|
|
490
614
|
function contextOptions(options, queries, onAutoUpdateProgress) {
|
|
615
|
+
const policy = resolveDirectSearchPolicy(options);
|
|
491
616
|
return {
|
|
492
617
|
queries: queries.length > 0 ? queries : undefined,
|
|
493
618
|
rg: options.rg,
|
|
@@ -495,9 +620,8 @@ function contextOptions(options, queries, onAutoUpdateProgress) {
|
|
|
495
620
|
rgPaths: options.rgPaths,
|
|
496
621
|
routes: options.routes,
|
|
497
622
|
fuse: options.fuse,
|
|
498
|
-
collection: options.collection,
|
|
499
623
|
limit: options.limit,
|
|
500
|
-
autoUpdate:
|
|
624
|
+
autoUpdate: policy.autoUpdate,
|
|
501
625
|
onAutoUpdateProgress,
|
|
502
626
|
trace: options.trace,
|
|
503
627
|
preferSymbol: options.preferSymbol,
|
|
@@ -517,303 +641,23 @@ function contextOptions(options, queries, onAutoUpdateProgress) {
|
|
|
517
641
|
embeddingConcurrency: options.embeddingConcurrency,
|
|
518
642
|
};
|
|
519
643
|
}
|
|
520
|
-
function normalizeRgInput(parsed) {
|
|
521
|
-
const explicitPatterns = parsed.options.rgOptions?.patterns ?? [];
|
|
522
|
-
const hasPatternFiles = (parsed.options.rgOptions?.patternFiles?.length ?? 0) > 0;
|
|
523
|
-
const queries = explicitPatterns.length > 0 || hasPatternFiles
|
|
524
|
-
? explicitPatterns
|
|
525
|
-
: parsed.positionals.slice(0, 1);
|
|
526
|
-
const paths = explicitPatterns.length > 0 || hasPatternFiles
|
|
527
|
-
? parsed.positionals
|
|
528
|
-
: parsed.positionals.slice(1);
|
|
529
|
-
return {
|
|
530
|
-
queries,
|
|
531
|
-
options: {
|
|
532
|
-
...parsed.options,
|
|
533
|
-
rgPaths: paths.length > 0 ? paths : undefined,
|
|
534
|
-
},
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
644
|
export function createServiceOptions(options, root) {
|
|
538
|
-
const embedding = options.embedding ?? process.env.ZVEC_GREP_EMBEDDING;
|
|
539
|
-
const apiKey = options.apiKey ??
|
|
540
|
-
process.env.ZVEC_GREP_API_KEY ??
|
|
541
|
-
process.env.DASHSCOPE_API_KEY ??
|
|
542
|
-
process.env.QWEN_API_KEY;
|
|
543
|
-
const endpoint = options.endpoint ?? process.env.ZVEC_GREP_ENDPOINT;
|
|
544
645
|
return {
|
|
545
646
|
root,
|
|
546
647
|
home: options.home ?? process.env.ZVEC_GREP_HOME,
|
|
547
|
-
embedding,
|
|
548
|
-
apiKey,
|
|
549
|
-
endpoint,
|
|
550
|
-
modelCacheDir: options.modelCacheDir
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
parseEnvPositiveInteger(process.env.ZVEC_GREP_EMBED_PARALLELISM),
|
|
648
|
+
embedding: options.embedding,
|
|
649
|
+
apiKey: options.apiKey,
|
|
650
|
+
endpoint: options.endpoint,
|
|
651
|
+
modelCacheDir: options.modelCacheDir,
|
|
652
|
+
device: options.device,
|
|
653
|
+
authorizationSigningKeyPath: process.env.ZVEC_GREP_AUTHORIZATION_KEY_FILE,
|
|
554
654
|
};
|
|
555
655
|
}
|
|
556
|
-
function persistExplicitGlobalConfig(options, indexedProvider) {
|
|
557
|
-
if (!updateGlobalConfigFromExplicitOptions(options, indexedProvider)) {
|
|
558
|
-
return;
|
|
559
|
-
}
|
|
560
|
-
console.log(`Global config: ${globalConfigPath()}`);
|
|
561
|
-
}
|
|
562
|
-
function parseEnvLlamaGpu(value) {
|
|
563
|
-
const normalized = value?.trim().toLowerCase() ?? "";
|
|
564
|
-
if (!normalized) {
|
|
565
|
-
return undefined;
|
|
566
|
-
}
|
|
567
|
-
if (normalized === "auto" ||
|
|
568
|
-
normalized === "metal" ||
|
|
569
|
-
normalized === "vulkan" ||
|
|
570
|
-
normalized === "cuda") {
|
|
571
|
-
return normalized;
|
|
572
|
-
}
|
|
573
|
-
if (["false", "off", "none", "disable", "disabled", "0"].includes(normalized)) {
|
|
574
|
-
return false;
|
|
575
|
-
}
|
|
576
|
-
return undefined;
|
|
577
|
-
}
|
|
578
|
-
function parseEnvPositiveInteger(value) {
|
|
579
|
-
const normalized = value?.trim() ?? "";
|
|
580
|
-
if (!/^\d+$/.test(normalized)) {
|
|
581
|
-
return undefined;
|
|
582
|
-
}
|
|
583
|
-
const parsed = Number(normalized);
|
|
584
|
-
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : undefined;
|
|
585
|
-
}
|
|
586
|
-
function resolveCodexHome() {
|
|
587
|
-
return resolve(process.env.CODEX_HOME ?? resolve(homedir(), ".codex"));
|
|
588
|
-
}
|
|
589
|
-
async function writeMarkedFile(options) {
|
|
590
|
-
let existing = await readTextFileIfExists(options.path);
|
|
591
|
-
const next = replaceMarkedBlock(existing, options.startMarker, options.endMarker, options.block);
|
|
592
|
-
if (next === null) {
|
|
593
|
-
existing = removeOrphanedMarkers(existing, options.startMarker, options.endMarker);
|
|
594
|
-
}
|
|
595
|
-
if (next === null && options.hasConflict?.(existing)) {
|
|
596
|
-
if (!options.force) {
|
|
597
|
-
throw new Error(options.conflictMessage ??
|
|
598
|
-
`Existing unmanaged configuration found in ${options.path}`);
|
|
599
|
-
}
|
|
600
|
-
existing = options.removeConflict
|
|
601
|
-
? options.removeConflict(existing)
|
|
602
|
-
: existing;
|
|
603
|
-
}
|
|
604
|
-
await writeTextFileAtomic(options.path, next ?? appendMarkedBlock(existing, options.block));
|
|
605
|
-
}
|
|
606
|
-
async function removeMarkedFile(options) {
|
|
607
|
-
const existing = await readTextFileIfExists(options.path);
|
|
608
|
-
if (!existing) {
|
|
609
|
-
return;
|
|
610
|
-
}
|
|
611
|
-
const next = replaceMarkedBlock(existing, options.startMarker, options.endMarker, "") ??
|
|
612
|
-
removeOrphanedMarkers(existing, options.startMarker, options.endMarker);
|
|
613
|
-
if (next === existing) {
|
|
614
|
-
return;
|
|
615
|
-
}
|
|
616
|
-
await writeTextFileAtomic(options.path, next);
|
|
617
|
-
}
|
|
618
|
-
async function writeTextFileAtomic(path, content) {
|
|
619
|
-
const targetPath = await resolveAtomicWriteTarget(path);
|
|
620
|
-
await mkdir(dirname(targetPath), { recursive: true });
|
|
621
|
-
const mode = await fileModeIfExists(targetPath);
|
|
622
|
-
const temporaryPath = `${targetPath}.${process.pid}.${randomUUID()}.tmp`;
|
|
623
|
-
let temporaryFile;
|
|
624
|
-
try {
|
|
625
|
-
temporaryFile = await open(temporaryPath, "wx", mode);
|
|
626
|
-
await temporaryFile.writeFile(content, "utf8");
|
|
627
|
-
await temporaryFile.sync();
|
|
628
|
-
await temporaryFile.close();
|
|
629
|
-
temporaryFile = undefined;
|
|
630
|
-
if (mode !== undefined) {
|
|
631
|
-
await chmod(temporaryPath, mode);
|
|
632
|
-
}
|
|
633
|
-
await rename(temporaryPath, targetPath);
|
|
634
|
-
}
|
|
635
|
-
catch (error) {
|
|
636
|
-
await temporaryFile?.close().catch(() => undefined);
|
|
637
|
-
await unlink(temporaryPath).catch(() => undefined);
|
|
638
|
-
throw error;
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
async function resolveAtomicWriteTarget(path, visited = new Set()) {
|
|
642
|
-
const absolutePath = resolve(path);
|
|
643
|
-
if (visited.has(absolutePath)) {
|
|
644
|
-
throw new Error(`Cannot atomically write through circular symbolic link: ${path}`);
|
|
645
|
-
}
|
|
646
|
-
try {
|
|
647
|
-
const file = await lstat(absolutePath);
|
|
648
|
-
if (!file.isSymbolicLink()) {
|
|
649
|
-
return absolutePath;
|
|
650
|
-
}
|
|
651
|
-
visited.add(absolutePath);
|
|
652
|
-
const link = await readlink(absolutePath);
|
|
653
|
-
return resolveAtomicWriteTarget(resolve(dirname(absolutePath), link), visited);
|
|
654
|
-
}
|
|
655
|
-
catch (error) {
|
|
656
|
-
if (isNodeError(error) && error.code === "ENOENT") {
|
|
657
|
-
return absolutePath;
|
|
658
|
-
}
|
|
659
|
-
throw error;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
async function fileModeIfExists(path) {
|
|
663
|
-
try {
|
|
664
|
-
return (await stat(path)).mode & 0o777;
|
|
665
|
-
}
|
|
666
|
-
catch (error) {
|
|
667
|
-
if (isNodeError(error) && error.code === "ENOENT") {
|
|
668
|
-
return undefined;
|
|
669
|
-
}
|
|
670
|
-
throw error;
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
async function readTextFileIfExists(path) {
|
|
674
|
-
try {
|
|
675
|
-
return await readFile(path, "utf8");
|
|
676
|
-
}
|
|
677
|
-
catch (error) {
|
|
678
|
-
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
679
|
-
return "";
|
|
680
|
-
}
|
|
681
|
-
throw error;
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
function isNodeError(error) {
|
|
685
|
-
return typeof error === "object" && error !== null && "code" in error;
|
|
686
|
-
}
|
|
687
|
-
function replaceMarkedBlock(existing, startMarker, endMarker, block) {
|
|
688
|
-
const lines = existing.split(/\r?\n/);
|
|
689
|
-
const markerLines = new Set();
|
|
690
|
-
const ranges = [];
|
|
691
|
-
let pendingStart;
|
|
692
|
-
for (const [index, line] of lines.entries()) {
|
|
693
|
-
const trimmed = line.trim();
|
|
694
|
-
if (trimmed === startMarker) {
|
|
695
|
-
markerLines.add(index);
|
|
696
|
-
pendingStart = index;
|
|
697
|
-
continue;
|
|
698
|
-
}
|
|
699
|
-
if (trimmed === endMarker) {
|
|
700
|
-
markerLines.add(index);
|
|
701
|
-
if (pendingStart !== undefined) {
|
|
702
|
-
ranges.push({ start: pendingStart, end: index });
|
|
703
|
-
pendingStart = undefined;
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
const first = ranges[0];
|
|
708
|
-
if (!first) {
|
|
709
|
-
return null;
|
|
710
|
-
}
|
|
711
|
-
const before = retainedMarkedLines(lines, 0, first.start, markerLines, [])
|
|
712
|
-
.join("\n")
|
|
713
|
-
.trimEnd();
|
|
714
|
-
const after = retainedMarkedLines(lines, first.end + 1, lines.length, markerLines, ranges.slice(1))
|
|
715
|
-
.join("\n")
|
|
716
|
-
.trim();
|
|
717
|
-
return ([before, block.trim(), after.trim()]
|
|
718
|
-
.filter((part) => part.length > 0)
|
|
719
|
-
.join("\n\n") + "\n");
|
|
720
|
-
}
|
|
721
|
-
function retainedMarkedLines(lines, start, end, markerLines, removedRanges) {
|
|
722
|
-
const retained = [];
|
|
723
|
-
for (let index = start; index < end; index += 1) {
|
|
724
|
-
if (markerLines.has(index)) {
|
|
725
|
-
continue;
|
|
726
|
-
}
|
|
727
|
-
if (removedRanges.some((range) => index >= range.start && index <= range.end)) {
|
|
728
|
-
continue;
|
|
729
|
-
}
|
|
730
|
-
retained.push(lines[index]);
|
|
731
|
-
}
|
|
732
|
-
return retained;
|
|
733
|
-
}
|
|
734
|
-
function removeOrphanedMarkers(existing, startMarker, endMarker) {
|
|
735
|
-
return (existing
|
|
736
|
-
.split(/\r?\n/)
|
|
737
|
-
.filter((line) => {
|
|
738
|
-
const trimmed = line.trim();
|
|
739
|
-
return trimmed !== startMarker && trimmed !== endMarker;
|
|
740
|
-
})
|
|
741
|
-
.join("\n")
|
|
742
|
-
.trimEnd() + "\n");
|
|
743
|
-
}
|
|
744
|
-
function appendMarkedBlock(existing, block) {
|
|
745
|
-
const prefix = existing.trimEnd();
|
|
746
|
-
return `${prefix.length > 0 ? `${prefix}\n\n` : ""}${block.trim()}\n`;
|
|
747
|
-
}
|
|
748
|
-
function hasCodexMcpServerConfig(existing) {
|
|
749
|
-
return existing.split(/\r?\n/).some((line) => {
|
|
750
|
-
const tableName = tomlTableName(line);
|
|
751
|
-
return tableName !== undefined && isCodexMcpServerTableName(tableName);
|
|
752
|
-
});
|
|
753
|
-
}
|
|
754
|
-
function removeCodexMcpServerConfig(existing) {
|
|
755
|
-
const lines = existing.split(/\r?\n/);
|
|
756
|
-
const kept = [];
|
|
757
|
-
let skipping = false;
|
|
758
|
-
for (const line of lines) {
|
|
759
|
-
const tableName = tomlTableName(line);
|
|
760
|
-
if (tableName !== undefined) {
|
|
761
|
-
skipping = isCodexMcpServerTableName(tableName);
|
|
762
|
-
}
|
|
763
|
-
if (!skipping) {
|
|
764
|
-
kept.push(line);
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
return kept.join("\n").trimEnd() + "\n";
|
|
768
|
-
}
|
|
769
|
-
function tomlTableName(line) {
|
|
770
|
-
return line.match(/^\s*\[([^\]]+)\]\s*(?:#.*)?$/)?.[1]?.trim();
|
|
771
|
-
}
|
|
772
|
-
function isCodexMcpServerTableName(tableName) {
|
|
773
|
-
return /^(?:mcp_servers|"mcp_servers"|'mcp_servers')\s*\.\s*(?:zvec_grep|"zvec_grep"|'zvec_grep')(?:\s*\.|$)/.test(tableName);
|
|
774
|
-
}
|
|
775
|
-
function codexConfigBlock(mcpToolTimeoutSeconds) {
|
|
776
|
-
return `${ZVEC_GREP_CONFIG_START}
|
|
777
|
-
[mcp_servers.zvec_grep]
|
|
778
|
-
command = "zg"
|
|
779
|
-
args = ["serve", "--mcp"]
|
|
780
|
-
env_vars = [
|
|
781
|
-
"DASHSCOPE_API_KEY",
|
|
782
|
-
"QWEN_API_KEY",
|
|
783
|
-
"ZVEC_GREP_API_KEY",
|
|
784
|
-
"ZVEC_GREP_EMBEDDING",
|
|
785
|
-
"ZVEC_GREP_ENDPOINT",
|
|
786
|
-
"ZVEC_GREP_HOME",
|
|
787
|
-
"ZVEC_GREP_MODEL_CACHE",
|
|
788
|
-
"ZVEC_GREP_LLAMA_GPU",
|
|
789
|
-
"ZVEC_GREP_EMBED_PARALLELISM",
|
|
790
|
-
"NODE_LLAMA_CPP_CMAKE_OPTION_GGML_OPENMP",
|
|
791
|
-
"NODE_LLAMA_CPP_CMAKE_OPTION_GGML_NATIVE",
|
|
792
|
-
"NODE_LLAMA_CPP_CMAKE_OPTION_GGML_CPU_ARM_ARCH"
|
|
793
|
-
]
|
|
794
|
-
startup_timeout_sec = 20
|
|
795
|
-
tool_timeout_sec = ${mcpToolTimeoutSeconds}
|
|
796
|
-
default_tools_approval_mode = "auto"
|
|
797
|
-
${ZVEC_GREP_CONFIG_END}`;
|
|
798
|
-
}
|
|
799
|
-
function codexAgentsBlock() {
|
|
800
|
-
return `${ZVEC_GREP_AGENTS_START}
|
|
801
|
-
## zvec-grep
|
|
802
|
-
|
|
803
|
-
Use zvec-grep before grep, rg, or broad file reads when you need to understand or locate code.
|
|
804
|
-
|
|
805
|
-
- **MCP tools**: Use \`zvec_grep_search\` for indexed semantic/lexical code search and \`zvec_grep_rg\` for explicit no-index lexical search.
|
|
806
|
-
- **Indexing and status**: These are CLI-only operations. If an index is missing, use \`zvec_grep_rg\` and mention \`zg index\` as the opt-in setup path; use \`zg status\` when status inspection is needed.
|
|
807
|
-
- **Shell fallback**: If the MCP server is unavailable, use \`zg status\`, \`zg query "<query>"\`, and \`zg query --rg "<pattern>"\`.
|
|
808
|
-
|
|
809
|
-
Prefer focused -g/--glob and -t/--type filters, and exclude dependencies, generated output, caches, build artifacts, and logs unless the task is about those files.
|
|
810
|
-
${ZVEC_GREP_AGENTS_END}`;
|
|
811
|
-
}
|
|
812
656
|
function resolveIndexRoot(root) {
|
|
813
657
|
if (root !== undefined) {
|
|
814
658
|
return root;
|
|
815
659
|
}
|
|
816
|
-
return
|
|
660
|
+
return findNearestWorkspace(process.cwd())?.root ?? process.cwd();
|
|
817
661
|
}
|
|
818
662
|
function indexRootPath(path, options) {
|
|
819
663
|
return {
|