Skip to content

Commit fc829e9

Browse files
add the Skill.md file at the init command
1 parent 425e710 commit fc829e9

11 files changed

Lines changed: 79 additions & 25 deletions

File tree

.cursor/skills/runly/SKILL.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ npx runly init
4343
```
4444

4545
- Creates **`runly.config.js`** only if none of **`runly.config.mjs`**, **`runly.config.js`**, or **`runly.config.cjs`** exists (otherwise prints a message and exits **0**).
46+
- Writes **`SKILL.md`** in the project root when missing (Cursor agent skill template from the package); you may move it to **`.cursor/skills/runly/SKILL.md`**.
4647
- Uses **`export default`** when **`package.json`** has **`"type": "module"`**, else **`module.exports`**.
4748
- Adds **`"runly": "runly"`** under **`scripts`** in **`package.json`** when the file exists and **`scripts.runly`** is not already set.
4849
- Default **`run`** in the scaffold is a small **`node -e`** smoke command; edit to **`node --test`**, **`npm test`**, etc.
@@ -118,7 +119,7 @@ Exported types: **`RunlyConfig`**, **`RunlyRun`**. **`loadConfig(cwd?)`** loads
118119

119120
| Command / flag | Meaning |
120121
|----------------|---------|
121-
| `runly init` | Scaffold **`runly.config.js`** and **`scripts.runly`** (see above). |
122+
| `runly init` | Scaffold **`runly.config.js`**, **`SKILL.md`** (if missing), and **`scripts.runly`** (see above). |
122123
| `runly` | Run matrix using config in cwd. |
123124
| `-c`, `--config` | Path to config file. |
124125
| `runly help` | Usage. |

.cursor/skills/runly/skill/SKILL.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ npx runly init
4343
```
4444

4545
- Creates **`runly.config.js`** only if none of **`runly.config.mjs`**, **`runly.config.js`**, or **`runly.config.cjs`** exists (otherwise prints a message and exits **0**).
46+
- Writes **`SKILL.md`** in the project root when missing (Cursor agent skill template from the package); you may move it to **`.cursor/skills/runly/SKILL.md`**.
4647
- Uses **`export default`** when **`package.json`** has **`"type": "module"`**, else **`module.exports`**.
4748
- Adds **`"runly": "runly"`** under **`scripts`** in **`package.json`** when the file exists and **`scripts.runly`** is not already set.
4849
- Default **`run`** in the scaffold is a small **`node -e`** smoke command; edit to **`node --test`**, **`npm test`**, etc.
@@ -118,7 +119,7 @@ Exported types: **`RunlyConfig`**, **`RunlyRun`**. **`loadConfig(cwd?)`** loads
118119

119120
| Command / flag | Meaning |
120121
|----------------|---------|
121-
| `runly init` | Scaffold **`runly.config.js`** and **`scripts.runly`** (see above). |
122+
| `runly init` | Scaffold **`runly.config.js`**, **`SKILL.md`** (if missing), and **`scripts.runly`** (see above). |
122123
| `runly` | Run matrix using config in cwd. |
123124
| `-c`, `--config` | Path to config file. |
124125
| `runly help` | Usage. |

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ The executable name is **`runly`** (see `bin` in `package.json`).
3030

3131
### First-time setup (`init`)
3232

33-
From your project root, create a default `runly.config.js` and add an npm script **`runly`** when `package.json` exists:
33+
From your project root, create a default `runly.config.js`, a **`SKILL.md`** agent-skill template (when `SKILL.md` is not already present), and add an npm script **`runly`** when `package.json` exists:
3434

3535
```bash
3636
npx runly init
3737
```
3838

39-
If any of `runly.config.mjs`, `runly.config.js`, or `runly.config.cjs` already exists, `init` does nothing (idempotent).
39+
If any of `runly.config.mjs`, `runly.config.js`, or `runly.config.cjs` already exists, `init` does nothing for the config (idempotent). Existing **`SKILL.md`** is never overwritten.
4040

4141
### Run the matrix
4242

@@ -141,7 +141,7 @@ Exported types include `RunlyConfig` and `RunlyRun`. **`loadConfig(cwd?)`** load
141141

142142
| Command / flag | Description |
143143
|----------------|-------------|
144-
| `runly init` | Create `runly.config.js` with defaults and add `"runly": "runly"` to `package.json` when present. No-op if a config file already exists. |
144+
| `runly init` | Create `runly.config.js` with defaults, copy **`SKILL.md`** when missing, and add `"runly": "runly"` to `package.json` when present. No-op for config if a config file already exists. |
145145
| `runly`, `runly -c <path>` | Run the matrix (search for config in cwd, or use `-c` / `--config`). |
146146
| `-c`, `--config` | Path to a config file. If omitted, Runly searches for `runly.config.mjs`, then `.js`, then `.cjs` in the current working directory. |
147147
| `runly help` | Print usage. |

dist/cli.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/init.d.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/**
2-
* Create `runly.config.js` with defaults and add `"runly": "runly"` to package.json when possible.
2+
* Create `runly.config.js` with defaults, copy `SKILL.md` when absent, and add `"runly": "runly"` to package.json when possible.
33
* @returns `"exists"` if any runly config file is already present, otherwise `"created"`.
44
*/
55
export declare function initRunlyProject(cwd: string): "exists" | "created";
6-
//# sourceMappingURL=init.d.ts.map

dist/init.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { existsSync, readFileSync, writeFileSync } from "node:fs";
2-
import { join } from "node:path";
2+
import { dirname, join } from "node:path";
3+
import { fileURLToPath } from "node:url";
34
import { hasAnyRunlyConfig } from "./config-paths.js";
45
const PKG = "@hamdymohamedak/runly";
56
const DEFAULT_FILE = "runly.config.js";
7+
const SKILL_FILE = "SKILL.md";
68
function readPkgJson(cwd) {
79
const p = join(cwd, "package.json");
810
if (!existsSync(p))
@@ -23,7 +25,6 @@ function defaultConfigBody() {
2325
shell: false,
2426
},
2527
}`;
26-
}
2728
function tryAddRunlyScriptToDisk(cwd) {
2829
const pkgPath = join(cwd, "package.json");
2930
if (!existsSync(pkgPath))
@@ -45,10 +46,26 @@ function tryAddRunlyScriptToDisk(cwd) {
4546
pkg.scripts = scripts;
4647
writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
4748
}
48-
/**
49-
* Create `runly.config.js` with defaults and add `"runly": "runly"` to package.json when possible.
50-
* @returns `"exists"` if any runly config file is already present, otherwise `"created"`.
51-
*/
49+
function bundledSkillTemplatePath() {
50+
const here = dirname(fileURLToPath(import.meta.url));
51+
const packageRoot = join(here, "..");
52+
const p = join(packageRoot, "templates", SKILL_FILE);
53+
return existsSync(p) ? p : null;
54+
}
55+
function tryWriteSkillTemplate(cwd) {
56+
const target = join(cwd, SKILL_FILE);
57+
if (existsSync(target))
58+
return;
59+
const src = bundledSkillTemplatePath();
60+
if (!src)
61+
return;
62+
try {
63+
writeFileSync(target, readFileSync(src, "utf8"));
64+
}
65+
catch {
66+
/* ignore */
67+
}
68+
}
5269
export function initRunlyProject(cwd) {
5370
if (hasAnyRunlyConfig(cwd))
5471
return "exists";
@@ -59,7 +76,7 @@ export function initRunlyProject(cwd) {
5976
? `/** @type {import("${PKG}").RunlyConfig} */\nexport default ${body};\n`
6077
: `/** @type {import("${PKG}").RunlyConfig} */\nmodule.exports = ${body};\n`;
6178
writeFileSync(join(cwd, DEFAULT_FILE), content, "utf8");
79+
tryWriteSkillTemplate(cwd);
6280
tryAddRunlyScriptToDisk(cwd);
6381
return "created";
6482
}
65-
//# sourceMappingURL=init.js.map

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@hamdymohamedak/runly",
3-
"version": "0.2.0",
3+
"version": "0.2.1",
44
"publishConfig": {
55
"access": "public"
66
},
@@ -19,7 +19,8 @@
1919
}
2020
},
2121
"files": [
22-
"dist"
22+
"dist",
23+
"templates/SKILL.md"
2324
],
2425
"scripts": {
2526
"test": "node --test test/smoke.test.js",

scripts/ci-verify-init.mjs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env node
22
/**
33
* CI: pack this repo, install tarball into fresh consumers, run `runly init`, assert
4-
* runly.config.js + scripts.runly, then `npm run runly`.
4+
* runly.config.js + SKILL.md + scripts.runly, then `npm run runly`.
55
*/
66
import { spawnSync } from "node:child_process";
77
import { existsSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
@@ -49,6 +49,16 @@ function verifyConsumer(label, pkgJson, assertConfig) {
4949
}
5050
assertConfig(readFileSync(cfg, "utf8"));
5151

52+
const skill = join(consumer, "SKILL.md");
53+
if (!existsSync(skill)) {
54+
console.error(`[${label}] missing SKILL.md after runly init`);
55+
process.exit(1);
56+
}
57+
if (!readFileSync(skill, "utf8").includes("name: runly")) {
58+
console.error(`[${label}] SKILL.md looks invalid`);
59+
process.exit(1);
60+
}
61+
5262
const installed = JSON.parse(readFileSync(join(consumer, "package.json"), "utf8"));
5363
if (installed.scripts?.runly !== "runly") {
5464
console.error(`[${label}] expected scripts.runly === "runly", got:`, installed.scripts);

src/cli.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ async function main() {
4949
process.exit(0);
5050
}
5151
console.error(
52-
"Created runly.config.js with default matrix. Added npm script \"runly\" if package.json is present.",
52+
"Created runly.config.js with default matrix, SKILL.md (if missing), and npm script \"runly\" if package.json is present.",
5353
);
5454
process.exit(0);
5555
}

src/init.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { existsSync, readFileSync, writeFileSync } from "node:fs";
2-
import { join } from "node:path";
2+
import { dirname, join } from "node:path";
3+
import { fileURLToPath } from "node:url";
34
import { hasAnyRunlyConfig } from "./config-paths.js";
45

56
const PKG = "@hamdymohamedak/runly";
67
const DEFAULT_FILE = "runly.config.js";
8+
const SKILL_FILE = "SKILL.md";
79

810
function readPkgJson(cwd: string) {
911
const p = join(cwd, "package.json");
@@ -46,8 +48,29 @@ function tryAddRunlyScriptToDisk(cwd: string): void {
4648
writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
4749
}
4850

51+
/** Path to bundled `templates/SKILL.md` inside the installed package (next to `dist/`). */
52+
function bundledSkillTemplatePath(): string | null {
53+
const here = dirname(fileURLToPath(import.meta.url));
54+
const packageRoot = join(here, "..");
55+
const p = join(packageRoot, "templates", SKILL_FILE);
56+
return existsSync(p) ? p : null;
57+
}
58+
59+
/** Copy agent skill template next to config; skip if `SKILL.md` already exists. */
60+
function tryWriteSkillTemplate(cwd: string): void {
61+
const target = join(cwd, SKILL_FILE);
62+
if (existsSync(target)) return;
63+
const src = bundledSkillTemplatePath();
64+
if (!src) return;
65+
try {
66+
writeFileSync(target, readFileSync(src, "utf8"));
67+
} catch {
68+
/* ignore missing or unreadable template */
69+
}
70+
}
71+
4972
/**
50-
* Create `runly.config.js` with defaults and add `"runly": "runly"` to package.json when possible.
73+
* Create `runly.config.js` with defaults, copy `SKILL.md` when absent, and add `"runly": "runly"` to package.json when possible.
5174
* @returns `"exists"` if any runly config file is already present, otherwise `"created"`.
5275
*/
5376
export function initRunlyProject(cwd: string): "exists" | "created" {
@@ -61,6 +84,7 @@ export function initRunlyProject(cwd: string): "exists" | "created" {
6184
: `/** @type {import("${PKG}").RunlyConfig} */\nmodule.exports = ${body};\n`;
6285

6386
writeFileSync(join(cwd, DEFAULT_FILE), content, "utf8");
87+
tryWriteSkillTemplate(cwd);
6488
tryAddRunlyScriptToDisk(cwd);
6589
return "created";
6690
}

0 commit comments

Comments
 (0)