codex-template 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 codex-template contributors
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,141 @@
1
+ # codex-template
2
+
3
+ [![CI](https://github.com/joeneldeasis/codex-template/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/joeneldeasis/codex-template/actions/workflows/ci.yml)
4
+ [![CodeQL](https://github.com/joeneldeasis/codex-template/actions/workflows/codeql.yml/badge.svg?branch=main)](https://github.com/joeneldeasis/codex-template/actions/workflows/codeql.yml)
5
+ ![Node.js](https://img.shields.io/badge/node-%3E%3D20-339933)
6
+ ![License](https://img.shields.io/badge/license-MIT-blue)
7
+
8
+ Install [aitmpl.com](https://aitmpl.com/) skills, commands, agents, and MCPs into Codex.
9
+
10
+ ```bash
11
+ npx codex-template --skill creative-design/frontend-design
12
+ ```
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install -g codex-template
18
+ codex-template --help
19
+ ```
20
+
21
+ Or run it once without a global install:
22
+
23
+ ```bash
24
+ npx codex-template@latest --skill creative-design/frontend-design
25
+ ```
26
+
27
+ ## Quick start
28
+
29
+ Global install is the default. Add `--project` or `--directory <path>` to write into a repository.
30
+
31
+ ```bash
32
+ npx codex-template --skill creative-design/frontend-design
33
+ npx codex-template --command testing/generate-tests
34
+ npx codex-template --agent development-team/frontend-developer
35
+ npx codex-template --mcp web/web-fetch
36
+ npx codex-template --doctor
37
+ ```
38
+
39
+ | Component | Location |
40
+ | --- | --- |
41
+ | Skill | `~/.agents/skills/<name>/` |
42
+ | Command | `~/.agents/skills/<name>/` as an explicit skill (`SKILL.md` plus `agents/openai.yaml`) |
43
+ | Agent | `~/.codex/agents/<name>.toml` |
44
+ | MCP | merged into `~/.codex/config.toml` as `[mcp_servers.<id>]` |
45
+
46
+ The category prefix is dropped, so `creative-design/frontend-design` installs as `frontend-design`. Command text keeps `$ARGUMENTS` and Claude `!` syntax. The first write to `config.toml` also saves `config.toml.bak`.
47
+
48
+ ## Commands and options
49
+
50
+ ```text
51
+ codex-template [options]
52
+
53
+ --skill <ids> Install skills, comma-separated
54
+ --command <ids> Install commands, comma-separated
55
+ --agent <ids> Install agents, comma-separated
56
+ --mcp <ids> Install MCPs, comma-separated
57
+ -d, --directory <path> Install into a project instead of the user profile
58
+ --project Same as --directory .
59
+ -y, --yes Overwrite without prompting
60
+ --dry-run Show planned writes and do not change files
61
+ --list [type] List catalog ids
62
+ --search <type> <query>
63
+ --info <type> <id>
64
+ --installed
65
+ --remove <type> <id>
66
+ --update <type> <id>
67
+ --update --all
68
+ --doctor
69
+ --verbose
70
+ --debug Print stack traces
71
+ -h, --help
72
+ -V, --version
73
+ ```
74
+
75
+ Browse the catalog at [skills](https://aitmpl.com/skills/), [commands](https://aitmpl.com/commands/), [agents](https://aitmpl.com/agents/), and [MCPs](https://aitmpl.com/mcps/).
76
+
77
+ ## Configuration
78
+
79
+ There is no config file. Scope comes from the CLI:
80
+
81
+ 1. `--directory` or `--project` installs into that project
82
+ 2. otherwise files go under the user profile
83
+
84
+ Existing keys in `config.toml`, including other MCP servers, are kept. A different value for the same server asks before overwrite unless `--yes` is set.
85
+
86
+ ## Environment variables
87
+
88
+ | Variable | Purpose |
89
+ | --- | --- |
90
+ | `GITHUB_TOKEN` | Optional token for the GitHub catalog API when unauthenticated requests are rate-limited. The token is not printed. |
91
+
92
+ ## Programmatic API
93
+
94
+ ```js
95
+ import { installComponent, destRoots, createCatalog } from 'codex-template';
96
+
97
+ const roots = destRoots({ target: 'codex', scope: 'project', directory: process.cwd() });
98
+ const catalog = createCatalog();
99
+ await installComponent({
100
+ target: 'codex',
101
+ roots,
102
+ type: 'skill',
103
+ id: 'creative-design/frontend-design',
104
+ yes: true,
105
+ catalog,
106
+ });
107
+ ```
108
+
109
+ Also exported: `removeComponent`, `listInstalled`, `checkInstall`, and `runCli`.
110
+
111
+ ## Troubleshooting
112
+
113
+ `GitHub rate limit` means the catalog request was rejected. Set `GITHUB_TOKEN` and run the command again.
114
+
115
+ `Unknown component type` means the type was not `skill`, `command`, `agent`, or `mcp`.
116
+
117
+ `not found` means that catalog id is not in `davila7/claude-code-templates`. Check the id on aitmpl.com.
118
+
119
+ Exit codes: `0` success, `1` the operation failed, `2` the arguments were invalid.
120
+
121
+ ## Development
122
+
123
+ Requires Node.js 20 or newer.
124
+
125
+ ```bash
126
+ npm ci
127
+ npm run validate
128
+ npm run ci
129
+ ```
130
+
131
+ `npm run validate` lints, typechecks, builds `dist/`, tests, and writes coverage. `npm run ci` also checks the packed files and runs the tarball with npx from a clean temporary directory.
132
+
133
+ ## Publishing
134
+
135
+ Publishing happens from a git tag `vX.Y.Z` whose version matches `package.json`. The release workflow runs the same validation, publishes with npm provenance, and creates a GitHub Release.
136
+
137
+ The published package contains `dist/`, `bin/cli.js`, `README.md`, and `LICENSE`. Check a packed build locally with:
138
+
139
+ ```bash
140
+ npm run ci
141
+ ```
package/bin/cli.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from '../dist/cli/run.js';
3
+
4
+ const code = await runCli('codex');
5
+ process.exit(code);
@@ -0,0 +1,30 @@
1
+ import { Command } from 'commander';
2
+ import type { CliOptions, Target } from '../core/types.js';
3
+ export declare function commandName(target: Target): string;
4
+ export declare function buildProgram(target: Target): Command;
5
+ export declare function expandArgv(argv: string[]): string[];
6
+ interface RawOpts {
7
+ skill?: string;
8
+ command?: string;
9
+ agent?: string;
10
+ mcp?: string;
11
+ directory?: string;
12
+ project?: boolean;
13
+ yes?: boolean;
14
+ dryRun?: boolean;
15
+ verbose?: boolean;
16
+ debug?: boolean;
17
+ list?: string | boolean;
18
+ installed?: boolean;
19
+ doctor?: boolean;
20
+ search?: string;
21
+ info?: string;
22
+ remove?: string;
23
+ update?: string;
24
+ updateAll?: boolean;
25
+ all?: boolean;
26
+ }
27
+ export declare function optionsFromCommand(opts: RawOpts): CliOptions;
28
+ export declare function parseCliArgs(argv: string[], target: Target): CliOptions;
29
+ export declare function hasAction(options: CliOptions): boolean;
30
+ export {};
@@ -0,0 +1,156 @@
1
+ import { Command } from 'commander';
2
+ import { VERSION } from '../config/constants.js';
3
+ import { UsageError } from '../utils/errors.js';
4
+ import { normalizeType, splitIds } from '../utils/ids.js';
5
+ export function commandName(target) {
6
+ return target === 'cursor' ? 'cursor-template' : 'codex-template';
7
+ }
8
+ export function buildProgram(target) {
9
+ const name = commandName(target);
10
+ const program = new Command()
11
+ .name(name)
12
+ .description(`Install aitmpl.com skills, commands, agents, and MCPs for ${target === 'cursor' ? 'Cursor' : 'Codex'}`)
13
+ .version(VERSION)
14
+ .option('--skill <ids>', 'install skills (comma-separated)')
15
+ .option('--command <ids>', 'install commands (comma-separated)')
16
+ .option('--agent <ids>', 'install agents (comma-separated)')
17
+ .option('--mcp <ids>', 'install MCPs (comma-separated)')
18
+ .option('-d, --directory <path>', 'install into a project directory instead of the user profile')
19
+ .option('--project', 'alias for --directory .')
20
+ .option('-y, --yes', 'overwrite without prompting')
21
+ .option('--dry-run', 'show planned writes without changing files')
22
+ .option('--verbose', 'log catalog requests (tokens are not printed)')
23
+ .option('--debug', 'print stack traces for unexpected errors')
24
+ .option('--list [type]', 'list catalog ids (skill, command, agent, mcp)')
25
+ .option('--search <pair>', 'search the catalog: --search <type> <query>')
26
+ .option('--info <pair>', 'show one component: --info <type> <id>')
27
+ .option('--installed', 'list components on disk')
28
+ .option('--remove <pair>', 'remove one component: --remove <type> <id>')
29
+ .option('--update <pair>', 're-fetch one component: --update <type> <id>')
30
+ .option('--update-all', 're-fetch every installed component')
31
+ .option('--all', 'with --update, refresh everything installed')
32
+ .option('--doctor', 'check install directories and files')
33
+ .allowExcessArguments(false);
34
+ program.addHelpText('after', `
35
+ Examples:
36
+ ${name} --skill creative-design/frontend-design
37
+ ${name} --command testing/generate-tests --project
38
+ ${name} --search skill frontend
39
+ ${name} --doctor
40
+
41
+ Environment:
42
+ GITHUB_TOKEN Optional GitHub token used when the catalog API is rate-limited
43
+ `);
44
+ return program;
45
+ }
46
+ export function expandArgv(argv) {
47
+ const out = argv.slice(0, 2);
48
+ const args = argv.slice(2);
49
+ for (let i = 0; i < args.length; i += 1) {
50
+ const token = args[i];
51
+ if (token === '--update' && args[i + 1] === '--all') {
52
+ out.push('--update-all');
53
+ i += 1;
54
+ continue;
55
+ }
56
+ if (token === '--update' && (!args[i + 1] || args[i + 1].startsWith('-'))) {
57
+ out.push('--update-all');
58
+ continue;
59
+ }
60
+ if (token === '--search' || token === '--info' || token === '--remove' || token === '--update') {
61
+ const left = args[i + 1];
62
+ const right = args[i + 2];
63
+ if (!left || left.startsWith('-') || !right || right.startsWith('-')) {
64
+ throw new UsageError(`${token} requires <type> and a second argument.\n\nUse:\n ${token} skill creative-design/frontend-design`);
65
+ }
66
+ out.push(token, `${left} ${right}`);
67
+ i += 2;
68
+ continue;
69
+ }
70
+ out.push(token);
71
+ }
72
+ return out;
73
+ }
74
+ function splitPair(value, flag) {
75
+ const index = value.indexOf(' ');
76
+ if (index === -1)
77
+ throw new UsageError(`${flag} requires <type> and a second argument`);
78
+ return [value.slice(0, index), value.slice(index + 1)];
79
+ }
80
+ function listValue(value) {
81
+ if (typeof value !== 'string')
82
+ return value === true ? true : null;
83
+ return normalizeType(value);
84
+ }
85
+ export function optionsFromCommand(opts) {
86
+ const options = {
87
+ skill: splitIds(opts.skill),
88
+ command: splitIds(opts.command),
89
+ agent: splitIds(opts.agent),
90
+ mcp: splitIds(opts.mcp),
91
+ directory: opts.directory || null,
92
+ yes: Boolean(opts.yes),
93
+ dryRun: Boolean(opts.dryRun),
94
+ verbose: Boolean(opts.verbose),
95
+ debug: Boolean(opts.debug),
96
+ list: listValue(opts.list),
97
+ installed: Boolean(opts.installed),
98
+ doctor: Boolean(opts.doctor),
99
+ search: null,
100
+ info: null,
101
+ remove: null,
102
+ update: null,
103
+ };
104
+ if (opts.project && !options.directory)
105
+ options.directory = '.';
106
+ if (opts.search) {
107
+ const [type, query] = splitPair(opts.search, '--search');
108
+ options.search = { type: normalizeType(type), query };
109
+ }
110
+ if (opts.info) {
111
+ const [type, id] = splitPair(opts.info, '--info');
112
+ options.info = { type: normalizeType(type), id };
113
+ }
114
+ if (opts.remove) {
115
+ const [type, id] = splitPair(opts.remove, '--remove');
116
+ options.remove = { type: normalizeType(type), id };
117
+ }
118
+ if (opts.updateAll || opts.all)
119
+ options.update = { all: true };
120
+ else if (opts.update) {
121
+ const [type, id] = splitPair(opts.update, '--update');
122
+ options.update = { type: normalizeType(type), id };
123
+ }
124
+ if (opts.all && !opts.update && !opts.updateAll) {
125
+ throw new UsageError('Use --update --all to refresh every installed component.');
126
+ }
127
+ return options;
128
+ }
129
+ export function parseCliArgs(argv, target) {
130
+ const program = buildProgram(target);
131
+ program.exitOverride();
132
+ program.configureOutput({ writeOut: () => { }, writeErr: () => { } });
133
+ try {
134
+ program.parse(expandArgv(argv));
135
+ }
136
+ catch (error) {
137
+ if (error instanceof UsageError)
138
+ throw error;
139
+ const message = error instanceof Error ? error.message : String(error);
140
+ throw new UsageError(message);
141
+ }
142
+ return optionsFromCommand(program.opts());
143
+ }
144
+ export function hasAction(options) {
145
+ return Boolean(options.skill.length
146
+ || options.command.length
147
+ || options.agent.length
148
+ || options.mcp.length
149
+ || options.list !== null
150
+ || options.search
151
+ || options.info
152
+ || options.installed
153
+ || options.remove
154
+ || options.update
155
+ || options.doctor);
156
+ }
@@ -0,0 +1,11 @@
1
+ import type { Catalog, Target } from '../core/types.js';
2
+ export interface CliIo {
3
+ stdout?: (message: string) => void;
4
+ stderr?: (message: string) => void;
5
+ home?: string;
6
+ catalog?: Catalog;
7
+ fetchImpl?: typeof fetch;
8
+ argv?: string[];
9
+ }
10
+ export declare function printHelp(target: Target): void;
11
+ export declare function runCli(target: Target, argv?: string[], io?: CliIo): Promise<number>;
@@ -0,0 +1,210 @@
1
+ import os from 'node:os';
2
+ import path from 'node:path';
3
+ import chalk from 'chalk';
4
+ import { BROWSE } from '../config/constants.js';
5
+ import { doctor } from '../core/doctor.js';
6
+ import { installById, removeInstalled, sourceLine } from '../core/install.js';
7
+ import { collectInstalled } from '../core/lifecycle.js';
8
+ import { readManifest } from '../core/manifest.js';
9
+ import { componentDest, destRoots } from '../core/paths.js';
10
+ import { createCatalog } from '../services/github.js';
11
+ import { UsageError, formatError } from '../utils/errors.js';
12
+ import { assertSafeId, normalizeType } from '../utils/ids.js';
13
+ import { buildProgram, hasAction, parseCliArgs } from './args.js';
14
+ function browseLines() {
15
+ return [
16
+ ` skills ${BROWSE.skills}`,
17
+ ` commands ${BROWSE.commands}`,
18
+ ` agents ${BROWSE.agents}`,
19
+ ` mcps ${BROWSE.mcps}`,
20
+ ].join('\n');
21
+ }
22
+ export function printHelp(target) {
23
+ buildProgram(target).outputHelp();
24
+ console.log(`\nBrowse:\n${browseLines()}`);
25
+ }
26
+ function rootsFor(target, options, home) {
27
+ return destRoots({
28
+ target,
29
+ scope: options.directory ? 'project' : 'global',
30
+ directory: options.directory ? path.resolve(options.directory) : undefined,
31
+ home,
32
+ });
33
+ }
34
+ export async function runCli(target, argv = process.argv, io = {}) {
35
+ const log = io.stdout || console.log;
36
+ const args = argv.slice(2);
37
+ if (args.length === 0 || args.includes('-h') || args.includes('--help')) {
38
+ printHelp(target);
39
+ return 0;
40
+ }
41
+ if (args.includes('-V') || args.includes('--version')) {
42
+ buildProgram(target).parse(argv);
43
+ return 0;
44
+ }
45
+ let options;
46
+ try {
47
+ options = parseCliArgs(argv, target);
48
+ }
49
+ catch (error) {
50
+ const stderr = io.stderr || ((message) => console.error(chalk.red(message)));
51
+ stderr(formatError(error, false));
52
+ return error instanceof UsageError ? error.exitCode : 2;
53
+ }
54
+ const stderr = io.stderr || ((message) => console.error(chalk.red(message)));
55
+ if (!hasAction(options)) {
56
+ printHelp(target);
57
+ return 0;
58
+ }
59
+ const roots = rootsFor(target, options, io.home || os.homedir());
60
+ const catalog = io.catalog || createCatalog({ verbose: options.verbose || options.debug, fetchImpl: io.fetchImpl });
61
+ let code = 0;
62
+ const fail = (error) => {
63
+ stderr(formatError(error, options.debug));
64
+ code = error instanceof UsageError ? error.exitCode : 1;
65
+ };
66
+ if (options.list !== null) {
67
+ try {
68
+ const records = await catalog.list(options.list === true ? null : options.list);
69
+ const groups = new Map();
70
+ for (const record of records) {
71
+ const list = groups.get(record.type) || [];
72
+ list.push(record.id);
73
+ groups.set(record.type, list);
74
+ }
75
+ for (const [group, ids] of groups) {
76
+ log(chalk.cyan(`${group} (${ids.length})`));
77
+ for (const id of ids)
78
+ log(` ${id}`);
79
+ }
80
+ }
81
+ catch (error) {
82
+ fail(error);
83
+ }
84
+ }
85
+ if (options.search) {
86
+ try {
87
+ const records = await catalog.search(options.search.type, options.search.query);
88
+ if (!records.length)
89
+ log(`no ${options.search.type} matches for "${options.search.query}"`);
90
+ for (const record of records) {
91
+ const description = await catalog.descriptionFor(record);
92
+ log(`${record.id}${description ? `\n ${description}` : ''}`);
93
+ }
94
+ }
95
+ catch (error) {
96
+ fail(error);
97
+ }
98
+ }
99
+ if (options.info) {
100
+ try {
101
+ assertSafeId(options.info.id);
102
+ const record = await catalog.resolve(options.info.type, options.info.id);
103
+ const dest = componentDest({ target, roots, type: record.type, name: record.name });
104
+ const description = await catalog.descriptionFor(record);
105
+ log(`${record.type} ${record.id}`);
106
+ log(`name: ${record.name}`);
107
+ log(`source: ${sourceLine(record)}`);
108
+ log(`install: ${dest.path}`);
109
+ if (description)
110
+ log(`description: ${description}`);
111
+ }
112
+ catch (error) {
113
+ fail(error);
114
+ }
115
+ }
116
+ if (options.installed) {
117
+ try {
118
+ const items = await collectInstalled({ target, roots });
119
+ if (!items.length)
120
+ log('nothing installed');
121
+ for (const item of items) {
122
+ const state = item.present ? '' : chalk.yellow(' missing');
123
+ log(`${item.type.padEnd(8)} ${item.tracked ? item.id : `${item.id} (untracked)`}${state}`);
124
+ log(` ${item.path}`);
125
+ }
126
+ }
127
+ catch (error) {
128
+ fail(error);
129
+ }
130
+ }
131
+ if (options.remove) {
132
+ try {
133
+ assertSafeId(options.remove.id);
134
+ const removed = await removeInstalled({
135
+ target,
136
+ roots,
137
+ type: options.remove.type,
138
+ id: options.remove.id,
139
+ yes: options.yes,
140
+ dryRun: options.dryRun,
141
+ });
142
+ if (!removed)
143
+ code = 1;
144
+ }
145
+ catch (error) {
146
+ fail(error);
147
+ }
148
+ }
149
+ if (options.update) {
150
+ try {
151
+ const jobs = [];
152
+ if ('all' in options.update) {
153
+ const manifest = await readManifest(roots.manifest);
154
+ jobs.push(...Object.values(manifest.components));
155
+ if (!jobs.length)
156
+ log('nothing installed to update');
157
+ }
158
+ else {
159
+ assertSafeId(options.update.id);
160
+ jobs.push({ type: options.update.type, id: options.update.id });
161
+ }
162
+ for (const job of jobs) {
163
+ const ok = await installById({
164
+ target,
165
+ roots,
166
+ type: normalizeType(job.type),
167
+ id: job.id,
168
+ yes: true,
169
+ dryRun: options.dryRun,
170
+ catalog,
171
+ });
172
+ if (ok === false)
173
+ code = 1;
174
+ }
175
+ }
176
+ catch (error) {
177
+ fail(error);
178
+ }
179
+ }
180
+ for (const type of ['skill', 'command', 'agent', 'mcp']) {
181
+ for (const id of options[type]) {
182
+ try {
183
+ assertSafeId(id);
184
+ const ok = await installById({ target, roots, type, id, yes: options.yes, dryRun: options.dryRun, catalog });
185
+ if (ok === false)
186
+ code = 1;
187
+ }
188
+ catch (error) {
189
+ fail(error);
190
+ }
191
+ }
192
+ }
193
+ if (options.doctor) {
194
+ try {
195
+ const report = await doctor({ target, roots });
196
+ for (const note of report.notes)
197
+ log(chalk.green(note));
198
+ for (const issue of report.issues)
199
+ log(chalk.yellow(issue));
200
+ if (report.issues.length)
201
+ code = 1;
202
+ else if (!report.notes.length)
203
+ log('doctor: ok');
204
+ }
205
+ catch (error) {
206
+ fail(error);
207
+ }
208
+ }
209
+ return code;
210
+ }
@@ -0,0 +1,27 @@
1
+ export declare const REPO = "davila7/claude-code-templates";
2
+ export declare const BRANCH = "main";
3
+ export declare const COMPONENTS_PREFIX = "cli-tool/components/";
4
+ export declare const VERSION = "0.1.0";
5
+ export declare const USER_AGENT = "cursor-codex-templates/0.1.0";
6
+ export declare const BROWSE: {
7
+ readonly skills: "https://aitmpl.com/skills/";
8
+ readonly commands: "https://aitmpl.com/commands/";
9
+ readonly agents: "https://aitmpl.com/agents/";
10
+ readonly mcps: "https://aitmpl.com/mcps/";
11
+ };
12
+ export declare const TYPE_ALIASES: {
13
+ readonly skill: "skill";
14
+ readonly skills: "skill";
15
+ readonly command: "command";
16
+ readonly commands: "command";
17
+ readonly agent: "agent";
18
+ readonly agents: "agent";
19
+ readonly mcp: "mcp";
20
+ readonly mcps: "mcp";
21
+ };
22
+ export declare const CATALOG_GROUPS: {
23
+ readonly skills: "skill";
24
+ readonly commands: "command";
25
+ readonly agents: "agent";
26
+ readonly mcps: "mcp";
27
+ };
@@ -0,0 +1,27 @@
1
+ export const REPO = 'davila7/claude-code-templates';
2
+ export const BRANCH = 'main';
3
+ export const COMPONENTS_PREFIX = 'cli-tool/components/';
4
+ export const VERSION = '0.1.0';
5
+ export const USER_AGENT = `cursor-codex-templates/${VERSION}`;
6
+ export const BROWSE = {
7
+ skills: 'https://aitmpl.com/skills/',
8
+ commands: 'https://aitmpl.com/commands/',
9
+ agents: 'https://aitmpl.com/agents/',
10
+ mcps: 'https://aitmpl.com/mcps/',
11
+ };
12
+ export const TYPE_ALIASES = {
13
+ skill: 'skill',
14
+ skills: 'skill',
15
+ command: 'command',
16
+ commands: 'command',
17
+ agent: 'agent',
18
+ agents: 'agent',
19
+ mcp: 'mcp',
20
+ mcps: 'mcp',
21
+ };
22
+ export const CATALOG_GROUPS = {
23
+ skills: 'skill',
24
+ commands: 'command',
25
+ agents: 'agent',
26
+ mcps: 'mcp',
27
+ };
@@ -0,0 +1,7 @@
1
+ export declare function cursorAgentMarkdown(markdown: string): string;
2
+ export declare function agentMarkdownToToml(markdown: string, fallbackName: string): string;
3
+ export declare function wrapCommandAsSkill(markdown: string, name: string): {
4
+ skill: string;
5
+ openaiYaml: string;
6
+ description: string;
7
+ };
@@ -0,0 +1,28 @@
1
+ import { stringify } from 'smol-toml';
2
+ import { descriptionText, parseFrontmatter, stringifyFrontmatter } from '../utils/frontmatter.js';
3
+ export function cursorAgentMarkdown(markdown) {
4
+ const { data, body } = parseFrontmatter(markdown);
5
+ if (!Object.keys(data).length)
6
+ return markdown.endsWith('\n') ? markdown : `${markdown}\n`;
7
+ delete data.tools;
8
+ return stringifyFrontmatter(data, body);
9
+ }
10
+ export function agentMarkdownToToml(markdown, fallbackName) {
11
+ const { data, body } = parseFrontmatter(markdown);
12
+ const name = descriptionText(data.name) || fallbackName;
13
+ const description = descriptionText(data.description) || `Use the ${name} agent.`;
14
+ return stringify({
15
+ name,
16
+ description,
17
+ developer_instructions: `${body.trim()}\n`,
18
+ });
19
+ }
20
+ export function wrapCommandAsSkill(markdown, name) {
21
+ const { data, body } = parseFrontmatter(markdown);
22
+ const description = descriptionText(data.description) || `Run the ${name} workflow from aitmpl.`;
23
+ return {
24
+ skill: stringifyFrontmatter({ name, description }, body),
25
+ openaiYaml: 'policy:\n allow_implicit_invocation: false\n',
26
+ description,
27
+ };
28
+ }
@@ -0,0 +1,8 @@
1
+ import type { InstallRoots, Target } from './types.js';
2
+ export declare function doctor({ target, roots }: {
3
+ target: Target;
4
+ roots: InstallRoots;
5
+ }): Promise<{
6
+ issues: string[];
7
+ notes: string[];
8
+ }>;