@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/index.cjs CHANGED
@@ -11,6 +11,8 @@ var module$1 = require('module');
11
11
  var readline = require('readline');
12
12
  var playwright$1 = require('playwright');
13
13
  var playwright = require('@agent-scope/playwright');
14
+ var http = require('http');
15
+ var site = require('@agent-scope/site');
14
16
 
15
17
  function _interopNamespace(e) {
16
18
  if (e && e.__esModule) return e;
@@ -1130,9 +1132,9 @@ function createRL() {
1130
1132
  });
1131
1133
  }
1132
1134
  async function ask(rl, question) {
1133
- return new Promise((resolve16) => {
1135
+ return new Promise((resolve17) => {
1134
1136
  rl.question(question, (answer) => {
1135
- resolve16(answer.trim());
1137
+ resolve17(answer.trim());
1136
1138
  });
1137
1139
  });
1138
1140
  }
@@ -4632,6 +4634,130 @@ function buildStructuredReport(report) {
4632
4634
  route: report.route?.pattern ?? null
4633
4635
  };
4634
4636
  }
4637
+ var MIME_TYPES = {
4638
+ ".html": "text/html; charset=utf-8",
4639
+ ".css": "text/css; charset=utf-8",
4640
+ ".js": "application/javascript; charset=utf-8",
4641
+ ".json": "application/json; charset=utf-8",
4642
+ ".png": "image/png",
4643
+ ".jpg": "image/jpeg",
4644
+ ".jpeg": "image/jpeg",
4645
+ ".svg": "image/svg+xml",
4646
+ ".ico": "image/x-icon"
4647
+ };
4648
+ function registerBuild(siteCmd) {
4649
+ 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(
4650
+ async (opts) => {
4651
+ try {
4652
+ const inputDir = path.resolve(process.cwd(), opts.input);
4653
+ const outputDir = path.resolve(process.cwd(), opts.output);
4654
+ if (!fs.existsSync(inputDir)) {
4655
+ throw new Error(
4656
+ `Input directory not found: ${inputDir}
4657
+ Run \`scope manifest generate\` and \`scope render\` first.`
4658
+ );
4659
+ }
4660
+ const manifestPath = path.join(inputDir, "manifest.json");
4661
+ if (!fs.existsSync(manifestPath)) {
4662
+ throw new Error(
4663
+ `Manifest not found at ${manifestPath}
4664
+ Run \`scope manifest generate\` first.`
4665
+ );
4666
+ }
4667
+ process.stderr.write(`Building site from ${inputDir}\u2026
4668
+ `);
4669
+ await site.buildSite({
4670
+ inputDir,
4671
+ outputDir,
4672
+ basePath: opts.basePath,
4673
+ ...opts.compliance !== void 0 && {
4674
+ compliancePath: path.resolve(process.cwd(), opts.compliance)
4675
+ },
4676
+ title: opts.title
4677
+ });
4678
+ process.stderr.write(`Site written to ${outputDir}
4679
+ `);
4680
+ process.stdout.write(`${outputDir}
4681
+ `);
4682
+ } catch (err) {
4683
+ process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
4684
+ `);
4685
+ process.exit(1);
4686
+ }
4687
+ }
4688
+ );
4689
+ }
4690
+ function registerServe(siteCmd) {
4691
+ 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) => {
4692
+ try {
4693
+ const port = Number.parseInt(opts.port, 10);
4694
+ if (Number.isNaN(port) || port < 1 || port > 65535) {
4695
+ throw new Error(`Invalid port: ${opts.port}`);
4696
+ }
4697
+ const serveDir = path.resolve(process.cwd(), opts.dir);
4698
+ if (!fs.existsSync(serveDir)) {
4699
+ throw new Error(
4700
+ `Serve directory not found: ${serveDir}
4701
+ Run \`scope site build\` first.`
4702
+ );
4703
+ }
4704
+ const server = http.createServer((req, res) => {
4705
+ const rawUrl = req.url ?? "/";
4706
+ const urlPath = decodeURIComponent(rawUrl.split("?")[0] ?? "/");
4707
+ const filePath = path.join(serveDir, urlPath.endsWith("/") ? `${urlPath}index.html` : urlPath);
4708
+ if (!filePath.startsWith(serveDir)) {
4709
+ res.writeHead(403, { "Content-Type": "text/plain" });
4710
+ res.end("Forbidden");
4711
+ return;
4712
+ }
4713
+ if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
4714
+ const ext = path.extname(filePath).toLowerCase();
4715
+ const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
4716
+ res.writeHead(200, { "Content-Type": contentType });
4717
+ fs.createReadStream(filePath).pipe(res);
4718
+ return;
4719
+ }
4720
+ const htmlPath = `${filePath}.html`;
4721
+ if (fs.existsSync(htmlPath) && fs.statSync(htmlPath).isFile()) {
4722
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
4723
+ fs.createReadStream(htmlPath).pipe(res);
4724
+ return;
4725
+ }
4726
+ res.writeHead(404, { "Content-Type": "text/plain" });
4727
+ res.end(`Not found: ${urlPath}`);
4728
+ });
4729
+ server.listen(port, () => {
4730
+ process.stderr.write(`Scope site running at http://localhost:${port}
4731
+ `);
4732
+ process.stderr.write(`Serving ${serveDir}
4733
+ `);
4734
+ process.stderr.write("Press Ctrl+C to stop.\n");
4735
+ });
4736
+ server.on("error", (err) => {
4737
+ if (err.code === "EADDRINUSE") {
4738
+ process.stderr.write(`Error: Port ${port} is already in use.
4739
+ `);
4740
+ } else {
4741
+ process.stderr.write(`Server error: ${err.message}
4742
+ `);
4743
+ }
4744
+ process.exit(1);
4745
+ });
4746
+ } catch (err) {
4747
+ process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
4748
+ `);
4749
+ process.exit(1);
4750
+ }
4751
+ });
4752
+ }
4753
+ function createSiteCommand() {
4754
+ const siteCmd = new commander.Command("site").description(
4755
+ "Build and serve the static component gallery site"
4756
+ );
4757
+ registerBuild(siteCmd);
4758
+ registerServe(siteCmd);
4759
+ return siteCmd;
4760
+ }
4635
4761
  var DEFAULT_STYLES_PATH = ".reactscope/compliance-styles.json";
4636
4762
  function loadStylesFile(stylesPath) {
4637
4763
  const absPath = path.resolve(process.cwd(), stylesPath);
@@ -5651,6 +5777,7 @@ function createProgram(options = {}) {
5651
5777
  registerDiffSubCommand(existingReportCmd);
5652
5778
  registerPrCommentSubCommand(existingReportCmd);
5653
5779
  }
5780
+ program.addCommand(createSiteCommand());
5654
5781
  return program;
5655
5782
  }
5656
5783