devicescan

package
v0.22.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 28, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package devicescan inventories local AI client configuration on a device.

Scan reads known config locations under a home directory (provided as an fs.FS), parses MCP server, skill, and plugin observations, and returns a types.DeviceScan suitable for submission to the Obot backend.

Each client is integrated as a value type implementing ClientScanner in its own file (claudecode.go, codex.go, …). The orchestrator below runs every scanner through a fixed pipeline: globals → glob walk → project hits → plugins → skills → presence → build.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DetectClaudeCodePresence

func DetectClaudeCodePresence(home string) types.DeviceScanClient

func DetectCursorPresence

func DetectCursorPresence(home string) types.DeviceScanClient

func Scan

func Scan(ctx context.Context, fsys fs.FS, homeAbs string, maxDepth int) (types.DeviceScanManifest, error)

Scan runs the full collection pipeline against fsys (rooted at homeAbs) and returns the assembled DeviceScan. Per-phase errors are dropped (logged at debug level) so a missing or malformed config never aborts the rest of the scan. Context cancellation propagates.

Server-assigned envelope fields (ScannerVersion, ScannedAt, DeviceID, Hostname, OS, Arch, Username, ID, ReceivedAt, SubmittedBy) are left zero; the caller fills them in.

maxDepth caps how deep the project walk descends from the home root when looking for project-scope configs and SKILL.md files.

Types

type ClientScanner

type ClientScanner interface {
	// Name is the wire `client` tag this scanner emits.
	Name() string

	// Presence returns the binary/app-bundle/config-dir signals used to
	// decide whether this client is installed on the device, regardless
	// of whether it has any config to scan. The orchestrator emits a
	// clients[] row when any signal fires.
	Presence() clientPresenceDef

	// GlobalConfigPaths returns fs-relative paths the scanner opens during
	// ScanGlobal. The orchestrator uses these to suppress redundant
	// project-walk hits on the same path (e.g. ~/.cursor/mcp.json appears
	// in both the global config list and the project glob).
	GlobalConfigPaths() []string

	// ProjectGlobs returns gobwas/glob patterns that match this client's
	// project-scope config files (e.g. "**/.cursor/mcp.json"). The
	// orchestrator runs a single fs.WalkDir, matches every file against
	// every scanner's globs, and dispatches hits to ScanProject.
	//
	// Empty for clients with no project-scope config.
	ProjectGlobs() []string

	// ScanGlobal opens this client's global config(s) and returns emitted
	// MCP server observations. May call s.addFile to record config files.
	ScanGlobal(s *scanState) []types.DeviceScanMCPServer

	// ScanProject parses one project-scope config file (already known to
	// match one of ProjectGlobs) and returns emitted MCP server
	// observations.
	ScanProject(s *scanState, configRel string) []types.DeviceScanMCPServer
}

ClientScanner is the per-client integration surface. Each AI client (Claude Code, Cursor, etc.) implements this with one struct in its own file. Methods are pure: they read the fs and return observations instead of mutating shared state.

State that genuinely is shared (file table, client table) lives on scanState and is updated via its methods (addFile, addClient).

type PluginScanner

type PluginScanner interface {
	// ScanPlugins returns plugin observations and any nested MCP/skill
	// observations discovered alongside them.
	ScanPlugins(s *scanState) (
		plugins []types.DeviceScanPlugin,
		servers []types.DeviceScanMCPServer,
		skills []types.DeviceScanSkill,
	)
}

PluginScanner is implemented by clients that emit DeviceScanPlugin observations alongside MCP scanning. Returning slices keeps the orchestrator the single point of accumulation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL