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