@wayai/cli 0.3.137 → 0.3.138
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 +1746 -784
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -447,11 +447,11 @@ function captureException2(error, context) {
|
|
|
447
447
|
Sentry.captureException(error);
|
|
448
448
|
});
|
|
449
449
|
}
|
|
450
|
-
function addApiBreadcrumb(method,
|
|
450
|
+
function addApiBreadcrumb(method, path36) {
|
|
451
451
|
if (!initialized) return;
|
|
452
452
|
Sentry.addBreadcrumb({
|
|
453
453
|
category: "http",
|
|
454
|
-
message: `${method} ${
|
|
454
|
+
message: `${method} ${path36}`,
|
|
455
455
|
level: "info"
|
|
456
456
|
});
|
|
457
457
|
}
|
|
@@ -905,8 +905,8 @@ var init_parseUtil = __esm({
|
|
|
905
905
|
init_errors();
|
|
906
906
|
init_en();
|
|
907
907
|
makeIssue = (params) => {
|
|
908
|
-
const { data, path:
|
|
909
|
-
const fullPath = [...
|
|
908
|
+
const { data, path: path36, errorMaps, issueData } = params;
|
|
909
|
+
const fullPath = [...path36, ...issueData.path || []];
|
|
910
910
|
const fullIssue = {
|
|
911
911
|
...issueData,
|
|
912
912
|
path: fullPath
|
|
@@ -1217,11 +1217,11 @@ var init_types = __esm({
|
|
|
1217
1217
|
init_parseUtil();
|
|
1218
1218
|
init_util();
|
|
1219
1219
|
ParseInputLazyPath = class {
|
|
1220
|
-
constructor(parent, value,
|
|
1220
|
+
constructor(parent, value, path36, key) {
|
|
1221
1221
|
this._cachedPath = [];
|
|
1222
1222
|
this.parent = parent;
|
|
1223
1223
|
this.data = value;
|
|
1224
|
-
this._path =
|
|
1224
|
+
this._path = path36;
|
|
1225
1225
|
this._key = key;
|
|
1226
1226
|
}
|
|
1227
1227
|
get path() {
|
|
@@ -4634,12 +4634,12 @@ function validateFollowupLinks(followups, label, ctx) {
|
|
|
4634
4634
|
const linkTargets = /* @__PURE__ */ new Set();
|
|
4635
4635
|
followups.forEach((followup, i) => {
|
|
4636
4636
|
const ref = followup?.after_followup_id;
|
|
4637
|
-
const
|
|
4637
|
+
const path36 = ["followups", i, "after_followup_id"];
|
|
4638
4638
|
if (followup?.type !== "inactivity_after_before_event") {
|
|
4639
4639
|
if (ref !== void 0) {
|
|
4640
4640
|
ctx.addIssue({
|
|
4641
4641
|
code: external_exports.ZodIssueCode.custom,
|
|
4642
|
-
path:
|
|
4642
|
+
path: path36,
|
|
4643
4643
|
message: `kanban status ${label}: after_followup_id is only valid on inactivity_after_before_event followups (this one is ${followup?.type})`
|
|
4644
4644
|
});
|
|
4645
4645
|
}
|
|
@@ -4648,7 +4648,7 @@ function validateFollowupLinks(followups, label, ctx) {
|
|
|
4648
4648
|
if (ref === void 0) {
|
|
4649
4649
|
ctx.addIssue({
|
|
4650
4650
|
code: external_exports.ZodIssueCode.custom,
|
|
4651
|
-
path:
|
|
4651
|
+
path: path36,
|
|
4652
4652
|
message: `kanban status ${label}: inactivity_after_before_event requires after_followup_id naming the id of a before_event followup in the same status`
|
|
4653
4653
|
});
|
|
4654
4654
|
return;
|
|
@@ -4658,7 +4658,7 @@ function validateFollowupLinks(followups, label, ctx) {
|
|
|
4658
4658
|
if (matches.length > 1) {
|
|
4659
4659
|
ctx.addIssue({
|
|
4660
4660
|
code: external_exports.ZodIssueCode.custom,
|
|
4661
|
-
path:
|
|
4661
|
+
path: path36,
|
|
4662
4662
|
message: `kanban status ${label}: after_followup_id "${ref}" matches ${matches.length} followups \u2014 a link must name exactly one`
|
|
4663
4663
|
});
|
|
4664
4664
|
return;
|
|
@@ -4670,7 +4670,7 @@ function validateFollowupLinks(followups, label, ctx) {
|
|
|
4670
4670
|
);
|
|
4671
4671
|
ctx.addIssue({
|
|
4672
4672
|
code: external_exports.ZodIssueCode.custom,
|
|
4673
|
-
path:
|
|
4673
|
+
path: path36,
|
|
4674
4674
|
message: hasIdlessBeforeEvent ? `kanban status ${label}: after_followup_id "${ref}" matches no followup \u2014 a link target must declare an explicit id, and this status has before_event followups without one` : `kanban status ${label}: after_followup_id "${ref}" matches no followup in this status`
|
|
4675
4675
|
});
|
|
4676
4676
|
return;
|
|
@@ -4678,7 +4678,7 @@ function validateFollowupLinks(followups, label, ctx) {
|
|
|
4678
4678
|
if (target.type !== "before_event") {
|
|
4679
4679
|
ctx.addIssue({
|
|
4680
4680
|
code: external_exports.ZodIssueCode.custom,
|
|
4681
|
-
path:
|
|
4681
|
+
path: path36,
|
|
4682
4682
|
message: `kanban status ${label}: after_followup_id "${ref}" points at a ${target.type} followup \u2014 only before_event followups can anchor a chain`
|
|
4683
4683
|
});
|
|
4684
4684
|
}
|
|
@@ -4754,12 +4754,12 @@ function typeMatches(typeField, allowed) {
|
|
|
4754
4754
|
if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
|
|
4755
4755
|
return false;
|
|
4756
4756
|
}
|
|
4757
|
-
function validateSchema(schema,
|
|
4757
|
+
function validateSchema(schema, path36, errors, opts = {}) {
|
|
4758
4758
|
if (typeof schema === "boolean") return;
|
|
4759
4759
|
const depth = opts.depth ?? 0;
|
|
4760
4760
|
if (depth > MAX_SCHEMA_DEPTH) {
|
|
4761
4761
|
errors.push({
|
|
4762
|
-
path:
|
|
4762
|
+
path: path36 || "<root>",
|
|
4763
4763
|
message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH} levels`,
|
|
4764
4764
|
suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
|
|
4765
4765
|
});
|
|
@@ -4767,7 +4767,7 @@ function validateSchema(schema, path31, errors, opts = {}) {
|
|
|
4767
4767
|
}
|
|
4768
4768
|
if (!isRecord(schema)) {
|
|
4769
4769
|
errors.push({
|
|
4770
|
-
path:
|
|
4770
|
+
path: path36,
|
|
4771
4771
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
4772
4772
|
});
|
|
4773
4773
|
return;
|
|
@@ -4775,14 +4775,14 @@ function validateSchema(schema, path31, errors, opts = {}) {
|
|
|
4775
4775
|
if (opts.isRoot) {
|
|
4776
4776
|
if ("type" in schema && schema.type !== "object") {
|
|
4777
4777
|
errors.push({
|
|
4778
|
-
path:
|
|
4778
|
+
path: path36 ? `${path36}.type` : "type",
|
|
4779
4779
|
message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
|
|
4780
4780
|
suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
|
|
4781
4781
|
});
|
|
4782
4782
|
}
|
|
4783
4783
|
} else if ("type" in schema && !typeMatches(schema.type, ALLOWED_TYPES)) {
|
|
4784
4784
|
errors.push({
|
|
4785
|
-
path: `${
|
|
4785
|
+
path: `${path36}.type`,
|
|
4786
4786
|
message: `type must be one of ${[...ALLOWED_TYPES].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
|
|
4787
4787
|
});
|
|
4788
4788
|
}
|
|
@@ -4792,25 +4792,25 @@ function validateSchema(schema, path31, errors, opts = {}) {
|
|
|
4792
4792
|
const isPlaceholder = PLACEHOLDER_TOKENS.includes(e);
|
|
4793
4793
|
const isOutcomePlaceholder = e === "[KANBAN_OUTCOME_VALUES]";
|
|
4794
4794
|
errors.push({
|
|
4795
|
-
path: `${
|
|
4795
|
+
path: `${path36}.enum`,
|
|
4796
4796
|
message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
|
|
4797
4797
|
suggestion: isOutcomePlaceholder ? "Declare `outcomes` on the hub's terminal kanban status so the platform can render the placeholder into a valid array; with none configured the platform drops the parameter instead." : 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"]`.'
|
|
4798
4798
|
});
|
|
4799
4799
|
} else if (!Array.isArray(e)) {
|
|
4800
4800
|
errors.push({
|
|
4801
|
-
path: `${
|
|
4801
|
+
path: `${path36}.enum`,
|
|
4802
4802
|
message: `enum must be a non-empty array of primitives, got ${typeof e}`
|
|
4803
4803
|
});
|
|
4804
4804
|
} else if (e.length === 0) {
|
|
4805
4805
|
errors.push({
|
|
4806
|
-
path: `${
|
|
4806
|
+
path: `${path36}.enum`,
|
|
4807
4807
|
message: "enum must not be empty"
|
|
4808
4808
|
});
|
|
4809
4809
|
} else {
|
|
4810
4810
|
for (let i = 0; i < e.length; i++) {
|
|
4811
4811
|
if (!isPrimitive(e[i])) {
|
|
4812
4812
|
errors.push({
|
|
4813
|
-
path: `${
|
|
4813
|
+
path: `${path36}.enum[${i}]`,
|
|
4814
4814
|
message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
|
|
4815
4815
|
});
|
|
4816
4816
|
}
|
|
@@ -4820,7 +4820,7 @@ function validateSchema(schema, path31, errors, opts = {}) {
|
|
|
4820
4820
|
for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
|
|
4821
4821
|
if (key in schema && typeof schema[key] === "boolean") {
|
|
4822
4822
|
errors.push({
|
|
4823
|
-
path: `${
|
|
4823
|
+
path: `${path36}.${key}`,
|
|
4824
4824
|
message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
|
|
4825
4825
|
suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
|
|
4826
4826
|
});
|
|
@@ -4829,45 +4829,45 @@ function validateSchema(schema, path31, errors, opts = {}) {
|
|
|
4829
4829
|
if ("properties" in schema) {
|
|
4830
4830
|
if (!isRecord(schema.properties)) {
|
|
4831
4831
|
errors.push({
|
|
4832
|
-
path: `${
|
|
4832
|
+
path: `${path36}.properties`,
|
|
4833
4833
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
4834
4834
|
});
|
|
4835
4835
|
} else {
|
|
4836
4836
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
4837
|
-
validateSchema(propSchema, `${
|
|
4837
|
+
validateSchema(propSchema, `${path36}.properties.${propName}`, errors, { depth: depth + 1 });
|
|
4838
4838
|
}
|
|
4839
4839
|
}
|
|
4840
4840
|
}
|
|
4841
4841
|
if (schemaTypeIncludes(schema, "array") && "items" in schema) {
|
|
4842
4842
|
if (Array.isArray(schema.items)) {
|
|
4843
|
-
schema.items.forEach((sub, i) => validateSchema(sub, `${
|
|
4843
|
+
schema.items.forEach((sub, i) => validateSchema(sub, `${path36}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
4844
4844
|
} else {
|
|
4845
|
-
validateSchema(schema.items, `${
|
|
4845
|
+
validateSchema(schema.items, `${path36}.items`, errors, { depth: depth + 1 });
|
|
4846
4846
|
}
|
|
4847
4847
|
}
|
|
4848
4848
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS) {
|
|
4849
4849
|
if (key in schema && isRecord(schema[key])) {
|
|
4850
|
-
validateSchema(schema[key], `${
|
|
4850
|
+
validateSchema(schema[key], `${path36}.${key}`, errors, { depth: depth + 1 });
|
|
4851
4851
|
}
|
|
4852
4852
|
}
|
|
4853
4853
|
for (const key of SUBSCHEMA_LIST_KEYWORDS) {
|
|
4854
4854
|
const list = schema[key];
|
|
4855
4855
|
if (Array.isArray(list)) {
|
|
4856
|
-
list.forEach((sub, i) => validateSchema(sub, `${
|
|
4856
|
+
list.forEach((sub, i) => validateSchema(sub, `${path36}.${key}[${i}]`, errors, { depth: depth + 1 }));
|
|
4857
4857
|
}
|
|
4858
4858
|
}
|
|
4859
4859
|
for (const key of SUBSCHEMA_MAP_KEYWORDS) {
|
|
4860
4860
|
const map = schema[key];
|
|
4861
4861
|
if (isRecord(map)) {
|
|
4862
4862
|
for (const [name, sub] of Object.entries(map)) {
|
|
4863
|
-
validateSchema(sub, `${
|
|
4863
|
+
validateSchema(sub, `${path36}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
4864
4864
|
}
|
|
4865
4865
|
}
|
|
4866
4866
|
}
|
|
4867
4867
|
const reportedPaths = new Set(errors.map((e) => e.path));
|
|
4868
4868
|
for (const [k, v] of Object.entries(schema)) {
|
|
4869
4869
|
if (typeof v !== "string") continue;
|
|
4870
|
-
const fieldPath = `${
|
|
4870
|
+
const fieldPath = `${path36}.${k}`;
|
|
4871
4871
|
if (reportedPaths.has(fieldPath)) continue;
|
|
4872
4872
|
for (const token of PLACEHOLDER_TOKENS) {
|
|
4873
4873
|
if (v === token) {
|
|
@@ -5012,8 +5012,8 @@ function evalInitialStateError(input) {
|
|
|
5012
5012
|
const parsed = evalInitialStateEntry.safeParse(entries[i]);
|
|
5013
5013
|
if (!parsed.success) {
|
|
5014
5014
|
const issue = parsed.error.issues[0];
|
|
5015
|
-
const
|
|
5016
|
-
return `initial_state[${i}].${
|
|
5015
|
+
const path36 = issue?.path.join(".") || "?";
|
|
5016
|
+
return `initial_state[${i}].${path36} is invalid: ${issue?.message ?? "malformed"}`;
|
|
5017
5017
|
}
|
|
5018
5018
|
if (seenSlugs.has(parsed.data.slug)) {
|
|
5019
5019
|
return `initial_state[${i}].slug "${parsed.data.slug}" is declared more than once`;
|
|
@@ -5201,10 +5201,10 @@ function refineHubAsCodeEvals(config, ctx) {
|
|
|
5201
5201
|
function refineHubAsCodeEvalAttachments(config, ctx) {
|
|
5202
5202
|
const cfg = config;
|
|
5203
5203
|
const referencedHashes = /* @__PURE__ */ new Set();
|
|
5204
|
-
const addTurnIssue = (
|
|
5204
|
+
const addTurnIssue = (path36, turn, name) => {
|
|
5205
5205
|
const error = evalTurnAttachmentsError(turn);
|
|
5206
5206
|
if (error) {
|
|
5207
|
-
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path:
|
|
5207
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path36, message: `${name}: ${error}` });
|
|
5208
5208
|
return;
|
|
5209
5209
|
}
|
|
5210
5210
|
for (const hash of collectTurnAttachmentHashes(turn)) referencedHashes.add(hash);
|
|
@@ -5350,11 +5350,11 @@ function refineHubAsCodeDelegation(config, ctx) {
|
|
|
5350
5350
|
}
|
|
5351
5351
|
}
|
|
5352
5352
|
if (del.context_boundary === void 0) return;
|
|
5353
|
-
const
|
|
5353
|
+
const path36 = ["agents", agentIndex, "tools", "delegation", delIndex, "context_boundary"];
|
|
5354
5354
|
if (del.type !== "hub") {
|
|
5355
5355
|
ctx.addIssue({
|
|
5356
5356
|
code: external_exports.ZodIssueCode.custom,
|
|
5357
|
-
path:
|
|
5357
|
+
path: path36,
|
|
5358
5358
|
message: `context_boundary applies only to \`type: hub\` delegations (got type "${String(del.type)}")`
|
|
5359
5359
|
});
|
|
5360
5360
|
return;
|
|
@@ -5362,7 +5362,7 @@ function refineHubAsCodeDelegation(config, ctx) {
|
|
|
5362
5362
|
if (!CONTEXT_BOUNDARIES.includes(del.context_boundary)) {
|
|
5363
5363
|
ctx.addIssue({
|
|
5364
5364
|
code: external_exports.ZodIssueCode.custom,
|
|
5365
|
-
path:
|
|
5365
|
+
path: path36,
|
|
5366
5366
|
message: `context_boundary must be one of: ${CONTEXT_BOUNDARIES.join(", ")}`
|
|
5367
5367
|
});
|
|
5368
5368
|
}
|
|
@@ -8737,10 +8737,10 @@ function toDataProxyPath(v1Path) {
|
|
|
8737
8737
|
}
|
|
8738
8738
|
return `${DATA_PROXY_PREFIX}${v1Path.slice(REKOR_V1_PREFIX.length)}`;
|
|
8739
8739
|
}
|
|
8740
|
-
function withOrgSelector(
|
|
8741
|
-
if (!orgId) return
|
|
8742
|
-
const separator =
|
|
8743
|
-
return `${
|
|
8740
|
+
function withOrgSelector(path36, orgId) {
|
|
8741
|
+
if (!orgId) return path36;
|
|
8742
|
+
const separator = path36.includes("?") ? "&" : "?";
|
|
8743
|
+
return `${path36}${separator}${DATA_PROXY_ORG_QUERY_PARAM}=${encodeURIComponent(orgId)}`;
|
|
8744
8744
|
}
|
|
8745
8745
|
function dataErrorMessage(err) {
|
|
8746
8746
|
if (!(err instanceof ApiError)) return null;
|
|
@@ -8764,7 +8764,7 @@ var init_api_client = __esm({
|
|
|
8764
8764
|
init_sentry();
|
|
8765
8765
|
init_mask_secrets();
|
|
8766
8766
|
RETRYABLE_BACKOFF_MS = [500, 1e3, 2e3];
|
|
8767
|
-
delay = (ms) => new Promise((
|
|
8767
|
+
delay = (ms) => new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
8768
8768
|
ApiError = class extends Error {
|
|
8769
8769
|
status;
|
|
8770
8770
|
body;
|
|
@@ -8774,13 +8774,13 @@ var init_api_client = __esm({
|
|
|
8774
8774
|
* telling them apart by body shape misreads one for the other.
|
|
8775
8775
|
*/
|
|
8776
8776
|
path;
|
|
8777
|
-
constructor(method,
|
|
8777
|
+
constructor(method, path36, status, body) {
|
|
8778
8778
|
const safeBody = maskSecretsInMessage(body);
|
|
8779
|
-
super(`API request failed: ${method} ${
|
|
8779
|
+
super(`API request failed: ${method} ${path36} (${status}): ${safeBody}`);
|
|
8780
8780
|
this.name = "ApiError";
|
|
8781
8781
|
this.status = status;
|
|
8782
8782
|
this.body = safeBody;
|
|
8783
|
-
this.path =
|
|
8783
|
+
this.path = path36;
|
|
8784
8784
|
}
|
|
8785
8785
|
/** True when the status code is a 4xx client error (expected user-facing condition, not a bug). */
|
|
8786
8786
|
get isExpected() {
|
|
@@ -8876,8 +8876,8 @@ var init_api_client = __esm({
|
|
|
8876
8876
|
...opts?.check && { check: true }
|
|
8877
8877
|
});
|
|
8878
8878
|
}
|
|
8879
|
-
async lookup(
|
|
8880
|
-
const params = new URLSearchParams({ path:
|
|
8879
|
+
async lookup(path36, opts) {
|
|
8880
|
+
const params = new URLSearchParams({ path: path36 });
|
|
8881
8881
|
if (opts?.organizationId) params.set("organization_id", opts.organizationId);
|
|
8882
8882
|
return this.request("GET", `/api/ci/lookup?${params.toString()}`);
|
|
8883
8883
|
}
|
|
@@ -9298,9 +9298,9 @@ var init_api_client = __esm({
|
|
|
9298
9298
|
* sandbox for this conversation, or the blob was purged).
|
|
9299
9299
|
*/
|
|
9300
9300
|
async downloadArchiveSandboxFs(hubId, conversationId) {
|
|
9301
|
-
const
|
|
9302
|
-
addApiBreadcrumb("GET",
|
|
9303
|
-
const url = `${this.apiUrl}${
|
|
9301
|
+
const path36 = `/api/archive/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}/sandbox`;
|
|
9302
|
+
addApiBreadcrumb("GET", path36);
|
|
9303
|
+
const url = `${this.apiUrl}${path36}`;
|
|
9304
9304
|
let response = await this.send(url, "GET");
|
|
9305
9305
|
if (response.status === 401 && this.onUnauthorized) {
|
|
9306
9306
|
let refreshed;
|
|
@@ -9314,7 +9314,7 @@ var init_api_client = __esm({
|
|
|
9314
9314
|
}
|
|
9315
9315
|
}
|
|
9316
9316
|
if (!response.ok) {
|
|
9317
|
-
throw new ApiError("GET",
|
|
9317
|
+
throw new ApiError("GET", path36, response.status, await response.text());
|
|
9318
9318
|
}
|
|
9319
9319
|
return new Uint8Array(await response.arrayBuffer());
|
|
9320
9320
|
}
|
|
@@ -9354,9 +9354,9 @@ var init_api_client = __esm({
|
|
|
9354
9354
|
`/api/admin/data-explorer/debug/observability/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}${qs}`
|
|
9355
9355
|
);
|
|
9356
9356
|
}
|
|
9357
|
-
async request(method,
|
|
9358
|
-
addApiBreadcrumb(method,
|
|
9359
|
-
const url = `${this.apiUrl}${
|
|
9357
|
+
async request(method, path36, body, extraHeaders, contentType) {
|
|
9358
|
+
addApiBreadcrumb(method, path36);
|
|
9359
|
+
const url = `${this.apiUrl}${path36}`;
|
|
9360
9360
|
let refreshedOn401 = false;
|
|
9361
9361
|
for (let retry = 0; ; retry++) {
|
|
9362
9362
|
let response = await this.send(url, method, body, extraHeaders, contentType);
|
|
@@ -9381,7 +9381,7 @@ var init_api_client = __esm({
|
|
|
9381
9381
|
await delay(RETRYABLE_BACKOFF_MS[retry]);
|
|
9382
9382
|
continue;
|
|
9383
9383
|
}
|
|
9384
|
-
throw new ApiError(method,
|
|
9384
|
+
throw new ApiError(method, path36, response.status, errorBody);
|
|
9385
9385
|
}
|
|
9386
9386
|
}
|
|
9387
9387
|
/**
|
|
@@ -9443,9 +9443,9 @@ var init_api_client = __esm({
|
|
|
9443
9443
|
* transient-retry loop — re-streaming a blob is not worth a cold-start probe.
|
|
9444
9444
|
*/
|
|
9445
9445
|
async dataDownload(v1Path, orgId) {
|
|
9446
|
-
const
|
|
9447
|
-
addApiBreadcrumb("GET",
|
|
9448
|
-
const url = `${this.apiUrl}${
|
|
9446
|
+
const path36 = withOrgSelector(toDataProxyPath(v1Path), orgId);
|
|
9447
|
+
addApiBreadcrumb("GET", path36);
|
|
9448
|
+
const url = `${this.apiUrl}${path36}`;
|
|
9449
9449
|
let response = await this.send(url, "GET");
|
|
9450
9450
|
if (response.status === 401 && this.onUnauthorized) {
|
|
9451
9451
|
let refreshed;
|
|
@@ -9459,7 +9459,7 @@ var init_api_client = __esm({
|
|
|
9459
9459
|
}
|
|
9460
9460
|
}
|
|
9461
9461
|
if (!response.ok) {
|
|
9462
|
-
throw new ApiError("GET",
|
|
9462
|
+
throw new ApiError("GET", path36, response.status, await response.text());
|
|
9463
9463
|
}
|
|
9464
9464
|
return {
|
|
9465
9465
|
bytes: new Uint8Array(await response.arrayBuffer()),
|
|
@@ -9611,12 +9611,12 @@ function validateFollowupLinks2(followups, label, ctx) {
|
|
|
9611
9611
|
const linkTargets = /* @__PURE__ */ new Set();
|
|
9612
9612
|
followups.forEach((followup, i) => {
|
|
9613
9613
|
const ref = followup?.after_followup_id;
|
|
9614
|
-
const
|
|
9614
|
+
const path36 = ["followups", i, "after_followup_id"];
|
|
9615
9615
|
if (followup?.type !== "inactivity_after_before_event") {
|
|
9616
9616
|
if (ref !== void 0) {
|
|
9617
9617
|
ctx.addIssue({
|
|
9618
9618
|
code: external_exports.ZodIssueCode.custom,
|
|
9619
|
-
path:
|
|
9619
|
+
path: path36,
|
|
9620
9620
|
message: `kanban status ${label}: after_followup_id is only valid on inactivity_after_before_event followups (this one is ${followup?.type})`
|
|
9621
9621
|
});
|
|
9622
9622
|
}
|
|
@@ -9625,7 +9625,7 @@ function validateFollowupLinks2(followups, label, ctx) {
|
|
|
9625
9625
|
if (ref === void 0) {
|
|
9626
9626
|
ctx.addIssue({
|
|
9627
9627
|
code: external_exports.ZodIssueCode.custom,
|
|
9628
|
-
path:
|
|
9628
|
+
path: path36,
|
|
9629
9629
|
message: `kanban status ${label}: inactivity_after_before_event requires after_followup_id naming the id of a before_event followup in the same status`
|
|
9630
9630
|
});
|
|
9631
9631
|
return;
|
|
@@ -9635,7 +9635,7 @@ function validateFollowupLinks2(followups, label, ctx) {
|
|
|
9635
9635
|
if (matches.length > 1) {
|
|
9636
9636
|
ctx.addIssue({
|
|
9637
9637
|
code: external_exports.ZodIssueCode.custom,
|
|
9638
|
-
path:
|
|
9638
|
+
path: path36,
|
|
9639
9639
|
message: `kanban status ${label}: after_followup_id "${ref}" matches ${matches.length} followups \u2014 a link must name exactly one`
|
|
9640
9640
|
});
|
|
9641
9641
|
return;
|
|
@@ -9647,7 +9647,7 @@ function validateFollowupLinks2(followups, label, ctx) {
|
|
|
9647
9647
|
);
|
|
9648
9648
|
ctx.addIssue({
|
|
9649
9649
|
code: external_exports.ZodIssueCode.custom,
|
|
9650
|
-
path:
|
|
9650
|
+
path: path36,
|
|
9651
9651
|
message: hasIdlessBeforeEvent ? `kanban status ${label}: after_followup_id "${ref}" matches no followup \u2014 a link target must declare an explicit id, and this status has before_event followups without one` : `kanban status ${label}: after_followup_id "${ref}" matches no followup in this status`
|
|
9652
9652
|
});
|
|
9653
9653
|
return;
|
|
@@ -9655,7 +9655,7 @@ function validateFollowupLinks2(followups, label, ctx) {
|
|
|
9655
9655
|
if (target.type !== "before_event") {
|
|
9656
9656
|
ctx.addIssue({
|
|
9657
9657
|
code: external_exports.ZodIssueCode.custom,
|
|
9658
|
-
path:
|
|
9658
|
+
path: path36,
|
|
9659
9659
|
message: `kanban status ${label}: after_followup_id "${ref}" points at a ${target.type} followup \u2014 only before_event followups can anchor a chain`
|
|
9660
9660
|
});
|
|
9661
9661
|
}
|
|
@@ -9731,12 +9731,12 @@ function typeMatches2(typeField, allowed) {
|
|
|
9731
9731
|
if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
|
|
9732
9732
|
return false;
|
|
9733
9733
|
}
|
|
9734
|
-
function validateSchema2(schema,
|
|
9734
|
+
function validateSchema2(schema, path36, errors, opts = {}) {
|
|
9735
9735
|
if (typeof schema === "boolean") return;
|
|
9736
9736
|
const depth = opts.depth ?? 0;
|
|
9737
9737
|
if (depth > MAX_SCHEMA_DEPTH2) {
|
|
9738
9738
|
errors.push({
|
|
9739
|
-
path:
|
|
9739
|
+
path: path36 || "<root>",
|
|
9740
9740
|
message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH2} levels`,
|
|
9741
9741
|
suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
|
|
9742
9742
|
});
|
|
@@ -9744,7 +9744,7 @@ function validateSchema2(schema, path31, errors, opts = {}) {
|
|
|
9744
9744
|
}
|
|
9745
9745
|
if (!isRecord2(schema)) {
|
|
9746
9746
|
errors.push({
|
|
9747
|
-
path:
|
|
9747
|
+
path: path36,
|
|
9748
9748
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
9749
9749
|
});
|
|
9750
9750
|
return;
|
|
@@ -9752,14 +9752,14 @@ function validateSchema2(schema, path31, errors, opts = {}) {
|
|
|
9752
9752
|
if (opts.isRoot) {
|
|
9753
9753
|
if ("type" in schema && schema.type !== "object") {
|
|
9754
9754
|
errors.push({
|
|
9755
|
-
path:
|
|
9755
|
+
path: path36 ? `${path36}.type` : "type",
|
|
9756
9756
|
message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
|
|
9757
9757
|
suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
|
|
9758
9758
|
});
|
|
9759
9759
|
}
|
|
9760
9760
|
} else if ("type" in schema && !typeMatches2(schema.type, ALLOWED_TYPES2)) {
|
|
9761
9761
|
errors.push({
|
|
9762
|
-
path: `${
|
|
9762
|
+
path: `${path36}.type`,
|
|
9763
9763
|
message: `type must be one of ${[...ALLOWED_TYPES2].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
|
|
9764
9764
|
});
|
|
9765
9765
|
}
|
|
@@ -9769,25 +9769,25 @@ function validateSchema2(schema, path31, errors, opts = {}) {
|
|
|
9769
9769
|
const isPlaceholder = PLACEHOLDER_TOKENS2.includes(e);
|
|
9770
9770
|
const isOutcomePlaceholder = e === "[KANBAN_OUTCOME_VALUES]";
|
|
9771
9771
|
errors.push({
|
|
9772
|
-
path: `${
|
|
9772
|
+
path: `${path36}.enum`,
|
|
9773
9773
|
message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
|
|
9774
9774
|
suggestion: isOutcomePlaceholder ? "Declare `outcomes` on the hub's terminal kanban status so the platform can render the placeholder into a valid array; with none configured the platform drops the parameter instead." : 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"]`.'
|
|
9775
9775
|
});
|
|
9776
9776
|
} else if (!Array.isArray(e)) {
|
|
9777
9777
|
errors.push({
|
|
9778
|
-
path: `${
|
|
9778
|
+
path: `${path36}.enum`,
|
|
9779
9779
|
message: `enum must be a non-empty array of primitives, got ${typeof e}`
|
|
9780
9780
|
});
|
|
9781
9781
|
} else if (e.length === 0) {
|
|
9782
9782
|
errors.push({
|
|
9783
|
-
path: `${
|
|
9783
|
+
path: `${path36}.enum`,
|
|
9784
9784
|
message: "enum must not be empty"
|
|
9785
9785
|
});
|
|
9786
9786
|
} else {
|
|
9787
9787
|
for (let i = 0; i < e.length; i++) {
|
|
9788
9788
|
if (!isPrimitive2(e[i])) {
|
|
9789
9789
|
errors.push({
|
|
9790
|
-
path: `${
|
|
9790
|
+
path: `${path36}.enum[${i}]`,
|
|
9791
9791
|
message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
|
|
9792
9792
|
});
|
|
9793
9793
|
}
|
|
@@ -9797,7 +9797,7 @@ function validateSchema2(schema, path31, errors, opts = {}) {
|
|
|
9797
9797
|
for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
|
|
9798
9798
|
if (key in schema && typeof schema[key] === "boolean") {
|
|
9799
9799
|
errors.push({
|
|
9800
|
-
path: `${
|
|
9800
|
+
path: `${path36}.${key}`,
|
|
9801
9801
|
message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
|
|
9802
9802
|
suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
|
|
9803
9803
|
});
|
|
@@ -9806,45 +9806,45 @@ function validateSchema2(schema, path31, errors, opts = {}) {
|
|
|
9806
9806
|
if ("properties" in schema) {
|
|
9807
9807
|
if (!isRecord2(schema.properties)) {
|
|
9808
9808
|
errors.push({
|
|
9809
|
-
path: `${
|
|
9809
|
+
path: `${path36}.properties`,
|
|
9810
9810
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
9811
9811
|
});
|
|
9812
9812
|
} else {
|
|
9813
9813
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
9814
|
-
validateSchema2(propSchema, `${
|
|
9814
|
+
validateSchema2(propSchema, `${path36}.properties.${propName}`, errors, { depth: depth + 1 });
|
|
9815
9815
|
}
|
|
9816
9816
|
}
|
|
9817
9817
|
}
|
|
9818
9818
|
if (schemaTypeIncludes2(schema, "array") && "items" in schema) {
|
|
9819
9819
|
if (Array.isArray(schema.items)) {
|
|
9820
|
-
schema.items.forEach((sub, i) => validateSchema2(sub, `${
|
|
9820
|
+
schema.items.forEach((sub, i) => validateSchema2(sub, `${path36}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
9821
9821
|
} else {
|
|
9822
|
-
validateSchema2(schema.items, `${
|
|
9822
|
+
validateSchema2(schema.items, `${path36}.items`, errors, { depth: depth + 1 });
|
|
9823
9823
|
}
|
|
9824
9824
|
}
|
|
9825
9825
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS2) {
|
|
9826
9826
|
if (key in schema && isRecord2(schema[key])) {
|
|
9827
|
-
validateSchema2(schema[key], `${
|
|
9827
|
+
validateSchema2(schema[key], `${path36}.${key}`, errors, { depth: depth + 1 });
|
|
9828
9828
|
}
|
|
9829
9829
|
}
|
|
9830
9830
|
for (const key of SUBSCHEMA_LIST_KEYWORDS2) {
|
|
9831
9831
|
const list = schema[key];
|
|
9832
9832
|
if (Array.isArray(list)) {
|
|
9833
|
-
list.forEach((sub, i) => validateSchema2(sub, `${
|
|
9833
|
+
list.forEach((sub, i) => validateSchema2(sub, `${path36}.${key}[${i}]`, errors, { depth: depth + 1 }));
|
|
9834
9834
|
}
|
|
9835
9835
|
}
|
|
9836
9836
|
for (const key of SUBSCHEMA_MAP_KEYWORDS2) {
|
|
9837
9837
|
const map = schema[key];
|
|
9838
9838
|
if (isRecord2(map)) {
|
|
9839
9839
|
for (const [name, sub] of Object.entries(map)) {
|
|
9840
|
-
validateSchema2(sub, `${
|
|
9840
|
+
validateSchema2(sub, `${path36}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
9841
9841
|
}
|
|
9842
9842
|
}
|
|
9843
9843
|
}
|
|
9844
9844
|
const reportedPaths = new Set(errors.map((e) => e.path));
|
|
9845
9845
|
for (const [k, v] of Object.entries(schema)) {
|
|
9846
9846
|
if (typeof v !== "string") continue;
|
|
9847
|
-
const fieldPath = `${
|
|
9847
|
+
const fieldPath = `${path36}.${k}`;
|
|
9848
9848
|
if (reportedPaths.has(fieldPath)) continue;
|
|
9849
9849
|
for (const token of PLACEHOLDER_TOKENS2) {
|
|
9850
9850
|
if (v === token) {
|
|
@@ -9989,8 +9989,8 @@ function evalInitialStateError2(input) {
|
|
|
9989
9989
|
const parsed = evalInitialStateEntry2.safeParse(entries[i]);
|
|
9990
9990
|
if (!parsed.success) {
|
|
9991
9991
|
const issue = parsed.error.issues[0];
|
|
9992
|
-
const
|
|
9993
|
-
return `initial_state[${i}].${
|
|
9992
|
+
const path36 = issue?.path.join(".") || "?";
|
|
9993
|
+
return `initial_state[${i}].${path36} is invalid: ${issue?.message ?? "malformed"}`;
|
|
9994
9994
|
}
|
|
9995
9995
|
if (seenSlugs.has(parsed.data.slug)) {
|
|
9996
9996
|
return `initial_state[${i}].slug "${parsed.data.slug}" is declared more than once`;
|
|
@@ -10195,10 +10195,10 @@ function refineHubAsCodeEvals2(config, ctx) {
|
|
|
10195
10195
|
function refineHubAsCodeEvalAttachments2(config, ctx) {
|
|
10196
10196
|
const cfg = config;
|
|
10197
10197
|
const referencedHashes = /* @__PURE__ */ new Set();
|
|
10198
|
-
const addTurnIssue = (
|
|
10198
|
+
const addTurnIssue = (path36, turn, name) => {
|
|
10199
10199
|
const error = evalTurnAttachmentsError2(turn);
|
|
10200
10200
|
if (error) {
|
|
10201
|
-
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path:
|
|
10201
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path36, message: `${name}: ${error}` });
|
|
10202
10202
|
return;
|
|
10203
10203
|
}
|
|
10204
10204
|
for (const hash of collectTurnAttachmentHashes2(turn)) referencedHashes.add(hash);
|
|
@@ -10344,11 +10344,11 @@ function refineHubAsCodeDelegation2(config, ctx) {
|
|
|
10344
10344
|
}
|
|
10345
10345
|
}
|
|
10346
10346
|
if (del.context_boundary === void 0) return;
|
|
10347
|
-
const
|
|
10347
|
+
const path36 = ["agents", agentIndex, "tools", "delegation", delIndex, "context_boundary"];
|
|
10348
10348
|
if (del.type !== "hub") {
|
|
10349
10349
|
ctx.addIssue({
|
|
10350
10350
|
code: external_exports.ZodIssueCode.custom,
|
|
10351
|
-
path:
|
|
10351
|
+
path: path36,
|
|
10352
10352
|
message: `context_boundary applies only to \`type: hub\` delegations (got type "${String(del.type)}")`
|
|
10353
10353
|
});
|
|
10354
10354
|
return;
|
|
@@ -10356,7 +10356,7 @@ function refineHubAsCodeDelegation2(config, ctx) {
|
|
|
10356
10356
|
if (!CONTEXT_BOUNDARIES2.includes(del.context_boundary)) {
|
|
10357
10357
|
ctx.addIssue({
|
|
10358
10358
|
code: external_exports.ZodIssueCode.custom,
|
|
10359
|
-
path:
|
|
10359
|
+
path: path36,
|
|
10360
10360
|
message: `context_boundary must be one of: ${CONTEXT_BOUNDARIES2.join(", ")}`
|
|
10361
10361
|
});
|
|
10362
10362
|
}
|
|
@@ -14149,6 +14149,10 @@ function hubsDirLabel(gitRoot) {
|
|
|
14149
14149
|
if (!gitRoot) return path.join(WAYAI_LAYOUT.wsDir, WAYAI_LAYOUT.hubsSubdir);
|
|
14150
14150
|
return path.relative(gitRoot, resolveLayout(gitRoot).hubsDir);
|
|
14151
14151
|
}
|
|
14152
|
+
function basesDirLabel(gitRoot) {
|
|
14153
|
+
if (!gitRoot) return path.join(WAYAI_LAYOUT.wsDir, WAYAI_LAYOUT.basesSubdir);
|
|
14154
|
+
return path.relative(gitRoot, resolveLayout(gitRoot).basesDir);
|
|
14155
|
+
}
|
|
14152
14156
|
function warnLayoutOnce(gitRoot) {
|
|
14153
14157
|
const r = resolveLayout(gitRoot);
|
|
14154
14158
|
if (r.legacyAlsoPresent) {
|
|
@@ -14640,24 +14644,24 @@ import * as path4 from "path";
|
|
|
14640
14644
|
import * as readline from "readline";
|
|
14641
14645
|
function prompt(question) {
|
|
14642
14646
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
14643
|
-
return new Promise((
|
|
14647
|
+
return new Promise((resolve7) => {
|
|
14644
14648
|
rl.question(question, (answer) => {
|
|
14645
14649
|
rl.close();
|
|
14646
|
-
|
|
14650
|
+
resolve7(answer.trim());
|
|
14647
14651
|
});
|
|
14648
14652
|
});
|
|
14649
14653
|
}
|
|
14650
14654
|
function confirm(question) {
|
|
14651
14655
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
14652
|
-
return new Promise((
|
|
14656
|
+
return new Promise((resolve7) => {
|
|
14653
14657
|
rl.question(`${question} [y/N]: `, (answer) => {
|
|
14654
14658
|
rl.close();
|
|
14655
|
-
|
|
14659
|
+
resolve7(answer.trim().toLowerCase() === "y");
|
|
14656
14660
|
});
|
|
14657
14661
|
});
|
|
14658
14662
|
}
|
|
14659
14663
|
function promptSecret(question) {
|
|
14660
|
-
return new Promise((
|
|
14664
|
+
return new Promise((resolve7) => {
|
|
14661
14665
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
14662
14666
|
const originalWrite = rl._writeToOutput;
|
|
14663
14667
|
let firstWrite = true;
|
|
@@ -14673,18 +14677,18 @@ function promptSecret(question) {
|
|
|
14673
14677
|
rl._writeToOutput = originalWrite;
|
|
14674
14678
|
process.stdout.write("\n");
|
|
14675
14679
|
rl.close();
|
|
14676
|
-
|
|
14680
|
+
resolve7(answer);
|
|
14677
14681
|
});
|
|
14678
14682
|
});
|
|
14679
14683
|
}
|
|
14680
14684
|
function readStdin() {
|
|
14681
|
-
return new Promise((
|
|
14685
|
+
return new Promise((resolve7, reject) => {
|
|
14682
14686
|
let data = "";
|
|
14683
14687
|
process.stdin.setEncoding("utf-8");
|
|
14684
14688
|
process.stdin.on("data", (chunk) => {
|
|
14685
14689
|
data += chunk;
|
|
14686
14690
|
});
|
|
14687
|
-
process.stdin.on("end", () =>
|
|
14691
|
+
process.stdin.on("end", () => resolve7(data.trim()));
|
|
14688
14692
|
process.stdin.on("error", reject);
|
|
14689
14693
|
});
|
|
14690
14694
|
}
|
|
@@ -15123,7 +15127,7 @@ var init_registry = __esm({
|
|
|
15123
15127
|
disposition: "routed",
|
|
15124
15128
|
surviving: "pull",
|
|
15125
15129
|
clause: null,
|
|
15126
|
-
shipped:
|
|
15130
|
+
shipped: true,
|
|
15127
15131
|
reason: "One verb, workspace-relative, routing by subtree: `hubs/` targets preview hubs, `bases/` targets preview bases. An invocation spanning both is refused, never merged."
|
|
15128
15132
|
},
|
|
15129
15133
|
{
|
|
@@ -15131,7 +15135,7 @@ var init_registry = __esm({
|
|
|
15131
15135
|
disposition: "routed",
|
|
15132
15136
|
surviving: "push",
|
|
15133
15137
|
clause: null,
|
|
15134
|
-
shipped:
|
|
15138
|
+
shipped: true,
|
|
15135
15139
|
reason: "Same as `pull`."
|
|
15136
15140
|
}
|
|
15137
15141
|
];
|
|
@@ -15150,9 +15154,9 @@ function getVersionCachePath(filename = CLI_CACHE_FILE) {
|
|
|
15150
15154
|
}
|
|
15151
15155
|
function readVersionCache(filename = CLI_CACHE_FILE) {
|
|
15152
15156
|
try {
|
|
15153
|
-
const
|
|
15154
|
-
if (!existsSync4(
|
|
15155
|
-
const parsed = JSON.parse(readFileSync5(
|
|
15157
|
+
const path36 = getVersionCachePath(filename);
|
|
15158
|
+
if (!existsSync4(path36)) return null;
|
|
15159
|
+
const parsed = JSON.parse(readFileSync5(path36, "utf-8"));
|
|
15156
15160
|
if (typeof parsed.lastCheck !== "number") return null;
|
|
15157
15161
|
if (parsed.latest !== null && typeof parsed.latest !== "string") return null;
|
|
15158
15162
|
return parsed;
|
|
@@ -15172,10 +15176,10 @@ function isVersionCacheStale(filename = CLI_CACHE_FILE, maxAgeMs = MAX_AGE_24H_M
|
|
|
15172
15176
|
return Date.now() - cache.lastCheck > maxAgeMs;
|
|
15173
15177
|
}
|
|
15174
15178
|
function writeVersionCache(filename, cache) {
|
|
15175
|
-
const
|
|
15176
|
-
const dir = dirname3(
|
|
15179
|
+
const path36 = getVersionCachePath(filename);
|
|
15180
|
+
const dir = dirname3(path36);
|
|
15177
15181
|
if (!existsSync4(dir)) mkdirSync(dir, { recursive: true });
|
|
15178
|
-
writeFileSync2(
|
|
15182
|
+
writeFileSync2(path36, JSON.stringify(cache));
|
|
15179
15183
|
}
|
|
15180
15184
|
function touchVersionCache(filename) {
|
|
15181
15185
|
writeVersionCache(filename, { lastCheck: Date.now(), latest: readVersionCache(filename)?.latest ?? null });
|
|
@@ -15214,14 +15218,14 @@ function parseFrontmatterVersion(content) {
|
|
|
15214
15218
|
function findInstalledSkills(projectRoot, paths = SKILL_INSTALL_PATHS) {
|
|
15215
15219
|
const found = [];
|
|
15216
15220
|
for (const rel of paths) {
|
|
15217
|
-
const
|
|
15218
|
-
if (!existsSync5(
|
|
15221
|
+
const path36 = join7(projectRoot, rel);
|
|
15222
|
+
if (!existsSync5(path36)) continue;
|
|
15219
15223
|
let version = null;
|
|
15220
15224
|
try {
|
|
15221
|
-
version = parseFrontmatterVersion(readFileSync6(
|
|
15225
|
+
version = parseFrontmatterVersion(readFileSync6(path36, "utf-8"));
|
|
15222
15226
|
} catch {
|
|
15223
15227
|
}
|
|
15224
|
-
found.push({ path:
|
|
15228
|
+
found.push({ path: path36, version });
|
|
15225
15229
|
}
|
|
15226
15230
|
return found;
|
|
15227
15231
|
}
|
|
@@ -15682,7 +15686,7 @@ async function validateToken(apiUrl, token) {
|
|
|
15682
15686
|
}
|
|
15683
15687
|
}
|
|
15684
15688
|
function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
15685
|
-
return new Promise((
|
|
15689
|
+
return new Promise((resolve7, reject) => {
|
|
15686
15690
|
const server = http.createServer((req, res) => {
|
|
15687
15691
|
const url = new URL(req.url || "/", `http://127.0.0.1:${port}`);
|
|
15688
15692
|
if (url.pathname === "/callback") {
|
|
@@ -15708,7 +15712,7 @@ function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
|
15708
15712
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
15709
15713
|
res.end("<html><body><h2>Login successful!</h2><p>You can close this tab and return to your terminal.</p></body></html>");
|
|
15710
15714
|
server.close();
|
|
15711
|
-
|
|
15715
|
+
resolve7({ code, port });
|
|
15712
15716
|
} else {
|
|
15713
15717
|
res.writeHead(400, { "Content-Type": "text/html" });
|
|
15714
15718
|
res.end("<html><body><h2>Login failed</h2><p>No authorization code received</p></body></html>");
|
|
@@ -15919,10 +15923,10 @@ import * as readline2 from "readline";
|
|
|
15919
15923
|
function prompt2(question, defaultValue) {
|
|
15920
15924
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
15921
15925
|
const display = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
|
|
15922
|
-
return new Promise((
|
|
15926
|
+
return new Promise((resolve7) => {
|
|
15923
15927
|
rl.question(display, (answer) => {
|
|
15924
15928
|
rl.close();
|
|
15925
|
-
|
|
15929
|
+
resolve7(answer.trim() || defaultValue || "");
|
|
15926
15930
|
});
|
|
15927
15931
|
});
|
|
15928
15932
|
}
|
|
@@ -16040,8 +16044,8 @@ async function tryOpenBrowser(url) {
|
|
|
16040
16044
|
cmd = "xdg-open";
|
|
16041
16045
|
args2 = [url];
|
|
16042
16046
|
}
|
|
16043
|
-
return new Promise((
|
|
16044
|
-
execFile(cmd, args2, (err) =>
|
|
16047
|
+
return new Promise((resolve7) => {
|
|
16048
|
+
execFile(cmd, args2, (err) => resolve7(!err));
|
|
16045
16049
|
});
|
|
16046
16050
|
} catch {
|
|
16047
16051
|
return false;
|
|
@@ -16801,6 +16805,15 @@ function ensureRealSubdirNoSymlink(root, target, create) {
|
|
|
16801
16805
|
}
|
|
16802
16806
|
return true;
|
|
16803
16807
|
}
|
|
16808
|
+
function readFileNoFollow(root, abs) {
|
|
16809
|
+
if (!ensureRealSubdirNoSymlink(root, path11.dirname(abs), false)) return null;
|
|
16810
|
+
try {
|
|
16811
|
+
if (!fs9.lstatSync(abs).isFile()) return null;
|
|
16812
|
+
return fs9.readFileSync(abs);
|
|
16813
|
+
} catch {
|
|
16814
|
+
return null;
|
|
16815
|
+
}
|
|
16816
|
+
}
|
|
16804
16817
|
function writeFileNoFollow(root, abs, data) {
|
|
16805
16818
|
const parent = path11.dirname(abs);
|
|
16806
16819
|
if (!ensureRealSubdirNoSymlink(root, parent, true)) return false;
|
|
@@ -18051,202 +18064,1414 @@ var init_hub_materializer = __esm({
|
|
|
18051
18064
|
}
|
|
18052
18065
|
});
|
|
18053
18066
|
|
|
18054
|
-
// src/
|
|
18055
|
-
|
|
18056
|
-
|
|
18057
|
-
|
|
18058
|
-
|
|
18059
|
-
|
|
18060
|
-
|
|
18061
|
-
|
|
18062
|
-
|
|
18063
|
-
|
|
18064
|
-
|
|
18065
|
-
|
|
18066
|
-
|
|
18067
|
-
|
|
18067
|
+
// src/lib/terminal-output.ts
|
|
18068
|
+
import { stripVTControlCharacters } from "util";
|
|
18069
|
+
function sanitizeTerminalText(value) {
|
|
18070
|
+
const normalizedNewlines = value.replace(/\r\n?/g, "\n");
|
|
18071
|
+
return stripVTControlCharacters(normalizedNewlines).replace(
|
|
18072
|
+
/[\u0000-\u0009\u000b-\u001f\u007f-\u009f]/g,
|
|
18073
|
+
""
|
|
18074
|
+
);
|
|
18075
|
+
}
|
|
18076
|
+
var init_terminal_output = __esm({
|
|
18077
|
+
"src/lib/terminal-output.ts"() {
|
|
18078
|
+
"use strict";
|
|
18079
|
+
}
|
|
18080
|
+
});
|
|
18081
|
+
|
|
18082
|
+
// src/lib/base-id.ts
|
|
18083
|
+
function isValidBaseId(id) {
|
|
18084
|
+
return BASE_ID_RE.test(id);
|
|
18085
|
+
}
|
|
18086
|
+
var BASE_ID_RE;
|
|
18087
|
+
var init_base_id = __esm({
|
|
18088
|
+
"src/lib/base-id.ts"() {
|
|
18089
|
+
"use strict";
|
|
18090
|
+
BASE_ID_RE = /^(?!\.\.?$)[A-Za-z0-9._-]{1,256}$/;
|
|
18091
|
+
}
|
|
18068
18092
|
});
|
|
18093
|
+
|
|
18094
|
+
// src/lib/base-workspace.ts
|
|
18069
18095
|
import * as fs14 from "fs";
|
|
18070
18096
|
import * as path17 from "path";
|
|
18071
18097
|
import * as yaml6 from "js-yaml";
|
|
18072
|
-
function
|
|
18073
|
-
|
|
18074
|
-
|
|
18075
|
-
let
|
|
18076
|
-
|
|
18077
|
-
|
|
18078
|
-
|
|
18079
|
-
|
|
18080
|
-
} else if (arg === "--hub" && args2[i + 1]) {
|
|
18081
|
-
hubSelector = args2[++i];
|
|
18082
|
-
} else if (arg === "--label" && args2[i + 1]) {
|
|
18083
|
-
label = args2[++i];
|
|
18084
|
-
}
|
|
18098
|
+
function readBaseMeta(folder) {
|
|
18099
|
+
const bytes = readFileNoFollow(folder, path17.join(folder, BASE_META_FILE));
|
|
18100
|
+
if (bytes === null) return null;
|
|
18101
|
+
let doc;
|
|
18102
|
+
try {
|
|
18103
|
+
doc = yaml6.load(bytes.toString("utf-8"));
|
|
18104
|
+
} catch {
|
|
18105
|
+
return null;
|
|
18085
18106
|
}
|
|
18086
|
-
|
|
18087
|
-
|
|
18088
|
-
function shouldWarnIgnoredPreviewLabel(localLabel, serverLabel) {
|
|
18089
|
-
return Boolean(localLabel) && serverLabel !== void 0 && localLabel !== serverLabel;
|
|
18107
|
+
if (!doc || typeof doc !== "object" || Array.isArray(doc)) return null;
|
|
18108
|
+
return doc;
|
|
18090
18109
|
}
|
|
18091
|
-
function
|
|
18092
|
-
|
|
18093
|
-
|
|
18094
|
-
|
|
18095
|
-
|
|
18110
|
+
function listBaseFolders(basesDir) {
|
|
18111
|
+
let entries;
|
|
18112
|
+
try {
|
|
18113
|
+
entries = fs14.readdirSync(basesDir).filter((entry) => !entry.startsWith("."));
|
|
18114
|
+
} catch {
|
|
18115
|
+
return [];
|
|
18096
18116
|
}
|
|
18097
|
-
|
|
18098
|
-
|
|
18099
|
-
|
|
18100
|
-
|
|
18101
|
-
|
|
18102
|
-
|
|
18103
|
-
if (c.connections_updated > 0) parts.push(`${c.connections_updated} connection(s) updated`);
|
|
18104
|
-
if (c.connections_deleted > 0) parts.push(`${c.connections_deleted} connection(s) deleted`);
|
|
18105
|
-
if (c.agents_created > 0) parts.push(`${c.agents_created} agent(s) created`);
|
|
18106
|
-
if (c.agents_updated > 0) parts.push(`${c.agents_updated} agent(s) updated`);
|
|
18107
|
-
if (c.agents_deleted > 0) parts.push(`${c.agents_deleted} agent(s) deleted`);
|
|
18108
|
-
if (c.tools_created > 0) parts.push(`${c.tools_created} tool(s) created`);
|
|
18109
|
-
if (c.tools_updated > 0) parts.push(`${c.tools_updated} tool(s) updated`);
|
|
18110
|
-
if (c.tools_deleted > 0) parts.push(`${c.tools_deleted} tool(s) deleted`);
|
|
18111
|
-
if (c.states_created > 0) parts.push(`${c.states_created} state(s) created`);
|
|
18112
|
-
if (c.states_updated > 0) parts.push(`${c.states_updated} state(s) updated`);
|
|
18113
|
-
if (c.states_deleted > 0) parts.push(`${c.states_deleted} state(s) deleted`);
|
|
18114
|
-
if (c.evals_created > 0) parts.push(`${c.evals_created} eval(s) created`);
|
|
18115
|
-
if (c.evals_updated > 0) parts.push(`${c.evals_updated} eval(s) updated`);
|
|
18116
|
-
if (c.evals_deleted > 0) parts.push(`${c.evals_deleted} eval(s) deleted`);
|
|
18117
|
-
if (c.journeys_created > 0) parts.push(`${c.journeys_created} journey(s) created`);
|
|
18118
|
-
if (c.journeys_updated > 0) parts.push(`${c.journeys_updated} journey(s) updated`);
|
|
18119
|
-
if (c.journeys_deleted > 0) parts.push(`${c.journeys_deleted} journey(s) deleted`);
|
|
18120
|
-
if (c.teams_created > 0) parts.push(`${c.teams_created} team(s) created`);
|
|
18121
|
-
if (c.teams_updated > 0) parts.push(`${c.teams_updated} team(s) updated`);
|
|
18122
|
-
if (c.teams_deleted > 0) parts.push(`${c.teams_deleted} team(s) deleted`);
|
|
18123
|
-
if (c.resources_created > 0) parts.push(`${c.resources_created} resource(s) created`);
|
|
18124
|
-
if (c.resources_updated > 0) parts.push(`${c.resources_updated} resource(s) updated`);
|
|
18125
|
-
if (c.resources_deleted > 0) parts.push(`${c.resources_deleted} resource(s) deleted`);
|
|
18126
|
-
if (c.resource_files_uploaded > 0) parts.push(`${c.resource_files_uploaded} resource file(s) uploaded`);
|
|
18127
|
-
if (c.resource_files_deleted > 0) parts.push(`${c.resource_files_deleted} resource file(s) deleted`);
|
|
18128
|
-
if (c.resource_links_created > 0) parts.push(`${c.resource_links_created} resource link(s) created`);
|
|
18129
|
-
if (c.resource_links_updated > 0) parts.push(`${c.resource_links_updated} resource link(s) updated`);
|
|
18130
|
-
if (c.resource_links_deleted > 0) parts.push(`${c.resource_links_deleted} resource link(s) deleted`);
|
|
18131
|
-
if (c.outbound_contacts_created > 0) parts.push(`${c.outbound_contacts_created} outbound contact(s) created`);
|
|
18132
|
-
if (c.outbound_contacts_updated > 0) parts.push(`${c.outbound_contacts_updated} outbound contact(s) updated`);
|
|
18133
|
-
if (c.outbound_contacts_deleted > 0) parts.push(`${c.outbound_contacts_deleted} outbound contact(s) deleted`);
|
|
18134
|
-
if (c.outbound_lists_created > 0) parts.push(`${c.outbound_lists_created} outbound list(s) created`);
|
|
18135
|
-
if (c.outbound_lists_updated > 0) parts.push(`${c.outbound_lists_updated} outbound list(s) updated`);
|
|
18136
|
-
if (c.outbound_lists_deleted > 0) parts.push(`${c.outbound_lists_deleted} outbound list(s) deleted`);
|
|
18137
|
-
if (c.outbound_schedules_created > 0) parts.push(`${c.outbound_schedules_created} outbound schedule(s) created`);
|
|
18138
|
-
if (c.outbound_schedules_updated > 0) parts.push(`${c.outbound_schedules_updated} outbound schedule(s) updated`);
|
|
18139
|
-
if (c.outbound_schedules_deleted > 0) parts.push(`${c.outbound_schedules_deleted} outbound schedule(s) deleted`);
|
|
18140
|
-
if (parts.length > 0) {
|
|
18141
|
-
console.log(`Changes: ${parts.join(", ")}`);
|
|
18117
|
+
const out = [];
|
|
18118
|
+
for (const name of entries.sort()) {
|
|
18119
|
+
const folder = path17.join(basesDir, name);
|
|
18120
|
+
if (!isDirectory(folder)) continue;
|
|
18121
|
+
const meta = readBaseMeta(folder);
|
|
18122
|
+
if (meta) out.push({ folder, meta });
|
|
18142
18123
|
}
|
|
18143
|
-
|
|
18144
|
-
|
|
18124
|
+
return out;
|
|
18125
|
+
}
|
|
18126
|
+
function isProductionFolder(meta) {
|
|
18127
|
+
return meta.environment === "production";
|
|
18128
|
+
}
|
|
18129
|
+
function filterEditableBases(bases) {
|
|
18130
|
+
return bases.filter((b) => !isProductionFolder(b.meta));
|
|
18131
|
+
}
|
|
18132
|
+
function isUnder(parent, child) {
|
|
18133
|
+
const rel = path17.relative(parent, child);
|
|
18134
|
+
return rel === "" || !rel.startsWith("..") && !path17.isAbsolute(rel);
|
|
18135
|
+
}
|
|
18136
|
+
function findEnclosingBaseFolder(basesDir, cwd) {
|
|
18137
|
+
let dir = path17.resolve(cwd);
|
|
18138
|
+
const stop = path17.resolve(basesDir);
|
|
18139
|
+
while (isUnder(stop, dir)) {
|
|
18140
|
+
const meta = readBaseMeta(dir);
|
|
18141
|
+
if (meta) return { folder: dir, meta };
|
|
18142
|
+
const parent = path17.dirname(dir);
|
|
18143
|
+
if (parent === dir) break;
|
|
18144
|
+
dir = parent;
|
|
18145
18145
|
}
|
|
18146
|
+
return null;
|
|
18146
18147
|
}
|
|
18147
|
-
function
|
|
18148
|
-
|
|
18149
|
-
|
|
18150
|
-
|
|
18151
|
-
|
|
18152
|
-
|
|
18148
|
+
function folderForSelector(basesDir, selector) {
|
|
18149
|
+
assertValidBaseSelector(selector);
|
|
18150
|
+
return path17.join(basesDir, selector);
|
|
18151
|
+
}
|
|
18152
|
+
function assertValidBaseSelector(selector, source = "base") {
|
|
18153
|
+
if (!isValidBaseId(selector)) {
|
|
18154
|
+
throw expected(
|
|
18155
|
+
`Invalid ${source} "${selector}". Base ids are slugs \u2014 letters, digits, dot, dash and underscore only, with no path separators.`
|
|
18156
|
+
);
|
|
18153
18157
|
}
|
|
18154
18158
|
}
|
|
18155
|
-
function
|
|
18156
|
-
|
|
18157
|
-
|
|
18158
|
-
|
|
18159
|
-
|
|
18160
|
-
|
|
18161
|
-
|
|
18159
|
+
function resolveBaseTarget(gitRoot, selector, cwd = process.cwd()) {
|
|
18160
|
+
const basesDir = resolveBasesDir(gitRoot);
|
|
18161
|
+
if (selector) {
|
|
18162
|
+
const folder = folderForSelector(basesDir, selector);
|
|
18163
|
+
if (!isUnder(basesDir, folder)) {
|
|
18164
|
+
throw expected(`Refusing to target ${folder}: it is outside ${basesDir}.`);
|
|
18165
|
+
}
|
|
18166
|
+
return { folder, exists: hasBaseMetaFile(folder), meta: readBaseMeta(folder) };
|
|
18167
|
+
}
|
|
18168
|
+
const enclosing = findEnclosingBaseFolder(basesDir, cwd);
|
|
18169
|
+
if (enclosing) return { folder: enclosing.folder, exists: true, meta: enclosing.meta };
|
|
18170
|
+
const editable = filterEditableBases(listBaseFolders(basesDir));
|
|
18171
|
+
if (editable.length === 1) {
|
|
18172
|
+
return { folder: editable[0].folder, exists: true, meta: editable[0].meta };
|
|
18173
|
+
}
|
|
18174
|
+
const label = basesDirLabel(gitRoot);
|
|
18175
|
+
if (editable.length === 0) {
|
|
18176
|
+
throw expected(
|
|
18177
|
+
`No base folders found in ${label}/. Pass a base id to fetch one for the first time (e.g. \`wayai pull bases/<base>\`).`
|
|
18178
|
+
);
|
|
18162
18179
|
}
|
|
18180
|
+
throw expected(
|
|
18181
|
+
[
|
|
18182
|
+
`Multiple bases found in ${label}/. Pass --base <id|folder-name> to choose, or run from inside a base folder:`,
|
|
18183
|
+
...editable.map((b) => ` ${path17.basename(b.folder)} (${b.meta.base_id ?? "not created yet"})`)
|
|
18184
|
+
].join("\n")
|
|
18185
|
+
);
|
|
18163
18186
|
}
|
|
18164
|
-
function
|
|
18165
|
-
if (
|
|
18166
|
-
|
|
18167
|
-
|
|
18187
|
+
function targetBaseId(target, selector) {
|
|
18188
|
+
if (target.meta?.base_id) return target.meta.base_id;
|
|
18189
|
+
if (selector && !selector.includes("/") && !selector.includes(path17.sep)) return selector;
|
|
18190
|
+
return target.exists ? null : path17.basename(target.folder);
|
|
18191
|
+
}
|
|
18192
|
+
function hasBaseMetaFile(folder) {
|
|
18193
|
+
try {
|
|
18194
|
+
return fs14.lstatSync(path17.join(folder, BASE_META_FILE)).isFile();
|
|
18195
|
+
} catch {
|
|
18196
|
+
return false;
|
|
18168
18197
|
}
|
|
18169
|
-
|
|
18170
|
-
|
|
18171
|
-
|
|
18172
|
-
|
|
18173
|
-
|
|
18174
|
-
|
|
18198
|
+
}
|
|
18199
|
+
var BASE_META_FILE;
|
|
18200
|
+
var init_base_workspace = __esm({
|
|
18201
|
+
"src/lib/base-workspace.ts"() {
|
|
18202
|
+
"use strict";
|
|
18203
|
+
init_layout();
|
|
18204
|
+
init_expected();
|
|
18205
|
+
init_base_id();
|
|
18206
|
+
init_fs_safety();
|
|
18207
|
+
BASE_META_FILE = "base.yaml";
|
|
18208
|
+
}
|
|
18209
|
+
});
|
|
18210
|
+
|
|
18211
|
+
// src/lib/subtree-routing.ts
|
|
18212
|
+
import * as fs15 from "fs";
|
|
18213
|
+
import * as path18 from "path";
|
|
18214
|
+
import * as yaml7 from "js-yaml";
|
|
18215
|
+
function readRepoDefaults(gitRoot) {
|
|
18216
|
+
const file = path18.join(gitRoot, WAYAI_LAYOUT.wsDir, REPO_DEFAULTS_FILE);
|
|
18217
|
+
let doc;
|
|
18218
|
+
try {
|
|
18219
|
+
doc = yaml7.load(fs15.readFileSync(file, "utf-8"));
|
|
18220
|
+
} catch {
|
|
18221
|
+
return {};
|
|
18222
|
+
}
|
|
18223
|
+
if (!doc || typeof doc !== "object") return {};
|
|
18224
|
+
const raw = doc;
|
|
18225
|
+
const str = (v) => {
|
|
18226
|
+
if (typeof v !== "string" || !v.trim()) return void 0;
|
|
18227
|
+
const value = v.trim();
|
|
18228
|
+
if (value.includes("/") || value.includes(path18.sep) || value === "." || value === "..") {
|
|
18229
|
+
console.warn(
|
|
18230
|
+
`Warning: ignoring ${JSON.stringify(value)} in ${WAYAI_LAYOUT.wsDir}/${REPO_DEFAULTS_FILE} \u2014 a default names a hub or base, not a path.`
|
|
18231
|
+
);
|
|
18232
|
+
return void 0;
|
|
18175
18233
|
}
|
|
18234
|
+
return value;
|
|
18176
18235
|
};
|
|
18177
|
-
|
|
18178
|
-
emit(delta.changed, "~");
|
|
18236
|
+
return { default_hub: str(raw.default_hub), default_base: str(raw.default_base) };
|
|
18179
18237
|
}
|
|
18180
|
-
|
|
18181
|
-
const
|
|
18182
|
-
let
|
|
18183
|
-
|
|
18184
|
-
const
|
|
18185
|
-
|
|
18186
|
-
|
|
18187
|
-
|
|
18188
|
-
|
|
18189
|
-
if (
|
|
18190
|
-
|
|
18191
|
-
|
|
18192
|
-
|
|
18193
|
-
console.warn(` Warning: could not parse agents/${file}, skipping`);
|
|
18238
|
+
function parseRoutingTokens(args2) {
|
|
18239
|
+
const tokens = {};
|
|
18240
|
+
for (let i = 0; i < args2.length; i++) {
|
|
18241
|
+
const arg = args2[i];
|
|
18242
|
+
const eq = arg.indexOf("=");
|
|
18243
|
+
const name = eq === -1 ? arg : arg.slice(0, eq);
|
|
18244
|
+
if (VALUE_FLAGS.has(name)) {
|
|
18245
|
+
const value = eq === -1 ? args2[i + 1] : arg.slice(eq + 1);
|
|
18246
|
+
if (value !== void 0) {
|
|
18247
|
+
if (name === "--hub") tokens.hubFlag ??= value;
|
|
18248
|
+
if (name === "--base") tokens.baseFlag ??= value;
|
|
18249
|
+
if (name === "--org") tokens.orgFlag ??= value;
|
|
18250
|
+
if (eq === -1) i++;
|
|
18194
18251
|
}
|
|
18252
|
+
continue;
|
|
18195
18253
|
}
|
|
18254
|
+
if (arg.startsWith("-")) continue;
|
|
18255
|
+
tokens.positional ??= arg;
|
|
18196
18256
|
}
|
|
18197
|
-
|
|
18198
|
-
|
|
18199
|
-
|
|
18200
|
-
|
|
18201
|
-
|
|
18202
|
-
|
|
18257
|
+
return tokens;
|
|
18258
|
+
}
|
|
18259
|
+
function firstSegment(p) {
|
|
18260
|
+
const normalized = p.split(path18.sep).join("/");
|
|
18261
|
+
const [head] = normalized.split("/").filter(Boolean);
|
|
18262
|
+
return head ?? p;
|
|
18263
|
+
}
|
|
18264
|
+
function selectorSubtree(layout, selector, cwd) {
|
|
18265
|
+
const parts = selector.split(path18.sep).join("/").split("/").filter(Boolean);
|
|
18266
|
+
const qualified = parts[0] === WAYAI_LAYOUT.wsDir ? parts.slice(1) : parts;
|
|
18267
|
+
if (qualified.length > 1) {
|
|
18268
|
+
if (qualified[0] === WAYAI_LAYOUT.hubsSubdir) return { kind: "hubs", target: qualified[1] };
|
|
18269
|
+
if (qualified[0] === WAYAI_LAYOUT.basesSubdir) return { kind: "bases", target: qualified[1] };
|
|
18270
|
+
}
|
|
18271
|
+
if (!layout) return { kind: "unknown" };
|
|
18272
|
+
const { hubsDir, basesDir } = layout;
|
|
18273
|
+
if (selector.includes("/") || selector.includes(path18.sep)) {
|
|
18274
|
+
const abs = path18.resolve(cwd, selector);
|
|
18275
|
+
if (isUnder(hubsDir, abs)) return { kind: "hubs", target: firstSegment(path18.relative(hubsDir, abs)) };
|
|
18276
|
+
if (isUnder(basesDir, abs)) return { kind: "bases", target: firstSegment(path18.relative(basesDir, abs)) };
|
|
18277
|
+
return { kind: "unknown" };
|
|
18278
|
+
}
|
|
18279
|
+
const inHubs = isDirectory(path18.join(hubsDir, selector));
|
|
18280
|
+
const inBases = isDirectory(path18.join(basesDir, selector));
|
|
18281
|
+
if (inHubs && inBases) return { kind: "both", target: selector };
|
|
18282
|
+
if (inHubs) return { kind: "hubs", target: selector };
|
|
18283
|
+
if (inBases) return { kind: "bases", target: selector };
|
|
18284
|
+
return { kind: "unknown" };
|
|
18285
|
+
}
|
|
18286
|
+
function listCandidates(layout) {
|
|
18287
|
+
const hubs = [
|
|
18288
|
+
...filterPreviewHubs(scanWorkspaceHubs(layout.hubsDir)).map((h) => h.hubFolder),
|
|
18289
|
+
...scanNewHubs(layout.hubsDir).map((h) => h.hubFolder)
|
|
18290
|
+
];
|
|
18291
|
+
const bases = filterEditableBases(listBaseFolders(layout.basesDir)).map((b) => b.folder);
|
|
18292
|
+
return [
|
|
18293
|
+
...hubs.map((folder) => ({ subtree: "hubs", name: path18.basename(folder) })),
|
|
18294
|
+
...bases.map((folder) => ({ subtree: "bases", name: path18.basename(folder) }))
|
|
18295
|
+
];
|
|
18296
|
+
}
|
|
18297
|
+
function mixedInvocationRefusal(verb, hubTarget, baseTarget) {
|
|
18298
|
+
const hub = sanitizeTerminalText(hubTarget);
|
|
18299
|
+
const base = sanitizeTerminalText(baseTarget);
|
|
18300
|
+
return [
|
|
18301
|
+
`Refusing a mixed ${verb}: this invocation spans both subtrees.`,
|
|
18302
|
+
` ${WAYAI_LAYOUT.hubsSubdir}/ -> ${hub}`,
|
|
18303
|
+
` ${WAYAI_LAYOUT.basesSubdir}/ -> ${base}`,
|
|
18304
|
+
"",
|
|
18305
|
+
"Run one at a time:",
|
|
18306
|
+
` wayai ${verb} ${WAYAI_LAYOUT.hubsSubdir}/${hub}`,
|
|
18307
|
+
` wayai ${verb} ${WAYAI_LAYOUT.basesSubdir}/${base}`
|
|
18308
|
+
].join("\n");
|
|
18309
|
+
}
|
|
18310
|
+
function routeSubtree(options) {
|
|
18311
|
+
const { verb, args: args2, gitRoot } = options;
|
|
18312
|
+
const cwd = options.cwd ?? process.cwd();
|
|
18313
|
+
const { hubFlag, baseFlag, positional, orgFlag } = parseRoutingTokens(args2);
|
|
18314
|
+
if (orgFlag !== void 0) {
|
|
18315
|
+
return {
|
|
18316
|
+
ok: false,
|
|
18317
|
+
refusal: [
|
|
18318
|
+
`\`wayai ${verb}\` does not take --org: it operates on the organization named by .wayai.yaml at the repo root.`,
|
|
18319
|
+
"",
|
|
18320
|
+
"To act on another organization:",
|
|
18321
|
+
" wayai bases <command> --org <uuid> # the Data surface honors it",
|
|
18322
|
+
" # or run from a checkout whose .wayai.yaml names that organization"
|
|
18323
|
+
].join("\n")
|
|
18324
|
+
};
|
|
18203
18325
|
}
|
|
18204
|
-
|
|
18205
|
-
|
|
18206
|
-
|
|
18207
|
-
if (!remote) {
|
|
18208
|
-
try {
|
|
18209
|
-
remote = await client.pull(hubId, organizationId);
|
|
18210
|
-
} catch (err) {
|
|
18211
|
-
console.warn(` Warning: could not fetch remote state for auto-rename (${err instanceof Error ? err.message : String(err)}). File renames skipped.`);
|
|
18212
|
-
return;
|
|
18213
|
-
}
|
|
18326
|
+
const layout = gitRoot ? resolveLayout(gitRoot) : null;
|
|
18327
|
+
if (hubFlag !== void 0 && baseFlag !== void 0) {
|
|
18328
|
+
return { ok: false, refusal: mixedInvocationRefusal(verb, hubFlag, baseFlag) };
|
|
18214
18329
|
}
|
|
18215
|
-
const
|
|
18216
|
-
|
|
18217
|
-
|
|
18218
|
-
|
|
18219
|
-
|
|
18330
|
+
const fromPositional = positional !== void 0 ? selectorSubtree(layout, positional, cwd) : void 0;
|
|
18331
|
+
if (fromPositional?.kind === "both") {
|
|
18332
|
+
return {
|
|
18333
|
+
ok: false,
|
|
18334
|
+
refusal: mixedInvocationRefusal(verb, fromPositional.target, fromPositional.target)
|
|
18335
|
+
};
|
|
18220
18336
|
}
|
|
18221
|
-
|
|
18222
|
-
|
|
18223
|
-
|
|
18224
|
-
if (!remoteName || remoteName === agent.name) continue;
|
|
18225
|
-
const oldSlug = slugify(remoteName);
|
|
18226
|
-
const newSlug = slugify(agent.name);
|
|
18227
|
-
if (oldSlug !== newSlug) {
|
|
18228
|
-
renames.push({ oldSlug, newSlug });
|
|
18337
|
+
if (hubFlag !== void 0) {
|
|
18338
|
+
if (fromPositional?.kind === "bases") {
|
|
18339
|
+
return { ok: false, refusal: mixedInvocationRefusal(verb, hubFlag, fromPositional.target) };
|
|
18229
18340
|
}
|
|
18341
|
+
return { ok: true, subtree: "hubs", selector: hubFlag };
|
|
18230
18342
|
}
|
|
18231
|
-
if (
|
|
18232
|
-
|
|
18233
|
-
|
|
18234
|
-
if (file.startsWith("__rename_temp_") && (file.endsWith(".md") || file.endsWith(".yaml"))) {
|
|
18235
|
-
console.warn(` Warning: removing orphaned temp file agents/${file}`);
|
|
18236
|
-
fs14.unlinkSync(path17.join(agentsDir, file));
|
|
18343
|
+
if (baseFlag !== void 0) {
|
|
18344
|
+
if (fromPositional?.kind === "hubs") {
|
|
18345
|
+
return { ok: false, refusal: mixedInvocationRefusal(verb, fromPositional.target, baseFlag) };
|
|
18237
18346
|
}
|
|
18347
|
+
return { ok: true, subtree: "bases", selector: baseFlag };
|
|
18238
18348
|
}
|
|
18239
|
-
|
|
18240
|
-
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
|
|
18244
|
-
|
|
18245
|
-
};
|
|
18246
|
-
|
|
18247
|
-
const
|
|
18248
|
-
|
|
18249
|
-
|
|
18349
|
+
if (fromPositional?.kind === "hubs" || fromPositional?.kind === "bases") {
|
|
18350
|
+
return { ok: true, subtree: fromPositional.kind, selector: fromPositional.target };
|
|
18351
|
+
}
|
|
18352
|
+
const carried = positional;
|
|
18353
|
+
if (!gitRoot || !layout) return { ok: true, subtree: "hubs", selector: carried };
|
|
18354
|
+
const { hubsDir, basesDir } = layout;
|
|
18355
|
+
if (isUnder(hubsDir, cwd)) return { ok: true, subtree: "hubs", selector: carried };
|
|
18356
|
+
if (isUnder(basesDir, cwd)) return { ok: true, subtree: "bases", selector: carried };
|
|
18357
|
+
const defaults = readRepoDefaults(gitRoot);
|
|
18358
|
+
if (defaults.default_hub && defaults.default_base) {
|
|
18359
|
+
return {
|
|
18360
|
+
ok: false,
|
|
18361
|
+
refusal: mixedInvocationRefusal(verb, defaults.default_hub, defaults.default_base)
|
|
18362
|
+
};
|
|
18363
|
+
}
|
|
18364
|
+
if (defaults.default_hub) return { ok: true, subtree: "hubs", selector: carried ?? defaults.default_hub };
|
|
18365
|
+
if (defaults.default_base) return { ok: true, subtree: "bases", selector: carried ?? defaults.default_base };
|
|
18366
|
+
const candidates = listCandidates(layout);
|
|
18367
|
+
if (candidates.length === 1) {
|
|
18368
|
+
return { ok: true, subtree: candidates[0].subtree, selector: carried };
|
|
18369
|
+
}
|
|
18370
|
+
const hubCandidates = candidates.filter((c) => c.subtree === "hubs");
|
|
18371
|
+
const baseCandidates = candidates.filter((c) => c.subtree === "bases");
|
|
18372
|
+
if (hubCandidates.length > 0 && baseCandidates.length > 0) {
|
|
18373
|
+
return {
|
|
18374
|
+
ok: false,
|
|
18375
|
+
refusal: mixedInvocationRefusal(verb, hubCandidates[0].name, baseCandidates[0].name)
|
|
18376
|
+
};
|
|
18377
|
+
}
|
|
18378
|
+
if (baseCandidates.length > 0) return { ok: true, subtree: "bases", selector: carried };
|
|
18379
|
+
return { ok: true, subtree: "hubs", selector: carried };
|
|
18380
|
+
}
|
|
18381
|
+
function requireSubtree(verb, args2, gitRoot) {
|
|
18382
|
+
const result = routeSubtree({ verb, args: args2, gitRoot });
|
|
18383
|
+
if (!result.ok) {
|
|
18384
|
+
console.error(result.refusal);
|
|
18385
|
+
process.exit(1);
|
|
18386
|
+
}
|
|
18387
|
+
return { subtree: result.subtree, selector: result.selector };
|
|
18388
|
+
}
|
|
18389
|
+
var REPO_DEFAULTS_FILE, VALUE_FLAGS;
|
|
18390
|
+
var init_subtree_routing = __esm({
|
|
18391
|
+
"src/lib/subtree-routing.ts"() {
|
|
18392
|
+
"use strict";
|
|
18393
|
+
init_layout();
|
|
18394
|
+
init_terminal_output();
|
|
18395
|
+
init_workspace();
|
|
18396
|
+
init_base_workspace();
|
|
18397
|
+
REPO_DEFAULTS_FILE = "wayai.yaml";
|
|
18398
|
+
VALUE_FLAGS = /* @__PURE__ */ new Set(["--hub", "--base", "--label", "--org"]);
|
|
18399
|
+
}
|
|
18400
|
+
});
|
|
18401
|
+
|
|
18402
|
+
// src/data/org-context.ts
|
|
18403
|
+
function setDataOrgOverride(orgId) {
|
|
18404
|
+
override = orgId;
|
|
18405
|
+
}
|
|
18406
|
+
function getDataOrgOverride() {
|
|
18407
|
+
return override;
|
|
18408
|
+
}
|
|
18409
|
+
var override;
|
|
18410
|
+
var init_org_context = __esm({
|
|
18411
|
+
"src/data/org-context.ts"() {
|
|
18412
|
+
"use strict";
|
|
18413
|
+
}
|
|
18414
|
+
});
|
|
18415
|
+
|
|
18416
|
+
// src/data/client.ts
|
|
18417
|
+
async function createDataClient(orgId) {
|
|
18418
|
+
const { config, accessToken } = await requireAuth();
|
|
18419
|
+
const api = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
18420
|
+
const selected = orgId ?? getDataOrgOverride();
|
|
18421
|
+
if (selected !== void 0 && !UUID_RE2.test(selected)) {
|
|
18422
|
+
throw expected(`Invalid --org: ${JSON.stringify(selected)}. Expected an organization UUID.`);
|
|
18423
|
+
}
|
|
18424
|
+
const org = selected ?? readRepoConfig()?.organization_id;
|
|
18425
|
+
return {
|
|
18426
|
+
async request(method, path36, body) {
|
|
18427
|
+
const envelope = await api.dataRequest(method, path36, body, org);
|
|
18428
|
+
return envelope.data;
|
|
18429
|
+
},
|
|
18430
|
+
async requestRaw(method, path36, body) {
|
|
18431
|
+
const body_ = await api.dataRequest(method, path36, body, org);
|
|
18432
|
+
return body_;
|
|
18433
|
+
},
|
|
18434
|
+
async collectPages(makePath) {
|
|
18435
|
+
const all = [];
|
|
18436
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18437
|
+
let cursor;
|
|
18438
|
+
for (let page = 0; page < MAX_PAGES; page++) {
|
|
18439
|
+
const { data, meta } = await api.dataRequest("GET", makePath(cursor), void 0, org);
|
|
18440
|
+
for (const row of data ?? []) all.push(row);
|
|
18441
|
+
cursor = meta?.has_more ? meta.cursor : void 0;
|
|
18442
|
+
if (cursor === void 0) break;
|
|
18443
|
+
if (seen.has(cursor)) break;
|
|
18444
|
+
seen.add(cursor);
|
|
18445
|
+
}
|
|
18446
|
+
return all;
|
|
18447
|
+
},
|
|
18448
|
+
async upload(v1Path, bytes, contentType, headers) {
|
|
18449
|
+
const envelope = await api.dataUpload(v1Path, bytes, contentType, org, headers);
|
|
18450
|
+
return envelope.data;
|
|
18451
|
+
},
|
|
18452
|
+
download(v1Path) {
|
|
18453
|
+
return api.dataDownload(v1Path, org);
|
|
18454
|
+
},
|
|
18455
|
+
url(v1Path) {
|
|
18456
|
+
return api.dataUrl(v1Path, org);
|
|
18457
|
+
}
|
|
18458
|
+
};
|
|
18459
|
+
}
|
|
18460
|
+
function dataErrorEnvelope(err) {
|
|
18461
|
+
if (!(err instanceof ApiError)) return null;
|
|
18462
|
+
try {
|
|
18463
|
+
const parsed = JSON.parse(err.body);
|
|
18464
|
+
return parsed?.error ?? null;
|
|
18465
|
+
} catch {
|
|
18466
|
+
return null;
|
|
18467
|
+
}
|
|
18468
|
+
}
|
|
18469
|
+
function dataErrorCode(err) {
|
|
18470
|
+
const code = dataErrorEnvelope(err)?.code;
|
|
18471
|
+
return typeof code === "string" && code ? code : null;
|
|
18472
|
+
}
|
|
18473
|
+
function dataErrorDetails(err) {
|
|
18474
|
+
const details = dataErrorEnvelope(err)?.details;
|
|
18475
|
+
return details && typeof details === "object" ? details : void 0;
|
|
18476
|
+
}
|
|
18477
|
+
var MAX_PAGES;
|
|
18478
|
+
var init_client = __esm({
|
|
18479
|
+
"src/data/client.ts"() {
|
|
18480
|
+
"use strict";
|
|
18481
|
+
init_auth();
|
|
18482
|
+
init_api_client();
|
|
18483
|
+
init_repo_config();
|
|
18484
|
+
init_utils();
|
|
18485
|
+
init_expected();
|
|
18486
|
+
init_org_context();
|
|
18487
|
+
MAX_PAGES = 1e3;
|
|
18488
|
+
}
|
|
18489
|
+
});
|
|
18490
|
+
|
|
18491
|
+
// src/lib/base-binding.ts
|
|
18492
|
+
var binding2, getBaseBindingPath, readBaseBinding, writeBaseBinding, clearBaseBinding, autoBindBaseIfUnbound, assertBaseMatchesBinding, assertNoBindingBlocksBaseCreation;
|
|
18493
|
+
var init_base_binding = __esm({
|
|
18494
|
+
"src/lib/base-binding.ts"() {
|
|
18495
|
+
"use strict";
|
|
18496
|
+
init_base_id();
|
|
18497
|
+
init_worktree_binding();
|
|
18498
|
+
binding2 = createWorktreeBinding({
|
|
18499
|
+
filename: "wayai-base-binding",
|
|
18500
|
+
isValidId: isValidBaseId,
|
|
18501
|
+
noun: "base",
|
|
18502
|
+
idLabel: "base id (must be a slug)",
|
|
18503
|
+
unbindCommand: "wayai bases unbind",
|
|
18504
|
+
useCommand: "wayai bases use"
|
|
18505
|
+
});
|
|
18506
|
+
getBaseBindingPath = binding2.getBindingPath;
|
|
18507
|
+
readBaseBinding = binding2.readBinding;
|
|
18508
|
+
writeBaseBinding = binding2.writeBinding;
|
|
18509
|
+
clearBaseBinding = binding2.clearBinding;
|
|
18510
|
+
autoBindBaseIfUnbound = binding2.autoBindIfUnbound;
|
|
18511
|
+
assertBaseMatchesBinding = binding2.assertMatchesBinding;
|
|
18512
|
+
assertNoBindingBlocksBaseCreation = binding2.assertNoBindingBlocksCreation;
|
|
18513
|
+
}
|
|
18514
|
+
});
|
|
18515
|
+
|
|
18516
|
+
// src/data/helpers.ts
|
|
18517
|
+
import { readFileSync as readFileSync16 } from "fs";
|
|
18518
|
+
function pathSegment(id, label = "id") {
|
|
18519
|
+
if (!isValidBaseId(id)) {
|
|
18520
|
+
throw expected(
|
|
18521
|
+
`Invalid ${label}: ${JSON.stringify(id)}. Ids are slugs \u2014 letters, digits, dot, dash and underscore only.`
|
|
18522
|
+
);
|
|
18523
|
+
}
|
|
18524
|
+
return encodeURIComponent(id);
|
|
18525
|
+
}
|
|
18526
|
+
function foreignSegment(value, label = "id") {
|
|
18527
|
+
if (value === "." || value === "..") {
|
|
18528
|
+
throw expected(`Invalid ${label}: ${JSON.stringify(value)} is a path traversal segment.`);
|
|
18529
|
+
}
|
|
18530
|
+
return encodeURIComponent(value);
|
|
18531
|
+
}
|
|
18532
|
+
function pathSegments(value, label = "path") {
|
|
18533
|
+
return value.split("/").map((segment) => foreignSegment(segment, label)).join("/");
|
|
18534
|
+
}
|
|
18535
|
+
function parseData(data, flag) {
|
|
18536
|
+
const prefix = flag ? `${flag}: ` : "";
|
|
18537
|
+
const source = data.startsWith("@") ? data.slice(1) : void 0;
|
|
18538
|
+
let text = data;
|
|
18539
|
+
if (source !== void 0) {
|
|
18540
|
+
try {
|
|
18541
|
+
text = readFileSync16(source, "utf-8");
|
|
18542
|
+
} catch (e) {
|
|
18543
|
+
throw expected(`${prefix}${source}: ${e instanceof Error ? e.message : "could not be read"}`);
|
|
18544
|
+
}
|
|
18545
|
+
}
|
|
18546
|
+
try {
|
|
18547
|
+
return JSON.parse(text);
|
|
18548
|
+
} catch (e) {
|
|
18549
|
+
const where = source !== void 0 ? ` in ${source}` : "";
|
|
18550
|
+
throw expected(`${prefix}invalid JSON${where}: ${e instanceof Error ? e.message : String(e)}`);
|
|
18551
|
+
}
|
|
18552
|
+
}
|
|
18553
|
+
function toolsetMcpUrl(slug) {
|
|
18554
|
+
return `https://data-mcp.wayai.pro/t/${slug}/mcp`;
|
|
18555
|
+
}
|
|
18556
|
+
function globals(cmd) {
|
|
18557
|
+
let namespace = cmd;
|
|
18558
|
+
while (namespace.parent?.parent) namespace = namespace.parent;
|
|
18559
|
+
return namespace.opts();
|
|
18560
|
+
}
|
|
18561
|
+
function withBaseOption(command2) {
|
|
18562
|
+
return command2.option("--base <id>", "Base id (or set WAYAI_BASE)");
|
|
18563
|
+
}
|
|
18564
|
+
function baseOptionHolder(cmd) {
|
|
18565
|
+
for (let c = cmd; c; c = c.parent ?? void 0) {
|
|
18566
|
+
if (c.options.some((o) => o.long === "--base")) return c;
|
|
18567
|
+
}
|
|
18568
|
+
return void 0;
|
|
18569
|
+
}
|
|
18570
|
+
function findBase(cmd) {
|
|
18571
|
+
return baseOptionHolder(cmd)?.opts()?.base;
|
|
18572
|
+
}
|
|
18573
|
+
function requireBase(cmd) {
|
|
18574
|
+
const base = findBase(cmd) ?? process.env.WAYAI_BASE ?? "";
|
|
18575
|
+
if (base) return base;
|
|
18576
|
+
console.error("Error: --base is required (or set WAYAI_BASE)");
|
|
18577
|
+
return process.exit(1);
|
|
18578
|
+
}
|
|
18579
|
+
function outputFormat(cmd) {
|
|
18580
|
+
const opts = globals(cmd);
|
|
18581
|
+
return opts.json || opts.output === "json" ? "json" : "table";
|
|
18582
|
+
}
|
|
18583
|
+
function historyQuery(opts) {
|
|
18584
|
+
const qs = new URLSearchParams();
|
|
18585
|
+
if (opts.limit) qs.set("limit", opts.limit);
|
|
18586
|
+
if (opts.offset) qs.set("offset", opts.offset);
|
|
18587
|
+
if (opts.diff) qs.set("diff", "true");
|
|
18588
|
+
const q = qs.toString();
|
|
18589
|
+
return q ? `?${q}` : "";
|
|
18590
|
+
}
|
|
18591
|
+
function splitList(value) {
|
|
18592
|
+
return value.split(",").map((v) => v.trim()).filter((v) => v.length > 0);
|
|
18593
|
+
}
|
|
18594
|
+
function parseByteCount(flag, value) {
|
|
18595
|
+
const n = Number(value);
|
|
18596
|
+
if (!Number.isInteger(n) || n < 0) {
|
|
18597
|
+
throw expected(`${flag} must be a whole number of bytes (0 = unlimited), not ${JSON.stringify(value)}.`);
|
|
18598
|
+
}
|
|
18599
|
+
return n;
|
|
18600
|
+
}
|
|
18601
|
+
async function readSecret(source, label) {
|
|
18602
|
+
const value = resolveSecretSource(source) === "stdin" ? (await readStdin()).trim() : (await promptSecret(`${label}: `)).trim();
|
|
18603
|
+
if (!value) throw expected(`${label} is required.`);
|
|
18604
|
+
return value;
|
|
18605
|
+
}
|
|
18606
|
+
function isInteractive() {
|
|
18607
|
+
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
18608
|
+
}
|
|
18609
|
+
function parseDuration(input, flag = "duration") {
|
|
18610
|
+
const match = DURATION_RE.exec(input.trim());
|
|
18611
|
+
const value = Number(match?.[1] ?? 0);
|
|
18612
|
+
const unit = match?.[2];
|
|
18613
|
+
const unitMs = unit ? DURATION_UNIT_MS[unit] : void 0;
|
|
18614
|
+
if (!unitMs || value <= 0) {
|
|
18615
|
+
throw expected(
|
|
18616
|
+
`Invalid ${flag} ${JSON.stringify(input)} \u2014 use <number><unit> with unit s/m/h/d (e.g. 10m, 2h, 30d).`
|
|
18617
|
+
);
|
|
18618
|
+
}
|
|
18619
|
+
return value * unitMs;
|
|
18620
|
+
}
|
|
18621
|
+
var DURATION_RE, DURATION_UNIT_MS;
|
|
18622
|
+
var init_helpers = __esm({
|
|
18623
|
+
"src/data/helpers.ts"() {
|
|
18624
|
+
"use strict";
|
|
18625
|
+
init_base_id();
|
|
18626
|
+
init_expected();
|
|
18627
|
+
init_utils();
|
|
18628
|
+
DURATION_RE = /^(\d+)([smhd])$/;
|
|
18629
|
+
DURATION_UNIT_MS = {
|
|
18630
|
+
s: 1e3,
|
|
18631
|
+
m: 6e4,
|
|
18632
|
+
h: 36e5,
|
|
18633
|
+
d: 864e5
|
|
18634
|
+
};
|
|
18635
|
+
}
|
|
18636
|
+
});
|
|
18637
|
+
|
|
18638
|
+
// src/data/config-as-code/types.ts
|
|
18639
|
+
var ENTITY_KINDS, ENTITY_DIRS, DEPRECATED_ENTITY_DIRS;
|
|
18640
|
+
var init_types2 = __esm({
|
|
18641
|
+
"src/data/config-as-code/types.ts"() {
|
|
18642
|
+
"use strict";
|
|
18643
|
+
ENTITY_KINDS = [
|
|
18644
|
+
"record_types",
|
|
18645
|
+
"relationship_types",
|
|
18646
|
+
"inbound_webhooks",
|
|
18647
|
+
"triggers",
|
|
18648
|
+
"toolsets",
|
|
18649
|
+
"actions",
|
|
18650
|
+
"seeds"
|
|
18651
|
+
];
|
|
18652
|
+
ENTITY_DIRS = {
|
|
18653
|
+
record_types: "record-types",
|
|
18654
|
+
relationship_types: "relationship-types",
|
|
18655
|
+
inbound_webhooks: "inbound-webhooks",
|
|
18656
|
+
triggers: "triggers",
|
|
18657
|
+
toolsets: "toolsets",
|
|
18658
|
+
actions: "actions",
|
|
18659
|
+
seeds: "seeds"
|
|
18660
|
+
};
|
|
18661
|
+
DEPRECATED_ENTITY_DIRS = ["endpoints", "collections", "tools"];
|
|
18662
|
+
}
|
|
18663
|
+
});
|
|
18664
|
+
|
|
18665
|
+
// src/data/config-as-code/config-writer.ts
|
|
18666
|
+
import * as fs16 from "fs";
|
|
18667
|
+
import * as path19 from "path";
|
|
18668
|
+
import * as yaml8 from "js-yaml";
|
|
18669
|
+
function dump4(value) {
|
|
18670
|
+
return yaml8.dump(value, YAML_DUMP_OPTIONS);
|
|
18671
|
+
}
|
|
18672
|
+
function omitUndefined(obj) {
|
|
18673
|
+
const out = {};
|
|
18674
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
18675
|
+
if (v !== void 0) out[k] = v;
|
|
18676
|
+
}
|
|
18677
|
+
return out;
|
|
18678
|
+
}
|
|
18679
|
+
function stripRecordTypeSources(sources) {
|
|
18680
|
+
if (!Array.isArray(sources)) return void 0;
|
|
18681
|
+
return sources.map((raw) => {
|
|
18682
|
+
const source = raw;
|
|
18683
|
+
const auth = source.auth;
|
|
18684
|
+
if (!auth) return source;
|
|
18685
|
+
const { secret: _secret, ...restAuth } = auth;
|
|
18686
|
+
return { ...source, auth: restAuth };
|
|
18687
|
+
});
|
|
18688
|
+
}
|
|
18689
|
+
function toFileObject(kind, entity) {
|
|
18690
|
+
const out = {};
|
|
18691
|
+
for (const key of ENTITY_FIELD_ORDER[kind]) {
|
|
18692
|
+
const value = kind === "record_types" && key === "sources" ? stripRecordTypeSources(entity.sources) : entity[key];
|
|
18693
|
+
if (value !== void 0) out[key] = value;
|
|
18694
|
+
}
|
|
18695
|
+
return out;
|
|
18696
|
+
}
|
|
18697
|
+
function pruneOrphans(folder, dir, keep, log) {
|
|
18698
|
+
if (!ensureRealSubdirNoSymlink(folder, dir, false)) return;
|
|
18699
|
+
let entries;
|
|
18700
|
+
try {
|
|
18701
|
+
entries = fs16.readdirSync(dir);
|
|
18702
|
+
} catch {
|
|
18703
|
+
return;
|
|
18704
|
+
}
|
|
18705
|
+
for (const file of entries) {
|
|
18706
|
+
if (!file.endsWith(".yaml") || keep.has(file)) continue;
|
|
18707
|
+
const abs = path19.join(dir, file);
|
|
18708
|
+
fs16.rmSync(abs);
|
|
18709
|
+
log.removed.push(path19.relative(folder, abs));
|
|
18710
|
+
}
|
|
18711
|
+
}
|
|
18712
|
+
function metaFileObject(meta) {
|
|
18713
|
+
const out = {};
|
|
18714
|
+
for (const key of META_ORDER) {
|
|
18715
|
+
if (meta[key] !== void 0) out[key] = meta[key];
|
|
18716
|
+
}
|
|
18717
|
+
return out;
|
|
18718
|
+
}
|
|
18719
|
+
function writeBaseFolder(folder, meta, config) {
|
|
18720
|
+
const delta = { changed: [], removed: [] };
|
|
18721
|
+
const parent = path19.dirname(folder);
|
|
18722
|
+
fs16.mkdirSync(parent, { recursive: true });
|
|
18723
|
+
if (!ensureRealSubdirNoSymlink(parent, folder, true)) {
|
|
18724
|
+
throw expected(
|
|
18725
|
+
`Refusing to write ${folder}: the path crosses a symlink. Remove it and pull again.`
|
|
18726
|
+
);
|
|
18727
|
+
}
|
|
18728
|
+
writeFileIfChanged(folder, path19.join(folder, BASE_META_FILE), dump4(metaFileObject(meta)), delta);
|
|
18729
|
+
for (const kind of ENTITY_KINDS) {
|
|
18730
|
+
const dir = path19.join(folder, ENTITY_DIRS[kind]);
|
|
18731
|
+
const entities = config[kind] ?? [];
|
|
18732
|
+
const keep = /* @__PURE__ */ new Set();
|
|
18733
|
+
for (const raw of entities) {
|
|
18734
|
+
const entity = raw;
|
|
18735
|
+
const id = String(entity.id);
|
|
18736
|
+
if (!isValidBaseId(id)) {
|
|
18737
|
+
console.warn(` Warning: skipping ${kind} entity with unusable id ${JSON.stringify(id)}.`);
|
|
18738
|
+
continue;
|
|
18739
|
+
}
|
|
18740
|
+
const file = `${id}.yaml`;
|
|
18741
|
+
keep.add(file);
|
|
18742
|
+
writeFileIfChanged(folder, path19.join(dir, file), dump4(toFileObject(kind, entity)), delta);
|
|
18743
|
+
}
|
|
18744
|
+
pruneOrphans(folder, dir, keep, delta);
|
|
18745
|
+
}
|
|
18746
|
+
for (const deprecated of DEPRECATED_ENTITY_DIRS) {
|
|
18747
|
+
const dir = path19.join(folder, deprecated);
|
|
18748
|
+
if (ensureRealSubdirNoSymlink(folder, dir, false)) {
|
|
18749
|
+
fs16.rmSync(dir, { recursive: true, force: true });
|
|
18750
|
+
}
|
|
18751
|
+
}
|
|
18752
|
+
return delta;
|
|
18753
|
+
}
|
|
18754
|
+
function markProductionMirror(folder, baseId) {
|
|
18755
|
+
const file = path19.join(folder, BASE_META_FILE);
|
|
18756
|
+
try {
|
|
18757
|
+
const body = readFileNoFollow(folder, file)?.toString("utf-8");
|
|
18758
|
+
if (body === void 0 || body.startsWith(MIRROR_MARKER_PREFIX)) return;
|
|
18759
|
+
const banner = `${MIRROR_MARKER_PREFIX} "${baseId}". Edits are ignored; \`wayai push\` refuses it. Edit the linked preview instead.
|
|
18760
|
+
`;
|
|
18761
|
+
writeFileNoFollow(folder, file, Buffer.from(banner + body, "utf-8"));
|
|
18762
|
+
} catch {
|
|
18763
|
+
}
|
|
18764
|
+
}
|
|
18765
|
+
function ensureMirrorIgnored(folder) {
|
|
18766
|
+
try {
|
|
18767
|
+
writeFileNoFollow(folder, path19.join(folder, ".gitignore"), Buffer.from(MIRROR_GITIGNORE, "utf-8"));
|
|
18768
|
+
} catch {
|
|
18769
|
+
}
|
|
18770
|
+
}
|
|
18771
|
+
var ENTITY_FIELD_ORDER, META_ORDER, MIRROR_MARKER_PREFIX, MIRROR_GITIGNORE;
|
|
18772
|
+
var init_config_writer = __esm({
|
|
18773
|
+
"src/data/config-as-code/config-writer.ts"() {
|
|
18774
|
+
"use strict";
|
|
18775
|
+
init_expected();
|
|
18776
|
+
init_yaml_writer();
|
|
18777
|
+
init_fs_safety();
|
|
18778
|
+
init_base_workspace();
|
|
18779
|
+
init_base_id();
|
|
18780
|
+
init_types2();
|
|
18781
|
+
ENTITY_FIELD_ORDER = {
|
|
18782
|
+
record_types: ["id", "name", "description", "icon", "color", "json_schema", "ui", "sources"],
|
|
18783
|
+
relationship_types: [
|
|
18784
|
+
"id",
|
|
18785
|
+
"description",
|
|
18786
|
+
"data_schema",
|
|
18787
|
+
"source_record_types",
|
|
18788
|
+
"target_record_types",
|
|
18789
|
+
"cascade"
|
|
18790
|
+
],
|
|
18791
|
+
inbound_webhooks: [
|
|
18792
|
+
"id",
|
|
18793
|
+
"name",
|
|
18794
|
+
"record_type_scope",
|
|
18795
|
+
"field_mapping",
|
|
18796
|
+
"source_binding",
|
|
18797
|
+
"ingest_auth",
|
|
18798
|
+
"hydration",
|
|
18799
|
+
"enabled"
|
|
18800
|
+
],
|
|
18801
|
+
triggers: [
|
|
18802
|
+
"id",
|
|
18803
|
+
"name",
|
|
18804
|
+
"action",
|
|
18805
|
+
"url",
|
|
18806
|
+
"events",
|
|
18807
|
+
"record_type_scope",
|
|
18808
|
+
"filter",
|
|
18809
|
+
"skip_inbound_webhook_writes",
|
|
18810
|
+
"skip_cascade_writes",
|
|
18811
|
+
"enabled"
|
|
18812
|
+
],
|
|
18813
|
+
toolsets: ["id", "name", "description", "actions", "relationships", "batch", "sql_query"],
|
|
18814
|
+
actions: [
|
|
18815
|
+
"id",
|
|
18816
|
+
"record_type",
|
|
18817
|
+
"operation",
|
|
18818
|
+
"steps",
|
|
18819
|
+
"description",
|
|
18820
|
+
"external_source",
|
|
18821
|
+
"writable_fields",
|
|
18822
|
+
"precondition",
|
|
18823
|
+
"binding",
|
|
18824
|
+
"filterable_fields",
|
|
18825
|
+
"expose_filter",
|
|
18826
|
+
"expose_sort",
|
|
18827
|
+
"default_sort",
|
|
18828
|
+
"expose_limit",
|
|
18829
|
+
"default_limit",
|
|
18830
|
+
"expose_offset",
|
|
18831
|
+
"expose_fields",
|
|
18832
|
+
"default_fields",
|
|
18833
|
+
"agent_minimal",
|
|
18834
|
+
"base_filter"
|
|
18835
|
+
],
|
|
18836
|
+
seeds: ["id", "description", "records", "relationships", "exclusive_record_types"]
|
|
18837
|
+
};
|
|
18838
|
+
META_ORDER = [
|
|
18839
|
+
"base_id",
|
|
18840
|
+
"origin_base_id",
|
|
18841
|
+
"name",
|
|
18842
|
+
"description",
|
|
18843
|
+
"environment",
|
|
18844
|
+
"integrations",
|
|
18845
|
+
"analytics"
|
|
18846
|
+
];
|
|
18847
|
+
MIRROR_MARKER_PREFIX = "# Read-only mirror of production base";
|
|
18848
|
+
MIRROR_GITIGNORE = "*\n";
|
|
18849
|
+
}
|
|
18850
|
+
});
|
|
18851
|
+
|
|
18852
|
+
// src/data/config-as-code/api.ts
|
|
18853
|
+
function metaFromRecord(record, fallbackId) {
|
|
18854
|
+
return omitUndefined({
|
|
18855
|
+
base_id: record.id ?? fallbackId,
|
|
18856
|
+
origin_base_id: record.origin_base_id ?? void 0,
|
|
18857
|
+
name: record.name,
|
|
18858
|
+
description: record.description,
|
|
18859
|
+
environment: record.environment,
|
|
18860
|
+
integrations: record.integrations,
|
|
18861
|
+
analytics: record.analytics
|
|
18862
|
+
});
|
|
18863
|
+
}
|
|
18864
|
+
function getBaseRecord(client, id) {
|
|
18865
|
+
return client.request("GET", `/v1/bases/${pathSegment(id, "base id")}`);
|
|
18866
|
+
}
|
|
18867
|
+
function getConfig(client, id) {
|
|
18868
|
+
return client.request("GET", `/v1/${pathSegment(id, "base id")}/config`);
|
|
18869
|
+
}
|
|
18870
|
+
function diffConfig(client, id, local) {
|
|
18871
|
+
return client.request("POST", `/v1/${pathSegment(id, "base id")}/config/diff`, local);
|
|
18872
|
+
}
|
|
18873
|
+
function applyConfig(client, id, local) {
|
|
18874
|
+
return client.request("PUT", `/v1/${pathSegment(id, "base id")}/config`, local);
|
|
18875
|
+
}
|
|
18876
|
+
function createPreview(client, originId, opts) {
|
|
18877
|
+
return client.requestRaw("POST", `/v1/${pathSegment(originId, "origin base id")}/preview`, {
|
|
18878
|
+
name: opts.name,
|
|
18879
|
+
...opts.description ? { description: opts.description } : {},
|
|
18880
|
+
// The tier is create-only, so this call is the ONLY chance to honor a tier
|
|
18881
|
+
// the folder declares. Omitted when absent so the clone default applies.
|
|
18882
|
+
...opts.analytics ? { analytics: opts.analytics } : {}
|
|
18883
|
+
});
|
|
18884
|
+
}
|
|
18885
|
+
function deleteEntity(client, baseId, kind, id) {
|
|
18886
|
+
return client.request(
|
|
18887
|
+
"DELETE",
|
|
18888
|
+
`/v1/${pathSegment(baseId, "base id")}/${ENTITY_DIRS[kind]}/${pathSegment(id, `${kind} id`)}`
|
|
18889
|
+
);
|
|
18890
|
+
}
|
|
18891
|
+
var init_api = __esm({
|
|
18892
|
+
"src/data/config-as-code/api.ts"() {
|
|
18893
|
+
"use strict";
|
|
18894
|
+
init_helpers();
|
|
18895
|
+
init_config_writer();
|
|
18896
|
+
init_types2();
|
|
18897
|
+
}
|
|
18898
|
+
});
|
|
18899
|
+
|
|
18900
|
+
// src/data/config-as-code/config-parser.ts
|
|
18901
|
+
import * as fs17 from "fs";
|
|
18902
|
+
import * as path20 from "path";
|
|
18903
|
+
import * as yaml9 from "js-yaml";
|
|
18904
|
+
function readEntityDir(folder, dir) {
|
|
18905
|
+
if (!ensureRealSubdirNoSymlink(folder, dir, false)) {
|
|
18906
|
+
throw expected(`Refusing to read ${dir}: it is a symlink, not a config directory.`);
|
|
18907
|
+
}
|
|
18908
|
+
if (!isDirectory(dir)) return [];
|
|
18909
|
+
const out = [];
|
|
18910
|
+
for (const file of fs17.readdirSync(dir).sort()) {
|
|
18911
|
+
if (!file.endsWith(".yaml")) continue;
|
|
18912
|
+
const abs = path20.join(dir, file);
|
|
18913
|
+
const bytes = readFileNoFollow(folder, abs);
|
|
18914
|
+
if (bytes === null) {
|
|
18915
|
+
throw expected(`Refusing to read ${abs}: it is a symlink, not a config file.`);
|
|
18916
|
+
}
|
|
18917
|
+
let parsed;
|
|
18918
|
+
try {
|
|
18919
|
+
parsed = yaml9.load(bytes.toString("utf-8"));
|
|
18920
|
+
} catch (err) {
|
|
18921
|
+
throw expected(`Failed to parse ${abs}: ${err instanceof Error ? err.message : String(err)}`);
|
|
18922
|
+
}
|
|
18923
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
18924
|
+
throw expected(`${abs} is empty or not a YAML object`);
|
|
18925
|
+
}
|
|
18926
|
+
const entity = parsed;
|
|
18927
|
+
const stem = path20.basename(file, ".yaml");
|
|
18928
|
+
if (entity.id === void 0) entity.id = stem;
|
|
18929
|
+
else if (String(entity.id) !== stem) {
|
|
18930
|
+
throw expected(`${abs}: id "${String(entity.id)}" does not match filename "${stem}.yaml"`);
|
|
18931
|
+
}
|
|
18932
|
+
out.push(entity);
|
|
18933
|
+
}
|
|
18934
|
+
return out;
|
|
18935
|
+
}
|
|
18936
|
+
function parseBaseFolder(folder) {
|
|
18937
|
+
const meta = readBaseMeta(folder);
|
|
18938
|
+
if (!meta) {
|
|
18939
|
+
throw expected(
|
|
18940
|
+
hasBaseMetaFile(folder) ? `${path20.join(folder, BASE_META_FILE)} could not be parsed as a YAML mapping. Fix it, or delete it and pull again.` : `No ${BASE_META_FILE} found in ${folder}`
|
|
18941
|
+
);
|
|
18942
|
+
}
|
|
18943
|
+
const read = (kind) => readEntityDir(folder, path20.join(folder, ENTITY_DIRS[kind]));
|
|
18944
|
+
const config = {
|
|
18945
|
+
record_types: read("record_types"),
|
|
18946
|
+
relationship_types: read("relationship_types"),
|
|
18947
|
+
inbound_webhooks: read("inbound_webhooks"),
|
|
18948
|
+
triggers: read("triggers"),
|
|
18949
|
+
toolsets: read("toolsets"),
|
|
18950
|
+
actions: read("actions"),
|
|
18951
|
+
seeds: read("seeds")
|
|
18952
|
+
};
|
|
18953
|
+
return { meta, config };
|
|
18954
|
+
}
|
|
18955
|
+
var init_config_parser = __esm({
|
|
18956
|
+
"src/data/config-as-code/config-parser.ts"() {
|
|
18957
|
+
"use strict";
|
|
18958
|
+
init_expected();
|
|
18959
|
+
init_layout();
|
|
18960
|
+
init_fs_safety();
|
|
18961
|
+
init_base_workspace();
|
|
18962
|
+
init_types2();
|
|
18963
|
+
}
|
|
18964
|
+
});
|
|
18965
|
+
|
|
18966
|
+
// src/data/config-as-code/diff-format.ts
|
|
18967
|
+
function bucket(diff, kind) {
|
|
18968
|
+
return diff[kind];
|
|
18969
|
+
}
|
|
18970
|
+
function isEmptyBucket(b) {
|
|
18971
|
+
return !b || b.added.length === 0 && b.modified.length === 0 && b.removed.length === 0;
|
|
18972
|
+
}
|
|
18973
|
+
function isDiffEmpty(diff) {
|
|
18974
|
+
return ENTITY_KINDS.every((kind) => isEmptyBucket(bucket(diff, kind)));
|
|
18975
|
+
}
|
|
18976
|
+
function collectRemovals(diff) {
|
|
18977
|
+
const out = [];
|
|
18978
|
+
for (const kind of ENTITY_KINDS) {
|
|
18979
|
+
for (const entity of bucket(diff, kind)?.removed ?? []) out.push({ kind, id: entity.id });
|
|
18980
|
+
}
|
|
18981
|
+
return out;
|
|
18982
|
+
}
|
|
18983
|
+
function countChanges(diff) {
|
|
18984
|
+
let added = 0;
|
|
18985
|
+
let modified = 0;
|
|
18986
|
+
let removed = 0;
|
|
18987
|
+
for (const kind of ENTITY_KINDS) {
|
|
18988
|
+
const b = bucket(diff, kind);
|
|
18989
|
+
if (!b) continue;
|
|
18990
|
+
added += b.added.length;
|
|
18991
|
+
modified += b.modified.length;
|
|
18992
|
+
removed += b.removed.length;
|
|
18993
|
+
}
|
|
18994
|
+
return { added, modified, removed };
|
|
18995
|
+
}
|
|
18996
|
+
function renderDiff(diff) {
|
|
18997
|
+
const lines = [];
|
|
18998
|
+
for (const kind of ENTITY_KINDS) {
|
|
18999
|
+
const b = bucket(diff, kind);
|
|
19000
|
+
if (!b || isEmptyBucket(b)) continue;
|
|
19001
|
+
lines.push(`${BOLD}${LABELS[kind]}s${RESET}`);
|
|
19002
|
+
for (const e of b.added) lines.push(`${GREEN} + ${sanitizeTerminalText(e.id)}${RESET}`);
|
|
19003
|
+
for (const m of b.modified) lines.push(`${YELLOW} ~ ${sanitizeTerminalText(m.after.id)}${RESET}`);
|
|
19004
|
+
for (const e of b.removed) lines.push(`${RED} - ${sanitizeTerminalText(e.id)}${RESET}`);
|
|
19005
|
+
}
|
|
19006
|
+
const { added, modified, removed } = countChanges(diff);
|
|
19007
|
+
lines.push("");
|
|
19008
|
+
lines.push(
|
|
19009
|
+
`${GREEN}${added} added${RESET}, ${YELLOW}${modified} modified${RESET}, ${RED}${removed} removed${RESET}`
|
|
19010
|
+
);
|
|
19011
|
+
if (removed > 0) {
|
|
19012
|
+
lines.push(
|
|
19013
|
+
`${RED} ${removed} entit${removed === 1 ? "y" : "ies"} exist on the base but not in your files \u2014 re-run with --prune to delete (record types cascade to their records).${RESET}`
|
|
19014
|
+
);
|
|
19015
|
+
}
|
|
19016
|
+
return lines.join("\n");
|
|
19017
|
+
}
|
|
19018
|
+
var LABELS, GREEN, YELLOW, RED, BOLD, RESET;
|
|
19019
|
+
var init_diff_format = __esm({
|
|
19020
|
+
"src/data/config-as-code/diff-format.ts"() {
|
|
19021
|
+
"use strict";
|
|
19022
|
+
init_terminal_output();
|
|
19023
|
+
init_types2();
|
|
19024
|
+
LABELS = {
|
|
19025
|
+
record_types: "record type",
|
|
19026
|
+
relationship_types: "relationship type",
|
|
19027
|
+
inbound_webhooks: "inbound webhook",
|
|
19028
|
+
triggers: "trigger",
|
|
19029
|
+
toolsets: "toolset",
|
|
19030
|
+
actions: "action",
|
|
19031
|
+
seeds: "seed"
|
|
19032
|
+
};
|
|
19033
|
+
GREEN = "\x1B[32m";
|
|
19034
|
+
YELLOW = "\x1B[33m";
|
|
19035
|
+
RED = "\x1B[31m";
|
|
19036
|
+
BOLD = "\x1B[1m";
|
|
19037
|
+
RESET = "\x1B[0m";
|
|
19038
|
+
}
|
|
19039
|
+
});
|
|
19040
|
+
|
|
19041
|
+
// src/data/config-as-code/sync.ts
|
|
19042
|
+
var sync_exports = {};
|
|
19043
|
+
__export(sync_exports, {
|
|
19044
|
+
pullBase: () => pullBase,
|
|
19045
|
+
pushBase: () => pushBase
|
|
19046
|
+
});
|
|
19047
|
+
import * as path21 from "path";
|
|
19048
|
+
function parseArgs4(args2) {
|
|
19049
|
+
return {
|
|
19050
|
+
autoConfirm: args2.includes("--yes") || args2.includes("-y"),
|
|
19051
|
+
dryRun: args2.includes("--dry-run"),
|
|
19052
|
+
prune: args2.includes("--prune")
|
|
19053
|
+
};
|
|
19054
|
+
}
|
|
19055
|
+
function requireGitRoot(gitRoot) {
|
|
19056
|
+
if (!gitRoot) throw expected("Not inside a git repository.");
|
|
19057
|
+
return gitRoot;
|
|
19058
|
+
}
|
|
19059
|
+
async function writeProductionMirror(client, basesDir, prodId, record) {
|
|
19060
|
+
if (!isValidBaseId(prodId)) {
|
|
19061
|
+
throw expected(`Refusing to mirror base ${JSON.stringify(prodId)}: not a usable base id.`);
|
|
19062
|
+
}
|
|
19063
|
+
const config = await getConfig(client, prodId);
|
|
19064
|
+
const folder = path21.join(basesDir, prodId);
|
|
19065
|
+
writeBaseFolder(folder, { ...metaFromRecord(record, prodId), environment: "production" }, config);
|
|
19066
|
+
markProductionMirror(folder, prodId);
|
|
19067
|
+
ensureMirrorIgnored(folder);
|
|
19068
|
+
return folder;
|
|
19069
|
+
}
|
|
19070
|
+
async function mirrorLinkedProduction(client, basesDir, originId) {
|
|
19071
|
+
try {
|
|
19072
|
+
const record = await getBaseRecord(client, originId);
|
|
19073
|
+
if (record.environment !== "production") return;
|
|
19074
|
+
const folder = await writeProductionMirror(client, basesDir, originId, record);
|
|
19075
|
+
console.log(`Mirrored production base \u2192 ${folder} (read-only, git-ignored)`);
|
|
19076
|
+
} catch (err) {
|
|
19077
|
+
console.warn(
|
|
19078
|
+
`Warning: could not mirror the production base (${err instanceof Error ? err.message : String(err)}). The preview pull is unaffected.`
|
|
19079
|
+
);
|
|
19080
|
+
}
|
|
19081
|
+
}
|
|
19082
|
+
async function pullBase(gitRootOrNull, selector, args2) {
|
|
19083
|
+
const { autoConfirm } = parseArgs4(args2);
|
|
19084
|
+
const gitRoot = requireGitRoot(gitRootOrNull);
|
|
19085
|
+
const target = resolveBaseTarget(gitRoot, selector);
|
|
19086
|
+
const basesDir = resolveBasesDir(gitRoot);
|
|
19087
|
+
const baseId = targetBaseId(target, selector);
|
|
19088
|
+
if (!baseId) {
|
|
19089
|
+
throw expected(
|
|
19090
|
+
`Could not determine the base id for ${target.folder}. Pass the base id explicitly.`
|
|
19091
|
+
);
|
|
19092
|
+
}
|
|
19093
|
+
const client = await createDataClient();
|
|
19094
|
+
console.log("Fetching base configuration...");
|
|
19095
|
+
const record = await getBaseRecord(client, baseId);
|
|
19096
|
+
if (record.environment === "production") {
|
|
19097
|
+
const folder = await writeProductionMirror(client, basesDir, record.id ?? baseId, record);
|
|
19098
|
+
console.log(`Production base mirrored (read-only) \u2192 ${folder}`);
|
|
19099
|
+
return;
|
|
19100
|
+
}
|
|
19101
|
+
assertBaseMatchesBinding(baseId);
|
|
19102
|
+
if (target.exists && !autoConfirm) {
|
|
19103
|
+
const ok = await confirm(
|
|
19104
|
+
`Overwrite local files in ${path21.relative(gitRoot, target.folder)} with the server config for "${sanitizeTerminalText(baseId)}"?`
|
|
19105
|
+
);
|
|
19106
|
+
if (!ok) {
|
|
19107
|
+
console.log("Cancelled.");
|
|
19108
|
+
return;
|
|
19109
|
+
}
|
|
19110
|
+
}
|
|
19111
|
+
const config = await getConfig(client, baseId);
|
|
19112
|
+
const isFirstPull = !target.exists;
|
|
19113
|
+
const delta = writeBaseFolder(target.folder, metaFromRecord(record, baseId), config);
|
|
19114
|
+
console.log(`Base configuration written to ${target.folder}`);
|
|
19115
|
+
console.log(
|
|
19116
|
+
` ${ENTITY_KINDS.map((kind) => `${(config[kind] ?? []).length} ${kind}`).join(", ")}`
|
|
19117
|
+
);
|
|
19118
|
+
if (!isFirstPull) printLocalFileChanges(delta);
|
|
19119
|
+
console.log(" Secrets are not written. Manage them with `wayai bases secrets`.");
|
|
19120
|
+
autoBindBaseIfUnbound(baseId);
|
|
19121
|
+
if (record.origin_base_id) {
|
|
19122
|
+
await mirrorLinkedProduction(client, basesDir, record.origin_base_id);
|
|
19123
|
+
}
|
|
19124
|
+
}
|
|
19125
|
+
function printLintWarnings(warnings) {
|
|
19126
|
+
if (!warnings || warnings.length === 0) return;
|
|
19127
|
+
const word = warnings.length === 1 ? "suggestion" : "suggestions";
|
|
19128
|
+
console.error(`
|
|
19129
|
+
${YELLOW}Tool design \u2014 ${warnings.length} ${word} (advisory, not blocking):${RESET}`);
|
|
19130
|
+
for (const w of warnings) {
|
|
19131
|
+
console.error(
|
|
19132
|
+
` ${sanitizeTerminalText(w.action)} [${sanitizeTerminalText(w.rule)}]
|
|
19133
|
+
${sanitizeTerminalText(w.message)}`
|
|
19134
|
+
);
|
|
19135
|
+
}
|
|
19136
|
+
}
|
|
19137
|
+
async function createDeclaredPreview(client, target, parsed, autoConfirm) {
|
|
19138
|
+
const { meta, config } = parsed;
|
|
19139
|
+
if (!meta.origin_base_id) {
|
|
19140
|
+
throw expected(
|
|
19141
|
+
"base.yaml needs a base_id (an existing preview) or an origin_base_id (to create one)."
|
|
19142
|
+
);
|
|
19143
|
+
}
|
|
19144
|
+
const name = meta.name ?? path21.basename(target.folder);
|
|
19145
|
+
assertNoBindingBlocksBaseCreation(name);
|
|
19146
|
+
if (!autoConfirm) {
|
|
19147
|
+
const ok = await confirm(
|
|
19148
|
+
`Create a new preview "${sanitizeTerminalText(name)}" from "${sanitizeTerminalText(meta.origin_base_id)}"?`
|
|
19149
|
+
);
|
|
19150
|
+
if (!ok) {
|
|
19151
|
+
console.log("Cancelled.");
|
|
19152
|
+
return null;
|
|
19153
|
+
}
|
|
19154
|
+
}
|
|
19155
|
+
const record = await createPreview(client, meta.origin_base_id, {
|
|
19156
|
+
name,
|
|
19157
|
+
description: meta.description,
|
|
19158
|
+
analytics: meta.analytics
|
|
19159
|
+
});
|
|
19160
|
+
const id = record.id;
|
|
19161
|
+
writeBaseFolder(target.folder, { ...meta, ...metaFromRecord(record, id) }, config);
|
|
19162
|
+
console.log(`Created preview "${sanitizeTerminalText(id)}".`);
|
|
19163
|
+
printWarnings((record.warnings ?? []).map((w) => sanitizeTerminalText(w.message)));
|
|
19164
|
+
autoBindBaseIfUnbound(id);
|
|
19165
|
+
return id;
|
|
19166
|
+
}
|
|
19167
|
+
async function pushBase(gitRootOrNull, selector, args2) {
|
|
19168
|
+
const { autoConfirm, dryRun, prune } = parseArgs4(args2);
|
|
19169
|
+
const gitRoot = requireGitRoot(gitRootOrNull);
|
|
19170
|
+
const target = resolveBaseTarget(gitRoot, selector);
|
|
19171
|
+
if (!target.exists) {
|
|
19172
|
+
throw expected(
|
|
19173
|
+
`No base.yaml in ${target.folder}. Pull an existing preview, or scaffold a folder with origin_base_id set to create one.`
|
|
19174
|
+
);
|
|
19175
|
+
}
|
|
19176
|
+
const parsed = parseBaseFolder(target.folder);
|
|
19177
|
+
const { meta, config } = parsed;
|
|
19178
|
+
if (isProductionFolder(meta)) {
|
|
19179
|
+
throw expected(
|
|
19180
|
+
`${path21.relative(gitRoot, target.folder)} is a read-only production mirror. Push operates on previews \u2014 edit the linked preview and promote with \`wayai bases promote\`.`
|
|
19181
|
+
);
|
|
19182
|
+
}
|
|
19183
|
+
if (!meta.base_id && dryRun) {
|
|
19184
|
+
console.log(
|
|
19185
|
+
`Dry run \u2014 nothing applied. ${path21.relative(gitRoot, target.folder)} has no base_id yet, so a real push would first create a preview from "${sanitizeTerminalText(meta.origin_base_id ?? "<origin_base_id>")}".`
|
|
19186
|
+
);
|
|
19187
|
+
return;
|
|
19188
|
+
}
|
|
19189
|
+
const client = await createDataClient();
|
|
19190
|
+
let baseId = meta.base_id;
|
|
19191
|
+
if (!baseId) {
|
|
19192
|
+
const created = await createDeclaredPreview(client, target, parsed, autoConfirm);
|
|
19193
|
+
if (!created) return;
|
|
19194
|
+
baseId = created;
|
|
19195
|
+
} else {
|
|
19196
|
+
const record = await getBaseRecord(client, baseId);
|
|
19197
|
+
if (record.environment && record.environment !== "preview") {
|
|
19198
|
+
throw expected(
|
|
19199
|
+
`"${sanitizeTerminalText(baseId)}" is a ${sanitizeTerminalText(record.environment)} base. Push operates on previews \u2014 promote with \`wayai bases promote\`.`
|
|
19200
|
+
);
|
|
19201
|
+
}
|
|
19202
|
+
assertBaseMatchesBinding(baseId);
|
|
19203
|
+
}
|
|
19204
|
+
const diff = await diffConfig(client, baseId, config);
|
|
19205
|
+
printLintWarnings(diff.warnings);
|
|
19206
|
+
if (isDiffEmpty(diff)) {
|
|
19207
|
+
console.log(`No changes \u2014 preview "${sanitizeTerminalText(baseId)}" already matches your files.`);
|
|
19208
|
+
if (!dryRun) autoBindBaseIfUnbound(baseId);
|
|
19209
|
+
return;
|
|
19210
|
+
}
|
|
19211
|
+
console.log(renderDiff(diff));
|
|
19212
|
+
if (dryRun) {
|
|
19213
|
+
console.log("\nDry run \u2014 nothing applied.");
|
|
19214
|
+
return;
|
|
19215
|
+
}
|
|
19216
|
+
if (!autoConfirm) {
|
|
19217
|
+
const ok = await confirm(`
|
|
19218
|
+
Apply these changes to preview "${sanitizeTerminalText(baseId)}"?`);
|
|
19219
|
+
if (!ok) {
|
|
19220
|
+
console.log("Cancelled.");
|
|
19221
|
+
return;
|
|
19222
|
+
}
|
|
19223
|
+
}
|
|
19224
|
+
const result = await applyConfig(client, baseId, config);
|
|
19225
|
+
const secretGroups = [
|
|
19226
|
+
["trigger", result.new_trigger_secrets],
|
|
19227
|
+
["inbound webhook", result.new_inbound_webhook_secrets]
|
|
19228
|
+
];
|
|
19229
|
+
if (secretGroups.some(([, map]) => map && Object.keys(map).length > 0)) {
|
|
19230
|
+
console.log(`
|
|
19231
|
+
${YELLOW}New secrets (shown once \u2014 save them now):${RESET}`);
|
|
19232
|
+
for (const [kind, map] of secretGroups) {
|
|
19233
|
+
for (const [id, secret] of Object.entries(map ?? {})) {
|
|
19234
|
+
console.log(` ${kind} ${sanitizeTerminalText(id)}: ${secret}`);
|
|
19235
|
+
}
|
|
19236
|
+
}
|
|
19237
|
+
}
|
|
19238
|
+
const removals = collectRemovals(diff);
|
|
19239
|
+
if (removals.length > 0) {
|
|
19240
|
+
const word = removals.length === 1 ? "entity" : "entities";
|
|
19241
|
+
if (!prune) {
|
|
19242
|
+
console.log(
|
|
19243
|
+
`
|
|
19244
|
+
${RED}${removals.length} ${word} not in your files were left on the base. Re-run with --prune to delete.${RESET}`
|
|
19245
|
+
);
|
|
19246
|
+
} else if (autoConfirm || await confirm(
|
|
19247
|
+
`
|
|
19248
|
+
Delete ${removals.length} server ${word} not in your files? Record types cascade to their records.`
|
|
19249
|
+
)) {
|
|
19250
|
+
for (const removal of removals) {
|
|
19251
|
+
await deleteEntity(client, baseId, removal.kind, removal.id);
|
|
19252
|
+
console.log(` - deleted ${removal.kind} ${sanitizeTerminalText(removal.id)}`);
|
|
19253
|
+
}
|
|
19254
|
+
} else {
|
|
19255
|
+
console.log("Skipped deletions.");
|
|
19256
|
+
}
|
|
19257
|
+
}
|
|
19258
|
+
console.log(`
|
|
19259
|
+
Pushed to preview "${sanitizeTerminalText(baseId)}".`);
|
|
19260
|
+
autoBindBaseIfUnbound(baseId);
|
|
19261
|
+
}
|
|
19262
|
+
var init_sync = __esm({
|
|
19263
|
+
"src/data/config-as-code/sync.ts"() {
|
|
19264
|
+
"use strict";
|
|
19265
|
+
init_client();
|
|
19266
|
+
init_utils();
|
|
19267
|
+
init_expected();
|
|
19268
|
+
init_layout();
|
|
19269
|
+
init_terminal_output();
|
|
19270
|
+
init_base_id();
|
|
19271
|
+
init_push();
|
|
19272
|
+
init_base_binding();
|
|
19273
|
+
init_api();
|
|
19274
|
+
init_config_parser();
|
|
19275
|
+
init_config_writer();
|
|
19276
|
+
init_diff_format();
|
|
19277
|
+
init_base_workspace();
|
|
19278
|
+
init_types2();
|
|
19279
|
+
}
|
|
19280
|
+
});
|
|
19281
|
+
|
|
19282
|
+
// src/commands/push.ts
|
|
19283
|
+
var push_exports = {};
|
|
19284
|
+
__export(push_exports, {
|
|
19285
|
+
autoRenameAgentFiles: () => autoRenameAgentFiles,
|
|
19286
|
+
createAndPushNewHub: () => createAndPushNewHub,
|
|
19287
|
+
printErrors: () => printErrors,
|
|
19288
|
+
printLocalFileChanges: () => printLocalFileChanges,
|
|
19289
|
+
printSyncResult: () => printSyncResult,
|
|
19290
|
+
printWarnings: () => printWarnings,
|
|
19291
|
+
pushCommand: () => pushCommand,
|
|
19292
|
+
reportUnresolvedPushTarget: () => reportUnresolvedPushTarget,
|
|
19293
|
+
selectExistingHub: () => selectExistingHub,
|
|
19294
|
+
shouldWarnIgnoredPreviewLabel: () => shouldWarnIgnoredPreviewLabel,
|
|
19295
|
+
syncAfterPush: () => syncAfterPush
|
|
19296
|
+
});
|
|
19297
|
+
import * as fs18 from "fs";
|
|
19298
|
+
import * as path22 from "path";
|
|
19299
|
+
import * as yaml10 from "js-yaml";
|
|
19300
|
+
function parseArgs5(args2) {
|
|
19301
|
+
let autoConfirm = false;
|
|
19302
|
+
let label;
|
|
19303
|
+
for (let i = 0; i < args2.length; i++) {
|
|
19304
|
+
const arg = args2[i];
|
|
19305
|
+
if (arg === "--yes" || arg === "-y") {
|
|
19306
|
+
autoConfirm = true;
|
|
19307
|
+
} else if (arg === "--label" && args2[i + 1]) {
|
|
19308
|
+
label = args2[++i];
|
|
19309
|
+
}
|
|
19310
|
+
}
|
|
19311
|
+
return { autoConfirm, label };
|
|
19312
|
+
}
|
|
19313
|
+
function shouldWarnIgnoredPreviewLabel(localLabel, serverLabel) {
|
|
19314
|
+
return Boolean(localLabel) && serverLabel !== void 0 && localLabel !== serverLabel;
|
|
19315
|
+
}
|
|
19316
|
+
function printSyncResult(result) {
|
|
19317
|
+
const applyErrors = result.apply_errors ?? result.errors;
|
|
19318
|
+
if (applyErrors && applyErrors.length > 0) {
|
|
19319
|
+
printErrors(applyErrors);
|
|
19320
|
+
throw expected(`Sync failed with ${applyErrors.length} error(s). No completion was reported; inspect the errors above.`);
|
|
19321
|
+
}
|
|
19322
|
+
console.log(`
|
|
19323
|
+
Sync complete. Preview hub: ${result.preview_hub_id}`);
|
|
19324
|
+
const c = result.changes;
|
|
19325
|
+
const parts = [];
|
|
19326
|
+
if (c.hub_updated) parts.push("hub updated");
|
|
19327
|
+
if (c.connections_created > 0) parts.push(`${c.connections_created} connection(s) created`);
|
|
19328
|
+
if (c.connections_updated > 0) parts.push(`${c.connections_updated} connection(s) updated`);
|
|
19329
|
+
if (c.connections_deleted > 0) parts.push(`${c.connections_deleted} connection(s) deleted`);
|
|
19330
|
+
if (c.agents_created > 0) parts.push(`${c.agents_created} agent(s) created`);
|
|
19331
|
+
if (c.agents_updated > 0) parts.push(`${c.agents_updated} agent(s) updated`);
|
|
19332
|
+
if (c.agents_deleted > 0) parts.push(`${c.agents_deleted} agent(s) deleted`);
|
|
19333
|
+
if (c.tools_created > 0) parts.push(`${c.tools_created} tool(s) created`);
|
|
19334
|
+
if (c.tools_updated > 0) parts.push(`${c.tools_updated} tool(s) updated`);
|
|
19335
|
+
if (c.tools_deleted > 0) parts.push(`${c.tools_deleted} tool(s) deleted`);
|
|
19336
|
+
if (c.states_created > 0) parts.push(`${c.states_created} state(s) created`);
|
|
19337
|
+
if (c.states_updated > 0) parts.push(`${c.states_updated} state(s) updated`);
|
|
19338
|
+
if (c.states_deleted > 0) parts.push(`${c.states_deleted} state(s) deleted`);
|
|
19339
|
+
if (c.evals_created > 0) parts.push(`${c.evals_created} eval(s) created`);
|
|
19340
|
+
if (c.evals_updated > 0) parts.push(`${c.evals_updated} eval(s) updated`);
|
|
19341
|
+
if (c.evals_deleted > 0) parts.push(`${c.evals_deleted} eval(s) deleted`);
|
|
19342
|
+
if (c.journeys_created > 0) parts.push(`${c.journeys_created} journey(s) created`);
|
|
19343
|
+
if (c.journeys_updated > 0) parts.push(`${c.journeys_updated} journey(s) updated`);
|
|
19344
|
+
if (c.journeys_deleted > 0) parts.push(`${c.journeys_deleted} journey(s) deleted`);
|
|
19345
|
+
if (c.teams_created > 0) parts.push(`${c.teams_created} team(s) created`);
|
|
19346
|
+
if (c.teams_updated > 0) parts.push(`${c.teams_updated} team(s) updated`);
|
|
19347
|
+
if (c.teams_deleted > 0) parts.push(`${c.teams_deleted} team(s) deleted`);
|
|
19348
|
+
if (c.resources_created > 0) parts.push(`${c.resources_created} resource(s) created`);
|
|
19349
|
+
if (c.resources_updated > 0) parts.push(`${c.resources_updated} resource(s) updated`);
|
|
19350
|
+
if (c.resources_deleted > 0) parts.push(`${c.resources_deleted} resource(s) deleted`);
|
|
19351
|
+
if (c.resource_files_uploaded > 0) parts.push(`${c.resource_files_uploaded} resource file(s) uploaded`);
|
|
19352
|
+
if (c.resource_files_deleted > 0) parts.push(`${c.resource_files_deleted} resource file(s) deleted`);
|
|
19353
|
+
if (c.resource_links_created > 0) parts.push(`${c.resource_links_created} resource link(s) created`);
|
|
19354
|
+
if (c.resource_links_updated > 0) parts.push(`${c.resource_links_updated} resource link(s) updated`);
|
|
19355
|
+
if (c.resource_links_deleted > 0) parts.push(`${c.resource_links_deleted} resource link(s) deleted`);
|
|
19356
|
+
if (c.outbound_contacts_created > 0) parts.push(`${c.outbound_contacts_created} outbound contact(s) created`);
|
|
19357
|
+
if (c.outbound_contacts_updated > 0) parts.push(`${c.outbound_contacts_updated} outbound contact(s) updated`);
|
|
19358
|
+
if (c.outbound_contacts_deleted > 0) parts.push(`${c.outbound_contacts_deleted} outbound contact(s) deleted`);
|
|
19359
|
+
if (c.outbound_lists_created > 0) parts.push(`${c.outbound_lists_created} outbound list(s) created`);
|
|
19360
|
+
if (c.outbound_lists_updated > 0) parts.push(`${c.outbound_lists_updated} outbound list(s) updated`);
|
|
19361
|
+
if (c.outbound_lists_deleted > 0) parts.push(`${c.outbound_lists_deleted} outbound list(s) deleted`);
|
|
19362
|
+
if (c.outbound_schedules_created > 0) parts.push(`${c.outbound_schedules_created} outbound schedule(s) created`);
|
|
19363
|
+
if (c.outbound_schedules_updated > 0) parts.push(`${c.outbound_schedules_updated} outbound schedule(s) updated`);
|
|
19364
|
+
if (c.outbound_schedules_deleted > 0) parts.push(`${c.outbound_schedules_deleted} outbound schedule(s) deleted`);
|
|
19365
|
+
if (parts.length > 0) {
|
|
19366
|
+
console.log(`Changes: ${parts.join(", ")}`);
|
|
19367
|
+
}
|
|
19368
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
19369
|
+
printWarnings(result.warnings.map((w) => w.message));
|
|
19370
|
+
}
|
|
19371
|
+
}
|
|
19372
|
+
function printWarnings(warnings) {
|
|
19373
|
+
if (warnings.length === 0) return;
|
|
19374
|
+
console.log(`
|
|
19375
|
+
\x1B[33mWarnings (${warnings.length}):\x1B[0m`);
|
|
19376
|
+
for (const w of warnings) {
|
|
19377
|
+
console.log(` \x1B[33m! ${w}\x1B[0m`);
|
|
19378
|
+
}
|
|
19379
|
+
}
|
|
19380
|
+
function printErrors(errors) {
|
|
19381
|
+
if (errors.length === 0) return;
|
|
19382
|
+
console.error(`
|
|
19383
|
+
\x1B[31mErrors (${errors.length}):\x1B[0m`);
|
|
19384
|
+
for (const error of errors) {
|
|
19385
|
+
const message = typeof error === "string" ? error : error.message;
|
|
19386
|
+
console.error(` \x1B[31m! ${message}\x1B[0m`);
|
|
19387
|
+
}
|
|
19388
|
+
}
|
|
19389
|
+
function printLocalFileChanges(delta) {
|
|
19390
|
+
if (delta.changed.length === 0 && delta.removed.length === 0) {
|
|
19391
|
+
console.log("Local files already in sync.");
|
|
19392
|
+
return;
|
|
19393
|
+
}
|
|
19394
|
+
console.log("Local files updated from server:");
|
|
19395
|
+
const emit = (paths, sigil) => {
|
|
19396
|
+
const sorted = [...paths].sort();
|
|
19397
|
+
for (const p of sorted.slice(0, LOCAL_CHANGE_LIST_CAP)) console.log(` ${sigil} ${p}`);
|
|
19398
|
+
if (sorted.length > LOCAL_CHANGE_LIST_CAP) {
|
|
19399
|
+
console.log(` \u2026and ${sorted.length - LOCAL_CHANGE_LIST_CAP} more ${sigil === "-" ? "removed" : "changed"}`);
|
|
19400
|
+
}
|
|
19401
|
+
};
|
|
19402
|
+
emit(delta.removed, "-");
|
|
19403
|
+
emit(delta.changed, "~");
|
|
19404
|
+
}
|
|
19405
|
+
async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, remoteConfig) {
|
|
19406
|
+
const agentsDir = path22.join(hubFolder, "agents");
|
|
19407
|
+
let agentsWithIds = [];
|
|
19408
|
+
if (fs18.existsSync(agentsDir)) {
|
|
19409
|
+
const yamlFiles = fs18.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml"));
|
|
19410
|
+
for (const file of yamlFiles) {
|
|
19411
|
+
try {
|
|
19412
|
+
const content = fs18.readFileSync(path22.join(agentsDir, file), "utf-8");
|
|
19413
|
+
const agent = yaml10.load(content);
|
|
19414
|
+
if (agent?.id && agent.name) {
|
|
19415
|
+
agentsWithIds.push({ id: agent.id, name: agent.name });
|
|
19416
|
+
}
|
|
19417
|
+
} catch {
|
|
19418
|
+
console.warn(` Warning: could not parse agents/${file}, skipping`);
|
|
19419
|
+
}
|
|
19420
|
+
}
|
|
19421
|
+
}
|
|
19422
|
+
if (agentsWithIds.length === 0) {
|
|
19423
|
+
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
19424
|
+
if (!yamlPath) return;
|
|
19425
|
+
const yamlContent = fs18.readFileSync(yamlPath, "utf-8");
|
|
19426
|
+
const config = yaml10.load(yamlContent);
|
|
19427
|
+
agentsWithIds = (config.agents || []).filter((a) => !!a.id && !!a.name);
|
|
19428
|
+
}
|
|
19429
|
+
if (agentsWithIds.length === 0) return;
|
|
19430
|
+
console.log("Checking for agent renames...");
|
|
19431
|
+
let remote = remoteConfig;
|
|
19432
|
+
if (!remote) {
|
|
19433
|
+
try {
|
|
19434
|
+
remote = await client.pull(hubId, organizationId);
|
|
19435
|
+
} catch (err) {
|
|
19436
|
+
console.warn(` Warning: could not fetch remote state for auto-rename (${err instanceof Error ? err.message : String(err)}). File renames skipped.`);
|
|
19437
|
+
return;
|
|
19438
|
+
}
|
|
19439
|
+
}
|
|
19440
|
+
const remoteAgentNames = /* @__PURE__ */ new Map();
|
|
19441
|
+
for (const agent of remote.agents || []) {
|
|
19442
|
+
if (agent.id) {
|
|
19443
|
+
remoteAgentNames.set(agent.id, agent.name);
|
|
19444
|
+
}
|
|
19445
|
+
}
|
|
19446
|
+
const renames = [];
|
|
19447
|
+
for (const agent of agentsWithIds) {
|
|
19448
|
+
const remoteName = remoteAgentNames.get(agent.id);
|
|
19449
|
+
if (!remoteName || remoteName === agent.name) continue;
|
|
19450
|
+
const oldSlug = slugify(remoteName);
|
|
19451
|
+
const newSlug = slugify(agent.name);
|
|
19452
|
+
if (oldSlug !== newSlug) {
|
|
19453
|
+
renames.push({ oldSlug, newSlug });
|
|
19454
|
+
}
|
|
19455
|
+
}
|
|
19456
|
+
if (renames.length === 0) return;
|
|
19457
|
+
if (!fs18.existsSync(agentsDir)) return;
|
|
19458
|
+
for (const file of fs18.readdirSync(agentsDir)) {
|
|
19459
|
+
if (file.startsWith("__rename_temp_") && (file.endsWith(".md") || file.endsWith(".yaml"))) {
|
|
19460
|
+
console.warn(` Warning: removing orphaned temp file agents/${file}`);
|
|
19461
|
+
fs18.unlinkSync(path22.join(agentsDir, file));
|
|
19462
|
+
}
|
|
19463
|
+
}
|
|
19464
|
+
const renameFileIfExists = (dir, oldName, newName) => {
|
|
19465
|
+
const oldPath = path22.join(dir, oldName);
|
|
19466
|
+
const newPath = path22.join(dir, newName);
|
|
19467
|
+
if (!fs18.existsSync(oldPath)) return false;
|
|
19468
|
+
fs18.renameSync(oldPath, newPath);
|
|
19469
|
+
return true;
|
|
19470
|
+
};
|
|
19471
|
+
const oldSlugs = new Set(renames.map((r) => r.oldSlug));
|
|
19472
|
+
const newSlugs = new Set(renames.map((r) => r.newSlug));
|
|
19473
|
+
const hasConflicts = renames.some((r) => oldSlugs.has(r.newSlug)) || newSlugs.size !== renames.length;
|
|
19474
|
+
const completedRenames = [];
|
|
18250
19475
|
const extensions = [".yaml", ".md"];
|
|
18251
19476
|
if (hasConflicts) {
|
|
18252
19477
|
const tempRenames = [];
|
|
@@ -18273,9 +19498,9 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
18273
19498
|
}
|
|
18274
19499
|
} else {
|
|
18275
19500
|
for (const { oldSlug, newSlug } of renames) {
|
|
18276
|
-
const hasOldFile = extensions.some((ext) =>
|
|
19501
|
+
const hasOldFile = extensions.some((ext) => fs18.existsSync(path22.join(agentsDir, `${oldSlug}${ext}`)));
|
|
18277
19502
|
if (!hasOldFile) continue;
|
|
18278
|
-
const hasNewFile = extensions.some((ext) =>
|
|
19503
|
+
const hasNewFile = extensions.some((ext) => fs18.existsSync(path22.join(agentsDir, `${newSlug}${ext}`)));
|
|
18279
19504
|
if (hasNewFile) {
|
|
18280
19505
|
console.warn(` Warning: skipping rename agents/${oldSlug}.* \u2192 agents/${newSlug}.* (target already exists)`);
|
|
18281
19506
|
continue;
|
|
@@ -18290,7 +19515,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
18290
19515
|
if (completedRenames.length === 0) return;
|
|
18291
19516
|
const mainYamlPath = resolveHubYamlPath(hubFolder);
|
|
18292
19517
|
if (mainYamlPath) {
|
|
18293
|
-
const mainYamlContent =
|
|
19518
|
+
const mainYamlContent = fs18.readFileSync(mainYamlPath, "utf-8");
|
|
18294
19519
|
const substitutionMap = /* @__PURE__ */ new Map();
|
|
18295
19520
|
for (const { oldSlug, newSlug } of completedRenames) {
|
|
18296
19521
|
substitutionMap.set(`agents/${oldSlug}.md`, `agents/${newSlug}.md`);
|
|
@@ -18301,8 +19526,8 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
18301
19526
|
(_match, prefix, pathMatch) => `${prefix}${substitutionMap.get(pathMatch) ?? pathMatch}`
|
|
18302
19527
|
);
|
|
18303
19528
|
if (updatedYaml !== mainYamlContent) {
|
|
18304
|
-
|
|
18305
|
-
console.log(` Updated instructions paths in ${
|
|
19529
|
+
fs18.writeFileSync(mainYamlPath, updatedYaml, "utf-8");
|
|
19530
|
+
console.log(` Updated instructions paths in ${path22.basename(mainYamlPath)}`);
|
|
18306
19531
|
}
|
|
18307
19532
|
}
|
|
18308
19533
|
}
|
|
@@ -18370,7 +19595,7 @@ async function pushSingleHub(client, hubId, hubFolder, autoConfirm, organization
|
|
|
18370
19595
|
function selectExistingHub(workspaceDir, allHubs, selector, wsLabel) {
|
|
18371
19596
|
if (selector) {
|
|
18372
19597
|
const match = allHubs.find(
|
|
18373
|
-
(h) => h.hubId === selector ||
|
|
19598
|
+
(h) => h.hubId === selector || path22.basename(h.hubFolder) === selector
|
|
18374
19599
|
);
|
|
18375
19600
|
if (!match) {
|
|
18376
19601
|
console.error(`No hub matching --hub ${selector} found in ${wsLabel}/.`);
|
|
@@ -18413,7 +19638,7 @@ New hub: "${newHub.hubName}" (${hubType})`);
|
|
|
18413
19638
|
process.exit(1);
|
|
18414
19639
|
}
|
|
18415
19640
|
console.log(`Hub created: ${createdHub.hub_name} (${hubId})`);
|
|
18416
|
-
const content =
|
|
19641
|
+
const content = fs18.readFileSync(hubYamlPath, "utf-8");
|
|
18417
19642
|
const hasVersion = content.match(/^version:\s/m);
|
|
18418
19643
|
let updated;
|
|
18419
19644
|
if (hasVersion) {
|
|
@@ -18429,7 +19654,7 @@ hub_id: "${hubId}"
|
|
|
18429
19654
|
hub_environment: preview
|
|
18430
19655
|
${content}`;
|
|
18431
19656
|
}
|
|
18432
|
-
|
|
19657
|
+
fs18.writeFileSync(hubYamlPath, updated, "utf-8");
|
|
18433
19658
|
autoBindIfUnbound(hubId);
|
|
18434
19659
|
await pushSingleHub(client, hubId, newHub.hubFolder, opts.autoConfirm, opts.organizationId, { skipAgentRename: true });
|
|
18435
19660
|
}
|
|
@@ -18438,7 +19663,7 @@ function reportUnresolvedPushTarget(reason, existingHubs, newHubs, selector, wsL
|
|
|
18438
19663
|
if (existingHubs.length > 0) {
|
|
18439
19664
|
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\`:`);
|
|
18440
19665
|
for (const h of existingHubs) {
|
|
18441
|
-
console.error(` ${
|
|
19666
|
+
console.error(` ${path22.basename(h.hubFolder)} (${h.hubId}, production mirror)`);
|
|
18442
19667
|
}
|
|
18443
19668
|
} else {
|
|
18444
19669
|
console.error(`No hub folders found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` and run \`wayai push\` (or \`wayai create\`).`);
|
|
@@ -18446,34 +19671,41 @@ function reportUnresolvedPushTarget(reason, existingHubs, newHubs, selector, wsL
|
|
|
18446
19671
|
process.exit(1);
|
|
18447
19672
|
}
|
|
18448
19673
|
if (reason === "selector_miss") {
|
|
18449
|
-
console.error(`No hub matching
|
|
19674
|
+
console.error(`No hub matching "${selector}" found in ${wsLabel}/. Available:`);
|
|
18450
19675
|
} else {
|
|
18451
19676
|
console.error(`Multiple hub folders found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
|
|
18452
19677
|
}
|
|
18453
19678
|
for (const h of existingHubs) {
|
|
18454
|
-
console.error(` ${
|
|
19679
|
+
console.error(` ${path22.basename(h.hubFolder)} (${h.hubId})`);
|
|
18455
19680
|
}
|
|
18456
19681
|
for (const h of newHubs) {
|
|
18457
|
-
console.error(` ${
|
|
19682
|
+
console.error(` ${path22.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
|
|
18458
19683
|
}
|
|
18459
19684
|
process.exit(1);
|
|
18460
19685
|
}
|
|
18461
19686
|
async function pushCommand(args2) {
|
|
18462
|
-
const
|
|
19687
|
+
const gitRoot = findGitRoot();
|
|
19688
|
+
const route = requireSubtree("push", args2, gitRoot);
|
|
19689
|
+
if (gitRoot) warnLayoutOnce(gitRoot);
|
|
19690
|
+
if (route.subtree === "bases") {
|
|
19691
|
+
const { pushBase: pushBase2 } = await Promise.resolve().then(() => (init_sync(), sync_exports));
|
|
19692
|
+
await pushBase2(gitRoot, route.selector, args2);
|
|
19693
|
+
return;
|
|
19694
|
+
}
|
|
19695
|
+
const { autoConfirm, label } = parseArgs5(args2);
|
|
19696
|
+
const hubSelector = route.selector;
|
|
18463
19697
|
const repoConfig = requireRepoConfig();
|
|
18464
19698
|
const { organization_id: organizationId } = repoConfig;
|
|
18465
19699
|
const { config, accessToken } = await requireAuth();
|
|
18466
19700
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
18467
19701
|
const workspaceDir = resolveWorkspaceDir();
|
|
18468
|
-
const gitRoot = findGitRoot();
|
|
18469
19702
|
const wsLabel = hubsDirLabel(gitRoot);
|
|
18470
|
-
if (gitRoot) warnLayoutOnce(gitRoot);
|
|
18471
19703
|
if (gitRoot) {
|
|
18472
19704
|
for (const file of ensureWorkspaceFiles(gitRoot)) {
|
|
18473
19705
|
console.error(`Created ${file}`);
|
|
18474
19706
|
}
|
|
18475
19707
|
}
|
|
18476
|
-
if (!
|
|
19708
|
+
if (!fs18.existsSync(workspaceDir)) {
|
|
18477
19709
|
console.error(`No ${wsLabel}/ directory found. Run \`wayai pull\` first or create hub files in ${wsLabel}/<hub>/hub.yaml.`);
|
|
18478
19710
|
process.exit(1);
|
|
18479
19711
|
}
|
|
@@ -18492,8 +19724,8 @@ async function pushCommand(args2) {
|
|
|
18492
19724
|
if (label) {
|
|
18493
19725
|
console.warn("Note: --label is only used when creating a new hub. To change an existing hub's label, use `wayai relabel`.");
|
|
18494
19726
|
}
|
|
18495
|
-
console.log(`Target hub: ${
|
|
18496
|
-
assertHubMatchesBinding(existing.hubId,
|
|
19727
|
+
console.log(`Target hub: ${path22.basename(existing.hubFolder)} (${existing.hubId})`);
|
|
19728
|
+
assertHubMatchesBinding(existing.hubId, path22.basename(existing.hubFolder));
|
|
18497
19729
|
await pushSingleHub(client, existing.hubId, existing.hubFolder, autoConfirm, organizationId);
|
|
18498
19730
|
return;
|
|
18499
19731
|
}
|
|
@@ -18517,6 +19749,7 @@ var init_push = __esm({
|
|
|
18517
19749
|
init_workspace_files();
|
|
18518
19750
|
init_repo_config();
|
|
18519
19751
|
init_hub_binding();
|
|
19752
|
+
init_subtree_routing();
|
|
18520
19753
|
LOCAL_CHANGE_LIST_CAP = 20;
|
|
18521
19754
|
}
|
|
18522
19755
|
});
|
|
@@ -18527,33 +19760,23 @@ __export(pull_exports, {
|
|
|
18527
19760
|
connectionsEqual: () => connectionsEqual,
|
|
18528
19761
|
pullCommand: () => pullCommand,
|
|
18529
19762
|
resolveHubTarget: () => resolveHubTarget,
|
|
18530
|
-
writeProductionMirror: () =>
|
|
19763
|
+
writeProductionMirror: () => writeProductionMirror2
|
|
18531
19764
|
});
|
|
18532
|
-
import * as
|
|
18533
|
-
import * as
|
|
18534
|
-
function
|
|
18535
|
-
|
|
18536
|
-
let hubSelector;
|
|
18537
|
-
for (let i = 0; i < args2.length; i++) {
|
|
18538
|
-
const arg = args2[i];
|
|
18539
|
-
if (arg === "--yes" || arg === "-y") {
|
|
18540
|
-
autoConfirm = true;
|
|
18541
|
-
} else if (arg === "--hub" && args2[i + 1]) {
|
|
18542
|
-
hubSelector = args2[++i];
|
|
18543
|
-
}
|
|
18544
|
-
}
|
|
18545
|
-
return { autoConfirm, hubSelector };
|
|
19765
|
+
import * as fs19 from "fs";
|
|
19766
|
+
import * as path23 from "path";
|
|
19767
|
+
function parseArgs6(args2) {
|
|
19768
|
+
return { autoConfirm: args2.includes("--yes") || args2.includes("-y") };
|
|
18546
19769
|
}
|
|
18547
19770
|
function resolveHubTarget(workspaceDir, selector) {
|
|
18548
19771
|
const wsLabel = hubsDirLabel(findGitRoot());
|
|
18549
19772
|
const allHubs = scanWorkspaceHubs(workspaceDir);
|
|
18550
19773
|
if (selector) {
|
|
18551
19774
|
const match = allHubs.find(
|
|
18552
|
-
(h) => h.hubId === selector ||
|
|
19775
|
+
(h) => h.hubId === selector || path23.basename(h.hubFolder) === selector
|
|
18553
19776
|
);
|
|
18554
19777
|
if (match) return { hubId: match.hubId, hubFolder: match.hubFolder };
|
|
18555
19778
|
if (UUID_RE2.test(selector)) return { hubId: selector, hubFolder: null };
|
|
18556
|
-
console.error(`No hub matching
|
|
19779
|
+
console.error(`No hub matching "${selector}" found in ${wsLabel}/. Pass a UUID for first-time pulls.`);
|
|
18557
19780
|
process.exit(1);
|
|
18558
19781
|
}
|
|
18559
19782
|
const enclosing = findEnclosingHubFolder(workspaceDir);
|
|
@@ -18566,19 +19789,26 @@ function resolveHubTarget(workspaceDir, selector) {
|
|
|
18566
19789
|
}
|
|
18567
19790
|
console.error(`Multiple hubs found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
|
|
18568
19791
|
for (const h of previewHubs) {
|
|
18569
|
-
console.error(` ${
|
|
19792
|
+
console.error(` ${path23.basename(h.hubFolder)} (${h.hubId})`);
|
|
18570
19793
|
}
|
|
18571
19794
|
process.exit(1);
|
|
18572
19795
|
}
|
|
18573
19796
|
async function pullCommand(args2) {
|
|
18574
|
-
const
|
|
19797
|
+
const gitRoot = findGitRoot();
|
|
19798
|
+
const route = requireSubtree("pull", args2, gitRoot);
|
|
19799
|
+
if (gitRoot) warnLayoutOnce(gitRoot);
|
|
19800
|
+
if (route.subtree === "bases") {
|
|
19801
|
+
const { pullBase: pullBase2 } = await Promise.resolve().then(() => (init_sync(), sync_exports));
|
|
19802
|
+
await pullBase2(gitRoot, route.selector, args2);
|
|
19803
|
+
return;
|
|
19804
|
+
}
|
|
19805
|
+
const { autoConfirm } = parseArgs6(args2);
|
|
19806
|
+
const hubSelector = route.selector;
|
|
18575
19807
|
const repoConfig = requireRepoConfig();
|
|
18576
19808
|
const { organization_id: organizationId } = repoConfig;
|
|
18577
19809
|
const { config, accessToken } = await requireAuth();
|
|
18578
19810
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
18579
19811
|
const workspaceDir = resolveWorkspaceDir();
|
|
18580
|
-
const gitRoot = findGitRoot();
|
|
18581
|
-
if (gitRoot) warnLayoutOnce(gitRoot);
|
|
18582
19812
|
if (gitRoot) {
|
|
18583
19813
|
for (const file of ensureWorkspaceFiles(gitRoot)) {
|
|
18584
19814
|
console.error(`Created ${file}`);
|
|
@@ -18588,7 +19818,7 @@ async function pullCommand(args2) {
|
|
|
18588
19818
|
console.log("Fetching hub configuration...");
|
|
18589
19819
|
const payload = await client.pull(hubId, organizationId);
|
|
18590
19820
|
if (payload.hub_environment === "production") {
|
|
18591
|
-
const folder = await
|
|
19821
|
+
const folder = await writeProductionMirror2(workspaceDir, payload);
|
|
18592
19822
|
console.log(`Production hub mirrored (read-only) \u2192 ${folder}`);
|
|
18593
19823
|
return;
|
|
18594
19824
|
}
|
|
@@ -18604,7 +19834,7 @@ async function pullCommand(args2) {
|
|
|
18604
19834
|
payload.preview_label,
|
|
18605
19835
|
payload.branch_name
|
|
18606
19836
|
);
|
|
18607
|
-
|
|
19837
|
+
fs19.mkdirSync(path23.dirname(hubFolder), { recursive: true });
|
|
18608
19838
|
console.log("Writing hub configuration...");
|
|
18609
19839
|
await materializeHubFolder(hubFolder, payload);
|
|
18610
19840
|
const finalFolder = autoRenameHubFolder(hubFolder, payload.hub.name, payload.hub_environment, payload.hub_id, payload.preview_label, payload.branch_name);
|
|
@@ -18653,34 +19883,34 @@ async function pullCommand(args2) {
|
|
|
18653
19883
|
}
|
|
18654
19884
|
if (wroteFiles) autoBindIfUnbound(hubId);
|
|
18655
19885
|
if (payload.production_hub_id) {
|
|
18656
|
-
await
|
|
19886
|
+
await mirrorLinkedProduction2(client, workspaceDir, payload.production_hub_id, organizationId);
|
|
18657
19887
|
}
|
|
18658
19888
|
}
|
|
18659
|
-
async function
|
|
19889
|
+
async function writeProductionMirror2(workspaceDir, prodPayload) {
|
|
18660
19890
|
const folder = resolveHubFolder(workspaceDir, prodPayload.hub_id, prodPayload.hub.name, "production", null, null);
|
|
18661
|
-
|
|
19891
|
+
fs19.mkdirSync(path23.dirname(folder), { recursive: true });
|
|
18662
19892
|
await materializeHubFolder(folder, prodPayload, { seedAgentContext: false });
|
|
18663
19893
|
const finalFolder = autoRenameHubFolder(folder, prodPayload.hub.name, "production", prodPayload.hub_id, null, null);
|
|
18664
19894
|
prependMirrorMarker(finalFolder, prodPayload.hub_id);
|
|
18665
19895
|
return finalFolder;
|
|
18666
19896
|
}
|
|
18667
|
-
async function
|
|
19897
|
+
async function mirrorLinkedProduction2(client, workspaceDir, productionHubId, organizationId) {
|
|
18668
19898
|
try {
|
|
18669
19899
|
const prodPayload = await client.pull(productionHubId, organizationId);
|
|
18670
|
-
const folder = await
|
|
19900
|
+
const folder = await writeProductionMirror2(workspaceDir, prodPayload);
|
|
18671
19901
|
console.log(`Mirrored production hub \u2192 ${folder} (read-only)`);
|
|
18672
19902
|
} catch (err) {
|
|
18673
19903
|
console.warn(`Warning: could not mirror production hub (${err instanceof Error ? err.message : String(err)}). Preview pull is unaffected.`);
|
|
18674
19904
|
}
|
|
18675
19905
|
}
|
|
18676
19906
|
function prependMirrorMarker(hubFolder, productionHubId) {
|
|
18677
|
-
const hubYaml =
|
|
19907
|
+
const hubYaml = path23.join(hubFolder, "hub.yaml");
|
|
18678
19908
|
try {
|
|
18679
|
-
const content =
|
|
18680
|
-
if (content.startsWith(
|
|
18681
|
-
const marker = `${
|
|
19909
|
+
const content = fs19.readFileSync(hubYaml, "utf-8");
|
|
19910
|
+
if (content.startsWith(MIRROR_MARKER_PREFIX2)) return;
|
|
19911
|
+
const marker = `${MIRROR_MARKER_PREFIX2} ${productionHubId}. Edits are ignored; push is blocked. Edit the linked preview hub instead.
|
|
18682
19912
|
`;
|
|
18683
|
-
|
|
19913
|
+
fs19.writeFileSync(hubYaml, marker + content, "utf-8");
|
|
18684
19914
|
} catch {
|
|
18685
19915
|
}
|
|
18686
19916
|
}
|
|
@@ -18697,7 +19927,7 @@ function connectionsEqual(a, b) {
|
|
|
18697
19927
|
}
|
|
18698
19928
|
return true;
|
|
18699
19929
|
}
|
|
18700
|
-
var
|
|
19930
|
+
var MIRROR_MARKER_PREFIX2;
|
|
18701
19931
|
var init_pull = __esm({
|
|
18702
19932
|
"src/commands/pull.ts"() {
|
|
18703
19933
|
"use strict";
|
|
@@ -18714,7 +19944,8 @@ var init_pull = __esm({
|
|
|
18714
19944
|
init_workspace_files();
|
|
18715
19945
|
init_repo_config();
|
|
18716
19946
|
init_hub_binding();
|
|
18717
|
-
|
|
19947
|
+
init_subtree_routing();
|
|
19948
|
+
MIRROR_MARKER_PREFIX2 = "# Read-only mirror of production hub";
|
|
18718
19949
|
}
|
|
18719
19950
|
});
|
|
18720
19951
|
|
|
@@ -18723,9 +19954,9 @@ var create_exports = {};
|
|
|
18723
19954
|
__export(create_exports, {
|
|
18724
19955
|
createCommand: () => createCommand
|
|
18725
19956
|
});
|
|
18726
|
-
import * as
|
|
18727
|
-
import * as
|
|
18728
|
-
function
|
|
19957
|
+
import * as path24 from "path";
|
|
19958
|
+
import * as fs20 from "fs";
|
|
19959
|
+
function parseArgs7(args2) {
|
|
18729
19960
|
let autoConfirm = false;
|
|
18730
19961
|
let folderSelector;
|
|
18731
19962
|
let label;
|
|
@@ -18742,7 +19973,7 @@ function parseArgs6(args2) {
|
|
|
18742
19973
|
return { autoConfirm, folderSelector, label };
|
|
18743
19974
|
}
|
|
18744
19975
|
async function createCommand(args2) {
|
|
18745
|
-
const { autoConfirm, folderSelector, label } =
|
|
19976
|
+
const { autoConfirm, folderSelector, label } = parseArgs7(args2);
|
|
18746
19977
|
const repoConfig = requireRepoConfig();
|
|
18747
19978
|
const { organization_id: organizationId } = repoConfig;
|
|
18748
19979
|
const { config, accessToken } = await requireAuth();
|
|
@@ -18751,7 +19982,7 @@ async function createCommand(args2) {
|
|
|
18751
19982
|
const gitRoot = findGitRoot();
|
|
18752
19983
|
const wsLabel = hubsDirLabel(gitRoot);
|
|
18753
19984
|
if (gitRoot) warnLayoutOnce(gitRoot);
|
|
18754
|
-
if (!
|
|
19985
|
+
if (!fs20.existsSync(workspaceDir)) {
|
|
18755
19986
|
console.error(`No ${wsLabel}/ directory found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` first.`);
|
|
18756
19987
|
process.exit(1);
|
|
18757
19988
|
}
|
|
@@ -18760,7 +19991,7 @@ async function createCommand(args2) {
|
|
|
18760
19991
|
const resolution = resolveNewHubForCreate(workspaceDir, existingHubs, newHubs, folderSelector);
|
|
18761
19992
|
if (!resolution.ok) {
|
|
18762
19993
|
if (resolution.reason === "exists") {
|
|
18763
|
-
const folder =
|
|
19994
|
+
const folder = path24.basename(resolution.existing.hubFolder);
|
|
18764
19995
|
console.error(`Hub "${folder}" already exists (${resolution.existing.hubId}). Use \`wayai push --hub ${folder}\` to update it.`);
|
|
18765
19996
|
process.exit(1);
|
|
18766
19997
|
}
|
|
@@ -18774,7 +20005,7 @@ async function createCommand(args2) {
|
|
|
18774
20005
|
}
|
|
18775
20006
|
console.error(`Multiple new hub folders found in ${wsLabel}/. Pass the folder name (\`wayai create <folder>\`) or run from inside one:`);
|
|
18776
20007
|
for (const h of newHubs) {
|
|
18777
|
-
console.error(` ${
|
|
20008
|
+
console.error(` ${path24.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
|
|
18778
20009
|
}
|
|
18779
20010
|
process.exit(1);
|
|
18780
20011
|
}
|
|
@@ -18798,9 +20029,9 @@ var init_create = __esm({
|
|
|
18798
20029
|
var diff_exports = {};
|
|
18799
20030
|
__export(diff_exports, {
|
|
18800
20031
|
diffCommand: () => diffCommand,
|
|
18801
|
-
parseArgs: () =>
|
|
20032
|
+
parseArgs: () => parseArgs8
|
|
18802
20033
|
});
|
|
18803
|
-
function
|
|
20034
|
+
function parseArgs8(args2) {
|
|
18804
20035
|
let production = false;
|
|
18805
20036
|
let hubSelector;
|
|
18806
20037
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -18814,7 +20045,7 @@ function parseArgs7(args2) {
|
|
|
18814
20045
|
return { production, hubSelector };
|
|
18815
20046
|
}
|
|
18816
20047
|
async function diffCommand(args2) {
|
|
18817
|
-
const { production, hubSelector } =
|
|
20048
|
+
const { production, hubSelector } = parseArgs8(args2);
|
|
18818
20049
|
const repoConfig = requireRepoConfig();
|
|
18819
20050
|
const { organization_id: organizationId } = repoConfig;
|
|
18820
20051
|
const { config, accessToken } = await requireAuth();
|
|
@@ -18885,9 +20116,9 @@ var replicate_exports = {};
|
|
|
18885
20116
|
__export(replicate_exports, {
|
|
18886
20117
|
replicateCommand: () => replicateCommand
|
|
18887
20118
|
});
|
|
18888
|
-
import * as
|
|
18889
|
-
import * as
|
|
18890
|
-
function
|
|
20119
|
+
import * as fs21 from "fs";
|
|
20120
|
+
import * as path25 from "path";
|
|
20121
|
+
function parseArgs9(args2) {
|
|
18891
20122
|
let label;
|
|
18892
20123
|
let hubSelector;
|
|
18893
20124
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -18903,7 +20134,7 @@ function parseArgs8(args2) {
|
|
|
18903
20134
|
return { label, hubSelector };
|
|
18904
20135
|
}
|
|
18905
20136
|
async function replicateCommand(args2) {
|
|
18906
|
-
const { label, hubSelector } =
|
|
20137
|
+
const { label, hubSelector } = parseArgs9(args2);
|
|
18907
20138
|
const normalizedLabel = label?.trim() || void 0;
|
|
18908
20139
|
if (normalizedLabel && normalizedLabel.length > PREVIEW_LABEL_MAX_LENGTH) {
|
|
18909
20140
|
console.error(`--label must be ${PREVIEW_LABEL_MAX_LENGTH} characters or fewer.`);
|
|
@@ -18932,8 +20163,8 @@ async function replicateCommand(args2) {
|
|
|
18932
20163
|
payload.preview_label,
|
|
18933
20164
|
payload.branch_name
|
|
18934
20165
|
);
|
|
18935
|
-
const folderPreExisted =
|
|
18936
|
-
|
|
20166
|
+
const folderPreExisted = fs21.existsSync(hubFolder);
|
|
20167
|
+
fs21.mkdirSync(path25.dirname(hubFolder), { recursive: true });
|
|
18937
20168
|
const delta = await materializeHubFolder(hubFolder, payload);
|
|
18938
20169
|
hubFolder = autoRenameHubFolder(
|
|
18939
20170
|
hubFolder,
|
|
@@ -18945,8 +20176,8 @@ async function replicateCommand(args2) {
|
|
|
18945
20176
|
);
|
|
18946
20177
|
autoBindIfUnbound(previewHubId);
|
|
18947
20178
|
if (folderPreExisted) printLocalFileChanges(delta);
|
|
18948
|
-
console.log(`Preview written to ${
|
|
18949
|
-
console.log(` Switch to it with: wayai use ${
|
|
20179
|
+
console.log(`Preview written to ${path25.basename(hubFolder)}`);
|
|
20180
|
+
console.log(` Switch to it with: wayai use ${path25.basename(hubFolder)}`);
|
|
18950
20181
|
}
|
|
18951
20182
|
var init_replicate = __esm({
|
|
18952
20183
|
"src/commands/replicate.ts"() {
|
|
@@ -18969,8 +20200,8 @@ var relabel_exports = {};
|
|
|
18969
20200
|
__export(relabel_exports, {
|
|
18970
20201
|
relabelCommand: () => relabelCommand
|
|
18971
20202
|
});
|
|
18972
|
-
import * as
|
|
18973
|
-
function
|
|
20203
|
+
import * as path26 from "path";
|
|
20204
|
+
function parseArgs10(args2) {
|
|
18974
20205
|
let label;
|
|
18975
20206
|
let clear = false;
|
|
18976
20207
|
let hubSelector;
|
|
@@ -18987,7 +20218,7 @@ function parseArgs9(args2) {
|
|
|
18987
20218
|
return { label, clear, hubSelector };
|
|
18988
20219
|
}
|
|
18989
20220
|
async function relabelCommand(args2) {
|
|
18990
|
-
const { label, clear, hubSelector } =
|
|
20221
|
+
const { label, clear, hubSelector } = parseArgs10(args2);
|
|
18991
20222
|
if (!clear && (label === void 0 || label.trim() === "")) {
|
|
18992
20223
|
console.error("Usage: wayai relabel <label> [--hub <uuid|folder>] (or --clear to remove the label)");
|
|
18993
20224
|
process.exit(1);
|
|
@@ -19013,7 +20244,7 @@ async function relabelCommand(args2) {
|
|
|
19013
20244
|
} else {
|
|
19014
20245
|
console.error(`Multiple hubs found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
|
|
19015
20246
|
for (const h of previewHubs) {
|
|
19016
|
-
console.error(` ${
|
|
20247
|
+
console.error(` ${path26.basename(h.hubFolder)} (${h.hubId})`);
|
|
19017
20248
|
}
|
|
19018
20249
|
}
|
|
19019
20250
|
process.exit(1);
|
|
@@ -19022,7 +20253,7 @@ async function relabelCommand(args2) {
|
|
|
19022
20253
|
console.log("This is a read-only production mirror \u2014 production hubs have no preview label. Relabel the linked preview hub instead.");
|
|
19023
20254
|
return;
|
|
19024
20255
|
}
|
|
19025
|
-
assertHubMatchesBinding(target.hubId,
|
|
20256
|
+
assertHubMatchesBinding(target.hubId, path26.basename(target.hubFolder));
|
|
19026
20257
|
console.log(normalizedLabel ? `Setting preview label to "${normalizedLabel}"...` : "Clearing preview label...");
|
|
19027
20258
|
const { data } = await client.relabelPreview(target.hubId, normalizedLabel);
|
|
19028
20259
|
const row = data[0];
|
|
@@ -19038,7 +20269,7 @@ async function relabelCommand(args2) {
|
|
|
19038
20269
|
);
|
|
19039
20270
|
console.log(serverLabel ? `Preview label set to "${serverLabel}".` : "Preview label cleared.");
|
|
19040
20271
|
if (finalFolder !== target.hubFolder) {
|
|
19041
|
-
console.log(`Hub folder is now ${
|
|
20272
|
+
console.log(`Hub folder is now ${path26.basename(finalFolder)}`);
|
|
19042
20273
|
}
|
|
19043
20274
|
}
|
|
19044
20275
|
var init_relabel = __esm({
|
|
@@ -19059,13 +20290,13 @@ var init_relabel = __esm({
|
|
|
19059
20290
|
// src/commands/publish.ts
|
|
19060
20291
|
var publish_exports = {};
|
|
19061
20292
|
__export(publish_exports, {
|
|
19062
|
-
parseArgs: () =>
|
|
20293
|
+
parseArgs: () => parseArgs11,
|
|
19063
20294
|
publishCommand: () => publishCommand,
|
|
19064
20295
|
renderHubDiff: () => renderHubDiff,
|
|
19065
20296
|
runPublish: () => runPublish
|
|
19066
20297
|
});
|
|
19067
|
-
import * as
|
|
19068
|
-
function
|
|
20298
|
+
import * as path27 from "path";
|
|
20299
|
+
function parseArgs11(args2) {
|
|
19069
20300
|
let autoConfirm = false;
|
|
19070
20301
|
let hubSelector;
|
|
19071
20302
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -19159,7 +20390,7 @@ Published. Production hub: ${data.production_hub_id}`);
|
|
|
19159
20390
|
return "synced";
|
|
19160
20391
|
}
|
|
19161
20392
|
async function publishCommand(args2) {
|
|
19162
|
-
const { autoConfirm, hubSelector } =
|
|
20393
|
+
const { autoConfirm, hubSelector } = parseArgs11(args2);
|
|
19163
20394
|
const repoConfig = requireRepoConfig();
|
|
19164
20395
|
const { organization_id: organizationId } = repoConfig;
|
|
19165
20396
|
const { config, accessToken } = await requireAuth();
|
|
@@ -19178,7 +20409,7 @@ async function publishCommand(args2) {
|
|
|
19178
20409
|
return;
|
|
19179
20410
|
}
|
|
19180
20411
|
}
|
|
19181
|
-
assertHubMatchesBinding(hubId, hubFolder ?
|
|
20412
|
+
assertHubMatchesBinding(hubId, hubFolder ? path27.basename(hubFolder) : void 0);
|
|
19182
20413
|
await runPublish(client, { hubId, localConfig, organizationId, autoConfirm });
|
|
19183
20414
|
}
|
|
19184
20415
|
var STATUS_STYLE;
|
|
@@ -19211,7 +20442,7 @@ var use_exports = {};
|
|
|
19211
20442
|
__export(use_exports, {
|
|
19212
20443
|
useCommand: () => useCommand
|
|
19213
20444
|
});
|
|
19214
|
-
import * as
|
|
20445
|
+
import * as path28 from "path";
|
|
19215
20446
|
async function useCommand(args2) {
|
|
19216
20447
|
const target = args2[0];
|
|
19217
20448
|
if (!target || target.startsWith("-")) {
|
|
@@ -19233,7 +20464,7 @@ async function useCommand(args2) {
|
|
|
19233
20464
|
const match = findHubByFolderName(workspaceDir, target);
|
|
19234
20465
|
if (!match) {
|
|
19235
20466
|
const newHubs = scanNewHubs(workspaceDir);
|
|
19236
|
-
const pending = newHubs.find((h) =>
|
|
20467
|
+
const pending = newHubs.find((h) => path28.basename(h.hubFolder) === target);
|
|
19237
20468
|
if (pending) {
|
|
19238
20469
|
console.error(
|
|
19239
20470
|
`"${target}" is a new hub that hasn't been created on the platform yet, so it has no id to bind to.
|
|
@@ -19244,10 +20475,10 @@ Create it first \u2014 the worktree binds automatically afterward:
|
|
|
19244
20475
|
}
|
|
19245
20476
|
console.error(`No hub matching "${target}" found in ${wsLabel}/. Pass a UUID or a folder name from:`);
|
|
19246
20477
|
for (const h of scanWorkspaceHubs(workspaceDir)) {
|
|
19247
|
-
console.error(` ${
|
|
20478
|
+
console.error(` ${path28.basename(h.hubFolder)} (${h.hubId})`);
|
|
19248
20479
|
}
|
|
19249
20480
|
for (const h of newHubs) {
|
|
19250
|
-
console.error(` ${
|
|
20481
|
+
console.error(` ${path28.basename(h.hubFolder)} (new \u2014 "${h.hubName}", run \`wayai create ${path28.basename(h.hubFolder)}\`)`);
|
|
19251
20482
|
}
|
|
19252
20483
|
process.exit(1);
|
|
19253
20484
|
}
|
|
@@ -19286,11 +20517,11 @@ __export(migrate_exports, {
|
|
|
19286
20517
|
migrateCommand: () => migrateCommand
|
|
19287
20518
|
});
|
|
19288
20519
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
19289
|
-
import * as
|
|
19290
|
-
import * as
|
|
20520
|
+
import * as fs22 from "fs";
|
|
20521
|
+
import * as path29 from "path";
|
|
19291
20522
|
function isTracked(gitRoot, p) {
|
|
19292
20523
|
try {
|
|
19293
|
-
execFileSync3("git", ["ls-files", "--error-unmatch", "--",
|
|
20524
|
+
execFileSync3("git", ["ls-files", "--error-unmatch", "--", path29.relative(gitRoot, p)], {
|
|
19294
20525
|
cwd: gitRoot,
|
|
19295
20526
|
stdio: ["pipe", "pipe", "pipe"]
|
|
19296
20527
|
});
|
|
@@ -19300,10 +20531,10 @@ function isTracked(gitRoot, p) {
|
|
|
19300
20531
|
}
|
|
19301
20532
|
}
|
|
19302
20533
|
function moveDir(gitRoot, from, to) {
|
|
19303
|
-
|
|
20534
|
+
fs22.mkdirSync(path29.dirname(to), { recursive: true });
|
|
19304
20535
|
if (isTracked(gitRoot, from)) {
|
|
19305
20536
|
try {
|
|
19306
|
-
execFileSync3("git", ["mv",
|
|
20537
|
+
execFileSync3("git", ["mv", path29.relative(gitRoot, from), path29.relative(gitRoot, to)], {
|
|
19307
20538
|
cwd: gitRoot,
|
|
19308
20539
|
stdio: ["pipe", "pipe", "pipe"]
|
|
19309
20540
|
});
|
|
@@ -19311,7 +20542,7 @@ function moveDir(gitRoot, from, to) {
|
|
|
19311
20542
|
} catch {
|
|
19312
20543
|
}
|
|
19313
20544
|
}
|
|
19314
|
-
|
|
20545
|
+
fs22.renameSync(from, to);
|
|
19315
20546
|
return "fs";
|
|
19316
20547
|
}
|
|
19317
20548
|
async function migrateCommand(_args) {
|
|
@@ -19320,12 +20551,12 @@ async function migrateCommand(_args) {
|
|
|
19320
20551
|
console.error("Not inside a git repository.");
|
|
19321
20552
|
process.exit(1);
|
|
19322
20553
|
}
|
|
19323
|
-
const rel = (p) =>
|
|
19324
|
-
const newWs =
|
|
19325
|
-
const legacyWs =
|
|
19326
|
-
const legacyOrg =
|
|
19327
|
-
const newHubs =
|
|
19328
|
-
const newOrg =
|
|
20554
|
+
const rel = (p) => path29.relative(gitRoot, p);
|
|
20555
|
+
const newWs = path29.join(gitRoot, WAYAI_LAYOUT.wsDir);
|
|
20556
|
+
const legacyWs = path29.join(gitRoot, WAYAI_LAYOUT.legacy.wsDir);
|
|
20557
|
+
const legacyOrg = path29.join(gitRoot, WAYAI_LAYOUT.legacy.orgAtRoot);
|
|
20558
|
+
const newHubs = path29.join(newWs, WAYAI_LAYOUT.hubsSubdir);
|
|
20559
|
+
const newOrg = path29.join(newWs, WAYAI_LAYOUT.orgSubdir);
|
|
19329
20560
|
const hasLegacyWs = isDirectory(legacyWs);
|
|
19330
20561
|
const hasLegacyOrg = isDirectory(legacyOrg);
|
|
19331
20562
|
if (!hasLegacyWs && !hasLegacyOrg) {
|
|
@@ -19399,12 +20630,12 @@ var send_message_exports = {};
|
|
|
19399
20630
|
__export(send_message_exports, {
|
|
19400
20631
|
sendMessageCommand: () => sendMessageCommand
|
|
19401
20632
|
});
|
|
19402
|
-
import * as
|
|
19403
|
-
import * as
|
|
20633
|
+
import * as fs23 from "fs";
|
|
20634
|
+
import * as path30 from "path";
|
|
19404
20635
|
function statAttachment(filePath) {
|
|
19405
20636
|
let stat2;
|
|
19406
20637
|
try {
|
|
19407
|
-
stat2 =
|
|
20638
|
+
stat2 = fs23.statSync(filePath);
|
|
19408
20639
|
} catch {
|
|
19409
20640
|
console.error(`Error: file not found: ${filePath}`);
|
|
19410
20641
|
process.exit(1);
|
|
@@ -19416,11 +20647,11 @@ function statAttachment(filePath) {
|
|
|
19416
20647
|
return { filePath, size: stat2.size };
|
|
19417
20648
|
}
|
|
19418
20649
|
function readAttachment(filePath, size) {
|
|
19419
|
-
const fileName =
|
|
19420
|
-
const ext =
|
|
20650
|
+
const fileName = path30.basename(filePath);
|
|
20651
|
+
const ext = path30.extname(fileName).replace(/^\./, "");
|
|
19421
20652
|
return {
|
|
19422
20653
|
file_name: fileName,
|
|
19423
|
-
file_binary:
|
|
20654
|
+
file_binary: fs23.readFileSync(filePath).toString("base64"),
|
|
19424
20655
|
file_size: size,
|
|
19425
20656
|
...ext && { file_extension: ext }
|
|
19426
20657
|
};
|
|
@@ -19467,7 +20698,7 @@ async function sendMessageCommand(args2) {
|
|
|
19467
20698
|
}
|
|
19468
20699
|
const stats = filePaths.map(statAttachment);
|
|
19469
20700
|
const filesTotal = stats.reduce((sum, s) => sum + base64Length(s.size), 0);
|
|
19470
|
-
const fileDetail = () => stats.map((s) => `${
|
|
20701
|
+
const fileDetail = () => stats.map((s) => `${path30.basename(s.filePath)} ${asMb(s.size)} MB`).join(", ");
|
|
19471
20702
|
if (filesTotal > MAX_MESSAGE_BODY_BYTES) {
|
|
19472
20703
|
console.error(
|
|
19473
20704
|
`Error: ${fileDetail()} encode to ~${asMb(filesTotal)} MB, over the ${asMb(MAX_MESSAGE_BODY_BYTES)} MB per-request limit.`
|
|
@@ -19475,10 +20706,10 @@ async function sendMessageCommand(args2) {
|
|
|
19475
20706
|
console.error("Base64 inflates a file by about a third, so ~7 MB of files is the practical ceiling.");
|
|
19476
20707
|
process.exit(1);
|
|
19477
20708
|
}
|
|
19478
|
-
const audioStats = stats.filter((s) => isAudioAttachmentFileName(
|
|
20709
|
+
const audioStats = stats.filter((s) => isAudioAttachmentFileName(path30.basename(s.filePath)));
|
|
19479
20710
|
if (audioStats.length > 1) {
|
|
19480
20711
|
console.error(
|
|
19481
|
-
`Error: at most one audio file per message (got ${audioStats.length}: ${audioStats.map((s) =>
|
|
20712
|
+
`Error: at most one audio file per message (got ${audioStats.length}: ${audioStats.map((s) => path30.basename(s.filePath)).join(", ")}).`
|
|
19482
20713
|
);
|
|
19483
20714
|
console.error("Audio is transcribed via the hub's STT connection, and only one file per message is transcribed.");
|
|
19484
20715
|
process.exit(1);
|
|
@@ -19486,7 +20717,7 @@ async function sendMessageCommand(args2) {
|
|
|
19486
20717
|
const oversizeAudio = audioStats.find((s) => base64Length(s.size) > MAX_AUDIO_FILE_BASE64_BYTES);
|
|
19487
20718
|
if (oversizeAudio) {
|
|
19488
20719
|
console.error(
|
|
19489
|
-
`Error: ${
|
|
20720
|
+
`Error: ${path30.basename(oversizeAudio.filePath)} (${asMb(oversizeAudio.size)} MB) is over the ~${asMb(MAX_AUDIO_FILE_BASE64_BYTES * 3 / 4)} MB audio limit for transcription.`
|
|
19490
20721
|
);
|
|
19491
20722
|
process.exit(1);
|
|
19492
20723
|
}
|
|
@@ -20363,10 +21594,10 @@ var init_delete_history = __esm({
|
|
|
20363
21594
|
// src/commands/sync-skills.ts
|
|
20364
21595
|
var sync_skills_exports = {};
|
|
20365
21596
|
__export(sync_skills_exports, {
|
|
20366
|
-
parseArgs: () =>
|
|
21597
|
+
parseArgs: () => parseArgs12,
|
|
20367
21598
|
syncSkillsCommand: () => syncSkillsCommand
|
|
20368
21599
|
});
|
|
20369
|
-
function
|
|
21600
|
+
function parseArgs12(args2) {
|
|
20370
21601
|
let connectionId;
|
|
20371
21602
|
const idx = args2.indexOf("--connection-id");
|
|
20372
21603
|
if (idx !== -1 && args2[idx + 1]) {
|
|
@@ -20389,7 +21620,7 @@ function printSyncResults(response) {
|
|
|
20389
21620
|
}
|
|
20390
21621
|
async function syncSkillsCommand(args2) {
|
|
20391
21622
|
const hubId = resolveActiveHubId(args2);
|
|
20392
|
-
const { connectionId } =
|
|
21623
|
+
const { connectionId } = parseArgs12(args2);
|
|
20393
21624
|
requireRepoConfig();
|
|
20394
21625
|
const { config, accessToken } = await requireAuth();
|
|
20395
21626
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
@@ -20414,10 +21645,10 @@ var init_sync_skills = __esm({
|
|
|
20414
21645
|
// src/commands/sync-mcp.ts
|
|
20415
21646
|
var sync_mcp_exports = {};
|
|
20416
21647
|
__export(sync_mcp_exports, {
|
|
20417
|
-
parseArgs: () =>
|
|
21648
|
+
parseArgs: () => parseArgs13,
|
|
20418
21649
|
syncMcpCommand: () => syncMcpCommand
|
|
20419
21650
|
});
|
|
20420
|
-
function
|
|
21651
|
+
function parseArgs13(args2) {
|
|
20421
21652
|
let connection;
|
|
20422
21653
|
let check = false;
|
|
20423
21654
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -20432,7 +21663,7 @@ function parseArgs12(args2) {
|
|
|
20432
21663
|
}
|
|
20433
21664
|
async function syncMcpCommand(args2) {
|
|
20434
21665
|
const hubId = resolveActiveHubId(args2);
|
|
20435
|
-
const { connection, check } =
|
|
21666
|
+
const { connection, check } = parseArgs13(args2);
|
|
20436
21667
|
if (!connection) {
|
|
20437
21668
|
console.error("Usage: wayai sync-mcp --connection <name> [--hub <uuid|folder-name>] [--check]");
|
|
20438
21669
|
console.error("");
|
|
@@ -20711,8 +21942,8 @@ function installEvalSignalHandlers(input) {
|
|
|
20711
21942
|
let signalCount = 0;
|
|
20712
21943
|
let disposed = false;
|
|
20713
21944
|
let settle;
|
|
20714
|
-
const settled = new Promise((
|
|
20715
|
-
settle =
|
|
21945
|
+
const settled = new Promise((resolve7) => {
|
|
21946
|
+
settle = resolve7;
|
|
20716
21947
|
});
|
|
20717
21948
|
const listeners = /* @__PURE__ */ new Map();
|
|
20718
21949
|
const dispose = () => {
|
|
@@ -21062,7 +22293,7 @@ Timeout after ${timeoutSeconds}s${queuedSeconds > 0 ? ` (${queuedSeconds}s of it
|
|
|
21062
22293
|
process.exit(1);
|
|
21063
22294
|
}
|
|
21064
22295
|
function sleep(ms) {
|
|
21065
|
-
return new Promise((
|
|
22296
|
+
return new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
21066
22297
|
}
|
|
21067
22298
|
function parseRunNumbers(raw) {
|
|
21068
22299
|
if (!raw || raw.startsWith("--")) {
|
|
@@ -21332,15 +22563,15 @@ var eval_capture_exports = {};
|
|
|
21332
22563
|
__export(eval_capture_exports, {
|
|
21333
22564
|
evalCaptureCommand: () => evalCaptureCommand
|
|
21334
22565
|
});
|
|
21335
|
-
import * as
|
|
21336
|
-
import * as
|
|
21337
|
-
import * as
|
|
22566
|
+
import * as fs24 from "fs";
|
|
22567
|
+
import * as path31 from "path";
|
|
22568
|
+
import * as yaml11 from "js-yaml";
|
|
21338
22569
|
function isValidSetName(name) {
|
|
21339
22570
|
if (name.length === 0 || name === "." || name === "..") return false;
|
|
21340
22571
|
if (name.startsWith(".")) return false;
|
|
21341
22572
|
return !/[\/\\\0]/.test(name);
|
|
21342
22573
|
}
|
|
21343
|
-
function
|
|
22574
|
+
function parseArgs14(args2) {
|
|
21344
22575
|
if (args2.length === 0 || args2[0].startsWith("-")) {
|
|
21345
22576
|
console.error("Usage: wayai eval capture <conversation_id> [--set <name>] [--name <eval_name>] [--instructions <text>]");
|
|
21346
22577
|
process.exit(1);
|
|
@@ -21386,7 +22617,7 @@ function parseArgs13(args2) {
|
|
|
21386
22617
|
}
|
|
21387
22618
|
async function evalCaptureCommand(args2) {
|
|
21388
22619
|
const hubId = resolveActiveHubId(args2);
|
|
21389
|
-
const parsed =
|
|
22620
|
+
const parsed = parseArgs14(args2);
|
|
21390
22621
|
const { config, accessToken } = await requireAuth();
|
|
21391
22622
|
requireRepoConfig();
|
|
21392
22623
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
@@ -21399,15 +22630,15 @@ async function evalCaptureCommand(args2) {
|
|
|
21399
22630
|
const setFolderName = targetSetName;
|
|
21400
22631
|
const scenarioName = parsed.evalName ?? `Capture ${parsed.conversationId.slice(0, 8)}`;
|
|
21401
22632
|
const slug = slugify(scenarioName);
|
|
21402
|
-
const evalsDir =
|
|
21403
|
-
const targetDir =
|
|
21404
|
-
const targetPath =
|
|
21405
|
-
if (!targetPath.startsWith(evalsDir +
|
|
21406
|
-
console.error(`Resolved path "${
|
|
22633
|
+
const evalsDir = path31.join(hubFolder, "evals");
|
|
22634
|
+
const targetDir = path31.join(evalsDir, setFolderName);
|
|
22635
|
+
const targetPath = path31.join(targetDir, `${slug}.yaml`);
|
|
22636
|
+
if (!targetPath.startsWith(evalsDir + path31.sep)) {
|
|
22637
|
+
console.error(`Resolved path "${path31.relative(hubFolder, targetPath)}" escapes evals/. Aborting.`);
|
|
21407
22638
|
process.exit(1);
|
|
21408
22639
|
}
|
|
21409
|
-
if (
|
|
21410
|
-
console.error(`File already exists: ${
|
|
22640
|
+
if (fs24.existsSync(targetPath)) {
|
|
22641
|
+
console.error(`File already exists: ${path31.relative(hubFolder, targetPath)}. Use --name to choose a different name.`);
|
|
21411
22642
|
process.exit(1);
|
|
21412
22643
|
}
|
|
21413
22644
|
console.log("Resolving scenario set...");
|
|
@@ -21439,9 +22670,9 @@ async function evalCaptureCommand(args2) {
|
|
|
21439
22670
|
...captured.evaluator_instructions ? { evaluator_instructions: captured.evaluator_instructions } : {}
|
|
21440
22671
|
};
|
|
21441
22672
|
const yamlObj = buildEvalYamlObject(evalEntry, slug);
|
|
21442
|
-
|
|
21443
|
-
|
|
21444
|
-
const relPath =
|
|
22673
|
+
fs24.mkdirSync(targetDir, { recursive: true });
|
|
22674
|
+
fs24.writeFileSync(targetPath, yaml11.dump(yamlObj, YAML_DUMP_OPTIONS), "utf-8");
|
|
22675
|
+
const relPath = path31.relative(process.cwd(), targetPath);
|
|
21445
22676
|
console.log(`
|
|
21446
22677
|
Wrote ${relPath}`);
|
|
21447
22678
|
console.log("Run `wayai pull` to refresh the agent display name, then commit. The scenario is already on the platform.");
|
|
@@ -21463,7 +22694,7 @@ var journey_capture_exports = {};
|
|
|
21463
22694
|
__export(journey_capture_exports, {
|
|
21464
22695
|
journeyCaptureCommand: () => journeyCaptureCommand
|
|
21465
22696
|
});
|
|
21466
|
-
function
|
|
22697
|
+
function parseArgs15(args2) {
|
|
21467
22698
|
if (args2.length === 0 || args2[0].startsWith("-")) {
|
|
21468
22699
|
console.error("Usage: wayai eval journey capture <conversation_id> [--name <journey_name>] [--instructions <text>]");
|
|
21469
22700
|
process.exit(1);
|
|
@@ -21498,7 +22729,7 @@ function parseArgs14(args2) {
|
|
|
21498
22729
|
}
|
|
21499
22730
|
async function journeyCaptureCommand(args2) {
|
|
21500
22731
|
const hubId = resolveActiveHubId(args2);
|
|
21501
|
-
const parsed =
|
|
22732
|
+
const parsed = parseArgs15(args2);
|
|
21502
22733
|
const { config, accessToken } = await requireAuth();
|
|
21503
22734
|
requireRepoConfig();
|
|
21504
22735
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
@@ -22426,9 +23657,9 @@ var init_credential_utils = __esm({
|
|
|
22426
23657
|
var create_credential_exports = {};
|
|
22427
23658
|
__export(create_credential_exports, {
|
|
22428
23659
|
createCredentialCommand: () => createCredentialCommand,
|
|
22429
|
-
parseArgs: () =>
|
|
23660
|
+
parseArgs: () => parseArgs16
|
|
22430
23661
|
});
|
|
22431
|
-
function
|
|
23662
|
+
function parseArgs16(args2) {
|
|
22432
23663
|
let name;
|
|
22433
23664
|
let type;
|
|
22434
23665
|
let orgId;
|
|
@@ -22456,7 +23687,7 @@ function parseArgs15(args2) {
|
|
|
22456
23687
|
return { name, type, orgId, description, tags: splitTagRefs(tags), environment, stdin };
|
|
22457
23688
|
}
|
|
22458
23689
|
async function createCredentialCommand(args2) {
|
|
22459
|
-
const parsed =
|
|
23690
|
+
const parsed = parseArgs16(args2);
|
|
22460
23691
|
if (!parsed.name) {
|
|
22461
23692
|
console.error("Missing required flag: --name <credential-name>");
|
|
22462
23693
|
console.error('Usage: wayai create-credential --name "openai-key" --type "Bearer Token"');
|
|
@@ -22563,10 +23794,10 @@ var init_create_credential = __esm({
|
|
|
22563
23794
|
// src/commands/update-credential.ts
|
|
22564
23795
|
var update_credential_exports = {};
|
|
22565
23796
|
__export(update_credential_exports, {
|
|
22566
|
-
parseArgs: () =>
|
|
23797
|
+
parseArgs: () => parseArgs17,
|
|
22567
23798
|
updateCredentialCommand: () => updateCredentialCommand
|
|
22568
23799
|
});
|
|
22569
|
-
function
|
|
23800
|
+
function parseArgs17(args2) {
|
|
22570
23801
|
let name;
|
|
22571
23802
|
let rename;
|
|
22572
23803
|
let orgId;
|
|
@@ -22599,7 +23830,7 @@ function parseArgs16(args2) {
|
|
|
22599
23830
|
return { name, rename, orgId, description, tags: splitTagRefs(tags), hasTagFlag, environment, stdin, secretPrompt };
|
|
22600
23831
|
}
|
|
22601
23832
|
async function updateCredentialCommand(args2) {
|
|
22602
|
-
const parsed =
|
|
23833
|
+
const parsed = parseArgs17(args2);
|
|
22603
23834
|
if (!parsed.name) {
|
|
22604
23835
|
console.error("Missing required flag: --name <credential-name>");
|
|
22605
23836
|
console.error('Usage: wayai update-credential --name "my-key" --stdin');
|
|
@@ -22712,10 +23943,10 @@ var init_update_credential = __esm({
|
|
|
22712
23943
|
// src/commands/set-connection-credential.ts
|
|
22713
23944
|
var set_connection_credential_exports = {};
|
|
22714
23945
|
__export(set_connection_credential_exports, {
|
|
22715
|
-
parseArgs: () =>
|
|
23946
|
+
parseArgs: () => parseArgs18,
|
|
22716
23947
|
setConnectionCredentialCommand: () => setConnectionCredentialCommand
|
|
22717
23948
|
});
|
|
22718
|
-
function
|
|
23949
|
+
function parseArgs18(args2) {
|
|
22719
23950
|
let connection;
|
|
22720
23951
|
let orgCredential;
|
|
22721
23952
|
let field;
|
|
@@ -22738,7 +23969,7 @@ function usage2(msg) {
|
|
|
22738
23969
|
}
|
|
22739
23970
|
async function setConnectionCredentialCommand(args2) {
|
|
22740
23971
|
const hubId = resolveActiveHubId(args2);
|
|
22741
|
-
const parsed =
|
|
23972
|
+
const parsed = parseArgs18(args2);
|
|
22742
23973
|
if (!parsed.connection) usage2("Missing required flag: --connection <name|id>");
|
|
22743
23974
|
const orgMode = !!parsed.orgCredential;
|
|
22744
23975
|
const directMode = !!parsed.field;
|
|
@@ -22807,23 +24038,23 @@ var init_set_connection_credential = __esm({
|
|
|
22807
24038
|
});
|
|
22808
24039
|
|
|
22809
24040
|
// src/lib/org-workspace.ts
|
|
22810
|
-
import * as
|
|
22811
|
-
import * as
|
|
22812
|
-
import * as
|
|
24041
|
+
import * as fs25 from "fs";
|
|
24042
|
+
import * as path32 from "path";
|
|
24043
|
+
import * as yaml12 from "js-yaml";
|
|
22813
24044
|
function getOrgDir(gitRoot) {
|
|
22814
24045
|
return resolveLayout(gitRoot).orgDir;
|
|
22815
24046
|
}
|
|
22816
24047
|
function orgManifestExists(orgDir) {
|
|
22817
|
-
return
|
|
24048
|
+
return fs25.existsSync(path32.join(orgDir, ORG_MANIFEST_NAME));
|
|
22818
24049
|
}
|
|
22819
24050
|
function parseOrgResources(orgDir) {
|
|
22820
|
-
const manifestPath =
|
|
24051
|
+
const manifestPath = path32.join(orgDir, ORG_MANIFEST_NAME);
|
|
22821
24052
|
let manifest = {};
|
|
22822
|
-
if (
|
|
22823
|
-
manifest =
|
|
24053
|
+
if (fs25.existsSync(manifestPath)) {
|
|
24054
|
+
manifest = yaml12.load(fs25.readFileSync(manifestPath, "utf-8")) ?? {};
|
|
22824
24055
|
}
|
|
22825
24056
|
const rawResources = Array.isArray(manifest.resources) ? manifest.resources : [];
|
|
22826
|
-
const resourcesDir =
|
|
24057
|
+
const resourcesDir = path32.join(orgDir, "resources");
|
|
22827
24058
|
const resources = rawResources.map((res) => {
|
|
22828
24059
|
const resource = { name: res.name };
|
|
22829
24060
|
if (res.id) resource.id = res.id;
|
|
@@ -22835,8 +24066,8 @@ function parseOrgResources(orgDir) {
|
|
|
22835
24066
|
if (res.environment) resource.environment = res.environment;
|
|
22836
24067
|
if (Array.isArray(res.tags)) resource.tags = res.tags;
|
|
22837
24068
|
if (Array.isArray(res.folders)) resource.folders = res.folders;
|
|
22838
|
-
const resDir =
|
|
22839
|
-
if (
|
|
24069
|
+
const resDir = path32.join(resourcesDir, slugify(resource.name));
|
|
24070
|
+
if (fs25.existsSync(resDir)) {
|
|
22840
24071
|
const files = scanResourceFiles(resDir, "");
|
|
22841
24072
|
if (files.length > 0) resource.files = files;
|
|
22842
24073
|
}
|
|
@@ -22845,28 +24076,28 @@ function parseOrgResources(orgDir) {
|
|
|
22845
24076
|
return { version: 1, resources };
|
|
22846
24077
|
}
|
|
22847
24078
|
function writeOrgResources(orgDir, payload) {
|
|
22848
|
-
|
|
24079
|
+
fs25.mkdirSync(orgDir, { recursive: true });
|
|
22849
24080
|
const resources = payload.resources ?? [];
|
|
22850
24081
|
const manifestResources = resources.map((r) => {
|
|
22851
24082
|
const { files: _files, ...rest } = r;
|
|
22852
24083
|
return rest;
|
|
22853
24084
|
});
|
|
22854
|
-
|
|
22855
|
-
|
|
22856
|
-
|
|
24085
|
+
fs25.writeFileSync(
|
|
24086
|
+
path32.join(orgDir, ORG_MANIFEST_NAME),
|
|
24087
|
+
yaml12.dump({ version: 1, resources: manifestResources }, YAML_DUMP_OPTIONS),
|
|
22857
24088
|
"utf-8"
|
|
22858
24089
|
);
|
|
22859
|
-
const resourcesDir =
|
|
24090
|
+
const resourcesDir = path32.join(orgDir, "resources");
|
|
22860
24091
|
const currentSlugs = /* @__PURE__ */ new Set();
|
|
22861
24092
|
for (const resource of resources) {
|
|
22862
24093
|
const resSlug = slugify(resource.name);
|
|
22863
24094
|
currentSlugs.add(resSlug);
|
|
22864
|
-
writeResourceFileTree(
|
|
24095
|
+
writeResourceFileTree(path32.join(resourcesDir, resSlug), resource.files || [], orgDir);
|
|
22865
24096
|
}
|
|
22866
|
-
if (
|
|
22867
|
-
for (const entry of
|
|
24097
|
+
if (fs25.existsSync(resourcesDir)) {
|
|
24098
|
+
for (const entry of fs25.readdirSync(resourcesDir, { withFileTypes: true })) {
|
|
22868
24099
|
if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
|
|
22869
|
-
|
|
24100
|
+
fs25.rmSync(path32.join(resourcesDir, entry.name), { recursive: true, force: true });
|
|
22870
24101
|
}
|
|
22871
24102
|
}
|
|
22872
24103
|
}
|
|
@@ -22875,7 +24106,7 @@ async function downloadOrgBinaryFiles(orgDir, payload) {
|
|
|
22875
24106
|
let count = 0;
|
|
22876
24107
|
for (const resource of payload.resources ?? []) {
|
|
22877
24108
|
if (!resource.files) continue;
|
|
22878
|
-
const resDir =
|
|
24109
|
+
const resDir = path32.join(orgDir, "resources", slugify(resource.name));
|
|
22879
24110
|
count += await downloadBinaryFiles(resDir, resource.files, orgDir);
|
|
22880
24111
|
}
|
|
22881
24112
|
if (count > 0) console.log(`Downloaded ${count} binary resource file(s).`);
|
|
@@ -23063,9 +24294,9 @@ var init_org = __esm({
|
|
|
23063
24294
|
var list_exports = {};
|
|
23064
24295
|
__export(list_exports, {
|
|
23065
24296
|
listCommand: () => listCommand,
|
|
23066
|
-
parseArgs: () =>
|
|
24297
|
+
parseArgs: () => parseArgs19
|
|
23067
24298
|
});
|
|
23068
|
-
function
|
|
24299
|
+
function parseArgs19(args2) {
|
|
23069
24300
|
let orgId;
|
|
23070
24301
|
let json = false;
|
|
23071
24302
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -23078,7 +24309,7 @@ function parseArgs18(args2) {
|
|
|
23078
24309
|
return { orgId, json };
|
|
23079
24310
|
}
|
|
23080
24311
|
async function listCommand(args2) {
|
|
23081
|
-
const { orgId, json } =
|
|
24312
|
+
const { orgId, json } = parseArgs19(args2);
|
|
23082
24313
|
const { config, accessToken } = await requireAuth();
|
|
23083
24314
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
23084
24315
|
const { organizations } = await client.organizations();
|
|
@@ -23171,8 +24402,8 @@ var init_report_edit_args = __esm({
|
|
|
23171
24402
|
});
|
|
23172
24403
|
|
|
23173
24404
|
// src/lib/file-map.ts
|
|
23174
|
-
import * as
|
|
23175
|
-
import * as
|
|
24405
|
+
import * as fs26 from "fs";
|
|
24406
|
+
import * as path33 from "path";
|
|
23176
24407
|
function isSafeRelPath(rel) {
|
|
23177
24408
|
if (rel.length === 0 || rel.length > 300) return false;
|
|
23178
24409
|
if (rel.startsWith("/") || rel.includes("\\")) return false;
|
|
@@ -23187,9 +24418,9 @@ function writeFileMap(targetDir, files) {
|
|
|
23187
24418
|
if (!isSafeRelPath(rel)) {
|
|
23188
24419
|
throw new Error(`Refusing to write unsafe path: ${rel}`);
|
|
23189
24420
|
}
|
|
23190
|
-
const abs =
|
|
23191
|
-
|
|
23192
|
-
|
|
24421
|
+
const abs = path33.join(targetDir, rel);
|
|
24422
|
+
fs26.mkdirSync(path33.dirname(abs), { recursive: true });
|
|
24423
|
+
fs26.writeFileSync(abs, body, "utf-8");
|
|
23193
24424
|
written.push(rel);
|
|
23194
24425
|
}
|
|
23195
24426
|
return written;
|
|
@@ -23205,8 +24436,8 @@ var admin_exports = {};
|
|
|
23205
24436
|
__export(admin_exports, {
|
|
23206
24437
|
adminCommand: () => adminCommand
|
|
23207
24438
|
});
|
|
23208
|
-
import * as
|
|
23209
|
-
import * as
|
|
24439
|
+
import * as fs27 from "fs";
|
|
24440
|
+
import * as path34 from "path";
|
|
23210
24441
|
async function adminCommand(args2) {
|
|
23211
24442
|
const [group, ...afterGroup] = args2;
|
|
23212
24443
|
if (!group) {
|
|
@@ -23507,7 +24738,7 @@ async function runArchiveRead(positional, flagArgs) {
|
|
|
23507
24738
|
exitOnApiError(err);
|
|
23508
24739
|
throw err;
|
|
23509
24740
|
}
|
|
23510
|
-
|
|
24741
|
+
fs27.writeFileSync(outPath, zip);
|
|
23511
24742
|
console.log(`Wrote ${zip.byteLength} bytes to ${outPath}`);
|
|
23512
24743
|
return;
|
|
23513
24744
|
}
|
|
@@ -23649,13 +24880,13 @@ async function runSkillInstall(positional) {
|
|
|
23649
24880
|
throw err;
|
|
23650
24881
|
}
|
|
23651
24882
|
const root = findGitRoot() ?? process.cwd();
|
|
23652
|
-
const present = HARNESS_SKILL_DIRS.filter((dir) =>
|
|
24883
|
+
const present = HARNESS_SKILL_DIRS.filter((dir) => fs27.existsSync(path34.join(root, dir)));
|
|
23653
24884
|
const targets = present.length > 0 ? present : HARNESS_SKILL_DIRS;
|
|
23654
24885
|
const fileCount = Object.keys(res.files).length;
|
|
23655
24886
|
const relDirs = targets.map((harness) => {
|
|
23656
|
-
const targetDir =
|
|
24887
|
+
const targetDir = path34.join(root, harness, "skills", name);
|
|
23657
24888
|
writeFileMap(targetDir, res.files);
|
|
23658
|
-
return `${
|
|
24889
|
+
return `${path34.relative(root, targetDir)}/`;
|
|
23659
24890
|
});
|
|
23660
24891
|
console.log(`Installed skill "${name}" (${fileCount} file${fileCount === 1 ? "" : "s"}) \u2192 ${relDirs.join(", ")}`);
|
|
23661
24892
|
console.log("Reload your agent (e.g. restart Claude Code) to pick up the skill.");
|
|
@@ -24480,24 +25711,9 @@ var init_admin = __esm({
|
|
|
24480
25711
|
init_skill_version();
|
|
24481
25712
|
init_file_map();
|
|
24482
25713
|
init_contracts();
|
|
24483
|
-
VALID_TYPES = dataExplorerDebugDoType.options;
|
|
24484
|
-
VALID_ANALYTICS_TABLES = dataExplorerDebugAnalyticsTable.options;
|
|
24485
|
-
VALID_NOTICE_SEVERITIES = ["critical", "warn", "info"];
|
|
24486
|
-
}
|
|
24487
|
-
});
|
|
24488
|
-
|
|
24489
|
-
// src/lib/terminal-output.ts
|
|
24490
|
-
import { stripVTControlCharacters } from "util";
|
|
24491
|
-
function sanitizeTerminalText(value) {
|
|
24492
|
-
const normalizedNewlines = value.replace(/\r\n?/g, "\n");
|
|
24493
|
-
return stripVTControlCharacters(normalizedNewlines).replace(
|
|
24494
|
-
/[\u0000-\u0009\u000b-\u001f\u007f-\u009f]/g,
|
|
24495
|
-
""
|
|
24496
|
-
);
|
|
24497
|
-
}
|
|
24498
|
-
var init_terminal_output = __esm({
|
|
24499
|
-
"src/lib/terminal-output.ts"() {
|
|
24500
|
-
"use strict";
|
|
25714
|
+
VALID_TYPES = dataExplorerDebugDoType.options;
|
|
25715
|
+
VALID_ANALYTICS_TABLES = dataExplorerDebugAnalyticsTable.options;
|
|
25716
|
+
VALID_NOTICE_SEVERITIES = ["critical", "warn", "info"];
|
|
24501
25717
|
}
|
|
24502
25718
|
});
|
|
24503
25719
|
|
|
@@ -24963,91 +26179,6 @@ var init_update = __esm({
|
|
|
24963
26179
|
}
|
|
24964
26180
|
});
|
|
24965
26181
|
|
|
24966
|
-
// src/data/org-context.ts
|
|
24967
|
-
function setDataOrgOverride(orgId) {
|
|
24968
|
-
override = orgId;
|
|
24969
|
-
}
|
|
24970
|
-
function getDataOrgOverride() {
|
|
24971
|
-
return override;
|
|
24972
|
-
}
|
|
24973
|
-
var override;
|
|
24974
|
-
var init_org_context = __esm({
|
|
24975
|
-
"src/data/org-context.ts"() {
|
|
24976
|
-
"use strict";
|
|
24977
|
-
}
|
|
24978
|
-
});
|
|
24979
|
-
|
|
24980
|
-
// src/data/client.ts
|
|
24981
|
-
async function createDataClient(orgId) {
|
|
24982
|
-
const { config, accessToken } = await requireAuth();
|
|
24983
|
-
const api = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
24984
|
-
const selected = orgId ?? getDataOrgOverride();
|
|
24985
|
-
if (selected !== void 0 && !UUID_RE2.test(selected)) {
|
|
24986
|
-
throw expected(`Invalid --org: ${JSON.stringify(selected)}. Expected an organization UUID.`);
|
|
24987
|
-
}
|
|
24988
|
-
const org = selected ?? readRepoConfig()?.organization_id;
|
|
24989
|
-
return {
|
|
24990
|
-
async request(method, path31, body) {
|
|
24991
|
-
const envelope = await api.dataRequest(method, path31, body, org);
|
|
24992
|
-
return envelope.data;
|
|
24993
|
-
},
|
|
24994
|
-
async collectPages(makePath) {
|
|
24995
|
-
const all = [];
|
|
24996
|
-
const seen = /* @__PURE__ */ new Set();
|
|
24997
|
-
let cursor;
|
|
24998
|
-
for (let page = 0; page < MAX_PAGES; page++) {
|
|
24999
|
-
const { data, meta } = await api.dataRequest("GET", makePath(cursor), void 0, org);
|
|
25000
|
-
for (const row of data ?? []) all.push(row);
|
|
25001
|
-
cursor = meta?.has_more ? meta.cursor : void 0;
|
|
25002
|
-
if (cursor === void 0) break;
|
|
25003
|
-
if (seen.has(cursor)) break;
|
|
25004
|
-
seen.add(cursor);
|
|
25005
|
-
}
|
|
25006
|
-
return all;
|
|
25007
|
-
},
|
|
25008
|
-
async upload(v1Path, bytes, contentType, headers) {
|
|
25009
|
-
const envelope = await api.dataUpload(v1Path, bytes, contentType, org, headers);
|
|
25010
|
-
return envelope.data;
|
|
25011
|
-
},
|
|
25012
|
-
download(v1Path) {
|
|
25013
|
-
return api.dataDownload(v1Path, org);
|
|
25014
|
-
},
|
|
25015
|
-
url(v1Path) {
|
|
25016
|
-
return api.dataUrl(v1Path, org);
|
|
25017
|
-
}
|
|
25018
|
-
};
|
|
25019
|
-
}
|
|
25020
|
-
function dataErrorEnvelope(err) {
|
|
25021
|
-
if (!(err instanceof ApiError)) return null;
|
|
25022
|
-
try {
|
|
25023
|
-
const parsed = JSON.parse(err.body);
|
|
25024
|
-
return parsed?.error ?? null;
|
|
25025
|
-
} catch {
|
|
25026
|
-
return null;
|
|
25027
|
-
}
|
|
25028
|
-
}
|
|
25029
|
-
function dataErrorCode(err) {
|
|
25030
|
-
const code = dataErrorEnvelope(err)?.code;
|
|
25031
|
-
return typeof code === "string" && code ? code : null;
|
|
25032
|
-
}
|
|
25033
|
-
function dataErrorDetails(err) {
|
|
25034
|
-
const details = dataErrorEnvelope(err)?.details;
|
|
25035
|
-
return details && typeof details === "object" ? details : void 0;
|
|
25036
|
-
}
|
|
25037
|
-
var MAX_PAGES;
|
|
25038
|
-
var init_client = __esm({
|
|
25039
|
-
"src/data/client.ts"() {
|
|
25040
|
-
"use strict";
|
|
25041
|
-
init_auth();
|
|
25042
|
-
init_api_client();
|
|
25043
|
-
init_repo_config();
|
|
25044
|
-
init_utils();
|
|
25045
|
-
init_expected();
|
|
25046
|
-
init_org_context();
|
|
25047
|
-
MAX_PAGES = 1e3;
|
|
25048
|
-
}
|
|
25049
|
-
});
|
|
25050
|
-
|
|
25051
26182
|
// src/data/output.ts
|
|
25052
26183
|
function printOutput(data, format) {
|
|
25053
26184
|
if (format === "json") {
|
|
@@ -25148,140 +26279,6 @@ var init_output = __esm({
|
|
|
25148
26279
|
}
|
|
25149
26280
|
});
|
|
25150
26281
|
|
|
25151
|
-
// src/lib/base-id.ts
|
|
25152
|
-
function isValidBaseId(id) {
|
|
25153
|
-
return BASE_ID_RE.test(id);
|
|
25154
|
-
}
|
|
25155
|
-
var BASE_ID_RE;
|
|
25156
|
-
var init_base_id = __esm({
|
|
25157
|
-
"src/lib/base-id.ts"() {
|
|
25158
|
-
"use strict";
|
|
25159
|
-
BASE_ID_RE = /^(?!\.\.?$)[A-Za-z0-9._-]{1,256}$/;
|
|
25160
|
-
}
|
|
25161
|
-
});
|
|
25162
|
-
|
|
25163
|
-
// src/data/helpers.ts
|
|
25164
|
-
import { readFileSync as readFileSync19 } from "fs";
|
|
25165
|
-
function pathSegment(id, label = "id") {
|
|
25166
|
-
if (!isValidBaseId(id)) {
|
|
25167
|
-
throw expected(
|
|
25168
|
-
`Invalid ${label}: ${JSON.stringify(id)}. Ids are slugs \u2014 letters, digits, dot, dash and underscore only.`
|
|
25169
|
-
);
|
|
25170
|
-
}
|
|
25171
|
-
return encodeURIComponent(id);
|
|
25172
|
-
}
|
|
25173
|
-
function foreignSegment(value, label = "id") {
|
|
25174
|
-
if (value === "." || value === "..") {
|
|
25175
|
-
throw expected(`Invalid ${label}: ${JSON.stringify(value)} is a path traversal segment.`);
|
|
25176
|
-
}
|
|
25177
|
-
return encodeURIComponent(value);
|
|
25178
|
-
}
|
|
25179
|
-
function pathSegments(value, label = "path") {
|
|
25180
|
-
return value.split("/").map((segment) => foreignSegment(segment, label)).join("/");
|
|
25181
|
-
}
|
|
25182
|
-
function parseData(data, flag) {
|
|
25183
|
-
const prefix = flag ? `${flag}: ` : "";
|
|
25184
|
-
const source = data.startsWith("@") ? data.slice(1) : void 0;
|
|
25185
|
-
let text = data;
|
|
25186
|
-
if (source !== void 0) {
|
|
25187
|
-
try {
|
|
25188
|
-
text = readFileSync19(source, "utf-8");
|
|
25189
|
-
} catch (e) {
|
|
25190
|
-
throw expected(`${prefix}${source}: ${e instanceof Error ? e.message : "could not be read"}`);
|
|
25191
|
-
}
|
|
25192
|
-
}
|
|
25193
|
-
try {
|
|
25194
|
-
return JSON.parse(text);
|
|
25195
|
-
} catch (e) {
|
|
25196
|
-
const where = source !== void 0 ? ` in ${source}` : "";
|
|
25197
|
-
throw expected(`${prefix}invalid JSON${where}: ${e instanceof Error ? e.message : String(e)}`);
|
|
25198
|
-
}
|
|
25199
|
-
}
|
|
25200
|
-
function toolsetMcpUrl(slug) {
|
|
25201
|
-
return `https://data-mcp.wayai.pro/t/${slug}/mcp`;
|
|
25202
|
-
}
|
|
25203
|
-
function globals(cmd) {
|
|
25204
|
-
let namespace = cmd;
|
|
25205
|
-
while (namespace.parent?.parent) namespace = namespace.parent;
|
|
25206
|
-
return namespace.opts();
|
|
25207
|
-
}
|
|
25208
|
-
function withBaseOption(command2) {
|
|
25209
|
-
return command2.option("--base <id>", "Base id (or set WAYAI_BASE)");
|
|
25210
|
-
}
|
|
25211
|
-
function baseOptionHolder(cmd) {
|
|
25212
|
-
for (let c = cmd; c; c = c.parent ?? void 0) {
|
|
25213
|
-
if (c.options.some((o) => o.long === "--base")) return c;
|
|
25214
|
-
}
|
|
25215
|
-
return void 0;
|
|
25216
|
-
}
|
|
25217
|
-
function findBase(cmd) {
|
|
25218
|
-
return baseOptionHolder(cmd)?.opts()?.base;
|
|
25219
|
-
}
|
|
25220
|
-
function requireBase(cmd) {
|
|
25221
|
-
const base = findBase(cmd) ?? process.env.WAYAI_BASE ?? "";
|
|
25222
|
-
if (base) return base;
|
|
25223
|
-
console.error("Error: --base is required (or set WAYAI_BASE)");
|
|
25224
|
-
return process.exit(1);
|
|
25225
|
-
}
|
|
25226
|
-
function outputFormat(cmd) {
|
|
25227
|
-
const opts = globals(cmd);
|
|
25228
|
-
return opts.json || opts.output === "json" ? "json" : "table";
|
|
25229
|
-
}
|
|
25230
|
-
function historyQuery(opts) {
|
|
25231
|
-
const qs = new URLSearchParams();
|
|
25232
|
-
if (opts.limit) qs.set("limit", opts.limit);
|
|
25233
|
-
if (opts.offset) qs.set("offset", opts.offset);
|
|
25234
|
-
if (opts.diff) qs.set("diff", "true");
|
|
25235
|
-
const q = qs.toString();
|
|
25236
|
-
return q ? `?${q}` : "";
|
|
25237
|
-
}
|
|
25238
|
-
function splitList(value) {
|
|
25239
|
-
return value.split(",").map((v) => v.trim()).filter((v) => v.length > 0);
|
|
25240
|
-
}
|
|
25241
|
-
function parseByteCount(flag, value) {
|
|
25242
|
-
const n = Number(value);
|
|
25243
|
-
if (!Number.isInteger(n) || n < 0) {
|
|
25244
|
-
throw expected(`${flag} must be a whole number of bytes (0 = unlimited), not ${JSON.stringify(value)}.`);
|
|
25245
|
-
}
|
|
25246
|
-
return n;
|
|
25247
|
-
}
|
|
25248
|
-
async function readSecret(source, label) {
|
|
25249
|
-
const value = resolveSecretSource(source) === "stdin" ? (await readStdin()).trim() : (await promptSecret(`${label}: `)).trim();
|
|
25250
|
-
if (!value) throw expected(`${label} is required.`);
|
|
25251
|
-
return value;
|
|
25252
|
-
}
|
|
25253
|
-
function isInteractive() {
|
|
25254
|
-
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
25255
|
-
}
|
|
25256
|
-
function parseDuration(input, flag = "duration") {
|
|
25257
|
-
const match = DURATION_RE.exec(input.trim());
|
|
25258
|
-
const value = Number(match?.[1] ?? 0);
|
|
25259
|
-
const unit = match?.[2];
|
|
25260
|
-
const unitMs = unit ? DURATION_UNIT_MS[unit] : void 0;
|
|
25261
|
-
if (!unitMs || value <= 0) {
|
|
25262
|
-
throw expected(
|
|
25263
|
-
`Invalid ${flag} ${JSON.stringify(input)} \u2014 use <number><unit> with unit s/m/h/d (e.g. 10m, 2h, 30d).`
|
|
25264
|
-
);
|
|
25265
|
-
}
|
|
25266
|
-
return value * unitMs;
|
|
25267
|
-
}
|
|
25268
|
-
var DURATION_RE, DURATION_UNIT_MS;
|
|
25269
|
-
var init_helpers = __esm({
|
|
25270
|
-
"src/data/helpers.ts"() {
|
|
25271
|
-
"use strict";
|
|
25272
|
-
init_base_id();
|
|
25273
|
-
init_expected();
|
|
25274
|
-
init_utils();
|
|
25275
|
-
DURATION_RE = /^(\d+)([smhd])$/;
|
|
25276
|
-
DURATION_UNIT_MS = {
|
|
25277
|
-
s: 1e3,
|
|
25278
|
-
m: 6e4,
|
|
25279
|
-
h: 36e5,
|
|
25280
|
-
d: 864e5
|
|
25281
|
-
};
|
|
25282
|
-
}
|
|
25283
|
-
});
|
|
25284
|
-
|
|
25285
26282
|
// src/data/commands/actions.ts
|
|
25286
26283
|
import { Command } from "commander";
|
|
25287
26284
|
function buildActionsCommand() {
|
|
@@ -25355,7 +26352,7 @@ var init_actions = __esm({
|
|
|
25355
26352
|
|
|
25356
26353
|
// src/data/commands/attachments.ts
|
|
25357
26354
|
import { Command as Command2 } from "commander";
|
|
25358
|
-
import { readFileSync as
|
|
26355
|
+
import { readFileSync as readFileSync21 } from "fs";
|
|
25359
26356
|
function findAttachmentByFilename(attachments, filename) {
|
|
25360
26357
|
return attachments.find((a) => a.key.endsWith(`/${filename}`)) ?? null;
|
|
25361
26358
|
}
|
|
@@ -25396,7 +26393,7 @@ function buildAttachmentsCommand() {
|
|
|
25396
26393
|
printOutput(data, outputFormat(this));
|
|
25397
26394
|
return;
|
|
25398
26395
|
}
|
|
25399
|
-
const body =
|
|
26396
|
+
const body = readFileSync21(opts.file);
|
|
25400
26397
|
await client.upload(uploadPathFrom(data?.upload_url), body, opts.contentType);
|
|
25401
26398
|
printOutput({ ...data, uploaded: true }, outputFormat(this));
|
|
25402
26399
|
});
|
|
@@ -25876,16 +26873,16 @@ var init_providers = __esm({
|
|
|
25876
26873
|
|
|
25877
26874
|
// src/data/commands/report.ts
|
|
25878
26875
|
import { Command as Command6 } from "commander";
|
|
25879
|
-
import { readFileSync as
|
|
25880
|
-
import { dirname as
|
|
26876
|
+
import { readFileSync as readFileSync22 } from "fs";
|
|
26877
|
+
import { dirname as dirname11, join as join32 } from "path";
|
|
25881
26878
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
25882
26879
|
function resolveCliVersion() {
|
|
25883
26880
|
for (const candidate of [
|
|
25884
|
-
|
|
25885
|
-
|
|
26881
|
+
join32(here, "..", "package.json"),
|
|
26882
|
+
join32(here, "..", "..", "..", "package.json")
|
|
25886
26883
|
]) {
|
|
25887
26884
|
try {
|
|
25888
|
-
const version = JSON.parse(
|
|
26885
|
+
const version = JSON.parse(readFileSync22(candidate, "utf-8")).version;
|
|
25889
26886
|
if (typeof version === "string" && version) return version;
|
|
25890
26887
|
} catch {
|
|
25891
26888
|
}
|
|
@@ -26081,13 +27078,13 @@ var init_report2 = __esm({
|
|
|
26081
27078
|
init_terminal_output();
|
|
26082
27079
|
init_workspace();
|
|
26083
27080
|
init_skill_version();
|
|
26084
|
-
here =
|
|
27081
|
+
here = dirname11(fileURLToPath2(import.meta.url));
|
|
26085
27082
|
}
|
|
26086
27083
|
});
|
|
26087
27084
|
|
|
26088
27085
|
// src/data/commands/secrets.ts
|
|
26089
27086
|
import { Command as Command7 } from "commander";
|
|
26090
|
-
import { readFileSync as
|
|
27087
|
+
import { readFileSync as readFileSync23 } from "fs";
|
|
26091
27088
|
function withValueSourceOptions(cmd, what) {
|
|
26092
27089
|
return cmd.option(
|
|
26093
27090
|
"--file <path>",
|
|
@@ -26100,7 +27097,7 @@ async function resolveValue(opts, label) {
|
|
|
26100
27097
|
throw expected("--file cannot be combined with --value-stdin or --value-prompt \u2014 pass one.");
|
|
26101
27098
|
}
|
|
26102
27099
|
try {
|
|
26103
|
-
return
|
|
27100
|
+
return readFileSync23(opts.file).toString("base64");
|
|
26104
27101
|
} catch (e) {
|
|
26105
27102
|
throw expected(`--file ${opts.file}: ${e instanceof Error ? e.message : "could not be read"}`);
|
|
26106
27103
|
}
|
|
@@ -26197,7 +27194,7 @@ var init_secrets = __esm({
|
|
|
26197
27194
|
|
|
26198
27195
|
// src/data/commands/sql.ts
|
|
26199
27196
|
import { Command as Command8 } from "commander";
|
|
26200
|
-
import { readFileSync as
|
|
27197
|
+
import { readFileSync as readFileSync24 } from "fs";
|
|
26201
27198
|
function buildBasesSqlCommand() {
|
|
26202
27199
|
return withBaseOption(new Command8("sql")).description("Execute a read-only SQL query against base data").argument("[query]", "SQL query (SELECT only)").option("--file <path>", "Read SQL from a file instead of the argument").option(
|
|
26203
27200
|
"--param <kv...>",
|
|
@@ -26207,7 +27204,7 @@ function buildBasesSqlCommand() {
|
|
|
26207
27204
|
let query;
|
|
26208
27205
|
if (opts.file) {
|
|
26209
27206
|
try {
|
|
26210
|
-
query =
|
|
27207
|
+
query = readFileSync24(opts.file, "utf-8").trim();
|
|
26211
27208
|
} catch (e) {
|
|
26212
27209
|
throw expected(`--file ${opts.file}: ${e instanceof Error ? e.message : "could not be read"}`);
|
|
26213
27210
|
}
|
|
@@ -26342,16 +27339,16 @@ MCP URL: ${toolsetMcpUrl(slug)}`);
|
|
|
26342
27339
|
).option("--force", "Revoke even if the token appears to be in live use").action(async function(tokenId, opts) {
|
|
26343
27340
|
const client = await createDataClient();
|
|
26344
27341
|
const id = pathSegment(tokenId, "token id");
|
|
26345
|
-
const
|
|
27342
|
+
const path36 = (force) => `/v1/tokens/${id}${force ? "?force=true" : ""}`;
|
|
26346
27343
|
const format = outputFormat(this);
|
|
26347
27344
|
const revoked = (forced) => printOutput({ token_id: tokenId, revoked: true, forced }, format);
|
|
26348
27345
|
if (opts.force) {
|
|
26349
|
-
await client.request("DELETE",
|
|
27346
|
+
await client.request("DELETE", path36(true));
|
|
26350
27347
|
revoked(true);
|
|
26351
27348
|
return;
|
|
26352
27349
|
}
|
|
26353
27350
|
try {
|
|
26354
|
-
await client.request("DELETE",
|
|
27351
|
+
await client.request("DELETE", path36(false));
|
|
26355
27352
|
revoked(false);
|
|
26356
27353
|
} catch (err) {
|
|
26357
27354
|
if (!(err instanceof ApiError) || err.status !== 409 || dataErrorDetails(err)?.requires_force !== true) {
|
|
@@ -26366,7 +27363,7 @@ MCP URL: ${toolsetMcpUrl(slug)}`);
|
|
|
26366
27363
|
console.error("Aborted.");
|
|
26367
27364
|
return process.exit(1);
|
|
26368
27365
|
}
|
|
26369
|
-
await client.request("DELETE",
|
|
27366
|
+
await client.request("DELETE", path36(true));
|
|
26370
27367
|
revoked(true);
|
|
26371
27368
|
}
|
|
26372
27369
|
});
|
|
@@ -26485,39 +27482,12 @@ Output:
|
|
|
26485
27482
|
}
|
|
26486
27483
|
});
|
|
26487
27484
|
|
|
26488
|
-
// src/lib/base-binding.ts
|
|
26489
|
-
var binding2, getBaseBindingPath, readBaseBinding, writeBaseBinding, clearBaseBinding, autoBindBaseIfUnbound, assertBaseMatchesBinding, assertNoBindingBlocksBaseCreation;
|
|
26490
|
-
var init_base_binding = __esm({
|
|
26491
|
-
"src/lib/base-binding.ts"() {
|
|
26492
|
-
"use strict";
|
|
26493
|
-
init_base_id();
|
|
26494
|
-
init_worktree_binding();
|
|
26495
|
-
binding2 = createWorktreeBinding({
|
|
26496
|
-
filename: "wayai-base-binding",
|
|
26497
|
-
isValidId: isValidBaseId,
|
|
26498
|
-
noun: "base",
|
|
26499
|
-
idLabel: "base id (must be a slug)",
|
|
26500
|
-
unbindCommand: "wayai bases unbind",
|
|
26501
|
-
useCommand: "wayai bases use"
|
|
26502
|
-
});
|
|
26503
|
-
getBaseBindingPath = binding2.getBindingPath;
|
|
26504
|
-
readBaseBinding = binding2.readBinding;
|
|
26505
|
-
writeBaseBinding = binding2.writeBinding;
|
|
26506
|
-
clearBaseBinding = binding2.clearBinding;
|
|
26507
|
-
autoBindBaseIfUnbound = binding2.autoBindIfUnbound;
|
|
26508
|
-
assertBaseMatchesBinding = binding2.assertMatchesBinding;
|
|
26509
|
-
assertNoBindingBlocksBaseCreation = binding2.assertNoBindingBlocksCreation;
|
|
26510
|
-
}
|
|
26511
|
-
});
|
|
26512
|
-
|
|
26513
27485
|
// src/data/commands/bases.ts
|
|
26514
27486
|
import { Command as Command10 } from "commander";
|
|
26515
|
-
import * as
|
|
26516
|
-
|
|
26517
|
-
|
|
26518
|
-
|
|
26519
|
-
if (!cursor) return path31;
|
|
26520
|
-
return `${path31}${path31.includes("?") ? "&" : "?"}cursor=${encodeURIComponent(cursor)}`;
|
|
27487
|
+
import * as path35 from "path";
|
|
27488
|
+
function pageOf(path36, cursor) {
|
|
27489
|
+
if (!cursor) return path36;
|
|
27490
|
+
return `${path36}${path36.includes("?") ? "&" : "?"}cursor=${encodeURIComponent(cursor)}`;
|
|
26521
27491
|
}
|
|
26522
27492
|
function parseEnum(flag, value, allowed) {
|
|
26523
27493
|
if (value === void 0) return void 0;
|
|
@@ -26658,9 +27628,9 @@ function buildBasesCommand() {
|
|
|
26658
27628
|
});
|
|
26659
27629
|
bases.command("list-previews <origin-id>").description("List preview bases cloned from a base (production or preview)").action(async function(originId) {
|
|
26660
27630
|
const client = await createDataClient();
|
|
26661
|
-
const
|
|
27631
|
+
const path36 = `/v1/${pathSegment(originId, "origin base id")}/previews`;
|
|
26662
27632
|
printOutput(
|
|
26663
|
-
await client.collectPages((cursor) => pageOf(
|
|
27633
|
+
await client.collectPages((cursor) => pageOf(path36, cursor)),
|
|
26664
27634
|
outputFormat(this)
|
|
26665
27635
|
);
|
|
26666
27636
|
});
|
|
@@ -26693,9 +27663,9 @@ function buildBasesCommand() {
|
|
|
26693
27663
|
});
|
|
26694
27664
|
bases.command("promotions <production-id>").description("List promotion history for a production base").action(async function(productionId) {
|
|
26695
27665
|
const client = await createDataClient();
|
|
26696
|
-
const
|
|
27666
|
+
const path36 = `/v1/${pathSegment(productionId, "production base id")}/promotions`;
|
|
26697
27667
|
printOutput(
|
|
26698
|
-
await client.collectPages((cursor) => pageOf(
|
|
27668
|
+
await client.collectPages((cursor) => pageOf(path36, cursor)),
|
|
26699
27669
|
outputFormat(this)
|
|
26700
27670
|
);
|
|
26701
27671
|
});
|
|
@@ -26745,19 +27715,11 @@ function buildBasesCommand() {
|
|
|
26745
27715
|
}
|
|
26746
27716
|
function resolveSelectorToBaseId(selector) {
|
|
26747
27717
|
const gitRoot = findGitRoot();
|
|
26748
|
-
if (!gitRoot || selector.includes("/") || selector.includes(
|
|
27718
|
+
if (!gitRoot || selector.includes("/") || selector.includes(path35.sep)) return selector;
|
|
26749
27719
|
if (!isValidBaseId(selector)) return selector;
|
|
26750
|
-
const
|
|
26751
|
-
let meta;
|
|
26752
|
-
try {
|
|
26753
|
-
meta = yaml9.load(fs24.readFileSync(metaPath, "utf-8"));
|
|
26754
|
-
} catch {
|
|
26755
|
-
return selector;
|
|
26756
|
-
}
|
|
26757
|
-
const id = meta?.[BASE_ID_FIELD];
|
|
27720
|
+
const id = readBaseMeta(path35.join(resolveBasesDir(gitRoot), selector))?.base_id;
|
|
26758
27721
|
return typeof id === "string" && isValidBaseId(id) ? id : selector;
|
|
26759
27722
|
}
|
|
26760
|
-
var BASE_META_FILE, BASE_ID_FIELD;
|
|
26761
27723
|
var init_bases = __esm({
|
|
26762
27724
|
"src/data/commands/bases.ts"() {
|
|
26763
27725
|
"use strict";
|
|
@@ -26775,11 +27737,10 @@ var init_bases = __esm({
|
|
|
26775
27737
|
init_terminal_output();
|
|
26776
27738
|
init_workspace();
|
|
26777
27739
|
init_layout();
|
|
27740
|
+
init_base_workspace();
|
|
26778
27741
|
init_base_binding();
|
|
26779
27742
|
init_base_id();
|
|
26780
27743
|
init_expected();
|
|
26781
|
-
BASE_META_FILE = "base.yaml";
|
|
26782
|
-
BASE_ID_FIELD = "base_id";
|
|
26783
27744
|
}
|
|
26784
27745
|
});
|
|
26785
27746
|
|
|
@@ -26844,7 +27805,7 @@ var init_file_types = __esm({
|
|
|
26844
27805
|
// src/data/commands/files.ts
|
|
26845
27806
|
import { Command as Command12 } from "commander";
|
|
26846
27807
|
import { readFileSync as readFileSync25, writeFileSync as writeFileSync16 } from "fs";
|
|
26847
|
-
import { basename as
|
|
27808
|
+
import { basename as basename18 } from "path";
|
|
26848
27809
|
function renderFileDiff(fileType, filePath, from, to, d) {
|
|
26849
27810
|
console.log(sanitizeTerminalText(`${fileType}/${filePath}: v${from} \u2192 v${to}`));
|
|
26850
27811
|
const md = d.metadata_delta;
|
|
@@ -26876,7 +27837,7 @@ function renderFileDiff(fileType, filePath, from, to, d) {
|
|
|
26876
27837
|
}
|
|
26877
27838
|
function downloadTarget(remotePath, to) {
|
|
26878
27839
|
if (to) return to;
|
|
26879
|
-
const derived =
|
|
27840
|
+
const derived = basename18(remotePath);
|
|
26880
27841
|
if (derived === "" || derived === "." || derived === "..") {
|
|
26881
27842
|
throw expected(
|
|
26882
27843
|
`Cannot derive a local filename from "${remotePath}" \u2014 pass --to <local> to name it.`
|
|
@@ -27252,8 +28213,8 @@ function buildRecordsCommand() {
|
|
|
27252
28213
|
const body = { data: parseData(opts.data) };
|
|
27253
28214
|
if (opts.externalId) body.external_id = opts.externalId;
|
|
27254
28215
|
if (opts.externalSource) body.external_source = opts.externalSource;
|
|
27255
|
-
const
|
|
27256
|
-
printOutput(await client.request("PUT",
|
|
28216
|
+
const path36 = opts.id ? `/v1/${base}/records/${pathSegment(recordType2, "record_type")}/${pathSegment(opts.id, "--id")}` : `/v1/${base}/records/${pathSegment(recordType2, "record_type")}`;
|
|
28217
|
+
printOutput(await client.request("PUT", path36, body), outputFormat(this));
|
|
27257
28218
|
});
|
|
27258
28219
|
records.command("query <record_type>").description("List/search records: exact filters + fuzzy `search`, sorting, pagination").option(
|
|
27259
28220
|
"--external-source <source>",
|
|
@@ -27288,9 +28249,9 @@ function buildRecordsCommand() {
|
|
|
27288
28249
|
).action(async function(recordType2, id, opts) {
|
|
27289
28250
|
const base = pathSegment(requireBase(this), "--base");
|
|
27290
28251
|
const client = await createDataClient();
|
|
27291
|
-
let
|
|
27292
|
-
if (opts.externalSource)
|
|
27293
|
-
printOutput(await client.request("GET",
|
|
28252
|
+
let path36 = `/v1/${base}/records/${pathSegment(recordType2, "record_type")}/${recordKey(id, opts.externalSource)}`;
|
|
28253
|
+
if (opts.externalSource) path36 += `?external_source=${encodeURIComponent(opts.externalSource)}`;
|
|
28254
|
+
printOutput(await client.request("GET", path36), outputFormat(this));
|
|
27294
28255
|
});
|
|
27295
28256
|
records.command("delete <record_type> <id>").description(
|
|
27296
28257
|
"Delete a record by internal ID, or by external_id (pass --external-source to scope it)"
|
|
@@ -27304,11 +28265,11 @@ function buildRecordsCommand() {
|
|
|
27304
28265
|
}
|
|
27305
28266
|
const base = pathSegment(requireBase(this), "--base");
|
|
27306
28267
|
const client = await createDataClient();
|
|
27307
|
-
let
|
|
28268
|
+
let path36 = `/v1/${base}/records/${pathSegment(recordType2, "record_type")}/${recordKey(id, opts.externalSource)}`;
|
|
27308
28269
|
if (opts.externalSource) {
|
|
27309
|
-
|
|
28270
|
+
path36 += `?external_source=${encodeURIComponent(opts.externalSource)}&external_id=${encodeURIComponent(id)}`;
|
|
27310
28271
|
}
|
|
27311
|
-
await client.request("DELETE",
|
|
28272
|
+
await client.request("DELETE", path36);
|
|
27312
28273
|
console.log("Deleted");
|
|
27313
28274
|
});
|
|
27314
28275
|
records.command("history <id>").description(
|
|
@@ -27473,8 +28434,8 @@ function buildRelationshipsCommand() {
|
|
|
27473
28434
|
if (opts.data) body.data = parseData(opts.data);
|
|
27474
28435
|
const base = pathSegment(requireBase(this), "--base");
|
|
27475
28436
|
const client = await createDataClient();
|
|
27476
|
-
const
|
|
27477
|
-
printOutput(await client.request("PUT",
|
|
28437
|
+
const path36 = opts.id ? `/v1/${base}/relationships/${pathSegment(opts.id, "--id")}` : `/v1/${base}/relationships`;
|
|
28438
|
+
printOutput(await client.request("PUT", path36, body), outputFormat(this));
|
|
27478
28439
|
});
|
|
27479
28440
|
relationships.command("get <id>").description(
|
|
27480
28441
|
"Get a relationship by ID (or by its external key: pass the external_id with --rel-type)"
|
|
@@ -27707,8 +28668,8 @@ function buildToolsetsCommand() {
|
|
|
27707
28668
|
toolsets.command("get <slug>").description("Get a toolset").option("--resolved", "Include resolved record_type schemas").action(async function(slug, opts) {
|
|
27708
28669
|
const base = pathSegment(requireBase(this), "--base");
|
|
27709
28670
|
const client = await createDataClient();
|
|
27710
|
-
const
|
|
27711
|
-
printOutput(await client.request("GET",
|
|
28671
|
+
const path36 = opts.resolved ? `/v1/${base}/toolsets/${pathSegment(slug, "toolset slug")}/resolved` : `/v1/${base}/toolsets/${pathSegment(slug, "toolset slug")}`;
|
|
28672
|
+
printOutput(await client.request("GET", path36), outputFormat(this));
|
|
27712
28673
|
});
|
|
27713
28674
|
toolsets.command("list").description("List all toolsets").action(async function() {
|
|
27714
28675
|
const base = pathSegment(requireBase(this), "--base");
|
|
@@ -27943,7 +28904,7 @@ init_utils();
|
|
|
27943
28904
|
init_registry();
|
|
27944
28905
|
import { readFileSync as readFileSync26 } from "fs";
|
|
27945
28906
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
27946
|
-
import { dirname as
|
|
28907
|
+
import { dirname as dirname12, join as join34 } from "path";
|
|
27947
28908
|
|
|
27948
28909
|
// src/lib/version-refresh.ts
|
|
27949
28910
|
init_version_cache();
|
|
@@ -27951,7 +28912,7 @@ init_skill_version();
|
|
|
27951
28912
|
import { exec } from "child_process";
|
|
27952
28913
|
var REFRESH_TIMEOUT_MS = 1e4;
|
|
27953
28914
|
function refreshCliCache() {
|
|
27954
|
-
return new Promise((
|
|
28915
|
+
return new Promise((resolve7) => {
|
|
27955
28916
|
exec("npm view @wayai/cli version", { timeout: REFRESH_TIMEOUT_MS }, (err, stdout) => {
|
|
27956
28917
|
if (!err) {
|
|
27957
28918
|
const latest = stdout.trim();
|
|
@@ -27962,7 +28923,7 @@ function refreshCliCache() {
|
|
|
27962
28923
|
}
|
|
27963
28924
|
}
|
|
27964
28925
|
}
|
|
27965
|
-
|
|
28926
|
+
resolve7();
|
|
27966
28927
|
});
|
|
27967
28928
|
});
|
|
27968
28929
|
}
|
|
@@ -27988,8 +28949,8 @@ async function refreshSkillCache() {
|
|
|
27988
28949
|
}
|
|
27989
28950
|
async function refreshAdminSkillCache() {
|
|
27990
28951
|
let timer;
|
|
27991
|
-
const deadline = new Promise((
|
|
27992
|
-
timer = setTimeout(
|
|
28952
|
+
const deadline = new Promise((resolve7) => {
|
|
28953
|
+
timer = setTimeout(resolve7, REFRESH_TIMEOUT_MS);
|
|
27993
28954
|
});
|
|
27994
28955
|
await Promise.race([deadline, fetchAndCacheAdminSkillVersion().catch(() => {
|
|
27995
28956
|
})]);
|
|
@@ -28098,8 +29059,8 @@ Run \`wayai admin skill install\` to update.`);
|
|
|
28098
29059
|
}
|
|
28099
29060
|
|
|
28100
29061
|
// src/index.ts
|
|
28101
|
-
var __dirname =
|
|
28102
|
-
var pkg = JSON.parse(readFileSync26(
|
|
29062
|
+
var __dirname = dirname12(fileURLToPath3(import.meta.url));
|
|
29063
|
+
var pkg = JSON.parse(readFileSync26(join34(__dirname, "..", "package.json"), "utf-8"));
|
|
28103
29064
|
var [, , command, ...args] = process.argv;
|
|
28104
29065
|
var isBackgroundRefresh = command === REFRESH_COMMAND;
|
|
28105
29066
|
if (!isBackgroundRefresh) initSentry(command, pkg.version);
|
|
@@ -28338,8 +29299,8 @@ Commands:
|
|
|
28338
29299
|
create-credential Create an organization credential (API key, token, etc.)
|
|
28339
29300
|
update-credential Update / rotate an organization credential (by name)
|
|
28340
29301
|
set-connection-credential Set a connection's credential directly (org link or --field/--stdin), preview or production
|
|
28341
|
-
pull Fetch
|
|
28342
|
-
push Parse local files, show diff, sync to preview (creates hub if new)
|
|
29302
|
+
pull Fetch config and write local files \u2014 \`hubs/<hub>\` or \`bases/<base>\` (also mirrors the linked production hub/base read-only)
|
|
29303
|
+
push Parse local files, show diff, sync to preview \u2014 \`hubs/<hub>\` or \`bases/<base>\` (creates the hub/base if new)
|
|
28343
29304
|
create [folder] Explicitly create a new hub from an idless folder, then push (--label to name the preview)
|
|
28344
29305
|
diff Dry-run diff of local files vs the platform (--production diffs vs the linked production hub)
|
|
28345
29306
|
replicate Clone a hub into a new sibling preview (--label to name it)
|
|
@@ -28378,6 +29339,7 @@ ${await dataHelpBlock()}
|
|
|
28378
29339
|
Flags:
|
|
28379
29340
|
--yes, -y Skip confirmation prompts (useful for CI and scripting)
|
|
28380
29341
|
--hub <uuid|name> Target hub when the workspace has more than one (push, pull, diff, replicate, relabel, publish)
|
|
29342
|
+
--base <id|name> Target base for pull/push \u2014 routes the invocation to the \`bases/\` subtree (never combined with --hub)
|
|
28381
29343
|
--production Diff local preview files against the linked production hub (diff)
|
|
28382
29344
|
--label <name> Preview label \u2014 for the new sibling (replicate) or a brand-new hub (create, or push on create)
|
|
28383
29345
|
--clear Remove the preview label (relabel)
|