cmd

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 30, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package cmd defines *cli.Command values for each codesearch subcommand. Each command is a thin wrapper that parses args (with flag.FlagSet where needed) and delegates to the relevant internal package.

Index

Constants

This section is empty.

Variables

View Source
var Facets = &cli.Command{
	Name:  "facets",
	Usage: "Return the distinct values seen in a given indexed field.",
	Flags: []cli.Flag{
		&cli.IntFlag{
			Name:  "limit",
			Usage: "max facets to return",
			Value: 10,
		},
	},
	Arguments: []cli.Argument{
		&cli.StringArg{
			Name:      "field",
			UsageText: "the name of the field to lookup",
		},
	},
	Action: func(ctx context.Context, c *cli.Command) error {
		limit := c.Value("limit").(int)
		field := c.StringArg("field")

		cfg, err := config.Load("")
		if err != nil {
			return err
		}
		idx, err := index.OpenReadOnly(cfg.IndexPath())
		if err != nil {
			return err
		}
		defer func() { _ = idx.Close() }()

		bleveReq := bleve.NewSearchRequestOptions(bleve.NewMatchAllQuery(), 0, 0, false)
		bleveReq.AddFacet(field, bleve.NewFacetRequest(field, limit))

		result, err := idx.Bleve().Search(bleveReq)
		if err != nil {
			return err
		}

		facet, ok := result.Facets[field]
		if !ok || facet == nil {
			return nil
		}

		for _, t := range facet.Terms.Terms() {
			fmt.Printf("%s\t%d\n", t.Term, t.Count)
		}

		return nil
	},
}
View Source
var Fields = &cli.Command{
	Name:  "fields",
	Usage: "List every indexed field name in the codesearch index.",
	Action: func(ctx context.Context, c *cli.Command) error {
		cfg, err := config.Load("")
		if err != nil {
			return err
		}
		idx, err := index.OpenReadOnly(cfg.IndexPath())
		if err != nil {
			return err
		}
		defer func() { _ = idx.Close() }()

		fields, err := idx.Bleve().Fields()
		if err != nil {
			return err
		}

		for _, field := range fields {
			fmt.Println(field)
		}

		return nil
	},
}
View Source
var Init = &cli.Command{
	Name:  "init",
	Usage: "Create an empty codesearch index at .codesearch/.",
	Action: func(ctx context.Context, c *cli.Command) error {
		cfg, err := config.Load("")
		if err != nil {
			return err
		}

		err = os.MkdirAll(cfg.IndexDir(), 0o755)
		if err != nil {
			return err
		}

		_, err = os.Stat(cfg.IndexPath())
		if err == nil {
			return fmt.Errorf("index already exists at %s", cfg.IndexPath())
		}
		if !errors.Is(err, fs.ErrNotExist) {
			return err
		}

		idx, err := index.Create(cfg.IndexPath())
		if err != nil {
			return err
		}
		defer func() { _ = idx.Close() }()

		meta := sync.Meta{
			SchemaVersion: index.SchemaVersion,
			LastSyncAt:    time.Time{},
		}

		err = sync.WriteMeta(cfg.MetaPath(), meta)
		if err != nil {
			return err
		}

		_, _ = fmt.Fprintf(os.Stdout, "created index at %s\n", cfg.IndexPath())
		return nil
	},
}

Init creates an empty codesearch index at .codesearch/.

View Source
var Query = &cli.Command{
	Name:  "query",
	Usage: "Search the index for the given terms.",
	Flags: []cli.Flag{
		&cli.StringMapFlag{
			Name:  "fields",
			Usage: "filter `key=value` (repeatable, AND)",
		},
		&cli.IntFlag{
			Name:  "limit",
			Usage: "max hits to return",
			Value: 10,
		},
		&cli.StringFlag{
			Name:  "format",
			Usage: "output format: text or json",
			Value: "text",
		},
		&cli.BoolFlag{
			Name:  "no-snippet",
			Usage: "skip snippet generation",
			Value: false,
		},
	},
	Action: func(ctx context.Context, c *cli.Command) error {
		fields := c.Value("fields").(map[string]string)
		limit := c.Value("limit").(int)
		format := c.Value("format").(string)
		noSnippet := c.Value("no-snippet").(bool)

		terms := strings.Join(c.Args().Slice(), " ")

		cfg, err := config.Load("")
		if err != nil {
			return err
		}
		idx, err := index.OpenReadOnly(cfg.IndexPath())
		if err != nil {
			return err
		}
		defer func() { _ = idx.Close() }()

		req := query.Request{
			Terms:     terms,
			Fields:    fields,
			Limit:     limit,
			NoSnippet: noSnippet,
			Boosts:    cfg.Boosts,
		}
		switch format {
		case "json":
			req.Highlight = "html"
		default:
			req.Highlight = "ansi"
		}

		res, err := query.Search(idx, req)
		if err != nil {
			return err
		}

		if format == "json" {
			enc := json.NewEncoder(os.Stdout)
			enc.SetIndent("", "  ")
			return enc.Encode(res)
		}
		return query.RenderText(os.Stdout, res)
	},
}

Query searches the index for the given terms.

View Source
var Serve = &cli.Command{
	Name:  "serve",
	Usage: "Run the codesearch MCP server on stdio (for AI assistants).",
	Action: func(ctx context.Context, c *cli.Command) error {
		cfg, err := config.Load("")
		if err != nil {
			return err
		}

		return mcp.Serve(cfg)
	},
}

Serve runs the codesearch MCP server on stdio (for AI assistants).

View Source
var Status = &cli.Command{
	Name:  "status",
	Usage: "Report doc count, on-disk size, and last sync time.",
	Action: func(ctx context.Context, c *cli.Command) error {
		cfg, err := config.Load("")
		if err != nil {
			return err
		}

		idx, err := index.OpenReadOnly(cfg.IndexPath())
		if err != nil {
			if errors.Is(err, fs.ErrNotExist) {
				return fmt.Errorf("no index found at %s; run `codesearch init` first", cfg.IndexPath())
			}
			return err
		}
		defer func() { _ = idx.Close() }()

		count, err := idx.DocCount()
		if err != nil {
			return err
		}
		meta, err := sync.ReadMeta(cfg.MetaPath())
		if err != nil {
			return err
		}
		size, err := dirSize(cfg.IndexPath())
		if err != nil {
			return err
		}

		lastSync := "never"
		if !meta.LastSyncAt.IsZero() {
			lastSync = meta.LastSyncAt.Format("2006-01-02 15:04:05 MST")
		}

		_, _ = fmt.Fprintf(os.Stdout, "index:          %s\n", cfg.IndexPath())
		_, _ = fmt.Fprintf(os.Stdout, "docs:           %d\n", count)
		_, _ = fmt.Fprintf(os.Stdout, "size:           %s\n", formatSize(size))
		_, _ = fmt.Fprintf(os.Stdout, "schema_version: %d\n", meta.SchemaVersion)
		_, _ = fmt.Fprintf(os.Stdout, "last_sync_at:   %s\n", lastSync)
		return nil
	},
}

Status reports doc count, on-disk size, and last sync time.

View Source
var Sync = &cli.Command{
	Name:  "sync",
	Usage: "Reconcile the codesearch index with the filesystem.",
	Action: func(ctx context.Context, c *cli.Command) error {
		cfg, err := config.Load("")
		if err != nil {
			return err
		}
		res, err := sync.Run(ctx, cfg)
		if err != nil {
			return err
		}
		_, _ = fmt.Fprintf(os.Stdout, "sync complete: scanned=%d upserted=%d touched=%d deleted=%d unchanged=%d\n",
			res.Scanned, res.Upserted, res.Touched, res.Deleted, res.Unchanged)
		return nil
	},
}

Sync reconciles the codesearch index with the filesystem.

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

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