rebar-mcp 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/template-writer.md +43 -0
- package/.claude/agents/test-runner.md +47 -0
- package/.claude/mcp.json +9 -0
- package/.claude/settings.json +29 -0
- package/.claude/skills/ /SKILL.md +21 -0
- package/.claude/skills/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/SKILL.md +21 -0
- package/.claude/skills/bmmibwetxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bmmibwjgvxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bmmibwsesxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bmmibwxufxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bmmibx3r9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bmmji0lrkxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bmmjiniphxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bmmjio86zxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bmmjiolfbxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bmmjit1lvxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bmmjita1qxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bnd-mmibweu3/SKILL.md +21 -0
- package/.claude/skills/bnd-mmibwjh4/SKILL.md +21 -0
- package/.claude/skills/bnd-mmibwsey/SKILL.md +21 -0
- package/.claude/skills/bnd-mmibwxup/SKILL.md +21 -0
- package/.claude/skills/bnd-mmibx3rg/SKILL.md +21 -0
- package/.claude/skills/bnd-mmji0lrp/SKILL.md +21 -0
- package/.claude/skills/bnd-mmjinipm/SKILL.md +21 -0
- package/.claude/skills/bnd-mmjio875/SKILL.md +21 -0
- package/.claude/skills/bnd-mmjiolfg/SKILL.md +21 -0
- package/.claude/skills/bnd-mmjit1m3/SKILL.md +21 -0
- package/.claude/skills/bnd-mmjita1x/SKILL.md +21 -0
- package/.claude/skills/coercion-test/SKILL.md +50 -0
- package/.claude/skills/large-skill/SKILL.md +21 -0
- package/.claude/skills/long-desc-skill/SKILL.md +21 -0
- package/.claude/skills/mcp-dev/SKILL.md +61 -0
- package/.claude/skills/nl-mmibweus/SKILL.md +25 -0
- package/.claude/skills/nl-mmibwjhf/SKILL.md +25 -0
- package/.claude/skills/nl-mmibwsf7/SKILL.md +25 -0
- package/.claude/skills/nl-mmibwxvq/SKILL.md +25 -0
- package/.claude/skills/nl-mmibx3rt/SKILL.md +25 -0
- package/.claude/skills/nl-mmji0lrz/SKILL.md +25 -0
- package/.claude/skills/nl-mmjinipx/SKILL.md +25 -0
- package/.claude/skills/nl-mmjio87f/SKILL.md +25 -0
- package/.claude/skills/nl-mmjiolfs/SKILL.md +25 -0
- package/.claude/skills/nl-mmjit1mc/SKILL.md +25 -0
- package/.claude/skills/nl-mmjita26/SKILL.md +25 -0
- package/.claude/skills/rapid-1/SKILL.md +21 -0
- package/.claude/skills/rapid-2/SKILL.md +21 -0
- package/.claude/skills/rapid-3/SKILL.md +21 -0
- package/.claude/skills/rapid-4/SKILL.md +21 -0
- package/.claude/skills/rapid-5/SKILL.md +21 -0
- package/.claude/skills/test/", /"malicious/": /"true/SKILL.md" +69 -0
- package/.claude/skills/test-emoji-/360/237/230/200-skill/SKILL.md +69 -0
- package/.claude/skills/test-skill/SKILL.md +69 -0
- package/.claude/skills/test; rm -rf /; skill/SKILL.md +69 -0
- package/.claude/skills/test<script>alert(1)</script>skill/SKILL.md +69 -0
- package/.claudeignore +5 -0
- package/.mcp.json +3 -0
- package/CHANGELOG.md +29 -0
- package/CLAUDE.md +76 -0
- package/LICENSE +21 -0
- package/README.md +149 -0
- package/ROADMAP.md +526 -0
- package/ccboot-PRD-v1.0.docx.md +732 -0
- package/ccboot-v1.2.0-enforcement-spec.md +1272 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +674 -0
- package/dist/cli.js.map +1 -0
- package/dist/constants.d.ts +25 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +118 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/common.d.ts +62 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +15 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/schemas/scaffolding.d.ts +277 -0
- package/dist/schemas/scaffolding.d.ts.map +1 -0
- package/dist/schemas/scaffolding.js +133 -0
- package/dist/schemas/scaffolding.js.map +1 -0
- package/dist/services/claudemd-generator.d.ts +16 -0
- package/dist/services/claudemd-generator.d.ts.map +1 -0
- package/dist/services/claudemd-generator.js +426 -0
- package/dist/services/claudemd-generator.js.map +1 -0
- package/dist/services/codex-generator.d.ts +6 -0
- package/dist/services/codex-generator.d.ts.map +1 -0
- package/dist/services/codex-generator.js +35 -0
- package/dist/services/codex-generator.js.map +1 -0
- package/dist/services/cursor-generator.d.ts +15 -0
- package/dist/services/cursor-generator.d.ts.map +1 -0
- package/dist/services/cursor-generator.js +134 -0
- package/dist/services/cursor-generator.js.map +1 -0
- package/dist/services/file-ops.d.ts +48 -0
- package/dist/services/file-ops.d.ts.map +1 -0
- package/dist/services/file-ops.js +153 -0
- package/dist/services/file-ops.js.map +1 -0
- package/dist/services/output-formatter.d.ts +57 -0
- package/dist/services/output-formatter.d.ts.map +1 -0
- package/dist/services/output-formatter.js +88 -0
- package/dist/services/output-formatter.js.map +1 -0
- package/dist/services/platform-detect.d.ts +14 -0
- package/dist/services/platform-detect.d.ts.map +1 -0
- package/dist/services/platform-detect.js +63 -0
- package/dist/services/platform-detect.js.map +1 -0
- package/dist/services/project-analyzer.d.ts +71 -0
- package/dist/services/project-analyzer.d.ts.map +1 -0
- package/dist/services/project-analyzer.js +595 -0
- package/dist/services/project-analyzer.js.map +1 -0
- package/dist/services/rules-engine.d.ts +41 -0
- package/dist/services/rules-engine.d.ts.map +1 -0
- package/dist/services/rules-engine.js +304 -0
- package/dist/services/rules-engine.js.map +1 -0
- package/dist/services/strictness.d.ts +37 -0
- package/dist/services/strictness.d.ts.map +1 -0
- package/dist/services/strictness.js +182 -0
- package/dist/services/strictness.js.map +1 -0
- package/dist/services/template-engine.d.ts +16 -0
- package/dist/services/template-engine.d.ts.map +1 -0
- package/dist/services/template-engine.js +85 -0
- package/dist/services/template-engine.js.map +1 -0
- package/dist/services/validation.d.ts +41 -0
- package/dist/services/validation.d.ts.map +1 -0
- package/dist/services/validation.js +104 -0
- package/dist/services/validation.js.map +1 -0
- package/dist/services/windsurf-generator.d.ts +15 -0
- package/dist/services/windsurf-generator.d.ts.map +1 -0
- package/dist/services/windsurf-generator.js +127 -0
- package/dist/services/windsurf-generator.js.map +1 -0
- package/dist/tests/enforcement.test.d.ts +2 -0
- package/dist/tests/enforcement.test.d.ts.map +1 -0
- package/dist/tests/enforcement.test.js +541 -0
- package/dist/tests/enforcement.test.js.map +1 -0
- package/dist/tests/enterprise.test.d.ts +2 -0
- package/dist/tests/enterprise.test.d.ts.map +1 -0
- package/dist/tests/enterprise.test.js +353 -0
- package/dist/tests/enterprise.test.js.map +1 -0
- package/dist/tests/fuzzing.test.d.ts +2 -0
- package/dist/tests/fuzzing.test.d.ts.map +1 -0
- package/dist/tests/fuzzing.test.js +596 -0
- package/dist/tests/fuzzing.test.js.map +1 -0
- package/dist/tests/knowledge.test.d.ts +2 -0
- package/dist/tests/knowledge.test.d.ts.map +1 -0
- package/dist/tests/knowledge.test.js +292 -0
- package/dist/tests/knowledge.test.js.map +1 -0
- package/dist/tests/management.test.d.ts +2 -0
- package/dist/tests/management.test.d.ts.map +1 -0
- package/dist/tests/management.test.js +338 -0
- package/dist/tests/management.test.js.map +1 -0
- package/dist/tests/scaffolding.test.d.ts +2 -0
- package/dist/tests/scaffolding.test.d.ts.map +1 -0
- package/dist/tests/scaffolding.test.js +419 -0
- package/dist/tests/scaffolding.test.js.map +1 -0
- package/dist/tests/test-utils.d.ts +76 -0
- package/dist/tests/test-utils.d.ts.map +1 -0
- package/dist/tests/test-utils.js +171 -0
- package/dist/tests/test-utils.js.map +1 -0
- package/dist/tests/tool-harness.d.ts +18 -0
- package/dist/tests/tool-harness.d.ts.map +1 -0
- package/dist/tests/tool-harness.js +51 -0
- package/dist/tests/tool-harness.js.map +1 -0
- package/dist/tools/enterprise.d.ts +8 -0
- package/dist/tools/enterprise.d.ts.map +1 -0
- package/dist/tools/enterprise.js +571 -0
- package/dist/tools/enterprise.js.map +1 -0
- package/dist/tools/knowledge.d.ts +7 -0
- package/dist/tools/knowledge.d.ts.map +1 -0
- package/dist/tools/knowledge.js +120 -0
- package/dist/tools/knowledge.js.map +1 -0
- package/dist/tools/management.d.ts +10 -0
- package/dist/tools/management.d.ts.map +1 -0
- package/dist/tools/management.js +1541 -0
- package/dist/tools/management.js.map +1 -0
- package/dist/tools/scaffolding.d.ts +8 -0
- package/dist/tools/scaffolding.d.ts.map +1 -0
- package/dist/tools/scaffolding.js +736 -0
- package/dist/tools/scaffolding.js.map +1 -0
- package/dist/types.d.ts +54 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/landing/app/layout.tsx +30 -0
- package/landing/app/page.tsx +944 -0
- package/landing/next-env.d.ts +6 -0
- package/landing/next.config.js +6 -0
- package/landing/package-lock.json +896 -0
- package/landing/package.json +20 -0
- package/landing/tsconfig.json +40 -0
- package/package.json +49 -0
- package/rebar-v2.0.0-platform-spec.md +1567 -0
- package/server.json +20 -0
- package/src/cli.ts +735 -0
- package/src/constants.ts +131 -0
- package/src/index.ts +54 -0
- package/src/schemas/common.ts +22 -0
- package/src/schemas/scaffolding.ts +161 -0
- package/src/services/claudemd-generator.ts +481 -0
- package/src/services/codex-generator.ts +44 -0
- package/src/services/cursor-generator.ts +153 -0
- package/src/services/file-ops.ts +172 -0
- package/src/services/platform-detect.ts +80 -0
- package/src/services/project-analyzer.ts +690 -0
- package/src/services/rules-engine.ts +353 -0
- package/src/services/strictness.ts +202 -0
- package/src/services/template-engine.ts +119 -0
- package/src/services/validation.ts +138 -0
- package/src/services/windsurf-generator.ts +145 -0
- package/src/tests/enforcement.test.ts +794 -0
- package/src/tests/enterprise.test.ts +483 -0
- package/src/tests/fuzzing.test.ts +690 -0
- package/src/tests/knowledge.test.ts +371 -0
- package/src/tests/management.test.ts +451 -0
- package/src/tests/scaffolding.test.ts +575 -0
- package/src/tests/test-utils.ts +206 -0
- package/src/tests/tool-harness.ts +70 -0
- package/src/tools/enterprise.ts +666 -0
- package/src/tools/knowledge.ts +162 -0
- package/src/tools/management.ts +1706 -0
- package/src/tools/scaffolding.ts +909 -0
- package/src/types.ts +93 -0
- package/supabase/.temp/cli-latest +1 -0
- package/supabase/.temp/gotrue-version +1 -0
- package/supabase/.temp/pooler-url +1 -0
- package/supabase/.temp/postgres-version +1 -0
- package/supabase/.temp/project-ref +1 -0
- package/supabase/.temp/rest-version +1 -0
- package/supabase/.temp/storage-migration +1 -0
- package/supabase/.temp/storage-version +1 -0
- package/templates/agents/explore.md +41 -0
- package/templates/agents/plan.md +73 -0
- package/templates/agents/security-auditor.md +77 -0
- package/templates/agents/test-runner.md +60 -0
- package/templates/claudemd/fastapi.md +49 -0
- package/templates/claudemd/monorepo.md +48 -0
- package/templates/claudemd/nextjs.md +52 -0
- package/templates/claudemd/react-spa.md +50 -0
- package/templates/claudemd/springboot.md +50 -0
- package/templates/hooks/danger-blocker.json +11 -0
- package/templates/hooks/format-on-write.json +17 -0
- package/templates/hooks/lint-on-write.json +16 -0
- package/templates/hooks/secret-detector.json +11 -0
- package/templates/skills/code-review.md +68 -0
- package/templates/skills/documentation.md +62 -0
- package/templates/skills/performance-audit.md +80 -0
- package/templates/skills/security-scan.md +66 -0
- package/templates/skills/test-writer.md +56 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex CLI configuration generator.
|
|
3
|
+
*
|
|
4
|
+
* OpenAI's Codex CLI uses an AGENTS.md file at the project root,
|
|
5
|
+
* which is functionally equivalent to CLAUDE.md.
|
|
6
|
+
*
|
|
7
|
+
* Codex does NOT support skills, agents, or hooks - just AGENTS.md.
|
|
8
|
+
*/
|
|
9
|
+
import * as path from "node:path";
|
|
10
|
+
import { atomicWrite } from "./file-ops.js";
|
|
11
|
+
/**
|
|
12
|
+
* Generates Codex CLI configuration (AGENTS.md) from CLAUDE.md content.
|
|
13
|
+
*/
|
|
14
|
+
export async function generateCodexConfig(projectPath, projectName, claudeMdContent) {
|
|
15
|
+
const files = [];
|
|
16
|
+
// Codex uses AGENTS.md with a specific header format
|
|
17
|
+
const header = `# ${projectName} — Agent Instructions
|
|
18
|
+
|
|
19
|
+
> Generated by Rebar (https://github.com/RCOLKITT/rebar-mcp)
|
|
20
|
+
> These rules apply to all AI coding agents working in this repository.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
`;
|
|
25
|
+
const agentsMdContent = header + claudeMdContent;
|
|
26
|
+
const agentsMdPath = path.join(projectPath, "AGENTS.md");
|
|
27
|
+
await atomicWrite(agentsMdPath, agentsMdContent);
|
|
28
|
+
files.push({
|
|
29
|
+
path: "AGENTS.md",
|
|
30
|
+
content: agentsMdContent,
|
|
31
|
+
description: "Codex CLI agent instructions",
|
|
32
|
+
});
|
|
33
|
+
return files;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=codex-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-generator.js","sourceRoot":"","sources":["../../src/services/codex-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,WAAmB,EACnB,WAAmB,EACnB,eAAuB;IAEvB,MAAM,KAAK,GAAoB,EAAE,CAAC;IAElC,qDAAqD;IACrD,MAAM,MAAM,GAAG,KAAK,WAAW;;;;;;;CAOhC,CAAC;IAEA,MAAM,eAAe,GAAG,MAAM,GAAG,eAAe,CAAC;IACjD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACzD,MAAM,WAAW,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;IAEjD,KAAK,CAAC,IAAI,CAAC;QACT,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,eAAe;QACxB,WAAW,EAAE,8BAA8B;KAC5C,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { GeneratedFile } from "../types.js";
|
|
2
|
+
export interface CursorRuleTemplate {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
content: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Generates Cursor configuration files from CLAUDE.md and skills.
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateCursorConfig(projectPath: string, projectName: string, claudeMdContent: string, skills: CursorRuleTemplate[]): Promise<GeneratedFile[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Default skills to convert to Cursor rules.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getDefaultCursorSkills(): CursorRuleTemplate[];
|
|
15
|
+
//# sourceMappingURL=cursor-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-generator.d.ts","sourceRoot":"","sources":["../../src/services/cursor-generator.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAmCD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,kBAAkB,EAAE,GAC3B,OAAO,CAAC,aAAa,EAAE,CAAC,CA6B1B;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,kBAAkB,EAAE,CA2D7D"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor configuration generator.
|
|
3
|
+
*
|
|
4
|
+
* Cursor uses .cursor/rules/*.md files that are functionally equivalent
|
|
5
|
+
* to Claude Code's skills. The format is different:
|
|
6
|
+
* - Uses YAML frontmatter with 'description' and 'globs' fields
|
|
7
|
+
* - Uses 'alwaysApply: true' for project-wide rules
|
|
8
|
+
*/
|
|
9
|
+
import * as path from "node:path";
|
|
10
|
+
import { ensureDir, atomicWrite } from "./file-ops.js";
|
|
11
|
+
/**
|
|
12
|
+
* Converts CLAUDE.md content to Cursor project-rules.md format.
|
|
13
|
+
*/
|
|
14
|
+
function convertToProjectRules(claudeMdContent, projectName) {
|
|
15
|
+
// Cursor rules use a different frontmatter format
|
|
16
|
+
const frontmatter = `---
|
|
17
|
+
description: Project rules and coding standards for ${projectName}
|
|
18
|
+
globs:
|
|
19
|
+
alwaysApply: true
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
> Note: Cursor does not support enforcement hooks. The guardrails below rely on
|
|
23
|
+
> you following these rules. For automated enforcement, use Rebar with Claude Code
|
|
24
|
+
> or run \`npx rebar-mcp audit\` in your CI pipeline.
|
|
25
|
+
|
|
26
|
+
`;
|
|
27
|
+
return frontmatter + claudeMdContent;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Converts a Claude Code skill to Cursor rule format.
|
|
31
|
+
*/
|
|
32
|
+
function convertSkillToCursorRule(skill) {
|
|
33
|
+
const frontmatter = `---
|
|
34
|
+
description: ${skill.description}
|
|
35
|
+
globs:
|
|
36
|
+
alwaysApply: false
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
`;
|
|
40
|
+
return frontmatter + skill.content;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Generates Cursor configuration files from CLAUDE.md and skills.
|
|
44
|
+
*/
|
|
45
|
+
export async function generateCursorConfig(projectPath, projectName, claudeMdContent, skills) {
|
|
46
|
+
const files = [];
|
|
47
|
+
const rulesDir = path.join(projectPath, ".cursor", "rules");
|
|
48
|
+
await ensureDir(rulesDir);
|
|
49
|
+
// Generate project-rules.md from CLAUDE.md
|
|
50
|
+
const projectRulesContent = convertToProjectRules(claudeMdContent, projectName);
|
|
51
|
+
const projectRulesPath = path.join(rulesDir, "project-rules.md");
|
|
52
|
+
await atomicWrite(projectRulesPath, projectRulesContent);
|
|
53
|
+
files.push({
|
|
54
|
+
path: ".cursor/rules/project-rules.md",
|
|
55
|
+
content: projectRulesContent,
|
|
56
|
+
description: "Main project rules (from CLAUDE.md)",
|
|
57
|
+
});
|
|
58
|
+
// Convert skills to Cursor rules
|
|
59
|
+
for (const skill of skills) {
|
|
60
|
+
const ruleContent = convertSkillToCursorRule(skill);
|
|
61
|
+
const rulePath = path.join(rulesDir, `${skill.name}.md`);
|
|
62
|
+
await atomicWrite(rulePath, ruleContent);
|
|
63
|
+
files.push({
|
|
64
|
+
path: `.cursor/rules/${skill.name}.md`,
|
|
65
|
+
content: ruleContent,
|
|
66
|
+
description: `${skill.name} rule`,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return files;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Default skills to convert to Cursor rules.
|
|
73
|
+
*/
|
|
74
|
+
export function getDefaultCursorSkills() {
|
|
75
|
+
return [
|
|
76
|
+
{
|
|
77
|
+
name: "code-review",
|
|
78
|
+
description: "Code review guidelines for quality and security",
|
|
79
|
+
content: `# Code Review
|
|
80
|
+
|
|
81
|
+
When reviewing code changes:
|
|
82
|
+
|
|
83
|
+
1. **Security First**: Check for injection vulnerabilities, auth issues, data exposure
|
|
84
|
+
2. **Error Handling**: Ensure errors are properly caught and handled
|
|
85
|
+
3. **Type Safety**: Verify types are correct and 'any' is avoided
|
|
86
|
+
4. **Performance**: Watch for N+1 queries, memory leaks, unnecessary re-renders
|
|
87
|
+
5. **Tests**: Ensure tests exist and pass for changed code
|
|
88
|
+
`,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: "test-writer",
|
|
92
|
+
description: "Test writing guidelines",
|
|
93
|
+
content: `# Test Writing
|
|
94
|
+
|
|
95
|
+
When writing tests:
|
|
96
|
+
|
|
97
|
+
1. Test behavior, not implementation
|
|
98
|
+
2. Use descriptive test names
|
|
99
|
+
3. Follow the Arrange-Act-Assert pattern
|
|
100
|
+
4. Mock external dependencies
|
|
101
|
+
5. Aim for edge cases, not just happy paths
|
|
102
|
+
`,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: "security-scan",
|
|
106
|
+
description: "Security scanning guidelines",
|
|
107
|
+
content: `# Security Scan
|
|
108
|
+
|
|
109
|
+
Check for:
|
|
110
|
+
|
|
111
|
+
1. Hardcoded secrets (API keys, passwords)
|
|
112
|
+
2. SQL injection vulnerabilities
|
|
113
|
+
3. XSS in rendered HTML
|
|
114
|
+
4. Insecure direct object references
|
|
115
|
+
5. Missing authentication/authorization
|
|
116
|
+
`,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "documentation",
|
|
120
|
+
description: "Documentation guidelines",
|
|
121
|
+
content: `# Documentation
|
|
122
|
+
|
|
123
|
+
When documenting:
|
|
124
|
+
|
|
125
|
+
1. Document the WHY, not the WHAT
|
|
126
|
+
2. Keep documentation close to code
|
|
127
|
+
3. Update docs when changing code
|
|
128
|
+
4. Use examples liberally
|
|
129
|
+
5. Document public APIs thoroughly
|
|
130
|
+
`,
|
|
131
|
+
},
|
|
132
|
+
];
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=cursor-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-generator.js","sourceRoot":"","sources":["../../src/services/cursor-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AASvD;;GAEG;AACH,SAAS,qBAAqB,CAAC,eAAuB,EAAE,WAAmB;IACzE,kDAAkD;IAClD,MAAM,WAAW,GAAG;sDACgC,WAAW;;;;;;;;;CAShE,CAAC;IACA,OAAO,WAAW,GAAG,eAAe,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,SAAS,wBAAwB,CAAC,KAAyB;IACzD,MAAM,WAAW,GAAG;eACP,KAAK,CAAC,WAAW;;;;;CAK/B,CAAC;IACA,OAAO,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,WAAmB,EACnB,WAAmB,EACnB,eAAuB,EACvB,MAA4B;IAE5B,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAE5D,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;IAE1B,2CAA2C;IAC3C,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;IAChF,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;IACjE,MAAM,WAAW,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC;QACT,IAAI,EAAE,gCAAgC;QACtC,OAAO,EAAE,mBAAmB;QAC5B,WAAW,EAAE,qCAAqC;KACnD,CAAC,CAAC;IAEH,iCAAiC;IACjC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;QACzD,MAAM,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,iBAAiB,KAAK,CAAC,IAAI,KAAK;YACtC,OAAO,EAAE,WAAW;YACpB,WAAW,EAAE,GAAG,KAAK,CAAC,IAAI,OAAO;SAClC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO;QACL;YACE,IAAI,EAAE,aAAa;YACnB,WAAW,EAAE,iDAAiD;YAC9D,OAAO,EAAE;;;;;;;;;CASd;SACI;QACD;YACE,IAAI,EAAE,aAAa;YACnB,WAAW,EAAE,yBAAyB;YACtC,OAAO,EAAE;;;;;;;;;CASd;SACI;QACD;YACE,IAAI,EAAE,eAAe;YACrB,WAAW,EAAE,8BAA8B;YAC3C,OAAO,EAAE;;;;;;;;;CASd;SACI;QACD;YACE,IAAI,EAAE,eAAe;YACrB,WAAW,EAAE,0BAA0B;YACvC,OAAO,EAAE;;;;;;;;;CASd;SACI;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ensures a directory exists, creating it recursively if needed.
|
|
3
|
+
*/
|
|
4
|
+
export declare function ensureDir(dirPath: string): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Writes a file atomically: writes to a temp file first, then renames.
|
|
7
|
+
* This prevents partial writes from corrupting existing files.
|
|
8
|
+
*/
|
|
9
|
+
export declare function atomicWrite(filePath: string, content: string): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Checks if a file exists.
|
|
12
|
+
*/
|
|
13
|
+
export declare function fileExists(filePath: string): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Reads a file and returns its content, or null if it doesn't exist.
|
|
16
|
+
*/
|
|
17
|
+
export declare function readFileSafe(filePath: string): Promise<string | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Lists files in a directory matching an optional extension filter.
|
|
20
|
+
*/
|
|
21
|
+
export declare function listFiles(dirPath: string, extension?: string): Promise<string[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Recursively lists all files under a directory.
|
|
24
|
+
*/
|
|
25
|
+
export declare function listFilesRecursive(dirPath: string, extension?: string): Promise<string[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Resolves a project path to an absolute path.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveProjectPath(projectPath: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Sanitizes a file path to prevent directory traversal attacks.
|
|
32
|
+
* Ensures the resolved path is within the project root.
|
|
33
|
+
*/
|
|
34
|
+
export declare function sanitizePath(basePath: string, relativePath: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Writes a file only if it doesn't exist or mergeExisting is true.
|
|
37
|
+
* Returns info about what was done.
|
|
38
|
+
*/
|
|
39
|
+
export declare function safeWriteFile(filePath: string, content: string, mergeExisting: boolean): Promise<{
|
|
40
|
+
written: boolean;
|
|
41
|
+
merged: boolean;
|
|
42
|
+
message: string;
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* Creates a temp directory for intermediate operations.
|
|
46
|
+
*/
|
|
47
|
+
export declare function createTempDir(): Promise<string>;
|
|
48
|
+
//# sourceMappingURL=file-ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-ops.d.ts","sourceRoot":"","sources":["../../src/services/file-ops.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBlF;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAM3E;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,EAAE,CAAC,CASnB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,EAAE,CAAC,CAiBnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK9D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAS3E;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,OAAO,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA0BjE;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAErD"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File operations service with atomic writes and safety checks
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from "node:fs/promises";
|
|
5
|
+
import * as path from "node:path";
|
|
6
|
+
import * as os from "node:os";
|
|
7
|
+
import * as crypto from "node:crypto";
|
|
8
|
+
/**
|
|
9
|
+
* Ensures a directory exists, creating it recursively if needed.
|
|
10
|
+
*/
|
|
11
|
+
export async function ensureDir(dirPath) {
|
|
12
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Writes a file atomically: writes to a temp file first, then renames.
|
|
16
|
+
* This prevents partial writes from corrupting existing files.
|
|
17
|
+
*/
|
|
18
|
+
export async function atomicWrite(filePath, content) {
|
|
19
|
+
const dir = path.dirname(filePath);
|
|
20
|
+
await ensureDir(dir);
|
|
21
|
+
const tmpName = `.tmp-${crypto.randomBytes(8).toString("hex")}`;
|
|
22
|
+
const tmpPath = path.join(dir, tmpName);
|
|
23
|
+
try {
|
|
24
|
+
await fs.writeFile(tmpPath, content, "utf-8");
|
|
25
|
+
await fs.rename(tmpPath, filePath);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
// Clean up temp file on failure
|
|
29
|
+
try {
|
|
30
|
+
await fs.unlink(tmpPath);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Ignore cleanup errors
|
|
34
|
+
}
|
|
35
|
+
throw err;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Checks if a file exists.
|
|
40
|
+
*/
|
|
41
|
+
export async function fileExists(filePath) {
|
|
42
|
+
try {
|
|
43
|
+
await fs.access(filePath);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Reads a file and returns its content, or null if it doesn't exist.
|
|
52
|
+
*/
|
|
53
|
+
export async function readFileSafe(filePath) {
|
|
54
|
+
try {
|
|
55
|
+
return await fs.readFile(filePath, "utf-8");
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Lists files in a directory matching an optional extension filter.
|
|
63
|
+
*/
|
|
64
|
+
export async function listFiles(dirPath, extension) {
|
|
65
|
+
try {
|
|
66
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
67
|
+
return entries
|
|
68
|
+
.filter((e) => e.isFile() && (!extension || e.name.endsWith(extension)))
|
|
69
|
+
.map((e) => path.join(dirPath, e.name));
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Recursively lists all files under a directory.
|
|
77
|
+
*/
|
|
78
|
+
export async function listFilesRecursive(dirPath, extension) {
|
|
79
|
+
const results = [];
|
|
80
|
+
try {
|
|
81
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
82
|
+
for (const entry of entries) {
|
|
83
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
84
|
+
if (entry.isDirectory()) {
|
|
85
|
+
const sub = await listFilesRecursive(fullPath, extension);
|
|
86
|
+
results.push(...sub);
|
|
87
|
+
}
|
|
88
|
+
else if (!extension || entry.name.endsWith(extension)) {
|
|
89
|
+
results.push(fullPath);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Directory doesn't exist or not readable
|
|
95
|
+
}
|
|
96
|
+
return results;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolves a project path to an absolute path.
|
|
100
|
+
*/
|
|
101
|
+
export function resolveProjectPath(projectPath) {
|
|
102
|
+
if (path.isAbsolute(projectPath)) {
|
|
103
|
+
return path.normalize(projectPath);
|
|
104
|
+
}
|
|
105
|
+
return path.resolve(process.cwd(), projectPath);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Sanitizes a file path to prevent directory traversal attacks.
|
|
109
|
+
* Ensures the resolved path is within the project root.
|
|
110
|
+
*/
|
|
111
|
+
export function sanitizePath(basePath, relativePath) {
|
|
112
|
+
const resolved = path.resolve(basePath, relativePath);
|
|
113
|
+
const normalizedBase = path.normalize(basePath);
|
|
114
|
+
if (!resolved.startsWith(normalizedBase)) {
|
|
115
|
+
throw new Error(`Path traversal detected: "${relativePath}" resolves outside project root`);
|
|
116
|
+
}
|
|
117
|
+
return resolved;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Writes a file only if it doesn't exist or mergeExisting is true.
|
|
121
|
+
* Returns info about what was done.
|
|
122
|
+
*/
|
|
123
|
+
export async function safeWriteFile(filePath, content, mergeExisting) {
|
|
124
|
+
const exists = await fileExists(filePath);
|
|
125
|
+
if (exists && !mergeExisting) {
|
|
126
|
+
return {
|
|
127
|
+
written: false,
|
|
128
|
+
merged: false,
|
|
129
|
+
message: `File already exists: ${filePath}. Set merge_existing=true to overwrite.`,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
if (exists && mergeExisting) {
|
|
133
|
+
await atomicWrite(filePath, content);
|
|
134
|
+
return {
|
|
135
|
+
written: true,
|
|
136
|
+
merged: true,
|
|
137
|
+
message: `Merged/updated: ${filePath}`,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
await atomicWrite(filePath, content);
|
|
141
|
+
return {
|
|
142
|
+
written: true,
|
|
143
|
+
merged: false,
|
|
144
|
+
message: `Created: ${filePath}`,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Creates a temp directory for intermediate operations.
|
|
149
|
+
*/
|
|
150
|
+
export async function createTempDir() {
|
|
151
|
+
return await fs.mkdtemp(path.join(os.tmpdir(), "rebar-"));
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=file-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-ops.js","sourceRoot":"","sources":["../../src/services/file-ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatting utilities for ccboot tools
|
|
3
|
+
* Supports markdown (human-readable) and JSON (programmatic) output formats
|
|
4
|
+
*/
|
|
5
|
+
import type { ToolResult } from "../types.js";
|
|
6
|
+
export type OutputFormat = "markdown" | "json";
|
|
7
|
+
/**
|
|
8
|
+
* Structured result data for JSON output
|
|
9
|
+
*/
|
|
10
|
+
export interface StructuredResult {
|
|
11
|
+
success: boolean;
|
|
12
|
+
operation: string;
|
|
13
|
+
data: Record<string, unknown>;
|
|
14
|
+
message?: string;
|
|
15
|
+
warnings?: string[];
|
|
16
|
+
errors?: string[];
|
|
17
|
+
next_steps?: string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Creates a tool result in the specified format
|
|
21
|
+
*/
|
|
22
|
+
export declare function makeFormattedResult(format: OutputFormat | undefined, structured: StructuredResult, markdownText: string, isError?: boolean): ToolResult;
|
|
23
|
+
/**
|
|
24
|
+
* Creates a simple text result (for backwards compatibility)
|
|
25
|
+
*/
|
|
26
|
+
export declare function makeResult(text: string, isError?: boolean): ToolResult;
|
|
27
|
+
/**
|
|
28
|
+
* Dry-run result wrapper
|
|
29
|
+
* Returns what would be generated without actually writing
|
|
30
|
+
*/
|
|
31
|
+
export interface DryRunFile {
|
|
32
|
+
path: string;
|
|
33
|
+
content: string;
|
|
34
|
+
operation: "create" | "update" | "skip";
|
|
35
|
+
reason?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface DryRunResult {
|
|
38
|
+
would_create: DryRunFile[];
|
|
39
|
+
would_update: DryRunFile[];
|
|
40
|
+
would_skip: DryRunFile[];
|
|
41
|
+
summary: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Formats a dry-run result
|
|
45
|
+
*/
|
|
46
|
+
export declare function makeDryRunResult(format: OutputFormat | undefined, dryRun: DryRunResult): ToolResult;
|
|
47
|
+
/**
|
|
48
|
+
* Helper to build structured result for common tool patterns
|
|
49
|
+
*/
|
|
50
|
+
export declare function buildStructuredResult(operation: string, data: Record<string, unknown>, options?: {
|
|
51
|
+
success?: boolean;
|
|
52
|
+
message?: string;
|
|
53
|
+
warnings?: string[];
|
|
54
|
+
errors?: string[];
|
|
55
|
+
next_steps?: string[];
|
|
56
|
+
}): StructuredResult;
|
|
57
|
+
//# sourceMappingURL=output-formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-formatter.d.ts","sourceRoot":"","sources":["../../src/services/output-formatter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,MAAM,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,GAAG,SAAS,EAChC,UAAU,EAAE,gBAAgB,EAC5B,YAAY,EAAE,MAAM,EACpB,OAAO,UAAQ,GACd,UAAU,CAcZ;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,UAAU,CAKpE;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,UAAU,EAAE,UAAU,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,YAAY,GAAG,SAAS,EAChC,MAAM,EAAE,YAAY,GACnB,UAAU,CA+CZ;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB,GACL,gBAAgB,CAUlB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatting utilities for ccboot tools
|
|
3
|
+
* Supports markdown (human-readable) and JSON (programmatic) output formats
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Creates a tool result in the specified format
|
|
7
|
+
*/
|
|
8
|
+
export function makeFormattedResult(format, structured, markdownText, isError = false) {
|
|
9
|
+
const effectiveFormat = format ?? "markdown";
|
|
10
|
+
if (effectiveFormat === "json") {
|
|
11
|
+
return {
|
|
12
|
+
content: [{ type: "text", text: JSON.stringify(structured, null, 2) }],
|
|
13
|
+
...(isError ? { isError: true } : {}),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
content: [{ type: "text", text: markdownText }],
|
|
18
|
+
...(isError ? { isError: true } : {}),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Creates a simple text result (for backwards compatibility)
|
|
23
|
+
*/
|
|
24
|
+
export function makeResult(text, isError = false) {
|
|
25
|
+
return {
|
|
26
|
+
content: [{ type: "text", text }],
|
|
27
|
+
...(isError ? { isError: true } : {}),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Formats a dry-run result
|
|
32
|
+
*/
|
|
33
|
+
export function makeDryRunResult(format, dryRun) {
|
|
34
|
+
const effectiveFormat = format ?? "markdown";
|
|
35
|
+
if (effectiveFormat === "json") {
|
|
36
|
+
return {
|
|
37
|
+
content: [{
|
|
38
|
+
type: "text",
|
|
39
|
+
text: JSON.stringify({
|
|
40
|
+
dry_run: true,
|
|
41
|
+
...dryRun,
|
|
42
|
+
}, null, 2),
|
|
43
|
+
}],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// Markdown format
|
|
47
|
+
let output = "DRY RUN — No files were written\n\n";
|
|
48
|
+
if (dryRun.would_create.length > 0) {
|
|
49
|
+
output += `── Would Create (${dryRun.would_create.length}) ──\n`;
|
|
50
|
+
for (const file of dryRun.would_create) {
|
|
51
|
+
output += ` + ${file.path}\n`;
|
|
52
|
+
}
|
|
53
|
+
output += "\n";
|
|
54
|
+
}
|
|
55
|
+
if (dryRun.would_update.length > 0) {
|
|
56
|
+
output += `── Would Update (${dryRun.would_update.length}) ──\n`;
|
|
57
|
+
for (const file of dryRun.would_update) {
|
|
58
|
+
output += ` ~ ${file.path}\n`;
|
|
59
|
+
}
|
|
60
|
+
output += "\n";
|
|
61
|
+
}
|
|
62
|
+
if (dryRun.would_skip.length > 0) {
|
|
63
|
+
output += `── Would Skip (${dryRun.would_skip.length}) ──\n`;
|
|
64
|
+
for (const file of dryRun.would_skip) {
|
|
65
|
+
output += ` - ${file.path}${file.reason ? ` (${file.reason})` : ""}\n`;
|
|
66
|
+
}
|
|
67
|
+
output += "\n";
|
|
68
|
+
}
|
|
69
|
+
output += `── Summary ──\n${dryRun.summary}`;
|
|
70
|
+
return {
|
|
71
|
+
content: [{ type: "text", text: output }],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Helper to build structured result for common tool patterns
|
|
76
|
+
*/
|
|
77
|
+
export function buildStructuredResult(operation, data, options = {}) {
|
|
78
|
+
return {
|
|
79
|
+
success: options.success ?? true,
|
|
80
|
+
operation,
|
|
81
|
+
data,
|
|
82
|
+
message: options.message,
|
|
83
|
+
warnings: options.warnings,
|
|
84
|
+
errors: options.errors,
|
|
85
|
+
next_steps: options.next_steps,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=output-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-formatter.js","sourceRoot":"","sources":["../../src/services/output-formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type AIPlatform = "claude-code" | "cursor" | "windsurf" | "codex";
|
|
2
|
+
export interface DetectedPlatforms {
|
|
3
|
+
platforms: AIPlatform[];
|
|
4
|
+
evidence: Record<AIPlatform, string>;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Detects which AI coding platforms are configured in a project.
|
|
8
|
+
*/
|
|
9
|
+
export declare function detectPlatforms(projectPath: string): Promise<DetectedPlatforms>;
|
|
10
|
+
/**
|
|
11
|
+
* Resolves "all" platform specifier to actual platforms.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolvePlatforms(projectPath: string, specified: string[]): Promise<AIPlatform[]>;
|
|
14
|
+
//# sourceMappingURL=platform-detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-detect.d.ts","sourceRoot":"","sources":["../../src/services/platform-detect.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAEzE,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,UAAU,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;CACtC;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAsCrF;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,UAAU,EAAE,CAAC,CAWvB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform detection for multi-AI-tool support.
|
|
3
|
+
*
|
|
4
|
+
* Detects which AI coding platforms are configured in a project:
|
|
5
|
+
* - Claude Code: .claude/ directory or CLAUDE.md
|
|
6
|
+
* - Cursor: .cursor/ directory or .cursorrules
|
|
7
|
+
* - Windsurf: .windsurf/ directory
|
|
8
|
+
* - Codex CLI: AGENTS.md
|
|
9
|
+
*/
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
import { fileExists } from "./file-ops.js";
|
|
12
|
+
/**
|
|
13
|
+
* Detects which AI coding platforms are configured in a project.
|
|
14
|
+
*/
|
|
15
|
+
export async function detectPlatforms(projectPath) {
|
|
16
|
+
const platforms = [];
|
|
17
|
+
const evidence = {};
|
|
18
|
+
// Claude Code: .claude/ directory or CLAUDE.md exists
|
|
19
|
+
if (await fileExists(path.join(projectPath, ".claude")) || await fileExists(path.join(projectPath, "CLAUDE.md"))) {
|
|
20
|
+
platforms.push("claude-code");
|
|
21
|
+
evidence["claude-code"] = "Found .claude/ directory or CLAUDE.md";
|
|
22
|
+
}
|
|
23
|
+
// Cursor: .cursor/ directory or .cursorrules exists
|
|
24
|
+
if (await fileExists(path.join(projectPath, ".cursor")) || await fileExists(path.join(projectPath, ".cursorrules"))) {
|
|
25
|
+
platforms.push("cursor");
|
|
26
|
+
evidence["cursor"] = "Found .cursor/ directory or .cursorrules";
|
|
27
|
+
}
|
|
28
|
+
// Windsurf: .windsurf/ directory exists
|
|
29
|
+
if (await fileExists(path.join(projectPath, ".windsurf"))) {
|
|
30
|
+
platforms.push("windsurf");
|
|
31
|
+
evidence["windsurf"] = "Found .windsurf/ directory";
|
|
32
|
+
}
|
|
33
|
+
// Codex: AGENTS.md exists
|
|
34
|
+
if (await fileExists(path.join(projectPath, "AGENTS.md"))) {
|
|
35
|
+
platforms.push("codex");
|
|
36
|
+
evidence["codex"] = "Found AGENTS.md";
|
|
37
|
+
}
|
|
38
|
+
// If nothing detected, default to Claude Code (since we're an MCP server running in it)
|
|
39
|
+
if (platforms.length === 0) {
|
|
40
|
+
platforms.push("claude-code");
|
|
41
|
+
evidence["claude-code"] = "Default (no platform detected)";
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
platforms,
|
|
45
|
+
evidence: evidence,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Resolves "all" platform specifier to actual platforms.
|
|
50
|
+
*/
|
|
51
|
+
export async function resolvePlatforms(projectPath, specified) {
|
|
52
|
+
if (specified.includes("all")) {
|
|
53
|
+
// Detect existing platforms, or generate for all if none found
|
|
54
|
+
const detected = await detectPlatforms(projectPath);
|
|
55
|
+
if (detected.platforms.length <= 1 && detected.evidence["claude-code"]?.includes("Default")) {
|
|
56
|
+
// Nothing detected, generate for all platforms
|
|
57
|
+
return ["claude-code", "cursor", "windsurf", "codex"];
|
|
58
|
+
}
|
|
59
|
+
return detected.platforms;
|
|
60
|
+
}
|
|
61
|
+
return specified.filter((p) => p !== "all");
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=platform-detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-detect.js","sourceRoot":"","sources":["../../src/services/platform-detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAS3C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,WAAmB;IACvD,MAAM,SAAS,GAAiB,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAwC,EAAE,CAAC;IAEzD,sDAAsD;IACtD,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QACjH,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC9B,QAAQ,CAAC,aAAa,CAAC,GAAG,uCAAuC,CAAC;IACpE,CAAC;IAED,oDAAoD;IACpD,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;QACpH,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzB,QAAQ,CAAC,QAAQ,CAAC,GAAG,0CAA0C,CAAC;IAClE,CAAC;IAED,wCAAwC;IACxC,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QAC1D,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3B,QAAQ,CAAC,UAAU,CAAC,GAAG,4BAA4B,CAAC;IACtD,CAAC;IAED,0BAA0B;IAC1B,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QAC1D,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,QAAQ,CAAC,OAAO,CAAC,GAAG,iBAAiB,CAAC;IACxC,CAAC;IAED,wFAAwF;IACxF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC9B,QAAQ,CAAC,aAAa,CAAC,GAAG,gCAAgC,CAAC;IAC7D,CAAC;IAED,OAAO;QACL,SAAS;QACT,QAAQ,EAAE,QAAsC;KACjD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,WAAmB,EACnB,SAAmB;IAEnB,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,+DAA+D;QAC/D,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;QACpD,IAAI,QAAQ,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5F,+CAA+C;YAC/C,OAAO,CAAC,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,QAAQ,CAAC,SAAS,CAAC;IAC5B,CAAC;IACD,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAiB,CAAC;AAC9D,CAAC"}
|