@construct-space/cli 1.9.4 → 1.9.6
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 +547 -289
- package/dist/templates/space/construct.md.tmpl +87 -8
- package/dist/templates/space/index.vue.tmpl +3 -2
- package/dist/templates/space/readme.md.tmpl +28 -3
- package/dist/templates/space/style.css.tmpl +2 -0
- package/dist/templates/space/tsconfig.json.tmpl +1 -2
- package/package.json +8 -3
- package/templates/space/construct.md.tmpl +87 -8
- package/templates/space/index.vue.tmpl +3 -2
- package/templates/space/readme.md.tmpl +28 -3
- package/templates/space/style.css.tmpl +2 -0
- package/templates/space/tsconfig.json.tmpl +1 -2
package/dist/index.js
CHANGED
|
@@ -2790,8 +2790,8 @@ var require_lib = __commonJS((exports, module) => {
|
|
|
2790
2790
|
});
|
|
2791
2791
|
|
|
2792
2792
|
// src/lib/appdir.ts
|
|
2793
|
-
import { existsSync as
|
|
2794
|
-
import { join as
|
|
2793
|
+
import { existsSync as existsSync9, readFileSync as readFileSync6 } from "fs";
|
|
2794
|
+
import { join as join11 } from "path";
|
|
2795
2795
|
import { homedir } from "os";
|
|
2796
2796
|
import { platform } from "process";
|
|
2797
2797
|
function dataDir() {
|
|
@@ -2800,32 +2800,32 @@ function dataDir() {
|
|
|
2800
2800
|
const home = homedir();
|
|
2801
2801
|
switch (platform) {
|
|
2802
2802
|
case "darwin":
|
|
2803
|
-
return
|
|
2803
|
+
return join11(home, "Library", "Application Support", "Construct");
|
|
2804
2804
|
case "win32": {
|
|
2805
|
-
const appData = process.env.APPDATA ||
|
|
2806
|
-
return
|
|
2805
|
+
const appData = process.env.APPDATA || join11(home, "AppData", "Roaming");
|
|
2806
|
+
return join11(appData, "Construct");
|
|
2807
2807
|
}
|
|
2808
2808
|
default: {
|
|
2809
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
2810
|
-
return
|
|
2809
|
+
const xdg = process.env.XDG_DATA_HOME || join11(home, ".local", "share");
|
|
2810
|
+
return join11(xdg, "construct");
|
|
2811
2811
|
}
|
|
2812
2812
|
}
|
|
2813
2813
|
}
|
|
2814
2814
|
function profilesDir() {
|
|
2815
|
-
return
|
|
2815
|
+
return join11(dataDir(), "profiles");
|
|
2816
2816
|
}
|
|
2817
2817
|
function activeProfileId() {
|
|
2818
2818
|
try {
|
|
2819
|
-
const credsPath =
|
|
2820
|
-
if (
|
|
2819
|
+
const credsPath = join11(dataDir(), "credentials.json");
|
|
2820
|
+
if (existsSync9(credsPath)) {
|
|
2821
2821
|
const c = JSON.parse(readFileSync6(credsPath, "utf-8"));
|
|
2822
2822
|
if (c.profileId)
|
|
2823
2823
|
return c.profileId;
|
|
2824
2824
|
}
|
|
2825
2825
|
} catch {}
|
|
2826
2826
|
try {
|
|
2827
|
-
const regPath =
|
|
2828
|
-
if (
|
|
2827
|
+
const regPath = join11(dataDir(), "profiles.json");
|
|
2828
|
+
if (existsSync9(regPath)) {
|
|
2829
2829
|
const r = JSON.parse(readFileSync6(regPath, "utf-8"));
|
|
2830
2830
|
if (r.active_profile)
|
|
2831
2831
|
return r.active_profile;
|
|
@@ -2836,29 +2836,29 @@ function activeProfileId() {
|
|
|
2836
2836
|
function spacesDir() {
|
|
2837
2837
|
const profileId = activeProfileId();
|
|
2838
2838
|
if (profileId)
|
|
2839
|
-
return
|
|
2840
|
-
return
|
|
2839
|
+
return join11(profilesDir(), profileId, "spaces");
|
|
2840
|
+
return join11(dataDir(), "spaces");
|
|
2841
2841
|
}
|
|
2842
2842
|
function spaceDir(spaceId) {
|
|
2843
|
-
return
|
|
2843
|
+
return join11(spacesDir(), `${spaceId}.space`);
|
|
2844
2844
|
}
|
|
2845
2845
|
var init_appdir = () => {};
|
|
2846
2846
|
|
|
2847
2847
|
// src/lib/auth.ts
|
|
2848
|
-
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as
|
|
2849
|
-
import { join as
|
|
2848
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, unlinkSync, existsSync as existsSync11, readdirSync as readdirSync5, statSync as statSync2 } from "fs";
|
|
2849
|
+
import { join as join13, dirname as dirname5 } from "path";
|
|
2850
2850
|
function listDesktopProfiles() {
|
|
2851
2851
|
const dir = profilesDir();
|
|
2852
|
-
if (!
|
|
2852
|
+
if (!existsSync11(dir))
|
|
2853
2853
|
return [];
|
|
2854
2854
|
const results = [];
|
|
2855
2855
|
for (const entry of readdirSync5(dir)) {
|
|
2856
|
-
const full =
|
|
2856
|
+
const full = join13(dir, entry);
|
|
2857
2857
|
try {
|
|
2858
|
-
if (!
|
|
2858
|
+
if (!statSync2(full).isDirectory())
|
|
2859
2859
|
continue;
|
|
2860
|
-
const authPath =
|
|
2861
|
-
if (!
|
|
2860
|
+
const authPath = join13(full, "auth.json");
|
|
2861
|
+
if (!existsSync11(authPath))
|
|
2862
2862
|
continue;
|
|
2863
2863
|
const data = JSON.parse(readFileSync7(authPath, "utf-8"));
|
|
2864
2864
|
if (!data.token)
|
|
@@ -2877,14 +2877,14 @@ function listDesktopProfiles() {
|
|
|
2877
2877
|
return results;
|
|
2878
2878
|
}
|
|
2879
2879
|
function legacyCredentialsPath() {
|
|
2880
|
-
return
|
|
2880
|
+
return join13(dataDir(), LEGACY_CREDENTIALS_FILE);
|
|
2881
2881
|
}
|
|
2882
2882
|
function registryPath() {
|
|
2883
|
-
return
|
|
2883
|
+
return join13(dataDir(), PROFILES_REGISTRY);
|
|
2884
2884
|
}
|
|
2885
2885
|
function readRegistry() {
|
|
2886
2886
|
const path = registryPath();
|
|
2887
|
-
if (!
|
|
2887
|
+
if (!existsSync11(path))
|
|
2888
2888
|
return {};
|
|
2889
2889
|
try {
|
|
2890
2890
|
return JSON.parse(readFileSync7(path, "utf-8"));
|
|
@@ -2894,7 +2894,7 @@ function readRegistry() {
|
|
|
2894
2894
|
}
|
|
2895
2895
|
function writeRegistry(reg) {
|
|
2896
2896
|
const path = registryPath();
|
|
2897
|
-
|
|
2897
|
+
mkdirSync6(dirname5(path), { recursive: true });
|
|
2898
2898
|
writeFileSync5(path, JSON.stringify({ version: 1, ...reg }, null, 2));
|
|
2899
2899
|
}
|
|
2900
2900
|
function store(creds) {
|
|
@@ -2902,10 +2902,10 @@ function store(creds) {
|
|
|
2902
2902
|
if (!profileId) {
|
|
2903
2903
|
throw new Error("cannot store credentials without a profile id (user.id or profileId)");
|
|
2904
2904
|
}
|
|
2905
|
-
const profilePath =
|
|
2906
|
-
|
|
2905
|
+
const profilePath = join13(profilesDir(), profileId, "auth.json");
|
|
2906
|
+
mkdirSync6(dirname5(profilePath), { recursive: true });
|
|
2907
2907
|
let existing = {};
|
|
2908
|
-
if (
|
|
2908
|
+
if (existsSync11(profilePath)) {
|
|
2909
2909
|
try {
|
|
2910
2910
|
existing = JSON.parse(readFileSync7(profilePath, "utf-8"));
|
|
2911
2911
|
} catch {}
|
|
@@ -2945,7 +2945,7 @@ function store(creds) {
|
|
|
2945
2945
|
}
|
|
2946
2946
|
function migrateLegacyCredentials() {
|
|
2947
2947
|
const legacy = legacyCredentialsPath();
|
|
2948
|
-
if (!
|
|
2948
|
+
if (!existsSync11(legacy))
|
|
2949
2949
|
return;
|
|
2950
2950
|
try {
|
|
2951
2951
|
const data = JSON.parse(readFileSync7(legacy, "utf-8"));
|
|
@@ -2954,8 +2954,8 @@ function migrateLegacyCredentials() {
|
|
|
2954
2954
|
const pid = data.profileId || data.user?.id;
|
|
2955
2955
|
if (!pid)
|
|
2956
2956
|
return;
|
|
2957
|
-
const profilePath =
|
|
2958
|
-
if (
|
|
2957
|
+
const profilePath = join13(profilesDir(), pid, "auth.json");
|
|
2958
|
+
if (existsSync11(profilePath))
|
|
2959
2959
|
return;
|
|
2960
2960
|
store({ ...data, profileId: pid });
|
|
2961
2961
|
} catch {}
|
|
@@ -2969,15 +2969,15 @@ function load2() {
|
|
|
2969
2969
|
}
|
|
2970
2970
|
function loadFromActiveProfile() {
|
|
2971
2971
|
try {
|
|
2972
|
-
const regPath =
|
|
2973
|
-
if (!
|
|
2972
|
+
const regPath = join13(dataDir(), "profiles.json");
|
|
2973
|
+
if (!existsSync11(regPath))
|
|
2974
2974
|
return null;
|
|
2975
2975
|
const reg = JSON.parse(readFileSync7(regPath, "utf-8"));
|
|
2976
2976
|
const activeId = reg.active_profile;
|
|
2977
2977
|
if (!activeId)
|
|
2978
2978
|
return null;
|
|
2979
|
-
const authPath =
|
|
2980
|
-
if (!
|
|
2979
|
+
const authPath = join13(profilesDir(), activeId, "auth.json");
|
|
2980
|
+
if (!existsSync11(authPath))
|
|
2981
2981
|
return null;
|
|
2982
2982
|
const a = JSON.parse(readFileSync7(authPath, "utf-8"));
|
|
2983
2983
|
if (!a.token)
|
|
@@ -3014,8 +3014,8 @@ function clear() {
|
|
|
3014
3014
|
const reg = readRegistry();
|
|
3015
3015
|
const activeId = reg.active_profile;
|
|
3016
3016
|
if (activeId) {
|
|
3017
|
-
const profilePath =
|
|
3018
|
-
if (
|
|
3017
|
+
const profilePath = join13(profilesDir(), activeId, "auth.json");
|
|
3018
|
+
if (existsSync11(profilePath)) {
|
|
3019
3019
|
try {
|
|
3020
3020
|
const data = JSON.parse(readFileSync7(profilePath, "utf-8"));
|
|
3021
3021
|
data.authenticated = false;
|
|
@@ -3025,7 +3025,7 @@ function clear() {
|
|
|
3025
3025
|
}
|
|
3026
3026
|
}
|
|
3027
3027
|
const legacy = legacyCredentialsPath();
|
|
3028
|
-
if (
|
|
3028
|
+
if (existsSync11(legacy))
|
|
3029
3029
|
unlinkSync(legacy);
|
|
3030
3030
|
}
|
|
3031
3031
|
var LEGACY_CREDENTIALS_FILE = "credentials.json", PROFILES_REGISTRY = "profiles.json", DEFAULT_PORTAL = "https://my.construct.space/api/developer";
|
|
@@ -3190,7 +3190,7 @@ function loadCreds() {
|
|
|
3190
3190
|
} catch (err) {
|
|
3191
3191
|
const msg = err instanceof Error ? err.message : String(err);
|
|
3192
3192
|
throw new Error(msg + `
|
|
3193
|
-
Run 'construct login' first
|
|
3193
|
+
Run 'construct login' first.`, { cause: err });
|
|
3194
3194
|
}
|
|
3195
3195
|
}
|
|
3196
3196
|
async function graphRequest(opts) {
|
|
@@ -5453,6 +5453,8 @@ async function scaffold(nameArg, options) {
|
|
|
5453
5453
|
join2(name, "scripts"),
|
|
5454
5454
|
join2(name, "references"),
|
|
5455
5455
|
join2(name, "assets"),
|
|
5456
|
+
join2(name, "tools"),
|
|
5457
|
+
join2(name, "lib"),
|
|
5456
5458
|
join2(name, "agent", "hooks"),
|
|
5457
5459
|
join2(name, "agent", "tools"),
|
|
5458
5460
|
join2(name, "widgets", "summary")
|
|
@@ -5516,9 +5518,9 @@ async function scaffold(nameArg, options) {
|
|
|
5516
5518
|
|
|
5517
5519
|
// src/commands/build.ts
|
|
5518
5520
|
init_source();
|
|
5519
|
-
import {
|
|
5520
|
-
import { join as
|
|
5521
|
-
import { createHash } from "crypto";
|
|
5521
|
+
import { existsSync as existsSync7, readFileSync as readFileSync4, readdirSync as readdirSync3, renameSync, rmSync as rmSync2 } from "fs";
|
|
5522
|
+
import { join as join7 } from "path";
|
|
5523
|
+
import { createHash as createHash2 } from "crypto";
|
|
5522
5524
|
|
|
5523
5525
|
// node_modules/ora/index.js
|
|
5524
5526
|
init_source();
|
|
@@ -8154,6 +8156,7 @@ function ora(options) {
|
|
|
8154
8156
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync3 } from "fs";
|
|
8155
8157
|
import { join as join3 } from "path";
|
|
8156
8158
|
var MANIFEST_FILE = "space.manifest.json";
|
|
8159
|
+
var HOST_API_VERSION = "0.6.0";
|
|
8157
8160
|
var idRegex = /^[a-z][a-z0-9-]*$/;
|
|
8158
8161
|
var versionRegex = /^\d+\.\d+\.\d+/;
|
|
8159
8162
|
function validate2(m) {
|
|
@@ -8247,7 +8250,7 @@ function scanPagesDir(pagesDir) {
|
|
|
8247
8250
|
function varNameFromFile(filePath) {
|
|
8248
8251
|
let cleaned = filePath.replace(/^pages\//, "").replace(/\.vue$/, "");
|
|
8249
8252
|
cleaned = cleaned.replace(/\[([^\]]+)\]/g, "$1");
|
|
8250
|
-
const segments = cleaned.split(/[
|
|
8253
|
+
const segments = cleaned.split(/[/-]/).filter(Boolean);
|
|
8251
8254
|
const name = segments.map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
|
8252
8255
|
return (name || "Index") + "Page";
|
|
8253
8256
|
}
|
|
@@ -8261,11 +8264,11 @@ function resolvePages(m, root, prefix) {
|
|
|
8261
8264
|
return m.pages.map((p) => {
|
|
8262
8265
|
if (p.component) {
|
|
8263
8266
|
const base = basename(p.component);
|
|
8264
|
-
const nameWithoutExt = base.replace(extname(base), "").replace(/[
|
|
8267
|
+
const nameWithoutExt = base.replace(extname(base), "").replace(/[[\]]/g, "");
|
|
8265
8268
|
const dir = p.component.replace(/^pages\//, "").replace(/\/[^/]+$/, "");
|
|
8266
8269
|
let varName;
|
|
8267
8270
|
if (dir && dir !== p.component.replace(/^pages\//, "")) {
|
|
8268
|
-
varName = capitalize(dir.split("/").map((s) => s.replace(/[
|
|
8271
|
+
varName = capitalize(dir.split("/").map((s) => s.replace(/[[\]]/g, "")).join("-")) + capitalize(nameWithoutExt) + "Page";
|
|
8269
8272
|
} else {
|
|
8270
8273
|
varName = capitalize(nameWithoutExt) + "Page";
|
|
8271
8274
|
}
|
|
@@ -8281,7 +8284,7 @@ function resolvePages(m, root, prefix) {
|
|
|
8281
8284
|
if (existsSync4(legacyFullPath)) {
|
|
8282
8285
|
let varName = "IndexPage";
|
|
8283
8286
|
if (p.path) {
|
|
8284
|
-
varName = capitalize(p.path.replace(/\[([^\]]+)\]/g, "$1").replace(/[
|
|
8287
|
+
varName = capitalize(p.path.replace(/\[([^\]]+)\]/g, "$1").replace(/[/:]/g, "-").replace(/-+/g, "-")) + "Page";
|
|
8285
8288
|
}
|
|
8286
8289
|
return { varName, importPath: prefix + legacyComponent, path: p.path };
|
|
8287
8290
|
}
|
|
@@ -8362,74 +8365,216 @@ function writeEntry(root, m) {
|
|
|
8362
8365
|
writeFileSync3(join4(srcDir, "entry.ts"), generate(root, m));
|
|
8363
8366
|
}
|
|
8364
8367
|
|
|
8365
|
-
// src/lib/
|
|
8366
|
-
import {
|
|
8367
|
-
import {
|
|
8368
|
-
|
|
8369
|
-
|
|
8370
|
-
|
|
8371
|
-
|
|
8372
|
-
const
|
|
8373
|
-
for (
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
}
|
|
8378
|
-
function readMdFiles(dir) {
|
|
8379
|
-
const result = {};
|
|
8380
|
-
if (!existsSync5(dir))
|
|
8381
|
-
return result;
|
|
8382
|
-
for (const f of readdirSync2(dir)) {
|
|
8383
|
-
if (extname2(f) !== ".md")
|
|
8368
|
+
// src/lib/spaceBundle.ts
|
|
8369
|
+
import { createHash } from "crypto";
|
|
8370
|
+
import { cpSync, existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync3, readFileSync as readFileSync3, readdirSync as readdirSync2, rmSync, writeFileSync as writeFileSync4 } from "fs";
|
|
8371
|
+
import { basename as basename2, dirname as dirname2, join as join5, relative as relative2 } from "path";
|
|
8372
|
+
var BUNDLE_DIRS = ["agent", "scripts", "references", "assets", "icons", "media", "public", "tools", "lib"];
|
|
8373
|
+
var BUNDLE_FILES = ["SKILL.md"];
|
|
8374
|
+
function stageSpaceResources(root, distDir) {
|
|
8375
|
+
const copied = [];
|
|
8376
|
+
for (const name of BUNDLE_DIRS) {
|
|
8377
|
+
rmSync(join5(distDir, name), { recursive: true, force: true });
|
|
8378
|
+
const src = join5(root, name);
|
|
8379
|
+
if (!existsSync5(src) || !lstatSync(src).isDirectory())
|
|
8384
8380
|
continue;
|
|
8385
|
-
|
|
8381
|
+
cpSync(src, join5(distDir, name), { recursive: true, verbatimSymlinks: true });
|
|
8382
|
+
copied.push(name);
|
|
8386
8383
|
}
|
|
8387
|
-
|
|
8384
|
+
for (const name of BUNDLE_FILES) {
|
|
8385
|
+
rmSync(join5(distDir, name), { recursive: true, force: true });
|
|
8386
|
+
const src = join5(root, name);
|
|
8387
|
+
if (!existsSync5(src) || !lstatSync(src).isFile())
|
|
8388
|
+
continue;
|
|
8389
|
+
cpSync(src, join5(distDir, name), { verbatimSymlinks: true });
|
|
8390
|
+
copied.push(name);
|
|
8391
|
+
}
|
|
8392
|
+
return copied;
|
|
8388
8393
|
}
|
|
8389
|
-
function
|
|
8390
|
-
|
|
8391
|
-
|
|
8392
|
-
|
|
8393
|
-
|
|
8394
|
-
|
|
8394
|
+
function slashPath(path) {
|
|
8395
|
+
return path.replace(/\\/g, "/");
|
|
8396
|
+
}
|
|
8397
|
+
function copyFileIntoBundle(src, dst) {
|
|
8398
|
+
mkdirSync3(dirname2(dst), { recursive: true });
|
|
8399
|
+
cpSync(src, dst, { verbatimSymlinks: true });
|
|
8400
|
+
}
|
|
8401
|
+
function collectFiles(root) {
|
|
8402
|
+
const files = [];
|
|
8403
|
+
function walk(dir) {
|
|
8404
|
+
for (const name of readdirSync2(dir).sort()) {
|
|
8405
|
+
const path = join5(dir, name);
|
|
8406
|
+
const stat = lstatSync(path);
|
|
8407
|
+
if (stat.isSymbolicLink())
|
|
8408
|
+
continue;
|
|
8409
|
+
if (stat.isDirectory()) {
|
|
8410
|
+
walk(path);
|
|
8411
|
+
} else if (stat.isFile()) {
|
|
8412
|
+
files.push(slashPath(relative2(root, path)));
|
|
8413
|
+
}
|
|
8414
|
+
}
|
|
8415
|
+
}
|
|
8416
|
+
walk(root);
|
|
8417
|
+
return files;
|
|
8418
|
+
}
|
|
8419
|
+
function sha256(path) {
|
|
8420
|
+
return createHash("sha256").update(readFileSync3(path)).digest("hex");
|
|
8421
|
+
}
|
|
8422
|
+
function writeChecksums(spaceDir, spaceId) {
|
|
8423
|
+
const files = collectFiles(spaceDir).filter((file) => file !== "checksums.json");
|
|
8424
|
+
const checksums = {};
|
|
8425
|
+
for (const file of files) {
|
|
8426
|
+
checksums[file] = sha256(join5(spaceDir, file));
|
|
8427
|
+
}
|
|
8428
|
+
writeFileSync4(join5(spaceDir, "checksums.json"), JSON.stringify({
|
|
8429
|
+
format: "construct.space/v1",
|
|
8430
|
+
id: spaceId,
|
|
8431
|
+
files: checksums
|
|
8432
|
+
}, null, 2) + `
|
|
8433
|
+
`);
|
|
8434
|
+
return collectFiles(spaceDir);
|
|
8435
|
+
}
|
|
8436
|
+
function createSpaceBundle(options) {
|
|
8437
|
+
const spaceDir = join5(options.distDir, `${options.spaceId}.space`);
|
|
8438
|
+
const appName = basename2(options.appBundlePath);
|
|
8439
|
+
const cssName = options.cssPath ? basename2(options.cssPath) : "";
|
|
8440
|
+
rmSync(spaceDir, { recursive: true, force: true });
|
|
8441
|
+
mkdirSync3(spaceDir, { recursive: true });
|
|
8442
|
+
copyFileIntoBundle(join5(options.distDir, "manifest.json"), join5(spaceDir, "manifest.json"));
|
|
8443
|
+
copyFileIntoBundle(options.appBundlePath, join5(spaceDir, "app.iife.js"));
|
|
8444
|
+
const hasStyle = Boolean(options.cssPath && existsSync5(options.cssPath));
|
|
8445
|
+
if (hasStyle && options.cssPath) {
|
|
8446
|
+
copyFileIntoBundle(options.cssPath, join5(spaceDir, "style.css"));
|
|
8447
|
+
}
|
|
8448
|
+
for (const entry of readdirSync2(options.distDir)) {
|
|
8449
|
+
if (entry === `${options.spaceId}.space`)
|
|
8450
|
+
continue;
|
|
8451
|
+
if (entry.endsWith(".space"))
|
|
8395
8452
|
continue;
|
|
8396
|
-
|
|
8453
|
+
if (entry === "manifest.json")
|
|
8454
|
+
continue;
|
|
8455
|
+
if (entry === appName || entry === cssName)
|
|
8456
|
+
continue;
|
|
8457
|
+
if (entry.endsWith(".iife.js") || entry.endsWith(".css"))
|
|
8458
|
+
continue;
|
|
8459
|
+
cpSync(join5(options.distDir, entry), join5(spaceDir, entry), {
|
|
8460
|
+
recursive: true,
|
|
8461
|
+
verbatimSymlinks: true
|
|
8462
|
+
});
|
|
8397
8463
|
}
|
|
8398
|
-
return
|
|
8464
|
+
return {
|
|
8465
|
+
dir: spaceDir,
|
|
8466
|
+
hasStyle,
|
|
8467
|
+
files: writeChecksums(spaceDir, options.spaceId)
|
|
8468
|
+
};
|
|
8399
8469
|
}
|
|
8400
|
-
|
|
8401
|
-
|
|
8402
|
-
|
|
8403
|
-
|
|
8404
|
-
|
|
8405
|
-
|
|
8470
|
+
|
|
8471
|
+
// src/lib/spaceTools.ts
|
|
8472
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync4 } from "fs";
|
|
8473
|
+
import { join as join6 } from "path";
|
|
8474
|
+
import { arch as nodeArch, platform as nodePlatform } from "process";
|
|
8475
|
+
import { spawnSync } from "child_process";
|
|
8476
|
+
var SPACE_TOOL_TARGETS = [
|
|
8477
|
+
"darwin-arm64",
|
|
8478
|
+
"darwin-x64",
|
|
8479
|
+
"linux-arm64",
|
|
8480
|
+
"linux-x64",
|
|
8481
|
+
"windows-arm64",
|
|
8482
|
+
"windows-x64"
|
|
8483
|
+
];
|
|
8484
|
+
var GO_TARGETS = {
|
|
8485
|
+
"darwin-arm64": { goos: "darwin", goarch: "arm64", ext: "" },
|
|
8486
|
+
"darwin-x64": { goos: "darwin", goarch: "amd64", ext: "" },
|
|
8487
|
+
"linux-arm64": { goos: "linux", goarch: "arm64", ext: "" },
|
|
8488
|
+
"linux-x64": { goos: "linux", goarch: "amd64", ext: "" },
|
|
8489
|
+
"windows-arm64": { goos: "windows", goarch: "arm64", ext: ".exe" },
|
|
8490
|
+
"windows-x64": { goos: "windows", goarch: "amd64", ext: ".exe" }
|
|
8491
|
+
};
|
|
8492
|
+
function isSpaceToolTarget(value) {
|
|
8493
|
+
return SPACE_TOOL_TARGETS.includes(value);
|
|
8494
|
+
}
|
|
8495
|
+
function currentSpaceToolTarget(platform = nodePlatform, arch = nodeArch) {
|
|
8496
|
+
if (platform === "darwin" && arch === "arm64")
|
|
8497
|
+
return "darwin-arm64";
|
|
8498
|
+
if (platform === "darwin" && arch === "x64")
|
|
8499
|
+
return "darwin-x64";
|
|
8500
|
+
if (platform === "linux" && arch === "arm64")
|
|
8501
|
+
return "linux-arm64";
|
|
8502
|
+
if (platform === "linux" && arch === "x64")
|
|
8503
|
+
return "linux-x64";
|
|
8504
|
+
if (platform === "win32" && arch === "arm64")
|
|
8505
|
+
return "windows-arm64";
|
|
8506
|
+
if (platform === "win32" && arch === "x64")
|
|
8507
|
+
return "windows-x64";
|
|
8508
|
+
return null;
|
|
8509
|
+
}
|
|
8510
|
+
function parseSpaceToolTargets(value = process.env.CONSTRUCT_TOOL_TARGETS) {
|
|
8511
|
+
const raw = value?.trim();
|
|
8512
|
+
if (!raw) {
|
|
8513
|
+
const current = currentSpaceToolTarget();
|
|
8514
|
+
if (!current)
|
|
8515
|
+
throw new Error(`Unsupported tool build platform: ${nodePlatform}-${nodeArch}`);
|
|
8516
|
+
return [current];
|
|
8517
|
+
}
|
|
8518
|
+
if (raw === "all")
|
|
8519
|
+
return [...SPACE_TOOL_TARGETS];
|
|
8520
|
+
const targets = raw.split(/[,\s]+/).filter(Boolean);
|
|
8521
|
+
const invalid = targets.filter((target) => !isSpaceToolTarget(target));
|
|
8522
|
+
if (invalid.length > 0) {
|
|
8523
|
+
throw new Error(`Invalid CONSTRUCT_TOOL_TARGETS value: ${invalid.join(", ")}. ` + `Expected one or more of: ${SPACE_TOOL_TARGETS.join(", ")}, or "all".`);
|
|
8524
|
+
}
|
|
8525
|
+
return Array.from(new Set(targets));
|
|
8526
|
+
}
|
|
8527
|
+
function defaultRunner(invocation) {
|
|
8528
|
+
const result = spawnSync("go", invocation.args, {
|
|
8529
|
+
cwd: invocation.root,
|
|
8530
|
+
env: invocation.env,
|
|
8531
|
+
encoding: "utf-8"
|
|
8532
|
+
});
|
|
8533
|
+
return {
|
|
8534
|
+
status: result.status,
|
|
8535
|
+
stdout: result.stdout || "",
|
|
8536
|
+
stderr: result.stderr || "",
|
|
8537
|
+
error: result.error
|
|
8406
8538
|
};
|
|
8407
|
-
|
|
8408
|
-
|
|
8409
|
-
|
|
8410
|
-
|
|
8411
|
-
|
|
8539
|
+
}
|
|
8540
|
+
function buildSpaceTools(root, distDir, spaceId, options = {}) {
|
|
8541
|
+
const sourcePath = join6(root, "tools.go");
|
|
8542
|
+
if (!existsSync6(sourcePath))
|
|
8543
|
+
return [];
|
|
8544
|
+
const built = [];
|
|
8545
|
+
const targets = options.targets ?? parseSpaceToolTargets(options.env?.CONSTRUCT_TOOL_TARGETS);
|
|
8546
|
+
const runner = options.runner ?? defaultRunner;
|
|
8547
|
+
for (const target of targets) {
|
|
8548
|
+
const goTarget = GO_TARGETS[target];
|
|
8549
|
+
const outputDir = join6(distDir, "tools", target);
|
|
8550
|
+
const outputName = `${spaceId}-tools${goTarget.ext}`;
|
|
8551
|
+
const outputPath = join6(outputDir, outputName);
|
|
8552
|
+
mkdirSync4(outputDir, { recursive: true });
|
|
8553
|
+
const env2 = {
|
|
8554
|
+
...process.env,
|
|
8555
|
+
...options.env,
|
|
8556
|
+
GOOS: goTarget.goos,
|
|
8557
|
+
GOARCH: goTarget.goarch
|
|
8558
|
+
};
|
|
8559
|
+
if (!env2.CGO_ENABLED)
|
|
8560
|
+
env2.CGO_ENABLED = "0";
|
|
8561
|
+
const args = ["build", "-trimpath", "-o", outputPath, "./tools.go"];
|
|
8562
|
+
const result = runner({ root, target, outputPath, args, env: env2 });
|
|
8563
|
+
if (result.error) {
|
|
8564
|
+
throw new Error(`Failed to build tools.go for ${target}: ${result.error.message}`);
|
|
8565
|
+
}
|
|
8566
|
+
if (result.status !== 0) {
|
|
8567
|
+
const details = [result.stderr, result.stdout].filter(Boolean).join(`
|
|
8568
|
+
`).trim();
|
|
8569
|
+
throw new Error(`Failed to build tools.go for ${target}${details ? `:
|
|
8570
|
+
${details}` : ""}`);
|
|
8412
8571
|
}
|
|
8572
|
+
built.push(`tools/${target}/${outputName}`);
|
|
8413
8573
|
}
|
|
8414
|
-
|
|
8415
|
-
return;
|
|
8416
|
-
const encoded = encode(JSON.stringify(bundle));
|
|
8417
|
-
writeFileSync4(join5(distDir, "config.agent"), encoded);
|
|
8574
|
+
return built;
|
|
8418
8575
|
}
|
|
8419
8576
|
|
|
8420
8577
|
// src/commands/build.ts
|
|
8421
|
-
var ASSET_DIRS = ["icons", "assets", "media", "public", "bin"];
|
|
8422
|
-
function copyAssetDirs(root, distDir) {
|
|
8423
|
-
const copied = [];
|
|
8424
|
-
for (const name of ASSET_DIRS) {
|
|
8425
|
-
const src = join6(root, name);
|
|
8426
|
-
if (!existsSync6(src) || !statSync2(src).isDirectory())
|
|
8427
|
-
continue;
|
|
8428
|
-
cpSync(src, join6(distDir, name), { recursive: true, verbatimSymlinks: true });
|
|
8429
|
-
copied.push(name);
|
|
8430
|
-
}
|
|
8431
|
-
return copied;
|
|
8432
|
-
}
|
|
8433
8578
|
function stripTsComments(source) {
|
|
8434
8579
|
let out = "";
|
|
8435
8580
|
let i = 0;
|
|
@@ -8518,7 +8663,7 @@ function readObjectEntries(source) {
|
|
|
8518
8663
|
i += 1;
|
|
8519
8664
|
if (i >= source.length)
|
|
8520
8665
|
break;
|
|
8521
|
-
let key
|
|
8666
|
+
let key;
|
|
8522
8667
|
const quote = source[i];
|
|
8523
8668
|
if (quote === '"' || quote === "'" || quote === "`") {
|
|
8524
8669
|
i += 1;
|
|
@@ -8629,41 +8774,52 @@ async function build(options) {
|
|
|
8629
8774
|
process.exit(1);
|
|
8630
8775
|
}
|
|
8631
8776
|
runHook(m.hooks, "postBuild", root);
|
|
8632
|
-
const
|
|
8633
|
-
if (
|
|
8634
|
-
|
|
8635
|
-
bundleAgentDir(agentDir, distDir2);
|
|
8636
|
-
bundleAgentDir(agentDir, root);
|
|
8777
|
+
const copiedResources = stageSpaceResources(root, join7(root, "dist"));
|
|
8778
|
+
if (copiedResources.length > 0) {
|
|
8779
|
+
console.log(source_default.blue(` Resources: ${copiedResources.join(", ")}`));
|
|
8637
8780
|
}
|
|
8638
|
-
|
|
8639
|
-
|
|
8640
|
-
|
|
8781
|
+
try {
|
|
8782
|
+
const builtTools = buildSpaceTools(root, join7(root, "dist"), m.id);
|
|
8783
|
+
if (builtTools.length > 0) {
|
|
8784
|
+
console.log(source_default.blue(` Tools: ${builtTools.join(", ")}`));
|
|
8785
|
+
}
|
|
8786
|
+
} catch (err) {
|
|
8787
|
+
console.error(source_default.red(err?.message || String(err)));
|
|
8788
|
+
process.exit(1);
|
|
8641
8789
|
}
|
|
8642
|
-
const distDir =
|
|
8790
|
+
const distDir = join7(root, "dist");
|
|
8643
8791
|
const expectedBundle = `space-${m.id}.iife.js`;
|
|
8644
|
-
|
|
8645
|
-
if (!
|
|
8792
|
+
const bundlePath = join7(distDir, expectedBundle);
|
|
8793
|
+
if (!existsSync7(bundlePath)) {
|
|
8646
8794
|
const matches = readdirSync3(distDir).filter((f) => f.startsWith("space-") && f.endsWith(".iife.js"));
|
|
8647
8795
|
if (matches.length === 1) {
|
|
8648
|
-
renameSync(
|
|
8649
|
-
const oldCSS =
|
|
8650
|
-
const newCSS =
|
|
8651
|
-
if (
|
|
8796
|
+
renameSync(join7(distDir, matches[0]), bundlePath);
|
|
8797
|
+
const oldCSS = join7(distDir, matches[0].replace(".iife.js", ".css"));
|
|
8798
|
+
const newCSS = join7(distDir, `space-${m.id}.css`);
|
|
8799
|
+
if (existsSync7(oldCSS))
|
|
8652
8800
|
renameSync(oldCSS, newCSS);
|
|
8653
8801
|
}
|
|
8654
8802
|
}
|
|
8655
|
-
|
|
8656
|
-
|
|
8803
|
+
if (!existsSync7(bundlePath)) {
|
|
8804
|
+
console.error(source_default.red(`Build did not emit ${expectedBundle}`));
|
|
8805
|
+
process.exit(1);
|
|
8806
|
+
}
|
|
8807
|
+
const expectedCSS = join7(distDir, `space-${m.id}.css`);
|
|
8808
|
+
if (!existsSync7(expectedCSS)) {
|
|
8657
8809
|
const cssMatches = readdirSync3(distDir).filter((f) => f.endsWith(".css"));
|
|
8658
8810
|
const renamedCSS = cssMatches.find((f) => f.startsWith("space-")) || (cssMatches.length === 1 ? cssMatches[0] : undefined);
|
|
8659
8811
|
if (renamedCSS)
|
|
8660
|
-
renameSync(
|
|
8812
|
+
renameSync(join7(distDir, renamedCSS), expectedCSS);
|
|
8813
|
+
}
|
|
8814
|
+
if (!existsSync7(expectedCSS)) {
|
|
8815
|
+
console.error(source_default.red(`Build did not emit CSS. Spaces must import src/style.css so pages and widgets are self-contained.`));
|
|
8816
|
+
process.exit(1);
|
|
8661
8817
|
}
|
|
8662
8818
|
const bundleData = readFileSync4(bundlePath);
|
|
8663
|
-
const checksum =
|
|
8819
|
+
const checksum = createHash2("sha256").update(bundleData).digest("hex");
|
|
8664
8820
|
const raw = readRaw(root);
|
|
8665
|
-
const actionsPath =
|
|
8666
|
-
if (
|
|
8821
|
+
const actionsPath = join7(root, "src", "actions.ts");
|
|
8822
|
+
if (existsSync7(actionsPath)) {
|
|
8667
8823
|
const actionMeta = extractActionMetadata(actionsPath);
|
|
8668
8824
|
if (actionMeta && Object.keys(actionMeta).length > 0) {
|
|
8669
8825
|
raw.actions = actionMeta;
|
|
@@ -8673,28 +8829,40 @@ async function build(options) {
|
|
|
8673
8829
|
writeWithBuild(distDir, raw, {
|
|
8674
8830
|
checksum,
|
|
8675
8831
|
size: bundleData.length,
|
|
8676
|
-
hostApiVersion:
|
|
8832
|
+
hostApiVersion: HOST_API_VERSION,
|
|
8677
8833
|
builtAt: new Date().toISOString()
|
|
8678
8834
|
});
|
|
8679
|
-
|
|
8835
|
+
const spaceBundle = createSpaceBundle({
|
|
8836
|
+
distDir,
|
|
8837
|
+
spaceId: m.id,
|
|
8838
|
+
appBundlePath: bundlePath,
|
|
8839
|
+
cssPath: expectedCSS
|
|
8840
|
+
});
|
|
8841
|
+
for (const entry of readdirSync3(distDir)) {
|
|
8842
|
+
if (entry === `${m.id}.space`)
|
|
8843
|
+
continue;
|
|
8844
|
+
rmSync2(join7(distDir, entry), { recursive: true, force: true });
|
|
8845
|
+
}
|
|
8846
|
+
console.log(source_default.green(`Built ${m.name} v${m.version} -> dist/${m.id}.space`));
|
|
8847
|
+
console.log(source_default.dim(` ${spaceBundle.files.length} files, ${spaceBundle.hasStyle ? "style.css included" : "no style.css"}`));
|
|
8680
8848
|
}
|
|
8681
8849
|
|
|
8682
8850
|
// src/commands/dev.ts
|
|
8683
8851
|
init_source();
|
|
8684
|
-
import { existsSync as
|
|
8685
|
-
import { join as
|
|
8686
|
-
import { createHash as
|
|
8852
|
+
import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
|
|
8853
|
+
import { join as join10 } from "path";
|
|
8854
|
+
import { createHash as createHash3 } from "crypto";
|
|
8687
8855
|
|
|
8688
|
-
// node_modules/chokidar/
|
|
8689
|
-
import { stat as statcb } from "fs";
|
|
8690
|
-
import { stat as stat3, readdir as readdir2 } from "fs/promises";
|
|
8856
|
+
// node_modules/chokidar/index.js
|
|
8691
8857
|
import { EventEmitter } from "events";
|
|
8692
|
-
import
|
|
8858
|
+
import { stat as statcb, Stats } from "fs";
|
|
8859
|
+
import { readdir as readdir2, stat as stat3 } from "fs/promises";
|
|
8860
|
+
import * as sp2 from "path";
|
|
8693
8861
|
|
|
8694
|
-
// node_modules/readdirp/
|
|
8695
|
-
import {
|
|
8862
|
+
// node_modules/readdirp/index.js
|
|
8863
|
+
import { lstat, readdir, realpath, stat } from "fs/promises";
|
|
8864
|
+
import { join as pjoin, relative as prelative, resolve as presolve, sep as psep } from "path";
|
|
8696
8865
|
import { Readable } from "stream";
|
|
8697
|
-
import { resolve as presolve, relative as prelative, join as pjoin, sep as psep } from "path";
|
|
8698
8866
|
var EntryTypes = {
|
|
8699
8867
|
FILE_TYPE: "files",
|
|
8700
8868
|
DIR_TYPE: "directories",
|
|
@@ -8750,6 +8918,20 @@ var normalizeFilter = (filter) => {
|
|
|
8750
8918
|
};
|
|
8751
8919
|
|
|
8752
8920
|
class ReaddirpStream extends Readable {
|
|
8921
|
+
parents;
|
|
8922
|
+
reading;
|
|
8923
|
+
parent;
|
|
8924
|
+
_stat;
|
|
8925
|
+
_maxDepth;
|
|
8926
|
+
_wantsDir;
|
|
8927
|
+
_wantsFile;
|
|
8928
|
+
_wantsEverything;
|
|
8929
|
+
_root;
|
|
8930
|
+
_isDirent;
|
|
8931
|
+
_statsProp;
|
|
8932
|
+
_rdOptions;
|
|
8933
|
+
_fileFilter;
|
|
8934
|
+
_directoryFilter;
|
|
8753
8935
|
constructor(options = {}) {
|
|
8754
8936
|
super({
|
|
8755
8937
|
objectMode: true,
|
|
@@ -8766,7 +8948,7 @@ class ReaddirpStream extends Readable {
|
|
|
8766
8948
|
} else {
|
|
8767
8949
|
this._stat = statMethod;
|
|
8768
8950
|
}
|
|
8769
|
-
this._maxDepth = opts.depth
|
|
8951
|
+
this._maxDepth = opts.depth != null && Number.isSafeInteger(opts.depth) ? opts.depth : defaultOptions.depth;
|
|
8770
8952
|
this._wantsDir = type ? DIR_TYPES.has(type) : false;
|
|
8771
8953
|
this._wantsFile = type ? FILE_TYPES.has(type) : false;
|
|
8772
8954
|
this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE;
|
|
@@ -8911,11 +9093,11 @@ function readdirp(root, options = {}) {
|
|
|
8911
9093
|
return new ReaddirpStream(options);
|
|
8912
9094
|
}
|
|
8913
9095
|
|
|
8914
|
-
// node_modules/chokidar/
|
|
8915
|
-
import {
|
|
8916
|
-
import {
|
|
8917
|
-
import * as sysPath from "path";
|
|
9096
|
+
// node_modules/chokidar/handler.js
|
|
9097
|
+
import { watch as fs_watch, unwatchFile, watchFile } from "fs";
|
|
9098
|
+
import { realpath as fsrealpath, lstat as lstat2, open, stat as stat2 } from "fs/promises";
|
|
8918
9099
|
import { type as osType } from "os";
|
|
9100
|
+
import * as sp from "path";
|
|
8919
9101
|
var STR_DATA = "data";
|
|
8920
9102
|
var STR_END = "end";
|
|
8921
9103
|
var STR_CLOSE = "close";
|
|
@@ -9207,7 +9389,7 @@ var binaryExtensions = new Set([
|
|
|
9207
9389
|
"zip",
|
|
9208
9390
|
"zipx"
|
|
9209
9391
|
]);
|
|
9210
|
-
var isBinaryPath = (filePath) => binaryExtensions.has(
|
|
9392
|
+
var isBinaryPath = (filePath) => binaryExtensions.has(sp.extname(filePath).slice(1).toLowerCase());
|
|
9211
9393
|
var foreach = (val, fn) => {
|
|
9212
9394
|
if (val instanceof Set) {
|
|
9213
9395
|
val.forEach(fn);
|
|
@@ -9245,7 +9427,7 @@ function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
|
|
|
9245
9427
|
listener(path);
|
|
9246
9428
|
emitRaw(rawEvent, evPath, { watchedPath: path });
|
|
9247
9429
|
if (evPath && path !== evPath) {
|
|
9248
|
-
fsWatchBroadcast(
|
|
9430
|
+
fsWatchBroadcast(sp.resolve(path, evPath), KEY_LISTENERS, sp.join(path, evPath));
|
|
9249
9431
|
}
|
|
9250
9432
|
};
|
|
9251
9433
|
try {
|
|
@@ -9360,17 +9542,19 @@ var setFsWatchFileListener = (path, fullPath, options, handlers) => {
|
|
|
9360
9542
|
};
|
|
9361
9543
|
|
|
9362
9544
|
class NodeFsHandler {
|
|
9545
|
+
fsw;
|
|
9546
|
+
_boundHandleError;
|
|
9363
9547
|
constructor(fsW) {
|
|
9364
9548
|
this.fsw = fsW;
|
|
9365
9549
|
this._boundHandleError = (error2) => fsW._handleError(error2);
|
|
9366
9550
|
}
|
|
9367
9551
|
_watchWithNodeFs(path, listener) {
|
|
9368
9552
|
const opts = this.fsw.options;
|
|
9369
|
-
const directory =
|
|
9370
|
-
const basename4 =
|
|
9553
|
+
const directory = sp.dirname(path);
|
|
9554
|
+
const basename4 = sp.basename(path);
|
|
9371
9555
|
const parent = this.fsw._getWatchedDir(directory);
|
|
9372
9556
|
parent.add(basename4);
|
|
9373
|
-
const absolutePath =
|
|
9557
|
+
const absolutePath = sp.resolve(path);
|
|
9374
9558
|
const options = {
|
|
9375
9559
|
persistent: opts.persistent
|
|
9376
9560
|
};
|
|
@@ -9397,9 +9581,9 @@ class NodeFsHandler {
|
|
|
9397
9581
|
if (this.fsw.closed) {
|
|
9398
9582
|
return;
|
|
9399
9583
|
}
|
|
9400
|
-
const
|
|
9401
|
-
const basename4 =
|
|
9402
|
-
const parent = this.fsw._getWatchedDir(
|
|
9584
|
+
const dirname4 = sp.dirname(file);
|
|
9585
|
+
const basename4 = sp.basename(file);
|
|
9586
|
+
const parent = this.fsw._getWatchedDir(dirname4);
|
|
9403
9587
|
let prevStats = stats;
|
|
9404
9588
|
if (parent.has(basename4))
|
|
9405
9589
|
return;
|
|
@@ -9426,7 +9610,7 @@ class NodeFsHandler {
|
|
|
9426
9610
|
prevStats = newStats2;
|
|
9427
9611
|
}
|
|
9428
9612
|
} catch (error2) {
|
|
9429
|
-
this.fsw._remove(
|
|
9613
|
+
this.fsw._remove(dirname4, basename4);
|
|
9430
9614
|
}
|
|
9431
9615
|
} else if (parent.has(basename4)) {
|
|
9432
9616
|
const at = newStats.atimeMs;
|
|
@@ -9481,8 +9665,9 @@ class NodeFsHandler {
|
|
|
9481
9665
|
this.fsw._symlinkPaths.set(full, true);
|
|
9482
9666
|
}
|
|
9483
9667
|
_handleRead(directory, initialAdd, wh, target, dir, depth, throttler) {
|
|
9484
|
-
directory =
|
|
9485
|
-
|
|
9668
|
+
directory = sp.join(directory, "");
|
|
9669
|
+
const throttleKey = target ? `${directory}:${target}` : directory;
|
|
9670
|
+
throttler = this.fsw._throttle("readdir", throttleKey, 1000);
|
|
9486
9671
|
if (!throttler)
|
|
9487
9672
|
return;
|
|
9488
9673
|
const previous = this.fsw._getWatchedDir(wh.path);
|
|
@@ -9499,7 +9684,7 @@ class NodeFsHandler {
|
|
|
9499
9684
|
return;
|
|
9500
9685
|
}
|
|
9501
9686
|
const item = entry.path;
|
|
9502
|
-
let path =
|
|
9687
|
+
let path = sp.join(directory, item);
|
|
9503
9688
|
current.add(item);
|
|
9504
9689
|
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path, item)) {
|
|
9505
9690
|
return;
|
|
@@ -9510,7 +9695,7 @@ class NodeFsHandler {
|
|
|
9510
9695
|
}
|
|
9511
9696
|
if (item === target || !target && !previous.has(item)) {
|
|
9512
9697
|
this.fsw._incrReadyCount();
|
|
9513
|
-
path =
|
|
9698
|
+
path = sp.join(dir, sp.relative(dir, path));
|
|
9514
9699
|
this._addToNodeFs(path, initialAdd, wh, depth + 1);
|
|
9515
9700
|
}
|
|
9516
9701
|
}).on(EV.ERROR, this._boundHandleError);
|
|
@@ -9536,12 +9721,12 @@ class NodeFsHandler {
|
|
|
9536
9721
|
});
|
|
9537
9722
|
}
|
|
9538
9723
|
async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath2) {
|
|
9539
|
-
const parentDir = this.fsw._getWatchedDir(
|
|
9540
|
-
const tracked = parentDir.has(
|
|
9724
|
+
const parentDir = this.fsw._getWatchedDir(sp.dirname(dir));
|
|
9725
|
+
const tracked = parentDir.has(sp.basename(dir));
|
|
9541
9726
|
if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) {
|
|
9542
9727
|
this.fsw._emit(EV.ADD_DIR, dir, stats);
|
|
9543
9728
|
}
|
|
9544
|
-
parentDir.add(
|
|
9729
|
+
parentDir.add(sp.basename(dir));
|
|
9545
9730
|
this.fsw._getWatchedDir(dir);
|
|
9546
9731
|
let throttler;
|
|
9547
9732
|
let closer;
|
|
@@ -9582,7 +9767,7 @@ class NodeFsHandler {
|
|
|
9582
9767
|
const follow = this.fsw.options.followSymlinks;
|
|
9583
9768
|
let closer;
|
|
9584
9769
|
if (stats.isDirectory()) {
|
|
9585
|
-
const absPath =
|
|
9770
|
+
const absPath = sp.resolve(path);
|
|
9586
9771
|
const targetPath = follow ? await fsrealpath(path) : path;
|
|
9587
9772
|
if (this.fsw.closed)
|
|
9588
9773
|
return;
|
|
@@ -9596,14 +9781,14 @@ class NodeFsHandler {
|
|
|
9596
9781
|
const targetPath = follow ? await fsrealpath(path) : path;
|
|
9597
9782
|
if (this.fsw.closed)
|
|
9598
9783
|
return;
|
|
9599
|
-
const parent =
|
|
9784
|
+
const parent = sp.dirname(wh.watchPath);
|
|
9600
9785
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
9601
9786
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
9602
9787
|
closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath);
|
|
9603
9788
|
if (this.fsw.closed)
|
|
9604
9789
|
return;
|
|
9605
9790
|
if (targetPath !== undefined) {
|
|
9606
|
-
this.fsw._symlinkPaths.set(
|
|
9791
|
+
this.fsw._symlinkPaths.set(sp.resolve(path), targetPath);
|
|
9607
9792
|
}
|
|
9608
9793
|
} else {
|
|
9609
9794
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
@@ -9621,7 +9806,7 @@ class NodeFsHandler {
|
|
|
9621
9806
|
}
|
|
9622
9807
|
}
|
|
9623
9808
|
|
|
9624
|
-
// node_modules/chokidar/
|
|
9809
|
+
// node_modules/chokidar/index.js
|
|
9625
9810
|
/*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) */
|
|
9626
9811
|
var SLASH = "/";
|
|
9627
9812
|
var SLASH_SLASH = "//";
|
|
@@ -9629,7 +9814,7 @@ var ONE_DOT = ".";
|
|
|
9629
9814
|
var TWO_DOTS = "..";
|
|
9630
9815
|
var STRING_TYPE = "string";
|
|
9631
9816
|
var BACK_SLASH_RE = /\\/g;
|
|
9632
|
-
var DOUBLE_SLASH_RE =
|
|
9817
|
+
var DOUBLE_SLASH_RE = /\/\//g;
|
|
9633
9818
|
var DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/;
|
|
9634
9819
|
var REPLACER_RE = /^\.[/\\]/;
|
|
9635
9820
|
function arrify(item) {
|
|
@@ -9648,11 +9833,11 @@ function createPattern(matcher) {
|
|
|
9648
9833
|
if (matcher.path === string)
|
|
9649
9834
|
return true;
|
|
9650
9835
|
if (matcher.recursive) {
|
|
9651
|
-
const
|
|
9652
|
-
if (!
|
|
9836
|
+
const relative5 = sp2.relative(matcher.path, string);
|
|
9837
|
+
if (!relative5) {
|
|
9653
9838
|
return false;
|
|
9654
9839
|
}
|
|
9655
|
-
return !
|
|
9840
|
+
return !relative5.startsWith("..") && !sp2.isAbsolute(relative5);
|
|
9656
9841
|
}
|
|
9657
9842
|
return false;
|
|
9658
9843
|
};
|
|
@@ -9662,14 +9847,12 @@ function createPattern(matcher) {
|
|
|
9662
9847
|
function normalizePath(path) {
|
|
9663
9848
|
if (typeof path !== "string")
|
|
9664
9849
|
throw new Error("string expected");
|
|
9665
|
-
path =
|
|
9850
|
+
path = sp2.normalize(path);
|
|
9666
9851
|
path = path.replace(/\\/g, "/");
|
|
9667
9852
|
let prepend = false;
|
|
9668
9853
|
if (path.startsWith("//"))
|
|
9669
9854
|
prepend = true;
|
|
9670
|
-
|
|
9671
|
-
while (path.match(DOUBLE_SLASH_RE2))
|
|
9672
|
-
path = path.replace(DOUBLE_SLASH_RE2, "/");
|
|
9855
|
+
path = path.replace(DOUBLE_SLASH_RE, "/");
|
|
9673
9856
|
if (prepend)
|
|
9674
9857
|
path = "/" + path;
|
|
9675
9858
|
return path;
|
|
@@ -9710,31 +9893,32 @@ var toUnix = (string) => {
|
|
|
9710
9893
|
if (str.startsWith(SLASH_SLASH)) {
|
|
9711
9894
|
prepend = true;
|
|
9712
9895
|
}
|
|
9713
|
-
|
|
9714
|
-
str = str.replace(DOUBLE_SLASH_RE, SLASH);
|
|
9715
|
-
}
|
|
9896
|
+
str = str.replace(DOUBLE_SLASH_RE, SLASH);
|
|
9716
9897
|
if (prepend) {
|
|
9717
9898
|
str = SLASH + str;
|
|
9718
9899
|
}
|
|
9719
9900
|
return str;
|
|
9720
9901
|
};
|
|
9721
|
-
var normalizePathToUnix = (path) => toUnix(
|
|
9902
|
+
var normalizePathToUnix = (path) => toUnix(sp2.normalize(toUnix(path)));
|
|
9722
9903
|
var normalizeIgnored = (cwd = "") => (path) => {
|
|
9723
9904
|
if (typeof path === "string") {
|
|
9724
|
-
return normalizePathToUnix(
|
|
9905
|
+
return normalizePathToUnix(sp2.isAbsolute(path) ? path : sp2.join(cwd, path));
|
|
9725
9906
|
} else {
|
|
9726
9907
|
return path;
|
|
9727
9908
|
}
|
|
9728
9909
|
};
|
|
9729
9910
|
var getAbsolutePath = (path, cwd) => {
|
|
9730
|
-
if (
|
|
9911
|
+
if (sp2.isAbsolute(path)) {
|
|
9731
9912
|
return path;
|
|
9732
9913
|
}
|
|
9733
|
-
return
|
|
9914
|
+
return sp2.join(cwd, path);
|
|
9734
9915
|
};
|
|
9735
9916
|
var EMPTY_SET = Object.freeze(new Set);
|
|
9736
9917
|
|
|
9737
9918
|
class DirEntry {
|
|
9919
|
+
path;
|
|
9920
|
+
_removeWatcher;
|
|
9921
|
+
items;
|
|
9738
9922
|
constructor(dir, removeWatcher) {
|
|
9739
9923
|
this.path = dir;
|
|
9740
9924
|
this._removeWatcher = removeWatcher;
|
|
@@ -9759,7 +9943,7 @@ class DirEntry {
|
|
|
9759
9943
|
await readdir2(dir);
|
|
9760
9944
|
} catch (err) {
|
|
9761
9945
|
if (this._removeWatcher) {
|
|
9762
|
-
this._removeWatcher(
|
|
9946
|
+
this._removeWatcher(sp2.dirname(dir), sp2.basename(dir));
|
|
9763
9947
|
}
|
|
9764
9948
|
}
|
|
9765
9949
|
}
|
|
@@ -9787,12 +9971,19 @@ var STAT_METHOD_F = "stat";
|
|
|
9787
9971
|
var STAT_METHOD_L = "lstat";
|
|
9788
9972
|
|
|
9789
9973
|
class WatchHelper {
|
|
9974
|
+
fsw;
|
|
9975
|
+
path;
|
|
9976
|
+
watchPath;
|
|
9977
|
+
fullWatchPath;
|
|
9978
|
+
dirParts;
|
|
9979
|
+
followSymlinks;
|
|
9980
|
+
statMethod;
|
|
9790
9981
|
constructor(path, follow, fsw) {
|
|
9791
9982
|
this.fsw = fsw;
|
|
9792
9983
|
const watchPath = path;
|
|
9793
9984
|
this.path = path = path.replace(REPLACER_RE, "");
|
|
9794
9985
|
this.watchPath = watchPath;
|
|
9795
|
-
this.fullWatchPath =
|
|
9986
|
+
this.fullWatchPath = sp2.resolve(watchPath);
|
|
9796
9987
|
this.dirParts = [];
|
|
9797
9988
|
this.dirParts.forEach((parts) => {
|
|
9798
9989
|
if (parts.length > 1)
|
|
@@ -9802,7 +9993,7 @@ class WatchHelper {
|
|
|
9802
9993
|
this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L;
|
|
9803
9994
|
}
|
|
9804
9995
|
entryPath(entry) {
|
|
9805
|
-
return
|
|
9996
|
+
return sp2.join(this.watchPath, sp2.relative(this.watchPath, entry.fullPath));
|
|
9806
9997
|
}
|
|
9807
9998
|
filterPath(entry) {
|
|
9808
9999
|
const { stats } = entry;
|
|
@@ -9817,6 +10008,24 @@ class WatchHelper {
|
|
|
9817
10008
|
}
|
|
9818
10009
|
|
|
9819
10010
|
class FSWatcher extends EventEmitter {
|
|
10011
|
+
closed;
|
|
10012
|
+
options;
|
|
10013
|
+
_closers;
|
|
10014
|
+
_ignoredPaths;
|
|
10015
|
+
_throttled;
|
|
10016
|
+
_streams;
|
|
10017
|
+
_symlinkPaths;
|
|
10018
|
+
_watched;
|
|
10019
|
+
_pendingWrites;
|
|
10020
|
+
_pendingUnlinks;
|
|
10021
|
+
_readyCount;
|
|
10022
|
+
_emitReady;
|
|
10023
|
+
_closePromise;
|
|
10024
|
+
_userIgnored;
|
|
10025
|
+
_readyEmitted;
|
|
10026
|
+
_emitRaw;
|
|
10027
|
+
_boundRemove;
|
|
10028
|
+
_nodeFsHandler;
|
|
9820
10029
|
constructor(_opts = {}) {
|
|
9821
10030
|
super();
|
|
9822
10031
|
this.closed = false;
|
|
@@ -9925,7 +10134,7 @@ class FSWatcher extends EventEmitter {
|
|
|
9925
10134
|
return;
|
|
9926
10135
|
results.forEach((item) => {
|
|
9927
10136
|
if (item)
|
|
9928
|
-
this.add(
|
|
10137
|
+
this.add(sp2.dirname(item), sp2.basename(_origAdd || item));
|
|
9929
10138
|
});
|
|
9930
10139
|
});
|
|
9931
10140
|
return this;
|
|
@@ -9936,10 +10145,10 @@ class FSWatcher extends EventEmitter {
|
|
|
9936
10145
|
const paths = unifyPaths(paths_);
|
|
9937
10146
|
const { cwd } = this.options;
|
|
9938
10147
|
paths.forEach((path) => {
|
|
9939
|
-
if (!
|
|
10148
|
+
if (!sp2.isAbsolute(path) && !this._closers.has(path)) {
|
|
9940
10149
|
if (cwd)
|
|
9941
|
-
path =
|
|
9942
|
-
path =
|
|
10150
|
+
path = sp2.join(cwd, path);
|
|
10151
|
+
path = sp2.resolve(path);
|
|
9943
10152
|
}
|
|
9944
10153
|
this._closePath(path);
|
|
9945
10154
|
this._addIgnoredPath(path);
|
|
@@ -9983,7 +10192,7 @@ class FSWatcher extends EventEmitter {
|
|
|
9983
10192
|
getWatched() {
|
|
9984
10193
|
const watchList = {};
|
|
9985
10194
|
this._watched.forEach((entry, dir) => {
|
|
9986
|
-
const key = this.options.cwd ?
|
|
10195
|
+
const key = this.options.cwd ? sp2.relative(this.options.cwd, dir) : dir;
|
|
9987
10196
|
const index = key || ONE_DOT;
|
|
9988
10197
|
watchList[index] = entry.getChildren().sort();
|
|
9989
10198
|
});
|
|
@@ -9999,9 +10208,9 @@ class FSWatcher extends EventEmitter {
|
|
|
9999
10208
|
return;
|
|
10000
10209
|
const opts = this.options;
|
|
10001
10210
|
if (isWindows)
|
|
10002
|
-
path =
|
|
10211
|
+
path = sp2.normalize(path);
|
|
10003
10212
|
if (opts.cwd)
|
|
10004
|
-
path =
|
|
10213
|
+
path = sp2.relative(opts.cwd, path);
|
|
10005
10214
|
const args = [path];
|
|
10006
10215
|
if (stats != null)
|
|
10007
10216
|
args.push(stats);
|
|
@@ -10052,7 +10261,7 @@ class FSWatcher extends EventEmitter {
|
|
|
10052
10261
|
return this;
|
|
10053
10262
|
}
|
|
10054
10263
|
if (opts.alwaysStat && stats === undefined && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
10055
|
-
const fullPath = opts.cwd ?
|
|
10264
|
+
const fullPath = opts.cwd ? sp2.join(opts.cwd, path) : path;
|
|
10056
10265
|
let stats2;
|
|
10057
10266
|
try {
|
|
10058
10267
|
stats2 = await stat3(fullPath);
|
|
@@ -10108,8 +10317,8 @@ class FSWatcher extends EventEmitter {
|
|
|
10108
10317
|
const pollInterval = awf.pollInterval;
|
|
10109
10318
|
let timeoutHandler;
|
|
10110
10319
|
let fullPath = path;
|
|
10111
|
-
if (this.options.cwd && !
|
|
10112
|
-
fullPath =
|
|
10320
|
+
if (this.options.cwd && !sp2.isAbsolute(path)) {
|
|
10321
|
+
fullPath = sp2.join(this.options.cwd, path);
|
|
10113
10322
|
}
|
|
10114
10323
|
const now = new Date;
|
|
10115
10324
|
const writes = this._pendingWrites;
|
|
@@ -10166,7 +10375,7 @@ class FSWatcher extends EventEmitter {
|
|
|
10166
10375
|
return new WatchHelper(path, this.options.followSymlinks, this);
|
|
10167
10376
|
}
|
|
10168
10377
|
_getWatchedDir(directory) {
|
|
10169
|
-
const dir =
|
|
10378
|
+
const dir = sp2.resolve(directory);
|
|
10170
10379
|
if (!this._watched.has(dir))
|
|
10171
10380
|
this._watched.set(dir, new DirEntry(dir, this._boundRemove));
|
|
10172
10381
|
return this._watched.get(dir);
|
|
@@ -10177,8 +10386,8 @@ class FSWatcher extends EventEmitter {
|
|
|
10177
10386
|
return Boolean(Number(stats.mode) & 256);
|
|
10178
10387
|
}
|
|
10179
10388
|
_remove(directory, item, isDirectory) {
|
|
10180
|
-
const path =
|
|
10181
|
-
const fullPath =
|
|
10389
|
+
const path = sp2.join(directory, item);
|
|
10390
|
+
const fullPath = sp2.resolve(path);
|
|
10182
10391
|
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path) || this._watched.has(fullPath);
|
|
10183
10392
|
if (!this._throttle("remove", path, 100))
|
|
10184
10393
|
return;
|
|
@@ -10196,7 +10405,7 @@ class FSWatcher extends EventEmitter {
|
|
|
10196
10405
|
}
|
|
10197
10406
|
let relPath = path;
|
|
10198
10407
|
if (this.options.cwd)
|
|
10199
|
-
relPath =
|
|
10408
|
+
relPath = sp2.relative(this.options.cwd, path);
|
|
10200
10409
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
10201
10410
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
10202
10411
|
if (event === EVENTS.ADD)
|
|
@@ -10211,8 +10420,8 @@ class FSWatcher extends EventEmitter {
|
|
|
10211
10420
|
}
|
|
10212
10421
|
_closePath(path) {
|
|
10213
10422
|
this._closeFile(path);
|
|
10214
|
-
const dir =
|
|
10215
|
-
this._getWatchedDir(dir).remove(
|
|
10423
|
+
const dir = sp2.dirname(path);
|
|
10424
|
+
this._getWatchedDir(dir).remove(sp2.basename(path));
|
|
10216
10425
|
}
|
|
10217
10426
|
_closeFile(path) {
|
|
10218
10427
|
const closers = this._closers.get(path);
|
|
@@ -10258,8 +10467,8 @@ function watch(paths, options = {}) {
|
|
|
10258
10467
|
// src/commands/dev.ts
|
|
10259
10468
|
function getEntryWatchPaths(root) {
|
|
10260
10469
|
return [
|
|
10261
|
-
|
|
10262
|
-
|
|
10470
|
+
join10(root, MANIFEST_FILE),
|
|
10471
|
+
join10(root, "src", "actions.ts")
|
|
10263
10472
|
];
|
|
10264
10473
|
}
|
|
10265
10474
|
async function dev() {
|
|
@@ -10298,26 +10507,59 @@ async function dev() {
|
|
|
10298
10507
|
}
|
|
10299
10508
|
console.log(source_default.blue("Actions changed -- entry regenerated"));
|
|
10300
10509
|
});
|
|
10301
|
-
const distDir =
|
|
10302
|
-
const bundleFile =
|
|
10510
|
+
const distDir = join10(root, "dist");
|
|
10511
|
+
const bundleFile = join10(distDir, `space-${m.id}.iife.js`);
|
|
10512
|
+
const cssFile = join10(distDir, `space-${m.id}.css`);
|
|
10303
10513
|
let lastChecksum = "";
|
|
10304
|
-
const
|
|
10305
|
-
|
|
10306
|
-
if (!existsSync7(bundleFile))
|
|
10514
|
+
const packageSpace = (force = false) => {
|
|
10515
|
+
if (!existsSync8(bundleFile) || !existsSync8(cssFile))
|
|
10307
10516
|
return;
|
|
10308
10517
|
const bundleData = readFileSync5(bundleFile);
|
|
10309
|
-
const checksum =
|
|
10310
|
-
if (checksum === lastChecksum)
|
|
10518
|
+
const checksum = createHash3("sha256").update(bundleData).digest("hex");
|
|
10519
|
+
if (!force && checksum === lastChecksum)
|
|
10311
10520
|
return;
|
|
10312
10521
|
lastChecksum = checksum;
|
|
10313
10522
|
const raw = readRaw(root);
|
|
10314
10523
|
writeWithBuild(distDir, raw, {
|
|
10315
10524
|
checksum,
|
|
10316
10525
|
size: bundleData.length,
|
|
10317
|
-
hostApiVersion:
|
|
10526
|
+
hostApiVersion: HOST_API_VERSION,
|
|
10318
10527
|
builtAt: new Date().toISOString()
|
|
10319
10528
|
});
|
|
10320
|
-
|
|
10529
|
+
stageSpaceResources(root, distDir);
|
|
10530
|
+
buildSpaceTools(root, distDir, m.id);
|
|
10531
|
+
createSpaceBundle({
|
|
10532
|
+
distDir,
|
|
10533
|
+
spaceId: m.id,
|
|
10534
|
+
appBundlePath: bundleFile,
|
|
10535
|
+
cssPath: cssFile
|
|
10536
|
+
});
|
|
10537
|
+
console.log(source_default.green(`Built -> dist/${m.id}.space (${(bundleData.length / 1024).toFixed(1)} KB)`));
|
|
10538
|
+
};
|
|
10539
|
+
const distWatcher = watch([bundleFile, cssFile], { ignoreInitial: false });
|
|
10540
|
+
distWatcher.on("all", () => {
|
|
10541
|
+
try {
|
|
10542
|
+
packageSpace();
|
|
10543
|
+
} catch (err) {
|
|
10544
|
+
console.error(source_default.red(err?.message || String(err)));
|
|
10545
|
+
}
|
|
10546
|
+
});
|
|
10547
|
+
const resourceWatcher = watch([
|
|
10548
|
+
join10(root, "tools.go"),
|
|
10549
|
+
join10(root, "tools"),
|
|
10550
|
+
join10(root, "lib"),
|
|
10551
|
+
join10(root, "agent"),
|
|
10552
|
+
join10(root, "scripts"),
|
|
10553
|
+
join10(root, "references"),
|
|
10554
|
+
join10(root, "assets"),
|
|
10555
|
+
join10(root, "SKILL.md")
|
|
10556
|
+
], { ignoreInitial: true });
|
|
10557
|
+
resourceWatcher.on("all", () => {
|
|
10558
|
+
try {
|
|
10559
|
+
packageSpace(true);
|
|
10560
|
+
} catch (err) {
|
|
10561
|
+
console.error(source_default.red(err?.message || String(err)));
|
|
10562
|
+
}
|
|
10321
10563
|
});
|
|
10322
10564
|
console.log(source_default.green("Watching for changes... (Ctrl+C to stop)"));
|
|
10323
10565
|
console.log(source_default.dim("Use the Preview button in Construct to open the Space Runner"));
|
|
@@ -10326,19 +10568,16 @@ async function dev() {
|
|
|
10326
10568
|
|
|
10327
10569
|
// src/commands/run.ts
|
|
10328
10570
|
init_source();
|
|
10329
|
-
import { existsSync as
|
|
10330
|
-
import { join as
|
|
10571
|
+
import { existsSync as existsSync10, cpSync as cpSync2, mkdirSync as mkdirSync5, readdirSync as readdirSync4, chmodSync, lstatSync as lstatSync2, rmSync as rmSync3 } from "fs";
|
|
10572
|
+
import { join as join12 } from "path";
|
|
10331
10573
|
init_appdir();
|
|
10332
|
-
function
|
|
10574
|
+
function ensureExecutableResources(installDir) {
|
|
10333
10575
|
if (process.platform === "win32")
|
|
10334
10576
|
return;
|
|
10335
|
-
const binRoot = join11(installDir, "bin");
|
|
10336
|
-
if (!existsSync9(binRoot))
|
|
10337
|
-
return;
|
|
10338
10577
|
const walk = (dir) => {
|
|
10339
10578
|
for (const name of readdirSync4(dir)) {
|
|
10340
|
-
const path =
|
|
10341
|
-
const st =
|
|
10579
|
+
const path = join12(dir, name);
|
|
10580
|
+
const st = lstatSync2(path);
|
|
10342
10581
|
if (st.isSymbolicLink())
|
|
10343
10582
|
continue;
|
|
10344
10583
|
if (st.isDirectory()) {
|
|
@@ -10348,7 +10587,11 @@ function ensureBinExecutable(installDir) {
|
|
|
10348
10587
|
}
|
|
10349
10588
|
}
|
|
10350
10589
|
};
|
|
10351
|
-
|
|
10590
|
+
for (const dirname5 of ["tools", "lib"]) {
|
|
10591
|
+
const root = join12(installDir, dirname5);
|
|
10592
|
+
if (existsSync10(root))
|
|
10593
|
+
walk(root);
|
|
10594
|
+
}
|
|
10352
10595
|
}
|
|
10353
10596
|
function install() {
|
|
10354
10597
|
const root = process.cwd();
|
|
@@ -10356,34 +10599,36 @@ function install() {
|
|
|
10356
10599
|
console.error(source_default.red("No space.manifest.json found in current directory"));
|
|
10357
10600
|
process.exit(1);
|
|
10358
10601
|
}
|
|
10359
|
-
const distDir =
|
|
10360
|
-
if (!
|
|
10602
|
+
const distDir = join12(root, "dist");
|
|
10603
|
+
if (!existsSync10(distDir)) {
|
|
10361
10604
|
console.error(source_default.red("No dist/ directory found. Run 'construct build' first."));
|
|
10362
10605
|
process.exit(1);
|
|
10363
10606
|
}
|
|
10364
10607
|
const m = read(root);
|
|
10365
|
-
const
|
|
10366
|
-
if (
|
|
10367
|
-
|
|
10608
|
+
const bundleDir = join12(distDir, `${m.id}.space`);
|
|
10609
|
+
if (!existsSync10(bundleDir)) {
|
|
10610
|
+
console.error(source_default.red(`No dist/${m.id}.space directory found. Run 'construct build' first.`));
|
|
10611
|
+
process.exit(1);
|
|
10368
10612
|
}
|
|
10369
10613
|
const installDir = spaceDir(m.id);
|
|
10370
|
-
|
|
10371
|
-
|
|
10372
|
-
|
|
10373
|
-
|
|
10614
|
+
rmSync3(join12(spacesDir(), m.id), { recursive: true, force: true });
|
|
10615
|
+
rmSync3(installDir, { recursive: true, force: true });
|
|
10616
|
+
mkdirSync5(installDir, { recursive: true });
|
|
10617
|
+
cpSync2(bundleDir, installDir, { recursive: true, verbatimSymlinks: true, force: true });
|
|
10618
|
+
ensureExecutableResources(installDir);
|
|
10374
10619
|
console.log(source_default.green(`Installed ${m.name} -> ${installDir}`));
|
|
10375
10620
|
console.log(source_default.dim(" Restart Construct to load the updated space."));
|
|
10376
10621
|
}
|
|
10377
10622
|
|
|
10378
10623
|
// src/commands/publish.ts
|
|
10379
10624
|
init_source();
|
|
10380
|
-
import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, statSync as
|
|
10381
|
-
import { join as
|
|
10625
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, statSync as statSync4, unlinkSync as unlinkSync2 } from "fs";
|
|
10626
|
+
import { join as join15, basename as basename5 } from "path";
|
|
10382
10627
|
init_auth();
|
|
10383
10628
|
|
|
10384
10629
|
// src/lib/pack.ts
|
|
10385
|
-
import { readdirSync as readdirSync6, statSync as
|
|
10386
|
-
import { join as
|
|
10630
|
+
import { readdirSync as readdirSync6, statSync as statSync3, existsSync as existsSync12 } from "fs";
|
|
10631
|
+
import { join as join14 } from "path";
|
|
10387
10632
|
import { tmpdir } from "os";
|
|
10388
10633
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
10389
10634
|
var allowedDirs = [
|
|
@@ -10406,7 +10651,9 @@ var allowedDirs = [
|
|
|
10406
10651
|
"icons",
|
|
10407
10652
|
"assets",
|
|
10408
10653
|
"media",
|
|
10409
|
-
"
|
|
10654
|
+
"tools",
|
|
10655
|
+
"lib",
|
|
10656
|
+
"go-tools"
|
|
10410
10657
|
];
|
|
10411
10658
|
var allowedRootFiles = [
|
|
10412
10659
|
"space.manifest.json",
|
|
@@ -10416,20 +10663,24 @@ var allowedRootFiles = [
|
|
|
10416
10663
|
"vite.config.js",
|
|
10417
10664
|
"space.config.ts",
|
|
10418
10665
|
"types.ts",
|
|
10419
|
-
"index.ts"
|
|
10666
|
+
"index.ts",
|
|
10667
|
+
"SKILL.md",
|
|
10668
|
+
"tools.go",
|
|
10669
|
+
"go.mod",
|
|
10670
|
+
"go.sum"
|
|
10420
10671
|
];
|
|
10421
10672
|
var allowedRootPatterns = [/.*\.config\.ts$/, /.*\.config\.js$/];
|
|
10422
10673
|
var blockedExtensions = [".env", ".log", ".lock", ".lockb"];
|
|
10423
10674
|
var MAX_SIZE = 50 * 1024 * 1024;
|
|
10424
10675
|
async function packSource(root) {
|
|
10425
|
-
const tarballPath =
|
|
10676
|
+
const tarballPath = join14(tmpdir(), `space-source-${Date.now()}.tar.gz`);
|
|
10426
10677
|
const entries = [];
|
|
10427
10678
|
for (const name of allowedRootFiles) {
|
|
10428
|
-
if (
|
|
10679
|
+
if (existsSync12(join14(root, name)))
|
|
10429
10680
|
entries.push(name);
|
|
10430
10681
|
}
|
|
10431
10682
|
for (const entry of readdirSync6(root)) {
|
|
10432
|
-
if (
|
|
10683
|
+
if (statSync3(join14(root, entry)).isDirectory())
|
|
10433
10684
|
continue;
|
|
10434
10685
|
if (allowedRootFiles.includes(entry))
|
|
10435
10686
|
continue;
|
|
@@ -10439,10 +10690,10 @@ async function packSource(root) {
|
|
|
10439
10690
|
entries.push(entry);
|
|
10440
10691
|
}
|
|
10441
10692
|
for (const dir of allowedDirs) {
|
|
10442
|
-
if (
|
|
10693
|
+
if (existsSync12(join14(root, dir)))
|
|
10443
10694
|
entries.push(dir);
|
|
10444
10695
|
}
|
|
10445
|
-
const validEntries = entries.filter((e) =>
|
|
10696
|
+
const validEntries = entries.filter((e) => existsSync12(join14(root, e)));
|
|
10446
10697
|
if (validEntries.length === 0) {
|
|
10447
10698
|
throw new Error("No files to pack");
|
|
10448
10699
|
}
|
|
@@ -10450,13 +10701,15 @@ async function packSource(root) {
|
|
|
10450
10701
|
"--exclude=node_modules",
|
|
10451
10702
|
"--exclude=dist",
|
|
10452
10703
|
"--exclude=.git",
|
|
10704
|
+
"--exclude=go-tools/spaceprobe",
|
|
10705
|
+
"--exclude=go-tools/spaceprobe.exe",
|
|
10453
10706
|
"--exclude=*.env",
|
|
10454
10707
|
"--exclude=*.log",
|
|
10455
10708
|
"--exclude=*.lock",
|
|
10456
10709
|
"--exclude=*.lockb"
|
|
10457
10710
|
];
|
|
10458
10711
|
execFileSync2("tar", ["czf", tarballPath, ...excludes, ...validEntries], { cwd: root });
|
|
10459
|
-
const size =
|
|
10712
|
+
const size = statSync3(tarballPath).size;
|
|
10460
10713
|
if (size > MAX_SIZE) {
|
|
10461
10714
|
throw new Error(`Source exceeds maximum size of ${MAX_SIZE / 1024 / 1024}MB`);
|
|
10462
10715
|
}
|
|
@@ -10535,7 +10788,7 @@ function setVersionInFiles(root, oldVer, newVer) {
|
|
|
10535
10788
|
const oldStr = `"version": "${oldVer}"`;
|
|
10536
10789
|
const newStr = `"version": "${newVer}"`;
|
|
10537
10790
|
for (const file of ["package.json", "space.manifest.json"]) {
|
|
10538
|
-
const path =
|
|
10791
|
+
const path = join15(root, file);
|
|
10539
10792
|
try {
|
|
10540
10793
|
const data = readFileSync8(path, "utf-8");
|
|
10541
10794
|
writeFileSync6(path, data.replace(oldStr, newStr));
|
|
@@ -10694,7 +10947,7 @@ async function publish(options) {
|
|
|
10694
10947
|
let tarballPath;
|
|
10695
10948
|
try {
|
|
10696
10949
|
tarballPath = await packSource(root);
|
|
10697
|
-
const size =
|
|
10950
|
+
const size = statSync4(tarballPath).size;
|
|
10698
10951
|
spinner.succeed(`Source packed (${formatBytes(size)})`);
|
|
10699
10952
|
} catch (err) {
|
|
10700
10953
|
spinner.fail("Pack failed");
|
|
@@ -10762,8 +11015,8 @@ async function publish(options) {
|
|
|
10762
11015
|
|
|
10763
11016
|
// src/commands/validate.ts
|
|
10764
11017
|
init_source();
|
|
10765
|
-
import { existsSync as
|
|
10766
|
-
import { join as
|
|
11018
|
+
import { existsSync as existsSync13, readFileSync as readFileSync9 } from "fs";
|
|
11019
|
+
import { join as join16 } from "path";
|
|
10767
11020
|
|
|
10768
11021
|
// src/lib/pagePaths.ts
|
|
10769
11022
|
function pageComponentFromPath(path) {
|
|
@@ -10797,21 +11050,21 @@ function validate3() {
|
|
|
10797
11050
|
let warnings = 0;
|
|
10798
11051
|
for (const page of m.pages) {
|
|
10799
11052
|
const component = page.component || pageComponentFromPath(page.path);
|
|
10800
|
-
const fullPath =
|
|
10801
|
-
if (!
|
|
11053
|
+
const fullPath = join16(root, "src", component);
|
|
11054
|
+
if (!existsSync13(fullPath)) {
|
|
10802
11055
|
console.log(source_default.yellow(` \u26A0 Page component not found: src/${component}`));
|
|
10803
11056
|
warnings++;
|
|
10804
11057
|
}
|
|
10805
11058
|
}
|
|
10806
11059
|
if (m.agent) {
|
|
10807
|
-
const agentPath =
|
|
10808
|
-
if (!
|
|
11060
|
+
const agentPath = join16(root, m.agent);
|
|
11061
|
+
if (!existsSync13(agentPath)) {
|
|
10809
11062
|
console.log(source_default.yellow(` \u26A0 Agent config not found: ${m.agent}`));
|
|
10810
11063
|
warnings++;
|
|
10811
11064
|
}
|
|
10812
11065
|
}
|
|
10813
|
-
const pkgPath =
|
|
10814
|
-
if (
|
|
11066
|
+
const pkgPath = join16(root, "package.json");
|
|
11067
|
+
if (existsSync13(pkgPath)) {
|
|
10815
11068
|
const pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
|
|
10816
11069
|
if (pkg.version && pkg.version !== m.version) {
|
|
10817
11070
|
console.log(source_default.yellow(` \u26A0 Version mismatch: manifest=${m.version} package.json=${pkg.version}`));
|
|
@@ -10828,8 +11081,8 @@ function validate3() {
|
|
|
10828
11081
|
// src/commands/check.ts
|
|
10829
11082
|
init_source();
|
|
10830
11083
|
import { execSync as execSync2 } from "child_process";
|
|
10831
|
-
import { existsSync as
|
|
10832
|
-
import { join as
|
|
11084
|
+
import { existsSync as existsSync14, readFileSync as readFileSync10 } from "fs";
|
|
11085
|
+
import { join as join17 } from "path";
|
|
10833
11086
|
function check() {
|
|
10834
11087
|
const root = process.cwd();
|
|
10835
11088
|
if (!exists(root)) {
|
|
@@ -10848,17 +11101,17 @@ function check() {
|
|
|
10848
11101
|
let warnings = 0;
|
|
10849
11102
|
for (const page of m.pages) {
|
|
10850
11103
|
const component = page.component || pageComponentFromPath(page.path);
|
|
10851
|
-
if (!
|
|
11104
|
+
if (!existsSync14(join17(root, "src", component))) {
|
|
10852
11105
|
console.log(source_default.yellow(` \u26A0 Page not found: src/${component}`));
|
|
10853
11106
|
warnings++;
|
|
10854
11107
|
}
|
|
10855
11108
|
}
|
|
10856
|
-
if (m.agent && !
|
|
11109
|
+
if (m.agent && !existsSync14(join17(root, m.agent))) {
|
|
10857
11110
|
console.log(source_default.yellow(` \u26A0 Agent config not found: ${m.agent}`));
|
|
10858
11111
|
warnings++;
|
|
10859
11112
|
}
|
|
10860
|
-
const pkgPath =
|
|
10861
|
-
if (
|
|
11113
|
+
const pkgPath = join17(root, "package.json");
|
|
11114
|
+
if (existsSync14(pkgPath)) {
|
|
10862
11115
|
const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
|
|
10863
11116
|
if (pkg.version && pkg.version !== m.version) {
|
|
10864
11117
|
console.log(source_default.yellow(` \u26A0 Version mismatch: manifest=${m.version} package.json=${pkg.version}`));
|
|
@@ -10891,8 +11144,8 @@ function check() {
|
|
|
10891
11144
|
|
|
10892
11145
|
// src/commands/clean.ts
|
|
10893
11146
|
init_source();
|
|
10894
|
-
import { rmSync as
|
|
10895
|
-
import { join as
|
|
11147
|
+
import { rmSync as rmSync4, existsSync as existsSync15 } from "fs";
|
|
11148
|
+
import { join as join18 } from "path";
|
|
10896
11149
|
function clean(options) {
|
|
10897
11150
|
const root = process.cwd();
|
|
10898
11151
|
const dirs = ["dist", ".vite"];
|
|
@@ -10901,17 +11154,17 @@ function clean(options) {
|
|
|
10901
11154
|
}
|
|
10902
11155
|
const lockfiles = ["bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"];
|
|
10903
11156
|
for (const dir of dirs) {
|
|
10904
|
-
const path =
|
|
10905
|
-
if (
|
|
10906
|
-
|
|
11157
|
+
const path = join18(root, dir);
|
|
11158
|
+
if (existsSync15(path)) {
|
|
11159
|
+
rmSync4(path, { recursive: true });
|
|
10907
11160
|
console.log(source_default.dim(` Removed ${dir}/`));
|
|
10908
11161
|
}
|
|
10909
11162
|
}
|
|
10910
11163
|
if (options?.all) {
|
|
10911
11164
|
for (const file of lockfiles) {
|
|
10912
|
-
const path =
|
|
10913
|
-
if (
|
|
10914
|
-
|
|
11165
|
+
const path = join18(root, file);
|
|
11166
|
+
if (existsSync15(path)) {
|
|
11167
|
+
rmSync4(path);
|
|
10915
11168
|
console.log(source_default.dim(` Removed ${file}`));
|
|
10916
11169
|
}
|
|
10917
11170
|
}
|
|
@@ -11071,8 +11324,8 @@ function update() {
|
|
|
11071
11324
|
|
|
11072
11325
|
// src/commands/graph/init.ts
|
|
11073
11326
|
init_source();
|
|
11074
|
-
import { existsSync as
|
|
11075
|
-
import { join as
|
|
11327
|
+
import { existsSync as existsSync16, readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7 } from "fs";
|
|
11328
|
+
import { join as join19 } from "path";
|
|
11076
11329
|
import { execSync as execSync4 } from "child_process";
|
|
11077
11330
|
function graphInit() {
|
|
11078
11331
|
const root = process.cwd();
|
|
@@ -11082,10 +11335,10 @@ function graphInit() {
|
|
|
11082
11335
|
process.exit(1);
|
|
11083
11336
|
}
|
|
11084
11337
|
const m = read(root);
|
|
11085
|
-
const modelsDir =
|
|
11086
|
-
|
|
11087
|
-
const indexPath =
|
|
11088
|
-
if (!
|
|
11338
|
+
const modelsDir = join19(root, "src", "models");
|
|
11339
|
+
mkdirSync7(modelsDir, { recursive: true });
|
|
11340
|
+
const indexPath = join19(modelsDir, "index.ts");
|
|
11341
|
+
if (!existsSync16(indexPath)) {
|
|
11089
11342
|
writeFileSync7(indexPath, `// Data models for ${m.name}
|
|
11090
11343
|
// Generated by construct graph init
|
|
11091
11344
|
|
|
@@ -11093,7 +11346,7 @@ function graphInit() {
|
|
|
11093
11346
|
// export { User } from './User'
|
|
11094
11347
|
`);
|
|
11095
11348
|
}
|
|
11096
|
-
const pkgPath =
|
|
11349
|
+
const pkgPath = join19(root, "package.json");
|
|
11097
11350
|
const pkg = JSON.parse(readFileSync11(pkgPath, "utf-8"));
|
|
11098
11351
|
if (!pkg.dependencies)
|
|
11099
11352
|
pkg.dependencies = {};
|
|
@@ -11125,8 +11378,8 @@ function graphInit() {
|
|
|
11125
11378
|
|
|
11126
11379
|
// src/commands/graph/generate.ts
|
|
11127
11380
|
init_source();
|
|
11128
|
-
import { existsSync as
|
|
11129
|
-
import { join as
|
|
11381
|
+
import { existsSync as existsSync17, readFileSync as readFileSync12, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8 } from "fs";
|
|
11382
|
+
import { join as join20 } from "path";
|
|
11130
11383
|
var FIELD_TYPES = {
|
|
11131
11384
|
string: "field.string()",
|
|
11132
11385
|
int: "field.int()",
|
|
@@ -11278,10 +11531,10 @@ function generate2(modelName, fieldSpecs, options) {
|
|
|
11278
11531
|
lines.push("");
|
|
11279
11532
|
const content = lines.join(`
|
|
11280
11533
|
`);
|
|
11281
|
-
const modelsDir =
|
|
11282
|
-
|
|
11283
|
-
const filePath =
|
|
11284
|
-
if (
|
|
11534
|
+
const modelsDir = join20(root, "src", "models");
|
|
11535
|
+
mkdirSync8(modelsDir, { recursive: true });
|
|
11536
|
+
const filePath = join20(modelsDir, `${name}.ts`);
|
|
11537
|
+
if (existsSync17(filePath)) {
|
|
11285
11538
|
console.log(source_default.yellow(` Model file already exists: src/models/${name}.ts`));
|
|
11286
11539
|
console.log(source_default.dim(" Overwriting..."));
|
|
11287
11540
|
}
|
|
@@ -11298,9 +11551,9 @@ function generate2(modelName, fieldSpecs, options) {
|
|
|
11298
11551
|
console.log();
|
|
11299
11552
|
}
|
|
11300
11553
|
function updateBarrel(modelsDir, modelName) {
|
|
11301
|
-
const indexPath =
|
|
11554
|
+
const indexPath = join20(modelsDir, "index.ts");
|
|
11302
11555
|
const exportLine = `export { ${modelName} } from './${modelName}'`;
|
|
11303
|
-
if (
|
|
11556
|
+
if (existsSync17(indexPath)) {
|
|
11304
11557
|
const content = readFileSync12(indexPath, "utf-8");
|
|
11305
11558
|
if (content.includes(exportLine))
|
|
11306
11559
|
return;
|
|
@@ -11316,8 +11569,8 @@ function updateBarrel(modelsDir, modelName) {
|
|
|
11316
11569
|
|
|
11317
11570
|
// src/commands/graph/push.ts
|
|
11318
11571
|
init_source();
|
|
11319
|
-
import { existsSync as
|
|
11320
|
-
import { join as
|
|
11572
|
+
import { existsSync as existsSync18, readdirSync as readdirSync7, readFileSync as readFileSync13 } from "fs";
|
|
11573
|
+
import { join as join21 } from "path";
|
|
11321
11574
|
init_auth();
|
|
11322
11575
|
async function graphPush() {
|
|
11323
11576
|
const root = process.cwd();
|
|
@@ -11326,8 +11579,8 @@ async function graphPush() {
|
|
|
11326
11579
|
process.exit(1);
|
|
11327
11580
|
}
|
|
11328
11581
|
const m = read(root);
|
|
11329
|
-
const modelsDir =
|
|
11330
|
-
if (!
|
|
11582
|
+
const modelsDir = join21(root, "src", "models");
|
|
11583
|
+
if (!existsSync18(modelsDir)) {
|
|
11331
11584
|
console.error(source_default.red("No src/models/ directory found. Run 'construct graph init' first."));
|
|
11332
11585
|
process.exit(1);
|
|
11333
11586
|
}
|
|
@@ -11340,7 +11593,7 @@ async function graphPush() {
|
|
|
11340
11593
|
console.log(source_default.blue(`Pushing ${modelFiles.length} model(s) for space: ${m.id}`));
|
|
11341
11594
|
const models = [];
|
|
11342
11595
|
for (const file of modelFiles) {
|
|
11343
|
-
const content = readFileSync13(
|
|
11596
|
+
const content = readFileSync13(join21(modelsDir, file), "utf-8");
|
|
11344
11597
|
const model = parseModelFile(content);
|
|
11345
11598
|
if (model)
|
|
11346
11599
|
models.push(model);
|
|
@@ -11523,8 +11776,8 @@ function parseModelFile(content) {
|
|
|
11523
11776
|
|
|
11524
11777
|
// src/commands/graph/migrate.ts
|
|
11525
11778
|
init_source();
|
|
11526
|
-
import { existsSync as
|
|
11527
|
-
import { join as
|
|
11779
|
+
import { existsSync as existsSync19, readdirSync as readdirSync8, readFileSync as readFileSync14 } from "fs";
|
|
11780
|
+
import { join as join22 } from "path";
|
|
11528
11781
|
init_auth();
|
|
11529
11782
|
async function graphMigrate(options) {
|
|
11530
11783
|
const root = process.cwd();
|
|
@@ -11533,8 +11786,8 @@ async function graphMigrate(options) {
|
|
|
11533
11786
|
process.exit(1);
|
|
11534
11787
|
}
|
|
11535
11788
|
const m = read(root);
|
|
11536
|
-
const modelsDir =
|
|
11537
|
-
if (!
|
|
11789
|
+
const modelsDir = join22(root, "src", "models");
|
|
11790
|
+
if (!existsSync19(modelsDir)) {
|
|
11538
11791
|
console.error(source_default.red("No src/models/ directory. Run 'construct graph init' first."));
|
|
11539
11792
|
process.exit(1);
|
|
11540
11793
|
}
|
|
@@ -11564,7 +11817,7 @@ async function graphMigrate(options) {
|
|
|
11564
11817
|
const modelFiles = readdirSync8(modelsDir).filter((f) => f.endsWith(".ts") && f !== "index.ts");
|
|
11565
11818
|
const localModels = [];
|
|
11566
11819
|
for (const file of modelFiles) {
|
|
11567
|
-
const content = readFileSync14(
|
|
11820
|
+
const content = readFileSync14(join22(modelsDir, file), "utf-8");
|
|
11568
11821
|
const model = parseModelFields(content);
|
|
11569
11822
|
if (model)
|
|
11570
11823
|
localModels.push(model);
|
|
@@ -11700,7 +11953,7 @@ function graphFork(newSpaceID) {
|
|
|
11700
11953
|
// package.json
|
|
11701
11954
|
var package_default = {
|
|
11702
11955
|
name: "@construct-space/cli",
|
|
11703
|
-
version: "1.9.
|
|
11956
|
+
version: "1.9.6",
|
|
11704
11957
|
description: "Construct CLI \u2014 scaffold, build, develop, and publish spaces",
|
|
11705
11958
|
type: "module",
|
|
11706
11959
|
bin: {
|
|
@@ -11719,7 +11972,9 @@ var package_default = {
|
|
|
11719
11972
|
build: "bun build src/index.ts --outdir dist --target bun --format esm && cp -r templates dist/",
|
|
11720
11973
|
dev: "bun run src/index.ts",
|
|
11721
11974
|
test: "bun test",
|
|
11722
|
-
typecheck: "tsc --noEmit"
|
|
11975
|
+
typecheck: "tsc --noEmit",
|
|
11976
|
+
lint: "eslint src",
|
|
11977
|
+
"lint:fix": "eslint src --fix"
|
|
11723
11978
|
},
|
|
11724
11979
|
dependencies: {
|
|
11725
11980
|
commander: "^14.0.3",
|
|
@@ -11730,7 +11985,10 @@ var package_default = {
|
|
|
11730
11985
|
},
|
|
11731
11986
|
devDependencies: {
|
|
11732
11987
|
"@types/bun": "latest",
|
|
11733
|
-
typescript: "^6.0.2"
|
|
11988
|
+
typescript: "^6.0.2",
|
|
11989
|
+
eslint: "^10.4.0",
|
|
11990
|
+
"@eslint/js": "^10.0.1",
|
|
11991
|
+
"typescript-eslint": "^8.59.4"
|
|
11734
11992
|
},
|
|
11735
11993
|
keywords: [
|
|
11736
11994
|
"construct",
|