@construct-space/cli 1.0.7 → 1.1.2

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.js CHANGED
@@ -5,25 +5,43 @@ var __getProtoOf = Object.getPrototypeOf;
5
5
  var __defProp = Object.defineProperty;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ function __accessProp(key) {
9
+ return this[key];
10
+ }
11
+ var __toESMCache_node;
12
+ var __toESMCache_esm;
8
13
  var __toESM = (mod, isNodeMode, target) => {
14
+ var canCache = mod != null && typeof mod === "object";
15
+ if (canCache) {
16
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
17
+ var cached = cache.get(mod);
18
+ if (cached)
19
+ return cached;
20
+ }
9
21
  target = mod != null ? __create(__getProtoOf(mod)) : {};
10
22
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
11
23
  for (let key of __getOwnPropNames(mod))
12
24
  if (!__hasOwnProp.call(to, key))
13
25
  __defProp(to, key, {
14
- get: () => mod[key],
26
+ get: __accessProp.bind(mod, key),
15
27
  enumerable: true
16
28
  });
29
+ if (canCache)
30
+ cache.set(mod, to);
17
31
  return to;
18
32
  };
19
33
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
34
+ var __returnValue = (v) => v;
35
+ function __exportSetter(name, newValue) {
36
+ this[name] = __returnValue.bind(null, newValue);
37
+ }
20
38
  var __export = (target, all) => {
21
39
  for (var name in all)
22
40
  __defProp(target, name, {
23
41
  get: all[name],
24
42
  enumerable: true,
25
43
  configurable: true,
26
- set: (newValue) => all[name] = () => newValue
44
+ set: __exportSetter.bind(all, name)
27
45
  });
28
46
  };
29
47
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
@@ -2298,8 +2316,8 @@ var {
2298
2316
  } = import__.default;
2299
2317
 
2300
2318
  // src/commands/scaffold.ts
2301
- import { mkdirSync, writeFileSync, existsSync, readFileSync } from "fs";
2302
- import { join, dirname } from "path";
2319
+ import { mkdirSync, writeFileSync, existsSync as existsSync2, readFileSync } from "fs";
2320
+ import { join as join2, dirname } from "path";
2303
2321
 
2304
2322
  // node_modules/chalk/source/vendor/ansi-styles/index.js
2305
2323
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -2789,7 +2807,6 @@ Object.defineProperties(createChalk.prototype, styles2);
2789
2807
  var chalk = createChalk();
2790
2808
  var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
2791
2809
  var source_default = chalk;
2792
-
2793
2810
  // node_modules/@inquirer/core/dist/lib/key.js
2794
2811
  var isUpKey = (key, keybindings = []) => key.name === "up" || keybindings.includes("vim") && key.name === "k" || keybindings.includes("emacs") && key.ctrl && key.name === "p";
2795
2812
  var isDownKey = (key, keybindings = []) => key.name === "down" || keybindings.includes("vim") && key.name === "j" || keybindings.includes("emacs") && key.ctrl && key.name === "n";
@@ -2934,7 +2951,7 @@ var effectScheduler = {
2934
2951
  // node_modules/@inquirer/core/dist/lib/use-state.js
2935
2952
  function useState(defaultValue) {
2936
2953
  return withPointer((pointer) => {
2937
- const setState = AsyncResource2.bind(function setState(newValue) {
2954
+ const setState = AsyncResource2.bind(function setState2(newValue) {
2938
2955
  if (pointer.get() !== newValue) {
2939
2956
  pointer.set(newValue);
2940
2957
  handleChange();
@@ -4557,14 +4574,58 @@ function toDisplayName(name) {
4557
4574
  return name.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
4558
4575
  }
4559
4576
 
4577
+ // src/lib/runtime.ts
4578
+ import { execSync as execSync2, spawn } from "child_process";
4579
+ import { existsSync } from "fs";
4580
+ import { join } from "path";
4581
+ function detect() {
4582
+ for (const rt of ["bun", "node"]) {
4583
+ try {
4584
+ const version = execSync2(`${rt} --version`, { encoding: "utf-8" }).trim().replace(/^v/, "");
4585
+ return { name: rt, version, exec: rt };
4586
+ } catch {}
4587
+ }
4588
+ throw new Error("No JavaScript runtime found. Install bun or node.");
4589
+ }
4590
+ function ensureDeps(root, rt) {
4591
+ const nmDir = join(root, "node_modules");
4592
+ if (existsSync(nmDir))
4593
+ return;
4594
+ const cmd = rt.name === "bun" ? "bun install" : "npm install";
4595
+ execSync2(cmd, { cwd: root, stdio: "inherit" });
4596
+ }
4597
+ function buildCmd(root, rt) {
4598
+ const cmd = rt.name === "bun" ? "bun" : "npx";
4599
+ const args = rt.name === "bun" ? ["run", "vite", "build"] : ["vite", "build"];
4600
+ const child = spawn(cmd, args, { cwd: root, stdio: "inherit" });
4601
+ return new Promise((resolve, reject) => {
4602
+ child.on("close", (code) => {
4603
+ if (code === 0)
4604
+ resolve();
4605
+ else
4606
+ reject(new Error(`Build failed with exit code ${code}`));
4607
+ });
4608
+ });
4609
+ }
4610
+ function watchCmd(root, rt) {
4611
+ const cmd = rt.name === "bun" ? "bun" : "npx";
4612
+ const args = rt.name === "bun" ? ["run", "vite", "build", "--watch"] : ["vite", "build", "--watch"];
4613
+ return spawn(cmd, args, { cwd: root, stdio: "pipe" });
4614
+ }
4615
+ function runHook(hooks, hookName, root) {
4616
+ if (!hooks || !hooks[hookName])
4617
+ return;
4618
+ execSync2(hooks[hookName], { cwd: root, stdio: "inherit" });
4619
+ }
4620
+
4560
4621
  // src/commands/scaffold.ts
4561
4622
  var nameRegex = /^[a-z][a-z0-9-]*$/;
4562
4623
  function render(template, data) {
4563
4624
  return template.replace(/\{\{\.Name\}\}/g, data.name).replace(/\{\{\.ID\}\}/g, data.id).replace(/\{\{\.IDUpper\}\}/g, data.idUpper).replace(/\{\{\.DisplayName\}\}/g, data.displayName).replace(/\{\{\.DisplayNameNoSpace\}\}/g, data.displayNameNoSpace);
4564
4625
  }
4565
4626
  function writeTemplate(templateDir, tmplName, outPath, data) {
4566
- const tmplPath = join(templateDir, tmplName);
4567
- if (!existsSync(tmplPath)) {
4627
+ const tmplPath = join2(templateDir, tmplName);
4628
+ if (!existsSync2(tmplPath)) {
4568
4629
  console.warn(source_default.yellow(`Template not found: ${tmplName}`));
4569
4630
  return;
4570
4631
  }
@@ -4572,6 +4633,11 @@ function writeTemplate(templateDir, tmplName, outPath, data) {
4572
4633
  mkdirSync(dirname(outPath), { recursive: true });
4573
4634
  writeFileSync(outPath, render(content, data));
4574
4635
  }
4636
+ async function installScaffoldDeps(root) {
4637
+ const rt = detect();
4638
+ console.log(source_default.blue(`Installing dependencies with ${rt.name}...`));
4639
+ ensureDeps(root, rt);
4640
+ }
4575
4641
  async function scaffold(nameArg, options) {
4576
4642
  let name = nameArg;
4577
4643
  if (!name) {
@@ -4584,7 +4650,7 @@ async function scaffold(nameArg, options) {
4584
4650
  console.error(source_default.red("Invalid name: must be lowercase alphanumeric with hyphens, starting with a letter"));
4585
4651
  process.exit(1);
4586
4652
  }
4587
- if (existsSync(name)) {
4653
+ if (existsSync2(name)) {
4588
4654
  console.error(source_default.red(`Directory '${name}' already exists`));
4589
4655
  process.exit(1);
4590
4656
  }
@@ -4597,54 +4663,70 @@ async function scaffold(nameArg, options) {
4597
4663
  displayName,
4598
4664
  displayNameNoSpace: displayName.replace(/ /g, "")
4599
4665
  };
4600
- console.log(source_default.blue(`Creating space: ${displayName}`));
4666
+ const isFull = options?.full ?? false;
4667
+ console.log(source_default.blue(`Creating space: ${displayName}${isFull ? " (full preset)" : ""}`));
4601
4668
  const dirs = [
4602
4669
  name,
4603
- join(name, "src", "pages"),
4604
- join(name, "src", "components"),
4605
- join(name, "src", "composables"),
4606
- join(name, "agent", "skills"),
4607
- join(name, "agent", "hooks"),
4608
- join(name, "agent", "tools"),
4609
- join(name, "widgets", "summary"),
4610
- join(name, ".github", "workflows")
4670
+ join2(name, "src", "pages"),
4671
+ join2(name, "src", "components"),
4672
+ join2(name, "src", "composables"),
4673
+ join2(name, "agent", "skills"),
4674
+ join2(name, "agent", "hooks"),
4675
+ join2(name, "agent", "tools"),
4676
+ join2(name, "widgets", "summary"),
4677
+ join2(name, ".github", "workflows")
4611
4678
  ];
4612
4679
  for (const d of dirs)
4613
4680
  mkdirSync(d, { recursive: true });
4614
4681
  const scriptDir = dirname(new URL(import.meta.url).pathname);
4615
- let templateDir = join(scriptDir, "templates", "space");
4616
- if (!existsSync(templateDir)) {
4617
- templateDir = join(scriptDir, "..", "templates", "space");
4682
+ let templateDir = join2(scriptDir, "templates", "space");
4683
+ if (!existsSync2(templateDir)) {
4684
+ templateDir = join2(scriptDir, "..", "templates", "space");
4685
+ }
4686
+ if (!existsSync2(templateDir)) {
4687
+ templateDir = join2(scriptDir, "..", "..", "templates", "space");
4618
4688
  }
4619
4689
  const files = {
4620
- "space.manifest.json.tmpl": join(name, "space.manifest.json"),
4621
- "package.json.tmpl": join(name, "package.json"),
4622
- "vite.config.ts.tmpl": join(name, "vite.config.ts"),
4623
- "index.vue.tmpl": join(name, "src", "pages", "index.vue"),
4624
- "config.md.tmpl": join(name, "agent", "config.md"),
4625
- "skill.md.tmpl": join(name, "agent", "skills", "default.md"),
4626
- "safety.json.tmpl": join(name, "agent", "hooks", "safety.json"),
4627
- "build.yml.tmpl": join(name, ".github", "workflows", "build.yml"),
4628
- "tsconfig.json.tmpl": join(name, "tsconfig.json"),
4629
- "gitignore.tmpl": join(name, ".gitignore"),
4630
- "readme.md.tmpl": join(name, "README.md"),
4631
- "widgets/2x1.vue.tmpl": join(name, "widgets", "summary", "2x1.vue"),
4632
- "widgets/4x1.vue.tmpl": join(name, "widgets", "summary", "4x1.vue"),
4633
- "actions.ts.tmpl": join(name, "src", "actions.ts")
4690
+ "package.json.tmpl": join2(name, "package.json"),
4691
+ "vite.config.ts.tmpl": join2(name, "vite.config.ts"),
4692
+ "index.vue.tmpl": join2(name, "src", "pages", "index.vue"),
4693
+ "config.md.tmpl": join2(name, "agent", "config.md"),
4694
+ "skill.md.tmpl": join2(name, "agent", "skills", "default.md"),
4695
+ "safety.json.tmpl": join2(name, "agent", "hooks", "safety.json"),
4696
+ "build.yml.tmpl": join2(name, ".github", "workflows", "build.yml"),
4697
+ "tsconfig.json.tmpl": join2(name, "tsconfig.json"),
4698
+ "gitignore.tmpl": join2(name, ".gitignore"),
4699
+ "readme.md.tmpl": join2(name, "README.md"),
4700
+ "widgets/2x1.vue.tmpl": join2(name, "widgets", "summary", "2x1.vue"),
4701
+ "widgets/4x1.vue.tmpl": join2(name, "widgets", "summary", "4x1.vue"),
4702
+ "actions.ts.tmpl": join2(name, "src", "actions.ts")
4634
4703
  };
4704
+ if (isFull) {
4705
+ files["full/space.manifest.json.tmpl"] = join2(name, "space.manifest.json");
4706
+ files["full/entry.ts.tmpl"] = join2(name, "src", "entry.ts");
4707
+ } else {
4708
+ files["space.manifest.json.tmpl"] = join2(name, "space.manifest.json");
4709
+ files["entry.ts.tmpl"] = join2(name, "src", "entry.ts");
4710
+ }
4635
4711
  for (const [tmpl, out] of Object.entries(files)) {
4636
4712
  writeTemplate(templateDir, tmpl, out, data);
4637
4713
  }
4714
+ if (isFull) {
4715
+ writeTemplate(templateDir, "full/settings.vue.tmpl", join2(name, "src", "pages", "settings.vue"), data);
4716
+ writeTemplate(templateDir, "full/skill-data.md.tmpl", join2(name, "agent", "skills", "data.md"), data);
4717
+ writeTemplate(templateDir, "full/skill-ui.md.tmpl", join2(name, "agent", "skills", "ui.md"), data);
4718
+ console.log(source_default.blue("Full preset: settings page + extra skills added"));
4719
+ }
4638
4720
  if (options?.withTests) {
4639
- mkdirSync(join(name, "e2e"), { recursive: true });
4640
- writeTemplate(templateDir, "e2e/playwright.config.ts.tmpl", join(name, "playwright.config.ts"), data);
4641
- writeTemplate(templateDir, "e2e/space.spec.ts.tmpl", join(name, "e2e", "space.spec.ts"), data);
4721
+ mkdirSync(join2(name, "e2e"), { recursive: true });
4722
+ writeTemplate(templateDir, "e2e/playwright.config.ts.tmpl", join2(name, "playwright.config.ts"), data);
4723
+ writeTemplate(templateDir, "e2e/space.spec.ts.tmpl", join2(name, "e2e", "space.spec.ts"), data);
4642
4724
  console.log(source_default.blue("E2E testing boilerplate added (Playwright)"));
4643
4725
  }
4726
+ await (options?.installDeps ?? installScaffoldDeps)(name);
4644
4727
  console.log(source_default.green(`Space '${name}' created!`));
4645
4728
  console.log();
4646
4729
  console.log(` cd ${name}`);
4647
- console.log(" bun install");
4648
4730
  console.log(" construct dev");
4649
4731
  console.log();
4650
4732
  }
@@ -7284,8 +7366,8 @@ function ora(options) {
7284
7366
  }
7285
7367
 
7286
7368
  // src/lib/manifest.ts
7287
- import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync2 } from "fs";
7288
- import { join as join2 } from "path";
7369
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync3 } from "fs";
7370
+ import { join as join3 } from "path";
7289
7371
  var MANIFEST_FILE = "space.manifest.json";
7290
7372
  var idRegex = /^[a-z][a-z0-9-]*$/;
7291
7373
  var versionRegex = /^\d+\.\d+\.\d+/;
@@ -7312,27 +7394,27 @@ function validate2(m) {
7312
7394
  return errors2;
7313
7395
  }
7314
7396
  function read(dir) {
7315
- const path = join2(dir, MANIFEST_FILE);
7397
+ const path = join3(dir, MANIFEST_FILE);
7316
7398
  const data = readFileSync2(path, "utf-8");
7317
7399
  return JSON.parse(data);
7318
7400
  }
7319
7401
  function readRaw(dir) {
7320
- const path = join2(dir, MANIFEST_FILE);
7402
+ const path = join3(dir, MANIFEST_FILE);
7321
7403
  const data = readFileSync2(path, "utf-8");
7322
7404
  return JSON.parse(data);
7323
7405
  }
7324
7406
  function writeWithBuild(dir, raw, build) {
7325
7407
  raw.build = build;
7326
- writeFileSync2(join2(dir, "manifest.json"), JSON.stringify(raw, null, 2) + `
7408
+ writeFileSync2(join3(dir, "manifest.json"), JSON.stringify(raw, null, 2) + `
7327
7409
  `);
7328
7410
  }
7329
7411
  function exists(dir) {
7330
- return existsSync2(join2(dir, MANIFEST_FILE));
7412
+ return existsSync3(join3(dir, MANIFEST_FILE));
7331
7413
  }
7332
7414
 
7333
7415
  // src/lib/entry.ts
7334
- import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, existsSync as existsSync3 } from "fs";
7335
- import { join as join3, basename, extname } from "path";
7416
+ import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, existsSync as existsSync4 } from "fs";
7417
+ import { join as join4, basename, extname } from "path";
7336
7418
  function capitalize(s) {
7337
7419
  if (!s)
7338
7420
  return s;
@@ -7372,11 +7454,11 @@ function resolveWidgets(m, prefix) {
7372
7454
  return imports;
7373
7455
  }
7374
7456
  function generate(root, m) {
7375
- const pagePrefix = existsSync3(join3(root, "src", "pages")) ? "./" : "../";
7457
+ const pagePrefix = existsSync4(join4(root, "src", "pages")) ? "./" : "../";
7376
7458
  const pages = resolvePages(m, pagePrefix);
7377
7459
  const widgets = resolveWidgets(m, "../");
7378
- const actionsPath = join3(root, "src", "actions.ts");
7379
- const hasActions = existsSync3(actionsPath);
7460
+ const actionsPath = join4(root, "src", "actions.ts");
7461
+ const hasActions = existsSync4(actionsPath);
7380
7462
  console.log(`[entry] root=${root} actionsPath=${actionsPath} hasActions=${hasActions}`);
7381
7463
  const lines = [
7382
7464
  "// Auto-generated entry — do not edit manually",
@@ -7423,53 +7505,9 @@ function generate(root, m) {
7423
7505
  `;
7424
7506
  }
7425
7507
  function writeEntry(root, m) {
7426
- const srcDir = join3(root, "src");
7508
+ const srcDir = join4(root, "src");
7427
7509
  mkdirSync2(srcDir, { recursive: true });
7428
- writeFileSync3(join3(srcDir, "entry.ts"), generate(root, m));
7429
- }
7430
-
7431
- // src/lib/runtime.ts
7432
- import { execSync as execSync2, spawn } from "child_process";
7433
- import { existsSync as existsSync4 } from "fs";
7434
- import { join as join4 } from "path";
7435
- function detect() {
7436
- for (const rt of ["bun", "node"]) {
7437
- try {
7438
- const version = execSync2(`${rt} --version`, { encoding: "utf-8" }).trim().replace(/^v/, "");
7439
- return { name: rt, version, exec: rt };
7440
- } catch {}
7441
- }
7442
- throw new Error("No JavaScript runtime found. Install bun or node.");
7443
- }
7444
- function ensureDeps(root, rt) {
7445
- const nmDir = join4(root, "node_modules");
7446
- if (existsSync4(nmDir))
7447
- return;
7448
- const cmd = rt.name === "bun" ? "bun install" : "npm install";
7449
- execSync2(cmd, { cwd: root, stdio: "inherit" });
7450
- }
7451
- function buildCmd(root, rt) {
7452
- const cmd = rt.name === "bun" ? "bun" : "npx";
7453
- const args = rt.name === "bun" ? ["run", "vite", "build"] : ["vite", "build"];
7454
- const child = spawn(cmd, args, { cwd: root, stdio: "inherit" });
7455
- return new Promise((resolve, reject) => {
7456
- child.on("close", (code) => {
7457
- if (code === 0)
7458
- resolve();
7459
- else
7460
- reject(new Error(`Build failed with exit code ${code}`));
7461
- });
7462
- });
7463
- }
7464
- function watchCmd(root, rt) {
7465
- const cmd = rt.name === "bun" ? "bun" : "npx";
7466
- const args = rt.name === "bun" ? ["run", "vite", "build", "--watch"] : ["vite", "build", "--watch"];
7467
- return spawn(cmd, args, { cwd: root, stdio: "pipe" });
7468
- }
7469
- function runHook(hooks, hookName, root) {
7470
- if (!hooks || !hooks[hookName])
7471
- return;
7472
- execSync2(hooks[hookName], { cwd: root, stdio: "inherit" });
7510
+ writeFileSync3(join4(srcDir, "entry.ts"), generate(root, m));
7473
7511
  }
7474
7512
 
7475
7513
  // src/lib/agent.ts
@@ -7528,6 +7566,41 @@ function bundleAgentDir(srcDir, distDir) {
7528
7566
  }
7529
7567
 
7530
7568
  // src/commands/build.ts
7569
+ function extractActionMetadata(actionsPath) {
7570
+ try {
7571
+ const source = readFileSync4(actionsPath, "utf-8");
7572
+ const result = {};
7573
+ const actionPattern = /(\w+)\s*:\s*\{[^}]*description\s*:\s*['"`]([^'"`]+)['"`]/g;
7574
+ let match;
7575
+ while ((match = actionPattern.exec(source)) !== null) {
7576
+ const actionId = match[1];
7577
+ const description = match[2];
7578
+ result[actionId] = { description };
7579
+ }
7580
+ for (const actionId of Object.keys(result)) {
7581
+ const paramBlockPattern = new RegExp(`${actionId}\\s*:\\s*\\{[\\s\\S]*?params\\s*:\\s*\\{([\\s\\S]*?)\\}\\s*,?\\s*(?:run|\\})`);
7582
+ const paramMatch = source.match(paramBlockPattern);
7583
+ if (paramMatch?.[1]) {
7584
+ const params = {};
7585
+ const paramEntryPattern = /(\w+)\s*:\s*\{\s*type\s*:\s*['"`](\w+)['"`](?:\s*,\s*description\s*:\s*['"`]([^'"`]*)['"`])?(?:\s*,\s*required\s*:\s*(true|false))?\s*\}/g;
7586
+ let pm;
7587
+ while ((pm = paramEntryPattern.exec(paramMatch[1])) !== null) {
7588
+ params[pm[1]] = {
7589
+ type: pm[2],
7590
+ ...pm[3] ? { description: pm[3] } : {},
7591
+ ...pm[4] === "true" ? { required: true } : {}
7592
+ };
7593
+ }
7594
+ if (Object.keys(params).length > 0) {
7595
+ result[actionId].params = params;
7596
+ }
7597
+ }
7598
+ }
7599
+ return Object.keys(result).length > 0 ? result : null;
7600
+ } catch {
7601
+ return null;
7602
+ }
7603
+ }
7531
7604
  async function build(options) {
7532
7605
  const root = process.cwd();
7533
7606
  if (!exists(root)) {
@@ -7576,6 +7649,14 @@ async function build(options) {
7576
7649
  const bundleData = readFileSync4(bundlePath);
7577
7650
  const checksum = createHash("sha256").update(bundleData).digest("hex");
7578
7651
  const raw = readRaw(root);
7652
+ const actionsPath = join6(root, "src", "actions.ts");
7653
+ if (existsSync6(actionsPath)) {
7654
+ const actionMeta = extractActionMetadata(actionsPath);
7655
+ if (actionMeta && Object.keys(actionMeta).length > 0) {
7656
+ raw.actions = actionMeta;
7657
+ console.log(source_default.blue(` Actions: ${Object.keys(actionMeta).join(", ")}`));
7658
+ }
7659
+ }
7579
7660
  writeWithBuild(distDir, raw, {
7580
7661
  checksum,
7581
7662
  size: bundleData.length,
@@ -7586,20 +7667,20 @@ async function build(options) {
7586
7667
  }
7587
7668
 
7588
7669
  // src/commands/dev.ts
7589
- import { existsSync as existsSync7, mkdirSync as mkdirSync3, writeFileSync as writeFileSync5, unlinkSync, readFileSync as readFileSync5, cpSync } from "fs";
7590
- import { join as join10 } from "path";
7670
+ import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
7671
+ import { join as join9 } from "path";
7591
7672
  import { createHash as createHash2 } from "crypto";
7592
7673
 
7593
- // node_modules/chokidar/index.js
7594
- import { EventEmitter } from "node:events";
7595
- import { stat as statcb, Stats } from "node:fs";
7596
- import { readdir as readdir2, stat as stat3 } from "node:fs/promises";
7597
- import * as sp2 from "node:path";
7674
+ // node_modules/chokidar/esm/index.js
7675
+ import { stat as statcb } from "fs";
7676
+ import { stat as stat3, readdir as readdir2 } from "fs/promises";
7677
+ import { EventEmitter } from "events";
7678
+ import * as sysPath2 from "path";
7598
7679
 
7599
- // node_modules/readdirp/index.js
7600
- import { lstat, readdir, realpath, stat } from "node:fs/promises";
7601
- import { join as pjoin, relative as prelative, resolve as presolve, sep as psep } from "node:path";
7680
+ // node_modules/readdirp/esm/index.js
7681
+ import { stat, lstat, readdir, realpath } from "node:fs/promises";
7602
7682
  import { Readable } from "node:stream";
7683
+ import { resolve as presolve, relative as prelative, join as pjoin, sep as psep } from "node:path";
7603
7684
  var EntryTypes = {
7604
7685
  FILE_TYPE: "files",
7605
7686
  DIR_TYPE: "directories",
@@ -7655,20 +7736,6 @@ var normalizeFilter = (filter) => {
7655
7736
  };
7656
7737
 
7657
7738
  class ReaddirpStream extends Readable {
7658
- parents;
7659
- reading;
7660
- parent;
7661
- _stat;
7662
- _maxDepth;
7663
- _wantsDir;
7664
- _wantsFile;
7665
- _wantsEverything;
7666
- _root;
7667
- _isDirent;
7668
- _statsProp;
7669
- _rdOptions;
7670
- _fileFilter;
7671
- _directoryFilter;
7672
7739
  constructor(options = {}) {
7673
7740
  super({
7674
7741
  objectMode: true,
@@ -7685,7 +7752,7 @@ class ReaddirpStream extends Readable {
7685
7752
  } else {
7686
7753
  this._stat = statMethod;
7687
7754
  }
7688
- this._maxDepth = opts.depth != null && Number.isSafeInteger(opts.depth) ? opts.depth : defaultOptions.depth;
7755
+ this._maxDepth = opts.depth ?? defaultOptions.depth;
7689
7756
  this._wantsDir = type ? DIR_TYPES.has(type) : false;
7690
7757
  this._wantsFile = type ? FILE_TYPES.has(type) : false;
7691
7758
  this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE;
@@ -7830,11 +7897,11 @@ function readdirp(root, options = {}) {
7830
7897
  return new ReaddirpStream(options);
7831
7898
  }
7832
7899
 
7833
- // node_modules/chokidar/handler.js
7834
- import { watch as fs_watch, unwatchFile, watchFile } from "node:fs";
7835
- import { realpath as fsrealpath, lstat as lstat2, open, stat as stat2 } from "node:fs/promises";
7836
- import { type as osType } from "node:os";
7837
- import * as sp from "node:path";
7900
+ // node_modules/chokidar/esm/handler.js
7901
+ import { watchFile, unwatchFile, watch as fs_watch } from "fs";
7902
+ import { open, stat as stat2, lstat as lstat2, realpath as fsrealpath } from "fs/promises";
7903
+ import * as sysPath from "path";
7904
+ import { type as osType } from "os";
7838
7905
  var STR_DATA = "data";
7839
7906
  var STR_END = "end";
7840
7907
  var STR_CLOSE = "close";
@@ -8126,7 +8193,7 @@ var binaryExtensions = new Set([
8126
8193
  "zip",
8127
8194
  "zipx"
8128
8195
  ]);
8129
- var isBinaryPath = (filePath) => binaryExtensions.has(sp.extname(filePath).slice(1).toLowerCase());
8196
+ var isBinaryPath = (filePath) => binaryExtensions.has(sysPath.extname(filePath).slice(1).toLowerCase());
8130
8197
  var foreach = (val, fn) => {
8131
8198
  if (val instanceof Set) {
8132
8199
  val.forEach(fn);
@@ -8164,7 +8231,7 @@ function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
8164
8231
  listener(path);
8165
8232
  emitRaw(rawEvent, evPath, { watchedPath: path });
8166
8233
  if (evPath && path !== evPath) {
8167
- fsWatchBroadcast(sp.resolve(path, evPath), KEY_LISTENERS, sp.join(path, evPath));
8234
+ fsWatchBroadcast(sysPath.resolve(path, evPath), KEY_LISTENERS, sysPath.join(path, evPath));
8168
8235
  }
8169
8236
  };
8170
8237
  try {
@@ -8279,19 +8346,17 @@ var setFsWatchFileListener = (path, fullPath, options, handlers) => {
8279
8346
  };
8280
8347
 
8281
8348
  class NodeFsHandler {
8282
- fsw;
8283
- _boundHandleError;
8284
8349
  constructor(fsW) {
8285
8350
  this.fsw = fsW;
8286
8351
  this._boundHandleError = (error2) => fsW._handleError(error2);
8287
8352
  }
8288
8353
  _watchWithNodeFs(path, listener) {
8289
8354
  const opts = this.fsw.options;
8290
- const directory = sp.dirname(path);
8291
- const basename4 = sp.basename(path);
8355
+ const directory = sysPath.dirname(path);
8356
+ const basename4 = sysPath.basename(path);
8292
8357
  const parent = this.fsw._getWatchedDir(directory);
8293
8358
  parent.add(basename4);
8294
- const absolutePath = sp.resolve(path);
8359
+ const absolutePath = sysPath.resolve(path);
8295
8360
  const options = {
8296
8361
  persistent: opts.persistent
8297
8362
  };
@@ -8318,8 +8383,8 @@ class NodeFsHandler {
8318
8383
  if (this.fsw.closed) {
8319
8384
  return;
8320
8385
  }
8321
- const dirname3 = sp.dirname(file);
8322
- const basename4 = sp.basename(file);
8386
+ const dirname3 = sysPath.dirname(file);
8387
+ const basename4 = sysPath.basename(file);
8323
8388
  const parent = this.fsw._getWatchedDir(dirname3);
8324
8389
  let prevStats = stats;
8325
8390
  if (parent.has(basename4))
@@ -8402,9 +8467,8 @@ class NodeFsHandler {
8402
8467
  this.fsw._symlinkPaths.set(full, true);
8403
8468
  }
8404
8469
  _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) {
8405
- directory = sp.join(directory, "");
8406
- const throttleKey = target ? `${directory}:${target}` : directory;
8407
- throttler = this.fsw._throttle("readdir", throttleKey, 1000);
8470
+ directory = sysPath.join(directory, "");
8471
+ throttler = this.fsw._throttle("readdir", directory, 1000);
8408
8472
  if (!throttler)
8409
8473
  return;
8410
8474
  const previous = this.fsw._getWatchedDir(wh.path);
@@ -8421,7 +8485,7 @@ class NodeFsHandler {
8421
8485
  return;
8422
8486
  }
8423
8487
  const item = entry.path;
8424
- let path = sp.join(directory, item);
8488
+ let path = sysPath.join(directory, item);
8425
8489
  current.add(item);
8426
8490
  if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path, item)) {
8427
8491
  return;
@@ -8432,7 +8496,7 @@ class NodeFsHandler {
8432
8496
  }
8433
8497
  if (item === target || !target && !previous.has(item)) {
8434
8498
  this.fsw._incrReadyCount();
8435
- path = sp.join(dir, sp.relative(dir, path));
8499
+ path = sysPath.join(dir, sysPath.relative(dir, path));
8436
8500
  this._addToNodeFs(path, initialAdd, wh, depth + 1);
8437
8501
  }
8438
8502
  }).on(EV.ERROR, this._boundHandleError);
@@ -8458,12 +8522,12 @@ class NodeFsHandler {
8458
8522
  });
8459
8523
  }
8460
8524
  async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath2) {
8461
- const parentDir = this.fsw._getWatchedDir(sp.dirname(dir));
8462
- const tracked = parentDir.has(sp.basename(dir));
8525
+ const parentDir = this.fsw._getWatchedDir(sysPath.dirname(dir));
8526
+ const tracked = parentDir.has(sysPath.basename(dir));
8463
8527
  if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) {
8464
8528
  this.fsw._emit(EV.ADD_DIR, dir, stats);
8465
8529
  }
8466
- parentDir.add(sp.basename(dir));
8530
+ parentDir.add(sysPath.basename(dir));
8467
8531
  this.fsw._getWatchedDir(dir);
8468
8532
  let throttler;
8469
8533
  let closer;
@@ -8504,7 +8568,7 @@ class NodeFsHandler {
8504
8568
  const follow = this.fsw.options.followSymlinks;
8505
8569
  let closer;
8506
8570
  if (stats.isDirectory()) {
8507
- const absPath = sp.resolve(path);
8571
+ const absPath = sysPath.resolve(path);
8508
8572
  const targetPath = follow ? await fsrealpath(path) : path;
8509
8573
  if (this.fsw.closed)
8510
8574
  return;
@@ -8518,14 +8582,14 @@ class NodeFsHandler {
8518
8582
  const targetPath = follow ? await fsrealpath(path) : path;
8519
8583
  if (this.fsw.closed)
8520
8584
  return;
8521
- const parent = sp.dirname(wh.watchPath);
8585
+ const parent = sysPath.dirname(wh.watchPath);
8522
8586
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
8523
8587
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
8524
8588
  closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath);
8525
8589
  if (this.fsw.closed)
8526
8590
  return;
8527
8591
  if (targetPath !== undefined) {
8528
- this.fsw._symlinkPaths.set(sp.resolve(path), targetPath);
8592
+ this.fsw._symlinkPaths.set(sysPath.resolve(path), targetPath);
8529
8593
  }
8530
8594
  } else {
8531
8595
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
@@ -8543,7 +8607,7 @@ class NodeFsHandler {
8543
8607
  }
8544
8608
  }
8545
8609
 
8546
- // node_modules/chokidar/index.js
8610
+ // node_modules/chokidar/esm/index.js
8547
8611
  /*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) */
8548
8612
  var SLASH = "/";
8549
8613
  var SLASH_SLASH = "//";
@@ -8551,7 +8615,7 @@ var ONE_DOT = ".";
8551
8615
  var TWO_DOTS = "..";
8552
8616
  var STRING_TYPE = "string";
8553
8617
  var BACK_SLASH_RE = /\\/g;
8554
- var DOUBLE_SLASH_RE = /\/\//g;
8618
+ var DOUBLE_SLASH_RE = /\/\//;
8555
8619
  var DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/;
8556
8620
  var REPLACER_RE = /^\.[/\\]/;
8557
8621
  function arrify(item) {
@@ -8570,11 +8634,11 @@ function createPattern(matcher) {
8570
8634
  if (matcher.path === string)
8571
8635
  return true;
8572
8636
  if (matcher.recursive) {
8573
- const relative3 = sp2.relative(matcher.path, string);
8637
+ const relative3 = sysPath2.relative(matcher.path, string);
8574
8638
  if (!relative3) {
8575
8639
  return false;
8576
8640
  }
8577
- return !relative3.startsWith("..") && !sp2.isAbsolute(relative3);
8641
+ return !relative3.startsWith("..") && !sysPath2.isAbsolute(relative3);
8578
8642
  }
8579
8643
  return false;
8580
8644
  };
@@ -8584,12 +8648,14 @@ function createPattern(matcher) {
8584
8648
  function normalizePath(path) {
8585
8649
  if (typeof path !== "string")
8586
8650
  throw new Error("string expected");
8587
- path = sp2.normalize(path);
8651
+ path = sysPath2.normalize(path);
8588
8652
  path = path.replace(/\\/g, "/");
8589
8653
  let prepend = false;
8590
8654
  if (path.startsWith("//"))
8591
8655
  prepend = true;
8592
- path = path.replace(DOUBLE_SLASH_RE, "/");
8656
+ const DOUBLE_SLASH_RE2 = /\/\//;
8657
+ while (path.match(DOUBLE_SLASH_RE2))
8658
+ path = path.replace(DOUBLE_SLASH_RE2, "/");
8593
8659
  if (prepend)
8594
8660
  path = "/" + path;
8595
8661
  return path;
@@ -8630,32 +8696,31 @@ var toUnix = (string) => {
8630
8696
  if (str.startsWith(SLASH_SLASH)) {
8631
8697
  prepend = true;
8632
8698
  }
8633
- str = str.replace(DOUBLE_SLASH_RE, SLASH);
8699
+ while (str.match(DOUBLE_SLASH_RE)) {
8700
+ str = str.replace(DOUBLE_SLASH_RE, SLASH);
8701
+ }
8634
8702
  if (prepend) {
8635
8703
  str = SLASH + str;
8636
8704
  }
8637
8705
  return str;
8638
8706
  };
8639
- var normalizePathToUnix = (path) => toUnix(sp2.normalize(toUnix(path)));
8707
+ var normalizePathToUnix = (path) => toUnix(sysPath2.normalize(toUnix(path)));
8640
8708
  var normalizeIgnored = (cwd = "") => (path) => {
8641
8709
  if (typeof path === "string") {
8642
- return normalizePathToUnix(sp2.isAbsolute(path) ? path : sp2.join(cwd, path));
8710
+ return normalizePathToUnix(sysPath2.isAbsolute(path) ? path : sysPath2.join(cwd, path));
8643
8711
  } else {
8644
8712
  return path;
8645
8713
  }
8646
8714
  };
8647
8715
  var getAbsolutePath = (path, cwd) => {
8648
- if (sp2.isAbsolute(path)) {
8716
+ if (sysPath2.isAbsolute(path)) {
8649
8717
  return path;
8650
8718
  }
8651
- return sp2.join(cwd, path);
8719
+ return sysPath2.join(cwd, path);
8652
8720
  };
8653
8721
  var EMPTY_SET = Object.freeze(new Set);
8654
8722
 
8655
8723
  class DirEntry {
8656
- path;
8657
- _removeWatcher;
8658
- items;
8659
8724
  constructor(dir, removeWatcher) {
8660
8725
  this.path = dir;
8661
8726
  this._removeWatcher = removeWatcher;
@@ -8680,7 +8745,7 @@ class DirEntry {
8680
8745
  await readdir2(dir);
8681
8746
  } catch (err) {
8682
8747
  if (this._removeWatcher) {
8683
- this._removeWatcher(sp2.dirname(dir), sp2.basename(dir));
8748
+ this._removeWatcher(sysPath2.dirname(dir), sysPath2.basename(dir));
8684
8749
  }
8685
8750
  }
8686
8751
  }
@@ -8708,19 +8773,12 @@ var STAT_METHOD_F = "stat";
8708
8773
  var STAT_METHOD_L = "lstat";
8709
8774
 
8710
8775
  class WatchHelper {
8711
- fsw;
8712
- path;
8713
- watchPath;
8714
- fullWatchPath;
8715
- dirParts;
8716
- followSymlinks;
8717
- statMethod;
8718
8776
  constructor(path, follow, fsw) {
8719
8777
  this.fsw = fsw;
8720
8778
  const watchPath = path;
8721
8779
  this.path = path = path.replace(REPLACER_RE, "");
8722
8780
  this.watchPath = watchPath;
8723
- this.fullWatchPath = sp2.resolve(watchPath);
8781
+ this.fullWatchPath = sysPath2.resolve(watchPath);
8724
8782
  this.dirParts = [];
8725
8783
  this.dirParts.forEach((parts) => {
8726
8784
  if (parts.length > 1)
@@ -8730,7 +8788,7 @@ class WatchHelper {
8730
8788
  this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L;
8731
8789
  }
8732
8790
  entryPath(entry) {
8733
- return sp2.join(this.watchPath, sp2.relative(this.watchPath, entry.fullPath));
8791
+ return sysPath2.join(this.watchPath, sysPath2.relative(this.watchPath, entry.fullPath));
8734
8792
  }
8735
8793
  filterPath(entry) {
8736
8794
  const { stats } = entry;
@@ -8745,24 +8803,6 @@ class WatchHelper {
8745
8803
  }
8746
8804
 
8747
8805
  class FSWatcher extends EventEmitter {
8748
- closed;
8749
- options;
8750
- _closers;
8751
- _ignoredPaths;
8752
- _throttled;
8753
- _streams;
8754
- _symlinkPaths;
8755
- _watched;
8756
- _pendingWrites;
8757
- _pendingUnlinks;
8758
- _readyCount;
8759
- _emitReady;
8760
- _closePromise;
8761
- _userIgnored;
8762
- _readyEmitted;
8763
- _emitRaw;
8764
- _boundRemove;
8765
- _nodeFsHandler;
8766
8806
  constructor(_opts = {}) {
8767
8807
  super();
8768
8808
  this.closed = false;
@@ -8871,7 +8911,7 @@ class FSWatcher extends EventEmitter {
8871
8911
  return;
8872
8912
  results.forEach((item) => {
8873
8913
  if (item)
8874
- this.add(sp2.dirname(item), sp2.basename(_origAdd || item));
8914
+ this.add(sysPath2.dirname(item), sysPath2.basename(_origAdd || item));
8875
8915
  });
8876
8916
  });
8877
8917
  return this;
@@ -8882,10 +8922,10 @@ class FSWatcher extends EventEmitter {
8882
8922
  const paths = unifyPaths(paths_);
8883
8923
  const { cwd } = this.options;
8884
8924
  paths.forEach((path) => {
8885
- if (!sp2.isAbsolute(path) && !this._closers.has(path)) {
8925
+ if (!sysPath2.isAbsolute(path) && !this._closers.has(path)) {
8886
8926
  if (cwd)
8887
- path = sp2.join(cwd, path);
8888
- path = sp2.resolve(path);
8927
+ path = sysPath2.join(cwd, path);
8928
+ path = sysPath2.resolve(path);
8889
8929
  }
8890
8930
  this._closePath(path);
8891
8931
  this._addIgnoredPath(path);
@@ -8929,7 +8969,7 @@ class FSWatcher extends EventEmitter {
8929
8969
  getWatched() {
8930
8970
  const watchList = {};
8931
8971
  this._watched.forEach((entry, dir) => {
8932
- const key = this.options.cwd ? sp2.relative(this.options.cwd, dir) : dir;
8972
+ const key = this.options.cwd ? sysPath2.relative(this.options.cwd, dir) : dir;
8933
8973
  const index = key || ONE_DOT;
8934
8974
  watchList[index] = entry.getChildren().sort();
8935
8975
  });
@@ -8945,9 +8985,9 @@ class FSWatcher extends EventEmitter {
8945
8985
  return;
8946
8986
  const opts = this.options;
8947
8987
  if (isWindows)
8948
- path = sp2.normalize(path);
8988
+ path = sysPath2.normalize(path);
8949
8989
  if (opts.cwd)
8950
- path = sp2.relative(opts.cwd, path);
8990
+ path = sysPath2.relative(opts.cwd, path);
8951
8991
  const args = [path];
8952
8992
  if (stats != null)
8953
8993
  args.push(stats);
@@ -8998,7 +9038,7 @@ class FSWatcher extends EventEmitter {
8998
9038
  return this;
8999
9039
  }
9000
9040
  if (opts.alwaysStat && stats === undefined && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
9001
- const fullPath = opts.cwd ? sp2.join(opts.cwd, path) : path;
9041
+ const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path) : path;
9002
9042
  let stats2;
9003
9043
  try {
9004
9044
  stats2 = await stat3(fullPath);
@@ -9054,8 +9094,8 @@ class FSWatcher extends EventEmitter {
9054
9094
  const pollInterval = awf.pollInterval;
9055
9095
  let timeoutHandler;
9056
9096
  let fullPath = path;
9057
- if (this.options.cwd && !sp2.isAbsolute(path)) {
9058
- fullPath = sp2.join(this.options.cwd, path);
9097
+ if (this.options.cwd && !sysPath2.isAbsolute(path)) {
9098
+ fullPath = sysPath2.join(this.options.cwd, path);
9059
9099
  }
9060
9100
  const now = new Date;
9061
9101
  const writes = this._pendingWrites;
@@ -9112,7 +9152,7 @@ class FSWatcher extends EventEmitter {
9112
9152
  return new WatchHelper(path, this.options.followSymlinks, this);
9113
9153
  }
9114
9154
  _getWatchedDir(directory) {
9115
- const dir = sp2.resolve(directory);
9155
+ const dir = sysPath2.resolve(directory);
9116
9156
  if (!this._watched.has(dir))
9117
9157
  this._watched.set(dir, new DirEntry(dir, this._boundRemove));
9118
9158
  return this._watched.get(dir);
@@ -9123,8 +9163,8 @@ class FSWatcher extends EventEmitter {
9123
9163
  return Boolean(Number(stats.mode) & 256);
9124
9164
  }
9125
9165
  _remove(directory, item, isDirectory) {
9126
- const path = sp2.join(directory, item);
9127
- const fullPath = sp2.resolve(path);
9166
+ const path = sysPath2.join(directory, item);
9167
+ const fullPath = sysPath2.resolve(path);
9128
9168
  isDirectory = isDirectory != null ? isDirectory : this._watched.has(path) || this._watched.has(fullPath);
9129
9169
  if (!this._throttle("remove", path, 100))
9130
9170
  return;
@@ -9142,7 +9182,7 @@ class FSWatcher extends EventEmitter {
9142
9182
  }
9143
9183
  let relPath = path;
9144
9184
  if (this.options.cwd)
9145
- relPath = sp2.relative(this.options.cwd, path);
9185
+ relPath = sysPath2.relative(this.options.cwd, path);
9146
9186
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
9147
9187
  const event = this._pendingWrites.get(relPath).cancelWait();
9148
9188
  if (event === EVENTS.ADD)
@@ -9157,8 +9197,8 @@ class FSWatcher extends EventEmitter {
9157
9197
  }
9158
9198
  _closePath(path) {
9159
9199
  this._closeFile(path);
9160
- const dir = sp2.dirname(path);
9161
- this._getWatchedDir(dir).remove(sp2.basename(path));
9200
+ const dir = sysPath2.dirname(path);
9201
+ this._getWatchedDir(dir).remove(sysPath2.basename(path));
9162
9202
  }
9163
9203
  _closeFile(path) {
9164
9204
  const closers = this._closers.get(path);
@@ -9201,62 +9241,11 @@ function watch(paths, options = {}) {
9201
9241
  return watcher;
9202
9242
  }
9203
9243
 
9204
- // src/lib/appdir.ts
9205
- import { join as join9 } from "path";
9206
- import { homedir } from "os";
9207
- import { platform as platform2 } from "process";
9208
- function dataDir() {
9209
- if (process.env.CONSTRUCT_DATA_DIR)
9210
- return process.env.CONSTRUCT_DATA_DIR;
9211
- const home = homedir();
9212
- switch (platform2) {
9213
- case "darwin":
9214
- return join9(home, "Library", "Application Support", "Construct");
9215
- case "win32": {
9216
- const appData = process.env.APPDATA || join9(home, "AppData", "Roaming");
9217
- return join9(appData, "Construct");
9218
- }
9219
- default: {
9220
- const xdg = process.env.XDG_DATA_HOME || join9(home, ".local", "share");
9221
- return join9(xdg, "construct");
9222
- }
9223
- }
9224
- }
9225
- function devDataDir() {
9226
- if (process.env.CONSTRUCT_DATA_DIR)
9227
- return process.env.CONSTRUCT_DATA_DIR;
9228
- const home = homedir();
9229
- switch (platform2) {
9230
- case "darwin":
9231
- return join9(home, "Library", "Application Support", "Construct Dev");
9232
- case "win32": {
9233
- const appData = process.env.APPDATA || join9(home, "AppData", "Roaming");
9234
- return join9(appData, "Construct Dev");
9235
- }
9236
- default: {
9237
- const xdg = process.env.XDG_DATA_HOME || join9(home, ".local", "share");
9238
- return join9(xdg, "construct-dev");
9239
- }
9240
- }
9241
- }
9242
- function spacesDir() {
9243
- return join9(dataDir(), "spaces");
9244
- }
9245
- function devSpacesDir() {
9246
- return join9(devDataDir(), "spaces");
9247
- }
9248
- function spaceDir(spaceId) {
9249
- return join9(spacesDir(), spaceId);
9250
- }
9251
- function devSpaceDir(spaceId) {
9252
- return join9(devSpacesDir(), spaceId);
9253
- }
9254
-
9255
9244
  // src/commands/dev.ts
9256
9245
  function getEntryWatchPaths(root) {
9257
9246
  return [
9258
- join10(root, MANIFEST_FILE),
9259
- join10(root, "src", "actions.ts")
9247
+ join9(root, MANIFEST_FILE),
9248
+ join9(root, "src", "actions.ts")
9260
9249
  ];
9261
9250
  }
9262
9251
  async function dev() {
@@ -9270,23 +9259,6 @@ async function dev() {
9270
9259
  console.log(source_default.blue(`Dev mode — ${m.id} (${rt.name} ${rt.version})`));
9271
9260
  ensureDeps(root, rt);
9272
9261
  writeEntry(root, m);
9273
- const installDir = spaceDir(m.id);
9274
- mkdirSync3(installDir, { recursive: true });
9275
- const devMarker = join10(installDir, ".dev");
9276
- writeFileSync5(devMarker, "dev");
9277
- const cleanup = () => {
9278
- try {
9279
- unlinkSync(devMarker);
9280
- } catch {}
9281
- };
9282
- process.on("SIGINT", () => {
9283
- cleanup();
9284
- process.exit(0);
9285
- });
9286
- process.on("SIGTERM", () => {
9287
- cleanup();
9288
- process.exit(0);
9289
- });
9290
9262
  const vite = watchCmd(root, rt);
9291
9263
  vite.stdout?.on("data", (data) => {
9292
9264
  process.stdout.write(source_default.dim(data.toString()));
@@ -9312,8 +9284,8 @@ async function dev() {
9312
9284
  }
9313
9285
  console.log(source_default.blue("Actions changed — entry regenerated"));
9314
9286
  });
9315
- const distDir = join10(root, "dist");
9316
- const bundleFile = join10(distDir, `space-${m.id}.iife.js`);
9287
+ const distDir = join9(root, "dist");
9288
+ const bundleFile = join9(distDir, `space-${m.id}.iife.js`);
9317
9289
  let lastChecksum = "";
9318
9290
  const distWatcher = watch(bundleFile, { ignoreInitial: false });
9319
9291
  distWatcher.on("all", () => {
@@ -9331,32 +9303,47 @@ async function dev() {
9331
9303
  hostApiVersion: "0.2.0",
9332
9304
  builtAt: new Date().toISOString()
9333
9305
  });
9334
- mkdirSync3(installDir, { recursive: true });
9335
- cpSync(distDir, installDir, { recursive: true });
9336
- writeFileSync5(join10(installDir, ".dev"), "dev");
9337
- const configAgent = join10(root, "config.agent");
9338
- if (existsSync7(configAgent)) {
9339
- cpSync(configAgent, join10(installDir, "config.agent"));
9340
- }
9341
- const devInstall = devSpaceDir(m.id);
9342
- const devParent = join10(devInstall, "..");
9343
- if (existsSync7(devParent)) {
9344
- mkdirSync3(devInstall, { recursive: true });
9345
- cpSync(distDir, devInstall, { recursive: true });
9346
- if (existsSync7(configAgent)) {
9347
- cpSync(configAgent, join10(devInstall, "config.agent"));
9348
- }
9349
- }
9350
- console.log(source_default.green(`Installed → ${m.id}`));
9306
+ console.log(source_default.green(`Built → dist/ (${(bundleData.length / 1024).toFixed(1)} KB)`));
9351
9307
  });
9352
9308
  console.log(source_default.green("Watching for changes... (Ctrl+C to stop)"));
9309
+ console.log(source_default.dim("Use the Preview button in Construct to open the Space Runner"));
9353
9310
  await new Promise(() => {});
9354
9311
  }
9355
9312
 
9356
9313
  // src/commands/run.ts
9357
- import { existsSync as existsSync8, cpSync as cpSync2, mkdirSync as mkdirSync4 } from "fs";
9314
+ import { existsSync as existsSync8, cpSync, mkdirSync as mkdirSync3 } from "fs";
9358
9315
  import { join as join11 } from "path";
9359
- function run() {
9316
+
9317
+ // src/lib/appdir.ts
9318
+ import { join as join10 } from "path";
9319
+ import { homedir } from "os";
9320
+ import { platform as platform2 } from "process";
9321
+ function dataDir() {
9322
+ if (process.env.CONSTRUCT_DATA_DIR)
9323
+ return process.env.CONSTRUCT_DATA_DIR;
9324
+ const home = homedir();
9325
+ switch (platform2) {
9326
+ case "darwin":
9327
+ return join10(home, "Library", "Application Support", "Construct");
9328
+ case "win32": {
9329
+ const appData = process.env.APPDATA || join10(home, "AppData", "Roaming");
9330
+ return join10(appData, "Construct");
9331
+ }
9332
+ default: {
9333
+ const xdg = process.env.XDG_DATA_HOME || join10(home, ".local", "share");
9334
+ return join10(xdg, "construct");
9335
+ }
9336
+ }
9337
+ }
9338
+ function spacesDir() {
9339
+ return join10(dataDir(), "spaces");
9340
+ }
9341
+ function spaceDir(spaceId) {
9342
+ return join10(spacesDir(), spaceId);
9343
+ }
9344
+
9345
+ // src/commands/run.ts
9346
+ function install() {
9360
9347
  const root = process.cwd();
9361
9348
  if (!exists(root)) {
9362
9349
  console.error(source_default.red("No space.manifest.json found in current directory"));
@@ -9373,18 +9360,18 @@ function run() {
9373
9360
  bundleAgentDir(agentDir, distDir);
9374
9361
  }
9375
9362
  const installDir = spaceDir(m.id);
9376
- mkdirSync4(installDir, { recursive: true });
9377
- cpSync2(distDir, installDir, { recursive: true });
9378
- console.log(source_default.green(`Installed ${m.name} to ${installDir}`));
9363
+ mkdirSync3(installDir, { recursive: true });
9364
+ cpSync(distDir, installDir, { recursive: true });
9365
+ console.log(source_default.green(`Installed ${m.name} ${installDir}`));
9379
9366
  console.log(source_default.dim(" Restart Construct to load the updated space."));
9380
9367
  }
9381
9368
 
9382
9369
  // src/commands/publish.ts
9383
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync7, statSync as statSync5, unlinkSync as unlinkSync3 } from "fs";
9370
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync6, statSync as statSync4, unlinkSync as unlinkSync2 } from "fs";
9384
9371
  import { join as join14, basename as basename6 } from "path";
9385
9372
 
9386
9373
  // src/lib/auth.ts
9387
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, unlinkSync as unlinkSync2, existsSync as existsSync9 } from "fs";
9374
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, unlinkSync, existsSync as existsSync9 } from "fs";
9388
9375
  import { join as join12, dirname as dirname4 } from "path";
9389
9376
  var CREDENTIALS_FILE = "credentials.json";
9390
9377
  var DEFAULT_PORTAL = "https://developer.construct.space";
@@ -9393,8 +9380,8 @@ function credentialsPath() {
9393
9380
  }
9394
9381
  function store(creds) {
9395
9382
  const path = credentialsPath();
9396
- mkdirSync5(dirname4(path), { recursive: true });
9397
- writeFileSync6(path, JSON.stringify(creds, null, 2) + `
9383
+ mkdirSync4(dirname4(path), { recursive: true });
9384
+ writeFileSync5(path, JSON.stringify(creds, null, 2) + `
9398
9385
  `, { mode: 384 });
9399
9386
  }
9400
9387
  function load2() {
@@ -9419,11 +9406,11 @@ function isAuthenticated() {
9419
9406
  function clear() {
9420
9407
  const path = credentialsPath();
9421
9408
  if (existsSync9(path))
9422
- unlinkSync2(path);
9409
+ unlinkSync(path);
9423
9410
  }
9424
9411
 
9425
9412
  // src/lib/pack.ts
9426
- import { readdirSync as readdirSync3, statSync as statSync4, existsSync as existsSync10 } from "fs";
9413
+ import { readdirSync as readdirSync3, statSync as statSync3, existsSync as existsSync10 } from "fs";
9427
9414
  import { join as join13 } from "path";
9428
9415
  import { tmpdir } from "os";
9429
9416
  import { execSync as execSync3 } from "child_process";
@@ -9466,7 +9453,7 @@ async function packSource(root) {
9466
9453
  entries.push(name);
9467
9454
  }
9468
9455
  for (const entry of readdirSync3(root)) {
9469
- if (statSync4(join13(root, entry)).isDirectory())
9456
+ if (statSync3(join13(root, entry)).isDirectory())
9470
9457
  continue;
9471
9458
  if (allowedRootFiles.includes(entry))
9472
9459
  continue;
@@ -9486,7 +9473,7 @@ async function packSource(root) {
9486
9473
  const excludes = "--exclude=node_modules --exclude=dist --exclude=.git --exclude=*.env --exclude=*.log --exclude=*.lock --exclude=*.lockb";
9487
9474
  const cmd = `tar czf "${tarballPath}" ${excludes} ${validEntries.join(" ")}`;
9488
9475
  execSync3(cmd, { cwd: root });
9489
- const size = statSync4(tarballPath).size;
9476
+ const size = statSync3(tarballPath).size;
9490
9477
  if (size > MAX_SIZE) {
9491
9478
  throw new Error(`Source exceeds maximum size of ${MAX_SIZE / 1024 / 1024}MB`);
9492
9479
  }
@@ -9522,7 +9509,7 @@ function setVersionInFiles(root, oldVer, newVer) {
9522
9509
  const path = join14(root, file);
9523
9510
  try {
9524
9511
  const data = readFileSync7(path, "utf-8");
9525
- writeFileSync7(path, data.replace(oldStr, newStr));
9512
+ writeFileSync6(path, data.replace(oldStr, newStr));
9526
9513
  } catch {}
9527
9514
  }
9528
9515
  }
@@ -9626,7 +9613,7 @@ async function publish(options) {
9626
9613
  let tarballPath;
9627
9614
  try {
9628
9615
  tarballPath = await packSource(root);
9629
- const size = statSync5(tarballPath).size;
9616
+ const size = statSync4(tarballPath).size;
9630
9617
  spinner.succeed(`Source packed (${formatBytes(size)})`);
9631
9618
  } catch (err) {
9632
9619
  spinner.fail("Pack failed");
@@ -9636,7 +9623,7 @@ async function publish(options) {
9636
9623
  const uploadSpinner = ora("Uploading & building...").start();
9637
9624
  try {
9638
9625
  const result = await uploadSource(creds.portal, creds.token, tarballPath, m);
9639
- unlinkSync3(tarballPath);
9626
+ unlinkSync2(tarballPath);
9640
9627
  gitSafe(root, "tag", `v${m.version}`);
9641
9628
  gitSafe(root, "push", "origin", `v${m.version}`);
9642
9629
  if (result.status === "approved" || result.status === "pending_review") {
@@ -9658,7 +9645,7 @@ async function publish(options) {
9658
9645
  }
9659
9646
  } catch (err) {
9660
9647
  uploadSpinner.fail("Upload failed");
9661
- unlinkSync3(tarballPath);
9648
+ unlinkSync2(tarballPath);
9662
9649
  console.error(source_default.red(err.message));
9663
9650
  process.exit(1);
9664
9651
  }
@@ -9916,7 +9903,7 @@ function update() {
9916
9903
  }
9917
9904
 
9918
9905
  // src/commands/graph/init.ts
9919
- import { existsSync as existsSync14, readFileSync as readFileSync10, writeFileSync as writeFileSync8, mkdirSync as mkdirSync6 } from "fs";
9906
+ import { existsSync as existsSync14, readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync5 } from "fs";
9920
9907
  import { join as join18 } from "path";
9921
9908
  import { execSync as execSync6 } from "child_process";
9922
9909
  function graphInit() {
@@ -9928,10 +9915,10 @@ function graphInit() {
9928
9915
  }
9929
9916
  const m = read(root);
9930
9917
  const modelsDir = join18(root, "src", "models");
9931
- mkdirSync6(modelsDir, { recursive: true });
9918
+ mkdirSync5(modelsDir, { recursive: true });
9932
9919
  const indexPath = join18(modelsDir, "index.ts");
9933
9920
  if (!existsSync14(indexPath)) {
9934
- writeFileSync8(indexPath, `// Data models for ${m.name}
9921
+ writeFileSync7(indexPath, `// Data models for ${m.name}
9935
9922
  // Generated by construct graph init
9936
9923
 
9937
9924
  // Export your models here:
@@ -9948,7 +9935,7 @@ function graphInit() {
9948
9935
  version = execSync6("npm view @construct-space/graph version", { encoding: "utf-8" }).trim();
9949
9936
  } catch {}
9950
9937
  pkg.dependencies["@construct-space/graph"] = `^${version}`;
9951
- writeFileSync8(pkgPath, JSON.stringify(pkg, null, 2) + `
9938
+ writeFileSync7(pkgPath, JSON.stringify(pkg, null, 2) + `
9952
9939
  `);
9953
9940
  console.log(source_default.blue(`Added @construct-space/graph@^${version} to dependencies`));
9954
9941
  } else {
@@ -9969,7 +9956,7 @@ function graphInit() {
9969
9956
  }
9970
9957
 
9971
9958
  // src/commands/graph/generate.ts
9972
- import { existsSync as existsSync15, readFileSync as readFileSync11, writeFileSync as writeFileSync9, mkdirSync as mkdirSync7 } from "fs";
9959
+ import { existsSync as existsSync15, readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync6 } from "fs";
9973
9960
  import { join as join19 } from "path";
9974
9961
  var FIELD_TYPES = {
9975
9962
  string: "field.string()",
@@ -10123,13 +10110,13 @@ function generate2(modelName, fieldSpecs, options) {
10123
10110
  const content = lines.join(`
10124
10111
  `);
10125
10112
  const modelsDir = join19(root, "src", "models");
10126
- mkdirSync7(modelsDir, { recursive: true });
10113
+ mkdirSync6(modelsDir, { recursive: true });
10127
10114
  const filePath = join19(modelsDir, `${name}.ts`);
10128
10115
  if (existsSync15(filePath)) {
10129
10116
  console.log(source_default.yellow(` Model file already exists: src/models/${name}.ts`));
10130
10117
  console.log(source_default.dim(" Overwriting..."));
10131
10118
  }
10132
- writeFileSync9(filePath, content);
10119
+ writeFileSync8(filePath, content);
10133
10120
  console.log(source_default.green(` Created src/models/${name}.ts`));
10134
10121
  updateBarrel(modelsDir, name);
10135
10122
  console.log();
@@ -10148,11 +10135,11 @@ function updateBarrel(modelsDir, modelName) {
10148
10135
  const content = readFileSync11(indexPath, "utf-8");
10149
10136
  if (content.includes(exportLine))
10150
10137
  return;
10151
- writeFileSync9(indexPath, content.trimEnd() + `
10138
+ writeFileSync8(indexPath, content.trimEnd() + `
10152
10139
  ` + exportLine + `
10153
10140
  `);
10154
10141
  } else {
10155
- writeFileSync9(indexPath, exportLine + `
10142
+ writeFileSync8(indexPath, exportLine + `
10156
10143
  `);
10157
10144
  }
10158
10145
  console.log(source_default.dim(` Updated src/models/index.ts`));
@@ -10442,13 +10429,13 @@ function parseModelFields(content, fileName) {
10442
10429
  }
10443
10430
 
10444
10431
  // src/index.ts
10445
- var VERSION = "1.0.7";
10432
+ var VERSION = "1.1.2";
10446
10433
  var program2 = new Command;
10447
10434
  program2.name("construct").description("Construct CLI — scaffold, build, develop, and publish spaces").version(VERSION);
10448
- program2.command("scaffold [name]").alias("new").alias("create").description("Create a new Construct space project").option("--with-tests", "Include E2E testing boilerplate").action(async (name, opts) => scaffold(name, opts));
10435
+ program2.command("scaffold [name]").alias("new").alias("create").description("Create a new Construct space project").option("--with-tests", "Include E2E testing boilerplate").option("--full", "Full preset: multiple pages, extra skills, widget templates").action(async (name, opts) => scaffold(name, opts));
10449
10436
  program2.command("build").description("Build the space (generate entry + run Vite)").option("--entry-only", "Only generate src/entry.ts").action(async (opts) => build(opts));
10450
10437
  program2.command("dev").description("Start dev mode with file watching and live reload").action(async () => dev());
10451
- program2.command("run").description("Install built space to Construct spaces directory").action(() => run());
10438
+ program2.command("install").alias("run").description("Install built space to Construct spaces directory").action(() => install());
10452
10439
  program2.command("publish").description("Publish a space to the Construct registry").option("-y, --yes", "Skip all confirmation prompts").option("--bump <type>", "Auto-bump version (patch, minor, major)").action(async (opts) => publish(opts));
10453
10440
  program2.command("validate").description("Validate space.manifest.json").action(() => validate3());
10454
10441
  program2.command("check").description("Run type-check (vue-tsc) and linter (eslint)").action(() => check());
@@ -10462,10 +10449,10 @@ graph.command("generate <model> [fields...]").alias("g").description("Generate a
10462
10449
  graph.command("push").description("Register models with the Graph service").action(async () => graphPush());
10463
10450
  graph.command("migrate").description("Compare local models with server schema and apply changes").option("--apply", "Apply destructive changes (drop columns, alter constraints)").action(async (opts) => graphMigrate(opts));
10464
10451
  var space = program2.command("space").description("Space development commands");
10465
- space.command("scaffold [name]").alias("new").alias("create").option("--with-tests", "Include E2E testing boilerplate").action(async (name, opts) => scaffold(name, opts));
10452
+ space.command("scaffold [name]").alias("new").alias("create").option("--with-tests", "Include E2E testing boilerplate").option("--full", "Full preset: multiple pages, extra skills, widget templates").action(async (name, opts) => scaffold(name, opts));
10466
10453
  space.command("build").option("--entry-only").action(async (opts) => build(opts));
10467
10454
  space.command("dev").action(async () => dev());
10468
- space.command("run").action(() => run());
10455
+ space.command("install").alias("run").action(() => install());
10469
10456
  space.command("publish").option("-y, --yes").option("--bump <type>").action(async (opts) => publish(opts));
10470
10457
  space.command("validate").action(() => validate3());
10471
10458
  space.command("check").action(() => check());