collect
collect(
root,options?):Promise<Catalog>
@sksizer/detect-runners — find the task runners a directory uses, and
normalize their tasks into one searchable model.
The problem it solves: a repository of any size runs its work through several tools at once — a build graph, a justfile, package.json scripts, a Makefile — and each answers only for itself. “How do I start that app?” then requires knowing which tool owns it before you can even look. This inverts that: one inventory, keyed by the call chain you would actually type.
import { collect, tasks } from "@sksizer/detect-runners";
const catalog = await collect(process.cwd(), { allowExec: true });for (const task of tasks(catalog)) console.log(task.display);Three things worth knowing before using it:
Execution is opt-in. allowExec defaults to false. Some runners can
only be read by asking them — moon query tasks runs the repo’s toolchain
configuration — so pointing this at a repository you did not write is code
execution. Providers declare kind: "parse" | "exec", and only parse ones
run by default.
The CLIs add a second gate on top of that one: per-repository TRUST, kept in
the XDG state directory and granted by waypost trust, plus a USER-layer
trust.paths/trust.owners policy in the config file. The library gates on
allowExec and nothing else — a programmatic caller’s answer must not depend
on a store it never asked about — while a CLI, which knows it is acting for a
person, resolves both through @sksizer/sdlc-tool’s policyExecGate before
calling collect. A repository cannot trust itself: allowExec: true and a
trust block are both ignored in waypost.config.json, because a file
inside the scanned repository authorizing the execution of that
repository’s code is no gate at all.
Collection is a function, not a snapshot. Every collect() call
re-probes and holds nothing across calls, so a catalog cannot silently go
stale after someone adds a task. Storing an answer is available as a separate
opt-in layer — readCachedCatalog paints what was last measured with a
per-runner fresh/stale/miss verdict, collectAndCache probes and stores —
for surfaces that would rather show a dated answer instantly than an empty
screen for four seconds. A caller that does not reach for it gets a fresh
probe, always.
argv and display are different strings. argv is executable and
carries no placeholders; display is for showing and copying and may contain
<required> / [optional] / *variadic markers. Never spawn display, and
never build a command by joining it.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
root | string |
options | CollectOptions |
Returns
Section titled “Returns”Promise<Catalog>