@ethlete/agent-rules 0.1.0-next.0 → 0.1.0-next.2
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/CHANGELOG.md +20 -0
- package/README.md +97 -15
- package/content/hooks/context-warning.py +215 -0
- package/content/skills/sdk-docs/SKILL.md +1 -0
- package/content/skills/sdk-local-build/SKILL.md +113 -0
- package/content/skills/sdk-source/SKILL.md +108 -0
- package/content/skills/styleguide/STYLEGUIDE.md +1 -1
- package/package.json +1 -1
- package/src/index.js +12 -4
- package/src/index.js.map +1 -1
- package/src/lib/config.d.ts +39 -2
- package/src/lib/config.js +30 -8
- package/src/lib/config.js.map +1 -1
- package/src/lib/index.d.ts +1 -0
- package/src/lib/index.js +1 -0
- package/src/lib/index.js.map +1 -1
- package/src/lib/migrate.d.ts +6 -0
- package/src/lib/migrate.js +155 -0
- package/src/lib/migrate.js.map +1 -0
- package/src/lib/owned-paths.js +4 -1
- package/src/lib/owned-paths.js.map +1 -1
- package/src/lib/plan.d.ts +4 -0
- package/src/lib/plan.js +85 -6
- package/src/lib/plan.js.map +1 -1
- package/src/lib/sync.js +8 -2
- package/src/lib/sync.js.map +1 -1
- package/src/lib/targets/agents-skills.d.ts +8 -0
- package/src/lib/targets/agents-skills.js +18 -0
- package/src/lib/targets/agents-skills.js.map +1 -0
- package/src/lib/targets/claude-hooks.d.ts +33 -0
- package/src/lib/targets/claude-hooks.js +97 -0
- package/src/lib/targets/claude-hooks.js.map +1 -0
- package/src/lib/targets/claude.d.ts +3 -1
- package/src/lib/targets/claude.js +13 -20
- package/src/lib/targets/claude.js.map +1 -1
- package/src/lib/targets/codex.d.ts +5 -3
- package/src/lib/targets/codex.js +8 -7
- package/src/lib/targets/codex.js.map +1 -1
- package/src/lib/targets/copilot.d.ts +3 -3
- package/src/lib/targets/copilot.js +5 -28
- package/src/lib/targets/copilot.js.map +1 -1
- package/src/lib/targets/cursor.d.ts +3 -3
- package/src/lib/targets/cursor.js +6 -11
- package/src/lib/targets/cursor.js.map +1 -1
- package/src/lib/targets/shared.d.ts +22 -12
- package/src/lib/targets/shared.js +32 -15
- package/src/lib/targets/shared.js.map +1 -1
- package/src/lib/targets/neutral.d.ts +0 -8
- package/src/lib/targets/neutral.js +0 -29
- package/src/lib/targets/neutral.js.map +0 -1
package/src/index.js
CHANGED
|
@@ -5,17 +5,22 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const fs_1 = require("fs");
|
|
6
6
|
const path_1 = require("path");
|
|
7
7
|
const config_1 = require("./lib/config");
|
|
8
|
+
const migrate_1 = require("./lib/migrate");
|
|
8
9
|
const sync_1 = require("./lib/sync");
|
|
9
10
|
const USAGE = `ethlete-agents — compile @ethlete agent rules and skills into your repo
|
|
10
11
|
|
|
11
|
-
ethlete-agents sync
|
|
12
|
-
ethlete-agents check
|
|
13
|
-
ethlete-agents init
|
|
12
|
+
ethlete-agents sync Write the generated rules/skills for every detected agent
|
|
13
|
+
ethlete-agents check Exit non-zero when the generated files are out of date (for CI)
|
|
14
|
+
ethlete-agents init Write a starter ${config_1.CONFIG_FILE_NAME}
|
|
15
|
+
ethlete-agents migrate Convert the repo to the AGENTS.md + .agents/skills layout:
|
|
16
|
+
CLAUDE.md content moves into AGENTS.md (CLAUDE.md becomes an
|
|
17
|
+
@AGENTS.md import), hand-written .claude/skills move to
|
|
18
|
+
.agents/skills with symlinks left behind, then a sync runs
|
|
14
19
|
|
|
15
20
|
Options
|
|
16
21
|
--targets <list> Comma-separated subset of: ${config_1.AGENT_TARGETS.join(', ')}
|
|
17
22
|
--root <path> Repo root to write into (default: current directory)
|
|
18
|
-
--dry-run Print what
|
|
23
|
+
--dry-run Print what would change without writing (sync and migrate)
|
|
19
24
|
`;
|
|
20
25
|
const readFlag = (args, flag) => {
|
|
21
26
|
const index = args.indexOf(flag);
|
|
@@ -43,6 +48,7 @@ const init = (root) => {
|
|
|
43
48
|
targets: (0, config_1.detectTargets)(root),
|
|
44
49
|
vars: {},
|
|
45
50
|
exclude: [],
|
|
51
|
+
hooks: [],
|
|
46
52
|
};
|
|
47
53
|
(0, fs_1.writeFileSync)(path, `${JSON.stringify(template, null, 2)}\n`, 'utf8');
|
|
48
54
|
console.log(`Wrote ${config_1.CONFIG_FILE_NAME}. Fill in "vars" for your repo, then run \`ethlete-agents sync\`.`);
|
|
@@ -60,6 +66,8 @@ const run = (argv) => {
|
|
|
60
66
|
return (0, sync_1.check)(options);
|
|
61
67
|
case 'init':
|
|
62
68
|
return init(root);
|
|
69
|
+
case 'migrate':
|
|
70
|
+
return (0, migrate_1.migrate)(Object.assign(Object.assign({}, options), { dryRun: argv.includes('--dry-run') }));
|
|
63
71
|
default:
|
|
64
72
|
console.log(USAGE);
|
|
65
73
|
return command === undefined || command === '--help' || command === '-h' ? 0 : 1;
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/agent-rules/src/index.ts"],"names":[],"mappings":";;;;AACA,2BAA6D;AAC7D,+BAA4B;AAC5B,yCAA2F;AAC3F,qCAAyC;AAEzC,MAAM,KAAK,GAAG;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/agent-rules/src/index.ts"],"names":[],"mappings":";;;;AACA,2BAA6D;AAC7D,+BAA4B;AAC5B,yCAA2F;AAC3F,2CAAwC;AACxC,qCAAyC;AAEzC,MAAM,KAAK,GAAG;;;;6CAI+B,yBAAgB;;;;;;;kDAOX,sBAAa,CAAC,IAAI,CAAC,IAAI,CAAC;;;CAGzE,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,IAAc,EAAE,IAAY,EAAE,EAAE;IAChD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjC,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAEnC,OAAO,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AACzB,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,IAAc,EAAE,EAAE;IACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAExC,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAE3B,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAkB,CAAC;AACtE,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,GAAG,EAAE;IACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,IAAA,WAAI,EAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAwB,CAAC;IAEhH,OAAO,QAAQ,CAAC,OAAO,CAAC;AAC1B,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE;IAC5B,MAAM,IAAI,GAAG,IAAA,WAAI,EAAC,IAAI,EAAE,yBAAgB,CAAC,CAAC;IAE1C,IAAI,IAAA,eAAU,EAAC,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,GAAG,yBAAgB,kBAAkB,CAAC,CAAC;QAErD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,QAAQ,GAAG;QACf,OAAO,EAAE,IAAA,sBAAa,EAAC,IAAI,CAAC;QAC5B,IAAI,EAAE,EAAE;QACR,OAAO,EAAE,EAAE;QACX,KAAK,EAAE,EAAE;KACV,CAAC;IAEF,IAAA,kBAAa,EAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,SAAS,yBAAgB,mEAAmE,CAAC,CAAC;IAE1G,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,MAAM,GAAG,GAAG,CAAC,IAAc,EAAE,EAAE;;IAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,IAAI,GAAG,MAAA,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,mCAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACvD,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;IAE9E,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,IAAA,WAAI,kCAAM,OAAO,KAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAG,CAAC;QAClE,KAAK,OAAO;YACV,OAAO,IAAA,YAAK,EAAC,OAAO,CAAC,CAAC;QACxB,KAAK,MAAM;YACT,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,KAAK,SAAS;YACZ,OAAO,IAAA,iBAAO,kCAAM,OAAO,KAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAG,CAAC;QACrE;YACE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAEnB,OAAO,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrF,CAAC;AACH,CAAC,CAAC;AAEF,gDAAsB;AAEtB,oFAAoF;AACpF,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
package/src/lib/config.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { ContentScope } from './frontmatter';
|
|
|
2
2
|
export declare const AGENT_TARGETS: readonly ["claude", "codex", "cursor", "copilot"];
|
|
3
3
|
export type AgentTarget = (typeof AGENT_TARGETS)[number];
|
|
4
4
|
export declare const CONFIG_FILE_NAME = "ethlete-agents.config.json";
|
|
5
|
+
export declare const LOCAL_CONFIG_FILE_NAME = "ethlete-agents.config.local.json";
|
|
5
6
|
export type SyncConfig = {
|
|
6
7
|
root: string;
|
|
7
8
|
targets: AgentTarget[];
|
|
@@ -9,10 +10,46 @@ export type SyncConfig = {
|
|
|
9
10
|
scopes: ContentScope[];
|
|
10
11
|
vars: Record<string, string | string[]>;
|
|
11
12
|
exclude: string[];
|
|
13
|
+
/**
|
|
14
|
+
* Declares that the repo's `CLAUDE.md` is an `@AGENTS.md` import (or symlink). The claude
|
|
15
|
+
* target then skips `.claude/rules/ethlete/` — the rules already reach Claude through the
|
|
16
|
+
* `AGENTS.md` marker block, and a second copy would load twice.
|
|
17
|
+
*/
|
|
18
|
+
claudeMdImportsAgentsMd: boolean;
|
|
19
|
+
/** Opt-in Claude Code hooks (they run commands on the developer's machine, so never default). */
|
|
20
|
+
hooks: string[];
|
|
12
21
|
};
|
|
13
22
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
23
|
+
* The gitignored local config holds per-machine values, read at runtime — by the generated hook
|
|
24
|
+
* scripts, and by the agent while following a skill — never by `sync`. Sync output must be
|
|
25
|
+
* identical on every machine and in CI (the generated files are committed and `check` diffs them),
|
|
26
|
+
* so nothing here may change what gets emitted:
|
|
27
|
+
*
|
|
28
|
+
* - `disableHooks: true` silences every generated hook, `["context-warning"]` just the named ones.
|
|
29
|
+
* - `sdkSourcePath` points at a local `ethlete-sdk` checkout, which the SDK source and local-build
|
|
30
|
+
* skills read when they need the SDK's own sources instead of the published package.
|
|
31
|
+
*/
|
|
32
|
+
export type LocalConfig = {
|
|
33
|
+
disableHooks?: boolean | string[];
|
|
34
|
+
sdkSourcePath?: string;
|
|
35
|
+
};
|
|
36
|
+
export type LocalConfigState = {
|
|
37
|
+
exists: false;
|
|
38
|
+
} | {
|
|
39
|
+
exists: true;
|
|
40
|
+
valid: false;
|
|
41
|
+
} | {
|
|
42
|
+
exists: true;
|
|
43
|
+
valid: true;
|
|
44
|
+
config: LocalConfig;
|
|
45
|
+
unknownKeys: string[];
|
|
46
|
+
};
|
|
47
|
+
export declare const readLocalConfig: (root: string) => LocalConfigState;
|
|
48
|
+
/**
|
|
49
|
+
* Emit for the agents a repo already uses. `codex` is always included: `AGENTS.md` is the
|
|
50
|
+
* cross-tool standard that Cursor, Copilot and most other agents read as well, and gating it on
|
|
51
|
+
* an existing `AGENTS.md` would mean the file that triggers Codex output is the very file the
|
|
52
|
+
* sync is supposed to create.
|
|
16
53
|
*/
|
|
17
54
|
export declare const detectTargets: (root: string) => AgentTarget[];
|
|
18
55
|
export declare const loadConfig: (options: {
|
package/src/lib/config.js
CHANGED
|
@@ -1,32 +1,52 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.loadConfig = exports.detectTargets = exports.CONFIG_FILE_NAME = exports.AGENT_TARGETS = void 0;
|
|
3
|
+
exports.loadConfig = exports.detectTargets = exports.readLocalConfig = exports.LOCAL_CONFIG_FILE_NAME = exports.CONFIG_FILE_NAME = exports.AGENT_TARGETS = void 0;
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
5
|
const path_1 = require("path");
|
|
6
6
|
const load_content_1 = require("./load-content");
|
|
7
7
|
exports.AGENT_TARGETS = ['claude', 'codex', 'cursor', 'copilot'];
|
|
8
8
|
exports.CONFIG_FILE_NAME = 'ethlete-agents.config.json';
|
|
9
|
+
exports.LOCAL_CONFIG_FILE_NAME = 'ethlete-agents.config.local.json';
|
|
9
10
|
const readRawConfig = (root) => {
|
|
10
11
|
const path = (0, path_1.join)(root, exports.CONFIG_FILE_NAME);
|
|
11
12
|
if (!(0, fs_1.existsSync)(path))
|
|
12
13
|
return {};
|
|
13
14
|
return JSON.parse((0, fs_1.readFileSync)(path, 'utf8'));
|
|
14
15
|
};
|
|
16
|
+
const LOCAL_CONFIG_KEYS = ['disableHooks', 'sdkSourcePath'];
|
|
17
|
+
const readLocalConfig = (root) => {
|
|
18
|
+
const path = (0, path_1.join)(root, exports.LOCAL_CONFIG_FILE_NAME);
|
|
19
|
+
if (!(0, fs_1.existsSync)(path))
|
|
20
|
+
return { exists: false };
|
|
21
|
+
let parsed;
|
|
22
|
+
try {
|
|
23
|
+
parsed = JSON.parse((0, fs_1.readFileSync)(path, 'utf8'));
|
|
24
|
+
}
|
|
25
|
+
catch (_a) {
|
|
26
|
+
return { exists: true, valid: false };
|
|
27
|
+
}
|
|
28
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
|
|
29
|
+
return { exists: true, valid: false };
|
|
30
|
+
const config = parsed;
|
|
31
|
+
const unknownKeys = Object.keys(config).filter((key) => !LOCAL_CONFIG_KEYS.includes(key));
|
|
32
|
+
return { exists: true, valid: true, config, unknownKeys };
|
|
33
|
+
};
|
|
34
|
+
exports.readLocalConfig = readLocalConfig;
|
|
15
35
|
/**
|
|
16
|
-
* Emit for the agents a repo already uses.
|
|
17
|
-
*
|
|
36
|
+
* Emit for the agents a repo already uses. `codex` is always included: `AGENTS.md` is the
|
|
37
|
+
* cross-tool standard that Cursor, Copilot and most other agents read as well, and gating it on
|
|
38
|
+
* an existing `AGENTS.md` would mean the file that triggers Codex output is the very file the
|
|
39
|
+
* sync is supposed to create.
|
|
18
40
|
*/
|
|
19
41
|
const detectTargets = (root) => {
|
|
20
|
-
const detected = [];
|
|
42
|
+
const detected = ['codex'];
|
|
21
43
|
if ((0, fs_1.existsSync)((0, path_1.join)(root, '.claude')))
|
|
22
44
|
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
45
|
if ((0, fs_1.existsSync)((0, path_1.join)(root, '.cursor')))
|
|
26
46
|
detected.push('cursor');
|
|
27
47
|
if ((0, fs_1.existsSync)((0, path_1.join)(root, '.github')))
|
|
28
48
|
detected.push('copilot');
|
|
29
|
-
return detected
|
|
49
|
+
return detected;
|
|
30
50
|
};
|
|
31
51
|
exports.detectTargets = detectTargets;
|
|
32
52
|
const assertKnownTargets = (targets) => {
|
|
@@ -36,7 +56,7 @@ const assertKnownTargets = (targets) => {
|
|
|
36
56
|
}
|
|
37
57
|
};
|
|
38
58
|
const loadConfig = (options) => {
|
|
39
|
-
var _a, _b, _c;
|
|
59
|
+
var _a, _b, _c, _d, _e;
|
|
40
60
|
const { root, targetOverride } = options;
|
|
41
61
|
const raw = readRawConfig(root);
|
|
42
62
|
const configured = raw.targets && raw.targets !== 'auto' ? raw.targets : undefined;
|
|
@@ -48,6 +68,8 @@ const loadConfig = (options) => {
|
|
|
48
68
|
scopes: raw.profile === 'sdk' ? ['both'] : ['consumer', 'both'],
|
|
49
69
|
vars: Object.assign(Object.assign({}, (0, load_content_1.loadDefaultVars)()), ((_b = raw.vars) !== null && _b !== void 0 ? _b : {})),
|
|
50
70
|
exclude: (_c = raw.exclude) !== null && _c !== void 0 ? _c : [],
|
|
71
|
+
claudeMdImportsAgentsMd: (_d = raw.claudeMdImportsAgentsMd) !== null && _d !== void 0 ? _d : false,
|
|
72
|
+
hooks: (_e = raw.hooks) !== null && _e !== void 0 ? _e : [],
|
|
51
73
|
};
|
|
52
74
|
};
|
|
53
75
|
exports.loadConfig = loadConfig;
|
package/src/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../libs/agent-rules/src/lib/config.ts"],"names":[],"mappings":";;;AAAA,2BAA8C;AAC9C,+BAA4B;AAE5B,iDAAiD;AAEpC,QAAA,aAAa,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAU,CAAC;AAIlE,QAAA,gBAAgB,GAAG,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../libs/agent-rules/src/lib/config.ts"],"names":[],"mappings":"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"}
|
package/src/lib/index.d.ts
CHANGED
package/src/lib/index.js
CHANGED
|
@@ -5,6 +5,7 @@ tslib_1.__exportStar(require("./config"), exports);
|
|
|
5
5
|
tslib_1.__exportStar(require("./filter"), exports);
|
|
6
6
|
tslib_1.__exportStar(require("./frontmatter"), exports);
|
|
7
7
|
tslib_1.__exportStar(require("./load-content"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./migrate"), exports);
|
|
8
9
|
tslib_1.__exportStar(require("./owned-paths"), exports);
|
|
9
10
|
tslib_1.__exportStar(require("./plan"), exports);
|
|
10
11
|
tslib_1.__exportStar(require("./render"), exports);
|
package/src/lib/index.js.map
CHANGED
|
@@ -1 +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"}
|
|
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,oDAA0B;AAC1B,wDAA8B;AAC9B,iDAAuB;AACvB,mDAAyB;AACzB,iDAAuB;AACvB,2DAAiC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.migrate = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const config_1 = require("./config");
|
|
7
|
+
const plan_1 = require("./plan");
|
|
8
|
+
const render_1 = require("./render");
|
|
9
|
+
const sync_1 = require("./sync");
|
|
10
|
+
const CLAUDE_MD = 'CLAUDE.md';
|
|
11
|
+
const AGENTS_MD = 'AGENTS.md';
|
|
12
|
+
const CLAUDE_SKILLS = '.claude/skills';
|
|
13
|
+
const AGENTS_SKILLS = '.agents/skills';
|
|
14
|
+
const log = (message) => console.log(` ${message}`);
|
|
15
|
+
/**
|
|
16
|
+
* `AGENTS.md` becomes the canonical instruction file: whatever `CLAUDE.md` held moves to the top
|
|
17
|
+
* of `AGENTS.md`, and `CLAUDE.md` shrinks to the `@AGENTS.md` import Claude Code documents for
|
|
18
|
+
* exactly this setup.
|
|
19
|
+
*/
|
|
20
|
+
const migrateClaudeMd = (options) => {
|
|
21
|
+
const { root, dryRun } = options;
|
|
22
|
+
const claudePath = (0, path_1.join)(root, CLAUDE_MD);
|
|
23
|
+
const agentsPath = (0, path_1.join)(root, AGENTS_MD);
|
|
24
|
+
if ((0, plan_1.claudeMdImportsAgentsMd)(root)) {
|
|
25
|
+
log(`keep ${CLAUDE_MD} — already imports ${AGENTS_MD}`);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (!(0, fs_1.existsSync)(claudePath)) {
|
|
29
|
+
log(`create ${CLAUDE_MD} — "@${AGENTS_MD}" import`);
|
|
30
|
+
if (!dryRun)
|
|
31
|
+
(0, fs_1.writeFileSync)(claudePath, `@${AGENTS_MD}\n`, 'utf8');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const claudeContent = (0, fs_1.readFileSync)(claudePath, 'utf8').trim();
|
|
35
|
+
const agentsContent = (0, fs_1.existsSync)(agentsPath) ? (0, fs_1.readFileSync)(agentsPath, 'utf8').trim() : '';
|
|
36
|
+
const merged = [claudeContent, agentsContent].filter((part) => part.length > 0).join('\n\n');
|
|
37
|
+
log(`move ${CLAUDE_MD} content into ${AGENTS_MD}`);
|
|
38
|
+
log(`write ${CLAUDE_MD} — "@${AGENTS_MD}" import`);
|
|
39
|
+
if (dryRun)
|
|
40
|
+
return;
|
|
41
|
+
(0, fs_1.writeFileSync)(agentsPath, `${merged}\n`, 'utf8');
|
|
42
|
+
(0, fs_1.writeFileSync)(claudePath, `@${AGENTS_MD}\n`, 'utf8');
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Hand-written skills move to the cross-tool `.agents/skills/` location; a symlink stays behind
|
|
46
|
+
* because Claude Code only scans `.claude/skills/` (and follows symlinks there). Generated
|
|
47
|
+
* `ethlete-` entries are left to `sync`, which owns them.
|
|
48
|
+
*/
|
|
49
|
+
const migrateSkills = (options) => {
|
|
50
|
+
const { root, dryRun } = options;
|
|
51
|
+
const claudeSkills = (0, path_1.join)(root, CLAUDE_SKILLS);
|
|
52
|
+
if (!(0, fs_1.existsSync)(claudeSkills))
|
|
53
|
+
return;
|
|
54
|
+
for (const entry of (0, fs_1.readdirSync)(claudeSkills)) {
|
|
55
|
+
const source = (0, path_1.join)(claudeSkills, entry);
|
|
56
|
+
if (entry.startsWith('ethlete-') || (0, fs_1.lstatSync)(source).isSymbolicLink() || !(0, fs_1.lstatSync)(source).isDirectory()) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const destination = (0, path_1.join)(root, AGENTS_SKILLS, entry);
|
|
60
|
+
if ((0, fs_1.existsSync)(destination)) {
|
|
61
|
+
log(`skip ${CLAUDE_SKILLS}/${entry} — ${AGENTS_SKILLS}/${entry} already exists`);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
log(`move ${CLAUDE_SKILLS}/${entry} → ${AGENTS_SKILLS}/${entry} (symlink stays behind)`);
|
|
65
|
+
if (dryRun)
|
|
66
|
+
continue;
|
|
67
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(destination), { recursive: true });
|
|
68
|
+
(0, fs_1.renameSync)(source, destination);
|
|
69
|
+
try {
|
|
70
|
+
(0, fs_1.symlinkSync)((0, path_1.relative)((0, path_1.dirname)(source), destination), source, 'dir');
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
(0, fs_1.renameSync)(destination, source);
|
|
74
|
+
log(`undo ${CLAUDE_SKILLS}/${entry} — creating the symlink failed (${error.message})`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const LAYOUT_NOTE = `## Agent file layout
|
|
79
|
+
|
|
80
|
+
\`AGENTS.md\` is canonical; \`CLAUDE.md\` is just an \`@AGENTS.md\` import. Skills live in
|
|
81
|
+
\`.agents/skills/<name>/\`; the entries in \`.claude/skills/\` are symlinks to them (Claude Code
|
|
82
|
+
only scans there) - same file, not a duplicate. Edit and create skills under \`.agents/skills/\`,
|
|
83
|
+
plus a symlink for new ones. \`ethlete-*\` skills and the marker block in this file are generated
|
|
84
|
+
by \`npx ethlete-agents sync\` - never edit them by hand.`;
|
|
85
|
+
const withoutMarkedBlock = (content) => {
|
|
86
|
+
const start = content.indexOf(render_1.START_MARKER);
|
|
87
|
+
const end = content.indexOf(render_1.END_MARKER);
|
|
88
|
+
if (start === -1 || end === -1 || end < start)
|
|
89
|
+
return content;
|
|
90
|
+
return content.slice(0, start) + content.slice(end + render_1.END_MARKER.length);
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Without this note an agent that lists both skill directories reads the symlinked entries as
|
|
94
|
+
* duplicated files. Skipped when the repo's own `AGENTS.md` prose already explains the layout.
|
|
95
|
+
*/
|
|
96
|
+
const addLayoutNote = (options) => {
|
|
97
|
+
const { root, dryRun } = options;
|
|
98
|
+
const path = (0, path_1.join)(root, AGENTS_MD);
|
|
99
|
+
const existing = (0, fs_1.existsSync)(path) ? (0, fs_1.readFileSync)(path, 'utf8') : '';
|
|
100
|
+
if (withoutMarkedBlock(existing).includes(AGENTS_SKILLS)) {
|
|
101
|
+
log(`keep ${AGENTS_MD} — already documents the ${AGENTS_SKILLS} layout`);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
log(`write ${AGENTS_MD} — add the agent file layout note`);
|
|
105
|
+
if (dryRun)
|
|
106
|
+
return;
|
|
107
|
+
const start = existing.indexOf(render_1.START_MARKER);
|
|
108
|
+
const contents = start === -1
|
|
109
|
+
? `${[existing.trimEnd(), LAYOUT_NOTE].filter((part) => part.length > 0).join('\n\n')}\n`
|
|
110
|
+
: `${existing.slice(0, start).trimEnd()}\n\n${LAYOUT_NOTE}\n\n${existing.slice(start)}`;
|
|
111
|
+
(0, fs_1.writeFileSync)(path, contents, 'utf8');
|
|
112
|
+
};
|
|
113
|
+
const migrateConfig = (options) => {
|
|
114
|
+
const { root, dryRun } = options;
|
|
115
|
+
const path = (0, path_1.join)(root, config_1.CONFIG_FILE_NAME);
|
|
116
|
+
const raw = (0, fs_1.existsSync)(path)
|
|
117
|
+
? JSON.parse((0, fs_1.readFileSync)(path, 'utf8'))
|
|
118
|
+
: { targets: 'auto', vars: {}, exclude: [] };
|
|
119
|
+
const targets = raw['targets'];
|
|
120
|
+
const explicit = Array.isArray(targets) ? targets : undefined;
|
|
121
|
+
const missingCodex = explicit !== undefined && !explicit.includes('codex');
|
|
122
|
+
const missingFlag = raw['claudeMdImportsAgentsMd'] !== true;
|
|
123
|
+
if (!missingCodex && !missingFlag) {
|
|
124
|
+
log(`keep ${config_1.CONFIG_FILE_NAME} — already migrated`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (missingCodex && explicit)
|
|
128
|
+
raw['targets'] = [...explicit, 'codex'];
|
|
129
|
+
raw['claudeMdImportsAgentsMd'] = true;
|
|
130
|
+
log(`write ${config_1.CONFIG_FILE_NAME} — codex target + claudeMdImportsAgentsMd`);
|
|
131
|
+
if (!dryRun)
|
|
132
|
+
(0, fs_1.writeFileSync)(path, `${JSON.stringify(raw, null, 2)}\n`, 'utf8');
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Converts a repo to the `AGENTS.md`-canonical layout and re-syncs. Safe to re-run: every step
|
|
136
|
+
* detects the migrated state and skips itself.
|
|
137
|
+
*/
|
|
138
|
+
const migrate = (options) => {
|
|
139
|
+
const { root, dryRun = false } = options;
|
|
140
|
+
console.log(dryRun ? 'Migration plan (dry run):' : 'Migrating to the AGENTS.md + .agents/skills layout:');
|
|
141
|
+
migrateClaudeMd({ root, dryRun });
|
|
142
|
+
migrateSkills({ root, dryRun });
|
|
143
|
+
addLayoutNote({ root, dryRun });
|
|
144
|
+
migrateConfig({ root, dryRun });
|
|
145
|
+
if (dryRun) {
|
|
146
|
+
console.log('\nRe-run without --dry-run to apply, then a sync runs automatically.');
|
|
147
|
+
return 0;
|
|
148
|
+
}
|
|
149
|
+
console.log('\nRunning sync:');
|
|
150
|
+
const result = (0, sync_1.sync)(options);
|
|
151
|
+
console.log('\nDone. Commit the result. Note: the .claude/skills symlinks need symlink support on checkout (Windows: Developer Mode).');
|
|
152
|
+
return result;
|
|
153
|
+
};
|
|
154
|
+
exports.migrate = migrate;
|
|
155
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../../../../libs/agent-rules/src/lib/migrate.ts"],"names":[],"mappings":"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"}
|
package/src/lib/owned-paths.js
CHANGED
|
@@ -3,8 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.collectOwnedPaths = void 0;
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
5
|
const path_1 = require("path");
|
|
6
|
-
|
|
6
|
+
// `.agents/ethlete` and `.github/instructions/ethlete-*` are no longer emitted, but stay owned so
|
|
7
|
+
// a sync prunes them from repos generated by older versions.
|
|
8
|
+
const OWNED_DIRECTORIES = ['.agents/ethlete', '.claude/rules/ethlete', '.claude/hooks/ethlete'];
|
|
7
9
|
const OWNED_PARENTS = [
|
|
10
|
+
{ dir: '.agents/skills', match: (entry) => entry.startsWith('ethlete-') },
|
|
8
11
|
{ dir: '.claude/skills', match: (entry) => entry.startsWith('ethlete-') },
|
|
9
12
|
{ dir: '.cursor/rules', match: (entry) => entry.startsWith('ethlete-') && entry.endsWith('.mdc') },
|
|
10
13
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"owned-paths.js","sourceRoot":"","sources":["../../../../../libs/agent-rules/src/lib/owned-paths.ts"],"names":[],"mappings":";;;AAAA,2BAAuD;AACvD,+BAA2C;AAE3C,MAAM,iBAAiB,GAAG,CAAC,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"owned-paths.js","sourceRoot":"","sources":["../../../../../libs/agent-rules/src/lib/owned-paths.ts"],"names":[],"mappings":";;;AAAA,2BAAuD;AACvD,+BAA2C;AAE3C,kGAAkG;AAClG,6DAA6D;AAC7D,MAAM,iBAAiB,GAAG,CAAC,iBAAiB,EAAE,uBAAuB,EAAE,uBAAuB,CAAC,CAAC;AAChG,MAAM,aAAa,GAAG;IACpB,EAAE,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;IACjF,EAAE,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;IACjF,EAAE,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;IAC1G;QACE,GAAG,EAAE,sBAAsB;QAC3B,KAAK,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC;KAC7F;CACF,CAAC;AAEF,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,WAAmB,EAAY,EAAE;IAC3D,IAAI,CAAC,IAAA,eAAU,EAAC,WAAW,CAAC;QAAE,OAAO,EAAE,CAAC;IAExC,OAAO,IAAA,gBAAW,EAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QAChD,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAE1C,IAAI,IAAA,aAAQ,EAAC,QAAQ,CAAC,CAAC,WAAW,EAAE;YAAE,OAAO,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAElE,OAAO,CAAC,IAAA,eAAQ,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,UAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;;;GAKG;AACI,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,EAAE;IAChD,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAA,WAAI,EAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAE9E,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,cAAc,GAAG,IAAA,WAAI,EAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QAE9C,IAAI,CAAC,IAAA,eAAU,EAAC,cAAc,CAAC;YAAE,SAAS;QAE1C,KAAK,MAAM,KAAK,IAAI,IAAA,gBAAW,EAAC,cAAc,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;gBAAE,SAAS;YAEnC,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,cAAc,EAAE,KAAK,CAAC,CAAC;YAE7C,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAA,aAAQ,EAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QACxG,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAlBW,QAAA,iBAAiB,qBAkB5B"}
|
package/src/lib/plan.d.ts
CHANGED
|
@@ -9,7 +9,11 @@ export type SyncPlan = {
|
|
|
9
9
|
from: string;
|
|
10
10
|
to: string;
|
|
11
11
|
}[];
|
|
12
|
+
/** Config/repo mismatches that won't fail the run but will silently lose content if ignored. */
|
|
13
|
+
warnings: string[];
|
|
12
14
|
};
|
|
15
|
+
/** `@AGENTS.md` on its own line (the documented import syntax), or a symlink pointing at it. */
|
|
16
|
+
export declare const claudeMdImportsAgentsMd: (root: string) => boolean;
|
|
13
17
|
/**
|
|
14
18
|
* Resolves the full set of files a sync would write, without touching disk — `sync` writes the
|
|
15
19
|
* result and `check` diffs it.
|
package/src/lib/plan.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildPlan = void 0;
|
|
3
|
+
exports.buildPlan = exports.claudeMdImportsAgentsMd = void 0;
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
5
|
const path_1 = require("path");
|
|
6
|
+
const config_1 = require("./config");
|
|
6
7
|
const filter_1 = require("./filter");
|
|
7
8
|
const load_content_1 = require("./load-content");
|
|
9
|
+
const agents_skills_1 = require("./targets/agents-skills");
|
|
10
|
+
const claude_hooks_1 = require("./targets/claude-hooks");
|
|
8
11
|
const claude_1 = require("./targets/claude");
|
|
9
12
|
const codex_1 = require("./targets/codex");
|
|
10
13
|
const copilot_1 = require("./targets/copilot");
|
|
11
14
|
const cursor_1 = require("./targets/cursor");
|
|
12
|
-
const neutral_1 = require("./targets/neutral");
|
|
13
15
|
const SKILL_LINK_PATTERN = /\{%\s*skill:([a-zA-Z0-9_.-]+)\s*%\}/g;
|
|
14
16
|
const findDanglingLinks = (items, emittedSkills) => items.flatMap((item) => [...item.body.matchAll(SKILL_LINK_PATTERN)]
|
|
15
17
|
.map((match) => match[1])
|
|
@@ -19,12 +21,83 @@ const readExisting = (root, relativePath) => {
|
|
|
19
21
|
const path = (0, path_1.join)(root, relativePath);
|
|
20
22
|
return (0, fs_1.existsSync)(path) ? (0, fs_1.readFileSync)(path, 'utf8') : '';
|
|
21
23
|
};
|
|
24
|
+
/** `@AGENTS.md` on its own line (the documented import syntax), or a symlink pointing at it. */
|
|
25
|
+
const claudeMdImportsAgentsMd = (root) => {
|
|
26
|
+
const path = (0, path_1.join)(root, 'CLAUDE.md');
|
|
27
|
+
if (!(0, fs_1.existsSync)(path))
|
|
28
|
+
return false;
|
|
29
|
+
if ((0, fs_1.lstatSync)(path).isSymbolicLink())
|
|
30
|
+
return (0, fs_1.readlinkSync)(path).endsWith('AGENTS.md');
|
|
31
|
+
return /^@AGENTS\.md\s*$/m.test((0, fs_1.readFileSync)(path, 'utf8'));
|
|
32
|
+
};
|
|
33
|
+
exports.claudeMdImportsAgentsMd = claudeMdImportsAgentsMd;
|
|
34
|
+
/** Marks a directory as an `ethlete-sdk` checkout rather than some other folder. */
|
|
35
|
+
const SDK_CHECKOUT_MARKERS = ['libs/components', 'libs/core', 'libs/agent-rules'];
|
|
36
|
+
const describeSdkSourcePath = (options) => {
|
|
37
|
+
const { root, value } = options;
|
|
38
|
+
if (value === undefined)
|
|
39
|
+
return [];
|
|
40
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
41
|
+
return [`${config_1.LOCAL_CONFIG_FILE_NAME} has an invalid "sdkSourcePath" — use a path to an ethlete-sdk checkout.`];
|
|
42
|
+
}
|
|
43
|
+
const absolute = (0, path_1.resolve)(root, value);
|
|
44
|
+
if (!(0, fs_1.existsSync)(absolute)) {
|
|
45
|
+
return [`${config_1.LOCAL_CONFIG_FILE_NAME} points "sdkSourcePath" at ${absolute}, which does not exist.`];
|
|
46
|
+
}
|
|
47
|
+
if (SDK_CHECKOUT_MARKERS.some((marker) => !(0, fs_1.existsSync)((0, path_1.join)(absolute, marker)))) {
|
|
48
|
+
return [`${config_1.LOCAL_CONFIG_FILE_NAME} points "sdkSourcePath" at ${absolute}, which is not an ethlete-sdk checkout.`];
|
|
49
|
+
}
|
|
50
|
+
return [];
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* The local file only affects runtime behavior, never sync output — so the warnings here are about
|
|
54
|
+
* the mistakes that would otherwise fail silently: a file the hooks can't parse, a key that
|
|
55
|
+
* suggests someone expected sync-time overrides, a hook name nothing matches, or an SDK path that
|
|
56
|
+
* no longer exists (the skills reading it would just report the checkout as missing).
|
|
57
|
+
*/
|
|
58
|
+
const collectLocalConfigWarnings = (root) => {
|
|
59
|
+
const local = (0, config_1.readLocalConfig)(root);
|
|
60
|
+
if (!local.exists)
|
|
61
|
+
return [];
|
|
62
|
+
if (!local.valid) {
|
|
63
|
+
return [`${config_1.LOCAL_CONFIG_FILE_NAME} is not a JSON object — hooks ignore it and stay enabled.`];
|
|
64
|
+
}
|
|
65
|
+
const warnings = [];
|
|
66
|
+
if (local.unknownKeys.length > 0) {
|
|
67
|
+
warnings.push(`${config_1.LOCAL_CONFIG_FILE_NAME} contains unsupported key(s): ${local.unknownKeys.join(', ')} — the local file supports "disableHooks" and "sdkSourcePath"; it never changes what sync writes.`);
|
|
68
|
+
}
|
|
69
|
+
warnings.push(...describeSdkSourcePath({ root, value: local.config.sdkSourcePath }));
|
|
70
|
+
const disable = local.config.disableHooks;
|
|
71
|
+
if (disable !== undefined && typeof disable !== 'boolean' && !Array.isArray(disable)) {
|
|
72
|
+
warnings.push(`${config_1.LOCAL_CONFIG_FILE_NAME} has an invalid "disableHooks" value — use true or an array of hook names; hooks stay enabled.`);
|
|
73
|
+
}
|
|
74
|
+
if (Array.isArray(disable)) {
|
|
75
|
+
const unknown = disable.filter((name) => !(name in claude_hooks_1.CLAUDE_HOOKS));
|
|
76
|
+
if (unknown.length > 0) {
|
|
77
|
+
warnings.push(`${config_1.LOCAL_CONFIG_FILE_NAME} disables unknown hook(s): ${unknown.join(', ')}. Known hooks: ${Object.keys(claude_hooks_1.CLAUDE_HOOKS).join(', ')}.`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return warnings;
|
|
81
|
+
};
|
|
82
|
+
const collectWarnings = (config) => {
|
|
83
|
+
const warnings = collectLocalConfigWarnings(config.root);
|
|
84
|
+
if (!config.claudeMdImportsAgentsMd)
|
|
85
|
+
return warnings;
|
|
86
|
+
if (!config.targets.includes('codex')) {
|
|
87
|
+
warnings.push('claudeMdImportsAgentsMd is set but the codex target is off — no AGENTS.md is generated, so Claude gets no rules at all.');
|
|
88
|
+
}
|
|
89
|
+
if (!(0, exports.claudeMdImportsAgentsMd)(config.root)) {
|
|
90
|
+
warnings.push('claudeMdImportsAgentsMd is set but CLAUDE.md does not import AGENTS.md — add a line containing exactly "@AGENTS.md" (or symlink CLAUDE.md to AGENTS.md), or Claude gets no rules at all.');
|
|
91
|
+
}
|
|
92
|
+
return warnings;
|
|
93
|
+
};
|
|
22
94
|
/**
|
|
23
95
|
* Resolves the full set of files a sync would write, without touching disk — `sync` writes the
|
|
24
96
|
* result and `check` diffs it.
|
|
25
97
|
*/
|
|
26
98
|
const buildPlan = (options) => {
|
|
27
99
|
const { config, version } = options;
|
|
100
|
+
(0, claude_hooks_1.assertKnownHooks)(config.hooks);
|
|
28
101
|
const { kept, skipped } = (0, filter_1.filterContent)((0, load_content_1.loadContent)(), config);
|
|
29
102
|
const skills = kept.filter((item) => item.frontmatter.kind === 'skill');
|
|
30
103
|
const emittedSkills = new Set(skills.map((item) => item.frontmatter.name));
|
|
@@ -34,12 +107,13 @@ const buildPlan = (options) => {
|
|
|
34
107
|
emittedSkills,
|
|
35
108
|
vars: config.vars,
|
|
36
109
|
version,
|
|
110
|
+
claudeMdImportsAgentsMd: config.claudeMdImportsAgentsMd,
|
|
111
|
+
hooks: config.hooks,
|
|
37
112
|
};
|
|
38
113
|
const files = [];
|
|
39
|
-
// Codex, Cursor and Copilot all
|
|
40
|
-
// mechanism, whole skills) out of the neutral tree.
|
|
114
|
+
// Codex, Cursor and Copilot all discover skills from the shared `.agents/skills/` tree.
|
|
41
115
|
if (config.targets.some((target) => target !== 'claude')) {
|
|
42
|
-
files.push(...(0,
|
|
116
|
+
files.push(...(0, agents_skills_1.emitAgentsSkills)(context));
|
|
43
117
|
}
|
|
44
118
|
if (config.targets.includes('claude'))
|
|
45
119
|
files.push(...(0, claude_1.emitClaude)(context));
|
|
@@ -51,7 +125,12 @@ const buildPlan = (options) => {
|
|
|
51
125
|
if (config.targets.includes('copilot')) {
|
|
52
126
|
files.push(...(0, copilot_1.emitCopilot)({ context, existing: readExisting(config.root, copilot_1.COPILOT_FILE) }));
|
|
53
127
|
}
|
|
54
|
-
|
|
128
|
+
files.push(...(0, claude_hooks_1.emitClaudeHooks)({
|
|
129
|
+
context,
|
|
130
|
+
claudeTarget: config.targets.includes('claude'),
|
|
131
|
+
existingSettings: readExisting(config.root, claude_hooks_1.CLAUDE_SETTINGS_FILE),
|
|
132
|
+
}));
|
|
133
|
+
return { files, skipped, danglingLinks: findDanglingLinks(kept, emittedSkills), warnings: collectWarnings(config) };
|
|
55
134
|
};
|
|
56
135
|
exports.buildPlan = buildPlan;
|
|
57
136
|
//# sourceMappingURL=plan.js.map
|
package/src/lib/plan.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../../../libs/agent-rules/src/lib/plan.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../../../libs/agent-rules/src/lib/plan.ts"],"names":[],"mappings":"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"}
|
package/src/lib/sync.js
CHANGED
|
@@ -39,9 +39,12 @@ const describe = (change) => {
|
|
|
39
39
|
};
|
|
40
40
|
const sync = (options) => {
|
|
41
41
|
const config = (0, config_1.loadConfig)({ root: options.root, targetOverride: options.targets });
|
|
42
|
-
const { files, skipped, danglingLinks } = (0, plan_1.buildPlan)({ config, version: options.version });
|
|
42
|
+
const { files, skipped, danglingLinks, warnings } = (0, plan_1.buildPlan)({ config, version: options.version });
|
|
43
43
|
const changes = diffPlan({ root: options.root, files, owned: (0, owned_paths_1.collectOwnedPaths)(options.root) });
|
|
44
44
|
console.log(`Targets: ${config.targets.join(', ')}`);
|
|
45
|
+
for (const warning of warnings) {
|
|
46
|
+
console.warn(` warn ${warning}`);
|
|
47
|
+
}
|
|
45
48
|
for (const entry of skipped) {
|
|
46
49
|
console.log(` skip ${entry.name} — ${entry.reason}`);
|
|
47
50
|
}
|
|
@@ -75,8 +78,11 @@ const sync = (options) => {
|
|
|
75
78
|
exports.sync = sync;
|
|
76
79
|
const check = (options) => {
|
|
77
80
|
const config = (0, config_1.loadConfig)({ root: options.root, targetOverride: options.targets });
|
|
78
|
-
const { files } = (0, plan_1.buildPlan)({ config, version: options.version });
|
|
81
|
+
const { files, warnings } = (0, plan_1.buildPlan)({ config, version: options.version });
|
|
79
82
|
const changes = diffPlan({ root: options.root, files, owned: (0, owned_paths_1.collectOwnedPaths)(options.root) });
|
|
83
|
+
for (const warning of warnings) {
|
|
84
|
+
console.warn(` warn ${warning}`);
|
|
85
|
+
}
|
|
80
86
|
if (changes.length === 0) {
|
|
81
87
|
console.log('Agent rules are in sync.');
|
|
82
88
|
return 0;
|