@teckedd-code2save/b2dp 1.0.1 → 1.0.3

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/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import figlet from "figlet";
6
6
  import pc5 from "picocolors";
7
7
 
8
8
  // src/constants.ts
9
- var VERSION = "1.0.1";
9
+ var VERSION = "1.0.3";
10
10
  var ORCHESTRATOR_SKILL = "business-to-data-platform";
11
11
  var ALL_SKILLS = [
12
12
  "business-to-data-platform",
@@ -158,10 +158,22 @@ async function detectAgents(scope) {
158
158
 
159
159
  // src/setup/skill-writer.ts
160
160
  import { readFile, writeFile } from "fs/promises";
161
+ import { existsSync } from "fs";
161
162
  import { join as join2, resolve, dirname } from "path";
162
163
  import { fileURLToPath } from "url";
163
164
  var __dirname = dirname(fileURLToPath(import.meta.url));
164
- var SKILLS_REPO_DIR = resolve(__dirname, "..", "..", "skills");
165
+ function findPackageRoot(startDir) {
166
+ let current = startDir;
167
+ while (current !== dirname(current)) {
168
+ if (existsSync(join2(current, "package.json"))) {
169
+ return current;
170
+ }
171
+ current = dirname(current);
172
+ }
173
+ return startDir;
174
+ }
175
+ var PACKAGE_ROOT = findPackageRoot(__dirname);
176
+ var SKILLS_REPO_DIR = resolve(PACKAGE_ROOT, "skills");
165
177
  async function readSkillFile(skill) {
166
178
  const skillPath = join2(SKILLS_REPO_DIR, skill, "SKILL.md");
167
179
  try {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/commands/setup.ts","../src/utils/logger.ts","../src/utils/fs.ts","../src/setup/agents.ts","../src/setup/skill-writer.ts","../src/setup/mcp-writer.ts","../src/setup/templates.ts","../src/commands/check.ts","../src/commands/skills.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport figlet from \"figlet\";\nimport pc from \"picocolors\";\n\nimport { VERSION } from \"./constants.js\";\nimport { registerSetupCommand } from \"./commands/setup.js\";\nimport { registerCheckCommand } from \"./commands/check.js\";\nimport { registerSkillsCommand } from \"./commands/skills.js\";\n\nfunction printBanner(): void {\n const banner = figlet.textSync(\"b2dp\", {\n font: \"Small\",\n horizontalLayout: \"default\",\n });\n console.log(pc.cyan(banner));\n console.log(\n pc.dim(\n \" Business-to-Data-Platform Orchestrator CLI — skill setup in one command\\n\"\n )\n );\n}\n\nconst program = new Command();\n\nprintBanner();\n\nprogram\n .name(\"b2dp\")\n .description(\n \"Set up the business-to-data-platform skill ecosystem for your AI coding agent\"\n )\n .version(VERSION, \"-v, --version\", \"Output the current version\");\n\nregisterSetupCommand(program);\nregisterCheckCommand(program);\nregisterSkillsCommand(program);\n\nprogram.parse(process.argv);\n","export const VERSION = \"1.0.1\";\n\nexport const SKILLS_DIR_NAME = \"skills\";\nexport const RULES_DIR_NAME = \"rules\";\n\nexport const ORCHESTRATOR_SKILL = \"business-to-data-platform\";\n\nexport const ALL_SKILLS = [\n \"business-to-data-platform\",\n \"cloud-solution-architect\",\n \"api-test-generator\",\n \"frontend-data-consumer\",\n \"frontend-design-review\",\n \"infrastructure-as-code-architect\",\n \"context7-mcp\",\n] as const;\n\nexport type SkillName = (typeof ALL_SKILLS)[number];\n\nexport const SKILL_DESCRIPTIONS: Record<SkillName, string> = {\n \"business-to-data-platform\":\n \"Orchestrator — converts any business spec into a production-grade data platform\",\n \"cloud-solution-architect\":\n \"Designs Docker/K8s + GitHub Actions cloud architectures\",\n \"api-test-generator\":\n \"Generates comprehensive integration tests for scaffolded backends\",\n \"frontend-data-consumer\":\n \"Scaffolds Vite/Next.js components with Tailwind CSS and Shadcn/UI\",\n \"frontend-design-review\":\n \"Reviews and creates distinctive, production-grade frontend interfaces\",\n \"infrastructure-as-code-architect\":\n \"Generates Dockerfiles, K8s manifests, and GitHub Actions workflows\",\n \"context7-mcp\":\n \"Fetches up-to-date docs and patterns for any library or framework\",\n};\n\nexport const RULE_FILENAME = \"b2dp.md\";\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport ora from \"ora\";\nimport { checkbox, input } from \"@inquirer/prompts\";\nimport { writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { log } from \"../utils/logger.js\";\nimport { ensureDir } from \"../utils/fs.js\";\nimport {\n type AgentName,\n ALL_AGENT_NAMES,\n AGENT_DISPLAY_NAMES,\n getAgent,\n detectAgents,\n} from \"../setup/agents.js\";\nimport {\n type SkillName,\n ALL_SKILLS,\n SKILL_DESCRIPTIONS,\n ORCHESTRATOR_SKILL,\n RULE_FILENAME,\n} from \"../constants.js\";\nimport { installSkills } from \"../setup/skill-writer.js\";\nimport {\n readJsonConfig,\n mergeServerEntry,\n writeJsonConfig,\n B2DP_MCP_SERVERS,\n} from \"../setup/mcp-writer.js\";\nimport { RULE_CONTENT } from \"../setup/templates.js\";\n\ninterface SetupOptions {\n antigravity?: boolean;\n claude?: boolean;\n cursor?: boolean;\n vscode?: boolean;\n gemini?: boolean;\n project?: boolean;\n yes?: boolean;\n}\n\nexport function registerSetupCommand(program: Command): void {\n program\n .command(\"setup\")\n .description(\"Set up the b2dp skill ecosystem for your AI coding agent\")\n .option(\"--antigravity\", \"Set up for Antigravity / Gemini CLI\")\n .option(\"--claude\", \"Set up for Claude Code\")\n .option(\"--cursor\", \"Set up for Cursor\")\n .option(\"--vscode\", \"Set up for VS Code (Copilot)\")\n .option(\"--gemini\", \"Set up for Gemini CLI\")\n .option(\n \"-p, --project\",\n \"Configure for current project only (default: global)\"\n )\n .option(\"-y, --yes\", \"Skip confirmation prompts, install everything\")\n .action(async (options: SetupOptions) => {\n await setupCommand(options);\n });\n}\n\nfunction getSelectedAgentsFromOptions(options: SetupOptions): AgentName[] {\n const agents: AgentName[] = [];\n if (options.antigravity) agents.push(\"antigravity\");\n if (options.claude) agents.push(\"claude\");\n if (options.cursor) agents.push(\"cursor\");\n if (options.vscode) agents.push(\"vscode\");\n if (options.gemini) agents.push(\"gemini\");\n return agents;\n}\n\nasync function resolveTargetAgents(\n options: SetupOptions,\n scope: \"project\" | \"global\"\n): Promise<AgentName[]> {\n let selected = getSelectedAgentsFromOptions(options);\n if (selected.length > 0) return selected;\n\n if (options.yes) {\n const spinner = ora(\"Detecting AI coding agents...\").start();\n selected = await detectAgents(scope);\n spinner.stop();\n if (selected.length === 0) {\n log.warn(\n \"No agents detected. Defaulting to Antigravity. Use a flag like --claude to target a specific agent.\"\n );\n return [\"antigravity\"];\n }\n log.info(\n `Auto-detected: ${selected.map((a) => AGENT_DISPLAY_NAMES[a]).join(\", \")}`\n );\n return selected;\n }\n\n const detected = await detectAgents(scope);\n const choices = ALL_AGENT_NAMES.map((name) => ({\n name: AGENT_DISPLAY_NAMES[name],\n value: name,\n checked: detected.includes(name),\n description: detected.includes(name) ? pc.dim(\"(detected)\") : \"\",\n }));\n\n return checkbox({\n message: \"Which AI coding agents should b2dp be set up for?\",\n choices,\n validate: (v) => (v.length > 0 ? true : \"Please select at least one agent.\"),\n });\n}\n\nasync function resolveTargetSkills(options: SetupOptions): Promise<SkillName[]> {\n if (options.yes) return [...ALL_SKILLS];\n\n const siblingSkills = ALL_SKILLS.filter((s) => s !== ORCHESTRATOR_SKILL);\n const choices = siblingSkills.map((skill) => ({\n name: `${skill}`,\n value: skill,\n checked: true,\n description: pc.dim(SKILL_DESCRIPTIONS[skill]),\n }));\n\n const picked = await checkbox<SkillName>({\n message:\n \"Which sibling skills should be installed? (orchestrator is always included)\",\n choices,\n });\n\n return [ORCHESTRATOR_SKILL, ...picked];\n}\n\nasync function resolveTargetMCPs(options: SetupOptions): Promise<string[]> {\n const allMcps = Object.keys(B2DP_MCP_SERVERS);\n if (options.yes) return allMcps.filter((m) => m !== \"redis\");\n\n const choices = allMcps.map((name) => ({\n name,\n value: name,\n checked: name !== \"redis\",\n }));\n\n return checkbox({\n message: \"Which MCP servers should be installed?\",\n choices,\n });\n}\n\nasync function installSkillFiles(skills: SkillName[], skillsDir: string) {\n const skillSpinner = ora(`Installing ${skills.length} skills...`).start();\n try {\n const results = await installSkills(skills, skillsDir);\n skillSpinner.stop();\n for (const r of results) {\n const prefix = r.alreadyExisted ? pc.dim(\"(updated) \") : \"\";\n log.success(`${prefix}${r.skill} → ${r.targetPath}`);\n }\n } catch (err) {\n skillSpinner.fail(\"Failed to install skills\");\n log.error(err instanceof Error ? err.message : String(err));\n }\n}\n\nasync function configureMCPServers(\n agent: Record<string, any>,\n mcpConfigPath: string,\n selectedMcps: string[],\n env: Record<string, string>\n) {\n const mcpSpinner = ora(\"Writing MCP server entries...\").start();\n try {\n const config = await readJsonConfig(mcpConfigPath);\n let updatedConfig = config;\n\n for (const serverName of selectedMcps) {\n const baseEntry = B2DP_MCP_SERVERS[serverName];\n const entry = { ...baseEntry };\n\n // Apply specific env vars to specific servers\n if (\n serverName === \"github-mcp-server\" &&\n env.GITHUB_PERSONAL_ACCESS_TOKEN\n ) {\n entry.env = {\n ...(entry.env as Record<string, string>),\n GITHUB_PERSONAL_ACCESS_TOKEN: env.GITHUB_PERSONAL_ACCESS_TOKEN,\n };\n }\n\n if (serverName === \"context7\" && env.CONTEXT7_API_KEY) {\n entry.args = [\n ...(entry.args as string[]),\n \"--api-key\",\n env.CONTEXT7_API_KEY,\n ];\n }\n\n const { config: merged, alreadyExists } = mergeServerEntry(\n updatedConfig,\n agent.mcpConfigKey,\n serverName,\n entry\n );\n updatedConfig = merged;\n if (!alreadyExists) {\n mcpSpinner.text = `Added MCP: ${serverName}`;\n }\n }\n\n await writeJsonConfig(mcpConfigPath, updatedConfig);\n mcpSpinner.succeed(`MCP config written → ${mcpConfigPath}`);\n } catch (err) {\n mcpSpinner.fail(\"Failed to write MCP config\");\n log.error(err instanceof Error ? err.message : String(err));\n }\n}\n\nasync function writeRuleFile(rulesDir: string) {\n const rulesSpinner = ora(\"Writing b2dp rule file...\").start();\n try {\n await ensureDir(rulesDir);\n const rulePath = join(rulesDir, RULE_FILENAME);\n await writeFile(rulePath, RULE_CONTENT, \"utf-8\");\n rulesSpinner.succeed(`Rule written → ${rulePath}`);\n } catch (err) {\n rulesSpinner.fail(\"Failed to write rule file\");\n log.error(err instanceof Error ? err.message : String(err));\n }\n}\n\nasync function setupAgent(\n agentName: AgentName,\n scope: \"project\" | \"global\",\n skills: SkillName[],\n selectedMcps: string[],\n env: Record<string, string>\n) {\n const agent = getAgent(agentName);\n log.info(pc.bold(`Setting up ${agent.displayName}...`));\n\n const skillsDir = agent.skillsDir(scope);\n const rulesDir = agent.rulesDir(scope);\n const mcpConfigPath = agent.mcpConfigPath(scope);\n\n await installSkillFiles(skills, skillsDir);\n await configureMCPServers(agent, mcpConfigPath, selectedMcps, env);\n await writeRuleFile(rulesDir);\n\n log.blank();\n}\n\nasync function setupCommand(options: SetupOptions): Promise<void> {\n const scope: \"project\" | \"global\" = options.project ? \"project\" : \"global\";\n\n const selectedAgents = await resolveTargetAgents(options, scope);\n const selectedSkills = await resolveTargetSkills(options);\n const selectedMcps = await resolveTargetMCPs(options);\n\n // Ask for keys if not in -y mode\n const env: Record<string, string> = {};\n if (!options.yes) {\n log.blank();\n log.info(pc.yellow(\"Interactive Configuration:\"));\n\n if (selectedMcps.includes(\"github-mcp-server\")) {\n const githubToken = await input({\n message: \"GitHub Personal Access Token (for github-mcp-server):\",\n transformer: (val) => (val ? \"*\".repeat(val.length) : val),\n });\n if (githubToken) {\n env[\"GITHUB_PERSONAL_ACCESS_TOKEN\"] = githubToken;\n }\n }\n\n if (selectedMcps.includes(\"context7\")) {\n const context7Key = await input({\n message: \"Context7 API Key (for context7):\",\n transformer: (val) => (val ? \"*\".repeat(val.length) : val),\n });\n if (context7Key) {\n env[\"CONTEXT7_API_KEY\"] = context7Key;\n }\n }\n }\n\n log.blank();\n\n for (const agentName of selectedAgents) {\n await setupAgent(agentName, scope, selectedSkills, selectedMcps, env);\n }\n\n log.success(pc.bold(\"b2dp setup complete! 🚀\"));\n log.blank();\n log.dim(\"Next steps:\");\n log.dim(\" 1. Edit your MCP config(s) to fill in the Datafy dbhub.toml path\");\n log.dim(\" (usually ~/Documents/.../datafy/dbhub.toml)\");\n log.dim(\" 2. Restart your AI agent to pick up the new skills and MCP servers.\");\n log.dim(\n ' 3. Try: \"Build me a SaaS platform for team task management\" in your agent.'\n );\n log.blank();\n log.dim(\"Run `b2dp check` to verify your MCP configuration at any time.\");\n}\n","import pc from \"picocolors\";\n\nexport const log = {\n info: (msg: string) => console.log(`${pc.cyan(\"ℹ\")} ${msg}`),\n success: (msg: string) => console.log(`${pc.green(\"✔\")} ${msg}`),\n warn: (msg: string) => console.log(`${pc.yellow(\"⚠\")} ${msg}`),\n error: (msg: string) => console.error(`${pc.red(\"✖\")} ${msg}`),\n dim: (msg: string) => console.log(pc.dim(msg)),\n blank: () => console.log(\"\"),\n};\n","import { access, mkdir } from \"fs/promises\";\n\nexport async function pathExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await mkdir(dir, { recursive: true });\n}\n","import { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { pathExists } from \"../utils/fs.js\";\n\nexport type AgentName = \"antigravity\" | \"claude\" | \"cursor\" | \"vscode\" | \"gemini\";\n\nexport interface AgentConfig {\n name: AgentName;\n displayName: string;\n skillsDir: (scope: \"project\" | \"global\") => string;\n rulesDir: (scope: \"project\" | \"global\") => string;\n mcpConfigPath: (scope: \"project\" | \"global\") => string;\n mcpConfigKey: string;\n detect: {\n projectPaths: string[];\n globalPaths: string[];\n };\n}\n\nconst agents: Record<AgentName, AgentConfig> = {\n // Antigravity / Gemini CLI — ~/.gemini/antigravity/\n antigravity: {\n name: \"antigravity\",\n displayName: \"Antigravity (Gemini CLI)\",\n skillsDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".gemini\", \"antigravity\", \"skills\")\n : join(\".agent\", \"skills\"),\n rulesDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".gemini\", \"antigravity\", \"rules\")\n : join(\".agent\", \"rules\"),\n mcpConfigPath: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".gemini\", \"antigravity\", \"mcp_config.json\")\n : join(\".agent\", \"mcp_config.json\"),\n mcpConfigKey: \"mcpServers\",\n detect: {\n projectPaths: [\".agent\"],\n globalPaths: [join(homedir(), \".gemini\", \"antigravity\")],\n },\n },\n\n // Claude Code — ~/.claude/\n claude: {\n name: \"claude\",\n displayName: \"Claude Code\",\n skillsDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".claude\", \"skills\")\n : join(\".claude\", \"skills\"),\n rulesDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".claude\", \"rules\")\n : join(\".claude\", \"rules\"),\n mcpConfigPath: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".claude.json\")\n : join(\".mcp.json\"),\n mcpConfigKey: \"mcpServers\",\n detect: {\n projectPaths: [\".mcp.json\", \".claude\"],\n globalPaths: [join(homedir(), \".claude\")],\n },\n },\n\n // Cursor — ~/.cursor/\n cursor: {\n name: \"cursor\",\n displayName: \"Cursor\",\n skillsDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".cursor\", \"skills\")\n : join(\".cursor\", \"skills\"),\n rulesDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".cursor\", \"rules\")\n : join(\".cursor\", \"rules\"),\n mcpConfigPath: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".cursor\", \"mcp.json\")\n : join(\".cursor\", \"mcp.json\"),\n mcpConfigKey: \"mcpServers\",\n detect: {\n projectPaths: [\".cursor\"],\n globalPaths: [join(homedir(), \".cursor\")],\n },\n },\n\n // VS Code — uses .vscode/ for project-level config\n vscode: {\n name: \"vscode\",\n displayName: \"VS Code (Copilot)\",\n skillsDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".vscode\", \"skills\")\n : join(\".vscode\", \"skills\"),\n rulesDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".vscode\", \"rules\")\n : join(\".vscode\", \"rules\"),\n mcpConfigPath: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".vscode\", \"mcp.json\")\n : join(\".vscode\", \"mcp.json\"),\n mcpConfigKey: \"servers\",\n detect: {\n projectPaths: [\".vscode\"],\n globalPaths: [join(homedir(), \".vscode\")],\n },\n },\n\n // Gemini CLI — ~/.gemini/settings.json\n gemini: {\n name: \"gemini\",\n displayName: \"Gemini CLI\",\n skillsDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".gemini\", \"skills\")\n : join(\".agent\", \"skills\"),\n rulesDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".gemini\", \"rules\")\n : join(\".agent\", \"rules\"),\n mcpConfigPath: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".gemini\", \"settings.json\")\n : join(\".agent\", \"settings.json\"),\n mcpConfigKey: \"mcpServers\",\n detect: {\n projectPaths: [\".agent\"],\n globalPaths: [join(homedir(), \".gemini\", \"settings.json\")],\n },\n },\n};\n\nexport function getAgent(name: AgentName): AgentConfig {\n return agents[name];\n}\n\nexport const ALL_AGENT_NAMES = Object.keys(agents) as AgentName[];\n\nexport const AGENT_DISPLAY_NAMES: Record<AgentName, string> = {\n antigravity: \"Antigravity (Gemini CLI)\",\n claude: \"Claude Code\",\n cursor: \"Cursor\",\n vscode: \"VS Code (Copilot)\",\n gemini: \"Gemini CLI\",\n};\n\nexport async function detectAgents(\n scope: \"project\" | \"global\"\n): Promise<AgentName[]> {\n const detected: AgentName[] = [];\n for (const name of ALL_AGENT_NAMES) {\n const agent = agents[name];\n const paths =\n scope === \"project\" ? agent.detect.projectPaths : agent.detect.globalPaths;\n for (const p of paths) {\n if (await pathExists(p)) {\n detected.push(name);\n break;\n }\n }\n }\n return detected;\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join, resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { ensureDir, pathExists } from \"../utils/fs.js\";\nimport { type SkillName, ALL_SKILLS } from \"../constants.js\";\n\n// After tsup bundles src/ → dist/index.js, __dirname === cli/dist/\n// The skills/ directory lives at cli/../skills (one level up from cli/)\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst SKILLS_REPO_DIR = resolve(__dirname, \"..\", \"..\", \"skills\");\n\nexport interface InstallResult {\n skill: SkillName;\n targetPath: string;\n alreadyExisted: boolean;\n}\n\n/**\n * Read the SKILL.md for a given skill name from the local skills/ directory.\n */\nexport async function readSkillFile(skill: SkillName): Promise<string | null> {\n const skillPath = join(SKILLS_REPO_DIR, skill, \"SKILL.md\");\n try {\n return await readFile(skillPath, \"utf-8\");\n } catch {\n return null;\n }\n}\n\n/**\n * Install a single skill into the target directory.\n * Creates <targetDir>/<skillName>/SKILL.md\n */\nexport async function installSkill(\n skill: SkillName,\n targetDir: string\n): Promise<InstallResult> {\n const skillDir = join(targetDir, skill);\n const targetPath = join(skillDir, \"SKILL.md\");\n\n const alreadyExisted = await pathExists(targetPath);\n const content = await readSkillFile(skill);\n\n if (!content) {\n throw new Error(`Could not read SKILL.md for skill: ${skill}`);\n }\n\n if (alreadyExisted) {\n const existingContent = await readFile(targetPath, \"utf-8\");\n if (existingContent === content) {\n return { skill, targetPath, alreadyExisted: true };\n }\n }\n\n await ensureDir(skillDir);\n await writeFile(targetPath, content, \"utf-8\");\n\n return { skill, targetPath, alreadyExisted };\n}\n\n/**\n * Install multiple skills into the target directory.\n */\nexport async function installSkills(\n skills: SkillName[],\n targetDir: string\n): Promise<InstallResult[]> {\n const results: InstallResult[] = [];\n for (const skill of skills) {\n const result = await installSkill(skill, targetDir);\n results.push(result);\n }\n return results;\n}\n\n/**\n * Get which skills are available in the local skills/ directory.\n */\nexport async function getAvailableSkills(): Promise<\n { name: SkillName; available: boolean }[]\n> {\n return Promise.all(\n ALL_SKILLS.map(async (skill) => ({\n name: skill,\n available: await pathExists(join(SKILLS_REPO_DIR, skill, \"SKILL.md\")),\n }))\n );\n}\n\n/**\n * Extract the description line from a SKILL.md frontmatter.\n */\nexport function parseSkillDescription(content: string): string | null {\n const match = /^description:\\s*[>|]?\\s*\\n?([\\s\\S]*?)(?=\\n\\w|\\n---)/m.exec(content);\n if (!match) return null;\n return match[1]\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean)\n .join(\" \")\n .slice(0, 120);\n}\n","import { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nexport async function readJsonConfig(\n filePath: string\n): Promise<Record<string, unknown>> {\n let raw: string;\n try {\n raw = await readFile(filePath, \"utf-8\");\n } catch {\n return {};\n }\n raw = raw.trim();\n if (!raw) return {};\n return JSON.parse(raw) as Record<string, unknown>;\n}\n\nexport function mergeServerEntry(\n existing: Record<string, unknown>,\n configKey: string,\n serverName: string,\n entry: Record<string, unknown>\n): { config: Record<string, unknown>; alreadyExists: boolean } {\n const section =\n (existing[configKey] as Record<string, unknown> | undefined) ?? {};\n\n // If server already exists, we might still want to merge env vars if they were empty\n if (serverName in section) {\n const existingEntry = section[serverName] as Record<string, any>;\n const newEnv = (entry.env as Record<string, string>) ?? {};\n const existingEnv = (existingEntry.env as Record<string, string>) ?? {};\n\n let envChanged = false;\n for (const [key, value] of Object.entries(newEnv)) {\n if (value && existingEnv[key] !== value) {\n existingEnv[key] = value;\n envChanged = true;\n }\n }\n\n if (!envChanged) {\n return { config: existing, alreadyExists: true };\n }\n\n return {\n config: {\n ...existing,\n [configKey]: {\n ...section,\n [serverName]: { ...existingEntry, env: existingEnv },\n },\n },\n alreadyExists: true,\n };\n }\n\n return {\n config: {\n ...existing,\n [configKey]: { ...section, [serverName]: entry },\n },\n alreadyExists: false,\n };\n}\n\nexport async function writeJsonConfig(\n filePath: string,\n config: Record<string, unknown>\n): Promise<void> {\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, JSON.stringify(config, null, 2) + \"\\n\", \"utf-8\");\n}\n\n/** MCP server entries for the b2dp ecosystem */\nexport const B2DP_MCP_SERVERS: Record<string, Record<string, unknown>> = {\n datafy: {\n command: \"npx\",\n args: [\n \"@teckedd-code2save/datafy@latest\",\n \"--config\",\n \"/path/to/your/dbhub.toml\",\n \"--transport\",\n \"stdio\",\n ],\n },\n \"prisma-mcp-server\": {\n command: \"npx\",\n args: [\"-y\", \"prisma\", \"mcp\"],\n },\n \"github-mcp-server\": {\n command: \"docker\",\n args: [\n \"run\",\n \"-i\",\n \"--rm\",\n \"-e\",\n \"GITHUB_PERSONAL_ACCESS_TOKEN\",\n \"ghcr.io/github/github-mcp-server\",\n ],\n env: {\n GITHUB_PERSONAL_ACCESS_TOKEN: \"\",\n },\n },\n context7: {\n command: \"npx\",\n args: [\"-y\", \"@upstash/context7-mcp\"],\n },\n redis: {\n command: \"npx\",\n args: [\"-y\", \"@modelcontextprotocol/server-redis\"],\n env: {\n REDIS_URL: \"\",\n },\n },\n};\n","export const RULE_CONTENT = `---\nalwaysApply: true\n---\n\n# Business-to-Data-Platform Orchestrator\n\nThis project uses the **business-to-data-platform** skill as the central orchestrator. When building any backend feature, database schema, or data-driven system:\n\n1. **Invoke \\`business-to-data-platform\\`** as the primary skill — it drives architecture design, schema creation, ORM setup, testing, frontend scaffolding, and infra provisioning.\n2. **Never hardcode data in UI components.** All data must come from real DB queries or API endpoints.\n3. **Always use Datafy MCP** for database operations — never raw psql in the terminal.\n4. **Follow the 12-step workflow** defined in the orchestrator skill — from architecture design through infrastructure provisioning.\n\n## Required MCPs for the full stack\n- **datafy** — DB operations, SQL execution, code generation\n- **prisma-mcp-server** — migrations and DB exploration\n- **github-mcp-server** — repo discovery, CI/CD setup\n- **context7** — up-to-date docs and patterns for any library\n\n## Sibling skills that get invoked automatically\n- \\`cloud-solution-architect\\` → Docker/K8s architecture\n- \\`api-test-generator\\` → integration tests\n- \\`frontend-data-consumer\\` → Vite/Next.js UI components\n- \\`infrastructure-as-code-architect\\` → Dockerfiles, K8s manifests, GitHub Actions\n`;\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport ora from \"ora\";\n\nimport { log } from \"../utils/logger.js\";\nimport {\n type AgentName,\n ALL_AGENT_NAMES,\n AGENT_DISPLAY_NAMES,\n getAgent,\n} from \"../setup/agents.js\";\nimport { readJsonConfig } from \"../setup/mcp-writer.js\";\nimport { B2DP_MCP_SERVERS } from \"../setup/mcp-writer.js\";\n\nconst REQUIRED_MCPS = [\"datafy\", \"prisma-mcp-server\", \"github-mcp-server\", \"context7\"];\n\ninterface CheckOptions {\n project?: boolean;\n}\n\nexport function registerCheckCommand(program: Command): void {\n program\n .command(\"check\")\n .description(\n \"Verify that the b2dp MCP servers are configured for your AI coding agents\"\n )\n .option(\"-p, --project\", \"Check project-level config instead of global\")\n .action(async (options: CheckOptions) => {\n await checkCommand(options);\n });\n}\n\nasync function checkCommand(options: CheckOptions): Promise<void> {\n const scope: \"project\" | \"global\" = options.project ? \"project\" : \"global\";\n\n log.info(\n pc.bold(`Checking b2dp MCP configuration (${scope} scope)...`)\n );\n log.blank();\n\n let anyAgentFound = false;\n\n for (const agentName of ALL_AGENT_NAMES as AgentName[]) {\n const agent = getAgent(agentName);\n const mcpConfigPath = agent.mcpConfigPath(scope);\n\n const spinner = ora(\n `Reading ${agent.displayName} config...`\n ).start();\n\n let config: Record<string, unknown>;\n try {\n config = await readJsonConfig(mcpConfigPath);\n } catch {\n spinner.warn(`${agent.displayName}: config not readable (${mcpConfigPath})`);\n continue;\n }\n\n const servers = (\n config[agent.mcpConfigKey] as Record<string, unknown> | undefined\n ) ?? {};\n\n if (Object.keys(servers).length === 0 && Object.keys(config).length === 0) {\n spinner.warn(\n `${agent.displayName}: no config found at ${mcpConfigPath}`\n );\n continue;\n }\n\n spinner.stop();\n anyAgentFound = true;\n\n console.log(pc.bold(`\\n ${agent.displayName}`));\n console.log(pc.dim(` ${mcpConfigPath}`));\n\n for (const mcp of REQUIRED_MCPS) {\n const isPresent = mcp in servers;\n const entry = servers[mcp] as Record<string, unknown> | undefined;\n\n // Check for unfilled placeholders\n const hasPlaceholder =\n isPresent &&\n JSON.stringify(entry).includes(\"/path/to/your/dbhub.toml\");\n\n const icon = !isPresent\n ? pc.red(\"✖\")\n : hasPlaceholder\n ? pc.yellow(\"⚠\")\n : pc.green(\"✔\");\n\n const note = !isPresent\n ? pc.dim(\" (missing — run `b2dp setup` to add)\")\n : hasPlaceholder\n ? pc.yellow(\" (needs dbhub.toml path filled in)\")\n : pc.dim(\" (configured)\");\n\n console.log(` ${icon} ${mcp}${note}`);\n }\n\n // Check for optional MCPs from b2dp ecosystem\n const optionalMcps = Object.keys(B2DP_MCP_SERVERS).filter(\n (s) => !REQUIRED_MCPS.includes(s)\n );\n for (const mcp of optionalMcps) {\n const isPresent = mcp in servers;\n const icon = isPresent ? pc.green(\"✔\") : pc.dim(\"○\");\n const label = isPresent ? pc.dim(\" (configured)\") : pc.dim(\" (optional, not set)\");\n console.log(` ${icon} ${pc.dim(mcp)}${label}`);\n }\n }\n\n log.blank();\n\n if (!anyAgentFound) {\n log.warn(\n \"No agent configs found. Run `b2dp setup` to install the b2dp skill ecosystem.\"\n );\n } else {\n log.dim(\"Run `b2dp setup` to add any missing MCPs or reinstall skills.\");\n }\n}\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\n\nimport { log } from \"../utils/logger.js\";\nimport { ALL_SKILLS, SKILL_DESCRIPTIONS, ORCHESTRATOR_SKILL } from \"../constants.js\";\nimport {\n getAvailableSkills,\n readSkillFile,\n parseSkillDescription,\n} from \"../setup/skill-writer.js\";\n\nexport function registerSkillsCommand(program: Command): void {\n const skills = program\n .command(\"skills\")\n .description(\"Manage b2dp skills\");\n\n // b2dp skills list\n skills\n .command(\"list\")\n .description(\"List all available b2dp skills\")\n .action(async () => {\n await listSkillsCommand();\n });\n\n // b2dp skills info <name>\n skills\n .command(\"info <skillName>\")\n .description(\"Show details about a specific skill\")\n .action(async (skillName: string) => {\n await infoSkillCommand(skillName);\n });\n}\n\nasync function listSkillsCommand(): Promise<void> {\n log.blank();\n console.log(pc.bold(\"Available b2dp skills:\"));\n log.blank();\n\n const available = await getAvailableSkills();\n\n for (const { name, available: isAvailable } of available) {\n const isOrchestrator = name === ORCHESTRATOR_SKILL;\n const statusIcon = isAvailable ? pc.green(\"✔\") : pc.red(\"✖\");\n const label = isOrchestrator\n ? pc.bold(pc.cyan(name)) + pc.cyan(\" (orchestrator)\")\n : pc.white(name);\n const desc = pc.dim(SKILL_DESCRIPTIONS[name]);\n const missing = isAvailable ? \"\" : pc.red(\" [SKILL.md not found]\");\n\n console.log(` ${statusIcon} ${label}${missing}`);\n console.log(` ${desc}`);\n log.blank();\n }\n\n const availableCount = available.filter((s) => s.available).length;\n log.dim(\n `${availableCount}/${ALL_SKILLS.length} skills available locally.`\n );\n log.dim(\n \"Run `b2dp setup` to install all skills into your AI coding agent.\"\n );\n}\n\nasync function infoSkillCommand(skillName: string): Promise<void> {\n const validSkill = ALL_SKILLS.find((s) => s === skillName);\n if (!validSkill) {\n log.error(\n `Unknown skill: \"${skillName}\". Run \\`b2dp skills list\\` to see available skills.`\n );\n process.exit(1);\n }\n\n const content = await readSkillFile(validSkill);\n if (!content) {\n log.error(\n `SKILL.md not found for \"${validSkill}\". Ensure the skills/ directory is intact.`\n );\n process.exit(1);\n }\n\n const description = parseSkillDescription(content) ?? SKILL_DESCRIPTIONS[validSkill];\n const isOrchestrator = validSkill === ORCHESTRATOR_SKILL;\n\n log.blank();\n console.log(\n pc.bold(\n isOrchestrator ? pc.cyan(`${validSkill} (orchestrator)`) : pc.white(validSkill)\n )\n );\n log.blank();\n console.log(` ${pc.dim(description)}`);\n log.blank();\n\n // Count lines in the SKILL.md as a rough size indicator\n const lineCount = content.split(\"\\n\").length;\n log.dim(` ${lineCount} lines · SKILL.md`);\n log.blank();\n\n log.dim(\n `Install with: b2dp setup --yes (or select it during interactive setup)`\n );\n}\n"],"mappings":"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","names":["pc","pc","writeFile","join","join","join","readFile","writeFile","mkdir","dirname","program","agents","pc","join","writeFile","pc","ora","program","pc","ora","pc","program","pc","pc"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/commands/setup.ts","../src/utils/logger.ts","../src/utils/fs.ts","../src/setup/agents.ts","../src/setup/skill-writer.ts","../src/setup/mcp-writer.ts","../src/setup/templates.ts","../src/commands/check.ts","../src/commands/skills.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport figlet from \"figlet\";\nimport pc from \"picocolors\";\n\nimport { VERSION } from \"./constants.js\";\nimport { registerSetupCommand } from \"./commands/setup.js\";\nimport { registerCheckCommand } from \"./commands/check.js\";\nimport { registerSkillsCommand } from \"./commands/skills.js\";\n\nfunction printBanner(): void {\n const banner = figlet.textSync(\"b2dp\", {\n font: \"Small\",\n horizontalLayout: \"default\",\n });\n console.log(pc.cyan(banner));\n console.log(\n pc.dim(\n \" Business-to-Data-Platform Orchestrator CLI — skill setup in one command\\n\"\n )\n );\n}\n\nconst program = new Command();\n\nprintBanner();\n\nprogram\n .name(\"b2dp\")\n .description(\n \"Set up the business-to-data-platform skill ecosystem for your AI coding agent\"\n )\n .version(VERSION, \"-v, --version\", \"Output the current version\");\n\nregisterSetupCommand(program);\nregisterCheckCommand(program);\nregisterSkillsCommand(program);\n\nprogram.parse(process.argv);\n","export const VERSION = \"1.0.3\";\n\nexport const SKILLS_DIR_NAME = \"skills\";\nexport const RULES_DIR_NAME = \"rules\";\n\nexport const ORCHESTRATOR_SKILL = \"business-to-data-platform\";\n\nexport const ALL_SKILLS = [\n \"business-to-data-platform\",\n \"cloud-solution-architect\",\n \"api-test-generator\",\n \"frontend-data-consumer\",\n \"frontend-design-review\",\n \"infrastructure-as-code-architect\",\n \"context7-mcp\",\n] as const;\n\nexport type SkillName = (typeof ALL_SKILLS)[number];\n\nexport const SKILL_DESCRIPTIONS: Record<SkillName, string> = {\n \"business-to-data-platform\":\n \"Orchestrator — converts any business spec into a production-grade data platform\",\n \"cloud-solution-architect\":\n \"Designs Docker/K8s + GitHub Actions cloud architectures\",\n \"api-test-generator\":\n \"Generates comprehensive integration tests for scaffolded backends\",\n \"frontend-data-consumer\":\n \"Scaffolds Vite/Next.js components with Tailwind CSS and Shadcn/UI\",\n \"frontend-design-review\":\n \"Reviews and creates distinctive, production-grade frontend interfaces\",\n \"infrastructure-as-code-architect\":\n \"Generates Dockerfiles, K8s manifests, and GitHub Actions workflows\",\n \"context7-mcp\":\n \"Fetches up-to-date docs and patterns for any library or framework\",\n};\n\nexport const RULE_FILENAME = \"b2dp.md\";\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport ora from \"ora\";\nimport { checkbox, input } from \"@inquirer/prompts\";\nimport { writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { log } from \"../utils/logger.js\";\nimport { ensureDir } from \"../utils/fs.js\";\nimport {\n type AgentName,\n ALL_AGENT_NAMES,\n AGENT_DISPLAY_NAMES,\n getAgent,\n detectAgents,\n} from \"../setup/agents.js\";\nimport {\n type SkillName,\n ALL_SKILLS,\n SKILL_DESCRIPTIONS,\n ORCHESTRATOR_SKILL,\n RULE_FILENAME,\n} from \"../constants.js\";\nimport { installSkills } from \"../setup/skill-writer.js\";\nimport {\n readJsonConfig,\n mergeServerEntry,\n writeJsonConfig,\n B2DP_MCP_SERVERS,\n} from \"../setup/mcp-writer.js\";\nimport { RULE_CONTENT } from \"../setup/templates.js\";\n\ninterface SetupOptions {\n antigravity?: boolean;\n claude?: boolean;\n cursor?: boolean;\n vscode?: boolean;\n gemini?: boolean;\n project?: boolean;\n yes?: boolean;\n}\n\nexport function registerSetupCommand(program: Command): void {\n program\n .command(\"setup\")\n .description(\"Set up the b2dp skill ecosystem for your AI coding agent\")\n .option(\"--antigravity\", \"Set up for Antigravity / Gemini CLI\")\n .option(\"--claude\", \"Set up for Claude Code\")\n .option(\"--cursor\", \"Set up for Cursor\")\n .option(\"--vscode\", \"Set up for VS Code (Copilot)\")\n .option(\"--gemini\", \"Set up for Gemini CLI\")\n .option(\n \"-p, --project\",\n \"Configure for current project only (default: global)\"\n )\n .option(\"-y, --yes\", \"Skip confirmation prompts, install everything\")\n .action(async (options: SetupOptions) => {\n await setupCommand(options);\n });\n}\n\nfunction getSelectedAgentsFromOptions(options: SetupOptions): AgentName[] {\n const agents: AgentName[] = [];\n if (options.antigravity) agents.push(\"antigravity\");\n if (options.claude) agents.push(\"claude\");\n if (options.cursor) agents.push(\"cursor\");\n if (options.vscode) agents.push(\"vscode\");\n if (options.gemini) agents.push(\"gemini\");\n return agents;\n}\n\nasync function resolveTargetAgents(\n options: SetupOptions,\n scope: \"project\" | \"global\"\n): Promise<AgentName[]> {\n let selected = getSelectedAgentsFromOptions(options);\n if (selected.length > 0) return selected;\n\n if (options.yes) {\n const spinner = ora(\"Detecting AI coding agents...\").start();\n selected = await detectAgents(scope);\n spinner.stop();\n if (selected.length === 0) {\n log.warn(\n \"No agents detected. Defaulting to Antigravity. Use a flag like --claude to target a specific agent.\"\n );\n return [\"antigravity\"];\n }\n log.info(\n `Auto-detected: ${selected.map((a) => AGENT_DISPLAY_NAMES[a]).join(\", \")}`\n );\n return selected;\n }\n\n const detected = await detectAgents(scope);\n const choices = ALL_AGENT_NAMES.map((name) => ({\n name: AGENT_DISPLAY_NAMES[name],\n value: name,\n checked: detected.includes(name),\n description: detected.includes(name) ? pc.dim(\"(detected)\") : \"\",\n }));\n\n return checkbox({\n message: \"Which AI coding agents should b2dp be set up for?\",\n choices,\n validate: (v) => (v.length > 0 ? true : \"Please select at least one agent.\"),\n });\n}\n\nasync function resolveTargetSkills(options: SetupOptions): Promise<SkillName[]> {\n if (options.yes) return [...ALL_SKILLS];\n\n const siblingSkills = ALL_SKILLS.filter((s) => s !== ORCHESTRATOR_SKILL);\n const choices = siblingSkills.map((skill) => ({\n name: `${skill}`,\n value: skill,\n checked: true,\n description: pc.dim(SKILL_DESCRIPTIONS[skill]),\n }));\n\n const picked = await checkbox<SkillName>({\n message:\n \"Which sibling skills should be installed? (orchestrator is always included)\",\n choices,\n });\n\n return [ORCHESTRATOR_SKILL, ...picked];\n}\n\nasync function resolveTargetMCPs(options: SetupOptions): Promise<string[]> {\n const allMcps = Object.keys(B2DP_MCP_SERVERS);\n if (options.yes) return allMcps.filter((m) => m !== \"redis\");\n\n const choices = allMcps.map((name) => ({\n name,\n value: name,\n checked: name !== \"redis\",\n }));\n\n return checkbox({\n message: \"Which MCP servers should be installed?\",\n choices,\n });\n}\n\nasync function installSkillFiles(skills: SkillName[], skillsDir: string) {\n const skillSpinner = ora(`Installing ${skills.length} skills...`).start();\n try {\n const results = await installSkills(skills, skillsDir);\n skillSpinner.stop();\n for (const r of results) {\n const prefix = r.alreadyExisted ? pc.dim(\"(updated) \") : \"\";\n log.success(`${prefix}${r.skill} → ${r.targetPath}`);\n }\n } catch (err) {\n skillSpinner.fail(\"Failed to install skills\");\n log.error(err instanceof Error ? err.message : String(err));\n }\n}\n\nasync function configureMCPServers(\n agent: Record<string, any>,\n mcpConfigPath: string,\n selectedMcps: string[],\n env: Record<string, string>\n) {\n const mcpSpinner = ora(\"Writing MCP server entries...\").start();\n try {\n const config = await readJsonConfig(mcpConfigPath);\n let updatedConfig = config;\n\n for (const serverName of selectedMcps) {\n const baseEntry = B2DP_MCP_SERVERS[serverName];\n const entry = { ...baseEntry };\n\n // Apply specific env vars to specific servers\n if (\n serverName === \"github-mcp-server\" &&\n env.GITHUB_PERSONAL_ACCESS_TOKEN\n ) {\n entry.env = {\n ...(entry.env as Record<string, string>),\n GITHUB_PERSONAL_ACCESS_TOKEN: env.GITHUB_PERSONAL_ACCESS_TOKEN,\n };\n }\n\n if (serverName === \"context7\" && env.CONTEXT7_API_KEY) {\n entry.args = [\n ...(entry.args as string[]),\n \"--api-key\",\n env.CONTEXT7_API_KEY,\n ];\n }\n\n const { config: merged, alreadyExists } = mergeServerEntry(\n updatedConfig,\n agent.mcpConfigKey,\n serverName,\n entry\n );\n updatedConfig = merged;\n if (!alreadyExists) {\n mcpSpinner.text = `Added MCP: ${serverName}`;\n }\n }\n\n await writeJsonConfig(mcpConfigPath, updatedConfig);\n mcpSpinner.succeed(`MCP config written → ${mcpConfigPath}`);\n } catch (err) {\n mcpSpinner.fail(\"Failed to write MCP config\");\n log.error(err instanceof Error ? err.message : String(err));\n }\n}\n\nasync function writeRuleFile(rulesDir: string) {\n const rulesSpinner = ora(\"Writing b2dp rule file...\").start();\n try {\n await ensureDir(rulesDir);\n const rulePath = join(rulesDir, RULE_FILENAME);\n await writeFile(rulePath, RULE_CONTENT, \"utf-8\");\n rulesSpinner.succeed(`Rule written → ${rulePath}`);\n } catch (err) {\n rulesSpinner.fail(\"Failed to write rule file\");\n log.error(err instanceof Error ? err.message : String(err));\n }\n}\n\nasync function setupAgent(\n agentName: AgentName,\n scope: \"project\" | \"global\",\n skills: SkillName[],\n selectedMcps: string[],\n env: Record<string, string>\n) {\n const agent = getAgent(agentName);\n log.info(pc.bold(`Setting up ${agent.displayName}...`));\n\n const skillsDir = agent.skillsDir(scope);\n const rulesDir = agent.rulesDir(scope);\n const mcpConfigPath = agent.mcpConfigPath(scope);\n\n await installSkillFiles(skills, skillsDir);\n await configureMCPServers(agent, mcpConfigPath, selectedMcps, env);\n await writeRuleFile(rulesDir);\n\n log.blank();\n}\n\nasync function setupCommand(options: SetupOptions): Promise<void> {\n const scope: \"project\" | \"global\" = options.project ? \"project\" : \"global\";\n\n const selectedAgents = await resolveTargetAgents(options, scope);\n const selectedSkills = await resolveTargetSkills(options);\n const selectedMcps = await resolveTargetMCPs(options);\n\n // Ask for keys if not in -y mode\n const env: Record<string, string> = {};\n if (!options.yes) {\n log.blank();\n log.info(pc.yellow(\"Interactive Configuration:\"));\n\n if (selectedMcps.includes(\"github-mcp-server\")) {\n const githubToken = await input({\n message: \"GitHub Personal Access Token (for github-mcp-server):\",\n transformer: (val) => (val ? \"*\".repeat(val.length) : val),\n });\n if (githubToken) {\n env[\"GITHUB_PERSONAL_ACCESS_TOKEN\"] = githubToken;\n }\n }\n\n if (selectedMcps.includes(\"context7\")) {\n const context7Key = await input({\n message: \"Context7 API Key (for context7):\",\n transformer: (val) => (val ? \"*\".repeat(val.length) : val),\n });\n if (context7Key) {\n env[\"CONTEXT7_API_KEY\"] = context7Key;\n }\n }\n }\n\n log.blank();\n\n for (const agentName of selectedAgents) {\n await setupAgent(agentName, scope, selectedSkills, selectedMcps, env);\n }\n\n log.success(pc.bold(\"b2dp setup complete! 🚀\"));\n log.blank();\n log.dim(\"Next steps:\");\n log.dim(\" 1. Edit your MCP config(s) to fill in the Datafy dbhub.toml path\");\n log.dim(\" (usually ~/Documents/.../datafy/dbhub.toml)\");\n log.dim(\" 2. Restart your AI agent to pick up the new skills and MCP servers.\");\n log.dim(\n ' 3. Try: \"Build me a SaaS platform for team task management\" in your agent.'\n );\n log.blank();\n log.dim(\"Run `b2dp check` to verify your MCP configuration at any time.\");\n}\n","import pc from \"picocolors\";\n\nexport const log = {\n info: (msg: string) => console.log(`${pc.cyan(\"ℹ\")} ${msg}`),\n success: (msg: string) => console.log(`${pc.green(\"✔\")} ${msg}`),\n warn: (msg: string) => console.log(`${pc.yellow(\"⚠\")} ${msg}`),\n error: (msg: string) => console.error(`${pc.red(\"✖\")} ${msg}`),\n dim: (msg: string) => console.log(pc.dim(msg)),\n blank: () => console.log(\"\"),\n};\n","import { access, mkdir } from \"fs/promises\";\n\nexport async function pathExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await mkdir(dir, { recursive: true });\n}\n","import { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { pathExists } from \"../utils/fs.js\";\n\nexport type AgentName = \"antigravity\" | \"claude\" | \"cursor\" | \"vscode\" | \"gemini\";\n\nexport interface AgentConfig {\n name: AgentName;\n displayName: string;\n skillsDir: (scope: \"project\" | \"global\") => string;\n rulesDir: (scope: \"project\" | \"global\") => string;\n mcpConfigPath: (scope: \"project\" | \"global\") => string;\n mcpConfigKey: string;\n detect: {\n projectPaths: string[];\n globalPaths: string[];\n };\n}\n\nconst agents: Record<AgentName, AgentConfig> = {\n // Antigravity / Gemini CLI — ~/.gemini/antigravity/\n antigravity: {\n name: \"antigravity\",\n displayName: \"Antigravity (Gemini CLI)\",\n skillsDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".gemini\", \"antigravity\", \"skills\")\n : join(\".agent\", \"skills\"),\n rulesDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".gemini\", \"antigravity\", \"rules\")\n : join(\".agent\", \"rules\"),\n mcpConfigPath: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".gemini\", \"antigravity\", \"mcp_config.json\")\n : join(\".agent\", \"mcp_config.json\"),\n mcpConfigKey: \"mcpServers\",\n detect: {\n projectPaths: [\".agent\"],\n globalPaths: [join(homedir(), \".gemini\", \"antigravity\")],\n },\n },\n\n // Claude Code — ~/.claude/\n claude: {\n name: \"claude\",\n displayName: \"Claude Code\",\n skillsDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".claude\", \"skills\")\n : join(\".claude\", \"skills\"),\n rulesDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".claude\", \"rules\")\n : join(\".claude\", \"rules\"),\n mcpConfigPath: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".claude.json\")\n : join(\".mcp.json\"),\n mcpConfigKey: \"mcpServers\",\n detect: {\n projectPaths: [\".mcp.json\", \".claude\"],\n globalPaths: [join(homedir(), \".claude\")],\n },\n },\n\n // Cursor — ~/.cursor/\n cursor: {\n name: \"cursor\",\n displayName: \"Cursor\",\n skillsDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".cursor\", \"skills\")\n : join(\".cursor\", \"skills\"),\n rulesDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".cursor\", \"rules\")\n : join(\".cursor\", \"rules\"),\n mcpConfigPath: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".cursor\", \"mcp.json\")\n : join(\".cursor\", \"mcp.json\"),\n mcpConfigKey: \"mcpServers\",\n detect: {\n projectPaths: [\".cursor\"],\n globalPaths: [join(homedir(), \".cursor\")],\n },\n },\n\n // VS Code — uses .vscode/ for project-level config\n vscode: {\n name: \"vscode\",\n displayName: \"VS Code (Copilot)\",\n skillsDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".vscode\", \"skills\")\n : join(\".vscode\", \"skills\"),\n rulesDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".vscode\", \"rules\")\n : join(\".vscode\", \"rules\"),\n mcpConfigPath: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".vscode\", \"mcp.json\")\n : join(\".vscode\", \"mcp.json\"),\n mcpConfigKey: \"servers\",\n detect: {\n projectPaths: [\".vscode\"],\n globalPaths: [join(homedir(), \".vscode\")],\n },\n },\n\n // Gemini CLI — ~/.gemini/settings.json\n gemini: {\n name: \"gemini\",\n displayName: \"Gemini CLI\",\n skillsDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".gemini\", \"skills\")\n : join(\".agent\", \"skills\"),\n rulesDir: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".gemini\", \"rules\")\n : join(\".agent\", \"rules\"),\n mcpConfigPath: (scope) =>\n scope === \"global\"\n ? join(homedir(), \".gemini\", \"settings.json\")\n : join(\".agent\", \"settings.json\"),\n mcpConfigKey: \"mcpServers\",\n detect: {\n projectPaths: [\".agent\"],\n globalPaths: [join(homedir(), \".gemini\", \"settings.json\")],\n },\n },\n};\n\nexport function getAgent(name: AgentName): AgentConfig {\n return agents[name];\n}\n\nexport const ALL_AGENT_NAMES = Object.keys(agents) as AgentName[];\n\nexport const AGENT_DISPLAY_NAMES: Record<AgentName, string> = {\n antigravity: \"Antigravity (Gemini CLI)\",\n claude: \"Claude Code\",\n cursor: \"Cursor\",\n vscode: \"VS Code (Copilot)\",\n gemini: \"Gemini CLI\",\n};\n\nexport async function detectAgents(\n scope: \"project\" | \"global\"\n): Promise<AgentName[]> {\n const detected: AgentName[] = [];\n for (const name of ALL_AGENT_NAMES) {\n const agent = agents[name];\n const paths =\n scope === \"project\" ? agent.detect.projectPaths : agent.detect.globalPaths;\n for (const p of paths) {\n if (await pathExists(p)) {\n detected.push(name);\n break;\n }\n }\n }\n return detected;\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join, resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { ensureDir, pathExists } from \"../utils/fs.js\";\nimport { type SkillName, ALL_SKILLS } from \"../constants.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n/**\n * Resolve the package root by looking for package.json\n */\nfunction findPackageRoot(startDir: string): string {\n let current = startDir;\n while (current !== dirname(current)) {\n if (existsSync(join(current, \"package.json\"))) {\n return current;\n }\n current = dirname(current);\n }\n return startDir; // Fallback to startDir if not found\n}\n\nconst PACKAGE_ROOT = findPackageRoot(__dirname);\nconst SKILLS_REPO_DIR = resolve(PACKAGE_ROOT, \"skills\");\n\nexport interface InstallResult {\n skill: SkillName;\n targetPath: string;\n alreadyExisted: boolean;\n}\n\n/**\n * Read the SKILL.md for a given skill name from the local skills/ directory.\n */\nexport async function readSkillFile(skill: SkillName): Promise<string | null> {\n const skillPath = join(SKILLS_REPO_DIR, skill, \"SKILL.md\");\n try {\n return await readFile(skillPath, \"utf-8\");\n } catch {\n return null;\n }\n}\n\n/**\n * Install a single skill into the target directory.\n * Creates <targetDir>/<skillName>/SKILL.md\n */\nexport async function installSkill(\n skill: SkillName,\n targetDir: string\n): Promise<InstallResult> {\n const skillDir = join(targetDir, skill);\n const targetPath = join(skillDir, \"SKILL.md\");\n\n const alreadyExisted = await pathExists(targetPath);\n const content = await readSkillFile(skill);\n\n if (!content) {\n throw new Error(`Could not read SKILL.md for skill: ${skill}`);\n }\n\n if (alreadyExisted) {\n const existingContent = await readFile(targetPath, \"utf-8\");\n if (existingContent === content) {\n return { skill, targetPath, alreadyExisted: true };\n }\n }\n\n await ensureDir(skillDir);\n await writeFile(targetPath, content, \"utf-8\");\n\n return { skill, targetPath, alreadyExisted };\n}\n\n/**\n * Install multiple skills into the target directory.\n */\nexport async function installSkills(\n skills: SkillName[],\n targetDir: string\n): Promise<InstallResult[]> {\n const results: InstallResult[] = [];\n for (const skill of skills) {\n const result = await installSkill(skill, targetDir);\n results.push(result);\n }\n return results;\n}\n\n/**\n * Get which skills are available in the local skills/ directory.\n */\nexport async function getAvailableSkills(): Promise<\n { name: SkillName; available: boolean }[]\n> {\n return Promise.all(\n ALL_SKILLS.map(async (skill) => ({\n name: skill,\n available: await pathExists(join(SKILLS_REPO_DIR, skill, \"SKILL.md\")),\n }))\n );\n}\n\n/**\n * Extract the description line from a SKILL.md frontmatter.\n */\nexport function parseSkillDescription(content: string): string | null {\n const match = /^description:\\s*[>|]?\\s*\\n?([\\s\\S]*?)(?=\\n\\w|\\n---)/m.exec(content);\n if (!match) return null;\n return match[1]\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean)\n .join(\" \")\n .slice(0, 120);\n}\n","import { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nexport async function readJsonConfig(\n filePath: string\n): Promise<Record<string, unknown>> {\n let raw: string;\n try {\n raw = await readFile(filePath, \"utf-8\");\n } catch {\n return {};\n }\n raw = raw.trim();\n if (!raw) return {};\n return JSON.parse(raw) as Record<string, unknown>;\n}\n\nexport function mergeServerEntry(\n existing: Record<string, unknown>,\n configKey: string,\n serverName: string,\n entry: Record<string, unknown>\n): { config: Record<string, unknown>; alreadyExists: boolean } {\n const section =\n (existing[configKey] as Record<string, unknown> | undefined) ?? {};\n\n // If server already exists, we might still want to merge env vars if they were empty\n if (serverName in section) {\n const existingEntry = section[serverName] as Record<string, any>;\n const newEnv = (entry.env as Record<string, string>) ?? {};\n const existingEnv = (existingEntry.env as Record<string, string>) ?? {};\n\n let envChanged = false;\n for (const [key, value] of Object.entries(newEnv)) {\n if (value && existingEnv[key] !== value) {\n existingEnv[key] = value;\n envChanged = true;\n }\n }\n\n if (!envChanged) {\n return { config: existing, alreadyExists: true };\n }\n\n return {\n config: {\n ...existing,\n [configKey]: {\n ...section,\n [serverName]: { ...existingEntry, env: existingEnv },\n },\n },\n alreadyExists: true,\n };\n }\n\n return {\n config: {\n ...existing,\n [configKey]: { ...section, [serverName]: entry },\n },\n alreadyExists: false,\n };\n}\n\nexport async function writeJsonConfig(\n filePath: string,\n config: Record<string, unknown>\n): Promise<void> {\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, JSON.stringify(config, null, 2) + \"\\n\", \"utf-8\");\n}\n\n/** MCP server entries for the b2dp ecosystem */\nexport const B2DP_MCP_SERVERS: Record<string, Record<string, unknown>> = {\n datafy: {\n command: \"npx\",\n args: [\n \"@teckedd-code2save/datafy@latest\",\n \"--config\",\n \"/path/to/your/dbhub.toml\",\n \"--transport\",\n \"stdio\",\n ],\n },\n \"prisma-mcp-server\": {\n command: \"npx\",\n args: [\"-y\", \"prisma\", \"mcp\"],\n },\n \"github-mcp-server\": {\n command: \"docker\",\n args: [\n \"run\",\n \"-i\",\n \"--rm\",\n \"-e\",\n \"GITHUB_PERSONAL_ACCESS_TOKEN\",\n \"ghcr.io/github/github-mcp-server\",\n ],\n env: {\n GITHUB_PERSONAL_ACCESS_TOKEN: \"\",\n },\n },\n context7: {\n command: \"npx\",\n args: [\"-y\", \"@upstash/context7-mcp\"],\n },\n redis: {\n command: \"npx\",\n args: [\"-y\", \"@modelcontextprotocol/server-redis\"],\n env: {\n REDIS_URL: \"\",\n },\n },\n};\n","export const RULE_CONTENT = `---\nalwaysApply: true\n---\n\n# Business-to-Data-Platform Orchestrator\n\nThis project uses the **business-to-data-platform** skill as the central orchestrator. When building any backend feature, database schema, or data-driven system:\n\n1. **Invoke \\`business-to-data-platform\\`** as the primary skill — it drives architecture design, schema creation, ORM setup, testing, frontend scaffolding, and infra provisioning.\n2. **Never hardcode data in UI components.** All data must come from real DB queries or API endpoints.\n3. **Always use Datafy MCP** for database operations — never raw psql in the terminal.\n4. **Follow the 12-step workflow** defined in the orchestrator skill — from architecture design through infrastructure provisioning.\n\n## Required MCPs for the full stack\n- **datafy** — DB operations, SQL execution, code generation\n- **prisma-mcp-server** — migrations and DB exploration\n- **github-mcp-server** — repo discovery, CI/CD setup\n- **context7** — up-to-date docs and patterns for any library\n\n## Sibling skills that get invoked automatically\n- \\`cloud-solution-architect\\` → Docker/K8s architecture\n- \\`api-test-generator\\` → integration tests\n- \\`frontend-data-consumer\\` → Vite/Next.js UI components\n- \\`infrastructure-as-code-architect\\` → Dockerfiles, K8s manifests, GitHub Actions\n`;\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport ora from \"ora\";\n\nimport { log } from \"../utils/logger.js\";\nimport {\n type AgentName,\n ALL_AGENT_NAMES,\n AGENT_DISPLAY_NAMES,\n getAgent,\n} from \"../setup/agents.js\";\nimport { readJsonConfig } from \"../setup/mcp-writer.js\";\nimport { B2DP_MCP_SERVERS } from \"../setup/mcp-writer.js\";\n\nconst REQUIRED_MCPS = [\"datafy\", \"prisma-mcp-server\", \"github-mcp-server\", \"context7\"];\n\ninterface CheckOptions {\n project?: boolean;\n}\n\nexport function registerCheckCommand(program: Command): void {\n program\n .command(\"check\")\n .description(\n \"Verify that the b2dp MCP servers are configured for your AI coding agents\"\n )\n .option(\"-p, --project\", \"Check project-level config instead of global\")\n .action(async (options: CheckOptions) => {\n await checkCommand(options);\n });\n}\n\nasync function checkCommand(options: CheckOptions): Promise<void> {\n const scope: \"project\" | \"global\" = options.project ? \"project\" : \"global\";\n\n log.info(\n pc.bold(`Checking b2dp MCP configuration (${scope} scope)...`)\n );\n log.blank();\n\n let anyAgentFound = false;\n\n for (const agentName of ALL_AGENT_NAMES as AgentName[]) {\n const agent = getAgent(agentName);\n const mcpConfigPath = agent.mcpConfigPath(scope);\n\n const spinner = ora(\n `Reading ${agent.displayName} config...`\n ).start();\n\n let config: Record<string, unknown>;\n try {\n config = await readJsonConfig(mcpConfigPath);\n } catch {\n spinner.warn(`${agent.displayName}: config not readable (${mcpConfigPath})`);\n continue;\n }\n\n const servers = (\n config[agent.mcpConfigKey] as Record<string, unknown> | undefined\n ) ?? {};\n\n if (Object.keys(servers).length === 0 && Object.keys(config).length === 0) {\n spinner.warn(\n `${agent.displayName}: no config found at ${mcpConfigPath}`\n );\n continue;\n }\n\n spinner.stop();\n anyAgentFound = true;\n\n console.log(pc.bold(`\\n ${agent.displayName}`));\n console.log(pc.dim(` ${mcpConfigPath}`));\n\n for (const mcp of REQUIRED_MCPS) {\n const isPresent = mcp in servers;\n const entry = servers[mcp] as Record<string, unknown> | undefined;\n\n // Check for unfilled placeholders\n const hasPlaceholder =\n isPresent &&\n JSON.stringify(entry).includes(\"/path/to/your/dbhub.toml\");\n\n const icon = !isPresent\n ? pc.red(\"✖\")\n : hasPlaceholder\n ? pc.yellow(\"⚠\")\n : pc.green(\"✔\");\n\n const note = !isPresent\n ? pc.dim(\" (missing — run `b2dp setup` to add)\")\n : hasPlaceholder\n ? pc.yellow(\" (needs dbhub.toml path filled in)\")\n : pc.dim(\" (configured)\");\n\n console.log(` ${icon} ${mcp}${note}`);\n }\n\n // Check for optional MCPs from b2dp ecosystem\n const optionalMcps = Object.keys(B2DP_MCP_SERVERS).filter(\n (s) => !REQUIRED_MCPS.includes(s)\n );\n for (const mcp of optionalMcps) {\n const isPresent = mcp in servers;\n const icon = isPresent ? pc.green(\"✔\") : pc.dim(\"○\");\n const label = isPresent ? pc.dim(\" (configured)\") : pc.dim(\" (optional, not set)\");\n console.log(` ${icon} ${pc.dim(mcp)}${label}`);\n }\n }\n\n log.blank();\n\n if (!anyAgentFound) {\n log.warn(\n \"No agent configs found. Run `b2dp setup` to install the b2dp skill ecosystem.\"\n );\n } else {\n log.dim(\"Run `b2dp setup` to add any missing MCPs or reinstall skills.\");\n }\n}\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\n\nimport { log } from \"../utils/logger.js\";\nimport { ALL_SKILLS, SKILL_DESCRIPTIONS, ORCHESTRATOR_SKILL } from \"../constants.js\";\nimport {\n getAvailableSkills,\n readSkillFile,\n parseSkillDescription,\n} from \"../setup/skill-writer.js\";\n\nexport function registerSkillsCommand(program: Command): void {\n const skills = program\n .command(\"skills\")\n .description(\"Manage b2dp skills\");\n\n // b2dp skills list\n skills\n .command(\"list\")\n .description(\"List all available b2dp skills\")\n .action(async () => {\n await listSkillsCommand();\n });\n\n // b2dp skills info <name>\n skills\n .command(\"info <skillName>\")\n .description(\"Show details about a specific skill\")\n .action(async (skillName: string) => {\n await infoSkillCommand(skillName);\n });\n}\n\nasync function listSkillsCommand(): Promise<void> {\n log.blank();\n console.log(pc.bold(\"Available b2dp skills:\"));\n log.blank();\n\n const available = await getAvailableSkills();\n\n for (const { name, available: isAvailable } of available) {\n const isOrchestrator = name === ORCHESTRATOR_SKILL;\n const statusIcon = isAvailable ? pc.green(\"✔\") : pc.red(\"✖\");\n const label = isOrchestrator\n ? pc.bold(pc.cyan(name)) + pc.cyan(\" (orchestrator)\")\n : pc.white(name);\n const desc = pc.dim(SKILL_DESCRIPTIONS[name]);\n const missing = isAvailable ? \"\" : pc.red(\" [SKILL.md not found]\");\n\n console.log(` ${statusIcon} ${label}${missing}`);\n console.log(` ${desc}`);\n log.blank();\n }\n\n const availableCount = available.filter((s) => s.available).length;\n log.dim(\n `${availableCount}/${ALL_SKILLS.length} skills available locally.`\n );\n log.dim(\n \"Run `b2dp setup` to install all skills into your AI coding agent.\"\n );\n}\n\nasync function infoSkillCommand(skillName: string): Promise<void> {\n const validSkill = ALL_SKILLS.find((s) => s === skillName);\n if (!validSkill) {\n log.error(\n `Unknown skill: \"${skillName}\". Run \\`b2dp skills list\\` to see available skills.`\n );\n process.exit(1);\n }\n\n const content = await readSkillFile(validSkill);\n if (!content) {\n log.error(\n `SKILL.md not found for \"${validSkill}\". Ensure the skills/ directory is intact.`\n );\n process.exit(1);\n }\n\n const description = parseSkillDescription(content) ?? SKILL_DESCRIPTIONS[validSkill];\n const isOrchestrator = validSkill === ORCHESTRATOR_SKILL;\n\n log.blank();\n console.log(\n pc.bold(\n isOrchestrator ? pc.cyan(`${validSkill} (orchestrator)`) : pc.white(validSkill)\n )\n );\n log.blank();\n console.log(` ${pc.dim(description)}`);\n log.blank();\n\n // Count lines in the SKILL.md as a rough size indicator\n const lineCount = content.split(\"\\n\").length;\n log.dim(` ${lineCount} lines · SKILL.md`);\n log.blank();\n\n log.dim(\n `Install with: b2dp setup --yes (or select it during interactive setup)`\n );\n}\n"],"mappings":"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","names":["pc","pc","writeFile","join","join","join","readFile","writeFile","mkdir","dirname","program","agents","pc","join","writeFile","pc","ora","program","pc","ora","pc","program","pc","pc"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teckedd-code2save/b2dp",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "b2dp CLI — One-command setup for the Business-to-Data-Platform skill ecosystem",
5
5
  "repository": {
6
6
  "type": "git",