universal-ai-config 1.0.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/LICENSE +21 -0
- package/README.md +628 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +323 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/generate-BdZFuS-y.mjs +673 -0
- package/dist/generate-BdZFuS-y.mjs.map +1 -0
- package/dist/index.d.mts +113 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +3 -0
- package/dist/meta-instructions-DFJL6MnP.mjs +46 -0
- package/dist/meta-instructions-DFJL6MnP.mjs.map +1 -0
- package/package.json +66 -0
- package/src/seed-types/meta-instructions/index.ts +60 -0
- package/src/seed-types/meta-instructions/templates/instructions/uac-template-guide.md +218 -0
- package/src/seed-types/meta-instructions/templates/skills/import-existing-ai-config.md +127 -0
- package/src/seed-types/meta-instructions/templates/skills/update-agent.md +52 -0
- package/src/seed-types/meta-instructions/templates/skills/update-ai-config.md +30 -0
- package/src/seed-types/meta-instructions/templates/skills/update-hook.md +76 -0
- package/src/seed-types/meta-instructions/templates/skills/update-instruction.md +83 -0
- package/src/seed-types/meta-instructions/templates/skills/update-skill.md +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kristaps Fabians Geikins
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,628 @@
|
|
|
1
|
+
# universal-ai-config
|
|
2
|
+
|
|
3
|
+
Generate tool-specific AI config files from shared templates. Write your AI instructions, skills, agents, and hooks once — generate config for Claude Code, GitHub Copilot, and Cursor automatically.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Why](#why)
|
|
8
|
+
- [Install](#install)
|
|
9
|
+
- [Quick Start](#quick-start)
|
|
10
|
+
- [Template Structure](#template-structure)
|
|
11
|
+
- [Writing Templates](#writing-templates)
|
|
12
|
+
- [Instructions](#instructions)
|
|
13
|
+
- [Skills](#skills)
|
|
14
|
+
- [Agents](#agents)
|
|
15
|
+
- [Hooks](#hooks)
|
|
16
|
+
- [Per-Target Overrides](#per-target-overrides)
|
|
17
|
+
- [EJS Template Variables](#ejs-template-variables)
|
|
18
|
+
- [Configuration](#configuration)
|
|
19
|
+
- [CLI Reference](#cli-reference)
|
|
20
|
+
- [`uac generate`](#uac-generate)
|
|
21
|
+
- [`uac init`](#uac-init)
|
|
22
|
+
- [`uac clean`](#uac-clean)
|
|
23
|
+
- [`uac seed`](#uac-seed)
|
|
24
|
+
- [Output Paths](#output-paths)
|
|
25
|
+
- [Frontmatter Mapping Reference](#frontmatter-mapping-reference)
|
|
26
|
+
- [Programmatic API](#programmatic-api)
|
|
27
|
+
- [Adding a New Target](#adding-a-new-target)
|
|
28
|
+
|
|
29
|
+
## Why
|
|
30
|
+
|
|
31
|
+
AI coding tools each have their own config formats stored in `.claude/`, `.github/`, `.cursor/`. Teams want shared AI config but each developer may use a different tool. This CLI generates target-specific config files from shared templates in `.universal-ai-config/`, so the tool-specific folders can be gitignored and each dev generates only what they need.
|
|
32
|
+
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pnpm add -D universal-ai-config
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Scaffold template directory with examples
|
|
43
|
+
pnpm uac init
|
|
44
|
+
|
|
45
|
+
# Generate config for all targets
|
|
46
|
+
pnpm uac generate
|
|
47
|
+
|
|
48
|
+
# Generate for specific targets
|
|
49
|
+
pnpm uac generate -t claude,cursor
|
|
50
|
+
|
|
51
|
+
# Preview without writing files
|
|
52
|
+
pnpm uac generate --dry-run
|
|
53
|
+
|
|
54
|
+
# Seed AI-assisted template management skills
|
|
55
|
+
pnpm uac seed meta-instructions
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Template Structure
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
your-project/
|
|
62
|
+
├── universal-ai-config.config.ts # Shared config (committed)
|
|
63
|
+
├── universal-ai-config.overrides.config.ts # Personal overrides (gitignored)
|
|
64
|
+
└── .universal-ai-config/
|
|
65
|
+
├── instructions/ # Rules/instructions (markdown + EJS)
|
|
66
|
+
│ ├── react-patterns.md
|
|
67
|
+
│ └── security.md
|
|
68
|
+
├── skills/ # One folder per skill
|
|
69
|
+
│ └── test-generation/
|
|
70
|
+
│ └── SKILL.md
|
|
71
|
+
├── agents/ # Agent/subagent definitions
|
|
72
|
+
│ └── code-reviewer.md
|
|
73
|
+
└── hooks/ # Hook configs (JSON, no templating)
|
|
74
|
+
├── security.json
|
|
75
|
+
└── quality.json
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Writing Templates
|
|
79
|
+
|
|
80
|
+
Templates are markdown files with YAML frontmatter. The body supports [EJS](https://ejs.co/) for conditional content per target.
|
|
81
|
+
|
|
82
|
+
### Instructions
|
|
83
|
+
|
|
84
|
+
```markdown
|
|
85
|
+
---
|
|
86
|
+
description: TypeScript specific rules
|
|
87
|
+
globs: ["**/*.ts", "**/*.tsx"]
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
Use strict TypeScript. Prefer interfaces over type aliases for object shapes.
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```markdown
|
|
94
|
+
---
|
|
95
|
+
description: Always applied coding standards
|
|
96
|
+
alwaysApply: true
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
Follow the project's coding standards at all times.
|
|
100
|
+
|
|
101
|
+
<% if (target === 'claude') { -%>
|
|
102
|
+
Use the Read tool to check existing patterns before creating new code.
|
|
103
|
+
<% } else { -%>
|
|
104
|
+
Check existing patterns before creating new code.
|
|
105
|
+
<% } -%>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
#### Frontmatter Fields
|
|
109
|
+
|
|
110
|
+
| Field | Type | Description |
|
|
111
|
+
| -------------- | -------------------- | ---------------------------------------------------------------- |
|
|
112
|
+
| `description` | `string` | What this instruction does |
|
|
113
|
+
| `globs` | `string \| string[]` | File patterns this applies to |
|
|
114
|
+
| `alwaysApply` | `boolean` | Apply to all files regardless of context |
|
|
115
|
+
| `excludeAgent` | `string` | Copilot-only: exclude from specific agent (e.g. `"code-review"`) |
|
|
116
|
+
|
|
117
|
+
### Skills
|
|
118
|
+
|
|
119
|
+
Skills live in subdirectories with a `SKILL.md` file:
|
|
120
|
+
|
|
121
|
+
```markdown
|
|
122
|
+
---
|
|
123
|
+
name: test-generation
|
|
124
|
+
description: Generate tests for code
|
|
125
|
+
disableAutoInvocation: true
|
|
126
|
+
userInvocable: /test
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
Generate comprehensive tests using vitest for the given code.
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### Frontmatter Fields
|
|
133
|
+
|
|
134
|
+
| Field | Type | Description |
|
|
135
|
+
| ----------------------- | ------------------- | -------------------------------------- |
|
|
136
|
+
| `name` | `string` | Skill identifier |
|
|
137
|
+
| `description` | `string` | What this skill does |
|
|
138
|
+
| `disableAutoInvocation` | `boolean` | Prevent automatic triggering |
|
|
139
|
+
| `userInvocable` | `boolean \| string` | Slash command trigger (Claude only) |
|
|
140
|
+
| `allowedTools` | `string[]` | Tools this skill can use (Claude only) |
|
|
141
|
+
| `model` | `string` | Model to use (Claude only) |
|
|
142
|
+
| `subagentType` | `string` | Agent type (Claude only) |
|
|
143
|
+
| `forkContext` | `boolean` | Fork context (Claude only) |
|
|
144
|
+
| `argumentHint` | `string` | Hint for arguments (Claude only) |
|
|
145
|
+
| `license` | `string` | License info (Copilot/Cursor) |
|
|
146
|
+
| `compatibility` | `string` | Compatibility info (Copilot/Cursor) |
|
|
147
|
+
| `metadata` | `object` | Extra metadata (Copilot/Cursor) |
|
|
148
|
+
| `hooks` | `object` | Hook definitions (Claude only) |
|
|
149
|
+
|
|
150
|
+
### Agents
|
|
151
|
+
|
|
152
|
+
```markdown
|
|
153
|
+
---
|
|
154
|
+
name: code-reviewer
|
|
155
|
+
description: Reviews code for quality
|
|
156
|
+
model: sonnet
|
|
157
|
+
tools: ["read", "grep", "glob"]
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
You are a code reviewer. Check for bugs and best practice violations.
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### Frontmatter Fields
|
|
164
|
+
|
|
165
|
+
| Field | Type | Description |
|
|
166
|
+
| ----------------- | ---------- | --------------------------------- |
|
|
167
|
+
| `name` | `string` | Agent identifier |
|
|
168
|
+
| `description` | `string` | What this agent does |
|
|
169
|
+
| `model` | `string` | Model to use |
|
|
170
|
+
| `tools` | `string[]` | Available tools |
|
|
171
|
+
| `disallowedTools` | `string[]` | Blocked tools (Claude only) |
|
|
172
|
+
| `permissionMode` | `string` | Permission mode (Claude only) |
|
|
173
|
+
| `skills` | `string[]` | Available skills (Claude only) |
|
|
174
|
+
| `hooks` | `object` | Hook definitions (Claude only) |
|
|
175
|
+
| `memory` | `string` | Memory scope (Claude only) |
|
|
176
|
+
| `target` | `string` | Target description (Copilot only) |
|
|
177
|
+
| `mcpServers` | `object` | MCP server config (Copilot only) |
|
|
178
|
+
| `handoffs` | `string[]` | Handoff targets (Copilot only) |
|
|
179
|
+
|
|
180
|
+
> **Note:** Cursor does not support agents. The CLI will warn and skip agent generation for the `cursor` target.
|
|
181
|
+
|
|
182
|
+
### Hooks
|
|
183
|
+
|
|
184
|
+
Hooks are JSON files that define automated scripts running at lifecycle events (pre-tool-use, session start, etc.). Unlike other template types, hooks use pure JSON with no EJS templating. Multiple `.json` files in the `hooks/` directory are deep-merged by event name.
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"hooks": {
|
|
189
|
+
"preToolUse": [
|
|
190
|
+
{
|
|
191
|
+
"matcher": "Bash",
|
|
192
|
+
"command": ".hooks/block-rm.sh",
|
|
193
|
+
"timeout": 30
|
|
194
|
+
}
|
|
195
|
+
],
|
|
196
|
+
"postToolUse": [
|
|
197
|
+
{
|
|
198
|
+
"command": ".hooks/lint.sh",
|
|
199
|
+
"timeout": 60
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
#### Handler Fields
|
|
207
|
+
|
|
208
|
+
| Field | Type | Required | Description |
|
|
209
|
+
| ------------- | -------- | -------- | --------------------------------------- |
|
|
210
|
+
| `command` | `string` | yes | Shell command or script path |
|
|
211
|
+
| `matcher` | `string` | no | Regex pattern to filter when hook fires |
|
|
212
|
+
| `timeout` | `number` | no | Timeout in seconds |
|
|
213
|
+
| `description` | `string` | no | Human-readable description |
|
|
214
|
+
|
|
215
|
+
#### Universal Event Names
|
|
216
|
+
|
|
217
|
+
Use camelCase event names. The CLI maps them to each target's format and silently drops unsupported events.
|
|
218
|
+
|
|
219
|
+
| Universal | Claude | Cursor | Copilot |
|
|
220
|
+
| -------------------- | -------------------- | -------------------- | --------------------- |
|
|
221
|
+
| `sessionStart` | `SessionStart` | `sessionStart` | `sessionStart` |
|
|
222
|
+
| `sessionEnd` | `SessionEnd` | `sessionEnd` | `sessionEnd` |
|
|
223
|
+
| `userPromptSubmit` | `UserPromptSubmit` | `beforeSubmitPrompt` | `userPromptSubmitted` |
|
|
224
|
+
| `preToolUse` | `PreToolUse` | `preToolUse` | `preToolUse` |
|
|
225
|
+
| `postToolUse` | `PostToolUse` | `postToolUse` | `postToolUse` |
|
|
226
|
+
| `postToolUseFailure` | `PostToolUseFailure` | `postToolUseFailure` | — |
|
|
227
|
+
| `stop` | `Stop` | `stop` | — |
|
|
228
|
+
| `subagentStart` | `SubagentStart` | `subagentStart` | — |
|
|
229
|
+
| `subagentStop` | `SubagentStop` | `subagentStop` | — |
|
|
230
|
+
| `preCompact` | `PreCompact` | `preCompact` | — |
|
|
231
|
+
| `permissionRequest` | `PermissionRequest` | — | — |
|
|
232
|
+
| `notification` | `Notification` | — | — |
|
|
233
|
+
| `errorOccurred` | — | — | `errorOccurred` |
|
|
234
|
+
|
|
235
|
+
Cursor-specific events (`beforeShellExecution`, `afterFileEdit`, etc.) can be used directly — they pass through to Cursor and are dropped for other targets.
|
|
236
|
+
|
|
237
|
+
## Per-Target Overrides
|
|
238
|
+
|
|
239
|
+
Any frontmatter field or hook handler field can accept per-target values instead of a single value. If a field's value is an object where **every key is a target name** (`claude`, `copilot`, `cursor`) or `default`, it's resolved to the matching target's value during generation. If the target isn't listed, the `default` value is used. If neither is present, the field is omitted.
|
|
240
|
+
|
|
241
|
+
### Frontmatter
|
|
242
|
+
|
|
243
|
+
```yaml
|
|
244
|
+
---
|
|
245
|
+
description:
|
|
246
|
+
claude: Use Claude Code conventions
|
|
247
|
+
copilot: Use Copilot conventions
|
|
248
|
+
cursor: Use Cursor conventions
|
|
249
|
+
tools:
|
|
250
|
+
default: ["read", "grep", "glob"]
|
|
251
|
+
claude: ["Read", "Grep", "Glob"]
|
|
252
|
+
model:
|
|
253
|
+
default: sonnet
|
|
254
|
+
claude: opus
|
|
255
|
+
copilot: gpt-4o
|
|
256
|
+
permissionMode:
|
|
257
|
+
claude: acceptEdits
|
|
258
|
+
---
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
When generating for Claude: `tools: ["Read", "Grep", "Glob"]`, `model: opus`, `permissionMode: acceptEdits`. For Copilot: `tools: ["read", "grep", "glob"]` (default), `model: gpt-4o`, `permissionMode` omitted. For Cursor: `tools: ["read", "grep", "glob"]` (default), `model: sonnet` (default), `permissionMode` omitted.
|
|
262
|
+
|
|
263
|
+
You can mix per-target and plain values freely — plain values apply to all targets:
|
|
264
|
+
|
|
265
|
+
```yaml
|
|
266
|
+
---
|
|
267
|
+
name: my-skill
|
|
268
|
+
description:
|
|
269
|
+
claude: Claude-specific description
|
|
270
|
+
copilot: Copilot-specific description
|
|
271
|
+
license: MIT
|
|
272
|
+
---
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Hooks
|
|
276
|
+
|
|
277
|
+
Hook handler fields (`command`, `matcher`, `timeout`, `description`) support the same syntax:
|
|
278
|
+
|
|
279
|
+
```json
|
|
280
|
+
{
|
|
281
|
+
"hooks": {
|
|
282
|
+
"preToolUse": [
|
|
283
|
+
{
|
|
284
|
+
"command": {
|
|
285
|
+
"claude": ".hooks/claude-check.sh",
|
|
286
|
+
"copilot": ".hooks/copilot-check.sh",
|
|
287
|
+
"cursor": ".hooks/cursor-check.sh"
|
|
288
|
+
},
|
|
289
|
+
"matcher": {
|
|
290
|
+
"claude": "Bash",
|
|
291
|
+
"cursor": "Bash"
|
|
292
|
+
},
|
|
293
|
+
"timeout": 30
|
|
294
|
+
}
|
|
295
|
+
]
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
If `command` resolves to `undefined` for a target (i.e. that target isn't listed), the entire handler is skipped for that target.
|
|
301
|
+
|
|
302
|
+
> **Note:** Objects with non-target keys (e.g. `metadata: { category: "devops" }`) are **not** treated as overrides — they pass through unchanged.
|
|
303
|
+
|
|
304
|
+
## EJS Template Variables
|
|
305
|
+
|
|
306
|
+
All templates have access to these variables:
|
|
307
|
+
|
|
308
|
+
| Variable | Type | Description |
|
|
309
|
+
| --------------------- | ---------------------------------------- | -------------------------------------------------- |
|
|
310
|
+
| `target` | `'claude' \| 'copilot' \| 'cursor'` | Current output target |
|
|
311
|
+
| `type` | `'instructions' \| 'skills' \| 'agents'` | Template type being rendered (hooks don't use EJS) |
|
|
312
|
+
| `config` | `ResolvedConfig` | Full resolved config object |
|
|
313
|
+
| `...config.variables` | `Record<string, unknown>` | Custom user variables spread into scope |
|
|
314
|
+
|
|
315
|
+
### Path Helpers
|
|
316
|
+
|
|
317
|
+
Templates have access to path helper functions. All `name` parameters are optional — omit to get the directory path.
|
|
318
|
+
|
|
319
|
+
**Output path helpers** — resolve to the target-specific output path:
|
|
320
|
+
|
|
321
|
+
| Function | Returns |
|
|
322
|
+
| ------------------------ | ------------------------------------------------------------- |
|
|
323
|
+
| `instructionPath(name?)` | Target-specific output path (or directory) for an instruction |
|
|
324
|
+
| `skillPath(name?)` | Target-specific output path (or directory) for a skill |
|
|
325
|
+
| `agentPath(name?)` | Target-specific output path (or directory) for an agent |
|
|
326
|
+
|
|
327
|
+
**Template path helpers** — resolve to the source template path in the templates directory:
|
|
328
|
+
|
|
329
|
+
| Function | Returns |
|
|
330
|
+
| -------------------------------- | ------------------------------------------------------ |
|
|
331
|
+
| `instructionTemplatePath(name?)` | Template source path (or directory) for an instruction |
|
|
332
|
+
| `skillTemplatePath(name?)` | Template source path (or directory) for a skill |
|
|
333
|
+
| `agentTemplatePath(name?)` | Template source path (or directory) for an agent |
|
|
334
|
+
| `hookTemplatePath(name?)` | Template source path (or directory) for a hook |
|
|
335
|
+
|
|
336
|
+
For example, `<%= instructionPath('coding-style') %>` renders to:
|
|
337
|
+
|
|
338
|
+
| Target | Output |
|
|
339
|
+
| ------- | --------------------------------------------------- |
|
|
340
|
+
| Claude | `.claude/rules/coding-style.md` |
|
|
341
|
+
| Copilot | `.github/instructions/coding-style.instructions.md` |
|
|
342
|
+
| Cursor | `.cursor/rules/coding-style.mdc` |
|
|
343
|
+
|
|
344
|
+
And `<%= instructionPath() %>` (no argument) renders to:
|
|
345
|
+
|
|
346
|
+
| Target | Output |
|
|
347
|
+
| ------- | ---------------------- |
|
|
348
|
+
| Claude | `.claude/rules` |
|
|
349
|
+
| Copilot | `.github/instructions` |
|
|
350
|
+
| Cursor | `.cursor/rules` |
|
|
351
|
+
|
|
352
|
+
Template path helpers are target-independent: `<%= instructionTemplatePath('coding-style') %>` always renders to `.universal-ai-config/instructions/coding-style.md` (or the configured `templatesDir`).
|
|
353
|
+
|
|
354
|
+
## Configuration
|
|
355
|
+
|
|
356
|
+
### Base config (`universal-ai-config.config.ts`) — committed
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
import { defineConfig } from "universal-ai-config";
|
|
360
|
+
|
|
361
|
+
export default defineConfig({
|
|
362
|
+
// Where templates live (default: '.universal-ai-config')
|
|
363
|
+
templatesDir: ".universal-ai-config",
|
|
364
|
+
|
|
365
|
+
// Which targets to generate (default: all three)
|
|
366
|
+
targets: ["claude", "copilot", "cursor"],
|
|
367
|
+
|
|
368
|
+
// Which types to generate (default: all)
|
|
369
|
+
types: ["instructions", "skills", "agents", "hooks"],
|
|
370
|
+
|
|
371
|
+
// Custom EJS variables available in templates
|
|
372
|
+
variables: {
|
|
373
|
+
projectName: "my-app",
|
|
374
|
+
useStrictMode: true,
|
|
375
|
+
},
|
|
376
|
+
|
|
377
|
+
// Override default output directories
|
|
378
|
+
outputDirs: {
|
|
379
|
+
claude: ".claude",
|
|
380
|
+
copilot: ".github",
|
|
381
|
+
cursor: ".cursor",
|
|
382
|
+
},
|
|
383
|
+
});
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Overrides config (`universal-ai-config.overrides.config.ts`) — (ideally gitignored)
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
import { defineConfig } from "universal-ai-config";
|
|
390
|
+
|
|
391
|
+
export default defineConfig({
|
|
392
|
+
// I only use Claude and Cursor
|
|
393
|
+
targets: ["claude", "cursor"],
|
|
394
|
+
|
|
395
|
+
// Extra variables for my local setup
|
|
396
|
+
variables: {
|
|
397
|
+
myPreferredStyle: "functional",
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### Merge Behavior
|
|
403
|
+
|
|
404
|
+
- **Arrays** (`targets`, `types`): overrides **replace** entirely
|
|
405
|
+
- **Objects** (`variables`, `outputDirs`): **deep-merged**
|
|
406
|
+
- **Scalars** (`templatesDir`): overrides **replace**
|
|
407
|
+
|
|
408
|
+
### Resolution Order (later wins)
|
|
409
|
+
|
|
410
|
+
1. Built-in defaults
|
|
411
|
+
2. `universal-ai-config.{ts,js,mjs,cjs}` (base)
|
|
412
|
+
3. `universal-ai-config.overrides.{ts,js,mjs,cjs}` (personal)
|
|
413
|
+
4. CLI flags (`--target`, `--type`, etc.)
|
|
414
|
+
|
|
415
|
+
## CLI Reference
|
|
416
|
+
|
|
417
|
+
### `uac generate`
|
|
418
|
+
|
|
419
|
+
Generate config files for specified targets.
|
|
420
|
+
|
|
421
|
+
| Flag | Short | Description | Default |
|
|
422
|
+
| ----------- | ----- | --------------------------- | --------------- |
|
|
423
|
+
| `--target` | `-t` | Comma-separated targets | All from config |
|
|
424
|
+
| `--type` | | Comma-separated types | All from config |
|
|
425
|
+
| `--config` | `-c` | Config file path | Auto-detected |
|
|
426
|
+
| `--root` | `-r` | Project root | cwd |
|
|
427
|
+
| `--dry-run` | `-d` | Preview without writing | `false` |
|
|
428
|
+
| `--clean` | | Remove existing files first | `false` |
|
|
429
|
+
|
|
430
|
+
### `uac init`
|
|
431
|
+
|
|
432
|
+
Scaffold `.universal-ai-config/` directory with example templates. Creates a `universal-ai-config.config.ts` config file if one doesn't exist. Adds `universal-ai-config.overrides.*` to `.gitignore`.
|
|
433
|
+
|
|
434
|
+
| Flag | Short | Description | Default |
|
|
435
|
+
| -------- | ----- | ------------ | ------- |
|
|
436
|
+
| `--root` | `-r` | Project root | cwd |
|
|
437
|
+
|
|
438
|
+
### `uac clean`
|
|
439
|
+
|
|
440
|
+
Remove all generated config directories.
|
|
441
|
+
|
|
442
|
+
| Flag | Short | Description | Default |
|
|
443
|
+
| ---------- | ----- | -------------------------------- | ------- |
|
|
444
|
+
| `--target` | `-t` | Comma-separated targets to clean | All |
|
|
445
|
+
| `--root` | `-r` | Project root | cwd |
|
|
446
|
+
|
|
447
|
+
### `uac seed`
|
|
448
|
+
|
|
449
|
+
Seed the templates directory with pre-built template sets. Currently available seed types:
|
|
450
|
+
|
|
451
|
+
- **`meta-instructions`** — Creates instruction and skill templates that teach AI tools how to create, update, and manage universal-ai-config templates. This bootstraps the AI's ability to extend its own configuration.
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
# Seed with default templates directory
|
|
455
|
+
pnpm uac seed meta-instructions
|
|
456
|
+
|
|
457
|
+
# Seed with custom project root
|
|
458
|
+
pnpm uac seed meta-instructions --root ./my-project
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
| Flag | Short | Description | Default |
|
|
462
|
+
| -------- | ----- | ------------ | ------- |
|
|
463
|
+
| `--root` | `-r` | Project root | cwd |
|
|
464
|
+
|
|
465
|
+
The `meta-instructions` seed creates 7 files in the templates directory:
|
|
466
|
+
|
|
467
|
+
| File | Purpose |
|
|
468
|
+
| ------------------------------------------- | -------------------------------------------------------------- |
|
|
469
|
+
| `instructions/uac-template-guide.md` | Decision guide for choosing the right template type |
|
|
470
|
+
| `skills/update-ai-config/SKILL.md` | Dispatcher — analyzes intent and delegates to the right skill |
|
|
471
|
+
| `skills/update-instruction/SKILL.md` | Full lifecycle management for instruction templates |
|
|
472
|
+
| `skills/update-skill/SKILL.md` | Full lifecycle management for skill templates |
|
|
473
|
+
| `skills/update-agent/SKILL.md` | Full lifecycle management for agent templates |
|
|
474
|
+
| `skills/update-hook/SKILL.md` | Full lifecycle management for hook templates |
|
|
475
|
+
| `skills/import-existing-ai-config/SKILL.md` | Import existing target-specific configs as universal templates |
|
|
476
|
+
|
|
477
|
+
Existing files are overwritten to ensure templates stay up to date.
|
|
478
|
+
|
|
479
|
+
## Output Paths
|
|
480
|
+
|
|
481
|
+
### Claude (`.claude/`)
|
|
482
|
+
|
|
483
|
+
| Type | Output Path |
|
|
484
|
+
| ------------ | ------------------------------------------------- |
|
|
485
|
+
| Instructions | `.claude/rules/<name>.md` |
|
|
486
|
+
| Skills | `.claude/skills/<name>/SKILL.md` |
|
|
487
|
+
| Agents | `.claude/agents/<name>.md` |
|
|
488
|
+
| Hooks | `.claude/settings.json` (merged into `hooks` key) |
|
|
489
|
+
|
|
490
|
+
### Copilot (`.github/`)
|
|
491
|
+
|
|
492
|
+
| Type | Output Path |
|
|
493
|
+
| ---------------------------- | --------------------------------------------- |
|
|
494
|
+
| Instructions | `.github/instructions/<name>.instructions.md` |
|
|
495
|
+
| Instructions (`alwaysApply`) | `.github/copilot-instructions.md` |
|
|
496
|
+
| Skills | `.github/skills/<name>/SKILL.md` |
|
|
497
|
+
| Agents | `.github/agents/<name>.agent.md` |
|
|
498
|
+
| Hooks | `.github/hooks/hooks.json` |
|
|
499
|
+
|
|
500
|
+
### Cursor (`.cursor/`)
|
|
501
|
+
|
|
502
|
+
| Type | Output Path |
|
|
503
|
+
| ------------ | -------------------------------- |
|
|
504
|
+
| Instructions | `.cursor/rules/<name>.mdc` |
|
|
505
|
+
| Skills | `.cursor/skills/<name>/SKILL.md` |
|
|
506
|
+
| Agents | Not supported |
|
|
507
|
+
| Hooks | `.cursor/hooks.json` |
|
|
508
|
+
|
|
509
|
+
## Frontmatter Mapping Reference
|
|
510
|
+
|
|
511
|
+
<details>
|
|
512
|
+
<summary>Instructions mapping</summary>
|
|
513
|
+
|
|
514
|
+
| Universal | Claude | Copilot | Cursor |
|
|
515
|
+
| -------------- | ------------- | ----------------------------------- | ------------------- |
|
|
516
|
+
| `description` | `description` | `description` | `description` |
|
|
517
|
+
| `globs` | `paths` | `applyTo` (comma-joined) | `globs` |
|
|
518
|
+
| `alwaysApply` | omits `paths` | routes to `copilot-instructions.md` | `alwaysApply: true` |
|
|
519
|
+
| `excludeAgent` | — | `excludeAgent` | — |
|
|
520
|
+
|
|
521
|
+
</details>
|
|
522
|
+
|
|
523
|
+
<details>
|
|
524
|
+
<summary>Skills mapping</summary>
|
|
525
|
+
|
|
526
|
+
| Universal | Claude | Copilot | Cursor |
|
|
527
|
+
| ----------------------- | -------------------------- | --------------- | -------------------------- |
|
|
528
|
+
| `name` | `name` | `name` | `name` |
|
|
529
|
+
| `description` | `description` | `description` | `description` |
|
|
530
|
+
| `disableAutoInvocation` | `disable-model-invocation` | — | `disable-model-invocation` |
|
|
531
|
+
| `userInvocable` | `user-invocable` | — | — |
|
|
532
|
+
| `allowedTools` | `allowed-tools` | — | — |
|
|
533
|
+
| `model` | `model` | — | — |
|
|
534
|
+
| `subagentType` | `agent` | — | — |
|
|
535
|
+
| `forkContext` | `context: fork` | — | — |
|
|
536
|
+
| `argumentHint` | `argument-hint` | — | — |
|
|
537
|
+
| `license` | — | `license` | `license` |
|
|
538
|
+
| `compatibility` | — | `compatibility` | `compatibility` |
|
|
539
|
+
| `metadata` | — | `metadata` | `metadata` |
|
|
540
|
+
| `hooks` | `hooks` | — | — |
|
|
541
|
+
|
|
542
|
+
</details>
|
|
543
|
+
|
|
544
|
+
<details>
|
|
545
|
+
<summary>Agents mapping</summary>
|
|
546
|
+
|
|
547
|
+
| Universal | Claude | Copilot |
|
|
548
|
+
| ----------------- | ----------------- | ------------- |
|
|
549
|
+
| `name` | `name` | `name` |
|
|
550
|
+
| `description` | `description` | `description` |
|
|
551
|
+
| `model` | `model` | `model` |
|
|
552
|
+
| `tools` | `tools` | `tools` |
|
|
553
|
+
| `disallowedTools` | `disallowedTools` | — |
|
|
554
|
+
| `permissionMode` | `permissionMode` | — |
|
|
555
|
+
| `skills` | `skills` | — |
|
|
556
|
+
| `hooks` | `hooks` | — |
|
|
557
|
+
| `memory` | `memory` | — |
|
|
558
|
+
| `target` | — | `target` |
|
|
559
|
+
| `mcpServers` | — | `mcp-servers` |
|
|
560
|
+
| `handoffs` | — | `handoffs` |
|
|
561
|
+
|
|
562
|
+
</details>
|
|
563
|
+
|
|
564
|
+
<details>
|
|
565
|
+
<summary>Hooks mapping</summary>
|
|
566
|
+
|
|
567
|
+
| Aspect | Claude | Copilot | Cursor |
|
|
568
|
+
| ----------------- | ----------------------------------- | -------------------------- | ------------------------- |
|
|
569
|
+
| Output file | `.claude/settings.json` | `.github/hooks/hooks.json` | `.cursor/hooks.json` |
|
|
570
|
+
| Merge behavior | Merges into `hooks` key | Standalone file | Standalone file |
|
|
571
|
+
| Event names | PascalCase | camelCase (some renamed) | camelCase (some renamed) |
|
|
572
|
+
| `command` field | `command` | `bash` | `command` |
|
|
573
|
+
| `timeout` field | `timeout` | `timeoutSec` | `timeout` |
|
|
574
|
+
| `matcher` support | Yes (groups handlers) | Dropped | Yes (flat) |
|
|
575
|
+
| Handler structure | Nested: `{ matcher, hooks: [...] }` | Flat: `{ type, bash }` | Flat: `{ type, command }` |
|
|
576
|
+
| Version wrapper | None | `"1"` (string) | `1` (number) |
|
|
577
|
+
|
|
578
|
+
</details>
|
|
579
|
+
|
|
580
|
+
## Programmatic API
|
|
581
|
+
|
|
582
|
+
```typescript
|
|
583
|
+
import { generate, defineConfig } from "universal-ai-config";
|
|
584
|
+
|
|
585
|
+
const files = await generate({
|
|
586
|
+
root: process.cwd(),
|
|
587
|
+
targets: ["claude"],
|
|
588
|
+
dryRun: true,
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
for (const file of files) {
|
|
592
|
+
console.log(file.path); // ".claude/rules/react-patterns.md"
|
|
593
|
+
console.log(file.content); // Rendered file content
|
|
594
|
+
console.log(file.target); // "claude"
|
|
595
|
+
console.log(file.type); // "instructions"
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
## Adding a New Target
|
|
600
|
+
|
|
601
|
+
Create a single file in `src/targets/` implementing `TargetDefinition`:
|
|
602
|
+
|
|
603
|
+
```typescript
|
|
604
|
+
import { defineTarget } from "../define-target.js";
|
|
605
|
+
|
|
606
|
+
export default defineTarget({
|
|
607
|
+
name: "zed",
|
|
608
|
+
outputDir: ".zed",
|
|
609
|
+
supportedTypes: ["instructions"],
|
|
610
|
+
instructions: {
|
|
611
|
+
frontmatterMap: {
|
|
612
|
+
globs: "path",
|
|
613
|
+
},
|
|
614
|
+
getOutputPath: (name) => `prompts/${name}.md`,
|
|
615
|
+
},
|
|
616
|
+
});
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
Then add one line to [src/targets/index.ts](src/targets/index.ts):
|
|
620
|
+
|
|
621
|
+
```typescript
|
|
622
|
+
import zed from "./zed/index.js";
|
|
623
|
+
export const targets = { claude, copilot, cursor, zed };
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
## License
|
|
627
|
+
|
|
628
|
+
MIT
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|