@construct-space/cli 1.0.7 → 1.1.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.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
@@ -7586,20 +7624,20 @@ async function build(options) {
7586
7624
  }
7587
7625
 
7588
7626
  // 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";
7627
+ import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
7628
+ import { join as join9 } from "path";
7591
7629
  import { createHash as createHash2 } from "crypto";
7592
7630
 
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";
7631
+ // node_modules/chokidar/esm/index.js
7632
+ import { stat as statcb } from "fs";
7633
+ import { stat as stat3, readdir as readdir2 } from "fs/promises";
7634
+ import { EventEmitter } from "events";
7635
+ import * as sysPath2 from "path";
7598
7636
 
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";
7637
+ // node_modules/readdirp/esm/index.js
7638
+ import { stat, lstat, readdir, realpath } from "node:fs/promises";
7602
7639
  import { Readable } from "node:stream";
7640
+ import { resolve as presolve, relative as prelative, join as pjoin, sep as psep } from "node:path";
7603
7641
  var EntryTypes = {
7604
7642
  FILE_TYPE: "files",
7605
7643
  DIR_TYPE: "directories",
@@ -7655,20 +7693,6 @@ var normalizeFilter = (filter) => {
7655
7693
  };
7656
7694
 
7657
7695
  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
7696
  constructor(options = {}) {
7673
7697
  super({
7674
7698
  objectMode: true,
@@ -7685,7 +7709,7 @@ class ReaddirpStream extends Readable {
7685
7709
  } else {
7686
7710
  this._stat = statMethod;
7687
7711
  }
7688
- this._maxDepth = opts.depth != null && Number.isSafeInteger(opts.depth) ? opts.depth : defaultOptions.depth;
7712
+ this._maxDepth = opts.depth ?? defaultOptions.depth;
7689
7713
  this._wantsDir = type ? DIR_TYPES.has(type) : false;
7690
7714
  this._wantsFile = type ? FILE_TYPES.has(type) : false;
7691
7715
  this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE;
@@ -7830,11 +7854,11 @@ function readdirp(root, options = {}) {
7830
7854
  return new ReaddirpStream(options);
7831
7855
  }
7832
7856
 
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";
7857
+ // node_modules/chokidar/esm/handler.js
7858
+ import { watchFile, unwatchFile, watch as fs_watch } from "fs";
7859
+ import { open, stat as stat2, lstat as lstat2, realpath as fsrealpath } from "fs/promises";
7860
+ import * as sysPath from "path";
7861
+ import { type as osType } from "os";
7838
7862
  var STR_DATA = "data";
7839
7863
  var STR_END = "end";
7840
7864
  var STR_CLOSE = "close";
@@ -8126,7 +8150,7 @@ var binaryExtensions = new Set([
8126
8150
  "zip",
8127
8151
  "zipx"
8128
8152
  ]);
8129
- var isBinaryPath = (filePath) => binaryExtensions.has(sp.extname(filePath).slice(1).toLowerCase());
8153
+ var isBinaryPath = (filePath) => binaryExtensions.has(sysPath.extname(filePath).slice(1).toLowerCase());
8130
8154
  var foreach = (val, fn) => {
8131
8155
  if (val instanceof Set) {
8132
8156
  val.forEach(fn);
@@ -8164,7 +8188,7 @@ function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
8164
8188
  listener(path);
8165
8189
  emitRaw(rawEvent, evPath, { watchedPath: path });
8166
8190
  if (evPath && path !== evPath) {
8167
- fsWatchBroadcast(sp.resolve(path, evPath), KEY_LISTENERS, sp.join(path, evPath));
8191
+ fsWatchBroadcast(sysPath.resolve(path, evPath), KEY_LISTENERS, sysPath.join(path, evPath));
8168
8192
  }
8169
8193
  };
8170
8194
  try {
@@ -8279,19 +8303,17 @@ var setFsWatchFileListener = (path, fullPath, options, handlers) => {
8279
8303
  };
8280
8304
 
8281
8305
  class NodeFsHandler {
8282
- fsw;
8283
- _boundHandleError;
8284
8306
  constructor(fsW) {
8285
8307
  this.fsw = fsW;
8286
8308
  this._boundHandleError = (error2) => fsW._handleError(error2);
8287
8309
  }
8288
8310
  _watchWithNodeFs(path, listener) {
8289
8311
  const opts = this.fsw.options;
8290
- const directory = sp.dirname(path);
8291
- const basename4 = sp.basename(path);
8312
+ const directory = sysPath.dirname(path);
8313
+ const basename4 = sysPath.basename(path);
8292
8314
  const parent = this.fsw._getWatchedDir(directory);
8293
8315
  parent.add(basename4);
8294
- const absolutePath = sp.resolve(path);
8316
+ const absolutePath = sysPath.resolve(path);
8295
8317
  const options = {
8296
8318
  persistent: opts.persistent
8297
8319
  };
@@ -8318,8 +8340,8 @@ class NodeFsHandler {
8318
8340
  if (this.fsw.closed) {
8319
8341
  return;
8320
8342
  }
8321
- const dirname3 = sp.dirname(file);
8322
- const basename4 = sp.basename(file);
8343
+ const dirname3 = sysPath.dirname(file);
8344
+ const basename4 = sysPath.basename(file);
8323
8345
  const parent = this.fsw._getWatchedDir(dirname3);
8324
8346
  let prevStats = stats;
8325
8347
  if (parent.has(basename4))
@@ -8402,9 +8424,8 @@ class NodeFsHandler {
8402
8424
  this.fsw._symlinkPaths.set(full, true);
8403
8425
  }
8404
8426
  _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);
8427
+ directory = sysPath.join(directory, "");
8428
+ throttler = this.fsw._throttle("readdir", directory, 1000);
8408
8429
  if (!throttler)
8409
8430
  return;
8410
8431
  const previous = this.fsw._getWatchedDir(wh.path);
@@ -8421,7 +8442,7 @@ class NodeFsHandler {
8421
8442
  return;
8422
8443
  }
8423
8444
  const item = entry.path;
8424
- let path = sp.join(directory, item);
8445
+ let path = sysPath.join(directory, item);
8425
8446
  current.add(item);
8426
8447
  if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path, item)) {
8427
8448
  return;
@@ -8432,7 +8453,7 @@ class NodeFsHandler {
8432
8453
  }
8433
8454
  if (item === target || !target && !previous.has(item)) {
8434
8455
  this.fsw._incrReadyCount();
8435
- path = sp.join(dir, sp.relative(dir, path));
8456
+ path = sysPath.join(dir, sysPath.relative(dir, path));
8436
8457
  this._addToNodeFs(path, initialAdd, wh, depth + 1);
8437
8458
  }
8438
8459
  }).on(EV.ERROR, this._boundHandleError);
@@ -8458,12 +8479,12 @@ class NodeFsHandler {
8458
8479
  });
8459
8480
  }
8460
8481
  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));
8482
+ const parentDir = this.fsw._getWatchedDir(sysPath.dirname(dir));
8483
+ const tracked = parentDir.has(sysPath.basename(dir));
8463
8484
  if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) {
8464
8485
  this.fsw._emit(EV.ADD_DIR, dir, stats);
8465
8486
  }
8466
- parentDir.add(sp.basename(dir));
8487
+ parentDir.add(sysPath.basename(dir));
8467
8488
  this.fsw._getWatchedDir(dir);
8468
8489
  let throttler;
8469
8490
  let closer;
@@ -8504,7 +8525,7 @@ class NodeFsHandler {
8504
8525
  const follow = this.fsw.options.followSymlinks;
8505
8526
  let closer;
8506
8527
  if (stats.isDirectory()) {
8507
- const absPath = sp.resolve(path);
8528
+ const absPath = sysPath.resolve(path);
8508
8529
  const targetPath = follow ? await fsrealpath(path) : path;
8509
8530
  if (this.fsw.closed)
8510
8531
  return;
@@ -8518,14 +8539,14 @@ class NodeFsHandler {
8518
8539
  const targetPath = follow ? await fsrealpath(path) : path;
8519
8540
  if (this.fsw.closed)
8520
8541
  return;
8521
- const parent = sp.dirname(wh.watchPath);
8542
+ const parent = sysPath.dirname(wh.watchPath);
8522
8543
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
8523
8544
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
8524
8545
  closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath);
8525
8546
  if (this.fsw.closed)
8526
8547
  return;
8527
8548
  if (targetPath !== undefined) {
8528
- this.fsw._symlinkPaths.set(sp.resolve(path), targetPath);
8549
+ this.fsw._symlinkPaths.set(sysPath.resolve(path), targetPath);
8529
8550
  }
8530
8551
  } else {
8531
8552
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
@@ -8543,7 +8564,7 @@ class NodeFsHandler {
8543
8564
  }
8544
8565
  }
8545
8566
 
8546
- // node_modules/chokidar/index.js
8567
+ // node_modules/chokidar/esm/index.js
8547
8568
  /*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) */
8548
8569
  var SLASH = "/";
8549
8570
  var SLASH_SLASH = "//";
@@ -8551,7 +8572,7 @@ var ONE_DOT = ".";
8551
8572
  var TWO_DOTS = "..";
8552
8573
  var STRING_TYPE = "string";
8553
8574
  var BACK_SLASH_RE = /\\/g;
8554
- var DOUBLE_SLASH_RE = /\/\//g;
8575
+ var DOUBLE_SLASH_RE = /\/\//;
8555
8576
  var DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/;
8556
8577
  var REPLACER_RE = /^\.[/\\]/;
8557
8578
  function arrify(item) {
@@ -8570,11 +8591,11 @@ function createPattern(matcher) {
8570
8591
  if (matcher.path === string)
8571
8592
  return true;
8572
8593
  if (matcher.recursive) {
8573
- const relative3 = sp2.relative(matcher.path, string);
8594
+ const relative3 = sysPath2.relative(matcher.path, string);
8574
8595
  if (!relative3) {
8575
8596
  return false;
8576
8597
  }
8577
- return !relative3.startsWith("..") && !sp2.isAbsolute(relative3);
8598
+ return !relative3.startsWith("..") && !sysPath2.isAbsolute(relative3);
8578
8599
  }
8579
8600
  return false;
8580
8601
  };
@@ -8584,12 +8605,14 @@ function createPattern(matcher) {
8584
8605
  function normalizePath(path) {
8585
8606
  if (typeof path !== "string")
8586
8607
  throw new Error("string expected");
8587
- path = sp2.normalize(path);
8608
+ path = sysPath2.normalize(path);
8588
8609
  path = path.replace(/\\/g, "/");
8589
8610
  let prepend = false;
8590
8611
  if (path.startsWith("//"))
8591
8612
  prepend = true;
8592
- path = path.replace(DOUBLE_SLASH_RE, "/");
8613
+ const DOUBLE_SLASH_RE2 = /\/\//;
8614
+ while (path.match(DOUBLE_SLASH_RE2))
8615
+ path = path.replace(DOUBLE_SLASH_RE2, "/");
8593
8616
  if (prepend)
8594
8617
  path = "/" + path;
8595
8618
  return path;
@@ -8630,32 +8653,31 @@ var toUnix = (string) => {
8630
8653
  if (str.startsWith(SLASH_SLASH)) {
8631
8654
  prepend = true;
8632
8655
  }
8633
- str = str.replace(DOUBLE_SLASH_RE, SLASH);
8656
+ while (str.match(DOUBLE_SLASH_RE)) {
8657
+ str = str.replace(DOUBLE_SLASH_RE, SLASH);
8658
+ }
8634
8659
  if (prepend) {
8635
8660
  str = SLASH + str;
8636
8661
  }
8637
8662
  return str;
8638
8663
  };
8639
- var normalizePathToUnix = (path) => toUnix(sp2.normalize(toUnix(path)));
8664
+ var normalizePathToUnix = (path) => toUnix(sysPath2.normalize(toUnix(path)));
8640
8665
  var normalizeIgnored = (cwd = "") => (path) => {
8641
8666
  if (typeof path === "string") {
8642
- return normalizePathToUnix(sp2.isAbsolute(path) ? path : sp2.join(cwd, path));
8667
+ return normalizePathToUnix(sysPath2.isAbsolute(path) ? path : sysPath2.join(cwd, path));
8643
8668
  } else {
8644
8669
  return path;
8645
8670
  }
8646
8671
  };
8647
8672
  var getAbsolutePath = (path, cwd) => {
8648
- if (sp2.isAbsolute(path)) {
8673
+ if (sysPath2.isAbsolute(path)) {
8649
8674
  return path;
8650
8675
  }
8651
- return sp2.join(cwd, path);
8676
+ return sysPath2.join(cwd, path);
8652
8677
  };
8653
8678
  var EMPTY_SET = Object.freeze(new Set);
8654
8679
 
8655
8680
  class DirEntry {
8656
- path;
8657
- _removeWatcher;
8658
- items;
8659
8681
  constructor(dir, removeWatcher) {
8660
8682
  this.path = dir;
8661
8683
  this._removeWatcher = removeWatcher;
@@ -8680,7 +8702,7 @@ class DirEntry {
8680
8702
  await readdir2(dir);
8681
8703
  } catch (err) {
8682
8704
  if (this._removeWatcher) {
8683
- this._removeWatcher(sp2.dirname(dir), sp2.basename(dir));
8705
+ this._removeWatcher(sysPath2.dirname(dir), sysPath2.basename(dir));
8684
8706
  }
8685
8707
  }
8686
8708
  }
@@ -8708,19 +8730,12 @@ var STAT_METHOD_F = "stat";
8708
8730
  var STAT_METHOD_L = "lstat";
8709
8731
 
8710
8732
  class WatchHelper {
8711
- fsw;
8712
- path;
8713
- watchPath;
8714
- fullWatchPath;
8715
- dirParts;
8716
- followSymlinks;
8717
- statMethod;
8718
8733
  constructor(path, follow, fsw) {
8719
8734
  this.fsw = fsw;
8720
8735
  const watchPath = path;
8721
8736
  this.path = path = path.replace(REPLACER_RE, "");
8722
8737
  this.watchPath = watchPath;
8723
- this.fullWatchPath = sp2.resolve(watchPath);
8738
+ this.fullWatchPath = sysPath2.resolve(watchPath);
8724
8739
  this.dirParts = [];
8725
8740
  this.dirParts.forEach((parts) => {
8726
8741
  if (parts.length > 1)
@@ -8730,7 +8745,7 @@ class WatchHelper {
8730
8745
  this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L;
8731
8746
  }
8732
8747
  entryPath(entry) {
8733
- return sp2.join(this.watchPath, sp2.relative(this.watchPath, entry.fullPath));
8748
+ return sysPath2.join(this.watchPath, sysPath2.relative(this.watchPath, entry.fullPath));
8734
8749
  }
8735
8750
  filterPath(entry) {
8736
8751
  const { stats } = entry;
@@ -8745,24 +8760,6 @@ class WatchHelper {
8745
8760
  }
8746
8761
 
8747
8762
  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
8763
  constructor(_opts = {}) {
8767
8764
  super();
8768
8765
  this.closed = false;
@@ -8871,7 +8868,7 @@ class FSWatcher extends EventEmitter {
8871
8868
  return;
8872
8869
  results.forEach((item) => {
8873
8870
  if (item)
8874
- this.add(sp2.dirname(item), sp2.basename(_origAdd || item));
8871
+ this.add(sysPath2.dirname(item), sysPath2.basename(_origAdd || item));
8875
8872
  });
8876
8873
  });
8877
8874
  return this;
@@ -8882,10 +8879,10 @@ class FSWatcher extends EventEmitter {
8882
8879
  const paths = unifyPaths(paths_);
8883
8880
  const { cwd } = this.options;
8884
8881
  paths.forEach((path) => {
8885
- if (!sp2.isAbsolute(path) && !this._closers.has(path)) {
8882
+ if (!sysPath2.isAbsolute(path) && !this._closers.has(path)) {
8886
8883
  if (cwd)
8887
- path = sp2.join(cwd, path);
8888
- path = sp2.resolve(path);
8884
+ path = sysPath2.join(cwd, path);
8885
+ path = sysPath2.resolve(path);
8889
8886
  }
8890
8887
  this._closePath(path);
8891
8888
  this._addIgnoredPath(path);
@@ -8929,7 +8926,7 @@ class FSWatcher extends EventEmitter {
8929
8926
  getWatched() {
8930
8927
  const watchList = {};
8931
8928
  this._watched.forEach((entry, dir) => {
8932
- const key = this.options.cwd ? sp2.relative(this.options.cwd, dir) : dir;
8929
+ const key = this.options.cwd ? sysPath2.relative(this.options.cwd, dir) : dir;
8933
8930
  const index = key || ONE_DOT;
8934
8931
  watchList[index] = entry.getChildren().sort();
8935
8932
  });
@@ -8945,9 +8942,9 @@ class FSWatcher extends EventEmitter {
8945
8942
  return;
8946
8943
  const opts = this.options;
8947
8944
  if (isWindows)
8948
- path = sp2.normalize(path);
8945
+ path = sysPath2.normalize(path);
8949
8946
  if (opts.cwd)
8950
- path = sp2.relative(opts.cwd, path);
8947
+ path = sysPath2.relative(opts.cwd, path);
8951
8948
  const args = [path];
8952
8949
  if (stats != null)
8953
8950
  args.push(stats);
@@ -8998,7 +8995,7 @@ class FSWatcher extends EventEmitter {
8998
8995
  return this;
8999
8996
  }
9000
8997
  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;
8998
+ const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path) : path;
9002
8999
  let stats2;
9003
9000
  try {
9004
9001
  stats2 = await stat3(fullPath);
@@ -9054,8 +9051,8 @@ class FSWatcher extends EventEmitter {
9054
9051
  const pollInterval = awf.pollInterval;
9055
9052
  let timeoutHandler;
9056
9053
  let fullPath = path;
9057
- if (this.options.cwd && !sp2.isAbsolute(path)) {
9058
- fullPath = sp2.join(this.options.cwd, path);
9054
+ if (this.options.cwd && !sysPath2.isAbsolute(path)) {
9055
+ fullPath = sysPath2.join(this.options.cwd, path);
9059
9056
  }
9060
9057
  const now = new Date;
9061
9058
  const writes = this._pendingWrites;
@@ -9112,7 +9109,7 @@ class FSWatcher extends EventEmitter {
9112
9109
  return new WatchHelper(path, this.options.followSymlinks, this);
9113
9110
  }
9114
9111
  _getWatchedDir(directory) {
9115
- const dir = sp2.resolve(directory);
9112
+ const dir = sysPath2.resolve(directory);
9116
9113
  if (!this._watched.has(dir))
9117
9114
  this._watched.set(dir, new DirEntry(dir, this._boundRemove));
9118
9115
  return this._watched.get(dir);
@@ -9123,8 +9120,8 @@ class FSWatcher extends EventEmitter {
9123
9120
  return Boolean(Number(stats.mode) & 256);
9124
9121
  }
9125
9122
  _remove(directory, item, isDirectory) {
9126
- const path = sp2.join(directory, item);
9127
- const fullPath = sp2.resolve(path);
9123
+ const path = sysPath2.join(directory, item);
9124
+ const fullPath = sysPath2.resolve(path);
9128
9125
  isDirectory = isDirectory != null ? isDirectory : this._watched.has(path) || this._watched.has(fullPath);
9129
9126
  if (!this._throttle("remove", path, 100))
9130
9127
  return;
@@ -9142,7 +9139,7 @@ class FSWatcher extends EventEmitter {
9142
9139
  }
9143
9140
  let relPath = path;
9144
9141
  if (this.options.cwd)
9145
- relPath = sp2.relative(this.options.cwd, path);
9142
+ relPath = sysPath2.relative(this.options.cwd, path);
9146
9143
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
9147
9144
  const event = this._pendingWrites.get(relPath).cancelWait();
9148
9145
  if (event === EVENTS.ADD)
@@ -9157,8 +9154,8 @@ class FSWatcher extends EventEmitter {
9157
9154
  }
9158
9155
  _closePath(path) {
9159
9156
  this._closeFile(path);
9160
- const dir = sp2.dirname(path);
9161
- this._getWatchedDir(dir).remove(sp2.basename(path));
9157
+ const dir = sysPath2.dirname(path);
9158
+ this._getWatchedDir(dir).remove(sysPath2.basename(path));
9162
9159
  }
9163
9160
  _closeFile(path) {
9164
9161
  const closers = this._closers.get(path);
@@ -9201,62 +9198,11 @@ function watch(paths, options = {}) {
9201
9198
  return watcher;
9202
9199
  }
9203
9200
 
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
9201
  // src/commands/dev.ts
9256
9202
  function getEntryWatchPaths(root) {
9257
9203
  return [
9258
- join10(root, MANIFEST_FILE),
9259
- join10(root, "src", "actions.ts")
9204
+ join9(root, MANIFEST_FILE),
9205
+ join9(root, "src", "actions.ts")
9260
9206
  ];
9261
9207
  }
9262
9208
  async function dev() {
@@ -9270,23 +9216,6 @@ async function dev() {
9270
9216
  console.log(source_default.blue(`Dev mode — ${m.id} (${rt.name} ${rt.version})`));
9271
9217
  ensureDeps(root, rt);
9272
9218
  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
9219
  const vite = watchCmd(root, rt);
9291
9220
  vite.stdout?.on("data", (data) => {
9292
9221
  process.stdout.write(source_default.dim(data.toString()));
@@ -9312,8 +9241,8 @@ async function dev() {
9312
9241
  }
9313
9242
  console.log(source_default.blue("Actions changed — entry regenerated"));
9314
9243
  });
9315
- const distDir = join10(root, "dist");
9316
- const bundleFile = join10(distDir, `space-${m.id}.iife.js`);
9244
+ const distDir = join9(root, "dist");
9245
+ const bundleFile = join9(distDir, `space-${m.id}.iife.js`);
9317
9246
  let lastChecksum = "";
9318
9247
  const distWatcher = watch(bundleFile, { ignoreInitial: false });
9319
9248
  distWatcher.on("all", () => {
@@ -9331,32 +9260,47 @@ async function dev() {
9331
9260
  hostApiVersion: "0.2.0",
9332
9261
  builtAt: new Date().toISOString()
9333
9262
  });
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}`));
9263
+ console.log(source_default.green(`Built → dist/ (${(bundleData.length / 1024).toFixed(1)} KB)`));
9351
9264
  });
9352
9265
  console.log(source_default.green("Watching for changes... (Ctrl+C to stop)"));
9266
+ console.log(source_default.dim("Use the Preview button in Construct to open the Space Runner"));
9353
9267
  await new Promise(() => {});
9354
9268
  }
9355
9269
 
9356
9270
  // src/commands/run.ts
9357
- import { existsSync as existsSync8, cpSync as cpSync2, mkdirSync as mkdirSync4 } from "fs";
9271
+ import { existsSync as existsSync8, cpSync, mkdirSync as mkdirSync3 } from "fs";
9358
9272
  import { join as join11 } from "path";
9359
- function run() {
9273
+
9274
+ // src/lib/appdir.ts
9275
+ import { join as join10 } from "path";
9276
+ import { homedir } from "os";
9277
+ import { platform as platform2 } from "process";
9278
+ function dataDir() {
9279
+ if (process.env.CONSTRUCT_DATA_DIR)
9280
+ return process.env.CONSTRUCT_DATA_DIR;
9281
+ const home = homedir();
9282
+ switch (platform2) {
9283
+ case "darwin":
9284
+ return join10(home, "Library", "Application Support", "Construct");
9285
+ case "win32": {
9286
+ const appData = process.env.APPDATA || join10(home, "AppData", "Roaming");
9287
+ return join10(appData, "Construct");
9288
+ }
9289
+ default: {
9290
+ const xdg = process.env.XDG_DATA_HOME || join10(home, ".local", "share");
9291
+ return join10(xdg, "construct");
9292
+ }
9293
+ }
9294
+ }
9295
+ function spacesDir() {
9296
+ return join10(dataDir(), "spaces");
9297
+ }
9298
+ function spaceDir(spaceId) {
9299
+ return join10(spacesDir(), spaceId);
9300
+ }
9301
+
9302
+ // src/commands/run.ts
9303
+ function install() {
9360
9304
  const root = process.cwd();
9361
9305
  if (!exists(root)) {
9362
9306
  console.error(source_default.red("No space.manifest.json found in current directory"));
@@ -9373,18 +9317,18 @@ function run() {
9373
9317
  bundleAgentDir(agentDir, distDir);
9374
9318
  }
9375
9319
  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}`));
9320
+ mkdirSync3(installDir, { recursive: true });
9321
+ cpSync(distDir, installDir, { recursive: true });
9322
+ console.log(source_default.green(`Installed ${m.name} ${installDir}`));
9379
9323
  console.log(source_default.dim(" Restart Construct to load the updated space."));
9380
9324
  }
9381
9325
 
9382
9326
  // src/commands/publish.ts
9383
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync7, statSync as statSync5, unlinkSync as unlinkSync3 } from "fs";
9327
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync6, statSync as statSync4, unlinkSync as unlinkSync2 } from "fs";
9384
9328
  import { join as join14, basename as basename6 } from "path";
9385
9329
 
9386
9330
  // src/lib/auth.ts
9387
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, unlinkSync as unlinkSync2, existsSync as existsSync9 } from "fs";
9331
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, unlinkSync, existsSync as existsSync9 } from "fs";
9388
9332
  import { join as join12, dirname as dirname4 } from "path";
9389
9333
  var CREDENTIALS_FILE = "credentials.json";
9390
9334
  var DEFAULT_PORTAL = "https://developer.construct.space";
@@ -9393,8 +9337,8 @@ function credentialsPath() {
9393
9337
  }
9394
9338
  function store(creds) {
9395
9339
  const path = credentialsPath();
9396
- mkdirSync5(dirname4(path), { recursive: true });
9397
- writeFileSync6(path, JSON.stringify(creds, null, 2) + `
9340
+ mkdirSync4(dirname4(path), { recursive: true });
9341
+ writeFileSync5(path, JSON.stringify(creds, null, 2) + `
9398
9342
  `, { mode: 384 });
9399
9343
  }
9400
9344
  function load2() {
@@ -9419,11 +9363,11 @@ function isAuthenticated() {
9419
9363
  function clear() {
9420
9364
  const path = credentialsPath();
9421
9365
  if (existsSync9(path))
9422
- unlinkSync2(path);
9366
+ unlinkSync(path);
9423
9367
  }
9424
9368
 
9425
9369
  // src/lib/pack.ts
9426
- import { readdirSync as readdirSync3, statSync as statSync4, existsSync as existsSync10 } from "fs";
9370
+ import { readdirSync as readdirSync3, statSync as statSync3, existsSync as existsSync10 } from "fs";
9427
9371
  import { join as join13 } from "path";
9428
9372
  import { tmpdir } from "os";
9429
9373
  import { execSync as execSync3 } from "child_process";
@@ -9466,7 +9410,7 @@ async function packSource(root) {
9466
9410
  entries.push(name);
9467
9411
  }
9468
9412
  for (const entry of readdirSync3(root)) {
9469
- if (statSync4(join13(root, entry)).isDirectory())
9413
+ if (statSync3(join13(root, entry)).isDirectory())
9470
9414
  continue;
9471
9415
  if (allowedRootFiles.includes(entry))
9472
9416
  continue;
@@ -9486,7 +9430,7 @@ async function packSource(root) {
9486
9430
  const excludes = "--exclude=node_modules --exclude=dist --exclude=.git --exclude=*.env --exclude=*.log --exclude=*.lock --exclude=*.lockb";
9487
9431
  const cmd = `tar czf "${tarballPath}" ${excludes} ${validEntries.join(" ")}`;
9488
9432
  execSync3(cmd, { cwd: root });
9489
- const size = statSync4(tarballPath).size;
9433
+ const size = statSync3(tarballPath).size;
9490
9434
  if (size > MAX_SIZE) {
9491
9435
  throw new Error(`Source exceeds maximum size of ${MAX_SIZE / 1024 / 1024}MB`);
9492
9436
  }
@@ -9522,7 +9466,7 @@ function setVersionInFiles(root, oldVer, newVer) {
9522
9466
  const path = join14(root, file);
9523
9467
  try {
9524
9468
  const data = readFileSync7(path, "utf-8");
9525
- writeFileSync7(path, data.replace(oldStr, newStr));
9469
+ writeFileSync6(path, data.replace(oldStr, newStr));
9526
9470
  } catch {}
9527
9471
  }
9528
9472
  }
@@ -9626,7 +9570,7 @@ async function publish(options) {
9626
9570
  let tarballPath;
9627
9571
  try {
9628
9572
  tarballPath = await packSource(root);
9629
- const size = statSync5(tarballPath).size;
9573
+ const size = statSync4(tarballPath).size;
9630
9574
  spinner.succeed(`Source packed (${formatBytes(size)})`);
9631
9575
  } catch (err) {
9632
9576
  spinner.fail("Pack failed");
@@ -9636,7 +9580,7 @@ async function publish(options) {
9636
9580
  const uploadSpinner = ora("Uploading & building...").start();
9637
9581
  try {
9638
9582
  const result = await uploadSource(creds.portal, creds.token, tarballPath, m);
9639
- unlinkSync3(tarballPath);
9583
+ unlinkSync2(tarballPath);
9640
9584
  gitSafe(root, "tag", `v${m.version}`);
9641
9585
  gitSafe(root, "push", "origin", `v${m.version}`);
9642
9586
  if (result.status === "approved" || result.status === "pending_review") {
@@ -9658,7 +9602,7 @@ async function publish(options) {
9658
9602
  }
9659
9603
  } catch (err) {
9660
9604
  uploadSpinner.fail("Upload failed");
9661
- unlinkSync3(tarballPath);
9605
+ unlinkSync2(tarballPath);
9662
9606
  console.error(source_default.red(err.message));
9663
9607
  process.exit(1);
9664
9608
  }
@@ -9916,7 +9860,7 @@ function update() {
9916
9860
  }
9917
9861
 
9918
9862
  // src/commands/graph/init.ts
9919
- import { existsSync as existsSync14, readFileSync as readFileSync10, writeFileSync as writeFileSync8, mkdirSync as mkdirSync6 } from "fs";
9863
+ import { existsSync as existsSync14, readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync5 } from "fs";
9920
9864
  import { join as join18 } from "path";
9921
9865
  import { execSync as execSync6 } from "child_process";
9922
9866
  function graphInit() {
@@ -9928,10 +9872,10 @@ function graphInit() {
9928
9872
  }
9929
9873
  const m = read(root);
9930
9874
  const modelsDir = join18(root, "src", "models");
9931
- mkdirSync6(modelsDir, { recursive: true });
9875
+ mkdirSync5(modelsDir, { recursive: true });
9932
9876
  const indexPath = join18(modelsDir, "index.ts");
9933
9877
  if (!existsSync14(indexPath)) {
9934
- writeFileSync8(indexPath, `// Data models for ${m.name}
9878
+ writeFileSync7(indexPath, `// Data models for ${m.name}
9935
9879
  // Generated by construct graph init
9936
9880
 
9937
9881
  // Export your models here:
@@ -9948,7 +9892,7 @@ function graphInit() {
9948
9892
  version = execSync6("npm view @construct-space/graph version", { encoding: "utf-8" }).trim();
9949
9893
  } catch {}
9950
9894
  pkg.dependencies["@construct-space/graph"] = `^${version}`;
9951
- writeFileSync8(pkgPath, JSON.stringify(pkg, null, 2) + `
9895
+ writeFileSync7(pkgPath, JSON.stringify(pkg, null, 2) + `
9952
9896
  `);
9953
9897
  console.log(source_default.blue(`Added @construct-space/graph@^${version} to dependencies`));
9954
9898
  } else {
@@ -9969,7 +9913,7 @@ function graphInit() {
9969
9913
  }
9970
9914
 
9971
9915
  // src/commands/graph/generate.ts
9972
- import { existsSync as existsSync15, readFileSync as readFileSync11, writeFileSync as writeFileSync9, mkdirSync as mkdirSync7 } from "fs";
9916
+ import { existsSync as existsSync15, readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync6 } from "fs";
9973
9917
  import { join as join19 } from "path";
9974
9918
  var FIELD_TYPES = {
9975
9919
  string: "field.string()",
@@ -10123,13 +10067,13 @@ function generate2(modelName, fieldSpecs, options) {
10123
10067
  const content = lines.join(`
10124
10068
  `);
10125
10069
  const modelsDir = join19(root, "src", "models");
10126
- mkdirSync7(modelsDir, { recursive: true });
10070
+ mkdirSync6(modelsDir, { recursive: true });
10127
10071
  const filePath = join19(modelsDir, `${name}.ts`);
10128
10072
  if (existsSync15(filePath)) {
10129
10073
  console.log(source_default.yellow(` Model file already exists: src/models/${name}.ts`));
10130
10074
  console.log(source_default.dim(" Overwriting..."));
10131
10075
  }
10132
- writeFileSync9(filePath, content);
10076
+ writeFileSync8(filePath, content);
10133
10077
  console.log(source_default.green(` Created src/models/${name}.ts`));
10134
10078
  updateBarrel(modelsDir, name);
10135
10079
  console.log();
@@ -10148,11 +10092,11 @@ function updateBarrel(modelsDir, modelName) {
10148
10092
  const content = readFileSync11(indexPath, "utf-8");
10149
10093
  if (content.includes(exportLine))
10150
10094
  return;
10151
- writeFileSync9(indexPath, content.trimEnd() + `
10095
+ writeFileSync8(indexPath, content.trimEnd() + `
10152
10096
  ` + exportLine + `
10153
10097
  `);
10154
10098
  } else {
10155
- writeFileSync9(indexPath, exportLine + `
10099
+ writeFileSync8(indexPath, exportLine + `
10156
10100
  `);
10157
10101
  }
10158
10102
  console.log(source_default.dim(` Updated src/models/index.ts`));
@@ -10442,13 +10386,13 @@ function parseModelFields(content, fileName) {
10442
10386
  }
10443
10387
 
10444
10388
  // src/index.ts
10445
- var VERSION = "1.0.7";
10389
+ var VERSION = "1.1.0";
10446
10390
  var program2 = new Command;
10447
10391
  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));
10392
+ 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
10393
  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
10394
  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());
10395
+ program2.command("install").alias("run").description("Install built space to Construct spaces directory").action(() => install());
10452
10396
  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
10397
  program2.command("validate").description("Validate space.manifest.json").action(() => validate3());
10454
10398
  program2.command("check").description("Run type-check (vue-tsc) and linter (eslint)").action(() => check());
@@ -10462,10 +10406,10 @@ graph.command("generate <model> [fields...]").alias("g").description("Generate a
10462
10406
  graph.command("push").description("Register models with the Graph service").action(async () => graphPush());
10463
10407
  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
10408
  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));
10409
+ 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
10410
  space.command("build").option("--entry-only").action(async (opts) => build(opts));
10467
10411
  space.command("dev").action(async () => dev());
10468
- space.command("run").action(() => run());
10412
+ space.command("install").alias("run").action(() => install());
10469
10413
  space.command("publish").option("-y, --yes").option("--bump <type>").action(async (opts) => publish(opts));
10470
10414
  space.command("validate").action(() => validate3());
10471
10415
  space.command("check").action(() => check());