Documentation
¶
Overview ¶
Package inventory defines the producer pipeline for endpoint inventory scans. The Item type is a domain-level mirror of the proto VetInventoryEvent.ItemObserved sub-message; proto translation lives outside this package (in CloudSink).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AgentDetail ¶
type AgentDetail struct {
// Version is the agent's reported version, when available.
Version string
// PermissionMode is the agent's configured permission mode.
PermissionMode string
// InstructionFiles is the set of instruction files driving the agent.
InstructionFiles []string
// Model is the configured LLM model identifier.
Model string
// APIKeyEnvName is the env var name (not value) holding the API key.
APIKeyEnvName string
}
AgentDetail mirrors proto VetInventoryEvent.AgentDetail. Populated only when Kind == KindCodingAgent.
type EmitFunc ¶
EmitFunc is the per-item callback supplied to Scanner.Scan. Returning a non-nil error tells the scanner to stop enumeration and return that error to the orchestrator.
type Item ¶
type Item struct {
// Kind classifies the item.
Kind Kind
// ItemIdentity is the deterministic dedup key (FNV-64a of
// app/kind/scope/name/config_path); computed by the scanner adapter.
ItemIdentity string
// SourceID groups items emitted from the same source (app + config file).
SourceID string
// Name is the human-readable label for the item.
Name string
// App is the application that owns / configures this item.
App string
// Scope is system-wide vs project-local.
Scope Scope
// ConfigPath is the absolute path to the config file the item was found in.
ConfigPath string
// Enabled is the optional enabled flag; nil means unknown.
Enabled *bool
// MCPServer carries MCP-server-specific details when Kind == KindMCPServer.
MCPServer *MCPServerDetail
// Agent carries coding-agent-specific details when Kind == KindCodingAgent.
Agent *AgentDetail
// Metadata holds free-form, kind-specific attributes for kinds without a
// typed sub-message (CLI tools, AI extensions, etc.).
Metadata map[string]string
}
Item is the in-process representation of a single discovered inventory item. Field-for-field equivalent to proto VetInventoryEvent.ItemObserved using Go-idiomatic naming. Pointer fields preserve the proto's optional semantics.
type Kind ¶
type Kind int
Kind classifies the subject of an ItemObserved event. Values mirror the proto InventoryItemKind enum.
const ( // KindUnspecified is the zero value; not a valid kind. KindUnspecified Kind = 0 // KindMCPServer is a discovered MCP server config entry. KindMCPServer Kind = 1 // KindCodingAgent is a discovered AI coding agent. KindCodingAgent Kind = 2 // KindAIExtension is a discovered AI editor / IDE extension. KindAIExtension Kind = 3 // KindCLITool is a discovered CLI tool binary. KindCLITool Kind = 4 // KindProjectConfig is a discovered project-level config file. KindProjectConfig Kind = 5 // KindBrowserExtension is a discovered browser extension. KindBrowserExtension Kind = 6 // KindIDEExtension is a discovered (non-AI) IDE extension. KindIDEExtension Kind = 7 // KindAgentPlugin is a discovered coding-agent plugin. KindAgentPlugin Kind = 8 // KindAgentSkill is a discovered coding-agent skill. KindAgentSkill Kind = 9 )
type MCPServerDetail ¶
type MCPServerDetail struct {
// Transport is the MCP transport classification.
Transport Transport
// Command is the binary executed for stdio transports.
Command string
// Args is the command-line arguments for stdio transports.
Args []string
// URL is the endpoint for HTTP-based transports.
URL string
// EnvVarNames is the names (not values) of env vars referenced.
EnvVarNames []string
// HeaderNames is the names (not values) of HTTP headers referenced.
HeaderNames []string
// AllowedTools is the explicit tool allowlist if configured.
AllowedTools []string
// AllowedResources is the explicit resource allowlist if configured.
AllowedResources []string
}
MCPServerDetail mirrors proto VetInventoryEvent.MCPServerDetail. Populated only when Kind == KindMCPServer.
type Orchestrator ¶
type Orchestrator struct {
// contains filtered or unexported fields
}
Orchestrator wires Scanners and Sinks into a single-goroutine producer pipeline.
The orchestrator is not safe for concurrent Run calls; instantiate one per scan.
func New ¶
func New(scanners []Scanner, sinks []Sink) *Orchestrator
New constructs an Orchestrator over a fixed scanner and sink registration order. Both slices may be nil or empty; the orchestrator's lifecycle still completes correctly (sinks see Begin/End/Close with an empty summary).
func (*Orchestrator) Run ¶
func (o *Orchestrator) Run(ctx context.Context, cfg ScanConfig) error
Run executes one full scan: Begin on every sink, scanners in registration order with items fanned to all sinks, then End and Close on every sink.
Errors in scanners and in Sink.Emit are captured into the ScanSummary; the scan continues. Begin failure aborts the Run after closing the sinks that were already begun successfully. End and Close errors are logged; the last non-nil one is returned so a real bug can surface as a non-zero exit at the cmd layer.
type ScanConfig ¶
type ScanConfig struct {
// HomeDir overrides the user home directory; empty string means
// "use the OS-detected home".
HomeDir string
// ProjectDir is the project root for project-scoped discovery; empty
// string means project-scoped discovery is skipped.
ProjectDir string
// Scopes is the allowlist of scopes a scanner should enumerate.
// A nil slice means "all scopes enabled" (mirrors aitool.DiscoveryConfig
// semantics). An empty (non-nil) slice means "no scopes enabled".
Scopes []Scope
}
ScanConfig carries the inputs every scanner needs to run a discovery pass. It is read-only; orchestrators copy it by value into each scanner.
func (ScanConfig) ScopeEnabled ¶
func (c ScanConfig) ScopeEnabled(scope Scope) bool
ScopeEnabled reports whether the given scope is permitted by this config. When Scopes is nil, every scope is enabled.
type ScanError ¶
type ScanError struct {
// ScannerName is the Scanner.Name() of the active scanner. Sink.Emit
// failures are attributed here too, matching the proto's discoverer
// field semantics.
ScannerName string
// ErrorType is a coarse classifier (e.g. "scanner_failed",
// "sink_emit_failed"). Optional; empty when not classified.
ErrorType string
// Message is the human-readable failure description.
Message string
}
ScanError describes a discoverer-level failure recorded during a scan. Field set mirrors proto VetInventoryEvent.ScanError, with ScannerName substituted for the proto's Discoverer field.
type ScanSummary ¶
type ScanSummary struct {
// TotalObserved is the number of items emitted across all scanners.
TotalObserved uint64
// KindCounts is the per-Kind tally of emitted items.
KindCounts map[Kind]uint64
// Errors are the discoverer-level failures collected during the scan;
// the scan continues past each error.
Errors []ScanError
}
ScanSummary aggregates the result of a scan. Built by the orchestrator and passed to Sink.End. The orchestrator owns its lifecycle; sinks must treat the value as read-only.
type Scanner ¶
type Scanner interface {
// Name is a stable, log-safe identifier (e.g. "aitool", "browser_ext").
Name() string
// Scan walks the configured sources and invokes emit for each item.
// Scan returns nil on success, the emit-callback's error if it
// requested early termination, or a discoverer-level failure.
Scan(ctx context.Context, cfg ScanConfig, emit EmitFunc) error
}
Scanner enumerates items of one or more inventory kinds from the local endpoint. Implementations are stateless with respect to the orchestrator; any caching is the implementation's concern.
type Scope ¶
type Scope int
Scope captures whether an item is system-wide or project-local. Values mirror the proto InventoryScope enum.
type Session ¶
type Session struct {
// InvocationID is a UUID identifying this scan run. Equal across all
// events emitted by the same Run; distinct between Runs.
InvocationID string
// StartedAt is the wall-clock time the session was created.
StartedAt time.Time
}
Session is created once per Orchestrator.Run and propagates the scan's invocation identity through every sink.
func NewSession ¶
func NewSession() *Session
NewSession constructs a Session with a freshly generated UUID invocation_id and a now() timestamp.
type Sink ¶
type Sink interface {
// Begin announces a new scan. Returning an error aborts the Run.
Begin(ctx context.Context, session *Session) error
// Emit consumes one observed item. The orchestrator does not retry; an
// error is captured into the ScanSummary and the next sink is called.
Emit(ctx context.Context, item *Item) error
// End delivers the aggregated summary at end-of-scan.
End(ctx context.Context, summary *ScanSummary) error
// Close releases resources held by the sink.
Close(ctx context.Context) error
}
Sink consumes the producer pipeline. Sinks are NOT required to be thread-safe: the orchestrator drives them serially.
Lifecycle, exactly once per Orchestrator.Run:
Begin -> Emit* -> End -> Close
Begin failure aborts the Run. Emit failure does not: the orchestrator records the error in ScanSummary.Errors and continues with the remaining sinks and scanners. End and Close errors are logged; only the last non-nil error from End/Close propagates out of Run, so a real bug surfaces as a non-zero exit.
type Transport ¶
type Transport int
Transport classifies an MCP server's wire protocol. Mirrors the proto VetInventoryEvent.MCPServerDetail.Transport enum.
const ( // TransportUnspecified is the zero value; not a valid transport. TransportUnspecified Transport = 0 // TransportStdio uses standard input/output to a local process. TransportStdio Transport = 1 // TransportSSE uses HTTP Server-Sent Events. TransportSSE Transport = 2 // TransportStreamableHTTP uses the streamable-HTTP MCP transport. TransportStreamableHTTP Transport = 3 )
Directories
¶
| Path | Synopsis |
|---|---|
|
Package scanners is the single source of truth for inventory.Scanner factories.
|
Package scanners is the single source of truth for inventory.Scanner factories. |
|
aitool
Package aitool adapts the aitool discovery layer to the inventory producer pipeline.
|
Package aitool adapts the aitool discovery layer to the inventory producer pipeline. |
|
skills
Package skills is an inventory.Scanner that discovers agent skill directories from all supported AI coding agents.
|
Package skills is an inventory.Scanner that discovers agent skill directories from all supported AI coding agents. |
|
sinks
|
|
|
cloud
Package cloud implements an inventory.Sink that ships discovered items, the end-of-scan summary, and per-discoverer errors to SafeDep Cloud via the endpointsync WAL.
|
Package cloud implements an inventory.Sink that ships discovered items, the end-of-scan summary, and per-discoverer errors to SafeDep Cloud via the endpointsync WAL. |
|
local
Package local implements an in-process inventory.Sink that accumulates emitted items, renders the same end-of-scan summary table vet's `ai discover` command produces today, and optionally writes the raw item list as JSON to disk.
|
Package local implements an in-process inventory.Sink that accumulates emitted items, renders the same end-of-scan summary table vet's `ai discover` command produces today, and optionally writes the raw item list as JSON to disk. |