Skip to content

Repository files navigation

quarry

One face for every repo.
Everything, in its right place.

Designed to be used with Capstone Installs as a single precompiled binary Requires Git 2.30 or newer at runtime Apache-2.0 licensed

Support quarry on Patreon Buy Gent a coffee

Capstone documents each repo in place, beside the code it describes. quarry copies those references into a single git repository and indexes them. What comes back is the answer that spans repos: who consumes what this one produces, what breaks if it changes, what a contract actually says. quarry writes no documentation and runs no model.

Capstone writes each repo's docs in place; init clones the shared docs repo; add and update import at one commit, subject to a stamp comparison; sync rebuilds a local index; eight docs commands answer from it.

Install · Use it · In CI · Edges · Contracts · Commands · Rules · With Capstone

Read the complete user manual · Markdown source
Worked examples, every command and output format, configuration, indexing, contract checks, and implementation limits.


Install

Step 1: give your repos something worth copying

quarry writes no documentation. It copies and indexes; every page it serves was generated somewhere else. Use Capstone to produce them. Same author, same licence, and the tool quarry was built against.

/plugin marketplace add GentBajko/capstone     # Claude Code
/plugin install capstone@capstone-marketplace
gh skill install GentBajko/capstone --all --agent github-copilot   # Copilot
npx skills add GentBajko/capstone                                  # 70+ other agents

Then /capstone:map in each repo, which reads the code and writes docs/capstone/: an index, numbered chapters, the business logic scenario by scenario, and 09-interfaces.md, the chapter that declares what the repo produces and consumes. That last one is what makes deps and path work at all.

This is not decoration. quarry's requirements are Capstone's output shape: quarry add refuses a repo with no 00-index.md, every result's date comes from a generated_date stamp, and edges come from the interfaces chapter. Anything else works only if you reproduce that shape by hand.

Step 2: install quarry

Build from the documented source revision. As of 9 September 2026, no GitHub binary releases are published; the previously listed release installer URLs return 404.

cargo install --locked --git https://github.com/GentBajko/quarry --rev 78c71fab5f5818662dc02d5867246cec963567a9

The same Cargo command works in a shell or PowerShell with Rust and the C build tools for your target installed. The manifest declares Rust 1.85+; the documented source build was verified with Rust 1.91.1. Cargo normally installs into ~/.cargo/bin; ensure its bin directory is on PATH. See the installation manual for a checkout-based build and release availability details.

Once built, Quarry needs Git 2.30+ on PATH and no background service. It uses Git's existing credentials and proxy settings. SQLite is compiled in.

Use it

Five commands run in a source repo, once each in the places you'd expect:

quarry init --url git@github.com:acme/docs-quarry.git   # once per repo
quarry add                                             # register and import
quarry update                                          # after every merge to main
quarry sync                                            # pull what other repos pushed
quarry check                                           # before merging: are consumers' fields still produced

Eight answer questions, from the local index, offline, with --json on every one. Add --sync to pull first, or set sync_on_read in the config to make every read do so:

quarry docs list                                    # every repo, with page and edge counts
quarry docs list record-store                       # one repo's files and their dates
quarry docs show record-store                       # stamps, both edge directions, overview
quarry docs section record-store "file-ingest (v2)" # one section, never a whole file
quarry docs search "file-ingest" --repo record-store
quarry docs deps ingest-api --downstream --depth 2  # who breaks if this changes
quarry docs deps report-builder --upstream          # what this repo relies on
quarry docs path ingest-api report-builder          # the chain between two repos

What that last group is for:

$ quarry docs deps ingest-api --downstream --depth 0
ingest-api
  sqs file-ingest -> record-store
    http GET /records -> report-builder
2 repos, depth 2

$ quarry docs section record-store "file-ingest (v2)"
record-store/09-interfaces.md § file-ingest (v2)   2026-09-03

| Field        | Type          | Required | Notes                                     |
|--------------|---------------|----------|-------------------------------------------|
| file_id      | string (uuid) | yes      |                                           |
| content_type | enum          | yes      | accepted: application/json, application/xml |

Two calls, and the CSV parser nobody has written yet already has a constraint attached to it: content_type is an enum without CSV, and it lives in a repo you were not going to open.

In CI

One reusable workflow, held in the docs repo, does the install, the init and the update. Each source repo calls it in one block and holds no secret of its own:

on: { push: { branches: [main] } }
jobs:
  quarry:
    uses: acme/docs-quarry/.github/workflows/quarry-update.yml@main
    with: { docs-repo: acme/docs-quarry }
    secrets:
      app-id: ${{ secrets.QUARRY_APP_ID }}
      app-private-key: ${{ secrets.QUARRY_APP_PRIVATE_KEY }}

templates/quarry-update.yml is the workflow being called. Create a GitHub App with contents: write, install it on the organisation, and store its id and private key as organisation secrets; every job mints a token scoped to the docs repo and valid for an hour, so nothing long-lived sits in any repo. Its quarry-version input pins the installer to a release tag and defaults to v0.2.0, so two hundred callers do not all move the day a release ships. The tag it names has to be a published release with the installer assets attached; cut the release before the workflow reaches the docs repo's default branch. The workflow runs quarry init with no --url, so link each repo once locally and commit its .quarry/.config; init is then a no-op. The token reaches git through an insteadOf rule on the runner rather than through the URL, so the committed config keeps its plain URL, ssh or https. Both rewrites are anchored on the .git suffix, so link the docs repo with it: quarry init --url https://github.com/acme/docs-quarry also works locally, but that spelling matches neither rewrite and the CI push then goes out with no token.

The committer is the folder. The workflow sets GIT_COMMITTER_NAME to the calling repo's name, and every import touches that folder plus the root 00-index.md. templates/quarry-audit.yml, run nightly in the docs repo, walks git log --name-only over the last 24 hours and fails on any commit that broke that rule; a monorepo's target folders count as the calling repo's, because each carries a stamp whose origin ends in that repo's name, and the parent commit's stamp answers for a folder the commit removed. Its second job lists organisation repos with no folder in the docs repo, the consumer nobody registered. Where the host can enforce the rule on push, do that as well: a GitLab custom server hook or a GitHub Enterprise pre-receive hook runs the same loop the audit job runs, over old..new instead of --since. GitHub.com cannot, which is what the nightly job is for.

Same access group as the code. Every page in the docs repo was read out of a source repo, so anyone who can read the docs repo can read a summary of all of them. Grant it to the group that already reads the code, and no wider.

--strict imports nothing it cannot vouch for. The workflow's strict input defaults to true. update --strict and add --strict refuse, before writing anything, when a page holds a secret-shaped string, naming the file and the shape and never the string:

docs/capstone/07-operations.md matches the github-token shape
remove them from the docs before importing

Without --strict the same finding is a note and the import proceeds. The shapes are AWS access keys, GitHub tokens, Slack tokens, Stripe keys, Google API keys and PEM private-key headers; Capstone's map check greps for the same six, and its redact config key keeps matching values out of the operations chapter in the first place. A site the interfaces chapter names but the tree does not hold refuses under --strict the same way, unless the chapter is marked mode: prescriptive, which skips the site check altogether. A repo that wants those findings as notes rather than a refusal calls the workflow with strict: false.

On pull requests, add a second job that runs quarry init and then quarry check; it needs the clone and nothing else, and exits 1 on a contract break (see Contract check).

Cross-repo edges

Edges come from each repo's own 09-interfaces.md, written as tables:

## Produces

| Kind | Name | To | Site |
|---|---|---|---|
| sqs | file-ingest | [record-store](../record-store/09-interfaces.md) | `src/publish.rs` |

## Consumes

| Kind | Name | From |
|---|---|---|
| http | GET /users/{id} | [identity-api](../identity-api/09-interfaces.md) |

Columns are matched by name, not position, so a renamed column is a warning rather than a silent zero; a To column that exists with an empty cell is a row for the name join, not a mistake. Backticks and link syntax are stripped from cells, so the relative link that gives you a graph in any markdown viewer is the same cell the repo name comes from. Tables are read only on that page and never inside a fenced block, so a document describing this format declares nothing.

Frontmatter says the same thing as data, and wins when a page carries both. The edges: block on 09-interfaces.md is the canonical form:

edges:
  produces:
    - { kind: sqs,  name: file-ingest,      site: src/publish.rs, schema: FileIngestMessage }
  consumes:
    - { kind: http, name: "GET /users/{id}", site: src/auth.rs,   schema: UserRef, from: identity-api }

kind is free-form and lowercased; name is required and kept verbatim. to takes one repo name or a list of them, and quarry writes one edge per entry. Three forms are read, in this order: the edges: block, then top-level produces:/consumes: keys, then the tables. Pages written against the older shapes keep working unchanged.

to and from are optional. A row that names neither is a row quarry resolves itself, described under The name join. to: unknown records a decision, so quarry never joins it and Capstone never asks about it again. Either side may declare an edge, and when both do quarry reports declared_by: both. A disagreement between the two stays visible instead of being merged away. An edge pointing at a repo that is not in the docs repo is kept and marked (not in quarry), so a broken link is something you can see. Repos declaring no edges at all are still fully searchable.

schema names a ### <Entity> section of the same repo's 02-models.md and quarry check reads the fields from there (see Contract check). A row without it carries its fields in its own ### <Name> section.

site is a repo-relative path. The chapter is normative and a line number drifts on every edit, so write the path alone; quarry strips a trailing :line or :from-to from what it reads, and pages written with one keep working. The path is tested against the imported commit's tracked files. A miss does not stop the import: the page lands, the output carries a note such as site src/gone.rs for http GET /records is not in the tree at 4f1c9a2, the folder's stamp records the edge under unverified, and deps marks it (site unverified) from either end until a later import verifies it. add --strict and update --strict refuse instead, listing every unverifiable site, and write nothing. A chapter whose frontmatter carries mode: prescriptive names planned paths. Its sites are skipped: nothing is noted or stamped, and --strict does not refuse on it.

The join key is the folder name, the last segment of the origin URL, and the consumer's code usually knows a hostname or a compose service name instead. A producer can list what it is called:

known_as: [records.internal, records-service, records-svc]

on any of its pages, and Capstone writes it into 09-interfaces.md from the deploy config. A to/from cell resolves against the exact folder name first, then case-insensitively, then through those aliases. An edge that resolved through an alias keeps the string as written in as_declared and prints (declared as records-svc), so the disagreement stays visible. An alias two repos claim is ignored with a warning, and quarry docs index lists every target that resolved to nothing with the nearest registered names beside it.

A producer that cannot name its callers writes to: unknown. That row is a publication: counted, searchable, shown by docs show as -> (unknown), and never an edge. docs deps --downstream then appends repos whose interfaces page mentions the name, marked (by name only). Treat that list as a lead and confirm it before acting on it. The walk stops at a by-name row rather than expanding it, and the closing <N> repos line counts only repos reached over a real edge. Five rows naming four repos can therefore end on 3 repos, depth 1, one name having arrived by name alone.

The name join

No repository holds another repository's name. A publisher knows a topic, a route knows a path, a client knows a base URL. So a page is allowed to leave to and from out, and quarry pairs the two ends itself at index time by matching (kind, name) across repos:

$ quarry docs deps record-store --downstream
record-store
  http GET /records -> report-builder (resolved by name)
1 repos, depth 1

Routed kinds (http, ws, wss, grpc) join on a normalised route: the method is lowercased and every path parameter becomes {}, so GET /users/{id}, get /users/:id and GET /users/<id> are one key. Every other kind joins on the name as written.

The join runs over the consumes rows: each one looks for repos publishing its key. Exactly one producer makes the edge, stored with declared_by: joined and resolved_by: "name" and marked (resolved by name) by deps and show. A producer's edges are the ones its consumers claim, so one API read by four repos is four edges and needs nothing from the producer's page.

Two repos publishing the key one consumer reads is a real question: the consumer calls one of them and nothing on the page says which. That row joins nothing, and quarry docs index reports it against the consumer and leaves the decision to a person:

unresolved: http GET /users/{id} consumed by ingest-api: 2 producers, identity-api, admin-api

--json carries the same rows under result.ambiguous. A produces row that reached no consumer stays a publication, exactly as to: unknown does. A to or from a person wrote is never overwritten, and the join never touches it.

Observed edges

Declared edges are what the model wrote down. Traffic is what happened. An optional observed-edges.json at the docs repo root brings the two together:

{
  "generated_at": "2026-09-05",
  "edges": [
    {"from": "record-store", "to": "report-builder", "kind": "http", "name": "GET /records", "last_seen": "2026-09-05"}
  ]
}

One row per caller, callee and route. from and to are repo names, or any known_as alias a repo declares, and resolve the same way declared edges do; a name nothing resolves is a warning in quarry docs index and the row is skipped. kind is lowercased and, with name, forms the edge key: a row whose kind or name differs from the page's becomes an edge of its own, so rest where the page says http costs you a second edge. last_seen and generated_at are optional; when a route appears twice the later last_seen wins.

Who writes the file is up to you: a gateway log job, a service mesh export, an OpenTelemetry query. quarry only reads it. Commit it to the docs repo like any other page; sync discards untracked files in the clone, and the index rebuilds when the docs repo's HEAD moves.

With the file present, deps and show say which edges traffic backs up:

$ quarry docs deps record-store --downstream
record-store
  http GET /records -> report-builder
  http GET /health -> monitor (observed, undeclared)
  grpc Lookup -> search-api (declared, never observed)
3 repos, depth 1

An edge no page declares is indexed with declared_by: observed and walked like any other. --json adds observed: true|false on every edge and last_seen where traffic carried a date, plus observed_file on the result, so a consumer can tell "never observed" from "no file". quarry docs index reports observed edges: 12 (generated 2026-09-05) while the file exists. A file that does not parse costs one warning; the index still builds.

This is the one way an empty deps result becomes evidence rather than absence. It still cannot see a consumer that was never registered, so the coverage job in templates/quarry-audit.yml compares gh repo list with the folders in the docs repo once a night and prints the repos with no folder.

Contract check

09-interfaces.md carries one ### <Name> section per edge row, under ## Produces for what this repo emits and under ## Consumes for the fields this repo actually reads:

## Produces

| Kind | Name | To |
|---|---|---|
| http | GET /records | [report-builder](../report-builder/09-interfaces.md) |

### GET /records

| Field | Type | Required |
|---|---|---|
| id | string | yes |
| created_at | string | yes |
| content_type | enum | yes |

A row that names a schema instead points at 02-models.md:

## Produces

| Kind | Name | To | Schema |
|---|---|---|---|
| sqs | file-ingest | | `FileIngestMessage` |

quarry check then reads the ### FileIngestMessage section of this repo's 02-models.md and compares against its table, naming the source on the contract line as (fields from 02-models.md § FileIngestMessage) and in --json as model. FileIngestMessage[] names the same section. A chapter or section that is not there is a warning, never a break. A section that lists fields and names a model keeps its table, with a warning that says so.

A consumes row's schema is read the same way, from that repo's own 02-models.md: the DTO a client deserialises into is the set of fields it reads, so a producer dropping one of them is a break like any other. The two ends name their own types, and neither has to know the other's. A consumer model that resolves to nothing keeps the lists no fields note and breaks nothing, and a consumer that also writes an inline table keeps that table.

quarry check reads the working tree's chapter, finds every consumer the quarry knows for each produced contract, and compares the two tables field by field:

$ quarry check
record-store produces http GET /records
  report-builder reads id, created_at, content_type   (2026-09-01)
  break: content_type no longer produced
1 break
The consumer reads a field that Verdict
the producer no longer lists break
changed type break
flipped between required and optional warning

A break exits 1; warnings and notes never do. --json keeps ok: true and puts the list under result.breaks, one object per consumer and field. A producer row with no payload section is a warning ("nothing to compare"); a consumer with no section for the contract is a note. Headings match exactly first, then with a version suffix (### file-ingest (v2) satisfies file-ingest); columns are matched by name; Required reads yes/no, and a table without the column is compared on field and type only; types are compared after trimming and case-folding.

The check reads the clone as last synced, like every other read, so in CI it runs right after quarry init, on pull requests, beside Capstone's map check, and blocks the merge before a consumer ever sees the change. Add --sync to pull first. quarry update runs the same comparison after every import and reports breaks as notes without changing its exit code.

Commands

In a source repo

Command What it does
quarry init [--url] [--docs-dir] [--default-branch] [--name] [--force] Link this repo to a docs repo, write .quarry/, clone it shallowly. --name <target> --docs-dir <dir> registers one monorepo target, one call per target. --force relinks to a different docs repo
quarry add [--strict] Register this repo in the docs repo and import its docs. Running it twice is a no-op. --strict refuses on an unverifiable site or a secret-shaped string
quarry update [--force] [--strict] Copy the docs at HEAD into the docs repo, commit, push. --force imports over a diverged or unreachable stamp; --strict refuses on an unverifiable site or a secret-shaped string
quarry sync Pull the docs repo clone, then rebuild the index
quarry remove Drop this repo's folder, reporting who still declares edges to it
quarry check Compare every produced contract's payload table with the fields each consumer records; exit 1 on a break

Queries

Command What it answers
quarry docs list [<repo>] Every repo with its page and edge counts, or one repo's files. --json adds each repo's known_as list
quarry docs show <repo> Stamps, aliases, both edge directions, publications with unknown consumers, and the repo's overview section. Edge lines carry the same observed marks as deps
quarry docs section <repo> "<heading>" One section by heading. Exact match first, then prefix; an ambiguous heading lists the candidates and exits 1
quarry docs search "<term>" [--repo] [--limit] Full-text hits by repo, file and heading
quarry docs deps <repo> --downstream|--upstream [--depth N] The edge walk. --depth 0 is unlimited; cycles are marked once and not expanded. An edge the name join made is marked (resolved by name). Publications add possible consumers (by name only), which the walk never follows and the closing <N> repos total never counts, so that total can be lower than the number of repo names on screen; with observed-edges.json present, edges are marked (observed, undeclared) or (declared, never observed)
quarry docs path <a> <b> The shortest chain of edges, falling back to the reverse direction
quarry docs index [--force] Rebuild the local index without touching the network, listing every edge target that resolved to nothing and, when observed-edges.json is there, the observed edges: count and its generation date

Every command takes --json and prints exactly one JSON document, including on failure. Add --verbose to see each git command on stderr. --sync pulls the docs repo before a read; --offline answers from the clone even when the config says to pull.

Rules worth knowing

Only commits reachable from the default branch are imported. The docs repo stays a function of what actually shipped, and branch previews live in the source repo where you already have them.

The imported commit is stamped, with the origin and the docs folder it came from. Re-importing the same commit does nothing; an older commit is skipped; a diverged history is refused until --force. On a shallow CI checkout quarry fetches the stamp commit rather than guessing.

Two writers never corrupt the docs repo. A person and a CI job racing on the same repo both end at the newer commit. A rejected push discards the local commit, resets to the remote and redoes the copy, up to three times. That is safe because an import is a pure function of (repo, commit): two machines produce identical bytes.

Queries never touch the network unless told to. The index rebuilds whenever the clone moves; sync pulls, and so does any read given --sync or run in a repo whose config sets sync_on_read. A clone unsynced for a day says so before it answers. docs index never pulls, since rebuilding the local index is its whole job.

A read that pulls still answers when the remote is gone. An unreachable docs repo is a note above the answer, never a failure, so a plane, a tunnel or a revoked token costs you freshness rather than the tool. The note names the git error, and the clone's age is reported beside it.

Declared sites are checked at import. A Site whose path is not in the tree at the imported commit is noted in the output and recorded in the stamp, and deps marks the edge from then on. --strict turns the note into a refusal.

Exit codes: 0 answered or nothing to do, 1 refused or a contract break, 2 something external failed.

The two halves are meant to be run together, and the split between them is the whole design. Capstone reads code with a model and writes each repo's docs in place. quarry copies those pages at one commit, indexes them, and answers — no model, no service, nothing to keep running. Generation and distribution never mix, which is why an import is deterministic enough for two machines to race on it.

What that buys you is one repo reaching for another repo's contract before writing code. Capstone's groom and plan call quarry docs deps and quarry docs section when a feature touches paths covered by 09-interfaces.md — by workspace name in a monorepo, which is the target name here. The constraint lands in the plan as a citation, rather than in code review a week later. Set cross_repo: "off" in capstone.json if you'd rather it didn't.

The other direction is quarry check: Capstone 6.2 writes a payload table under every Produces and Consumes row, and the producer's CI compares its own against each consumer's before the change merges.

Designing something new works the same way. A repo with no origin, no commits and no docs can still run quarry init and read the whole quarry; registration is only needed to contribute. So the architecture and stack interviews can ask what already runs here and get an answer instead of a guess. An internal service that already does the job is a dependency you never take.

Without Capstone, quarry still runs: point it at any docs/ folder that carries 00-index.md and generated_date stamps, and declare edges with the two frontmatter keys above. You will be hand-maintaining the shape Capstone produces for free.


What lands where
<source repo>/.quarry/
  .config              docs repo URL, docs folder, default branch
  .gitignore           ignores the clone and the index
  <docs-repo>/         shallow clone; the commits inside it are quarry's
  .docs-index.sqlite   derived, never committed, rebuilt when the clone moves

Commit .quarry/.config and .quarry/.gitignore; everything else is local and disposable. init writes nothing outside .quarry/.

The docs repo itself is one folder per repo, plus a root 00-index.md regenerated on every write:

docs-quarry/
  00-index.md
  observed-edges.json  optional, written by your traffic exporter (see Observed edges)
  ingest-api/
    .quarry-stamp        the imported commit, origin, docs folder, and any edges whose site path was not in the tree
    00-index.md, 01-architecture.md, …, 09-interfaces.md, logic/
  record-store/
  …

file:line pointers in the copied pages are rewritten into permalinks pinned to the imported commit, so a link stays true after the code moves. GitHub and GitLab shapes are built in; anything else uses the GitHub shape unless .quarry/.config carries a permalink_template with {owner}, {repo}, {sha}, {path} and {line}.

Configuration

.quarry/.config, written by init:

{
  "default_branch": "main",
  "docs_dir": "docs/capstone",
  "permalink_template": null,
  "targets": [{"name": "billing", "docs_dir": "services/billing/docs/capstone"}],
  "sync_on_read": true,
  "url": "git@github.com:acme/docs-quarry.git"
}

targets is absent until init --name writes it. sync_on_read is absent until you set it by hand: true makes every read pull the docs repo first, as if --sync were given, and --offline still overrides it for one call. A stored value survives every later init.

QUARRY_DOCS_REPO, QUARRY_DOCS_DIR and QUARRY_DEFAULT_BRANCH stand in for --url, --docs-dir and --default-branch when there is no config yet, which is what makes a fresh CI runner work. Precedence is flag, then environment, then the file, then what quarry can work out for itself.

default_branch is the branch update imports from, and it is the one setting quarry guesses. It reads origin/HEAD, asks the remote when that is unset, and only then falls back to whichever of main, master, trunk or develop actually has a ref. Pass --default-branch once if your repo uses something else; a stored value survives every later init, including the one your CI runs on every job.

The repo's name in the docs repo is the last path segment of its origin URL and is not configurable; a monorepo target's folder is its target name. Two folders claiming one name are refused, on the strength of the origin and docs folder recorded in the stamp. Other names a repo answers to go in a known_as list in its own pages; they are resolved at index time and never change the folder name.

Monorepos

One repository can hold several documented workspaces. Register each one once:

quarry init --url git@github.com:acme/docs-quarry.git \
  --name billing --docs-dir services/billing/docs/capstone
quarry init --name orders --docs-dir services/orders/docs/capstone

add, update, remove and check then walk every target. Each lands as its own folder in the docs repo, named after the target, with its own stamp; edges between two targets of one repo are ordinary edges. When the root docs_dir holds a 00-index.md (Capstone's index-of-indexes), it is imported too, under the repo's own name, with every link into a target's docs folder rewritten to ../<target>/…. Registering a target rewrites those links on the next run, without waiting for a new source commit. One update is one commit (update billing, orders, acme-app @4f1c9a2); with targets configured, --json add, update and remove return an array with one block per folder they touched, --json check names the producing target on every contract and break row, and --json init lists the registered targets. Capstone names its workspaces the same way, so groom and plan query quarry by target name.

A target name is one path segment, and not 00-index.md or observed-edges.json, which the docs repo root already owns. Its docs folder is validated like the root one, and both are rechecked on every run, so a hand-edited .quarry/.config is refused before anything is written. Two targets may not share a name or a docs folder, and one target's docs folder may not sit inside another's; a target's folder inside the root docs_dir is fine, and the umbrella import skips it.

Rough edges

Retrieval is SQLite FTS5 over the copied markdown. That is quick at a few thousand pages and untested at fifty thousand; the rebuild budget is one marked test, at ten seconds for five thousand pages.

The docs repo's own CI is the nightly audit in templates/quarry-audit.yml; nothing garbage-collects a repo that stops pushing. Its folder simply keeps its last stamp, and quarry docs list shows the date going stale.

Windows is built and tested but thin in the field. macOS and Linux are the ones in daily use.

quarry reads whatever docs/capstone/ holds and does not care which tool wrote it. Everything it assumes about that folder still comes from Capstone: an index page, dated frontmatter, an interfaces chapter. Running it against hand-written docs works, and is more maintenance than it sounds like.


License

Apache-2.0. Free to use, fork and build on, commercially or otherwise. A file you modify carries a notice saying you changed it (§4(b)), and a derivative you distribute reproduces the attribution in NOTICE (§4(d)).

Issues and pull requests welcome; by opening one you license your contribution under the same terms (§5).

About

One face for every repo.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages