@agent-scope/cli 1.16.0 → 1.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.
- package/dist/cli.js +165 -33
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +129 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +131 -4
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// src/program.ts
|
|
4
4
|
import { readFileSync as readFileSync11 } from "fs";
|
|
5
5
|
import { generateTest, loadTrace } from "@agent-scope/playwright";
|
|
6
|
-
import { Command as
|
|
6
|
+
import { Command as Command10 } from "commander";
|
|
7
7
|
|
|
8
8
|
// src/browser.ts
|
|
9
9
|
import { writeFileSync } from "fs";
|
|
@@ -1174,9 +1174,9 @@ function createRL() {
|
|
|
1174
1174
|
});
|
|
1175
1175
|
}
|
|
1176
1176
|
async function ask(rl, question) {
|
|
1177
|
-
return new Promise((
|
|
1177
|
+
return new Promise((resolve17) => {
|
|
1178
1178
|
rl.question(question, (answer) => {
|
|
1179
|
-
|
|
1179
|
+
resolve17(answer.trim());
|
|
1180
1180
|
});
|
|
1181
1181
|
});
|
|
1182
1182
|
}
|
|
@@ -4702,9 +4702,140 @@ function buildStructuredReport(report) {
|
|
|
4702
4702
|
};
|
|
4703
4703
|
}
|
|
4704
4704
|
|
|
4705
|
+
// src/site-commands.ts
|
|
4706
|
+
import { createReadStream, existsSync as existsSync9, statSync } from "fs";
|
|
4707
|
+
import { createServer } from "http";
|
|
4708
|
+
import { extname, join as join3, resolve as resolve12 } from "path";
|
|
4709
|
+
import { buildSite } from "@agent-scope/site";
|
|
4710
|
+
import { Command as Command7 } from "commander";
|
|
4711
|
+
var MIME_TYPES = {
|
|
4712
|
+
".html": "text/html; charset=utf-8",
|
|
4713
|
+
".css": "text/css; charset=utf-8",
|
|
4714
|
+
".js": "application/javascript; charset=utf-8",
|
|
4715
|
+
".json": "application/json; charset=utf-8",
|
|
4716
|
+
".png": "image/png",
|
|
4717
|
+
".jpg": "image/jpeg",
|
|
4718
|
+
".jpeg": "image/jpeg",
|
|
4719
|
+
".svg": "image/svg+xml",
|
|
4720
|
+
".ico": "image/x-icon"
|
|
4721
|
+
};
|
|
4722
|
+
function registerBuild(siteCmd) {
|
|
4723
|
+
siteCmd.command("build").description("Build a static HTML gallery from .reactscope/ output").option("-i, --input <path>", "Path to .reactscope input directory", ".reactscope").option("-o, --output <path>", "Output directory for generated site", ".reactscope/site").option("--base-path <path>", "Base URL path prefix for subdirectory deployment", "/").option("--compliance <path>", "Path to compliance batch report JSON").option("--title <text>", "Site title", "Scope \u2014 Component Gallery").action(
|
|
4724
|
+
async (opts) => {
|
|
4725
|
+
try {
|
|
4726
|
+
const inputDir = resolve12(process.cwd(), opts.input);
|
|
4727
|
+
const outputDir = resolve12(process.cwd(), opts.output);
|
|
4728
|
+
if (!existsSync9(inputDir)) {
|
|
4729
|
+
throw new Error(
|
|
4730
|
+
`Input directory not found: ${inputDir}
|
|
4731
|
+
Run \`scope manifest generate\` and \`scope render\` first.`
|
|
4732
|
+
);
|
|
4733
|
+
}
|
|
4734
|
+
const manifestPath = join3(inputDir, "manifest.json");
|
|
4735
|
+
if (!existsSync9(manifestPath)) {
|
|
4736
|
+
throw new Error(
|
|
4737
|
+
`Manifest not found at ${manifestPath}
|
|
4738
|
+
Run \`scope manifest generate\` first.`
|
|
4739
|
+
);
|
|
4740
|
+
}
|
|
4741
|
+
process.stderr.write(`Building site from ${inputDir}\u2026
|
|
4742
|
+
`);
|
|
4743
|
+
await buildSite({
|
|
4744
|
+
inputDir,
|
|
4745
|
+
outputDir,
|
|
4746
|
+
basePath: opts.basePath,
|
|
4747
|
+
...opts.compliance !== void 0 && {
|
|
4748
|
+
compliancePath: resolve12(process.cwd(), opts.compliance)
|
|
4749
|
+
},
|
|
4750
|
+
title: opts.title
|
|
4751
|
+
});
|
|
4752
|
+
process.stderr.write(`Site written to ${outputDir}
|
|
4753
|
+
`);
|
|
4754
|
+
process.stdout.write(`${outputDir}
|
|
4755
|
+
`);
|
|
4756
|
+
} catch (err) {
|
|
4757
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
4758
|
+
`);
|
|
4759
|
+
process.exit(1);
|
|
4760
|
+
}
|
|
4761
|
+
}
|
|
4762
|
+
);
|
|
4763
|
+
}
|
|
4764
|
+
function registerServe(siteCmd) {
|
|
4765
|
+
siteCmd.command("serve").description("Serve the built static site locally").option("-p, --port <number>", "Port to listen on", "3000").option("-d, --dir <path>", "Directory to serve", ".reactscope/site").action((opts) => {
|
|
4766
|
+
try {
|
|
4767
|
+
const port = Number.parseInt(opts.port, 10);
|
|
4768
|
+
if (Number.isNaN(port) || port < 1 || port > 65535) {
|
|
4769
|
+
throw new Error(`Invalid port: ${opts.port}`);
|
|
4770
|
+
}
|
|
4771
|
+
const serveDir = resolve12(process.cwd(), opts.dir);
|
|
4772
|
+
if (!existsSync9(serveDir)) {
|
|
4773
|
+
throw new Error(
|
|
4774
|
+
`Serve directory not found: ${serveDir}
|
|
4775
|
+
Run \`scope site build\` first.`
|
|
4776
|
+
);
|
|
4777
|
+
}
|
|
4778
|
+
const server = createServer((req, res) => {
|
|
4779
|
+
const rawUrl = req.url ?? "/";
|
|
4780
|
+
const urlPath = decodeURIComponent(rawUrl.split("?")[0] ?? "/");
|
|
4781
|
+
const filePath = join3(serveDir, urlPath.endsWith("/") ? `${urlPath}index.html` : urlPath);
|
|
4782
|
+
if (!filePath.startsWith(serveDir)) {
|
|
4783
|
+
res.writeHead(403, { "Content-Type": "text/plain" });
|
|
4784
|
+
res.end("Forbidden");
|
|
4785
|
+
return;
|
|
4786
|
+
}
|
|
4787
|
+
if (existsSync9(filePath) && statSync(filePath).isFile()) {
|
|
4788
|
+
const ext = extname(filePath).toLowerCase();
|
|
4789
|
+
const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
4790
|
+
res.writeHead(200, { "Content-Type": contentType });
|
|
4791
|
+
createReadStream(filePath).pipe(res);
|
|
4792
|
+
return;
|
|
4793
|
+
}
|
|
4794
|
+
const htmlPath = `${filePath}.html`;
|
|
4795
|
+
if (existsSync9(htmlPath) && statSync(htmlPath).isFile()) {
|
|
4796
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
4797
|
+
createReadStream(htmlPath).pipe(res);
|
|
4798
|
+
return;
|
|
4799
|
+
}
|
|
4800
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
4801
|
+
res.end(`Not found: ${urlPath}`);
|
|
4802
|
+
});
|
|
4803
|
+
server.listen(port, () => {
|
|
4804
|
+
process.stderr.write(`Scope site running at http://localhost:${port}
|
|
4805
|
+
`);
|
|
4806
|
+
process.stderr.write(`Serving ${serveDir}
|
|
4807
|
+
`);
|
|
4808
|
+
process.stderr.write("Press Ctrl+C to stop.\n");
|
|
4809
|
+
});
|
|
4810
|
+
server.on("error", (err) => {
|
|
4811
|
+
if (err.code === "EADDRINUSE") {
|
|
4812
|
+
process.stderr.write(`Error: Port ${port} is already in use.
|
|
4813
|
+
`);
|
|
4814
|
+
} else {
|
|
4815
|
+
process.stderr.write(`Server error: ${err.message}
|
|
4816
|
+
`);
|
|
4817
|
+
}
|
|
4818
|
+
process.exit(1);
|
|
4819
|
+
});
|
|
4820
|
+
} catch (err) {
|
|
4821
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
4822
|
+
`);
|
|
4823
|
+
process.exit(1);
|
|
4824
|
+
}
|
|
4825
|
+
});
|
|
4826
|
+
}
|
|
4827
|
+
function createSiteCommand() {
|
|
4828
|
+
const siteCmd = new Command7("site").description(
|
|
4829
|
+
"Build and serve the static component gallery site"
|
|
4830
|
+
);
|
|
4831
|
+
registerBuild(siteCmd);
|
|
4832
|
+
registerServe(siteCmd);
|
|
4833
|
+
return siteCmd;
|
|
4834
|
+
}
|
|
4835
|
+
|
|
4705
4836
|
// src/tokens/commands.ts
|
|
4706
|
-
import { existsSync as
|
|
4707
|
-
import { resolve as
|
|
4837
|
+
import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
|
|
4838
|
+
import { resolve as resolve16 } from "path";
|
|
4708
4839
|
import {
|
|
4709
4840
|
parseTokenFileSync as parseTokenFileSync2,
|
|
4710
4841
|
TokenParseError,
|
|
@@ -4712,19 +4843,19 @@ import {
|
|
|
4712
4843
|
TokenValidationError,
|
|
4713
4844
|
validateTokenFile
|
|
4714
4845
|
} from "@agent-scope/tokens";
|
|
4715
|
-
import { Command as
|
|
4846
|
+
import { Command as Command9 } from "commander";
|
|
4716
4847
|
|
|
4717
4848
|
// src/tokens/compliance.ts
|
|
4718
|
-
import { existsSync as
|
|
4719
|
-
import { resolve as
|
|
4849
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
|
|
4850
|
+
import { resolve as resolve13 } from "path";
|
|
4720
4851
|
import {
|
|
4721
4852
|
ComplianceEngine as ComplianceEngine4,
|
|
4722
4853
|
TokenResolver as TokenResolver4
|
|
4723
4854
|
} from "@agent-scope/tokens";
|
|
4724
4855
|
var DEFAULT_STYLES_PATH = ".reactscope/compliance-styles.json";
|
|
4725
4856
|
function loadStylesFile(stylesPath) {
|
|
4726
|
-
const absPath =
|
|
4727
|
-
if (!
|
|
4857
|
+
const absPath = resolve13(process.cwd(), stylesPath);
|
|
4858
|
+
if (!existsSync10(absPath)) {
|
|
4728
4859
|
throw new Error(
|
|
4729
4860
|
`Compliance styles file not found at ${absPath}.
|
|
4730
4861
|
Run \`scope render all\` first to generate component styles, or use --styles to specify a path.
|
|
@@ -4891,38 +5022,38 @@ function registerCompliance(tokensCmd) {
|
|
|
4891
5022
|
}
|
|
4892
5023
|
|
|
4893
5024
|
// src/tokens/export.ts
|
|
4894
|
-
import { existsSync as
|
|
4895
|
-
import { resolve as
|
|
5025
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync9 } from "fs";
|
|
5026
|
+
import { resolve as resolve14 } from "path";
|
|
4896
5027
|
import {
|
|
4897
5028
|
exportTokens,
|
|
4898
5029
|
parseTokenFileSync,
|
|
4899
5030
|
ThemeResolver,
|
|
4900
5031
|
TokenResolver as TokenResolver5
|
|
4901
5032
|
} from "@agent-scope/tokens";
|
|
4902
|
-
import { Command as
|
|
5033
|
+
import { Command as Command8 } from "commander";
|
|
4903
5034
|
var DEFAULT_TOKEN_FILE = "reactscope.tokens.json";
|
|
4904
5035
|
var CONFIG_FILE = "reactscope.config.json";
|
|
4905
5036
|
var SUPPORTED_FORMATS = ["css", "ts", "scss", "tailwind", "flat-json", "figma"];
|
|
4906
5037
|
function resolveTokenFilePath2(fileFlag) {
|
|
4907
5038
|
if (fileFlag !== void 0) {
|
|
4908
|
-
return
|
|
5039
|
+
return resolve14(process.cwd(), fileFlag);
|
|
4909
5040
|
}
|
|
4910
|
-
const configPath =
|
|
4911
|
-
if (
|
|
5041
|
+
const configPath = resolve14(process.cwd(), CONFIG_FILE);
|
|
5042
|
+
if (existsSync11(configPath)) {
|
|
4912
5043
|
try {
|
|
4913
5044
|
const raw = readFileSync9(configPath, "utf-8");
|
|
4914
5045
|
const config = JSON.parse(raw);
|
|
4915
5046
|
if (typeof config === "object" && config !== null && "tokens" in config && typeof config.tokens === "object" && config.tokens !== null && typeof config.tokens?.file === "string") {
|
|
4916
5047
|
const file = config.tokens.file;
|
|
4917
|
-
return
|
|
5048
|
+
return resolve14(process.cwd(), file);
|
|
4918
5049
|
}
|
|
4919
5050
|
} catch {
|
|
4920
5051
|
}
|
|
4921
5052
|
}
|
|
4922
|
-
return
|
|
5053
|
+
return resolve14(process.cwd(), DEFAULT_TOKEN_FILE);
|
|
4923
5054
|
}
|
|
4924
5055
|
function createTokensExportCommand() {
|
|
4925
|
-
return new
|
|
5056
|
+
return new Command8("export").description("Export design tokens to a downstream format").requiredOption("--format <fmt>", `Output format: ${SUPPORTED_FORMATS.join(", ")}`).option("--file <path>", "Path to token file (overrides config)").option("--out <path>", "Write output to file instead of stdout").option("--prefix <prefix>", "CSS/SCSS: prefix for variable names (e.g. 'scope')").option("--selector <selector>", "CSS: custom root selector (default: ':root')").option(
|
|
4926
5057
|
"--theme <name>",
|
|
4927
5058
|
"Include theme overrides for the named theme (applies to css, ts, scss, tailwind, figma)"
|
|
4928
5059
|
).action(
|
|
@@ -4938,7 +5069,7 @@ Supported formats: ${SUPPORTED_FORMATS.join(", ")}
|
|
|
4938
5069
|
const format = opts.format;
|
|
4939
5070
|
try {
|
|
4940
5071
|
const filePath = resolveTokenFilePath2(opts.file);
|
|
4941
|
-
if (!
|
|
5072
|
+
if (!existsSync11(filePath)) {
|
|
4942
5073
|
throw new Error(
|
|
4943
5074
|
`Token file not found at ${filePath}.
|
|
4944
5075
|
Create a reactscope.tokens.json file or use --file to specify a path.`
|
|
@@ -4983,7 +5114,7 @@ Available themes: ${themeNames.join(", ")}`
|
|
|
4983
5114
|
themes: themesMap
|
|
4984
5115
|
});
|
|
4985
5116
|
if (opts.out !== void 0) {
|
|
4986
|
-
const outPath =
|
|
5117
|
+
const outPath = resolve14(process.cwd(), opts.out);
|
|
4987
5118
|
writeFileSync9(outPath, output, "utf-8");
|
|
4988
5119
|
process.stderr.write(`Exported ${tokens.length} tokens to ${outPath}
|
|
4989
5120
|
`);
|
|
@@ -5099,7 +5230,7 @@ ${formatImpactSummary(report)}
|
|
|
5099
5230
|
|
|
5100
5231
|
// src/tokens/preview.ts
|
|
5101
5232
|
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync10 } from "fs";
|
|
5102
|
-
import { resolve as
|
|
5233
|
+
import { resolve as resolve15 } from "path";
|
|
5103
5234
|
import { BrowserPool as BrowserPool7, SpriteSheetGenerator } from "@agent-scope/render";
|
|
5104
5235
|
import { ComplianceEngine as ComplianceEngine6, ImpactAnalyzer as ImpactAnalyzer2, TokenResolver as TokenResolver7 } from "@agent-scope/tokens";
|
|
5105
5236
|
var DEFAULT_STYLES_PATH3 = ".reactscope/compliance-styles.json";
|
|
@@ -5280,8 +5411,8 @@ function registerPreview(tokensCmd) {
|
|
|
5280
5411
|
});
|
|
5281
5412
|
const spriteResult = await generator.generate(matrixResult);
|
|
5282
5413
|
const tokenLabel = tokenPath.replace(/\./g, "-");
|
|
5283
|
-
const outputPath = opts.output ??
|
|
5284
|
-
const outputDir =
|
|
5414
|
+
const outputPath = opts.output ?? resolve15(process.cwd(), DEFAULT_OUTPUT_DIR2, `preview-${tokenLabel}.png`);
|
|
5415
|
+
const outputDir = resolve15(outputPath, "..");
|
|
5285
5416
|
mkdirSync5(outputDir, { recursive: true });
|
|
5286
5417
|
writeFileSync10(outputPath, spriteResult.png);
|
|
5287
5418
|
const useJson = opts.format === "json" || opts.format !== "text" && !isTTY();
|
|
@@ -5342,24 +5473,24 @@ function buildTable2(headers, rows) {
|
|
|
5342
5473
|
}
|
|
5343
5474
|
function resolveTokenFilePath(fileFlag) {
|
|
5344
5475
|
if (fileFlag !== void 0) {
|
|
5345
|
-
return
|
|
5476
|
+
return resolve16(process.cwd(), fileFlag);
|
|
5346
5477
|
}
|
|
5347
|
-
const configPath =
|
|
5348
|
-
if (
|
|
5478
|
+
const configPath = resolve16(process.cwd(), CONFIG_FILE2);
|
|
5479
|
+
if (existsSync12(configPath)) {
|
|
5349
5480
|
try {
|
|
5350
5481
|
const raw = readFileSync10(configPath, "utf-8");
|
|
5351
5482
|
const config = JSON.parse(raw);
|
|
5352
5483
|
if (typeof config === "object" && config !== null && "tokens" in config && typeof config.tokens === "object" && config.tokens !== null && typeof config.tokens?.file === "string") {
|
|
5353
5484
|
const file = config.tokens.file;
|
|
5354
|
-
return
|
|
5485
|
+
return resolve16(process.cwd(), file);
|
|
5355
5486
|
}
|
|
5356
5487
|
} catch {
|
|
5357
5488
|
}
|
|
5358
5489
|
}
|
|
5359
|
-
return
|
|
5490
|
+
return resolve16(process.cwd(), DEFAULT_TOKEN_FILE2);
|
|
5360
5491
|
}
|
|
5361
5492
|
function loadTokens(absPath) {
|
|
5362
|
-
if (!
|
|
5493
|
+
if (!existsSync12(absPath)) {
|
|
5363
5494
|
throw new Error(
|
|
5364
5495
|
`Token file not found at ${absPath}.
|
|
5365
5496
|
Create a reactscope.tokens.json file or use --file to specify a path.`
|
|
@@ -5579,7 +5710,7 @@ function registerValidate(tokensCmd) {
|
|
|
5579
5710
|
).option("--file <path>", "Path to token file (overrides config)").option("--format <fmt>", "Output format: json or text (default: auto-detect)").action((opts) => {
|
|
5580
5711
|
try {
|
|
5581
5712
|
const filePath = resolveTokenFilePath(opts.file);
|
|
5582
|
-
if (!
|
|
5713
|
+
if (!existsSync12(filePath)) {
|
|
5583
5714
|
throw new Error(
|
|
5584
5715
|
`Token file not found at ${filePath}.
|
|
5585
5716
|
Create a reactscope.tokens.json file or use --file to specify a path.`
|
|
@@ -5653,7 +5784,7 @@ function outputValidationResult(filePath, errors, useJson) {
|
|
|
5653
5784
|
}
|
|
5654
5785
|
}
|
|
5655
5786
|
function createTokensCommand() {
|
|
5656
|
-
const tokensCmd = new
|
|
5787
|
+
const tokensCmd = new Command9("tokens").description(
|
|
5657
5788
|
"Query and validate design tokens from a reactscope.tokens.json file"
|
|
5658
5789
|
);
|
|
5659
5790
|
registerGet2(tokensCmd);
|
|
@@ -5670,7 +5801,7 @@ function createTokensCommand() {
|
|
|
5670
5801
|
|
|
5671
5802
|
// src/program.ts
|
|
5672
5803
|
function createProgram(options = {}) {
|
|
5673
|
-
const program2 = new
|
|
5804
|
+
const program2 = new Command10("scope").version(options.version ?? "0.1.0").description("Scope \u2014 React instrumentation toolkit");
|
|
5674
5805
|
program2.command("capture <url>").description("Capture a React component tree from a live URL and output as JSON").option("-o, --output <path>", "Write JSON to file instead of stdout").option("--pretty", "Pretty-print JSON output (default: minified)", false).option("--timeout <ms>", "Max wait time for React to mount (ms)", "10000").option("--wait <ms>", "Additional wait after page load before capture (ms)", "0").action(
|
|
5675
5806
|
async (url, opts) => {
|
|
5676
5807
|
try {
|
|
@@ -5764,6 +5895,7 @@ function createProgram(options = {}) {
|
|
|
5764
5895
|
registerDiffSubCommand(existingReportCmd);
|
|
5765
5896
|
registerPrCommentSubCommand(existingReportCmd);
|
|
5766
5897
|
}
|
|
5898
|
+
program2.addCommand(createSiteCommand());
|
|
5767
5899
|
return program2;
|
|
5768
5900
|
}
|
|
5769
5901
|
|