openplanr 0.1.0

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.
Files changed (146) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +168 -0
  3. package/bin/planr.js +2 -0
  4. package/dist/cli/commands/checklist.d.ts +3 -0
  5. package/dist/cli/commands/checklist.d.ts.map +1 -0
  6. package/dist/cli/commands/checklist.js +34 -0
  7. package/dist/cli/commands/checklist.js.map +1 -0
  8. package/dist/cli/commands/epic.d.ts +3 -0
  9. package/dist/cli/commands/epic.d.ts.map +1 -0
  10. package/dist/cli/commands/epic.js +61 -0
  11. package/dist/cli/commands/epic.js.map +1 -0
  12. package/dist/cli/commands/feature.d.ts +3 -0
  13. package/dist/cli/commands/feature.d.ts.map +1 -0
  14. package/dist/cli/commands/feature.js +65 -0
  15. package/dist/cli/commands/feature.js.map +1 -0
  16. package/dist/cli/commands/init.d.ts +3 -0
  17. package/dist/cli/commands/init.d.ts.map +1 -0
  18. package/dist/cli/commands/init.js +49 -0
  19. package/dist/cli/commands/init.js.map +1 -0
  20. package/dist/cli/commands/rules.d.ts +3 -0
  21. package/dist/cli/commands/rules.d.ts.map +1 -0
  22. package/dist/cli/commands/rules.js +48 -0
  23. package/dist/cli/commands/rules.js.map +1 -0
  24. package/dist/cli/commands/status.d.ts +3 -0
  25. package/dist/cli/commands/status.d.ts.map +1 -0
  26. package/dist/cli/commands/status.js +38 -0
  27. package/dist/cli/commands/status.js.map +1 -0
  28. package/dist/cli/commands/story.d.ts +3 -0
  29. package/dist/cli/commands/story.d.ts.map +1 -0
  30. package/dist/cli/commands/story.js +81 -0
  31. package/dist/cli/commands/story.js.map +1 -0
  32. package/dist/cli/commands/task.d.ts +3 -0
  33. package/dist/cli/commands/task.d.ts.map +1 -0
  34. package/dist/cli/commands/task.js +76 -0
  35. package/dist/cli/commands/task.js.map +1 -0
  36. package/dist/cli/index.d.ts +2 -0
  37. package/dist/cli/index.d.ts.map +1 -0
  38. package/dist/cli/index.js +27 -0
  39. package/dist/cli/index.js.map +1 -0
  40. package/dist/generators/base-generator.d.ts +9 -0
  41. package/dist/generators/base-generator.d.ts.map +1 -0
  42. package/dist/generators/base-generator.js +9 -0
  43. package/dist/generators/base-generator.js.map +1 -0
  44. package/dist/generators/claude-generator.d.ts +7 -0
  45. package/dist/generators/claude-generator.d.ts.map +1 -0
  46. package/dist/generators/claude-generator.js +27 -0
  47. package/dist/generators/claude-generator.js.map +1 -0
  48. package/dist/generators/codex-generator.d.ts +7 -0
  49. package/dist/generators/codex-generator.d.ts.map +1 -0
  50. package/dist/generators/codex-generator.js +22 -0
  51. package/dist/generators/codex-generator.js.map +1 -0
  52. package/dist/generators/cursor-generator.d.ts +7 -0
  53. package/dist/generators/cursor-generator.d.ts.map +1 -0
  54. package/dist/generators/cursor-generator.js +37 -0
  55. package/dist/generators/cursor-generator.js.map +1 -0
  56. package/dist/generators/generator-factory.d.ts +5 -0
  57. package/dist/generators/generator-factory.d.ts.map +1 -0
  58. package/dist/generators/generator-factory.js +19 -0
  59. package/dist/generators/generator-factory.js.map +1 -0
  60. package/dist/generators/generator-types.d.ts +4 -0
  61. package/dist/generators/generator-types.d.ts.map +1 -0
  62. package/dist/generators/generator-types.js +2 -0
  63. package/dist/generators/generator-types.js.map +1 -0
  64. package/dist/models/schema.d.ts +79 -0
  65. package/dist/models/schema.d.ts.map +1 -0
  66. package/dist/models/schema.js +22 -0
  67. package/dist/models/schema.js.map +1 -0
  68. package/dist/models/types.d.ts +78 -0
  69. package/dist/models/types.d.ts.map +1 -0
  70. package/dist/models/types.js +2 -0
  71. package/dist/models/types.js.map +1 -0
  72. package/dist/services/artifact-service.d.ts +17 -0
  73. package/dist/services/artifact-service.d.ts.map +1 -0
  74. package/dist/services/artifact-service.js +63 -0
  75. package/dist/services/artifact-service.js.map +1 -0
  76. package/dist/services/checklist-service.d.ts +6 -0
  77. package/dist/services/checklist-service.d.ts.map +1 -0
  78. package/dist/services/checklist-service.js +26 -0
  79. package/dist/services/checklist-service.js.map +1 -0
  80. package/dist/services/config-service.d.ts +5 -0
  81. package/dist/services/config-service.d.ts.map +1 -0
  82. package/dist/services/config-service.js +38 -0
  83. package/dist/services/config-service.js.map +1 -0
  84. package/dist/services/id-service.d.ts +6 -0
  85. package/dist/services/id-service.d.ts.map +1 -0
  86. package/dist/services/id-service.js +22 -0
  87. package/dist/services/id-service.js.map +1 -0
  88. package/dist/services/prompt-service.d.ts +9 -0
  89. package/dist/services/prompt-service.d.ts.map +1 -0
  90. package/dist/services/prompt-service.js +23 -0
  91. package/dist/services/prompt-service.js.map +1 -0
  92. package/dist/services/template-service.d.ts +2 -0
  93. package/dist/services/template-service.d.ts.map +1 -0
  94. package/dist/services/template-service.js +32 -0
  95. package/dist/services/template-service.js.map +1 -0
  96. package/dist/templates/adrs/adr-general.md.hbs +46 -0
  97. package/dist/templates/checklists/agile-checklist.md.hbs +49 -0
  98. package/dist/templates/epics/epic.md.hbs +46 -0
  99. package/dist/templates/features/feature.md.hbs +42 -0
  100. package/dist/templates/rules/claude/CLAUDE.md.hbs +63 -0
  101. package/dist/templates/rules/codex/AGENTS.md.hbs +28 -0
  102. package/dist/templates/rules/cursor/2000-agile-checklist.mdc.hbs +33 -0
  103. package/dist/templates/rules/cursor/2001-agile-create-epic.mdc.hbs +35 -0
  104. package/dist/templates/rules/cursor/2002-agile-create-features.mdc.hbs +35 -0
  105. package/dist/templates/rules/cursor/2003-agile-create-user-story.mdc.hbs +31 -0
  106. package/dist/templates/rules/cursor/2100-create-task-list.mdc.hbs +36 -0
  107. package/dist/templates/rules/cursor/2101-implement-task-list.mdc.hbs +28 -0
  108. package/dist/templates/stories/gherkin.feature.hbs +13 -0
  109. package/dist/templates/stories/user-story.md.hbs +28 -0
  110. package/dist/templates/tasks/task-list.md.hbs +24 -0
  111. package/dist/templates/templates/adrs/adr-general.md.hbs +46 -0
  112. package/dist/templates/templates/checklists/agile-checklist.md.hbs +49 -0
  113. package/dist/templates/templates/epics/epic.md.hbs +46 -0
  114. package/dist/templates/templates/features/feature.md.hbs +42 -0
  115. package/dist/templates/templates/rules/claude/CLAUDE.md.hbs +63 -0
  116. package/dist/templates/templates/rules/codex/AGENTS.md.hbs +28 -0
  117. package/dist/templates/templates/rules/cursor/2000-agile-checklist.mdc.hbs +33 -0
  118. package/dist/templates/templates/rules/cursor/2001-agile-create-epic.mdc.hbs +35 -0
  119. package/dist/templates/templates/rules/cursor/2002-agile-create-features.mdc.hbs +35 -0
  120. package/dist/templates/templates/rules/cursor/2003-agile-create-user-story.mdc.hbs +31 -0
  121. package/dist/templates/templates/rules/cursor/2100-create-task-list.mdc.hbs +36 -0
  122. package/dist/templates/templates/rules/cursor/2101-implement-task-list.mdc.hbs +28 -0
  123. package/dist/templates/templates/stories/gherkin.feature.hbs +13 -0
  124. package/dist/templates/templates/stories/user-story.md.hbs +28 -0
  125. package/dist/templates/templates/tasks/task-list.md.hbs +24 -0
  126. package/dist/utils/constants.d.ts +20 -0
  127. package/dist/utils/constants.d.ts.map +1 -0
  128. package/dist/utils/constants.js +26 -0
  129. package/dist/utils/constants.js.map +1 -0
  130. package/dist/utils/fs.d.ts +6 -0
  131. package/dist/utils/fs.d.ts.map +1 -0
  132. package/dist/utils/fs.js +26 -0
  133. package/dist/utils/fs.js.map +1 -0
  134. package/dist/utils/logger.d.ts +9 -0
  135. package/dist/utils/logger.d.ts.map +1 -0
  136. package/dist/utils/logger.js +22 -0
  137. package/dist/utils/logger.js.map +1 -0
  138. package/dist/utils/markdown.d.ts +7 -0
  139. package/dist/utils/markdown.d.ts.map +1 -0
  140. package/dist/utils/markdown.js +9 -0
  141. package/dist/utils/markdown.js.map +1 -0
  142. package/dist/utils/slugify.d.ts +2 -0
  143. package/dist/utils/slugify.d.ts.map +1 -0
  144. package/dist/utils/slugify.js +10 -0
  145. package/dist/utils/slugify.js.map +1 -0
  146. package/package.json +68 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 OpenPlanr Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,168 @@
1
+ # Planr
2
+
3
+ [![npm version](https://img.shields.io/npm/v/openplanr.svg)](https://www.npmjs.com/package/openplanr)
4
+ [![license](https://img.shields.io/npm/l/openplanr.svg)](https://github.com/TechArc-io/OpenPlanr/blob/main/LICENSE)
5
+ [![node](https://img.shields.io/node/v/openplanr.svg)](https://nodejs.org)
6
+
7
+ **Agile planning CLI for AI-assisted development.** Generate epics, features, user stories, tasks, and AI agent rules — all from your terminal.
8
+
9
+ Planr brings structured agile planning to AI coding workflows. Create planning artifacts with a simple CLI, then generate rule files that teach Cursor, Claude Code, or Codex how to follow your plan.
10
+
11
+ ---
12
+
13
+ ## Why Planr?
14
+
15
+ AI coding assistants are powerful but lack structured planning. Without a clear plan, they generate code that drifts from requirements. Planr solves this by:
16
+
17
+ 1. **Structuring your planning** — epics, features, stories, and tasks in markdown
18
+ 2. **Generating AI rules** — rule files that give your AI assistant context about the plan
19
+ 3. **Keeping everything in your repo** — artifacts live alongside your code, version-controlled
20
+
21
+ ## Quick Start
22
+
23
+ ```bash
24
+ # Install globally
25
+ npm install -g openplanr
26
+
27
+ # Initialize in your project
28
+ cd my-project
29
+ planr init
30
+
31
+ # Create your first epic
32
+ planr epic create
33
+
34
+ # Break it down
35
+ planr feature create --epic EPIC-001
36
+ planr story create --feature FEAT-001
37
+ planr task create --story US-001
38
+
39
+ # Generate AI rules for your editor
40
+ planr rules generate
41
+ ```
42
+
43
+ ## How It Works
44
+
45
+ ```
46
+ planr init
47
+ └── planr epic create # Define the big picture
48
+ └── planr feature create --epic EPIC-001 # Break into features
49
+ └── planr story create --feature FEAT-001 # User stories + Gherkin
50
+ └── planr task create --story US-001 # Implementation tasks
51
+
52
+ planr rules generate # Generate .cursor/rules, CLAUDE.md, AGENTS.md
53
+ ```
54
+
55
+ Each command creates markdown artifacts in `docs/agile/` and interactively prompts for the details. The hierarchy is enforced — features require an epic, stories require a feature, tasks require a story.
56
+
57
+ ## Supported AI Targets
58
+
59
+ | Target | Generated File(s) | Used By |
60
+ |--------|--------------------|---------|
61
+ | Cursor | `.cursor/rules/*.mdc` | Cursor IDE |
62
+ | Claude | `CLAUDE.md` | Claude Code CLI |
63
+ | Codex | `AGENTS.md` | OpenAI Codex CLI |
64
+
65
+ ```bash
66
+ planr rules generate # all targets
67
+ planr rules generate --target cursor # cursor only
68
+ planr rules generate --dry-run # preview
69
+ ```
70
+
71
+ ## Commands
72
+
73
+ | Command | Description |
74
+ |---------|-------------|
75
+ | `planr init` | Initialize project with config and directory structure |
76
+ | `planr epic create` | Create a new epic |
77
+ | `planr epic list` | List all epics |
78
+ | `planr feature create --epic <ID>` | Create a feature from an epic |
79
+ | `planr feature list` | List all features |
80
+ | `planr story create --feature <ID>` | Create a user story with Gherkin criteria |
81
+ | `planr story list` | List all user stories |
82
+ | `planr task create --story <ID>` | Create a task list from a story |
83
+ | `planr task list` | List all task lists |
84
+ | `planr task implement <ID>` | View tasks and start implementing |
85
+ | `planr checklist show` | View the agile development checklist |
86
+ | `planr checklist reset` | Reset checklist to initial state |
87
+ | `planr rules generate` | Generate AI agent rule files |
88
+ | `planr status` | Show planning progress overview |
89
+
90
+ See [docs/CLI.md](docs/CLI.md) for the full command reference with all options and flags.
91
+
92
+ ## Project Structure
93
+
94
+ After running `planr init` and creating artifacts:
95
+
96
+ ```
97
+ my-project/
98
+ ├── planr.config.json
99
+ ├── docs/agile/
100
+ │ ├── epics/ # EPIC-001-*.md
101
+ │ ├── features/ # FEAT-001-*.md
102
+ │ ├── stories/ # US-001-*.md + US-001-gherkin.feature
103
+ │ ├── tasks/ # TASK-001-*.md
104
+ │ ├── adrs/ # Architecture Decision Records
105
+ │ ├── checklists/ # Agile development checklist
106
+ │ └── diagrams/ # UML, C4, sequence diagrams
107
+ ├── .cursor/rules/ # Generated Cursor rules
108
+ ├── CLAUDE.md # Generated Claude Code rules
109
+ └── AGENTS.md # Generated Codex rules
110
+ ```
111
+
112
+ ## Configuration
113
+
114
+ `planr.config.json` is created by `planr init`:
115
+
116
+ ```json
117
+ {
118
+ "projectName": "my-project",
119
+ "targets": ["cursor", "claude", "codex"],
120
+ "outputPaths": {
121
+ "agile": "docs/agile",
122
+ "cursorRules": ".cursor/rules",
123
+ "claudeConfig": ".",
124
+ "codexConfig": "."
125
+ },
126
+ "idPrefix": {
127
+ "epic": "EPIC",
128
+ "feature": "FEAT",
129
+ "story": "US",
130
+ "task": "TASK"
131
+ }
132
+ }
133
+ ```
134
+
135
+ ## Development
136
+
137
+ ```bash
138
+ # Clone and install
139
+ git clone https://github.com/TechArc-io/OpenPlanr.git
140
+ cd openplanr
141
+ npm install
142
+
143
+ # Run from source
144
+ npx tsx src/cli/index.ts init
145
+
146
+ # Build
147
+ npm run build
148
+
149
+ # Run tests
150
+ npm test
151
+
152
+ # Link globally for development
153
+ npm install -g .
154
+ ```
155
+
156
+ ## Contributing
157
+
158
+ Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
159
+
160
+ 1. Fork the repository
161
+ 2. Create your feature branch (`git checkout -b feat/amazing-feature`)
162
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
163
+ 4. Push to the branch (`git push origin feat/amazing-feature`)
164
+ 5. Open a Pull Request
165
+
166
+ ## License
167
+
168
+ [MIT](LICENSE)
package/bin/planr.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/cli/index.js';
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerChecklistCommand(program: Command): void;
3
+ //# sourceMappingURL=checklist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checklist.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/checklist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,QAiCxD"}
@@ -0,0 +1,34 @@
1
+ import { loadConfig } from '../../services/config-service.js';
2
+ import { readChecklist, resetChecklist, createChecklist, } from '../../services/checklist-service.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export function registerChecklistCommand(program) {
5
+ const checklist = program
6
+ .command('checklist')
7
+ .description('Manage the agile development checklist');
8
+ checklist
9
+ .command('show')
10
+ .description('Display the agile development checklist')
11
+ .action(async () => {
12
+ const projectDir = program.opts().projectDir;
13
+ const config = await loadConfig(projectDir);
14
+ let content = await readChecklist(projectDir, config);
15
+ if (!content) {
16
+ logger.info('No checklist found. Creating one...');
17
+ await createChecklist(projectDir, config);
18
+ content = await readChecklist(projectDir, config);
19
+ }
20
+ if (content) {
21
+ console.log(content);
22
+ }
23
+ });
24
+ checklist
25
+ .command('reset')
26
+ .description('Reset the checklist to its initial state')
27
+ .action(async () => {
28
+ const projectDir = program.opts().projectDir;
29
+ const config = await loadConfig(projectDir);
30
+ await resetChecklist(projectDir, config);
31
+ logger.success('Checklist has been reset.');
32
+ });
33
+ }
34
+ //# sourceMappingURL=checklist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checklist.js","sourceRoot":"","sources":["../../../src/cli/commands/checklist.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EACL,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,MAAM,UAAU,wBAAwB,CAAC,OAAgB;IACvD,MAAM,SAAS,GAAG,OAAO;SACtB,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,wCAAwC,CAAC,CAAC;IAEzD,SAAS;SACN,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,UAAoB,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;QAE5C,IAAI,OAAO,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;YACnD,MAAM,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAC1C,OAAO,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACpD,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,SAAS;SACN,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,0CAA0C,CAAC;SACvD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,UAAoB,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACzC,MAAM,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerEpicCommand(program: Command): void;
3
+ //# sourceMappingURL=epic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epic.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/epic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,QAqEnD"}
@@ -0,0 +1,61 @@
1
+ import { loadConfig } from '../../services/config-service.js';
2
+ import { createArtifact, listArtifacts } from '../../services/artifact-service.js';
3
+ import { promptText, promptMultiText } from '../../services/prompt-service.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ export function registerEpicCommand(program) {
6
+ const epic = program.command('epic').description('Manage epics');
7
+ epic
8
+ .command('create')
9
+ .description('Create a new epic')
10
+ .option('--title <title>', 'epic title')
11
+ .option('--owner <owner>', 'epic owner')
12
+ .action(async (opts) => {
13
+ const projectDir = program.opts().projectDir;
14
+ const config = await loadConfig(projectDir);
15
+ logger.heading('Create Epic');
16
+ const title = opts.title || (await promptText('Epic title:'));
17
+ const owner = opts.owner || (await promptText('Owner:', config.author));
18
+ const businessValue = await promptText('Business value:');
19
+ const targetUsers = await promptText('Target users:');
20
+ const problemStatement = await promptText('Problem statement:');
21
+ const solutionOverview = await promptText('Solution overview:');
22
+ const successCriteria = await promptText('Success criteria:');
23
+ const keyFeatures = await promptMultiText('Key features', 'comma-separated');
24
+ const dependencies = await promptText('Dependencies:', 'None');
25
+ const risks = await promptText('Risks:', 'None');
26
+ const { id, filePath } = await createArtifact(projectDir, config, 'epic', 'epics/epic.md.hbs', {
27
+ title,
28
+ owner,
29
+ businessValue,
30
+ targetUsers,
31
+ problemStatement,
32
+ solutionOverview,
33
+ successCriteria,
34
+ keyFeatures,
35
+ dependencies,
36
+ risks,
37
+ featureIds: [],
38
+ });
39
+ logger.success(`Created epic ${id}: ${title}`);
40
+ logger.dim(` ${filePath}`);
41
+ logger.dim('');
42
+ logger.dim(`Next: planr feature create --epic ${id}`);
43
+ });
44
+ epic
45
+ .command('list')
46
+ .description('List all epics')
47
+ .action(async () => {
48
+ const projectDir = program.opts().projectDir;
49
+ const config = await loadConfig(projectDir);
50
+ const epics = await listArtifacts(projectDir, config, 'epic');
51
+ if (epics.length === 0) {
52
+ logger.info('No epics found. Run "planr epic create" to create one.');
53
+ return;
54
+ }
55
+ logger.heading('Epics');
56
+ for (const epic of epics) {
57
+ console.log(` ${epic.id} ${epic.title}`);
58
+ }
59
+ });
60
+ }
61
+ //# sourceMappingURL=epic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epic.js","sourceRoot":"","sources":["../../../src/cli/commands/epic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerFeatureCommand(program: Command): void;
3
+ //# sourceMappingURL=feature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/feature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,QA6EtD"}
@@ -0,0 +1,65 @@
1
+ import { loadConfig } from '../../services/config-service.js';
2
+ import { createArtifact, listArtifacts, readArtifact } from '../../services/artifact-service.js';
3
+ import { promptText, promptMultiText } from '../../services/prompt-service.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ export function registerFeatureCommand(program) {
6
+ const feature = program.command('feature').description('Manage features');
7
+ feature
8
+ .command('create')
9
+ .description('Create a new feature from an epic')
10
+ .requiredOption('--epic <epicId>', 'parent epic ID (e.g., EPIC-001)')
11
+ .option('--title <title>', 'feature title')
12
+ .action(async (opts) => {
13
+ const projectDir = program.opts().projectDir;
14
+ const config = await loadConfig(projectDir);
15
+ // Verify epic exists
16
+ const epicData = await readArtifact(projectDir, config, 'epic', opts.epic);
17
+ if (!epicData) {
18
+ logger.error(`Epic ${opts.epic} not found.`);
19
+ process.exit(1);
20
+ }
21
+ logger.heading(`Create Feature (from ${opts.epic})`);
22
+ const title = opts.title || (await promptText('Feature title:'));
23
+ const owner = await promptText('Owner:', config.author);
24
+ const overview = await promptText('Overview:');
25
+ const functionalRequirements = await promptMultiText('Functional requirements', 'comma-separated');
26
+ const dependencies = await promptText('Dependencies:', 'None');
27
+ const technicalConsiderations = await promptText('Technical considerations:', 'None');
28
+ const risks = await promptText('Risks:', 'None');
29
+ const successMetrics = await promptText('Success metrics:');
30
+ const { id, filePath } = await createArtifact(projectDir, config, 'feature', 'features/feature.md.hbs', {
31
+ title,
32
+ epicId: opts.epic,
33
+ owner,
34
+ overview,
35
+ functionalRequirements,
36
+ dependencies,
37
+ technicalConsiderations,
38
+ risks,
39
+ successMetrics,
40
+ storyIds: [],
41
+ });
42
+ logger.success(`Created feature ${id}: ${title}`);
43
+ logger.dim(` ${filePath}`);
44
+ logger.dim('');
45
+ logger.dim(`Next: planr story create --feature ${id}`);
46
+ });
47
+ feature
48
+ .command('list')
49
+ .description('List features')
50
+ .option('--epic <epicId>', 'filter by epic ID')
51
+ .action(async (opts) => {
52
+ const projectDir = program.opts().projectDir;
53
+ const config = await loadConfig(projectDir);
54
+ const features = await listArtifacts(projectDir, config, 'feature');
55
+ if (features.length === 0) {
56
+ logger.info('No features found. Run "planr feature create --epic <ID>" to create one.');
57
+ return;
58
+ }
59
+ logger.heading('Features');
60
+ for (const f of features) {
61
+ console.log(` ${f.id} ${f.title}`);
62
+ }
63
+ });
64
+ }
65
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature.js","sourceRoot":"","sources":["../../../src/cli/commands/feature.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerInitCommand(program: Command): void;
3
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,QAkDnD"}
@@ -0,0 +1,49 @@
1
+ import path from 'node:path';
2
+ import { createDefaultConfig, saveConfig } from '../../services/config-service.js';
3
+ import { createChecklist } from '../../services/checklist-service.js';
4
+ import { ensureDir } from '../../utils/fs.js';
5
+ import { fileExists } from '../../utils/fs.js';
6
+ import { CONFIG_FILENAME, ARTIFACT_DIRS } from '../../utils/constants.js';
7
+ import { logger } from '../../utils/logger.js';
8
+ import { promptText, promptConfirm } from '../../services/prompt-service.js';
9
+ export function registerInitCommand(program) {
10
+ program
11
+ .command('init')
12
+ .description('Initialize Planr in the current project')
13
+ .option('--name <name>', 'project name')
14
+ .action(async (opts) => {
15
+ const projectDir = program.opts().projectDir;
16
+ const configPath = path.join(projectDir, CONFIG_FILENAME);
17
+ if (await fileExists(configPath)) {
18
+ const overwrite = await promptConfirm(`${CONFIG_FILENAME} already exists. Overwrite?`, false);
19
+ if (!overwrite) {
20
+ logger.info('Init cancelled.');
21
+ return;
22
+ }
23
+ }
24
+ const projectName = opts.name || (await promptText('Project name:', path.basename(projectDir)));
25
+ const config = createDefaultConfig(projectName);
26
+ // Create directory structure
27
+ const agileDir = path.join(projectDir, config.outputPaths.agile);
28
+ for (const dir of Object.values(ARTIFACT_DIRS)) {
29
+ await ensureDir(path.join(agileDir, dir));
30
+ }
31
+ // Also create diagrams dir
32
+ await ensureDir(path.join(agileDir, 'diagrams'));
33
+ // Save config
34
+ await saveConfig(projectDir, config);
35
+ logger.success(`Created ${CONFIG_FILENAME}`);
36
+ // Create checklist
37
+ const checklistPath = await createChecklist(projectDir, config);
38
+ logger.success(`Created agile development checklist`);
39
+ logger.heading('Planr initialized!');
40
+ logger.info(`Project: ${projectName}`);
41
+ logger.info(`Artifacts: ${config.outputPaths.agile}/`);
42
+ logger.dim('');
43
+ logger.dim('Next steps:');
44
+ logger.dim(' planr epic create — Create your first epic');
45
+ logger.dim(' planr rules generate — Generate AI agent rules');
46
+ logger.dim(' planr checklist show — View the agile checklist');
47
+ });
48
+ }
49
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerRulesCommand(program: Command): void;
3
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAiDpD"}
@@ -0,0 +1,48 @@
1
+ import { loadConfig } from '../../services/config-service.js';
2
+ import { createGenerators, createGenerator } from '../../generators/generator-factory.js';
3
+ import { writeFile, ensureDir } from '../../utils/fs.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import path from 'node:path';
6
+ export function registerRulesCommand(program) {
7
+ program
8
+ .command('rules')
9
+ .description('Generate AI agent rule files')
10
+ .command('generate')
11
+ .description('Generate rule files for configured AI CLIs')
12
+ .option('--target <target>', 'specific target: cursor, claude, codex, or all', 'all')
13
+ .option('--dry-run', 'show what would be generated without writing files', false)
14
+ .action(async (opts) => {
15
+ const projectDir = program.opts().projectDir;
16
+ const config = await loadConfig(projectDir);
17
+ // Empty artifact collection — generators read from disk as needed
18
+ const artifacts = {
19
+ epics: [],
20
+ features: [],
21
+ stories: [],
22
+ tasks: [],
23
+ };
24
+ const generators = opts.target === 'all'
25
+ ? createGenerators(config, projectDir)
26
+ : [createGenerator(opts.target, config, projectDir)];
27
+ logger.heading('Generating AI Agent Rules');
28
+ let totalFiles = 0;
29
+ for (const generator of generators) {
30
+ const files = await generator.generate(artifacts);
31
+ logger.info(`${generator.getTargetName()}: ${files.length} file(s)`);
32
+ for (const file of files) {
33
+ const fullPath = path.join(projectDir, file.path);
34
+ if (opts.dryRun) {
35
+ logger.dim(` [dry-run] ${file.path}`);
36
+ }
37
+ else {
38
+ await ensureDir(path.dirname(fullPath));
39
+ await writeFile(fullPath, file.content);
40
+ logger.dim(` ${file.path}`);
41
+ }
42
+ totalFiles++;
43
+ }
44
+ }
45
+ logger.success(`${opts.dryRun ? 'Would generate' : 'Generated'} ${totalFiles} rule file(s)`);
46
+ });
47
+ }
48
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../../src/cli/commands/rules.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,8BAA8B,CAAC;SAC3C,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,4CAA4C,CAAC;SACzD,MAAM,CAAC,mBAAmB,EAAE,gDAAgD,EAAE,KAAK,CAAC;SACpF,MAAM,CAAC,WAAW,EAAE,oDAAoD,EAAE,KAAK,CAAC;SAChF,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,UAAoB,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;QAE5C,kEAAkE;QAClE,MAAM,SAAS,GAAuB;YACpC,KAAK,EAAE,EAAE;YACT,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,EAAE;YACX,KAAK,EAAE,EAAE;SACV,CAAC;QAEF,MAAM,UAAU,GACd,IAAI,CAAC,MAAM,KAAK,KAAK;YACnB,CAAC,CAAC,gBAAgB,CAAC,MAAM,EAAE,UAAU,CAAC;YACtC,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,MAAmB,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;QAEtE,MAAM,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;QAC5C,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,aAAa,EAAE,KAAK,KAAK,CAAC,MAAM,UAAU,CAAC,CAAC;YAErE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAClD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBAChB,MAAM,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBACzC,CAAC;qBAAM,CAAC;oBACN,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACxC,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;oBACxC,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC/B,CAAC;gBACD,UAAU,EAAE,CAAC;YACf,CAAC;QACH,CAAC;QAED,MAAM,CAAC,OAAO,CACZ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,IAAI,UAAU,eAAe,CAC7E,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerStatusCommand(program: Command): void;
3
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,QAqCrD"}
@@ -0,0 +1,38 @@
1
+ import { loadConfig } from '../../services/config-service.js';
2
+ import { listArtifacts } from '../../services/artifact-service.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ export function registerStatusCommand(program) {
5
+ program
6
+ .command('status')
7
+ .description('Show project planning status')
8
+ .action(async () => {
9
+ const projectDir = program.opts().projectDir;
10
+ const config = await loadConfig(projectDir);
11
+ logger.heading(`OpenPlanr Status — ${config.projectName}`);
12
+ console.log('');
13
+ const types = [
14
+ { type: 'epic', label: 'Epics' },
15
+ { type: 'feature', label: 'Features' },
16
+ { type: 'story', label: 'User Stories' },
17
+ { type: 'task', label: 'Task Lists' },
18
+ ];
19
+ for (const { type, label } of types) {
20
+ const items = await listArtifacts(projectDir, config, type);
21
+ const count = items.length;
22
+ const icon = count > 0 ? '●' : '○';
23
+ console.log(` ${icon} ${label}: ${count}`);
24
+ if (count > 0) {
25
+ for (const item of items.slice(0, 5)) {
26
+ console.log(` ${item.id} ${item.title}`);
27
+ }
28
+ if (count > 5) {
29
+ console.log(` ... and ${count - 5} more`);
30
+ }
31
+ }
32
+ }
33
+ console.log('');
34
+ logger.dim('Targets: ' + config.targets.join(', '));
35
+ logger.dim('Artifacts: ' + config.outputPaths.agile + '/');
36
+ });
37
+ }
38
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAG/C,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,8BAA8B,CAAC;SAC3C,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,UAAoB,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;QAE5C,MAAM,CAAC,OAAO,CAAC,sBAAsB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,MAAM,KAAK,GAAiD;YAC1D,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE;YAChC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE;YACtC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE;YACxC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE;SACtC,CAAC;QAEF,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,KAAK,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;YAC5D,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;YAC3B,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC,CAAC;YAC5C,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACd,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;oBACrC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC/C,CAAC;gBACD,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;oBACd,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,MAAM,CAAC,GAAG,CAAC,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACpD,MAAM,CAAC,GAAG,CAAC,aAAa,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerStoryCommand(program: Command): void;
3
+ //# sourceMappingURL=story.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"story.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/story.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QA8FpD"}