@wayai/cli 0.3.227 → 0.3.229

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 CHANGED
@@ -4706,10 +4706,10 @@ var init_chunk_SXDX4GHS = __esm({
4706
4706
  }
4707
4707
  });
4708
4708
 
4709
- // ../../packages/core/dist/chunk-FK6HBXM7.js
4709
+ // ../../packages/core/dist/chunk-HENF6YTF.js
4710
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"() {
4711
+ var init_chunk_HENF6YTF = __esm({
4712
+ "../../packages/core/dist/chunk-HENF6YTF.js"() {
4713
4713
  "use strict";
4714
4714
  init_zod();
4715
4715
  orgResourceIdParam = external_exports.object({
@@ -4736,10 +4736,11 @@ var init_chunk_FK6HBXM7 = __esm({
4736
4736
  organization_id: external_exports.string().uuid(),
4737
4737
  resource_name: external_exports.string().min(1).max(255),
4738
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
4739
+ // `knowledge` parses so the route can refuse it with its reason (wayai-pro/wayai#5142 step 5).
4740
+ resource_type: external_exports.enum(["knowledge", "skill"]).default("skill"),
4741
+ // Skill-only fields. `skill_name` is required for a skill (validated in
4741
4742
  // the route layer since cross-field refinement complicates the inferred
4742
- // input type for callers). Ignored for `knowledge`.
4743
+ // input type for callers).
4743
4744
  skill_name: external_exports.string().min(1).max(255).nullish(),
4744
4745
  skill_version: external_exports.string().max(50).nullish(),
4745
4746
  folder_metadata_schema: external_exports.record(external_exports.unknown()).optional(),
@@ -4896,10 +4897,10 @@ var init_chunk_HZ6CADSY = __esm({
4896
4897
  }
4897
4898
  });
4898
4899
 
4899
- // ../../packages/core/dist/chunk-TIZ57ZBA.js
4900
+ // ../../packages/core/dist/chunk-DYI3BRJ3.js
4900
4901
  var resourceIdParam, listResourcesQuery, createResourceBody, updateResourceBody, syncSkillsBody, resourceFileIdParam, listResourceFilesQuery, createResourceFileBody, updateResourceFileBody, uploadResourceFileBody, uploadSkillZipBody, resourceFolderIdParam, listResourceFoldersQuery, createResourceFolderBody, updateResourceFolderBody, agentResourceQuery, hubResourceQuery, linkAgentResourceBody, updateAgentResourceBody, unlinkAgentResourceQuery;
4901
- var init_chunk_TIZ57ZBA = __esm({
4902
- "../../packages/core/dist/chunk-TIZ57ZBA.js"() {
4902
+ var init_chunk_DYI3BRJ3 = __esm({
4903
+ "../../packages/core/dist/chunk-DYI3BRJ3.js"() {
4903
4904
  "use strict";
4904
4905
  init_chunk_HZ6CADSY();
4905
4906
  init_zod();
@@ -5288,6 +5289,149 @@ var init_chunk_GK27ENTT = __esm({
5288
5289
  }
5289
5290
  });
5290
5291
 
5292
+ // ../../packages/core/dist/chunk-IPDOHAZ5.js
5293
+ var reportSourceSchema, intakeReportSourceSchema, reportClassificationSchema, reportStatusSchema, reportLocaleSchema, reportMessageAuthorRoleSchema, reportMessageSchema, sentryRefStatusSchema, createReportBody, editReportBody, reporterReportSummarySchema, reporterListResponseSchema, getReportResponseSchema, reporterTransitionResponseSchema, contestReportBody, reporterListQuery, listReportsQuery, GITHUB_ISSUE_URL_REGEX, githubIssueUrlSchema, transitionReportBody, groupReportsBody, holdReportBody;
5294
+ var init_chunk_IPDOHAZ5 = __esm({
5295
+ "../../packages/core/dist/chunk-IPDOHAZ5.js"() {
5296
+ "use strict";
5297
+ init_chunk_HZ6CADSY();
5298
+ init_zod();
5299
+ reportSourceSchema = external_exports.enum(["sentry", "cli", "review", "security_audit"]);
5300
+ intakeReportSourceSchema = external_exports.enum(["cli", "review", "security_audit"]);
5301
+ reportClassificationSchema = external_exports.enum(["bug", "flaky_test", "security", "enhancement"]);
5302
+ reportStatusSchema = external_exports.enum([
5303
+ "pending",
5304
+ "grouped",
5305
+ "escalated",
5306
+ "shipped",
5307
+ "contested",
5308
+ "addressed",
5309
+ "dismissed"
5310
+ ]);
5311
+ reportLocaleSchema = external_exports.enum(["en", "pt", "es"]);
5312
+ reportMessageAuthorRoleSchema = external_exports.enum(["reporter", "triage", "fixer", "system"]);
5313
+ reportMessageSchema = external_exports.object({
5314
+ message_id: external_exports.string(),
5315
+ author_role: reportMessageAuthorRoleSchema,
5316
+ /** The status transition this note accompanied (e.g. 'shipped'); null for a free/system note. */
5317
+ transition: external_exports.string().nullable(),
5318
+ body: external_exports.string(),
5319
+ created_at: timestampSchema,
5320
+ /**
5321
+ * Visibility: `false` = reporter-facing (the default for every narrative entry); `true` =
5322
+ * triage-internal (e.g. a `hold` rationale) — surfaced to platform admins only and NEVER
5323
+ * returned on the reporter read path. The reporter's `GET /api/reports/:id` filters these out.
5324
+ */
5325
+ internal: external_exports.boolean()
5326
+ });
5327
+ sentryRefStatusSchema = external_exports.enum(["valid", "not_found", "mismatch", "unverified"]);
5328
+ createReportBody = external_exports.object({
5329
+ title: external_exports.string().min(5).max(256),
5330
+ description: external_exports.string().min(10).max(5e3),
5331
+ steps_to_reproduce: external_exports.string().max(3e3).optional(),
5332
+ error_message: external_exports.string().max(2e3).optional(),
5333
+ // Taxonomy (server defaults: source=cli, classification=bug when absent).
5334
+ source: intakeReportSourceSchema.optional(),
5335
+ classification: reportClassificationSchema.optional(),
5336
+ // Stable dedup key (e.g. "<file>::<test>" for flaky, "<file>:<line>" for
5337
+ // security). When present, the fingerprint uses it instead of the body hash.
5338
+ dedup_key: external_exports.string().min(1).max(256).optional(),
5339
+ // Context fields (auto-captured by the CLI)
5340
+ organization_id: external_exports.string().optional(),
5341
+ hub_id: external_exports.string().uuid().optional(),
5342
+ hub_name: external_exports.string().max(256).optional(),
5343
+ conversation_id: external_exports.string().uuid().optional(),
5344
+ agent_id: external_exports.string().uuid().optional(),
5345
+ agent_name: external_exports.string().max(256).optional(),
5346
+ client_version: external_exports.string().max(64).optional(),
5347
+ additional_context: external_exports.string().max(2e3).optional()
5348
+ });
5349
+ editReportBody = external_exports.object({
5350
+ title: external_exports.string().min(5).max(256).optional(),
5351
+ description: external_exports.string().min(10).max(5e3).optional(),
5352
+ steps_to_reproduce: external_exports.string().max(3e3).optional(),
5353
+ error_message: external_exports.string().max(2e3).optional(),
5354
+ additional_context: external_exports.string().max(2e3).optional()
5355
+ }).strict().refine((b) => Object.keys(b).length > 0, {
5356
+ message: "at least one field must be provided"
5357
+ });
5358
+ reporterReportSummarySchema = external_exports.object({
5359
+ report_id: external_exports.string(),
5360
+ title: external_exports.string(),
5361
+ description: external_exports.string(),
5362
+ classification: reportClassificationSchema,
5363
+ status: reportStatusSchema,
5364
+ created_at: timestampSchema,
5365
+ triaged_at: timestampSchema.nullable(),
5366
+ resolved_at: timestampSchema.nullable(),
5367
+ /** How many times the reporter has contested (gates the hard cap). */
5368
+ contest_count: external_exports.number(),
5369
+ /** True once triage issued a non-contestable (final) dismissal. */
5370
+ dismissal_final: external_exports.boolean()
5371
+ });
5372
+ reporterListResponseSchema = external_exports.object({
5373
+ data: external_exports.array(reporterReportSummarySchema)
5374
+ });
5375
+ getReportResponseSchema = external_exports.object({
5376
+ report: reporterReportSummarySchema,
5377
+ messages: external_exports.array(reportMessageSchema)
5378
+ });
5379
+ reporterTransitionResponseSchema = external_exports.object({
5380
+ report: reporterReportSummarySchema
5381
+ });
5382
+ contestReportBody = external_exports.object({
5383
+ reason: external_exports.string().min(1).max(5e3)
5384
+ });
5385
+ reporterListQuery = external_exports.object({
5386
+ status: reportStatusSchema.optional()
5387
+ });
5388
+ listReportsQuery = external_exports.object({
5389
+ status: reportStatusSchema.optional(),
5390
+ source: reportSourceSchema.optional(),
5391
+ limit: external_exports.coerce.number().int().min(1).max(200).optional(),
5392
+ offset: external_exports.coerce.number().int().min(0).optional(),
5393
+ /** ISO 8601 lower bound on created_at. */
5394
+ since: external_exports.string().datetime().optional(),
5395
+ /**
5396
+ * ISO 8601 lower bound on resolution time — "what did we resolve recently", which `since`
5397
+ * (a created_at filter) cannot answer for a long-lived report resolved yesterday. Implies
5398
+ * a terminal status (`addressed`/`dismissed`) and orders on that same axis.
5399
+ */
5400
+ resolved_since: external_exports.string().datetime().optional()
5401
+ });
5402
+ GITHUB_ISSUE_URL_REGEX = /^https:\/\/github\.com\/[^/]+\/[^/]+\/issues\/\d+(?:[/?#]|$)/;
5403
+ githubIssueUrlSchema = external_exports.string().url().refine((u) => GITHUB_ISSUE_URL_REGEX.test(u), {
5404
+ message: "must be an https://github.com/<owner>/<repo>/issues/<number> URL"
5405
+ });
5406
+ transitionReportBody = external_exports.discriminatedUnion("target", [
5407
+ external_exports.object({
5408
+ target: external_exports.literal("escalated"),
5409
+ gh_issue_url: githubIssueUrlSchema,
5410
+ ai_verdict: external_exports.string().max(2e3).optional()
5411
+ }),
5412
+ external_exports.object({
5413
+ target: external_exports.literal("shipped"),
5414
+ note: external_exports.string().min(1).max(2e3).optional()
5415
+ }),
5416
+ external_exports.object({
5417
+ target: external_exports.literal("addressed")
5418
+ }),
5419
+ external_exports.object({
5420
+ target: external_exports.literal("dismissed"),
5421
+ dismissal_reason: external_exports.string().min(1).max(5e3),
5422
+ ai_verdict: external_exports.string().max(2e3).optional(),
5423
+ final: external_exports.boolean().optional()
5424
+ })
5425
+ ]);
5426
+ groupReportsBody = external_exports.object({
5427
+ member_ids: external_exports.array(external_exports.string().uuid()).min(1).max(100)
5428
+ });
5429
+ holdReportBody = external_exports.object({
5430
+ reason: external_exports.string().min(1).max(5e3)
5431
+ });
5432
+ }
5433
+ });
5434
+
5291
5435
  // ../../packages/core/dist/chunk-GPM7PE44.js
5292
5436
  var bootstrapQuery;
5293
5437
  var init_chunk_GPM7PE44 = __esm({
@@ -5622,7 +5766,7 @@ var init_chunk_5XEJSR22 = __esm({
5622
5766
  }
5623
5767
  });
5624
5768
 
5625
- // ../../packages/core/dist/chunk-ISFDR7SP.js
5769
+ // ../../packages/core/dist/chunk-KJXJKAYT.js
5626
5770
  function matchPath(pattern, path42) {
5627
5771
  const normalizedPath = path42.replace(/\/$/, "");
5628
5772
  if (pattern.endsWith("/*")) {
@@ -5650,8 +5794,8 @@ function getEndpointConfig(path42) {
5650
5794
  return { tier: "STANDARD" };
5651
5795
  }
5652
5796
  var ENDPOINT_CONFIGS, EXCLUDED_PATHS;
5653
- var init_chunk_ISFDR7SP = __esm({
5654
- "../../packages/core/dist/chunk-ISFDR7SP.js"() {
5797
+ var init_chunk_KJXJKAYT = __esm({
5798
+ "../../packages/core/dist/chunk-KJXJKAYT.js"() {
5655
5799
  "use strict";
5656
5800
  init_chunk_5XEJSR22();
5657
5801
  ENDPOINT_CONFIGS = {
@@ -5808,8 +5952,10 @@ var init_chunk_ISFDR7SP = __esm({
5808
5952
  // platform's egress addresses carry many tenants' deliveries. The per-automation budget is
5809
5953
  // `AUTOMATION_WEBHOOK_PER_AUTOMATION_LIMIT`, counted after the delivery is verified.
5810
5954
  [`${AUTOMATION_WEBHOOK_MOUNT}/*`]: { tier: "HIGH" },
5811
- // Managed Agents session events (#5083 Phase 4): HIGH, one vendor address carries many tenants'.
5812
- [`${MANAGED_AGENTS_WEBHOOK_MOUNT}/*`]: { tier: "HIGH" },
5955
+ // Managed Agents session events (#5083 Phase 4): one delivery per hosted tool round, and one
5956
+ // vendor address carries every tenant's, so BULK. The per-connection budget is
5957
+ // `MANAGED_AGENTS_WEBHOOK_PER_CONNECTION_LIMIT`, counted after the delivery is verified.
5958
+ [`${MANAGED_AGENTS_WEBHOOK_MOUNT}/*`]: { tier: "BULK" },
5813
5959
  // Reports (CLI → platform_report triage queue). One per-user budget covers intake
5814
5960
  // (POST), the content edit (PATCH /:id), the reporter read-back (GET, GET /:id), and the
5815
5961
  // verification loop (POST /:id/accept, /:id/contest). The limiter is path-based, so a
@@ -6118,7 +6264,7 @@ var init_chunk_ISFDR7SP = __esm({
6118
6264
  }
6119
6265
  });
6120
6266
 
6121
- // ../../packages/core/dist/chunk-FNNHGL7K.js
6267
+ // ../../packages/core/dist/chunk-4QBKRQMM.js
6122
6268
  function fileSnapshotChanged(run) {
6123
6269
  return run.written + run.removed > 0;
6124
6270
  }
@@ -6159,10 +6305,10 @@ async function sendWithRetry(opts, cursor) {
6159
6305
  }
6160
6306
  }
6161
6307
  var rekorFileSnapshotAnswerSchema, FILE_SNAPSHOT_MAX_PAGES, FILE_SNAPSHOT_CONFLICT_ATTEMPTS, FILE_SNAPSHOT_PAGE_SPACING_MS, FILE_SNAPSHOT_CONFLICT_STATUS;
6162
- var init_chunk_FNNHGL7K = __esm({
6163
- "../../packages/core/dist/chunk-FNNHGL7K.js"() {
6308
+ var init_chunk_4QBKRQMM = __esm({
6309
+ "../../packages/core/dist/chunk-4QBKRQMM.js"() {
6164
6310
  "use strict";
6165
- init_chunk_ISFDR7SP();
6311
+ init_chunk_KJXJKAYT();
6166
6312
  init_chunk_5XEJSR22();
6167
6313
  init_zod();
6168
6314
  rekorFileSnapshotAnswerSchema = external_exports.object({
@@ -6395,145 +6541,57 @@ var init_chunk_4MRBBR5L = __esm({
6395
6541
  }
6396
6542
  });
6397
6543
 
6398
- // ../../packages/core/dist/chunk-IPDOHAZ5.js
6399
- var reportSourceSchema, intakeReportSourceSchema, reportClassificationSchema, reportStatusSchema, reportLocaleSchema, reportMessageAuthorRoleSchema, reportMessageSchema, sentryRefStatusSchema, createReportBody, editReportBody, reporterReportSummarySchema, reporterListResponseSchema, getReportResponseSchema, reporterTransitionResponseSchema, contestReportBody, reporterListQuery, listReportsQuery, GITHUB_ISSUE_URL_REGEX, githubIssueUrlSchema, transitionReportBody, groupReportsBody, holdReportBody;
6400
- var init_chunk_IPDOHAZ5 = __esm({
6401
- "../../packages/core/dist/chunk-IPDOHAZ5.js"() {
6544
+ // ../../packages/core/dist/chunk-SY6PLCPK.js
6545
+ var jsonSchemaSchema, hubUserIdentity, stateValueEntry, getHubUserContextResponse, updateHubUserBody, updateHubUserResponse, unlockHubUserNameResponse, stateResetParams, stateResetResponse;
6546
+ var init_chunk_SY6PLCPK = __esm({
6547
+ "../../packages/core/dist/chunk-SY6PLCPK.js"() {
6402
6548
  "use strict";
6403
- init_chunk_HZ6CADSY();
6549
+ init_chunk_6TSQ5HXC();
6404
6550
  init_zod();
6405
- reportSourceSchema = external_exports.enum(["sentry", "cli", "review", "security_audit"]);
6406
- intakeReportSourceSchema = external_exports.enum(["cli", "review", "security_audit"]);
6407
- reportClassificationSchema = external_exports.enum(["bug", "flaky_test", "security", "enhancement"]);
6408
- reportStatusSchema = external_exports.enum([
6409
- "pending",
6410
- "grouped",
6411
- "escalated",
6412
- "shipped",
6413
- "contested",
6414
- "addressed",
6415
- "dismissed"
6416
- ]);
6417
- reportLocaleSchema = external_exports.enum(["en", "pt", "es"]);
6418
- reportMessageAuthorRoleSchema = external_exports.enum(["reporter", "triage", "fixer", "system"]);
6419
- reportMessageSchema = external_exports.object({
6420
- message_id: external_exports.string(),
6421
- author_role: reportMessageAuthorRoleSchema,
6422
- /** The status transition this note accompanied (e.g. 'shipped'); null for a free/system note. */
6423
- transition: external_exports.string().nullable(),
6424
- body: external_exports.string(),
6425
- created_at: timestampSchema,
6426
- /**
6427
- * Visibility: `false` = reporter-facing (the default for every narrative entry); `true` =
6428
- * triage-internal (e.g. a `hold` rationale) — surfaced to platform admins only and NEVER
6429
- * returned on the reporter read path. The reporter's `GET /api/reports/:id` filters these out.
6430
- */
6431
- internal: external_exports.boolean()
6432
- });
6433
- sentryRefStatusSchema = external_exports.enum(["valid", "not_found", "mismatch", "unverified"]);
6434
- createReportBody = external_exports.object({
6435
- title: external_exports.string().min(5).max(256),
6436
- description: external_exports.string().min(10).max(5e3),
6437
- steps_to_reproduce: external_exports.string().max(3e3).optional(),
6438
- error_message: external_exports.string().max(2e3).optional(),
6439
- // Taxonomy (server defaults: source=cli, classification=bug when absent).
6440
- source: intakeReportSourceSchema.optional(),
6441
- classification: reportClassificationSchema.optional(),
6442
- // Stable dedup key (e.g. "<file>::<test>" for flaky, "<file>:<line>" for
6443
- // security). When present, the fingerprint uses it instead of the body hash.
6444
- dedup_key: external_exports.string().min(1).max(256).optional(),
6445
- // Context fields (auto-captured by the CLI)
6446
- organization_id: external_exports.string().optional(),
6447
- hub_id: external_exports.string().uuid().optional(),
6448
- hub_name: external_exports.string().max(256).optional(),
6449
- conversation_id: external_exports.string().uuid().optional(),
6450
- agent_id: external_exports.string().uuid().optional(),
6451
- agent_name: external_exports.string().max(256).optional(),
6452
- client_version: external_exports.string().max(64).optional(),
6453
- additional_context: external_exports.string().max(2e3).optional()
6454
- });
6455
- editReportBody = external_exports.object({
6456
- title: external_exports.string().min(5).max(256).optional(),
6457
- description: external_exports.string().min(10).max(5e3).optional(),
6458
- steps_to_reproduce: external_exports.string().max(3e3).optional(),
6459
- error_message: external_exports.string().max(2e3).optional(),
6460
- additional_context: external_exports.string().max(2e3).optional()
6461
- }).strict().refine((b) => Object.keys(b).length > 0, {
6462
- message: "at least one field must be provided"
6463
- });
6464
- reporterReportSummarySchema = external_exports.object({
6465
- report_id: external_exports.string(),
6466
- title: external_exports.string(),
6467
- description: external_exports.string(),
6468
- classification: reportClassificationSchema,
6469
- status: reportStatusSchema,
6470
- created_at: timestampSchema,
6471
- triaged_at: timestampSchema.nullable(),
6472
- resolved_at: timestampSchema.nullable(),
6473
- /** How many times the reporter has contested (gates the hard cap). */
6474
- contest_count: external_exports.number(),
6475
- /** True once triage issued a non-contestable (final) dismissal. */
6476
- dismissal_final: external_exports.boolean()
6477
- });
6478
- reporterListResponseSchema = external_exports.object({
6479
- data: external_exports.array(reporterReportSummarySchema)
6480
- });
6481
- getReportResponseSchema = external_exports.object({
6482
- report: reporterReportSummarySchema,
6483
- messages: external_exports.array(reportMessageSchema)
6551
+ jsonSchemaSchema = external_exports.record(external_exports.unknown());
6552
+ hubUserIdentity = external_exports.object({
6553
+ user_id: external_exports.string().nullable(),
6554
+ user_name: external_exports.string().nullable(),
6555
+ user_email: external_exports.string().nullable(),
6556
+ user_name_locked: external_exports.boolean(),
6557
+ created_at: external_exports.string(),
6558
+ updated_at: external_exports.string().nullable(),
6559
+ hub_user_id: external_exports.string().optional(),
6560
+ enabled: external_exports.boolean().optional(),
6561
+ hub_team_id: external_exports.string().nullable().optional(),
6562
+ source: external_exports.enum(["grant", "auto"]).optional()
6484
6563
  });
6485
- reporterTransitionResponseSchema = external_exports.object({
6486
- report: reporterReportSummarySchema
6564
+ stateValueEntry = external_exports.object({
6565
+ state_slug: external_exports.string(),
6566
+ state_name: external_exports.string(),
6567
+ state_description: external_exports.string().nullable().optional(),
6568
+ scope: external_exports.enum(["user", "conversation"]),
6569
+ json_schema: jsonSchemaSchema,
6570
+ initial_value: external_exports.unknown(),
6571
+ value: external_exports.unknown(),
6572
+ is_reserved: external_exports.boolean()
6487
6573
  });
6488
- contestReportBody = external_exports.object({
6489
- reason: external_exports.string().min(1).max(5e3)
6574
+ getHubUserContextResponse = external_exports.object({
6575
+ user: hubUserIdentity,
6576
+ user_states: external_exports.array(stateValueEntry),
6577
+ conversation_states: external_exports.array(stateValueEntry)
6490
6578
  });
6491
- reporterListQuery = external_exports.object({
6492
- status: reportStatusSchema.optional()
6579
+ updateHubUserBody = external_exports.object({
6580
+ // Non-empty, non-null. `.nullable()` here would bypass `.min(1)` and let an
6581
+ // admin arm the lock on a null name — see hub-do.ts updateHubUser null-guard.
6582
+ user_name: external_exports.string().min(1).max(120)
6493
6583
  });
6494
- listReportsQuery = external_exports.object({
6495
- status: reportStatusSchema.optional(),
6496
- source: reportSourceSchema.optional(),
6497
- limit: external_exports.coerce.number().int().min(1).max(200).optional(),
6498
- offset: external_exports.coerce.number().int().min(0).optional(),
6499
- /** ISO 8601 lower bound on created_at. */
6500
- since: external_exports.string().datetime().optional(),
6501
- /**
6502
- * ISO 8601 lower bound on resolution time — "what did we resolve recently", which `since`
6503
- * (a created_at filter) cannot answer for a long-lived report resolved yesterday. Implies
6504
- * a terminal status (`addressed`/`dismissed`) and orders on that same axis.
6505
- */
6506
- resolved_since: external_exports.string().datetime().optional()
6584
+ updateHubUserResponse = external_exports.object({
6585
+ user: hubUserIdentity
6507
6586
  });
6508
- GITHUB_ISSUE_URL_REGEX = /^https:\/\/github\.com\/[^/]+\/[^/]+\/issues\/\d+(?:[/?#]|$)/;
6509
- githubIssueUrlSchema = external_exports.string().url().refine((u) => GITHUB_ISSUE_URL_REGEX.test(u), {
6510
- message: "must be an https://github.com/<owner>/<repo>/issues/<number> URL"
6587
+ unlockHubUserNameResponse = external_exports.object({
6588
+ user: hubUserIdentity
6511
6589
  });
6512
- transitionReportBody = external_exports.discriminatedUnion("target", [
6513
- external_exports.object({
6514
- target: external_exports.literal("escalated"),
6515
- gh_issue_url: githubIssueUrlSchema,
6516
- ai_verdict: external_exports.string().max(2e3).optional()
6517
- }),
6518
- external_exports.object({
6519
- target: external_exports.literal("shipped"),
6520
- note: external_exports.string().min(1).max(2e3).optional()
6521
- }),
6522
- external_exports.object({
6523
- target: external_exports.literal("addressed")
6524
- }),
6525
- external_exports.object({
6526
- target: external_exports.literal("dismissed"),
6527
- dismissal_reason: external_exports.string().min(1).max(5e3),
6528
- ai_verdict: external_exports.string().max(2e3).optional(),
6529
- final: external_exports.boolean().optional()
6530
- })
6531
- ]);
6532
- groupReportsBody = external_exports.object({
6533
- member_ids: external_exports.array(external_exports.string().uuid()).min(1).max(100)
6590
+ stateResetParams = external_exports.object({
6591
+ stateSlug: slugSchema
6534
6592
  });
6535
- holdReportBody = external_exports.object({
6536
- reason: external_exports.string().min(1).max(5e3)
6593
+ stateResetResponse = external_exports.object({
6594
+ ok: external_exports.literal(true)
6537
6595
  });
6538
6596
  }
6539
6597
  });
@@ -6656,6 +6714,101 @@ var init_chunk_FPSDNS2E = __esm({
6656
6714
  }
6657
6715
  });
6658
6716
 
6717
+ // ../../packages/core/dist/chunk-LKBSHANA.js
6718
+ var DESKTOP_SHELL_VERSION_RE, DESKTOP_PLATFORMS, DESKTOP_FLAVORS, desktopShellInfoSchema, DESKTOP_PRESENCE_STATES, desktopPresenceSchema, desktopUpdateSchema, DESKTOP_SIGN_IN_URL_MAX_LENGTH, DESKTOP_APP_PATH_MAX_LENGTH, desktopAppPathSchema, DESKTOP_NOTIFICATION_KINDS, DESKTOP_NOTIFICATION_TITLE_MAX_LENGTH, DESKTOP_NOTIFICATION_BODY_MAX_LENGTH, notificationTitleSchema, notificationBodySchema, desktopNotificationSchema, DESKTOP_BADGE_MAX_COUNT, DESKTOP_BADGE_LABEL_MAX_LENGTH, desktopBadgeSchema, desktopNavigateSchema, desktopSettingsSchema, desktopSettingsChangeSchema, desktopBridgeArgsSchemas;
6719
+ var init_chunk_LKBSHANA = __esm({
6720
+ "../../packages/core/dist/chunk-LKBSHANA.js"() {
6721
+ "use strict";
6722
+ init_zod();
6723
+ DESKTOP_SHELL_VERSION_RE = /^(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})(-[0-9A-Za-z.-]{1,32})?$/;
6724
+ DESKTOP_PLATFORMS = ["darwin", "win32"];
6725
+ DESKTOP_FLAVORS = ["production", "development"];
6726
+ desktopShellInfoSchema = external_exports.object({
6727
+ /** The shell's own release version, independent of the web deploy. */
6728
+ shellVersion: external_exports.string().regex(DESKTOP_SHELL_VERSION_RE),
6729
+ /** The Electron runtime the shell was built with. */
6730
+ electronVersion: external_exports.string().regex(/^\d{1,4}\.\d{1,4}\.\d{1,4}(-[0-9A-Za-z.-]{1,32})?$/),
6731
+ platform: external_exports.enum(DESKTOP_PLATFORMS),
6732
+ /** CPU architecture as Node reports it (`arm64`, `x64`). */
6733
+ arch: external_exports.string().regex(/^[a-z0-9_]{1,16}$/),
6734
+ flavor: external_exports.enum(DESKTOP_FLAVORS),
6735
+ /**
6736
+ * Present, and true, when the shell runs from the Microsoft Store's package: the Store updates it,
6737
+ * and Windows alone opens it at login (the package's startup task, which the person turns on in
6738
+ * Windows' settings). An optional field, so no new `bridgeVersion`: an older page ignores it, and
6739
+ * its absence is every other shell.
6740
+ */
6741
+ store: external_exports.literal(true).optional()
6742
+ });
6743
+ DESKTOP_PRESENCE_STATES = ["present", "away"];
6744
+ desktopPresenceSchema = external_exports.object({
6745
+ presence: external_exports.enum(DESKTOP_PRESENCE_STATES),
6746
+ mainWindow: external_exports.object({
6747
+ shown: external_exports.boolean(),
6748
+ focused: external_exports.boolean()
6749
+ })
6750
+ });
6751
+ desktopUpdateSchema = external_exports.object({
6752
+ ready: external_exports.object({
6753
+ version: external_exports.string().regex(DESKTOP_SHELL_VERSION_RE),
6754
+ offerRestart: external_exports.boolean()
6755
+ }).nullable()
6756
+ });
6757
+ DESKTOP_SIGN_IN_URL_MAX_LENGTH = 4096;
6758
+ DESKTOP_APP_PATH_MAX_LENGTH = 512;
6759
+ desktopAppPathSchema = external_exports.string().max(DESKTOP_APP_PATH_MAX_LENGTH).regex(/^\/(?![/\\])[^\s\\]*$/);
6760
+ DESKTOP_NOTIFICATION_KINDS = ["handoff", "message", "summary"];
6761
+ DESKTOP_NOTIFICATION_TITLE_MAX_LENGTH = 200;
6762
+ DESKTOP_NOTIFICATION_BODY_MAX_LENGTH = 500;
6763
+ notificationTitleSchema = external_exports.string().min(1).max(DESKTOP_NOTIFICATION_TITLE_MAX_LENGTH);
6764
+ notificationBodySchema = external_exports.string().max(DESKTOP_NOTIFICATION_BODY_MAX_LENGTH);
6765
+ desktopNotificationSchema = external_exports.object({
6766
+ kind: external_exports.enum(DESKTOP_NOTIFICATION_KINDS),
6767
+ title: notificationTitleSchema,
6768
+ body: notificationBodySchema,
6769
+ path: desktopAppPathSchema,
6770
+ withoutPreview: external_exports.object({ title: notificationTitleSchema, body: notificationBodySchema }).optional()
6771
+ });
6772
+ DESKTOP_BADGE_MAX_COUNT = 1e6;
6773
+ DESKTOP_BADGE_LABEL_MAX_LENGTH = 200;
6774
+ desktopBadgeSchema = external_exports.object({
6775
+ count: external_exports.number().int().min(0).max(DESKTOP_BADGE_MAX_COUNT),
6776
+ label: external_exports.string().max(DESKTOP_BADGE_LABEL_MAX_LENGTH)
6777
+ });
6778
+ desktopNavigateSchema = external_exports.object({
6779
+ path: desktopAppPathSchema
6780
+ });
6781
+ desktopSettingsSchema = external_exports.object({
6782
+ /** The app opens when the person logs in to the computer: the operating system's own login item. */
6783
+ openAtLogin: external_exports.boolean(),
6784
+ /** Closing the window keeps the app running in the tray (true), or quits it (false). */
6785
+ closeToTray: external_exports.boolean(),
6786
+ /** The shell shows notifications (true), or none (false). The badge is not a notification. */
6787
+ notifications: external_exports.boolean(),
6788
+ /**
6789
+ * A customer message's notification shows the customer's name and words, where the platform
6790
+ * allows them at all (`desktopShowsCustomerWords`: macOS); elsewhere the shell never shows them.
6791
+ */
6792
+ messagePreview: external_exports.boolean()
6793
+ });
6794
+ desktopSettingsChangeSchema = desktopSettingsSchema.partial().strict().refine((change) => Object.values(change).every((value) => typeof value === "boolean"), {
6795
+ message: "each setting changed is true or false"
6796
+ });
6797
+ desktopBridgeArgsSchemas = {
6798
+ getShellInfo: external_exports.tuple([]),
6799
+ getPresence: external_exports.tuple([]),
6800
+ openSignIn: external_exports.tuple([external_exports.string().max(DESKTOP_SIGN_IN_URL_MAX_LENGTH)]),
6801
+ getUpdate: external_exports.tuple([]),
6802
+ restartToUpdate: external_exports.tuple([]),
6803
+ notify: external_exports.tuple([desktopNotificationSchema]),
6804
+ setBadge: external_exports.tuple([desktopBadgeSchema]),
6805
+ clearAll: external_exports.tuple([]),
6806
+ getSettings: external_exports.tuple([]),
6807
+ setSettings: external_exports.tuple([desktopSettingsChangeSchema])
6808
+ };
6809
+ }
6810
+ });
6811
+
6659
6812
  // ../../packages/core/dist/chunk-MIWZOSPI.js
6660
6813
  function toIso(epochMs) {
6661
6814
  return new Date(epochMs).toISOString();
@@ -6811,7 +6964,16 @@ var init_chunk_E4DIIOOE = __esm({
6811
6964
  }
6812
6965
  });
6813
6966
 
6814
- // ../../packages/core/dist/chunk-OGXIPFQY.js
6967
+ // ../../packages/core/dist/chunk-A4JC7DXB.js
6968
+ var GIT_CHECKOUT_MAX_LENGTH;
6969
+ var init_chunk_A4JC7DXB = __esm({
6970
+ "../../packages/core/dist/chunk-A4JC7DXB.js"() {
6971
+ "use strict";
6972
+ GIT_CHECKOUT_MAX_LENGTH = 255;
6973
+ }
6974
+ });
6975
+
6976
+ // ../../packages/core/dist/chunk-23UZ2IKU.js
6815
6977
  function spokenLineField(label, description2) {
6816
6978
  return { type: "text", label, maxLength: SPOKEN_LINE_MAX_CHARS, default: "", description: description2 };
6817
6979
  }
@@ -6821,9 +6983,10 @@ function byLowercaseName(a, b) {
6821
6983
  return x < y ? -1 : x > y ? 1 : 0;
6822
6984
  }
6823
6985
  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;
6824
- var init_chunk_OGXIPFQY = __esm({
6825
- "../../packages/core/dist/chunk-OGXIPFQY.js"() {
6986
+ var init_chunk_23UZ2IKU = __esm({
6987
+ "../../packages/core/dist/chunk-23UZ2IKU.js"() {
6826
6988
  "use strict";
6989
+ init_chunk_A4JC7DXB();
6827
6990
  CALLER_LANGUAGE = "caller";
6828
6991
  TTS_VOICE_REPLY_ENABLED_FIELD = {
6829
6992
  voice_reply_enabled: {
@@ -7686,12 +7849,12 @@ var init_chunk_OGXIPFQY = __esm({
7686
7849
  // The managed session is conversation-lifetime and is NOT reaped at this deadline.
7687
7850
  max_session_minutes: { type: "number", label: "Max Turn (minutes)", min: 1, max: 480, default: 60, description: "Hard cap on a single turn's drain wall-clock, and the bound on the per-turn harness token TTL. The managed session itself lives for the conversation \u2014 it is not reaped at this deadline." },
7688
7851
  ...HARNESS_EGRESS_FIELDS,
7689
- // repo_url only, with no `repo_branch`: the session clones the default branch. The
7690
- // vendor's `github_repository` resource now takes a `checkout` (branch or commit,
7691
- // platform.claude.com/docs/en/managed-agents/github, 2026-10-19); a branch setting is
7692
- // left to the "work on a repository" agent template (wayai-pro/wayai#5083 Phase 4).
7693
- // Until then, working on another branch is an agent-instruction concern.
7694
- repo_url: { type: "text", label: "Repository URL", description: "Optional GitHub repository (https://github.com/<owner>/<repo>) cloned into the managed workspace at session start. Needs the connection's GitHub App installed on it. The DEFAULT branch is cloned \u2014 to work on another branch, instruct the agent to check it out." },
7852
+ repo_url: { type: "text", label: "Repository URL", description: "Optional GitHub repository (https://github.com/<owner>/<repo>) cloned into the managed workspace at session start. Needs the connection's GitHub App installed on it." },
7853
+ // The vendor's `checkout` on the session's `github_repository` resource (a branch, or a
7854
+ // commit: platform.claude.com/docs/en/managed-agents/github, checked 2026-10-19). It is
7855
+ // fixed at session create, so a change recreates the session (`config-hash.ts`). Checked
7856
+ // at write (`format: 'git_checkout'`); a full commit hash is read as a commit.
7857
+ repo_checkout: { type: "text", format: "git_checkout", maxLength: GIT_CHECKOUT_MAX_LENGTH, label: "Branch or Commit", description: "Optional: the branch, or the full commit hash, cloned from the Repository URL. Empty clones the repository's default branch." },
7695
7858
  ...COPILOT_TRIGGER_FIELD
7696
7859
  },
7697
7860
  channel_settings_schema: null,
@@ -7788,13 +7951,13 @@ var init_chunk_OGXIPFQY = __esm({
7788
7951
  }
7789
7952
  });
7790
7953
 
7791
- // ../../packages/core/dist/chunk-QZZ3OHLV.js
7954
+ // ../../packages/core/dist/chunk-23ESQLLF.js
7792
7955
  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;
7793
- var init_chunk_QZZ3OHLV = __esm({
7794
- "../../packages/core/dist/chunk-QZZ3OHLV.js"() {
7956
+ var init_chunk_23ESQLLF = __esm({
7957
+ "../../packages/core/dist/chunk-23ESQLLF.js"() {
7795
7958
  "use strict";
7796
7959
  init_chunk_E4DIIOOE();
7797
- init_chunk_OGXIPFQY();
7960
+ init_chunk_23UZ2IKU();
7798
7961
  init_chunk_HZ6CADSY();
7799
7962
  init_chunk_MIWZOSPI();
7800
7963
  init_zod();
@@ -8049,58 +8212,58 @@ var init_chunk_EA23LSDS = __esm({
8049
8212
  }
8050
8213
  });
8051
8214
 
8052
- // ../../packages/core/dist/chunk-SY6PLCPK.js
8053
- var jsonSchemaSchema, hubUserIdentity, stateValueEntry, getHubUserContextResponse, updateHubUserBody, updateHubUserResponse, unlockHubUserNameResponse, stateResetParams, stateResetResponse;
8054
- var init_chunk_SY6PLCPK = __esm({
8055
- "../../packages/core/dist/chunk-SY6PLCPK.js"() {
8215
+ // ../../packages/core/dist/chunk-V4FRPRH5.js
8216
+ var CONSULT_THREAD_STATUSES, consultThreadStatus, CONSULT_THREAD_TITLE_MAX, consultThreadTitle, consultThreadSummary, listConsultThreadsQuery, listConsultThreadsResponse, createConsultThreadBody, createConsultThreadResponse, consultThreadIdParam, updateConsultThreadBody, updateConsultThreadResponse, CONSULT_AWAIT_TIMEOUT_MS;
8217
+ var init_chunk_V4FRPRH5 = __esm({
8218
+ "../../packages/core/dist/chunk-V4FRPRH5.js"() {
8056
8219
  "use strict";
8057
- init_chunk_6TSQ5HXC();
8058
8220
  init_zod();
8059
- jsonSchemaSchema = external_exports.record(external_exports.unknown());
8060
- hubUserIdentity = external_exports.object({
8061
- user_id: external_exports.string().nullable(),
8062
- user_name: external_exports.string().nullable(),
8063
- user_email: external_exports.string().nullable(),
8064
- user_name_locked: external_exports.boolean(),
8065
- created_at: external_exports.string(),
8066
- updated_at: external_exports.string().nullable(),
8067
- hub_user_id: external_exports.string().optional(),
8068
- enabled: external_exports.boolean().optional(),
8069
- hub_team_id: external_exports.string().nullable().optional(),
8070
- source: external_exports.enum(["grant", "auto"]).optional()
8221
+ CONSULT_THREAD_STATUSES = ["open", "awaiting", "resolved", "cancelled_at_close"];
8222
+ consultThreadStatus = external_exports.enum(CONSULT_THREAD_STATUSES);
8223
+ CONSULT_THREAD_TITLE_MAX = 120;
8224
+ consultThreadTitle = external_exports.string().trim().min(1).max(CONSULT_THREAD_TITLE_MAX);
8225
+ consultThreadSummary = external_exports.object({
8226
+ consult_thread_id: external_exports.string(),
8227
+ conversation_id: external_exports.string(),
8228
+ initiator_type: external_exports.enum(["team", "agent"]),
8229
+ initiator_id: external_exports.string(),
8230
+ engaged_agent_id: external_exports.string().nullable(),
8231
+ engaged_agent_name: external_exports.string().nullable(),
8232
+ title: external_exports.string().nullable(),
8233
+ status: consultThreadStatus,
8234
+ created_at: external_exports.string()
8071
8235
  });
8072
- stateValueEntry = external_exports.object({
8073
- state_slug: external_exports.string(),
8074
- state_name: external_exports.string(),
8075
- state_description: external_exports.string().nullable().optional(),
8076
- scope: external_exports.enum(["user", "conversation"]),
8077
- json_schema: jsonSchemaSchema,
8078
- initial_value: external_exports.unknown(),
8079
- value: external_exports.unknown(),
8080
- is_reserved: external_exports.boolean()
8236
+ listConsultThreadsQuery = external_exports.object({
8237
+ hub_id: external_exports.string().uuid()
8081
8238
  });
8082
- getHubUserContextResponse = external_exports.object({
8083
- user: hubUserIdentity,
8084
- user_states: external_exports.array(stateValueEntry),
8085
- conversation_states: external_exports.array(stateValueEntry)
8239
+ listConsultThreadsResponse = external_exports.object({
8240
+ threads: external_exports.array(consultThreadSummary)
8086
8241
  });
8087
- updateHubUserBody = external_exports.object({
8088
- // Non-empty, non-null. `.nullable()` here would bypass `.min(1)` and let an
8089
- // admin arm the lock on a null name — see hub-do.ts updateHubUser null-guard.
8090
- user_name: external_exports.string().min(1).max(120)
8242
+ createConsultThreadBody = external_exports.object({
8243
+ hub_id: external_exports.string().uuid(),
8244
+ title: consultThreadTitle.optional(),
8245
+ // Optionally engage a consultant on creation. Validated server-side against the
8246
+ // hub's `consultant`-role agents; a non-consultant / unknown id is rejected.
8247
+ engaged_agent_id: external_exports.string().uuid().optional()
8091
8248
  });
8092
- updateHubUserResponse = external_exports.object({
8093
- user: hubUserIdentity
8249
+ createConsultThreadResponse = external_exports.object({
8250
+ thread: consultThreadSummary
8094
8251
  });
8095
- unlockHubUserNameResponse = external_exports.object({
8096
- user: hubUserIdentity
8252
+ consultThreadIdParam = external_exports.object({
8253
+ id: external_exports.string().uuid(),
8254
+ threadId: external_exports.string().uuid()
8097
8255
  });
8098
- stateResetParams = external_exports.object({
8099
- stateSlug: slugSchema
8256
+ updateConsultThreadBody = external_exports.object({
8257
+ hub_id: external_exports.string().uuid(),
8258
+ title: consultThreadTitle.optional(),
8259
+ engaged_agent_id: external_exports.string().uuid().optional()
8260
+ }).refine((v) => v.title !== void 0 || v.engaged_agent_id !== void 0, {
8261
+ message: "Provide a title and/or an engaged_agent_id to update"
8100
8262
  });
8101
- stateResetResponse = external_exports.object({
8102
- ok: external_exports.literal(true)
8263
+ updateConsultThreadResponse = external_exports.object({
8264
+ thread: consultThreadSummary
8103
8265
  });
8266
+ CONSULT_AWAIT_TIMEOUT_MS = 15 * 6e4;
8104
8267
  }
8105
8268
  });
8106
8269
 
@@ -8161,15 +8324,15 @@ var init_chunk_MH4O3YEX = __esm({
8161
8324
  }
8162
8325
  });
8163
8326
 
8164
- // ../../packages/core/dist/chunk-UZ7SPBM3.js
8327
+ // ../../packages/core/dist/chunk-UFYIBL66.js
8165
8328
  function catalogToolSideEffects(toolName) {
8166
8329
  const sideEffects = CATALOG_SIDE_EFFECTS.get(toolName);
8167
8330
  if (sideEffects === void 0) return "unknown";
8168
8331
  return sideEffects ? "side_effects" : "none";
8169
8332
  }
8170
8333
  var NATIVE_TOOL_SCHEMAS, WAYAI_CONNECTOR, SANDBOX_AGENT_ROLES, BASE_NATIVE_TOOLS, NATIVE_TOOLS, CATALOG_SIDE_EFFECTS;
8171
- var init_chunk_UZ7SPBM3 = __esm({
8172
- "../../packages/core/dist/chunk-UZ7SPBM3.js"() {
8334
+ var init_chunk_UFYIBL66 = __esm({
8335
+ "../../packages/core/dist/chunk-UFYIBL66.js"() {
8173
8336
  "use strict";
8174
8337
  init_chunk_DHPUPI4Y();
8175
8338
  NATIVE_TOOL_SCHEMAS = {
@@ -8390,15 +8553,15 @@ var init_chunk_UZ7SPBM3 = __esm({
8390
8553
  "properties": {
8391
8554
  "path": {
8392
8555
  "type": "string",
8393
- "description": 'Path to the file. Documents of your knowledge base live under "data/<file-type>/", exactly as list_files lists them \u2014 e.g. "data/policies/eu/refunds.md" \u2014 always written in full, and come back with the version the file is at: as text, or as base64 when the file is not text. Knowledge and skill files live under "resources/", exactly as listed in your resource structure or in a file listing \u2014 e.g. "resources/product-docs/references/menu.md", where the segment after "resources/" names the resource. Files attached to this conversation live under "conversation/" and are announced in the transcript by that path \u2014 e.g. "conversation/report.pdf". A shorter form also works for those two and is matched across everything you can read, preferring an exact path over one that merely ends with what you wrote ("references/menu.md", or just "menu.md"); dropping a middle segment does not resolve, and a bare name carried by both a resource and this conversation is reported as ambiguous so you can retry with the full path. Files from an EARLIER conversation with the same user live under "conversations/<conversation_id>/" \u2014 e.g. "conversations/1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed/receipt.pdf", exactly as the transcript of that conversation announces them (get_conversation). That form takes no shortening: write the mount, the conversation id and the file name in full. Prefer this over file_id: paths are stable, while IDs are regenerated whenever a hub is published.'
8556
+ "description": 'Path to the file. Documents of your knowledge base live under "data/<file-type>/", exactly as list_files lists them \u2014 e.g. "data/policies/eu/refunds.md" \u2014 always written in full, and come back with the version the file is at: as text, or as base64 when the file is not text. Skill files live under "skills/" and knowledge files under "resources/", exactly as listed in your resource structure or in a file listing \u2014 e.g. "skills/order-processing/references/menu.md", where the segment after "skills/" names the skill, or "resources/product-docs/menu.md", where the segment after "resources/" names the knowledge resource. Files attached to this conversation live under "conversation/" and are announced in the transcript by that path \u2014 e.g. "conversation/report.pdf". A shorter form also works for those and is matched across everything you can read, preferring an exact path over one that merely ends with what you wrote ("references/menu.md", or just "menu.md"); dropping a middle segment does not resolve, and a bare name carried by both a skill or resource and this conversation is reported as ambiguous so you can retry with the full path. Files from an EARLIER conversation with the same user live under "conversations/<conversation_id>/" \u2014 e.g. "conversations/1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed/receipt.pdf", exactly as the transcript of that conversation announces them (get_conversation). That form takes no shortening: write the mount, the conversation id and the file name in full. Prefer this over file_id: paths are stable, while IDs are regenerated whenever a hub is published.'
8394
8557
  },
8395
8558
  "file_id": {
8396
8559
  "type": "string",
8397
8560
  "description": "The file ID to retrieve, from a conversation message or a file listing. Still supported, but prefer path for resource files."
8398
8561
  },
8399
- "resource_id": {
8562
+ "skill_id": {
8400
8563
  "type": "string",
8401
- "description": "Optional. Restricts a path to one resource \u2014 use it when the same file name exists in more than one resource and the tool reports the reference as ambiguous. Must be a resource linked to this agent."
8564
+ "description": "Optional. Restricts a path to one skill, named by its id or its slug \u2014 use it when the same file name exists in more than one skill and the tool reports the reference as ambiguous. Must be a skill linked to this agent."
8402
8565
  },
8403
8566
  "view_range": {
8404
8567
  "type": "array",
@@ -8585,7 +8748,7 @@ var init_chunk_UZ7SPBM3 = __esm({
8585
8748
  "items": {
8586
8749
  "type": "string"
8587
8750
  },
8588
- "description": 'Files to send to the user, each named by path (preferred) or by ID. Paths are the addresses announced in the transcript and in your resource structure \u2014 "conversation/report.pdf" for a file attached to this conversation, "conversations/<conversation_id>/receipt.pdf" for one attached to an earlier conversation with the same user, "resources/product-docs/price-list.pdf" for a knowledge or skill file. IDs remain accepted, but they are regenerated whenever a hub is published, so a path is the stable address.'
8751
+ "description": 'Files to send to the user, each named by path (preferred) or by ID. Paths are the addresses announced in the transcript and in your resource structure \u2014 "conversation/report.pdf" for a file attached to this conversation, "conversations/<conversation_id>/receipt.pdf" for one attached to an earlier conversation with the same user, "skills/order-processing/price-list.pdf" for a skill file, "resources/product-docs/price-list.pdf" for a knowledge file. IDs remain accepted, but they are regenerated whenever a hub is published, so a path is the stable address.'
8589
8752
  },
8590
8753
  "folder_ids": {
8591
8754
  "type": "array",
@@ -8615,7 +8778,7 @@ var init_chunk_UZ7SPBM3 = __esm({
8615
8778
  "properties": {
8616
8779
  "path": {
8617
8780
  "type": "string",
8618
- "description": 'What to list. Omit it (or pass "") for the mounts you can browse \u2014 the available mounts are listed here at runtime. "conversation" lists the files attached to this conversation. "resources" lists every resource mount. "resources/<resource-slug>" lists the top level of a knowledge resource or skill, and "resources/<resource-slug>/<folder>/<subfolder>" lists that folder. Folder rows come back with their own path, so you drill down by passing back the path of the row you want. "data" lists your document mounts, and "data/<file-type>" or "data/<file-type>/<folder>" lists every document beneath it, a page at a time.'
8781
+ "description": 'What to list. Omit it (or pass "") for the mounts you can browse \u2014 the available mounts are listed here at runtime. "conversation" lists the files attached to this conversation. "skills" lists every skill mount, and "resources" every knowledge resource mount. "skills/<skill-slug>" lists the top level of a skill and "resources/<resource-slug>" that of a knowledge resource; "skills/<skill-slug>/<folder>/<subfolder>" (or the same under "resources/") lists that folder. Folder rows come back with their own path, so you drill down by passing back the path of the row you want. "data" lists your document mounts, and "data/<file-type>" or "data/<file-type>/<folder>" lists every document beneath it, a page at a time.'
8619
8782
  },
8620
8783
  "query": {
8621
8784
  "type": "string",
@@ -8645,7 +8808,7 @@ var init_chunk_UZ7SPBM3 = __esm({
8645
8808
  "additionalProperties": false
8646
8809
  }
8647
8810
  },
8648
- "tool_instructions": 'Use to find out which files exist before reading one. Call it with no path first: that returns the mounts \u2014 "conversation" for what the user attached here, and one "resources/<slug>" per knowledge resource or skill linked to you. Then pass a mount or folder path back to list its contents. Every row carries a `path`; pass that path to read_file to open the file, or (outside "data/") to send_files to deliver it. Pass query, tags or metadata_filter to search a whole resource or data/ file type at once instead of walking it folder by folder. Files from EARLIER conversations are not listed here \u2014 the transcript of each past conversation announces its own files by path (get_conversation).'
8811
+ "tool_instructions": 'Use to find out which files exist before reading one. Call it with no path first: that returns the mounts \u2014 "conversation" for what the user attached here, one "skills/<slug>" per skill and one "resources/<slug>" per knowledge resource linked to you. Then pass a mount or folder path back to list its contents. Every row carries a `path`; pass that path to read_file to open the file, or (outside "data/") to send_files to deliver it. Pass query, tags or metadata_filter to search a whole skill, resource or data/ file type at once instead of walking it folder by folder. Files from EARLIER conversations are not listed here \u2014 the transcript of each past conversation announces its own files by path (get_conversation).'
8649
8812
  },
8650
8813
  "list_resource_folders": {
8651
8814
  "tool_config": {
@@ -9057,20 +9220,20 @@ var init_chunk_UZ7SPBM3 = __esm({
9057
9220
  SANDBOX_AGENT_ROLES = [...PILOT_TRACK_ROLES, ...COPILOT_TRACK_ROLES];
9058
9221
  BASE_NATIVE_TOOLS = [
9059
9222
  // --- Wayai core tools ---
9060
- { tool_native_id: "nt-001", tool_name: "transfer_to_agent", tool_display_name: "Transfer to Agent", tool_description: "Transfer the conversation to another AI agent", connector_id: WAYAI_CONNECTOR, operation: "transfer_to_agent", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, side_effects: false, replay: "keyed" },
9061
- { tool_native_id: "nt-002", tool_name: "transfer_to_team", tool_display_name: "Transfer to Team", tool_description: "Escalate conversation to a human support team", connector_id: WAYAI_CONNECTOR, operation: "transfer_to_team", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, side_effects: false, replay: "keyed" },
9062
- { tool_native_id: "nt-003", tool_name: "close_conversation", tool_display_name: "Close Conversation", tool_description: "Close and end the current conversation", connector_id: WAYAI_CONNECTOR, operation: "close_conversation", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: true, replay: "keyed" },
9063
- { tool_native_id: "nt-004", tool_name: "update_kanban_status", tool_display_name: "Update Kanban Status", tool_description: "Update the kanban status of the conversation", connector_id: WAYAI_CONNECTOR, operation: "update_kanban_status", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
9064
- { tool_native_id: "nt-005", tool_name: "schedule_followup", tool_display_name: "Schedule Follow-up", tool_description: "Schedule a follow-up message for the conversation", connector_id: WAYAI_CONNECTOR, operation: "schedule_followup", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: true, execution_config: null, side_effects: true, replay: "keyed" },
9065
- { tool_native_id: "nt-006", tool_name: "send_files", tool_display_name: "Send Files", tool_description: "Send files to the user", connector_id: WAYAI_CONNECTOR, operation: "send_files", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: true, replay: "keyed" },
9066
- { tool_native_id: "nt-007", tool_name: "update_state", tool_display_name: "Update State", tool_description: "Update conversation or user state variables", connector_id: WAYAI_CONNECTOR, operation: "update_state", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
9067
- { tool_native_id: "nt-008", tool_name: "get_state", tool_display_name: "Get State", tool_description: "Retrieve conversation or user state values", connector_id: WAYAI_CONNECTOR, operation: "get_state", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
9068
- { tool_native_id: "nt-009", tool_name: "reset_state", tool_display_name: "Reset State", tool_description: "Reset conversation or user state to initial values", connector_id: WAYAI_CONNECTOR, operation: "reset_state", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
9069
- { tool_native_id: "nt-010", tool_name: "set_state_path", tool_display_name: "Set State Path", tool_description: "Set a specific path within state object", connector_id: WAYAI_CONNECTOR, operation: "set_state_path", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
9070
- { tool_native_id: "nt-011", tool_name: "consult_agent", tool_display_name: "Consult Agent", tool_description: "Consult an advisor agent for advice without transferring", connector_id: WAYAI_CONNECTOR, operation: "consult_agent", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "keyed" },
9071
- { tool_native_id: "nt-013", tool_name: "read_skill", tool_display_name: "Read Skill", tool_description: "Read the full specification of a skill", connector_id: WAYAI_CONNECTOR, operation: "read_skill", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
9072
- { tool_native_id: "nt-014", tool_name: "read_skill_file", tool_display_name: "Read Skill File", tool_description: "Read a specific file within a skill", connector_id: WAYAI_CONNECTOR, operation: "read_skill_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
9073
- { tool_native_id: "nt-015", tool_name: "read_file", tool_display_name: "Read File", tool_description: "Read the contents of a resource file", connector_id: WAYAI_CONNECTOR, operation: "read_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
9223
+ { tool_native_id: "nt-001", tool_name: "transfer_to_agent", tool_display_name: "Transfer to Agent", tool_description: "Transfer the conversation to another AI agent", connector_id: WAYAI_CONNECTOR, operation: "transfer_to_agent", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, side_effects: false, replay: "keyed", hosted: true },
9224
+ { tool_native_id: "nt-002", tool_name: "transfer_to_team", tool_display_name: "Transfer to Team", tool_description: "Escalate conversation to a human support team", connector_id: WAYAI_CONNECTOR, operation: "transfer_to_team", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, side_effects: false, replay: "keyed", hosted: true },
9225
+ { tool_native_id: "nt-003", tool_name: "close_conversation", tool_display_name: "Close Conversation", tool_description: "Close and end the current conversation", connector_id: WAYAI_CONNECTOR, operation: "close_conversation", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: true, replay: "keyed", hosted: true },
9226
+ { tool_native_id: "nt-004", tool_name: "update_kanban_status", tool_display_name: "Update Kanban Status", tool_description: "Update the kanban status of the conversation", connector_id: WAYAI_CONNECTOR, operation: "update_kanban_status", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: true },
9227
+ { tool_native_id: "nt-005", tool_name: "schedule_followup", tool_display_name: "Schedule Follow-up", tool_description: "Schedule a follow-up message for the conversation", connector_id: WAYAI_CONNECTOR, operation: "schedule_followup", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: true, execution_config: null, side_effects: true, replay: "keyed", hosted: true },
9228
+ { tool_native_id: "nt-006", tool_name: "send_files", tool_display_name: "Send Files", tool_description: "Send files to the user", connector_id: WAYAI_CONNECTOR, operation: "send_files", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: true, replay: "keyed", hosted: false },
9229
+ { tool_native_id: "nt-007", tool_name: "update_state", tool_display_name: "Update State", tool_description: "Update conversation or user state variables", connector_id: WAYAI_CONNECTOR, operation: "update_state", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: true },
9230
+ { tool_native_id: "nt-008", tool_name: "get_state", tool_display_name: "Get State", tool_description: "Retrieve conversation or user state values", connector_id: WAYAI_CONNECTOR, operation: "get_state", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: true },
9231
+ { tool_native_id: "nt-009", tool_name: "reset_state", tool_display_name: "Reset State", tool_description: "Reset conversation or user state to initial values", connector_id: WAYAI_CONNECTOR, operation: "reset_state", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: true },
9232
+ { tool_native_id: "nt-010", tool_name: "set_state_path", tool_display_name: "Set State Path", tool_description: "Set a specific path within state object", connector_id: WAYAI_CONNECTOR, operation: "set_state_path", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: true },
9233
+ { tool_native_id: "nt-011", tool_name: "consult_agent", tool_display_name: "Consult Agent", tool_description: "Consult an advisor agent for advice without transferring", connector_id: WAYAI_CONNECTOR, operation: "consult_agent", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "keyed", hosted: false },
9234
+ { tool_native_id: "nt-013", tool_name: "read_skill", tool_display_name: "Read Skill", tool_description: "Read the full specification of a skill", connector_id: WAYAI_CONNECTOR, operation: "read_skill", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: false },
9235
+ { tool_native_id: "nt-014", tool_name: "read_skill_file", tool_display_name: "Read Skill File", tool_description: "Read a specific file within a skill", connector_id: WAYAI_CONNECTOR, operation: "read_skill_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: false },
9236
+ { tool_native_id: "nt-015", tool_name: "read_file", tool_display_name: "Read File", tool_description: "Read the contents of a resource file", connector_id: WAYAI_CONNECTOR, operation: "read_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: false },
9074
9237
  // Superseded by `list_files` (nt-027), which browses the same resource files
9075
9238
  // by PATH plus this conversation's attachments.
9076
9239
  //
@@ -9084,13 +9247,13 @@ var init_chunk_UZ7SPBM3 = __esm({
9084
9247
  // name, and `wayai pull` / `push` still round-trips the YAML. There is no
9085
9248
  // auto-provisioning anywhere in the platform, so an existing agent is never
9086
9249
  // migrated for free — an author swaps the tool deliberately.
9087
- { tool_native_id: "nt-016", tool_name: "list_resource_files", tool_display_name: "List Resource Files", tool_description: "(deprecated \u2014 use list_files) List files in a resource folder", connector_id: WAYAI_CONNECTOR, operation: "list_resource_files", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", ui_assignable: false },
9088
- { tool_native_id: "nt-017", tool_name: "list_resource_folders", tool_display_name: "List Resource Folders", tool_description: "(deprecated \u2014 use list_files) List all resource folders", connector_id: WAYAI_CONNECTOR, operation: "list_resource_folders", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", ui_assignable: false },
9089
- { tool_native_id: "nt-018", tool_name: "get_conversations_summary", tool_display_name: "Get Conversations Summary", tool_description: "Get a summary of recent conversations", connector_id: WAYAI_CONNECTOR, operation: "get_conversations_summary", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
9090
- { tool_native_id: "nt-019", tool_name: "get_conversation", tool_display_name: "Get Conversation", tool_description: "Retrieve full conversation history", connector_id: WAYAI_CONNECTOR, operation: "get_conversation", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
9091
- { tool_native_id: "nt-020", tool_name: "get_tool_schema", tool_display_name: "Get Tool Schema", tool_description: "Retrieve the JSON schema for a tool", connector_id: WAYAI_CONNECTOR, operation: "get_tool_schema", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
9092
- { tool_native_id: "nt-021", tool_name: "execute_tool", tool_display_name: "Execute Tool", tool_description: "Execute any available tool by name", connector_id: WAYAI_CONNECTOR, operation: "execute_tool", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "reconcile" },
9093
- { tool_native_id: "nt-022", tool_name: "expand_summary", tool_display_name: "Expand Summary", tool_description: "Retrieve the original messages of a section in the conversation summary", connector_id: WAYAI_CONNECTOR, operation: "expand_summary", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
9250
+ { tool_native_id: "nt-016", tool_name: "list_resource_files", tool_display_name: "List Resource Files", tool_description: "(deprecated \u2014 use list_files) List files in a resource folder", connector_id: WAYAI_CONNECTOR, operation: "list_resource_files", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: false, ui_assignable: false },
9251
+ { tool_native_id: "nt-017", tool_name: "list_resource_folders", tool_display_name: "List Resource Folders", tool_description: "(deprecated \u2014 use list_files) List all resource folders", connector_id: WAYAI_CONNECTOR, operation: "list_resource_folders", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: false, ui_assignable: false },
9252
+ { tool_native_id: "nt-018", tool_name: "get_conversations_summary", tool_display_name: "Get Conversations Summary", tool_description: "Get a summary of recent conversations", connector_id: WAYAI_CONNECTOR, operation: "get_conversations_summary", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: true },
9253
+ { tool_native_id: "nt-019", tool_name: "get_conversation", tool_display_name: "Get Conversation", tool_description: "Retrieve full conversation history", connector_id: WAYAI_CONNECTOR, operation: "get_conversation", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: true },
9254
+ { tool_native_id: "nt-020", tool_name: "get_tool_schema", tool_display_name: "Get Tool Schema", tool_description: "Retrieve the JSON schema for a tool", connector_id: WAYAI_CONNECTOR, operation: "get_tool_schema", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: false },
9255
+ { tool_native_id: "nt-021", tool_name: "execute_tool", tool_display_name: "Execute Tool", tool_description: "Execute any available tool by name", connector_id: WAYAI_CONNECTOR, operation: "execute_tool", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "reconcile", hosted: false },
9256
+ { tool_native_id: "nt-022", tool_name: "expand_summary", tool_display_name: "Expand Summary", tool_description: "Retrieve the original messages of a section in the conversation summary", connector_id: WAYAI_CONNECTOR, operation: "expand_summary", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: false },
9094
9257
  // Hub-as-agent delegation (consultant-agents H1.5). UN-GATED in PR 7 (H1.5b): the
9095
9258
  // spawn + cross-DO completion callback shipped, so the tool is live across the
9096
9259
  // catalog listing, CI push, the config snapshot, and the handler. (PR 6 shipped it
@@ -9103,7 +9266,7 @@ var init_chunk_UZ7SPBM3 = __esm({
9103
9266
  // delegation dialog, clicking Add would submit no delegation params and the write
9104
9267
  // path would reject it — a live button that only ever errors. Assign it via
9105
9268
  // `wayai push` until the picker + boundary control ship.
9106
- { tool_native_id: "nt-025", tool_name: "delegate_to_hub", tool_display_name: "Delegate to Hub", tool_description: "Delegate a request to another hub as a task, and receive the result asynchronously", connector_id: WAYAI_CONNECTOR, operation: "delegate_to_hub", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, side_effects: true, replay: "reconcile", ui_assignable: false },
9269
+ { tool_native_id: "nt-025", tool_name: "delegate_to_hub", tool_display_name: "Delegate to Hub", tool_description: "Delegate a request to another hub as a task, and receive the result asynchronously", connector_id: WAYAI_CONNECTOR, operation: "delegate_to_hub", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, side_effects: true, replay: "reconcile", hosted: false, ui_assignable: false },
9107
9270
  // Agent-initiated consults (consultant-agents H1.7b). A delegation tool like the
9108
9271
  // three above: the TARGET is admin configuration (`delegated_agent_id` for a
9109
9272
  // same-hub consultant, `delegated_hub_id` for a partner hub) and the model supplies
@@ -9115,13 +9278,13 @@ var init_chunk_UZ7SPBM3 = __esm({
9115
9278
  // collect (and, for a consultant target, the `allow_consultant_chain` opt-in). A
9116
9279
  // live button that only ever errors is worse than no button. Assign via `wayai push`
9117
9280
  // until the picker ships.
9118
- { tool_native_id: "nt-026", tool_name: "start_consult_thread", tool_display_name: "Start Consult Thread", tool_description: "Ask a configured consultant (or partner hub) a question in a visible consult thread", connector_id: WAYAI_CONNECTOR, operation: "start_consult_thread", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, side_effects: true, replay: "keyed", ui_assignable: false },
9281
+ { tool_native_id: "nt-026", tool_name: "start_consult_thread", tool_display_name: "Start Consult Thread", tool_description: "Ask a configured consultant (or partner hub) a question in a visible consult thread", connector_id: WAYAI_CONNECTOR, operation: "start_consult_thread", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, side_effects: true, replay: "keyed", hosted: false, ui_assignable: false },
9119
9282
  // One drill-down listing for every file namespace, replacing `list_resource_files`
9120
9283
  // (nt-016) and `list_resource_folders` (nt-017). Fully visible: it needs no
9121
9284
  // configuration the Add dialog cannot collect — the mounts an agent may browse
9122
9285
  // come from its existing resource links and its own conversation, and the only
9123
9286
  // model-supplied input is a path.
9124
- { tool_native_id: "nt-027", tool_name: "list_files", tool_display_name: "List Files", tool_description: "Browse the files this agent can reach, by path", connector_id: WAYAI_CONNECTOR, operation: "list_files", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
9287
+ { tool_native_id: "nt-027", tool_name: "list_files", tool_display_name: "List Files", tool_description: "Browse the files this agent can reach, by path", connector_id: WAYAI_CONNECTOR, operation: "list_files", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: false },
9125
9288
  // TWO gates, and BOTH are load-bearing — the first shipped alone and was not
9126
9289
  // enough. `assignable_roles: ['monitor']` says only a monitor may HOLD it,
9127
9290
  // because the tool has no meaning off a monitor: a rule SELECTS it and the note
@@ -9131,7 +9294,7 @@ var init_chunk_UZ7SPBM3 = __esm({
9131
9294
  // and a re-roled agent keeps the tools it holds. Offered and called, it reaches
9132
9295
  // the native dispatcher's `default:` branch: a Sentry event and a provider
9133
9296
  // re-call. See `NativeTool.model_callable`.
9134
- { tool_native_id: "nt-028", tool_name: "insert_note", tool_display_name: "Insert Note", tool_description: "Brief the answering agent with an admin-authored note before it replies", connector_id: WAYAI_CONNECTOR, operation: "insert_note", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", assignable_roles: ["monitor"], model_callable: false },
9297
+ { tool_native_id: "nt-028", tool_name: "insert_note", tool_display_name: "Insert Note", tool_description: "Brief the answering agent with an admin-authored note before it replies", connector_id: WAYAI_CONNECTOR, operation: "insert_note", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun", hosted: false, assignable_roles: ["monitor"], model_callable: false },
9135
9298
  // TWO gates, same pair and same reasons as `insert_note` above — this is the
9136
9299
  // second tool to need both, which is why they are catalog fields rather than a
9137
9300
  // check at one site. `assignable_roles: ['monitor']`: only a monitor may hold it,
@@ -9144,32 +9307,32 @@ var init_chunk_UZ7SPBM3 = __esm({
9144
9307
  // would need remapping on both branching mechanisms and normalizing on both CI
9145
9308
  // directions. `action.tool_name`, one key away in the same object, is the
9146
9309
  // precedent.
9147
- { tool_native_id: "nt-029", tool_name: "run_monitor", tool_display_name: "Run Monitor", tool_description: "Run another monitor on this hub and let it act on its own rules", connector_id: WAYAI_CONNECTOR, operation: "run_monitor", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: true, replay: "reconcile", assignable_roles: ["monitor"], model_callable: false },
9310
+ { tool_native_id: "nt-029", tool_name: "run_monitor", tool_display_name: "Run Monitor", tool_description: "Run another monitor on this hub and let it act on its own rules", connector_id: WAYAI_CONNECTOR, operation: "run_monitor", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: true, replay: "reconcile", hosted: false, assignable_roles: ["monitor"], model_callable: false },
9148
9311
  // The code sandbox (wayai#5083 Phase 3): runs only for an agent whose `code_execution_enabled`
9149
9312
  // setting is on, on any provider. Side effects: under an Allowlist or Web network setting, the
9150
9313
  // code it runs can send data out of the conversation.
9151
- { 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 },
9314
+ { 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", hosted: false, assignable_roles: SANDBOX_AGENT_ROLES },
9152
9315
  // Copies a conversation file, or a toolset document (`data/`, read through the toolset's `get`),
9153
9316
  // INTO the sandbox: the sandbox is conversation state, so nothing leaves the conversation. The
9154
9317
  // conversation's sandbox is shared by its agents whose `sandbox_scope` is `conversation`, so a
9155
9318
  // document copied in is there for each of them, as anything else an agent leaves in it; an agent
9156
9319
  // set to `agent` copies into its own, which no other agent reaches (decision 147).
9157
- { 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 },
9320
+ { 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", hosted: false, assignable_roles: SANDBOX_AGENT_ROLES },
9158
9321
  // Copies a sandbox file OUT into the conversation, as an internal note for the team: nothing
9159
9322
  // reaches the customer until `send_files` sends it. With `path`, it writes a toolset document
9160
9323
  // instead, through the toolset's `put` with its version check: such a call is `reconcile`, not
9161
9324
  // `keyed`, as `write_file` is (`toolCallReplay` reads its arguments). Its side effects stay `false`:
9162
9325
  // only an agent holding a toolset `put` can write one, never a customer-facing role (premise 8),
9163
9326
  // and a voice call's turns, which read this flag, run the pilot track, which is customer-facing.
9164
- { tool_native_id: "nt-032", tool_name: "copy_from_sandbox", tool_display_name: "Copy File from Sandbox", tool_description: "Copy a file out of the code sandbox into the conversation, for the team", connector_id: WAYAI_CONNECTOR, operation: "copy_from_sandbox", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "keyed", assignable_roles: SANDBOX_AGENT_ROLES },
9327
+ { tool_native_id: "nt-032", tool_name: "copy_from_sandbox", tool_display_name: "Copy File from Sandbox", tool_description: "Copy a file out of the code sandbox into the conversation, for the team", connector_id: WAYAI_CONNECTOR, operation: "copy_from_sandbox", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "keyed", hosted: false, assignable_roles: SANDBOX_AGENT_ROLES },
9165
9328
  // The `data/` mount's writes (#5142 step 2): a document of the agent's Base Toolset, written
9166
9329
  // through the toolset's own `put` tool with its version check. `reconcile`, not `keyed`: a re-run
9167
9330
  // after a first write that changed the file is refused by that check (its version, or the create's
9168
9331
  // path, is taken), so it never writes twice, but it answers a refusal where the first answered the
9169
9332
  // write, which is not the no-op `keyed` re-runs promise (owner decision 74). A first write of the
9170
9333
  // content the file already held kept its version, so its re-run is that same no-op.
9171
- { tool_native_id: "nt-033", tool_name: "write_file", tool_display_name: "Write File", tool_description: "Create or replace a Base Toolset document under data/, with a version check", connector_id: WAYAI_CONNECTOR, operation: "write_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: true, replay: "reconcile" },
9172
- { tool_native_id: "nt-034", tool_name: "edit_file", tool_display_name: "Edit File", tool_description: "Replace text in a Base Toolset document under data/, with a version check", connector_id: WAYAI_CONNECTOR, operation: "edit_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: true, replay: "reconcile" }
9334
+ { tool_native_id: "nt-033", tool_name: "write_file", tool_display_name: "Write File", tool_description: "Create or replace a Base Toolset document under data/, with a version check", connector_id: WAYAI_CONNECTOR, operation: "write_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: true, replay: "reconcile", hosted: false },
9335
+ { tool_native_id: "nt-034", tool_name: "edit_file", tool_display_name: "Edit File", tool_description: "Replace text in a Base Toolset document under data/, with a version check", connector_id: WAYAI_CONNECTOR, operation: "edit_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: true, replay: "reconcile", hosted: false }
9173
9336
  ];
9174
9337
  NATIVE_TOOLS = BASE_NATIVE_TOOLS.map((base) => {
9175
9338
  const schema = NATIVE_TOOL_SCHEMAS[base.tool_name];
@@ -9200,7 +9363,7 @@ var init_chunk_IBL7FANV = __esm({
9200
9363
  }
9201
9364
  });
9202
9365
 
9203
- // ../../packages/core/dist/chunk-PFDZEKDE.js
9366
+ // ../../packages/core/dist/chunk-Y3S4XX4K.js
9204
9367
  function parseExpr(expr) {
9205
9368
  const fnMatch = expr.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*\((.*?)\)\s*(?:\.(.*))?$/);
9206
9369
  if (!fnMatch) return null;
@@ -9284,8 +9447,8 @@ function scanTemplateResources(template) {
9284
9447
  return scan;
9285
9448
  }
9286
9449
  var PREVIOUS_CONVERSATIONS_MAX, PLACEHOLDER_RE, CATALOG_FN, LEGACY_CATALOG_FN, EMPTY_SCAN;
9287
- var init_chunk_PFDZEKDE = __esm({
9288
- "../../packages/core/dist/chunk-PFDZEKDE.js"() {
9450
+ var init_chunk_Y3S4XX4K = __esm({
9451
+ "../../packages/core/dist/chunk-Y3S4XX4K.js"() {
9289
9452
  "use strict";
9290
9453
  PREVIOUS_CONVERSATIONS_MAX = 20;
9291
9454
  PLACEHOLDER_RE = /\{\{\s*([^{}]+?)\s*\}\}/g;
@@ -9489,7 +9652,7 @@ var init_chunk_T7KQKDET = __esm({
9489
9652
  }
9490
9653
  });
9491
9654
 
9492
- // ../../packages/core/dist/chunk-XOGFONTQ.js
9655
+ // ../../packages/core/dist/chunk-DIBRGYL6.js
9493
9656
  function resolveMonitorTrigger(monitorConfig) {
9494
9657
  if (!monitorConfig || typeof monitorConfig !== "object") return "idle";
9495
9658
  const raw = monitorConfig.trigger;
@@ -9795,12 +9958,12 @@ function refineMonitorRulesStructuredOutput(body, ctx) {
9795
9958
  if (refusal2) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["response_format"], message: refusal2 });
9796
9959
  }
9797
9960
  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;
9798
- var init_chunk_XOGFONTQ = __esm({
9799
- "../../packages/core/dist/chunk-XOGFONTQ.js"() {
9961
+ var init_chunk_DIBRGYL6 = __esm({
9962
+ "../../packages/core/dist/chunk-DIBRGYL6.js"() {
9800
9963
  "use strict";
9801
- init_chunk_UZ7SPBM3();
9964
+ init_chunk_UFYIBL66();
9802
9965
  init_chunk_IBL7FANV();
9803
- init_chunk_PFDZEKDE();
9966
+ init_chunk_Y3S4XX4K();
9804
9967
  init_chunk_HZ6CADSY();
9805
9968
  init_chunk_C2UEA2KW();
9806
9969
  init_chunk_DHPUPI4Y();
@@ -10021,12 +10184,12 @@ var init_chunk_XOGFONTQ = __esm({
10021
10184
  }
10022
10185
  });
10023
10186
 
10024
- // ../../packages/core/dist/chunk-TUP5Y6ZB.js
10187
+ // ../../packages/core/dist/chunk-6GBBTCME.js
10025
10188
  var conversationIdParam, conversationHubQuery, claimBody, releaseBody, transferBody, closeBody, additionalContextPayloadSchema, kanbanUpdateBody, annotateConversationBody, observabilityParams, observabilityListParams, deleteUserConversationsBody, deleteUserConversationsResponse, sendMessageBody, listConversationsQuery, flagSourceSchema, getConversationsResponse, getConversationDetailParams, getConversationDetailQuery, getConversationDetailResponse, listWhatsAppTemplatesQuery, sendWhatsAppTemplateBody;
10026
- var init_chunk_TUP5Y6ZB = __esm({
10027
- "../../packages/core/dist/chunk-TUP5Y6ZB.js"() {
10189
+ var init_chunk_6GBBTCME = __esm({
10190
+ "../../packages/core/dist/chunk-6GBBTCME.js"() {
10028
10191
  "use strict";
10029
- init_chunk_XOGFONTQ();
10192
+ init_chunk_DIBRGYL6();
10030
10193
  init_chunk_HZ6CADSY();
10031
10194
  init_chunk_DHPUPI4Y();
10032
10195
  init_zod();
@@ -10323,98 +10486,115 @@ var init_chunk_KSTYTQ7I = __esm({
10323
10486
  }
10324
10487
  });
10325
10488
 
10326
- // ../../packages/core/dist/chunk-LKBSHANA.js
10327
- var DESKTOP_SHELL_VERSION_RE, DESKTOP_PLATFORMS, DESKTOP_FLAVORS, desktopShellInfoSchema, DESKTOP_PRESENCE_STATES, desktopPresenceSchema, desktopUpdateSchema, DESKTOP_SIGN_IN_URL_MAX_LENGTH, DESKTOP_APP_PATH_MAX_LENGTH, desktopAppPathSchema, DESKTOP_NOTIFICATION_KINDS, DESKTOP_NOTIFICATION_TITLE_MAX_LENGTH, DESKTOP_NOTIFICATION_BODY_MAX_LENGTH, notificationTitleSchema, notificationBodySchema, desktopNotificationSchema, DESKTOP_BADGE_MAX_COUNT, DESKTOP_BADGE_LABEL_MAX_LENGTH, desktopBadgeSchema, desktopNavigateSchema, desktopSettingsSchema, desktopSettingsChangeSchema, desktopBridgeArgsSchemas;
10328
- var init_chunk_LKBSHANA = __esm({
10329
- "../../packages/core/dist/chunk-LKBSHANA.js"() {
10489
+ // ../../packages/core/dist/chunk-7CYHPF35.js
10490
+ var appMessageSenderType, appMessageReceiverType, apiChannelMessage, apiChannelMessageBody, appMessageBody, appMessageResponse;
10491
+ var init_chunk_7CYHPF35 = __esm({
10492
+ "../../packages/core/dist/chunk-7CYHPF35.js"() {
10330
10493
  "use strict";
10494
+ init_chunk_HZ6CADSY();
10331
10495
  init_zod();
10332
- DESKTOP_SHELL_VERSION_RE = /^(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})(-[0-9A-Za-z.-]{1,32})?$/;
10333
- DESKTOP_PLATFORMS = ["darwin", "win32"];
10334
- DESKTOP_FLAVORS = ["production", "development"];
10335
- desktopShellInfoSchema = external_exports.object({
10336
- /** The shell's own release version, independent of the web deploy. */
10337
- shellVersion: external_exports.string().regex(DESKTOP_SHELL_VERSION_RE),
10338
- /** The Electron runtime the shell was built with. */
10339
- electronVersion: external_exports.string().regex(/^\d{1,4}\.\d{1,4}\.\d{1,4}(-[0-9A-Za-z.-]{1,32})?$/),
10340
- platform: external_exports.enum(DESKTOP_PLATFORMS),
10341
- /** CPU architecture as Node reports it (`arm64`, `x64`). */
10342
- arch: external_exports.string().regex(/^[a-z0-9_]{1,16}$/),
10343
- flavor: external_exports.enum(DESKTOP_FLAVORS),
10344
- /**
10345
- * Present, and true, when the shell runs from the Microsoft Store's package: the Store updates it,
10346
- * and Windows alone opens it at login (the package's startup task, which the person turns on in
10347
- * Windows' settings). An optional field, so no new `bridgeVersion`: an older page ignores it, and
10348
- * its absence is every other shell.
10349
- */
10350
- store: external_exports.literal(true).optional()
10351
- });
10352
- DESKTOP_PRESENCE_STATES = ["present", "away"];
10353
- desktopPresenceSchema = external_exports.object({
10354
- presence: external_exports.enum(DESKTOP_PRESENCE_STATES),
10355
- mainWindow: external_exports.object({
10356
- shown: external_exports.boolean(),
10357
- focused: external_exports.boolean()
10358
- })
10359
- });
10360
- desktopUpdateSchema = external_exports.object({
10361
- ready: external_exports.object({
10362
- version: external_exports.string().regex(DESKTOP_SHELL_VERSION_RE),
10363
- offerRestart: external_exports.boolean()
10364
- }).nullable()
10365
- });
10366
- DESKTOP_SIGN_IN_URL_MAX_LENGTH = 4096;
10367
- DESKTOP_APP_PATH_MAX_LENGTH = 512;
10368
- desktopAppPathSchema = external_exports.string().max(DESKTOP_APP_PATH_MAX_LENGTH).regex(/^\/(?![/\\])[^\s\\]*$/);
10369
- DESKTOP_NOTIFICATION_KINDS = ["handoff", "message", "summary"];
10370
- DESKTOP_NOTIFICATION_TITLE_MAX_LENGTH = 200;
10371
- DESKTOP_NOTIFICATION_BODY_MAX_LENGTH = 500;
10372
- notificationTitleSchema = external_exports.string().min(1).max(DESKTOP_NOTIFICATION_TITLE_MAX_LENGTH);
10373
- notificationBodySchema = external_exports.string().max(DESKTOP_NOTIFICATION_BODY_MAX_LENGTH);
10374
- desktopNotificationSchema = external_exports.object({
10375
- kind: external_exports.enum(DESKTOP_NOTIFICATION_KINDS),
10376
- title: notificationTitleSchema,
10377
- body: notificationBodySchema,
10378
- path: desktopAppPathSchema,
10379
- withoutPreview: external_exports.object({ title: notificationTitleSchema, body: notificationBodySchema }).optional()
10380
- });
10381
- DESKTOP_BADGE_MAX_COUNT = 1e6;
10382
- DESKTOP_BADGE_LABEL_MAX_LENGTH = 200;
10383
- desktopBadgeSchema = external_exports.object({
10384
- count: external_exports.number().int().min(0).max(DESKTOP_BADGE_MAX_COUNT),
10385
- label: external_exports.string().max(DESKTOP_BADGE_LABEL_MAX_LENGTH)
10496
+ appMessageSenderType = external_exports.enum(["user", "team"]);
10497
+ appMessageReceiverType = external_exports.enum(["user", "team", "agent", "assistant"]).transform((v) => v === "assistant" ? "agent" : v);
10498
+ apiChannelMessage = external_exports.object({
10499
+ text: clientOptionalString,
10500
+ attachments: external_exports.array(messageAttachment).max(MAX_ATTACHMENTS_PER_MESSAGE).nullish().transform((v) => v ?? void 0)
10501
+ }).refine((m) => m.text && m.text.length > 0 || m.attachments && m.attachments.length > 0, {
10502
+ message: "message must have text or at least one attachment"
10386
10503
  });
10387
- desktopNavigateSchema = external_exports.object({
10388
- path: desktopAppPathSchema
10504
+ apiChannelMessageBody = external_exports.object({
10505
+ // Correlation id (task hubs): new → new conversation, repeat → continue. min 1 so an
10506
+ // empty string can't masquerade as a ref. Mutually exclusive with conversation_id.
10507
+ external_ref: external_exports.string().min(1).max(256).optional(),
10508
+ // Continue a specific WayAI conversation (authorized against the hub/channel + owner).
10509
+ // UUID-validated here (unlike the app channel, whose client we control): allocation
10510
+ // only treats a UUID-shaped id as a provided conversation, so a malformed id would
10511
+ // otherwise skip the owner guard and silently MINT a new conversation instead of
10512
+ // rejecting. A format 400 is shape-only — not an existence oracle (a valid-but-unknown
10513
+ // UUID still collapses to the opaque authorization error downstream).
10514
+ conversation_id: external_exports.string().uuid().optional(),
10515
+ // On-behalf-of end-user identity. Absent → per-connection service principal (task-hub
10516
+ // only; chat hub rejects with 422 in the route).
10517
+ user: external_exports.object({
10518
+ id: external_exports.string().min(1),
10519
+ email: clientOptionalString,
10520
+ name: clientOptionalString
10521
+ }).optional(),
10522
+ message: apiChannelMessage,
10523
+ // Idempotency key: maps to channel_message_sid, deduped within one conversation
10524
+ // (ConversationDO.storeMessage). A retried POST resolves to the same conversation (a chat
10525
+ // hub's user, the external_ref, the conversation_id, or on a task hub with neither, this key
10526
+ // scoped by the sender), so it echoes the original message_id and skips billing / turn
10527
+ // dispatch. A failed store answers a retryable 503 only when this key is set; without it a
10528
+ // retry could store the message twice, so it answers 400.
10529
+ client_message_id: external_exports.string().min(1).max(256).optional()
10530
+ }).refine((b) => !(b.external_ref && b.conversation_id), {
10531
+ message: "provide external_ref or conversation_id, not both",
10532
+ path: ["external_ref"]
10389
10533
  });
10390
- desktopSettingsSchema = external_exports.object({
10391
- /** The app opens when the person logs in to the computer: the operating system's own login item. */
10392
- openAtLogin: external_exports.boolean(),
10393
- /** Closing the window keeps the app running in the tray (true), or quits it (false). */
10394
- closeToTray: external_exports.boolean(),
10395
- /** The shell shows notifications (true), or none (false). The badge is not a notification. */
10396
- notifications: external_exports.boolean(),
10397
- /**
10398
- * A customer message's notification shows the customer's name and words, where the platform
10399
- * allows them at all (`desktopShowsCustomerWords`: macOS); elsewhere the shell never shows them.
10400
- */
10401
- messagePreview: external_exports.boolean()
10534
+ appMessageBody = external_exports.object({
10535
+ // Message content — three historical aliases. All optional: an attachment-only
10536
+ // or voice-only message carries no text.
10537
+ content: clientOptionalString,
10538
+ message_text: clientOptionalString,
10539
+ message_body: clientOptionalString,
10540
+ // Conversation context. Ids are plain strings rather than `.uuid()` on purpose:
10541
+ // they are AUTHORIZED downstream, which is the stronger guarantee — a well-formed
10542
+ // uuid belonging to another tenant must fail just as hard as junk. `hub_id` is
10543
+ // gated by `assertHubEndUserAccess` (gh #3286) and `conversation_id` by HubDO's
10544
+ // conversation_index owner check (gh #2781, #3281). The route's own falsy guards
10545
+ // ('hub_id is required') still reject an empty one.
10546
+ hub_id: clientOptionalString,
10547
+ channel_id: clientOptionalString,
10548
+ conversation_id: clientOptionalString,
10549
+ hub_type: external_exports.enum(["chat", "task"]).nullish().transform((v) => v ?? void 0),
10550
+ // Stable idempotency key for one explicit task-hub launcher. HubDO scopes it
10551
+ // to the authenticated user and resolves retries/tabs to one conversation.
10552
+ task_start_id: external_exports.string().uuid().nullish().transform((v) => v ?? void 0),
10553
+ // Routing.
10554
+ sender_type: appMessageSenderType.nullish().transform((v) => v ?? void 0),
10555
+ receiver_type: appMessageReceiverType.nullish().transform((v) => v ?? void 0),
10556
+ // Only meaningful on a team send, where `validateAppTeamSendContext` proves the
10557
+ // caller may send to this receiver. Absent on a team send to a conversation with no
10558
+ // person, which names its `conversation_id` instead. The end-user branch ignores it —
10559
+ // see the receiver derivation in the route.
10560
+ user_receiver_id: clientOptionalString,
10561
+ // ── Internal consult (consultant-agents PR 2 — H1.0) ──────────────────────
10562
+ // A team member handling a customer conversation can tag a `consultant`-role
10563
+ // agent for a PRIVATE, team-only exchange that never reaches the customer. A
10564
+ // consult send is a team send with `receiver_type: 'agent'` targeting the
10565
+ // consultant; `user_receiver_id` identifies the customer whose conversation this is
10566
+ // (and is authorized by `validateAppTeamSendContext`, exactly as a team→user send is),
10567
+ // and is absent, as on a team→user send, when the conversation has no person. The consultant is resolved from `agent_receiver_id`
10568
+ // when supplied, else from an `@mention` parsed out of the message text against
10569
+ // the hub's consultant agents. `consult_thread_id` continues an existing thread;
10570
+ // absent, the route creates/reuses the single implicit thread. These fields are
10571
+ // inert on every non-consult send (end-user send, team→user send).
10572
+ agent_receiver_id: clientOptionalString,
10573
+ consult_thread_id: clientOptionalString,
10574
+ is_first_message: clientOptionalBoolean,
10575
+ end_conversation: clientOptionalBoolean,
10576
+ // Pre-generated by the client so the optimistic bubble and the stored row share
10577
+ // a key (transcription live-updates land on the same row instead of duplicating).
10578
+ message_id: clientOptionalString,
10579
+ attachments: external_exports.array(messageAttachment).max(MAX_ATTACHMENTS_PER_MESSAGE).nullish().transform((v) => v ?? void 0),
10580
+ // Base64-encoded audio for STT. Size-capped in the route (the cap is a byte
10581
+ // budget tied to the /channels/* bodyLimit, not a shape rule).
10582
+ audio_file: clientOptionalString
10402
10583
  });
10403
- desktopSettingsChangeSchema = desktopSettingsSchema.partial().strict().refine((change) => Object.values(change).every((value) => typeof value === "boolean"), {
10404
- message: "each setting changed is true or false"
10584
+ appMessageResponse = external_exports.object({
10585
+ success: external_exports.boolean(),
10586
+ message: external_exports.string(),
10587
+ result: external_exports.object({
10588
+ conversation_id: external_exports.string().optional(),
10589
+ message_id: external_exports.string().optional(),
10590
+ status: external_exports.string().optional(),
10591
+ files: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown())).optional(),
10592
+ // True when this request reused a task-start/message id already accepted by
10593
+ // the server. Clients must replace their optimistic payload with a fresh
10594
+ // authoritative read because another tab may have won with different text.
10595
+ deduped: external_exports.boolean().optional()
10596
+ }).optional()
10405
10597
  });
10406
- desktopBridgeArgsSchemas = {
10407
- getShellInfo: external_exports.tuple([]),
10408
- getPresence: external_exports.tuple([]),
10409
- openSignIn: external_exports.tuple([external_exports.string().max(DESKTOP_SIGN_IN_URL_MAX_LENGTH)]),
10410
- getUpdate: external_exports.tuple([]),
10411
- restartToUpdate: external_exports.tuple([]),
10412
- notify: external_exports.tuple([desktopNotificationSchema]),
10413
- setBadge: external_exports.tuple([desktopBadgeSchema]),
10414
- clearAll: external_exports.tuple([]),
10415
- getSettings: external_exports.tuple([]),
10416
- setSettings: external_exports.tuple([desktopSettingsChangeSchema])
10417
- };
10418
10598
  }
10419
10599
  });
10420
10600
 
@@ -10482,7 +10662,7 @@ var init_chunk_BPCNB5RT = __esm({
10482
10662
  }
10483
10663
  });
10484
10664
 
10485
- // ../../packages/core/dist/chunk-LQSENJ26.js
10665
+ // ../../packages/core/dist/chunk-MCSEEMGN.js
10486
10666
  function idempotencyHeaderRefusal(value) {
10487
10667
  if (typeof value !== "string" || !/^[A-Za-z0-9][A-Za-z0-9-]{0,63}$/.test(value)) {
10488
10668
  return "idempotency_header must be a header name: letters, digits and dashes, at most 64";
@@ -10493,10 +10673,10 @@ function idempotencyHeaderRefusal(value) {
10493
10673
  return null;
10494
10674
  }
10495
10675
  var CATALOG_REPLAY, REPLAY_OVERRIDES, RESERVED_HEADERS;
10496
- var init_chunk_LQSENJ26 = __esm({
10497
- "../../packages/core/dist/chunk-LQSENJ26.js"() {
10676
+ var init_chunk_MCSEEMGN = __esm({
10677
+ "../../packages/core/dist/chunk-MCSEEMGN.js"() {
10498
10678
  "use strict";
10499
- init_chunk_UZ7SPBM3();
10679
+ init_chunk_UFYIBL66();
10500
10680
  CATALOG_REPLAY = new Map(
10501
10681
  NATIVE_TOOLS.map((tool) => [tool.tool_name, tool.replay])
10502
10682
  );
@@ -10729,7 +10909,7 @@ var init_chunk_WEXVYJ5H = __esm({
10729
10909
  }
10730
10910
  });
10731
10911
 
10732
- // ../../packages/core/dist/chunk-KRGVB7U6.js
10912
+ // ../../packages/core/dist/chunk-4S4FBSBE.js
10733
10913
  function refineToolConfig(value, ctx) {
10734
10914
  const raw = value.tool_config;
10735
10915
  if (raw == null) return;
@@ -10765,10 +10945,10 @@ function refineToolConfig(value, ctx) {
10765
10945
  }
10766
10946
  }
10767
10947
  var toolIdParam, listToolsQuery, toolAgentQuery, deleteToolQuery, toolConnectionsQuery, nativeToolIdSchema, CONTEXT_BOUNDARIES, contextBoundarySchema, addNativeToolBody, addMcpToolBody, toolReplaySettingsFields, toolReplaySettingsSchema, createCustomToolBody, updateCustomToolBody, updateToolExecutionConfigBody;
10768
- var init_chunk_KRGVB7U6 = __esm({
10769
- "../../packages/core/dist/chunk-KRGVB7U6.js"() {
10948
+ var init_chunk_4S4FBSBE = __esm({
10949
+ "../../packages/core/dist/chunk-4S4FBSBE.js"() {
10770
10950
  "use strict";
10771
- init_chunk_LQSENJ26();
10951
+ init_chunk_MCSEEMGN();
10772
10952
  init_chunk_WEXVYJ5H();
10773
10953
  init_chunk_HZ6CADSY();
10774
10954
  init_zod();
@@ -10839,7 +11019,7 @@ var init_chunk_4LXDRTO4 = __esm({
10839
11019
  }
10840
11020
  });
10841
11021
 
10842
- // ../../packages/core/dist/chunk-LZDVDC2S.js
11022
+ // ../../packages/core/dist/chunk-C5MU3WEM.js
10843
11023
  function isIanaTimezone(timezone) {
10844
11024
  try {
10845
11025
  new Intl.DateTimeFormat("en-US", { timeZone: timezone }).format(0);
@@ -10849,10 +11029,10 @@ function isIanaTimezone(timezone) {
10849
11029
  }
10850
11030
  }
10851
11031
  var evalDateContextSchema;
10852
- var init_chunk_LZDVDC2S = __esm({
10853
- "../../packages/core/dist/chunk-LZDVDC2S.js"() {
11032
+ var init_chunk_C5MU3WEM = __esm({
11033
+ "../../packages/core/dist/chunk-C5MU3WEM.js"() {
10854
11034
  "use strict";
10855
- init_chunk_PFDZEKDE();
11035
+ init_chunk_Y3S4XX4K();
10856
11036
  init_chunk_HZ6CADSY();
10857
11037
  init_chunk_MIWZOSPI();
10858
11038
  init_chunk_DHPUPI4Y();
@@ -10879,7 +11059,7 @@ var init_chunk_2ISUBJG7 = __esm({
10879
11059
  }
10880
11060
  });
10881
11061
 
10882
- // ../../packages/core/dist/chunk-623SRYWZ.js
11062
+ // ../../packages/core/dist/chunk-6UKJ6EMZ.js
10883
11063
  function describeRole(role) {
10884
11064
  if (typeof role === "string") {
10885
11065
  return JSON.stringify(role.length > ROLE_ECHO_MAX ? `${role.slice(0, ROLE_ECHO_MAX)}\u2026` : role);
@@ -11053,11 +11233,11 @@ function terminalRunCount(counts) {
11053
11233
  return counts.successful_runs + counts.failed_runs;
11054
11234
  }
11055
11235
  var evalIdParam, sessionIdParam, scenarioSetIdParam, hubIdQuery, EVAL_FIXTURE_NAME_MAX_LENGTH, evalFixtureOverrideSchema, runSessionQuery, runJourneyQuery, EVAL_INPUT_ROLES, EVAL_INPUT_ROLE_LIST, ROLE_ECHO_MAX, EVAL_INITIAL_STATE_SCOPES, MAX_INITIAL_STATE_ENTRIES, evalInitialStateEntry, evalCustomerContactIdSchema, evalBody, EVAL_LIST_MAX_LIMIT, evalListLimit, getEvalsQuery, toggleEvalBody, bulkToggleEvalsBody, pacingConfigSchema, EVAL_MAX_SELECTED_SCENARIOS, evalScenarioSelectionEntrySchema, evalScenarioSelectionSchema, sessionConfigSchema, createSessionBody, getSessionsQuery, getSessionResultsQuery, getSessionRunsQuery, evalAnalyticsQuery, getSessionCostQuery, compareSessionsQuery, evalsSqlBody, evalsSqlSchemaQuery, exportResultsQuery, validateEvalBody, hubAgentsQuery, createScenarioSetBody, updateScenarioSetBody, scenarioSetsHubQuery, createScenarioFromConversationBody, createJourneyFromConversationBody, evalAttachmentRef, turnMayCarryAttachments, ATTACHMENTS_USER_ONLY_MESSAGE, journeyIdParam, journeyToolCallSchema, journeyTurnSchema, journeyStepOverrideSchema, fixtureField, createJourneyBody, updateJourneyBody, evalSessionConfigResponseSchema, evalSessionResponseSchema, evalSessionListConfigSchema, evalSessionListItemSchema, seedReleaseStatusSchema, EVAL_SESSION_NOT_QUIESCENT;
11056
- var init_chunk_623SRYWZ = __esm({
11057
- "../../packages/core/dist/chunk-623SRYWZ.js"() {
11236
+ var init_chunk_6UKJ6EMZ = __esm({
11237
+ "../../packages/core/dist/chunk-6UKJ6EMZ.js"() {
11058
11238
  "use strict";
11059
11239
  init_chunk_4LXDRTO4();
11060
- init_chunk_LZDVDC2S();
11240
+ init_chunk_C5MU3WEM();
11061
11241
  init_chunk_HZ6CADSY();
11062
11242
  init_chunk_2ISUBJG7();
11063
11243
  init_zod();
@@ -12140,7 +12320,7 @@ var init_chunk_6NI5RAM4 = __esm({
12140
12320
  }
12141
12321
  });
12142
12322
 
12143
- // ../../packages/core/dist/chunk-RT35VFUY.js
12323
+ // ../../packages/core/dist/chunk-SCZ3GSJE.js
12144
12324
  function refineHubAsCodeCustomTools(config, ctx) {
12145
12325
  const agents = config.agents;
12146
12326
  if (!Array.isArray(agents)) return;
@@ -12676,12 +12856,12 @@ function refineHubAsCodeMonitorRulesOutput(config, ctx) {
12676
12856
  });
12677
12857
  }
12678
12858
  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;
12679
- var init_chunk_RT35VFUY = __esm({
12680
- "../../packages/core/dist/chunk-RT35VFUY.js"() {
12859
+ var init_chunk_SCZ3GSJE = __esm({
12860
+ "../../packages/core/dist/chunk-SCZ3GSJE.js"() {
12681
12861
  "use strict";
12682
- init_chunk_KRGVB7U6();
12683
- init_chunk_623SRYWZ();
12684
- init_chunk_XOGFONTQ();
12862
+ init_chunk_4S4FBSBE();
12863
+ init_chunk_6UKJ6EMZ();
12864
+ init_chunk_DIBRGYL6();
12685
12865
  init_chunk_LBDH7LCG();
12686
12866
  init_chunk_4LXDRTO4();
12687
12867
  init_chunk_T4Q5COKJ();
@@ -12734,8 +12914,9 @@ var init_chunk_RT35VFUY = __esm({
12734
12914
  hubAsCodeResourceSchema = external_exports.object({
12735
12915
  id: external_exports.string().min(1).optional(),
12736
12916
  name: external_exports.string().min(1),
12917
+ // Omitted: a new resource is a skill, an existing one keeps its type. A push refuses a new
12918
+ // knowledge resource and a change to knowledge (wayai-pro/wayai#5142 step 5).
12737
12919
  type: external_exports.enum(["knowledge", "skill"]).optional(),
12738
- // 'knowledge' (default) | 'skill'
12739
12920
  description: external_exports.string().optional(),
12740
12921
  enabled: external_exports.boolean().optional(),
12741
12922
  // No `user_browsable`: the field is retired (wayai#4710). This schema is `.passthrough()`,
@@ -13522,58 +13703,29 @@ var init_chunk_YULHXJ5M = __esm({
13522
13703
  }
13523
13704
  });
13524
13705
 
13525
- // ../../packages/core/dist/chunk-V4FRPRH5.js
13526
- var CONSULT_THREAD_STATUSES, consultThreadStatus, CONSULT_THREAD_TITLE_MAX, consultThreadTitle, consultThreadSummary, listConsultThreadsQuery, listConsultThreadsResponse, createConsultThreadBody, createConsultThreadResponse, consultThreadIdParam, updateConsultThreadBody, updateConsultThreadResponse, CONSULT_AWAIT_TIMEOUT_MS;
13527
- var init_chunk_V4FRPRH5 = __esm({
13528
- "../../packages/core/dist/chunk-V4FRPRH5.js"() {
13706
+ // ../../packages/core/dist/chunk-UEJOG2Q7.js
13707
+ var archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams;
13708
+ var init_chunk_UEJOG2Q7 = __esm({
13709
+ "../../packages/core/dist/chunk-UEJOG2Q7.js"() {
13529
13710
  "use strict";
13530
13711
  init_zod();
13531
- CONSULT_THREAD_STATUSES = ["open", "awaiting", "resolved", "cancelled_at_close"];
13532
- consultThreadStatus = external_exports.enum(CONSULT_THREAD_STATUSES);
13533
- CONSULT_THREAD_TITLE_MAX = 120;
13534
- consultThreadTitle = external_exports.string().trim().min(1).max(CONSULT_THREAD_TITLE_MAX);
13535
- consultThreadSummary = external_exports.object({
13536
- consult_thread_id: external_exports.string(),
13537
- conversation_id: external_exports.string(),
13538
- initiator_type: external_exports.enum(["team", "agent"]),
13539
- initiator_id: external_exports.string(),
13540
- engaged_agent_id: external_exports.string().nullable(),
13541
- engaged_agent_name: external_exports.string().nullable(),
13542
- title: external_exports.string().nullable(),
13543
- status: consultThreadStatus,
13544
- created_at: external_exports.string()
13545
- });
13546
- listConsultThreadsQuery = external_exports.object({
13547
- hub_id: external_exports.string().uuid()
13548
- });
13549
- listConsultThreadsResponse = external_exports.object({
13550
- threads: external_exports.array(consultThreadSummary)
13551
- });
13552
- createConsultThreadBody = external_exports.object({
13553
- hub_id: external_exports.string().uuid(),
13554
- title: consultThreadTitle.optional(),
13555
- // Optionally engage a consultant on creation. Validated server-side against the
13556
- // hub's `consultant`-role agents; a non-consultant / unknown id is rejected.
13557
- engaged_agent_id: external_exports.string().uuid().optional()
13558
- });
13559
- createConsultThreadResponse = external_exports.object({
13560
- thread: consultThreadSummary
13712
+ archiveHubIdParam = external_exports.object({
13713
+ hubId: external_exports.string().uuid()
13561
13714
  });
13562
- consultThreadIdParam = external_exports.object({
13563
- id: external_exports.string().uuid(),
13564
- threadId: external_exports.string().uuid()
13715
+ archiveConversationParams = external_exports.object({
13716
+ hubId: external_exports.string().uuid(),
13717
+ conversationId: external_exports.string().uuid()
13565
13718
  });
13566
- updateConsultThreadBody = external_exports.object({
13567
- hub_id: external_exports.string().uuid(),
13568
- title: consultThreadTitle.optional(),
13569
- engaged_agent_id: external_exports.string().uuid().optional()
13570
- }).refine((v) => v.title !== void 0 || v.engaged_agent_id !== void 0, {
13571
- message: "Provide a title and/or an engaged_agent_id to update"
13719
+ archiveListQuery = external_exports.object({
13720
+ user_id: external_exports.string().optional(),
13721
+ start: external_exports.string().optional(),
13722
+ end: external_exports.string().optional(),
13723
+ page: external_exports.string().regex(/^\d+$/).optional(),
13724
+ page_size: external_exports.string().regex(/^\d+$/).optional()
13572
13725
  });
13573
- updateConsultThreadResponse = external_exports.object({
13574
- thread: consultThreadSummary
13726
+ archiveMessageObservabilityParams = archiveConversationParams.extend({
13727
+ messageId: external_exports.string().uuid()
13575
13728
  });
13576
- CONSULT_AWAIT_TIMEOUT_MS = 15 * 6e4;
13577
13729
  }
13578
13730
  });
13579
13731
 
@@ -13690,13 +13842,13 @@ var init_chunk_LQY2OCQL = __esm({
13690
13842
  }
13691
13843
  });
13692
13844
 
13693
- // ../../packages/core/dist/chunk-2VTDOH67.js
13845
+ // ../../packages/core/dist/chunk-EHPGISOL.js
13694
13846
  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;
13695
- var init_chunk_2VTDOH67 = __esm({
13696
- "../../packages/core/dist/chunk-2VTDOH67.js"() {
13847
+ var init_chunk_EHPGISOL = __esm({
13848
+ "../../packages/core/dist/chunk-EHPGISOL.js"() {
13697
13849
  "use strict";
13698
13850
  init_chunk_LQY2OCQL();
13699
- init_chunk_XOGFONTQ();
13851
+ init_chunk_DIBRGYL6();
13700
13852
  init_chunk_3HSB6J4J();
13701
13853
  init_chunk_5XEJSR22();
13702
13854
  init_chunk_DHPUPI4Y();
@@ -13947,118 +14099,6 @@ var init_chunk_ZJJ5ODOD = __esm({
13947
14099
  }
13948
14100
  });
13949
14101
 
13950
- // ../../packages/core/dist/chunk-7CYHPF35.js
13951
- var appMessageSenderType, appMessageReceiverType, apiChannelMessage, apiChannelMessageBody, appMessageBody, appMessageResponse;
13952
- var init_chunk_7CYHPF35 = __esm({
13953
- "../../packages/core/dist/chunk-7CYHPF35.js"() {
13954
- "use strict";
13955
- init_chunk_HZ6CADSY();
13956
- init_zod();
13957
- appMessageSenderType = external_exports.enum(["user", "team"]);
13958
- appMessageReceiverType = external_exports.enum(["user", "team", "agent", "assistant"]).transform((v) => v === "assistant" ? "agent" : v);
13959
- apiChannelMessage = external_exports.object({
13960
- text: clientOptionalString,
13961
- attachments: external_exports.array(messageAttachment).max(MAX_ATTACHMENTS_PER_MESSAGE).nullish().transform((v) => v ?? void 0)
13962
- }).refine((m) => m.text && m.text.length > 0 || m.attachments && m.attachments.length > 0, {
13963
- message: "message must have text or at least one attachment"
13964
- });
13965
- apiChannelMessageBody = external_exports.object({
13966
- // Correlation id (task hubs): new → new conversation, repeat → continue. min 1 so an
13967
- // empty string can't masquerade as a ref. Mutually exclusive with conversation_id.
13968
- external_ref: external_exports.string().min(1).max(256).optional(),
13969
- // Continue a specific WayAI conversation (authorized against the hub/channel + owner).
13970
- // UUID-validated here (unlike the app channel, whose client we control): allocation
13971
- // only treats a UUID-shaped id as a provided conversation, so a malformed id would
13972
- // otherwise skip the owner guard and silently MINT a new conversation instead of
13973
- // rejecting. A format 400 is shape-only — not an existence oracle (a valid-but-unknown
13974
- // UUID still collapses to the opaque authorization error downstream).
13975
- conversation_id: external_exports.string().uuid().optional(),
13976
- // On-behalf-of end-user identity. Absent → per-connection service principal (task-hub
13977
- // only; chat hub rejects with 422 in the route).
13978
- user: external_exports.object({
13979
- id: external_exports.string().min(1),
13980
- email: clientOptionalString,
13981
- name: clientOptionalString
13982
- }).optional(),
13983
- message: apiChannelMessage,
13984
- // Idempotency key: maps to channel_message_sid, deduped within one conversation
13985
- // (ConversationDO.storeMessage). A retried POST resolves to the same conversation (a chat
13986
- // hub's user, the external_ref, the conversation_id, or on a task hub with neither, this key
13987
- // scoped by the sender), so it echoes the original message_id and skips billing / turn
13988
- // dispatch. A failed store answers a retryable 503 only when this key is set; without it a
13989
- // retry could store the message twice, so it answers 400.
13990
- client_message_id: external_exports.string().min(1).max(256).optional()
13991
- }).refine((b) => !(b.external_ref && b.conversation_id), {
13992
- message: "provide external_ref or conversation_id, not both",
13993
- path: ["external_ref"]
13994
- });
13995
- appMessageBody = external_exports.object({
13996
- // Message content — three historical aliases. All optional: an attachment-only
13997
- // or voice-only message carries no text.
13998
- content: clientOptionalString,
13999
- message_text: clientOptionalString,
14000
- message_body: clientOptionalString,
14001
- // Conversation context. Ids are plain strings rather than `.uuid()` on purpose:
14002
- // they are AUTHORIZED downstream, which is the stronger guarantee — a well-formed
14003
- // uuid belonging to another tenant must fail just as hard as junk. `hub_id` is
14004
- // gated by `assertHubEndUserAccess` (gh #3286) and `conversation_id` by HubDO's
14005
- // conversation_index owner check (gh #2781, #3281). The route's own falsy guards
14006
- // ('hub_id is required') still reject an empty one.
14007
- hub_id: clientOptionalString,
14008
- channel_id: clientOptionalString,
14009
- conversation_id: clientOptionalString,
14010
- hub_type: external_exports.enum(["chat", "task"]).nullish().transform((v) => v ?? void 0),
14011
- // Stable idempotency key for one explicit task-hub launcher. HubDO scopes it
14012
- // to the authenticated user and resolves retries/tabs to one conversation.
14013
- task_start_id: external_exports.string().uuid().nullish().transform((v) => v ?? void 0),
14014
- // Routing.
14015
- sender_type: appMessageSenderType.nullish().transform((v) => v ?? void 0),
14016
- receiver_type: appMessageReceiverType.nullish().transform((v) => v ?? void 0),
14017
- // Only meaningful on a team send, where `validateAppTeamSendContext` proves the
14018
- // caller may send to this receiver. Absent on a team send to a conversation with no
14019
- // person, which names its `conversation_id` instead. The end-user branch ignores it —
14020
- // see the receiver derivation in the route.
14021
- user_receiver_id: clientOptionalString,
14022
- // ── Internal consult (consultant-agents PR 2 — H1.0) ──────────────────────
14023
- // A team member handling a customer conversation can tag a `consultant`-role
14024
- // agent for a PRIVATE, team-only exchange that never reaches the customer. A
14025
- // consult send is a team send with `receiver_type: 'agent'` targeting the
14026
- // consultant; `user_receiver_id` identifies the customer whose conversation this is
14027
- // (and is authorized by `validateAppTeamSendContext`, exactly as a team→user send is),
14028
- // and is absent, as on a team→user send, when the conversation has no person. The consultant is resolved from `agent_receiver_id`
14029
- // when supplied, else from an `@mention` parsed out of the message text against
14030
- // the hub's consultant agents. `consult_thread_id` continues an existing thread;
14031
- // absent, the route creates/reuses the single implicit thread. These fields are
14032
- // inert on every non-consult send (end-user send, team→user send).
14033
- agent_receiver_id: clientOptionalString,
14034
- consult_thread_id: clientOptionalString,
14035
- is_first_message: clientOptionalBoolean,
14036
- end_conversation: clientOptionalBoolean,
14037
- // Pre-generated by the client so the optimistic bubble and the stored row share
14038
- // a key (transcription live-updates land on the same row instead of duplicating).
14039
- message_id: clientOptionalString,
14040
- attachments: external_exports.array(messageAttachment).max(MAX_ATTACHMENTS_PER_MESSAGE).nullish().transform((v) => v ?? void 0),
14041
- // Base64-encoded audio for STT. Size-capped in the route (the cap is a byte
14042
- // budget tied to the /channels/* bodyLimit, not a shape rule).
14043
- audio_file: clientOptionalString
14044
- });
14045
- appMessageResponse = external_exports.object({
14046
- success: external_exports.boolean(),
14047
- message: external_exports.string(),
14048
- result: external_exports.object({
14049
- conversation_id: external_exports.string().optional(),
14050
- message_id: external_exports.string().optional(),
14051
- status: external_exports.string().optional(),
14052
- files: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown())).optional(),
14053
- // True when this request reused a task-start/message id already accepted by
14054
- // the server. Clients must replace their optimistic payload with a fresh
14055
- // authoritative read because another tab may have won with different text.
14056
- deduped: external_exports.boolean().optional()
14057
- }).optional()
14058
- });
14059
- }
14060
- });
14061
-
14062
14102
  // ../../packages/core/dist/chunk-NVKU5PPQ.js
14063
14103
  var ADMIN_SKILL_NAME_REGEX, adminSkillNameParam;
14064
14104
  var init_chunk_NVKU5PPQ = __esm({
@@ -14701,32 +14741,6 @@ var init_chunk_2PZIF56U = __esm({
14701
14741
  }
14702
14742
  });
14703
14743
 
14704
- // ../../packages/core/dist/chunk-UEJOG2Q7.js
14705
- var archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams;
14706
- var init_chunk_UEJOG2Q7 = __esm({
14707
- "../../packages/core/dist/chunk-UEJOG2Q7.js"() {
14708
- "use strict";
14709
- init_zod();
14710
- archiveHubIdParam = external_exports.object({
14711
- hubId: external_exports.string().uuid()
14712
- });
14713
- archiveConversationParams = external_exports.object({
14714
- hubId: external_exports.string().uuid(),
14715
- conversationId: external_exports.string().uuid()
14716
- });
14717
- archiveListQuery = external_exports.object({
14718
- user_id: external_exports.string().optional(),
14719
- start: external_exports.string().optional(),
14720
- end: external_exports.string().optional(),
14721
- page: external_exports.string().regex(/^\d+$/).optional(),
14722
- page_size: external_exports.string().regex(/^\d+$/).optional()
14723
- });
14724
- archiveMessageObservabilityParams = archiveConversationParams.extend({
14725
- messageId: external_exports.string().uuid()
14726
- });
14727
- }
14728
- });
14729
-
14730
14744
  // ../../packages/core/dist/chunk-SOJMWM63.js
14731
14745
  var init_chunk_SOJMWM63 = __esm({
14732
14746
  "../../packages/core/dist/chunk-SOJMWM63.js"() {
@@ -14942,13 +14956,14 @@ var init_contracts = __esm({
14942
14956
  "../../packages/core/dist/contracts/index.js"() {
14943
14957
  "use strict";
14944
14958
  init_chunk_SXDX4GHS();
14945
- init_chunk_FK6HBXM7();
14959
+ init_chunk_HENF6YTF();
14946
14960
  init_chunk_VXEAR36B();
14947
- init_chunk_TIZ57ZBA();
14961
+ init_chunk_DYI3BRJ3();
14948
14962
  init_chunk_Q7KIQHAZ();
14949
14963
  init_chunk_WBFLPPDI();
14950
14964
  init_chunk_IPXBFWUU();
14951
14965
  init_chunk_GK27ENTT();
14966
+ init_chunk_IPDOHAZ5();
14952
14967
  init_chunk_GPM7PE44();
14953
14968
  init_chunk_DGKMMFIR();
14954
14969
  init_chunk_ZC6YGHNX();
@@ -14956,40 +14971,41 @@ var init_contracts = __esm({
14956
14971
  init_chunk_ZXK6N2HN();
14957
14972
  init_chunk_Y7CFCYX4();
14958
14973
  init_chunk_5DGHIY7L();
14959
- init_chunk_FNNHGL7K();
14974
+ init_chunk_4QBKRQMM();
14960
14975
  init_chunk_4MRBBR5L();
14961
14976
  init_chunk_BEOHBREG();
14962
- init_chunk_IPDOHAZ5();
14977
+ init_chunk_SY6PLCPK();
14963
14978
  init_chunk_YUZFHVB2();
14964
14979
  init_chunk_I3O2RACG();
14965
14980
  init_chunk_34LE6P7E();
14966
14981
  init_chunk_FPSDNS2E();
14967
- init_chunk_QZZ3OHLV();
14982
+ init_chunk_LKBSHANA();
14983
+ init_chunk_23ESQLLF();
14968
14984
  init_chunk_C4HEZ7ZI();
14969
14985
  init_chunk_IR2NOSI3();
14970
14986
  init_chunk_EA23LSDS();
14971
- init_chunk_SY6PLCPK();
14987
+ init_chunk_V4FRPRH5();
14972
14988
  init_chunk_LWMLR2WI();
14973
14989
  init_chunk_ACGAI25T();
14974
14990
  init_chunk_MH4O3YEX();
14975
- init_chunk_TUP5Y6ZB();
14991
+ init_chunk_6GBBTCME();
14976
14992
  init_chunk_KSTYTQ7I();
14977
- init_chunk_LKBSHANA();
14993
+ init_chunk_7CYHPF35();
14978
14994
  init_chunk_BPCNB5RT();
14979
- init_chunk_RT35VFUY();
14980
- init_chunk_KRGVB7U6();
14981
- init_chunk_623SRYWZ();
14995
+ init_chunk_SCZ3GSJE();
14996
+ init_chunk_4S4FBSBE();
14997
+ init_chunk_6UKJ6EMZ();
14982
14998
  init_chunk_JDJ4EUOL();
14983
14999
  init_chunk_3KYTITOR();
14984
15000
  init_chunk_XCDUP42J();
14985
15001
  init_chunk_6J742GLA();
14986
15002
  init_chunk_ZVXO3XL6();
14987
15003
  init_chunk_YULHXJ5M();
14988
- init_chunk_V4FRPRH5();
15004
+ init_chunk_UEJOG2Q7();
14989
15005
  init_chunk_ZHJEQBXJ();
14990
- init_chunk_2VTDOH67();
15006
+ init_chunk_EHPGISOL();
14991
15007
  init_chunk_LQY2OCQL();
14992
- init_chunk_XOGFONTQ();
15008
+ init_chunk_DIBRGYL6();
14993
15009
  init_chunk_3HSB6J4J();
14994
15010
  init_chunk_IG6QBZMA();
14995
15011
  init_chunk_ZJJ5ODOD();
@@ -14997,10 +15013,9 @@ var init_contracts = __esm({
14997
15013
  init_chunk_LBDH7LCG();
14998
15014
  init_chunk_4LXDRTO4();
14999
15015
  init_chunk_E4DIIOOE();
15000
- init_chunk_7CYHPF35();
15001
- init_chunk_OGXIPFQY();
15002
- init_chunk_LQSENJ26();
15003
- init_chunk_UZ7SPBM3();
15016
+ init_chunk_23UZ2IKU();
15017
+ init_chunk_MCSEEMGN();
15018
+ init_chunk_UFYIBL66();
15004
15019
  init_chunk_NVKU5PPQ();
15005
15020
  init_chunk_2FCLSQSQ();
15006
15021
  init_chunk_FECLIZTY();
@@ -15012,14 +15027,14 @@ var init_contracts = __esm({
15012
15027
  init_chunk_ACN6GXU6();
15013
15028
  init_chunk_OMPT4ZHR();
15014
15029
  init_chunk_2PZIF56U();
15015
- init_chunk_UEJOG2Q7();
15016
- init_chunk_ISFDR7SP();
15030
+ init_chunk_KJXJKAYT();
15017
15031
  init_chunk_SOJMWM63();
15018
15032
  init_chunk_WEXVYJ5H();
15019
- init_chunk_LZDVDC2S();
15033
+ init_chunk_C5MU3WEM();
15020
15034
  init_chunk_5XEJSR22();
15021
15035
  init_chunk_IBL7FANV();
15022
- init_chunk_PFDZEKDE();
15036
+ init_chunk_Y3S4XX4K();
15037
+ init_chunk_A4JC7DXB();
15023
15038
  init_chunk_VORPHGDT();
15024
15039
  init_chunk_HZ6CADSY();
15025
15040
  init_chunk_MIWZOSPI();
@@ -16341,13 +16356,14 @@ var UUID_RE2, WAYAI_WORKSPACE_LAYOUT;
16341
16356
  var init_dist = __esm({
16342
16357
  "../../packages/core/dist/index.js"() {
16343
16358
  "use strict";
16344
- init_chunk_ISFDR7SP();
16359
+ init_chunk_KJXJKAYT();
16345
16360
  init_chunk_SOJMWM63();
16346
16361
  init_chunk_WEXVYJ5H();
16347
- init_chunk_LZDVDC2S();
16362
+ init_chunk_C5MU3WEM();
16348
16363
  init_chunk_5XEJSR22();
16349
16364
  init_chunk_IBL7FANV();
16350
- init_chunk_PFDZEKDE();
16365
+ init_chunk_Y3S4XX4K();
16366
+ init_chunk_A4JC7DXB();
16351
16367
  init_chunk_P3AWZG3N();
16352
16368
  init_chunk_VORPHGDT();
16353
16369
  init_chunk_HZ6CADSY();
@@ -22250,7 +22266,7 @@ function renderDiff(diff) {
22250
22266
  for (const kind of ENTITY_KINDS) {
22251
22267
  const b = bucket(diff, kind);
22252
22268
  if (!b || isEmptyBucket(b)) continue;
22253
- lines.push(`${BOLD}${LABELS[kind]}s${RESET}`);
22269
+ lines.push(`${BOLD}${ENTITY_LABELS[kind]}s${RESET}`);
22254
22270
  for (const e of b.added) lines.push(`${GREEN} + ${sanitizeTerminalText(e.id)}${RESET}`);
22255
22271
  for (const m of b.modified) lines.push(`${YELLOW} ~ ${sanitizeTerminalText(m.after.id)}${RESET}`);
22256
22272
  for (const e of b.removed) {
@@ -22271,14 +22287,14 @@ function renderDiff(diff) {
22271
22287
  }
22272
22288
  return lines.join("\n");
22273
22289
  }
22274
- var LABELS, GREEN, YELLOW, RED, BOLD, RESET;
22290
+ var ENTITY_LABELS, GREEN, YELLOW, RED, BOLD, RESET;
22275
22291
  var init_diff_format = __esm({
22276
22292
  "src/data/config-as-code/diff-format.ts"() {
22277
22293
  "use strict";
22278
22294
  init_terminal_output();
22279
22295
  init_base_id();
22280
22296
  init_types2();
22281
- LABELS = {
22297
+ ENTITY_LABELS = {
22282
22298
  record_types: "record type",
22283
22299
  relationship_types: "relationship type",
22284
22300
  file_types: "file type",
@@ -33554,13 +33570,23 @@ function compareForSlugOrder(a, b) {
33554
33570
  if (at !== bt) return at < bt ? -1 : 1;
33555
33571
  return a.resource_id < b.resource_id ? -1 : a.resource_id > b.resource_id ? 1 : 0;
33556
33572
  }
33557
- function buildResourceSlugMap(resources) {
33558
- const ordered = [...resources].sort(compareForSlugOrder);
33573
+ function isSkill(resource) {
33574
+ return resource.resource_type === "skill";
33575
+ }
33576
+ function resourceNamespace(resource) {
33577
+ return isSkill(resource) ? SKILL_NAMESPACE : RESOURCE_NAMESPACE;
33578
+ }
33579
+ function resourceMountPath(resource, slug) {
33580
+ return `${resourceNamespace(resource)}/${slug}`;
33581
+ }
33582
+ function baseSlug(resource) {
33583
+ return slugifySkillName(resourceDisplayName(resource)) || FALLBACK_SLUG;
33584
+ }
33585
+ function rankSlugs(ordered) {
33559
33586
  const used = /* @__PURE__ */ new Set();
33560
33587
  const slugByResourceId = /* @__PURE__ */ new Map();
33561
33588
  for (const resource of ordered) {
33562
- if (!resource?.resource_id) continue;
33563
- const base = slugifySkillName(resourceDisplayName(resource)) || FALLBACK_SLUG;
33589
+ const base = baseSlug(resource);
33564
33590
  let slug = base;
33565
33591
  for (let ordinal = 2; used.has(slug); ordinal++) slug = `${base}-${ordinal}`;
33566
33592
  used.add(slug);
@@ -33568,6 +33594,17 @@ function buildResourceSlugMap(resources) {
33568
33594
  }
33569
33595
  return slugByResourceId;
33570
33596
  }
33597
+ function buildResourceSlugMap(resources) {
33598
+ const ordered = resources.filter((resource) => !!resource?.resource_id).sort(compareForSlugOrder);
33599
+ const overAll = rankSlugs(ordered);
33600
+ const overSkills = rankSlugs(ordered.filter(isSkill));
33601
+ const slugByResourceId = /* @__PURE__ */ new Map();
33602
+ for (const resource of ordered) {
33603
+ const slug = isSkill(resource) ? overSkills.get(resource.resource_id) : overAll.get(resource.resource_id);
33604
+ if (slug) slugByResourceId.set(resource.resource_id, slug);
33605
+ }
33606
+ return slugByResourceId;
33607
+ }
33571
33608
  function sanitizeSegment(name) {
33572
33609
  const cleaned = (name ?? "").replace(/[\\/]+/g, "-").replace(/[\u0000-\u001F\u007F-\u009F\u2028\u2029]+/g, " ").trim();
33573
33610
  return cleaned === "." || cleaned === ".." ? "" : cleaned;
@@ -33684,8 +33721,15 @@ function compareForOrdinalOrder(a, b) {
33684
33721
  }
33685
33722
  function buildResourcePathIndex(resources, files, folders) {
33686
33723
  const slugByResourceId = buildResourceSlugMap(resources);
33687
- const resourceIdBySlug = /* @__PURE__ */ new Map();
33688
- for (const [resourceId, slug] of slugByResourceId) resourceIdBySlug.set(slug, resourceId);
33724
+ const mountPathByResourceId = /* @__PURE__ */ new Map();
33725
+ const resourceIdByMountPath = /* @__PURE__ */ new Map();
33726
+ for (const resource of resources) {
33727
+ const slug = resource?.resource_id ? slugByResourceId.get(resource.resource_id) : void 0;
33728
+ if (!slug) continue;
33729
+ const mountPath = resourceMountPath(resource, slug);
33730
+ mountPathByResourceId.set(resource.resource_id, mountPath);
33731
+ resourceIdByMountPath.set(mountPath, resource.resource_id);
33732
+ }
33689
33733
  const resolveFolder = buildFolderPathResolver(folders);
33690
33734
  const filesByResource = /* @__PURE__ */ new Map();
33691
33735
  for (const row of files) {
@@ -33700,7 +33744,8 @@ function buildResourcePathIndex(resources, files, folders) {
33700
33744
  const entriesByResourceId = /* @__PURE__ */ new Map();
33701
33745
  for (const [resourceId, rows] of filesByResource) {
33702
33746
  const slug = slugByResourceId.get(resourceId);
33703
- if (!slug) continue;
33747
+ const mountPath = mountPathByResourceId.get(resourceId);
33748
+ if (!slug || !mountPath) continue;
33704
33749
  const takenPaths = /* @__PURE__ */ new Set();
33705
33750
  const resourceEntries = [];
33706
33751
  for (const row of [...rows].sort(compareForOrdinalOrder)) {
@@ -33721,7 +33766,7 @@ function buildResourcePathIndex(resources, files, folders) {
33721
33766
  resource_file_id: row.resource_file_id,
33722
33767
  file_id: row.file_id,
33723
33768
  relative_path: relativePath,
33724
- canonical_path: `${RESOURCE_NAMESPACE}/${slug}/${relativePath}`,
33769
+ canonical_path: `${mountPath}/${relativePath}`,
33725
33770
  file: row
33726
33771
  };
33727
33772
  entries.push(entry);
@@ -33731,9 +33776,9 @@ function buildResourcePathIndex(resources, files, folders) {
33731
33776
  }
33732
33777
  entriesByResourceId.set(resourceId, resourceEntries);
33733
33778
  }
33734
- return { entries, slugByResourceId, resourceIdBySlug, byCanonicalPath, byFileId, entriesByResourceId };
33779
+ return { entries, slugByResourceId, mountPathByResourceId, resourceIdByMountPath, byCanonicalPath, byFileId, entriesByResourceId };
33735
33780
  }
33736
- var RESOURCE_NAMESPACE, FALLBACK_SLUG, FALLBACK_LEAF, MAX_FOLDER_DEPTH, UI_UPLOAD_TIMESTAMP_PREFIX, UUID_SEGMENT;
33781
+ var RESOURCE_NAMESPACE, SKILL_NAMESPACE, FALLBACK_SLUG, FALLBACK_LEAF, MAX_FOLDER_DEPTH, UI_UPLOAD_TIMESTAMP_PREFIX, UUID_SEGMENT;
33737
33782
  var init_resource_paths = __esm({
33738
33783
  "../../packages/core/dist/resource-paths.js"() {
33739
33784
  "use strict";
@@ -33741,6 +33786,7 @@ var init_resource_paths = __esm({
33741
33786
  init_chunk_CJ3L46X6();
33742
33787
  init_chunk_6TSQ5HXC();
33743
33788
  RESOURCE_NAMESPACE = "resources";
33789
+ SKILL_NAMESPACE = "skills";
33744
33790
  FALLBACK_SLUG = "resource";
33745
33791
  FALLBACK_LEAF = "file";
33746
33792
  MAX_FOLDER_DEPTH = 32;
@@ -34590,7 +34636,7 @@ function sameFileType(remote, spec) {
34590
34636
  function isObject(value) {
34591
34637
  return typeof value === "object" && value !== null && !Array.isArray(value);
34592
34638
  }
34593
- function promotionProblems(result, ids, section = "file_types") {
34639
+ function promotionProblems(result, ids, { section = "file_types", createOnly = false } = {}) {
34594
34640
  const answer = isObject(result) ? result : {};
34595
34641
  const problems2 = [];
34596
34642
  for (const [kind, bucket2] of Object.entries(isObject(answer.diff) ? answer.diff : {})) {
@@ -34599,7 +34645,15 @@ function promotionProblems(result, ids, section = "file_types") {
34599
34645
  for (const entry of Array.isArray(bucket2[change]) ? bucket2[change] : []) {
34600
34646
  const row = isObject(entry) ? isObject(entry.after) ? entry.after : entry : {};
34601
34647
  const id = typeof row.id === "string" ? row.id : JSON.stringify(row).slice(0, 80);
34602
- if (kind === section && change !== "removed" && ids.has(id)) continue;
34648
+ if (kind === section && ids.has(id)) {
34649
+ if (change === "added" || change === "modified" && !createOnly) continue;
34650
+ if (change === "modified") {
34651
+ problems2.push(
34652
+ `${ENTITY_LABELS[section]} "${id}" was created in production while the migration ran, and differs from the one it would promote, so the production one is kept`
34653
+ );
34654
+ continue;
34655
+ }
34656
+ }
34603
34657
  problems2.push(`it would also apply ${kind} ${change}: "${id}"`);
34604
34658
  }
34605
34659
  }
@@ -34762,7 +34816,7 @@ Dry run: nothing written (${writes === 0 ? "nothing to write" : `${writes} write
34762
34816
  for (const spec of toWrite) await kb.putFileType(preview, spec);
34763
34817
  if (toPromote.length > 0) {
34764
34818
  const ids = toPromote.map((s) => s.id);
34765
- const problems2 = promotionProblems(await kb.promoteFileTypes(productionId, preview, ids, true), new Set(ids));
34819
+ const problems2 = promotionProblems(await kb.promoteFileTypes(productionId, preview, ids, true), new Set(ids), { createOnly: true });
34766
34820
  if (problems2.length > 0) {
34767
34821
  throw expected(
34768
34822
  `The promotion into "${safe(productionId)}" would not apply as planned (${problems2.map(safe).join("; ")}). Its file types are written in "${safe(preview)}"; nothing reached production.`
@@ -34797,6 +34851,7 @@ var init_migrate2 = __esm({
34797
34851
  "use strict";
34798
34852
  init_resource_files();
34799
34853
  init_api_client();
34854
+ init_diff_format();
34800
34855
  init_expected();
34801
34856
  init_terminal_output();
34802
34857
  init_utils();
@@ -35367,9 +35422,10 @@ var COUNTER_KEYS, STT_PRICING, CONTAINER_PRICING, connectorById, nativeToolById;
35367
35422
  var init_catalog = __esm({
35368
35423
  "../../packages/core/dist/catalog/index.js"() {
35369
35424
  "use strict";
35370
- init_chunk_OGXIPFQY();
35371
- init_chunk_LQSENJ26();
35372
- init_chunk_UZ7SPBM3();
35425
+ init_chunk_23UZ2IKU();
35426
+ init_chunk_MCSEEMGN();
35427
+ init_chunk_UFYIBL66();
35428
+ init_chunk_A4JC7DXB();
35373
35429
  init_chunk_MIWZOSPI();
35374
35430
  init_chunk_DHPUPI4Y();
35375
35431
  COUNTER_KEYS = Object.keys({
@@ -35767,7 +35823,7 @@ Dry run: nothing written (${writes === 0 ? "nothing to write" : `${writes} write
35767
35823
  for (const spec of toolsetsToWrite) await kb.putToolset(preview, spec);
35768
35824
  if (toolsetsToPromote.length > 0) {
35769
35825
  const slugs = toolsetsToPromote.map((s) => s.id);
35770
- const problems2 = promotionProblems(await kb.promoteToolsets(production, preview, slugs, true), new Set(slugs), "toolsets");
35826
+ const problems2 = promotionProblems(await kb.promoteToolsets(production, preview, slugs, true), new Set(slugs), { section: "toolsets" });
35771
35827
  if (problems2.length > 0) {
35772
35828
  throw expected(
35773
35829
  `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.`
@@ -35964,7 +36020,9 @@ migrate: move knowledge resources into the organization's knowledge base.
35964
36020
  file type, its files keep their paths, and each described folder gains an _index.md. Files are
35965
36021
  written create-only: one created at its path while it runs is kept, and the run stops there,
35966
36022
  naming it. A re-run writes what is left once that file matches its source or is moved or
35967
- removed; until then it stops before any write, naming it.
36023
+ removed; until then it stops before any write, naming it. A file type created in production at
36024
+ an id it would add, after it read production, is kept too: unless it is already what the run
36025
+ would promote, the run stops before promoting, naming it.
35968
36026
 
35969
36027
  --base The knowledge base: its production base, or the preview its file types are
35970
36028
  written in. File types are written in the preview and promoted; files are