fathom-cli 0.3.4 → 0.3.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fathom-cli",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "Headless intelligence layer for AI-augmented development — intent-driven, provider-agnostic, self-improving. Active development.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -76,12 +76,12 @@
76
76
  "@fathom/core": "0.1.0",
77
77
  "@fathom/intake": "0.1.0",
78
78
  "@fathom/intent": "0.1.0",
79
- "@fathom/reports": "0.1.0",
80
79
  "@fathom/projections": "0.1.0",
81
- "@fathom/sync": "0.1.0",
80
+ "@fathom/reports": "0.1.0",
82
81
  "@fathom/store": "0.1.0",
83
- "@fathom/velocity": "0.1.0",
84
- "@fathom/tracker": "0.1.0"
82
+ "@fathom/sync": "0.1.0",
83
+ "@fathom/tracker": "0.1.0",
84
+ "@fathom/velocity": "0.1.0"
85
85
  },
86
86
  "scripts": {
87
87
  "build": "tsup",
@@ -1,8 +1,10 @@
1
1
  import { readFileSync, existsSync } from "node:fs";
2
2
  import { resolve } from "node:path";
3
+ import { execSync } from "node:child_process";
3
4
  import { describe, it, expect } from "vitest";
4
5
 
5
- const DOCS_ROOT = resolve(__dirname, "../../../docs/integrations");
6
+ const REPO_ROOT = execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
7
+ const DOCS_ROOT = resolve(REPO_ROOT, "docs/integrations");
6
8
 
7
9
  const INTEGRATION_DOCS = [
8
10
  {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../intent/src/schema.ts","../../intent/src/loader.ts","../../intent/src/guardrails.ts"],"sourcesContent":["import { z } from \"zod\";\n\n// ── Value schema ────────────────────────────────────────────\n\nexport const ValueSchema = z.object({\n name: z.string(),\n description: z.string(),\n priority: z.enum([\"critical\", \"high\", \"medium\", \"low\"]).default(\"medium\"),\n details: z.string().optional(),\n});\n\nexport type Value = z.infer<typeof ValueSchema>;\n\n// ── Budget schema ───────────────────────────────────────────\n\nexport const BudgetSchema = z.object({\n monthly_limit: z.number().positive(),\n alert_threshold: z.number().min(0).max(1).default(0.8),\n prefer_batch: z.boolean().default(false),\n currency: z.string().default(\"USD\"),\n});\n\nexport type Budget = z.infer<typeof BudgetSchema>;\n\n// ── Guardrails schema ───────────────────────────────────────\n\nexport const GuardrailsSchema = z.object({\n security: z\n .object({\n templates: z.array(z.string()).default([]),\n custom: z.array(z.string()).default([]),\n })\n .optional(),\n quality: z.array(z.string()).default([]),\n process: z.array(z.string()).default([]),\n});\n\nexport type Guardrails = z.infer<typeof GuardrailsSchema>;\n\n// ── Tech schema ─────────────────────────────────────────────\n\nexport const TechSchema = z.object({\n stack: z.array(z.string()).default([]),\n opinions: z.array(z.string()).default([]),\n});\n\nexport type Tech = z.infer<typeof TechSchema>;\n\n// ── Providers schema ────────────────────────────────────────\n\nexport const ProvidersSchema = z.object({\n preferred: z.string().optional(),\n api_key_env: z.string().optional(),\n fallback: z.string().optional(),\n local_models: z.array(z.string()).default([]),\n});\n\nexport type Providers = z.infer<typeof ProvidersSchema>;\n\n// ── Intent schema (top-level) ───────────────────────────────\n\nexport const IntentSchema = z.object({\n project: z.string(),\n description: z.string(),\n audience: z.string().optional(),\n values: z.array(ValueSchema).default([]),\n budget: BudgetSchema.optional(),\n guardrails: GuardrailsSchema.optional(),\n tech: TechSchema.optional(),\n providers: ProvidersSchema.optional(),\n});\n\nexport type IntentConfig = z.infer<typeof IntentSchema>;\n\n// ── Guardrail template schema ───────────────────────────────\n\nexport const GuardrailTemplateSchema = z.object({\n name: z.string(),\n description: z.string(),\n category: z.enum([\"security\", \"quality\"]),\n status: z.string().optional(),\n rules: z.array(z.string()),\n});\n\nexport type GuardrailTemplate = z.infer<typeof GuardrailTemplateSchema>;\n\n// ── Resolved guardrails (flat output) ───────────────────────\n\nexport interface ResolvedGuardrails {\n security: string[];\n quality: string[];\n process: string[];\n}\n\nexport interface TemplateInfo {\n name: string;\n description: string;\n category: string;\n status?: string;\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport yaml from \"js-yaml\";\nimport { IntentSchema, type IntentConfig } from \"./schema.js\";\n\nconst INTENT_DIR = \".fathom\";\nconst INTENT_FILE = \"intent.yaml\";\n\nfunction intentPath(dir: string): string {\n return join(dir, INTENT_DIR, INTENT_FILE);\n}\n\n/**\n * Load and validate intent from a project directory.\n * Reads `.fathom/intent.yaml`, parses YAML, validates with Zod.\n */\nexport async function loadIntent(dir: string): Promise<IntentConfig> {\n const filePath = intentPath(dir);\n\n if (!existsSync(filePath)) {\n throw new Error(`Intent file not found: ${filePath}`);\n }\n\n const content = readFileSync(filePath, \"utf-8\");\n const raw = yaml.load(content);\n return IntentSchema.parse(raw);\n}\n\n/**\n * Validate and save intent to a project directory.\n * Writes validated YAML to `.fathom/intent.yaml`. Creates `.fathom/` if needed.\n */\nexport async function saveIntent(dir: string, intent: IntentConfig): Promise<void> {\n // Validate before writing\n const validated = IntentSchema.parse(intent);\n\n const fathomDir = join(dir, INTENT_DIR);\n if (!existsSync(fathomDir)) {\n mkdirSync(fathomDir, { recursive: true });\n }\n\n const content = yaml.dump(validated, {\n lineWidth: 120,\n noRefs: true,\n quotingType: '\"',\n forceQuotes: false,\n });\n\n writeFileSync(intentPath(dir), content, \"utf-8\");\n}\n\n/**\n * Synchronously check if `.fathom/intent.yaml` exists in a directory.\n */\nexport function detectIntent(dir: string): boolean {\n return existsSync(intentPath(dir));\n}\n","import { readFileSync, readdirSync } from \"node:fs\";\nimport { resolve, basename } from \"node:path\";\nimport yaml from \"js-yaml\";\nimport {\n GuardrailTemplateSchema,\n type GuardrailTemplate,\n type IntentConfig,\n type ResolvedGuardrails,\n type TemplateInfo,\n} from \"./schema.js\";\n\nfunction findDataDir(): string {\n const base = import.meta.dirname ?? __dirname;\n // Try bundled location first (dist/data/ when installed from npm)\n const bundled = resolve(base, \"data\", \"guardrails\");\n try {\n readdirSync(bundled);\n return bundled;\n } catch {\n // Fall back to monorepo location (packages/intent/data/guardrails from dist/)\n return resolve(base, \"..\", \"data\", \"guardrails\");\n }\n}\n\n/**\n * Load a guardrail template by name.\n */\nexport function loadTemplate(name: string): GuardrailTemplate {\n const dir = findDataDir();\n const filePath = resolve(dir, `${name}.yaml`);\n\n let content: string;\n try {\n content = readFileSync(filePath, \"utf-8\");\n } catch {\n throw new Error(\n `Unknown guardrail template: \"${name}\". Use listTemplates() to see available templates.`,\n );\n }\n\n const raw = yaml.load(content);\n return GuardrailTemplateSchema.parse(raw);\n}\n\n/**\n * List all available guardrail templates.\n */\nexport function listTemplates(): TemplateInfo[] {\n const dir = findDataDir();\n const files = readdirSync(dir).filter((f) => f.endsWith(\".yaml\"));\n\n return files.map((file) => {\n const content = readFileSync(resolve(dir, file), \"utf-8\");\n const raw = yaml.load(content) as Record<string, unknown>;\n return {\n name: raw.name as string,\n description: raw.description as string,\n category: raw.category as string,\n status: raw.status as string | undefined,\n };\n });\n}\n\n/**\n * Resolve all guardrail templates and custom rules from an intent config\n * into a flat categorized object.\n */\nexport function resolveGuardrails(intent: IntentConfig): ResolvedGuardrails {\n const result: ResolvedGuardrails = {\n security: [],\n quality: [],\n process: [],\n };\n\n if (!intent.guardrails) {\n return result;\n }\n\n const { guardrails } = intent;\n\n // Expand security templates\n if (guardrails.security) {\n for (const templateName of guardrails.security.templates) {\n const template = loadTemplate(templateName);\n if (template.category === \"security\") {\n result.security.push(...template.rules);\n } else if (template.category === \"quality\") {\n result.quality.push(...template.rules);\n }\n }\n\n // Add custom security rules\n result.security.push(...guardrails.security.custom);\n }\n\n // Add quality rules (these are direct string rules, not template refs)\n result.quality.push(...guardrails.quality);\n\n // Add process rules\n result.process.push(...guardrails.process);\n\n return result;\n}\n"],"mappings":"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","names":["readFileSync","readFileSync","yaml"]}