@wayai/cli 0.3.53 → 0.3.55
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 +803 -95
- 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,25 @@ 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
|
+
}
|
|
270
|
+
// Download a private operator skill (platform-admin gated) for local install.
|
|
271
|
+
async adminSkillInstall(name) {
|
|
272
|
+
return this.request("GET", `/api/admin/skills/${encodeURIComponent(name)}`);
|
|
273
|
+
}
|
|
255
274
|
/**
|
|
256
275
|
* Re-discover an MCP connection's tool/resource catalog (refreshes stale
|
|
257
276
|
* input schemas that `push` leaves untouched). `connection` is the display
|
|
@@ -264,8 +283,8 @@ var init_api_client = __esm({
|
|
|
264
283
|
...organizationId && { organization_id: organizationId }
|
|
265
284
|
});
|
|
266
285
|
}
|
|
267
|
-
async lookup(
|
|
268
|
-
const params = new URLSearchParams({ path:
|
|
286
|
+
async lookup(path22, opts) {
|
|
287
|
+
const params = new URLSearchParams({ path: path22 });
|
|
269
288
|
if (opts?.organizationId) params.set("organization_id", opts.organizationId);
|
|
270
289
|
return this.request("GET", `/api/ci/lookup?${params.toString()}`);
|
|
271
290
|
}
|
|
@@ -615,9 +634,9 @@ var init_api_client = __esm({
|
|
|
615
634
|
`/api/admin/data-explorer/debug/observability/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}${qs}`
|
|
616
635
|
);
|
|
617
636
|
}
|
|
618
|
-
async request(method,
|
|
619
|
-
addApiBreadcrumb(method,
|
|
620
|
-
const url = `${this.apiUrl}${
|
|
637
|
+
async request(method, path22, body) {
|
|
638
|
+
addApiBreadcrumb(method, path22);
|
|
639
|
+
const url = `${this.apiUrl}${path22}`;
|
|
621
640
|
let refreshedOn401 = false;
|
|
622
641
|
for (let retry = 0; ; retry++) {
|
|
623
642
|
let response = await this.send(url, method, body);
|
|
@@ -641,7 +660,7 @@ var init_api_client = __esm({
|
|
|
641
660
|
await delay(RETRYABLE_BACKOFF_MS[retry]);
|
|
642
661
|
continue;
|
|
643
662
|
}
|
|
644
|
-
throw new ApiError(method,
|
|
663
|
+
throw new ApiError(method, path22, response.status, errorBody);
|
|
645
664
|
}
|
|
646
665
|
}
|
|
647
666
|
/** Issue a single authenticated request with the client's current token. */
|
|
@@ -1076,8 +1095,8 @@ var init_parseUtil = __esm({
|
|
|
1076
1095
|
init_errors();
|
|
1077
1096
|
init_en();
|
|
1078
1097
|
makeIssue = (params) => {
|
|
1079
|
-
const { data, path:
|
|
1080
|
-
const fullPath = [...
|
|
1098
|
+
const { data, path: path22, errorMaps, issueData } = params;
|
|
1099
|
+
const fullPath = [...path22, ...issueData.path || []];
|
|
1081
1100
|
const fullIssue = {
|
|
1082
1101
|
...issueData,
|
|
1083
1102
|
path: fullPath
|
|
@@ -1388,11 +1407,11 @@ var init_types = __esm({
|
|
|
1388
1407
|
init_parseUtil();
|
|
1389
1408
|
init_util();
|
|
1390
1409
|
ParseInputLazyPath = class {
|
|
1391
|
-
constructor(parent, value,
|
|
1410
|
+
constructor(parent, value, path22, key) {
|
|
1392
1411
|
this._cachedPath = [];
|
|
1393
1412
|
this.parent = parent;
|
|
1394
1413
|
this.data = value;
|
|
1395
|
-
this._path =
|
|
1414
|
+
this._path = path22;
|
|
1396
1415
|
this._key = key;
|
|
1397
1416
|
}
|
|
1398
1417
|
get path() {
|
|
@@ -4783,6 +4802,38 @@ function normalizeAuthType(raw) {
|
|
|
4783
4802
|
function visibleLength(s) {
|
|
4784
4803
|
return s.replace(INVISIBLE_NAME_CHARS, "").length;
|
|
4785
4804
|
}
|
|
4805
|
+
function validateLaneReferences(lanes, statuses) {
|
|
4806
|
+
const issues = [];
|
|
4807
|
+
if (!Array.isArray(statuses) || statuses.length === 0) return issues;
|
|
4808
|
+
const declared = new Set((Array.isArray(lanes) ? lanes : []).map((l) => l.slug).filter(Boolean));
|
|
4809
|
+
statuses.forEach((s, i) => {
|
|
4810
|
+
const lane = s.lane_slug;
|
|
4811
|
+
if (typeof lane !== "string" || lane.length === 0) return;
|
|
4812
|
+
const label = s.slug ? `"${s.slug}"` : `[${i}]`;
|
|
4813
|
+
if (s.isInitialStatus === true) {
|
|
4814
|
+
issues.push({
|
|
4815
|
+
path: [i, "lane_slug"],
|
|
4816
|
+
message: `kanban status ${label}: the initial status cannot belong to a lane (it is the shared entry point)`
|
|
4817
|
+
});
|
|
4818
|
+
return;
|
|
4819
|
+
}
|
|
4820
|
+
if (!declared.has(lane)) {
|
|
4821
|
+
issues.push({
|
|
4822
|
+
path: [i, "lane_slug"],
|
|
4823
|
+
message: `kanban status ${label}: lane_slug references unknown lane "${lane}"`
|
|
4824
|
+
});
|
|
4825
|
+
}
|
|
4826
|
+
});
|
|
4827
|
+
return issues;
|
|
4828
|
+
}
|
|
4829
|
+
function refineLaneReferences(val, ctx) {
|
|
4830
|
+
const lanes = val.lanes;
|
|
4831
|
+
const statuses = val.kanban_statuses;
|
|
4832
|
+
if (lanes == null || statuses == null) return;
|
|
4833
|
+
for (const issue of validateLaneReferences(lanes, statuses)) {
|
|
4834
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["kanban_statuses", ...issue.path], message: issue.message });
|
|
4835
|
+
}
|
|
4836
|
+
}
|
|
4786
4837
|
function containsKanbanPlaceholders(value) {
|
|
4787
4838
|
if (value == null) return false;
|
|
4788
4839
|
const serialized = typeof value === "string" ? value : JSON.stringify(value);
|
|
@@ -4814,12 +4865,12 @@ function typeMatches(typeField, allowed) {
|
|
|
4814
4865
|
if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
|
|
4815
4866
|
return false;
|
|
4816
4867
|
}
|
|
4817
|
-
function validateSchema(schema,
|
|
4868
|
+
function validateSchema(schema, path22, errors, opts = {}) {
|
|
4818
4869
|
if (typeof schema === "boolean") return;
|
|
4819
4870
|
const depth = opts.depth ?? 0;
|
|
4820
4871
|
if (depth > MAX_SCHEMA_DEPTH) {
|
|
4821
4872
|
errors.push({
|
|
4822
|
-
path:
|
|
4873
|
+
path: path22 || "<root>",
|
|
4823
4874
|
message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH} levels`,
|
|
4824
4875
|
suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
|
|
4825
4876
|
});
|
|
@@ -4827,7 +4878,7 @@ function validateSchema(schema, path19, errors, opts = {}) {
|
|
|
4827
4878
|
}
|
|
4828
4879
|
if (!isRecord(schema)) {
|
|
4829
4880
|
errors.push({
|
|
4830
|
-
path:
|
|
4881
|
+
path: path22,
|
|
4831
4882
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
4832
4883
|
});
|
|
4833
4884
|
return;
|
|
@@ -4835,14 +4886,14 @@ function validateSchema(schema, path19, errors, opts = {}) {
|
|
|
4835
4886
|
if (opts.isRoot) {
|
|
4836
4887
|
if ("type" in schema && schema.type !== "object") {
|
|
4837
4888
|
errors.push({
|
|
4838
|
-
path:
|
|
4889
|
+
path: path22 ? `${path22}.type` : "type",
|
|
4839
4890
|
message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
|
|
4840
4891
|
suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
|
|
4841
4892
|
});
|
|
4842
4893
|
}
|
|
4843
4894
|
} else if ("type" in schema && !typeMatches(schema.type, ALLOWED_TYPES)) {
|
|
4844
4895
|
errors.push({
|
|
4845
|
-
path: `${
|
|
4896
|
+
path: `${path22}.type`,
|
|
4846
4897
|
message: `type must be one of ${[...ALLOWED_TYPES].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
|
|
4847
4898
|
});
|
|
4848
4899
|
}
|
|
@@ -4851,25 +4902,25 @@ function validateSchema(schema, path19, errors, opts = {}) {
|
|
|
4851
4902
|
if (typeof e === "string") {
|
|
4852
4903
|
const isPlaceholder = PLACEHOLDER_TOKENS.includes(e);
|
|
4853
4904
|
errors.push({
|
|
4854
|
-
path: `${
|
|
4905
|
+
path: `${path22}.enum`,
|
|
4855
4906
|
message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
|
|
4856
4907
|
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
4908
|
});
|
|
4858
4909
|
} else if (!Array.isArray(e)) {
|
|
4859
4910
|
errors.push({
|
|
4860
|
-
path: `${
|
|
4911
|
+
path: `${path22}.enum`,
|
|
4861
4912
|
message: `enum must be a non-empty array of primitives, got ${typeof e}`
|
|
4862
4913
|
});
|
|
4863
4914
|
} else if (e.length === 0) {
|
|
4864
4915
|
errors.push({
|
|
4865
|
-
path: `${
|
|
4916
|
+
path: `${path22}.enum`,
|
|
4866
4917
|
message: "enum must not be empty"
|
|
4867
4918
|
});
|
|
4868
4919
|
} else {
|
|
4869
4920
|
for (let i = 0; i < e.length; i++) {
|
|
4870
4921
|
if (!isPrimitive(e[i])) {
|
|
4871
4922
|
errors.push({
|
|
4872
|
-
path: `${
|
|
4923
|
+
path: `${path22}.enum[${i}]`,
|
|
4873
4924
|
message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
|
|
4874
4925
|
});
|
|
4875
4926
|
}
|
|
@@ -4879,7 +4930,7 @@ function validateSchema(schema, path19, errors, opts = {}) {
|
|
|
4879
4930
|
for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
|
|
4880
4931
|
if (key in schema && typeof schema[key] === "boolean") {
|
|
4881
4932
|
errors.push({
|
|
4882
|
-
path: `${
|
|
4933
|
+
path: `${path22}.${key}`,
|
|
4883
4934
|
message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
|
|
4884
4935
|
suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
|
|
4885
4936
|
});
|
|
@@ -4888,45 +4939,45 @@ function validateSchema(schema, path19, errors, opts = {}) {
|
|
|
4888
4939
|
if ("properties" in schema) {
|
|
4889
4940
|
if (!isRecord(schema.properties)) {
|
|
4890
4941
|
errors.push({
|
|
4891
|
-
path: `${
|
|
4942
|
+
path: `${path22}.properties`,
|
|
4892
4943
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
4893
4944
|
});
|
|
4894
4945
|
} else {
|
|
4895
4946
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
4896
|
-
validateSchema(propSchema, `${
|
|
4947
|
+
validateSchema(propSchema, `${path22}.properties.${propName}`, errors, { depth: depth + 1 });
|
|
4897
4948
|
}
|
|
4898
4949
|
}
|
|
4899
4950
|
}
|
|
4900
4951
|
if (schemaTypeIncludes(schema, "array") && "items" in schema) {
|
|
4901
4952
|
if (Array.isArray(schema.items)) {
|
|
4902
|
-
schema.items.forEach((sub, i) => validateSchema(sub, `${
|
|
4953
|
+
schema.items.forEach((sub, i) => validateSchema(sub, `${path22}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
4903
4954
|
} else {
|
|
4904
|
-
validateSchema(schema.items, `${
|
|
4955
|
+
validateSchema(schema.items, `${path22}.items`, errors, { depth: depth + 1 });
|
|
4905
4956
|
}
|
|
4906
4957
|
}
|
|
4907
4958
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS) {
|
|
4908
4959
|
if (key in schema && isRecord(schema[key])) {
|
|
4909
|
-
validateSchema(schema[key], `${
|
|
4960
|
+
validateSchema(schema[key], `${path22}.${key}`, errors, { depth: depth + 1 });
|
|
4910
4961
|
}
|
|
4911
4962
|
}
|
|
4912
4963
|
for (const key of SUBSCHEMA_LIST_KEYWORDS) {
|
|
4913
4964
|
const list = schema[key];
|
|
4914
4965
|
if (Array.isArray(list)) {
|
|
4915
|
-
list.forEach((sub, i) => validateSchema(sub, `${
|
|
4966
|
+
list.forEach((sub, i) => validateSchema(sub, `${path22}.${key}[${i}]`, errors, { depth: depth + 1 }));
|
|
4916
4967
|
}
|
|
4917
4968
|
}
|
|
4918
4969
|
for (const key of SUBSCHEMA_MAP_KEYWORDS) {
|
|
4919
4970
|
const map = schema[key];
|
|
4920
4971
|
if (isRecord(map)) {
|
|
4921
4972
|
for (const [name, sub] of Object.entries(map)) {
|
|
4922
|
-
validateSchema(sub, `${
|
|
4973
|
+
validateSchema(sub, `${path22}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
4923
4974
|
}
|
|
4924
4975
|
}
|
|
4925
4976
|
}
|
|
4926
4977
|
const reportedPaths = new Set(errors.map((e) => e.path));
|
|
4927
4978
|
for (const [k, v] of Object.entries(schema)) {
|
|
4928
4979
|
if (typeof v !== "string") continue;
|
|
4929
|
-
const fieldPath = `${
|
|
4980
|
+
const fieldPath = `${path22}.${k}`;
|
|
4930
4981
|
if (reportedPaths.has(fieldPath)) continue;
|
|
4931
4982
|
for (const token of PLACEHOLDER_TOKENS) {
|
|
4932
4983
|
if (v === token) {
|
|
@@ -5059,6 +5110,37 @@ function refineHubAsCodeKanbanStatuses(config, ctx) {
|
|
|
5059
5110
|
}
|
|
5060
5111
|
}
|
|
5061
5112
|
}
|
|
5113
|
+
function refineHubAsCodeLanes(config, ctx) {
|
|
5114
|
+
const hub = config.hub;
|
|
5115
|
+
if (hub == null) return;
|
|
5116
|
+
if ("lanes" in hub && hub.lanes != null) {
|
|
5117
|
+
if (!Array.isArray(hub.lanes)) {
|
|
5118
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["hub", "lanes"], message: "lanes must be an array" });
|
|
5119
|
+
return;
|
|
5120
|
+
}
|
|
5121
|
+
const result = lanesArraySchema.safeParse(hub.lanes);
|
|
5122
|
+
if (!result.success) {
|
|
5123
|
+
for (const issue of result.error.issues) {
|
|
5124
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["hub", "lanes", ...issue.path], message: issue.message });
|
|
5125
|
+
}
|
|
5126
|
+
return;
|
|
5127
|
+
}
|
|
5128
|
+
}
|
|
5129
|
+
const statuses = hub.kanban_statuses;
|
|
5130
|
+
if (Array.isArray(statuses)) {
|
|
5131
|
+
for (const issue of validateLaneReferences(hub.lanes, statuses)) {
|
|
5132
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["hub", "kanban_statuses", ...issue.path], message: issue.message });
|
|
5133
|
+
}
|
|
5134
|
+
}
|
|
5135
|
+
}
|
|
5136
|
+
function isSafeTemplatePath(path22) {
|
|
5137
|
+
if (path22.length === 0 || path22.length > 300) return false;
|
|
5138
|
+
if (path22.startsWith("/") || path22.includes("\\")) return false;
|
|
5139
|
+
const segments = path22.split("/");
|
|
5140
|
+
return segments.every(
|
|
5141
|
+
(seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
|
|
5142
|
+
);
|
|
5143
|
+
}
|
|
5062
5144
|
function identifyTokenType(token) {
|
|
5063
5145
|
if (token.startsWith("way_")) return "way_token";
|
|
5064
5146
|
if (token.startsWith("eyJ")) return "jwt";
|
|
@@ -5124,7 +5206,7 @@ function findStepBoundaries(transcript) {
|
|
|
5124
5206
|
}
|
|
5125
5207
|
return out;
|
|
5126
5208
|
}
|
|
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;
|
|
5209
|
+
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, ADMIN_SKILL_NAME_REGEX, adminSkillNameParam, WAYAI_WORKSPACE_LAYOUT, MAX_RESOURCE_FILE_SIZE;
|
|
5128
5210
|
var init_dist = __esm({
|
|
5129
5211
|
"../../packages/core/dist/index.js"() {
|
|
5130
5212
|
"use strict";
|
|
@@ -5172,6 +5254,8 @@ var init_dist = __esm({
|
|
|
5172
5254
|
init_zod();
|
|
5173
5255
|
init_zod();
|
|
5174
5256
|
init_zod();
|
|
5257
|
+
init_zod();
|
|
5258
|
+
init_zod();
|
|
5175
5259
|
APP_ERROR_BRAND = /* @__PURE__ */ Symbol.for("wayai.AppError");
|
|
5176
5260
|
AppError = class extends Error {
|
|
5177
5261
|
constructor(message, code, statusCode = 500, details) {
|
|
@@ -5417,6 +5501,7 @@ var init_dist = __esm({
|
|
|
5417
5501
|
INVISIBLE_NAME_CHARS = /[\s\p{Default_Ignorable_Code_Point}]/gu;
|
|
5418
5502
|
MAX_KANBAN_STATUSES = 50;
|
|
5419
5503
|
MAX_FOLLOWUPS_PER_STATUS = 20;
|
|
5504
|
+
MAX_LANES = 20;
|
|
5420
5505
|
MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES = 16384;
|
|
5421
5506
|
RESERVED_TEMPLATE_DUMP_NAME = "additional_data";
|
|
5422
5507
|
kanbanStatusSlugSchema = slugSchema;
|
|
@@ -5473,7 +5558,14 @@ var init_dist = __esm({
|
|
|
5473
5558
|
/** Slugs this status may transition to. `undefined` = unrestricted (any
|
|
5474
5559
|
* next status). Empty array `[]` is rejected — author must use
|
|
5475
5560
|
* `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()
|
|
5561
|
+
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(),
|
|
5562
|
+
/** Optional presentational grouping — the slug of a hub `lanes[]` entry this
|
|
5563
|
+
* status belongs to. `undefined` = ungrouped. Purely a board-filter/organization
|
|
5564
|
+
* concept; it does NOT constrain transitions (those live in `allowed_next_statuses`)
|
|
5565
|
+
* and is not exposed to agents. The cross-reference invariant (must point at a
|
|
5566
|
+
* declared lane; the initial status must not have one) is enforced at the hub
|
|
5567
|
+
* level via `validateLaneReferences` — this schema only sees the status array. */
|
|
5568
|
+
lane_slug: kanbanStatusSlugSchema.optional()
|
|
5477
5569
|
}).passthrough().superRefine((status, ctx) => {
|
|
5478
5570
|
const label = status.name ? `"${status.name}"` : status.slug ? `"${status.slug}"` : "<unnamed>";
|
|
5479
5571
|
for (const [a, b] of EXCLUSIVE_FLAG_PAIRS) {
|
|
@@ -5564,6 +5656,28 @@ var init_dist = __esm({
|
|
|
5564
5656
|
});
|
|
5565
5657
|
});
|
|
5566
5658
|
});
|
|
5659
|
+
laneSchema = external_exports.object({
|
|
5660
|
+
slug: kanbanStatusSlugSchema,
|
|
5661
|
+
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"),
|
|
5662
|
+
color: external_exports.string().optional(),
|
|
5663
|
+
order: external_exports.number().int().nonnegative().optional()
|
|
5664
|
+
}).passthrough();
|
|
5665
|
+
lanesArraySchema = external_exports.array(laneSchema).max(MAX_LANES, `lanes must have at most ${MAX_LANES} entries`).superRefine((lanes, ctx) => {
|
|
5666
|
+
const seen = /* @__PURE__ */ new Map();
|
|
5667
|
+
lanes.forEach((l, i) => {
|
|
5668
|
+
if (!l.slug) return;
|
|
5669
|
+
const arr = seen.get(l.slug) ?? [];
|
|
5670
|
+
arr.push(i);
|
|
5671
|
+
seen.set(l.slug, arr);
|
|
5672
|
+
});
|
|
5673
|
+
for (const [slug, indices] of seen) {
|
|
5674
|
+
if (indices.length > 1) {
|
|
5675
|
+
for (const i of indices) {
|
|
5676
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: [i, "slug"], message: `lanes: duplicate slug "${slug}"` });
|
|
5677
|
+
}
|
|
5678
|
+
}
|
|
5679
|
+
}
|
|
5680
|
+
});
|
|
5567
5681
|
hubIdParam = external_exports.object({ id: uuidSchema });
|
|
5568
5682
|
hubAdminIdParam = external_exports.object({ id: uuidSchema, adminId: uuidSchema });
|
|
5569
5683
|
hubUserIdParam = external_exports.object({ id: uuidSchema, hubUserId: uuidSchema });
|
|
@@ -5576,14 +5690,16 @@ var init_dist = __esm({
|
|
|
5576
5690
|
hub_name: external_exports.string().min(1, "hub_name is required"),
|
|
5577
5691
|
hub_description: external_exports.string().optional(),
|
|
5578
5692
|
kanban_statuses: kanbanStatusesArraySchema.nullable().optional(),
|
|
5693
|
+
lanes: lanesArraySchema.nullable().optional(),
|
|
5579
5694
|
// Write-once at creation; updateHubBody does not accept this.
|
|
5580
5695
|
primary_region: primaryRegionSchema.optional()
|
|
5581
|
-
}).passthrough();
|
|
5696
|
+
}).passthrough().superRefine(refineLaneReferences);
|
|
5582
5697
|
updateHubBody = external_exports.object({
|
|
5583
5698
|
support_model: external_exports.enum(["conversation", "account"]).optional(),
|
|
5584
5699
|
unassigned_policy: external_exports.enum(["default_team", "auto_assign_random", "auto_assign_round_robin", "pull_queue"]).optional(),
|
|
5585
5700
|
default_hub_team_id: uuidSchema.nullable().optional(),
|
|
5586
5701
|
kanban_statuses: kanbanStatusesArraySchema.nullable().optional(),
|
|
5702
|
+
lanes: lanesArraySchema.nullable().optional(),
|
|
5587
5703
|
// summarization_threshold_tokens relocated to the summarizer AGENT (PR4) — validated/
|
|
5588
5704
|
// persisted via the agent path (.passthrough() agent body → HubDO column), not here.
|
|
5589
5705
|
auto_close_inactive_days: external_exports.number().int().min(1).max(180).optional(),
|
|
@@ -5592,7 +5708,7 @@ var init_dist = __esm({
|
|
|
5592
5708
|
language: external_exports.enum(["en", "pt", "es"]).optional(),
|
|
5593
5709
|
access_request_message: external_exports.string().max(1e3).nullable().optional(),
|
|
5594
5710
|
access_approval_role: external_exports.enum(["admin", "team"]).optional()
|
|
5595
|
-
}).passthrough();
|
|
5711
|
+
}).passthrough().superRefine(refineLaneReferences);
|
|
5596
5712
|
addHubAdminBody = external_exports.object({
|
|
5597
5713
|
user_email: external_exports.string().email("valid email is required")
|
|
5598
5714
|
});
|
|
@@ -6768,6 +6884,7 @@ var init_dist = __esm({
|
|
|
6768
6884
|
}).passthrough().superRefine((config, ctx) => {
|
|
6769
6885
|
refineHubAsCodeCustomTools(config, ctx);
|
|
6770
6886
|
refineHubAsCodeKanbanStatuses(config, ctx);
|
|
6887
|
+
refineHubAsCodeLanes(config, ctx);
|
|
6771
6888
|
});
|
|
6772
6889
|
ciPullHubIdParam = external_exports.object({
|
|
6773
6890
|
hub_id: ciUuidSchema
|
|
@@ -7439,6 +7556,66 @@ var init_dist = __esm({
|
|
|
7439
7556
|
offset: external_exports.coerce.number().int().min(0).optional()
|
|
7440
7557
|
});
|
|
7441
7558
|
noticeIdParamSchema = external_exports.object({ id: external_exports.string().min(1) });
|
|
7559
|
+
TEMPLATE_SLUG_REGEX = /^[a-z0-9][a-z0-9-]{0,62}$/;
|
|
7560
|
+
templateSlugSchema = external_exports.string().regex(TEMPLATE_SLUG_REGEX, "slug must be lowercase alphanumeric with hyphens (max 63)");
|
|
7561
|
+
templateStatusSchema = external_exports.enum(["published", "draft", "internal"]);
|
|
7562
|
+
templateFileMapSchema = external_exports.record(external_exports.string()).refine((m) => Object.keys(m).every(isSafeTemplatePath), {
|
|
7563
|
+
message: 'file map contains an unsafe path (no absolute paths, "..", or backslashes)'
|
|
7564
|
+
});
|
|
7565
|
+
templateWayaiBlockSchema = external_exports.object({
|
|
7566
|
+
metaTitle: external_exports.string().min(1).max(200),
|
|
7567
|
+
metaDescription: external_exports.string().max(1e3).default(""),
|
|
7568
|
+
installCommand: external_exports.string().min(1).max(300)
|
|
7569
|
+
});
|
|
7570
|
+
templateRekorBlockSchema = templateWayaiBlockSchema.extend({
|
|
7571
|
+
mcpEndpoint: external_exports.string().url().optional(),
|
|
7572
|
+
url: external_exports.string().url().optional()
|
|
7573
|
+
});
|
|
7574
|
+
templateYamlWayaiBlock = templateWayaiBlockSchema.extend({
|
|
7575
|
+
source: external_exports.string().min(1)
|
|
7576
|
+
});
|
|
7577
|
+
templateYamlRekorBlock = templateRekorBlockSchema.extend({
|
|
7578
|
+
source: external_exports.string().min(1)
|
|
7579
|
+
});
|
|
7580
|
+
templateYamlSchema = external_exports.object({
|
|
7581
|
+
slug: templateSlugSchema,
|
|
7582
|
+
category: external_exports.string().min(1).max(60),
|
|
7583
|
+
status: templateStatusSchema.default("draft"),
|
|
7584
|
+
order: external_exports.number().int().min(0).max(1e5).optional(),
|
|
7585
|
+
hero: external_exports.string().optional(),
|
|
7586
|
+
// relative path to a hero image inside the template folder
|
|
7587
|
+
wayai: templateYamlWayaiBlock.optional(),
|
|
7588
|
+
rekor: templateYamlRekorBlock.optional()
|
|
7589
|
+
}).refine((c) => Boolean(c.wayai) || Boolean(c.rekor), {
|
|
7590
|
+
message: "template.yaml must define at least one of `wayai:` or `rekor:`"
|
|
7591
|
+
});
|
|
7592
|
+
templatePushMetadataSchema = external_exports.object({
|
|
7593
|
+
category: external_exports.string().min(1).max(60),
|
|
7594
|
+
status: templateStatusSchema,
|
|
7595
|
+
order: external_exports.number().int().min(0).max(1e5).default(0),
|
|
7596
|
+
wayai: templateWayaiBlockSchema.optional(),
|
|
7597
|
+
rekor: templateRekorBlockSchema.optional()
|
|
7598
|
+
});
|
|
7599
|
+
templateHeroSchema = external_exports.object({
|
|
7600
|
+
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)"),
|
|
7601
|
+
// ~8MB of base64 ≈ a ~6MB image — a generous cap that bounds the inline payload
|
|
7602
|
+
// (the endpoint is platform-admin-only, but an unbounded blob is still avoidable).
|
|
7603
|
+
dataBase64: external_exports.string().min(1).max(8e6)
|
|
7604
|
+
});
|
|
7605
|
+
templatePushBody = external_exports.object({
|
|
7606
|
+
slug: templateSlugSchema,
|
|
7607
|
+
metadata: templatePushMetadataSchema,
|
|
7608
|
+
// wayai slice file-map (path -> body); ABSENT for a Rekor-only template.
|
|
7609
|
+
wayaiFiles: templateFileMapSchema.optional(),
|
|
7610
|
+
// raw README markdown; the backend renders + sanitizes (single authority).
|
|
7611
|
+
readmeMarkdown: external_exports.string().default(""),
|
|
7612
|
+
hero: templateHeroSchema.optional()
|
|
7613
|
+
});
|
|
7614
|
+
templateSlugParam = external_exports.object({ slug: templateSlugSchema });
|
|
7615
|
+
ADMIN_SKILL_NAME_REGEX = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
7616
|
+
adminSkillNameParam = external_exports.object({
|
|
7617
|
+
name: external_exports.string().regex(ADMIN_SKILL_NAME_REGEX, "invalid skill name")
|
|
7618
|
+
});
|
|
7442
7619
|
WAYAI_WORKSPACE_LAYOUT = {
|
|
7443
7620
|
/** Product-namespaced root dir at the git root. */
|
|
7444
7621
|
wsDir: "wayai-ws",
|
|
@@ -7490,6 +7667,9 @@ function resolveLayout(gitRoot, layout = WAYAI_LAYOUT) {
|
|
|
7490
7667
|
legacyAlsoPresent: false
|
|
7491
7668
|
};
|
|
7492
7669
|
}
|
|
7670
|
+
function resolveTemplatesDir(gitRoot) {
|
|
7671
|
+
return path.join(gitRoot, TEMPLATES_AUTHORING_SUBDIR);
|
|
7672
|
+
}
|
|
7493
7673
|
function hubsDirLabel(gitRoot) {
|
|
7494
7674
|
if (!gitRoot) return path.join(WAYAI_LAYOUT.wsDir, WAYAI_LAYOUT.hubsSubdir);
|
|
7495
7675
|
return path.relative(gitRoot, resolveLayout(gitRoot).hubsDir);
|
|
@@ -7515,7 +7695,7 @@ function warnLayoutOnce(gitRoot) {
|
|
|
7515
7695
|
);
|
|
7516
7696
|
}
|
|
7517
7697
|
}
|
|
7518
|
-
var WAYAI_LAYOUT, _layoutWarned;
|
|
7698
|
+
var WAYAI_LAYOUT, TEMPLATES_AUTHORING_SUBDIR, _layoutWarned;
|
|
7519
7699
|
var init_layout = __esm({
|
|
7520
7700
|
"src/lib/layout.ts"() {
|
|
7521
7701
|
"use strict";
|
|
@@ -7524,6 +7704,7 @@ var init_layout = __esm({
|
|
|
7524
7704
|
...WAYAI_WORKSPACE_LAYOUT,
|
|
7525
7705
|
legacy: { wsDir: "workspace", orgAtRoot: "org" }
|
|
7526
7706
|
};
|
|
7707
|
+
TEMPLATES_AUTHORING_SUBDIR = "templates";
|
|
7527
7708
|
_layoutWarned = false;
|
|
7528
7709
|
}
|
|
7529
7710
|
});
|
|
@@ -7814,24 +7995,24 @@ import * as path4 from "path";
|
|
|
7814
7995
|
import * as readline from "readline";
|
|
7815
7996
|
function prompt(question) {
|
|
7816
7997
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
7817
|
-
return new Promise((
|
|
7998
|
+
return new Promise((resolve5) => {
|
|
7818
7999
|
rl.question(question, (answer) => {
|
|
7819
8000
|
rl.close();
|
|
7820
|
-
|
|
8001
|
+
resolve5(answer.trim());
|
|
7821
8002
|
});
|
|
7822
8003
|
});
|
|
7823
8004
|
}
|
|
7824
8005
|
function confirm(question) {
|
|
7825
8006
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
7826
|
-
return new Promise((
|
|
8007
|
+
return new Promise((resolve5) => {
|
|
7827
8008
|
rl.question(`${question} [y/N]: `, (answer) => {
|
|
7828
8009
|
rl.close();
|
|
7829
|
-
|
|
8010
|
+
resolve5(answer.trim().toLowerCase() === "y");
|
|
7830
8011
|
});
|
|
7831
8012
|
});
|
|
7832
8013
|
}
|
|
7833
8014
|
function promptSecret(question) {
|
|
7834
|
-
return new Promise((
|
|
8015
|
+
return new Promise((resolve5) => {
|
|
7835
8016
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
7836
8017
|
const originalWrite = rl._writeToOutput;
|
|
7837
8018
|
let firstWrite = true;
|
|
@@ -7847,18 +8028,18 @@ function promptSecret(question) {
|
|
|
7847
8028
|
rl._writeToOutput = originalWrite;
|
|
7848
8029
|
process.stdout.write("\n");
|
|
7849
8030
|
rl.close();
|
|
7850
|
-
|
|
8031
|
+
resolve5(answer);
|
|
7851
8032
|
});
|
|
7852
8033
|
});
|
|
7853
8034
|
}
|
|
7854
8035
|
function readStdin() {
|
|
7855
|
-
return new Promise((
|
|
8036
|
+
return new Promise((resolve5, reject) => {
|
|
7856
8037
|
let data = "";
|
|
7857
8038
|
process.stdin.setEncoding("utf-8");
|
|
7858
8039
|
process.stdin.on("data", (chunk) => {
|
|
7859
8040
|
data += chunk;
|
|
7860
8041
|
});
|
|
7861
|
-
process.stdin.on("end", () =>
|
|
8042
|
+
process.stdin.on("end", () => resolve5(data.trim()));
|
|
7862
8043
|
process.stdin.on("error", reject);
|
|
7863
8044
|
});
|
|
7864
8045
|
}
|
|
@@ -8019,9 +8200,9 @@ function getVersionCachePath(filename = CLI_CACHE_FILE) {
|
|
|
8019
8200
|
}
|
|
8020
8201
|
function readVersionCache(filename = CLI_CACHE_FILE) {
|
|
8021
8202
|
try {
|
|
8022
|
-
const
|
|
8023
|
-
if (!existsSync4(
|
|
8024
|
-
const parsed = JSON.parse(readFileSync5(
|
|
8203
|
+
const path22 = getVersionCachePath(filename);
|
|
8204
|
+
if (!existsSync4(path22)) return null;
|
|
8205
|
+
const parsed = JSON.parse(readFileSync5(path22, "utf-8"));
|
|
8025
8206
|
if (typeof parsed.lastCheck !== "number") return null;
|
|
8026
8207
|
if (parsed.latest !== null && typeof parsed.latest !== "string") return null;
|
|
8027
8208
|
return parsed;
|
|
@@ -8041,10 +8222,10 @@ function isVersionCacheStale(filename = CLI_CACHE_FILE, maxAgeMs = MAX_AGE_24H_M
|
|
|
8041
8222
|
return Date.now() - cache.lastCheck > maxAgeMs;
|
|
8042
8223
|
}
|
|
8043
8224
|
function writeVersionCache(filename, cache) {
|
|
8044
|
-
const
|
|
8045
|
-
const dir = dirname3(
|
|
8225
|
+
const path22 = getVersionCachePath(filename);
|
|
8226
|
+
const dir = dirname3(path22);
|
|
8046
8227
|
if (!existsSync4(dir)) mkdirSync(dir, { recursive: true });
|
|
8047
|
-
writeFileSync2(
|
|
8228
|
+
writeFileSync2(path22, JSON.stringify(cache));
|
|
8048
8229
|
}
|
|
8049
8230
|
function touchVersionCache(filename) {
|
|
8050
8231
|
writeVersionCache(filename, { lastCheck: Date.now(), latest: readVersionCache(filename)?.latest ?? null });
|
|
@@ -8079,14 +8260,14 @@ function parseFrontmatterVersion(content) {
|
|
|
8079
8260
|
function findInstalledSkills(projectRoot) {
|
|
8080
8261
|
const found = [];
|
|
8081
8262
|
for (const rel of SKILL_INSTALL_PATHS) {
|
|
8082
|
-
const
|
|
8083
|
-
if (!existsSync5(
|
|
8263
|
+
const path22 = join7(projectRoot, rel);
|
|
8264
|
+
if (!existsSync5(path22)) continue;
|
|
8084
8265
|
let version = null;
|
|
8085
8266
|
try {
|
|
8086
|
-
version = parseFrontmatterVersion(readFileSync6(
|
|
8267
|
+
version = parseFrontmatterVersion(readFileSync6(path22, "utf-8"));
|
|
8087
8268
|
} catch {
|
|
8088
8269
|
}
|
|
8089
|
-
found.push({ path:
|
|
8270
|
+
found.push({ path: path22, version });
|
|
8090
8271
|
}
|
|
8091
8272
|
return found;
|
|
8092
8273
|
}
|
|
@@ -8516,7 +8697,7 @@ async function validateToken(apiUrl, token) {
|
|
|
8516
8697
|
}
|
|
8517
8698
|
}
|
|
8518
8699
|
function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
8519
|
-
return new Promise((
|
|
8700
|
+
return new Promise((resolve5, reject) => {
|
|
8520
8701
|
const server = http.createServer((req, res) => {
|
|
8521
8702
|
const url = new URL(req.url || "/", `http://127.0.0.1:${port}`);
|
|
8522
8703
|
if (url.pathname === "/callback") {
|
|
@@ -8542,7 +8723,7 @@ function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
|
|
|
8542
8723
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
8543
8724
|
res.end("<html><body><h2>Login successful!</h2><p>You can close this tab and return to your terminal.</p></body></html>");
|
|
8544
8725
|
server.close();
|
|
8545
|
-
|
|
8726
|
+
resolve5({ code, port });
|
|
8546
8727
|
} else {
|
|
8547
8728
|
res.writeHead(400, { "Content-Type": "text/html" });
|
|
8548
8729
|
res.end("<html><body><h2>Login failed</h2><p>No authorization code received</p></body></html>");
|
|
@@ -8707,10 +8888,10 @@ import * as readline2 from "readline";
|
|
|
8707
8888
|
function prompt2(question, defaultValue) {
|
|
8708
8889
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
8709
8890
|
const display = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
|
|
8710
|
-
return new Promise((
|
|
8891
|
+
return new Promise((resolve5) => {
|
|
8711
8892
|
rl.question(display, (answer) => {
|
|
8712
8893
|
rl.close();
|
|
8713
|
-
|
|
8894
|
+
resolve5(answer.trim() || defaultValue || "");
|
|
8714
8895
|
});
|
|
8715
8896
|
});
|
|
8716
8897
|
}
|
|
@@ -8828,8 +9009,8 @@ async function tryOpenBrowser(url) {
|
|
|
8828
9009
|
cmd = "xdg-open";
|
|
8829
9010
|
args2 = [url];
|
|
8830
9011
|
}
|
|
8831
|
-
return new Promise((
|
|
8832
|
-
execFile(cmd, args2, (err) =>
|
|
9012
|
+
return new Promise((resolve5) => {
|
|
9013
|
+
execFile(cmd, args2, (err) => resolve5(!err));
|
|
8833
9014
|
});
|
|
8834
9015
|
} catch {
|
|
8835
9016
|
return false;
|
|
@@ -11948,7 +12129,7 @@ Timeout after ${timeoutSeconds}s. Session is still running.`);
|
|
|
11948
12129
|
console.log(`Check results: wayai eval-results --session ${sessionId}`);
|
|
11949
12130
|
}
|
|
11950
12131
|
function sleep(ms) {
|
|
11951
|
-
return new Promise((
|
|
12132
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
11952
12133
|
}
|
|
11953
12134
|
function extractApiMessage(err) {
|
|
11954
12135
|
if (err instanceof ApiError) {
|
|
@@ -12531,6 +12712,38 @@ function normalizeAuthType2(raw) {
|
|
|
12531
12712
|
function visibleLength2(s) {
|
|
12532
12713
|
return s.replace(INVISIBLE_NAME_CHARS2, "").length;
|
|
12533
12714
|
}
|
|
12715
|
+
function validateLaneReferences2(lanes, statuses) {
|
|
12716
|
+
const issues = [];
|
|
12717
|
+
if (!Array.isArray(statuses) || statuses.length === 0) return issues;
|
|
12718
|
+
const declared = new Set((Array.isArray(lanes) ? lanes : []).map((l) => l.slug).filter(Boolean));
|
|
12719
|
+
statuses.forEach((s, i) => {
|
|
12720
|
+
const lane = s.lane_slug;
|
|
12721
|
+
if (typeof lane !== "string" || lane.length === 0) return;
|
|
12722
|
+
const label = s.slug ? `"${s.slug}"` : `[${i}]`;
|
|
12723
|
+
if (s.isInitialStatus === true) {
|
|
12724
|
+
issues.push({
|
|
12725
|
+
path: [i, "lane_slug"],
|
|
12726
|
+
message: `kanban status ${label}: the initial status cannot belong to a lane (it is the shared entry point)`
|
|
12727
|
+
});
|
|
12728
|
+
return;
|
|
12729
|
+
}
|
|
12730
|
+
if (!declared.has(lane)) {
|
|
12731
|
+
issues.push({
|
|
12732
|
+
path: [i, "lane_slug"],
|
|
12733
|
+
message: `kanban status ${label}: lane_slug references unknown lane "${lane}"`
|
|
12734
|
+
});
|
|
12735
|
+
}
|
|
12736
|
+
});
|
|
12737
|
+
return issues;
|
|
12738
|
+
}
|
|
12739
|
+
function refineLaneReferences2(val, ctx) {
|
|
12740
|
+
const lanes = val.lanes;
|
|
12741
|
+
const statuses = val.kanban_statuses;
|
|
12742
|
+
if (lanes == null || statuses == null) return;
|
|
12743
|
+
for (const issue of validateLaneReferences2(lanes, statuses)) {
|
|
12744
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["kanban_statuses", ...issue.path], message: issue.message });
|
|
12745
|
+
}
|
|
12746
|
+
}
|
|
12534
12747
|
function containsKanbanPlaceholders2(value) {
|
|
12535
12748
|
if (value == null) return false;
|
|
12536
12749
|
const serialized = typeof value === "string" ? value : JSON.stringify(value);
|
|
@@ -12562,12 +12775,12 @@ function typeMatches2(typeField, allowed) {
|
|
|
12562
12775
|
if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
|
|
12563
12776
|
return false;
|
|
12564
12777
|
}
|
|
12565
|
-
function validateSchema2(schema,
|
|
12778
|
+
function validateSchema2(schema, path22, errors, opts = {}) {
|
|
12566
12779
|
if (typeof schema === "boolean") return;
|
|
12567
12780
|
const depth = opts.depth ?? 0;
|
|
12568
12781
|
if (depth > MAX_SCHEMA_DEPTH2) {
|
|
12569
12782
|
errors.push({
|
|
12570
|
-
path:
|
|
12783
|
+
path: path22 || "<root>",
|
|
12571
12784
|
message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH2} levels`,
|
|
12572
12785
|
suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
|
|
12573
12786
|
});
|
|
@@ -12575,7 +12788,7 @@ function validateSchema2(schema, path19, errors, opts = {}) {
|
|
|
12575
12788
|
}
|
|
12576
12789
|
if (!isRecord2(schema)) {
|
|
12577
12790
|
errors.push({
|
|
12578
|
-
path:
|
|
12791
|
+
path: path22,
|
|
12579
12792
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
12580
12793
|
});
|
|
12581
12794
|
return;
|
|
@@ -12583,14 +12796,14 @@ function validateSchema2(schema, path19, errors, opts = {}) {
|
|
|
12583
12796
|
if (opts.isRoot) {
|
|
12584
12797
|
if ("type" in schema && schema.type !== "object") {
|
|
12585
12798
|
errors.push({
|
|
12586
|
-
path:
|
|
12799
|
+
path: path22 ? `${path22}.type` : "type",
|
|
12587
12800
|
message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
|
|
12588
12801
|
suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
|
|
12589
12802
|
});
|
|
12590
12803
|
}
|
|
12591
12804
|
} else if ("type" in schema && !typeMatches2(schema.type, ALLOWED_TYPES2)) {
|
|
12592
12805
|
errors.push({
|
|
12593
|
-
path: `${
|
|
12806
|
+
path: `${path22}.type`,
|
|
12594
12807
|
message: `type must be one of ${[...ALLOWED_TYPES2].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
|
|
12595
12808
|
});
|
|
12596
12809
|
}
|
|
@@ -12599,25 +12812,25 @@ function validateSchema2(schema, path19, errors, opts = {}) {
|
|
|
12599
12812
|
if (typeof e === "string") {
|
|
12600
12813
|
const isPlaceholder = PLACEHOLDER_TOKENS2.includes(e);
|
|
12601
12814
|
errors.push({
|
|
12602
|
-
path: `${
|
|
12815
|
+
path: `${path22}.enum`,
|
|
12603
12816
|
message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
|
|
12604
12817
|
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"]`.'
|
|
12605
12818
|
});
|
|
12606
12819
|
} else if (!Array.isArray(e)) {
|
|
12607
12820
|
errors.push({
|
|
12608
|
-
path: `${
|
|
12821
|
+
path: `${path22}.enum`,
|
|
12609
12822
|
message: `enum must be a non-empty array of primitives, got ${typeof e}`
|
|
12610
12823
|
});
|
|
12611
12824
|
} else if (e.length === 0) {
|
|
12612
12825
|
errors.push({
|
|
12613
|
-
path: `${
|
|
12826
|
+
path: `${path22}.enum`,
|
|
12614
12827
|
message: "enum must not be empty"
|
|
12615
12828
|
});
|
|
12616
12829
|
} else {
|
|
12617
12830
|
for (let i = 0; i < e.length; i++) {
|
|
12618
12831
|
if (!isPrimitive2(e[i])) {
|
|
12619
12832
|
errors.push({
|
|
12620
|
-
path: `${
|
|
12833
|
+
path: `${path22}.enum[${i}]`,
|
|
12621
12834
|
message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
|
|
12622
12835
|
});
|
|
12623
12836
|
}
|
|
@@ -12627,7 +12840,7 @@ function validateSchema2(schema, path19, errors, opts = {}) {
|
|
|
12627
12840
|
for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
|
|
12628
12841
|
if (key in schema && typeof schema[key] === "boolean") {
|
|
12629
12842
|
errors.push({
|
|
12630
|
-
path: `${
|
|
12843
|
+
path: `${path22}.${key}`,
|
|
12631
12844
|
message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
|
|
12632
12845
|
suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
|
|
12633
12846
|
});
|
|
@@ -12636,45 +12849,45 @@ function validateSchema2(schema, path19, errors, opts = {}) {
|
|
|
12636
12849
|
if ("properties" in schema) {
|
|
12637
12850
|
if (!isRecord2(schema.properties)) {
|
|
12638
12851
|
errors.push({
|
|
12639
|
-
path: `${
|
|
12852
|
+
path: `${path22}.properties`,
|
|
12640
12853
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
12641
12854
|
});
|
|
12642
12855
|
} else {
|
|
12643
12856
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
12644
|
-
validateSchema2(propSchema, `${
|
|
12857
|
+
validateSchema2(propSchema, `${path22}.properties.${propName}`, errors, { depth: depth + 1 });
|
|
12645
12858
|
}
|
|
12646
12859
|
}
|
|
12647
12860
|
}
|
|
12648
12861
|
if (schemaTypeIncludes2(schema, "array") && "items" in schema) {
|
|
12649
12862
|
if (Array.isArray(schema.items)) {
|
|
12650
|
-
schema.items.forEach((sub, i) => validateSchema2(sub, `${
|
|
12863
|
+
schema.items.forEach((sub, i) => validateSchema2(sub, `${path22}.items[${i}]`, errors, { depth: depth + 1 }));
|
|
12651
12864
|
} else {
|
|
12652
|
-
validateSchema2(schema.items, `${
|
|
12865
|
+
validateSchema2(schema.items, `${path22}.items`, errors, { depth: depth + 1 });
|
|
12653
12866
|
}
|
|
12654
12867
|
}
|
|
12655
12868
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS2) {
|
|
12656
12869
|
if (key in schema && isRecord2(schema[key])) {
|
|
12657
|
-
validateSchema2(schema[key], `${
|
|
12870
|
+
validateSchema2(schema[key], `${path22}.${key}`, errors, { depth: depth + 1 });
|
|
12658
12871
|
}
|
|
12659
12872
|
}
|
|
12660
12873
|
for (const key of SUBSCHEMA_LIST_KEYWORDS2) {
|
|
12661
12874
|
const list = schema[key];
|
|
12662
12875
|
if (Array.isArray(list)) {
|
|
12663
|
-
list.forEach((sub, i) => validateSchema2(sub, `${
|
|
12876
|
+
list.forEach((sub, i) => validateSchema2(sub, `${path22}.${key}[${i}]`, errors, { depth: depth + 1 }));
|
|
12664
12877
|
}
|
|
12665
12878
|
}
|
|
12666
12879
|
for (const key of SUBSCHEMA_MAP_KEYWORDS2) {
|
|
12667
12880
|
const map = schema[key];
|
|
12668
12881
|
if (isRecord2(map)) {
|
|
12669
12882
|
for (const [name, sub] of Object.entries(map)) {
|
|
12670
|
-
validateSchema2(sub, `${
|
|
12883
|
+
validateSchema2(sub, `${path22}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
12671
12884
|
}
|
|
12672
12885
|
}
|
|
12673
12886
|
}
|
|
12674
12887
|
const reportedPaths = new Set(errors.map((e) => e.path));
|
|
12675
12888
|
for (const [k, v] of Object.entries(schema)) {
|
|
12676
12889
|
if (typeof v !== "string") continue;
|
|
12677
|
-
const fieldPath = `${
|
|
12890
|
+
const fieldPath = `${path22}.${k}`;
|
|
12678
12891
|
if (reportedPaths.has(fieldPath)) continue;
|
|
12679
12892
|
for (const token of PLACEHOLDER_TOKENS2) {
|
|
12680
12893
|
if (v === token) {
|
|
@@ -12807,7 +13020,38 @@ function refineHubAsCodeKanbanStatuses2(config, ctx) {
|
|
|
12807
13020
|
}
|
|
12808
13021
|
}
|
|
12809
13022
|
}
|
|
12810
|
-
|
|
13023
|
+
function refineHubAsCodeLanes2(config, ctx) {
|
|
13024
|
+
const hub = config.hub;
|
|
13025
|
+
if (hub == null) return;
|
|
13026
|
+
if ("lanes" in hub && hub.lanes != null) {
|
|
13027
|
+
if (!Array.isArray(hub.lanes)) {
|
|
13028
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["hub", "lanes"], message: "lanes must be an array" });
|
|
13029
|
+
return;
|
|
13030
|
+
}
|
|
13031
|
+
const result = lanesArraySchema2.safeParse(hub.lanes);
|
|
13032
|
+
if (!result.success) {
|
|
13033
|
+
for (const issue of result.error.issues) {
|
|
13034
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["hub", "lanes", ...issue.path], message: issue.message });
|
|
13035
|
+
}
|
|
13036
|
+
return;
|
|
13037
|
+
}
|
|
13038
|
+
}
|
|
13039
|
+
const statuses = hub.kanban_statuses;
|
|
13040
|
+
if (Array.isArray(statuses)) {
|
|
13041
|
+
for (const issue of validateLaneReferences2(hub.lanes, statuses)) {
|
|
13042
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["hub", "kanban_statuses", ...issue.path], message: issue.message });
|
|
13043
|
+
}
|
|
13044
|
+
}
|
|
13045
|
+
}
|
|
13046
|
+
function isSafeTemplatePath2(path22) {
|
|
13047
|
+
if (path22.length === 0 || path22.length > 300) return false;
|
|
13048
|
+
if (path22.startsWith("/") || path22.includes("\\")) return false;
|
|
13049
|
+
const segments = path22.split("/");
|
|
13050
|
+
return segments.every(
|
|
13051
|
+
(seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
|
|
13052
|
+
);
|
|
13053
|
+
}
|
|
13054
|
+
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, ADMIN_SKILL_NAME_REGEX2, adminSkillNameParam2;
|
|
12811
13055
|
var init_contracts = __esm({
|
|
12812
13056
|
"../../packages/core/dist/contracts/index.js"() {
|
|
12813
13057
|
"use strict";
|
|
@@ -12855,6 +13099,8 @@ var init_contracts = __esm({
|
|
|
12855
13099
|
init_zod();
|
|
12856
13100
|
init_zod();
|
|
12857
13101
|
init_zod();
|
|
13102
|
+
init_zod();
|
|
13103
|
+
init_zod();
|
|
12858
13104
|
uuidSchema2 = external_exports.string().uuid();
|
|
12859
13105
|
paginationSchema3 = external_exports.object({
|
|
12860
13106
|
limit: external_exports.coerce.number().int().min(1).max(100).default(50),
|
|
@@ -13016,6 +13262,7 @@ var init_contracts = __esm({
|
|
|
13016
13262
|
INVISIBLE_NAME_CHARS2 = /[\s\p{Default_Ignorable_Code_Point}]/gu;
|
|
13017
13263
|
MAX_KANBAN_STATUSES2 = 50;
|
|
13018
13264
|
MAX_FOLLOWUPS_PER_STATUS2 = 20;
|
|
13265
|
+
MAX_LANES2 = 20;
|
|
13019
13266
|
MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES2 = 16384;
|
|
13020
13267
|
RESERVED_TEMPLATE_DUMP_NAME2 = "additional_data";
|
|
13021
13268
|
kanbanStatusSlugSchema2 = slugSchema2;
|
|
@@ -13072,7 +13319,14 @@ var init_contracts = __esm({
|
|
|
13072
13319
|
/** Slugs this status may transition to. `undefined` = unrestricted (any
|
|
13073
13320
|
* next status). Empty array `[]` is rejected — author must use
|
|
13074
13321
|
* `isTerminalStatus: true` to express "no outbound transitions". */
|
|
13075
|
-
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()
|
|
13322
|
+
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(),
|
|
13323
|
+
/** Optional presentational grouping — the slug of a hub `lanes[]` entry this
|
|
13324
|
+
* status belongs to. `undefined` = ungrouped. Purely a board-filter/organization
|
|
13325
|
+
* concept; it does NOT constrain transitions (those live in `allowed_next_statuses`)
|
|
13326
|
+
* and is not exposed to agents. The cross-reference invariant (must point at a
|
|
13327
|
+
* declared lane; the initial status must not have one) is enforced at the hub
|
|
13328
|
+
* level via `validateLaneReferences` — this schema only sees the status array. */
|
|
13329
|
+
lane_slug: kanbanStatusSlugSchema2.optional()
|
|
13076
13330
|
}).passthrough().superRefine((status, ctx) => {
|
|
13077
13331
|
const label = status.name ? `"${status.name}"` : status.slug ? `"${status.slug}"` : "<unnamed>";
|
|
13078
13332
|
for (const [a, b] of EXCLUSIVE_FLAG_PAIRS2) {
|
|
@@ -13163,6 +13417,28 @@ var init_contracts = __esm({
|
|
|
13163
13417
|
});
|
|
13164
13418
|
});
|
|
13165
13419
|
});
|
|
13420
|
+
laneSchema2 = external_exports.object({
|
|
13421
|
+
slug: kanbanStatusSlugSchema2,
|
|
13422
|
+
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"),
|
|
13423
|
+
color: external_exports.string().optional(),
|
|
13424
|
+
order: external_exports.number().int().nonnegative().optional()
|
|
13425
|
+
}).passthrough();
|
|
13426
|
+
lanesArraySchema2 = external_exports.array(laneSchema2).max(MAX_LANES2, `lanes must have at most ${MAX_LANES2} entries`).superRefine((lanes, ctx) => {
|
|
13427
|
+
const seen = /* @__PURE__ */ new Map();
|
|
13428
|
+
lanes.forEach((l, i) => {
|
|
13429
|
+
if (!l.slug) return;
|
|
13430
|
+
const arr = seen.get(l.slug) ?? [];
|
|
13431
|
+
arr.push(i);
|
|
13432
|
+
seen.set(l.slug, arr);
|
|
13433
|
+
});
|
|
13434
|
+
for (const [slug, indices] of seen) {
|
|
13435
|
+
if (indices.length > 1) {
|
|
13436
|
+
for (const i of indices) {
|
|
13437
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: [i, "slug"], message: `lanes: duplicate slug "${slug}"` });
|
|
13438
|
+
}
|
|
13439
|
+
}
|
|
13440
|
+
}
|
|
13441
|
+
});
|
|
13166
13442
|
hubIdParam2 = external_exports.object({ id: uuidSchema2 });
|
|
13167
13443
|
hubAdminIdParam2 = external_exports.object({ id: uuidSchema2, adminId: uuidSchema2 });
|
|
13168
13444
|
hubUserIdParam2 = external_exports.object({ id: uuidSchema2, hubUserId: uuidSchema2 });
|
|
@@ -13175,14 +13451,16 @@ var init_contracts = __esm({
|
|
|
13175
13451
|
hub_name: external_exports.string().min(1, "hub_name is required"),
|
|
13176
13452
|
hub_description: external_exports.string().optional(),
|
|
13177
13453
|
kanban_statuses: kanbanStatusesArraySchema2.nullable().optional(),
|
|
13454
|
+
lanes: lanesArraySchema2.nullable().optional(),
|
|
13178
13455
|
// Write-once at creation; updateHubBody does not accept this.
|
|
13179
13456
|
primary_region: primaryRegionSchema2.optional()
|
|
13180
|
-
}).passthrough();
|
|
13457
|
+
}).passthrough().superRefine(refineLaneReferences2);
|
|
13181
13458
|
updateHubBody2 = external_exports.object({
|
|
13182
13459
|
support_model: external_exports.enum(["conversation", "account"]).optional(),
|
|
13183
13460
|
unassigned_policy: external_exports.enum(["default_team", "auto_assign_random", "auto_assign_round_robin", "pull_queue"]).optional(),
|
|
13184
13461
|
default_hub_team_id: uuidSchema2.nullable().optional(),
|
|
13185
13462
|
kanban_statuses: kanbanStatusesArraySchema2.nullable().optional(),
|
|
13463
|
+
lanes: lanesArraySchema2.nullable().optional(),
|
|
13186
13464
|
// summarization_threshold_tokens relocated to the summarizer AGENT (PR4) — validated/
|
|
13187
13465
|
// persisted via the agent path (.passthrough() agent body → HubDO column), not here.
|
|
13188
13466
|
auto_close_inactive_days: external_exports.number().int().min(1).max(180).optional(),
|
|
@@ -13191,7 +13469,7 @@ var init_contracts = __esm({
|
|
|
13191
13469
|
language: external_exports.enum(["en", "pt", "es"]).optional(),
|
|
13192
13470
|
access_request_message: external_exports.string().max(1e3).nullable().optional(),
|
|
13193
13471
|
access_approval_role: external_exports.enum(["admin", "team"]).optional()
|
|
13194
|
-
}).passthrough();
|
|
13472
|
+
}).passthrough().superRefine(refineLaneReferences2);
|
|
13195
13473
|
addHubAdminBody2 = external_exports.object({
|
|
13196
13474
|
user_email: external_exports.string().email("valid email is required")
|
|
13197
13475
|
});
|
|
@@ -14367,6 +14645,7 @@ var init_contracts = __esm({
|
|
|
14367
14645
|
}).passthrough().superRefine((config, ctx) => {
|
|
14368
14646
|
refineHubAsCodeCustomTools2(config, ctx);
|
|
14369
14647
|
refineHubAsCodeKanbanStatuses2(config, ctx);
|
|
14648
|
+
refineHubAsCodeLanes2(config, ctx);
|
|
14370
14649
|
});
|
|
14371
14650
|
ciPullHubIdParam2 = external_exports.object({
|
|
14372
14651
|
hub_id: ciUuidSchema2
|
|
@@ -15038,6 +15317,66 @@ var init_contracts = __esm({
|
|
|
15038
15317
|
offset: external_exports.coerce.number().int().min(0).optional()
|
|
15039
15318
|
});
|
|
15040
15319
|
noticeIdParamSchema2 = external_exports.object({ id: external_exports.string().min(1) });
|
|
15320
|
+
TEMPLATE_SLUG_REGEX2 = /^[a-z0-9][a-z0-9-]{0,62}$/;
|
|
15321
|
+
templateSlugSchema2 = external_exports.string().regex(TEMPLATE_SLUG_REGEX2, "slug must be lowercase alphanumeric with hyphens (max 63)");
|
|
15322
|
+
templateStatusSchema2 = external_exports.enum(["published", "draft", "internal"]);
|
|
15323
|
+
templateFileMapSchema2 = external_exports.record(external_exports.string()).refine((m) => Object.keys(m).every(isSafeTemplatePath2), {
|
|
15324
|
+
message: 'file map contains an unsafe path (no absolute paths, "..", or backslashes)'
|
|
15325
|
+
});
|
|
15326
|
+
templateWayaiBlockSchema2 = external_exports.object({
|
|
15327
|
+
metaTitle: external_exports.string().min(1).max(200),
|
|
15328
|
+
metaDescription: external_exports.string().max(1e3).default(""),
|
|
15329
|
+
installCommand: external_exports.string().min(1).max(300)
|
|
15330
|
+
});
|
|
15331
|
+
templateRekorBlockSchema2 = templateWayaiBlockSchema2.extend({
|
|
15332
|
+
mcpEndpoint: external_exports.string().url().optional(),
|
|
15333
|
+
url: external_exports.string().url().optional()
|
|
15334
|
+
});
|
|
15335
|
+
templateYamlWayaiBlock2 = templateWayaiBlockSchema2.extend({
|
|
15336
|
+
source: external_exports.string().min(1)
|
|
15337
|
+
});
|
|
15338
|
+
templateYamlRekorBlock2 = templateRekorBlockSchema2.extend({
|
|
15339
|
+
source: external_exports.string().min(1)
|
|
15340
|
+
});
|
|
15341
|
+
templateYamlSchema2 = external_exports.object({
|
|
15342
|
+
slug: templateSlugSchema2,
|
|
15343
|
+
category: external_exports.string().min(1).max(60),
|
|
15344
|
+
status: templateStatusSchema2.default("draft"),
|
|
15345
|
+
order: external_exports.number().int().min(0).max(1e5).optional(),
|
|
15346
|
+
hero: external_exports.string().optional(),
|
|
15347
|
+
// relative path to a hero image inside the template folder
|
|
15348
|
+
wayai: templateYamlWayaiBlock2.optional(),
|
|
15349
|
+
rekor: templateYamlRekorBlock2.optional()
|
|
15350
|
+
}).refine((c) => Boolean(c.wayai) || Boolean(c.rekor), {
|
|
15351
|
+
message: "template.yaml must define at least one of `wayai:` or `rekor:`"
|
|
15352
|
+
});
|
|
15353
|
+
templatePushMetadataSchema2 = external_exports.object({
|
|
15354
|
+
category: external_exports.string().min(1).max(60),
|
|
15355
|
+
status: templateStatusSchema2,
|
|
15356
|
+
order: external_exports.number().int().min(0).max(1e5).default(0),
|
|
15357
|
+
wayai: templateWayaiBlockSchema2.optional(),
|
|
15358
|
+
rekor: templateRekorBlockSchema2.optional()
|
|
15359
|
+
});
|
|
15360
|
+
templateHeroSchema2 = external_exports.object({
|
|
15361
|
+
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)"),
|
|
15362
|
+
// ~8MB of base64 ≈ a ~6MB image — a generous cap that bounds the inline payload
|
|
15363
|
+
// (the endpoint is platform-admin-only, but an unbounded blob is still avoidable).
|
|
15364
|
+
dataBase64: external_exports.string().min(1).max(8e6)
|
|
15365
|
+
});
|
|
15366
|
+
templatePushBody2 = external_exports.object({
|
|
15367
|
+
slug: templateSlugSchema2,
|
|
15368
|
+
metadata: templatePushMetadataSchema2,
|
|
15369
|
+
// wayai slice file-map (path -> body); ABSENT for a Rekor-only template.
|
|
15370
|
+
wayaiFiles: templateFileMapSchema2.optional(),
|
|
15371
|
+
// raw README markdown; the backend renders + sanitizes (single authority).
|
|
15372
|
+
readmeMarkdown: external_exports.string().default(""),
|
|
15373
|
+
hero: templateHeroSchema2.optional()
|
|
15374
|
+
});
|
|
15375
|
+
templateSlugParam2 = external_exports.object({ slug: templateSlugSchema2 });
|
|
15376
|
+
ADMIN_SKILL_NAME_REGEX2 = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
15377
|
+
adminSkillNameParam2 = external_exports.object({
|
|
15378
|
+
name: external_exports.string().regex(ADMIN_SKILL_NAME_REGEX2, "invalid skill name")
|
|
15379
|
+
});
|
|
15041
15380
|
}
|
|
15042
15381
|
});
|
|
15043
15382
|
|
|
@@ -16231,6 +16570,172 @@ var init_list = __esm({
|
|
|
16231
16570
|
}
|
|
16232
16571
|
});
|
|
16233
16572
|
|
|
16573
|
+
// src/lib/template-files.ts
|
|
16574
|
+
import * as fs16 from "fs";
|
|
16575
|
+
import * as path19 from "path";
|
|
16576
|
+
function readDirToFileMap(rootDir) {
|
|
16577
|
+
const out = {};
|
|
16578
|
+
function walk(dir, prefix) {
|
|
16579
|
+
const entries = fs16.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
16580
|
+
for (const entry of entries) {
|
|
16581
|
+
const abs = path19.join(dir, entry.name);
|
|
16582
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
16583
|
+
if (entry.isDirectory()) walk(abs, rel);
|
|
16584
|
+
else if (entry.isFile()) out[rel] = fs16.readFileSync(abs, "utf-8");
|
|
16585
|
+
}
|
|
16586
|
+
}
|
|
16587
|
+
if (fs16.existsSync(rootDir)) walk(rootDir, "");
|
|
16588
|
+
return out;
|
|
16589
|
+
}
|
|
16590
|
+
function writeFileMap(targetDir, files) {
|
|
16591
|
+
const written = [];
|
|
16592
|
+
for (const [rel, body] of Object.entries(files)) {
|
|
16593
|
+
if (!isSafeTemplatePath2(rel)) {
|
|
16594
|
+
throw new Error(`Refusing to write unsafe template path: ${rel}`);
|
|
16595
|
+
}
|
|
16596
|
+
const abs = path19.join(targetDir, rel);
|
|
16597
|
+
fs16.mkdirSync(path19.dirname(abs), { recursive: true });
|
|
16598
|
+
fs16.writeFileSync(abs, body, "utf-8");
|
|
16599
|
+
written.push(rel);
|
|
16600
|
+
}
|
|
16601
|
+
return written;
|
|
16602
|
+
}
|
|
16603
|
+
var init_template_files = __esm({
|
|
16604
|
+
"src/lib/template-files.ts"() {
|
|
16605
|
+
"use strict";
|
|
16606
|
+
init_contracts();
|
|
16607
|
+
}
|
|
16608
|
+
});
|
|
16609
|
+
|
|
16610
|
+
// src/commands/templates.ts
|
|
16611
|
+
var templates_exports = {};
|
|
16612
|
+
__export(templates_exports, {
|
|
16613
|
+
templateCommand: () => templateCommand
|
|
16614
|
+
});
|
|
16615
|
+
import * as path20 from "path";
|
|
16616
|
+
async function templateCommand(args2) {
|
|
16617
|
+
const [sub, ...rest] = args2;
|
|
16618
|
+
switch (sub) {
|
|
16619
|
+
case "list":
|
|
16620
|
+
await runTemplateList();
|
|
16621
|
+
return;
|
|
16622
|
+
case "pull":
|
|
16623
|
+
await runTemplatePull(rest);
|
|
16624
|
+
return;
|
|
16625
|
+
case void 0:
|
|
16626
|
+
case "help":
|
|
16627
|
+
case "--help":
|
|
16628
|
+
case "-h":
|
|
16629
|
+
printTemplateHelp();
|
|
16630
|
+
return;
|
|
16631
|
+
default:
|
|
16632
|
+
console.error(`Unknown template subcommand: ${sub}`);
|
|
16633
|
+
printTemplateHelp();
|
|
16634
|
+
process.exit(1);
|
|
16635
|
+
}
|
|
16636
|
+
}
|
|
16637
|
+
function includesLabel(includes) {
|
|
16638
|
+
const parts = [];
|
|
16639
|
+
if (includes.wayai) parts.push("wayai agent");
|
|
16640
|
+
if (includes.rekor) parts.push("rekor data layer");
|
|
16641
|
+
return parts.length ? parts.join(" + ") : "(none)";
|
|
16642
|
+
}
|
|
16643
|
+
async function runTemplateList() {
|
|
16644
|
+
const { config, accessToken } = await requireAuth();
|
|
16645
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
16646
|
+
let response;
|
|
16647
|
+
try {
|
|
16648
|
+
response = await client.templateList();
|
|
16649
|
+
} catch (err) {
|
|
16650
|
+
exitOnTemplateApiError(err);
|
|
16651
|
+
throw err;
|
|
16652
|
+
}
|
|
16653
|
+
const { templates } = response;
|
|
16654
|
+
if (templates.length === 0) {
|
|
16655
|
+
console.log("(no templates published yet)");
|
|
16656
|
+
return;
|
|
16657
|
+
}
|
|
16658
|
+
const slugWidth = Math.max(4, ...templates.map((t) => t.slug.length));
|
|
16659
|
+
const catWidth = Math.max(8, ...templates.map((t) => t.category.length));
|
|
16660
|
+
console.log(`${"SLUG".padEnd(slugWidth)} ${"CATEGORY".padEnd(catWidth)} INCLUDES`);
|
|
16661
|
+
for (const t of templates) {
|
|
16662
|
+
console.log(`${t.slug.padEnd(slugWidth)} ${t.category.padEnd(catWidth)} ${includesLabel(t.includes)}`);
|
|
16663
|
+
}
|
|
16664
|
+
}
|
|
16665
|
+
async function runTemplatePull(rest) {
|
|
16666
|
+
const slug = rest[0];
|
|
16667
|
+
if (!slug) {
|
|
16668
|
+
console.error("wayai template pull <slug>");
|
|
16669
|
+
process.exit(1);
|
|
16670
|
+
}
|
|
16671
|
+
if (!TEMPLATE_SLUG_REGEX2.test(slug)) {
|
|
16672
|
+
console.error(`Invalid template slug: ${slug}`);
|
|
16673
|
+
process.exit(1);
|
|
16674
|
+
}
|
|
16675
|
+
const gitRoot = findGitRoot();
|
|
16676
|
+
if (!gitRoot) {
|
|
16677
|
+
console.error("Not in a git repository. Run `wayai template pull` inside your project repo.");
|
|
16678
|
+
process.exit(1);
|
|
16679
|
+
}
|
|
16680
|
+
const { config, accessToken } = await requireAuth();
|
|
16681
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
16682
|
+
let detail;
|
|
16683
|
+
try {
|
|
16684
|
+
detail = await client.templatePull(slug);
|
|
16685
|
+
} catch (err) {
|
|
16686
|
+
exitOnTemplateApiError(err);
|
|
16687
|
+
throw err;
|
|
16688
|
+
}
|
|
16689
|
+
if (!detail.includes.wayai) {
|
|
16690
|
+
console.log(`Template "${slug}" has no WayAI slice \u2014 run \`rekor template pull ${slug}\` for its data layer.`);
|
|
16691
|
+
return;
|
|
16692
|
+
}
|
|
16693
|
+
const targetDir = path20.join(resolveLayout(gitRoot).hubsDir, slug);
|
|
16694
|
+
const written = writeFileMap(targetDir, detail.files);
|
|
16695
|
+
console.log(`Pulled template "${slug}" \u2192 ${path20.relative(gitRoot, targetDir)}/ (${written.length} file${written.length === 1 ? "" : "s"}).`);
|
|
16696
|
+
console.log(`Next: \`wayai push\` to deploy it into your own hub.`);
|
|
16697
|
+
if (detail.includes.rekor) {
|
|
16698
|
+
console.log(`
|
|
16699
|
+
This template includes a Rekor data layer \u2014 run \`rekor template pull ${slug}\` to add it.`);
|
|
16700
|
+
}
|
|
16701
|
+
}
|
|
16702
|
+
function printTemplateHelp() {
|
|
16703
|
+
console.log(`wayai template \u2014 install ready-made hub templates
|
|
16704
|
+
|
|
16705
|
+
Usage:
|
|
16706
|
+
wayai template list List available templates
|
|
16707
|
+
wayai template pull <slug> Write a template's WayAI slice into wayai-ws/hubs/<slug>/
|
|
16708
|
+
|
|
16709
|
+
After pulling, run \`wayai push\` to deploy the template into your own hub.`);
|
|
16710
|
+
}
|
|
16711
|
+
function exitOnTemplateApiError(err) {
|
|
16712
|
+
if (err instanceof ApiError) {
|
|
16713
|
+
if (err.status === 401) {
|
|
16714
|
+
console.error("Authentication failed. Run `wayai login` again.");
|
|
16715
|
+
} else if (err.status === 404) {
|
|
16716
|
+
console.error("Template not found. Run `wayai template list` to see available templates.");
|
|
16717
|
+
} else if (err.status === 429) {
|
|
16718
|
+
console.error("Rate limited. Please retry in a moment.");
|
|
16719
|
+
} else {
|
|
16720
|
+
console.error(err.message);
|
|
16721
|
+
}
|
|
16722
|
+
process.exit(1);
|
|
16723
|
+
}
|
|
16724
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
16725
|
+
process.exit(1);
|
|
16726
|
+
}
|
|
16727
|
+
var init_templates = __esm({
|
|
16728
|
+
"src/commands/templates.ts"() {
|
|
16729
|
+
"use strict";
|
|
16730
|
+
init_auth();
|
|
16731
|
+
init_api_client();
|
|
16732
|
+
init_workspace();
|
|
16733
|
+
init_layout();
|
|
16734
|
+
init_template_files();
|
|
16735
|
+
init_contracts();
|
|
16736
|
+
}
|
|
16737
|
+
});
|
|
16738
|
+
|
|
16234
16739
|
// src/lib/report-edit-args.ts
|
|
16235
16740
|
function parseReportEditArgs(args2) {
|
|
16236
16741
|
const patch = {};
|
|
@@ -16276,6 +16781,9 @@ var admin_exports = {};
|
|
|
16276
16781
|
__export(admin_exports, {
|
|
16277
16782
|
adminCommand: () => adminCommand
|
|
16278
16783
|
});
|
|
16784
|
+
import * as fs17 from "fs";
|
|
16785
|
+
import * as path21 from "path";
|
|
16786
|
+
import * as yaml9 from "js-yaml";
|
|
16279
16787
|
async function adminCommand(args2) {
|
|
16280
16788
|
const [group, ...afterGroup] = args2;
|
|
16281
16789
|
if (!group) {
|
|
@@ -16389,6 +16897,37 @@ async function adminCommand(args2) {
|
|
|
16389
16897
|
process.exit(1);
|
|
16390
16898
|
}
|
|
16391
16899
|
}
|
|
16900
|
+
if (group === "template") {
|
|
16901
|
+
if (!sub) {
|
|
16902
|
+
printHelp2();
|
|
16903
|
+
process.exit(1);
|
|
16904
|
+
}
|
|
16905
|
+
switch (sub) {
|
|
16906
|
+
case "push":
|
|
16907
|
+
await runTemplatePush(positional);
|
|
16908
|
+
return;
|
|
16909
|
+
case "pull":
|
|
16910
|
+
await runTemplatePull2(positional, flagArgs);
|
|
16911
|
+
return;
|
|
16912
|
+
default:
|
|
16913
|
+
printHelp2();
|
|
16914
|
+
process.exit(1);
|
|
16915
|
+
}
|
|
16916
|
+
}
|
|
16917
|
+
if (group === "skill") {
|
|
16918
|
+
if (!sub) {
|
|
16919
|
+
printHelp2();
|
|
16920
|
+
process.exit(1);
|
|
16921
|
+
}
|
|
16922
|
+
switch (sub) {
|
|
16923
|
+
case "install":
|
|
16924
|
+
await runSkillInstall(positional);
|
|
16925
|
+
return;
|
|
16926
|
+
default:
|
|
16927
|
+
printHelp2();
|
|
16928
|
+
process.exit(1);
|
|
16929
|
+
}
|
|
16930
|
+
}
|
|
16392
16931
|
printHelp2();
|
|
16393
16932
|
process.exit(1);
|
|
16394
16933
|
}
|
|
@@ -16613,6 +17152,160 @@ function parseFlags2(flagArgs, allowed) {
|
|
|
16613
17152
|
}
|
|
16614
17153
|
return out;
|
|
16615
17154
|
}
|
|
17155
|
+
async function runTemplatePush(positional) {
|
|
17156
|
+
const slug = positional[0];
|
|
17157
|
+
if (!slug) {
|
|
17158
|
+
console.error("wayai admin template push <slug>");
|
|
17159
|
+
process.exit(1);
|
|
17160
|
+
}
|
|
17161
|
+
if (!TEMPLATE_SLUG_REGEX2.test(slug)) {
|
|
17162
|
+
console.error(`Invalid template slug: ${slug}`);
|
|
17163
|
+
process.exit(1);
|
|
17164
|
+
}
|
|
17165
|
+
const gitRoot = findGitRoot();
|
|
17166
|
+
if (!gitRoot) {
|
|
17167
|
+
console.error("Not in a git repository. Run from the tutorials/ authoring repo.");
|
|
17168
|
+
process.exit(1);
|
|
17169
|
+
}
|
|
17170
|
+
const templateDir = path21.join(resolveTemplatesDir(gitRoot), slug);
|
|
17171
|
+
const manifestPath = path21.join(templateDir, "template.yaml");
|
|
17172
|
+
if (!fs17.existsSync(manifestPath)) {
|
|
17173
|
+
console.error(`template.yaml not found at ${path21.relative(gitRoot, manifestPath)}`);
|
|
17174
|
+
process.exit(1);
|
|
17175
|
+
}
|
|
17176
|
+
let manifest;
|
|
17177
|
+
try {
|
|
17178
|
+
manifest = templateYamlSchema2.parse(yaml9.load(fs17.readFileSync(manifestPath, "utf-8")));
|
|
17179
|
+
} catch (err) {
|
|
17180
|
+
console.error(`Invalid template.yaml: ${err instanceof Error ? err.message : String(err)}`);
|
|
17181
|
+
process.exit(1);
|
|
17182
|
+
}
|
|
17183
|
+
if (manifest.slug !== slug) {
|
|
17184
|
+
console.error(`template.yaml slug "${manifest.slug}" does not match folder "${slug}".`);
|
|
17185
|
+
process.exit(1);
|
|
17186
|
+
}
|
|
17187
|
+
let wayaiFiles;
|
|
17188
|
+
if (manifest.wayai) {
|
|
17189
|
+
const sliceDir = path21.resolve(templateDir, manifest.wayai.source);
|
|
17190
|
+
if (!fs17.existsSync(sliceDir)) {
|
|
17191
|
+
console.error(`wayai source not found: ${manifest.wayai.source} (resolved ${sliceDir})`);
|
|
17192
|
+
process.exit(1);
|
|
17193
|
+
}
|
|
17194
|
+
wayaiFiles = readDirToFileMap(sliceDir);
|
|
17195
|
+
}
|
|
17196
|
+
const readmePath = path21.join(templateDir, "README.md");
|
|
17197
|
+
const readmeMarkdown = fs17.existsSync(readmePath) ? fs17.readFileSync(readmePath, "utf-8") : "";
|
|
17198
|
+
let hero;
|
|
17199
|
+
if (manifest.hero) {
|
|
17200
|
+
const heroPath = path21.resolve(templateDir, manifest.hero);
|
|
17201
|
+
if (fs17.existsSync(heroPath)) {
|
|
17202
|
+
hero = { filename: path21.basename(heroPath), dataBase64: fs17.readFileSync(heroPath).toString("base64") };
|
|
17203
|
+
} else {
|
|
17204
|
+
console.error(`Warning: hero not found at ${manifest.hero}; skipping.`);
|
|
17205
|
+
}
|
|
17206
|
+
}
|
|
17207
|
+
const metadata = {
|
|
17208
|
+
category: manifest.category,
|
|
17209
|
+
status: manifest.status,
|
|
17210
|
+
order: manifest.order ?? 0,
|
|
17211
|
+
...manifest.wayai && {
|
|
17212
|
+
wayai: {
|
|
17213
|
+
metaTitle: manifest.wayai.metaTitle,
|
|
17214
|
+
metaDescription: manifest.wayai.metaDescription,
|
|
17215
|
+
installCommand: manifest.wayai.installCommand
|
|
17216
|
+
}
|
|
17217
|
+
},
|
|
17218
|
+
...manifest.rekor && {
|
|
17219
|
+
rekor: {
|
|
17220
|
+
metaTitle: manifest.rekor.metaTitle,
|
|
17221
|
+
metaDescription: manifest.rekor.metaDescription,
|
|
17222
|
+
installCommand: manifest.rekor.installCommand,
|
|
17223
|
+
...manifest.rekor.mcpEndpoint && { mcpEndpoint: manifest.rekor.mcpEndpoint }
|
|
17224
|
+
}
|
|
17225
|
+
}
|
|
17226
|
+
};
|
|
17227
|
+
const body = { slug, metadata, wayaiFiles, readmeMarkdown, hero };
|
|
17228
|
+
const { config, accessToken } = await requireAuth();
|
|
17229
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
17230
|
+
let result;
|
|
17231
|
+
try {
|
|
17232
|
+
result = await client.adminTemplatePush(body);
|
|
17233
|
+
} catch (err) {
|
|
17234
|
+
exitOnApiError(err);
|
|
17235
|
+
throw err;
|
|
17236
|
+
}
|
|
17237
|
+
console.log(`Template "${result.slug}": ${result.action} (${result.filesWritten} written, ${result.filesDeleted} deleted).`);
|
|
17238
|
+
if (manifest.status !== "published") {
|
|
17239
|
+
console.log(`(status=${manifest.status} \u2192 unpublished from the store)`);
|
|
17240
|
+
}
|
|
17241
|
+
}
|
|
17242
|
+
async function runTemplatePull2(positional, flagArgs) {
|
|
17243
|
+
const slug = positional[0];
|
|
17244
|
+
if (!slug) {
|
|
17245
|
+
console.error("wayai admin template pull <slug> [--out DIR] [--json]");
|
|
17246
|
+
process.exit(1);
|
|
17247
|
+
}
|
|
17248
|
+
if (!TEMPLATE_SLUG_REGEX2.test(slug)) {
|
|
17249
|
+
console.error(`Invalid template slug: ${slug}`);
|
|
17250
|
+
process.exit(1);
|
|
17251
|
+
}
|
|
17252
|
+
let outDir;
|
|
17253
|
+
let jsonOutput = false;
|
|
17254
|
+
for (let i = 0; i < flagArgs.length; i++) {
|
|
17255
|
+
if (flagArgs[i] === "--json") {
|
|
17256
|
+
jsonOutput = true;
|
|
17257
|
+
continue;
|
|
17258
|
+
}
|
|
17259
|
+
if (flagArgs[i] === "--out") {
|
|
17260
|
+
outDir = flagArgs[++i];
|
|
17261
|
+
if (!outDir) {
|
|
17262
|
+
console.error("--out requires a value");
|
|
17263
|
+
process.exit(1);
|
|
17264
|
+
}
|
|
17265
|
+
continue;
|
|
17266
|
+
}
|
|
17267
|
+
console.error(`Unknown flag: ${flagArgs[i]}`);
|
|
17268
|
+
process.exit(1);
|
|
17269
|
+
}
|
|
17270
|
+
const { config, accessToken } = await requireAuth();
|
|
17271
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
17272
|
+
let detail;
|
|
17273
|
+
try {
|
|
17274
|
+
detail = await client.adminTemplatePull(slug);
|
|
17275
|
+
} catch (err) {
|
|
17276
|
+
exitOnApiError(err);
|
|
17277
|
+
throw err;
|
|
17278
|
+
}
|
|
17279
|
+
if (jsonOutput) {
|
|
17280
|
+
console.log(JSON.stringify(detail, null, 2));
|
|
17281
|
+
return;
|
|
17282
|
+
}
|
|
17283
|
+
const target = outDir ? path21.resolve(outDir) : path21.join(process.cwd(), "template-store-pull", slug);
|
|
17284
|
+
const written = writeFileMap(target, detail.files);
|
|
17285
|
+
console.log(`Pulled "${slug}" from the store \u2192 ${target} (${written.length} file${written.length === 1 ? "" : "s"}).`);
|
|
17286
|
+
console.log(`includes: wayai=${detail.includes.wayai} rekor=${detail.includes.rekor}`);
|
|
17287
|
+
}
|
|
17288
|
+
async function runSkillInstall(positional) {
|
|
17289
|
+
const name = positional[0] ?? "wayai-admin";
|
|
17290
|
+
if (!ADMIN_SKILL_NAME_REGEX2.test(name)) {
|
|
17291
|
+
console.error(`Invalid skill name: ${name}`);
|
|
17292
|
+
process.exit(1);
|
|
17293
|
+
}
|
|
17294
|
+
const { config, accessToken } = await requireAuth();
|
|
17295
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
17296
|
+
let res;
|
|
17297
|
+
try {
|
|
17298
|
+
res = await client.adminSkillInstall(name);
|
|
17299
|
+
} catch (err) {
|
|
17300
|
+
exitOnApiError(err);
|
|
17301
|
+
throw err;
|
|
17302
|
+
}
|
|
17303
|
+
const root = findGitRoot() ?? process.cwd();
|
|
17304
|
+
const targetDir = path21.join(root, ".claude", "skills", name);
|
|
17305
|
+
const written = writeFileMap(targetDir, res.files);
|
|
17306
|
+
console.log(`Installed skill "${name}" \u2192 ${path21.relative(root, targetDir)}/ (${written.length} file${written.length === 1 ? "" : "s"}).`);
|
|
17307
|
+
console.log("Reload your agent (e.g. restart Claude Code) to pick up the skill.");
|
|
17308
|
+
}
|
|
16616
17309
|
function exitOnApiError(err) {
|
|
16617
17310
|
if (err instanceof ApiError) {
|
|
16618
17311
|
if (err.status === 401) {
|
|
@@ -17024,6 +17717,11 @@ Usage:
|
|
|
17024
17717
|
wayai admin notice list [--status active|resolved] [--limit N] [--offset N] [--json]
|
|
17025
17718
|
wayai admin notice resolve <notice_id>
|
|
17026
17719
|
|
|
17720
|
+
wayai admin template push <slug> Publish a template from tutorials/templates/<slug>/ into the store
|
|
17721
|
+
wayai admin template pull <slug> [--out DIR] [--json] Pull a published template from the store for inspection
|
|
17722
|
+
|
|
17723
|
+
wayai admin skill install [name] Install a private operator skill (default: wayai-admin) into .claude/skills/
|
|
17724
|
+
|
|
17027
17725
|
Sources:
|
|
17028
17726
|
do Live DO SQLite (existing conversation, hub config, etc.).
|
|
17029
17727
|
analytics ClickHouse projections (conversation, message, billing_event, schedule_event).
|
|
@@ -17081,6 +17779,9 @@ var init_admin = __esm({
|
|
|
17081
17779
|
init_api_client();
|
|
17082
17780
|
init_observability();
|
|
17083
17781
|
init_report_edit_args();
|
|
17782
|
+
init_workspace();
|
|
17783
|
+
init_layout();
|
|
17784
|
+
init_template_files();
|
|
17084
17785
|
init_contracts();
|
|
17085
17786
|
VALID_TYPES = dataExplorerDebugDoType2.options;
|
|
17086
17787
|
VALID_ANALYTICS_TABLES = dataExplorerDebugAnalyticsTable2.options;
|
|
@@ -17089,12 +17790,12 @@ var init_admin = __esm({
|
|
|
17089
17790
|
});
|
|
17090
17791
|
|
|
17091
17792
|
// src/commands/report-create.ts
|
|
17092
|
-
import { readFileSync as
|
|
17093
|
-
import { dirname as
|
|
17793
|
+
import { readFileSync as readFileSync16 } from "fs";
|
|
17794
|
+
import { dirname as dirname8, join as join23 } from "path";
|
|
17094
17795
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
17095
17796
|
function getCliVersion() {
|
|
17096
17797
|
try {
|
|
17097
|
-
const pkg2 = JSON.parse(
|
|
17798
|
+
const pkg2 = JSON.parse(readFileSync16(join23(__dirname, "..", "..", "package.json"), "utf-8"));
|
|
17098
17799
|
return `cli@${pkg2.version}`;
|
|
17099
17800
|
} catch {
|
|
17100
17801
|
return "cli@unknown";
|
|
@@ -17201,7 +17902,7 @@ var init_report_create = __esm({
|
|
|
17201
17902
|
init_auth();
|
|
17202
17903
|
init_repo_config();
|
|
17203
17904
|
init_api_client();
|
|
17204
|
-
__dirname =
|
|
17905
|
+
__dirname = dirname8(fileURLToPath2(import.meta.url));
|
|
17205
17906
|
}
|
|
17206
17907
|
});
|
|
17207
17908
|
|
|
@@ -17476,9 +18177,9 @@ var init_update = __esm({
|
|
|
17476
18177
|
|
|
17477
18178
|
// src/index.ts
|
|
17478
18179
|
init_sentry();
|
|
17479
|
-
import { readFileSync as
|
|
18180
|
+
import { readFileSync as readFileSync17 } from "fs";
|
|
17480
18181
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
17481
|
-
import { dirname as
|
|
18182
|
+
import { dirname as dirname9, join as join24 } from "path";
|
|
17482
18183
|
|
|
17483
18184
|
// src/lib/errors.ts
|
|
17484
18185
|
init_api_client();
|
|
@@ -17503,7 +18204,7 @@ init_skill_version();
|
|
|
17503
18204
|
import { exec } from "child_process";
|
|
17504
18205
|
var REFRESH_TIMEOUT_MS = 1e4;
|
|
17505
18206
|
function refreshCliCache() {
|
|
17506
|
-
return new Promise((
|
|
18207
|
+
return new Promise((resolve5) => {
|
|
17507
18208
|
exec("npm view @wayai/cli version", { timeout: REFRESH_TIMEOUT_MS }, (err, stdout) => {
|
|
17508
18209
|
if (!err) {
|
|
17509
18210
|
const latest = stdout.trim();
|
|
@@ -17514,7 +18215,7 @@ function refreshCliCache() {
|
|
|
17514
18215
|
}
|
|
17515
18216
|
}
|
|
17516
18217
|
}
|
|
17517
|
-
|
|
18218
|
+
resolve5();
|
|
17518
18219
|
});
|
|
17519
18220
|
});
|
|
17520
18221
|
}
|
|
@@ -17606,8 +18307,8 @@ Run \`npx skills add wayai-pro/wayai-skill -y\` to update.`);
|
|
|
17606
18307
|
}
|
|
17607
18308
|
|
|
17608
18309
|
// src/index.ts
|
|
17609
|
-
var __dirname2 =
|
|
17610
|
-
var pkg = JSON.parse(
|
|
18310
|
+
var __dirname2 = dirname9(fileURLToPath3(import.meta.url));
|
|
18311
|
+
var pkg = JSON.parse(readFileSync17(join24(__dirname2, "..", "package.json"), "utf-8"));
|
|
17611
18312
|
var [, , command, ...args] = process.argv;
|
|
17612
18313
|
var isBackgroundRefresh = command === REFRESH_COMMAND;
|
|
17613
18314
|
if (!isBackgroundRefresh) initSentry(command);
|
|
@@ -17739,6 +18440,11 @@ async function main() {
|
|
|
17739
18440
|
await listCommand2(args);
|
|
17740
18441
|
break;
|
|
17741
18442
|
}
|
|
18443
|
+
case "template": {
|
|
18444
|
+
const { templateCommand: templateCommand2 } = await Promise.resolve().then(() => (init_templates(), templates_exports));
|
|
18445
|
+
await templateCommand2(args);
|
|
18446
|
+
break;
|
|
18447
|
+
}
|
|
17742
18448
|
case "admin": {
|
|
17743
18449
|
const { adminCommand: adminCommand2 } = await Promise.resolve().then(() => (init_admin(), admin_exports));
|
|
17744
18450
|
await adminCommand2(args);
|
|
@@ -17805,6 +18511,8 @@ Commands:
|
|
|
17805
18511
|
sync-skills Sync skills to Anthropic/OpenAI provider connections
|
|
17806
18512
|
sync-mcp Re-discover an MCP connection's tools (refresh stale schemas)
|
|
17807
18513
|
list List organizations and hubs
|
|
18514
|
+
template list List ready-made hub templates
|
|
18515
|
+
template pull Write a template's WayAI slice into wayai-ws/hubs/<slug>/
|
|
17808
18516
|
report create Report a platform bug (submits to the triage queue)
|
|
17809
18517
|
report edit Amend your own pending report (title/description/error/steps/context)
|
|
17810
18518
|
update Update CLI to the latest version
|