@wayai/cli 0.3.222 → 0.3.224
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 +1455 -623
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -488,6 +488,67 @@ var init_sentry = __esm({
|
|
|
488
488
|
}
|
|
489
489
|
});
|
|
490
490
|
|
|
491
|
+
// ../../packages/core/dist/chunk-DHPUPI4Y.js
|
|
492
|
+
function normalizeAuthType(raw) {
|
|
493
|
+
if (VALID_AUTH_TYPES.has(raw)) return raw;
|
|
494
|
+
return LEGACY_AUTH_TYPE_MAP[raw] ?? raw;
|
|
495
|
+
}
|
|
496
|
+
var AUTH_TYPE, ORG_CREDENTIAL_AUTH_TYPES, AUTH_TYPE_DISPLAY, LEGACY_AUTH_TYPE_MAP, VALID_AUTH_TYPES, AGENT_ROLES, PILOT_TRACK_ROLES, COPILOT_TRACK_ROLES, CUSTOMER_FACING_AGENT_ROLES, SAFE_USER_ID_REGEX, SUPPORTED_LOCALES, SKILL_INSTALL_COMMAND;
|
|
497
|
+
var init_chunk_DHPUPI4Y = __esm({
|
|
498
|
+
"../../packages/core/dist/chunk-DHPUPI4Y.js"() {
|
|
499
|
+
"use strict";
|
|
500
|
+
AUTH_TYPE = {
|
|
501
|
+
OAUTH: "oauth",
|
|
502
|
+
API_KEY: "api_key",
|
|
503
|
+
BASIC_AUTH: "basic_auth",
|
|
504
|
+
BEARER: "bearer",
|
|
505
|
+
NONE: "none"
|
|
506
|
+
};
|
|
507
|
+
ORG_CREDENTIAL_AUTH_TYPES = [
|
|
508
|
+
AUTH_TYPE.API_KEY,
|
|
509
|
+
AUTH_TYPE.BEARER,
|
|
510
|
+
AUTH_TYPE.BASIC_AUTH
|
|
511
|
+
];
|
|
512
|
+
AUTH_TYPE_DISPLAY = {
|
|
513
|
+
[AUTH_TYPE.OAUTH]: "OAuth",
|
|
514
|
+
[AUTH_TYPE.API_KEY]: "API Key",
|
|
515
|
+
[AUTH_TYPE.BASIC_AUTH]: "Basic Auth",
|
|
516
|
+
[AUTH_TYPE.BEARER]: "Bearer Token",
|
|
517
|
+
[AUTH_TYPE.NONE]: "No Authentication"
|
|
518
|
+
};
|
|
519
|
+
LEGACY_AUTH_TYPE_MAP = {
|
|
520
|
+
"OAuth": AUTH_TYPE.OAUTH,
|
|
521
|
+
"API Key": AUTH_TYPE.API_KEY,
|
|
522
|
+
"Basic Auth": AUTH_TYPE.BASIC_AUTH,
|
|
523
|
+
"Bearer Token": AUTH_TYPE.BEARER,
|
|
524
|
+
"No authentication": AUTH_TYPE.NONE,
|
|
525
|
+
// Also handle the old DISPLAY_TO_CODE bug where 'basic' was used instead of 'basic_auth'
|
|
526
|
+
"basic": AUTH_TYPE.BASIC_AUTH
|
|
527
|
+
};
|
|
528
|
+
VALID_AUTH_TYPES = new Set(Object.values(AUTH_TYPE));
|
|
529
|
+
AGENT_ROLES = [
|
|
530
|
+
"pilot",
|
|
531
|
+
"copilot",
|
|
532
|
+
"pilot_specialist",
|
|
533
|
+
"copilot_specialist",
|
|
534
|
+
"pilot_advisor",
|
|
535
|
+
"copilot_advisor",
|
|
536
|
+
"monitor",
|
|
537
|
+
"conversation_evaluator",
|
|
538
|
+
"message_evaluator",
|
|
539
|
+
"summarizer",
|
|
540
|
+
"consultant",
|
|
541
|
+
"pilot_voice"
|
|
542
|
+
];
|
|
543
|
+
PILOT_TRACK_ROLES = ["pilot", "pilot_specialist"];
|
|
544
|
+
COPILOT_TRACK_ROLES = ["copilot", "copilot_specialist"];
|
|
545
|
+
CUSTOMER_FACING_AGENT_ROLES = [...PILOT_TRACK_ROLES, "pilot_advisor"];
|
|
546
|
+
SAFE_USER_ID_REGEX = /^[A-Za-z0-9_-]{1,64}$/;
|
|
547
|
+
SUPPORTED_LOCALES = ["en", "pt", "es"];
|
|
548
|
+
SKILL_INSTALL_COMMAND = "mkdir -p .claude && npx skills add wayai-pro/wayai-skill -y";
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
|
|
491
552
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js
|
|
492
553
|
var util, objectUtil, ZodParsedType, getParsedType;
|
|
493
554
|
var init_util = __esm({
|
|
@@ -4604,6 +4665,146 @@ var init_zod = __esm({
|
|
|
4604
4665
|
}
|
|
4605
4666
|
});
|
|
4606
4667
|
|
|
4668
|
+
// ../../packages/core/dist/chunk-SXDX4GHS.js
|
|
4669
|
+
var orgCredentialIdParam, listOrgCredentialsQuery, createOrgCredentialBody, updateOrgCredentialBody;
|
|
4670
|
+
var init_chunk_SXDX4GHS = __esm({
|
|
4671
|
+
"../../packages/core/dist/chunk-SXDX4GHS.js"() {
|
|
4672
|
+
"use strict";
|
|
4673
|
+
init_chunk_DHPUPI4Y();
|
|
4674
|
+
init_zod();
|
|
4675
|
+
orgCredentialIdParam = external_exports.object({
|
|
4676
|
+
id: external_exports.string().uuid()
|
|
4677
|
+
});
|
|
4678
|
+
listOrgCredentialsQuery = external_exports.object({
|
|
4679
|
+
organization_id: external_exports.string().uuid(),
|
|
4680
|
+
hub_id: external_exports.string().uuid().optional()
|
|
4681
|
+
});
|
|
4682
|
+
createOrgCredentialBody = external_exports.object({
|
|
4683
|
+
organization_id: external_exports.string().uuid(),
|
|
4684
|
+
credential_display_name: external_exports.string().min(1).max(255),
|
|
4685
|
+
credential_description: external_exports.string().max(1e3).nullish(),
|
|
4686
|
+
authentication_type: external_exports.enum(["api_key", "bearer", "basic_auth"]).or(
|
|
4687
|
+
external_exports.enum(["API Key", "Bearer Token", "Basic Auth"]).transform((v) => normalizeAuthType(v))
|
|
4688
|
+
),
|
|
4689
|
+
api_key: external_exports.string().optional(),
|
|
4690
|
+
access_token: external_exports.string().optional(),
|
|
4691
|
+
username: external_exports.string().optional(),
|
|
4692
|
+
password: external_exports.string().optional(),
|
|
4693
|
+
tags: external_exports.array(external_exports.string().uuid()).optional(),
|
|
4694
|
+
environment: external_exports.enum(["preview", "production", "all"]).optional()
|
|
4695
|
+
});
|
|
4696
|
+
updateOrgCredentialBody = external_exports.object({
|
|
4697
|
+
credential_display_name: external_exports.string().min(1).max(255).optional(),
|
|
4698
|
+
credential_description: external_exports.string().max(1e3).nullish(),
|
|
4699
|
+
api_key: external_exports.string().optional(),
|
|
4700
|
+
access_token: external_exports.string().optional(),
|
|
4701
|
+
username: external_exports.string().optional(),
|
|
4702
|
+
password: external_exports.string().optional(),
|
|
4703
|
+
tags: external_exports.array(external_exports.string().uuid()).optional(),
|
|
4704
|
+
environment: external_exports.enum(["preview", "production", "all"]).optional()
|
|
4705
|
+
});
|
|
4706
|
+
}
|
|
4707
|
+
});
|
|
4708
|
+
|
|
4709
|
+
// ../../packages/core/dist/chunk-FK6HBXM7.js
|
|
4710
|
+
var orgResourceIdParam, orgResourceFileIdParam, orgResourceFolderIdParam, hubOrgResourceParam, listOrgResourcesQuery, orgIdQuery, createOrgResourceBody, updateOrgResourceBody, createOrgResourceFolderBody, updateOrgResourceFolderBody, uploadOrgResourceFileBody, updateOrgResourceFileBody, uploadOrgSkillZipBody, linkOrgResourceBody;
|
|
4711
|
+
var init_chunk_FK6HBXM7 = __esm({
|
|
4712
|
+
"../../packages/core/dist/chunk-FK6HBXM7.js"() {
|
|
4713
|
+
"use strict";
|
|
4714
|
+
init_zod();
|
|
4715
|
+
orgResourceIdParam = external_exports.object({
|
|
4716
|
+
id: external_exports.string().uuid()
|
|
4717
|
+
});
|
|
4718
|
+
orgResourceFileIdParam = external_exports.object({
|
|
4719
|
+
file_id: external_exports.string().uuid()
|
|
4720
|
+
});
|
|
4721
|
+
orgResourceFolderIdParam = external_exports.object({
|
|
4722
|
+
folder_id: external_exports.string().uuid()
|
|
4723
|
+
});
|
|
4724
|
+
hubOrgResourceParam = external_exports.object({
|
|
4725
|
+
id: external_exports.string().uuid(),
|
|
4726
|
+
org_resource_id: external_exports.string().uuid()
|
|
4727
|
+
});
|
|
4728
|
+
listOrgResourcesQuery = external_exports.object({
|
|
4729
|
+
organization_id: external_exports.string().uuid(),
|
|
4730
|
+
hub_id: external_exports.string().uuid().optional()
|
|
4731
|
+
});
|
|
4732
|
+
orgIdQuery = external_exports.object({
|
|
4733
|
+
organization_id: external_exports.string().uuid()
|
|
4734
|
+
});
|
|
4735
|
+
createOrgResourceBody = external_exports.object({
|
|
4736
|
+
organization_id: external_exports.string().uuid(),
|
|
4737
|
+
resource_name: external_exports.string().min(1).max(255),
|
|
4738
|
+
resource_description: external_exports.string().max(1e3).nullish(),
|
|
4739
|
+
resource_type: external_exports.enum(["knowledge", "skill"]).default("knowledge"),
|
|
4740
|
+
// Skill-only fields. Required for `resource_type = 'skill'` (validated in
|
|
4741
|
+
// the route layer since cross-field refinement complicates the inferred
|
|
4742
|
+
// input type for callers). Ignored for `knowledge`.
|
|
4743
|
+
skill_name: external_exports.string().min(1).max(255).nullish(),
|
|
4744
|
+
skill_version: external_exports.string().max(50).nullish(),
|
|
4745
|
+
folder_metadata_schema: external_exports.record(external_exports.unknown()).optional(),
|
|
4746
|
+
file_metadata_schema: external_exports.record(external_exports.unknown()).optional(),
|
|
4747
|
+
enabled: external_exports.boolean().optional(),
|
|
4748
|
+
tags: external_exports.array(external_exports.string().uuid()).optional(),
|
|
4749
|
+
environment: external_exports.enum(["preview", "production", "all"]).optional()
|
|
4750
|
+
});
|
|
4751
|
+
updateOrgResourceBody = external_exports.object({
|
|
4752
|
+
resource_name: external_exports.string().min(1).max(255).optional(),
|
|
4753
|
+
resource_description: external_exports.string().max(1e3).nullish(),
|
|
4754
|
+
skill_name: external_exports.string().min(1).max(255).nullish(),
|
|
4755
|
+
skill_version: external_exports.string().max(50).nullish(),
|
|
4756
|
+
folder_metadata_schema: external_exports.record(external_exports.unknown()).optional(),
|
|
4757
|
+
file_metadata_schema: external_exports.record(external_exports.unknown()).optional(),
|
|
4758
|
+
enabled: external_exports.boolean().optional(),
|
|
4759
|
+
tags: external_exports.array(external_exports.string().uuid()).optional(),
|
|
4760
|
+
environment: external_exports.enum(["preview", "production", "all"]).optional()
|
|
4761
|
+
});
|
|
4762
|
+
createOrgResourceFolderBody = external_exports.object({
|
|
4763
|
+
org_resource_id: external_exports.string().uuid(),
|
|
4764
|
+
folder_name: external_exports.string().min(1).max(255),
|
|
4765
|
+
folder_description: external_exports.string().max(1e3).nullish(),
|
|
4766
|
+
parent_folder_id: external_exports.string().uuid().nullish(),
|
|
4767
|
+
order_index: external_exports.number().int().nonnegative().optional(),
|
|
4768
|
+
enabled: external_exports.boolean().optional(),
|
|
4769
|
+
metadata: external_exports.record(external_exports.unknown()).optional()
|
|
4770
|
+
});
|
|
4771
|
+
updateOrgResourceFolderBody = external_exports.object({
|
|
4772
|
+
folder_name: external_exports.string().min(1).max(255).optional(),
|
|
4773
|
+
folder_description: external_exports.string().max(1e3).nullish(),
|
|
4774
|
+
parent_folder_id: external_exports.string().uuid().nullish(),
|
|
4775
|
+
order_index: external_exports.number().int().nonnegative().optional(),
|
|
4776
|
+
enabled: external_exports.boolean().optional(),
|
|
4777
|
+
metadata: external_exports.record(external_exports.unknown()).optional()
|
|
4778
|
+
});
|
|
4779
|
+
uploadOrgResourceFileBody = external_exports.object({
|
|
4780
|
+
org_resource_id: external_exports.string().uuid(),
|
|
4781
|
+
folder_id: external_exports.string().uuid().nullish(),
|
|
4782
|
+
file_name: external_exports.string().min(1).max(255),
|
|
4783
|
+
file_data: external_exports.string(),
|
|
4784
|
+
// base64
|
|
4785
|
+
mime_type: external_exports.string().optional(),
|
|
4786
|
+
file_size: external_exports.number().int().nonnegative().optional(),
|
|
4787
|
+
resource_file_tags: external_exports.array(external_exports.string()).optional(),
|
|
4788
|
+
metadata: external_exports.record(external_exports.unknown()).optional()
|
|
4789
|
+
});
|
|
4790
|
+
updateOrgResourceFileBody = external_exports.object({
|
|
4791
|
+
resource_file_title: external_exports.string().min(1).max(255).optional(),
|
|
4792
|
+
folder_id: external_exports.string().uuid().nullish(),
|
|
4793
|
+
order_index: external_exports.number().int().nonnegative().optional(),
|
|
4794
|
+
enabled: external_exports.boolean().optional(),
|
|
4795
|
+
resource_file_tags: external_exports.array(external_exports.string()).optional(),
|
|
4796
|
+
metadata: external_exports.record(external_exports.unknown()).optional()
|
|
4797
|
+
});
|
|
4798
|
+
uploadOrgSkillZipBody = external_exports.object({
|
|
4799
|
+
zip_data: external_exports.string().min(1),
|
|
4800
|
+
replace_existing: external_exports.boolean().optional()
|
|
4801
|
+
});
|
|
4802
|
+
linkOrgResourceBody = external_exports.object({
|
|
4803
|
+
org_resource_id: external_exports.string().uuid()
|
|
4804
|
+
});
|
|
4805
|
+
}
|
|
4806
|
+
});
|
|
4807
|
+
|
|
4607
4808
|
// ../../packages/core/dist/chunk-VXEAR36B.js
|
|
4608
4809
|
var orgTagIdParam, listOrgTagsQuery, ORG_TAG_NAME_REGEX, ORG_TAG_NAME_MAX_LENGTH, createOrgTagBody, updateOrgTagBody;
|
|
4609
4810
|
var init_chunk_VXEAR36B = __esm({
|
|
@@ -4912,10 +5113,10 @@ var init_chunk_Q7KIQHAZ = __esm({
|
|
|
4912
5113
|
}
|
|
4913
5114
|
});
|
|
4914
5115
|
|
|
4915
|
-
// ../../packages/core/dist/chunk-
|
|
5116
|
+
// ../../packages/core/dist/chunk-QUGQIL47.js
|
|
4916
5117
|
var connectionIdParam, connectorIdParam, listConnectionsQuery, deleteConnectionQuery, addConnectionBody, editConnectionBody, PRODUCTION_DIRECT_FIELDS, setProductionCredentialBody, registerWhatsappQuery, registerWhatsappBody, retryProvisioningQuery, resendDomainStatusQuery;
|
|
4917
|
-
var
|
|
4918
|
-
"../../packages/core/dist/chunk-
|
|
5118
|
+
var init_chunk_QUGQIL47 = __esm({
|
|
5119
|
+
"../../packages/core/dist/chunk-QUGQIL47.js"() {
|
|
4919
5120
|
"use strict";
|
|
4920
5121
|
init_chunk_HZ6CADSY();
|
|
4921
5122
|
init_zod();
|
|
@@ -4959,8 +5160,10 @@ var init_chunk_2U4BTOR7 = __esm({
|
|
|
4959
5160
|
webhook_signing_secret: external_exports.string().optional()
|
|
4960
5161
|
}).strict().superRefine((data, ctx) => {
|
|
4961
5162
|
const hasOrgLink = !!data.organization_credential_id || !!data.organization_credential_token_id;
|
|
4962
|
-
const
|
|
4963
|
-
|
|
5163
|
+
const sets = (f) => data[f] != null && data[f] !== `__USE_EXISTING_${f.toUpperCase()}__`;
|
|
5164
|
+
const hasDirect = PRODUCTION_DIRECT_FIELDS.some(sets);
|
|
5165
|
+
const hasDirectBesideLink = PRODUCTION_DIRECT_FIELDS.some((f) => f !== "webhook_secret_token" && sets(f));
|
|
5166
|
+
if (hasOrgLink && hasDirectBesideLink) {
|
|
4964
5167
|
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "Provide either an organization credential link or direct credential fields, not both" });
|
|
4965
5168
|
}
|
|
4966
5169
|
if (!hasOrgLink && !hasDirect) {
|
|
@@ -5082,207 +5285,6 @@ var init_chunk_GK27ENTT = __esm({
|
|
|
5082
5285
|
}
|
|
5083
5286
|
});
|
|
5084
5287
|
|
|
5085
|
-
// ../../packages/core/dist/chunk-DHPUPI4Y.js
|
|
5086
|
-
function normalizeAuthType(raw) {
|
|
5087
|
-
if (VALID_AUTH_TYPES.has(raw)) return raw;
|
|
5088
|
-
return LEGACY_AUTH_TYPE_MAP[raw] ?? raw;
|
|
5089
|
-
}
|
|
5090
|
-
var AUTH_TYPE, ORG_CREDENTIAL_AUTH_TYPES, AUTH_TYPE_DISPLAY, LEGACY_AUTH_TYPE_MAP, VALID_AUTH_TYPES, AGENT_ROLES, PILOT_TRACK_ROLES, COPILOT_TRACK_ROLES, CUSTOMER_FACING_AGENT_ROLES, SAFE_USER_ID_REGEX, SUPPORTED_LOCALES, SKILL_INSTALL_COMMAND;
|
|
5091
|
-
var init_chunk_DHPUPI4Y = __esm({
|
|
5092
|
-
"../../packages/core/dist/chunk-DHPUPI4Y.js"() {
|
|
5093
|
-
"use strict";
|
|
5094
|
-
AUTH_TYPE = {
|
|
5095
|
-
OAUTH: "oauth",
|
|
5096
|
-
API_KEY: "api_key",
|
|
5097
|
-
BASIC_AUTH: "basic_auth",
|
|
5098
|
-
BEARER: "bearer",
|
|
5099
|
-
NONE: "none"
|
|
5100
|
-
};
|
|
5101
|
-
ORG_CREDENTIAL_AUTH_TYPES = [
|
|
5102
|
-
AUTH_TYPE.API_KEY,
|
|
5103
|
-
AUTH_TYPE.BEARER,
|
|
5104
|
-
AUTH_TYPE.BASIC_AUTH
|
|
5105
|
-
];
|
|
5106
|
-
AUTH_TYPE_DISPLAY = {
|
|
5107
|
-
[AUTH_TYPE.OAUTH]: "OAuth",
|
|
5108
|
-
[AUTH_TYPE.API_KEY]: "API Key",
|
|
5109
|
-
[AUTH_TYPE.BASIC_AUTH]: "Basic Auth",
|
|
5110
|
-
[AUTH_TYPE.BEARER]: "Bearer Token",
|
|
5111
|
-
[AUTH_TYPE.NONE]: "No Authentication"
|
|
5112
|
-
};
|
|
5113
|
-
LEGACY_AUTH_TYPE_MAP = {
|
|
5114
|
-
"OAuth": AUTH_TYPE.OAUTH,
|
|
5115
|
-
"API Key": AUTH_TYPE.API_KEY,
|
|
5116
|
-
"Basic Auth": AUTH_TYPE.BASIC_AUTH,
|
|
5117
|
-
"Bearer Token": AUTH_TYPE.BEARER,
|
|
5118
|
-
"No authentication": AUTH_TYPE.NONE,
|
|
5119
|
-
// Also handle the old DISPLAY_TO_CODE bug where 'basic' was used instead of 'basic_auth'
|
|
5120
|
-
"basic": AUTH_TYPE.BASIC_AUTH
|
|
5121
|
-
};
|
|
5122
|
-
VALID_AUTH_TYPES = new Set(Object.values(AUTH_TYPE));
|
|
5123
|
-
AGENT_ROLES = [
|
|
5124
|
-
"pilot",
|
|
5125
|
-
"copilot",
|
|
5126
|
-
"pilot_specialist",
|
|
5127
|
-
"copilot_specialist",
|
|
5128
|
-
"pilot_advisor",
|
|
5129
|
-
"copilot_advisor",
|
|
5130
|
-
"monitor",
|
|
5131
|
-
"conversation_evaluator",
|
|
5132
|
-
"message_evaluator",
|
|
5133
|
-
"summarizer",
|
|
5134
|
-
"consultant",
|
|
5135
|
-
"pilot_voice"
|
|
5136
|
-
];
|
|
5137
|
-
PILOT_TRACK_ROLES = ["pilot", "pilot_specialist"];
|
|
5138
|
-
COPILOT_TRACK_ROLES = ["copilot", "copilot_specialist"];
|
|
5139
|
-
CUSTOMER_FACING_AGENT_ROLES = [...PILOT_TRACK_ROLES, "pilot_advisor"];
|
|
5140
|
-
SAFE_USER_ID_REGEX = /^[A-Za-z0-9_-]{1,64}$/;
|
|
5141
|
-
SUPPORTED_LOCALES = ["en", "pt", "es"];
|
|
5142
|
-
SKILL_INSTALL_COMMAND = "mkdir -p .claude && npx skills add wayai-pro/wayai-skill -y";
|
|
5143
|
-
}
|
|
5144
|
-
});
|
|
5145
|
-
|
|
5146
|
-
// ../../packages/core/dist/chunk-SXDX4GHS.js
|
|
5147
|
-
var orgCredentialIdParam, listOrgCredentialsQuery, createOrgCredentialBody, updateOrgCredentialBody;
|
|
5148
|
-
var init_chunk_SXDX4GHS = __esm({
|
|
5149
|
-
"../../packages/core/dist/chunk-SXDX4GHS.js"() {
|
|
5150
|
-
"use strict";
|
|
5151
|
-
init_chunk_DHPUPI4Y();
|
|
5152
|
-
init_zod();
|
|
5153
|
-
orgCredentialIdParam = external_exports.object({
|
|
5154
|
-
id: external_exports.string().uuid()
|
|
5155
|
-
});
|
|
5156
|
-
listOrgCredentialsQuery = external_exports.object({
|
|
5157
|
-
organization_id: external_exports.string().uuid(),
|
|
5158
|
-
hub_id: external_exports.string().uuid().optional()
|
|
5159
|
-
});
|
|
5160
|
-
createOrgCredentialBody = external_exports.object({
|
|
5161
|
-
organization_id: external_exports.string().uuid(),
|
|
5162
|
-
credential_display_name: external_exports.string().min(1).max(255),
|
|
5163
|
-
credential_description: external_exports.string().max(1e3).nullish(),
|
|
5164
|
-
authentication_type: external_exports.enum(["api_key", "bearer", "basic_auth"]).or(
|
|
5165
|
-
external_exports.enum(["API Key", "Bearer Token", "Basic Auth"]).transform((v) => normalizeAuthType(v))
|
|
5166
|
-
),
|
|
5167
|
-
api_key: external_exports.string().optional(),
|
|
5168
|
-
access_token: external_exports.string().optional(),
|
|
5169
|
-
username: external_exports.string().optional(),
|
|
5170
|
-
password: external_exports.string().optional(),
|
|
5171
|
-
tags: external_exports.array(external_exports.string().uuid()).optional(),
|
|
5172
|
-
environment: external_exports.enum(["preview", "production", "all"]).optional()
|
|
5173
|
-
});
|
|
5174
|
-
updateOrgCredentialBody = external_exports.object({
|
|
5175
|
-
credential_display_name: external_exports.string().min(1).max(255).optional(),
|
|
5176
|
-
credential_description: external_exports.string().max(1e3).nullish(),
|
|
5177
|
-
api_key: external_exports.string().optional(),
|
|
5178
|
-
access_token: external_exports.string().optional(),
|
|
5179
|
-
username: external_exports.string().optional(),
|
|
5180
|
-
password: external_exports.string().optional(),
|
|
5181
|
-
tags: external_exports.array(external_exports.string().uuid()).optional(),
|
|
5182
|
-
environment: external_exports.enum(["preview", "production", "all"]).optional()
|
|
5183
|
-
});
|
|
5184
|
-
}
|
|
5185
|
-
});
|
|
5186
|
-
|
|
5187
|
-
// ../../packages/core/dist/chunk-FK6HBXM7.js
|
|
5188
|
-
var orgResourceIdParam, orgResourceFileIdParam, orgResourceFolderIdParam, hubOrgResourceParam, listOrgResourcesQuery, orgIdQuery, createOrgResourceBody, updateOrgResourceBody, createOrgResourceFolderBody, updateOrgResourceFolderBody, uploadOrgResourceFileBody, updateOrgResourceFileBody, uploadOrgSkillZipBody, linkOrgResourceBody;
|
|
5189
|
-
var init_chunk_FK6HBXM7 = __esm({
|
|
5190
|
-
"../../packages/core/dist/chunk-FK6HBXM7.js"() {
|
|
5191
|
-
"use strict";
|
|
5192
|
-
init_zod();
|
|
5193
|
-
orgResourceIdParam = external_exports.object({
|
|
5194
|
-
id: external_exports.string().uuid()
|
|
5195
|
-
});
|
|
5196
|
-
orgResourceFileIdParam = external_exports.object({
|
|
5197
|
-
file_id: external_exports.string().uuid()
|
|
5198
|
-
});
|
|
5199
|
-
orgResourceFolderIdParam = external_exports.object({
|
|
5200
|
-
folder_id: external_exports.string().uuid()
|
|
5201
|
-
});
|
|
5202
|
-
hubOrgResourceParam = external_exports.object({
|
|
5203
|
-
id: external_exports.string().uuid(),
|
|
5204
|
-
org_resource_id: external_exports.string().uuid()
|
|
5205
|
-
});
|
|
5206
|
-
listOrgResourcesQuery = external_exports.object({
|
|
5207
|
-
organization_id: external_exports.string().uuid(),
|
|
5208
|
-
hub_id: external_exports.string().uuid().optional()
|
|
5209
|
-
});
|
|
5210
|
-
orgIdQuery = external_exports.object({
|
|
5211
|
-
organization_id: external_exports.string().uuid()
|
|
5212
|
-
});
|
|
5213
|
-
createOrgResourceBody = external_exports.object({
|
|
5214
|
-
organization_id: external_exports.string().uuid(),
|
|
5215
|
-
resource_name: external_exports.string().min(1).max(255),
|
|
5216
|
-
resource_description: external_exports.string().max(1e3).nullish(),
|
|
5217
|
-
resource_type: external_exports.enum(["knowledge", "skill"]).default("knowledge"),
|
|
5218
|
-
// Skill-only fields. Required for `resource_type = 'skill'` (validated in
|
|
5219
|
-
// the route layer since cross-field refinement complicates the inferred
|
|
5220
|
-
// input type for callers). Ignored for `knowledge`.
|
|
5221
|
-
skill_name: external_exports.string().min(1).max(255).nullish(),
|
|
5222
|
-
skill_version: external_exports.string().max(50).nullish(),
|
|
5223
|
-
folder_metadata_schema: external_exports.record(external_exports.unknown()).optional(),
|
|
5224
|
-
file_metadata_schema: external_exports.record(external_exports.unknown()).optional(),
|
|
5225
|
-
enabled: external_exports.boolean().optional(),
|
|
5226
|
-
tags: external_exports.array(external_exports.string().uuid()).optional(),
|
|
5227
|
-
environment: external_exports.enum(["preview", "production", "all"]).optional()
|
|
5228
|
-
});
|
|
5229
|
-
updateOrgResourceBody = external_exports.object({
|
|
5230
|
-
resource_name: external_exports.string().min(1).max(255).optional(),
|
|
5231
|
-
resource_description: external_exports.string().max(1e3).nullish(),
|
|
5232
|
-
skill_name: external_exports.string().min(1).max(255).nullish(),
|
|
5233
|
-
skill_version: external_exports.string().max(50).nullish(),
|
|
5234
|
-
folder_metadata_schema: external_exports.record(external_exports.unknown()).optional(),
|
|
5235
|
-
file_metadata_schema: external_exports.record(external_exports.unknown()).optional(),
|
|
5236
|
-
enabled: external_exports.boolean().optional(),
|
|
5237
|
-
tags: external_exports.array(external_exports.string().uuid()).optional(),
|
|
5238
|
-
environment: external_exports.enum(["preview", "production", "all"]).optional()
|
|
5239
|
-
});
|
|
5240
|
-
createOrgResourceFolderBody = external_exports.object({
|
|
5241
|
-
org_resource_id: external_exports.string().uuid(),
|
|
5242
|
-
folder_name: external_exports.string().min(1).max(255),
|
|
5243
|
-
folder_description: external_exports.string().max(1e3).nullish(),
|
|
5244
|
-
parent_folder_id: external_exports.string().uuid().nullish(),
|
|
5245
|
-
order_index: external_exports.number().int().nonnegative().optional(),
|
|
5246
|
-
enabled: external_exports.boolean().optional(),
|
|
5247
|
-
metadata: external_exports.record(external_exports.unknown()).optional()
|
|
5248
|
-
});
|
|
5249
|
-
updateOrgResourceFolderBody = external_exports.object({
|
|
5250
|
-
folder_name: external_exports.string().min(1).max(255).optional(),
|
|
5251
|
-
folder_description: external_exports.string().max(1e3).nullish(),
|
|
5252
|
-
parent_folder_id: external_exports.string().uuid().nullish(),
|
|
5253
|
-
order_index: external_exports.number().int().nonnegative().optional(),
|
|
5254
|
-
enabled: external_exports.boolean().optional(),
|
|
5255
|
-
metadata: external_exports.record(external_exports.unknown()).optional()
|
|
5256
|
-
});
|
|
5257
|
-
uploadOrgResourceFileBody = external_exports.object({
|
|
5258
|
-
org_resource_id: external_exports.string().uuid(),
|
|
5259
|
-
folder_id: external_exports.string().uuid().nullish(),
|
|
5260
|
-
file_name: external_exports.string().min(1).max(255),
|
|
5261
|
-
file_data: external_exports.string(),
|
|
5262
|
-
// base64
|
|
5263
|
-
mime_type: external_exports.string().optional(),
|
|
5264
|
-
file_size: external_exports.number().int().nonnegative().optional(),
|
|
5265
|
-
resource_file_tags: external_exports.array(external_exports.string()).optional(),
|
|
5266
|
-
metadata: external_exports.record(external_exports.unknown()).optional()
|
|
5267
|
-
});
|
|
5268
|
-
updateOrgResourceFileBody = external_exports.object({
|
|
5269
|
-
resource_file_title: external_exports.string().min(1).max(255).optional(),
|
|
5270
|
-
folder_id: external_exports.string().uuid().nullish(),
|
|
5271
|
-
order_index: external_exports.number().int().nonnegative().optional(),
|
|
5272
|
-
enabled: external_exports.boolean().optional(),
|
|
5273
|
-
resource_file_tags: external_exports.array(external_exports.string()).optional(),
|
|
5274
|
-
metadata: external_exports.record(external_exports.unknown()).optional()
|
|
5275
|
-
});
|
|
5276
|
-
uploadOrgSkillZipBody = external_exports.object({
|
|
5277
|
-
zip_data: external_exports.string().min(1),
|
|
5278
|
-
replace_existing: external_exports.boolean().optional()
|
|
5279
|
-
});
|
|
5280
|
-
linkOrgResourceBody = external_exports.object({
|
|
5281
|
-
org_resource_id: external_exports.string().uuid()
|
|
5282
|
-
});
|
|
5283
|
-
}
|
|
5284
|
-
});
|
|
5285
|
-
|
|
5286
5288
|
// ../../packages/core/dist/chunk-GPM7PE44.js
|
|
5287
5289
|
var bootstrapQuery;
|
|
5288
5290
|
var init_chunk_GPM7PE44 = __esm({
|
|
@@ -5517,6 +5519,34 @@ var init_chunk_ZVXO3XL6 = __esm({
|
|
|
5517
5519
|
}
|
|
5518
5520
|
});
|
|
5519
5521
|
|
|
5522
|
+
// ../../packages/core/dist/chunk-ZXK6N2HN.js
|
|
5523
|
+
var PEOPLE_MODERATION_NOTE_MAX_LENGTH, ADMIN_PEOPLE_REPORTS_PAGE_MAX, ADMIN_PEOPLE_REPORTS_PAGE_DEFAULT, PEOPLE_SUSPENDED_REASON, peopleModerationActionSchema, moderationNoteSchema, adminPeopleReportListQuery, adminPeopleReportIdParam, adminPeopleMessageRemovalBody, adminPeopleSuspendBody, adminPeopleNoteBody;
|
|
5524
|
+
var init_chunk_ZXK6N2HN = __esm({
|
|
5525
|
+
"../../packages/core/dist/chunk-ZXK6N2HN.js"() {
|
|
5526
|
+
"use strict";
|
|
5527
|
+
init_chunk_ZVXO3XL6();
|
|
5528
|
+
init_chunk_HZ6CADSY();
|
|
5529
|
+
init_zod();
|
|
5530
|
+
PEOPLE_MODERATION_NOTE_MAX_LENGTH = 500;
|
|
5531
|
+
ADMIN_PEOPLE_REPORTS_PAGE_MAX = 100;
|
|
5532
|
+
ADMIN_PEOPLE_REPORTS_PAGE_DEFAULT = 50;
|
|
5533
|
+
PEOPLE_SUSPENDED_REASON = "suspended";
|
|
5534
|
+
peopleModerationActionSchema = external_exports.enum(["remove_message", "suspend", "unsuspend", "dismiss"]);
|
|
5535
|
+
moderationNoteSchema = optionalTrimmedText(PEOPLE_MODERATION_NOTE_MAX_LENGTH);
|
|
5536
|
+
adminPeopleReportListQuery = external_exports.object({
|
|
5537
|
+
pending: external_exports.enum(["true", "false"]).optional().transform((value) => value === "true"),
|
|
5538
|
+
/** Lower bound on `created_at`. */
|
|
5539
|
+
since: timestampSchema.optional(),
|
|
5540
|
+
limit: external_exports.coerce.number().int().min(1).max(ADMIN_PEOPLE_REPORTS_PAGE_MAX).default(ADMIN_PEOPLE_REPORTS_PAGE_DEFAULT),
|
|
5541
|
+
offset: external_exports.coerce.number().int().min(0).default(0)
|
|
5542
|
+
});
|
|
5543
|
+
adminPeopleReportIdParam = external_exports.object({ reportId: uuidSchema });
|
|
5544
|
+
adminPeopleMessageRemovalBody = external_exports.object({ report_id: uuidSchema, message_id: uuidSchema.optional(), note: moderationNoteSchema }).strict();
|
|
5545
|
+
adminPeopleSuspendBody = external_exports.object({ report_id: uuidSchema.optional(), note: moderationNoteSchema }).strict();
|
|
5546
|
+
adminPeopleNoteBody = external_exports.object({ note: moderationNoteSchema }).strict();
|
|
5547
|
+
}
|
|
5548
|
+
});
|
|
5549
|
+
|
|
5520
5550
|
// ../../packages/core/dist/chunk-Y7CFCYX4.js
|
|
5521
5551
|
var PEOPLE_REPORT_DETAILS_MAX_LENGTH, peopleReportReasonSchema, reportDetailsSchema, reportFields, peopleReportBody;
|
|
5522
5552
|
var init_chunk_Y7CFCYX4 = __esm({
|
|
@@ -5572,10 +5602,10 @@ var init_chunk_5DGHIY7L = __esm({
|
|
|
5572
5602
|
}
|
|
5573
5603
|
});
|
|
5574
5604
|
|
|
5575
|
-
// ../../packages/core/dist/chunk-
|
|
5576
|
-
var DATA_PROXY_MOUNT, DATA_PROXY_PREFIX, BASE_DESTRUCTION_MOUNT, BASE_DESTRUCTION_PREFIX, BASE_DESTRUCTION_CONFIRM_PATH, COMMUNITY_EMAIL_UNSUBSCRIBE_PATH, CONTACT_BOOK_EMAIL_UNSUBSCRIBE_PATH, AUTOMATION_WEBHOOK_MOUNT;
|
|
5577
|
-
var
|
|
5578
|
-
"../../packages/core/dist/chunk-
|
|
5605
|
+
// ../../packages/core/dist/chunk-5XEJSR22.js
|
|
5606
|
+
var DATA_PROXY_MOUNT, DATA_PROXY_PREFIX, BASE_DESTRUCTION_MOUNT, BASE_DESTRUCTION_PREFIX, BASE_DESTRUCTION_CONFIRM_PATH, COMMUNITY_EMAIL_UNSUBSCRIBE_PATH, CONTACT_BOOK_EMAIL_UNSUBSCRIBE_PATH, AUTOMATION_WEBHOOK_MOUNT, MANAGED_AGENTS_WEBHOOK_MOUNT;
|
|
5607
|
+
var init_chunk_5XEJSR22 = __esm({
|
|
5608
|
+
"../../packages/core/dist/chunk-5XEJSR22.js"() {
|
|
5579
5609
|
"use strict";
|
|
5580
5610
|
DATA_PROXY_MOUNT = "/data";
|
|
5581
5611
|
DATA_PROXY_PREFIX = `/api${DATA_PROXY_MOUNT}`;
|
|
@@ -5585,10 +5615,11 @@ var init_chunk_F3JHI4Y4 = __esm({
|
|
|
5585
5615
|
COMMUNITY_EMAIL_UNSUBSCRIBE_PATH = "/api/communities/email-unsubscribe";
|
|
5586
5616
|
CONTACT_BOOK_EMAIL_UNSUBSCRIBE_PATH = "/api/contact-book/email-unsubscribe";
|
|
5587
5617
|
AUTOMATION_WEBHOOK_MOUNT = "/webhooks/automations";
|
|
5618
|
+
MANAGED_AGENTS_WEBHOOK_MOUNT = "/webhooks/managed-agents";
|
|
5588
5619
|
}
|
|
5589
5620
|
});
|
|
5590
5621
|
|
|
5591
|
-
// ../../packages/core/dist/chunk-
|
|
5622
|
+
// ../../packages/core/dist/chunk-ISFDR7SP.js
|
|
5592
5623
|
function matchPath(pattern, path42) {
|
|
5593
5624
|
const normalizedPath = path42.replace(/\/$/, "");
|
|
5594
5625
|
if (pattern.endsWith("/*")) {
|
|
@@ -5616,10 +5647,10 @@ function getEndpointConfig(path42) {
|
|
|
5616
5647
|
return { tier: "STANDARD" };
|
|
5617
5648
|
}
|
|
5618
5649
|
var ENDPOINT_CONFIGS, EXCLUDED_PATHS;
|
|
5619
|
-
var
|
|
5620
|
-
"../../packages/core/dist/chunk-
|
|
5650
|
+
var init_chunk_ISFDR7SP = __esm({
|
|
5651
|
+
"../../packages/core/dist/chunk-ISFDR7SP.js"() {
|
|
5621
5652
|
"use strict";
|
|
5622
|
-
|
|
5653
|
+
init_chunk_5XEJSR22();
|
|
5623
5654
|
ENDPOINT_CONFIGS = {
|
|
5624
5655
|
// OAuth callbacks - strict, fail-closed (prevent brute force)
|
|
5625
5656
|
"/oauth/callback/*": { tier: "STRICT", failClosed: true },
|
|
@@ -5774,6 +5805,8 @@ var init_chunk_IEWJ5MZH = __esm({
|
|
|
5774
5805
|
// platform's egress addresses carry many tenants' deliveries. The per-automation budget is
|
|
5775
5806
|
// `AUTOMATION_WEBHOOK_PER_AUTOMATION_LIMIT`, counted after the delivery is verified.
|
|
5776
5807
|
[`${AUTOMATION_WEBHOOK_MOUNT}/*`]: { tier: "HIGH" },
|
|
5808
|
+
// Managed Agents session events (#5083 Phase 4): HIGH, one vendor address carries many tenants'.
|
|
5809
|
+
[`${MANAGED_AGENTS_WEBHOOK_MOUNT}/*`]: { tier: "HIGH" },
|
|
5777
5810
|
// Reports (CLI → platform_report triage queue). One per-user budget covers intake
|
|
5778
5811
|
// (POST), the content edit (PATCH /:id), the reporter read-back (GET, GET /:id), and the
|
|
5779
5812
|
// verification loop (POST /:id/accept, /:id/contest). The limiter is path-based, so a
|
|
@@ -6082,7 +6115,7 @@ var init_chunk_IEWJ5MZH = __esm({
|
|
|
6082
6115
|
}
|
|
6083
6116
|
});
|
|
6084
6117
|
|
|
6085
|
-
// ../../packages/core/dist/chunk-
|
|
6118
|
+
// ../../packages/core/dist/chunk-FNNHGL7K.js
|
|
6086
6119
|
function fileSnapshotChanged(run) {
|
|
6087
6120
|
return run.written + run.removed > 0;
|
|
6088
6121
|
}
|
|
@@ -6123,11 +6156,11 @@ async function sendWithRetry(opts, cursor) {
|
|
|
6123
6156
|
}
|
|
6124
6157
|
}
|
|
6125
6158
|
var rekorFileSnapshotAnswerSchema, FILE_SNAPSHOT_MAX_PAGES, FILE_SNAPSHOT_CONFLICT_ATTEMPTS, FILE_SNAPSHOT_PAGE_SPACING_MS, FILE_SNAPSHOT_CONFLICT_STATUS;
|
|
6126
|
-
var
|
|
6127
|
-
"../../packages/core/dist/chunk-
|
|
6159
|
+
var init_chunk_FNNHGL7K = __esm({
|
|
6160
|
+
"../../packages/core/dist/chunk-FNNHGL7K.js"() {
|
|
6128
6161
|
"use strict";
|
|
6129
|
-
|
|
6130
|
-
|
|
6162
|
+
init_chunk_ISFDR7SP();
|
|
6163
|
+
init_chunk_5XEJSR22();
|
|
6131
6164
|
init_zod();
|
|
6132
6165
|
rekorFileSnapshotAnswerSchema = external_exports.object({
|
|
6133
6166
|
data: external_exports.object({
|
|
@@ -6193,13 +6226,19 @@ var init_chunk_BEOHBREG = __esm({
|
|
|
6193
6226
|
});
|
|
6194
6227
|
|
|
6195
6228
|
// ../../packages/core/dist/chunk-4MRBBR5L.js
|
|
6196
|
-
|
|
6229
|
+
function toolsetFileToolName(entry, op) {
|
|
6230
|
+
const names = entry.names;
|
|
6231
|
+
const stated = names?.[op];
|
|
6232
|
+
return stated !== void 0 && stated !== null ? String(stated) : `${op}_${entry.name ?? entry.file_type}`;
|
|
6233
|
+
}
|
|
6234
|
+
var TOOLSET_SLUG_SETTING, TOOLSET_SLUG_PATTERN, REKOR_STRUCTURAL_ID_PATTERN, baseEnvironmentSchema, TOOLSET_FILE_OPERATIONS, toolsetFileToolSchema, toolsetSurfaceSchema, toolsetConnectionBindingSchema, rekorToolsetToolsSchema, rekorBoundAttestation, rekorResolvedToolsetSchema, resolvedFileToolSchema, rekorToolsetFileSchema, rekorToolsetFileListSchema, rekorToolsetFileGetSchema, rekorToolsetFilePutSchema, TOOLSET_CUSTOMER_FACING_REFUSAL_MARK, TOOLSET_CUSTOMER_FACING_REFUSAL;
|
|
6197
6235
|
var init_chunk_4MRBBR5L = __esm({
|
|
6198
6236
|
"../../packages/core/dist/chunk-4MRBBR5L.js"() {
|
|
6199
6237
|
"use strict";
|
|
6200
6238
|
init_chunk_BEOHBREG();
|
|
6201
6239
|
init_chunk_DHPUPI4Y();
|
|
6202
6240
|
init_zod();
|
|
6241
|
+
TOOLSET_SLUG_SETTING = "toolset";
|
|
6203
6242
|
TOOLSET_SLUG_PATTERN = /^[A-Za-z0-9_-]{1,128}$/;
|
|
6204
6243
|
REKOR_STRUCTURAL_ID_PATTERN = TOOLSET_SLUG_PATTERN;
|
|
6205
6244
|
baseEnvironmentSchema = external_exports.enum(["preview", "production"]);
|
|
@@ -6525,6 +6564,20 @@ var init_chunk_YUZFHVB2 = __esm({
|
|
|
6525
6564
|
}
|
|
6526
6565
|
});
|
|
6527
6566
|
|
|
6567
|
+
// ../../packages/core/dist/chunk-I3O2RACG.js
|
|
6568
|
+
var managedAgentsWebhookParams, MANAGED_AGENTS_WEBHOOK_BODY_MAX_BYTES;
|
|
6569
|
+
var init_chunk_I3O2RACG = __esm({
|
|
6570
|
+
"../../packages/core/dist/chunk-I3O2RACG.js"() {
|
|
6571
|
+
"use strict";
|
|
6572
|
+
init_zod();
|
|
6573
|
+
managedAgentsWebhookParams = external_exports.object({
|
|
6574
|
+
hub_id: external_exports.string().uuid(),
|
|
6575
|
+
connection_id: external_exports.string().uuid()
|
|
6576
|
+
});
|
|
6577
|
+
MANAGED_AGENTS_WEBHOOK_BODY_MAX_BYTES = 16 * 1024;
|
|
6578
|
+
}
|
|
6579
|
+
});
|
|
6580
|
+
|
|
6528
6581
|
// ../../packages/core/dist/chunk-34LE6P7E.js
|
|
6529
6582
|
var templateIdParam, listTemplatesQuery, deleteTemplateQuery, templateStatusQuery, createTemplateBody, updateTemplateBody, submitTemplateBody, testTemplateBody;
|
|
6530
6583
|
var init_chunk_34LE6P7E = __esm({
|
|
@@ -6600,34 +6653,6 @@ var init_chunk_FPSDNS2E = __esm({
|
|
|
6600
6653
|
}
|
|
6601
6654
|
});
|
|
6602
6655
|
|
|
6603
|
-
// ../../packages/core/dist/chunk-ZXK6N2HN.js
|
|
6604
|
-
var PEOPLE_MODERATION_NOTE_MAX_LENGTH, ADMIN_PEOPLE_REPORTS_PAGE_MAX, ADMIN_PEOPLE_REPORTS_PAGE_DEFAULT, PEOPLE_SUSPENDED_REASON, peopleModerationActionSchema, moderationNoteSchema, adminPeopleReportListQuery, adminPeopleReportIdParam, adminPeopleMessageRemovalBody, adminPeopleSuspendBody, adminPeopleNoteBody;
|
|
6605
|
-
var init_chunk_ZXK6N2HN = __esm({
|
|
6606
|
-
"../../packages/core/dist/chunk-ZXK6N2HN.js"() {
|
|
6607
|
-
"use strict";
|
|
6608
|
-
init_chunk_ZVXO3XL6();
|
|
6609
|
-
init_chunk_HZ6CADSY();
|
|
6610
|
-
init_zod();
|
|
6611
|
-
PEOPLE_MODERATION_NOTE_MAX_LENGTH = 500;
|
|
6612
|
-
ADMIN_PEOPLE_REPORTS_PAGE_MAX = 100;
|
|
6613
|
-
ADMIN_PEOPLE_REPORTS_PAGE_DEFAULT = 50;
|
|
6614
|
-
PEOPLE_SUSPENDED_REASON = "suspended";
|
|
6615
|
-
peopleModerationActionSchema = external_exports.enum(["remove_message", "suspend", "unsuspend", "dismiss"]);
|
|
6616
|
-
moderationNoteSchema = optionalTrimmedText(PEOPLE_MODERATION_NOTE_MAX_LENGTH);
|
|
6617
|
-
adminPeopleReportListQuery = external_exports.object({
|
|
6618
|
-
pending: external_exports.enum(["true", "false"]).optional().transform((value) => value === "true"),
|
|
6619
|
-
/** Lower bound on `created_at`. */
|
|
6620
|
-
since: timestampSchema.optional(),
|
|
6621
|
-
limit: external_exports.coerce.number().int().min(1).max(ADMIN_PEOPLE_REPORTS_PAGE_MAX).default(ADMIN_PEOPLE_REPORTS_PAGE_DEFAULT),
|
|
6622
|
-
offset: external_exports.coerce.number().int().min(0).default(0)
|
|
6623
|
-
});
|
|
6624
|
-
adminPeopleReportIdParam = external_exports.object({ reportId: uuidSchema });
|
|
6625
|
-
adminPeopleMessageRemovalBody = external_exports.object({ report_id: uuidSchema, message_id: uuidSchema.optional(), note: moderationNoteSchema }).strict();
|
|
6626
|
-
adminPeopleSuspendBody = external_exports.object({ report_id: uuidSchema.optional(), note: moderationNoteSchema }).strict();
|
|
6627
|
-
adminPeopleNoteBody = external_exports.object({ note: moderationNoteSchema }).strict();
|
|
6628
|
-
}
|
|
6629
|
-
});
|
|
6630
|
-
|
|
6631
6656
|
// ../../packages/core/dist/chunk-MIWZOSPI.js
|
|
6632
6657
|
function toIso(epochMs) {
|
|
6633
6658
|
return new Date(epochMs).toISOString();
|
|
@@ -6783,7 +6808,7 @@ var init_chunk_E4DIIOOE = __esm({
|
|
|
6783
6808
|
}
|
|
6784
6809
|
});
|
|
6785
6810
|
|
|
6786
|
-
// ../../packages/core/dist/chunk-
|
|
6811
|
+
// ../../packages/core/dist/chunk-GMWMQ4YA.js
|
|
6787
6812
|
function spokenLineField(label, description2) {
|
|
6788
6813
|
return { type: "text", label, maxLength: SPOKEN_LINE_MAX_CHARS, default: "", description: description2 };
|
|
6789
6814
|
}
|
|
@@ -6793,8 +6818,8 @@ function byLowercaseName(a, b) {
|
|
|
6793
6818
|
return x < y ? -1 : x > y ? 1 : 0;
|
|
6794
6819
|
}
|
|
6795
6820
|
var CALLER_LANGUAGE, TTS_VOICE_REPLY_ENABLED_FIELD, COPILOT_TRIGGER_FIELD, SANDBOX_AGENT_FIELDS, AUDIO_LANGUAGE_OPTIONS, whatsapp, instagram, resend, telegram, API_CHANNEL_DELIVERY_EVENTS, apiChannel, OPENAI_REASONING_MODELS, openai, anthropic, googleAiStudio, openRouter, xai, groqStt, openaiStt, elevenLabsStt, openaiTts, groqTts, elevenLabsTts, GEMINI_TTS_VOICES, googleTts, wayai, externalResources, restApiTool, mcpServer, REKOR_TOOLSET_SERVICE_NAME, rekorToolset, CLAUDE_HARNESS_MODELS, CLAUDE_HARNESS_MODEL_OPTIONS, HARNESS_MCP_SERVERS_FIELD, HARNESS_EGRESS_FIELDS, claudeManagedAgents, SPOKEN_LINE_MAX_CHARS, gptLive, CONNECTORS;
|
|
6796
|
-
var
|
|
6797
|
-
"../../packages/core/dist/chunk-
|
|
6821
|
+
var init_chunk_GMWMQ4YA = __esm({
|
|
6822
|
+
"../../packages/core/dist/chunk-GMWMQ4YA.js"() {
|
|
6798
6823
|
"use strict";
|
|
6799
6824
|
CALLER_LANGUAGE = "caller";
|
|
6800
6825
|
TTS_VOICE_REPLY_ENABLED_FIELD = {
|
|
@@ -6822,7 +6847,17 @@ var init_chunk_FMXFEZN4 = __esm({
|
|
|
6822
6847
|
type: "toggle",
|
|
6823
6848
|
label: "Code Execution Sandbox",
|
|
6824
6849
|
default: false,
|
|
6825
|
-
description: "Let this agent run code in a WayAI sandbox with the sandbox tools, bash, copy_to_sandbox and copy_from_sandbox (add them under Tools):
|
|
6850
|
+
description: "Let this agent run code in a WayAI sandbox with the sandbox tools, bash, copy_to_sandbox and copy_from_sandbox (add them under Tools): a disposable Linux container, shared with the conversation's other agents or private to this agent (Sandbox Scope), started on first use and ended after 10 minutes without use, 60 minutes in all, or when the conversation closes."
|
|
6851
|
+
},
|
|
6852
|
+
sandbox_scope: {
|
|
6853
|
+
type: "select",
|
|
6854
|
+
label: "Sandbox Scope",
|
|
6855
|
+
options: [
|
|
6856
|
+
{ value: "conversation", label: "Conversation (shared with the conversation's other agents)" },
|
|
6857
|
+
{ value: "agent", label: "Agent (private to this agent)" }
|
|
6858
|
+
],
|
|
6859
|
+
default: "conversation",
|
|
6860
|
+
description: "Whose sandbox this agent uses. Conversation: shared with the conversation's other agents; every agent sharing it sees its files, and agents sharing it need the same Sandbox Network setting, or a command from one ends the sandbox and starts a new one, which keeps its /workspace files but none of its running processes. Agent: private to this agent; no other agent sees its files. Set Agent for an agent that handles files others must not see, such as a copilot with internal documents. Each agent sandbox is its own container, counts toward the organization's limit on running sandboxes, and ends with the conversation."
|
|
6826
6861
|
},
|
|
6827
6862
|
sandbox_network: {
|
|
6828
6863
|
type: "select",
|
|
@@ -7662,7 +7697,8 @@ var init_chunk_FMXFEZN4 = __esm({
|
|
|
7662
7697
|
api_key: {
|
|
7663
7698
|
connection_display_name: { type: "text", label: "Connection Name", placeholder: "Enter a name for this connection", description: "This name will be used to identify the connection in the system", required: true },
|
|
7664
7699
|
api_key: { type: "password", label: "API Key", placeholder: "Enter your Anthropic API key", description: "Anthropic API key for the Managed Agents API. Used only from the WayAI Worker \u2014 no sandbox ever sees it.", required: true, maskInEdit: true, useExistingPlaceholder: "__USE_EXISTING_API_KEY__" },
|
|
7665
|
-
access_token: { type: "password", label: "GitHub Token (Optional)", placeholder: "Enter a GitHub personal access token", description: "Optional: personal access token for the repo_url checkout. Anthropic's git proxy injects it after requests leave the sandbox \u2014 it never enters the sandbox.", maskInEdit: true, useExistingPlaceholder: "__USE_EXISTING_ACCESS_TOKEN__" }
|
|
7700
|
+
access_token: { type: "password", label: "GitHub Token (Optional)", placeholder: "Enter a GitHub personal access token", description: "Optional: personal access token for the repo_url checkout. Anthropic's git proxy injects it after requests leave the sandbox \u2014 it never enters the sandbox.", maskInEdit: true, useExistingPlaceholder: "__USE_EXISTING_ACCESS_TOKEN__" },
|
|
7701
|
+
webhook_secret_token: { type: "password", label: "Webhook Signing Secret", placeholder: "whsec_\u2026", description: "Signing secret of this connection's webhook endpoint in the Claude Console. Without it, a finished turn is picked up only by a check every 5 minutes.", maskInEdit: true, useExistingPlaceholder: "__USE_EXISTING_WEBHOOK_SECRET_TOKEN__" }
|
|
7666
7702
|
}
|
|
7667
7703
|
},
|
|
7668
7704
|
token_refresh_config: { api_key: { strategy: "none" } },
|
|
@@ -7748,13 +7784,13 @@ var init_chunk_FMXFEZN4 = __esm({
|
|
|
7748
7784
|
}
|
|
7749
7785
|
});
|
|
7750
7786
|
|
|
7751
|
-
// ../../packages/core/dist/chunk-
|
|
7787
|
+
// ../../packages/core/dist/chunk-PEXTNF6S.js
|
|
7752
7788
|
var evalCallInstant, EVAL_CALL_MIN_SECONDS, EVAL_CALL_MAX_SECONDS, EVAL_CALL_SPOKEN_LINE_MAX_CHARS, hubScoped2, createEvalCallBody, createEvalCallResponse, evalCallConversationQuery, evalCallRecordQuery, evalCallSpeaker, evalCallUtterance, evalCallTurn, evalCallRecording, evalCallRecordResponse, evalCallFinishResponse;
|
|
7753
|
-
var
|
|
7754
|
-
"../../packages/core/dist/chunk-
|
|
7789
|
+
var init_chunk_PEXTNF6S = __esm({
|
|
7790
|
+
"../../packages/core/dist/chunk-PEXTNF6S.js"() {
|
|
7755
7791
|
"use strict";
|
|
7756
7792
|
init_chunk_E4DIIOOE();
|
|
7757
|
-
|
|
7793
|
+
init_chunk_GMWMQ4YA();
|
|
7758
7794
|
init_chunk_HZ6CADSY();
|
|
7759
7795
|
init_chunk_MIWZOSPI();
|
|
7760
7796
|
init_zod();
|
|
@@ -8121,15 +8157,15 @@ var init_chunk_MH4O3YEX = __esm({
|
|
|
8121
8157
|
}
|
|
8122
8158
|
});
|
|
8123
8159
|
|
|
8124
|
-
// ../../packages/core/dist/chunk-
|
|
8160
|
+
// ../../packages/core/dist/chunk-UZ7SPBM3.js
|
|
8125
8161
|
function catalogToolSideEffects(toolName) {
|
|
8126
8162
|
const sideEffects = CATALOG_SIDE_EFFECTS.get(toolName);
|
|
8127
8163
|
if (sideEffects === void 0) return "unknown";
|
|
8128
8164
|
return sideEffects ? "side_effects" : "none";
|
|
8129
8165
|
}
|
|
8130
8166
|
var NATIVE_TOOL_SCHEMAS, WAYAI_CONNECTOR, SANDBOX_AGENT_ROLES, BASE_NATIVE_TOOLS, NATIVE_TOOLS, CATALOG_SIDE_EFFECTS;
|
|
8131
|
-
var
|
|
8132
|
-
"../../packages/core/dist/chunk-
|
|
8167
|
+
var init_chunk_UZ7SPBM3 = __esm({
|
|
8168
|
+
"../../packages/core/dist/chunk-UZ7SPBM3.js"() {
|
|
8133
8169
|
"use strict";
|
|
8134
8170
|
init_chunk_DHPUPI4Y();
|
|
8135
8171
|
NATIVE_TOOL_SCHEMAS = {
|
|
@@ -8450,7 +8486,7 @@ var init_chunk_HX2LNKHX = __esm({
|
|
|
8450
8486
|
"bash": {
|
|
8451
8487
|
"tool_config": {
|
|
8452
8488
|
"name": "bash",
|
|
8453
|
-
"description": "Run a Bash command in this conversation's sandbox: a disposable Linux container (Debian, with Python 3, curl, jq, zip and other common tools) whose working directory is /workspace. The sandbox starts on the first command and keeps its files between commands in this conversation, but it ends after 10 minutes without use or 60 minutes in all; the next command then starts
|
|
8489
|
+
"description": "Run a Bash command in this conversation's sandbox: a disposable Linux container (Debian, with Python 3, curl, jq, zip and other common tools) whose working directory is /workspace. The sandbox starts on the first command and keeps its files between commands in this conversation, but it ends after 10 minutes without use or 60 minutes in all; the next command then starts a new one with the /workspace files from the last save, made when a sandbox stopped and at the end of each turn that ran a command, and its result says what came back. Only files under /workspace are kept, never a running process: a long job should write its progress to files under /workspace, so the work can go on from them. HOME is /workspace, so a pip install --user, or a virtual environment under /workspace, is kept too; a plain pip install is not. Installs count toward the saved workspace's size, and when it is too large to keep, what is under /workspace/.local is left out first. What the sandbox can reach over the network is set for this agent by a hub admin; with no network, nothing leaves it. A command runs for at most timeout_seconds and never past the turn's own time limit. Long output keeps only its first and last parts. The result gives the exit code, stdout and stderr.",
|
|
8454
8490
|
"strict": false,
|
|
8455
8491
|
"parameters": {
|
|
8456
8492
|
"type": "object",
|
|
@@ -8477,7 +8513,7 @@ var init_chunk_HX2LNKHX = __esm({
|
|
|
8477
8513
|
"copy_to_sandbox": {
|
|
8478
8514
|
"tool_config": {
|
|
8479
8515
|
"name": "copy_to_sandbox",
|
|
8480
|
-
"description": `Copy one of this conversation's files, or one of your documents, into the code sandbox, so commands run with bash can read or edit it there. path names the file as read_file does: this conversation's attachments under "conversation/" (e.g. "conversation/report.xlsx"), an earlier conversation's under "conversations/<conversation_id>/<name>", or a document under "data/<file-type>/" (e.g. "data/contracts/acme/msa.docx"), whose result gives the version you copied: pass it to copy_from_sandbox to copy the document back. Hub resource files cannot be copied. The copy lands at sandbox_path, replacing any file there; a file larger than 25 MiB is refused, and a document larger than 1 MiB. If no sandbox is running, the copy starts
|
|
8516
|
+
"description": `Copy one of this conversation's files, or one of your documents, into the code sandbox, so commands run with bash can read or edit it there. path names the file as read_file does: this conversation's attachments under "conversation/" (e.g. "conversation/report.xlsx"), an earlier conversation's under "conversations/<conversation_id>/<name>", or a document under "data/<file-type>/" (e.g. "data/contracts/acme/msa.docx"), whose result gives the version you copied: pass it to copy_from_sandbox to copy the document back. Hub resource files cannot be copied. The copy lands at sandbox_path, replacing any file there; a file larger than 25 MiB is refused, and a document larger than 1 MiB. If no sandbox is running, the copy starts one, with the /workspace files from the last save.`,
|
|
8481
8517
|
"strict": false,
|
|
8482
8518
|
"parameters": {
|
|
8483
8519
|
"type": "object",
|
|
@@ -9110,9 +9146,10 @@ var init_chunk_HX2LNKHX = __esm({
|
|
|
9110
9146
|
// code it runs can send data out of the conversation.
|
|
9111
9147
|
{ tool_native_id: "nt-030", tool_name: "bash", tool_display_name: "Run Code (Bash)", tool_description: "Run a Bash command in the conversation's code sandbox", connector_id: WAYAI_CONNECTOR, operation: "bash", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: true, replay: "reconcile", assignable_roles: SANDBOX_AGENT_ROLES },
|
|
9112
9148
|
// Copies a conversation file, or a toolset document (`data/`, read through the toolset's `get`),
|
|
9113
|
-
// INTO the sandbox: the sandbox is conversation state, so nothing leaves the conversation.
|
|
9114
|
-
//
|
|
9115
|
-
// them, as anything else an agent leaves in it
|
|
9149
|
+
// INTO the sandbox: the sandbox is conversation state, so nothing leaves the conversation. The
|
|
9150
|
+
// conversation's sandbox is shared by its agents whose `sandbox_scope` is `conversation`, so a
|
|
9151
|
+
// document copied in is there for each of them, as anything else an agent leaves in it; an agent
|
|
9152
|
+
// set to `agent` copies into its own, which no other agent reaches (decision 147).
|
|
9116
9153
|
{ tool_native_id: "nt-031", tool_name: "copy_to_sandbox", tool_display_name: "Copy File to Sandbox", tool_description: "Copy one of the conversation's files into its code sandbox", connector_id: WAYAI_CONNECTOR, operation: "copy_to_sandbox", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", assignable_roles: SANDBOX_AGENT_ROLES },
|
|
9117
9154
|
// Copies a sandbox file OUT into the conversation, as an internal note for the team: nothing
|
|
9118
9155
|
// reaches the customer until `send_files` sends it. With `path`, it writes a toolset document
|
|
@@ -9160,11 +9197,104 @@ var init_chunk_IBL7FANV = __esm({
|
|
|
9160
9197
|
});
|
|
9161
9198
|
|
|
9162
9199
|
// ../../packages/core/dist/chunk-PFDZEKDE.js
|
|
9163
|
-
|
|
9200
|
+
function parseExpr(expr) {
|
|
9201
|
+
const fnMatch = expr.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*\((.*?)\)\s*(?:\.(.*))?$/);
|
|
9202
|
+
if (!fnMatch) return null;
|
|
9203
|
+
const [, fn, rawArgs, rawPath] = fnMatch;
|
|
9204
|
+
const args2 = splitArgs(rawArgs);
|
|
9205
|
+
const path42 = rawPath ? rawPath.split(".").flatMap((seg) => {
|
|
9206
|
+
const indexed = [];
|
|
9207
|
+
seg.replace(/([^\[\]]+)|\[(\d+)\]/g, (_, prop, idx) => {
|
|
9208
|
+
if (prop) indexed.push(prop);
|
|
9209
|
+
else if (idx !== void 0) indexed.push(idx);
|
|
9210
|
+
return "";
|
|
9211
|
+
});
|
|
9212
|
+
return indexed;
|
|
9213
|
+
}) : [];
|
|
9214
|
+
return { fn, args: args2, path: path42 };
|
|
9215
|
+
}
|
|
9216
|
+
function splitArgs(rawArgs) {
|
|
9217
|
+
const trimmed = rawArgs.trim();
|
|
9218
|
+
return trimmed ? trimmed.split(",").map((s) => stripQuotes(s.trim())) : [];
|
|
9219
|
+
}
|
|
9220
|
+
function stripQuotes(s) {
|
|
9221
|
+
if (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'")) {
|
|
9222
|
+
return s.slice(1, -1);
|
|
9223
|
+
}
|
|
9224
|
+
return s;
|
|
9225
|
+
}
|
|
9226
|
+
function parseCatalogArgs(args2) {
|
|
9227
|
+
let kind = null;
|
|
9228
|
+
let tree = false;
|
|
9229
|
+
for (const token of args2) {
|
|
9230
|
+
if (token === "tree") tree = true;
|
|
9231
|
+
else if ((token === "kb" || token === "skill") && kind === null) kind = token;
|
|
9232
|
+
}
|
|
9233
|
+
return { kind, tree };
|
|
9234
|
+
}
|
|
9235
|
+
function widenKinds(kinds) {
|
|
9236
|
+
if (kinds.has("all") || kinds.size > 1) return "all";
|
|
9237
|
+
return [...kinds][0] ?? null;
|
|
9238
|
+
}
|
|
9239
|
+
function* parseCalls(template) {
|
|
9240
|
+
for (const match of template.matchAll(PLACEHOLDER_RE)) {
|
|
9241
|
+
const parsed = parseExpr(match[1].trim());
|
|
9242
|
+
if (parsed) yield parsed;
|
|
9243
|
+
}
|
|
9244
|
+
}
|
|
9245
|
+
function scanTemplateResources(template) {
|
|
9246
|
+
if (!template || !template.includes("{{")) return EMPTY_SCAN;
|
|
9247
|
+
const scan = { ...EMPTY_SCAN };
|
|
9248
|
+
const names = /* @__PURE__ */ new Set();
|
|
9249
|
+
const paths = /* @__PURE__ */ new Set();
|
|
9250
|
+
const treeKinds = /* @__PURE__ */ new Set();
|
|
9251
|
+
const legacyKinds = /* @__PURE__ */ new Set();
|
|
9252
|
+
for (const { fn, args: args2 } of parseCalls(template)) {
|
|
9253
|
+
switch (fn) {
|
|
9254
|
+
case CATALOG_FN:
|
|
9255
|
+
case LEGACY_CATALOG_FN: {
|
|
9256
|
+
scan.needs_catalog = true;
|
|
9257
|
+
scan.has_catalog_call = true;
|
|
9258
|
+
const { kind, tree } = parseCatalogArgs(args2);
|
|
9259
|
+
if (fn === LEGACY_CATALOG_FN) legacyKinds.add(kind ?? "all");
|
|
9260
|
+
if (tree) treeKinds.add(kind ?? "all");
|
|
9261
|
+
break;
|
|
9262
|
+
}
|
|
9263
|
+
case "agent_skills":
|
|
9264
|
+
scan.needs_catalog = true;
|
|
9265
|
+
break;
|
|
9266
|
+
case "resource_content":
|
|
9267
|
+
if (args2[0]) names.add(args2[0]);
|
|
9268
|
+
break;
|
|
9269
|
+
case "file_content":
|
|
9270
|
+
if (args2[0]) paths.add(args2[0]);
|
|
9271
|
+
break;
|
|
9272
|
+
default:
|
|
9273
|
+
break;
|
|
9274
|
+
}
|
|
9275
|
+
}
|
|
9276
|
+
scan.tree_kinds = widenKinds(treeKinds);
|
|
9277
|
+
scan.legacy_kinds = widenKinds(legacyKinds);
|
|
9278
|
+
scan.resource_content_names = [...names];
|
|
9279
|
+
scan.file_content_paths = [...paths];
|
|
9280
|
+
return scan;
|
|
9281
|
+
}
|
|
9282
|
+
var PREVIOUS_CONVERSATIONS_MAX, PLACEHOLDER_RE, CATALOG_FN, LEGACY_CATALOG_FN, EMPTY_SCAN;
|
|
9164
9283
|
var init_chunk_PFDZEKDE = __esm({
|
|
9165
9284
|
"../../packages/core/dist/chunk-PFDZEKDE.js"() {
|
|
9166
9285
|
"use strict";
|
|
9167
9286
|
PREVIOUS_CONVERSATIONS_MAX = 20;
|
|
9287
|
+
PLACEHOLDER_RE = /\{\{\s*([^{}]+?)\s*\}\}/g;
|
|
9288
|
+
CATALOG_FN = "files";
|
|
9289
|
+
LEGACY_CATALOG_FN = "resources";
|
|
9290
|
+
EMPTY_SCAN = {
|
|
9291
|
+
needs_catalog: false,
|
|
9292
|
+
has_catalog_call: false,
|
|
9293
|
+
legacy_kinds: null,
|
|
9294
|
+
tree_kinds: null,
|
|
9295
|
+
resource_content_names: [],
|
|
9296
|
+
file_content_paths: []
|
|
9297
|
+
};
|
|
9168
9298
|
}
|
|
9169
9299
|
});
|
|
9170
9300
|
|
|
@@ -9355,7 +9485,7 @@ var init_chunk_T7KQKDET = __esm({
|
|
|
9355
9485
|
}
|
|
9356
9486
|
});
|
|
9357
9487
|
|
|
9358
|
-
// ../../packages/core/dist/chunk-
|
|
9488
|
+
// ../../packages/core/dist/chunk-XOGFONTQ.js
|
|
9359
9489
|
function resolveMonitorTrigger(monitorConfig) {
|
|
9360
9490
|
if (!monitorConfig || typeof monitorConfig !== "object") return "idle";
|
|
9361
9491
|
const raw = monitorConfig.trigger;
|
|
@@ -9661,10 +9791,10 @@ function refineMonitorRulesStructuredOutput(body, ctx) {
|
|
|
9661
9791
|
if (refusal2) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["response_format"], message: refusal2 });
|
|
9662
9792
|
}
|
|
9663
9793
|
var NATIVE_TOOL_NAMES, previousConversationsCountField, summarizationThresholdField, flagConditionSchema, MONITOR_TRIGGERS, monitorTriggerSchema, AUTOMATION_GATE_TRIGGERS, NON_FIRING_TRIGGERS, MONITOR_FIRING_TRIGGERS, MONITOR_DELAY_SECONDS_MIN, MONITOR_IDLE_DELAY_REQUIRED_MESSAGE, MONITOR_HISTORY_MESSAGES_MAX, monitorHistoryMessagesSchema, monitorIncludeToolResultsSchema, MONITOR_INPUT_SHAPING_KEYS, MONITOR_INPUT_SHAPING_SCHEMAS, MONITOR_INPUT_SHAPING_IDLE_MESSAGE, monitorArgumentSourceSchema, MONITOR_NOTE_TEMPLATE_MAX, MONITOR_STEER_NOTE_MAX, MONITOR_GATE_AGENT_NAME_MAX, monitorActionSchema, monitorRuleSchema, MONITOR_RULE_KEYS, MONITOR_RULE_SCHEMAS, MONITOR_RULE_TRIGGERS, MONITOR_RULE_TRIGGER_MESSAGE, CALL_UTTERANCE_SPEAKERS, callUtteranceSpeakerSchema, MONITOR_CALL_KEYS, MONITOR_CALL_SCHEMAS, MONITOR_CALL_KEY_MESSAGE, CALL_STEERING_MIN_CONFIDENCE, CALL_UTTERANCE_RULE_NOT_CONFIDENT_MESSAGE, CALL_UTTERANCE_FALLBACK_MESSAGE, CALL_UTTERANCE_FLAG_CONDITIONS_MESSAGE, CALL_STEER_NOTE_BLANK_MESSAGE, MONITOR_USER_MESSAGE_ACTION_KINDS, MONITOR_ASSISTANT_REPLY_ACTION_KINDS, MONITOR_CALL_UTTERANCE_ACTION_KINDS, MONITOR_AUTOMATION_FIRE_ACTION_KINDS, MONITOR_AUTOMATION_ITEM_ACTION_KINDS, INSERT_NOTE_TOOL_NAME, RUN_MONITOR_TOOL_NAME, MONITOR_RULE_ALLOWED_NATIVE_TOOLS, MONITOR_RULE_REENTRY_TOOLS, MONITOR_RULE_REENTRY_TRACKS, AUTOMATION_FIRE_FLAG_CONDITIONS_MESSAGE, AUTOMATION_FIRE_INPUT_SHAPING_MESSAGE, AUTOMATION_ITEM_FLAG_CONDITIONS_MESSAGE, AUTOMATION_ITEM_INPUT_SHAPING_MESSAGE, AUTOMATION_GATE_KEY_MESSAGES, monitorConfigField, flagConditionsField, agentIdParam, listAgentsQuery, agentConnectionsQuery, createAgentBody, updateAgentBody, AGENT_PARAMETER_TYPES, AGENT_PARAMETER_NAME_REGEX, agentParameterCreateSchema, MAX_AGENT_PARAMETERS_PER_REQUEST, createAgentParametersBody;
|
|
9664
|
-
var
|
|
9665
|
-
"../../packages/core/dist/chunk-
|
|
9794
|
+
var init_chunk_XOGFONTQ = __esm({
|
|
9795
|
+
"../../packages/core/dist/chunk-XOGFONTQ.js"() {
|
|
9666
9796
|
"use strict";
|
|
9667
|
-
|
|
9797
|
+
init_chunk_UZ7SPBM3();
|
|
9668
9798
|
init_chunk_IBL7FANV();
|
|
9669
9799
|
init_chunk_PFDZEKDE();
|
|
9670
9800
|
init_chunk_HZ6CADSY();
|
|
@@ -9887,12 +10017,12 @@ var init_chunk_BUXNYLB7 = __esm({
|
|
|
9887
10017
|
}
|
|
9888
10018
|
});
|
|
9889
10019
|
|
|
9890
|
-
// ../../packages/core/dist/chunk-
|
|
10020
|
+
// ../../packages/core/dist/chunk-TUP5Y6ZB.js
|
|
9891
10021
|
var conversationIdParam, conversationHubQuery, claimBody, releaseBody, transferBody, closeBody, additionalContextPayloadSchema, kanbanUpdateBody, annotateConversationBody, observabilityParams, observabilityListParams, deleteUserConversationsBody, deleteUserConversationsResponse, sendMessageBody, listConversationsQuery, flagSourceSchema, getConversationsResponse, getConversationDetailParams, getConversationDetailQuery, getConversationDetailResponse, listWhatsAppTemplatesQuery, sendWhatsAppTemplateBody;
|
|
9892
|
-
var
|
|
9893
|
-
"../../packages/core/dist/chunk-
|
|
10022
|
+
var init_chunk_TUP5Y6ZB = __esm({
|
|
10023
|
+
"../../packages/core/dist/chunk-TUP5Y6ZB.js"() {
|
|
9894
10024
|
"use strict";
|
|
9895
|
-
|
|
10025
|
+
init_chunk_XOGFONTQ();
|
|
9896
10026
|
init_chunk_HZ6CADSY();
|
|
9897
10027
|
init_chunk_DHPUPI4Y();
|
|
9898
10028
|
init_zod();
|
|
@@ -10348,7 +10478,7 @@ var init_chunk_BPCNB5RT = __esm({
|
|
|
10348
10478
|
}
|
|
10349
10479
|
});
|
|
10350
10480
|
|
|
10351
|
-
// ../../packages/core/dist/chunk-
|
|
10481
|
+
// ../../packages/core/dist/chunk-LQSENJ26.js
|
|
10352
10482
|
function idempotencyHeaderRefusal(value) {
|
|
10353
10483
|
if (typeof value !== "string" || !/^[A-Za-z0-9][A-Za-z0-9-]{0,63}$/.test(value)) {
|
|
10354
10484
|
return "idempotency_header must be a header name: letters, digits and dashes, at most 64";
|
|
@@ -10359,10 +10489,10 @@ function idempotencyHeaderRefusal(value) {
|
|
|
10359
10489
|
return null;
|
|
10360
10490
|
}
|
|
10361
10491
|
var CATALOG_REPLAY, REPLAY_OVERRIDES, RESERVED_HEADERS;
|
|
10362
|
-
var
|
|
10363
|
-
"../../packages/core/dist/chunk-
|
|
10492
|
+
var init_chunk_LQSENJ26 = __esm({
|
|
10493
|
+
"../../packages/core/dist/chunk-LQSENJ26.js"() {
|
|
10364
10494
|
"use strict";
|
|
10365
|
-
|
|
10495
|
+
init_chunk_UZ7SPBM3();
|
|
10366
10496
|
CATALOG_REPLAY = new Map(
|
|
10367
10497
|
NATIVE_TOOLS.map((tool) => [tool.tool_name, tool.replay])
|
|
10368
10498
|
);
|
|
@@ -10595,7 +10725,7 @@ var init_chunk_WEXVYJ5H = __esm({
|
|
|
10595
10725
|
}
|
|
10596
10726
|
});
|
|
10597
10727
|
|
|
10598
|
-
// ../../packages/core/dist/chunk-
|
|
10728
|
+
// ../../packages/core/dist/chunk-KRGVB7U6.js
|
|
10599
10729
|
function refineToolConfig(value, ctx) {
|
|
10600
10730
|
const raw = value.tool_config;
|
|
10601
10731
|
if (raw == null) return;
|
|
@@ -10631,10 +10761,10 @@ function refineToolConfig(value, ctx) {
|
|
|
10631
10761
|
}
|
|
10632
10762
|
}
|
|
10633
10763
|
var toolIdParam, listToolsQuery, toolAgentQuery, deleteToolQuery, toolConnectionsQuery, nativeToolIdSchema, CONTEXT_BOUNDARIES, contextBoundarySchema, addNativeToolBody, addMcpToolBody, toolReplaySettingsFields, toolReplaySettingsSchema, createCustomToolBody, updateCustomToolBody, updateToolExecutionConfigBody;
|
|
10634
|
-
var
|
|
10635
|
-
"../../packages/core/dist/chunk-
|
|
10764
|
+
var init_chunk_KRGVB7U6 = __esm({
|
|
10765
|
+
"../../packages/core/dist/chunk-KRGVB7U6.js"() {
|
|
10636
10766
|
"use strict";
|
|
10637
|
-
|
|
10767
|
+
init_chunk_LQSENJ26();
|
|
10638
10768
|
init_chunk_WEXVYJ5H();
|
|
10639
10769
|
init_chunk_HZ6CADSY();
|
|
10640
10770
|
init_zod();
|
|
@@ -12006,7 +12136,7 @@ var init_chunk_6NI5RAM4 = __esm({
|
|
|
12006
12136
|
}
|
|
12007
12137
|
});
|
|
12008
12138
|
|
|
12009
|
-
// ../../packages/core/dist/chunk-
|
|
12139
|
+
// ../../packages/core/dist/chunk-RT35VFUY.js
|
|
12010
12140
|
function refineHubAsCodeCustomTools(config, ctx) {
|
|
12011
12141
|
const agents = config.agents;
|
|
12012
12142
|
if (!Array.isArray(agents)) return;
|
|
@@ -12542,12 +12672,12 @@ function refineHubAsCodeMonitorRulesOutput(config, ctx) {
|
|
|
12542
12672
|
});
|
|
12543
12673
|
}
|
|
12544
12674
|
var MAX_10MB_BASE64_ENCODED_BYTES, MAX_EVAL_ATTACHMENT_ENCODED_BYTES, MAX_EVAL_ATTACHMENT_CARRIERS, MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES, MAX_RESOURCE_ENCODED_BYTES, MAX_HUB_AS_CODE_RESOURCES, MAX_HUB_AS_CODE_RESOURCE_FILES, MAX_RESOURCE_AGGREGATE_ENCODED_BYTES, MAX_CI_CONFIG_BODY_BYTES, MAX_CALL_OPENING_CARRIERS, MAX_CALL_OPENING_AGGREGATE_ENCODED_BYTES, hubAsCodeStateSchema, hubAsCodeResourceFileSchema, hubAsCodeResourceSchema, uuidPattern, ciUuidSchema, boundedHubAsCodeResourcesSchema, hubAsCodeConfigSchema, ciPullHubIdParam, ciBranchParam, ciPullQuery, ciHubsQuery, ciLookupQuery, ciBranchesQuery, ciSyncBody, ciPushBody, ciDiffBody, ciPublishBody, ciPublishPreviewBody, ciSyncMcpBody, ciOrgResourcesParam, orgResourcesConfigSchema, ciOrgResourcesPushBody, ciOrgResourcesDiffBody, CI_APPLY_ENTITY_KINDS, CI_APPLY_OPERATIONS, ciApplyErrorBaseSchema, ciApplyErrorSchema, ciSyncCountSchema, ciSyncChangesSchema, ciSyncWarningSchema, ciSyncResponseSchema;
|
|
12545
|
-
var
|
|
12546
|
-
"../../packages/core/dist/chunk-
|
|
12675
|
+
var init_chunk_RT35VFUY = __esm({
|
|
12676
|
+
"../../packages/core/dist/chunk-RT35VFUY.js"() {
|
|
12547
12677
|
"use strict";
|
|
12548
|
-
|
|
12678
|
+
init_chunk_KRGVB7U6();
|
|
12549
12679
|
init_chunk_623SRYWZ();
|
|
12550
|
-
|
|
12680
|
+
init_chunk_XOGFONTQ();
|
|
12551
12681
|
init_chunk_LBDH7LCG();
|
|
12552
12682
|
init_chunk_4LXDRTO4();
|
|
12553
12683
|
init_chunk_T4Q5COKJ();
|
|
@@ -13556,15 +13686,15 @@ var init_chunk_LQY2OCQL = __esm({
|
|
|
13556
13686
|
}
|
|
13557
13687
|
});
|
|
13558
13688
|
|
|
13559
|
-
// ../../packages/core/dist/chunk-
|
|
13689
|
+
// ../../packages/core/dist/chunk-2VTDOH67.js
|
|
13560
13690
|
var AUTOMATION_TRIGGER_TYPES, AUTOMATION_EVENT_TYPES, AUTOMATION_TARGET_TYPES, AUTOMATION_ACTION_TYPES, AUTOMATION_CHANNEL_TYPES, AUTOMATION_PURPOSES, AUTOMATION_NAME_MAX, AUTOMATION_DESCRIPTION_MAX, AUTOMATION_INSTRUCTIONS_MAX, AUTOMATION_TEXT_MAX, AUTOMATION_CRON_MAX, AUTOMATION_WEBHOOK_AUTHS, AUTOMATION_WEBHOOK_HEADERS, AUTOMATION_WEBHOOK_BODY_MAX_BYTES, AUTOMATION_WEBHOOK_HEADER_NAME_MAX, WEBHOOK_RESERVED_HEADERS, automationTriggerSchema, automationTargetSchema, automationActionSchema, automationGateSchema, automationName, automationDescription, automationIdParam, automationHubQuery, automationWebhookParams, AUTOMATION_RUNS_PAGE_MAX, listAutomationRunsQuery, createAutomationBody, updateAutomationBody, AUTOMATION_ALERT_CATEGORIES, AUTOMATION_BLOCKED_ALERT_CATEGORY, automationEventSubscriberParam;
|
|
13561
|
-
var
|
|
13562
|
-
"../../packages/core/dist/chunk-
|
|
13691
|
+
var init_chunk_2VTDOH67 = __esm({
|
|
13692
|
+
"../../packages/core/dist/chunk-2VTDOH67.js"() {
|
|
13563
13693
|
"use strict";
|
|
13564
13694
|
init_chunk_LQY2OCQL();
|
|
13565
|
-
|
|
13695
|
+
init_chunk_XOGFONTQ();
|
|
13566
13696
|
init_chunk_3HSB6J4J();
|
|
13567
|
-
|
|
13697
|
+
init_chunk_5XEJSR22();
|
|
13568
13698
|
init_chunk_DHPUPI4Y();
|
|
13569
13699
|
init_chunk_T7KQKDET();
|
|
13570
13700
|
init_zod();
|
|
@@ -14807,29 +14937,30 @@ var init_chunk_TS4EYU3W = __esm({
|
|
|
14807
14937
|
var init_contracts = __esm({
|
|
14808
14938
|
"../../packages/core/dist/contracts/index.js"() {
|
|
14809
14939
|
"use strict";
|
|
14940
|
+
init_chunk_SXDX4GHS();
|
|
14941
|
+
init_chunk_FK6HBXM7();
|
|
14810
14942
|
init_chunk_VXEAR36B();
|
|
14811
14943
|
init_chunk_TIZ57ZBA();
|
|
14812
14944
|
init_chunk_Q7KIQHAZ();
|
|
14813
|
-
|
|
14945
|
+
init_chunk_QUGQIL47();
|
|
14814
14946
|
init_chunk_IPXBFWUU();
|
|
14815
14947
|
init_chunk_GK27ENTT();
|
|
14816
|
-
init_chunk_SXDX4GHS();
|
|
14817
|
-
init_chunk_FK6HBXM7();
|
|
14818
14948
|
init_chunk_GPM7PE44();
|
|
14819
14949
|
init_chunk_DGKMMFIR();
|
|
14820
14950
|
init_chunk_ZC6YGHNX();
|
|
14821
14951
|
init_chunk_ACKF2MVU();
|
|
14952
|
+
init_chunk_ZXK6N2HN();
|
|
14822
14953
|
init_chunk_Y7CFCYX4();
|
|
14823
14954
|
init_chunk_5DGHIY7L();
|
|
14824
|
-
|
|
14955
|
+
init_chunk_FNNHGL7K();
|
|
14825
14956
|
init_chunk_4MRBBR5L();
|
|
14826
14957
|
init_chunk_BEOHBREG();
|
|
14827
14958
|
init_chunk_IPDOHAZ5();
|
|
14828
14959
|
init_chunk_YUZFHVB2();
|
|
14960
|
+
init_chunk_I3O2RACG();
|
|
14829
14961
|
init_chunk_34LE6P7E();
|
|
14830
14962
|
init_chunk_FPSDNS2E();
|
|
14831
|
-
|
|
14832
|
-
init_chunk_VOC3AGY4();
|
|
14963
|
+
init_chunk_PEXTNF6S();
|
|
14833
14964
|
init_chunk_C4HEZ7ZI();
|
|
14834
14965
|
init_chunk_IR2NOSI3();
|
|
14835
14966
|
init_chunk_EA23LSDS();
|
|
@@ -14837,12 +14968,12 @@ var init_contracts = __esm({
|
|
|
14837
14968
|
init_chunk_LWMLR2WI();
|
|
14838
14969
|
init_chunk_ACGAI25T();
|
|
14839
14970
|
init_chunk_MH4O3YEX();
|
|
14840
|
-
|
|
14971
|
+
init_chunk_TUP5Y6ZB();
|
|
14841
14972
|
init_chunk_KSTYTQ7I();
|
|
14842
14973
|
init_chunk_LKBSHANA();
|
|
14843
14974
|
init_chunk_BPCNB5RT();
|
|
14844
|
-
|
|
14845
|
-
|
|
14975
|
+
init_chunk_RT35VFUY();
|
|
14976
|
+
init_chunk_KRGVB7U6();
|
|
14846
14977
|
init_chunk_623SRYWZ();
|
|
14847
14978
|
init_chunk_JDJ4EUOL();
|
|
14848
14979
|
init_chunk_3KYTITOR();
|
|
@@ -14852,9 +14983,9 @@ var init_contracts = __esm({
|
|
|
14852
14983
|
init_chunk_YULHXJ5M();
|
|
14853
14984
|
init_chunk_V4FRPRH5();
|
|
14854
14985
|
init_chunk_ZHJEQBXJ();
|
|
14855
|
-
|
|
14986
|
+
init_chunk_2VTDOH67();
|
|
14856
14987
|
init_chunk_LQY2OCQL();
|
|
14857
|
-
|
|
14988
|
+
init_chunk_XOGFONTQ();
|
|
14858
14989
|
init_chunk_3HSB6J4J();
|
|
14859
14990
|
init_chunk_IG6QBZMA();
|
|
14860
14991
|
init_chunk_ZJJ5ODOD();
|
|
@@ -14863,9 +14994,9 @@ var init_contracts = __esm({
|
|
|
14863
14994
|
init_chunk_4LXDRTO4();
|
|
14864
14995
|
init_chunk_E4DIIOOE();
|
|
14865
14996
|
init_chunk_7CYHPF35();
|
|
14866
|
-
|
|
14867
|
-
|
|
14868
|
-
|
|
14997
|
+
init_chunk_GMWMQ4YA();
|
|
14998
|
+
init_chunk_LQSENJ26();
|
|
14999
|
+
init_chunk_UZ7SPBM3();
|
|
14869
15000
|
init_chunk_NVKU5PPQ();
|
|
14870
15001
|
init_chunk_2FCLSQSQ();
|
|
14871
15002
|
init_chunk_FECLIZTY();
|
|
@@ -14878,11 +15009,11 @@ var init_contracts = __esm({
|
|
|
14878
15009
|
init_chunk_OMPT4ZHR();
|
|
14879
15010
|
init_chunk_2PZIF56U();
|
|
14880
15011
|
init_chunk_UEJOG2Q7();
|
|
14881
|
-
|
|
15012
|
+
init_chunk_ISFDR7SP();
|
|
14882
15013
|
init_chunk_SOJMWM63();
|
|
14883
15014
|
init_chunk_WEXVYJ5H();
|
|
14884
15015
|
init_chunk_LZDVDC2S();
|
|
14885
|
-
|
|
15016
|
+
init_chunk_5XEJSR22();
|
|
14886
15017
|
init_chunk_IBL7FANV();
|
|
14887
15018
|
init_chunk_PFDZEKDE();
|
|
14888
15019
|
init_chunk_VORPHGDT();
|
|
@@ -15286,6 +15417,61 @@ var init_api_client = __esm({
|
|
|
15286
15417
|
}
|
|
15287
15418
|
return new Uint8Array(await response.arrayBuffer());
|
|
15288
15419
|
}
|
|
15420
|
+
// ---- A preview hub's knowledge cut-over (`wayai knowledge cut-over`) ----
|
|
15421
|
+
//
|
|
15422
|
+
// The setup routes the web console writes through, so each write takes the same checks: the
|
|
15423
|
+
// as-code push never sees a hub's copies of organization resources or their agent links.
|
|
15424
|
+
async listAgents(hubId) {
|
|
15425
|
+
const params = new URLSearchParams({ hub_id: hubId });
|
|
15426
|
+
return this.request("GET", `/api/setup/agents?${params}`);
|
|
15427
|
+
}
|
|
15428
|
+
/** Patch an agent of a preview hub: the text it reads (`updateAgentBody` takes more). */
|
|
15429
|
+
async updateAgent(hubId, agentId, patch) {
|
|
15430
|
+
const params = new URLSearchParams({ hub_id: hubId });
|
|
15431
|
+
await this.request("PATCH", `/api/setup/agents/${encodeURIComponent(agentId)}?${params}`, patch);
|
|
15432
|
+
}
|
|
15433
|
+
async listAgentResources(hubId, agentId) {
|
|
15434
|
+
const params = new URLSearchParams({ hub_id: hubId, agent_id: agentId });
|
|
15435
|
+
return this.request("GET", `/api/setup/resources/agent-resources?${params}`);
|
|
15436
|
+
}
|
|
15437
|
+
async updateAgentResource(body) {
|
|
15438
|
+
return this.request("PATCH", "/api/setup/resources/agent-resources", body);
|
|
15439
|
+
}
|
|
15440
|
+
/** An agent's tools, and the native and connection tools it could add (`available_action: 'Add'`). */
|
|
15441
|
+
async listAgentTools(hubId, agentId) {
|
|
15442
|
+
const params = new URLSearchParams({ hub_id: hubId, agent_id: agentId });
|
|
15443
|
+
return this.request("GET", `/api/setup/tools?${params}`);
|
|
15444
|
+
}
|
|
15445
|
+
async addNativeTool(hubId, agentId, toolNativeId) {
|
|
15446
|
+
return this.request("POST", "/api/setup/tools/native", {
|
|
15447
|
+
hub_id: hubId,
|
|
15448
|
+
agent_id: agentId,
|
|
15449
|
+
tool_native_id: toolNativeId
|
|
15450
|
+
});
|
|
15451
|
+
}
|
|
15452
|
+
async addMcpTool(hubId, agentId, mcpToolId) {
|
|
15453
|
+
return this.request("POST", "/api/setup/tools/mcp", { hub_id: hubId, agent_id: agentId, mcp_tool_id: mcpToolId });
|
|
15454
|
+
}
|
|
15455
|
+
async enableTool(hubId, agentId, toolId) {
|
|
15456
|
+
const params = new URLSearchParams({ hub_id: hubId, agent_id: agentId });
|
|
15457
|
+
await this.request("POST", `/api/setup/tools/${encodeURIComponent(toolId)}/enable?${params}`);
|
|
15458
|
+
}
|
|
15459
|
+
/** Add a token-holding connection (a Base Toolset's) to a preview hub; the answer lists the hub's connections. */
|
|
15460
|
+
async addConnection(body) {
|
|
15461
|
+
return this.request("POST", "/api/setup/connections", body);
|
|
15462
|
+
}
|
|
15463
|
+
async listAutomations(hubId) {
|
|
15464
|
+
const params = new URLSearchParams({ hub_id: hubId });
|
|
15465
|
+
return this.request("GET", `/api/automations?${params}`);
|
|
15466
|
+
}
|
|
15467
|
+
async updateAutomation(hubId, automationId, body) {
|
|
15468
|
+
const params = new URLSearchParams({ hub_id: hubId });
|
|
15469
|
+
await this.request("PATCH", `/api/automations/${encodeURIComponent(automationId)}?${params}`, body);
|
|
15470
|
+
}
|
|
15471
|
+
/** Record one knowledge resource's move into the org's knowledge base (#5142 step 4). */
|
|
15472
|
+
async recordKnowledgeMove(body) {
|
|
15473
|
+
return this.request("POST", "/api/setup/knowledge/moves", body);
|
|
15474
|
+
}
|
|
15289
15475
|
async me() {
|
|
15290
15476
|
return this.request("GET", "/api/auth/me");
|
|
15291
15477
|
}
|
|
@@ -16151,11 +16337,11 @@ var UUID_RE2, WAYAI_WORKSPACE_LAYOUT;
|
|
|
16151
16337
|
var init_dist = __esm({
|
|
16152
16338
|
"../../packages/core/dist/index.js"() {
|
|
16153
16339
|
"use strict";
|
|
16154
|
-
|
|
16340
|
+
init_chunk_ISFDR7SP();
|
|
16155
16341
|
init_chunk_SOJMWM63();
|
|
16156
16342
|
init_chunk_WEXVYJ5H();
|
|
16157
16343
|
init_chunk_LZDVDC2S();
|
|
16158
|
-
|
|
16344
|
+
init_chunk_5XEJSR22();
|
|
16159
16345
|
init_chunk_IBL7FANV();
|
|
16160
16346
|
init_chunk_PFDZEKDE();
|
|
16161
16347
|
init_chunk_P3AWZG3N();
|
|
@@ -21694,6 +21880,7 @@ var init_types2 = __esm({
|
|
|
21694
21880
|
ENTITY_KINDS = [
|
|
21695
21881
|
"record_types",
|
|
21696
21882
|
"relationship_types",
|
|
21883
|
+
"file_types",
|
|
21697
21884
|
"inbound_webhooks",
|
|
21698
21885
|
"triggers",
|
|
21699
21886
|
"toolsets",
|
|
@@ -21703,6 +21890,7 @@ var init_types2 = __esm({
|
|
|
21703
21890
|
ENTITY_DIRS = {
|
|
21704
21891
|
record_types: "record-types",
|
|
21705
21892
|
relationship_types: "relationship-types",
|
|
21893
|
+
file_types: "file-types",
|
|
21706
21894
|
inbound_webhooks: "inbound-webhooks",
|
|
21707
21895
|
triggers: "triggers",
|
|
21708
21896
|
toolsets: "toolsets",
|
|
@@ -21839,6 +22027,7 @@ var init_config_writer = __esm({
|
|
|
21839
22027
|
"target_record_types",
|
|
21840
22028
|
"cascade"
|
|
21841
22029
|
],
|
|
22030
|
+
file_types: ["id", "name", "description", "icon", "color", "max_size", "allowed_content_types", "metadata_schema"],
|
|
21842
22031
|
inbound_webhooks: [
|
|
21843
22032
|
"id",
|
|
21844
22033
|
"name",
|
|
@@ -21992,9 +22181,12 @@ function parseBaseFolder(folder) {
|
|
|
21992
22181
|
);
|
|
21993
22182
|
}
|
|
21994
22183
|
const read = (kind) => readEntityDir(folder, path22.join(folder, ENTITY_DIRS[kind]));
|
|
22184
|
+
const fileTypesDir = path22.join(folder, ENTITY_DIRS.file_types);
|
|
22185
|
+
const fileTypes = readEntityDir(folder, fileTypesDir);
|
|
21995
22186
|
const config = {
|
|
21996
22187
|
record_types: read("record_types"),
|
|
21997
22188
|
relationship_types: read("relationship_types"),
|
|
22189
|
+
...isDirectory(fileTypesDir) ? { file_types: fileTypes } : {},
|
|
21998
22190
|
inbound_webhooks: read("inbound_webhooks"),
|
|
21999
22191
|
triggers: read("triggers"),
|
|
22000
22192
|
toolsets: read("toolsets"),
|
|
@@ -22024,10 +22216,15 @@ function isEmptyBucket(b) {
|
|
|
22024
22216
|
function isDiffEmpty(diff) {
|
|
22025
22217
|
return ENTITY_KINDS.every((kind) => isEmptyBucket(bucket(diff, kind)));
|
|
22026
22218
|
}
|
|
22219
|
+
function isPrunable(id) {
|
|
22220
|
+
return isPathSafeId(id);
|
|
22221
|
+
}
|
|
22027
22222
|
function collectRemovals(diff) {
|
|
22028
22223
|
const out = [];
|
|
22029
22224
|
for (const kind of ENTITY_KINDS) {
|
|
22030
|
-
for (const entity of bucket(diff, kind)?.removed ?? [])
|
|
22225
|
+
for (const entity of bucket(diff, kind)?.removed ?? []) {
|
|
22226
|
+
if (isPrunable(entity.id)) out.push({ kind, id: entity.id });
|
|
22227
|
+
}
|
|
22031
22228
|
}
|
|
22032
22229
|
return out;
|
|
22033
22230
|
}
|
|
@@ -22040,7 +22237,7 @@ function countChanges(diff) {
|
|
|
22040
22237
|
if (!b) continue;
|
|
22041
22238
|
added += b.added.length;
|
|
22042
22239
|
modified += b.modified.length;
|
|
22043
|
-
removed += b.removed.length;
|
|
22240
|
+
removed += b.removed.filter((e) => isPrunable(e.id)).length;
|
|
22044
22241
|
}
|
|
22045
22242
|
return { added, modified, removed };
|
|
22046
22243
|
}
|
|
@@ -22052,7 +22249,11 @@ function renderDiff(diff) {
|
|
|
22052
22249
|
lines.push(`${BOLD}${LABELS[kind]}s${RESET}`);
|
|
22053
22250
|
for (const e of b.added) lines.push(`${GREEN} + ${sanitizeTerminalText(e.id)}${RESET}`);
|
|
22054
22251
|
for (const m of b.modified) lines.push(`${YELLOW} ~ ${sanitizeTerminalText(m.after.id)}${RESET}`);
|
|
22055
|
-
for (const e of b.removed)
|
|
22252
|
+
for (const e of b.removed) {
|
|
22253
|
+
lines.push(
|
|
22254
|
+
isPrunable(e.id) ? `${RED} - ${sanitizeTerminalText(e.id)}${RESET}` : `${YELLOW} = ${sanitizeTerminalText(e.id)} (kept: pull cannot write its id to a file)${RESET}`
|
|
22255
|
+
);
|
|
22256
|
+
}
|
|
22056
22257
|
}
|
|
22057
22258
|
const { added, modified, removed } = countChanges(diff);
|
|
22058
22259
|
lines.push("");
|
|
@@ -22061,7 +22262,7 @@ function renderDiff(diff) {
|
|
|
22061
22262
|
);
|
|
22062
22263
|
if (removed > 0) {
|
|
22063
22264
|
lines.push(
|
|
22064
|
-
`${RED} ${removed} entit${removed === 1 ? "y" : "ies"} exist on the base but not in your files \u2014 re-run with --prune to delete (record types cascade to their records).${RESET}`
|
|
22265
|
+
`${RED} ${removed} entit${removed === 1 ? "y" : "ies"} exist on the base but not in your files \u2014 re-run with --prune to delete (record types cascade to their records, file types to their files).${RESET}`
|
|
22065
22266
|
);
|
|
22066
22267
|
}
|
|
22067
22268
|
return lines.join("\n");
|
|
@@ -22071,10 +22272,12 @@ var init_diff_format = __esm({
|
|
|
22071
22272
|
"src/data/config-as-code/diff-format.ts"() {
|
|
22072
22273
|
"use strict";
|
|
22073
22274
|
init_terminal_output();
|
|
22275
|
+
init_base_id();
|
|
22074
22276
|
init_types2();
|
|
22075
22277
|
LABELS = {
|
|
22076
22278
|
record_types: "record type",
|
|
22077
22279
|
relationship_types: "relationship type",
|
|
22280
|
+
file_types: "file type",
|
|
22078
22281
|
inbound_webhooks: "inbound webhook",
|
|
22079
22282
|
triggers: "trigger",
|
|
22080
22283
|
toolsets: "toolset",
|
|
@@ -22296,7 +22499,7 @@ ${RED}${removals.length} ${word} not in your files were left on the base. Re-run
|
|
|
22296
22499
|
);
|
|
22297
22500
|
} else if (autoConfirm || await confirm(
|
|
22298
22501
|
`
|
|
22299
|
-
Delete ${removals.length} server ${word} not in your files? Record types cascade to their records.`
|
|
22502
|
+
Delete ${removals.length} server ${word} not in your files? Record types cascade to their records, file types to their files.`
|
|
22300
22503
|
)) {
|
|
22301
22504
|
for (const removal of removals) {
|
|
22302
22505
|
await deleteEntity(client, baseId2, removal.kind, removal.id);
|
|
@@ -33543,6 +33746,12 @@ var init_resource_paths = __esm({
|
|
|
33543
33746
|
});
|
|
33544
33747
|
|
|
33545
33748
|
// src/knowledge/source.ts
|
|
33749
|
+
function orgSourceKey(orgResourceId) {
|
|
33750
|
+
return `organization resource ${orgResourceId}`;
|
|
33751
|
+
}
|
|
33752
|
+
function hubSourceKey(productionHubId, resourceId) {
|
|
33753
|
+
return `hub ${productionHubId} resource ${resourceId}`;
|
|
33754
|
+
}
|
|
33546
33755
|
function movesFromOrg(resource) {
|
|
33547
33756
|
return resource.resource_type === "knowledge";
|
|
33548
33757
|
}
|
|
@@ -33592,7 +33801,7 @@ function orgSources(resources, rows) {
|
|
|
33592
33801
|
skill_name: r.skill_name,
|
|
33593
33802
|
resource_type: r.resource_type,
|
|
33594
33803
|
created_at: r.created_at,
|
|
33595
|
-
sourceKey:
|
|
33804
|
+
sourceKey: orgSourceKey(r.org_resource_id),
|
|
33596
33805
|
description: r.resource_description ?? "",
|
|
33597
33806
|
folderSchema: r.folder_metadata_schema,
|
|
33598
33807
|
fileSchema: r.file_metadata_schema,
|
|
@@ -33641,7 +33850,7 @@ function hubSources(hubId, resources, rows) {
|
|
|
33641
33850
|
skill_name: r.skill_name,
|
|
33642
33851
|
resource_type: r.resource_type,
|
|
33643
33852
|
created_at: r.created_at,
|
|
33644
|
-
sourceKey:
|
|
33853
|
+
sourceKey: hubSourceKey(hubId, r.resource_id),
|
|
33645
33854
|
description: r.resource_description ?? "",
|
|
33646
33855
|
folderSchema: r.folder_metadata_schema,
|
|
33647
33856
|
fileSchema: r.file_metadata_schema,
|
|
@@ -33712,7 +33921,10 @@ function orgFileTypeId(resource) {
|
|
|
33712
33921
|
return resource.slug;
|
|
33713
33922
|
}
|
|
33714
33923
|
function hubFileTypeId(hubSlug, resource) {
|
|
33715
|
-
return `${hubSlug}
|
|
33924
|
+
return `${hubSlug}${HUB_PART_SEPARATOR}${resource.slug}`;
|
|
33925
|
+
}
|
|
33926
|
+
function hubPartOf(fileTypeId) {
|
|
33927
|
+
return fileTypeId.split(HUB_PART_SEPARATOR)[0];
|
|
33716
33928
|
}
|
|
33717
33929
|
function toolAlias(id) {
|
|
33718
33930
|
const hash = createHash5("sha256").update(id).digest("hex").slice(0, 6);
|
|
@@ -34251,7 +34463,7 @@ function describeSkip(skip) {
|
|
|
34251
34463
|
return `${skip.fileType}: folder "${skip.folder}" has a description but no path, so it gets no ${INDEX_FILE}.`;
|
|
34252
34464
|
}
|
|
34253
34465
|
}
|
|
34254
|
-
var MAX_TOOL_BASE_LENGTH, INDEX_FILE, PROVENANCE_PREFIX, MAX_NAME_LENGTH3, MAX_PATH_LENGTH, TITLE_SCHEMA, TAGS_SCHEMA, MAX_NOTE_VALUES, DEFINITION_KEYS, DRAFT, MAX_PATTERNED_VALUE_LENGTH, SUBSCHEMA_KEYS, SUBSCHEMA_MAP_KEYS;
|
|
34466
|
+
var MAX_TOOL_BASE_LENGTH, INDEX_FILE, PROVENANCE_PREFIX, MAX_NAME_LENGTH3, MAX_PATH_LENGTH, TITLE_SCHEMA, TAGS_SCHEMA, MAX_NOTE_VALUES, HUB_PART_SEPARATOR, DEFINITION_KEYS, DRAFT, MAX_PATTERNED_VALUE_LENGTH, SUBSCHEMA_KEYS, SUBSCHEMA_MAP_KEYS;
|
|
34255
34467
|
var init_plan = __esm({
|
|
34256
34468
|
"src/knowledge/plan.ts"() {
|
|
34257
34469
|
"use strict";
|
|
@@ -34266,6 +34478,7 @@ var init_plan = __esm({
|
|
|
34266
34478
|
TITLE_SCHEMA = { type: "string" };
|
|
34267
34479
|
TAGS_SCHEMA = { type: "array", items: { type: "string" } };
|
|
34268
34480
|
MAX_NOTE_VALUES = 3;
|
|
34481
|
+
HUB_PART_SEPARATOR = "--";
|
|
34269
34482
|
DEFINITION_KEYS = ["$defs", "definitions"];
|
|
34270
34483
|
DRAFT = "2020-12";
|
|
34271
34484
|
MAX_PATTERNED_VALUE_LENGTH = 1024;
|
|
@@ -34373,17 +34586,17 @@ function sameFileType(remote, spec) {
|
|
|
34373
34586
|
function isObject(value) {
|
|
34374
34587
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
34375
34588
|
}
|
|
34376
|
-
function promotionProblems(result, ids) {
|
|
34589
|
+
function promotionProblems(result, ids, section = "file_types") {
|
|
34377
34590
|
const answer = isObject(result) ? result : {};
|
|
34378
34591
|
const problems2 = [];
|
|
34379
|
-
for (const [
|
|
34592
|
+
for (const [kind, bucket2] of Object.entries(isObject(answer.diff) ? answer.diff : {})) {
|
|
34380
34593
|
if (!isObject(bucket2)) continue;
|
|
34381
34594
|
for (const change of ["added", "modified", "removed"]) {
|
|
34382
34595
|
for (const entry of Array.isArray(bucket2[change]) ? bucket2[change] : []) {
|
|
34383
34596
|
const row = isObject(entry) ? isObject(entry.after) ? entry.after : entry : {};
|
|
34384
34597
|
const id = typeof row.id === "string" ? row.id : JSON.stringify(row).slice(0, 80);
|
|
34385
|
-
if (
|
|
34386
|
-
problems2.push(`it would also apply ${
|
|
34598
|
+
if (kind === section && change !== "removed" && ids.has(id)) continue;
|
|
34599
|
+
problems2.push(`it would also apply ${kind} ${change}: "${id}"`);
|
|
34387
34600
|
}
|
|
34388
34601
|
}
|
|
34389
34602
|
}
|
|
@@ -34641,6 +34854,7 @@ function metadataValue(value) {
|
|
|
34641
34854
|
function fileWriteHeaders(opts) {
|
|
34642
34855
|
const headers = {};
|
|
34643
34856
|
if (opts.ifMatch !== void 0) headers["If-Match"] = ifMatchValue(opts.ifMatch);
|
|
34857
|
+
if (opts.createOnly) headers["If-None-Match"] = "*";
|
|
34644
34858
|
if (opts.label !== void 0) headers["X-Data-Label"] = labelValue(opts.label);
|
|
34645
34859
|
if (opts.metadata !== void 0) headers["X-Data-Metadata"] = metadataValue(opts.metadata);
|
|
34646
34860
|
return headers;
|
|
@@ -34652,6 +34866,253 @@ var init_headers = __esm({
|
|
|
34652
34866
|
}
|
|
34653
34867
|
});
|
|
34654
34868
|
|
|
34869
|
+
// src/data/commands/tokens.ts
|
|
34870
|
+
import { Command } from "commander";
|
|
34871
|
+
function rawTokenFrom(data) {
|
|
34872
|
+
const token = typeof data === "object" && data !== null && "token" in data ? data.token : void 0;
|
|
34873
|
+
if (typeof token !== "string" || !RAW_TOKEN_PATTERN.test(token)) {
|
|
34874
|
+
throw new Error("Token creation response did not contain a valid rec_ token");
|
|
34875
|
+
}
|
|
34876
|
+
return token;
|
|
34877
|
+
}
|
|
34878
|
+
function addTokenLifecycleOptions(cmd) {
|
|
34879
|
+
return cmd.option("--expires-at <date>", "Expiration date (ISO 8601, e.g. 2026-06-01T00:00:00Z)").option(
|
|
34880
|
+
"--ttl <duration>",
|
|
34881
|
+
"Relative expiry, e.g. 10m, 2h, 7d (use for disposable probe/test tokens)"
|
|
34882
|
+
).option(
|
|
34883
|
+
"--description <text>",
|
|
34884
|
+
'What holds this token (e.g. "behind credential X"); shown in list and revoke warnings'
|
|
34885
|
+
).addHelpText("after", TOKEN_OUTPUT_HELP);
|
|
34886
|
+
}
|
|
34887
|
+
function tokenCreationOutput(cmd, opts) {
|
|
34888
|
+
return opts.tokenOnly ? "token" : outputFormat(cmd);
|
|
34889
|
+
}
|
|
34890
|
+
function printCreatedToken(data, output) {
|
|
34891
|
+
if (output !== "token") {
|
|
34892
|
+
printOutput(data, output);
|
|
34893
|
+
return;
|
|
34894
|
+
}
|
|
34895
|
+
console.log(rawTokenFrom(data));
|
|
34896
|
+
}
|
|
34897
|
+
function resolveExpiresAt(opts) {
|
|
34898
|
+
if (opts.ttl && opts.expiresAt) {
|
|
34899
|
+
throw expected("--ttl and --expires-at are mutually exclusive \u2014 pass one.");
|
|
34900
|
+
}
|
|
34901
|
+
if (opts.ttl) return new Date(Date.now() + parseDuration(opts.ttl, "--ttl")).toISOString();
|
|
34902
|
+
return opts.expiresAt;
|
|
34903
|
+
}
|
|
34904
|
+
function applyTokenLifecycleOpts(body, opts) {
|
|
34905
|
+
const expiresAt = resolveExpiresAt(opts);
|
|
34906
|
+
if (expiresAt) body.expires_at = expiresAt;
|
|
34907
|
+
if (opts.description) body.description = opts.description;
|
|
34908
|
+
}
|
|
34909
|
+
function listAllTokens(client) {
|
|
34910
|
+
return client.collectPages(
|
|
34911
|
+
(cursor) => `/v1/tokens?limit=${TOKEN_LIST_PAGE_LIMIT}${cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""}`
|
|
34912
|
+
);
|
|
34913
|
+
}
|
|
34914
|
+
function pruneRow(t, reason) {
|
|
34915
|
+
return {
|
|
34916
|
+
token_id: t.token_id,
|
|
34917
|
+
name: t.name,
|
|
34918
|
+
reason,
|
|
34919
|
+
last_used: t.last_used_at ?? "never"
|
|
34920
|
+
};
|
|
34921
|
+
}
|
|
34922
|
+
function buildBasesTokensCommand() {
|
|
34923
|
+
const tokens2 = new Command("tokens").description("Manage API tokens");
|
|
34924
|
+
addTokenLifecycleOptions(
|
|
34925
|
+
tokens2.command("create").description("Create a scoped API token").requiredOption("--name <name>", "Token name").requiredOption("--grants <json>", "Grant definitions as JSON array").option(
|
|
34926
|
+
"--token-only",
|
|
34927
|
+
"Print only the raw rec_ token for secure command substitution (shown once)"
|
|
34928
|
+
)
|
|
34929
|
+
).action(async function(opts) {
|
|
34930
|
+
const grants = parseData(opts.grants, "--grants");
|
|
34931
|
+
const body = { name: opts.name, grants };
|
|
34932
|
+
applyTokenLifecycleOpts(body, opts);
|
|
34933
|
+
const client = await createDataClient();
|
|
34934
|
+
const data = await client.request("POST", "/v1/tokens", body);
|
|
34935
|
+
printCreatedToken(data, tokenCreationOutput(this, opts));
|
|
34936
|
+
});
|
|
34937
|
+
addTokenLifecycleOptions(
|
|
34938
|
+
// The only token verb that addresses a base, so it alone declares `--base`.
|
|
34939
|
+
// Putting it on the `tokens` group would advertise a flag that does nothing
|
|
34940
|
+
// on `list`, `revoke` and `prune` — the defect `withBaseOption` exists to
|
|
34941
|
+
// avoid.
|
|
34942
|
+
withBaseOption(tokens2.command("create-for-toolset <slug>")).description(
|
|
34943
|
+
"Create a toolset-bound (consumer) token whose authorization IS the toolset tool surface \u2014 it can call exactly the tools that toolset exposes (those record types + operations, relationships, batch, and sql only if enabled) and nothing else. Binds to the configured --base."
|
|
34944
|
+
).option("--name <name>", 'Token name (default: "<slug> consumer")').option(
|
|
34945
|
+
"--token-only",
|
|
34946
|
+
"Print only the raw rec_ token for secure command substitution (shown once)"
|
|
34947
|
+
)
|
|
34948
|
+
).action(async function(slug, opts) {
|
|
34949
|
+
const base = requireBase(this);
|
|
34950
|
+
const body = {
|
|
34951
|
+
name: opts.name ?? `${slug} consumer`,
|
|
34952
|
+
toolset_binding: { base_id: base, toolset_id: slug }
|
|
34953
|
+
};
|
|
34954
|
+
applyTokenLifecycleOpts(body, opts);
|
|
34955
|
+
const client = await createDataClient();
|
|
34956
|
+
const data = await client.request("POST", "/v1/tokens", body);
|
|
34957
|
+
const output = tokenCreationOutput(this, opts);
|
|
34958
|
+
printCreatedToken(data, output);
|
|
34959
|
+
if (output === "table") {
|
|
34960
|
+
console.log(`
|
|
34961
|
+
MCP URL: ${toolsetMcpUrl(slug)}`);
|
|
34962
|
+
}
|
|
34963
|
+
});
|
|
34964
|
+
tokens2.command("list").description("List API tokens (status, last_used_at, expires_at, description)").action(async function() {
|
|
34965
|
+
const client = await createDataClient();
|
|
34966
|
+
printOutput(await listAllTokens(client), outputFormat(this));
|
|
34967
|
+
});
|
|
34968
|
+
tokens2.command("revoke <token_id>").description(
|
|
34969
|
+
"Revoke an API token (permanent). A recently-used or toolset-bound token requires --force."
|
|
34970
|
+
).option("--force", "Revoke even if the token appears to be in live use").action(async function(tokenId, opts) {
|
|
34971
|
+
const client = await createDataClient();
|
|
34972
|
+
const id = pathSegment(tokenId, "token id");
|
|
34973
|
+
const path42 = (force) => `/v1/tokens/${id}${force ? "?force=true" : ""}`;
|
|
34974
|
+
const format = outputFormat(this);
|
|
34975
|
+
const revoked = (forced) => printOutput({ token_id: tokenId, revoked: true, forced }, format);
|
|
34976
|
+
if (opts.force) {
|
|
34977
|
+
await client.request("DELETE", path42(true));
|
|
34978
|
+
revoked(true);
|
|
34979
|
+
return;
|
|
34980
|
+
}
|
|
34981
|
+
try {
|
|
34982
|
+
await client.request("DELETE", path42(false));
|
|
34983
|
+
revoked(false);
|
|
34984
|
+
} catch (err) {
|
|
34985
|
+
if (!(err instanceof ApiError) || err.status !== 409 || dataErrorDetails(err)?.requires_force !== true) {
|
|
34986
|
+
throw err;
|
|
34987
|
+
}
|
|
34988
|
+
console.error(err.message);
|
|
34989
|
+
if (!isInteractive()) {
|
|
34990
|
+
console.error("\nRe-run with --force to revoke anyway.");
|
|
34991
|
+
return process.exit(1);
|
|
34992
|
+
}
|
|
34993
|
+
if (!await confirm("Revoke anyway?")) {
|
|
34994
|
+
console.error("Aborted.");
|
|
34995
|
+
return process.exit(1);
|
|
34996
|
+
}
|
|
34997
|
+
await client.request("DELETE", path42(true));
|
|
34998
|
+
revoked(true);
|
|
34999
|
+
}
|
|
35000
|
+
});
|
|
35001
|
+
tokens2.command("prune").description(
|
|
35002
|
+
"Revoke stale tokens, selected by staleness only (expired, or unused past --unused-since) \u2014 never by name. Previews by default; revoking requires --yes or an interactive confirmation."
|
|
35003
|
+
).option(
|
|
35004
|
+
"--unused-since <duration>",
|
|
35005
|
+
"Also prune tokens with no activity for this long (e.g. 30d). Skips toolset-bound and legacy usage-untracked tokens."
|
|
35006
|
+
).option("--include-bound", "Allow pruning stale toolset-bound (consumer) tokens").option("-y, --yes", "Revoke without prompting (required when non-interactive)").action(async function(opts) {
|
|
35007
|
+
const staleMs = opts.unusedSince ? parseDuration(opts.unusedSince, "--unused-since") : void 0;
|
|
35008
|
+
const client = await createDataClient();
|
|
35009
|
+
const allTokens = await listAllTokens(client);
|
|
35010
|
+
const now = Date.now();
|
|
35011
|
+
const targets = [];
|
|
35012
|
+
const skipped = [];
|
|
35013
|
+
for (const t of allTokens) {
|
|
35014
|
+
const expired = t.status ? t.status === "expired" : !!t.expires_at && Date.parse(t.expires_at) <= now;
|
|
35015
|
+
if (expired) {
|
|
35016
|
+
targets.push(pruneRow(t, "expired"));
|
|
35017
|
+
continue;
|
|
35018
|
+
}
|
|
35019
|
+
if (staleMs === void 0) continue;
|
|
35020
|
+
const lastActivity = Date.parse(t.last_used_at ?? t.created_at);
|
|
35021
|
+
if (!(now - lastActivity > staleMs)) continue;
|
|
35022
|
+
if (t.usage_tracked !== true) {
|
|
35023
|
+
skipped.push(
|
|
35024
|
+
pruneRow(
|
|
35025
|
+
t,
|
|
35026
|
+
"usage untracked (legacy token) \u2014 revoke individually if truly unused"
|
|
35027
|
+
)
|
|
35028
|
+
);
|
|
35029
|
+
} else if (t.toolset_binding && !opts.includeBound) {
|
|
35030
|
+
skipped.push(
|
|
35031
|
+
pruneRow(
|
|
35032
|
+
t,
|
|
35033
|
+
`toolset-bound ('${t.toolset_binding.toolset_id}') \u2014 pass --include-bound to prune`
|
|
35034
|
+
)
|
|
35035
|
+
);
|
|
35036
|
+
} else {
|
|
35037
|
+
targets.push(pruneRow(t, `unused for over ${opts.unusedSince}`));
|
|
35038
|
+
}
|
|
35039
|
+
}
|
|
35040
|
+
const format = outputFormat(this);
|
|
35041
|
+
const json = format === "json";
|
|
35042
|
+
const note = (line) => json ? console.error(line) : console.log(line);
|
|
35043
|
+
const printPreview = () => {
|
|
35044
|
+
if (targets.length === 0) {
|
|
35045
|
+
note("Nothing to prune.");
|
|
35046
|
+
} else {
|
|
35047
|
+
note(`Would revoke ${targets.length} token(s):`);
|
|
35048
|
+
if (!json) printOutput(targets, format);
|
|
35049
|
+
}
|
|
35050
|
+
if (skipped.length === 0) return;
|
|
35051
|
+
note(`
|
|
35052
|
+
Skipped ${skipped.length} stale token(s):`);
|
|
35053
|
+
if (!json) printOutput(skipped, format);
|
|
35054
|
+
};
|
|
35055
|
+
printPreview();
|
|
35056
|
+
if (targets.length === 0) {
|
|
35057
|
+
if (json) printOutput({ revoked: 0, failed: 0, targets, skipped }, format);
|
|
35058
|
+
return;
|
|
35059
|
+
}
|
|
35060
|
+
if (!opts.yes) {
|
|
35061
|
+
if (!isInteractive()) {
|
|
35062
|
+
console.error("\nPreview only \u2014 re-run with --yes to revoke these tokens.");
|
|
35063
|
+
if (json) printOutput({ preview: true, revoked: 0, failed: 0, targets, skipped }, format);
|
|
35064
|
+
return process.exit(1);
|
|
35065
|
+
}
|
|
35066
|
+
if (!await confirm(`
|
|
35067
|
+
Revoke ${targets.length} token(s)?`)) {
|
|
35068
|
+
console.error("Aborted.");
|
|
35069
|
+
return process.exit(1);
|
|
35070
|
+
}
|
|
35071
|
+
}
|
|
35072
|
+
let revoked = 0;
|
|
35073
|
+
let failed = 0;
|
|
35074
|
+
for (const t of targets) {
|
|
35075
|
+
try {
|
|
35076
|
+
await client.request(
|
|
35077
|
+
"DELETE",
|
|
35078
|
+
`/v1/tokens/${pathSegment(t.token_id, "token id")}?force=true`
|
|
35079
|
+
);
|
|
35080
|
+
revoked++;
|
|
35081
|
+
} catch (err) {
|
|
35082
|
+
failed++;
|
|
35083
|
+
console.error(
|
|
35084
|
+
`Failed to revoke ${t.token_id} ('${sanitizeTerminalText(t.name)}'): ${err instanceof Error ? err.message : String(err)}`
|
|
35085
|
+
);
|
|
35086
|
+
}
|
|
35087
|
+
}
|
|
35088
|
+
if (json) printOutput({ revoked, failed, targets, skipped }, format);
|
|
35089
|
+
else console.log(`Revoked ${revoked} token(s)${failed > 0 ? `, ${failed} failed` : ""}.`);
|
|
35090
|
+
if (failed > 0) return process.exit(1);
|
|
35091
|
+
});
|
|
35092
|
+
return tokens2;
|
|
35093
|
+
}
|
|
35094
|
+
var RAW_TOKEN_PATTERN, TOKEN_OUTPUT_HELP, TOKEN_LIST_PAGE_LIMIT;
|
|
35095
|
+
var init_tokens = __esm({
|
|
35096
|
+
"src/data/commands/tokens.ts"() {
|
|
35097
|
+
"use strict";
|
|
35098
|
+
init_client();
|
|
35099
|
+
init_output();
|
|
35100
|
+
init_helpers();
|
|
35101
|
+
init_api_client();
|
|
35102
|
+
init_terminal_output();
|
|
35103
|
+
init_utils();
|
|
35104
|
+
init_expected();
|
|
35105
|
+
RAW_TOKEN_PATTERN = /^rec_[A-Za-z0-9_-]{43}$/;
|
|
35106
|
+
TOKEN_OUTPUT_HELP = `
|
|
35107
|
+
Output:
|
|
35108
|
+
--json prints the unwrapped response object; the secret is at top-level .token, never .data.token.
|
|
35109
|
+
--token-only prints only a validated rec_ token and overrides table/JSON formatting.
|
|
35110
|
+
The raw token is shown once. Capture it securely and do not log it.
|
|
35111
|
+
`;
|
|
35112
|
+
TOKEN_LIST_PAGE_LIMIT = 250;
|
|
35113
|
+
}
|
|
35114
|
+
});
|
|
35115
|
+
|
|
34655
35116
|
// src/knowledge/remote.ts
|
|
34656
35117
|
function pacedRequestsPerMinute(path42, fallback) {
|
|
34657
35118
|
const budget = getEndpointConfig(path42)?.userLimit;
|
|
@@ -34702,6 +35163,14 @@ function knowledgeBase(client) {
|
|
|
34702
35163
|
const request = (method, path42, body) => pacer.run(() => client.request(method, path42, body));
|
|
34703
35164
|
const baseSeg = (id) => pathSegment(id, "--base");
|
|
34704
35165
|
const typeSeg = (id) => pathSegment(id, "file type");
|
|
35166
|
+
const toolsetSeg = (id) => pathSegment(id, "toolset slug");
|
|
35167
|
+
const promoteOnly = (production, preview, section, ids, dryRun) => request("POST", `/v1/${baseSeg(production)}/promote`, {
|
|
35168
|
+
source_base_id: preview,
|
|
35169
|
+
dry_run: dryRun,
|
|
35170
|
+
...Object.fromEntries(ENTITY_KINDS.map((kind) => [kind, []])),
|
|
35171
|
+
file_types: [],
|
|
35172
|
+
[section]: ids
|
|
35173
|
+
});
|
|
34705
35174
|
return {
|
|
34706
35175
|
getBase: (id) => unlessMissing(() => pacer.run(() => getBaseRecord(client, id))),
|
|
34707
35176
|
listPreviews: (id) => pacer.run(
|
|
@@ -34713,14 +35182,7 @@ function knowledgeBase(client) {
|
|
|
34713
35182
|
const { id, ...body } = spec;
|
|
34714
35183
|
await request("PUT", `/v1/${baseSeg(base)}/file-types/${typeSeg(id)}`, body);
|
|
34715
35184
|
},
|
|
34716
|
-
|
|
34717
|
-
return request("POST", `/v1/${baseSeg(production)}/promote`, {
|
|
34718
|
-
source_base_id: preview,
|
|
34719
|
-
dry_run: dryRun,
|
|
34720
|
-
...Object.fromEntries(ENTITY_KINDS.map((kind) => [kind, []])),
|
|
34721
|
-
file_types: ids
|
|
34722
|
-
});
|
|
34723
|
-
},
|
|
35185
|
+
promoteFileTypes: (production, preview, ids, dryRun) => promoteOnly(production, preview, "file_types", ids, dryRun),
|
|
34724
35186
|
async listFiles(base, fileType) {
|
|
34725
35187
|
const rows = [];
|
|
34726
35188
|
for (let page = 0; page < MAX_LIST_PAGES; page++) {
|
|
@@ -34731,6 +35193,13 @@ function knowledgeBase(client) {
|
|
|
34731
35193
|
}
|
|
34732
35194
|
throw expected(`The listing of file type "${fileType}" on base "${base}" did not end after ${MAX_LIST_PAGES} pages.`);
|
|
34733
35195
|
},
|
|
35196
|
+
getToolset: (base, slug) => unlessMissing(() => request("GET", `/v1/${baseSeg(base)}/toolsets/${toolsetSeg(slug)}`)),
|
|
35197
|
+
async putToolset(base, spec) {
|
|
35198
|
+
const { id, ...body } = spec;
|
|
35199
|
+
await request("PUT", `/v1/${baseSeg(base)}/toolsets/${toolsetSeg(id)}`, { ...body, actions: [] });
|
|
35200
|
+
},
|
|
35201
|
+
promoteToolsets: (production, preview, slugs, dryRun) => promoteOnly(production, preview, "toolsets", slugs, dryRun),
|
|
35202
|
+
mintToolsetToken: async (base, slug, name) => rawTokenFrom(await request("POST", "/v1/tokens", { name, toolset_binding: { base_id: base, toolset_id: slug } })),
|
|
34734
35203
|
// `requestRaw`: the page is read whole, `{ data: … }`, as WayAI's copy of its answer declares it
|
|
34735
35204
|
// (`@wayai/core/contracts` `rekorFileSnapshotAnswerSchema`).
|
|
34736
35205
|
snapshotPage: (preview, cursor) => pacer.run(() => client.requestRaw("POST", `/v1/${baseSeg(preview)}/files/snapshot`, cursor === void 0 ? {} : { cursor })),
|
|
@@ -34746,7 +35215,70 @@ function knowledgeBase(client) {
|
|
|
34746
35215
|
}
|
|
34747
35216
|
};
|
|
34748
35217
|
}
|
|
34749
|
-
|
|
35218
|
+
function connectionsOf(rows) {
|
|
35219
|
+
return (rows ?? []).flatMap(
|
|
35220
|
+
(c) => c.connection_id ? [{ connection_id: c.connection_id, connection_display_name: c.connection_display_name, connector_id: c.connector_id, settings: c.settings }] : []
|
|
35221
|
+
);
|
|
35222
|
+
}
|
|
35223
|
+
function hubSetup(api, orgId, pacers = {
|
|
35224
|
+
setup: pacerFor(CUT_OVER_BUDGETS.setup, "setup"),
|
|
35225
|
+
automations: pacerFor(CUT_OVER_BUDGETS.automations, "automations")
|
|
35226
|
+
}) {
|
|
35227
|
+
const run = (send) => pacers.setup.run(send);
|
|
35228
|
+
const auto = (send) => pacers.automations.run(send);
|
|
35229
|
+
return {
|
|
35230
|
+
listHubs: async () => hubsOf(await run(() => api.getUserSchema()), orgId),
|
|
35231
|
+
hubDiff: async (hubId) => (await run(() => api.getHubDiff(hubId))).data,
|
|
35232
|
+
// The rows are the hub's `resource` rows whole, the move's mark (`moved_file_type`) among them.
|
|
35233
|
+
listResources: async (hubId) => (await run(() => api.listHubResources(hubId))).data ?? [],
|
|
35234
|
+
listAgents: async (hubId) => (await run(() => api.listAgents(hubId))).data ?? [],
|
|
35235
|
+
listAgentLinks: async (hubId, agentId) => (await run(() => api.listAgentResources(hubId, agentId))).resources ?? [],
|
|
35236
|
+
listAgentTools: async (hubId, agentId) => {
|
|
35237
|
+
const tools = await run(() => api.listAgentTools(hubId, agentId));
|
|
35238
|
+
return { native: tools.tools ?? [], connection: (tools.mcp_tools ?? []).map((t) => ({ ...t, tool_id: t.tool_id ?? null })) };
|
|
35239
|
+
},
|
|
35240
|
+
listConnections: async (hubId) => connectionsOf((await run(() => api.listConnections(hubId))).connections),
|
|
35241
|
+
listAutomations: async (hubId) => (await auto(() => api.listAutomations(hubId))).automations ?? [],
|
|
35242
|
+
// The answer lists the hub's connections, the new one among them.
|
|
35243
|
+
addToolsetConnection: async (hubId, input) => connectionsOf(
|
|
35244
|
+
(await run(
|
|
35245
|
+
() => api.addConnection({
|
|
35246
|
+
hub_id: hubId,
|
|
35247
|
+
connector_id: input.connectorId,
|
|
35248
|
+
connection_display_name: input.name,
|
|
35249
|
+
settings: { [TOOLSET_SLUG_SETTING]: input.toolset },
|
|
35250
|
+
access_token: input.token
|
|
35251
|
+
})
|
|
35252
|
+
)).connections
|
|
35253
|
+
),
|
|
35254
|
+
async syncConnection(hubId, connectionId) {
|
|
35255
|
+
const answer = await run(() => api.syncMcp(hubId, connectionId));
|
|
35256
|
+
if (!answer.success) {
|
|
35257
|
+
throw expected(`Syncing connection ${connectionId}'s tools failed: ${sanitizeTerminalText(answer.message ?? "no reason given")}`);
|
|
35258
|
+
}
|
|
35259
|
+
},
|
|
35260
|
+
async addNativeTool(hubId, agentId, toolNativeId) {
|
|
35261
|
+
await run(() => api.addNativeTool(hubId, agentId, toolNativeId));
|
|
35262
|
+
},
|
|
35263
|
+
async addConnectionTool(hubId, agentId, mcpToolId) {
|
|
35264
|
+
await run(() => api.addMcpTool(hubId, agentId, mcpToolId));
|
|
35265
|
+
},
|
|
35266
|
+
async enableTool(hubId, agentId, toolId) {
|
|
35267
|
+
await run(() => api.enableTool(hubId, agentId, toolId));
|
|
35268
|
+
},
|
|
35269
|
+
async updateAgentText(hubId, agentId, patch) {
|
|
35270
|
+
await run(() => api.updateAgent(hubId, agentId, patch));
|
|
35271
|
+
},
|
|
35272
|
+
async updateAutomationAction(hubId, automationId, action) {
|
|
35273
|
+
await auto(() => api.updateAutomation(hubId, automationId, { action }));
|
|
35274
|
+
},
|
|
35275
|
+
async disableLink(hubId, agentId, resourceId) {
|
|
35276
|
+
await run(() => api.updateAgentResource({ hub_id: hubId, agent_id: agentId, resource_id: resourceId, enabled: false }));
|
|
35277
|
+
},
|
|
35278
|
+
recordMove: async (body) => (await run(() => api.recordKnowledgeMove(body))).data.recorded
|
|
35279
|
+
};
|
|
35280
|
+
}
|
|
35281
|
+
var LIST_PAGE, MAX_LIST_PAGES, MIGRATION_LABEL, READER_BUDGETS, CUT_OVER_BUDGETS;
|
|
34750
35282
|
var init_remote = __esm({
|
|
34751
35283
|
"src/knowledge/remote.ts"() {
|
|
34752
35284
|
"use strict";
|
|
@@ -34759,10 +35291,14 @@ var init_remote = __esm({
|
|
|
34759
35291
|
init_types2();
|
|
34760
35292
|
init_headers();
|
|
34761
35293
|
init_helpers();
|
|
35294
|
+
init_terminal_output();
|
|
35295
|
+
init_tokens();
|
|
35296
|
+
init_rekor_toolset();
|
|
34762
35297
|
LIST_PAGE = 1e3;
|
|
34763
35298
|
MAX_LIST_PAGES = 1e3;
|
|
34764
35299
|
MIGRATION_LABEL = "wayai knowledge migrate";
|
|
34765
35300
|
READER_BUDGETS = { setup: "/api/setup/organization-resources", sign: "/api/files/sign" };
|
|
35301
|
+
CUT_OVER_BUDGETS = { setup: "/api/setup/agents", automations: "/api/automations" };
|
|
34766
35302
|
}
|
|
34767
35303
|
});
|
|
34768
35304
|
|
|
@@ -34797,6 +35333,520 @@ var init_refresh_preview = __esm({
|
|
|
34797
35333
|
}
|
|
34798
35334
|
});
|
|
34799
35335
|
|
|
35336
|
+
// ../../packages/core/dist/catalog/index.js
|
|
35337
|
+
function getConnectors(filter) {
|
|
35338
|
+
if (!filter?.connector_type && !filter?.service_name) return CONNECTORS;
|
|
35339
|
+
return CONNECTORS.filter(
|
|
35340
|
+
(c) => (!filter.connector_type || c.connector_type === filter.connector_type) && (!filter.service_name || c.service_name === filter.service_name)
|
|
35341
|
+
);
|
|
35342
|
+
}
|
|
35343
|
+
function getConnectorById(id) {
|
|
35344
|
+
return connectorById.get(id) ?? null;
|
|
35345
|
+
}
|
|
35346
|
+
function isRekorToolsetConnector(connector) {
|
|
35347
|
+
return connector?.service_name === REKOR_TOOLSET_SERVICE_NAME;
|
|
35348
|
+
}
|
|
35349
|
+
function isRekorToolsetConnectorId(connectorId) {
|
|
35350
|
+
return typeof connectorId === "string" && isRekorToolsetConnector(connectorById.get(connectorId));
|
|
35351
|
+
}
|
|
35352
|
+
var COUNTER_KEYS, STT_PRICING, CONTAINER_PRICING, connectorById, nativeToolById;
|
|
35353
|
+
var init_catalog = __esm({
|
|
35354
|
+
"../../packages/core/dist/catalog/index.js"() {
|
|
35355
|
+
"use strict";
|
|
35356
|
+
init_chunk_GMWMQ4YA();
|
|
35357
|
+
init_chunk_LQSENJ26();
|
|
35358
|
+
init_chunk_UZ7SPBM3();
|
|
35359
|
+
init_chunk_MIWZOSPI();
|
|
35360
|
+
init_chunk_DHPUPI4Y();
|
|
35361
|
+
COUNTER_KEYS = Object.keys({
|
|
35362
|
+
input_tokens: true,
|
|
35363
|
+
output_tokens: true,
|
|
35364
|
+
cache_read_input_tokens: true,
|
|
35365
|
+
cache_creation_input_tokens: true,
|
|
35366
|
+
cache_creation_1h_input_tokens: true
|
|
35367
|
+
});
|
|
35368
|
+
STT_PRICING = {
|
|
35369
|
+
"Openai/whisper-1": { per_second: 6e-3 / 60 },
|
|
35370
|
+
"Openai/gpt-4o-mini-transcribe": { per_second: 3e-3 / 60 },
|
|
35371
|
+
"Groq/whisper-large-v3-turbo": { per_second: 0.04 / 3600 },
|
|
35372
|
+
"ElevenLabs/scribe_v2": { per_second: 0.22 / 3600 }
|
|
35373
|
+
};
|
|
35374
|
+
CONTAINER_PRICING = {
|
|
35375
|
+
anthropic_per_request_usd: 0.05 * 10 / 3600,
|
|
35376
|
+
// $0.05/hr × ~10s/request ≈ $0.000139
|
|
35377
|
+
openai_per_session_usd: 0.03
|
|
35378
|
+
// 1GB tier, 20-min session
|
|
35379
|
+
};
|
|
35380
|
+
connectorById = new Map(CONNECTORS.map((c) => [c.connector_id, c]));
|
|
35381
|
+
nativeToolById = new Map(NATIVE_TOOLS.map((t) => [t.tool_native_id, t]));
|
|
35382
|
+
}
|
|
35383
|
+
});
|
|
35384
|
+
|
|
35385
|
+
// src/knowledge/cut-over.ts
|
|
35386
|
+
import { createHash as createHash6 } from "crypto";
|
|
35387
|
+
import { isDeepStrictEqual as isDeepStrictEqual4 } from "util";
|
|
35388
|
+
function toolsetSlug(productionHubId, fileTypes) {
|
|
35389
|
+
const hash = createHash6("sha256").update([productionHubId, ...fileTypes].join("\n")).digest("hex").slice(0, 12);
|
|
35390
|
+
return `${CUT_OVER_TOOLSET_PREFIX}${hash}`;
|
|
35391
|
+
}
|
|
35392
|
+
function toolsetEntry(fileType) {
|
|
35393
|
+
const base = toolBase(fileType);
|
|
35394
|
+
return { file_type: fileType, operations: [...FILE_OPERATIONS], ...base === fileType ? {} : { name: base } };
|
|
35395
|
+
}
|
|
35396
|
+
function toolsetToolName(op, fileType) {
|
|
35397
|
+
return toolsetFileToolName(toolsetEntry(fileType), op);
|
|
35398
|
+
}
|
|
35399
|
+
function rewriteCitations(text, fileTypeBySlug) {
|
|
35400
|
+
return text.replace(CITATION_RE, (whole, slash, slug) => {
|
|
35401
|
+
const fileType = fileTypeBySlug.get(slug.toLowerCase());
|
|
35402
|
+
return fileType ? `${slash}${DATA_NAMESPACE}/${fileType}` : whole;
|
|
35403
|
+
});
|
|
35404
|
+
}
|
|
35405
|
+
function knowledgePlaceholders(template, losing) {
|
|
35406
|
+
if (losing.length === 0 || !template.includes("{{")) return [];
|
|
35407
|
+
const scan = scanTemplateResources(template);
|
|
35408
|
+
const kinds = scanTemplateResources(template.replace(/\{\{(\s*)files(\s*\()/g, "{{$1resources$2")).legacy_kinds;
|
|
35409
|
+
const uses = [];
|
|
35410
|
+
if (kinds === "all" || kinds === "kb") uses.push("a {{files()}} catalog that lists knowledge");
|
|
35411
|
+
const names = new Set(losing.map((r) => r.name));
|
|
35412
|
+
for (const name of scan.resource_content_names) if (names.has(name)) uses.push(`{{resource_content(${name})}}`);
|
|
35413
|
+
const slugs = new Set(losing.map((r) => r.slug));
|
|
35414
|
+
for (const path42 of scan.file_content_paths) {
|
|
35415
|
+
const [namespace, slug] = cleanRelativePath(path42).split("/");
|
|
35416
|
+
if (namespace?.toLowerCase() === RESOURCE_NAMESPACE && slug && slugs.has(slug.toLowerCase())) {
|
|
35417
|
+
uses.push(`{{file_content(${path42})}}`);
|
|
35418
|
+
}
|
|
35419
|
+
}
|
|
35420
|
+
return uses;
|
|
35421
|
+
}
|
|
35422
|
+
function sameToolset(remote, spec) {
|
|
35423
|
+
if (!remote) return false;
|
|
35424
|
+
const files = (entries) => [...entries ?? []].map((e) => ({ file_type: e.file_type, operations: [...e.operations].sort(), name: e.name ?? null, path_prefix: e.path_prefix || null })).sort((a, b) => a.file_type.localeCompare(b.file_type));
|
|
35425
|
+
return remote.name === spec.name && (remote.description ?? "") === spec.description && (remote.actions ?? []).length === 0 && (remote.relationships ?? []).length === 0 && !remote.batch && !remote.sql_query && isDeepStrictEqual4(files(remote.files), files(spec.files));
|
|
35426
|
+
}
|
|
35427
|
+
function toolsetConnectorId() {
|
|
35428
|
+
const connector = getConnectors().find((c) => isRekorToolsetConnector(c));
|
|
35429
|
+
if (!connector) throw new Error("The Base Toolset connector is missing from the catalog");
|
|
35430
|
+
return connector.connector_id;
|
|
35431
|
+
}
|
|
35432
|
+
function cutOverToolsetOf(connection) {
|
|
35433
|
+
const toolset = connection.settings?.[TOOLSET_SLUG_SETTING];
|
|
35434
|
+
return isRekorToolsetConnectorId(connection.connector_id) && typeof toolset === "string" && CUT_OVER_TOOLSET_RE.test(toolset) ? toolset : null;
|
|
35435
|
+
}
|
|
35436
|
+
function wantedConnectionTools(fileTypes) {
|
|
35437
|
+
return fileTypes.flatMap((ft) => FILE_OPERATIONS.map((op) => toolsetToolName(op, ft)));
|
|
35438
|
+
}
|
|
35439
|
+
function toolWork(tools, wanted, connectionId) {
|
|
35440
|
+
const native = [];
|
|
35441
|
+
const unavailable = [];
|
|
35442
|
+
for (const name of MOUNT_TOOLS) {
|
|
35443
|
+
const row = tools.native.find((t) => t.tool_name === name);
|
|
35444
|
+
if (!row) unavailable.push(name);
|
|
35445
|
+
else if (row.available_action !== "Disable") native.push(row);
|
|
35446
|
+
}
|
|
35447
|
+
const connection = [];
|
|
35448
|
+
const uncatalogued = [];
|
|
35449
|
+
for (const name of wanted) {
|
|
35450
|
+
const row = connectionId ? tools.connection.find((t) => t.connection_id === connectionId && t.tool_name === name) : void 0;
|
|
35451
|
+
if (!row) uncatalogued.push(name);
|
|
35452
|
+
else if (row.available_action !== "Disable") connection.push(row);
|
|
35453
|
+
}
|
|
35454
|
+
return { native, connection, uncatalogued, unavailable };
|
|
35455
|
+
}
|
|
35456
|
+
function describeToolWork(work) {
|
|
35457
|
+
return [
|
|
35458
|
+
...work.native.map((t) => `${t.available_action === "Enable" ? "enable" : "add"} ${t.tool_name}`),
|
|
35459
|
+
...work.connection.map((t) => `${t.available_action === "Enable" ? "enable" : "add"} ${t.tool_name}`),
|
|
35460
|
+
...work.uncatalogued.map((name) => `add ${name}`)
|
|
35461
|
+
];
|
|
35462
|
+
}
|
|
35463
|
+
async function cutOverHub(hub, kb, opts, io) {
|
|
35464
|
+
const { production, preview } = await resolveBases(kb, opts.base, opts.orgId);
|
|
35465
|
+
const stops = [];
|
|
35466
|
+
const hubs = await hub.listHubs();
|
|
35467
|
+
const previewHub = hubs.find((h) => h.hub_id === opts.hubId);
|
|
35468
|
+
if (!previewHub) throw expected(`Hub ${safe2(opts.hubId)} not found in this organization, or you cannot read it.`);
|
|
35469
|
+
if (previewHub.hub_environment !== "preview") {
|
|
35470
|
+
throw expected(`Hub ${safe2(opts.hubId)} is a production hub. A hub is cut over on its preview; publishing carries it to production.`);
|
|
35471
|
+
}
|
|
35472
|
+
const productionHub2 = previewHub.production_hub_id ? hubs.find((h) => h.hub_id === previewHub.production_hub_id) : void 0;
|
|
35473
|
+
if (!productionHub2) {
|
|
35474
|
+
throw expected(`Hub ${safe2(opts.hubId)} has not been published, and its knowledge moved from its production hub. Publish it, then migrate its knowledge first.`);
|
|
35475
|
+
}
|
|
35476
|
+
const productionHubId = productionHub2.hub_id;
|
|
35477
|
+
const fileTypes = await kb.listFileTypes(production);
|
|
35478
|
+
const fileTypeBySource = /* @__PURE__ */ new Map();
|
|
35479
|
+
for (const ft of fileTypes) {
|
|
35480
|
+
const source = provenanceOf(ft.metadata_schema);
|
|
35481
|
+
if (source) fileTypeBySource.set(source, ft.id);
|
|
35482
|
+
}
|
|
35483
|
+
const resources = await hub.listResources(opts.hubId);
|
|
35484
|
+
const ownKnowledge = (rows) => rows.filter((r) => r.resource_type === "knowledge" && !r.org_resource_id);
|
|
35485
|
+
const productionOwn = ownKnowledge(await hub.listResources(productionHubId));
|
|
35486
|
+
const previewOwn = ownKnowledge(resources);
|
|
35487
|
+
const diff = await hub.hubDiff(opts.hubId);
|
|
35488
|
+
const marked = new Set(previewOwn.filter((r) => r.moved_file_type).map((r) => r.resource_name));
|
|
35489
|
+
const knowledgeNames = new Set([...previewOwn, ...productionOwn].map((r) => r.resource_name).filter((name) => !marked.has(name)));
|
|
35490
|
+
const changed = [
|
|
35491
|
+
...diff.resources.filter((e) => knowledgeNames.has(e.name)).map((e) => `resource "${e.name}" (${e.status})`),
|
|
35492
|
+
...(diff.resource_folders ?? []).filter((e) => e.type && knowledgeNames.has(e.type)).map((e) => `a folder of "${e.type}"`),
|
|
35493
|
+
...(diff.resource_files ?? []).filter((e) => e.type && knowledgeNames.has(e.type)).map((e) => `a file of "${e.type}"`)
|
|
35494
|
+
];
|
|
35495
|
+
if (changed.length > 0) {
|
|
35496
|
+
stops.push(
|
|
35497
|
+
`The preview's knowledge resources differ from production's, which moved (${[...new Set(changed)].join(", ")}): sync or discard those changes first, so its agents are cut over to what they read.`
|
|
35498
|
+
);
|
|
35499
|
+
}
|
|
35500
|
+
const fileTypeOf = /* @__PURE__ */ new Map();
|
|
35501
|
+
for (const resource of resources) {
|
|
35502
|
+
if (resource.resource_type !== "knowledge") continue;
|
|
35503
|
+
if (resource.org_resource_id) {
|
|
35504
|
+
const ft2 = fileTypeBySource.get(orgSourceKey(resource.org_resource_id));
|
|
35505
|
+
if (ft2) fileTypeOf.set(resource.resource_id, ft2);
|
|
35506
|
+
continue;
|
|
35507
|
+
}
|
|
35508
|
+
if (resource.moved_file_type) {
|
|
35509
|
+
fileTypeOf.set(resource.resource_id, resource.moved_file_type);
|
|
35510
|
+
continue;
|
|
35511
|
+
}
|
|
35512
|
+
const twins = productionOwn.filter((r) => r.resource_name === resource.resource_name);
|
|
35513
|
+
const previewTwins = previewOwn.filter((r) => r.resource_name === resource.resource_name);
|
|
35514
|
+
if (twins.length > 1 || previewTwins.length > 1) {
|
|
35515
|
+
stops.push(`Two knowledge resources are named "${resource.resource_name}": rename one (in the preview, then sync), so each pairs with its production copy.`);
|
|
35516
|
+
continue;
|
|
35517
|
+
}
|
|
35518
|
+
const ft = twins[0] ? fileTypeBySource.get(hubSourceKey(productionHubId, twins[0].resource_id)) : void 0;
|
|
35519
|
+
if (ft) fileTypeOf.set(resource.resource_id, ft);
|
|
35520
|
+
}
|
|
35521
|
+
const productionHubs = hubs.filter((h) => h.hub_environment === "production");
|
|
35522
|
+
for (const resource of previewOwn) {
|
|
35523
|
+
const ft = fileTypeOf.get(resource.resource_id);
|
|
35524
|
+
if (!ft || resource.moved_file_type) continue;
|
|
35525
|
+
const hubPart = hubPartOf(ft);
|
|
35526
|
+
const holders = productionHubs.filter((h) => slugifySkillName(h.hub_name) === hubPart);
|
|
35527
|
+
if (holders.length > 1) {
|
|
35528
|
+
stops.push(
|
|
35529
|
+
`File type "${ft}" names the hub slug "${hubPart}", which ${holders.length} production hubs share (${holders.map((h) => `"${h.hub_name}"`).join(", ")}): its move can't be recorded until all but one are renamed.`
|
|
35530
|
+
);
|
|
35531
|
+
}
|
|
35532
|
+
}
|
|
35533
|
+
const slugById = buildResourceSlugMap(resources);
|
|
35534
|
+
const fileTypeBySlug = /* @__PURE__ */ new Map();
|
|
35535
|
+
for (const [resourceId, ft] of fileTypeOf) {
|
|
35536
|
+
const slug = slugById.get(resourceId);
|
|
35537
|
+
if (slug) fileTypeBySlug.set(slug, ft);
|
|
35538
|
+
}
|
|
35539
|
+
const byId = new Map(resources.map((r) => [r.resource_id, r]));
|
|
35540
|
+
const connections = await hub.listConnections(opts.hubId);
|
|
35541
|
+
const previewToolsets = /* @__PURE__ */ new Map();
|
|
35542
|
+
const connectionBySlug = /* @__PURE__ */ new Map();
|
|
35543
|
+
for (const connection of connections) {
|
|
35544
|
+
const slug = cutOverToolsetOf(connection);
|
|
35545
|
+
if (!slug) continue;
|
|
35546
|
+
connectionBySlug.set(slug, connection);
|
|
35547
|
+
if (!previewToolsets.has(slug)) previewToolsets.set(slug, await kb.getToolset(preview, slug));
|
|
35548
|
+
}
|
|
35549
|
+
const toolsetTypes = (slug) => (previewToolsets.get(slug)?.files ?? []).map((e) => e.file_type);
|
|
35550
|
+
const slugByConnection = new Map([...connectionBySlug].map(([slug, c]) => [c.connection_id, slug]));
|
|
35551
|
+
const agents = await hub.listAgents(opts.hubId);
|
|
35552
|
+
const plans = [];
|
|
35553
|
+
for (const agent of agents) {
|
|
35554
|
+
const links2 = (await hub.listAgentLinks(opts.hubId, agent.agent_id)).filter((l) => l.resource_type === "knowledge");
|
|
35555
|
+
const enabled = links2.filter((l) => l.enabled);
|
|
35556
|
+
const tools = await hub.listAgentTools(opts.hubId, agent.agent_id);
|
|
35557
|
+
const set = /* @__PURE__ */ new Set();
|
|
35558
|
+
for (const link of enabled) {
|
|
35559
|
+
const ft = fileTypeOf.get(link.resource_id);
|
|
35560
|
+
const resource = byId.get(link.resource_id);
|
|
35561
|
+
if (!ft) {
|
|
35562
|
+
stops.push(
|
|
35563
|
+
`Agent "${agent.agent_name}" reads knowledge resource "${resource?.resource_name ?? link.resource_id}", which has not moved: move it first (\`wayai knowledge migrate --org ${opts.orgId} --base ${opts.base}${resource?.org_resource_id ? "" : ` --hub ${productionHubId}`}\`).`
|
|
35564
|
+
);
|
|
35565
|
+
continue;
|
|
35566
|
+
}
|
|
35567
|
+
set.add(ft);
|
|
35568
|
+
}
|
|
35569
|
+
for (const tool of tools.connection) {
|
|
35570
|
+
const slug = tool.connection_id ? slugByConnection.get(tool.connection_id) : void 0;
|
|
35571
|
+
if (slug && tool.available_action === "Disable") for (const ft of toolsetTypes(slug)) set.add(ft);
|
|
35572
|
+
}
|
|
35573
|
+
const runner = connections.find((c) => c.connection_id === agent.connection_id);
|
|
35574
|
+
if (enabled.length > 0 && runner && getConnectorById(runner.connector_id)?.is_harness === true) {
|
|
35575
|
+
stops.push(
|
|
35576
|
+
`Agent "${agent.agent_name}" runs on a hosted harness, which takes no Base Toolset's tools yet, so it would lose its knowledge: connect it to a toolset through an MCP Server connection, or detach its knowledge links, then run again.`
|
|
35577
|
+
);
|
|
35578
|
+
}
|
|
35579
|
+
const losing = enabled.flatMap((link) => {
|
|
35580
|
+
const resource = byId.get(link.resource_id);
|
|
35581
|
+
const slug = slugById.get(link.resource_id);
|
|
35582
|
+
return resource && slug ? [{ slug, name: resourceDisplayName(resource) }] : [];
|
|
35583
|
+
});
|
|
35584
|
+
for (const [field, template] of [
|
|
35585
|
+
["instructions", agent.instructions],
|
|
35586
|
+
["additional context", agent.additional_context_template]
|
|
35587
|
+
]) {
|
|
35588
|
+
for (const use of knowledgePlaceholders(template ?? "", losing)) {
|
|
35589
|
+
stops.push(
|
|
35590
|
+
`Agent "${agent.agent_name}" uses ${use} in its ${field}, which reads nothing once its knowledge moves (K19): move that text into its instructions or a skill, then run again.`
|
|
35591
|
+
);
|
|
35592
|
+
}
|
|
35593
|
+
}
|
|
35594
|
+
if (set.size > 0 || enabled.length > 0) plans.push({ agent, fileTypes: [...set].sort(), linksToDisable: enabled, tools });
|
|
35595
|
+
}
|
|
35596
|
+
const groups = /* @__PURE__ */ new Map();
|
|
35597
|
+
for (const plan of plans) {
|
|
35598
|
+
if (plan.fileTypes.length === 0) continue;
|
|
35599
|
+
const slug = toolsetSlug(productionHubId, plan.fileTypes);
|
|
35600
|
+
const group = groups.get(slug);
|
|
35601
|
+
if (group) {
|
|
35602
|
+
group.agents.push(plan.agent);
|
|
35603
|
+
plan.group = group;
|
|
35604
|
+
continue;
|
|
35605
|
+
}
|
|
35606
|
+
plan.group = {
|
|
35607
|
+
slug,
|
|
35608
|
+
fileTypes: plan.fileTypes,
|
|
35609
|
+
agents: [plan.agent],
|
|
35610
|
+
connection: connectionBySlug.get(slug),
|
|
35611
|
+
created: !connectionBySlug.has(slug),
|
|
35612
|
+
spec: {
|
|
35613
|
+
id: slug,
|
|
35614
|
+
name: `Knowledge of ${previewHub.hub_name}`.slice(0, 200),
|
|
35615
|
+
description: `Read-only knowledge for agents of hub ${productionHubId}, written by wayai knowledge cut-over: list and get on ${plan.fileTypes.join(", ")}.`,
|
|
35616
|
+
files: plan.fileTypes.map(toolsetEntry)
|
|
35617
|
+
}
|
|
35618
|
+
};
|
|
35619
|
+
groups.set(slug, plan.group);
|
|
35620
|
+
}
|
|
35621
|
+
const plannedTypes = [...new Set([...groups.values()].flatMap((g) => g.fileTypes))].sort();
|
|
35622
|
+
const missing = [];
|
|
35623
|
+
for (const ft of plannedTypes) {
|
|
35624
|
+
const [inProduction, inPreview] = await Promise.all([kb.listFiles(production, ft), filesOrNone(kb, preview, ft)]);
|
|
35625
|
+
const there = new Set(inPreview.map((f) => f.path));
|
|
35626
|
+
for (const file of inProduction) if (!there.has(file.path)) missing.push(`${ft}/${file.path}`);
|
|
35627
|
+
}
|
|
35628
|
+
if (missing.length > 0) {
|
|
35629
|
+
stops.push(
|
|
35630
|
+
`The preview base "${preview}" lacks ${missing.length} file(s) production holds (${missing.slice(0, 5).join(", ")}${missing.length > 5 ? ", \u2026" : ""}), so the preview's agents would read none of them: copy them in with \`${refreshPreviewCommand(opts.orgId, opts.base)}\`, then run again.`
|
|
35631
|
+
);
|
|
35632
|
+
}
|
|
35633
|
+
const toolsetsToWrite = [];
|
|
35634
|
+
const toolsetsToPromote = [];
|
|
35635
|
+
for (const group of groups.values()) {
|
|
35636
|
+
const [inPreview, inProduction] = await Promise.all([
|
|
35637
|
+
previewToolsets.has(group.slug) ? previewToolsets.get(group.slug) : kb.getToolset(preview, group.slug),
|
|
35638
|
+
kb.getToolset(production, group.slug)
|
|
35639
|
+
]);
|
|
35640
|
+
if (!sameToolset(inPreview, group.spec)) toolsetsToWrite.push(group.spec);
|
|
35641
|
+
if (!sameToolset(inProduction, group.spec)) toolsetsToPromote.push(group.spec);
|
|
35642
|
+
}
|
|
35643
|
+
const connectionsToCreate = [...groups.values()].filter((g) => g.created);
|
|
35644
|
+
const toolLines = [];
|
|
35645
|
+
let toolWrites = 0;
|
|
35646
|
+
for (const plan of plans) {
|
|
35647
|
+
const group = plan.group;
|
|
35648
|
+
if (!group) continue;
|
|
35649
|
+
const work = toolWork(plan.tools, wantedConnectionTools(group.fileTypes), group.connection?.connection_id);
|
|
35650
|
+
for (const name of work.unavailable) stops.push(`Agent "${plan.agent.agent_name}" can't be given ${name}: the hub offers it no such tool.`);
|
|
35651
|
+
const lines = describeToolWork(work);
|
|
35652
|
+
toolWrites += lines.length;
|
|
35653
|
+
if (lines.length > 0) toolLines.push(` ${safe2(plan.agent.agent_name)}: ${lines.map(safe2).join(", ")} (${group.slug})`);
|
|
35654
|
+
}
|
|
35655
|
+
const agentRewrites = [];
|
|
35656
|
+
for (const agent of agents) {
|
|
35657
|
+
const patch = {};
|
|
35658
|
+
const instructions = rewriteCitations(agent.instructions ?? "", fileTypeBySlug);
|
|
35659
|
+
if (instructions !== (agent.instructions ?? "")) patch.instructions = instructions;
|
|
35660
|
+
const context = rewriteCitations(agent.additional_context_template ?? "", fileTypeBySlug);
|
|
35661
|
+
if (context !== (agent.additional_context_template ?? "")) patch.additional_context_template = context;
|
|
35662
|
+
if (Object.keys(patch).length > 0) agentRewrites.push({ agent, patch });
|
|
35663
|
+
}
|
|
35664
|
+
const automationRewrites = [];
|
|
35665
|
+
for (const automation of await hub.listAutomations(opts.hubId)) {
|
|
35666
|
+
const text = automation.action.type === "run_agent" ? automation.action.instructions : null;
|
|
35667
|
+
if (!text) continue;
|
|
35668
|
+
const rewritten = rewriteCitations(text, fileTypeBySlug);
|
|
35669
|
+
if (rewritten !== text) automationRewrites.push({ automation, action: { ...automation.action, instructions: rewritten } });
|
|
35670
|
+
}
|
|
35671
|
+
const moves = [];
|
|
35672
|
+
for (const resource of previewOwn) {
|
|
35673
|
+
const ft = fileTypeOf.get(resource.resource_id);
|
|
35674
|
+
if (!ft || resource.moved_file_type) continue;
|
|
35675
|
+
moves.push({
|
|
35676
|
+
body: { scope: "hub", hub_id: opts.hubId, resource_id: resource.resource_id, file_type: ft, base_id: production },
|
|
35677
|
+
label: `hub resource "${resource.resource_name}" \u2192 ${ft}`
|
|
35678
|
+
});
|
|
35679
|
+
}
|
|
35680
|
+
const orgRecorded = /* @__PURE__ */ new Set();
|
|
35681
|
+
for (const plan of plans) {
|
|
35682
|
+
for (const link of plan.linksToDisable) {
|
|
35683
|
+
const resource = byId.get(link.resource_id);
|
|
35684
|
+
const ft = fileTypeOf.get(link.resource_id);
|
|
35685
|
+
if (!resource?.org_resource_id || !ft || orgRecorded.has(resource.org_resource_id)) continue;
|
|
35686
|
+
orgRecorded.add(resource.org_resource_id);
|
|
35687
|
+
moves.push({
|
|
35688
|
+
body: { scope: "organization", organization_id: opts.orgId, org_resource_id: resource.org_resource_id, file_type: ft, base_id: production },
|
|
35689
|
+
label: `organization resource "${resource.resource_name}" \u2192 ${ft}`
|
|
35690
|
+
});
|
|
35691
|
+
}
|
|
35692
|
+
}
|
|
35693
|
+
const links = plans.flatMap((plan) => plan.linksToDisable.map((link) => ({ plan, link })));
|
|
35694
|
+
const result = {
|
|
35695
|
+
toolsets: [...groups.values()].map((g) => ({ slug: g.slug, fileTypes: g.fileTypes, agents: g.agents.map((a) => a.agent_name) })),
|
|
35696
|
+
toolsetsWritten: toolsetsToWrite.map((s) => s.id),
|
|
35697
|
+
toolsetsPromoted: toolsetsToPromote.map((s) => s.id),
|
|
35698
|
+
connectionsCreated: connectionsToCreate.map((g) => g.slug),
|
|
35699
|
+
toolsAssigned: toolLines,
|
|
35700
|
+
agentsRewritten: agentRewrites.map((r) => r.agent.agent_name),
|
|
35701
|
+
automationsRewritten: automationRewrites.map((r) => r.automation.name),
|
|
35702
|
+
movesRecorded: moves.map((m) => m.label),
|
|
35703
|
+
linksDisabled: links.map(({ plan, link }) => `${plan.agent.agent_name}: ${byId.get(link.resource_id)?.resource_name ?? link.resource_id}`),
|
|
35704
|
+
written: false
|
|
35705
|
+
};
|
|
35706
|
+
io.log(`Cut-over of hub "${safe2(previewHub.hub_name)}" (${opts.hubId}) to base "${safe2(production)}" (toolsets written in "${safe2(preview)}")`);
|
|
35707
|
+
io.log("\nToolsets (read-only: list and get):");
|
|
35708
|
+
if (groups.size === 0) io.log(" (none: no agent reads moved knowledge)");
|
|
35709
|
+
for (const group of groups.values()) {
|
|
35710
|
+
const mark = toolsetsToPromote.includes(group.spec) || toolsetsToWrite.includes(group.spec) ? "+" : "=";
|
|
35711
|
+
io.log(` ${mark} ${group.slug}: ${group.fileTypes.map(safe2).join(", ")} \u2014 ${group.agents.map((a) => safe2(a.agent_name)).join(", ")}`);
|
|
35712
|
+
}
|
|
35713
|
+
io.log("\nConnections:");
|
|
35714
|
+
for (const group of groups.values()) {
|
|
35715
|
+
io.log(` ${group.connection ? "=" : "+"} Base Toolset "${group.slug}"${group.connection ? "" : ", with a new token bound to it on the preview base"}`);
|
|
35716
|
+
}
|
|
35717
|
+
io.log("\nAgent tools:");
|
|
35718
|
+
if (toolLines.length === 0) io.log(" (nothing to assign)");
|
|
35719
|
+
for (const line of toolLines) io.log(line);
|
|
35720
|
+
io.log("\nPaths rewritten to data/ (K13):");
|
|
35721
|
+
if (agentRewrites.length + automationRewrites.length === 0) io.log(" (none)");
|
|
35722
|
+
for (const { agent, patch } of agentRewrites) io.log(` agent "${safe2(agent.agent_name)}": ${Object.keys(patch).join(", ")}`);
|
|
35723
|
+
for (const { automation } of automationRewrites) io.log(` automation "${safe2(automation.name)}": instructions`);
|
|
35724
|
+
io.log("\nMoves recorded:");
|
|
35725
|
+
if (moves.length === 0) io.log(" (none)");
|
|
35726
|
+
for (const move of moves) io.log(` + ${safe2(move.label)}`);
|
|
35727
|
+
io.log("\nKnowledge links disabled:");
|
|
35728
|
+
if (links.length === 0) io.log(" (none)");
|
|
35729
|
+
for (const line of result.linksDisabled) io.log(` - ${safe2(line)}`);
|
|
35730
|
+
if (stops.length > 0) {
|
|
35731
|
+
io.log("\nStopped:");
|
|
35732
|
+
for (const stop of stops) io.log(` ${safe2(stop)}`);
|
|
35733
|
+
throw expected(`The cut-over stops on ${stops.length} reason(s) above; nothing was written.`);
|
|
35734
|
+
}
|
|
35735
|
+
const writes = toolsetsToWrite.length + toolsetsToPromote.length + connectionsToCreate.length + toolWrites + agentRewrites.length + automationRewrites.length + moves.length + links.length;
|
|
35736
|
+
const printProduction = () => printProductionSteps(io, opts, production, productionHubId, [...groups.values()]);
|
|
35737
|
+
if (opts.dryRun) {
|
|
35738
|
+
io.log(`
|
|
35739
|
+
Dry run: nothing written (${writes === 0 ? "nothing to write" : `${writes} write(s) planned`}).`);
|
|
35740
|
+
printProduction();
|
|
35741
|
+
return result;
|
|
35742
|
+
}
|
|
35743
|
+
if (writes === 0) {
|
|
35744
|
+
io.log("\nNothing to write: this hub is cut over.");
|
|
35745
|
+
printProduction();
|
|
35746
|
+
return result;
|
|
35747
|
+
}
|
|
35748
|
+
if (!opts.yes && !await io.confirm(`Make these ${writes} change(s) to the preview hub and its knowledge base?`)) {
|
|
35749
|
+
io.log("Cancelled.");
|
|
35750
|
+
return result;
|
|
35751
|
+
}
|
|
35752
|
+
for (const move of moves) await hub.recordMove(move.body);
|
|
35753
|
+
for (const spec of toolsetsToWrite) await kb.putToolset(preview, spec);
|
|
35754
|
+
if (toolsetsToPromote.length > 0) {
|
|
35755
|
+
const slugs = toolsetsToPromote.map((s) => s.id);
|
|
35756
|
+
const problems2 = promotionProblems(await kb.promoteToolsets(production, preview, slugs, true), new Set(slugs), "toolsets");
|
|
35757
|
+
if (problems2.length > 0) {
|
|
35758
|
+
throw expected(
|
|
35759
|
+
`The promotion into "${safe2(production)}" would not apply as planned (${problems2.map(safe2).join("; ")}). The toolsets are written in "${safe2(preview)}"; nothing reached production, and the hub's agents are unchanged.`
|
|
35760
|
+
);
|
|
35761
|
+
}
|
|
35762
|
+
await kb.promoteToolsets(production, preview, slugs, false);
|
|
35763
|
+
}
|
|
35764
|
+
if (connectionsToCreate.length > 0) {
|
|
35765
|
+
const connectorId = toolsetConnectorId();
|
|
35766
|
+
for (const group of connectionsToCreate) {
|
|
35767
|
+
const token = await kb.mintToolsetToken(preview, group.slug, `${group.slug} (hub ${opts.hubId})`);
|
|
35768
|
+
const after = await hub.addToolsetConnection(opts.hubId, { connectorId, name: group.slug, toolset: group.slug, token });
|
|
35769
|
+
group.connection = after.find((c) => cutOverToolsetOf(c) === group.slug);
|
|
35770
|
+
if (!group.connection) throw new Error(`The Base Toolset connection "${group.slug}" was not found after it was created.`);
|
|
35771
|
+
}
|
|
35772
|
+
}
|
|
35773
|
+
const synced2 = /* @__PURE__ */ new Set();
|
|
35774
|
+
for (const plan of plans) {
|
|
35775
|
+
const group = plan.group;
|
|
35776
|
+
if (!group?.connection) continue;
|
|
35777
|
+
const connectionId = group.connection.connection_id;
|
|
35778
|
+
const wanted = wantedConnectionTools(group.fileTypes);
|
|
35779
|
+
const stale = group.created || synced2.has(connectionId);
|
|
35780
|
+
let tools = stale ? await hub.listAgentTools(opts.hubId, plan.agent.agent_id) : plan.tools;
|
|
35781
|
+
let work = toolWork(tools, wanted, connectionId);
|
|
35782
|
+
if (work.uncatalogued.length > 0 && !synced2.has(connectionId)) {
|
|
35783
|
+
await hub.syncConnection(opts.hubId, connectionId);
|
|
35784
|
+
synced2.add(connectionId);
|
|
35785
|
+
tools = await hub.listAgentTools(opts.hubId, plan.agent.agent_id);
|
|
35786
|
+
work = toolWork(tools, wanted, connectionId);
|
|
35787
|
+
}
|
|
35788
|
+
if (work.uncatalogued.length > 0) {
|
|
35789
|
+
throw new Error(
|
|
35790
|
+
`Connection "${group.slug}" catalogs no ${safe2(work.uncatalogued.join(", "))} after a sync, so agent "${safe2(plan.agent.agent_name)}" can't be given them.`
|
|
35791
|
+
);
|
|
35792
|
+
}
|
|
35793
|
+
for (const tool of [...work.native, ...work.connection]) {
|
|
35794
|
+
if (tool.available_action === "Enable" && tool.tool_id) await hub.enableTool(opts.hubId, plan.agent.agent_id, tool.tool_id);
|
|
35795
|
+
else if (tool.tool_native_id) await hub.addNativeTool(opts.hubId, plan.agent.agent_id, tool.tool_native_id);
|
|
35796
|
+
else if (tool.mcp_tool_id) await hub.addConnectionTool(opts.hubId, plan.agent.agent_id, tool.mcp_tool_id);
|
|
35797
|
+
}
|
|
35798
|
+
}
|
|
35799
|
+
for (const { agent, patch } of agentRewrites) await hub.updateAgentText(opts.hubId, agent.agent_id, patch);
|
|
35800
|
+
for (const { automation, action } of automationRewrites) await hub.updateAutomationAction(opts.hubId, automation.automation_id, action);
|
|
35801
|
+
for (const { plan, link } of links) await hub.disableLink(opts.hubId, plan.agent.agent_id, link.resource_id);
|
|
35802
|
+
io.log(`
|
|
35803
|
+
Done: the preview hub's agents read their knowledge from "${safe2(preview)}" through ${groups.size} toolset(s).`);
|
|
35804
|
+
printProduction();
|
|
35805
|
+
return { ...result, written: true };
|
|
35806
|
+
}
|
|
35807
|
+
async function filesOrNone(kb, base, fileType) {
|
|
35808
|
+
try {
|
|
35809
|
+
return await kb.listFiles(base, fileType);
|
|
35810
|
+
} catch (err) {
|
|
35811
|
+
if (err instanceof ApiError && err.status === 404) return [];
|
|
35812
|
+
throw err;
|
|
35813
|
+
}
|
|
35814
|
+
}
|
|
35815
|
+
function printProductionSteps(io, opts, production, productionHubId, groups) {
|
|
35816
|
+
if (groups.length === 0) return;
|
|
35817
|
+
io.log("\nProduction (not run by this command), once the preview passes its evals:");
|
|
35818
|
+
io.log(` 1. Publish the preview: wayai publish --hub ${opts.hubId}`);
|
|
35819
|
+
io.log(" 2. For each toolset, mint a token bound to it on the production base, and save it on production's connection:");
|
|
35820
|
+
for (const group of groups) {
|
|
35821
|
+
io.log(
|
|
35822
|
+
` wayai bases tokens create-for-toolset ${group.slug} --base ${safe2(production)} --token-only | wayai set-connection-credential --hub ${productionHubId} --connection "${group.slug}" --field access_token --stdin`
|
|
35823
|
+
);
|
|
35824
|
+
}
|
|
35825
|
+
}
|
|
35826
|
+
var CUT_OVER_TOOLSET_PREFIX, CUT_OVER_TOOLSET_RE, FILE_OPERATIONS, MOUNT_TOOLS, DATA_NAMESPACE, safe2, CITATION_RE;
|
|
35827
|
+
var init_cut_over = __esm({
|
|
35828
|
+
"src/knowledge/cut-over.ts"() {
|
|
35829
|
+
"use strict";
|
|
35830
|
+
init_dist();
|
|
35831
|
+
init_catalog();
|
|
35832
|
+
init_rekor_toolset();
|
|
35833
|
+
init_resource_paths();
|
|
35834
|
+
init_expected();
|
|
35835
|
+
init_terminal_output();
|
|
35836
|
+
init_api_client();
|
|
35837
|
+
init_migrate2();
|
|
35838
|
+
init_plan();
|
|
35839
|
+
init_source();
|
|
35840
|
+
CUT_OVER_TOOLSET_PREFIX = "knowledge-";
|
|
35841
|
+
CUT_OVER_TOOLSET_RE = /^knowledge-[0-9a-f]{12}$/;
|
|
35842
|
+
FILE_OPERATIONS = ["list", "get"];
|
|
35843
|
+
MOUNT_TOOLS = ["list_files", "read_file"];
|
|
35844
|
+
DATA_NAMESPACE = "data";
|
|
35845
|
+
safe2 = (text) => sanitizeTerminalText(text);
|
|
35846
|
+
CITATION_RE = /(?<![\w./-])(\/?)resources\/([a-z0-9]+(?:-[a-z0-9]+)*)(?![a-z0-9_]|-[a-z0-9]|\.\w)/gi;
|
|
35847
|
+
}
|
|
35848
|
+
});
|
|
35849
|
+
|
|
34800
35850
|
// src/commands/knowledge.ts
|
|
34801
35851
|
var knowledge_exports = {};
|
|
34802
35852
|
__export(knowledge_exports, {
|
|
@@ -34818,7 +35868,7 @@ function readArgs(args2) {
|
|
|
34818
35868
|
function parseKnowledgeArgs(args2) {
|
|
34819
35869
|
const { values, positionals } = readArgs(args2);
|
|
34820
35870
|
const [verb, ...extra] = positionals;
|
|
34821
|
-
if (verb !== "migrate" && verb !== "refresh-preview") {
|
|
35871
|
+
if (verb !== "migrate" && verb !== "refresh-preview" && verb !== "cut-over") {
|
|
34822
35872
|
throw usageError3(verb === void 0 ? "No subcommand given." : `Unknown subcommand ${JSON.stringify(verb)}.`);
|
|
34823
35873
|
}
|
|
34824
35874
|
if (extra.length > 0) throw usageError3(`Unexpected argument ${JSON.stringify(extra[0])}.`);
|
|
@@ -34826,13 +35876,17 @@ function parseKnowledgeArgs(args2) {
|
|
|
34826
35876
|
if (!UUID_RE3.test(values.org)) throw usageError3(`Invalid --org ${JSON.stringify(values.org)}: expected an organization id (a UUID).`);
|
|
34827
35877
|
if (!values.base) throw usageError3("--base <knowledge base> is required.");
|
|
34828
35878
|
if (verb === "refresh-preview") {
|
|
34829
|
-
if (values.hub !== void 0) throw usageError3("--hub is migrate's: a refresh copies the whole knowledge base.");
|
|
34830
|
-
if (values["dry-run"] !== void 0) throw usageError3("--dry-run is migrate's: a refresh has none.");
|
|
35879
|
+
if (values.hub !== void 0) throw usageError3("--hub is migrate's and cut-over's: a refresh copies the whole knowledge base.");
|
|
35880
|
+
if (values["dry-run"] !== void 0) throw usageError3("--dry-run is migrate's and cut-over's: a refresh has none.");
|
|
34831
35881
|
return { verb, orgId: values.org, base: values.base, yes: values.yes === true };
|
|
34832
35882
|
}
|
|
34833
35883
|
if (values.hub !== void 0 && !UUID_RE3.test(values.hub)) {
|
|
34834
35884
|
throw usageError3(`Invalid --hub ${JSON.stringify(values.hub)}: expected a hub id (a UUID).`);
|
|
34835
35885
|
}
|
|
35886
|
+
if (verb === "cut-over") {
|
|
35887
|
+
if (values.hub === void 0) throw usageError3("--hub <preview hub_id> is required: a cut-over is one preview hub's.");
|
|
35888
|
+
return { verb, orgId: values.org, base: values.base, hubId: values.hub, dryRun: values["dry-run"] === true, yes: values.yes === true };
|
|
35889
|
+
}
|
|
34836
35890
|
return {
|
|
34837
35891
|
verb,
|
|
34838
35892
|
orgId: values.org,
|
|
@@ -34860,10 +35914,12 @@ async function knowledgeCommand(args2) {
|
|
|
34860
35914
|
const { config, accessToken } = await requireAuth();
|
|
34861
35915
|
const api = new ApiClient({ apiUrl: config.api_url, accessToken, onUnauthorized: () => getAccessToken(config) });
|
|
34862
35916
|
const data = await createDataClient(options.orgId, { refreshLogin: true });
|
|
34863
|
-
|
|
34864
|
-
|
|
34865
|
-
|
|
34866
|
-
|
|
35917
|
+
const io = { log: (line) => console.log(line), confirm };
|
|
35918
|
+
if (options.verb === "cut-over") {
|
|
35919
|
+
await cutOverHub(hubSetup(api, options.orgId), knowledgeBase(data), options, io);
|
|
35920
|
+
return;
|
|
35921
|
+
}
|
|
35922
|
+
await migrateKnowledge(knowledgeReader(api, options.orgId), knowledgeBase(data), options, io);
|
|
34867
35923
|
}
|
|
34868
35924
|
var USAGE4, OPTIONS;
|
|
34869
35925
|
var init_knowledge = __esm({
|
|
@@ -34878,12 +35934,14 @@ var init_knowledge = __esm({
|
|
|
34878
35934
|
init_migrate2();
|
|
34879
35935
|
init_remote();
|
|
34880
35936
|
init_refresh_preview();
|
|
35937
|
+
init_cut_over();
|
|
34881
35938
|
USAGE4 = `
|
|
34882
35939
|
wayai knowledge \u2014 the organization's knowledge base
|
|
34883
35940
|
|
|
34884
35941
|
Usage:
|
|
34885
35942
|
wayai knowledge migrate --org <org_id> --base <knowledge base> [--hub <hub_id>] [--dry-run] [-y]
|
|
34886
35943
|
wayai knowledge refresh-preview --org <org_id> --base <knowledge base> [-y]
|
|
35944
|
+
wayai knowledge cut-over --org <org_id> --base <knowledge base> --hub <preview hub_id> [--dry-run] [-y]
|
|
34887
35945
|
|
|
34888
35946
|
migrate: move knowledge resources into the organization's knowledge base.
|
|
34889
35947
|
|
|
@@ -34905,6 +35963,21 @@ refresh-preview: make the knowledge base's preview hold its production base's fi
|
|
|
34905
35963
|
|
|
34906
35964
|
--base The production knowledge base, or its preview.
|
|
34907
35965
|
-y, --yes Skip the question before copying.
|
|
35966
|
+
|
|
35967
|
+
cut-over: switch a preview hub's agents from their knowledge resources to the knowledge base, once
|
|
35968
|
+
its knowledge has moved. Each distinct set of knowledge its agents read gets one read-only
|
|
35969
|
+
toolset on the knowledge base, reached through a Base Toolset connection; each agent is given
|
|
35970
|
+
list_files, read_file and its toolset's list_ and get_ tools, its resources/<slug>/ paths become
|
|
35971
|
+
data/<file type>/, its knowledge links are disabled, and each move is recorded. It changes the
|
|
35972
|
+
preview only, and prints the production steps. The preview base must hold production's files
|
|
35973
|
+
first (refresh-preview): the preview's agents read them there. It stops before writing on a resource placeholder
|
|
35974
|
+
({{files()}}, {{resource_content()}}, {{file_content()}}) that reads knowledge an agent is about
|
|
35975
|
+
to lose: move that text into its instructions or a skill first.
|
|
35976
|
+
|
|
35977
|
+
--hub The preview hub.
|
|
35978
|
+
--base The production knowledge base, or its preview.
|
|
35979
|
+
--dry-run List every change, and every reason it would stop, without writing.
|
|
35980
|
+
-y, --yes Skip the question before writing.
|
|
34908
35981
|
`;
|
|
34909
35982
|
OPTIONS = {
|
|
34910
35983
|
org: { type: "string" },
|
|
@@ -34960,17 +36033,17 @@ async function adminCommand(args2) {
|
|
|
34960
36033
|
process.exit(1);
|
|
34961
36034
|
}
|
|
34962
36035
|
if (group === "archive") {
|
|
34963
|
-
const { positional: positional2, flagArgs: flagArgs2 } =
|
|
36036
|
+
const { positional: positional2, flagArgs: flagArgs2 } = splitArgs2(afterGroup);
|
|
34964
36037
|
await runArchiveRead(positional2, flagArgs2);
|
|
34965
36038
|
return;
|
|
34966
36039
|
}
|
|
34967
36040
|
if (group === "observability") {
|
|
34968
|
-
const { positional: positional2, flagArgs: flagArgs2 } =
|
|
36041
|
+
const { positional: positional2, flagArgs: flagArgs2 } = splitArgs2(afterGroup);
|
|
34969
36042
|
await runObservabilityRead(positional2, flagArgs2);
|
|
34970
36043
|
return;
|
|
34971
36044
|
}
|
|
34972
36045
|
const [sub, ...rest] = afterGroup;
|
|
34973
|
-
const { positional, flagArgs } =
|
|
36046
|
+
const { positional, flagArgs } = splitArgs2(rest);
|
|
34974
36047
|
if (group === "do") {
|
|
34975
36048
|
if (!sub) {
|
|
34976
36049
|
printHelp2();
|
|
@@ -35258,7 +36331,7 @@ async function adminCommand(args2) {
|
|
|
35258
36331
|
printHelp2();
|
|
35259
36332
|
process.exit(1);
|
|
35260
36333
|
}
|
|
35261
|
-
function
|
|
36334
|
+
function splitArgs2(args2) {
|
|
35262
36335
|
const positional = [];
|
|
35263
36336
|
const flagArgs = [];
|
|
35264
36337
|
for (const a of args2) {
|
|
@@ -37383,9 +38456,9 @@ var init_update = __esm({
|
|
|
37383
38456
|
});
|
|
37384
38457
|
|
|
37385
38458
|
// src/data/commands/actions.ts
|
|
37386
|
-
import { Command } from "commander";
|
|
38459
|
+
import { Command as Command2 } from "commander";
|
|
37387
38460
|
function buildActionsCommand() {
|
|
37388
|
-
const actions = new
|
|
38461
|
+
const actions = new Command2("actions").description(
|
|
37389
38462
|
"Manage Actions \u2014 reusable, named definitions: one record_type + one operation, or a composite of atomic write steps (--config with `steps`)"
|
|
37390
38463
|
);
|
|
37391
38464
|
actions.command("upsert <id>").description(
|
|
@@ -37454,7 +38527,7 @@ var init_actions = __esm({
|
|
|
37454
38527
|
});
|
|
37455
38528
|
|
|
37456
38529
|
// src/data/commands/attachments.ts
|
|
37457
|
-
import { Command as
|
|
38530
|
+
import { Command as Command3 } from "commander";
|
|
37458
38531
|
import { readFileSync as readFileSync19 } from "fs";
|
|
37459
38532
|
function findAttachmentByFilename(attachments, filename) {
|
|
37460
38533
|
return attachments.find((a) => a.key.endsWith(`/${filename}`)) ?? null;
|
|
@@ -37481,7 +38554,7 @@ function uploadPathFrom(uploadUrl) {
|
|
|
37481
38554
|
return uploadUrl;
|
|
37482
38555
|
}
|
|
37483
38556
|
function buildAttachmentsCommand() {
|
|
37484
|
-
const attachments = new
|
|
38557
|
+
const attachments = new Command3("attachments").description("Manage record attachments");
|
|
37485
38558
|
attachments.command("upload <record_type> <id>").description(
|
|
37486
38559
|
"Get a presigned upload URL for a record attachment. With --file, uploads the file content in one step."
|
|
37487
38560
|
).requiredOption("--filename <name>", "File name or path (e.g. docs/guide.md)").option("--content-type <type>", "MIME type", "application/octet-stream").option("--file <path>", "Local file to upload (skips presigned URL output, uploads directly)").action(async function(recordType2, id, opts) {
|
|
@@ -37561,9 +38634,9 @@ var init_attachments = __esm({
|
|
|
37561
38634
|
});
|
|
37562
38635
|
|
|
37563
38636
|
// src/data/commands/batch.ts
|
|
37564
|
-
import { Command as
|
|
38637
|
+
import { Command as Command4 } from "commander";
|
|
37565
38638
|
function buildBasesBatchCommand() {
|
|
37566
|
-
return withBaseOption(new
|
|
38639
|
+
return withBaseOption(new Command4("batch")).description("Execute atomic batch operations (up to 1,000 operations)").requiredOption("--operations <json>", "Operations array (inline JSON or @filename)").action(async function(opts) {
|
|
37567
38640
|
const base = pathSegment(requireBase(this), "--base");
|
|
37568
38641
|
const operations = parseData(opts.operations, "--operations");
|
|
37569
38642
|
const client = await createDataClient();
|
|
@@ -37592,7 +38665,7 @@ import { createReadStream } from "fs";
|
|
|
37592
38665
|
import { access, constants, stat } from "fs/promises";
|
|
37593
38666
|
import { createInterface as createInterface3 } from "readline";
|
|
37594
38667
|
import { randomUUID } from "crypto";
|
|
37595
|
-
import { Command as
|
|
38668
|
+
import { Command as Command5 } from "commander";
|
|
37596
38669
|
function isRetryable(err) {
|
|
37597
38670
|
if (isNetworkError(err)) return true;
|
|
37598
38671
|
if (!(err instanceof ApiError)) return false;
|
|
@@ -37668,7 +38741,7 @@ async function beginSession(state, client, base, recordType2, requestKey) {
|
|
|
37668
38741
|
return res.session;
|
|
37669
38742
|
}
|
|
37670
38743
|
function buildBasesImportCommand() {
|
|
37671
|
-
const importCmd = withBaseOption(new
|
|
38744
|
+
const importCmd = withBaseOption(new Command5("import")).description(
|
|
37672
38745
|
"Bulk historical import: load an NDJSON backfill, list sessions, or undo one"
|
|
37673
38746
|
);
|
|
37674
38747
|
importCmd.command("run <record_type>").description(
|
|
@@ -37895,7 +38968,7 @@ var init_import = __esm({
|
|
|
37895
38968
|
});
|
|
37896
38969
|
|
|
37897
38970
|
// src/data/commands/providers.ts
|
|
37898
|
-
import { Command as
|
|
38971
|
+
import { Command as Command6 } from "commander";
|
|
37899
38972
|
import { writeFileSync as writeFileSync10 } from "fs";
|
|
37900
38973
|
function providerSegment(provider) {
|
|
37901
38974
|
if (!VALID_PROVIDERS.includes(provider)) {
|
|
@@ -37904,7 +38977,7 @@ function providerSegment(provider) {
|
|
|
37904
38977
|
return pathSegment(provider, "provider");
|
|
37905
38978
|
}
|
|
37906
38979
|
function buildBasesProvidersCommand() {
|
|
37907
|
-
const providers = withBaseOption(new
|
|
38980
|
+
const providers = withBaseOption(new Command6("providers")).description(
|
|
37908
38981
|
"Import/export tool definitions between LLM providers and record types"
|
|
37909
38982
|
);
|
|
37910
38983
|
providers.command("import <provider>").description(`Import tool definitions as record types. Providers: ${VALID_PROVIDERS_HELP}`).requiredOption("--tools <json>", "Tool definitions (inline JSON or @filename)").action(async function(provider, opts) {
|
|
@@ -37975,7 +39048,7 @@ var init_providers = __esm({
|
|
|
37975
39048
|
});
|
|
37976
39049
|
|
|
37977
39050
|
// src/data/commands/report.ts
|
|
37978
|
-
import { Command as
|
|
39051
|
+
import { Command as Command7 } from "commander";
|
|
37979
39052
|
import { readFileSync as readFileSync20 } from "fs";
|
|
37980
39053
|
import { dirname as dirname15, join as join36 } from "path";
|
|
37981
39054
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -38019,7 +39092,7 @@ function reportActionError2(err) {
|
|
|
38019
39092
|
throw err;
|
|
38020
39093
|
}
|
|
38021
39094
|
function buildBasesReportCommand() {
|
|
38022
|
-
const report2 = new
|
|
39095
|
+
const report2 = new Command7("report").description(
|
|
38023
39096
|
"File a report to the Data triage queue and verify the outcome"
|
|
38024
39097
|
);
|
|
38025
39098
|
report2.command("create").description("Submit a report to the Data triage queue (deduplicated)").requiredOption("--title <title>", "Short summary").requiredOption("--description <text>", "What happened").option("--source <source>", "Origin: cli_report (default) | review | security_audit").option("--classification <c>", "Nature: bug (default) | flaky_test | security | enhancement").option(
|
|
@@ -38186,7 +39259,7 @@ var init_report3 = __esm({
|
|
|
38186
39259
|
});
|
|
38187
39260
|
|
|
38188
39261
|
// src/data/commands/credentials.ts
|
|
38189
|
-
import { Command as
|
|
39262
|
+
import { Command as Command8 } from "commander";
|
|
38190
39263
|
import { readFileSync as readFileSync21 } from "fs";
|
|
38191
39264
|
function withValueSourceOptions(cmd, what) {
|
|
38192
39265
|
return cmd.option(
|
|
@@ -38221,7 +39294,7 @@ function credentialPath(base, id) {
|
|
|
38221
39294
|
}
|
|
38222
39295
|
function buildBasesCredentialsCommand() {
|
|
38223
39296
|
const credentials = withBaseOption(
|
|
38224
|
-
new
|
|
39297
|
+
new Command8("credentials").description("Manage a base's integration credentials")
|
|
38225
39298
|
);
|
|
38226
39299
|
withValueSourceOptions(
|
|
38227
39300
|
credentials.command("create").description("Store a credential on this base (value read from stdin, a masked prompt, or --file)").requiredOption("--name <name>", "Credential name \u2014 what a credential:<name> reference resolves").option("--content-type <mime>", "MIME type of the value (e.g. application/x-pkcs12)").option(
|
|
@@ -38348,10 +39421,10 @@ var init_credentials = __esm({
|
|
|
38348
39421
|
});
|
|
38349
39422
|
|
|
38350
39423
|
// src/data/commands/sql.ts
|
|
38351
|
-
import { Command as
|
|
39424
|
+
import { Command as Command9 } from "commander";
|
|
38352
39425
|
import { readFileSync as readFileSync22 } from "fs";
|
|
38353
39426
|
function buildBasesSqlCommand() {
|
|
38354
|
-
return withBaseOption(new
|
|
39427
|
+
return withBaseOption(new Command9("sql")).description("Execute a read-only SQL query against base data").argument("[query]", "SQL query (SELECT only)").option("--file <path>", "Read SQL from a file instead of the argument").option(
|
|
38355
39428
|
"--param <kv...>",
|
|
38356
39429
|
"Named parameters as key=value pairs (e.g. --param status=issued)"
|
|
38357
39430
|
).action(async function(queryArg, opts) {
|
|
@@ -38393,250 +39466,6 @@ var init_sql = __esm({
|
|
|
38393
39466
|
}
|
|
38394
39467
|
});
|
|
38395
39468
|
|
|
38396
|
-
// src/data/commands/tokens.ts
|
|
38397
|
-
import { Command as Command9 } from "commander";
|
|
38398
|
-
function addTokenLifecycleOptions(cmd) {
|
|
38399
|
-
return cmd.option("--expires-at <date>", "Expiration date (ISO 8601, e.g. 2026-06-01T00:00:00Z)").option(
|
|
38400
|
-
"--ttl <duration>",
|
|
38401
|
-
"Relative expiry, e.g. 10m, 2h, 7d (use for disposable probe/test tokens)"
|
|
38402
|
-
).option(
|
|
38403
|
-
"--description <text>",
|
|
38404
|
-
'What holds this token (e.g. "behind credential X"); shown in list and revoke warnings'
|
|
38405
|
-
).addHelpText("after", TOKEN_OUTPUT_HELP);
|
|
38406
|
-
}
|
|
38407
|
-
function tokenCreationOutput(cmd, opts) {
|
|
38408
|
-
return opts.tokenOnly ? "token" : outputFormat(cmd);
|
|
38409
|
-
}
|
|
38410
|
-
function printCreatedToken(data, output) {
|
|
38411
|
-
if (output !== "token") {
|
|
38412
|
-
printOutput(data, output);
|
|
38413
|
-
return;
|
|
38414
|
-
}
|
|
38415
|
-
const token = typeof data === "object" && data !== null && "token" in data ? data.token : void 0;
|
|
38416
|
-
if (typeof token !== "string" || !RAW_TOKEN_PATTERN.test(token)) {
|
|
38417
|
-
throw new Error("Token creation response did not contain a valid rec_ token");
|
|
38418
|
-
}
|
|
38419
|
-
console.log(token);
|
|
38420
|
-
}
|
|
38421
|
-
function resolveExpiresAt(opts) {
|
|
38422
|
-
if (opts.ttl && opts.expiresAt) {
|
|
38423
|
-
throw expected("--ttl and --expires-at are mutually exclusive \u2014 pass one.");
|
|
38424
|
-
}
|
|
38425
|
-
if (opts.ttl) return new Date(Date.now() + parseDuration(opts.ttl, "--ttl")).toISOString();
|
|
38426
|
-
return opts.expiresAt;
|
|
38427
|
-
}
|
|
38428
|
-
function applyTokenLifecycleOpts(body, opts) {
|
|
38429
|
-
const expiresAt = resolveExpiresAt(opts);
|
|
38430
|
-
if (expiresAt) body.expires_at = expiresAt;
|
|
38431
|
-
if (opts.description) body.description = opts.description;
|
|
38432
|
-
}
|
|
38433
|
-
function listAllTokens(client) {
|
|
38434
|
-
return client.collectPages(
|
|
38435
|
-
(cursor) => `/v1/tokens?limit=${TOKEN_LIST_PAGE_LIMIT}${cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""}`
|
|
38436
|
-
);
|
|
38437
|
-
}
|
|
38438
|
-
function pruneRow(t, reason) {
|
|
38439
|
-
return {
|
|
38440
|
-
token_id: t.token_id,
|
|
38441
|
-
name: t.name,
|
|
38442
|
-
reason,
|
|
38443
|
-
last_used: t.last_used_at ?? "never"
|
|
38444
|
-
};
|
|
38445
|
-
}
|
|
38446
|
-
function buildBasesTokensCommand() {
|
|
38447
|
-
const tokens2 = new Command9("tokens").description("Manage API tokens");
|
|
38448
|
-
addTokenLifecycleOptions(
|
|
38449
|
-
tokens2.command("create").description("Create a scoped API token").requiredOption("--name <name>", "Token name").requiredOption("--grants <json>", "Grant definitions as JSON array").option(
|
|
38450
|
-
"--token-only",
|
|
38451
|
-
"Print only the raw rec_ token for secure command substitution (shown once)"
|
|
38452
|
-
)
|
|
38453
|
-
).action(async function(opts) {
|
|
38454
|
-
const grants = parseData(opts.grants, "--grants");
|
|
38455
|
-
const body = { name: opts.name, grants };
|
|
38456
|
-
applyTokenLifecycleOpts(body, opts);
|
|
38457
|
-
const client = await createDataClient();
|
|
38458
|
-
const data = await client.request("POST", "/v1/tokens", body);
|
|
38459
|
-
printCreatedToken(data, tokenCreationOutput(this, opts));
|
|
38460
|
-
});
|
|
38461
|
-
addTokenLifecycleOptions(
|
|
38462
|
-
// The only token verb that addresses a base, so it alone declares `--base`.
|
|
38463
|
-
// Putting it on the `tokens` group would advertise a flag that does nothing
|
|
38464
|
-
// on `list`, `revoke` and `prune` — the defect `withBaseOption` exists to
|
|
38465
|
-
// avoid.
|
|
38466
|
-
withBaseOption(tokens2.command("create-for-toolset <slug>")).description(
|
|
38467
|
-
"Create a toolset-bound (consumer) token whose authorization IS the toolset tool surface \u2014 it can call exactly the tools that toolset exposes (those record types + operations, relationships, batch, and sql only if enabled) and nothing else. Binds to the configured --base."
|
|
38468
|
-
).option("--name <name>", 'Token name (default: "<slug> consumer")').option(
|
|
38469
|
-
"--token-only",
|
|
38470
|
-
"Print only the raw rec_ token for secure command substitution (shown once)"
|
|
38471
|
-
)
|
|
38472
|
-
).action(async function(slug, opts) {
|
|
38473
|
-
const base = requireBase(this);
|
|
38474
|
-
const body = {
|
|
38475
|
-
name: opts.name ?? `${slug} consumer`,
|
|
38476
|
-
toolset_binding: { base_id: base, toolset_id: slug }
|
|
38477
|
-
};
|
|
38478
|
-
applyTokenLifecycleOpts(body, opts);
|
|
38479
|
-
const client = await createDataClient();
|
|
38480
|
-
const data = await client.request("POST", "/v1/tokens", body);
|
|
38481
|
-
const output = tokenCreationOutput(this, opts);
|
|
38482
|
-
printCreatedToken(data, output);
|
|
38483
|
-
if (output === "table") {
|
|
38484
|
-
console.log(`
|
|
38485
|
-
MCP URL: ${toolsetMcpUrl(slug)}`);
|
|
38486
|
-
}
|
|
38487
|
-
});
|
|
38488
|
-
tokens2.command("list").description("List API tokens (status, last_used_at, expires_at, description)").action(async function() {
|
|
38489
|
-
const client = await createDataClient();
|
|
38490
|
-
printOutput(await listAllTokens(client), outputFormat(this));
|
|
38491
|
-
});
|
|
38492
|
-
tokens2.command("revoke <token_id>").description(
|
|
38493
|
-
"Revoke an API token (permanent). A recently-used or toolset-bound token requires --force."
|
|
38494
|
-
).option("--force", "Revoke even if the token appears to be in live use").action(async function(tokenId, opts) {
|
|
38495
|
-
const client = await createDataClient();
|
|
38496
|
-
const id = pathSegment(tokenId, "token id");
|
|
38497
|
-
const path42 = (force) => `/v1/tokens/${id}${force ? "?force=true" : ""}`;
|
|
38498
|
-
const format = outputFormat(this);
|
|
38499
|
-
const revoked = (forced) => printOutput({ token_id: tokenId, revoked: true, forced }, format);
|
|
38500
|
-
if (opts.force) {
|
|
38501
|
-
await client.request("DELETE", path42(true));
|
|
38502
|
-
revoked(true);
|
|
38503
|
-
return;
|
|
38504
|
-
}
|
|
38505
|
-
try {
|
|
38506
|
-
await client.request("DELETE", path42(false));
|
|
38507
|
-
revoked(false);
|
|
38508
|
-
} catch (err) {
|
|
38509
|
-
if (!(err instanceof ApiError) || err.status !== 409 || dataErrorDetails(err)?.requires_force !== true) {
|
|
38510
|
-
throw err;
|
|
38511
|
-
}
|
|
38512
|
-
console.error(err.message);
|
|
38513
|
-
if (!isInteractive()) {
|
|
38514
|
-
console.error("\nRe-run with --force to revoke anyway.");
|
|
38515
|
-
return process.exit(1);
|
|
38516
|
-
}
|
|
38517
|
-
if (!await confirm("Revoke anyway?")) {
|
|
38518
|
-
console.error("Aborted.");
|
|
38519
|
-
return process.exit(1);
|
|
38520
|
-
}
|
|
38521
|
-
await client.request("DELETE", path42(true));
|
|
38522
|
-
revoked(true);
|
|
38523
|
-
}
|
|
38524
|
-
});
|
|
38525
|
-
tokens2.command("prune").description(
|
|
38526
|
-
"Revoke stale tokens, selected by staleness only (expired, or unused past --unused-since) \u2014 never by name. Previews by default; revoking requires --yes or an interactive confirmation."
|
|
38527
|
-
).option(
|
|
38528
|
-
"--unused-since <duration>",
|
|
38529
|
-
"Also prune tokens with no activity for this long (e.g. 30d). Skips toolset-bound and legacy usage-untracked tokens."
|
|
38530
|
-
).option("--include-bound", "Allow pruning stale toolset-bound (consumer) tokens").option("-y, --yes", "Revoke without prompting (required when non-interactive)").action(async function(opts) {
|
|
38531
|
-
const staleMs = opts.unusedSince ? parseDuration(opts.unusedSince, "--unused-since") : void 0;
|
|
38532
|
-
const client = await createDataClient();
|
|
38533
|
-
const allTokens = await listAllTokens(client);
|
|
38534
|
-
const now = Date.now();
|
|
38535
|
-
const targets = [];
|
|
38536
|
-
const skipped = [];
|
|
38537
|
-
for (const t of allTokens) {
|
|
38538
|
-
const expired = t.status ? t.status === "expired" : !!t.expires_at && Date.parse(t.expires_at) <= now;
|
|
38539
|
-
if (expired) {
|
|
38540
|
-
targets.push(pruneRow(t, "expired"));
|
|
38541
|
-
continue;
|
|
38542
|
-
}
|
|
38543
|
-
if (staleMs === void 0) continue;
|
|
38544
|
-
const lastActivity = Date.parse(t.last_used_at ?? t.created_at);
|
|
38545
|
-
if (!(now - lastActivity > staleMs)) continue;
|
|
38546
|
-
if (t.usage_tracked !== true) {
|
|
38547
|
-
skipped.push(
|
|
38548
|
-
pruneRow(
|
|
38549
|
-
t,
|
|
38550
|
-
"usage untracked (legacy token) \u2014 revoke individually if truly unused"
|
|
38551
|
-
)
|
|
38552
|
-
);
|
|
38553
|
-
} else if (t.toolset_binding && !opts.includeBound) {
|
|
38554
|
-
skipped.push(
|
|
38555
|
-
pruneRow(
|
|
38556
|
-
t,
|
|
38557
|
-
`toolset-bound ('${t.toolset_binding.toolset_id}') \u2014 pass --include-bound to prune`
|
|
38558
|
-
)
|
|
38559
|
-
);
|
|
38560
|
-
} else {
|
|
38561
|
-
targets.push(pruneRow(t, `unused for over ${opts.unusedSince}`));
|
|
38562
|
-
}
|
|
38563
|
-
}
|
|
38564
|
-
const format = outputFormat(this);
|
|
38565
|
-
const json = format === "json";
|
|
38566
|
-
const note = (line) => json ? console.error(line) : console.log(line);
|
|
38567
|
-
const printPreview = () => {
|
|
38568
|
-
if (targets.length === 0) {
|
|
38569
|
-
note("Nothing to prune.");
|
|
38570
|
-
} else {
|
|
38571
|
-
note(`Would revoke ${targets.length} token(s):`);
|
|
38572
|
-
if (!json) printOutput(targets, format);
|
|
38573
|
-
}
|
|
38574
|
-
if (skipped.length === 0) return;
|
|
38575
|
-
note(`
|
|
38576
|
-
Skipped ${skipped.length} stale token(s):`);
|
|
38577
|
-
if (!json) printOutput(skipped, format);
|
|
38578
|
-
};
|
|
38579
|
-
printPreview();
|
|
38580
|
-
if (targets.length === 0) {
|
|
38581
|
-
if (json) printOutput({ revoked: 0, failed: 0, targets, skipped }, format);
|
|
38582
|
-
return;
|
|
38583
|
-
}
|
|
38584
|
-
if (!opts.yes) {
|
|
38585
|
-
if (!isInteractive()) {
|
|
38586
|
-
console.error("\nPreview only \u2014 re-run with --yes to revoke these tokens.");
|
|
38587
|
-
if (json) printOutput({ preview: true, revoked: 0, failed: 0, targets, skipped }, format);
|
|
38588
|
-
return process.exit(1);
|
|
38589
|
-
}
|
|
38590
|
-
if (!await confirm(`
|
|
38591
|
-
Revoke ${targets.length} token(s)?`)) {
|
|
38592
|
-
console.error("Aborted.");
|
|
38593
|
-
return process.exit(1);
|
|
38594
|
-
}
|
|
38595
|
-
}
|
|
38596
|
-
let revoked = 0;
|
|
38597
|
-
let failed = 0;
|
|
38598
|
-
for (const t of targets) {
|
|
38599
|
-
try {
|
|
38600
|
-
await client.request(
|
|
38601
|
-
"DELETE",
|
|
38602
|
-
`/v1/tokens/${pathSegment(t.token_id, "token id")}?force=true`
|
|
38603
|
-
);
|
|
38604
|
-
revoked++;
|
|
38605
|
-
} catch (err) {
|
|
38606
|
-
failed++;
|
|
38607
|
-
console.error(
|
|
38608
|
-
`Failed to revoke ${t.token_id} ('${sanitizeTerminalText(t.name)}'): ${err instanceof Error ? err.message : String(err)}`
|
|
38609
|
-
);
|
|
38610
|
-
}
|
|
38611
|
-
}
|
|
38612
|
-
if (json) printOutput({ revoked, failed, targets, skipped }, format);
|
|
38613
|
-
else console.log(`Revoked ${revoked} token(s)${failed > 0 ? `, ${failed} failed` : ""}.`);
|
|
38614
|
-
if (failed > 0) return process.exit(1);
|
|
38615
|
-
});
|
|
38616
|
-
return tokens2;
|
|
38617
|
-
}
|
|
38618
|
-
var RAW_TOKEN_PATTERN, TOKEN_OUTPUT_HELP, TOKEN_LIST_PAGE_LIMIT;
|
|
38619
|
-
var init_tokens = __esm({
|
|
38620
|
-
"src/data/commands/tokens.ts"() {
|
|
38621
|
-
"use strict";
|
|
38622
|
-
init_client();
|
|
38623
|
-
init_output();
|
|
38624
|
-
init_helpers();
|
|
38625
|
-
init_api_client();
|
|
38626
|
-
init_terminal_output();
|
|
38627
|
-
init_utils();
|
|
38628
|
-
init_expected();
|
|
38629
|
-
RAW_TOKEN_PATTERN = /^rec_[A-Za-z0-9_-]{43}$/;
|
|
38630
|
-
TOKEN_OUTPUT_HELP = `
|
|
38631
|
-
Output:
|
|
38632
|
-
--json prints the unwrapped response object; the secret is at top-level .token, never .data.token.
|
|
38633
|
-
--token-only prints only a validated rec_ token and overrides table/JSON formatting.
|
|
38634
|
-
The raw token is shown once. Capture it securely and do not log it.
|
|
38635
|
-
`;
|
|
38636
|
-
TOKEN_LIST_PAGE_LIMIT = 250;
|
|
38637
|
-
}
|
|
38638
|
-
});
|
|
38639
|
-
|
|
38640
39469
|
// src/data/base-tags.ts
|
|
38641
39470
|
async function resolveBaseTags(rawTags, client) {
|
|
38642
39471
|
const refs = splitList(rawTags);
|
|
@@ -39550,7 +40379,7 @@ function isConflict(err) {
|
|
|
39550
40379
|
return err instanceof ApiError && (err.status === 409 || err.status === 412);
|
|
39551
40380
|
}
|
|
39552
40381
|
function conflictLine(c, texts) {
|
|
39553
|
-
return `${
|
|
40382
|
+
return `${safe3(c.rel)}: ${texts[c.reason]}${c.other === void 0 ? "" : ` "${safe3(c.other)}"`}`;
|
|
39554
40383
|
}
|
|
39555
40384
|
function remedy(conflicts, overwriteCommand) {
|
|
39556
40385
|
const isClash = (c) => c.reason === "case_twin" || c.reason === "file_folder";
|
|
@@ -39571,7 +40400,7 @@ async function pullFiles(opts) {
|
|
|
39571
40400
|
const plan = planPull({ synced: existing?.files ?? {}, local, remote, overwrite: opts.overwrite });
|
|
39572
40401
|
if (plan.replacedLocal.length > 0) {
|
|
39573
40402
|
console.log("These local changes would be replaced with the base's copies:");
|
|
39574
|
-
for (const rel of plan.replacedLocal) console.log(` ${
|
|
40403
|
+
for (const rel of plan.replacedLocal) console.log(` ${safe3(rel)}`);
|
|
39575
40404
|
if (!await agree(`Replace ${plan.replacedLocal.length} locally changed file(s)?`, opts.yes)) {
|
|
39576
40405
|
console.log("Cancelled.");
|
|
39577
40406
|
return;
|
|
@@ -39592,7 +40421,7 @@ async function pullFiles(opts) {
|
|
|
39592
40421
|
}
|
|
39593
40422
|
removeLocal(dir, rel);
|
|
39594
40423
|
delete record.files[rel];
|
|
39595
|
-
changes.push(`${MARK.delete} ${
|
|
40424
|
+
changes.push(`${MARK.delete} ${safe3(rel)}`);
|
|
39596
40425
|
}
|
|
39597
40426
|
for (const w of plan.writes) {
|
|
39598
40427
|
const clash = diskClash(dir, w.rel);
|
|
@@ -39625,7 +40454,7 @@ async function pullFiles(opts) {
|
|
|
39625
40454
|
const hash = computeHash(bytes);
|
|
39626
40455
|
writeLocal(dir, w.rel, bytes);
|
|
39627
40456
|
record.files[w.rel] = { version, content_sha256: hash };
|
|
39628
|
-
changes.push(`${local.has(w.rel) ? MARK.update : MARK.create} ${
|
|
40457
|
+
changes.push(`${local.has(w.rel) ? MARK.update : MARK.create} ${safe3(w.rel)}`);
|
|
39629
40458
|
}
|
|
39630
40459
|
} finally {
|
|
39631
40460
|
writeRecord(dir, record);
|
|
@@ -39633,13 +40462,13 @@ async function pullFiles(opts) {
|
|
|
39633
40462
|
const count = Object.keys(record.files).length;
|
|
39634
40463
|
console.log(sanitizeTerminalText(`Pulled ${describeSync(target)} \u2192 ${dir} (${count} file${count === 1 ? "" : "s"}).`));
|
|
39635
40464
|
printSection("Changes:", changes);
|
|
39636
|
-
printSection("Kept \u2014 your local changes:", plan.kept.map((k) => `${
|
|
40465
|
+
printSection("Kept \u2014 your local changes:", plan.kept.map((k) => `${safe3(k.rel)}: ${PULL_KEPT[k.reason]}`));
|
|
39637
40466
|
printSection(
|
|
39638
40467
|
`Conflicts \u2014 your copy is kept; to settle them, ${remedy(conflicts, pullCommand2(target, opts.dir, true))}:`,
|
|
39639
40468
|
conflicts.map((c) => conflictLine(c, PULL_CONFLICT))
|
|
39640
40469
|
);
|
|
39641
|
-
printSection("Changed or deleted on the base while pulling \u2014 left as is; pull again to take it:", changedWhilePulling.map(
|
|
39642
|
-
printSection(`Not synced \u2014 names a synced folder leaves out (${OUTSIDE_SYNC.join(", ")}):`, excluded.map(
|
|
40470
|
+
printSection("Changed or deleted on the base while pulling \u2014 left as is; pull again to take it:", changedWhilePulling.map(safe3));
|
|
40471
|
+
printSection(`Not synced \u2014 names a synced folder leaves out (${OUTSIDE_SYNC.join(", ")}):`, excluded.map(safe3));
|
|
39643
40472
|
}
|
|
39644
40473
|
function isTextType(contentType) {
|
|
39645
40474
|
const ct = contentType.split(";")[0].trim().toLowerCase();
|
|
@@ -39657,7 +40486,7 @@ function changedLines(before, after) {
|
|
|
39657
40486
|
async function describeSteps(client, t, dir, steps) {
|
|
39658
40487
|
const lines = [];
|
|
39659
40488
|
for (const step of steps) {
|
|
39660
|
-
const rel =
|
|
40489
|
+
const rel = safe3(step.rel);
|
|
39661
40490
|
if (step.op === "create") {
|
|
39662
40491
|
lines.push(`${MARK.create} ${rel} (new, ${step.local.size} bytes)`);
|
|
39663
40492
|
} else if (step.op === "delete") {
|
|
@@ -39684,10 +40513,10 @@ async function describeSteps(client, t, dir, steps) {
|
|
|
39684
40513
|
return lines;
|
|
39685
40514
|
}
|
|
39686
40515
|
function printPushNotes(plan) {
|
|
39687
|
-
printSection("Changed on the base since your last pull \u2014 left as is; pull to take it:", plan.changedOnBase.map(
|
|
39688
|
-
printSection("Deleted on the base since your last pull \u2014 left as is; pull to remove your copy:", plan.deletedOnBase.map(
|
|
39689
|
-
printSection("On the base, not in your files \u2014 left as is; pull to fetch it:", plan.onlyOnBase.map(
|
|
39690
|
-
printSection("Deleted in your files \u2014 kept on the base; push with --prune to delete it:", plan.keptOnBase.map(
|
|
40516
|
+
printSection("Changed on the base since your last pull \u2014 left as is; pull to take it:", plan.changedOnBase.map(safe3));
|
|
40517
|
+
printSection("Deleted on the base since your last pull \u2014 left as is; pull to remove your copy:", plan.deletedOnBase.map(safe3));
|
|
40518
|
+
printSection("On the base, not in your files \u2014 left as is; pull to fetch it:", plan.onlyOnBase.map(safe3));
|
|
40519
|
+
printSection("Deleted in your files \u2014 kept on the base; push with --prune to delete it:", plan.keptOnBase.map(safe3));
|
|
39691
40520
|
}
|
|
39692
40521
|
async function pushFiles(opts) {
|
|
39693
40522
|
const label = opts.label === void 0 ? void 0 : labelValue(opts.label);
|
|
@@ -39750,14 +40579,14 @@ Push ${n} change${n === 1 ? "" : "s"} to ${describeSync(target)}?`, opts.yes)) {
|
|
|
39750
40579
|
} else {
|
|
39751
40580
|
const bytes = readLocal(dir, step.rel);
|
|
39752
40581
|
if (computeHash(bytes) !== step.local.content_sha256) {
|
|
39753
|
-
throw expected(`${
|
|
40582
|
+
throw expected(`${safe3(step.rel)} changed while the push ran. Nothing more was pushed; run the push again.`);
|
|
39754
40583
|
}
|
|
39755
40584
|
const contentType = step.op === "update" ? step.remote.content_type : guessMimeType(step.rel) ?? "application/octet-stream";
|
|
39756
40585
|
const row = await client.upload(
|
|
39757
40586
|
path42,
|
|
39758
40587
|
bytes,
|
|
39759
40588
|
contentType,
|
|
39760
|
-
fileWriteHeaders({
|
|
40589
|
+
fileWriteHeaders({ ...step.op === "update" ? { ifMatch: step.ifMatch } : { createOnly: true }, label })
|
|
39761
40590
|
);
|
|
39762
40591
|
record.files[step.rel] = {
|
|
39763
40592
|
version: typeof row?.version === "number" ? row.version : 0,
|
|
@@ -39765,13 +40594,14 @@ Push ${n} change${n === 1 ? "" : "s"} to ${describeSync(target)}?`, opts.yes)) {
|
|
|
39765
40594
|
};
|
|
39766
40595
|
}
|
|
39767
40596
|
pushed++;
|
|
39768
|
-
console.log(` ${MARK[step.op]} ${
|
|
40597
|
+
console.log(` ${MARK[step.op]} ${safe3(step.rel)}`);
|
|
39769
40598
|
} catch (err) {
|
|
39770
40599
|
if (step.op === "delete" && err instanceof ApiError && err.status === 404) {
|
|
39771
40600
|
delete record.files[step.rel];
|
|
39772
40601
|
} else if (isConflict(err)) {
|
|
39773
40602
|
if (step.op === "delete") refusedDeletes.add(step.rel);
|
|
39774
|
-
const
|
|
40603
|
+
const reason = step.op === "create" && err.status === 412 ? "created_while_pushing" : "changed_while_pushing";
|
|
40604
|
+
const conflict = { rel: step.rel, reason };
|
|
39775
40605
|
conflicts.push(conflict);
|
|
39776
40606
|
console.log(` ! ${conflictLine(conflict, PUSH_CONFLICT)}`);
|
|
39777
40607
|
continue;
|
|
@@ -39792,7 +40622,7 @@ function finishWithConflicts(t, dir, conflicts) {
|
|
|
39792
40622
|
`${count} conflict${count === 1 ? "" : "s"} not pushed \u2014 the base's copies of those files were left as they are. To settle them, ${remedy(conflicts, pullCommand2(t, dir, true))}, then push again.`
|
|
39793
40623
|
);
|
|
39794
40624
|
}
|
|
39795
|
-
var LIST_PAGE2, MAX_LIST_PAGES2, MAX_DIFF_BYTES, MARK,
|
|
40625
|
+
var LIST_PAGE2, MAX_LIST_PAGES2, MAX_DIFF_BYTES, MARK, safe3, PULL_KEPT, PULL_CONFLICT, PUSH_CONFLICT;
|
|
39796
40626
|
var init_sync3 = __esm({
|
|
39797
40627
|
"src/data/files-sync/sync.ts"() {
|
|
39798
40628
|
"use strict";
|
|
@@ -39814,7 +40644,7 @@ var init_sync3 = __esm({
|
|
|
39814
40644
|
MAX_LIST_PAGES2 = 1e3;
|
|
39815
40645
|
MAX_DIFF_BYTES = 256 * 1024;
|
|
39816
40646
|
MARK = { create: "+", update: "~", delete: "-" };
|
|
39817
|
-
|
|
40647
|
+
safe3 = (rel) => sanitizeTerminalText(rel);
|
|
39818
40648
|
PULL_KEPT = {
|
|
39819
40649
|
edited: "edited in your files, not pushed yet",
|
|
39820
40650
|
deleted: "deleted in your files, not pushed yet (push --prune deletes it from the base)"
|
|
@@ -39834,7 +40664,8 @@ var init_sync3 = __esm({
|
|
|
39834
40664
|
exists_on_base: "created on the base since your last pull",
|
|
39835
40665
|
case_twin: "differs only in case from the base's",
|
|
39836
40666
|
file_folder: "would make one path both a file and a folder with the base's",
|
|
39837
|
-
changed_while_pushing: "changed on the base while pushing \u2014 not written"
|
|
40667
|
+
changed_while_pushing: "changed on the base while pushing \u2014 not written",
|
|
40668
|
+
created_while_pushing: "created on the base while pushing \u2014 not written"
|
|
39838
40669
|
};
|
|
39839
40670
|
}
|
|
39840
40671
|
});
|
|
@@ -40018,7 +40849,7 @@ function buildFilesCommand() {
|
|
|
40018
40849
|
});
|
|
40019
40850
|
});
|
|
40020
40851
|
files.command("push <file_type>").description(
|
|
40021
|
-
"Push the local changes of a folder pulled with `files pull` to the base, after showing the diff. A file changed, deleted or created on the base since your pull is a conflict, not written; an update or delete also carries the version pulled, so the base refuses
|
|
40852
|
+
"Push the local changes of a folder pulled with `files pull` to the base, after showing the diff. A file changed, deleted or created on the base since your pull is a conflict, not written; an update or delete also carries the version pulled and a new file is sent create-only, so the base refuses a write to a file changed or created meanwhile"
|
|
40022
40853
|
).option("--folder <path>", "The folder of the file type the local folder was pulled from").option("--dir <local>", "Local folder to push (default ./<file_type>, or ./<file_type>/<folder>)").option("--dry-run", "Show the diff and push nothing").option("--prune", "Also delete files you deleted locally \u2014 only those unchanged on the base since your pull").option("--label <text>", "Label for every content version the push creates (printable ASCII)").option("-y, --yes", "Push without asking").action(async function(fileType, opts) {
|
|
40023
40854
|
const base = requireBase(this);
|
|
40024
40855
|
await pushFiles({
|
|
@@ -41436,6 +42267,7 @@ Commands:
|
|
|
41436
42267
|
contacts Link a contact to its customer record in a base, or unlink it (browser sign-in only) \u2014 \`wayai contacts --help\`
|
|
41437
42268
|
knowledge migrate Move an organization's knowledge resources, then a hub's (--hub), into its knowledge base as file types and files \u2014 \`wayai knowledge --help\`
|
|
41438
42269
|
knowledge refresh-preview Make the knowledge base's preview hold its production base's files \u2014 \`wayai knowledge --help\`
|
|
42270
|
+
knowledge cut-over Switch a preview hub's agents from their knowledge resources to the knowledge base \u2014 \`wayai knowledge --help\`
|
|
41439
42271
|
report create Report a platform bug (submits to the triage queue)
|
|
41440
42272
|
report edit Amend your own pending report (title/description/error/steps/context)
|
|
41441
42273
|
update Update CLI to the latest version
|