create-restforge-skills 0.4.0 → 1.0.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 CHANGED
@@ -28,18 +28,20 @@ restforge-skills/
28
28
  ├── *.bat ← maintainer scripts (see docs/DEVELOPMENT.md)
29
29
  ├── cli/
30
30
  │ ├── index.js ← installer that copies the skill into each client
31
- │ └── mcp.js ← merges the MCP server into each client config
31
+ │ ├── mcp.js ← merges JSON MCP config for Claude Code / Cursor
32
+ │ └── codex.js ← safely appends Codex TOML MCP configuration
32
33
  ├── docs/
33
34
  │ └── DEVELOPMENT.md ← maintainer guide, NOT published (excluded from npm files)
34
35
  └── skills/
35
36
  └── restforge/
36
- ├── SKILL.md ← the portable skill (name + description + workflow)
37
+ ├── SKILL.md ← the portable skill (name + description + workflow)
38
+ ├── agents/openai.yaml ← Codex display metadata and example prompt
37
39
  └── references/ ← progressive-disclosure reference material
38
40
  ```
39
41
 
40
42
  ## Install
41
43
 
42
- One command. It detects your installed clients (Claude Code, Cursor), copies the
44
+ One command. It detects your installed clients (Claude Code, Cursor, Codex), copies the
43
45
  skill into each, and registers the RESTForge MCP server — because the skill is
44
46
  inert without it:
45
47
 
@@ -58,7 +60,8 @@ it takes **no positional folder argument** (`myapp` / `.`). The install location
58
60
  is chosen by `--scope`, not by where you stand or by a path you pass.
59
61
 
60
62
  - **Default (`--scope=user`) — run it from anywhere.** The current directory is
61
- ignored. The skill goes to your home (`~/.claude/skills/`, `~/.cursor/skills/`)
63
+ ignored. The skill goes to your home (`~/.claude/skills/`, `~/.cursor/skills/`,
64
+ or `~/.agents/skills/` for Codex)
62
65
  and is available across **all** your projects. This is the normal usage: a skill
63
66
  is editor/agent tooling, not part of any one app's source.
64
67
 
@@ -68,7 +71,9 @@ is chosen by `--scope`, not by where you stand or by a path you pass.
68
71
  `./.claude/skills/` or `./.cursor/skills/`; the MCP config goes to `./.mcp.json`
69
72
  for Claude Code (its project-scope convention, not a file under `.claude/`) and
70
73
  to `./.cursor/mcp.json` for Cursor. Use this to commit the skill with a specific
71
- repo so the team gets it on clone.
74
+ repo so the team gets it on clone.
75
+ For Codex, the corresponding paths are `./.agents/skills/` and
76
+ `./.codex/config.toml`; project MCP settings load only in trusted projects.
72
77
 
73
78
  ```bash
74
79
  # normal — anywhere, global for every project
@@ -85,8 +90,9 @@ Note: a bare path such as `npx create-restforge-skills .` is **not** recognized
85
90
  ### Options
86
91
 
87
92
  ```bash
88
- npx create-restforge-skills --client=cursor # one client only
89
- npx create-restforge-skills --scope=project # skill into ./.claude or ./.cursor, MCP into ./.mcp.json (commit for the team)
93
+ npx create-restforge-skills --client=cursor # one client only
94
+ npx create-restforge-skills --client=codex # Codex skill + MCP configuration
95
+ npx create-restforge-skills --scope=project # install into the current project
90
96
  npx create-restforge-skills --mcp-command=global # use the installed restforge-mcp binary instead of npx
91
97
  npx create-restforge-skills --no-mcp # skill only; you manage MCP yourself
92
98
  npx create-restforge-skills --dry-run # preview, write nothing
@@ -118,7 +124,9 @@ so the update touches only the skill and leaves the MCP config alone.
118
124
  | Claude Code | user (default) | `~/.claude/skills/restforge/` | `~/.claude.json` |
119
125
  | Claude Code | project | `./.claude/skills/restforge/` | `./.mcp.json` |
120
126
  | Cursor | user (default) | `~/.cursor/skills/restforge/` | `~/.cursor/mcp.json` |
121
- | Cursor | project | `./.cursor/skills/restforge/` | `./.cursor/mcp.json` |
127
+ | Cursor | project | `./.cursor/skills/restforge/` | `./.cursor/mcp.json` |
128
+ | Codex | user (default) | `~/.agents/skills/restforge/` | `$CODEX_HOME/config.toml` (default `~/.codex/config.toml`) |
129
+ | Codex | project | `./.agents/skills/restforge/` | `./.codex/config.toml` |
122
130
 
123
131
  Note the asymmetry on the project row: Claude Code reads a project-scope MCP
124
132
  server from `./.mcp.json` in the repo root, so that is where the installer writes
@@ -127,14 +135,53 @@ it — not into `./.claude/`.
127
135
  ### Manual install (no CLI)
128
136
 
129
137
  The skill folder is self-contained — copy `skills/restforge/` (including
130
- `references/`) into the client's skills directory and add
138
+ `references/` and `agents/`) into the client's skills directory. For Claude Code
139
+ and Cursor, add
131
140
  `{ "mcpServers": { "restforge": { "command": "npx", "args": ["-y", "@restforgejs/mcp-server"] } } }`
132
141
  to the client's MCP config.
133
142
 
134
- ### Gemini CLI / OpenAI Codex
135
-
136
- Planned. Both consume the same `skills/restforge/` folder; only the skills
137
- directory path and MCP config file differ per client.
143
+ ### OpenAI Codex
144
+
145
+ Install for Codex explicitly, or let auto-detection find `CODEX_HOME` (default
146
+ `~/.codex`). No Codex CLI binary is required by the installer:
147
+
148
+ ```bash
149
+ npx create-restforge-skills --client=codex
150
+ # Or install into the current project:
151
+ npx create-restforge-skills --client=codex --scope=project
152
+ ```
153
+
154
+ Restart Codex after installation and invoke `$restforge`, for example:
155
+ `Use $restforge to create a product API.` Check the MCP connection with `/mcp`
156
+ in Codex or `codex mcp list` in a terminal.
157
+
158
+ For manual setup, copy the entire skill folder to the Codex skill path in the
159
+ table above and add this to the corresponding `config.toml`:
160
+
161
+ ```toml
162
+ [mcp_servers.restforge]
163
+ command = "npx"
164
+ args = ["-y", "@restforgejs/mcp-server"]
165
+ ```
166
+
167
+ The installer preserves existing Codex RESTForge registrations, including custom
168
+ commands, URLs, environment variables and timeouts. `--mcp-command` chooses the
169
+ command for a **new** registration; edit `config.toml` to change an existing one.
170
+ `--force` only replaces the skill. Existing TOML comments and formatting are
171
+ preserved, and a changed config is backed up to `config.toml.bak`. If the TOML
172
+ cannot be parsed or extended safely (for example an inline `mcp_servers` table),
173
+ the installer leaves it untouched, reports an error, and exits with code 1;
174
+ the skill may already have been copied. Finish the MCP setup manually.
175
+
176
+ `CODEX_HOME` changes the user MCP config location and auto-detection marker;
177
+ user skills still go into `~/.agents/skills/`. See the official
178
+ [skill discovery documentation](https://developers.openai.com/codex/skills) and
179
+ [MCP configuration documentation](https://developers.openai.com/codex/mcp).
180
+
181
+ ### Gemini CLI
182
+
183
+ Installer support is planned. Use the same `skills/restforge/` folder with the
184
+ client's manual skill installation procedure.
138
185
 
139
186
  ## Developing and releasing
140
187
 
package/cli/codex.js ADDED
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const toml = require('@iarna/toml');
6
+
7
+ function formatCodexMcp(entry) {
8
+ return toml.stringify({ mcp_servers: { restforge: entry } });
9
+ }
10
+
11
+ // Append only, preserving comments, formatting, and any existing custom server.
12
+ // Parse both documents so inline tables, quoted keys and multiline strings are
13
+ // handled by a TOML parser rather than potentially destructive text matching.
14
+ function registerCodexMcp(file, entry, opts) {
15
+ try {
16
+ const existed = fs.existsSync(file);
17
+ const raw = existed ? fs.readFileSync(file, 'utf8') : '';
18
+ const config = toml.parse(raw);
19
+ if (config.mcp_servers && Object.hasOwn(config.mcp_servers, 'restforge')) {
20
+ const existing = config.mcp_servers.restforge;
21
+ const same = existing.command === entry.command &&
22
+ JSON.stringify(existing.args || []) === JSON.stringify(entry.args || []);
23
+ return { status: same ? 'already-registered' : 'preserved' };
24
+ }
25
+ const next = raw + (raw.endsWith('\n') || !raw ? '' : '\n') + '\n' + formatCodexMcp(entry);
26
+ toml.parse(next);
27
+ if (opts.dryRun) return { status: 'would-register' };
28
+ let backup;
29
+ if (existed) {
30
+ backup = file + '.bak';
31
+ fs.copyFileSync(file, backup);
32
+ }
33
+ fs.mkdirSync(path.dirname(file), { recursive: true });
34
+ fs.writeFileSync(file, next, 'utf8');
35
+ return { status: 'registered', backup };
36
+ } catch (err) {
37
+ // Parser diagnostics can contain config values (including credentials).
38
+ return { status: 'error', error: `Cannot safely register Codex MCP (${err.code || 'invalid or conflicting TOML'}); check config.toml manually.` };
39
+ }
40
+ }
41
+
42
+ module.exports = { formatCodexMcp, registerCodexMcp };