describe

package
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2025 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

cmd/project/describe/describe.go

Index

Constants

This section is empty.

Variables

View Source
var DescribeCmd = &cobra.Command{
	Use:     "describe [-o <output_file>]",
	Example: `  contextvibes project describe -o project_snapshot.md`,
	Args:    cobra.NoArgs,
	RunE: func(cmd *cobra.Command, args []string) error {
		presenter := ui.NewPresenter(cmd.OutOrStdout(), cmd.ErrOrStderr())
		ctx := cmd.Context()

		presenter.Summary("Generating project context description.")

		workDir, err := os.Getwd()
		if err != nil {
			return err
		}

		gitCfg := git.GitClientConfig{
			Logger:                globals.AppLogger,
			DefaultRemoteName:     globals.LoadedAppConfig.Git.DefaultRemote,
			DefaultMainBranchName: globals.LoadedAppConfig.Git.DefaultMainBranch,
			Executor:              globals.ExecClient.UnderlyingExecutor(),
		}
		client, err := git.NewClient(ctx, workDir, gitCfg)
		if err != nil {
			presenter.Error("Failed git init: %v", err)
			return err
		}
		cwd := client.Path()

		includeRe, _ := regexp.Compile(includeExtensionsRegex)
		excludeRe, _ := regexp.Compile(excludePathsRegex)
		maxSizeBytes := int64(maxFileSizeKB * 1024)

		var aiExcluder gitignore.GitIgnore
		aiExcludeFilePath := filepath.Join(cwd, ".aiexclude")
		aiExcludeContent, readErr := os.ReadFile(aiExcludeFilePath)
		if readErr == nil {
			aiExcluder = gitignore.New(bytes.NewReader(aiExcludeContent), cwd, nil)
		}

		var outputBuffer bytes.Buffer
		userPrompt, err := presenter.PromptForInput("Enter a prompt for the AI: ")
		if err != nil || userPrompt == "" {
			return errors.New("prompt cannot be empty")
		}
		fmt.Fprintf(&outputBuffer, "### Prompt\n\n%s\n\n", userPrompt)

		gitStatus, _, statusErr := client.GetStatusShort(ctx)
		if statusErr != nil {
			gitStatus = "Failed to get git status."
		}
		tools.AppendSectionHeader(&outputBuffer, "Git Status (Summary)")
		tools.AppendFencedCodeBlock(&outputBuffer, strings.TrimSpace(gitStatus), "")

		treeOutput, _, treeErr := globals.ExecClient.CaptureOutput(ctx, workDir, "tree", "-L", "2", "-a", "-I", treeIgnorePattern)
		if treeErr != nil {
			treeOutput = "Could not generate tree view. 'tree' command may not be installed."
		}
		tools.AppendSectionHeader(&outputBuffer, "Project Structure")
		tools.AppendFencedCodeBlock(&outputBuffer, strings.TrimSpace(treeOutput), "")

		tools.AppendSectionHeader(&outputBuffer, "Relevant Code Files")

		gitLsFilesOutput, _, err := client.ListTrackedAndCachedFiles(ctx)
		if err != nil {
			return err
		}
		filesToList := strings.Split(strings.TrimSpace(gitLsFilesOutput), "\n")

		for _, file := range filesToList {
			if file == "" {
				continue
			}

			if !includeRe.MatchString(file) || excludeRe.MatchString(file) {
				continue
			}
			if aiExcluder != nil && aiExcluder.Match(file) != nil && aiExcluder.Match(file).Ignore() {
				continue
			}

			info, statErr := os.Stat(file)
			if statErr != nil {
				continue
			}
			if info.Size() > maxSizeBytes {
				continue
			}

			content, readErr := tools.ReadFileContent(file)
			if readErr == nil {
				tools.AppendFileMarkerHeader(&outputBuffer, file)
				outputBuffer.Write(content)
				tools.AppendFileMarkerFooter(&outputBuffer, file)
			}
		}

		if err := tools.WriteBufferToFile(describeOutputFile, &outputBuffer); err != nil {
			return err
		}

		presenter.Success("Successfully generated context file: %s", describeOutputFile)
		return nil
	},
}

DescribeCmd represents the describe command

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