ajhahn.de
← eeco
Go 49 lines
package workflow

import (
	"fmt"

	"github.com/ajhahnde/eeco/internal/manifest"
)

// manifestRefresh rebuilds the per-directory .ai.json manifests across the
// knowledge dirs (the project-type-aware directories scaffolded under
// <repo>/<username>/ as siblings of the engine workspace) and all of their
// nested subdirectories. Each manifest is a deterministic skeleton — paths and
// kinds only; the opt-in AI enrichment pass fills descriptions separately, so
// this builtin needs no AI and never blocks.
//
// It is the post-merge member of the family: a `git pull` / `git merge` is when
// another author's files land, so it is the moment to re-enumerate the
// knowledge tree. The writes land in the gitignored per-user area (never the
// tracked tree) and are idempotent — the .ai.json itself is excluded from the
// walk, so a re-run over unchanged dirs reproduces byte-identical files.
type manifestRefresh struct{}

func (manifestRefresh) Name() string { return "manifest-refresh" }

func (manifestRefresh) Summary() string {
	return "rebuild the per-directory .ai.json manifests in the knowledge dirs"
}

func (manifestRefresh) Run(env Env) (Result, error) {
	cfg := env.Config
	dirs, err := manifest.KnowledgeDirs(cfg.UserDir, cfg.WorkspaceName)
	if err != nil {
		return Result{}, fmt.Errorf("manifest-refresh: list knowledge dirs: %w", err)
	}
	if len(dirs) == 0 {
		return Result{Code: CodeClean, Summary: "no knowledge dirs to refresh"}, nil
	}
	for _, d := range dirs {
		m, err := manifest.Build(cfg.UserDir, d)
		if err != nil {
			return Result{}, fmt.Errorf("manifest-refresh: build %s: %w", d, err)
		}
		if err := manifest.Write(cfg.UserDir, d, m); err != nil {
			return Result{}, fmt.Errorf("manifest-refresh: write %s: %w", d, err)
		}
	}
	return Result{Code: CodeClean, Summary: fmt.Sprintf("refreshed %d manifest(s)", len(dirs))}, nil
}