atomism 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -199,11 +199,11 @@ executionError('Runtime failure') // Execution error
199
199
 
200
200
  ## Documentation
201
201
 
202
- Full documentation: https://trust-will.github.io/atomic-explore/
202
+ Full documentation: https://github.com/roach88/atomism
203
203
 
204
204
  ## Requirements
205
205
 
206
- - Node.js 18+
206
+ - Node.js 20+
207
207
 
208
208
  ## License
209
209
 
package/dist/cli.js CHANGED
@@ -5,7 +5,7 @@ import { Command } from "commander";
5
5
  var program = new Command();
6
6
  program.name("atomic").description("Schema-first agent swarm orchestration framework").version("0.1.0");
7
7
  program.command("init").description("Initialize .atomic/ directory with storage and registry").option("--json", "Output structured JSON response").action(async (options) => {
8
- const { initCommand } = await import("./init-2FINDMYK.js");
8
+ const { initCommand } = await import("./init-EH6ZWP5R.js");
9
9
  return initCommand(options);
10
10
  });
11
11
  program.command("register <path>").description("Register an atom file").option("--json", "Output structured JSON response").action(async (atomPath, options) => {
@@ -42,7 +42,7 @@ create.command("atom <name>").description("Create a new atom with scaffolded fil
42
42
  return createAtomCommand(name, options);
43
43
  });
44
44
  program.command("extract").description("Extract atom from existing skill, BMAD workflow, MCP tool, or code").option("--skill <path>", "Extract from Claude Code skill").option("--bmad <path>", "Extract from BMAD workflow").option("--mcp <path>", "Extract from MCP tool definition").option("--code <path>", "Extract from existing code file").option("--output <dir>", "Output directory for generated atom").option("-y, --yes", "Auto-create without confirmation").option("--json", "Output structured JSON response").action(async (options) => {
45
- const { extractCommand } = await import("./extract-RPKCTINT.js");
45
+ const { extractCommand } = await import("./extract-6WTZGLKX.js");
46
46
  return extractCommand(options);
47
47
  });
48
48
  program.command("suggest").description("Scan codebase for functions that could become atoms").option("--path <dir>", "Directory to scan (default: cwd)").option("--limit <n>", "Max candidates to show (default: 20)").option("--scan-limit <n>", "Max files to scan (default: 1000)").option("--json", "Output structured JSON response").action(async (options) => {
@@ -468,7 +468,7 @@ async function extractCommand(options) {
468
468
  const testPath = join(outputDir, `${extracted.name}.test.ts`);
469
469
  const resolvedOutputDir = resolve(outputDir);
470
470
  const rel = relative(resolvedOutputDir, resolve(atomPath));
471
- if (rel.startsWith("..") || isAbsolute(rel)) {
471
+ if (isAbsolute(rel) || rel.startsWith("..")) {
472
472
  throw new Error("Generated path escapes output directory");
473
473
  }
474
474
  if (await fileExists(atomPath)) {
@@ -511,4 +511,4 @@ export {
511
511
  escapeSourcePath,
512
512
  extractCommand
513
513
  };
514
- //# sourceMappingURL=extract-RPKCTINT.js.map
514
+ //# sourceMappingURL=extract-6WTZGLKX.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/extract.ts"],"sourcesContent":["/**\n * Extract command - Create atoms from existing sources.\n *\n * Story 1.10: AOP-1216\n *\n * Acceptance Criteria:\n * - Extract from Claude Code skills, BMAD workflows, MCP tools, or code\n * - Analyze source for input parameters, output format, description\n * - Display proposed atom definition for user approval\n * - Create atom file with extracted structure\n */\n\nimport { readFile, stat, mkdir, writeFile } from 'node:fs/promises';\nimport { join, basename, dirname, resolve, relative, isAbsolute } from 'node:path';\nimport { fmt } from '../cli/format.js';\nimport { initStorage, ATOMIC_DIR, fileExists } from '../storage/index.js';\nimport { toErrorMessage } from '../utils/errors.js';\nimport { resolveAtomPath } from '../utils/paths.js';\n\n/**\n * Options for the extract command.\n */\nexport interface ExtractOptions {\n skill?: string;\n bmad?: string;\n mcp?: string;\n code?: string;\n output?: string;\n yes?: boolean;\n json?: boolean;\n}\n\n/**\n * A single extracted field with human-readable type and Zod code-gen token.\n */\nexport interface ExtractedField {\n name: string;\n type: string; // human label: 'string', 'number', etc.\n zodType: string; // code-gen token: 'z.string()', 'z.number()', etc.\n description: string;\n}\n\n/**\n * Extracted atom definition.\n */\nexport interface ExtractedAtom {\n name: string;\n description: string;\n inputFields: ExtractedField[];\n outputFields: ExtractedField[];\n sourceType: 'skill' | 'bmad' | 'mcp' | 'code';\n sourcePath: string;\n}\n\n/**\n * Result of extraction.\n */\nexport interface ExtractResult {\n success: boolean;\n extracted?: ExtractedAtom;\n atomPath?: string;\n testPath?: string;\n error?: string;\n}\n\n/**\n * Parse YAML frontmatter from markdown content.\n *\n * Note: This is a simple parser that handles basic key: value pairs.\n * It does not support quoted values with colons, multi-line strings,\n * or nested structures. For complex YAML, consider using a proper parser.\n */\nfunction parseFrontmatter(content: string): Record<string, string> {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match || !match[1]) {\n return {};\n }\n\n const frontmatter: Record<string, string> = {};\n const lines = match[1].split('\\n');\n\n for (const line of lines) {\n const colonIndex = line.indexOf(':');\n if (colonIndex > 0) {\n const key = line.substring(0, colonIndex).trim();\n const value = line.substring(colonIndex + 1).trim();\n frontmatter[key] = value;\n }\n }\n\n return frontmatter;\n}\n\n/**\n * Convert a name to snake_case.\n */\nfunction toSnakeCase(name: string): string {\n return name\n .replace(/[^a-zA-Z0-9]+/g, '_')\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .toLowerCase()\n .replace(/^_+|_+$/g, '')\n .replace(/_+/g, '_');\n}\n\n/** Valid JS identifier pattern for field names in generated code. */\nconst VALID_JS_IDENTIFIER = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\n/**\n * Validate that a zodType string is a safe Zod expression.\n * zodType is injected as raw code — structural validation prevents code injection.\n * Matches only the patterns produced by tsTypeToZodType/jsonSchemaTypeToZodType:\n * z.method() — z.string(), z.number(), etc.\n * z.method(z.method()) — z.array(z.string())\n * z.method(z.method(), z.method()) — z.record(z.string(), z.number())\n * z.enum([\"a\", \"b\"]) — enum with JSON-stringified values\n * any of the above + .optional() — optional modifier\n */\nfunction isSafeZodType(expr: string): boolean {\n const base = expr.replace(/\\.optional\\(\\)$/, '');\n // Simple: z.string(), z.number(), z.unknown(), etc.\n if (/^z\\.[a-z]+\\(\\)$/.test(base)) return true;\n // Wrapper: z.array(z.string()), z.record(z.string(), z.number())\n if (/^z\\.[a-z]+\\(z\\.[a-z]+\\(\\)(, z\\.[a-z]+\\(\\))?\\)$/.test(base)) return true;\n // Enum: z.enum([\"a\", \"b\", \"c\"]) — values are JSON.stringify'd (no unescaped quotes/backslashes)\n if (/^z\\.enum\\(\\[(\"[^\"\\\\]*\"(, \"[^\"\\\\]*\")*)\\]\\)$/.test(base)) return true;\n return false;\n}\n\n/**\n * Map a TypeScript type annotation string to a Zod type expression.\n */\nfunction tsTypeToZodType(tsType: string | undefined): string {\n if (!tsType) return 'z.unknown()';\n switch (tsType) {\n case 'string': return 'z.string()';\n case 'number': return 'z.number()';\n case 'boolean': return 'z.boolean()';\n case 'Date': return 'z.date()';\n case 'bigint': return 'z.bigint()';\n case 'void': return 'z.void()';\n case 'undefined': return 'z.undefined()';\n case 'null': return 'z.null()';\n case 'any': return 'z.any()';\n case 'unknown': return 'z.unknown()';\n case 'never': return 'z.never()';\n default:\n if (tsType.endsWith('[]')) {\n const inner = tsTypeToZodType(tsType.slice(0, -2));\n return `z.array(${inner})`;\n }\n if (tsType.startsWith('Record<')) {\n const match = tsType.match(/^Record<(.+),\\s*(.+)>$/);\n if (match) {\n return `z.record(${tsTypeToZodType(match[1])}, ${tsTypeToZodType(match[2])})`;\n }\n }\n return 'z.unknown()';\n }\n}\n\n/**\n * Map a JSON Schema type string to a Zod type expression.\n */\nfunction jsonSchemaTypeToZodType(schemaType: string | undefined): string {\n switch (schemaType) {\n case 'string': return 'z.string()';\n case 'number': case 'integer': return 'z.number()';\n case 'boolean': return 'z.boolean()';\n case 'array': return 'z.array(z.unknown())';\n case 'object': return 'z.record(z.string(), z.unknown())';\n case 'null': return 'z.null()';\n default: return 'z.unknown()';\n }\n}\n\n/**\n * Escape sourcePath to prevent comment injection (close-comment sequence).\n */\nexport function escapeSourcePath(path: string): string {\n return path.replace(/\\*\\//g, '*\\\\/');\n}\n\n/**\n * Extract atom from Claude Code skill.\n */\nasync function extractFromSkill(skillPath: string): Promise<ExtractedAtom> {\n const resolvedPath = resolveAtomPath(skillPath, process.cwd());\n\n // Check if it's a directory or file\n const stats = await stat(resolvedPath);\n let skillContent: string;\n let skillFile: string;\n\n if (stats.isDirectory()) {\n // Look for SKILL.md in directory\n skillFile = join(resolvedPath, 'SKILL.md');\n if (!(await fileExists(skillFile))) {\n throw new Error(`No SKILL.md found in ${resolvedPath}`);\n }\n skillContent = await readFile(skillFile, 'utf-8');\n } else {\n // Direct file path\n skillFile = resolvedPath;\n skillContent = await readFile(skillFile, 'utf-8');\n }\n\n // Parse frontmatter\n const frontmatter = parseFrontmatter(skillContent);\n const name = frontmatter['name'] || basename(dirname(skillFile));\n const description = frontmatter['description'] || 'Extracted from Claude Code skill';\n\n // Analyze content for input/output patterns\n const inputFields = analyzeSkillInputs(skillContent);\n const outputFields = analyzeSkillOutputs(skillContent);\n\n return {\n name: toSnakeCase(name),\n description,\n inputFields,\n outputFields,\n sourceType: 'skill',\n sourcePath: skillFile,\n };\n}\n\n/**\n * Analyze content for field patterns matching a set of regexes.\n * Shared logic for input/output field extraction from skill documentation.\n */\nfunction analyzeFieldPatterns(\n content: string,\n patterns: RegExp[],\n defaultField: { name: string; description: string },\n descriptionSuffix: string,\n): ExtractedAtom['inputFields'] {\n const found = new Set<string>();\n\n for (const pattern of patterns) {\n for (const match of content.matchAll(pattern)) {\n const name = match[1]?.toLowerCase();\n if (name && !found.has(name) && name.length > 2) {\n found.add(name);\n }\n }\n }\n\n if (found.size === 0) {\n return [{ name: defaultField.name, type: 'string', zodType: 'z.string()', description: defaultField.description }];\n }\n\n const fields: ExtractedAtom['inputFields'] = [];\n for (const name of found) {\n fields.push({ name: toSnakeCase(name), type: 'string', zodType: 'z.string()', description: `${name} ${descriptionSuffix}` });\n }\n return fields.slice(0, 5);\n}\n\nconst INPUT_PATTERNS = [\n /accepts?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n /input[:\\s]+([a-z_]+)/gi,\n /receives?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n /takes?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n];\n\nconst OUTPUT_PATTERNS = [\n /outputs?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n /returns?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n /produces?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n /generates?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n];\n\nfunction analyzeSkillInputs(content: string): ExtractedAtom['inputFields'] {\n return analyzeFieldPatterns(content, INPUT_PATTERNS, { name: 'input', description: 'Input data to process' }, 'parameter');\n}\n\nfunction analyzeSkillOutputs(content: string): ExtractedAtom['outputFields'] {\n return analyzeFieldPatterns(content, OUTPUT_PATTERNS, { name: 'result', description: 'Processing result' }, 'output');\n}\n\n/**\n * Extract atom from BMAD workflow.\n */\nasync function extractFromBmad(bmadPath: string): Promise<ExtractedAtom> {\n const resolvedPath = resolveAtomPath(bmadPath, process.cwd());\n\n if (!(await fileExists(resolvedPath))) {\n throw new Error(`BMAD workflow not found: ${resolvedPath}`);\n }\n\n const content = await readFile(resolvedPath, 'utf-8');\n const frontmatter = parseFrontmatter(content);\n\n const name = frontmatter['name'] || basename(resolvedPath, '.md');\n const description = frontmatter['description'] || 'Extracted from BMAD workflow';\n\n return {\n name: toSnakeCase(name),\n description,\n inputFields: [{ name: 'context', type: 'string', zodType: 'z.string()', description: 'Workflow context' }],\n outputFields: [{ name: 'result', type: 'string', zodType: 'z.string()', description: 'Workflow result' }],\n sourceType: 'bmad',\n sourcePath: resolvedPath,\n };\n}\n\n/**\n * Extract atom from MCP tool definition.\n */\nasync function extractFromMcp(mcpPath: string): Promise<ExtractedAtom> {\n const resolvedPath = resolveAtomPath(mcpPath, process.cwd());\n\n if (!(await fileExists(resolvedPath))) {\n throw new Error(`MCP tool definition not found: ${resolvedPath}`);\n }\n\n const content = await readFile(resolvedPath, 'utf-8');\n\n // Try to parse as JSON (MCP tool definitions are often JSON)\n let mcpDef: { name?: string; description?: string; inputSchema?: unknown };\n try {\n mcpDef = JSON.parse(content);\n } catch (err) {\n // If not JSON, warn and treat as a generic definition\n console.warn(\n fmt.yellow(`Warning: Could not parse MCP definition as JSON: ${toErrorMessage(err)}`)\n );\n mcpDef = { name: basename(resolvedPath, '.json') };\n }\n\n const name = mcpDef.name || basename(resolvedPath, '.json');\n const description = mcpDef.description || 'Extracted from MCP tool';\n\n // Extract input fields from inputSchema if present\n const inputFields: ExtractedAtom['inputFields'] = [];\n if (mcpDef.inputSchema && typeof mcpDef.inputSchema === 'object') {\n const schema = mcpDef.inputSchema as {\n properties?: Record<string, { type?: string; description?: string; enum?: string[] }>;\n required?: string[];\n };\n const required = new Set(schema.required ?? []);\n if (schema.properties) {\n for (const [key, value] of Object.entries(schema.properties)) {\n let zodType: string;\n if (value.enum) {\n zodType = `z.enum([${value.enum.map(v => JSON.stringify(v)).join(', ')}])`;\n } else {\n zodType = jsonSchemaTypeToZodType(value.type);\n }\n if (!required.has(key)) {\n zodType += '.optional()';\n }\n inputFields.push({\n name: toSnakeCase(key),\n type: value.type ?? 'unknown',\n zodType,\n description: value.description || `${key} parameter`,\n });\n }\n }\n }\n\n if (inputFields.length === 0) {\n inputFields.push({ name: 'input', type: 'string', zodType: 'z.string()', description: 'Tool input' });\n }\n\n return {\n name: toSnakeCase(name),\n description,\n inputFields,\n outputFields: [{ name: 'result', type: 'string', zodType: 'z.string()', description: 'Tool result' }],\n sourceType: 'mcp',\n sourcePath: resolvedPath,\n };\n}\n\n/**\n * Extract atom from existing code file using AST-based extraction.\n *\n * For JS/TS files, uses oxc-parser via dynamic import to extract typed\n * function signatures. Falls back to regex for non-JS/TS or parse failures.\n * The dynamic import ensures oxc-parser is only loaded when --code is used.\n */\nasync function extractFromCode(codePath: string): Promise<ExtractedAtom> {\n const resolvedPath = resolveAtomPath(codePath, process.cwd());\n\n if (!(await fileExists(resolvedPath))) {\n throw new Error(`Code file not found: ${resolvedPath}`);\n }\n\n const content = await readFile(resolvedPath, 'utf-8');\n const name = basename(resolvedPath).replace(/\\.[^.]+$/, '');\n\n // Extract description from JSDoc or first comment\n let description = 'Extracted from code';\n const jsdocMatch = content.match(/\\/\\*\\*\\s*\\n\\s*\\*\\s*([^\\n]+)/);\n if (jsdocMatch && jsdocMatch[1]) {\n description = jsdocMatch[1].trim();\n }\n\n // Try AST-based extraction for JS/TS files\n const { detectLanguage, isJavaScriptFamily, parseFile } = await import('../parser/index.js');\n const { extractSignatures } = await import('../parser/signatures.js');\n const lang = detectLanguage(resolvedPath);\n const jsFamily = lang && isJavaScriptFamily(lang);\n\n if (jsFamily) {\n try {\n\n const parseResult = await parseFile(content, resolvedPath);\n if (parseResult.success && parseResult.language !== 'python') {\n const sigs = extractSignatures(parseResult.ast, content, parseResult.comments);\n // Pick primary export: first default export, or first named export\n const primary = sigs.find(s => s.exportDefault) ?? sigs.find(s => s.exported) ?? sigs[0];\n\n if (primary) {\n const inputFields: ExtractedAtom['inputFields'] = primary.params\n .filter(p => {\n const fieldName = toSnakeCase(p.name);\n return VALID_JS_IDENTIFIER.test(fieldName);\n })\n .map(p => ({\n name: toSnakeCase(p.name),\n type: p.type ?? 'unknown',\n zodType: tsTypeToZodType(p.type),\n description: `${p.name} parameter`,\n }));\n\n if (inputFields.length === 0) {\n inputFields.push({ name: 'input', type: 'unknown', zodType: 'z.unknown()', description: 'Function input' });\n }\n\n return {\n name: toSnakeCase(name),\n description,\n inputFields,\n outputFields: [{ name: 'result', type: 'string', zodType: 'z.string()', description: 'Function result' }],\n sourceType: 'code',\n sourcePath: resolvedPath,\n };\n }\n }\n // Parse succeeded but no functions found — fall through to regex\n } catch {\n // AST parse failed — fall through to regex fallback\n }\n }\n\n // Regex fallback for non-JS/TS files or parse failures\n const inputFields: ExtractedAtom['inputFields'] = [];\n const functionMatch = content.match(/(?:function|const|let|var)\\s+\\w+\\s*[=:]\\s*(?:async\\s+)?(?:\\([^)]*\\)|[^=]+=>)/);\n if (functionMatch && functionMatch[0]) {\n const paramMatch = functionMatch[0].match(/\\(([^)]*)\\)/);\n if (paramMatch && paramMatch[1]) {\n const paramsStr = paramMatch[1];\n const params = paramsStr.split(',').map((p) => p.trim().split(':')[0]?.trim() ?? '');\n for (const param of params) {\n if (param && param !== '' && !param.startsWith('{')) {\n inputFields.push({\n name: toSnakeCase(param),\n type: 'string',\n zodType: 'z.string()',\n description: `${param} parameter`,\n });\n }\n }\n }\n }\n\n if (inputFields.length === 0) {\n inputFields.push({ name: 'input', type: 'string', zodType: 'z.string()', description: 'Function input' });\n }\n\n return {\n name: toSnakeCase(name),\n description,\n inputFields,\n outputFields: [{ name: 'result', type: 'string', zodType: 'z.string()', description: 'Function result' }],\n sourceType: 'code',\n sourcePath: resolvedPath,\n };\n}\n\n/**\n * Escape a string for use in a single-quoted TypeScript string literal.\n */\nfunction escapeForTemplate(str: string): string {\n return str\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/'/g, \"\\\\'\")\n .replace(/`/g, '\\\\`')\n .replace(/\\$\\{/g, '\\\\${')\n .replace(/\\*\\//g, '* /')\n .replace(/\\n/g, ' ')\n .replace(/\\r/g, '');\n}\n\n/**\n * Generate atom template from extracted definition.\n */\nfunction generateAtomTemplate(extracted: ExtractedAtom): string {\n const escapedName = escapeForTemplate(extracted.name);\n const escapedDescription = escapeForTemplate(extracted.description);\n const escapedPath = escapeSourcePath(extracted.sourcePath);\n\n // Filter fields to valid JS identifiers and safe Zod types only\n const safeInputFields = extracted.inputFields\n .filter(f => VALID_JS_IDENTIFIER.test(f.name) && isSafeZodType(f.zodType));\n const safeOutputFields = extracted.outputFields\n .filter(f => VALID_JS_IDENTIFIER.test(f.name) && isSafeZodType(f.zodType));\n\n const droppedInputCount = extracted.inputFields.length - safeInputFields.length;\n const droppedOutputCount = extracted.outputFields.length - safeOutputFields.length;\n if (droppedInputCount > 0 || droppedOutputCount > 0) {\n const parts: string[] = [];\n if (droppedInputCount > 0) parts.push(`${droppedInputCount} input`);\n if (droppedOutputCount > 0) parts.push(`${droppedOutputCount} output`);\n console.error(fmt.warning(`Dropped ${parts.join(' and ')} field(s) with unsafe or invalid schema types`));\n }\n\n const inputSchema = safeInputFields\n .map((f) => ` ${f.name}: ${f.zodType}.describe('${escapeForTemplate(f.description)}'),`)\n .join('\\n');\n\n const outputSchema = safeOutputFields\n .map((f) => ` ${f.name}: ${f.zodType}.describe('${escapeForTemplate(f.description)}'),`)\n .join('\\n');\n\n const inputDestructure = safeInputFields.map((f) => f.name).join(', ');\n\n return `import { defineAtom, success, executionError, z } from 'atomism';\n\n/**\n * ${escapedName} atom\n *\n * ${escapeForTemplate(extracted.description)}\n *\n * Extracted from: ${extracted.sourceType} at ${escapedPath}\n */\nexport default defineAtom({\n name: '${escapedName}',\n description: '${escapedDescription}',\n input: z.object({\n${inputSchema}\n }),\n output: z.object({\n${outputSchema}\n }),\n tests: {\n path: './${escapedName}.test.ts',\n },\n idempotent: true,\n handler: async ({ ${inputDestructure} }) => {\n // TODO: Implement handler logic\n // Original source: ${escapedPath}\n\n return success({\n${safeOutputFields.map((f) => ` ${f.name}: '',`).join('\\n')}\n });\n },\n});\n`;\n}\n\n/**\n * Generate test template from extracted definition.\n */\nfunction generateTestTemplate(extracted: ExtractedAtom): string {\n const escapedName = escapeForTemplate(extracted.name);\n const safeInputFields = extracted.inputFields.filter(f => VALID_JS_IDENTIFIER.test(f.name));\n return `import { describe, it, expect } from 'vitest';\nimport atom from './${escapedName}.js';\n\ndescribe('${escapedName}', () => {\n describe('input validation', () => {\n${safeInputFields.map((f) => ` it.todo('validates ${f.name} field');`).join('\\n')}\n });\n\n describe('handler behavior', () => {\n it.todo('processes valid input correctly');\n it.todo('returns expected output structure');\n });\n\n describe('error handling', () => {\n it.todo('handles invalid input gracefully');\n });\n});\n`;\n}\n\n/**\n * Format extracted definition for display.\n */\nfunction formatExtractedAtom(extracted: ExtractedAtom): string {\n const lines: string[] = [];\n\n lines.push(fmt.bold('Proposed Atom Definition'));\n lines.push('─'.repeat(60));\n lines.push(` ${fmt.dim('Name:')} ${fmt.cyan(extracted.name)}`);\n lines.push(` ${fmt.dim('Source:')} ${extracted.sourceType} (${extracted.sourcePath})`);\n lines.push(` ${fmt.dim('Description:')} ${extracted.description.substring(0, 60)}${extracted.description.length > 60 ? '...' : ''}`);\n lines.push('');\n\n lines.push(fmt.bold('Input Schema'));\n lines.push('─'.repeat(60));\n for (const field of extracted.inputFields) {\n lines.push(` ${fmt.green(field.name)}: ${field.type}`);\n lines.push(` ${fmt.dim(field.description)}`);\n }\n lines.push('');\n\n lines.push(fmt.bold('Output Schema'));\n lines.push('─'.repeat(60));\n for (const field of extracted.outputFields) {\n lines.push(` ${fmt.green(field.name)}: ${field.type}`);\n lines.push(` ${fmt.dim(field.description)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Extract command handler.\n */\nexport async function extractCommand(options: ExtractOptions): Promise<void> {\n const projectRoot = process.cwd();\n\n try {\n // Determine source type and path\n let extracted: ExtractedAtom;\n\n if (options.skill) {\n extracted = await extractFromSkill(options.skill);\n } else if (options.bmad) {\n extracted = await extractFromBmad(options.bmad);\n } else if (options.mcp) {\n extracted = await extractFromMcp(options.mcp);\n } else if (options.code) {\n extracted = await extractFromCode(options.code);\n } else {\n throw new Error(\n 'No source specified.\\n' +\n 'Use one of: --skill <path>, --bmad <path>, --mcp <path>, --code <path>'\n );\n }\n\n // Display proposed definition\n if (!options.json) {\n console.log(formatExtractedAtom(extracted));\n console.log('');\n }\n\n // If --yes not specified and not in JSON mode, show preview and exit\n if (!options.yes && !options.json) {\n console.log(fmt.yellow('Use --yes to automatically create the atom.'));\n console.log(fmt.dim('Use --json for programmatic output.'));\n return;\n }\n\n // If --yes not specified but in JSON mode, output dry-run with wouldWriteTo\n if (!options.yes && options.json) {\n const outputDir = options.output\n ? resolveAtomPath(options.output, projectRoot)\n : join(projectRoot, 'atoms');\n const result: ExtractResult & { wouldWriteTo?: { atom: string; test: string } } = {\n success: true,\n extracted,\n wouldWriteTo: {\n atom: join(outputDir, `${extracted.name}.ts`),\n test: join(outputDir, `${extracted.name}.test.ts`),\n },\n };\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n // Initialize storage if needed\n const atomicPath = join(projectRoot, ATOMIC_DIR);\n if (!(await fileExists(atomicPath))) {\n await initStorage(projectRoot);\n }\n\n // Determine output directory\n const outputDir = options.output\n ? resolveAtomPath(options.output, projectRoot)\n : join(projectRoot, 'atoms');\n\n await mkdir(outputDir, { recursive: true });\n\n // Check if files already exist (with path containment guard)\n const atomPath = join(outputDir, `${extracted.name}.ts`);\n const testPath = join(outputDir, `${extracted.name}.test.ts`);\n const resolvedOutputDir = resolve(outputDir);\n const rel = relative(resolvedOutputDir, resolve(atomPath));\n if (rel.startsWith('..') || isAbsolute(rel)) {\n throw new Error('Generated path escapes output directory');\n }\n\n if (await fileExists(atomPath)) {\n throw new Error(`Atom file already exists: ${atomPath}`);\n }\n if (await fileExists(testPath)) {\n throw new Error(`Test file already exists: ${testPath}`);\n }\n\n // Write files\n await writeFile(atomPath, generateAtomTemplate(extracted));\n await writeFile(testPath, generateTestTemplate(extracted));\n\n // Output result\n const result: ExtractResult = {\n success: true,\n extracted,\n atomPath,\n testPath,\n };\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(fmt.green('✓ Atom extracted successfully'));\n console.log(` ${fmt.dim('Atom:')} ${atomPath}`);\n console.log(` ${fmt.dim('Test:')} ${testPath}`);\n console.log('');\n console.log('Next steps:');\n console.log(` 1. Review and edit ${atomPath}`);\n console.log(` 2. Run: atomic register ${atomPath}`);\n }\n } catch (err) {\n const message = toErrorMessage(err);\n if (options.json) {\n const { deriveErrorCode } = await import('./helpers.js');\n console.log(JSON.stringify({ success: false, error: message, errorCode: deriveErrorCode(err) }, null, 2));\n } else {\n console.error(fmt.error(`Extraction failed: ${message}`));\n }\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["inputFields","outputDir","result"]}
1
+ {"version":3,"sources":["../src/commands/extract.ts"],"sourcesContent":["/**\n * Extract command - Create atoms from existing sources.\n *\n * Story 1.10: AOP-1216\n *\n * Acceptance Criteria:\n * - Extract from Claude Code skills, BMAD workflows, MCP tools, or code\n * - Analyze source for input parameters, output format, description\n * - Display proposed atom definition for user approval\n * - Create atom file with extracted structure\n */\n\nimport { readFile, stat, mkdir, writeFile } from 'node:fs/promises';\nimport { join, basename, dirname, resolve, relative, isAbsolute } from 'node:path';\nimport { fmt } from '../cli/format.js';\nimport { initStorage, ATOMIC_DIR, fileExists } from '../storage/index.js';\nimport { toErrorMessage } from '../utils/errors.js';\nimport { resolveAtomPath } from '../utils/paths.js';\n\n/**\n * Options for the extract command.\n */\nexport interface ExtractOptions {\n skill?: string;\n bmad?: string;\n mcp?: string;\n code?: string;\n output?: string;\n yes?: boolean;\n json?: boolean;\n}\n\n/**\n * A single extracted field with human-readable type and Zod code-gen token.\n */\nexport interface ExtractedField {\n name: string;\n type: string; // human label: 'string', 'number', etc.\n zodType: string; // code-gen token: 'z.string()', 'z.number()', etc.\n description: string;\n}\n\n/**\n * Extracted atom definition.\n */\nexport interface ExtractedAtom {\n name: string;\n description: string;\n inputFields: ExtractedField[];\n outputFields: ExtractedField[];\n sourceType: 'skill' | 'bmad' | 'mcp' | 'code';\n sourcePath: string;\n}\n\n/**\n * Result of extraction.\n */\nexport interface ExtractResult {\n success: boolean;\n extracted?: ExtractedAtom;\n atomPath?: string;\n testPath?: string;\n error?: string;\n}\n\n/**\n * Parse YAML frontmatter from markdown content.\n *\n * Note: This is a simple parser that handles basic key: value pairs.\n * It does not support quoted values with colons, multi-line strings,\n * or nested structures. For complex YAML, consider using a proper parser.\n */\nfunction parseFrontmatter(content: string): Record<string, string> {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match || !match[1]) {\n return {};\n }\n\n const frontmatter: Record<string, string> = {};\n const lines = match[1].split('\\n');\n\n for (const line of lines) {\n const colonIndex = line.indexOf(':');\n if (colonIndex > 0) {\n const key = line.substring(0, colonIndex).trim();\n const value = line.substring(colonIndex + 1).trim();\n frontmatter[key] = value;\n }\n }\n\n return frontmatter;\n}\n\n/**\n * Convert a name to snake_case.\n */\nfunction toSnakeCase(name: string): string {\n return name\n .replace(/[^a-zA-Z0-9]+/g, '_')\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .toLowerCase()\n .replace(/^_+|_+$/g, '')\n .replace(/_+/g, '_');\n}\n\n/** Valid JS identifier pattern for field names in generated code. */\nconst VALID_JS_IDENTIFIER = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\n/**\n * Validate that a zodType string is a safe Zod expression.\n * zodType is injected as raw code — structural validation prevents code injection.\n * Matches only the patterns produced by tsTypeToZodType/jsonSchemaTypeToZodType:\n * z.method() — z.string(), z.number(), etc.\n * z.method(z.method()) — z.array(z.string())\n * z.method(z.method(), z.method()) — z.record(z.string(), z.number())\n * z.enum([\"a\", \"b\"]) — enum with JSON-stringified values\n * any of the above + .optional() — optional modifier\n */\nfunction isSafeZodType(expr: string): boolean {\n const base = expr.replace(/\\.optional\\(\\)$/, '');\n // Simple: z.string(), z.number(), z.unknown(), etc.\n if (/^z\\.[a-z]+\\(\\)$/.test(base)) return true;\n // Wrapper: z.array(z.string()), z.record(z.string(), z.number())\n if (/^z\\.[a-z]+\\(z\\.[a-z]+\\(\\)(, z\\.[a-z]+\\(\\))?\\)$/.test(base)) return true;\n // Enum: z.enum([\"a\", \"b\", \"c\"]) — values are JSON.stringify'd (no unescaped quotes/backslashes)\n if (/^z\\.enum\\(\\[(\"[^\"\\\\]*\"(, \"[^\"\\\\]*\")*)\\]\\)$/.test(base)) return true;\n return false;\n}\n\n/**\n * Map a TypeScript type annotation string to a Zod type expression.\n */\nfunction tsTypeToZodType(tsType: string | undefined): string {\n if (!tsType) return 'z.unknown()';\n switch (tsType) {\n case 'string': return 'z.string()';\n case 'number': return 'z.number()';\n case 'boolean': return 'z.boolean()';\n case 'Date': return 'z.date()';\n case 'bigint': return 'z.bigint()';\n case 'void': return 'z.void()';\n case 'undefined': return 'z.undefined()';\n case 'null': return 'z.null()';\n case 'any': return 'z.any()';\n case 'unknown': return 'z.unknown()';\n case 'never': return 'z.never()';\n default:\n if (tsType.endsWith('[]')) {\n const inner = tsTypeToZodType(tsType.slice(0, -2));\n return `z.array(${inner})`;\n }\n if (tsType.startsWith('Record<')) {\n const match = tsType.match(/^Record<(.+),\\s*(.+)>$/);\n if (match) {\n return `z.record(${tsTypeToZodType(match[1])}, ${tsTypeToZodType(match[2])})`;\n }\n }\n return 'z.unknown()';\n }\n}\n\n/**\n * Map a JSON Schema type string to a Zod type expression.\n */\nfunction jsonSchemaTypeToZodType(schemaType: string | undefined): string {\n switch (schemaType) {\n case 'string': return 'z.string()';\n case 'number': case 'integer': return 'z.number()';\n case 'boolean': return 'z.boolean()';\n case 'array': return 'z.array(z.unknown())';\n case 'object': return 'z.record(z.string(), z.unknown())';\n case 'null': return 'z.null()';\n default: return 'z.unknown()';\n }\n}\n\n/**\n * Escape sourcePath to prevent comment injection (close-comment sequence).\n */\nexport function escapeSourcePath(path: string): string {\n return path.replace(/\\*\\//g, '*\\\\/');\n}\n\n/**\n * Extract atom from Claude Code skill.\n */\nasync function extractFromSkill(skillPath: string): Promise<ExtractedAtom> {\n const resolvedPath = resolveAtomPath(skillPath, process.cwd());\n\n // Check if it's a directory or file\n const stats = await stat(resolvedPath);\n let skillContent: string;\n let skillFile: string;\n\n if (stats.isDirectory()) {\n // Look for SKILL.md in directory\n skillFile = join(resolvedPath, 'SKILL.md');\n if (!(await fileExists(skillFile))) {\n throw new Error(`No SKILL.md found in ${resolvedPath}`);\n }\n skillContent = await readFile(skillFile, 'utf-8');\n } else {\n // Direct file path\n skillFile = resolvedPath;\n skillContent = await readFile(skillFile, 'utf-8');\n }\n\n // Parse frontmatter\n const frontmatter = parseFrontmatter(skillContent);\n const name = frontmatter['name'] || basename(dirname(skillFile));\n const description = frontmatter['description'] || 'Extracted from Claude Code skill';\n\n // Analyze content for input/output patterns\n const inputFields = analyzeSkillInputs(skillContent);\n const outputFields = analyzeSkillOutputs(skillContent);\n\n return {\n name: toSnakeCase(name),\n description,\n inputFields,\n outputFields,\n sourceType: 'skill',\n sourcePath: skillFile,\n };\n}\n\n/**\n * Analyze content for field patterns matching a set of regexes.\n * Shared logic for input/output field extraction from skill documentation.\n */\nfunction analyzeFieldPatterns(\n content: string,\n patterns: RegExp[],\n defaultField: { name: string; description: string },\n descriptionSuffix: string,\n): ExtractedAtom['inputFields'] {\n const found = new Set<string>();\n\n for (const pattern of patterns) {\n for (const match of content.matchAll(pattern)) {\n const name = match[1]?.toLowerCase();\n if (name && !found.has(name) && name.length > 2) {\n found.add(name);\n }\n }\n }\n\n if (found.size === 0) {\n return [{ name: defaultField.name, type: 'string', zodType: 'z.string()', description: defaultField.description }];\n }\n\n const fields: ExtractedAtom['inputFields'] = [];\n for (const name of found) {\n fields.push({ name: toSnakeCase(name), type: 'string', zodType: 'z.string()', description: `${name} ${descriptionSuffix}` });\n }\n return fields.slice(0, 5);\n}\n\nconst INPUT_PATTERNS = [\n /accepts?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n /input[:\\s]+([a-z_]+)/gi,\n /receives?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n /takes?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n];\n\nconst OUTPUT_PATTERNS = [\n /outputs?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n /returns?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n /produces?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n /generates?\\s+(?:an?\\s+)?([a-z_]+)/gi,\n];\n\nfunction analyzeSkillInputs(content: string): ExtractedAtom['inputFields'] {\n return analyzeFieldPatterns(content, INPUT_PATTERNS, { name: 'input', description: 'Input data to process' }, 'parameter');\n}\n\nfunction analyzeSkillOutputs(content: string): ExtractedAtom['outputFields'] {\n return analyzeFieldPatterns(content, OUTPUT_PATTERNS, { name: 'result', description: 'Processing result' }, 'output');\n}\n\n/**\n * Extract atom from BMAD workflow.\n */\nasync function extractFromBmad(bmadPath: string): Promise<ExtractedAtom> {\n const resolvedPath = resolveAtomPath(bmadPath, process.cwd());\n\n if (!(await fileExists(resolvedPath))) {\n throw new Error(`BMAD workflow not found: ${resolvedPath}`);\n }\n\n const content = await readFile(resolvedPath, 'utf-8');\n const frontmatter = parseFrontmatter(content);\n\n const name = frontmatter['name'] || basename(resolvedPath, '.md');\n const description = frontmatter['description'] || 'Extracted from BMAD workflow';\n\n return {\n name: toSnakeCase(name),\n description,\n inputFields: [{ name: 'context', type: 'string', zodType: 'z.string()', description: 'Workflow context' }],\n outputFields: [{ name: 'result', type: 'string', zodType: 'z.string()', description: 'Workflow result' }],\n sourceType: 'bmad',\n sourcePath: resolvedPath,\n };\n}\n\n/**\n * Extract atom from MCP tool definition.\n */\nasync function extractFromMcp(mcpPath: string): Promise<ExtractedAtom> {\n const resolvedPath = resolveAtomPath(mcpPath, process.cwd());\n\n if (!(await fileExists(resolvedPath))) {\n throw new Error(`MCP tool definition not found: ${resolvedPath}`);\n }\n\n const content = await readFile(resolvedPath, 'utf-8');\n\n // Try to parse as JSON (MCP tool definitions are often JSON)\n let mcpDef: { name?: string; description?: string; inputSchema?: unknown };\n try {\n mcpDef = JSON.parse(content);\n } catch (err) {\n // If not JSON, warn and treat as a generic definition\n console.warn(\n fmt.yellow(`Warning: Could not parse MCP definition as JSON: ${toErrorMessage(err)}`)\n );\n mcpDef = { name: basename(resolvedPath, '.json') };\n }\n\n const name = mcpDef.name || basename(resolvedPath, '.json');\n const description = mcpDef.description || 'Extracted from MCP tool';\n\n // Extract input fields from inputSchema if present\n const inputFields: ExtractedAtom['inputFields'] = [];\n if (mcpDef.inputSchema && typeof mcpDef.inputSchema === 'object') {\n const schema = mcpDef.inputSchema as {\n properties?: Record<string, { type?: string; description?: string; enum?: string[] }>;\n required?: string[];\n };\n const required = new Set(schema.required ?? []);\n if (schema.properties) {\n for (const [key, value] of Object.entries(schema.properties)) {\n let zodType: string;\n if (value.enum) {\n zodType = `z.enum([${value.enum.map(v => JSON.stringify(v)).join(', ')}])`;\n } else {\n zodType = jsonSchemaTypeToZodType(value.type);\n }\n if (!required.has(key)) {\n zodType += '.optional()';\n }\n inputFields.push({\n name: toSnakeCase(key),\n type: value.type ?? 'unknown',\n zodType,\n description: value.description || `${key} parameter`,\n });\n }\n }\n }\n\n if (inputFields.length === 0) {\n inputFields.push({ name: 'input', type: 'string', zodType: 'z.string()', description: 'Tool input' });\n }\n\n return {\n name: toSnakeCase(name),\n description,\n inputFields,\n outputFields: [{ name: 'result', type: 'string', zodType: 'z.string()', description: 'Tool result' }],\n sourceType: 'mcp',\n sourcePath: resolvedPath,\n };\n}\n\n/**\n * Extract atom from existing code file using AST-based extraction.\n *\n * For JS/TS files, uses oxc-parser via dynamic import to extract typed\n * function signatures. Falls back to regex for non-JS/TS or parse failures.\n * The dynamic import ensures oxc-parser is only loaded when --code is used.\n */\nasync function extractFromCode(codePath: string): Promise<ExtractedAtom> {\n const resolvedPath = resolveAtomPath(codePath, process.cwd());\n\n if (!(await fileExists(resolvedPath))) {\n throw new Error(`Code file not found: ${resolvedPath}`);\n }\n\n const content = await readFile(resolvedPath, 'utf-8');\n const name = basename(resolvedPath).replace(/\\.[^.]+$/, '');\n\n // Extract description from JSDoc or first comment\n let description = 'Extracted from code';\n const jsdocMatch = content.match(/\\/\\*\\*\\s*\\n\\s*\\*\\s*([^\\n]+)/);\n if (jsdocMatch && jsdocMatch[1]) {\n description = jsdocMatch[1].trim();\n }\n\n // Try AST-based extraction for JS/TS files\n const { detectLanguage, isJavaScriptFamily, parseFile } = await import('../parser/index.js');\n const { extractSignatures } = await import('../parser/signatures.js');\n const lang = detectLanguage(resolvedPath);\n const jsFamily = lang && isJavaScriptFamily(lang);\n\n if (jsFamily) {\n try {\n\n const parseResult = await parseFile(content, resolvedPath);\n if (parseResult.success && parseResult.language !== 'python') {\n const sigs = extractSignatures(parseResult.ast, content, parseResult.comments);\n // Pick primary export: first default export, or first named export\n const primary = sigs.find(s => s.exportDefault) ?? sigs.find(s => s.exported) ?? sigs[0];\n\n if (primary) {\n const inputFields: ExtractedAtom['inputFields'] = primary.params\n .filter(p => {\n const fieldName = toSnakeCase(p.name);\n return VALID_JS_IDENTIFIER.test(fieldName);\n })\n .map(p => ({\n name: toSnakeCase(p.name),\n type: p.type ?? 'unknown',\n zodType: tsTypeToZodType(p.type),\n description: `${p.name} parameter`,\n }));\n\n if (inputFields.length === 0) {\n inputFields.push({ name: 'input', type: 'unknown', zodType: 'z.unknown()', description: 'Function input' });\n }\n\n return {\n name: toSnakeCase(name),\n description,\n inputFields,\n outputFields: [{ name: 'result', type: 'string', zodType: 'z.string()', description: 'Function result' }],\n sourceType: 'code',\n sourcePath: resolvedPath,\n };\n }\n }\n // Parse succeeded but no functions found — fall through to regex\n } catch {\n // AST parse failed — fall through to regex fallback\n }\n }\n\n // Regex fallback for non-JS/TS files or parse failures\n const inputFields: ExtractedAtom['inputFields'] = [];\n const functionMatch = content.match(/(?:function|const|let|var)\\s+\\w+\\s*[=:]\\s*(?:async\\s+)?(?:\\([^)]*\\)|[^=]+=>)/);\n if (functionMatch && functionMatch[0]) {\n const paramMatch = functionMatch[0].match(/\\(([^)]*)\\)/);\n if (paramMatch && paramMatch[1]) {\n const paramsStr = paramMatch[1];\n const params = paramsStr.split(',').map((p) => p.trim().split(':')[0]?.trim() ?? '');\n for (const param of params) {\n if (param && param !== '' && !param.startsWith('{')) {\n inputFields.push({\n name: toSnakeCase(param),\n type: 'string',\n zodType: 'z.string()',\n description: `${param} parameter`,\n });\n }\n }\n }\n }\n\n if (inputFields.length === 0) {\n inputFields.push({ name: 'input', type: 'string', zodType: 'z.string()', description: 'Function input' });\n }\n\n return {\n name: toSnakeCase(name),\n description,\n inputFields,\n outputFields: [{ name: 'result', type: 'string', zodType: 'z.string()', description: 'Function result' }],\n sourceType: 'code',\n sourcePath: resolvedPath,\n };\n}\n\n/**\n * Escape a string for use in a single-quoted TypeScript string literal.\n */\nfunction escapeForTemplate(str: string): string {\n return str\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/'/g, \"\\\\'\")\n .replace(/`/g, '\\\\`')\n .replace(/\\$\\{/g, '\\\\${')\n .replace(/\\*\\//g, '* /')\n .replace(/\\n/g, ' ')\n .replace(/\\r/g, '');\n}\n\n/**\n * Generate atom template from extracted definition.\n */\nfunction generateAtomTemplate(extracted: ExtractedAtom): string {\n const escapedName = escapeForTemplate(extracted.name);\n const escapedDescription = escapeForTemplate(extracted.description);\n const escapedPath = escapeSourcePath(extracted.sourcePath);\n\n // Filter fields to valid JS identifiers and safe Zod types only\n const safeInputFields = extracted.inputFields\n .filter(f => VALID_JS_IDENTIFIER.test(f.name) && isSafeZodType(f.zodType));\n const safeOutputFields = extracted.outputFields\n .filter(f => VALID_JS_IDENTIFIER.test(f.name) && isSafeZodType(f.zodType));\n\n const droppedInputCount = extracted.inputFields.length - safeInputFields.length;\n const droppedOutputCount = extracted.outputFields.length - safeOutputFields.length;\n if (droppedInputCount > 0 || droppedOutputCount > 0) {\n const parts: string[] = [];\n if (droppedInputCount > 0) parts.push(`${droppedInputCount} input`);\n if (droppedOutputCount > 0) parts.push(`${droppedOutputCount} output`);\n console.error(fmt.warning(`Dropped ${parts.join(' and ')} field(s) with unsafe or invalid schema types`));\n }\n\n const inputSchema = safeInputFields\n .map((f) => ` ${f.name}: ${f.zodType}.describe('${escapeForTemplate(f.description)}'),`)\n .join('\\n');\n\n const outputSchema = safeOutputFields\n .map((f) => ` ${f.name}: ${f.zodType}.describe('${escapeForTemplate(f.description)}'),`)\n .join('\\n');\n\n const inputDestructure = safeInputFields.map((f) => f.name).join(', ');\n\n return `import { defineAtom, success, executionError, z } from 'atomism';\n\n/**\n * ${escapedName} atom\n *\n * ${escapeForTemplate(extracted.description)}\n *\n * Extracted from: ${extracted.sourceType} at ${escapedPath}\n */\nexport default defineAtom({\n name: '${escapedName}',\n description: '${escapedDescription}',\n input: z.object({\n${inputSchema}\n }),\n output: z.object({\n${outputSchema}\n }),\n tests: {\n path: './${escapedName}.test.ts',\n },\n idempotent: true,\n handler: async ({ ${inputDestructure} }) => {\n // TODO: Implement handler logic\n // Original source: ${escapedPath}\n\n return success({\n${safeOutputFields.map((f) => ` ${f.name}: '',`).join('\\n')}\n });\n },\n});\n`;\n}\n\n/**\n * Generate test template from extracted definition.\n */\nfunction generateTestTemplate(extracted: ExtractedAtom): string {\n const escapedName = escapeForTemplate(extracted.name);\n const safeInputFields = extracted.inputFields.filter(f => VALID_JS_IDENTIFIER.test(f.name));\n return `import { describe, it, expect } from 'vitest';\nimport atom from './${escapedName}.js';\n\ndescribe('${escapedName}', () => {\n describe('input validation', () => {\n${safeInputFields.map((f) => ` it.todo('validates ${f.name} field');`).join('\\n')}\n });\n\n describe('handler behavior', () => {\n it.todo('processes valid input correctly');\n it.todo('returns expected output structure');\n });\n\n describe('error handling', () => {\n it.todo('handles invalid input gracefully');\n });\n});\n`;\n}\n\n/**\n * Format extracted definition for display.\n */\nfunction formatExtractedAtom(extracted: ExtractedAtom): string {\n const lines: string[] = [];\n\n lines.push(fmt.bold('Proposed Atom Definition'));\n lines.push('─'.repeat(60));\n lines.push(` ${fmt.dim('Name:')} ${fmt.cyan(extracted.name)}`);\n lines.push(` ${fmt.dim('Source:')} ${extracted.sourceType} (${extracted.sourcePath})`);\n lines.push(` ${fmt.dim('Description:')} ${extracted.description.substring(0, 60)}${extracted.description.length > 60 ? '...' : ''}`);\n lines.push('');\n\n lines.push(fmt.bold('Input Schema'));\n lines.push('─'.repeat(60));\n for (const field of extracted.inputFields) {\n lines.push(` ${fmt.green(field.name)}: ${field.type}`);\n lines.push(` ${fmt.dim(field.description)}`);\n }\n lines.push('');\n\n lines.push(fmt.bold('Output Schema'));\n lines.push('─'.repeat(60));\n for (const field of extracted.outputFields) {\n lines.push(` ${fmt.green(field.name)}: ${field.type}`);\n lines.push(` ${fmt.dim(field.description)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Extract command handler.\n */\nexport async function extractCommand(options: ExtractOptions): Promise<void> {\n const projectRoot = process.cwd();\n\n try {\n // Determine source type and path\n let extracted: ExtractedAtom;\n\n if (options.skill) {\n extracted = await extractFromSkill(options.skill);\n } else if (options.bmad) {\n extracted = await extractFromBmad(options.bmad);\n } else if (options.mcp) {\n extracted = await extractFromMcp(options.mcp);\n } else if (options.code) {\n extracted = await extractFromCode(options.code);\n } else {\n throw new Error(\n 'No source specified.\\n' +\n 'Use one of: --skill <path>, --bmad <path>, --mcp <path>, --code <path>'\n );\n }\n\n // Display proposed definition\n if (!options.json) {\n console.log(formatExtractedAtom(extracted));\n console.log('');\n }\n\n // If --yes not specified and not in JSON mode, show preview and exit\n if (!options.yes && !options.json) {\n console.log(fmt.yellow('Use --yes to automatically create the atom.'));\n console.log(fmt.dim('Use --json for programmatic output.'));\n return;\n }\n\n // If --yes not specified but in JSON mode, output dry-run with wouldWriteTo\n if (!options.yes && options.json) {\n const outputDir = options.output\n ? resolveAtomPath(options.output, projectRoot)\n : join(projectRoot, 'atoms');\n const result: ExtractResult & { wouldWriteTo?: { atom: string; test: string } } = {\n success: true,\n extracted,\n wouldWriteTo: {\n atom: join(outputDir, `${extracted.name}.ts`),\n test: join(outputDir, `${extracted.name}.test.ts`),\n },\n };\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n // Initialize storage if needed\n const atomicPath = join(projectRoot, ATOMIC_DIR);\n if (!(await fileExists(atomicPath))) {\n await initStorage(projectRoot);\n }\n\n // Determine output directory\n const outputDir = options.output\n ? resolveAtomPath(options.output, projectRoot)\n : join(projectRoot, 'atoms');\n\n await mkdir(outputDir, { recursive: true });\n\n // Check if files already exist (with path containment guard)\n const atomPath = join(outputDir, `${extracted.name}.ts`);\n const testPath = join(outputDir, `${extracted.name}.test.ts`);\n const resolvedOutputDir = resolve(outputDir);\n const rel = relative(resolvedOutputDir, resolve(atomPath));\n if (isAbsolute(rel) || rel.startsWith('..')) {\n throw new Error('Generated path escapes output directory');\n }\n\n if (await fileExists(atomPath)) {\n throw new Error(`Atom file already exists: ${atomPath}`);\n }\n if (await fileExists(testPath)) {\n throw new Error(`Test file already exists: ${testPath}`);\n }\n\n // Write files\n await writeFile(atomPath, generateAtomTemplate(extracted));\n await writeFile(testPath, generateTestTemplate(extracted));\n\n // Output result\n const result: ExtractResult = {\n success: true,\n extracted,\n atomPath,\n testPath,\n };\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(fmt.green('✓ Atom extracted successfully'));\n console.log(` ${fmt.dim('Atom:')} ${atomPath}`);\n console.log(` ${fmt.dim('Test:')} ${testPath}`);\n console.log('');\n console.log('Next steps:');\n console.log(` 1. Review and edit ${atomPath}`);\n console.log(` 2. Run: atomic register ${atomPath}`);\n }\n } catch (err) {\n const message = toErrorMessage(err);\n if (options.json) {\n const { deriveErrorCode } = await import('./helpers.js');\n console.log(JSON.stringify({ success: false, error: message, errorCode: deriveErrorCode(err) }, null, 2));\n } else {\n console.error(fmt.error(`Extraction failed: ${message}`));\n }\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["inputFields","outputDir","result"]}
@@ -608,7 +608,8 @@ async function ensureDeps(projectRoot) {
608
608
  try {
609
609
  execSync(`node -e "require.resolve('atomism')"`, {
610
610
  cwd: projectRoot,
611
- stdio: "ignore"
611
+ stdio: "ignore",
612
+ timeout: 5e3
612
613
  });
613
614
  return { success: true, packageJsonCreated, tsconfigCreated, tsconfigNeedsInclude, suggestedInclude, atomismLinked };
614
615
  } catch {
@@ -738,4 +739,4 @@ async function initCommand(options) {
738
739
  export {
739
740
  initCommand
740
741
  };
741
- //# sourceMappingURL=init-2FINDMYK.js.map
742
+ //# sourceMappingURL=init-EH6ZWP5R.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/init.ts","../src/commands/skills-init.ts","../src/commands/claude-md-init.ts","../src/commands/gitignore-init.ts"],"sourcesContent":["import { readFile, writeFile, access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { initStorage } from '../storage/index.js';\nimport { initSkill } from './skills-init.js';\nimport { initClaudeMd } from './claude-md-init.js';\nimport { initGitignore } from './gitignore-init.js';\nimport { toErrorMessage } from '../utils/errors.js';\nimport { withErrorHandling } from './helpers.js';\n\nexport interface InitOptions {\n json?: boolean;\n}\n\ninterface DepsResult {\n success: boolean;\n packageJsonCreated: boolean;\n tsconfigCreated: boolean;\n tsconfigNeedsInclude?: boolean;\n suggestedInclude?: string;\n atomismLinked: boolean;\n error?: string;\n}\n\n/**\n * Ensure the project can resolve 'atomism' and 'zod' as modules.\n *\n * Atoms are TypeScript files that import from 'atomism'. Without a local\n * package.json that resolves the module, `atomic register` and any TS\n * tooling will fail with \"Cannot find module 'atomism'\".\n */\nasync function ensureDeps(projectRoot: string): Promise<DepsResult> {\n const pkgPath = join(projectRoot, 'package.json');\n const tsconfigPath = join(projectRoot, 'tsconfig.json');\n let packageJsonCreated = false;\n let tsconfigCreated = false;\n let atomismLinked = false;\n\n // 1. Ensure package.json exists\n let hasPackageJson = false;\n try {\n await access(pkgPath);\n hasPackageJson = true;\n } catch {\n // No package.json — create a minimal one\n }\n\n if (!hasPackageJson) {\n const minimal = {\n private: true,\n description: 'Atomism-enabled project',\n dependencies: {},\n };\n await writeFile(pkgPath, JSON.stringify(minimal, null, 2) + '\\n');\n packageJsonCreated = true;\n }\n\n // 2. Ensure tsconfig.json exists (required for TS type inference in atoms)\n let hasTsconfig = false;\n try {\n await access(tsconfigPath);\n hasTsconfig = true;\n } catch {\n // No tsconfig.json\n }\n\n let tsconfigNeedsInclude: boolean | undefined;\n let suggestedInclude: string | undefined;\n\n if (hasTsconfig) {\n // Check if existing tsconfig includes atom files\n try {\n const raw = await readFile(tsconfigPath, 'utf-8');\n const parsed = JSON.parse(raw);\n const includes: string[] = Array.isArray(parsed.include) ? parsed.include : [];\n const coversAtoms = includes.some((pattern: string) =>\n pattern === 'atoms/**/*.ts' ||\n pattern.startsWith('atoms/') ||\n pattern === '**/*.ts' ||\n pattern === './**/*.ts'\n );\n if (!coversAtoms) {\n tsconfigNeedsInclude = true;\n suggestedInclude = 'atoms/**/*.ts';\n }\n } catch {\n // tsconfig parse failure is non-fatal — skip the check\n }\n } else {\n const tsconfig = {\n compilerOptions: {\n target: 'ES2022',\n module: 'ESNext',\n moduleResolution: 'bundler',\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n outDir: 'dist',\n },\n include: ['atoms/**/*.ts'],\n };\n await writeFile(tsconfigPath, JSON.stringify(tsconfig, null, 2) + '\\n');\n tsconfigCreated = true;\n }\n\n // 3. Check if atomism is resolvable\n try {\n execSync('node -e \"require.resolve(\\'atomism\\')\"', {\n cwd: projectRoot,\n stdio: 'ignore',\n timeout: 5000,\n });\n // Already resolvable\n return { success: true, packageJsonCreated, tsconfigCreated, tsconfigNeedsInclude, suggestedInclude, atomismLinked };\n } catch {\n // Not resolvable — try to link it\n }\n\n // 4. Link atomism (works when atomism is installed globally via npm link)\n try {\n execSync('npm link atomism', {\n cwd: projectRoot,\n stdio: 'ignore',\n timeout: 30000,\n });\n atomismLinked = true;\n } catch {\n return {\n success: false,\n packageJsonCreated,\n tsconfigCreated,\n tsconfigNeedsInclude,\n suggestedInclude,\n atomismLinked: false,\n error: 'Could not resolve atomism. Run: npm link atomism (if globally installed) or npm install atomism',\n };\n }\n\n return { success: true, packageJsonCreated, tsconfigCreated, tsconfigNeedsInclude, suggestedInclude, atomismLinked };\n}\n\nexport async function initCommand(options: InitOptions): Promise<void> {\n await withErrorHandling(options, async () => {\n const projectRoot = process.cwd();\n const result = await initStorage(projectRoot);\n\n // Ensure module resolution (non-fatal — warn but continue)\n let depsResult: DepsResult;\n try {\n depsResult = await ensureDeps(projectRoot);\n } catch (depsError) {\n depsResult = {\n success: false,\n packageJsonCreated: false,\n tsconfigCreated: false,\n atomismLinked: false,\n error: toErrorMessage(depsError),\n };\n }\n\n // Create Claude Code skill (non-fatal)\n let skillResult: { success: boolean; skipped?: boolean; path?: string; error?: string };\n try {\n skillResult = await initSkill({ force: false });\n } catch (skillError) {\n skillResult = {\n success: false,\n error: toErrorMessage(skillError),\n };\n }\n\n // Create CLAUDE.md snippet (non-fatal)\n let claudeMdResult: { success: boolean; skipped?: boolean; path?: string; error?: string };\n try {\n claudeMdResult = await initClaudeMd();\n } catch (claudeError) {\n claudeMdResult = {\n success: false,\n error: toErrorMessage(claudeError),\n };\n }\n\n // Manage .gitignore (non-fatal)\n let gitignoreResult: { success: boolean; skipped?: boolean; path?: string; error?: string };\n try {\n gitignoreResult = await initGitignore(projectRoot);\n } catch (gitignoreError) {\n gitignoreResult = {\n success: false,\n error: toErrorMessage(gitignoreError),\n };\n }\n\n if (options.json) {\n console.log(JSON.stringify({\n ...result,\n deps: depsResult,\n skill: skillResult,\n claudeMd: claudeMdResult,\n gitignore: gitignoreResult,\n }, null, 2));\n } else {\n if (result.created) {\n console.log(`✓ Created ${result.path}`);\n } else {\n console.log(`✓ ${result.path} already exists`);\n }\n console.log(`✓ Database initialized at ${result.dbPath}`);\n console.log(`✓ ${result.migrationsRun} migrations applied`);\n\n // Report deps status\n if (depsResult.success) {\n if (depsResult.packageJsonCreated) {\n console.log('✓ Created package.json for module resolution');\n }\n if (depsResult.tsconfigCreated) {\n console.log('✓ Created tsconfig.json for atom type inference');\n }\n if (depsResult.atomismLinked) {\n console.log('✓ Linked atomism for module resolution');\n }\n } else {\n console.log(`⚠ Module resolution: ${depsResult.error ?? 'unknown error'}`);\n }\n\n // tsconfig warning is useful regardless of deps success\n if (depsResult.tsconfigNeedsInclude) {\n console.log(`⚠ tsconfig.json does not include atom files. Add to your \"include\" array:`);\n console.log(` \"${depsResult.suggestedInclude}\"`);\n }\n\n // Report skill status\n if (skillResult.success && !skillResult.skipped) {\n console.log(`✓ Claude Code skill created at ${skillResult.path}`);\n } else if (skillResult.skipped) {\n console.log('✓ Claude Code skill already exists');\n } else if (!skillResult.success) {\n console.log(`⚠ Claude Code skill creation failed: ${skillResult.error ?? 'unknown error'}`);\n }\n\n // Report CLAUDE.md status\n if (claudeMdResult.success && !claudeMdResult.skipped) {\n console.log(`✓ CLAUDE.md updated at ${claudeMdResult.path}`);\n } else if (claudeMdResult.skipped) {\n console.log('✓ CLAUDE.md already has atomism section');\n } else if (!claudeMdResult.success) {\n console.log(`⚠ CLAUDE.md update failed: ${claudeMdResult.error ?? 'unknown error'}`);\n }\n\n // Report .gitignore status\n if (gitignoreResult.success && !gitignoreResult.skipped) {\n console.log(`✓ .gitignore updated at ${gitignoreResult.path}`);\n } else if (gitignoreResult.skipped) {\n console.log('✓ .gitignore already has atomism entries');\n } else if (!gitignoreResult.success) {\n console.log(`⚠ .gitignore update failed: ${gitignoreResult.error ?? 'unknown error'}`);\n }\n\n console.log('\\nReady to register atoms with: atomic register <path>');\n console.log('Commit: registry.json, trust.json, atoms/');\n }\n });\n}\n","/**\n * Skills Init - Create Claude Code skill teaching atomic usage.\n *\n * Creates a SKILL.md in the project's .claude/skills/atomic/ directory\n * that teaches Claude Code how to effectively use the atomic CLI.\n */\n\nimport { mkdir, writeFile, stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { toErrorMessage } from '../utils/errors.js';\n\n/**\n * Generate the atomic skill content.\n */\nexport function generateSkillContent(): string {\n return `---\nname: atomic\ndescription: Schema-first agent swarm orchestration framework\n---\n\n# Atomic Framework\n\nSchema-first agent swarm orchestration. Use atomic to define, execute, and evolve reusable capabilities.\n\n## Trigger\n\nUse this skill when:\n- User mentions \"atomic\", \"atom\", \"capability\", or \"workflow\" in context of task orchestration\n- User wants to create reusable, schema-validated tasks\n- User wants to graduate patterns from probabilistic (AI) to deterministic (generator)\n- Project has \\`.atomic/\\` directory\n- User invokes \\`/atomic\\`\n\n## Why Atoms?\n\nAtoms solve a fundamental problem: **probabilistic work should become deterministic over time.**\n\nWhen you write an API route the first time, it's creative work. The tenth time you write a similar route, it should be a template fill. But without tracking, you start from scratch every time.\n\nAtoms provide:\n1. **Schema enforcement** — Inputs/outputs are Zod-validated, not freeform\n2. **Execution history** — Every run is recorded with inputs, outputs, success/failure\n3. **Similarity detection** — AST-level comparison identifies when outputs converge on patterns\n4. **Generator graduation** — When an atom produces 85%+ similar outputs, it can become a deterministic template\n5. **Trust progression** — New capabilities require review; proven ones auto-execute\n\nThe goal: **Capture patterns once, replay deterministically forever.** Focus human attention on genuinely novel problems.\n\n## When to Use Atoms\n\n| Situation | Use |\n|-----------|-----|\n| One-off task, no verification needed | Direct code |\n| Teaching Claude a capability | Claude Code skill |\n| Repetitive task, same shape each time | **Atom** (extract or create) |\n| Need trust gating / human review | **Atom with trust level** |\n| Task should evolve to template | **Atom** (graduation path) |\n| Always-on validation/enforcement | Hook |\n\n**Proactive extraction**: When you notice doing the same thing 3+ times with the same shape, suggest: \"This pattern would benefit from atomization — want me to extract it?\"\n\nUse \\`atomic extract\\` to create atoms from:\n- Existing Claude Code skills (\\`--skill\\`)\n- BMAD workflows (\\`--bmad\\`)\n- MCP tool definitions (\\`--mcp\\`)\n- Existing code files (\\`--code\\`)\n\n## Directory Structure\n\n\\`\\`\\`\nproject/\n├── .atomic/ # Metadata and storage (auto-created by init)\n│ ├── registry.json # Registered atoms and capabilities\n│ ├── trust.json # Trust levels for capability stacks\n│ └── db/ # SQLite storage for runs and artifacts\n├── .claude/\n│ └── skills/\n│ └── atomic/\n│ └── SKILL.md # This skill (auto-created by init)\n├── atoms/ # Atom source files (default location)\n│ ├── my_atom.ts\n│ └── my_atom.test.ts\n└── generators/ # Graduated generators (created by graduation)\n └── my_generator.ts\n\\`\\`\\`\n\n## Core Concepts\n\n### Atoms\nThe fundamental unit. A schema-validated, idempotent task with defined inputs/outputs.\n\n\\`\\`\\`typescript\n// atoms/create_component.ts\nimport { defineAtom, success, executionError, z } from 'atomism';\n\nexport default defineAtom({\n name: 'create_component',\n description: 'Create a React component with tests',\n input: z.object({\n name: z.string().min(1),\n type: z.enum(['functional', 'class']).default('functional'),\n }),\n output: z.object({\n componentPath: z.string(),\n testPath: z.string(),\n }),\n tests: { path: './create_component.test.ts' },\n idempotent: true,\n handler: async ({ name, type }) => {\n // Implementation here\n return success({ componentPath: '...', testPath: '...' });\n },\n});\n\\`\\`\\`\n\n### Capabilities\nRoute requests to either an atom (probabilistic) or generator (deterministic).\n\n- **Atom-backed**: AI executes with schema validation\n- **Generator-backed**: Deterministic template execution\n\n### Generators\nGraduated atoms. When an atom produces similar outputs repeatedly, it can graduate to a generator (template-based, deterministic).\n\n### Workflows\nCompositions of capabilities with dependency resolution. Like Make/Terraform - declare dependencies, system resolves execution order.\n\n### Trust Levels\n- **new**: Requires human review\n- **proven**: Track record of success, optional review\n- **trusted**: Auto-execute without review\n\n### Capability Stacks\nReusable groups of capabilities reviewed once, reused many times.\n\n## Project Initialization\n\n\\`\\`\\`bash\n# Initialize atomic in a project\natomic init\n\n# Creates:\n# .atomic/\n# registry.json # Registered atoms and capabilities\n# trust.json # Trust levels for capability stacks\n# db/ # SQLite storage for runs and artifacts\n\\`\\`\\`\n\n## Common Workflows\n\n### 1. Register an Atom\n\n\\`\\`\\`bash\n# Register a new atom\natomic register atoms/my_atom.ts\n\n# Register with capability name\natomic register atoms/my_atom.ts --capability my_capability\n\\`\\`\\`\n\n### 2. Run an Atom or Capability\n\n\\`\\`\\`bash\n# Run by atom name\natomic run my_atom --input '{\"key\": \"value\"}'\n\n# Run by capability name\natomic run my_capability --capability --input '{\"key\": \"value\"}'\n\n# Skip confirmation for non-idempotent atoms\natomic run my_atom --input '{\"key\": \"value\"}' --yes\n\\`\\`\\`\n\n### 3. Work with Workflows\n\n\\`\\`\\`bash\n# List available workflows\natomic workflow list\n\n# Run a workflow\natomic workflow run my_workflow\n\n# Resume a failed workflow\natomic workflow resume my_workflow\n\n# Preview execution plan\natomic plan my_workflow\n\\`\\`\\`\n\n### 4. Graduate to Generator\n\nWhen an atom produces consistent patterns:\n\n\\`\\`\\`bash\n# Graduate a capability to generator\natomic graduate --capability my_capability\n\n# Skip confirmation\natomic graduate --capability my_capability --yes\n\\`\\`\\`\n\n### 5. Manage Trust\n\n\\`\\`\\`bash\n# List all stacks with trust levels\natomic trust --list\n\n# View specific stack\natomic trust my_stack\n\n# Set trust level\natomic trust my_stack --level proven\n\n# Reset to new\natomic trust my_stack --reset\n\\`\\`\\`\n\n## Command Reference\n\n| Command | Description |\n|---------|-------------|\n| \\`atomic init\\` | Initialize .atomic/ directory and skill |\n| \\`atomic register <path>\\` | Register an atom file |\n| \\`atomic list\\` | List atoms and capabilities |\n| \\`atomic run <target>\\` | Execute atom or capability |\n| \\`atomic test <atom>\\` | Run tests for an atom |\n| \\`atomic test-gen <path>\\` | Generate structural tests |\n| \\`atomic extract\\` | Create atom from skill/bmad/mcp/code |\n| \\`atomic workflow run <name>\\` | Execute a workflow |\n| \\`atomic workflow list\\` | List available workflows |\n| \\`atomic workflow resume <name>\\` | Resume failed workflow |\n| \\`atomic plan <workflow>\\` | Preview execution plan |\n| \\`atomic graduate\\` | Graduate capability to generator |\n| \\`atomic trust [stack]\\` | Manage trust levels |\n| \\`atomic status\\` | Show system state |\n| \\`atomic history [runId]\\` | Show execution history |\n| \\`atomic escalate\\` | Create Beads issue for problems |\n| \\`atomic skills scan\\` | Discover available skills |\n| \\`atomic skills suggest <atom>\\` | Get skill recommendations |\n| \\`atomic skills assign <atom>\\` | Assign skill to atom |\n| \\`atomic skills list <atom>\\` | List atom's assigned skills |\n| \\`atomic skills remove <atom>\\` | Remove skill from atom |\n| \\`atomic scan-generators\\` | Detect existing generators |\n| \\`atomic import-generator\\` | Import from Plop/Hygen/etc |\n| \\`atomic validate-generator\\` | Validate imported generators |\n\n## Best Practices\n\n### 1. Atoms Should Be\n\n- **Small**: Single responsibility\n- **Idempotent**: Same input = same output (or no adverse effects)\n- **Schema-validated**: Zod schemas for input/output\n- **Tested**: Include test file path in definition\n- **Descriptive**: Clear name and description\n\n### 2. Naming Conventions\n\n- Atom names: \\`snake_case\\` (e.g., \\`create_component\\`, \\`run_migration\\`)\n- Capability names: \\`snake_case\\`\n- Workflow names: \\`snake_case\\`\n- Stack names: \\`snake_case\\`\n\n### 3. Error Handling\n\nUse structured errors:\n\n\\`\\`\\`typescript\nimport { failure, validationError, executionError } from 'atomism';\n\n// Validation error (bad input — recoverable by default)\nreturn validationError('Name cannot be empty');\n\n// Execution error (runtime failure)\nreturn executionError('Database connection failed', true /* recoverable */);\n\n// Generic failure (full AtomError object)\nreturn failure({ type: 'execution', message: 'Something went wrong', recoverable: false });\n\\`\\`\\`\n\n### 4. Trust Progression\n\n1. Start capabilities at \\`new\\` (human review required)\n2. After successful executions, promote to \\`proven\\`\n3. Only promote to \\`trusted\\` for well-tested, stable capabilities\n4. Demote immediately if issues arise\n\n### 5. Generator Graduation\n\nGraduate when:\n- Atom produces 85%+ structurally similar outputs\n- Pattern is well-understood\n- Template can capture the variation\n\nDon't graduate:\n- Spec/planning atoms (inherently variable)\n- Creative/exploratory work\n- Low-frequency capabilities\n\n## Skills Assignment\n\nAtoms can have Claude Code skills assigned to them. When an atom executes, assigned skills are loaded into Claude's context.\n\n\\`\\`\\`bash\n# Scan available skills\natomic skills scan\n\n# Get skill recommendations for an atom\natomic skills suggest my_atom\n\n# Assign a skill to an atom\natomic skills assign my_atom --skill compound-engineering:workflows:review\n\n# List skills assigned to an atom\natomic skills list my_atom\n\n# Remove a skill from an atom\natomic skills remove my_atom --skill compound-engineering:workflows:review\n\\`\\`\\`\n\n**Use skills for**:\n- Review workflows (e.g., \\`compound-engineering:review:kieran-rails-reviewer\\`)\n- Domain expertise (e.g., \\`dhh-rails-style\\`)\n- Specialized capabilities the atom needs\n\nSkills complement atoms: the skill teaches *how*, the atom enforces *what* (schema) and tracks *whether it worked* (history).\n\n## Work Tracking with Beads\n\n**Beads is THE work tracking system.** All atomic work that needs tracking should flow through Beads.\n\n### Escalation\n\nWhen an atom fails and you can't resolve it:\n\n\\`\\`\\`bash\n# Create a Beads issue for unresolvable problems\natomic escalate --message \"Cannot connect to database\" --capability my_capability\n\n# Link to a specific run\natomic escalate --run abc123 --reason \"Schema validation failing on edge case\"\n\n# Include retry attempts\natomic escalate --capability my_atom --retries 3 --reason \"Flaky network\"\n\\`\\`\\`\n\n### Workflow Tracking\n\nWhen running workflows, atomic creates Beads issues automatically:\n- **Parent bead**: Tracks the overall workflow\n- **Child beads**: Track each capability execution\n\n\\`\\`\\`bash\n# Workflow execution creates beads automatically\natomic workflow run my_workflow\n\n# View workflow progress in Beads\nbd list --label atomic\n\\`\\`\\`\n\n## Integration with Claude Code\n\nWhen working in a project with atomic:\n\n1. **Check for \\`.atomic/\\`** - If present, use atomic commands\n2. **Register new atoms** - When creating reusable tasks\n3. **Use capabilities** - Route through registry, not direct execution\n4. **Assign skills** - Give atoms the Claude Code skills they need\n5. **Trust the system** - Let atomic handle validation and execution\n6. **Escalate to Beads** - Use \\`atomic escalate\\` for unresolvable problems\n7. **Suggest atomization** - When you see repetitive patterns, offer to extract\n\n## Example: Full Workflow\n\n\\`\\`\\`bash\n# 1. Initialize project\natomic init\n\n# 2. Create an atom\ncat > atoms/greet_user.ts << 'EOF'\nimport { defineAtom, success, z } from 'atomism';\n\nexport default defineAtom({\n name: 'greet_user',\n description: 'Generate a greeting message',\n input: z.object({ name: z.string() }),\n output: z.object({ greeting: z.string() }),\n tests: { path: './greet_user.test.ts' },\n async execute(input) {\n return success({ greeting: \\\\\\`Hello, \\\\\\${input.name}!\\\\\\` });\n },\n});\nEOF\n\n# 3. Generate tests\natomic test-gen atoms/greet_user.ts\n\n# 4. Register\natomic register atoms/greet_user.ts --capability greet\n\n# 5. Run\natomic run greet --input '{\"name\": \"World\"}'\n\n# 6. Check status\natomic status\n\\`\\`\\`\n\n## Troubleshooting\n\n### \"Not initialized\"\nRun \\`atomic init\\` in the project root.\n\n### \"Atom not found\"\nCheck registration with \\`atomic list\\`. Register with \\`atomic register <path>\\`.\n\n### \"Schema validation failed\"\nCheck input matches the atom's Zod schema. Use \\`atomic list <atom>\\` to see the expected schema.\n\n### \"Trust level insufficient\"\nPromote the stack with \\`atomic trust <stack> --level proven\\` or \\`--level trusted\\`.\n`;\n}\n\n/**\n * Get the skill directory path.\n */\nexport function getSkillPath(): string {\n return join(process.cwd(), '.claude', 'skills', 'atomic');\n}\n\n/**\n * Get the skill file path.\n */\nexport function getSkillFilePath(): string {\n return join(getSkillPath(), 'SKILL.md');\n}\n\n/**\n * Check if skill already exists.\n */\nexport async function skillExists(): Promise<boolean> {\n try {\n await stat(getSkillFilePath());\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Initialize the atomic skill for Claude Code.\n */\nexport async function initSkill(options: { force?: boolean }): Promise<{\n success: boolean;\n path?: string;\n error?: string;\n skipped?: boolean;\n}> {\n const skillPath = getSkillPath();\n const skillFile = getSkillFilePath();\n\n // Check if already exists\n if (!options.force && (await skillExists())) {\n return {\n success: true,\n path: skillFile,\n skipped: true,\n };\n }\n\n try {\n // Create directory\n await mkdir(skillPath, { recursive: true });\n\n // Write skill file\n const content = generateSkillContent();\n await writeFile(skillFile, content, 'utf-8');\n\n return {\n success: true,\n path: skillFile,\n };\n } catch (err) {\n return {\n success: false,\n error: toErrorMessage(err),\n };\n }\n}\n\n","/**\n * CLAUDE.md Init — Append atomism instructions to project's CLAUDE.md.\n *\n * When `atomic init` runs, this ensures Claude Code knows how to work\n * with atoms in the project. The snippet is appended once (idempotent).\n */\n\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { fileExists } from '../storage/index.js';\n\nconst ATOMISM_MARKER = '<!-- atomism -->';\n\nconst ATOMISM_SECTION = `\n${ATOMISM_MARKER}\n## Atomism\n\nThis project uses [Atomism](https://github.com/roach88/atomism) for schema-validated, composable work units.\n\n### Before Writing New Code\n\n1. Check registered atoms: \\`atomic list --json\\`\n2. If an atom exists for the task, use it: \\`atomic run <name> --input '{}' --yes --json\\`\n3. If no atom exists but the task is repeatable, create one: \\`atomic create atom <name> --json\\`\n\n### Atom API Reference\n\n\\`\\`\\`typescript\nimport { defineAtom, success, executionError, validationError } from 'atomism';\n\n// Success\nreturn success({ result: 'done' });\n\n// Bad input\nreturn validationError('Expected positive number');\n\n// Runtime failure (recoverable)\nreturn executionError('API timeout', true);\n\n// Runtime failure (not recoverable)\nreturn executionError('Missing required config');\n\\`\\`\\`\n\n### When to Atomize\n\n- You're about to write a standalone script for a repeatable task\n- You notice doing the same thing 3+ times with the same shape\n- The task has clear inputs and outputs that can be schema-validated\n`;\n\n/**\n * Initialize or update CLAUDE.md with atomism section.\n */\nexport async function initClaudeMd(): Promise<{\n success: boolean;\n path?: string;\n skipped?: boolean;\n error?: string;\n}> {\n const claudeDir = join(process.cwd(), '.claude');\n const claudeMdPath = join(claudeDir, 'CLAUDE.md');\n\n // Check if CLAUDE.md already has our section\n if (await fileExists(claudeMdPath)) {\n const content = await readFile(claudeMdPath, 'utf-8');\n if (content.includes(ATOMISM_MARKER)) {\n return { success: true, path: claudeMdPath, skipped: true };\n }\n\n // Append our section\n await writeFile(claudeMdPath, content.trimEnd() + '\\n' + ATOMISM_SECTION, 'utf-8');\n return { success: true, path: claudeMdPath };\n }\n\n // No CLAUDE.md — create .claude/ dir and write fresh file\n await mkdir(claudeDir, { recursive: true });\n await writeFile(claudeMdPath, ATOMISM_SECTION.trimStart(), 'utf-8');\n return { success: true, path: claudeMdPath };\n}\n","/**\n * .gitignore Init — Ensure local atomism data files are gitignored.\n *\n * When `atomic init` runs, this ensures storage.db (execution history),\n * its WAL journal, and transient workflow runs are not committed.\n * Uses a marker comment for idempotency.\n */\n\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { fileExists } from '../storage/index.js';\n\nconst ATOMISM_MARKER = '# atomism local data';\n\nconst ATOMISM_ENTRIES = `\n${ATOMISM_MARKER}\n.atomic/storage.db\n.atomic/storage.db-journal\n.atomic/runs/\n`;\n\nexport async function initGitignore(projectRoot: string): Promise<{\n success: boolean;\n path?: string;\n skipped?: boolean;\n error?: string;\n}> {\n const gitignorePath = join(projectRoot, '.gitignore');\n\n if (await fileExists(gitignorePath)) {\n const content = await readFile(gitignorePath, 'utf-8');\n if (content.includes(ATOMISM_MARKER)) {\n return { success: true, path: gitignorePath, skipped: true };\n }\n\n // Append our entries\n await writeFile(gitignorePath, content.trimEnd() + '\\n' + ATOMISM_ENTRIES, 'utf-8');\n return { success: true, path: gitignorePath };\n }\n\n // No .gitignore — create one\n await writeFile(gitignorePath, ATOMISM_ENTRIES.trimStart(), 'utf-8');\n return { success: true, path: gitignorePath };\n}\n"],"mappings":"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","names":["readFile","writeFile","join","writeFile","mkdir","join","join","writeFile","mkdir","readFile","writeFile","join","ATOMISM_MARKER","join","readFile","writeFile","join","writeFile","readFile"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atomism",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Schema-first agent swarm orchestration framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "repository": {
34
34
  "type": "git",
35
- "url": "git+https://github.com/Trust-Will/atomic-explore.git"
35
+ "url": "git+https://github.com/roach88/atomism.git"
36
36
  },
37
37
  "keywords": [
38
38
  "cli",
@@ -51,11 +51,11 @@
51
51
  "author": "",
52
52
  "license": "MIT",
53
53
  "bugs": {
54
- "url": "https://github.com/Trust-Will/atomic-explore/issues"
54
+ "url": "https://github.com/roach88/atomism/issues"
55
55
  },
56
- "homepage": "https://github.com/Trust-Will/atomic-explore#readme",
56
+ "homepage": "https://github.com/roach88/atomism#readme",
57
57
  "engines": {
58
- "node": ">=18"
58
+ "node": ">=20"
59
59
  },
60
60
  "dependencies": {
61
61
  "@tursodatabase/database": "^0.4.4",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/init.ts","../src/commands/skills-init.ts","../src/commands/claude-md-init.ts","../src/commands/gitignore-init.ts"],"sourcesContent":["import { readFile, writeFile, access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { initStorage } from '../storage/index.js';\nimport { initSkill } from './skills-init.js';\nimport { initClaudeMd } from './claude-md-init.js';\nimport { initGitignore } from './gitignore-init.js';\nimport { toErrorMessage } from '../utils/errors.js';\nimport { withErrorHandling } from './helpers.js';\n\nexport interface InitOptions {\n json?: boolean;\n}\n\ninterface DepsResult {\n success: boolean;\n packageJsonCreated: boolean;\n tsconfigCreated: boolean;\n tsconfigNeedsInclude?: boolean;\n suggestedInclude?: string;\n atomismLinked: boolean;\n error?: string;\n}\n\n/**\n * Ensure the project can resolve 'atomism' and 'zod' as modules.\n *\n * Atoms are TypeScript files that import from 'atomism'. Without a local\n * package.json that resolves the module, `atomic register` and any TS\n * tooling will fail with \"Cannot find module 'atomism'\".\n */\nasync function ensureDeps(projectRoot: string): Promise<DepsResult> {\n const pkgPath = join(projectRoot, 'package.json');\n const tsconfigPath = join(projectRoot, 'tsconfig.json');\n let packageJsonCreated = false;\n let tsconfigCreated = false;\n let atomismLinked = false;\n\n // 1. Ensure package.json exists\n let hasPackageJson = false;\n try {\n await access(pkgPath);\n hasPackageJson = true;\n } catch {\n // No package.json — create a minimal one\n }\n\n if (!hasPackageJson) {\n const minimal = {\n private: true,\n description: 'Atomism-enabled project',\n dependencies: {},\n };\n await writeFile(pkgPath, JSON.stringify(minimal, null, 2) + '\\n');\n packageJsonCreated = true;\n }\n\n // 2. Ensure tsconfig.json exists (required for TS type inference in atoms)\n let hasTsconfig = false;\n try {\n await access(tsconfigPath);\n hasTsconfig = true;\n } catch {\n // No tsconfig.json\n }\n\n let tsconfigNeedsInclude: boolean | undefined;\n let suggestedInclude: string | undefined;\n\n if (hasTsconfig) {\n // Check if existing tsconfig includes atom files\n try {\n const raw = await readFile(tsconfigPath, 'utf-8');\n const parsed = JSON.parse(raw);\n const includes: string[] = Array.isArray(parsed.include) ? parsed.include : [];\n const coversAtoms = includes.some((pattern: string) =>\n pattern === 'atoms/**/*.ts' ||\n pattern.startsWith('atoms/') ||\n pattern === '**/*.ts' ||\n pattern === './**/*.ts'\n );\n if (!coversAtoms) {\n tsconfigNeedsInclude = true;\n suggestedInclude = 'atoms/**/*.ts';\n }\n } catch {\n // tsconfig parse failure is non-fatal — skip the check\n }\n } else {\n const tsconfig = {\n compilerOptions: {\n target: 'ES2022',\n module: 'ESNext',\n moduleResolution: 'bundler',\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n outDir: 'dist',\n },\n include: ['atoms/**/*.ts'],\n };\n await writeFile(tsconfigPath, JSON.stringify(tsconfig, null, 2) + '\\n');\n tsconfigCreated = true;\n }\n\n // 3. Check if atomism is resolvable\n try {\n execSync('node -e \"require.resolve(\\'atomism\\')\"', {\n cwd: projectRoot,\n stdio: 'ignore',\n });\n // Already resolvable\n return { success: true, packageJsonCreated, tsconfigCreated, tsconfigNeedsInclude, suggestedInclude, atomismLinked };\n } catch {\n // Not resolvable — try to link it\n }\n\n // 4. Link atomism (works when atomism is installed globally via npm link)\n try {\n execSync('npm link atomism', {\n cwd: projectRoot,\n stdio: 'ignore',\n timeout: 30000,\n });\n atomismLinked = true;\n } catch {\n return {\n success: false,\n packageJsonCreated,\n tsconfigCreated,\n tsconfigNeedsInclude,\n suggestedInclude,\n atomismLinked: false,\n error: 'Could not resolve atomism. Run: npm link atomism (if globally installed) or npm install atomism',\n };\n }\n\n return { success: true, packageJsonCreated, tsconfigCreated, tsconfigNeedsInclude, suggestedInclude, atomismLinked };\n}\n\nexport async function initCommand(options: InitOptions): Promise<void> {\n await withErrorHandling(options, async () => {\n const projectRoot = process.cwd();\n const result = await initStorage(projectRoot);\n\n // Ensure module resolution (non-fatal — warn but continue)\n let depsResult: DepsResult;\n try {\n depsResult = await ensureDeps(projectRoot);\n } catch (depsError) {\n depsResult = {\n success: false,\n packageJsonCreated: false,\n tsconfigCreated: false,\n atomismLinked: false,\n error: toErrorMessage(depsError),\n };\n }\n\n // Create Claude Code skill (non-fatal)\n let skillResult: { success: boolean; skipped?: boolean; path?: string; error?: string };\n try {\n skillResult = await initSkill({ force: false });\n } catch (skillError) {\n skillResult = {\n success: false,\n error: toErrorMessage(skillError),\n };\n }\n\n // Create CLAUDE.md snippet (non-fatal)\n let claudeMdResult: { success: boolean; skipped?: boolean; path?: string; error?: string };\n try {\n claudeMdResult = await initClaudeMd();\n } catch (claudeError) {\n claudeMdResult = {\n success: false,\n error: toErrorMessage(claudeError),\n };\n }\n\n // Manage .gitignore (non-fatal)\n let gitignoreResult: { success: boolean; skipped?: boolean; path?: string; error?: string };\n try {\n gitignoreResult = await initGitignore(projectRoot);\n } catch (gitignoreError) {\n gitignoreResult = {\n success: false,\n error: toErrorMessage(gitignoreError),\n };\n }\n\n if (options.json) {\n console.log(JSON.stringify({\n ...result,\n deps: depsResult,\n skill: skillResult,\n claudeMd: claudeMdResult,\n gitignore: gitignoreResult,\n }, null, 2));\n } else {\n if (result.created) {\n console.log(`✓ Created ${result.path}`);\n } else {\n console.log(`✓ ${result.path} already exists`);\n }\n console.log(`✓ Database initialized at ${result.dbPath}`);\n console.log(`✓ ${result.migrationsRun} migrations applied`);\n\n // Report deps status\n if (depsResult.success) {\n if (depsResult.packageJsonCreated) {\n console.log('✓ Created package.json for module resolution');\n }\n if (depsResult.tsconfigCreated) {\n console.log('✓ Created tsconfig.json for atom type inference');\n }\n if (depsResult.atomismLinked) {\n console.log('✓ Linked atomism for module resolution');\n }\n } else {\n console.log(`⚠ Module resolution: ${depsResult.error ?? 'unknown error'}`);\n }\n\n // tsconfig warning is useful regardless of deps success\n if (depsResult.tsconfigNeedsInclude) {\n console.log(`⚠ tsconfig.json does not include atom files. Add to your \"include\" array:`);\n console.log(` \"${depsResult.suggestedInclude}\"`);\n }\n\n // Report skill status\n if (skillResult.success && !skillResult.skipped) {\n console.log(`✓ Claude Code skill created at ${skillResult.path}`);\n } else if (skillResult.skipped) {\n console.log('✓ Claude Code skill already exists');\n } else if (!skillResult.success) {\n console.log(`⚠ Claude Code skill creation failed: ${skillResult.error ?? 'unknown error'}`);\n }\n\n // Report CLAUDE.md status\n if (claudeMdResult.success && !claudeMdResult.skipped) {\n console.log(`✓ CLAUDE.md updated at ${claudeMdResult.path}`);\n } else if (claudeMdResult.skipped) {\n console.log('✓ CLAUDE.md already has atomism section');\n } else if (!claudeMdResult.success) {\n console.log(`⚠ CLAUDE.md update failed: ${claudeMdResult.error ?? 'unknown error'}`);\n }\n\n // Report .gitignore status\n if (gitignoreResult.success && !gitignoreResult.skipped) {\n console.log(`✓ .gitignore updated at ${gitignoreResult.path}`);\n } else if (gitignoreResult.skipped) {\n console.log('✓ .gitignore already has atomism entries');\n } else if (!gitignoreResult.success) {\n console.log(`⚠ .gitignore update failed: ${gitignoreResult.error ?? 'unknown error'}`);\n }\n\n console.log('\\nReady to register atoms with: atomic register <path>');\n console.log('Commit: registry.json, trust.json, atoms/');\n }\n });\n}\n","/**\n * Skills Init - Create Claude Code skill teaching atomic usage.\n *\n * Creates a SKILL.md in the project's .claude/skills/atomic/ directory\n * that teaches Claude Code how to effectively use the atomic CLI.\n */\n\nimport { mkdir, writeFile, stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { toErrorMessage } from '../utils/errors.js';\n\n/**\n * Generate the atomic skill content.\n */\nexport function generateSkillContent(): string {\n return `---\nname: atomic\ndescription: Schema-first agent swarm orchestration framework\n---\n\n# Atomic Framework\n\nSchema-first agent swarm orchestration. Use atomic to define, execute, and evolve reusable capabilities.\n\n## Trigger\n\nUse this skill when:\n- User mentions \"atomic\", \"atom\", \"capability\", or \"workflow\" in context of task orchestration\n- User wants to create reusable, schema-validated tasks\n- User wants to graduate patterns from probabilistic (AI) to deterministic (generator)\n- Project has \\`.atomic/\\` directory\n- User invokes \\`/atomic\\`\n\n## Why Atoms?\n\nAtoms solve a fundamental problem: **probabilistic work should become deterministic over time.**\n\nWhen you write an API route the first time, it's creative work. The tenth time you write a similar route, it should be a template fill. But without tracking, you start from scratch every time.\n\nAtoms provide:\n1. **Schema enforcement** — Inputs/outputs are Zod-validated, not freeform\n2. **Execution history** — Every run is recorded with inputs, outputs, success/failure\n3. **Similarity detection** — AST-level comparison identifies when outputs converge on patterns\n4. **Generator graduation** — When an atom produces 85%+ similar outputs, it can become a deterministic template\n5. **Trust progression** — New capabilities require review; proven ones auto-execute\n\nThe goal: **Capture patterns once, replay deterministically forever.** Focus human attention on genuinely novel problems.\n\n## When to Use Atoms\n\n| Situation | Use |\n|-----------|-----|\n| One-off task, no verification needed | Direct code |\n| Teaching Claude a capability | Claude Code skill |\n| Repetitive task, same shape each time | **Atom** (extract or create) |\n| Need trust gating / human review | **Atom with trust level** |\n| Task should evolve to template | **Atom** (graduation path) |\n| Always-on validation/enforcement | Hook |\n\n**Proactive extraction**: When you notice doing the same thing 3+ times with the same shape, suggest: \"This pattern would benefit from atomization — want me to extract it?\"\n\nUse \\`atomic extract\\` to create atoms from:\n- Existing Claude Code skills (\\`--skill\\`)\n- BMAD workflows (\\`--bmad\\`)\n- MCP tool definitions (\\`--mcp\\`)\n- Existing code files (\\`--code\\`)\n\n## Directory Structure\n\n\\`\\`\\`\nproject/\n├── .atomic/ # Metadata and storage (auto-created by init)\n│ ├── registry.json # Registered atoms and capabilities\n│ ├── trust.json # Trust levels for capability stacks\n│ └── db/ # SQLite storage for runs and artifacts\n├── .claude/\n│ └── skills/\n│ └── atomic/\n│ └── SKILL.md # This skill (auto-created by init)\n├── atoms/ # Atom source files (default location)\n│ ├── my_atom.ts\n│ └── my_atom.test.ts\n└── generators/ # Graduated generators (created by graduation)\n └── my_generator.ts\n\\`\\`\\`\n\n## Core Concepts\n\n### Atoms\nThe fundamental unit. A schema-validated, idempotent task with defined inputs/outputs.\n\n\\`\\`\\`typescript\n// atoms/create_component.ts\nimport { defineAtom, success, executionError, z } from 'atomism';\n\nexport default defineAtom({\n name: 'create_component',\n description: 'Create a React component with tests',\n input: z.object({\n name: z.string().min(1),\n type: z.enum(['functional', 'class']).default('functional'),\n }),\n output: z.object({\n componentPath: z.string(),\n testPath: z.string(),\n }),\n tests: { path: './create_component.test.ts' },\n idempotent: true,\n handler: async ({ name, type }) => {\n // Implementation here\n return success({ componentPath: '...', testPath: '...' });\n },\n});\n\\`\\`\\`\n\n### Capabilities\nRoute requests to either an atom (probabilistic) or generator (deterministic).\n\n- **Atom-backed**: AI executes with schema validation\n- **Generator-backed**: Deterministic template execution\n\n### Generators\nGraduated atoms. When an atom produces similar outputs repeatedly, it can graduate to a generator (template-based, deterministic).\n\n### Workflows\nCompositions of capabilities with dependency resolution. Like Make/Terraform - declare dependencies, system resolves execution order.\n\n### Trust Levels\n- **new**: Requires human review\n- **proven**: Track record of success, optional review\n- **trusted**: Auto-execute without review\n\n### Capability Stacks\nReusable groups of capabilities reviewed once, reused many times.\n\n## Project Initialization\n\n\\`\\`\\`bash\n# Initialize atomic in a project\natomic init\n\n# Creates:\n# .atomic/\n# registry.json # Registered atoms and capabilities\n# trust.json # Trust levels for capability stacks\n# db/ # SQLite storage for runs and artifacts\n\\`\\`\\`\n\n## Common Workflows\n\n### 1. Register an Atom\n\n\\`\\`\\`bash\n# Register a new atom\natomic register atoms/my_atom.ts\n\n# Register with capability name\natomic register atoms/my_atom.ts --capability my_capability\n\\`\\`\\`\n\n### 2. Run an Atom or Capability\n\n\\`\\`\\`bash\n# Run by atom name\natomic run my_atom --input '{\"key\": \"value\"}'\n\n# Run by capability name\natomic run my_capability --capability --input '{\"key\": \"value\"}'\n\n# Skip confirmation for non-idempotent atoms\natomic run my_atom --input '{\"key\": \"value\"}' --yes\n\\`\\`\\`\n\n### 3. Work with Workflows\n\n\\`\\`\\`bash\n# List available workflows\natomic workflow list\n\n# Run a workflow\natomic workflow run my_workflow\n\n# Resume a failed workflow\natomic workflow resume my_workflow\n\n# Preview execution plan\natomic plan my_workflow\n\\`\\`\\`\n\n### 4. Graduate to Generator\n\nWhen an atom produces consistent patterns:\n\n\\`\\`\\`bash\n# Graduate a capability to generator\natomic graduate --capability my_capability\n\n# Skip confirmation\natomic graduate --capability my_capability --yes\n\\`\\`\\`\n\n### 5. Manage Trust\n\n\\`\\`\\`bash\n# List all stacks with trust levels\natomic trust --list\n\n# View specific stack\natomic trust my_stack\n\n# Set trust level\natomic trust my_stack --level proven\n\n# Reset to new\natomic trust my_stack --reset\n\\`\\`\\`\n\n## Command Reference\n\n| Command | Description |\n|---------|-------------|\n| \\`atomic init\\` | Initialize .atomic/ directory and skill |\n| \\`atomic register <path>\\` | Register an atom file |\n| \\`atomic list\\` | List atoms and capabilities |\n| \\`atomic run <target>\\` | Execute atom or capability |\n| \\`atomic test <atom>\\` | Run tests for an atom |\n| \\`atomic test-gen <path>\\` | Generate structural tests |\n| \\`atomic extract\\` | Create atom from skill/bmad/mcp/code |\n| \\`atomic workflow run <name>\\` | Execute a workflow |\n| \\`atomic workflow list\\` | List available workflows |\n| \\`atomic workflow resume <name>\\` | Resume failed workflow |\n| \\`atomic plan <workflow>\\` | Preview execution plan |\n| \\`atomic graduate\\` | Graduate capability to generator |\n| \\`atomic trust [stack]\\` | Manage trust levels |\n| \\`atomic status\\` | Show system state |\n| \\`atomic history [runId]\\` | Show execution history |\n| \\`atomic escalate\\` | Create Beads issue for problems |\n| \\`atomic skills scan\\` | Discover available skills |\n| \\`atomic skills suggest <atom>\\` | Get skill recommendations |\n| \\`atomic skills assign <atom>\\` | Assign skill to atom |\n| \\`atomic skills list <atom>\\` | List atom's assigned skills |\n| \\`atomic skills remove <atom>\\` | Remove skill from atom |\n| \\`atomic scan-generators\\` | Detect existing generators |\n| \\`atomic import-generator\\` | Import from Plop/Hygen/etc |\n| \\`atomic validate-generator\\` | Validate imported generators |\n\n## Best Practices\n\n### 1. Atoms Should Be\n\n- **Small**: Single responsibility\n- **Idempotent**: Same input = same output (or no adverse effects)\n- **Schema-validated**: Zod schemas for input/output\n- **Tested**: Include test file path in definition\n- **Descriptive**: Clear name and description\n\n### 2. Naming Conventions\n\n- Atom names: \\`snake_case\\` (e.g., \\`create_component\\`, \\`run_migration\\`)\n- Capability names: \\`snake_case\\`\n- Workflow names: \\`snake_case\\`\n- Stack names: \\`snake_case\\`\n\n### 3. Error Handling\n\nUse structured errors:\n\n\\`\\`\\`typescript\nimport { failure, validationError, executionError } from 'atomism';\n\n// Validation error (bad input — recoverable by default)\nreturn validationError('Name cannot be empty');\n\n// Execution error (runtime failure)\nreturn executionError('Database connection failed', true /* recoverable */);\n\n// Generic failure (full AtomError object)\nreturn failure({ type: 'execution', message: 'Something went wrong', recoverable: false });\n\\`\\`\\`\n\n### 4. Trust Progression\n\n1. Start capabilities at \\`new\\` (human review required)\n2. After successful executions, promote to \\`proven\\`\n3. Only promote to \\`trusted\\` for well-tested, stable capabilities\n4. Demote immediately if issues arise\n\n### 5. Generator Graduation\n\nGraduate when:\n- Atom produces 85%+ structurally similar outputs\n- Pattern is well-understood\n- Template can capture the variation\n\nDon't graduate:\n- Spec/planning atoms (inherently variable)\n- Creative/exploratory work\n- Low-frequency capabilities\n\n## Skills Assignment\n\nAtoms can have Claude Code skills assigned to them. When an atom executes, assigned skills are loaded into Claude's context.\n\n\\`\\`\\`bash\n# Scan available skills\natomic skills scan\n\n# Get skill recommendations for an atom\natomic skills suggest my_atom\n\n# Assign a skill to an atom\natomic skills assign my_atom --skill compound-engineering:workflows:review\n\n# List skills assigned to an atom\natomic skills list my_atom\n\n# Remove a skill from an atom\natomic skills remove my_atom --skill compound-engineering:workflows:review\n\\`\\`\\`\n\n**Use skills for**:\n- Review workflows (e.g., \\`compound-engineering:review:kieran-rails-reviewer\\`)\n- Domain expertise (e.g., \\`dhh-rails-style\\`)\n- Specialized capabilities the atom needs\n\nSkills complement atoms: the skill teaches *how*, the atom enforces *what* (schema) and tracks *whether it worked* (history).\n\n## Work Tracking with Beads\n\n**Beads is THE work tracking system.** All atomic work that needs tracking should flow through Beads.\n\n### Escalation\n\nWhen an atom fails and you can't resolve it:\n\n\\`\\`\\`bash\n# Create a Beads issue for unresolvable problems\natomic escalate --message \"Cannot connect to database\" --capability my_capability\n\n# Link to a specific run\natomic escalate --run abc123 --reason \"Schema validation failing on edge case\"\n\n# Include retry attempts\natomic escalate --capability my_atom --retries 3 --reason \"Flaky network\"\n\\`\\`\\`\n\n### Workflow Tracking\n\nWhen running workflows, atomic creates Beads issues automatically:\n- **Parent bead**: Tracks the overall workflow\n- **Child beads**: Track each capability execution\n\n\\`\\`\\`bash\n# Workflow execution creates beads automatically\natomic workflow run my_workflow\n\n# View workflow progress in Beads\nbd list --label atomic\n\\`\\`\\`\n\n## Integration with Claude Code\n\nWhen working in a project with atomic:\n\n1. **Check for \\`.atomic/\\`** - If present, use atomic commands\n2. **Register new atoms** - When creating reusable tasks\n3. **Use capabilities** - Route through registry, not direct execution\n4. **Assign skills** - Give atoms the Claude Code skills they need\n5. **Trust the system** - Let atomic handle validation and execution\n6. **Escalate to Beads** - Use \\`atomic escalate\\` for unresolvable problems\n7. **Suggest atomization** - When you see repetitive patterns, offer to extract\n\n## Example: Full Workflow\n\n\\`\\`\\`bash\n# 1. Initialize project\natomic init\n\n# 2. Create an atom\ncat > atoms/greet_user.ts << 'EOF'\nimport { defineAtom, success, z } from 'atomism';\n\nexport default defineAtom({\n name: 'greet_user',\n description: 'Generate a greeting message',\n input: z.object({ name: z.string() }),\n output: z.object({ greeting: z.string() }),\n tests: { path: './greet_user.test.ts' },\n async execute(input) {\n return success({ greeting: \\\\\\`Hello, \\\\\\${input.name}!\\\\\\` });\n },\n});\nEOF\n\n# 3. Generate tests\natomic test-gen atoms/greet_user.ts\n\n# 4. Register\natomic register atoms/greet_user.ts --capability greet\n\n# 5. Run\natomic run greet --input '{\"name\": \"World\"}'\n\n# 6. Check status\natomic status\n\\`\\`\\`\n\n## Troubleshooting\n\n### \"Not initialized\"\nRun \\`atomic init\\` in the project root.\n\n### \"Atom not found\"\nCheck registration with \\`atomic list\\`. Register with \\`atomic register <path>\\`.\n\n### \"Schema validation failed\"\nCheck input matches the atom's Zod schema. Use \\`atomic list <atom>\\` to see the expected schema.\n\n### \"Trust level insufficient\"\nPromote the stack with \\`atomic trust <stack> --level proven\\` or \\`--level trusted\\`.\n`;\n}\n\n/**\n * Get the skill directory path.\n */\nexport function getSkillPath(): string {\n return join(process.cwd(), '.claude', 'skills', 'atomic');\n}\n\n/**\n * Get the skill file path.\n */\nexport function getSkillFilePath(): string {\n return join(getSkillPath(), 'SKILL.md');\n}\n\n/**\n * Check if skill already exists.\n */\nexport async function skillExists(): Promise<boolean> {\n try {\n await stat(getSkillFilePath());\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Initialize the atomic skill for Claude Code.\n */\nexport async function initSkill(options: { force?: boolean }): Promise<{\n success: boolean;\n path?: string;\n error?: string;\n skipped?: boolean;\n}> {\n const skillPath = getSkillPath();\n const skillFile = getSkillFilePath();\n\n // Check if already exists\n if (!options.force && (await skillExists())) {\n return {\n success: true,\n path: skillFile,\n skipped: true,\n };\n }\n\n try {\n // Create directory\n await mkdir(skillPath, { recursive: true });\n\n // Write skill file\n const content = generateSkillContent();\n await writeFile(skillFile, content, 'utf-8');\n\n return {\n success: true,\n path: skillFile,\n };\n } catch (err) {\n return {\n success: false,\n error: toErrorMessage(err),\n };\n }\n}\n\n","/**\n * CLAUDE.md Init — Append atomism instructions to project's CLAUDE.md.\n *\n * When `atomic init` runs, this ensures Claude Code knows how to work\n * with atoms in the project. The snippet is appended once (idempotent).\n */\n\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { fileExists } from '../storage/index.js';\n\nconst ATOMISM_MARKER = '<!-- atomism -->';\n\nconst ATOMISM_SECTION = `\n${ATOMISM_MARKER}\n## Atomism\n\nThis project uses [Atomism](https://github.com/roach88/atomism) for schema-validated, composable work units.\n\n### Before Writing New Code\n\n1. Check registered atoms: \\`atomic list --json\\`\n2. If an atom exists for the task, use it: \\`atomic run <name> --input '{}' --yes --json\\`\n3. If no atom exists but the task is repeatable, create one: \\`atomic create atom <name> --json\\`\n\n### Atom API Reference\n\n\\`\\`\\`typescript\nimport { defineAtom, success, executionError, validationError } from 'atomism';\n\n// Success\nreturn success({ result: 'done' });\n\n// Bad input\nreturn validationError('Expected positive number');\n\n// Runtime failure (recoverable)\nreturn executionError('API timeout', true);\n\n// Runtime failure (not recoverable)\nreturn executionError('Missing required config');\n\\`\\`\\`\n\n### When to Atomize\n\n- You're about to write a standalone script for a repeatable task\n- You notice doing the same thing 3+ times with the same shape\n- The task has clear inputs and outputs that can be schema-validated\n`;\n\n/**\n * Initialize or update CLAUDE.md with atomism section.\n */\nexport async function initClaudeMd(): Promise<{\n success: boolean;\n path?: string;\n skipped?: boolean;\n error?: string;\n}> {\n const claudeDir = join(process.cwd(), '.claude');\n const claudeMdPath = join(claudeDir, 'CLAUDE.md');\n\n // Check if CLAUDE.md already has our section\n if (await fileExists(claudeMdPath)) {\n const content = await readFile(claudeMdPath, 'utf-8');\n if (content.includes(ATOMISM_MARKER)) {\n return { success: true, path: claudeMdPath, skipped: true };\n }\n\n // Append our section\n await writeFile(claudeMdPath, content.trimEnd() + '\\n' + ATOMISM_SECTION, 'utf-8');\n return { success: true, path: claudeMdPath };\n }\n\n // No CLAUDE.md — create .claude/ dir and write fresh file\n await mkdir(claudeDir, { recursive: true });\n await writeFile(claudeMdPath, ATOMISM_SECTION.trimStart(), 'utf-8');\n return { success: true, path: claudeMdPath };\n}\n","/**\n * .gitignore Init — Ensure local atomism data files are gitignored.\n *\n * When `atomic init` runs, this ensures storage.db (execution history),\n * its WAL journal, and transient workflow runs are not committed.\n * Uses a marker comment for idempotency.\n */\n\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { fileExists } from '../storage/index.js';\n\nconst ATOMISM_MARKER = '# atomism local data';\n\nconst ATOMISM_ENTRIES = `\n${ATOMISM_MARKER}\n.atomic/storage.db\n.atomic/storage.db-journal\n.atomic/runs/\n`;\n\nexport async function initGitignore(projectRoot: string): Promise<{\n success: boolean;\n path?: string;\n skipped?: boolean;\n error?: string;\n}> {\n const gitignorePath = join(projectRoot, '.gitignore');\n\n if (await fileExists(gitignorePath)) {\n const content = await readFile(gitignorePath, 'utf-8');\n if (content.includes(ATOMISM_MARKER)) {\n return { success: true, path: gitignorePath, skipped: true };\n }\n\n // Append our entries\n await writeFile(gitignorePath, content.trimEnd() + '\\n' + ATOMISM_ENTRIES, 'utf-8');\n return { success: true, path: gitignorePath };\n }\n\n // No .gitignore — create one\n await writeFile(gitignorePath, ATOMISM_ENTRIES.trimStart(), 'utf-8');\n return { success: true, path: gitignorePath };\n}\n"],"mappings":"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","names":["readFile","writeFile","join","writeFile","mkdir","join","join","writeFile","mkdir","readFile","writeFile","join","ATOMISM_MARKER","join","readFile","writeFile","join","writeFile","readFile"]}