@wayai/cli 0.3.52 → 0.3.54
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 +792 -97
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -133,11 +133,11 @@ function captureException2(error, context) {
|
|
|
133
133
|
Sentry.captureException(error);
|
|
134
134
|
});
|
|
135
135
|
}
|
|
136
|
-
function addApiBreadcrumb(method,
|
|
136
|
+
function addApiBreadcrumb(method, path22) {
|
|
137
137
|
if (!initialized) return;
|
|
138
138
|
Sentry.addBreadcrumb({
|
|
139
139
|
category: "http",
|
|
140
|
-
message: `${method} ${
|
|
140
|
+
message: `${method} ${path22}`,
|
|
141
141
|
level: "info"
|
|
142
142
|
});
|
|
143
143
|
}
|
|
@@ -189,13 +189,13 @@ var init_api_client = __esm({
|
|
|
189
189
|
init_sentry();
|
|
190
190
|
init_redact();
|
|
191
191
|
RETRYABLE_BACKOFF_MS = [500, 1e3, 2e3];
|
|
192
|
-
delay = (ms) => new Promise((
|
|
192
|
+
delay = (ms) => new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
193
193
|
ApiError = class extends Error {
|
|
194
194
|
status;
|
|
195
195
|
body;
|
|
196
|
-
constructor(method,
|
|
196
|
+
constructor(method, path22, status, body) {
|
|
197
197
|
const safeBody = redactSecrets(body);
|
|
198
|
-
super(`API request failed: ${method} ${
|
|
198
|
+
super(`API request failed: ${method} ${path22} (${status}): ${safeBody}`);
|
|
199
199
|
this.name = "ApiError";
|
|
200
200
|
this.status = status;
|
|
201
201
|
this.body = safeBody;
|
|
@@ -252,6 +252,21 @@ var init_api_client = __esm({
|
|
|
252
252
|
commit_sha: commitSha
|
|
253
253
|
});
|
|
254
254
|
}
|
|
255
|
+
// --- Templates gallery ---
|
|
256
|
+
// Consumer (any authed user): list the joint template set + pull the wayai slice.
|
|
257
|
+
async templateList() {
|
|
258
|
+
return this.request("GET", "/api/ci/templates");
|
|
259
|
+
}
|
|
260
|
+
async templatePull(slug) {
|
|
261
|
+
return this.request("GET", `/api/ci/templates/${encodeURIComponent(slug)}`);
|
|
262
|
+
}
|
|
263
|
+
// Author (platform-admin): push a template into the store / pull it for inspection.
|
|
264
|
+
async adminTemplatePush(body) {
|
|
265
|
+
return this.request("POST", "/api/admin/templates/push", body);
|
|
266
|
+
}
|
|
267
|
+
async adminTemplatePull(slug) {
|
|
268
|
+
return this.request("GET", `/api/admin/templates/${encodeURIComponent(slug)}`);
|
|
269
|
+
}
|
|
255
270
|
/**
|
|
256
271
|
* Re-discover an MCP connection's tool/resource catalog (refreshes stale
|
|
257
272
|
* input schemas that `push` leaves untouched). `connection` is the display
|
|
@@ -264,8 +279,8 @@ var init_api_client = __esm({
|
|
|
264
279
|
...organizationId && { organization_id: organizationId }
|
|
265
280
|
});
|
|
266
281
|
}
|
|
267
|
-
async lookup(
|
|
268
|
-
const params = new URLSearchParams({ path:
|
|
282
|
+
async lookup(path22, opts) {
|
|
283
|
+
const params = new URLSearchParams({ path: path22 });
|
|
269
284
|
if (opts?.organizationId) params.set("organization_id", opts.organizationId);
|
|
270
285
|
return this.request("GET", `/api/ci/lookup?${params.toString()}`);
|
|
271
286
|
}
|
|
@@ -615,9 +630,9 @@ var init_api_client = __esm({
|
|
|
615
630
|
`/api/admin/data-explorer/debug/observability/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}${qs}`
|
|
616
631
|
);
|
|
617
632
|
}
|
|
618
|
-
async request(method,
|
|
619
|
-
addApiBreadcrumb(method,
|
|
620
|
-
const url = `${this.apiUrl}${
|
|
633
|
+
async request(method, path22, body) {
|
|
634
|
+
addApiBreadcrumb(method, path22);
|
|
635
|
+
const url = `${this.apiUrl}${path22}`;
|
|
621
636
|
let refreshedOn401 = false;
|
|
622
637
|
for (let retry = 0; ; retry++) {
|
|
623
638
|
let response = await this.send(url, method, body);
|
|
@@ -641,7 +656,7 @@ var init_api_client = __esm({
|
|
|
641
656
|
await delay(RETRYABLE_BACKOFF_MS[retry]);
|
|
642
657
|
continue;
|
|
643
658
|
}
|
|
644
|
-
throw new ApiError(method,
|
|
659
|
+
throw new ApiError(method, path22, response.status, errorBody);
|
|
645
660
|
}
|
|
646
661
|
}
|
|
647
662
|
/** Issue a single authenticated request with the client's current token. */
|
|
@@ -1076,8 +1091,8 @@ var init_parseUtil = __esm({
|
|
|
1076
1091
|
init_errors();
|
|
1077
1092
|
init_en();
|
|
1078
1093
|
makeIssue = (params) => {
|
|
1079
|
-
const { data, path:
|
|
1080
|
-
const fullPath = [...
|
|
1094
|
+
const { data, path: path22, errorMaps, issueData } = params;
|
|
1095
|
+
const fullPath = [...path22, ...issueData.path || []];
|
|
1081
1096
|
const fullIssue = {
|
|
1082
1097
|
...issueData,
|
|
1083
1098
|
path: fullPath
|
|
@@ -1388,11 +1403,11 @@ var init_types = __esm({
|
|
|
1388
1403
|
init_parseUtil();
|
|
1389
1404
|
init_util();
|
|
1390
1405
|
ParseInputLazyPath = class {
|
|
1391
|
-
constructor(parent, value,
|
|
1406
|
+
constructor(parent, value, path22, key) {
|
|
1392
1407
|
this._cachedPath = [];
|
|
1393
1408
|
this.parent = parent;
|
|
1394
1409
|
this.data = value;
|
|
1395
|
-
this._path =
|
|
1410
|
+
this._path = path22;
|
|
1396
1411
|
this._key = key;
|
|
1397
1412
|
}
|
|
1398
1413
|
get path() {
|
|
@@ -4783,6 +4798,38 @@ function normalizeAuthType(raw) {
|
|
|
4783
4798
|
function visibleLength(s) {
|
|
4784
4799
|
return s.replace(INVISIBLE_NAME_CHARS, "").length;
|
|
4785
4800
|
}
|
|
4801
|
+
function validateLaneReferences(lanes, statuses) {
|
|
4802
|
+
const issues = [];
|
|
4803
|
+
if (!Array.isArray(statuses) || statuses.length === 0) return issues;
|
|
4804
|
+
const declared = new Set((Array.isArray(lanes) ? lanes : []).map((l) => l.slug).filter(Boolean));
|
|
4805
|
+
statuses.forEach((s, i) => {
|
|
4806
|
+
const lane = s.lane_slug;
|
|
4807
|
+
if (typeof lane !== "string" || lane.length === 0) return;
|
|
4808
|
+
const label = s.slug ? `"${s.slug}"` : `[${i}]`;
|
|
4809
|
+
if (s.isInitialStatus === true) {
|
|
4810
|
+
issues.push({
|
|
4811
|
+
path: [i, "lane_slug"],
|
|
4812
|
+
message: `kanban status ${label}: the initial status cannot belong to a lane (it is the shared entry point)`
|
|
4813
|
+
});
|
|
4814
|
+
return;
|
|
4815
|
+
}
|
|
4816
|
+
if (!declared.has(lane)) {
|
|
4817
|
+
issues.push({
|
|
4818
|
+
path: [i, "lane_slug"],
|
|
4819
|
+
message: `kanban status ${label}: lane_slug references unknown lane "${lane}"`
|
|
4820
|
+
});
|
|
4821
|
+
}
|
|
4822
|
+
});
|
|
4823
|
+
return issues;
|
|
4824
|
+
}
|
|
4825
|
+
function refineLaneReferences(val, ctx) {
|
|
4826
|
+
const lanes = val.lanes;
|
|
4827
|
+
const statuses = val.kanban_statuses;
|
|
4828
|
+
if (lanes == null || statuses == null) return;
|
|
4829
|
+
for (const issue of validateLaneReferences(lanes, statuses)) {
|
|
4830
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["kanban_statuses", ...issue.path], message: issue.message });
|
|
4831
|
+
}
|
|
4832
|
+
}
|
|
4786
4833
|
function containsKanbanPlaceholders(value) {
|
|
4787
4834
|
if (value == null) return false;
|
|
4788
4835
|
const serialized = typeof value === "string" ? value : JSON.stringify(value);
|
|
@@ -4814,12 +4861,12 @@ function typeMatches(typeField, allowed) {
|
|
|
4814
4861
|
if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
|
|
4815
4862
|
return false;
|
|
4816
4863
|
}
|
|
4817
|
-
function validateSchema(schema,
|
|
4864
|
+
function validateSchema(schema, path22, errors, opts = {}) {
|
|
4818
4865
|
if (typeof schema === "boolean") return;
|
|
4819
4866
|
const depth = opts.depth ?? 0;
|
|
4820
4867
|
if (depth > MAX_SCHEMA_DEPTH) {
|
|
4821
4868
|
errors.push({
|
|
4822
|
-
path:
|
|
4869
|
+
path: path22 || "<root>",
|
|
4823
4870
|
message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH} levels`,
|
|
4824
4871
|
suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
|
|
4825
4872
|
});
|
|
@@ -4827,7 +4874,7 @@ function validateSchema(schema, path19, errors, opts = {}) {
|
|
|
4827
4874
|
}
|
|
4828
4875
|
if (!isRecord(schema)) {
|
|
4829
4876
|
errors.push({
|
|
4830
|
-
path:
|
|
4877
|
+
path: path22,
|
|
4831
4878
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
4832
4879
|
});
|
|
4833
4880
|
return;
|
|
@@ -4835,14 +4882,14 @@ function validateSchema(schema, path19, errors, opts = {}) {
|
|
|
4835
4882
|
if (opts.isRoot) {
|
|
4836
4883
|
if ("type" in schema && schema.type !== "object") {
|
|
4837
4884
|
errors.push({
|
|
4838
|
-
path:
|
|
4885
|
+
path: path22 ? `${path22}.type` : "type",
|
|
4839
4886
|
message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
|
|
4840
4887
|
suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
|
|
4841
4888
|
});
|
|
4842
4889
|
}
|
|
4843
4890
|
} else if ("type" in schema && !typeMatches(schema.type, ALLOWED_TYPES)) {
|
|
4844
4891
|
errors.push({
|
|
4845
|
-
path: `${
|
|
4892
|
+
path: `${path22}.type`,
|
|
4846
4893
|
message: `type must be one of ${[...ALLOWED_TYPES].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
|
|
4847
4894
|
});
|
|
4848
4895
|
}
|
|
@@ -4851,25 +4898,25 @@ function validateSchema(schema, path19, errors, opts = {}) {
|
|
|
4851
4898
|
if (typeof e === "string") {
|
|
4852
4899
|
const isPlaceholder = PLACEHOLDER_TOKENS.includes(e);
|
|
4853
4900
|
errors.push({
|
|
4854
|
-
path: `${
|
|
4901
|
+
path: `${path22}.enum`,
|
|
4855
4902
|
message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
|
|
4856
4903
|
suggestion: isPlaceholder ? "Set `operation: 'update_kanban_status'` on the tool and ensure at least one hub.kanban_status has `allowsAgentUpdate: true` so the platform can render the placeholder into a valid array." : 'Wrap the value in an array: `enum: ["value"]`.'
|
|
4857
4904
|
});
|
|
4858
4905
|
} else if (!Array.isArray(e)) {
|
|
4859
4906
|
errors.push({
|
|
4860
|
-
path: `${
|
|
4907
|
+
path: `${path22}.enum`,
|
|
4861
4908
|
message: `enum must be a non-empty array of primitives, got ${typeof e}`
|
|
4862
4909
|
});
|
|
4863
4910
|
} else if (e.length === 0) {
|
|
4864
4911
|
errors.push({
|
|
4865
|
-
path: `${
|
|
4912
|
+
path: `${path22}.enum`,
|
|
4866
4913
|
message: "enum must not be empty"
|
|
4867
4914
|
});
|
|
4868
4915
|
} else {
|
|
4869
4916
|
for (let i = 0; i < e.length; i++) {
|
|
4870
4917
|
if (!isPrimitive(e[i])) {
|
|
4871
4918
|
errors.push({
|
|
4872
|
-
path: `${
|
|
4919
|
+
path: `${path22}.enum[${i}]`,
|
|
4873
4920
|
message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
|
|
4874
4921
|
});
|
|
4875
4922
|
}
|
|
@@ -4879,7 +4926,7 @@ function validateSchema(schema, path19, errors, opts = {}) {
|
|
|
4879
4926
|
for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
|
|
4880
4927
|
if (key in schema && typeof schema[key] === "boolean") {
|
|
4881
4928
|
errors.push({
|
|
4882
|
-
path: `${
|
|
4929
|
+
path: `${path22}.${key}`,
|
|
4883
4930
|
message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
|
|
4884
4931
|
suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
|
|
4885
4932
|
});
|
|
@@ -4888,45 +4935,45 @@ function validateSchema(schema, path19, errors, opts = {}) {
|
|
|
4888
4935
|
if ("properties" in schema) {
|
|
4889
4936
|
if (!isRecord(schema.properties)) {
|
|
4890
4937
|
errors.push({
|
|
4891
|
-
path: `${
|
|
4938
|
+
path: `${path22}.properties`,
|
|
4892
4939
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
4893
4940
|
});
|
|
4894
4941
|
} else {
|
|
4895
4942
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
4896
|
-
validateSchema(propSchema, `${
|
|
4943
|
+
validateSchema(propSchema, `${path22}.properties.${propName}`, errors, { depth: depth + 1 });
|
|
4897
4944
|
}
|
|
4898
4945
|
}
|
|
4899
4946
|
}
|
|
4900
4947
|
if (schemaTypeIncludes(schema, "array") && "items" in schema) {
|
|
4901
4948
|
if (Array.isArray(schema.items)) {
|
|
4902
|
-
schema.items.forEach((sub, i) => validateSchema(sub, `${
|
|
4949
|
+
schema.items.forEach((sub, i) => validateSchema(sub, `${path22}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
4903
4950
|
} else {
|
|
4904
|
-
validateSchema(schema.items, `${
|
|
4951
|
+
validateSchema(schema.items, `${path22}.items`, errors, { depth: depth + 1 });
|
|
4905
4952
|
}
|
|
4906
4953
|
}
|
|
4907
4954
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS) {
|
|
4908
4955
|
if (key in schema && isRecord(schema[key])) {
|
|
4909
|
-
validateSchema(schema[key], `${
|
|
4956
|
+
validateSchema(schema[key], `${path22}.${key}`, errors, { depth: depth + 1 });
|
|
4910
4957
|
}
|
|
4911
4958
|
}
|
|
4912
4959
|
for (const key of SUBSCHEMA_LIST_KEYWORDS) {
|
|
4913
4960
|
const list = schema[key];
|
|
4914
4961
|
if (Array.isArray(list)) {
|
|
4915
|
-
list.forEach((sub, i) => validateSchema(sub, `${
|
|
4962
|
+
list.forEach((sub, i) => validateSchema(sub, `${path22}.${key}[${i}]`, errors, { depth: depth + 1 }));
|
|
4916
4963
|
}
|
|
4917
4964
|
}
|
|
4918
4965
|
for (const key of SUBSCHEMA_MAP_KEYWORDS) {
|
|
4919
4966
|
const map = schema[key];
|
|
4920
4967
|
if (isRecord(map)) {
|
|
4921
4968
|
for (const [name, sub] of Object.entries(map)) {
|
|
4922
|
-
validateSchema(sub, `${
|
|
4969
|
+
validateSchema(sub, `${path22}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
4923
4970
|
}
|
|
4924
4971
|
}
|
|
4925
4972
|
}
|
|
4926
4973
|
const reportedPaths = new Set(errors.map((e) => e.path));
|
|
4927
4974
|
for (const [k, v] of Object.entries(schema)) {
|
|
4928
4975
|
if (typeof v !== "string") continue;
|
|
4929
|
-
const fieldPath = `${
|
|
4976
|
+
const fieldPath = `${path22}.${k}`;
|
|
4930
4977
|
if (reportedPaths.has(fieldPath)) continue;
|
|
4931
4978
|
for (const token of PLACEHOLDER_TOKENS) {
|
|
4932
4979
|
if (v === token) {
|
|
@@ -5059,6 +5106,37 @@ function refineHubAsCodeKanbanStatuses(config, ctx) {
|
|
|
5059
5106
|
}
|
|
5060
5107
|
}
|
|
5061
5108
|
}
|
|
5109
|
+
function refineHubAsCodeLanes(config, ctx) {
|
|
5110
|
+
const hub = config.hub;
|
|
5111
|
+
if (hub == null) return;
|
|
5112
|
+
if ("lanes" in hub && hub.lanes != null) {
|
|
5113
|
+
if (!Array.isArray(hub.lanes)) {
|
|
5114
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["hub", "lanes"], message: "lanes must be an array" });
|
|
5115
|
+
return;
|
|
5116
|
+
}
|
|
5117
|
+
const result = lanesArraySchema.safeParse(hub.lanes);
|
|
5118
|
+
if (!result.success) {
|
|
5119
|
+
for (const issue of result.error.issues) {
|
|
5120
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["hub", "lanes", ...issue.path], message: issue.message });
|
|
5121
|
+
}
|
|
5122
|
+
return;
|
|
5123
|
+
}
|
|
5124
|
+
}
|
|
5125
|
+
const statuses = hub.kanban_statuses;
|
|
5126
|
+
if (Array.isArray(statuses)) {
|
|
5127
|
+
for (const issue of validateLaneReferences(hub.lanes, statuses)) {
|
|
5128
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["hub", "kanban_statuses", ...issue.path], message: issue.message });
|
|
5129
|
+
}
|
|
5130
|
+
}
|
|
5131
|
+
}
|
|
5132
|
+
function isSafeTemplatePath(path22) {
|
|
5133
|
+
if (path22.length === 0 || path22.length > 300) return false;
|
|
5134
|
+
if (path22.startsWith("/") || path22.includes("\\")) return false;
|
|
5135
|
+
const segments = path22.split("/");
|
|
5136
|
+
return segments.every(
|
|
5137
|
+
(seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
|
|
5138
|
+
);
|
|
5139
|
+
}
|
|
5062
5140
|
function identifyTokenType(token) {
|
|
5063
5141
|
if (token.startsWith("way_")) return "way_token";
|
|
5064
5142
|
if (token.startsWith("eyJ")) return "jwt";
|
|
@@ -5124,7 +5202,7 @@ function findStepBoundaries(transcript) {
|
|
|
5124
5202
|
}
|
|
5125
5203
|
return out;
|
|
5126
5204
|
}
|
|
5127
|
-
var APP_ERROR_BRAND, AppError, LLM_RATE_LIMIT_BRAND, LlmRateLimitError, LLM_PROVIDER_HTTP_BRAND, LlmProviderHttpError, LLM_PROVIDER_TIMEOUT_BRAND, LlmProviderTimeoutError, ExternalServiceError, CHANNEL_PROVIDER_HTTP_BRAND, ChannelProviderHttpError, MEDIA_PROVIDER_HTTP_BRAND, MediaProviderHttpError, AUTH_TYPE, ORG_CREDENTIAL_AUTH_TYPES, AUTH_TYPE_DISPLAY, LEGACY_AUTH_TYPE_MAP, VALID_AUTH_TYPES, AGENT_ROLES, SAFE_USER_ID_REGEX, uuidSchema, paginationSchema, timestampSchema, idParamSchema, primaryRegionSchema, placementSourceSchema, orgIdParam, orgAdminIdParam, createOrganizationBody, updateOrganizationBody, addOrgAdminBody, SUMMARIZATION_THRESHOLD_MIN, SUMMARIZATION_THRESHOLD_MAX, summarizationThresholdField, monitorConfigField, agentIdParam, listAgentsQuery, agentConnectionsQuery, createAgentBody, updateAgentBody, AGENT_PARAMETER_TYPES, AGENT_PARAMETER_NAME_REGEX, agentParameterCreateSchema, MAX_AGENT_PARAMETERS_PER_REQUEST, createAgentParametersBody, SLUG_REGEX, slugSchema, INVISIBLE_NAME_CHARS, MAX_KANBAN_STATUSES, MAX_FOLLOWUPS_PER_STATUS, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES, RESERVED_TEMPLATE_DUMP_NAME, kanbanStatusSlugSchema, followupSchema, EXCLUSIVE_FLAG_PAIRS, kanbanStatusSchema, kanbanStatusesArraySchema, hubIdParam, hubAdminIdParam, hubUserIdParam, hubIdentityIdParam, hubTeamIdParam, hubTeamUserDeleteParam, hubSchemaQuery, createHubBody, updateHubBody, addHubAdminBody, addHubIdentityAuthorizationBody, contactDecisionBody, approveContactBody, listContactAccessQuery, createHubTeamBody, updateHubTeamBody, addHubTeamUserBody, reassignHubUserBody, replicatePreviewBody, claimCodeChannelParam, claimCodeDeleteParam, connectionIdParam, connectorIdParam, listConnectionsQuery, deleteConnectionQuery, addConnectionBody, editConnectionBody, registerWhatsappQuery, registerWhatsappBody, retryProvisioningQuery, resendDomainStatusQuery, PLACEHOLDER_TOKENS, ALLOWED_TYPES, SUBSCHEMA_OBJECT_KEYWORDS, SUBSCHEMA_LIST_KEYWORDS, SUBSCHEMA_MAP_KEYWORDS, MAX_SCHEMA_DEPTH, toolIdParam, listToolsQuery, toolAgentQuery, deleteToolQuery, toolConnectionsQuery, nativeToolIdSchema, addNativeToolBody, addMcpToolBody, createCustomToolBody, updateCustomToolBody, updateToolExecutionConfigBody, initialValueCreateSchema, initialValueUpdateSchema, stateIdParam, listStatesQuery, stateNameSchema, createStateBody, updateStateBody, reorderStatesBody, orgTagIdParam, listOrgTagsQuery, createOrgTagBody, updateOrgTagBody, orgCredentialIdParam, listOrgCredentialsQuery, createOrgCredentialBody, updateOrgCredentialBody, orgResourceIdParam, orgResourceFileIdParam, orgResourceFolderIdParam, hubOrgResourceParam, listOrgResourcesQuery, orgIdQuery, createOrgResourceBody, updateOrgResourceBody, createOrgResourceFolderBody, updateOrgResourceFolderBody, uploadOrgResourceFileBody, updateOrgResourceFileBody, uploadOrgSkillZipBody, linkOrgResourceBody, resourceIdParam, listResourcesQuery, createResourceBody, updateResourceBody, syncSkillsBody, resourceFileIdParam, listResourceFilesQuery, createResourceFileBody, updateResourceFileBody, uploadResourceFileBody, uploadSkillZipBody, resourceFolderIdParam, listResourceFoldersQuery, createResourceFolderBody, updateResourceFolderBody, agentResourceQuery, hubResourceQuery, linkAgentResourceBody, updateAgentResourceBody, unlinkAgentResourceQuery, navItemSchema, hubCountResetBody, navItemCountResetBody, typingBody, analyticsHubIdParam, analyticsVariableIdParam, updateVariablePinBody, updateAnalyticsViewBody, NUMERIC_FILTER_OPS, TEXT_FILTER_OPS, CATEGORICAL_FILTER_OPS, VARIABLE_FILTER_OPS, STRUCTURED_QUERY_OPS, STRUCTURED_QUERY_AGGREGATIONS, filterValueSchema, conversationsBody, analyticsConversationIdParam, messagesQuery, conversationDetailDataQuery, analyticsDataBody, structuredQueryBody, analyticsSqlBody, analyticsSqlSchemaQuery, PACING_INTERVAL_MIN_MS, PACING_INTERVAL_MAX_MS, EVAL_RUN_DEADLINE_MIN_MS, EVAL_RUN_DEADLINE_MAX_MS, paginationSchema2, evalIdParam, sessionIdParam, scenarioSetIdParam, hubIdQuery, createEvalBody, updateEvalBody, getEvalsQuery, toggleEvalBody, bulkToggleEvalsBody, pacingConfigSchema, sessionConfigSchema, createSessionBody, getSessionsQuery, getSessionResultsQuery, getSessionRunsQuery, evalAnalyticsQuery, getSessionCostQuery, compareSessionsQuery, evalsSqlBody, evalsSqlSchemaQuery, exportResultsQuery, validateEvalBody, hubAgentsQuery, createScenarioSetBody, updateScenarioSetBody, scenarioSetsHubQuery, createScenarioFromConversationBody, createJourneyFromConversationBody, journeyIdParam, journeyToolCallSchema, journeyTurnSchema, journeyStepOverrideSchema, createJourneyBody, updateJourneyBody, getConversationsQuery, getMessagesQuery, updateUserBody, updateProfileBody, pathnameRegex, updatePreferencesBody, registerPushTokenBody, deletePushTokenQuery, activityQuery, deletionModeSchema, deletionRequestBody, archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams, conversationIdParam, claimBody, releaseBody, transferBody, closeBody, additionalContextPayloadSchema, kanbanUpdateBody, observabilityParams, observabilityListParams, deleteUserConversationsBody, sendMessageBody, listConversationsQuery, getConversationDetailParams, getConversationDetailQuery, listWhatsAppTemplatesQuery, sendWhatsAppTemplateBody, billingOrgIdParam, subscriptionItemParams, spendCapBody, growthPacksBody, portalSessionBody, checkoutSessionBody, updateBillingCurrencyBody, invoicesQuery, downloadBody, uploadQuery, signUrlBody, completionsBody, outboundSchemaQuery, templateIdParam, listTemplatesQuery, deleteTemplateQuery, templateStatusQuery, createTemplateBody, updateTemplateBody, submitTemplateBody, testTemplateBody, contactIdParam, listContactsQuery, createContactBody, updateContactBody, listIdParam, listListsQuery, listListContactsQuery, createListBody, updateListBody, addListContactsBody, removeListContactsBody, scheduleIdParam, listSchedulesQuery, listExecutionsQuery, createScheduleBody, updateScheduleBody, uuidPattern, ciUuidSchema, hubAsCodeConfigSchema, ciPullHubIdParam, ciBranchParam, ciPullQuery, ciHubsQuery, ciLookupQuery, ciBranchesQuery, ciSyncBody, ciPushBody, ciDiffBody, ciPublishBody, ciPublishPreviewBody, ciSyncMcpBody, ciOrgResourcesParam, orgResourcesConfigSchema, ciOrgResourcesPushBody, ciOrgResourcesDiffBody, adminOrgIdParam, adminOrgAdminIdParam, adminUserIdParam, adminPlanIdParam, adminOrganizationsQuery, adminUserSearchQuery, kanbanSlugMigrationQuery, adjustQuotaBody, updatePlanBody, addAdminUserBody, updatePlatformConfigBody, updateFreeOrgLimitBody, updatePricingPlanBody, dataExplorerSearchQuery, dataExplorerOrgIdParam, dataExplorerHubIdParam, dataExplorerConvIdParam, dataExplorerDoInstancesQuery, dataExplorerNsIdParam, dataExplorerKvKeysQuery, dataExplorerKvKeyParam, uuidOrHexId, dataExplorerDeleteOrgParam, dataExplorerDeleteHubParam, dataExplorerDeleteConvParam, dataExplorerDeleteUserParam, dataExplorerDeleteQuery, dataExplorerKvDeleteQuery, pitrDoNamespace, pitrBookmarkParam, pitrRestoreBody, healthSamplingTriggerBody, dataExplorerDebugDoType, DEBUG_READ_MAX_LIMIT, DEBUG_READ_DEFAULT_LIMIT, DEBUG_DO_HEX_PREFIX, debugDoEntityId, debugTableName, dataExplorerDebugTablesParam, dataExplorerDebugRowsParam, dataExplorerDebugRowsQuery, dataExplorerDebugAnalyticsTable, debugUuid, dataExplorerDebugAnalyticsRowsParam, dataExplorerDebugAnalyticsRowsQuery, debugHubConvParam, debugMessageIdQuery, whatsappCallbackBody, authMeResponse, wsTicketResponse, sessionCheckResponse, logoutResponse, magicCodeSendBody, magicCodeSendResponse, magicCodeVerifyBody, magicCodeVerifyResponse, browserParams, browserFoldersQuery, browserFilesQuery, stateOperationBody, conversationListResourcesQuery, conversationReadResourceQuery, listPendingSchedulesQuery, listHubAggregateSchedulesQuery, reportSourceSchema, intakeReportSourceSchema, reportClassificationSchema, reportStatusSchema, reportLocaleSchema, reportMessageAuthorRoleSchema, sentryRefStatusSchema, createReportBody, editReportBody, contestReportBody, reporterListQuery, listReportsQuery, GITHUB_ISSUE_URL_REGEX, githubIssueUrlSchema, transitionReportBody, groupReportsBody, holdReportBody, clickhouseReadyResponse, bootstrapQuery, requestSnapshotChunkMessage, MAX_NAME_LENGTH, MAX_VALUE_LENGTH, MAX_TAGS, MAX_TAG_LENGTH, MAX_SCOPE_HUBS, MAX_SCOPE_TAGS, vaultSecretScopeSchema, vaultCreateBody, vaultUpdateBody, PERMISSIONS, MAX_NAME_LENGTH2, MAX_HUBS_PER_GRANT, MAX_HUB_TAGS_PER_GRANT, MAX_GRANTS, permissionEnum, grantScopeSchema, grantSchema, createTokenBody, tokenOrgIdParam, tokenGrantScopeSchema, tokenGrantSchema, tokenMetadataSchema, listTokensResponse, createTokenResponse, orgTokenSummarySchema, listOrgTokensResponse, invitePreviewQuery, invitePreviewResponse, discordTier, discordBillingCycle, discordMetadata, discordOAuthStartResponse, discordOAuthFinalizeBody, discordOAuthFinalizeResponse, discordDisconnectResponse, jsonSchemaSchema, hubUserIdentity, stateValueEntry, getHubUserContextResponse, updateHubUserBody, updateHubUserResponse, unlockHubUserNameResponse, stateResetParams, stateResetResponse, hubAlertsParam, hubAlertSeverity, hubAlert, hubAlertsListResponse, noticeSeveritySchema, noticeStatusSchema, NOTICE_SCOPE_REGEX, noticeScopeSchema, noticeLinkSchema, createNoticeBody, updateNoticeBody, listNoticesQuery, noticeIdParamSchema, WAYAI_WORKSPACE_LAYOUT, MAX_RESOURCE_FILE_SIZE;
|
|
5205
|
+
var APP_ERROR_BRAND, AppError, LLM_RATE_LIMIT_BRAND, LlmRateLimitError, LLM_PROVIDER_HTTP_BRAND, LlmProviderHttpError, LLM_PROVIDER_TIMEOUT_BRAND, LlmProviderTimeoutError, ExternalServiceError, CHANNEL_PROVIDER_HTTP_BRAND, ChannelProviderHttpError, MEDIA_PROVIDER_HTTP_BRAND, MediaProviderHttpError, AUTH_TYPE, ORG_CREDENTIAL_AUTH_TYPES, AUTH_TYPE_DISPLAY, LEGACY_AUTH_TYPE_MAP, VALID_AUTH_TYPES, AGENT_ROLES, SAFE_USER_ID_REGEX, uuidSchema, paginationSchema, timestampSchema, idParamSchema, primaryRegionSchema, placementSourceSchema, orgIdParam, orgAdminIdParam, createOrganizationBody, updateOrganizationBody, addOrgAdminBody, SUMMARIZATION_THRESHOLD_MIN, SUMMARIZATION_THRESHOLD_MAX, summarizationThresholdField, monitorConfigField, agentIdParam, listAgentsQuery, agentConnectionsQuery, createAgentBody, updateAgentBody, AGENT_PARAMETER_TYPES, AGENT_PARAMETER_NAME_REGEX, agentParameterCreateSchema, MAX_AGENT_PARAMETERS_PER_REQUEST, createAgentParametersBody, SLUG_REGEX, slugSchema, INVISIBLE_NAME_CHARS, MAX_KANBAN_STATUSES, MAX_FOLLOWUPS_PER_STATUS, MAX_LANES, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES, RESERVED_TEMPLATE_DUMP_NAME, kanbanStatusSlugSchema, followupSchema, EXCLUSIVE_FLAG_PAIRS, kanbanStatusSchema, kanbanStatusesArraySchema, laneSchema, lanesArraySchema, hubIdParam, hubAdminIdParam, hubUserIdParam, hubIdentityIdParam, hubTeamIdParam, hubTeamUserDeleteParam, hubSchemaQuery, createHubBody, updateHubBody, addHubAdminBody, addHubIdentityAuthorizationBody, contactDecisionBody, approveContactBody, listContactAccessQuery, createHubTeamBody, updateHubTeamBody, addHubTeamUserBody, reassignHubUserBody, replicatePreviewBody, claimCodeChannelParam, claimCodeDeleteParam, connectionIdParam, connectorIdParam, listConnectionsQuery, deleteConnectionQuery, addConnectionBody, editConnectionBody, registerWhatsappQuery, registerWhatsappBody, retryProvisioningQuery, resendDomainStatusQuery, PLACEHOLDER_TOKENS, ALLOWED_TYPES, SUBSCHEMA_OBJECT_KEYWORDS, SUBSCHEMA_LIST_KEYWORDS, SUBSCHEMA_MAP_KEYWORDS, MAX_SCHEMA_DEPTH, toolIdParam, listToolsQuery, toolAgentQuery, deleteToolQuery, toolConnectionsQuery, nativeToolIdSchema, addNativeToolBody, addMcpToolBody, createCustomToolBody, updateCustomToolBody, updateToolExecutionConfigBody, initialValueCreateSchema, initialValueUpdateSchema, stateIdParam, listStatesQuery, stateNameSchema, createStateBody, updateStateBody, reorderStatesBody, orgTagIdParam, listOrgTagsQuery, createOrgTagBody, updateOrgTagBody, orgCredentialIdParam, listOrgCredentialsQuery, createOrgCredentialBody, updateOrgCredentialBody, orgResourceIdParam, orgResourceFileIdParam, orgResourceFolderIdParam, hubOrgResourceParam, listOrgResourcesQuery, orgIdQuery, createOrgResourceBody, updateOrgResourceBody, createOrgResourceFolderBody, updateOrgResourceFolderBody, uploadOrgResourceFileBody, updateOrgResourceFileBody, uploadOrgSkillZipBody, linkOrgResourceBody, resourceIdParam, listResourcesQuery, createResourceBody, updateResourceBody, syncSkillsBody, resourceFileIdParam, listResourceFilesQuery, createResourceFileBody, updateResourceFileBody, uploadResourceFileBody, uploadSkillZipBody, resourceFolderIdParam, listResourceFoldersQuery, createResourceFolderBody, updateResourceFolderBody, agentResourceQuery, hubResourceQuery, linkAgentResourceBody, updateAgentResourceBody, unlinkAgentResourceQuery, navItemSchema, hubCountResetBody, navItemCountResetBody, typingBody, analyticsHubIdParam, analyticsVariableIdParam, updateVariablePinBody, updateAnalyticsViewBody, NUMERIC_FILTER_OPS, TEXT_FILTER_OPS, CATEGORICAL_FILTER_OPS, VARIABLE_FILTER_OPS, STRUCTURED_QUERY_OPS, STRUCTURED_QUERY_AGGREGATIONS, filterValueSchema, conversationsBody, analyticsConversationIdParam, messagesQuery, conversationDetailDataQuery, analyticsDataBody, structuredQueryBody, analyticsSqlBody, analyticsSqlSchemaQuery, PACING_INTERVAL_MIN_MS, PACING_INTERVAL_MAX_MS, EVAL_RUN_DEADLINE_MIN_MS, EVAL_RUN_DEADLINE_MAX_MS, paginationSchema2, evalIdParam, sessionIdParam, scenarioSetIdParam, hubIdQuery, createEvalBody, updateEvalBody, getEvalsQuery, toggleEvalBody, bulkToggleEvalsBody, pacingConfigSchema, sessionConfigSchema, createSessionBody, getSessionsQuery, getSessionResultsQuery, getSessionRunsQuery, evalAnalyticsQuery, getSessionCostQuery, compareSessionsQuery, evalsSqlBody, evalsSqlSchemaQuery, exportResultsQuery, validateEvalBody, hubAgentsQuery, createScenarioSetBody, updateScenarioSetBody, scenarioSetsHubQuery, createScenarioFromConversationBody, createJourneyFromConversationBody, journeyIdParam, journeyToolCallSchema, journeyTurnSchema, journeyStepOverrideSchema, createJourneyBody, updateJourneyBody, getConversationsQuery, getMessagesQuery, updateUserBody, updateProfileBody, pathnameRegex, updatePreferencesBody, registerPushTokenBody, deletePushTokenQuery, activityQuery, deletionModeSchema, deletionRequestBody, archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams, conversationIdParam, claimBody, releaseBody, transferBody, closeBody, additionalContextPayloadSchema, kanbanUpdateBody, observabilityParams, observabilityListParams, deleteUserConversationsBody, sendMessageBody, listConversationsQuery, getConversationDetailParams, getConversationDetailQuery, listWhatsAppTemplatesQuery, sendWhatsAppTemplateBody, billingOrgIdParam, subscriptionItemParams, spendCapBody, growthPacksBody, portalSessionBody, checkoutSessionBody, updateBillingCurrencyBody, invoicesQuery, downloadBody, uploadQuery, signUrlBody, completionsBody, outboundSchemaQuery, templateIdParam, listTemplatesQuery, deleteTemplateQuery, templateStatusQuery, createTemplateBody, updateTemplateBody, submitTemplateBody, testTemplateBody, contactIdParam, listContactsQuery, createContactBody, updateContactBody, listIdParam, listListsQuery, listListContactsQuery, createListBody, updateListBody, addListContactsBody, removeListContactsBody, scheduleIdParam, listSchedulesQuery, listExecutionsQuery, createScheduleBody, updateScheduleBody, uuidPattern, ciUuidSchema, hubAsCodeConfigSchema, ciPullHubIdParam, ciBranchParam, ciPullQuery, ciHubsQuery, ciLookupQuery, ciBranchesQuery, ciSyncBody, ciPushBody, ciDiffBody, ciPublishBody, ciPublishPreviewBody, ciSyncMcpBody, ciOrgResourcesParam, orgResourcesConfigSchema, ciOrgResourcesPushBody, ciOrgResourcesDiffBody, adminOrgIdParam, adminOrgAdminIdParam, adminUserIdParam, adminPlanIdParam, adminOrganizationsQuery, adminUserSearchQuery, kanbanSlugMigrationQuery, adjustQuotaBody, updatePlanBody, addAdminUserBody, updatePlatformConfigBody, updateFreeOrgLimitBody, updatePricingPlanBody, dataExplorerSearchQuery, dataExplorerOrgIdParam, dataExplorerHubIdParam, dataExplorerConvIdParam, dataExplorerDoInstancesQuery, dataExplorerNsIdParam, dataExplorerKvKeysQuery, dataExplorerKvKeyParam, uuidOrHexId, dataExplorerDeleteOrgParam, dataExplorerDeleteHubParam, dataExplorerDeleteConvParam, dataExplorerDeleteUserParam, dataExplorerDeleteQuery, dataExplorerKvDeleteQuery, pitrDoNamespace, pitrBookmarkParam, pitrRestoreBody, healthSamplingTriggerBody, dataExplorerDebugDoType, DEBUG_READ_MAX_LIMIT, DEBUG_READ_DEFAULT_LIMIT, DEBUG_DO_HEX_PREFIX, debugDoEntityId, debugTableName, dataExplorerDebugTablesParam, dataExplorerDebugRowsParam, dataExplorerDebugRowsQuery, dataExplorerDebugAnalyticsTable, debugUuid, dataExplorerDebugAnalyticsRowsParam, dataExplorerDebugAnalyticsRowsQuery, debugHubConvParam, debugMessageIdQuery, whatsappCallbackBody, authMeResponse, wsTicketResponse, sessionCheckResponse, logoutResponse, magicCodeSendBody, magicCodeSendResponse, magicCodeVerifyBody, magicCodeVerifyResponse, browserParams, browserFoldersQuery, browserFilesQuery, stateOperationBody, conversationListResourcesQuery, conversationReadResourceQuery, listPendingSchedulesQuery, listHubAggregateSchedulesQuery, reportSourceSchema, intakeReportSourceSchema, reportClassificationSchema, reportStatusSchema, reportLocaleSchema, reportMessageAuthorRoleSchema, sentryRefStatusSchema, createReportBody, editReportBody, contestReportBody, reporterListQuery, listReportsQuery, GITHUB_ISSUE_URL_REGEX, githubIssueUrlSchema, transitionReportBody, groupReportsBody, holdReportBody, clickhouseReadyResponse, bootstrapQuery, requestSnapshotChunkMessage, MAX_NAME_LENGTH, MAX_VALUE_LENGTH, MAX_TAGS, MAX_TAG_LENGTH, MAX_SCOPE_HUBS, MAX_SCOPE_TAGS, vaultSecretScopeSchema, vaultCreateBody, vaultUpdateBody, PERMISSIONS, MAX_NAME_LENGTH2, MAX_HUBS_PER_GRANT, MAX_HUB_TAGS_PER_GRANT, MAX_GRANTS, permissionEnum, grantScopeSchema, grantSchema, createTokenBody, tokenOrgIdParam, tokenGrantScopeSchema, tokenGrantSchema, tokenMetadataSchema, listTokensResponse, createTokenResponse, orgTokenSummarySchema, listOrgTokensResponse, invitePreviewQuery, invitePreviewResponse, discordTier, discordBillingCycle, discordMetadata, discordOAuthStartResponse, discordOAuthFinalizeBody, discordOAuthFinalizeResponse, discordDisconnectResponse, jsonSchemaSchema, hubUserIdentity, stateValueEntry, getHubUserContextResponse, updateHubUserBody, updateHubUserResponse, unlockHubUserNameResponse, stateResetParams, stateResetResponse, hubAlertsParam, hubAlertSeverity, hubAlert, hubAlertsListResponse, noticeSeveritySchema, noticeStatusSchema, NOTICE_SCOPE_REGEX, noticeScopeSchema, noticeLinkSchema, createNoticeBody, updateNoticeBody, listNoticesQuery, noticeIdParamSchema, TEMPLATE_SLUG_REGEX, templateSlugSchema, templateStatusSchema, templateFileMapSchema, templateWayaiBlockSchema, templateRekorBlockSchema, templateYamlWayaiBlock, templateYamlRekorBlock, templateYamlSchema, templatePushMetadataSchema, templateHeroSchema, templatePushBody, templateSlugParam, WAYAI_WORKSPACE_LAYOUT, MAX_RESOURCE_FILE_SIZE;
|
|
5128
5206
|
var init_dist = __esm({
|
|
5129
5207
|
"../../packages/core/dist/index.js"() {
|
|
5130
5208
|
"use strict";
|
|
@@ -5172,6 +5250,7 @@ var init_dist = __esm({
|
|
|
5172
5250
|
init_zod();
|
|
5173
5251
|
init_zod();
|
|
5174
5252
|
init_zod();
|
|
5253
|
+
init_zod();
|
|
5175
5254
|
APP_ERROR_BRAND = /* @__PURE__ */ Symbol.for("wayai.AppError");
|
|
5176
5255
|
AppError = class extends Error {
|
|
5177
5256
|
constructor(message, code, statusCode = 500, details) {
|
|
@@ -5417,6 +5496,7 @@ var init_dist = __esm({
|
|
|
5417
5496
|
INVISIBLE_NAME_CHARS = /[\s\p{Default_Ignorable_Code_Point}]/gu;
|
|
5418
5497
|
MAX_KANBAN_STATUSES = 50;
|
|
5419
5498
|
MAX_FOLLOWUPS_PER_STATUS = 20;
|
|
5499
|
+
MAX_LANES = 20;
|
|
5420
5500
|
MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES = 16384;
|
|
5421
5501
|
RESERVED_TEMPLATE_DUMP_NAME = "additional_data";
|
|
5422
5502
|
kanbanStatusSlugSchema = slugSchema;
|
|
@@ -5473,7 +5553,14 @@ var init_dist = __esm({
|
|
|
5473
5553
|
/** Slugs this status may transition to. `undefined` = unrestricted (any
|
|
5474
5554
|
* next status). Empty array `[]` is rejected — author must use
|
|
5475
5555
|
* `isTerminalStatus: true` to express "no outbound transitions". */
|
|
5476
|
-
allowed_next_statuses: external_exports.array(external_exports.string()).min(1, "allowed_next_statuses cannot be empty \u2014 use isTerminalStatus: true for no outbound transitions").optional()
|
|
5556
|
+
allowed_next_statuses: external_exports.array(external_exports.string()).min(1, "allowed_next_statuses cannot be empty \u2014 use isTerminalStatus: true for no outbound transitions").optional(),
|
|
5557
|
+
/** Optional presentational grouping — the slug of a hub `lanes[]` entry this
|
|
5558
|
+
* status belongs to. `undefined` = ungrouped. Purely a board-filter/organization
|
|
5559
|
+
* concept; it does NOT constrain transitions (those live in `allowed_next_statuses`)
|
|
5560
|
+
* and is not exposed to agents. The cross-reference invariant (must point at a
|
|
5561
|
+
* declared lane; the initial status must not have one) is enforced at the hub
|
|
5562
|
+
* level via `validateLaneReferences` — this schema only sees the status array. */
|
|
5563
|
+
lane_slug: kanbanStatusSlugSchema.optional()
|
|
5477
5564
|
}).passthrough().superRefine((status, ctx) => {
|
|
5478
5565
|
const label = status.name ? `"${status.name}"` : status.slug ? `"${status.slug}"` : "<unnamed>";
|
|
5479
5566
|
for (const [a, b] of EXCLUSIVE_FLAG_PAIRS) {
|
|
@@ -5564,6 +5651,28 @@ var init_dist = __esm({
|
|
|
5564
5651
|
});
|
|
5565
5652
|
});
|
|
5566
5653
|
});
|
|
5654
|
+
laneSchema = external_exports.object({
|
|
5655
|
+
slug: kanbanStatusSlugSchema,
|
|
5656
|
+
name: external_exports.string().min(1, "name is required").max(100, "name must be 100 characters or fewer").refine((v) => visibleLength(v) > 0, "name must not be blank"),
|
|
5657
|
+
color: external_exports.string().optional(),
|
|
5658
|
+
order: external_exports.number().int().nonnegative().optional()
|
|
5659
|
+
}).passthrough();
|
|
5660
|
+
lanesArraySchema = external_exports.array(laneSchema).max(MAX_LANES, `lanes must have at most ${MAX_LANES} entries`).superRefine((lanes, ctx) => {
|
|
5661
|
+
const seen = /* @__PURE__ */ new Map();
|
|
5662
|
+
lanes.forEach((l, i) => {
|
|
5663
|
+
if (!l.slug) return;
|
|
5664
|
+
const arr = seen.get(l.slug) ?? [];
|
|
5665
|
+
arr.push(i);
|
|
5666
|
+
seen.set(l.slug, arr);
|
|
5667
|
+
});
|
|
5668
|
+
for (const [slug, indices] of seen) {
|
|
5669
|
+
if (indices.length > 1) {
|
|
5670
|
+
for (const i of indices) {
|
|
5671
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: [i, "slug"], message: `lanes: duplicate slug "${slug}"` });
|
|
5672
|
+
}
|
|
5673
|
+
}
|
|
5674
|
+
}
|
|
5675
|
+
});
|
|
5567
5676
|
hubIdParam = external_exports.object({ id: uuidSchema });
|
|
5568
5677
|
hubAdminIdParam = external_exports.object({ id: uuidSchema, adminId: uuidSchema });
|
|
5569
5678
|
hubUserIdParam = external_exports.object({ id: uuidSchema, hubUserId: uuidSchema });
|
|
@@ -5576,14 +5685,16 @@ var init_dist = __esm({
|
|
|
5576
5685
|
hub_name: external_exports.string().min(1, "hub_name is required"),
|
|
5577
5686
|
hub_description: external_exports.string().optional(),
|
|
5578
5687
|
kanban_statuses: kanbanStatusesArraySchema.nullable().optional(),
|
|
5688
|
+
lanes: lanesArraySchema.nullable().optional(),
|
|
5579
5689
|
// Write-once at creation; updateHubBody does not accept this.
|
|
5580
5690
|
primary_region: primaryRegionSchema.optional()
|
|
5581
|
-
}).passthrough();
|
|
5691
|
+
}).passthrough().superRefine(refineLaneReferences);
|
|
5582
5692
|
updateHubBody = external_exports.object({
|
|
5583
5693
|
support_model: external_exports.enum(["conversation", "account"]).optional(),
|
|
5584
5694
|
unassigned_policy: external_exports.enum(["default_team", "auto_assign_random", "auto_assign_round_robin", "pull_queue"]).optional(),
|
|
5585
5695
|
default_hub_team_id: uuidSchema.nullable().optional(),
|
|
5586
5696
|
kanban_statuses: kanbanStatusesArraySchema.nullable().optional(),
|
|
5697
|
+
lanes: lanesArraySchema.nullable().optional(),
|
|
5587
5698
|
// summarization_threshold_tokens relocated to the summarizer AGENT (PR4) — validated/
|
|
5588
5699
|
// persisted via the agent path (.passthrough() agent body → HubDO column), not here.
|
|
5589
5700
|
auto_close_inactive_days: external_exports.number().int().min(1).max(180).optional(),
|
|
@@ -5592,7 +5703,7 @@ var init_dist = __esm({
|
|
|
5592
5703
|
language: external_exports.enum(["en", "pt", "es"]).optional(),
|
|
5593
5704
|
access_request_message: external_exports.string().max(1e3).nullable().optional(),
|
|
5594
5705
|
access_approval_role: external_exports.enum(["admin", "team"]).optional()
|
|
5595
|
-
}).passthrough();
|
|
5706
|
+
}).passthrough().superRefine(refineLaneReferences);
|
|
5596
5707
|
addHubAdminBody = external_exports.object({
|
|
5597
5708
|
user_email: external_exports.string().email("valid email is required")
|
|
5598
5709
|
});
|
|
@@ -6768,6 +6879,7 @@ var init_dist = __esm({
|
|
|
6768
6879
|
}).passthrough().superRefine((config, ctx) => {
|
|
6769
6880
|
refineHubAsCodeCustomTools(config, ctx);
|
|
6770
6881
|
refineHubAsCodeKanbanStatuses(config, ctx);
|
|
6882
|
+
refineHubAsCodeLanes(config, ctx);
|
|
6771
6883
|
});
|
|
6772
6884
|
ciPullHubIdParam = external_exports.object({
|
|
6773
6885
|
hub_id: ciUuidSchema
|
|
@@ -7439,6 +7551,62 @@ var init_dist = __esm({
|
|
|
7439
7551
|
offset: external_exports.coerce.number().int().min(0).optional()
|
|
7440
7552
|
});
|
|
7441
7553
|
noticeIdParamSchema = external_exports.object({ id: external_exports.string().min(1) });
|
|
7554
|
+
TEMPLATE_SLUG_REGEX = /^[a-z0-9][a-z0-9-]{0,62}$/;
|
|
7555
|
+
templateSlugSchema = external_exports.string().regex(TEMPLATE_SLUG_REGEX, "slug must be lowercase alphanumeric with hyphens (max 63)");
|
|
7556
|
+
templateStatusSchema = external_exports.enum(["published", "draft", "internal"]);
|
|
7557
|
+
templateFileMapSchema = external_exports.record(external_exports.string()).refine((m) => Object.keys(m).every(isSafeTemplatePath), {
|
|
7558
|
+
message: 'file map contains an unsafe path (no absolute paths, "..", or backslashes)'
|
|
7559
|
+
});
|
|
7560
|
+
templateWayaiBlockSchema = external_exports.object({
|
|
7561
|
+
metaTitle: external_exports.string().min(1).max(200),
|
|
7562
|
+
metaDescription: external_exports.string().max(1e3).default(""),
|
|
7563
|
+
installCommand: external_exports.string().min(1).max(300)
|
|
7564
|
+
});
|
|
7565
|
+
templateRekorBlockSchema = templateWayaiBlockSchema.extend({
|
|
7566
|
+
mcpEndpoint: external_exports.string().url().optional(),
|
|
7567
|
+
url: external_exports.string().url().optional()
|
|
7568
|
+
});
|
|
7569
|
+
templateYamlWayaiBlock = templateWayaiBlockSchema.extend({
|
|
7570
|
+
source: external_exports.string().min(1)
|
|
7571
|
+
});
|
|
7572
|
+
templateYamlRekorBlock = templateRekorBlockSchema.extend({
|
|
7573
|
+
source: external_exports.string().min(1)
|
|
7574
|
+
});
|
|
7575
|
+
templateYamlSchema = external_exports.object({
|
|
7576
|
+
slug: templateSlugSchema,
|
|
7577
|
+
category: external_exports.string().min(1).max(60),
|
|
7578
|
+
status: templateStatusSchema.default("draft"),
|
|
7579
|
+
order: external_exports.number().int().min(0).max(1e5).optional(),
|
|
7580
|
+
hero: external_exports.string().optional(),
|
|
7581
|
+
// relative path to a hero image inside the template folder
|
|
7582
|
+
wayai: templateYamlWayaiBlock.optional(),
|
|
7583
|
+
rekor: templateYamlRekorBlock.optional()
|
|
7584
|
+
}).refine((c) => Boolean(c.wayai) || Boolean(c.rekor), {
|
|
7585
|
+
message: "template.yaml must define at least one of `wayai:` or `rekor:`"
|
|
7586
|
+
});
|
|
7587
|
+
templatePushMetadataSchema = external_exports.object({
|
|
7588
|
+
category: external_exports.string().min(1).max(60),
|
|
7589
|
+
status: templateStatusSchema,
|
|
7590
|
+
order: external_exports.number().int().min(0).max(1e5).default(0),
|
|
7591
|
+
wayai: templateWayaiBlockSchema.optional(),
|
|
7592
|
+
rekor: templateRekorBlockSchema.optional()
|
|
7593
|
+
});
|
|
7594
|
+
templateHeroSchema = external_exports.object({
|
|
7595
|
+
filename: external_exports.string().min(1).max(200).regex(/\.(png|jpe?g|webp|gif)$/i, "hero must be a raster image (png/jpg/webp/gif)"),
|
|
7596
|
+
// ~8MB of base64 ≈ a ~6MB image — a generous cap that bounds the inline payload
|
|
7597
|
+
// (the endpoint is platform-admin-only, but an unbounded blob is still avoidable).
|
|
7598
|
+
dataBase64: external_exports.string().min(1).max(8e6)
|
|
7599
|
+
});
|
|
7600
|
+
templatePushBody = external_exports.object({
|
|
7601
|
+
slug: templateSlugSchema,
|
|
7602
|
+
metadata: templatePushMetadataSchema,
|
|
7603
|
+
// wayai slice file-map (path -> body); ABSENT for a Rekor-only template.
|
|
7604
|
+
wayaiFiles: templateFileMapSchema.optional(),
|
|
7605
|
+
// raw README markdown; the backend renders + sanitizes (single authority).
|
|
7606
|
+
readmeMarkdown: external_exports.string().default(""),
|
|
7607
|
+
hero: templateHeroSchema.optional()
|
|
7608
|
+
});
|
|
7609
|
+
templateSlugParam = external_exports.object({ slug: templateSlugSchema });
|
|
7442
7610
|
WAYAI_WORKSPACE_LAYOUT = {
|
|
7443
7611
|
/** Product-namespaced root dir at the git root. */
|
|
7444
7612
|
wsDir: "wayai-ws",
|
|
@@ -7490,6 +7658,9 @@ function resolveLayout(gitRoot, layout = WAYAI_LAYOUT) {
|
|
|
7490
7658
|
legacyAlsoPresent: false
|
|
7491
7659
|
};
|
|
7492
7660
|
}
|
|
7661
|
+
function resolveTemplatesDir(gitRoot) {
|
|
7662
|
+
return path.join(gitRoot, TEMPLATES_AUTHORING_SUBDIR);
|
|
7663
|
+
}
|
|
7493
7664
|
function hubsDirLabel(gitRoot) {
|
|
7494
7665
|
if (!gitRoot) return path.join(WAYAI_LAYOUT.wsDir, WAYAI_LAYOUT.hubsSubdir);
|
|
7495
7666
|
return path.relative(gitRoot, resolveLayout(gitRoot).hubsDir);
|
|
@@ -7515,7 +7686,7 @@ function warnLayoutOnce(gitRoot) {
|
|
|
7515
7686
|
);
|
|
7516
7687
|
}
|
|
7517
7688
|
}
|
|
7518
|
-
var WAYAI_LAYOUT, _layoutWarned;
|
|
7689
|
+
var WAYAI_LAYOUT, TEMPLATES_AUTHORING_SUBDIR, _layoutWarned;
|
|
7519
7690
|
var init_layout = __esm({
|
|
7520
7691
|
"src/lib/layout.ts"() {
|
|
7521
7692
|
"use strict";
|
|
@@ -7524,6 +7695,7 @@ var init_layout = __esm({
|
|
|
7524
7695
|
...WAYAI_WORKSPACE_LAYOUT,
|
|
7525
7696
|
legacy: { wsDir: "workspace", orgAtRoot: "org" }
|
|
7526
7697
|
};
|
|
7698
|
+
TEMPLATES_AUTHORING_SUBDIR = "templates";
|
|
7527
7699
|
_layoutWarned = false;
|
|
7528
7700
|
}
|
|
7529
7701
|
});
|
|
@@ -7814,24 +7986,24 @@ import * as path4 from "path";
|
|
|
7814
7986
|
import * as readline from "readline";
|
|
7815
7987
|
function prompt(question) {
|
|
7816
7988
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
7817
|
-
return new Promise((
|
|
7989
|
+
return new Promise((resolve5) => {
|
|
7818
7990
|
rl.question(question, (answer) => {
|
|
7819
7991
|
rl.close();
|
|
7820
|
-
|
|
7992
|
+
resolve5(answer.trim());
|
|
7821
7993
|
});
|
|
7822
7994
|
});
|
|
7823
7995
|
}
|
|
7824
7996
|
function confirm(question) {
|
|
7825
7997
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
7826
|
-
return new Promise((
|
|
7998
|
+
return new Promise((resolve5) => {
|
|
7827
7999
|
rl.question(`${question} [y/N]: `, (answer) => {
|
|
7828
8000
|
rl.close();
|
|
7829
|
-
|
|
8001
|
+
resolve5(answer.trim().toLowerCase() === "y");
|
|
7830
8002
|
});
|
|
7831
8003
|
});
|
|
7832
8004
|
}
|
|
7833
8005
|
function promptSecret(question) {
|
|
7834
|
-
return new Promise((
|
|
8006
|
+
return new Promise((resolve5) => {
|
|
7835
8007
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
7836
8008
|
const originalWrite = rl._writeToOutput;
|
|
7837
8009
|
let firstWrite = true;
|
|
@@ -7847,18 +8019,18 @@ function promptSecret(question) {
|
|
|
7847
8019
|
rl._writeToOutput = originalWrite;
|
|
7848
8020
|
process.stdout.write("\n");
|
|
7849
8021
|
rl.close();
|
|
7850
|
-
|
|
8022
|
+
resolve5(answer);
|
|
7851
8023
|
});
|
|
7852
8024
|
});
|
|
7853
8025
|
}
|
|
7854
8026
|
function readStdin() {
|
|
7855
|
-
return new Promise((
|
|
8027
|
+
return new Promise((resolve5, reject) => {
|
|
7856
8028
|
let data = "";
|
|
7857
8029
|
process.stdin.setEncoding("utf-8");
|
|
7858
8030
|
process.stdin.on("data", (chunk) => {
|
|
7859
8031
|
data += chunk;
|
|
7860
8032
|
});
|
|
7861
|
-
process.stdin.on("end", () =>
|
|
8033
|
+
process.stdin.on("end", () => resolve5(data.trim()));
|
|
7862
8034
|
process.stdin.on("error", reject);
|
|
7863
8035
|
});
|
|
7864
8036
|
}
|
|
@@ -7994,13 +8166,19 @@ function isNewerVersion(latest, current) {
|
|
|
7994
8166
|
}
|
|
7995
8167
|
return false;
|
|
7996
8168
|
}
|
|
7997
|
-
var UUID_RE, slugify;
|
|
8169
|
+
var UUID_RE, slugify, OWN_HELP_COMMANDS;
|
|
7998
8170
|
var init_utils = __esm({
|
|
7999
8171
|
"src/lib/utils.ts"() {
|
|
8000
8172
|
"use strict";
|
|
8001
8173
|
init_dist();
|
|
8002
8174
|
UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
8003
8175
|
slugify = slugifySkillName;
|
|
8176
|
+
OWN_HELP_COMMANDS = /* @__PURE__ */ new Set([
|
|
8177
|
+
"eval",
|
|
8178
|
+
"admin",
|
|
8179
|
+
"report",
|
|
8180
|
+
"conversations"
|
|
8181
|
+
]);
|
|
8004
8182
|
}
|
|
8005
8183
|
});
|
|
8006
8184
|
|
|
@@ -8013,9 +8191,9 @@ function getVersionCachePath(filename = CLI_CACHE_FILE) {
|
|
|
8013
8191
|
}
|
|
8014
8192
|
function readVersionCache(filename = CLI_CACHE_FILE) {
|
|
8015
8193
|
try {
|
|
8016
|
-
const
|
|
8017
|
-
if (!existsSync4(
|
|
8018
|
-
const parsed = JSON.parse(readFileSync5(
|
|
8194
|
+
const path22 = getVersionCachePath(filename);
|
|
8195
|
+
if (!existsSync4(path22)) return null;
|
|
8196
|
+
const parsed = JSON.parse(readFileSync5(path22, "utf-8"));
|
|
8019
8197
|
if (typeof parsed.lastCheck !== "number") return null;
|
|
8020
8198
|
if (parsed.latest !== null && typeof parsed.latest !== "string") return null;
|
|
8021
8199
|
return parsed;
|
|
@@ -8035,10 +8213,10 @@ function isVersionCacheStale(filename = CLI_CACHE_FILE, maxAgeMs = MAX_AGE_24H_M
|
|
|
8035
8213
|
return Date.now() - cache.lastCheck > maxAgeMs;
|
|
8036
8214
|
}
|
|
8037
8215
|
function writeVersionCache(filename, cache) {
|
|
8038
|
-
const
|
|
8039
|
-
const dir = dirname3(
|
|
8216
|
+
const path22 = getVersionCachePath(filename);
|
|
8217
|
+
const dir = dirname3(path22);
|
|
8040
8218
|
if (!existsSync4(dir)) mkdirSync(dir, { recursive: true });
|
|
8041
|
-
writeFileSync2(
|
|
8219
|
+
writeFileSync2(path22, JSON.stringify(cache));
|
|
8042
8220
|
}
|
|
8043
8221
|
function touchVersionCache(filename) {
|
|
8044
8222
|
writeVersionCache(filename, { lastCheck: Date.now(), latest: readVersionCache(filename)?.latest ?? null });
|
|
@@ -8073,14 +8251,14 @@ function parseFrontmatterVersion(content) {
|
|
|
8073
8251
|
function findInstalledSkills(projectRoot) {
|
|
8074
8252
|
const found = [];
|
|
8075
8253
|
for (const rel of SKILL_INSTALL_PATHS) {
|
|
8076
|
-
const
|
|
8077
|
-
if (!existsSync5(
|
|
8254
|
+
const path22 = join7(projectRoot, rel);
|
|
8255
|
+
if (!existsSync5(path22)) continue;
|
|
8078
8256
|
let version = null;
|
|
8079
8257
|
try {
|
|
8080
|
-
version = parseFrontmatterVersion(readFileSync6(
|
|
8258
|
+
version = parseFrontmatterVersion(readFileSync6(path22, "utf-8"));
|
|
8081
8259
|
} catch {
|
|
8082
8260
|
}
|
|
8083
|
-
found.push({ path:
|
|
8261
|
+
found.push({ path: path22, version });
|
|
8084
8262
|
}
|
|
8085
8263
|
return found;
|
|
8086
8264
|
}
|
|
@@ -8510,7 +8688,7 @@ async function validateToken(apiUrl, token) {
|
|
|
8510
8688
|
}
|
|
8511
8689
|
}
|
|
8512
8690
|
function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
8513
|
-
return new Promise((
|
|
8691
|
+
return new Promise((resolve5, reject) => {
|
|
8514
8692
|
const server = http.createServer((req, res) => {
|
|
8515
8693
|
const url = new URL(req.url || "/", `http://127.0.0.1:${port}`);
|
|
8516
8694
|
if (url.pathname === "/callback") {
|
|
@@ -8536,7 +8714,7 @@ function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
|
8536
8714
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
8537
8715
|
res.end("<html><body><h2>Login successful!</h2><p>You can close this tab and return to your terminal.</p></body></html>");
|
|
8538
8716
|
server.close();
|
|
8539
|
-
|
|
8717
|
+
resolve5({ code, port });
|
|
8540
8718
|
} else {
|
|
8541
8719
|
res.writeHead(400, { "Content-Type": "text/html" });
|
|
8542
8720
|
res.end("<html><body><h2>Login failed</h2><p>No authorization code received</p></body></html>");
|
|
@@ -8701,10 +8879,10 @@ import * as readline2 from "readline";
|
|
|
8701
8879
|
function prompt2(question, defaultValue) {
|
|
8702
8880
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
8703
8881
|
const display = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
|
|
8704
|
-
return new Promise((
|
|
8882
|
+
return new Promise((resolve5) => {
|
|
8705
8883
|
rl.question(display, (answer) => {
|
|
8706
8884
|
rl.close();
|
|
8707
|
-
|
|
8885
|
+
resolve5(answer.trim() || defaultValue || "");
|
|
8708
8886
|
});
|
|
8709
8887
|
});
|
|
8710
8888
|
}
|
|
@@ -8822,8 +9000,8 @@ async function tryOpenBrowser(url) {
|
|
|
8822
9000
|
cmd = "xdg-open";
|
|
8823
9001
|
args2 = [url];
|
|
8824
9002
|
}
|
|
8825
|
-
return new Promise((
|
|
8826
|
-
execFile(cmd, args2, (err) =>
|
|
9003
|
+
return new Promise((resolve5) => {
|
|
9004
|
+
execFile(cmd, args2, (err) => resolve5(!err));
|
|
8827
9005
|
});
|
|
8828
9006
|
} catch {
|
|
8829
9007
|
return false;
|
|
@@ -11138,7 +11316,41 @@ var conversations_exports = {};
|
|
|
11138
11316
|
__export(conversations_exports, {
|
|
11139
11317
|
conversationsCommand: () => conversationsCommand
|
|
11140
11318
|
});
|
|
11319
|
+
function printConversationsHelp() {
|
|
11320
|
+
console.error(`
|
|
11321
|
+
wayai conversations \u2014 list conversations or inspect what an agent received
|
|
11322
|
+
|
|
11323
|
+
Usage:
|
|
11324
|
+
wayai conversations List conversations
|
|
11325
|
+
wayai conversations --status <agent|team|ended> Filter by status
|
|
11326
|
+
wayai conversations --period 7d Analytics-powered list
|
|
11327
|
+
wayai conversations --from <date> --to <date> List within a date range
|
|
11328
|
+
wayai conversations <conversation_id> Show detail + messages
|
|
11329
|
+
wayai conversations <conversation_id> observability List the LLM turns (per-message id, latency, tool_calls)
|
|
11330
|
+
wayai conversations <conversation_id> observability --message-id <id>
|
|
11331
|
+
Full record for one turn:
|
|
11332
|
+
resolved system prompt, the exact
|
|
11333
|
+
messages the model saw (rendered
|
|
11334
|
+
additional_context, injected
|
|
11335
|
+
timestamps, replayed history),
|
|
11336
|
+
completion, tool calls, tokens
|
|
11337
|
+
|
|
11338
|
+
Options:
|
|
11339
|
+
--message-id <id> Expand one turn (only with the \`observability\` subcommand)
|
|
11340
|
+
--limit <n> Max rows (list view)
|
|
11341
|
+
--offset <n> Skip rows (list view)
|
|
11342
|
+
--json Raw JSON output
|
|
11343
|
+
|
|
11344
|
+
The default text list omits message ids \u2014 use \`--json\` or the \`observability\`
|
|
11345
|
+
subcommand to discover them. \`observability\` is the answer to "the agent did X \u2014
|
|
11346
|
+
what did it ACTUALLY see?".
|
|
11347
|
+
`.trim());
|
|
11348
|
+
}
|
|
11141
11349
|
async function conversationsCommand(args2) {
|
|
11350
|
+
if (wantsHelp(args2)) {
|
|
11351
|
+
printConversationsHelp();
|
|
11352
|
+
return;
|
|
11353
|
+
}
|
|
11142
11354
|
const hubId = resolveActiveHubId(args2);
|
|
11143
11355
|
const { config, accessToken } = await requireAuth();
|
|
11144
11356
|
requireRepoConfig();
|
|
@@ -11908,7 +12120,7 @@ Timeout after ${timeoutSeconds}s. Session is still running.`);
|
|
|
11908
12120
|
console.log(`Check results: wayai eval-results --session ${sessionId}`);
|
|
11909
12121
|
}
|
|
11910
12122
|
function sleep(ms) {
|
|
11911
|
-
return new Promise((
|
|
12123
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
11912
12124
|
}
|
|
11913
12125
|
function extractApiMessage(err) {
|
|
11914
12126
|
if (err instanceof ApiError) {
|
|
@@ -12491,6 +12703,38 @@ function normalizeAuthType2(raw) {
|
|
|
12491
12703
|
function visibleLength2(s) {
|
|
12492
12704
|
return s.replace(INVISIBLE_NAME_CHARS2, "").length;
|
|
12493
12705
|
}
|
|
12706
|
+
function validateLaneReferences2(lanes, statuses) {
|
|
12707
|
+
const issues = [];
|
|
12708
|
+
if (!Array.isArray(statuses) || statuses.length === 0) return issues;
|
|
12709
|
+
const declared = new Set((Array.isArray(lanes) ? lanes : []).map((l) => l.slug).filter(Boolean));
|
|
12710
|
+
statuses.forEach((s, i) => {
|
|
12711
|
+
const lane = s.lane_slug;
|
|
12712
|
+
if (typeof lane !== "string" || lane.length === 0) return;
|
|
12713
|
+
const label = s.slug ? `"${s.slug}"` : `[${i}]`;
|
|
12714
|
+
if (s.isInitialStatus === true) {
|
|
12715
|
+
issues.push({
|
|
12716
|
+
path: [i, "lane_slug"],
|
|
12717
|
+
message: `kanban status ${label}: the initial status cannot belong to a lane (it is the shared entry point)`
|
|
12718
|
+
});
|
|
12719
|
+
return;
|
|
12720
|
+
}
|
|
12721
|
+
if (!declared.has(lane)) {
|
|
12722
|
+
issues.push({
|
|
12723
|
+
path: [i, "lane_slug"],
|
|
12724
|
+
message: `kanban status ${label}: lane_slug references unknown lane "${lane}"`
|
|
12725
|
+
});
|
|
12726
|
+
}
|
|
12727
|
+
});
|
|
12728
|
+
return issues;
|
|
12729
|
+
}
|
|
12730
|
+
function refineLaneReferences2(val, ctx) {
|
|
12731
|
+
const lanes = val.lanes;
|
|
12732
|
+
const statuses = val.kanban_statuses;
|
|
12733
|
+
if (lanes == null || statuses == null) return;
|
|
12734
|
+
for (const issue of validateLaneReferences2(lanes, statuses)) {
|
|
12735
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["kanban_statuses", ...issue.path], message: issue.message });
|
|
12736
|
+
}
|
|
12737
|
+
}
|
|
12494
12738
|
function containsKanbanPlaceholders2(value) {
|
|
12495
12739
|
if (value == null) return false;
|
|
12496
12740
|
const serialized = typeof value === "string" ? value : JSON.stringify(value);
|
|
@@ -12522,12 +12766,12 @@ function typeMatches2(typeField, allowed) {
|
|
|
12522
12766
|
if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
|
|
12523
12767
|
return false;
|
|
12524
12768
|
}
|
|
12525
|
-
function validateSchema2(schema,
|
|
12769
|
+
function validateSchema2(schema, path22, errors, opts = {}) {
|
|
12526
12770
|
if (typeof schema === "boolean") return;
|
|
12527
12771
|
const depth = opts.depth ?? 0;
|
|
12528
12772
|
if (depth > MAX_SCHEMA_DEPTH2) {
|
|
12529
12773
|
errors.push({
|
|
12530
|
-
path:
|
|
12774
|
+
path: path22 || "<root>",
|
|
12531
12775
|
message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH2} levels`,
|
|
12532
12776
|
suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
|
|
12533
12777
|
});
|
|
@@ -12535,7 +12779,7 @@ function validateSchema2(schema, path19, errors, opts = {}) {
|
|
|
12535
12779
|
}
|
|
12536
12780
|
if (!isRecord2(schema)) {
|
|
12537
12781
|
errors.push({
|
|
12538
|
-
path:
|
|
12782
|
+
path: path22,
|
|
12539
12783
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
12540
12784
|
});
|
|
12541
12785
|
return;
|
|
@@ -12543,14 +12787,14 @@ function validateSchema2(schema, path19, errors, opts = {}) {
|
|
|
12543
12787
|
if (opts.isRoot) {
|
|
12544
12788
|
if ("type" in schema && schema.type !== "object") {
|
|
12545
12789
|
errors.push({
|
|
12546
|
-
path:
|
|
12790
|
+
path: path22 ? `${path22}.type` : "type",
|
|
12547
12791
|
message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
|
|
12548
12792
|
suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
|
|
12549
12793
|
});
|
|
12550
12794
|
}
|
|
12551
12795
|
} else if ("type" in schema && !typeMatches2(schema.type, ALLOWED_TYPES2)) {
|
|
12552
12796
|
errors.push({
|
|
12553
|
-
path: `${
|
|
12797
|
+
path: `${path22}.type`,
|
|
12554
12798
|
message: `type must be one of ${[...ALLOWED_TYPES2].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
|
|
12555
12799
|
});
|
|
12556
12800
|
}
|
|
@@ -12559,25 +12803,25 @@ function validateSchema2(schema, path19, errors, opts = {}) {
|
|
|
12559
12803
|
if (typeof e === "string") {
|
|
12560
12804
|
const isPlaceholder = PLACEHOLDER_TOKENS2.includes(e);
|
|
12561
12805
|
errors.push({
|
|
12562
|
-
path: `${
|
|
12806
|
+
path: `${path22}.enum`,
|
|
12563
12807
|
message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
|
|
12564
12808
|
suggestion: isPlaceholder ? "Set `operation: 'update_kanban_status'` on the tool and ensure at least one hub.kanban_status has `allowsAgentUpdate: true` so the platform can render the placeholder into a valid array." : 'Wrap the value in an array: `enum: ["value"]`.'
|
|
12565
12809
|
});
|
|
12566
12810
|
} else if (!Array.isArray(e)) {
|
|
12567
12811
|
errors.push({
|
|
12568
|
-
path: `${
|
|
12812
|
+
path: `${path22}.enum`,
|
|
12569
12813
|
message: `enum must be a non-empty array of primitives, got ${typeof e}`
|
|
12570
12814
|
});
|
|
12571
12815
|
} else if (e.length === 0) {
|
|
12572
12816
|
errors.push({
|
|
12573
|
-
path: `${
|
|
12817
|
+
path: `${path22}.enum`,
|
|
12574
12818
|
message: "enum must not be empty"
|
|
12575
12819
|
});
|
|
12576
12820
|
} else {
|
|
12577
12821
|
for (let i = 0; i < e.length; i++) {
|
|
12578
12822
|
if (!isPrimitive2(e[i])) {
|
|
12579
12823
|
errors.push({
|
|
12580
|
-
path: `${
|
|
12824
|
+
path: `${path22}.enum[${i}]`,
|
|
12581
12825
|
message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
|
|
12582
12826
|
});
|
|
12583
12827
|
}
|
|
@@ -12587,7 +12831,7 @@ function validateSchema2(schema, path19, errors, opts = {}) {
|
|
|
12587
12831
|
for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
|
|
12588
12832
|
if (key in schema && typeof schema[key] === "boolean") {
|
|
12589
12833
|
errors.push({
|
|
12590
|
-
path: `${
|
|
12834
|
+
path: `${path22}.${key}`,
|
|
12591
12835
|
message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
|
|
12592
12836
|
suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
|
|
12593
12837
|
});
|
|
@@ -12596,45 +12840,45 @@ function validateSchema2(schema, path19, errors, opts = {}) {
|
|
|
12596
12840
|
if ("properties" in schema) {
|
|
12597
12841
|
if (!isRecord2(schema.properties)) {
|
|
12598
12842
|
errors.push({
|
|
12599
|
-
path: `${
|
|
12843
|
+
path: `${path22}.properties`,
|
|
12600
12844
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
12601
12845
|
});
|
|
12602
12846
|
} else {
|
|
12603
12847
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
12604
|
-
validateSchema2(propSchema, `${
|
|
12848
|
+
validateSchema2(propSchema, `${path22}.properties.${propName}`, errors, { depth: depth + 1 });
|
|
12605
12849
|
}
|
|
12606
12850
|
}
|
|
12607
12851
|
}
|
|
12608
12852
|
if (schemaTypeIncludes2(schema, "array") && "items" in schema) {
|
|
12609
12853
|
if (Array.isArray(schema.items)) {
|
|
12610
|
-
schema.items.forEach((sub, i) => validateSchema2(sub, `${
|
|
12854
|
+
schema.items.forEach((sub, i) => validateSchema2(sub, `${path22}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
12611
12855
|
} else {
|
|
12612
|
-
validateSchema2(schema.items, `${
|
|
12856
|
+
validateSchema2(schema.items, `${path22}.items`, errors, { depth: depth + 1 });
|
|
12613
12857
|
}
|
|
12614
12858
|
}
|
|
12615
12859
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS2) {
|
|
12616
12860
|
if (key in schema && isRecord2(schema[key])) {
|
|
12617
|
-
validateSchema2(schema[key], `${
|
|
12861
|
+
validateSchema2(schema[key], `${path22}.${key}`, errors, { depth: depth + 1 });
|
|
12618
12862
|
}
|
|
12619
12863
|
}
|
|
12620
12864
|
for (const key of SUBSCHEMA_LIST_KEYWORDS2) {
|
|
12621
12865
|
const list = schema[key];
|
|
12622
12866
|
if (Array.isArray(list)) {
|
|
12623
|
-
list.forEach((sub, i) => validateSchema2(sub, `${
|
|
12867
|
+
list.forEach((sub, i) => validateSchema2(sub, `${path22}.${key}[${i}]`, errors, { depth: depth + 1 }));
|
|
12624
12868
|
}
|
|
12625
12869
|
}
|
|
12626
12870
|
for (const key of SUBSCHEMA_MAP_KEYWORDS2) {
|
|
12627
12871
|
const map = schema[key];
|
|
12628
12872
|
if (isRecord2(map)) {
|
|
12629
12873
|
for (const [name, sub] of Object.entries(map)) {
|
|
12630
|
-
validateSchema2(sub, `${
|
|
12874
|
+
validateSchema2(sub, `${path22}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
12631
12875
|
}
|
|
12632
12876
|
}
|
|
12633
12877
|
}
|
|
12634
12878
|
const reportedPaths = new Set(errors.map((e) => e.path));
|
|
12635
12879
|
for (const [k, v] of Object.entries(schema)) {
|
|
12636
12880
|
if (typeof v !== "string") continue;
|
|
12637
|
-
const fieldPath = `${
|
|
12881
|
+
const fieldPath = `${path22}.${k}`;
|
|
12638
12882
|
if (reportedPaths.has(fieldPath)) continue;
|
|
12639
12883
|
for (const token of PLACEHOLDER_TOKENS2) {
|
|
12640
12884
|
if (v === token) {
|
|
@@ -12767,7 +13011,38 @@ function refineHubAsCodeKanbanStatuses2(config, ctx) {
|
|
|
12767
13011
|
}
|
|
12768
13012
|
}
|
|
12769
13013
|
}
|
|
12770
|
-
|
|
13014
|
+
function refineHubAsCodeLanes2(config, ctx) {
|
|
13015
|
+
const hub = config.hub;
|
|
13016
|
+
if (hub == null) return;
|
|
13017
|
+
if ("lanes" in hub && hub.lanes != null) {
|
|
13018
|
+
if (!Array.isArray(hub.lanes)) {
|
|
13019
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["hub", "lanes"], message: "lanes must be an array" });
|
|
13020
|
+
return;
|
|
13021
|
+
}
|
|
13022
|
+
const result = lanesArraySchema2.safeParse(hub.lanes);
|
|
13023
|
+
if (!result.success) {
|
|
13024
|
+
for (const issue of result.error.issues) {
|
|
13025
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["hub", "lanes", ...issue.path], message: issue.message });
|
|
13026
|
+
}
|
|
13027
|
+
return;
|
|
13028
|
+
}
|
|
13029
|
+
}
|
|
13030
|
+
const statuses = hub.kanban_statuses;
|
|
13031
|
+
if (Array.isArray(statuses)) {
|
|
13032
|
+
for (const issue of validateLaneReferences2(hub.lanes, statuses)) {
|
|
13033
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["hub", "kanban_statuses", ...issue.path], message: issue.message });
|
|
13034
|
+
}
|
|
13035
|
+
}
|
|
13036
|
+
}
|
|
13037
|
+
function isSafeTemplatePath2(path22) {
|
|
13038
|
+
if (path22.length === 0 || path22.length > 300) return false;
|
|
13039
|
+
if (path22.startsWith("/") || path22.includes("\\")) return false;
|
|
13040
|
+
const segments = path22.split("/");
|
|
13041
|
+
return segments.every(
|
|
13042
|
+
(seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
|
|
13043
|
+
);
|
|
13044
|
+
}
|
|
13045
|
+
var uuidSchema2, paginationSchema3, timestampSchema2, idParamSchema2, primaryRegionSchema2, placementSourceSchema2, orgIdParam2, orgAdminIdParam2, createOrganizationBody2, updateOrganizationBody2, addOrgAdminBody2, AUTH_TYPE2, ORG_CREDENTIAL_AUTH_TYPES2, AUTH_TYPE_DISPLAY2, LEGACY_AUTH_TYPE_MAP2, VALID_AUTH_TYPES2, AGENT_ROLES2, SAFE_USER_ID_REGEX2, SUMMARIZATION_THRESHOLD_MIN2, SUMMARIZATION_THRESHOLD_MAX2, summarizationThresholdField2, monitorConfigField2, agentIdParam2, listAgentsQuery2, agentConnectionsQuery2, createAgentBody2, updateAgentBody2, AGENT_PARAMETER_TYPES2, AGENT_PARAMETER_NAME_REGEX2, agentParameterCreateSchema2, MAX_AGENT_PARAMETERS_PER_REQUEST2, createAgentParametersBody2, SLUG_REGEX2, slugSchema2, INVISIBLE_NAME_CHARS2, MAX_KANBAN_STATUSES2, MAX_FOLLOWUPS_PER_STATUS2, MAX_LANES2, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES2, RESERVED_TEMPLATE_DUMP_NAME2, kanbanStatusSlugSchema2, followupSchema2, EXCLUSIVE_FLAG_PAIRS2, kanbanStatusSchema2, kanbanStatusesArraySchema2, laneSchema2, lanesArraySchema2, hubIdParam2, hubAdminIdParam2, hubUserIdParam2, hubIdentityIdParam2, hubTeamIdParam2, hubTeamUserDeleteParam2, hubSchemaQuery2, createHubBody2, updateHubBody2, addHubAdminBody2, addHubIdentityAuthorizationBody2, contactDecisionBody2, approveContactBody2, listContactAccessQuery2, createHubTeamBody2, updateHubTeamBody2, addHubTeamUserBody2, reassignHubUserBody2, replicatePreviewBody2, claimCodeChannelParam2, claimCodeDeleteParam2, connectionIdParam2, connectorIdParam2, listConnectionsQuery2, deleteConnectionQuery2, addConnectionBody2, editConnectionBody2, registerWhatsappQuery2, registerWhatsappBody2, retryProvisioningQuery2, resendDomainStatusQuery2, PLACEHOLDER_TOKENS2, ALLOWED_TYPES2, SUBSCHEMA_OBJECT_KEYWORDS2, SUBSCHEMA_LIST_KEYWORDS2, SUBSCHEMA_MAP_KEYWORDS2, MAX_SCHEMA_DEPTH2, toolIdParam2, listToolsQuery2, toolAgentQuery2, deleteToolQuery2, toolConnectionsQuery2, nativeToolIdSchema2, addNativeToolBody2, addMcpToolBody2, createCustomToolBody2, updateCustomToolBody2, updateToolExecutionConfigBody2, initialValueCreateSchema2, initialValueUpdateSchema2, stateIdParam2, listStatesQuery2, stateNameSchema2, createStateBody2, updateStateBody2, reorderStatesBody2, orgTagIdParam2, listOrgTagsQuery2, createOrgTagBody2, updateOrgTagBody2, orgCredentialIdParam2, listOrgCredentialsQuery2, createOrgCredentialBody2, updateOrgCredentialBody2, orgResourceIdParam2, orgResourceFileIdParam2, orgResourceFolderIdParam2, hubOrgResourceParam2, listOrgResourcesQuery2, orgIdQuery2, createOrgResourceBody2, updateOrgResourceBody2, createOrgResourceFolderBody2, updateOrgResourceFolderBody2, uploadOrgResourceFileBody2, updateOrgResourceFileBody2, uploadOrgSkillZipBody2, linkOrgResourceBody2, resourceIdParam2, listResourcesQuery2, createResourceBody2, updateResourceBody2, syncSkillsBody2, resourceFileIdParam2, listResourceFilesQuery2, createResourceFileBody2, updateResourceFileBody2, uploadResourceFileBody2, uploadSkillZipBody2, resourceFolderIdParam2, listResourceFoldersQuery2, createResourceFolderBody2, updateResourceFolderBody2, agentResourceQuery2, hubResourceQuery2, linkAgentResourceBody2, updateAgentResourceBody2, unlinkAgentResourceQuery2, navItemSchema2, hubCountResetBody2, navItemCountResetBody2, typingBody2, analyticsHubIdParam2, analyticsVariableIdParam2, updateVariablePinBody2, updateAnalyticsViewBody2, NUMERIC_FILTER_OPS2, TEXT_FILTER_OPS2, CATEGORICAL_FILTER_OPS2, VARIABLE_FILTER_OPS2, STRUCTURED_QUERY_OPS2, STRUCTURED_QUERY_AGGREGATIONS2, filterValueSchema2, conversationsBody2, analyticsConversationIdParam2, messagesQuery2, conversationDetailDataQuery2, analyticsDataBody2, structuredQueryBody2, analyticsSqlBody2, analyticsSqlSchemaQuery2, PACING_INTERVAL_MIN_MS2, PACING_INTERVAL_MAX_MS2, EVAL_RUN_DEADLINE_MIN_MS2, EVAL_RUN_DEADLINE_MAX_MS2, paginationSchema22, evalIdParam2, sessionIdParam2, scenarioSetIdParam2, hubIdQuery2, createEvalBody2, updateEvalBody2, getEvalsQuery2, toggleEvalBody2, bulkToggleEvalsBody2, pacingConfigSchema2, sessionConfigSchema2, createSessionBody2, getSessionsQuery2, getSessionResultsQuery2, getSessionRunsQuery2, evalAnalyticsQuery2, getSessionCostQuery2, compareSessionsQuery2, evalsSqlBody2, evalsSqlSchemaQuery2, exportResultsQuery2, validateEvalBody2, hubAgentsQuery2, createScenarioSetBody2, updateScenarioSetBody2, scenarioSetsHubQuery2, createScenarioFromConversationBody2, createJourneyFromConversationBody2, journeyIdParam2, journeyToolCallSchema2, journeyTurnSchema2, journeyStepOverrideSchema2, createJourneyBody2, updateJourneyBody2, getConversationsQuery2, getMessagesQuery2, updateUserBody2, updateProfileBody2, pathnameRegex2, updatePreferencesBody2, registerPushTokenBody2, deletePushTokenQuery2, activityQuery2, deletionModeSchema2, deletionRequestBody2, archiveHubIdParam2, archiveConversationParams2, archiveListQuery2, archiveMessageObservabilityParams2, conversationIdParam2, claimBody2, releaseBody2, transferBody2, closeBody2, additionalContextPayloadSchema2, kanbanUpdateBody2, observabilityParams2, observabilityListParams2, deleteUserConversationsBody2, sendMessageBody2, listConversationsQuery2, getConversationDetailParams2, getConversationDetailQuery2, listWhatsAppTemplatesQuery2, sendWhatsAppTemplateBody2, billingOrgIdParam2, subscriptionItemParams2, spendCapBody2, growthPacksBody2, portalSessionBody2, checkoutSessionBody2, updateBillingCurrencyBody2, invoicesQuery2, downloadBody2, uploadQuery2, signUrlBody2, completionsBody2, outboundSchemaQuery2, templateIdParam2, listTemplatesQuery2, deleteTemplateQuery2, templateStatusQuery2, createTemplateBody2, updateTemplateBody2, submitTemplateBody2, testTemplateBody2, contactIdParam2, listContactsQuery2, createContactBody2, updateContactBody2, listIdParam2, listListsQuery2, listListContactsQuery2, createListBody2, updateListBody2, addListContactsBody2, removeListContactsBody2, scheduleIdParam2, listSchedulesQuery2, listExecutionsQuery2, createScheduleBody2, updateScheduleBody2, uuidPattern2, ciUuidSchema2, hubAsCodeConfigSchema2, ciPullHubIdParam2, ciBranchParam2, ciPullQuery2, ciHubsQuery2, ciLookupQuery2, ciBranchesQuery2, ciSyncBody2, ciPushBody2, ciDiffBody2, ciPublishBody2, ciPublishPreviewBody2, ciSyncMcpBody2, ciOrgResourcesParam2, orgResourcesConfigSchema2, ciOrgResourcesPushBody2, ciOrgResourcesDiffBody2, adminOrgIdParam2, adminOrgAdminIdParam2, adminUserIdParam2, adminPlanIdParam2, adminOrganizationsQuery2, adminUserSearchQuery2, kanbanSlugMigrationQuery2, adjustQuotaBody2, updatePlanBody2, addAdminUserBody2, updatePlatformConfigBody2, updateFreeOrgLimitBody2, updatePricingPlanBody2, dataExplorerSearchQuery2, dataExplorerOrgIdParam2, dataExplorerHubIdParam2, dataExplorerConvIdParam2, dataExplorerDoInstancesQuery2, dataExplorerNsIdParam2, dataExplorerKvKeysQuery2, dataExplorerKvKeyParam2, uuidOrHexId2, dataExplorerDeleteOrgParam2, dataExplorerDeleteHubParam2, dataExplorerDeleteConvParam2, dataExplorerDeleteUserParam2, dataExplorerDeleteQuery2, dataExplorerKvDeleteQuery2, pitrDoNamespace2, pitrBookmarkParam2, pitrRestoreBody2, healthSamplingTriggerBody2, dataExplorerDebugDoType2, DEBUG_READ_MAX_LIMIT2, DEBUG_READ_DEFAULT_LIMIT2, DEBUG_DO_HEX_PREFIX2, debugDoEntityId2, debugTableName2, dataExplorerDebugTablesParam2, dataExplorerDebugRowsParam2, dataExplorerDebugRowsQuery2, dataExplorerDebugAnalyticsTable2, debugUuid2, dataExplorerDebugAnalyticsRowsParam2, dataExplorerDebugAnalyticsRowsQuery2, debugHubConvParam2, debugMessageIdQuery2, whatsappCallbackBody2, authMeResponse2, wsTicketResponse2, sessionCheckResponse2, logoutResponse2, magicCodeSendBody2, magicCodeSendResponse2, magicCodeVerifyBody2, magicCodeVerifyResponse2, browserParams2, browserFoldersQuery2, browserFilesQuery2, stateOperationBody2, conversationListResourcesQuery2, conversationReadResourceQuery2, listPendingSchedulesQuery2, listHubAggregateSchedulesQuery2, reportSourceSchema2, intakeReportSourceSchema2, reportClassificationSchema2, reportStatusSchema2, reportLocaleSchema2, reportMessageAuthorRoleSchema2, sentryRefStatusSchema2, createReportBody2, editReportBody2, contestReportBody2, reporterListQuery2, listReportsQuery2, GITHUB_ISSUE_URL_REGEX2, githubIssueUrlSchema2, transitionReportBody2, groupReportsBody2, holdReportBody2, clickhouseReadyResponse2, bootstrapQuery2, requestSnapshotChunkMessage2, MAX_NAME_LENGTH3, MAX_VALUE_LENGTH2, MAX_TAGS2, MAX_TAG_LENGTH2, MAX_SCOPE_HUBS2, MAX_SCOPE_TAGS2, vaultSecretScopeSchema2, vaultCreateBody2, vaultUpdateBody2, PERMISSIONS2, MAX_NAME_LENGTH22, MAX_HUBS_PER_GRANT2, MAX_HUB_TAGS_PER_GRANT2, MAX_GRANTS2, permissionEnum2, grantScopeSchema2, grantSchema2, createTokenBody2, tokenOrgIdParam2, tokenGrantScopeSchema2, tokenGrantSchema2, tokenMetadataSchema2, listTokensResponse2, createTokenResponse2, orgTokenSummarySchema2, listOrgTokensResponse2, invitePreviewQuery2, invitePreviewResponse2, discordTier2, discordBillingCycle2, discordMetadata2, discordOAuthStartResponse2, discordOAuthFinalizeBody2, discordOAuthFinalizeResponse2, discordDisconnectResponse2, jsonSchemaSchema2, hubUserIdentity2, stateValueEntry2, getHubUserContextResponse2, updateHubUserBody2, updateHubUserResponse2, unlockHubUserNameResponse2, stateResetParams2, stateResetResponse2, hubAlertsParam2, hubAlertSeverity2, hubAlert2, hubAlertsListResponse2, noticeSeveritySchema2, noticeStatusSchema2, NOTICE_SCOPE_REGEX2, noticeScopeSchema2, noticeLinkSchema2, createNoticeBody2, updateNoticeBody2, listNoticesQuery2, noticeIdParamSchema2, TEMPLATE_SLUG_REGEX2, templateSlugSchema2, templateStatusSchema2, templateFileMapSchema2, templateWayaiBlockSchema2, templateRekorBlockSchema2, templateYamlWayaiBlock2, templateYamlRekorBlock2, templateYamlSchema2, templatePushMetadataSchema2, templateHeroSchema2, templatePushBody2, templateSlugParam2;
|
|
12771
13046
|
var init_contracts = __esm({
|
|
12772
13047
|
"../../packages/core/dist/contracts/index.js"() {
|
|
12773
13048
|
"use strict";
|
|
@@ -12815,6 +13090,7 @@ var init_contracts = __esm({
|
|
|
12815
13090
|
init_zod();
|
|
12816
13091
|
init_zod();
|
|
12817
13092
|
init_zod();
|
|
13093
|
+
init_zod();
|
|
12818
13094
|
uuidSchema2 = external_exports.string().uuid();
|
|
12819
13095
|
paginationSchema3 = external_exports.object({
|
|
12820
13096
|
limit: external_exports.coerce.number().int().min(1).max(100).default(50),
|
|
@@ -12976,6 +13252,7 @@ var init_contracts = __esm({
|
|
|
12976
13252
|
INVISIBLE_NAME_CHARS2 = /[\s\p{Default_Ignorable_Code_Point}]/gu;
|
|
12977
13253
|
MAX_KANBAN_STATUSES2 = 50;
|
|
12978
13254
|
MAX_FOLLOWUPS_PER_STATUS2 = 20;
|
|
13255
|
+
MAX_LANES2 = 20;
|
|
12979
13256
|
MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES2 = 16384;
|
|
12980
13257
|
RESERVED_TEMPLATE_DUMP_NAME2 = "additional_data";
|
|
12981
13258
|
kanbanStatusSlugSchema2 = slugSchema2;
|
|
@@ -13032,7 +13309,14 @@ var init_contracts = __esm({
|
|
|
13032
13309
|
/** Slugs this status may transition to. `undefined` = unrestricted (any
|
|
13033
13310
|
* next status). Empty array `[]` is rejected — author must use
|
|
13034
13311
|
* `isTerminalStatus: true` to express "no outbound transitions". */
|
|
13035
|
-
allowed_next_statuses: external_exports.array(external_exports.string()).min(1, "allowed_next_statuses cannot be empty \u2014 use isTerminalStatus: true for no outbound transitions").optional()
|
|
13312
|
+
allowed_next_statuses: external_exports.array(external_exports.string()).min(1, "allowed_next_statuses cannot be empty \u2014 use isTerminalStatus: true for no outbound transitions").optional(),
|
|
13313
|
+
/** Optional presentational grouping — the slug of a hub `lanes[]` entry this
|
|
13314
|
+
* status belongs to. `undefined` = ungrouped. Purely a board-filter/organization
|
|
13315
|
+
* concept; it does NOT constrain transitions (those live in `allowed_next_statuses`)
|
|
13316
|
+
* and is not exposed to agents. The cross-reference invariant (must point at a
|
|
13317
|
+
* declared lane; the initial status must not have one) is enforced at the hub
|
|
13318
|
+
* level via `validateLaneReferences` — this schema only sees the status array. */
|
|
13319
|
+
lane_slug: kanbanStatusSlugSchema2.optional()
|
|
13036
13320
|
}).passthrough().superRefine((status, ctx) => {
|
|
13037
13321
|
const label = status.name ? `"${status.name}"` : status.slug ? `"${status.slug}"` : "<unnamed>";
|
|
13038
13322
|
for (const [a, b] of EXCLUSIVE_FLAG_PAIRS2) {
|
|
@@ -13123,6 +13407,28 @@ var init_contracts = __esm({
|
|
|
13123
13407
|
});
|
|
13124
13408
|
});
|
|
13125
13409
|
});
|
|
13410
|
+
laneSchema2 = external_exports.object({
|
|
13411
|
+
slug: kanbanStatusSlugSchema2,
|
|
13412
|
+
name: external_exports.string().min(1, "name is required").max(100, "name must be 100 characters or fewer").refine((v) => visibleLength2(v) > 0, "name must not be blank"),
|
|
13413
|
+
color: external_exports.string().optional(),
|
|
13414
|
+
order: external_exports.number().int().nonnegative().optional()
|
|
13415
|
+
}).passthrough();
|
|
13416
|
+
lanesArraySchema2 = external_exports.array(laneSchema2).max(MAX_LANES2, `lanes must have at most ${MAX_LANES2} entries`).superRefine((lanes, ctx) => {
|
|
13417
|
+
const seen = /* @__PURE__ */ new Map();
|
|
13418
|
+
lanes.forEach((l, i) => {
|
|
13419
|
+
if (!l.slug) return;
|
|
13420
|
+
const arr = seen.get(l.slug) ?? [];
|
|
13421
|
+
arr.push(i);
|
|
13422
|
+
seen.set(l.slug, arr);
|
|
13423
|
+
});
|
|
13424
|
+
for (const [slug, indices] of seen) {
|
|
13425
|
+
if (indices.length > 1) {
|
|
13426
|
+
for (const i of indices) {
|
|
13427
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: [i, "slug"], message: `lanes: duplicate slug "${slug}"` });
|
|
13428
|
+
}
|
|
13429
|
+
}
|
|
13430
|
+
}
|
|
13431
|
+
});
|
|
13126
13432
|
hubIdParam2 = external_exports.object({ id: uuidSchema2 });
|
|
13127
13433
|
hubAdminIdParam2 = external_exports.object({ id: uuidSchema2, adminId: uuidSchema2 });
|
|
13128
13434
|
hubUserIdParam2 = external_exports.object({ id: uuidSchema2, hubUserId: uuidSchema2 });
|
|
@@ -13135,14 +13441,16 @@ var init_contracts = __esm({
|
|
|
13135
13441
|
hub_name: external_exports.string().min(1, "hub_name is required"),
|
|
13136
13442
|
hub_description: external_exports.string().optional(),
|
|
13137
13443
|
kanban_statuses: kanbanStatusesArraySchema2.nullable().optional(),
|
|
13444
|
+
lanes: lanesArraySchema2.nullable().optional(),
|
|
13138
13445
|
// Write-once at creation; updateHubBody does not accept this.
|
|
13139
13446
|
primary_region: primaryRegionSchema2.optional()
|
|
13140
|
-
}).passthrough();
|
|
13447
|
+
}).passthrough().superRefine(refineLaneReferences2);
|
|
13141
13448
|
updateHubBody2 = external_exports.object({
|
|
13142
13449
|
support_model: external_exports.enum(["conversation", "account"]).optional(),
|
|
13143
13450
|
unassigned_policy: external_exports.enum(["default_team", "auto_assign_random", "auto_assign_round_robin", "pull_queue"]).optional(),
|
|
13144
13451
|
default_hub_team_id: uuidSchema2.nullable().optional(),
|
|
13145
13452
|
kanban_statuses: kanbanStatusesArraySchema2.nullable().optional(),
|
|
13453
|
+
lanes: lanesArraySchema2.nullable().optional(),
|
|
13146
13454
|
// summarization_threshold_tokens relocated to the summarizer AGENT (PR4) — validated/
|
|
13147
13455
|
// persisted via the agent path (.passthrough() agent body → HubDO column), not here.
|
|
13148
13456
|
auto_close_inactive_days: external_exports.number().int().min(1).max(180).optional(),
|
|
@@ -13151,7 +13459,7 @@ var init_contracts = __esm({
|
|
|
13151
13459
|
language: external_exports.enum(["en", "pt", "es"]).optional(),
|
|
13152
13460
|
access_request_message: external_exports.string().max(1e3).nullable().optional(),
|
|
13153
13461
|
access_approval_role: external_exports.enum(["admin", "team"]).optional()
|
|
13154
|
-
}).passthrough();
|
|
13462
|
+
}).passthrough().superRefine(refineLaneReferences2);
|
|
13155
13463
|
addHubAdminBody2 = external_exports.object({
|
|
13156
13464
|
user_email: external_exports.string().email("valid email is required")
|
|
13157
13465
|
});
|
|
@@ -14327,6 +14635,7 @@ var init_contracts = __esm({
|
|
|
14327
14635
|
}).passthrough().superRefine((config, ctx) => {
|
|
14328
14636
|
refineHubAsCodeCustomTools2(config, ctx);
|
|
14329
14637
|
refineHubAsCodeKanbanStatuses2(config, ctx);
|
|
14638
|
+
refineHubAsCodeLanes2(config, ctx);
|
|
14330
14639
|
});
|
|
14331
14640
|
ciPullHubIdParam2 = external_exports.object({
|
|
14332
14641
|
hub_id: ciUuidSchema2
|
|
@@ -14998,6 +15307,62 @@ var init_contracts = __esm({
|
|
|
14998
15307
|
offset: external_exports.coerce.number().int().min(0).optional()
|
|
14999
15308
|
});
|
|
15000
15309
|
noticeIdParamSchema2 = external_exports.object({ id: external_exports.string().min(1) });
|
|
15310
|
+
TEMPLATE_SLUG_REGEX2 = /^[a-z0-9][a-z0-9-]{0,62}$/;
|
|
15311
|
+
templateSlugSchema2 = external_exports.string().regex(TEMPLATE_SLUG_REGEX2, "slug must be lowercase alphanumeric with hyphens (max 63)");
|
|
15312
|
+
templateStatusSchema2 = external_exports.enum(["published", "draft", "internal"]);
|
|
15313
|
+
templateFileMapSchema2 = external_exports.record(external_exports.string()).refine((m) => Object.keys(m).every(isSafeTemplatePath2), {
|
|
15314
|
+
message: 'file map contains an unsafe path (no absolute paths, "..", or backslashes)'
|
|
15315
|
+
});
|
|
15316
|
+
templateWayaiBlockSchema2 = external_exports.object({
|
|
15317
|
+
metaTitle: external_exports.string().min(1).max(200),
|
|
15318
|
+
metaDescription: external_exports.string().max(1e3).default(""),
|
|
15319
|
+
installCommand: external_exports.string().min(1).max(300)
|
|
15320
|
+
});
|
|
15321
|
+
templateRekorBlockSchema2 = templateWayaiBlockSchema2.extend({
|
|
15322
|
+
mcpEndpoint: external_exports.string().url().optional(),
|
|
15323
|
+
url: external_exports.string().url().optional()
|
|
15324
|
+
});
|
|
15325
|
+
templateYamlWayaiBlock2 = templateWayaiBlockSchema2.extend({
|
|
15326
|
+
source: external_exports.string().min(1)
|
|
15327
|
+
});
|
|
15328
|
+
templateYamlRekorBlock2 = templateRekorBlockSchema2.extend({
|
|
15329
|
+
source: external_exports.string().min(1)
|
|
15330
|
+
});
|
|
15331
|
+
templateYamlSchema2 = external_exports.object({
|
|
15332
|
+
slug: templateSlugSchema2,
|
|
15333
|
+
category: external_exports.string().min(1).max(60),
|
|
15334
|
+
status: templateStatusSchema2.default("draft"),
|
|
15335
|
+
order: external_exports.number().int().min(0).max(1e5).optional(),
|
|
15336
|
+
hero: external_exports.string().optional(),
|
|
15337
|
+
// relative path to a hero image inside the template folder
|
|
15338
|
+
wayai: templateYamlWayaiBlock2.optional(),
|
|
15339
|
+
rekor: templateYamlRekorBlock2.optional()
|
|
15340
|
+
}).refine((c) => Boolean(c.wayai) || Boolean(c.rekor), {
|
|
15341
|
+
message: "template.yaml must define at least one of `wayai:` or `rekor:`"
|
|
15342
|
+
});
|
|
15343
|
+
templatePushMetadataSchema2 = external_exports.object({
|
|
15344
|
+
category: external_exports.string().min(1).max(60),
|
|
15345
|
+
status: templateStatusSchema2,
|
|
15346
|
+
order: external_exports.number().int().min(0).max(1e5).default(0),
|
|
15347
|
+
wayai: templateWayaiBlockSchema2.optional(),
|
|
15348
|
+
rekor: templateRekorBlockSchema2.optional()
|
|
15349
|
+
});
|
|
15350
|
+
templateHeroSchema2 = external_exports.object({
|
|
15351
|
+
filename: external_exports.string().min(1).max(200).regex(/\.(png|jpe?g|webp|gif)$/i, "hero must be a raster image (png/jpg/webp/gif)"),
|
|
15352
|
+
// ~8MB of base64 ≈ a ~6MB image — a generous cap that bounds the inline payload
|
|
15353
|
+
// (the endpoint is platform-admin-only, but an unbounded blob is still avoidable).
|
|
15354
|
+
dataBase64: external_exports.string().min(1).max(8e6)
|
|
15355
|
+
});
|
|
15356
|
+
templatePushBody2 = external_exports.object({
|
|
15357
|
+
slug: templateSlugSchema2,
|
|
15358
|
+
metadata: templatePushMetadataSchema2,
|
|
15359
|
+
// wayai slice file-map (path -> body); ABSENT for a Rekor-only template.
|
|
15360
|
+
wayaiFiles: templateFileMapSchema2.optional(),
|
|
15361
|
+
// raw README markdown; the backend renders + sanitizes (single authority).
|
|
15362
|
+
readmeMarkdown: external_exports.string().default(""),
|
|
15363
|
+
hero: templateHeroSchema2.optional()
|
|
15364
|
+
});
|
|
15365
|
+
templateSlugParam2 = external_exports.object({ slug: templateSlugSchema2 });
|
|
15001
15366
|
}
|
|
15002
15367
|
});
|
|
15003
15368
|
|
|
@@ -16191,6 +16556,171 @@ var init_list = __esm({
|
|
|
16191
16556
|
}
|
|
16192
16557
|
});
|
|
16193
16558
|
|
|
16559
|
+
// src/lib/template-files.ts
|
|
16560
|
+
import * as fs16 from "fs";
|
|
16561
|
+
import * as path19 from "path";
|
|
16562
|
+
function readDirToFileMap(rootDir) {
|
|
16563
|
+
const out = {};
|
|
16564
|
+
function walk(dir, prefix) {
|
|
16565
|
+
for (const entry of fs16.readdirSync(dir, { withFileTypes: true })) {
|
|
16566
|
+
const abs = path19.join(dir, entry.name);
|
|
16567
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
16568
|
+
if (entry.isDirectory()) walk(abs, rel);
|
|
16569
|
+
else if (entry.isFile()) out[rel] = fs16.readFileSync(abs, "utf-8");
|
|
16570
|
+
}
|
|
16571
|
+
}
|
|
16572
|
+
if (fs16.existsSync(rootDir)) walk(rootDir, "");
|
|
16573
|
+
return out;
|
|
16574
|
+
}
|
|
16575
|
+
function writeFileMap(targetDir, files) {
|
|
16576
|
+
const written = [];
|
|
16577
|
+
for (const [rel, body] of Object.entries(files)) {
|
|
16578
|
+
if (!isSafeTemplatePath2(rel)) {
|
|
16579
|
+
throw new Error(`Refusing to write unsafe template path: ${rel}`);
|
|
16580
|
+
}
|
|
16581
|
+
const abs = path19.join(targetDir, rel);
|
|
16582
|
+
fs16.mkdirSync(path19.dirname(abs), { recursive: true });
|
|
16583
|
+
fs16.writeFileSync(abs, body, "utf-8");
|
|
16584
|
+
written.push(rel);
|
|
16585
|
+
}
|
|
16586
|
+
return written;
|
|
16587
|
+
}
|
|
16588
|
+
var init_template_files = __esm({
|
|
16589
|
+
"src/lib/template-files.ts"() {
|
|
16590
|
+
"use strict";
|
|
16591
|
+
init_contracts();
|
|
16592
|
+
}
|
|
16593
|
+
});
|
|
16594
|
+
|
|
16595
|
+
// src/commands/templates.ts
|
|
16596
|
+
var templates_exports = {};
|
|
16597
|
+
__export(templates_exports, {
|
|
16598
|
+
templateCommand: () => templateCommand
|
|
16599
|
+
});
|
|
16600
|
+
import * as path20 from "path";
|
|
16601
|
+
async function templateCommand(args2) {
|
|
16602
|
+
const [sub, ...rest] = args2;
|
|
16603
|
+
switch (sub) {
|
|
16604
|
+
case "list":
|
|
16605
|
+
await runTemplateList();
|
|
16606
|
+
return;
|
|
16607
|
+
case "pull":
|
|
16608
|
+
await runTemplatePull(rest);
|
|
16609
|
+
return;
|
|
16610
|
+
case void 0:
|
|
16611
|
+
case "help":
|
|
16612
|
+
case "--help":
|
|
16613
|
+
case "-h":
|
|
16614
|
+
printTemplateHelp();
|
|
16615
|
+
return;
|
|
16616
|
+
default:
|
|
16617
|
+
console.error(`Unknown template subcommand: ${sub}`);
|
|
16618
|
+
printTemplateHelp();
|
|
16619
|
+
process.exit(1);
|
|
16620
|
+
}
|
|
16621
|
+
}
|
|
16622
|
+
function includesLabel(includes) {
|
|
16623
|
+
const parts = [];
|
|
16624
|
+
if (includes.wayai) parts.push("wayai agent");
|
|
16625
|
+
if (includes.rekor) parts.push("rekor data layer");
|
|
16626
|
+
return parts.length ? parts.join(" + ") : "(none)";
|
|
16627
|
+
}
|
|
16628
|
+
async function runTemplateList() {
|
|
16629
|
+
const { config, accessToken } = await requireAuth();
|
|
16630
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
16631
|
+
let response;
|
|
16632
|
+
try {
|
|
16633
|
+
response = await client.templateList();
|
|
16634
|
+
} catch (err) {
|
|
16635
|
+
exitOnTemplateApiError(err);
|
|
16636
|
+
throw err;
|
|
16637
|
+
}
|
|
16638
|
+
const { templates } = response;
|
|
16639
|
+
if (templates.length === 0) {
|
|
16640
|
+
console.log("(no templates published yet)");
|
|
16641
|
+
return;
|
|
16642
|
+
}
|
|
16643
|
+
const slugWidth = Math.max(4, ...templates.map((t) => t.slug.length));
|
|
16644
|
+
const catWidth = Math.max(8, ...templates.map((t) => t.category.length));
|
|
16645
|
+
console.log(`${"SLUG".padEnd(slugWidth)} ${"CATEGORY".padEnd(catWidth)} INCLUDES`);
|
|
16646
|
+
for (const t of templates) {
|
|
16647
|
+
console.log(`${t.slug.padEnd(slugWidth)} ${t.category.padEnd(catWidth)} ${includesLabel(t.includes)}`);
|
|
16648
|
+
}
|
|
16649
|
+
}
|
|
16650
|
+
async function runTemplatePull(rest) {
|
|
16651
|
+
const slug = rest[0];
|
|
16652
|
+
if (!slug) {
|
|
16653
|
+
console.error("wayai template pull <slug>");
|
|
16654
|
+
process.exit(1);
|
|
16655
|
+
}
|
|
16656
|
+
if (!TEMPLATE_SLUG_REGEX2.test(slug)) {
|
|
16657
|
+
console.error(`Invalid template slug: ${slug}`);
|
|
16658
|
+
process.exit(1);
|
|
16659
|
+
}
|
|
16660
|
+
const gitRoot = findGitRoot();
|
|
16661
|
+
if (!gitRoot) {
|
|
16662
|
+
console.error("Not in a git repository. Run `wayai template pull` inside your project repo.");
|
|
16663
|
+
process.exit(1);
|
|
16664
|
+
}
|
|
16665
|
+
const { config, accessToken } = await requireAuth();
|
|
16666
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
16667
|
+
let detail;
|
|
16668
|
+
try {
|
|
16669
|
+
detail = await client.templatePull(slug);
|
|
16670
|
+
} catch (err) {
|
|
16671
|
+
exitOnTemplateApiError(err);
|
|
16672
|
+
throw err;
|
|
16673
|
+
}
|
|
16674
|
+
if (!detail.includes.wayai) {
|
|
16675
|
+
console.log(`Template "${slug}" has no WayAI slice \u2014 run \`rekor template pull ${slug}\` for its data layer.`);
|
|
16676
|
+
return;
|
|
16677
|
+
}
|
|
16678
|
+
const targetDir = path20.join(resolveLayout(gitRoot).hubsDir, slug);
|
|
16679
|
+
const written = writeFileMap(targetDir, detail.files);
|
|
16680
|
+
console.log(`Pulled template "${slug}" \u2192 ${path20.relative(gitRoot, targetDir)}/ (${written.length} file${written.length === 1 ? "" : "s"}).`);
|
|
16681
|
+
console.log(`Next: \`wayai push\` to deploy it into your own hub.`);
|
|
16682
|
+
if (detail.includes.rekor) {
|
|
16683
|
+
console.log(`
|
|
16684
|
+
This template includes a Rekor data layer \u2014 run \`rekor template pull ${slug}\` to add it.`);
|
|
16685
|
+
}
|
|
16686
|
+
}
|
|
16687
|
+
function printTemplateHelp() {
|
|
16688
|
+
console.log(`wayai template \u2014 install ready-made hub templates
|
|
16689
|
+
|
|
16690
|
+
Usage:
|
|
16691
|
+
wayai template list List available templates
|
|
16692
|
+
wayai template pull <slug> Write a template's WayAI slice into wayai-ws/hubs/<slug>/
|
|
16693
|
+
|
|
16694
|
+
After pulling, run \`wayai push\` to deploy the template into your own hub.`);
|
|
16695
|
+
}
|
|
16696
|
+
function exitOnTemplateApiError(err) {
|
|
16697
|
+
if (err instanceof ApiError) {
|
|
16698
|
+
if (err.status === 401) {
|
|
16699
|
+
console.error("Authentication failed. Run `wayai login` again.");
|
|
16700
|
+
} else if (err.status === 404) {
|
|
16701
|
+
console.error("Template not found. Run `wayai template list` to see available templates.");
|
|
16702
|
+
} else if (err.status === 429) {
|
|
16703
|
+
console.error("Rate limited. Please retry in a moment.");
|
|
16704
|
+
} else {
|
|
16705
|
+
console.error(err.message);
|
|
16706
|
+
}
|
|
16707
|
+
process.exit(1);
|
|
16708
|
+
}
|
|
16709
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
16710
|
+
process.exit(1);
|
|
16711
|
+
}
|
|
16712
|
+
var init_templates = __esm({
|
|
16713
|
+
"src/commands/templates.ts"() {
|
|
16714
|
+
"use strict";
|
|
16715
|
+
init_auth();
|
|
16716
|
+
init_api_client();
|
|
16717
|
+
init_workspace();
|
|
16718
|
+
init_layout();
|
|
16719
|
+
init_template_files();
|
|
16720
|
+
init_contracts();
|
|
16721
|
+
}
|
|
16722
|
+
});
|
|
16723
|
+
|
|
16194
16724
|
// src/lib/report-edit-args.ts
|
|
16195
16725
|
function parseReportEditArgs(args2) {
|
|
16196
16726
|
const patch = {};
|
|
@@ -16236,6 +16766,9 @@ var admin_exports = {};
|
|
|
16236
16766
|
__export(admin_exports, {
|
|
16237
16767
|
adminCommand: () => adminCommand
|
|
16238
16768
|
});
|
|
16769
|
+
import * as fs17 from "fs";
|
|
16770
|
+
import * as path21 from "path";
|
|
16771
|
+
import * as yaml9 from "js-yaml";
|
|
16239
16772
|
async function adminCommand(args2) {
|
|
16240
16773
|
const [group, ...afterGroup] = args2;
|
|
16241
16774
|
if (!group) {
|
|
@@ -16349,6 +16882,23 @@ async function adminCommand(args2) {
|
|
|
16349
16882
|
process.exit(1);
|
|
16350
16883
|
}
|
|
16351
16884
|
}
|
|
16885
|
+
if (group === "template") {
|
|
16886
|
+
if (!sub) {
|
|
16887
|
+
printHelp2();
|
|
16888
|
+
process.exit(1);
|
|
16889
|
+
}
|
|
16890
|
+
switch (sub) {
|
|
16891
|
+
case "push":
|
|
16892
|
+
await runTemplatePush(positional);
|
|
16893
|
+
return;
|
|
16894
|
+
case "pull":
|
|
16895
|
+
await runTemplatePull2(positional, flagArgs);
|
|
16896
|
+
return;
|
|
16897
|
+
default:
|
|
16898
|
+
printHelp2();
|
|
16899
|
+
process.exit(1);
|
|
16900
|
+
}
|
|
16901
|
+
}
|
|
16352
16902
|
printHelp2();
|
|
16353
16903
|
process.exit(1);
|
|
16354
16904
|
}
|
|
@@ -16573,6 +17123,139 @@ function parseFlags2(flagArgs, allowed) {
|
|
|
16573
17123
|
}
|
|
16574
17124
|
return out;
|
|
16575
17125
|
}
|
|
17126
|
+
async function runTemplatePush(positional) {
|
|
17127
|
+
const slug = positional[0];
|
|
17128
|
+
if (!slug) {
|
|
17129
|
+
console.error("wayai admin template push <slug>");
|
|
17130
|
+
process.exit(1);
|
|
17131
|
+
}
|
|
17132
|
+
if (!TEMPLATE_SLUG_REGEX2.test(slug)) {
|
|
17133
|
+
console.error(`Invalid template slug: ${slug}`);
|
|
17134
|
+
process.exit(1);
|
|
17135
|
+
}
|
|
17136
|
+
const gitRoot = findGitRoot();
|
|
17137
|
+
if (!gitRoot) {
|
|
17138
|
+
console.error("Not in a git repository. Run from the tutorials/ authoring repo.");
|
|
17139
|
+
process.exit(1);
|
|
17140
|
+
}
|
|
17141
|
+
const templateDir = path21.join(resolveTemplatesDir(gitRoot), slug);
|
|
17142
|
+
const manifestPath = path21.join(templateDir, "template.yaml");
|
|
17143
|
+
if (!fs17.existsSync(manifestPath)) {
|
|
17144
|
+
console.error(`template.yaml not found at ${path21.relative(gitRoot, manifestPath)}`);
|
|
17145
|
+
process.exit(1);
|
|
17146
|
+
}
|
|
17147
|
+
let manifest;
|
|
17148
|
+
try {
|
|
17149
|
+
manifest = templateYamlSchema2.parse(yaml9.load(fs17.readFileSync(manifestPath, "utf-8")));
|
|
17150
|
+
} catch (err) {
|
|
17151
|
+
console.error(`Invalid template.yaml: ${err instanceof Error ? err.message : String(err)}`);
|
|
17152
|
+
process.exit(1);
|
|
17153
|
+
}
|
|
17154
|
+
if (manifest.slug !== slug) {
|
|
17155
|
+
console.error(`template.yaml slug "${manifest.slug}" does not match folder "${slug}".`);
|
|
17156
|
+
process.exit(1);
|
|
17157
|
+
}
|
|
17158
|
+
let wayaiFiles;
|
|
17159
|
+
if (manifest.wayai) {
|
|
17160
|
+
const sliceDir = path21.resolve(templateDir, manifest.wayai.source);
|
|
17161
|
+
if (!fs17.existsSync(sliceDir)) {
|
|
17162
|
+
console.error(`wayai source not found: ${manifest.wayai.source} (resolved ${sliceDir})`);
|
|
17163
|
+
process.exit(1);
|
|
17164
|
+
}
|
|
17165
|
+
wayaiFiles = readDirToFileMap(sliceDir);
|
|
17166
|
+
}
|
|
17167
|
+
const readmePath = path21.join(templateDir, "README.md");
|
|
17168
|
+
const readmeMarkdown = fs17.existsSync(readmePath) ? fs17.readFileSync(readmePath, "utf-8") : "";
|
|
17169
|
+
let hero;
|
|
17170
|
+
if (manifest.hero) {
|
|
17171
|
+
const heroPath = path21.resolve(templateDir, manifest.hero);
|
|
17172
|
+
if (fs17.existsSync(heroPath)) {
|
|
17173
|
+
hero = { filename: path21.basename(heroPath), dataBase64: fs17.readFileSync(heroPath).toString("base64") };
|
|
17174
|
+
} else {
|
|
17175
|
+
console.error(`Warning: hero not found at ${manifest.hero}; skipping.`);
|
|
17176
|
+
}
|
|
17177
|
+
}
|
|
17178
|
+
const metadata = {
|
|
17179
|
+
category: manifest.category,
|
|
17180
|
+
status: manifest.status,
|
|
17181
|
+
order: manifest.order ?? 0,
|
|
17182
|
+
...manifest.wayai && {
|
|
17183
|
+
wayai: {
|
|
17184
|
+
metaTitle: manifest.wayai.metaTitle,
|
|
17185
|
+
metaDescription: manifest.wayai.metaDescription,
|
|
17186
|
+
installCommand: manifest.wayai.installCommand
|
|
17187
|
+
}
|
|
17188
|
+
},
|
|
17189
|
+
...manifest.rekor && {
|
|
17190
|
+
rekor: {
|
|
17191
|
+
metaTitle: manifest.rekor.metaTitle,
|
|
17192
|
+
metaDescription: manifest.rekor.metaDescription,
|
|
17193
|
+
installCommand: manifest.rekor.installCommand,
|
|
17194
|
+
...manifest.rekor.mcpEndpoint && { mcpEndpoint: manifest.rekor.mcpEndpoint }
|
|
17195
|
+
}
|
|
17196
|
+
}
|
|
17197
|
+
};
|
|
17198
|
+
const body = { slug, metadata, wayaiFiles, readmeMarkdown, hero };
|
|
17199
|
+
const { config, accessToken } = await requireAuth();
|
|
17200
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
17201
|
+
let result;
|
|
17202
|
+
try {
|
|
17203
|
+
result = await client.adminTemplatePush(body);
|
|
17204
|
+
} catch (err) {
|
|
17205
|
+
exitOnApiError(err);
|
|
17206
|
+
throw err;
|
|
17207
|
+
}
|
|
17208
|
+
console.log(`Template "${result.slug}": ${result.action} (${result.filesWritten} written, ${result.filesDeleted} deleted).`);
|
|
17209
|
+
if (manifest.status !== "published") {
|
|
17210
|
+
console.log(`(status=${manifest.status} \u2192 unpublished from the store)`);
|
|
17211
|
+
}
|
|
17212
|
+
}
|
|
17213
|
+
async function runTemplatePull2(positional, flagArgs) {
|
|
17214
|
+
const slug = positional[0];
|
|
17215
|
+
if (!slug) {
|
|
17216
|
+
console.error("wayai admin template pull <slug> [--out DIR] [--json]");
|
|
17217
|
+
process.exit(1);
|
|
17218
|
+
}
|
|
17219
|
+
if (!TEMPLATE_SLUG_REGEX2.test(slug)) {
|
|
17220
|
+
console.error(`Invalid template slug: ${slug}`);
|
|
17221
|
+
process.exit(1);
|
|
17222
|
+
}
|
|
17223
|
+
let outDir;
|
|
17224
|
+
let jsonOutput = false;
|
|
17225
|
+
for (let i = 0; i < flagArgs.length; i++) {
|
|
17226
|
+
if (flagArgs[i] === "--json") {
|
|
17227
|
+
jsonOutput = true;
|
|
17228
|
+
continue;
|
|
17229
|
+
}
|
|
17230
|
+
if (flagArgs[i] === "--out") {
|
|
17231
|
+
outDir = flagArgs[++i];
|
|
17232
|
+
if (!outDir) {
|
|
17233
|
+
console.error("--out requires a value");
|
|
17234
|
+
process.exit(1);
|
|
17235
|
+
}
|
|
17236
|
+
continue;
|
|
17237
|
+
}
|
|
17238
|
+
console.error(`Unknown flag: ${flagArgs[i]}`);
|
|
17239
|
+
process.exit(1);
|
|
17240
|
+
}
|
|
17241
|
+
const { config, accessToken } = await requireAuth();
|
|
17242
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
17243
|
+
let detail;
|
|
17244
|
+
try {
|
|
17245
|
+
detail = await client.adminTemplatePull(slug);
|
|
17246
|
+
} catch (err) {
|
|
17247
|
+
exitOnApiError(err);
|
|
17248
|
+
throw err;
|
|
17249
|
+
}
|
|
17250
|
+
if (jsonOutput) {
|
|
17251
|
+
console.log(JSON.stringify(detail, null, 2));
|
|
17252
|
+
return;
|
|
17253
|
+
}
|
|
17254
|
+
const target = outDir ? path21.resolve(outDir) : path21.join(process.cwd(), "template-store-pull", slug);
|
|
17255
|
+
const written = writeFileMap(target, detail.files);
|
|
17256
|
+
console.log(`Pulled "${slug}" from the store \u2192 ${target} (${written.length} file${written.length === 1 ? "" : "s"}).`);
|
|
17257
|
+
console.log(`includes: wayai=${detail.includes.wayai} rekor=${detail.includes.rekor}`);
|
|
17258
|
+
}
|
|
16576
17259
|
function exitOnApiError(err) {
|
|
16577
17260
|
if (err instanceof ApiError) {
|
|
16578
17261
|
if (err.status === 401) {
|
|
@@ -16984,6 +17667,9 @@ Usage:
|
|
|
16984
17667
|
wayai admin notice list [--status active|resolved] [--limit N] [--offset N] [--json]
|
|
16985
17668
|
wayai admin notice resolve <notice_id>
|
|
16986
17669
|
|
|
17670
|
+
wayai admin template push <slug> Publish a template from tutorials/templates/<slug>/ into the store
|
|
17671
|
+
wayai admin template pull <slug> [--out DIR] [--json] Pull a published template from the store for inspection
|
|
17672
|
+
|
|
16987
17673
|
Sources:
|
|
16988
17674
|
do Live DO SQLite (existing conversation, hub config, etc.).
|
|
16989
17675
|
analytics ClickHouse projections (conversation, message, billing_event, schedule_event).
|
|
@@ -17041,6 +17727,9 @@ var init_admin = __esm({
|
|
|
17041
17727
|
init_api_client();
|
|
17042
17728
|
init_observability();
|
|
17043
17729
|
init_report_edit_args();
|
|
17730
|
+
init_workspace();
|
|
17731
|
+
init_layout();
|
|
17732
|
+
init_template_files();
|
|
17044
17733
|
init_contracts();
|
|
17045
17734
|
VALID_TYPES = dataExplorerDebugDoType2.options;
|
|
17046
17735
|
VALID_ANALYTICS_TABLES = dataExplorerDebugAnalyticsTable2.options;
|
|
@@ -17049,12 +17738,12 @@ var init_admin = __esm({
|
|
|
17049
17738
|
});
|
|
17050
17739
|
|
|
17051
17740
|
// src/commands/report-create.ts
|
|
17052
|
-
import { readFileSync as
|
|
17053
|
-
import { dirname as
|
|
17741
|
+
import { readFileSync as readFileSync16 } from "fs";
|
|
17742
|
+
import { dirname as dirname8, join as join23 } from "path";
|
|
17054
17743
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
17055
17744
|
function getCliVersion() {
|
|
17056
17745
|
try {
|
|
17057
|
-
const pkg2 = JSON.parse(
|
|
17746
|
+
const pkg2 = JSON.parse(readFileSync16(join23(__dirname, "..", "..", "package.json"), "utf-8"));
|
|
17058
17747
|
return `cli@${pkg2.version}`;
|
|
17059
17748
|
} catch {
|
|
17060
17749
|
return "cli@unknown";
|
|
@@ -17161,7 +17850,7 @@ var init_report_create = __esm({
|
|
|
17161
17850
|
init_auth();
|
|
17162
17851
|
init_repo_config();
|
|
17163
17852
|
init_api_client();
|
|
17164
|
-
__dirname =
|
|
17853
|
+
__dirname = dirname8(fileURLToPath2(import.meta.url));
|
|
17165
17854
|
}
|
|
17166
17855
|
});
|
|
17167
17856
|
|
|
@@ -17436,9 +18125,9 @@ var init_update = __esm({
|
|
|
17436
18125
|
|
|
17437
18126
|
// src/index.ts
|
|
17438
18127
|
init_sentry();
|
|
17439
|
-
import { readFileSync as
|
|
18128
|
+
import { readFileSync as readFileSync17 } from "fs";
|
|
17440
18129
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
17441
|
-
import { dirname as
|
|
18130
|
+
import { dirname as dirname9, join as join24 } from "path";
|
|
17442
18131
|
|
|
17443
18132
|
// src/lib/errors.ts
|
|
17444
18133
|
init_api_client();
|
|
@@ -17463,7 +18152,7 @@ init_skill_version();
|
|
|
17463
18152
|
import { exec } from "child_process";
|
|
17464
18153
|
var REFRESH_TIMEOUT_MS = 1e4;
|
|
17465
18154
|
function refreshCliCache() {
|
|
17466
|
-
return new Promise((
|
|
18155
|
+
return new Promise((resolve5) => {
|
|
17467
18156
|
exec("npm view @wayai/cli version", { timeout: REFRESH_TIMEOUT_MS }, (err, stdout) => {
|
|
17468
18157
|
if (!err) {
|
|
17469
18158
|
const latest = stdout.trim();
|
|
@@ -17474,7 +18163,7 @@ function refreshCliCache() {
|
|
|
17474
18163
|
}
|
|
17475
18164
|
}
|
|
17476
18165
|
}
|
|
17477
|
-
|
|
18166
|
+
resolve5();
|
|
17478
18167
|
});
|
|
17479
18168
|
});
|
|
17480
18169
|
}
|
|
@@ -17566,11 +18255,10 @@ Run \`npx skills add wayai-pro/wayai-skill -y\` to update.`);
|
|
|
17566
18255
|
}
|
|
17567
18256
|
|
|
17568
18257
|
// src/index.ts
|
|
17569
|
-
var __dirname2 =
|
|
17570
|
-
var pkg = JSON.parse(
|
|
18258
|
+
var __dirname2 = dirname9(fileURLToPath3(import.meta.url));
|
|
18259
|
+
var pkg = JSON.parse(readFileSync17(join24(__dirname2, "..", "package.json"), "utf-8"));
|
|
17571
18260
|
var [, , command, ...args] = process.argv;
|
|
17572
18261
|
var isBackgroundRefresh = command === REFRESH_COMMAND;
|
|
17573
|
-
var OWN_HELP_COMMANDS = /* @__PURE__ */ new Set(["eval", "admin", "report"]);
|
|
17574
18262
|
if (!isBackgroundRefresh) initSentry(command);
|
|
17575
18263
|
async function main() {
|
|
17576
18264
|
if (shouldInterceptHelp(command, args, OWN_HELP_COMMANDS)) {
|
|
@@ -17700,6 +18388,11 @@ async function main() {
|
|
|
17700
18388
|
await listCommand2(args);
|
|
17701
18389
|
break;
|
|
17702
18390
|
}
|
|
18391
|
+
case "template": {
|
|
18392
|
+
const { templateCommand: templateCommand2 } = await Promise.resolve().then(() => (init_templates(), templates_exports));
|
|
18393
|
+
await templateCommand2(args);
|
|
18394
|
+
break;
|
|
18395
|
+
}
|
|
17703
18396
|
case "admin": {
|
|
17704
18397
|
const { adminCommand: adminCommand2 } = await Promise.resolve().then(() => (init_admin(), admin_exports));
|
|
17705
18398
|
await adminCommand2(args);
|
|
@@ -17766,6 +18459,8 @@ Commands:
|
|
|
17766
18459
|
sync-skills Sync skills to Anthropic/OpenAI provider connections
|
|
17767
18460
|
sync-mcp Re-discover an MCP connection's tools (refresh stale schemas)
|
|
17768
18461
|
list List organizations and hubs
|
|
18462
|
+
template list List ready-made hub templates
|
|
18463
|
+
template pull Write a template's WayAI slice into wayai-ws/hubs/<slug>/
|
|
17769
18464
|
report create Report a platform bug (submits to the triage queue)
|
|
17770
18465
|
report edit Amend your own pending report (title/description/error/steps/context)
|
|
17771
18466
|
update Update CLI to the latest version
|