EnsureGitignore writes a minimal .gitignore (.ctask/ +
logs/sessions.log) iff one does not already exist. This is the
file-system half of the v0.3 seed-wins rule for .gitignore: if
either the general or project seed copied a .gitignore into the
workspace, EnsureGitignore must be a no-op.
GitAvailable + RunGitInit wrap exec.LookPath("git") and `git init`
respectively, so the caller in cmd/new.go can decide whether to
print the informational note when git is missing.
Tests cover:
- missing -> created with the minimal body
- present -> preserved verbatim
- integration: general seed .gitignore preserved end-to-end
- integration: project seed .gitignore preserved end-to-end
- integration: no seed -> minimal body created
When SkipCategoryDir is true, Create places the workspace directly
under Root and does not append a Category subdirectory. This is the
mechanism that prevents doubled paths like
~/projects/projects/<slug> when the user sets CTASK_PROJECT_ROOT
without an explicit -c flag. The Category value is still recorded
on TaskMeta so list/info/filter still work.
CreateOpts gains IsProject, SeedDir, and ProjectSeedDir. The new
seeding flow is:
1. write built-in defaults (task or project CLAUDE.md + notes.md)
2. apply general seed if SeedDir != "" (overlay)
3. apply project seed if IsProject && ProjectSeedDir != "" (overlay)
4. write task.yaml (last, so seeds can never inject metadata)
The obsolete TestCreateDoesNotOverwriteSeedFiles test is removed:
its v0.2 invariant ("don't overwrite existing files") no longer
holds because v0.3 always lays defaults onto a fresh dir and seeds
are expected to overwrite.
TaskMeta now records type: task or type: project. EffectiveType
returns 'task' for missing/empty/unknown values and for nil meta,
so v0.2 workspaces continue to read as tasks without any
migration. The field is placed between Category and Mode in the
YAML output. Tests cover the round-trip and the legacy
no-type-field case.
Create function produces full workspace layout (task.yaml, CLAUDE.md, notes.md, context/, output/, logs/). Seed files only written if missing. Collision suffixing tested.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Slugify, AutoTitle, DirName, ResolveDir with -2, -3 suffixing. Full test coverage.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TaskMeta struct matching task.yaml schema exactly. Tests for roundtrip, field presence, and archive state.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>