@wayai/cli 0.3.151 → 0.3.152
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 +581 -339
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8942,7 +8942,7 @@ var init_api_client = __esm({
|
|
|
8942
8942
|
init_sentry();
|
|
8943
8943
|
init_mask_secrets();
|
|
8944
8944
|
RETRYABLE_BACKOFF_MS = [500, 1e3, 2e3];
|
|
8945
|
-
delay = (ms) => new Promise((
|
|
8945
|
+
delay = (ms) => new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
8946
8946
|
ApiError = class extends Error {
|
|
8947
8947
|
status;
|
|
8948
8948
|
body;
|
|
@@ -9607,7 +9607,7 @@ var init_api_client = __esm({
|
|
|
9607
9607
|
* `dataErrorMessage` recovers the envelope's own message for display.
|
|
9608
9608
|
*
|
|
9609
9609
|
* `orgId` is the caller's org SELECTOR (the `--org` flag, else the repo's
|
|
9610
|
-
*
|
|
9610
|
+
* `wayai-ws/wayai.yaml`), not an authorization claim: the backend validates it against
|
|
9611
9611
|
* the caller's grants and attests only the validated result. A multi-org user
|
|
9612
9612
|
* needs it to pick; a single-org user can omit it.
|
|
9613
9613
|
*
|
|
@@ -14516,34 +14516,15 @@ function resolveLayout(gitRoot, layout = WAYAI_LAYOUT) {
|
|
|
14516
14516
|
const newWs = path.join(gitRoot, layout.wsDir);
|
|
14517
14517
|
const legacyWs = path.join(gitRoot, layout.legacy.wsDir);
|
|
14518
14518
|
const legacyOrg = path.join(gitRoot, layout.legacy.orgAtRoot);
|
|
14519
|
-
const newExists = isDirectory(newWs);
|
|
14520
14519
|
const legacyExists = isDirectory(legacyWs) || isDirectory(legacyOrg);
|
|
14521
14520
|
const basesDir = path.join(newWs, layout.basesSubdir);
|
|
14522
|
-
|
|
14523
|
-
|
|
14524
|
-
|
|
14525
|
-
|
|
14526
|
-
|
|
14527
|
-
isLegacy: false,
|
|
14528
|
-
legacyAlsoPresent: legacyExists
|
|
14529
|
-
};
|
|
14530
|
-
}
|
|
14531
|
-
if (legacyExists) {
|
|
14532
|
-
return {
|
|
14533
|
-
hubsDir: legacyWs,
|
|
14534
|
-
orgDir: legacyOrg,
|
|
14535
|
-
basesDir,
|
|
14536
|
-
isLegacy: true,
|
|
14537
|
-
legacyAlsoPresent: false
|
|
14538
|
-
};
|
|
14521
|
+
const hubsDir = path.join(newWs, layout.hubsSubdir);
|
|
14522
|
+
const orgDir = path.join(newWs, layout.orgSubdir);
|
|
14523
|
+
const newDisplacesLegacy = () => isDirectory(hubsDir) || isDirectory(orgDir) || isDirectory(basesDir);
|
|
14524
|
+
if (legacyExists && !newDisplacesLegacy()) {
|
|
14525
|
+
return { hubsDir: legacyWs, orgDir: legacyOrg, basesDir, isLegacy: true, legacyAlsoPresent: false };
|
|
14539
14526
|
}
|
|
14540
|
-
return {
|
|
14541
|
-
hubsDir: path.join(newWs, layout.hubsSubdir),
|
|
14542
|
-
orgDir: path.join(newWs, layout.orgSubdir),
|
|
14543
|
-
basesDir,
|
|
14544
|
-
isLegacy: false,
|
|
14545
|
-
legacyAlsoPresent: false
|
|
14546
|
-
};
|
|
14527
|
+
return { hubsDir, orgDir, basesDir, isLegacy: false, legacyAlsoPresent: legacyExists };
|
|
14547
14528
|
}
|
|
14548
14529
|
function resolveBasesDir(gitRoot) {
|
|
14549
14530
|
return resolveLayout(gitRoot).basesDir;
|
|
@@ -14960,111 +14941,344 @@ var init_workspace = __esm({
|
|
|
14960
14941
|
}
|
|
14961
14942
|
});
|
|
14962
14943
|
|
|
14944
|
+
// src/lib/workspace-manifest.ts
|
|
14945
|
+
import * as fs3 from "fs";
|
|
14946
|
+
import * as path3 from "path";
|
|
14947
|
+
import * as yaml2 from "js-yaml";
|
|
14948
|
+
function workspaceManifestPath(gitRoot) {
|
|
14949
|
+
return path3.join(gitRoot, WAYAI_LAYOUT.wsDir, WORKSPACE_MANIFEST_FILE);
|
|
14950
|
+
}
|
|
14951
|
+
function rootConfigPath(gitRoot) {
|
|
14952
|
+
return path3.join(gitRoot, ROOT_CONFIG_FILE);
|
|
14953
|
+
}
|
|
14954
|
+
function loadYamlMapping(file) {
|
|
14955
|
+
let raw;
|
|
14956
|
+
try {
|
|
14957
|
+
raw = fs3.readFileSync(file, "utf-8");
|
|
14958
|
+
} catch (err) {
|
|
14959
|
+
if (err.code === "ENOENT") return { kind: "absent" };
|
|
14960
|
+
return { kind: "malformed", reason: err instanceof Error ? err.message : String(err) };
|
|
14961
|
+
}
|
|
14962
|
+
let doc;
|
|
14963
|
+
try {
|
|
14964
|
+
doc = yaml2.load(raw);
|
|
14965
|
+
} catch (err) {
|
|
14966
|
+
return { kind: "malformed", reason: err instanceof Error ? err.message : String(err) };
|
|
14967
|
+
}
|
|
14968
|
+
if (doc === void 0 || doc === null) return { kind: "ok", doc: {} };
|
|
14969
|
+
if (typeof doc !== "object" || Array.isArray(doc)) {
|
|
14970
|
+
return { kind: "malformed", reason: "expected a YAML mapping of settings" };
|
|
14971
|
+
}
|
|
14972
|
+
return { kind: "ok", doc };
|
|
14973
|
+
}
|
|
14974
|
+
function loadWorkspaceManifest(gitRoot) {
|
|
14975
|
+
return loadYamlMapping(workspaceManifestPath(gitRoot));
|
|
14976
|
+
}
|
|
14977
|
+
var WORKSPACE_MANIFEST_FILE, WORKSPACE_MANIFEST_LABEL, ROOT_CONFIG_FILE;
|
|
14978
|
+
var init_workspace_manifest = __esm({
|
|
14979
|
+
"src/lib/workspace-manifest.ts"() {
|
|
14980
|
+
"use strict";
|
|
14981
|
+
init_layout();
|
|
14982
|
+
WORKSPACE_MANIFEST_FILE = "wayai.yaml";
|
|
14983
|
+
WORKSPACE_MANIFEST_LABEL = `${WAYAI_LAYOUT.wsDir}/${WORKSPACE_MANIFEST_FILE}`;
|
|
14984
|
+
ROOT_CONFIG_FILE = ".wayai.yaml";
|
|
14985
|
+
}
|
|
14986
|
+
});
|
|
14987
|
+
|
|
14963
14988
|
// src/lib/repo-config.ts
|
|
14964
14989
|
var repo_config_exports = {};
|
|
14965
14990
|
__export(repo_config_exports, {
|
|
14991
|
+
_resetRepoConfigNotices: () => _resetRepoConfigNotices,
|
|
14992
|
+
planOrgMigration: () => planOrgMigration,
|
|
14966
14993
|
readRepoConfig: () => readRepoConfig,
|
|
14994
|
+
readRepoConfigUnlessBlocked: () => readRepoConfigUnlessBlocked,
|
|
14995
|
+
readRepoScopeBlocker: () => readRepoScopeBlocker,
|
|
14967
14996
|
requireRepoConfig: () => requireRepoConfig,
|
|
14997
|
+
resolveRepoConfig: () => resolveRepoConfig,
|
|
14968
14998
|
writeRepoConfig: () => writeRepoConfig
|
|
14969
14999
|
});
|
|
14970
|
-
import * as
|
|
14971
|
-
import * as
|
|
14972
|
-
import * as
|
|
14973
|
-
function
|
|
14974
|
-
if (
|
|
14975
|
-
|
|
14976
|
-
|
|
14977
|
-
|
|
14978
|
-
|
|
15000
|
+
import * as fs4 from "fs";
|
|
15001
|
+
import * as path4 from "path";
|
|
15002
|
+
import * as yaml3 from "js-yaml";
|
|
15003
|
+
function noticeOnce(key, emit) {
|
|
15004
|
+
if (noticed.has(key)) return;
|
|
15005
|
+
noticed.add(key);
|
|
15006
|
+
emit();
|
|
15007
|
+
}
|
|
15008
|
+
function _resetRepoConfigNotices() {
|
|
15009
|
+
noticed.clear();
|
|
15010
|
+
}
|
|
15011
|
+
function readOrgFields(doc) {
|
|
15012
|
+
const raw = doc.organization_id;
|
|
15013
|
+
if (raw === void 0 || raw === null) {
|
|
15014
|
+
if (typeof doc.organization === "string") {
|
|
15015
|
+
return {
|
|
15016
|
+
kind: "invalid",
|
|
15017
|
+
detail: "it uses the old format (organization: <name>) \u2014 replace it with organization_id: <uuid>"
|
|
15018
|
+
};
|
|
15019
|
+
}
|
|
15020
|
+
return { kind: "none" };
|
|
15021
|
+
}
|
|
15022
|
+
if (typeof raw !== "string" || !UUID_RE2.test(raw.trim())) {
|
|
15023
|
+
return { kind: "invalid", detail: "organization_id must be a UUID" };
|
|
15024
|
+
}
|
|
15025
|
+
const name = typeof doc.organization_name === "string" && doc.organization_name.trim() ? doc.organization_name.trim() : void 0;
|
|
15026
|
+
const config = { organization_id: raw.trim() };
|
|
15027
|
+
if (name) config.organization_name = name;
|
|
15028
|
+
return { kind: "declared", config };
|
|
15029
|
+
}
|
|
15030
|
+
function declarationFrom(load11) {
|
|
15031
|
+
if (load11.kind === "absent") return { kind: "none" };
|
|
15032
|
+
if (load11.kind === "malformed") return { kind: "invalid", detail: `it does not parse (${load11.reason})` };
|
|
15033
|
+
return readOrgFields(load11.doc);
|
|
15034
|
+
}
|
|
15035
|
+
function legacyFieldsIn(load11) {
|
|
15036
|
+
if (load11.kind !== "ok") return [];
|
|
15037
|
+
return LEGACY_FIELDS.filter((f) => load11.doc[f] !== void 0);
|
|
15038
|
+
}
|
|
15039
|
+
function resolve2(gitRoot) {
|
|
15040
|
+
const manifestFile = workspaceManifestPath(gitRoot);
|
|
15041
|
+
const manifest = declarationFrom(loadWorkspaceManifest(gitRoot));
|
|
15042
|
+
if (manifest.kind === "invalid") {
|
|
15043
|
+
return { kind: "invalid", source: "manifest", file: manifestFile, detail: manifest.detail };
|
|
15044
|
+
}
|
|
15045
|
+
const rootFile = rootConfigPath(gitRoot);
|
|
15046
|
+
const rootLoad = loadYamlMapping(rootFile);
|
|
15047
|
+
const root = declarationFrom(rootLoad);
|
|
15048
|
+
if (manifest.kind === "declared") {
|
|
15049
|
+
if (root.kind === "declared" && root.config.organization_id !== manifest.config.organization_id) {
|
|
15050
|
+
return {
|
|
15051
|
+
kind: "conflict",
|
|
15052
|
+
manifestOrg: manifest.config.organization_id,
|
|
15053
|
+
rootOrg: root.config.organization_id
|
|
15054
|
+
};
|
|
15055
|
+
}
|
|
15056
|
+
return {
|
|
15057
|
+
kind: "ok",
|
|
15058
|
+
resolved: { config: manifest.config, source: "manifest", path: manifestFile },
|
|
15059
|
+
legacyRootFields: []
|
|
15060
|
+
};
|
|
15061
|
+
}
|
|
15062
|
+
if (root.kind === "declared") {
|
|
15063
|
+
return {
|
|
15064
|
+
kind: "ok",
|
|
15065
|
+
resolved: { config: root.config, source: "root", path: rootFile },
|
|
15066
|
+
legacyRootFields: legacyFieldsIn(rootLoad)
|
|
15067
|
+
};
|
|
15068
|
+
}
|
|
15069
|
+
if (root.kind === "invalid") {
|
|
15070
|
+
return { kind: "invalid", source: "root", file: rootFile, detail: root.detail };
|
|
15071
|
+
}
|
|
15072
|
+
return { kind: "none" };
|
|
15073
|
+
}
|
|
15074
|
+
function conflictMessage(manifestOrg, rootOrg, remedy = RECONCILE_REMEDY) {
|
|
15075
|
+
return [
|
|
15076
|
+
"Refusing to guess the organization: two files in this repo name different ones.",
|
|
15077
|
+
` ${WORKSPACE_MANIFEST_LABEL} -> ${manifestOrg} (the workspace manifest)`,
|
|
15078
|
+
` ${ROOT_CONFIG_FILE} -> ${rootOrg} (deprecated fallback)`,
|
|
15079
|
+
"",
|
|
15080
|
+
...remedy
|
|
15081
|
+
].join("\n");
|
|
15082
|
+
}
|
|
15083
|
+
function rebindRefusal(requestedOrg, rootOrg) {
|
|
15084
|
+
return [
|
|
15085
|
+
`Refusing to re-bind the organization: ${ROOT_CONFIG_FILE} still names a different one, and it is read as a fallback.`,
|
|
15086
|
+
` requested -> ${requestedOrg}`,
|
|
15087
|
+
` ${ROOT_CONFIG_FILE} -> ${rootOrg} (deprecated fallback)`,
|
|
15088
|
+
"",
|
|
15089
|
+
`Delete ${ROOT_CONFIG_FILE} (or set its organization_id to ${requestedOrg}), then re-run.`,
|
|
15090
|
+
"Nothing was written \u2014 this repo still resolves to the organization it had."
|
|
15091
|
+
].join("\n");
|
|
15092
|
+
}
|
|
15093
|
+
function invalidMessage(file, detail) {
|
|
15094
|
+
return [
|
|
15095
|
+
`Invalid organization binding in ${file}: ${detail}.`,
|
|
15096
|
+
"",
|
|
15097
|
+
" organization_id: <your-org-uuid>",
|
|
15098
|
+
"",
|
|
15099
|
+
"Run `wayai init` to set up the workspace."
|
|
15100
|
+
].join("\n");
|
|
15101
|
+
}
|
|
15102
|
+
function missingMessage() {
|
|
15103
|
+
return [
|
|
15104
|
+
"This repository is not scoped to an organization.",
|
|
15105
|
+
`Declare it in ${WORKSPACE_MANIFEST_LABEL}:`,
|
|
15106
|
+
"",
|
|
15107
|
+
" organization_id: <your-org-uuid>",
|
|
15108
|
+
"",
|
|
15109
|
+
"Run `wayai init` to set up the workspace."
|
|
15110
|
+
].join("\n");
|
|
15111
|
+
}
|
|
15112
|
+
function report(r, posture) {
|
|
15113
|
+
switch (r.kind) {
|
|
15114
|
+
case "ok":
|
|
15115
|
+
if (r.resolved.source !== "root") return;
|
|
15116
|
+
noticeOnce(
|
|
15117
|
+
"root-fallback",
|
|
15118
|
+
() => console.warn(
|
|
15119
|
+
`Note: this repo's organization binding is still in ${ROOT_CONFIG_FILE} at the repository root. It belongs in the workspace manifest ${WORKSPACE_MANIFEST_LABEL} \u2014 run \`wayai migrate\` to copy it there.`
|
|
15120
|
+
)
|
|
15121
|
+
);
|
|
15122
|
+
if (r.legacyRootFields.length > 0) {
|
|
15123
|
+
noticeOnce(
|
|
15124
|
+
"legacy-fields",
|
|
15125
|
+
() => console.warn(
|
|
15126
|
+
`Note: ${ROOT_CONFIG_FILE} contains deprecated field(s) ${r.legacyRootFields.join(", ")}. These are ignored \u2014 only organization_id is used now. You can remove them.`
|
|
15127
|
+
)
|
|
15128
|
+
);
|
|
15129
|
+
}
|
|
15130
|
+
return;
|
|
15131
|
+
case "invalid": {
|
|
15132
|
+
const emit = () => console.error(invalidMessage(r.file, r.detail));
|
|
15133
|
+
if (posture === "hard") emit();
|
|
15134
|
+
else noticeOnce(`invalid:${r.source}`, emit);
|
|
15135
|
+
return;
|
|
15136
|
+
}
|
|
15137
|
+
case "conflict":
|
|
15138
|
+
console.error(conflictMessage(r.manifestOrg, r.rootOrg));
|
|
15139
|
+
return;
|
|
15140
|
+
case "none":
|
|
15141
|
+
if (posture === "hard") console.error(missingMessage());
|
|
15142
|
+
return;
|
|
15143
|
+
}
|
|
15144
|
+
}
|
|
15145
|
+
function resolveRepoConfig(root) {
|
|
15146
|
+
const gitRoot = root ?? findGitRoot();
|
|
15147
|
+
if (!gitRoot) return null;
|
|
15148
|
+
const r = resolve2(gitRoot);
|
|
15149
|
+
report(r, "soft");
|
|
15150
|
+
return r.kind === "ok" ? r.resolved : null;
|
|
14979
15151
|
}
|
|
14980
15152
|
function readRepoConfig(root) {
|
|
15153
|
+
return resolveRepoConfig(root)?.config ?? null;
|
|
15154
|
+
}
|
|
15155
|
+
function readRepoConfigUnlessBlocked(root) {
|
|
14981
15156
|
const gitRoot = root ?? findGitRoot();
|
|
14982
15157
|
if (!gitRoot) return null;
|
|
14983
|
-
const
|
|
14984
|
-
|
|
14985
|
-
|
|
14986
|
-
|
|
14987
|
-
|
|
14988
|
-
|
|
14989
|
-
if (config?.organization && typeof config.organization === "string") {
|
|
14990
|
-
console.error(
|
|
14991
|
-
".wayai.yaml uses the old format (organization: name). Replace it with organization_id: <uuid>."
|
|
14992
|
-
);
|
|
14993
|
-
}
|
|
15158
|
+
const r = resolve2(gitRoot);
|
|
15159
|
+
switch (r.kind) {
|
|
15160
|
+
case "ok":
|
|
15161
|
+
report(r, "soft");
|
|
15162
|
+
return r.resolved.config;
|
|
15163
|
+
case "none":
|
|
14994
15164
|
return null;
|
|
14995
|
-
|
|
14996
|
-
|
|
14997
|
-
|
|
14998
|
-
|
|
14999
|
-
|
|
15165
|
+
case "conflict":
|
|
15166
|
+
throw expected(conflictMessage(r.manifestOrg, r.rootOrg));
|
|
15167
|
+
case "invalid":
|
|
15168
|
+
throw expected(invalidMessage(r.file, r.detail));
|
|
15169
|
+
}
|
|
15170
|
+
}
|
|
15171
|
+
function requireRepoConfig(root) {
|
|
15172
|
+
const gitRoot = root ?? findGitRoot();
|
|
15173
|
+
const r = gitRoot ? resolve2(gitRoot) : { kind: "none" };
|
|
15174
|
+
report(r, "hard");
|
|
15175
|
+
if (r.kind === "ok") return r.resolved.config;
|
|
15176
|
+
return process.exit(1);
|
|
15177
|
+
}
|
|
15178
|
+
function readRepoScopeBlocker(root) {
|
|
15179
|
+
const gitRoot = root ?? findGitRoot();
|
|
15180
|
+
if (!gitRoot) return null;
|
|
15181
|
+
const r = resolve2(gitRoot);
|
|
15182
|
+
if (r.kind === "conflict") {
|
|
15000
15183
|
return {
|
|
15001
|
-
|
|
15002
|
-
|
|
15184
|
+
kind: "conflict",
|
|
15185
|
+
manifest_organization_id: r.manifestOrg,
|
|
15186
|
+
root_organization_id: r.rootOrg
|
|
15003
15187
|
};
|
|
15004
|
-
} catch {
|
|
15005
|
-
return null;
|
|
15006
15188
|
}
|
|
15189
|
+
if (r.kind === "invalid") return { kind: "invalid", path: r.file, detail: r.detail };
|
|
15190
|
+
return null;
|
|
15007
15191
|
}
|
|
15008
|
-
function
|
|
15009
|
-
const
|
|
15010
|
-
|
|
15011
|
-
|
|
15012
|
-
|
|
15013
|
-
|
|
15014
|
-
|
|
15015
|
-
|
|
15016
|
-
|
|
15017
|
-
|
|
15192
|
+
function planOrgMigration(gitRoot) {
|
|
15193
|
+
const manifest = declarationFrom(loadWorkspaceManifest(gitRoot));
|
|
15194
|
+
const root = declarationFrom(loadYamlMapping(rootConfigPath(gitRoot)));
|
|
15195
|
+
if (root.kind !== "declared") return { kind: "nothing" };
|
|
15196
|
+
if (manifest.kind === "declared") {
|
|
15197
|
+
if (manifest.config.organization_id === root.config.organization_id) return { kind: "nothing" };
|
|
15198
|
+
return {
|
|
15199
|
+
kind: "refuse",
|
|
15200
|
+
message: conflictMessage(manifest.config.organization_id, root.config.organization_id, [
|
|
15201
|
+
"Reconcile them by hand \u2014 migrate cannot know which one you meant."
|
|
15202
|
+
])
|
|
15203
|
+
};
|
|
15204
|
+
}
|
|
15205
|
+
if (manifest.kind === "invalid") {
|
|
15206
|
+
return {
|
|
15207
|
+
kind: "refuse",
|
|
15208
|
+
message: `Cannot copy the organization binding: ${WORKSPACE_MANIFEST_LABEL} is unusable \u2014 ${manifest.detail}. Fix or delete it, then re-run \`wayai migrate\`.`
|
|
15209
|
+
};
|
|
15018
15210
|
}
|
|
15019
|
-
return config;
|
|
15211
|
+
return { kind: "copy", config: root.config };
|
|
15020
15212
|
}
|
|
15021
15213
|
function writeRepoConfig(config, root) {
|
|
15022
15214
|
const gitRoot = root ?? findGitRoot();
|
|
15023
15215
|
if (!gitRoot) {
|
|
15024
15216
|
throw new Error("Not inside a git repository. Run `git init` first.");
|
|
15025
15217
|
}
|
|
15026
|
-
const
|
|
15218
|
+
const stale = declarationFrom(loadYamlMapping(rootConfigPath(gitRoot)));
|
|
15219
|
+
if (stale.kind === "declared" && stale.config.organization_id !== config.organization_id) {
|
|
15220
|
+
throw expected(rebindRefusal(config.organization_id, stale.config.organization_id));
|
|
15221
|
+
}
|
|
15222
|
+
const load11 = loadWorkspaceManifest(gitRoot);
|
|
15223
|
+
if (load11.kind === "malformed") {
|
|
15224
|
+
throw expected(
|
|
15225
|
+
`Cannot write the organization binding: ${WORKSPACE_MANIFEST_LABEL} does not parse (${load11.reason}). Fix or delete it, then re-run.`
|
|
15226
|
+
);
|
|
15227
|
+
}
|
|
15228
|
+
const { organization_id: _id, organization_name: _name, ...rest } = load11.kind === "ok" ? load11.doc : {};
|
|
15027
15229
|
const doc = { organization_id: config.organization_id };
|
|
15028
15230
|
if (config.organization_name?.trim()) doc.organization_name = config.organization_name.trim();
|
|
15029
|
-
|
|
15030
|
-
|
|
15031
|
-
|
|
15231
|
+
Object.assign(doc, rest);
|
|
15232
|
+
const file = workspaceManifestPath(gitRoot);
|
|
15233
|
+
fs4.mkdirSync(path4.dirname(file), { recursive: true });
|
|
15234
|
+
fs4.writeFileSync(
|
|
15235
|
+
file,
|
|
15236
|
+
yaml3.dump(doc, { lineWidth: -1, quotingType: '"', forceQuotes: false }),
|
|
15237
|
+
"utf-8"
|
|
15238
|
+
);
|
|
15239
|
+
return file;
|
|
15032
15240
|
}
|
|
15033
|
-
var LEGACY_FIELDS,
|
|
15241
|
+
var LEGACY_FIELDS, noticed, RECONCILE_REMEDY;
|
|
15034
15242
|
var init_repo_config = __esm({
|
|
15035
15243
|
"src/lib/repo-config.ts"() {
|
|
15036
15244
|
"use strict";
|
|
15245
|
+
init_expected();
|
|
15037
15246
|
init_workspace();
|
|
15038
15247
|
init_utils();
|
|
15248
|
+
init_workspace_manifest();
|
|
15039
15249
|
LEGACY_FIELDS = ["project_id", "project_name", "hub_id", "hub_name"];
|
|
15040
|
-
|
|
15250
|
+
noticed = /* @__PURE__ */ new Set();
|
|
15251
|
+
RECONCILE_REMEDY = [
|
|
15252
|
+
"Keep the organization_id you actually work in and delete the other declaration.",
|
|
15253
|
+
`\`wayai init\` rewrites ${WORKSPACE_MANIFEST_LABEL}; the root file is yours to remove.`
|
|
15254
|
+
];
|
|
15041
15255
|
}
|
|
15042
15256
|
});
|
|
15043
15257
|
|
|
15044
15258
|
// src/lib/utils.ts
|
|
15045
|
-
import * as
|
|
15046
|
-
import * as
|
|
15259
|
+
import * as fs5 from "fs";
|
|
15260
|
+
import * as path5 from "path";
|
|
15047
15261
|
import * as readline from "readline";
|
|
15048
15262
|
function prompt(question) {
|
|
15049
15263
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
15050
|
-
return new Promise((
|
|
15264
|
+
return new Promise((resolve8) => {
|
|
15051
15265
|
rl.question(question, (answer) => {
|
|
15052
15266
|
rl.close();
|
|
15053
|
-
|
|
15267
|
+
resolve8(answer.trim());
|
|
15054
15268
|
});
|
|
15055
15269
|
});
|
|
15056
15270
|
}
|
|
15057
15271
|
function confirm(question) {
|
|
15058
15272
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
15059
|
-
return new Promise((
|
|
15273
|
+
return new Promise((resolve8) => {
|
|
15060
15274
|
rl.question(`${question} [y/N]: `, (answer) => {
|
|
15061
15275
|
rl.close();
|
|
15062
|
-
|
|
15276
|
+
resolve8(answer.trim().toLowerCase() === "y");
|
|
15063
15277
|
});
|
|
15064
15278
|
});
|
|
15065
15279
|
}
|
|
15066
15280
|
function promptSecret(question) {
|
|
15067
|
-
return new Promise((
|
|
15281
|
+
return new Promise((resolve8) => {
|
|
15068
15282
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
15069
15283
|
const originalWrite = rl._writeToOutput;
|
|
15070
15284
|
let firstWrite = true;
|
|
@@ -15080,25 +15294,25 @@ function promptSecret(question) {
|
|
|
15080
15294
|
rl._writeToOutput = originalWrite;
|
|
15081
15295
|
process.stdout.write("\n");
|
|
15082
15296
|
rl.close();
|
|
15083
|
-
|
|
15297
|
+
resolve8(answer);
|
|
15084
15298
|
});
|
|
15085
15299
|
});
|
|
15086
15300
|
}
|
|
15087
15301
|
function readStdin() {
|
|
15088
|
-
return new Promise((
|
|
15302
|
+
return new Promise((resolve8, reject) => {
|
|
15089
15303
|
let data = "";
|
|
15090
15304
|
process.stdin.setEncoding("utf-8");
|
|
15091
15305
|
process.stdin.on("data", (chunk) => {
|
|
15092
15306
|
data += chunk;
|
|
15093
15307
|
});
|
|
15094
|
-
process.stdin.on("end", () =>
|
|
15308
|
+
process.stdin.on("end", () => resolve8(data.trim()));
|
|
15095
15309
|
process.stdin.on("error", reject);
|
|
15096
15310
|
});
|
|
15097
15311
|
}
|
|
15098
15312
|
function resolveHubYamlPath(hubFolder) {
|
|
15099
15313
|
for (const filename of ["hub.yaml", "wayai.yaml"]) {
|
|
15100
|
-
const yamlPath =
|
|
15101
|
-
if (
|
|
15314
|
+
const yamlPath = path5.join(hubFolder, filename);
|
|
15315
|
+
if (fs5.existsSync(yamlPath)) return yamlPath;
|
|
15102
15316
|
}
|
|
15103
15317
|
return null;
|
|
15104
15318
|
}
|
|
@@ -15175,8 +15389,8 @@ async function resolveOrganizationId(client, orgIdFlag) {
|
|
|
15175
15389
|
}
|
|
15176
15390
|
return { organizationId: orgIdFlag };
|
|
15177
15391
|
}
|
|
15178
|
-
const {
|
|
15179
|
-
const repoConfig =
|
|
15392
|
+
const { readRepoConfigUnlessBlocked: readRepoConfigUnlessBlocked2 } = await Promise.resolve().then(() => (init_repo_config(), repo_config_exports));
|
|
15393
|
+
const repoConfig = readRepoConfigUnlessBlocked2();
|
|
15180
15394
|
if (repoConfig) {
|
|
15181
15395
|
return { organizationId: repoConfig.organization_id, organizationName: repoConfig.organization_name };
|
|
15182
15396
|
}
|
|
@@ -15312,7 +15526,7 @@ var init_registry = __esm({
|
|
|
15312
15526
|
surviving: null,
|
|
15313
15527
|
clause: 1,
|
|
15314
15528
|
shipped: true,
|
|
15315
|
-
reason: "One
|
|
15529
|
+
reason: "One org binding per repo (`wayai-ws/wayai.yaml`), so one `init`."
|
|
15316
15530
|
},
|
|
15317
15531
|
{
|
|
15318
15532
|
original: "update",
|
|
@@ -15563,8 +15777,8 @@ var init_registry = __esm({
|
|
|
15563
15777
|
});
|
|
15564
15778
|
|
|
15565
15779
|
// src/lib/version-cache.ts
|
|
15566
|
-
import { existsSync as
|
|
15567
|
-
import { dirname as
|
|
15780
|
+
import { existsSync as existsSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
15781
|
+
import { dirname as dirname4, join as join6 } from "path";
|
|
15568
15782
|
import { homedir as homedir2 } from "os";
|
|
15569
15783
|
function getVersionCachePath(filename = CLI_CACHE_FILE) {
|
|
15570
15784
|
return join6(homedir2(), ".wayai", filename);
|
|
@@ -15572,7 +15786,7 @@ function getVersionCachePath(filename = CLI_CACHE_FILE) {
|
|
|
15572
15786
|
function readVersionCache(filename = CLI_CACHE_FILE) {
|
|
15573
15787
|
try {
|
|
15574
15788
|
const path35 = getVersionCachePath(filename);
|
|
15575
|
-
if (!
|
|
15789
|
+
if (!existsSync3(path35)) return null;
|
|
15576
15790
|
const parsed = JSON.parse(readFileSync5(path35, "utf-8"));
|
|
15577
15791
|
if (typeof parsed.lastCheck !== "number") return null;
|
|
15578
15792
|
if (parsed.latest !== null && typeof parsed.latest !== "string") return null;
|
|
@@ -15594,8 +15808,8 @@ function isVersionCacheStale(filename = CLI_CACHE_FILE, maxAgeMs = MAX_AGE_24H_M
|
|
|
15594
15808
|
}
|
|
15595
15809
|
function writeVersionCache(filename, cache) {
|
|
15596
15810
|
const path35 = getVersionCachePath(filename);
|
|
15597
|
-
const dir =
|
|
15598
|
-
if (!
|
|
15811
|
+
const dir = dirname4(path35);
|
|
15812
|
+
if (!existsSync3(dir)) mkdirSync2(dir, { recursive: true });
|
|
15599
15813
|
writeFileSync2(path35, JSON.stringify(cache));
|
|
15600
15814
|
}
|
|
15601
15815
|
function touchVersionCache(filename) {
|
|
@@ -15613,9 +15827,9 @@ var init_version_cache = __esm({
|
|
|
15613
15827
|
});
|
|
15614
15828
|
|
|
15615
15829
|
// src/lib/skill-version.ts
|
|
15616
|
-
import { existsSync as
|
|
15830
|
+
import { existsSync as existsSync4, readFileSync as readFileSync6 } from "fs";
|
|
15617
15831
|
import { join as join7 } from "path";
|
|
15618
|
-
import * as
|
|
15832
|
+
import * as yaml4 from "js-yaml";
|
|
15619
15833
|
function skillInstallPaths(skillName) {
|
|
15620
15834
|
return HARNESS_SKILL_DIRS.map((dir) => `${dir}/skills/${skillName}/${SKILL_FILENAME}`);
|
|
15621
15835
|
}
|
|
@@ -15624,7 +15838,7 @@ function parseFrontmatterVersion(content) {
|
|
|
15624
15838
|
if (!match) return null;
|
|
15625
15839
|
let parsed;
|
|
15626
15840
|
try {
|
|
15627
|
-
parsed =
|
|
15841
|
+
parsed = yaml4.load(match[1]);
|
|
15628
15842
|
} catch {
|
|
15629
15843
|
return null;
|
|
15630
15844
|
}
|
|
@@ -15636,7 +15850,7 @@ function findInstalledSkills(projectRoot, paths = SKILL_INSTALL_PATHS) {
|
|
|
15636
15850
|
const found = [];
|
|
15637
15851
|
for (const rel of paths) {
|
|
15638
15852
|
const path35 = join7(projectRoot, rel);
|
|
15639
|
-
if (!
|
|
15853
|
+
if (!existsSync4(path35)) continue;
|
|
15640
15854
|
let version = null;
|
|
15641
15855
|
try {
|
|
15642
15856
|
version = parseFrontmatterVersion(readFileSync6(path35, "utf-8"));
|
|
@@ -15673,22 +15887,22 @@ __export(config_exports, {
|
|
|
15673
15887
|
readConfig: () => readConfig,
|
|
15674
15888
|
writeConfig: () => writeConfig
|
|
15675
15889
|
});
|
|
15676
|
-
import * as
|
|
15677
|
-
import * as
|
|
15890
|
+
import * as fs6 from "fs";
|
|
15891
|
+
import * as path6 from "path";
|
|
15678
15892
|
import * as os from "os";
|
|
15679
15893
|
function configDir() {
|
|
15680
|
-
return
|
|
15894
|
+
return path6.join(os.homedir(), ".wayai");
|
|
15681
15895
|
}
|
|
15682
15896
|
function configPath() {
|
|
15683
|
-
return
|
|
15897
|
+
return path6.join(configDir(), "config.json");
|
|
15684
15898
|
}
|
|
15685
15899
|
function getConfigPath() {
|
|
15686
15900
|
return configPath();
|
|
15687
15901
|
}
|
|
15688
15902
|
function readConfig() {
|
|
15689
|
-
if (!
|
|
15903
|
+
if (!fs6.existsSync(configPath())) return null;
|
|
15690
15904
|
try {
|
|
15691
|
-
const content =
|
|
15905
|
+
const content = fs6.readFileSync(configPath(), "utf-8");
|
|
15692
15906
|
const parsed = JSON.parse(content);
|
|
15693
15907
|
if (!parsed.api_url) return null;
|
|
15694
15908
|
return {
|
|
@@ -15701,13 +15915,13 @@ function readConfig() {
|
|
|
15701
15915
|
}
|
|
15702
15916
|
}
|
|
15703
15917
|
function writeConfig(config) {
|
|
15704
|
-
if (!
|
|
15705
|
-
|
|
15918
|
+
if (!fs6.existsSync(configDir())) {
|
|
15919
|
+
fs6.mkdirSync(configDir(), { recursive: true });
|
|
15706
15920
|
}
|
|
15707
15921
|
let existing = {};
|
|
15708
|
-
if (
|
|
15922
|
+
if (fs6.existsSync(configPath())) {
|
|
15709
15923
|
try {
|
|
15710
|
-
existing = JSON.parse(
|
|
15924
|
+
existing = JSON.parse(fs6.readFileSync(configPath(), "utf-8"));
|
|
15711
15925
|
} catch {
|
|
15712
15926
|
}
|
|
15713
15927
|
}
|
|
@@ -15715,14 +15929,14 @@ function writeConfig(config) {
|
|
|
15715
15929
|
delete existing.access_token;
|
|
15716
15930
|
delete existing.refresh_token;
|
|
15717
15931
|
Object.assign(existing, config);
|
|
15718
|
-
|
|
15932
|
+
fs6.writeFileSync(configPath(), JSON.stringify(existing, null, 2) + "\n", {
|
|
15719
15933
|
mode: 384
|
|
15720
15934
|
// owner-only read/write
|
|
15721
15935
|
});
|
|
15722
15936
|
}
|
|
15723
15937
|
function deleteConfig() {
|
|
15724
|
-
if (
|
|
15725
|
-
|
|
15938
|
+
if (fs6.existsSync(configPath())) {
|
|
15939
|
+
fs6.unlinkSync(configPath());
|
|
15726
15940
|
}
|
|
15727
15941
|
}
|
|
15728
15942
|
var init_config = __esm({
|
|
@@ -15732,14 +15946,14 @@ var init_config = __esm({
|
|
|
15732
15946
|
});
|
|
15733
15947
|
|
|
15734
15948
|
// src/lib/token-store.ts
|
|
15735
|
-
import * as
|
|
15736
|
-
import * as
|
|
15949
|
+
import * as fs7 from "fs";
|
|
15950
|
+
import * as path7 from "path";
|
|
15737
15951
|
import * as os2 from "os";
|
|
15738
15952
|
function configDir2() {
|
|
15739
|
-
return
|
|
15953
|
+
return path7.join(os2.homedir(), ".wayai");
|
|
15740
15954
|
}
|
|
15741
15955
|
function configPath2() {
|
|
15742
|
-
return
|
|
15956
|
+
return path7.join(configDir2(), "config.json");
|
|
15743
15957
|
}
|
|
15744
15958
|
function manualCleanupCommand(account) {
|
|
15745
15959
|
if (process.platform === "darwin") {
|
|
@@ -15791,9 +16005,9 @@ async function getKeyring() {
|
|
|
15791
16005
|
return keyringCache;
|
|
15792
16006
|
}
|
|
15793
16007
|
function readLegacyConfigFile() {
|
|
15794
|
-
if (!
|
|
16008
|
+
if (!fs7.existsSync(configPath2())) return null;
|
|
15795
16009
|
try {
|
|
15796
|
-
return JSON.parse(
|
|
16010
|
+
return JSON.parse(fs7.readFileSync(configPath2(), "utf-8"));
|
|
15797
16011
|
} catch {
|
|
15798
16012
|
return null;
|
|
15799
16013
|
}
|
|
@@ -15806,7 +16020,7 @@ function stripTokensFromFile() {
|
|
|
15806
16020
|
if (k === "token" || k === "access_token" || k === "refresh_token") continue;
|
|
15807
16021
|
cleaned[k] = v;
|
|
15808
16022
|
}
|
|
15809
|
-
|
|
16023
|
+
fs7.writeFileSync(configPath2(), JSON.stringify(cleaned, null, 2) + "\n", { mode: 384 });
|
|
15810
16024
|
}
|
|
15811
16025
|
async function migrateLegacyTokens() {
|
|
15812
16026
|
const legacy = readLegacyConfigFile();
|
|
@@ -15957,8 +16171,8 @@ async function clearTokens() {
|
|
|
15957
16171
|
}
|
|
15958
16172
|
}
|
|
15959
16173
|
}
|
|
15960
|
-
if (
|
|
15961
|
-
|
|
16174
|
+
if (fs7.existsSync(configPath2())) {
|
|
16175
|
+
fs7.unlinkSync(configPath2());
|
|
15962
16176
|
}
|
|
15963
16177
|
}
|
|
15964
16178
|
function readMetadataExpiresAt() {
|
|
@@ -15972,7 +16186,7 @@ function writeMetadataExpiresAt(expires_at) {
|
|
|
15972
16186
|
delete existing.refresh_token;
|
|
15973
16187
|
existing.token_expires_at = expires_at;
|
|
15974
16188
|
ensureConfigDir();
|
|
15975
|
-
|
|
16189
|
+
fs7.writeFileSync(configPath2(), JSON.stringify(existing, null, 2) + "\n", { mode: 384 });
|
|
15976
16190
|
}
|
|
15977
16191
|
function clearMetadataExpiresAt() {
|
|
15978
16192
|
const existing = readLegacyConfigFile();
|
|
@@ -15982,11 +16196,11 @@ function clearMetadataExpiresAt() {
|
|
|
15982
16196
|
delete existing.refresh_token;
|
|
15983
16197
|
delete existing.token_expires_at;
|
|
15984
16198
|
ensureConfigDir();
|
|
15985
|
-
|
|
16199
|
+
fs7.writeFileSync(configPath2(), JSON.stringify(existing, null, 2) + "\n", { mode: 384 });
|
|
15986
16200
|
}
|
|
15987
16201
|
function ensureConfigDir() {
|
|
15988
|
-
if (!
|
|
15989
|
-
|
|
16202
|
+
if (!fs7.existsSync(configDir2())) {
|
|
16203
|
+
fs7.mkdirSync(configDir2(), { recursive: true });
|
|
15990
16204
|
}
|
|
15991
16205
|
}
|
|
15992
16206
|
function writeFileFallback(tokens) {
|
|
@@ -15997,7 +16211,7 @@ function writeFileFallback(tokens) {
|
|
|
15997
16211
|
delete existing.token_expires_at;
|
|
15998
16212
|
Object.assign(existing, tokens);
|
|
15999
16213
|
ensureConfigDir();
|
|
16000
|
-
|
|
16214
|
+
fs7.writeFileSync(configPath2(), JSON.stringify(existing, null, 2) + "\n", { mode: 384 });
|
|
16001
16215
|
}
|
|
16002
16216
|
var KEYRING_SERVICE, KEY_WAY_TOKEN, KEY_OAUTH_ACCESS, KEY_OAUTH_REFRESH, keyringCache, StaleKeyringSlotError;
|
|
16003
16217
|
var init_token_store = __esm({
|
|
@@ -16106,7 +16320,7 @@ async function validateToken(apiUrl, token) {
|
|
|
16106
16320
|
}
|
|
16107
16321
|
}
|
|
16108
16322
|
function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
16109
|
-
return new Promise((
|
|
16323
|
+
return new Promise((resolve8, reject) => {
|
|
16110
16324
|
const server = http.createServer((req, res) => {
|
|
16111
16325
|
const url = new URL(req.url || "/", `http://127.0.0.1:${port}`);
|
|
16112
16326
|
if (url.pathname === "/callback") {
|
|
@@ -16132,7 +16346,7 @@ function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
|
16132
16346
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
16133
16347
|
res.end("<html><body><h2>Login successful!</h2><p>You can close this tab and return to your terminal.</p></body></html>");
|
|
16134
16348
|
server.close();
|
|
16135
|
-
|
|
16349
|
+
resolve8({ code, port });
|
|
16136
16350
|
} else {
|
|
16137
16351
|
res.writeHead(400, { "Content-Type": "text/html" });
|
|
16138
16352
|
res.end("<html><body><h2>Login failed</h2><p>No authorization code received</p></body></html>");
|
|
@@ -16239,14 +16453,14 @@ __export(skill_symlink_exports, {
|
|
|
16239
16453
|
healClaudeSkillLink: () => healClaudeSkillLink,
|
|
16240
16454
|
healSkillLinkForCommand: () => healSkillLinkForCommand
|
|
16241
16455
|
});
|
|
16242
|
-
import { existsSync as
|
|
16456
|
+
import { existsSync as existsSync7, lstatSync, mkdirSync as mkdirSync5, rmSync, symlinkSync } from "fs";
|
|
16243
16457
|
import { join as join10 } from "path";
|
|
16244
16458
|
function healClaudeSkillLink(root) {
|
|
16245
16459
|
try {
|
|
16246
16460
|
const source = join10(root, ".agents", "skills", SKILL_NAME);
|
|
16247
|
-
if (!
|
|
16461
|
+
if (!existsSync7(join10(source, SKILL_FILENAME))) return false;
|
|
16248
16462
|
const link = join10(root, ".claude", "skills", SKILL_NAME);
|
|
16249
|
-
if (
|
|
16463
|
+
if (existsSync7(join10(link, SKILL_FILENAME))) return false;
|
|
16250
16464
|
let entry = null;
|
|
16251
16465
|
try {
|
|
16252
16466
|
entry = lstatSync(link);
|
|
@@ -16257,7 +16471,7 @@ function healClaudeSkillLink(root) {
|
|
|
16257
16471
|
if (!entry.isSymbolicLink()) return false;
|
|
16258
16472
|
rmSync(link, { force: true });
|
|
16259
16473
|
}
|
|
16260
|
-
|
|
16474
|
+
mkdirSync5(join10(root, ".claude", "skills"), { recursive: true });
|
|
16261
16475
|
symlinkSync(join10("..", "..", ".agents", "skills", SKILL_NAME), link, "dir");
|
|
16262
16476
|
return true;
|
|
16263
16477
|
} catch {
|
|
@@ -16344,10 +16558,10 @@ import * as readline2 from "readline";
|
|
|
16344
16558
|
function prompt2(question, defaultValue) {
|
|
16345
16559
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
16346
16560
|
const display = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
|
|
16347
|
-
return new Promise((
|
|
16561
|
+
return new Promise((resolve8) => {
|
|
16348
16562
|
rl.question(display, (answer) => {
|
|
16349
16563
|
rl.close();
|
|
16350
|
-
|
|
16564
|
+
resolve8(answer.trim() || defaultValue || "");
|
|
16351
16565
|
});
|
|
16352
16566
|
});
|
|
16353
16567
|
}
|
|
@@ -16475,8 +16689,8 @@ async function tryOpenBrowser(url) {
|
|
|
16475
16689
|
cmd = "xdg-open";
|
|
16476
16690
|
args2 = [url];
|
|
16477
16691
|
}
|
|
16478
|
-
return new Promise((
|
|
16479
|
-
execFile(cmd, args2, (err) =>
|
|
16692
|
+
return new Promise((resolve8) => {
|
|
16693
|
+
execFile(cmd, args2, (err) => resolve8(!err));
|
|
16480
16694
|
});
|
|
16481
16695
|
} catch {
|
|
16482
16696
|
return false;
|
|
@@ -16541,9 +16755,9 @@ var init_base_id = __esm({
|
|
|
16541
16755
|
|
|
16542
16756
|
// src/lib/worktree-scope.ts
|
|
16543
16757
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
16544
|
-
import * as
|
|
16545
|
-
import * as
|
|
16546
|
-
import * as
|
|
16758
|
+
import * as fs8 from "fs";
|
|
16759
|
+
import * as path8 from "path";
|
|
16760
|
+
import * as yaml5 from "js-yaml";
|
|
16547
16761
|
function axisNoun(axis) {
|
|
16548
16762
|
return AXES[axis].noun;
|
|
16549
16763
|
}
|
|
@@ -16557,7 +16771,7 @@ function resolveGitDir() {
|
|
|
16557
16771
|
encoding: "utf-8",
|
|
16558
16772
|
stdio: ["pipe", "pipe", "pipe"]
|
|
16559
16773
|
}).trim();
|
|
16560
|
-
gitDir = raw ?
|
|
16774
|
+
gitDir = raw ? path8.resolve(cwd, raw) : null;
|
|
16561
16775
|
} catch {
|
|
16562
16776
|
gitDir = null;
|
|
16563
16777
|
}
|
|
@@ -16566,12 +16780,12 @@ function resolveGitDir() {
|
|
|
16566
16780
|
}
|
|
16567
16781
|
function getScopePath() {
|
|
16568
16782
|
const gitDir = resolveGitDir();
|
|
16569
|
-
return gitDir ?
|
|
16783
|
+
return gitDir ? path8.join(gitDir, SCOPE_FILE) : null;
|
|
16570
16784
|
}
|
|
16571
16785
|
function legacyPaths() {
|
|
16572
16786
|
const gitDir = resolveGitDir();
|
|
16573
16787
|
if (!gitDir) return [];
|
|
16574
|
-
return AXIS_ORDER.flatMap((axis) => AXES[axis].legacyFiles).map((f) =>
|
|
16788
|
+
return AXIS_ORDER.flatMap((axis) => AXES[axis].legacyFiles).map((f) => path8.join(gitDir, f));
|
|
16575
16789
|
}
|
|
16576
16790
|
function emptyScope() {
|
|
16577
16791
|
return { hubs: [], bases: [] };
|
|
@@ -16595,7 +16809,7 @@ function readLegacyAxis(axis) {
|
|
|
16595
16809
|
for (const filename of legacyFiles) {
|
|
16596
16810
|
let raw;
|
|
16597
16811
|
try {
|
|
16598
|
-
raw =
|
|
16812
|
+
raw = fs8.readFileSync(path8.join(gitDir, filename), "utf-8");
|
|
16599
16813
|
} catch (err) {
|
|
16600
16814
|
if (err.code === "ENOENT") continue;
|
|
16601
16815
|
throw err;
|
|
@@ -16610,7 +16824,7 @@ function readScope() {
|
|
|
16610
16824
|
if (!scopePath) return emptyScope();
|
|
16611
16825
|
let raw;
|
|
16612
16826
|
try {
|
|
16613
|
-
raw =
|
|
16827
|
+
raw = fs8.readFileSync(scopePath, "utf-8");
|
|
16614
16828
|
} catch (err) {
|
|
16615
16829
|
if (err.code === "ENOENT") {
|
|
16616
16830
|
return { hubs: readLegacyAxis("hubs"), bases: readLegacyAxis("bases") };
|
|
@@ -16619,7 +16833,7 @@ function readScope() {
|
|
|
16619
16833
|
}
|
|
16620
16834
|
let doc;
|
|
16621
16835
|
try {
|
|
16622
|
-
doc =
|
|
16836
|
+
doc = yaml5.load(raw);
|
|
16623
16837
|
} catch {
|
|
16624
16838
|
return emptyScope();
|
|
16625
16839
|
}
|
|
@@ -16630,7 +16844,7 @@ function readScope() {
|
|
|
16630
16844
|
function sweepLegacyFiles() {
|
|
16631
16845
|
for (const legacyPath of legacyPaths()) {
|
|
16632
16846
|
try {
|
|
16633
|
-
|
|
16847
|
+
fs8.unlinkSync(legacyPath);
|
|
16634
16848
|
} catch {
|
|
16635
16849
|
}
|
|
16636
16850
|
}
|
|
@@ -16646,14 +16860,14 @@ function writeScope(scope) {
|
|
|
16646
16860
|
if (!scopePath) {
|
|
16647
16861
|
throw expected("Not inside a git repository \u2014 cannot write the worktree scope.");
|
|
16648
16862
|
}
|
|
16649
|
-
const body =
|
|
16863
|
+
const body = yaml5.dump({ hubs: scope.hubs, bases: scope.bases }, { flowLevel: 1 });
|
|
16650
16864
|
const tmpPath = `${scopePath}.tmp-${process.pid}`;
|
|
16651
16865
|
try {
|
|
16652
|
-
|
|
16653
|
-
|
|
16866
|
+
fs8.writeFileSync(tmpPath, body, "utf-8");
|
|
16867
|
+
fs8.renameSync(tmpPath, scopePath);
|
|
16654
16868
|
} catch (err) {
|
|
16655
16869
|
try {
|
|
16656
|
-
|
|
16870
|
+
fs8.unlinkSync(tmpPath);
|
|
16657
16871
|
} catch {
|
|
16658
16872
|
}
|
|
16659
16873
|
throw asExpectedEnvironmentError(err);
|
|
@@ -16689,7 +16903,7 @@ function clearScope() {
|
|
|
16689
16903
|
let removed = false;
|
|
16690
16904
|
for (const target of [...scopePath ? [scopePath] : [], ...legacyPaths()]) {
|
|
16691
16905
|
try {
|
|
16692
|
-
|
|
16906
|
+
fs8.unlinkSync(target);
|
|
16693
16907
|
removed = true;
|
|
16694
16908
|
} catch (err) {
|
|
16695
16909
|
if (err.code !== "ENOENT") throw err;
|
|
@@ -16794,7 +17008,6 @@ __export(status_exports, {
|
|
|
16794
17008
|
parseArgs: () => parseArgs,
|
|
16795
17009
|
statusCommand: () => statusCommand
|
|
16796
17010
|
});
|
|
16797
|
-
import * as path8 from "path";
|
|
16798
17011
|
function parseArgs(args2) {
|
|
16799
17012
|
return { json: args2.includes("--json") };
|
|
16800
17013
|
}
|
|
@@ -16814,19 +17027,19 @@ function buildSkillState() {
|
|
|
16814
17027
|
paths: installs.map((i) => i.path)
|
|
16815
17028
|
};
|
|
16816
17029
|
}
|
|
16817
|
-
function buildWorkspaceState(
|
|
16818
|
-
if (!
|
|
17030
|
+
function buildWorkspaceState(resolved) {
|
|
17031
|
+
if (!resolved) return { scoped: false, path: null, hub_count: 0 };
|
|
16819
17032
|
const ws = detectWorkspace();
|
|
16820
|
-
const gitRoot = ws?.gitRoot ?? findGitRoot();
|
|
16821
17033
|
const hubCount = ws ? scanWorkspaceHubs(ws.workspaceDir).length : 0;
|
|
16822
|
-
|
|
16823
|
-
return { scoped: true, path: yamlPath, hub_count: hubCount };
|
|
17034
|
+
return { scoped: true, path: resolved.path, hub_count: hubCount };
|
|
16824
17035
|
}
|
|
16825
17036
|
async function statusCommand(args2, pkg2) {
|
|
16826
17037
|
const { json } = parseArgs(args2);
|
|
16827
17038
|
const config = readConfig();
|
|
16828
|
-
const
|
|
16829
|
-
const
|
|
17039
|
+
const resolvedRepo = resolveRepoConfig();
|
|
17040
|
+
const repoConfig = resolvedRepo?.config ?? null;
|
|
17041
|
+
const workspace = buildWorkspaceState(resolvedRepo);
|
|
17042
|
+
const repoScopeBlocker = resolvedRepo ? null : readRepoScopeBlocker();
|
|
16830
17043
|
const cachedCliLatest = readCachedLatest(CLI_CACHE_FILE);
|
|
16831
17044
|
const cliLatest = cachedCliLatest && isNewerVersion(cachedCliLatest, pkg2.version) ? cachedCliLatest : null;
|
|
16832
17045
|
const skill = buildSkillState();
|
|
@@ -16849,6 +17062,7 @@ async function statusCommand(args2, pkg2) {
|
|
|
16849
17062
|
orgs: [],
|
|
16850
17063
|
active_org: null,
|
|
16851
17064
|
workspace,
|
|
17065
|
+
repo_scope_blocker: repoScopeBlocker,
|
|
16852
17066
|
worktree_scope: scope,
|
|
16853
17067
|
worktree_binding: { hub_id: boundHubId },
|
|
16854
17068
|
worktree_lock: { hub_id: boundHubId }
|
|
@@ -16905,6 +17119,7 @@ async function statusCommand(args2, pkg2) {
|
|
|
16905
17119
|
orgs,
|
|
16906
17120
|
active_org: activeOrg,
|
|
16907
17121
|
workspace,
|
|
17122
|
+
repo_scope_blocker: repoScopeBlocker,
|
|
16908
17123
|
worktree_scope: scope,
|
|
16909
17124
|
worktree_binding: { hub_id: boundHubId },
|
|
16910
17125
|
worktree_lock: { hub_id: boundHubId }
|
|
@@ -16934,8 +17149,17 @@ async function statusCommand(args2, pkg2) {
|
|
|
16934
17149
|
console.log(`Repository scope:`);
|
|
16935
17150
|
console.log(` Organization: ${orgLine}`);
|
|
16936
17151
|
console.log(` Hubs: ${workspace.hub_count}`);
|
|
17152
|
+
} else if (repoScopeBlocker?.kind === "conflict") {
|
|
17153
|
+
console.log("Repository scope: UNRESOLVED \u2014 two files name different organizations:");
|
|
17154
|
+
console.log(` ${WORKSPACE_MANIFEST_LABEL} -> ${repoScopeBlocker.manifest_organization_id}`);
|
|
17155
|
+
console.log(` ${ROOT_CONFIG_FILE} -> ${repoScopeBlocker.root_organization_id}`);
|
|
17156
|
+
console.log(` Delete or correct ${ROOT_CONFIG_FILE}; until then every command refuses.`);
|
|
17157
|
+
} else if (repoScopeBlocker?.kind === "invalid") {
|
|
17158
|
+
console.log(`Repository scope: UNRESOLVED \u2014 ${repoScopeBlocker.path} is unusable (${repoScopeBlocker.detail}).`);
|
|
16937
17159
|
} else {
|
|
16938
|
-
console.log(
|
|
17160
|
+
console.log(
|
|
17161
|
+
`No organization binding found in ${WORKSPACE_MANIFEST_LABEL} \u2014 run \`wayai init\` to scope this repo to an organization.`
|
|
17162
|
+
);
|
|
16939
17163
|
}
|
|
16940
17164
|
if (scope.hubs.length > 0 || scope.bases.length > 0) {
|
|
16941
17165
|
console.log("Worktree scope: (run `wayai unbind` to clear)");
|
|
@@ -16952,6 +17176,7 @@ var init_status = __esm({
|
|
|
16952
17176
|
init_config();
|
|
16953
17177
|
init_auth();
|
|
16954
17178
|
init_repo_config();
|
|
17179
|
+
init_workspace_manifest();
|
|
16955
17180
|
init_workspace();
|
|
16956
17181
|
init_worktree_scope();
|
|
16957
17182
|
init_api_client();
|
|
@@ -17035,7 +17260,7 @@ var init_constants = __esm({
|
|
|
17035
17260
|
});
|
|
17036
17261
|
|
|
17037
17262
|
// src/lib/workspace-files.ts
|
|
17038
|
-
import * as
|
|
17263
|
+
import * as fs9 from "fs";
|
|
17039
17264
|
import * as path9 from "path";
|
|
17040
17265
|
function perHubAgentsMd(hubFolderName) {
|
|
17041
17266
|
return [
|
|
@@ -17052,12 +17277,13 @@ function perHubAgentsMd(hubFolderName) {
|
|
|
17052
17277
|
].join("\n");
|
|
17053
17278
|
}
|
|
17054
17279
|
function isWorkspace(gitRoot) {
|
|
17055
|
-
if (
|
|
17280
|
+
if (fs9.existsSync(workspaceManifestPath(gitRoot))) return true;
|
|
17281
|
+
if (fs9.existsSync(rootConfigPath(gitRoot))) return true;
|
|
17056
17282
|
return isDirectory(resolveLayout(gitRoot).hubsDir);
|
|
17057
17283
|
}
|
|
17058
17284
|
function writeIfAbsent(filePath, content) {
|
|
17059
|
-
if (
|
|
17060
|
-
|
|
17285
|
+
if (fs9.existsSync(filePath)) return null;
|
|
17286
|
+
fs9.writeFileSync(filePath, content, "utf-8");
|
|
17061
17287
|
return path9.basename(filePath);
|
|
17062
17288
|
}
|
|
17063
17289
|
function ensureWorkspaceFiles(gitRoot) {
|
|
@@ -17075,6 +17301,7 @@ var init_workspace_files = __esm({
|
|
|
17075
17301
|
"use strict";
|
|
17076
17302
|
init_constants();
|
|
17077
17303
|
init_layout();
|
|
17304
|
+
init_workspace_manifest();
|
|
17078
17305
|
CLAUDE_MD_SHIM = "@AGENTS.md\n";
|
|
17079
17306
|
ROOT_AGENTS_MD = [
|
|
17080
17307
|
"# Working with WayAI",
|
|
@@ -17112,12 +17339,12 @@ __export(init_exports, {
|
|
|
17112
17339
|
initCommand: () => initCommand,
|
|
17113
17340
|
parseArgs: () => parseArgs3
|
|
17114
17341
|
});
|
|
17115
|
-
import { mkdirSync as
|
|
17342
|
+
import { mkdirSync as mkdirSync6 } from "fs";
|
|
17116
17343
|
import path10 from "path";
|
|
17117
17344
|
function ensureHubsDir(gitRoot) {
|
|
17118
17345
|
const hubsDir = resolveLayout(gitRoot).hubsDir;
|
|
17119
17346
|
if (isDirectory(hubsDir)) return null;
|
|
17120
|
-
|
|
17347
|
+
mkdirSync6(hubsDir, { recursive: true });
|
|
17121
17348
|
return `${path10.relative(gitRoot, hubsDir)}/`;
|
|
17122
17349
|
}
|
|
17123
17350
|
function parseArgs3(args2) {
|
|
@@ -17252,18 +17479,18 @@ var init_init = __esm({
|
|
|
17252
17479
|
});
|
|
17253
17480
|
|
|
17254
17481
|
// src/lib/fs-safety.ts
|
|
17255
|
-
import * as
|
|
17482
|
+
import * as fs10 from "fs";
|
|
17256
17483
|
import * as path11 from "path";
|
|
17257
17484
|
function fileHasBytes(abs, data) {
|
|
17258
17485
|
let st;
|
|
17259
17486
|
try {
|
|
17260
|
-
st =
|
|
17487
|
+
st = fs10.lstatSync(abs);
|
|
17261
17488
|
} catch {
|
|
17262
17489
|
return false;
|
|
17263
17490
|
}
|
|
17264
17491
|
if (!st.isFile() || st.isSymbolicLink()) return false;
|
|
17265
17492
|
try {
|
|
17266
|
-
return
|
|
17493
|
+
return fs10.readFileSync(abs).equals(data);
|
|
17267
17494
|
} catch {
|
|
17268
17495
|
return false;
|
|
17269
17496
|
}
|
|
@@ -17272,8 +17499,8 @@ function realpathContained(root, abs) {
|
|
|
17272
17499
|
let realRoot;
|
|
17273
17500
|
let realAbs;
|
|
17274
17501
|
try {
|
|
17275
|
-
realRoot =
|
|
17276
|
-
realAbs =
|
|
17502
|
+
realRoot = fs10.realpathSync(root);
|
|
17503
|
+
realAbs = fs10.realpathSync(abs);
|
|
17277
17504
|
} catch {
|
|
17278
17505
|
return false;
|
|
17279
17506
|
}
|
|
@@ -17281,13 +17508,13 @@ function realpathContained(root, abs) {
|
|
|
17281
17508
|
}
|
|
17282
17509
|
function mkdirTolerateRace(dir) {
|
|
17283
17510
|
try {
|
|
17284
|
-
|
|
17511
|
+
fs10.mkdirSync(dir);
|
|
17285
17512
|
return true;
|
|
17286
17513
|
} catch (err) {
|
|
17287
17514
|
if (err.code !== "EEXIST") throw err;
|
|
17288
17515
|
let st;
|
|
17289
17516
|
try {
|
|
17290
|
-
st =
|
|
17517
|
+
st = fs10.lstatSync(dir);
|
|
17291
17518
|
} catch {
|
|
17292
17519
|
st = void 0;
|
|
17293
17520
|
}
|
|
@@ -17299,7 +17526,7 @@ function ensureRealSubdirNoSymlink(root, target, create) {
|
|
|
17299
17526
|
const targetResolved = path11.resolve(target);
|
|
17300
17527
|
if (targetResolved !== rootResolved && !targetResolved.startsWith(rootResolved + path11.sep)) return false;
|
|
17301
17528
|
try {
|
|
17302
|
-
if (!
|
|
17529
|
+
if (!fs10.lstatSync(rootResolved).isDirectory()) return false;
|
|
17303
17530
|
} catch {
|
|
17304
17531
|
return false;
|
|
17305
17532
|
}
|
|
@@ -17310,7 +17537,7 @@ function ensureRealSubdirNoSymlink(root, target, create) {
|
|
|
17310
17537
|
cur = path11.join(cur, segment);
|
|
17311
17538
|
let st;
|
|
17312
17539
|
try {
|
|
17313
|
-
st =
|
|
17540
|
+
st = fs10.lstatSync(cur);
|
|
17314
17541
|
} catch {
|
|
17315
17542
|
st = void 0;
|
|
17316
17543
|
}
|
|
@@ -17327,8 +17554,8 @@ function ensureRealSubdirNoSymlink(root, target, create) {
|
|
|
17327
17554
|
function readFileNoFollow(root, abs) {
|
|
17328
17555
|
if (!ensureRealSubdirNoSymlink(root, path11.dirname(abs), false)) return null;
|
|
17329
17556
|
try {
|
|
17330
|
-
if (!
|
|
17331
|
-
return
|
|
17557
|
+
if (!fs10.lstatSync(abs).isFile()) return null;
|
|
17558
|
+
return fs10.readFileSync(abs);
|
|
17332
17559
|
} catch {
|
|
17333
17560
|
return null;
|
|
17334
17561
|
}
|
|
@@ -17338,11 +17565,11 @@ function writeFileNoFollow(root, abs, data) {
|
|
|
17338
17565
|
if (!ensureRealSubdirNoSymlink(root, parent, true)) return false;
|
|
17339
17566
|
let st;
|
|
17340
17567
|
try {
|
|
17341
|
-
st =
|
|
17568
|
+
st = fs10.lstatSync(abs);
|
|
17342
17569
|
} catch {
|
|
17343
17570
|
}
|
|
17344
|
-
if (st?.isSymbolicLink())
|
|
17345
|
-
|
|
17571
|
+
if (st?.isSymbolicLink()) fs10.rmSync(abs);
|
|
17572
|
+
fs10.writeFileSync(abs, data);
|
|
17346
17573
|
return true;
|
|
17347
17574
|
}
|
|
17348
17575
|
var init_fs_safety = __esm({
|
|
@@ -17352,7 +17579,7 @@ var init_fs_safety = __esm({
|
|
|
17352
17579
|
});
|
|
17353
17580
|
|
|
17354
17581
|
// src/lib/resource-files.ts
|
|
17355
|
-
import * as
|
|
17582
|
+
import * as fs11 from "fs";
|
|
17356
17583
|
import * as path12 from "path";
|
|
17357
17584
|
import * as crypto3 from "crypto";
|
|
17358
17585
|
function isBinaryFile(filename) {
|
|
@@ -17399,14 +17626,14 @@ function computeHash(data) {
|
|
|
17399
17626
|
}
|
|
17400
17627
|
function scanResourceFiles(dir, prefix = "") {
|
|
17401
17628
|
const files = [];
|
|
17402
|
-
const entries =
|
|
17629
|
+
const entries = fs11.readdirSync(dir, { withFileTypes: true });
|
|
17403
17630
|
for (const entry of entries) {
|
|
17404
17631
|
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
17405
17632
|
if (entry.isDirectory()) {
|
|
17406
17633
|
files.push(...scanResourceFiles(path12.join(dir, entry.name), relPath));
|
|
17407
17634
|
} else if (entry.isFile()) {
|
|
17408
17635
|
const fullPath = path12.join(dir, entry.name);
|
|
17409
|
-
const stat2 =
|
|
17636
|
+
const stat2 = fs11.statSync(fullPath);
|
|
17410
17637
|
if (stat2.size > MAX_RESOURCE_FILE_SIZE3) {
|
|
17411
17638
|
console.warn(` Warning: skipping ${relPath} (${(stat2.size / 1024 / 1024).toFixed(1)}MB exceeds 10MB limit)`);
|
|
17412
17639
|
continue;
|
|
@@ -17416,7 +17643,7 @@ function scanResourceFiles(dir, prefix = "") {
|
|
|
17416
17643
|
mime_type: guessMimeType(entry.name),
|
|
17417
17644
|
file_size: stat2.size
|
|
17418
17645
|
};
|
|
17419
|
-
const data =
|
|
17646
|
+
const data = fs11.readFileSync(fullPath);
|
|
17420
17647
|
fileEntry.hash = computeHash(data);
|
|
17421
17648
|
if (isBinaryFile(entry.name)) {
|
|
17422
17649
|
fileEntry.content_base64 = data.toString("base64");
|
|
@@ -17476,7 +17703,7 @@ function writeResourceFileTree(resDir, files, root, log) {
|
|
|
17476
17703
|
return;
|
|
17477
17704
|
}
|
|
17478
17705
|
if (files.length === 0) {
|
|
17479
|
-
if (
|
|
17706
|
+
if (fs11.existsSync(resDir)) cleanOrphanFiles(resDir, "", /* @__PURE__ */ new Set(), root, log);
|
|
17480
17707
|
return;
|
|
17481
17708
|
}
|
|
17482
17709
|
const writtenPaths = /* @__PURE__ */ new Set();
|
|
@@ -17497,18 +17724,18 @@ function writeResourceFileTree(resDir, files, root, log) {
|
|
|
17497
17724
|
writtenPaths.delete(file.path);
|
|
17498
17725
|
}
|
|
17499
17726
|
}
|
|
17500
|
-
if (
|
|
17727
|
+
if (fs11.existsSync(resDir)) cleanOrphanFiles(resDir, "", writtenPaths, root, log);
|
|
17501
17728
|
}
|
|
17502
17729
|
function cleanOrphanFiles(dir, prefix, writtenPaths, root, log) {
|
|
17503
|
-
const entries =
|
|
17730
|
+
const entries = fs11.readdirSync(dir, { withFileTypes: true });
|
|
17504
17731
|
for (const entry of entries) {
|
|
17505
17732
|
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
17506
17733
|
const fullPath = path12.join(dir, entry.name);
|
|
17507
17734
|
if (entry.isDirectory()) {
|
|
17508
17735
|
cleanOrphanFiles(fullPath, relPath, writtenPaths, root, log);
|
|
17509
|
-
if (
|
|
17736
|
+
if (fs11.readdirSync(fullPath).length === 0) fs11.rmdirSync(fullPath);
|
|
17510
17737
|
} else if (!writtenPaths.has(relPath)) {
|
|
17511
|
-
|
|
17738
|
+
fs11.unlinkSync(fullPath);
|
|
17512
17739
|
if (log && root) log.removed.push(path12.relative(root, fullPath));
|
|
17513
17740
|
}
|
|
17514
17741
|
}
|
|
@@ -17529,8 +17756,8 @@ async function downloadBinaryFiles(resDir, files, root, log) {
|
|
|
17529
17756
|
}
|
|
17530
17757
|
if (file.hash) {
|
|
17531
17758
|
try {
|
|
17532
|
-
const st =
|
|
17533
|
-
if (st.isFile() && !st.isSymbolicLink() && computeHash(
|
|
17759
|
+
const st = fs11.lstatSync(filePath);
|
|
17760
|
+
if (st.isFile() && !st.isSymbolicLink() && computeHash(fs11.readFileSync(filePath)) === file.hash) continue;
|
|
17534
17761
|
} catch {
|
|
17535
17762
|
}
|
|
17536
17763
|
}
|
|
@@ -17584,7 +17811,7 @@ var init_resource_files = __esm({
|
|
|
17584
17811
|
});
|
|
17585
17812
|
|
|
17586
17813
|
// src/lib/eval-attachments.ts
|
|
17587
|
-
import * as
|
|
17814
|
+
import * as fs12 from "fs";
|
|
17588
17815
|
import * as path13 from "path";
|
|
17589
17816
|
function resolveTurnAttachments(hubFolder, turn, label, bytesByHash) {
|
|
17590
17817
|
const raw = turn.attachments;
|
|
@@ -17608,7 +17835,7 @@ function resolveTurnAttachments(hubFolder, turn, label, bytesByHash) {
|
|
|
17608
17835
|
}
|
|
17609
17836
|
let stat2;
|
|
17610
17837
|
try {
|
|
17611
|
-
stat2 =
|
|
17838
|
+
stat2 = fs12.statSync(abs);
|
|
17612
17839
|
} catch {
|
|
17613
17840
|
}
|
|
17614
17841
|
if (!stat2?.isFile()) {
|
|
@@ -17622,7 +17849,7 @@ function resolveTurnAttachments(hubFolder, turn, label, bytesByHash) {
|
|
|
17622
17849
|
`${label}: attachment "${entry}" is ${(stat2.size / 1024 / 1024).toFixed(1)}MB, over the 10MB limit.`
|
|
17623
17850
|
);
|
|
17624
17851
|
}
|
|
17625
|
-
const data =
|
|
17852
|
+
const data = fs12.readFileSync(abs);
|
|
17626
17853
|
const hash = computeHash(data);
|
|
17627
17854
|
const fileName = path13.basename(abs);
|
|
17628
17855
|
const mimeType = guessMimeType(fileName) ?? "application/octet-stream";
|
|
@@ -17730,16 +17957,16 @@ async function downloadEvalAttachments(hubFolder, downloads) {
|
|
|
17730
17957
|
console.warn(` Warning: ${ATTACHMENTS_DIR}/ is not reachable inside the hub folder without a symlink; skipping attachment sync.`);
|
|
17731
17958
|
return result;
|
|
17732
17959
|
}
|
|
17733
|
-
if (!
|
|
17960
|
+
if (!fs12.existsSync(attachDir)) return result;
|
|
17734
17961
|
for (const dl of downloads) {
|
|
17735
17962
|
const abs = path13.resolve(hubFolder, dl.relPath);
|
|
17736
17963
|
if (abs !== attachDir && !abs.startsWith(attachDir + path13.sep)) continue;
|
|
17737
17964
|
let existing;
|
|
17738
17965
|
try {
|
|
17739
|
-
existing =
|
|
17966
|
+
existing = fs12.lstatSync(abs);
|
|
17740
17967
|
} catch {
|
|
17741
17968
|
}
|
|
17742
|
-
if (existing?.isFile() && !existing.isSymbolicLink() && computeHash(
|
|
17969
|
+
if (existing?.isFile() && !existing.isSymbolicLink() && computeHash(fs12.readFileSync(abs)) === dl.hash) {
|
|
17743
17970
|
continue;
|
|
17744
17971
|
}
|
|
17745
17972
|
try {
|
|
@@ -17757,11 +17984,11 @@ async function downloadEvalAttachments(hubFolder, downloads) {
|
|
|
17757
17984
|
}
|
|
17758
17985
|
}
|
|
17759
17986
|
const keep = new Set(downloads.map((d) => path13.resolve(hubFolder, d.relPath)));
|
|
17760
|
-
for (const name of
|
|
17987
|
+
for (const name of fs12.readdirSync(attachDir)) {
|
|
17761
17988
|
const abs = path13.join(attachDir, name);
|
|
17762
|
-
const st =
|
|
17989
|
+
const st = fs12.lstatSync(abs);
|
|
17763
17990
|
if ((st.isFile() || st.isSymbolicLink()) && !keep.has(abs)) {
|
|
17764
|
-
|
|
17991
|
+
fs12.rmSync(abs);
|
|
17765
17992
|
result.removed.push(path13.relative(hubFolder, abs));
|
|
17766
17993
|
}
|
|
17767
17994
|
}
|
|
@@ -17779,20 +18006,20 @@ var init_eval_attachments = __esm({
|
|
|
17779
18006
|
});
|
|
17780
18007
|
|
|
17781
18008
|
// src/lib/parser.ts
|
|
17782
|
-
import * as
|
|
18009
|
+
import * as fs13 from "fs";
|
|
17783
18010
|
import * as path14 from "path";
|
|
17784
|
-
import * as
|
|
18011
|
+
import * as yaml6 from "js-yaml";
|
|
17785
18012
|
function parseHubFolder(hubFolder, opts) {
|
|
17786
18013
|
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
17787
18014
|
if (!yamlPath) {
|
|
17788
18015
|
throw expected(`hub.yaml not found in ${hubFolder}`);
|
|
17789
18016
|
}
|
|
17790
|
-
const yamlContent =
|
|
18017
|
+
const yamlContent = fs13.readFileSync(yamlPath, "utf-8");
|
|
17791
18018
|
let config;
|
|
17792
18019
|
try {
|
|
17793
|
-
config =
|
|
18020
|
+
config = yaml6.load(yamlContent);
|
|
17794
18021
|
} catch (err) {
|
|
17795
|
-
if (err instanceof
|
|
18022
|
+
if (err instanceof yaml6.YAMLException) {
|
|
17796
18023
|
throw expected(`Invalid YAML in ${yamlPath}: ${err.message}`);
|
|
17797
18024
|
}
|
|
17798
18025
|
throw err;
|
|
@@ -17815,8 +18042,8 @@ function parseHubFolder(hubFolder, opts) {
|
|
|
17815
18042
|
if (typeof resolved.instructions === "string" && resolved.instructions.endsWith(".md")) {
|
|
17816
18043
|
const instrValue = resolved.instructions;
|
|
17817
18044
|
const instructionsPath = instrValue.startsWith("agents/") ? path14.join(hubFolder, instrValue) : path14.join(hubFolder, "agents", instrValue);
|
|
17818
|
-
if (
|
|
17819
|
-
resolved.instructions =
|
|
18045
|
+
if (fs13.existsSync(instructionsPath)) {
|
|
18046
|
+
resolved.instructions = fs13.readFileSync(instructionsPath, "utf-8");
|
|
17820
18047
|
} else {
|
|
17821
18048
|
throw expected(
|
|
17822
18049
|
`Agent instructions file not found: ${instructionsPath} (referenced by agent "${agent.name}")`
|
|
@@ -17824,8 +18051,8 @@ function parseHubFolder(hubFolder, opts) {
|
|
|
17824
18051
|
}
|
|
17825
18052
|
} else if (resolved.instructions === void 0 && typeof agent.name === "string") {
|
|
17826
18053
|
const conventionPath = path14.join(hubFolder, "agents", `${slugify(agent.name)}.md`);
|
|
17827
|
-
if (
|
|
17828
|
-
resolved.instructions =
|
|
18054
|
+
if (fs13.existsSync(conventionPath)) {
|
|
18055
|
+
resolved.instructions = fs13.readFileSync(conventionPath, "utf-8");
|
|
17829
18056
|
}
|
|
17830
18057
|
}
|
|
17831
18058
|
return resolved;
|
|
@@ -17880,17 +18107,17 @@ function parseHubFolder(hubFolder, opts) {
|
|
|
17880
18107
|
}
|
|
17881
18108
|
function scanEvalYamlFiles(hubFolder, bytesByHash) {
|
|
17882
18109
|
const evalsDir = path14.join(hubFolder, "evals");
|
|
17883
|
-
if (!
|
|
18110
|
+
if (!fs13.existsSync(evalsDir)) return [];
|
|
17884
18111
|
const evals = [];
|
|
17885
18112
|
const seen = /* @__PURE__ */ new Set();
|
|
17886
|
-
const topEntries =
|
|
18113
|
+
const topEntries = fs13.readdirSync(evalsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
17887
18114
|
for (const entry of topEntries) {
|
|
17888
18115
|
if (entry.isFile() && entry.name.endsWith(".yaml")) {
|
|
17889
18116
|
collectEval(evals, seen, path14.join(evalsDir, entry.name), `evals/${entry.name}`, null, hubFolder, bytesByHash);
|
|
17890
18117
|
} else if (entry.isDirectory()) {
|
|
17891
18118
|
const setName = entry.name;
|
|
17892
18119
|
const setDir = path14.join(evalsDir, setName);
|
|
17893
|
-
const setEntries =
|
|
18120
|
+
const setEntries = fs13.readdirSync(setDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
17894
18121
|
for (const sub of setEntries) {
|
|
17895
18122
|
if (sub.isDirectory()) {
|
|
17896
18123
|
throw expected(
|
|
@@ -17919,12 +18146,12 @@ function collectEval(evals, seen, filePath, relPath, setName, hubFolder, bytesBy
|
|
|
17919
18146
|
evals.push(evalEntry);
|
|
17920
18147
|
}
|
|
17921
18148
|
function parseEvalYaml(filePath, relPath, setName, hubFolder, bytesByHash) {
|
|
17922
|
-
const content =
|
|
18149
|
+
const content = fs13.readFileSync(filePath, "utf-8");
|
|
17923
18150
|
let raw;
|
|
17924
18151
|
try {
|
|
17925
|
-
raw =
|
|
18152
|
+
raw = yaml6.load(content);
|
|
17926
18153
|
} catch (err) {
|
|
17927
|
-
if (err instanceof
|
|
18154
|
+
if (err instanceof yaml6.YAMLException) {
|
|
17928
18155
|
throw expected(`Invalid YAML in ${relPath}: ${err.message}`);
|
|
17929
18156
|
}
|
|
17930
18157
|
throw err;
|
|
@@ -18022,10 +18249,10 @@ function parseFixtureField(raw, label, key) {
|
|
|
18022
18249
|
}
|
|
18023
18250
|
function scanJourneyYamlFiles(hubFolder, bytesByHash) {
|
|
18024
18251
|
const journeysDir = path14.join(hubFolder, "journeys");
|
|
18025
|
-
if (!
|
|
18252
|
+
if (!fs13.existsSync(journeysDir)) return [];
|
|
18026
18253
|
const journeys = [];
|
|
18027
18254
|
const seen = /* @__PURE__ */ new Set();
|
|
18028
|
-
const entries =
|
|
18255
|
+
const entries = fs13.readdirSync(journeysDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
18029
18256
|
for (const entry of entries) {
|
|
18030
18257
|
if (entry.isDirectory()) {
|
|
18031
18258
|
throw expected(
|
|
@@ -18046,12 +18273,12 @@ function scanJourneyYamlFiles(hubFolder, bytesByHash) {
|
|
|
18046
18273
|
return journeys;
|
|
18047
18274
|
}
|
|
18048
18275
|
function parseJourneyYaml(filePath, relPath, hubFolder, bytesByHash) {
|
|
18049
|
-
const content =
|
|
18276
|
+
const content = fs13.readFileSync(filePath, "utf-8");
|
|
18050
18277
|
let raw;
|
|
18051
18278
|
try {
|
|
18052
|
-
raw =
|
|
18279
|
+
raw = yaml6.load(content);
|
|
18053
18280
|
} catch (err) {
|
|
18054
|
-
if (err instanceof
|
|
18281
|
+
if (err instanceof yaml6.YAMLException) {
|
|
18055
18282
|
throw expected(`Invalid YAML in ${relPath}: ${err.message}`);
|
|
18056
18283
|
}
|
|
18057
18284
|
throw err;
|
|
@@ -18102,18 +18329,18 @@ function parseJourneyYaml(filePath, relPath, hubFolder, bytesByHash) {
|
|
|
18102
18329
|
}
|
|
18103
18330
|
function scanAgentYamlFiles(hubFolder) {
|
|
18104
18331
|
const agentsDir = path14.join(hubFolder, "agents");
|
|
18105
|
-
if (!
|
|
18106
|
-
const yamlFiles =
|
|
18332
|
+
if (!fs13.existsSync(agentsDir)) return [];
|
|
18333
|
+
const yamlFiles = fs13.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml")).sort();
|
|
18107
18334
|
if (yamlFiles.length === 0) return [];
|
|
18108
18335
|
const agents = [];
|
|
18109
18336
|
for (const file of yamlFiles) {
|
|
18110
18337
|
const filePath = path14.join(agentsDir, file);
|
|
18111
|
-
const content =
|
|
18338
|
+
const content = fs13.readFileSync(filePath, "utf-8");
|
|
18112
18339
|
let agent;
|
|
18113
18340
|
try {
|
|
18114
|
-
agent =
|
|
18341
|
+
agent = yaml6.load(content);
|
|
18115
18342
|
} catch (err) {
|
|
18116
|
-
if (err instanceof
|
|
18343
|
+
if (err instanceof yaml6.YAMLException) {
|
|
18117
18344
|
throw expected(`Invalid YAML in agents/${file}: ${err.message}`);
|
|
18118
18345
|
}
|
|
18119
18346
|
throw err;
|
|
@@ -18143,7 +18370,7 @@ function parseResources(hubFolder, configResources) {
|
|
|
18143
18370
|
if (res.skill_name) resource.skill_name = res.skill_name;
|
|
18144
18371
|
const resSlug = slugify(resource.name);
|
|
18145
18372
|
const resDir = path14.join(resourcesDir, resSlug);
|
|
18146
|
-
if (
|
|
18373
|
+
if (fs13.existsSync(resDir)) {
|
|
18147
18374
|
const files = scanResourceFiles(resDir, "");
|
|
18148
18375
|
if (files.length > 0) {
|
|
18149
18376
|
resource.files = files;
|
|
@@ -18191,9 +18418,9 @@ var init_diff_display = __esm({
|
|
|
18191
18418
|
});
|
|
18192
18419
|
|
|
18193
18420
|
// src/lib/yaml-writer.ts
|
|
18194
|
-
import * as
|
|
18421
|
+
import * as fs14 from "fs";
|
|
18195
18422
|
import * as path15 from "path";
|
|
18196
|
-
import * as
|
|
18423
|
+
import * as yaml7 from "js-yaml";
|
|
18197
18424
|
function writeFileIfChanged(hubFolder, absPath, content, log) {
|
|
18198
18425
|
const buf = Buffer.from(content, "utf-8");
|
|
18199
18426
|
if (fileHasBytes(absPath, buf)) return;
|
|
@@ -18242,15 +18469,15 @@ function buildEvalYamlObject(evalEntry, slug) {
|
|
|
18242
18469
|
function writeHubFolder(hubFolder, payload, options = {}) {
|
|
18243
18470
|
const log = { changed: [], removed: [] };
|
|
18244
18471
|
const agentsDir = path15.join(hubFolder, "agents");
|
|
18245
|
-
if (!
|
|
18246
|
-
|
|
18472
|
+
if (!fs14.existsSync(hubFolder)) {
|
|
18473
|
+
fs14.mkdirSync(hubFolder, { recursive: true });
|
|
18247
18474
|
}
|
|
18248
|
-
if (!
|
|
18249
|
-
|
|
18475
|
+
if (!fs14.existsSync(agentsDir)) {
|
|
18476
|
+
fs14.mkdirSync(agentsDir, { recursive: true });
|
|
18250
18477
|
}
|
|
18251
18478
|
const yamlPayload = buildYamlPayload(payload);
|
|
18252
18479
|
const agentFiles = extractAgentFiles(payload);
|
|
18253
|
-
const yamlContent =
|
|
18480
|
+
const yamlContent = yaml7.dump(yamlPayload, YAML_DUMP_OPTIONS);
|
|
18254
18481
|
writeFileIfChanged(hubFolder, path15.join(hubFolder, "hub.yaml"), yamlContent, log);
|
|
18255
18482
|
if (options.seedAgentContext ?? true) {
|
|
18256
18483
|
for (const seeded of [
|
|
@@ -18261,8 +18488,8 @@ function writeHubFolder(hubFolder, payload, options = {}) {
|
|
|
18261
18488
|
}
|
|
18262
18489
|
}
|
|
18263
18490
|
const oldYamlPath = path15.join(hubFolder, "wayai.yaml");
|
|
18264
|
-
if (
|
|
18265
|
-
|
|
18491
|
+
if (fs14.existsSync(oldYamlPath)) {
|
|
18492
|
+
fs14.unlinkSync(oldYamlPath);
|
|
18266
18493
|
log.removed.push(path15.relative(hubFolder, oldYamlPath));
|
|
18267
18494
|
}
|
|
18268
18495
|
const yamlSlugs = writeAgentYamlFiles(hubFolder, agentsDir, payload.agents || [], log);
|
|
@@ -18271,20 +18498,20 @@ function writeHubFolder(hubFolder, payload, options = {}) {
|
|
|
18271
18498
|
mdSlugs.add(slug);
|
|
18272
18499
|
writeFileIfChanged(hubFolder, path15.join(agentsDir, `${slug}.md`), content, log);
|
|
18273
18500
|
}
|
|
18274
|
-
const existingFiles =
|
|
18501
|
+
const existingFiles = fs14.readdirSync(agentsDir);
|
|
18275
18502
|
for (const file of existingFiles) {
|
|
18276
18503
|
if (file.endsWith(".yaml")) {
|
|
18277
18504
|
const slug = file.slice(0, -5);
|
|
18278
18505
|
if (!yamlSlugs.has(slug)) {
|
|
18279
18506
|
const orphan = path15.join(agentsDir, file);
|
|
18280
|
-
|
|
18507
|
+
fs14.unlinkSync(orphan);
|
|
18281
18508
|
log.removed.push(path15.relative(hubFolder, orphan));
|
|
18282
18509
|
}
|
|
18283
18510
|
} else if (file.endsWith(".md")) {
|
|
18284
18511
|
const slug = file.slice(0, -3);
|
|
18285
18512
|
if (!mdSlugs.has(slug)) {
|
|
18286
18513
|
const orphan = path15.join(agentsDir, file);
|
|
18287
|
-
|
|
18514
|
+
fs14.unlinkSync(orphan);
|
|
18288
18515
|
log.removed.push(path15.relative(hubFolder, orphan));
|
|
18289
18516
|
}
|
|
18290
18517
|
}
|
|
@@ -18297,10 +18524,10 @@ function writeHubFolder(hubFolder, payload, options = {}) {
|
|
|
18297
18524
|
function setPreviewLabelInHubYaml(hubFolder, label) {
|
|
18298
18525
|
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
18299
18526
|
if (!yamlPath) return;
|
|
18300
|
-
const obj =
|
|
18527
|
+
const obj = yaml7.load(fs14.readFileSync(yamlPath, "utf-8")) ?? {};
|
|
18301
18528
|
if (label) obj.preview_label = label;
|
|
18302
18529
|
else delete obj.preview_label;
|
|
18303
|
-
|
|
18530
|
+
fs14.writeFileSync(yamlPath, yaml7.dump(obj, YAML_DUMP_OPTIONS), "utf-8");
|
|
18304
18531
|
}
|
|
18305
18532
|
function buildYamlPayload(payload) {
|
|
18306
18533
|
const result = {
|
|
@@ -18345,7 +18572,7 @@ function writeAgentYamlFiles(hubFolder, agentsDir, agents, log) {
|
|
|
18345
18572
|
slugs.add(slug);
|
|
18346
18573
|
const entry = { ...agent };
|
|
18347
18574
|
delete entry.instructions;
|
|
18348
|
-
const yamlContent =
|
|
18575
|
+
const yamlContent = yaml7.dump(entry, YAML_DUMP_OPTIONS);
|
|
18349
18576
|
writeFileIfChanged(hubFolder, path15.join(agentsDir, `${slug}.yaml`), yamlContent, log);
|
|
18350
18577
|
}
|
|
18351
18578
|
return slugs;
|
|
@@ -18365,17 +18592,17 @@ function extractAgentFiles(payload) {
|
|
|
18365
18592
|
function writeEvalYamlFiles(hubFolder, evals, log) {
|
|
18366
18593
|
const evalsDir = path15.join(hubFolder, "evals");
|
|
18367
18594
|
if (evals.length === 0) {
|
|
18368
|
-
if (
|
|
18595
|
+
if (fs14.existsSync(evalsDir)) {
|
|
18369
18596
|
cleanEvalOrphans(hubFolder, evalsDir, /* @__PURE__ */ new Set(), log);
|
|
18370
18597
|
try {
|
|
18371
|
-
if (
|
|
18598
|
+
if (fs14.readdirSync(evalsDir).length === 0) fs14.rmdirSync(evalsDir);
|
|
18372
18599
|
} catch {
|
|
18373
18600
|
}
|
|
18374
18601
|
}
|
|
18375
18602
|
return;
|
|
18376
18603
|
}
|
|
18377
|
-
if (!
|
|
18378
|
-
|
|
18604
|
+
if (!fs14.existsSync(evalsDir)) {
|
|
18605
|
+
fs14.mkdirSync(evalsDir, { recursive: true });
|
|
18379
18606
|
}
|
|
18380
18607
|
const writtenRelPaths = /* @__PURE__ */ new Set();
|
|
18381
18608
|
for (const evalEntry of evals) {
|
|
@@ -18389,42 +18616,42 @@ function writeEvalYamlFiles(hubFolder, evals, log) {
|
|
|
18389
18616
|
}
|
|
18390
18617
|
if (setName) {
|
|
18391
18618
|
const setDir = path15.join(evalsDir, setName);
|
|
18392
|
-
if (!
|
|
18393
|
-
|
|
18619
|
+
if (!fs14.existsSync(setDir)) {
|
|
18620
|
+
fs14.mkdirSync(setDir, { recursive: true });
|
|
18394
18621
|
}
|
|
18395
18622
|
}
|
|
18396
|
-
const yamlContent =
|
|
18623
|
+
const yamlContent = yaml7.dump(buildEvalYamlObject(evalEntry, slug), YAML_DUMP_OPTIONS);
|
|
18397
18624
|
writeFileIfChanged(hubFolder, targetPath, yamlContent, log);
|
|
18398
18625
|
writtenRelPaths.add(relPath);
|
|
18399
18626
|
}
|
|
18400
18627
|
cleanEvalOrphans(hubFolder, evalsDir, writtenRelPaths, log);
|
|
18401
18628
|
}
|
|
18402
18629
|
function cleanEvalOrphans(hubFolder, evalsDir, writtenRelPaths, log) {
|
|
18403
|
-
const entries =
|
|
18630
|
+
const entries = fs14.readdirSync(evalsDir, { withFileTypes: true });
|
|
18404
18631
|
for (const entry of entries) {
|
|
18405
18632
|
const fullPath = path15.join(evalsDir, entry.name);
|
|
18406
18633
|
if (entry.isFile()) {
|
|
18407
18634
|
if (entry.name.endsWith(".yaml") && !writtenRelPaths.has(entry.name)) {
|
|
18408
|
-
|
|
18635
|
+
fs14.unlinkSync(fullPath);
|
|
18409
18636
|
log.removed.push(path15.relative(hubFolder, fullPath));
|
|
18410
18637
|
}
|
|
18411
18638
|
continue;
|
|
18412
18639
|
}
|
|
18413
18640
|
if (entry.isDirectory()) {
|
|
18414
18641
|
const setName = entry.name;
|
|
18415
|
-
const subEntries =
|
|
18642
|
+
const subEntries = fs14.readdirSync(fullPath, { withFileTypes: true });
|
|
18416
18643
|
for (const sub of subEntries) {
|
|
18417
18644
|
if (sub.isFile() && sub.name.endsWith(".yaml")) {
|
|
18418
18645
|
const relPath = `${setName}/${sub.name}`;
|
|
18419
18646
|
if (!writtenRelPaths.has(relPath)) {
|
|
18420
18647
|
const orphan = path15.join(fullPath, sub.name);
|
|
18421
|
-
|
|
18648
|
+
fs14.unlinkSync(orphan);
|
|
18422
18649
|
log.removed.push(path15.relative(hubFolder, orphan));
|
|
18423
18650
|
}
|
|
18424
18651
|
}
|
|
18425
18652
|
}
|
|
18426
18653
|
try {
|
|
18427
|
-
if (
|
|
18654
|
+
if (fs14.readdirSync(fullPath).length === 0) fs14.rmdirSync(fullPath);
|
|
18428
18655
|
} catch {
|
|
18429
18656
|
}
|
|
18430
18657
|
}
|
|
@@ -18463,35 +18690,35 @@ function buildJourneyYamlObject(journeyEntry, slug) {
|
|
|
18463
18690
|
function writeJourneyYamlFiles(hubFolder, journeys, log) {
|
|
18464
18691
|
const journeysDir = path15.join(hubFolder, "journeys");
|
|
18465
18692
|
if (journeys.length === 0) {
|
|
18466
|
-
if (
|
|
18693
|
+
if (fs14.existsSync(journeysDir)) {
|
|
18467
18694
|
cleanJourneyOrphans(hubFolder, journeysDir, /* @__PURE__ */ new Set(), log);
|
|
18468
18695
|
try {
|
|
18469
|
-
if (
|
|
18696
|
+
if (fs14.readdirSync(journeysDir).length === 0) fs14.rmdirSync(journeysDir);
|
|
18470
18697
|
} catch {
|
|
18471
18698
|
}
|
|
18472
18699
|
}
|
|
18473
18700
|
return;
|
|
18474
18701
|
}
|
|
18475
|
-
if (!
|
|
18476
|
-
|
|
18702
|
+
if (!fs14.existsSync(journeysDir)) {
|
|
18703
|
+
fs14.mkdirSync(journeysDir, { recursive: true });
|
|
18477
18704
|
}
|
|
18478
18705
|
const writtenFiles = /* @__PURE__ */ new Set();
|
|
18479
18706
|
const usedSlugs = /* @__PURE__ */ new Set();
|
|
18480
18707
|
for (const journeyEntry of journeys) {
|
|
18481
18708
|
const slug = ensureUniqueSlug(slugify(journeyEntry.name), usedSlugs);
|
|
18482
18709
|
const fileName = `${slug}.yaml`;
|
|
18483
|
-
const yamlContent =
|
|
18710
|
+
const yamlContent = yaml7.dump(buildJourneyYamlObject(journeyEntry, slug), YAML_DUMP_OPTIONS);
|
|
18484
18711
|
writeFileIfChanged(hubFolder, path15.join(journeysDir, fileName), yamlContent, log);
|
|
18485
18712
|
writtenFiles.add(fileName);
|
|
18486
18713
|
}
|
|
18487
18714
|
cleanJourneyOrphans(hubFolder, journeysDir, writtenFiles, log);
|
|
18488
18715
|
}
|
|
18489
18716
|
function cleanJourneyOrphans(hubFolder, journeysDir, writtenFiles, log) {
|
|
18490
|
-
const entries =
|
|
18717
|
+
const entries = fs14.readdirSync(journeysDir, { withFileTypes: true });
|
|
18491
18718
|
for (const entry of entries) {
|
|
18492
18719
|
if (entry.isFile() && entry.name.endsWith(".yaml") && !writtenFiles.has(entry.name)) {
|
|
18493
18720
|
const orphan = path15.join(journeysDir, entry.name);
|
|
18494
|
-
|
|
18721
|
+
fs14.unlinkSync(orphan);
|
|
18495
18722
|
log.removed.push(path15.relative(hubFolder, orphan));
|
|
18496
18723
|
}
|
|
18497
18724
|
}
|
|
@@ -18505,12 +18732,12 @@ function writeResourceFiles(hubFolder, resources, log) {
|
|
|
18505
18732
|
const resDir = path15.join(resourcesDir, resSlug);
|
|
18506
18733
|
writeResourceFileTree(resDir, resource.files || [], hubFolder, log);
|
|
18507
18734
|
}
|
|
18508
|
-
if (
|
|
18509
|
-
const existingDirs =
|
|
18735
|
+
if (fs14.existsSync(resourcesDir)) {
|
|
18736
|
+
const existingDirs = fs14.readdirSync(resourcesDir, { withFileTypes: true });
|
|
18510
18737
|
for (const entry of existingDirs) {
|
|
18511
18738
|
if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
|
|
18512
18739
|
const orphanDir = path15.join(resourcesDir, entry.name);
|
|
18513
|
-
|
|
18740
|
+
fs14.rmSync(orphanDir, { recursive: true, force: true });
|
|
18514
18741
|
log.removed.push(`${path15.relative(hubFolder, orphanDir)}/`);
|
|
18515
18742
|
}
|
|
18516
18743
|
}
|
|
@@ -18599,15 +18826,15 @@ var init_terminal_output = __esm({
|
|
|
18599
18826
|
});
|
|
18600
18827
|
|
|
18601
18828
|
// src/lib/base-workspace.ts
|
|
18602
|
-
import * as
|
|
18829
|
+
import * as fs15 from "fs";
|
|
18603
18830
|
import * as path17 from "path";
|
|
18604
|
-
import * as
|
|
18831
|
+
import * as yaml8 from "js-yaml";
|
|
18605
18832
|
function readBaseMeta(folder) {
|
|
18606
18833
|
const bytes = readFileNoFollow(folder, path17.join(folder, BASE_META_FILE));
|
|
18607
18834
|
if (bytes === null) return null;
|
|
18608
18835
|
let doc;
|
|
18609
18836
|
try {
|
|
18610
|
-
doc =
|
|
18837
|
+
doc = yaml8.load(bytes.toString("utf-8"));
|
|
18611
18838
|
} catch {
|
|
18612
18839
|
return null;
|
|
18613
18840
|
}
|
|
@@ -18617,7 +18844,7 @@ function readBaseMeta(folder) {
|
|
|
18617
18844
|
function listBaseFolders(basesDir) {
|
|
18618
18845
|
let entries;
|
|
18619
18846
|
try {
|
|
18620
|
-
entries =
|
|
18847
|
+
entries = fs15.readdirSync(basesDir).filter((entry) => !entry.startsWith("."));
|
|
18621
18848
|
} catch {
|
|
18622
18849
|
return [];
|
|
18623
18850
|
}
|
|
@@ -18704,7 +18931,7 @@ function resolveBaseSelectorToId(gitRoot, selector) {
|
|
|
18704
18931
|
}
|
|
18705
18932
|
function hasBaseMetaFile(folder) {
|
|
18706
18933
|
try {
|
|
18707
|
-
return
|
|
18934
|
+
return fs15.lstatSync(path17.join(folder, BASE_META_FILE)).isFile();
|
|
18708
18935
|
} catch {
|
|
18709
18936
|
return false;
|
|
18710
18937
|
}
|
|
@@ -18722,25 +18949,17 @@ var init_base_workspace = __esm({
|
|
|
18722
18949
|
});
|
|
18723
18950
|
|
|
18724
18951
|
// src/lib/subtree-routing.ts
|
|
18725
|
-
import * as fs15 from "fs";
|
|
18726
18952
|
import * as path18 from "path";
|
|
18727
|
-
import * as yaml8 from "js-yaml";
|
|
18728
18953
|
function readRepoDefaults(gitRoot) {
|
|
18729
|
-
const
|
|
18730
|
-
|
|
18731
|
-
|
|
18732
|
-
doc = yaml8.load(fs15.readFileSync(file, "utf-8"));
|
|
18733
|
-
} catch {
|
|
18734
|
-
return {};
|
|
18735
|
-
}
|
|
18736
|
-
if (!doc || typeof doc !== "object") return {};
|
|
18737
|
-
const raw = doc;
|
|
18954
|
+
const load11 = loadWorkspaceManifest(gitRoot);
|
|
18955
|
+
if (load11.kind !== "ok") return {};
|
|
18956
|
+
const raw = load11.doc;
|
|
18738
18957
|
const str = (v) => {
|
|
18739
18958
|
if (typeof v !== "string" || !v.trim()) return void 0;
|
|
18740
18959
|
const value = v.trim();
|
|
18741
18960
|
if (value.includes("/") || value.includes(path18.sep) || value === "." || value === "..") {
|
|
18742
18961
|
console.warn(
|
|
18743
|
-
`Warning: ignoring ${JSON.stringify(value)} in ${
|
|
18962
|
+
`Warning: ignoring ${JSON.stringify(value)} in ${WORKSPACE_MANIFEST_LABEL} \u2014 a default names a hub or base, not a path.`
|
|
18744
18963
|
);
|
|
18745
18964
|
return void 0;
|
|
18746
18965
|
}
|
|
@@ -18828,11 +19047,11 @@ function routeSubtree(options) {
|
|
|
18828
19047
|
return {
|
|
18829
19048
|
ok: false,
|
|
18830
19049
|
refusal: [
|
|
18831
|
-
`\`wayai ${verb}\` does not take --org: it operates on the organization named by
|
|
19050
|
+
`\`wayai ${verb}\` does not take --org: it operates on the organization named by ${WORKSPACE_MANIFEST_LABEL}.`,
|
|
18832
19051
|
"",
|
|
18833
19052
|
"To act on another organization:",
|
|
18834
19053
|
" wayai bases <command> --org <uuid> # the Data surface honors it",
|
|
18835
|
-
" # or run from a checkout whose
|
|
19054
|
+
" # or run from a checkout whose workspace manifest names that organization"
|
|
18836
19055
|
].join("\n")
|
|
18837
19056
|
};
|
|
18838
19057
|
}
|
|
@@ -18899,15 +19118,15 @@ function requireSubtree(verb, args2, gitRoot) {
|
|
|
18899
19118
|
}
|
|
18900
19119
|
return { subtree: result.subtree, selector: result.selector };
|
|
18901
19120
|
}
|
|
18902
|
-
var
|
|
19121
|
+
var VALUE_FLAGS;
|
|
18903
19122
|
var init_subtree_routing = __esm({
|
|
18904
19123
|
"src/lib/subtree-routing.ts"() {
|
|
18905
19124
|
"use strict";
|
|
18906
19125
|
init_layout();
|
|
18907
19126
|
init_terminal_output();
|
|
19127
|
+
init_workspace_manifest();
|
|
18908
19128
|
init_workspace();
|
|
18909
19129
|
init_base_workspace();
|
|
18910
|
-
REPO_DEFAULTS_FILE = "wayai.yaml";
|
|
18911
19130
|
VALUE_FLAGS = /* @__PURE__ */ new Set(["--hub", "--base", "--label", "--org"]);
|
|
18912
19131
|
}
|
|
18913
19132
|
});
|
|
@@ -18934,12 +19153,12 @@ async function createDataClient(orgId) {
|
|
|
18934
19153
|
if (selected !== void 0 && !UUID_RE2.test(selected)) {
|
|
18935
19154
|
throw expected(`Invalid --org: ${JSON.stringify(selected)}. Expected an organization UUID.`);
|
|
18936
19155
|
}
|
|
18937
|
-
const org = selected ??
|
|
19156
|
+
const org = selected ?? readRepoConfigUnlessBlocked()?.organization_id;
|
|
18938
19157
|
async function requireOrgForSetupRoute(what) {
|
|
18939
19158
|
const orgId2 = org ?? (await api.me()).org_id;
|
|
18940
19159
|
if (!orgId2) {
|
|
18941
19160
|
throw expected(
|
|
18942
|
-
`No organization to ${what} against. Pass --org <uuid>, or run this from a repo
|
|
19161
|
+
`No organization to ${what} against. Pass --org <uuid>, or run this from a repo scoped by \`wayai init\`.`
|
|
18943
19162
|
);
|
|
18944
19163
|
}
|
|
18945
19164
|
return orgId2;
|
|
@@ -19025,7 +19244,7 @@ var init_client = __esm({
|
|
|
19025
19244
|
});
|
|
19026
19245
|
|
|
19027
19246
|
// src/data/helpers.ts
|
|
19028
|
-
import { readFileSync as
|
|
19247
|
+
import { readFileSync as readFileSync15 } from "fs";
|
|
19029
19248
|
function pathSegment(id, label = "id") {
|
|
19030
19249
|
if (!isPathSafeId(id)) {
|
|
19031
19250
|
throw expected(`Invalid ${label}: ${JSON.stringify(id)}. An id may use ${PATH_SAFE_ID_RULE}.`);
|
|
@@ -19053,7 +19272,7 @@ function parseData(data, flag) {
|
|
|
19053
19272
|
let text = data;
|
|
19054
19273
|
if (source !== void 0) {
|
|
19055
19274
|
try {
|
|
19056
|
-
text =
|
|
19275
|
+
text = readFileSync15(source, "utf-8");
|
|
19057
19276
|
} catch (e) {
|
|
19058
19277
|
throw expected(`${prefix}${source}: ${e instanceof Error ? e.message : "could not be read"}`);
|
|
19059
19278
|
}
|
|
@@ -21148,9 +21367,10 @@ async function migrateCommand(_args) {
|
|
|
21148
21367
|
const newOrg = path29.join(newWs, WAYAI_LAYOUT.orgSubdir);
|
|
21149
21368
|
const hasLegacyWs = isDirectory(legacyWs);
|
|
21150
21369
|
const hasLegacyOrg = isDirectory(legacyOrg);
|
|
21151
|
-
|
|
21152
|
-
|
|
21153
|
-
|
|
21370
|
+
const orgPlan = planOrgMigration(gitRoot);
|
|
21371
|
+
if (orgPlan.kind === "refuse") {
|
|
21372
|
+
console.error(orgPlan.message);
|
|
21373
|
+
process.exit(1);
|
|
21154
21374
|
}
|
|
21155
21375
|
if (hasLegacyWs && isDirectory(newHubs)) {
|
|
21156
21376
|
console.error(
|
|
@@ -21176,10 +21396,30 @@ async function migrateCommand(_args) {
|
|
|
21176
21396
|
usedFsFallback ||= how === "fs";
|
|
21177
21397
|
moved.push(`${WAYAI_LAYOUT.legacy.orgAtRoot}/ \u2192 ${rel(newOrg)}/`);
|
|
21178
21398
|
}
|
|
21179
|
-
|
|
21180
|
-
|
|
21181
|
-
|
|
21182
|
-
|
|
21399
|
+
if (moved.length > 0) {
|
|
21400
|
+
console.log(`Migrated to the ${WAYAI_LAYOUT.wsDir}/ layout:`);
|
|
21401
|
+
for (const m of moved) console.log(` ${m}`);
|
|
21402
|
+
if (usedFsFallback) {
|
|
21403
|
+
console.log("\n(Some dirs were moved on disk, not via git \u2014 they will show as untracked.)");
|
|
21404
|
+
}
|
|
21405
|
+
}
|
|
21406
|
+
const copiedOrg = orgPlan.kind === "copy";
|
|
21407
|
+
if (copiedOrg) {
|
|
21408
|
+
writeRepoConfig(orgPlan.config, gitRoot);
|
|
21409
|
+
console.log(`${moved.length > 0 ? "\n" : ""}Copied the organization binding into ${WORKSPACE_MANIFEST_LABEL}.`);
|
|
21410
|
+
console.log(
|
|
21411
|
+
` ${ROOT_CONFIG_FILE} is KEPT on purpose \u2014 an older CLI in a teammate's environment or in CI still requires it.`
|
|
21412
|
+
);
|
|
21413
|
+
console.log(
|
|
21414
|
+
" It stays a supported fallback until the next major, which removes both the fallback and the file."
|
|
21415
|
+
);
|
|
21416
|
+
console.log(" Delete it once every environment that runs this repo reads the manifest.");
|
|
21417
|
+
}
|
|
21418
|
+
if (moved.length === 0 && !copiedOrg) {
|
|
21419
|
+
console.log(
|
|
21420
|
+
`Already migrated \u2014 no legacy ${WAYAI_LAYOUT.legacy.wsDir}/ or ${WAYAI_LAYOUT.legacy.orgAtRoot}/ to move, and no organization binding to copy into ${WORKSPACE_MANIFEST_LABEL}.`
|
|
21421
|
+
);
|
|
21422
|
+
return;
|
|
21183
21423
|
}
|
|
21184
21424
|
console.log("\nNext steps:");
|
|
21185
21425
|
console.log(' git add -A && git commit -m "chore: migrate to wayai-ws layout"');
|
|
@@ -21190,6 +21430,8 @@ var init_migrate = __esm({
|
|
|
21190
21430
|
"use strict";
|
|
21191
21431
|
init_workspace();
|
|
21192
21432
|
init_layout();
|
|
21433
|
+
init_repo_config();
|
|
21434
|
+
init_workspace_manifest();
|
|
21193
21435
|
}
|
|
21194
21436
|
});
|
|
21195
21437
|
|
|
@@ -22583,8 +22825,8 @@ function installEvalSignalHandlers(input) {
|
|
|
22583
22825
|
let signalCount = 0;
|
|
22584
22826
|
let disposed = false;
|
|
22585
22827
|
let settle;
|
|
22586
|
-
const settled = new Promise((
|
|
22587
|
-
settle =
|
|
22828
|
+
const settled = new Promise((resolve8) => {
|
|
22829
|
+
settle = resolve8;
|
|
22588
22830
|
});
|
|
22589
22831
|
const listeners = /* @__PURE__ */ new Map();
|
|
22590
22832
|
const dispose = () => {
|
|
@@ -22934,7 +23176,7 @@ Timeout after ${timeoutSeconds}s${queuedSeconds > 0 ? ` (${queuedSeconds}s of it
|
|
|
22934
23176
|
process.exit(1);
|
|
22935
23177
|
}
|
|
22936
23178
|
function sleep(ms) {
|
|
22937
|
-
return new Promise((
|
|
23179
|
+
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
22938
23180
|
}
|
|
22939
23181
|
function parseRunNumbers(raw) {
|
|
22940
23182
|
if (!raw || raw.startsWith("--")) {
|
|
@@ -26790,26 +27032,26 @@ async function reportGetCommand(args2) {
|
|
|
26790
27032
|
console.log(JSON.stringify(result, null, 2));
|
|
26791
27033
|
return;
|
|
26792
27034
|
}
|
|
26793
|
-
const { report, messages } = result;
|
|
26794
|
-
const title = sanitizeTerminalText(
|
|
26795
|
-
const description = sanitizeTerminalText(
|
|
26796
|
-
console.log(`Report ${
|
|
27035
|
+
const { report: report2, messages } = result;
|
|
27036
|
+
const title = sanitizeTerminalText(report2.title);
|
|
27037
|
+
const description = sanitizeTerminalText(report2.description);
|
|
27038
|
+
console.log(`Report ${report2.report_id}`);
|
|
26797
27039
|
console.log(` title: ${title}`);
|
|
26798
27040
|
console.log(` description: ${description.replace(/\n/g, "\n ")}`);
|
|
26799
|
-
console.log(` status: ${
|
|
26800
|
-
console.log(` classification: ${
|
|
26801
|
-
if (
|
|
26802
|
-
if (
|
|
27041
|
+
console.log(` status: ${report2.status}`);
|
|
27042
|
+
console.log(` classification: ${report2.classification}`);
|
|
27043
|
+
if (report2.contest_count > 0) console.log(` contests: ${report2.contest_count}`);
|
|
27044
|
+
if (report2.dismissal_final) console.log(" dismissal: final (non-contestable)");
|
|
26803
27045
|
if (messages.length > 0) {
|
|
26804
27046
|
console.log("\n Thread:");
|
|
26805
27047
|
for (const m of messages) {
|
|
26806
27048
|
console.log(` [${m.author_role}] ${sanitizeTerminalText(m.body)}`);
|
|
26807
27049
|
}
|
|
26808
27050
|
}
|
|
26809
|
-
if (
|
|
27051
|
+
if (report2.status === "shipped") {
|
|
26810
27052
|
console.log(`
|
|
26811
|
-
This fix is shipped. Run \`wayai report accept ${
|
|
26812
|
-
console.log(` or \`wayai report contest ${
|
|
27053
|
+
This fix is shipped. Run \`wayai report accept ${report2.report_id}\` if it works,`);
|
|
27054
|
+
console.log(` or \`wayai report contest ${report2.report_id} --reason "..."\` if it does not.`);
|
|
26813
27055
|
}
|
|
26814
27056
|
} catch (err) {
|
|
26815
27057
|
reportActionError(err);
|
|
@@ -27089,7 +27331,7 @@ var init_actions = __esm({
|
|
|
27089
27331
|
|
|
27090
27332
|
// src/data/commands/attachments.ts
|
|
27091
27333
|
import { Command as Command2 } from "commander";
|
|
27092
|
-
import { readFileSync as
|
|
27334
|
+
import { readFileSync as readFileSync20 } from "fs";
|
|
27093
27335
|
function findAttachmentByFilename(attachments, filename) {
|
|
27094
27336
|
return attachments.find((a) => a.key.endsWith(`/${filename}`)) ?? null;
|
|
27095
27337
|
}
|
|
@@ -27130,7 +27372,7 @@ function buildAttachmentsCommand() {
|
|
|
27130
27372
|
printOutput(data, outputFormat(this));
|
|
27131
27373
|
return;
|
|
27132
27374
|
}
|
|
27133
|
-
const body =
|
|
27375
|
+
const body = readFileSync20(opts.file);
|
|
27134
27376
|
await client.upload(uploadPathFrom(data?.upload_url), body, opts.contentType);
|
|
27135
27377
|
printOutput({ ...data, uploaded: true }, outputFormat(this));
|
|
27136
27378
|
});
|
|
@@ -27610,16 +27852,16 @@ var init_providers = __esm({
|
|
|
27610
27852
|
|
|
27611
27853
|
// src/data/commands/report.ts
|
|
27612
27854
|
import { Command as Command6 } from "commander";
|
|
27613
|
-
import { readFileSync as
|
|
27614
|
-
import { dirname as
|
|
27855
|
+
import { readFileSync as readFileSync21 } from "fs";
|
|
27856
|
+
import { dirname as dirname12, join as join31 } from "path";
|
|
27615
27857
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
27616
27858
|
function resolveCliVersion() {
|
|
27617
27859
|
for (const candidate of [
|
|
27618
|
-
|
|
27619
|
-
|
|
27860
|
+
join31(here, "..", "package.json"),
|
|
27861
|
+
join31(here, "..", "..", "..", "package.json")
|
|
27620
27862
|
]) {
|
|
27621
27863
|
try {
|
|
27622
|
-
const version = JSON.parse(
|
|
27864
|
+
const version = JSON.parse(readFileSync21(candidate, "utf-8")).version;
|
|
27623
27865
|
if (typeof version === "string" && version) return version;
|
|
27624
27866
|
} catch {
|
|
27625
27867
|
}
|
|
@@ -27653,10 +27895,10 @@ function reportActionError2(err) {
|
|
|
27653
27895
|
throw err;
|
|
27654
27896
|
}
|
|
27655
27897
|
function buildBasesReportCommand() {
|
|
27656
|
-
const
|
|
27898
|
+
const report2 = new Command6("report").description(
|
|
27657
27899
|
"File a report to the Data triage queue and verify the outcome"
|
|
27658
27900
|
);
|
|
27659
|
-
|
|
27901
|
+
report2.command("create").description("Submit a report to the Data triage queue (deduplicated)").requiredOption("--title <title>", "Short summary").requiredOption("--description <text>", "What happened").option("--source <source>", "Origin: cli_report (default) | review | security_audit").option("--classification <c>", "Nature: bug (default) | flaky_test | security | enhancement").option(
|
|
27660
27902
|
"--dedup-key <key>",
|
|
27661
27903
|
'Stable dedup key (e.g. "<file>::<test>"); collapses repeat occurrences'
|
|
27662
27904
|
).option("--severity <level>", "low | medium | high | critical").option("--steps <text>", "Steps to reproduce").option("--error-message <text>", "Exact error text if any").option("--context <text>", "Additional context (logs, request ids)").option("--locale <code>", "Notification locale (en | pt | es)", "en").option("--reporter-email <addr>", "Override reporter email (defaults to session email)").option("--base-id <id>", "Base the error relates to (defaults to the configured base)").option("--record-type <name>", "Record type the error relates to").option("--record-id <id>", "Record id (UUID) the error relates to").option("--external-id <id>", "External id of the related record").option("--external-source <src>", "External source of the related record").option("--relationship-id <id>", "Relationship id the error relates to").action(async function(opts) {
|
|
@@ -27707,7 +27949,7 @@ function buildBasesReportCommand() {
|
|
|
27707
27949
|
);
|
|
27708
27950
|
}
|
|
27709
27951
|
});
|
|
27710
|
-
|
|
27952
|
+
report2.command("list").description("List your reports, newest first").option("--status <s>", "Filter by status (e.g. shipped \u2014 awaiting your verification)").action(async function(opts) {
|
|
27711
27953
|
const client = await createDataClient();
|
|
27712
27954
|
const qs = opts.status ? `?status=${encodeURIComponent(opts.status)}` : "";
|
|
27713
27955
|
try {
|
|
@@ -27730,7 +27972,7 @@ function buildBasesReportCommand() {
|
|
|
27730
27972
|
reportActionError2(err);
|
|
27731
27973
|
}
|
|
27732
27974
|
});
|
|
27733
|
-
|
|
27975
|
+
report2.command("get <report_id>").description("Show one of your reports: status + the message thread").action(async function(reportId) {
|
|
27734
27976
|
const client = await createDataClient();
|
|
27735
27977
|
try {
|
|
27736
27978
|
const data = await client.request("GET", `/v1/reports/${pathSegment(reportId, "report id")}`);
|
|
@@ -27767,7 +28009,7 @@ function buildBasesReportCommand() {
|
|
|
27767
28009
|
reportActionError2(err);
|
|
27768
28010
|
}
|
|
27769
28011
|
});
|
|
27770
|
-
|
|
28012
|
+
report2.command("accept <report_id>").description("Accept a shipped fix (\u2192 addressed)").action(async function(reportId) {
|
|
27771
28013
|
const client = await createDataClient();
|
|
27772
28014
|
try {
|
|
27773
28015
|
const data = await client.request(
|
|
@@ -27783,7 +28025,7 @@ function buildBasesReportCommand() {
|
|
|
27783
28025
|
reportActionError2(err);
|
|
27784
28026
|
}
|
|
27785
28027
|
});
|
|
27786
|
-
|
|
28028
|
+
report2.command("contest <report_id>").description("Contest a shipped fix or a dismissal (\u2192 back to triage)").requiredOption("--reason <text>", "Why the fix/dismissal is wrong").action(async function(reportId, opts) {
|
|
27787
28029
|
const client = await createDataClient();
|
|
27788
28030
|
try {
|
|
27789
28031
|
const data = await client.request(
|
|
@@ -27802,7 +28044,7 @@ function buildBasesReportCommand() {
|
|
|
27802
28044
|
reportActionError2(err);
|
|
27803
28045
|
}
|
|
27804
28046
|
});
|
|
27805
|
-
return
|
|
28047
|
+
return report2;
|
|
27806
28048
|
}
|
|
27807
28049
|
var here;
|
|
27808
28050
|
var init_report2 = __esm({
|
|
@@ -27815,13 +28057,13 @@ var init_report2 = __esm({
|
|
|
27815
28057
|
init_terminal_output();
|
|
27816
28058
|
init_workspace();
|
|
27817
28059
|
init_skill_version();
|
|
27818
|
-
here =
|
|
28060
|
+
here = dirname12(fileURLToPath2(import.meta.url));
|
|
27819
28061
|
}
|
|
27820
28062
|
});
|
|
27821
28063
|
|
|
27822
28064
|
// src/data/commands/credentials.ts
|
|
27823
28065
|
import { Command as Command7 } from "commander";
|
|
27824
|
-
import { readFileSync as
|
|
28066
|
+
import { readFileSync as readFileSync22 } from "fs";
|
|
27825
28067
|
function withValueSourceOptions(cmd, what) {
|
|
27826
28068
|
return cmd.option(
|
|
27827
28069
|
"--file <path>",
|
|
@@ -27834,7 +28076,7 @@ async function resolveValue(opts, label) {
|
|
|
27834
28076
|
throw expected("--file cannot be combined with --value-stdin or --value-prompt \u2014 pass one.");
|
|
27835
28077
|
}
|
|
27836
28078
|
try {
|
|
27837
|
-
return
|
|
28079
|
+
return readFileSync22(opts.file).toString("base64");
|
|
27838
28080
|
} catch (e) {
|
|
27839
28081
|
throw expected(`--file ${opts.file}: ${e instanceof Error ? e.message : "could not be read"}`);
|
|
27840
28082
|
}
|
|
@@ -27983,7 +28225,7 @@ var init_credentials = __esm({
|
|
|
27983
28225
|
|
|
27984
28226
|
// src/data/commands/sql.ts
|
|
27985
28227
|
import { Command as Command8 } from "commander";
|
|
27986
|
-
import { readFileSync as
|
|
28228
|
+
import { readFileSync as readFileSync23 } from "fs";
|
|
27987
28229
|
function buildBasesSqlCommand() {
|
|
27988
28230
|
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(
|
|
27989
28231
|
"--param <kv...>",
|
|
@@ -27993,7 +28235,7 @@ function buildBasesSqlCommand() {
|
|
|
27993
28235
|
let query;
|
|
27994
28236
|
if (opts.file) {
|
|
27995
28237
|
try {
|
|
27996
|
-
query =
|
|
28238
|
+
query = readFileSync23(opts.file, "utf-8").trim();
|
|
27997
28239
|
} catch (e) {
|
|
27998
28240
|
throw expected(`--file ${opts.file}: ${e instanceof Error ? e.message : "could not be read"}`);
|
|
27999
28241
|
}
|
|
@@ -28648,7 +28890,7 @@ var init_file_types = __esm({
|
|
|
28648
28890
|
|
|
28649
28891
|
// src/data/commands/files.ts
|
|
28650
28892
|
import { Command as Command12 } from "commander";
|
|
28651
|
-
import { readFileSync as
|
|
28893
|
+
import { readFileSync as readFileSync24, writeFileSync as writeFileSync16 } from "fs";
|
|
28652
28894
|
import { basename as basename18 } from "path";
|
|
28653
28895
|
function renderFileDiff(fileType, filePath, from, to, d) {
|
|
28654
28896
|
console.log(sanitizeTerminalText(`${fileType}/${filePath}: v${from} \u2192 v${to}`));
|
|
@@ -28697,7 +28939,7 @@ function buildFilesCommand() {
|
|
|
28697
28939
|
"Upload a local file to a path (e.g. wayai files put reports q3/summary.pdf --file ./summary.pdf)"
|
|
28698
28940
|
).requiredOption("--file <local>", "Local file to upload").option("--content-type <type>", "MIME type", "application/octet-stream").action(async function(fileType, filePath, opts) {
|
|
28699
28941
|
const base = pathSegment(requireBase(this), "--base");
|
|
28700
|
-
const body =
|
|
28942
|
+
const body = readFileSync24(opts.file);
|
|
28701
28943
|
const client = await createDataClient();
|
|
28702
28944
|
printOutput(
|
|
28703
28945
|
await client.upload(
|
|
@@ -29658,7 +29900,7 @@ __export(program_exports, {
|
|
|
29658
29900
|
});
|
|
29659
29901
|
import { Command as Command22 } from "commander";
|
|
29660
29902
|
function withDataGlobals(command2) {
|
|
29661
|
-
return command2.option("--org <uuid>", "Organization to operate against (overrides
|
|
29903
|
+
return command2.option("--org <uuid>", "Organization to operate against (overrides the repo's org binding)").option("--output <format>", "Output format: json or table", "table").option("--json", "Shorthand for --output json");
|
|
29662
29904
|
}
|
|
29663
29905
|
function routeErrorsToCli(command2) {
|
|
29664
29906
|
command2.exitOverride().configureOutput({ outputError: () => {
|
|
@@ -29746,9 +29988,9 @@ init_errors2();
|
|
|
29746
29988
|
init_mask_secrets();
|
|
29747
29989
|
init_utils();
|
|
29748
29990
|
init_registry();
|
|
29749
|
-
import { readFileSync as
|
|
29991
|
+
import { readFileSync as readFileSync25 } from "fs";
|
|
29750
29992
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
29751
|
-
import { dirname as
|
|
29993
|
+
import { dirname as dirname13, join as join32 } from "path";
|
|
29752
29994
|
|
|
29753
29995
|
// src/lib/version-refresh.ts
|
|
29754
29996
|
init_version_cache();
|
|
@@ -29756,7 +29998,7 @@ init_skill_version();
|
|
|
29756
29998
|
import { exec } from "child_process";
|
|
29757
29999
|
var REFRESH_TIMEOUT_MS = 1e4;
|
|
29758
30000
|
function refreshCliCache() {
|
|
29759
|
-
return new Promise((
|
|
30001
|
+
return new Promise((resolve8) => {
|
|
29760
30002
|
exec("npm view @wayai/cli version", { timeout: REFRESH_TIMEOUT_MS }, (err, stdout) => {
|
|
29761
30003
|
if (!err) {
|
|
29762
30004
|
const latest = stdout.trim();
|
|
@@ -29767,7 +30009,7 @@ function refreshCliCache() {
|
|
|
29767
30009
|
}
|
|
29768
30010
|
}
|
|
29769
30011
|
}
|
|
29770
|
-
|
|
30012
|
+
resolve8();
|
|
29771
30013
|
});
|
|
29772
30014
|
});
|
|
29773
30015
|
}
|
|
@@ -29793,8 +30035,8 @@ async function refreshSkillCache() {
|
|
|
29793
30035
|
}
|
|
29794
30036
|
async function refreshAdminSkillCache() {
|
|
29795
30037
|
let timer;
|
|
29796
|
-
const deadline = new Promise((
|
|
29797
|
-
timer = setTimeout(
|
|
30038
|
+
const deadline = new Promise((resolve8) => {
|
|
30039
|
+
timer = setTimeout(resolve8, REFRESH_TIMEOUT_MS);
|
|
29798
30040
|
});
|
|
29799
30041
|
await Promise.race([deadline, fetchAndCacheAdminSkillVersion().catch(() => {
|
|
29800
30042
|
})]);
|
|
@@ -29903,8 +30145,8 @@ Run \`wayai admin skill install\` to update.`);
|
|
|
29903
30145
|
}
|
|
29904
30146
|
|
|
29905
30147
|
// src/index.ts
|
|
29906
|
-
var __dirname =
|
|
29907
|
-
var pkg = JSON.parse(
|
|
30148
|
+
var __dirname = dirname13(fileURLToPath3(import.meta.url));
|
|
30149
|
+
var pkg = JSON.parse(readFileSync25(join32(__dirname, "..", "package.json"), "utf-8"));
|
|
29908
30150
|
var [, , command, ...args] = process.argv;
|
|
29909
30151
|
var isBackgroundRefresh = command === REFRESH_COMMAND;
|
|
29910
30152
|
if (!isBackgroundRefresh) initSentry(command, pkg.version);
|
|
@@ -30139,7 +30381,7 @@ Commands:
|
|
|
30139
30381
|
logout Clear stored credentials
|
|
30140
30382
|
status Show current auth and config status
|
|
30141
30383
|
whoami Show the authenticated identity (supports --json)
|
|
30142
|
-
init
|
|
30384
|
+
init Scope this repo to an organization (pick one)
|
|
30143
30385
|
create-credential Create an organization credential (API key, token, etc.)
|
|
30144
30386
|
update-credential Update / rotate an organization credential (by name)
|
|
30145
30387
|
set-connection-credential Set a connection's credential directly (org link or --field/--stdin), preview or production
|
|
@@ -30222,7 +30464,7 @@ Flags:
|
|
|
30222
30464
|
--version, -v Show CLI version
|
|
30223
30465
|
|
|
30224
30466
|
Org-scoped mode:
|
|
30225
|
-
Each repository is scoped to a single organization via
|
|
30467
|
+
Each repository is scoped to a single organization via wayai-ws/wayai.yaml
|
|
30226
30468
|
(only \`organization_id\` is required). Hubs self-identify via \`hub.yaml\`
|
|
30227
30469
|
inside their folder under \`workspace/\`.
|
|
30228
30470
|
|