planager 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
planager/__init__.py ADDED
@@ -0,0 +1 @@
1
+ """planager — Feature plans for LLM-assisted development."""
planager/cli.py ADDED
@@ -0,0 +1,112 @@
1
+ """CLI entry point: `planager init` sets up a project for plan-based development."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import shutil
7
+ import sys
8
+ from importlib.resources import files
9
+ from pathlib import Path
10
+
11
+ SNIPPET_MARKER = "<!-- planager:start -->"
12
+ SNIPPET_END_MARKER = "<!-- planager:end -->"
13
+
14
+ TEMPLATES = files("planager.templates")
15
+
16
+
17
+ def get_template_path() -> Path:
18
+ """Resolve the templates directory to a filesystem path."""
19
+ return Path(str(TEMPLATES))
20
+
21
+
22
+ def init_project(target: Path) -> list[str]:
23
+ """Install planager files into *target* project directory.
24
+
25
+ Returns a list of actions taken (for user feedback).
26
+ """
27
+ actions: list[str] = []
28
+ template_dir = get_template_path()
29
+
30
+ # 1. Create .plans/ directory
31
+ plans_dir = target / ".plans"
32
+ if not plans_dir.exists():
33
+ plans_dir.mkdir(parents=True)
34
+ actions.append("Created .plans/")
35
+ else:
36
+ actions.append(".plans/ already exists, skipped")
37
+
38
+ # 2. Copy skill files
39
+ skills_dir = target / ".claude" / "skills"
40
+ for skill_name in ("plan", "plan-status"):
41
+ skill_dest = skills_dir / skill_name / "SKILL.md"
42
+ skill_src = template_dir / skill_name / "SKILL.md"
43
+
44
+ if skill_dest.exists():
45
+ actions.append(f".claude/skills/{skill_name}/SKILL.md already exists, skipped")
46
+ else:
47
+ skill_dest.parent.mkdir(parents=True, exist_ok=True)
48
+ shutil.copy2(str(skill_src), str(skill_dest))
49
+ actions.append(f"Created .claude/skills/{skill_name}/SKILL.md")
50
+
51
+ # 3. Append CLAUDE.md snippet
52
+ claude_md = target / "CLAUDE.md"
53
+ snippet = (template_dir / "CLAUDE.md.snippet").read_text()
54
+ wrapped_snippet = f"{SNIPPET_MARKER}\n{snippet}{SNIPPET_END_MARKER}\n"
55
+
56
+ if claude_md.exists():
57
+ existing = claude_md.read_text()
58
+ if SNIPPET_MARKER in existing:
59
+ actions.append("CLAUDE.md already has planager snippet, skipped")
60
+ else:
61
+ with claude_md.open("a") as f:
62
+ f.write("\n" + wrapped_snippet)
63
+ actions.append("Appended planager snippet to CLAUDE.md")
64
+ else:
65
+ claude_md.write_text(wrapped_snippet)
66
+ actions.append("Created CLAUDE.md with planager snippet")
67
+
68
+ return actions
69
+
70
+
71
+ def main(argv: list[str] | None = None) -> int:
72
+ parser = argparse.ArgumentParser(
73
+ prog="planager",
74
+ description="Feature plans for LLM-assisted development.",
75
+ )
76
+ sub = parser.add_subparsers(dest="command")
77
+
78
+ init_parser = sub.add_parser(
79
+ "init",
80
+ help="Set up the current project for plan-based development.",
81
+ )
82
+ init_parser.add_argument(
83
+ "--path",
84
+ type=Path,
85
+ default=Path.cwd(),
86
+ help="Project root directory (default: current directory).",
87
+ )
88
+
89
+ args = parser.parse_args(argv)
90
+
91
+ if args.command is None:
92
+ parser.print_help()
93
+ return 1
94
+
95
+ if args.command == "init":
96
+ target = args.path.resolve()
97
+ if not target.is_dir():
98
+ print(f"Error: {target} is not a directory.", file=sys.stderr)
99
+ return 1
100
+
101
+ actions = init_project(target)
102
+ print(f"Initialized planager in {target}\n")
103
+ for action in actions:
104
+ print(f" {action}")
105
+ print("\nDone. Start a Claude Code session and plans will work automatically.")
106
+ return 0
107
+
108
+ return 1
109
+
110
+
111
+ if __name__ == "__main__":
112
+ raise SystemExit(main())
@@ -0,0 +1,75 @@
1
+
2
+ # Feature Plans
3
+
4
+ This project uses **planager** for structured feature planning. Plans are
5
+ markdown files in `.plans/` with phased steps and checkboxes.
6
+
7
+ ## Automatic behavior
8
+
9
+ ### On session start
10
+
11
+ Check `.plans/` for any plans with `status: in-progress` or `status: blocked`.
12
+ If any exist, briefly note them to the user (e.g. "There's an in-progress plan
13
+ for <title>"). If the user's request clearly relates to one, read it and resume
14
+ from the first unchecked step. Don't force it — if the user is asking about
15
+ something unrelated, just mention the plan exists and move on.
16
+
17
+ ### When starting new feature work
18
+
19
+ Before writing code for a non-trivial feature, create a plan:
20
+
21
+ 1. Ask the user for a brief description (if not already provided).
22
+ 2. Explore the codebase to understand what's involved.
23
+ 3. Draft a phased plan with concrete, checkable steps.
24
+ 4. Present the plan to the user for approval.
25
+ 5. Save the approved plan to `.plans/<feature-slug>.md`.
26
+ 6. Begin implementation from Phase 1.
27
+
28
+ Skip planning for trivial tasks (single-file fixes, typos, config changes).
29
+ Use judgment — if the work spans multiple files or sessions, it deserves a plan.
30
+
31
+ ### While working on a planned feature
32
+
33
+ - Check off steps (`- [x]`) as they are completed.
34
+ - Add notes to the `## Notes` section for decisions, blockers, or alternatives
35
+ considered.
36
+ - Update the `updated` date in frontmatter.
37
+ - Set `status: in-progress` when work begins (if still `planning`).
38
+ - If blocked, set `status: blocked` and note the reason.
39
+
40
+ ### On completion
41
+
42
+ - Set `status: done` in frontmatter.
43
+ - Write a brief summary in `## Notes` of what was built.
44
+ - Check off all remaining steps.
45
+
46
+ ## Plan format
47
+
48
+ ```markdown
49
+ ---
50
+ feature: short-slug
51
+ title: Human-Readable Title
52
+ status: planning | in-progress | blocked | done
53
+ created: YYYY-MM-DD
54
+ updated: YYYY-MM-DD
55
+ ---
56
+
57
+ ## Context
58
+
59
+ What the feature is, why it matters, constraints, links to issues or docs.
60
+
61
+ ## Phase 1: <title>
62
+
63
+ Brief description of this phase.
64
+
65
+ - [ ] Step description
66
+ - [ ] Step description
67
+
68
+ ## Phase 2: <title>
69
+
70
+ - [ ] Step description
71
+
72
+ ## Notes
73
+
74
+ Running log of decisions, blockers, things tried.
75
+ ```
File without changes
@@ -0,0 +1,35 @@
1
+ # /plan — Create or resume a feature plan
2
+
3
+ When the user invokes `/plan`, follow this workflow.
4
+
5
+ ## If given a description (e.g. `/plan add dark mode support`)
6
+
7
+ 1. Choose a short slug from the description (e.g. `dark-mode`).
8
+ 2. Check if `.plans/<slug>.md` already exists.
9
+ - If it does and is `in-progress`, switch to the **resume** flow below.
10
+ - If it does and is `done`, tell the user and ask if they want a new plan.
11
+ 3. Explore the codebase to understand what the feature involves:
12
+ - Read relevant files, check existing patterns, identify what needs to change.
13
+ 4. Draft a phased plan with concrete steps. Each step should be small enough
14
+ to complete in one action (a file edit, a test run, etc.).
15
+ 5. Present the plan to the user. Ask for approval or adjustments.
16
+ 6. Save the approved plan to `.plans/<slug>.md` with `status: planning`.
17
+ 7. Ask the user if they want to begin implementation now.
18
+ - If yes, set `status: in-progress` and start from Phase 1, step 1.
19
+
20
+ ## If invoked without a description (e.g. just `/plan`)
21
+
22
+ 1. Glob `.plans/*.md` and read the frontmatter of each.
23
+ 2. List any `in-progress` or `blocked` plans.
24
+ 3. If there are in-progress plans, ask the user:
25
+ - Resume one of them? (default if there's only one)
26
+ - Or create a new plan?
27
+ 4. If creating new, ask for a brief description and follow the flow above.
28
+
29
+ ## Resume flow
30
+
31
+ 1. Read the full plan file.
32
+ 2. Summarize current status: which phases are done, what's next.
33
+ 3. Begin work from the first unchecked step.
34
+ 4. Follow the standard plan update behavior (check steps, add notes, update
35
+ frontmatter) as you work.
@@ -0,0 +1,22 @@
1
+ # /plan-status — Show status of all feature plans
2
+
3
+ When the user invokes `/plan-status`, do the following:
4
+
5
+ 1. Glob `.plans/*.md` to find all plan files.
6
+ 2. If no plans exist, say so and exit.
7
+ 3. For each plan file, read it and extract:
8
+ - `feature` and `title` from frontmatter
9
+ - `status` from frontmatter
10
+ - Checkbox counts: total `- [ ]` and `- [x]` lines per `## Phase N:` section
11
+ - Overall progress: completed steps / total steps
12
+ 4. Print a summary table, for example:
13
+
14
+ ```
15
+ Feature Status Progress
16
+ ─────────────── ─────────── ────────────────
17
+ auth in-progress Phase 2: 3/7
18
+ dark-mode planning Phase 1: 0/4
19
+ api-v2 done 5/5
20
+ ```
21
+
22
+ 5. If any plan is `blocked`, show the reason from the Notes section if available.
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.4
2
+ Name: planager
3
+ Version: 0.1.1
4
+ Summary: Feature plans for LLM-assisted development. One command sets up your project so coding agents automatically create, follow, and maintain structured plans.
5
+ Project-URL: Repository, https://github.com/forest-d/planager
6
+ Author: forest-d
7
+ License-Expression: MIT
8
+ Keywords: claude,codex,development,llm,planning
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Topic :: Software Development
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+
16
+ # planager
17
+
18
+ Feature plans for LLM-assisted development.
19
+
20
+ One command sets up your project so coding agents (Claude Code, Codex, etc.)
21
+ automatically create, follow, and maintain structured feature plans across
22
+ sessions.
23
+
24
+ ## Install
25
+
26
+ ```bash
27
+ cd your-project
28
+ uvx planager init
29
+ ```
30
+
31
+ That's it. No runtime dependencies, no background processes. The command copies
32
+ a few template files into your project and you're done.
33
+
34
+ ## What it does
35
+
36
+ After `planager init`, your project gets:
37
+
38
+ - **`.plans/`** — directory where feature plans live (markdown files).
39
+ - **`.claude/skills/plan/`** — a `/plan` slash command for creating and resuming plans.
40
+ - **`.claude/skills/plan-status/`** — a `/plan-status` slash command for checking progress.
41
+ - **CLAUDE.md snippet** — instructions that make the agent automatically discover
42
+ and follow plans without you having to ask.
43
+
44
+ ## How it works
45
+
46
+ Plans are markdown files with frontmatter, phased steps, and checkboxes:
47
+
48
+ ```markdown
49
+ ---
50
+ feature: auth
51
+ title: User Authentication
52
+ status: in-progress
53
+ created: 2026-04-18
54
+ updated: 2026-04-18
55
+ ---
56
+
57
+ ## Context
58
+
59
+ Implement email/password authentication with session management.
60
+
61
+ ## Phase 1: Database schema
62
+
63
+ - [x] Create users table migration
64
+ - [x] Add password hashing utility
65
+ - [ ] Add session table migration
66
+
67
+ ## Phase 2: API endpoints
68
+
69
+ - [ ] POST /login
70
+ - [ ] POST /register
71
+
72
+ ## Notes
73
+
74
+ Using bcrypt for hashing. Decided against JWT — sessions are simpler for now.
75
+ ```
76
+
77
+ The CLAUDE.md snippet teaches the agent to:
78
+
79
+ 1. **Check for in-progress plans** at the start of each session.
80
+ 2. **Create plans** before starting non-trivial features.
81
+ 3. **Update plans** as work progresses (check off steps, add notes).
82
+ 4. **Mark plans done** when a feature is complete.
83
+
84
+ No special tools or MCP servers — the agent reads and writes plain markdown files.
85
+
86
+ ## Slash commands
87
+
88
+ ### `/plan`
89
+
90
+ Create a new feature plan or resume an existing one.
91
+
92
+ - With a description: `/plan add dark mode support` — explores the codebase,
93
+ drafts a phased plan, asks for approval.
94
+ - Without: `/plan` — lists in-progress plans and offers to resume or create new.
95
+
96
+ ### `/plan-status`
97
+
98
+ Show progress across all plans:
99
+
100
+ ```
101
+ Feature Status Progress
102
+ ─────────────── ─────────── ────────────────
103
+ auth in-progress Phase 2: 3/7
104
+ dark-mode planning Phase 1: 0/4
105
+ api-v2 done 5/5
106
+ ```
107
+
108
+ ## Idempotent
109
+
110
+ Running `uvx planager init` again is safe — it skips files that already exist
111
+ and won't duplicate the CLAUDE.md snippet.
112
+
113
+ ## License
114
+
115
+ MIT
@@ -0,0 +1,10 @@
1
+ planager/__init__.py,sha256=epy7RGoiiClOFva8dyElWibyIU08Gg-yfLZa4uPhsQA,63
2
+ planager/cli.py,sha256=YR6mSHleEA-W3zE3qt-fArBFlIbu332biGMc5j2K18g,3440
3
+ planager/templates/CLAUDE.md.snippet,sha256=CitSzrtFmsinSA5czhct5tKBLM9GJtiHtZK07AysQgg,2131
4
+ planager/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ planager/templates/plan/SKILL.md,sha256=thTGhlRWHXtcNqMQbAFhZfsJgdvSEI_25w9-0i3NDC0,1607
6
+ planager/templates/plan-status/SKILL.md,sha256=tLq43-wYicmIdFy6dwtXOfIIlu4F-3NL9VTHSfUuB2o,868
7
+ planager-0.1.1.dist-info/METADATA,sha256=AzRxt7hfdsuQO3lpKV2q-dEB0Qh7xpOUrNW4AowClsY,3222
8
+ planager-0.1.1.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
9
+ planager-0.1.1.dist-info/entry_points.txt,sha256=RNKI-EOTSugD0VaOWu5AguWHdE_otCzdSNG0-vLW4dc,47
10
+ planager-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ planager = planager.cli:main