project-kit-cli 0.1.0__tar.gz → 0.3.0__tar.gz

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 (73) hide show
  1. project_kit_cli-0.3.0/PKG-INFO +229 -0
  2. project_kit_cli-0.3.0/README.md +209 -0
  3. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/pyproject.toml +2 -2
  4. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/pyproject.toml.orig +2 -2
  5. project_kit_cli-0.3.0/src/project_kit/agents.py +179 -0
  6. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/ai_attribution.py +5 -0
  7. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/approval.py +7 -0
  8. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/hooks/commit-msg +2 -1
  9. project_kit_cli-0.3.0/src/project_kit/assets/project/skills-catalog.yml +184 -0
  10. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/project/workflow.yml +11 -1
  11. project_kit_cli-0.3.0/src/project_kit/assets/skills/pk-amend/SKILL.md +52 -0
  12. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/skills/pk-decide/SKILL.md +5 -3
  13. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/skills/pk-discover/SKILL.md +4 -4
  14. project_kit_cli-0.3.0/src/project_kit/assets/skills/pk-foundations/SKILL.md +64 -0
  15. project_kit_cli-0.3.0/src/project_kit/assets/skills/pk-grill/SKILL.md +52 -0
  16. project_kit_cli-0.3.0/src/project_kit/assets/skills/pk-handoff/SKILL.md +59 -0
  17. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/skills/pk-plan/SKILL.md +6 -5
  18. project_kit_cli-0.3.0/src/project_kit/assets/skills/pk-provision/SKILL.md +61 -0
  19. project_kit_cli-0.3.0/src/project_kit/assets/skills/pk-skills/SKILL.md +54 -0
  20. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/skills/pk-start/SKILL.md +17 -15
  21. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/skills/pk-workflow/SKILL.md +27 -6
  22. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/templates/constitution-input.md +10 -4
  23. project_kit_cli-0.3.0/src/project_kit/assets/templates/gitlab/issue_templates/adr.md +9 -0
  24. project_kit_cli-0.3.0/src/project_kit/assets/templates/gitlab/issue_templates/bug.md +11 -0
  25. project_kit_cli-0.3.0/src/project_kit/assets/templates/gitlab/issue_templates/epic.md +7 -0
  26. project_kit_cli-0.3.0/src/project_kit/assets/templates/gitlab/issue_templates/feature.md +11 -0
  27. project_kit_cli-0.3.0/src/project_kit/assets/templates/gitlab/merge_request_templates/Default.md +21 -0
  28. project_kit_cli-0.3.0/src/project_kit/assets/templates/interview.md +75 -0
  29. project_kit_cli-0.3.0/src/project_kit/cli.py +486 -0
  30. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/config.py +57 -3
  31. project_kit_cli-0.3.0/src/project_kit/context_files.py +125 -0
  32. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/doctor.py +68 -4
  33. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/fsutil.py +17 -0
  34. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/gh.py +9 -5
  35. project_kit_cli-0.3.0/src/project_kit/glab.py +130 -0
  36. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/handoff.py +202 -11
  37. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/help.py +22 -15
  38. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/installer.py +50 -12
  39. project_kit_cli-0.3.0/src/project_kit/manifest.py +64 -0
  40. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/project_choice.py +16 -1
  41. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/providers/github.py +12 -4
  42. project_kit_cli-0.3.0/src/project_kit/providers/gitlab.py +157 -0
  43. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/provision.py +7 -2
  44. project_kit_cli-0.3.0/src/project_kit/provision_gitlab.py +194 -0
  45. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/provision_issues.py +5 -1
  46. project_kit_cli-0.3.0/src/project_kit/skills.py +282 -0
  47. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/state.py +10 -1
  48. project_kit_cli-0.3.0/src/project_kit/upgrade.py +220 -0
  49. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/workflow.py +27 -9
  50. project_kit_cli-0.1.0/PKG-INFO +0 -97
  51. project_kit_cli-0.1.0/README.md +0 -77
  52. project_kit_cli-0.1.0/src/project_kit/agents.py +0 -81
  53. project_kit_cli-0.1.0/src/project_kit/assets/skills/pk-handoff/SKILL.md +0 -43
  54. project_kit_cli-0.1.0/src/project_kit/assets/skills/pk-provision/SKILL.md +0 -45
  55. project_kit_cli-0.1.0/src/project_kit/assets/templates/interview.md +0 -68
  56. project_kit_cli-0.1.0/src/project_kit/cli.py +0 -286
  57. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/LICENSE +0 -0
  58. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/__init__.py +0 -0
  59. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/__main__.py +0 -0
  60. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/templates/adr.md +0 -0
  61. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/templates/backlog.example.json +0 -0
  62. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/templates/brief.md +0 -0
  63. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/templates/development-workflow.md +0 -0
  64. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/templates/github/ISSUE_TEMPLATE/adr.yml +0 -0
  65. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/templates/github/ISSUE_TEMPLATE/bug.yml +0 -0
  66. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/templates/github/ISSUE_TEMPLATE/config.yml +0 -0
  67. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/templates/github/ISSUE_TEMPLATE/epic.yml +0 -0
  68. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/templates/github/ISSUE_TEMPLATE/feature.yml +0 -0
  69. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/assets/templates/github/pull_request_template.md +0 -0
  70. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/backlog.py +0 -0
  71. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/labels.py +0 -0
  72. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/providers/__init__.py +0 -0
  73. {project_kit_cli-0.1.0 → project_kit_cli-0.3.0}/src/project_kit/templating.py +0 -0
@@ -0,0 +1,229 @@
1
+ Metadata-Version: 2.4
2
+ Name: project-kit-cli
3
+ Version: 0.3.0
4
+ Summary: Project definition and dev-workflow kit that hands off to Spec Kit
5
+ Keywords: project-management,spec-kit,claude-code,workflow,github
6
+ Author: Miguel Tomás
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: Software Development
15
+ Requires-Dist: pyyaml>=6.0.3
16
+ Requires-Python: >=3.12
17
+ Project-URL: Repository, https://github.com/miguelmatg/project-kit
18
+ Project-URL: Issues, https://github.com/miguelmatg/project-kit/issues
19
+ Description-Content-Type: text/markdown
20
+
21
+ # project-kit
22
+
23
+ [![PyPI](https://img.shields.io/pypi/v/project-kit-cli)](https://pypi.org/project/project-kit-cli/)
24
+ [![License: MIT](https://img.shields.io/pypi/l/project-kit-cli)](https://github.com/miguelmatg/project-kit/blob/main/LICENSE)
25
+
26
+ **Everything that happens before the first line of code.** project-kit guides you, with an AI
27
+ agent, through defining a project, deciding its stack and architecture, agreeing how the team
28
+ works and planning the backlog. It then sets up GitHub and hands the project over to
29
+ [Spec Kit](https://github.com/github/spec-kit), which specifies and builds each feature.
30
+
31
+ ```
32
+ idea ──▶ brief ──▶ decisions (ADRs) ──▶ workflow ──▶ backlog ──▶ GitHub ──▶ Spec Kit
33
+ /pk-discover /pk-decide /pk-workflow /pk-plan /pk-provision /pk-handoff
34
+ ```
35
+
36
+ The conversations run in your AI agent ([Claude Code](https://claude.com/claude-code), Codex CLI,
37
+ Gemini CLI, GitHub Copilot or Cursor) as
38
+ `/pk-…` skills: one question at a time, a recommended answer for each, and everything written to
39
+ documents in your repository. Every phase ends with your approval, and every document can be
40
+ written by hand instead.
41
+
42
+ > **Status: alpha.** It works end to end on GitHub with Claude Code. Other agents get their skills
43
+ > and context files but are started by hand. **GitLab support is new and has only been tried
44
+ > against a simulated API**, not a real GitLab project: read the `--dry-run` before applying.
45
+
46
+ ## Requirements
47
+
48
+ - [uv](https://docs.astral.sh/uv/) (it also fetches Python 3.12+ if you do not have it)
49
+ - `git`
50
+ - [Claude Code](https://claude.com/claude-code), to run the guided phases
51
+ - [`gh`](https://cli.github.com/), logged in with the `repo` and `project` scopes
52
+ (`gh auth login`, then `gh auth refresh -s project`), to create things on GitHub; or
53
+ [`glab`](https://gitlab.com/gitlab-org/cli) (`glab auth login`) for GitLab; or neither, with
54
+ `--provider none`
55
+
56
+ `pjkit doctor` checks all of this for you. Spec Kit is installed for you at the end, if
57
+ you want it.
58
+
59
+ ## Install
60
+
61
+ ```bash
62
+ uv tool install project-kit-cli # installs the `pjkit` command
63
+ uv tool upgrade project-kit-cli # later, to update the program
64
+ ```
65
+
66
+ The package is called `project-kit-cli`; the command is `pjkit`. To try it without
67
+ installing: `uvx --from project-kit-cli pjkit help`.
68
+
69
+ **Updating a project.** `init` copies the skills and templates into your repository and never
70
+ overwrites them, so a new version of the program does not change a project that already exists.
71
+ Run `pjkit upgrade` inside it to see what is out of date, and `pjkit upgrade --apply`
72
+ to bring it up to date. Files you edited are never overwritten; see
73
+ [upgrading](https://github.com/miguelmatg/project-kit/blob/main/docs/upgrade.md).
74
+
75
+ ## Quick start
76
+
77
+ In your repository, new or existing:
78
+
79
+ ```bash
80
+ cd my-project
81
+ pjkit init
82
+ ```
83
+
84
+ `init` copies the skills and templates into the repository and then offers to open Claude Code
85
+ right there, already running `/pk-start` (press Enter to accept). `/pk-start` asks whether to
86
+ **only initialise** or to **start defining the project now**, and after every phase it asks
87
+ whether to continue or stop. You can leave at any point and come back later:
88
+
89
+ ```bash
90
+ pjkit status # where you are and what comes next
91
+ pjkit help # a visual guide to the flow and the commands
92
+ ```
93
+
94
+ ## The phases
95
+
96
+ | # | Skill | What it does | Produces |
97
+ |---|---|---|---|
98
+ | 0 | `/pk-start` | Checks your setup and lets you choose: only initialise, or start now | `.project-kit/` |
99
+ | 1 | `/pk-discover` | Interviews you about the project: problem, users, scope, constraints | `docs/project/brief.md` |
100
+ | 2 | `/pk-decide` | Guides the technical decisions: monolith or monorepo, language, package manager, data, auth, hosting | `docs/adr/*.md` |
101
+ | 3 | `/pk-workflow` | Agrees how the team works: branches, reviews, quality gates | `docs/development-workflow.md` |
102
+ | 4 | `/pk-foundations` | Writes the project's own rules from its stack: code standards, testing, security, documentation | `docs/project/standards.md`, `testing.md`, `security.md`, `documentation.md` |
103
+ | 5 | `/pk-plan` | Derives phases, epics and a backlog from all of the above | `docs/project/roadmap.md`, `.project-kit/backlog.json` |
104
+ | 6 | `/pk-provision` | Creates milestones, labels, branches, the GitHub Project and the issues (skipped with `provider: none`) | GitHub |
105
+ | 7 | `/pk-handoff` | Prepares the Spec Kit constitution; each issue becomes a spec; writes `CLAUDE.md` / `AGENTS.md` | `.project-kit/handoff/constitution-input.md` |
106
+
107
+ Outside the sequence, three skills are always available: `/pk-grill` interviews you hard and
108
+ cross-checks the project's documents for contradictions (it is offered before each approval),
109
+ `/pk-skills` recommends third-party skills that fit the project, and `/pk-amend` brings a change
110
+ after the plan (a new epic, a decision that replaces another) into the documents and the backlog.
111
+
112
+ Each phase ends with an explicit approval (`pjkit approve <phase>`), and a phase cannot be
113
+ approved while an earlier one is still open. The phases are listed in `.project-kit/workflow.yml`;
114
+ for a small project, switch one off with `enabled: false`.
115
+
116
+ To fill a document by hand instead, copy the matching template from `.project-kit/templates/`
117
+ (`brief.md`, `adr.md`, `development-workflow.md`). The skills read what is already there and only
118
+ ask about what is missing.
119
+
120
+ ## Existing repositories and Projects
121
+
122
+ `init` never overwrites a file, so it is safe in a repository that already has code, documents or
123
+ a `.claude/` folder. Before creating a GitHub Project, `provision` looks at the ones already
124
+ linked to the repository: with one it asks whether to use it, with several it lists them, and
125
+ with none it asks for a name. Use `--project <number or title>` to choose without being asked.
126
+ It never rewrites issues that already exist, and re-running it is always safe.
127
+
128
+ ## Commands
129
+
130
+ | Command | What it does |
131
+ |---|---|
132
+ | `pjkit init` | Install the skills, templates and workflow in the current directory |
133
+ | `pjkit status` | Show the phases and what comes next |
134
+ | `pjkit upgrade [--apply] [--adopt] [--diff]` | Update the skills and templates a project already has |
135
+ | `pjkit help` | Show a visual guide (also what plain `pjkit` prints) |
136
+ | `pjkit doctor` | Check that git, gh, uv and Spec Kit are available |
137
+ | `pjkit approve <phase>` | Record your sign-off of a phase |
138
+ | `pjkit backlog validate` | Validate `.project-kit/backlog.json` |
139
+ | `pjkit provision [--dry-run] [--project X]` | Create milestones, branches, the Project and issues on GitHub |
140
+ | `pjkit handoff [--install-speckit]` | Generate the Spec Kit constitution input |
141
+ | `pjkit context [--dry-run]` | Write or refresh the project block in `CLAUDE.md` / `AGENTS.md` / `GEMINI.md` |
142
+ | `pjkit skills list\|show\|mark` | Recommended third-party skills, their install command, and what the project decided |
143
+
144
+ Useful `init` options: `--project-name`, `--language` (language of the generated documents),
145
+ `--agents claude,codex,...` (the AI agents you use; asked when there is a terminal),
146
+ `--agent claude|none` (open the agent or not), `--provider github|gitlab|none` and
147
+ `--ai-coauthor keep|remove`.
148
+
149
+ ## AI agents
150
+
151
+ Like Spec Kit, `init` asks which agents you use, and you can pick several: Claude Code, Codex
152
+ CLI, Gemini CLI, GitHub Copilot and Cursor. The skills are installed where each one reads them
153
+ (`.claude/skills` for Claude Code, `.agents/skills` for the rest) and, at the end of the handoff, project-kit
154
+ writes the context file each one reads (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`). Only the block
155
+ between its markers is managed; the rest of the file is yours. Only Claude Code is started by
156
+ `init`; for the others, open the agent and ask it to run the `pk-start` skill.
157
+
158
+ ## GitLab
159
+
160
+ `pjkit init --provider gitlab` makes `provision` use `glab`: phases become milestones, kind,
161
+ priority, size and status become labels, and an issue board named `project-kit` is built from the
162
+ status labels. Details in [provisioning](https://github.com/miguelmatg/project-kit/blob/main/docs/provisioning.md).
163
+
164
+ ## Generating a project without GitHub
165
+
166
+ `pjkit init --provider none` generates everything that lives in files (brief, decisions, workflow,
167
+ rules, roadmap, backlog, constitution input, context files) and skips `provision`; `doctor` does
168
+ not ask for `gh` either.
169
+
170
+ ## Recommended skills
171
+
172
+ project-kit keeps a catalog of third-party skills (UI/UX, motion, accessibility, SEO, security,
173
+ architecture, browser testing, `grill-me`, `find-skills`...) in `.project-kit/skills-catalog.yml`.
174
+ `/pk-skills` recommends the ones that fit your brief and decisions, warns when a task would
175
+ benefit from one you do not have, and records the answer in `.project-kit/skills.yml`. project-kit
176
+ never installs a skill: it shows the command and you run it; `pjkit skills detect` records the ones you already have. How the entries were chosen is in
177
+ [docs/skills.md](https://github.com/miguelmatg/project-kit/blob/main/docs/skills.md).
178
+
179
+ ## AI co-author
180
+
181
+ `init` asks whether AI assistants may appear as co-authors of your commits and pull requests. If
182
+ not, it configures Claude Code to stop signing them and installs a `commit-msg` hook that strips
183
+ the co-author trailer of other assistants. Switch the hook on once per clone with
184
+ `git config core.hooksPath .githooks`.
185
+
186
+ ## After the handoff
187
+
188
+ `/pk-handoff` leaves a text file for Spec Kit's constitution and tells you the next step:
189
+
190
+ ```
191
+ /speckit-constitution @.project-kit/handoff/constitution-input.md
192
+ ```
193
+
194
+ From there Spec Kit does the work. Each issue of the backlog is one spec: its text is the input of
195
+ `/speckit-specify`, followed by `/speckit-clarify`, `/speckit-plan`, `/speckit-tasks` and
196
+ `/speckit-implement`. project-kit never writes inside `.specify/` and does not write specs.
197
+
198
+ The constitution is generated from your own rules: the branch pattern and merge strategy you agreed,
199
+ the decisions on record, and an index of where each kind of rule lives (including the GitHub
200
+ Project used for tasks). Once the constitution is written, `pjkit approve handoff` deletes
201
+ the temporary input files; from then on the constitution is the single source.
202
+
203
+ ## What it adds to your repository
204
+
205
+ ```
206
+ .project-kit/ config.yml, state.json, workflow.yml, templates/, handoff/
207
+ .claude/skills/pk-*/ the skills
208
+ docs/project/ brief.md, roadmap.md (created by the phases)
209
+ docs/adr/ one file per decision (created by the phases)
210
+ .githooks/commit-msg only if you removed the AI co-author
211
+ ```
212
+
213
+ ## Documentation
214
+
215
+ More detail lives in the repository (in Spanish):
216
+ [design](https://github.com/miguelmatg/project-kit/blob/main/docs/design.md),
217
+ [backlog schema](https://github.com/miguelmatg/project-kit/blob/main/docs/backlog-schema.md),
218
+ [provisioning](https://github.com/miguelmatg/project-kit/blob/main/docs/provisioning.md) and
219
+ [Spec Kit handoff](https://github.com/miguelmatg/project-kit/blob/main/docs/handoff.md).
220
+
221
+ ## Feedback
222
+
223
+ Ideas and bug reports are welcome as
224
+ [issues](https://github.com/miguelmatg/project-kit/issues). Pull requests are not accepted; see
225
+ [CONTRIBUTING](https://github.com/miguelmatg/project-kit/blob/main/CONTRIBUTING.md).
226
+
227
+ ## License
228
+
229
+ [MIT](https://github.com/miguelmatg/project-kit/blob/main/LICENSE)
@@ -0,0 +1,209 @@
1
+ # project-kit
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/project-kit-cli)](https://pypi.org/project/project-kit-cli/)
4
+ [![License: MIT](https://img.shields.io/pypi/l/project-kit-cli)](https://github.com/miguelmatg/project-kit/blob/main/LICENSE)
5
+
6
+ **Everything that happens before the first line of code.** project-kit guides you, with an AI
7
+ agent, through defining a project, deciding its stack and architecture, agreeing how the team
8
+ works and planning the backlog. It then sets up GitHub and hands the project over to
9
+ [Spec Kit](https://github.com/github/spec-kit), which specifies and builds each feature.
10
+
11
+ ```
12
+ idea ──▶ brief ──▶ decisions (ADRs) ──▶ workflow ──▶ backlog ──▶ GitHub ──▶ Spec Kit
13
+ /pk-discover /pk-decide /pk-workflow /pk-plan /pk-provision /pk-handoff
14
+ ```
15
+
16
+ The conversations run in your AI agent ([Claude Code](https://claude.com/claude-code), Codex CLI,
17
+ Gemini CLI, GitHub Copilot or Cursor) as
18
+ `/pk-…` skills: one question at a time, a recommended answer for each, and everything written to
19
+ documents in your repository. Every phase ends with your approval, and every document can be
20
+ written by hand instead.
21
+
22
+ > **Status: alpha.** It works end to end on GitHub with Claude Code. Other agents get their skills
23
+ > and context files but are started by hand. **GitLab support is new and has only been tried
24
+ > against a simulated API**, not a real GitLab project: read the `--dry-run` before applying.
25
+
26
+ ## Requirements
27
+
28
+ - [uv](https://docs.astral.sh/uv/) (it also fetches Python 3.12+ if you do not have it)
29
+ - `git`
30
+ - [Claude Code](https://claude.com/claude-code), to run the guided phases
31
+ - [`gh`](https://cli.github.com/), logged in with the `repo` and `project` scopes
32
+ (`gh auth login`, then `gh auth refresh -s project`), to create things on GitHub; or
33
+ [`glab`](https://gitlab.com/gitlab-org/cli) (`glab auth login`) for GitLab; or neither, with
34
+ `--provider none`
35
+
36
+ `pjkit doctor` checks all of this for you. Spec Kit is installed for you at the end, if
37
+ you want it.
38
+
39
+ ## Install
40
+
41
+ ```bash
42
+ uv tool install project-kit-cli # installs the `pjkit` command
43
+ uv tool upgrade project-kit-cli # later, to update the program
44
+ ```
45
+
46
+ The package is called `project-kit-cli`; the command is `pjkit`. To try it without
47
+ installing: `uvx --from project-kit-cli pjkit help`.
48
+
49
+ **Updating a project.** `init` copies the skills and templates into your repository and never
50
+ overwrites them, so a new version of the program does not change a project that already exists.
51
+ Run `pjkit upgrade` inside it to see what is out of date, and `pjkit upgrade --apply`
52
+ to bring it up to date. Files you edited are never overwritten; see
53
+ [upgrading](https://github.com/miguelmatg/project-kit/blob/main/docs/upgrade.md).
54
+
55
+ ## Quick start
56
+
57
+ In your repository, new or existing:
58
+
59
+ ```bash
60
+ cd my-project
61
+ pjkit init
62
+ ```
63
+
64
+ `init` copies the skills and templates into the repository and then offers to open Claude Code
65
+ right there, already running `/pk-start` (press Enter to accept). `/pk-start` asks whether to
66
+ **only initialise** or to **start defining the project now**, and after every phase it asks
67
+ whether to continue or stop. You can leave at any point and come back later:
68
+
69
+ ```bash
70
+ pjkit status # where you are and what comes next
71
+ pjkit help # a visual guide to the flow and the commands
72
+ ```
73
+
74
+ ## The phases
75
+
76
+ | # | Skill | What it does | Produces |
77
+ |---|---|---|---|
78
+ | 0 | `/pk-start` | Checks your setup and lets you choose: only initialise, or start now | `.project-kit/` |
79
+ | 1 | `/pk-discover` | Interviews you about the project: problem, users, scope, constraints | `docs/project/brief.md` |
80
+ | 2 | `/pk-decide` | Guides the technical decisions: monolith or monorepo, language, package manager, data, auth, hosting | `docs/adr/*.md` |
81
+ | 3 | `/pk-workflow` | Agrees how the team works: branches, reviews, quality gates | `docs/development-workflow.md` |
82
+ | 4 | `/pk-foundations` | Writes the project's own rules from its stack: code standards, testing, security, documentation | `docs/project/standards.md`, `testing.md`, `security.md`, `documentation.md` |
83
+ | 5 | `/pk-plan` | Derives phases, epics and a backlog from all of the above | `docs/project/roadmap.md`, `.project-kit/backlog.json` |
84
+ | 6 | `/pk-provision` | Creates milestones, labels, branches, the GitHub Project and the issues (skipped with `provider: none`) | GitHub |
85
+ | 7 | `/pk-handoff` | Prepares the Spec Kit constitution; each issue becomes a spec; writes `CLAUDE.md` / `AGENTS.md` | `.project-kit/handoff/constitution-input.md` |
86
+
87
+ Outside the sequence, three skills are always available: `/pk-grill` interviews you hard and
88
+ cross-checks the project's documents for contradictions (it is offered before each approval),
89
+ `/pk-skills` recommends third-party skills that fit the project, and `/pk-amend` brings a change
90
+ after the plan (a new epic, a decision that replaces another) into the documents and the backlog.
91
+
92
+ Each phase ends with an explicit approval (`pjkit approve <phase>`), and a phase cannot be
93
+ approved while an earlier one is still open. The phases are listed in `.project-kit/workflow.yml`;
94
+ for a small project, switch one off with `enabled: false`.
95
+
96
+ To fill a document by hand instead, copy the matching template from `.project-kit/templates/`
97
+ (`brief.md`, `adr.md`, `development-workflow.md`). The skills read what is already there and only
98
+ ask about what is missing.
99
+
100
+ ## Existing repositories and Projects
101
+
102
+ `init` never overwrites a file, so it is safe in a repository that already has code, documents or
103
+ a `.claude/` folder. Before creating a GitHub Project, `provision` looks at the ones already
104
+ linked to the repository: with one it asks whether to use it, with several it lists them, and
105
+ with none it asks for a name. Use `--project <number or title>` to choose without being asked.
106
+ It never rewrites issues that already exist, and re-running it is always safe.
107
+
108
+ ## Commands
109
+
110
+ | Command | What it does |
111
+ |---|---|
112
+ | `pjkit init` | Install the skills, templates and workflow in the current directory |
113
+ | `pjkit status` | Show the phases and what comes next |
114
+ | `pjkit upgrade [--apply] [--adopt] [--diff]` | Update the skills and templates a project already has |
115
+ | `pjkit help` | Show a visual guide (also what plain `pjkit` prints) |
116
+ | `pjkit doctor` | Check that git, gh, uv and Spec Kit are available |
117
+ | `pjkit approve <phase>` | Record your sign-off of a phase |
118
+ | `pjkit backlog validate` | Validate `.project-kit/backlog.json` |
119
+ | `pjkit provision [--dry-run] [--project X]` | Create milestones, branches, the Project and issues on GitHub |
120
+ | `pjkit handoff [--install-speckit]` | Generate the Spec Kit constitution input |
121
+ | `pjkit context [--dry-run]` | Write or refresh the project block in `CLAUDE.md` / `AGENTS.md` / `GEMINI.md` |
122
+ | `pjkit skills list\|show\|mark` | Recommended third-party skills, their install command, and what the project decided |
123
+
124
+ Useful `init` options: `--project-name`, `--language` (language of the generated documents),
125
+ `--agents claude,codex,...` (the AI agents you use; asked when there is a terminal),
126
+ `--agent claude|none` (open the agent or not), `--provider github|gitlab|none` and
127
+ `--ai-coauthor keep|remove`.
128
+
129
+ ## AI agents
130
+
131
+ Like Spec Kit, `init` asks which agents you use, and you can pick several: Claude Code, Codex
132
+ CLI, Gemini CLI, GitHub Copilot and Cursor. The skills are installed where each one reads them
133
+ (`.claude/skills` for Claude Code, `.agents/skills` for the rest) and, at the end of the handoff, project-kit
134
+ writes the context file each one reads (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`). Only the block
135
+ between its markers is managed; the rest of the file is yours. Only Claude Code is started by
136
+ `init`; for the others, open the agent and ask it to run the `pk-start` skill.
137
+
138
+ ## GitLab
139
+
140
+ `pjkit init --provider gitlab` makes `provision` use `glab`: phases become milestones, kind,
141
+ priority, size and status become labels, and an issue board named `project-kit` is built from the
142
+ status labels. Details in [provisioning](https://github.com/miguelmatg/project-kit/blob/main/docs/provisioning.md).
143
+
144
+ ## Generating a project without GitHub
145
+
146
+ `pjkit init --provider none` generates everything that lives in files (brief, decisions, workflow,
147
+ rules, roadmap, backlog, constitution input, context files) and skips `provision`; `doctor` does
148
+ not ask for `gh` either.
149
+
150
+ ## Recommended skills
151
+
152
+ project-kit keeps a catalog of third-party skills (UI/UX, motion, accessibility, SEO, security,
153
+ architecture, browser testing, `grill-me`, `find-skills`...) in `.project-kit/skills-catalog.yml`.
154
+ `/pk-skills` recommends the ones that fit your brief and decisions, warns when a task would
155
+ benefit from one you do not have, and records the answer in `.project-kit/skills.yml`. project-kit
156
+ never installs a skill: it shows the command and you run it; `pjkit skills detect` records the ones you already have. How the entries were chosen is in
157
+ [docs/skills.md](https://github.com/miguelmatg/project-kit/blob/main/docs/skills.md).
158
+
159
+ ## AI co-author
160
+
161
+ `init` asks whether AI assistants may appear as co-authors of your commits and pull requests. If
162
+ not, it configures Claude Code to stop signing them and installs a `commit-msg` hook that strips
163
+ the co-author trailer of other assistants. Switch the hook on once per clone with
164
+ `git config core.hooksPath .githooks`.
165
+
166
+ ## After the handoff
167
+
168
+ `/pk-handoff` leaves a text file for Spec Kit's constitution and tells you the next step:
169
+
170
+ ```
171
+ /speckit-constitution @.project-kit/handoff/constitution-input.md
172
+ ```
173
+
174
+ From there Spec Kit does the work. Each issue of the backlog is one spec: its text is the input of
175
+ `/speckit-specify`, followed by `/speckit-clarify`, `/speckit-plan`, `/speckit-tasks` and
176
+ `/speckit-implement`. project-kit never writes inside `.specify/` and does not write specs.
177
+
178
+ The constitution is generated from your own rules: the branch pattern and merge strategy you agreed,
179
+ the decisions on record, and an index of where each kind of rule lives (including the GitHub
180
+ Project used for tasks). Once the constitution is written, `pjkit approve handoff` deletes
181
+ the temporary input files; from then on the constitution is the single source.
182
+
183
+ ## What it adds to your repository
184
+
185
+ ```
186
+ .project-kit/ config.yml, state.json, workflow.yml, templates/, handoff/
187
+ .claude/skills/pk-*/ the skills
188
+ docs/project/ brief.md, roadmap.md (created by the phases)
189
+ docs/adr/ one file per decision (created by the phases)
190
+ .githooks/commit-msg only if you removed the AI co-author
191
+ ```
192
+
193
+ ## Documentation
194
+
195
+ More detail lives in the repository (in Spanish):
196
+ [design](https://github.com/miguelmatg/project-kit/blob/main/docs/design.md),
197
+ [backlog schema](https://github.com/miguelmatg/project-kit/blob/main/docs/backlog-schema.md),
198
+ [provisioning](https://github.com/miguelmatg/project-kit/blob/main/docs/provisioning.md) and
199
+ [Spec Kit handoff](https://github.com/miguelmatg/project-kit/blob/main/docs/handoff.md).
200
+
201
+ ## Feedback
202
+
203
+ Ideas and bug reports are welcome as
204
+ [issues](https://github.com/miguelmatg/project-kit/issues). Pull requests are not accepted; see
205
+ [CONTRIBUTING](https://github.com/miguelmatg/project-kit/blob/main/CONTRIBUTING.md).
206
+
207
+ ## License
208
+
209
+ [MIT](https://github.com/miguelmatg/project-kit/blob/main/LICENSE)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "project-kit-cli"
3
- version = "0.1.0"
3
+ version = "0.3.0"
4
4
  description = "Project definition and dev-workflow kit that hands off to Spec Kit"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -31,7 +31,7 @@ Repository = "https://github.com/miguelmatg/project-kit"
31
31
  Issues = "https://github.com/miguelmatg/project-kit/issues"
32
32
 
33
33
  [project.scripts]
34
- project-kit = "project_kit.cli:main"
34
+ pjkit = "project_kit.cli:main"
35
35
 
36
36
  [tool.uv.build-backend]
37
37
  module-name = "project_kit"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "project-kit-cli"
3
- version = "0.1.0"
3
+ version = "0.3.0"
4
4
  description = "Project definition and dev-workflow kit that hands off to Spec Kit"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -25,7 +25,7 @@ Repository = "https://github.com/miguelmatg/project-kit"
25
25
  Issues = "https://github.com/miguelmatg/project-kit/issues"
26
26
 
27
27
  [project.scripts]
28
- project-kit = "project_kit.cli:main"
28
+ pjkit = "project_kit.cli:main"
29
29
 
30
30
  [tool.uv.build-backend]
31
31
  # The distribution is project-kit-cli (the name free on PyPI); the package keeps its name.
@@ -0,0 +1,179 @@
1
+ """AI coding agents project-kit installs for, and can hand the terminal over to after ``init``.
2
+
3
+ An agent is whatever reads the installed skills. Each one has a directory where it looks for
4
+ skills and a context file it reads at the start of a session; several agents may share both
5
+ (``.agents/skills`` and ``AGENTS.md`` are read by Codex, Cursor, Copilot and Gemini CLI).
6
+ Only an agent with a ``prompt`` can be started by ``init``: the others are opened by the user,
7
+ because how a skill is invoked differs between tools and project-kit does not guess it.
8
+ Supporting another agent is a new entry in ``AGENTS``.
9
+ """
10
+
11
+ import os
12
+ import shutil
13
+ import subprocess
14
+ from collections.abc import Callable, Mapping, Sequence
15
+ from dataclasses import dataclass
16
+ from pathlib import Path
17
+
18
+
19
+ @dataclass(frozen=True)
20
+ class Agent:
21
+ id: str
22
+ name: str
23
+ executable: str
24
+ install_hint: str
25
+ skills_dir: str # where the agent looks for skills, relative to the repository
26
+ context_file: str # the file it reads for the project's context, relative to the repository
27
+ speckit_key: str = "" # its name in `specify init --integration`
28
+ prompt: str = "" # what it is started with (the entry-point skill); empty: not launchable
29
+ inside_env: str = "" # environment variable it sets in the shells it opens, if any
30
+
31
+
32
+ AGENTS = (
33
+ Agent(
34
+ id="claude",
35
+ name="Claude Code",
36
+ executable="claude",
37
+ install_hint="https://claude.com/claude-code",
38
+ skills_dir=".claude/skills",
39
+ context_file="CLAUDE.md",
40
+ speckit_key="claude",
41
+ prompt="/pk-start",
42
+ inside_env="CLAUDECODE",
43
+ ),
44
+ Agent(
45
+ id="codex",
46
+ name="Codex CLI",
47
+ executable="codex",
48
+ install_hint="https://developers.openai.com/codex/cli",
49
+ skills_dir=".agents/skills",
50
+ context_file="AGENTS.md",
51
+ speckit_key="codex",
52
+ ),
53
+ Agent(
54
+ id="gemini",
55
+ name="Gemini CLI",
56
+ executable="gemini",
57
+ install_hint="https://github.com/google-gemini/gemini-cli",
58
+ skills_dir=".agents/skills", # the documented alias of .gemini/skills
59
+ context_file="GEMINI.md",
60
+ speckit_key="gemini",
61
+ ),
62
+ Agent(
63
+ id="copilot",
64
+ name="GitHub Copilot",
65
+ executable="copilot",
66
+ install_hint="https://docs.github.com/copilot",
67
+ skills_dir=".agents/skills",
68
+ context_file="AGENTS.md",
69
+ speckit_key="copilot",
70
+ ),
71
+ Agent(
72
+ id="cursor",
73
+ name="Cursor",
74
+ executable="cursor-agent",
75
+ install_hint="https://cursor.com/cli",
76
+ skills_dir=".agents/skills",
77
+ context_file="AGENTS.md",
78
+ speckit_key="cursor-agent",
79
+ ),
80
+ )
81
+ AGENT_IDS = tuple(a.id for a in AGENTS)
82
+ DEFAULT_AGENTS = ("claude",)
83
+
84
+
85
+ def get_agent(agent_id: str) -> Agent:
86
+ return next(a for a in AGENTS if a.id == agent_id)
87
+
88
+
89
+ def launchable(selected: Sequence[Agent] | None = None) -> list[Agent]:
90
+ """The agents ``init`` can start, among ``selected`` (default: all)."""
91
+ return [a for a in (AGENTS if selected is None else selected) if a.prompt]
92
+
93
+
94
+ def skills_dirs(agent_ids: Sequence[str]) -> list[str]:
95
+ """Where the skills go for these agents, without repeats, in order."""
96
+ return list(dict.fromkeys(get_agent(i).skills_dir for i in agent_ids))
97
+
98
+
99
+ def context_files(agent_ids: Sequence[str]) -> list[str]:
100
+ """The context files of these agents, without repeats, in order."""
101
+ return list(dict.fromkeys(get_agent(i).context_file for i in agent_ids))
102
+
103
+
104
+ def is_inside(agent: Agent, env: Mapping[str, str] | None = None) -> bool:
105
+ """True when we run from a shell opened by this agent: launching it again would nest."""
106
+ if not agent.inside_env:
107
+ return False
108
+ return bool((os.environ if env is None else env).get(agent.inside_env))
109
+
110
+
111
+ def parse_ids(text: str) -> list[str]:
112
+ """Agent ids from a comma-separated list, validated; ``ValueError`` names the bad ones."""
113
+ ids = list(dict.fromkeys(p.strip().lower() for p in text.split(",") if p.strip()))
114
+ bad = [i for i in ids if i not in AGENT_IDS]
115
+ if bad:
116
+ raise ValueError(f"unknown agent(s): {', '.join(bad)}; choose from {', '.join(AGENT_IDS)}")
117
+ return ids
118
+
119
+
120
+ def choose_many(
121
+ ask: Callable[[str], str] | None = None,
122
+ out: Callable[[str], None] = print,
123
+ ) -> list[str]:
124
+ """Ask which agents the project is used with (several allowed). Enter takes the default."""
125
+ out("\nWhich AI agents will you use in this project? Skills are installed for each one.")
126
+ for n, agent in enumerate(AGENTS, 1):
127
+ out(f" {n}) {agent.name}")
128
+ try:
129
+ answer = (ask or input)("Numbers separated by commas [1]: ").strip()
130
+ except EOFError: # no terminal attached: keep the default
131
+ return list(DEFAULT_AGENTS)
132
+ if answer == "":
133
+ return list(DEFAULT_AGENTS)
134
+ picked = [p.strip() for p in answer.split(",") if p.strip()]
135
+ if not all(p.isdigit() and 1 <= int(p) <= len(AGENTS) for p in picked):
136
+ out(f"Not understood; using the default ({', '.join(DEFAULT_AGENTS)}).")
137
+ return list(DEFAULT_AGENTS)
138
+ return list(dict.fromkeys(AGENTS[int(p) - 1].id for p in picked))
139
+
140
+
141
+ def find_executable(agent: Agent) -> str | None:
142
+ return shutil.which(agent.executable)
143
+
144
+
145
+ def choose(
146
+ ask: Callable[[str], str] | None = None,
147
+ out: Callable[[str], None] = print,
148
+ options: Sequence[Agent] | None = None,
149
+ ) -> Agent | None:
150
+ """Ask which agent to open now. Enter takes the first one. ``None``: the user declines."""
151
+ pool = launchable(options)
152
+ if not pool:
153
+ return None
154
+ out("\nOpen an AI agent now to continue with /pk-start?")
155
+ for n, agent in enumerate(pool, 1):
156
+ out(f" {n}) {agent.name}")
157
+ none = len(pool) + 1
158
+ out(f" {none}) No, I will do it myself")
159
+ try:
160
+ answer = (ask or input)("Choice [1]: ").strip()
161
+ except EOFError: # no terminal attached: never launch anything
162
+ return None
163
+ if answer == "":
164
+ return pool[0]
165
+ if answer.isdigit() and 1 <= int(answer) <= len(pool):
166
+ return pool[int(answer) - 1]
167
+ return None
168
+
169
+
170
+ def launch(agent: Agent, root: Path, run: Callable[..., object] = subprocess.run) -> int:
171
+ """Run the agent in the current terminal, in ``root``, started with its entry skill.
172
+
173
+ Returns the agent's exit code; the terminal is inherited, so it is interactive.
174
+ """
175
+ exe = find_executable(agent)
176
+ if exe is None:
177
+ raise FileNotFoundError(agent.executable)
178
+ result = run([exe, agent.prompt], cwd=root, check=False)
179
+ return getattr(result, "returncode", 0)
@@ -60,6 +60,11 @@ def install_hook(root: Path) -> tuple[Path | None, str]:
60
60
  return HOOK, ""
61
61
 
62
62
 
63
+ def hook_bytes() -> bytes:
64
+ """The shipped commit-msg hook, as it is installed."""
65
+ return (files("project_kit") / "assets" / "hooks" / "commit-msg").read_bytes()
66
+
67
+
63
68
  def hook_is_active(root: Path) -> bool:
64
69
  """True if git is already pointed at ``.githooks`` in this repository."""
65
70
  config = root / ".git" / "config"