reyson-spec-gate 0.1.0 → 0.1.1
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 +148 -166
- package/bin/reyson-spec-gate.js +239 -0
- package/bin/skill-reyson.js +1 -233
- package/package.json +3 -2
- package/templates/adapters/AGENTS.md +0 -16
- package/templates/adapters/CLAUDE.md +0 -16
- /package/templates/{adapters/RULES.md → RULES.md} +0 -0
package/README.md
CHANGED
|
@@ -1,272 +1,254 @@
|
|
|
1
|
-
#
|
|
1
|
+
# reyson-spec-gate
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A spec-first installer for coding-agent workflow rules, docs, and skills.
|
|
4
4
|
|
|
5
|
-
`
|
|
5
|
+
`reyson-spec-gate` is designed to install a consistent pre-coding workflow into a workspace so that agents do not jump directly from a loose request into implementation.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Its central rule is simple:
|
|
8
8
|
|
|
9
9
|
> No coding before the spec is clear, the task list exists, and the checklist exists.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Recommended usage
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Do **not** rely on global installation as the primary path.
|
|
16
|
+
|
|
17
|
+
The recommended way to use this package is:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx reyson-spec-gate
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This launches the interactive installer directly and avoids depending on a permanently global npm installation.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## What it installs
|
|
28
|
+
|
|
29
|
+
The installer always installs the shared workflow assets:
|
|
16
30
|
|
|
17
31
|
- `docs/spec-workflow.md`
|
|
18
32
|
- `skills/generate-task-list/SKILL.md`
|
|
19
33
|
- `skills/generate-checklist/SKILL.md`
|
|
20
34
|
|
|
21
|
-
|
|
35
|
+
It also installs **RULES.md only** for selected agents.
|
|
22
36
|
|
|
23
|
-
|
|
37
|
+
It does **not** install:
|
|
38
|
+
- `AGENTS.md`
|
|
39
|
+
- `CLAUDE.md`
|
|
24
40
|
|
|
25
|
-
- `
|
|
26
|
-
- `CLAUDE.md` for Claude Code-style workflows
|
|
27
|
-
- `RULES.md` as a generic rules entrypoint
|
|
41
|
+
All agent-specific rule entrypoints are normalized to `RULES.md`.
|
|
28
42
|
|
|
29
43
|
---
|
|
30
44
|
|
|
31
|
-
##
|
|
45
|
+
## Supported agents
|
|
32
46
|
|
|
33
|
-
|
|
34
|
-
npm i -g reyson-spec-gate
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Quick start
|
|
47
|
+
The interactive installer currently supports these agent targets:
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
1. Codex
|
|
50
|
+
2. Trae
|
|
51
|
+
3. Claude Code
|
|
52
|
+
4. Cursor
|
|
53
|
+
5. Antigravity
|
|
40
54
|
|
|
41
|
-
|
|
42
|
-
skill-reyson
|
|
43
|
-
```
|
|
55
|
+
You can select one or more targets in the same run.
|
|
44
56
|
|
|
45
|
-
|
|
57
|
+
If you do not select anything, the installer will:
|
|
58
|
+
- default to **Codex**
|
|
59
|
+
- print a message explaining that Codex was chosen by default
|
|
46
60
|
|
|
47
|
-
|
|
48
|
-
# install only docs + skills into the current project
|
|
49
|
-
skill-reyson install --yes --dir .
|
|
61
|
+
---
|
|
50
62
|
|
|
51
|
-
|
|
52
|
-
skill-reyson install --yes --dir . --with-agent-files --agents codex
|
|
53
|
-
```
|
|
63
|
+
## Interactive behavior
|
|
54
64
|
|
|
55
|
-
|
|
65
|
+
Run:
|
|
56
66
|
|
|
57
67
|
```bash
|
|
58
|
-
|
|
68
|
+
npx reyson-spec-gate
|
|
59
69
|
```
|
|
60
70
|
|
|
61
|
-
|
|
71
|
+
The installer will ask:
|
|
72
|
+
1. which directory to install into
|
|
73
|
+
2. which agent targets to install for
|
|
62
74
|
|
|
63
|
-
|
|
64
|
-
skill-reyson install
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
---
|
|
75
|
+
Agent selection is multi-select.
|
|
68
76
|
|
|
69
|
-
|
|
77
|
+
Example:
|
|
78
|
+
- `1,3,4` installs for Codex, Claude Code, and Cursor
|
|
70
79
|
|
|
71
|
-
|
|
80
|
+
If you press ENTER without choosing an agent, it falls back to Codex.
|
|
72
81
|
|
|
73
|
-
|
|
74
|
-
1. where to install the scaffold
|
|
75
|
-
2. whether to install agent guidance files
|
|
76
|
-
3. which agent adapters to install
|
|
82
|
+
---
|
|
77
83
|
|
|
78
|
-
|
|
84
|
+
## Output structure
|
|
79
85
|
|
|
80
|
-
|
|
81
|
-
- docs and skills are installed
|
|
82
|
-
- `AGENTS.md` / `CLAUDE.md` / `RULES.md` are **not** installed
|
|
86
|
+
The installer writes the shared assets into the target directory and installs rule files per agent under `agents/<agent>/RULES.md`.
|
|
83
87
|
|
|
84
|
-
|
|
88
|
+
Example output:
|
|
85
89
|
|
|
86
|
-
|
|
90
|
+
```text
|
|
91
|
+
my-project/
|
|
92
|
+
├── docs/
|
|
93
|
+
│ └── spec-workflow.md
|
|
94
|
+
├── skills/
|
|
95
|
+
│ ├── generate-task-list/
|
|
96
|
+
│ │ └── SKILL.md
|
|
97
|
+
│ └── generate-checklist/
|
|
98
|
+
│ └── SKILL.md
|
|
99
|
+
└── agents/
|
|
100
|
+
├── codex/
|
|
101
|
+
│ └── RULES.md
|
|
102
|
+
├── claude-code/
|
|
103
|
+
│ └── RULES.md
|
|
104
|
+
└── cursor/
|
|
105
|
+
└── RULES.md
|
|
106
|
+
```
|
|
87
107
|
|
|
88
|
-
|
|
108
|
+
This structure avoids filename collisions when multiple agents are installed in one run.
|
|
89
109
|
|
|
90
|
-
|
|
110
|
+
---
|
|
91
111
|
|
|
92
|
-
|
|
112
|
+
## Non-interactive usage
|
|
93
113
|
|
|
94
|
-
|
|
95
|
-
skill-reyson install --yes --dir ./my-project
|
|
96
|
-
```
|
|
114
|
+
If you want a scriptable path, you can still run the installer non-interactively.
|
|
97
115
|
|
|
98
|
-
###
|
|
116
|
+
### Default to Codex
|
|
99
117
|
|
|
100
118
|
```bash
|
|
101
|
-
|
|
119
|
+
npx reyson-spec-gate install --yes --dir ./my-project
|
|
102
120
|
```
|
|
103
121
|
|
|
104
|
-
### Install multiple agent
|
|
122
|
+
### Install multiple agent targets
|
|
105
123
|
|
|
106
124
|
```bash
|
|
107
|
-
|
|
125
|
+
npx reyson-spec-gate install --yes --dir ./my-project --agents codex,trae,claude,cursor,antigravity
|
|
108
126
|
```
|
|
109
127
|
|
|
110
128
|
---
|
|
111
129
|
|
|
112
|
-
## Why
|
|
113
|
-
|
|
114
|
-
In many spec-driven workflows, an agent may produce a decent spec and still move into coding too early.
|
|
130
|
+
## Why `npx` is preferred
|
|
115
131
|
|
|
116
|
-
|
|
117
|
-
- the task list is implicit instead of explicit
|
|
118
|
-
- the checklist is missing or too generic
|
|
119
|
-
- the agent starts coding before execution and verification artifacts are aligned
|
|
132
|
+
The purpose of this package is to run an installation workflow, not simply to sit globally on a machine.
|
|
120
133
|
|
|
121
|
-
`
|
|
134
|
+
Using `npx reyson-spec-gate` is preferable because:
|
|
135
|
+
- it is explicit
|
|
136
|
+
- it is easy to run in any repository
|
|
137
|
+
- it avoids stale global versions
|
|
138
|
+
- it keeps the install workflow lightweight
|
|
122
139
|
|
|
123
|
-
|
|
124
|
-
- **docs** explain the workflow and readiness gate
|
|
125
|
-
- **skills** generate missing artifacts
|
|
140
|
+
Global installation can still work, but it is no longer the recommended entrypoint.
|
|
126
141
|
|
|
127
142
|
---
|
|
128
143
|
|
|
129
|
-
##
|
|
130
|
-
|
|
131
|
-
```text
|
|
132
|
-
skill-reyson/
|
|
133
|
-
├── AGENTS.md
|
|
134
|
-
├── LICENSE
|
|
135
|
-
├── README.md
|
|
136
|
-
├── package.json
|
|
137
|
-
├── bin/
|
|
138
|
-
│ └── skill-reyson.js
|
|
139
|
-
├── docs/
|
|
140
|
-
│ └── spec-workflow.md
|
|
141
|
-
├── examples/
|
|
142
|
-
│ ├── example-derived-artifacts.md
|
|
143
|
-
│ └── example-input-spec.md
|
|
144
|
-
├── skills/
|
|
145
|
-
│ ├── generate-task-list/
|
|
146
|
-
│ │ └── SKILL.md
|
|
147
|
-
│ └── generate-checklist/
|
|
148
|
-
│ └── SKILL.md
|
|
149
|
-
└── templates/
|
|
150
|
-
└── adapters/
|
|
151
|
-
├── AGENTS.md
|
|
152
|
-
├── CLAUDE.md
|
|
153
|
-
└── RULES.md
|
|
154
|
-
```
|
|
144
|
+
## Workflow model
|
|
155
145
|
|
|
156
|
-
|
|
146
|
+
This package is based on a spec-first coding workflow.
|
|
157
147
|
|
|
158
|
-
|
|
148
|
+
The intended flow is:
|
|
159
149
|
|
|
160
|
-
|
|
150
|
+
1. The agent reads `docs/spec-workflow.md`
|
|
151
|
+
2. The agent checks whether the current work has:
|
|
152
|
+
- a working spec
|
|
153
|
+
- a task list
|
|
154
|
+
- a checklist
|
|
155
|
+
3. If the task list is missing, the agent uses `generate-task-list`
|
|
156
|
+
4. If the checklist is missing, the agent uses `generate-checklist`
|
|
157
|
+
5. Only after both artifacts exist does coding begin
|
|
158
|
+
6. After coding, the checklist is revisited before claiming completion
|
|
161
159
|
|
|
162
|
-
|
|
160
|
+
---
|
|
163
161
|
|
|
164
|
-
|
|
165
|
-
- read the workflow doc before coding
|
|
166
|
-
- check whether task list and checklist exist
|
|
167
|
-
- generate missing artifacts before implementation
|
|
168
|
-
- revisit the checklist after coding
|
|
162
|
+
## Responsibilities
|
|
169
163
|
|
|
170
|
-
###
|
|
164
|
+
### `docs/spec-workflow.md`
|
|
171
165
|
|
|
172
|
-
This is the workflow knowledge
|
|
166
|
+
This file is the workflow knowledge source.
|
|
173
167
|
|
|
174
168
|
It defines:
|
|
175
169
|
- the pre-coding gate
|
|
176
|
-
- artifact ordering
|
|
177
|
-
- task-list
|
|
178
|
-
- checklist
|
|
170
|
+
- artifact ordering
|
|
171
|
+
- task-list requirements
|
|
172
|
+
- checklist requirements
|
|
179
173
|
- coding readiness rules
|
|
180
|
-
- post-coding
|
|
174
|
+
- post-coding verification rules
|
|
181
175
|
|
|
182
|
-
###
|
|
176
|
+
### `skills/generate-task-list`
|
|
183
177
|
|
|
184
|
-
|
|
178
|
+
This skill generates or normalizes an explicit task list from a spec or plan.
|
|
185
179
|
|
|
186
|
-
|
|
187
|
-
Use this when the workflow has a spec or plan but no explicit task list.
|
|
180
|
+
### `skills/generate-checklist`
|
|
188
181
|
|
|
189
|
-
|
|
190
|
-
Use this when the workflow has a spec and task list but no explicit checklist.
|
|
182
|
+
This skill generates a checklist from the working spec and task list.
|
|
191
183
|
|
|
192
|
-
|
|
184
|
+
### `agents/<agent>/RULES.md`
|
|
193
185
|
|
|
194
|
-
|
|
186
|
+
Each selected agent receives a `RULES.md` entrypoint.
|
|
195
187
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
6. If checklist is missing, generate it
|
|
202
|
-
7. Start coding only after the readiness gate is satisfied
|
|
203
|
-
8. Revisit the checklist after coding
|
|
188
|
+
Its job is to remind the target agent to:
|
|
189
|
+
- read the workflow doc first
|
|
190
|
+
- check for task list and checklist presence
|
|
191
|
+
- generate missing artifacts before implementation
|
|
192
|
+
- avoid coding before the pre-coding gate passes
|
|
204
193
|
|
|
205
194
|
---
|
|
206
195
|
|
|
207
|
-
##
|
|
196
|
+
## Example installation commands
|
|
208
197
|
|
|
209
|
-
|
|
210
|
-
- `examples/example-input-spec.md`
|
|
211
|
-
- `examples/example-derived-artifacts.md`
|
|
198
|
+
### Install for Codex only
|
|
212
199
|
|
|
213
|
-
|
|
200
|
+
```bash
|
|
201
|
+
npx reyson-spec-gate install --yes --dir ./my-project --agents codex
|
|
202
|
+
```
|
|
214
203
|
|
|
215
|
-
|
|
204
|
+
### Install for Trae and Cursor
|
|
216
205
|
|
|
217
|
-
|
|
206
|
+
```bash
|
|
207
|
+
npx reyson-spec-gate install --yes --dir ./my-project --agents trae,cursor
|
|
208
|
+
```
|
|
218
209
|
|
|
219
|
-
|
|
210
|
+
### Install for all supported agents
|
|
220
211
|
|
|
221
212
|
```bash
|
|
222
|
-
|
|
223
|
-
node bin/skill-reyson.js install
|
|
213
|
+
npx reyson-spec-gate install --yes --dir ./my-project --agents codex,trae,claude,cursor,antigravity
|
|
224
214
|
```
|
|
225
215
|
|
|
226
216
|
---
|
|
227
217
|
|
|
228
|
-
##
|
|
218
|
+
## Development
|
|
229
219
|
|
|
230
|
-
|
|
220
|
+
Run locally:
|
|
231
221
|
|
|
232
|
-
|
|
233
|
-
-
|
|
234
|
-
-
|
|
235
|
-
|
|
236
|
-
- project-specific workflow variants
|
|
237
|
-
- validation fixtures and smoke tests
|
|
222
|
+
```bash
|
|
223
|
+
node bin/reyson-spec-gate.js --help
|
|
224
|
+
node bin/reyson-spec-gate.js install
|
|
225
|
+
```
|
|
238
226
|
|
|
239
227
|
---
|
|
240
228
|
|
|
241
|
-
##
|
|
229
|
+
## Package identity
|
|
242
230
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
- `node bin/skill-reyson.js --help` works
|
|
246
|
-
- `skill-reyson install --yes --dir /tmp/somewhere` copies the expected files
|
|
247
|
-
- default install does **not** copy agent guidance files
|
|
248
|
-
- `--with-agent-files --agents ...` copies the selected adapter files
|
|
249
|
-
- `README.md` matches current CLI behavior
|
|
250
|
-
- `package.json` name, version, license, and bin entry are correct
|
|
251
|
-
|
|
252
|
-
### Suggested GitHub steps
|
|
231
|
+
Current npm package:
|
|
253
232
|
|
|
254
233
|
```bash
|
|
255
|
-
|
|
256
|
-
git remote add origin <your-github-repo-url>
|
|
257
|
-
git push -u origin master
|
|
234
|
+
reyson-spec-gate
|
|
258
235
|
```
|
|
259
236
|
|
|
260
|
-
|
|
237
|
+
Recommended invocation:
|
|
261
238
|
|
|
262
239
|
```bash
|
|
263
|
-
|
|
264
|
-
npm login
|
|
265
|
-
npm publish
|
|
240
|
+
npx reyson-spec-gate
|
|
266
241
|
```
|
|
267
242
|
|
|
268
|
-
|
|
243
|
+
---
|
|
269
244
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
245
|
+
## Notes
|
|
246
|
+
|
|
247
|
+
This repository intentionally standardizes every agent rule entrypoint to `RULES.md`.
|
|
248
|
+
|
|
249
|
+
That means:
|
|
250
|
+
- no `AGENTS.md`
|
|
251
|
+
- no `CLAUDE.md`
|
|
252
|
+
- a single normalized rules filename for all supported agent targets
|
|
253
|
+
|
|
254
|
+
This keeps the workflow easier to reason about and easier to extend.
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const readline = require('readline');
|
|
5
|
+
|
|
6
|
+
const PACKAGE_ROOT = path.resolve(__dirname, '..');
|
|
7
|
+
const DOC_SOURCE = path.join(PACKAGE_ROOT, 'docs', 'spec-workflow.md');
|
|
8
|
+
const RULES_SOURCE = path.join(PACKAGE_ROOT, 'templates', 'RULES.md');
|
|
9
|
+
const SKILL_SOURCES = [
|
|
10
|
+
{
|
|
11
|
+
source: path.join(PACKAGE_ROOT, 'skills', 'generate-task-list', 'SKILL.md'),
|
|
12
|
+
relativeTarget: path.join('skills', 'generate-task-list', 'SKILL.md'),
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
source: path.join(PACKAGE_ROOT, 'skills', 'generate-checklist', 'SKILL.md'),
|
|
16
|
+
relativeTarget: path.join('skills', 'generate-checklist', 'SKILL.md'),
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const AGENTS = {
|
|
21
|
+
codex: { label: 'Codex', target: path.join('agents', 'codex', 'RULES.md') },
|
|
22
|
+
trae: { label: 'Trae', target: path.join('agents', 'trae', 'RULES.md') },
|
|
23
|
+
claude: { label: 'Claude Code', target: path.join('agents', 'claude-code', 'RULES.md') },
|
|
24
|
+
cursor: { label: 'Cursor', target: path.join('agents', 'cursor', 'RULES.md') },
|
|
25
|
+
antigravity: { label: 'Antigravity', target: path.join('agents', 'antigravity', 'RULES.md') },
|
|
26
|
+
};
|
|
27
|
+
const DEFAULT_AGENT = 'codex';
|
|
28
|
+
const AGENT_NUMBER_MAP = { '1': 'codex', '2': 'trae', '3': 'claude', '4': 'cursor', '5': 'antigravity' };
|
|
29
|
+
|
|
30
|
+
function printHelp() {
|
|
31
|
+
console.log(`reyson-spec-gate
|
|
32
|
+
|
|
33
|
+
Recommended usage:
|
|
34
|
+
npx reyson-spec-gate
|
|
35
|
+
|
|
36
|
+
Other usage:
|
|
37
|
+
reyson-spec-gate Start interactive installer
|
|
38
|
+
reyson-spec-gate install Start interactive installer
|
|
39
|
+
reyson-spec-gate install --dir <path>
|
|
40
|
+
reyson-spec-gate install --yes [--dir <path>] [--agents codex,trae,claude,cursor,antigravity]
|
|
41
|
+
reyson-spec-gate --help Show help
|
|
42
|
+
|
|
43
|
+
Interactive defaults:
|
|
44
|
+
- Installs docs/spec-workflow.md
|
|
45
|
+
- Installs skills/generate-task-list/SKILL.md
|
|
46
|
+
- Installs skills/generate-checklist/SKILL.md
|
|
47
|
+
- Prompts for agent selection
|
|
48
|
+
- If no agent is selected, defaults to Codex
|
|
49
|
+
- Installs RULES.md only (never AGENTS.md / CLAUDE.md)
|
|
50
|
+
`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function parseArgs(argv) {
|
|
54
|
+
const args = argv.slice(2);
|
|
55
|
+
const options = { command: 'install', dir: process.cwd(), yes: false, agents: [] };
|
|
56
|
+
if (args[0] && !args[0].startsWith('-')) {
|
|
57
|
+
options.command = args.shift();
|
|
58
|
+
}
|
|
59
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
60
|
+
const arg = args[i];
|
|
61
|
+
if (arg === '--help' || arg === '-h') {
|
|
62
|
+
options.command = 'help';
|
|
63
|
+
} else if (arg === '--yes' || arg === '-y') {
|
|
64
|
+
options.yes = true;
|
|
65
|
+
} else if (arg === '--dir') {
|
|
66
|
+
options.dir = path.resolve(args[i + 1] || process.cwd());
|
|
67
|
+
i += 1;
|
|
68
|
+
} else if (arg.startsWith('--dir=')) {
|
|
69
|
+
options.dir = path.resolve(arg.split('=')[1]);
|
|
70
|
+
} else if (arg === '--agents') {
|
|
71
|
+
options.agents = (args[i + 1] || '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
72
|
+
i += 1;
|
|
73
|
+
} else if (arg.startsWith('--agents=')) {
|
|
74
|
+
options.agents = arg.split('=')[1].split(',').map((s) => s.trim()).filter(Boolean);
|
|
75
|
+
} else {
|
|
76
|
+
throw new Error(`Unknown argument: ${arg}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return options;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function ensureDir(dirPath) {
|
|
83
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function copyFile(source, target) {
|
|
87
|
+
ensureDir(path.dirname(target));
|
|
88
|
+
fs.copyFileSync(source, target);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function normalizeAgents(agentKeys) {
|
|
92
|
+
return Array.from(new Set(agentKeys.map((key) => key.toLowerCase()).filter((key) => AGENTS[key])));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function copyCoreArtifacts(targetDir) {
|
|
96
|
+
const docTarget = path.join(targetDir, 'docs', 'spec-workflow.md');
|
|
97
|
+
copyFile(DOC_SOURCE, docTarget);
|
|
98
|
+
for (const skill of SKILL_SOURCES) {
|
|
99
|
+
copyFile(skill.source, path.join(targetDir, skill.relativeTarget));
|
|
100
|
+
}
|
|
101
|
+
return [
|
|
102
|
+
path.relative(targetDir, docTarget),
|
|
103
|
+
...SKILL_SOURCES.map((skill) => skill.relativeTarget),
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function copyRulesFiles(targetDir, selectedAgents) {
|
|
108
|
+
const copied = [];
|
|
109
|
+
for (const key of selectedAgents) {
|
|
110
|
+
const agent = AGENTS[key];
|
|
111
|
+
if (!agent) continue;
|
|
112
|
+
copyFile(RULES_SOURCE, path.join(targetDir, agent.target));
|
|
113
|
+
copied.push(agent.target);
|
|
114
|
+
}
|
|
115
|
+
return copied;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function createInterface() {
|
|
119
|
+
return readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function ask(rl, question) {
|
|
123
|
+
return new Promise((resolve) => rl.question(question, resolve));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function parseInteractiveAgents(answer) {
|
|
127
|
+
const raw = answer.trim();
|
|
128
|
+
if (!raw) {
|
|
129
|
+
return { agents: [DEFAULT_AGENT], usedDefault: true };
|
|
130
|
+
}
|
|
131
|
+
const selected = normalizeAgents(raw.split(',').map((token) => {
|
|
132
|
+
const trimmed = token.trim();
|
|
133
|
+
return AGENT_NUMBER_MAP[trimmed] || trimmed;
|
|
134
|
+
}));
|
|
135
|
+
if (selected.length === 0) {
|
|
136
|
+
return { agents: [DEFAULT_AGENT], usedDefault: true };
|
|
137
|
+
}
|
|
138
|
+
return { agents: selected, usedDefault: false };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function performInstall({ targetDir, agents }) {
|
|
142
|
+
ensureDir(targetDir);
|
|
143
|
+
const coreFiles = copyCoreArtifacts(targetDir);
|
|
144
|
+
const normalizedAgents = normalizeAgents(agents);
|
|
145
|
+
const finalAgents = normalizedAgents.length > 0 ? normalizedAgents : [DEFAULT_AGENT];
|
|
146
|
+
const rulesFiles = copyRulesFiles(targetDir, finalAgents);
|
|
147
|
+
return { targetDir, coreFiles, rulesFiles, agents: finalAgents };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function printSummary(result) {
|
|
151
|
+
console.log('\nInstalled reyson-spec-gate scaffold:\n');
|
|
152
|
+
console.log(`Target: ${result.targetDir}`);
|
|
153
|
+
console.log('\nCore files:');
|
|
154
|
+
for (const file of result.coreFiles) {
|
|
155
|
+
console.log(` - ${file}`);
|
|
156
|
+
}
|
|
157
|
+
console.log('\nAgent rule files:');
|
|
158
|
+
for (const file of result.rulesFiles) {
|
|
159
|
+
console.log(` - ${file}`);
|
|
160
|
+
}
|
|
161
|
+
console.log(`\nSelected agents: ${result.agents.map((agent) => AGENTS[agent].label).join(', ')}`);
|
|
162
|
+
console.log('\nNext steps:');
|
|
163
|
+
console.log(' 1) Open docs/spec-workflow.md');
|
|
164
|
+
console.log(' 2) Point your chosen agent(s) at their installed RULES.md file(s)');
|
|
165
|
+
console.log(' 3) Use generate-task-list and generate-checklist when artifacts are missing');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async function runInteractive(defaults) {
|
|
169
|
+
const rl = createInterface();
|
|
170
|
+
try {
|
|
171
|
+
console.log('\nreyson-spec-gate interactive installer\n');
|
|
172
|
+
console.log('Recommended usage: npx reyson-spec-gate');
|
|
173
|
+
const dirAnswer = await ask(rl, `\nTarget directory [${defaults.dir}]: `);
|
|
174
|
+
const targetDir = path.resolve(dirAnswer.trim() || defaults.dir);
|
|
175
|
+
|
|
176
|
+
console.log('\nSelect agent targets (comma-separated, multi-select supported):');
|
|
177
|
+
console.log(' 1) Codex');
|
|
178
|
+
console.log(' 2) Trae');
|
|
179
|
+
console.log(' 3) Claude Code');
|
|
180
|
+
console.log(' 4) Cursor');
|
|
181
|
+
console.log(' 5) Antigravity');
|
|
182
|
+
console.log(' Press ENTER to accept the default: Codex');
|
|
183
|
+
const agentAnswer = await ask(rl, 'Choice(s) [Codex default]: ');
|
|
184
|
+
const { agents, usedDefault } = parseInteractiveAgents(agentAnswer);
|
|
185
|
+
if (usedDefault) {
|
|
186
|
+
console.log('No valid selection provided. Defaulting to Codex.');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const confirmation = await ask(
|
|
190
|
+
rl,
|
|
191
|
+
`\nProceed installing into ${targetDir} for ${agents.map((agent) => AGENTS[agent].label).join(', ')}? [Y/n]: `,
|
|
192
|
+
);
|
|
193
|
+
const ok = confirmation.trim() === '' || /^y(es)?$/i.test(confirmation.trim());
|
|
194
|
+
if (!ok) {
|
|
195
|
+
console.log('Installation cancelled.');
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const result = performInstall({ targetDir, agents });
|
|
200
|
+
printSummary(result);
|
|
201
|
+
} finally {
|
|
202
|
+
rl.close();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async function main() {
|
|
207
|
+
let options;
|
|
208
|
+
try {
|
|
209
|
+
options = parseArgs(process.argv);
|
|
210
|
+
} catch (error) {
|
|
211
|
+
console.error(error.message);
|
|
212
|
+
printHelp();
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (options.command === 'help' || options.command === '--help' || options.command === '-h') {
|
|
217
|
+
printHelp();
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (options.command !== 'install') {
|
|
222
|
+
console.error(`Unknown command: ${options.command}`);
|
|
223
|
+
printHelp();
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (options.yes) {
|
|
228
|
+
const result = performInstall({ targetDir: options.dir, agents: options.agents });
|
|
229
|
+
printSummary(result);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
await runInteractive(options);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
main().catch((error) => {
|
|
237
|
+
console.error(error.stack || error.message);
|
|
238
|
+
process.exit(1);
|
|
239
|
+
});
|
package/bin/skill-reyson.js
CHANGED
|
@@ -1,234 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const os = require('os');
|
|
5
|
-
const readline = require('readline');
|
|
6
|
-
|
|
7
|
-
const PACKAGE_ROOT = path.resolve(__dirname, '..');
|
|
8
|
-
const DOC_SOURCE = path.join(PACKAGE_ROOT, 'docs', 'spec-workflow.md');
|
|
9
|
-
const SKILL_SOURCES = [
|
|
10
|
-
{
|
|
11
|
-
source: path.join(PACKAGE_ROOT, 'skills', 'generate-task-list', 'SKILL.md'),
|
|
12
|
-
relativeTarget: path.join('skills', 'generate-task-list', 'SKILL.md'),
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
source: path.join(PACKAGE_ROOT, 'skills', 'generate-checklist', 'SKILL.md'),
|
|
16
|
-
relativeTarget: path.join('skills', 'generate-checklist', 'SKILL.md'),
|
|
17
|
-
},
|
|
18
|
-
];
|
|
19
|
-
const ADAPTERS = {
|
|
20
|
-
codex: {
|
|
21
|
-
label: 'Codex',
|
|
22
|
-
source: path.join(PACKAGE_ROOT, 'templates', 'adapters', 'AGENTS.md'),
|
|
23
|
-
target: 'AGENTS.md',
|
|
24
|
-
},
|
|
25
|
-
claude: {
|
|
26
|
-
label: 'Claude Code',
|
|
27
|
-
source: path.join(PACKAGE_ROOT, 'templates', 'adapters', 'CLAUDE.md'),
|
|
28
|
-
target: 'CLAUDE.md',
|
|
29
|
-
},
|
|
30
|
-
generic: {
|
|
31
|
-
label: 'Generic rules',
|
|
32
|
-
source: path.join(PACKAGE_ROOT, 'templates', 'adapters', 'RULES.md'),
|
|
33
|
-
target: 'RULES.md',
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
function printHelp() {
|
|
38
|
-
console.log(`skill-reyson
|
|
39
|
-
|
|
40
|
-
Usage:
|
|
41
|
-
skill-reyson Start interactive installer
|
|
42
|
-
skill-reyson install Start interactive installer
|
|
43
|
-
skill-reyson install --dir <path> [--agents codex,claude,generic] [--with-agent-files]
|
|
44
|
-
skill-reyson install --yes [--dir <path>] [--agents codex,claude,generic] [--with-agent-files]
|
|
45
|
-
skill-reyson --help Show help
|
|
46
|
-
|
|
47
|
-
Defaults:
|
|
48
|
-
- Installs docs/spec-workflow.md
|
|
49
|
-
- Installs skills/generate-task-list/SKILL.md
|
|
50
|
-
- Installs skills/generate-checklist/SKILL.md
|
|
51
|
-
- Does NOT install agent guidance files unless requested
|
|
52
|
-
`);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function parseArgs(argv) {
|
|
56
|
-
const args = argv.slice(2);
|
|
57
|
-
const options = { command: 'install', dir: process.cwd(), yes: false, withAgentFiles: false, agents: [] };
|
|
58
|
-
if (args[0] && !args[0].startsWith('-')) {
|
|
59
|
-
options.command = args.shift();
|
|
60
|
-
}
|
|
61
|
-
for (let i = 0; i < args.length; i += 1) {
|
|
62
|
-
const arg = args[i];
|
|
63
|
-
if (arg === '--help' || arg === '-h') {
|
|
64
|
-
options.command = 'help';
|
|
65
|
-
} else if (arg === '--yes' || arg === '-y') {
|
|
66
|
-
options.yes = true;
|
|
67
|
-
} else if (arg === '--with-agent-files') {
|
|
68
|
-
options.withAgentFiles = true;
|
|
69
|
-
} else if (arg === '--dir') {
|
|
70
|
-
options.dir = path.resolve(args[i + 1] || process.cwd());
|
|
71
|
-
i += 1;
|
|
72
|
-
} else if (arg.startsWith('--dir=')) {
|
|
73
|
-
options.dir = path.resolve(arg.split('=')[1]);
|
|
74
|
-
} else if (arg === '--agents') {
|
|
75
|
-
options.agents = (args[i + 1] || '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
76
|
-
i += 1;
|
|
77
|
-
} else if (arg.startsWith('--agents=')) {
|
|
78
|
-
options.agents = arg.split('=')[1].split(',').map((s) => s.trim()).filter(Boolean);
|
|
79
|
-
} else {
|
|
80
|
-
throw new Error(`Unknown argument: ${arg}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return options;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function ensureDir(dirPath) {
|
|
87
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function copyFile(source, target) {
|
|
91
|
-
ensureDir(path.dirname(target));
|
|
92
|
-
fs.copyFileSync(source, target);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function copyCoreArtifacts(targetDir) {
|
|
96
|
-
const docTarget = path.join(targetDir, 'docs', 'spec-workflow.md');
|
|
97
|
-
copyFile(DOC_SOURCE, docTarget);
|
|
98
|
-
for (const skill of SKILL_SOURCES) {
|
|
99
|
-
copyFile(skill.source, path.join(targetDir, skill.relativeTarget));
|
|
100
|
-
}
|
|
101
|
-
return [
|
|
102
|
-
path.relative(targetDir, docTarget),
|
|
103
|
-
...SKILL_SOURCES.map((skill) => skill.relativeTarget),
|
|
104
|
-
];
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function copyAgentFiles(targetDir, selectedAgents) {
|
|
108
|
-
const copied = [];
|
|
109
|
-
for (const key of selectedAgents) {
|
|
110
|
-
const adapter = ADAPTERS[key];
|
|
111
|
-
if (!adapter) continue;
|
|
112
|
-
copyFile(adapter.source, path.join(targetDir, adapter.target));
|
|
113
|
-
copied.push(adapter.target);
|
|
114
|
-
}
|
|
115
|
-
return copied;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function normalizeAgents(agentKeys) {
|
|
119
|
-
return Array.from(new Set(agentKeys.filter((key) => ADAPTERS[key])));
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function createInterface() {
|
|
123
|
-
return readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function ask(rl, question) {
|
|
127
|
-
return new Promise((resolve) => rl.question(question, resolve));
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
async function runInteractive(defaults) {
|
|
131
|
-
const rl = createInterface();
|
|
132
|
-
try {
|
|
133
|
-
console.log('\nskill-reyson interactive installer\n');
|
|
134
|
-
const dirAnswer = await ask(rl, `Target directory [${defaults.dir}]: `);
|
|
135
|
-
const targetDir = path.resolve(dirAnswer.trim() || defaults.dir);
|
|
136
|
-
|
|
137
|
-
const includeAgentAnswer = await ask(rl, 'Install agent guidance files (AGENTS.md / CLAUDE.md / RULES.md)? [y/N]: ');
|
|
138
|
-
const withAgentFiles = /^y(es)?$/i.test(includeAgentAnswer.trim());
|
|
139
|
-
|
|
140
|
-
let agents = [];
|
|
141
|
-
if (withAgentFiles) {
|
|
142
|
-
console.log('\nSelect agent adapters (comma-separated numbers):');
|
|
143
|
-
console.log(' 1) Codex -> AGENTS.md');
|
|
144
|
-
console.log(' 2) Claude Code -> CLAUDE.md');
|
|
145
|
-
console.log(' 3) Generic rules -> RULES.md');
|
|
146
|
-
const agentAnswer = await ask(rl, 'Choice(s) [1]: ');
|
|
147
|
-
const tokens = (agentAnswer.trim() || '1').split(',').map((s) => s.trim());
|
|
148
|
-
const mapping = { '1': 'codex', '2': 'claude', '3': 'generic' };
|
|
149
|
-
agents = normalizeAgents(tokens.map((token) => mapping[token] || token.toLowerCase()));
|
|
150
|
-
if (agents.length === 0) {
|
|
151
|
-
agents = ['codex'];
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const confirmation = await ask(rl, `\nProceed installing into ${targetDir}? [Y/n]: `);
|
|
156
|
-
const ok = confirmation.trim() === '' || /^y(es)?$/i.test(confirmation.trim());
|
|
157
|
-
if (!ok) {
|
|
158
|
-
console.log('Installation cancelled.');
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const result = performInstall({ targetDir, withAgentFiles, agents });
|
|
163
|
-
printSummary(result);
|
|
164
|
-
} finally {
|
|
165
|
-
rl.close();
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function performInstall({ targetDir, withAgentFiles, agents }) {
|
|
170
|
-
ensureDir(targetDir);
|
|
171
|
-
const coreFiles = copyCoreArtifacts(targetDir);
|
|
172
|
-
const agentFiles = withAgentFiles ? copyAgentFiles(targetDir, normalizeAgents(agents)) : [];
|
|
173
|
-
return { targetDir, coreFiles, agentFiles };
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function printSummary(result) {
|
|
177
|
-
console.log('\nInstalled skill-reyson scaffold:\n');
|
|
178
|
-
console.log(`Target: ${result.targetDir}`);
|
|
179
|
-
console.log('\nCore files:');
|
|
180
|
-
for (const file of result.coreFiles) {
|
|
181
|
-
console.log(` - ${file}`);
|
|
182
|
-
}
|
|
183
|
-
if (result.agentFiles.length > 0) {
|
|
184
|
-
console.log('\nAgent guidance files:');
|
|
185
|
-
for (const file of result.agentFiles) {
|
|
186
|
-
console.log(` - ${file}`);
|
|
187
|
-
}
|
|
188
|
-
} else {
|
|
189
|
-
console.log('\nAgent guidance files: none (default)');
|
|
190
|
-
}
|
|
191
|
-
console.log('\nNext steps:');
|
|
192
|
-
console.log(' 1) Open docs/spec-workflow.md');
|
|
193
|
-
console.log(' 2) Ensure your agent knows to read the workflow before coding');
|
|
194
|
-
console.log(' 3) Use generate-task-list and generate-checklist when artifacts are missing');
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
async function main() {
|
|
198
|
-
let options;
|
|
199
|
-
try {
|
|
200
|
-
options = parseArgs(process.argv);
|
|
201
|
-
} catch (error) {
|
|
202
|
-
console.error(error.message);
|
|
203
|
-
printHelp();
|
|
204
|
-
process.exit(1);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
if (options.command === 'help' || options.command === '--help' || options.command === '-h') {
|
|
208
|
-
printHelp();
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (options.command !== 'install') {
|
|
213
|
-
console.error(`Unknown command: ${options.command}`);
|
|
214
|
-
printHelp();
|
|
215
|
-
process.exit(1);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (options.yes) {
|
|
219
|
-
const result = performInstall({
|
|
220
|
-
targetDir: options.dir,
|
|
221
|
-
withAgentFiles: options.withAgentFiles,
|
|
222
|
-
agents: options.agents,
|
|
223
|
-
});
|
|
224
|
-
printSummary(result);
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
await runInteractive(options);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
main().catch((error) => {
|
|
232
|
-
console.error(error.stack || error.message);
|
|
233
|
-
process.exit(1);
|
|
234
|
-
});
|
|
2
|
+
require('./reyson-spec-gate.js');
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reyson-spec-gate",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Interactive installer for a spec-first workflow scaffold with docs, skills, and optional agent guidance files.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
7
|
-
"
|
|
7
|
+
"reyson-spec-gate": "bin/reyson-spec-gate.js",
|
|
8
|
+
"skill-reyson": "bin/reyson-spec-gate.js"
|
|
8
9
|
},
|
|
9
10
|
"files": [
|
|
10
11
|
"bin",
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# AGENTS.md
|
|
2
|
-
|
|
3
|
-
## Spec-first workflow rules
|
|
4
|
-
|
|
5
|
-
Before any implementation task, read `docs/spec-workflow.md`.
|
|
6
|
-
|
|
7
|
-
Before coding begins, verify whether the current work includes:
|
|
8
|
-
- an explicit task list
|
|
9
|
-
- an explicit checklist
|
|
10
|
-
|
|
11
|
-
If the task list is missing, generate it first.
|
|
12
|
-
If the checklist is missing, generate it second.
|
|
13
|
-
If both are missing, generate both before coding.
|
|
14
|
-
|
|
15
|
-
Do not begin implementation until the pre-coding gate is satisfied.
|
|
16
|
-
After coding, revisit the checklist before claiming completion.
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
## Spec-first workflow rules
|
|
4
|
-
|
|
5
|
-
Before any implementation task, read `docs/spec-workflow.md`.
|
|
6
|
-
|
|
7
|
-
Before coding begins, verify whether the current work includes:
|
|
8
|
-
- an explicit task list
|
|
9
|
-
- an explicit checklist
|
|
10
|
-
|
|
11
|
-
If the task list is missing, generate it first.
|
|
12
|
-
If the checklist is missing, generate it second.
|
|
13
|
-
If both are missing, generate both before coding.
|
|
14
|
-
|
|
15
|
-
Do not begin implementation until the pre-coding gate is satisfied.
|
|
16
|
-
After coding, revisit the checklist before claiming completion.
|
|
File without changes
|