@vibgrate/cli 2026.717.1 → 2026.720.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import { hashString, langById, shortId, canonicalize, grammarSetVersion, hashBytes, langForExtension, setGrammarsOverride, parseSource } from './chunk-VFO5UDAT.js';
2
- import { writeTextFile, pathExists, readJsonFile, loadConfig, computeUpgradeImpact, getChangelogSignals, gitHistoryAvailable, buildVersionTimelines, findPackageTimeline, severityRank, projectTypeToVulnEcosystem, VERSION } from './chunk-M62BGJMK.js';
2
+ import { writeTextFile, pathExists, readJsonFile, loadConfig, computeUpgradeImpact, getChangelogSignals, gitHistoryAvailable, buildVersionTimelines, findPackageTimeline, severityRank, projectTypeToVulnEcosystem, VERSION } from './chunk-AJDUMRVI.js';
3
3
  import * as fs19 from 'fs';
4
4
  import { spawnSync, execFileSync } from 'child_process';
5
5
  import * as path19 from 'path';
@@ -3445,6 +3445,7 @@ function readUsage(root, days, now) {
3445
3445
  const byTool = /* @__PURE__ */ new Map();
3446
3446
  const bySource = /* @__PURE__ */ new Map();
3447
3447
  const byClient = /* @__PURE__ */ new Map();
3448
+ const msByTool = /* @__PURE__ */ new Map();
3448
3449
  const bump2 = (m, key, outcome) => {
3449
3450
  const row = m.get(key) ?? { complete: 0, partial: 0, miss: 0 };
3450
3451
  row[outcome]++;
@@ -3460,18 +3461,28 @@ function readUsage(root, days, now) {
3460
3461
  bump2(byTool, e.tool, outcome);
3461
3462
  bump2(bySource, e.source ?? "mcp", outcome);
3462
3463
  bump2(byClient, e.client ?? "unknown", outcome);
3464
+ if (typeof e.ms === "number" && e.ms >= 0) {
3465
+ const timing = msByTool.get(e.tool) ?? { sum: 0, n: 0 };
3466
+ timing.sum += e.ms;
3467
+ timing.n++;
3468
+ msByTool.set(e.tool, timing);
3469
+ }
3463
3470
  } catch {
3464
3471
  }
3465
3472
  }
3466
3473
  }
3467
- const commands = toDimensionStats(byTool).map((d) => ({
3468
- tool: d.key,
3469
- calls: d.calls,
3470
- complete: d.complete,
3471
- partial: d.partial,
3472
- miss: d.miss,
3473
- successPct: d.successPct
3474
- }));
3474
+ const commands = toDimensionStats(byTool).map((d) => {
3475
+ const timing = msByTool.get(d.key);
3476
+ return {
3477
+ tool: d.key,
3478
+ calls: d.calls,
3479
+ complete: d.complete,
3480
+ partial: d.partial,
3481
+ miss: d.miss,
3482
+ successPct: d.successPct,
3483
+ avgMs: timing && timing.n > 0 ? Math.round(timing.sum / timing.n) : null
3484
+ };
3485
+ });
3475
3486
  const totals = commands.reduce(
3476
3487
  (t, c) => ({
3477
3488
  calls: t.calls + c.calls,
@@ -6596,11 +6607,14 @@ var TOOLS = [
6596
6607
  },
6597
6608
  {
6598
6609
  name: "resolve_library",
6599
- description: "Resolve a library to its canonical id and the version YOUR project uses (drift-annotated).",
6610
+ description: "Resolve a library to its canonical id and the version YOUR project uses (drift-annotated). Call once per library and reuse the returned targetId for every library_docs follow-up \u2014 never guess an id.",
6600
6611
  // Canonical §4: `query` (+ optional `context_project`). `name` kept as a back-compat alias.
6601
6612
  inputSchema: obj(
6602
6613
  {
6603
- query: { type: "string", description: "library name or query" },
6614
+ query: {
6615
+ type: "string",
6616
+ description: 'the package name as written in the dependency file. Good: "react-hook-form". Bad: "forms"'
6617
+ },
6604
6618
  name: { type: "string" },
6605
6619
  context_project: { type: "string" }
6606
6620
  },
@@ -6645,17 +6659,22 @@ var TOOLS = [
6645
6659
  },
6646
6660
  {
6647
6661
  name: "library_docs",
6648
- description: "Version-correct usage docs for a library, sliced to a token budget.",
6662
+ description: "Version-correct usage docs for a library, sliced to a token budget \u2014 official content matched to the version this project has installed, not web-search results. Ask a focused question via query; one call usually answers. After 2 calls without the section you need, stop and read the package source under node_modules instead of searching again.",
6649
6663
  // Canonical §4: `targetId`/`query`, `verbosity`, `max_tokens`. `name`/`tokens` kept as aliases.
6650
6664
  inputSchema: obj(
6651
6665
  {
6652
- targetId: { type: "string", description: "id from resolve_library" },
6653
- query: { type: "string", description: "library name or query" },
6666
+ targetId: { type: "string", description: "id from resolve_library (preferred over query)" },
6667
+ query: {
6668
+ type: "string",
6669
+ description: 'the library plus the specific need. Good: "zod refine custom error message". Bad: "zod" or "docs"'
6670
+ },
6654
6671
  name: { type: "string" },
6655
6672
  context_project: { type: "string" },
6656
6673
  verbosity: { type: "string", enum: ["concise", "balanced", "exhaustive"] },
6657
- max_tokens: { type: "number", description: "token budget" },
6658
- tokens: { type: "number" },
6674
+ // Tolerant on purpose: models often send budgets as strings — the
6675
+ // handler coerces, so don't fail validation over "4000" vs 4000.
6676
+ max_tokens: { type: ["number", "string"], description: "token budget (a numeric string is accepted)" },
6677
+ tokens: { type: ["number", "string"] },
6659
6678
  enterprise_strict: { type: "boolean" },
6660
6679
  follow_up: { type: "boolean" }
6661
6680
  },
@@ -6870,7 +6889,7 @@ var GraphSource = class {
6870
6889
  }
6871
6890
  };
6872
6891
  function createServer(source, opts = {}) {
6873
- const { savings = false, shareStats = false, local = false, dedup = false } = opts;
6892
+ const { savings = false, shareStats = false, local = false, dedup = false, stats } = opts;
6874
6893
  const record = savings || shareStats;
6875
6894
  const root = path19.dirname(path19.dirname(source.graphPath));
6876
6895
  const seen = /* @__PURE__ */ new Set();
@@ -6881,7 +6900,7 @@ function createServer(source, opts = {}) {
6881
6900
  // Routing guidance once at the server level (hosts that surface
6882
6901
  // `instructions` get it at zero per-step schema cost): the flashlight
6883
6902
  // vs the map.
6884
- instructions: 'vg is a code map. Use search_symbols to find a known name or literal string fast \u2014 a multi-word/quoted phrase runs a complete literal sweep and reports totalTextMatches, so reach for it instead of grep even for plain-string "find every occurrence" lookups. Use orient/query_graph for meaning: symptoms, relationships, and what-breaks-if. Responses are concise by default; pass response_format:"detailed" only when a node proves load-bearing. Navigate as little as possible: one good search/query usually locates the code. As soon as you have the file and line, read that file and make the edit \u2014 do not call further graph tools unless the edit fails or the match was wrong.'
6903
+ instructions: 'vg is a code map. Use search_symbols to find a known name or literal string fast \u2014 a multi-word/quoted phrase runs a complete literal sweep and reports totalTextMatches, so reach for it instead of grep even for plain-string "find every occurrence" lookups. Use orient/query_graph for meaning: symptoms, relationships, and what-breaks-if. Responses are concise by default; pass response_format:"detailed" only when a node proves load-bearing. Navigate as little as possible: one good search/query usually locates the code. As soon as you have the file and line, read that file and make the edit \u2014 do not call further graph tools unless the edit fails or the match was wrong. For how-do-I-use-this-library questions call resolve_library once, then library_docs with the returned targetId and a focused query: the docs are official and matched to the version THIS project has installed (drift-annotated) \u2014 prefer them over web search or training-data recall when they conflict. Skip them for language built-ins or APIs already shown in context. If two library_docs calls have not surfaced the section you need, read the package source under node_modules instead of searching again.'
6885
6904
  }
6886
6905
  );
6887
6906
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
@@ -6905,12 +6924,23 @@ function createServer(source, opts = {}) {
6905
6924
  "no code map found. Run `vg` in the project to build .vibgrate/graph.json, then retry."
6906
6925
  );
6907
6926
  }
6927
+ const startedAt = Date.now();
6908
6928
  try {
6909
6929
  const args = request.params.arguments ?? {};
6910
6930
  const result = await tool.handler(graph, args, { root, local, dedup, seen });
6911
- if (record) recordUsage(root, tool.name, result, detectClient(server));
6931
+ const ms = Date.now() - startedAt;
6932
+ stats?.record({ ...measureCall(tool.name, result), client: sanitizeClient(detectClient(server)), ms });
6933
+ if (record) recordUsage(root, tool.name, result, detectClient(server), ms);
6912
6934
  return renderToolResult(result);
6913
6935
  } catch (err) {
6936
+ stats?.record({
6937
+ tool: tool.name,
6938
+ client: sanitizeClient(detectClient(server)),
6939
+ outcome: "miss",
6940
+ ms: Date.now() - startedAt,
6941
+ vgTokens: 0,
6942
+ baselineTokens: 0
6943
+ });
6914
6944
  return errorResult(`tool "${tool.name}" failed: ${err.message}`);
6915
6945
  }
6916
6946
  });
@@ -6928,7 +6958,14 @@ function sleep(ms) {
6928
6958
  timer.unref?.();
6929
6959
  });
6930
6960
  }
6931
- function recordUsage(root, tool, result, client) {
6961
+ function recordUsage(root, tool, result, client, ms) {
6962
+ recordSaving(
6963
+ root,
6964
+ { ...measureCall(tool, result), source: "mcp", client: sanitizeClient(client), ...ms !== void 0 ? { ms } : {} },
6965
+ Date.now()
6966
+ );
6967
+ }
6968
+ function measureCall(tool, result) {
6932
6969
  const outcome = classifyOutcome(result);
6933
6970
  let vgTokens = 0;
6934
6971
  let baselineTokens = 0;
@@ -6936,11 +6973,7 @@ function recordUsage(root, tool, result, client) {
6936
6973
  vgTokens = countTokens(renderedText(renderToolResult(result)));
6937
6974
  baselineTokens = referencedFiles(result).size * PER_FILE_TOKENS;
6938
6975
  }
6939
- recordSaving(
6940
- root,
6941
- { tool, outcome, vgTokens, baselineTokens, source: "mcp", client: sanitizeClient(client) },
6942
- Date.now()
6943
- );
6976
+ return { tool, outcome, vgTokens, baselineTokens };
6944
6977
  }
6945
6978
  function detectClient(server) {
6946
6979
  try {
@@ -7043,6 +7076,21 @@ tools improved):
7043
7076
  - **Version-correct docs:** \`vg lib <name>\` returns drift-annotated, version-
7044
7077
  specific usage docs for a library \u2014 inject these instead of guessing an API.
7045
7078
 
7079
+ ### Library-docs discipline
7080
+
7081
+ When a task needs a library's API, use the docs tools before web search or
7082
+ training-data recall \u2014 they are official content matched to the version **this
7083
+ project has installed**, and they win when the two conflict.
7084
+
7085
+ - **Workflow:** \`resolve_library\` once per library, then \`library_docs\` with the
7086
+ returned \`targetId\` and a focused query (good: "zod refine custom error
7087
+ message"; bad: "zod"). Never guess a targetId.
7088
+ - **Budget:** at most **3 docs calls per task**. If 2 \`library_docs\` calls have
7089
+ not surfaced the section you need, read the package source under
7090
+ \`node_modules\` instead of searching again.
7091
+ - **Skip the docs tools** for language built-ins, stable well-known syntax, or
7092
+ an API already shown in the current context \u2014 they add nothing there.
7093
+
7046
7094
  ## Keep it fresh
7047
7095
 
7048
7096
  The map keeps itself fresh: \`vg ask\` and the MCP tools detect changed files
@@ -7541,6 +7589,6 @@ function spdx(ctx) {
7541
7589
  return JSON.stringify(doc, null, 2) + "\n";
7542
7590
  }
7543
7591
 
7544
- export { ASSISTANTS, CLI_TOOL_ALIASES, CliError, ECOSYSTEMS, ExitCode, FREE_PACK, GraphIndex, GraphSource, NPX_INVOCATION, ResourceLimitError, SCHEMA_VERSION, SKIP_DIRS, SKIP_FILES, TOOLS, UsageError, addLibrary, analyze, applyCoverage, applyStaticTestLinkage, assessDocQuality, assistantById, availableRegionIds, buildFacts, buildGraph, buildModuleResolver, cacheDir, catalogPath, clearModelCache, clearStoredCredentials, cosine, countPending, countTokens, coveringTests, createServer, createWorkspaceDsn, credentialsPath, dashHostForIngestHost, decodeScipIndex, defaultGraphPath, detectAssistants, detectRunner, detectServeLaunch, discover, discoverModels, driftCount, driftFor, dsnCommand, embeddingsCached, enrichOnline, ensureGitignored, epistemicBreakdown, exportGraph, fetchHostedDocsCached, findGitRoot, findNodes, formatForExt, getNodeEmbeddings, gitignoreEntryForCredentials, groundGraph, hasDrift, identifierParts, impactOf, indexFor, ingestHostForRegionId, installAssistant, inventory, isModelReady, isTestFile, libDir, libId, loadCatalog, loadCoverage, loadEmbedder, loadGraph, loadSnapshot, localApiSurface, localPackageDocs, modelCacheInfo, nodeById, nodeEmbedText, parseDsn, parseGraph, parseJsonc, probeFreshness, publishPrivateLibrary, pushCommand, queryGraph, queryGraphSemantic, readDoc, readSavings, readScanArtifact, readUsage, recordCliCall, recordSaving, refreshIfStale, relativeResolver, renderHtml, renderReport, resolveCliInvocation, resolveDsn, resolveEmbedModel, resolveIngestHost, resolveLib, resolveLimits, resolveOne, resolveVersion, saveCatalog, savingsRecorded, scipEdges, selectForBudget, serializeGraph, serveStdio, shortestPath, stableStringify, symbolsFromApi, testsToRun, unavailableMessage, uninstallAssistant, uploadScanArtifact, usageError, verifyDeterminism, vibgrateDir, writeArtifacts, writeNavigationConfig, writeSnapshot, writeStoredCredentials };
7545
- //# sourceMappingURL=chunk-L42NVMD6.js.map
7546
- //# sourceMappingURL=chunk-L42NVMD6.js.map
7592
+ export { ASSISTANTS, CLI_TOOL_ALIASES, CliError, DEFAULT_RATE_LABEL, DEFAULT_RATE_PER_M, ECOSYSTEMS, ExitCode, FREE_PACK, GraphIndex, GraphSource, NPX_INVOCATION, ResourceLimitError, SAVINGS_TOOLS, SCHEMA_VERSION, SKIP_DIRS, SKIP_FILES, TOOLS, UsageError, addLibrary, analyze, applyCoverage, applyStaticTestLinkage, assessDocQuality, assistantById, availableRegionIds, buildFacts, buildGraph, buildModuleResolver, cacheDir, catalogPath, clearModelCache, clearStoredCredentials, cosine, countPending, countTokens, coveringTests, createServer, createWorkspaceDsn, credentialsPath, dashHostForIngestHost, decodeScipIndex, defaultGraphPath, detectAssistants, detectRunner, detectServeLaunch, discover, discoverModels, driftCount, driftFor, dsnCommand, embeddingsCached, enrichOnline, ensureGitignored, epistemicBreakdown, exportGraph, fetchHostedDocsCached, findGitRoot, findNodes, formatForExt, getNodeEmbeddings, gitignoreEntryForCredentials, groundGraph, hasDrift, homeCredentialsPath, hostedBase, identifierParts, impactOf, indexFor, ingestHostForRegionId, installAssistant, inventory, isModelReady, isTestFile, libDir, libId, loadCatalog, loadCoverage, loadEmbedder, loadGraph, loadSnapshot, localApiSurface, localPackageDocs, modelCacheInfo, nodeById, nodeEmbedText, parseDsn, parseGraph, parseJsonc, probeFreshness, projectCredentialsPath, publishPrivateLibrary, pushCommand, queryGraph, queryGraphSemantic, readDoc, readSavings, readScanArtifact, readStoredCredentials, readUsage, recordCliCall, recordSaving, refreshIfStale, relativeResolver, renderHtml, renderReport, resolveCliInvocation, resolveDsn, resolveEmbedModel, resolveIngestHost, resolveLib, resolveLimits, resolveOne, resolveVersion, saveCatalog, savingsRecorded, scipEdges, selectForBudget, serializeGraph, serveStdio, shortestPath, stableStringify, symbolsFromApi, testsToRun, unavailableMessage, uninstallAssistant, uploadScanArtifact, usageError, verifyDeterminism, vibgrateDir, writeArtifacts, writeNavigationConfig, writeSnapshot, writeStoredCredentials };
7593
+ //# sourceMappingURL=chunk-VQLOVQZP.js.map
7594
+ //# sourceMappingURL=chunk-VQLOVQZP.js.map