@whxway/loom 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/loom.mjs +80 -21
- package/package.json +1 -1
package/bin/loom.mjs
CHANGED
|
@@ -121,12 +121,69 @@ var init_paths = __esm({
|
|
|
121
121
|
}
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
+
// lib/cli/external-aliases.ts
|
|
125
|
+
import { existsSync as existsSync2, lstatSync, mkdirSync, readFileSync as readFileSync2, readlinkSync, rmSync, symlinkSync } from "node:fs";
|
|
126
|
+
import { createRequire } from "node:module";
|
|
127
|
+
import { dirname, relative, resolve as resolve2 } from "node:path";
|
|
128
|
+
function ensureExternalAliases() {
|
|
129
|
+
if (!existsSync2(MANIFEST)) return;
|
|
130
|
+
let aliases;
|
|
131
|
+
try {
|
|
132
|
+
aliases = JSON.parse(readFileSync2(MANIFEST, "utf8"));
|
|
133
|
+
} catch (err) {
|
|
134
|
+
console.warn(`[loom] failed to parse ${MANIFEST}:`, err.message);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (!aliases || typeof aliases !== "object" || Object.keys(aliases).length === 0) return;
|
|
138
|
+
mkdirSync(MODULES_DIR, { recursive: true });
|
|
139
|
+
const requireFromPkg = createRequire(resolve2(PACKAGE_ROOT, "package.json"));
|
|
140
|
+
let created = 0;
|
|
141
|
+
for (const [hashed, real] of Object.entries(aliases)) {
|
|
142
|
+
const linkPath = resolve2(MODULES_DIR, hashed);
|
|
143
|
+
try {
|
|
144
|
+
const stat = lstatSync(linkPath);
|
|
145
|
+
if (stat.isSymbolicLink()) {
|
|
146
|
+
const target2 = resolve2(MODULES_DIR, readlinkSync(linkPath));
|
|
147
|
+
if (existsSync2(target2)) continue;
|
|
148
|
+
}
|
|
149
|
+
rmSync(linkPath, { recursive: true, force: true });
|
|
150
|
+
} catch {
|
|
151
|
+
}
|
|
152
|
+
let realPkgDir;
|
|
153
|
+
try {
|
|
154
|
+
realPkgDir = dirname(requireFromPkg.resolve(`${real}/package.json`));
|
|
155
|
+
} catch (err) {
|
|
156
|
+
console.warn(`[loom] couldn't resolve "${real}" for alias "${hashed}": ${err.message}`);
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const target = relative(MODULES_DIR, realPkgDir);
|
|
160
|
+
try {
|
|
161
|
+
symlinkSync(target, linkPath, "junction");
|
|
162
|
+
created++;
|
|
163
|
+
} catch (err) {
|
|
164
|
+
console.warn(`[loom] failed to symlink "${hashed}" -> "${target}": ${err.message}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (created > 0) {
|
|
168
|
+
console.log(`[loom] linked ${created} external package alias${created === 1 ? "" : "es"}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
var MANIFEST, MODULES_DIR;
|
|
172
|
+
var init_external_aliases = __esm({
|
|
173
|
+
"lib/cli/external-aliases.ts"() {
|
|
174
|
+
"use strict";
|
|
175
|
+
init_paths();
|
|
176
|
+
MANIFEST = resolve2(PACKAGE_ROOT, ".next/external-aliases.json");
|
|
177
|
+
MODULES_DIR = resolve2(PACKAGE_ROOT, ".next/node_modules");
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
124
181
|
// lib/cli/next-runtime.ts
|
|
125
182
|
import { spawn } from "node:child_process";
|
|
126
|
-
import { createRequire } from "node:module";
|
|
127
|
-
import { resolve as
|
|
183
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
184
|
+
import { resolve as resolve3 } from "node:path";
|
|
128
185
|
function resolveNextBin() {
|
|
129
|
-
const requireFromPkg =
|
|
186
|
+
const requireFromPkg = createRequire2(resolve3(PACKAGE_ROOT, "package.json"));
|
|
130
187
|
try {
|
|
131
188
|
return requireFromPkg.resolve("next/dist/bin/next");
|
|
132
189
|
} catch (err) {
|
|
@@ -141,6 +198,7 @@ function runNext(mode, opts) {
|
|
|
141
198
|
const nextBin = resolveNextBin();
|
|
142
199
|
process.env.LOOM_USER_CWD = USER_CWD;
|
|
143
200
|
process.env.LOOM_PACKAGE_ROOT = PACKAGE_ROOT;
|
|
201
|
+
if (mode === "start") ensureExternalAliases();
|
|
144
202
|
const { path: cfgPath, applied } = preflightFromConfig();
|
|
145
203
|
if (cfgPath) {
|
|
146
204
|
const note2 = applied.length > 0 ? ` (env: ${applied.join(", ")})` : "";
|
|
@@ -162,6 +220,7 @@ var init_next_runtime = __esm({
|
|
|
162
220
|
"lib/cli/next-runtime.ts"() {
|
|
163
221
|
"use strict";
|
|
164
222
|
init_preflight();
|
|
223
|
+
init_external_aliases();
|
|
165
224
|
init_paths();
|
|
166
225
|
}
|
|
167
226
|
});
|
|
@@ -402,9 +461,9 @@ var init_template = __esm({
|
|
|
402
461
|
});
|
|
403
462
|
|
|
404
463
|
// lib/cli/init/wizard.ts
|
|
405
|
-
import { existsSync as
|
|
464
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, writeFileSync } from "node:fs";
|
|
406
465
|
import { homedir as homedir2 } from "node:os";
|
|
407
|
-
import { dirname, resolve as
|
|
466
|
+
import { dirname as dirname2, resolve as resolve4 } from "node:path";
|
|
408
467
|
import { confirm, group, intro, log, note, outro, password as password2, select as select2, text as text2 } from "@clack/prompts";
|
|
409
468
|
async function runInteractiveInit(opts) {
|
|
410
469
|
if (opts.print) {
|
|
@@ -413,7 +472,7 @@ async function runInteractiveInit(opts) {
|
|
|
413
472
|
}
|
|
414
473
|
if (opts.yes) {
|
|
415
474
|
const outPath2 = resolveOutPath(opts);
|
|
416
|
-
if (
|
|
475
|
+
if (existsSync3(outPath2) && !opts.force) {
|
|
417
476
|
console.error(`Refusing to overwrite existing file: ${outPath2}`);
|
|
418
477
|
console.error("Pass --force to replace it.");
|
|
419
478
|
process.exit(1);
|
|
@@ -497,22 +556,22 @@ async function promptOutPath() {
|
|
|
497
556
|
initialValue: "project"
|
|
498
557
|
})
|
|
499
558
|
);
|
|
500
|
-
if (target === "project") return
|
|
559
|
+
if (target === "project") return resolve4(USER_CWD, "loom.config.yaml");
|
|
501
560
|
if (target === "user") {
|
|
502
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
503
|
-
return
|
|
561
|
+
const xdg = process.env.XDG_CONFIG_HOME || resolve4(homedir2(), ".config");
|
|
562
|
+
return resolve4(xdg, "loom.yaml");
|
|
504
563
|
}
|
|
505
564
|
const custom = await ask(
|
|
506
565
|
text2({
|
|
507
566
|
message: "Config path",
|
|
508
|
-
placeholder:
|
|
509
|
-
initialValue:
|
|
567
|
+
placeholder: resolve4(USER_CWD, "loom.config.yaml"),
|
|
568
|
+
initialValue: resolve4(USER_CWD, "loom.config.yaml")
|
|
510
569
|
})
|
|
511
570
|
);
|
|
512
|
-
return
|
|
571
|
+
return resolve4(USER_CWD, custom);
|
|
513
572
|
}
|
|
514
573
|
async function promptOverwrite(outPath) {
|
|
515
|
-
if (!
|
|
574
|
+
if (!existsSync3(outPath)) return;
|
|
516
575
|
const overwrite = await ask(
|
|
517
576
|
confirm({
|
|
518
577
|
message: `${outPath} already exists. Overwrite?`,
|
|
@@ -541,15 +600,15 @@ async function promptAdminPassword() {
|
|
|
541
600
|
);
|
|
542
601
|
}
|
|
543
602
|
function resolveOutPath(opts) {
|
|
544
|
-
if (opts.explicitOut) return
|
|
603
|
+
if (opts.explicitOut) return resolve4(USER_CWD, opts.explicitOut);
|
|
545
604
|
if (opts.user) {
|
|
546
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
547
|
-
return
|
|
605
|
+
const xdg = process.env.XDG_CONFIG_HOME || resolve4(homedir2(), ".config");
|
|
606
|
+
return resolve4(xdg, "loom.yaml");
|
|
548
607
|
}
|
|
549
|
-
return
|
|
608
|
+
return resolve4(USER_CWD, "loom.config.yaml");
|
|
550
609
|
}
|
|
551
610
|
function writeOut(outPath, yaml) {
|
|
552
|
-
|
|
611
|
+
mkdirSync2(dirname2(outPath), { recursive: true });
|
|
553
612
|
writeFileSync(outPath, yaml, { mode: 384 });
|
|
554
613
|
log.success(`Wrote ${outPath}`);
|
|
555
614
|
}
|
|
@@ -649,7 +708,7 @@ var init_main = __esm({
|
|
|
649
708
|
main = defineCommand4({
|
|
650
709
|
meta: {
|
|
651
710
|
name: "loom",
|
|
652
|
-
version: "
|
|
711
|
+
version: "1.0.2",
|
|
653
712
|
description: "Self-hosted AI testing platform \u2014 playground, MCP runtime, request logs, and an OpenAI-compatible gateway."
|
|
654
713
|
},
|
|
655
714
|
subCommands: {
|
|
@@ -667,9 +726,9 @@ var init_main = __esm({
|
|
|
667
726
|
});
|
|
668
727
|
|
|
669
728
|
// bin/loom.ts
|
|
670
|
-
import { dirname as
|
|
729
|
+
import { dirname as dirname3, resolve as resolve5 } from "node:path";
|
|
671
730
|
import { fileURLToPath } from "node:url";
|
|
672
731
|
import { runMain } from "citty";
|
|
673
|
-
process.env.LOOM_PACKAGE_ROOT =
|
|
732
|
+
process.env.LOOM_PACKAGE_ROOT = resolve5(dirname3(fileURLToPath(import.meta.url)), "..");
|
|
674
733
|
var { main: main2 } = await Promise.resolve().then(() => (init_main(), main_exports));
|
|
675
734
|
runMain(main2);
|
package/package.json
CHANGED