Documentation
¶
Overview ¶
Package initrepo implements `aiwf init`: idempotent first-time setup for a consumer repo. See docs/pocv3/archive/poc-plan-pre-migration.md Session 3 for the full contract.
The package never produces a git commit — it writes/scaffolds and reports back; the user commits when ready. It is also safe to re-run: pre-existing files (aiwf.yaml, CLAUDE.md, custom .gitignore content) are preserved verbatim; skills are always wiped-and-rewritten per the cache contract.
Index ¶
Constants ¶
const CLAUDETemplate = `# CLAUDE.md
This repository uses [aiwf](https://github.com/23min/ai-workflow-v2) to track planning state.
## Quick reference
- ` + "`aiwf check`" + ` — validate the planning tree.
- ` + "`aiwf add <kind> --title \"...\"`" + ` — create an entity (epic, milestone, adr, gap, decision, contract).
- ` + "`aiwf promote <id> <status>`" + ` — advance status.
- ` + "`aiwf history <id>`" + ` — show what happened to an entity.
The pre-push hook runs ` + "`aiwf check`" + ` automatically; broken state cannot be pushed.
Skills under ` + "`.claude/skills/aiwf-*/`" + ` are gitignored and regenerated on ` + "`aiwf update`" + `.
`
CLAUDETemplate is the boilerplate written to CLAUDE.md when no file exists. Short by design — consumers customize it freely.
Variables ¶
This section is empty.
Functions ¶
func HookMarker ¶
func HookMarker() string
HookMarker exposes the marker line for tests that assert the hook was installed by aiwf vs. someone else.
func PreCommitHookMarker ¶
func PreCommitHookMarker() string
PreCommitHookMarker exposes the pre-commit hook's marker line for tests and for `aiwf doctor` to identify a marker-managed hook versus a user-written one.
Types ¶
type Action ¶
type Action string
Action classifies what init did for a single step. The CLI uses this to render a friendly summary.
const ( ActionCreated Action = "created" ActionPreserved Action = "preserved" ActionUpdated Action = "updated" // ActionSkipped marks a step that init declined to perform because // doing so would clobber user-managed state. The Detail field on // the StepResult explains why and what the user should do next. ActionSkipped Action = "skipped" // ActionRemoved marks a step that uninstalled a previously-managed // artifact because the consumer opted out. Currently used only by // the pre-commit hook step when status_md.auto_update flips false. ActionRemoved Action = "removed" // ActionMigrated marks a hook step that mv'd a pre-existing // non-aiwf hook to <name>.local before installing aiwf's chain-aware // hook (G45). The Detail names what moved where so the user can // audit it. ActionMigrated Action = "migrated" )
Action values reported per step.
type Options ¶
Options carries init-time inputs that override or supplement the defaults. ActorOverride bypasses git-config derivation when set.
DryRun computes the would-be ledger without performing any filesystem mutations. SkipHook omits *both* the pre-push and the pre-commit hook installations entirely (each still reported in the ledger as a skipped step). The flag is for consumers who run husky/lefthook (or similar) and want aiwf to leave .git/hooks/ alone.
Per G47, `aiwf_version:` is no longer stored in aiwf.yaml — the running binary's version is the authoritative answer to "what version are we on" (`aiwf version`); a stored pin produced chronic doctor noise without serving its intended purpose.
type RefreshOptions ¶
RefreshOptions carries the inputs that drive RefreshArtifacts — the shared installer pipeline run by both `aiwf init` (after scaffolding) and `aiwf update`.
StatusMdAutoUpdate carries the consumer's opt-out state from `aiwf.yaml.status_md.auto_update`. When true, the pre-commit hook that regenerates `STATUS.md` is installed/refreshed; when false, a previously-installed marker-managed pre-commit hook is removed and a fresh refresh pass installs nothing in its place.
SkipHooks omits both pre-push and pre-commit installation entirely (init's `--skip-hook` flag forwards into this field).
type Result ¶
type Result struct {
Steps []StepResult
HookConflict bool
DryRun bool
}
Result is the per-step ledger init returns. Order matches the order of operations. HookConflict is set when init declined to install the pre-push hook because a non-aiwf hook was already in place; callers should surface remediation guidance to the user. DryRun echoes Options.DryRun so callers can format output appropriately (a dry-run ledger looks identical but no writes occurred).
func Init ¶
Init runs the documented setup steps in order. Returns a Result that describes what was created vs preserved vs updated. Errors abort early — a partially-applied init is rare in practice (init only touches config / scaffolding / skills) and the user can re-run.
Step order:
- aiwf.yaml (first-time-only)
- work/* and docs/adr scaffold dirs (first-time-only)
- CLAUDE.md (first-time-only)
- RefreshArtifacts: skills + .gitignore + pre-push hook + pre-commit hook (the same pipeline `aiwf update` calls).
Steps 1–3 write only if the artifact is missing; step 4 wipes-and- rewrites per the cache contract for derivable artifacts.
type StepResult ¶
StepResult is one line of init's per-step ledger.
func RefreshArtifacts ¶
func RefreshArtifacts(ctx context.Context, root string, opts RefreshOptions) ([]StepResult, bool, error)
RefreshArtifacts runs the wipe-and-rewrite pipeline shared by `aiwf init` (after first-time-only scaffolding) and `aiwf update`. All four steps return a StepResult; only the hook steps can produce a conflict (returned as the second value), at which point the caller surfaces remediation guidance to the user.
Step order:
- .claude/skills/aiwf-* (skills materialization)
- aiwf.yaml legacy `actor:` strip (idempotent)
- .gitignore (skill cache patterns)
- .git/hooks/pre-push (the validation chokepoint)
- .git/hooks/pre-commit (gated by StatusMdAutoUpdate)
SkipHooks bypasses both hook steps; each is reported as a SKipped row in the ledger so the user sees what was deliberately not done. StatusMdAutoUpdate=false drives ensurePreCommitHook into its uninstall path (removes a previously-installed marker-managed hook, leaves user-written hooks alone).