@wayai/cli 0.3.149 → 0.3.151
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 +696 -491
- 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, path35) {
|
|
451
451
|
if (!initialized) return;
|
|
452
452
|
Sentry.addBreadcrumb({
|
|
453
453
|
category: "http",
|
|
454
|
-
message: `${method} ${
|
|
454
|
+
message: `${method} ${path35}`,
|
|
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: path35, errorMaps, issueData } = params;
|
|
909
|
+
const fullPath = [...path35, ...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, path35, key) {
|
|
1221
1221
|
this._cachedPath = [];
|
|
1222
1222
|
this.parent = parent;
|
|
1223
1223
|
this.data = value;
|
|
1224
|
-
this._path =
|
|
1224
|
+
this._path = path35;
|
|
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 path35 = ["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: path35,
|
|
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: path35,
|
|
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: path35,
|
|
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: path35,
|
|
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: path35,
|
|
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, path35, 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: path35 || "<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, path36, errors, opts = {}) {
|
|
|
4767
4767
|
}
|
|
4768
4768
|
if (!isRecord(schema)) {
|
|
4769
4769
|
errors.push({
|
|
4770
|
-
path:
|
|
4770
|
+
path: path35,
|
|
4771
4771
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
4772
4772
|
});
|
|
4773
4773
|
return;
|
|
@@ -4775,14 +4775,14 @@ function validateSchema(schema, path36, errors, opts = {}) {
|
|
|
4775
4775
|
if (opts.isRoot) {
|
|
4776
4776
|
if ("type" in schema && schema.type !== "object") {
|
|
4777
4777
|
errors.push({
|
|
4778
|
-
path:
|
|
4778
|
+
path: path35 ? `${path35}.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: `${path35}.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, path36, 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: `${path35}.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: `${path35}.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: `${path35}.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: `${path35}.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, path36, 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: `${path35}.${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, path36, errors, opts = {}) {
|
|
|
4829
4829
|
if ("properties" in schema) {
|
|
4830
4830
|
if (!isRecord(schema.properties)) {
|
|
4831
4831
|
errors.push({
|
|
4832
|
-
path: `${
|
|
4832
|
+
path: `${path35}.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, `${path35}.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, `${path35}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
4844
4844
|
} else {
|
|
4845
|
-
validateSchema(schema.items, `${
|
|
4845
|
+
validateSchema(schema.items, `${path35}.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], `${path35}.${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, `${path35}.${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, `${path35}.${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 = `${path35}.${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 path35 = issue?.path.join(".") || "?";
|
|
5016
|
+
return `initial_state[${i}].${path35} 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 = (path35, 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: path35, 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 path35 = ["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: path35,
|
|
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: path35,
|
|
5366
5366
|
message: `context_boundary must be one of: ${CONTEXT_BOUNDARIES.join(", ")}`
|
|
5367
5367
|
});
|
|
5368
5368
|
}
|
|
@@ -8915,10 +8915,10 @@ function toDataProxyPath(v1Path) {
|
|
|
8915
8915
|
}
|
|
8916
8916
|
return `${DATA_PROXY_PREFIX}${v1Path.slice(REKOR_V1_PREFIX.length)}`;
|
|
8917
8917
|
}
|
|
8918
|
-
function withOrgSelector(
|
|
8919
|
-
if (!orgId) return
|
|
8920
|
-
const separator =
|
|
8921
|
-
return `${
|
|
8918
|
+
function withOrgSelector(path35, orgId) {
|
|
8919
|
+
if (!orgId) return path35;
|
|
8920
|
+
const separator = path35.includes("?") ? "&" : "?";
|
|
8921
|
+
return `${path35}${separator}${DATA_PROXY_ORG_QUERY_PARAM}=${encodeURIComponent(orgId)}`;
|
|
8922
8922
|
}
|
|
8923
8923
|
function dataErrorMessage(err) {
|
|
8924
8924
|
if (!(err instanceof ApiError)) return null;
|
|
@@ -8952,13 +8952,13 @@ var init_api_client = __esm({
|
|
|
8952
8952
|
* telling them apart by body shape misreads one for the other.
|
|
8953
8953
|
*/
|
|
8954
8954
|
path;
|
|
8955
|
-
constructor(method,
|
|
8955
|
+
constructor(method, path35, status, body) {
|
|
8956
8956
|
const safeBody = maskSecretsInMessage(body);
|
|
8957
|
-
super(`API request failed: ${method} ${
|
|
8957
|
+
super(`API request failed: ${method} ${path35} (${status}): ${safeBody}`);
|
|
8958
8958
|
this.name = "ApiError";
|
|
8959
8959
|
this.status = status;
|
|
8960
8960
|
this.body = safeBody;
|
|
8961
|
-
this.path =
|
|
8961
|
+
this.path = path35;
|
|
8962
8962
|
}
|
|
8963
8963
|
/** True when the status code is a 4xx client error (expected user-facing condition, not a bug). */
|
|
8964
8964
|
get isExpected() {
|
|
@@ -9060,8 +9060,8 @@ var init_api_client = __esm({
|
|
|
9060
9060
|
...opts?.check && { check: true }
|
|
9061
9061
|
});
|
|
9062
9062
|
}
|
|
9063
|
-
async lookup(
|
|
9064
|
-
const params = new URLSearchParams({ path:
|
|
9063
|
+
async lookup(path35, opts) {
|
|
9064
|
+
const params = new URLSearchParams({ path: path35 });
|
|
9065
9065
|
if (opts?.organizationId) params.set("organization_id", opts.organizationId);
|
|
9066
9066
|
return this.request("GET", `/api/ci/lookup?${params.toString()}`);
|
|
9067
9067
|
}
|
|
@@ -9504,9 +9504,9 @@ var init_api_client = __esm({
|
|
|
9504
9504
|
* sandbox for this conversation, or the blob was purged).
|
|
9505
9505
|
*/
|
|
9506
9506
|
async downloadArchiveSandboxFs(hubId, conversationId) {
|
|
9507
|
-
const
|
|
9508
|
-
addApiBreadcrumb("GET",
|
|
9509
|
-
const url = `${this.apiUrl}${
|
|
9507
|
+
const path35 = `/api/archive/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}/sandbox`;
|
|
9508
|
+
addApiBreadcrumb("GET", path35);
|
|
9509
|
+
const url = `${this.apiUrl}${path35}`;
|
|
9510
9510
|
let response = await this.send(url, "GET");
|
|
9511
9511
|
if (response.status === 401 && this.onUnauthorized) {
|
|
9512
9512
|
let refreshed;
|
|
@@ -9520,7 +9520,7 @@ var init_api_client = __esm({
|
|
|
9520
9520
|
}
|
|
9521
9521
|
}
|
|
9522
9522
|
if (!response.ok) {
|
|
9523
|
-
throw new ApiError("GET",
|
|
9523
|
+
throw new ApiError("GET", path35, response.status, await response.text());
|
|
9524
9524
|
}
|
|
9525
9525
|
return new Uint8Array(await response.arrayBuffer());
|
|
9526
9526
|
}
|
|
@@ -9560,9 +9560,9 @@ var init_api_client = __esm({
|
|
|
9560
9560
|
`/api/admin/data-explorer/debug/observability/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}${qs}`
|
|
9561
9561
|
);
|
|
9562
9562
|
}
|
|
9563
|
-
async request(method,
|
|
9564
|
-
addApiBreadcrumb(method,
|
|
9565
|
-
const url = `${this.apiUrl}${
|
|
9563
|
+
async request(method, path35, body, extraHeaders, contentType) {
|
|
9564
|
+
addApiBreadcrumb(method, path35);
|
|
9565
|
+
const url = `${this.apiUrl}${path35}`;
|
|
9566
9566
|
let refreshedOn401 = false;
|
|
9567
9567
|
for (let retry = 0; ; retry++) {
|
|
9568
9568
|
let response = await this.send(url, method, body, extraHeaders, contentType);
|
|
@@ -9587,7 +9587,7 @@ var init_api_client = __esm({
|
|
|
9587
9587
|
await delay(RETRYABLE_BACKOFF_MS[retry]);
|
|
9588
9588
|
continue;
|
|
9589
9589
|
}
|
|
9590
|
-
throw new ApiError(method,
|
|
9590
|
+
throw new ApiError(method, path35, response.status, errorBody);
|
|
9591
9591
|
}
|
|
9592
9592
|
}
|
|
9593
9593
|
/**
|
|
@@ -9649,9 +9649,9 @@ var init_api_client = __esm({
|
|
|
9649
9649
|
* transient-retry loop — re-streaming a blob is not worth a cold-start probe.
|
|
9650
9650
|
*/
|
|
9651
9651
|
async dataDownload(v1Path, orgId) {
|
|
9652
|
-
const
|
|
9653
|
-
addApiBreadcrumb("GET",
|
|
9654
|
-
const url = `${this.apiUrl}${
|
|
9652
|
+
const path35 = withOrgSelector(toDataProxyPath(v1Path), orgId);
|
|
9653
|
+
addApiBreadcrumb("GET", path35);
|
|
9654
|
+
const url = `${this.apiUrl}${path35}`;
|
|
9655
9655
|
let response = await this.send(url, "GET");
|
|
9656
9656
|
if (response.status === 401 && this.onUnauthorized) {
|
|
9657
9657
|
let refreshed;
|
|
@@ -9665,7 +9665,7 @@ var init_api_client = __esm({
|
|
|
9665
9665
|
}
|
|
9666
9666
|
}
|
|
9667
9667
|
if (!response.ok) {
|
|
9668
|
-
throw new ApiError("GET",
|
|
9668
|
+
throw new ApiError("GET", path35, response.status, await response.text());
|
|
9669
9669
|
}
|
|
9670
9670
|
return {
|
|
9671
9671
|
bytes: new Uint8Array(await response.arrayBuffer()),
|
|
@@ -9817,12 +9817,12 @@ function validateFollowupLinks2(followups, label, ctx) {
|
|
|
9817
9817
|
const linkTargets = /* @__PURE__ */ new Set();
|
|
9818
9818
|
followups.forEach((followup, i) => {
|
|
9819
9819
|
const ref = followup?.after_followup_id;
|
|
9820
|
-
const
|
|
9820
|
+
const path35 = ["followups", i, "after_followup_id"];
|
|
9821
9821
|
if (followup?.type !== "inactivity_after_before_event") {
|
|
9822
9822
|
if (ref !== void 0) {
|
|
9823
9823
|
ctx.addIssue({
|
|
9824
9824
|
code: external_exports.ZodIssueCode.custom,
|
|
9825
|
-
path:
|
|
9825
|
+
path: path35,
|
|
9826
9826
|
message: `kanban status ${label}: after_followup_id is only valid on inactivity_after_before_event followups (this one is ${followup?.type})`
|
|
9827
9827
|
});
|
|
9828
9828
|
}
|
|
@@ -9831,7 +9831,7 @@ function validateFollowupLinks2(followups, label, ctx) {
|
|
|
9831
9831
|
if (ref === void 0) {
|
|
9832
9832
|
ctx.addIssue({
|
|
9833
9833
|
code: external_exports.ZodIssueCode.custom,
|
|
9834
|
-
path:
|
|
9834
|
+
path: path35,
|
|
9835
9835
|
message: `kanban status ${label}: inactivity_after_before_event requires after_followup_id naming the id of a before_event followup in the same status`
|
|
9836
9836
|
});
|
|
9837
9837
|
return;
|
|
@@ -9841,7 +9841,7 @@ function validateFollowupLinks2(followups, label, ctx) {
|
|
|
9841
9841
|
if (matches.length > 1) {
|
|
9842
9842
|
ctx.addIssue({
|
|
9843
9843
|
code: external_exports.ZodIssueCode.custom,
|
|
9844
|
-
path:
|
|
9844
|
+
path: path35,
|
|
9845
9845
|
message: `kanban status ${label}: after_followup_id "${ref}" matches ${matches.length} followups \u2014 a link must name exactly one`
|
|
9846
9846
|
});
|
|
9847
9847
|
return;
|
|
@@ -9853,7 +9853,7 @@ function validateFollowupLinks2(followups, label, ctx) {
|
|
|
9853
9853
|
);
|
|
9854
9854
|
ctx.addIssue({
|
|
9855
9855
|
code: external_exports.ZodIssueCode.custom,
|
|
9856
|
-
path:
|
|
9856
|
+
path: path35,
|
|
9857
9857
|
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`
|
|
9858
9858
|
});
|
|
9859
9859
|
return;
|
|
@@ -9861,7 +9861,7 @@ function validateFollowupLinks2(followups, label, ctx) {
|
|
|
9861
9861
|
if (target.type !== "before_event") {
|
|
9862
9862
|
ctx.addIssue({
|
|
9863
9863
|
code: external_exports.ZodIssueCode.custom,
|
|
9864
|
-
path:
|
|
9864
|
+
path: path35,
|
|
9865
9865
|
message: `kanban status ${label}: after_followup_id "${ref}" points at a ${target.type} followup \u2014 only before_event followups can anchor a chain`
|
|
9866
9866
|
});
|
|
9867
9867
|
}
|
|
@@ -9937,12 +9937,12 @@ function typeMatches2(typeField, allowed) {
|
|
|
9937
9937
|
if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
|
|
9938
9938
|
return false;
|
|
9939
9939
|
}
|
|
9940
|
-
function validateSchema2(schema,
|
|
9940
|
+
function validateSchema2(schema, path35, errors, opts = {}) {
|
|
9941
9941
|
if (typeof schema === "boolean") return;
|
|
9942
9942
|
const depth = opts.depth ?? 0;
|
|
9943
9943
|
if (depth > MAX_SCHEMA_DEPTH2) {
|
|
9944
9944
|
errors.push({
|
|
9945
|
-
path:
|
|
9945
|
+
path: path35 || "<root>",
|
|
9946
9946
|
message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH2} levels`,
|
|
9947
9947
|
suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
|
|
9948
9948
|
});
|
|
@@ -9950,7 +9950,7 @@ function validateSchema2(schema, path36, errors, opts = {}) {
|
|
|
9950
9950
|
}
|
|
9951
9951
|
if (!isRecord2(schema)) {
|
|
9952
9952
|
errors.push({
|
|
9953
|
-
path:
|
|
9953
|
+
path: path35,
|
|
9954
9954
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
9955
9955
|
});
|
|
9956
9956
|
return;
|
|
@@ -9958,14 +9958,14 @@ function validateSchema2(schema, path36, errors, opts = {}) {
|
|
|
9958
9958
|
if (opts.isRoot) {
|
|
9959
9959
|
if ("type" in schema && schema.type !== "object") {
|
|
9960
9960
|
errors.push({
|
|
9961
|
-
path:
|
|
9961
|
+
path: path35 ? `${path35}.type` : "type",
|
|
9962
9962
|
message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
|
|
9963
9963
|
suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
|
|
9964
9964
|
});
|
|
9965
9965
|
}
|
|
9966
9966
|
} else if ("type" in schema && !typeMatches2(schema.type, ALLOWED_TYPES2)) {
|
|
9967
9967
|
errors.push({
|
|
9968
|
-
path: `${
|
|
9968
|
+
path: `${path35}.type`,
|
|
9969
9969
|
message: `type must be one of ${[...ALLOWED_TYPES2].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
|
|
9970
9970
|
});
|
|
9971
9971
|
}
|
|
@@ -9975,25 +9975,25 @@ function validateSchema2(schema, path36, errors, opts = {}) {
|
|
|
9975
9975
|
const isPlaceholder = PLACEHOLDER_TOKENS2.includes(e);
|
|
9976
9976
|
const isOutcomePlaceholder = e === "[KANBAN_OUTCOME_VALUES]";
|
|
9977
9977
|
errors.push({
|
|
9978
|
-
path: `${
|
|
9978
|
+
path: `${path35}.enum`,
|
|
9979
9979
|
message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
|
|
9980
9980
|
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"]`.'
|
|
9981
9981
|
});
|
|
9982
9982
|
} else if (!Array.isArray(e)) {
|
|
9983
9983
|
errors.push({
|
|
9984
|
-
path: `${
|
|
9984
|
+
path: `${path35}.enum`,
|
|
9985
9985
|
message: `enum must be a non-empty array of primitives, got ${typeof e}`
|
|
9986
9986
|
});
|
|
9987
9987
|
} else if (e.length === 0) {
|
|
9988
9988
|
errors.push({
|
|
9989
|
-
path: `${
|
|
9989
|
+
path: `${path35}.enum`,
|
|
9990
9990
|
message: "enum must not be empty"
|
|
9991
9991
|
});
|
|
9992
9992
|
} else {
|
|
9993
9993
|
for (let i = 0; i < e.length; i++) {
|
|
9994
9994
|
if (!isPrimitive2(e[i])) {
|
|
9995
9995
|
errors.push({
|
|
9996
|
-
path: `${
|
|
9996
|
+
path: `${path35}.enum[${i}]`,
|
|
9997
9997
|
message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
|
|
9998
9998
|
});
|
|
9999
9999
|
}
|
|
@@ -10003,7 +10003,7 @@ function validateSchema2(schema, path36, errors, opts = {}) {
|
|
|
10003
10003
|
for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
|
|
10004
10004
|
if (key in schema && typeof schema[key] === "boolean") {
|
|
10005
10005
|
errors.push({
|
|
10006
|
-
path: `${
|
|
10006
|
+
path: `${path35}.${key}`,
|
|
10007
10007
|
message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
|
|
10008
10008
|
suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
|
|
10009
10009
|
});
|
|
@@ -10012,45 +10012,45 @@ function validateSchema2(schema, path36, errors, opts = {}) {
|
|
|
10012
10012
|
if ("properties" in schema) {
|
|
10013
10013
|
if (!isRecord2(schema.properties)) {
|
|
10014
10014
|
errors.push({
|
|
10015
|
-
path: `${
|
|
10015
|
+
path: `${path35}.properties`,
|
|
10016
10016
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
10017
10017
|
});
|
|
10018
10018
|
} else {
|
|
10019
10019
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
10020
|
-
validateSchema2(propSchema, `${
|
|
10020
|
+
validateSchema2(propSchema, `${path35}.properties.${propName}`, errors, { depth: depth + 1 });
|
|
10021
10021
|
}
|
|
10022
10022
|
}
|
|
10023
10023
|
}
|
|
10024
10024
|
if (schemaTypeIncludes2(schema, "array") && "items" in schema) {
|
|
10025
10025
|
if (Array.isArray(schema.items)) {
|
|
10026
|
-
schema.items.forEach((sub, i) => validateSchema2(sub, `${
|
|
10026
|
+
schema.items.forEach((sub, i) => validateSchema2(sub, `${path35}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
10027
10027
|
} else {
|
|
10028
|
-
validateSchema2(schema.items, `${
|
|
10028
|
+
validateSchema2(schema.items, `${path35}.items`, errors, { depth: depth + 1 });
|
|
10029
10029
|
}
|
|
10030
10030
|
}
|
|
10031
10031
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS2) {
|
|
10032
10032
|
if (key in schema && isRecord2(schema[key])) {
|
|
10033
|
-
validateSchema2(schema[key], `${
|
|
10033
|
+
validateSchema2(schema[key], `${path35}.${key}`, errors, { depth: depth + 1 });
|
|
10034
10034
|
}
|
|
10035
10035
|
}
|
|
10036
10036
|
for (const key of SUBSCHEMA_LIST_KEYWORDS2) {
|
|
10037
10037
|
const list = schema[key];
|
|
10038
10038
|
if (Array.isArray(list)) {
|
|
10039
|
-
list.forEach((sub, i) => validateSchema2(sub, `${
|
|
10039
|
+
list.forEach((sub, i) => validateSchema2(sub, `${path35}.${key}[${i}]`, errors, { depth: depth + 1 }));
|
|
10040
10040
|
}
|
|
10041
10041
|
}
|
|
10042
10042
|
for (const key of SUBSCHEMA_MAP_KEYWORDS2) {
|
|
10043
10043
|
const map = schema[key];
|
|
10044
10044
|
if (isRecord2(map)) {
|
|
10045
10045
|
for (const [name, sub] of Object.entries(map)) {
|
|
10046
|
-
validateSchema2(sub, `${
|
|
10046
|
+
validateSchema2(sub, `${path35}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
10047
10047
|
}
|
|
10048
10048
|
}
|
|
10049
10049
|
}
|
|
10050
10050
|
const reportedPaths = new Set(errors.map((e) => e.path));
|
|
10051
10051
|
for (const [k, v] of Object.entries(schema)) {
|
|
10052
10052
|
if (typeof v !== "string") continue;
|
|
10053
|
-
const fieldPath = `${
|
|
10053
|
+
const fieldPath = `${path35}.${k}`;
|
|
10054
10054
|
if (reportedPaths.has(fieldPath)) continue;
|
|
10055
10055
|
for (const token of PLACEHOLDER_TOKENS2) {
|
|
10056
10056
|
if (v === token) {
|
|
@@ -10195,8 +10195,8 @@ function evalInitialStateError2(input) {
|
|
|
10195
10195
|
const parsed = evalInitialStateEntry2.safeParse(entries[i]);
|
|
10196
10196
|
if (!parsed.success) {
|
|
10197
10197
|
const issue = parsed.error.issues[0];
|
|
10198
|
-
const
|
|
10199
|
-
return `initial_state[${i}].${
|
|
10198
|
+
const path35 = issue?.path.join(".") || "?";
|
|
10199
|
+
return `initial_state[${i}].${path35} is invalid: ${issue?.message ?? "malformed"}`;
|
|
10200
10200
|
}
|
|
10201
10201
|
if (seenSlugs.has(parsed.data.slug)) {
|
|
10202
10202
|
return `initial_state[${i}].slug "${parsed.data.slug}" is declared more than once`;
|
|
@@ -10401,10 +10401,10 @@ function refineHubAsCodeEvals2(config, ctx) {
|
|
|
10401
10401
|
function refineHubAsCodeEvalAttachments2(config, ctx) {
|
|
10402
10402
|
const cfg = config;
|
|
10403
10403
|
const referencedHashes = /* @__PURE__ */ new Set();
|
|
10404
|
-
const addTurnIssue = (
|
|
10404
|
+
const addTurnIssue = (path35, turn, name) => {
|
|
10405
10405
|
const error = evalTurnAttachmentsError2(turn);
|
|
10406
10406
|
if (error) {
|
|
10407
|
-
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path:
|
|
10407
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path35, message: `${name}: ${error}` });
|
|
10408
10408
|
return;
|
|
10409
10409
|
}
|
|
10410
10410
|
for (const hash of collectTurnAttachmentHashes2(turn)) referencedHashes.add(hash);
|
|
@@ -10550,11 +10550,11 @@ function refineHubAsCodeDelegation2(config, ctx) {
|
|
|
10550
10550
|
}
|
|
10551
10551
|
}
|
|
10552
10552
|
if (del.context_boundary === void 0) return;
|
|
10553
|
-
const
|
|
10553
|
+
const path35 = ["agents", agentIndex, "tools", "delegation", delIndex, "context_boundary"];
|
|
10554
10554
|
if (del.type !== "hub") {
|
|
10555
10555
|
ctx.addIssue({
|
|
10556
10556
|
code: external_exports.ZodIssueCode.custom,
|
|
10557
|
-
path:
|
|
10557
|
+
path: path35,
|
|
10558
10558
|
message: `context_boundary applies only to \`type: hub\` delegations (got type "${String(del.type)}")`
|
|
10559
10559
|
});
|
|
10560
10560
|
return;
|
|
@@ -10562,7 +10562,7 @@ function refineHubAsCodeDelegation2(config, ctx) {
|
|
|
10562
10562
|
if (!CONTEXT_BOUNDARIES2.includes(del.context_boundary)) {
|
|
10563
10563
|
ctx.addIssue({
|
|
10564
10564
|
code: external_exports.ZodIssueCode.custom,
|
|
10565
|
-
path:
|
|
10565
|
+
path: path35,
|
|
10566
10566
|
message: `context_boundary must be one of: ${CONTEXT_BOUNDARIES2.join(", ")}`
|
|
10567
10567
|
});
|
|
10568
10568
|
}
|
|
@@ -15442,7 +15442,7 @@ var init_registry = __esm({
|
|
|
15442
15442
|
surviving: "bases use",
|
|
15443
15443
|
clause: 3,
|
|
15444
15444
|
shipped: true,
|
|
15445
|
-
reason: "
|
|
15445
|
+
reason: "Deprecated since the worktree scope merged into one set-valued file: `wayai use bases/<id>` covers this. Kept as an alias for its JSON output shape."
|
|
15446
15446
|
},
|
|
15447
15447
|
{
|
|
15448
15448
|
original: "unbind",
|
|
@@ -15450,7 +15450,7 @@ var init_registry = __esm({
|
|
|
15450
15450
|
surviving: "bases unbind",
|
|
15451
15451
|
clause: 3,
|
|
15452
15452
|
shipped: true,
|
|
15453
|
-
reason: "
|
|
15453
|
+
reason: "Deprecated alongside `bases use`: `wayai unbind bases/<id>` covers this. It still clears only the bases axis of the worktree scope, never the hubs one."
|
|
15454
15454
|
},
|
|
15455
15455
|
{
|
|
15456
15456
|
original: "bases promote",
|
|
@@ -15571,9 +15571,9 @@ function getVersionCachePath(filename = CLI_CACHE_FILE) {
|
|
|
15571
15571
|
}
|
|
15572
15572
|
function readVersionCache(filename = CLI_CACHE_FILE) {
|
|
15573
15573
|
try {
|
|
15574
|
-
const
|
|
15575
|
-
if (!existsSync4(
|
|
15576
|
-
const parsed = JSON.parse(readFileSync5(
|
|
15574
|
+
const path35 = getVersionCachePath(filename);
|
|
15575
|
+
if (!existsSync4(path35)) return null;
|
|
15576
|
+
const parsed = JSON.parse(readFileSync5(path35, "utf-8"));
|
|
15577
15577
|
if (typeof parsed.lastCheck !== "number") return null;
|
|
15578
15578
|
if (parsed.latest !== null && typeof parsed.latest !== "string") return null;
|
|
15579
15579
|
return parsed;
|
|
@@ -15593,10 +15593,10 @@ function isVersionCacheStale(filename = CLI_CACHE_FILE, maxAgeMs = MAX_AGE_24H_M
|
|
|
15593
15593
|
return Date.now() - cache.lastCheck > maxAgeMs;
|
|
15594
15594
|
}
|
|
15595
15595
|
function writeVersionCache(filename, cache) {
|
|
15596
|
-
const
|
|
15597
|
-
const dir = dirname3(
|
|
15596
|
+
const path35 = getVersionCachePath(filename);
|
|
15597
|
+
const dir = dirname3(path35);
|
|
15598
15598
|
if (!existsSync4(dir)) mkdirSync(dir, { recursive: true });
|
|
15599
|
-
writeFileSync2(
|
|
15599
|
+
writeFileSync2(path35, JSON.stringify(cache));
|
|
15600
15600
|
}
|
|
15601
15601
|
function touchVersionCache(filename) {
|
|
15602
15602
|
writeVersionCache(filename, { lastCheck: Date.now(), latest: readVersionCache(filename)?.latest ?? null });
|
|
@@ -15635,14 +15635,14 @@ function parseFrontmatterVersion(content) {
|
|
|
15635
15635
|
function findInstalledSkills(projectRoot, paths = SKILL_INSTALL_PATHS) {
|
|
15636
15636
|
const found = [];
|
|
15637
15637
|
for (const rel of paths) {
|
|
15638
|
-
const
|
|
15639
|
-
if (!existsSync5(
|
|
15638
|
+
const path35 = join7(projectRoot, rel);
|
|
15639
|
+
if (!existsSync5(path35)) continue;
|
|
15640
15640
|
let version = null;
|
|
15641
15641
|
try {
|
|
15642
|
-
version = parseFrontmatterVersion(readFileSync6(
|
|
15642
|
+
version = parseFrontmatterVersion(readFileSync6(path35, "utf-8"));
|
|
15643
15643
|
} catch {
|
|
15644
15644
|
}
|
|
15645
|
-
found.push({ path:
|
|
15645
|
+
found.push({ path: path35, version });
|
|
15646
15646
|
}
|
|
15647
15647
|
return found;
|
|
15648
15648
|
}
|
|
@@ -16520,10 +16520,33 @@ var init_logout = __esm({
|
|
|
16520
16520
|
}
|
|
16521
16521
|
});
|
|
16522
16522
|
|
|
16523
|
-
// src/lib/
|
|
16523
|
+
// src/lib/base-id.ts
|
|
16524
|
+
function isValidBaseId(id) {
|
|
16525
|
+
return id.length > 0 && id.length <= BASE_ID_MAX_LENGTH && BASE_ID_RE.test(id);
|
|
16526
|
+
}
|
|
16527
|
+
function isPathSafeId(id) {
|
|
16528
|
+
return PATH_SAFE_ID_RE.test(id);
|
|
16529
|
+
}
|
|
16530
|
+
var BASE_ID_MAX_LENGTH, BASE_ID_RE, BASE_ID_RULE, PATH_SAFE_ID_RE, PATH_SAFE_ID_RULE;
|
|
16531
|
+
var init_base_id = __esm({
|
|
16532
|
+
"src/lib/base-id.ts"() {
|
|
16533
|
+
"use strict";
|
|
16534
|
+
BASE_ID_MAX_LENGTH = 128;
|
|
16535
|
+
BASE_ID_RE = /^[A-Za-z0-9_][A-Za-z0-9_-]*$/;
|
|
16536
|
+
BASE_ID_RULE = `letters, digits, \`-\` and \`_\`, starting with a letter, digit or \`_\`, ${BASE_ID_MAX_LENGTH} characters or fewer`;
|
|
16537
|
+
PATH_SAFE_ID_RE = /^(?!\.\.?$)[A-Za-z0-9._-]{1,256}$/;
|
|
16538
|
+
PATH_SAFE_ID_RULE = "letters, digits, dot, dash and underscore, with no path separators, not `.` or `..` alone, 256 characters or fewer";
|
|
16539
|
+
}
|
|
16540
|
+
});
|
|
16541
|
+
|
|
16542
|
+
// src/lib/worktree-scope.ts
|
|
16524
16543
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
16525
16544
|
import * as fs7 from "fs";
|
|
16526
16545
|
import * as path7 from "path";
|
|
16546
|
+
import * as yaml4 from "js-yaml";
|
|
16547
|
+
function axisNoun(axis) {
|
|
16548
|
+
return AXES[axis].noun;
|
|
16549
|
+
}
|
|
16527
16550
|
function resolveGitDir() {
|
|
16528
16551
|
const cwd = process.cwd();
|
|
16529
16552
|
if (_gitDirCache && _gitDirCache.cwd === cwd) return _gitDirCache.gitDir;
|
|
@@ -16541,158 +16564,227 @@ function resolveGitDir() {
|
|
|
16541
16564
|
_gitDirCache = { cwd, gitDir };
|
|
16542
16565
|
return gitDir;
|
|
16543
16566
|
}
|
|
16544
|
-
function
|
|
16545
|
-
const
|
|
16546
|
-
|
|
16547
|
-
|
|
16548
|
-
|
|
16549
|
-
|
|
16550
|
-
|
|
16551
|
-
|
|
16552
|
-
|
|
16553
|
-
|
|
16554
|
-
|
|
16555
|
-
|
|
16556
|
-
|
|
16557
|
-
|
|
16558
|
-
|
|
16559
|
-
|
|
16560
|
-
|
|
16561
|
-
|
|
16562
|
-
|
|
16563
|
-
|
|
16564
|
-
|
|
16565
|
-
|
|
16566
|
-
|
|
16567
|
-
|
|
16568
|
-
|
|
16569
|
-
|
|
16570
|
-
|
|
16571
|
-
|
|
16572
|
-
|
|
16573
|
-
|
|
16574
|
-
|
|
16567
|
+
function getScopePath() {
|
|
16568
|
+
const gitDir = resolveGitDir();
|
|
16569
|
+
return gitDir ? path7.join(gitDir, SCOPE_FILE) : null;
|
|
16570
|
+
}
|
|
16571
|
+
function legacyPaths() {
|
|
16572
|
+
const gitDir = resolveGitDir();
|
|
16573
|
+
if (!gitDir) return [];
|
|
16574
|
+
return AXIS_ORDER.flatMap((axis) => AXES[axis].legacyFiles).map((f) => path7.join(gitDir, f));
|
|
16575
|
+
}
|
|
16576
|
+
function emptyScope() {
|
|
16577
|
+
return { hubs: [], bases: [] };
|
|
16578
|
+
}
|
|
16579
|
+
function parseAxis(raw, axis) {
|
|
16580
|
+
if (!Array.isArray(raw)) return [];
|
|
16581
|
+
const { isValidId } = AXES[axis];
|
|
16582
|
+
const out = [];
|
|
16583
|
+
for (const entry of raw) {
|
|
16584
|
+
if (typeof entry !== "string") continue;
|
|
16585
|
+
const id = entry.trim();
|
|
16586
|
+
if (!isValidId(id) || out.includes(id)) continue;
|
|
16587
|
+
out.push(id);
|
|
16588
|
+
}
|
|
16589
|
+
return out;
|
|
16590
|
+
}
|
|
16591
|
+
function readLegacyAxis(axis) {
|
|
16592
|
+
const gitDir = resolveGitDir();
|
|
16593
|
+
if (!gitDir) return [];
|
|
16594
|
+
const { isValidId, legacyFiles } = AXES[axis];
|
|
16595
|
+
for (const filename of legacyFiles) {
|
|
16596
|
+
let raw;
|
|
16597
|
+
try {
|
|
16598
|
+
raw = fs7.readFileSync(path7.join(gitDir, filename), "utf-8");
|
|
16599
|
+
} catch (err) {
|
|
16600
|
+
if (err.code === "ENOENT") continue;
|
|
16601
|
+
throw err;
|
|
16575
16602
|
}
|
|
16576
|
-
|
|
16603
|
+
const trimmed = raw.trim();
|
|
16604
|
+
return isValidId(trimmed) ? [trimmed] : [];
|
|
16577
16605
|
}
|
|
16578
|
-
|
|
16579
|
-
|
|
16580
|
-
|
|
16606
|
+
return [];
|
|
16607
|
+
}
|
|
16608
|
+
function readScope() {
|
|
16609
|
+
const scopePath = getScopePath();
|
|
16610
|
+
if (!scopePath) return emptyScope();
|
|
16611
|
+
let raw;
|
|
16612
|
+
try {
|
|
16613
|
+
raw = fs7.readFileSync(scopePath, "utf-8");
|
|
16614
|
+
} catch (err) {
|
|
16615
|
+
if (err.code === "ENOENT") {
|
|
16616
|
+
return { hubs: readLegacyAxis("hubs"), bases: readLegacyAxis("bases") };
|
|
16617
|
+
}
|
|
16618
|
+
throw err;
|
|
16619
|
+
}
|
|
16620
|
+
let doc;
|
|
16621
|
+
try {
|
|
16622
|
+
doc = yaml4.load(raw);
|
|
16623
|
+
} catch {
|
|
16624
|
+
return emptyScope();
|
|
16625
|
+
}
|
|
16626
|
+
if (!doc || typeof doc !== "object" || Array.isArray(doc)) return emptyScope();
|
|
16627
|
+
const map = doc;
|
|
16628
|
+
return { hubs: parseAxis(map.hubs, "hubs"), bases: parseAxis(map.bases, "bases") };
|
|
16629
|
+
}
|
|
16630
|
+
function sweepLegacyFiles() {
|
|
16631
|
+
for (const legacyPath of legacyPaths()) {
|
|
16581
16632
|
try {
|
|
16582
16633
|
fs7.unlinkSync(legacyPath);
|
|
16583
16634
|
} catch {
|
|
16584
16635
|
}
|
|
16585
16636
|
}
|
|
16586
|
-
|
|
16587
|
-
|
|
16588
|
-
|
|
16589
|
-
}
|
|
16590
|
-
const
|
|
16591
|
-
|
|
16592
|
-
throw new Error(`Not inside a git repository \u2014 cannot write ${noun} binding.`);
|
|
16637
|
+
}
|
|
16638
|
+
function writeScope(scope) {
|
|
16639
|
+
for (const axis of AXIS_ORDER) {
|
|
16640
|
+
const { isValidId, idLabel } = AXES[axis];
|
|
16641
|
+
for (const id of scope[axis]) {
|
|
16642
|
+
if (!isValidId(id)) throw expected(`Invalid ${idLabel}: ${id}`);
|
|
16593
16643
|
}
|
|
16594
|
-
fs7.writeFileSync(bindingPath, `${id}
|
|
16595
|
-
`, "utf-8");
|
|
16596
|
-
removeLegacyBinding();
|
|
16597
16644
|
}
|
|
16598
|
-
|
|
16599
|
-
|
|
16600
|
-
|
|
16601
|
-
if (!bindingPath) continue;
|
|
16602
|
-
try {
|
|
16603
|
-
fs7.unlinkSync(bindingPath);
|
|
16604
|
-
removed = true;
|
|
16605
|
-
} catch (err) {
|
|
16606
|
-
if (err.code !== "ENOENT") throw err;
|
|
16607
|
-
}
|
|
16608
|
-
}
|
|
16609
|
-
return removed;
|
|
16645
|
+
const scopePath = getScopePath();
|
|
16646
|
+
if (!scopePath) {
|
|
16647
|
+
throw expected("Not inside a git repository \u2014 cannot write the worktree scope.");
|
|
16610
16648
|
}
|
|
16611
|
-
|
|
16612
|
-
|
|
16613
|
-
|
|
16614
|
-
|
|
16615
|
-
|
|
16616
|
-
|
|
16617
|
-
|
|
16618
|
-
|
|
16619
|
-
|
|
16620
|
-
|
|
16621
|
-
|
|
16622
|
-
` ${unbindCommand2} # clear the binding for this worktree`,
|
|
16623
|
-
` ${useCommand2} ${resolvedId} # rebind this worktree to the new ${noun}`
|
|
16624
|
-
].join("\n")
|
|
16625
|
-
);
|
|
16626
|
-
process.exit(1);
|
|
16649
|
+
const body = yaml4.dump({ hubs: scope.hubs, bases: scope.bases }, { flowLevel: 1 });
|
|
16650
|
+
const tmpPath = `${scopePath}.tmp-${process.pid}`;
|
|
16651
|
+
try {
|
|
16652
|
+
fs7.writeFileSync(tmpPath, body, "utf-8");
|
|
16653
|
+
fs7.renameSync(tmpPath, scopePath);
|
|
16654
|
+
} catch (err) {
|
|
16655
|
+
try {
|
|
16656
|
+
fs7.unlinkSync(tmpPath);
|
|
16657
|
+
} catch {
|
|
16658
|
+
}
|
|
16659
|
+
throw asExpectedEnvironmentError(err);
|
|
16627
16660
|
}
|
|
16628
|
-
|
|
16629
|
-
|
|
16630
|
-
|
|
16631
|
-
|
|
16632
|
-
|
|
16633
|
-
`This worktree is bound to ${noun} ${bound}, but you're about to create a new ${noun} "${newName}" here.`,
|
|
16634
|
-
"",
|
|
16635
|
-
"This usually means a prompt was routed to the wrong worktree.",
|
|
16636
|
-
"Confirm with the user before unbinding. To override:",
|
|
16637
|
-
` ${unbindCommand2} # clear the binding for this worktree`
|
|
16638
|
-
].join("\n")
|
|
16639
|
-
);
|
|
16640
|
-
process.exit(1);
|
|
16661
|
+
sweepLegacyFiles();
|
|
16662
|
+
}
|
|
16663
|
+
function asExpectedEnvironmentError(err) {
|
|
16664
|
+
if (err instanceof Error && typeof err.code === "string") {
|
|
16665
|
+
return expected(err.message);
|
|
16641
16666
|
}
|
|
16642
|
-
|
|
16667
|
+
return err;
|
|
16668
|
+
}
|
|
16669
|
+
function setScopeAxis(axis, ids) {
|
|
16670
|
+
writeScope({ ...readScope(), [axis]: ids });
|
|
16671
|
+
return ids;
|
|
16672
|
+
}
|
|
16673
|
+
function addToScope(axis, id) {
|
|
16674
|
+
const scope = readScope();
|
|
16675
|
+
if (scope[axis].includes(id)) return null;
|
|
16676
|
+
const next = [...scope[axis], id];
|
|
16677
|
+
writeScope({ ...scope, [axis]: next });
|
|
16678
|
+
return next;
|
|
16679
|
+
}
|
|
16680
|
+
function removeFromScope(axis, id) {
|
|
16681
|
+
const scope = readScope();
|
|
16682
|
+
if (!scope[axis].includes(id)) return null;
|
|
16683
|
+
const next = scope[axis].filter((entry) => entry !== id);
|
|
16684
|
+
writeScope({ ...scope, [axis]: next });
|
|
16685
|
+
return next;
|
|
16686
|
+
}
|
|
16687
|
+
function clearScope() {
|
|
16688
|
+
const scopePath = getScopePath();
|
|
16689
|
+
let removed = false;
|
|
16690
|
+
for (const target of [...scopePath ? [scopePath] : [], ...legacyPaths()]) {
|
|
16643
16691
|
try {
|
|
16644
|
-
|
|
16645
|
-
|
|
16646
|
-
console.log(`Worktree bound to ${noun} ${id} (run \`${unbindCommand2}\` to clear).`);
|
|
16647
|
-
return true;
|
|
16692
|
+
fs7.unlinkSync(target);
|
|
16693
|
+
removed = true;
|
|
16648
16694
|
} catch (err) {
|
|
16649
|
-
|
|
16650
|
-
` Warning: could not auto-bind worktree (${err instanceof Error ? err.message : String(err)})`
|
|
16651
|
-
);
|
|
16652
|
-
return false;
|
|
16695
|
+
if (err.code !== "ENOENT") throw err;
|
|
16653
16696
|
}
|
|
16654
16697
|
}
|
|
16655
|
-
return
|
|
16656
|
-
getBindingPath: getBindingPath2,
|
|
16657
|
-
readBinding: readBinding2,
|
|
16658
|
-
writeBinding: writeBinding2,
|
|
16659
|
-
clearBinding: clearBinding2,
|
|
16660
|
-
assertMatchesBinding,
|
|
16661
|
-
assertNoBindingBlocksCreation,
|
|
16662
|
-
autoBindIfUnbound: autoBindIfUnbound2
|
|
16663
|
-
};
|
|
16698
|
+
return removed;
|
|
16664
16699
|
}
|
|
16665
|
-
|
|
16666
|
-
|
|
16667
|
-
|
|
16668
|
-
|
|
16700
|
+
function describeAxis(axis, ids) {
|
|
16701
|
+
const { noun } = AXES[axis];
|
|
16702
|
+
return ids.length === 1 ? `${noun} ${ids[0]}` : `${noun}s ${ids.join(", ")}`;
|
|
16703
|
+
}
|
|
16704
|
+
function describeScope(scope) {
|
|
16705
|
+
return AXIS_ORDER.filter((axis) => scope[axis].length > 0).map((axis) => describeAxis(axis, scope[axis])).join("; ");
|
|
16706
|
+
}
|
|
16707
|
+
function assertInScope(axis, resolvedId, label) {
|
|
16708
|
+
const scoped = readScope()[axis];
|
|
16709
|
+
if (scoped.length === 0) return;
|
|
16710
|
+
if (scoped.includes(resolvedId)) return;
|
|
16711
|
+
const { noun, selectorFor } = AXES[axis];
|
|
16712
|
+
const selector = selectorFor(resolvedId);
|
|
16713
|
+
const target = label ? `${label} (${resolvedId})` : resolvedId;
|
|
16714
|
+
console.error(
|
|
16715
|
+
[
|
|
16716
|
+
`This worktree is scoped to ${describeAxis(axis, scoped)}, but the command resolved to ${target}.`,
|
|
16717
|
+
"",
|
|
16718
|
+
"This usually means a prompt was routed to the wrong worktree.",
|
|
16719
|
+
"Confirm with the user before changing this scope. To override:",
|
|
16720
|
+
` ${REPLACE_COMMAND} ${selector} # scope this worktree to that ${noun} INSTEAD`,
|
|
16721
|
+
` ${ADD_COMMAND} ${selector} # scope it to that ${noun} AS WELL`,
|
|
16722
|
+
` ${CLEAR_COMMAND} # clear the whole worktree scope (both hubs and bases)`
|
|
16723
|
+
].join("\n")
|
|
16724
|
+
);
|
|
16725
|
+
process.exit(1);
|
|
16726
|
+
}
|
|
16727
|
+
function assertScopeAllowsCreation(axis, newName) {
|
|
16728
|
+
const scoped = readScope()[axis];
|
|
16729
|
+
if (scoped.length === 0) return;
|
|
16730
|
+
const { noun } = AXES[axis];
|
|
16731
|
+
console.error(
|
|
16732
|
+
[
|
|
16733
|
+
`This worktree is scoped to ${describeAxis(axis, scoped)}, but you're about to create a new ${noun} "${newName}" here.`,
|
|
16734
|
+
"",
|
|
16735
|
+
"This usually means a prompt was routed to the wrong worktree.",
|
|
16736
|
+
"Confirm with the user before clearing this scope. To override:",
|
|
16737
|
+
` ${CLEAR_COMMAND} # clear the whole worktree scope (both hubs and bases)`
|
|
16738
|
+
].join("\n")
|
|
16739
|
+
);
|
|
16740
|
+
process.exit(1);
|
|
16741
|
+
}
|
|
16742
|
+
function seedScopeIfEmpty(axis, id) {
|
|
16743
|
+
try {
|
|
16744
|
+
if (readScope()[axis].length > 0) return false;
|
|
16745
|
+
setScopeAxis(axis, [id]);
|
|
16746
|
+
console.log(
|
|
16747
|
+
`Worktree bound to ${AXES[axis].noun} ${id} (run \`${CLEAR_COMMAND}\` to clear).`
|
|
16748
|
+
);
|
|
16749
|
+
return true;
|
|
16750
|
+
} catch (err) {
|
|
16751
|
+
console.warn(
|
|
16752
|
+
` Warning: could not bind worktree (${err instanceof Error ? err.message : String(err)})`
|
|
16753
|
+
);
|
|
16754
|
+
return false;
|
|
16669
16755
|
}
|
|
16670
|
-
}
|
|
16671
|
-
|
|
16672
|
-
|
|
16673
|
-
|
|
16674
|
-
var init_hub_binding = __esm({
|
|
16675
|
-
"src/lib/hub-binding.ts"() {
|
|
16756
|
+
}
|
|
16757
|
+
var SCOPE_FILE, LEGACY_HUB_SCOPE_FILE, LEGACY_HUB_SCOPE_FILE_PRE_RENAME, LEGACY_BASE_SCOPE_FILE, AXES, AXIS_ORDER, ADD_COMMAND, REPLACE_COMMAND, CLEAR_COMMAND, _gitDirCache;
|
|
16758
|
+
var init_worktree_scope = __esm({
|
|
16759
|
+
"src/lib/worktree-scope.ts"() {
|
|
16676
16760
|
"use strict";
|
|
16761
|
+
init_base_id();
|
|
16762
|
+
init_expected();
|
|
16677
16763
|
init_utils();
|
|
16678
|
-
|
|
16679
|
-
|
|
16680
|
-
|
|
16681
|
-
|
|
16682
|
-
|
|
16683
|
-
|
|
16684
|
-
|
|
16685
|
-
|
|
16686
|
-
|
|
16687
|
-
|
|
16688
|
-
|
|
16689
|
-
|
|
16690
|
-
|
|
16691
|
-
|
|
16692
|
-
|
|
16693
|
-
|
|
16694
|
-
|
|
16695
|
-
|
|
16764
|
+
SCOPE_FILE = "wayai-scope";
|
|
16765
|
+
LEGACY_HUB_SCOPE_FILE = "wayai-binding";
|
|
16766
|
+
LEGACY_HUB_SCOPE_FILE_PRE_RENAME = "wayai-lock";
|
|
16767
|
+
LEGACY_BASE_SCOPE_FILE = "wayai-base-binding";
|
|
16768
|
+
AXES = {
|
|
16769
|
+
hubs: {
|
|
16770
|
+
noun: "hub",
|
|
16771
|
+
idLabel: "hub_id (must be a UUID)",
|
|
16772
|
+
isValidId: (id) => UUID_RE2.test(id),
|
|
16773
|
+
selectorFor: (id) => id,
|
|
16774
|
+
legacyFiles: [LEGACY_HUB_SCOPE_FILE, LEGACY_HUB_SCOPE_FILE_PRE_RENAME]
|
|
16775
|
+
},
|
|
16776
|
+
bases: {
|
|
16777
|
+
noun: "base",
|
|
16778
|
+
idLabel: `base id (${PATH_SAFE_ID_RULE})`,
|
|
16779
|
+
isValidId: isPathSafeId,
|
|
16780
|
+
selectorFor: (id) => `bases/${id}`,
|
|
16781
|
+
legacyFiles: [LEGACY_BASE_SCOPE_FILE]
|
|
16782
|
+
}
|
|
16783
|
+
};
|
|
16784
|
+
AXIS_ORDER = ["hubs", "bases"];
|
|
16785
|
+
ADD_COMMAND = "wayai use --add";
|
|
16786
|
+
REPLACE_COMMAND = "wayai use";
|
|
16787
|
+
CLEAR_COMMAND = "wayai unbind";
|
|
16696
16788
|
}
|
|
16697
16789
|
});
|
|
16698
16790
|
|
|
@@ -16738,12 +16830,13 @@ async function statusCommand(args2, pkg2) {
|
|
|
16738
16830
|
const cachedCliLatest = readCachedLatest(CLI_CACHE_FILE);
|
|
16739
16831
|
const cliLatest = cachedCliLatest && isNewerVersion(cachedCliLatest, pkg2.version) ? cachedCliLatest : null;
|
|
16740
16832
|
const skill = buildSkillState();
|
|
16741
|
-
let
|
|
16833
|
+
let scope;
|
|
16742
16834
|
try {
|
|
16743
|
-
|
|
16835
|
+
scope = readScope();
|
|
16744
16836
|
} catch {
|
|
16745
|
-
|
|
16837
|
+
scope = emptyScope();
|
|
16746
16838
|
}
|
|
16839
|
+
const boundHubId = scope.hubs[0] ?? null;
|
|
16747
16840
|
if (!config) {
|
|
16748
16841
|
const snapshot2 = {
|
|
16749
16842
|
logged_in: false,
|
|
@@ -16756,6 +16849,7 @@ async function statusCommand(args2, pkg2) {
|
|
|
16756
16849
|
orgs: [],
|
|
16757
16850
|
active_org: null,
|
|
16758
16851
|
workspace,
|
|
16852
|
+
worktree_scope: scope,
|
|
16759
16853
|
worktree_binding: { hub_id: boundHubId },
|
|
16760
16854
|
worktree_lock: { hub_id: boundHubId }
|
|
16761
16855
|
};
|
|
@@ -16811,6 +16905,7 @@ async function statusCommand(args2, pkg2) {
|
|
|
16811
16905
|
orgs,
|
|
16812
16906
|
active_org: activeOrg,
|
|
16813
16907
|
workspace,
|
|
16908
|
+
worktree_scope: scope,
|
|
16814
16909
|
worktree_binding: { hub_id: boundHubId },
|
|
16815
16910
|
worktree_lock: { hub_id: boundHubId }
|
|
16816
16911
|
};
|
|
@@ -16842,8 +16937,10 @@ async function statusCommand(args2, pkg2) {
|
|
|
16842
16937
|
} else {
|
|
16843
16938
|
console.log("No .wayai.yaml found \u2014 run `wayai init` to scope this repo to an organization.");
|
|
16844
16939
|
}
|
|
16845
|
-
if (
|
|
16846
|
-
console.log(
|
|
16940
|
+
if (scope.hubs.length > 0 || scope.bases.length > 0) {
|
|
16941
|
+
console.log("Worktree scope: (run `wayai unbind` to clear)");
|
|
16942
|
+
if (scope.hubs.length > 0) console.log(` Hubs: ${scope.hubs.join(", ")}`);
|
|
16943
|
+
if (scope.bases.length > 0) console.log(` Bases: ${scope.bases.join(", ")}`);
|
|
16847
16944
|
}
|
|
16848
16945
|
if (tokenValid === true && accessToken) {
|
|
16849
16946
|
await nudgeReportActions(config.api_url, accessToken);
|
|
@@ -16856,7 +16953,7 @@ var init_status = __esm({
|
|
|
16856
16953
|
init_auth();
|
|
16857
16954
|
init_repo_config();
|
|
16858
16955
|
init_workspace();
|
|
16859
|
-
|
|
16956
|
+
init_worktree_scope();
|
|
16860
16957
|
init_api_client();
|
|
16861
16958
|
init_version_cache();
|
|
16862
16959
|
init_skill_version();
|
|
@@ -17684,7 +17781,7 @@ var init_eval_attachments = __esm({
|
|
|
17684
17781
|
// src/lib/parser.ts
|
|
17685
17782
|
import * as fs12 from "fs";
|
|
17686
17783
|
import * as path14 from "path";
|
|
17687
|
-
import * as
|
|
17784
|
+
import * as yaml5 from "js-yaml";
|
|
17688
17785
|
function parseHubFolder(hubFolder, opts) {
|
|
17689
17786
|
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
17690
17787
|
if (!yamlPath) {
|
|
@@ -17693,9 +17790,9 @@ function parseHubFolder(hubFolder, opts) {
|
|
|
17693
17790
|
const yamlContent = fs12.readFileSync(yamlPath, "utf-8");
|
|
17694
17791
|
let config;
|
|
17695
17792
|
try {
|
|
17696
|
-
config =
|
|
17793
|
+
config = yaml5.load(yamlContent);
|
|
17697
17794
|
} catch (err) {
|
|
17698
|
-
if (err instanceof
|
|
17795
|
+
if (err instanceof yaml5.YAMLException) {
|
|
17699
17796
|
throw expected(`Invalid YAML in ${yamlPath}: ${err.message}`);
|
|
17700
17797
|
}
|
|
17701
17798
|
throw err;
|
|
@@ -17825,9 +17922,9 @@ function parseEvalYaml(filePath, relPath, setName, hubFolder, bytesByHash) {
|
|
|
17825
17922
|
const content = fs12.readFileSync(filePath, "utf-8");
|
|
17826
17923
|
let raw;
|
|
17827
17924
|
try {
|
|
17828
|
-
raw =
|
|
17925
|
+
raw = yaml5.load(content);
|
|
17829
17926
|
} catch (err) {
|
|
17830
|
-
if (err instanceof
|
|
17927
|
+
if (err instanceof yaml5.YAMLException) {
|
|
17831
17928
|
throw expected(`Invalid YAML in ${relPath}: ${err.message}`);
|
|
17832
17929
|
}
|
|
17833
17930
|
throw err;
|
|
@@ -17952,9 +18049,9 @@ function parseJourneyYaml(filePath, relPath, hubFolder, bytesByHash) {
|
|
|
17952
18049
|
const content = fs12.readFileSync(filePath, "utf-8");
|
|
17953
18050
|
let raw;
|
|
17954
18051
|
try {
|
|
17955
|
-
raw =
|
|
18052
|
+
raw = yaml5.load(content);
|
|
17956
18053
|
} catch (err) {
|
|
17957
|
-
if (err instanceof
|
|
18054
|
+
if (err instanceof yaml5.YAMLException) {
|
|
17958
18055
|
throw expected(`Invalid YAML in ${relPath}: ${err.message}`);
|
|
17959
18056
|
}
|
|
17960
18057
|
throw err;
|
|
@@ -18014,9 +18111,9 @@ function scanAgentYamlFiles(hubFolder) {
|
|
|
18014
18111
|
const content = fs12.readFileSync(filePath, "utf-8");
|
|
18015
18112
|
let agent;
|
|
18016
18113
|
try {
|
|
18017
|
-
agent =
|
|
18114
|
+
agent = yaml5.load(content);
|
|
18018
18115
|
} catch (err) {
|
|
18019
|
-
if (err instanceof
|
|
18116
|
+
if (err instanceof yaml5.YAMLException) {
|
|
18020
18117
|
throw expected(`Invalid YAML in agents/${file}: ${err.message}`);
|
|
18021
18118
|
}
|
|
18022
18119
|
throw err;
|
|
@@ -18096,7 +18193,7 @@ var init_diff_display = __esm({
|
|
|
18096
18193
|
// src/lib/yaml-writer.ts
|
|
18097
18194
|
import * as fs13 from "fs";
|
|
18098
18195
|
import * as path15 from "path";
|
|
18099
|
-
import * as
|
|
18196
|
+
import * as yaml6 from "js-yaml";
|
|
18100
18197
|
function writeFileIfChanged(hubFolder, absPath, content, log) {
|
|
18101
18198
|
const buf = Buffer.from(content, "utf-8");
|
|
18102
18199
|
if (fileHasBytes(absPath, buf)) return;
|
|
@@ -18153,7 +18250,7 @@ function writeHubFolder(hubFolder, payload, options = {}) {
|
|
|
18153
18250
|
}
|
|
18154
18251
|
const yamlPayload = buildYamlPayload(payload);
|
|
18155
18252
|
const agentFiles = extractAgentFiles(payload);
|
|
18156
|
-
const yamlContent =
|
|
18253
|
+
const yamlContent = yaml6.dump(yamlPayload, YAML_DUMP_OPTIONS);
|
|
18157
18254
|
writeFileIfChanged(hubFolder, path15.join(hubFolder, "hub.yaml"), yamlContent, log);
|
|
18158
18255
|
if (options.seedAgentContext ?? true) {
|
|
18159
18256
|
for (const seeded of [
|
|
@@ -18200,10 +18297,10 @@ function writeHubFolder(hubFolder, payload, options = {}) {
|
|
|
18200
18297
|
function setPreviewLabelInHubYaml(hubFolder, label) {
|
|
18201
18298
|
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
18202
18299
|
if (!yamlPath) return;
|
|
18203
|
-
const obj =
|
|
18300
|
+
const obj = yaml6.load(fs13.readFileSync(yamlPath, "utf-8")) ?? {};
|
|
18204
18301
|
if (label) obj.preview_label = label;
|
|
18205
18302
|
else delete obj.preview_label;
|
|
18206
|
-
fs13.writeFileSync(yamlPath,
|
|
18303
|
+
fs13.writeFileSync(yamlPath, yaml6.dump(obj, YAML_DUMP_OPTIONS), "utf-8");
|
|
18207
18304
|
}
|
|
18208
18305
|
function buildYamlPayload(payload) {
|
|
18209
18306
|
const result = {
|
|
@@ -18248,7 +18345,7 @@ function writeAgentYamlFiles(hubFolder, agentsDir, agents, log) {
|
|
|
18248
18345
|
slugs.add(slug);
|
|
18249
18346
|
const entry = { ...agent };
|
|
18250
18347
|
delete entry.instructions;
|
|
18251
|
-
const yamlContent =
|
|
18348
|
+
const yamlContent = yaml6.dump(entry, YAML_DUMP_OPTIONS);
|
|
18252
18349
|
writeFileIfChanged(hubFolder, path15.join(agentsDir, `${slug}.yaml`), yamlContent, log);
|
|
18253
18350
|
}
|
|
18254
18351
|
return slugs;
|
|
@@ -18296,7 +18393,7 @@ function writeEvalYamlFiles(hubFolder, evals, log) {
|
|
|
18296
18393
|
fs13.mkdirSync(setDir, { recursive: true });
|
|
18297
18394
|
}
|
|
18298
18395
|
}
|
|
18299
|
-
const yamlContent =
|
|
18396
|
+
const yamlContent = yaml6.dump(buildEvalYamlObject(evalEntry, slug), YAML_DUMP_OPTIONS);
|
|
18300
18397
|
writeFileIfChanged(hubFolder, targetPath, yamlContent, log);
|
|
18301
18398
|
writtenRelPaths.add(relPath);
|
|
18302
18399
|
}
|
|
@@ -18383,7 +18480,7 @@ function writeJourneyYamlFiles(hubFolder, journeys, log) {
|
|
|
18383
18480
|
for (const journeyEntry of journeys) {
|
|
18384
18481
|
const slug = ensureUniqueSlug(slugify(journeyEntry.name), usedSlugs);
|
|
18385
18482
|
const fileName = `${slug}.yaml`;
|
|
18386
|
-
const yamlContent =
|
|
18483
|
+
const yamlContent = yaml6.dump(buildJourneyYamlObject(journeyEntry, slug), YAML_DUMP_OPTIONS);
|
|
18387
18484
|
writeFileIfChanged(hubFolder, path15.join(journeysDir, fileName), yamlContent, log);
|
|
18388
18485
|
writtenFiles.add(fileName);
|
|
18389
18486
|
}
|
|
@@ -18501,28 +18598,16 @@ var init_terminal_output = __esm({
|
|
|
18501
18598
|
}
|
|
18502
18599
|
});
|
|
18503
18600
|
|
|
18504
|
-
// src/lib/base-id.ts
|
|
18505
|
-
function isValidBaseId(id) {
|
|
18506
|
-
return BASE_ID_RE.test(id);
|
|
18507
|
-
}
|
|
18508
|
-
var BASE_ID_RE;
|
|
18509
|
-
var init_base_id = __esm({
|
|
18510
|
-
"src/lib/base-id.ts"() {
|
|
18511
|
-
"use strict";
|
|
18512
|
-
BASE_ID_RE = /^(?!\.\.?$)[A-Za-z0-9._-]{1,256}$/;
|
|
18513
|
-
}
|
|
18514
|
-
});
|
|
18515
|
-
|
|
18516
18601
|
// src/lib/base-workspace.ts
|
|
18517
18602
|
import * as fs14 from "fs";
|
|
18518
18603
|
import * as path17 from "path";
|
|
18519
|
-
import * as
|
|
18604
|
+
import * as yaml7 from "js-yaml";
|
|
18520
18605
|
function readBaseMeta(folder) {
|
|
18521
18606
|
const bytes = readFileNoFollow(folder, path17.join(folder, BASE_META_FILE));
|
|
18522
18607
|
if (bytes === null) return null;
|
|
18523
18608
|
let doc;
|
|
18524
18609
|
try {
|
|
18525
|
-
doc =
|
|
18610
|
+
doc = yaml7.load(bytes.toString("utf-8"));
|
|
18526
18611
|
} catch {
|
|
18527
18612
|
return null;
|
|
18528
18613
|
}
|
|
@@ -18572,9 +18657,9 @@ function folderForSelector(basesDir, selector) {
|
|
|
18572
18657
|
return path17.join(basesDir, selector);
|
|
18573
18658
|
}
|
|
18574
18659
|
function assertValidBaseSelector(selector, source = "base") {
|
|
18575
|
-
if (!
|
|
18660
|
+
if (!isPathSafeId(selector)) {
|
|
18576
18661
|
throw expected(
|
|
18577
|
-
`Invalid ${source} "${selector}".
|
|
18662
|
+
`Invalid ${source} "${selector}". A base selector is one folder name \u2014 ${PATH_SAFE_ID_RULE}.`
|
|
18578
18663
|
);
|
|
18579
18664
|
}
|
|
18580
18665
|
}
|
|
@@ -18611,6 +18696,12 @@ function targetBaseId(target, selector) {
|
|
|
18611
18696
|
if (selector && !selector.includes("/") && !selector.includes(path17.sep)) return selector;
|
|
18612
18697
|
return target.exists ? null : path17.basename(target.folder);
|
|
18613
18698
|
}
|
|
18699
|
+
function resolveBaseSelectorToId(gitRoot, selector) {
|
|
18700
|
+
if (!gitRoot || selector.includes("/") || selector.includes(path17.sep)) return selector;
|
|
18701
|
+
if (!isPathSafeId(selector)) return selector;
|
|
18702
|
+
const id = readBaseMeta(path17.join(resolveBasesDir(gitRoot), selector))?.base_id;
|
|
18703
|
+
return typeof id === "string" && isPathSafeId(id) ? id : selector;
|
|
18704
|
+
}
|
|
18614
18705
|
function hasBaseMetaFile(folder) {
|
|
18615
18706
|
try {
|
|
18616
18707
|
return fs14.lstatSync(path17.join(folder, BASE_META_FILE)).isFile();
|
|
@@ -18633,12 +18724,12 @@ var init_base_workspace = __esm({
|
|
|
18633
18724
|
// src/lib/subtree-routing.ts
|
|
18634
18725
|
import * as fs15 from "fs";
|
|
18635
18726
|
import * as path18 from "path";
|
|
18636
|
-
import * as
|
|
18727
|
+
import * as yaml8 from "js-yaml";
|
|
18637
18728
|
function readRepoDefaults(gitRoot) {
|
|
18638
18729
|
const file = path18.join(gitRoot, WAYAI_LAYOUT.wsDir, REPO_DEFAULTS_FILE);
|
|
18639
18730
|
let doc;
|
|
18640
18731
|
try {
|
|
18641
|
-
doc =
|
|
18732
|
+
doc = yaml8.load(fs15.readFileSync(file, "utf-8"));
|
|
18642
18733
|
} catch {
|
|
18643
18734
|
return {};
|
|
18644
18735
|
}
|
|
@@ -18683,7 +18774,7 @@ function firstSegment(p) {
|
|
|
18683
18774
|
const [head] = normalized.split("/").filter(Boolean);
|
|
18684
18775
|
return head ?? p;
|
|
18685
18776
|
}
|
|
18686
|
-
function
|
|
18777
|
+
function resolveSelectorSubtree(layout, selector, cwd) {
|
|
18687
18778
|
const parts = selector.split(path18.sep).join("/").split("/").filter(Boolean);
|
|
18688
18779
|
const qualified = parts[0] === WAYAI_LAYOUT.wsDir ? parts.slice(1) : parts;
|
|
18689
18780
|
if (qualified.length > 1) {
|
|
@@ -18749,7 +18840,7 @@ function routeSubtree(options) {
|
|
|
18749
18840
|
if (hubFlag !== void 0 && baseFlag !== void 0) {
|
|
18750
18841
|
return { ok: false, refusal: mixedInvocationRefusal(verb, hubFlag, baseFlag) };
|
|
18751
18842
|
}
|
|
18752
|
-
const fromPositional = positional !== void 0 ?
|
|
18843
|
+
const fromPositional = positional !== void 0 ? resolveSelectorSubtree(layout, positional, cwd) : void 0;
|
|
18753
18844
|
if (fromPositional?.kind === "both") {
|
|
18754
18845
|
return {
|
|
18755
18846
|
ok: false,
|
|
@@ -18854,12 +18945,12 @@ async function createDataClient(orgId) {
|
|
|
18854
18945
|
return orgId2;
|
|
18855
18946
|
}
|
|
18856
18947
|
return {
|
|
18857
|
-
async request(method,
|
|
18858
|
-
const envelope = await api.dataRequest(method,
|
|
18948
|
+
async request(method, path35, body) {
|
|
18949
|
+
const envelope = await api.dataRequest(method, path35, body, org);
|
|
18859
18950
|
return envelope.data;
|
|
18860
18951
|
},
|
|
18861
|
-
async requestRaw(method,
|
|
18862
|
-
const body_ = await api.dataRequest(method,
|
|
18952
|
+
async requestRaw(method, path35, body) {
|
|
18953
|
+
const body_ = await api.dataRequest(method, path35, body, org);
|
|
18863
18954
|
return body_;
|
|
18864
18955
|
},
|
|
18865
18956
|
async collectPages(makePath) {
|
|
@@ -18933,38 +19024,17 @@ var init_client = __esm({
|
|
|
18933
19024
|
}
|
|
18934
19025
|
});
|
|
18935
19026
|
|
|
18936
|
-
// src/lib/base-binding.ts
|
|
18937
|
-
var binding2, getBaseBindingPath, readBaseBinding, writeBaseBinding, clearBaseBinding, autoBindBaseIfUnbound, assertBaseMatchesBinding, assertNoBindingBlocksBaseCreation;
|
|
18938
|
-
var init_base_binding = __esm({
|
|
18939
|
-
"src/lib/base-binding.ts"() {
|
|
18940
|
-
"use strict";
|
|
18941
|
-
init_base_id();
|
|
18942
|
-
init_worktree_binding();
|
|
18943
|
-
binding2 = createWorktreeBinding({
|
|
18944
|
-
filename: "wayai-base-binding",
|
|
18945
|
-
isValidId: isValidBaseId,
|
|
18946
|
-
noun: "base",
|
|
18947
|
-
idLabel: "base id (must be a slug)",
|
|
18948
|
-
unbindCommand: "wayai bases unbind",
|
|
18949
|
-
useCommand: "wayai bases use"
|
|
18950
|
-
});
|
|
18951
|
-
getBaseBindingPath = binding2.getBindingPath;
|
|
18952
|
-
readBaseBinding = binding2.readBinding;
|
|
18953
|
-
writeBaseBinding = binding2.writeBinding;
|
|
18954
|
-
clearBaseBinding = binding2.clearBinding;
|
|
18955
|
-
autoBindBaseIfUnbound = binding2.autoBindIfUnbound;
|
|
18956
|
-
assertBaseMatchesBinding = binding2.assertMatchesBinding;
|
|
18957
|
-
assertNoBindingBlocksBaseCreation = binding2.assertNoBindingBlocksCreation;
|
|
18958
|
-
}
|
|
18959
|
-
});
|
|
18960
|
-
|
|
18961
19027
|
// src/data/helpers.ts
|
|
18962
19028
|
import { readFileSync as readFileSync16 } from "fs";
|
|
18963
19029
|
function pathSegment(id, label = "id") {
|
|
19030
|
+
if (!isPathSafeId(id)) {
|
|
19031
|
+
throw expected(`Invalid ${label}: ${JSON.stringify(id)}. An id may use ${PATH_SAFE_ID_RULE}.`);
|
|
19032
|
+
}
|
|
19033
|
+
return encodeURIComponent(id);
|
|
19034
|
+
}
|
|
19035
|
+
function basePathSegment(id, label = "base id") {
|
|
18964
19036
|
if (!isValidBaseId(id)) {
|
|
18965
|
-
throw expected(
|
|
18966
|
-
`Invalid ${label}: ${JSON.stringify(id)}. Ids are slugs \u2014 letters, digits, dot, dash and underscore only.`
|
|
18967
|
-
);
|
|
19037
|
+
throw expected(`Invalid ${label}: ${JSON.stringify(id)}. Base ids are slugs \u2014 ${BASE_ID_RULE}.`);
|
|
18968
19038
|
}
|
|
18969
19039
|
return encodeURIComponent(id);
|
|
18970
19040
|
}
|
|
@@ -19110,9 +19180,9 @@ var init_types2 = __esm({
|
|
|
19110
19180
|
// src/data/config-as-code/config-writer.ts
|
|
19111
19181
|
import * as fs16 from "fs";
|
|
19112
19182
|
import * as path19 from "path";
|
|
19113
|
-
import * as
|
|
19114
|
-
function
|
|
19115
|
-
return
|
|
19183
|
+
import * as yaml9 from "js-yaml";
|
|
19184
|
+
function dump5(value) {
|
|
19185
|
+
return yaml9.dump(value, YAML_DUMP_OPTIONS);
|
|
19116
19186
|
}
|
|
19117
19187
|
function omitUndefined(obj) {
|
|
19118
19188
|
const out = {};
|
|
@@ -19170,7 +19240,7 @@ function writeBaseFolder(folder, meta, config) {
|
|
|
19170
19240
|
`Refusing to write ${folder}: the path crosses a symlink. Remove it and pull again.`
|
|
19171
19241
|
);
|
|
19172
19242
|
}
|
|
19173
|
-
writeFileIfChanged(folder, path19.join(folder, BASE_META_FILE),
|
|
19243
|
+
writeFileIfChanged(folder, path19.join(folder, BASE_META_FILE), dump5(metaFileObject(meta)), delta);
|
|
19174
19244
|
for (const kind of ENTITY_KINDS) {
|
|
19175
19245
|
const dir = path19.join(folder, ENTITY_DIRS[kind]);
|
|
19176
19246
|
const entities = config[kind] ?? [];
|
|
@@ -19178,13 +19248,13 @@ function writeBaseFolder(folder, meta, config) {
|
|
|
19178
19248
|
for (const raw of entities) {
|
|
19179
19249
|
const entity = raw;
|
|
19180
19250
|
const id = String(entity.id);
|
|
19181
|
-
if (!
|
|
19251
|
+
if (!isPathSafeId(id)) {
|
|
19182
19252
|
console.warn(` Warning: skipping ${kind} entity with unusable id ${JSON.stringify(id)}.`);
|
|
19183
19253
|
continue;
|
|
19184
19254
|
}
|
|
19185
19255
|
const file = `${id}.yaml`;
|
|
19186
19256
|
keep.add(file);
|
|
19187
|
-
writeFileIfChanged(folder, path19.join(dir, file),
|
|
19257
|
+
writeFileIfChanged(folder, path19.join(dir, file), dump5(toFileObject(kind, entity)), delta);
|
|
19188
19258
|
}
|
|
19189
19259
|
pruneOrphans(folder, dir, keep, delta);
|
|
19190
19260
|
}
|
|
@@ -19345,7 +19415,7 @@ var init_api = __esm({
|
|
|
19345
19415
|
// src/data/config-as-code/config-parser.ts
|
|
19346
19416
|
import * as fs17 from "fs";
|
|
19347
19417
|
import * as path20 from "path";
|
|
19348
|
-
import * as
|
|
19418
|
+
import * as yaml10 from "js-yaml";
|
|
19349
19419
|
function readEntityDir(folder, dir) {
|
|
19350
19420
|
if (!ensureRealSubdirNoSymlink(folder, dir, false)) {
|
|
19351
19421
|
throw expected(`Refusing to read ${dir}: it is a symlink, not a config directory.`);
|
|
@@ -19361,7 +19431,7 @@ function readEntityDir(folder, dir) {
|
|
|
19361
19431
|
}
|
|
19362
19432
|
let parsed;
|
|
19363
19433
|
try {
|
|
19364
|
-
parsed =
|
|
19434
|
+
parsed = yaml10.load(bytes.toString("utf-8"));
|
|
19365
19435
|
} catch (err) {
|
|
19366
19436
|
throw expected(`Failed to parse ${abs}: ${err instanceof Error ? err.message : String(err)}`);
|
|
19367
19437
|
}
|
|
@@ -19502,7 +19572,7 @@ function requireGitRoot(gitRoot) {
|
|
|
19502
19572
|
return gitRoot;
|
|
19503
19573
|
}
|
|
19504
19574
|
async function writeProductionMirror(client, basesDir, prodId, record) {
|
|
19505
|
-
if (!
|
|
19575
|
+
if (!isPathSafeId(prodId)) {
|
|
19506
19576
|
throw expected(`Refusing to mirror base ${JSON.stringify(prodId)}: not a usable base id.`);
|
|
19507
19577
|
}
|
|
19508
19578
|
const config = await getConfig(client, prodId);
|
|
@@ -19543,7 +19613,7 @@ async function pullBase(gitRootOrNull, selector, args2) {
|
|
|
19543
19613
|
console.log(`Production base mirrored (read-only) \u2192 ${folder}`);
|
|
19544
19614
|
return;
|
|
19545
19615
|
}
|
|
19546
|
-
|
|
19616
|
+
assertInScope("bases", baseId);
|
|
19547
19617
|
if (target.exists && !autoConfirm) {
|
|
19548
19618
|
const ok = await confirm(
|
|
19549
19619
|
`Overwrite local files in ${path21.relative(gitRoot, target.folder)} with the server config for "${sanitizeTerminalText(baseId)}"?`
|
|
@@ -19562,7 +19632,7 @@ async function pullBase(gitRootOrNull, selector, args2) {
|
|
|
19562
19632
|
);
|
|
19563
19633
|
if (!isFirstPull) printLocalFileChanges(delta);
|
|
19564
19634
|
console.log(" Credential values are not written. Manage them with `wayai bases credentials`.");
|
|
19565
|
-
|
|
19635
|
+
seedScopeIfEmpty("bases", baseId);
|
|
19566
19636
|
if (record.origin_base_id) {
|
|
19567
19637
|
await mirrorLinkedProduction(client, basesDir, record.origin_base_id);
|
|
19568
19638
|
}
|
|
@@ -19587,7 +19657,7 @@ async function createDeclaredPreview(client, target, parsed, autoConfirm) {
|
|
|
19587
19657
|
);
|
|
19588
19658
|
}
|
|
19589
19659
|
const name = meta.name ?? path21.basename(target.folder);
|
|
19590
|
-
|
|
19660
|
+
assertScopeAllowsCreation("bases", name);
|
|
19591
19661
|
if (!autoConfirm) {
|
|
19592
19662
|
const ok = await confirm(
|
|
19593
19663
|
`Create a new preview "${sanitizeTerminalText(name)}" from "${sanitizeTerminalText(meta.origin_base_id)}"?`
|
|
@@ -19606,7 +19676,7 @@ async function createDeclaredPreview(client, target, parsed, autoConfirm) {
|
|
|
19606
19676
|
writeBaseFolder(target.folder, { ...meta, ...metaFromRecord(record, id) }, config);
|
|
19607
19677
|
console.log(`Created preview "${sanitizeTerminalText(id)}".`);
|
|
19608
19678
|
printWarnings((record.warnings ?? []).map((w) => sanitizeTerminalText(w.message)));
|
|
19609
|
-
|
|
19679
|
+
seedScopeIfEmpty("bases", id);
|
|
19610
19680
|
return id;
|
|
19611
19681
|
}
|
|
19612
19682
|
async function pushBase(gitRootOrNull, selector, args2) {
|
|
@@ -19644,13 +19714,13 @@ async function pushBase(gitRootOrNull, selector, args2) {
|
|
|
19644
19714
|
`"${sanitizeTerminalText(baseId)}" is a ${sanitizeTerminalText(record.environment)} base. Push operates on previews \u2014 promote with \`wayai bases promote\`.`
|
|
19645
19715
|
);
|
|
19646
19716
|
}
|
|
19647
|
-
|
|
19717
|
+
assertInScope("bases", baseId);
|
|
19648
19718
|
}
|
|
19649
19719
|
const diff = await diffConfig(client, baseId, config);
|
|
19650
19720
|
printLintWarnings(diff.warnings);
|
|
19651
19721
|
if (isDiffEmpty(diff)) {
|
|
19652
19722
|
console.log(`No changes \u2014 preview "${sanitizeTerminalText(baseId)}" already matches your files.`);
|
|
19653
|
-
if (!dryRun)
|
|
19723
|
+
if (!dryRun) seedScopeIfEmpty("bases", baseId);
|
|
19654
19724
|
return;
|
|
19655
19725
|
}
|
|
19656
19726
|
console.log(renderDiff(diff));
|
|
@@ -19702,7 +19772,7 @@ Delete ${removals.length} server ${word} not in your files? Record types cascade
|
|
|
19702
19772
|
}
|
|
19703
19773
|
console.log(`
|
|
19704
19774
|
Pushed to preview "${sanitizeTerminalText(baseId)}".`);
|
|
19705
|
-
|
|
19775
|
+
seedScopeIfEmpty("bases", baseId);
|
|
19706
19776
|
}
|
|
19707
19777
|
var init_sync = __esm({
|
|
19708
19778
|
"src/data/config-as-code/sync.ts"() {
|
|
@@ -19714,7 +19784,7 @@ var init_sync = __esm({
|
|
|
19714
19784
|
init_terminal_output();
|
|
19715
19785
|
init_base_id();
|
|
19716
19786
|
init_push();
|
|
19717
|
-
|
|
19787
|
+
init_worktree_scope();
|
|
19718
19788
|
init_api();
|
|
19719
19789
|
init_config_parser();
|
|
19720
19790
|
init_config_writer();
|
|
@@ -19741,7 +19811,7 @@ __export(push_exports, {
|
|
|
19741
19811
|
});
|
|
19742
19812
|
import * as fs18 from "fs";
|
|
19743
19813
|
import * as path22 from "path";
|
|
19744
|
-
import * as
|
|
19814
|
+
import * as yaml11 from "js-yaml";
|
|
19745
19815
|
function parseArgs5(args2) {
|
|
19746
19816
|
let autoConfirm = false;
|
|
19747
19817
|
let label;
|
|
@@ -19855,7 +19925,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
19855
19925
|
for (const file of yamlFiles) {
|
|
19856
19926
|
try {
|
|
19857
19927
|
const content = fs18.readFileSync(path22.join(agentsDir, file), "utf-8");
|
|
19858
|
-
const agent =
|
|
19928
|
+
const agent = yaml11.load(content);
|
|
19859
19929
|
if (agent?.id && agent.name) {
|
|
19860
19930
|
agentsWithIds.push({ id: agent.id, name: agent.name });
|
|
19861
19931
|
}
|
|
@@ -19868,7 +19938,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
19868
19938
|
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
19869
19939
|
if (!yamlPath) return;
|
|
19870
19940
|
const yamlContent = fs18.readFileSync(yamlPath, "utf-8");
|
|
19871
|
-
const config =
|
|
19941
|
+
const config = yaml11.load(yamlContent);
|
|
19872
19942
|
agentsWithIds = (config.agents || []).filter((a) => !!a.id && !!a.name);
|
|
19873
19943
|
}
|
|
19874
19944
|
if (agentsWithIds.length === 0) return;
|
|
@@ -20018,7 +20088,7 @@ async function pushSingleHub(client, hubId, hubFolder, autoConfirm, organization
|
|
|
20018
20088
|
} else {
|
|
20019
20089
|
console.log("No changes to push; folder renamed.");
|
|
20020
20090
|
}
|
|
20021
|
-
|
|
20091
|
+
seedScopeIfEmpty("hubs", hubId);
|
|
20022
20092
|
return true;
|
|
20023
20093
|
}
|
|
20024
20094
|
console.log("\nChanges to push:");
|
|
@@ -20034,7 +20104,7 @@ async function pushSingleHub(client, hubId, hubFolder, autoConfirm, organization
|
|
|
20034
20104
|
const result = await client.push(hubId, wireConfig, organizationId);
|
|
20035
20105
|
printSyncResult(result);
|
|
20036
20106
|
await syncAfterPush(client, hubId, hubFolder, organizationId);
|
|
20037
|
-
|
|
20107
|
+
seedScopeIfEmpty("hubs", hubId);
|
|
20038
20108
|
return true;
|
|
20039
20109
|
}
|
|
20040
20110
|
function selectExistingHub(workspaceDir, allHubs, selector, wsLabel) {
|
|
@@ -20100,7 +20170,7 @@ hub_environment: preview
|
|
|
20100
20170
|
${content}`;
|
|
20101
20171
|
}
|
|
20102
20172
|
fs18.writeFileSync(hubYamlPath, updated, "utf-8");
|
|
20103
|
-
|
|
20173
|
+
seedScopeIfEmpty("hubs", hubId);
|
|
20104
20174
|
await pushSingleHub(client, hubId, newHub.hubFolder, opts.autoConfirm, opts.organizationId, { skipAgentRename: true });
|
|
20105
20175
|
}
|
|
20106
20176
|
function reportUnresolvedPushTarget(reason, existingHubs, newHubs, selector, wsLabel) {
|
|
@@ -20170,11 +20240,11 @@ async function pushCommand(args2) {
|
|
|
20170
20240
|
console.warn("Note: --label is only used when creating a new hub. To change an existing hub's label, use `wayai relabel`.");
|
|
20171
20241
|
}
|
|
20172
20242
|
console.log(`Target hub: ${path22.basename(existing.hubFolder)} (${existing.hubId})`);
|
|
20173
|
-
|
|
20243
|
+
assertInScope("hubs", existing.hubId, path22.basename(existing.hubFolder));
|
|
20174
20244
|
await pushSingleHub(client, existing.hubId, existing.hubFolder, autoConfirm, organizationId);
|
|
20175
20245
|
return;
|
|
20176
20246
|
}
|
|
20177
|
-
|
|
20247
|
+
assertScopeAllowsCreation("hubs", resolution.target.hub.hubName);
|
|
20178
20248
|
await createAndPushNewHub(client, resolution.target.hub, { autoConfirm, label, organizationId });
|
|
20179
20249
|
}
|
|
20180
20250
|
var LOCAL_CHANGE_LIST_CAP;
|
|
@@ -20193,7 +20263,7 @@ var init_push = __esm({
|
|
|
20193
20263
|
init_layout();
|
|
20194
20264
|
init_workspace_files();
|
|
20195
20265
|
init_repo_config();
|
|
20196
|
-
|
|
20266
|
+
init_worktree_scope();
|
|
20197
20267
|
init_subtree_routing();
|
|
20198
20268
|
LOCAL_CHANGE_LIST_CAP = 20;
|
|
20199
20269
|
}
|
|
@@ -20267,7 +20337,7 @@ async function pullCommand(args2) {
|
|
|
20267
20337
|
console.log(`Production hub mirrored (read-only) \u2192 ${folder}`);
|
|
20268
20338
|
return;
|
|
20269
20339
|
}
|
|
20270
|
-
|
|
20340
|
+
assertInScope("hubs", hubId);
|
|
20271
20341
|
let hubFolder = existingFolder;
|
|
20272
20342
|
let wroteFiles = false;
|
|
20273
20343
|
if (!hubFolder) {
|
|
@@ -20326,7 +20396,7 @@ async function pullCommand(args2) {
|
|
|
20326
20396
|
printLocalFileChanges(delta);
|
|
20327
20397
|
}
|
|
20328
20398
|
}
|
|
20329
|
-
if (wroteFiles)
|
|
20399
|
+
if (wroteFiles) seedScopeIfEmpty("hubs", hubId);
|
|
20330
20400
|
if (payload.production_hub_id) {
|
|
20331
20401
|
await mirrorLinkedProduction2(client, workspaceDir, payload.production_hub_id, organizationId);
|
|
20332
20402
|
}
|
|
@@ -20388,7 +20458,7 @@ var init_pull = __esm({
|
|
|
20388
20458
|
init_layout();
|
|
20389
20459
|
init_workspace_files();
|
|
20390
20460
|
init_repo_config();
|
|
20391
|
-
|
|
20461
|
+
init_worktree_scope();
|
|
20392
20462
|
init_subtree_routing();
|
|
20393
20463
|
MIRROR_MARKER_PREFIX2 = "# Read-only mirror of production hub";
|
|
20394
20464
|
}
|
|
@@ -20454,7 +20524,7 @@ async function createCommand(args2) {
|
|
|
20454
20524
|
}
|
|
20455
20525
|
process.exit(1);
|
|
20456
20526
|
}
|
|
20457
|
-
|
|
20527
|
+
assertScopeAllowsCreation("hubs", resolution.hub.hubName);
|
|
20458
20528
|
await createAndPushNewHub(client, resolution.hub, { autoConfirm, label, organizationId });
|
|
20459
20529
|
}
|
|
20460
20530
|
var init_create = __esm({
|
|
@@ -20466,7 +20536,7 @@ var init_create = __esm({
|
|
|
20466
20536
|
init_workspace();
|
|
20467
20537
|
init_layout();
|
|
20468
20538
|
init_repo_config();
|
|
20469
|
-
|
|
20539
|
+
init_worktree_scope();
|
|
20470
20540
|
}
|
|
20471
20541
|
});
|
|
20472
20542
|
|
|
@@ -20619,7 +20689,7 @@ async function replicateCommand(args2) {
|
|
|
20619
20689
|
payload.preview_label,
|
|
20620
20690
|
payload.branch_name
|
|
20621
20691
|
);
|
|
20622
|
-
|
|
20692
|
+
seedScopeIfEmpty("hubs", previewHubId);
|
|
20623
20693
|
if (folderPreExisted) printLocalFileChanges(delta);
|
|
20624
20694
|
console.log(`Preview written to ${path25.basename(hubFolder)}`);
|
|
20625
20695
|
console.log(` Switch to it with: wayai use ${path25.basename(hubFolder)}`);
|
|
@@ -20635,7 +20705,7 @@ var init_replicate = __esm({
|
|
|
20635
20705
|
init_workspace();
|
|
20636
20706
|
init_layout();
|
|
20637
20707
|
init_repo_config();
|
|
20638
|
-
|
|
20708
|
+
init_worktree_scope();
|
|
20639
20709
|
init_contracts();
|
|
20640
20710
|
}
|
|
20641
20711
|
});
|
|
@@ -20698,7 +20768,7 @@ async function relabelCommand(args2) {
|
|
|
20698
20768
|
console.log("This is a read-only production mirror \u2014 production hubs have no preview label. Relabel the linked preview hub instead.");
|
|
20699
20769
|
return;
|
|
20700
20770
|
}
|
|
20701
|
-
|
|
20771
|
+
assertInScope("hubs", target.hubId, path26.basename(target.hubFolder));
|
|
20702
20772
|
console.log(normalizedLabel ? `Setting preview label to "${normalizedLabel}"...` : "Clearing preview label...");
|
|
20703
20773
|
const { data } = await client.relabelPreview(target.hubId, normalizedLabel);
|
|
20704
20774
|
const row = data[0];
|
|
@@ -20727,7 +20797,7 @@ var init_relabel = __esm({
|
|
|
20727
20797
|
init_workspace();
|
|
20728
20798
|
init_layout();
|
|
20729
20799
|
init_repo_config();
|
|
20730
|
-
|
|
20800
|
+
init_worktree_scope();
|
|
20731
20801
|
init_contracts();
|
|
20732
20802
|
}
|
|
20733
20803
|
});
|
|
@@ -20854,7 +20924,7 @@ async function publishCommand(args2) {
|
|
|
20854
20924
|
return;
|
|
20855
20925
|
}
|
|
20856
20926
|
}
|
|
20857
|
-
|
|
20927
|
+
assertInScope("hubs", hubId, hubFolder ? path27.basename(hubFolder) : void 0);
|
|
20858
20928
|
await runPublish(client, { hubId, localConfig, organizationId, autoConfirm });
|
|
20859
20929
|
}
|
|
20860
20930
|
var STATUS_STYLE;
|
|
@@ -20870,7 +20940,7 @@ var init_publish = __esm({
|
|
|
20870
20940
|
init_layout();
|
|
20871
20941
|
init_resource_files();
|
|
20872
20942
|
init_repo_config();
|
|
20873
|
-
|
|
20943
|
+
init_worktree_scope();
|
|
20874
20944
|
STATUS_STYLE = {
|
|
20875
20945
|
added: { sym: "+", color: 32 },
|
|
20876
20946
|
// green
|
|
@@ -20882,77 +20952,151 @@ var init_publish = __esm({
|
|
|
20882
20952
|
}
|
|
20883
20953
|
});
|
|
20884
20954
|
|
|
20955
|
+
// src/lib/scope-selector.ts
|
|
20956
|
+
import * as path28 from "path";
|
|
20957
|
+
function findAddFlag(args2) {
|
|
20958
|
+
return args2.find((arg) => arg === "--add" || arg.startsWith("--add="));
|
|
20959
|
+
}
|
|
20960
|
+
function isValuedFlag(token) {
|
|
20961
|
+
return token.includes("=");
|
|
20962
|
+
}
|
|
20963
|
+
function resolveScopeSelector(verb, args2) {
|
|
20964
|
+
const { hubFlag, baseFlag, positional } = parseRoutingTokens(args2);
|
|
20965
|
+
if (hubFlag !== void 0 && baseFlag !== void 0) {
|
|
20966
|
+
throw expected(mixedInvocationRefusal(verb, hubFlag, baseFlag));
|
|
20967
|
+
}
|
|
20968
|
+
assertValueIsNotAFlag(verb, "--hub", hubFlag);
|
|
20969
|
+
assertValueIsNotAFlag(verb, "--base", baseFlag);
|
|
20970
|
+
assertFlagWasGivenAValue(verb, "--hub", args2, hubFlag);
|
|
20971
|
+
assertFlagWasGivenAValue(verb, "--base", args2, baseFlag);
|
|
20972
|
+
if (hubFlag !== void 0) return { axis: "hubs", target: hubFlag, gitRoot: findGitRoot() };
|
|
20973
|
+
if (baseFlag !== void 0) return { axis: "bases", target: baseFlag, gitRoot: findGitRoot() };
|
|
20974
|
+
if (positional === void 0) return null;
|
|
20975
|
+
const gitRoot = findGitRoot();
|
|
20976
|
+
const layout = gitRoot ? resolveLayout(gitRoot) : null;
|
|
20977
|
+
const resolved = resolveSelectorSubtree(layout, positional, process.cwd());
|
|
20978
|
+
if (resolved.kind === "both") {
|
|
20979
|
+
throw expected(mixedInvocationRefusal(verb, resolved.target, resolved.target));
|
|
20980
|
+
}
|
|
20981
|
+
if (resolved.kind === "hubs" || resolved.kind === "bases") {
|
|
20982
|
+
return { axis: resolved.kind, target: resolved.target, gitRoot };
|
|
20983
|
+
}
|
|
20984
|
+
return { axis: "hubs", target: positional, gitRoot };
|
|
20985
|
+
}
|
|
20986
|
+
function assertValueIsNotAFlag(verb, flag, captured) {
|
|
20987
|
+
if (captured === void 0 || !captured.startsWith("-")) return;
|
|
20988
|
+
throw refusal(verb, flag, `but got ${JSON.stringify(captured)} \u2014 which is a flag, not a hub or base`);
|
|
20989
|
+
}
|
|
20990
|
+
function assertFlagWasGivenAValue(verb, flag, args2, captured) {
|
|
20991
|
+
if (captured !== void 0 && captured !== "") return;
|
|
20992
|
+
if (!args2.some((arg) => arg === flag || arg.startsWith(`${flag}=`))) return;
|
|
20993
|
+
throw refusal(verb, flag, "but no target followed it");
|
|
20994
|
+
}
|
|
20995
|
+
function refusal(verb, flag, problem) {
|
|
20996
|
+
return expected(
|
|
20997
|
+
`\`wayai ${verb} ${flag}\` needs a target, ${problem}.
|
|
20998
|
+
wayai ${verb} ${flag} <hub-or-base>`
|
|
20999
|
+
);
|
|
21000
|
+
}
|
|
21001
|
+
function resolveHubSelectorToId(gitRoot, selector) {
|
|
21002
|
+
if (UUID_RE2.test(selector)) return selector;
|
|
21003
|
+
const workspaceDir = detectWorkspace()?.workspaceDir ?? (gitRoot ? resolveLayout(gitRoot).hubsDir : null);
|
|
21004
|
+
if (!workspaceDir) {
|
|
21005
|
+
throw expected("Not inside a git repository, and no UUID provided.");
|
|
21006
|
+
}
|
|
21007
|
+
const match = findHubByFolderName(workspaceDir, selector);
|
|
21008
|
+
if (match) return match.hubId;
|
|
21009
|
+
const newHubs = scanNewHubs(workspaceDir);
|
|
21010
|
+
const pending = newHubs.find((h) => path28.basename(h.hubFolder) === selector);
|
|
21011
|
+
if (pending) {
|
|
21012
|
+
throw expected(
|
|
21013
|
+
`"${selector}" is a new hub that hasn't been created on the platform yet, so it has no id to bind to.
|
|
21014
|
+
Create it first \u2014 the worktree scope picks it up automatically afterward:
|
|
21015
|
+
wayai create ${selector}`
|
|
21016
|
+
);
|
|
21017
|
+
}
|
|
21018
|
+
throw expected(
|
|
21019
|
+
[
|
|
21020
|
+
`No hub matching "${selector}" found in ${hubsDirLabel(gitRoot)}/. Pass a UUID or a folder name from:`,
|
|
21021
|
+
...scanWorkspaceHubs(workspaceDir).map((h) => ` ${path28.basename(h.hubFolder)} (${h.hubId})`),
|
|
21022
|
+
...newHubs.map(
|
|
21023
|
+
(h) => ` ${path28.basename(h.hubFolder)} (new \u2014 "${h.hubName}", run \`wayai create ${path28.basename(h.hubFolder)}\`)`
|
|
21024
|
+
)
|
|
21025
|
+
].join("\n")
|
|
21026
|
+
);
|
|
21027
|
+
}
|
|
21028
|
+
function resolveScopeTarget(selector) {
|
|
21029
|
+
const { axis, target, gitRoot } = selector;
|
|
21030
|
+
if (axis === "hubs") {
|
|
21031
|
+
return { axis, id: resolveHubSelectorToId(gitRoot, target) };
|
|
21032
|
+
}
|
|
21033
|
+
const id = resolveBaseSelectorToId(gitRoot, target);
|
|
21034
|
+
assertValidBaseSelector(id, "base id");
|
|
21035
|
+
return { axis, id };
|
|
21036
|
+
}
|
|
21037
|
+
var init_scope_selector = __esm({
|
|
21038
|
+
"src/lib/scope-selector.ts"() {
|
|
21039
|
+
"use strict";
|
|
21040
|
+
init_expected();
|
|
21041
|
+
init_base_workspace();
|
|
21042
|
+
init_layout();
|
|
21043
|
+
init_subtree_routing();
|
|
21044
|
+
init_utils();
|
|
21045
|
+
init_workspace();
|
|
21046
|
+
}
|
|
21047
|
+
});
|
|
21048
|
+
|
|
20885
21049
|
// src/commands/use.ts
|
|
20886
21050
|
var use_exports = {};
|
|
20887
21051
|
__export(use_exports, {
|
|
20888
21052
|
useCommand: () => useCommand
|
|
20889
21053
|
});
|
|
20890
|
-
import * as path28 from "path";
|
|
20891
21054
|
async function useCommand(args2) {
|
|
20892
|
-
const
|
|
20893
|
-
if (
|
|
20894
|
-
|
|
20895
|
-
|
|
20896
|
-
|
|
20897
|
-
|
|
20898
|
-
|
|
20899
|
-
|
|
20900
|
-
|
|
20901
|
-
const workspace = detectWorkspace();
|
|
20902
|
-
const gitRoot = findGitRoot();
|
|
20903
|
-
const workspaceDir = workspace?.workspaceDir ?? (gitRoot ? resolveLayout(gitRoot).hubsDir : null);
|
|
20904
|
-
if (!workspaceDir) {
|
|
20905
|
-
console.error("Not inside a git repository, and no UUID provided.");
|
|
20906
|
-
process.exit(1);
|
|
20907
|
-
}
|
|
20908
|
-
const wsLabel = hubsDirLabel(gitRoot);
|
|
20909
|
-
const match = findHubByFolderName(workspaceDir, target);
|
|
20910
|
-
if (!match) {
|
|
20911
|
-
const newHubs = scanNewHubs(workspaceDir);
|
|
20912
|
-
const pending = newHubs.find((h) => path28.basename(h.hubFolder) === target);
|
|
20913
|
-
if (pending) {
|
|
20914
|
-
console.error(
|
|
20915
|
-
`"${target}" is a new hub that hasn't been created on the platform yet, so it has no id to bind to.
|
|
20916
|
-
Create it first \u2014 the worktree binds automatically afterward:
|
|
20917
|
-
wayai create ${target}`
|
|
20918
|
-
);
|
|
20919
|
-
process.exit(1);
|
|
20920
|
-
}
|
|
20921
|
-
console.error(`No hub matching "${target}" found in ${wsLabel}/. Pass a UUID or a folder name from:`);
|
|
20922
|
-
for (const h of scanWorkspaceHubs(workspaceDir)) {
|
|
20923
|
-
console.error(` ${path28.basename(h.hubFolder)} (${h.hubId})`);
|
|
20924
|
-
}
|
|
20925
|
-
for (const h of newHubs) {
|
|
20926
|
-
console.error(` ${path28.basename(h.hubFolder)} (new \u2014 "${h.hubName}", run \`wayai create ${path28.basename(h.hubFolder)}\`)`);
|
|
20927
|
-
}
|
|
20928
|
-
process.exit(1);
|
|
20929
|
-
}
|
|
20930
|
-
hubId = match.hubId;
|
|
21055
|
+
const addFlag = findAddFlag(args2);
|
|
21056
|
+
if (addFlag !== void 0 && isValuedFlag(addFlag)) {
|
|
21057
|
+
throw expected(
|
|
21058
|
+
[
|
|
21059
|
+
`\`--add\` is a boolean flag \u2014 write it bare, not ${JSON.stringify(addFlag)}.`,
|
|
21060
|
+
" wayai use --add <selector> # widen the worktree scope",
|
|
21061
|
+
" wayai use <selector> # replace that axis instead"
|
|
21062
|
+
].join("\n")
|
|
21063
|
+
);
|
|
20931
21064
|
}
|
|
20932
|
-
const
|
|
20933
|
-
|
|
20934
|
-
|
|
21065
|
+
const add = addFlag !== void 0;
|
|
21066
|
+
const selector = resolveScopeSelector("use", args2);
|
|
21067
|
+
if (!selector) throw expected(USAGE);
|
|
21068
|
+
const { axis, id } = resolveScopeTarget(selector);
|
|
21069
|
+
const noun = axisNoun(axis);
|
|
21070
|
+
if (add) {
|
|
21071
|
+
const widened = addToScope(axis, id);
|
|
21072
|
+
console.log(
|
|
21073
|
+
widened ? `Worktree scope widened \u2014 now ${describeAxis(axis, widened)}.` : `Worktree scope already includes ${noun} ${id}.`
|
|
21074
|
+
);
|
|
20935
21075
|
return;
|
|
20936
21076
|
}
|
|
20937
|
-
|
|
20938
|
-
|
|
20939
|
-
|
|
20940
|
-
|
|
20941
|
-
process.exit(1);
|
|
20942
|
-
}
|
|
20943
|
-
if (previous) {
|
|
20944
|
-
console.log(`Worktree rebound: ${previous} \u2192 ${hubId}`);
|
|
20945
|
-
} else {
|
|
20946
|
-
console.log(`Worktree bound to hub ${hubId}.`);
|
|
21077
|
+
const previous = readScope()[axis];
|
|
21078
|
+
if (previous.length === 1 && previous[0] === id) {
|
|
21079
|
+
console.log(`Worktree already bound to ${noun} ${id}.`);
|
|
21080
|
+
return;
|
|
20947
21081
|
}
|
|
21082
|
+
setScopeAxis(axis, [id]);
|
|
21083
|
+
console.log(
|
|
21084
|
+
previous.length > 0 ? `Worktree rebound: ${previous.join(", ")} \u2192 ${id}.` : `Worktree bound to ${noun} ${id}.`
|
|
21085
|
+
);
|
|
20948
21086
|
}
|
|
21087
|
+
var USAGE;
|
|
20949
21088
|
var init_use = __esm({
|
|
20950
21089
|
"src/commands/use.ts"() {
|
|
20951
21090
|
"use strict";
|
|
20952
|
-
|
|
20953
|
-
|
|
20954
|
-
|
|
20955
|
-
|
|
21091
|
+
init_expected();
|
|
21092
|
+
init_scope_selector();
|
|
21093
|
+
init_worktree_scope();
|
|
21094
|
+
USAGE = [
|
|
21095
|
+
"Usage: wayai use [--add] <hub_uuid|folder-name|hubs/<name>|bases/<name>>",
|
|
21096
|
+
" wayai use [--add] --hub <hub> | --base <base>",
|
|
21097
|
+
"",
|
|
21098
|
+
" --add widen the worktree scope instead of replacing that axis"
|
|
21099
|
+
].join("\n");
|
|
20956
21100
|
}
|
|
20957
21101
|
});
|
|
20958
21102
|
|
|
@@ -21054,19 +21198,71 @@ var unbind_exports = {};
|
|
|
21054
21198
|
__export(unbind_exports, {
|
|
21055
21199
|
unbindCommand: () => unbindCommand
|
|
21056
21200
|
});
|
|
21057
|
-
async function unbindCommand(
|
|
21058
|
-
const
|
|
21059
|
-
if (
|
|
21060
|
-
|
|
21201
|
+
async function unbindCommand(args2) {
|
|
21202
|
+
const addFlag = findAddFlag(args2);
|
|
21203
|
+
if (addFlag !== void 0) {
|
|
21204
|
+
throw expected(
|
|
21205
|
+
[
|
|
21206
|
+
`\`wayai unbind\` does not take ${JSON.stringify(addFlag)}.`,
|
|
21207
|
+
" wayai unbind <selector> # remove one entry from the worktree scope",
|
|
21208
|
+
" wayai unbind # clear the whole scope (both hubs and bases)",
|
|
21209
|
+
" wayai use --add <selector> # WIDEN the scope instead (the opposite change)"
|
|
21210
|
+
].join("\n")
|
|
21211
|
+
);
|
|
21212
|
+
}
|
|
21213
|
+
const selector = resolveScopeSelector("unbind", args2);
|
|
21214
|
+
if (!selector) {
|
|
21215
|
+
if (args2.length > 0) {
|
|
21216
|
+
throw expected(
|
|
21217
|
+
[
|
|
21218
|
+
`\`wayai unbind ${args2.join(" ")}\` does not name anything to remove.`,
|
|
21219
|
+
"",
|
|
21220
|
+
"Refusing rather than clearing the whole scope \u2014 that is what a BARE",
|
|
21221
|
+
"`wayai unbind` does, and it is not what this invocation asked for.",
|
|
21222
|
+
" wayai unbind <selector> # remove one entry",
|
|
21223
|
+
" wayai unbind # clear the whole scope (both hubs and bases)"
|
|
21224
|
+
].join("\n")
|
|
21225
|
+
);
|
|
21226
|
+
}
|
|
21227
|
+
const described = describeScope(readScope());
|
|
21228
|
+
clearScope();
|
|
21229
|
+
console.log(
|
|
21230
|
+
described ? `Worktree scope cleared (was ${described}).` : "No worktree scope to clear."
|
|
21231
|
+
);
|
|
21061
21232
|
return;
|
|
21062
21233
|
}
|
|
21063
|
-
|
|
21064
|
-
|
|
21234
|
+
const scope = readScope();
|
|
21235
|
+
const literal = AXIS_ORDER.filter((axis2) => scope[axis2].includes(selector.target));
|
|
21236
|
+
const literalAxis = literal.includes(selector.axis) ? selector.axis : literal.length === 1 ? literal[0] : null;
|
|
21237
|
+
if (literalAxis) {
|
|
21238
|
+
announce(literalAxis, selector.target, removeFromScope(literalAxis, selector.target) ?? []);
|
|
21239
|
+
return;
|
|
21240
|
+
}
|
|
21241
|
+
const { axis, id } = resolveScopeTarget(selector);
|
|
21242
|
+
const remaining = removeFromScope(axis, id);
|
|
21243
|
+
if (!remaining) {
|
|
21244
|
+
const described = describeScope(scope);
|
|
21245
|
+
throw expected(
|
|
21246
|
+
[
|
|
21247
|
+
`${axisNoun(axis)} ${id} is not in this worktree's scope.`,
|
|
21248
|
+
described ? `This worktree is scoped to ${described}.` : "This worktree has no scope."
|
|
21249
|
+
].join("\n")
|
|
21250
|
+
);
|
|
21251
|
+
}
|
|
21252
|
+
announce(axis, id, remaining);
|
|
21253
|
+
}
|
|
21254
|
+
function announce(axis, id, remaining) {
|
|
21255
|
+
const noun = axisNoun(axis);
|
|
21256
|
+
console.log(
|
|
21257
|
+
remaining.length > 0 ? `Removed ${noun} ${id} from the worktree scope (${axis}: ${remaining.join(", ")}).` : `Removed ${noun} ${id} \u2014 this worktree is no longer scoped to any ${noun}.`
|
|
21258
|
+
);
|
|
21065
21259
|
}
|
|
21066
21260
|
var init_unbind = __esm({
|
|
21067
21261
|
"src/commands/unbind.ts"() {
|
|
21068
21262
|
"use strict";
|
|
21069
|
-
|
|
21263
|
+
init_expected();
|
|
21264
|
+
init_scope_selector();
|
|
21265
|
+
init_worktree_scope();
|
|
21070
21266
|
}
|
|
21071
21267
|
});
|
|
21072
21268
|
|
|
@@ -23010,7 +23206,7 @@ __export(eval_capture_exports, {
|
|
|
23010
23206
|
});
|
|
23011
23207
|
import * as fs24 from "fs";
|
|
23012
23208
|
import * as path31 from "path";
|
|
23013
|
-
import * as
|
|
23209
|
+
import * as yaml12 from "js-yaml";
|
|
23014
23210
|
function isValidSetName(name) {
|
|
23015
23211
|
if (name.length === 0 || name === "." || name === "..") return false;
|
|
23016
23212
|
if (name.startsWith(".")) return false;
|
|
@@ -23116,7 +23312,7 @@ async function evalCaptureCommand(args2) {
|
|
|
23116
23312
|
};
|
|
23117
23313
|
const yamlObj = buildEvalYamlObject(evalEntry, slug);
|
|
23118
23314
|
fs24.mkdirSync(targetDir, { recursive: true });
|
|
23119
|
-
fs24.writeFileSync(targetPath,
|
|
23315
|
+
fs24.writeFileSync(targetPath, yaml12.dump(yamlObj, YAML_DUMP_OPTIONS), "utf-8");
|
|
23120
23316
|
const relPath = path31.relative(process.cwd(), targetPath);
|
|
23121
23317
|
console.log(`
|
|
23122
23318
|
Wrote ${relPath}`);
|
|
@@ -24489,7 +24685,7 @@ var init_set_connection_credential = __esm({
|
|
|
24489
24685
|
// src/lib/org-workspace.ts
|
|
24490
24686
|
import * as fs25 from "fs";
|
|
24491
24687
|
import * as path32 from "path";
|
|
24492
|
-
import * as
|
|
24688
|
+
import * as yaml13 from "js-yaml";
|
|
24493
24689
|
function getOrgDir(gitRoot) {
|
|
24494
24690
|
return resolveLayout(gitRoot).orgDir;
|
|
24495
24691
|
}
|
|
@@ -24500,7 +24696,7 @@ function parseOrgResources(orgDir) {
|
|
|
24500
24696
|
const manifestPath = path32.join(orgDir, ORG_MANIFEST_NAME);
|
|
24501
24697
|
let manifest = {};
|
|
24502
24698
|
if (fs25.existsSync(manifestPath)) {
|
|
24503
|
-
manifest =
|
|
24699
|
+
manifest = yaml13.load(fs25.readFileSync(manifestPath, "utf-8")) ?? {};
|
|
24504
24700
|
}
|
|
24505
24701
|
const rawResources = Array.isArray(manifest.resources) ? manifest.resources : [];
|
|
24506
24702
|
const resourcesDir = path32.join(orgDir, "resources");
|
|
@@ -24533,7 +24729,7 @@ function writeOrgResources(orgDir, payload) {
|
|
|
24533
24729
|
});
|
|
24534
24730
|
fs25.writeFileSync(
|
|
24535
24731
|
path32.join(orgDir, ORG_MANIFEST_NAME),
|
|
24536
|
-
|
|
24732
|
+
yaml13.dump({ version: 1, resources: manifestResources }, YAML_DUMP_OPTIONS),
|
|
24537
24733
|
"utf-8"
|
|
24538
24734
|
);
|
|
24539
24735
|
const resourcesDir = path32.join(orgDir, "resources");
|
|
@@ -25355,7 +25551,7 @@ async function runSkillInstall(positional) {
|
|
|
25355
25551
|
console.log("Reload your agent (e.g. restart Claude Code) to pick up the skill.");
|
|
25356
25552
|
}
|
|
25357
25553
|
async function runSandboxExec(positional, flagArgs) {
|
|
25358
|
-
const
|
|
25554
|
+
const USAGE2 = 'wayai admin sandbox exec [--cmd "<command>" | <command>] --hub <hub_id> --connection <connection_id> [--egress open|allowlist|isolated] [--allow <host> ...] [--timeout <ms>] [--json]';
|
|
25359
25555
|
let hubId;
|
|
25360
25556
|
let connectionId;
|
|
25361
25557
|
let egress;
|
|
@@ -25409,7 +25605,7 @@ async function runSandboxExec(positional, flagArgs) {
|
|
|
25409
25605
|
const positionalCmd = positional[0];
|
|
25410
25606
|
if (positional.length > 1) {
|
|
25411
25607
|
console.error("Provide the command as a single quoted argument (or use --cmd).");
|
|
25412
|
-
console.error(
|
|
25608
|
+
console.error(USAGE2);
|
|
25413
25609
|
process.exit(1);
|
|
25414
25610
|
}
|
|
25415
25611
|
if (positionalCmd && cmdFlag) {
|
|
@@ -25418,7 +25614,7 @@ async function runSandboxExec(positional, flagArgs) {
|
|
|
25418
25614
|
}
|
|
25419
25615
|
const cmd = cmdFlag ?? positionalCmd;
|
|
25420
25616
|
if (!cmd || !hubId || !connectionId) {
|
|
25421
|
-
console.error(
|
|
25617
|
+
console.error(USAGE2);
|
|
25422
25618
|
process.exit(1);
|
|
25423
25619
|
}
|
|
25424
25620
|
const body = {
|
|
@@ -25515,8 +25711,8 @@ function parseScopedTargetFlags(flagArgs, usage3, opts = {}) {
|
|
|
25515
25711
|
return { body: { scope: "hub", hub_id: hubId, dry_run: dryRun }, targetLabel: `hub ${hubId}`, dryRun, yes, jsonOutput };
|
|
25516
25712
|
}
|
|
25517
25713
|
async function runRepairTeamOrphans(flagArgs) {
|
|
25518
|
-
const
|
|
25519
|
-
const { body, targetLabel, dryRun, yes, jsonOutput } = parseScopedTargetFlags(flagArgs,
|
|
25714
|
+
const USAGE2 = "wayai admin hubs repair-team-orphans --all | --org <org_id> | --hub <hub_id> [--dry-run] [--yes] [--json]";
|
|
25715
|
+
const { body, targetLabel, dryRun, yes, jsonOutput } = parseScopedTargetFlags(flagArgs, USAGE2);
|
|
25520
25716
|
if (!dryRun && !yes && !jsonOutput) {
|
|
25521
25717
|
console.log(`About to PURGE dangling team references in: ${targetLabel}.`);
|
|
25522
25718
|
console.log("Memberships pointing at a deleted team are removed (HubDO + UserDO mirror); conversations pinned to one are unassigned.");
|
|
@@ -25562,8 +25758,8 @@ async function runRepairTeamOrphans(flagArgs) {
|
|
|
25562
25758
|
}
|
|
25563
25759
|
}
|
|
25564
25760
|
async function runRepairLegacyOrgGrants(flagArgs) {
|
|
25565
|
-
const
|
|
25566
|
-
const scoped = parseScopedTargetFlags(flagArgs,
|
|
25761
|
+
const USAGE2 = "wayai admin orgs repair-legacy-grants --all | --org <org_id> [--dry-run] [--yes] [--json]";
|
|
25762
|
+
const scoped = parseScopedTargetFlags(flagArgs, USAGE2, {
|
|
25567
25763
|
scopes: ["all", "org"],
|
|
25568
25764
|
allLabel: "ALL organizations (platform-wide)"
|
|
25569
25765
|
});
|
|
@@ -25615,8 +25811,8 @@ async function runRepairLegacyOrgGrants(flagArgs) {
|
|
|
25615
25811
|
}
|
|
25616
25812
|
}
|
|
25617
25813
|
async function runHarnessMassDestroy(flagArgs) {
|
|
25618
|
-
const
|
|
25619
|
-
const { body, targetLabel, dryRun, yes, jsonOutput } = parseScopedTargetFlags(flagArgs,
|
|
25814
|
+
const USAGE2 = "wayai admin harness mass-destroy --all | --org <org_id> | --hub <hub_id> [--dry-run] [--yes] [--json]";
|
|
25815
|
+
const { body, targetLabel, dryRun, yes, jsonOutput } = parseScopedTargetFlags(flagArgs, USAGE2);
|
|
25620
25816
|
if (!dryRun && !yes && !jsonOutput) {
|
|
25621
25817
|
console.log(`About to REAP every live harness sandbox / token / slot in: ${targetLabel}.`);
|
|
25622
25818
|
console.log("This destroys running sandboxes and revokes their tokens. Run with --dry-run first to see the blast radius.");
|
|
@@ -25670,8 +25866,8 @@ function rejectHarnessFlags(flagArgs, usage3) {
|
|
|
25670
25866
|
process.exit(1);
|
|
25671
25867
|
}
|
|
25672
25868
|
async function runHarnessToggle(enable, flagArgs) {
|
|
25673
|
-
const
|
|
25674
|
-
rejectHarnessFlags(flagArgs,
|
|
25869
|
+
const USAGE2 = "wayai admin harness enable|disable";
|
|
25870
|
+
rejectHarnessFlags(flagArgs, USAGE2);
|
|
25675
25871
|
const { config, accessToken } = await requireAuth();
|
|
25676
25872
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
25677
25873
|
let value;
|
|
@@ -25692,8 +25888,8 @@ async function runHarnessToggle(enable, flagArgs) {
|
|
|
25692
25888
|
}
|
|
25693
25889
|
}
|
|
25694
25890
|
async function runHarnessStatus(flagArgs) {
|
|
25695
|
-
const
|
|
25696
|
-
rejectHarnessFlags(flagArgs,
|
|
25891
|
+
const USAGE2 = "wayai admin harness status";
|
|
25892
|
+
rejectHarnessFlags(flagArgs, USAGE2);
|
|
25697
25893
|
const { config, accessToken } = await requireAuth();
|
|
25698
25894
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
25699
25895
|
let value = 0;
|
|
@@ -27932,16 +28128,16 @@ MCP URL: ${toolsetMcpUrl(slug)}`);
|
|
|
27932
28128
|
).option("--force", "Revoke even if the token appears to be in live use").action(async function(tokenId, opts) {
|
|
27933
28129
|
const client = await createDataClient();
|
|
27934
28130
|
const id = pathSegment(tokenId, "token id");
|
|
27935
|
-
const
|
|
28131
|
+
const path35 = (force) => `/v1/tokens/${id}${force ? "?force=true" : ""}`;
|
|
27936
28132
|
const format = outputFormat(this);
|
|
27937
28133
|
const revoked = (forced) => printOutput({ token_id: tokenId, revoked: true, forced }, format);
|
|
27938
28134
|
if (opts.force) {
|
|
27939
|
-
await client.request("DELETE",
|
|
28135
|
+
await client.request("DELETE", path35(true));
|
|
27940
28136
|
revoked(true);
|
|
27941
28137
|
return;
|
|
27942
28138
|
}
|
|
27943
28139
|
try {
|
|
27944
|
-
await client.request("DELETE",
|
|
28140
|
+
await client.request("DELETE", path35(false));
|
|
27945
28141
|
revoked(false);
|
|
27946
28142
|
} catch (err) {
|
|
27947
28143
|
if (!(err instanceof ApiError) || err.status !== 409 || dataErrorDetails(err)?.requires_force !== true) {
|
|
@@ -27956,7 +28152,7 @@ MCP URL: ${toolsetMcpUrl(slug)}`);
|
|
|
27956
28152
|
console.error("Aborted.");
|
|
27957
28153
|
return process.exit(1);
|
|
27958
28154
|
}
|
|
27959
|
-
await client.request("DELETE",
|
|
28155
|
+
await client.request("DELETE", path35(true));
|
|
27960
28156
|
revoked(true);
|
|
27961
28157
|
}
|
|
27962
28158
|
});
|
|
@@ -28104,10 +28300,9 @@ var init_base_tags = __esm({
|
|
|
28104
28300
|
|
|
28105
28301
|
// src/data/commands/bases.ts
|
|
28106
28302
|
import { Command as Command10 } from "commander";
|
|
28107
|
-
|
|
28108
|
-
|
|
28109
|
-
|
|
28110
|
-
return `${path36}${path36.includes("?") ? "&" : "?"}cursor=${encodeURIComponent(cursor)}`;
|
|
28303
|
+
function pageOf(path35, cursor) {
|
|
28304
|
+
if (!cursor) return path35;
|
|
28305
|
+
return `${path35}${path35.includes("?") ? "&" : "?"}cursor=${encodeURIComponent(cursor)}`;
|
|
28111
28306
|
}
|
|
28112
28307
|
function parseEnum(flag, value, allowed) {
|
|
28113
28308
|
if (value === void 0) return void 0;
|
|
@@ -28141,12 +28336,13 @@ function buildBasesCommand() {
|
|
|
28141
28336
|
"production",
|
|
28142
28337
|
"preview"
|
|
28143
28338
|
]);
|
|
28339
|
+
const target = basePathSegment(id);
|
|
28144
28340
|
const client = await createDataClient();
|
|
28145
28341
|
const body = { name: opts.name, description: opts.description };
|
|
28146
28342
|
if (environment) body.environment = environment;
|
|
28147
28343
|
if (opts.tags) body.tags = await resolveBaseTags(opts.tags, client);
|
|
28148
28344
|
if (opts.timezone) body.settings = { timezone: opts.timezone };
|
|
28149
|
-
printOutput(await client.request("PUT", `/v1/bases/${
|
|
28345
|
+
printOutput(await client.request("PUT", `/v1/bases/${target}`, body), outputFormat(this));
|
|
28150
28346
|
});
|
|
28151
28347
|
bases.command("update <id>").description(
|
|
28152
28348
|
"Update a base's mutable config (display name, description, tags, default timezone/settings). The id/slug is immutable."
|
|
@@ -28169,6 +28365,7 @@ function buildBasesCommand() {
|
|
|
28169
28365
|
"Nothing to update. Provide at least one of --name, --description, --tags, --timezone, --settings, --integrations."
|
|
28170
28366
|
);
|
|
28171
28367
|
}
|
|
28368
|
+
const target = basePathSegment(id);
|
|
28172
28369
|
const client = await createDataClient();
|
|
28173
28370
|
const body = {};
|
|
28174
28371
|
if (opts.name !== void 0) body.name = opts.name;
|
|
@@ -28189,20 +28386,21 @@ function buildBasesCommand() {
|
|
|
28189
28386
|
}
|
|
28190
28387
|
settings = parsed;
|
|
28191
28388
|
} else {
|
|
28192
|
-
const existing = await client.request("GET", `/v1/bases/${
|
|
28389
|
+
const existing = await client.request("GET", `/v1/bases/${target}`);
|
|
28193
28390
|
settings = { ...existing?.settings ?? {} };
|
|
28194
28391
|
}
|
|
28195
28392
|
if (opts.timezone !== void 0) settings.timezone = opts.timezone;
|
|
28196
28393
|
body.settings = settings;
|
|
28197
28394
|
}
|
|
28198
|
-
printOutput(await client.request("PUT", `/v1/bases/${
|
|
28395
|
+
printOutput(await client.request("PUT", `/v1/bases/${target}`, body), outputFormat(this));
|
|
28199
28396
|
});
|
|
28200
28397
|
bases.command("rename <id>").description(
|
|
28201
28398
|
"Rename a base's display name (the id/slug is immutable \u2014 it scopes token grants, MCP endpoints, and references)"
|
|
28202
28399
|
).requiredOption("--name <name>", "New display name").action(async function(id, opts) {
|
|
28400
|
+
const target = basePathSegment(id);
|
|
28203
28401
|
const client = await createDataClient();
|
|
28204
28402
|
printOutput(
|
|
28205
|
-
await client.request("PUT", `/v1/bases/${
|
|
28403
|
+
await client.request("PUT", `/v1/bases/${target}`, { name: opts.name }),
|
|
28206
28404
|
outputFormat(this)
|
|
28207
28405
|
);
|
|
28208
28406
|
});
|
|
@@ -28210,10 +28408,11 @@ function buildBasesCommand() {
|
|
|
28210
28408
|
"--tags <tags>",
|
|
28211
28409
|
"Comma-separated organization tag names (e.g. clinica-medica,billing). An empty value clears them"
|
|
28212
28410
|
).action(async function(id, opts) {
|
|
28411
|
+
const target = basePathSegment(id);
|
|
28213
28412
|
const client = await createDataClient();
|
|
28214
28413
|
const tags = await resolveBaseTags(opts.tags, client);
|
|
28215
28414
|
printOutput(
|
|
28216
|
-
await client.request("PUT", `/v1/bases/${
|
|
28415
|
+
await client.request("PUT", `/v1/bases/${target}`, { tags }),
|
|
28217
28416
|
outputFormat(this)
|
|
28218
28417
|
);
|
|
28219
28418
|
});
|
|
@@ -28244,6 +28443,11 @@ function buildBasesCommand() {
|
|
|
28244
28443
|
const integrations = parseEnum("--integrations", opts.integrations, ["enabled", "disabled"]);
|
|
28245
28444
|
const client = await createDataClient();
|
|
28246
28445
|
printOutput(
|
|
28446
|
+
// `pathSegment`, not `basePathSegment`: the id at fault here is the
|
|
28447
|
+
// ORIGIN's, which is immutable and not the caller's to re-spell. The API's
|
|
28448
|
+
// `assertDerivablePreviewId` answers that case with the remedy instead of
|
|
28449
|
+
// the charset, and refusing locally would replace it with a rule the
|
|
28450
|
+
// caller cannot act on.
|
|
28247
28451
|
await client.request("POST", `/v1/${pathSegment(originId, "origin base id")}/preview`, {
|
|
28248
28452
|
name: opts.name,
|
|
28249
28453
|
description: opts.description,
|
|
@@ -28255,9 +28459,9 @@ function buildBasesCommand() {
|
|
|
28255
28459
|
});
|
|
28256
28460
|
bases.command("list-previews <origin-id>").description("List preview bases cloned from a base (production or preview)").action(async function(originId) {
|
|
28257
28461
|
const client = await createDataClient();
|
|
28258
|
-
const
|
|
28462
|
+
const path35 = `/v1/${pathSegment(originId, "origin base id")}/previews`;
|
|
28259
28463
|
printOutput(
|
|
28260
|
-
await client.collectPages((cursor) => pageOf(
|
|
28464
|
+
await client.collectPages((cursor) => pageOf(path35, cursor)),
|
|
28261
28465
|
outputFormat(this)
|
|
28262
28466
|
);
|
|
28263
28467
|
});
|
|
@@ -28304,45 +28508,52 @@ function buildBasesCommand() {
|
|
|
28304
28508
|
});
|
|
28305
28509
|
bases.command("promotions <production-id>").description("List promotion history for a production base").action(async function(productionId) {
|
|
28306
28510
|
const client = await createDataClient();
|
|
28307
|
-
const
|
|
28511
|
+
const path35 = `/v1/${pathSegment(productionId, "production base id")}/promotions`;
|
|
28308
28512
|
printOutput(
|
|
28309
|
-
await client.collectPages((cursor) => pageOf(
|
|
28513
|
+
await client.collectPages((cursor) => pageOf(path35, cursor)),
|
|
28310
28514
|
outputFormat(this)
|
|
28311
28515
|
);
|
|
28312
28516
|
});
|
|
28313
28517
|
bases.command("use <base>").description(
|
|
28314
|
-
"
|
|
28518
|
+
"Deprecated alias of `wayai use bases/<id>` \u2014 scope this worktree to a base"
|
|
28315
28519
|
).action(async function(selector) {
|
|
28316
|
-
const baseId =
|
|
28317
|
-
const previous =
|
|
28318
|
-
|
|
28520
|
+
const baseId = resolveBaseSelectorToId(findGitRoot(), selector);
|
|
28521
|
+
const previous = readScope().bases;
|
|
28522
|
+
const changed = previous.length !== 1 || previous[0] !== baseId;
|
|
28523
|
+
if (changed) {
|
|
28319
28524
|
try {
|
|
28320
|
-
|
|
28525
|
+
setScopeAxis("bases", [baseId]);
|
|
28321
28526
|
} catch (err) {
|
|
28322
28527
|
throw expected(err instanceof Error ? err.message : String(err));
|
|
28323
28528
|
}
|
|
28324
28529
|
}
|
|
28325
28530
|
if (outputFormat(this) === "json") {
|
|
28326
|
-
printOutput(
|
|
28531
|
+
printOutput(
|
|
28532
|
+
{ base_id: baseId, previous_base_id: previous[0] ?? null, changed },
|
|
28533
|
+
"json"
|
|
28534
|
+
);
|
|
28327
28535
|
return;
|
|
28328
28536
|
}
|
|
28329
|
-
if (
|
|
28537
|
+
if (!changed) {
|
|
28330
28538
|
console.log(`Worktree already bound to base ${baseId}.`);
|
|
28331
28539
|
} else {
|
|
28332
28540
|
console.log(
|
|
28333
|
-
previous ? `Worktree rebound: ${previous} -> ${baseId}.` : `Worktree bound to base ${baseId}.`
|
|
28541
|
+
previous.length > 0 ? `Worktree rebound: ${previous.join(", ")} -> ${baseId}.` : `Worktree bound to base ${baseId}.`
|
|
28334
28542
|
);
|
|
28335
28543
|
}
|
|
28336
28544
|
});
|
|
28337
|
-
bases.command("unbind").description("
|
|
28338
|
-
const previous =
|
|
28339
|
-
if (previous)
|
|
28545
|
+
bases.command("unbind").description("Deprecated alias of `wayai unbind bases/<id>` \u2014 clear the base scope").action(async function() {
|
|
28546
|
+
const previous = readScope().bases;
|
|
28547
|
+
if (previous.length > 0) setScopeAxis("bases", []);
|
|
28340
28548
|
if (outputFormat(this) === "json") {
|
|
28341
|
-
printOutput(
|
|
28549
|
+
printOutput(
|
|
28550
|
+
{ previous_base_id: previous[0] ?? null, cleared: previous.length > 0 },
|
|
28551
|
+
"json"
|
|
28552
|
+
);
|
|
28342
28553
|
return;
|
|
28343
28554
|
}
|
|
28344
28555
|
console.log(
|
|
28345
|
-
previous ? `Worktree unbound from base (was: ${previous}).` : "No base binding to clear."
|
|
28556
|
+
previous.length > 0 ? `Worktree unbound from base (was: ${previous.join(", ")}).` : "No base binding to clear."
|
|
28346
28557
|
);
|
|
28347
28558
|
});
|
|
28348
28559
|
bases.addCommand(buildBasesTokensCommand());
|
|
@@ -28354,13 +28565,6 @@ function buildBasesCommand() {
|
|
|
28354
28565
|
bases.addCommand(buildBasesReportCommand());
|
|
28355
28566
|
return bases;
|
|
28356
28567
|
}
|
|
28357
|
-
function resolveSelectorToBaseId(selector) {
|
|
28358
|
-
const gitRoot = findGitRoot();
|
|
28359
|
-
if (!gitRoot || selector.includes("/") || selector.includes(path35.sep)) return selector;
|
|
28360
|
-
if (!isValidBaseId(selector)) return selector;
|
|
28361
|
-
const id = readBaseMeta(path35.join(resolveBasesDir(gitRoot), selector))?.base_id;
|
|
28362
|
-
return typeof id === "string" && isValidBaseId(id) ? id : selector;
|
|
28363
|
-
}
|
|
28364
28568
|
var init_bases = __esm({
|
|
28365
28569
|
"src/data/commands/bases.ts"() {
|
|
28366
28570
|
"use strict";
|
|
@@ -28378,10 +28582,8 @@ var init_bases = __esm({
|
|
|
28378
28582
|
init_utils();
|
|
28379
28583
|
init_terminal_output();
|
|
28380
28584
|
init_workspace();
|
|
28381
|
-
init_layout();
|
|
28382
28585
|
init_base_workspace();
|
|
28383
|
-
|
|
28384
|
-
init_base_id();
|
|
28586
|
+
init_worktree_scope();
|
|
28385
28587
|
init_expected();
|
|
28386
28588
|
}
|
|
28387
28589
|
});
|
|
@@ -28855,8 +29057,8 @@ function buildRecordsCommand() {
|
|
|
28855
29057
|
const body = { data: parseData(opts.data) };
|
|
28856
29058
|
if (opts.externalId) body.external_id = opts.externalId;
|
|
28857
29059
|
if (opts.externalSource) body.external_source = opts.externalSource;
|
|
28858
|
-
const
|
|
28859
|
-
printOutput(await client.request("PUT",
|
|
29060
|
+
const path35 = opts.id ? `/v1/${base}/records/${pathSegment(recordType2, "record_type")}/${pathSegment(opts.id, "--id")}` : `/v1/${base}/records/${pathSegment(recordType2, "record_type")}`;
|
|
29061
|
+
printOutput(await client.request("PUT", path35, body), outputFormat(this));
|
|
28860
29062
|
});
|
|
28861
29063
|
records.command("query <record_type>").description("List/search records: exact filters + fuzzy `search`, sorting, pagination").option(
|
|
28862
29064
|
"--external-source <source>",
|
|
@@ -28891,9 +29093,9 @@ function buildRecordsCommand() {
|
|
|
28891
29093
|
).action(async function(recordType2, id, opts) {
|
|
28892
29094
|
const base = pathSegment(requireBase(this), "--base");
|
|
28893
29095
|
const client = await createDataClient();
|
|
28894
|
-
let
|
|
28895
|
-
if (opts.externalSource)
|
|
28896
|
-
printOutput(await client.request("GET",
|
|
29096
|
+
let path35 = `/v1/${base}/records/${pathSegment(recordType2, "record_type")}/${recordKey(id, opts.externalSource)}`;
|
|
29097
|
+
if (opts.externalSource) path35 += `?external_source=${encodeURIComponent(opts.externalSource)}`;
|
|
29098
|
+
printOutput(await client.request("GET", path35), outputFormat(this));
|
|
28897
29099
|
});
|
|
28898
29100
|
records.command("delete <record_type> <id>").description(
|
|
28899
29101
|
"Delete a record by internal ID, or by external_id (pass --external-source to scope it)"
|
|
@@ -28907,11 +29109,11 @@ function buildRecordsCommand() {
|
|
|
28907
29109
|
}
|
|
28908
29110
|
const base = pathSegment(requireBase(this), "--base");
|
|
28909
29111
|
const client = await createDataClient();
|
|
28910
|
-
let
|
|
29112
|
+
let path35 = `/v1/${base}/records/${pathSegment(recordType2, "record_type")}/${recordKey(id, opts.externalSource)}`;
|
|
28911
29113
|
if (opts.externalSource) {
|
|
28912
|
-
|
|
29114
|
+
path35 += `?external_source=${encodeURIComponent(opts.externalSource)}&external_id=${encodeURIComponent(id)}`;
|
|
28913
29115
|
}
|
|
28914
|
-
await client.request("DELETE",
|
|
29116
|
+
await client.request("DELETE", path35);
|
|
28915
29117
|
console.log("Deleted");
|
|
28916
29118
|
});
|
|
28917
29119
|
records.command("history <id>").description(
|
|
@@ -29076,8 +29278,8 @@ function buildRelationshipsCommand() {
|
|
|
29076
29278
|
if (opts.data) body.data = parseData(opts.data);
|
|
29077
29279
|
const base = pathSegment(requireBase(this), "--base");
|
|
29078
29280
|
const client = await createDataClient();
|
|
29079
|
-
const
|
|
29080
|
-
printOutput(await client.request("PUT",
|
|
29281
|
+
const path35 = opts.id ? `/v1/${base}/relationships/${pathSegment(opts.id, "--id")}` : `/v1/${base}/relationships`;
|
|
29282
|
+
printOutput(await client.request("PUT", path35, body), outputFormat(this));
|
|
29081
29283
|
});
|
|
29082
29284
|
relationships.command("get <id>").description(
|
|
29083
29285
|
"Get a relationship by ID (or by its external key: pass the external_id with --rel-type)"
|
|
@@ -29310,8 +29512,8 @@ function buildToolsetsCommand() {
|
|
|
29310
29512
|
toolsets.command("get <slug>").description("Get a toolset").option("--resolved", "Include resolved record_type schemas").action(async function(slug, opts) {
|
|
29311
29513
|
const base = pathSegment(requireBase(this), "--base");
|
|
29312
29514
|
const client = await createDataClient();
|
|
29313
|
-
const
|
|
29314
|
-
printOutput(await client.request("GET",
|
|
29515
|
+
const path35 = opts.resolved ? `/v1/${base}/toolsets/${pathSegment(slug, "toolset slug")}/resolved` : `/v1/${base}/toolsets/${pathSegment(slug, "toolset slug")}`;
|
|
29516
|
+
printOutput(await client.request("GET", path35), outputFormat(this));
|
|
29315
29517
|
});
|
|
29316
29518
|
toolsets.command("list").description("List all toolsets").action(async function() {
|
|
29317
29519
|
const base = pathSegment(requireBase(this), "--base");
|
|
@@ -29546,7 +29748,7 @@ init_utils();
|
|
|
29546
29748
|
init_registry();
|
|
29547
29749
|
import { readFileSync as readFileSync26 } from "fs";
|
|
29548
29750
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
29549
|
-
import { dirname as dirname12, join as
|
|
29751
|
+
import { dirname as dirname12, join as join33 } from "path";
|
|
29550
29752
|
|
|
29551
29753
|
// src/lib/version-refresh.ts
|
|
29552
29754
|
init_version_cache();
|
|
@@ -29702,7 +29904,7 @@ Run \`wayai admin skill install\` to update.`);
|
|
|
29702
29904
|
|
|
29703
29905
|
// src/index.ts
|
|
29704
29906
|
var __dirname = dirname12(fileURLToPath3(import.meta.url));
|
|
29705
|
-
var pkg = JSON.parse(readFileSync26(
|
|
29907
|
+
var pkg = JSON.parse(readFileSync26(join33(__dirname, "..", "package.json"), "utf-8"));
|
|
29706
29908
|
var [, , command, ...args] = process.argv;
|
|
29707
29909
|
var isBackgroundRefresh = command === REFRESH_COMMAND;
|
|
29708
29910
|
if (!isBackgroundRefresh) initSentry(command, pkg.version);
|
|
@@ -29951,9 +30153,9 @@ Commands:
|
|
|
29951
30153
|
sync Alias of \`publish\` (not to be confused with sync-skills / sync-mcp)
|
|
29952
30154
|
org create Create a new organization (you become its owner)
|
|
29953
30155
|
org <pull|push|diff> Sync org-scoped resources as code (wayai-ws/org/)
|
|
29954
|
-
use <
|
|
30156
|
+
use [--add] <sel> Scope this worktree to a hub or base (UUID, folder name, hubs/<n>, bases/<n>; --add widens)
|
|
29955
30157
|
migrate Move a legacy repo to the wayai-ws/{hubs,org} layout
|
|
29956
|
-
unbind
|
|
30158
|
+
unbind [<sel>] Drop one entry from the worktree scope, or clear the whole scope
|
|
29957
30159
|
send-message Send a test message to a hub (preview or production; -f <path> to attach a file)
|
|
29958
30160
|
conversations List or inspect conversations
|
|
29959
30161
|
alerts Show a hub's active connection/credential alerts (run this FIRST when a hub misbehaves)
|
|
@@ -29975,8 +30177,8 @@ Commands:
|
|
|
29975
30177
|
Data \u2014 one namespace per entity. Run \`wayai <namespace> --help\` for its tree.
|
|
29976
30178
|
${await dataHelpBlock()}
|
|
29977
30179
|
bases promote Promote a preview base to production (distinct from \`publish\`, which promotes a hub)
|
|
29978
|
-
bases use <base>
|
|
29979
|
-
bases unbind
|
|
30180
|
+
bases use <base> Deprecated alias of \`wayai use bases/<id>\`
|
|
30181
|
+
bases unbind Deprecated alias of \`wayai unbind bases/<id>\` (clears the base axis)
|
|
29980
30182
|
|
|
29981
30183
|
Flags:
|
|
29982
30184
|
--yes, -y Skip confirmation prompts (useful for CI and scripting)
|
|
@@ -30028,12 +30230,15 @@ Org-scoped mode:
|
|
|
30028
30230
|
pull/push operate on the single hub in the workspace, or pass
|
|
30029
30231
|
\`--hub <uuid|name>\` to disambiguate when multiple hubs exist.
|
|
30030
30232
|
|
|
30031
|
-
Worktree
|
|
30032
|
-
Each git checkout (main or linked worktree)
|
|
30033
|
-
|
|
30034
|
-
|
|
30035
|
-
|
|
30036
|
-
|
|
30233
|
+
Worktree scope:
|
|
30234
|
+
Each git checkout (main or linked worktree) carries a scope: a set of hubs and
|
|
30235
|
+
a set of bases, at \`<git-dir>/wayai-scope\` \u2014 per-checkout, never tracked.
|
|
30236
|
+
push/pull/publish refuse to run against anything outside a non-empty set. Each
|
|
30237
|
+
axis is seeded by the first successful pull/push/create into a checkout that
|
|
30238
|
+
has none, and only widens on purpose: \`wayai use --add <sel>\` adds one,
|
|
30239
|
+
\`wayai use <sel>\` replaces that axis, \`wayai unbind <sel>\` drops one entry and
|
|
30240
|
+
bare \`wayai unbind\` clears everything. It is a routing tripwire, not a lock
|
|
30241
|
+
and not authorization.
|
|
30037
30242
|
|
|
30038
30243
|
Examples:
|
|
30039
30244
|
wayai login
|