From f4ebbee8ec1e32511a5a68530afba11e3e6ae72b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 9 Oct 2026 12:06:52 +0000 Subject: [PATCH 1/2] docs: document vg lib lockfile pin and failure modes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Describe lockfile → installed → declared resolution, the lockfiles that lookup reads, and the offline and registry failure text. Signed-off-by: Cursor Agent Co-authored-by: vibgrate-team --- DOCS.md | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++----- README.md | 9 ++++--- 2 files changed, 79 insertions(+), 11 deletions(-) diff --git a/DOCS.md b/DOCS.md index 7f9fb20..9e2c645 100644 --- a/DOCS.md +++ b/DOCS.md @@ -3545,21 +3545,88 @@ Run `vg install --list` for the live support matrix (ids can grow over time) — ### vg lib -Version-correct library docs — from the hosted catalog or local ingestion. +Version-correct library docs, local files first. The page comes from a catalog you ingested with `vg lib add`, or from the package installed in this project. For an installed package, the version in the header is the lockfile pin when the lockfile names that package. A catalog entry prints the version stored with that entry. A thin or missing local page is the only case that asks the hosted catalog, and only when the network is allowed. ```bash -vg lib # List the catalog -vg lib # Show docs for a library (pinned to your lockfile version) -vg lib add # Ingest docs from a local source -vg lib publish # Upload private library docs to the hosted catalog -vg lib resolve # Resolve name → catalog id + version -vg lib refresh # Re-ingest all local sources +vg lib # List the catalog +vg lib react # Docs for react at the lockfile pin +vg lib express --budget 2000 # Same lookup, trimmed to about 2000 tokens +vg lib add # Ingest docs from a local source +vg lib publish # Upload private library docs to the hosted catalog +vg lib resolve # Resolve name → catalog id + version +vg lib refresh # Re-ingest all local sources ``` +`vg lib react` is the local-first lookup. Run it from the project that depends on React. No extra flag is required. + +**Which version.** The version is chosen in this order. An empty step leaves that slot empty: + +1. **Lockfile** — the exact version recorded for that package. +2. **Installed** — the copy on disk when the lockfile has no entry for the name. npm reads `node_modules`. Python reads a `.dist-info` directory under `.venv`, `venv`, `env`, or `.tox`. PHP reads `vendor/composer/installed.json`. +3. **Declared** — the range written in the project manifest when there is no pin and no install. +4. **unknown** — none of the three. No version number is filled in. + +**Lockfiles read.** Files in this table are read from the working directory (`-C` / `--cwd`, otherwise the directory you ran `vg` from). Inside one ecosystem the first file that contains the package supplies the pin. + +| Ecosystem | Lockfiles, in order | +|-----------|---------------------| +| npm | `package-lock.json`, then `pnpm-lock.yaml`, then `yarn.lock` | +| Python | `poetry.lock`, then `uv.lock`, then `Pipfile.lock` | +| Rust | `Cargo.lock` | +| PHP | `composer.lock` | +| Ruby | `Gemfile.lock` | +| .NET | `packages.lock.json` | +| Swift | `Package.resolved` | +| Dart | `pubspec.lock` | +| Java | `gradle.lockfile` | + +**Go (`go.sum`).** `go.sum` is read from that same directory. A kept line is `module version hash`. A line whose version ends in `/go.mod` is the manifest hash and is skipped. That file is the resolved module list. The version `vg lib` prints for a Go module comes from the installed tree, then the `go.mod` `require` line, then unknown. + +**Missing lockfile entry.** The package is not pinned. The command continues with the next step: installed, then declared, then unknown. Generate the lockfile with your package manager and commit it when the header should stay on one exact version. + +**Lockfile and installed tree disagree.** Both versions were readable and they differ. A leading run of `v`, `^`, `~`, `>`, `=`, `<`, and whitespace is ignored before the comparison. The header stays on the lockfile pin, and the command prints: + +``` +⚠ lockfile pins 18.2.0 but the installed tree has 18.3.1 — your install is out of sync with the lockfile (re-install or commit the lock) +``` + +`vg lib react --json` puts the same object on `version_mismatch` (`lockfile`, `installed`, and `note`). When the versions agree, the warning is absent and `version_mismatch` is `null`. The page body is the files on disk, so re-install from the lockfile, or commit the lock that matches what is installed, before treating the page as the pin. + +**Offline and `--local`.** Asking the hosted catalog is on by default, and only after local docs are missing or thin. When the catalog answers, that page is what you see: `✔ local docs were thin — served richer docs from the hosted catalog`. `--offline` skips that request. `--local` implies `--offline`, so it skips the request too. Thin local docs stay on screen: + +``` +⚠ local docs look thin (no code example) — run without --local for the hosted catalog +``` + +The text in parentheses lists why the local page was thin. Several reasons are comma-separated. With no local docs at all the process exits non-zero: + +``` +no library docs for "react" — add with `vg lib add --name react` or install the package (or retry with --online for the hosted catalog) +``` + +`--online` is deprecated on `vg lib` (network is already the default for `add` and `refresh`). It leaves `--offline` and `--local` in force. Drop those flags and run the command again to allow the hosted miss. + +**Registry fetch failed.** A timeout, a failed request, or a response that contains no docs is dropped. The text you see names the library and the next command. It leaves out credentials, a DSN, and the response body. When local docs exist they are still printed: + +``` +⚠ local docs look thin (no code example) — hosted catalog had nothing better +``` + +With no local docs, the process exits non-zero: + +``` +no library docs for "react" — add with `vg lib add --name react` or install the package +``` + +Install the package, or ingest a local source with `vg lib add --name react`, and run `vg lib react` again. + +Global `--json` applies here. `--offline` and `--local` are the switches that keep this command on the machine. + | Flag | Default | Description | |------|---------|-------------| | `--name ` | — | Library name (for `add`) | | `--version ` | — | Pin the doc version (for `add`/`publish`) | +| `--online` | — | Deprecated. Network is already on for `add`/`refresh`. `--offline` and `--local` stay in force | | `-b, --budget ` | — | Trim docs to ~N tokens | | `--readme ` | `./README.md` | README path (for `publish`) | | `--dts ` | — | TypeScript declaration path (for `publish`) | diff --git a/README.md b/README.md index 530e759..d7e7680 100644 --- a/README.md +++ b/README.md @@ -595,13 +595,14 @@ Copy-paste CI templates live in `examples/github-actions/`. When the job fails, ## Version-correct library docs -`vg lib` fetches usage docs pinned to the **exact version in your lockfile** — never a newer API your code can't call yet: +`vg lib` prints usage docs for the exact version in your lockfile, then the installed tree, then the declared range. Local files come first. A thin or missing local page asks the hosted catalog unless you pass `--offline` or `--local`. ```bash -vg lib react # React docs at your installed version -vg lib express --fn middleware # specific function reference +vg lib react ``` +Lockfiles, the pin order, and the failure text are in [DOCS.md](./DOCS.md#vg-lib). + AI assistants connected via MCP use `vg lib` automatically when answering questions about library APIs in your project. --- @@ -722,7 +723,7 @@ Under each set, commands are listed A–Z. A short **typical path** (usual order | `vg guide ` | Cited standards / practices for a node (free pack) | | `vg impact ` | What breaks if you change it — and the tests to run | | `vg install` / `vg uninstall` | Wire (or remove) **Vibgrate AI Context** + skill in your AI assistant (`--detect`, `--all`, `--list`) | -| `vg lib ` | Version-correct, drift-annotated library docs | +| `vg lib ` | Version-correct, drift-annotated library docs pinned to the lockfile ([DOCS.md](./DOCS.md#vg-lib)) | | `vg locale` | Manage your app's translations — locale projects, keys, and translations in Vibgrate Cloud (`push` / `pull` / `status`; `vg localize` is an alias) | | `vg map` / `vg hubs` / `vg areas` / `vg oddities` | Map insights: overview, most-depended-on code, natural groupings, cross-area smells | | `vg models` | Code Modes (Spark / Flow / Forge) + local fleet (Ollama / LM Studio / gguf); `install` / `pull` by default (`--dry-run` to preview) | From c331311d1e9c76e2d5e413e109ab549590d166a3 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 9 Oct 2026 13:07:16 +0000 Subject: [PATCH 2/2] docs: skip go.sum in vg lib lockfile pin docs Rewrite the vg lib section so the version label comes from the lockfiles that are read. go.sum is skipped; Go keeps the version declared in go.mod. Signed-off-by: Cursor Agent Co-authored-by: vibgrate-team --- DOCS.md | 126 +++++++++++++++++++++++++++--------------------------- README.md | 6 +-- 2 files changed, 64 insertions(+), 68 deletions(-) diff --git a/DOCS.md b/DOCS.md index 9e2c645..f39554a 100644 --- a/DOCS.md +++ b/DOCS.md @@ -54,6 +54,8 @@ For a quick overview, see the [README](./README.md). This document covers everyt - [vg impact](#vg-impact) - [vg install / vg uninstall](#vg-install) - [vg lib](#vg-lib) + - [Lockfile pin](#lockfile-pin) + - [When a lookup fails](#when-a-lookup-fails) - [vg locale](#vg-locale) - [vg map / vg hubs / vg areas / vg oddities](#vg-map--vg-hubs--vg-areas--vg-oddities) - [vg llm-host](#vg-llm-host) @@ -3545,94 +3547,90 @@ Run `vg install --list` for the live support matrix (ids can grow over time) — ### vg lib -Version-correct library docs, local files first. The page comes from a catalog you ingested with `vg lib add`, or from the package installed in this project. For an installed package, the version in the header is the lockfile pin when the lockfile names that package. A catalog entry prints the version stored with that entry. A thin or missing local page is the only case that asks the hosted catalog, and only when the network is allowed. +`vg lib ` prints usage docs for one library. When a lockfile in the project root lists that package, the version label is that pin. ```bash -vg lib # List the catalog -vg lib react # Docs for react at the lockfile pin -vg lib express --budget 2000 # Same lookup, trimmed to about 2000 tokens -vg lib add # Ingest docs from a local source -vg lib publish # Upload private library docs to the hosted catalog -vg lib resolve # Resolve name → catalog id + version -vg lib refresh # Re-ingest all local sources +vg lib react ``` -`vg lib react` is the local-first lookup. Run it from the project that depends on React. No extra flag is required. - -**Which version.** The version is chosen in this order. An empty step leaves that slot empty: - -1. **Lockfile** — the exact version recorded for that package. -2. **Installed** — the copy on disk when the lockfile has no entry for the name. npm reads `node_modules`. Python reads a `.dist-info` directory under `.venv`, `venv`, `env`, or `.tox`. PHP reads `vendor/composer/installed.json`. -3. **Declared** — the range written in the project manifest when there is no pin and no install. -4. **unknown** — none of the three. No version number is filled in. +```bash +vg lib # List the local catalog +vg lib # Docs for one library +vg lib add # Ingest docs from a local source +vg lib publish # Upload private library docs to the hosted catalog +vg lib resolve # Resolve name → catalog id + version +vg lib refresh # Re-ingest local sources +``` -**Lockfiles read.** Files in this table are read from the working directory (`-C` / `--cwd`, otherwise the directory you ran `vg` from). Inside one ecosystem the first file that contains the package supplies the pin. +| Flag | Default | Description | +|------|---------|-------------| +| `--name ` | — | Library name (for `add`) | +| `--version ` | — | Pin the doc version (for `add`/`publish`) | +| `-b, --budget ` | — | Trim docs to ~N tokens | +| `--readme ` | `./README.md` | README path (for `publish`) | +| `--dts ` | — | TypeScript declaration path (for `publish`) | +| `--language ` | — | Primary language (for `publish`) | +| `--region ` | `us` | Data-residency region for the hosted catalog | +| `--ingest ` | — | Hosted catalog URL override (wins over `--region`) | +| `-C, --cwd ` | `.` | Directory whose lockfiles and manifests are read | +| `--json` | — | Machine-readable JSON, including `source` and `version_mismatch` | +| `--offline` | off | Skip the hosted catalog | +| `--local` | off | On-device only; implies `--offline`, so the hosted catalog is skipped | -| Ecosystem | Lockfiles, in order | -|-----------|---------------------| -| npm | `package-lock.json`, then `pnpm-lock.yaml`, then `yarn.lock` | -| Python | `poetry.lock`, then `uv.lock`, then `Pipfile.lock` | -| Rust | `Cargo.lock` | -| PHP | `composer.lock` | -| Ruby | `Gemfile.lock` | -| .NET | `packages.lock.json` | -| Swift | `Package.resolved` | -| Dart | `pubspec.lock` | -| Java | `gradle.lockfile` | +#### Lockfile pin -**Go (`go.sum`).** `go.sum` is read from that same directory. A kept line is `module version hash`. A line whose version ends in `/go.mod` is the manifest hash and is skipped. That file is the resolved module list. The version `vg lib` prints for a Go module comes from the installed tree, then the `go.mod` `require` line, then unknown. +A pin is looked up when the name is a declared dependency. For npm that is `dependencies` and `devDependencies` in `package.json`. A name that exists only inside a lockfile has no pin from this command. -**Missing lockfile entry.** The package is not pinned. The command continues with the next step: installed, then declared, then unknown. Generate the lockfile with your package manager and commit it when the header should stay on one exact version. +The label uses the first version it can read: -**Lockfile and installed tree disagree.** Both versions were readable and they differ. A leading run of `v`, `^`, `~`, `>`, `=`, `<`, and whitespace is ignored before the comparison. The header stays on the lockfile pin, and the command prints: +1. The lockfile pin, from the files in the table below. +2. The installed copy, when those files have no entry. +3. The range written in the manifest, when there is no pin and no installed copy. -``` -⚠ lockfile pins 18.2.0 but the installed tree has 18.3.1 — your install is out of sync with the lockfile (re-install or commit the lock) -``` +`--json` reports that choice as `source`: `lockfile`, `installed`, `declared`, or `unknown`. -`vg lib react --json` puts the same object on `version_mismatch` (`lockfile`, `installed`, and `note`). When the versions agree, the warning is absent and `version_mismatch` is `null`. The page body is the files on disk, so re-install from the lockfile, or commit the lock that matches what is installed, before treating the page as the pin. +Readers open these filenames in the directory you run from (`-C` changes it). A lockfile that lives only in a subdirectory is left unread. For npm, the first file that contains the name wins. -**Offline and `--local`.** Asking the hosted catalog is on by default, and only after local docs are missing or thin. When the catalog answers, that page is what you see: `✔ local docs were thin — served richer docs from the hosted catalog`. `--offline` skips that request. `--local` implies `--offline`, so it skips the request too. Thin local docs stay on screen: +| Ecosystem | File | What is read | +|-----------|------|----------------| +| npm | `package-lock.json` | v2/v3: `packages["node_modules/"].version`. v1: `dependencies..version`. | +| npm | `pnpm-lock.yaml` | The importer entry's `version`. A peer suffix such as `(zod@4.0.0)` is removed. | +| npm | `yarn.lock` | The `version` line in the block whose header names the package. | +| Python | `poetry.lock`, then `uv.lock` | `version` on the `[[package]]` table with that name. Matching ignores case and treats `-`, `_`, and `.` as the same character. | +| Python | `Pipfile.lock` | `version` under `default` or `develop`, with a leading `==` removed. Same name matching as Poetry. | +| Rust | `Cargo.lock` | `version` on the `[[package]]` table. Crate names are matched case-insensitively. | +| Ruby | `Gemfile.lock` | The concrete version in the specs block (`name (1.2.3)`). | +| PHP | `composer.lock` | `version` in `packages` or `packages-dev`, with a leading `v` removed. | +| .NET | `packages.lock.json` | `resolved` under `dependencies..`. Ids are matched case-insensitively. | +| Swift | `Package.resolved` | `state.version` for a matching `identity` (v1 `object.pins`, or v2/v3 `pins`). | +| Dart | `pubspec.lock` | The `version` field on that package. | +| Java | `gradle.lockfile` | The version in a `group:artifact:version=` line. Pass the name as `group:artifact`. | -``` -⚠ local docs look thin (no code example) — run without --local for the hosted catalog -``` +The pin lookup skips `go.sum` (Go keeps the version declared in `go.mod`), `pdm.lock`, `npm-shrinkwrap.json`, `bun.lock`, and Maven lockfiles. A Java dependency declared only in `pom.xml` uses that declared version. -The text in parentheses lists why the local page was thin. Several reasons are comma-separated. With no local docs at all the process exits non-zero: +The text is chosen separately from the label: -``` -no library docs for "react" — add with `vg lib add --name react` or install the package (or retry with --online for the hosted catalog) -``` +- A catalog entry from `vg lib add` is printed with the version stored on that entry. +- Otherwise, for an npm package, the command reads the installed package: `llms.txt`, then a README, then markdown under `docs/`, then the `description` in `package.json`. The label stays the lockfile pin when one exists, so the words can be the installed copy while the heading shows the pin. +- When that text is missing or too thin, and the run may use the network, the hosted catalog is asked by library name. The heading then shows the version the catalog returned. When the catalog omits a version, the heading keeps the lockfile label. -`--online` is deprecated on `vg lib` (network is already the default for `add` and `refresh`). It leaves `--offline` and `--local` in force. Drop those flags and run the command again to allow the hosted miss. +#### When a lookup fails -**Registry fetch failed.** A timeout, a failed request, or a response that contains no docs is dropped. The text you see names the library and the next command. It leaves out credentials, a DSN, and the response body. When local docs exist they are still printed: +**Missing lockfile entry.** The lockfile is absent, or it has no row for that name. The label moves to the installed version, then to the declared range. `--json` sets `source` to `installed`, `declared`, or `unknown`. -``` -⚠ local docs look thin (no code example) — hosted catalog had nothing better -``` +**Lockfile and install disagree.** When both a pin and an installed version are readable and they differ, the label stays the pin. The command prints a warning that names both versions: the lockfile pins one version and the installed tree has the other. Reinstall from the lockfile, or commit the lockfile that matches what is installed. The warning is omitted when the two versions agree. `--json` puts the same pair on `version_mismatch` (`lockfile`, `installed`, `note`), or `null` when they agree. The installed copy is `node_modules//package.json` for npm, a `.dist-info` directory under `.venv`, `venv`, `env`, or `.tox` for Python, and `vendor/composer/installed.json` for PHP. Other ecosystems can show a pin without this comparison. -With no local docs, the process exits non-zero: +**Offline or `--local`.** `--local` and `--offline` both skip the hosted catalog. A catalog entry and installed npm docs still print. When neither exists, the command exits 3: -``` -no library docs for "react" — add with `vg lib add --name react` or install the package +```text +no library docs for "" — add with `vg lib add --name ` or install the package (or retry with --online for the hosted catalog) ``` -Install the package, or ingest a local source with `vg lib add --name react`, and run `vg lib react` again. +The error text mentions `--online`. Remove `--local` or `--offline` and run the command again; those two flags are what keep the hosted catalog off. The network is on unless you pass one of them. -Global `--json` applies here. `--offline` and `--local` are the switches that keep this command on the machine. +**Network fetch fails.** A timeout, a connection error, a non-success response, or an empty body counts as no hosted answer. The message leaves out the response body and any credential. A failed attempt is not saved. A successful answer can be reused for about a day, so a later outage can still show that earlier text. When local text exists, it is printed, with a note that the local docs look thin and the hosted catalog had nothing better. When no local text exists either, the command exits 3 with the not-found message above, without the `--online` hint. -| Flag | Default | Description | -|------|---------|-------------| -| `--name ` | — | Library name (for `add`) | -| `--version ` | — | Pin the doc version (for `add`/`publish`) | -| `--online` | — | Deprecated. Network is already on for `add`/`refresh`. `--offline` and `--local` stay in force | -| `-b, --budget ` | — | Trim docs to ~N tokens | -| `--readme ` | `./README.md` | README path (for `publish`) | -| `--dts ` | — | TypeScript declaration path (for `publish`) | -| `--language ` | — | Primary language (for `publish`) | -| `--region ` | `us` | Data-residency region for the hosted catalog | -| `--ingest ` | — | Hosted catalog URL override (wins over `--region`) | +**Unreadable lockfile.** A lockfile that is present but truncated, invalid, or unreadable stops the command and exits 1. The message names the file and tells you to restore or regenerate it with your package manager. File contents stay out of the message. --- diff --git a/README.md b/README.md index d7e7680..2e2bb26 100644 --- a/README.md +++ b/README.md @@ -595,14 +595,12 @@ Copy-paste CI templates live in `examples/github-actions/`. When the job fails, ## Version-correct library docs -`vg lib` prints usage docs for the exact version in your lockfile, then the installed tree, then the declared range. Local files come first. A thin or missing local page asks the hosted catalog unless you pass `--offline` or `--local`. +`vg lib ` prints usage docs for one library. When a lockfile in the project root lists that package, the version label is that pin. Which files are read, and what happens when the pin is missing, the install disagrees, or the catalog fetch fails: [DOCS.md](./DOCS.md#lockfile-pin). ```bash vg lib react ``` -Lockfiles, the pin order, and the failure text are in [DOCS.md](./DOCS.md#vg-lib). - AI assistants connected via MCP use `vg lib` automatically when answering questions about library APIs in your project. --- @@ -723,7 +721,7 @@ Under each set, commands are listed A–Z. A short **typical path** (usual order | `vg guide ` | Cited standards / practices for a node (free pack) | | `vg impact ` | What breaks if you change it — and the tests to run | | `vg install` / `vg uninstall` | Wire (or remove) **Vibgrate AI Context** + skill in your AI assistant (`--detect`, `--all`, `--list`) | -| `vg lib ` | Version-correct, drift-annotated library docs pinned to the lockfile ([DOCS.md](./DOCS.md#vg-lib)) | +| `vg lib ` | Version-correct, drift-annotated library docs | | `vg locale` | Manage your app's translations — locale projects, keys, and translations in Vibgrate Cloud (`push` / `pull` / `status`; `vg localize` is an alias) | | `vg map` / `vg hubs` / `vg areas` / `vg oddities` | Map insights: overview, most-depended-on code, natural groupings, cross-area smells | | `vg models` | Code Modes (Spark / Flow / Forge) + local fleet (Ollama / LM Studio / gguf); `install` / `pull` by default (`--dry-run` to preview) |