internal

package
v1.7.3 Latest Latest
Warning

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

Go to latest
Published: Jun 11, 2026 License: MIT Imports: 38 Imported by: 0

Documentation

Overview

SPDX-License-Identifier: MIT Purpose: adw — Architectural Debt Watchdogs. Detects god modules, circular dependencies, high coupling, long functions, large files, and code smells. Pure Go implementation.

SPDX-License-Identifier: MIT Purpose: agent-show and agent-doctor CLI commands.

SPDX-License-Identifier: MIT Purpose: agent-edit, agent-set, agent-reset CLI commands.

SPDX-License-Identifier: MIT Purpose: shared helpers for the agent edit/set/reset/show/doctor CLI.

SPDX-License-Identifier: MIT Purpose: ast_go — exact Go outlines via go/parser + go/ast (stdlib, zero dependencies, always on). Replaces every Go regex heuristic: real start/end lines from the token.FileSet, methods named "Receiver.Name", struct fields and interface methods as children, full import list. Docs: cmd/sin-code/internal/ast.doc.md

SPDX-License-Identifier: MIT Purpose: ast_provider — language-aware structure extraction behind a single interface. Three tiers, best available wins: exact go/ast for Go (stdlib, always on), tree-sitter for Python/JS/TS/Rust/Java when built with -tags treesitter (CGO, opt-in — default build stays zero-dependency), and a pure-Go structural engine (brace/indent tracking with real end lines) as the universal fallback. Consumers: read --mode outline, edit --symbol, grasp, and (later) map/SCKG. Docs: cmd/sin-code/internal/ast.doc.md

SPDX-License-Identifier: MIT Purpose: ast_structural — pure-Go structural outlines for non-Go languages (always on; upgraded transparently by tree-sitter when built with -tags treesitter). Unlike the legacy single-line regex heuristics this engine computes REAL end lines: brace-depth tracking (string/comment aware) for C-family languages, indentation tracking for Python. That is what makes AST-anchored symbol edits safe without CGO. Docs: cmd/sin-code/internal/ast.doc.md

SPDX-License-Identifier: MIT Purpose: Build-tag stub: without -tags treesitter the structural engine (ast_structural.go) handles all non-Go languages and the bundle stays zero-dependency. This file only documents the seam. Docs: cmd/sin-code/internal/ast.doc.md

SPDX-License-Identifier: MIT Purpose: Shared utilities for the sin-code unified binary (error printing, shared flags, output formatting). All subcommands import this package.

SPDX-License-Identifier: MIT Purpose: config — view and manage sin-code configuration files. Supports reading, setting, and listing configuration values. Docs: config.doc.md

SPDX-License-Identifier: MIT Purpose: discover — file discovery with relevance scoring, pattern matching, and dependency analysis. Built-in Go implementation (no external binary dependency).

SPDX-License-Identifier: MIT Purpose: edit — hashline-anchored surgical file editing. Replaces fragile native string/line editors: anchors carry a content hash so stale edits fail loudly instead of corrupting files, drift up to ±25 lines is auto-resolved, occurrence counting prevents ambiguous string replaces, and every edit re-runs the atomic write path with syntax validation. Docs: cmd/sin-code/internal/edit.doc.md

SPDX-License-Identifier: MIT Purpose: efm — Ephemeral Full-Stack Mocking. Manages docker-compose stacks and ephemeral test environments. Pure Go implementation.

SPDX-License-Identifier: MIT Purpose: execute — safe shell command execution with safety checks, secret redaction, timeout handling, and error analysis. Built-in Go implementation.

SPDX-License-Identifier: MIT Purpose: grasp — deep code understanding for a single file. Built-in Go implementation providing structure, dependencies, and usage context.

SPDX-License-Identifier: MIT Purpose: harvest — URL fetching with caching, structure extraction, and change detection. Built-in Go implementation using net/http with local disk cache.

SPDX-License-Identifier: MIT Purpose: hashline — content-hash anchored line addressing shared by read and edit. An anchor "12:ab34cd56" means "line 12, whose content hashes to ab34cd56". Edits validate anchors against current content and tolerate small drift, eliminating the stale-line-number failure mode of classic line-based editors. Docs: cmd/sin-code/internal/hashline.doc.md

SPDX-License-Identifier: MIT Purpose: ibd — Intent-Based Diffing. Compare two versions of code and determine if the changes match the stated intent. Pure Go implementation.

SPDX-License-Identifier: MIT Purpose: sin-code lsp CLI — wrapper around Language Server Protocol (gopls, pyright, tsserver) for IDE-grade code intelligence.

SPDX-License-Identifier: MIT Purpose: map — architecture mapping with dependency graphs, entry points, hot paths, and module-level analysis. Built-in Go implementation.

SPDX-License-Identifier: MIT Purpose: sin-code memory CLI — long-term project knowledge.

SPDX-License-Identifier: MIT Purpose: oracle — Verification Oracle. Compares source files against test files to verify coverage. Pure Go implementation.

SPDX-License-Identifier: MIT Purpose: orchestrate — task management with dependencies, parallel execution plans, blocker detection, and rollback plans. Built-in Go implementation with JSON file storage in ~/.local/state/sin-code/.

SPDX-License-Identifier: MIT Purpose: sin-code orchestrate — multi-agent orchestrator CLI (v2). SOTA June 2026: Pre-LLM router + planner + parallel specialized agents with per-agent model + system prompt. Backed by the orchestrator package.

SPDX-License-Identifier: MIT Purpose: sin-code plugin CLI — install/list/info/enable/disable.

SPDX-License-Identifier: MIT Purpose: poc — Proof-of-Correctness. Verifies that code satisfies its specification by comparing code against spec documents (markdown, text, or structured requirements). Pure Go implementation.

SPDX-License-Identifier: MIT Purpose: read — token-efficient, anchor-aware file reading. Replaces naive native read/cat for agents: hashline mode emits stable edit anchors, outline mode emits structure instead of raw content (80–95% token savings on large files), and hard byte/line guards prevent context blowouts. Docs: cmd/sin-code/internal/read.doc.md

SPDX-License-Identifier: MIT Purpose: sbom — generate SPDX or CycloneDX JSON SBOMs for Go, Python, Node, and generic projects. Docs: cmd/sin-code/internal/sbom.go.doc.md

SPDX-License-Identifier: MIT Purpose: sckg — Semantic Codebase Knowledge Graphs. Builds a knowledge graph of a codebase: files, functions, imports, and their relationships. Pure Go implementation.

SPDX-License-Identifier: MIT Purpose: scout — parallel code search with regex, semantic, symbol, usage. Uses ripgrep (rg) as a fast bridge when available; falls back to a parallel Go worker pool with gitignore-aware walking. Binary files are auto-skipped. Docs: cmd/sin-code/internal/scout.doc.md

SPDX-License-Identifier: MIT Purpose: security — fast security analysis for Go, Python, Node, and generic projects. Auto-detects project type, finds available security tools, and runs a targeted scan. Docs: security.doc.md

SPDX-License-Identifier: MIT Purpose: self-update — check for and install new sin-code releases from GitHub. Auto-detects platform, downloads the correct binary, and replaces the current one. Docs: self-update.doc.md

SPDX-License-Identifier: MIT Purpose: serve — start an MCP (Model Context Protocol) server that exposes all 13 sin-code subcommands as MCP tools. This replaces the 7 separate MCP server registrations in opencode.json with a single one.

SPDX-License-Identifier: MIT Purpose: MCP tool handlers for the v2.0+ subcommands (todo, memory, notifications, orchestrator-*, agent-*, lsp). Each handler dispatches to the corresponding cobra subcommand and returns stdout.

SPDX-License-Identifier: MIT Purpose: MCP handlers for sin_read, sin_write, sin_edit. Call the internal readFile/writeFileAtomic/applyEdit functions directly (no subprocess), making the edit loop hot path as fast as possible. Docs: cmd/sin-code/internal/serve_rw_handlers.doc.md

SPDX-License-Identifier: MIT Purpose: write — atomic, validated file writing. Replaces naive native write: temp-file + fsync + rename (never a half-written file), syntax pre-validation before anything touches disk (Go via go/parser, JSON via encoding/json, bracket-balance heuristic elsewhere), and optional backup. Docs: cmd/sin-code/internal/write.doc.md

Index

Constants

View Source
const DefaultDriftWindow = 25
View Source
const HashLineLen = 8

Variables

View Source
var AdwCmd = &cobra.Command{
	Use:   "adw",
	Short: "Architectural Debt Watchdogs — detect god modules, circular deps, etc.",
	Long: `Detect and report architectural debt in a codebase. Pure Go implementation.

Detects:
  - God modules (files with >15 imports or >500 lines)
  - Circular dependencies (import cycles)
  - High coupling (files imported by >10 others)
  - Long functions (>100 lines)
  - Large files (>500 lines)
  - TODO/FIXME comments
  - Missing tests (source files without corresponding test files)

Examples:
  sin-code adw .
  sin-code adw ./src --strict
  sin-code adw . --format json`,
	Args: cobra.ArbitraryArgs,
	RunE: func(cmd *cobra.Command, args []string) error {
		path := "."
		if len(args) > 0 {
			path = args[0]
		}
		absPath, err := filepath.Abs(path)
		if err != nil {
			return fmt.Errorf("invalid path: %w", err)
		}
		if info, err := os.Stat(absPath); err != nil || !info.IsDir() {
			if err != nil {
				return fmt.Errorf("path not found: %w", err)
			}
			return fmt.Errorf("path is not a directory: %s", absPath)
		}

		result := scanDebt(absPath, adwStrict)

		if adwFormat == "json" {
			enc := json.NewEncoder(os.Stdout)
			enc.SetIndent("", "  ")
			return enc.Encode(result)
		}
		return outputTextADW(result)
	},
}
View Source
var ConfigCmd = &cobra.Command{
	Use:   "config",
	Short: "View and manage sin-code configuration",
	Long: `Manage sin-code configuration files and settings.

Configuration files:
  ~/.config/sin/sin-code.toml    Main configuration (theme, defaults)
  ~/.config/sin/tui.toml         TUI preferences (theme, keybindings)

Subcommands:
  config get <key>          Get a configuration value
  config set <key> <value>  Set a configuration value
  config list               List all configuration values
  config path               Show configuration directory path
  config init               Create default configuration files`,
}
View Source
var DiscoverCmd = &cobra.Command{
	Use:   "discover [path]",
	Short: "Discover files with relevance scoring and pattern matching",
	Long: `Discover files in a directory with relevance scoring, pattern matching,
and dependency analysis. Pure Go implementation — no external binary needed.

Example:
  sin-code discover . --pattern "**/*.go" --sort_by relevance --format json`,
	Args: cobra.ArbitraryArgs,
	RunE: func(cmd *cobra.Command, args []string) error {
		path := "."
		if len(args) > 0 {
			path = args[0]
		}
		absPath, err := filepath.Abs(path)
		if err != nil {
			return fmt.Errorf("invalid path: %w", err)
		}
		if info, err := os.Stat(absPath); err != nil || !info.IsDir() {
			if err != nil {
				return fmt.Errorf("path not found: %w", err)
			}
			return fmt.Errorf("path is not a directory: %s", absPath)
		}

		results, err := discoverFiles(absPath, discoverPattern, discoverLimit)
		if err != nil {
			return err
		}

		sortResults(results, discoverSort)
		if len(results) > discoverLimit {
			results = results[:discoverLimit]
		}

		if discoverFormat == "json" {
			return outputJSON(results)
		}
		return outputText(results)
	},
}
View Source
var EditCmd = &cobra.Command{
	Use:   "edit [path]",
	Short: "Hashline-anchored surgical edits with validation",
	Long: `Surgical file editing with two addressing modes:

Anchor mode (preferred — anchors come from 'sin-code read'):
  --anchor 12:ab34cd56 --new-text "replacement"        replace one line
  --anchor 12:ab34cd56 --end-anchor 20:ef99aa01 ...    replace a line range
  --anchor 12:ab34cd56 --insert after --new-text "..." insert after a line
  --anchor 12:ab34cd56 --delete                        delete line (or range)

String mode (exact match, fails on ambiguity):
  --old-string "foo(a, b)" --new-string "foo(a, b, c)"
  --old-string "x" --new-string "y" --replace-all

Every edit validates syntax (like 'sin-code write') and applies atomically.
--dry-run prints a unified diff without touching the file.`,
	Args: cobra.ExactArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		absPath, err := filepath.Abs(args[0])
		if err != nil {
			return fmt.Errorf("invalid path: %w", err)
		}
		req := editRequest{
			Anchor: editAnchor, EndAnchor: editEndAnchor, NewText: editNewText,
			OldString: editOldString, NewString: editNewString,
			ReplaceAll: editReplaceAll, Insert: editInsert, Delete: editDelete,
			DryRun: editDryRun, Validate: !editNoValidate, Drift: editDrift,
			Symbol: editSymbol,
		}
		result, err := applyEdit(absPath, req)
		if err != nil {
			return err
		}
		if editFormat == "json" {
			enc := json.NewEncoder(os.Stdout)
			enc.SetIndent("", "  ")
			return enc.Encode(result)
		}
		if result.DryRun {
			fmt.Print(result.Diff)
			return nil
		}
		fmt.Printf("edited %s: %s (%+d lines)\n", result.Path, result.Operation, result.LineDelta)
		if result.Diff != "" {
			fmt.Print(result.Diff)
		}
		return nil
	},
}
View Source
var EfmCmd = &cobra.Command{
	Use:   "efm",
	Short: "Ephemeral Full-Stack Mocking — spin up disposable test environments",
	Long: `Manage disposable full-stack environments (Docker Compose, ephemeral containers).
Pure Go implementation.

Container runtime:
  On macOS, OrbStack ('orb') is preferred and used automatically when available,
  with 'docker' as the fallback. On Linux, 'docker' is used directly.
  The runtime is fully Docker CLI-compatible, so the same compose commands work.

  Use --runtime to override the auto-detected value:
    --runtime auto    auto-detect (default)
    --runtime orb     force OrbStack
    --runtime docker  force Docker (incl. legacy docker-compose fallback)

Examples:
  sin-code efm --action list
  sin-code efm --action up --stack docker-compose.yml --ttl 3600
  sin-code efm --action down --stack docker-compose.yml
  sin-code efm --action status
  sin-code efm --action list --runtime orb`,
	RunE: func(cmd *cobra.Command, args []string) error {
		return runEFM(efmAction, efmStack, efmTTL, efmFormat, efmRuntime)
	},
}
View Source
var ExecuteCmd = &cobra.Command{
	Use:   "execute",
	Short: "Execute shell commands safely with secret redaction and timeout",
	Long: `Execute shell commands with safety checks, secret redaction, timeout
handling, and error analysis. Pure Go implementation — no external binary needed.

Example:
  sin-code execute --command "ls -la" --timeout 10 --format json`,
	RunE: func(cmd *cobra.Command, args []string) error {
		if execCommand == "" {
			return fmt.Errorf("--command is required")
		}
		if err := checkSafety(execCommand); err != nil {
			return err
		}
		return runCommand(execCommand, execTimeout, execFormat, execStream)
	},
}
View Source
var GraspCmd = &cobra.Command{
	Use:   "grasp [path]",
	Short: "Deep code understanding for a single file",
	Long: `Deep code understanding for individual files — structure, dependencies,
usage, and related context. Pure Go implementation.

Example:
  sin-code grasp cmd/sin-code/main.go --format json`,
	Args: cobra.ExactArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		absPath, err := filepath.Abs(args[0])
		if err != nil {
			return fmt.Errorf("invalid path: %w", err)
		}
		info, err := os.Stat(absPath)
		if err != nil {
			return fmt.Errorf("file not found: %w", err)
		}
		if info.IsDir() {
			return fmt.Errorf("path is a directory, not a file: %s", absPath)
		}

		result, err := analyzeFile(absPath, info)
		if err != nil {
			return err
		}

		if graspFormat == "json" {
			enc := json.NewEncoder(os.Stdout)
			enc.SetIndent("", "  ")
			return enc.Encode(result)
		}
		return outputTextGrasp(result)
	},
}
View Source
var HarvestCmd = &cobra.Command{
	Use:   "harvest",
	Short: "Fetch URLs with caching, structure extraction, and change detection",
	Long: `Fetch URLs with caching, structure extraction, change detection, and
auth management. Pure Go implementation with local disk cache.

Example:
  sin-code harvest --url https://api.example.com/data --format json`,
	RunE: func(cmd *cobra.Command, args []string) error {
		if harvestURL == "" {
			return fmt.Errorf("--url is required")
		}
		return harvestURLFetch(harvestURL, harvestMethod, harvestTimeout, harvestFormat)
	},
}
View Source
var IbdCmd = &cobra.Command{
	Use:   "ibd",
	Short: "Intent-Based Diffing — compare code changes against stated intent",
	Long: `Compare two versions of code and determine if the changes match the
stated intent. Pure Go implementation.

Examples:
  sin-code ibd --before old.py --after new.py --intent "add retry logic"
  sin-code ibd --before v1.0 --after HEAD --intent "refactor authentication"
  sin-code ibd file.go --from main --to feature-branch --intent "add error handling"`,
	RunE: func(cmd *cobra.Command, args []string) error {
		var beforePath, afterPath string

		if ibdBefore != "" && ibdAfter != "" {
			beforePath = ibdBefore
			afterPath = ibdAfter
		} else if len(args) > 0 {
			beforePath = args[0]

			if ibdFrom != "" && ibdTo != "" {

				fmt.Fprintf(os.Stderr, "Note: Git diff (--from/--to) requires manual diff extraction. Reading file as-is.\n")
			}
		} else {
			return fmt.Errorf("either --before/--after or a target path is required")
		}

		result, err := diffWithIntent(beforePath, afterPath, ibdIntent)
		if err != nil {
			return err
		}

		if ibdFormat == "json" {
			enc := json.NewEncoder(os.Stdout)
			enc.SetIndent("", "  ")
			return enc.Encode(result)
		}
		return outputTextIBD(result)
	},
}
View Source
var LSPCmd = &cobra.Command{
	Use:   "lsp",
	Short: "LSP (Language Server Protocol) — IDE-grade code intelligence",
	Long: `Language Server Protocol wrapper for sin-code. Provides go-to-definition,
find-references, hover, rename, document symbols, formatting, and diagnostics
without launching an IDE. Spawns gopls/pyright/typescript-language-server
on demand and caches them per-language.

Examples:
  sin-code lsp servers                    # list detected LSPs
  sin-code lsp definition main.go 5 9     # go-to-def at line 5, col 9
  sin-code lsp references main.go 5 9    # find all references
  sin-code lsp hover main.go 5 9         # type/doc on hover
  sin-code lsp rename main.go 5 9 MyFunc # rename symbol
  sin-code lsp symbols main.go            # outline
  sin-code lsp format main.go             # format file
  sin-code lsp diagnostics main.go        # all errors/warnings`,
	SilenceUsage: true,
}
View Source
var MapCmd = &cobra.Command{
	Use:   "map [path]",
	Short: "Map code architecture with dependency graphs and hot-path analysis",
	Long: `Map code architecture with dependency graphs, entry points, hot paths,
and module-level analysis. Pure Go implementation.

Example:
  sin-code map . --action map --format json`,
	Args: cobra.ArbitraryArgs,
	RunE: func(cmd *cobra.Command, args []string) error {
		path := "."
		if len(args) > 0 {
			path = args[0]
		}
		absPath, err := filepath.Abs(path)
		if err != nil {
			return fmt.Errorf("invalid path: %w", err)
		}
		info, err := os.Stat(absPath)
		if err != nil {
			return fmt.Errorf("path not found: %w", err)
		}
		if !info.IsDir() {
			return fmt.Errorf("path is not a directory: %s", absPath)
		}

		result, err := mapArchitecture(absPath, mapAction)
		if err != nil {
			return err
		}

		if mapFormat == "json" {
			enc := json.NewEncoder(os.Stdout)
			enc.SetIndent("", "  ")
			return enc.Encode(result)
		}
		return outputTextMap(result)
	},
}
View Source
var MemoryCmd = &cobra.Command{
	Use:   "memory",
	Short: "Long-term project memory with semantic search",
	Long: `Memory is a bd-style project knowledge store backed by bbolt.

  add <insight>            Add a memory
  list                      List memories (filter by --project, --tag, --actor)
  search <query>            Semantic search (uses NIM embeddings if SIN_NIM_API_KEY is set)
  link <from> <to> --rel    Add a knowledge-graph link
  unlink <from> <to>        Remove a link
  graph <id>                Show knowledge-graph neighborhood
  prime <query>             Print top-K relevant memories for an LLM prompt
  forget <id>               Soft-delete (--hard for permanent)
  show <id>                 Show one memory
  stats                     Memory statistics

Storage: ~/.config/sin-code/memory.db (override with --db).
Embeddings: NIM nv-embed-v1 (set SIN_NIM_API_KEY).`,
	SilenceUsage: true,
}
View Source
var OracleCmd = &cobra.Command{
	Use:   "oracle",
	Short: "Verification Oracle — verify claims with evidence",
	Long: `Verify that source code has corresponding test coverage.
Compares functions/methods in a source file with test cases in a test file.

Examples:
  sin-code oracle --claim src/main.py --evidence tests/test_main.py
  sin-code oracle --claim cmd/sin-code/main.go --evidence cmd/sin-code/main_test.go`,
	RunE: func(cmd *cobra.Command, args []string) error {
		if oracleClaim == "" {
			return fmt.Errorf("--claim (source file) is required")
		}
		if oracleEvidence == "" {
			return fmt.Errorf("--evidence (test file) is required")
		}

		result, err := verifyCoverage(oracleClaim, oracleEvidence)
		if err != nil {
			return err
		}

		if oracleFormat == "json" {
			enc := json.NewEncoder(os.Stdout)
			enc.SetIndent("", "  ")
			return enc.Encode(result)
		}
		return outputTextOracle(result)
	},
}
View Source
var OrchestrateCmd = &cobra.Command{
	Use:   "orchestrate",
	Short: "Legacy task manager (use 'sin-code todo' for the SOTA issue tracker)",
	Long: `Manage tasks with dependencies, parallel execution plans, blocker
detection, and rollback plans. Pure Go implementation with JSON file storage.

DEPRECATED: This command is maintained for backward compatibility.
For new projects, use 'sin-code todo' which provides:
  - bbolt storage (faster, ACID)
  - Hash-based IDs (st-a1b2)
  - Dependency graph with cycle detection
  - Append-only audit log
  - Ready/Blocked queries
  - Project namespaces
  - Compaction for old closed tasks

Example:
  sin-code orchestrate --action add --title "Implement feature X" --tags "urgent,backend"
  sin-code orchestrate --action list --format json
  sin-code orchestrate --action complete --id 1`,
	RunE: func(cmd *cobra.Command, args []string) error {
		return runOrchestrate(orchAction, orchTitle, orchTags, orchID, orchFormat)
	},
}
View Source
var OrchestratorAgentDoctorCmd = &cobra.Command{
	Use:   "agent-doctor [name]",
	Short: "Validate agents: model IDs exist, API keys present, base URLs reachable",
	Args:  cobra.MaximumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		offline := agDoctorOffline || os.Getenv("SIN_LLM_OFFLINE") == "1"
		var filterName string
		if len(args) == 1 {
			filterName = strings.ToLower(args[0])
		}
		agents, err := loadAllEffectiveAgents()
		if err != nil {
			return err
		}
		if filterName != "" {
			filtered := []orchestrator.AgentConfig{}
			for _, a := range agents {
				if a.Name == filterName {
					filtered = append(filtered, a)
				}
			}
			agents = filtered
		}
		report := runDoctor(agents, offline)
		if orch2Format == "json" {
			return json.NewEncoder(os.Stdout).Encode(report)
		}
		printDoctor(report)
		failed := 0
		for _, r := range report {
			if !r.OK {
				failed++
			}
		}
		if failed > 0 {
			return fmt.Errorf("%d/%d agents have issues", failed, len(report))
		}
		return nil
	},
}
View Source
var OrchestratorAgentEditCmd = &cobra.Command{
	Use:   "agent-edit",
	Short: "Edit a per-agent TOML config (interactive $EDITOR or programmatic with --set)",
	Args:  cobra.NoArgs,
	RunE: func(cmd *cobra.Command, args []string) error {
		agEditAgent = strings.ToLower(strings.TrimSpace(agEditAgent))
		if agEditAgent == "" {
			return fmt.Errorf("--agent <name> required")
		}
		if len(agEditSet) > 0 {
			return applyAgentEdits(agEditAgent, agEditSet)
		}
		return openAgentInEditor(agEditAgent)
	},
}
View Source
var OrchestratorAgentResetCmd = &cobra.Command{
	Use:   "agent-reset <name>",
	Short: "Remove a user agent (falls back to defaults)",
	Args:  cobra.ExactArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		name := strings.ToLower(args[0])
		dir, err := agentDir(name)
		if err != nil {
			return err
		}
		if _, err := os.Stat(dir); os.IsNotExist(err) {
			fmt.Printf("Agent %s has no user config — nothing to reset.\n", name)
			return nil
		}
		if err := os.RemoveAll(dir); err != nil {
			return err
		}
		fmt.Printf("Reset agent %s to defaults (removed %s)\n", name, dir)
		return nil
	},
}
View Source
var OrchestratorAgentSetCmd = &cobra.Command{
	Use:   "agent-set <name> key=value [key=value ...]",
	Short: "Programmatically set fields on a user agent (no editor required)",
	Args:  cobra.MinimumNArgs(2),
	RunE: func(cmd *cobra.Command, args []string) error {
		name := strings.ToLower(args[0])
		return applyAgentEdits(name, args[1:])
	},
}
View Source
var OrchestratorAgentShowCmd = &cobra.Command{
	Use:   "agent-show <name>",
	Short: "Show effective config for an agent (merged defaults + user overrides)",
	Args:  cobra.ExactArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		name := strings.ToLower(args[0])
		merged, source, err := loadEffectiveAgent(name)
		if err != nil {
			return err
		}
		if orch2Format == "json" {
			out := map[string]interface{}{
				"agent":  merged,
				"source": source,
			}
			return json.NewEncoder(os.Stdout).Encode(out)
		}
		fmt.Printf("Agent %s (source: %s):\n", name, source)
		fmt.Printf("  description:  %s\n", merged.Description)
		fmt.Printf("  type:         %s\n", merged.Type)
		fmt.Printf("  provider:     %s\n", orDash(merged.Provider))
		fmt.Printf("  base_url:     %s\n", orDash(merged.BaseURL))
		fmt.Printf("  model:        %s\n", orDash(merged.Model))
		fmt.Printf("  max_tokens:   %d\n", merged.MaxTokens)
		fmt.Printf("  temperature:  %g\n", merged.Temperature)
		fmt.Printf("  system_file:  %s\n", orDash(merged.SystemFile))
		fmt.Printf("  max_context:  %d\n", merged.MaxContext)
		fmt.Printf("  memory_ns:    %s\n", orDash(merged.MemoryNS))
		fmt.Printf("  retention:    %d days\n", merged.RetentionDays)
		if len(merged.ToolsAllow) > 0 {
			fmt.Printf("  tools_allow:  %s\n", strings.Join(merged.ToolsAllow, ", "))
		}
		if len(merged.ToolsDeny) > 0 {
			fmt.Printf("  tools_deny:   %s\n", strings.Join(merged.ToolsDeny, ", "))
		}
		return nil
	},
}
View Source
var OrchestratorAgentsCmd = &cobra.Command{
	Use:   "orchestrator-agents",
	Short: "List available agents (default + user-defined + plugin)",
	RunE: func(cmd *cobra.Command, args []string) error {
		extra, err := loadAllAgents()
		if err != nil {
			return err
		}
		o := orchestrator.NewWithAgents(extra)
		registry := o.Registry
		all := registry.List()

		pluginAgent := map[string]string{}
		if !orch2NoPlugins {
			pr := plugins.NewRegistry()
			_ = pr.LoadFromDir("")
			for _, p := range pr.List() {
				for _, a := range p.Agents {
					pluginAgent["plugin-"+p.Name+"-"+a.Name] = p.Name
				}
			}
		}

		if orch2Format == "json" {
			out := make([]map[string]any, 0, len(all))
			for _, c := range all {
				entry := map[string]any{
					"name":        c.Name,
					"type":        c.Type,
					"model":       c.Model,
					"tools_allow": c.ToolsAllow,
					"description": c.Description,
				}
				if src, ok := pluginAgent[c.Name]; ok {
					entry["source"] = "plugin"
					entry["plugin"] = src
				} else {
					entry["source"] = "default-or-user"
				}
				out = append(out, entry)
			}
			return json.NewEncoder(os.Stdout).Encode(out)
		}
		fmt.Printf("Loaded %d agents:\n\n", len(all))
		for _, c := range all {
			prefix := ""
			if src, ok := pluginAgent[c.Name]; ok {
				prefix = fmt.Sprintf("[plugin %s] ", src)
			}
			fmt.Printf("  %s%-12s type=%-10s model=%-32s tools=%d\n",
				prefix, c.Name, c.Type, c.Model, len(c.ToolsAllow))
			if c.Description != "" {
				fmt.Printf("      %s\n", c.Description)
			}
		}
		return nil
	},
}
View Source
var OrchestratorPlanCmd = &cobra.Command{
	Use:   "orchestrator-plan <prompt>",
	Short: "Build a plan from a prompt (no execution)",
	Args:  cobra.ExactArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		extra, err := loadAllAgents()
		if err != nil {
			return err
		}
		o := orchestrator.NewWithAgents(extra)
		plan := o.Plan(args[0])
		if orch2Format == "json" {
			return json.NewEncoder(os.Stdout).Encode(plan)
		}
		fmt.Printf("Plan %s (intent=%s, %d tasks):\n\n", plan.ID, plan.Intent, len(plan.Tasks))
		for i, t := range plan.Tasks {
			deps := ""
			if len(t.DependsOn) > 0 {
				deps = fmt.Sprintf(" deps=[%s]", joinIDs(t.DependsOn))
			}
			fmt.Printf("  %d. [%s] agent=%-10s%s\n     %s\n",
				i+1, t.Type, t.AgentName, deps, t.Description)
		}
		return nil
	},
}
View Source
var OrchestratorRunCmd = &cobra.Command{
	Use:   "orchestrator-run <prompt>",
	Short: "Run a prompt through the multi-agent orchestrator (Pre-LLM router → planner → parallel agents)",
	Long: `orchestrate-run is the v2 SOTA orchestrator. It:
  1. Routes the prompt via cheap keyword-based intent classification (Pre-LLM)
  2. Decomposes it into ordered sub-tasks, each bound to a specialized agent
  3. Dispatches the tasks in parallel (respecting dependencies)
  4. Each agent runs with its own model, system prompt, and tool whitelist
  5. Results merge into a shared scratchpad
  6. Final aggregation produces the response

Default agents: coder, tester, reviewer, docs, security, architect.
User agents can be added to ~/.config/sin-code/agents/{name}/agent.toml
Plugin agents are auto-loaded from ~/.local/share/sin-code/plugins/<name>/

Examples:
  sin-code orchestrate-run "Add user authentication with OAuth2"
  sin-code orchestrate-run "Refactor the billing module" --plan-only
  sin-code orchestrate-run "Write docs for the API" --format json --show-scratch`,
	Args: cobra.ExactArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		orch2Prompt = args[0]
		return runOrchestrator()
	},
}
View Source
var PluginCmd = &cobra.Command{
	Use:   "plugin",
	Short: "Manage user-installed plugins (subcommands, agents, tools, hooks)",
	Long: `Plugins extend sin-code without forking. Install from a local path or
git URL, and sin-code will:
  - Register their subcommands under sin-code (e.g. sin-code my-plugin-cmd)
  - Register their agents with the orchestrator (prefixed plugin-<name>-<agent>)
  - Register their tools with the MCP server (prefixed sin_plugin_<name>_<tool>)
  - Wire their hooks into todo events

Discovery: ~/.local/share/sin-code/plugins/<name>/ with plugin.toml manifest.`,
	SilenceUsage: true,
}
View Source
var PocCmd = &cobra.Command{
	Use:   "poc",
	Short: "Proof-of-Correctness — verify code satisfies its specification",
	Long: `Verify that code satisfies its specification. Compares code against
spec documents (markdown, text, or structured requirements) and checks for
compliance.

Pure Go implementation. Checks:
  - Required functions/classes mentioned in spec exist in code
  - Function signatures match specification
  - Required imports are present
  - No forbidden patterns (e.g., os.Exit in library code)

Examples:
  sin-code poc --spec spec.md --code src/main.py
  sin-code poc --spec requirements.json --code src/`,
	RunE: func(cmd *cobra.Command, args []string) error {
		target := pocCode
		if target == "" {
			target = pocSpec
		}
		if target == "" {
			return fmt.Errorf("--code (or --spec for back-compat) is required")
		}

		result, err := verifyCorrectness(pocSpec, target)
		if err != nil {
			return err
		}

		if pocFormat == "json" {
			enc := json.NewEncoder(os.Stdout)
			enc.SetIndent("", "  ")
			return enc.Encode(result)
		}
		return outputTextPOC(result)
	},
}
View Source
var ReadCmd = &cobra.Command{
	Use:   "read [path]",
	Short: "Read files with hashline anchors, outline, and size guards",
	Long: `Token-efficient file reading for agents and humans.

Modes:
  hashline  (default) lines prefixed with "LINE:HASH|" — anchors feed 'sin-code edit'
  raw       plain content (still offset/limit guarded)
  outline   structure only: imports, functions, classes, exports (huge files)

Examples:
  sin-code read main.go
  sin-code read main.go --mode outline
  sin-code read big.log --offset 5000 --limit 200 --mode raw
  sin-code read pkg/x.go --format json`,
	Args: cobra.ExactArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		absPath, err := filepath.Abs(args[0])
		if err != nil {
			return fmt.Errorf("invalid path: %w", err)
		}
		result, err := readFile(absPath, readMode, readOffset, readLimit, readMaxBytes)
		if err != nil {
			return err
		}
		if readFormat == "json" {
			enc := json.NewEncoder(os.Stdout)
			enc.SetIndent("", "  ")
			return enc.Encode(result)
		}
		fmt.Print(result.Content)
		if result.Truncated {
			fmt.Fprintf(os.Stderr, "\n[truncated: showing lines %d-%d of %d — use --offset/--limit, or --mode outline]\n",
				result.Offset, result.Offset+result.ReturnedLines-1, result.TotalLines)
		}
		return nil
	},
}
View Source
var SbomCmd = &cobra.Command{
	Use:   "sbom [path]",
	Short: "Generate SPDX or CycloneDX JSON SBOM for a project",
	Long: `sbom generates a Software Bill of Materials (SBOM) for the project at <path>.

Supported project types:
  Go      → parses go.mod / go list -m -json all
  Python  → parses requirements.txt or pyproject.toml
  Node.js → parses package.json (+ package-lock.json for versions)
  Generic → lists directory structure as a basic component tree

Output formats:
  spdx-json      (default) SPDX 2.3 JSON
  cyclonedx-json CycloneDX 1.5 JSON

Examples:
  sin-code sbom .
  sin-code sbom ./my-project --format cyclonedx-json --output sbom.json`,
	Args: cobra.MaximumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		path := "."
		if len(args) > 0 {
			path = args[0]
		}
		path, _ = filepath.Abs(path)

		format, _ := cmd.Flags().GetString("format")
		output, _ := cmd.Flags().GetString("output")

		projType := detectProjectType(path)

		sbom, err := generateSBOM(path, projType, format)
		if err != nil {
			return fmt.Errorf("sbom generation failed: %w", err)
		}

		var out io.Writer = os.Stdout
		if output != "" && output != "-" {
			f, err := os.Create(output)
			if err != nil {
				return fmt.Errorf("cannot create output file: %w", err)
			}
			defer f.Close()
			out = f
		}

		enc := json.NewEncoder(out)
		enc.SetIndent("", "  ")
		return enc.Encode(sbom)
	},
}

SbomCmd generates a Software Bill of Materials in SPDX or CycloneDX format.

View Source
var SckgCmd = &cobra.Command{
	Use:   "sckg",
	Short: "Semantic Codebase Knowledge Graphs — build & query code graph",
	Long: `Build and query a semantic graph of a codebase. Pure Go implementation.

Actions:
  build  — Build the knowledge graph from source code
  query  — Query the graph for relationships (requires --query)
  stats  — Show graph statistics
  export — Export graph as JSON

Examples:
  sin-code sckg . --action build
  sin-code sckg . --action query --query "auth module dependencies"
  sin-code sckg . --action stats
  sin-code sckg . --action export --format json`,
	Args: cobra.ArbitraryArgs,
	RunE: func(cmd *cobra.Command, args []string) error {
		path := "."
		if len(args) > 0 {
			path = args[0]
		}
		absPath, err := filepath.Abs(path)
		if err != nil {
			return fmt.Errorf("invalid path: %w", err)
		}
		if info, err := os.Stat(absPath); err != nil || !info.IsDir() {
			if err != nil {
				return fmt.Errorf("path not found: %w", err)
			}
			return fmt.Errorf("path is not a directory: %s", absPath)
		}

		switch sckgAction {
		case "build":
			graph, err := buildGraph(absPath)
			if err != nil {
				return err
			}
			if sckgFormat == "json" {
				enc := json.NewEncoder(os.Stdout)
				enc.SetIndent("", "  ")
				return enc.Encode(graph)
			}
			return outputTextSCKGBuild(graph)
		case "query":
			if sckgQuery == "" {
				return fmt.Errorf("--query is required for action=query")
			}
			graph, err := buildGraph(absPath)
			if err != nil {
				return err
			}
			results := queryGraph(graph, sckgQuery)
			if sckgFormat == "json" {
				enc := json.NewEncoder(os.Stdout)
				enc.SetIndent("", "  ")
				return enc.Encode(results)
			}
			return outputTextSCKGQuery(results)
		case "stats":
			graph, err := buildGraph(absPath)
			if err != nil {
				return err
			}
			stats := graphStats(graph)
			if sckgFormat == "json" {
				enc := json.NewEncoder(os.Stdout)
				enc.SetIndent("", "  ")
				return enc.Encode(stats)
			}
			return outputTextSCKGStats(stats)
		case "export":
			graph, err := buildGraph(absPath)
			if err != nil {
				return err
			}
			enc := json.NewEncoder(os.Stdout)
			enc.SetIndent("", "  ")
			return enc.Encode(graph)
		default:
			return fmt.Errorf("unknown action: %s (use build|query|stats|export)", sckgAction)
		}
	},
}
View Source
var ScoutCmd = &cobra.Command{
	Use:   "scout",
	Short: "Search code with regex, semantic, symbol, and usage search",
	Long: `Parallel code search with optional ripgrep bridge (auto-detected on PATH).

Search types: regex|semantic|symbol|usage
  regex     literal regex pattern
  semantic  word-order matching (case insensitive)
  symbol    function/class/struct/variable definitions
  usage     all references to a symbol name

Examples:
  sin-code scout --query "func.*main" --path . --search_type regex --format json
  sin-code scout --query "handleError" --path . --search_type usage
  sin-code scout --query "class.*Factory" --search_type symbol --no-rg`,
	RunE: func(cmd *cobra.Command, args []string) error {
		if scoutQuery == "" {
			return fmt.Errorf("--query is required")
		}
		absPath, err := filepath.Abs(scoutPath)
		if err != nil {
			return fmt.Errorf("invalid path: %w", err)
		}
		if info, err := os.Stat(absPath); err != nil || !info.IsDir() {
			if err != nil {
				return fmt.Errorf("path not found: %w", err)
			}
			return fmt.Errorf("path is not a directory: %s", absPath)
		}

		results, err := searchFiles(absPath, scoutQuery, scoutType, scoutMax, scoutNoRG)
		if err != nil {
			return err
		}

		if scoutFormat == "json" {
			enc := json.NewEncoder(os.Stdout)
			enc.SetIndent("", "  ")
			return enc.Encode(results)
		}
		return outputTextScout(results)
	},
}
View Source
var SecurityCmd = &cobra.Command{
	Use:   "security [path]",
	Short: "Fast security analysis — auto-detects project type and runs available tools",
	Long: `security runs a targeted security scan based on the project type detected at <path>.

Supported project types and tools:
  Go        → govulncheck, gosec, go vet (if available)
  Python    → bandit, safety (if available)
  Node.js   → npm audit (if available)
  Generic   → secrets scan (grep for high-entropy strings), file-permission checks

The scan is fast (defaults to 5-minute timeout) and produces a concise summary.
Use --format json for machine-readable output.`,
	Args: cobra.MaximumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		path := "."
		if len(args) > 0 {
			path = args[0]
		}
		path, _ = filepath.Abs(path)

		projType, _ := cmd.Flags().GetString("type")
		if projType == "" || projType == "auto" {
			projType = detectProjectType(path)
		}

		toolFilter, _ := cmd.Flags().GetString("tools")
		format, _ := cmd.Flags().GetString("format")
		timeoutSec, _ := cmd.Flags().GetInt("timeout")
		strict, _ := cmd.Flags().GetBool("strict")

		result := runSecurityScan(path, projType, toolFilter, timeoutSec)
		result.Strict = strict

		if format == "json" {
			out, _ := json.MarshalIndent(result, "", "  ")
			fmt.Println(string(out))
		} else {
			printSecurityResult(result)
		}

		if strict && result.Summary.Issues > 0 {
			return fmt.Errorf("security scan found %d issues (strict mode)", result.Summary.Issues)
		}
		return nil
	},
}

SecurityCmd runs a fast security analysis tailored to the detected project type.

View Source
var SelfUpdateCmd = &cobra.Command{
	Use:   "self-update",
	Short: "Check for and install the latest sin-code release",
	Long: `self-update checks GitHub releases for a newer version of sin-code,
downloads the correct binary for your platform, and installs it.

The current binary is backed up before replacement. If the update fails,
the backup is restored automatically.

Usage:
  sin-code self-update              # Check and install latest stable
  sin-code self-update --version    # Show current version info
  sin-code self-update --dry-run    # Check only, don't install

Supported platforms: darwin/amd64, darwin/arm64, linux/amd64, linux/arm64, windows/amd64`,
	RunE: func(cmd *cobra.Command, args []string) error {
		dryRun, _ := cmd.Flags().GetBool("dry-run")
		showVersion, _ := cmd.Flags().GetBool("version")

		if showVersion {
			return printVersionInfo()
		}

		return runSelfUpdate(dryRun)
	},
}
View Source
var ServeCmd = &cobra.Command{
	Use:   "serve",
	Short: "Start an MCP server exposing all 13 sin-code tools",
	Long: `Start a Model Context Protocol (MCP) server that exposes all 13 sin-code
subcommands as MCP tools. This allows opencode (and any MCP-compatible client)
to use sin-code as a single registered MCP server instead of registering 13
separate binaries.

Note: security, sbom, config, self-update, and tui are CLI-only subcommands
and are NOT exposed as MCP tools. The MCP server only exposes the 13 core
analysis tools listed below.

Example opencode.json entry:

  "sin-code": {
    "command": ["/Users/jeremy/.local/bin/sin-code", "serve"],
    "description": "SIN-Code unified toolchain (13 MCP tools)",
    "enabled": true,
    "type": "local"
  }

Then use sin_discover, sin_execute, sin_map, sin_grasp, sin_scout, sin_harvest,
sin_orchestrate, sin_ibd, sin_poc, sin_sckg, sin_adw, sin_oracle, sin_efm as
MCP tools.`,
	RunE: func(cmd *cobra.Command, args []string) error {
		ctx, cancel := context.WithCancel(context.Background())
		defer cancel()

		server := mcp.NewServer(&mcp.Implementation{
			Name:    "sin-code",
			Version: ServerVersion,
		}, &mcp.ServerOptions{
			Capabilities: &mcp.ServerCapabilities{
				Tools: &mcp.ToolCapabilities{},
			},
		})

		registerAllMCPTools(server)

		if serveTransport == "stdio" {
			return server.Run(ctx, &mcp.StdioTransport{})
		}
		return fmt.Errorf("unsupported transport: %s (only stdio supported)", serveTransport)
	},
}
View Source
var ServerVersion = "dev"

ServerVersion is set at build time via -ldflags "-X github.com/OpenSIN-Code/SIN-Code-Bundle/cmd/sin-code/internal.ServerVersion=..."

View Source
var WriteCmd = &cobra.Command{
	Use:   "write [path]",
	Short: "Write files atomically with syntax pre-validation",
	Long: `Atomic file writing: content is validated, written to a temp file in the
target directory, fsynced, then renamed over the destination. A crash or
validation failure never leaves a corrupt file behind.

Validation (skip with --no-validate):
  .go    full parse via go/parser
  .json  encoding/json
  other  bracket/brace/paren balance heuristic (string/comment aware)

Examples:
  sin-code write pkg/new.go --content "$(cat /tmp/draft.go)"
  cat draft.json | sin-code write config.json --stdin --backup
  sin-code write docs/new/file.md --stdin --mkdir < notes.md`,
	Args: cobra.ExactArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		absPath, err := filepath.Abs(args[0])
		if err != nil {
			return fmt.Errorf("invalid path: %w", err)
		}
		content := writeContent
		if writeStdin {
			data, err := io.ReadAll(os.Stdin)
			if err != nil {
				return fmt.Errorf("reading stdin: %w", err)
			}
			content = string(data)
		}
		result, err := writeFileAtomic(absPath, content, writeOpts{
			validate: !writeNoValidate,
			backup:   writeBackup,
			mkdir:    writeMkdir,
		})
		if err != nil {
			return err
		}
		if writeFormat == "json" {
			enc := json.NewEncoder(os.Stdout)
			enc.SetIndent("", "  ")
			return enc.Encode(result)
		}
		fmt.Printf("wrote %s (%d bytes, %d lines)%s\n", result.Path, result.Bytes, result.Lines,
			map[bool]string{true: " [backup: " + result.BackupPath + "]", false: ""}[result.BackupPath != ""])
		return nil
	},
}

Functions

func CheckUpdateAvailable

func CheckUpdateAvailable() (string, bool, error)

CheckUpdateAvailable queries GitHub for the latest release and reports whether the current binary is outdated.

func FormatHashlines

func FormatHashlines(lines []string, start int) string

func JoinLines

func JoinLines(lines []string, trailingNewline bool) string

func LineHash

func LineHash(line string) string

func PrintError

func PrintError(err error)

PrintError prints an error to stderr in a consistent format and exits with code 1.

func ResolveAnchor

func ResolveAnchor(lines []string, a Anchor, driftWindow int) (idx int, drift int, err error)

func SetCurrentVersion

func SetCurrentVersion(v string)

func SplitLines

func SplitLines(content string) (lines []string, trailingNewline bool)

Types

type Anchor

type Anchor struct {
	Line int    `json:"line"`
	Hash string `json:"hash"`
}

func ParseAnchor

func ParseAnchor(s string) (Anchor, error)

func (Anchor) String

func (a Anchor) String() string

type CycloneDXComponent

type CycloneDXComponent struct {
	Type    string `json:"type"`
	BomRef  string `json:"bom-ref"`
	Name    string `json:"name"`
	Version string `json:"version,omitempty"`
	PURL    string `json:"purl,omitempty"`
	Scope   string `json:"scope,omitempty"`
}

type CycloneDXDocument

type CycloneDXDocument struct {
	BomFormat    string               `json:"bomFormat"`
	SpecVersion  string               `json:"specVersion"`
	SerialNumber string               `json:"serialNumber"`
	Version      int                  `json:"version"`
	Metadata     CycloneDXMetadata    `json:"metadata"`
	Components   []CycloneDXComponent `json:"components"`
}

CycloneDX 1.5 document

type CycloneDXMetadata

type CycloneDXMetadata struct {
	Timestamp string          `json:"timestamp"`
	Tools     []CycloneDXTool `json:"tools"`
}

type CycloneDXTool

type CycloneDXTool struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

type DoctorReport

type DoctorReport struct {
	Agent  string                 `json:"agent"`
	OK     bool                   `json:"ok"`
	Issues []string               `json:"issues,omitempty"`
	Info   map[string]interface{} `json:"info,omitempty"`
}

type FileOutline

type FileOutline struct {
	Language string       `json:"language"`
	Engine   string       `json:"engine"`
	Symbols  []SymbolInfo `json:"symbols"`
	Imports  []string     `json:"imports"`
}

type GitHubRelease

type GitHubRelease struct {
	TagName   string `json:"tag_name"`
	Name      string `json:"name"`
	Published string `json:"published_at"`
	Body      string `json:"body"`
	Assets    []struct {
		Name string `json:"name"`
		Size int    `json:"size"`
		URL  string `json:"browser_download_url"`
	} `json:"assets"`
}

type SPDXCreationInfo

type SPDXCreationInfo struct {
	Created  string   `json:"created"`
	Creators []string `json:"creators"`
}

type SPDXDocument

type SPDXDocument struct {
	SPDXVersion       string           `json:"spdxVersion"`
	SPDXID            string           `json:"SPDXID"`
	Name              string           `json:"name"`
	DocumentNamespace string           `json:"documentNamespace"`
	CreationInfo      SPDXCreationInfo `json:"creationInfo"`
	Packages          []SPDXPackage    `json:"packages"`
}

SPDX 2.3 document

type SPDXPackage

type SPDXPackage struct {
	SPDXID                string  `json:"SPDXID"`
	Name                  string  `json:"name"`
	VersionInfo           string  `json:"versionInfo"`
	DownloadLocation      string  `json:"downloadLocation"`
	FilesAnalyzed         bool    `json:"filesAnalyzed"`
	VerificationCode      *string `json:"verificationCode"`
	LicenseConcluded      string  `json:"licenseConcluded"`
	LicenseDeclared       string  `json:"licenseDeclared"`
	CopyrightText         string  `json:"copyrightText"`
	PrimaryPackagePurpose string  `json:"primaryPackagePurpose"`
}

type SecurityResult

type SecurityResult struct {
	ProjectType string          `json:"project_type"`
	Path        string          `json:"path"`
	Duration    time.Duration   `json:"duration"`
	Strict      bool            `json:"strict"`
	Tools       []ToolResult    `json:"tools"`
	Summary     SecuritySummary `json:"summary"`
}

type SecuritySummary

type SecuritySummary struct {
	ToolsRun int `json:"tools_run"`
	Issues   int `json:"issues"`
	Errors   int `json:"errors"`
	Skipped  int `json:"skipped"`
	NotFound int `json:"not_found"`
}

type SinCodeConfig

type SinCodeConfig struct {
	Theme            string `toml:"theme"`
	DefaultTimeout   int    `toml:"default_timeout"`
	DefaultFormat    string `toml:"default_format"`
	MCPServerEnabled bool   `toml:"mcp_server_enabled"`
}

type SymbolInfo

type SymbolInfo struct {
	Name      string       `json:"name"`
	Kind      string       `json:"kind"`
	StartLine int          `json:"start_line"`
	EndLine   int          `json:"end_line"`
	Signature string       `json:"signature"`
	Children  []SymbolInfo `json:"children,omitempty"`
}

type ToolResult

type ToolResult struct {
	Name     string `json:"name"`
	Status   string `json:"status"` // ok, issues, skipped, error, not_found
	Issues   int    `json:"issues"`
	Duration string `json:"duration"`
	Output   string `json:"output,omitempty"`
	Error    string `json:"error,omitempty"`
}

Directories

Path Synopsis
SPDX-License-Identifier: MIT Purpose: attachment store with SHA-256 dedup and magic-byte MIME detection.
SPDX-License-Identifier: MIT Purpose: attachment store with SHA-256 dedup and magic-byte MIME detection.
SPDX-License-Identifier: MIT Purpose: NVIDIA NIM-specific helpers.
SPDX-License-Identifier: MIT Purpose: NVIDIA NIM-specific helpers.
SPDX-License-Identifier: MIT Purpose: LSP (Language Server Protocol) client.
SPDX-License-Identifier: MIT Purpose: LSP (Language Server Protocol) client.
SPDX-License-Identifier: MIT Purpose: text embedding via NVIDIA NIM.
SPDX-License-Identifier: MIT Purpose: text embedding via NVIDIA NIM.
SPDX-License-Identifier: MIT Purpose: cobra CLI for sin-code notifications: list/read/dismiss/listen/clear/stats/prune.
SPDX-License-Identifier: MIT Purpose: cobra CLI for sin-code notifications: list/read/dismiss/listen/clear/stats/prune.
SPDX-License-Identifier: MIT Purpose: Agent abstraction + mock implementation.
SPDX-License-Identifier: MIT Purpose: Agent abstraction + mock implementation.
SPDX-License-Identifier: MIT Purpose: plugin manifest format + validator.
SPDX-License-Identifier: MIT Purpose: plugin manifest format + validator.
SPDX-License-Identifier: MIT Purpose: sin-code todo hook — manage pre/post event shell commands.
SPDX-License-Identifier: MIT Purpose: sin-code todo hook — manage pre/post event shell commands.
SPDX-License-Identifier: MIT Purpose: sin-code web UI — stdlib HTTP server that exposes the orchestrator, todo store, notifications, and EFM stacks through a browser.
SPDX-License-Identifier: MIT Purpose: sin-code web UI — stdlib HTTP server that exposes the orchestrator, todo store, notifications, and EFM stacks through a browser.

Jump to

Keyboard shortcuts

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