@julioborges/gantry 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.
- package/.agents/skills/gantry/SKILL.md +166 -0
- package/.agents/skills/gantry/capabilities/claude-code.json +15 -0
- package/.agents/skills/gantry/capabilities/codex.json +14 -0
- package/.agents/skills/gantry/capabilities/opencode.json +15 -0
- package/.agents/skills/gantry/dashboard/static/app.js +100 -0
- package/.agents/skills/gantry/dashboard/static/index.html +16 -0
- package/.agents/skills/gantry/dashboard/static/style.css +74 -0
- package/.agents/skills/gantry/hooks/claude-code.settings.json +56 -0
- package/.agents/skills/gantry/hooks/codex.hooks.json +4 -0
- package/.agents/skills/gantry/hooks/git/pre-commit +77 -0
- package/.agents/skills/gantry/hooks/git/pre-push +123 -0
- package/.agents/skills/gantry/hooks/git/skipscan.py +88 -0
- package/.agents/skills/gantry/hooks/opencode.plugin.js +44 -0
- package/.agents/skills/gantry/reference/plan-workflow.md +383 -0
- package/.agents/skills/gantry/reference/round-workflow.md +755 -0
- package/.agents/skills/gantry/schemas/critic.json +93 -0
- package/.agents/skills/gantry/schemas/implementer.json +52 -0
- package/.agents/skills/gantry/schemas/learner.json +35 -0
- package/.agents/skills/gantry/schemas/plan-critic.json +39 -0
- package/.agents/skills/gantry/schemas/planner.json +64 -0
- package/.agents/skills/gantry/schemas/requirement-critic.json +48 -0
- package/.agents/skills/gantry/schemas/reviewer.json +52 -0
- package/.agents/skills/gantry/scripts/acceptance.py +66 -0
- package/.agents/skills/gantry/scripts/budget.py +162 -0
- package/.agents/skills/gantry/scripts/cleanup.py +186 -0
- package/.agents/skills/gantry/scripts/common.py +361 -0
- package/.agents/skills/gantry/scripts/dashboard.py +233 -0
- package/.agents/skills/gantry/scripts/frontier.py +192 -0
- package/.agents/skills/gantry/scripts/gates.py +401 -0
- package/.agents/skills/gantry/scripts/guard.py +568 -0
- package/.agents/skills/gantry/scripts/learner.py +99 -0
- package/.agents/skills/gantry/scripts/result.py +104 -0
- package/.agents/skills/gantry/scripts/roadmap.py +212 -0
- package/.agents/skills/gantry/scripts/runlog.py +491 -0
- package/.agents/skills/gantry/scripts/setup.py +139 -0
- package/.agents/skills/gantry/scripts/spec.py +252 -0
- package/.agents/skills/gantry/templates/issue.md +32 -0
- package/.agents/skills/gantry/templates/prd.md +26 -0
- package/.agents/skills/gantry/templates/spec.md +48 -0
- package/.agents/skills/gantry-dashboard/SKILL.md +55 -0
- package/.agents/skills/gantry-setup/SKILL.md +30 -0
- package/LICENSE +201 -0
- package/README.md +437 -0
- package/bin/gantry.mjs +45 -0
- package/package.json +36 -0
- package/scripts/ensure-npm-author.mjs +29 -0
package/README.md
ADDED
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
# Gantry
|
|
2
|
+
|
|
3
|
+
**Turn an approved Spec into verified software deliveries inside your coding
|
|
4
|
+
harness.**
|
|
5
|
+
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](#requirements)
|
|
8
|
+
[](#installation)
|
|
9
|
+
[](#project-status)
|
|
10
|
+
|
|
11
|
+
Gantry is an open source, harness-neutral skill pack for agentic software
|
|
12
|
+
development. Deterministic scripts decide which Issues are ready and whether
|
|
13
|
+
checks pass. Fresh agents implement, review, and challenge each delivery. You
|
|
14
|
+
approve the plan and decide how the resulting Run is handed off.
|
|
15
|
+
|
|
16
|
+
[Get started](#quick-start) · [Greenfield example](#greenfield-build-a-new-project) ·
|
|
17
|
+
[Brownfield example](#brownfield-extend-an-existing-project) ·
|
|
18
|
+
[Contribute](#contributing)
|
|
19
|
+
|
|
20
|
+
## Why Gantry?
|
|
21
|
+
|
|
22
|
+
Agent-written code needs more than a passing test suite and a completion summary.
|
|
23
|
+
Gantry gives each delivery a repeatable path from requirements to independent
|
|
24
|
+
verification:
|
|
25
|
+
|
|
26
|
+
- **Plan before building.** Validate the Spec, create vertical-slice Issues, and
|
|
27
|
+
critique the breakdown before asking for your approval.
|
|
28
|
+
- **Verify independently.** A fresh Critic runs acceptance checks and real
|
|
29
|
+
repository gates, demanding evidence for every criterion.
|
|
30
|
+
- **Respect dependencies.** Scripts compute readiness from the blocker graph;
|
|
31
|
+
accepted branches integrate serially with gates after every merge.
|
|
32
|
+
- **Track delivery in Git.** Markdown Issues and `ROADMAP.md` record completion;
|
|
33
|
+
only the roadmap script updates authoritative status and checkboxes.
|
|
34
|
+
- **Keep decisions in your harness.** Review plans, proposed lessons, draft PRs,
|
|
35
|
+
and cleanup without a separate execution service.
|
|
36
|
+
|
|
37
|
+
Named after the [gantry crane](https://en.wikipedia.org/wiki/Gantry_crane), the
|
|
38
|
+
pack provides the rails for the work. See [ADR-0004](docs/adr/0004-skill-pack-instead-of-an-engine.md)
|
|
39
|
+
for the product boundary.
|
|
40
|
+
|
|
41
|
+
## Project status
|
|
42
|
+
|
|
43
|
+
The canonical pack lives in `.agents/skills/`. Gantry is under active development.
|
|
44
|
+
Capability files declare harness tiers; fixture validation is required before
|
|
45
|
+
claiming support for a particular integration. See [PRD §13](PRD.md#13-harness-support)
|
|
46
|
+
for harness support and fixture requirements. A declared tier does not prove every harness version
|
|
47
|
+
has been exercised.
|
|
48
|
+
|
|
49
|
+
The npm installer is configured locally as `@julioborges/gantry` version `0.1.0`;
|
|
50
|
+
publication is a separate release step. Use the GitHub installation below until
|
|
51
|
+
an npm release is available.
|
|
52
|
+
|
|
53
|
+
## Requirements
|
|
54
|
+
|
|
55
|
+
| Component | Requirement |
|
|
56
|
+
|---|---|
|
|
57
|
+
| Workflow | Python 3.10+ and Git |
|
|
58
|
+
| Agent environment | A coding harness that can load skills and run commands |
|
|
59
|
+
| npm installer | Node.js 22.20.0+ |
|
|
60
|
+
| Draft Run PR (optional) | `gh`, authenticated with access to the repository |
|
|
61
|
+
| Project checks | Your project's own toolchain and dependencies |
|
|
62
|
+
|
|
63
|
+
Gantry's workflow scripts use only the Python standard library. Your project's
|
|
64
|
+
checks can require additional tools. Keep the host harness open during a Run;
|
|
65
|
+
Gantry does not continue as a background service.
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
|
|
69
|
+
Run this in the project where you want to use Gantry:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx skills add JulioBorges/gantry
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Select all three skills and your harness in the installer:
|
|
76
|
+
|
|
77
|
+
| Skill | Purpose |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `gantry-setup` | Configure artifact locations, templates, checks, Git policy, and hooks |
|
|
80
|
+
| `gantry` | Plan and execute verified Issues |
|
|
81
|
+
| `gantry-dashboard` | Open the read-only kanban for recorded Runs |
|
|
82
|
+
|
|
83
|
+
You can also copy or symlink the three directories into
|
|
84
|
+
`<repo>/.agents/skills/` or `~/.agents/skills/`. The repository copy wins.
|
|
85
|
+
|
|
86
|
+
Once the npm package is published, its bundled installer supports:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npx @julioborges/gantry add
|
|
90
|
+
npx @julioborges/gantry add --agent codex --yes
|
|
91
|
+
npx @julioborges/gantry add --global
|
|
92
|
+
npx @julioborges/gantry add --list
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`add` delegates to a pinned version of the [skills CLI](https://github.com/vercel-labs/skills)
|
|
96
|
+
using the bundled files. Agent selection and global installation options pass
|
|
97
|
+
through unchanged. The npm command installs skills; it does not execute a Run.
|
|
98
|
+
|
|
99
|
+
## Quick start
|
|
100
|
+
|
|
101
|
+
After installation, open your coding harness in the repository and send:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
Use gantry-setup to configure this repository. Present the proposed artifact
|
|
105
|
+
locations, templates, check commands, Git target, and hook settings for approval
|
|
106
|
+
before applying the policy.
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Approve the reviewed setup, prepare a Spec using the
|
|
110
|
+
[default template](.agents/skills/gantry/templates/spec.md) or your repository's
|
|
111
|
+
configured equivalent, and commit the setup and Spec. Start from a clean Git
|
|
112
|
+
working tree, then send:
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
Use gantry for Spec delivery-api. Validate the Spec and prepare the Issue
|
|
116
|
+
breakdown. Stop for my planning approval before implementation.
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Review the resulting Issues, criteria, dependencies, and plan critique. If you
|
|
120
|
+
accept that particular breakdown, send:
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
I approve the delivery-api Spec and the Issue breakdown just presented.
|
|
124
|
+
Use gantry delivery-api --limit 4 --budget 2 to execute all approved Issues.
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
These are **prompts in your coding harness**, not terminal commands. Use its
|
|
128
|
+
skill invocation syntax when available, or explicitly name the skill in prose.
|
|
129
|
+
`delivery-api` identifies your Spec scope, normally
|
|
130
|
+
`.scratch/delivery-api/spec.md`; it is not a filename to copy verbatim.
|
|
131
|
+
|
|
132
|
+
## Complete execution examples
|
|
133
|
+
|
|
134
|
+
The examples below cover setup, Spec preparation, planning approval,
|
|
135
|
+
implementation, and handoff. Spec authoring happens before the Gantry Run;
|
|
136
|
+
Gantry reads and critiques the Spec rather than rewriting it.
|
|
137
|
+
|
|
138
|
+
### Greenfield: build a new project
|
|
139
|
+
|
|
140
|
+
Build a small Python CLI that adds and lists tasks in a local JSON file. Start
|
|
141
|
+
with an initial Git commit so the Run has a target branch to branch from:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
mkdir task-cli
|
|
145
|
+
cd task-cli
|
|
146
|
+
git init -b main
|
|
147
|
+
printf '# Task CLI\n' > README.md
|
|
148
|
+
git add README.md
|
|
149
|
+
git commit -m "Initialize task CLI repository"
|
|
150
|
+
npx skills add JulioBorges/gantry
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**1. Configure the repository.** Open your harness in `task-cli` and send:
|
|
154
|
+
|
|
155
|
+
```text
|
|
156
|
+
Use gantry-setup for this new Python project. Propose main as the Git target,
|
|
157
|
+
.scratch/<slug>/ for Specs and Issues, and unittest discovery as the test gate.
|
|
158
|
+
There is no test suite yet: identify the bootstrap requirement, and do not
|
|
159
|
+
accept no_gates or an empty test run as proof of completion. Present the full
|
|
160
|
+
policy and hook choices before writing them.
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Review and approve the proposed policy. The bootstrap Issue must establish and
|
|
164
|
+
exercise meaningful tests before it can complete.
|
|
165
|
+
|
|
166
|
+
**2. Prepare the Spec outside the Run.** Create
|
|
167
|
+
`.scratch/task-cli/spec.md` from the effective template and fill every required
|
|
168
|
+
section. Define these outcomes and boundaries:
|
|
169
|
+
|
|
170
|
+
- `python3 -m task_cli add "Buy milk" --file tasks.json` creates a stored task
|
|
171
|
+
with a unique ID and reports it to the user.
|
|
172
|
+
- `python3 -m task_cli list --file tasks.json` lists stored tasks; a missing file
|
|
173
|
+
produces an empty list without an error.
|
|
174
|
+
- Tasks persist across separate CLI invocations. Empty titles and malformed JSON
|
|
175
|
+
produce a clear error and a nonzero exit code without overwriting stored data.
|
|
176
|
+
- Tests exercise the CLI with temporary files. No network, accounts, task
|
|
177
|
+
deletion, or UI is included.
|
|
178
|
+
|
|
179
|
+
Include observable Given/When/Then scenarios and regression guardrails in the
|
|
180
|
+
Spec. Commit the installation files, approved setup, and completed Spec before
|
|
181
|
+
starting the Run.
|
|
182
|
+
|
|
183
|
+
**3. Request and review the plan.** Send:
|
|
184
|
+
|
|
185
|
+
```text
|
|
186
|
+
Use gantry task-cli --limit 2 --budget 2. Validate the Spec and prepare vertical
|
|
187
|
+
slices covering every outcome, including bootstrap tests. Show the dependencies
|
|
188
|
+
and plan critique, then stop for my approval.
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
A possible breakdown is an add-and-persist slice with real tests, followed by a
|
|
192
|
+
list-and-error-handling slice. Review the actual generated plan rather than
|
|
193
|
+
assuming these example slices are authoritative. Amend the Spec if Requirement
|
|
194
|
+
Review finds a blocker, then request planning again.
|
|
195
|
+
|
|
196
|
+
**4. Approve the concrete plan and execute.** After reviewing the draft Issues:
|
|
197
|
+
|
|
198
|
+
```text
|
|
199
|
+
I approve the task-cli Spec and the exact Issue breakdown just presented.
|
|
200
|
+
Use gantry task-cli --limit 2 --budget 2 to execute the approved scope in a
|
|
201
|
+
dedicated Run worktree. Keep the bootstrap test gate meaningful.
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Answer the preflight worktree and model choices. Gantry schedules ready Issues,
|
|
205
|
+
implements each with TDD, reviews it, runs independent Critic verification, and
|
|
206
|
+
integrates accepted work into the Run branch. Successful rounds advance until
|
|
207
|
+
the scope completes; a failed round stops with evidence and preserved work.
|
|
208
|
+
|
|
209
|
+
**5. Review the handoff.** Expect criterion evidence, integration gate results,
|
|
210
|
+
updated Issues and roadmap, the declared support tier, remaining frontier,
|
|
211
|
+
optional lesson candidates, and a cleanup plan. If you want the offered PR:
|
|
212
|
+
|
|
213
|
+
```text
|
|
214
|
+
Open the draft Run pull request from the reported Run branch to main using the
|
|
215
|
+
verified delivery evidence. Leave merging for my review.
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
If `gh` is unavailable, the Run branch is the handoff. Review the proposed
|
|
219
|
+
cleanup separately before authorizing removal of any branches or worktrees.
|
|
220
|
+
|
|
221
|
+
### Brownfield: extend an existing project
|
|
222
|
+
|
|
223
|
+
Add pagination to an existing `GET /orders` endpoint while preserving its
|
|
224
|
+
current behavior for clients that do not request pagination.
|
|
225
|
+
|
|
226
|
+
**1. Establish the baseline and install.** In your existing repository, review
|
|
227
|
+
`git status`, resolve uncommitted work, install project dependencies, and run the
|
|
228
|
+
current checks using the repository's documented commands. Then install Gantry:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
npx skills add JulioBorges/gantry
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**2. Adapt setup to existing conventions.** Open your harness and send:
|
|
235
|
+
|
|
236
|
+
```text
|
|
237
|
+
Use gantry-setup for this existing repository. Inspect AGENTS.md, the canonical
|
|
238
|
+
Specs and Issues, ADRs, test commands, and target branch. Reuse those locations
|
|
239
|
+
and templates; propose equivalent heading mappings where needed. Preserve
|
|
240
|
+
existing hooks and present any conflicts. Show the full proposed policy before
|
|
241
|
+
writing it. Keep tests absolute; offer differential checks only where real
|
|
242
|
+
structured output supports comparison.
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Approve the concrete settings. Existing debt in a differential check remains
|
|
246
|
+
visible; new or aggravated findings block. An absolute check still has to pass.
|
|
247
|
+
Setup does not waive a failing baseline or approve the feature plan.
|
|
248
|
+
|
|
249
|
+
**3. Prepare or adapt the canonical Spec.** Use the agreed location and template
|
|
250
|
+
for the `orders-pagination` scope. Include these explicit behaviors:
|
|
251
|
+
|
|
252
|
+
- Requests without pagination parameters keep the existing response shape,
|
|
253
|
+
ordering, and authorization behavior.
|
|
254
|
+
- Requests with `page` and `pageSize` return the agreed paginated contract,
|
|
255
|
+
including stable ordering and the defined metadata.
|
|
256
|
+
- Invalid values return the repository's standard client error. Define default
|
|
257
|
+
values, maximum page size, and out-of-range behavior in the Spec.
|
|
258
|
+
- Existing clients and access restrictions have regression scenarios. Tests use
|
|
259
|
+
the repository's established integration fixtures and required real services.
|
|
260
|
+
- No schema migration, authorization redesign, or unrelated refactoring is
|
|
261
|
+
included.
|
|
262
|
+
|
|
263
|
+
Replace every undecided detail with an agreed value before planning. If an
|
|
264
|
+
existing Spec is missing required content, review and amend it in its canonical
|
|
265
|
+
format. Commit the installation, approved setup, and Spec so preflight sees a
|
|
266
|
+
clean working tree.
|
|
267
|
+
|
|
268
|
+
**4. Plan, approve, and execute.** Send:
|
|
269
|
+
|
|
270
|
+
```text
|
|
271
|
+
Use gantry orders-pagination --limit 2 --budget 2. Validate the canonical Spec,
|
|
272
|
+
inspect existing endpoint and integration tests, and propose vertical slices
|
|
273
|
+
with compatibility criteria. Stop after the plan critique for my approval.
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
After reviewing that exact breakdown, send:
|
|
277
|
+
|
|
278
|
+
```text
|
|
279
|
+
I approve the orders-pagination Spec and the Issue breakdown just presented.
|
|
280
|
+
Use gantry orders-pagination --limit 2 --budget 2 in a dedicated Run worktree.
|
|
281
|
+
Execute the approved scope with the configured gates and regression checks.
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Answer the worktree and model choices. Each accepted Issue integrates into the
|
|
285
|
+
Run branch serially; gates run after every merge. A red integration gate stops
|
|
286
|
+
the Run. Changes to approved behavior or dependencies require a plan amendment.
|
|
287
|
+
|
|
288
|
+
**5. Inspect results and resume when needed.** Review the same evidence-backed
|
|
289
|
+
handoff described in the greenfield example. To revisit an interrupted scope:
|
|
290
|
+
|
|
291
|
+
```text
|
|
292
|
+
Use gantry orders-pagination. Report remaining ready and blocked Issues and
|
|
293
|
+
any in-flight worktrees. Offer continuation in the preserved worktree before
|
|
294
|
+
starting new work, retaining correction attempts already spent.
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Continuation is an operator choice, not an automatic budget reset. Once the
|
|
298
|
+
scope completes, explicitly authorize the offered draft Run PR if desired,
|
|
299
|
+
review it under the repository's normal process, and approve cleanup separately.
|
|
300
|
+
|
|
301
|
+
## How a Run works
|
|
302
|
+
|
|
303
|
+
```text
|
|
304
|
+
Preflight → Spec validation → Requirement Review → Plan → Plan critique
|
|
305
|
+
↓
|
|
306
|
+
Operator approval
|
|
307
|
+
↓
|
|
308
|
+
Ready Issues → Implement (TDD) → Review → Critic → Serial integration
|
|
309
|
+
↑ │ + gates
|
|
310
|
+
└── bounded corrections ┘ ↓
|
|
311
|
+
Roadmap update
|
|
312
|
+
↓
|
|
313
|
+
Next round or final report + PR offer
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Already planned scopes skip planning. `--limit` caps Issues per round (default
|
|
317
|
+
4); `--budget` caps Critic correction attempts per Issue (default 2). The single
|
|
318
|
+
review fix pass is separate. These limits do not approve a plan or restrict a
|
|
319
|
+
Run to a single round.
|
|
320
|
+
|
|
321
|
+
| Scope | Meaning |
|
|
322
|
+
|---|---|
|
|
323
|
+
| `delivery-api` | One Spec's Issues |
|
|
324
|
+
| `delivery-api#01` | One Issue |
|
|
325
|
+
| `wave:1` | A roadmap wave |
|
|
326
|
+
| `frontier` | Currently ready work |
|
|
327
|
+
| `all` | All discovered Issues |
|
|
328
|
+
| `"free-text goal"` | Unplanned scope; draft planning stops for approval |
|
|
329
|
+
|
|
330
|
+
Workflow scripts own readiness (`frontier.py`), criteria (`acceptance.py`),
|
|
331
|
+
gates (`gates.py`), Spec structure (`spec.py`), context estimates (`budget.py`),
|
|
332
|
+
result validation (`result.py`), and status updates (`roadmap.py`). Guard hooks
|
|
333
|
+
block shortcuts and record events; they never grant completion.
|
|
334
|
+
|
|
335
|
+
Only Critic acceptance, passing gates, and a clean worktree permit completion.
|
|
336
|
+
Gantry offers one draft PR per Run after explicit approval. It never merges
|
|
337
|
+
into the target branch. Lessons stay proposals, and cleanup requires approval
|
|
338
|
+
of the printed plan.
|
|
339
|
+
|
|
340
|
+
## Harness capabilities
|
|
341
|
+
|
|
342
|
+
The current [capability files](.agents/skills/gantry/capabilities/) declare:
|
|
343
|
+
|
|
344
|
+
| Tier | Harness | Declared capabilities |
|
|
345
|
+
|---|---|---|
|
|
346
|
+
| Reference | Claude Code | Parallel rounds, native structured output, worktree isolation, per-role models, hooks |
|
|
347
|
+
| Supported | OpenCode | Per-role models and plugin hooks; script-validated results; manually managed isolation |
|
|
348
|
+
| Compatible | Codex | Manually driven chain and script-validated results; no hooks or native parallel rounds declared |
|
|
349
|
+
|
|
350
|
+
Use the host's available features without assuming parity. Every final Run
|
|
351
|
+
report states its declared tier. Gantry does not provide session security or
|
|
352
|
+
output redaction; apply your harness's policy layer for those concerns.
|
|
353
|
+
|
|
354
|
+
## Dashboard and artifacts
|
|
355
|
+
|
|
356
|
+
Ask your harness to `use gantry-dashboard` to open the read-only local kanban.
|
|
357
|
+
It displays recorded Runs and operator waits; decisions remain in the harness.
|
|
358
|
+
|
|
359
|
+
| Artifact | Default location |
|
|
360
|
+
|---|---|
|
|
361
|
+
| Spec | `.scratch/<slug>/spec.md` |
|
|
362
|
+
| Issues | `.scratch/<slug>/issues/` |
|
|
363
|
+
| Delivery roadmap | `ROADMAP.md` |
|
|
364
|
+
| Repository policy | `.gantry/config.json` |
|
|
365
|
+
| Custom templates | `.gantry/templates/` |
|
|
366
|
+
| Run logs | `~/.gantry/state/<unit-id>/runs/<run-id>.jsonl` |
|
|
367
|
+
|
|
368
|
+
Setup can map existing repository locations. Issue status and criteria are the
|
|
369
|
+
authority on delivery state; Run logs provide observation across a clone's
|
|
370
|
+
worktrees.
|
|
371
|
+
|
|
372
|
+
## Documentation
|
|
373
|
+
|
|
374
|
+
- [Product requirements](PRD.md): scope, workflow, and acceptance requirements.
|
|
375
|
+
- [Domain glossary](CONTEXT.md): canonical terms and product boundaries.
|
|
376
|
+
- [Architecture decisions](docs/adr/): standing decisions.
|
|
377
|
+
- [Agent contribution rules](AGENTS.md): repository instructions.
|
|
378
|
+
- [Delivery roadmap](ROADMAP.md): implementation progress and dependencies.
|
|
379
|
+
- [Workflow skill](.agents/skills/gantry/SKILL.md): execution protocol and references.
|
|
380
|
+
|
|
381
|
+
## Contributing
|
|
382
|
+
|
|
383
|
+
Bug reports, documentation improvements, and focused pull requests are welcome.
|
|
384
|
+
Use [GitHub Issues](https://github.com/JulioBorges/gantry/issues) to describe a
|
|
385
|
+
reproducible problem or propose a change. Delivery Issues used by Gantry itself
|
|
386
|
+
remain local Markdown artifacts.
|
|
387
|
+
|
|
388
|
+
Before changing the pack, read `PRD.md`, `CONTEXT.md`, `docs/adr/`, and `AGENTS.md`.
|
|
389
|
+
Keep documentation and generated artifacts in English. Explain behavior changes
|
|
390
|
+
and include validation evidence in your pull request.
|
|
391
|
+
|
|
392
|
+
Run the Python suite from the repository root:
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
make test
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
For installer or packaging changes, also run:
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
npm ci
|
|
402
|
+
npm run test:package
|
|
403
|
+
npm pack --dry-run
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
Frontend changes require Playwright validation under `AGENTS.md`. Complete
|
|
407
|
+
roadmap Issues only when all criteria are met, using `roadmap.py done`, and
|
|
408
|
+
verify with `roadmap.py check`.
|
|
409
|
+
|
|
410
|
+
### Publishing to npm
|
|
411
|
+
|
|
412
|
+
The package is configured for public publication as `@julioborges/gantry`, initially version `0.1.0`.
|
|
413
|
+
Only the installer, three skill directories, README and license are included; Python caches,
|
|
414
|
+
project Issues, fixtures, local configuration and runtime state are excluded.
|
|
415
|
+
|
|
416
|
+
```bash
|
|
417
|
+
npm ci
|
|
418
|
+
npm run test:package
|
|
419
|
+
npm pack --dry-run
|
|
420
|
+
# After approving the release and authenticating with an account allowed to publish the scope:
|
|
421
|
+
make release
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
`make release` verifies the npm account before installing locked dependencies with `npm ci` and publishing the current version from
|
|
425
|
+
`package.json` to npm. Update that version before publishing a subsequent release.
|
|
426
|
+
`prepublishOnly` first checks `npm whoami` against npmjs.org and refuses publication unless the
|
|
427
|
+
authenticated account is exactly `julioborges`. Authentication and network failures block publication.
|
|
428
|
+
This applies to both `make release` and direct `npm publish`; npm's registry permissions remain the
|
|
429
|
+
authority, and lifecycle hooks can be bypassed with npm options.
|
|
430
|
+
After authorization, it runs the repository test suite and the tarball installation test once before publication.
|
|
431
|
+
The tarball test executes `npx` and installs all three skills in a temporary project using the packed
|
|
432
|
+
artifact. See [npm's package metadata documentation](https://docs.npmjs.com/cli/v11/configuring-npm/package-json/)
|
|
433
|
+
for the `bin`, `files` and `publishConfig` settings. No automatic publication is configured.
|
|
434
|
+
|
|
435
|
+
## License
|
|
436
|
+
|
|
437
|
+
Gantry is licensed under the [Apache License 2.0](LICENSE).
|
package/bin/gantry.mjs
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
5
|
+
import { dirname, resolve } from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
9
|
+
const [command, ...options] = process.argv.slice(2);
|
|
10
|
+
|
|
11
|
+
if (!command || ['--help', '-h', 'help'].includes(command)) {
|
|
12
|
+
console.log(`Gantry skill pack installer
|
|
13
|
+
|
|
14
|
+
Usage: gantry add [skills options]
|
|
15
|
+
gantry --version
|
|
16
|
+
|
|
17
|
+
Install into the current project:
|
|
18
|
+
npx @julioborges/gantry add
|
|
19
|
+
npx @julioborges/gantry add --agent codex --yes
|
|
20
|
+
|
|
21
|
+
Install into your user environment:
|
|
22
|
+
npx @julioborges/gantry add --global
|
|
23
|
+
|
|
24
|
+
List bundled skills without installing:
|
|
25
|
+
npx @julioborges/gantry add --list
|
|
26
|
+
|
|
27
|
+
Options are passed to the skills CLI. After installation, invoke gantry-setup
|
|
28
|
+
inside your coding harness. Runs execute in the harness, not this installer.`);
|
|
29
|
+
} else if (['--version', '-v'].includes(command)) {
|
|
30
|
+
console.log(JSON.parse(readFileSync(resolve(packageRoot, 'package.json'), 'utf8')).version);
|
|
31
|
+
} else if (command === 'add') {
|
|
32
|
+
const require = createRequire(import.meta.url);
|
|
33
|
+
const skillsRoot = dirname(require.resolve('skills/package.json'));
|
|
34
|
+
const manifest = JSON.parse(readFileSync(resolve(skillsRoot, 'package.json'), 'utf8'));
|
|
35
|
+
const result = spawnSync(process.execPath, [
|
|
36
|
+
resolve(skillsRoot, manifest.bin.skills), 'add', resolve(packageRoot, '.agents/skills'), ...options,
|
|
37
|
+
], { stdio: 'inherit' });
|
|
38
|
+
if (result.error) {
|
|
39
|
+
console.error(`Gantry installation failed: ${result.error.message}`);
|
|
40
|
+
}
|
|
41
|
+
process.exitCode = result.status ?? 1;
|
|
42
|
+
} else {
|
|
43
|
+
console.error(`Unknown command: ${command}. Use gantry --help.`);
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@julioborges/gantry",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Install the Gantry harness-neutral agentic SDLC skill pack.",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/JulioBorges/gantry.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/JulioBorges/gantry#readme",
|
|
12
|
+
"bugs": "https://github.com/JulioBorges/gantry/issues",
|
|
13
|
+
"keywords": ["agent-skills", "gantry", "sdlc", "claude-code", "codex", "opencode"],
|
|
14
|
+
"engines": {"node": ">=22.20.0"},
|
|
15
|
+
"bin": {"gantry": "bin/gantry.mjs"},
|
|
16
|
+
"files": [
|
|
17
|
+
"bin/gantry.mjs",
|
|
18
|
+
"scripts/ensure-npm-author.mjs",
|
|
19
|
+
".agents/skills/gantry",
|
|
20
|
+
".agents/skills/gantry-setup",
|
|
21
|
+
".agents/skills/gantry-dashboard",
|
|
22
|
+
"README.md",
|
|
23
|
+
"LICENSE",
|
|
24
|
+
"!**/__pycache__/**",
|
|
25
|
+
"!**/*.pyc",
|
|
26
|
+
"!**/.DS_Store"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"test": "make test",
|
|
30
|
+
"test:package": "node --test tests/npm-package.test.mjs tests/npm-author.test.mjs",
|
|
31
|
+
"pack:check": "npm run test:package",
|
|
32
|
+
"prepublishOnly": "node scripts/ensure-npm-author.mjs && npm test && npm run test:package"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {"skills": "1.5.26"},
|
|
35
|
+
"publishConfig": {"access": "public", "registry": "https://registry.npmjs.org/"}
|
|
36
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { pathToFileURL } from 'node:url';
|
|
3
|
+
|
|
4
|
+
const author = 'julioborges';
|
|
5
|
+
const registry = 'https://registry.npmjs.org/';
|
|
6
|
+
|
|
7
|
+
export function ensureNpmAuthor(run = spawnSync) {
|
|
8
|
+
const args = ['whoami', '--registry', registry];
|
|
9
|
+
const result = process.env.npm_execpath
|
|
10
|
+
? run(process.execPath, [process.env.npm_execpath, ...args], { encoding: 'utf8', timeout: 30_000 })
|
|
11
|
+
: run(process.platform === 'win32' ? 'npm.cmd' : 'npm', args, {
|
|
12
|
+
encoding: 'utf8', timeout: 30_000, shell: process.platform === 'win32',
|
|
13
|
+
});
|
|
14
|
+
if (result.error || result.status !== 0) {
|
|
15
|
+
throw new Error('Publication blocked: could not verify the npm account. Run npm login for npmjs.org.');
|
|
16
|
+
}
|
|
17
|
+
if (result.stdout.trim() !== author) {
|
|
18
|
+
throw new Error(`Publication blocked: only npm account ${author} may publish this package.`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
23
|
+
try {
|
|
24
|
+
ensureNpmAuthor();
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.error(error.message);
|
|
27
|
+
process.exitCode = 1;
|
|
28
|
+
}
|
|
29
|
+
}
|