@wayai/cli 0.3.86 → 0.3.88
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 +463 -299
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -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
|
);
|
|
@@ -5914,7 +5914,12 @@ var init_dist = __esm({
|
|
|
5914
5914
|
// A NATIVE LLM (Agent) connection id on this hub; validated at set-time on the REST
|
|
5915
5915
|
// PATCH (setup/hubs.ts rejects a non-existent / non-Agent / harness id) and re-checked
|
|
5916
5916
|
// at fallback time in the turn seam (a stale/missing id simply no-ops). Nullable to clear it.
|
|
5917
|
-
fallback_connection_id: uuidSchema.nullable().optional()
|
|
5917
|
+
fallback_connection_id: uuidSchema.nullable().optional(),
|
|
5918
|
+
// Rekor API connection used to reset/clear eval seed fixtures (gh #3090). A
|
|
5919
|
+
// connection id on this hub (a REST API (custom tool) connection whose base_url
|
|
5920
|
+
// is the Rekor API origin + a bearer/api_key `write:seeds` token). Validated at
|
|
5921
|
+
// set-time on the REST PATCH (setup/hubs.ts). Nullable to clear it.
|
|
5922
|
+
seed_connection_id: uuidSchema.nullable().optional()
|
|
5918
5923
|
}).passthrough().superRefine(refineLaneReferences);
|
|
5919
5924
|
addHubAdminBody = external_exports.object({
|
|
5920
5925
|
user_email: external_exports.string().email("valid email is required")
|
|
@@ -7455,7 +7460,6 @@ var init_dist = __esm({
|
|
|
7455
7460
|
dataExplorerDebugAnalyticsTable = external_exports.enum([
|
|
7456
7461
|
"conversation",
|
|
7457
7462
|
"message",
|
|
7458
|
-
"billing_event",
|
|
7459
7463
|
"schedule_event"
|
|
7460
7464
|
]);
|
|
7461
7465
|
debugUuid = external_exports.string().uuid();
|
|
@@ -7637,7 +7641,7 @@ var init_dist = __esm({
|
|
|
7637
7641
|
message: "at least one field must be provided"
|
|
7638
7642
|
});
|
|
7639
7643
|
contestReportBody = external_exports.object({
|
|
7640
|
-
reason: external_exports.string().min(1).max(
|
|
7644
|
+
reason: external_exports.string().min(1).max(5e3)
|
|
7641
7645
|
});
|
|
7642
7646
|
reporterListQuery = external_exports.object({
|
|
7643
7647
|
status: reportStatusSchema.optional()
|
|
@@ -7669,7 +7673,7 @@ var init_dist = __esm({
|
|
|
7669
7673
|
}),
|
|
7670
7674
|
external_exports.object({
|
|
7671
7675
|
target: external_exports.literal("dismissed"),
|
|
7672
|
-
dismissal_reason: external_exports.string().min(1).max(
|
|
7676
|
+
dismissal_reason: external_exports.string().min(1).max(5e3),
|
|
7673
7677
|
ai_verdict: external_exports.string().max(2e3).optional(),
|
|
7674
7678
|
final: external_exports.boolean().optional()
|
|
7675
7679
|
})
|
|
@@ -7678,7 +7682,7 @@ var init_dist = __esm({
|
|
|
7678
7682
|
member_ids: external_exports.array(external_exports.string().uuid()).min(1).max(100)
|
|
7679
7683
|
});
|
|
7680
7684
|
holdReportBody = external_exports.object({
|
|
7681
|
-
reason: external_exports.string().min(1).max(
|
|
7685
|
+
reason: external_exports.string().min(1).max(5e3)
|
|
7682
7686
|
});
|
|
7683
7687
|
clickhouseReadyResponse = external_exports.object({
|
|
7684
7688
|
ready: external_exports.boolean()
|
|
@@ -8125,6 +8129,7 @@ __export(workspace_exports, {
|
|
|
8125
8129
|
detectWorkspace: () => detectWorkspace,
|
|
8126
8130
|
filterPreviewHubs: () => filterPreviewHubs,
|
|
8127
8131
|
findEnclosingHubFolder: () => findEnclosingHubFolder,
|
|
8132
|
+
findEnclosingNewHubFolder: () => findEnclosingNewHubFolder,
|
|
8128
8133
|
findGitRoot: () => findGitRoot,
|
|
8129
8134
|
findHubByFolderName: () => findHubByFolderName,
|
|
8130
8135
|
findLocalHubFolder: () => findLocalHubFolder,
|
|
@@ -8137,6 +8142,8 @@ __export(workspace_exports, {
|
|
|
8137
8142
|
resolveExplicitHubPath: () => resolveExplicitHubPath,
|
|
8138
8143
|
resolveHubFolder: () => resolveHubFolder,
|
|
8139
8144
|
resolveHubFolderBySelector: () => resolveHubFolderBySelector,
|
|
8145
|
+
resolveNewHubForCreate: () => resolveNewHubForCreate,
|
|
8146
|
+
resolvePushTarget: () => resolvePushTarget,
|
|
8140
8147
|
resolveWorkspaceDir: () => resolveWorkspaceDir,
|
|
8141
8148
|
scanNewHubs: () => scanNewHubs,
|
|
8142
8149
|
scanWorkspaceHubs: () => scanWorkspaceHubs
|
|
@@ -8379,6 +8386,56 @@ function findEnclosingHubFolder(workspaceDir) {
|
|
|
8379
8386
|
current = parent;
|
|
8380
8387
|
}
|
|
8381
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
|
+
}
|
|
8382
8439
|
function resolveActiveHubId(args2) {
|
|
8383
8440
|
let selector;
|
|
8384
8441
|
const hubIdx = args2.indexOf("--hub");
|
|
@@ -8533,24 +8590,24 @@ import * as path4 from "path";
|
|
|
8533
8590
|
import * as readline from "readline";
|
|
8534
8591
|
function prompt(question) {
|
|
8535
8592
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
8536
|
-
return new Promise((
|
|
8593
|
+
return new Promise((resolve4) => {
|
|
8537
8594
|
rl.question(question, (answer) => {
|
|
8538
8595
|
rl.close();
|
|
8539
|
-
|
|
8596
|
+
resolve4(answer.trim());
|
|
8540
8597
|
});
|
|
8541
8598
|
});
|
|
8542
8599
|
}
|
|
8543
8600
|
function confirm(question) {
|
|
8544
8601
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
8545
|
-
return new Promise((
|
|
8602
|
+
return new Promise((resolve4) => {
|
|
8546
8603
|
rl.question(`${question} [y/N]: `, (answer) => {
|
|
8547
8604
|
rl.close();
|
|
8548
|
-
|
|
8605
|
+
resolve4(answer.trim().toLowerCase() === "y");
|
|
8549
8606
|
});
|
|
8550
8607
|
});
|
|
8551
8608
|
}
|
|
8552
8609
|
function promptSecret(question) {
|
|
8553
|
-
return new Promise((
|
|
8610
|
+
return new Promise((resolve4) => {
|
|
8554
8611
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
8555
8612
|
const originalWrite = rl._writeToOutput;
|
|
8556
8613
|
let firstWrite = true;
|
|
@@ -8566,18 +8623,18 @@ function promptSecret(question) {
|
|
|
8566
8623
|
rl._writeToOutput = originalWrite;
|
|
8567
8624
|
process.stdout.write("\n");
|
|
8568
8625
|
rl.close();
|
|
8569
|
-
|
|
8626
|
+
resolve4(answer);
|
|
8570
8627
|
});
|
|
8571
8628
|
});
|
|
8572
8629
|
}
|
|
8573
8630
|
function readStdin() {
|
|
8574
|
-
return new Promise((
|
|
8631
|
+
return new Promise((resolve4, reject) => {
|
|
8575
8632
|
let data = "";
|
|
8576
8633
|
process.stdin.setEncoding("utf-8");
|
|
8577
8634
|
process.stdin.on("data", (chunk) => {
|
|
8578
8635
|
data += chunk;
|
|
8579
8636
|
});
|
|
8580
|
-
process.stdin.on("end", () =>
|
|
8637
|
+
process.stdin.on("end", () => resolve4(data.trim()));
|
|
8581
8638
|
process.stdin.on("error", reject);
|
|
8582
8639
|
});
|
|
8583
8640
|
}
|
|
@@ -8738,9 +8795,9 @@ function getVersionCachePath(filename = CLI_CACHE_FILE) {
|
|
|
8738
8795
|
}
|
|
8739
8796
|
function readVersionCache(filename = CLI_CACHE_FILE) {
|
|
8740
8797
|
try {
|
|
8741
|
-
const
|
|
8742
|
-
if (!existsSync4(
|
|
8743
|
-
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"));
|
|
8744
8801
|
if (typeof parsed.lastCheck !== "number") return null;
|
|
8745
8802
|
if (parsed.latest !== null && typeof parsed.latest !== "string") return null;
|
|
8746
8803
|
return parsed;
|
|
@@ -8760,10 +8817,10 @@ function isVersionCacheStale(filename = CLI_CACHE_FILE, maxAgeMs = MAX_AGE_24H_M
|
|
|
8760
8817
|
return Date.now() - cache.lastCheck > maxAgeMs;
|
|
8761
8818
|
}
|
|
8762
8819
|
function writeVersionCache(filename, cache) {
|
|
8763
|
-
const
|
|
8764
|
-
const dir = dirname3(
|
|
8820
|
+
const path26 = getVersionCachePath(filename);
|
|
8821
|
+
const dir = dirname3(path26);
|
|
8765
8822
|
if (!existsSync4(dir)) mkdirSync(dir, { recursive: true });
|
|
8766
|
-
writeFileSync2(
|
|
8823
|
+
writeFileSync2(path26, JSON.stringify(cache));
|
|
8767
8824
|
}
|
|
8768
8825
|
function touchVersionCache(filename) {
|
|
8769
8826
|
writeVersionCache(filename, { lastCheck: Date.now(), latest: readVersionCache(filename)?.latest ?? null });
|
|
@@ -8802,14 +8859,14 @@ function parseFrontmatterVersion(content) {
|
|
|
8802
8859
|
function findInstalledSkills(projectRoot, paths = SKILL_INSTALL_PATHS) {
|
|
8803
8860
|
const found = [];
|
|
8804
8861
|
for (const rel of paths) {
|
|
8805
|
-
const
|
|
8806
|
-
if (!existsSync5(
|
|
8862
|
+
const path26 = join7(projectRoot, rel);
|
|
8863
|
+
if (!existsSync5(path26)) continue;
|
|
8807
8864
|
let version = null;
|
|
8808
8865
|
try {
|
|
8809
|
-
version = parseFrontmatterVersion(readFileSync6(
|
|
8866
|
+
version = parseFrontmatterVersion(readFileSync6(path26, "utf-8"));
|
|
8810
8867
|
} catch {
|
|
8811
8868
|
}
|
|
8812
|
-
found.push({ path:
|
|
8869
|
+
found.push({ path: path26, version });
|
|
8813
8870
|
}
|
|
8814
8871
|
return found;
|
|
8815
8872
|
}
|
|
@@ -9270,7 +9327,7 @@ async function validateToken(apiUrl, token) {
|
|
|
9270
9327
|
}
|
|
9271
9328
|
}
|
|
9272
9329
|
function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
9273
|
-
return new Promise((
|
|
9330
|
+
return new Promise((resolve4, reject) => {
|
|
9274
9331
|
const server = http.createServer((req, res) => {
|
|
9275
9332
|
const url = new URL(req.url || "/", `http://127.0.0.1:${port}`);
|
|
9276
9333
|
if (url.pathname === "/callback") {
|
|
@@ -9296,7 +9353,7 @@ function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
|
9296
9353
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
9297
9354
|
res.end("<html><body><h2>Login successful!</h2><p>You can close this tab and return to your terminal.</p></body></html>");
|
|
9298
9355
|
server.close();
|
|
9299
|
-
|
|
9356
|
+
resolve4({ code, port });
|
|
9300
9357
|
} else {
|
|
9301
9358
|
res.writeHead(400, { "Content-Type": "text/html" });
|
|
9302
9359
|
res.end("<html><body><h2>Login failed</h2><p>No authorization code received</p></body></html>");
|
|
@@ -9506,10 +9563,10 @@ import * as readline2 from "readline";
|
|
|
9506
9563
|
function prompt2(question, defaultValue) {
|
|
9507
9564
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
9508
9565
|
const display = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
|
|
9509
|
-
return new Promise((
|
|
9566
|
+
return new Promise((resolve4) => {
|
|
9510
9567
|
rl.question(display, (answer) => {
|
|
9511
9568
|
rl.close();
|
|
9512
|
-
|
|
9569
|
+
resolve4(answer.trim() || defaultValue || "");
|
|
9513
9570
|
});
|
|
9514
9571
|
});
|
|
9515
9572
|
}
|
|
@@ -9627,8 +9684,8 @@ async function tryOpenBrowser(url) {
|
|
|
9627
9684
|
cmd = "xdg-open";
|
|
9628
9685
|
args2 = [url];
|
|
9629
9686
|
}
|
|
9630
|
-
return new Promise((
|
|
9631
|
-
execFile(cmd, args2, (err) =>
|
|
9687
|
+
return new Promise((resolve4) => {
|
|
9688
|
+
execFile(cmd, args2, (err) => resolve4(!err));
|
|
9632
9689
|
});
|
|
9633
9690
|
} catch {
|
|
9634
9691
|
return false;
|
|
@@ -11266,9 +11323,11 @@ var init_pull = __esm({
|
|
|
11266
11323
|
var push_exports = {};
|
|
11267
11324
|
__export(push_exports, {
|
|
11268
11325
|
autoRenameAgentFiles: () => autoRenameAgentFiles,
|
|
11326
|
+
createAndPushNewHub: () => createAndPushNewHub,
|
|
11269
11327
|
printSyncResult: () => printSyncResult,
|
|
11270
11328
|
printWarnings: () => printWarnings,
|
|
11271
11329
|
pushCommand: () => pushCommand,
|
|
11330
|
+
reportUnresolvedPushTarget: () => reportUnresolvedPushTarget,
|
|
11272
11331
|
selectExistingHub: () => selectExistingHub,
|
|
11273
11332
|
shouldWarnIgnoredPreviewLabel: () => shouldWarnIgnoredPreviewLabel
|
|
11274
11333
|
});
|
|
@@ -11554,67 +11613,11 @@ function selectExistingHub(workspaceDir, allHubs, selector, wsLabel) {
|
|
|
11554
11613
|
if (previewHubs.length === 1) return previewHubs[0];
|
|
11555
11614
|
return null;
|
|
11556
11615
|
}
|
|
11557
|
-
function
|
|
11558
|
-
if (selector) {
|
|
11559
|
-
const match = newHubs.find((h) => path14.basename(h.hubFolder) === selector);
|
|
11560
|
-
if (!match) return null;
|
|
11561
|
-
return match;
|
|
11562
|
-
}
|
|
11563
|
-
const cwd = process.cwd();
|
|
11564
|
-
const cwdMatch = newHubs.find((h) => path14.resolve(h.hubFolder) === path14.resolve(cwd));
|
|
11565
|
-
if (cwdMatch) return cwdMatch;
|
|
11566
|
-
if (newHubs.length === 1) return newHubs[0];
|
|
11567
|
-
return null;
|
|
11568
|
-
}
|
|
11569
|
-
async function pushCommand(args2) {
|
|
11570
|
-
const { autoConfirm, hubSelector, label } = parseArgs5(args2);
|
|
11571
|
-
const repoConfig = requireRepoConfig();
|
|
11572
|
-
const { organization_id: organizationId } = repoConfig;
|
|
11573
|
-
const { config, accessToken } = await requireAuth();
|
|
11574
|
-
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
11575
|
-
const workspaceDir = resolveWorkspaceDir();
|
|
11576
|
-
const gitRoot = findGitRoot();
|
|
11577
|
-
const wsLabel = hubsDirLabel(gitRoot);
|
|
11578
|
-
if (gitRoot) warnLayoutOnce(gitRoot);
|
|
11579
|
-
if (!fs12.existsSync(workspaceDir)) {
|
|
11580
|
-
console.error(`No ${wsLabel}/ directory found. Run \`wayai pull\` first or create hub files in ${wsLabel}/<hub>/hub.yaml.`);
|
|
11581
|
-
process.exit(1);
|
|
11582
|
-
}
|
|
11583
|
-
const existingHubs = scanWorkspaceHubs(workspaceDir);
|
|
11584
|
-
const newHubs = scanNewHubs(workspaceDir);
|
|
11585
|
-
const existing = selectExistingHub(workspaceDir, existingHubs, hubSelector, wsLabel);
|
|
11586
|
-
if (existing) {
|
|
11587
|
-
if (existing.hubEnvironment === "production") {
|
|
11588
|
-
console.log("This is a read-only production mirror \u2014 production hubs cannot be pushed. Edit the linked preview hub instead.");
|
|
11589
|
-
return;
|
|
11590
|
-
}
|
|
11591
|
-
if (label) {
|
|
11592
|
-
console.warn("Note: --label is only used when creating a new hub. To change an existing hub's label, use `wayai relabel`.");
|
|
11593
|
-
}
|
|
11594
|
-
assertHubMatchesBinding(existing.hubId, path14.basename(existing.hubFolder));
|
|
11595
|
-
await pushSingleHub(client, existing.hubId, existing.hubFolder, autoConfirm, organizationId);
|
|
11596
|
-
return;
|
|
11597
|
-
}
|
|
11598
|
-
const newHub = selectNewHub(newHubs, hubSelector);
|
|
11599
|
-
if (!newHub) {
|
|
11600
|
-
if (existingHubs.length === 0 && newHubs.length === 0) {
|
|
11601
|
-
console.error(`No hub folders found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` and run \`wayai push\`.`);
|
|
11602
|
-
process.exit(1);
|
|
11603
|
-
}
|
|
11604
|
-
console.error(`Multiple hub folders found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
|
|
11605
|
-
for (const h of existingHubs) {
|
|
11606
|
-
console.error(` ${path14.basename(h.hubFolder)} (${h.hubId})`);
|
|
11607
|
-
}
|
|
11608
|
-
for (const h of newHubs) {
|
|
11609
|
-
console.error(` ${path14.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
|
|
11610
|
-
}
|
|
11611
|
-
process.exit(1);
|
|
11612
|
-
}
|
|
11613
|
-
assertNoBindingBlocksHubCreation(newHub.hubName);
|
|
11616
|
+
async function createAndPushNewHub(client, newHub, opts) {
|
|
11614
11617
|
const hubType = newHub.hubType || "chat";
|
|
11615
11618
|
console.log(`
|
|
11616
|
-
New hub
|
|
11617
|
-
if (!autoConfirm) {
|
|
11619
|
+
New hub: "${newHub.hubName}" (${hubType})`);
|
|
11620
|
+
if (!opts.autoConfirm) {
|
|
11618
11621
|
const ok = await confirm("Create this hub on the platform?");
|
|
11619
11622
|
if (!ok) {
|
|
11620
11623
|
console.log("Cancelled.");
|
|
@@ -11627,10 +11630,10 @@ New hub detected: "${newHub.hubName}" (${hubType})`);
|
|
|
11627
11630
|
process.exit(1);
|
|
11628
11631
|
}
|
|
11629
11632
|
console.log("Creating hub...");
|
|
11630
|
-
const createResult = await client.createHub(organizationId, {
|
|
11633
|
+
const createResult = await client.createHub(opts.organizationId, {
|
|
11631
11634
|
hubName: newHub.hubName,
|
|
11632
11635
|
hubType,
|
|
11633
|
-
previewLabel: label?.trim() || void 0
|
|
11636
|
+
previewLabel: opts.label?.trim() || void 0
|
|
11634
11637
|
});
|
|
11635
11638
|
const createdHub = createResult.data[0];
|
|
11636
11639
|
const hubId = createdHub.hub_id;
|
|
@@ -11657,7 +11660,69 @@ ${content}`;
|
|
|
11657
11660
|
}
|
|
11658
11661
|
fs12.writeFileSync(hubYamlPath, updated, "utf-8");
|
|
11659
11662
|
autoBindIfUnbound(hubId);
|
|
11660
|
-
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 });
|
|
11661
11726
|
}
|
|
11662
11727
|
var init_push = __esm({
|
|
11663
11728
|
"src/commands/push.ts"() {
|
|
@@ -11676,13 +11741,89 @@ var init_push = __esm({
|
|
|
11676
11741
|
}
|
|
11677
11742
|
});
|
|
11678
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
|
+
|
|
11679
11820
|
// src/commands/diff.ts
|
|
11680
11821
|
var diff_exports = {};
|
|
11681
11822
|
__export(diff_exports, {
|
|
11682
11823
|
diffCommand: () => diffCommand,
|
|
11683
|
-
parseArgs: () =>
|
|
11824
|
+
parseArgs: () => parseArgs7
|
|
11684
11825
|
});
|
|
11685
|
-
function
|
|
11826
|
+
function parseArgs7(args2) {
|
|
11686
11827
|
let production = false;
|
|
11687
11828
|
let hubSelector;
|
|
11688
11829
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -11696,7 +11837,7 @@ function parseArgs6(args2) {
|
|
|
11696
11837
|
return { production, hubSelector };
|
|
11697
11838
|
}
|
|
11698
11839
|
async function diffCommand(args2) {
|
|
11699
|
-
const { production, hubSelector } =
|
|
11840
|
+
const { production, hubSelector } = parseArgs7(args2);
|
|
11700
11841
|
const repoConfig = requireRepoConfig();
|
|
11701
11842
|
const { organization_id: organizationId } = repoConfig;
|
|
11702
11843
|
const { config, accessToken } = await requireAuth();
|
|
@@ -11826,12 +11967,12 @@ function typeMatches2(typeField, allowed) {
|
|
|
11826
11967
|
if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
|
|
11827
11968
|
return false;
|
|
11828
11969
|
}
|
|
11829
|
-
function validateSchema2(schema,
|
|
11970
|
+
function validateSchema2(schema, path26, errors, opts = {}) {
|
|
11830
11971
|
if (typeof schema === "boolean") return;
|
|
11831
11972
|
const depth = opts.depth ?? 0;
|
|
11832
11973
|
if (depth > MAX_SCHEMA_DEPTH2) {
|
|
11833
11974
|
errors.push({
|
|
11834
|
-
path:
|
|
11975
|
+
path: path26 || "<root>",
|
|
11835
11976
|
message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH2} levels`,
|
|
11836
11977
|
suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
|
|
11837
11978
|
});
|
|
@@ -11839,7 +11980,7 @@ function validateSchema2(schema, path25, errors, opts = {}) {
|
|
|
11839
11980
|
}
|
|
11840
11981
|
if (!isRecord2(schema)) {
|
|
11841
11982
|
errors.push({
|
|
11842
|
-
path:
|
|
11983
|
+
path: path26,
|
|
11843
11984
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
11844
11985
|
});
|
|
11845
11986
|
return;
|
|
@@ -11847,14 +11988,14 @@ function validateSchema2(schema, path25, errors, opts = {}) {
|
|
|
11847
11988
|
if (opts.isRoot) {
|
|
11848
11989
|
if ("type" in schema && schema.type !== "object") {
|
|
11849
11990
|
errors.push({
|
|
11850
|
-
path:
|
|
11991
|
+
path: path26 ? `${path26}.type` : "type",
|
|
11851
11992
|
message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
|
|
11852
11993
|
suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
|
|
11853
11994
|
});
|
|
11854
11995
|
}
|
|
11855
11996
|
} else if ("type" in schema && !typeMatches2(schema.type, ALLOWED_TYPES2)) {
|
|
11856
11997
|
errors.push({
|
|
11857
|
-
path: `${
|
|
11998
|
+
path: `${path26}.type`,
|
|
11858
11999
|
message: `type must be one of ${[...ALLOWED_TYPES2].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
|
|
11859
12000
|
});
|
|
11860
12001
|
}
|
|
@@ -11863,25 +12004,25 @@ function validateSchema2(schema, path25, errors, opts = {}) {
|
|
|
11863
12004
|
if (typeof e === "string") {
|
|
11864
12005
|
const isPlaceholder = PLACEHOLDER_TOKENS2.includes(e);
|
|
11865
12006
|
errors.push({
|
|
11866
|
-
path: `${
|
|
12007
|
+
path: `${path26}.enum`,
|
|
11867
12008
|
message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
|
|
11868
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"]`.'
|
|
11869
12010
|
});
|
|
11870
12011
|
} else if (!Array.isArray(e)) {
|
|
11871
12012
|
errors.push({
|
|
11872
|
-
path: `${
|
|
12013
|
+
path: `${path26}.enum`,
|
|
11873
12014
|
message: `enum must be a non-empty array of primitives, got ${typeof e}`
|
|
11874
12015
|
});
|
|
11875
12016
|
} else if (e.length === 0) {
|
|
11876
12017
|
errors.push({
|
|
11877
|
-
path: `${
|
|
12018
|
+
path: `${path26}.enum`,
|
|
11878
12019
|
message: "enum must not be empty"
|
|
11879
12020
|
});
|
|
11880
12021
|
} else {
|
|
11881
12022
|
for (let i = 0; i < e.length; i++) {
|
|
11882
12023
|
if (!isPrimitive2(e[i])) {
|
|
11883
12024
|
errors.push({
|
|
11884
|
-
path: `${
|
|
12025
|
+
path: `${path26}.enum[${i}]`,
|
|
11885
12026
|
message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
|
|
11886
12027
|
});
|
|
11887
12028
|
}
|
|
@@ -11891,7 +12032,7 @@ function validateSchema2(schema, path25, errors, opts = {}) {
|
|
|
11891
12032
|
for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
|
|
11892
12033
|
if (key in schema && typeof schema[key] === "boolean") {
|
|
11893
12034
|
errors.push({
|
|
11894
|
-
path: `${
|
|
12035
|
+
path: `${path26}.${key}`,
|
|
11895
12036
|
message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
|
|
11896
12037
|
suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
|
|
11897
12038
|
});
|
|
@@ -11900,45 +12041,45 @@ function validateSchema2(schema, path25, errors, opts = {}) {
|
|
|
11900
12041
|
if ("properties" in schema) {
|
|
11901
12042
|
if (!isRecord2(schema.properties)) {
|
|
11902
12043
|
errors.push({
|
|
11903
|
-
path: `${
|
|
12044
|
+
path: `${path26}.properties`,
|
|
11904
12045
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
11905
12046
|
});
|
|
11906
12047
|
} else {
|
|
11907
12048
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
11908
|
-
validateSchema2(propSchema, `${
|
|
12049
|
+
validateSchema2(propSchema, `${path26}.properties.${propName}`, errors, { depth: depth + 1 });
|
|
11909
12050
|
}
|
|
11910
12051
|
}
|
|
11911
12052
|
}
|
|
11912
12053
|
if (schemaTypeIncludes2(schema, "array") && "items" in schema) {
|
|
11913
12054
|
if (Array.isArray(schema.items)) {
|
|
11914
|
-
schema.items.forEach((sub, i) => validateSchema2(sub, `${
|
|
12055
|
+
schema.items.forEach((sub, i) => validateSchema2(sub, `${path26}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
11915
12056
|
} else {
|
|
11916
|
-
validateSchema2(schema.items, `${
|
|
12057
|
+
validateSchema2(schema.items, `${path26}.items`, errors, { depth: depth + 1 });
|
|
11917
12058
|
}
|
|
11918
12059
|
}
|
|
11919
12060
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS2) {
|
|
11920
12061
|
if (key in schema && isRecord2(schema[key])) {
|
|
11921
|
-
validateSchema2(schema[key], `${
|
|
12062
|
+
validateSchema2(schema[key], `${path26}.${key}`, errors, { depth: depth + 1 });
|
|
11922
12063
|
}
|
|
11923
12064
|
}
|
|
11924
12065
|
for (const key of SUBSCHEMA_LIST_KEYWORDS2) {
|
|
11925
12066
|
const list = schema[key];
|
|
11926
12067
|
if (Array.isArray(list)) {
|
|
11927
|
-
list.forEach((sub, i) => validateSchema2(sub, `${
|
|
12068
|
+
list.forEach((sub, i) => validateSchema2(sub, `${path26}.${key}[${i}]`, errors, { depth: depth + 1 }));
|
|
11928
12069
|
}
|
|
11929
12070
|
}
|
|
11930
12071
|
for (const key of SUBSCHEMA_MAP_KEYWORDS2) {
|
|
11931
12072
|
const map = schema[key];
|
|
11932
12073
|
if (isRecord2(map)) {
|
|
11933
12074
|
for (const [name, sub] of Object.entries(map)) {
|
|
11934
|
-
validateSchema2(sub, `${
|
|
12075
|
+
validateSchema2(sub, `${path26}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
11935
12076
|
}
|
|
11936
12077
|
}
|
|
11937
12078
|
}
|
|
11938
12079
|
const reportedPaths = new Set(errors.map((e) => e.path));
|
|
11939
12080
|
for (const [k, v] of Object.entries(schema)) {
|
|
11940
12081
|
if (typeof v !== "string") continue;
|
|
11941
|
-
const fieldPath = `${
|
|
12082
|
+
const fieldPath = `${path26}.${k}`;
|
|
11942
12083
|
if (reportedPaths.has(fieldPath)) continue;
|
|
11943
12084
|
for (const token of PLACEHOLDER_TOKENS2) {
|
|
11944
12085
|
if (v === token) {
|
|
@@ -12094,10 +12235,10 @@ function refineHubAsCodeLanes2(config, ctx) {
|
|
|
12094
12235
|
}
|
|
12095
12236
|
}
|
|
12096
12237
|
}
|
|
12097
|
-
function isSafeTemplatePath2(
|
|
12098
|
-
if (
|
|
12099
|
-
if (
|
|
12100
|
-
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("/");
|
|
12101
12242
|
return segments.every(
|
|
12102
12243
|
(seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
|
|
12103
12244
|
);
|
|
@@ -12125,9 +12266,9 @@ function isPlainObject(value) {
|
|
|
12125
12266
|
const proto = Object.getPrototypeOf(value);
|
|
12126
12267
|
return proto === Object.prototype || proto === null;
|
|
12127
12268
|
}
|
|
12128
|
-
function isSanitizableSliceFile(
|
|
12129
|
-
if (!/\.ya?ml$/i.test(
|
|
12130
|
-
return
|
|
12269
|
+
function isSanitizableSliceFile(path26) {
|
|
12270
|
+
if (!/\.ya?ml$/i.test(path26)) return false;
|
|
12271
|
+
return path26 !== "resources" && !path26.startsWith("resources/");
|
|
12131
12272
|
}
|
|
12132
12273
|
function distinctUsesBackends(uses) {
|
|
12133
12274
|
return [...new Set((uses ?? []).map((u) => u.backend))];
|
|
@@ -12569,7 +12710,12 @@ var init_contracts = __esm({
|
|
|
12569
12710
|
// A NATIVE LLM (Agent) connection id on this hub; validated at set-time on the REST
|
|
12570
12711
|
// PATCH (setup/hubs.ts rejects a non-existent / non-Agent / harness id) and re-checked
|
|
12571
12712
|
// at fallback time in the turn seam (a stale/missing id simply no-ops). Nullable to clear it.
|
|
12572
|
-
fallback_connection_id: uuidSchema2.nullable().optional()
|
|
12713
|
+
fallback_connection_id: uuidSchema2.nullable().optional(),
|
|
12714
|
+
// Rekor API connection used to reset/clear eval seed fixtures (gh #3090). A
|
|
12715
|
+
// connection id on this hub (a REST API (custom tool) connection whose base_url
|
|
12716
|
+
// is the Rekor API origin + a bearer/api_key `write:seeds` token). Validated at
|
|
12717
|
+
// set-time on the REST PATCH (setup/hubs.ts). Nullable to clear it.
|
|
12718
|
+
seed_connection_id: uuidSchema2.nullable().optional()
|
|
12573
12719
|
}).passthrough().superRefine(refineLaneReferences2);
|
|
12574
12720
|
addHubAdminBody2 = external_exports.object({
|
|
12575
12721
|
user_email: external_exports.string().email("valid email is required")
|
|
@@ -14110,7 +14256,6 @@ var init_contracts = __esm({
|
|
|
14110
14256
|
dataExplorerDebugAnalyticsTable2 = external_exports.enum([
|
|
14111
14257
|
"conversation",
|
|
14112
14258
|
"message",
|
|
14113
|
-
"billing_event",
|
|
14114
14259
|
"schedule_event"
|
|
14115
14260
|
]);
|
|
14116
14261
|
debugUuid2 = external_exports.string().uuid();
|
|
@@ -14292,7 +14437,7 @@ var init_contracts = __esm({
|
|
|
14292
14437
|
message: "at least one field must be provided"
|
|
14293
14438
|
});
|
|
14294
14439
|
contestReportBody2 = external_exports.object({
|
|
14295
|
-
reason: external_exports.string().min(1).max(
|
|
14440
|
+
reason: external_exports.string().min(1).max(5e3)
|
|
14296
14441
|
});
|
|
14297
14442
|
reporterListQuery2 = external_exports.object({
|
|
14298
14443
|
status: reportStatusSchema2.optional()
|
|
@@ -14324,7 +14469,7 @@ var init_contracts = __esm({
|
|
|
14324
14469
|
}),
|
|
14325
14470
|
external_exports.object({
|
|
14326
14471
|
target: external_exports.literal("dismissed"),
|
|
14327
|
-
dismissal_reason: external_exports.string().min(1).max(
|
|
14472
|
+
dismissal_reason: external_exports.string().min(1).max(5e3),
|
|
14328
14473
|
ai_verdict: external_exports.string().max(2e3).optional(),
|
|
14329
14474
|
final: external_exports.boolean().optional()
|
|
14330
14475
|
})
|
|
@@ -14333,7 +14478,7 @@ var init_contracts = __esm({
|
|
|
14333
14478
|
member_ids: external_exports.array(external_exports.string().uuid()).min(1).max(100)
|
|
14334
14479
|
});
|
|
14335
14480
|
holdReportBody2 = external_exports.object({
|
|
14336
|
-
reason: external_exports.string().min(1).max(
|
|
14481
|
+
reason: external_exports.string().min(1).max(5e3)
|
|
14337
14482
|
});
|
|
14338
14483
|
clickhouseReadyResponse2 = external_exports.object({
|
|
14339
14484
|
ready: external_exports.boolean()
|
|
@@ -14743,9 +14888,9 @@ var replicate_exports = {};
|
|
|
14743
14888
|
__export(replicate_exports, {
|
|
14744
14889
|
replicateCommand: () => replicateCommand
|
|
14745
14890
|
});
|
|
14746
|
-
import * as
|
|
14747
|
-
import * as
|
|
14748
|
-
function
|
|
14891
|
+
import * as fs14 from "fs";
|
|
14892
|
+
import * as path16 from "path";
|
|
14893
|
+
function parseArgs8(args2) {
|
|
14749
14894
|
let label;
|
|
14750
14895
|
let hubSelector;
|
|
14751
14896
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -14761,7 +14906,7 @@ function parseArgs7(args2) {
|
|
|
14761
14906
|
return { label, hubSelector };
|
|
14762
14907
|
}
|
|
14763
14908
|
async function replicateCommand(args2) {
|
|
14764
|
-
const { label, hubSelector } =
|
|
14909
|
+
const { label, hubSelector } = parseArgs8(args2);
|
|
14765
14910
|
const normalizedLabel = label?.trim() || void 0;
|
|
14766
14911
|
if (normalizedLabel && normalizedLabel.length > PREVIEW_LABEL_MAX_LENGTH2) {
|
|
14767
14912
|
console.error(`--label must be ${PREVIEW_LABEL_MAX_LENGTH2} characters or fewer.`);
|
|
@@ -14790,7 +14935,7 @@ async function replicateCommand(args2) {
|
|
|
14790
14935
|
payload.preview_label,
|
|
14791
14936
|
payload.branch_name
|
|
14792
14937
|
);
|
|
14793
|
-
|
|
14938
|
+
fs14.mkdirSync(path16.dirname(hubFolder), { recursive: true });
|
|
14794
14939
|
writeHubFolder(hubFolder, payload);
|
|
14795
14940
|
await downloadBinaryResourceFiles(hubFolder, payload);
|
|
14796
14941
|
hubFolder = autoRenameHubFolder(
|
|
@@ -14802,8 +14947,8 @@ async function replicateCommand(args2) {
|
|
|
14802
14947
|
payload.branch_name
|
|
14803
14948
|
);
|
|
14804
14949
|
autoBindIfUnbound(previewHubId);
|
|
14805
|
-
console.log(`Preview written to ${
|
|
14806
|
-
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)}`);
|
|
14807
14952
|
}
|
|
14808
14953
|
var init_replicate = __esm({
|
|
14809
14954
|
"src/commands/replicate.ts"() {
|
|
@@ -14825,8 +14970,8 @@ var relabel_exports = {};
|
|
|
14825
14970
|
__export(relabel_exports, {
|
|
14826
14971
|
relabelCommand: () => relabelCommand
|
|
14827
14972
|
});
|
|
14828
|
-
import * as
|
|
14829
|
-
function
|
|
14973
|
+
import * as path17 from "path";
|
|
14974
|
+
function parseArgs9(args2) {
|
|
14830
14975
|
let label;
|
|
14831
14976
|
let clear = false;
|
|
14832
14977
|
let hubSelector;
|
|
@@ -14843,7 +14988,7 @@ function parseArgs8(args2) {
|
|
|
14843
14988
|
return { label, clear, hubSelector };
|
|
14844
14989
|
}
|
|
14845
14990
|
async function relabelCommand(args2) {
|
|
14846
|
-
const { label, clear, hubSelector } =
|
|
14991
|
+
const { label, clear, hubSelector } = parseArgs9(args2);
|
|
14847
14992
|
if (!clear && (label === void 0 || label.trim() === "")) {
|
|
14848
14993
|
console.error("Usage: wayai relabel <label> [--hub <uuid|folder>] (or --clear to remove the label)");
|
|
14849
14994
|
process.exit(1);
|
|
@@ -14869,7 +15014,7 @@ async function relabelCommand(args2) {
|
|
|
14869
15014
|
} else {
|
|
14870
15015
|
console.error(`Multiple hubs found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
|
|
14871
15016
|
for (const h of previewHubs) {
|
|
14872
|
-
console.error(` ${
|
|
15017
|
+
console.error(` ${path17.basename(h.hubFolder)} (${h.hubId})`);
|
|
14873
15018
|
}
|
|
14874
15019
|
}
|
|
14875
15020
|
process.exit(1);
|
|
@@ -14878,7 +15023,7 @@ async function relabelCommand(args2) {
|
|
|
14878
15023
|
console.log("This is a read-only production mirror \u2014 production hubs have no preview label. Relabel the linked preview hub instead.");
|
|
14879
15024
|
return;
|
|
14880
15025
|
}
|
|
14881
|
-
assertHubMatchesBinding(target.hubId,
|
|
15026
|
+
assertHubMatchesBinding(target.hubId, path17.basename(target.hubFolder));
|
|
14882
15027
|
console.log(normalizedLabel ? `Setting preview label to "${normalizedLabel}"...` : "Clearing preview label...");
|
|
14883
15028
|
const { data } = await client.relabelPreview(target.hubId, normalizedLabel);
|
|
14884
15029
|
const row = data[0];
|
|
@@ -14894,7 +15039,7 @@ async function relabelCommand(args2) {
|
|
|
14894
15039
|
);
|
|
14895
15040
|
console.log(serverLabel ? `Preview label set to "${serverLabel}".` : "Preview label cleared.");
|
|
14896
15041
|
if (finalFolder !== target.hubFolder) {
|
|
14897
|
-
console.log(`Hub folder is now ${
|
|
15042
|
+
console.log(`Hub folder is now ${path17.basename(finalFolder)}`);
|
|
14898
15043
|
}
|
|
14899
15044
|
}
|
|
14900
15045
|
var init_relabel = __esm({
|
|
@@ -14915,13 +15060,13 @@ var init_relabel = __esm({
|
|
|
14915
15060
|
// src/commands/publish.ts
|
|
14916
15061
|
var publish_exports = {};
|
|
14917
15062
|
__export(publish_exports, {
|
|
14918
|
-
parseArgs: () =>
|
|
15063
|
+
parseArgs: () => parseArgs10,
|
|
14919
15064
|
publishCommand: () => publishCommand,
|
|
14920
15065
|
renderHubDiff: () => renderHubDiff,
|
|
14921
15066
|
runPublish: () => runPublish
|
|
14922
15067
|
});
|
|
14923
|
-
import * as
|
|
14924
|
-
function
|
|
15068
|
+
import * as path18 from "path";
|
|
15069
|
+
function parseArgs10(args2) {
|
|
14925
15070
|
let autoConfirm = false;
|
|
14926
15071
|
let hubSelector;
|
|
14927
15072
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -15007,7 +15152,7 @@ Published. Production hub: ${data.production_hub_id}`);
|
|
|
15007
15152
|
return "synced";
|
|
15008
15153
|
}
|
|
15009
15154
|
async function publishCommand(args2) {
|
|
15010
|
-
const { autoConfirm, hubSelector } =
|
|
15155
|
+
const { autoConfirm, hubSelector } = parseArgs10(args2);
|
|
15011
15156
|
const repoConfig = requireRepoConfig();
|
|
15012
15157
|
const { organization_id: organizationId } = repoConfig;
|
|
15013
15158
|
const { config, accessToken } = await requireAuth();
|
|
@@ -15026,7 +15171,7 @@ async function publishCommand(args2) {
|
|
|
15026
15171
|
return;
|
|
15027
15172
|
}
|
|
15028
15173
|
}
|
|
15029
|
-
assertHubMatchesBinding(hubId, hubFolder ?
|
|
15174
|
+
assertHubMatchesBinding(hubId, hubFolder ? path18.basename(hubFolder) : void 0);
|
|
15030
15175
|
await runPublish(client, { hubId, localConfig, organizationId, autoConfirm });
|
|
15031
15176
|
}
|
|
15032
15177
|
var STATUS_STYLE;
|
|
@@ -15058,7 +15203,7 @@ var use_exports = {};
|
|
|
15058
15203
|
__export(use_exports, {
|
|
15059
15204
|
useCommand: () => useCommand
|
|
15060
15205
|
});
|
|
15061
|
-
import * as
|
|
15206
|
+
import * as path19 from "path";
|
|
15062
15207
|
async function useCommand(args2) {
|
|
15063
15208
|
const target = args2[0];
|
|
15064
15209
|
if (!target || target.startsWith("-")) {
|
|
@@ -15079,9 +15224,22 @@ async function useCommand(args2) {
|
|
|
15079
15224
|
const wsLabel = hubsDirLabel(gitRoot);
|
|
15080
15225
|
const match = findHubByFolderName(workspaceDir, target);
|
|
15081
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
|
+
}
|
|
15082
15237
|
console.error(`No hub matching "${target}" found in ${wsLabel}/. Pass a UUID or a folder name from:`);
|
|
15083
15238
|
for (const h of scanWorkspaceHubs(workspaceDir)) {
|
|
15084
|
-
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)}\`)`);
|
|
15085
15243
|
}
|
|
15086
15244
|
process.exit(1);
|
|
15087
15245
|
}
|
|
@@ -15120,11 +15278,11 @@ __export(migrate_exports, {
|
|
|
15120
15278
|
migrateCommand: () => migrateCommand
|
|
15121
15279
|
});
|
|
15122
15280
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
15123
|
-
import * as
|
|
15124
|
-
import * as
|
|
15281
|
+
import * as fs15 from "fs";
|
|
15282
|
+
import * as path20 from "path";
|
|
15125
15283
|
function isTracked(gitRoot, p) {
|
|
15126
15284
|
try {
|
|
15127
|
-
execFileSync3("git", ["ls-files", "--error-unmatch", "--",
|
|
15285
|
+
execFileSync3("git", ["ls-files", "--error-unmatch", "--", path20.relative(gitRoot, p)], {
|
|
15128
15286
|
cwd: gitRoot,
|
|
15129
15287
|
stdio: ["pipe", "pipe", "pipe"]
|
|
15130
15288
|
});
|
|
@@ -15134,10 +15292,10 @@ function isTracked(gitRoot, p) {
|
|
|
15134
15292
|
}
|
|
15135
15293
|
}
|
|
15136
15294
|
function moveDir(gitRoot, from, to) {
|
|
15137
|
-
|
|
15295
|
+
fs15.mkdirSync(path20.dirname(to), { recursive: true });
|
|
15138
15296
|
if (isTracked(gitRoot, from)) {
|
|
15139
15297
|
try {
|
|
15140
|
-
execFileSync3("git", ["mv",
|
|
15298
|
+
execFileSync3("git", ["mv", path20.relative(gitRoot, from), path20.relative(gitRoot, to)], {
|
|
15141
15299
|
cwd: gitRoot,
|
|
15142
15300
|
stdio: ["pipe", "pipe", "pipe"]
|
|
15143
15301
|
});
|
|
@@ -15145,7 +15303,7 @@ function moveDir(gitRoot, from, to) {
|
|
|
15145
15303
|
} catch {
|
|
15146
15304
|
}
|
|
15147
15305
|
}
|
|
15148
|
-
|
|
15306
|
+
fs15.renameSync(from, to);
|
|
15149
15307
|
return "fs";
|
|
15150
15308
|
}
|
|
15151
15309
|
async function migrateCommand(_args) {
|
|
@@ -15154,12 +15312,12 @@ async function migrateCommand(_args) {
|
|
|
15154
15312
|
console.error("Not inside a git repository.");
|
|
15155
15313
|
process.exit(1);
|
|
15156
15314
|
}
|
|
15157
|
-
const rel = (p) =>
|
|
15158
|
-
const newWs =
|
|
15159
|
-
const legacyWs =
|
|
15160
|
-
const legacyOrg =
|
|
15161
|
-
const newHubs =
|
|
15162
|
-
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);
|
|
15163
15321
|
const hasLegacyWs = isDirectory(legacyWs);
|
|
15164
15322
|
const hasLegacyOrg = isDirectory(legacyOrg);
|
|
15165
15323
|
if (!hasLegacyWs && !hasLegacyOrg) {
|
|
@@ -15793,10 +15951,10 @@ var init_delete_history = __esm({
|
|
|
15793
15951
|
// src/commands/sync-skills.ts
|
|
15794
15952
|
var sync_skills_exports = {};
|
|
15795
15953
|
__export(sync_skills_exports, {
|
|
15796
|
-
parseArgs: () =>
|
|
15954
|
+
parseArgs: () => parseArgs11,
|
|
15797
15955
|
syncSkillsCommand: () => syncSkillsCommand
|
|
15798
15956
|
});
|
|
15799
|
-
function
|
|
15957
|
+
function parseArgs11(args2) {
|
|
15800
15958
|
let connectionId;
|
|
15801
15959
|
const idx = args2.indexOf("--connection-id");
|
|
15802
15960
|
if (idx !== -1 && args2[idx + 1]) {
|
|
@@ -15819,7 +15977,7 @@ function printSyncResults(response) {
|
|
|
15819
15977
|
}
|
|
15820
15978
|
async function syncSkillsCommand(args2) {
|
|
15821
15979
|
const hubId = resolveActiveHubId(args2);
|
|
15822
|
-
const { connectionId } =
|
|
15980
|
+
const { connectionId } = parseArgs11(args2);
|
|
15823
15981
|
requireRepoConfig();
|
|
15824
15982
|
const { config, accessToken } = await requireAuth();
|
|
15825
15983
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
@@ -15844,10 +16002,10 @@ var init_sync_skills = __esm({
|
|
|
15844
16002
|
// src/commands/sync-mcp.ts
|
|
15845
16003
|
var sync_mcp_exports = {};
|
|
15846
16004
|
__export(sync_mcp_exports, {
|
|
15847
|
-
parseArgs: () =>
|
|
16005
|
+
parseArgs: () => parseArgs12,
|
|
15848
16006
|
syncMcpCommand: () => syncMcpCommand
|
|
15849
16007
|
});
|
|
15850
|
-
function
|
|
16008
|
+
function parseArgs12(args2) {
|
|
15851
16009
|
let connection;
|
|
15852
16010
|
for (let i = 0; i < args2.length; i++) {
|
|
15853
16011
|
const arg = args2[i];
|
|
@@ -15859,7 +16017,7 @@ function parseArgs11(args2) {
|
|
|
15859
16017
|
}
|
|
15860
16018
|
async function syncMcpCommand(args2) {
|
|
15861
16019
|
const hubId = resolveActiveHubId(args2);
|
|
15862
|
-
const { connection } =
|
|
16020
|
+
const { connection } = parseArgs12(args2);
|
|
15863
16021
|
if (!connection) {
|
|
15864
16022
|
console.error("Usage: wayai sync-mcp --connection <name> [--hub <uuid|folder-name>]");
|
|
15865
16023
|
console.error("");
|
|
@@ -16271,7 +16429,7 @@ Timeout after ${timeoutSeconds}s. Session is still running.`);
|
|
|
16271
16429
|
console.log(`Check results: wayai eval-results --session ${sessionId}`);
|
|
16272
16430
|
}
|
|
16273
16431
|
function sleep(ms) {
|
|
16274
|
-
return new Promise((
|
|
16432
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
16275
16433
|
}
|
|
16276
16434
|
function parsePacing(raw) {
|
|
16277
16435
|
const NAMED = EVAL_PACING_PRESET_NAMES.filter((p) => p !== "custom");
|
|
@@ -16496,15 +16654,15 @@ var eval_capture_exports = {};
|
|
|
16496
16654
|
__export(eval_capture_exports, {
|
|
16497
16655
|
evalCaptureCommand: () => evalCaptureCommand
|
|
16498
16656
|
});
|
|
16499
|
-
import * as
|
|
16500
|
-
import * as
|
|
16657
|
+
import * as fs16 from "fs";
|
|
16658
|
+
import * as path21 from "path";
|
|
16501
16659
|
import * as yaml7 from "js-yaml";
|
|
16502
16660
|
function isValidSetName(name) {
|
|
16503
16661
|
if (name.length === 0 || name === "." || name === "..") return false;
|
|
16504
16662
|
if (name.startsWith(".")) return false;
|
|
16505
16663
|
return !/[\/\\\0]/.test(name);
|
|
16506
16664
|
}
|
|
16507
|
-
function
|
|
16665
|
+
function parseArgs13(args2) {
|
|
16508
16666
|
if (args2.length === 0 || args2[0].startsWith("-")) {
|
|
16509
16667
|
console.error("Usage: wayai eval capture <conversation_id> [--set <name>] [--name <eval_name>] [--instructions <text>]");
|
|
16510
16668
|
process.exit(1);
|
|
@@ -16550,7 +16708,7 @@ function parseArgs12(args2) {
|
|
|
16550
16708
|
}
|
|
16551
16709
|
async function evalCaptureCommand(args2) {
|
|
16552
16710
|
const hubId = resolveActiveHubId(args2);
|
|
16553
|
-
const parsed =
|
|
16711
|
+
const parsed = parseArgs13(args2);
|
|
16554
16712
|
const { config, accessToken } = await requireAuth();
|
|
16555
16713
|
requireRepoConfig();
|
|
16556
16714
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
@@ -16563,15 +16721,15 @@ async function evalCaptureCommand(args2) {
|
|
|
16563
16721
|
const setFolderName = targetSetName;
|
|
16564
16722
|
const scenarioName = parsed.evalName ?? `Capture ${parsed.conversationId.slice(0, 8)}`;
|
|
16565
16723
|
const slug = slugify(scenarioName);
|
|
16566
|
-
const evalsDir =
|
|
16567
|
-
const targetDir =
|
|
16568
|
-
const targetPath =
|
|
16569
|
-
if (!targetPath.startsWith(evalsDir +
|
|
16570
|
-
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.`);
|
|
16571
16729
|
process.exit(1);
|
|
16572
16730
|
}
|
|
16573
|
-
if (
|
|
16574
|
-
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.`);
|
|
16575
16733
|
process.exit(1);
|
|
16576
16734
|
}
|
|
16577
16735
|
console.log("Resolving scenario set...");
|
|
@@ -16603,9 +16761,9 @@ async function evalCaptureCommand(args2) {
|
|
|
16603
16761
|
...captured.evaluator_instructions ? { evaluator_instructions: captured.evaluator_instructions } : {}
|
|
16604
16762
|
};
|
|
16605
16763
|
const yamlObj = buildEvalYamlObject(evalEntry, slug);
|
|
16606
|
-
|
|
16607
|
-
|
|
16608
|
-
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);
|
|
16609
16767
|
console.log(`
|
|
16610
16768
|
Wrote ${relPath}`);
|
|
16611
16769
|
console.log("Run `wayai pull` to refresh the agent display name, then commit. The scenario is already on the platform.");
|
|
@@ -16627,7 +16785,7 @@ var journey_capture_exports = {};
|
|
|
16627
16785
|
__export(journey_capture_exports, {
|
|
16628
16786
|
journeyCaptureCommand: () => journeyCaptureCommand
|
|
16629
16787
|
});
|
|
16630
|
-
function
|
|
16788
|
+
function parseArgs14(args2) {
|
|
16631
16789
|
if (args2.length === 0 || args2[0].startsWith("-")) {
|
|
16632
16790
|
console.error("Usage: wayai eval journey capture <conversation_id> [--name <journey_name>] [--instructions <text>]");
|
|
16633
16791
|
process.exit(1);
|
|
@@ -16662,7 +16820,7 @@ function parseArgs13(args2) {
|
|
|
16662
16820
|
}
|
|
16663
16821
|
async function journeyCaptureCommand(args2) {
|
|
16664
16822
|
const hubId = resolveActiveHubId(args2);
|
|
16665
|
-
const parsed =
|
|
16823
|
+
const parsed = parseArgs14(args2);
|
|
16666
16824
|
const { config, accessToken } = await requireAuth();
|
|
16667
16825
|
requireRepoConfig();
|
|
16668
16826
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
@@ -17459,9 +17617,9 @@ var init_credential_utils = __esm({
|
|
|
17459
17617
|
var create_credential_exports = {};
|
|
17460
17618
|
__export(create_credential_exports, {
|
|
17461
17619
|
createCredentialCommand: () => createCredentialCommand,
|
|
17462
|
-
parseArgs: () =>
|
|
17620
|
+
parseArgs: () => parseArgs15
|
|
17463
17621
|
});
|
|
17464
|
-
function
|
|
17622
|
+
function parseArgs15(args2) {
|
|
17465
17623
|
let name;
|
|
17466
17624
|
let type;
|
|
17467
17625
|
let orgId;
|
|
@@ -17489,7 +17647,7 @@ function parseArgs14(args2) {
|
|
|
17489
17647
|
return { name, type, orgId, description, tags: splitTagRefs(tags), environment, stdin };
|
|
17490
17648
|
}
|
|
17491
17649
|
async function createCredentialCommand(args2) {
|
|
17492
|
-
const parsed =
|
|
17650
|
+
const parsed = parseArgs15(args2);
|
|
17493
17651
|
if (!parsed.name) {
|
|
17494
17652
|
console.error("Missing required flag: --name <credential-name>");
|
|
17495
17653
|
console.error('Usage: wayai create-credential --name "openai-key" --type "Bearer Token"');
|
|
@@ -17596,10 +17754,10 @@ var init_create_credential = __esm({
|
|
|
17596
17754
|
// src/commands/update-credential.ts
|
|
17597
17755
|
var update_credential_exports = {};
|
|
17598
17756
|
__export(update_credential_exports, {
|
|
17599
|
-
parseArgs: () =>
|
|
17757
|
+
parseArgs: () => parseArgs16,
|
|
17600
17758
|
updateCredentialCommand: () => updateCredentialCommand
|
|
17601
17759
|
});
|
|
17602
|
-
function
|
|
17760
|
+
function parseArgs16(args2) {
|
|
17603
17761
|
let name;
|
|
17604
17762
|
let rename;
|
|
17605
17763
|
let orgId;
|
|
@@ -17632,7 +17790,7 @@ function parseArgs15(args2) {
|
|
|
17632
17790
|
return { name, rename, orgId, description, tags: splitTagRefs(tags), hasTagFlag, environment, stdin, secretPrompt };
|
|
17633
17791
|
}
|
|
17634
17792
|
async function updateCredentialCommand(args2) {
|
|
17635
|
-
const parsed =
|
|
17793
|
+
const parsed = parseArgs16(args2);
|
|
17636
17794
|
if (!parsed.name) {
|
|
17637
17795
|
console.error("Missing required flag: --name <credential-name>");
|
|
17638
17796
|
console.error('Usage: wayai update-credential --name "my-key" --stdin');
|
|
@@ -17737,10 +17895,10 @@ var init_update_credential = __esm({
|
|
|
17737
17895
|
// src/commands/set-connection-credential.ts
|
|
17738
17896
|
var set_connection_credential_exports = {};
|
|
17739
17897
|
__export(set_connection_credential_exports, {
|
|
17740
|
-
parseArgs: () =>
|
|
17898
|
+
parseArgs: () => parseArgs17,
|
|
17741
17899
|
setConnectionCredentialCommand: () => setConnectionCredentialCommand
|
|
17742
17900
|
});
|
|
17743
|
-
function
|
|
17901
|
+
function parseArgs17(args2) {
|
|
17744
17902
|
let connection;
|
|
17745
17903
|
let orgCredential;
|
|
17746
17904
|
let field;
|
|
@@ -17763,7 +17921,7 @@ function usage(msg) {
|
|
|
17763
17921
|
}
|
|
17764
17922
|
async function setConnectionCredentialCommand(args2) {
|
|
17765
17923
|
const hubId = resolveActiveHubId(args2);
|
|
17766
|
-
const parsed =
|
|
17924
|
+
const parsed = parseArgs17(args2);
|
|
17767
17925
|
if (!parsed.connection) usage("Missing required flag: --connection <name|id>");
|
|
17768
17926
|
const orgMode = !!parsed.orgCredential;
|
|
17769
17927
|
const directMode = !!parsed.field;
|
|
@@ -17832,23 +17990,23 @@ var init_set_connection_credential = __esm({
|
|
|
17832
17990
|
});
|
|
17833
17991
|
|
|
17834
17992
|
// src/lib/org-workspace.ts
|
|
17835
|
-
import * as
|
|
17836
|
-
import * as
|
|
17993
|
+
import * as fs17 from "fs";
|
|
17994
|
+
import * as path22 from "path";
|
|
17837
17995
|
import * as yaml8 from "js-yaml";
|
|
17838
17996
|
function getOrgDir(gitRoot) {
|
|
17839
17997
|
return resolveLayout(gitRoot).orgDir;
|
|
17840
17998
|
}
|
|
17841
17999
|
function orgManifestExists(orgDir) {
|
|
17842
|
-
return
|
|
18000
|
+
return fs17.existsSync(path22.join(orgDir, ORG_MANIFEST_NAME));
|
|
17843
18001
|
}
|
|
17844
18002
|
function parseOrgResources(orgDir) {
|
|
17845
|
-
const manifestPath =
|
|
18003
|
+
const manifestPath = path22.join(orgDir, ORG_MANIFEST_NAME);
|
|
17846
18004
|
let manifest = {};
|
|
17847
|
-
if (
|
|
17848
|
-
manifest = yaml8.load(
|
|
18005
|
+
if (fs17.existsSync(manifestPath)) {
|
|
18006
|
+
manifest = yaml8.load(fs17.readFileSync(manifestPath, "utf-8")) ?? {};
|
|
17849
18007
|
}
|
|
17850
18008
|
const rawResources = Array.isArray(manifest.resources) ? manifest.resources : [];
|
|
17851
|
-
const resourcesDir =
|
|
18009
|
+
const resourcesDir = path22.join(orgDir, "resources");
|
|
17852
18010
|
const resources = rawResources.map((res) => {
|
|
17853
18011
|
const resource = { name: res.name };
|
|
17854
18012
|
if (res.id) resource.id = res.id;
|
|
@@ -17860,8 +18018,8 @@ function parseOrgResources(orgDir) {
|
|
|
17860
18018
|
if (res.environment) resource.environment = res.environment;
|
|
17861
18019
|
if (Array.isArray(res.tags)) resource.tags = res.tags;
|
|
17862
18020
|
if (Array.isArray(res.folders)) resource.folders = res.folders;
|
|
17863
|
-
const resDir =
|
|
17864
|
-
if (
|
|
18021
|
+
const resDir = path22.join(resourcesDir, slugify(resource.name));
|
|
18022
|
+
if (fs17.existsSync(resDir)) {
|
|
17865
18023
|
const files = scanResourceFiles(resDir, "");
|
|
17866
18024
|
if (files.length > 0) resource.files = files;
|
|
17867
18025
|
}
|
|
@@ -17870,28 +18028,28 @@ function parseOrgResources(orgDir) {
|
|
|
17870
18028
|
return { version: 1, resources };
|
|
17871
18029
|
}
|
|
17872
18030
|
function writeOrgResources(orgDir, payload) {
|
|
17873
|
-
|
|
18031
|
+
fs17.mkdirSync(orgDir, { recursive: true });
|
|
17874
18032
|
const resources = payload.resources ?? [];
|
|
17875
18033
|
const manifestResources = resources.map((r) => {
|
|
17876
18034
|
const { files: _files, ...rest } = r;
|
|
17877
18035
|
return rest;
|
|
17878
18036
|
});
|
|
17879
|
-
|
|
17880
|
-
|
|
18037
|
+
fs17.writeFileSync(
|
|
18038
|
+
path22.join(orgDir, ORG_MANIFEST_NAME),
|
|
17881
18039
|
yaml8.dump({ version: 1, resources: manifestResources }, YAML_DUMP_OPTIONS),
|
|
17882
18040
|
"utf-8"
|
|
17883
18041
|
);
|
|
17884
|
-
const resourcesDir =
|
|
18042
|
+
const resourcesDir = path22.join(orgDir, "resources");
|
|
17885
18043
|
const currentSlugs = /* @__PURE__ */ new Set();
|
|
17886
18044
|
for (const resource of resources) {
|
|
17887
18045
|
const resSlug = slugify(resource.name);
|
|
17888
18046
|
currentSlugs.add(resSlug);
|
|
17889
|
-
writeResourceFileTree(
|
|
18047
|
+
writeResourceFileTree(path22.join(resourcesDir, resSlug), resource.files || []);
|
|
17890
18048
|
}
|
|
17891
|
-
if (
|
|
17892
|
-
for (const entry of
|
|
18049
|
+
if (fs17.existsSync(resourcesDir)) {
|
|
18050
|
+
for (const entry of fs17.readdirSync(resourcesDir, { withFileTypes: true })) {
|
|
17893
18051
|
if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
|
|
17894
|
-
|
|
18052
|
+
fs17.rmSync(path22.join(resourcesDir, entry.name), { recursive: true, force: true });
|
|
17895
18053
|
}
|
|
17896
18054
|
}
|
|
17897
18055
|
}
|
|
@@ -17900,7 +18058,7 @@ async function downloadOrgBinaryFiles(orgDir, payload) {
|
|
|
17900
18058
|
let count = 0;
|
|
17901
18059
|
for (const resource of payload.resources ?? []) {
|
|
17902
18060
|
if (!resource.files) continue;
|
|
17903
|
-
const resDir =
|
|
18061
|
+
const resDir = path22.join(orgDir, "resources", slugify(resource.name));
|
|
17904
18062
|
count += await downloadBinaryFiles(resDir, resource.files);
|
|
17905
18063
|
}
|
|
17906
18064
|
if (count > 0) console.log(`Downloaded ${count} binary resource file(s).`);
|
|
@@ -18088,9 +18246,9 @@ var init_org = __esm({
|
|
|
18088
18246
|
var list_exports = {};
|
|
18089
18247
|
__export(list_exports, {
|
|
18090
18248
|
listCommand: () => listCommand,
|
|
18091
|
-
parseArgs: () =>
|
|
18249
|
+
parseArgs: () => parseArgs18
|
|
18092
18250
|
});
|
|
18093
|
-
function
|
|
18251
|
+
function parseArgs18(args2) {
|
|
18094
18252
|
let orgId;
|
|
18095
18253
|
let json = false;
|
|
18096
18254
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -18103,7 +18261,7 @@ function parseArgs17(args2) {
|
|
|
18103
18261
|
return { orgId, json };
|
|
18104
18262
|
}
|
|
18105
18263
|
async function listCommand(args2) {
|
|
18106
|
-
const { orgId, json } =
|
|
18264
|
+
const { orgId, json } = parseArgs18(args2);
|
|
18107
18265
|
const { config, accessToken } = await requireAuth();
|
|
18108
18266
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
18109
18267
|
const { organizations } = await client.organizations();
|
|
@@ -18156,20 +18314,20 @@ var init_list = __esm({
|
|
|
18156
18314
|
});
|
|
18157
18315
|
|
|
18158
18316
|
// src/lib/template-files.ts
|
|
18159
|
-
import * as
|
|
18160
|
-
import * as
|
|
18317
|
+
import * as fs18 from "fs";
|
|
18318
|
+
import * as path23 from "path";
|
|
18161
18319
|
function readDirToFileMap(rootDir) {
|
|
18162
18320
|
const out = {};
|
|
18163
18321
|
function walk(dir, prefix) {
|
|
18164
|
-
const entries =
|
|
18322
|
+
const entries = fs18.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
18165
18323
|
for (const entry of entries) {
|
|
18166
|
-
const abs =
|
|
18324
|
+
const abs = path23.join(dir, entry.name);
|
|
18167
18325
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
18168
18326
|
if (entry.isDirectory()) walk(abs, rel);
|
|
18169
|
-
else if (entry.isFile()) out[rel] =
|
|
18327
|
+
else if (entry.isFile()) out[rel] = fs18.readFileSync(abs, "utf-8");
|
|
18170
18328
|
}
|
|
18171
18329
|
}
|
|
18172
|
-
if (
|
|
18330
|
+
if (fs18.existsSync(rootDir)) walk(rootDir, "");
|
|
18173
18331
|
return out;
|
|
18174
18332
|
}
|
|
18175
18333
|
function detectCollisions(targetDir, files) {
|
|
@@ -18178,7 +18336,7 @@ function detectCollisions(targetDir, files) {
|
|
|
18178
18336
|
if (!isSafeTemplatePath2(rel)) {
|
|
18179
18337
|
throw new Error(`Refusing to inspect unsafe template path: ${rel}`);
|
|
18180
18338
|
}
|
|
18181
|
-
if (
|
|
18339
|
+
if (fs18.existsSync(path23.join(targetDir, rel))) collisions.push(rel);
|
|
18182
18340
|
}
|
|
18183
18341
|
return collisions.sort((a, b) => a.localeCompare(b));
|
|
18184
18342
|
}
|
|
@@ -18188,9 +18346,9 @@ function writeFileMap(targetDir, files) {
|
|
|
18188
18346
|
if (!isSafeTemplatePath2(rel)) {
|
|
18189
18347
|
throw new Error(`Refusing to write unsafe template path: ${rel}`);
|
|
18190
18348
|
}
|
|
18191
|
-
const abs =
|
|
18192
|
-
|
|
18193
|
-
|
|
18349
|
+
const abs = path23.join(targetDir, rel);
|
|
18350
|
+
fs18.mkdirSync(path23.dirname(abs), { recursive: true });
|
|
18351
|
+
fs18.writeFileSync(abs, body, "utf-8");
|
|
18194
18352
|
written.push(rel);
|
|
18195
18353
|
}
|
|
18196
18354
|
return written;
|
|
@@ -18198,20 +18356,20 @@ function writeFileMap(targetDir, files) {
|
|
|
18198
18356
|
function listDirRelFiles(dir) {
|
|
18199
18357
|
const out = [];
|
|
18200
18358
|
function walk(d, prefix) {
|
|
18201
|
-
for (const entry of
|
|
18359
|
+
for (const entry of fs18.readdirSync(d, { withFileTypes: true })) {
|
|
18202
18360
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
18203
|
-
if (entry.isDirectory()) walk(
|
|
18361
|
+
if (entry.isDirectory()) walk(path23.join(d, entry.name), rel);
|
|
18204
18362
|
else if (entry.isFile()) out.push(rel);
|
|
18205
18363
|
}
|
|
18206
18364
|
}
|
|
18207
|
-
if (
|
|
18365
|
+
if (fs18.existsSync(dir)) walk(dir, "");
|
|
18208
18366
|
return out;
|
|
18209
18367
|
}
|
|
18210
18368
|
function writeSliceSnapshot(targetDir, files) {
|
|
18211
18369
|
const keep = new Set(Object.keys(files));
|
|
18212
18370
|
const removed = listDirRelFiles(targetDir).filter((rel) => !keep.has(rel)).sort((a, b) => a.localeCompare(b));
|
|
18213
18371
|
const written = writeFileMap(targetDir, files).sort((a, b) => a.localeCompare(b));
|
|
18214
|
-
if (
|
|
18372
|
+
if (fs18.existsSync(targetDir)) cleanOrphanFiles(targetDir, "", keep);
|
|
18215
18373
|
return { written, removed };
|
|
18216
18374
|
}
|
|
18217
18375
|
var init_template_files = __esm({
|
|
@@ -18227,7 +18385,7 @@ var templates_exports = {};
|
|
|
18227
18385
|
__export(templates_exports, {
|
|
18228
18386
|
templateCommand: () => templateCommand
|
|
18229
18387
|
});
|
|
18230
|
-
import * as
|
|
18388
|
+
import * as path24 from "path";
|
|
18231
18389
|
async function templateCommand(args2) {
|
|
18232
18390
|
const [sub, ...rest] = args2;
|
|
18233
18391
|
switch (sub) {
|
|
@@ -18343,8 +18501,8 @@ async function runTemplatePull(rest) {
|
|
|
18343
18501
|
console.log(`Template "${slug}" has no WayAI slice${hint}`);
|
|
18344
18502
|
return;
|
|
18345
18503
|
}
|
|
18346
|
-
const targetDir =
|
|
18347
|
-
const relTarget =
|
|
18504
|
+
const targetDir = path24.join(resolveLayout(gitRoot).hubsDir, slug);
|
|
18505
|
+
const relTarget = path24.relative(gitRoot, targetDir);
|
|
18348
18506
|
const collisions = detectCollisions(targetDir, detail.files);
|
|
18349
18507
|
if (dryRun) {
|
|
18350
18508
|
const planned = Object.keys(detail.files).sort((a, b) => a.localeCompare(b));
|
|
@@ -18518,8 +18676,8 @@ var admin_exports = {};
|
|
|
18518
18676
|
__export(admin_exports, {
|
|
18519
18677
|
adminCommand: () => adminCommand
|
|
18520
18678
|
});
|
|
18521
|
-
import * as
|
|
18522
|
-
import * as
|
|
18679
|
+
import * as fs19 from "fs";
|
|
18680
|
+
import * as path25 from "path";
|
|
18523
18681
|
import * as yaml10 from "js-yaml";
|
|
18524
18682
|
async function adminCommand(args2) {
|
|
18525
18683
|
const [group, ...afterGroup] = args2;
|
|
@@ -18827,7 +18985,7 @@ async function runArchiveRead(positional, flagArgs) {
|
|
|
18827
18985
|
exitOnApiError(err);
|
|
18828
18986
|
throw err;
|
|
18829
18987
|
}
|
|
18830
|
-
|
|
18988
|
+
fs19.writeFileSync(outPath, zip);
|
|
18831
18989
|
console.log(`Wrote ${zip.byteLength} bytes to ${outPath}`);
|
|
18832
18990
|
return;
|
|
18833
18991
|
}
|
|
@@ -18959,15 +19117,15 @@ function loadTemplateManifest(slug) {
|
|
|
18959
19117
|
console.error("Not in a git repository. Run from the tutorials/ authoring repo.");
|
|
18960
19118
|
process.exit(1);
|
|
18961
19119
|
}
|
|
18962
|
-
const templateDir =
|
|
18963
|
-
const manifestPath =
|
|
18964
|
-
if (!
|
|
18965
|
-
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)}`);
|
|
18966
19124
|
process.exit(1);
|
|
18967
19125
|
}
|
|
18968
19126
|
let manifest;
|
|
18969
19127
|
try {
|
|
18970
|
-
manifest = templateYamlSchema2.parse(yaml10.load(
|
|
19128
|
+
manifest = templateYamlSchema2.parse(yaml10.load(fs19.readFileSync(manifestPath, "utf-8")));
|
|
18971
19129
|
} catch (err) {
|
|
18972
19130
|
console.error(`Invalid template.yaml: ${err instanceof Error ? err.message : String(err)}`);
|
|
18973
19131
|
process.exit(1);
|
|
@@ -18997,20 +19155,20 @@ async function runTemplatePush(positional) {
|
|
|
18997
19155
|
const wayaiEntry = manifest.wayai.locales[locale];
|
|
18998
19156
|
let wayaiFiles;
|
|
18999
19157
|
if (wayaiEntry) {
|
|
19000
|
-
const sliceDir =
|
|
19001
|
-
if (!
|
|
19158
|
+
const sliceDir = path25.resolve(templateDir, wayaiEntry.source);
|
|
19159
|
+
if (!fs19.existsSync(sliceDir)) {
|
|
19002
19160
|
console.error(`wayai source not found for ${locale}: ${wayaiEntry.source} (resolved ${sliceDir})`);
|
|
19003
19161
|
process.exit(1);
|
|
19004
19162
|
}
|
|
19005
19163
|
if (!isInsideTemplateDir(sliceDir, templateDir)) {
|
|
19006
19164
|
console.warn(
|
|
19007
|
-
`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.`
|
|
19008
19166
|
);
|
|
19009
19167
|
}
|
|
19010
19168
|
wayaiFiles = readDirToFileMap(sliceDir);
|
|
19011
19169
|
}
|
|
19012
|
-
const readmePath =
|
|
19013
|
-
const readmeMarkdown =
|
|
19170
|
+
const readmePath = path25.join(templateDir, `README.${locale}.md`);
|
|
19171
|
+
const readmeMarkdown = fs19.existsSync(readmePath) ? fs19.readFileSync(readmePath, "utf-8") : "";
|
|
19014
19172
|
locales[locale] = {
|
|
19015
19173
|
readmeMarkdown,
|
|
19016
19174
|
...wayaiFiles && { wayaiFiles },
|
|
@@ -19021,9 +19179,9 @@ async function runTemplatePush(positional) {
|
|
|
19021
19179
|
}
|
|
19022
19180
|
let hero;
|
|
19023
19181
|
if (manifest.hero) {
|
|
19024
|
-
const heroPath =
|
|
19025
|
-
if (
|
|
19026
|
-
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") };
|
|
19027
19185
|
} else {
|
|
19028
19186
|
console.error(`Warning: hero not found at ${manifest.hero}; skipping.`);
|
|
19029
19187
|
}
|
|
@@ -19049,7 +19207,7 @@ async function runTemplatePush(positional) {
|
|
|
19049
19207
|
}
|
|
19050
19208
|
}
|
|
19051
19209
|
function isInsideTemplateDir(dest, templateDir) {
|
|
19052
|
-
return dest === templateDir || dest.startsWith(templateDir +
|
|
19210
|
+
return dest === templateDir || dest.startsWith(templateDir + path25.sep);
|
|
19053
19211
|
}
|
|
19054
19212
|
async function runTemplateFreeze(positional, flagArgs) {
|
|
19055
19213
|
const slug = positional[0];
|
|
@@ -19110,7 +19268,7 @@ async function runTemplateFreeze(positional, flagArgs) {
|
|
|
19110
19268
|
process.exit(1);
|
|
19111
19269
|
}
|
|
19112
19270
|
const entry = manifest.wayai.locales[targetLocale];
|
|
19113
|
-
const dest =
|
|
19271
|
+
const dest = path25.resolve(templateDir, entry.source);
|
|
19114
19272
|
if (!isInsideTemplateDir(dest, templateDir) || dest === templateDir) {
|
|
19115
19273
|
console.error(
|
|
19116
19274
|
`source for "${targetLocale}" must be a committed path inside ${slug}/ (e.g. "./${targetLocale}/slice"), but resolved to:
|
|
@@ -19129,7 +19287,7 @@ Set it to a subdir of the template folder and re-run freeze.`
|
|
|
19129
19287
|
const hubs = scanWorkspaceHubs(hubsDir);
|
|
19130
19288
|
if (hubs.length) {
|
|
19131
19289
|
console.error("Available hubs:");
|
|
19132
|
-
for (const h of hubs) console.error(` ${
|
|
19290
|
+
for (const h of hubs) console.error(` ${path25.basename(h.hubFolder)} (${h.hubId})`);
|
|
19133
19291
|
}
|
|
19134
19292
|
console.error(`
|
|
19135
19293
|
Pass --from <folder|uuid>${selector ? "." : " or run `wayai use <hub>` first."}`);
|
|
@@ -19137,12 +19295,12 @@ Pass --from <folder|uuid>${selector ? "." : " or run `wayai use <hub>` first."}`
|
|
|
19137
19295
|
}
|
|
19138
19296
|
const liveFiles = readDirToFileMap(hubFolder);
|
|
19139
19297
|
if (Object.keys(liveFiles).length === 0) {
|
|
19140
|
-
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)}`);
|
|
19141
19299
|
process.exit(1);
|
|
19142
19300
|
}
|
|
19143
19301
|
const sanitized = sanitizeWayaiSliceFiles(liveFiles);
|
|
19144
|
-
const relDest =
|
|
19145
|
-
const relSrc =
|
|
19302
|
+
const relDest = path25.relative(gitRoot, dest);
|
|
19303
|
+
const relSrc = path25.relative(gitRoot, hubFolder);
|
|
19146
19304
|
if (dryRun) {
|
|
19147
19305
|
const existing = new Set(listDirRelFiles(dest));
|
|
19148
19306
|
const nextKeys = new Set(Object.keys(sanitized));
|
|
@@ -19202,7 +19360,7 @@ async function runTemplatePull2(positional, flagArgs) {
|
|
|
19202
19360
|
console.log(JSON.stringify(detail, null, 2));
|
|
19203
19361
|
return;
|
|
19204
19362
|
}
|
|
19205
|
-
const target = outDir ?
|
|
19363
|
+
const target = outDir ? path25.resolve(outDir) : path25.join(process.cwd(), "template-store-pull", slug);
|
|
19206
19364
|
const written = writeFileMap(target, detail.files);
|
|
19207
19365
|
console.log(`Pulled "${slug}" from the store \u2192 ${target} (${written.length} file${written.length === 1 ? "" : "s"}).`);
|
|
19208
19366
|
const uses = detail.uses ?? [];
|
|
@@ -19225,13 +19383,13 @@ async function runSkillInstall(positional) {
|
|
|
19225
19383
|
throw err;
|
|
19226
19384
|
}
|
|
19227
19385
|
const root = findGitRoot() ?? process.cwd();
|
|
19228
|
-
const present = HARNESS_SKILL_DIRS.filter((dir) =>
|
|
19386
|
+
const present = HARNESS_SKILL_DIRS.filter((dir) => fs19.existsSync(path25.join(root, dir)));
|
|
19229
19387
|
const targets = present.length > 0 ? present : HARNESS_SKILL_DIRS;
|
|
19230
19388
|
const fileCount = Object.keys(res.files).length;
|
|
19231
19389
|
const relDirs = targets.map((harness) => {
|
|
19232
|
-
const targetDir =
|
|
19390
|
+
const targetDir = path25.join(root, harness, "skills", name);
|
|
19233
19391
|
writeFileMap(targetDir, res.files);
|
|
19234
|
-
return `${
|
|
19392
|
+
return `${path25.relative(root, targetDir)}/`;
|
|
19235
19393
|
});
|
|
19236
19394
|
console.log(`Installed skill "${name}" (${fileCount} file${fileCount === 1 ? "" : "s"}) \u2192 ${relDirs.join(", ")}`);
|
|
19237
19395
|
console.log("Reload your agent (e.g. restart Claude Code) to pick up the skill.");
|
|
@@ -19971,7 +20129,7 @@ Usage:
|
|
|
19971
20129
|
|
|
19972
20130
|
Sources:
|
|
19973
20131
|
do Live DO SQLite (existing conversation, hub config, etc.).
|
|
19974
|
-
analytics ClickHouse projections (conversation, message,
|
|
20132
|
+
analytics ClickHouse projections (conversation, message, schedule_event).
|
|
19975
20133
|
archive R2 archive blob \u2014 canonical content for ended conversations after DO cleanup.
|
|
19976
20134
|
observability R2 LLM observability \u2014 per-message OTel GenAI records (prompts, completions,
|
|
19977
20135
|
tool calls, tokens, latency). Default lists all records for the conversation;
|
|
@@ -20486,7 +20644,7 @@ init_skill_version();
|
|
|
20486
20644
|
import { exec } from "child_process";
|
|
20487
20645
|
var REFRESH_TIMEOUT_MS = 1e4;
|
|
20488
20646
|
function refreshCliCache() {
|
|
20489
|
-
return new Promise((
|
|
20647
|
+
return new Promise((resolve4) => {
|
|
20490
20648
|
exec("npm view @wayai/cli version", { timeout: REFRESH_TIMEOUT_MS }, (err, stdout) => {
|
|
20491
20649
|
if (!err) {
|
|
20492
20650
|
const latest = stdout.trim();
|
|
@@ -20497,7 +20655,7 @@ function refreshCliCache() {
|
|
|
20497
20655
|
}
|
|
20498
20656
|
}
|
|
20499
20657
|
}
|
|
20500
|
-
|
|
20658
|
+
resolve4();
|
|
20501
20659
|
});
|
|
20502
20660
|
});
|
|
20503
20661
|
}
|
|
@@ -20523,8 +20681,8 @@ async function refreshSkillCache() {
|
|
|
20523
20681
|
}
|
|
20524
20682
|
async function refreshAdminSkillCache() {
|
|
20525
20683
|
let timer;
|
|
20526
|
-
const deadline = new Promise((
|
|
20527
|
-
timer = setTimeout(
|
|
20684
|
+
const deadline = new Promise((resolve4) => {
|
|
20685
|
+
timer = setTimeout(resolve4, REFRESH_TIMEOUT_MS);
|
|
20528
20686
|
});
|
|
20529
20687
|
await Promise.race([deadline, fetchAndCacheAdminSkillVersion().catch(() => {
|
|
20530
20688
|
})]);
|
|
@@ -20688,6 +20846,11 @@ async function main() {
|
|
|
20688
20846
|
await pushCommand2(args);
|
|
20689
20847
|
break;
|
|
20690
20848
|
}
|
|
20849
|
+
case "create": {
|
|
20850
|
+
const { createCommand: createCommand2 } = await Promise.resolve().then(() => (init_create(), create_exports));
|
|
20851
|
+
await createCommand2(args);
|
|
20852
|
+
break;
|
|
20853
|
+
}
|
|
20691
20854
|
case "diff": {
|
|
20692
20855
|
const { diffCommand: diffCommand2 } = await Promise.resolve().then(() => (init_diff(), diff_exports));
|
|
20693
20856
|
await diffCommand2(args);
|
|
@@ -20858,6 +21021,7 @@ Commands:
|
|
|
20858
21021
|
set-connection-credential Set a connection's credential directly (org link or --field/--stdin), preview or production
|
|
20859
21022
|
pull Fetch hub config and write local files (also mirrors the linked production hub read-only)
|
|
20860
21023
|
push Parse local files, show diff, sync to preview (creates hub if new)
|
|
21024
|
+
create [folder] Explicitly create a new hub from an idless folder, then push (--label to name the preview)
|
|
20861
21025
|
diff Dry-run diff of local files vs the platform (--production diffs vs the linked production hub)
|
|
20862
21026
|
replicate Clone a hub into a new sibling preview (--label to name it)
|
|
20863
21027
|
relabel Set a preview hub's label (--clear to remove it)
|
|
@@ -20890,7 +21054,7 @@ Flags:
|
|
|
20890
21054
|
--yes, -y Skip confirmation prompts (useful for CI and scripting)
|
|
20891
21055
|
--hub <uuid|name> Target hub when the workspace has more than one (push, pull, diff, replicate, relabel, publish)
|
|
20892
21056
|
--production Diff local preview files against the linked production hub (diff)
|
|
20893
|
-
--label <name> Preview label \u2014 for the new sibling (replicate) or a brand-new hub (push on create)
|
|
21057
|
+
--label <name> Preview label \u2014 for the new sibling (replicate) or a brand-new hub (create, or push on create)
|
|
20894
21058
|
--clear Remove the preview label (relabel)
|
|
20895
21059
|
--name <name> Credential name (create-credential; target for update-credential)
|
|
20896
21060
|
--type <auth-type> Auth type: "api_key", "bearer", "basic_auth" (create-credential)
|