@wayai/cli 0.3.87 → 0.3.89
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 +532 -320
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -82,8 +82,8 @@ import { fileURLToPath } from "url";
|
|
|
82
82
|
import { homedir, platform, arch } from "os";
|
|
83
83
|
function getVersion() {
|
|
84
84
|
try {
|
|
85
|
-
const
|
|
86
|
-
const pkg2 = JSON.parse(readFileSync(join(
|
|
85
|
+
const __dirname2 = dirname(fileURLToPath(import.meta.url));
|
|
86
|
+
const pkg2 = JSON.parse(readFileSync(join(__dirname2, "..", "..", "package.json"), "utf-8"));
|
|
87
87
|
return pkg2.version || "0.0.0";
|
|
88
88
|
} catch {
|
|
89
89
|
return "0.0.0";
|
|
@@ -96,16 +96,16 @@ function isInstalledPackage() {
|
|
|
96
96
|
return false;
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
|
-
function initSentry(command2) {
|
|
99
|
+
function initSentry(command2, version) {
|
|
100
100
|
if (initialized) return;
|
|
101
101
|
if (process.env.WAYAI_TELEMETRY_DISABLED === "1") return;
|
|
102
102
|
const dsn = process.env.SENTRY_DSN || HARDCODED_DSN;
|
|
103
103
|
if (!process.env.SENTRY_DSN && !isInstalledPackage()) return;
|
|
104
|
-
const
|
|
104
|
+
const resolvedVersion = version ?? getVersion();
|
|
105
105
|
Sentry.init({
|
|
106
106
|
dsn,
|
|
107
107
|
tracesSampleRate: 0,
|
|
108
|
-
release: `wayai-cli@${
|
|
108
|
+
release: `wayai-cli@${resolvedVersion}`,
|
|
109
109
|
environment: "production",
|
|
110
110
|
defaultIntegrations: false,
|
|
111
111
|
beforeSend(event) {
|
|
@@ -165,11 +165,11 @@ function captureException2(error, context) {
|
|
|
165
165
|
Sentry.captureException(error);
|
|
166
166
|
});
|
|
167
167
|
}
|
|
168
|
-
function addApiBreadcrumb(method,
|
|
168
|
+
function addApiBreadcrumb(method, path26) {
|
|
169
169
|
if (!initialized) return;
|
|
170
170
|
Sentry.addBreadcrumb({
|
|
171
171
|
category: "http",
|
|
172
|
-
message: `${method} ${
|
|
172
|
+
message: `${method} ${path26}`,
|
|
173
173
|
level: "info"
|
|
174
174
|
});
|
|
175
175
|
}
|
|
@@ -227,13 +227,13 @@ var init_api_client = __esm({
|
|
|
227
227
|
init_sentry();
|
|
228
228
|
init_redact();
|
|
229
229
|
RETRYABLE_BACKOFF_MS = [500, 1e3, 2e3];
|
|
230
|
-
delay = (ms) => new Promise((
|
|
230
|
+
delay = (ms) => new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
231
231
|
ApiError = class extends Error {
|
|
232
232
|
status;
|
|
233
233
|
body;
|
|
234
|
-
constructor(method,
|
|
234
|
+
constructor(method, path26, status, body) {
|
|
235
235
|
const safeBody = redactSecrets(body);
|
|
236
|
-
super(`API request failed: ${method} ${
|
|
236
|
+
super(`API request failed: ${method} ${path26} (${status}): ${safeBody}`);
|
|
237
237
|
this.name = "ApiError";
|
|
238
238
|
this.status = status;
|
|
239
239
|
this.body = safeBody;
|
|
@@ -376,8 +376,8 @@ var init_api_client = __esm({
|
|
|
376
376
|
...organizationId && { organization_id: organizationId }
|
|
377
377
|
});
|
|
378
378
|
}
|
|
379
|
-
async lookup(
|
|
380
|
-
const params = new URLSearchParams({ path:
|
|
379
|
+
async lookup(path26, opts) {
|
|
380
|
+
const params = new URLSearchParams({ path: path26 });
|
|
381
381
|
if (opts?.organizationId) params.set("organization_id", opts.organizationId);
|
|
382
382
|
return this.request("GET", `/api/ci/lookup?${params.toString()}`);
|
|
383
383
|
}
|
|
@@ -765,9 +765,9 @@ var init_api_client = __esm({
|
|
|
765
765
|
* sandbox for this conversation, or the blob was purged).
|
|
766
766
|
*/
|
|
767
767
|
async downloadArchiveSandboxFs(hubId, conversationId) {
|
|
768
|
-
const
|
|
769
|
-
addApiBreadcrumb("GET",
|
|
770
|
-
const url = `${this.apiUrl}${
|
|
768
|
+
const path26 = `/api/archive/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}/sandbox`;
|
|
769
|
+
addApiBreadcrumb("GET", path26);
|
|
770
|
+
const url = `${this.apiUrl}${path26}`;
|
|
771
771
|
let response = await this.send(url, "GET");
|
|
772
772
|
if (response.status === 401 && this.onUnauthorized) {
|
|
773
773
|
let refreshed;
|
|
@@ -781,7 +781,7 @@ var init_api_client = __esm({
|
|
|
781
781
|
}
|
|
782
782
|
}
|
|
783
783
|
if (!response.ok) {
|
|
784
|
-
throw new ApiError("GET",
|
|
784
|
+
throw new ApiError("GET", path26, response.status, await response.text());
|
|
785
785
|
}
|
|
786
786
|
return new Uint8Array(await response.arrayBuffer());
|
|
787
787
|
}
|
|
@@ -821,9 +821,9 @@ var init_api_client = __esm({
|
|
|
821
821
|
`/api/admin/data-explorer/debug/observability/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}${qs}`
|
|
822
822
|
);
|
|
823
823
|
}
|
|
824
|
-
async request(method,
|
|
825
|
-
addApiBreadcrumb(method,
|
|
826
|
-
const url = `${this.apiUrl}${
|
|
824
|
+
async request(method, path26, body) {
|
|
825
|
+
addApiBreadcrumb(method, path26);
|
|
826
|
+
const url = `${this.apiUrl}${path26}`;
|
|
827
827
|
let refreshedOn401 = false;
|
|
828
828
|
for (let retry = 0; ; retry++) {
|
|
829
829
|
let response = await this.send(url, method, body);
|
|
@@ -847,7 +847,7 @@ var init_api_client = __esm({
|
|
|
847
847
|
await delay(RETRYABLE_BACKOFF_MS[retry]);
|
|
848
848
|
continue;
|
|
849
849
|
}
|
|
850
|
-
throw new ApiError(method,
|
|
850
|
+
throw new ApiError(method, path26, response.status, errorBody);
|
|
851
851
|
}
|
|
852
852
|
}
|
|
853
853
|
/** Issue a single authenticated request with the client's current token. */
|
|
@@ -1282,8 +1282,8 @@ var init_parseUtil = __esm({
|
|
|
1282
1282
|
init_errors();
|
|
1283
1283
|
init_en();
|
|
1284
1284
|
makeIssue = (params) => {
|
|
1285
|
-
const { data, path:
|
|
1286
|
-
const fullPath = [...
|
|
1285
|
+
const { data, path: path26, errorMaps, issueData } = params;
|
|
1286
|
+
const fullPath = [...path26, ...issueData.path || []];
|
|
1287
1287
|
const fullIssue = {
|
|
1288
1288
|
...issueData,
|
|
1289
1289
|
path: fullPath
|
|
@@ -1594,11 +1594,11 @@ var init_types = __esm({
|
|
|
1594
1594
|
init_parseUtil();
|
|
1595
1595
|
init_util();
|
|
1596
1596
|
ParseInputLazyPath = class {
|
|
1597
|
-
constructor(parent, value,
|
|
1597
|
+
constructor(parent, value, path26, key) {
|
|
1598
1598
|
this._cachedPath = [];
|
|
1599
1599
|
this.parent = parent;
|
|
1600
1600
|
this.data = value;
|
|
1601
|
-
this._path =
|
|
1601
|
+
this._path = path26;
|
|
1602
1602
|
this._key = key;
|
|
1603
1603
|
}
|
|
1604
1604
|
get path() {
|
|
@@ -5052,12 +5052,12 @@ function typeMatches(typeField, allowed) {
|
|
|
5052
5052
|
if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
|
|
5053
5053
|
return false;
|
|
5054
5054
|
}
|
|
5055
|
-
function validateSchema(schema,
|
|
5055
|
+
function validateSchema(schema, path26, errors, opts = {}) {
|
|
5056
5056
|
if (typeof schema === "boolean") return;
|
|
5057
5057
|
const depth = opts.depth ?? 0;
|
|
5058
5058
|
if (depth > MAX_SCHEMA_DEPTH) {
|
|
5059
5059
|
errors.push({
|
|
5060
|
-
path:
|
|
5060
|
+
path: path26 || "<root>",
|
|
5061
5061
|
message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH} levels`,
|
|
5062
5062
|
suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
|
|
5063
5063
|
});
|
|
@@ -5065,7 +5065,7 @@ function validateSchema(schema, path25, errors, opts = {}) {
|
|
|
5065
5065
|
}
|
|
5066
5066
|
if (!isRecord(schema)) {
|
|
5067
5067
|
errors.push({
|
|
5068
|
-
path:
|
|
5068
|
+
path: path26,
|
|
5069
5069
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
5070
5070
|
});
|
|
5071
5071
|
return;
|
|
@@ -5073,14 +5073,14 @@ function validateSchema(schema, path25, errors, opts = {}) {
|
|
|
5073
5073
|
if (opts.isRoot) {
|
|
5074
5074
|
if ("type" in schema && schema.type !== "object") {
|
|
5075
5075
|
errors.push({
|
|
5076
|
-
path:
|
|
5076
|
+
path: path26 ? `${path26}.type` : "type",
|
|
5077
5077
|
message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
|
|
5078
5078
|
suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
|
|
5079
5079
|
});
|
|
5080
5080
|
}
|
|
5081
5081
|
} else if ("type" in schema && !typeMatches(schema.type, ALLOWED_TYPES)) {
|
|
5082
5082
|
errors.push({
|
|
5083
|
-
path: `${
|
|
5083
|
+
path: `${path26}.type`,
|
|
5084
5084
|
message: `type must be one of ${[...ALLOWED_TYPES].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
|
|
5085
5085
|
});
|
|
5086
5086
|
}
|
|
@@ -5089,25 +5089,25 @@ function validateSchema(schema, path25, errors, opts = {}) {
|
|
|
5089
5089
|
if (typeof e === "string") {
|
|
5090
5090
|
const isPlaceholder = PLACEHOLDER_TOKENS.includes(e);
|
|
5091
5091
|
errors.push({
|
|
5092
|
-
path: `${
|
|
5092
|
+
path: `${path26}.enum`,
|
|
5093
5093
|
message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
|
|
5094
5094
|
suggestion: isPlaceholder ? "Set `operation: 'update_kanban_status'` on the tool and ensure at least one hub.kanban_status has `allowsAgentUpdate: true` so the platform can render the placeholder into a valid array." : 'Wrap the value in an array: `enum: ["value"]`.'
|
|
5095
5095
|
});
|
|
5096
5096
|
} else if (!Array.isArray(e)) {
|
|
5097
5097
|
errors.push({
|
|
5098
|
-
path: `${
|
|
5098
|
+
path: `${path26}.enum`,
|
|
5099
5099
|
message: `enum must be a non-empty array of primitives, got ${typeof e}`
|
|
5100
5100
|
});
|
|
5101
5101
|
} else if (e.length === 0) {
|
|
5102
5102
|
errors.push({
|
|
5103
|
-
path: `${
|
|
5103
|
+
path: `${path26}.enum`,
|
|
5104
5104
|
message: "enum must not be empty"
|
|
5105
5105
|
});
|
|
5106
5106
|
} else {
|
|
5107
5107
|
for (let i = 0; i < e.length; i++) {
|
|
5108
5108
|
if (!isPrimitive(e[i])) {
|
|
5109
5109
|
errors.push({
|
|
5110
|
-
path: `${
|
|
5110
|
+
path: `${path26}.enum[${i}]`,
|
|
5111
5111
|
message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
|
|
5112
5112
|
});
|
|
5113
5113
|
}
|
|
@@ -5117,7 +5117,7 @@ function validateSchema(schema, path25, errors, opts = {}) {
|
|
|
5117
5117
|
for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
|
|
5118
5118
|
if (key in schema && typeof schema[key] === "boolean") {
|
|
5119
5119
|
errors.push({
|
|
5120
|
-
path: `${
|
|
5120
|
+
path: `${path26}.${key}`,
|
|
5121
5121
|
message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
|
|
5122
5122
|
suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
|
|
5123
5123
|
});
|
|
@@ -5126,45 +5126,45 @@ function validateSchema(schema, path25, errors, opts = {}) {
|
|
|
5126
5126
|
if ("properties" in schema) {
|
|
5127
5127
|
if (!isRecord(schema.properties)) {
|
|
5128
5128
|
errors.push({
|
|
5129
|
-
path: `${
|
|
5129
|
+
path: `${path26}.properties`,
|
|
5130
5130
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
5131
5131
|
});
|
|
5132
5132
|
} else {
|
|
5133
5133
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
5134
|
-
validateSchema(propSchema, `${
|
|
5134
|
+
validateSchema(propSchema, `${path26}.properties.${propName}`, errors, { depth: depth + 1 });
|
|
5135
5135
|
}
|
|
5136
5136
|
}
|
|
5137
5137
|
}
|
|
5138
5138
|
if (schemaTypeIncludes(schema, "array") && "items" in schema) {
|
|
5139
5139
|
if (Array.isArray(schema.items)) {
|
|
5140
|
-
schema.items.forEach((sub, i) => validateSchema(sub, `${
|
|
5140
|
+
schema.items.forEach((sub, i) => validateSchema(sub, `${path26}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
5141
5141
|
} else {
|
|
5142
|
-
validateSchema(schema.items, `${
|
|
5142
|
+
validateSchema(schema.items, `${path26}.items`, errors, { depth: depth + 1 });
|
|
5143
5143
|
}
|
|
5144
5144
|
}
|
|
5145
5145
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS) {
|
|
5146
5146
|
if (key in schema && isRecord(schema[key])) {
|
|
5147
|
-
validateSchema(schema[key], `${
|
|
5147
|
+
validateSchema(schema[key], `${path26}.${key}`, errors, { depth: depth + 1 });
|
|
5148
5148
|
}
|
|
5149
5149
|
}
|
|
5150
5150
|
for (const key of SUBSCHEMA_LIST_KEYWORDS) {
|
|
5151
5151
|
const list = schema[key];
|
|
5152
5152
|
if (Array.isArray(list)) {
|
|
5153
|
-
list.forEach((sub, i) => validateSchema(sub, `${
|
|
5153
|
+
list.forEach((sub, i) => validateSchema(sub, `${path26}.${key}[${i}]`, errors, { depth: depth + 1 }));
|
|
5154
5154
|
}
|
|
5155
5155
|
}
|
|
5156
5156
|
for (const key of SUBSCHEMA_MAP_KEYWORDS) {
|
|
5157
5157
|
const map = schema[key];
|
|
5158
5158
|
if (isRecord(map)) {
|
|
5159
5159
|
for (const [name, sub] of Object.entries(map)) {
|
|
5160
|
-
validateSchema(sub, `${
|
|
5160
|
+
validateSchema(sub, `${path26}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
5161
5161
|
}
|
|
5162
5162
|
}
|
|
5163
5163
|
}
|
|
5164
5164
|
const reportedPaths = new Set(errors.map((e) => e.path));
|
|
5165
5165
|
for (const [k, v] of Object.entries(schema)) {
|
|
5166
5166
|
if (typeof v !== "string") continue;
|
|
5167
|
-
const fieldPath = `${
|
|
5167
|
+
const fieldPath = `${path26}.${k}`;
|
|
5168
5168
|
if (reportedPaths.has(fieldPath)) continue;
|
|
5169
5169
|
for (const token of PLACEHOLDER_TOKENS) {
|
|
5170
5170
|
if (v === token) {
|
|
@@ -5320,10 +5320,10 @@ function refineHubAsCodeLanes(config, ctx) {
|
|
|
5320
5320
|
}
|
|
5321
5321
|
}
|
|
5322
5322
|
}
|
|
5323
|
-
function isSafeTemplatePath(
|
|
5324
|
-
if (
|
|
5325
|
-
if (
|
|
5326
|
-
const segments =
|
|
5323
|
+
function isSafeTemplatePath(path26) {
|
|
5324
|
+
if (path26.length === 0 || path26.length > 300) return false;
|
|
5325
|
+
if (path26.startsWith("/") || path26.includes("\\")) return false;
|
|
5326
|
+
const segments = path26.split("/");
|
|
5327
5327
|
return segments.every(
|
|
5328
5328
|
(seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
|
|
5329
5329
|
);
|
|
@@ -5916,7 +5916,7 @@ var init_dist = __esm({
|
|
|
5916
5916
|
// at fallback time in the turn seam (a stale/missing id simply no-ops). Nullable to clear it.
|
|
5917
5917
|
fallback_connection_id: uuidSchema.nullable().optional(),
|
|
5918
5918
|
// Rekor API connection used to reset/clear eval seed fixtures (gh #3090). A
|
|
5919
|
-
// connection id on this hub (a REST API
|
|
5919
|
+
// connection id on this hub (a REST API (custom tool) connection whose base_url
|
|
5920
5920
|
// is the Rekor API origin + a bearer/api_key `write:seeds` token). Validated at
|
|
5921
5921
|
// set-time on the REST PATCH (setup/hubs.ts). Nullable to clear it.
|
|
5922
5922
|
seed_connection_id: uuidSchema.nullable().optional()
|
|
@@ -8129,6 +8129,7 @@ __export(workspace_exports, {
|
|
|
8129
8129
|
detectWorkspace: () => detectWorkspace,
|
|
8130
8130
|
filterPreviewHubs: () => filterPreviewHubs,
|
|
8131
8131
|
findEnclosingHubFolder: () => findEnclosingHubFolder,
|
|
8132
|
+
findEnclosingNewHubFolder: () => findEnclosingNewHubFolder,
|
|
8132
8133
|
findGitRoot: () => findGitRoot,
|
|
8133
8134
|
findHubByFolderName: () => findHubByFolderName,
|
|
8134
8135
|
findLocalHubFolder: () => findLocalHubFolder,
|
|
@@ -8141,6 +8142,8 @@ __export(workspace_exports, {
|
|
|
8141
8142
|
resolveExplicitHubPath: () => resolveExplicitHubPath,
|
|
8142
8143
|
resolveHubFolder: () => resolveHubFolder,
|
|
8143
8144
|
resolveHubFolderBySelector: () => resolveHubFolderBySelector,
|
|
8145
|
+
resolveNewHubForCreate: () => resolveNewHubForCreate,
|
|
8146
|
+
resolvePushTarget: () => resolvePushTarget,
|
|
8144
8147
|
resolveWorkspaceDir: () => resolveWorkspaceDir,
|
|
8145
8148
|
scanNewHubs: () => scanNewHubs,
|
|
8146
8149
|
scanWorkspaceHubs: () => scanWorkspaceHubs
|
|
@@ -8383,6 +8386,56 @@ function findEnclosingHubFolder(workspaceDir) {
|
|
|
8383
8386
|
current = parent;
|
|
8384
8387
|
}
|
|
8385
8388
|
}
|
|
8389
|
+
function findEnclosingNewHubFolder(workspaceDir) {
|
|
8390
|
+
let current = process.cwd();
|
|
8391
|
+
const stop = path2.resolve(workspaceDir);
|
|
8392
|
+
while (true) {
|
|
8393
|
+
const meta = readNewHubYaml(path2.join(current, "hub.yaml")) || readNewHubYaml(path2.join(current, "wayai.yaml"));
|
|
8394
|
+
if (meta) {
|
|
8395
|
+
return { hubFolder: current, hubName: meta.hubName, hubType: meta.hubType };
|
|
8396
|
+
}
|
|
8397
|
+
if (current === stop) return null;
|
|
8398
|
+
const parent = path2.dirname(current);
|
|
8399
|
+
if (parent === current) return null;
|
|
8400
|
+
current = parent;
|
|
8401
|
+
}
|
|
8402
|
+
}
|
|
8403
|
+
function resolvePushTarget(workspaceDir, existingHubs, newHubs, selector) {
|
|
8404
|
+
if (selector) {
|
|
8405
|
+
const existingMatch = existingHubs.find(
|
|
8406
|
+
(h) => h.hubId === selector || path2.basename(h.hubFolder) === selector
|
|
8407
|
+
);
|
|
8408
|
+
if (existingMatch) return { ok: true, target: { kind: "existing", hub: existingMatch } };
|
|
8409
|
+
const newMatch = newHubs.find((h) => path2.basename(h.hubFolder) === selector);
|
|
8410
|
+
if (newMatch) return { ok: true, target: { kind: "new", hub: newMatch } };
|
|
8411
|
+
return { ok: false, reason: "selector_miss" };
|
|
8412
|
+
}
|
|
8413
|
+
const enclosingExisting = findEnclosingHubFolder(workspaceDir);
|
|
8414
|
+
if (enclosingExisting) return { ok: true, target: { kind: "existing", hub: enclosingExisting } };
|
|
8415
|
+
const enclosingNew = findEnclosingNewHubFolder(workspaceDir);
|
|
8416
|
+
if (enclosingNew) return { ok: true, target: { kind: "new", hub: enclosingNew } };
|
|
8417
|
+
const previewHubs = filterPreviewHubs(existingHubs);
|
|
8418
|
+
const total = previewHubs.length + newHubs.length;
|
|
8419
|
+
if (total === 0) return { ok: false, reason: "none" };
|
|
8420
|
+
if (total > 1) return { ok: false, reason: "ambiguous" };
|
|
8421
|
+
return previewHubs.length === 1 ? { ok: true, target: { kind: "existing", hub: previewHubs[0] } } : { ok: true, target: { kind: "new", hub: newHubs[0] } };
|
|
8422
|
+
}
|
|
8423
|
+
function resolveNewHubForCreate(workspaceDir, existingHubs, newHubs, selector) {
|
|
8424
|
+
if (selector) {
|
|
8425
|
+
const newMatch = newHubs.find((h) => path2.basename(h.hubFolder) === selector);
|
|
8426
|
+
if (newMatch) return { ok: true, hub: newMatch };
|
|
8427
|
+
const existingMatch = existingHubs.find(
|
|
8428
|
+
(h) => h.hubId === selector || path2.basename(h.hubFolder) === selector
|
|
8429
|
+
);
|
|
8430
|
+
if (existingMatch) return { ok: false, reason: "exists", existing: existingMatch };
|
|
8431
|
+
return { ok: false, reason: "selector_miss" };
|
|
8432
|
+
}
|
|
8433
|
+
const enclosingNew = findEnclosingNewHubFolder(workspaceDir);
|
|
8434
|
+
if (enclosingNew) return { ok: true, hub: enclosingNew };
|
|
8435
|
+
if (newHubs.length === 1) return { ok: true, hub: newHubs[0] };
|
|
8436
|
+
if (newHubs.length === 0) return { ok: false, reason: "none" };
|
|
8437
|
+
return { ok: false, reason: "ambiguous" };
|
|
8438
|
+
}
|
|
8386
8439
|
function resolveActiveHubId(args2) {
|
|
8387
8440
|
let selector;
|
|
8388
8441
|
const hubIdx = args2.indexOf("--hub");
|
|
@@ -8537,24 +8590,24 @@ import * as path4 from "path";
|
|
|
8537
8590
|
import * as readline from "readline";
|
|
8538
8591
|
function prompt(question) {
|
|
8539
8592
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
8540
|
-
return new Promise((
|
|
8593
|
+
return new Promise((resolve4) => {
|
|
8541
8594
|
rl.question(question, (answer) => {
|
|
8542
8595
|
rl.close();
|
|
8543
|
-
|
|
8596
|
+
resolve4(answer.trim());
|
|
8544
8597
|
});
|
|
8545
8598
|
});
|
|
8546
8599
|
}
|
|
8547
8600
|
function confirm(question) {
|
|
8548
8601
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
8549
|
-
return new Promise((
|
|
8602
|
+
return new Promise((resolve4) => {
|
|
8550
8603
|
rl.question(`${question} [y/N]: `, (answer) => {
|
|
8551
8604
|
rl.close();
|
|
8552
|
-
|
|
8605
|
+
resolve4(answer.trim().toLowerCase() === "y");
|
|
8553
8606
|
});
|
|
8554
8607
|
});
|
|
8555
8608
|
}
|
|
8556
8609
|
function promptSecret(question) {
|
|
8557
|
-
return new Promise((
|
|
8610
|
+
return new Promise((resolve4) => {
|
|
8558
8611
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
8559
8612
|
const originalWrite = rl._writeToOutput;
|
|
8560
8613
|
let firstWrite = true;
|
|
@@ -8570,18 +8623,18 @@ function promptSecret(question) {
|
|
|
8570
8623
|
rl._writeToOutput = originalWrite;
|
|
8571
8624
|
process.stdout.write("\n");
|
|
8572
8625
|
rl.close();
|
|
8573
|
-
|
|
8626
|
+
resolve4(answer);
|
|
8574
8627
|
});
|
|
8575
8628
|
});
|
|
8576
8629
|
}
|
|
8577
8630
|
function readStdin() {
|
|
8578
|
-
return new Promise((
|
|
8631
|
+
return new Promise((resolve4, reject) => {
|
|
8579
8632
|
let data = "";
|
|
8580
8633
|
process.stdin.setEncoding("utf-8");
|
|
8581
8634
|
process.stdin.on("data", (chunk) => {
|
|
8582
8635
|
data += chunk;
|
|
8583
8636
|
});
|
|
8584
|
-
process.stdin.on("end", () =>
|
|
8637
|
+
process.stdin.on("end", () => resolve4(data.trim()));
|
|
8585
8638
|
process.stdin.on("error", reject);
|
|
8586
8639
|
});
|
|
8587
8640
|
}
|
|
@@ -8742,9 +8795,9 @@ function getVersionCachePath(filename = CLI_CACHE_FILE) {
|
|
|
8742
8795
|
}
|
|
8743
8796
|
function readVersionCache(filename = CLI_CACHE_FILE) {
|
|
8744
8797
|
try {
|
|
8745
|
-
const
|
|
8746
|
-
if (!existsSync4(
|
|
8747
|
-
const parsed = JSON.parse(readFileSync5(
|
|
8798
|
+
const path26 = getVersionCachePath(filename);
|
|
8799
|
+
if (!existsSync4(path26)) return null;
|
|
8800
|
+
const parsed = JSON.parse(readFileSync5(path26, "utf-8"));
|
|
8748
8801
|
if (typeof parsed.lastCheck !== "number") return null;
|
|
8749
8802
|
if (parsed.latest !== null && typeof parsed.latest !== "string") return null;
|
|
8750
8803
|
return parsed;
|
|
@@ -8764,10 +8817,10 @@ function isVersionCacheStale(filename = CLI_CACHE_FILE, maxAgeMs = MAX_AGE_24H_M
|
|
|
8764
8817
|
return Date.now() - cache.lastCheck > maxAgeMs;
|
|
8765
8818
|
}
|
|
8766
8819
|
function writeVersionCache(filename, cache) {
|
|
8767
|
-
const
|
|
8768
|
-
const dir = dirname3(
|
|
8820
|
+
const path26 = getVersionCachePath(filename);
|
|
8821
|
+
const dir = dirname3(path26);
|
|
8769
8822
|
if (!existsSync4(dir)) mkdirSync(dir, { recursive: true });
|
|
8770
|
-
writeFileSync2(
|
|
8823
|
+
writeFileSync2(path26, JSON.stringify(cache));
|
|
8771
8824
|
}
|
|
8772
8825
|
function touchVersionCache(filename) {
|
|
8773
8826
|
writeVersionCache(filename, { lastCheck: Date.now(), latest: readVersionCache(filename)?.latest ?? null });
|
|
@@ -8806,14 +8859,14 @@ function parseFrontmatterVersion(content) {
|
|
|
8806
8859
|
function findInstalledSkills(projectRoot, paths = SKILL_INSTALL_PATHS) {
|
|
8807
8860
|
const found = [];
|
|
8808
8861
|
for (const rel of paths) {
|
|
8809
|
-
const
|
|
8810
|
-
if (!existsSync5(
|
|
8862
|
+
const path26 = join7(projectRoot, rel);
|
|
8863
|
+
if (!existsSync5(path26)) continue;
|
|
8811
8864
|
let version = null;
|
|
8812
8865
|
try {
|
|
8813
|
-
version = parseFrontmatterVersion(readFileSync6(
|
|
8866
|
+
version = parseFrontmatterVersion(readFileSync6(path26, "utf-8"));
|
|
8814
8867
|
} catch {
|
|
8815
8868
|
}
|
|
8816
|
-
found.push({ path:
|
|
8869
|
+
found.push({ path: path26, version });
|
|
8817
8870
|
}
|
|
8818
8871
|
return found;
|
|
8819
8872
|
}
|
|
@@ -9274,7 +9327,7 @@ async function validateToken(apiUrl, token) {
|
|
|
9274
9327
|
}
|
|
9275
9328
|
}
|
|
9276
9329
|
function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
9277
|
-
return new Promise((
|
|
9330
|
+
return new Promise((resolve4, reject) => {
|
|
9278
9331
|
const server = http.createServer((req, res) => {
|
|
9279
9332
|
const url = new URL(req.url || "/", `http://127.0.0.1:${port}`);
|
|
9280
9333
|
if (url.pathname === "/callback") {
|
|
@@ -9300,7 +9353,7 @@ function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
|
9300
9353
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
9301
9354
|
res.end("<html><body><h2>Login successful!</h2><p>You can close this tab and return to your terminal.</p></body></html>");
|
|
9302
9355
|
server.close();
|
|
9303
|
-
|
|
9356
|
+
resolve4({ code, port });
|
|
9304
9357
|
} else {
|
|
9305
9358
|
res.writeHead(400, { "Content-Type": "text/html" });
|
|
9306
9359
|
res.end("<html><body><h2>Login failed</h2><p>No authorization code received</p></body></html>");
|
|
@@ -9510,10 +9563,10 @@ import * as readline2 from "readline";
|
|
|
9510
9563
|
function prompt2(question, defaultValue) {
|
|
9511
9564
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
9512
9565
|
const display = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
|
|
9513
|
-
return new Promise((
|
|
9566
|
+
return new Promise((resolve4) => {
|
|
9514
9567
|
rl.question(display, (answer) => {
|
|
9515
9568
|
rl.close();
|
|
9516
|
-
|
|
9569
|
+
resolve4(answer.trim() || defaultValue || "");
|
|
9517
9570
|
});
|
|
9518
9571
|
});
|
|
9519
9572
|
}
|
|
@@ -9631,8 +9684,8 @@ async function tryOpenBrowser(url) {
|
|
|
9631
9684
|
cmd = "xdg-open";
|
|
9632
9685
|
args2 = [url];
|
|
9633
9686
|
}
|
|
9634
|
-
return new Promise((
|
|
9635
|
-
execFile(cmd, args2, (err) =>
|
|
9687
|
+
return new Promise((resolve4) => {
|
|
9688
|
+
execFile(cmd, args2, (err) => resolve4(!err));
|
|
9636
9689
|
});
|
|
9637
9690
|
} catch {
|
|
9638
9691
|
return false;
|
|
@@ -11270,9 +11323,11 @@ var init_pull = __esm({
|
|
|
11270
11323
|
var push_exports = {};
|
|
11271
11324
|
__export(push_exports, {
|
|
11272
11325
|
autoRenameAgentFiles: () => autoRenameAgentFiles,
|
|
11326
|
+
createAndPushNewHub: () => createAndPushNewHub,
|
|
11273
11327
|
printSyncResult: () => printSyncResult,
|
|
11274
11328
|
printWarnings: () => printWarnings,
|
|
11275
11329
|
pushCommand: () => pushCommand,
|
|
11330
|
+
reportUnresolvedPushTarget: () => reportUnresolvedPushTarget,
|
|
11276
11331
|
selectExistingHub: () => selectExistingHub,
|
|
11277
11332
|
shouldWarnIgnoredPreviewLabel: () => shouldWarnIgnoredPreviewLabel
|
|
11278
11333
|
});
|
|
@@ -11558,67 +11613,11 @@ function selectExistingHub(workspaceDir, allHubs, selector, wsLabel) {
|
|
|
11558
11613
|
if (previewHubs.length === 1) return previewHubs[0];
|
|
11559
11614
|
return null;
|
|
11560
11615
|
}
|
|
11561
|
-
function
|
|
11562
|
-
if (selector) {
|
|
11563
|
-
const match = newHubs.find((h) => path14.basename(h.hubFolder) === selector);
|
|
11564
|
-
if (!match) return null;
|
|
11565
|
-
return match;
|
|
11566
|
-
}
|
|
11567
|
-
const cwd = process.cwd();
|
|
11568
|
-
const cwdMatch = newHubs.find((h) => path14.resolve(h.hubFolder) === path14.resolve(cwd));
|
|
11569
|
-
if (cwdMatch) return cwdMatch;
|
|
11570
|
-
if (newHubs.length === 1) return newHubs[0];
|
|
11571
|
-
return null;
|
|
11572
|
-
}
|
|
11573
|
-
async function pushCommand(args2) {
|
|
11574
|
-
const { autoConfirm, hubSelector, label } = parseArgs5(args2);
|
|
11575
|
-
const repoConfig = requireRepoConfig();
|
|
11576
|
-
const { organization_id: organizationId } = repoConfig;
|
|
11577
|
-
const { config, accessToken } = await requireAuth();
|
|
11578
|
-
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
11579
|
-
const workspaceDir = resolveWorkspaceDir();
|
|
11580
|
-
const gitRoot = findGitRoot();
|
|
11581
|
-
const wsLabel = hubsDirLabel(gitRoot);
|
|
11582
|
-
if (gitRoot) warnLayoutOnce(gitRoot);
|
|
11583
|
-
if (!fs12.existsSync(workspaceDir)) {
|
|
11584
|
-
console.error(`No ${wsLabel}/ directory found. Run \`wayai pull\` first or create hub files in ${wsLabel}/<hub>/hub.yaml.`);
|
|
11585
|
-
process.exit(1);
|
|
11586
|
-
}
|
|
11587
|
-
const existingHubs = scanWorkspaceHubs(workspaceDir);
|
|
11588
|
-
const newHubs = scanNewHubs(workspaceDir);
|
|
11589
|
-
const existing = selectExistingHub(workspaceDir, existingHubs, hubSelector, wsLabel);
|
|
11590
|
-
if (existing) {
|
|
11591
|
-
if (existing.hubEnvironment === "production") {
|
|
11592
|
-
console.log("This is a read-only production mirror \u2014 production hubs cannot be pushed. Edit the linked preview hub instead.");
|
|
11593
|
-
return;
|
|
11594
|
-
}
|
|
11595
|
-
if (label) {
|
|
11596
|
-
console.warn("Note: --label is only used when creating a new hub. To change an existing hub's label, use `wayai relabel`.");
|
|
11597
|
-
}
|
|
11598
|
-
assertHubMatchesBinding(existing.hubId, path14.basename(existing.hubFolder));
|
|
11599
|
-
await pushSingleHub(client, existing.hubId, existing.hubFolder, autoConfirm, organizationId);
|
|
11600
|
-
return;
|
|
11601
|
-
}
|
|
11602
|
-
const newHub = selectNewHub(newHubs, hubSelector);
|
|
11603
|
-
if (!newHub) {
|
|
11604
|
-
if (existingHubs.length === 0 && newHubs.length === 0) {
|
|
11605
|
-
console.error(`No hub folders found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` and run \`wayai push\`.`);
|
|
11606
|
-
process.exit(1);
|
|
11607
|
-
}
|
|
11608
|
-
console.error(`Multiple hub folders found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
|
|
11609
|
-
for (const h of existingHubs) {
|
|
11610
|
-
console.error(` ${path14.basename(h.hubFolder)} (${h.hubId})`);
|
|
11611
|
-
}
|
|
11612
|
-
for (const h of newHubs) {
|
|
11613
|
-
console.error(` ${path14.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
|
|
11614
|
-
}
|
|
11615
|
-
process.exit(1);
|
|
11616
|
-
}
|
|
11617
|
-
assertNoBindingBlocksHubCreation(newHub.hubName);
|
|
11616
|
+
async function createAndPushNewHub(client, newHub, opts) {
|
|
11618
11617
|
const hubType = newHub.hubType || "chat";
|
|
11619
11618
|
console.log(`
|
|
11620
|
-
New hub
|
|
11621
|
-
if (!autoConfirm) {
|
|
11619
|
+
New hub: "${newHub.hubName}" (${hubType})`);
|
|
11620
|
+
if (!opts.autoConfirm) {
|
|
11622
11621
|
const ok = await confirm("Create this hub on the platform?");
|
|
11623
11622
|
if (!ok) {
|
|
11624
11623
|
console.log("Cancelled.");
|
|
@@ -11631,10 +11630,10 @@ New hub detected: "${newHub.hubName}" (${hubType})`);
|
|
|
11631
11630
|
process.exit(1);
|
|
11632
11631
|
}
|
|
11633
11632
|
console.log("Creating hub...");
|
|
11634
|
-
const createResult = await client.createHub(organizationId, {
|
|
11633
|
+
const createResult = await client.createHub(opts.organizationId, {
|
|
11635
11634
|
hubName: newHub.hubName,
|
|
11636
11635
|
hubType,
|
|
11637
|
-
previewLabel: label?.trim() || void 0
|
|
11636
|
+
previewLabel: opts.label?.trim() || void 0
|
|
11638
11637
|
});
|
|
11639
11638
|
const createdHub = createResult.data[0];
|
|
11640
11639
|
const hubId = createdHub.hub_id;
|
|
@@ -11661,7 +11660,69 @@ ${content}`;
|
|
|
11661
11660
|
}
|
|
11662
11661
|
fs12.writeFileSync(hubYamlPath, updated, "utf-8");
|
|
11663
11662
|
autoBindIfUnbound(hubId);
|
|
11664
|
-
await pushSingleHub(client, hubId, newHub.hubFolder, autoConfirm, organizationId, { skipAgentRename: true });
|
|
11663
|
+
await pushSingleHub(client, hubId, newHub.hubFolder, opts.autoConfirm, opts.organizationId, { skipAgentRename: true });
|
|
11664
|
+
}
|
|
11665
|
+
function reportUnresolvedPushTarget(reason, existingHubs, newHubs, selector, wsLabel) {
|
|
11666
|
+
if (reason === "none") {
|
|
11667
|
+
if (existingHubs.length > 0) {
|
|
11668
|
+
console.error(`No pushable hub found in ${wsLabel}/ \u2014 only read-only production mirror folder(s). Edit the linked preview hub, pull one, or create a new hub with \`wayai create\`:`);
|
|
11669
|
+
for (const h of existingHubs) {
|
|
11670
|
+
console.error(` ${path14.basename(h.hubFolder)} (${h.hubId}, production mirror)`);
|
|
11671
|
+
}
|
|
11672
|
+
} else {
|
|
11673
|
+
console.error(`No hub folders found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` and run \`wayai push\` (or \`wayai create\`).`);
|
|
11674
|
+
}
|
|
11675
|
+
process.exit(1);
|
|
11676
|
+
}
|
|
11677
|
+
if (reason === "selector_miss") {
|
|
11678
|
+
console.error(`No hub matching --hub ${selector} found in ${wsLabel}/. Available:`);
|
|
11679
|
+
} else {
|
|
11680
|
+
console.error(`Multiple hub folders found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
|
|
11681
|
+
}
|
|
11682
|
+
for (const h of existingHubs) {
|
|
11683
|
+
console.error(` ${path14.basename(h.hubFolder)} (${h.hubId})`);
|
|
11684
|
+
}
|
|
11685
|
+
for (const h of newHubs) {
|
|
11686
|
+
console.error(` ${path14.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
|
|
11687
|
+
}
|
|
11688
|
+
process.exit(1);
|
|
11689
|
+
}
|
|
11690
|
+
async function pushCommand(args2) {
|
|
11691
|
+
const { autoConfirm, hubSelector, label } = parseArgs5(args2);
|
|
11692
|
+
const repoConfig = requireRepoConfig();
|
|
11693
|
+
const { organization_id: organizationId } = repoConfig;
|
|
11694
|
+
const { config, accessToken } = await requireAuth();
|
|
11695
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
11696
|
+
const workspaceDir = resolveWorkspaceDir();
|
|
11697
|
+
const gitRoot = findGitRoot();
|
|
11698
|
+
const wsLabel = hubsDirLabel(gitRoot);
|
|
11699
|
+
if (gitRoot) warnLayoutOnce(gitRoot);
|
|
11700
|
+
if (!fs12.existsSync(workspaceDir)) {
|
|
11701
|
+
console.error(`No ${wsLabel}/ directory found. Run \`wayai pull\` first or create hub files in ${wsLabel}/<hub>/hub.yaml.`);
|
|
11702
|
+
process.exit(1);
|
|
11703
|
+
}
|
|
11704
|
+
const existingHubs = scanWorkspaceHubs(workspaceDir);
|
|
11705
|
+
const newHubs = scanNewHubs(workspaceDir);
|
|
11706
|
+
const resolution = resolvePushTarget(workspaceDir, existingHubs, newHubs, hubSelector);
|
|
11707
|
+
if (!resolution.ok) {
|
|
11708
|
+
reportUnresolvedPushTarget(resolution.reason, existingHubs, newHubs, hubSelector, wsLabel);
|
|
11709
|
+
}
|
|
11710
|
+
if (resolution.target.kind === "existing") {
|
|
11711
|
+
const existing = resolution.target.hub;
|
|
11712
|
+
if (existing.hubEnvironment === "production") {
|
|
11713
|
+
console.log("This is a read-only production mirror \u2014 production hubs cannot be pushed. Edit the linked preview hub instead.");
|
|
11714
|
+
return;
|
|
11715
|
+
}
|
|
11716
|
+
if (label) {
|
|
11717
|
+
console.warn("Note: --label is only used when creating a new hub. To change an existing hub's label, use `wayai relabel`.");
|
|
11718
|
+
}
|
|
11719
|
+
console.log(`Target hub: ${path14.basename(existing.hubFolder)} (${existing.hubId})`);
|
|
11720
|
+
assertHubMatchesBinding(existing.hubId, path14.basename(existing.hubFolder));
|
|
11721
|
+
await pushSingleHub(client, existing.hubId, existing.hubFolder, autoConfirm, organizationId);
|
|
11722
|
+
return;
|
|
11723
|
+
}
|
|
11724
|
+
assertNoBindingBlocksHubCreation(resolution.target.hub.hubName);
|
|
11725
|
+
await createAndPushNewHub(client, resolution.target.hub, { autoConfirm, label, organizationId });
|
|
11665
11726
|
}
|
|
11666
11727
|
var init_push = __esm({
|
|
11667
11728
|
"src/commands/push.ts"() {
|
|
@@ -11680,13 +11741,89 @@ var init_push = __esm({
|
|
|
11680
11741
|
}
|
|
11681
11742
|
});
|
|
11682
11743
|
|
|
11744
|
+
// src/commands/create.ts
|
|
11745
|
+
var create_exports = {};
|
|
11746
|
+
__export(create_exports, {
|
|
11747
|
+
createCommand: () => createCommand
|
|
11748
|
+
});
|
|
11749
|
+
import * as path15 from "path";
|
|
11750
|
+
import * as fs13 from "fs";
|
|
11751
|
+
function parseArgs6(args2) {
|
|
11752
|
+
let autoConfirm = false;
|
|
11753
|
+
let folderSelector;
|
|
11754
|
+
let label;
|
|
11755
|
+
for (let i = 0; i < args2.length; i++) {
|
|
11756
|
+
const arg = args2[i];
|
|
11757
|
+
if (arg === "--yes" || arg === "-y") {
|
|
11758
|
+
autoConfirm = true;
|
|
11759
|
+
} else if (arg === "--label" && args2[i + 1]) {
|
|
11760
|
+
label = args2[++i];
|
|
11761
|
+
} else if (!arg.startsWith("-") && folderSelector === void 0) {
|
|
11762
|
+
folderSelector = arg;
|
|
11763
|
+
}
|
|
11764
|
+
}
|
|
11765
|
+
return { autoConfirm, folderSelector, label };
|
|
11766
|
+
}
|
|
11767
|
+
async function createCommand(args2) {
|
|
11768
|
+
const { autoConfirm, folderSelector, label } = parseArgs6(args2);
|
|
11769
|
+
const repoConfig = requireRepoConfig();
|
|
11770
|
+
const { organization_id: organizationId } = repoConfig;
|
|
11771
|
+
const { config, accessToken } = await requireAuth();
|
|
11772
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
11773
|
+
const workspaceDir = resolveWorkspaceDir();
|
|
11774
|
+
const gitRoot = findGitRoot();
|
|
11775
|
+
const wsLabel = hubsDirLabel(gitRoot);
|
|
11776
|
+
if (gitRoot) warnLayoutOnce(gitRoot);
|
|
11777
|
+
if (!fs13.existsSync(workspaceDir)) {
|
|
11778
|
+
console.error(`No ${wsLabel}/ directory found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` first.`);
|
|
11779
|
+
process.exit(1);
|
|
11780
|
+
}
|
|
11781
|
+
const existingHubs = scanWorkspaceHubs(workspaceDir);
|
|
11782
|
+
const newHubs = scanNewHubs(workspaceDir);
|
|
11783
|
+
const resolution = resolveNewHubForCreate(workspaceDir, existingHubs, newHubs, folderSelector);
|
|
11784
|
+
if (!resolution.ok) {
|
|
11785
|
+
if (resolution.reason === "exists") {
|
|
11786
|
+
const folder = path15.basename(resolution.existing.hubFolder);
|
|
11787
|
+
console.error(`Hub "${folder}" already exists (${resolution.existing.hubId}). Use \`wayai push --hub ${folder}\` to update it.`);
|
|
11788
|
+
process.exit(1);
|
|
11789
|
+
}
|
|
11790
|
+
if (resolution.reason === "selector_miss") {
|
|
11791
|
+
console.error(`No new (uncreated) hub folder "${folderSelector}" found in ${wsLabel}/. A new hub folder needs a hub.yaml with \`hub: { name: ... }\` and no hub_id.`);
|
|
11792
|
+
process.exit(1);
|
|
11793
|
+
}
|
|
11794
|
+
if (resolution.reason === "none") {
|
|
11795
|
+
console.error(`No new (uncreated) hub folders found in ${wsLabel}/. Create ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` first, then run \`wayai create\`.`);
|
|
11796
|
+
process.exit(1);
|
|
11797
|
+
}
|
|
11798
|
+
console.error(`Multiple new hub folders found in ${wsLabel}/. Pass the folder name (\`wayai create <folder>\`) or run from inside one:`);
|
|
11799
|
+
for (const h of newHubs) {
|
|
11800
|
+
console.error(` ${path15.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
|
|
11801
|
+
}
|
|
11802
|
+
process.exit(1);
|
|
11803
|
+
}
|
|
11804
|
+
assertNoBindingBlocksHubCreation(resolution.hub.hubName);
|
|
11805
|
+
await createAndPushNewHub(client, resolution.hub, { autoConfirm, label, organizationId });
|
|
11806
|
+
}
|
|
11807
|
+
var init_create = __esm({
|
|
11808
|
+
"src/commands/create.ts"() {
|
|
11809
|
+
"use strict";
|
|
11810
|
+
init_auth();
|
|
11811
|
+
init_api_client();
|
|
11812
|
+
init_push();
|
|
11813
|
+
init_workspace();
|
|
11814
|
+
init_layout();
|
|
11815
|
+
init_repo_config();
|
|
11816
|
+
init_hub_binding();
|
|
11817
|
+
}
|
|
11818
|
+
});
|
|
11819
|
+
|
|
11683
11820
|
// src/commands/diff.ts
|
|
11684
11821
|
var diff_exports = {};
|
|
11685
11822
|
__export(diff_exports, {
|
|
11686
11823
|
diffCommand: () => diffCommand,
|
|
11687
|
-
parseArgs: () =>
|
|
11824
|
+
parseArgs: () => parseArgs7
|
|
11688
11825
|
});
|
|
11689
|
-
function
|
|
11826
|
+
function parseArgs7(args2) {
|
|
11690
11827
|
let production = false;
|
|
11691
11828
|
let hubSelector;
|
|
11692
11829
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -11700,7 +11837,7 @@ function parseArgs6(args2) {
|
|
|
11700
11837
|
return { production, hubSelector };
|
|
11701
11838
|
}
|
|
11702
11839
|
async function diffCommand(args2) {
|
|
11703
|
-
const { production, hubSelector } =
|
|
11840
|
+
const { production, hubSelector } = parseArgs7(args2);
|
|
11704
11841
|
const repoConfig = requireRepoConfig();
|
|
11705
11842
|
const { organization_id: organizationId } = repoConfig;
|
|
11706
11843
|
const { config, accessToken } = await requireAuth();
|
|
@@ -11830,12 +11967,12 @@ function typeMatches2(typeField, allowed) {
|
|
|
11830
11967
|
if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
|
|
11831
11968
|
return false;
|
|
11832
11969
|
}
|
|
11833
|
-
function validateSchema2(schema,
|
|
11970
|
+
function validateSchema2(schema, path26, errors, opts = {}) {
|
|
11834
11971
|
if (typeof schema === "boolean") return;
|
|
11835
11972
|
const depth = opts.depth ?? 0;
|
|
11836
11973
|
if (depth > MAX_SCHEMA_DEPTH2) {
|
|
11837
11974
|
errors.push({
|
|
11838
|
-
path:
|
|
11975
|
+
path: path26 || "<root>",
|
|
11839
11976
|
message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH2} levels`,
|
|
11840
11977
|
suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
|
|
11841
11978
|
});
|
|
@@ -11843,7 +11980,7 @@ function validateSchema2(schema, path25, errors, opts = {}) {
|
|
|
11843
11980
|
}
|
|
11844
11981
|
if (!isRecord2(schema)) {
|
|
11845
11982
|
errors.push({
|
|
11846
|
-
path:
|
|
11983
|
+
path: path26,
|
|
11847
11984
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
11848
11985
|
});
|
|
11849
11986
|
return;
|
|
@@ -11851,14 +11988,14 @@ function validateSchema2(schema, path25, errors, opts = {}) {
|
|
|
11851
11988
|
if (opts.isRoot) {
|
|
11852
11989
|
if ("type" in schema && schema.type !== "object") {
|
|
11853
11990
|
errors.push({
|
|
11854
|
-
path:
|
|
11991
|
+
path: path26 ? `${path26}.type` : "type",
|
|
11855
11992
|
message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
|
|
11856
11993
|
suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
|
|
11857
11994
|
});
|
|
11858
11995
|
}
|
|
11859
11996
|
} else if ("type" in schema && !typeMatches2(schema.type, ALLOWED_TYPES2)) {
|
|
11860
11997
|
errors.push({
|
|
11861
|
-
path: `${
|
|
11998
|
+
path: `${path26}.type`,
|
|
11862
11999
|
message: `type must be one of ${[...ALLOWED_TYPES2].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
|
|
11863
12000
|
});
|
|
11864
12001
|
}
|
|
@@ -11867,25 +12004,25 @@ function validateSchema2(schema, path25, errors, opts = {}) {
|
|
|
11867
12004
|
if (typeof e === "string") {
|
|
11868
12005
|
const isPlaceholder = PLACEHOLDER_TOKENS2.includes(e);
|
|
11869
12006
|
errors.push({
|
|
11870
|
-
path: `${
|
|
12007
|
+
path: `${path26}.enum`,
|
|
11871
12008
|
message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
|
|
11872
12009
|
suggestion: isPlaceholder ? "Set `operation: 'update_kanban_status'` on the tool and ensure at least one hub.kanban_status has `allowsAgentUpdate: true` so the platform can render the placeholder into a valid array." : 'Wrap the value in an array: `enum: ["value"]`.'
|
|
11873
12010
|
});
|
|
11874
12011
|
} else if (!Array.isArray(e)) {
|
|
11875
12012
|
errors.push({
|
|
11876
|
-
path: `${
|
|
12013
|
+
path: `${path26}.enum`,
|
|
11877
12014
|
message: `enum must be a non-empty array of primitives, got ${typeof e}`
|
|
11878
12015
|
});
|
|
11879
12016
|
} else if (e.length === 0) {
|
|
11880
12017
|
errors.push({
|
|
11881
|
-
path: `${
|
|
12018
|
+
path: `${path26}.enum`,
|
|
11882
12019
|
message: "enum must not be empty"
|
|
11883
12020
|
});
|
|
11884
12021
|
} else {
|
|
11885
12022
|
for (let i = 0; i < e.length; i++) {
|
|
11886
12023
|
if (!isPrimitive2(e[i])) {
|
|
11887
12024
|
errors.push({
|
|
11888
|
-
path: `${
|
|
12025
|
+
path: `${path26}.enum[${i}]`,
|
|
11889
12026
|
message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
|
|
11890
12027
|
});
|
|
11891
12028
|
}
|
|
@@ -11895,7 +12032,7 @@ function validateSchema2(schema, path25, errors, opts = {}) {
|
|
|
11895
12032
|
for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
|
|
11896
12033
|
if (key in schema && typeof schema[key] === "boolean") {
|
|
11897
12034
|
errors.push({
|
|
11898
|
-
path: `${
|
|
12035
|
+
path: `${path26}.${key}`,
|
|
11899
12036
|
message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
|
|
11900
12037
|
suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
|
|
11901
12038
|
});
|
|
@@ -11904,45 +12041,45 @@ function validateSchema2(schema, path25, errors, opts = {}) {
|
|
|
11904
12041
|
if ("properties" in schema) {
|
|
11905
12042
|
if (!isRecord2(schema.properties)) {
|
|
11906
12043
|
errors.push({
|
|
11907
|
-
path: `${
|
|
12044
|
+
path: `${path26}.properties`,
|
|
11908
12045
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
11909
12046
|
});
|
|
11910
12047
|
} else {
|
|
11911
12048
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
11912
|
-
validateSchema2(propSchema, `${
|
|
12049
|
+
validateSchema2(propSchema, `${path26}.properties.${propName}`, errors, { depth: depth + 1 });
|
|
11913
12050
|
}
|
|
11914
12051
|
}
|
|
11915
12052
|
}
|
|
11916
12053
|
if (schemaTypeIncludes2(schema, "array") && "items" in schema) {
|
|
11917
12054
|
if (Array.isArray(schema.items)) {
|
|
11918
|
-
schema.items.forEach((sub, i) => validateSchema2(sub, `${
|
|
12055
|
+
schema.items.forEach((sub, i) => validateSchema2(sub, `${path26}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
11919
12056
|
} else {
|
|
11920
|
-
validateSchema2(schema.items, `${
|
|
12057
|
+
validateSchema2(schema.items, `${path26}.items`, errors, { depth: depth + 1 });
|
|
11921
12058
|
}
|
|
11922
12059
|
}
|
|
11923
12060
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS2) {
|
|
11924
12061
|
if (key in schema && isRecord2(schema[key])) {
|
|
11925
|
-
validateSchema2(schema[key], `${
|
|
12062
|
+
validateSchema2(schema[key], `${path26}.${key}`, errors, { depth: depth + 1 });
|
|
11926
12063
|
}
|
|
11927
12064
|
}
|
|
11928
12065
|
for (const key of SUBSCHEMA_LIST_KEYWORDS2) {
|
|
11929
12066
|
const list = schema[key];
|
|
11930
12067
|
if (Array.isArray(list)) {
|
|
11931
|
-
list.forEach((sub, i) => validateSchema2(sub, `${
|
|
12068
|
+
list.forEach((sub, i) => validateSchema2(sub, `${path26}.${key}[${i}]`, errors, { depth: depth + 1 }));
|
|
11932
12069
|
}
|
|
11933
12070
|
}
|
|
11934
12071
|
for (const key of SUBSCHEMA_MAP_KEYWORDS2) {
|
|
11935
12072
|
const map = schema[key];
|
|
11936
12073
|
if (isRecord2(map)) {
|
|
11937
12074
|
for (const [name, sub] of Object.entries(map)) {
|
|
11938
|
-
validateSchema2(sub, `${
|
|
12075
|
+
validateSchema2(sub, `${path26}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
11939
12076
|
}
|
|
11940
12077
|
}
|
|
11941
12078
|
}
|
|
11942
12079
|
const reportedPaths = new Set(errors.map((e) => e.path));
|
|
11943
12080
|
for (const [k, v] of Object.entries(schema)) {
|
|
11944
12081
|
if (typeof v !== "string") continue;
|
|
11945
|
-
const fieldPath = `${
|
|
12082
|
+
const fieldPath = `${path26}.${k}`;
|
|
11946
12083
|
if (reportedPaths.has(fieldPath)) continue;
|
|
11947
12084
|
for (const token of PLACEHOLDER_TOKENS2) {
|
|
11948
12085
|
if (v === token) {
|
|
@@ -12098,10 +12235,10 @@ function refineHubAsCodeLanes2(config, ctx) {
|
|
|
12098
12235
|
}
|
|
12099
12236
|
}
|
|
12100
12237
|
}
|
|
12101
|
-
function isSafeTemplatePath2(
|
|
12102
|
-
if (
|
|
12103
|
-
if (
|
|
12104
|
-
const segments =
|
|
12238
|
+
function isSafeTemplatePath2(path26) {
|
|
12239
|
+
if (path26.length === 0 || path26.length > 300) return false;
|
|
12240
|
+
if (path26.startsWith("/") || path26.includes("\\")) return false;
|
|
12241
|
+
const segments = path26.split("/");
|
|
12105
12242
|
return segments.every(
|
|
12106
12243
|
(seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
|
|
12107
12244
|
);
|
|
@@ -12129,9 +12266,9 @@ function isPlainObject(value) {
|
|
|
12129
12266
|
const proto = Object.getPrototypeOf(value);
|
|
12130
12267
|
return proto === Object.prototype || proto === null;
|
|
12131
12268
|
}
|
|
12132
|
-
function isSanitizableSliceFile(
|
|
12133
|
-
if (!/\.ya?ml$/i.test(
|
|
12134
|
-
return
|
|
12269
|
+
function isSanitizableSliceFile(path26) {
|
|
12270
|
+
if (!/\.ya?ml$/i.test(path26)) return false;
|
|
12271
|
+
return path26 !== "resources" && !path26.startsWith("resources/");
|
|
12135
12272
|
}
|
|
12136
12273
|
function distinctUsesBackends(uses) {
|
|
12137
12274
|
return [...new Set((uses ?? []).map((u) => u.backend))];
|
|
@@ -12575,7 +12712,7 @@ var init_contracts = __esm({
|
|
|
12575
12712
|
// at fallback time in the turn seam (a stale/missing id simply no-ops). Nullable to clear it.
|
|
12576
12713
|
fallback_connection_id: uuidSchema2.nullable().optional(),
|
|
12577
12714
|
// Rekor API connection used to reset/clear eval seed fixtures (gh #3090). A
|
|
12578
|
-
// connection id on this hub (a REST API
|
|
12715
|
+
// connection id on this hub (a REST API (custom tool) connection whose base_url
|
|
12579
12716
|
// is the Rekor API origin + a bearer/api_key `write:seeds` token). Validated at
|
|
12580
12717
|
// set-time on the REST PATCH (setup/hubs.ts). Nullable to clear it.
|
|
12581
12718
|
seed_connection_id: uuidSchema2.nullable().optional()
|
|
@@ -14751,9 +14888,9 @@ var replicate_exports = {};
|
|
|
14751
14888
|
__export(replicate_exports, {
|
|
14752
14889
|
replicateCommand: () => replicateCommand
|
|
14753
14890
|
});
|
|
14754
|
-
import * as
|
|
14755
|
-
import * as
|
|
14756
|
-
function
|
|
14891
|
+
import * as fs14 from "fs";
|
|
14892
|
+
import * as path16 from "path";
|
|
14893
|
+
function parseArgs8(args2) {
|
|
14757
14894
|
let label;
|
|
14758
14895
|
let hubSelector;
|
|
14759
14896
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -14769,7 +14906,7 @@ function parseArgs7(args2) {
|
|
|
14769
14906
|
return { label, hubSelector };
|
|
14770
14907
|
}
|
|
14771
14908
|
async function replicateCommand(args2) {
|
|
14772
|
-
const { label, hubSelector } =
|
|
14909
|
+
const { label, hubSelector } = parseArgs8(args2);
|
|
14773
14910
|
const normalizedLabel = label?.trim() || void 0;
|
|
14774
14911
|
if (normalizedLabel && normalizedLabel.length > PREVIEW_LABEL_MAX_LENGTH2) {
|
|
14775
14912
|
console.error(`--label must be ${PREVIEW_LABEL_MAX_LENGTH2} characters or fewer.`);
|
|
@@ -14798,7 +14935,7 @@ async function replicateCommand(args2) {
|
|
|
14798
14935
|
payload.preview_label,
|
|
14799
14936
|
payload.branch_name
|
|
14800
14937
|
);
|
|
14801
|
-
|
|
14938
|
+
fs14.mkdirSync(path16.dirname(hubFolder), { recursive: true });
|
|
14802
14939
|
writeHubFolder(hubFolder, payload);
|
|
14803
14940
|
await downloadBinaryResourceFiles(hubFolder, payload);
|
|
14804
14941
|
hubFolder = autoRenameHubFolder(
|
|
@@ -14810,8 +14947,8 @@ async function replicateCommand(args2) {
|
|
|
14810
14947
|
payload.branch_name
|
|
14811
14948
|
);
|
|
14812
14949
|
autoBindIfUnbound(previewHubId);
|
|
14813
|
-
console.log(`Preview written to ${
|
|
14814
|
-
console.log(` Switch to it with: wayai use ${
|
|
14950
|
+
console.log(`Preview written to ${path16.basename(hubFolder)}`);
|
|
14951
|
+
console.log(` Switch to it with: wayai use ${path16.basename(hubFolder)}`);
|
|
14815
14952
|
}
|
|
14816
14953
|
var init_replicate = __esm({
|
|
14817
14954
|
"src/commands/replicate.ts"() {
|
|
@@ -14833,8 +14970,8 @@ var relabel_exports = {};
|
|
|
14833
14970
|
__export(relabel_exports, {
|
|
14834
14971
|
relabelCommand: () => relabelCommand
|
|
14835
14972
|
});
|
|
14836
|
-
import * as
|
|
14837
|
-
function
|
|
14973
|
+
import * as path17 from "path";
|
|
14974
|
+
function parseArgs9(args2) {
|
|
14838
14975
|
let label;
|
|
14839
14976
|
let clear = false;
|
|
14840
14977
|
let hubSelector;
|
|
@@ -14851,7 +14988,7 @@ function parseArgs8(args2) {
|
|
|
14851
14988
|
return { label, clear, hubSelector };
|
|
14852
14989
|
}
|
|
14853
14990
|
async function relabelCommand(args2) {
|
|
14854
|
-
const { label, clear, hubSelector } =
|
|
14991
|
+
const { label, clear, hubSelector } = parseArgs9(args2);
|
|
14855
14992
|
if (!clear && (label === void 0 || label.trim() === "")) {
|
|
14856
14993
|
console.error("Usage: wayai relabel <label> [--hub <uuid|folder>] (or --clear to remove the label)");
|
|
14857
14994
|
process.exit(1);
|
|
@@ -14877,7 +15014,7 @@ async function relabelCommand(args2) {
|
|
|
14877
15014
|
} else {
|
|
14878
15015
|
console.error(`Multiple hubs found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
|
|
14879
15016
|
for (const h of previewHubs) {
|
|
14880
|
-
console.error(` ${
|
|
15017
|
+
console.error(` ${path17.basename(h.hubFolder)} (${h.hubId})`);
|
|
14881
15018
|
}
|
|
14882
15019
|
}
|
|
14883
15020
|
process.exit(1);
|
|
@@ -14886,7 +15023,7 @@ async function relabelCommand(args2) {
|
|
|
14886
15023
|
console.log("This is a read-only production mirror \u2014 production hubs have no preview label. Relabel the linked preview hub instead.");
|
|
14887
15024
|
return;
|
|
14888
15025
|
}
|
|
14889
|
-
assertHubMatchesBinding(target.hubId,
|
|
15026
|
+
assertHubMatchesBinding(target.hubId, path17.basename(target.hubFolder));
|
|
14890
15027
|
console.log(normalizedLabel ? `Setting preview label to "${normalizedLabel}"...` : "Clearing preview label...");
|
|
14891
15028
|
const { data } = await client.relabelPreview(target.hubId, normalizedLabel);
|
|
14892
15029
|
const row = data[0];
|
|
@@ -14902,7 +15039,7 @@ async function relabelCommand(args2) {
|
|
|
14902
15039
|
);
|
|
14903
15040
|
console.log(serverLabel ? `Preview label set to "${serverLabel}".` : "Preview label cleared.");
|
|
14904
15041
|
if (finalFolder !== target.hubFolder) {
|
|
14905
|
-
console.log(`Hub folder is now ${
|
|
15042
|
+
console.log(`Hub folder is now ${path17.basename(finalFolder)}`);
|
|
14906
15043
|
}
|
|
14907
15044
|
}
|
|
14908
15045
|
var init_relabel = __esm({
|
|
@@ -14923,13 +15060,13 @@ var init_relabel = __esm({
|
|
|
14923
15060
|
// src/commands/publish.ts
|
|
14924
15061
|
var publish_exports = {};
|
|
14925
15062
|
__export(publish_exports, {
|
|
14926
|
-
parseArgs: () =>
|
|
15063
|
+
parseArgs: () => parseArgs10,
|
|
14927
15064
|
publishCommand: () => publishCommand,
|
|
14928
15065
|
renderHubDiff: () => renderHubDiff,
|
|
14929
15066
|
runPublish: () => runPublish
|
|
14930
15067
|
});
|
|
14931
|
-
import * as
|
|
14932
|
-
function
|
|
15068
|
+
import * as path18 from "path";
|
|
15069
|
+
function parseArgs10(args2) {
|
|
14933
15070
|
let autoConfirm = false;
|
|
14934
15071
|
let hubSelector;
|
|
14935
15072
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -15015,7 +15152,7 @@ Published. Production hub: ${data.production_hub_id}`);
|
|
|
15015
15152
|
return "synced";
|
|
15016
15153
|
}
|
|
15017
15154
|
async function publishCommand(args2) {
|
|
15018
|
-
const { autoConfirm, hubSelector } =
|
|
15155
|
+
const { autoConfirm, hubSelector } = parseArgs10(args2);
|
|
15019
15156
|
const repoConfig = requireRepoConfig();
|
|
15020
15157
|
const { organization_id: organizationId } = repoConfig;
|
|
15021
15158
|
const { config, accessToken } = await requireAuth();
|
|
@@ -15034,7 +15171,7 @@ async function publishCommand(args2) {
|
|
|
15034
15171
|
return;
|
|
15035
15172
|
}
|
|
15036
15173
|
}
|
|
15037
|
-
assertHubMatchesBinding(hubId, hubFolder ?
|
|
15174
|
+
assertHubMatchesBinding(hubId, hubFolder ? path18.basename(hubFolder) : void 0);
|
|
15038
15175
|
await runPublish(client, { hubId, localConfig, organizationId, autoConfirm });
|
|
15039
15176
|
}
|
|
15040
15177
|
var STATUS_STYLE;
|
|
@@ -15066,7 +15203,7 @@ var use_exports = {};
|
|
|
15066
15203
|
__export(use_exports, {
|
|
15067
15204
|
useCommand: () => useCommand
|
|
15068
15205
|
});
|
|
15069
|
-
import * as
|
|
15206
|
+
import * as path19 from "path";
|
|
15070
15207
|
async function useCommand(args2) {
|
|
15071
15208
|
const target = args2[0];
|
|
15072
15209
|
if (!target || target.startsWith("-")) {
|
|
@@ -15087,9 +15224,22 @@ async function useCommand(args2) {
|
|
|
15087
15224
|
const wsLabel = hubsDirLabel(gitRoot);
|
|
15088
15225
|
const match = findHubByFolderName(workspaceDir, target);
|
|
15089
15226
|
if (!match) {
|
|
15227
|
+
const newHubs = scanNewHubs(workspaceDir);
|
|
15228
|
+
const pending = newHubs.find((h) => path19.basename(h.hubFolder) === target);
|
|
15229
|
+
if (pending) {
|
|
15230
|
+
console.error(
|
|
15231
|
+
`"${target}" is a new hub that hasn't been created on the platform yet, so it has no id to bind to.
|
|
15232
|
+
Create it first \u2014 the worktree binds automatically afterward:
|
|
15233
|
+
wayai create ${target}`
|
|
15234
|
+
);
|
|
15235
|
+
process.exit(1);
|
|
15236
|
+
}
|
|
15090
15237
|
console.error(`No hub matching "${target}" found in ${wsLabel}/. Pass a UUID or a folder name from:`);
|
|
15091
15238
|
for (const h of scanWorkspaceHubs(workspaceDir)) {
|
|
15092
|
-
console.error(` ${
|
|
15239
|
+
console.error(` ${path19.basename(h.hubFolder)} (${h.hubId})`);
|
|
15240
|
+
}
|
|
15241
|
+
for (const h of newHubs) {
|
|
15242
|
+
console.error(` ${path19.basename(h.hubFolder)} (new \u2014 "${h.hubName}", run \`wayai create ${path19.basename(h.hubFolder)}\`)`);
|
|
15093
15243
|
}
|
|
15094
15244
|
process.exit(1);
|
|
15095
15245
|
}
|
|
@@ -15128,11 +15278,11 @@ __export(migrate_exports, {
|
|
|
15128
15278
|
migrateCommand: () => migrateCommand
|
|
15129
15279
|
});
|
|
15130
15280
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
15131
|
-
import * as
|
|
15132
|
-
import * as
|
|
15281
|
+
import * as fs15 from "fs";
|
|
15282
|
+
import * as path20 from "path";
|
|
15133
15283
|
function isTracked(gitRoot, p) {
|
|
15134
15284
|
try {
|
|
15135
|
-
execFileSync3("git", ["ls-files", "--error-unmatch", "--",
|
|
15285
|
+
execFileSync3("git", ["ls-files", "--error-unmatch", "--", path20.relative(gitRoot, p)], {
|
|
15136
15286
|
cwd: gitRoot,
|
|
15137
15287
|
stdio: ["pipe", "pipe", "pipe"]
|
|
15138
15288
|
});
|
|
@@ -15142,10 +15292,10 @@ function isTracked(gitRoot, p) {
|
|
|
15142
15292
|
}
|
|
15143
15293
|
}
|
|
15144
15294
|
function moveDir(gitRoot, from, to) {
|
|
15145
|
-
|
|
15295
|
+
fs15.mkdirSync(path20.dirname(to), { recursive: true });
|
|
15146
15296
|
if (isTracked(gitRoot, from)) {
|
|
15147
15297
|
try {
|
|
15148
|
-
execFileSync3("git", ["mv",
|
|
15298
|
+
execFileSync3("git", ["mv", path20.relative(gitRoot, from), path20.relative(gitRoot, to)], {
|
|
15149
15299
|
cwd: gitRoot,
|
|
15150
15300
|
stdio: ["pipe", "pipe", "pipe"]
|
|
15151
15301
|
});
|
|
@@ -15153,7 +15303,7 @@ function moveDir(gitRoot, from, to) {
|
|
|
15153
15303
|
} catch {
|
|
15154
15304
|
}
|
|
15155
15305
|
}
|
|
15156
|
-
|
|
15306
|
+
fs15.renameSync(from, to);
|
|
15157
15307
|
return "fs";
|
|
15158
15308
|
}
|
|
15159
15309
|
async function migrateCommand(_args) {
|
|
@@ -15162,12 +15312,12 @@ async function migrateCommand(_args) {
|
|
|
15162
15312
|
console.error("Not inside a git repository.");
|
|
15163
15313
|
process.exit(1);
|
|
15164
15314
|
}
|
|
15165
|
-
const rel = (p) =>
|
|
15166
|
-
const newWs =
|
|
15167
|
-
const legacyWs =
|
|
15168
|
-
const legacyOrg =
|
|
15169
|
-
const newHubs =
|
|
15170
|
-
const newOrg =
|
|
15315
|
+
const rel = (p) => path20.relative(gitRoot, p);
|
|
15316
|
+
const newWs = path20.join(gitRoot, WAYAI_LAYOUT.wsDir);
|
|
15317
|
+
const legacyWs = path20.join(gitRoot, WAYAI_LAYOUT.legacy.wsDir);
|
|
15318
|
+
const legacyOrg = path20.join(gitRoot, WAYAI_LAYOUT.legacy.orgAtRoot);
|
|
15319
|
+
const newHubs = path20.join(newWs, WAYAI_LAYOUT.hubsSubdir);
|
|
15320
|
+
const newOrg = path20.join(newWs, WAYAI_LAYOUT.orgSubdir);
|
|
15171
15321
|
const hasLegacyWs = isDirectory(legacyWs);
|
|
15172
15322
|
const hasLegacyOrg = isDirectory(legacyOrg);
|
|
15173
15323
|
if (!hasLegacyWs && !hasLegacyOrg) {
|
|
@@ -15801,10 +15951,10 @@ var init_delete_history = __esm({
|
|
|
15801
15951
|
// src/commands/sync-skills.ts
|
|
15802
15952
|
var sync_skills_exports = {};
|
|
15803
15953
|
__export(sync_skills_exports, {
|
|
15804
|
-
parseArgs: () =>
|
|
15954
|
+
parseArgs: () => parseArgs11,
|
|
15805
15955
|
syncSkillsCommand: () => syncSkillsCommand
|
|
15806
15956
|
});
|
|
15807
|
-
function
|
|
15957
|
+
function parseArgs11(args2) {
|
|
15808
15958
|
let connectionId;
|
|
15809
15959
|
const idx = args2.indexOf("--connection-id");
|
|
15810
15960
|
if (idx !== -1 && args2[idx + 1]) {
|
|
@@ -15827,7 +15977,7 @@ function printSyncResults(response) {
|
|
|
15827
15977
|
}
|
|
15828
15978
|
async function syncSkillsCommand(args2) {
|
|
15829
15979
|
const hubId = resolveActiveHubId(args2);
|
|
15830
|
-
const { connectionId } =
|
|
15980
|
+
const { connectionId } = parseArgs11(args2);
|
|
15831
15981
|
requireRepoConfig();
|
|
15832
15982
|
const { config, accessToken } = await requireAuth();
|
|
15833
15983
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
@@ -15852,10 +16002,10 @@ var init_sync_skills = __esm({
|
|
|
15852
16002
|
// src/commands/sync-mcp.ts
|
|
15853
16003
|
var sync_mcp_exports = {};
|
|
15854
16004
|
__export(sync_mcp_exports, {
|
|
15855
|
-
parseArgs: () =>
|
|
16005
|
+
parseArgs: () => parseArgs12,
|
|
15856
16006
|
syncMcpCommand: () => syncMcpCommand
|
|
15857
16007
|
});
|
|
15858
|
-
function
|
|
16008
|
+
function parseArgs12(args2) {
|
|
15859
16009
|
let connection;
|
|
15860
16010
|
for (let i = 0; i < args2.length; i++) {
|
|
15861
16011
|
const arg = args2[i];
|
|
@@ -15867,7 +16017,7 @@ function parseArgs11(args2) {
|
|
|
15867
16017
|
}
|
|
15868
16018
|
async function syncMcpCommand(args2) {
|
|
15869
16019
|
const hubId = resolveActiveHubId(args2);
|
|
15870
|
-
const { connection } =
|
|
16020
|
+
const { connection } = parseArgs12(args2);
|
|
15871
16021
|
if (!connection) {
|
|
15872
16022
|
console.error("Usage: wayai sync-mcp --connection <name> [--hub <uuid|folder-name>]");
|
|
15873
16023
|
console.error("");
|
|
@@ -16279,7 +16429,7 @@ Timeout after ${timeoutSeconds}s. Session is still running.`);
|
|
|
16279
16429
|
console.log(`Check results: wayai eval-results --session ${sessionId}`);
|
|
16280
16430
|
}
|
|
16281
16431
|
function sleep(ms) {
|
|
16282
|
-
return new Promise((
|
|
16432
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
16283
16433
|
}
|
|
16284
16434
|
function parsePacing(raw) {
|
|
16285
16435
|
const NAMED = EVAL_PACING_PRESET_NAMES.filter((p) => p !== "custom");
|
|
@@ -16504,15 +16654,15 @@ var eval_capture_exports = {};
|
|
|
16504
16654
|
__export(eval_capture_exports, {
|
|
16505
16655
|
evalCaptureCommand: () => evalCaptureCommand
|
|
16506
16656
|
});
|
|
16507
|
-
import * as
|
|
16508
|
-
import * as
|
|
16657
|
+
import * as fs16 from "fs";
|
|
16658
|
+
import * as path21 from "path";
|
|
16509
16659
|
import * as yaml7 from "js-yaml";
|
|
16510
16660
|
function isValidSetName(name) {
|
|
16511
16661
|
if (name.length === 0 || name === "." || name === "..") return false;
|
|
16512
16662
|
if (name.startsWith(".")) return false;
|
|
16513
16663
|
return !/[\/\\\0]/.test(name);
|
|
16514
16664
|
}
|
|
16515
|
-
function
|
|
16665
|
+
function parseArgs13(args2) {
|
|
16516
16666
|
if (args2.length === 0 || args2[0].startsWith("-")) {
|
|
16517
16667
|
console.error("Usage: wayai eval capture <conversation_id> [--set <name>] [--name <eval_name>] [--instructions <text>]");
|
|
16518
16668
|
process.exit(1);
|
|
@@ -16558,7 +16708,7 @@ function parseArgs12(args2) {
|
|
|
16558
16708
|
}
|
|
16559
16709
|
async function evalCaptureCommand(args2) {
|
|
16560
16710
|
const hubId = resolveActiveHubId(args2);
|
|
16561
|
-
const parsed =
|
|
16711
|
+
const parsed = parseArgs13(args2);
|
|
16562
16712
|
const { config, accessToken } = await requireAuth();
|
|
16563
16713
|
requireRepoConfig();
|
|
16564
16714
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
@@ -16571,15 +16721,15 @@ async function evalCaptureCommand(args2) {
|
|
|
16571
16721
|
const setFolderName = targetSetName;
|
|
16572
16722
|
const scenarioName = parsed.evalName ?? `Capture ${parsed.conversationId.slice(0, 8)}`;
|
|
16573
16723
|
const slug = slugify(scenarioName);
|
|
16574
|
-
const evalsDir =
|
|
16575
|
-
const targetDir =
|
|
16576
|
-
const targetPath =
|
|
16577
|
-
if (!targetPath.startsWith(evalsDir +
|
|
16578
|
-
console.error(`Resolved path "${
|
|
16724
|
+
const evalsDir = path21.join(hubFolder, "evals");
|
|
16725
|
+
const targetDir = path21.join(evalsDir, setFolderName);
|
|
16726
|
+
const targetPath = path21.join(targetDir, `${slug}.yaml`);
|
|
16727
|
+
if (!targetPath.startsWith(evalsDir + path21.sep)) {
|
|
16728
|
+
console.error(`Resolved path "${path21.relative(hubFolder, targetPath)}" escapes evals/. Aborting.`);
|
|
16579
16729
|
process.exit(1);
|
|
16580
16730
|
}
|
|
16581
|
-
if (
|
|
16582
|
-
console.error(`File already exists: ${
|
|
16731
|
+
if (fs16.existsSync(targetPath)) {
|
|
16732
|
+
console.error(`File already exists: ${path21.relative(hubFolder, targetPath)}. Use --name to choose a different name.`);
|
|
16583
16733
|
process.exit(1);
|
|
16584
16734
|
}
|
|
16585
16735
|
console.log("Resolving scenario set...");
|
|
@@ -16611,9 +16761,9 @@ async function evalCaptureCommand(args2) {
|
|
|
16611
16761
|
...captured.evaluator_instructions ? { evaluator_instructions: captured.evaluator_instructions } : {}
|
|
16612
16762
|
};
|
|
16613
16763
|
const yamlObj = buildEvalYamlObject(evalEntry, slug);
|
|
16614
|
-
|
|
16615
|
-
|
|
16616
|
-
const relPath =
|
|
16764
|
+
fs16.mkdirSync(targetDir, { recursive: true });
|
|
16765
|
+
fs16.writeFileSync(targetPath, yaml7.dump(yamlObj, YAML_DUMP_OPTIONS), "utf-8");
|
|
16766
|
+
const relPath = path21.relative(process.cwd(), targetPath);
|
|
16617
16767
|
console.log(`
|
|
16618
16768
|
Wrote ${relPath}`);
|
|
16619
16769
|
console.log("Run `wayai pull` to refresh the agent display name, then commit. The scenario is already on the platform.");
|
|
@@ -16635,7 +16785,7 @@ var journey_capture_exports = {};
|
|
|
16635
16785
|
__export(journey_capture_exports, {
|
|
16636
16786
|
journeyCaptureCommand: () => journeyCaptureCommand
|
|
16637
16787
|
});
|
|
16638
|
-
function
|
|
16788
|
+
function parseArgs14(args2) {
|
|
16639
16789
|
if (args2.length === 0 || args2[0].startsWith("-")) {
|
|
16640
16790
|
console.error("Usage: wayai eval journey capture <conversation_id> [--name <journey_name>] [--instructions <text>]");
|
|
16641
16791
|
process.exit(1);
|
|
@@ -16670,7 +16820,7 @@ function parseArgs13(args2) {
|
|
|
16670
16820
|
}
|
|
16671
16821
|
async function journeyCaptureCommand(args2) {
|
|
16672
16822
|
const hubId = resolveActiveHubId(args2);
|
|
16673
|
-
const parsed =
|
|
16823
|
+
const parsed = parseArgs14(args2);
|
|
16674
16824
|
const { config, accessToken } = await requireAuth();
|
|
16675
16825
|
requireRepoConfig();
|
|
16676
16826
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
@@ -17467,9 +17617,9 @@ var init_credential_utils = __esm({
|
|
|
17467
17617
|
var create_credential_exports = {};
|
|
17468
17618
|
__export(create_credential_exports, {
|
|
17469
17619
|
createCredentialCommand: () => createCredentialCommand,
|
|
17470
|
-
parseArgs: () =>
|
|
17620
|
+
parseArgs: () => parseArgs15
|
|
17471
17621
|
});
|
|
17472
|
-
function
|
|
17622
|
+
function parseArgs15(args2) {
|
|
17473
17623
|
let name;
|
|
17474
17624
|
let type;
|
|
17475
17625
|
let orgId;
|
|
@@ -17497,7 +17647,7 @@ function parseArgs14(args2) {
|
|
|
17497
17647
|
return { name, type, orgId, description, tags: splitTagRefs(tags), environment, stdin };
|
|
17498
17648
|
}
|
|
17499
17649
|
async function createCredentialCommand(args2) {
|
|
17500
|
-
const parsed =
|
|
17650
|
+
const parsed = parseArgs15(args2);
|
|
17501
17651
|
if (!parsed.name) {
|
|
17502
17652
|
console.error("Missing required flag: --name <credential-name>");
|
|
17503
17653
|
console.error('Usage: wayai create-credential --name "openai-key" --type "Bearer Token"');
|
|
@@ -17604,10 +17754,10 @@ var init_create_credential = __esm({
|
|
|
17604
17754
|
// src/commands/update-credential.ts
|
|
17605
17755
|
var update_credential_exports = {};
|
|
17606
17756
|
__export(update_credential_exports, {
|
|
17607
|
-
parseArgs: () =>
|
|
17757
|
+
parseArgs: () => parseArgs16,
|
|
17608
17758
|
updateCredentialCommand: () => updateCredentialCommand
|
|
17609
17759
|
});
|
|
17610
|
-
function
|
|
17760
|
+
function parseArgs16(args2) {
|
|
17611
17761
|
let name;
|
|
17612
17762
|
let rename;
|
|
17613
17763
|
let orgId;
|
|
@@ -17640,7 +17790,7 @@ function parseArgs15(args2) {
|
|
|
17640
17790
|
return { name, rename, orgId, description, tags: splitTagRefs(tags), hasTagFlag, environment, stdin, secretPrompt };
|
|
17641
17791
|
}
|
|
17642
17792
|
async function updateCredentialCommand(args2) {
|
|
17643
|
-
const parsed =
|
|
17793
|
+
const parsed = parseArgs16(args2);
|
|
17644
17794
|
if (!parsed.name) {
|
|
17645
17795
|
console.error("Missing required flag: --name <credential-name>");
|
|
17646
17796
|
console.error('Usage: wayai update-credential --name "my-key" --stdin');
|
|
@@ -17745,10 +17895,10 @@ var init_update_credential = __esm({
|
|
|
17745
17895
|
// src/commands/set-connection-credential.ts
|
|
17746
17896
|
var set_connection_credential_exports = {};
|
|
17747
17897
|
__export(set_connection_credential_exports, {
|
|
17748
|
-
parseArgs: () =>
|
|
17898
|
+
parseArgs: () => parseArgs17,
|
|
17749
17899
|
setConnectionCredentialCommand: () => setConnectionCredentialCommand
|
|
17750
17900
|
});
|
|
17751
|
-
function
|
|
17901
|
+
function parseArgs17(args2) {
|
|
17752
17902
|
let connection;
|
|
17753
17903
|
let orgCredential;
|
|
17754
17904
|
let field;
|
|
@@ -17771,7 +17921,7 @@ function usage(msg) {
|
|
|
17771
17921
|
}
|
|
17772
17922
|
async function setConnectionCredentialCommand(args2) {
|
|
17773
17923
|
const hubId = resolveActiveHubId(args2);
|
|
17774
|
-
const parsed =
|
|
17924
|
+
const parsed = parseArgs17(args2);
|
|
17775
17925
|
if (!parsed.connection) usage("Missing required flag: --connection <name|id>");
|
|
17776
17926
|
const orgMode = !!parsed.orgCredential;
|
|
17777
17927
|
const directMode = !!parsed.field;
|
|
@@ -17840,23 +17990,23 @@ var init_set_connection_credential = __esm({
|
|
|
17840
17990
|
});
|
|
17841
17991
|
|
|
17842
17992
|
// src/lib/org-workspace.ts
|
|
17843
|
-
import * as
|
|
17844
|
-
import * as
|
|
17993
|
+
import * as fs17 from "fs";
|
|
17994
|
+
import * as path22 from "path";
|
|
17845
17995
|
import * as yaml8 from "js-yaml";
|
|
17846
17996
|
function getOrgDir(gitRoot) {
|
|
17847
17997
|
return resolveLayout(gitRoot).orgDir;
|
|
17848
17998
|
}
|
|
17849
17999
|
function orgManifestExists(orgDir) {
|
|
17850
|
-
return
|
|
18000
|
+
return fs17.existsSync(path22.join(orgDir, ORG_MANIFEST_NAME));
|
|
17851
18001
|
}
|
|
17852
18002
|
function parseOrgResources(orgDir) {
|
|
17853
|
-
const manifestPath =
|
|
18003
|
+
const manifestPath = path22.join(orgDir, ORG_MANIFEST_NAME);
|
|
17854
18004
|
let manifest = {};
|
|
17855
|
-
if (
|
|
17856
|
-
manifest = yaml8.load(
|
|
18005
|
+
if (fs17.existsSync(manifestPath)) {
|
|
18006
|
+
manifest = yaml8.load(fs17.readFileSync(manifestPath, "utf-8")) ?? {};
|
|
17857
18007
|
}
|
|
17858
18008
|
const rawResources = Array.isArray(manifest.resources) ? manifest.resources : [];
|
|
17859
|
-
const resourcesDir =
|
|
18009
|
+
const resourcesDir = path22.join(orgDir, "resources");
|
|
17860
18010
|
const resources = rawResources.map((res) => {
|
|
17861
18011
|
const resource = { name: res.name };
|
|
17862
18012
|
if (res.id) resource.id = res.id;
|
|
@@ -17868,8 +18018,8 @@ function parseOrgResources(orgDir) {
|
|
|
17868
18018
|
if (res.environment) resource.environment = res.environment;
|
|
17869
18019
|
if (Array.isArray(res.tags)) resource.tags = res.tags;
|
|
17870
18020
|
if (Array.isArray(res.folders)) resource.folders = res.folders;
|
|
17871
|
-
const resDir =
|
|
17872
|
-
if (
|
|
18021
|
+
const resDir = path22.join(resourcesDir, slugify(resource.name));
|
|
18022
|
+
if (fs17.existsSync(resDir)) {
|
|
17873
18023
|
const files = scanResourceFiles(resDir, "");
|
|
17874
18024
|
if (files.length > 0) resource.files = files;
|
|
17875
18025
|
}
|
|
@@ -17878,28 +18028,28 @@ function parseOrgResources(orgDir) {
|
|
|
17878
18028
|
return { version: 1, resources };
|
|
17879
18029
|
}
|
|
17880
18030
|
function writeOrgResources(orgDir, payload) {
|
|
17881
|
-
|
|
18031
|
+
fs17.mkdirSync(orgDir, { recursive: true });
|
|
17882
18032
|
const resources = payload.resources ?? [];
|
|
17883
18033
|
const manifestResources = resources.map((r) => {
|
|
17884
18034
|
const { files: _files, ...rest } = r;
|
|
17885
18035
|
return rest;
|
|
17886
18036
|
});
|
|
17887
|
-
|
|
17888
|
-
|
|
18037
|
+
fs17.writeFileSync(
|
|
18038
|
+
path22.join(orgDir, ORG_MANIFEST_NAME),
|
|
17889
18039
|
yaml8.dump({ version: 1, resources: manifestResources }, YAML_DUMP_OPTIONS),
|
|
17890
18040
|
"utf-8"
|
|
17891
18041
|
);
|
|
17892
|
-
const resourcesDir =
|
|
18042
|
+
const resourcesDir = path22.join(orgDir, "resources");
|
|
17893
18043
|
const currentSlugs = /* @__PURE__ */ new Set();
|
|
17894
18044
|
for (const resource of resources) {
|
|
17895
18045
|
const resSlug = slugify(resource.name);
|
|
17896
18046
|
currentSlugs.add(resSlug);
|
|
17897
|
-
writeResourceFileTree(
|
|
18047
|
+
writeResourceFileTree(path22.join(resourcesDir, resSlug), resource.files || []);
|
|
17898
18048
|
}
|
|
17899
|
-
if (
|
|
17900
|
-
for (const entry of
|
|
18049
|
+
if (fs17.existsSync(resourcesDir)) {
|
|
18050
|
+
for (const entry of fs17.readdirSync(resourcesDir, { withFileTypes: true })) {
|
|
17901
18051
|
if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
|
|
17902
|
-
|
|
18052
|
+
fs17.rmSync(path22.join(resourcesDir, entry.name), { recursive: true, force: true });
|
|
17903
18053
|
}
|
|
17904
18054
|
}
|
|
17905
18055
|
}
|
|
@@ -17908,7 +18058,7 @@ async function downloadOrgBinaryFiles(orgDir, payload) {
|
|
|
17908
18058
|
let count = 0;
|
|
17909
18059
|
for (const resource of payload.resources ?? []) {
|
|
17910
18060
|
if (!resource.files) continue;
|
|
17911
|
-
const resDir =
|
|
18061
|
+
const resDir = path22.join(orgDir, "resources", slugify(resource.name));
|
|
17912
18062
|
count += await downloadBinaryFiles(resDir, resource.files);
|
|
17913
18063
|
}
|
|
17914
18064
|
if (count > 0) console.log(`Downloaded ${count} binary resource file(s).`);
|
|
@@ -18096,9 +18246,9 @@ var init_org = __esm({
|
|
|
18096
18246
|
var list_exports = {};
|
|
18097
18247
|
__export(list_exports, {
|
|
18098
18248
|
listCommand: () => listCommand,
|
|
18099
|
-
parseArgs: () =>
|
|
18249
|
+
parseArgs: () => parseArgs18
|
|
18100
18250
|
});
|
|
18101
|
-
function
|
|
18251
|
+
function parseArgs18(args2) {
|
|
18102
18252
|
let orgId;
|
|
18103
18253
|
let json = false;
|
|
18104
18254
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -18111,7 +18261,7 @@ function parseArgs17(args2) {
|
|
|
18111
18261
|
return { orgId, json };
|
|
18112
18262
|
}
|
|
18113
18263
|
async function listCommand(args2) {
|
|
18114
|
-
const { orgId, json } =
|
|
18264
|
+
const { orgId, json } = parseArgs18(args2);
|
|
18115
18265
|
const { config, accessToken } = await requireAuth();
|
|
18116
18266
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
18117
18267
|
const { organizations } = await client.organizations();
|
|
@@ -18164,20 +18314,20 @@ var init_list = __esm({
|
|
|
18164
18314
|
});
|
|
18165
18315
|
|
|
18166
18316
|
// src/lib/template-files.ts
|
|
18167
|
-
import * as
|
|
18168
|
-
import * as
|
|
18317
|
+
import * as fs18 from "fs";
|
|
18318
|
+
import * as path23 from "path";
|
|
18169
18319
|
function readDirToFileMap(rootDir) {
|
|
18170
18320
|
const out = {};
|
|
18171
18321
|
function walk(dir, prefix) {
|
|
18172
|
-
const entries =
|
|
18322
|
+
const entries = fs18.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
18173
18323
|
for (const entry of entries) {
|
|
18174
|
-
const abs =
|
|
18324
|
+
const abs = path23.join(dir, entry.name);
|
|
18175
18325
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
18176
18326
|
if (entry.isDirectory()) walk(abs, rel);
|
|
18177
|
-
else if (entry.isFile()) out[rel] =
|
|
18327
|
+
else if (entry.isFile()) out[rel] = fs18.readFileSync(abs, "utf-8");
|
|
18178
18328
|
}
|
|
18179
18329
|
}
|
|
18180
|
-
if (
|
|
18330
|
+
if (fs18.existsSync(rootDir)) walk(rootDir, "");
|
|
18181
18331
|
return out;
|
|
18182
18332
|
}
|
|
18183
18333
|
function detectCollisions(targetDir, files) {
|
|
@@ -18186,7 +18336,7 @@ function detectCollisions(targetDir, files) {
|
|
|
18186
18336
|
if (!isSafeTemplatePath2(rel)) {
|
|
18187
18337
|
throw new Error(`Refusing to inspect unsafe template path: ${rel}`);
|
|
18188
18338
|
}
|
|
18189
|
-
if (
|
|
18339
|
+
if (fs18.existsSync(path23.join(targetDir, rel))) collisions.push(rel);
|
|
18190
18340
|
}
|
|
18191
18341
|
return collisions.sort((a, b) => a.localeCompare(b));
|
|
18192
18342
|
}
|
|
@@ -18196,9 +18346,9 @@ function writeFileMap(targetDir, files) {
|
|
|
18196
18346
|
if (!isSafeTemplatePath2(rel)) {
|
|
18197
18347
|
throw new Error(`Refusing to write unsafe template path: ${rel}`);
|
|
18198
18348
|
}
|
|
18199
|
-
const abs =
|
|
18200
|
-
|
|
18201
|
-
|
|
18349
|
+
const abs = path23.join(targetDir, rel);
|
|
18350
|
+
fs18.mkdirSync(path23.dirname(abs), { recursive: true });
|
|
18351
|
+
fs18.writeFileSync(abs, body, "utf-8");
|
|
18202
18352
|
written.push(rel);
|
|
18203
18353
|
}
|
|
18204
18354
|
return written;
|
|
@@ -18206,20 +18356,20 @@ function writeFileMap(targetDir, files) {
|
|
|
18206
18356
|
function listDirRelFiles(dir) {
|
|
18207
18357
|
const out = [];
|
|
18208
18358
|
function walk(d, prefix) {
|
|
18209
|
-
for (const entry of
|
|
18359
|
+
for (const entry of fs18.readdirSync(d, { withFileTypes: true })) {
|
|
18210
18360
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
18211
|
-
if (entry.isDirectory()) walk(
|
|
18361
|
+
if (entry.isDirectory()) walk(path23.join(d, entry.name), rel);
|
|
18212
18362
|
else if (entry.isFile()) out.push(rel);
|
|
18213
18363
|
}
|
|
18214
18364
|
}
|
|
18215
|
-
if (
|
|
18365
|
+
if (fs18.existsSync(dir)) walk(dir, "");
|
|
18216
18366
|
return out;
|
|
18217
18367
|
}
|
|
18218
18368
|
function writeSliceSnapshot(targetDir, files) {
|
|
18219
18369
|
const keep = new Set(Object.keys(files));
|
|
18220
18370
|
const removed = listDirRelFiles(targetDir).filter((rel) => !keep.has(rel)).sort((a, b) => a.localeCompare(b));
|
|
18221
18371
|
const written = writeFileMap(targetDir, files).sort((a, b) => a.localeCompare(b));
|
|
18222
|
-
if (
|
|
18372
|
+
if (fs18.existsSync(targetDir)) cleanOrphanFiles(targetDir, "", keep);
|
|
18223
18373
|
return { written, removed };
|
|
18224
18374
|
}
|
|
18225
18375
|
var init_template_files = __esm({
|
|
@@ -18235,7 +18385,7 @@ var templates_exports = {};
|
|
|
18235
18385
|
__export(templates_exports, {
|
|
18236
18386
|
templateCommand: () => templateCommand
|
|
18237
18387
|
});
|
|
18238
|
-
import * as
|
|
18388
|
+
import * as path24 from "path";
|
|
18239
18389
|
async function templateCommand(args2) {
|
|
18240
18390
|
const [sub, ...rest] = args2;
|
|
18241
18391
|
switch (sub) {
|
|
@@ -18351,8 +18501,8 @@ async function runTemplatePull(rest) {
|
|
|
18351
18501
|
console.log(`Template "${slug}" has no WayAI slice${hint}`);
|
|
18352
18502
|
return;
|
|
18353
18503
|
}
|
|
18354
|
-
const targetDir =
|
|
18355
|
-
const relTarget =
|
|
18504
|
+
const targetDir = path24.join(resolveLayout(gitRoot).hubsDir, slug);
|
|
18505
|
+
const relTarget = path24.relative(gitRoot, targetDir);
|
|
18356
18506
|
const collisions = detectCollisions(targetDir, detail.files);
|
|
18357
18507
|
if (dryRun) {
|
|
18358
18508
|
const planned = Object.keys(detail.files).sort((a, b) => a.localeCompare(b));
|
|
@@ -18526,8 +18676,8 @@ var admin_exports = {};
|
|
|
18526
18676
|
__export(admin_exports, {
|
|
18527
18677
|
adminCommand: () => adminCommand
|
|
18528
18678
|
});
|
|
18529
|
-
import * as
|
|
18530
|
-
import * as
|
|
18679
|
+
import * as fs19 from "fs";
|
|
18680
|
+
import * as path25 from "path";
|
|
18531
18681
|
import * as yaml10 from "js-yaml";
|
|
18532
18682
|
async function adminCommand(args2) {
|
|
18533
18683
|
const [group, ...afterGroup] = args2;
|
|
@@ -18835,7 +18985,7 @@ async function runArchiveRead(positional, flagArgs) {
|
|
|
18835
18985
|
exitOnApiError(err);
|
|
18836
18986
|
throw err;
|
|
18837
18987
|
}
|
|
18838
|
-
|
|
18988
|
+
fs19.writeFileSync(outPath, zip);
|
|
18839
18989
|
console.log(`Wrote ${zip.byteLength} bytes to ${outPath}`);
|
|
18840
18990
|
return;
|
|
18841
18991
|
}
|
|
@@ -18967,15 +19117,15 @@ function loadTemplateManifest(slug) {
|
|
|
18967
19117
|
console.error("Not in a git repository. Run from the tutorials/ authoring repo.");
|
|
18968
19118
|
process.exit(1);
|
|
18969
19119
|
}
|
|
18970
|
-
const templateDir =
|
|
18971
|
-
const manifestPath =
|
|
18972
|
-
if (!
|
|
18973
|
-
console.error(`template.yaml not found at ${
|
|
19120
|
+
const templateDir = path25.join(resolveTemplatesDir(gitRoot), slug);
|
|
19121
|
+
const manifestPath = path25.join(templateDir, "template.yaml");
|
|
19122
|
+
if (!fs19.existsSync(manifestPath)) {
|
|
19123
|
+
console.error(`template.yaml not found at ${path25.relative(gitRoot, manifestPath)}`);
|
|
18974
19124
|
process.exit(1);
|
|
18975
19125
|
}
|
|
18976
19126
|
let manifest;
|
|
18977
19127
|
try {
|
|
18978
|
-
manifest = templateYamlSchema2.parse(yaml10.load(
|
|
19128
|
+
manifest = templateYamlSchema2.parse(yaml10.load(fs19.readFileSync(manifestPath, "utf-8")));
|
|
18979
19129
|
} catch (err) {
|
|
18980
19130
|
console.error(`Invalid template.yaml: ${err instanceof Error ? err.message : String(err)}`);
|
|
18981
19131
|
process.exit(1);
|
|
@@ -19005,20 +19155,20 @@ async function runTemplatePush(positional) {
|
|
|
19005
19155
|
const wayaiEntry = manifest.wayai.locales[locale];
|
|
19006
19156
|
let wayaiFiles;
|
|
19007
19157
|
if (wayaiEntry) {
|
|
19008
|
-
const sliceDir =
|
|
19009
|
-
if (!
|
|
19158
|
+
const sliceDir = path25.resolve(templateDir, wayaiEntry.source);
|
|
19159
|
+
if (!fs19.existsSync(sliceDir)) {
|
|
19010
19160
|
console.error(`wayai source not found for ${locale}: ${wayaiEntry.source} (resolved ${sliceDir})`);
|
|
19011
19161
|
process.exit(1);
|
|
19012
19162
|
}
|
|
19013
19163
|
if (!isInsideTemplateDir(sliceDir, templateDir)) {
|
|
19014
19164
|
console.warn(
|
|
19015
|
-
`Note: ${locale} source points at a live hub (${wayaiEntry.source}); it can go stale on a hub recreate. Run \`wayai admin template freeze ${slug} --locale ${locale} --from ${
|
|
19165
|
+
`Note: ${locale} source points at a live hub (${wayaiEntry.source}); it can go stale on a hub recreate. Run \`wayai admin template freeze ${slug} --locale ${locale} --from ${path25.basename(sliceDir)}\` to commit a stable frozen slice.`
|
|
19016
19166
|
);
|
|
19017
19167
|
}
|
|
19018
19168
|
wayaiFiles = readDirToFileMap(sliceDir);
|
|
19019
19169
|
}
|
|
19020
|
-
const readmePath =
|
|
19021
|
-
const readmeMarkdown =
|
|
19170
|
+
const readmePath = path25.join(templateDir, `README.${locale}.md`);
|
|
19171
|
+
const readmeMarkdown = fs19.existsSync(readmePath) ? fs19.readFileSync(readmePath, "utf-8") : "";
|
|
19022
19172
|
locales[locale] = {
|
|
19023
19173
|
readmeMarkdown,
|
|
19024
19174
|
...wayaiFiles && { wayaiFiles },
|
|
@@ -19029,9 +19179,9 @@ async function runTemplatePush(positional) {
|
|
|
19029
19179
|
}
|
|
19030
19180
|
let hero;
|
|
19031
19181
|
if (manifest.hero) {
|
|
19032
|
-
const heroPath =
|
|
19033
|
-
if (
|
|
19034
|
-
hero = { filename:
|
|
19182
|
+
const heroPath = path25.resolve(templateDir, manifest.hero);
|
|
19183
|
+
if (fs19.existsSync(heroPath)) {
|
|
19184
|
+
hero = { filename: path25.basename(heroPath), dataBase64: fs19.readFileSync(heroPath).toString("base64") };
|
|
19035
19185
|
} else {
|
|
19036
19186
|
console.error(`Warning: hero not found at ${manifest.hero}; skipping.`);
|
|
19037
19187
|
}
|
|
@@ -19057,7 +19207,7 @@ async function runTemplatePush(positional) {
|
|
|
19057
19207
|
}
|
|
19058
19208
|
}
|
|
19059
19209
|
function isInsideTemplateDir(dest, templateDir) {
|
|
19060
|
-
return dest === templateDir || dest.startsWith(templateDir +
|
|
19210
|
+
return dest === templateDir || dest.startsWith(templateDir + path25.sep);
|
|
19061
19211
|
}
|
|
19062
19212
|
async function runTemplateFreeze(positional, flagArgs) {
|
|
19063
19213
|
const slug = positional[0];
|
|
@@ -19118,7 +19268,7 @@ async function runTemplateFreeze(positional, flagArgs) {
|
|
|
19118
19268
|
process.exit(1);
|
|
19119
19269
|
}
|
|
19120
19270
|
const entry = manifest.wayai.locales[targetLocale];
|
|
19121
|
-
const dest =
|
|
19271
|
+
const dest = path25.resolve(templateDir, entry.source);
|
|
19122
19272
|
if (!isInsideTemplateDir(dest, templateDir) || dest === templateDir) {
|
|
19123
19273
|
console.error(
|
|
19124
19274
|
`source for "${targetLocale}" must be a committed path inside ${slug}/ (e.g. "./${targetLocale}/slice"), but resolved to:
|
|
@@ -19137,7 +19287,7 @@ Set it to a subdir of the template folder and re-run freeze.`
|
|
|
19137
19287
|
const hubs = scanWorkspaceHubs(hubsDir);
|
|
19138
19288
|
if (hubs.length) {
|
|
19139
19289
|
console.error("Available hubs:");
|
|
19140
|
-
for (const h of hubs) console.error(` ${
|
|
19290
|
+
for (const h of hubs) console.error(` ${path25.basename(h.hubFolder)} (${h.hubId})`);
|
|
19141
19291
|
}
|
|
19142
19292
|
console.error(`
|
|
19143
19293
|
Pass --from <folder|uuid>${selector ? "." : " or run `wayai use <hub>` first."}`);
|
|
@@ -19145,12 +19295,12 @@ Pass --from <folder|uuid>${selector ? "." : " or run `wayai use <hub>` first."}`
|
|
|
19145
19295
|
}
|
|
19146
19296
|
const liveFiles = readDirToFileMap(hubFolder);
|
|
19147
19297
|
if (Object.keys(liveFiles).length === 0) {
|
|
19148
|
-
console.error(`Source hub folder has no files to freeze: ${
|
|
19298
|
+
console.error(`Source hub folder has no files to freeze: ${path25.relative(gitRoot, hubFolder)}`);
|
|
19149
19299
|
process.exit(1);
|
|
19150
19300
|
}
|
|
19151
19301
|
const sanitized = sanitizeWayaiSliceFiles(liveFiles);
|
|
19152
|
-
const relDest =
|
|
19153
|
-
const relSrc =
|
|
19302
|
+
const relDest = path25.relative(gitRoot, dest);
|
|
19303
|
+
const relSrc = path25.relative(gitRoot, hubFolder);
|
|
19154
19304
|
if (dryRun) {
|
|
19155
19305
|
const existing = new Set(listDirRelFiles(dest));
|
|
19156
19306
|
const nextKeys = new Set(Object.keys(sanitized));
|
|
@@ -19210,7 +19360,7 @@ async function runTemplatePull2(positional, flagArgs) {
|
|
|
19210
19360
|
console.log(JSON.stringify(detail, null, 2));
|
|
19211
19361
|
return;
|
|
19212
19362
|
}
|
|
19213
|
-
const target = outDir ?
|
|
19363
|
+
const target = outDir ? path25.resolve(outDir) : path25.join(process.cwd(), "template-store-pull", slug);
|
|
19214
19364
|
const written = writeFileMap(target, detail.files);
|
|
19215
19365
|
console.log(`Pulled "${slug}" from the store \u2192 ${target} (${written.length} file${written.length === 1 ? "" : "s"}).`);
|
|
19216
19366
|
const uses = detail.uses ?? [];
|
|
@@ -19233,13 +19383,13 @@ async function runSkillInstall(positional) {
|
|
|
19233
19383
|
throw err;
|
|
19234
19384
|
}
|
|
19235
19385
|
const root = findGitRoot() ?? process.cwd();
|
|
19236
|
-
const present = HARNESS_SKILL_DIRS.filter((dir) =>
|
|
19386
|
+
const present = HARNESS_SKILL_DIRS.filter((dir) => fs19.existsSync(path25.join(root, dir)));
|
|
19237
19387
|
const targets = present.length > 0 ? present : HARNESS_SKILL_DIRS;
|
|
19238
19388
|
const fileCount = Object.keys(res.files).length;
|
|
19239
19389
|
const relDirs = targets.map((harness) => {
|
|
19240
|
-
const targetDir =
|
|
19390
|
+
const targetDir = path25.join(root, harness, "skills", name);
|
|
19241
19391
|
writeFileMap(targetDir, res.files);
|
|
19242
|
-
return `${
|
|
19392
|
+
return `${path25.relative(root, targetDir)}/`;
|
|
19243
19393
|
});
|
|
19244
19394
|
console.log(`Installed skill "${name}" (${fileCount} file${fileCount === 1 ? "" : "s"}) \u2192 ${relDirs.join(", ")}`);
|
|
19245
19395
|
console.log("Reload your agent (e.g. restart Claude Code) to pick up the skill.");
|
|
@@ -20072,19 +20222,58 @@ var init_admin = __esm({
|
|
|
20072
20222
|
}
|
|
20073
20223
|
});
|
|
20074
20224
|
|
|
20075
|
-
// src/
|
|
20076
|
-
|
|
20077
|
-
|
|
20078
|
-
|
|
20079
|
-
function
|
|
20080
|
-
|
|
20081
|
-
|
|
20082
|
-
|
|
20083
|
-
|
|
20084
|
-
|
|
20225
|
+
// src/lib/version-status.ts
|
|
20226
|
+
function componentStatus(current, latest) {
|
|
20227
|
+
return { current, latest, behind: Boolean(current && latest && isNewerVersion(latest, current)) };
|
|
20228
|
+
}
|
|
20229
|
+
function resolveVersionStatus(cliVersion) {
|
|
20230
|
+
const cliLatest = readVersionCache(CLI_CACHE_FILE)?.latest ?? null;
|
|
20231
|
+
const repoRoot = findRepoRootSync() ?? process.cwd();
|
|
20232
|
+
const skillCurrent = lowestInstalledVersion(findInstalledSkills(repoRoot));
|
|
20233
|
+
const skillLatest = skillCurrent ? readVersionCache(SKILL_CACHE_FILE)?.latest ?? null : null;
|
|
20234
|
+
return { cli: componentStatus(cliVersion, cliLatest), skill: componentStatus(skillCurrent, skillLatest) };
|
|
20235
|
+
}
|
|
20236
|
+
function isVersionBehind(status) {
|
|
20237
|
+
return status.cli.behind || status.skill.behind;
|
|
20238
|
+
}
|
|
20239
|
+
function formatClientVersion(status) {
|
|
20240
|
+
const cli = `cli@${status.cli.current ?? "unknown"}`;
|
|
20241
|
+
if (!status.skill.current) return cli.slice(0, 64);
|
|
20242
|
+
const withSkill = `${cli} skill@${status.skill.current}`;
|
|
20243
|
+
return withSkill.length <= 64 ? withSkill : cli.slice(0, 64);
|
|
20244
|
+
}
|
|
20245
|
+
function buildStaleToolingWarning(status) {
|
|
20246
|
+
const lines = [];
|
|
20247
|
+
if (status.cli.behind) {
|
|
20248
|
+
lines.push(` CLI ${status.cli.current} \u2192 ${status.cli.latest} (run: wayai update)`);
|
|
20249
|
+
}
|
|
20250
|
+
if (status.skill.behind) {
|
|
20251
|
+
lines.push(` Skill ${status.skill.current} \u2192 ${status.skill.latest} (run: npx skills add wayai-pro/wayai-skill -y)`);
|
|
20252
|
+
}
|
|
20253
|
+
if (lines.length === 0) return null;
|
|
20254
|
+
return [
|
|
20255
|
+
"Your WayAI tooling is behind the latest release:",
|
|
20256
|
+
...lines,
|
|
20257
|
+
"",
|
|
20258
|
+
"A stale CLI or skill is the most common cause of a false bug report \u2014 the issue may",
|
|
20259
|
+
"already be fixed upstream. Update, then reproduce before reporting."
|
|
20260
|
+
].join("\n");
|
|
20261
|
+
}
|
|
20262
|
+
var init_version_status = __esm({
|
|
20263
|
+
"src/lib/version-status.ts"() {
|
|
20264
|
+
"use strict";
|
|
20265
|
+
init_version_cache();
|
|
20266
|
+
init_skill_version();
|
|
20267
|
+
init_workspace();
|
|
20268
|
+
init_utils();
|
|
20085
20269
|
}
|
|
20270
|
+
});
|
|
20271
|
+
|
|
20272
|
+
// src/commands/report-create.ts
|
|
20273
|
+
function isVersionGateDisabled() {
|
|
20274
|
+
return Boolean(process.env.NO_UPDATE_NOTIFIER || process.env.WAYAI_NO_UPDATE_CHECK);
|
|
20086
20275
|
}
|
|
20087
|
-
async function reportCreateCommand(args2) {
|
|
20276
|
+
async function reportCreateCommand(args2, cliVersion = null) {
|
|
20088
20277
|
let title;
|
|
20089
20278
|
let description;
|
|
20090
20279
|
let source;
|
|
@@ -20095,9 +20284,12 @@ async function reportCreateCommand(args2) {
|
|
|
20095
20284
|
let errorMessage;
|
|
20096
20285
|
let steps;
|
|
20097
20286
|
let context;
|
|
20287
|
+
let skipVersionCheck = false;
|
|
20098
20288
|
for (let i = 0; i < args2.length; i++) {
|
|
20099
20289
|
const arg = args2[i];
|
|
20100
|
-
if (arg === "--
|
|
20290
|
+
if (arg === "--skip-version-check") {
|
|
20291
|
+
skipVersionCheck = true;
|
|
20292
|
+
} else if (arg === "--title" || arg === "-t") {
|
|
20101
20293
|
title = args2[++i];
|
|
20102
20294
|
} else if (arg === "--description" || arg === "-d") {
|
|
20103
20295
|
description = args2[++i];
|
|
@@ -20135,8 +20327,23 @@ async function reportCreateCommand(args2) {
|
|
|
20135
20327
|
console.error(" -e, --error <text> Error message or stack trace");
|
|
20136
20328
|
console.error(" -s, --steps <text> Steps to reproduce");
|
|
20137
20329
|
console.error(" --context <text> Additional context");
|
|
20330
|
+
console.error(" --skip-version-check File even when the CLI/skill is behind the latest release");
|
|
20138
20331
|
process.exit(1);
|
|
20139
20332
|
}
|
|
20333
|
+
const versionStatus = resolveVersionStatus(cliVersion);
|
|
20334
|
+
const clientVersion = formatClientVersion(versionStatus);
|
|
20335
|
+
if (isVersionBehind(versionStatus) && !isVersionGateDisabled()) {
|
|
20336
|
+
const warning = buildStaleToolingWarning(versionStatus);
|
|
20337
|
+
if (!skipVersionCheck) {
|
|
20338
|
+
console.error(warning);
|
|
20339
|
+
console.error("");
|
|
20340
|
+
console.error("To file this report anyway, re-run with --skip-version-check.");
|
|
20341
|
+
process.exit(1);
|
|
20342
|
+
}
|
|
20343
|
+
console.error("Filing on stale tooling (--skip-version-check):");
|
|
20344
|
+
console.error(warning);
|
|
20345
|
+
console.error("");
|
|
20346
|
+
}
|
|
20140
20347
|
const { config, accessToken } = await requireAuth();
|
|
20141
20348
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
20142
20349
|
const repoConfig = readRepoConfig();
|
|
@@ -20154,7 +20361,7 @@ async function reportCreateCommand(args2) {
|
|
|
20154
20361
|
error_message: errorMessage,
|
|
20155
20362
|
steps_to_reproduce: steps,
|
|
20156
20363
|
additional_context: context,
|
|
20157
|
-
client_version:
|
|
20364
|
+
client_version: clientVersion
|
|
20158
20365
|
});
|
|
20159
20366
|
if (result.created) {
|
|
20160
20367
|
console.log(`Report submitted: ${result.report_id}`);
|
|
@@ -20178,14 +20385,13 @@ async function reportCreateCommand(args2) {
|
|
|
20178
20385
|
throw err;
|
|
20179
20386
|
}
|
|
20180
20387
|
}
|
|
20181
|
-
var __dirname;
|
|
20182
20388
|
var init_report_create = __esm({
|
|
20183
20389
|
"src/commands/report-create.ts"() {
|
|
20184
20390
|
"use strict";
|
|
20185
20391
|
init_auth();
|
|
20186
20392
|
init_repo_config();
|
|
20187
20393
|
init_api_client();
|
|
20188
|
-
|
|
20394
|
+
init_version_status();
|
|
20189
20395
|
}
|
|
20190
20396
|
});
|
|
20191
20397
|
|
|
@@ -20194,11 +20400,11 @@ var report_exports = {};
|
|
|
20194
20400
|
__export(report_exports, {
|
|
20195
20401
|
reportCommand: () => reportCommand
|
|
20196
20402
|
});
|
|
20197
|
-
async function reportCommand(args2) {
|
|
20403
|
+
async function reportCommand(args2, cliVersion) {
|
|
20198
20404
|
const sub = args2[0];
|
|
20199
20405
|
switch (sub) {
|
|
20200
20406
|
case "create":
|
|
20201
|
-
await reportCreateCommand(args2.slice(1));
|
|
20407
|
+
await reportCreateCommand(args2.slice(1), cliVersion ?? null);
|
|
20202
20408
|
return;
|
|
20203
20409
|
case "edit":
|
|
20204
20410
|
await reportEditCommand(args2.slice(1));
|
|
@@ -20460,9 +20666,9 @@ var init_update = __esm({
|
|
|
20460
20666
|
|
|
20461
20667
|
// src/index.ts
|
|
20462
20668
|
init_sentry();
|
|
20463
|
-
import { readFileSync as
|
|
20464
|
-
import { fileURLToPath as
|
|
20465
|
-
import { dirname as
|
|
20669
|
+
import { readFileSync as readFileSync18 } from "fs";
|
|
20670
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
20671
|
+
import { dirname as dirname9, join as join24 } from "path";
|
|
20466
20672
|
|
|
20467
20673
|
// src/lib/errors.ts
|
|
20468
20674
|
init_api_client();
|
|
@@ -20494,7 +20700,7 @@ init_skill_version();
|
|
|
20494
20700
|
import { exec } from "child_process";
|
|
20495
20701
|
var REFRESH_TIMEOUT_MS = 1e4;
|
|
20496
20702
|
function refreshCliCache() {
|
|
20497
|
-
return new Promise((
|
|
20703
|
+
return new Promise((resolve4) => {
|
|
20498
20704
|
exec("npm view @wayai/cli version", { timeout: REFRESH_TIMEOUT_MS }, (err, stdout) => {
|
|
20499
20705
|
if (!err) {
|
|
20500
20706
|
const latest = stdout.trim();
|
|
@@ -20505,7 +20711,7 @@ function refreshCliCache() {
|
|
|
20505
20711
|
}
|
|
20506
20712
|
}
|
|
20507
20713
|
}
|
|
20508
|
-
|
|
20714
|
+
resolve4();
|
|
20509
20715
|
});
|
|
20510
20716
|
});
|
|
20511
20717
|
}
|
|
@@ -20531,8 +20737,8 @@ async function refreshSkillCache() {
|
|
|
20531
20737
|
}
|
|
20532
20738
|
async function refreshAdminSkillCache() {
|
|
20533
20739
|
let timer;
|
|
20534
|
-
const deadline = new Promise((
|
|
20535
|
-
timer = setTimeout(
|
|
20740
|
+
const deadline = new Promise((resolve4) => {
|
|
20741
|
+
timer = setTimeout(resolve4, REFRESH_TIMEOUT_MS);
|
|
20536
20742
|
});
|
|
20537
20743
|
await Promise.race([deadline, fetchAndCacheAdminSkillVersion().catch(() => {
|
|
20538
20744
|
})]);
|
|
@@ -20641,11 +20847,11 @@ Run \`wayai admin skill install\` to update.`);
|
|
|
20641
20847
|
}
|
|
20642
20848
|
|
|
20643
20849
|
// src/index.ts
|
|
20644
|
-
var
|
|
20645
|
-
var pkg = JSON.parse(
|
|
20850
|
+
var __dirname = dirname9(fileURLToPath2(import.meta.url));
|
|
20851
|
+
var pkg = JSON.parse(readFileSync18(join24(__dirname, "..", "package.json"), "utf-8"));
|
|
20646
20852
|
var [, , command, ...args] = process.argv;
|
|
20647
20853
|
var isBackgroundRefresh = command === REFRESH_COMMAND;
|
|
20648
|
-
if (!isBackgroundRefresh) initSentry(command);
|
|
20854
|
+
if (!isBackgroundRefresh) initSentry(command, pkg.version);
|
|
20649
20855
|
async function main() {
|
|
20650
20856
|
if (shouldInterceptHelp(command, args, OWN_HELP_COMMANDS)) {
|
|
20651
20857
|
printHelp3();
|
|
@@ -20696,6 +20902,11 @@ async function main() {
|
|
|
20696
20902
|
await pushCommand2(args);
|
|
20697
20903
|
break;
|
|
20698
20904
|
}
|
|
20905
|
+
case "create": {
|
|
20906
|
+
const { createCommand: createCommand2 } = await Promise.resolve().then(() => (init_create(), create_exports));
|
|
20907
|
+
await createCommand2(args);
|
|
20908
|
+
break;
|
|
20909
|
+
}
|
|
20699
20910
|
case "diff": {
|
|
20700
20911
|
const { diffCommand: diffCommand2 } = await Promise.resolve().then(() => (init_diff(), diff_exports));
|
|
20701
20912
|
await diffCommand2(args);
|
|
@@ -20823,7 +21034,7 @@ async function main() {
|
|
|
20823
21034
|
}
|
|
20824
21035
|
case "report": {
|
|
20825
21036
|
const { reportCommand: reportCommand2 } = await Promise.resolve().then(() => (init_report(), report_exports));
|
|
20826
|
-
await reportCommand2(args);
|
|
21037
|
+
await reportCommand2(args, pkg.version);
|
|
20827
21038
|
break;
|
|
20828
21039
|
}
|
|
20829
21040
|
case "update": {
|
|
@@ -20866,6 +21077,7 @@ Commands:
|
|
|
20866
21077
|
set-connection-credential Set a connection's credential directly (org link or --field/--stdin), preview or production
|
|
20867
21078
|
pull Fetch hub config and write local files (also mirrors the linked production hub read-only)
|
|
20868
21079
|
push Parse local files, show diff, sync to preview (creates hub if new)
|
|
21080
|
+
create [folder] Explicitly create a new hub from an idless folder, then push (--label to name the preview)
|
|
20869
21081
|
diff Dry-run diff of local files vs the platform (--production diffs vs the linked production hub)
|
|
20870
21082
|
replicate Clone a hub into a new sibling preview (--label to name it)
|
|
20871
21083
|
relabel Set a preview hub's label (--clear to remove it)
|
|
@@ -20898,7 +21110,7 @@ Flags:
|
|
|
20898
21110
|
--yes, -y Skip confirmation prompts (useful for CI and scripting)
|
|
20899
21111
|
--hub <uuid|name> Target hub when the workspace has more than one (push, pull, diff, replicate, relabel, publish)
|
|
20900
21112
|
--production Diff local preview files against the linked production hub (diff)
|
|
20901
|
-
--label <name> Preview label \u2014 for the new sibling (replicate) or a brand-new hub (push on create)
|
|
21113
|
+
--label <name> Preview label \u2014 for the new sibling (replicate) or a brand-new hub (create, or push on create)
|
|
20902
21114
|
--clear Remove the preview label (relabel)
|
|
20903
21115
|
--name <name> Credential name (create-credential; target for update-credential)
|
|
20904
21116
|
--type <auth-type> Auth type: "api_key", "bearer", "basic_auth" (create-credential)
|
|
@@ -20959,7 +21171,7 @@ async function runForeground() {
|
|
|
20959
21171
|
try {
|
|
20960
21172
|
await main();
|
|
20961
21173
|
if (command && !SKIP_UPDATE_CHECK.includes(command) && !wantsHelp(args)) {
|
|
20962
|
-
showUpdateNudges(pkg.version,
|
|
21174
|
+
showUpdateNudges(pkg.version, fileURLToPath2(import.meta.url));
|
|
20963
21175
|
}
|
|
20964
21176
|
await closeSentry();
|
|
20965
21177
|
} catch (err) {
|