@fragments-sdk/cli 0.15.10 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +896 -787
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-6SQPP47U.js → chunk-77AAP6R6.js} +532 -31
- package/dist/chunk-77AAP6R6.js.map +1 -0
- package/dist/{chunk-5JF26E55.js → chunk-ACFVKMVZ.js} +11 -11
- package/dist/{chunk-BJE3425I.js → chunk-ACX7YWZW.js} +2 -2
- package/dist/{chunk-ONUP6Z4W.js → chunk-G6UVWMFU.js} +8 -8
- package/dist/{chunk-2WXKALIG.js → chunk-OZZ4SVZX.js} +2 -2
- package/dist/{chunk-32LIWN2P.js → chunk-SJFSG7QF.js} +582 -261
- package/dist/chunk-SJFSG7QF.js.map +1 -0
- package/dist/{chunk-HQ6A6DTV.js → chunk-XRADMHMV.js} +315 -1089
- package/dist/chunk-XRADMHMV.js.map +1 -0
- package/dist/core/index.js +53 -1
- package/dist/{create-EXURTBKK.js → create-3ZFYQB3T.js} +2 -2
- package/dist/{doctor-BDPMYYE6.js → doctor-4IDUM7HI.js} +2 -2
- package/dist/{generate-PVOLUAAC.js → generate-VNUUWVWQ.js} +4 -4
- package/dist/{govern-scan-DW4QUAYD.js → govern-scan-HTACKYPF.js} +158 -120
- package/dist/govern-scan-HTACKYPF.js.map +1 -0
- package/dist/index.js +6 -7
- package/dist/index.js.map +1 -1
- package/dist/{init-SSGUSP7Z.js → init-PXFRAQ64.js} +5 -5
- package/dist/mcp-bin.js +2 -2
- package/dist/{scan-PKSYSTRR.js → scan-L4GWGEZX.js} +5 -6
- package/dist/{scan-generate-VY27PIOX.js → scan-generate-74EYSAGH.js} +4 -4
- package/dist/{service-QJGWUIVL.js → service-VELQHEWV.js} +12 -14
- package/dist/{snapshot-WIJMEIFT.js → snapshot-DT4B6DPR.js} +2 -2
- package/dist/{static-viewer-7QIBQZRC.js → static-viewer-E4OJWFDJ.js} +3 -3
- package/dist/{test-64Z5BKBA.js → test-QJY2QO4X.js} +3 -3
- package/dist/{token-normalizer-TEPOVBPV.js → token-normalizer-56H4242J.js} +2 -2
- package/dist/{tokens-NZWFQIAB.js → tokens-K6URXFPK.js} +7 -8
- package/dist/{tokens-NZWFQIAB.js.map → tokens-K6URXFPK.js.map} +1 -1
- package/dist/{tokens-generate-5JQSJ27E.js → tokens-generate-EL6IN536.js} +2 -2
- package/package.json +7 -6
- package/src/bin.ts +49 -88
- package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/label.contract.json +1 -1
- package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/primitive.contract.json +1 -1
- package/src/commands/__tests__/context-cloud.test.ts +291 -0
- package/src/commands/__tests__/govern-scan.test.ts +185 -0
- package/src/commands/__tests__/govern.test.ts +1 -0
- package/src/commands/context-cloud.ts +355 -0
- package/src/commands/govern-scan-report.ts +170 -0
- package/src/commands/govern-scan.ts +42 -147
- package/src/commands/govern.ts +0 -157
- package/dist/chunk-32LIWN2P.js.map +0 -1
- package/dist/chunk-6SQPP47U.js.map +0 -1
- package/dist/chunk-HQ6A6DTV.js.map +0 -1
- package/dist/chunk-MHIBEEW4.js +0 -511
- package/dist/chunk-MHIBEEW4.js.map +0 -1
- package/dist/govern-scan-DW4QUAYD.js.map +0 -1
- package/dist/init-cloud-3DNKPWFB.js +0 -304
- package/dist/init-cloud-3DNKPWFB.js.map +0 -1
- package/dist/node-37AUE74M.js +0 -65
- package/dist/push-contracts-WY32TFP6.js +0 -84
- package/dist/push-contracts-WY32TFP6.js.map +0 -1
- package/dist/static-viewer-7QIBQZRC.js.map +0 -1
- package/dist/token-parser-32KOIOFN.js +0 -22
- package/dist/token-parser-32KOIOFN.js.map +0 -1
- package/dist/tokens-push-HY3KO36V.js +0 -148
- package/dist/tokens-push-HY3KO36V.js.map +0 -1
- package/src/commands/init-cloud.ts +0 -382
- package/src/commands/push-contracts.ts +0 -112
- package/src/commands/tokens-push.ts +0 -199
- /package/dist/{chunk-5JF26E55.js.map → chunk-ACFVKMVZ.js.map} +0 -0
- /package/dist/{chunk-BJE3425I.js.map → chunk-ACX7YWZW.js.map} +0 -0
- /package/dist/{chunk-ONUP6Z4W.js.map → chunk-G6UVWMFU.js.map} +0 -0
- /package/dist/{chunk-2WXKALIG.js.map → chunk-OZZ4SVZX.js.map} +0 -0
- /package/dist/{create-EXURTBKK.js.map → create-3ZFYQB3T.js.map} +0 -0
- /package/dist/{doctor-BDPMYYE6.js.map → doctor-4IDUM7HI.js.map} +0 -0
- /package/dist/{generate-PVOLUAAC.js.map → generate-VNUUWVWQ.js.map} +0 -0
- /package/dist/{init-SSGUSP7Z.js.map → init-PXFRAQ64.js.map} +0 -0
- /package/dist/{node-37AUE74M.js.map → scan-L4GWGEZX.js.map} +0 -0
- /package/dist/{scan-generate-VY27PIOX.js.map → scan-generate-74EYSAGH.js.map} +0 -0
- /package/dist/{scan-PKSYSTRR.js.map → service-VELQHEWV.js.map} +0 -0
- /package/dist/{snapshot-WIJMEIFT.js.map → snapshot-DT4B6DPR.js.map} +0 -0
- /package/dist/{service-QJGWUIVL.js.map → static-viewer-E4OJWFDJ.js.map} +0 -0
- /package/dist/{test-64Z5BKBA.js.map → test-QJY2QO4X.js.map} +0 -0
- /package/dist/{token-normalizer-TEPOVBPV.js.map → token-normalizer-56H4242J.js.map} +0 -0
- /package/dist/{tokens-generate-5JQSJ27E.js.map → tokens-generate-EL6IN536.js.map} +0 -0
|
@@ -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-
|
|
84
|
+
} from "./chunk-77AAP6R6.js";
|
|
76
85
|
import "./chunk-D2CDBRNU.js";
|
|
77
86
|
import {
|
|
78
87
|
BRAND,
|
|
79
88
|
DEFAULTS
|
|
80
|
-
} from "./chunk-
|
|
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-SJFSG7QF.js";
|
|
92
90
|
import {
|
|
93
91
|
aggregateAllUsages,
|
|
94
92
|
aggregateComponentUsages,
|
|
@@ -217,4 +215,4 @@ export {
|
|
|
217
215
|
sleep,
|
|
218
216
|
summarizePatternsForPrompt
|
|
219
217
|
};
|
|
220
|
-
//# sourceMappingURL=service-
|
|
218
|
+
//# sourceMappingURL=service-VELQHEWV.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-
|
|
5
|
+
} from "./chunk-SJFSG7QF.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-
|
|
138
|
+
//# sourceMappingURL=snapshot-DT4B6DPR.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-
|
|
5
|
+
} from "./chunk-OZZ4SVZX.js";
|
|
6
6
|
import "./chunk-D2CDBRNU.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-SJFSG7QF.js";
|
|
8
8
|
export {
|
|
9
9
|
generateStaticViewer,
|
|
10
10
|
generateViewerFromJson
|
|
11
11
|
};
|
|
12
|
-
//# sourceMappingURL=static-viewer-
|
|
12
|
+
//# sourceMappingURL=static-viewer-E4OJWFDJ.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-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-XRADMHMV.js";
|
|
6
|
+
import "./chunk-SJFSG7QF.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-
|
|
1071
|
+
//# sourceMappingURL=test-QJY2QO4X.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-
|
|
4
|
+
} from "./chunk-SJFSG7QF.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-
|
|
312
|
+
//# sourceMappingURL=token-normalizer-56H4242J.js.map
|
|
@@ -1,15 +1,14 @@
|
|
|
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-
|
|
7
|
-
import {
|
|
8
|
-
BRAND
|
|
9
|
-
} from "./chunk-32LIWN2P.js";
|
|
4
|
+
} from "./chunk-XRADMHMV.js";
|
|
10
5
|
import {
|
|
11
6
|
parseTokenFiles
|
|
12
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-77AAP6R6.js";
|
|
8
|
+
import "./chunk-D2CDBRNU.js";
|
|
9
|
+
import {
|
|
10
|
+
BRAND
|
|
11
|
+
} from "./chunk-SJFSG7QF.js";
|
|
13
12
|
import "./chunk-QCN35LJU.js";
|
|
14
13
|
import "./chunk-7DZC4YEV.js";
|
|
15
14
|
|
|
@@ -173,4 +172,4 @@ export {
|
|
|
173
172
|
tokens_default as default,
|
|
174
173
|
tokens
|
|
175
174
|
};
|
|
176
|
-
//# sourceMappingURL=tokens-
|
|
175
|
+
//# sourceMappingURL=tokens-K6URXFPK.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-
|
|
8
|
+
} from "./chunk-SJFSG7QF.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-
|
|
85
|
+
//# sourceMappingURL=tokens-generate-EL6IN536.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fragments-sdk/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.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,12 +82,12 @@
|
|
|
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.
|
|
85
|
-
"@fragments-sdk/extract": "0.1.
|
|
86
|
-
"@fragments-sdk/
|
|
87
|
-
"@fragments-sdk/
|
|
85
|
+
"@fragments-sdk/compiler": "0.2.1",
|
|
86
|
+
"@fragments-sdk/extract": "0.1.1",
|
|
87
|
+
"@fragments-sdk/core": "2.1.0",
|
|
88
|
+
"@fragments-sdk/context": "0.6.1",
|
|
88
89
|
"@fragments-sdk/govern": "^0.3.1",
|
|
89
|
-
"@fragments-sdk/viewer": "0.2.
|
|
90
|
+
"@fragments-sdk/viewer": "0.2.10",
|
|
90
91
|
"@fragments-sdk/webmcp": "3.0.0"
|
|
91
92
|
},
|
|
92
93
|
"devDependencies": {
|
package/src/bin.ts
CHANGED
|
@@ -23,6 +23,10 @@ const EXPERIMENTAL = process.env.FRAGMENTS_EXPERIMENTAL === '1';
|
|
|
23
23
|
import { validate } from './commands/validate.js';
|
|
24
24
|
import { build } from './commands/build.js';
|
|
25
25
|
import { context } from './commands/context.js';
|
|
26
|
+
import {
|
|
27
|
+
contextInstallCloud,
|
|
28
|
+
contextStatusCloud,
|
|
29
|
+
} from './commands/context-cloud.js';
|
|
26
30
|
import { list } from './commands/list.js';
|
|
27
31
|
import { reset } from './commands/reset.js';
|
|
28
32
|
import { compare } from './commands/compare.js';
|
|
@@ -45,7 +49,7 @@ import { perf } from './commands/perf.js';
|
|
|
45
49
|
type DoctorFn = typeof import('./commands/doctor.js')['doctor'];
|
|
46
50
|
import { setup } from './commands/setup.js';
|
|
47
51
|
import { sync } from './commands/sync.js';
|
|
48
|
-
import { governCheck, governInit, governReport
|
|
52
|
+
import { governCheck, governInit, governReport } from './commands/govern.js';
|
|
49
53
|
import { migrateContract } from './commands/migrate-contract.js';
|
|
50
54
|
|
|
51
55
|
// Import existing commands that were already extracted
|
|
@@ -157,8 +161,8 @@ program
|
|
|
157
161
|
// CONTEXT COMMAND
|
|
158
162
|
// ============================================================================
|
|
159
163
|
program
|
|
160
|
-
.command('context')
|
|
161
|
-
.description('Generate AI-ready context
|
|
164
|
+
.command('context [action]')
|
|
165
|
+
.description('Generate AI-ready context or install a Fragments Cloud bundle')
|
|
162
166
|
.option('-c, --config <path>', 'Path to config file')
|
|
163
167
|
.option('-i, --input <path>', `Path to ${BRAND.outFile} (builds if not provided)`)
|
|
164
168
|
.option('-f, --format <format>', 'Output format (markdown/json)', 'markdown')
|
|
@@ -166,8 +170,47 @@ program
|
|
|
166
170
|
.option('--code', 'Include code examples')
|
|
167
171
|
.option('--relations', 'Include component relationships')
|
|
168
172
|
.option('--tokens', 'Only output token estimate')
|
|
169
|
-
.
|
|
173
|
+
.option('--cloud', 'Use Fragments Cloud bundle endpoints')
|
|
174
|
+
.option('--api-key <key>', 'Fragments Cloud API key (or use FRAGMENTS_API_KEY)')
|
|
175
|
+
.option('--targets <list>', 'Comma-separated helper targets (cursor,agents,claude,copilot)')
|
|
176
|
+
.option('--cwd <path>', 'Project root for install/status')
|
|
177
|
+
.option('--dry-run', 'Preview file writes without modifying the repo')
|
|
178
|
+
.option('-y, --yes', 'Non-interactive mode')
|
|
179
|
+
.option('--root-files <mode>', 'Root instruction file mode (prompt|never|patch)')
|
|
180
|
+
.option('--gitignore-fragments', 'Add .fragments/ to .gitignore after install')
|
|
181
|
+
.action(async (action, options) => {
|
|
170
182
|
try {
|
|
183
|
+
if (options.cloud && action === 'install') {
|
|
184
|
+
await contextInstallCloud({
|
|
185
|
+
apiKey: options.apiKey,
|
|
186
|
+
targets: options.targets,
|
|
187
|
+
cwd: options.cwd,
|
|
188
|
+
dryRun: options.dryRun,
|
|
189
|
+
yes: options.yes,
|
|
190
|
+
rootFiles: options.rootFiles,
|
|
191
|
+
gitignoreFragments: options.gitignoreFragments,
|
|
192
|
+
});
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (options.cloud && action === 'status') {
|
|
197
|
+
await contextStatusCloud({
|
|
198
|
+
apiKey: options.apiKey,
|
|
199
|
+
cwd: options.cwd,
|
|
200
|
+
});
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (action === 'install' || action === 'status') {
|
|
205
|
+
throw new Error(
|
|
206
|
+
`context ${action} requires --cloud`,
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (action && action !== 'install' && action !== 'status') {
|
|
211
|
+
throw new Error(`Unknown context action: ${action}`);
|
|
212
|
+
}
|
|
213
|
+
|
|
171
214
|
const result = await context({
|
|
172
215
|
config: options.config,
|
|
173
216
|
input: options.input,
|
|
@@ -885,35 +928,8 @@ const initCmd = program
|
|
|
885
928
|
.option('--api-key <key>', 'API key for AI enrichment')
|
|
886
929
|
.option('--model <model>', 'Override AI model for enrichment');
|
|
887
930
|
|
|
888
|
-
// Cloud governance flags — only visible with FRAGMENTS_EXPERIMENTAL=1
|
|
889
|
-
if (EXPERIMENTAL) {
|
|
890
|
-
initCmd
|
|
891
|
-
.option('--cloud', 'Set up Fragments Cloud governance (zero-config browser auth)')
|
|
892
|
-
.option('--cloud-url <url>', 'Cloud dashboard URL (default: https://app.usefragments.com)')
|
|
893
|
-
.option('--port <port>', 'Localhost port for auth callback (default: 9876)')
|
|
894
|
-
.option('--auth-only', 'Only authenticate, skip project setup')
|
|
895
|
-
.option('--skip-check', 'Skip running the first governance check');
|
|
896
|
-
}
|
|
897
|
-
|
|
898
931
|
initCmd.action(async (options) => {
|
|
899
932
|
try {
|
|
900
|
-
// Cloud init — experimental, requires FRAGMENTS_EXPERIMENTAL=1
|
|
901
|
-
if (options.cloud) {
|
|
902
|
-
if (!EXPERIMENTAL) {
|
|
903
|
-
console.log(pc.yellow(`\n Fragments Cloud is not yet publicly available.`));
|
|
904
|
-
console.log(pc.dim(` Set FRAGMENTS_EXPERIMENTAL=1 to enable preview features.\n`));
|
|
905
|
-
process.exit(1);
|
|
906
|
-
}
|
|
907
|
-
const { initCloud } = await import('./commands/init-cloud.js');
|
|
908
|
-
await initCloud({
|
|
909
|
-
url: options.cloudUrl,
|
|
910
|
-
port: options.port ? Number(options.port) : undefined,
|
|
911
|
-
authOnly: options.authOnly,
|
|
912
|
-
skipCheck: options.skipCheck,
|
|
913
|
-
});
|
|
914
|
-
return;
|
|
915
|
-
}
|
|
916
|
-
|
|
917
933
|
const { init } = await import('./commands/init.js');
|
|
918
934
|
const result = await init({
|
|
919
935
|
projectRoot: process.cwd(),
|
|
@@ -1036,28 +1052,6 @@ tokensCmd
|
|
|
1036
1052
|
}
|
|
1037
1053
|
});
|
|
1038
1054
|
|
|
1039
|
-
tokensCmd
|
|
1040
|
-
.command('push')
|
|
1041
|
-
.description('Push code tokens to Fragments Cloud for drift comparison')
|
|
1042
|
-
.option('-c, --config <path>', 'Path to fragments config file')
|
|
1043
|
-
.option('--tailwind-v4 <path>', 'Path to Tailwind v4 CSS file with @theme block')
|
|
1044
|
-
.option('--dry-run', 'Parse and display tokens without pushing')
|
|
1045
|
-
.option('--verbose', 'Show detailed output')
|
|
1046
|
-
.action(async (options) => {
|
|
1047
|
-
try {
|
|
1048
|
-
const { tokensPush } = await import('./commands/tokens-push.js');
|
|
1049
|
-
await tokensPush({
|
|
1050
|
-
config: options.config,
|
|
1051
|
-
tailwindV4: options.tailwindV4,
|
|
1052
|
-
dryRun: options.dryRun,
|
|
1053
|
-
verbose: options.verbose,
|
|
1054
|
-
});
|
|
1055
|
-
} catch (error) {
|
|
1056
|
-
console.error(pc.red('Error:'), error instanceof Error ? error.message : error);
|
|
1057
|
-
process.exit(1);
|
|
1058
|
-
}
|
|
1059
|
-
});
|
|
1060
|
-
|
|
1061
1055
|
// ============================================================================
|
|
1062
1056
|
// GENERATE COMMAND
|
|
1063
1057
|
// ============================================================================
|
|
@@ -1374,24 +1368,13 @@ governCmd
|
|
|
1374
1368
|
}
|
|
1375
1369
|
});
|
|
1376
1370
|
|
|
1377
|
-
governCmd
|
|
1378
|
-
.command('connect')
|
|
1379
|
-
.description('Connect your project to the Fragments Govern cloud dashboard')
|
|
1380
|
-
.action(async () => {
|
|
1381
|
-
try {
|
|
1382
|
-
await governConnect();
|
|
1383
|
-
} catch (error) {
|
|
1384
|
-
console.error(pc.red('Error:'), error instanceof Error ? error.message : error);
|
|
1385
|
-
process.exit(1);
|
|
1386
|
-
}
|
|
1387
|
-
});
|
|
1388
|
-
|
|
1389
1371
|
governCmd
|
|
1390
1372
|
.command('scan')
|
|
1391
1373
|
.description('Scan JSX/TSX codebase for governance violations')
|
|
1392
1374
|
.option('-d, --dir <path>', 'Root directory (default: auto-detect)')
|
|
1393
1375
|
.option('-c, --config <path>', 'Path to govern.config.ts')
|
|
1394
1376
|
.option('-f, --format <format>', 'Output format: summary, json, sarif', 'summary')
|
|
1377
|
+
.option('-r, --report <path>', 'Write an aggregated machine-readable JSON report')
|
|
1395
1378
|
.option('-q, --quiet', 'Suppress non-error output')
|
|
1396
1379
|
.action(async (options) => {
|
|
1397
1380
|
try {
|
|
@@ -1400,6 +1383,7 @@ governCmd
|
|
|
1400
1383
|
dir: options.dir,
|
|
1401
1384
|
config: options.config,
|
|
1402
1385
|
format: options.format,
|
|
1386
|
+
report: options.report,
|
|
1403
1387
|
quiet: options.quiet,
|
|
1404
1388
|
});
|
|
1405
1389
|
process.exit(exitCode);
|
|
@@ -1431,28 +1415,5 @@ governCmd
|
|
|
1431
1415
|
}
|
|
1432
1416
|
});
|
|
1433
1417
|
|
|
1434
|
-
governCmd
|
|
1435
|
-
.command('push-contracts')
|
|
1436
|
-
.description('Push component contracts to Fragments Cloud')
|
|
1437
|
-
.option('-i, --input <path>', 'Path to fragments.json (default: ./fragments.json)')
|
|
1438
|
-
.option('--url <url>', 'Fragments Cloud URL')
|
|
1439
|
-
.option('--api-key <key>', 'API key (default: FRAGMENTS_API_KEY env var)')
|
|
1440
|
-
.option('-q, --quiet', 'Suppress non-error output')
|
|
1441
|
-
.action(async (options) => {
|
|
1442
|
-
try {
|
|
1443
|
-
const { pushContracts } = await import('./commands/push-contracts.js');
|
|
1444
|
-
const { exitCode } = await pushContracts({
|
|
1445
|
-
input: options.input,
|
|
1446
|
-
url: options.url,
|
|
1447
|
-
apiKey: options.apiKey,
|
|
1448
|
-
quiet: options.quiet,
|
|
1449
|
-
});
|
|
1450
|
-
process.exit(exitCode);
|
|
1451
|
-
} catch (error) {
|
|
1452
|
-
console.error(pc.red('Error:'), error instanceof Error ? error.message : error);
|
|
1453
|
-
process.exit(1);
|
|
1454
|
-
}
|
|
1455
|
-
});
|
|
1456
|
-
|
|
1457
1418
|
// Parse command line arguments
|
|
1458
1419
|
program.parse();
|