@wayai/cli 0.3.164 → 0.3.165
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 +475 -386
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17455,40 +17455,214 @@ var init_expected = __esm({
|
|
|
17455
17455
|
}
|
|
17456
17456
|
});
|
|
17457
17457
|
|
|
17458
|
-
// src/lib/
|
|
17458
|
+
// src/lib/fs-safety.ts
|
|
17459
17459
|
import * as fs from "fs";
|
|
17460
17460
|
import * as path from "path";
|
|
17461
|
+
function fileHasBytes(abs, data) {
|
|
17462
|
+
let st;
|
|
17463
|
+
try {
|
|
17464
|
+
st = fs.lstatSync(abs);
|
|
17465
|
+
} catch {
|
|
17466
|
+
return false;
|
|
17467
|
+
}
|
|
17468
|
+
if (!st.isFile() || st.isSymbolicLink()) return false;
|
|
17469
|
+
try {
|
|
17470
|
+
return fs.readFileSync(abs).equals(data);
|
|
17471
|
+
} catch {
|
|
17472
|
+
return false;
|
|
17473
|
+
}
|
|
17474
|
+
}
|
|
17475
|
+
function realpathContained(root, abs) {
|
|
17476
|
+
let realRoot;
|
|
17477
|
+
let realAbs;
|
|
17478
|
+
try {
|
|
17479
|
+
realRoot = fs.realpathSync(root);
|
|
17480
|
+
realAbs = fs.realpathSync(abs);
|
|
17481
|
+
} catch {
|
|
17482
|
+
return false;
|
|
17483
|
+
}
|
|
17484
|
+
return realAbs === realRoot || realAbs.startsWith(realRoot + path.sep);
|
|
17485
|
+
}
|
|
17486
|
+
function mkdirTolerateRace(dir) {
|
|
17487
|
+
try {
|
|
17488
|
+
fs.mkdirSync(dir);
|
|
17489
|
+
return true;
|
|
17490
|
+
} catch (err) {
|
|
17491
|
+
if (err.code !== "EEXIST") throw err;
|
|
17492
|
+
let st;
|
|
17493
|
+
try {
|
|
17494
|
+
st = fs.lstatSync(dir);
|
|
17495
|
+
} catch {
|
|
17496
|
+
st = void 0;
|
|
17497
|
+
}
|
|
17498
|
+
return !!st?.isDirectory();
|
|
17499
|
+
}
|
|
17500
|
+
}
|
|
17501
|
+
function ensureRealSubdirNoSymlink(root, target, create) {
|
|
17502
|
+
const rootResolved = path.resolve(root);
|
|
17503
|
+
const targetResolved = path.resolve(target);
|
|
17504
|
+
if (targetResolved !== rootResolved && !targetResolved.startsWith(rootResolved + path.sep)) return false;
|
|
17505
|
+
try {
|
|
17506
|
+
if (!fs.lstatSync(rootResolved).isDirectory()) return false;
|
|
17507
|
+
} catch {
|
|
17508
|
+
return false;
|
|
17509
|
+
}
|
|
17510
|
+
const rel = path.relative(rootResolved, targetResolved);
|
|
17511
|
+
if (rel === "") return true;
|
|
17512
|
+
let cur = rootResolved;
|
|
17513
|
+
for (const segment of rel.split(path.sep)) {
|
|
17514
|
+
cur = path.join(cur, segment);
|
|
17515
|
+
let st;
|
|
17516
|
+
try {
|
|
17517
|
+
st = fs.lstatSync(cur);
|
|
17518
|
+
} catch {
|
|
17519
|
+
st = void 0;
|
|
17520
|
+
}
|
|
17521
|
+
if (st) {
|
|
17522
|
+
if (!st.isDirectory()) return false;
|
|
17523
|
+
} else if (create) {
|
|
17524
|
+
if (!mkdirTolerateRace(cur)) return false;
|
|
17525
|
+
} else {
|
|
17526
|
+
return true;
|
|
17527
|
+
}
|
|
17528
|
+
}
|
|
17529
|
+
return true;
|
|
17530
|
+
}
|
|
17531
|
+
function requireRealSubdirNoSymlink(root, target, create) {
|
|
17532
|
+
if (ensureRealSubdirNoSymlink(root, target, create)) return;
|
|
17533
|
+
throw expected(
|
|
17534
|
+
`${path.relative(path.dirname(root), target)} is reached through a symlink (or a file is in the way). The CLI never reads or writes workspace config through a symlink \u2014 make it a real directory.`
|
|
17535
|
+
);
|
|
17536
|
+
}
|
|
17537
|
+
function requireRealHubFolder(hubFolder, create) {
|
|
17538
|
+
if (!create) {
|
|
17539
|
+
try {
|
|
17540
|
+
fs.lstatSync(hubFolder);
|
|
17541
|
+
} catch {
|
|
17542
|
+
return;
|
|
17543
|
+
}
|
|
17544
|
+
}
|
|
17545
|
+
requireRealSubdirNoSymlink(path.dirname(hubFolder), hubFolder, create);
|
|
17546
|
+
for (const sub of HUB_MANAGED_SUBDIRS) {
|
|
17547
|
+
requireRealSubdirNoSymlink(hubFolder, path.join(hubFolder, sub), false);
|
|
17548
|
+
}
|
|
17549
|
+
for (const name of HUB_CONFIG_FILES) {
|
|
17550
|
+
let st;
|
|
17551
|
+
try {
|
|
17552
|
+
st = fs.lstatSync(path.join(hubFolder, name));
|
|
17553
|
+
} catch {
|
|
17554
|
+
continue;
|
|
17555
|
+
}
|
|
17556
|
+
if (!st.isFile()) {
|
|
17557
|
+
throw expected(
|
|
17558
|
+
`${path.join(path.basename(hubFolder), name)} is a symlink (or not a file). The CLI never reads or writes workspace config through a symlink \u2014 make it a real file.`
|
|
17559
|
+
);
|
|
17560
|
+
}
|
|
17561
|
+
}
|
|
17562
|
+
}
|
|
17563
|
+
function readRealFileOrThrow(root, abs) {
|
|
17564
|
+
let st;
|
|
17565
|
+
try {
|
|
17566
|
+
st = fs.lstatSync(abs);
|
|
17567
|
+
} catch {
|
|
17568
|
+
return null;
|
|
17569
|
+
}
|
|
17570
|
+
const bytes = st.isFile() ? readFileNoFollow(root, abs) : null;
|
|
17571
|
+
if (!bytes) {
|
|
17572
|
+
throw expected(
|
|
17573
|
+
`${path.relative(path.dirname(root), abs)} is a symlink (or reached through one). The CLI never reads or writes workspace config through a symlink \u2014 make it a real file.`
|
|
17574
|
+
);
|
|
17575
|
+
}
|
|
17576
|
+
return bytes.toString("utf-8");
|
|
17577
|
+
}
|
|
17578
|
+
function readFileNoFollow(root, abs) {
|
|
17579
|
+
if (!ensureRealSubdirNoSymlink(root, path.dirname(abs), false)) return null;
|
|
17580
|
+
try {
|
|
17581
|
+
if (!fs.lstatSync(abs).isFile()) return null;
|
|
17582
|
+
return fs.readFileSync(abs);
|
|
17583
|
+
} catch {
|
|
17584
|
+
return null;
|
|
17585
|
+
}
|
|
17586
|
+
}
|
|
17587
|
+
function writeFileNoFollow(root, abs, data) {
|
|
17588
|
+
const parent = path.dirname(abs);
|
|
17589
|
+
if (!ensureRealSubdirNoSymlink(root, parent, true)) return false;
|
|
17590
|
+
let st;
|
|
17591
|
+
try {
|
|
17592
|
+
st = fs.lstatSync(abs);
|
|
17593
|
+
} catch {
|
|
17594
|
+
}
|
|
17595
|
+
if (st?.isSymbolicLink()) fs.rmSync(abs);
|
|
17596
|
+
fs.writeFileSync(abs, data);
|
|
17597
|
+
return true;
|
|
17598
|
+
}
|
|
17599
|
+
function createFileNoFollow(root, abs, data) {
|
|
17600
|
+
if (!ensureRealSubdirNoSymlink(root, path.dirname(abs), true)) return "refused";
|
|
17601
|
+
try {
|
|
17602
|
+
fs.writeFileSync(abs, data, { flag: "wx" });
|
|
17603
|
+
} catch (err) {
|
|
17604
|
+
if (err.code === "EEXIST") return "exists";
|
|
17605
|
+
throw err;
|
|
17606
|
+
}
|
|
17607
|
+
return "created";
|
|
17608
|
+
}
|
|
17609
|
+
var HUB_MANAGED_SUBDIRS, HUB_CONFIG_FILES;
|
|
17610
|
+
var init_fs_safety = __esm({
|
|
17611
|
+
"src/lib/fs-safety.ts"() {
|
|
17612
|
+
"use strict";
|
|
17613
|
+
init_expected();
|
|
17614
|
+
HUB_MANAGED_SUBDIRS = ["agents", "evals", "journeys", "resources", "attachments"];
|
|
17615
|
+
HUB_CONFIG_FILES = ["hub.yaml", "wayai.yaml"];
|
|
17616
|
+
}
|
|
17617
|
+
});
|
|
17618
|
+
|
|
17619
|
+
// src/lib/layout.ts
|
|
17620
|
+
import * as fs2 from "fs";
|
|
17621
|
+
import * as path2 from "path";
|
|
17461
17622
|
function isDirectory(p) {
|
|
17462
17623
|
try {
|
|
17463
|
-
return
|
|
17624
|
+
return fs2.statSync(p).isDirectory();
|
|
17625
|
+
} catch {
|
|
17626
|
+
return false;
|
|
17627
|
+
}
|
|
17628
|
+
}
|
|
17629
|
+
function isRealDirectory(p) {
|
|
17630
|
+
try {
|
|
17631
|
+
return fs2.lstatSync(p).isDirectory();
|
|
17464
17632
|
} catch {
|
|
17465
17633
|
return false;
|
|
17466
17634
|
}
|
|
17467
17635
|
}
|
|
17468
17636
|
function resolveLayout(gitRoot, layout = WAYAI_LAYOUT) {
|
|
17469
|
-
const newWs =
|
|
17470
|
-
const legacyWs =
|
|
17471
|
-
const legacyOrg =
|
|
17472
|
-
const legacyExists =
|
|
17473
|
-
const basesDir =
|
|
17474
|
-
const hubsDir =
|
|
17475
|
-
const orgDir =
|
|
17637
|
+
const newWs = path2.join(gitRoot, layout.wsDir);
|
|
17638
|
+
const legacyWs = path2.join(gitRoot, layout.legacy.wsDir);
|
|
17639
|
+
const legacyOrg = path2.join(gitRoot, layout.legacy.orgAtRoot);
|
|
17640
|
+
const legacyExists = isRealDirectory(legacyWs) || isRealDirectory(legacyOrg);
|
|
17641
|
+
const basesDir = path2.join(newWs, layout.basesSubdir);
|
|
17642
|
+
const hubsDir = path2.join(newWs, layout.hubsSubdir);
|
|
17643
|
+
const orgDir = path2.join(newWs, layout.orgSubdir);
|
|
17476
17644
|
const newDisplacesLegacy = () => isDirectory(hubsDir) || isDirectory(orgDir) || isDirectory(basesDir);
|
|
17645
|
+
let resolved;
|
|
17477
17646
|
if (legacyExists && !newDisplacesLegacy()) {
|
|
17478
|
-
|
|
17647
|
+
resolved = { hubsDir: legacyWs, orgDir: legacyOrg, basesDir, isLegacy: true, legacyAlsoPresent: false };
|
|
17648
|
+
} else {
|
|
17649
|
+
resolved = { hubsDir, orgDir, basesDir, isLegacy: false, legacyAlsoPresent: legacyExists };
|
|
17479
17650
|
}
|
|
17480
|
-
|
|
17651
|
+
for (const dir of [resolved.hubsDir, resolved.orgDir, resolved.basesDir]) {
|
|
17652
|
+
requireRealSubdirNoSymlink(gitRoot, dir, false);
|
|
17653
|
+
}
|
|
17654
|
+
return resolved;
|
|
17481
17655
|
}
|
|
17482
17656
|
function resolveBasesDir(gitRoot) {
|
|
17483
17657
|
return resolveLayout(gitRoot).basesDir;
|
|
17484
17658
|
}
|
|
17485
17659
|
function hubsDirLabel(gitRoot) {
|
|
17486
|
-
if (!gitRoot) return
|
|
17487
|
-
return
|
|
17660
|
+
if (!gitRoot) return path2.join(WAYAI_LAYOUT.wsDir, WAYAI_LAYOUT.hubsSubdir);
|
|
17661
|
+
return path2.relative(gitRoot, resolveLayout(gitRoot).hubsDir);
|
|
17488
17662
|
}
|
|
17489
17663
|
function basesDirLabel(gitRoot) {
|
|
17490
|
-
if (!gitRoot) return
|
|
17491
|
-
return
|
|
17664
|
+
if (!gitRoot) return path2.join(WAYAI_LAYOUT.wsDir, WAYAI_LAYOUT.basesSubdir);
|
|
17665
|
+
return path2.relative(gitRoot, resolveLayout(gitRoot).basesDir);
|
|
17492
17666
|
}
|
|
17493
17667
|
function warnLayoutOnce(gitRoot) {
|
|
17494
17668
|
const r = resolveLayout(gitRoot);
|
|
@@ -17516,6 +17690,7 @@ var init_layout = __esm({
|
|
|
17516
17690
|
"src/lib/layout.ts"() {
|
|
17517
17691
|
"use strict";
|
|
17518
17692
|
init_dist();
|
|
17693
|
+
init_fs_safety();
|
|
17519
17694
|
WAYAI_LAYOUT = {
|
|
17520
17695
|
...WAYAI_WORKSPACE_LAYOUT,
|
|
17521
17696
|
legacy: { wsDir: "workspace", orgAtRoot: "org" }
|
|
@@ -17550,8 +17725,8 @@ __export(workspace_exports, {
|
|
|
17550
17725
|
scanWorkspaceHubs: () => scanWorkspaceHubs
|
|
17551
17726
|
});
|
|
17552
17727
|
import { execFileSync } from "child_process";
|
|
17553
|
-
import * as
|
|
17554
|
-
import * as
|
|
17728
|
+
import * as fs3 from "fs";
|
|
17729
|
+
import * as path3 from "path";
|
|
17555
17730
|
import * as yaml from "js-yaml";
|
|
17556
17731
|
function findGitRoot() {
|
|
17557
17732
|
try {
|
|
@@ -17566,8 +17741,8 @@ function findGitRoot() {
|
|
|
17566
17741
|
function findRepoRootSync() {
|
|
17567
17742
|
let current = process.cwd();
|
|
17568
17743
|
while (true) {
|
|
17569
|
-
if (
|
|
17570
|
-
const parent =
|
|
17744
|
+
if (fs3.existsSync(path3.join(current, ".git"))) return current;
|
|
17745
|
+
const parent = path3.dirname(current);
|
|
17571
17746
|
if (parent === current) return null;
|
|
17572
17747
|
current = parent;
|
|
17573
17748
|
}
|
|
@@ -17576,7 +17751,7 @@ function detectWorkspace() {
|
|
|
17576
17751
|
const gitRoot = findGitRoot();
|
|
17577
17752
|
if (!gitRoot) return null;
|
|
17578
17753
|
const { hubsDir } = resolveLayout(gitRoot);
|
|
17579
|
-
if (!
|
|
17754
|
+
if (!fs3.existsSync(hubsDir) || !fs3.statSync(hubsDir).isDirectory()) {
|
|
17580
17755
|
return null;
|
|
17581
17756
|
}
|
|
17582
17757
|
return { gitRoot, workspaceDir: hubsDir };
|
|
@@ -17592,9 +17767,9 @@ function resolveWorkspaceDir() {
|
|
|
17592
17767
|
return resolveLayout(gitRoot).hubsDir;
|
|
17593
17768
|
}
|
|
17594
17769
|
function readHubYaml(yamlPath) {
|
|
17595
|
-
if (!
|
|
17770
|
+
if (!fs3.existsSync(yamlPath)) return null;
|
|
17596
17771
|
try {
|
|
17597
|
-
const content =
|
|
17772
|
+
const content = fs3.readFileSync(yamlPath, "utf-8");
|
|
17598
17773
|
const config = yaml.load(content);
|
|
17599
17774
|
if (!config?.hub_id || !config.hub_environment) return null;
|
|
17600
17775
|
return { hubId: config.hub_id, hubEnvironment: config.hub_environment };
|
|
@@ -17605,9 +17780,9 @@ function readHubYaml(yamlPath) {
|
|
|
17605
17780
|
function scanWorkspaceHubs(workspaceDir) {
|
|
17606
17781
|
const hubs = [];
|
|
17607
17782
|
for (const top of safeReaddir(workspaceDir)) {
|
|
17608
|
-
const topDir =
|
|
17609
|
-
if (!
|
|
17610
|
-
const meta = readHubYaml(
|
|
17783
|
+
const topDir = path3.join(workspaceDir, top);
|
|
17784
|
+
if (!isRealDirectory(topDir)) continue;
|
|
17785
|
+
const meta = readHubYaml(path3.join(topDir, "hub.yaml")) || readHubYaml(path3.join(topDir, "wayai.yaml"));
|
|
17611
17786
|
if (meta) {
|
|
17612
17787
|
hubs.push({ hubFolder: topDir, hubId: meta.hubId, hubEnvironment: meta.hubEnvironment });
|
|
17613
17788
|
}
|
|
@@ -17621,9 +17796,9 @@ function filterPreviewHubs(hubs) {
|
|
|
17621
17796
|
return hubs.filter(isPreviewHub);
|
|
17622
17797
|
}
|
|
17623
17798
|
function readNewHubYaml(yamlPath) {
|
|
17624
|
-
if (!
|
|
17799
|
+
if (!fs3.existsSync(yamlPath)) return null;
|
|
17625
17800
|
try {
|
|
17626
|
-
const content =
|
|
17801
|
+
const content = fs3.readFileSync(yamlPath, "utf-8");
|
|
17627
17802
|
const config = yaml.load(content);
|
|
17628
17803
|
if (config?.hub_id) return null;
|
|
17629
17804
|
if (!config?.hub?.name) return null;
|
|
@@ -17635,9 +17810,9 @@ function readNewHubYaml(yamlPath) {
|
|
|
17635
17810
|
function scanNewHubs(workspaceDir) {
|
|
17636
17811
|
const hubs = [];
|
|
17637
17812
|
for (const top of safeReaddir(workspaceDir)) {
|
|
17638
|
-
const topDir =
|
|
17639
|
-
if (!
|
|
17640
|
-
const meta = readNewHubYaml(
|
|
17813
|
+
const topDir = path3.join(workspaceDir, top);
|
|
17814
|
+
if (!isRealDirectory(topDir)) continue;
|
|
17815
|
+
const meta = readNewHubYaml(path3.join(topDir, "hub.yaml")) || readNewHubYaml(path3.join(topDir, "wayai.yaml"));
|
|
17641
17816
|
if (meta) {
|
|
17642
17817
|
hubs.push({ hubFolder: topDir, hubName: meta.hubName, hubType: meta.hubType });
|
|
17643
17818
|
}
|
|
@@ -17657,22 +17832,22 @@ function resolveHubFolder(workspaceDir, hubId, hubName, hubEnvironment, previewL
|
|
|
17657
17832
|
if (match) return match.hubFolder;
|
|
17658
17833
|
}
|
|
17659
17834
|
const hubFolderSlug = getHubFolderSlug(hubName, hubEnvironment, hubId || "", previewLabel, branchName);
|
|
17660
|
-
return
|
|
17835
|
+
return path3.join(workspaceDir, hubFolderSlug);
|
|
17661
17836
|
}
|
|
17662
17837
|
function findLocalHubFolder(hubId) {
|
|
17663
17838
|
const workspace = detectWorkspace();
|
|
17664
17839
|
const gitRoot = findGitRoot();
|
|
17665
17840
|
const workspaceDir = workspace?.workspaceDir ?? (gitRoot ? resolveLayout(gitRoot).hubsDir : null);
|
|
17666
|
-
if (!workspaceDir || !
|
|
17841
|
+
if (!workspaceDir || !fs3.existsSync(workspaceDir)) return null;
|
|
17667
17842
|
const match = scanWorkspaceHubs(workspaceDir).find((h) => h.hubId === hubId);
|
|
17668
17843
|
return match ? match.hubFolder : null;
|
|
17669
17844
|
}
|
|
17670
17845
|
function getChangedHubs(workspaceDir) {
|
|
17671
17846
|
const gitRoot = findGitRoot();
|
|
17672
17847
|
if (!gitRoot) return [];
|
|
17673
|
-
const relWorkspace =
|
|
17674
|
-
const normalizedRel =
|
|
17675
|
-
if (normalizedRel.startsWith("..") ||
|
|
17848
|
+
const relWorkspace = path3.relative(gitRoot, workspaceDir);
|
|
17849
|
+
const normalizedRel = path3.normalize(relWorkspace);
|
|
17850
|
+
if (normalizedRel.startsWith("..") || path3.isAbsolute(normalizedRel)) {
|
|
17676
17851
|
return [];
|
|
17677
17852
|
}
|
|
17678
17853
|
let statusOutput;
|
|
@@ -17697,9 +17872,9 @@ function getChangedHubs(workspaceDir) {
|
|
|
17697
17872
|
if (hubFiles.length === 0) return [];
|
|
17698
17873
|
const hubFolders = /* @__PURE__ */ new Set();
|
|
17699
17874
|
for (const file of hubFiles) {
|
|
17700
|
-
const absFile =
|
|
17875
|
+
const absFile = path3.resolve(gitRoot, file);
|
|
17701
17876
|
if (file.endsWith("hub.yaml") || file.endsWith("wayai.yaml")) {
|
|
17702
|
-
hubFolders.add(
|
|
17877
|
+
hubFolders.add(path3.dirname(absFile));
|
|
17703
17878
|
} else if (file.includes("/agents/")) {
|
|
17704
17879
|
const agentsIndex = absFile.lastIndexOf("/agents/");
|
|
17705
17880
|
hubFolders.add(absFile.substring(0, agentsIndex));
|
|
@@ -17707,7 +17882,7 @@ function getChangedHubs(workspaceDir) {
|
|
|
17707
17882
|
}
|
|
17708
17883
|
const hubs = [];
|
|
17709
17884
|
for (const hubFolder of hubFolders) {
|
|
17710
|
-
const meta = readHubYaml(
|
|
17885
|
+
const meta = readHubYaml(path3.join(hubFolder, "hub.yaml")) || readHubYaml(path3.join(hubFolder, "wayai.yaml"));
|
|
17711
17886
|
if (meta) {
|
|
17712
17887
|
hubs.push({ hubFolder, hubId: meta.hubId, hubEnvironment: meta.hubEnvironment });
|
|
17713
17888
|
}
|
|
@@ -17742,19 +17917,19 @@ function resolveExplicitHubPath(hubPath) {
|
|
|
17742
17917
|
}
|
|
17743
17918
|
function findHubByFolderName(workspaceDir, hubFolderName) {
|
|
17744
17919
|
const all = scanWorkspaceHubs(workspaceDir);
|
|
17745
|
-
return all.find((h) =>
|
|
17920
|
+
return all.find((h) => path3.basename(h.hubFolder) === hubFolderName) ?? null;
|
|
17746
17921
|
}
|
|
17747
17922
|
function autoRenameHubFolder(currentFolder, hubName, hubEnvironment, hubId, previewLabel, branchName) {
|
|
17748
17923
|
const expectedSlug = getHubFolderSlug(hubName, hubEnvironment, hubId, previewLabel, branchName);
|
|
17749
|
-
const currentSlug =
|
|
17924
|
+
const currentSlug = path3.basename(currentFolder);
|
|
17750
17925
|
if (currentSlug === expectedSlug) return currentFolder;
|
|
17751
|
-
const targetFolder =
|
|
17752
|
-
if (
|
|
17926
|
+
const targetFolder = path3.join(path3.dirname(currentFolder), expectedSlug);
|
|
17927
|
+
if (fs3.existsSync(targetFolder)) {
|
|
17753
17928
|
console.warn(` Warning: skipping hub folder rename ${currentSlug} \u2192 ${expectedSlug} (target already exists)`);
|
|
17754
17929
|
return currentFolder;
|
|
17755
17930
|
}
|
|
17756
17931
|
try {
|
|
17757
|
-
|
|
17932
|
+
fs3.renameSync(currentFolder, targetFolder);
|
|
17758
17933
|
} catch (err) {
|
|
17759
17934
|
console.warn(` Warning: could not rename ${currentSlug} \u2192 ${expectedSlug}: ${err instanceof Error ? err.message : String(err)}`);
|
|
17760
17935
|
return currentFolder;
|
|
@@ -17765,28 +17940,28 @@ function autoRenameHubFolder(currentFolder, hubName, hubEnvironment, hubId, prev
|
|
|
17765
17940
|
}
|
|
17766
17941
|
function findEnclosingHubFolder(workspaceDir) {
|
|
17767
17942
|
let current = process.cwd();
|
|
17768
|
-
const stop =
|
|
17943
|
+
const stop = path3.resolve(workspaceDir);
|
|
17769
17944
|
while (true) {
|
|
17770
|
-
const meta = readHubYaml(
|
|
17945
|
+
const meta = readHubYaml(path3.join(current, "hub.yaml")) || readHubYaml(path3.join(current, "wayai.yaml"));
|
|
17771
17946
|
if (meta) {
|
|
17772
17947
|
return { hubFolder: current, hubId: meta.hubId, hubEnvironment: meta.hubEnvironment };
|
|
17773
17948
|
}
|
|
17774
17949
|
if (current === stop) return null;
|
|
17775
|
-
const parent =
|
|
17950
|
+
const parent = path3.dirname(current);
|
|
17776
17951
|
if (parent === current) return null;
|
|
17777
17952
|
current = parent;
|
|
17778
17953
|
}
|
|
17779
17954
|
}
|
|
17780
17955
|
function findEnclosingNewHubFolder(workspaceDir) {
|
|
17781
17956
|
let current = process.cwd();
|
|
17782
|
-
const stop =
|
|
17957
|
+
const stop = path3.resolve(workspaceDir);
|
|
17783
17958
|
while (true) {
|
|
17784
|
-
const meta = readNewHubYaml(
|
|
17959
|
+
const meta = readNewHubYaml(path3.join(current, "hub.yaml")) || readNewHubYaml(path3.join(current, "wayai.yaml"));
|
|
17785
17960
|
if (meta) {
|
|
17786
17961
|
return { hubFolder: current, hubName: meta.hubName, hubType: meta.hubType };
|
|
17787
17962
|
}
|
|
17788
17963
|
if (current === stop) return null;
|
|
17789
|
-
const parent =
|
|
17964
|
+
const parent = path3.dirname(current);
|
|
17790
17965
|
if (parent === current) return null;
|
|
17791
17966
|
current = parent;
|
|
17792
17967
|
}
|
|
@@ -17794,10 +17969,10 @@ function findEnclosingNewHubFolder(workspaceDir) {
|
|
|
17794
17969
|
function resolvePushTarget(workspaceDir, existingHubs, newHubs, selector) {
|
|
17795
17970
|
if (selector) {
|
|
17796
17971
|
const existingMatch = existingHubs.find(
|
|
17797
|
-
(h) => h.hubId === selector ||
|
|
17972
|
+
(h) => h.hubId === selector || path3.basename(h.hubFolder) === selector
|
|
17798
17973
|
);
|
|
17799
17974
|
if (existingMatch) return { ok: true, target: { kind: "existing", hub: existingMatch } };
|
|
17800
|
-
const newMatch = newHubs.find((h) =>
|
|
17975
|
+
const newMatch = newHubs.find((h) => path3.basename(h.hubFolder) === selector);
|
|
17801
17976
|
if (newMatch) return { ok: true, target: { kind: "new", hub: newMatch } };
|
|
17802
17977
|
return { ok: false, reason: "selector_miss" };
|
|
17803
17978
|
}
|
|
@@ -17813,10 +17988,10 @@ function resolvePushTarget(workspaceDir, existingHubs, newHubs, selector) {
|
|
|
17813
17988
|
}
|
|
17814
17989
|
function resolveNewHubForCreate(workspaceDir, existingHubs, newHubs, selector) {
|
|
17815
17990
|
if (selector) {
|
|
17816
|
-
const newMatch = newHubs.find((h) =>
|
|
17991
|
+
const newMatch = newHubs.find((h) => path3.basename(h.hubFolder) === selector);
|
|
17817
17992
|
if (newMatch) return { ok: true, hub: newMatch };
|
|
17818
17993
|
const existingMatch = existingHubs.find(
|
|
17819
|
-
(h) => h.hubId === selector ||
|
|
17994
|
+
(h) => h.hubId === selector || path3.basename(h.hubFolder) === selector
|
|
17820
17995
|
);
|
|
17821
17996
|
if (existingMatch) return { ok: false, reason: "exists", existing: existingMatch };
|
|
17822
17997
|
return { ok: false, reason: "selector_miss" };
|
|
@@ -17843,7 +18018,7 @@ function resolveActiveHubId(args2) {
|
|
|
17843
18018
|
const gitRoot = findGitRoot();
|
|
17844
18019
|
const workspaceDir = workspace?.workspaceDir ?? (gitRoot ? resolveLayout(gitRoot).hubsDir : null);
|
|
17845
18020
|
const wsLabel = hubsDirLabel(gitRoot);
|
|
17846
|
-
if (!workspaceDir || !
|
|
18021
|
+
if (!workspaceDir || !fs3.existsSync(workspaceDir)) {
|
|
17847
18022
|
if (selector && UUID_RE2.test(selector)) return selector;
|
|
17848
18023
|
console.error(`No ${wsLabel}/ directory found. Run \`wayai pull --hub <uuid>\` to fetch a hub, or pass --hub <uuid>.`);
|
|
17849
18024
|
process.exit(1);
|
|
@@ -17851,7 +18026,7 @@ function resolveActiveHubId(args2) {
|
|
|
17851
18026
|
const allHubs = scanWorkspaceHubs(workspaceDir);
|
|
17852
18027
|
if (selector) {
|
|
17853
18028
|
const match = allHubs.find(
|
|
17854
|
-
(h) => h.hubId === selector ||
|
|
18029
|
+
(h) => h.hubId === selector || path3.basename(h.hubFolder) === selector
|
|
17855
18030
|
);
|
|
17856
18031
|
if (match) return match.hubId;
|
|
17857
18032
|
if (UUID_RE2.test(selector)) return selector;
|
|
@@ -17868,7 +18043,7 @@ function resolveActiveHubId(args2) {
|
|
|
17868
18043
|
}
|
|
17869
18044
|
console.error(`Multiple hubs in ${wsLabel}/. Pass --hub <uuid|folder-name> or run from inside a hub folder:`);
|
|
17870
18045
|
for (const h of previewHubs) {
|
|
17871
|
-
console.error(` ${
|
|
18046
|
+
console.error(` ${path3.basename(h.hubFolder)} (${h.hubId})`);
|
|
17872
18047
|
}
|
|
17873
18048
|
process.exit(1);
|
|
17874
18049
|
}
|
|
@@ -17876,12 +18051,12 @@ function localHubEnvironment(hubId) {
|
|
|
17876
18051
|
const workspace = detectWorkspace();
|
|
17877
18052
|
const gitRoot = findGitRoot();
|
|
17878
18053
|
const workspaceDir = workspace?.workspaceDir ?? (gitRoot ? resolveLayout(gitRoot).hubsDir : null);
|
|
17879
|
-
if (!workspaceDir || !
|
|
18054
|
+
if (!workspaceDir || !fs3.existsSync(workspaceDir)) return null;
|
|
17880
18055
|
return scanWorkspaceHubs(workspaceDir).find((h) => h.hubId === hubId)?.hubEnvironment ?? null;
|
|
17881
18056
|
}
|
|
17882
18057
|
function safeReaddir(dir) {
|
|
17883
18058
|
try {
|
|
17884
|
-
return
|
|
18059
|
+
return fs3.readdirSync(dir).filter((entry) => !entry.startsWith("."));
|
|
17885
18060
|
} catch {
|
|
17886
18061
|
return [];
|
|
17887
18062
|
}
|
|
@@ -17895,19 +18070,19 @@ var init_workspace = __esm({
|
|
|
17895
18070
|
});
|
|
17896
18071
|
|
|
17897
18072
|
// src/lib/workspace-manifest.ts
|
|
17898
|
-
import * as
|
|
17899
|
-
import * as
|
|
18073
|
+
import * as fs4 from "fs";
|
|
18074
|
+
import * as path4 from "path";
|
|
17900
18075
|
import * as yaml2 from "js-yaml";
|
|
17901
18076
|
function workspaceManifestPath(gitRoot) {
|
|
17902
|
-
return
|
|
18077
|
+
return path4.join(gitRoot, WAYAI_LAYOUT.wsDir, WORKSPACE_MANIFEST_FILE);
|
|
17903
18078
|
}
|
|
17904
18079
|
function rootConfigPath(gitRoot) {
|
|
17905
|
-
return
|
|
18080
|
+
return path4.join(gitRoot, ROOT_CONFIG_FILE);
|
|
17906
18081
|
}
|
|
17907
18082
|
function loadYamlMapping(file) {
|
|
17908
18083
|
let raw;
|
|
17909
18084
|
try {
|
|
17910
|
-
raw =
|
|
18085
|
+
raw = fs4.readFileSync(file, "utf-8");
|
|
17911
18086
|
} catch (err) {
|
|
17912
18087
|
if (err.code === "ENOENT") return { kind: "absent" };
|
|
17913
18088
|
return { kind: "malformed", reason: err instanceof Error ? err.message : String(err) };
|
|
@@ -17950,8 +18125,7 @@ __export(repo_config_exports, {
|
|
|
17950
18125
|
resolveRepoConfig: () => resolveRepoConfig,
|
|
17951
18126
|
writeRepoConfig: () => writeRepoConfig
|
|
17952
18127
|
});
|
|
17953
|
-
import * as
|
|
17954
|
-
import * as path4 from "path";
|
|
18128
|
+
import * as path5 from "path";
|
|
17955
18129
|
import * as yaml3 from "js-yaml";
|
|
17956
18130
|
function noticeOnce(key, emit) {
|
|
17957
18131
|
if (noticed.has(key)) return;
|
|
@@ -17989,7 +18163,7 @@ function legacyFieldsIn(load11) {
|
|
|
17989
18163
|
if (load11.kind !== "ok") return [];
|
|
17990
18164
|
return LEGACY_FIELDS.filter((f) => load11.doc[f] !== void 0);
|
|
17991
18165
|
}
|
|
17992
|
-
function
|
|
18166
|
+
function resolve3(gitRoot) {
|
|
17993
18167
|
const manifestFile = workspaceManifestPath(gitRoot);
|
|
17994
18168
|
const manifest = declarationFrom(loadWorkspaceManifest(gitRoot));
|
|
17995
18169
|
if (manifest.kind === "invalid") {
|
|
@@ -18098,7 +18272,7 @@ function report(r, posture) {
|
|
|
18098
18272
|
function resolveRepoConfig(root) {
|
|
18099
18273
|
const gitRoot = root ?? findGitRoot();
|
|
18100
18274
|
if (!gitRoot) return null;
|
|
18101
|
-
const r =
|
|
18275
|
+
const r = resolve3(gitRoot);
|
|
18102
18276
|
report(r, "soft");
|
|
18103
18277
|
return r.kind === "ok" ? r.resolved : null;
|
|
18104
18278
|
}
|
|
@@ -18108,7 +18282,7 @@ function readRepoConfig(root) {
|
|
|
18108
18282
|
function readRepoConfigUnlessBlocked(root) {
|
|
18109
18283
|
const gitRoot = root ?? findGitRoot();
|
|
18110
18284
|
if (!gitRoot) return null;
|
|
18111
|
-
const r =
|
|
18285
|
+
const r = resolve3(gitRoot);
|
|
18112
18286
|
switch (r.kind) {
|
|
18113
18287
|
case "ok":
|
|
18114
18288
|
report(r, "soft");
|
|
@@ -18123,7 +18297,7 @@ function readRepoConfigUnlessBlocked(root) {
|
|
|
18123
18297
|
}
|
|
18124
18298
|
function requireRepoConfig(root) {
|
|
18125
18299
|
const gitRoot = root ?? findGitRoot();
|
|
18126
|
-
const r = gitRoot ?
|
|
18300
|
+
const r = gitRoot ? resolve3(gitRoot) : { kind: "none" };
|
|
18127
18301
|
report(r, "hard");
|
|
18128
18302
|
if (r.kind === "ok") return r.resolved.config;
|
|
18129
18303
|
return process.exit(1);
|
|
@@ -18131,7 +18305,7 @@ function requireRepoConfig(root) {
|
|
|
18131
18305
|
function readRepoScopeBlocker(root) {
|
|
18132
18306
|
const gitRoot = root ?? findGitRoot();
|
|
18133
18307
|
if (!gitRoot) return null;
|
|
18134
|
-
const r =
|
|
18308
|
+
const r = resolve3(gitRoot);
|
|
18135
18309
|
if (r.kind === "conflict") {
|
|
18136
18310
|
return {
|
|
18137
18311
|
kind: "conflict",
|
|
@@ -18168,6 +18342,7 @@ function writeRepoConfig(config, root) {
|
|
|
18168
18342
|
if (!gitRoot) {
|
|
18169
18343
|
throw expected("Not inside a git repository. Run `git init` first.");
|
|
18170
18344
|
}
|
|
18345
|
+
readRealFileOrThrow(gitRoot, workspaceManifestPath(gitRoot));
|
|
18171
18346
|
const stale = declarationFrom(loadYamlMapping(rootConfigPath(gitRoot)));
|
|
18172
18347
|
if (stale.kind === "declared" && stale.config.organization_id !== config.organization_id) {
|
|
18173
18348
|
throw expected(rebindRefusal(config.organization_id, stale.config.organization_id));
|
|
@@ -18183,12 +18358,8 @@ function writeRepoConfig(config, root) {
|
|
|
18183
18358
|
if (config.organization_name?.trim()) doc.organization_name = config.organization_name.trim();
|
|
18184
18359
|
Object.assign(doc, rest);
|
|
18185
18360
|
const file = workspaceManifestPath(gitRoot);
|
|
18186
|
-
|
|
18187
|
-
|
|
18188
|
-
file,
|
|
18189
|
-
yaml3.dump(doc, { lineWidth: -1, quotingType: '"', forceQuotes: false }),
|
|
18190
|
-
"utf-8"
|
|
18191
|
-
);
|
|
18361
|
+
requireRealSubdirNoSymlink(gitRoot, path5.dirname(file), true);
|
|
18362
|
+
writeFileNoFollow(gitRoot, file, Buffer.from(yaml3.dump(doc, { lineWidth: -1, quotingType: '"', forceQuotes: false }), "utf-8"));
|
|
18192
18363
|
return file;
|
|
18193
18364
|
}
|
|
18194
18365
|
var LEGACY_FIELDS, noticed, RECONCILE_REMEDY;
|
|
@@ -18196,6 +18367,7 @@ var init_repo_config = __esm({
|
|
|
18196
18367
|
"src/lib/repo-config.ts"() {
|
|
18197
18368
|
"use strict";
|
|
18198
18369
|
init_expected();
|
|
18370
|
+
init_fs_safety();
|
|
18199
18371
|
init_workspace();
|
|
18200
18372
|
init_utils();
|
|
18201
18373
|
init_workspace_manifest();
|
|
@@ -18210,7 +18382,7 @@ var init_repo_config = __esm({
|
|
|
18210
18382
|
|
|
18211
18383
|
// src/lib/utils.ts
|
|
18212
18384
|
import * as fs5 from "fs";
|
|
18213
|
-
import * as
|
|
18385
|
+
import * as path6 from "path";
|
|
18214
18386
|
import * as readline from "readline";
|
|
18215
18387
|
function prompt(question) {
|
|
18216
18388
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -18264,7 +18436,7 @@ function readStdin() {
|
|
|
18264
18436
|
}
|
|
18265
18437
|
function resolveHubYamlPath(hubFolder) {
|
|
18266
18438
|
for (const filename of ["hub.yaml", "wayai.yaml"]) {
|
|
18267
|
-
const yamlPath =
|
|
18439
|
+
const yamlPath = path6.join(hubFolder, filename);
|
|
18268
18440
|
if (fs5.existsSync(yamlPath)) return yamlPath;
|
|
18269
18441
|
}
|
|
18270
18442
|
return null;
|
|
@@ -18730,17 +18902,17 @@ var init_registry = __esm({
|
|
|
18730
18902
|
});
|
|
18731
18903
|
|
|
18732
18904
|
// src/lib/version-cache.ts
|
|
18733
|
-
import { existsSync as existsSync3, readFileSync as
|
|
18734
|
-
import { dirname as
|
|
18905
|
+
import { existsSync as existsSync3, readFileSync as readFileSync6, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
18906
|
+
import { dirname as dirname5, join as join7 } from "path";
|
|
18735
18907
|
import { homedir as homedir2 } from "os";
|
|
18736
18908
|
function getVersionCachePath(filename = CLI_CACHE_FILE) {
|
|
18737
|
-
return
|
|
18909
|
+
return join7(homedir2(), ".wayai", filename);
|
|
18738
18910
|
}
|
|
18739
18911
|
function readVersionCache(filename = CLI_CACHE_FILE) {
|
|
18740
18912
|
try {
|
|
18741
18913
|
const path35 = getVersionCachePath(filename);
|
|
18742
18914
|
if (!existsSync3(path35)) return null;
|
|
18743
|
-
const parsed = JSON.parse(
|
|
18915
|
+
const parsed = JSON.parse(readFileSync6(path35, "utf-8"));
|
|
18744
18916
|
if (typeof parsed.lastCheck !== "number") return null;
|
|
18745
18917
|
if (parsed.latest !== null && typeof parsed.latest !== "string") return null;
|
|
18746
18918
|
return parsed;
|
|
@@ -18761,7 +18933,7 @@ function isVersionCacheStale(filename = CLI_CACHE_FILE, maxAgeMs = MAX_AGE_24H_M
|
|
|
18761
18933
|
}
|
|
18762
18934
|
function writeVersionCache(filename, cache) {
|
|
18763
18935
|
const path35 = getVersionCachePath(filename);
|
|
18764
|
-
const dir =
|
|
18936
|
+
const dir = dirname5(path35);
|
|
18765
18937
|
if (!existsSync3(dir)) mkdirSync2(dir, { recursive: true });
|
|
18766
18938
|
writeFileSync2(path35, JSON.stringify(cache));
|
|
18767
18939
|
}
|
|
@@ -18780,8 +18952,8 @@ var init_version_cache = __esm({
|
|
|
18780
18952
|
});
|
|
18781
18953
|
|
|
18782
18954
|
// src/lib/skill-version.ts
|
|
18783
|
-
import { existsSync as existsSync4, readFileSync as
|
|
18784
|
-
import { join as
|
|
18955
|
+
import { existsSync as existsSync4, readFileSync as readFileSync7 } from "fs";
|
|
18956
|
+
import { join as join8 } from "path";
|
|
18785
18957
|
import * as yaml4 from "js-yaml";
|
|
18786
18958
|
function skillInstallPaths(skillName) {
|
|
18787
18959
|
return HARNESS_SKILL_DIRS.map((dir) => `${dir}/skills/${skillName}/${SKILL_FILENAME}`);
|
|
@@ -18802,11 +18974,11 @@ function parseFrontmatterVersion(content) {
|
|
|
18802
18974
|
function findInstalledSkills(projectRoot, paths = SKILL_INSTALL_PATHS) {
|
|
18803
18975
|
const found = [];
|
|
18804
18976
|
for (const rel of paths) {
|
|
18805
|
-
const path35 =
|
|
18977
|
+
const path35 = join8(projectRoot, rel);
|
|
18806
18978
|
if (!existsSync4(path35)) continue;
|
|
18807
18979
|
let version = null;
|
|
18808
18980
|
try {
|
|
18809
|
-
version = parseFrontmatterVersion(
|
|
18981
|
+
version = parseFrontmatterVersion(readFileSync7(path35, "utf-8"));
|
|
18810
18982
|
} catch {
|
|
18811
18983
|
}
|
|
18812
18984
|
found.push({ path: path35, version });
|
|
@@ -18841,13 +19013,13 @@ __export(config_exports, {
|
|
|
18841
19013
|
writeConfig: () => writeConfig
|
|
18842
19014
|
});
|
|
18843
19015
|
import * as fs6 from "fs";
|
|
18844
|
-
import * as
|
|
19016
|
+
import * as path7 from "path";
|
|
18845
19017
|
import * as os from "os";
|
|
18846
19018
|
function configDir() {
|
|
18847
|
-
return
|
|
19019
|
+
return path7.join(os.homedir(), ".wayai");
|
|
18848
19020
|
}
|
|
18849
19021
|
function configPath() {
|
|
18850
|
-
return
|
|
19022
|
+
return path7.join(configDir(), "config.json");
|
|
18851
19023
|
}
|
|
18852
19024
|
function getConfigPath() {
|
|
18853
19025
|
return configPath();
|
|
@@ -18900,13 +19072,13 @@ var init_config = __esm({
|
|
|
18900
19072
|
|
|
18901
19073
|
// src/lib/token-store.ts
|
|
18902
19074
|
import * as fs7 from "fs";
|
|
18903
|
-
import * as
|
|
19075
|
+
import * as path8 from "path";
|
|
18904
19076
|
import * as os2 from "os";
|
|
18905
19077
|
function configDir2() {
|
|
18906
|
-
return
|
|
19078
|
+
return path8.join(os2.homedir(), ".wayai");
|
|
18907
19079
|
}
|
|
18908
19080
|
function configPath2() {
|
|
18909
|
-
return
|
|
19081
|
+
return path8.join(configDir2(), "config.json");
|
|
18910
19082
|
}
|
|
18911
19083
|
function manualCleanupCommand(account) {
|
|
18912
19084
|
if (process.platform === "darwin") {
|
|
@@ -19406,26 +19578,26 @@ __export(skill_symlink_exports, {
|
|
|
19406
19578
|
healClaudeSkillLink: () => healClaudeSkillLink,
|
|
19407
19579
|
healSkillLinkForCommand: () => healSkillLinkForCommand
|
|
19408
19580
|
});
|
|
19409
|
-
import { existsSync as existsSync7, lstatSync, mkdirSync as mkdirSync5, rmSync, symlinkSync } from "fs";
|
|
19410
|
-
import { join as
|
|
19581
|
+
import { existsSync as existsSync7, lstatSync as lstatSync3, mkdirSync as mkdirSync5, rmSync as rmSync2, symlinkSync } from "fs";
|
|
19582
|
+
import { join as join11 } from "path";
|
|
19411
19583
|
function healClaudeSkillLink(root) {
|
|
19412
19584
|
try {
|
|
19413
|
-
const source =
|
|
19414
|
-
if (!existsSync7(
|
|
19415
|
-
const link =
|
|
19416
|
-
if (existsSync7(
|
|
19585
|
+
const source = join11(root, ".agents", "skills", SKILL_NAME);
|
|
19586
|
+
if (!existsSync7(join11(source, SKILL_FILENAME))) return false;
|
|
19587
|
+
const link = join11(root, ".claude", "skills", SKILL_NAME);
|
|
19588
|
+
if (existsSync7(join11(link, SKILL_FILENAME))) return false;
|
|
19417
19589
|
let entry = null;
|
|
19418
19590
|
try {
|
|
19419
|
-
entry =
|
|
19591
|
+
entry = lstatSync3(link);
|
|
19420
19592
|
} catch {
|
|
19421
19593
|
entry = null;
|
|
19422
19594
|
}
|
|
19423
19595
|
if (entry) {
|
|
19424
19596
|
if (!entry.isSymbolicLink()) return false;
|
|
19425
|
-
|
|
19597
|
+
rmSync2(link, { force: true });
|
|
19426
19598
|
}
|
|
19427
|
-
mkdirSync5(
|
|
19428
|
-
symlinkSync(
|
|
19599
|
+
mkdirSync5(join11(root, ".claude", "skills"), { recursive: true });
|
|
19600
|
+
symlinkSync(join11("..", "..", ".agents", "skills", SKILL_NAME), link, "dir");
|
|
19429
19601
|
return true;
|
|
19430
19602
|
} catch {
|
|
19431
19603
|
return false;
|
|
@@ -19709,7 +19881,7 @@ var init_base_id = __esm({
|
|
|
19709
19881
|
// src/lib/worktree-scope.ts
|
|
19710
19882
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
19711
19883
|
import * as fs8 from "fs";
|
|
19712
|
-
import * as
|
|
19884
|
+
import * as path9 from "path";
|
|
19713
19885
|
import * as yaml5 from "js-yaml";
|
|
19714
19886
|
function axisNoun(axis) {
|
|
19715
19887
|
return AXES[axis].noun;
|
|
@@ -19724,7 +19896,7 @@ function resolveGitDir() {
|
|
|
19724
19896
|
encoding: "utf-8",
|
|
19725
19897
|
stdio: ["pipe", "pipe", "pipe"]
|
|
19726
19898
|
}).trim();
|
|
19727
|
-
gitDir = raw ?
|
|
19899
|
+
gitDir = raw ? path9.resolve(cwd, raw) : null;
|
|
19728
19900
|
} catch {
|
|
19729
19901
|
gitDir = null;
|
|
19730
19902
|
}
|
|
@@ -19733,12 +19905,12 @@ function resolveGitDir() {
|
|
|
19733
19905
|
}
|
|
19734
19906
|
function getScopePath() {
|
|
19735
19907
|
const gitDir = resolveGitDir();
|
|
19736
|
-
return gitDir ?
|
|
19908
|
+
return gitDir ? path9.join(gitDir, SCOPE_FILE) : null;
|
|
19737
19909
|
}
|
|
19738
19910
|
function legacyPaths() {
|
|
19739
19911
|
const gitDir = resolveGitDir();
|
|
19740
19912
|
if (!gitDir) return [];
|
|
19741
|
-
return AXIS_ORDER.flatMap((axis) => AXES[axis].legacyFiles).map((f) =>
|
|
19913
|
+
return AXIS_ORDER.flatMap((axis) => AXES[axis].legacyFiles).map((f) => path9.join(gitDir, f));
|
|
19742
19914
|
}
|
|
19743
19915
|
function emptyScope() {
|
|
19744
19916
|
return { hubs: [], bases: [] };
|
|
@@ -19762,7 +19934,7 @@ function readLegacyAxis(axis) {
|
|
|
19762
19934
|
for (const filename of legacyFiles) {
|
|
19763
19935
|
let raw;
|
|
19764
19936
|
try {
|
|
19765
|
-
raw = fs8.readFileSync(
|
|
19937
|
+
raw = fs8.readFileSync(path9.join(gitDir, filename), "utf-8");
|
|
19766
19938
|
} catch (err) {
|
|
19767
19939
|
if (err.code === "ENOENT") continue;
|
|
19768
19940
|
throw err;
|
|
@@ -19982,8 +20154,13 @@ function buildSkillState() {
|
|
|
19982
20154
|
}
|
|
19983
20155
|
function buildWorkspaceState(resolved) {
|
|
19984
20156
|
if (!resolved) return { scoped: false, path: null, hub_count: 0 };
|
|
19985
|
-
|
|
19986
|
-
|
|
20157
|
+
let hubCount = 0;
|
|
20158
|
+
try {
|
|
20159
|
+
const ws = detectWorkspace();
|
|
20160
|
+
hubCount = ws ? scanWorkspaceHubs(ws.workspaceDir).length : 0;
|
|
20161
|
+
} catch {
|
|
20162
|
+
hubCount = 0;
|
|
20163
|
+
}
|
|
19987
20164
|
return { scoped: true, path: resolved.path, hub_count: hubCount };
|
|
19988
20165
|
}
|
|
19989
20166
|
async function statusCommand(args2, pkg2) {
|
|
@@ -20221,12 +20398,12 @@ __export(init_exports, {
|
|
|
20221
20398
|
parseArgs: () => parseArgs3
|
|
20222
20399
|
});
|
|
20223
20400
|
import { mkdirSync as mkdirSync6 } from "fs";
|
|
20224
|
-
import
|
|
20401
|
+
import path10 from "path";
|
|
20225
20402
|
function ensureHubsDir(gitRoot) {
|
|
20226
20403
|
const hubsDir = resolveLayout(gitRoot).hubsDir;
|
|
20227
20404
|
if (isDirectory(hubsDir)) return null;
|
|
20228
20405
|
mkdirSync6(hubsDir, { recursive: true });
|
|
20229
|
-
return `${
|
|
20406
|
+
return `${path10.relative(gitRoot, hubsDir)}/`;
|
|
20230
20407
|
}
|
|
20231
20408
|
function parseArgs3(args2) {
|
|
20232
20409
|
let orgId;
|
|
@@ -20355,118 +20532,8 @@ var init_init = __esm({
|
|
|
20355
20532
|
}
|
|
20356
20533
|
});
|
|
20357
20534
|
|
|
20358
|
-
// src/lib/fs-safety.ts
|
|
20359
|
-
import * as fs9 from "fs";
|
|
20360
|
-
import * as path10 from "path";
|
|
20361
|
-
function fileHasBytes(abs, data) {
|
|
20362
|
-
let st;
|
|
20363
|
-
try {
|
|
20364
|
-
st = fs9.lstatSync(abs);
|
|
20365
|
-
} catch {
|
|
20366
|
-
return false;
|
|
20367
|
-
}
|
|
20368
|
-
if (!st.isFile() || st.isSymbolicLink()) return false;
|
|
20369
|
-
try {
|
|
20370
|
-
return fs9.readFileSync(abs).equals(data);
|
|
20371
|
-
} catch {
|
|
20372
|
-
return false;
|
|
20373
|
-
}
|
|
20374
|
-
}
|
|
20375
|
-
function realpathContained(root, abs) {
|
|
20376
|
-
let realRoot;
|
|
20377
|
-
let realAbs;
|
|
20378
|
-
try {
|
|
20379
|
-
realRoot = fs9.realpathSync(root);
|
|
20380
|
-
realAbs = fs9.realpathSync(abs);
|
|
20381
|
-
} catch {
|
|
20382
|
-
return false;
|
|
20383
|
-
}
|
|
20384
|
-
return realAbs === realRoot || realAbs.startsWith(realRoot + path10.sep);
|
|
20385
|
-
}
|
|
20386
|
-
function mkdirTolerateRace(dir) {
|
|
20387
|
-
try {
|
|
20388
|
-
fs9.mkdirSync(dir);
|
|
20389
|
-
return true;
|
|
20390
|
-
} catch (err) {
|
|
20391
|
-
if (err.code !== "EEXIST") throw err;
|
|
20392
|
-
let st;
|
|
20393
|
-
try {
|
|
20394
|
-
st = fs9.lstatSync(dir);
|
|
20395
|
-
} catch {
|
|
20396
|
-
st = void 0;
|
|
20397
|
-
}
|
|
20398
|
-
return !!st?.isDirectory();
|
|
20399
|
-
}
|
|
20400
|
-
}
|
|
20401
|
-
function ensureRealSubdirNoSymlink(root, target, create) {
|
|
20402
|
-
const rootResolved = path10.resolve(root);
|
|
20403
|
-
const targetResolved = path10.resolve(target);
|
|
20404
|
-
if (targetResolved !== rootResolved && !targetResolved.startsWith(rootResolved + path10.sep)) return false;
|
|
20405
|
-
try {
|
|
20406
|
-
if (!fs9.lstatSync(rootResolved).isDirectory()) return false;
|
|
20407
|
-
} catch {
|
|
20408
|
-
return false;
|
|
20409
|
-
}
|
|
20410
|
-
const rel = path10.relative(rootResolved, targetResolved);
|
|
20411
|
-
if (rel === "") return true;
|
|
20412
|
-
let cur = rootResolved;
|
|
20413
|
-
for (const segment of rel.split(path10.sep)) {
|
|
20414
|
-
cur = path10.join(cur, segment);
|
|
20415
|
-
let st;
|
|
20416
|
-
try {
|
|
20417
|
-
st = fs9.lstatSync(cur);
|
|
20418
|
-
} catch {
|
|
20419
|
-
st = void 0;
|
|
20420
|
-
}
|
|
20421
|
-
if (st) {
|
|
20422
|
-
if (!st.isDirectory()) return false;
|
|
20423
|
-
} else if (create) {
|
|
20424
|
-
if (!mkdirTolerateRace(cur)) return false;
|
|
20425
|
-
} else {
|
|
20426
|
-
return true;
|
|
20427
|
-
}
|
|
20428
|
-
}
|
|
20429
|
-
return true;
|
|
20430
|
-
}
|
|
20431
|
-
function readFileNoFollow(root, abs) {
|
|
20432
|
-
if (!ensureRealSubdirNoSymlink(root, path10.dirname(abs), false)) return null;
|
|
20433
|
-
try {
|
|
20434
|
-
if (!fs9.lstatSync(abs).isFile()) return null;
|
|
20435
|
-
return fs9.readFileSync(abs);
|
|
20436
|
-
} catch {
|
|
20437
|
-
return null;
|
|
20438
|
-
}
|
|
20439
|
-
}
|
|
20440
|
-
function writeFileNoFollow(root, abs, data) {
|
|
20441
|
-
const parent = path10.dirname(abs);
|
|
20442
|
-
if (!ensureRealSubdirNoSymlink(root, parent, true)) return false;
|
|
20443
|
-
let st;
|
|
20444
|
-
try {
|
|
20445
|
-
st = fs9.lstatSync(abs);
|
|
20446
|
-
} catch {
|
|
20447
|
-
}
|
|
20448
|
-
if (st?.isSymbolicLink()) fs9.rmSync(abs);
|
|
20449
|
-
fs9.writeFileSync(abs, data);
|
|
20450
|
-
return true;
|
|
20451
|
-
}
|
|
20452
|
-
function createFileNoFollow(root, abs, data) {
|
|
20453
|
-
if (!ensureRealSubdirNoSymlink(root, path10.dirname(abs), true)) return "refused";
|
|
20454
|
-
try {
|
|
20455
|
-
fs9.writeFileSync(abs, data, { flag: "wx" });
|
|
20456
|
-
} catch (err) {
|
|
20457
|
-
if (err.code === "EEXIST") return "exists";
|
|
20458
|
-
throw err;
|
|
20459
|
-
}
|
|
20460
|
-
return "created";
|
|
20461
|
-
}
|
|
20462
|
-
var init_fs_safety = __esm({
|
|
20463
|
-
"src/lib/fs-safety.ts"() {
|
|
20464
|
-
"use strict";
|
|
20465
|
-
}
|
|
20466
|
-
});
|
|
20467
|
-
|
|
20468
20535
|
// src/lib/resource-files.ts
|
|
20469
|
-
import * as
|
|
20536
|
+
import * as fs9 from "fs";
|
|
20470
20537
|
import * as path11 from "path";
|
|
20471
20538
|
import * as crypto3 from "crypto";
|
|
20472
20539
|
function isBinaryFile(filename) {
|
|
@@ -20513,14 +20580,14 @@ function computeHash(data) {
|
|
|
20513
20580
|
}
|
|
20514
20581
|
function scanResourceFiles(dir, prefix = "") {
|
|
20515
20582
|
const files = [];
|
|
20516
|
-
const entries =
|
|
20583
|
+
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
20517
20584
|
for (const entry of entries) {
|
|
20518
20585
|
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
20519
20586
|
if (entry.isDirectory()) {
|
|
20520
20587
|
files.push(...scanResourceFiles(path11.join(dir, entry.name), relPath));
|
|
20521
20588
|
} else if (entry.isFile()) {
|
|
20522
20589
|
const fullPath = path11.join(dir, entry.name);
|
|
20523
|
-
const stat2 =
|
|
20590
|
+
const stat2 = fs9.statSync(fullPath);
|
|
20524
20591
|
if (stat2.size > MAX_RESOURCE_FILE_SIZE3) {
|
|
20525
20592
|
console.warn(` Warning: skipping ${relPath} (${(stat2.size / 1024 / 1024).toFixed(1)}MB exceeds 10MB limit)`);
|
|
20526
20593
|
continue;
|
|
@@ -20530,7 +20597,7 @@ function scanResourceFiles(dir, prefix = "") {
|
|
|
20530
20597
|
mime_type: guessMimeType(entry.name),
|
|
20531
20598
|
file_size: stat2.size
|
|
20532
20599
|
};
|
|
20533
|
-
const data =
|
|
20600
|
+
const data = fs9.readFileSync(fullPath);
|
|
20534
20601
|
fileEntry.hash = computeHash(data);
|
|
20535
20602
|
if (isBinaryFile(entry.name)) {
|
|
20536
20603
|
fileEntry.content_base64 = data.toString("base64");
|
|
@@ -20590,7 +20657,7 @@ function writeResourceFileTree(resDir, files, root, log) {
|
|
|
20590
20657
|
return;
|
|
20591
20658
|
}
|
|
20592
20659
|
if (files.length === 0) {
|
|
20593
|
-
if (
|
|
20660
|
+
if (fs9.existsSync(resDir)) cleanOrphanFiles(resDir, "", /* @__PURE__ */ new Set(), root, log);
|
|
20594
20661
|
return;
|
|
20595
20662
|
}
|
|
20596
20663
|
const writtenPaths = /* @__PURE__ */ new Set();
|
|
@@ -20611,18 +20678,18 @@ function writeResourceFileTree(resDir, files, root, log) {
|
|
|
20611
20678
|
writtenPaths.delete(file.path);
|
|
20612
20679
|
}
|
|
20613
20680
|
}
|
|
20614
|
-
if (
|
|
20681
|
+
if (fs9.existsSync(resDir)) cleanOrphanFiles(resDir, "", writtenPaths, root, log);
|
|
20615
20682
|
}
|
|
20616
20683
|
function cleanOrphanFiles(dir, prefix, writtenPaths, root, log) {
|
|
20617
|
-
const entries =
|
|
20684
|
+
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
20618
20685
|
for (const entry of entries) {
|
|
20619
20686
|
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
20620
20687
|
const fullPath = path11.join(dir, entry.name);
|
|
20621
20688
|
if (entry.isDirectory()) {
|
|
20622
20689
|
cleanOrphanFiles(fullPath, relPath, writtenPaths, root, log);
|
|
20623
|
-
if (
|
|
20690
|
+
if (fs9.readdirSync(fullPath).length === 0) fs9.rmdirSync(fullPath);
|
|
20624
20691
|
} else if (!writtenPaths.has(relPath)) {
|
|
20625
|
-
|
|
20692
|
+
fs9.unlinkSync(fullPath);
|
|
20626
20693
|
if (log && root) log.removed.push(path11.relative(root, fullPath));
|
|
20627
20694
|
}
|
|
20628
20695
|
}
|
|
@@ -20643,8 +20710,8 @@ async function downloadBinaryFiles(resDir, files, root, log) {
|
|
|
20643
20710
|
}
|
|
20644
20711
|
if (file.hash) {
|
|
20645
20712
|
try {
|
|
20646
|
-
const st =
|
|
20647
|
-
if (st.isFile() && !st.isSymbolicLink() && computeHash(
|
|
20713
|
+
const st = fs9.lstatSync(filePath);
|
|
20714
|
+
if (st.isFile() && !st.isSymbolicLink() && computeHash(fs9.readFileSync(filePath)) === file.hash) continue;
|
|
20648
20715
|
} catch {
|
|
20649
20716
|
}
|
|
20650
20717
|
}
|
|
@@ -20698,7 +20765,7 @@ var init_resource_files = __esm({
|
|
|
20698
20765
|
});
|
|
20699
20766
|
|
|
20700
20767
|
// src/lib/eval-attachments.ts
|
|
20701
|
-
import * as
|
|
20768
|
+
import * as fs10 from "fs";
|
|
20702
20769
|
import * as path12 from "path";
|
|
20703
20770
|
function resolveTurnAttachments(hubFolder, turn, label, bytesByHash) {
|
|
20704
20771
|
const raw = turn.attachments;
|
|
@@ -20722,7 +20789,7 @@ function resolveTurnAttachments(hubFolder, turn, label, bytesByHash) {
|
|
|
20722
20789
|
}
|
|
20723
20790
|
let stat2;
|
|
20724
20791
|
try {
|
|
20725
|
-
stat2 =
|
|
20792
|
+
stat2 = fs10.statSync(abs);
|
|
20726
20793
|
} catch {
|
|
20727
20794
|
}
|
|
20728
20795
|
if (!stat2?.isFile()) {
|
|
@@ -20736,7 +20803,7 @@ function resolveTurnAttachments(hubFolder, turn, label, bytesByHash) {
|
|
|
20736
20803
|
`${label}: attachment "${entry}" is ${(stat2.size / 1024 / 1024).toFixed(1)}MB, over the 10MB limit.`
|
|
20737
20804
|
);
|
|
20738
20805
|
}
|
|
20739
|
-
const data =
|
|
20806
|
+
const data = fs10.readFileSync(abs);
|
|
20740
20807
|
const hash = computeHash(data);
|
|
20741
20808
|
const fileName = path12.basename(abs);
|
|
20742
20809
|
const mimeType = guessMimeType(fileName) ?? "application/octet-stream";
|
|
@@ -20844,16 +20911,16 @@ async function downloadEvalAttachments(hubFolder, downloads) {
|
|
|
20844
20911
|
console.warn(` Warning: ${ATTACHMENTS_DIR}/ is not reachable inside the hub folder without a symlink; skipping attachment sync.`);
|
|
20845
20912
|
return result;
|
|
20846
20913
|
}
|
|
20847
|
-
if (!
|
|
20914
|
+
if (!fs10.existsSync(attachDir)) return result;
|
|
20848
20915
|
for (const dl of downloads) {
|
|
20849
20916
|
const abs = path12.resolve(hubFolder, dl.relPath);
|
|
20850
20917
|
if (abs !== attachDir && !abs.startsWith(attachDir + path12.sep)) continue;
|
|
20851
20918
|
let existing;
|
|
20852
20919
|
try {
|
|
20853
|
-
existing =
|
|
20920
|
+
existing = fs10.lstatSync(abs);
|
|
20854
20921
|
} catch {
|
|
20855
20922
|
}
|
|
20856
|
-
if (existing?.isFile() && !existing.isSymbolicLink() && computeHash(
|
|
20923
|
+
if (existing?.isFile() && !existing.isSymbolicLink() && computeHash(fs10.readFileSync(abs)) === dl.hash) {
|
|
20857
20924
|
continue;
|
|
20858
20925
|
}
|
|
20859
20926
|
try {
|
|
@@ -20871,11 +20938,11 @@ async function downloadEvalAttachments(hubFolder, downloads) {
|
|
|
20871
20938
|
}
|
|
20872
20939
|
}
|
|
20873
20940
|
const keep = new Set(downloads.map((d) => path12.resolve(hubFolder, d.relPath)));
|
|
20874
|
-
for (const name of
|
|
20941
|
+
for (const name of fs10.readdirSync(attachDir)) {
|
|
20875
20942
|
const abs = path12.join(attachDir, name);
|
|
20876
|
-
const st =
|
|
20943
|
+
const st = fs10.lstatSync(abs);
|
|
20877
20944
|
if ((st.isFile() || st.isSymbolicLink()) && !keep.has(abs)) {
|
|
20878
|
-
|
|
20945
|
+
fs10.rmSync(abs);
|
|
20879
20946
|
result.removed.push(path12.relative(hubFolder, abs));
|
|
20880
20947
|
}
|
|
20881
20948
|
}
|
|
@@ -20893,15 +20960,16 @@ var init_eval_attachments = __esm({
|
|
|
20893
20960
|
});
|
|
20894
20961
|
|
|
20895
20962
|
// src/lib/parser.ts
|
|
20896
|
-
import * as
|
|
20963
|
+
import * as fs11 from "fs";
|
|
20897
20964
|
import * as path13 from "path";
|
|
20898
20965
|
import * as yaml6 from "js-yaml";
|
|
20899
20966
|
function parseHubFolder(hubFolder, opts) {
|
|
20967
|
+
requireRealHubFolder(hubFolder, false);
|
|
20900
20968
|
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
20901
20969
|
if (!yamlPath) {
|
|
20902
20970
|
throw expected(`hub.yaml not found in ${hubFolder}`);
|
|
20903
20971
|
}
|
|
20904
|
-
const yamlContent =
|
|
20972
|
+
const yamlContent = readRealFileOrThrow(hubFolder, yamlPath) ?? "";
|
|
20905
20973
|
let config;
|
|
20906
20974
|
try {
|
|
20907
20975
|
config = yaml6.load(yamlContent);
|
|
@@ -20929,8 +20997,8 @@ function parseHubFolder(hubFolder, opts) {
|
|
|
20929
20997
|
if (typeof resolved.instructions === "string" && resolved.instructions.endsWith(".md")) {
|
|
20930
20998
|
const instrValue = resolved.instructions;
|
|
20931
20999
|
const instructionsPath = instrValue.startsWith("agents/") ? path13.join(hubFolder, instrValue) : path13.join(hubFolder, "agents", instrValue);
|
|
20932
|
-
if (
|
|
20933
|
-
resolved.instructions =
|
|
21000
|
+
if (fs11.existsSync(instructionsPath)) {
|
|
21001
|
+
resolved.instructions = fs11.readFileSync(instructionsPath, "utf-8");
|
|
20934
21002
|
} else {
|
|
20935
21003
|
throw expected(
|
|
20936
21004
|
`Agent instructions file not found: ${instructionsPath} (referenced by agent "${agent.name}")`
|
|
@@ -20938,8 +21006,8 @@ function parseHubFolder(hubFolder, opts) {
|
|
|
20938
21006
|
}
|
|
20939
21007
|
} else if (resolved.instructions === void 0 && typeof agent.name === "string") {
|
|
20940
21008
|
const conventionPath = path13.join(hubFolder, "agents", `${slugify(agent.name)}.md`);
|
|
20941
|
-
if (
|
|
20942
|
-
resolved.instructions =
|
|
21009
|
+
if (fs11.existsSync(conventionPath)) {
|
|
21010
|
+
resolved.instructions = fs11.readFileSync(conventionPath, "utf-8");
|
|
20943
21011
|
}
|
|
20944
21012
|
}
|
|
20945
21013
|
return resolved;
|
|
@@ -20994,17 +21062,17 @@ function parseHubFolder(hubFolder, opts) {
|
|
|
20994
21062
|
}
|
|
20995
21063
|
function scanEvalYamlFiles(hubFolder, bytesByHash) {
|
|
20996
21064
|
const evalsDir = path13.join(hubFolder, "evals");
|
|
20997
|
-
if (!
|
|
21065
|
+
if (!fs11.existsSync(evalsDir)) return [];
|
|
20998
21066
|
const evals = [];
|
|
20999
21067
|
const seen = /* @__PURE__ */ new Set();
|
|
21000
|
-
const topEntries =
|
|
21068
|
+
const topEntries = fs11.readdirSync(evalsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
21001
21069
|
for (const entry of topEntries) {
|
|
21002
21070
|
if (entry.isFile() && entry.name.endsWith(".yaml")) {
|
|
21003
21071
|
collectEval(evals, seen, path13.join(evalsDir, entry.name), `evals/${entry.name}`, null, hubFolder, bytesByHash);
|
|
21004
21072
|
} else if (entry.isDirectory()) {
|
|
21005
21073
|
const setName = entry.name;
|
|
21006
21074
|
const setDir = path13.join(evalsDir, setName);
|
|
21007
|
-
const setEntries =
|
|
21075
|
+
const setEntries = fs11.readdirSync(setDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
21008
21076
|
for (const sub of setEntries) {
|
|
21009
21077
|
if (sub.isDirectory()) {
|
|
21010
21078
|
throw expected(
|
|
@@ -21033,7 +21101,7 @@ function collectEval(evals, seen, filePath, relPath, setName, hubFolder, bytesBy
|
|
|
21033
21101
|
evals.push(evalEntry);
|
|
21034
21102
|
}
|
|
21035
21103
|
function parseEvalYaml(filePath, relPath, setName, hubFolder, bytesByHash) {
|
|
21036
|
-
const content =
|
|
21104
|
+
const content = fs11.readFileSync(filePath, "utf-8");
|
|
21037
21105
|
let raw;
|
|
21038
21106
|
try {
|
|
21039
21107
|
raw = yaml6.load(content);
|
|
@@ -21136,10 +21204,10 @@ function parseFixtureField(raw, label, key) {
|
|
|
21136
21204
|
}
|
|
21137
21205
|
function scanJourneyYamlFiles(hubFolder, bytesByHash) {
|
|
21138
21206
|
const journeysDir = path13.join(hubFolder, "journeys");
|
|
21139
|
-
if (!
|
|
21207
|
+
if (!fs11.existsSync(journeysDir)) return [];
|
|
21140
21208
|
const journeys = [];
|
|
21141
21209
|
const seen = /* @__PURE__ */ new Set();
|
|
21142
|
-
const entries =
|
|
21210
|
+
const entries = fs11.readdirSync(journeysDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
21143
21211
|
for (const entry of entries) {
|
|
21144
21212
|
if (entry.isDirectory()) {
|
|
21145
21213
|
throw expected(
|
|
@@ -21160,7 +21228,7 @@ function scanJourneyYamlFiles(hubFolder, bytesByHash) {
|
|
|
21160
21228
|
return journeys;
|
|
21161
21229
|
}
|
|
21162
21230
|
function parseJourneyYaml(filePath, relPath, hubFolder, bytesByHash) {
|
|
21163
|
-
const content =
|
|
21231
|
+
const content = fs11.readFileSync(filePath, "utf-8");
|
|
21164
21232
|
let raw;
|
|
21165
21233
|
try {
|
|
21166
21234
|
raw = yaml6.load(content);
|
|
@@ -21216,13 +21284,13 @@ function parseJourneyYaml(filePath, relPath, hubFolder, bytesByHash) {
|
|
|
21216
21284
|
}
|
|
21217
21285
|
function scanAgentYamlFiles(hubFolder) {
|
|
21218
21286
|
const agentsDir = path13.join(hubFolder, "agents");
|
|
21219
|
-
if (!
|
|
21220
|
-
const yamlFiles =
|
|
21287
|
+
if (!fs11.existsSync(agentsDir)) return [];
|
|
21288
|
+
const yamlFiles = fs11.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml")).sort();
|
|
21221
21289
|
if (yamlFiles.length === 0) return [];
|
|
21222
21290
|
const agents = [];
|
|
21223
21291
|
for (const file of yamlFiles) {
|
|
21224
21292
|
const filePath = path13.join(agentsDir, file);
|
|
21225
|
-
const content =
|
|
21293
|
+
const content = fs11.readFileSync(filePath, "utf-8");
|
|
21226
21294
|
let agent;
|
|
21227
21295
|
try {
|
|
21228
21296
|
agent = yaml6.load(content);
|
|
@@ -21257,7 +21325,7 @@ function parseResources(hubFolder, configResources) {
|
|
|
21257
21325
|
if (res.skill_name) resource.skill_name = res.skill_name;
|
|
21258
21326
|
const resSlug = slugify(resource.name);
|
|
21259
21327
|
const resDir = path13.join(resourcesDir, resSlug);
|
|
21260
|
-
if (
|
|
21328
|
+
if (fs11.existsSync(resDir)) {
|
|
21261
21329
|
const files = scanResourceFiles(resDir, "");
|
|
21262
21330
|
if (files.length > 0) {
|
|
21263
21331
|
resource.files = files;
|
|
@@ -21274,6 +21342,7 @@ var init_parser = __esm({
|
|
|
21274
21342
|
init_resource_files();
|
|
21275
21343
|
init_eval_attachments();
|
|
21276
21344
|
init_expected();
|
|
21345
|
+
init_fs_safety();
|
|
21277
21346
|
}
|
|
21278
21347
|
});
|
|
21279
21348
|
|
|
@@ -21331,7 +21400,7 @@ var init_workspace_files = __esm({
|
|
|
21331
21400
|
});
|
|
21332
21401
|
|
|
21333
21402
|
// src/lib/yaml-writer.ts
|
|
21334
|
-
import * as
|
|
21403
|
+
import * as fs12 from "fs";
|
|
21335
21404
|
import * as path15 from "path";
|
|
21336
21405
|
import * as yaml7 from "js-yaml";
|
|
21337
21406
|
function writeFileIfChanged(hubFolder, absPath, content, log) {
|
|
@@ -21382,11 +21451,11 @@ function buildEvalYamlObject(evalEntry, slug) {
|
|
|
21382
21451
|
function writeHubFolder(hubFolder, payload, options = {}) {
|
|
21383
21452
|
const log = { changed: [], removed: [] };
|
|
21384
21453
|
const agentsDir = path15.join(hubFolder, "agents");
|
|
21385
|
-
if (!
|
|
21386
|
-
|
|
21454
|
+
if (!fs12.existsSync(hubFolder)) {
|
|
21455
|
+
fs12.mkdirSync(hubFolder, { recursive: true });
|
|
21387
21456
|
}
|
|
21388
|
-
if (!
|
|
21389
|
-
|
|
21457
|
+
if (!fs12.existsSync(agentsDir)) {
|
|
21458
|
+
fs12.mkdirSync(agentsDir, { recursive: true });
|
|
21390
21459
|
}
|
|
21391
21460
|
const yamlPayload = buildYamlPayload(payload);
|
|
21392
21461
|
const agentFiles = extractAgentFiles(payload);
|
|
@@ -21401,8 +21470,8 @@ function writeHubFolder(hubFolder, payload, options = {}) {
|
|
|
21401
21470
|
if (seeded) log.changed.push(seeded);
|
|
21402
21471
|
}
|
|
21403
21472
|
const oldYamlPath = path15.join(hubFolder, "wayai.yaml");
|
|
21404
|
-
if (
|
|
21405
|
-
|
|
21473
|
+
if (fs12.existsSync(oldYamlPath)) {
|
|
21474
|
+
fs12.unlinkSync(oldYamlPath);
|
|
21406
21475
|
log.removed.push(path15.relative(hubFolder, oldYamlPath));
|
|
21407
21476
|
}
|
|
21408
21477
|
const yamlSlugs = writeAgentYamlFiles(hubFolder, agentsDir, payload.agents || [], log);
|
|
@@ -21411,20 +21480,20 @@ function writeHubFolder(hubFolder, payload, options = {}) {
|
|
|
21411
21480
|
mdSlugs.add(slug);
|
|
21412
21481
|
writeFileIfChanged(hubFolder, path15.join(agentsDir, `${slug}.md`), content, log);
|
|
21413
21482
|
}
|
|
21414
|
-
const existingFiles =
|
|
21483
|
+
const existingFiles = fs12.readdirSync(agentsDir);
|
|
21415
21484
|
for (const file of existingFiles) {
|
|
21416
21485
|
if (file.endsWith(".yaml")) {
|
|
21417
21486
|
const slug = file.slice(0, -5);
|
|
21418
21487
|
if (!yamlSlugs.has(slug)) {
|
|
21419
21488
|
const orphan = path15.join(agentsDir, file);
|
|
21420
|
-
|
|
21489
|
+
fs12.unlinkSync(orphan);
|
|
21421
21490
|
log.removed.push(path15.relative(hubFolder, orphan));
|
|
21422
21491
|
}
|
|
21423
21492
|
} else if (file.endsWith(".md")) {
|
|
21424
21493
|
const slug = file.slice(0, -3);
|
|
21425
21494
|
if (!mdSlugs.has(slug)) {
|
|
21426
21495
|
const orphan = path15.join(agentsDir, file);
|
|
21427
|
-
|
|
21496
|
+
fs12.unlinkSync(orphan);
|
|
21428
21497
|
log.removed.push(path15.relative(hubFolder, orphan));
|
|
21429
21498
|
}
|
|
21430
21499
|
}
|
|
@@ -21435,12 +21504,13 @@ function writeHubFolder(hubFolder, payload, options = {}) {
|
|
|
21435
21504
|
return log;
|
|
21436
21505
|
}
|
|
21437
21506
|
function setPreviewLabelInHubYaml(hubFolder, label) {
|
|
21507
|
+
requireRealHubFolder(hubFolder, false);
|
|
21438
21508
|
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
21439
21509
|
if (!yamlPath) return;
|
|
21440
|
-
const obj = yaml7.load(
|
|
21510
|
+
const obj = yaml7.load(readRealFileOrThrow(hubFolder, yamlPath) ?? "") ?? {};
|
|
21441
21511
|
if (label) obj.preview_label = label;
|
|
21442
21512
|
else delete obj.preview_label;
|
|
21443
|
-
|
|
21513
|
+
writeFileNoFollow(hubFolder, yamlPath, Buffer.from(yaml7.dump(obj, YAML_DUMP_OPTIONS), "utf-8"));
|
|
21444
21514
|
}
|
|
21445
21515
|
function buildYamlPayload(payload) {
|
|
21446
21516
|
const result = {
|
|
@@ -21505,17 +21575,17 @@ function extractAgentFiles(payload) {
|
|
|
21505
21575
|
function writeEvalYamlFiles(hubFolder, evals, log) {
|
|
21506
21576
|
const evalsDir = path15.join(hubFolder, "evals");
|
|
21507
21577
|
if (evals.length === 0) {
|
|
21508
|
-
if (
|
|
21578
|
+
if (fs12.existsSync(evalsDir)) {
|
|
21509
21579
|
cleanEvalOrphans(hubFolder, evalsDir, /* @__PURE__ */ new Set(), log);
|
|
21510
21580
|
try {
|
|
21511
|
-
if (
|
|
21581
|
+
if (fs12.readdirSync(evalsDir).length === 0) fs12.rmdirSync(evalsDir);
|
|
21512
21582
|
} catch {
|
|
21513
21583
|
}
|
|
21514
21584
|
}
|
|
21515
21585
|
return;
|
|
21516
21586
|
}
|
|
21517
|
-
if (!
|
|
21518
|
-
|
|
21587
|
+
if (!fs12.existsSync(evalsDir)) {
|
|
21588
|
+
fs12.mkdirSync(evalsDir, { recursive: true });
|
|
21519
21589
|
}
|
|
21520
21590
|
const writtenRelPaths = /* @__PURE__ */ new Set();
|
|
21521
21591
|
for (const evalEntry of evals) {
|
|
@@ -21527,12 +21597,6 @@ function writeEvalYamlFiles(hubFolder, evals, log) {
|
|
|
21527
21597
|
console.warn(` Warning: skipping eval "${evalEntry.name}" (scenario set "${setName}" escapes evals/ \u2014 possible bad backend data)`);
|
|
21528
21598
|
continue;
|
|
21529
21599
|
}
|
|
21530
|
-
if (setName) {
|
|
21531
|
-
const setDir = path15.join(evalsDir, setName);
|
|
21532
|
-
if (!fs13.existsSync(setDir)) {
|
|
21533
|
-
fs13.mkdirSync(setDir, { recursive: true });
|
|
21534
|
-
}
|
|
21535
|
-
}
|
|
21536
21600
|
const yamlContent = yaml7.dump(buildEvalYamlObject(evalEntry, slug), YAML_DUMP_OPTIONS);
|
|
21537
21601
|
writeFileIfChanged(hubFolder, targetPath, yamlContent, log);
|
|
21538
21602
|
writtenRelPaths.add(relPath);
|
|
@@ -21540,31 +21604,31 @@ function writeEvalYamlFiles(hubFolder, evals, log) {
|
|
|
21540
21604
|
cleanEvalOrphans(hubFolder, evalsDir, writtenRelPaths, log);
|
|
21541
21605
|
}
|
|
21542
21606
|
function cleanEvalOrphans(hubFolder, evalsDir, writtenRelPaths, log) {
|
|
21543
|
-
const entries =
|
|
21607
|
+
const entries = fs12.readdirSync(evalsDir, { withFileTypes: true });
|
|
21544
21608
|
for (const entry of entries) {
|
|
21545
21609
|
const fullPath = path15.join(evalsDir, entry.name);
|
|
21546
21610
|
if (entry.isFile()) {
|
|
21547
21611
|
if (entry.name.endsWith(".yaml") && !writtenRelPaths.has(entry.name)) {
|
|
21548
|
-
|
|
21612
|
+
fs12.unlinkSync(fullPath);
|
|
21549
21613
|
log.removed.push(path15.relative(hubFolder, fullPath));
|
|
21550
21614
|
}
|
|
21551
21615
|
continue;
|
|
21552
21616
|
}
|
|
21553
21617
|
if (entry.isDirectory()) {
|
|
21554
21618
|
const setName = entry.name;
|
|
21555
|
-
const subEntries =
|
|
21619
|
+
const subEntries = fs12.readdirSync(fullPath, { withFileTypes: true });
|
|
21556
21620
|
for (const sub of subEntries) {
|
|
21557
21621
|
if (sub.isFile() && sub.name.endsWith(".yaml")) {
|
|
21558
21622
|
const relPath = `${setName}/${sub.name}`;
|
|
21559
21623
|
if (!writtenRelPaths.has(relPath)) {
|
|
21560
21624
|
const orphan = path15.join(fullPath, sub.name);
|
|
21561
|
-
|
|
21625
|
+
fs12.unlinkSync(orphan);
|
|
21562
21626
|
log.removed.push(path15.relative(hubFolder, orphan));
|
|
21563
21627
|
}
|
|
21564
21628
|
}
|
|
21565
21629
|
}
|
|
21566
21630
|
try {
|
|
21567
|
-
if (
|
|
21631
|
+
if (fs12.readdirSync(fullPath).length === 0) fs12.rmdirSync(fullPath);
|
|
21568
21632
|
} catch {
|
|
21569
21633
|
}
|
|
21570
21634
|
}
|
|
@@ -21603,17 +21667,17 @@ function buildJourneyYamlObject(journeyEntry, slug) {
|
|
|
21603
21667
|
function writeJourneyYamlFiles(hubFolder, journeys, log) {
|
|
21604
21668
|
const journeysDir = path15.join(hubFolder, "journeys");
|
|
21605
21669
|
if (journeys.length === 0) {
|
|
21606
|
-
if (
|
|
21670
|
+
if (fs12.existsSync(journeysDir)) {
|
|
21607
21671
|
cleanJourneyOrphans(hubFolder, journeysDir, /* @__PURE__ */ new Set(), log);
|
|
21608
21672
|
try {
|
|
21609
|
-
if (
|
|
21673
|
+
if (fs12.readdirSync(journeysDir).length === 0) fs12.rmdirSync(journeysDir);
|
|
21610
21674
|
} catch {
|
|
21611
21675
|
}
|
|
21612
21676
|
}
|
|
21613
21677
|
return;
|
|
21614
21678
|
}
|
|
21615
|
-
if (!
|
|
21616
|
-
|
|
21679
|
+
if (!fs12.existsSync(journeysDir)) {
|
|
21680
|
+
fs12.mkdirSync(journeysDir, { recursive: true });
|
|
21617
21681
|
}
|
|
21618
21682
|
const writtenFiles = /* @__PURE__ */ new Set();
|
|
21619
21683
|
const usedSlugs = /* @__PURE__ */ new Set();
|
|
@@ -21627,11 +21691,11 @@ function writeJourneyYamlFiles(hubFolder, journeys, log) {
|
|
|
21627
21691
|
cleanJourneyOrphans(hubFolder, journeysDir, writtenFiles, log);
|
|
21628
21692
|
}
|
|
21629
21693
|
function cleanJourneyOrphans(hubFolder, journeysDir, writtenFiles, log) {
|
|
21630
|
-
const entries =
|
|
21694
|
+
const entries = fs12.readdirSync(journeysDir, { withFileTypes: true });
|
|
21631
21695
|
for (const entry of entries) {
|
|
21632
21696
|
if (entry.isFile() && entry.name.endsWith(".yaml") && !writtenFiles.has(entry.name)) {
|
|
21633
21697
|
const orphan = path15.join(journeysDir, entry.name);
|
|
21634
|
-
|
|
21698
|
+
fs12.unlinkSync(orphan);
|
|
21635
21699
|
log.removed.push(path15.relative(hubFolder, orphan));
|
|
21636
21700
|
}
|
|
21637
21701
|
}
|
|
@@ -21645,12 +21709,12 @@ function writeResourceFiles(hubFolder, resources, log) {
|
|
|
21645
21709
|
const resDir = path15.join(resourcesDir, resSlug);
|
|
21646
21710
|
writeResourceFileTree(resDir, resource.files || [], hubFolder, log);
|
|
21647
21711
|
}
|
|
21648
|
-
if (
|
|
21649
|
-
const existingDirs =
|
|
21712
|
+
if (fs12.existsSync(resourcesDir)) {
|
|
21713
|
+
const existingDirs = fs12.readdirSync(resourcesDir, { withFileTypes: true });
|
|
21650
21714
|
for (const entry of existingDirs) {
|
|
21651
21715
|
if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
|
|
21652
21716
|
const orphanDir = path15.join(resourcesDir, entry.name);
|
|
21653
|
-
|
|
21717
|
+
fs12.rmSync(orphanDir, { recursive: true, force: true });
|
|
21654
21718
|
log.removed.push(`${path15.relative(hubFolder, orphanDir)}/`);
|
|
21655
21719
|
}
|
|
21656
21720
|
}
|
|
@@ -21687,6 +21751,7 @@ async function materializeHubFolder(hubFolder, payload, options = {}) {
|
|
|
21687
21751
|
);
|
|
21688
21752
|
}
|
|
21689
21753
|
materialized.add(payload);
|
|
21754
|
+
requireRealHubFolder(hubFolder, true);
|
|
21690
21755
|
const attachmentDownloads = rewriteEvalAttachmentsToLocalPaths(payload);
|
|
21691
21756
|
const writeLog = writeHubFolder(hubFolder, payload, options);
|
|
21692
21757
|
const resourceDownloads = await downloadBinaryResourceFiles(hubFolder, payload);
|
|
@@ -21718,6 +21783,7 @@ var init_hub_materializer = __esm({
|
|
|
21718
21783
|
init_yaml_writer();
|
|
21719
21784
|
init_eval_attachments();
|
|
21720
21785
|
init_resource_files();
|
|
21786
|
+
init_fs_safety();
|
|
21721
21787
|
init_utils();
|
|
21722
21788
|
materialized = /* @__PURE__ */ new WeakSet();
|
|
21723
21789
|
}
|
|
@@ -21739,7 +21805,7 @@ var init_terminal_output = __esm({
|
|
|
21739
21805
|
});
|
|
21740
21806
|
|
|
21741
21807
|
// src/lib/base-workspace.ts
|
|
21742
|
-
import * as
|
|
21808
|
+
import * as fs13 from "fs";
|
|
21743
21809
|
import * as path17 from "path";
|
|
21744
21810
|
import * as yaml8 from "js-yaml";
|
|
21745
21811
|
function readBaseMeta(folder) {
|
|
@@ -21757,7 +21823,7 @@ function readBaseMeta(folder) {
|
|
|
21757
21823
|
function listBaseFolders(basesDir) {
|
|
21758
21824
|
let entries;
|
|
21759
21825
|
try {
|
|
21760
|
-
entries =
|
|
21826
|
+
entries = fs13.readdirSync(basesDir).filter((entry) => !entry.startsWith("."));
|
|
21761
21827
|
} catch {
|
|
21762
21828
|
return [];
|
|
21763
21829
|
}
|
|
@@ -21844,7 +21910,7 @@ function resolveBaseSelectorToId(gitRoot, selector) {
|
|
|
21844
21910
|
}
|
|
21845
21911
|
function hasBaseMetaFile(folder) {
|
|
21846
21912
|
try {
|
|
21847
|
-
return
|
|
21913
|
+
return fs13.lstatSync(path17.join(folder, BASE_META_FILE)).isFile();
|
|
21848
21914
|
} catch {
|
|
21849
21915
|
return false;
|
|
21850
21916
|
}
|
|
@@ -22157,7 +22223,7 @@ var init_client = __esm({
|
|
|
22157
22223
|
});
|
|
22158
22224
|
|
|
22159
22225
|
// src/data/helpers.ts
|
|
22160
|
-
import { readFileSync as
|
|
22226
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
22161
22227
|
function pathSegment(id, label = "id") {
|
|
22162
22228
|
if (!isPathSafeId(id)) {
|
|
22163
22229
|
throw expected(`Invalid ${label}: ${JSON.stringify(id)}. An id may use ${PATH_SAFE_ID_RULE}.`);
|
|
@@ -22185,7 +22251,7 @@ function parseData(data, flag) {
|
|
|
22185
22251
|
let text = data;
|
|
22186
22252
|
if (source !== void 0) {
|
|
22187
22253
|
try {
|
|
22188
|
-
text =
|
|
22254
|
+
text = readFileSync14(source, "utf-8");
|
|
22189
22255
|
} catch (e) {
|
|
22190
22256
|
throw expected(`${prefix}${source}: ${e instanceof Error ? e.message : "could not be read"}`);
|
|
22191
22257
|
}
|
|
@@ -22310,7 +22376,7 @@ var init_types2 = __esm({
|
|
|
22310
22376
|
});
|
|
22311
22377
|
|
|
22312
22378
|
// src/data/config-as-code/config-writer.ts
|
|
22313
|
-
import * as
|
|
22379
|
+
import * as fs14 from "fs";
|
|
22314
22380
|
import * as path19 from "path";
|
|
22315
22381
|
import * as yaml9 from "js-yaml";
|
|
22316
22382
|
function dump5(value) {
|
|
@@ -22345,14 +22411,14 @@ function pruneOrphans(folder, dir, keep, log) {
|
|
|
22345
22411
|
if (!ensureRealSubdirNoSymlink(folder, dir, false)) return;
|
|
22346
22412
|
let entries;
|
|
22347
22413
|
try {
|
|
22348
|
-
entries =
|
|
22414
|
+
entries = fs14.readdirSync(dir);
|
|
22349
22415
|
} catch {
|
|
22350
22416
|
return;
|
|
22351
22417
|
}
|
|
22352
22418
|
for (const file of entries) {
|
|
22353
22419
|
if (!file.endsWith(".yaml") || keep.has(file)) continue;
|
|
22354
22420
|
const abs = path19.join(dir, file);
|
|
22355
|
-
|
|
22421
|
+
fs14.rmSync(abs);
|
|
22356
22422
|
log.removed.push(path19.relative(folder, abs));
|
|
22357
22423
|
}
|
|
22358
22424
|
}
|
|
@@ -22366,7 +22432,7 @@ function metaFileObject(meta) {
|
|
|
22366
22432
|
function writeBaseFolder(folder, meta, config) {
|
|
22367
22433
|
const delta = { changed: [], removed: [] };
|
|
22368
22434
|
const parent = path19.dirname(folder);
|
|
22369
|
-
|
|
22435
|
+
fs14.mkdirSync(parent, { recursive: true });
|
|
22370
22436
|
if (!ensureRealSubdirNoSymlink(parent, folder, true)) {
|
|
22371
22437
|
throw expected(
|
|
22372
22438
|
`Refusing to write ${folder}: the path crosses a symlink. Remove it and pull again.`
|
|
@@ -22393,7 +22459,7 @@ function writeBaseFolder(folder, meta, config) {
|
|
|
22393
22459
|
for (const deprecated of DEPRECATED_ENTITY_DIRS) {
|
|
22394
22460
|
const dir = path19.join(folder, deprecated);
|
|
22395
22461
|
if (ensureRealSubdirNoSymlink(folder, dir, false)) {
|
|
22396
|
-
|
|
22462
|
+
fs14.rmSync(dir, { recursive: true, force: true });
|
|
22397
22463
|
}
|
|
22398
22464
|
}
|
|
22399
22465
|
return delta;
|
|
@@ -22545,7 +22611,7 @@ var init_api = __esm({
|
|
|
22545
22611
|
});
|
|
22546
22612
|
|
|
22547
22613
|
// src/data/config-as-code/config-parser.ts
|
|
22548
|
-
import * as
|
|
22614
|
+
import * as fs15 from "fs";
|
|
22549
22615
|
import * as path20 from "path";
|
|
22550
22616
|
import * as yaml10 from "js-yaml";
|
|
22551
22617
|
function readEntityDir(folder, dir) {
|
|
@@ -22554,7 +22620,7 @@ function readEntityDir(folder, dir) {
|
|
|
22554
22620
|
}
|
|
22555
22621
|
if (!isDirectory(dir)) return [];
|
|
22556
22622
|
const out = [];
|
|
22557
|
-
for (const file of
|
|
22623
|
+
for (const file of fs15.readdirSync(dir).sort()) {
|
|
22558
22624
|
if (!file.endsWith(".yaml")) continue;
|
|
22559
22625
|
const abs = path20.join(dir, file);
|
|
22560
22626
|
const bytes = readFileNoFollow(folder, abs);
|
|
@@ -22941,7 +23007,7 @@ __export(push_exports, {
|
|
|
22941
23007
|
shouldWarnIgnoredPreviewLabel: () => shouldWarnIgnoredPreviewLabel,
|
|
22942
23008
|
syncAfterPush: () => syncAfterPush
|
|
22943
23009
|
});
|
|
22944
|
-
import * as
|
|
23010
|
+
import * as fs16 from "fs";
|
|
22945
23011
|
import * as path22 from "path";
|
|
22946
23012
|
import * as yaml11 from "js-yaml";
|
|
22947
23013
|
function parseArgs5(args2) {
|
|
@@ -23050,13 +23116,14 @@ function printLocalFileChanges(delta) {
|
|
|
23050
23116
|
emit(delta.changed, "~");
|
|
23051
23117
|
}
|
|
23052
23118
|
async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, remoteConfig) {
|
|
23119
|
+
requireRealHubFolder(hubFolder, false);
|
|
23053
23120
|
const agentsDir = path22.join(hubFolder, "agents");
|
|
23054
23121
|
let agentsWithIds = [];
|
|
23055
|
-
if (
|
|
23056
|
-
const yamlFiles =
|
|
23122
|
+
if (fs16.existsSync(agentsDir)) {
|
|
23123
|
+
const yamlFiles = fs16.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml"));
|
|
23057
23124
|
for (const file of yamlFiles) {
|
|
23058
23125
|
try {
|
|
23059
|
-
const content =
|
|
23126
|
+
const content = fs16.readFileSync(path22.join(agentsDir, file), "utf-8");
|
|
23060
23127
|
const agent = yaml11.load(content);
|
|
23061
23128
|
if (agent?.id && agent.name) {
|
|
23062
23129
|
agentsWithIds.push({ id: agent.id, name: agent.name });
|
|
@@ -23069,7 +23136,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
23069
23136
|
if (agentsWithIds.length === 0) {
|
|
23070
23137
|
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
23071
23138
|
if (!yamlPath) return;
|
|
23072
|
-
const yamlContent =
|
|
23139
|
+
const yamlContent = readRealFileOrThrow(hubFolder, yamlPath) ?? "";
|
|
23073
23140
|
const config = yaml11.load(yamlContent);
|
|
23074
23141
|
agentsWithIds = (config.agents || []).filter((a) => !!a.id && !!a.name);
|
|
23075
23142
|
}
|
|
@@ -23101,18 +23168,18 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
23101
23168
|
}
|
|
23102
23169
|
}
|
|
23103
23170
|
if (renames.length === 0) return;
|
|
23104
|
-
if (!
|
|
23105
|
-
for (const file of
|
|
23171
|
+
if (!fs16.existsSync(agentsDir)) return;
|
|
23172
|
+
for (const file of fs16.readdirSync(agentsDir)) {
|
|
23106
23173
|
if (file.startsWith("__rename_temp_") && (file.endsWith(".md") || file.endsWith(".yaml"))) {
|
|
23107
23174
|
console.warn(` Warning: removing orphaned temp file agents/${file}`);
|
|
23108
|
-
|
|
23175
|
+
fs16.unlinkSync(path22.join(agentsDir, file));
|
|
23109
23176
|
}
|
|
23110
23177
|
}
|
|
23111
23178
|
const renameFileIfExists = (dir, oldName, newName) => {
|
|
23112
23179
|
const oldPath = path22.join(dir, oldName);
|
|
23113
23180
|
const newPath = path22.join(dir, newName);
|
|
23114
|
-
if (!
|
|
23115
|
-
|
|
23181
|
+
if (!fs16.existsSync(oldPath)) return false;
|
|
23182
|
+
fs16.renameSync(oldPath, newPath);
|
|
23116
23183
|
return true;
|
|
23117
23184
|
};
|
|
23118
23185
|
const oldSlugs = new Set(renames.map((r) => r.oldSlug));
|
|
@@ -23145,9 +23212,9 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
23145
23212
|
}
|
|
23146
23213
|
} else {
|
|
23147
23214
|
for (const { oldSlug, newSlug } of renames) {
|
|
23148
|
-
const hasOldFile = extensions.some((ext) =>
|
|
23215
|
+
const hasOldFile = extensions.some((ext) => fs16.existsSync(path22.join(agentsDir, `${oldSlug}${ext}`)));
|
|
23149
23216
|
if (!hasOldFile) continue;
|
|
23150
|
-
const hasNewFile = extensions.some((ext) =>
|
|
23217
|
+
const hasNewFile = extensions.some((ext) => fs16.existsSync(path22.join(agentsDir, `${newSlug}${ext}`)));
|
|
23151
23218
|
if (hasNewFile) {
|
|
23152
23219
|
console.warn(` Warning: skipping rename agents/${oldSlug}.* \u2192 agents/${newSlug}.* (target already exists)`);
|
|
23153
23220
|
continue;
|
|
@@ -23162,7 +23229,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
23162
23229
|
if (completedRenames.length === 0) return;
|
|
23163
23230
|
const mainYamlPath = resolveHubYamlPath(hubFolder);
|
|
23164
23231
|
if (mainYamlPath) {
|
|
23165
|
-
const mainYamlContent =
|
|
23232
|
+
const mainYamlContent = readRealFileOrThrow(hubFolder, mainYamlPath) ?? "";
|
|
23166
23233
|
const substitutionMap = /* @__PURE__ */ new Map();
|
|
23167
23234
|
for (const { oldSlug, newSlug } of completedRenames) {
|
|
23168
23235
|
substitutionMap.set(`agents/${oldSlug}.md`, `agents/${newSlug}.md`);
|
|
@@ -23173,7 +23240,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
23173
23240
|
(_match, prefix, pathMatch) => `${prefix}${substitutionMap.get(pathMatch) ?? pathMatch}`
|
|
23174
23241
|
);
|
|
23175
23242
|
if (updatedYaml !== mainYamlContent) {
|
|
23176
|
-
|
|
23243
|
+
writeFileNoFollow(hubFolder, mainYamlPath, Buffer.from(updatedYaml, "utf-8"));
|
|
23177
23244
|
console.log(` Updated instructions paths in ${path22.basename(mainYamlPath)}`);
|
|
23178
23245
|
}
|
|
23179
23246
|
}
|
|
@@ -23267,11 +23334,13 @@ New hub: "${newHub.hubName}" (${hubType})`);
|
|
|
23267
23334
|
return;
|
|
23268
23335
|
}
|
|
23269
23336
|
}
|
|
23337
|
+
requireRealHubFolder(newHub.hubFolder, false);
|
|
23270
23338
|
const hubYamlPath = resolveHubYamlPath(newHub.hubFolder);
|
|
23271
23339
|
if (!hubYamlPath) {
|
|
23272
23340
|
console.error(`hub.yaml not found in ${newHub.hubFolder}. Cannot proceed with hub creation.`);
|
|
23273
23341
|
process.exit(1);
|
|
23274
23342
|
}
|
|
23343
|
+
const content = readRealFileOrThrow(newHub.hubFolder, hubYamlPath) ?? "";
|
|
23275
23344
|
console.log("Creating hub...");
|
|
23276
23345
|
const createResult = await client.createHub(opts.organizationId, {
|
|
23277
23346
|
hubName: newHub.hubName,
|
|
@@ -23285,7 +23354,6 @@ New hub: "${newHub.hubName}" (${hubType})`);
|
|
|
23285
23354
|
process.exit(1);
|
|
23286
23355
|
}
|
|
23287
23356
|
console.log(`Hub created: ${createdHub.hub_name} (${hubId})`);
|
|
23288
|
-
const content = fs17.readFileSync(hubYamlPath, "utf-8");
|
|
23289
23357
|
const hasVersion = content.match(/^version:\s/m);
|
|
23290
23358
|
let updated;
|
|
23291
23359
|
if (hasVersion) {
|
|
@@ -23301,7 +23369,7 @@ hub_id: "${hubId}"
|
|
|
23301
23369
|
hub_environment: preview
|
|
23302
23370
|
${content}`;
|
|
23303
23371
|
}
|
|
23304
|
-
|
|
23372
|
+
writeFileNoFollow(newHub.hubFolder, hubYamlPath, Buffer.from(updated, "utf-8"));
|
|
23305
23373
|
seedScopeIfEmpty("hubs", hubId);
|
|
23306
23374
|
await pushSingleHub(client, hubId, newHub.hubFolder, opts.autoConfirm, opts.organizationId, { skipAgentRename: true });
|
|
23307
23375
|
}
|
|
@@ -23347,7 +23415,7 @@ async function pushCommand(args2) {
|
|
|
23347
23415
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
23348
23416
|
const workspaceDir = resolveWorkspaceDir();
|
|
23349
23417
|
const wsLabel = hubsDirLabel(gitRoot);
|
|
23350
|
-
if (!
|
|
23418
|
+
if (!fs16.existsSync(workspaceDir)) {
|
|
23351
23419
|
console.error(`No ${wsLabel}/ directory found. Run \`wayai pull\` first or create hub files in ${wsLabel}/<hub>/hub.yaml.`);
|
|
23352
23420
|
process.exit(1);
|
|
23353
23421
|
}
|
|
@@ -23391,6 +23459,7 @@ var init_push = __esm({
|
|
|
23391
23459
|
init_repo_config();
|
|
23392
23460
|
init_worktree_scope();
|
|
23393
23461
|
init_subtree_routing();
|
|
23462
|
+
init_fs_safety();
|
|
23394
23463
|
LOCAL_CHANGE_LIST_CAP = 20;
|
|
23395
23464
|
}
|
|
23396
23465
|
});
|
|
@@ -23403,7 +23472,7 @@ __export(pull_exports, {
|
|
|
23403
23472
|
resolveHubTarget: () => resolveHubTarget,
|
|
23404
23473
|
writeProductionMirror: () => writeProductionMirror2
|
|
23405
23474
|
});
|
|
23406
|
-
import * as
|
|
23475
|
+
import * as fs17 from "fs";
|
|
23407
23476
|
import * as path23 from "path";
|
|
23408
23477
|
function parseArgs6(args2) {
|
|
23409
23478
|
return { autoConfirm: args2.includes("--yes") || args2.includes("-y") };
|
|
@@ -23470,7 +23539,7 @@ async function pullCommand(args2) {
|
|
|
23470
23539
|
payload.preview_label,
|
|
23471
23540
|
payload.branch_name
|
|
23472
23541
|
);
|
|
23473
|
-
|
|
23542
|
+
fs17.mkdirSync(path23.dirname(hubFolder), { recursive: true });
|
|
23474
23543
|
console.log("Writing hub configuration...");
|
|
23475
23544
|
await materializeHubFolder(hubFolder, payload);
|
|
23476
23545
|
const finalFolder = autoRenameHubFolder(hubFolder, payload.hub.name, payload.hub_environment, payload.hub_id, payload.preview_label, payload.branch_name);
|
|
@@ -23524,7 +23593,7 @@ async function pullCommand(args2) {
|
|
|
23524
23593
|
}
|
|
23525
23594
|
async function writeProductionMirror2(workspaceDir, prodPayload) {
|
|
23526
23595
|
const folder = resolveHubFolder(workspaceDir, prodPayload.hub_id, prodPayload.hub.name, "production", null, null);
|
|
23527
|
-
|
|
23596
|
+
fs17.mkdirSync(path23.dirname(folder), { recursive: true });
|
|
23528
23597
|
await materializeHubFolder(folder, prodPayload, { seedAgentContext: false });
|
|
23529
23598
|
const finalFolder = autoRenameHubFolder(folder, prodPayload.hub.name, "production", prodPayload.hub_id, null, null);
|
|
23530
23599
|
prependMirrorMarker(finalFolder, prodPayload.hub_id);
|
|
@@ -23542,11 +23611,11 @@ async function mirrorLinkedProduction2(client, workspaceDir, productionHubId, or
|
|
|
23542
23611
|
function prependMirrorMarker(hubFolder, productionHubId) {
|
|
23543
23612
|
const hubYaml = path23.join(hubFolder, "hub.yaml");
|
|
23544
23613
|
try {
|
|
23545
|
-
const content =
|
|
23614
|
+
const content = fs17.readFileSync(hubYaml, "utf-8");
|
|
23546
23615
|
if (content.startsWith(MIRROR_MARKER_PREFIX2)) return;
|
|
23547
23616
|
const marker = `${MIRROR_MARKER_PREFIX2} ${productionHubId}. Edits are ignored; push is blocked. Edit the linked preview hub instead.
|
|
23548
23617
|
`;
|
|
23549
|
-
|
|
23618
|
+
fs17.writeFileSync(hubYaml, marker + content, "utf-8");
|
|
23550
23619
|
} catch {
|
|
23551
23620
|
}
|
|
23552
23621
|
}
|
|
@@ -23590,7 +23659,7 @@ __export(create_exports, {
|
|
|
23590
23659
|
createCommand: () => createCommand
|
|
23591
23660
|
});
|
|
23592
23661
|
import * as path24 from "path";
|
|
23593
|
-
import * as
|
|
23662
|
+
import * as fs18 from "fs";
|
|
23594
23663
|
function parseArgs7(args2) {
|
|
23595
23664
|
let autoConfirm = false;
|
|
23596
23665
|
let folderSelector;
|
|
@@ -23617,7 +23686,7 @@ async function createCommand(args2) {
|
|
|
23617
23686
|
const gitRoot = findGitRoot();
|
|
23618
23687
|
const wsLabel = hubsDirLabel(gitRoot);
|
|
23619
23688
|
if (gitRoot) warnLayoutOnce(gitRoot);
|
|
23620
|
-
if (!
|
|
23689
|
+
if (!fs18.existsSync(workspaceDir)) {
|
|
23621
23690
|
console.error(`No ${wsLabel}/ directory found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` first.`);
|
|
23622
23691
|
process.exit(1);
|
|
23623
23692
|
}
|
|
@@ -23751,7 +23820,7 @@ var replicate_exports = {};
|
|
|
23751
23820
|
__export(replicate_exports, {
|
|
23752
23821
|
replicateCommand: () => replicateCommand
|
|
23753
23822
|
});
|
|
23754
|
-
import * as
|
|
23823
|
+
import * as fs19 from "fs";
|
|
23755
23824
|
import * as path25 from "path";
|
|
23756
23825
|
function parseArgs9(args2) {
|
|
23757
23826
|
let label;
|
|
@@ -23798,8 +23867,8 @@ async function replicateCommand(args2) {
|
|
|
23798
23867
|
payload.preview_label,
|
|
23799
23868
|
payload.branch_name
|
|
23800
23869
|
);
|
|
23801
|
-
const folderPreExisted =
|
|
23802
|
-
|
|
23870
|
+
const folderPreExisted = fs19.existsSync(hubFolder);
|
|
23871
|
+
fs19.mkdirSync(path25.dirname(hubFolder), { recursive: true });
|
|
23803
23872
|
const delta = await materializeHubFolder(hubFolder, payload);
|
|
23804
23873
|
hubFolder = autoRenameHubFolder(
|
|
23805
23874
|
hubFolder,
|
|
@@ -24226,7 +24295,7 @@ __export(migrate_exports, {
|
|
|
24226
24295
|
migrateCommand: () => migrateCommand
|
|
24227
24296
|
});
|
|
24228
24297
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
24229
|
-
import * as
|
|
24298
|
+
import * as fs20 from "fs";
|
|
24230
24299
|
import * as path29 from "path";
|
|
24231
24300
|
function isTracked(gitRoot, p) {
|
|
24232
24301
|
try {
|
|
@@ -24240,7 +24309,7 @@ function isTracked(gitRoot, p) {
|
|
|
24240
24309
|
}
|
|
24241
24310
|
}
|
|
24242
24311
|
function moveDir(gitRoot, from, to) {
|
|
24243
|
-
|
|
24312
|
+
fs20.mkdirSync(path29.dirname(to), { recursive: true });
|
|
24244
24313
|
if (isTracked(gitRoot, from)) {
|
|
24245
24314
|
try {
|
|
24246
24315
|
execFileSync3("git", ["mv", path29.relative(gitRoot, from), path29.relative(gitRoot, to)], {
|
|
@@ -24251,7 +24320,7 @@ function moveDir(gitRoot, from, to) {
|
|
|
24251
24320
|
} catch {
|
|
24252
24321
|
}
|
|
24253
24322
|
}
|
|
24254
|
-
|
|
24323
|
+
fs20.renameSync(from, to);
|
|
24255
24324
|
return "fs";
|
|
24256
24325
|
}
|
|
24257
24326
|
async function migrateCommand(_args) {
|
|
@@ -24266,8 +24335,11 @@ async function migrateCommand(_args) {
|
|
|
24266
24335
|
const legacyOrg = path29.join(gitRoot, WAYAI_LAYOUT.legacy.orgAtRoot);
|
|
24267
24336
|
const newHubs = path29.join(newWs, WAYAI_LAYOUT.hubsSubdir);
|
|
24268
24337
|
const newOrg = path29.join(newWs, WAYAI_LAYOUT.orgSubdir);
|
|
24269
|
-
|
|
24270
|
-
|
|
24338
|
+
requireRealSubdirNoSymlink(gitRoot, newHubs, false);
|
|
24339
|
+
requireRealSubdirNoSymlink(gitRoot, newOrg, false);
|
|
24340
|
+
readRealFileOrThrow(gitRoot, workspaceManifestPath(gitRoot));
|
|
24341
|
+
const hasLegacyWs = isRealDirectory(legacyWs);
|
|
24342
|
+
const hasLegacyOrg = isRealDirectory(legacyOrg);
|
|
24271
24343
|
const orgPlan = planOrgMigration(gitRoot);
|
|
24272
24344
|
if (orgPlan.kind === "refuse") {
|
|
24273
24345
|
console.error(orgPlan.message);
|
|
@@ -24331,6 +24403,7 @@ var init_migrate = __esm({
|
|
|
24331
24403
|
"use strict";
|
|
24332
24404
|
init_workspace();
|
|
24333
24405
|
init_layout();
|
|
24406
|
+
init_fs_safety();
|
|
24334
24407
|
init_repo_config();
|
|
24335
24408
|
init_workspace_manifest();
|
|
24336
24409
|
}
|
|
@@ -24414,12 +24487,12 @@ var send_message_exports = {};
|
|
|
24414
24487
|
__export(send_message_exports, {
|
|
24415
24488
|
sendMessageCommand: () => sendMessageCommand
|
|
24416
24489
|
});
|
|
24417
|
-
import * as
|
|
24490
|
+
import * as fs21 from "fs";
|
|
24418
24491
|
import * as path30 from "path";
|
|
24419
24492
|
function statAttachment(filePath) {
|
|
24420
24493
|
let stat2;
|
|
24421
24494
|
try {
|
|
24422
|
-
stat2 =
|
|
24495
|
+
stat2 = fs21.statSync(filePath);
|
|
24423
24496
|
} catch {
|
|
24424
24497
|
console.error(`Error: file not found: ${filePath}`);
|
|
24425
24498
|
process.exit(1);
|
|
@@ -24435,7 +24508,7 @@ function readAttachment(filePath, size) {
|
|
|
24435
24508
|
const ext = path30.extname(fileName).replace(/^\./, "");
|
|
24436
24509
|
return {
|
|
24437
24510
|
file_name: fileName,
|
|
24438
|
-
file_binary:
|
|
24511
|
+
file_binary: fs21.readFileSync(filePath).toString("base64"),
|
|
24439
24512
|
file_size: size,
|
|
24440
24513
|
...ext && { file_extension: ext }
|
|
24441
24514
|
};
|
|
@@ -26634,7 +26707,7 @@ var eval_capture_exports = {};
|
|
|
26634
26707
|
__export(eval_capture_exports, {
|
|
26635
26708
|
evalCaptureCommand: () => evalCaptureCommand
|
|
26636
26709
|
});
|
|
26637
|
-
import * as
|
|
26710
|
+
import * as fs22 from "fs";
|
|
26638
26711
|
import * as path31 from "path";
|
|
26639
26712
|
import * as yaml12 from "js-yaml";
|
|
26640
26713
|
function isValidSetName(name) {
|
|
@@ -26708,7 +26781,17 @@ async function evalCaptureCommand(args2) {
|
|
|
26708
26781
|
console.error(`Resolved path "${path31.relative(hubFolder, targetPath)}" escapes evals/. Aborting.`);
|
|
26709
26782
|
process.exit(1);
|
|
26710
26783
|
}
|
|
26711
|
-
if (
|
|
26784
|
+
if (!ensureRealSubdirNoSymlink(hubFolder, targetDir, false)) {
|
|
26785
|
+
console.error(`${path31.relative(hubFolder, targetDir)} is reached through a symlink. Aborting.`);
|
|
26786
|
+
process.exit(1);
|
|
26787
|
+
}
|
|
26788
|
+
let targetTaken = true;
|
|
26789
|
+
try {
|
|
26790
|
+
fs22.lstatSync(targetPath);
|
|
26791
|
+
} catch {
|
|
26792
|
+
targetTaken = false;
|
|
26793
|
+
}
|
|
26794
|
+
if (targetTaken) {
|
|
26712
26795
|
console.error(`File already exists: ${path31.relative(hubFolder, targetPath)}. Use --name to choose a different name.`);
|
|
26713
26796
|
process.exit(1);
|
|
26714
26797
|
}
|
|
@@ -26741,8 +26824,13 @@ async function evalCaptureCommand(args2) {
|
|
|
26741
26824
|
...captured.evaluator_instructions ? { evaluator_instructions: captured.evaluator_instructions } : {}
|
|
26742
26825
|
};
|
|
26743
26826
|
const yamlObj = buildEvalYamlObject(evalEntry, slug);
|
|
26744
|
-
|
|
26745
|
-
|
|
26827
|
+
const outcome = createFileNoFollow(hubFolder, targetPath, Buffer.from(yaml12.dump(yamlObj, YAML_DUMP_OPTIONS), "utf-8"));
|
|
26828
|
+
if (outcome !== "created") {
|
|
26829
|
+
console.error(
|
|
26830
|
+
`Could not write ${path31.relative(hubFolder, targetPath)} (${outcome === "exists" ? "it appeared meanwhile" : "its folder is reached through a symlink"}). The scenario was created on the platform as ${captured.eval_id} \u2014 run \`wayai pull\` to fetch it.`
|
|
26831
|
+
);
|
|
26832
|
+
process.exit(1);
|
|
26833
|
+
}
|
|
26746
26834
|
const relPath = path31.relative(process.cwd(), targetPath);
|
|
26747
26835
|
console.log(`
|
|
26748
26836
|
Wrote ${relPath}`);
|
|
@@ -26757,6 +26845,7 @@ var init_eval_capture = __esm({
|
|
|
26757
26845
|
init_workspace();
|
|
26758
26846
|
init_utils();
|
|
26759
26847
|
init_yaml_writer();
|
|
26848
|
+
init_fs_safety();
|
|
26760
26849
|
}
|
|
26761
26850
|
});
|
|
26762
26851
|
|
|
@@ -28114,23 +28203,21 @@ var init_set_connection_credential = __esm({
|
|
|
28114
28203
|
});
|
|
28115
28204
|
|
|
28116
28205
|
// src/lib/org-workspace.ts
|
|
28117
|
-
import * as
|
|
28206
|
+
import * as fs23 from "fs";
|
|
28118
28207
|
import * as path32 from "path";
|
|
28119
28208
|
import * as yaml13 from "js-yaml";
|
|
28120
28209
|
function getOrgDir(gitRoot) {
|
|
28121
28210
|
return resolveLayout(gitRoot).orgDir;
|
|
28122
28211
|
}
|
|
28123
28212
|
function orgManifestExists(orgDir) {
|
|
28124
|
-
return
|
|
28213
|
+
return fs23.existsSync(path32.join(orgDir, ORG_MANIFEST_NAME));
|
|
28125
28214
|
}
|
|
28126
28215
|
function parseOrgResources(orgDir) {
|
|
28127
|
-
const manifestPath = path32.join(orgDir, ORG_MANIFEST_NAME);
|
|
28128
|
-
let manifest = {};
|
|
28129
|
-
if (fs24.existsSync(manifestPath)) {
|
|
28130
|
-
manifest = yaml13.load(fs24.readFileSync(manifestPath, "utf-8")) ?? {};
|
|
28131
|
-
}
|
|
28132
|
-
const rawResources = Array.isArray(manifest.resources) ? manifest.resources : [];
|
|
28133
28216
|
const resourcesDir = path32.join(orgDir, "resources");
|
|
28217
|
+
requireRealSubdirNoSymlink(orgDir, resourcesDir, false);
|
|
28218
|
+
const manifestText = readRealFileOrThrow(orgDir, path32.join(orgDir, ORG_MANIFEST_NAME));
|
|
28219
|
+
const manifest = (manifestText !== null ? yaml13.load(manifestText) : null) ?? {};
|
|
28220
|
+
const rawResources = Array.isArray(manifest.resources) ? manifest.resources : [];
|
|
28134
28221
|
const resources = rawResources.map((res) => {
|
|
28135
28222
|
const resource = { name: res.name };
|
|
28136
28223
|
if (res.id) resource.id = res.id;
|
|
@@ -28143,7 +28230,7 @@ function parseOrgResources(orgDir) {
|
|
|
28143
28230
|
if (Array.isArray(res.tags)) resource.tags = res.tags;
|
|
28144
28231
|
if (Array.isArray(res.folders)) resource.folders = res.folders;
|
|
28145
28232
|
const resDir = path32.join(resourcesDir, slugify(resource.name));
|
|
28146
|
-
if (
|
|
28233
|
+
if (fs23.existsSync(resDir)) {
|
|
28147
28234
|
const files = scanResourceFiles(resDir, "");
|
|
28148
28235
|
if (files.length > 0) resource.files = files;
|
|
28149
28236
|
}
|
|
@@ -28152,28 +28239,29 @@ function parseOrgResources(orgDir) {
|
|
|
28152
28239
|
return { version: 1, resources };
|
|
28153
28240
|
}
|
|
28154
28241
|
function writeOrgResources(orgDir, payload) {
|
|
28155
|
-
|
|
28242
|
+
fs23.mkdirSync(orgDir, { recursive: true });
|
|
28243
|
+
const resourcesDir = path32.join(orgDir, "resources");
|
|
28244
|
+
requireRealSubdirNoSymlink(orgDir, resourcesDir, false);
|
|
28156
28245
|
const resources = payload.resources ?? [];
|
|
28157
28246
|
const manifestResources = resources.map((r) => {
|
|
28158
28247
|
const { files: _files, ...rest } = r;
|
|
28159
28248
|
return rest;
|
|
28160
28249
|
});
|
|
28161
|
-
|
|
28250
|
+
writeFileNoFollow(
|
|
28251
|
+
orgDir,
|
|
28162
28252
|
path32.join(orgDir, ORG_MANIFEST_NAME),
|
|
28163
|
-
yaml13.dump({ version: 1, resources: manifestResources }, YAML_DUMP_OPTIONS),
|
|
28164
|
-
"utf-8"
|
|
28253
|
+
Buffer.from(yaml13.dump({ version: 1, resources: manifestResources }, YAML_DUMP_OPTIONS), "utf-8")
|
|
28165
28254
|
);
|
|
28166
|
-
const resourcesDir = path32.join(orgDir, "resources");
|
|
28167
28255
|
const currentSlugs = /* @__PURE__ */ new Set();
|
|
28168
28256
|
for (const resource of resources) {
|
|
28169
28257
|
const resSlug = slugify(resource.name);
|
|
28170
28258
|
currentSlugs.add(resSlug);
|
|
28171
28259
|
writeResourceFileTree(path32.join(resourcesDir, resSlug), resource.files || [], orgDir);
|
|
28172
28260
|
}
|
|
28173
|
-
if (
|
|
28174
|
-
for (const entry of
|
|
28261
|
+
if (fs23.existsSync(resourcesDir)) {
|
|
28262
|
+
for (const entry of fs23.readdirSync(resourcesDir, { withFileTypes: true })) {
|
|
28175
28263
|
if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
|
|
28176
|
-
|
|
28264
|
+
fs23.rmSync(path32.join(resourcesDir, entry.name), { recursive: true, force: true });
|
|
28177
28265
|
}
|
|
28178
28266
|
}
|
|
28179
28267
|
}
|
|
@@ -28193,6 +28281,7 @@ var init_org_workspace = __esm({
|
|
|
28193
28281
|
"use strict";
|
|
28194
28282
|
init_utils();
|
|
28195
28283
|
init_layout();
|
|
28284
|
+
init_fs_safety();
|
|
28196
28285
|
init_resource_files();
|
|
28197
28286
|
init_yaml_writer();
|
|
28198
28287
|
ORG_MANIFEST_NAME = "resources.yaml";
|
|
@@ -28478,7 +28567,7 @@ var init_report_edit_args = __esm({
|
|
|
28478
28567
|
});
|
|
28479
28568
|
|
|
28480
28569
|
// src/lib/file-map.ts
|
|
28481
|
-
import * as
|
|
28570
|
+
import * as fs24 from "fs";
|
|
28482
28571
|
import * as path33 from "path";
|
|
28483
28572
|
function isSafeRelPath(rel) {
|
|
28484
28573
|
if (rel.length === 0 || rel.length > 300) return false;
|
|
@@ -28495,8 +28584,8 @@ function writeFileMap(targetDir, files) {
|
|
|
28495
28584
|
throw new Error(`Refusing to write unsafe path: ${rel}`);
|
|
28496
28585
|
}
|
|
28497
28586
|
const abs = path33.join(targetDir, rel);
|
|
28498
|
-
|
|
28499
|
-
|
|
28587
|
+
fs24.mkdirSync(path33.dirname(abs), { recursive: true });
|
|
28588
|
+
fs24.writeFileSync(abs, body, "utf-8");
|
|
28500
28589
|
written.push(rel);
|
|
28501
28590
|
}
|
|
28502
28591
|
return written;
|
|
@@ -28512,7 +28601,7 @@ var admin_exports = {};
|
|
|
28512
28601
|
__export(admin_exports, {
|
|
28513
28602
|
adminCommand: () => adminCommand
|
|
28514
28603
|
});
|
|
28515
|
-
import * as
|
|
28604
|
+
import * as fs25 from "fs";
|
|
28516
28605
|
import * as path34 from "path";
|
|
28517
28606
|
async function adminCommand(args2) {
|
|
28518
28607
|
const [group, ...afterGroup] = args2;
|
|
@@ -28828,7 +28917,7 @@ async function runArchiveRead(positional, flagArgs) {
|
|
|
28828
28917
|
exitOnApiError(err);
|
|
28829
28918
|
throw err;
|
|
28830
28919
|
}
|
|
28831
|
-
|
|
28920
|
+
fs25.writeFileSync(outPath, zip);
|
|
28832
28921
|
console.log(`Wrote ${zip.byteLength} bytes to ${outPath}`);
|
|
28833
28922
|
return;
|
|
28834
28923
|
}
|
|
@@ -28970,7 +29059,7 @@ async function runSkillInstall(positional) {
|
|
|
28970
29059
|
throw err;
|
|
28971
29060
|
}
|
|
28972
29061
|
const root = findGitRoot() ?? process.cwd();
|
|
28973
|
-
const present = HARNESS_SKILL_DIRS.filter((dir) =>
|
|
29062
|
+
const present = HARNESS_SKILL_DIRS.filter((dir) => fs25.existsSync(path34.join(root, dir)));
|
|
28974
29063
|
const targets = present.length > 0 ? present : HARNESS_SKILL_DIRS;
|
|
28975
29064
|
const fileCount = Object.keys(res.files).length;
|
|
28976
29065
|
const relDirs = targets.map((harness) => {
|
|
@@ -30528,7 +30617,7 @@ var init_actions = __esm({
|
|
|
30528
30617
|
|
|
30529
30618
|
// src/data/commands/attachments.ts
|
|
30530
30619
|
import { Command as Command2 } from "commander";
|
|
30531
|
-
import { readFileSync as
|
|
30620
|
+
import { readFileSync as readFileSync18 } from "fs";
|
|
30532
30621
|
function findAttachmentByFilename(attachments, filename) {
|
|
30533
30622
|
return attachments.find((a) => a.key.endsWith(`/${filename}`)) ?? null;
|
|
30534
30623
|
}
|
|
@@ -30569,7 +30658,7 @@ function buildAttachmentsCommand() {
|
|
|
30569
30658
|
printOutput(data, outputFormat(this));
|
|
30570
30659
|
return;
|
|
30571
30660
|
}
|
|
30572
|
-
const body =
|
|
30661
|
+
const body = readFileSync18(opts.file);
|
|
30573
30662
|
await client.upload(uploadPathFrom(data?.upload_url), body, opts.contentType);
|
|
30574
30663
|
printOutput({ ...data, uploaded: true }, outputFormat(this));
|
|
30575
30664
|
});
|
|
@@ -30969,7 +31058,7 @@ var init_import = __esm({
|
|
|
30969
31058
|
|
|
30970
31059
|
// src/data/commands/providers.ts
|
|
30971
31060
|
import { Command as Command5 } from "commander";
|
|
30972
|
-
import { writeFileSync as
|
|
31061
|
+
import { writeFileSync as writeFileSync9 } from "fs";
|
|
30973
31062
|
function providerSegment(provider) {
|
|
30974
31063
|
if (!VALID_PROVIDERS.includes(provider)) {
|
|
30975
31064
|
throw expected(`Unknown provider ${JSON.stringify(provider)}. Expected one of: ${VALID_PROVIDERS_HELP}.`);
|
|
@@ -31002,7 +31091,7 @@ function buildBasesProvidersCommand() {
|
|
|
31002
31091
|
);
|
|
31003
31092
|
if (opts.to) {
|
|
31004
31093
|
try {
|
|
31005
|
-
|
|
31094
|
+
writeFileSync9(opts.to, JSON.stringify(data, null, 2));
|
|
31006
31095
|
} catch (e) {
|
|
31007
31096
|
throw expected(`--to ${opts.to}: ${e instanceof Error ? e.message : "could not be written"}`);
|
|
31008
31097
|
}
|
|
@@ -31049,7 +31138,7 @@ var init_providers = __esm({
|
|
|
31049
31138
|
|
|
31050
31139
|
// src/data/commands/report.ts
|
|
31051
31140
|
import { Command as Command6 } from "commander";
|
|
31052
|
-
import { readFileSync as
|
|
31141
|
+
import { readFileSync as readFileSync19 } from "fs";
|
|
31053
31142
|
import { dirname as dirname12, join as join30 } from "path";
|
|
31054
31143
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
31055
31144
|
function resolveCliVersion() {
|
|
@@ -31058,7 +31147,7 @@ function resolveCliVersion() {
|
|
|
31058
31147
|
join30(here, "..", "..", "..", "package.json")
|
|
31059
31148
|
]) {
|
|
31060
31149
|
try {
|
|
31061
|
-
const version = JSON.parse(
|
|
31150
|
+
const version = JSON.parse(readFileSync19(candidate, "utf-8")).version;
|
|
31062
31151
|
if (typeof version === "string" && version) return version;
|
|
31063
31152
|
} catch {
|
|
31064
31153
|
}
|
|
@@ -31260,7 +31349,7 @@ var init_report2 = __esm({
|
|
|
31260
31349
|
|
|
31261
31350
|
// src/data/commands/credentials.ts
|
|
31262
31351
|
import { Command as Command7 } from "commander";
|
|
31263
|
-
import { readFileSync as
|
|
31352
|
+
import { readFileSync as readFileSync20 } from "fs";
|
|
31264
31353
|
function withValueSourceOptions(cmd, what) {
|
|
31265
31354
|
return cmd.option(
|
|
31266
31355
|
"--file <path>",
|
|
@@ -31273,7 +31362,7 @@ async function resolveValue(opts, label) {
|
|
|
31273
31362
|
throw expected("--file cannot be combined with --value-stdin or --value-prompt \u2014 pass one.");
|
|
31274
31363
|
}
|
|
31275
31364
|
try {
|
|
31276
|
-
return
|
|
31365
|
+
return readFileSync20(opts.file).toString("base64");
|
|
31277
31366
|
} catch (e) {
|
|
31278
31367
|
throw expected(`--file ${opts.file}: ${e instanceof Error ? e.message : "could not be read"}`);
|
|
31279
31368
|
}
|
|
@@ -31422,7 +31511,7 @@ var init_credentials = __esm({
|
|
|
31422
31511
|
|
|
31423
31512
|
// src/data/commands/sql.ts
|
|
31424
31513
|
import { Command as Command8 } from "commander";
|
|
31425
|
-
import { readFileSync as
|
|
31514
|
+
import { readFileSync as readFileSync21 } from "fs";
|
|
31426
31515
|
function buildBasesSqlCommand() {
|
|
31427
31516
|
return withBaseOption(new Command8("sql")).description("Execute a read-only SQL query against base data").argument("[query]", "SQL query (SELECT only)").option("--file <path>", "Read SQL from a file instead of the argument").option(
|
|
31428
31517
|
"--param <kv...>",
|
|
@@ -31432,7 +31521,7 @@ function buildBasesSqlCommand() {
|
|
|
31432
31521
|
let query;
|
|
31433
31522
|
if (opts.file) {
|
|
31434
31523
|
try {
|
|
31435
|
-
query =
|
|
31524
|
+
query = readFileSync21(opts.file, "utf-8").trim();
|
|
31436
31525
|
} catch (e) {
|
|
31437
31526
|
throw expected(`--file ${opts.file}: ${e instanceof Error ? e.message : "could not be read"}`);
|
|
31438
31527
|
}
|
|
@@ -32087,8 +32176,8 @@ var init_file_types = __esm({
|
|
|
32087
32176
|
|
|
32088
32177
|
// src/data/commands/files.ts
|
|
32089
32178
|
import { Command as Command12 } from "commander";
|
|
32090
|
-
import { readFileSync as
|
|
32091
|
-
import { basename as
|
|
32179
|
+
import { readFileSync as readFileSync22, writeFileSync as writeFileSync10 } from "fs";
|
|
32180
|
+
import { basename as basename19 } from "path";
|
|
32092
32181
|
function renderFileDiff(fileType, filePath, from, to, d) {
|
|
32093
32182
|
console.log(sanitizeTerminalText(`${fileType}/${filePath}: v${from} \u2192 v${to}`));
|
|
32094
32183
|
const md = d.metadata_delta;
|
|
@@ -32120,7 +32209,7 @@ function renderFileDiff(fileType, filePath, from, to, d) {
|
|
|
32120
32209
|
}
|
|
32121
32210
|
function downloadTarget(remotePath, to) {
|
|
32122
32211
|
if (to) return to;
|
|
32123
|
-
const derived =
|
|
32212
|
+
const derived = basename19(remotePath);
|
|
32124
32213
|
if (derived === "" || derived === "." || derived === "..") {
|
|
32125
32214
|
throw expected(
|
|
32126
32215
|
`Cannot derive a local filename from "${remotePath}" \u2014 pass --to <local> to name it.`
|
|
@@ -32136,7 +32225,7 @@ function buildFilesCommand() {
|
|
|
32136
32225
|
"Upload a local file to a path (e.g. wayai files put reports q3/summary.pdf --file ./summary.pdf)"
|
|
32137
32226
|
).requiredOption("--file <local>", "Local file to upload").option("--content-type <type>", "MIME type", "application/octet-stream").action(async function(fileType, filePath, opts) {
|
|
32138
32227
|
const base = pathSegment(requireBase(this), "--base");
|
|
32139
|
-
const body =
|
|
32228
|
+
const body = readFileSync22(opts.file);
|
|
32140
32229
|
const client = await createDataClient();
|
|
32141
32230
|
printOutput(
|
|
32142
32231
|
await client.upload(
|
|
@@ -32167,7 +32256,7 @@ function buildFilesCommand() {
|
|
|
32167
32256
|
const { bytes } = await client.download(
|
|
32168
32257
|
`/v1/${base}/files/${pathSegment(fileType, "file_type")}/${encoded}${versionQs ? `?${versionQs}` : ""}`
|
|
32169
32258
|
);
|
|
32170
|
-
|
|
32259
|
+
writeFileSync10(out, bytes);
|
|
32171
32260
|
console.log(`Downloaded to ${out}`);
|
|
32172
32261
|
});
|
|
32173
32262
|
files.command("history <file_type> <path>").description("List the content versions of a file (newest first)").option("--limit <n>", "Max versions to return").option("--offset <n>", "Pagination offset").action(async function(fileType, filePath, opts) {
|
|
@@ -33185,7 +33274,7 @@ init_errors2();
|
|
|
33185
33274
|
init_mask_secrets();
|
|
33186
33275
|
init_utils();
|
|
33187
33276
|
init_registry();
|
|
33188
|
-
import { readFileSync as
|
|
33277
|
+
import { readFileSync as readFileSync23 } from "fs";
|
|
33189
33278
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
33190
33279
|
import { dirname as dirname13, join as join31 } from "path";
|
|
33191
33280
|
|
|
@@ -33343,7 +33432,7 @@ Run \`wayai admin skill install\` to update.`);
|
|
|
33343
33432
|
|
|
33344
33433
|
// src/index.ts
|
|
33345
33434
|
var __dirname = dirname13(fileURLToPath3(import.meta.url));
|
|
33346
|
-
var pkg = JSON.parse(
|
|
33435
|
+
var pkg = JSON.parse(readFileSync23(join31(__dirname, "..", "package.json"), "utf-8"));
|
|
33347
33436
|
var [, , command, ...args] = process.argv;
|
|
33348
33437
|
var isBackgroundRefresh = command === REFRESH_COMMAND;
|
|
33349
33438
|
if (!isBackgroundRefresh) initSentry(command, pkg.version);
|