@mossbear/projections 0.1.0-alpha.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +7 -0
- package/dist/agents-dir.d.ts +13 -0
- package/dist/agents-dir.d.ts.map +1 -0
- package/dist/agents-dir.js +36 -0
- package/dist/agents-dir.js.map +1 -0
- package/dist/agents-dir.test.d.ts +2 -0
- package/dist/agents-dir.test.d.ts.map +1 -0
- package/dist/agents-dir.test.js +30 -0
- package/dist/agents-dir.test.js.map +1 -0
- package/dist/agents-md.d.ts +12 -0
- package/dist/agents-md.d.ts.map +1 -0
- package/dist/agents-md.js +47 -0
- package/dist/agents-md.js.map +1 -0
- package/dist/agents-md.test.d.ts +2 -0
- package/dist/agents-md.test.d.ts.map +1 -0
- package/dist/agents-md.test.js +44 -0
- package/dist/agents-md.test.js.map +1 -0
- package/dist/claude-md.d.ts +17 -0
- package/dist/claude-md.d.ts.map +1 -0
- package/dist/claude-md.js +43 -0
- package/dist/claude-md.js.map +1 -0
- package/dist/claude-md.test.d.ts +2 -0
- package/dist/claude-md.test.d.ts.map +1 -0
- package/dist/claude-md.test.js +61 -0
- package/dist/claude-md.test.js.map +1 -0
- package/dist/claude-rules.d.ts +17 -0
- package/dist/claude-rules.d.ts.map +1 -0
- package/dist/claude-rules.js +43 -0
- package/dist/claude-rules.js.map +1 -0
- package/dist/claude-rules.test.d.ts +2 -0
- package/dist/claude-rules.test.d.ts.map +1 -0
- package/dist/claude-rules.test.js +34 -0
- package/dist/claude-rules.test.js.map +1 -0
- package/dist/compatibility-attribution.d.ts +7 -0
- package/dist/compatibility-attribution.d.ts.map +1 -0
- package/dist/compatibility-attribution.js +11 -0
- package/dist/compatibility-attribution.js.map +1 -0
- package/dist/cursor-rules.d.ts +17 -0
- package/dist/cursor-rules.d.ts.map +1 -0
- package/dist/cursor-rules.js +36 -0
- package/dist/cursor-rules.js.map +1 -0
- package/dist/cursor-rules.test.d.ts +2 -0
- package/dist/cursor-rules.test.d.ts.map +1 -0
- package/dist/cursor-rules.test.js +58 -0
- package/dist/cursor-rules.test.js.map +1 -0
- package/dist/detect-format.d.ts +15 -0
- package/dist/detect-format.d.ts.map +1 -0
- package/dist/detect-format.js +88 -0
- package/dist/detect-format.js.map +1 -0
- package/dist/detect-format.test.d.ts +2 -0
- package/dist/detect-format.test.d.ts.map +1 -0
- package/dist/detect-format.test.js +104 -0
- package/dist/detect-format.test.js.map +1 -0
- package/dist/eval-path.d.ts +91 -0
- package/dist/eval-path.d.ts.map +1 -0
- package/dist/eval-path.js +110 -0
- package/dist/eval-path.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/path-rules.d.ts +45 -0
- package/dist/path-rules.d.ts.map +1 -0
- package/dist/path-rules.js +65 -0
- package/dist/path-rules.js.map +1 -0
- package/dist/skill-member-path.d.ts +51 -0
- package/dist/skill-member-path.d.ts.map +1 -0
- package/dist/skill-member-path.js +76 -0
- package/dist/skill-member-path.js.map +1 -0
- package/dist/skill-member-path.test.d.ts +2 -0
- package/dist/skill-member-path.test.d.ts.map +1 -0
- package/dist/skill-member-path.test.js +0 -0
- package/dist/skill-member-path.test.js.map +1 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mossbear
|
|
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,7 @@
|
|
|
1
|
+
# @mossbear/projections
|
|
2
|
+
|
|
3
|
+
Guide-file format detection and compatibility renderers for [Mossbear](https://app.mossbear.io) — `detectFormat()` for `AGENTS.md`, `.agents/`, `CLAUDE.md`, `.claude/rules/`, `.cursorrules`, and `.cursor/rules/*.mdc`, plus exporters that render Mossbear guides into those formats. Used by the [`mossbear` CLI](https://www.npmjs.com/package/mossbear).
|
|
4
|
+
|
|
5
|
+
You normally don't install this directly; it ships as a dependency of `mossbear`.
|
|
6
|
+
|
|
7
|
+
Source: https://github.com/auden-to/auden (`packages/projections`)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projection: .agents/ directory
|
|
3
|
+
*
|
|
4
|
+
* Generates per-agent files for the .agents/ directory.
|
|
5
|
+
* Pure function – no I/O.
|
|
6
|
+
*/
|
|
7
|
+
import type { AgentConfig } from '@mossbear/protocol';
|
|
8
|
+
/**
|
|
9
|
+
* Returns a map of { filename: content } for the .agents/ directory.
|
|
10
|
+
* Each agent gets its own YAML-like descriptor file.
|
|
11
|
+
*/
|
|
12
|
+
export declare function renderAgentsDir(agents: AgentConfig[]): Record<string, string>;
|
|
13
|
+
//# sourceMappingURL=agents-dir.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-dir.d.ts","sourceRoot":"","sources":["../src/agents-dir.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA0B7E"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projection: .agents/ directory
|
|
3
|
+
*
|
|
4
|
+
* Generates per-agent files for the .agents/ directory.
|
|
5
|
+
* Pure function – no I/O.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Returns a map of { filename: content } for the .agents/ directory.
|
|
9
|
+
* Each agent gets its own YAML-like descriptor file.
|
|
10
|
+
*/
|
|
11
|
+
export function renderAgentsDir(agents) {
|
|
12
|
+
const files = {};
|
|
13
|
+
for (const agent of agents) {
|
|
14
|
+
const filename = `${agent.id}.md`;
|
|
15
|
+
const lines = [
|
|
16
|
+
`# ${agent.name}`,
|
|
17
|
+
'',
|
|
18
|
+
`id: ${agent.id}`,
|
|
19
|
+
`description: ${agent.description || '(none)'}`,
|
|
20
|
+
`capabilities:`,
|
|
21
|
+
];
|
|
22
|
+
for (const cap of agent.capabilities) {
|
|
23
|
+
lines.push(` - ${cap}`);
|
|
24
|
+
}
|
|
25
|
+
if (agent.meta) {
|
|
26
|
+
lines.push('');
|
|
27
|
+
lines.push('meta:');
|
|
28
|
+
lines.push('```json');
|
|
29
|
+
lines.push(JSON.stringify(agent.meta, null, 2));
|
|
30
|
+
lines.push('```');
|
|
31
|
+
}
|
|
32
|
+
files[filename] = lines.join('\n');
|
|
33
|
+
}
|
|
34
|
+
return files;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=agents-dir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-dir.js","sourceRoot":"","sources":["../src/agents-dir.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAqB;IACnD,MAAM,KAAK,GAA2B,EAAE,CAAA;IAExC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,EAAE,KAAK,CAAA;QACjC,MAAM,KAAK,GAAa;YACtB,KAAK,KAAK,CAAC,IAAI,EAAE;YACjB,EAAE;YACF,OAAO,KAAK,CAAC,EAAE,EAAE;YACjB,gBAAgB,KAAK,CAAC,WAAW,IAAI,QAAQ,EAAE;YAC/C,eAAe;SAChB,CAAA;QACD,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,CAAA;QAC1B,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACd,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACnB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YACrB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YAC/C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACnB,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACpC,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-dir.test.d.ts","sourceRoot":"","sources":["../src/agents-dir.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { renderAgentsDir } from './agents-dir.js';
|
|
3
|
+
const sampleAgents = [
|
|
4
|
+
{
|
|
5
|
+
id: 'agent-alpha',
|
|
6
|
+
name: 'Alpha',
|
|
7
|
+
description: 'First agent',
|
|
8
|
+
capabilities: ['read'],
|
|
9
|
+
},
|
|
10
|
+
];
|
|
11
|
+
describe('renderAgentsDir', () => {
|
|
12
|
+
it('creates a file per agent', () => {
|
|
13
|
+
const files = renderAgentsDir(sampleAgents);
|
|
14
|
+
expect(Object.keys(files)).toContain('agent-alpha.md');
|
|
15
|
+
});
|
|
16
|
+
it('file content contains id and capabilities', () => {
|
|
17
|
+
const files = renderAgentsDir(sampleAgents);
|
|
18
|
+
const content = files['agent-alpha.md'] ?? '';
|
|
19
|
+
expect(content).toContain('agent-alpha');
|
|
20
|
+
expect(content).toContain('- read');
|
|
21
|
+
});
|
|
22
|
+
it('returns empty object for empty input', () => {
|
|
23
|
+
expect(renderAgentsDir([])).toEqual({});
|
|
24
|
+
});
|
|
25
|
+
it('does not add compatibility attribution to canonical outputs', () => {
|
|
26
|
+
const files = renderAgentsDir(sampleAgents);
|
|
27
|
+
expect(files['agent-alpha.md']).not.toContain('Guides managed by Mossbear');
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=agents-dir.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-dir.test.js","sourceRoot":"","sources":["../src/agents-dir.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAIjD,MAAM,YAAY,GAAkB;IAClC;QACE,EAAE,EAAE,aAAa;QACjB,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,aAAa;QAC1B,YAAY,EAAE,CAAC,MAAM,CAAC;KACvB;CACF,CAAA;AAED,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,KAAK,GAAG,eAAe,CAAC,YAAY,CAAC,CAAA;QAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,KAAK,GAAG,eAAe,CAAC,YAAY,CAAC,CAAA;QAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAA;QAC7C,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAA;QACxC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,KAAK,GAAG,eAAe,CAAC,YAAY,CAAC,CAAA;QAC3C,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projection: AGENTS.md
|
|
3
|
+
*
|
|
4
|
+
* Generates the canonical AGENTS.md file content from an array of AgentConfig.
|
|
5
|
+
* Pure function – no I/O.
|
|
6
|
+
*/
|
|
7
|
+
import type { AgentConfig } from '@mossbear/protocol';
|
|
8
|
+
/**
|
|
9
|
+
* Render the AGENTS.md content for the given agents.
|
|
10
|
+
*/
|
|
11
|
+
export declare function renderAgentsMd(agents: AgentConfig[]): string;
|
|
12
|
+
//# sourceMappingURL=agents-md.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-md.d.ts","sourceRoot":"","sources":["../src/agents-md.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAsC5D"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projection: AGENTS.md
|
|
3
|
+
*
|
|
4
|
+
* Generates the canonical AGENTS.md file content from an array of AgentConfig.
|
|
5
|
+
* Pure function – no I/O.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Render the AGENTS.md content for the given agents.
|
|
9
|
+
*/
|
|
10
|
+
export function renderAgentsMd(agents) {
|
|
11
|
+
const lines = [
|
|
12
|
+
'# Agents',
|
|
13
|
+
'',
|
|
14
|
+
'> Auto-generated by mossbear. Do not edit manually.',
|
|
15
|
+
'',
|
|
16
|
+
];
|
|
17
|
+
for (const agent of agents) {
|
|
18
|
+
lines.push(`## ${agent.name}`);
|
|
19
|
+
lines.push('');
|
|
20
|
+
lines.push(`**ID:** \`${agent.id}\``);
|
|
21
|
+
lines.push('');
|
|
22
|
+
if (agent.description) {
|
|
23
|
+
lines.push(agent.description);
|
|
24
|
+
lines.push('');
|
|
25
|
+
}
|
|
26
|
+
if (agent.capabilities.length > 0) {
|
|
27
|
+
lines.push('**Capabilities:**');
|
|
28
|
+
lines.push('');
|
|
29
|
+
for (const cap of agent.capabilities) {
|
|
30
|
+
lines.push(`- ${cap}`);
|
|
31
|
+
}
|
|
32
|
+
lines.push('');
|
|
33
|
+
}
|
|
34
|
+
if (agent.meta && Object.keys(agent.meta).length > 0) {
|
|
35
|
+
lines.push('**Meta:**');
|
|
36
|
+
lines.push('');
|
|
37
|
+
lines.push('```json');
|
|
38
|
+
lines.push(JSON.stringify(agent.meta, null, 2));
|
|
39
|
+
lines.push('```');
|
|
40
|
+
lines.push('');
|
|
41
|
+
}
|
|
42
|
+
lines.push('---');
|
|
43
|
+
lines.push('');
|
|
44
|
+
}
|
|
45
|
+
return lines.join('\n');
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=agents-md.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../src/agents-md.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAqB;IAClD,MAAM,KAAK,GAAa;QACtB,UAAU;QACV,EAAE;QACF,qDAAqD;QACrD,EAAE;KACH,CAAA;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,EAAE,IAAI,CAAC,CAAA;QACrC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAChB,CAAC;QACD,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;YAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACd,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;gBACrC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,CAAA;YACxB,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAChB,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YACvB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACd,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YACrB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YAC/C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACjB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAChB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACjB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAChB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-md.test.d.ts","sourceRoot":"","sources":["../src/agents-md.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { renderAgentsMd } from './agents-md.js';
|
|
3
|
+
const sampleAgents = [
|
|
4
|
+
{
|
|
5
|
+
id: 'agent-alpha',
|
|
6
|
+
name: 'Alpha',
|
|
7
|
+
description: 'The first agent',
|
|
8
|
+
capabilities: ['read', 'write'],
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
id: 'agent-beta',
|
|
12
|
+
name: 'Beta',
|
|
13
|
+
description: 'The second agent',
|
|
14
|
+
capabilities: [],
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
describe('renderAgentsMd', () => {
|
|
18
|
+
it('includes a header and agent entries', () => {
|
|
19
|
+
const md = renderAgentsMd(sampleAgents);
|
|
20
|
+
expect(md).toContain('# Agents');
|
|
21
|
+
expect(md).toContain('## Alpha');
|
|
22
|
+
expect(md).toContain('## Beta');
|
|
23
|
+
expect(md).toContain('`agent-alpha`');
|
|
24
|
+
});
|
|
25
|
+
it('lists capabilities', () => {
|
|
26
|
+
const md = renderAgentsMd(sampleAgents);
|
|
27
|
+
expect(md).toContain('- read');
|
|
28
|
+
expect(md).toContain('- write');
|
|
29
|
+
});
|
|
30
|
+
it('handles an empty agents array', () => {
|
|
31
|
+
const md = renderAgentsMd([]);
|
|
32
|
+
expect(md).toContain('# Agents');
|
|
33
|
+
expect(md).not.toContain('## ');
|
|
34
|
+
});
|
|
35
|
+
it('includes separator between agents', () => {
|
|
36
|
+
const md = renderAgentsMd(sampleAgents);
|
|
37
|
+
expect(md).toContain('---');
|
|
38
|
+
});
|
|
39
|
+
it('does not add compatibility attribution to canonical outputs', () => {
|
|
40
|
+
const md = renderAgentsMd(sampleAgents);
|
|
41
|
+
expect(md).not.toContain('Guides managed by Mossbear');
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=agents-md.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-md.test.js","sourceRoot":"","sources":["../src/agents-md.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAI/C,MAAM,YAAY,GAAkB;IAClC;QACE,EAAE,EAAE,aAAa;QACjB,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,iBAAiB;QAC9B,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;KAChC;IACD;QACE,EAAE,EAAE,YAAY;QAChB,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,kBAAkB;QAC/B,YAAY,EAAE,EAAE;KACjB;CACF,CAAA;AAED,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,EAAE,GAAG,cAAc,CAAC,YAAY,CAAC,CAAA;QACvC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;QAChC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;QAChC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;QAC/B,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAC5B,MAAM,EAAE,GAAG,cAAc,CAAC,YAAY,CAAC,CAAA;QACvC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QAC9B,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;IACjC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,EAAE,GAAG,cAAc,CAAC,EAAE,CAAC,CAAA;QAC7B,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;QAChC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IACjC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,EAAE,GAAG,cAAc,CAAC,YAAY,CAAC,CAAA;QACvC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,EAAE,GAAG,cAAc,CAAC,YAAY,CAAC,CAAA;QACvC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compatibility exporter: CLAUDE.md
|
|
3
|
+
*
|
|
4
|
+
* Emits a CLAUDE.md-format file from an array of AgentConfig.
|
|
5
|
+
* Pure function – no I/O.
|
|
6
|
+
*
|
|
7
|
+
* This is a compatibility output, not the canonical projection target.
|
|
8
|
+
* Canonical outputs are AGENTS.md and .agents/ (see agents-md.ts, agents-dir.ts).
|
|
9
|
+
*/
|
|
10
|
+
import type { CompatibilityRendererOptions } from './compatibility-attribution.js';
|
|
11
|
+
import type { AgentConfig } from '@mossbear/protocol';
|
|
12
|
+
/**
|
|
13
|
+
* Render CLAUDE.md content for the given agents.
|
|
14
|
+
* Emits a `## <agent name>` section per agent with capabilities listed as rules.
|
|
15
|
+
*/
|
|
16
|
+
export declare function renderClaudeMd(agents: AgentConfig[], options?: CompatibilityRendererOptions): string;
|
|
17
|
+
//# sourceMappingURL=claude-md.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-md.d.ts","sourceRoot":"","sources":["../src/claude-md.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAA;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EAAE,EACrB,OAAO,CAAC,EAAE,4BAA4B,GACrC,MAAM,CA8BR"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compatibility exporter: CLAUDE.md
|
|
3
|
+
*
|
|
4
|
+
* Emits a CLAUDE.md-format file from an array of AgentConfig.
|
|
5
|
+
* Pure function – no I/O.
|
|
6
|
+
*
|
|
7
|
+
* This is a compatibility output, not the canonical projection target.
|
|
8
|
+
* Canonical outputs are AGENTS.md and .agents/ (see agents-md.ts, agents-dir.ts).
|
|
9
|
+
*/
|
|
10
|
+
import { resolveCompatibilityAttribution } from './compatibility-attribution.js';
|
|
11
|
+
/**
|
|
12
|
+
* Render CLAUDE.md content for the given agents.
|
|
13
|
+
* Emits a `## <agent name>` section per agent with capabilities listed as rules.
|
|
14
|
+
*/
|
|
15
|
+
export function renderClaudeMd(agents, options) {
|
|
16
|
+
const attribution = resolveCompatibilityAttribution(options);
|
|
17
|
+
const lines = [
|
|
18
|
+
'# Agent Rules',
|
|
19
|
+
'',
|
|
20
|
+
'> Auto-generated by mossbear. Edit in AGENTS.md, not here.',
|
|
21
|
+
'',
|
|
22
|
+
];
|
|
23
|
+
for (const agent of agents) {
|
|
24
|
+
lines.push(`## ${agent.name}`);
|
|
25
|
+
lines.push('');
|
|
26
|
+
if (agent.description) {
|
|
27
|
+
lines.push(agent.description);
|
|
28
|
+
lines.push('');
|
|
29
|
+
}
|
|
30
|
+
if (agent.capabilities.length > 0) {
|
|
31
|
+
for (const cap of agent.capabilities) {
|
|
32
|
+
lines.push(`- ${cap}`);
|
|
33
|
+
}
|
|
34
|
+
lines.push('');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (attribution) {
|
|
38
|
+
lines.push(`> ${attribution}`);
|
|
39
|
+
lines.push('');
|
|
40
|
+
}
|
|
41
|
+
return lines.join('\n');
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=claude-md.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-md.js","sourceRoot":"","sources":["../src/claude-md.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,+BAA+B,EAAE,MAAM,gCAAgC,CAAA;AAKhF;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAqB,EACrB,OAAsC;IAEtC,MAAM,WAAW,GAAG,+BAA+B,CAAC,OAAO,CAAC,CAAA;IAC5D,MAAM,KAAK,GAAa;QACtB,eAAe;QACf,EAAE;QACF,4DAA4D;QAC5D,EAAE;KACH,CAAA;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAChB,CAAC;QACD,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;gBACrC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,CAAA;YACxB,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAChB,CAAC;IACH,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,KAAK,WAAW,EAAE,CAAC,CAAA;QAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAChB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-md.test.d.ts","sourceRoot":"","sources":["../src/claude-md.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { renderClaudeMd } from './claude-md.js';
|
|
3
|
+
const agent = {
|
|
4
|
+
id: 'reviewer',
|
|
5
|
+
name: 'Code Reviewer',
|
|
6
|
+
description: 'Reviews code for quality issues.',
|
|
7
|
+
capabilities: ['no trailing whitespace', 'prefer const over let'],
|
|
8
|
+
};
|
|
9
|
+
describe('renderClaudeMd', () => {
|
|
10
|
+
it('renders a header and agent rules section', () => {
|
|
11
|
+
const output = renderClaudeMd([agent]);
|
|
12
|
+
expect(output).toContain('# Agent Rules');
|
|
13
|
+
expect(output).toContain('## Code Reviewer');
|
|
14
|
+
expect(output).toContain('- no trailing whitespace');
|
|
15
|
+
expect(output).toContain('- prefer const over let');
|
|
16
|
+
expect(output).toContain('Reviews code for quality issues.');
|
|
17
|
+
});
|
|
18
|
+
it('includes the auto-generated note', () => {
|
|
19
|
+
const output = renderClaudeMd([agent]);
|
|
20
|
+
expect(output).toContain('Auto-generated by mossbear');
|
|
21
|
+
});
|
|
22
|
+
it('does not include attribution by default', () => {
|
|
23
|
+
const output = renderClaudeMd([agent]);
|
|
24
|
+
expect(output).not.toContain('Guides managed by Mossbear');
|
|
25
|
+
});
|
|
26
|
+
it('appends attribution when enabled', () => {
|
|
27
|
+
const output = renderClaudeMd([agent], { includeAttribution: true });
|
|
28
|
+
expect(output).toContain('> Guides managed by Mossbear (mossbear.io)');
|
|
29
|
+
});
|
|
30
|
+
it('uses a custom attribution string when provided', () => {
|
|
31
|
+
const output = renderClaudeMd([agent], {
|
|
32
|
+
includeAttribution: true,
|
|
33
|
+
attribution: 'Managed by Mossbear — 94% alignment score',
|
|
34
|
+
});
|
|
35
|
+
expect(output).toContain('> Managed by Mossbear — 94% alignment score');
|
|
36
|
+
});
|
|
37
|
+
it('returns a valid string for an empty agent list', () => {
|
|
38
|
+
const output = renderClaudeMd([]);
|
|
39
|
+
expect(typeof output).toBe('string');
|
|
40
|
+
expect(output).toContain('# Agent Rules');
|
|
41
|
+
});
|
|
42
|
+
it('renders multiple agents in order', () => {
|
|
43
|
+
const second = {
|
|
44
|
+
id: 'formatter',
|
|
45
|
+
name: 'Formatter',
|
|
46
|
+
description: '',
|
|
47
|
+
capabilities: ['use 2-space indentation'],
|
|
48
|
+
};
|
|
49
|
+
const output = renderClaudeMd([agent, second]);
|
|
50
|
+
const reviewerPos = output.indexOf('## Code Reviewer');
|
|
51
|
+
const formatterPos = output.indexOf('## Formatter');
|
|
52
|
+
expect(reviewerPos).toBeLessThan(formatterPos);
|
|
53
|
+
});
|
|
54
|
+
it('skips the description block when description is empty', () => {
|
|
55
|
+
const noDesc = { ...agent, description: '' };
|
|
56
|
+
const output = renderClaudeMd([noDesc]);
|
|
57
|
+
// Should not emit a blank description paragraph
|
|
58
|
+
expect(output).not.toMatch(/## Code Reviewer\n\n\n/);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=claude-md.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-md.test.js","sourceRoot":"","sources":["../src/claude-md.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compatibility exporter: .claude/rules/
|
|
3
|
+
*
|
|
4
|
+
* Emits a file map for `.claude/rules/` from an array of AgentConfig.
|
|
5
|
+
* Pure function – no I/O.
|
|
6
|
+
*
|
|
7
|
+
* This is a compatibility output, not the canonical projection target.
|
|
8
|
+
* Canonical outputs are AGENTS.md and .agents/ (see agents-md.ts, agents-dir.ts).
|
|
9
|
+
*/
|
|
10
|
+
import type { CompatibilityRendererOptions } from './compatibility-attribution.js';
|
|
11
|
+
import type { AgentConfig } from '@mossbear/protocol';
|
|
12
|
+
/**
|
|
13
|
+
* Returns a map of `{ filename: content }` for `.claude/rules/`.
|
|
14
|
+
* Each agent gets its own markdown rule file.
|
|
15
|
+
*/
|
|
16
|
+
export declare function renderClaudeRules(agents: AgentConfig[], options?: CompatibilityRendererOptions): Record<string, string>;
|
|
17
|
+
//# sourceMappingURL=claude-rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-rules.d.ts","sourceRoot":"","sources":["../src/claude-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAA;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EAAE,EACrB,OAAO,CAAC,EAAE,4BAA4B,GACrC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiCxB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compatibility exporter: .claude/rules/
|
|
3
|
+
*
|
|
4
|
+
* Emits a file map for `.claude/rules/` from an array of AgentConfig.
|
|
5
|
+
* Pure function – no I/O.
|
|
6
|
+
*
|
|
7
|
+
* This is a compatibility output, not the canonical projection target.
|
|
8
|
+
* Canonical outputs are AGENTS.md and .agents/ (see agents-md.ts, agents-dir.ts).
|
|
9
|
+
*/
|
|
10
|
+
import { resolveCompatibilityAttribution } from './compatibility-attribution.js';
|
|
11
|
+
/**
|
|
12
|
+
* Returns a map of `{ filename: content }` for `.claude/rules/`.
|
|
13
|
+
* Each agent gets its own markdown rule file.
|
|
14
|
+
*/
|
|
15
|
+
export function renderClaudeRules(agents, options) {
|
|
16
|
+
const attribution = resolveCompatibilityAttribution(options);
|
|
17
|
+
const files = {};
|
|
18
|
+
for (const agent of agents) {
|
|
19
|
+
const lines = [
|
|
20
|
+
`# ${agent.name}`,
|
|
21
|
+
'',
|
|
22
|
+
'> Auto-generated by mossbear. Edit in AGENTS.md, not here.',
|
|
23
|
+
'',
|
|
24
|
+
];
|
|
25
|
+
if (agent.description) {
|
|
26
|
+
lines.push(agent.description);
|
|
27
|
+
lines.push('');
|
|
28
|
+
}
|
|
29
|
+
if (agent.capabilities.length > 0) {
|
|
30
|
+
for (const capability of agent.capabilities) {
|
|
31
|
+
lines.push(`- ${capability}`);
|
|
32
|
+
}
|
|
33
|
+
lines.push('');
|
|
34
|
+
}
|
|
35
|
+
if (attribution) {
|
|
36
|
+
lines.push(`> ${attribution}`);
|
|
37
|
+
lines.push('');
|
|
38
|
+
}
|
|
39
|
+
files[`${agent.id}.md`] = lines.join('\n');
|
|
40
|
+
}
|
|
41
|
+
return files;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=claude-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-rules.js","sourceRoot":"","sources":["../src/claude-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,+BAA+B,EAAE,MAAM,gCAAgC,CAAA;AAKhF;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAqB,EACrB,OAAsC;IAEtC,MAAM,WAAW,GAAG,+BAA+B,CAAC,OAAO,CAAC,CAAA;IAC5D,MAAM,KAAK,GAA2B,EAAE,CAAA;IAExC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAa;YACtB,KAAK,KAAK,CAAC,IAAI,EAAE;YACjB,EAAE;YACF,4DAA4D;YAC5D,EAAE;SACH,CAAA;QAED,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAChB,CAAC;QAED,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,KAAK,MAAM,UAAU,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;gBAC5C,KAAK,CAAC,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC,CAAA;YAC/B,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAChB,CAAC;QAED,IAAI,WAAW,EAAE,CAAC;YAChB,KAAK,CAAC,IAAI,CAAC,KAAK,WAAW,EAAE,CAAC,CAAA;YAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAChB,CAAC;QAED,KAAK,CAAC,GAAG,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC5C,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-rules.test.d.ts","sourceRoot":"","sources":["../src/claude-rules.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { renderClaudeRules } from './claude-rules.js';
|
|
3
|
+
const agent = {
|
|
4
|
+
id: 'reviewer',
|
|
5
|
+
name: 'Code Reviewer',
|
|
6
|
+
description: 'Reviews code for quality issues.',
|
|
7
|
+
capabilities: ['no trailing whitespace', 'prefer const over let'],
|
|
8
|
+
};
|
|
9
|
+
describe('renderClaudeRules', () => {
|
|
10
|
+
it('creates a file per agent', () => {
|
|
11
|
+
const files = renderClaudeRules([agent]);
|
|
12
|
+
expect(Object.keys(files)).toContain('reviewer.md');
|
|
13
|
+
});
|
|
14
|
+
it('renders markdown rule content for each file', () => {
|
|
15
|
+
const files = renderClaudeRules([agent]);
|
|
16
|
+
const content = files['reviewer.md'] ?? '';
|
|
17
|
+
expect(content).toContain('# Code Reviewer');
|
|
18
|
+
expect(content).toContain('Reviews code for quality issues.');
|
|
19
|
+
expect(content).toContain('- no trailing whitespace');
|
|
20
|
+
expect(content).toContain('- prefer const over let');
|
|
21
|
+
});
|
|
22
|
+
it('does not include attribution by default', () => {
|
|
23
|
+
const files = renderClaudeRules([agent]);
|
|
24
|
+
expect(files['reviewer.md']).not.toContain('Guides managed by Mossbear');
|
|
25
|
+
});
|
|
26
|
+
it('appends attribution when enabled', () => {
|
|
27
|
+
const files = renderClaudeRules([agent], { includeAttribution: true });
|
|
28
|
+
expect(files['reviewer.md']).toContain('> Guides managed by Mossbear (mossbear.io)');
|
|
29
|
+
});
|
|
30
|
+
it('returns an empty object for empty input', () => {
|
|
31
|
+
expect(renderClaudeRules([])).toEqual({});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=claude-rules.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-rules.test.js","sourceRoot":"","sources":["../src/claude-rules.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAIrD,MAAM,KAAK,GAAgB;IACzB,EAAE,EAAE,UAAU;IACd,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE,kCAAkC;IAC/C,YAAY,EAAE,CAAC,wBAAwB,EAAE,uBAAuB,CAAC;CAClE,CAAA;AAED,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QACxC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QACxC,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,CAAA;QAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAA;QAC5C,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,kCAAkC,CAAC,CAAA;QAC7D,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAA;QACrD,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QACxC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAA;IAC1E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAA;QACtE,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,4CAA4C,CAAC,CAAA;IACtF,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC3C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type CompatibilityRendererOptions = {
|
|
2
|
+
includeAttribution?: boolean;
|
|
3
|
+
attribution?: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const DEFAULT_COMPATIBILITY_ATTRIBUTION = "Guides managed by Mossbear (mossbear.io)";
|
|
6
|
+
export declare function resolveCompatibilityAttribution(options?: CompatibilityRendererOptions): string | null;
|
|
7
|
+
//# sourceMappingURL=compatibility-attribution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compatibility-attribution.d.ts","sourceRoot":"","sources":["../src/compatibility-attribution.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,4BAA4B,GAAG;IACzC,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,eAAO,MAAM,iCAAiC,6CACF,CAAA;AAE5C,wBAAgB,+BAA+B,CAC7C,OAAO,CAAC,EAAE,4BAA4B,GACrC,MAAM,GAAG,IAAI,CASf"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const DEFAULT_COMPATIBILITY_ATTRIBUTION = 'Guides managed by Mossbear (mossbear.io)';
|
|
2
|
+
export function resolveCompatibilityAttribution(options) {
|
|
3
|
+
if (!options?.includeAttribution) {
|
|
4
|
+
return null;
|
|
5
|
+
}
|
|
6
|
+
const attribution = options.attribution?.trim();
|
|
7
|
+
return attribution && attribution.length > 0
|
|
8
|
+
? attribution
|
|
9
|
+
: DEFAULT_COMPATIBILITY_ATTRIBUTION;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=compatibility-attribution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compatibility-attribution.js","sourceRoot":"","sources":["../src/compatibility-attribution.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,iCAAiC,GAC5C,0CAA0C,CAAA;AAE5C,MAAM,UAAU,+BAA+B,CAC7C,OAAsC;IAEtC,IAAI,CAAC,OAAO,EAAE,kBAAkB,EAAE,CAAC;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CAAA;IAC/C,OAAO,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;QAC1C,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,iCAAiC,CAAA;AACvC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compatibility exporter: .cursorrules
|
|
3
|
+
*
|
|
4
|
+
* Emits a .cursorrules-format file from an array of AgentConfig.
|
|
5
|
+
* Pure function – no I/O.
|
|
6
|
+
*
|
|
7
|
+
* This is a compatibility output, not the canonical projection target.
|
|
8
|
+
* Canonical outputs are AGENTS.md and .agents/ (see agents-md.ts, agents-dir.ts).
|
|
9
|
+
*/
|
|
10
|
+
import type { CompatibilityRendererOptions } from './compatibility-attribution.js';
|
|
11
|
+
import type { AgentConfig } from '@mossbear/protocol';
|
|
12
|
+
/**
|
|
13
|
+
* Render .cursorrules content for the given agents.
|
|
14
|
+
* Emits one rule line per capability, prefixed with the agent name.
|
|
15
|
+
*/
|
|
16
|
+
export declare function renderCursorRules(agents: AgentConfig[], options?: CompatibilityRendererOptions): string;
|
|
17
|
+
//# sourceMappingURL=cursor-rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-rules.d.ts","sourceRoot":"","sources":["../src/cursor-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAA;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EAAE,EACrB,OAAO,CAAC,EAAE,4BAA4B,GACrC,MAAM,CAsBR"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compatibility exporter: .cursorrules
|
|
3
|
+
*
|
|
4
|
+
* Emits a .cursorrules-format file from an array of AgentConfig.
|
|
5
|
+
* Pure function – no I/O.
|
|
6
|
+
*
|
|
7
|
+
* This is a compatibility output, not the canonical projection target.
|
|
8
|
+
* Canonical outputs are AGENTS.md and .agents/ (see agents-md.ts, agents-dir.ts).
|
|
9
|
+
*/
|
|
10
|
+
import { resolveCompatibilityAttribution } from './compatibility-attribution.js';
|
|
11
|
+
/**
|
|
12
|
+
* Render .cursorrules content for the given agents.
|
|
13
|
+
* Emits one rule line per capability, prefixed with the agent name.
|
|
14
|
+
*/
|
|
15
|
+
export function renderCursorRules(agents, options) {
|
|
16
|
+
const attribution = resolveCompatibilityAttribution(options);
|
|
17
|
+
const lines = [
|
|
18
|
+
'# Auto-generated by mossbear. Edit in AGENTS.md, not here.',
|
|
19
|
+
'',
|
|
20
|
+
];
|
|
21
|
+
for (const agent of agents) {
|
|
22
|
+
if (agent.capabilities.length === 0)
|
|
23
|
+
continue;
|
|
24
|
+
lines.push(`# ${agent.name}`);
|
|
25
|
+
for (const cap of agent.capabilities) {
|
|
26
|
+
lines.push(`[${agent.name}] ${cap}`);
|
|
27
|
+
}
|
|
28
|
+
lines.push('');
|
|
29
|
+
}
|
|
30
|
+
if (attribution) {
|
|
31
|
+
lines.push(`# ${attribution}`);
|
|
32
|
+
lines.push('');
|
|
33
|
+
}
|
|
34
|
+
return lines.join('\n');
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=cursor-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-rules.js","sourceRoot":"","sources":["../src/cursor-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,+BAA+B,EAAE,MAAM,gCAAgC,CAAA;AAKhF;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAqB,EACrB,OAAsC;IAEtC,MAAM,WAAW,GAAG,+BAA+B,CAAC,OAAO,CAAC,CAAA;IAC5D,MAAM,KAAK,GAAa;QACtB,4DAA4D;QAC5D,EAAE;KACH,CAAA;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC;YAAE,SAAQ;QAC7C,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QAC7B,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC,CAAA;QACtC,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAChB,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,KAAK,WAAW,EAAE,CAAC,CAAA;QAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAChB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-rules.test.d.ts","sourceRoot":"","sources":["../src/cursor-rules.test.ts"],"names":[],"mappings":""}
|