@fragments-sdk/cli 0.12.1 → 0.13.1
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 +299 -61
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-AM4MRTMN.js → chunk-55KERLWL.js} +2 -2
- package/dist/{chunk-LVWFOLUZ.js → chunk-7K3VROEP.js} +2 -2
- package/dist/{chunk-JJ2VRTBU.js → chunk-EYXVAMEX.js} +2 -2
- package/dist/chunk-EYXVAMEX.js.map +1 -0
- package/dist/{chunk-GVDSFQ4E.js → chunk-FZLPVN32.js} +6 -6
- package/dist/{chunk-WFS63PCW.js → chunk-I34BC3CU.js} +45 -2
- package/dist/chunk-I34BC3CU.js.map +1 -0
- package/dist/{chunk-T5OMVL7E.js → chunk-PJT5IZ37.js} +2 -2
- package/dist/{chunk-4OC7FTJB.js → chunk-TXFCEDOC.js} +2 -2
- package/dist/{chunk-TPWGL2XS.js → chunk-Z5BUXIFJ.js} +5 -5
- package/dist/{chunk-OQKMEFOS.js → chunk-ZKTFKHWN.js} +2 -2
- package/dist/core/index.js +5 -1
- package/dist/{discovery-ZJQSXF56.js → discovery-VDANZAJ2.js} +3 -3
- package/dist/{generate-RJFS2JWA.js → generate-RYWIPDN2.js} +4 -4
- package/dist/index.js +7 -7
- package/dist/{init-ZSX3NRCZ.js → init-U6534EMZ.js} +5 -5
- package/dist/mcp-bin.js +2 -2
- package/dist/{scan-3PMCJ4RB.js → scan-LE2JEIJ4.js} +6 -6
- package/dist/{scan-generate-SYU4PYZD.js → scan-generate-TFZVL3BT.js} +5 -5
- package/dist/{service-VMGNJZ42.js → service-S5LXPKV4.js} +3 -3
- package/dist/{snapshot-XOISO2IS.js → snapshot-C5DYIGIV.js} +2 -2
- package/dist/{static-viewer-5GXH2MGE.js → static-viewer-DUVC4UIM.js} +3 -3
- package/dist/{test-SI4NSHQX.js → test-JW7JIDFG.js} +4 -4
- package/dist/{tokens-T6SIVUT5.js → tokens-OPVTVITP.js} +5 -5
- package/dist/{viewer-7ZEAFBVN.js → viewer-OBTEPVY7.js} +14 -14
- package/dist/viewer-OBTEPVY7.js.map +1 -0
- package/package.json +11 -9
- package/src/bin.ts +67 -0
- package/src/commands/govern.ts +279 -0
- package/src/core/component-extractor.ts +1 -1
- package/src/viewer/vite-plugin.ts +1 -1
- package/dist/chunk-JJ2VRTBU.js.map +0 -1
- package/dist/chunk-WFS63PCW.js.map +0 -1
- package/dist/viewer-7ZEAFBVN.js.map +0 -1
- /package/dist/{chunk-AM4MRTMN.js.map → chunk-55KERLWL.js.map} +0 -0
- /package/dist/{chunk-LVWFOLUZ.js.map → chunk-7K3VROEP.js.map} +0 -0
- /package/dist/{chunk-GVDSFQ4E.js.map → chunk-FZLPVN32.js.map} +0 -0
- /package/dist/{chunk-T5OMVL7E.js.map → chunk-PJT5IZ37.js.map} +0 -0
- /package/dist/{chunk-4OC7FTJB.js.map → chunk-TXFCEDOC.js.map} +0 -0
- /package/dist/{chunk-TPWGL2XS.js.map → chunk-Z5BUXIFJ.js.map} +0 -0
- /package/dist/{chunk-OQKMEFOS.js.map → chunk-ZKTFKHWN.js.map} +0 -0
- /package/dist/{discovery-ZJQSXF56.js.map → discovery-VDANZAJ2.js.map} +0 -0
- /package/dist/{generate-RJFS2JWA.js.map → generate-RYWIPDN2.js.map} +0 -0
- /package/dist/{init-ZSX3NRCZ.js.map → init-U6534EMZ.js.map} +0 -0
- /package/dist/{scan-3PMCJ4RB.js.map → scan-LE2JEIJ4.js.map} +0 -0
- /package/dist/{scan-generate-SYU4PYZD.js.map → scan-generate-TFZVL3BT.js.map} +0 -0
- /package/dist/{service-VMGNJZ42.js.map → service-S5LXPKV4.js.map} +0 -0
- /package/dist/{snapshot-XOISO2IS.js.map → snapshot-C5DYIGIV.js.map} +0 -0
- /package/dist/{static-viewer-5GXH2MGE.js.map → static-viewer-DUVC4UIM.js.map} +0 -0
- /package/dist/{test-SI4NSHQX.js.map → test-JW7JIDFG.js.map} +0 -0
- /package/dist/{tokens-T6SIVUT5.js.map → tokens-OPVTVITP.js.map} +0 -0
package/dist/bin.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-SXTKFDCR.js";
|
|
8
8
|
import {
|
|
9
9
|
setup
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-PJT5IZ37.js";
|
|
11
11
|
import {
|
|
12
12
|
buildFragments,
|
|
13
13
|
buildFragmentsDir,
|
|
@@ -22,21 +22,21 @@ import {
|
|
|
22
22
|
validateDrift,
|
|
23
23
|
validateSchema,
|
|
24
24
|
validateSnippets
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-FZLPVN32.js";
|
|
26
26
|
import {
|
|
27
27
|
createComponentExtractor
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-EYXVAMEX.js";
|
|
29
29
|
import {
|
|
30
30
|
scan
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-Z5BUXIFJ.js";
|
|
32
32
|
import {
|
|
33
33
|
loadConfig,
|
|
34
34
|
loadFragmentFile,
|
|
35
35
|
parseFragmentFile
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-55KERLWL.js";
|
|
37
37
|
import {
|
|
38
38
|
discoverFragmentFiles
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-ZKTFKHWN.js";
|
|
40
40
|
import {
|
|
41
41
|
FigmaClient,
|
|
42
42
|
StorageManager,
|
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
renderAllComponentVariants,
|
|
53
53
|
scanCodebase,
|
|
54
54
|
shutdownSharedPool
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-7K3VROEP.js";
|
|
56
56
|
import "./chunk-D2CDBRNU.js";
|
|
57
57
|
import {
|
|
58
58
|
BRAND,
|
|
@@ -60,12 +60,12 @@ import {
|
|
|
60
60
|
formatBytes,
|
|
61
61
|
generateContext,
|
|
62
62
|
resolvePerformanceConfig
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-I34BC3CU.js";
|
|
64
64
|
import "./chunk-Z7EY4VHE.js";
|
|
65
65
|
|
|
66
66
|
// src/bin.ts
|
|
67
67
|
import { Command } from "commander";
|
|
68
|
-
import
|
|
68
|
+
import pc25 from "picocolors";
|
|
69
69
|
import { readFileSync } from "fs";
|
|
70
70
|
import { fileURLToPath } from "url";
|
|
71
71
|
import { dirname as dirname4, join as join11 } from "path";
|
|
@@ -1901,7 +1901,7 @@ ${BRAND.name} Dev Server
|
|
|
1901
1901
|
}
|
|
1902
1902
|
}
|
|
1903
1903
|
}
|
|
1904
|
-
const { createDevServer } = await import("./viewer-
|
|
1904
|
+
const { createDevServer } = await import("./viewer-OBTEPVY7.js");
|
|
1905
1905
|
console.log(pc7.dim("\nStarting dev server..."));
|
|
1906
1906
|
const parsedPort = typeof port === "string" ? parseInt(port, 10) : port;
|
|
1907
1907
|
try {
|
|
@@ -6023,6 +6023,205 @@ function escapeRegex(str) {
|
|
|
6023
6023
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6024
6024
|
}
|
|
6025
6025
|
|
|
6026
|
+
// src/commands/govern.ts
|
|
6027
|
+
import pc24 from "picocolors";
|
|
6028
|
+
async function governCheck(options = {}) {
|
|
6029
|
+
console.log(pc24.cyan(`
|
|
6030
|
+
${BRAND.name} Governance Check
|
|
6031
|
+
`));
|
|
6032
|
+
const { cliCheck, formatVerdict } = await import("@fragments-sdk/govern");
|
|
6033
|
+
const result = await cliCheck(options);
|
|
6034
|
+
const output = formatVerdict(result.verdict, options.format ?? "summary");
|
|
6035
|
+
if (!options.quiet) {
|
|
6036
|
+
console.log(output);
|
|
6037
|
+
console.log();
|
|
6038
|
+
}
|
|
6039
|
+
if (result.verdict.passed) {
|
|
6040
|
+
console.log(pc24.green(`\u2713 Governance check passed (score: ${result.verdict.score}/100)
|
|
6041
|
+
`));
|
|
6042
|
+
} else {
|
|
6043
|
+
console.log(pc24.red(`\u2717 Governance check failed (score: ${result.verdict.score}/100)
|
|
6044
|
+
`));
|
|
6045
|
+
}
|
|
6046
|
+
return { exitCode: result.exitCode };
|
|
6047
|
+
}
|
|
6048
|
+
async function governInit(options = {}) {
|
|
6049
|
+
const { writeFile: writeFile10 } = await import("fs/promises");
|
|
6050
|
+
const { resolve: resolve9 } = await import("path");
|
|
6051
|
+
const { generateConfigTemplate } = await import("@fragments-sdk/govern");
|
|
6052
|
+
const outputPath = resolve9(options.output ?? "fragments.config.ts");
|
|
6053
|
+
const template = generateConfigTemplate();
|
|
6054
|
+
await writeFile10(outputPath, template, "utf-8");
|
|
6055
|
+
console.log(pc24.green(`\u2713 Created ${outputPath}
|
|
6056
|
+
`));
|
|
6057
|
+
}
|
|
6058
|
+
async function governConnect() {
|
|
6059
|
+
const { readFile: readFile10, writeFile: writeFile10, appendFile } = await import("fs/promises");
|
|
6060
|
+
const { existsSync: existsSync2 } = await import("fs");
|
|
6061
|
+
const { resolve: resolve9 } = await import("path");
|
|
6062
|
+
const { platform } = await import("os");
|
|
6063
|
+
const { exec } = await import("child_process");
|
|
6064
|
+
const { password, confirm } = await import("@inquirer/prompts");
|
|
6065
|
+
const cloudUrl = process.env.FRAGMENTS_URL ?? "https://app.usefragments.com";
|
|
6066
|
+
console.log(pc24.cyan(`
|
|
6067
|
+
${BRAND.name} \u2014 Connect to Cloud
|
|
6068
|
+
`));
|
|
6069
|
+
console.log(
|
|
6070
|
+
pc24.dim(" This will connect your project to the Fragments dashboard\n") + pc24.dim(" for centralized audit tracking and team visibility.\n")
|
|
6071
|
+
);
|
|
6072
|
+
console.log(pc24.bold(" Step 1 of 3: Get your API key\n"));
|
|
6073
|
+
const dashboardUrl = `${cloudUrl}/dashboard/settings`;
|
|
6074
|
+
console.log(pc24.dim(` \u2192 Opening the dashboard in your browser...`));
|
|
6075
|
+
console.log(pc24.dim(` Copy your API key from Settings \u2192 API Keys
|
|
6076
|
+
`));
|
|
6077
|
+
const os = platform();
|
|
6078
|
+
const openCmd = os === "darwin" ? `open "${dashboardUrl}"` : os === "win32" ? `start "" "${dashboardUrl}"` : `xdg-open "${dashboardUrl}"`;
|
|
6079
|
+
exec(openCmd);
|
|
6080
|
+
let apiKey;
|
|
6081
|
+
let orgName;
|
|
6082
|
+
while (true) {
|
|
6083
|
+
apiKey = await password({
|
|
6084
|
+
message: "Paste your API key:",
|
|
6085
|
+
mask: "*"
|
|
6086
|
+
});
|
|
6087
|
+
if (!apiKey.trim()) {
|
|
6088
|
+
console.log(pc24.yellow("\n API key cannot be empty. Please try again.\n"));
|
|
6089
|
+
continue;
|
|
6090
|
+
}
|
|
6091
|
+
console.log(pc24.dim("\n Verifying..."));
|
|
6092
|
+
try {
|
|
6093
|
+
const response = await fetch(`${cloudUrl}/api/verify`, {
|
|
6094
|
+
headers: { Authorization: `Bearer ${apiKey.trim()}` }
|
|
6095
|
+
});
|
|
6096
|
+
if (!response.ok) {
|
|
6097
|
+
console.log(pc24.red(`
|
|
6098
|
+
\u2717 Invalid API key (HTTP ${response.status}). Please try again.
|
|
6099
|
+
`));
|
|
6100
|
+
continue;
|
|
6101
|
+
}
|
|
6102
|
+
const data = await response.json();
|
|
6103
|
+
if (!data.valid) {
|
|
6104
|
+
console.log(pc24.red("\n \u2717 API key not recognized. Please try again.\n"));
|
|
6105
|
+
continue;
|
|
6106
|
+
}
|
|
6107
|
+
orgName = data.orgName ?? "your organization";
|
|
6108
|
+
console.log(pc24.green(`
|
|
6109
|
+
\u2713 Connected to "${orgName}" (verified)
|
|
6110
|
+
`));
|
|
6111
|
+
break;
|
|
6112
|
+
} catch (error) {
|
|
6113
|
+
console.log(
|
|
6114
|
+
pc24.red("\n \u2717 Could not reach the dashboard.")
|
|
6115
|
+
);
|
|
6116
|
+
console.log(
|
|
6117
|
+
pc24.dim(` ${error instanceof Error ? error.message : "Network error"}
|
|
6118
|
+
`)
|
|
6119
|
+
);
|
|
6120
|
+
continue;
|
|
6121
|
+
}
|
|
6122
|
+
}
|
|
6123
|
+
console.log(pc24.bold(" Step 2 of 3: Save configuration\n"));
|
|
6124
|
+
const saveToEnv = await confirm({
|
|
6125
|
+
message: "Save API key to .env file?",
|
|
6126
|
+
default: true
|
|
6127
|
+
});
|
|
6128
|
+
if (saveToEnv) {
|
|
6129
|
+
const envPath = resolve9(".env");
|
|
6130
|
+
const envEntry = `FRAGMENTS_API_KEY=${apiKey.trim()}`;
|
|
6131
|
+
if (existsSync2(envPath)) {
|
|
6132
|
+
const envContent = await readFile10(envPath, "utf-8");
|
|
6133
|
+
if (envContent.includes("FRAGMENTS_API_KEY=")) {
|
|
6134
|
+
const updated = envContent.replace(
|
|
6135
|
+
/^FRAGMENTS_API_KEY=.*$/m,
|
|
6136
|
+
envEntry
|
|
6137
|
+
);
|
|
6138
|
+
await writeFile10(envPath, updated, "utf-8");
|
|
6139
|
+
console.log(pc24.green(" \u2713 Updated FRAGMENTS_API_KEY in .env"));
|
|
6140
|
+
} else {
|
|
6141
|
+
await appendFile(envPath, `
|
|
6142
|
+
${envEntry}
|
|
6143
|
+
`, "utf-8");
|
|
6144
|
+
console.log(pc24.green(" \u2713 Added FRAGMENTS_API_KEY to .env"));
|
|
6145
|
+
}
|
|
6146
|
+
} else {
|
|
6147
|
+
await writeFile10(envPath, `${envEntry}
|
|
6148
|
+
`, "utf-8");
|
|
6149
|
+
console.log(pc24.green(" \u2713 Created .env with FRAGMENTS_API_KEY"));
|
|
6150
|
+
}
|
|
6151
|
+
if (cloudUrl !== "https://app.usefragments.com") {
|
|
6152
|
+
const envContent = await readFile10(envPath, "utf-8");
|
|
6153
|
+
if (!envContent.includes("FRAGMENTS_URL=")) {
|
|
6154
|
+
await appendFile(envPath, `FRAGMENTS_URL=${cloudUrl}
|
|
6155
|
+
`, "utf-8");
|
|
6156
|
+
console.log(pc24.green(` \u2713 Added FRAGMENTS_URL to .env`));
|
|
6157
|
+
}
|
|
6158
|
+
}
|
|
6159
|
+
const gitignorePath = resolve9(".gitignore");
|
|
6160
|
+
if (existsSync2(gitignorePath)) {
|
|
6161
|
+
const gitignore = await readFile10(gitignorePath, "utf-8");
|
|
6162
|
+
if (!gitignore.split("\n").some((line) => line.trim() === ".env")) {
|
|
6163
|
+
await appendFile(gitignorePath, "\n.env\n", "utf-8");
|
|
6164
|
+
console.log(pc24.green(" \u2713 Added .env to .gitignore"));
|
|
6165
|
+
}
|
|
6166
|
+
} else {
|
|
6167
|
+
await writeFile10(gitignorePath, ".env\n", "utf-8");
|
|
6168
|
+
console.log(pc24.green(" \u2713 Created .gitignore with .env entry"));
|
|
6169
|
+
}
|
|
6170
|
+
}
|
|
6171
|
+
console.log(pc24.bold("\n Step 3 of 3: Config check\n"));
|
|
6172
|
+
const { findGovernConfig } = await import("@fragments-sdk/govern");
|
|
6173
|
+
const configPath = findGovernConfig();
|
|
6174
|
+
if (configPath) {
|
|
6175
|
+
console.log(pc24.green(` \u2713 Found govern config: ${configPath}`));
|
|
6176
|
+
} else {
|
|
6177
|
+
console.log(
|
|
6178
|
+
pc24.yellow(" No govern config found \u2014 run `fragments govern init` to create one")
|
|
6179
|
+
);
|
|
6180
|
+
}
|
|
6181
|
+
console.log(pc24.dim("\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n"));
|
|
6182
|
+
console.log(pc24.green(" \u2713 All set!") + " Run `fragments govern check` to send your first audit.\n");
|
|
6183
|
+
console.log(pc24.dim(` Dashboard: ${cloudUrl}/dashboard
|
|
6184
|
+
`));
|
|
6185
|
+
}
|
|
6186
|
+
async function governReport() {
|
|
6187
|
+
const { readFile: readFile10 } = await import("fs/promises");
|
|
6188
|
+
console.log(pc24.cyan(`
|
|
6189
|
+
${BRAND.name} Governance Report
|
|
6190
|
+
`));
|
|
6191
|
+
let raw;
|
|
6192
|
+
try {
|
|
6193
|
+
raw = await readFile10(".govern-audit.jsonl", "utf-8");
|
|
6194
|
+
} catch {
|
|
6195
|
+
console.log(pc24.yellow("No audit log found (.govern-audit.jsonl)\n"));
|
|
6196
|
+
console.log(pc24.dim("Run `fragments govern check` to generate audit data.\n"));
|
|
6197
|
+
return;
|
|
6198
|
+
}
|
|
6199
|
+
const lines = raw.trim().split("\n").filter(Boolean);
|
|
6200
|
+
if (lines.length === 0) {
|
|
6201
|
+
console.log(pc24.yellow("Audit log is empty.\n"));
|
|
6202
|
+
return;
|
|
6203
|
+
}
|
|
6204
|
+
let totalScore = 0;
|
|
6205
|
+
let passCount = 0;
|
|
6206
|
+
let totalViolations = 0;
|
|
6207
|
+
for (const line of lines) {
|
|
6208
|
+
try {
|
|
6209
|
+
const entry = JSON.parse(line);
|
|
6210
|
+
totalScore += entry.score ?? 0;
|
|
6211
|
+
if (entry.passed) passCount++;
|
|
6212
|
+
totalViolations += entry.violationCount ?? 0;
|
|
6213
|
+
} catch {
|
|
6214
|
+
}
|
|
6215
|
+
}
|
|
6216
|
+
const avgScore = Math.round(totalScore / lines.length);
|
|
6217
|
+
const passRate = Math.round(passCount / lines.length * 100);
|
|
6218
|
+
console.log(` Checks: ${lines.length}`);
|
|
6219
|
+
console.log(` Pass rate: ${passRate}%`);
|
|
6220
|
+
console.log(` Avg score: ${avgScore}/100`);
|
|
6221
|
+
console.log(` Violations: ${totalViolations} total`);
|
|
6222
|
+
console.log();
|
|
6223
|
+
}
|
|
6224
|
+
|
|
6026
6225
|
// src/bin.ts
|
|
6027
6226
|
var __dirname = dirname4(fileURLToPath(import.meta.url));
|
|
6028
6227
|
var pkg = JSON.parse(readFileSync(join11(__dirname, "../package.json"), "utf-8"));
|
|
@@ -6035,7 +6234,7 @@ program.command("validate").description("Validate fragment files").option("-c, -
|
|
|
6035
6234
|
process.exit(1);
|
|
6036
6235
|
}
|
|
6037
6236
|
} catch (error) {
|
|
6038
|
-
console.error(
|
|
6237
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6039
6238
|
process.exit(1);
|
|
6040
6239
|
}
|
|
6041
6240
|
});
|
|
@@ -6051,7 +6250,7 @@ program.command("sync").description("Auto-update fragment files from component s
|
|
|
6051
6250
|
process.exit(1);
|
|
6052
6251
|
}
|
|
6053
6252
|
} catch (error) {
|
|
6054
|
-
console.error(
|
|
6253
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6055
6254
|
process.exit(1);
|
|
6056
6255
|
}
|
|
6057
6256
|
});
|
|
@@ -6071,7 +6270,7 @@ program.command("build").description(`Build compiled ${BRAND.outFile} and ${BRAN
|
|
|
6071
6270
|
process.exit(1);
|
|
6072
6271
|
}
|
|
6073
6272
|
} catch (error) {
|
|
6074
|
-
console.error(
|
|
6273
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6075
6274
|
process.exit(1);
|
|
6076
6275
|
}
|
|
6077
6276
|
});
|
|
@@ -6090,7 +6289,7 @@ program.command("context").description("Generate AI-ready context for your desig
|
|
|
6090
6289
|
process.exit(1);
|
|
6091
6290
|
}
|
|
6092
6291
|
} catch (error) {
|
|
6093
|
-
console.error(
|
|
6292
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6094
6293
|
process.exit(1);
|
|
6095
6294
|
}
|
|
6096
6295
|
});
|
|
@@ -6117,7 +6316,7 @@ program.command("ai").description("Generate context optimized for AI assistants
|
|
|
6117
6316
|
}
|
|
6118
6317
|
}
|
|
6119
6318
|
} catch (error) {
|
|
6120
|
-
console.error(
|
|
6319
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6121
6320
|
process.exit(1);
|
|
6122
6321
|
}
|
|
6123
6322
|
});
|
|
@@ -6125,7 +6324,7 @@ program.command("list").description("List all discovered fragment files").option
|
|
|
6125
6324
|
try {
|
|
6126
6325
|
await list(options);
|
|
6127
6326
|
} catch (error) {
|
|
6128
|
-
console.error(
|
|
6327
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6129
6328
|
process.exit(1);
|
|
6130
6329
|
}
|
|
6131
6330
|
});
|
|
@@ -6133,7 +6332,7 @@ program.command("reset").description("Reset to initial state (delete all generat
|
|
|
6133
6332
|
try {
|
|
6134
6333
|
await reset(options);
|
|
6135
6334
|
} catch (error) {
|
|
6136
|
-
console.error(
|
|
6335
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6137
6336
|
process.exit(1);
|
|
6138
6337
|
}
|
|
6139
6338
|
});
|
|
@@ -6147,7 +6346,7 @@ linkCommand.command("figma").argument("[figma-url]", "Figma file URL to link com
|
|
|
6147
6346
|
variants: options.variants
|
|
6148
6347
|
});
|
|
6149
6348
|
} catch (error) {
|
|
6150
|
-
console.error(
|
|
6349
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6151
6350
|
process.exit(1);
|
|
6152
6351
|
}
|
|
6153
6352
|
});
|
|
@@ -6162,7 +6361,7 @@ linkCommand.command("storybook").description("Bootstrap fragments from existing
|
|
|
6162
6361
|
exclude: options.exclude
|
|
6163
6362
|
});
|
|
6164
6363
|
} catch (error) {
|
|
6165
|
-
console.error(
|
|
6364
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6166
6365
|
process.exit(1);
|
|
6167
6366
|
}
|
|
6168
6367
|
});
|
|
@@ -6177,9 +6376,9 @@ program.command("dev").description("Start the development server with live compo
|
|
|
6177
6376
|
skipBuild: options.skipBuild
|
|
6178
6377
|
});
|
|
6179
6378
|
} catch (error) {
|
|
6180
|
-
console.error(
|
|
6379
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6181
6380
|
if (error instanceof Error && error.stack) {
|
|
6182
|
-
console.error(
|
|
6381
|
+
console.error(pc25.dim(error.stack));
|
|
6183
6382
|
}
|
|
6184
6383
|
process.exit(1);
|
|
6185
6384
|
}
|
|
@@ -6200,7 +6399,7 @@ program.command("screenshot").description("Capture screenshots of component vari
|
|
|
6200
6399
|
process.exit(1);
|
|
6201
6400
|
}
|
|
6202
6401
|
} catch (error) {
|
|
6203
|
-
console.error(
|
|
6402
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6204
6403
|
process.exit(1);
|
|
6205
6404
|
}
|
|
6206
6405
|
});
|
|
@@ -6219,7 +6418,7 @@ program.command("diff").argument("[component]", "Component name to diff (optiona
|
|
|
6219
6418
|
process.exit(1);
|
|
6220
6419
|
}
|
|
6221
6420
|
} catch (error) {
|
|
6222
|
-
console.error(
|
|
6421
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6223
6422
|
process.exit(1);
|
|
6224
6423
|
}
|
|
6225
6424
|
});
|
|
@@ -6238,8 +6437,8 @@ program.command("compare").argument("[component]", "Component name to compare").
|
|
|
6238
6437
|
process.exit(1);
|
|
6239
6438
|
}
|
|
6240
6439
|
} catch (error) {
|
|
6241
|
-
console.error(
|
|
6242
|
-
console.log(
|
|
6440
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6441
|
+
console.log(pc25.dim(`
|
|
6243
6442
|
Make sure the dev server is running: ${BRAND.cliCommand} dev`));
|
|
6244
6443
|
process.exit(1);
|
|
6245
6444
|
}
|
|
@@ -6258,7 +6457,7 @@ program.command("analyze").description("Analyze design system and generate repor
|
|
|
6258
6457
|
process.exit(1);
|
|
6259
6458
|
}
|
|
6260
6459
|
} catch (error) {
|
|
6261
|
-
console.error(
|
|
6460
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6262
6461
|
process.exit(1);
|
|
6263
6462
|
}
|
|
6264
6463
|
});
|
|
@@ -6277,7 +6476,7 @@ program.command("verify").argument("[component]", "Component name to verify (opt
|
|
|
6277
6476
|
if (options.ci) {
|
|
6278
6477
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Verification failed" }));
|
|
6279
6478
|
} else {
|
|
6280
|
-
console.error(
|
|
6479
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6281
6480
|
}
|
|
6282
6481
|
process.exit(1);
|
|
6283
6482
|
}
|
|
@@ -6294,7 +6493,7 @@ program.command("audit").description("Scan all fragments and show compliance met
|
|
|
6294
6493
|
if (options.json) {
|
|
6295
6494
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Audit failed" }));
|
|
6296
6495
|
} else {
|
|
6297
|
-
console.error(
|
|
6496
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6298
6497
|
}
|
|
6299
6498
|
process.exit(1);
|
|
6300
6499
|
}
|
|
@@ -6316,7 +6515,7 @@ program.command("a11y").description("Run accessibility checks on all component v
|
|
|
6316
6515
|
if (options.json) {
|
|
6317
6516
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "A11y check failed" }));
|
|
6318
6517
|
} else {
|
|
6319
|
-
console.error(
|
|
6518
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6320
6519
|
}
|
|
6321
6520
|
process.exit(1);
|
|
6322
6521
|
}
|
|
@@ -6339,7 +6538,7 @@ program.command("enhance").description("AI-powered documentation generation from
|
|
|
6339
6538
|
if (options.format === "json") {
|
|
6340
6539
|
console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : "Enhance failed" }));
|
|
6341
6540
|
} else {
|
|
6342
|
-
console.error(
|
|
6541
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6343
6542
|
}
|
|
6344
6543
|
process.exit(1);
|
|
6345
6544
|
}
|
|
@@ -6360,7 +6559,7 @@ program.command("scan").description(`Zero-config ${BRAND.outFile} generation fro
|
|
|
6360
6559
|
process.exit(1);
|
|
6361
6560
|
}
|
|
6362
6561
|
} catch (error) {
|
|
6363
|
-
console.error(
|
|
6562
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6364
6563
|
process.exit(1);
|
|
6365
6564
|
}
|
|
6366
6565
|
});
|
|
@@ -6373,7 +6572,7 @@ program.command("storygen").description("Generate Storybook stories from fragmen
|
|
|
6373
6572
|
format: options.format
|
|
6374
6573
|
});
|
|
6375
6574
|
} catch (error) {
|
|
6376
|
-
console.error(
|
|
6575
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6377
6576
|
process.exit(1);
|
|
6378
6577
|
}
|
|
6379
6578
|
});
|
|
@@ -6385,7 +6584,7 @@ program.command("metrics").argument("[component]", "Component name (optional, sh
|
|
|
6385
6584
|
json: options.json
|
|
6386
6585
|
});
|
|
6387
6586
|
} catch (error) {
|
|
6388
|
-
console.error(
|
|
6587
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6389
6588
|
process.exit(1);
|
|
6390
6589
|
}
|
|
6391
6590
|
});
|
|
@@ -6399,9 +6598,9 @@ program.command("baseline").description("Manage visual regression baselines").ar
|
|
|
6399
6598
|
port: options.port
|
|
6400
6599
|
});
|
|
6401
6600
|
} catch (error) {
|
|
6402
|
-
console.error(
|
|
6601
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6403
6602
|
if (action === "update") {
|
|
6404
|
-
console.log(
|
|
6603
|
+
console.log(pc25.dim(`
|
|
6405
6604
|
Make sure the dev server is running: ${BRAND.cliCommand} dev`));
|
|
6406
6605
|
}
|
|
6407
6606
|
process.exit(1);
|
|
@@ -6409,27 +6608,27 @@ Make sure the dev server is running: ${BRAND.cliCommand} dev`));
|
|
|
6409
6608
|
});
|
|
6410
6609
|
program.command("view").description(`Generate a static HTML viewer for ${BRAND.outFile}`).option("-i, --input <path>", `Path to ${BRAND.outFile}`, BRAND.outFile).option("-o, --output <path>", "Output HTML file path", BRAND.viewerHtmlFile).option("--open", "Open in browser after generation").action(async (options) => {
|
|
6411
6610
|
try {
|
|
6412
|
-
const { generateViewerFromJson } = await import("./static-viewer-
|
|
6611
|
+
const { generateViewerFromJson } = await import("./static-viewer-DUVC4UIM.js");
|
|
6413
6612
|
const fs2 = await import("fs/promises");
|
|
6414
6613
|
const path = await import("path");
|
|
6415
6614
|
const inputPath = path.resolve(process.cwd(), options.input);
|
|
6416
6615
|
const outputPath = path.resolve(process.cwd(), options.output);
|
|
6417
|
-
console.log(
|
|
6616
|
+
console.log(pc25.cyan(`
|
|
6418
6617
|
${BRAND.name} Viewer Generator
|
|
6419
6618
|
`));
|
|
6420
6619
|
try {
|
|
6421
6620
|
await fs2.access(inputPath);
|
|
6422
6621
|
} catch {
|
|
6423
|
-
console.log(
|
|
6424
|
-
console.log(
|
|
6425
|
-
Run ${
|
|
6622
|
+
console.log(pc25.red(`Error: ${options.input} not found.`));
|
|
6623
|
+
console.log(pc25.dim(`
|
|
6624
|
+
Run ${pc25.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
|
|
6426
6625
|
`));
|
|
6427
6626
|
process.exit(1);
|
|
6428
6627
|
}
|
|
6429
|
-
console.log(
|
|
6628
|
+
console.log(pc25.dim(`Reading: ${options.input}`));
|
|
6430
6629
|
const html = await generateViewerFromJson(inputPath);
|
|
6431
6630
|
await fs2.writeFile(outputPath, html);
|
|
6432
|
-
console.log(
|
|
6631
|
+
console.log(pc25.green(`
|
|
6433
6632
|
\u2713 Generated: ${options.output}
|
|
6434
6633
|
`));
|
|
6435
6634
|
if (options.open) {
|
|
@@ -6438,7 +6637,7 @@ Run ${pc24.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
|
|
|
6438
6637
|
exec(`${openCmd} "${outputPath}"`);
|
|
6439
6638
|
}
|
|
6440
6639
|
} catch (error) {
|
|
6441
|
-
console.error(
|
|
6640
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6442
6641
|
process.exit(1);
|
|
6443
6642
|
}
|
|
6444
6643
|
});
|
|
@@ -6451,7 +6650,7 @@ program.command("add").argument("[name]", 'Component name (e.g., "Button", "Text
|
|
|
6451
6650
|
component: options.component
|
|
6452
6651
|
});
|
|
6453
6652
|
} catch (error) {
|
|
6454
|
-
console.error(
|
|
6653
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6455
6654
|
process.exit(1);
|
|
6456
6655
|
}
|
|
6457
6656
|
});
|
|
@@ -6468,13 +6667,13 @@ program.command("setup").description("Configure @fragments-sdk/ui in a consumer
|
|
|
6468
6667
|
process.exit(1);
|
|
6469
6668
|
}
|
|
6470
6669
|
} catch (error) {
|
|
6471
|
-
console.error(
|
|
6670
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6472
6671
|
process.exit(1);
|
|
6473
6672
|
}
|
|
6474
6673
|
});
|
|
6475
6674
|
program.command("init").description("Initialize fragments in a project (zero-config by default)").option("--force", "Overwrite existing config").option("-y, --yes", "Non-interactive mode (now the default)").option("--configure", "Interactive mode for theme seeds, snapshots, etc.").option("--scan <path>", "Scan a TypeScript component directory and generate fragment files").option("--enrich", "Use AI to fill knowledge fields during --scan (requires API key)").option("--dry-run", "Show what --enrich would generate without calling API").option("--provider <provider>", "AI provider for enrichment: anthropic or openai").option("--api-key <key>", "API key for AI enrichment").option("--model <model>", "Override AI model for enrichment").action(async (options) => {
|
|
6476
6675
|
try {
|
|
6477
|
-
const { init } = await import("./init-
|
|
6676
|
+
const { init } = await import("./init-U6534EMZ.js");
|
|
6478
6677
|
const result = await init({
|
|
6479
6678
|
projectRoot: process.cwd(),
|
|
6480
6679
|
force: options.force,
|
|
@@ -6488,20 +6687,20 @@ program.command("init").description("Initialize fragments in a project (zero-con
|
|
|
6488
6687
|
model: options.model
|
|
6489
6688
|
});
|
|
6490
6689
|
if (!result.success) {
|
|
6491
|
-
console.error(
|
|
6690
|
+
console.error(pc25.red("\nInit failed with errors:"));
|
|
6492
6691
|
for (const error of result.errors) {
|
|
6493
|
-
console.error(
|
|
6692
|
+
console.error(pc25.red(` - ${error}`));
|
|
6494
6693
|
}
|
|
6495
6694
|
process.exit(1);
|
|
6496
6695
|
}
|
|
6497
6696
|
} catch (error) {
|
|
6498
|
-
console.error(
|
|
6697
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6499
6698
|
process.exit(1);
|
|
6500
6699
|
}
|
|
6501
6700
|
});
|
|
6502
6701
|
program.command("snapshot").description("Run visual snapshot tests per component variant").option("-p, --port <port>", "Port of running dev server (skips starting one)").option("--update", "Update existing snapshots instead of comparing").option("--component <name>", "Filter to a specific component").option("--spec <path>", "Path to snapshot spec file").option("--ci", "CI mode - exit 1 on mismatch").action(async (options) => {
|
|
6503
6702
|
try {
|
|
6504
|
-
const { snapshot } = await import("./snapshot-
|
|
6703
|
+
const { snapshot } = await import("./snapshot-C5DYIGIV.js");
|
|
6505
6704
|
const result = await snapshot({
|
|
6506
6705
|
port: options.port,
|
|
6507
6706
|
update: options.update,
|
|
@@ -6513,13 +6712,13 @@ program.command("snapshot").description("Run visual snapshot tests per component
|
|
|
6513
6712
|
process.exit(1);
|
|
6514
6713
|
}
|
|
6515
6714
|
} catch (error) {
|
|
6516
|
-
console.error(
|
|
6715
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6517
6716
|
process.exit(1);
|
|
6518
6717
|
}
|
|
6519
6718
|
});
|
|
6520
6719
|
program.command("tokens").description("Discover and list design tokens from CSS/SCSS files").option("-c, --config <path>", "Path to config file").option("--json", "Output as JSON").option("--categories", "Group tokens by category").option("--theme <theme>", "Filter by theme name").option("--category <category>", "Filter by category (color, spacing, typography, etc.)").option("--verbose", "Show all tokens (no truncation)").action(async (options) => {
|
|
6521
6720
|
try {
|
|
6522
|
-
const { tokens } = await import("./tokens-
|
|
6721
|
+
const { tokens } = await import("./tokens-OPVTVITP.js");
|
|
6523
6722
|
const result = await tokens({
|
|
6524
6723
|
config: options.config,
|
|
6525
6724
|
json: options.json,
|
|
@@ -6532,13 +6731,13 @@ program.command("tokens").description("Discover and list design tokens from CSS/
|
|
|
6532
6731
|
process.exit(1);
|
|
6533
6732
|
}
|
|
6534
6733
|
} catch (error) {
|
|
6535
|
-
console.error(
|
|
6734
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6536
6735
|
process.exit(1);
|
|
6537
6736
|
}
|
|
6538
6737
|
});
|
|
6539
6738
|
program.command("generate").description("Generate fragment files from component source code").argument("[component]", "Specific component name to generate (optional)").option("--force", "Overwrite existing fragment files").option("--pattern <glob>", "Pattern for component files", "src/components/**/*.tsx").action(async (component, options) => {
|
|
6540
6739
|
try {
|
|
6541
|
-
const { generate } = await import("./generate-
|
|
6740
|
+
const { generate } = await import("./generate-RYWIPDN2.js");
|
|
6542
6741
|
const result = await generate({
|
|
6543
6742
|
projectRoot: process.cwd(),
|
|
6544
6743
|
component,
|
|
@@ -6546,11 +6745,11 @@ program.command("generate").description("Generate fragment files from component
|
|
|
6546
6745
|
componentPattern: options.pattern
|
|
6547
6746
|
});
|
|
6548
6747
|
if (!result.success) {
|
|
6549
|
-
console.error(
|
|
6748
|
+
console.error(pc25.red("\nGenerate completed with errors"));
|
|
6550
6749
|
process.exit(1);
|
|
6551
6750
|
}
|
|
6552
6751
|
} catch (error) {
|
|
6553
|
-
console.error(
|
|
6752
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6554
6753
|
process.exit(1);
|
|
6555
6754
|
}
|
|
6556
6755
|
});
|
|
@@ -6558,7 +6757,7 @@ program.command("graph").description("Query the component relationship graph").a
|
|
|
6558
6757
|
try {
|
|
6559
6758
|
await graph(component, options);
|
|
6560
6759
|
} catch (error) {
|
|
6561
|
-
console.error(
|
|
6760
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6562
6761
|
process.exit(1);
|
|
6563
6762
|
}
|
|
6564
6763
|
});
|
|
@@ -6576,14 +6775,14 @@ program.command("perf").description("Profile component bundle sizes and performa
|
|
|
6576
6775
|
process.exit(1);
|
|
6577
6776
|
}
|
|
6578
6777
|
} catch (error) {
|
|
6579
|
-
console.error(
|
|
6778
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6580
6779
|
process.exit(1);
|
|
6581
6780
|
}
|
|
6582
6781
|
});
|
|
6583
6782
|
program.command("test").description("Run interaction tests for fragments with play functions").option("-c, --config <path>", "Path to config file").option("--component <name>", "Filter by component name").option("--tags <tags>", "Filter by tags (comma-separated)").option("--grep <pattern>", "Filter by variant name pattern").option("--exclude <pattern>", "Exclude tests matching pattern").option("--parallel <count>", "Number of parallel browser contexts", parseInt, 4).option("--timeout <ms>", "Timeout per test in milliseconds", parseInt, 3e4).option("--retries <count>", "Number of retries for failed tests", parseInt, 0).option("--bail", "Stop on first failure").option("--browser <name>", "Browser to use (chromium, firefox, webkit)", "chromium").option("--headed", "Run in headed mode (show browser)").option("--a11y", "Run accessibility checks with axe-core").option("--visual", "Capture screenshots for visual regression").option("--update-snapshots", "Update visual snapshots").option("--watch", "Watch mode - re-run on file changes").option("--reporters <names>", "Reporters to use (console, junit, json)", "console").option("-o, --output <dir>", "Output directory for results", "./test-results").option("--server-url <url>", "URL of running dev server (skips starting server)").option("-p, --port <port>", "Port for dev server", parseInt, 6006).option("--ci", "CI mode - non-interactive, exit with code 1 on failure").option("--list", "List available tests without running them").action(async (options) => {
|
|
6584
6783
|
try {
|
|
6585
6784
|
const { config, configDir } = await loadConfig(options.config);
|
|
6586
|
-
const { runTestCommand, listTests } = await import("./test-
|
|
6785
|
+
const { runTestCommand, listTests } = await import("./test-JW7JIDFG.js");
|
|
6587
6786
|
if (options.list) {
|
|
6588
6787
|
await listTests(config, configDir, {
|
|
6589
6788
|
component: options.component,
|
|
@@ -6616,7 +6815,7 @@ program.command("test").description("Run interaction tests for fragments with pl
|
|
|
6616
6815
|
});
|
|
6617
6816
|
process.exit(exitCode);
|
|
6618
6817
|
} catch (error) {
|
|
6619
|
-
console.error(
|
|
6818
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6620
6819
|
process.exit(1);
|
|
6621
6820
|
}
|
|
6622
6821
|
});
|
|
@@ -6631,7 +6830,46 @@ program.command("doctor").description("Diagnose design system configuration issu
|
|
|
6631
6830
|
process.exit(1);
|
|
6632
6831
|
}
|
|
6633
6832
|
} catch (error) {
|
|
6634
|
-
console.error(
|
|
6833
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6834
|
+
process.exit(1);
|
|
6835
|
+
}
|
|
6836
|
+
});
|
|
6837
|
+
var governCmd = program.command("govern").description("AI UI governance checks");
|
|
6838
|
+
governCmd.command("check").description("Validate a UISpec against governance policies").option("-i, --input <path>", "Path to UISpec JSON file (or - for stdin)").option("-c, --config <path>", "Path to govern.config.ts").option("-f, --format <format>", "Output format: summary, json, sarif", "summary").option("-q, --quiet", "Suppress non-error output").action(async (options) => {
|
|
6839
|
+
try {
|
|
6840
|
+
const { exitCode } = await governCheck({
|
|
6841
|
+
input: options.input,
|
|
6842
|
+
config: options.config,
|
|
6843
|
+
format: options.format,
|
|
6844
|
+
quiet: options.quiet
|
|
6845
|
+
});
|
|
6846
|
+
process.exit(exitCode);
|
|
6847
|
+
} catch (error) {
|
|
6848
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6849
|
+
process.exit(1);
|
|
6850
|
+
}
|
|
6851
|
+
});
|
|
6852
|
+
governCmd.command("init").description("Generate a fragments.config.ts with govern section").option("-o, --output <path>", "Output path", "fragments.config.ts").action(async (options) => {
|
|
6853
|
+
try {
|
|
6854
|
+
await governInit({ output: options.output });
|
|
6855
|
+
} catch (error) {
|
|
6856
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6857
|
+
process.exit(1);
|
|
6858
|
+
}
|
|
6859
|
+
});
|
|
6860
|
+
governCmd.command("report").description("Summarize governance audit log").action(async () => {
|
|
6861
|
+
try {
|
|
6862
|
+
await governReport();
|
|
6863
|
+
} catch (error) {
|
|
6864
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6865
|
+
process.exit(1);
|
|
6866
|
+
}
|
|
6867
|
+
});
|
|
6868
|
+
governCmd.command("connect").description("Connect your project to the Fragments Govern cloud dashboard").action(async () => {
|
|
6869
|
+
try {
|
|
6870
|
+
await governConnect();
|
|
6871
|
+
} catch (error) {
|
|
6872
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6635
6873
|
process.exit(1);
|
|
6636
6874
|
}
|
|
6637
6875
|
});
|