@fragments-sdk/cli 0.15.10 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/bin.js +901 -789
  2. package/dist/bin.js.map +1 -1
  3. package/dist/{chunk-6SQPP47U.js → chunk-ANTWP3UG.js} +532 -31
  4. package/dist/chunk-ANTWP3UG.js.map +1 -0
  5. package/dist/{chunk-ONUP6Z4W.js → chunk-B4A4ZEGS.js} +9 -9
  6. package/dist/{chunk-32LIWN2P.js → chunk-FFCI6OVZ.js} +584 -261
  7. package/dist/chunk-FFCI6OVZ.js.map +1 -0
  8. package/dist/{chunk-HQ6A6DTV.js → chunk-HNHE64CR.js} +315 -1089
  9. package/dist/chunk-HNHE64CR.js.map +1 -0
  10. package/dist/{chunk-BJE3425I.js → chunk-MN3B2EE6.js} +2 -2
  11. package/dist/{chunk-QCN35LJU.js → chunk-SAQW37L5.js} +3 -2
  12. package/dist/chunk-SAQW37L5.js.map +1 -0
  13. package/dist/{chunk-2WXKALIG.js → chunk-SNZXGHL2.js} +2 -2
  14. package/dist/{chunk-5JF26E55.js → chunk-VT2J62ND.js} +11 -11
  15. package/dist/{codebase-scanner-MQHUZC2G.js → codebase-scanner-2T5QIDBA.js} +2 -2
  16. package/dist/core/index.js +53 -1
  17. package/dist/{create-EXURTBKK.js → create-D44QD7MV.js} +2 -2
  18. package/dist/{doctor-BDPMYYE6.js → doctor-7B5N4JYU.js} +2 -2
  19. package/dist/{generate-PVOLUAAC.js → generate-T47JZRVU.js} +4 -4
  20. package/dist/govern-scan-X6UEIOSV.js +632 -0
  21. package/dist/govern-scan-X6UEIOSV.js.map +1 -0
  22. package/dist/index.js +7 -8
  23. package/dist/index.js.map +1 -1
  24. package/dist/{init-SSGUSP7Z.js → init-2RGAY4W6.js} +5 -5
  25. package/dist/mcp-bin.js +2 -2
  26. package/dist/scan-A2WJM54L.js +14 -0
  27. package/dist/{scan-generate-VY27PIOX.js → scan-generate-LUSOHT36.js} +4 -4
  28. package/dist/{service-QJGWUIVL.js → service-ROCP7TKG.js} +13 -15
  29. package/dist/{snapshot-WIJMEIFT.js → snapshot-B3SAW74Y.js} +2 -2
  30. package/dist/{static-viewer-7QIBQZRC.js → static-viewer-7L6UEYTJ.js} +3 -3
  31. package/dist/{test-64Z5BKBA.js → test-PQDVDURE.js} +3 -3
  32. package/dist/{token-normalizer-TEPOVBPV.js → token-normalizer-7TFCVDZL.js} +2 -2
  33. package/dist/{tokens-NZWFQIAB.js → tokens-64FG5FDP.js} +8 -9
  34. package/dist/{tokens-NZWFQIAB.js.map → tokens-64FG5FDP.js.map} +1 -1
  35. package/dist/{tokens-generate-5JQSJ27E.js → tokens-generate-CL4LBBQA.js} +2 -2
  36. package/package.json +9 -8
  37. package/src/bin.ts +55 -88
  38. package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/label.contract.json +1 -1
  39. package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/primitive.contract.json +1 -1
  40. package/src/commands/__tests__/context-cloud.test.ts +291 -0
  41. package/src/commands/__tests__/govern-scan.test.ts +185 -0
  42. package/src/commands/__tests__/govern.test.ts +1 -0
  43. package/src/commands/context-cloud.ts +355 -0
  44. package/src/commands/govern-scan-report.ts +170 -0
  45. package/src/commands/govern-scan.ts +282 -135
  46. package/src/commands/govern.ts +0 -157
  47. package/src/mcp/__tests__/server.integration.test.ts +9 -20
  48. package/src/service/enhance/codebase-scanner.ts +3 -2
  49. package/src/service/enhance/types.ts +3 -0
  50. package/dist/chunk-32LIWN2P.js.map +0 -1
  51. package/dist/chunk-6SQPP47U.js.map +0 -1
  52. package/dist/chunk-HQ6A6DTV.js.map +0 -1
  53. package/dist/chunk-MHIBEEW4.js +0 -511
  54. package/dist/chunk-MHIBEEW4.js.map +0 -1
  55. package/dist/chunk-QCN35LJU.js.map +0 -1
  56. package/dist/govern-scan-DW4QUAYD.js +0 -414
  57. package/dist/govern-scan-DW4QUAYD.js.map +0 -1
  58. package/dist/init-cloud-3DNKPWFB.js +0 -304
  59. package/dist/init-cloud-3DNKPWFB.js.map +0 -1
  60. package/dist/node-37AUE74M.js +0 -65
  61. package/dist/push-contracts-WY32TFP6.js +0 -84
  62. package/dist/push-contracts-WY32TFP6.js.map +0 -1
  63. package/dist/scan-PKSYSTRR.js +0 -15
  64. package/dist/static-viewer-7QIBQZRC.js.map +0 -1
  65. package/dist/token-parser-32KOIOFN.js +0 -22
  66. package/dist/token-parser-32KOIOFN.js.map +0 -1
  67. package/dist/tokens-push-HY3KO36V.js +0 -148
  68. package/dist/tokens-push-HY3KO36V.js.map +0 -1
  69. package/src/commands/init-cloud.ts +0 -382
  70. package/src/commands/push-contracts.ts +0 -112
  71. package/src/commands/tokens-push.ts +0 -199
  72. /package/dist/{chunk-ONUP6Z4W.js.map → chunk-B4A4ZEGS.js.map} +0 -0
  73. /package/dist/{chunk-BJE3425I.js.map → chunk-MN3B2EE6.js.map} +0 -0
  74. /package/dist/{chunk-2WXKALIG.js.map → chunk-SNZXGHL2.js.map} +0 -0
  75. /package/dist/{chunk-5JF26E55.js.map → chunk-VT2J62ND.js.map} +0 -0
  76. /package/dist/{codebase-scanner-MQHUZC2G.js.map → codebase-scanner-2T5QIDBA.js.map} +0 -0
  77. /package/dist/{create-EXURTBKK.js.map → create-D44QD7MV.js.map} +0 -0
  78. /package/dist/{doctor-BDPMYYE6.js.map → doctor-7B5N4JYU.js.map} +0 -0
  79. /package/dist/{generate-PVOLUAAC.js.map → generate-T47JZRVU.js.map} +0 -0
  80. /package/dist/{init-SSGUSP7Z.js.map → init-2RGAY4W6.js.map} +0 -0
  81. /package/dist/{node-37AUE74M.js.map → scan-A2WJM54L.js.map} +0 -0
  82. /package/dist/{scan-generate-VY27PIOX.js.map → scan-generate-LUSOHT36.js.map} +0 -0
  83. /package/dist/{scan-PKSYSTRR.js.map → service-ROCP7TKG.js.map} +0 -0
  84. /package/dist/{snapshot-WIJMEIFT.js.map → snapshot-B3SAW74Y.js.map} +0 -0
  85. /package/dist/{service-QJGWUIVL.js.map → static-viewer-7L6UEYTJ.js.map} +0 -0
  86. /package/dist/{test-64Z5BKBA.js.map → test-PQDVDURE.js.map} +0 -0
  87. /package/dist/{token-normalizer-TEPOVBPV.js.map → token-normalizer-7TFCVDZL.js.map} +0 -0
  88. /package/dist/{tokens-generate-5JQSJ27E.js.map → tokens-generate-CL4LBBQA.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/govern-scan.ts","../src/commands/govern-scan-report.ts"],"sourcesContent":["/**\n * govern scan / govern watch — Zero-config governance scanning\n *\n * Parses real JSX/TSX files via the existing codebase scanner, converts\n * component usages to UISpec, and runs governance checks per file.\n */\n\nimport pc from 'picocolors';\nimport { resolve, relative } from 'node:path';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { BRAND } from '../core/index.js';\nimport type { ComponentUsage } from '../service/enhance/types.js';\nimport type { GovernanceVerdict } from '@fragments-sdk/govern';\nimport {\n aggregateVerdicts,\n flattenComponentUsage,\n buildComplianceSummary,\n writeGovernScanReport,\n type GovernScanReport,\n} from './govern-scan-report.js';\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface GovernScanOptions {\n /** Root directory to scan (default: auto-detect) */\n dir?: string;\n /** Path to govern.config.ts */\n config?: string;\n /** Output format */\n format?: 'summary' | 'json' | 'sarif';\n /** Write an aggregated machine-readable JSON report */\n report?: string;\n /** Suppress non-error output */\n quiet?: boolean;\n /** Fragments Cloud API key — reports findings to Cloud */\n apiKey?: string;\n /** Fragments Cloud base URL (default: https://app.usefragments.com) */\n cloudUrl?: string;\n /** Only scan files changed vs a base ref (default base: auto-detected merge base) */\n diff?: boolean | string;\n}\n\nexport interface GovernWatchOptions extends GovernScanOptions {\n /** Debounce interval in ms (default: 300) */\n debounce?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Git diff helpers\n// ---------------------------------------------------------------------------\n\nconst SCANNABLE_EXTENSIONS = new Set([\n '.tsx', '.ts', '.jsx', '.js',\n]);\n\nfunction getChangedFiles(rootDir: string, base?: string): string[] | null {\n try {\n const baseRef = base || detectMergeBase(rootDir);\n if (!baseRef) return null;\n\n const output = execSync(\n `git diff --name-only --diff-filter=ACMR ${baseRef}...HEAD`,\n { cwd: rootDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] },\n );\n\n return output\n .split('\\n')\n .map((f) => f.trim())\n .filter((f) => f && SCANNABLE_EXTENSIONS.has(f.slice(f.lastIndexOf('.'))))\n .map((f) => resolve(rootDir, f));\n } catch {\n return null;\n }\n}\n\nfunction detectMergeBase(rootDir: string): string | null {\n try {\n const remote = execSync('git rev-parse --abbrev-ref origin/HEAD', {\n cwd: rootDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n if (remote) return remote;\n } catch { /* fallback */ }\n\n for (const candidate of ['origin/main', 'origin/master']) {\n try {\n execSync(`git rev-parse --verify ${candidate}`, {\n cwd: rootDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'],\n });\n return candidate;\n } catch { /* try next */ }\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Scan defaults — applied when no config file exists\n// ---------------------------------------------------------------------------\n\nconst SCAN_DEFAULT_RULES: Record<string, boolean | object> = {\n 'safety/block-event-handlers': true,\n 'safety/block-dangerous-props': true,\n 'safety/block-controlled-props': true,\n 'safety/block-function-props': true,\n 'safety/sanitize-hrefs': true,\n 'tokens/require-design-tokens': true,\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Auto-detect root directory by looking for common React project dirs\n */\nfunction detectRootDir(cwd: string): string {\n const candidates = ['src', 'app', 'pages', 'components'];\n for (const dir of candidates) {\n if (existsSync(resolve(cwd, dir))) {\n return cwd;\n }\n }\n return cwd;\n}\n\n/**\n * Group component usages by their source file\n */\nfunction groupByFile(usages: ComponentUsage[]): Map<string, ComponentUsage[]> {\n const grouped = new Map<string, ComponentUsage[]>();\n for (const usage of usages) {\n const existing = grouped.get(usage.filePath);\n if (existing) {\n existing.push(usage);\n } else {\n grouped.set(usage.filePath, [usage]);\n }\n }\n return grouped;\n}\n\n\n// ---------------------------------------------------------------------------\n// governScan\n// ---------------------------------------------------------------------------\n\nexport async function governScan(\n options: GovernScanOptions = {},\n): Promise<{ exitCode: number }> {\n const {\n loadPolicy,\n createEngine,\n buildAdaptersFromConfig,\n formatVerdict,\n computeComponentHealth,\n computeScore,\n } = await import('@fragments-sdk/govern');\n\n const { scanCodebase } = await import(\n '../service/enhance/codebase-scanner.js'\n );\n const { usagesToSpec } = await import(\n '../service/enhance/converter.js'\n );\n\n const format = options.format ?? 'summary';\n const quiet = options.quiet ?? false;\n\n if (!quiet) {\n console.log(pc.cyan(`\\n${BRAND.name} Governance Scan\\n`));\n }\n\n // 1. Resolve root directory\n const rootDir = resolve(options.dir ?? detectRootDir(process.cwd()));\n if (!quiet) {\n console.log(pc.dim(` Root: ${rootDir}\\n`));\n }\n\n // 2. Load policy — use scan defaults if no config exists\n let policy = await loadPolicy(options.config);\n const hasRules = Object.keys(policy.rules).length > 0;\n\n if (!hasRules) {\n policy = { ...policy, rules: SCAN_DEFAULT_RULES };\n if (!quiet) {\n console.log(pc.dim(' No config found — using scan defaults (safety + tokens)\\n'));\n }\n }\n\n // 3. Load contract registry for contract-aware scoring (if fragments.json exists)\n let registryMap: Record<string, unknown> | undefined;\n let hasRegistry = false;\n {\n const fragmentsJsonPath = resolve(rootDir, 'fragments.json');\n if (existsSync(fragmentsJsonPath)) {\n try {\n const raw = readFileSync(fragmentsJsonPath, 'utf-8');\n const parsed = JSON.parse(raw);\n if (parsed.fragments && Array.isArray(parsed.fragments)) {\n const map: Record<string, unknown> = {};\n for (const fragment of parsed.fragments) {\n if (fragment.meta?.name) {\n map[fragment.meta.name] = fragment;\n }\n }\n registryMap = map;\n hasRegistry = true;\n if (!quiet) {\n console.log(\n pc.dim(` Contract registry loaded (${parsed.fragments.length} components)\\n`),\n );\n }\n }\n } catch {\n // Invalid fragments.json — skip registry-aware summary\n }\n }\n }\n\n // 4. Build adapters from policy config\n const adapters = buildAdaptersFromConfig(policy.audit);\n\n // 5. Create engine (with registry for contract-aware validators)\n const engine = createEngine(\n policy,\n adapters,\n registryMap\n ? { registry: { fragments: registryMap as Record<string, Record<string, unknown>> } }\n : undefined,\n );\n\n // 6. Scan codebase (optionally scoped to changed files via --diff)\n let diffFiles: string[] | undefined;\n if (options.diff) {\n const base = typeof options.diff === 'string' ? options.diff : undefined;\n const changed = getChangedFiles(rootDir, base);\n if (changed && changed.length > 0) {\n diffFiles = changed;\n if (!quiet) {\n console.log(pc.dim(` Diff mode: scanning ${changed.length} changed file(s)...\\n`));\n }\n } else if (changed && changed.length === 0) {\n if (!quiet) {\n console.log(pc.green(' No scannable files changed — all clear.\\n'));\n }\n return { exitCode: 0 };\n } else {\n if (!quiet) {\n console.log(pc.yellow(' Could not detect git diff — falling back to full scan.\\n'));\n }\n }\n }\n\n if (!quiet && !diffFiles) {\n console.log(pc.dim(' Scanning files...\\n'));\n }\n\n const analysis = await scanCodebase({\n rootDir,\n useCache: true,\n files: diffFiles,\n onProgress: quiet\n ? undefined\n : (progress) => {\n if (progress.phase === 'scanning') {\n process.stdout.write(\n `\\r ${pc.dim(`[${progress.current}/${progress.total}]`)} ${pc.dim(relative(rootDir, progress.currentFile))}`,\n );\n }\n },\n });\n\n if (!quiet) {\n // Clear progress line\n process.stdout.write('\\r' + ' '.repeat(80) + '\\r');\n console.log(\n pc.dim(` Scanned ${analysis.totalFiles} files, found ${analysis.totalComponents} component types\\n`),\n );\n }\n\n // 7. Collect all usages across components\n const allUsages: ComponentUsage[] = [];\n for (const comp of Object.values(analysis.components)) {\n allUsages.push(...comp.usages);\n }\n\n if (allUsages.length === 0) {\n if (!quiet) {\n console.log(pc.yellow(' No component usages found.\\n'));\n }\n if (options.report) {\n const report: GovernScanReport = {\n verdict: aggregateVerdicts([], computeScore, 'ci'),\n componentUsage: [],\n };\n await writeGovernScanReport(options.report, report);\n if (!quiet) {\n console.log(pc.dim(` Wrote governance report: ${resolve(options.report)}\\n`));\n }\n }\n return { exitCode: 0 };\n }\n\n // 8. Group by file and run checks\n const grouped = groupByFile(allUsages);\n let totalFiles = 0;\n let passedFiles = 0;\n let totalViolations = 0;\n const violationCounts = new Map<string, number>();\n const allVerdicts: GovernanceVerdict[] = [];\n\n for (const [filePath, usages] of grouped) {\n const spec = usagesToSpec(usages, filePath, rootDir);\n const relPath = relative(rootDir, filePath);\n\n const verdict = await engine.check(spec, {\n runner: 'cli',\n input: relPath,\n });\n allVerdicts.push(verdict);\n\n totalFiles++;\n\n if (verdict.passed) {\n passedFiles++;\n } else {\n if (!quiet) {\n console.log(pc.red(` ✗ ${relPath}`));\n if (format === 'summary') {\n for (const result of verdict.results) {\n for (const v of result.violations) {\n const count = violationCounts.get(v.rule) ?? 0;\n violationCounts.set(v.rule, count + 1);\n totalViolations++;\n console.log(\n pc.dim(` ${v.severity} `) +\n pc.yellow(v.rule) +\n pc.dim(` — ${v.message}`),\n );\n if (v.nodeId) {\n console.log(pc.dim(` at ${v.nodeId}`));\n }\n }\n }\n }\n }\n }\n\n if (verdict.passed && !quiet && format === 'summary') {\n console.log(pc.green(` ✓ ${relPath}`) + pc.dim(` (${usages.length} components, score: ${verdict.score}/100)`));\n }\n\n // JSON/SARIF: print per-file\n if (format === 'json' || format === 'sarif') {\n const output = formatVerdict(verdict, format);\n console.log(output);\n }\n }\n\n // 8b. Compute component health\n const health = computeComponentHealth(allVerdicts, registryMap ?? {});\n\n // 9. Summary\n if (!quiet && format === 'summary') {\n console.log(pc.dim('\\n ─────────────────────────────────────\\n'));\n console.log(` Files checked: ${totalFiles}`);\n console.log(` Passed: ${passedFiles}/${totalFiles}`);\n console.log(` Violations: ${totalViolations}`);\n\n if (violationCounts.size > 0) {\n console.log(pc.dim('\\n Top violations:'));\n const sorted = [...violationCounts.entries()].sort((a, b) => b[1] - a[1]);\n for (const [rule, count] of sorted.slice(0, 5)) {\n console.log(pc.dim(` ${count}× `) + pc.yellow(rule));\n }\n }\n\n // Component health\n console.log(pc.dim('\\n Component Health:'));\n console.log(` Contract coverage: ${health.contractCoverage}% (${health.contractedComponents}/${health.totalComponents})`);\n console.log(` Compliance rate: ${health.overallCompliance}%`);\n\n if (health.uncontracted.length > 0) {\n console.log(pc.dim(` Uncontracted: ${health.uncontracted.slice(0, 5).join(', ')}${health.uncontracted.length > 5 ? ` (+${health.uncontracted.length - 5} more)` : ''}`));\n }\n\n console.log();\n\n if (passedFiles === totalFiles) {\n console.log(pc.green(` ✓ All files passed governance checks\\n`));\n } else {\n console.log(\n pc.red(` ✗ ${totalFiles - passedFiles} file(s) failed governance checks\\n`),\n );\n }\n }\n\n if (options.report) {\n const report: GovernScanReport = {\n verdict: aggregateVerdicts(allVerdicts, computeScore, 'ci'),\n componentUsage: flattenComponentUsage(allUsages, rootDir),\n };\n if (hasRegistry) {\n report.complianceSummary = buildComplianceSummary(health);\n }\n await writeGovernScanReport(options.report, report);\n if (!quiet) {\n console.log(pc.dim(` Wrote governance report: ${resolve(options.report)}\\n`));\n }\n }\n\n // Report to Fragments Cloud\n if (options.apiKey) {\n await reportToCloud({\n apiKey: options.apiKey,\n cloudUrl: options.cloudUrl,\n verdicts: allVerdicts,\n rootDir,\n quiet,\n diffOnly: !!diffFiles,\n });\n }\n\n return { exitCode: passedFiles === totalFiles ? 0 : 1 };\n}\n\n// ---------------------------------------------------------------------------\n// Cloud reporting\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_CLOUD_URL = 'https://app.usefragments.com';\n\ninterface CloudReportOptions {\n apiKey: string;\n cloudUrl?: string;\n verdicts: GovernanceVerdict[];\n rootDir: string;\n quiet: boolean;\n diffOnly?: boolean;\n}\n\nfunction detectGitMetadata(): {\n commitSha?: string;\n branch?: string;\n pr?: number;\n repoFullName?: string;\n} {\n const env = process.env;\n const meta: ReturnType<typeof detectGitMetadata> = {};\n\n if (env.GITHUB_SHA) meta.commitSha = env.GITHUB_SHA;\n if (env.GITHUB_REPOSITORY) meta.repoFullName = env.GITHUB_REPOSITORY;\n if (env.GITHUB_REF_NAME) meta.branch = env.GITHUB_REF_NAME;\n\n if (env.GITHUB_EVENT_NAME === 'pull_request' && env.GITHUB_EVENT_PATH) {\n try {\n const event = JSON.parse(readFileSync(env.GITHUB_EVENT_PATH, 'utf-8'));\n if (event?.pull_request?.number) {\n meta.pr = event.pull_request.number;\n }\n if (event?.pull_request?.head?.sha) {\n meta.commitSha = event.pull_request.head?.sha;\n }\n } catch {\n // Event file unreadable — skip PR number\n }\n }\n\n return meta;\n}\n\nasync function reportToCloud(options: CloudReportOptions): Promise<void> {\n const { apiKey, verdicts, rootDir, quiet, diffOnly } = options;\n const baseUrl = (options.cloudUrl ?? DEFAULT_CLOUD_URL).replace(/\\/+$/, '');\n\n const findings: Array<{\n ruleId: string;\n severity: 'error' | 'warning' | 'info';\n filePath?: string;\n line?: number;\n column?: number;\n rawValue?: string;\n suggestedToken?: string;\n message: string;\n category?: string;\n fingerprint: string;\n }> = [];\n\n const { createHash } = await import('node:crypto');\n\n for (const verdict of verdicts) {\n for (const result of verdict.results) {\n for (const v of result.violations) {\n const severity = v.severity === 'critical' || v.severity === 'serious'\n ? 'error'\n : v.severity === 'moderate'\n ? 'warning'\n : 'info';\n\n const fingerprint = createHash('sha256')\n .update(`${v.rule}:${v.nodeType}:${v.nodeId}:${v.message}`)\n .digest('hex')\n .slice(0, 16);\n\n let filePath: string | undefined;\n let line: number | undefined;\n let column: number | undefined;\n\n if (v.filePath) {\n filePath = v.filePath;\n line = v.line;\n column = v.column;\n } else if (v.nodeId) {\n const parts = v.nodeId.split(':');\n if (parts.length >= 3) {\n const col = parseInt(parts.pop()!, 10);\n const ln = parseInt(parts.pop()!, 10);\n const path = parts.join(':');\n if (!isNaN(ln) && !isNaN(col) && path) {\n filePath = path;\n line = ln;\n column = col;\n }\n }\n if (!filePath) {\n filePath = relative(rootDir, v.nodeId);\n }\n }\n\n findings.push({\n ruleId: v.rule,\n severity,\n filePath,\n line,\n column,\n rawValue: v.rawValue,\n message: `[${result.validator}] ${v.message}`,\n category: result.validator,\n fingerprint,\n suggestedToken: v.suggestion,\n });\n }\n }\n }\n\n if (!quiet) {\n console.log(pc.dim(` Reporting ${findings.length} finding(s) to Fragments Cloud...`));\n }\n\n const gitMeta = detectGitMetadata();\n\n try {\n const response = await fetch(`${baseUrl}/api/govern/ingest`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n findings,\n source: 'ci',\n diffOnly: diffOnly ?? false,\n ...gitMeta,\n }),\n });\n\n if (!response.ok) {\n const body = await response.json().catch(() => ({}));\n const msg = (body as { error?: string }).error ?? `HTTP ${response.status}`;\n console.error(pc.red(` ✗ Cloud report failed: ${msg}\\n`));\n return;\n }\n\n const body = await response.json() as { ingested?: number; orgSlug?: string };\n if (!quiet) {\n console.log(\n pc.green(` ✓ Reported ${body.ingested ?? findings.length} finding(s) to Cloud`) +\n (body.orgSlug ? pc.dim(` (${body.orgSlug})`) : '') +\n '\\n',\n );\n }\n } catch (err) {\n console.error(\n pc.red(` ✗ Cloud report failed: `) +\n pc.dim(err instanceof Error ? err.message : 'Network error') +\n '\\n',\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// governWatch\n// ---------------------------------------------------------------------------\n\nexport async function governWatch(\n options: GovernWatchOptions = {},\n): Promise<void> {\n const {\n loadPolicy,\n createEngine,\n buildAdaptersFromConfig,\n formatVerdict,\n } = await import('@fragments-sdk/govern');\n\n const { scanFile } = await import('../service/enhance/scanner.js');\n const { usagesToSpec } = await import(\n '../service/enhance/converter.js'\n );\n\n const quiet = options.quiet ?? false;\n const debounceMs = options.debounce ?? 300;\n const format = options.format ?? 'summary';\n\n // 1. Run initial scan\n console.log(pc.cyan(`\\n${BRAND.name} Governance Watch\\n`));\n\n const { exitCode } = await governScan(options);\n if (!quiet) {\n console.log(\n pc.dim(` Initial scan ${exitCode === 0 ? 'passed' : 'completed with violations'}\\n`),\n );\n }\n\n // 2. Set up engine for incremental checks\n const rootDir = resolve(options.dir ?? detectRootDir(process.cwd()));\n let policy = await loadPolicy(options.config);\n if (Object.keys(policy.rules).length === 0) {\n policy = { ...policy, rules: SCAN_DEFAULT_RULES };\n }\n const adapters = buildAdaptersFromConfig(policy.audit);\n const engine = createEngine(policy, adapters);\n\n // 3. Watch for changes\n console.log(pc.dim(' Watching for changes... (Ctrl+C to stop)\\n'));\n\n const chokidar = await import('chokidar');\n\n const watcher = chokidar.watch(\n ['**/*.tsx', '**/*.ts', '**/*.jsx', '**/*.js'],\n {\n cwd: rootDir,\n ignoreInitial: true,\n ignored: [\n '**/node_modules/**',\n '**/dist/**',\n '**/build/**',\n '**/.next/**',\n '**/*.test.*',\n '**/*.spec.*',\n '**/*.stories.*',\n ],\n awaitWriteFinish: { stabilityThreshold: debounceMs },\n },\n );\n\n const handleChange = async (changedRelPath: string) => {\n const absolutePath = resolve(rootDir, changedRelPath);\n\n try {\n const { usages } = await scanFile(absolutePath);\n\n if (usages.length === 0) {\n if (!quiet) {\n console.log(pc.dim(` ○ ${changedRelPath} — no component usages`));\n }\n return;\n }\n\n const spec = usagesToSpec(usages, absolutePath, rootDir);\n const verdict = await engine.check(spec, {\n runner: 'cli',\n input: changedRelPath,\n });\n\n if (verdict.passed) {\n console.log(\n pc.green(` ✓ ${changedRelPath}`) +\n pc.dim(` (${usages.length} components, score: ${verdict.score}/100)`),\n );\n } else {\n console.log(pc.red(` ✗ ${changedRelPath}`));\n if (format === 'summary') {\n for (const result of verdict.results) {\n for (const v of result.violations) {\n console.log(\n pc.dim(` ${v.severity} `) +\n pc.yellow(v.rule) +\n pc.dim(` — ${v.message}`),\n );\n }\n }\n } else {\n console.log(formatVerdict(verdict, format));\n }\n }\n } catch (error) {\n if (!quiet) {\n console.log(\n pc.dim(` ⚠ ${changedRelPath} — `) +\n pc.yellow(error instanceof Error ? error.message : 'parse error'),\n );\n }\n }\n };\n\n watcher.on('change', handleChange);\n watcher.on('add', handleChange);\n\n // Keep process alive\n await new Promise(() => {});\n}\n","import { resolve, dirname, relative } from 'node:path';\nimport type {\n GovernanceVerdict,\n Severity,\n ComponentHealthSummary,\n Violation,\n} from '@fragments-sdk/govern';\nimport type { ComponentUsage } from '../service/enhance/types.js';\n\nexport interface FlatUsageEntry {\n component: string;\n file: string;\n occurrences: number;\n}\n\nexport interface ComplianceSummary {\n complianceRate: number;\n passingUsages: number;\n totalUsages: number;\n contractedCount: number;\n detectedCount: number;\n}\n\nexport interface GovernScanReport {\n verdict: GovernanceVerdict;\n componentUsage: FlatUsageEntry[];\n complianceSummary?: ComplianceSummary;\n}\n\nconst SEVERITY_RANK: Record<Severity, number> = {\n critical: 4,\n serious: 3,\n moderate: 2,\n minor: 1,\n};\n\nfunction mergeSeverity(a: Severity, b: Severity): Severity {\n return SEVERITY_RANK[a] >= SEVERITY_RANK[b] ? a : b;\n}\n\nexport function aggregateVerdicts(\n verdicts: GovernanceVerdict[],\n computeScore: (violations: Violation[]) => number,\n runner: string = 'cli',\n): GovernanceVerdict {\n if (verdicts.length === 0) {\n return {\n passed: true,\n score: 100,\n results: [],\n metadata: {\n runner,\n duration: 0,\n nodeCount: 0,\n componentTypes: [],\n },\n };\n }\n\n const byValidator = new Map<string, GovernanceVerdict['results'][number]>();\n let duration = 0;\n let nodeCount = 0;\n const componentTypes = new Set<string>();\n\n for (const verdict of verdicts) {\n duration += verdict.metadata.duration;\n nodeCount += verdict.metadata.nodeCount;\n for (const type of verdict.metadata.componentTypes) {\n componentTypes.add(type);\n }\n\n for (const result of verdict.results) {\n const existing = byValidator.get(result.validator);\n if (!existing) {\n byValidator.set(result.validator, {\n validator: result.validator,\n severity: result.severity,\n passed: result.passed,\n violations: [...result.violations],\n suggestions: result.suggestions ? [...result.suggestions] : undefined,\n });\n continue;\n }\n\n existing.passed = existing.passed && result.passed;\n existing.severity = mergeSeverity(existing.severity, result.severity);\n existing.violations.push(...result.violations);\n\n if (result.suggestions?.length) {\n const merged = existing.suggestions ?? [];\n merged.push(...result.suggestions);\n existing.suggestions = merged;\n }\n }\n }\n\n const results = [...byValidator.values()].sort((a, b) =>\n a.validator.localeCompare(b.validator),\n );\n const allViolations = results.flatMap((result) => result.violations);\n\n return {\n passed: verdicts.every((verdict) => verdict.passed),\n score: computeScore(allViolations),\n results,\n metadata: {\n runner,\n duration,\n nodeCount,\n componentTypes: [...componentTypes].sort(),\n },\n };\n}\n\nexport function flattenComponentUsage(\n usages: ComponentUsage[],\n rootDir: string,\n): FlatUsageEntry[] {\n const counts = new Map<string, number>();\n\n for (const usage of usages) {\n const relPath = relative(rootDir, usage.filePath);\n const key = `${relPath}\\u0000${usage.componentName}`;\n counts.set(key, (counts.get(key) ?? 0) + 1);\n }\n\n return [...counts.entries()]\n .map(([key, occurrences]) => {\n const separatorIndex = key.indexOf('\\u0000');\n const file = key.slice(0, separatorIndex);\n const component = key.slice(separatorIndex + 1);\n return { component, file, occurrences };\n })\n .sort((a, b) =>\n a.file === b.file\n ? a.component.localeCompare(b.component)\n : a.file.localeCompare(b.file),\n );\n}\n\nexport function buildComplianceSummary(\n health: ComponentHealthSummary,\n): ComplianceSummary {\n const usageTotals = Object.values(health.components).reduce(\n (acc, component) => {\n acc.passingUsages += component.passed;\n acc.totalUsages += component.total;\n return acc;\n },\n { passingUsages: 0, totalUsages: 0 },\n );\n\n return {\n complianceRate: health.overallCompliance,\n passingUsages: usageTotals.passingUsages,\n totalUsages: usageTotals.totalUsages,\n contractedCount: health.contractedComponents,\n detectedCount: health.totalComponents,\n };\n}\n\nexport async function writeGovernScanReport(\n path: string,\n report: GovernScanReport,\n): Promise<void> {\n const { mkdir, writeFile } = await import('node:fs/promises');\n const absPath = resolve(path);\n await mkdir(dirname(absPath), { recursive: true });\n await writeFile(absPath, JSON.stringify(report, null, 2), 'utf-8');\n}\n"],"mappings":"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","names":["resolve","relative","resolve","relative","body"]}
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { createRequire as __banner_createRequire } from 'module'; const require
2
2
  import {
3
3
  generateStaticViewer,
4
4
  generateViewerFromJson
5
- } from "./chunk-2WXKALIG.js";
5
+ } from "./chunk-SNZXGHL2.js";
6
6
  import {
7
7
  runAnalyzeCommand,
8
8
  runDiffCommand,
@@ -11,22 +11,21 @@ import {
11
11
  validateCoverage,
12
12
  validateSchema,
13
13
  validateSnippets
14
- } from "./chunk-5JF26E55.js";
15
- import "./chunk-6SQPP47U.js";
16
- import "./chunk-D2CDBRNU.js";
14
+ } from "./chunk-VT2J62ND.js";
17
15
  import {
18
16
  discoverComponentFiles,
19
17
  discoverFragmentFiles,
20
18
  extractComponentName,
21
19
  findConfigFile,
22
20
  loadConfig
23
- } from "./chunk-HQ6A6DTV.js";
21
+ } from "./chunk-HNHE64CR.js";
22
+ import "./chunk-ANTWP3UG.js";
23
+ import "./chunk-D2CDBRNU.js";
24
24
  import {
25
25
  defineBlock,
26
26
  defineFragment
27
- } from "./chunk-32LIWN2P.js";
28
- import "./chunk-MHIBEEW4.js";
29
- import "./chunk-QCN35LJU.js";
27
+ } from "./chunk-FFCI6OVZ.js";
28
+ import "./chunk-SAQW37L5.js";
30
29
  import "./chunk-7DZC4YEV.js";
31
30
 
32
31
  // src/index.ts
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/cli-commands.ts"],"sourcesContent":["// Re-export from core/node (Node.js-only APIs)\nexport {\n loadConfig,\n findConfigFile,\n discoverFragmentFiles,\n discoverComponentFiles,\n extractComponentName,\n} from \"./core/node.js\";\nexport type { DiscoveredFile } from \"./core/node.js\";\n\n// Validators\nexport { validateSchema, validateCoverage, validateAll, validateSnippets } from \"./validators.js\";\nexport type {\n ValidationResult,\n ValidationError,\n ValidationWarning,\n ValidationRunOptions,\n} from \"./validators.js\";\n\n// Build (delegated to @fragments-sdk/compiler)\nexport { buildFragments } from '@fragments-sdk/compiler';\nexport type { BuildResult } from '@fragments-sdk/compiler';\n\n// Screenshot\nexport { runScreenshotCommand } from \"./screenshot.js\";\nexport type {\n ScreenshotCommandOptions,\n ScreenshotResult,\n} from \"./screenshot.js\";\n\n// Diff\nexport { runDiffCommand } from \"./diff.js\";\nexport type {\n DiffCommandOptions,\n DiffCommandResult,\n VariantDiffResult,\n} from \"./diff.js\";\n\n// Analyze\nexport { runAnalyzeCommand } from \"./analyze.js\";\nexport type { AnalyzeOptions, AnalyzeResult } from \"./analyze.js\";\n\n// Static Viewer\nexport { generateStaticViewer, generateViewerFromJson } from \"./static-viewer.js\";\n\n// Config type (used by generated fragments.config.ts)\nexport type { FragmentsConfig } from \"./core/index.js\";\n\n// Fragment definition API (used by generated .fragment.tsx files)\nexport { defineFragment, defineBlock } from \"./core/index.js\";\n\n// CLI Command metadata (for docs)\nexport { CLI_COMMANDS, CLI_COMMAND_CATEGORIES } from \"./cli-commands.js\";\nexport type { CliCommandDef, CliOptionDef, CliCommandCategory, CliCategoryInfo } from \"./cli-commands.js\";\n","/**\n * CLI command metadata — re-exported from @fragments-sdk/context for convenience.\n *\n * The source of truth lives in @fragments-sdk/context/cli-commands so that\n * browser-safe consumers (like the docs site) can import without pulling in\n * Node.js dependencies from the CLI package.\n */\nexport {\n CLI_COMMANDS,\n CLI_COMMAND_CATEGORIES,\n} from '@fragments-sdk/context/cli-commands';\n\nexport type {\n CliCommandDef,\n CliOptionDef,\n CliCommandCategory,\n CliCategoryInfo,\n} from '@fragments-sdk/context/cli-commands';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,SAAS,sBAAsB;;;ACb/B;AAAA,EACE;AAAA,EACA;AAAA,OACK;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/cli-commands.ts"],"sourcesContent":["// Re-export from core/node (Node.js-only APIs)\nexport {\n loadConfig,\n findConfigFile,\n discoverFragmentFiles,\n discoverComponentFiles,\n extractComponentName,\n} from \"./core/node.js\";\nexport type { DiscoveredFile } from \"./core/node.js\";\n\n// Validators\nexport { validateSchema, validateCoverage, validateAll, validateSnippets } from \"./validators.js\";\nexport type {\n ValidationResult,\n ValidationError,\n ValidationWarning,\n ValidationRunOptions,\n} from \"./validators.js\";\n\n// Build (delegated to @fragments-sdk/compiler)\nexport { buildFragments } from '@fragments-sdk/compiler';\nexport type { BuildResult } from '@fragments-sdk/compiler';\n\n// Screenshot\nexport { runScreenshotCommand } from \"./screenshot.js\";\nexport type {\n ScreenshotCommandOptions,\n ScreenshotResult,\n} from \"./screenshot.js\";\n\n// Diff\nexport { runDiffCommand } from \"./diff.js\";\nexport type {\n DiffCommandOptions,\n DiffCommandResult,\n VariantDiffResult,\n} from \"./diff.js\";\n\n// Analyze\nexport { runAnalyzeCommand } from \"./analyze.js\";\nexport type { AnalyzeOptions, AnalyzeResult } from \"./analyze.js\";\n\n// Static Viewer\nexport { generateStaticViewer, generateViewerFromJson } from \"./static-viewer.js\";\n\n// Config type (used by generated fragments.config.ts)\nexport type { FragmentsConfig } from \"./core/index.js\";\n\n// Fragment definition API (used by generated .fragment.tsx files)\nexport { defineFragment, defineBlock } from \"./core/index.js\";\n\n// CLI Command metadata (for docs)\nexport { CLI_COMMANDS, CLI_COMMAND_CATEGORIES } from \"./cli-commands.js\";\nexport type { CliCommandDef, CliOptionDef, CliCommandCategory, CliCategoryInfo } from \"./cli-commands.js\";\n","/**\n * CLI command metadata — re-exported from @fragments-sdk/context for convenience.\n *\n * The source of truth lives in @fragments-sdk/context/cli-commands so that\n * browser-safe consumers (like the docs site) can import without pulling in\n * Node.js dependencies from the CLI package.\n */\nexport {\n CLI_COMMANDS,\n CLI_COMMAND_CATEGORIES,\n} from '@fragments-sdk/context/cli-commands';\n\nexport type {\n CliCommandDef,\n CliOptionDef,\n CliCommandCategory,\n CliCategoryInfo,\n} from '@fragments-sdk/context/cli-commands';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,SAAS,sBAAsB;;;ACb/B;AAAA,EACE;AAAA,EACA;AAAA,OACK;","names":[]}
@@ -5,11 +5,11 @@ import {
5
5
  addTranspilePackages,
6
6
  detectSetupFramework,
7
7
  findEntryFile
8
- } from "./chunk-BJE3425I.js";
8
+ } from "./chunk-MN3B2EE6.js";
9
9
  import "./chunk-D2CDBRNU.js";
10
10
  import {
11
11
  BRAND
12
- } from "./chunk-32LIWN2P.js";
12
+ } from "./chunk-FFCI6OVZ.js";
13
13
 
14
14
  // src/commands/init.ts
15
15
  import { readFile, writeFile, mkdir, access } from "fs/promises";
@@ -370,7 +370,7 @@ Scan path not found: ${scanPath}
370
370
  errors: [`Scan path not found: ${scanPath}`]
371
371
  };
372
372
  }
373
- const { scanGenerate } = await import("./scan-generate-VY27PIOX.js");
373
+ const { scanGenerate } = await import("./scan-generate-LUSOHT36.js");
374
374
  const scanResult = await scanGenerate({
375
375
  scanPath,
376
376
  force: options.force,
@@ -578,7 +578,7 @@ ${BRAND.name} init
578
578
  }
579
579
  if (scenario === "components" || scenario === "stories") {
580
580
  try {
581
- const { scan } = await import("./scan-PKSYSTRR.js");
581
+ const { scan } = await import("./scan-A2WJM54L.js");
582
582
  const scanResult = await scan({
583
583
  config: configPath,
584
584
  verbose: false,
@@ -635,4 +635,4 @@ ${BRAND.name} init
635
635
  export {
636
636
  init
637
637
  };
638
- //# sourceMappingURL=init-SSGUSP7Z.js.map
638
+ //# sourceMappingURL=init-2RGAY4W6.js.map
package/dist/mcp-bin.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  BRAND,
9
9
  DEFAULTS,
10
10
  generateContext
11
- } from "./chunk-32LIWN2P.js";
11
+ } from "./chunk-FFCI6OVZ.js";
12
12
 
13
13
  // src/mcp/server.ts
14
14
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -42,7 +42,7 @@ var _service = null;
42
42
  async function getService() {
43
43
  if (!_service) {
44
44
  try {
45
- _service = await import("./service-QJGWUIVL.js");
45
+ _service = await import("./service-ROCP7TKG.js");
46
46
  } catch {
47
47
  throw new Error(
48
48
  "Visual tools require playwright. Install it with: npm install playwright"
@@ -0,0 +1,14 @@
1
+ import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
2
+ import {
3
+ scan
4
+ } from "./chunk-B4A4ZEGS.js";
5
+ import "./chunk-HNHE64CR.js";
6
+ import "./chunk-ANTWP3UG.js";
7
+ import "./chunk-D2CDBRNU.js";
8
+ import "./chunk-FFCI6OVZ.js";
9
+ import "./chunk-SAQW37L5.js";
10
+ import "./chunk-7DZC4YEV.js";
11
+ export {
12
+ scan
13
+ };
14
+ //# sourceMappingURL=scan-A2WJM54L.js.map
@@ -1,11 +1,11 @@
1
1
  import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
2
- import "./chunk-D2CDBRNU.js";
3
2
  import {
4
3
  discoverAllComponents
5
- } from "./chunk-HQ6A6DTV.js";
4
+ } from "./chunk-HNHE64CR.js";
5
+ import "./chunk-D2CDBRNU.js";
6
6
  import {
7
7
  BRAND
8
- } from "./chunk-32LIWN2P.js";
8
+ } from "./chunk-FFCI6OVZ.js";
9
9
 
10
10
  // src/commands/scan-generate.ts
11
11
  import { readFile, writeFile, access, mkdir } from "fs/promises";
@@ -1400,4 +1400,4 @@ export {
1400
1400
  resolveCoreInstallCommand,
1401
1401
  scanGenerate
1402
1402
  };
1403
- //# sourceMappingURL=scan-generate-VY27PIOX.js.map
1403
+ //# sourceMappingURL=scan-generate-LUSOHT36.js.map
@@ -23,6 +23,7 @@ import {
23
23
  checkStorybookRunning,
24
24
  clearSharedRegistry,
25
25
  computeHash,
26
+ containsTailwindV4Theme,
26
27
  convertToFragmentProps,
27
28
  createCaptureEngine,
28
29
  createDeferred,
@@ -60,35 +61,32 @@ import {
60
61
  getSharedPool,
61
62
  getSharedTokenRegistry,
62
63
  getStorybookStoryIds,
64
+ hexToRgb,
63
65
  initializeSharedRegistry,
64
66
  isBoilerplate,
65
67
  mergeStorybookIntoDoc,
68
+ normalizeColor,
66
69
  parseAllStories,
70
+ parseRgb,
67
71
  parseStoryFile,
68
72
  parseStorySource,
73
+ parseTailwindV4File,
74
+ parseTailwindV4Theme,
75
+ parseTokenFile,
76
+ parseTokenFiles,
69
77
  renderAllComponentVariants,
70
78
  renderVariants,
71
79
  retry,
80
+ rgbToHex,
72
81
  sanitizeFilename,
73
82
  shutdownSharedPool,
74
83
  sleep
75
- } from "./chunk-6SQPP47U.js";
84
+ } from "./chunk-ANTWP3UG.js";
76
85
  import "./chunk-D2CDBRNU.js";
77
86
  import {
78
87
  BRAND,
79
88
  DEFAULTS
80
- } from "./chunk-32LIWN2P.js";
81
- import {
82
- containsTailwindV4Theme,
83
- hexToRgb,
84
- normalizeColor,
85
- parseRgb,
86
- parseTailwindV4File,
87
- parseTailwindV4Theme,
88
- parseTokenFile,
89
- parseTokenFiles,
90
- rgbToHex
91
- } from "./chunk-MHIBEEW4.js";
89
+ } from "./chunk-FFCI6OVZ.js";
92
90
  import {
93
91
  aggregateAllUsages,
94
92
  aggregateComponentUsages,
@@ -106,7 +104,7 @@ import {
106
104
  saveCache,
107
105
  scanCodebase,
108
106
  summarizePatternsForPrompt
109
- } from "./chunk-QCN35LJU.js";
107
+ } from "./chunk-SAQW37L5.js";
110
108
  import {
111
109
  scanFile,
112
110
  scanFileForImports,
@@ -217,4 +215,4 @@ export {
217
215
  sleep,
218
216
  summarizePatternsForPrompt
219
217
  };
220
- //# sourceMappingURL=service-QJGWUIVL.js.map
218
+ //# sourceMappingURL=service-ROCP7TKG.js.map
@@ -2,7 +2,7 @@ import { createRequire as __banner_createRequire } from 'module'; const require
2
2
  import "./chunk-D2CDBRNU.js";
3
3
  import {
4
4
  BRAND
5
- } from "./chunk-32LIWN2P.js";
5
+ } from "./chunk-FFCI6OVZ.js";
6
6
 
7
7
  // src/commands/snapshot.ts
8
8
  import { resolve } from "path";
@@ -135,4 +135,4 @@ ${BRAND.name} Visual Snapshots
135
135
  export {
136
136
  snapshot
137
137
  };
138
- //# sourceMappingURL=snapshot-WIJMEIFT.js.map
138
+ //# sourceMappingURL=snapshot-B3SAW74Y.js.map
@@ -2,11 +2,11 @@ import { createRequire as __banner_createRequire } from 'module'; const require
2
2
  import {
3
3
  generateStaticViewer,
4
4
  generateViewerFromJson
5
- } from "./chunk-2WXKALIG.js";
5
+ } from "./chunk-SNZXGHL2.js";
6
6
  import "./chunk-D2CDBRNU.js";
7
- import "./chunk-32LIWN2P.js";
7
+ import "./chunk-FFCI6OVZ.js";
8
8
  export {
9
9
  generateStaticViewer,
10
10
  generateViewerFromJson
11
11
  };
12
- //# sourceMappingURL=static-viewer-7QIBQZRC.js.map
12
+ //# sourceMappingURL=static-viewer-7L6UEYTJ.js.map
@@ -2,8 +2,8 @@ import { createRequire as __banner_createRequire } from 'module'; const require
2
2
  import {
3
3
  discoverFragmentFiles,
4
4
  parseFragmentFile
5
- } from "./chunk-HQ6A6DTV.js";
6
- import "./chunk-32LIWN2P.js";
5
+ } from "./chunk-HNHE64CR.js";
6
+ import "./chunk-FFCI6OVZ.js";
7
7
 
8
8
  // src/test/index.ts
9
9
  import { resolve as resolve2, join as join2 } from "path";
@@ -1068,4 +1068,4 @@ export {
1068
1068
  listTests,
1069
1069
  runTestCommand
1070
1070
  };
1071
- //# sourceMappingURL=test-64Z5BKBA.js.map
1071
+ //# sourceMappingURL=test-PQDVDURE.js.map
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
2
2
  import {
3
3
  parseColor
4
- } from "./chunk-32LIWN2P.js";
4
+ } from "./chunk-FFCI6OVZ.js";
5
5
 
6
6
  // src/service/token-normalizer.ts
7
7
  import { existsSync } from "fs";
@@ -309,4 +309,4 @@ export {
309
309
  normalizeCSSVarTokens,
310
310
  normalizeTailwindTheme
311
311
  };
312
- //# sourceMappingURL=token-normalizer-TEPOVBPV.js.map
312
+ //# sourceMappingURL=token-normalizer-7TFCVDZL.js.map
@@ -1,16 +1,15 @@
1
1
  import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
2
- import "./chunk-6SQPP47U.js";
3
- import "./chunk-D2CDBRNU.js";
4
2
  import {
5
3
  loadConfig
6
- } from "./chunk-HQ6A6DTV.js";
7
- import {
8
- BRAND
9
- } from "./chunk-32LIWN2P.js";
4
+ } from "./chunk-HNHE64CR.js";
10
5
  import {
11
6
  parseTokenFiles
12
- } from "./chunk-MHIBEEW4.js";
13
- import "./chunk-QCN35LJU.js";
7
+ } from "./chunk-ANTWP3UG.js";
8
+ import "./chunk-D2CDBRNU.js";
9
+ import {
10
+ BRAND
11
+ } from "./chunk-FFCI6OVZ.js";
12
+ import "./chunk-SAQW37L5.js";
14
13
  import "./chunk-7DZC4YEV.js";
15
14
 
16
15
  // src/commands/tokens.ts
@@ -173,4 +172,4 @@ export {
173
172
  tokens_default as default,
174
173
  tokens
175
174
  };
176
- //# sourceMappingURL=tokens-NZWFQIAB.js.map
175
+ //# sourceMappingURL=tokens-64FG5FDP.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/tokens.ts"],"sourcesContent":["/**\n * CLI Tokens Command\n *\n * Discover and list design tokens from CSS/SCSS files.\n *\n * Usage:\n * fragments tokens # List all tokens\n * fragments tokens --json # Output as JSON\n * fragments tokens --categories # Group by category\n * fragments tokens --theme dark # Filter by theme\n */\n\nimport pc from \"picocolors\";\nimport { BRAND } from \"../core/index.js\";\nimport type { DesignToken, TokenCategory, TokenConfig } from \"../core/index.js\";\nimport { loadConfig } from \"../core/node.js\";\nimport { parseTokenFiles, createTokenRegistry } from \"../service/index.js\";\n\nexport interface TokensCommandOptions {\n config?: string;\n json?: boolean;\n categories?: boolean;\n theme?: string;\n category?: string;\n verbose?: boolean;\n}\n\nexport interface TokensCommandResult {\n success: boolean;\n tokenCount: number;\n errors: string[];\n}\n\n/**\n * Run the tokens command\n */\nexport async function tokens(\n options: TokensCommandOptions\n): Promise<TokensCommandResult> {\n const errors: string[] = [];\n\n try {\n console.log(pc.cyan(`\\n${BRAND.name} Token Discovery\\n`));\n\n // Load config\n const { config, configDir } = await loadConfig(options.config);\n\n // Check for token configuration\n if (!config.tokens || !config.tokens.include || config.tokens.include.length === 0) {\n console.log(pc.yellow(\"No token configuration found.\\n\"));\n console.log(pc.dim(\"Add 'tokens' config to fragments.config.ts:\"));\n console.log(pc.dim(`\n tokens: {\n include: ['src/styles/theme.scss', 'src/styles/variables.css'],\n themeSelectors: {\n ':root': 'default',\n '[data-theme=\"dark\"]': 'dark',\n },\n },\n`));\n return { success: false, tokenCount: 0, errors: [\"No token configuration\"] };\n }\n\n console.log(pc.dim(`Scanning files: ${config.tokens.include.join(\", \")}\\n`));\n\n // Parse token files\n const parseResult = await parseTokenFiles(config.tokens, configDir);\n\n if (parseResult.errors.length > 0) {\n console.log(pc.yellow(\"Parse errors:\"));\n for (const err of parseResult.errors) {\n console.log(pc.red(` ${err.file}: ${err.message}`));\n errors.push(`${err.file}: ${err.message}`);\n }\n console.log();\n }\n\n if (parseResult.warnings.length > 0 && options.verbose) {\n console.log(pc.yellow(\"Warnings:\"));\n for (const warning of parseResult.warnings) {\n console.log(pc.dim(` ${warning}`));\n }\n console.log();\n }\n\n let tokens = parseResult.tokens;\n\n // Filter by theme if specified\n if (options.theme) {\n tokens = tokens.filter(\n (t) => t.theme === options.theme || t.theme === \"default\"\n );\n }\n\n // Filter by category if specified\n if (options.category) {\n tokens = tokens.filter((t) => t.category === options.category);\n }\n\n if (tokens.length === 0) {\n console.log(pc.yellow(\"No tokens found.\\n\"));\n console.log(pc.dim(\"Make sure your CSS files contain CSS custom properties (--token-name: value;)\"));\n return { success: true, tokenCount: 0, errors };\n }\n\n // Output based on format\n if (options.json) {\n outputJson(tokens, parseResult.parseTimeMs);\n } else if (options.categories) {\n outputByCategory(tokens, parseResult.parseTimeMs);\n } else {\n outputList(tokens, parseResult.parseTimeMs, options.verbose);\n }\n\n return { success: true, tokenCount: tokens.length, errors };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n console.error(pc.red(\"Error:\"), message);\n errors.push(message);\n return { success: false, tokenCount: 0, errors };\n }\n}\n\n/**\n * Output tokens as JSON\n */\nfunction outputJson(tokens: DesignToken[], parseTimeMs: number): void {\n const output = {\n tokens,\n meta: {\n totalTokens: tokens.length,\n parseTimeMs,\n discoveredAt: new Date().toISOString(),\n },\n };\n\n console.log(JSON.stringify(output, null, 2));\n}\n\n/**\n * Output tokens grouped by category\n */\nfunction outputByCategory(tokens: DesignToken[], parseTimeMs: number): void {\n // Group by category\n const byCategory = new Map<TokenCategory, DesignToken[]>();\n\n for (const token of tokens) {\n const list = byCategory.get(token.category) || [];\n list.push(token);\n byCategory.set(token.category, list);\n }\n\n // Sort categories alphabetically\n const categories = Array.from(byCategory.keys()).sort();\n\n for (const category of categories) {\n const categoryTokens = byCategory.get(category) || [];\n console.log(pc.bold(`${category} (${categoryTokens.length})`));\n console.log(pc.dim(\"─\".repeat(40)));\n\n for (const token of categoryTokens.slice(0, 10)) {\n const levelLabel = token.level === 1 ? \"base\" : token.level === 2 ? \"semantic\" : \"component\";\n console.log(` ${pc.cyan(token.name)}`);\n console.log(` ${pc.dim(\"Value:\")} ${token.resolvedValue}`);\n console.log(` ${pc.dim(\"Level:\")} ${levelLabel} ${pc.dim(`(${token.theme})`)}`);\n }\n\n if (categoryTokens.length > 10) {\n console.log(pc.dim(` ... and ${categoryTokens.length - 10} more`));\n }\n console.log();\n }\n\n // Summary\n console.log(pc.dim(\"─\".repeat(40)));\n console.log(pc.green(`✓ Found ${tokens.length} token(s) in ${categories.length} categories`));\n console.log(pc.dim(` Parsed in ${parseTimeMs.toFixed(1)}ms\\n`));\n}\n\n/**\n * Output tokens as a simple list\n */\nfunction outputList(tokens: DesignToken[], parseTimeMs: number, verbose?: boolean): void {\n // Group by theme first\n const byTheme = new Map<string, DesignToken[]>();\n\n for (const token of tokens) {\n const list = byTheme.get(token.theme) || [];\n list.push(token);\n byTheme.set(token.theme, list);\n }\n\n const themes = Array.from(byTheme.keys()).sort();\n\n for (const theme of themes) {\n const themeTokens = byTheme.get(theme) || [];\n\n if (themes.length > 1) {\n console.log(pc.bold(`Theme: ${theme} (${themeTokens.length} tokens)`));\n console.log(pc.dim(\"─\".repeat(50)));\n }\n\n // Sort tokens by name\n themeTokens.sort((a, b) => a.name.localeCompare(b.name));\n\n // Table header\n console.log(\n pc.dim(\n `${\"Token Name\".padEnd(32)} ${\"Value\".padEnd(20)} ${\"Category\".padEnd(12)}`\n )\n );\n console.log(pc.dim(\"─\".repeat(70)));\n\n const displayTokens = verbose ? themeTokens : themeTokens.slice(0, 30);\n\n for (const token of displayTokens) {\n const name = token.name.length > 30 ? token.name.slice(0, 27) + \"...\" : token.name;\n const value = token.resolvedValue.length > 18 ? token.resolvedValue.slice(0, 15) + \"...\" : token.resolvedValue;\n\n console.log(\n `${pc.cyan(name.padEnd(32))} ${value.padEnd(20)} ${pc.dim(token.category.padEnd(12))}`\n );\n }\n\n if (!verbose && themeTokens.length > 30) {\n console.log(pc.dim(`\\n ... and ${themeTokens.length - 30} more (use --verbose to show all)`));\n }\n\n console.log();\n }\n\n // Summary\n console.log(pc.dim(\"─\".repeat(50)));\n console.log(pc.green(`✓ Found ${tokens.length} token(s)`));\n\n // Category breakdown\n const categoryCounts: Record<string, number> = {};\n for (const token of tokens) {\n categoryCounts[token.category] = (categoryCounts[token.category] || 0) + 1;\n }\n\n const breakdown = Object.entries(categoryCounts)\n .sort((a, b) => b[1] - a[1])\n .map(([cat, count]) => `${cat}: ${count}`)\n .join(\", \");\n\n console.log(pc.dim(` ${breakdown}`));\n console.log(pc.dim(` Parsed in ${parseTimeMs.toFixed(1)}ms\\n`));\n}\n\nexport default tokens;\n"],"mappings":"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","names":["tokens"]}
1
+ {"version":3,"sources":["../src/commands/tokens.ts"],"sourcesContent":["/**\n * CLI Tokens Command\n *\n * Discover and list design tokens from CSS/SCSS files.\n *\n * Usage:\n * fragments tokens # List all tokens\n * fragments tokens --json # Output as JSON\n * fragments tokens --categories # Group by category\n * fragments tokens --theme dark # Filter by theme\n */\n\nimport pc from \"picocolors\";\nimport { BRAND } from \"../core/index.js\";\nimport type { DesignToken, TokenCategory, TokenConfig } from \"../core/index.js\";\nimport { loadConfig } from \"../core/node.js\";\nimport { parseTokenFiles, createTokenRegistry } from \"../service/index.js\";\n\nexport interface TokensCommandOptions {\n config?: string;\n json?: boolean;\n categories?: boolean;\n theme?: string;\n category?: string;\n verbose?: boolean;\n}\n\nexport interface TokensCommandResult {\n success: boolean;\n tokenCount: number;\n errors: string[];\n}\n\n/**\n * Run the tokens command\n */\nexport async function tokens(\n options: TokensCommandOptions\n): Promise<TokensCommandResult> {\n const errors: string[] = [];\n\n try {\n console.log(pc.cyan(`\\n${BRAND.name} Token Discovery\\n`));\n\n // Load config\n const { config, configDir } = await loadConfig(options.config);\n\n // Check for token configuration\n if (!config.tokens || !config.tokens.include || config.tokens.include.length === 0) {\n console.log(pc.yellow(\"No token configuration found.\\n\"));\n console.log(pc.dim(\"Add 'tokens' config to fragments.config.ts:\"));\n console.log(pc.dim(`\n tokens: {\n include: ['src/styles/theme.scss', 'src/styles/variables.css'],\n themeSelectors: {\n ':root': 'default',\n '[data-theme=\"dark\"]': 'dark',\n },\n },\n`));\n return { success: false, tokenCount: 0, errors: [\"No token configuration\"] };\n }\n\n console.log(pc.dim(`Scanning files: ${config.tokens.include.join(\", \")}\\n`));\n\n // Parse token files\n const parseResult = await parseTokenFiles(config.tokens, configDir);\n\n if (parseResult.errors.length > 0) {\n console.log(pc.yellow(\"Parse errors:\"));\n for (const err of parseResult.errors) {\n console.log(pc.red(` ${err.file}: ${err.message}`));\n errors.push(`${err.file}: ${err.message}`);\n }\n console.log();\n }\n\n if (parseResult.warnings.length > 0 && options.verbose) {\n console.log(pc.yellow(\"Warnings:\"));\n for (const warning of parseResult.warnings) {\n console.log(pc.dim(` ${warning}`));\n }\n console.log();\n }\n\n let tokens = parseResult.tokens;\n\n // Filter by theme if specified\n if (options.theme) {\n tokens = tokens.filter(\n (t) => t.theme === options.theme || t.theme === \"default\"\n );\n }\n\n // Filter by category if specified\n if (options.category) {\n tokens = tokens.filter((t) => t.category === options.category);\n }\n\n if (tokens.length === 0) {\n console.log(pc.yellow(\"No tokens found.\\n\"));\n console.log(pc.dim(\"Make sure your CSS files contain CSS custom properties (--token-name: value;)\"));\n return { success: true, tokenCount: 0, errors };\n }\n\n // Output based on format\n if (options.json) {\n outputJson(tokens, parseResult.parseTimeMs);\n } else if (options.categories) {\n outputByCategory(tokens, parseResult.parseTimeMs);\n } else {\n outputList(tokens, parseResult.parseTimeMs, options.verbose);\n }\n\n return { success: true, tokenCount: tokens.length, errors };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n console.error(pc.red(\"Error:\"), message);\n errors.push(message);\n return { success: false, tokenCount: 0, errors };\n }\n}\n\n/**\n * Output tokens as JSON\n */\nfunction outputJson(tokens: DesignToken[], parseTimeMs: number): void {\n const output = {\n tokens,\n meta: {\n totalTokens: tokens.length,\n parseTimeMs,\n discoveredAt: new Date().toISOString(),\n },\n };\n\n console.log(JSON.stringify(output, null, 2));\n}\n\n/**\n * Output tokens grouped by category\n */\nfunction outputByCategory(tokens: DesignToken[], parseTimeMs: number): void {\n // Group by category\n const byCategory = new Map<TokenCategory, DesignToken[]>();\n\n for (const token of tokens) {\n const list = byCategory.get(token.category) || [];\n list.push(token);\n byCategory.set(token.category, list);\n }\n\n // Sort categories alphabetically\n const categories = Array.from(byCategory.keys()).sort();\n\n for (const category of categories) {\n const categoryTokens = byCategory.get(category) || [];\n console.log(pc.bold(`${category} (${categoryTokens.length})`));\n console.log(pc.dim(\"─\".repeat(40)));\n\n for (const token of categoryTokens.slice(0, 10)) {\n const levelLabel = token.level === 1 ? \"base\" : token.level === 2 ? \"semantic\" : \"component\";\n console.log(` ${pc.cyan(token.name)}`);\n console.log(` ${pc.dim(\"Value:\")} ${token.resolvedValue}`);\n console.log(` ${pc.dim(\"Level:\")} ${levelLabel} ${pc.dim(`(${token.theme})`)}`);\n }\n\n if (categoryTokens.length > 10) {\n console.log(pc.dim(` ... and ${categoryTokens.length - 10} more`));\n }\n console.log();\n }\n\n // Summary\n console.log(pc.dim(\"─\".repeat(40)));\n console.log(pc.green(`✓ Found ${tokens.length} token(s) in ${categories.length} categories`));\n console.log(pc.dim(` Parsed in ${parseTimeMs.toFixed(1)}ms\\n`));\n}\n\n/**\n * Output tokens as a simple list\n */\nfunction outputList(tokens: DesignToken[], parseTimeMs: number, verbose?: boolean): void {\n // Group by theme first\n const byTheme = new Map<string, DesignToken[]>();\n\n for (const token of tokens) {\n const list = byTheme.get(token.theme) || [];\n list.push(token);\n byTheme.set(token.theme, list);\n }\n\n const themes = Array.from(byTheme.keys()).sort();\n\n for (const theme of themes) {\n const themeTokens = byTheme.get(theme) || [];\n\n if (themes.length > 1) {\n console.log(pc.bold(`Theme: ${theme} (${themeTokens.length} tokens)`));\n console.log(pc.dim(\"─\".repeat(50)));\n }\n\n // Sort tokens by name\n themeTokens.sort((a, b) => a.name.localeCompare(b.name));\n\n // Table header\n console.log(\n pc.dim(\n `${\"Token Name\".padEnd(32)} ${\"Value\".padEnd(20)} ${\"Category\".padEnd(12)}`\n )\n );\n console.log(pc.dim(\"─\".repeat(70)));\n\n const displayTokens = verbose ? themeTokens : themeTokens.slice(0, 30);\n\n for (const token of displayTokens) {\n const name = token.name.length > 30 ? token.name.slice(0, 27) + \"...\" : token.name;\n const value = token.resolvedValue.length > 18 ? token.resolvedValue.slice(0, 15) + \"...\" : token.resolvedValue;\n\n console.log(\n `${pc.cyan(name.padEnd(32))} ${value.padEnd(20)} ${pc.dim(token.category.padEnd(12))}`\n );\n }\n\n if (!verbose && themeTokens.length > 30) {\n console.log(pc.dim(`\\n ... and ${themeTokens.length - 30} more (use --verbose to show all)`));\n }\n\n console.log();\n }\n\n // Summary\n console.log(pc.dim(\"─\".repeat(50)));\n console.log(pc.green(`✓ Found ${tokens.length} token(s)`));\n\n // Category breakdown\n const categoryCounts: Record<string, number> = {};\n for (const token of tokens) {\n categoryCounts[token.category] = (categoryCounts[token.category] || 0) + 1;\n }\n\n const breakdown = Object.entries(categoryCounts)\n .sort((a, b) => b[1] - a[1])\n .map(([cat, count]) => `${cat}: ${count}`)\n .join(\", \");\n\n console.log(pc.dim(` ${breakdown}`));\n console.log(pc.dim(` Parsed in ${parseTimeMs.toFixed(1)}ms\\n`));\n}\n\nexport default tokens;\n"],"mappings":"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","names":["tokens"]}
@@ -5,7 +5,7 @@ import {
5
5
  generateFigmaVariables,
6
6
  generateSCSSVariables,
7
7
  generateTailwindConfig
8
- } from "./chunk-32LIWN2P.js";
8
+ } from "./chunk-FFCI6OVZ.js";
9
9
 
10
10
  // src/commands/tokens-generate.ts
11
11
  import { readFile, writeFile, mkdir } from "fs/promises";
@@ -82,4 +82,4 @@ export default ${JSON.stringify(config, null, 2)};
82
82
  export {
83
83
  tokensGenerate
84
84
  };
85
- //# sourceMappingURL=tokens-generate-5JQSJ27E.js.map
85
+ //# sourceMappingURL=tokens-generate-CL4LBBQA.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fragments-sdk/cli",
3
- "version": "0.15.10",
3
+ "version": "0.17.0",
4
4
  "license": "FSL-1.1-MIT",
5
5
  "description": "CLI, MCP server, and dev tools for Fragments design system",
6
6
  "author": "Conan McNicholl",
@@ -70,6 +70,7 @@
70
70
  "chokidar": "^4.0.3",
71
71
  "commander": "^12.1.0",
72
72
  "esbuild": "^0.24.0",
73
+ "fflate": "^0.8.2",
73
74
  "fast-glob": "^3.3.3",
74
75
  "jiti": "^2.6.1",
75
76
  "openai": "^6.16.0",
@@ -81,13 +82,13 @@
81
82
  "vite": "^6.0.0",
82
83
  "vite-plugin-svgr": "^4.5.0",
83
84
  "zod": "^3.24.1",
84
- "@fragments-sdk/compiler": "0.2.0",
85
- "@fragments-sdk/extract": "0.1.0",
86
- "@fragments-sdk/context": "0.6.0",
87
- "@fragments-sdk/core": "2.0.0",
88
- "@fragments-sdk/govern": "^0.3.1",
89
- "@fragments-sdk/viewer": "0.2.9",
90
- "@fragments-sdk/webmcp": "3.0.0"
85
+ "@fragments-sdk/compiler": "0.2.1",
86
+ "@fragments-sdk/extract": "0.1.1",
87
+ "@fragments-sdk/context": "0.6.1",
88
+ "@fragments-sdk/govern": "^0.3.2",
89
+ "@fragments-sdk/viewer": "0.2.10",
90
+ "@fragments-sdk/webmcp": "3.0.0",
91
+ "@fragments-sdk/core": "2.1.0"
91
92
  },
92
93
  "devDependencies": {
93
94
  "@types/babel__generator": "^7.6.8",