Documentation
¶
Overview ¶
Package scanner defines the ecosystem adapter contract and orchestrates project scanning. Adapters keep language quirks out of the core (goal.md §20.4); each publishes only the capabilities it truly has (§13.1).
Index ¶
Constants ¶
const ( PublicnessPublic = "PUBLIC" PublicnessPrivate = "PRIVATE" PublicnessUnknown = "UNKNOWN" )
Publicness of a resolved package. UNKNOWN is treated as private for evidence purposes — the safe default (goal.md §8.1).
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Adapter ¶
type Adapter interface {
// Ecosystem returns the purl ecosystem: "npm" | "pypi" | "golang" | "cargo".
Ecosystem() string
// Capabilities returns honest capability levels, e.g. ["A0","A1","A2"].
Capabilities() []string
// Detect reports whether dir looks like a project of this ecosystem.
Detect(dir string) bool
// ScanPackages returns dependencies with lockfile-resolved versions.
// Publicness is set to PRIVATE for file:/link:/git/workspace/path deps;
// otherwise UNKNOWN (a separate registry check upgrades to PUBLIC).
ScanPackages(ctx context.Context, dir string) ([]ResolvedPackage, error)
// ScanSymbols extracts public-symbol usages for the given packages.
ScanSymbols(ctx context.Context, dir string, pkgs []ResolvedPackage) ([]SymbolUsage, error)
// ClassifyCommand maps an argv to an observation stage.
ClassifyCommand(argv []string) CommandProfile
// EnvironmentHints returns fingerprint hints (JSON field names of
// domain.EnvironmentFingerprint) for environment.Collect.
EnvironmentHints(ctx context.Context, dir string) map[string]string
}
Adapter is implemented once per ecosystem (adapters/node, adapters/python, adapters/goadapter, adapters/rust).
type CommandProfile ¶
type CommandProfile struct {
Stage domain.Stage // PROJECT_TYPECHECK | PROJECT_COMPILE | PROJECT_TEST | PROJECT_PROCESS
Known bool // false ⇒ unclassified, recorded as PROJECT_PROCESS only if Known
Tool string // "tsc", "go", "cargo", ... diagnostic only
}
CommandProfile classifies a command the user ran through csx.
type Edge ¶ added in v0.1.32
Edge is one "this package pulled that one" relationship, as a lockfile records it, with both ends resolved to concrete versions.
Two versions of one library in a tree is the commonest reason a build breaks, and knowing only that there are two is the half of the answer nobody can act on. The other half is which parent wanted which, and only the machine holding the lockfile can say.
type EdgeScanner ¶ added in v0.1.32
EdgeScanner is implemented by adapters whose lockfile records the tree.
Optional on purpose. npm, uv/poetry and Cargo all write the edges into the file the adapter already reads; go.mod records only requirements, and its graph needs `go mod graph` — a command, not a parse. An adapter that cannot answer says so by not implementing this rather than by returning a guess.
type PackageChecker ¶
type PackageChecker interface {
CheckAll(ctx context.Context, pkgs []ResolvedPackage)
}
PackageChecker upgrades UNKNOWN publicness verdicts in place. *registry.Checker satisfies it; the indirection exists because internal/registry imports this package (interface breaks the cycle).
type ResolvedPackage ¶
type ResolvedPackage struct {
PURL domain.PURL
Publicness string // PUBLIC | PRIVATE | UNKNOWN; PRIVATE/UNKNOWN never leave the machine
Direct bool // direct dependency vs transitive
Source string // which file resolved it, local diagnostic only (never uploaded)
}
ResolvedPackage is one dependency with its lockfile-resolved version (goal.md §7.1 — never a manifest range when a lockfile exists).
type ScanResult ¶
type ScanResult struct {
Adapters []Adapter
Packages []ResolvedPackage
Symbols []SymbolUsage
// Edges is the dependency tree, when the adapter's lockfile records one.
// Empty is not "no dependencies": it is "this ecosystem's lockfile does
// not say", which is the case for go.mod.
Edges []Edge
Env domain.EnvironmentFingerprint
// TargetContext is a best-effort TARGET execution-context hint detected
// from project clues (bun.lock/bun.lockb → "bun", deno.json(c) → "deno",
// an "electron" dependency → "electron"). Per docs/execution-context.md
// it is used only to widen search environments; it is deliberately NOT
// part of Env — build/test observations stay in the toolchain context
// they actually executed in.
TargetContext string
}
ScanResult is everything one project scan produced (contract C14 step 1).
func Scan ¶
func Scan(ctx context.Context, dir string, ads []Adapter, checker PackageChecker) (*ScanResult, error)
Scan orchestrates one project scan: per-adapter package scanning (lockfile-resolved), a publicness upgrade pass, per-adapter symbol extraction, and environment collection from merged adapter hints (first adapter wins per key). ads is the detected adapter set — callers obtain it via adapters.Detect(dir). A nil checker skips the publicness pass, so packages stay UNKNOWN (= excluded from evidence, the safe default). Adapter errors are non-fatal: scanning is best-effort and must never break the wrapped command.
func (*ScanResult) Classify ¶
func (r *ScanResult) Classify(argv []string) CommandProfile
Classify maps argv to an observation stage by asking each detected adapter in order; the first confident classification wins. Commands no adapter knows come back with Known=false and are recorded as USED only.
type SymbolUsage ¶
type SymbolUsage struct {
Package domain.PURL
Family string // e.g. "axios.post", "serde::Deserialize", "github.com/x/y.Func"
Kind string // function | class | method | property | module
Confidence domain.SymbolConfidence
}
SymbolUsage is one observed public-symbol use in the local project.