@ethlete/agent-rules 0.1.0-next.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.
Files changed (68) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +106 -0
  3. package/content/defaults.json +10 -0
  4. package/content/rules/comments.md +31 -0
  5. package/content/rules/lint-and-format.md +26 -0
  6. package/content/rules/reactive-state.md +15 -0
  7. package/content/rules/styling.md +35 -0
  8. package/content/skills/angular-patterns/SKILL.md +60 -0
  9. package/content/skills/git-commit/SKILL.md +29 -0
  10. package/content/skills/handoff/SKILL.md +98 -0
  11. package/content/skills/query/SKILL.md +114 -0
  12. package/content/skills/rxjs-signals/SKILL.md +65 -0
  13. package/content/skills/sdk-docs/SKILL.md +70 -0
  14. package/content/skills/story-styling/SKILL.md +83 -0
  15. package/content/skills/styleguide/SKILL.md +66 -0
  16. package/content/skills/styleguide/STYLEGUIDE.md +520 -0
  17. package/content/skills/theming/SKILL.md +110 -0
  18. package/content/skills/verify-in-storybook/SKILL.md +78 -0
  19. package/content/skills/verify-in-storybook/verify-template.mjs +42 -0
  20. package/package.json +15 -0
  21. package/src/index.d.ts +2 -0
  22. package/src/index.js +79 -0
  23. package/src/index.js.map +1 -0
  24. package/src/lib/config.d.ts +21 -0
  25. package/src/lib/config.js +54 -0
  26. package/src/lib/config.js.map +1 -0
  27. package/src/lib/filter.d.ts +16 -0
  28. package/src/lib/filter.js +49 -0
  29. package/src/lib/filter.js.map +1 -0
  30. package/src/lib/frontmatter.d.ts +23 -0
  31. package/src/lib/frontmatter.js +117 -0
  32. package/src/lib/frontmatter.js.map +1 -0
  33. package/src/lib/index.d.ts +9 -0
  34. package/src/lib/index.js +13 -0
  35. package/src/lib/index.js.map +1 -0
  36. package/src/lib/load-content.d.ts +19 -0
  37. package/src/lib/load-content.js +79 -0
  38. package/src/lib/load-content.js.map +1 -0
  39. package/src/lib/owned-paths.d.ts +7 -0
  40. package/src/lib/owned-paths.js +47 -0
  41. package/src/lib/owned-paths.js.map +1 -0
  42. package/src/lib/plan.d.ts +20 -0
  43. package/src/lib/plan.js +57 -0
  44. package/src/lib/plan.js.map +1 -0
  45. package/src/lib/render.d.ts +39 -0
  46. package/src/lib/render.js +73 -0
  47. package/src/lib/render.js.map +1 -0
  48. package/src/lib/sync.d.ts +9 -0
  49. package/src/lib/sync.js +90 -0
  50. package/src/lib/sync.js.map +1 -0
  51. package/src/lib/targets/claude.d.ts +7 -0
  52. package/src/lib/targets/claude.js +46 -0
  53. package/src/lib/targets/claude.js.map +1 -0
  54. package/src/lib/targets/codex.d.ts +11 -0
  55. package/src/lib/targets/codex.js +26 -0
  56. package/src/lib/targets/codex.js.map +1 -0
  57. package/src/lib/targets/copilot.d.ts +11 -0
  58. package/src/lib/targets/copilot.js +43 -0
  59. package/src/lib/targets/copilot.js.map +1 -0
  60. package/src/lib/targets/cursor.d.ts +7 -0
  61. package/src/lib/targets/cursor.js +35 -0
  62. package/src/lib/targets/cursor.js.map +1 -0
  63. package/src/lib/targets/neutral.d.ts +8 -0
  64. package/src/lib/targets/neutral.js +29 -0
  65. package/src/lib/targets/neutral.js.map +1 -0
  66. package/src/lib/targets/shared.d.ts +60 -0
  67. package/src/lib/targets/shared.js +50 -0
  68. package/src/lib/targets/shared.js.map +1 -0
@@ -0,0 +1,78 @@
1
+ ---
2
+ name: verify-in-storybook
3
+ description: Visually/behaviorally verify a component change by driving its Storybook story headlessly with Playwright. Use whenever you change a UI component and need to confirm the rendered DOM, computed styles, animations, or interactions actually work - not just that it compiles.
4
+ kind: skill
5
+ scope: consumer
6
+ vars: [storybookUrl, storybookStartCommand]
7
+ ---
8
+
9
+ # Verify a component change in Storybook (headless Playwright)
10
+
11
+ Storybook is the ground truth for component behaviour. Drive the real story in a
12
+ headless browser and assert on the rendered DOM / computed styles, rather than
13
+ trusting a build alone.
14
+
15
+ ## 1. Make sure Storybook is running
16
+
17
+ It is usually already up. Check first - **do not blindly start a second
18
+ instance**, it will hit an interactive port prompt and hang:
19
+
20
+ ```bash
21
+ curl -s -o /dev/null -w "%{http_code}" {%storybookUrl%}/
22
+ ```
23
+
24
+ - `200` → it's up, proceed.
25
+ - anything else → start it in the background and wait for the port:
26
+ ```bash
27
+ {%storybookStartCommand%}
28
+ ```
29
+ Run it in the background and poll the curl above until it returns `200`
30
+ (a cold start can take 30–60s).
31
+
32
+ ## 2. Find the story ID
33
+
34
+ Story IDs are derived from the story `title` + export name, e.g.
35
+ `Components/Tabs/Inline` → `components-tabs-inline--default`. List them from the
36
+ index:
37
+
38
+ ```bash
39
+ curl -s {%storybookUrl%}/index.json \
40
+ | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const j=JSON.parse(d);Object.values(j.entries).filter(s=>/YOURFILTER/i.test(s.title)).forEach(s=>console.log(s.id,'::',s.title,'::',s.name))})"
41
+ ```
42
+
43
+ ## 3. Open the story headlessly
44
+
45
+ Render a single story in isolation via the **iframe URL** (no manager chrome):
46
+
47
+ ```
48
+ {%storybookUrl%}/iframe.html?id=<story-id>&viewMode=story
49
+ ```
50
+
51
+ ## 4. Drive it with Playwright
52
+
53
+ Playwright must be in the repo's devDependencies (`@playwright/test` /
54
+ `playwright`). Write the script in a scratch directory, resolve Playwright from
55
+ the repo's `node_modules`, and run it - {%resource:verify-template.mjs%} is a
56
+ copy-paste starting point.
57
+
58
+ Gotchas that will waste your time if you forget them:
59
+
60
+ - **`playwright` is CommonJS.** In an `.mjs`, resolve it with `createRequire`
61
+ (as the template does) - a named `import { chromium } from 'playwright'` fails.
62
+ - **Use `waitUntil: 'domcontentloaded'`**, never `networkidle` - Storybook's HMR
63
+ websocket keeps the connection open so `networkidle` times out forever.
64
+ - **`waitForSelector` defaults to `state: 'visible'`.** Elements that are
65
+ correctly hidden (`visibility:hidden`, `opacity:0`, collapsed height, `inert`)
66
+ will never become "visible" and you'll get a misleading timeout. Use
67
+ `{ state: 'attached' }` when you intend to inspect a hidden element.
68
+ - **Assert on the real signal.** Portal/`ng-content` text lands as text nodes, so
69
+ `childElementCount` is 0 even when content is present - check `el.textContent`.
70
+ Read computed styles with `getComputedStyle(el)` inside `page.$eval`.
71
+ - After a click that triggers a CSS transition, `waitForTimeout(transitionMs + buffer)`
72
+ before reading final-state styles.
73
+
74
+ ## 5. Report
75
+
76
+ State plainly what you drove and observed (collapsed→open→collapsed, tab switch,
77
+ etc.) and whether it matched the expected behaviour. Keep the throwaway script in
78
+ the scratch directory, not the repo.
@@ -0,0 +1,42 @@
1
+ // Headless Storybook verification template.
2
+ // Copy into a scratch directory, adjust STORY_ID + the assertions, then run:
3
+ // node <scratch>/verify.mjs
4
+ //
5
+ // Playwright is CommonJS and lives in the repo's node_modules, so resolve it
6
+ // through createRequire from the repo root rather than importing it by name.
7
+ import { createRequire } from 'node:module';
8
+
9
+ const require = createRequire(`${process.cwd()}/`);
10
+ const { chromium } = require('playwright');
11
+
12
+ const STORY_ID = 'components-button--default'; // <-- change me
13
+ const url = `{%storybookUrl%}/iframe.html?viewMode=story&id=${STORY_ID}`;
14
+
15
+ const browser = await chromium.launch(); // headless by default
16
+ const page = await browser.newPage({ viewport: { width: 900, height: 700 } });
17
+
18
+ // domcontentloaded, NOT networkidle (Storybook's HMR socket never goes idle)
19
+ await page.goto(url, { waitUntil: 'domcontentloaded' });
20
+
21
+ // state:'attached' so intentionally-hidden elements don't time out on 'visible'
22
+ await page.waitForSelector('.et-some-component', { state: 'attached' });
23
+
24
+ // Inspect rendered DOM + computed styles. textContent (not childElementCount)
25
+ // is the reliable signal for ng-content / portal-projected text.
26
+ const state = await page.$eval('.et-some-component', (el) => {
27
+ const cs = getComputedStyle(el);
28
+ return {
29
+ visibility: cs.visibility,
30
+ opacity: cs.opacity,
31
+ height: el.offsetHeight,
32
+ text: el.textContent.trim(),
33
+ };
34
+ });
35
+ console.log('state:', JSON.stringify(state));
36
+
37
+ // Example interaction: click, wait out a CSS transition, re-read.
38
+ // await page.click('.et-some-trigger');
39
+ // await page.waitForTimeout(500); // >= transition duration
40
+ // console.log('after:', JSON.stringify(await page.$eval('.et-some-component', ...)));
41
+
42
+ await browser.close();
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "@ethlete/agent-rules",
3
+ "version": "0.1.0-next.0",
4
+ "license": "MIT",
5
+ "type": "commonjs",
6
+ "main": "./src/index.js",
7
+ "typings": "./src/index.d.ts",
8
+ "bin": {
9
+ "ethlete-agents": "./src/index.js"
10
+ },
11
+ "peerDependencies": {
12
+ "tslib": "2.8.1"
13
+ },
14
+ "types": "./src/index.d.ts"
15
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export * from './lib';
package/src/index.js ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const tslib_1 = require("tslib");
5
+ const fs_1 = require("fs");
6
+ const path_1 = require("path");
7
+ const config_1 = require("./lib/config");
8
+ const sync_1 = require("./lib/sync");
9
+ const USAGE = `ethlete-agents — compile @ethlete agent rules and skills into your repo
10
+
11
+ ethlete-agents sync Write the generated rules/skills for every detected agent
12
+ ethlete-agents check Exit non-zero when the generated files are out of date (for CI)
13
+ ethlete-agents init Write a starter ${config_1.CONFIG_FILE_NAME}
14
+
15
+ Options
16
+ --targets <list> Comma-separated subset of: ${config_1.AGENT_TARGETS.join(', ')}
17
+ --root <path> Repo root to write into (default: current directory)
18
+ --dry-run Print what sync would change without writing (sync only)
19
+ `;
20
+ const readFlag = (args, flag) => {
21
+ const index = args.indexOf(flag);
22
+ if (index === -1)
23
+ return undefined;
24
+ return args[index + 1];
25
+ };
26
+ const parseTargets = (args) => {
27
+ const raw = readFlag(args, '--targets');
28
+ if (!raw)
29
+ return undefined;
30
+ return raw.split(',').map((entry) => entry.trim());
31
+ };
32
+ const readVersion = () => {
33
+ const manifest = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '..', 'package.json'), 'utf8'));
34
+ return manifest.version;
35
+ };
36
+ const init = (root) => {
37
+ const path = (0, path_1.join)(root, config_1.CONFIG_FILE_NAME);
38
+ if ((0, fs_1.existsSync)(path)) {
39
+ console.error(`${config_1.CONFIG_FILE_NAME} already exists.`);
40
+ return 1;
41
+ }
42
+ const template = {
43
+ targets: (0, config_1.detectTargets)(root),
44
+ vars: {},
45
+ exclude: [],
46
+ };
47
+ (0, fs_1.writeFileSync)(path, `${JSON.stringify(template, null, 2)}\n`, 'utf8');
48
+ console.log(`Wrote ${config_1.CONFIG_FILE_NAME}. Fill in "vars" for your repo, then run \`ethlete-agents sync\`.`);
49
+ return 0;
50
+ };
51
+ const run = (argv) => {
52
+ var _a;
53
+ const command = argv[0];
54
+ const root = (_a = readFlag(argv, '--root')) !== null && _a !== void 0 ? _a : process.cwd();
55
+ const options = { root, version: readVersion(), targets: parseTargets(argv) };
56
+ switch (command) {
57
+ case 'sync':
58
+ return (0, sync_1.sync)(Object.assign(Object.assign({}, options), { dryRun: argv.includes('--dry-run') }));
59
+ case 'check':
60
+ return (0, sync_1.check)(options);
61
+ case 'init':
62
+ return init(root);
63
+ default:
64
+ console.log(USAGE);
65
+ return command === undefined || command === '--help' || command === '-h' ? 0 : 1;
66
+ }
67
+ };
68
+ tslib_1.__exportStar(require("./lib"), exports);
69
+ // Guarded so the package can also be imported as a library without running the CLI.
70
+ if (require.main === module) {
71
+ try {
72
+ process.exit(run(process.argv.slice(2)));
73
+ }
74
+ catch (error) {
75
+ console.error(error instanceof Error ? error.message : error);
76
+ process.exit(1);
77
+ }
78
+ }
79
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/agent-rules/src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { ContentScope } from './frontmatter';
2
+ export declare const AGENT_TARGETS: readonly ["claude", "codex", "cursor", "copilot"];
3
+ export type AgentTarget = (typeof AGENT_TARGETS)[number];
4
+ export declare const CONFIG_FILE_NAME = "ethlete-agents.config.json";
5
+ export type SyncConfig = {
6
+ root: string;
7
+ targets: AgentTarget[];
8
+ /** Scopes to emit: a consumer repo wants `consumer` + `both`, the SDK repo only `both`. */
9
+ scopes: ContentScope[];
10
+ vars: Record<string, string | string[]>;
11
+ exclude: string[];
12
+ };
13
+ /**
14
+ * Emit for the agents a repo already uses. Everything falls back to Codex's `AGENTS.md`,
15
+ * which Cursor, Copilot and most other agents read as well.
16
+ */
17
+ export declare const detectTargets: (root: string) => AgentTarget[];
18
+ export declare const loadConfig: (options: {
19
+ root: string;
20
+ targetOverride?: AgentTarget[];
21
+ }) => SyncConfig;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadConfig = exports.detectTargets = exports.CONFIG_FILE_NAME = exports.AGENT_TARGETS = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const load_content_1 = require("./load-content");
7
+ exports.AGENT_TARGETS = ['claude', 'codex', 'cursor', 'copilot'];
8
+ exports.CONFIG_FILE_NAME = 'ethlete-agents.config.json';
9
+ const readRawConfig = (root) => {
10
+ const path = (0, path_1.join)(root, exports.CONFIG_FILE_NAME);
11
+ if (!(0, fs_1.existsSync)(path))
12
+ return {};
13
+ return JSON.parse((0, fs_1.readFileSync)(path, 'utf8'));
14
+ };
15
+ /**
16
+ * Emit for the agents a repo already uses. Everything falls back to Codex's `AGENTS.md`,
17
+ * which Cursor, Copilot and most other agents read as well.
18
+ */
19
+ const detectTargets = (root) => {
20
+ const detected = [];
21
+ if ((0, fs_1.existsSync)((0, path_1.join)(root, '.claude')))
22
+ detected.push('claude');
23
+ if ((0, fs_1.existsSync)((0, path_1.join)(root, 'AGENTS.md')) || (0, fs_1.existsSync)((0, path_1.join)(root, '.codex')))
24
+ detected.push('codex');
25
+ if ((0, fs_1.existsSync)((0, path_1.join)(root, '.cursor')))
26
+ detected.push('cursor');
27
+ if ((0, fs_1.existsSync)((0, path_1.join)(root, '.github')))
28
+ detected.push('copilot');
29
+ return detected.length > 0 ? detected : ['codex'];
30
+ };
31
+ exports.detectTargets = detectTargets;
32
+ const assertKnownTargets = (targets) => {
33
+ const unknown = targets.filter((target) => !exports.AGENT_TARGETS.includes(target));
34
+ if (unknown.length > 0) {
35
+ throw new Error(`Unknown target(s): ${unknown.join(', ')}. Known targets: ${exports.AGENT_TARGETS.join(', ')}.`);
36
+ }
37
+ };
38
+ const loadConfig = (options) => {
39
+ var _a, _b, _c;
40
+ const { root, targetOverride } = options;
41
+ const raw = readRawConfig(root);
42
+ const configured = raw.targets && raw.targets !== 'auto' ? raw.targets : undefined;
43
+ const targets = (_a = targetOverride !== null && targetOverride !== void 0 ? targetOverride : configured) !== null && _a !== void 0 ? _a : (0, exports.detectTargets)(root);
44
+ assertKnownTargets(targets);
45
+ return {
46
+ root,
47
+ targets,
48
+ scopes: raw.profile === 'sdk' ? ['both'] : ['consumer', 'both'],
49
+ vars: Object.assign(Object.assign({}, (0, load_content_1.loadDefaultVars)()), ((_b = raw.vars) !== null && _b !== void 0 ? _b : {})),
50
+ exclude: (_c = raw.exclude) !== null && _c !== void 0 ? _c : [],
51
+ };
52
+ };
53
+ exports.loadConfig = loadConfig;
54
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../libs/agent-rules/src/lib/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { SyncConfig } from './config';
2
+ import { ContentItem } from './load-content';
3
+ export type SkippedItem = {
4
+ name: string;
5
+ reason: string;
6
+ };
7
+ export type FilterResult = {
8
+ kept: ContentItem[];
9
+ skipped: SkippedItem[];
10
+ };
11
+ /**
12
+ * A hoisted `node_modules` entry counts as installed even when the dependency is declared in a
13
+ * workspace package rather than at the root, so monorepo consumers are not silently filtered out.
14
+ */
15
+ export declare const isPackageInstalled: (root: string, packageName: string) => boolean;
16
+ export declare const filterContent: (items: ContentItem[], config: SyncConfig) => FilterResult;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.filterContent = exports.isPackageInstalled = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ /**
7
+ * A hoisted `node_modules` entry counts as installed even when the dependency is declared in a
8
+ * workspace package rather than at the root, so monorepo consumers are not silently filtered out.
9
+ */
10
+ const isPackageInstalled = (root, packageName) => {
11
+ if ((0, fs_1.existsSync)((0, path_1.join)(root, 'node_modules', ...packageName.split('/'))))
12
+ return true;
13
+ const manifestPath = (0, path_1.join)(root, 'package.json');
14
+ if (!(0, fs_1.existsSync)(manifestPath))
15
+ return false;
16
+ const manifest = JSON.parse((0, fs_1.readFileSync)(manifestPath, 'utf8'));
17
+ const declared = Object.assign(Object.assign(Object.assign({}, manifest.dependencies), manifest.devDependencies), manifest.peerDependencies);
18
+ return Object.prototype.hasOwnProperty.call(declared, packageName);
19
+ };
20
+ exports.isPackageInstalled = isPackageInstalled;
21
+ const filterContent = (items, config) => {
22
+ const kept = [];
23
+ const skipped = [];
24
+ for (const item of items) {
25
+ const { name, scope, requires, vars } = item.frontmatter;
26
+ if (config.exclude.includes(name)) {
27
+ skipped.push({ name, reason: 'excluded by config' });
28
+ continue;
29
+ }
30
+ if (!config.scopes.includes(scope)) {
31
+ skipped.push({ name, reason: `scope "${scope}" is not emitted for this profile` });
32
+ continue;
33
+ }
34
+ const missingPackage = requires.find((packageName) => !(0, exports.isPackageInstalled)(config.root, packageName));
35
+ if (missingPackage) {
36
+ skipped.push({ name, reason: `requires ${missingPackage}, which is not installed` });
37
+ continue;
38
+ }
39
+ const missingVar = vars.find((varName) => config.vars[varName] === undefined);
40
+ if (missingVar) {
41
+ skipped.push({ name, reason: `needs the "${missingVar}" variable — set it in vars` });
42
+ continue;
43
+ }
44
+ kept.push(item);
45
+ }
46
+ return { kept, skipped };
47
+ };
48
+ exports.filterContent = filterContent;
49
+ //# sourceMappingURL=filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.js","sourceRoot":"","sources":["../../../../../libs/agent-rules/src/lib/filter.ts"],"names":[],"mappings":";;;AAAA,2BAA8C;AAC9C,+BAA4B;AAoB5B;;;GAGG;AACI,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAE,WAAmB,EAAE,EAAE;IACtE,IAAI,IAAA,eAAU,EAAC,IAAA,WAAI,EAAC,IAAI,EAAE,cAAc,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnF,MAAM,YAAY,GAAG,IAAA,WAAI,EAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAEhD,IAAI,CAAC,IAAA,eAAU,EAAC,YAAY,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,YAAY,EAAE,MAAM,CAAC,CAAoB,CAAC;IACnF,MAAM,QAAQ,iDACT,QAAQ,CAAC,YAAY,GACrB,QAAQ,CAAC,eAAe,GACxB,QAAQ,CAAC,gBAAgB,CAC7B,CAAC;IAEF,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AACrE,CAAC,CAAC;AAfW,QAAA,kBAAkB,sBAe7B;AAEK,MAAM,aAAa,GAAG,CAAC,KAAoB,EAAE,MAAkB,EAAgB,EAAE;IACtF,MAAM,IAAI,GAAkB,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;QAEzD,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACrD,SAAS;QACX,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,KAAK,mCAAmC,EAAE,CAAC,CAAC;YACnF,SAAS;QACX,CAAC;QAED,MAAM,cAAc,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAA,0BAAkB,EAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;QAErG,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,cAAc,0BAA0B,EAAE,CAAC,CAAC;YACrF,SAAS;QACX,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC;QAE9E,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,UAAU,6BAA6B,EAAE,CAAC,CAAC;YACtF,SAAS;QACX,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC,CAAC;AAnCW,QAAA,aAAa,iBAmCxB"}
@@ -0,0 +1,23 @@
1
+ export declare const CONTENT_KINDS: readonly ["rule", "skill"];
2
+ export declare const CONTENT_SCOPES: readonly ["consumer", "sdk", "both"];
3
+ export type ContentKind = (typeof CONTENT_KINDS)[number];
4
+ export type ContentScope = (typeof CONTENT_SCOPES)[number];
5
+ export type Frontmatter = {
6
+ name: string;
7
+ description: string;
8
+ kind: ContentKind;
9
+ scope: ContentScope;
10
+ requires: string[];
11
+ paths: string[];
12
+ vars: string[];
13
+ };
14
+ export type ParsedDocument = {
15
+ frontmatter: Frontmatter;
16
+ body: string;
17
+ };
18
+ /**
19
+ * Reads the tiny subset of YAML the content files are allowed to use: single-line
20
+ * `key: value` pairs, inline `key: [a, b]` lists, and `- item` block lists. Anything
21
+ * else throws — silently mis-parsing an agent instruction is worse than failing the build.
22
+ */
23
+ export declare const parseFrontmatter: (source: string, origin: string) => ParsedDocument;
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseFrontmatter = exports.CONTENT_SCOPES = exports.CONTENT_KINDS = void 0;
4
+ exports.CONTENT_KINDS = ['rule', 'skill'];
5
+ exports.CONTENT_SCOPES = ['consumer', 'sdk', 'both'];
6
+ const FENCE = '---';
7
+ const KNOWN_KEYS = ['name', 'description', 'kind', 'scope', 'requires', 'paths', 'vars'];
8
+ const LIST_KEYS = ['requires', 'paths', 'vars'];
9
+ const unquote = (value) => {
10
+ const trimmed = value.trim();
11
+ const quoted = trimmed.length >= 2 &&
12
+ ((trimmed.startsWith("'") && trimmed.endsWith("'")) || (trimmed.startsWith('"') && trimmed.endsWith('"')));
13
+ return quoted ? trimmed.slice(1, -1) : trimmed;
14
+ };
15
+ const parseInlineList = (value) => {
16
+ const inner = value.trim().slice(1, -1).trim();
17
+ if (!inner)
18
+ return [];
19
+ return inner
20
+ .split(',')
21
+ .map(unquote)
22
+ .filter((entry) => entry.length > 0);
23
+ };
24
+ const splitBlock = (source, origin) => {
25
+ const normalized = source.replace(/\r\n/g, '\n');
26
+ const padded = normalized.endsWith('\n') ? normalized : `${normalized}\n`;
27
+ if (!padded.startsWith(`${FENCE}\n`)) {
28
+ throw new Error(`${origin}: missing the opening '---' frontmatter fence.`);
29
+ }
30
+ const end = padded.indexOf(`\n${FENCE}\n`, FENCE.length);
31
+ if (end === -1) {
32
+ throw new Error(`${origin}: the frontmatter block is never closed with '---'.`);
33
+ }
34
+ return {
35
+ head: padded.slice(FENCE.length + 1, end).split('\n'),
36
+ body: padded.slice(end + FENCE.length + 2).replace(/^\n+/, ''),
37
+ };
38
+ };
39
+ /**
40
+ * Reads the tiny subset of YAML the content files are allowed to use: single-line
41
+ * `key: value` pairs, inline `key: [a, b]` lists, and `- item` block lists. Anything
42
+ * else throws — silently mis-parsing an agent instruction is worse than failing the build.
43
+ */
44
+ const parseFrontmatter = (source, origin) => {
45
+ var _a;
46
+ const { head, body } = splitBlock(source, origin);
47
+ const raw = {};
48
+ let listKey = null;
49
+ for (const line of head) {
50
+ if (!line.trim() || line.trim().startsWith('#'))
51
+ continue;
52
+ const item = /^\s*-\s+(.*)$/.exec(line);
53
+ if ((item === null || item === void 0 ? void 0 : item[1]) !== undefined) {
54
+ if (!listKey) {
55
+ throw new Error(`${origin}: list item "${line.trim()}" does not belong to a key.`);
56
+ }
57
+ raw[listKey].push(unquote(item[1]));
58
+ continue;
59
+ }
60
+ const separator = line.indexOf(':');
61
+ if (separator === -1) {
62
+ throw new Error(`${origin}: cannot parse frontmatter line "${line}".`);
63
+ }
64
+ const key = line.slice(0, separator).trim();
65
+ const value = line.slice(separator + 1).trim();
66
+ if (!KNOWN_KEYS.includes(key)) {
67
+ throw new Error(`${origin}: unknown frontmatter key "${key}". Known keys: ${KNOWN_KEYS.join(', ')}.`);
68
+ }
69
+ if (LIST_KEYS.includes(key) && !value) {
70
+ raw[key] = [];
71
+ listKey = key;
72
+ continue;
73
+ }
74
+ listKey = null;
75
+ raw[key] = value.startsWith('[') ? parseInlineList(value) : unquote(value);
76
+ }
77
+ const readText = (key) => {
78
+ const value = raw[key];
79
+ return typeof value === 'string' ? value : undefined;
80
+ };
81
+ const readList = (key) => {
82
+ const value = raw[key];
83
+ if (value === undefined)
84
+ return [];
85
+ return Array.isArray(value) ? value : [value];
86
+ };
87
+ const name = readText('name');
88
+ const description = readText('description');
89
+ const kind = readText('kind');
90
+ const scope = (_a = readText('scope')) !== null && _a !== void 0 ? _a : 'consumer';
91
+ if (!name)
92
+ throw new Error(`${origin}: frontmatter is missing "name".`);
93
+ if (!description)
94
+ throw new Error(`${origin}: frontmatter is missing "description".`);
95
+ if (!kind)
96
+ throw new Error(`${origin}: frontmatter is missing "kind".`);
97
+ if (!exports.CONTENT_KINDS.includes(kind)) {
98
+ throw new Error(`${origin}: kind "${kind}" must be one of ${exports.CONTENT_KINDS.join(', ')}.`);
99
+ }
100
+ if (!exports.CONTENT_SCOPES.includes(scope)) {
101
+ throw new Error(`${origin}: scope "${scope}" must be one of ${exports.CONTENT_SCOPES.join(', ')}.`);
102
+ }
103
+ return {
104
+ frontmatter: {
105
+ name,
106
+ description,
107
+ kind: kind,
108
+ scope: scope,
109
+ requires: readList('requires'),
110
+ paths: readList('paths'),
111
+ vars: readList('vars'),
112
+ },
113
+ body: body.trimEnd(),
114
+ };
115
+ };
116
+ exports.parseFrontmatter = parseFrontmatter;
117
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../../../../libs/agent-rules/src/lib/frontmatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export * from './config';
2
+ export * from './filter';
3
+ export * from './frontmatter';
4
+ export * from './load-content';
5
+ export * from './owned-paths';
6
+ export * from './plan';
7
+ export * from './render';
8
+ export * from './sync';
9
+ export * from './targets/shared';
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./config"), exports);
5
+ tslib_1.__exportStar(require("./filter"), exports);
6
+ tslib_1.__exportStar(require("./frontmatter"), exports);
7
+ tslib_1.__exportStar(require("./load-content"), exports);
8
+ tslib_1.__exportStar(require("./owned-paths"), exports);
9
+ tslib_1.__exportStar(require("./plan"), exports);
10
+ tslib_1.__exportStar(require("./render"), exports);
11
+ tslib_1.__exportStar(require("./sync"), exports);
12
+ tslib_1.__exportStar(require("./targets/shared"), exports);
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/agent-rules/src/lib/index.ts"],"names":[],"mappings":";;;AAAA,mDAAyB;AACzB,mDAAyB;AACzB,wDAA8B;AAC9B,yDAA+B;AAC/B,wDAA8B;AAC9B,iDAAuB;AACvB,mDAAyB;AACzB,iDAAuB;AACvB,2DAAiC"}
@@ -0,0 +1,19 @@
1
+ import { Frontmatter } from './frontmatter';
2
+ export type ContentResource = {
3
+ /** File name as referenced from a body via `{{resource:…}}`. */
4
+ fileName: string;
5
+ absolutePath: string;
6
+ };
7
+ export type ContentItem = {
8
+ frontmatter: Frontmatter;
9
+ body: string;
10
+ sourcePath: string;
11
+ resources: ContentResource[];
12
+ };
13
+ /**
14
+ * The compiled CLI lives at `<pkg>/src/lib/`, the shipped markdown at `<pkg>/content/`.
15
+ * The same relative hop works from the TypeScript sources, so dev and published runs agree.
16
+ */
17
+ export declare const resolveContentRoot: () => string;
18
+ export declare const loadContent: (contentRoot?: string) => ContentItem[];
19
+ export declare const loadDefaultVars: (contentRoot?: string) => Record<string, string | string[]>;