plankit-cli 1.3.0 → 1.4.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.
- package/README.md +229 -34
- package/package.json +1 -1
- package/src/agents.js +8 -4
- package/src/cli.js +126 -5
- package/src/commandBundles.js +105 -0
- package/src/config.js +20 -2
- package/templates/PLANKIT.md +7 -0
- package/templates/dotnet-commands/codex/dotnet-architecture-audit.md +25 -0
- package/templates/dotnet-commands/codex/dotnet-clean-guardrails.md +24 -0
- package/templates/dotnet-commands/codex/dotnet-ef-migration.md +25 -0
- package/templates/dotnet-commands/codex/dotnet-endpoint-from-model.md +26 -0
- package/templates/dotnet-commands/codex/dotnet-extract-service.md +25 -0
- package/templates/dotnet-commands/codex/dotnet-feature.md +26 -0
- package/templates/dotnet-commands/codex/dotnet-generate-tests.md +25 -0
- package/templates/dotnet-commands/codex/dotnet-health.md +24 -0
- package/templates/dotnet-commands/codex/dotnet-migrate-minimal-api.md +25 -0
- package/templates/dotnet-commands/codex/dotnet-modernize.md +25 -0
- package/templates/dotnet-commands/cursor/dotnet-architecture-audit.md +26 -0
- package/templates/dotnet-commands/cursor/dotnet-clean-guardrails.md +25 -0
- package/templates/dotnet-commands/cursor/dotnet-ef-migration.md +26 -0
- package/templates/dotnet-commands/cursor/dotnet-endpoint-from-model.md +27 -0
- package/templates/dotnet-commands/cursor/dotnet-extract-service.md +26 -0
- package/templates/dotnet-commands/cursor/dotnet-feature.md +27 -0
- package/templates/dotnet-commands/cursor/dotnet-generate-tests.md +26 -0
- package/templates/dotnet-commands/cursor/dotnet-health.md +25 -0
- package/templates/dotnet-commands/cursor/dotnet-migrate-minimal-api.md +26 -0
- package/templates/dotnet-commands/cursor/dotnet-modernize.md +26 -0
- package/templates/dotnet-commands/opencode/dotnet-architecture-audit.md +23 -0
- package/templates/dotnet-commands/opencode/dotnet-clean-guardrails.md +22 -0
- package/templates/dotnet-commands/opencode/dotnet-ef-migration.md +23 -0
- package/templates/dotnet-commands/opencode/dotnet-endpoint-from-model.md +24 -0
- package/templates/dotnet-commands/opencode/dotnet-extract-service.md +23 -0
- package/templates/dotnet-commands/opencode/dotnet-feature.md +24 -0
- package/templates/dotnet-commands/opencode/dotnet-generate-tests.md +23 -0
- package/templates/dotnet-commands/opencode/dotnet-health.md +22 -0
- package/templates/dotnet-commands/opencode/dotnet-migrate-minimal-api.md +23 -0
- package/templates/dotnet-commands/opencode/dotnet-modernize.md +23 -0
- package/templates/dotnet-skills/gemini/dotnet-architecture-audit/SKILL.md +26 -0
- package/templates/dotnet-skills/gemini/dotnet-clean-guardrails/SKILL.md +25 -0
- package/templates/dotnet-skills/gemini/dotnet-ef-migration/SKILL.md +26 -0
- package/templates/dotnet-skills/gemini/dotnet-endpoint-from-model/SKILL.md +27 -0
- package/templates/dotnet-skills/gemini/dotnet-extract-service/SKILL.md +26 -0
- package/templates/dotnet-skills/gemini/dotnet-feature/SKILL.md +27 -0
- package/templates/dotnet-skills/gemini/dotnet-generate-tests/SKILL.md +26 -0
- package/templates/dotnet-skills/gemini/dotnet-health/SKILL.md +25 -0
- package/templates/dotnet-skills/gemini/dotnet-migrate-minimal-api/SKILL.md +26 -0
- package/templates/dotnet-skills/gemini/dotnet-modernize/SKILL.md +26 -0
- package/templates/vue-commands/codex/component-pattern-audit.md +24 -0
- package/templates/vue-commands/codex/design-token-discover.md +24 -0
- package/templates/vue-commands/codex/design-token-migrate.md +24 -0
- package/templates/vue-commands/codex/js-to-ts.md +25 -0
- package/templates/vue-commands/codex/reactivity-audit.md +25 -0
- package/templates/vue-commands/codex/state-strategy-audit.md +23 -0
- package/templates/vue-commands/codex/vue-guardrails.md +24 -0
- package/templates/vue-commands/codex/vue-health.md +28 -0
- package/templates/vue-commands/codex/vue-legacy-map.md +25 -0
- package/templates/vue-commands/codex/vue-migration-plan.md +24 -0
- package/templates/vue-commands/codex/vue-modernize-slice.md +26 -0
- package/templates/vue-commands/codex/vue-pattern-map.md +24 -0
- package/templates/vue-commands/codex/vue-standardize.md +26 -0
- package/templates/vue-commands/codex/vue-style-audit.md +24 -0
- package/templates/vue-commands/codex/vue-target-architecture.md +24 -0
- package/templates/vue-commands/cursor/component-pattern-audit.md +25 -0
- package/templates/vue-commands/cursor/design-token-discover.md +25 -0
- package/templates/vue-commands/cursor/design-token-migrate.md +25 -0
- package/templates/vue-commands/cursor/js-to-ts.md +26 -0
- package/templates/vue-commands/cursor/reactivity-audit.md +26 -0
- package/templates/vue-commands/cursor/state-strategy-audit.md +24 -0
- package/templates/vue-commands/cursor/vue-guardrails.md +25 -0
- package/templates/vue-commands/cursor/vue-health.md +29 -0
- package/templates/vue-commands/cursor/vue-legacy-map.md +26 -0
- package/templates/vue-commands/cursor/vue-migration-plan.md +25 -0
- package/templates/vue-commands/cursor/vue-modernize-slice.md +27 -0
- package/templates/vue-commands/cursor/vue-pattern-map.md +25 -0
- package/templates/vue-commands/cursor/vue-standardize.md +27 -0
- package/templates/vue-commands/cursor/vue-style-audit.md +25 -0
- package/templates/vue-commands/cursor/vue-target-architecture.md +25 -0
- package/templates/vue-commands/opencode/component-pattern-audit.md +22 -0
- package/templates/vue-commands/opencode/design-token-discover.md +22 -0
- package/templates/vue-commands/opencode/design-token-migrate.md +22 -0
- package/templates/vue-commands/opencode/js-to-ts.md +23 -0
- package/templates/vue-commands/opencode/reactivity-audit.md +23 -0
- package/templates/vue-commands/opencode/state-strategy-audit.md +21 -0
- package/templates/vue-commands/opencode/vue-guardrails.md +22 -0
- package/templates/vue-commands/opencode/vue-health.md +26 -0
- package/templates/vue-commands/opencode/vue-legacy-map.md +23 -0
- package/templates/vue-commands/opencode/vue-migration-plan.md +22 -0
- package/templates/vue-commands/opencode/vue-modernize-slice.md +24 -0
- package/templates/vue-commands/opencode/vue-pattern-map.md +22 -0
- package/templates/vue-commands/opencode/vue-standardize.md +24 -0
- package/templates/vue-commands/opencode/vue-style-audit.md +22 -0
- package/templates/vue-commands/opencode/vue-target-architecture.md +22 -0
- package/templates/vue-skills/gemini/component-pattern-audit/SKILL.md +25 -0
- package/templates/vue-skills/gemini/design-token-discover/SKILL.md +25 -0
- package/templates/vue-skills/gemini/design-token-migrate/SKILL.md +25 -0
- package/templates/vue-skills/gemini/js-to-ts/SKILL.md +26 -0
- package/templates/vue-skills/gemini/reactivity-audit/SKILL.md +26 -0
- package/templates/vue-skills/gemini/state-strategy-audit/SKILL.md +24 -0
- package/templates/vue-skills/gemini/vue-guardrails/SKILL.md +25 -0
- package/templates/vue-skills/gemini/vue-health/SKILL.md +29 -0
- package/templates/vue-skills/gemini/vue-legacy-map/SKILL.md +26 -0
- package/templates/vue-skills/gemini/vue-migration-plan/SKILL.md +25 -0
- package/templates/vue-skills/gemini/vue-modernize-slice/SKILL.md +27 -0
- package/templates/vue-skills/gemini/vue-pattern-map/SKILL.md +25 -0
- package/templates/vue-skills/gemini/vue-standardize/SKILL.md +27 -0
- package/templates/vue-skills/gemini/vue-style-audit/SKILL.md +25 -0
- package/templates/vue-skills/gemini/vue-target-architecture/SKILL.md +25 -0
package/README.md
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
|
-
#
|
|
1
|
+
# PlanKit CLI — AI Coding Agent Workflow Command Suite
|
|
2
2
|
|
|
3
|
-
PlanKit is a lightweight, zero-dependency CLI that installs and manages a multi-phase feature workflow for AI coding assistants.
|
|
3
|
+
PlanKit is a lightweight, **zero-dependency** CLI (Node ≥ 18) that installs and manages a multi-phase feature workflow for AI coding assistants (OpenCode, Gemini/Antigravity, Codex, Cursor). It creates a predictable artifact structure, installs the **selected agent's** command/skill bindings, generates phase specs and output reports, and archive records — and ships with a per-agent Angular command library so your AI agent can run deterministic, repository-aware Angular workflows.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
```
|
|
6
|
+
plankit init → installs ONE agent's folders/commands + artifact scaffold
|
|
7
|
+
plankit plan → creates artifacts/current/<feature>/ workspace
|
|
8
|
+
plankit implement → executes a phase against spec + prior outputs
|
|
9
|
+
plankit review → verifies, validates Definition of Done, archives
|
|
10
|
+
```
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
Use it without installing (latest published version):
|
|
8
17
|
|
|
9
18
|
```bash
|
|
10
19
|
npx plankit-cli init
|
|
11
20
|
npx plankit-cli plan my-feature "Add configurable templates"
|
|
12
21
|
```
|
|
13
22
|
|
|
14
|
-
|
|
23
|
+
Or install globally once:
|
|
15
24
|
|
|
16
25
|
```bash
|
|
17
26
|
npm install -g plankit-cli
|
|
@@ -19,17 +28,76 @@ plankit init
|
|
|
19
28
|
plankit plan my-feature
|
|
20
29
|
```
|
|
21
30
|
|
|
31
|
+
> **Check your version** — if behavior ever looks "old", run `plankit --version` first (see [Troubleshooting](#troubleshooting)).
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Quick start
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# 1. Initialize the workspace for your agent (you'll be prompted which one)
|
|
39
|
+
plankit init
|
|
40
|
+
|
|
41
|
+
# 2. Plan a feature (non-interactive agent selection, no prompt)
|
|
42
|
+
plankit init --agent opencode
|
|
43
|
+
|
|
44
|
+
# 3. Create a feature workspace under artifacts/current/<feature>/
|
|
45
|
+
plankit plan my-feature "Add configurable templates"
|
|
46
|
+
|
|
47
|
+
# 4. Prepare Phase 1, execute, then move to Phase 2...
|
|
48
|
+
plankit implement my-feature 1
|
|
49
|
+
plankit implement my-feature 2
|
|
50
|
+
|
|
51
|
+
# 5. Review, verify, and archive when done
|
|
52
|
+
plankit review my-feature
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
22
57
|
## Commands
|
|
23
58
|
|
|
24
59
|
| Command | Action |
|
|
25
60
|
|---|---|
|
|
26
|
-
| `plankit init [--agent <name>]` | Create PlanKit config, artifact folders, spec, and the **selected agent's** folders/commands. Prompts for the agent when
|
|
61
|
+
| `plankit init [--agent <name>] [--framework <name>]` | Create PlanKit config, artifact folders, spec, and the **selected agent's** folders/commands. Prompts for the agent and framework suite(s) when run interactively. |
|
|
27
62
|
| `plankit plan <feature> [requirements]` | Create `artifacts/current/<feature>/` with README, phase specs, outputs folder, and state metadata. |
|
|
28
63
|
| `plankit clarify <feature> [phase]` | Create a clarification artifact for requirements and design decisions. |
|
|
29
|
-
| `plankit implement <feature> <phase>` | Validate phase context and prepare `outputs/phase-N-output.md`. |
|
|
30
|
-
| `plankit review <feature>` | Run verification commands, mark
|
|
64
|
+
| `plankit implement <feature> <phase>` | Validate phase context (spec + prior outputs) and prepare `outputs/phase-N-output.md`. |
|
|
65
|
+
| `plankit review <feature>` | Run verification commands, mark README archived, and move the feature to `artifacts/archived/`. |
|
|
31
66
|
| `plankit status [--json]` | List active and archived features. |
|
|
32
67
|
| `plankit archive <feature>` | Move a feature to archived without running verification. |
|
|
68
|
+
| `plankit version` / `--version` / `-v` | Print the installed version (`plankit-cli vX.Y.Z`). |
|
|
69
|
+
| `plankit help` / `--help` / `-h` | Show usage. |
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Global options
|
|
74
|
+
|
|
75
|
+
| Option | Description |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `--force` | Overwrite generated files where safe. |
|
|
78
|
+
| `--dry-run` | Show intended actions without writing anything. |
|
|
79
|
+
| `--agent <name>` | Select your coding agent during `init` (`opencode`, `gemini`, `codex`, `cursor`; default `opencode`). |
|
|
80
|
+
| `--framework <name>` | Select framework command suite during `init` (`angular`, `vue`, `dotnet`, `none`, `all`; default `none`). |
|
|
81
|
+
| `--frameworks <list>` | Comma-separated list of framework command suites (e.g. `vue,dotnet`). |
|
|
82
|
+
|
|
83
|
+
### Plan options
|
|
84
|
+
|
|
85
|
+
| Option | Description |
|
|
86
|
+
|---|---|
|
|
87
|
+
| `--phases 3` | Generate N default phases. |
|
|
88
|
+
| `--phases "Design,Build,Test"` | Generate named phases. |
|
|
89
|
+
| `--requirements "text"` | Set feature requirements. |
|
|
90
|
+
|
|
91
|
+
### Review options
|
|
92
|
+
|
|
93
|
+
| Option | Description |
|
|
94
|
+
|---|---|
|
|
95
|
+
| `--test-command "cmd"` | Override the review test command. |
|
|
96
|
+
| `--build-command "cmd"` | Override the review build command. |
|
|
97
|
+
| `--skip-test` | Skip the review test command. |
|
|
98
|
+
| `--skip-build` | Skip the review build command. |
|
|
99
|
+
|
|
100
|
+
---
|
|
33
101
|
|
|
34
102
|
## Customization
|
|
35
103
|
|
|
@@ -58,51 +126,128 @@ plankit plan my-feature
|
|
|
58
126
|
}
|
|
59
127
|
```
|
|
60
128
|
|
|
61
|
-
|
|
129
|
+
| Config key | Type | Default | Purpose |
|
|
130
|
+
|---|---|---|---|
|
|
131
|
+
| `artifactsDir` | `string` | `"artifacts"` | Root folder for `current/` and `archived/` workspaces. |
|
|
132
|
+
| `overwrite` | `string` | `"skip"` | `"skip"` or `"force"` for regenerated files. |
|
|
133
|
+
| `agents.default` | `string` | `"opencode"` | The agent whose folders/commands `init` installs. |
|
|
134
|
+
| `defaultPhases` | `array` | 3 phases | Phases used when `--phases` isn't given. |
|
|
135
|
+
| `verification` | `object` | `npm test` / `npm run build` | Commands run by `plankit review`. |
|
|
136
|
+
| `templatesDir` | `string \| null` | `null` | Custom template overrides directory. |
|
|
62
137
|
|
|
63
|
-
|
|
64
|
-
plankit init --agent opencode
|
|
65
|
-
plankit init --agent gemini --global-gemini-skills
|
|
66
|
-
plankit init --force
|
|
67
|
-
plankit plan my-feature --phases 4
|
|
68
|
-
plankit plan my-feature --phases "Design,Build,Test"
|
|
69
|
-
plankit review my-feature --test-command "pnpm test" --build-command "pnpm build"
|
|
70
|
-
plankit review my-feature --skip-build
|
|
71
|
-
plankit status --json
|
|
72
|
-
```
|
|
138
|
+
---
|
|
73
139
|
|
|
74
|
-
|
|
140
|
+
## Agent selection
|
|
75
141
|
|
|
76
142
|
`plankit init` installs **only** the folders/commands for the agent you select. Supported agents:
|
|
77
143
|
|
|
78
|
-
| Agent | What
|
|
144
|
+
| Agent | What gets installed |
|
|
79
145
|
|---|---|
|
|
80
|
-
| `opencode` (default) | Slash commands under `.opencode/commands/` |
|
|
81
|
-
| `gemini` / `antigravity` | `.gemini/instructions.md` + `angular-*` skills
|
|
82
|
-
| `codex` | `AGENTS.md` + Angular commands under `.codex
|
|
83
|
-
| `cursor` | `.cursorrules` + Angular command rules under `.cursor/rules
|
|
146
|
+
| `opencode` (default) | Slash commands under `.opencode/commands/` (`plankit-*.md` + `angular-*.md`). |
|
|
147
|
+
| `gemini` / `antigravity` | `.gemini/instructions.md` + `angular-*` skills. `--global-gemini-skills` also installs skills under `~/.gemini/skills/`. |
|
|
148
|
+
| `codex` | `AGENTS.md` + Angular commands under `.codex/`. |
|
|
149
|
+
| `cursor` | `.cursorrules` + Angular command rules under `.cursor/rules/`. |
|
|
150
|
+
|
|
151
|
+
Selection order during `init`:
|
|
84
152
|
|
|
85
|
-
Selection order:
|
|
86
153
|
1. `--agent <name>` flag (non-interactive / CI).
|
|
87
154
|
2. A previously configured `agents.default` in `plankit.config.json`.
|
|
88
155
|
3. An interactive numbered menu (when run in a terminal).
|
|
89
|
-
4. The `opencode` default — announced explicitly so the behavior is never silent.
|
|
156
|
+
4. The `opencode` default — **announced explicitly** so the behavior is never silent.
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
plankit init --agent opencode
|
|
160
|
+
plankit init --agent gemini --global-gemini-skills
|
|
161
|
+
plankit init --agent codex
|
|
162
|
+
plankit init --agent cursor
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
90
166
|
|
|
91
|
-
|
|
167
|
+
## Framework command suites
|
|
92
168
|
|
|
93
|
-
|
|
169
|
+
During `plankit init`, PlanKit prompts you to choose optional framework-specific command suites (or pass `--framework <name>` / `--frameworks <names>`):
|
|
170
|
+
- **None**: Installs only the core PlanKit feature planning workflow.
|
|
171
|
+
- **Angular**: Installs 17 Angular engineering workflows.
|
|
172
|
+
- **Vue**: Installs 15 Vue modernization and architectural standardization workflows.
|
|
173
|
+
- **.NET**: Installs 10 .NET clean architecture and API engineering workflows.
|
|
174
|
+
- **All**: Installs all supported framework suites.
|
|
94
175
|
|
|
95
|
-
|
|
176
|
+
### Vue modernization suite (`--framework vue`)
|
|
96
177
|
|
|
97
|
-
|
|
178
|
+
Designed for legacy and mixed Vue codebases (JavaScript/TypeScript, Options API, Composition API, `<script setup>`, Vuex/Pinia) following the PlanKit Vue Modernization Specification:
|
|
179
|
+
|
|
180
|
+
| Command | Purpose |
|
|
181
|
+
|---|---|
|
|
182
|
+
| `vue-health` | Audit Vue codebase health, tech debt score, Options vs Composition ratio, and modernization risks. |
|
|
183
|
+
| `vue-pattern-map` | Map architectural patterns across state, data fetching, styling, and components. |
|
|
184
|
+
| `vue-target-architecture` | Define or inspect target architectural conventions (Vue 3, `<script setup>`, TS, Pinia). |
|
|
185
|
+
| `vue-legacy-map` | Catalog legacy Vue files, mixins, filters, Options API components, and hotspots. |
|
|
186
|
+
| `vue-standardize` | Refactor a component or composable to conform to the established target architecture. |
|
|
187
|
+
| `vue-migration-plan` | Generate an incremental, phased migration plan for a legacy feature slice. |
|
|
188
|
+
| `js-to-ts` | Convert JavaScript Vue SFCs and utility modules to TypeScript with typed props/emits. |
|
|
189
|
+
| `vue-style-audit` | Audit styling patterns, global vs scoped CSS/SCSS, deep selectors, and hardcoded values. |
|
|
190
|
+
| `design-token-discover` | Discover repeated color literals, typography, spacing, and shadows into token candidates. |
|
|
191
|
+
| `design-token-migrate` | Migrate hardcoded styles in Vue components to standardized design tokens. |
|
|
192
|
+
| `state-strategy-audit` | Audit Vuex vs Pinia vs composables; detect state duplication and reactivity leaks. |
|
|
193
|
+
| `reactivity-audit` | Audit reactivity anti-patterns (destructuring props without `toRefs`, watcher leaks). |
|
|
194
|
+
| `component-pattern-audit` | Audit SFC component design, god components, prop drilling, and emits declarations. |
|
|
195
|
+
| `vue-modernize-slice` | Orchestrate an end-to-end modernization of a Vue feature slice with validation. |
|
|
196
|
+
| `vue-guardrails` | Configure ESLint rules and TypeScript strict settings to prevent legacy regressions. |
|
|
197
|
+
|
|
198
|
+
### .NET clean architecture suite (`--framework dotnet`)
|
|
199
|
+
|
|
200
|
+
Designed for ASP.NET Core and .NET solutions following Clean Architecture and Vertical Slice patterns:
|
|
201
|
+
|
|
202
|
+
| Command | Purpose |
|
|
203
|
+
|---|---|
|
|
204
|
+
| `dotnet-health` | Audit solution health: SDK versions, NuGet packages, vulnerabilities, and compiler warnings. |
|
|
205
|
+
| `dotnet-architecture-audit` | Audit layer dependencies (Domain, Application, Infrastructure, API) and circular references. |
|
|
206
|
+
| `dotnet-feature` | Build an end-to-end vertical slice feature (Command/Query, MediatR, FluentValidation, Endpoint). |
|
|
207
|
+
| `dotnet-endpoint-from-model` | Generate ASP.NET Core Minimal API or Controller endpoints with typed results and error handling. |
|
|
208
|
+
| `dotnet-migrate-minimal-api` | Migrate traditional controllers to modern Minimal API route groups. |
|
|
209
|
+
| `dotnet-ef-migration` | Safe Entity Framework Core migration lifecycle: entity check, migration, SQL preview, rollback. |
|
|
210
|
+
| `dotnet-extract-service` | Refactor fat services into isolated CQRS handlers or domain services. |
|
|
211
|
+
| `dotnet-generate-tests` | Generate xUnit/NUnit tests with FluentAssertions and WebApplicationFactory integration tests. |
|
|
212
|
+
| `dotnet-clean-guardrails` | Generate NetArchTest architectural unit tests and EditorConfig rules to guard layer boundaries. |
|
|
213
|
+
| `dotnet-modernize` | Upgrade legacy C# syntax to modern C# 12+ / .NET 8+ patterns (primary constructors, collection expressions). |
|
|
214
|
+
|
|
215
|
+
### Angular command suite (`--framework angular`)
|
|
216
|
+
|
|
217
|
+
Alongside the phase workflow, `init` installs a per-agent Angular command library that gives your AI assistant **16 deterministic Angular engineering workflows**, driven by repository discovery rather than generic prompts:
|
|
218
|
+
|
|
219
|
+
| Command | Purpose |
|
|
220
|
+
|---|---|
|
|
221
|
+
| `component-from` | Generate a component from an existing one as an architectural reference. |
|
|
222
|
+
| `feature` | Build a whole feature respecting existing architecture. |
|
|
223
|
+
| `clone-pattern` | Clone any architectural pattern (feature/page/dialog/store/form/table/service). |
|
|
224
|
+
| `design-match` | Align a generated component with the design system. |
|
|
225
|
+
| `page-from-api` | Scaffold a page from a typed API method, deriving UI from the contract. |
|
|
226
|
+
| `form-from-model` | Build a form from a domain model with inferred controls/validation. |
|
|
227
|
+
| `table-from-model` | Build a table with semantic columns and correct formatting. |
|
|
228
|
+
| `wire-api` | Replace mock data with real API calls using the dominant data-access pattern. |
|
|
229
|
+
| `signalize` | Migrate state to Signals only where appropriate. |
|
|
230
|
+
| `extract-component` | Extract a template region into a child component with a clean API. |
|
|
231
|
+
| `split-component` | Decompose an oversized component into focused parts. |
|
|
232
|
+
| `extract-store` | Move server/user state into a feature-scoped store. |
|
|
233
|
+
| `modernize` | Orchestrate incremental Angular migrations (build/test between stages). |
|
|
234
|
+
| `responsive` | Make a component responsive per project conventions. |
|
|
235
|
+
| `generate-tests` | Write behavior-focused tests, filling coverage gaps only. |
|
|
236
|
+
| `fixtures` | Generate reusable fixtures from TypeScript domain models. |
|
|
237
|
+
|
|
238
|
+
Plus a shared `angular-project-discovery` reference that every command leans on (Angular version, standalone vs NgModule, Signals/RxJS, state management, forms strategy, UI library, styling, testing, conventions, architecture).
|
|
239
|
+
|
|
240
|
+
Only your **selected agent's** folder/commands are copied. To customize the command templates in your own `templatesDir`, mirror the `templates/<framework>-commands/` and `templates/<framework>-skills/` folder layout from the package.
|
|
241
|
+
|
|
242
|
+
---
|
|
98
243
|
|
|
99
244
|
## Template overrides
|
|
100
245
|
|
|
101
|
-
Default templates live
|
|
246
|
+
Default templates live inside the package at `templates/`. To override them in a project:
|
|
102
247
|
|
|
103
248
|
1. Create a directory such as `.plankit/templates`.
|
|
104
249
|
2. Set `"templatesDir": ".plankit/templates"` in `plankit.config.json`.
|
|
105
|
-
3. Add files matching the built-in template names
|
|
250
|
+
3. Add files matching the built-in template names. For example:
|
|
106
251
|
|
|
107
252
|
```text
|
|
108
253
|
.plankit/templates/
|
|
@@ -114,7 +259,57 @@ Default templates live in the package `templates/` directory. To override them i
|
|
|
114
259
|
plankit-plan.md
|
|
115
260
|
```
|
|
116
261
|
|
|
117
|
-
Supported placeholders use `{{name}}` syntax.
|
|
262
|
+
Custom template directories mirror the package `templates/` layout, including `angular-commands/` and `angular-skills/`. Supported placeholders use `{{name}}` syntax (e.g. `{{artifactsDir}}`).
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Development
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
# Run the test suite (Node's built-in test runner)
|
|
270
|
+
npm test
|
|
271
|
+
|
|
272
|
+
# Inspect the exact tarball contents
|
|
273
|
+
npm pack --dry-run
|
|
274
|
+
|
|
275
|
+
# Build the per-agent Angular command/skill bundles from canonical sources
|
|
276
|
+
node scripts/generate-angular-bundles.mjs
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
> The Angular command files are **generated** from the canonical definitions in [`scripts/generate-angular-bundles.mjs`](scripts/generate-angular-bundles.mjs). Edit that file (or the per-command body) and re-run the generator; don't hand-edit the four generated folders.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Troubleshooting
|
|
284
|
+
|
|
285
|
+
**"I ran `plankit init` but I still see the old all-agents behavior / no Angular commands."**
|
|
286
|
+
|
|
287
|
+
Almost always a **stale global install**. First confirm what's really running:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
plankit --version # should be >= 1.3.1
|
|
291
|
+
npm view plankit-cli version # latest published version
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
If `plankit --version` reports an old version (or an error), update:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
npm install -g plankit-cli@latest
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Two-competing-global-installs (Windows/macOS PATH shadowing):** it's possible to have `plankit-cli` installed under **two** global locations — your npm prefix (e.g. `D:\node24\...`) and a separately-linked one (e.g. `%APPDATA%\npm\...`). If `npm install -g` reports success but `plankit --version` still shows old output, the `plankit` shim earlier on your `PATH` may point at the stale copy. Fix by installing into the location that actually resolves:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
# Windows PowerShell (check your APPDATA npm location)
|
|
304
|
+
npm install -g --prefix "$env:APPDATA\npm" plankit-cli@latest
|
|
305
|
+
|
|
306
|
+
# Or find every copy and refresh:
|
|
307
|
+
where.exe plankit
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Then restart your terminal so PATH refreshes and verify with `plankit --version`.
|
|
311
|
+
|
|
312
|
+
---
|
|
118
313
|
|
|
119
314
|
## Verification
|
|
120
315
|
|
package/package.json
CHANGED
package/src/agents.js
CHANGED
|
@@ -33,7 +33,7 @@ export const AGENTS = {
|
|
|
33
33
|
{ template: 'opencode/plankit-implement.md', dest: ['.opencode', 'commands', 'plankit-implement.md'] },
|
|
34
34
|
{ template: 'opencode/plankit-review.md', dest: ['.opencode', 'commands', 'plankit-review.md'] }
|
|
35
35
|
],
|
|
36
|
-
commandBundles: [
|
|
36
|
+
commandBundles: [],
|
|
37
37
|
globalSkillEntries: null
|
|
38
38
|
},
|
|
39
39
|
gemini: {
|
|
@@ -44,7 +44,7 @@ export const AGENTS = {
|
|
|
44
44
|
bindings: [
|
|
45
45
|
{ template: 'gemini-instructions.md', dest: ['.gemini', 'instructions.md'] }
|
|
46
46
|
],
|
|
47
|
-
commandBundles: [
|
|
47
|
+
commandBundles: [],
|
|
48
48
|
globalSkillEntries: GEMINI_SKILL_ENTRIES
|
|
49
49
|
},
|
|
50
50
|
codex: {
|
|
@@ -55,7 +55,7 @@ export const AGENTS = {
|
|
|
55
55
|
bindings: [
|
|
56
56
|
{ template: 'AGENTS.md', dest: ['AGENTS.md'] }
|
|
57
57
|
],
|
|
58
|
-
commandBundles: [
|
|
58
|
+
commandBundles: [],
|
|
59
59
|
globalSkillEntries: null
|
|
60
60
|
},
|
|
61
61
|
cursor: {
|
|
@@ -66,11 +66,15 @@ export const AGENTS = {
|
|
|
66
66
|
bindings: [
|
|
67
67
|
{ template: 'cursorrules', dest: ['.cursorrules'] }
|
|
68
68
|
],
|
|
69
|
-
commandBundles: [
|
|
69
|
+
commandBundles: [],
|
|
70
70
|
globalSkillEntries: null
|
|
71
71
|
}
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
+
export function resolveAgentBundles(agentId, frameworks = []) {
|
|
75
|
+
return (frameworks || []).map((fw) => `${agentId}-${fw}`);
|
|
76
|
+
}
|
|
77
|
+
|
|
74
78
|
export function listAgents() {
|
|
75
79
|
return AGENT_ORDER.map((id) => AGENTS[id]);
|
|
76
80
|
}
|
package/src/cli.js
CHANGED
|
@@ -15,8 +15,14 @@ import {
|
|
|
15
15
|
writeManagedFile
|
|
16
16
|
} from './config.js';
|
|
17
17
|
import { renderList, renderTemplate, packageRoot } from './templates.js';
|
|
18
|
-
import { DEFAULT_AGENT, GEMINI_SKILL_ENTRIES, getAgent, listAgents, validAgentNames } from './agents.js';
|
|
19
|
-
import {
|
|
18
|
+
import { DEFAULT_AGENT, GEMINI_SKILL_ENTRIES, getAgent, listAgents, resolveAgentBundles, validAgentNames } from './agents.js';
|
|
19
|
+
import {
|
|
20
|
+
SUPPORTED_FRAMEWORKS,
|
|
21
|
+
bundleEntry,
|
|
22
|
+
bundleSourceExists,
|
|
23
|
+
normalizeFramework,
|
|
24
|
+
parseFrameworksInput
|
|
25
|
+
} from './commandBundles.js';
|
|
20
26
|
|
|
21
27
|
export async function runCli(args, context = {}) {
|
|
22
28
|
const io = createIo(context);
|
|
@@ -47,6 +53,11 @@ export async function runCli(args, context = {}) {
|
|
|
47
53
|
case 'archive':
|
|
48
54
|
archiveFeature(parsed, io);
|
|
49
55
|
break;
|
|
56
|
+
case 'version':
|
|
57
|
+
case '--version':
|
|
58
|
+
case '-v':
|
|
59
|
+
showVersion(io);
|
|
60
|
+
break;
|
|
50
61
|
case 'help':
|
|
51
62
|
case '--help':
|
|
52
63
|
case '-h':
|
|
@@ -66,6 +77,7 @@ async function initProject(parsed, io) {
|
|
|
66
77
|
const { config, path: configPath } = loadConfig(io.cwd);
|
|
67
78
|
const options = writeOptions(parsed, config);
|
|
68
79
|
const agent = await resolveAgent(parsed, config, io, configPath);
|
|
80
|
+
const frameworks = await resolveFrameworks(parsed, config, io, configPath);
|
|
69
81
|
const results = [];
|
|
70
82
|
const artifactsDir = safeJoin(io.cwd, config.artifactsDir);
|
|
71
83
|
|
|
@@ -79,7 +91,7 @@ async function initProject(parsed, io) {
|
|
|
79
91
|
));
|
|
80
92
|
results.push(writeManagedFile(path.join(artifactsDir, 'current', '.gitkeep'), '', options));
|
|
81
93
|
results.push(writeManagedFile(path.join(artifactsDir, 'archived', '.gitkeep'), '', options));
|
|
82
|
-
results.push(createDefaultConfigFile(io.cwd, options));
|
|
94
|
+
results.push(createDefaultConfigFile(io.cwd, options, frameworks));
|
|
83
95
|
|
|
84
96
|
for (const binding of agent.bindings) {
|
|
85
97
|
results.push(writeManagedFile(
|
|
@@ -89,7 +101,8 @@ async function initProject(parsed, io) {
|
|
|
89
101
|
));
|
|
90
102
|
}
|
|
91
103
|
|
|
92
|
-
|
|
104
|
+
const bundlesToInstall = resolveAgentBundles(agent.id, frameworks);
|
|
105
|
+
for (const bundleName of bundlesToInstall) {
|
|
93
106
|
results.push(installCommandBundle(agent, bundleName, config, options, io));
|
|
94
107
|
}
|
|
95
108
|
|
|
@@ -97,7 +110,10 @@ async function initProject(parsed, io) {
|
|
|
97
110
|
results.push(...installGlobalGeminiSkills(config, options));
|
|
98
111
|
}
|
|
99
112
|
|
|
100
|
-
|
|
113
|
+
const fwMsg = frameworks.length > 0
|
|
114
|
+
? ` with framework suite(s): ${frameworks.join(', ')}`
|
|
115
|
+
: ' (base planning commands only)';
|
|
116
|
+
io.stdout(`PlanKit initialized for agent "${agent.id}"${fwMsg}.`);
|
|
101
117
|
printResults(results, io);
|
|
102
118
|
}
|
|
103
119
|
|
|
@@ -517,6 +533,93 @@ async function promptAgent(io) {
|
|
|
517
533
|
return getAgent(trimmed) || null;
|
|
518
534
|
}
|
|
519
535
|
|
|
536
|
+
async function resolveFrameworks(parsed, config, io, configPath = null) {
|
|
537
|
+
const fromFlag = parsed.flags.framework || parsed.flags.frameworks;
|
|
538
|
+
if (fromFlag !== undefined) {
|
|
539
|
+
const frameworks = parseFrameworksInput(fromFlag);
|
|
540
|
+
if (frameworks.length > 0) {
|
|
541
|
+
io.stdout(`Using framework(s) from --framework flag: "${frameworks.join(', ')}".`);
|
|
542
|
+
} else {
|
|
543
|
+
io.stdout('No framework suites selected via --framework flag.');
|
|
544
|
+
}
|
|
545
|
+
return frameworks;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (configPath && Array.isArray(config.frameworks) && config.frameworks.length > 0) {
|
|
549
|
+
io.stdout(`Using configured framework(s) "${config.frameworks.join(', ')}" from plan config.`);
|
|
550
|
+
return config.frameworks;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
if (io.isTTY && io.promptChoice) {
|
|
554
|
+
const selected = await promptFrameworks(io);
|
|
555
|
+
if (selected !== null) {
|
|
556
|
+
if (selected.length > 0) {
|
|
557
|
+
io.stdout(`Selected framework(s): "${selected.join(', ')}".`);
|
|
558
|
+
} else {
|
|
559
|
+
io.stdout('Selected base planning commands only.');
|
|
560
|
+
}
|
|
561
|
+
return selected;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
io.stdout('No framework suite selected — installing base planning commands only. Pass --framework <angular|vue|dotnet|none> to add framework suites.');
|
|
566
|
+
return [];
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
async function promptFrameworks(io) {
|
|
570
|
+
const promptText = `Select framework command suites to install (in addition to base planning commands):
|
|
571
|
+
1. None (Base planning commands only)
|
|
572
|
+
2. Angular command suite
|
|
573
|
+
3. Vue modernization & architecture suite
|
|
574
|
+
4. .NET clean architecture & API suite
|
|
575
|
+
5. All framework suites
|
|
576
|
+
|
|
577
|
+
Enter a number (1-5), comma-separated numbers, or framework names (default: 1)`;
|
|
578
|
+
|
|
579
|
+
const validChoices = ['1', '2', '3', '4', '5', 'none', 'angular', 'vue', 'dotnet', 'all'];
|
|
580
|
+
const answer = await io.promptChoice(promptText, validChoices);
|
|
581
|
+
if (!answer || !answer.trim()) {
|
|
582
|
+
return [];
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
const raw = answer.trim().toLowerCase();
|
|
586
|
+
const tokens = raw.split(',').map((t) => t.trim()).filter(Boolean);
|
|
587
|
+
const result = new Set();
|
|
588
|
+
|
|
589
|
+
for (const token of tokens) {
|
|
590
|
+
if (token === '1' || token === 'none') {
|
|
591
|
+
continue;
|
|
592
|
+
}
|
|
593
|
+
if (token === '2' || token === 'angular' || token === 'ng') {
|
|
594
|
+
result.add('angular');
|
|
595
|
+
continue;
|
|
596
|
+
}
|
|
597
|
+
if (token === '3' || token === 'vue' || token === 'vuejs') {
|
|
598
|
+
result.add('vue');
|
|
599
|
+
continue;
|
|
600
|
+
}
|
|
601
|
+
if (token === '4' || token === 'dotnet' || token === '.net' || token === 'net') {
|
|
602
|
+
result.add('dotnet');
|
|
603
|
+
continue;
|
|
604
|
+
}
|
|
605
|
+
if (token === '5' || token === 'all') {
|
|
606
|
+
SUPPORTED_FRAMEWORKS.forEach((fw) => result.add(fw));
|
|
607
|
+
continue;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
const normalized = normalizeFramework(token);
|
|
611
|
+
if (Array.isArray(normalized)) {
|
|
612
|
+
normalized.forEach((fw) => result.add(fw));
|
|
613
|
+
} else if (normalized) {
|
|
614
|
+
result.add(normalized);
|
|
615
|
+
} else {
|
|
616
|
+
throw new Error(`Unknown framework selection "${token}". Valid options: 1-5, ${SUPPORTED_FRAMEWORKS.join(', ')}, none, all.`);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
return Array.from(result);
|
|
621
|
+
}
|
|
622
|
+
|
|
520
623
|
function writeOptions(parsed, config) {
|
|
521
624
|
return {
|
|
522
625
|
force: Boolean(parsed.flags.force) || config.overwrite === 'force',
|
|
@@ -632,6 +735,7 @@ Commands:
|
|
|
632
735
|
review <feature> Run verification and archive a completed feature
|
|
633
736
|
status [--json] Show active and archived features
|
|
634
737
|
archive <feature> Move a feature to archived without running verification
|
|
738
|
+
version Show the installed PlankKit CLI version
|
|
635
739
|
help Show this help message
|
|
636
740
|
|
|
637
741
|
Options:
|
|
@@ -639,6 +743,9 @@ Options:
|
|
|
639
743
|
--dry-run Show intended actions without writing
|
|
640
744
|
--agent <name> Select your coding agent during init
|
|
641
745
|
(opencode, gemini, codex, cursor; default: opencode)
|
|
746
|
+
--framework <name> Select framework command suite during init
|
|
747
|
+
(angular, vue, dotnet, none, all; default: none)
|
|
748
|
+
--frameworks <list> Comma-separated list of framework suites during init
|
|
642
749
|
--global-gemini-skills Also install Gemini skills under the user profile
|
|
643
750
|
--phases 3 Generate N default phases during plan
|
|
644
751
|
--phases "Design,Build,Test" Generate named phases during plan
|
|
@@ -649,3 +756,17 @@ Options:
|
|
|
649
756
|
--skip-build Skip review build command
|
|
650
757
|
`);
|
|
651
758
|
}
|
|
759
|
+
|
|
760
|
+
function showVersion(io) {
|
|
761
|
+
const version = readPackageVersion();
|
|
762
|
+
io.stdout(`plankit-cli v${version}`);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
function readPackageVersion() {
|
|
766
|
+
try {
|
|
767
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
|
|
768
|
+
return pkg.version || 'unknown';
|
|
769
|
+
} catch {
|
|
770
|
+
return 'unknown';
|
|
771
|
+
}
|
|
772
|
+
}
|