@wayai/cli 0.3.40 → 0.3.42

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.
Files changed (166) hide show
  1. package/dist/index.js +16920 -310
  2. package/dist/index.js.map +1 -1
  3. package/package.json +6 -4
  4. package/dist/commands/admin.d.ts +0 -1
  5. package/dist/commands/admin.js +0 -913
  6. package/dist/commands/admin.js.map +0 -1
  7. package/dist/commands/analytics.d.ts +0 -34
  8. package/dist/commands/analytics.js +0 -605
  9. package/dist/commands/analytics.js.map +0 -1
  10. package/dist/commands/conversations.d.ts +0 -14
  11. package/dist/commands/conversations.js +0 -292
  12. package/dist/commands/conversations.js.map +0 -1
  13. package/dist/commands/create-credential.d.ts +0 -20
  14. package/dist/commands/create-credential.js +0 -146
  15. package/dist/commands/create-credential.js.map +0 -1
  16. package/dist/commands/delete-history.d.ts +0 -15
  17. package/dist/commands/delete-history.js +0 -56
  18. package/dist/commands/delete-history.js.map +0 -1
  19. package/dist/commands/eval-capture.d.ts +0 -1
  20. package/dist/commands/eval-capture.js +0 -135
  21. package/dist/commands/eval-capture.js.map +0 -1
  22. package/dist/commands/eval-results.d.ts +0 -10
  23. package/dist/commands/eval-results.js +0 -168
  24. package/dist/commands/eval-results.js.map +0 -1
  25. package/dist/commands/eval.d.ts +0 -1
  26. package/dist/commands/eval.js +0 -49
  27. package/dist/commands/eval.js.map +0 -1
  28. package/dist/commands/evals.d.ts +0 -21
  29. package/dist/commands/evals.js +0 -120
  30. package/dist/commands/evals.js.map +0 -1
  31. package/dist/commands/init.d.ts +0 -16
  32. package/dist/commands/init.js +0 -191
  33. package/dist/commands/init.js.map +0 -1
  34. package/dist/commands/list.d.ts +0 -13
  35. package/dist/commands/list.js +0 -70
  36. package/dist/commands/list.js.map +0 -1
  37. package/dist/commands/login.d.ts +0 -8
  38. package/dist/commands/login.js +0 -145
  39. package/dist/commands/login.js.map +0 -1
  40. package/dist/commands/logout.d.ts +0 -1
  41. package/dist/commands/logout.js +0 -19
  42. package/dist/commands/logout.js.map +0 -1
  43. package/dist/commands/migrate.d.ts +0 -12
  44. package/dist/commands/migrate.js +0 -106
  45. package/dist/commands/migrate.js.map +0 -1
  46. package/dist/commands/observability.d.ts +0 -14
  47. package/dist/commands/observability.js +0 -124
  48. package/dist/commands/observability.js.map +0 -1
  49. package/dist/commands/org.d.ts +0 -19
  50. package/dist/commands/org.js +0 -186
  51. package/dist/commands/org.js.map +0 -1
  52. package/dist/commands/pull.d.ts +0 -31
  53. package/dist/commands/pull.js +0 -210
  54. package/dist/commands/pull.js.map +0 -1
  55. package/dist/commands/push.d.ts +0 -25
  56. package/dist/commands/push.js +0 -472
  57. package/dist/commands/push.js.map +0 -1
  58. package/dist/commands/report-create.d.ts +0 -18
  59. package/dist/commands/report-create.js +0 -143
  60. package/dist/commands/report-create.js.map +0 -1
  61. package/dist/commands/report.d.ts +0 -16
  62. package/dist/commands/report.js +0 -252
  63. package/dist/commands/report.js.map +0 -1
  64. package/dist/commands/run-eval.d.ts +0 -15
  65. package/dist/commands/run-eval.js +0 -187
  66. package/dist/commands/run-eval.js.map +0 -1
  67. package/dist/commands/send-message.d.ts +0 -11
  68. package/dist/commands/send-message.js +0 -63
  69. package/dist/commands/send-message.js.map +0 -1
  70. package/dist/commands/status.d.ts +0 -17
  71. package/dist/commands/status.js +0 -205
  72. package/dist/commands/status.js.map +0 -1
  73. package/dist/commands/sync-mcp.d.ts +0 -16
  74. package/dist/commands/sync-mcp.js +0 -51
  75. package/dist/commands/sync-mcp.js.map +0 -1
  76. package/dist/commands/sync-skills.d.ts +0 -10
  77. package/dist/commands/sync-skills.js +0 -49
  78. package/dist/commands/sync-skills.js.map +0 -1
  79. package/dist/commands/unlock.d.ts +0 -1
  80. package/dist/commands/unlock.js +0 -13
  81. package/dist/commands/unlock.js.map +0 -1
  82. package/dist/commands/update-credential.d.ts +0 -29
  83. package/dist/commands/update-credential.js +0 -156
  84. package/dist/commands/update-credential.js.map +0 -1
  85. package/dist/commands/update.d.ts +0 -6
  86. package/dist/commands/update.js +0 -36
  87. package/dist/commands/update.js.map +0 -1
  88. package/dist/commands/use.d.ts +0 -1
  89. package/dist/commands/use.js +0 -56
  90. package/dist/commands/use.js.map +0 -1
  91. package/dist/commands/whoami.d.ts +0 -11
  92. package/dist/commands/whoami.js +0 -30
  93. package/dist/commands/whoami.js.map +0 -1
  94. package/dist/index.d.ts +0 -28
  95. package/dist/lib/analytics-constants.d.ts +0 -6
  96. package/dist/lib/analytics-constants.js +0 -14
  97. package/dist/lib/analytics-constants.js.map +0 -1
  98. package/dist/lib/api-client.d.ts +0 -568
  99. package/dist/lib/api-client.js +0 -445
  100. package/dist/lib/api-client.js.map +0 -1
  101. package/dist/lib/auth.d.ts +0 -50
  102. package/dist/lib/auth.js +0 -230
  103. package/dist/lib/auth.js.map +0 -1
  104. package/dist/lib/config.d.ts +0 -34
  105. package/dist/lib/config.js +0 -69
  106. package/dist/lib/config.js.map +0 -1
  107. package/dist/lib/credential-utils.d.ts +0 -36
  108. package/dist/lib/credential-utils.js +0 -88
  109. package/dist/lib/credential-utils.js.map +0 -1
  110. package/dist/lib/diff-display.d.ts +0 -8
  111. package/dist/lib/diff-display.js +0 -37
  112. package/dist/lib/diff-display.js.map +0 -1
  113. package/dist/lib/eval-format.d.ts +0 -29
  114. package/dist/lib/eval-format.js +0 -44
  115. package/dist/lib/eval-format.js.map +0 -1
  116. package/dist/lib/hub-lock.d.ts +0 -7
  117. package/dist/lib/hub-lock.js +0 -116
  118. package/dist/lib/hub-lock.js.map +0 -1
  119. package/dist/lib/layout.d.ts +0 -79
  120. package/dist/lib/layout.js +0 -133
  121. package/dist/lib/layout.js.map +0 -1
  122. package/dist/lib/org-workspace.d.ts +0 -22
  123. package/dist/lib/org-workspace.js +0 -106
  124. package/dist/lib/org-workspace.js.map +0 -1
  125. package/dist/lib/parser.d.ts +0 -16
  126. package/dist/lib/parser.js +0 -306
  127. package/dist/lib/parser.js.map +0 -1
  128. package/dist/lib/repo-config.d.ts +0 -23
  129. package/dist/lib/repo-config.js +0 -91
  130. package/dist/lib/repo-config.js.map +0 -1
  131. package/dist/lib/report-edit-args.d.ts +0 -27
  132. package/dist/lib/report-edit-args.js +0 -56
  133. package/dist/lib/report-edit-args.js.map +0 -1
  134. package/dist/lib/report-inbox.d.ts +0 -19
  135. package/dist/lib/report-inbox.js +0 -73
  136. package/dist/lib/report-inbox.js.map +0 -1
  137. package/dist/lib/resource-files.d.ts +0 -29
  138. package/dist/lib/resource-files.js +0 -156
  139. package/dist/lib/resource-files.js.map +0 -1
  140. package/dist/lib/sentry.d.ts +0 -38
  141. package/dist/lib/sentry.js +0 -168
  142. package/dist/lib/sentry.js.map +0 -1
  143. package/dist/lib/skill-version.d.ts +0 -9
  144. package/dist/lib/skill-version.js +0 -53
  145. package/dist/lib/skill-version.js.map +0 -1
  146. package/dist/lib/sql-output.d.ts +0 -17
  147. package/dist/lib/sql-output.js +0 -48
  148. package/dist/lib/sql-output.js.map +0 -1
  149. package/dist/lib/token-store.d.ts +0 -37
  150. package/dist/lib/token-store.js +0 -354
  151. package/dist/lib/token-store.js.map +0 -1
  152. package/dist/lib/types.d.ts +0 -18
  153. package/dist/lib/types.js +0 -5
  154. package/dist/lib/types.js.map +0 -1
  155. package/dist/lib/utils.d.ts +0 -97
  156. package/dist/lib/utils.js +0 -288
  157. package/dist/lib/utils.js.map +0 -1
  158. package/dist/lib/version-cache.d.ts +0 -10
  159. package/dist/lib/version-cache.js +0 -34
  160. package/dist/lib/version-cache.js.map +0 -1
  161. package/dist/lib/workspace.d.ts +0 -112
  162. package/dist/lib/workspace.js +0 -387
  163. package/dist/lib/workspace.js.map +0 -1
  164. package/dist/lib/yaml-writer.d.ts +0 -18
  165. package/dist/lib/yaml-writer.js +0 -283
  166. package/dist/lib/yaml-writer.js.map +0 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"sources":["../src/lib/sentry.ts","../../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js","../../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js","../../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js","../../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js","../../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js","../../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/typeAliases.js","../../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js","../../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js","../../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js","../../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/index.js","../../../packages/core/src/errors.ts","../../../packages/core/src/circuit-breaker.ts","../../../packages/core/src/tracing.ts","../../../packages/core/src/rate-limits.ts","../../../packages/core/src/agent-settings.ts","../../../packages/core/src/constants.ts","../../../packages/core/src/contracts/common.ts","../../../packages/core/src/contracts/setup/organizations.ts","../../../packages/core/src/contracts/setup/agents.ts","../../../packages/core/src/summarizer/index.ts","../../../packages/core/src/contracts/setup/slug.ts","../../../packages/core/src/contracts/setup/kanban.ts","../../../packages/core/src/contracts/setup/hubs.ts","../../../packages/core/src/contracts/setup/connections.ts","../../../packages/core/src/contracts/setup/tools.ts","../../../packages/core/src/tool-schema-validator.ts","../../../packages/core/src/contracts/setup/states.ts","../../../packages/core/src/contracts/setup/organization-tags.ts","../../../packages/core/src/contracts/setup/organization-credentials.ts","../../../packages/core/src/contracts/setup/organization-resources.ts","../../../packages/core/src/contracts/setup/resources.ts","../../../packages/core/src/contracts/live-updates.ts","../../../packages/core/src/contracts/analytics.ts","../../../packages/core/src/contracts/evals.ts","../../../packages/core/src/eval-pacing.ts","../../../packages/core/src/contracts/chat.ts","../../../packages/core/src/contracts/users.ts","../../../packages/core/src/contracts/archive.ts","../../../packages/core/src/contracts/conversations.ts","../../../packages/core/src/contracts/billing.ts","../../../packages/core/src/contracts/files.ts","../../../packages/core/src/contracts/completions.ts","../../../packages/core/src/contracts/outbound.ts","../../../packages/core/src/contracts/outbound-contacts.ts","../../../packages/core/src/contracts/outbound-lists.ts","../../../packages/core/src/contracts/outbound-schedules.ts","../../../packages/core/src/contracts/ci.ts","../../../packages/core/src/contracts/admin.ts","../../../packages/core/src/contracts/auth.ts","../../../packages/core/src/contracts/resource-browser.ts","../../../packages/core/src/contracts/conversation-state.ts","../../../packages/core/src/contracts/conversation-resources.ts","../../../packages/core/src/contracts/conversation-schedules.ts","../../../packages/core/src/contracts/reports.ts","../../../packages/core/src/contracts/clickhouse.ts","../../../packages/core/src/contracts/session-snapshot.ts","../../../packages/core/src/contracts/vault.ts","../../../packages/core/src/contracts/tokens.ts","../../../packages/core/src/auth/permissions.ts","../../../packages/core/src/contracts/invites.ts","../../../packages/core/src/contracts/discord.ts","../../../packages/core/src/contracts/hub-users.ts","../../../packages/core/src/contracts/hub-alerts.ts","../../../packages/core/src/contracts/notices.ts","../../../packages/core/src/time.ts","../../../packages/core/src/auth/grants.ts","../../../packages/core/src/auth/token-hash.ts","../../../packages/core/src/auth/jwt-verify.ts","../../../packages/core/src/auth/dual-auth.ts","../../../packages/core/src/auth/token-utils.ts","../../../packages/core/src/crypto.ts","../../../packages/core/src/markdown-format.ts","../../../packages/core/src/strip-reasoning-tags.ts","../../../packages/core/src/conversation-event-format.ts","../../../packages/core/src/streaming-types.ts","../../../packages/core/src/slugify.ts","../../../packages/core/src/workspace-layout.ts","../../../packages/core/src/resources.ts","../../../packages/core/src/scheduling/placeholders.ts","../../../packages/core/src/whatsapp-template-vars.ts","../src/lib/layout.ts","../src/lib/workspace.ts","../src/lib/repo-config.ts","../src/lib/utils.ts","../src/lib/version-cache.ts","../src/lib/skill-version.ts","../src/lib/config.ts","../src/lib/token-store.ts","../src/lib/auth.ts","../src/lib/api-client.ts","../src/lib/report-inbox.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/lib/hub-lock.ts","../src/commands/status.ts","../src/commands/whoami.ts","../src/commands/init.ts","../src/lib/resource-files.ts","../src/lib/yaml-writer.ts","../src/lib/parser.ts","../src/lib/diff-display.ts","../src/commands/pull.ts","../src/commands/push.ts","../src/commands/use.ts","../src/commands/migrate.ts","../src/commands/unlock.ts","../src/commands/send-message.ts","../src/commands/observability.ts","../src/commands/conversations.ts","../src/commands/delete-history.ts","../src/commands/sync-skills.ts","../src/commands/sync-mcp.ts","../src/lib/sql-output.ts","../src/commands/evals.ts","../src/lib/eval-format.ts","../src/commands/run-eval.ts","../src/commands/eval-results.ts","../src/commands/eval-capture.ts","../src/commands/eval.ts","../../../packages/core/src/contracts/common.ts","../../../packages/core/src/contracts/setup/organizations.ts","../../../packages/core/src/contracts/setup/agents.ts","../../../packages/core/src/constants.ts","../../../packages/core/src/summarizer/index.ts","../../../packages/core/src/contracts/setup/slug.ts","../../../packages/core/src/contracts/setup/kanban.ts","../../../packages/core/src/contracts/setup/hubs.ts","../../../packages/core/src/contracts/setup/connections.ts","../../../packages/core/src/contracts/setup/tools.ts","../../../packages/core/src/tool-schema-validator.ts","../../../packages/core/src/contracts/setup/states.ts","../../../packages/core/src/contracts/setup/organization-tags.ts","../../../packages/core/src/contracts/setup/organization-credentials.ts","../../../packages/core/src/contracts/setup/organization-resources.ts","../../../packages/core/src/contracts/setup/resources.ts","../../../packages/core/src/contracts/live-updates.ts","../../../packages/core/src/contracts/analytics.ts","../../../packages/core/src/contracts/evals.ts","../../../packages/core/src/eval-pacing.ts","../../../packages/core/src/contracts/chat.ts","../../../packages/core/src/contracts/users.ts","../../../packages/core/src/contracts/archive.ts","../../../packages/core/src/contracts/conversations.ts","../../../packages/core/src/contracts/billing.ts","../../../packages/core/src/contracts/files.ts","../../../packages/core/src/contracts/completions.ts","../../../packages/core/src/contracts/outbound.ts","../../../packages/core/src/contracts/outbound-contacts.ts","../../../packages/core/src/contracts/outbound-lists.ts","../../../packages/core/src/contracts/outbound-schedules.ts","../../../packages/core/src/contracts/ci.ts","../../../packages/core/src/contracts/admin.ts","../../../packages/core/src/contracts/auth.ts","../../../packages/core/src/contracts/resource-browser.ts","../../../packages/core/src/contracts/conversation-state.ts","../../../packages/core/src/contracts/conversation-resources.ts","../../../packages/core/src/contracts/conversation-schedules.ts","../../../packages/core/src/contracts/reports.ts","../../../packages/core/src/contracts/clickhouse.ts","../../../packages/core/src/contracts/session-snapshot.ts","../../../packages/core/src/contracts/vault.ts","../../../packages/core/src/contracts/tokens.ts","../../../packages/core/src/auth/permissions.ts","../../../packages/core/src/contracts/invites.ts","../../../packages/core/src/contracts/discord.ts","../../../packages/core/src/contracts/hub-users.ts","../../../packages/core/src/contracts/hub-alerts.ts","../../../packages/core/src/contracts/notices.ts","../src/lib/analytics-constants.ts","../src/commands/analytics.ts","../src/lib/credential-utils.ts","../src/commands/create-credential.ts","../src/commands/update-credential.ts","../src/lib/org-workspace.ts","../src/commands/org.ts","../src/commands/list.ts","../src/lib/report-edit-args.ts","../src/commands/admin.ts","../src/commands/report-create.ts","../src/commands/report.ts","../src/commands/update.ts","../src/index.ts"],"sourcesContent":["/**\n * Sentry error tracking for @wayai/cli\n *\n * Production-only: skips initialization when running from source (development).\n * Opt-out: set WAYAI_TELEMETRY_DISABLED=1 to disable.\n */\n\nimport * as Sentry from '@sentry/node';\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { homedir, platform, arch } from 'node:os';\n\nconst HARDCODED_DSN = 'https://ffe500121277babcabf32e5868f00f9e@o4510669417807872.ingest.us.sentry.io/4510960145465344';\n\nlet initialized = false;\n\nfunction getVersion(): string {\n try {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'package.json'), 'utf-8'));\n return pkg.version || '0.0.0';\n } catch {\n return '0.0.0';\n }\n}\n\n/**\n * Detect if running from npm install (production) vs from source (development).\n * When installed via npm, import.meta.url path contains 'node_modules'.\n * SENTRY_DSN env var overrides this check for testing.\n */\nfunction isInstalledPackage(): boolean {\n try {\n return fileURLToPath(import.meta.url).includes('node_modules');\n } catch {\n return false;\n }\n}\n\n/**\n * Initialize Sentry for the CLI.\n *\n * @param command - The CLI command being run (e.g., 'push', 'pull')\n */\nexport function initSentry(command?: string): void {\n if (initialized) return;\n\n // Opt-out\n if (process.env.WAYAI_TELEMETRY_DISABLED === '1') return;\n\n const dsn = process.env.SENTRY_DSN || HARDCODED_DSN;\n\n // Skip when running from source (dev), unless SENTRY_DSN is explicitly set\n if (!process.env.SENTRY_DSN && !isInstalledPackage()) return;\n\n const version = getVersion();\n\n Sentry.init({\n dsn,\n tracesSampleRate: 0,\n release: `wayai-cli@${version}`,\n environment: 'production',\n defaultIntegrations: false,\n beforeSend(event) {\n // Sanitize home directory paths in stack frames\n const home = homedir();\n if (home && event.exception?.values) {\n for (const value of event.exception.values) {\n if (value.stacktrace?.frames) {\n for (const frame of value.stacktrace.frames) {\n if (frame.filename && frame.filename.includes(home)) {\n frame.filename = frame.filename.replace(home, '~');\n }\n }\n }\n }\n }\n return event;\n },\n });\n\n // Set default tags\n Sentry.setTag('command', command || 'unknown');\n Sentry.setTag('node_version', process.version);\n Sentry.setTag('os_platform', platform());\n Sentry.setTag('os_arch', arch());\n\n initialized = true;\n}\n\n/**\n * Whether an error should be reported to Sentry.\n * Expected API errors (4xx) are user-facing conditions, not bugs.\n */\nexport function shouldReportToSentry(error: unknown): boolean {\n if (\n error instanceof Error &&\n 'isExpected' in error &&\n (error as { isExpected: boolean }).isExpected\n ) {\n return false;\n }\n return true;\n}\n\n/**\n * Capture an exception to Sentry.\n */\nexport function captureException(\n error: unknown,\n context?: { tags?: Record<string, string>; extra?: Record<string, unknown> }\n): void {\n if (!initialized) return;\n\n Sentry.withScope((scope) => {\n if (context?.tags) {\n for (const [key, value] of Object.entries(context.tags)) {\n scope.setTag(key, value);\n }\n }\n if (context?.extra) {\n for (const [key, value] of Object.entries(context.extra)) {\n scope.setExtra(key, value);\n }\n }\n Sentry.captureException(error);\n });\n}\n\n/**\n * Add a breadcrumb for API requests.\n */\nexport function addApiBreadcrumb(method: string, path: string): void {\n if (!initialized) return;\n\n Sentry.addBreadcrumb({\n category: 'http',\n message: `${method} ${path}`,\n level: 'info',\n });\n}\n\n/**\n * Set the Sentry user from a way_ token or JWT access token.\n * For way_ tokens, uses a hash prefix as the user identifier.\n * For JWTs (legacy), decodes the payload to extract the `sub` claim.\n */\nexport function setSentryUser(accessToken: string): void {\n if (!initialized) return;\n\n try {\n if (accessToken.startsWith('way_')) {\n // way_ tokens are opaque — use a truncated hash as user identifier\n const hash = require('node:crypto')\n .createHash('sha256')\n .update(accessToken)\n .digest('hex')\n .slice(0, 16);\n Sentry.setUser({ id: `token:${hash}` });\n return;\n }\n\n // Legacy JWT path\n const payloadBase64 = accessToken.split('.')[1];\n if (!payloadBase64) return;\n\n const payload = JSON.parse(Buffer.from(payloadBase64, 'base64url').toString());\n if (payload.sub) {\n Sentry.setUser({ id: payload.sub });\n }\n } catch {\n // Silently ignore malformed tokens — user context is best-effort\n }\n}\n\n/**\n * Flush and close Sentry. Must be awaited before process.exit().\n */\nexport async function closeSentry(): Promise<void> {\n if (!initialized) return;\n await Sentry.close(2000);\n initialized = false;\n}\n","export var util;\n(function (util) {\n util.assertEqual = (_) => { };\n function assertIs(_arg) { }\n util.assertIs = assertIs;\n function assertNever(_x) {\n throw new Error();\n }\n util.assertNever = assertNever;\n util.arrayToEnum = (items) => {\n const obj = {};\n for (const item of items) {\n obj[item] = item;\n }\n return obj;\n };\n util.getValidEnumValues = (obj) => {\n const validKeys = util.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== \"number\");\n const filtered = {};\n for (const k of validKeys) {\n filtered[k] = obj[k];\n }\n return util.objectValues(filtered);\n };\n util.objectValues = (obj) => {\n return util.objectKeys(obj).map(function (e) {\n return obj[e];\n });\n };\n util.objectKeys = typeof Object.keys === \"function\" // eslint-disable-line ban/ban\n ? (obj) => Object.keys(obj) // eslint-disable-line ban/ban\n : (object) => {\n const keys = [];\n for (const key in object) {\n if (Object.prototype.hasOwnProperty.call(object, key)) {\n keys.push(key);\n }\n }\n return keys;\n };\n util.find = (arr, checker) => {\n for (const item of arr) {\n if (checker(item))\n return item;\n }\n return undefined;\n };\n util.isInteger = typeof Number.isInteger === \"function\"\n ? (val) => Number.isInteger(val) // eslint-disable-line ban/ban\n : (val) => typeof val === \"number\" && Number.isFinite(val) && Math.floor(val) === val;\n function joinValues(array, separator = \" | \") {\n return array.map((val) => (typeof val === \"string\" ? `'${val}'` : val)).join(separator);\n }\n util.joinValues = joinValues;\n util.jsonStringifyReplacer = (_, value) => {\n if (typeof value === \"bigint\") {\n return value.toString();\n }\n return value;\n };\n})(util || (util = {}));\nexport var objectUtil;\n(function (objectUtil) {\n objectUtil.mergeShapes = (first, second) => {\n return {\n ...first,\n ...second, // second overwrites first\n };\n };\n})(objectUtil || (objectUtil = {}));\nexport const ZodParsedType = util.arrayToEnum([\n \"string\",\n \"nan\",\n \"number\",\n \"integer\",\n \"float\",\n \"boolean\",\n \"date\",\n \"bigint\",\n \"symbol\",\n \"function\",\n \"undefined\",\n \"null\",\n \"array\",\n \"object\",\n \"unknown\",\n \"promise\",\n \"void\",\n \"never\",\n \"map\",\n \"set\",\n]);\nexport const getParsedType = (data) => {\n const t = typeof data;\n switch (t) {\n case \"undefined\":\n return ZodParsedType.undefined;\n case \"string\":\n return ZodParsedType.string;\n case \"number\":\n return Number.isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;\n case \"boolean\":\n return ZodParsedType.boolean;\n case \"function\":\n return ZodParsedType.function;\n case \"bigint\":\n return ZodParsedType.bigint;\n case \"symbol\":\n return ZodParsedType.symbol;\n case \"object\":\n if (Array.isArray(data)) {\n return ZodParsedType.array;\n }\n if (data === null) {\n return ZodParsedType.null;\n }\n if (data.then && typeof data.then === \"function\" && data.catch && typeof data.catch === \"function\") {\n return ZodParsedType.promise;\n }\n if (typeof Map !== \"undefined\" && data instanceof Map) {\n return ZodParsedType.map;\n }\n if (typeof Set !== \"undefined\" && data instanceof Set) {\n return ZodParsedType.set;\n }\n if (typeof Date !== \"undefined\" && data instanceof Date) {\n return ZodParsedType.date;\n }\n return ZodParsedType.object;\n default:\n return ZodParsedType.unknown;\n }\n};\n","import { util } from \"./helpers/util.js\";\nexport const ZodIssueCode = util.arrayToEnum([\n \"invalid_type\",\n \"invalid_literal\",\n \"custom\",\n \"invalid_union\",\n \"invalid_union_discriminator\",\n \"invalid_enum_value\",\n \"unrecognized_keys\",\n \"invalid_arguments\",\n \"invalid_return_type\",\n \"invalid_date\",\n \"invalid_string\",\n \"too_small\",\n \"too_big\",\n \"invalid_intersection_types\",\n \"not_multiple_of\",\n \"not_finite\",\n]);\nexport const quotelessJson = (obj) => {\n const json = JSON.stringify(obj, null, 2);\n return json.replace(/\"([^\"]+)\":/g, \"$1:\");\n};\nexport class ZodError extends Error {\n get errors() {\n return this.issues;\n }\n constructor(issues) {\n super();\n this.issues = [];\n this.addIssue = (sub) => {\n this.issues = [...this.issues, sub];\n };\n this.addIssues = (subs = []) => {\n this.issues = [...this.issues, ...subs];\n };\n const actualProto = new.target.prototype;\n if (Object.setPrototypeOf) {\n // eslint-disable-next-line ban/ban\n Object.setPrototypeOf(this, actualProto);\n }\n else {\n this.__proto__ = actualProto;\n }\n this.name = \"ZodError\";\n this.issues = issues;\n }\n format(_mapper) {\n const mapper = _mapper ||\n function (issue) {\n return issue.message;\n };\n const fieldErrors = { _errors: [] };\n const processError = (error) => {\n for (const issue of error.issues) {\n if (issue.code === \"invalid_union\") {\n issue.unionErrors.map(processError);\n }\n else if (issue.code === \"invalid_return_type\") {\n processError(issue.returnTypeError);\n }\n else if (issue.code === \"invalid_arguments\") {\n processError(issue.argumentsError);\n }\n else if (issue.path.length === 0) {\n fieldErrors._errors.push(mapper(issue));\n }\n else {\n let curr = fieldErrors;\n let i = 0;\n while (i < issue.path.length) {\n const el = issue.path[i];\n const terminal = i === issue.path.length - 1;\n if (!terminal) {\n curr[el] = curr[el] || { _errors: [] };\n // if (typeof el === \"string\") {\n // curr[el] = curr[el] || { _errors: [] };\n // } else if (typeof el === \"number\") {\n // const errorArray: any = [];\n // errorArray._errors = [];\n // curr[el] = curr[el] || errorArray;\n // }\n }\n else {\n curr[el] = curr[el] || { _errors: [] };\n curr[el]._errors.push(mapper(issue));\n }\n curr = curr[el];\n i++;\n }\n }\n }\n };\n processError(this);\n return fieldErrors;\n }\n static assert(value) {\n if (!(value instanceof ZodError)) {\n throw new Error(`Not a ZodError: ${value}`);\n }\n }\n toString() {\n return this.message;\n }\n get message() {\n return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);\n }\n get isEmpty() {\n return this.issues.length === 0;\n }\n flatten(mapper = (issue) => issue.message) {\n const fieldErrors = {};\n const formErrors = [];\n for (const sub of this.issues) {\n if (sub.path.length > 0) {\n const firstEl = sub.path[0];\n fieldErrors[firstEl] = fieldErrors[firstEl] || [];\n fieldErrors[firstEl].push(mapper(sub));\n }\n else {\n formErrors.push(mapper(sub));\n }\n }\n return { formErrors, fieldErrors };\n }\n get formErrors() {\n return this.flatten();\n }\n}\nZodError.create = (issues) => {\n const error = new ZodError(issues);\n return error;\n};\n","import { ZodIssueCode } from \"../ZodError.js\";\nimport { util, ZodParsedType } from \"../helpers/util.js\";\nconst errorMap = (issue, _ctx) => {\n let message;\n switch (issue.code) {\n case ZodIssueCode.invalid_type:\n if (issue.received === ZodParsedType.undefined) {\n message = \"Required\";\n }\n else {\n message = `Expected ${issue.expected}, received ${issue.received}`;\n }\n break;\n case ZodIssueCode.invalid_literal:\n message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`;\n break;\n case ZodIssueCode.unrecognized_keys:\n message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, \", \")}`;\n break;\n case ZodIssueCode.invalid_union:\n message = `Invalid input`;\n break;\n case ZodIssueCode.invalid_union_discriminator:\n message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;\n break;\n case ZodIssueCode.invalid_enum_value:\n message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`;\n break;\n case ZodIssueCode.invalid_arguments:\n message = `Invalid function arguments`;\n break;\n case ZodIssueCode.invalid_return_type:\n message = `Invalid function return type`;\n break;\n case ZodIssueCode.invalid_date:\n message = `Invalid date`;\n break;\n case ZodIssueCode.invalid_string:\n if (typeof issue.validation === \"object\") {\n if (\"includes\" in issue.validation) {\n message = `Invalid input: must include \"${issue.validation.includes}\"`;\n if (typeof issue.validation.position === \"number\") {\n message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;\n }\n }\n else if (\"startsWith\" in issue.validation) {\n message = `Invalid input: must start with \"${issue.validation.startsWith}\"`;\n }\n else if (\"endsWith\" in issue.validation) {\n message = `Invalid input: must end with \"${issue.validation.endsWith}\"`;\n }\n else {\n util.assertNever(issue.validation);\n }\n }\n else if (issue.validation !== \"regex\") {\n message = `Invalid ${issue.validation}`;\n }\n else {\n message = \"Invalid\";\n }\n break;\n case ZodIssueCode.too_small:\n if (issue.type === \"array\")\n message = `Array must contain ${issue.exact ? \"exactly\" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;\n else if (issue.type === \"string\")\n message = `String must contain ${issue.exact ? \"exactly\" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;\n else if (issue.type === \"number\")\n message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;\n else if (issue.type === \"bigint\")\n message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;\n else if (issue.type === \"date\")\n message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;\n else\n message = \"Invalid input\";\n break;\n case ZodIssueCode.too_big:\n if (issue.type === \"array\")\n message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;\n else if (issue.type === \"string\")\n message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;\n else if (issue.type === \"number\")\n message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;\n else if (issue.type === \"bigint\")\n message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;\n else if (issue.type === \"date\")\n message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`;\n else\n message = \"Invalid input\";\n break;\n case ZodIssueCode.custom:\n message = `Invalid input`;\n break;\n case ZodIssueCode.invalid_intersection_types:\n message = `Intersection results could not be merged`;\n break;\n case ZodIssueCode.not_multiple_of:\n message = `Number must be a multiple of ${issue.multipleOf}`;\n break;\n case ZodIssueCode.not_finite:\n message = \"Number must be finite\";\n break;\n default:\n message = _ctx.defaultError;\n util.assertNever(issue);\n }\n return { message };\n};\nexport default errorMap;\n","import defaultErrorMap from \"./locales/en.js\";\nlet overrideErrorMap = defaultErrorMap;\nexport { defaultErrorMap };\nexport function setErrorMap(map) {\n overrideErrorMap = map;\n}\nexport function getErrorMap() {\n return overrideErrorMap;\n}\n","import { getErrorMap } from \"../errors.js\";\nimport defaultErrorMap from \"../locales/en.js\";\nexport const makeIssue = (params) => {\n const { data, path, errorMaps, issueData } = params;\n const fullPath = [...path, ...(issueData.path || [])];\n const fullIssue = {\n ...issueData,\n path: fullPath,\n };\n if (issueData.message !== undefined) {\n return {\n ...issueData,\n path: fullPath,\n message: issueData.message,\n };\n }\n let errorMessage = \"\";\n const maps = errorMaps\n .filter((m) => !!m)\n .slice()\n .reverse();\n for (const map of maps) {\n errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message;\n }\n return {\n ...issueData,\n path: fullPath,\n message: errorMessage,\n };\n};\nexport const EMPTY_PATH = [];\nexport function addIssueToContext(ctx, issueData) {\n const overrideMap = getErrorMap();\n const issue = makeIssue({\n issueData: issueData,\n data: ctx.data,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap, // contextual error map is first priority\n ctx.schemaErrorMap, // then schema-bound map if available\n overrideMap, // then global override map\n overrideMap === defaultErrorMap ? undefined : defaultErrorMap, // then global default map\n ].filter((x) => !!x),\n });\n ctx.common.issues.push(issue);\n}\nexport class ParseStatus {\n constructor() {\n this.value = \"valid\";\n }\n dirty() {\n if (this.value === \"valid\")\n this.value = \"dirty\";\n }\n abort() {\n if (this.value !== \"aborted\")\n this.value = \"aborted\";\n }\n static mergeArray(status, results) {\n const arrayValue = [];\n for (const s of results) {\n if (s.status === \"aborted\")\n return INVALID;\n if (s.status === \"dirty\")\n status.dirty();\n arrayValue.push(s.value);\n }\n return { status: status.value, value: arrayValue };\n }\n static async mergeObjectAsync(status, pairs) {\n const syncPairs = [];\n for (const pair of pairs) {\n const key = await pair.key;\n const value = await pair.value;\n syncPairs.push({\n key,\n value,\n });\n }\n return ParseStatus.mergeObjectSync(status, syncPairs);\n }\n static mergeObjectSync(status, pairs) {\n const finalObject = {};\n for (const pair of pairs) {\n const { key, value } = pair;\n if (key.status === \"aborted\")\n return INVALID;\n if (value.status === \"aborted\")\n return INVALID;\n if (key.status === \"dirty\")\n status.dirty();\n if (value.status === \"dirty\")\n status.dirty();\n if (key.value !== \"__proto__\" && (typeof value.value !== \"undefined\" || pair.alwaysSet)) {\n finalObject[key.value] = value.value;\n }\n }\n return { status: status.value, value: finalObject };\n }\n}\nexport const INVALID = Object.freeze({\n status: \"aborted\",\n});\nexport const DIRTY = (value) => ({ status: \"dirty\", value });\nexport const OK = (value) => ({ status: \"valid\", value });\nexport const isAborted = (x) => x.status === \"aborted\";\nexport const isDirty = (x) => x.status === \"dirty\";\nexport const isValid = (x) => x.status === \"valid\";\nexport const isAsync = (x) => typeof Promise !== \"undefined\" && x instanceof Promise;\n","export {};\n","export var errorUtil;\n(function (errorUtil) {\n errorUtil.errToObj = (message) => typeof message === \"string\" ? { message } : message || {};\n // biome-ignore lint:\n errorUtil.toString = (message) => typeof message === \"string\" ? message : message?.message;\n})(errorUtil || (errorUtil = {}));\n","import { ZodError, ZodIssueCode, } from \"./ZodError.js\";\nimport { defaultErrorMap, getErrorMap } from \"./errors.js\";\nimport { errorUtil } from \"./helpers/errorUtil.js\";\nimport { DIRTY, INVALID, OK, ParseStatus, addIssueToContext, isAborted, isAsync, isDirty, isValid, makeIssue, } from \"./helpers/parseUtil.js\";\nimport { util, ZodParsedType, getParsedType } from \"./helpers/util.js\";\nclass ParseInputLazyPath {\n constructor(parent, value, path, key) {\n this._cachedPath = [];\n this.parent = parent;\n this.data = value;\n this._path = path;\n this._key = key;\n }\n get path() {\n if (!this._cachedPath.length) {\n if (Array.isArray(this._key)) {\n this._cachedPath.push(...this._path, ...this._key);\n }\n else {\n this._cachedPath.push(...this._path, this._key);\n }\n }\n return this._cachedPath;\n }\n}\nconst handleResult = (ctx, result) => {\n if (isValid(result)) {\n return { success: true, data: result.value };\n }\n else {\n if (!ctx.common.issues.length) {\n throw new Error(\"Validation failed but no issues detected.\");\n }\n return {\n success: false,\n get error() {\n if (this._error)\n return this._error;\n const error = new ZodError(ctx.common.issues);\n this._error = error;\n return this._error;\n },\n };\n }\n};\nfunction processCreateParams(params) {\n if (!params)\n return {};\n const { errorMap, invalid_type_error, required_error, description } = params;\n if (errorMap && (invalid_type_error || required_error)) {\n throw new Error(`Can't use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.`);\n }\n if (errorMap)\n return { errorMap: errorMap, description };\n const customMap = (iss, ctx) => {\n const { message } = params;\n if (iss.code === \"invalid_enum_value\") {\n return { message: message ?? ctx.defaultError };\n }\n if (typeof ctx.data === \"undefined\") {\n return { message: message ?? required_error ?? ctx.defaultError };\n }\n if (iss.code !== \"invalid_type\")\n return { message: ctx.defaultError };\n return { message: message ?? invalid_type_error ?? ctx.defaultError };\n };\n return { errorMap: customMap, description };\n}\nexport class ZodType {\n get description() {\n return this._def.description;\n }\n _getType(input) {\n return getParsedType(input.data);\n }\n _getOrReturnCtx(input, ctx) {\n return (ctx || {\n common: input.parent.common,\n data: input.data,\n parsedType: getParsedType(input.data),\n schemaErrorMap: this._def.errorMap,\n path: input.path,\n parent: input.parent,\n });\n }\n _processInputParams(input) {\n return {\n status: new ParseStatus(),\n ctx: {\n common: input.parent.common,\n data: input.data,\n parsedType: getParsedType(input.data),\n schemaErrorMap: this._def.errorMap,\n path: input.path,\n parent: input.parent,\n },\n };\n }\n _parseSync(input) {\n const result = this._parse(input);\n if (isAsync(result)) {\n throw new Error(\"Synchronous parse encountered promise.\");\n }\n return result;\n }\n _parseAsync(input) {\n const result = this._parse(input);\n return Promise.resolve(result);\n }\n parse(data, params) {\n const result = this.safeParse(data, params);\n if (result.success)\n return result.data;\n throw result.error;\n }\n safeParse(data, params) {\n const ctx = {\n common: {\n issues: [],\n async: params?.async ?? false,\n contextualErrorMap: params?.errorMap,\n },\n path: params?.path || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: getParsedType(data),\n };\n const result = this._parseSync({ data, path: ctx.path, parent: ctx });\n return handleResult(ctx, result);\n }\n \"~validate\"(data) {\n const ctx = {\n common: {\n issues: [],\n async: !!this[\"~standard\"].async,\n },\n path: [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: getParsedType(data),\n };\n if (!this[\"~standard\"].async) {\n try {\n const result = this._parseSync({ data, path: [], parent: ctx });\n return isValid(result)\n ? {\n value: result.value,\n }\n : {\n issues: ctx.common.issues,\n };\n }\n catch (err) {\n if (err?.message?.toLowerCase()?.includes(\"encountered\")) {\n this[\"~standard\"].async = true;\n }\n ctx.common = {\n issues: [],\n async: true,\n };\n }\n }\n return this._parseAsync({ data, path: [], parent: ctx }).then((result) => isValid(result)\n ? {\n value: result.value,\n }\n : {\n issues: ctx.common.issues,\n });\n }\n async parseAsync(data, params) {\n const result = await this.safeParseAsync(data, params);\n if (result.success)\n return result.data;\n throw result.error;\n }\n async safeParseAsync(data, params) {\n const ctx = {\n common: {\n issues: [],\n contextualErrorMap: params?.errorMap,\n async: true,\n },\n path: params?.path || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: getParsedType(data),\n };\n const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx });\n const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));\n return handleResult(ctx, result);\n }\n refine(check, message) {\n const getIssueProperties = (val) => {\n if (typeof message === \"string\" || typeof message === \"undefined\") {\n return { message };\n }\n else if (typeof message === \"function\") {\n return message(val);\n }\n else {\n return message;\n }\n };\n return this._refinement((val, ctx) => {\n const result = check(val);\n const setError = () => ctx.addIssue({\n code: ZodIssueCode.custom,\n ...getIssueProperties(val),\n });\n if (typeof Promise !== \"undefined\" && result instanceof Promise) {\n return result.then((data) => {\n if (!data) {\n setError();\n return false;\n }\n else {\n return true;\n }\n });\n }\n if (!result) {\n setError();\n return false;\n }\n else {\n return true;\n }\n });\n }\n refinement(check, refinementData) {\n return this._refinement((val, ctx) => {\n if (!check(val)) {\n ctx.addIssue(typeof refinementData === \"function\" ? refinementData(val, ctx) : refinementData);\n return false;\n }\n else {\n return true;\n }\n });\n }\n _refinement(refinement) {\n return new ZodEffects({\n schema: this,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect: { type: \"refinement\", refinement },\n });\n }\n superRefine(refinement) {\n return this._refinement(refinement);\n }\n constructor(def) {\n /** Alias of safeParseAsync */\n this.spa = this.safeParseAsync;\n this._def = def;\n this.parse = this.parse.bind(this);\n this.safeParse = this.safeParse.bind(this);\n this.parseAsync = this.parseAsync.bind(this);\n this.safeParseAsync = this.safeParseAsync.bind(this);\n this.spa = this.spa.bind(this);\n this.refine = this.refine.bind(this);\n this.refinement = this.refinement.bind(this);\n this.superRefine = this.superRefine.bind(this);\n this.optional = this.optional.bind(this);\n this.nullable = this.nullable.bind(this);\n this.nullish = this.nullish.bind(this);\n this.array = this.array.bind(this);\n this.promise = this.promise.bind(this);\n this.or = this.or.bind(this);\n this.and = this.and.bind(this);\n this.transform = this.transform.bind(this);\n this.brand = this.brand.bind(this);\n this.default = this.default.bind(this);\n this.catch = this.catch.bind(this);\n this.describe = this.describe.bind(this);\n this.pipe = this.pipe.bind(this);\n this.readonly = this.readonly.bind(this);\n this.isNullable = this.isNullable.bind(this);\n this.isOptional = this.isOptional.bind(this);\n this[\"~standard\"] = {\n version: 1,\n vendor: \"zod\",\n validate: (data) => this[\"~validate\"](data),\n };\n }\n optional() {\n return ZodOptional.create(this, this._def);\n }\n nullable() {\n return ZodNullable.create(this, this._def);\n }\n nullish() {\n return this.nullable().optional();\n }\n array() {\n return ZodArray.create(this);\n }\n promise() {\n return ZodPromise.create(this, this._def);\n }\n or(option) {\n return ZodUnion.create([this, option], this._def);\n }\n and(incoming) {\n return ZodIntersection.create(this, incoming, this._def);\n }\n transform(transform) {\n return new ZodEffects({\n ...processCreateParams(this._def),\n schema: this,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect: { type: \"transform\", transform },\n });\n }\n default(def) {\n const defaultValueFunc = typeof def === \"function\" ? def : () => def;\n return new ZodDefault({\n ...processCreateParams(this._def),\n innerType: this,\n defaultValue: defaultValueFunc,\n typeName: ZodFirstPartyTypeKind.ZodDefault,\n });\n }\n brand() {\n return new ZodBranded({\n typeName: ZodFirstPartyTypeKind.ZodBranded,\n type: this,\n ...processCreateParams(this._def),\n });\n }\n catch(def) {\n const catchValueFunc = typeof def === \"function\" ? def : () => def;\n return new ZodCatch({\n ...processCreateParams(this._def),\n innerType: this,\n catchValue: catchValueFunc,\n typeName: ZodFirstPartyTypeKind.ZodCatch,\n });\n }\n describe(description) {\n const This = this.constructor;\n return new This({\n ...this._def,\n description,\n });\n }\n pipe(target) {\n return ZodPipeline.create(this, target);\n }\n readonly() {\n return ZodReadonly.create(this);\n }\n isOptional() {\n return this.safeParse(undefined).success;\n }\n isNullable() {\n return this.safeParse(null).success;\n }\n}\nconst cuidRegex = /^c[^\\s-]{8,}$/i;\nconst cuid2Regex = /^[0-9a-z]+$/;\nconst ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i;\n// const uuidRegex =\n// /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i;\nconst uuidRegex = /^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i;\nconst nanoidRegex = /^[a-z0-9_-]{21}$/i;\nconst jwtRegex = /^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$/;\nconst durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??$/;\n// from https://stackoverflow.com/a/46181/1550155\n// old version: too slow, didn't support unicode\n// const emailRegex = /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i;\n//old email regex\n// const emailRegex = /^(([^<>()[\\].,;:\\s@\"]+(\\.[^<>()[\\].,;:\\s@\"]+)*)|(\".+\"))@((?!-)([^<>()[\\].,;:\\s@\"]+\\.)+[^<>()[\\].,;:\\s@\"]{1,})[^-<>()[\\].,;:\\s@\"]$/i;\n// eslint-disable-next-line\n// const emailRegex =\n// /^(([^<>()[\\]\\\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@((\\[(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\])|(\\[IPv6:(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\\])|([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])*(\\.[A-Za-z]{2,})+))$/;\n// const emailRegex =\n// /^[a-zA-Z0-9\\.\\!\\#\\$\\%\\&\\'\\*\\+\\/\\=\\?\\^\\_\\`\\{\\|\\}\\~\\-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\n// const emailRegex =\n// /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])$/i;\nconst emailRegex = /^(?!\\.)(?!.*\\.\\.)([A-Z0-9_'+\\-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i;\n// const emailRegex =\n// /^[a-z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-z0-9-]+(?:\\.[a-z0-9\\-]+)*$/i;\n// from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression\nconst _emojiRegex = `^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+$`;\nlet emojiRegex;\n// faster, simpler, safer\nconst ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;\nconst ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/(3[0-2]|[12]?[0-9])$/;\n// const ipv6Regex =\n// /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;\nconst ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;\nconst ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;\n// https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript\nconst base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;\n// https://base64.guru/standards/base64url\nconst base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/;\n// simple\n// const dateRegexSource = `\\\\d{4}-\\\\d{2}-\\\\d{2}`;\n// no leap year validation\n// const dateRegexSource = `\\\\d{4}-((0[13578]|10|12)-31|(0[13-9]|1[0-2])-30|(0[1-9]|1[0-2])-(0[1-9]|1\\\\d|2\\\\d))`;\n// with leap year validation\nconst dateRegexSource = `((\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\\\d|30)|(02)-(0[1-9]|1\\\\d|2[0-8])))`;\nconst dateRegex = new RegExp(`^${dateRegexSource}$`);\nfunction timeRegexSource(args) {\n let secondsRegexSource = `[0-5]\\\\d`;\n if (args.precision) {\n secondsRegexSource = `${secondsRegexSource}\\\\.\\\\d{${args.precision}}`;\n }\n else if (args.precision == null) {\n secondsRegexSource = `${secondsRegexSource}(\\\\.\\\\d+)?`;\n }\n const secondsQuantifier = args.precision ? \"+\" : \"?\"; // require seconds if precision is nonzero\n return `([01]\\\\d|2[0-3]):[0-5]\\\\d(:${secondsRegexSource})${secondsQuantifier}`;\n}\nfunction timeRegex(args) {\n return new RegExp(`^${timeRegexSource(args)}$`);\n}\n// Adapted from https://stackoverflow.com/a/3143231\nexport function datetimeRegex(args) {\n let regex = `${dateRegexSource}T${timeRegexSource(args)}`;\n const opts = [];\n opts.push(args.local ? `Z?` : `Z`);\n if (args.offset)\n opts.push(`([+-]\\\\d{2}:?\\\\d{2})`);\n regex = `${regex}(${opts.join(\"|\")})`;\n return new RegExp(`^${regex}$`);\n}\nfunction isValidIP(ip, version) {\n if ((version === \"v4\" || !version) && ipv4Regex.test(ip)) {\n return true;\n }\n if ((version === \"v6\" || !version) && ipv6Regex.test(ip)) {\n return true;\n }\n return false;\n}\nfunction isValidJWT(jwt, alg) {\n if (!jwtRegex.test(jwt))\n return false;\n try {\n const [header] = jwt.split(\".\");\n if (!header)\n return false;\n // Convert base64url to base64\n const base64 = header\n .replace(/-/g, \"+\")\n .replace(/_/g, \"/\")\n .padEnd(header.length + ((4 - (header.length % 4)) % 4), \"=\");\n const decoded = JSON.parse(atob(base64));\n if (typeof decoded !== \"object\" || decoded === null)\n return false;\n if (\"typ\" in decoded && decoded?.typ !== \"JWT\")\n return false;\n if (!decoded.alg)\n return false;\n if (alg && decoded.alg !== alg)\n return false;\n return true;\n }\n catch {\n return false;\n }\n}\nfunction isValidCidr(ip, version) {\n if ((version === \"v4\" || !version) && ipv4CidrRegex.test(ip)) {\n return true;\n }\n if ((version === \"v6\" || !version) && ipv6CidrRegex.test(ip)) {\n return true;\n }\n return false;\n}\nexport class ZodString extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = String(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.string) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.string,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const status = new ParseStatus();\n let ctx = undefined;\n for (const check of this._def.checks) {\n if (check.kind === \"min\") {\n if (input.data.length < check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: check.value,\n type: \"string\",\n inclusive: true,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n if (input.data.length > check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: check.value,\n type: \"string\",\n inclusive: true,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"length\") {\n const tooBig = input.data.length > check.value;\n const tooSmall = input.data.length < check.value;\n if (tooBig || tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n if (tooBig) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: check.value,\n type: \"string\",\n inclusive: true,\n exact: true,\n message: check.message,\n });\n }\n else if (tooSmall) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: check.value,\n type: \"string\",\n inclusive: true,\n exact: true,\n message: check.message,\n });\n }\n status.dirty();\n }\n }\n else if (check.kind === \"email\") {\n if (!emailRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"email\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"emoji\") {\n if (!emojiRegex) {\n emojiRegex = new RegExp(_emojiRegex, \"u\");\n }\n if (!emojiRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"emoji\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"uuid\") {\n if (!uuidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"uuid\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"nanoid\") {\n if (!nanoidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"nanoid\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"cuid\") {\n if (!cuidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"cuid\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"cuid2\") {\n if (!cuid2Regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"cuid2\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"ulid\") {\n if (!ulidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"ulid\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"url\") {\n try {\n new URL(input.data);\n }\n catch {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"url\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"regex\") {\n check.regex.lastIndex = 0;\n const testResult = check.regex.test(input.data);\n if (!testResult) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"regex\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"trim\") {\n input.data = input.data.trim();\n }\n else if (check.kind === \"includes\") {\n if (!input.data.includes(check.value, check.position)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: { includes: check.value, position: check.position },\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"toLowerCase\") {\n input.data = input.data.toLowerCase();\n }\n else if (check.kind === \"toUpperCase\") {\n input.data = input.data.toUpperCase();\n }\n else if (check.kind === \"startsWith\") {\n if (!input.data.startsWith(check.value)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: { startsWith: check.value },\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"endsWith\") {\n if (!input.data.endsWith(check.value)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: { endsWith: check.value },\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"datetime\") {\n const regex = datetimeRegex(check);\n if (!regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: \"datetime\",\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"date\") {\n const regex = dateRegex;\n if (!regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: \"date\",\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"time\") {\n const regex = timeRegex(check);\n if (!regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: \"time\",\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"duration\") {\n if (!durationRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"duration\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"ip\") {\n if (!isValidIP(input.data, check.version)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"ip\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"jwt\") {\n if (!isValidJWT(input.data, check.alg)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"jwt\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"cidr\") {\n if (!isValidCidr(input.data, check.version)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"cidr\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"base64\") {\n if (!base64Regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"base64\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"base64url\") {\n if (!base64urlRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"base64url\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else {\n util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n _regex(regex, validation, message) {\n return this.refinement((data) => regex.test(data), {\n validation,\n code: ZodIssueCode.invalid_string,\n ...errorUtil.errToObj(message),\n });\n }\n _addCheck(check) {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n email(message) {\n return this._addCheck({ kind: \"email\", ...errorUtil.errToObj(message) });\n }\n url(message) {\n return this._addCheck({ kind: \"url\", ...errorUtil.errToObj(message) });\n }\n emoji(message) {\n return this._addCheck({ kind: \"emoji\", ...errorUtil.errToObj(message) });\n }\n uuid(message) {\n return this._addCheck({ kind: \"uuid\", ...errorUtil.errToObj(message) });\n }\n nanoid(message) {\n return this._addCheck({ kind: \"nanoid\", ...errorUtil.errToObj(message) });\n }\n cuid(message) {\n return this._addCheck({ kind: \"cuid\", ...errorUtil.errToObj(message) });\n }\n cuid2(message) {\n return this._addCheck({ kind: \"cuid2\", ...errorUtil.errToObj(message) });\n }\n ulid(message) {\n return this._addCheck({ kind: \"ulid\", ...errorUtil.errToObj(message) });\n }\n base64(message) {\n return this._addCheck({ kind: \"base64\", ...errorUtil.errToObj(message) });\n }\n base64url(message) {\n // base64url encoding is a modification of base64 that can safely be used in URLs and filenames\n return this._addCheck({\n kind: \"base64url\",\n ...errorUtil.errToObj(message),\n });\n }\n jwt(options) {\n return this._addCheck({ kind: \"jwt\", ...errorUtil.errToObj(options) });\n }\n ip(options) {\n return this._addCheck({ kind: \"ip\", ...errorUtil.errToObj(options) });\n }\n cidr(options) {\n return this._addCheck({ kind: \"cidr\", ...errorUtil.errToObj(options) });\n }\n datetime(options) {\n if (typeof options === \"string\") {\n return this._addCheck({\n kind: \"datetime\",\n precision: null,\n offset: false,\n local: false,\n message: options,\n });\n }\n return this._addCheck({\n kind: \"datetime\",\n precision: typeof options?.precision === \"undefined\" ? null : options?.precision,\n offset: options?.offset ?? false,\n local: options?.local ?? false,\n ...errorUtil.errToObj(options?.message),\n });\n }\n date(message) {\n return this._addCheck({ kind: \"date\", message });\n }\n time(options) {\n if (typeof options === \"string\") {\n return this._addCheck({\n kind: \"time\",\n precision: null,\n message: options,\n });\n }\n return this._addCheck({\n kind: \"time\",\n precision: typeof options?.precision === \"undefined\" ? null : options?.precision,\n ...errorUtil.errToObj(options?.message),\n });\n }\n duration(message) {\n return this._addCheck({ kind: \"duration\", ...errorUtil.errToObj(message) });\n }\n regex(regex, message) {\n return this._addCheck({\n kind: \"regex\",\n regex: regex,\n ...errorUtil.errToObj(message),\n });\n }\n includes(value, options) {\n return this._addCheck({\n kind: \"includes\",\n value: value,\n position: options?.position,\n ...errorUtil.errToObj(options?.message),\n });\n }\n startsWith(value, message) {\n return this._addCheck({\n kind: \"startsWith\",\n value: value,\n ...errorUtil.errToObj(message),\n });\n }\n endsWith(value, message) {\n return this._addCheck({\n kind: \"endsWith\",\n value: value,\n ...errorUtil.errToObj(message),\n });\n }\n min(minLength, message) {\n return this._addCheck({\n kind: \"min\",\n value: minLength,\n ...errorUtil.errToObj(message),\n });\n }\n max(maxLength, message) {\n return this._addCheck({\n kind: \"max\",\n value: maxLength,\n ...errorUtil.errToObj(message),\n });\n }\n length(len, message) {\n return this._addCheck({\n kind: \"length\",\n value: len,\n ...errorUtil.errToObj(message),\n });\n }\n /**\n * Equivalent to `.min(1)`\n */\n nonempty(message) {\n return this.min(1, errorUtil.errToObj(message));\n }\n trim() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: \"trim\" }],\n });\n }\n toLowerCase() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: \"toLowerCase\" }],\n });\n }\n toUpperCase() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: \"toUpperCase\" }],\n });\n }\n get isDatetime() {\n return !!this._def.checks.find((ch) => ch.kind === \"datetime\");\n }\n get isDate() {\n return !!this._def.checks.find((ch) => ch.kind === \"date\");\n }\n get isTime() {\n return !!this._def.checks.find((ch) => ch.kind === \"time\");\n }\n get isDuration() {\n return !!this._def.checks.find((ch) => ch.kind === \"duration\");\n }\n get isEmail() {\n return !!this._def.checks.find((ch) => ch.kind === \"email\");\n }\n get isURL() {\n return !!this._def.checks.find((ch) => ch.kind === \"url\");\n }\n get isEmoji() {\n return !!this._def.checks.find((ch) => ch.kind === \"emoji\");\n }\n get isUUID() {\n return !!this._def.checks.find((ch) => ch.kind === \"uuid\");\n }\n get isNANOID() {\n return !!this._def.checks.find((ch) => ch.kind === \"nanoid\");\n }\n get isCUID() {\n return !!this._def.checks.find((ch) => ch.kind === \"cuid\");\n }\n get isCUID2() {\n return !!this._def.checks.find((ch) => ch.kind === \"cuid2\");\n }\n get isULID() {\n return !!this._def.checks.find((ch) => ch.kind === \"ulid\");\n }\n get isIP() {\n return !!this._def.checks.find((ch) => ch.kind === \"ip\");\n }\n get isCIDR() {\n return !!this._def.checks.find((ch) => ch.kind === \"cidr\");\n }\n get isBase64() {\n return !!this._def.checks.find((ch) => ch.kind === \"base64\");\n }\n get isBase64url() {\n // base64url encoding is a modification of base64 that can safely be used in URLs and filenames\n return !!this._def.checks.find((ch) => ch.kind === \"base64url\");\n }\n get minLength() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxLength() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n}\nZodString.create = (params) => {\n return new ZodString({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodString,\n coerce: params?.coerce ?? false,\n ...processCreateParams(params),\n });\n};\n// https://stackoverflow.com/questions/3966484/why-does-modulus-operator-return-fractional-number-in-javascript/31711034#31711034\nfunction floatSafeRemainder(val, step) {\n const valDecCount = (val.toString().split(\".\")[1] || \"\").length;\n const stepDecCount = (step.toString().split(\".\")[1] || \"\").length;\n const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;\n const valInt = Number.parseInt(val.toFixed(decCount).replace(\".\", \"\"));\n const stepInt = Number.parseInt(step.toFixed(decCount).replace(\".\", \"\"));\n return (valInt % stepInt) / 10 ** decCount;\n}\nexport class ZodNumber extends ZodType {\n constructor() {\n super(...arguments);\n this.min = this.gte;\n this.max = this.lte;\n this.step = this.multipleOf;\n }\n _parse(input) {\n if (this._def.coerce) {\n input.data = Number(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.number) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.number,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n let ctx = undefined;\n const status = new ParseStatus();\n for (const check of this._def.checks) {\n if (check.kind === \"int\") {\n if (!util.isInteger(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: \"integer\",\n received: \"float\",\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"min\") {\n const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;\n if (tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: check.value,\n type: \"number\",\n inclusive: check.inclusive,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;\n if (tooBig) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: check.value,\n type: \"number\",\n inclusive: check.inclusive,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"multipleOf\") {\n if (floatSafeRemainder(input.data, check.value) !== 0) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.not_multiple_of,\n multipleOf: check.value,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"finite\") {\n if (!Number.isFinite(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.not_finite,\n message: check.message,\n });\n status.dirty();\n }\n }\n else {\n util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n gte(value, message) {\n return this.setLimit(\"min\", value, true, errorUtil.toString(message));\n }\n gt(value, message) {\n return this.setLimit(\"min\", value, false, errorUtil.toString(message));\n }\n lte(value, message) {\n return this.setLimit(\"max\", value, true, errorUtil.toString(message));\n }\n lt(value, message) {\n return this.setLimit(\"max\", value, false, errorUtil.toString(message));\n }\n setLimit(kind, value, inclusive, message) {\n return new ZodNumber({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind,\n value,\n inclusive,\n message: errorUtil.toString(message),\n },\n ],\n });\n }\n _addCheck(check) {\n return new ZodNumber({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n int(message) {\n return this._addCheck({\n kind: \"int\",\n message: errorUtil.toString(message),\n });\n }\n positive(message) {\n return this._addCheck({\n kind: \"min\",\n value: 0,\n inclusive: false,\n message: errorUtil.toString(message),\n });\n }\n negative(message) {\n return this._addCheck({\n kind: \"max\",\n value: 0,\n inclusive: false,\n message: errorUtil.toString(message),\n });\n }\n nonpositive(message) {\n return this._addCheck({\n kind: \"max\",\n value: 0,\n inclusive: true,\n message: errorUtil.toString(message),\n });\n }\n nonnegative(message) {\n return this._addCheck({\n kind: \"min\",\n value: 0,\n inclusive: true,\n message: errorUtil.toString(message),\n });\n }\n multipleOf(value, message) {\n return this._addCheck({\n kind: \"multipleOf\",\n value: value,\n message: errorUtil.toString(message),\n });\n }\n finite(message) {\n return this._addCheck({\n kind: \"finite\",\n message: errorUtil.toString(message),\n });\n }\n safe(message) {\n return this._addCheck({\n kind: \"min\",\n inclusive: true,\n value: Number.MIN_SAFE_INTEGER,\n message: errorUtil.toString(message),\n })._addCheck({\n kind: \"max\",\n inclusive: true,\n value: Number.MAX_SAFE_INTEGER,\n message: errorUtil.toString(message),\n });\n }\n get minValue() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxValue() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n get isInt() {\n return !!this._def.checks.find((ch) => ch.kind === \"int\" || (ch.kind === \"multipleOf\" && util.isInteger(ch.value)));\n }\n get isFinite() {\n let max = null;\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"finite\" || ch.kind === \"int\" || ch.kind === \"multipleOf\") {\n return true;\n }\n else if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n else if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return Number.isFinite(min) && Number.isFinite(max);\n }\n}\nZodNumber.create = (params) => {\n return new ZodNumber({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodNumber,\n coerce: params?.coerce || false,\n ...processCreateParams(params),\n });\n};\nexport class ZodBigInt extends ZodType {\n constructor() {\n super(...arguments);\n this.min = this.gte;\n this.max = this.lte;\n }\n _parse(input) {\n if (this._def.coerce) {\n try {\n input.data = BigInt(input.data);\n }\n catch {\n return this._getInvalidInput(input);\n }\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.bigint) {\n return this._getInvalidInput(input);\n }\n let ctx = undefined;\n const status = new ParseStatus();\n for (const check of this._def.checks) {\n if (check.kind === \"min\") {\n const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;\n if (tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n type: \"bigint\",\n minimum: check.value,\n inclusive: check.inclusive,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;\n if (tooBig) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n type: \"bigint\",\n maximum: check.value,\n inclusive: check.inclusive,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"multipleOf\") {\n if (input.data % check.value !== BigInt(0)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.not_multiple_of,\n multipleOf: check.value,\n message: check.message,\n });\n status.dirty();\n }\n }\n else {\n util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n _getInvalidInput(input) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.bigint,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n gte(value, message) {\n return this.setLimit(\"min\", value, true, errorUtil.toString(message));\n }\n gt(value, message) {\n return this.setLimit(\"min\", value, false, errorUtil.toString(message));\n }\n lte(value, message) {\n return this.setLimit(\"max\", value, true, errorUtil.toString(message));\n }\n lt(value, message) {\n return this.setLimit(\"max\", value, false, errorUtil.toString(message));\n }\n setLimit(kind, value, inclusive, message) {\n return new ZodBigInt({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind,\n value,\n inclusive,\n message: errorUtil.toString(message),\n },\n ],\n });\n }\n _addCheck(check) {\n return new ZodBigInt({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n positive(message) {\n return this._addCheck({\n kind: \"min\",\n value: BigInt(0),\n inclusive: false,\n message: errorUtil.toString(message),\n });\n }\n negative(message) {\n return this._addCheck({\n kind: \"max\",\n value: BigInt(0),\n inclusive: false,\n message: errorUtil.toString(message),\n });\n }\n nonpositive(message) {\n return this._addCheck({\n kind: \"max\",\n value: BigInt(0),\n inclusive: true,\n message: errorUtil.toString(message),\n });\n }\n nonnegative(message) {\n return this._addCheck({\n kind: \"min\",\n value: BigInt(0),\n inclusive: true,\n message: errorUtil.toString(message),\n });\n }\n multipleOf(value, message) {\n return this._addCheck({\n kind: \"multipleOf\",\n value,\n message: errorUtil.toString(message),\n });\n }\n get minValue() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxValue() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n}\nZodBigInt.create = (params) => {\n return new ZodBigInt({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodBigInt,\n coerce: params?.coerce ?? false,\n ...processCreateParams(params),\n });\n};\nexport class ZodBoolean extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = Boolean(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.boolean) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.boolean,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n}\nZodBoolean.create = (params) => {\n return new ZodBoolean({\n typeName: ZodFirstPartyTypeKind.ZodBoolean,\n coerce: params?.coerce || false,\n ...processCreateParams(params),\n });\n};\nexport class ZodDate extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = new Date(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.date) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.date,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n if (Number.isNaN(input.data.getTime())) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_date,\n });\n return INVALID;\n }\n const status = new ParseStatus();\n let ctx = undefined;\n for (const check of this._def.checks) {\n if (check.kind === \"min\") {\n if (input.data.getTime() < check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n message: check.message,\n inclusive: true,\n exact: false,\n minimum: check.value,\n type: \"date\",\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n if (input.data.getTime() > check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n message: check.message,\n inclusive: true,\n exact: false,\n maximum: check.value,\n type: \"date\",\n });\n status.dirty();\n }\n }\n else {\n util.assertNever(check);\n }\n }\n return {\n status: status.value,\n value: new Date(input.data.getTime()),\n };\n }\n _addCheck(check) {\n return new ZodDate({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n min(minDate, message) {\n return this._addCheck({\n kind: \"min\",\n value: minDate.getTime(),\n message: errorUtil.toString(message),\n });\n }\n max(maxDate, message) {\n return this._addCheck({\n kind: \"max\",\n value: maxDate.getTime(),\n message: errorUtil.toString(message),\n });\n }\n get minDate() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min != null ? new Date(min) : null;\n }\n get maxDate() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max != null ? new Date(max) : null;\n }\n}\nZodDate.create = (params) => {\n return new ZodDate({\n checks: [],\n coerce: params?.coerce || false,\n typeName: ZodFirstPartyTypeKind.ZodDate,\n ...processCreateParams(params),\n });\n};\nexport class ZodSymbol extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.symbol) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.symbol,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n}\nZodSymbol.create = (params) => {\n return new ZodSymbol({\n typeName: ZodFirstPartyTypeKind.ZodSymbol,\n ...processCreateParams(params),\n });\n};\nexport class ZodUndefined extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.undefined) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.undefined,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n}\nZodUndefined.create = (params) => {\n return new ZodUndefined({\n typeName: ZodFirstPartyTypeKind.ZodUndefined,\n ...processCreateParams(params),\n });\n};\nexport class ZodNull extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.null) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.null,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n}\nZodNull.create = (params) => {\n return new ZodNull({\n typeName: ZodFirstPartyTypeKind.ZodNull,\n ...processCreateParams(params),\n });\n};\nexport class ZodAny extends ZodType {\n constructor() {\n super(...arguments);\n // to prevent instances of other classes from extending ZodAny. this causes issues with catchall in ZodObject.\n this._any = true;\n }\n _parse(input) {\n return OK(input.data);\n }\n}\nZodAny.create = (params) => {\n return new ZodAny({\n typeName: ZodFirstPartyTypeKind.ZodAny,\n ...processCreateParams(params),\n });\n};\nexport class ZodUnknown extends ZodType {\n constructor() {\n super(...arguments);\n // required\n this._unknown = true;\n }\n _parse(input) {\n return OK(input.data);\n }\n}\nZodUnknown.create = (params) => {\n return new ZodUnknown({\n typeName: ZodFirstPartyTypeKind.ZodUnknown,\n ...processCreateParams(params),\n });\n};\nexport class ZodNever extends ZodType {\n _parse(input) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.never,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n}\nZodNever.create = (params) => {\n return new ZodNever({\n typeName: ZodFirstPartyTypeKind.ZodNever,\n ...processCreateParams(params),\n });\n};\nexport class ZodVoid extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.undefined) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.void,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n}\nZodVoid.create = (params) => {\n return new ZodVoid({\n typeName: ZodFirstPartyTypeKind.ZodVoid,\n ...processCreateParams(params),\n });\n};\nexport class ZodArray extends ZodType {\n _parse(input) {\n const { ctx, status } = this._processInputParams(input);\n const def = this._def;\n if (ctx.parsedType !== ZodParsedType.array) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.array,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n if (def.exactLength !== null) {\n const tooBig = ctx.data.length > def.exactLength.value;\n const tooSmall = ctx.data.length < def.exactLength.value;\n if (tooBig || tooSmall) {\n addIssueToContext(ctx, {\n code: tooBig ? ZodIssueCode.too_big : ZodIssueCode.too_small,\n minimum: (tooSmall ? def.exactLength.value : undefined),\n maximum: (tooBig ? def.exactLength.value : undefined),\n type: \"array\",\n inclusive: true,\n exact: true,\n message: def.exactLength.message,\n });\n status.dirty();\n }\n }\n if (def.minLength !== null) {\n if (ctx.data.length < def.minLength.value) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: def.minLength.value,\n type: \"array\",\n inclusive: true,\n exact: false,\n message: def.minLength.message,\n });\n status.dirty();\n }\n }\n if (def.maxLength !== null) {\n if (ctx.data.length > def.maxLength.value) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: def.maxLength.value,\n type: \"array\",\n inclusive: true,\n exact: false,\n message: def.maxLength.message,\n });\n status.dirty();\n }\n }\n if (ctx.common.async) {\n return Promise.all([...ctx.data].map((item, i) => {\n return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));\n })).then((result) => {\n return ParseStatus.mergeArray(status, result);\n });\n }\n const result = [...ctx.data].map((item, i) => {\n return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));\n });\n return ParseStatus.mergeArray(status, result);\n }\n get element() {\n return this._def.type;\n }\n min(minLength, message) {\n return new ZodArray({\n ...this._def,\n minLength: { value: minLength, message: errorUtil.toString(message) },\n });\n }\n max(maxLength, message) {\n return new ZodArray({\n ...this._def,\n maxLength: { value: maxLength, message: errorUtil.toString(message) },\n });\n }\n length(len, message) {\n return new ZodArray({\n ...this._def,\n exactLength: { value: len, message: errorUtil.toString(message) },\n });\n }\n nonempty(message) {\n return this.min(1, message);\n }\n}\nZodArray.create = (schema, params) => {\n return new ZodArray({\n type: schema,\n minLength: null,\n maxLength: null,\n exactLength: null,\n typeName: ZodFirstPartyTypeKind.ZodArray,\n ...processCreateParams(params),\n });\n};\nfunction deepPartialify(schema) {\n if (schema instanceof ZodObject) {\n const newShape = {};\n for (const key in schema.shape) {\n const fieldSchema = schema.shape[key];\n newShape[key] = ZodOptional.create(deepPartialify(fieldSchema));\n }\n return new ZodObject({\n ...schema._def,\n shape: () => newShape,\n });\n }\n else if (schema instanceof ZodArray) {\n return new ZodArray({\n ...schema._def,\n type: deepPartialify(schema.element),\n });\n }\n else if (schema instanceof ZodOptional) {\n return ZodOptional.create(deepPartialify(schema.unwrap()));\n }\n else if (schema instanceof ZodNullable) {\n return ZodNullable.create(deepPartialify(schema.unwrap()));\n }\n else if (schema instanceof ZodTuple) {\n return ZodTuple.create(schema.items.map((item) => deepPartialify(item)));\n }\n else {\n return schema;\n }\n}\nexport class ZodObject extends ZodType {\n constructor() {\n super(...arguments);\n this._cached = null;\n /**\n * @deprecated In most cases, this is no longer needed - unknown properties are now silently stripped.\n * If you want to pass through unknown properties, use `.passthrough()` instead.\n */\n this.nonstrict = this.passthrough;\n // extend<\n // Augmentation extends ZodRawShape,\n // NewOutput extends util.flatten<{\n // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation\n // ? Augmentation[k][\"_output\"]\n // : k extends keyof Output\n // ? Output[k]\n // : never;\n // }>,\n // NewInput extends util.flatten<{\n // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation\n // ? Augmentation[k][\"_input\"]\n // : k extends keyof Input\n // ? Input[k]\n // : never;\n // }>\n // >(\n // augmentation: Augmentation\n // ): ZodObject<\n // extendShape<T, Augmentation>,\n // UnknownKeys,\n // Catchall,\n // NewOutput,\n // NewInput\n // > {\n // return new ZodObject({\n // ...this._def,\n // shape: () => ({\n // ...this._def.shape(),\n // ...augmentation,\n // }),\n // }) as any;\n // }\n /**\n * @deprecated Use `.extend` instead\n * */\n this.augment = this.extend;\n }\n _getCached() {\n if (this._cached !== null)\n return this._cached;\n const shape = this._def.shape();\n const keys = util.objectKeys(shape);\n this._cached = { shape, keys };\n return this._cached;\n }\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.object) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.object,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const { status, ctx } = this._processInputParams(input);\n const { shape, keys: shapeKeys } = this._getCached();\n const extraKeys = [];\n if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === \"strip\")) {\n for (const key in ctx.data) {\n if (!shapeKeys.includes(key)) {\n extraKeys.push(key);\n }\n }\n }\n const pairs = [];\n for (const key of shapeKeys) {\n const keyValidator = shape[key];\n const value = ctx.data[key];\n pairs.push({\n key: { status: \"valid\", value: key },\n value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)),\n alwaysSet: key in ctx.data,\n });\n }\n if (this._def.catchall instanceof ZodNever) {\n const unknownKeys = this._def.unknownKeys;\n if (unknownKeys === \"passthrough\") {\n for (const key of extraKeys) {\n pairs.push({\n key: { status: \"valid\", value: key },\n value: { status: \"valid\", value: ctx.data[key] },\n });\n }\n }\n else if (unknownKeys === \"strict\") {\n if (extraKeys.length > 0) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.unrecognized_keys,\n keys: extraKeys,\n });\n status.dirty();\n }\n }\n else if (unknownKeys === \"strip\") {\n }\n else {\n throw new Error(`Internal ZodObject error: invalid unknownKeys value.`);\n }\n }\n else {\n // run catchall validation\n const catchall = this._def.catchall;\n for (const key of extraKeys) {\n const value = ctx.data[key];\n pairs.push({\n key: { status: \"valid\", value: key },\n value: catchall._parse(new ParseInputLazyPath(ctx, value, ctx.path, key) //, ctx.child(key), value, getParsedType(value)\n ),\n alwaysSet: key in ctx.data,\n });\n }\n }\n if (ctx.common.async) {\n return Promise.resolve()\n .then(async () => {\n const syncPairs = [];\n for (const pair of pairs) {\n const key = await pair.key;\n const value = await pair.value;\n syncPairs.push({\n key,\n value,\n alwaysSet: pair.alwaysSet,\n });\n }\n return syncPairs;\n })\n .then((syncPairs) => {\n return ParseStatus.mergeObjectSync(status, syncPairs);\n });\n }\n else {\n return ParseStatus.mergeObjectSync(status, pairs);\n }\n }\n get shape() {\n return this._def.shape();\n }\n strict(message) {\n errorUtil.errToObj;\n return new ZodObject({\n ...this._def,\n unknownKeys: \"strict\",\n ...(message !== undefined\n ? {\n errorMap: (issue, ctx) => {\n const defaultError = this._def.errorMap?.(issue, ctx).message ?? ctx.defaultError;\n if (issue.code === \"unrecognized_keys\")\n return {\n message: errorUtil.errToObj(message).message ?? defaultError,\n };\n return {\n message: defaultError,\n };\n },\n }\n : {}),\n });\n }\n strip() {\n return new ZodObject({\n ...this._def,\n unknownKeys: \"strip\",\n });\n }\n passthrough() {\n return new ZodObject({\n ...this._def,\n unknownKeys: \"passthrough\",\n });\n }\n // const AugmentFactory =\n // <Def extends ZodObjectDef>(def: Def) =>\n // <Augmentation extends ZodRawShape>(\n // augmentation: Augmentation\n // ): ZodObject<\n // extendShape<ReturnType<Def[\"shape\"]>, Augmentation>,\n // Def[\"unknownKeys\"],\n // Def[\"catchall\"]\n // > => {\n // return new ZodObject({\n // ...def,\n // shape: () => ({\n // ...def.shape(),\n // ...augmentation,\n // }),\n // }) as any;\n // };\n extend(augmentation) {\n return new ZodObject({\n ...this._def,\n shape: () => ({\n ...this._def.shape(),\n ...augmentation,\n }),\n });\n }\n /**\n * Prior to zod@1.0.12 there was a bug in the\n * inferred type of merged objects. Please\n * upgrade if you are experiencing issues.\n */\n merge(merging) {\n const merged = new ZodObject({\n unknownKeys: merging._def.unknownKeys,\n catchall: merging._def.catchall,\n shape: () => ({\n ...this._def.shape(),\n ...merging._def.shape(),\n }),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n });\n return merged;\n }\n // merge<\n // Incoming extends AnyZodObject,\n // Augmentation extends Incoming[\"shape\"],\n // NewOutput extends {\n // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation\n // ? Augmentation[k][\"_output\"]\n // : k extends keyof Output\n // ? Output[k]\n // : never;\n // },\n // NewInput extends {\n // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation\n // ? Augmentation[k][\"_input\"]\n // : k extends keyof Input\n // ? Input[k]\n // : never;\n // }\n // >(\n // merging: Incoming\n // ): ZodObject<\n // extendShape<T, ReturnType<Incoming[\"_def\"][\"shape\"]>>,\n // Incoming[\"_def\"][\"unknownKeys\"],\n // Incoming[\"_def\"][\"catchall\"],\n // NewOutput,\n // NewInput\n // > {\n // const merged: any = new ZodObject({\n // unknownKeys: merging._def.unknownKeys,\n // catchall: merging._def.catchall,\n // shape: () =>\n // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),\n // typeName: ZodFirstPartyTypeKind.ZodObject,\n // }) as any;\n // return merged;\n // }\n setKey(key, schema) {\n return this.augment({ [key]: schema });\n }\n // merge<Incoming extends AnyZodObject>(\n // merging: Incoming\n // ): //ZodObject<T & Incoming[\"_shape\"], UnknownKeys, Catchall> = (merging) => {\n // ZodObject<\n // extendShape<T, ReturnType<Incoming[\"_def\"][\"shape\"]>>,\n // Incoming[\"_def\"][\"unknownKeys\"],\n // Incoming[\"_def\"][\"catchall\"]\n // > {\n // // const mergedShape = objectUtil.mergeShapes(\n // // this._def.shape(),\n // // merging._def.shape()\n // // );\n // const merged: any = new ZodObject({\n // unknownKeys: merging._def.unknownKeys,\n // catchall: merging._def.catchall,\n // shape: () =>\n // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),\n // typeName: ZodFirstPartyTypeKind.ZodObject,\n // }) as any;\n // return merged;\n // }\n catchall(index) {\n return new ZodObject({\n ...this._def,\n catchall: index,\n });\n }\n pick(mask) {\n const shape = {};\n for (const key of util.objectKeys(mask)) {\n if (mask[key] && this.shape[key]) {\n shape[key] = this.shape[key];\n }\n }\n return new ZodObject({\n ...this._def,\n shape: () => shape,\n });\n }\n omit(mask) {\n const shape = {};\n for (const key of util.objectKeys(this.shape)) {\n if (!mask[key]) {\n shape[key] = this.shape[key];\n }\n }\n return new ZodObject({\n ...this._def,\n shape: () => shape,\n });\n }\n /**\n * @deprecated\n */\n deepPartial() {\n return deepPartialify(this);\n }\n partial(mask) {\n const newShape = {};\n for (const key of util.objectKeys(this.shape)) {\n const fieldSchema = this.shape[key];\n if (mask && !mask[key]) {\n newShape[key] = fieldSchema;\n }\n else {\n newShape[key] = fieldSchema.optional();\n }\n }\n return new ZodObject({\n ...this._def,\n shape: () => newShape,\n });\n }\n required(mask) {\n const newShape = {};\n for (const key of util.objectKeys(this.shape)) {\n if (mask && !mask[key]) {\n newShape[key] = this.shape[key];\n }\n else {\n const fieldSchema = this.shape[key];\n let newField = fieldSchema;\n while (newField instanceof ZodOptional) {\n newField = newField._def.innerType;\n }\n newShape[key] = newField;\n }\n }\n return new ZodObject({\n ...this._def,\n shape: () => newShape,\n });\n }\n keyof() {\n return createZodEnum(util.objectKeys(this.shape));\n }\n}\nZodObject.create = (shape, params) => {\n return new ZodObject({\n shape: () => shape,\n unknownKeys: \"strip\",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params),\n });\n};\nZodObject.strictCreate = (shape, params) => {\n return new ZodObject({\n shape: () => shape,\n unknownKeys: \"strict\",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params),\n });\n};\nZodObject.lazycreate = (shape, params) => {\n return new ZodObject({\n shape,\n unknownKeys: \"strip\",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params),\n });\n};\nexport class ZodUnion extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const options = this._def.options;\n function handleResults(results) {\n // return first issue-free validation if it exists\n for (const result of results) {\n if (result.result.status === \"valid\") {\n return result.result;\n }\n }\n for (const result of results) {\n if (result.result.status === \"dirty\") {\n // add issues from dirty option\n ctx.common.issues.push(...result.ctx.common.issues);\n return result.result;\n }\n }\n // return invalid\n const unionErrors = results.map((result) => new ZodError(result.ctx.common.issues));\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_union,\n unionErrors,\n });\n return INVALID;\n }\n if (ctx.common.async) {\n return Promise.all(options.map(async (option) => {\n const childCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: [],\n },\n parent: null,\n };\n return {\n result: await option._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: childCtx,\n }),\n ctx: childCtx,\n };\n })).then(handleResults);\n }\n else {\n let dirty = undefined;\n const issues = [];\n for (const option of options) {\n const childCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: [],\n },\n parent: null,\n };\n const result = option._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: childCtx,\n });\n if (result.status === \"valid\") {\n return result;\n }\n else if (result.status === \"dirty\" && !dirty) {\n dirty = { result, ctx: childCtx };\n }\n if (childCtx.common.issues.length) {\n issues.push(childCtx.common.issues);\n }\n }\n if (dirty) {\n ctx.common.issues.push(...dirty.ctx.common.issues);\n return dirty.result;\n }\n const unionErrors = issues.map((issues) => new ZodError(issues));\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_union,\n unionErrors,\n });\n return INVALID;\n }\n }\n get options() {\n return this._def.options;\n }\n}\nZodUnion.create = (types, params) => {\n return new ZodUnion({\n options: types,\n typeName: ZodFirstPartyTypeKind.ZodUnion,\n ...processCreateParams(params),\n });\n};\n/////////////////////////////////////////////////////\n/////////////////////////////////////////////////////\n////////// //////////\n////////// ZodDiscriminatedUnion //////////\n////////// //////////\n/////////////////////////////////////////////////////\n/////////////////////////////////////////////////////\nconst getDiscriminator = (type) => {\n if (type instanceof ZodLazy) {\n return getDiscriminator(type.schema);\n }\n else if (type instanceof ZodEffects) {\n return getDiscriminator(type.innerType());\n }\n else if (type instanceof ZodLiteral) {\n return [type.value];\n }\n else if (type instanceof ZodEnum) {\n return type.options;\n }\n else if (type instanceof ZodNativeEnum) {\n // eslint-disable-next-line ban/ban\n return util.objectValues(type.enum);\n }\n else if (type instanceof ZodDefault) {\n return getDiscriminator(type._def.innerType);\n }\n else if (type instanceof ZodUndefined) {\n return [undefined];\n }\n else if (type instanceof ZodNull) {\n return [null];\n }\n else if (type instanceof ZodOptional) {\n return [undefined, ...getDiscriminator(type.unwrap())];\n }\n else if (type instanceof ZodNullable) {\n return [null, ...getDiscriminator(type.unwrap())];\n }\n else if (type instanceof ZodBranded) {\n return getDiscriminator(type.unwrap());\n }\n else if (type instanceof ZodReadonly) {\n return getDiscriminator(type.unwrap());\n }\n else if (type instanceof ZodCatch) {\n return getDiscriminator(type._def.innerType);\n }\n else {\n return [];\n }\n};\nexport class ZodDiscriminatedUnion extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.object) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.object,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const discriminator = this.discriminator;\n const discriminatorValue = ctx.data[discriminator];\n const option = this.optionsMap.get(discriminatorValue);\n if (!option) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_union_discriminator,\n options: Array.from(this.optionsMap.keys()),\n path: [discriminator],\n });\n return INVALID;\n }\n if (ctx.common.async) {\n return option._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n }\n else {\n return option._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n }\n }\n get discriminator() {\n return this._def.discriminator;\n }\n get options() {\n return this._def.options;\n }\n get optionsMap() {\n return this._def.optionsMap;\n }\n /**\n * The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor.\n * However, it only allows a union of objects, all of which need to share a discriminator property. This property must\n * have a different value for each object in the union.\n * @param discriminator the name of the discriminator property\n * @param types an array of object schemas\n * @param params\n */\n static create(discriminator, options, params) {\n // Get all the valid discriminator values\n const optionsMap = new Map();\n // try {\n for (const type of options) {\n const discriminatorValues = getDiscriminator(type.shape[discriminator]);\n if (!discriminatorValues.length) {\n throw new Error(`A discriminator value for key \\`${discriminator}\\` could not be extracted from all schema options`);\n }\n for (const value of discriminatorValues) {\n if (optionsMap.has(value)) {\n throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`);\n }\n optionsMap.set(value, type);\n }\n }\n return new ZodDiscriminatedUnion({\n typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion,\n discriminator,\n options,\n optionsMap,\n ...processCreateParams(params),\n });\n }\n}\nfunction mergeValues(a, b) {\n const aType = getParsedType(a);\n const bType = getParsedType(b);\n if (a === b) {\n return { valid: true, data: a };\n }\n else if (aType === ZodParsedType.object && bType === ZodParsedType.object) {\n const bKeys = util.objectKeys(b);\n const sharedKeys = util.objectKeys(a).filter((key) => bKeys.indexOf(key) !== -1);\n const newObj = { ...a, ...b };\n for (const key of sharedKeys) {\n const sharedValue = mergeValues(a[key], b[key]);\n if (!sharedValue.valid) {\n return { valid: false };\n }\n newObj[key] = sharedValue.data;\n }\n return { valid: true, data: newObj };\n }\n else if (aType === ZodParsedType.array && bType === ZodParsedType.array) {\n if (a.length !== b.length) {\n return { valid: false };\n }\n const newArray = [];\n for (let index = 0; index < a.length; index++) {\n const itemA = a[index];\n const itemB = b[index];\n const sharedValue = mergeValues(itemA, itemB);\n if (!sharedValue.valid) {\n return { valid: false };\n }\n newArray.push(sharedValue.data);\n }\n return { valid: true, data: newArray };\n }\n else if (aType === ZodParsedType.date && bType === ZodParsedType.date && +a === +b) {\n return { valid: true, data: a };\n }\n else {\n return { valid: false };\n }\n}\nexport class ZodIntersection extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n const handleParsed = (parsedLeft, parsedRight) => {\n if (isAborted(parsedLeft) || isAborted(parsedRight)) {\n return INVALID;\n }\n const merged = mergeValues(parsedLeft.value, parsedRight.value);\n if (!merged.valid) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_intersection_types,\n });\n return INVALID;\n }\n if (isDirty(parsedLeft) || isDirty(parsedRight)) {\n status.dirty();\n }\n return { status: status.value, value: merged.data };\n };\n if (ctx.common.async) {\n return Promise.all([\n this._def.left._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }),\n this._def.right._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }),\n ]).then(([left, right]) => handleParsed(left, right));\n }\n else {\n return handleParsed(this._def.left._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }), this._def.right._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }));\n }\n }\n}\nZodIntersection.create = (left, right, params) => {\n return new ZodIntersection({\n left: left,\n right: right,\n typeName: ZodFirstPartyTypeKind.ZodIntersection,\n ...processCreateParams(params),\n });\n};\n// type ZodTupleItems = [ZodTypeAny, ...ZodTypeAny[]];\nexport class ZodTuple extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.array) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.array,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n if (ctx.data.length < this._def.items.length) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: this._def.items.length,\n inclusive: true,\n exact: false,\n type: \"array\",\n });\n return INVALID;\n }\n const rest = this._def.rest;\n if (!rest && ctx.data.length > this._def.items.length) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: this._def.items.length,\n inclusive: true,\n exact: false,\n type: \"array\",\n });\n status.dirty();\n }\n const items = [...ctx.data]\n .map((item, itemIndex) => {\n const schema = this._def.items[itemIndex] || this._def.rest;\n if (!schema)\n return null;\n return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex));\n })\n .filter((x) => !!x); // filter nulls\n if (ctx.common.async) {\n return Promise.all(items).then((results) => {\n return ParseStatus.mergeArray(status, results);\n });\n }\n else {\n return ParseStatus.mergeArray(status, items);\n }\n }\n get items() {\n return this._def.items;\n }\n rest(rest) {\n return new ZodTuple({\n ...this._def,\n rest,\n });\n }\n}\nZodTuple.create = (schemas, params) => {\n if (!Array.isArray(schemas)) {\n throw new Error(\"You must pass an array of schemas to z.tuple([ ... ])\");\n }\n return new ZodTuple({\n items: schemas,\n typeName: ZodFirstPartyTypeKind.ZodTuple,\n rest: null,\n ...processCreateParams(params),\n });\n};\nexport class ZodRecord extends ZodType {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.object) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.object,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const pairs = [];\n const keyType = this._def.keyType;\n const valueType = this._def.valueType;\n for (const key in ctx.data) {\n pairs.push({\n key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)),\n value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)),\n alwaysSet: key in ctx.data,\n });\n }\n if (ctx.common.async) {\n return ParseStatus.mergeObjectAsync(status, pairs);\n }\n else {\n return ParseStatus.mergeObjectSync(status, pairs);\n }\n }\n get element() {\n return this._def.valueType;\n }\n static create(first, second, third) {\n if (second instanceof ZodType) {\n return new ZodRecord({\n keyType: first,\n valueType: second,\n typeName: ZodFirstPartyTypeKind.ZodRecord,\n ...processCreateParams(third),\n });\n }\n return new ZodRecord({\n keyType: ZodString.create(),\n valueType: first,\n typeName: ZodFirstPartyTypeKind.ZodRecord,\n ...processCreateParams(second),\n });\n }\n}\nexport class ZodMap extends ZodType {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.map) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.map,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const keyType = this._def.keyType;\n const valueType = this._def.valueType;\n const pairs = [...ctx.data.entries()].map(([key, value], index) => {\n return {\n key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, \"key\"])),\n value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, \"value\"])),\n };\n });\n if (ctx.common.async) {\n const finalMap = new Map();\n return Promise.resolve().then(async () => {\n for (const pair of pairs) {\n const key = await pair.key;\n const value = await pair.value;\n if (key.status === \"aborted\" || value.status === \"aborted\") {\n return INVALID;\n }\n if (key.status === \"dirty\" || value.status === \"dirty\") {\n status.dirty();\n }\n finalMap.set(key.value, value.value);\n }\n return { status: status.value, value: finalMap };\n });\n }\n else {\n const finalMap = new Map();\n for (const pair of pairs) {\n const key = pair.key;\n const value = pair.value;\n if (key.status === \"aborted\" || value.status === \"aborted\") {\n return INVALID;\n }\n if (key.status === \"dirty\" || value.status === \"dirty\") {\n status.dirty();\n }\n finalMap.set(key.value, value.value);\n }\n return { status: status.value, value: finalMap };\n }\n }\n}\nZodMap.create = (keyType, valueType, params) => {\n return new ZodMap({\n valueType,\n keyType,\n typeName: ZodFirstPartyTypeKind.ZodMap,\n ...processCreateParams(params),\n });\n};\nexport class ZodSet extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.set) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.set,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const def = this._def;\n if (def.minSize !== null) {\n if (ctx.data.size < def.minSize.value) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: def.minSize.value,\n type: \"set\",\n inclusive: true,\n exact: false,\n message: def.minSize.message,\n });\n status.dirty();\n }\n }\n if (def.maxSize !== null) {\n if (ctx.data.size > def.maxSize.value) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: def.maxSize.value,\n type: \"set\",\n inclusive: true,\n exact: false,\n message: def.maxSize.message,\n });\n status.dirty();\n }\n }\n const valueType = this._def.valueType;\n function finalizeSet(elements) {\n const parsedSet = new Set();\n for (const element of elements) {\n if (element.status === \"aborted\")\n return INVALID;\n if (element.status === \"dirty\")\n status.dirty();\n parsedSet.add(element.value);\n }\n return { status: status.value, value: parsedSet };\n }\n const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)));\n if (ctx.common.async) {\n return Promise.all(elements).then((elements) => finalizeSet(elements));\n }\n else {\n return finalizeSet(elements);\n }\n }\n min(minSize, message) {\n return new ZodSet({\n ...this._def,\n minSize: { value: minSize, message: errorUtil.toString(message) },\n });\n }\n max(maxSize, message) {\n return new ZodSet({\n ...this._def,\n maxSize: { value: maxSize, message: errorUtil.toString(message) },\n });\n }\n size(size, message) {\n return this.min(size, message).max(size, message);\n }\n nonempty(message) {\n return this.min(1, message);\n }\n}\nZodSet.create = (valueType, params) => {\n return new ZodSet({\n valueType,\n minSize: null,\n maxSize: null,\n typeName: ZodFirstPartyTypeKind.ZodSet,\n ...processCreateParams(params),\n });\n};\nexport class ZodFunction extends ZodType {\n constructor() {\n super(...arguments);\n this.validate = this.implement;\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.function) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.function,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n function makeArgsIssue(args, error) {\n return makeIssue({\n data: args,\n path: ctx.path,\n errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, getErrorMap(), defaultErrorMap].filter((x) => !!x),\n issueData: {\n code: ZodIssueCode.invalid_arguments,\n argumentsError: error,\n },\n });\n }\n function makeReturnsIssue(returns, error) {\n return makeIssue({\n data: returns,\n path: ctx.path,\n errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, getErrorMap(), defaultErrorMap].filter((x) => !!x),\n issueData: {\n code: ZodIssueCode.invalid_return_type,\n returnTypeError: error,\n },\n });\n }\n const params = { errorMap: ctx.common.contextualErrorMap };\n const fn = ctx.data;\n if (this._def.returns instanceof ZodPromise) {\n // Would love a way to avoid disabling this rule, but we need\n // an alias (using an arrow function was what caused 2651).\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const me = this;\n return OK(async function (...args) {\n const error = new ZodError([]);\n const parsedArgs = await me._def.args.parseAsync(args, params).catch((e) => {\n error.addIssue(makeArgsIssue(args, e));\n throw error;\n });\n const result = await Reflect.apply(fn, this, parsedArgs);\n const parsedReturns = await me._def.returns._def.type\n .parseAsync(result, params)\n .catch((e) => {\n error.addIssue(makeReturnsIssue(result, e));\n throw error;\n });\n return parsedReturns;\n });\n }\n else {\n // Would love a way to avoid disabling this rule, but we need\n // an alias (using an arrow function was what caused 2651).\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const me = this;\n return OK(function (...args) {\n const parsedArgs = me._def.args.safeParse(args, params);\n if (!parsedArgs.success) {\n throw new ZodError([makeArgsIssue(args, parsedArgs.error)]);\n }\n const result = Reflect.apply(fn, this, parsedArgs.data);\n const parsedReturns = me._def.returns.safeParse(result, params);\n if (!parsedReturns.success) {\n throw new ZodError([makeReturnsIssue(result, parsedReturns.error)]);\n }\n return parsedReturns.data;\n });\n }\n }\n parameters() {\n return this._def.args;\n }\n returnType() {\n return this._def.returns;\n }\n args(...items) {\n return new ZodFunction({\n ...this._def,\n args: ZodTuple.create(items).rest(ZodUnknown.create()),\n });\n }\n returns(returnType) {\n return new ZodFunction({\n ...this._def,\n returns: returnType,\n });\n }\n implement(func) {\n const validatedFunc = this.parse(func);\n return validatedFunc;\n }\n strictImplement(func) {\n const validatedFunc = this.parse(func);\n return validatedFunc;\n }\n static create(args, returns, params) {\n return new ZodFunction({\n args: (args ? args : ZodTuple.create([]).rest(ZodUnknown.create())),\n returns: returns || ZodUnknown.create(),\n typeName: ZodFirstPartyTypeKind.ZodFunction,\n ...processCreateParams(params),\n });\n }\n}\nexport class ZodLazy extends ZodType {\n get schema() {\n return this._def.getter();\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const lazySchema = this._def.getter();\n return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx });\n }\n}\nZodLazy.create = (getter, params) => {\n return new ZodLazy({\n getter: getter,\n typeName: ZodFirstPartyTypeKind.ZodLazy,\n ...processCreateParams(params),\n });\n};\nexport class ZodLiteral extends ZodType {\n _parse(input) {\n if (input.data !== this._def.value) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n received: ctx.data,\n code: ZodIssueCode.invalid_literal,\n expected: this._def.value,\n });\n return INVALID;\n }\n return { status: \"valid\", value: input.data };\n }\n get value() {\n return this._def.value;\n }\n}\nZodLiteral.create = (value, params) => {\n return new ZodLiteral({\n value: value,\n typeName: ZodFirstPartyTypeKind.ZodLiteral,\n ...processCreateParams(params),\n });\n};\nfunction createZodEnum(values, params) {\n return new ZodEnum({\n values,\n typeName: ZodFirstPartyTypeKind.ZodEnum,\n ...processCreateParams(params),\n });\n}\nexport class ZodEnum extends ZodType {\n _parse(input) {\n if (typeof input.data !== \"string\") {\n const ctx = this._getOrReturnCtx(input);\n const expectedValues = this._def.values;\n addIssueToContext(ctx, {\n expected: util.joinValues(expectedValues),\n received: ctx.parsedType,\n code: ZodIssueCode.invalid_type,\n });\n return INVALID;\n }\n if (!this._cache) {\n this._cache = new Set(this._def.values);\n }\n if (!this._cache.has(input.data)) {\n const ctx = this._getOrReturnCtx(input);\n const expectedValues = this._def.values;\n addIssueToContext(ctx, {\n received: ctx.data,\n code: ZodIssueCode.invalid_enum_value,\n options: expectedValues,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n get options() {\n return this._def.values;\n }\n get enum() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n get Values() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n get Enum() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n extract(values, newDef = this._def) {\n return ZodEnum.create(values, {\n ...this._def,\n ...newDef,\n });\n }\n exclude(values, newDef = this._def) {\n return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)), {\n ...this._def,\n ...newDef,\n });\n }\n}\nZodEnum.create = createZodEnum;\nexport class ZodNativeEnum extends ZodType {\n _parse(input) {\n const nativeEnumValues = util.getValidEnumValues(this._def.values);\n const ctx = this._getOrReturnCtx(input);\n if (ctx.parsedType !== ZodParsedType.string && ctx.parsedType !== ZodParsedType.number) {\n const expectedValues = util.objectValues(nativeEnumValues);\n addIssueToContext(ctx, {\n expected: util.joinValues(expectedValues),\n received: ctx.parsedType,\n code: ZodIssueCode.invalid_type,\n });\n return INVALID;\n }\n if (!this._cache) {\n this._cache = new Set(util.getValidEnumValues(this._def.values));\n }\n if (!this._cache.has(input.data)) {\n const expectedValues = util.objectValues(nativeEnumValues);\n addIssueToContext(ctx, {\n received: ctx.data,\n code: ZodIssueCode.invalid_enum_value,\n options: expectedValues,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n get enum() {\n return this._def.values;\n }\n}\nZodNativeEnum.create = (values, params) => {\n return new ZodNativeEnum({\n values: values,\n typeName: ZodFirstPartyTypeKind.ZodNativeEnum,\n ...processCreateParams(params),\n });\n};\nexport class ZodPromise extends ZodType {\n unwrap() {\n return this._def.type;\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.promise && ctx.common.async === false) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.promise,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const promisified = ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data);\n return OK(promisified.then((data) => {\n return this._def.type.parseAsync(data, {\n path: ctx.path,\n errorMap: ctx.common.contextualErrorMap,\n });\n }));\n }\n}\nZodPromise.create = (schema, params) => {\n return new ZodPromise({\n type: schema,\n typeName: ZodFirstPartyTypeKind.ZodPromise,\n ...processCreateParams(params),\n });\n};\nexport class ZodEffects extends ZodType {\n innerType() {\n return this._def.schema;\n }\n sourceType() {\n return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects\n ? this._def.schema.sourceType()\n : this._def.schema;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n const effect = this._def.effect || null;\n const checkCtx = {\n addIssue: (arg) => {\n addIssueToContext(ctx, arg);\n if (arg.fatal) {\n status.abort();\n }\n else {\n status.dirty();\n }\n },\n get path() {\n return ctx.path;\n },\n };\n checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);\n if (effect.type === \"preprocess\") {\n const processed = effect.transform(ctx.data, checkCtx);\n if (ctx.common.async) {\n return Promise.resolve(processed).then(async (processed) => {\n if (status.value === \"aborted\")\n return INVALID;\n const result = await this._def.schema._parseAsync({\n data: processed,\n path: ctx.path,\n parent: ctx,\n });\n if (result.status === \"aborted\")\n return INVALID;\n if (result.status === \"dirty\")\n return DIRTY(result.value);\n if (status.value === \"dirty\")\n return DIRTY(result.value);\n return result;\n });\n }\n else {\n if (status.value === \"aborted\")\n return INVALID;\n const result = this._def.schema._parseSync({\n data: processed,\n path: ctx.path,\n parent: ctx,\n });\n if (result.status === \"aborted\")\n return INVALID;\n if (result.status === \"dirty\")\n return DIRTY(result.value);\n if (status.value === \"dirty\")\n return DIRTY(result.value);\n return result;\n }\n }\n if (effect.type === \"refinement\") {\n const executeRefinement = (acc) => {\n const result = effect.refinement(acc, checkCtx);\n if (ctx.common.async) {\n return Promise.resolve(result);\n }\n if (result instanceof Promise) {\n throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");\n }\n return acc;\n };\n if (ctx.common.async === false) {\n const inner = this._def.schema._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (inner.status === \"aborted\")\n return INVALID;\n if (inner.status === \"dirty\")\n status.dirty();\n // return value is ignored\n executeRefinement(inner.value);\n return { status: status.value, value: inner.value };\n }\n else {\n return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => {\n if (inner.status === \"aborted\")\n return INVALID;\n if (inner.status === \"dirty\")\n status.dirty();\n return executeRefinement(inner.value).then(() => {\n return { status: status.value, value: inner.value };\n });\n });\n }\n }\n if (effect.type === \"transform\") {\n if (ctx.common.async === false) {\n const base = this._def.schema._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (!isValid(base))\n return INVALID;\n const result = effect.transform(base.value, checkCtx);\n if (result instanceof Promise) {\n throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);\n }\n return { status: status.value, value: result };\n }\n else {\n return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {\n if (!isValid(base))\n return INVALID;\n return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({\n status: status.value,\n value: result,\n }));\n });\n }\n }\n util.assertNever(effect);\n }\n}\nZodEffects.create = (schema, effect, params) => {\n return new ZodEffects({\n schema,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect,\n ...processCreateParams(params),\n });\n};\nZodEffects.createWithPreprocess = (preprocess, schema, params) => {\n return new ZodEffects({\n schema,\n effect: { type: \"preprocess\", transform: preprocess },\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n ...processCreateParams(params),\n });\n};\nexport { ZodEffects as ZodTransformer };\nexport class ZodOptional extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType === ZodParsedType.undefined) {\n return OK(undefined);\n }\n return this._def.innerType._parse(input);\n }\n unwrap() {\n return this._def.innerType;\n }\n}\nZodOptional.create = (type, params) => {\n return new ZodOptional({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodOptional,\n ...processCreateParams(params),\n });\n};\nexport class ZodNullable extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType === ZodParsedType.null) {\n return OK(null);\n }\n return this._def.innerType._parse(input);\n }\n unwrap() {\n return this._def.innerType;\n }\n}\nZodNullable.create = (type, params) => {\n return new ZodNullable({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodNullable,\n ...processCreateParams(params),\n });\n};\nexport class ZodDefault extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n let data = ctx.data;\n if (ctx.parsedType === ZodParsedType.undefined) {\n data = this._def.defaultValue();\n }\n return this._def.innerType._parse({\n data,\n path: ctx.path,\n parent: ctx,\n });\n }\n removeDefault() {\n return this._def.innerType;\n }\n}\nZodDefault.create = (type, params) => {\n return new ZodDefault({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodDefault,\n defaultValue: typeof params.default === \"function\" ? params.default : () => params.default,\n ...processCreateParams(params),\n });\n};\nexport class ZodCatch extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n // newCtx is used to not collect issues from inner types in ctx\n const newCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: [],\n },\n };\n const result = this._def.innerType._parse({\n data: newCtx.data,\n path: newCtx.path,\n parent: {\n ...newCtx,\n },\n });\n if (isAsync(result)) {\n return result.then((result) => {\n return {\n status: \"valid\",\n value: result.status === \"valid\"\n ? result.value\n : this._def.catchValue({\n get error() {\n return new ZodError(newCtx.common.issues);\n },\n input: newCtx.data,\n }),\n };\n });\n }\n else {\n return {\n status: \"valid\",\n value: result.status === \"valid\"\n ? result.value\n : this._def.catchValue({\n get error() {\n return new ZodError(newCtx.common.issues);\n },\n input: newCtx.data,\n }),\n };\n }\n }\n removeCatch() {\n return this._def.innerType;\n }\n}\nZodCatch.create = (type, params) => {\n return new ZodCatch({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodCatch,\n catchValue: typeof params.catch === \"function\" ? params.catch : () => params.catch,\n ...processCreateParams(params),\n });\n};\nexport class ZodNaN extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.nan) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.nan,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n return { status: \"valid\", value: input.data };\n }\n}\nZodNaN.create = (params) => {\n return new ZodNaN({\n typeName: ZodFirstPartyTypeKind.ZodNaN,\n ...processCreateParams(params),\n });\n};\nexport const BRAND = Symbol(\"zod_brand\");\nexport class ZodBranded extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const data = ctx.data;\n return this._def.type._parse({\n data,\n path: ctx.path,\n parent: ctx,\n });\n }\n unwrap() {\n return this._def.type;\n }\n}\nexport class ZodPipeline extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.common.async) {\n const handleAsync = async () => {\n const inResult = await this._def.in._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (inResult.status === \"aborted\")\n return INVALID;\n if (inResult.status === \"dirty\") {\n status.dirty();\n return DIRTY(inResult.value);\n }\n else {\n return this._def.out._parseAsync({\n data: inResult.value,\n path: ctx.path,\n parent: ctx,\n });\n }\n };\n return handleAsync();\n }\n else {\n const inResult = this._def.in._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (inResult.status === \"aborted\")\n return INVALID;\n if (inResult.status === \"dirty\") {\n status.dirty();\n return {\n status: \"dirty\",\n value: inResult.value,\n };\n }\n else {\n return this._def.out._parseSync({\n data: inResult.value,\n path: ctx.path,\n parent: ctx,\n });\n }\n }\n }\n static create(a, b) {\n return new ZodPipeline({\n in: a,\n out: b,\n typeName: ZodFirstPartyTypeKind.ZodPipeline,\n });\n }\n}\nexport class ZodReadonly extends ZodType {\n _parse(input) {\n const result = this._def.innerType._parse(input);\n const freeze = (data) => {\n if (isValid(data)) {\n data.value = Object.freeze(data.value);\n }\n return data;\n };\n return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result);\n }\n unwrap() {\n return this._def.innerType;\n }\n}\nZodReadonly.create = (type, params) => {\n return new ZodReadonly({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodReadonly,\n ...processCreateParams(params),\n });\n};\n////////////////////////////////////////\n////////////////////////////////////////\n////////// //////////\n////////// z.custom //////////\n////////// //////////\n////////////////////////////////////////\n////////////////////////////////////////\nfunction cleanParams(params, data) {\n const p = typeof params === \"function\" ? params(data) : typeof params === \"string\" ? { message: params } : params;\n const p2 = typeof p === \"string\" ? { message: p } : p;\n return p2;\n}\nexport function custom(check, _params = {}, \n/**\n * @deprecated\n *\n * Pass `fatal` into the params object instead:\n *\n * ```ts\n * z.string().custom((val) => val.length > 5, { fatal: false })\n * ```\n *\n */\nfatal) {\n if (check)\n return ZodAny.create().superRefine((data, ctx) => {\n const r = check(data);\n if (r instanceof Promise) {\n return r.then((r) => {\n if (!r) {\n const params = cleanParams(_params, data);\n const _fatal = params.fatal ?? fatal ?? true;\n ctx.addIssue({ code: \"custom\", ...params, fatal: _fatal });\n }\n });\n }\n if (!r) {\n const params = cleanParams(_params, data);\n const _fatal = params.fatal ?? fatal ?? true;\n ctx.addIssue({ code: \"custom\", ...params, fatal: _fatal });\n }\n return;\n });\n return ZodAny.create();\n}\nexport { ZodType as Schema, ZodType as ZodSchema };\nexport const late = {\n object: ZodObject.lazycreate,\n};\nexport var ZodFirstPartyTypeKind;\n(function (ZodFirstPartyTypeKind) {\n ZodFirstPartyTypeKind[\"ZodString\"] = \"ZodString\";\n ZodFirstPartyTypeKind[\"ZodNumber\"] = \"ZodNumber\";\n ZodFirstPartyTypeKind[\"ZodNaN\"] = \"ZodNaN\";\n ZodFirstPartyTypeKind[\"ZodBigInt\"] = \"ZodBigInt\";\n ZodFirstPartyTypeKind[\"ZodBoolean\"] = \"ZodBoolean\";\n ZodFirstPartyTypeKind[\"ZodDate\"] = \"ZodDate\";\n ZodFirstPartyTypeKind[\"ZodSymbol\"] = \"ZodSymbol\";\n ZodFirstPartyTypeKind[\"ZodUndefined\"] = \"ZodUndefined\";\n ZodFirstPartyTypeKind[\"ZodNull\"] = \"ZodNull\";\n ZodFirstPartyTypeKind[\"ZodAny\"] = \"ZodAny\";\n ZodFirstPartyTypeKind[\"ZodUnknown\"] = \"ZodUnknown\";\n ZodFirstPartyTypeKind[\"ZodNever\"] = \"ZodNever\";\n ZodFirstPartyTypeKind[\"ZodVoid\"] = \"ZodVoid\";\n ZodFirstPartyTypeKind[\"ZodArray\"] = \"ZodArray\";\n ZodFirstPartyTypeKind[\"ZodObject\"] = \"ZodObject\";\n ZodFirstPartyTypeKind[\"ZodUnion\"] = \"ZodUnion\";\n ZodFirstPartyTypeKind[\"ZodDiscriminatedUnion\"] = \"ZodDiscriminatedUnion\";\n ZodFirstPartyTypeKind[\"ZodIntersection\"] = \"ZodIntersection\";\n ZodFirstPartyTypeKind[\"ZodTuple\"] = \"ZodTuple\";\n ZodFirstPartyTypeKind[\"ZodRecord\"] = \"ZodRecord\";\n ZodFirstPartyTypeKind[\"ZodMap\"] = \"ZodMap\";\n ZodFirstPartyTypeKind[\"ZodSet\"] = \"ZodSet\";\n ZodFirstPartyTypeKind[\"ZodFunction\"] = \"ZodFunction\";\n ZodFirstPartyTypeKind[\"ZodLazy\"] = \"ZodLazy\";\n ZodFirstPartyTypeKind[\"ZodLiteral\"] = \"ZodLiteral\";\n ZodFirstPartyTypeKind[\"ZodEnum\"] = \"ZodEnum\";\n ZodFirstPartyTypeKind[\"ZodEffects\"] = \"ZodEffects\";\n ZodFirstPartyTypeKind[\"ZodNativeEnum\"] = \"ZodNativeEnum\";\n ZodFirstPartyTypeKind[\"ZodOptional\"] = \"ZodOptional\";\n ZodFirstPartyTypeKind[\"ZodNullable\"] = \"ZodNullable\";\n ZodFirstPartyTypeKind[\"ZodDefault\"] = \"ZodDefault\";\n ZodFirstPartyTypeKind[\"ZodCatch\"] = \"ZodCatch\";\n ZodFirstPartyTypeKind[\"ZodPromise\"] = \"ZodPromise\";\n ZodFirstPartyTypeKind[\"ZodBranded\"] = \"ZodBranded\";\n ZodFirstPartyTypeKind[\"ZodPipeline\"] = \"ZodPipeline\";\n ZodFirstPartyTypeKind[\"ZodReadonly\"] = \"ZodReadonly\";\n})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));\n// requires TS 4.4+\nclass Class {\n constructor(..._) { }\n}\nconst instanceOfType = (\n// const instanceOfType = <T extends new (...args: any[]) => any>(\ncls, params = {\n message: `Input not instance of ${cls.name}`,\n}) => custom((data) => data instanceof cls, params);\nconst stringType = ZodString.create;\nconst numberType = ZodNumber.create;\nconst nanType = ZodNaN.create;\nconst bigIntType = ZodBigInt.create;\nconst booleanType = ZodBoolean.create;\nconst dateType = ZodDate.create;\nconst symbolType = ZodSymbol.create;\nconst undefinedType = ZodUndefined.create;\nconst nullType = ZodNull.create;\nconst anyType = ZodAny.create;\nconst unknownType = ZodUnknown.create;\nconst neverType = ZodNever.create;\nconst voidType = ZodVoid.create;\nconst arrayType = ZodArray.create;\nconst objectType = ZodObject.create;\nconst strictObjectType = ZodObject.strictCreate;\nconst unionType = ZodUnion.create;\nconst discriminatedUnionType = ZodDiscriminatedUnion.create;\nconst intersectionType = ZodIntersection.create;\nconst tupleType = ZodTuple.create;\nconst recordType = ZodRecord.create;\nconst mapType = ZodMap.create;\nconst setType = ZodSet.create;\nconst functionType = ZodFunction.create;\nconst lazyType = ZodLazy.create;\nconst literalType = ZodLiteral.create;\nconst enumType = ZodEnum.create;\nconst nativeEnumType = ZodNativeEnum.create;\nconst promiseType = ZodPromise.create;\nconst effectsType = ZodEffects.create;\nconst optionalType = ZodOptional.create;\nconst nullableType = ZodNullable.create;\nconst preprocessType = ZodEffects.createWithPreprocess;\nconst pipelineType = ZodPipeline.create;\nconst ostring = () => stringType().optional();\nconst onumber = () => numberType().optional();\nconst oboolean = () => booleanType().optional();\nexport const coerce = {\n string: ((arg) => ZodString.create({ ...arg, coerce: true })),\n number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),\n boolean: ((arg) => ZodBoolean.create({\n ...arg,\n coerce: true,\n })),\n bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),\n date: ((arg) => ZodDate.create({ ...arg, coerce: true })),\n};\nexport { anyType as any, arrayType as array, bigIntType as bigint, booleanType as boolean, dateType as date, discriminatedUnionType as discriminatedUnion, effectsType as effect, enumType as enum, functionType as function, instanceOfType as instanceof, intersectionType as intersection, lazyType as lazy, literalType as literal, mapType as map, nanType as nan, nativeEnumType as nativeEnum, neverType as never, nullType as null, nullableType as nullable, numberType as number, objectType as object, oboolean, onumber, optionalType as optional, ostring, pipelineType as pipeline, preprocessType as preprocess, promiseType as promise, recordType as record, setType as set, strictObjectType as strictObject, stringType as string, symbolType as symbol, effectsType as transformer, tupleType as tuple, undefinedType as undefined, unionType as union, unknownType as unknown, voidType as void, };\nexport const NEVER = INVALID;\n","export * from \"./errors.js\";\nexport * from \"./helpers/parseUtil.js\";\nexport * from \"./helpers/typeAliases.js\";\nexport * from \"./helpers/util.js\";\nexport * from \"./types.js\";\nexport * from \"./ZodError.js\";\n","import * as z from \"./v3/external.js\";\nexport * from \"./v3/external.js\";\nexport { z };\nexport default z;\n","/**\n * Consistent error types for all WayAI workers\n * These provide structured error responses with proper HTTP status codes.\n */\n\n/**\n * Symbol brand for AppError identification across module boundaries.\n * Using Symbol.for() ensures the same symbol is used across all bundles,\n * solving the instanceof problem in monorepos.\n */\nconst APP_ERROR_BRAND = Symbol.for('wayai.AppError');\n\nexport class AppError extends Error {\n readonly [APP_ERROR_BRAND] = true;\n\n constructor(\n message: string,\n public code: string,\n public statusCode: number = 500,\n public details?: Record<string, unknown>\n ) {\n super(message);\n this.name = 'AppError';\n }\n\n toJSON() {\n return {\n error: this.code,\n message: this.message,\n ...(this.details && { details: this.details }),\n };\n }\n}\n\n/**\n * 400 - Bad Request: Invalid input data\n */\nexport class ValidationError extends AppError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, 'VALIDATION_ERROR', 400, details);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * 401 - Unauthorized: Authentication required\n */\nexport class AuthenticationError extends AppError {\n constructor(message = 'Authentication required') {\n super(message, 'AUTHENTICATION_ERROR', 401);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * 403 - Forbidden: Permission denied\n */\nexport class AuthorizationError extends AppError {\n constructor(message = 'Permission denied') {\n super(message, 'AUTHORIZATION_ERROR', 403);\n this.name = 'AuthorizationError';\n }\n}\n\n/**\n * 404 - Not Found: Resource doesn't exist\n */\nexport class NotFoundError extends AppError {\n readonly resource: string;\n constructor(resource: string) {\n super(`${resource} not found`, 'NOT_FOUND', 404);\n this.name = 'NotFoundError';\n this.resource = resource;\n }\n}\n\n/**\n * 409 - Conflict: Resource already exists or state conflict\n */\nexport class ConflictError extends AppError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, 'CONFLICT', 409, details);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * 429 - Too Many Requests: Rate limit exceeded\n */\nexport class RateLimitError extends AppError {\n constructor(retryAfter?: number) {\n super('Rate limit exceeded', 'RATE_LIMIT_EXCEEDED', 429, { retryAfter });\n this.name = 'RateLimitError';\n }\n}\n\n/**\n * Providers that can surface an upstream HTTP error or rate-limit. Typed (not\n * bare string) so adapter throw sites get typo protection.\n */\nexport type LlmProvider = 'anthropic' | 'openai' | 'openrouter' | 'gemini';\n\n/**\n * Internal control-flow signal: upstream LLM provider returned 429.\n * Caught in ConversationDO.handleProcess to reschedule the turn via the\n * local alarm instead of failing. Not an HTTP response — distinct from\n * the gateway-level RateLimitError above.\n */\nconst LLM_RATE_LIMIT_BRAND = Symbol.for('wayai.LlmRateLimitError');\n\nexport class LlmRateLimitError extends Error {\n readonly [LLM_RATE_LIMIT_BRAND] = true;\n\n constructor(\n public readonly provider: LlmProvider,\n public readonly retryAfterMs: number,\n ) {\n super(`${provider} rate limited; retry after ${retryAfterMs}ms`);\n this.name = 'LlmRateLimitError';\n }\n}\n\nexport function isLlmRateLimitError(error: unknown): error is LlmRateLimitError {\n return (\n typeof error === 'object' &&\n error !== null &&\n LLM_RATE_LIMIT_BRAND in error &&\n (error as Record<symbol, unknown>)[LLM_RATE_LIMIT_BRAND] === true\n );\n}\n\n/**\n * Internal signal: an upstream LLM provider returned a non-OK HTTP response\n * OTHER than 429 (429 is LlmRateLimitError — rescheduled, not failed). Carries\n * the HTTP status so the catch site can classify the failure.\n *\n * An upstream 4xx (401 invalid/revoked key, 403, 400) is almost always a\n * customer-credential/config problem — degraded-but-handled and surfaced to the\n * user — so it belongs at logger.warn (Loki only), NOT logger.error (Sentry →\n * autofix). A transient, retryable 503/529 (provider overloaded/unavailable)\n * reschedules the turn instead — see isRetryableLlmError (gh #2659). Other 5xx /\n * transport / our-own faults stay at error. Mirrors the MCP McpError +\n * isExternalMcpHttpError precedent (gh #2534, #2539).\n *\n * `message` keeps the adapter's existing human string (\"OpenAI API error: 401 -\n * …\") so callers/tests are unchanged; `status` + `provider` are the structured\n * fields the catch site logs. The catch site MUST log only those two — never the\n * message/body, which can embed a credential fragment (e.g. the OpenAI 401 body\n * \"Incorrect API key provided: sk-proj-…\").\n */\nconst LLM_PROVIDER_HTTP_BRAND = Symbol.for('wayai.LlmProviderHttpError');\n\nexport class LlmProviderHttpError extends Error {\n readonly [LLM_PROVIDER_HTTP_BRAND] = true;\n\n constructor(\n message: string,\n public readonly status: number,\n public readonly provider: LlmProvider,\n ) {\n super(message);\n this.name = 'LlmProviderHttpError';\n }\n}\n\nexport function isLlmProviderHttpError(error: unknown): error is LlmProviderHttpError {\n return (\n typeof error === 'object' &&\n error !== null &&\n LLM_PROVIDER_HTTP_BRAND in error &&\n (error as Record<symbol, unknown>)[LLM_PROVIDER_HTTP_BRAND] === true\n );\n}\n\nconst LLM_PROVIDER_DISPLAY_NAME: Record<LlmProvider, string> = {\n anthropic: 'Anthropic',\n openai: 'OpenAI',\n openrouter: 'OpenRouter',\n gemini: 'Gemini',\n};\n\n/**\n * Credential-safe, client-facing description of a failed LLM turn (gh #2670).\n *\n * Surfaced to the operator/CLI in place of an opaque `'Processing failed'` so a\n * provider rejection (e.g. Gemini 400/500 on an unsupported tool schema) is\n * self-diagnosable. Derived ONLY from the structured `status` + `provider` —\n * NEVER from `error.message`, which embeds the raw upstream body that can carry a\n * credential fragment (the same invariant that keeps the body out of Sentry).\n * Non-provider errors fall back to the generic string (no safe detail to add).\n */\nexport function describeLlmHttpErrorForClient(error: unknown): string {\n if (isLlmProviderHttpError(error)) {\n const provider = LLM_PROVIDER_DISPLAY_NAME[error.provider] ?? error.provider;\n return error.status >= 400 && error.status < 500\n ? `${provider} rejected the request (${error.status})`\n : `${provider} upstream error (${error.status})`;\n }\n return 'Processing failed';\n}\n\n/**\n * True when `error` is an upstream LLM provider 4xx — a client/auth error\n * (almost always a customer credential misconfiguration). These belong at\n * logger.warn (Loki), NOT logger.error (Sentry). gh #2539.\n *\n * Note 429 never reaches here: every adapter throws LlmRateLimitError for 429\n * before the generic non-OK path, so the [400,500) range is exactly the\n * client/auth class. A retryable 5xx (503/529) is handled by isRetryableLlmError,\n * not here; any other 5xx stays at error (genuine outage / our-side fault).\n */\nexport function isExternalLlmHttpError(error: unknown): error is LlmProviderHttpError {\n return isLlmProviderHttpError(error) && error.status >= 400 && error.status < 500;\n}\n\n/**\n * Map a tenant-actionable provider HTTP status to a Status & Notices alert\n * category — the axis the hub admin acts on. 402/429 (payment / quota) →\n * `connection_quota` (upgrade or pay); the rest of the 4xx auth/config class →\n * `connection_auth` (rotate / re-enter the credential). Note: for LLM providers\n * 429 throws LlmRateLimitError before the 4xx boundary, so the LLM path only ever\n * yields `connection_auth`; channel/STT/TTS producers (which do surface 402/429)\n * exercise the quota branch.\n */\nexport function statusToAlertCategory(status: number): 'connection_auth' | 'connection_quota' {\n return status === 402 || status === 429 ? 'connection_quota' : 'connection_auth';\n}\n\n/**\n * Upstream LLM HTTP statuses that are transient and explicitly retryable — the\n * provider told us to back off and try again, not that the request was wrong:\n *\n * - 503 — Service Unavailable (Gemini `UNAVAILABLE` \"high demand\", OpenAI\n * overloaded): the canonical \"try again later\" status.\n * - 529 — Anthropic `overloaded_error`: Anthropic's transient-overload status.\n *\n * 500/502/504 are deliberately OUT: an unexpected 5xx is a genuine fault worth\n * investigating, so it stays at logger.error → Sentry (gh #2539). A *sustained*\n * 503/529 still reaches Sentry via the retry-exhaustion path — only a transient\n * blip is downgraded to warn + reschedule.\n */\nconst RETRYABLE_LLM_PROVIDER_STATUSES: ReadonlySet<number> = new Set([503, 529]);\n\n/**\n * True when `error` is a transient, retryable upstream LLM error that should\n * reschedule the turn via `retry_turn` rather than fail it — either a 429\n * (LlmRateLimitError) or a provider 503/529 (LlmProviderHttpError). The\n * ConversationDO catch site keys its reschedule branch on this, and the LLM\n * circuit breaker excludes it from the failure count (a throttle/overload blip\n * is not provider unhealth). Classified here so it covers every adapter — they\n * all already throw LlmProviderHttpError for a non-429 non-OK response. gh #2659.\n */\nexport function isRetryableLlmError(error: unknown): boolean {\n return (\n isLlmRateLimitError(error) ||\n (isLlmProviderHttpError(error) && RETRYABLE_LLM_PROVIDER_STATUSES.has(error.status))\n );\n}\n\n/**\n * 502 - Bad Gateway: External service error\n */\nexport class ExternalServiceError extends AppError {\n constructor(service: string, originalError?: Error) {\n super(`External service error: ${service}`, 'EXTERNAL_SERVICE_ERROR', 502, {\n service,\n originalMessage: originalError?.message,\n });\n this.name = 'ExternalServiceError';\n }\n}\n\n/**\n * An external channel-send API rejected an outbound message with an HTTP status —\n * Meta WhatsApp / Instagram Graph or the Telegram Bot API (Telegram surfaces its\n * status as `error_code` on an HTTP-200 `ok:false` body, which we carry as `status`).\n *\n * Extends `ExternalServiceError` so the existing `instanceof ExternalServiceError`\n * delivery catches keep treating it as an expected degraded condition (warn → Loki,\n * NOT Sentry); adds the numeric upstream `status` the Status & Notices producer keys\n * on to raise a tenant-actionable `channel_token` / `connection_quota` alert for the\n * 4xx class. Mirrors `LlmProviderHttpError` / `McpError`.\n *\n * NEVER carries the upstream response body. A Meta error body embeds an\n * OAuthException whose message can include a token fragment, so — unlike the plain\n * `ExternalServiceError('WhatsApp', new Error('API error 401: …body…'))` it replaces —\n * it passes NO `originalError`, keeping only `provider` + `status` and the **numeric**\n * provider error `code`/`subcode` (Meta's `error.code` / `error.error_subcode`). Those\n * are small integers, not secrets — they let consumers classify the failure (token\n * vs. per-recipient vs. outside-window) without re-introducing the body:\n * `providerCode === 190` = Meta OAuthException (expired/invalid token);\n * `providerCode === 131047` = WhatsApp outside-24h-window; `providerCode === 10` +\n * `providerSubcode === 2534022` = Instagram outside-window. (Named `providerCode`,\n * not `code`, because `AppError.code` is already the string error-code enum.)\n */\nconst CHANNEL_PROVIDER_HTTP_BRAND = Symbol.for('wayai.ChannelProviderHttpError');\n\nexport class ChannelProviderHttpError extends ExternalServiceError {\n readonly [CHANNEL_PROVIDER_HTTP_BRAND] = true;\n readonly status: number;\n readonly provider: string;\n /** Provider numeric error code (Meta `error.code`) — body-free. */\n readonly providerCode?: number;\n /** Provider numeric error subcode (Meta `error.error_subcode`) — body-free. */\n readonly providerSubcode?: number;\n\n constructor(provider: string, status: number, providerCode?: number, providerSubcode?: number) {\n // No originalError on purpose: ExternalServiceError stores originalError.message\n // in details.originalMessage, and the upstream body can carry a credential\n // fragment. Only the numeric status + code/subcode survive.\n super(provider);\n this.name = 'ChannelProviderHttpError';\n this.status = status;\n this.provider = provider;\n this.providerCode = providerCode;\n this.providerSubcode = providerSubcode;\n }\n}\n\nexport function isChannelProviderHttpError(error: unknown): error is ChannelProviderHttpError {\n return (\n typeof error === 'object' &&\n error !== null &&\n CHANNEL_PROVIDER_HTTP_BRAND in error &&\n (error as Record<symbol, unknown>)[CHANNEL_PROVIDER_HTTP_BRAND] === true\n );\n}\n\n/**\n * True when `error` is an external channel-send 4xx — a tenant-actionable\n * credential/config/quota condition (expired/revoked channel token, rate/quota).\n * The ConversationDO delivery catch raises a Status & Notices alert for these; a\n * 5xx (provider outage) stays observability-only. Mirrors `isExternalLlmHttpError`.\n */\nexport function isExternalChannelHttpError(error: unknown): error is ChannelProviderHttpError {\n return isChannelProviderHttpError(error) && error.status >= 400 && error.status < 500;\n}\n\n/**\n * An external media-provider (STT/TTS) API rejected a request with an HTTP status —\n * speech-to-text (Groq, OpenAI) or text-to-speech (ElevenLabs, OpenAI-compatible).\n * These run on hub credentials and are billable, so a bad/expired key or quota is a\n * tenant-actionable condition the hub admin fixes — a 4xx belongs at `logger.warn`\n * (Loki), NOT `logger.error` (Sentry → autofix, the anti-pattern this removes), and\n * raises a Status & Notices alert. Mirrors `LlmProviderHttpError` / `ChannelProviderHttpError`.\n *\n * NEVER carries the upstream response body (a provider error message can name the\n * key) — only the numeric `status` + `provider` display name. `message` is a body-free\n * `\"Groq API error (401)\"`; the catch site logs only `status`/`provider`.\n */\nconst MEDIA_PROVIDER_HTTP_BRAND = Symbol.for('wayai.MediaProviderHttpError');\n\nexport class MediaProviderHttpError extends Error {\n readonly [MEDIA_PROVIDER_HTTP_BRAND] = true;\n\n constructor(\n public readonly provider: string,\n public readonly status: number,\n ) {\n super(`${provider} API error (${status})`);\n this.name = 'MediaProviderHttpError';\n }\n}\n\nexport function isMediaProviderHttpError(error: unknown): error is MediaProviderHttpError {\n return (\n typeof error === 'object' &&\n error !== null &&\n MEDIA_PROVIDER_HTTP_BRAND in error &&\n (error as Record<symbol, unknown>)[MEDIA_PROVIDER_HTTP_BRAND] === true\n );\n}\n\n/**\n * True when `error` is an external media-provider (STT/TTS) 4xx — a tenant-actionable\n * credential/quota condition. The ConversationDO transcribe/synthesize catch raises a\n * Status & Notices alert for these; a 5xx (provider outage) stays observability-only.\n */\nexport function isExternalMediaHttpError(error: unknown): error is MediaProviderHttpError {\n return isMediaProviderHttpError(error) && error.status >= 400 && error.status < 500;\n}\n\n/**\n * 503 - Service Unavailable: Circuit breaker open\n */\nexport class CircuitBreakerOpenError extends AppError {\n constructor(service: string) {\n super(`Service temporarily unavailable: ${service}`, 'CIRCUIT_BREAKER_OPEN', 503, {\n service,\n });\n this.name = 'CircuitBreakerOpenError';\n }\n}\n\n/**\n * 503 - Service Unavailable: Generic service unavailability\n */\nexport class ServiceUnavailableError extends AppError {\n constructor(message = 'Service temporarily unavailable', details?: Record<string, unknown>) {\n super(message, 'SERVICE_UNAVAILABLE', 503, details);\n this.name = 'ServiceUnavailableError';\n }\n}\n\n/** 503 — CF DO storage transient (Sentry-skipped via TRANSIENT_STORAGE). */\nexport class TransientStorageError extends AppError {\n constructor(message = 'Storage temporarily unavailable') {\n super(message, 'TRANSIENT_STORAGE', 503);\n this.name = 'TransientStorageError';\n }\n}\n\n/**\n * 503 — ClickHouse cold-start (Cloud auto-suspend resume). Retryable,\n * Sentry-skipped via CLICKHOUSE_COLD.\n *\n * Thrown by detail-style CH routes (archive transcript / observability) whose\n * response contract can't carry a `cold: true` flag — an opaque blob would\n * silently render as an empty transcript. They surface this retryable error\n * instead; the matching `withClickHouseQuery` wake probe means the client's\n * retry succeeds once CH is warm. List/dashboard CH routes still return\n * `{ cold: true }` 200, since their consumers handle the cold banner.\n */\nexport class ClickHouseColdStartError extends AppError {\n constructor(message = 'Conversation store is warming up, please retry') {\n super(message, 'CLICKHOUSE_COLD', 503, { retryable: true });\n this.name = 'ClickHouseColdStartError';\n }\n}\n\n/**\n * AppError codes that represent expected client-correctable conditions —\n * the backend's onError handler skips Sentry for these, and the frontend\n * logger mirrors the same policy (console logs still hit Loki).\n *\n * Single source of truth used by both workers/backend/src/middleware/error-handler.ts\n * and frontend/src/lib/logger.ts.\n */\nexport const SENTRY_SKIP_CODES: ReadonlySet<string> = new Set([\n 'VALIDATION_ERROR',\n 'AUTHENTICATION_ERROR',\n 'AUTHORIZATION_ERROR',\n 'NOT_FOUND',\n 'RATE_LIMIT_EXCEEDED',\n // 409 — expected client-correctable state conflicts (already-exists,\n // locked, \"in use by …\"). A genuine bug surfaces as a 5xx, never a 409.\n 'CONFLICT',\n // CF DO storage transients (object reset / op timeout) — gh #1966.\n 'TRANSIENT_STORAGE',\n // ClickHouse Cloud cold-start (auto-suspend resume) — expected/transient,\n // recovered by the withClickHouseQuery wake probe + client retry.\n 'CLICKHOUSE_COLD',\n]);\n\n/**\n * Check if an error is an AppError.\n * Uses Symbol brand instead of instanceof to work across module boundaries.\n */\nexport function isAppError(error: unknown): error is AppError {\n return (\n typeof error === 'object' &&\n error !== null &&\n APP_ERROR_BRAND in error &&\n (error as Record<symbol, unknown>)[APP_ERROR_BRAND] === true\n );\n}\n\n/**\n * Derive a stable, PII-free grouping token from an error message.\n *\n * Sentry's default grouping for the backend Worker is unreliable: the bundle\n * is minified to a single `index.js` with no uploaded source maps, so distinct\n * errors collapse to indistinguishable stack frames and group under one issue\n * (gh #2440). Every backend Sentry capture path therefore sets an explicit\n * fingerprint, and that fingerprint needs a message discriminator — but a raw\n * message can embed user input (library errors interpolate values, e.g.\n * `Invalid phone number: ${e.message}`). This normalizes a message into a token\n * that is stable across interpolated values yet distinct across different\n * logical errors, without leaking user data.\n *\n * Replacement order matters: URLs/emails first (they contain digits and dots),\n * then ids, then quoted strings, then bare numbers.\n */\nexport function errorMessageShape(message: string): string {\n // Bound the input before the regex chain: this runs in the per-event\n // beforeSend hook, so a pathologically long message must not turn it into a\n // perf/DoS sink. 256 keeps enough to discriminate; the trailing slice caps\n // the emitted token at 120.\n return (message ?? '')\n .slice(0, 256)\n .replace(/https?:\\/\\/\\S+/gi, '<url>')\n .replace(/[\\w.+-]+@[\\w-]+\\.[\\w.-]+/gi, '<email>')\n .replace(\n // No \\b anchors: a UUID may abut a word char (e.g. `<uuid>internal`); the\n // 8-4-4-4-12 dash shape is specific enough that mid-string matching is safe.\n /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,\n '<uuid>',\n )\n .replace(/\\b[0-9a-f]{16,}\\b/gi, '<hex>')\n // Mask quoted values per quote type. A single combined class [\"'`][^\"'`]*[\"'`]\n // mis-pairs across types (e.g. `\"it's valid\"` matches only `\"it'`), leaking\n // the tail — so strip each quote type independently.\n .replace(/\"[^\"]*\"/g, '<str>')\n .replace(/'[^']*'/g, '<str>')\n .replace(/`[^`]*`/g, '<str>')\n // No trailing \\b: a number abutting a unit letter (`30.5s`, `1.5GB`) would\n // otherwise match only `30.` and leave a stray digit, which both leaks and\n // splits grouping across values. The leading \\b still prevents matching\n // digits inside an opaque token before the <id> rule below can claim it.\n .replace(/\\b\\d[\\d.,]*/g, '<n>')\n // Long opaque tokens that survive the rules above (WorkOS user_/org_ ids,\n // way_/wst_ API tokens, slugs): mask so the fingerprint can't fragment by\n // identifier or carry token-shaped data — mirrors the >20-char heuristic in\n // logger.ts's sanitizeForSentry.\n .replace(/\\b[A-Za-z0-9][A-Za-z0-9_-]{19,}\\b/g, '<id>')\n .replace(/\\s+/g, ' ')\n .trim()\n .toLowerCase()\n .slice(0, 120);\n}\n","/**\n * Circuit breaker pattern for fault tolerance\n *\n * States:\n * - closed: Normal operation, requests pass through\n * - open: Failures exceeded threshold, requests fail fast\n * - half-open: Testing if service has recovered\n */\n\nimport { CircuitBreakerOpenError } from './errors';\n\nexport type CircuitState = 'closed' | 'open' | 'half-open';\n\nexport interface CircuitBreakerConfig {\n /** Number of failures before opening circuit */\n threshold: number;\n /** Time in ms before attempting to close circuit */\n resetTimeout: number;\n /** Optional name for logging */\n name?: string;\n}\n\nconst DEFAULT_CONFIG: CircuitBreakerConfig = {\n threshold: 5,\n resetTimeout: 30000,\n};\n\nexport class CircuitBreaker {\n private failures = 0;\n private lastFailure = 0;\n private state: CircuitState = 'closed';\n private config: CircuitBreakerConfig;\n\n constructor(config: Partial<CircuitBreakerConfig> = {}) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Execute a function with circuit breaker protection.\n * `shouldCount` lets the caller exclude expected/transient errors (e.g. rate\n * limits) from tripping the breaker — those aren't signals of provider unhealth.\n */\n async execute<T>(fn: () => Promise<T>, opts?: { shouldCount?: (err: unknown) => boolean }): Promise<T> {\n if (this.state === 'open') {\n if (Date.now() - this.lastFailure > this.config.resetTimeout) {\n // Try to recover\n this.state = 'half-open';\n } else {\n throw new CircuitBreakerOpenError(this.config.name || 'service');\n }\n }\n\n try {\n const result = await fn();\n this.onSuccess();\n return result;\n } catch (error) {\n if (!opts?.shouldCount || opts.shouldCount(error)) {\n this.onFailure();\n }\n throw error;\n }\n }\n\n /**\n * Record a successful operation\n */\n private onSuccess(): void {\n this.failures = 0;\n this.state = 'closed';\n }\n\n /**\n * Record a failed operation\n */\n private onFailure(): void {\n this.failures++;\n this.lastFailure = Date.now();\n if (this.failures >= this.config.threshold) {\n this.state = 'open';\n }\n }\n\n /**\n * Get current circuit state\n */\n getState(): CircuitState {\n return this.state;\n }\n\n /**\n * Get current failure count\n */\n getFailures(): number {\n return this.failures;\n }\n\n /**\n * Manually reset the circuit breaker\n */\n reset(): void {\n this.failures = 0;\n this.lastFailure = 0;\n this.state = 'closed';\n }\n}\n\n/**\n * Factory function to create circuit breakers for multiple services\n */\nexport function createCircuitBreakers<T extends string>(\n services: T[],\n config: Partial<CircuitBreakerConfig> = {}\n): Record<T, CircuitBreaker> {\n const breakers: Record<string, CircuitBreaker> = {};\n for (const service of services) {\n breakers[service] = new CircuitBreaker({ ...config, name: service });\n }\n return breakers as Record<T, CircuitBreaker>;\n}\n","/**\n * Request tracing utilities for observability\n *\n * Provides lightweight tracing that can be used with or without Sentry.\n */\n\nexport interface Span {\n name: string;\n startTime: number;\n endTime?: number;\n attributes: Record<string, string | number | boolean>;\n status: 'ok' | 'error';\n error?: string;\n children: Span[];\n}\n\nexport class Tracer {\n private spans: Span[] = [];\n private currentSpan: Span | null = null;\n\n /**\n * Start a new span\n */\n startSpan(name: string, attributes: Record<string, string | number | boolean> = {}): Span {\n const span: Span = {\n name,\n startTime: Date.now(),\n attributes,\n status: 'ok',\n children: [],\n };\n\n if (this.currentSpan) {\n this.currentSpan.children.push(span);\n } else {\n this.spans.push(span);\n }\n\n return span;\n }\n\n /**\n * End a span\n */\n endSpan(span: Span, error?: Error): void {\n span.endTime = Date.now();\n if (error) {\n span.status = 'error';\n span.error = error.message;\n }\n }\n\n /**\n * Get all spans\n */\n getSpans(): Span[] {\n return this.spans;\n }\n\n /**\n * Get trace data as a JSON-serializable object\n */\n toJSON(): object {\n return {\n spans: this.spans.map(this.spanToJSON.bind(this)),\n totalDuration: this.getTotalDuration(),\n };\n }\n\n private spanToJSON(span: Span): object {\n return {\n name: span.name,\n duration: span.endTime ? span.endTime - span.startTime : undefined,\n attributes: span.attributes,\n status: span.status,\n error: span.error,\n children: span.children.map(this.spanToJSON.bind(this)),\n };\n }\n\n /**\n * Get total duration of all root spans\n */\n getTotalDuration(): number {\n return this.spans.reduce((total, span) => {\n const duration = span.endTime ? span.endTime - span.startTime : 0;\n return total + duration;\n }, 0);\n }\n\n /**\n * Log trace summary to console\n */\n logSummary(): void {\n for (const span of this.spans) {\n this.logSpan(span, 0);\n }\n }\n\n private logSpan(span: Span, depth: number): void {\n const indent = ' '.repeat(depth);\n const duration = span.endTime ? `${span.endTime - span.startTime}ms` : 'in progress';\n const status = span.status === 'error' ? ' [ERROR]' : '';\n console.log(`${indent}${span.name}: ${duration}${status}`);\n\n for (const child of span.children) {\n this.logSpan(child, depth + 1);\n }\n }\n}\n\n/**\n * Execute a function with automatic span tracking\n */\nexport async function withSpan<T>(\n tracer: Tracer,\n name: string,\n fn: () => Promise<T>,\n attributes: Record<string, string | number | boolean> = {}\n): Promise<T> {\n const span = tracer.startSpan(name, attributes);\n try {\n const result = await fn();\n tracer.endSpan(span);\n return result;\n } catch (error) {\n tracer.endSpan(span, error as Error);\n throw error;\n }\n}\n\n/**\n * Create a tracer that can be attached to a request context\n */\nexport function createTracer(): Tracer {\n return new Tracer();\n}\n","/**\n * Rate limit configuration for all endpoints\n *\n * Multi-tier rate limiting:\n * - Layer 1: Cloudflare native (IP-based, fast, at edge)\n * - Layer 2: Redis (user-based, granular, for authenticated endpoints)\n */\n\n/**\n * Rate limit tiers using Cloudflare bindings\n */\nexport const RATE_LIMIT_TIERS = {\n /** Very restrictive - OAuth, auth endpoints (5/min) */\n STRICT: { limit: 5, period: 60, bindingName: 'RATE_LIMITER_STRICT' },\n /** Moderate - billing, token exchange (30/min) */\n MODERATE: { limit: 30, period: 60, bindingName: 'RATE_LIMITER_MODERATE' },\n /** Standard - general API endpoints (100/min) */\n STANDARD: { limit: 100, period: 60, bindingName: 'RATE_LIMITER_STANDARD' },\n /** High throughput - message webhooks (300/min) */\n HIGH: { limit: 300, period: 60, bindingName: 'RATE_LIMITER_HIGH' },\n} as const;\n\nexport type RateLimitTier = keyof typeof RATE_LIMIT_TIERS;\n\n/**\n * Configuration for a specific endpoint's rate limiting\n */\nexport interface EndpointRateLimitConfig {\n /** IP-based tier using Cloudflare binding */\n tier: RateLimitTier;\n /** User-based limit (requests per minute) - only for authenticated requests */\n userLimit?: number;\n /** Window in seconds for user limit (default: 60) */\n userWindow?: number;\n /** If true, return 503 when Redis is unavailable (default: false = fail-open) */\n failClosed?: boolean;\n /** If true, skip IP rate limit for authenticated users (default: false) */\n skipAuthenticatedUsers?: boolean;\n}\n\n/**\n * Endpoint configurations\n * Keys are path patterns that support wildcards (*)\n */\nconst ENDPOINT_CONFIGS: Record<string, EndpointRateLimitConfig> = {\n // OAuth callbacks - strict, fail-closed (prevent brute force)\n '/oauth/callback/*': { tier: 'STRICT', failClosed: true },\n\n // Auth endpoints - strict, fail-closed\n '/auth/phone': { tier: 'STRICT', failClosed: true },\n '/auth/mcp/exchange': { tier: 'MODERATE', failClosed: true },\n\n // Billing - moderate, fail-closed with user limits\n '/api/billing/*': { tier: 'MODERATE', userLimit: 100, failClosed: true, skipAuthenticatedUsers: true },\n '/webhooks/stripe': { tier: 'MODERATE', failClosed: true },\n '/webhooks/workos': { tier: 'MODERATE', failClosed: true },\n\n // API endpoints - standard with user limits\n '/api/setup/*': { tier: 'STANDARD', userLimit: 150, skipAuthenticatedUsers: true },\n '/api/conversations/*': { tier: 'STANDARD', userLimit: 150, skipAuthenticatedUsers: true },\n '/api/users/*': { tier: 'STANDARD', userLimit: 150, skipAuthenticatedUsers: true },\n '/api/analytics/*': { tier: 'STANDARD', userLimit: 150, skipAuthenticatedUsers: true },\n '/api/evals/*': { tier: 'STANDARD', userLimit: 150, skipAuthenticatedUsers: true },\n '/api/files/*': { tier: 'STANDARD', userLimit: 150, skipAuthenticatedUsers: true },\n '/api/outbound/*': { tier: 'STANDARD', userLimit: 150, skipAuthenticatedUsers: true },\n '/api/completions/*': { tier: 'STANDARD', userLimit: 150, skipAuthenticatedUsers: true },\n '/api/live-updates/*': { tier: 'STANDARD', userLimit: 150, skipAuthenticatedUsers: true },\n '/api/hub-users/*': { tier: 'STANDARD', userLimit: 150, skipAuthenticatedUsers: true },\n '/api/conversation-state/*': { tier: 'STANDARD', userLimit: 150, skipAuthenticatedUsers: true },\n\n // Channel webhooks - high throughput (external systems, never authenticated)\n '/webhooks/whatsapp/*': { tier: 'HIGH' },\n '/webhooks/instagram/*': { tier: 'HIGH' },\n\n // Reports (CLI → platform_report triage queue). One per-user budget covers intake\n // (POST), the content edit (PATCH /:id), the reporter read-back (GET, GET /:id), and the\n // verification loop (POST /:id/accept, /:id/contest). The limiter is path-based, so a\n // method-level split (loose reads, strict writes) isn't expressible — GET /:id and PATCH\n // /:id share a path. So the budget is sized for the read-heavy poll loop (a reporter agent\n // polling `report get`/`list` while it waits for the fix), at 60/hour. Intake-flooding stays\n // bounded regardless: identical reports collapse on `fingerprint` (ON CONFLICT DO NOTHING),\n // so a runaway create loop merges rather than floods. Still STRICT tier + failClosed so a\n // genuinely runaway distinct-report loop surfaces as 429. The `/*` is load-bearing — an\n // exact `/api/reports` key would leave the `/:id` paths unmatched (→ unthrottled).\n '/api/reports/*': { tier: 'STRICT', userLimit: 60, userWindow: 3600, failClosed: true, skipAuthenticatedUsers: true },\n\n // Admin report mutations (transition/group/ungroup/edit) — platform-admin\n // gated at the route, rate-limited here as defense-in-depth. Generous STANDARD\n // cap so legitimate triage bursts aren't throttled (grouping is one request\n // even for many members); deliberately NOT failClosed so a Redis blip never\n // blocks an admin's triage. The bare GET reads share this budget harmlessly.\n '/api/admin/reports/*': { tier: 'STANDARD', userLimit: 150 },\n\n // GitHub webhook (issues.closed → platform_report addressed). MODERATE +\n // fail-closed; GitHub retries on transient failures so a brief Redis blip\n // doesn't lose state.\n '/webhooks/github': { tier: 'MODERATE', failClosed: true },\n\n // Account deletion — strict on the destructive POST + public undo. The\n // /api/users/* default tier above ALSO matches these, but `getEndpointConfig`\n // returns the longest-prefix match, so the more specific entries here win.\n // `skipAuthenticatedUsers` deliberately omitted: every caller is authenticated,\n // so including it would make `userLimit` a no-op — the per-user cap IS the gate.\n '/api/users/me/deletion': { tier: 'STRICT', userLimit: 3, userWindow: 3600, failClosed: true },\n '/api/users/me/deletion/preflight': { tier: 'STANDARD', userLimit: 30, failClosed: true },\n '/api/users/deletion/undo': { tier: 'STRICT', failClosed: true },\n\n // Email-invite preview — public, fail-closed. MODERATE (30/min IP) leaves\n // headroom for the signup-page server-fetch + reloads + prefetches; STRICT\n // would throttle legitimate users opening the link in multiple tabs.\n '/api/invites/preview': { tier: 'MODERATE', failClosed: true },\n\n // Admin DO debug reads - very strict, fail-closed. Platform-admin only (enforced\n // at route), but we rate-limit independently as a defense-in-depth signal so a\n // runaway investigation script surfaces as 429 instead of silently scanning.\n '/api/admin/data-explorer/debug/*': { tier: 'STRICT', userLimit: 60, userWindow: 3600, failClosed: true },\n\n // CI/GitOps endpoints - standard with user limits\n '/api/ci/*': { tier: 'STANDARD', userLimit: 100, skipAuthenticatedUsers: true },\n\n // App channel - high throughput with user limits\n '/channels/app/*': { tier: 'HIGH', userLimit: 500, skipAuthenticatedUsers: true },\n\n // System/scheduled - high throughput (internal)\n '/channels/system/*': { tier: 'HIGH', skipAuthenticatedUsers: true },\n '/scheduled/*': { tier: 'HIGH', skipAuthenticatedUsers: true },\n\n // WebSocket - standard with user limit to prevent connection spam\n '/live-updates/ws': { tier: 'STANDARD', userLimit: 100, failClosed: true },\n\n // WS ticket mint - per-user 60/min accommodates aggressive reconnect patterns\n // without opening abuse vectors; fail-closed so Redis outages don't let\n // runaway clients mint unbounded tickets.\n '/api/auth/ws-ticket': { tier: 'MODERATE', userLimit: 60, failClosed: true, skipAuthenticatedUsers: true },\n '/api/auth/session-check': { tier: 'STANDARD', userLimit: 120, skipAuthenticatedUsers: true },\n '/api/auth/logout': { tier: 'MODERATE', userLimit: 10, failClosed: true, skipAuthenticatedUsers: true },\n};\n\n/**\n * Paths that should be excluded from rate limiting entirely\n *\n * Note: /files/* is the R2 file serving route (public/signed URLs, no auth)\n * This is different from /api/files/* which is the authenticated API route\n */\nconst EXCLUDED_PATHS = new Set(['/health', '/files/*']);\n\n/**\n * Check if a path matches a pattern\n * Supports wildcards (*) at the end of patterns\n *\n * Examples:\n * - '/api/billing/*' matches '/api/billing', '/api/billing/', and '/api/billing/foo'\n * - '/api/billing/*' does NOT match '/api/billing-new'\n */\nfunction matchPath(pattern: string, path: string): boolean {\n // Normalize: remove trailing slash for consistent matching\n const normalizedPath = path.replace(/\\/$/, '');\n\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2); // Remove '/*'\n return normalizedPath === prefix || normalizedPath.startsWith(prefix + '/');\n }\n return pattern === normalizedPath;\n}\n\n/**\n * Get rate limit configuration for a specific path\n * Returns null if the path is excluded from rate limiting\n */\nexport function getEndpointConfig(path: string): EndpointRateLimitConfig | null {\n // Check exclusions first\n for (const excluded of EXCLUDED_PATHS) {\n if (matchPath(excluded, path)) {\n return null;\n }\n }\n\n // Find matching config (most specific first - longer patterns)\n const sortedPatterns = Object.keys(ENDPOINT_CONFIGS).sort((a, b) => b.length - a.length);\n\n for (const pattern of sortedPatterns) {\n if (matchPath(pattern, path)) {\n return ENDPOINT_CONFIGS[pattern];\n }\n }\n\n // Default config for unlisted endpoints\n return { tier: 'STANDARD' };\n}\n\n/**\n * Get the rate limit tier configuration\n */\nexport function getTierConfig(tier: RateLimitTier): (typeof RATE_LIMIT_TIERS)[RateLimitTier] {\n return RATE_LIMIT_TIERS[tier];\n}\n","/**\n * Agent settings validation and sanitization against connector schemas.\n *\n * The `connector` table defines `agent_settings_schema` as the source of truth\n * for valid settings per connector type. These utilities ensure settings\n * are valid before persisting to the database.\n */\n\n/**\n * Schema field definition from connector.agent_settings_schema\n */\nexport interface SchemaField {\n type: 'select' | 'slider' | 'number' | 'text' | 'toggle';\n required?: boolean;\n default?: unknown;\n options?: Array<string | { value: string; label: string; deprecated?: boolean }>;\n /** When true, accept any string value for select fields (not just values in options) */\n allowCustomValue?: boolean;\n min?: number;\n max?: number;\n dependsOn?: { field: string; values: string[] };\n}\n\nexport type AgentSettingsSchema = Record<string, SchemaField>;\n\n/**\n * Validates agent_settings against the connector's schema.\n * Returns array of validation errors, or empty array if valid.\n * Use for strict validation paths (MCP, CI).\n */\nexport function validateAgentSettings(\n settings: Record<string, unknown>,\n schema: AgentSettingsSchema\n): string[] {\n const errors: string[] = [];\n\n // Check required fields\n for (const [fieldName, fieldSchema] of Object.entries(schema)) {\n // Skip validation if field has dependsOn and condition is not met\n if (fieldSchema.dependsOn) {\n const dependsOnValue = settings[fieldSchema.dependsOn.field];\n if (!fieldSchema.dependsOn.values.includes(dependsOnValue as string)) {\n continue; // Field is not applicable for this configuration\n }\n }\n\n const value = settings[fieldName];\n\n // Check required\n if (fieldSchema.required && (value === undefined || value === null)) {\n errors.push(`Missing required field: ${fieldName}`);\n continue;\n }\n\n // Skip further validation if value not provided (and not required)\n if (value === undefined) continue;\n\n // Validate by type\n switch (fieldSchema.type) {\n case 'select': {\n if (typeof value !== 'string') {\n errors.push(`${fieldName} must be a string`);\n } else if (fieldSchema.options && !fieldSchema.allowCustomValue) {\n const allowedValues = fieldSchema.options.map(opt =>\n typeof opt === 'string' ? opt : opt.value\n );\n if (!allowedValues.includes(value)) {\n errors.push(`Invalid value for ${fieldName}: \"${value}\". Allowed: ${allowedValues.join(', ')}`);\n }\n }\n break;\n }\n case 'slider':\n case 'number': {\n if (typeof value !== 'number') {\n errors.push(`${fieldName} must be a number`);\n } else {\n if (fieldSchema.min !== undefined && value < fieldSchema.min) {\n errors.push(`${fieldName} must be >= ${fieldSchema.min}`);\n }\n if (fieldSchema.max !== undefined && value > fieldSchema.max) {\n errors.push(`${fieldName} must be <= ${fieldSchema.max}`);\n }\n }\n break;\n }\n case 'text': {\n if (typeof value !== 'string') {\n errors.push(`${fieldName} must be a string`);\n }\n break;\n }\n case 'toggle': {\n if (typeof value !== 'boolean') {\n errors.push(`${fieldName} must be a boolean`);\n }\n break;\n }\n }\n }\n\n // Warn about unknown fields (not in schema)\n for (const fieldName of Object.keys(settings)) {\n if (!(fieldName in schema)) {\n errors.push(`Unknown field: ${fieldName}. This connector does not support this setting.`);\n }\n }\n\n return errors;\n}\n\n/**\n * Result of sanitizing agent settings\n */\nexport interface SanitizeResult {\n /** Settings object with only schema-defined keys */\n sanitized: Record<string, unknown>;\n /** Keys that were stripped (not in schema) */\n strippedKeys: string[];\n}\n\n/**\n * Sanitizes agent_settings against the connector's schema.\n * Strips unknown keys not defined in the schema.\n * Use for lenient paths (REST API, CI, frontend).\n */\nexport function sanitizeAgentSettings(\n settings: Record<string, unknown>,\n schema: AgentSettingsSchema\n): SanitizeResult {\n const sanitized: Record<string, unknown> = {};\n const strippedKeys: string[] = [];\n\n // Copy only schema-defined keys\n for (const key of Object.keys(settings)) {\n if (key in schema) {\n sanitized[key] = settings[key];\n } else {\n strippedKeys.push(key);\n }\n }\n\n return { sanitized, strippedKeys };\n}\n","/**\n * Shared constants for WayAI Workers\n */\n\n/** Meta (Facebook) Graph API version used for WhatsApp and Instagram integrations */\nexport const META_API_VERSION = 'v25.0';\n\n// ---------------------------------------------------------------------------\n// Tool Execution\n// ---------------------------------------------------------------------------\n\n/**\n * Hard ceiling (ms) on a single AI-triggered external/MCP/native tool HTTP fetch\n * during an agent turn. Bounds tool execution so a slow or hung endpoint can't\n * wedge the turn indefinitely (gh #2599).\n *\n * 60s is generous for legitimate slow tool APIs yet well under the eval watchdog\n * default (`EVAL_DEFAULT_RUN_DEADLINE_MS`, 180s): a single hung tool fetch fails\n * fast instead of consuming the whole run budget and falsely reaping a still-\n * progressing eval run. Applied to ALL conversations, not just eval runs.\n */\nexport const EXTERNAL_TOOL_FETCH_TIMEOUT_MS = 60_000;\n\n// ---------------------------------------------------------------------------\n// Authentication Types\n// ---------------------------------------------------------------------------\n\n/** Canonical lowercase auth type codes used in seed data, DB storage, and all comparisons. */\nexport const AUTH_TYPE = {\n OAUTH: 'oauth',\n API_KEY: 'api_key',\n BASIC_AUTH: 'basic_auth',\n BEARER: 'bearer',\n NONE: 'none',\n} as const;\n\nexport type AuthTypeCode = (typeof AUTH_TYPE)[keyof typeof AUTH_TYPE];\n\n/** Auth types valid for organization credentials (excludes OAuth and None). */\nexport const ORG_CREDENTIAL_AUTH_TYPES = [\n AUTH_TYPE.API_KEY,\n AUTH_TYPE.BEARER,\n AUTH_TYPE.BASIC_AUTH,\n] as const;\n\nexport type OrgCredentialAuthType = (typeof ORG_CREDENTIAL_AUTH_TYPES)[number];\n\n/** Maps lowercase code to human-readable display label. */\nexport const AUTH_TYPE_DISPLAY: Record<string, string> = {\n [AUTH_TYPE.OAUTH]: 'OAuth',\n [AUTH_TYPE.API_KEY]: 'API Key',\n [AUTH_TYPE.BASIC_AUTH]: 'Basic Auth',\n [AUTH_TYPE.BEARER]: 'Bearer Token',\n [AUTH_TYPE.NONE]: 'No Authentication',\n};\n\n/** Maps old capitalized display names to canonical lowercase codes. */\nconst LEGACY_AUTH_TYPE_MAP: Record<string, AuthTypeCode> = {\n 'OAuth': AUTH_TYPE.OAUTH,\n 'API Key': AUTH_TYPE.API_KEY,\n 'Basic Auth': AUTH_TYPE.BASIC_AUTH,\n 'Bearer Token': AUTH_TYPE.BEARER,\n 'No authentication': AUTH_TYPE.NONE,\n // Also handle the old DISPLAY_TO_CODE bug where 'basic' was used instead of 'basic_auth'\n 'basic': AUTH_TYPE.BASIC_AUTH,\n};\n\nconst VALID_AUTH_TYPES = new Set<string>(Object.values(AUTH_TYPE));\n\n/** Normalizes any auth type string (legacy capitalized or already lowercase) to canonical code. */\nexport function normalizeAuthType(raw: string): AuthTypeCode {\n if (VALID_AUTH_TYPES.has(raw)) return raw as AuthTypeCode;\n return LEGACY_AUTH_TYPE_MAP[raw] ?? (raw as AuthTypeCode);\n}\n\n// ---------------------------------------------------------------------------\n// Agent Roles\n// ---------------------------------------------------------------------------\n\nexport const AGENT_ROLES = [\n 'pilot', 'copilot',\n 'pilot_specialist', 'copilot_specialist',\n 'pilot_advisor', 'copilot_advisor',\n 'monitor', 'conversation_evaluator', 'message_evaluator',\n 'summarizer',\n] as const;\n\nexport type AgentRole = (typeof AGENT_ROLES)[number];\n\nexport const BACKGROUND_AGENT_ROLES: readonly AgentRole[] = ['conversation_evaluator', 'message_evaluator', 'monitor', 'summarizer'];\nexport const PILOT_TRACK_ROLES: readonly AgentRole[] = ['pilot', 'pilot_specialist'];\nexport const COPILOT_TRACK_ROLES: readonly AgentRole[] = ['copilot', 'copilot_specialist'];\n\n/** Maps agent role to human-readable display label. */\nexport const AGENT_ROLE_DISPLAY: Record<AgentRole, string> = {\n pilot: 'Pilot',\n copilot: 'Copilot',\n pilot_specialist: 'Pilot Specialist',\n copilot_specialist: 'Copilot Specialist',\n pilot_advisor: 'Pilot Advisor',\n copilot_advisor: 'Copilot Advisor',\n monitor: 'Monitor',\n conversation_evaluator: 'Conversation Evaluator',\n message_evaluator: 'Message Evaluator',\n summarizer: 'Summarizer',\n};\n\n// ---------------------------------------------------------------------------\n// AI Modes\n// ---------------------------------------------------------------------------\n\nexport const AI_MODES = ['pilot', 'copilot', 'pilot+copilot', 'turned_off'] as const;\n\nexport type AiMode = (typeof AI_MODES)[number];\n\nexport const COPILOT_MODES: readonly AiMode[] = ['pilot+copilot', 'copilot'];\n\n/** Maps AI mode to human-readable display label. */\nexport const AI_MODE_DISPLAY: Record<AiMode, string> = {\n pilot: 'Pilot',\n copilot: 'Copilot',\n 'pilot+copilot': 'Pilot+Copilot',\n turned_off: 'Turned Off',\n};\n\n// ---------------------------------------------------------------------------\n// Identifier validation\n// ---------------------------------------------------------------------------\n\n/**\n * Injection-safe whitelist for `user_id` values that may appear in URL paths,\n * R2 key prefixes, ScheduleSession scope keys, and interpolated SQL. Accepts\n * both HubDO-generated UUIDs and WorkOS-style ids (e.g. `user_01KMR9AZ...`)\n * while excluding every character that could break out of a single-quoted SQL\n * literal or create structural ambiguity in `:`-delimited keys.\n */\nexport const SAFE_USER_ID_REGEX = /^[A-Za-z0-9_-]{1,64}$/;\n\n// ---------------------------------------------------------------------------\n// Supported UI locales — proxy-to-backend auth-locale contract\n// ---------------------------------------------------------------------------\n\n// Single source of truth for frontend cookie + backend header locale validation.\nexport const SUPPORTED_LOCALES = ['en', 'pt', 'es'] as const;\nexport type SupportedLocale = (typeof SUPPORTED_LOCALES)[number];\n\nexport function isSupportedLocale(value: string): value is SupportedLocale {\n return (SUPPORTED_LOCALES as readonly string[]).includes(value);\n}\n\n/** Header set by the same-origin proxy from the auth-locale cookie. */\nexport const AUTH_LOCALE_HEADER = 'x-wayai-auth-locale';\n","import { z } from 'zod';\n\nexport const uuidSchema = z.string().uuid();\n\nexport const paginationSchema = z.object({\n limit: z.coerce.number().int().min(1).max(100).default(50),\n offset: z.coerce.number().int().min(0).default(0),\n});\n\nexport const timestampSchema = z.string().datetime();\n\nexport const idParamSchema = z.object({\n id: uuidSchema,\n});\n\n// =============================================================================\n// UTILITY TYPES\n// =============================================================================\n\n/** Generic JSON-compatible value (replaces the old Supabase-generated Json type) */\nexport type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[];\n\n// =============================================================================\n// RESPONSE TYPE WRAPPERS\n// =============================================================================\n\nexport interface ApiErrorResponse {\n error: string;\n message: string;\n details?: Record<string, unknown>;\n}\n\nexport interface ApiDataResponse<T> {\n data: T;\n}\n\nexport interface ApiListResponse<T> {\n data: T[];\n}\n\nexport interface ApiSuccessResponse {\n success: true;\n}\n","import { z } from 'zod';\nimport { uuidSchema } from '../common';\n\n// 9 Cloudflare DurableObject location hints. `sam`, `afr`, `me` currently route\n// to the nearest supported region (CF doesn't yet spawn DOs there) — see\n// https://developers.cloudflare.com/durable-objects/reference/data-location/\n// The customer-stored value takes effect natively once CF expands support.\nexport const primaryRegionSchema = z.enum([\n 'wnam', 'enam', 'sam', 'weur', 'eeur', 'apac', 'oc', 'afr', 'me',\n]);\nexport type PrimaryRegion = z.infer<typeof primaryRegionSchema>;\n\n// Source of the placement_region value resolved by the backend cascade.\nexport const placementSourceSchema = z.enum([\n 'hub_config', 'org_config', 'parent_cascade',\n 'cf_colo', 'country', 'fallback',\n]);\nexport type PlacementSource = z.infer<typeof placementSourceSchema>;\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\nexport const orgIdParam = z.object({\n id: uuidSchema,\n});\n\nexport const orgAdminIdParam = z.object({\n id: uuidSchema,\n adminId: z.string().min(1),\n});\n\nexport const createOrganizationBody = z.object({\n organization_name: z.string().min(1, 'organization_name is required'),\n // Write-once at creation; updateOrganizationBody does not accept this.\n primary_region: primaryRegionSchema.optional(),\n});\n\nexport const updateOrganizationBody = z.object({\n organization_name: z.string().min(1).optional(),\n organization_avatar_url: z.string().url().nullable().optional(),\n timezone: z.string().optional(),\n business_hours: z.unknown().optional(),\n}).passthrough();\n\nexport const addOrgAdminBody = z.object({\n user_email: z.string().email('valid email is required'),\n});\n\n// =============================================================================\n// INFERRED TYPES (for consumers that need request types without importing zod)\n// =============================================================================\n\nexport type CreateOrganizationInput = z.infer<typeof createOrganizationBody>;\nexport type UpdateOrganizationInput = z.infer<typeof updateOrganizationBody>;\nexport type AddOrgAdminInput = z.infer<typeof addOrgAdminBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\nexport interface OrganizationResponse {\n organization_id: string;\n created_at: string;\n organization_name: string;\n updated_at: string;\n created_by: string;\n billing_currency: string;\n primary_region: PrimaryRegion | null;\n placement_region: PrimaryRegion | null;\n placement_source: PlacementSource | null;\n}\n\nexport interface OrganizationAdminUserResponse {\n organization_admin_user_id: string;\n organization_id: string;\n created_at: string;\n updated_at: string;\n user_id: string | null;\n enabled: boolean;\n user_email: string;\n is_owner: boolean;\n}\n\nexport interface GetOrganizationResponse {\n data: {\n organization: OrganizationResponse;\n admin_users: OrganizationAdminUserResponse[];\n };\n}\n\nexport interface CreateOrganizationResponse {\n data: OrganizationResponse[];\n}\n\nexport interface UpdateOrganizationResponse {\n data: OrganizationResponse[];\n}\n\nexport interface AddOrgAdminResponse {\n data: OrganizationAdminUserResponse[];\n}\n\n// Composite org-view endpoint — returns everything OrganizationDetailView needs\n// (organization + admins + tags) in one request to collapse the 2–3 parallel\n// fetches that would otherwise fire on every org-settings entry.\nexport interface GetOrganizationViewResponse {\n data: {\n organization: OrganizationResponse;\n admin_users: OrganizationAdminUserResponse[];\n tags: Array<{\n tag_id: string;\n name: string;\n display_name: string | null;\n color: string | null;\n organization_id: string;\n created_at: string;\n updated_at: string;\n }>;\n };\n}\n","import { z } from 'zod';\nimport { uuidSchema } from '../common';\nimport { AGENT_ROLES, type AgentRole } from '../../constants';\nimport { SUMMARIZATION_THRESHOLD_MIN, SUMMARIZATION_THRESHOLD_MAX } from '../../summarizer';\n\n// Relocated from the hub (`updateHubBody`) to the summarizer agent — preserve the\n// original int+range guard on the write paths that set it. `.passthrough()` keeps\n// other agent keys flowing; this explicit key restores validation for this one.\nconst summarizationThresholdField = z\n .number()\n .int()\n .min(SUMMARIZATION_THRESHOLD_MIN)\n .max(SUMMARIZATION_THRESHOLD_MAX)\n .nullable()\n .optional();\n\n// Relocated from the hub (`updateHubBody`) to the monitor agent — restore the\n// guards the hub UI enforced (`delay_seconds >= 10`) on every write path so a caller\n// (REST/CLI/MCP) can't persist an invalid monitor schedule. JSON object on the monitor\n// agent column; `.passthrough()` keeps other agent keys flowing. Meaningful only on\n// `monitor` agents. `flag_conditions` mirrors the FlagCondition shape used elsewhere.\nconst monitorConfigField = z\n .object({\n delay_seconds: z.number().int().min(10),\n flag_conditions: z\n .array(\n z.object({\n variable: z.string(),\n operator: z.enum(['=', '!=']),\n value: z.union([z.string(), z.number()]),\n }),\n )\n .optional(),\n })\n .passthrough()\n .nullable()\n .optional();\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\nexport const agentIdParam = z.object({\n id: uuidSchema,\n});\n\nexport const listAgentsQuery = z.object({\n hub_id: uuidSchema,\n});\n\nexport const agentConnectionsQuery = z.object({\n hub_id: uuidSchema,\n});\n\nexport const createAgentBody = z.object({\n agent_name: z.string().min(1),\n hub_id: uuidSchema,\n agent_role: z.enum(AGENT_ROLES),\n additional_context_template: z.string().max(20000).optional(),\n summarization_threshold_tokens: summarizationThresholdField,\n monitor_config: monitorConfigField,\n}).passthrough();\n\nexport const updateAgentBody = z.object({\n additional_context_template: z.string().max(20000).optional(),\n summarization_threshold_tokens: summarizationThresholdField,\n monitor_config: monitorConfigField,\n}).passthrough();\n\n// =============================================================================\n// INFERRED TYPES (for consumers that need request types without importing zod)\n// =============================================================================\n\nexport type CreateAgentInput = z.infer<typeof createAgentBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n/** Full agent row as returned by select('*') on the agent table */\nexport interface AgentResponse {\n agent_id: string;\n agent_name: string;\n created_at: string;\n agent_sid: string | null;\n instructions: string;\n response_format: string;\n updated_at: string | null;\n hub_id: string;\n connection_id: string;\n agent_role: AgentRole;\n schema_json: Record<string, unknown> | null;\n schema_name: string | null;\n agent_settings: Record<string, unknown> | null;\n instructions_file_id: string | null;\n additional_context_template: string;\n enabled: boolean;\n include_message_timestamps: boolean;\n auto_format: boolean;\n /** Conversation-flagging conditions, evaluated post-close by the\n * `conversation_evaluator` agent (relocated from the hub column). Only\n * meaningful on `conversation_evaluator` agents; null/omitted elsewhere. */\n flag_conditions: Array<{ variable: string; operator: '=' | '!='; value: string | number }> | null;\n /** Token threshold that fires the rolling summarizer (sum of input + cache_read +\n * cache_creation). A `summarizer` agent setting (relocated from the hub column).\n * Only meaningful on `summarizer` agents; null/omitted elsewhere → falls back to\n * DEFAULT_SUMMARIZATION_THRESHOLD_TOKENS at the read site. */\n summarization_threshold_tokens?: number | null;\n /** Monitor scheduling + flagging config ({delay_seconds, flag_conditions}). A\n * `monitor` agent setting (relocated from the hub column). Only meaningful on\n * `monitor` agents; null/omitted elsewhere. The monitor is NOT auto-provisioned. */\n monitor_config?: {\n delay_seconds: number;\n flag_conditions?: Array<{ variable: string; operator: '=' | '!='; value: string | number }>;\n } | null;\n}\n\n/** Agent parameter row */\nexport interface AgentParameterResponse {\n agent_parameter_id: string;\n created_at: string;\n agent_id: string;\n parameter_name: string;\n parameter_type: 'string' | 'number' | 'boolean' | 'integer' | 'enum';\n parameter_description: string;\n parameter_label: string | null;\n parameter_enum: string[] | null;\n parameter_required: boolean;\n variable_category: 'quality' | 'satisfaction' | 'compliance' | 'categorization' | null;\n is_summary: boolean;\n}\n\n/** Simplified agent connection detail returned by fetchAgentById */\nexport interface AgentConnectionDetail {\n connection_id: string;\n connection_display_name: string | null;\n connector_id: string;\n agent_settings_schema: Record<string, unknown> | null;\n}\n\n/** Connection with nested connector, returned by the /connections endpoint */\nexport interface AgentConnectionWithConnector {\n connection_id: string;\n created_at: string;\n service_name: string | null;\n api_key: string | null;\n updated_at: string | null;\n hub_id: string;\n access_token: string | null;\n access_token_expires_at: string | null;\n access_token_secret_id: string | null;\n account_sid: string | null;\n api_key_secret_id: string | null;\n authentication_type: string;\n enabled: boolean;\n connector_id: string;\n connector_name: string;\n password: string | null;\n password_secret_id: string | null;\n connection_display_name: string | null;\n connector_type: string;\n refresh_token: string | null;\n refresh_token_expires_at: string | null;\n refresh_token_secret_id: string | null;\n state: Record<string, unknown> | null;\n username: string | null;\n base_url: string | null;\n connection_headers: Record<string, unknown> | null;\n settings: Record<string, unknown> | null;\n token_refresh_config: Record<string, unknown> | null;\n next_access_token_refresh_at: string | null;\n next_refresh_token_renewal_at: string | null;\n last_token_refresh_at: string | null;\n last_token_refresh_error: string | null;\n organization_credential_id: string | null;\n connector: {\n connector_id: string;\n created_at: string;\n service_name: string;\n authentication_type: string;\n init_endpoint: string | null;\n connector_type: string;\n connector_name: string;\n unique_per_hub: boolean;\n account_sid_placeholder: string | null;\n models: string[] | null;\n is_internal: boolean;\n connector_module: string | null;\n enabled: boolean;\n connector_settings_schema: Record<string, unknown> | null;\n agent_settings_schema: Record<string, unknown> | null;\n channel_settings_schema: Record<string, unknown> | null;\n tool_settings_schema: Record<string, unknown> | null;\n connector_credential_schema: Record<string, unknown> | null;\n token_refresh_config: Record<string, unknown>;\n connector_description: string | null;\n } | null;\n}\n\n// -- Endpoint response wrappers --\n\nexport interface ListAgentsResponse {\n data: AgentResponse[];\n}\n\nexport interface GetAgentResponse {\n data: {\n agent: AgentResponse;\n agent_connections: AgentConnectionDetail[];\n agent_parameters: AgentParameterResponse[];\n };\n}\n\nexport interface CreateAgentResponse {\n data: AgentResponse[];\n}\n\nexport interface UpdateAgentResponse {\n data: AgentResponse[];\n}\n\nexport interface ListAgentConnectionsResponse {\n data: AgentConnectionWithConnector[];\n}\n\nexport interface ListAgentParametersResponse {\n data: AgentParameterResponse[];\n}\n\nexport interface CreateAgentParametersResponse {\n data: AgentParameterResponse[];\n}\n","// Summarizer constants — shared across HubDO, ConversationDO, and buildAgentSettings.\n\nexport const RESERVED_SUMMARY_STATE_SLUG = 'conversation_summary' as const;\nexport const DEFAULT_SUMMARIZATION_THRESHOLD_TOKENS = 120000;\nexport const SUMMARIZATION_THRESHOLD_MIN = 1000;\nexport const SUMMARIZATION_THRESHOLD_MAX = 1_000_000;\nexport const SUMMARIZER_FAILURE_THRESHOLD = 3;\nexport const SUMMARIZER_DEBOUNCE_MS = 60_000;\n\n/** Strict invariant — load-bearing for expand_summary. Extra fields allowed; anchors are not. */\nexport const SUMMARIZER_INVARIANT_SCHEMA = {\n type: 'object',\n required: ['sections'],\n properties: {\n sections: {\n type: 'array',\n items: {\n type: 'object',\n required: ['id', 'message_id_start', 'message_id_end'],\n properties: {\n id: { type: 'string', minLength: 1 },\n message_id_start: { type: 'string', minLength: 1 },\n message_id_end: { type: 'string', minLength: 1 },\n },\n },\n },\n },\n} as const;\n\n/** Default user-editable schema seeded for new hubs. */\nexport const SUMMARIZER_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['sections'],\n properties: {\n sections: {\n type: 'array',\n description: 'Topically-grouped summary units covering the conversation up to the verbatim tail. Each section carries a message-range anchor used by expand_summary.',\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['id', 'topic', 'summary', 'message_id_start', 'message_id_end'],\n properties: {\n id: {\n type: 'string',\n minLength: 1,\n description: 'Stable identifier for this section (e.g. \"sec_01\"). Used by expand_summary to fetch original messages.',\n },\n topic: {\n type: 'string',\n minLength: 1,\n description: 'Short topic label (1-5 words) describing what this section covers.',\n },\n summary: {\n type: 'string',\n minLength: 1,\n description: 'Concise prose summary of what happened in this section. Preserve concrete details (names, prices, decisions); compress filler.',\n },\n message_id_start: {\n type: 'string',\n minLength: 1,\n description: 'message_id of the FIRST message included in this section.',\n },\n message_id_end: {\n type: 'string',\n minLength: 1,\n description: 'message_id of the LAST message included in this section.',\n },\n key_decisions: {\n type: 'array',\n items: { type: 'string' },\n description: 'Decisions or commitments made in this section (e.g. \"agreed price: $79/yr\").',\n },\n open_threads: {\n type: 'array',\n items: { type: 'string' },\n description: 'Unresolved threads opened in this section that may need follow-up.',\n },\n },\n },\n },\n },\n} as const;\n\n/** System prompt for the summarizer agent. */\nexport const SUMMARIZER_INSTRUCTIONS = `You are the conversation summarizer. Your job is to compress older messages of a conversation into a structured JSON summary while preserving everything that matters for the agents who will continue the conversation.\n\nRules:\n1. Read the entire input. Each message has a \\`message_id\\` attribute — record them exactly.\n2. Group messages into topical sections. A section is one coherent thread (a question being resolved, a topic being discussed, a decision being made). Aim for one section per topic; don't fragment.\n3. For each section, set:\n - \\`id\\`: a short stable identifier (e.g. \"sec_01\", \"sec_02\"). Use sequential numbering.\n - \\`topic\\`: 1–5 words naming the thread.\n - \\`summary\\`: concise prose. Preserve concrete details (exact names, prices, IDs, decisions, commitments, dates). Compress filler. Do NOT invent facts.\n - \\`message_id_start\\` and \\`message_id_end\\`: the exact message_id of the FIRST and LAST messages you included in this section. These are load-bearing — they must reference real messages from the input.\n - \\`key_decisions\\`: decisions or commitments made (optional).\n - \\`open_threads\\`: unresolved items that may need follow-up (optional).\n4. If a prior summary is provided, the new summary should fold it in: re-use stable section ids where the underlying messages are unchanged, add new sections for the new messages. Replace the prior summary in its entirety with your output.\n5. Emit ONLY valid JSON matching the schema. No prose preamble, no markdown fences.\n6. Tone: factual, third-person, terse.`;\n\n/** Appended to non-background agents' system prompt when the hub has a conversation_summary state. */\nexport const SUMMARIZER_PROMPT_ADDENDUM = `\n---\n**Conversation summary available.** Older parts of this conversation may have been compressed into a structured summary delivered as a \\`<conversation_summary>\\` block prepended to the message history. Each section in that summary carries an \\`id\\` and a message-range anchor.\n\nIf a section's summary is insufficient for your current task — for example, you need the user's exact wording, the precise text of a previous decision, or details that aren't captured in the prose — call the \\`expand_summary\\` tool with the section's \\`id\\` to retrieve the original messages. Don't confabulate from a compressed summary when the originals are one tool call away.`;\n","// Slug primitive shared by kanban_status and state — strict subset of ClickHouse VALID_JSON_PATH_REGEX so analytics paths never need quoting.\n\nimport { z } from 'zod';\n\nexport const SLUG_REGEX = /^[a-z][a-z0-9_]{0,49}$/;\n\nexport const slugSchema = z\n .string()\n .regex(\n SLUG_REGEX,\n 'slug must be lowercase, start with a letter, contain only [a-z0-9_], and be 1–50 characters',\n );\n\nconst INVISIBLE_NAME_CHARS = /[\\s\\p{Default_Ignorable_Code_Point}]/gu;\n\nexport function visibleLength(s: string): number {\n return s.replace(INVISIBLE_NAME_CHARS, '').length;\n}\n","/**\n * Zod schemas for kanban status configuration on a hub.\n *\n * Single source of truth for cross-field validation invariants enforced on\n * every write path that lands `kanban_statuses` in HubDO SQLite:\n * - REST: createHubBody / updateHubBody (workers/shared/src/contracts/setup/hubs.ts)\n * - CI: hubAsCodeConfigSchema (workers/shared/src/contracts/ci.ts)\n *\n * Field shapes mirror the existing TypeScript interfaces:\n * - HubAsCodeKanbanStatus / HubAsCodeKanbanFollowup (contracts/ci.ts)\n * - KanbanStatusConfig / FollowupConfig (backend/scheduling/types.ts)\n *\n * Human-facing constraint summary lives in skills/wayai/SKILL.md \"Kanban &\n * States — Constraints\".\n *\n * `additional_context_schema` is a JSON Schema (Draft 2020-12). Structural\n * shape is gated here (size, reserved-name); semantic well-formedness\n * (`ajv.validateSchema`) runs at the backend route handler so AJV does not\n * leak into shared/frontend bundles.\n */\n\nimport { z } from 'zod';\nimport { SLUG_REGEX, slugSchema, visibleLength } from './slug';\n\n// Defensive bounds. Typical hubs have 3–10 statuses with 0–3 followups each;\n// caps are generous on intent and tight enough that the per-request\n// superRefine cost stays bounded. Mirrors MAX_GRANTS in contracts/tokens.ts.\nconst MAX_KANBAN_STATUSES = 50;\nconst MAX_FOLLOWUPS_PER_STATUS = 20;\nexport const MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES = 16384;\n\n/**\n * Reserved placeholder name in `additional_instructions` templates: dumps the\n * full payload as JSON. Schemas may not declare this as a top-level property.\n */\nexport const RESERVED_TEMPLATE_DUMP_NAME = 'additional_data';\n\n/** Matches `{{path}}` and `{{ path.to.field }}` in templates. */\nconst PLACEHOLDER_RE = /\\{\\{\\s*([a-zA-Z_][a-zA-Z0-9_.]*)\\s*\\}\\}/g;\n\n/**\n * Kanban slug — alias of the shared SLUG_REGEX. Used as the immutable runtime\n * identifier (`conversation.kanban_status`, ClickHouse `data.meta.kanban_status`,\n * native tool params, transition refs).\n */\nexport const KANBAN_SLUG_REGEX = SLUG_REGEX;\nexport const kanbanStatusSlugSchema = slugSchema;\n\n// =============================================================================\n// FOLLOWUP SCHEMA\n// =============================================================================\n\nexport const followupSchema = z\n .object({\n id: z.string().optional(),\n order: z.number().int().nonnegative(),\n type: z.enum(['inactivity', 'before_event']),\n threshold: z.number().int().positive(),\n timeUnit: z.enum(['seconds', 'minutes', 'hours', 'days']),\n instructions: z.string().optional(),\n excludedWeekDays: z.array(z.number().int().min(0).max(6)).optional(),\n excludeHolidays: z.boolean().optional(),\n excludedTimeStart: z.string().optional(),\n excludedTimeEnd: z.string().optional(),\n delivery_mode: z.enum(['agent_generated', 'direct']).optional(),\n direct_text: z.string().optional(),\n template_whatsapp_id: z.string().nullable().optional(),\n outside_window_policy: z.enum(['route_to_team', 'skip']).optional(),\n include_tools: z.boolean().optional(),\n })\n .passthrough()\n .superRefine((followup, ctx) => {\n if (followup.delivery_mode === 'direct' && !followup.direct_text?.trim()) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['direct_text'],\n message: 'direct_text is required and must be non-empty when delivery_mode=\"direct\"',\n });\n }\n });\n\n// =============================================================================\n// PER-STATUS SCHEMA\n// =============================================================================\n\n/**\n * Mutually-exclusive boolean flag pairs. Order within each pair is purely for\n * the error path: the issue is anchored on the second flag (the one the user\n * most recently toggled in typical UI flows).\n */\nconst EXCLUSIVE_FLAG_PAIRS = [\n ['isInitialStatus', 'triggersAgentResponse'],\n ['isInitialStatus', 'allowsAgentUpdate'],\n ['isInitialStatus', 'isTerminalStatus'],\n ['isInitialStatus', 'isSchedulingStatus'],\n ['triggersAgentResponse', 'allowsAgentUpdate'],\n ['triggersAgentResponse', 'isTerminalStatus'],\n] as const;\n\nexport const kanbanStatusSchema = z\n .object({\n slug: kanbanStatusSlugSchema,\n name: z\n .string()\n .min(1, 'name is required')\n .max(100, 'name must be 100 characters or fewer')\n .refine((v) => visibleLength(v) > 0, 'name must not be blank'),\n order: z.number().int().nonnegative().optional(),\n color: z.string().optional(),\n isInitialStatus: z.boolean().optional(),\n triggersAgentResponse: z.boolean().optional(),\n allowsAgentUpdate: z.boolean().optional(),\n isTerminalStatus: z.boolean().optional(),\n isSchedulingStatus: z.boolean().optional(),\n eventName: z.string().optional(),\n additional_instructions: z.string().optional(),\n additional_context_schema: z\n .record(z.unknown())\n .refine(\n (s) => JSON.stringify(s).length <= MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES,\n `additional_context_schema must be at most ${MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES} bytes when JSON-serialized`,\n )\n .optional(),\n followups: z\n .array(followupSchema)\n .max(MAX_FOLLOWUPS_PER_STATUS, `followups must have at most ${MAX_FOLLOWUPS_PER_STATUS} entries`)\n .optional(),\n /** Slugs this status may transition to. `undefined` = unrestricted (any\n * next status). Empty array `[]` is rejected — author must use\n * `isTerminalStatus: true` to express \"no outbound transitions\". */\n allowed_next_statuses: z\n .array(z.string())\n .min(1, 'allowed_next_statuses cannot be empty — use isTerminalStatus: true for no outbound transitions')\n .optional(),\n })\n .passthrough()\n .superRefine((status, ctx) => {\n const label = status.name ? `\"${status.name}\"` : status.slug ? `\"${status.slug}\"` : '<unnamed>';\n\n for (const [a, b] of EXCLUSIVE_FLAG_PAIRS) {\n if (status[a] === true && status[b] === true) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [b],\n message: `kanban status ${label}: ${a} and ${b} cannot both be true`,\n });\n }\n }\n\n if (status.isSchedulingStatus === true && !status.eventName?.trim()) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['eventName'],\n message: `kanban status ${label}: eventName is required when isSchedulingStatus=true`,\n });\n }\n\n if (\n Array.isArray(status.followups) &&\n status.followups.some((f) => f?.type === 'before_event') &&\n status.isSchedulingStatus !== true\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['followups'],\n message: `kanban status ${label}: before_event followups require isSchedulingStatus=true on the parent status`,\n });\n }\n\n // Reserved-name collision: `additional_data` is the magic dump placeholder.\n if (status.additional_context_schema && typeof status.additional_context_schema === 'object') {\n const schema = status.additional_context_schema as Record<string, unknown>;\n const props = schema.properties;\n if (props && typeof props === 'object' && RESERVED_TEMPLATE_DUMP_NAME in (props as object)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['additional_context_schema', 'properties', RESERVED_TEMPLATE_DUMP_NAME],\n message: `kanban status ${label}: \"${RESERVED_TEMPLATE_DUMP_NAME}\" is a reserved template placeholder name and cannot be used as a top-level schema property`,\n });\n }\n }\n });\n\n// =============================================================================\n// ARRAY SCHEMA — cross-status invariants\n// =============================================================================\n\nexport const kanbanStatusesArraySchema = z\n .array(kanbanStatusSchema)\n .max(MAX_KANBAN_STATUSES, `kanban_statuses must have at most ${MAX_KANBAN_STATUSES} entries`)\n .superRefine((statuses, ctx) => {\n if (statuses.length === 0) return;\n\n const initialIndices = statuses\n .map((s, i) => ({ s, i }))\n .filter(({ s }) => s.isInitialStatus === true);\n\n if (initialIndices.length === 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [],\n message: 'kanban_statuses: exactly one status must have isInitialStatus=true (found 0)',\n });\n } else if (initialIndices.length > 1) {\n const slugs = initialIndices.map(({ s }) => s.slug).join(', ');\n for (const { i } of initialIndices) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [i, 'isInitialStatus'],\n message: `kanban_statuses: only one status may have isInitialStatus=true (found ${initialIndices.length}: ${slugs})`,\n });\n }\n }\n\n // Unique slugs (slugs are the runtime identifier — duplicates corrupt routing).\n const seenSlugs = new Map<string, number[]>();\n statuses.forEach((s, i) => {\n const key = s.slug;\n if (!key) return;\n const arr = seenSlugs.get(key) ?? [];\n arr.push(i);\n seenSlugs.set(key, arr);\n });\n for (const [slug, indices] of seenSlugs) {\n if (indices.length > 1) {\n for (const i of indices) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [i, 'slug'],\n message: `kanban_statuses: duplicate slug \"${slug}\"`,\n });\n }\n }\n }\n\n // allowed_next_statuses entries must reference sibling slugs.\n const validSlugs = new Set(statuses.map((s) => s.slug).filter(Boolean));\n statuses.forEach((s, i) => {\n if (!Array.isArray(s.allowed_next_statuses)) return;\n s.allowed_next_statuses.forEach((target, j) => {\n if (typeof target !== 'string' || target.length === 0) return;\n if (!validSlugs.has(target)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [i, 'allowed_next_statuses', j],\n message: `kanban_statuses[${i}] (slug \"${s.slug}\"): allowed_next_statuses references unknown slug \"${target}\"`,\n });\n }\n });\n });\n });\n\n// =============================================================================\n// LINT — non-blocking warnings (returned alongside successful saves)\n// =============================================================================\n\nexport interface KanbanLintWarning {\n code: 'unreachable' | 'placeholder_unresolved';\n slug: string;\n name: string;\n message: string;\n}\n\n/**\n * Lint pass for kanban_statuses. Returns warnings that don't block save.\n *\n * - `unreachable`: a non-initial status that no other status lists in its\n * `allowed_next_statuses`. Conversations cannot reach it.\n * - `placeholder_unresolved`: an `{{path}}` placeholder in `additional_instructions`\n * that does not match any path in the declared `additional_context_schema`.\n *\n * Run after Zod validation succeeds; surface in the response so authors can\n * see warnings without being blocked mid-edit.\n */\nexport function lintKanbanStatuses(statuses: KanbanStatusInput[]): KanbanLintWarning[] {\n if (!Array.isArray(statuses) || statuses.length === 0) return [];\n\n const slugs = statuses.map((s) => s.slug).filter(Boolean);\n if (slugs.length === 0) return [];\n\n // -- Reachability ---------------------------------------------------------\n const allSlugs = new Set(slugs);\n const inboundFromAny = new Set<string>();\n const inboundExplicit = new Map<string, Set<string>>();\n\n for (const s of statuses) {\n if (!s.slug) continue;\n if (s.isTerminalStatus === true) continue;\n if (s.allowed_next_statuses === undefined) {\n for (const other of allSlugs) {\n if (other !== s.slug) inboundFromAny.add(other);\n }\n } else {\n for (const target of s.allowed_next_statuses) {\n if (!allSlugs.has(target)) continue;\n const set = inboundExplicit.get(target) ?? new Set<string>();\n set.add(s.slug);\n inboundExplicit.set(target, set);\n }\n }\n }\n\n const warnings: KanbanLintWarning[] = [];\n for (const s of statuses) {\n if (!s.slug) continue;\n if (s.isInitialStatus === true) continue;\n const hasInbound = inboundFromAny.has(s.slug) || (inboundExplicit.get(s.slug)?.size ?? 0) > 0;\n if (!hasInbound) {\n warnings.push({\n code: 'unreachable',\n slug: s.slug,\n name: s.name,\n message: `kanban status \"${s.slug}\" is unreachable — no other status transitions to it and it is not isInitialStatus`,\n });\n }\n }\n\n // -- Placeholder paths vs schema -----------------------------------------\n for (const s of statuses) {\n if (!s.slug || !s.additional_instructions) continue;\n const paths = extractPlaceholderPaths(s.additional_instructions);\n if (paths.length === 0) continue;\n const schema = s.additional_context_schema;\n for (const path of paths) {\n if (path === RESERVED_TEMPLATE_DUMP_NAME) continue;\n if (!schema || !isPathInJsonSchema(schema, path)) {\n warnings.push({\n code: 'placeholder_unresolved',\n slug: s.slug,\n name: s.name,\n message: `kanban status \"${s.slug}\": template placeholder \"{{${path}}}\" does not match any path in additional_context_schema`,\n });\n }\n }\n }\n\n return warnings;\n}\n\nfunction extractPlaceholderPaths(template: string): string[] {\n const out = new Set<string>();\n for (const match of template.matchAll(PLACEHOLDER_RE)) {\n out.add(match[1]);\n }\n return Array.from(out);\n}\n\n/**\n * Lint-side path resolver against a JSON Schema (Draft 2020-12 subset).\n * Walks `properties` for objects and `items` for arrays. Numeric segments\n * after an array indirect into `items`. Refs / oneOf / unknown shapes\n * return false (lint is best-effort; runtime renders empty string anyway).\n *\n * Treats an absent `type` as object-like when `properties` is present\n * (legal per JSON Schema spec — type is not required) and array-like when\n * `items` is present. Without these, schemas authored as raw YAML by CLI/MCP\n * users (who often omit `type`) would false-positive every placeholder.\n */\nfunction isPathInJsonSchema(schema: unknown, path: string): boolean {\n if (typeof schema !== 'object' || schema === null) return false;\n const segments = path.split('.');\n let cur: unknown = schema;\n for (const seg of segments) {\n if (typeof cur !== 'object' || cur === null) return false;\n const obj = cur as Record<string, unknown>;\n const propsObj = obj.properties && typeof obj.properties === 'object' ? (obj.properties as Record<string, unknown>) : null;\n const itemsObj = obj.items && typeof obj.items === 'object' ? (obj.items as Record<string, unknown>) : null;\n const isObjectLike = obj.type === 'object' || (obj.type === undefined && propsObj !== null);\n const isArrayLike = obj.type === 'array' || (obj.type === undefined && itemsObj !== null && propsObj === null);\n if (isObjectLike && propsObj) {\n if (!(seg in propsObj)) return false;\n cur = propsObj[seg];\n } else if (isArrayLike && itemsObj) {\n if (!/^\\d+$/.test(seg)) return false;\n cur = itemsObj;\n } else {\n return false;\n }\n }\n return true;\n}\n\n// =============================================================================\n// INFERRED TYPES\n// =============================================================================\n\nexport type FollowupInput = z.infer<typeof followupSchema>;\nexport type KanbanStatusInput = z.infer<typeof kanbanStatusSchema>;\nexport type KanbanStatusesInput = z.infer<typeof kanbanStatusesArraySchema>;\n","import { z } from 'zod';\nimport { uuidSchema } from '../common';\nimport type { AiMode } from '../../constants';\nimport { kanbanStatusesArraySchema, type KanbanLintWarning } from './kanban';\nimport { primaryRegionSchema, type PrimaryRegion, type PlacementSource } from './organizations';\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\n// Param schemas\nexport const hubIdParam = z.object({ id: uuidSchema });\nexport const hubAdminIdParam = z.object({ id: uuidSchema, adminId: uuidSchema });\nexport const hubUserIdParam = z.object({ id: uuidSchema, hubUserId: uuidSchema });\nexport const hubIdentityIdParam = z.object({ id: uuidSchema, identityId: uuidSchema });\nexport const hubTeamIdParam = z.object({ id: uuidSchema, teamId: uuidSchema });\nexport const hubTeamUserDeleteParam = z.object({ id: uuidSchema, teamUserId: uuidSchema });\n// Query schemas\nexport const hubSchemaQuery = z.object({ hub_id: uuidSchema });\n\n// Body schemas\nexport const createHubBody = z.object({\n organization_id: uuidSchema,\n hub_name: z.string().min(1, 'hub_name is required'),\n hub_description: z.string().optional(),\n kanban_statuses: kanbanStatusesArraySchema.nullable().optional(),\n // Write-once at creation; updateHubBody does not accept this.\n primary_region: primaryRegionSchema.optional(),\n}).passthrough();\n\n// Enum fields validated; other fields pass through to the backend updateHub() allowlist.\nexport const updateHubBody = z.object({\n support_model: z.enum(['conversation', 'account']).optional(),\n unassigned_policy: z\n .enum(['default_team', 'auto_assign_random', 'auto_assign_round_robin', 'pull_queue'])\n .optional(),\n default_hub_team_id: uuidSchema.nullable().optional(),\n kanban_statuses: kanbanStatusesArraySchema.nullable().optional(),\n // summarization_threshold_tokens relocated to the summarizer AGENT (PR4) — validated/\n // persisted via the agent path (.passthrough() agent body → HubDO column), not here.\n auto_close_inactive_days: z.number().int().min(1).max(180).optional(),\n // Channel contact access control. Enum-validated explicitly (not via passthrough)\n // so `language`/`access_approval_role` can't reach the DB with an invalid value.\n language: z.enum(['en', 'pt', 'es']).optional(),\n access_request_message: z.string().max(1000).nullable().optional(),\n access_approval_role: z.enum(['admin', 'team']).optional(),\n}).passthrough();\n\nexport const addHubAdminBody = z.object({\n user_email: z.string().email('valid email is required'),\n});\n\nexport const addHubIdentityAuthorizationBody = z.object({\n identity_value: z.string().min(1),\n identity_type: z.string().min(1),\n channel_type: z.string().min(1),\n});\n\n// Channel contact access control: approve / block / unblock a contact. The row is\n// located by `contact_access_id` OR the (identity_type, identity_value, channel_type)\n// tuple; block/unblock may also carry the conversation's user_id so open conversations\n// can be transitioned even before a contact_access row exists (block on `everyone`).\nexport const contactDecisionBody = z.object({\n contact_access_id: uuidSchema.optional(),\n identity_type: z.string().min(1).optional(),\n identity_value: z.string().min(1).optional(),\n channel_type: z.string().min(1).optional(),\n channel_id: uuidSchema.optional(),\n connection_id: uuidSchema.optional(),\n user_id: uuidSchema.optional(),\n sender_display_name: z.string().max(200).optional(),\n});\n\nexport const approveContactBody = contactDecisionBody.extend({\n user_name: z.string().min(1).max(120).optional(),\n});\n\nexport const listContactAccessQuery = z.object({\n status: z.enum(['pending', 'blocked']).optional(),\n});\n\nexport const createHubTeamBody = z.object({\n team_name: z.string().min(1, 'team_name is required'),\n});\n\nexport const updateHubTeamBody = z.object({\n team_name: z.string().min(1).optional(),\n}).passthrough();\n\nexport const addHubTeamUserBody = z.object({\n user_email: z.string().email('valid email is required'),\n});\n\n/** Account-mode: reassign a hub_user to a different team (or clear via null). */\nexport const reassignHubUserBody = z.object({\n hub_team_id: uuidSchema.nullable(),\n});\n\nexport const replicatePreviewBody = z.object({\n preview_label: z\n .string()\n .max(60)\n .optional()\n .nullable()\n .transform((v) => {\n if (v == null) return null;\n const trimmed = v.trim();\n return trimmed || null;\n }),\n});\n\n// =============================================================================\n// INFERRED TYPES (for consumers that need request types without importing zod)\n// =============================================================================\n\nexport type CreateHubInput = z.infer<typeof createHubBody>;\nexport type UpdateHubInput = z.infer<typeof updateHubBody>;\nexport type AddHubAdminInput = z.infer<typeof addHubAdminBody>;\nexport type AddHubIdentityAuthorizationInput = z.infer<typeof addHubIdentityAuthorizationBody>;\nexport type ContactDecisionInput = z.infer<typeof contactDecisionBody>;\nexport type ApproveContactInput = z.infer<typeof approveContactBody>;\nexport type ListContactAccessQuery = z.infer<typeof listContactAccessQuery>;\nexport type CreateHubTeamInput = z.infer<typeof createHubTeamBody>;\nexport type UpdateHubTeamInput = z.infer<typeof updateHubTeamBody>;\nexport type AddHubTeamUserInput = z.infer<typeof addHubTeamUserBody>;\nexport type ReplicatePreviewInput = z.infer<typeof replicatePreviewBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n// --- Hub entity responses ---\n\n/** Resolves a hub_id to its owning organization (used by direct-link redirect). */\nexport interface GetHubOrganizationResponse {\n data: {\n hub_id: string;\n organization_id: string;\n };\n}\n\n/** Organization nested inside a hub join. */\nexport interface HubListOrganizationResponse {\n organization_id: string;\n name: string;\n}\n\n// --- Channel contact access control responses ---\n\n/** approve / block / unblock result (HubDO ContactTransitionResult, success branch). */\nexport interface ContactTransitionResult {\n ok: true;\n user_id: string | null;\n conversation_ids: string[];\n next_access_status: 'approved' | 'pending' | 'blocked';\n hub_user_id?: string;\n identity_type?: string;\n identity_value?: string;\n channel_type?: string;\n}\n\nexport interface ContactDecisionResponse {\n data: ContactTransitionResult;\n}\n\n/** A contact_access row (pending / blocked) for the admin review surface. */\nexport interface ContactAccessRowResponse {\n contact_access_id: string;\n channel_id: string | null;\n connection_id: string | null;\n identity_type: string;\n identity_value: string;\n channel_type: string;\n user_id: string | null;\n status: 'pending' | 'blocked';\n sender_display_name: string | null;\n last_message_preview: string | null;\n notified_at: string | null;\n requested_at: string;\n last_seen_at: string;\n decided_at: string | null;\n decided_by_user_id: string | null;\n}\n\nexport interface ListContactAccessResponse {\n data: { contacts: ContactAccessRowResponse[] };\n}\n\n/** Hub row as returned by list hubs (subset with joined organization). */\nexport interface HubListItemResponse {\n hub_id: string;\n name: string;\n description: string | null;\n created_at: string;\n organization: HubListOrganizationResponse | HubListOrganizationResponse[] | null;\n}\n\n/** Full hub row as returned by get hub by ID. */\nexport interface HubResponse {\n hub_id: string;\n created_at: string;\n updated_at: string;\n hub_name: string;\n hub_type: string;\n hub_description: string | null;\n ai_mode: AiMode;\n non_app_permission: string;\n created_by: string;\n hub_contexts: string[] | null;\n hub_course_name: string | null;\n is_platform_hub: boolean;\n template_id: string;\n kanban_statuses: Record<string, unknown>[] | null;\n timezone: string | null;\n mcp_access: string;\n hub_environment: string;\n production_hub_id: string | null;\n branch_name: string | null;\n last_ci_activity_at: string | null;\n ci_commit_sha: string | null;\n preview_label: string | null;\n is_support_hub: boolean;\n support_model: 'conversation' | 'account';\n unassigned_policy: 'default_team' | 'auto_assign_random' | 'auto_assign_round_robin' | 'pull_queue';\n default_hub_team_id: string | null;\n welcome_message: string | null;\n storage_retention_months: number | null;\n // flag_conditions relocated to the conversation_evaluator AGENT (AgentResponse.flag_conditions).\n // summarization_threshold_tokens relocated to the summarizer AGENT (AgentResponse.summarization_threshold_tokens).\n // monitor_config relocated to the monitor AGENT (AgentResponse.monitor_config).\n auto_close_inactive_days: number;\n tags: string[];\n holidays: string[] | null;\n org_id: string;\n primary_region: PrimaryRegion | null;\n placement_region: PrimaryRegion | null;\n placement_source: PlacementSource | null;\n}\n\n// --- Hub admin user ---\n\nexport interface HubAdminUserResponse {\n hub_admin_user_id: string;\n hub_id: string;\n created_at: string;\n user_id: string | null;\n enabled: boolean;\n user_email: string;\n}\n\n// --- Hub user ---\n\nexport interface HubUserResponse {\n hub_user_id: string;\n hub_id: string;\n created_at: string;\n updated_at: string;\n user_id: string;\n user_name: string | null;\n user_email: string | null;\n enabled: boolean;\n /** Account-mode: the team that owns this end user (\"the account\"). */\n hub_team_id: string | null;\n /** 'grant' = pre-authorized access row. 'auto' = created on inbound in account-mode hubs (no platform access). */\n source: 'grant' | 'auto';\n}\n\n/** Hub user with linked identities (as returned by fetchHubById). */\nexport interface HubUserWithIdentitiesResponse extends HubUserResponse {\n identities: HubUserLinkedIdentityResponse[];\n}\n\nexport interface HubUserLinkedIdentityResponse {\n hub_user_identity_id: string;\n identity_value: string;\n identity_type: string;\n channel_type: string;\n user_identity_id: string | null;\n}\n\n// --- Hub user identity (pre-authorized) ---\n\nexport interface HubUserIdentityResponse {\n hub_user_identity_id: string;\n hub_user_id: string | null;\n user_identity_id: string | null;\n identity_value: string;\n identity_type: string;\n channel_type: string;\n created_at: string;\n updated_at: string;\n hub_id: string;\n}\n\n// --- Hub team ---\n\nexport interface HubTeamResponse {\n hub_team_id: string;\n created_at: string;\n team_name: string;\n hub_id: string;\n conversation_display_only_if_claimed: boolean;\n team_access_rule: string;\n initial_team: boolean | null;\n}\n\n/** Team with nested team users (as returned by fetchHubById). */\nexport interface HubTeamWithUsersResponse extends HubTeamResponse {\n team_users: HubTeamUserResponse[];\n}\n\n// --- Hub team user ---\n\nexport interface HubTeamUserResponse {\n hub_team_user_id: string;\n hub_team_id: string;\n created_at: string;\n user_id: string | null;\n enabled: boolean;\n user_email: string;\n}\n\n// --- Composite hub responses ---\n\n/** GET /:id — hub with agents, connections, tools. */\nexport interface GetHubResponse {\n data: HubResponse & {\n agents: Record<string, unknown>[];\n connections: Record<string, unknown>[];\n tools: Record<string, unknown>[];\n };\n}\n\n/** GET /:id/users — hub with admin users, hub users, teams, pre-authorized identities. */\nexport interface GetHubUsersResponse {\n data: {\n hub: HubResponse;\n admin_users: HubAdminUserResponse[];\n users: HubUserWithIdentitiesResponse[];\n pre_authorized_identities: HubUserIdentityResponse[];\n teams: HubTeamWithUsersResponse[];\n };\n}\n\n/** GET / — list of hubs. */\nexport interface ListHubsResponse {\n data: HubListItemResponse[];\n}\n\n/** POST / — create hub returns array with single hub plus optional kanban warnings. */\nexport interface CreateHubResponse {\n data: HubResponse[];\n /** Non-blocking lint warnings (e.g. unreachable kanban statuses). Empty when no warnings apply. */\n warnings?: KanbanLintWarning[];\n}\n\n/** PATCH /:id — update hub returns array with single hub plus optional kanban warnings. */\nexport interface UpdateHubResponse {\n data: HubResponse[];\n warnings?: KanbanLintWarning[];\n}\n\n// --- Hub admin user operations ---\n\nexport interface AddHubAdminResponse {\n data: HubAdminUserResponse[];\n}\n\n// --- Hub user identity operations ---\n\nexport interface AddHubIdentityAuthorizationResponse {\n data: HubUserIdentityResponse[];\n}\n\n// --- Hub team operations ---\n\nexport interface CreateHubTeamResponse {\n data: HubTeamResponse[];\n}\n\nexport interface UpdateHubTeamResponse {\n data: HubTeamResponse[];\n}\n\n// --- Hub team user operations ---\n\nexport interface AddHubTeamUserResponse {\n data: HubTeamUserResponse[];\n}\n\n// --- Hub branching responses ---\n\n/** GET /:id/diff */\nexport interface DiffEntry {\n name: string;\n type?: string;\n status: 'added' | 'removed' | 'updated';\n}\n\nexport interface HubDiffResult {\n has_changes: boolean;\n is_first_publish: boolean;\n hub_changed: boolean;\n agents: DiffEntry[];\n connections: DiffEntry[];\n tools: DiffEntry[];\n channels: DiffEntry[];\n states: DiffEntry[];\n resources: DiffEntry[];\n}\n\nexport interface GetHubDiffResponse {\n data: HubDiffResult;\n}\n\n/** POST /:id/publish */\nexport interface PublishHubResponse {\n data: {\n production_hub_id: string;\n };\n}\n\n/** POST /:id/sync */\nexport interface SyncHubResponse {\n data: {\n synced: boolean;\n };\n}\n\n/** POST /:id/replicate-preview */\nexport interface ReplicatePreviewHubResponse {\n data: {\n preview_hub_id: string;\n };\n}\n\n// --- Hub schema response ---\n\nexport interface HubSchemaAgentToolResponse {\n tool_id: string;\n tool_name: string;\n tool_description: string | null;\n is_native: boolean;\n enabled: boolean;\n tool_group: string | null;\n tool_native_id: string | null;\n connector_id: string | null;\n connector_name: string | null;\n}\n\nexport interface HubSchemaAgentResponse {\n agent_id: string;\n agent_name: string;\n agent_role: string | null;\n agent_settings: unknown;\n instructions: string | null;\n tools: HubSchemaAgentToolResponse[];\n}\n\nexport interface HubSchemaConnectionResponse {\n connection_id: string;\n connection_display_name: string;\n connector_id: string | null;\n connector_name: string | null;\n connector_type: string;\n connector_description: string | null;\n enabled: boolean;\n}\n\nexport interface HubSchemaNativeToolInstallationResponse {\n agent_id: string;\n tool_id: string;\n enabled: boolean;\n}\n\nexport interface HubSchemaNativeToolResponse {\n tool_native_id: string;\n tool_name: string;\n tool_description: string | null;\n is_delegation: boolean;\n installations: HubSchemaNativeToolInstallationResponse[];\n}\n\nexport interface HubSchemaTeamResponse {\n hub_team_id: string;\n team_name: string;\n team_access_rule: string;\n initial_team: boolean;\n conversation_display_only_if_claimed: boolean;\n}\n\nexport interface HubSchemaHubResponse {\n hub_id: string;\n hub_name: string;\n hub_description: string | null;\n ai_mode: AiMode | null;\n created_at: string;\n}\n\nexport interface GetHubSchemaResponse {\n data: {\n hub: HubSchemaHubResponse;\n agents: HubSchemaAgentResponse[];\n connections: HubSchemaConnectionResponse[];\n teams: HubSchemaTeamResponse[];\n native_tools: HubSchemaNativeToolResponse[];\n };\n}\n\n// --- Claim codes (preview hub tester registration) ---\n\nexport const claimCodeChannelParam = z.object({\n id: uuidSchema,\n channelId: uuidSchema,\n});\nexport type ClaimCodeChannelParam = z.infer<typeof claimCodeChannelParam>;\n\nexport const claimCodeDeleteParam = z.object({\n id: uuidSchema,\n channelId: uuidSchema,\n code: z.string().regex(/^[A-Za-z0-9]{6}$/, 'Invalid claim code format').transform((s) => s.toUpperCase()),\n});\nexport type ClaimCodeDeleteParam = z.infer<typeof claimCodeDeleteParam>;\n\nexport interface ClaimCodeSummaryResponse {\n code: string;\n created_at: string;\n created_by: string;\n}\n\nexport interface GenerateClaimCodeResponse {\n data: {\n code: string;\n expires_at: string;\n channel_type: string;\n };\n}\n\nexport interface ListClaimCodesResponse {\n data: {\n codes: ClaimCodeSummaryResponse[];\n };\n}\n\n// --- User + Hub schema responses (scoped fetches for Settings) ---\n\ninterface SchemaEntityItem {\n id: string;\n name: string;\n [key: string]: unknown;\n}\n\n/** GET /api/setup/user-schema — orgs + hubs hierarchy, no agents/tools. */\nexport interface GetUserSchemaResponse {\n data: {\n connectors: unknown[];\n native_tools: unknown[];\n flat: {\n organizations: SchemaEntityItem[];\n hubsByOrg: Record<string, SchemaEntityItem[]>;\n };\n lastUpdated: string;\n };\n}\n\n/** GET /api/setup/hub-schema/:hubId — agents + tools + states for a single hub. */\nexport interface GetHubDetailSchemaResponse {\n data: {\n hub_id: string;\n agents: SchemaEntityItem[];\n toolsByAgent: Record<string, SchemaEntityItem[]>;\n states: SchemaEntityItem[];\n };\n}\n","import { z } from 'zod';\nimport { uuidSchema } from '../common';\nimport type { Connector } from '../../catalog/types';\n\nexport const connectionIdParam = z.object({ id: uuidSchema });\nexport const connectorIdParam = z.object({ id: uuidSchema });\n\nexport const listConnectionsQuery = z.object({ hub_id: uuidSchema });\n\nexport const deleteConnectionQuery = z.object({ hub_id: uuidSchema });\n\nexport const addConnectionBody = z.object({\n hub_id: uuidSchema,\n connector_id: uuidSchema,\n authentication_type: z.string().optional(),\n inbound_mode: z.enum(['wayai', 'resend']).optional(),\n inbound_address: z.string().email().optional(),\n}).passthrough().superRefine((data, ctx) => {\n if (data.inbound_mode === 'resend' && !data.inbound_address) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Receiving email address is required when using Resend inbound mode',\n path: ['inbound_address'],\n });\n }\n});\n\nexport const editConnectionBody = z.object({\n hub_id: uuidSchema,\n}).passthrough();\n\nexport const registerWhatsappQuery = z.object({ hub_id: uuidSchema });\n\nexport const registerWhatsappBody = z.object({\n pin: z.string().optional(),\n});\n\nexport type AddConnectionInput = z.infer<typeof addConnectionBody>;\nexport type EditConnectionInput = z.infer<typeof editConnectionBody>;\nexport type RegisterWhatsappInput = z.infer<typeof registerWhatsappBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n/** Single connection item as returned by the `get_connections` RPC. */\nexport interface ConnectionItemResponse {\n connection_id: string | null;\n hub_id: string;\n account_sid: string | null;\n connection_display_name: string | null;\n username: string | null;\n state: Record<string, unknown> | null;\n settings: Record<string, unknown> | null;\n organization_credential_id: string | null;\n organization_credential_token_id: string | null;\n connector_id: string;\n connector_name: string;\n connector_type: string;\n service_name: string;\n authentication_type: string;\n authentication_types: string[];\n unique_per_hub: boolean;\n account_sid_placeholder: string | null;\n init_endpoint: string | null;\n connector_credential_schema: Record<string, unknown> | null;\n connector_settings_schema: Record<string, unknown> | null;\n agent_settings_schema: Record<string, unknown> | null;\n available_action: 'Add' | 'Edit' | 'Remove' | 'Enable' | 'Disable';\n enabled: boolean;\n base_url: string | null;\n connection_headers: Record<string, unknown> | null;\n}\n\n/** Full connection row with nested connector, returned by GET /connections/:id. */\nexport interface ConnectionWithConnectorResponse {\n connection_id: string;\n created_at: string;\n service_name: string | null;\n api_key: string | null;\n updated_at: string | null;\n hub_id: string;\n access_token: string | null;\n access_token_expires_at: string | null;\n access_token_secret_id: string | null;\n account_sid: string | null;\n api_key_secret_id: string | null;\n authentication_type: string;\n enabled: boolean;\n connector_id: string;\n connector_name: string;\n password: string | null;\n password_secret_id: string | null;\n connection_display_name: string | null;\n connector_type: string;\n refresh_token: string | null;\n refresh_token_expires_at: string | null;\n refresh_token_secret_id: string | null;\n state: Record<string, unknown> | null;\n username: string | null;\n base_url: string | null;\n connection_headers: Record<string, unknown> | null;\n settings: Record<string, unknown> | null;\n token_refresh_config: Record<string, unknown> | null;\n next_access_token_refresh_at: string | null;\n next_refresh_token_renewal_at: string | null;\n last_token_refresh_at: string | null;\n last_token_refresh_error: string | null;\n organization_credential_id: string | null;\n organization_credential_token_id: string | null;\n available_action: 'Add' | 'Edit' | 'Remove' | 'Enable' | 'Disable';\n connector_credential_schema: Record<string, unknown> | null;\n connector_settings_schema: Record<string, unknown> | null;\n agent_settings_schema: Record<string, unknown> | null;\n connector: ConnectorResponse;\n}\n\n/** Connector row returned by GET /connectors/:id and as nested data. */\nexport type ConnectorResponse = Connector;\n\n/** GET /connections?hub_id=... */\nexport interface ListConnectionsResponse {\n connections: ConnectionItemResponse[];\n}\n\n/** GET /connections/:id */\nexport interface GetConnectionResponse {\n data: ConnectionWithConnectorResponse;\n}\n\n/** POST /connections (add connection — may return OAuth redirect) */\nexport interface AddConnectionResponse {\n connections: ConnectionItemResponse[];\n warnings?: string[];\n oauth_url?: string;\n state?: string;\n}\n\n/** PATCH /connections/:id (edit connection) */\nexport interface EditConnectionResponse {\n connections: ConnectionItemResponse[];\n warnings?: string[];\n}\n\n/** POST /connections/:id/enable */\nexport interface EnableConnectionResponse {\n connections: ConnectionItemResponse[];\n warnings?: string[];\n}\n\n/** POST /connections/:id/disable */\nexport interface DisableConnectionResponse {\n connections: ConnectionItemResponse[];\n}\n\n/** DELETE /connections/:id */\nexport interface DeleteConnectionResponse {\n connections: ConnectionItemResponse[];\n}\n\n/** GET /connections/:id/channel-info */\nexport interface ChannelInfoResponse {\n channel: Record<string, unknown> | null;\n connection: Record<string, unknown>;\n}\n\n/** POST /connections/:id/sync-mcp */\nexport interface SyncMcpConnectionResponse {\n success: boolean;\n tools_count?: number;\n resources_count?: number;\n message?: string;\n warnings?: string[];\n}\n\n/** POST /connections/:id/register-whatsapp */\nexport interface RegisterWhatsappResponse {\n success: boolean;\n message?: string;\n error?: string;\n}\n\n/** GET /connectors/:id */\nexport interface GetConnectorResponse {\n data: ConnectorResponse;\n}\n\n// =============================================================================\n// ASYNC PROVISIONING RETRY\n// =============================================================================\n\n/** POST /connections/:id/retry-provisioning — query */\nexport const retryProvisioningQuery = z.object({ hub_id: uuidSchema });\n\n/** POST /connections/:id/retry-provisioning — response */\nexport interface RetryProvisioningResponse {\n success: true;\n connection_id: string;\n}\n\n// =============================================================================\n// RESEND DOMAIN VERIFICATION\n// =============================================================================\n\nexport const resendDomainStatusQuery = z.object({ hub_id: uuidSchema });\n\nexport interface ResendDnsRecord {\n record: string;\n name: string;\n type: string;\n ttl: string;\n status: string;\n value: string;\n priority?: number;\n}\n\n/** GET /connections/:id/domain-status */\nexport interface ResendDomainStatusResponse {\n verified: boolean;\n domain_id: string | null;\n domain_name: string | null;\n status: string;\n records: ResendDnsRecord[];\n inbound_address: string | null;\n inbound_mode: 'wayai' | 'resend' | null;\n}\n\n/** POST /connections/:id/verify-domain */\nexport interface ResendVerifyDomainResponse {\n domain_id: string;\n status: string;\n}\n","import { z } from 'zod';\nimport { uuidSchema } from '../common';\nimport {\n validateToolInputSchema,\n containsKanbanPlaceholders,\n extractToolParameters,\n} from '../../tool-schema-validator';\n\n/**\n * Configure-time guard for `tool_config.parameters` on REST custom-tool\n * routes (gh #1542). Adds draft-2020-12 violations to the Zod context so the\n * Hono handler emits a 400 with structured messages before we cross the\n * HubDO boundary. The HubDO chokepoint re-validates as defense in depth.\n *\n * IMPORTANT: unresolved `[KANBAN_STATUS_*]` placeholder tokens are SKIPPED\n * here. They would otherwise block legitimate template pushes — the chokepoint\n * renders them first, then validates.\n */\nfunction refineToolConfig(value: Record<string, unknown>, ctx: z.RefinementCtx): void {\n const raw = value.tool_config;\n if (raw == null) return;\n\n const params = extractToolParameters(raw);\n if (params === undefined) {\n // Either tool_config is not an object shape, or there's no `parameters`\n // field to validate. Only the former is an error.\n const looksLikeObject = raw !== null\n && typeof raw === 'object'\n && !Array.isArray(raw)\n || (typeof raw === 'string' && (() => {\n try { const parsed = JSON.parse(raw); return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed); }\n catch { return false; }\n })());\n if (!looksLikeObject) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['tool_config'],\n message: 'tool_config must be an object',\n });\n }\n return;\n }\n\n if (containsKanbanPlaceholders(params)) return;\n\n const result = validateToolInputSchema(params);\n if (!result.ok) {\n for (const err of result.errors) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['tool_config', 'parameters', ...err.path.split('.').filter(Boolean)],\n message: err.suggestion ? `${err.message} — ${err.suggestion}` : err.message,\n });\n }\n }\n}\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\nexport const toolIdParam = z.object({ id: uuidSchema });\n\nexport const listToolsQuery = z.object({ agent_id: uuidSchema, hub_id: uuidSchema });\n\nexport const toolAgentQuery = z.object({ agent_id: uuidSchema, hub_id: uuidSchema });\n\nexport const deleteToolQuery = z.object({ agent_id: uuidSchema.optional(), hub_id: uuidSchema });\n\nexport const toolConnectionsQuery = z.object({ hub_id: uuidSchema });\n\nexport const nativeToolIdSchema = z.string().regex(/^nt-\\d{3,}$/, 'Invalid native tool id');\n\nexport const addNativeToolBody = z.object({\n agent_id: uuidSchema,\n hub_id: uuidSchema,\n tool_native_id: nativeToolIdSchema,\n delegation_type: z.enum(['team', 'agent']).optional(),\n delegation_id: z.string().optional(),\n delegation_name: z.string().optional(),\n resource_config: z.object({\n access_mode: z.enum(['all', 'selected', 'none']),\n enabled_resources: z.array(z.string()).optional(),\n }).optional(),\n});\n\nexport const addMcpToolBody = z.object({\n agent_id: uuidSchema,\n hub_id: uuidSchema,\n mcp_tool_id: uuidSchema,\n});\n\nexport const createCustomToolBody = z.object({\n agent_id: uuidSchema,\n hub_id: uuidSchema,\n}).passthrough().superRefine(refineToolConfig);\n\nexport const updateCustomToolBody = z.object({\n hub_id: uuidSchema.optional(),\n}).passthrough().superRefine(refineToolConfig);\n\nexport const updateToolExecutionConfigBody = z.object({\n agent_id: uuidSchema,\n hub_id: uuidSchema,\n execution_config: z.object({\n keep_in_history: z.boolean().optional(),\n }).nullable(),\n});\n\nexport function resolveKeepInHistory(\n ec: { keep_in_history?: boolean } | null | undefined,\n): boolean {\n return ec?.keep_in_history === true;\n}\n\n/** Coerce a SQL `keep_in_history` value (0|1|null|boolean) to the \"kept\" boolean. */\nexport function isMessageKept(v: number | boolean | null | undefined): boolean {\n return v !== 0 && v !== false;\n}\n\n/** Coerce an optional boolean `keep_in_history` to the SQL integer value (default = kept). */\nexport function keepInHistoryToInt(v: boolean | undefined | null): 0 | 1 {\n return v === false ? 0 : 1;\n}\n\n// =============================================================================\n// INFERRED TYPES\n// =============================================================================\n\nexport type AddNativeToolInput = z.infer<typeof addNativeToolBody>;\nexport type AddMcpToolInput = z.infer<typeof addMcpToolBody>;\nexport type CreateCustomToolInput = z.infer<typeof createCustomToolBody>;\nexport type UpdateToolExecutionConfigInput = z.infer<typeof updateToolExecutionConfigBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n/** A native tool item as returned by the get_native_tools RPC */\nexport interface NativeToolResponse {\n tool_id: string | null;\n tool_display_name: string;\n tool_name: string;\n tool_description: string | null;\n tool_config: Record<string, unknown> | null;\n enabled: boolean | null;\n is_native: boolean;\n operation: string | null;\n created_at: string;\n available_action: 'Add' | 'Enable' | 'Disable';\n tool_native_id: string | null;\n connection_display_name: string;\n connector_name: string;\n is_delegation: boolean;\n tool_group: string;\n keep_in_history: boolean;\n}\n\n/** An MCP external tool item as returned by the get_native_tools RPC */\nexport interface McpToolResponse {\n // Installed-only fields (the \"Add\" catalog branch of getNativeTools omits\n // them); mirrors the optionality of the frontend MCPTool type.\n tool_id?: string | null;\n mcp_tool_id: string;\n tool_display_name: string;\n tool_name: string;\n tool_description: string | null;\n // The LLM function-spec rendered LIVE from the `mcp_tool` catalog (source of\n // truth), not the frozen assignment snapshot — what the agent actually\n // receives (report 1876b8be).\n tool_config?: Record<string, unknown> | null;\n /** When the catalog row was last refreshed by `sync-mcp` (`mcp_tool.updated_at`),\n * surfaced as a \"last synced\" indicator. */\n synced_at?: string | null;\n enabled?: boolean | null;\n created_at?: string;\n available_action: 'Add' | 'Enable' | 'Disable';\n connection_display_name: string;\n connection_id: string;\n keep_in_history?: boolean;\n}\n\n/** A delegation entity (team or agent) */\nexport interface DelegationEntityResponse {\n id: string;\n name: string;\n type: string;\n}\n\n/** A resource available for tool configuration */\nexport interface ToolResourceResponse {\n resource_id: string;\n resource_name: string;\n resource_description: string | null;\n hub_id: string;\n}\n\n/** Full response from the get_native_tools RPC (list tools endpoint) */\nexport interface ListToolsResponse {\n tools: NativeToolResponse[];\n mcp_tools: McpToolResponse[];\n available_delegation_teams: DelegationEntityResponse[];\n available_delegation_agents: DelegationEntityResponse[];\n available_consultant_agents: DelegationEntityResponse[];\n available_resources: ToolResourceResponse[];\n}\n\n/** Tool row as stored in the database */\nexport interface ToolRowResponse {\n tool_id: string;\n created_at: string;\n tool_method: string | null;\n connection_id: string;\n tool_display_name: string;\n hub_id: string;\n agent_id: string;\n delegated_agent_id: string | null;\n delegated_hub_team_id: string | null;\n enabled: boolean;\n tool_description: string | null;\n tool_group: string;\n tool_headers: Record<string, unknown> | null;\n tool_name: string | null;\n tool_native_id: string | null;\n tool_path: string | null;\n is_native: boolean;\n operation: string | null;\n is_delegation: boolean;\n updated_at: string | null;\n tool_config: Record<string, unknown>;\n tool_instructions: string | null;\n resource_config: Record<string, unknown> | null;\n additional_body_params: Record<string, unknown> | null;\n tool_query_params: Record<string, unknown> | null;\n mcp_tool_id: string | null;\n composed_tools: Array<{\n tool_name: string;\n mappings: Record<string, string | { source: string; type?: string; description?: string }>;\n appended_description?: string;\n success_path?: string;\n }> | null;\n execution_config: Record<string, unknown> | null;\n tool_body_format: string;\n expose_schema_to_llm: boolean;\n}\n\n/** Agent row shape used in tool get-by-id join */\nexport interface ToolAgentResponse {\n agent_id: string;\n agent_name: string;\n created_at: string;\n agent_sid: string | null;\n instructions: string;\n response_format: string;\n updated_at: string | null;\n hub_id: string;\n connection_id: string;\n agent_role: string;\n schema_json: Record<string, unknown> | null;\n schema_name: string | null;\n agent_settings: Record<string, unknown> | null;\n instructions_file_id: string | null;\n enabled: boolean;\n include_message_timestamps: boolean;\n}\n\n/** Native tool row shape used in tool get-by-id join */\nexport interface ToolNativeResponse {\n tool_native_id: string;\n created_at: string;\n tool_display_name: string;\n operation: string;\n tool_method: string;\n tool_description: string;\n tool_name: string;\n connector_id: string;\n tool_group: string;\n is_delegation: boolean;\n is_auto_set: boolean;\n tool_config: Record<string, unknown> | null;\n tool_instructions: string | null;\n execution_config: Record<string, unknown> | null;\n}\n\n/** Connection row shape used in tool get-by-id join */\nexport interface ToolConnectionResponse {\n connection_id: string;\n created_at: string;\n service_name: string | null;\n api_key: string | null;\n updated_at: string | null;\n hub_id: string;\n access_token: string | null;\n access_token_expires_at: string | null;\n access_token_secret_id: string | null;\n account_sid: string | null;\n api_key_secret_id: string | null;\n authentication_type: string;\n enabled: boolean;\n connector_id: string;\n connector_name: string;\n password: string | null;\n password_secret_id: string | null;\n connection_display_name: string | null;\n connector_type: string;\n refresh_token: string | null;\n refresh_token_expires_at: string | null;\n refresh_token_secret_id: string | null;\n state: Record<string, unknown> | null;\n username: string | null;\n base_url: string | null;\n connection_headers: Record<string, unknown> | null;\n settings: Record<string, unknown> | null;\n token_refresh_config: Record<string, unknown> | null;\n next_access_token_refresh_at: string | null;\n next_refresh_token_renewal_at: string | null;\n last_token_refresh_at: string | null;\n last_token_refresh_error: string | null;\n organization_credential_id: string | null;\n}\n\n/** Response for GET /tools/:id */\nexport interface GetToolResponse {\n data: {\n tool: ToolRowResponse & {\n agent: ToolAgentResponse;\n native_tool: ToolNativeResponse | null;\n connection: ToolConnectionResponse;\n };\n };\n}\n\n/** Connector subset in tool connections response */\nexport interface ToolConnectionConnectorResponse {\n connector_type: string;\n connector_name: string;\n}\n\n/** Connection item in the tool connections list */\nexport interface ToolConnectionItemResponse {\n connection_id: string;\n connector_name: string;\n connection_display_name: string | null;\n enabled: boolean;\n connector: ToolConnectionConnectorResponse;\n}\n\n/** Response for GET /tools/connections */\nexport interface ListToolConnectionsResponse {\n data: ToolConnectionItemResponse[];\n}\n\n/** Response for POST /tools/native (add native tool) */\nexport interface AddNativeToolResponse {\n data: Record<string, unknown>;\n}\n\n/** Response for POST /tools/mcp (add MCP tool) */\nexport interface AddMcpToolResponse {\n data: Record<string, unknown>;\n}\n\n/** Response for POST /tools/custom (create custom tool) */\nexport interface CreateCustomToolResponse {\n data: ToolRowResponse[];\n}\n\n/** Response for PATCH /tools/:id (update custom tool) */\nexport interface UpdateCustomToolResponse {\n data: ToolRowResponse[];\n}\n\n/** Response for DELETE /tools/:id without agent_id */\nexport interface DeleteToolResponse {\n ok: true;\n}\n","/**\n * Minimal JSON Schema draft 2020-12 linter for LLM tool `input_schema`.\n *\n * Targets the failure modes we've seen Anthropic reject in practice, not\n * full spec conformance. A permissive `ajv` build ships ~40KB gzipped and\n * fights Workers' eval restrictions; a hand-rolled linter tailored to the\n * ~8 observed violations gives better error messages at ~3KB with no deps.\n *\n * Used by:\n * - Zod `superRefine` on tool CRUD contracts (configure-time gate)\n * - HubDO `createTool`/`updateTool` (defense-in-depth at the write boundary)\n * - `buildAgentSettings.buildAgentToolsForLLM` (runtime drop — logs error,\n * does not throw)\n *\n * Pure — no side effects.\n */\n\nexport const PLACEHOLDER_TOKENS = [\n '[KANBAN_STATUS_VALUES]',\n '[KANBAN_STATUS_NAMES]',\n '[SCHEDULING_STATUS_NAMES]',\n '[STATE_SLUG_VALUES]',\n] as const;\n\n/**\n * True if `value` serializes to a JSON blob containing any kanban placeholder\n * token. Callers use this to skip strict JSON Schema validation on template\n * configs that the HubDO chokepoint will render before validating.\n */\nexport function containsKanbanPlaceholders(value: unknown): boolean {\n if (value == null) return false;\n const serialized = typeof value === 'string' ? value : JSON.stringify(value);\n for (const token of PLACEHOLDER_TOKENS) {\n if (serialized.includes(token)) return true;\n }\n return false;\n}\n\n/**\n * Parse a `tool_config` (object or JSON string) and return its `parameters`\n * field, or `undefined` if the config isn't a non-array object or doesn't\n * carry one. Shared by the HubDO chokepoint and both zod `superRefine`s so\n * they all agree on what \"has a schema to validate\" means.\n */\nexport function extractToolParameters(toolConfig: unknown): unknown {\n let cfg: unknown = toolConfig;\n if (typeof cfg === 'string') {\n try { cfg = JSON.parse(cfg); } catch { return undefined; }\n }\n if (!cfg || typeof cfg !== 'object' || Array.isArray(cfg)) return undefined;\n return (cfg as Record<string, unknown>).parameters;\n}\n\nconst ALLOWED_PRIMITIVE_TYPES = new Set(['string', 'number', 'integer', 'boolean', 'null']);\nconst ALLOWED_TYPES = new Set(['string', 'number', 'integer', 'boolean', 'object', 'array', 'null']);\n\n// Keyword positions whose value is itself a subschema (or a boolean schema in\n// draft 2020-12). The validator MUST descend these — a structurally-invalid\n// subschema buried in a composition/`$defs`/conditional keyword would otherwise\n// reach the LLM provider and 400 the whole agent turn. `properties` and `items`\n// have dedicated blocks below (richer error messages / type-guarded), so they\n// are intentionally absent here.\nconst SUBSCHEMA_OBJECT_KEYWORDS = [\n 'additionalProperties', 'unevaluatedProperties', 'additionalItems', 'unevaluatedItems',\n 'contains', 'propertyNames', 'not', 'if', 'then', 'else',\n] as const;\nconst SUBSCHEMA_LIST_KEYWORDS = ['allOf', 'anyOf', 'oneOf', 'prefixItems'] as const;\nconst SUBSCHEMA_MAP_KEYWORDS = ['$defs', 'definitions', 'patternProperties', 'dependentSchemas'] as const;\n\nexport interface SchemaViolation {\n path: string;\n message: string;\n suggestion?: string;\n}\n\nexport type ValidationResult =\n | { ok: true }\n | { ok: false; errors: SchemaViolation[] };\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nfunction isPrimitive(v: unknown): boolean {\n return v === null || ['string', 'number', 'boolean'].includes(typeof v);\n}\n\nfunction typeMatches(typeField: unknown, allowed: Set<string>): boolean {\n if (typeof typeField === 'string') return allowed.has(typeField);\n if (Array.isArray(typeField)) return typeField.every(t => typeof t === 'string' && allowed.has(t));\n return false;\n}\n\n/** Max recursion depth. Anthropic's own validator caps nesting well below\n * this; we add our own floor to keep a pathological user-supplied schema\n * from exhausting the Worker call stack. */\nexport const MAX_SCHEMA_DEPTH = 20;\n\nfunction validateSchema(\n schema: unknown,\n path: string,\n errors: SchemaViolation[],\n opts: { isRoot?: boolean; depth?: number } = {},\n): void {\n // A boolean is a valid subschema in draft 2020-12 (`true` = match-anything,\n // `false` = match-nothing) — legal in any nested position (`anyOf` element,\n // tuple `items` element, `$defs`/`additionalProperties` value, …). The\n // truncation sanitizer preserves these booleans verbatim, so rejecting them\n // here would silently drop an otherwise-valid tool (the sanitizer-preserves /\n // validator-rejects class this validator was hardened against). A boolean is a\n // leaf — no children, so depth is irrelevant. The object-only root constraint\n // is still enforced upstream in `validateToolInputSchema`.\n if (typeof schema === 'boolean') return;\n\n const depth = opts.depth ?? 0;\n if (depth > MAX_SCHEMA_DEPTH) {\n errors.push({\n path: path || '<root>',\n message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH} levels`,\n suggestion: 'Flatten the schema; LLM providers reject deeply nested tool input_schemas.',\n });\n return;\n }\n\n if (!isRecord(schema)) {\n errors.push({\n path,\n message: `expected object, got ${schema === null ? 'null' : typeof schema}`,\n });\n return;\n }\n\n // Root schemas must be objects specifically (not just any allowed type).\n // This check replaces the earlier duplicate root-type check in\n // `validateToolInputSchema` — keeping both produced two errors per bad root.\n if (opts.isRoot) {\n if ('type' in schema && schema.type !== 'object') {\n errors.push({\n path: path ? `${path}.type` : 'type',\n message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,\n suggestion: \"Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`.\",\n });\n }\n } else if ('type' in schema && !typeMatches(schema.type, ALLOWED_TYPES)) {\n errors.push({\n path: `${path}.type`,\n message: `type must be one of ${[...ALLOWED_TYPES].join('/')} or an array of those, got ${JSON.stringify(schema.type)}`,\n });\n }\n\n if ('enum' in schema) {\n const e = schema.enum;\n if (typeof e === 'string') {\n const isPlaceholder = PLACEHOLDER_TOKENS.includes(e as (typeof PLACEHOLDER_TOKENS)[number]);\n errors.push({\n path: `${path}.enum`,\n message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,\n suggestion: isPlaceholder\n ? \"Set `operation: 'update_kanban_status'` on the tool and ensure at least one hub.kanban_status has `allowsAgentUpdate: true` so the platform can render the placeholder into a valid array.\"\n : 'Wrap the value in an array: `enum: [\"value\"]`.',\n });\n } else if (!Array.isArray(e)) {\n errors.push({\n path: `${path}.enum`,\n message: `enum must be a non-empty array of primitives, got ${typeof e}`,\n });\n } else if (e.length === 0) {\n errors.push({\n path: `${path}.enum`,\n message: 'enum must not be empty',\n });\n } else {\n for (let i = 0; i < e.length; i++) {\n if (!isPrimitive(e[i])) {\n errors.push({\n path: `${path}.enum[${i}]`,\n message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`,\n });\n }\n }\n }\n }\n\n for (const key of ['exclusiveMinimum', 'exclusiveMaximum'] as const) {\n if (key in schema && typeof schema[key] === 'boolean') {\n errors.push({\n path: `${path}.${key}`,\n message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,\n suggestion: `Replace with the numeric bound, e.g. \\`${key}: 0\\`.`,\n });\n }\n }\n\n if ('properties' in schema) {\n if (!isRecord(schema.properties)) {\n errors.push({\n path: `${path}.properties`,\n message: `properties must be an object, got ${Array.isArray(schema.properties) ? 'array' : typeof schema.properties}`,\n });\n } else {\n for (const [propName, propSchema] of Object.entries(schema.properties)) {\n validateSchema(propSchema, `${path}.properties.${propName}`, errors, { depth: depth + 1 });\n }\n }\n }\n\n if (schemaTypeIncludes(schema, 'array') && 'items' in schema) {\n // `items` straddles two forms: a single subschema (2020-12) or a tuple array\n // of subschemas (draft-07). MCP servers emit both, and the truncation\n // sanitizer preserves the tuple array — validating it as a single schema\n // would reject the whole tool (\"expected object, got object\") and silently\n // drop a valid tool from the agent. Validate each tuple element instead.\n if (Array.isArray(schema.items)) {\n schema.items.forEach((sub, i) => validateSchema(sub, `${path}.items[${i}]`, errors, { depth: depth + 1 }));\n } else {\n validateSchema(schema.items, `${path}.items`, errors, { depth: depth + 1 });\n }\n }\n\n // Descend the remaining subschema-bearing keywords (composition, `$defs`,\n // conditional, pattern/additional). Booleans are valid subschemas in draft\n // 2020-12 (e.g. `additionalProperties: false`) — only object/array forms carry\n // a nested schema, so skip the rest.\n for (const key of SUBSCHEMA_OBJECT_KEYWORDS) {\n if (key in schema && isRecord(schema[key])) {\n validateSchema(schema[key], `${path}.${key}`, errors, { depth: depth + 1 });\n }\n }\n for (const key of SUBSCHEMA_LIST_KEYWORDS) {\n const list = schema[key];\n if (Array.isArray(list)) {\n list.forEach((sub, i) => validateSchema(sub, `${path}.${key}[${i}]`, errors, { depth: depth + 1 }));\n }\n }\n for (const key of SUBSCHEMA_MAP_KEYWORDS) {\n const map = schema[key];\n if (isRecord(map)) {\n for (const [name, sub] of Object.entries(map)) {\n validateSchema(sub, `${path}.${key}.${name}`, errors, { depth: depth + 1 });\n }\n }\n }\n\n // Flag unresolved placeholder literals on any string-valued field, but skip\n // fields the `enum` block above already reported on — otherwise a string\n // enum set to e.g. \"[KANBAN_STATUS_VALUES]\" would produce two errors for\n // the same path.\n const reportedPaths = new Set(errors.map(e => e.path));\n for (const [k, v] of Object.entries(schema)) {\n if (typeof v !== 'string') continue;\n const fieldPath = `${path}.${k}`;\n if (reportedPaths.has(fieldPath)) continue;\n for (const token of PLACEHOLDER_TOKENS) {\n if (v === token) {\n errors.push({\n path: fieldPath,\n message: `unresolved placeholder ${JSON.stringify(token)}`,\n suggestion: \"The platform renders this placeholder at tool-creation time. Ensure `operation: 'update_kanban_status'` is set and the hub has at least one kanban_status with `allowsAgentUpdate: true`.\",\n });\n }\n }\n }\n}\n\n/**\n * True when `schema.type` is `wanted` either as the scalar value or as an\n * entry in a type-array (draft 2020-12's union-type syntax, e.g. `[\"array\",\"null\"]`).\n */\nfunction schemaTypeIncludes(schema: Record<string, unknown>, wanted: string): boolean {\n const t = schema.type;\n if (typeof t === 'string') return t === wanted;\n if (Array.isArray(t)) return t.includes(wanted);\n return false;\n}\n\n// Keyword positions whose valid value is a string or array — NEVER an object.\n// zod→JSON-Schema serializers sometimes emit an empty object `{}` here (e.g.\n// `type:{}` for a `z.string()`, `enum:{}` for a `z.enum()`, nested inside array\n// items — gh #2554). The empty object carries zero constraint yet makes the\n// schema structurally INVALID, so the LLM provider 400s the turn / the tool is\n// dropped at runtime — total capability loss for a tool that is otherwise fine.\n// MUST stay in sync with `EMPTY_OBJECT_ARTIFACT_KEYS` in\n// `workers/backend/src/utils/sanitize-mcp-tool.ts` (the ingestion-boundary\n// repair); a drift-guard test pins the two behaviours together.\nconst EMPTY_OBJECT_ARTIFACT_KEYS = new Set(['type', 'enum', 'required']);\n// Proto-pollution keys never copied onto the repaired tree. Inlined (not\n// imported from the backend `nested-path` util) to keep this shared module\n// dependency-free.\nconst REPAIR_UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n// Absolute recursion backstop. The structure-aware walk only descends recognized\n// subschema positions (unknown keywords are copied verbatim, so they can't drive\n// unbounded recursion), and validated schemas are already ≤ MAX_SCHEMA_DEPTH —\n// but the runtime read may see rows persisted before that gate, so keep a stack\n// backstop well above any real schema. Past the cap a node is returned verbatim.\nconst MAX_REPAIR_DEPTH = 200;\n\nfunction isEmptyPlainObject(v: unknown): boolean {\n return isRecord(v) && Object.keys(v).length === 0;\n}\n\nfunction includesKey(keys: readonly string[], k: string): boolean {\n return keys.includes(k);\n}\n\n/**\n * Normalize known third-party JSON-Schema serialization artifacts so the result\n * is structurally valid: an empty-object value in a string/array-only KEYWORD\n * position (`type`/`enum`/`required`) — a meaningless zod→JSON-Schema artifact\n * (gh #2554) whose removal is lossless. ONLY the empty-object case is repaired; a\n * non-empty object there is ambiguous and left for `validateToolInputSchema` to\n * reject.\n *\n * The traversal MIRRORS `validateSchema` (and the ingestion-boundary\n * `capSchemaNode`): it descends ONLY genuine subschema positions, so a property\n * literally NAMED `type`/`enum`/`required` (a key inside `properties`/`$defs`/…\n * whose value is a sub-schema) is preserved, never mistaken for a keyword\n * artifact. Keyword VALUES and data (`enum` arrays, `const`, `default`,\n * `examples`, descriptions, …) are copied verbatim — unknown keywords too.\n *\n * Pure. On the clean path the result tree is NOT deep-cloned — an unchanged\n * subtree returns its original reference (structural sharing), so the per-turn hot\n * path pays a walk plus transient per-node scratch objects, not a full clone.\n * `repaired` is true iff something was dropped (`result !== schema`). Used at the\n * runtime snapshot read (`buildAgentToolsForLLM`) to heal rows persisted before\n * #2552 hardened the validator's composition-keyword descent.\n */\nexport function repairToolInputSchemaArtifacts(schema: unknown): { schema: unknown; repaired: boolean } {\n // Recurse a subschema-MAP value (`properties`/`$defs`/…): keys are names, values\n // are subschemas — recurse the values only; a name is never a keyword artifact.\n const repairMap = (v: unknown, depth: number): unknown => {\n if (!isRecord(v)) return v;\n let changed = false;\n const out: Record<string, unknown> = {};\n for (const [name, sub] of Object.entries(v)) {\n if (REPAIR_UNSAFE_KEYS.has(name)) { changed = true; continue; }\n const r = repairNode(sub, depth + 1);\n if (r !== sub) changed = true;\n out[name] = r;\n }\n return changed ? out : v;\n };\n\n // Recurse a subschema-LIST value (`anyOf`/`oneOf`/`allOf`/`prefixItems`, or a\n // draft-07 tuple `items`): an array of subschemas.\n const repairList = (arr: unknown[], depth: number): unknown[] => {\n let changed = false;\n const out = arr.map((e) => {\n const r = repairNode(e, depth + 1);\n if (r !== e) changed = true;\n return r;\n });\n return changed ? out : arr;\n };\n\n function repairNode(node: unknown, depth: number): unknown {\n if (depth >= MAX_REPAIR_DEPTH) return node;\n // Booleans are valid subschemas (draft 2020-12); a non-object/array in a\n // schema position is malformed server output — return verbatim (the validator\n // flags it), never descend.\n if (!isRecord(node)) return node;\n\n let changed = false;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(node)) {\n if (REPAIR_UNSAFE_KEYS.has(k)) { changed = true; continue; }\n if (EMPTY_OBJECT_ARTIFACT_KEYS.has(k) && isEmptyPlainObject(v)) {\n changed = true; // drop the empty-object artifact keyword\n continue;\n }\n let nv: unknown;\n if (k === 'properties' || includesKey(SUBSCHEMA_MAP_KEYWORDS, k)) {\n nv = repairMap(v, depth);\n } else if (k === 'items') {\n nv = Array.isArray(v) ? repairList(v, depth) : repairNode(v, depth + 1);\n } else if (includesKey(SUBSCHEMA_OBJECT_KEYWORDS, k)) {\n nv = repairNode(v, depth + 1);\n } else if (includesKey(SUBSCHEMA_LIST_KEYWORDS, k)) {\n nv = Array.isArray(v) ? repairList(v, depth) : v;\n } else {\n nv = v; // keyword value / data / unknown keyword — verbatim\n }\n if (nv !== v) changed = true;\n out[k] = nv;\n }\n return changed ? out : node;\n }\n\n const result = repairNode(schema, 0);\n return { schema: result, repaired: result !== schema };\n}\n\n/**\n * Non-mutating structural rewrite of a JSON-Schema tree (draft 2020-12).\n *\n * Descends the SAME subschema positions `validateSchema` and\n * `repairToolInputSchemaArtifacts` recognize — via the shared `SUBSCHEMA_*`\n * taxonomy — so a rewrite (e.g. a provider-subset filter) can't miss a keyword\n * the validator accepts. Children are rewritten first (post-order); each schema\n * NODE is then handed to `transform` with its children already rewritten.\n * `transform` returns the node's replacement keyword-set (typically a filtered\n * copy of its OWN keywords) and MUST NOT recurse — descent is handled here.\n *\n * Subschema-MAP positions (`properties`/`$defs`/`patternProperties`/\n * `dependentSchemas`) recurse VALUES only, so a property/definition NAMED like a\n * keyword (e.g. a param literally named `default`) is preserved, never mistaken\n * for the keyword. List positions (`allOf`/`anyOf`/`oneOf`/`prefixItems` and the\n * draft-07 tuple `items` array) recurse each element. Booleans / non-records are\n * valid leaf subschemas and pass through verbatim. Depth-bounded + proto-safe,\n * mirroring the repair walk (kept separate: repair optimizes for structural\n * sharing + a `repaired` flag; this always returns fresh nodes).\n */\nexport function mapSchemaTree(\n schema: unknown,\n transform: (node: Record<string, unknown>) => Record<string, unknown>,\n): unknown {\n function walk(node: unknown, depth: number): unknown {\n if (depth >= MAX_REPAIR_DEPTH) return node;\n if (!isRecord(node)) return node; // boolean / malformed leaf — verbatim\n\n const rewritten: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(node)) {\n if (REPAIR_UNSAFE_KEYS.has(k)) continue;\n if (k === 'properties' || includesKey(SUBSCHEMA_MAP_KEYWORDS, k)) {\n if (isRecord(v)) {\n const out: Record<string, unknown> = {};\n for (const [name, sub] of Object.entries(v)) {\n if (REPAIR_UNSAFE_KEYS.has(name)) continue;\n out[name] = walk(sub, depth + 1);\n }\n rewritten[k] = out;\n } else {\n rewritten[k] = v;\n }\n } else if (k === 'items') {\n rewritten[k] = Array.isArray(v)\n ? v.map((e) => walk(e, depth + 1))\n : walk(v, depth + 1);\n } else if (includesKey(SUBSCHEMA_OBJECT_KEYWORDS, k)) {\n rewritten[k] = walk(v, depth + 1);\n } else if (includesKey(SUBSCHEMA_LIST_KEYWORDS, k)) {\n rewritten[k] = Array.isArray(v) ? v.map((e) => walk(e, depth + 1)) : v;\n } else {\n rewritten[k] = v; // keyword value / data / unknown keyword — verbatim\n }\n }\n return transform(rewritten);\n }\n return walk(schema, 0);\n}\n\n/**\n * Validate a tool's `input_schema` (the value of `parameters` on an OpenAI\n * function tool, or `input_schema` on an Anthropic custom tool).\n *\n * Returns `{ ok: true }` on success, or `{ ok: false, errors }` with one\n * entry per distinct violation. Returns multiple errors per call to let\n * the CLI render them all at once, rather than one-per-push.\n */\nexport function validateToolInputSchema(schema: unknown): ValidationResult {\n const errors: SchemaViolation[] = [];\n\n if (!isRecord(schema)) {\n errors.push({\n path: '',\n message: `expected object at root, got ${schema === null ? 'null' : typeof schema}`,\n });\n return { ok: false, errors };\n }\n\n // `isRoot: true` enforces the stricter \"root must be object\" constraint\n // inside `validateSchema` (vs the ALLOWED_TYPES set used for nested\n // schemas). Consolidating the check here avoids the previous double-report\n // at paths `type` and `.type` when the root had an invalid type.\n validateSchema(schema, '', errors, { isRoot: true });\n\n return errors.length === 0 ? { ok: true } : { ok: false, errors };\n}\n","import { z } from 'zod';\nimport { SLUG_REGEX, slugSchema, visibleLength } from './slug';\n\n// state_slug = immutable wire identifier (LLM tool args, ClickHouse path, placeholder lookup, prompt-tag attribute). state_name = freely editable display label.\n\n// {} and null collapse to null at the contract boundary; undefined stays undefined so PATCH partial-update guards still work.\nconst initialValueCreateSchema = z\n .record(z.unknown())\n .nullish()\n .transform((v) => (v && Object.keys(v).length > 0 ? v : null));\n\nconst initialValueUpdateSchema = z\n .record(z.unknown())\n .nullish()\n .transform((v) => (v === undefined ? undefined : v && Object.keys(v).length > 0 ? v : null));\n\n// Param schemas\nexport const stateIdParam = z.object({\n id: z.string().uuid(),\n});\n\n// Query schemas\nexport const listStatesQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\nexport const stateNameSchema = z\n .string()\n .min(1, 'state_name is required')\n .max(100, 'state_name must be 100 characters or fewer')\n .refine((v) => visibleLength(v) > 0, 'state_name must not be blank');\n\n// Body schemas\nexport const createStateBody = z.object({\n hub_id: z.string().uuid(),\n state_slug: slugSchema,\n state_name: stateNameSchema,\n state_scope: z.enum(['conversation', 'user']),\n state_description: z.string().max(1000).nullish(),\n json_schema: z.record(z.unknown()).default({}),\n initial_value: initialValueCreateSchema,\n display_order: z.number().int().nonnegative().optional(),\n is_enabled: z.boolean().default(true),\n inject_in_last_message: z.boolean().default(true),\n});\n\nexport const updateStateBody = z.object({\n // state_slug is immutable after first persist — not accepted here.\n state_name: stateNameSchema.optional(),\n state_scope: z.enum(['conversation', 'user']).optional(),\n state_description: z.string().max(1000).nullish(),\n json_schema: z.record(z.unknown()).optional(),\n initial_value: initialValueUpdateSchema,\n display_order: z.number().int().nonnegative().optional(),\n is_enabled: z.boolean().optional(),\n inject_in_last_message: z.boolean().optional(),\n});\n\nexport const reorderStatesBody = z.object({\n states: z.array(z.object({\n state_id: z.string().uuid(),\n display_order: z.number().int().nonnegative(),\n })).min(1),\n});\n\n// Re-export the slug regex under a state-specific name for callers that want\n// to validate ad-hoc (migrations, slugify helpers).\nexport const STATE_SLUG_REGEX = SLUG_REGEX;\n\n// Inferred types\nexport type CreateStateInput = z.infer<typeof createStateBody>;\nexport type UpdateStateInput = z.infer<typeof updateStateBody>;\nexport type ReorderStatesInput = z.infer<typeof reorderStatesBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\nexport interface StateResponse {\n state_id: string;\n created_at: string;\n updated_at: string;\n hub_id: string;\n state_slug: string;\n state_name: string;\n state_scope: 'conversation' | 'user';\n state_description: string | null;\n json_schema: Record<string, unknown>;\n initial_value: Record<string, unknown> | null;\n display_order: number;\n is_enabled: boolean;\n inject_in_last_message: boolean;\n}\n\nexport interface ListStatesResponse {\n data: StateResponse[];\n}\n\nexport interface GetStateResponse {\n data: StateResponse;\n}\n\nexport interface CreateStateResponse {\n data: StateResponse;\n}\n\nexport interface UpdateStateResponse {\n data: StateResponse;\n}\n","import { z } from 'zod';\n\n// Param schemas\nexport const orgTagIdParam = z.object({\n id: z.string().uuid(),\n});\n\n// Query schemas\nexport const listOrgTagsQuery = z.object({\n organization_id: z.string().uuid(),\n});\n\n// Body schemas\nexport const createOrgTagBody = z.object({\n organization_id: z.string().uuid(),\n name: z.string().min(1).max(50).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, {\n message: 'Must be lowercase alphanumeric with hyphens (e.g. \"my-tag\")',\n }),\n display_name: z.string().max(100).nullish(),\n color: z.string().max(20).nullish(),\n});\n\nexport const updateOrgTagBody = z.object({\n // Required so the route targets the org the UI is managing (which may differ\n // from the token's default `auth.org_id` for multi-org users) — mirrors create/list.\n organization_id: z.string().uuid(),\n name: z.string().min(1).max(50).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, {\n message: 'Must be lowercase alphanumeric with hyphens (e.g. \"my-tag\")',\n }).optional(),\n display_name: z.string().max(100).nullish(),\n color: z.string().max(20).nullish(),\n});\n\n// Inferred types\nexport type CreateOrgTagInput = z.infer<typeof createOrgTagBody>;\nexport type UpdateOrgTagInput = z.infer<typeof updateOrgTagBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\nexport interface OrgTagResponse {\n tag_id: string;\n name: string;\n display_name: string | null;\n color: string | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface ListOrgTagsResponse {\n data: OrgTagResponse[];\n}\n\nexport interface CreateOrgTagResponse {\n data: OrgTagResponse;\n}\n\nexport interface UpdateOrgTagResponse {\n data: OrgTagResponse;\n}\n","import { z } from 'zod';\nimport { normalizeAuthType } from '../../constants';\n\n// Param schemas\nexport const orgCredentialIdParam = z.object({\n id: z.string().uuid(),\n});\n\n// Query schemas\nexport const listOrgCredentialsQuery = z.object({\n organization_id: z.string().uuid(),\n hub_id: z.string().uuid().optional(),\n});\n\n// Body schemas — accept both lowercase (canonical) and legacy capitalized values\nexport const createOrgCredentialBody = z.object({\n organization_id: z.string().uuid(),\n credential_display_name: z.string().min(1).max(255),\n credential_description: z.string().max(1000).nullish(),\n authentication_type: z.enum(['api_key', 'bearer', 'basic_auth']).or(\n z.enum(['API Key', 'Bearer Token', 'Basic Auth']).transform((v) => normalizeAuthType(v) as 'api_key' | 'bearer' | 'basic_auth')\n ),\n api_key: z.string().optional(),\n access_token: z.string().optional(),\n username: z.string().optional(),\n password: z.string().optional(),\n tags: z.array(z.string().uuid()).optional(),\n environment: z.enum(['preview', 'production', 'all']).optional(),\n});\n\nexport const updateOrgCredentialBody = z.object({\n credential_display_name: z.string().min(1).max(255).optional(),\n credential_description: z.string().max(1000).nullish(),\n api_key: z.string().optional(),\n access_token: z.string().optional(),\n username: z.string().optional(),\n password: z.string().optional(),\n tags: z.array(z.string().uuid()).optional(),\n environment: z.enum(['preview', 'production', 'all']).optional(),\n});\n\n// Inferred types\nexport type CreateOrgCredentialInput = z.infer<typeof createOrgCredentialBody>;\nexport type UpdateOrgCredentialInput = z.infer<typeof updateOrgCredentialBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\nexport interface OrgCredentialResponse {\n organization_credential_id: string;\n created_at: string;\n updated_at: string;\n organization_id: string;\n credential_display_name: string;\n credential_description: string | null;\n authentication_type: 'api_key' | 'bearer' | 'basic_auth';\n tags: string[];\n environment: 'preview' | 'production' | 'all';\n}\n\nexport interface ListOrgCredentialsResponse {\n data: OrgCredentialResponse[];\n}\n\nexport interface GetOrgCredentialResponse {\n data: OrgCredentialResponse;\n}\n\nexport interface CreateOrgCredentialResponse {\n data: OrgCredentialResponse;\n}\n\nexport interface UpdateOrgCredentialResponse {\n data: OrgCredentialResponse;\n}\n","/**\n * Organization-scoped shared resources — Zod schemas + response types.\n *\n * Org resources are linked into hubs as read-only shadow rows. The link surface\n * lives at `/api/setup/hubs/:hub_id/org-resources/*`; the canonical CRUD lives\n * at `/api/setup/organization-resources/*`. Skill resources are out of scope\n * for v1 — only `resource_type = 'knowledge'` is accepted.\n */\n\nimport { z } from 'zod';\nimport type { UploadSkillZipResponse } from './resources';\n\n// ---------------------------------------------------------------------------\n// Param schemas\n// ---------------------------------------------------------------------------\n\nexport const orgResourceIdParam = z.object({\n id: z.string().uuid(),\n});\n\nexport const orgResourceFileIdParam = z.object({\n file_id: z.string().uuid(),\n});\n\nexport const orgResourceFolderIdParam = z.object({\n folder_id: z.string().uuid(),\n});\n\n/**\n * `:id` is the hub id, `:org_resource_id` is the org resource being unlinked.\n * Used by `DELETE /api/setup/hubs/:id/org-resources/:org_resource_id`.\n */\nexport const hubOrgResourceParam = z.object({\n id: z.string().uuid(),\n org_resource_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Query schemas\n// ---------------------------------------------------------------------------\n\nexport const listOrgResourcesQuery = z.object({\n organization_id: z.string().uuid(),\n hub_id: z.string().uuid().optional(),\n});\n\nexport const orgIdQuery = z.object({\n organization_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Body schemas — canonical CRUD\n// ---------------------------------------------------------------------------\n\nexport const createOrgResourceBody = z.object({\n organization_id: z.string().uuid(),\n resource_name: z.string().min(1).max(255),\n resource_description: z.string().max(1000).nullish(),\n resource_type: z.enum(['knowledge', 'skill']).default('knowledge'),\n // Skill-only fields. Required for `resource_type = 'skill'` (validated in\n // the route layer since cross-field refinement complicates the inferred\n // input type for callers). Ignored for `knowledge`.\n skill_name: z.string().min(1).max(255).nullish(),\n skill_version: z.string().max(50).nullish(),\n folder_metadata_schema: z.record(z.unknown()).optional(),\n file_metadata_schema: z.record(z.unknown()).optional(),\n enabled: z.boolean().optional(),\n user_browsable: z.boolean().optional(),\n tags: z.array(z.string().uuid()).optional(),\n environment: z.enum(['preview', 'production', 'all']).optional(),\n});\n\nexport const updateOrgResourceBody = z.object({\n resource_name: z.string().min(1).max(255).optional(),\n resource_description: z.string().max(1000).nullish(),\n skill_name: z.string().min(1).max(255).nullish(),\n skill_version: z.string().max(50).nullish(),\n folder_metadata_schema: z.record(z.unknown()).optional(),\n file_metadata_schema: z.record(z.unknown()).optional(),\n enabled: z.boolean().optional(),\n user_browsable: z.boolean().optional(),\n tags: z.array(z.string().uuid()).optional(),\n environment: z.enum(['preview', 'production', 'all']).optional(),\n});\n\nexport const createOrgResourceFolderBody = z.object({\n org_resource_id: z.string().uuid(),\n folder_name: z.string().min(1).max(255),\n folder_description: z.string().max(1000).nullish(),\n parent_folder_id: z.string().uuid().nullish(),\n order_index: z.number().int().nonnegative().optional(),\n enabled: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const updateOrgResourceFolderBody = z.object({\n folder_name: z.string().min(1).max(255).optional(),\n folder_description: z.string().max(1000).nullish(),\n parent_folder_id: z.string().uuid().nullish(),\n order_index: z.number().int().nonnegative().optional(),\n enabled: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const uploadOrgResourceFileBody = z.object({\n org_resource_id: z.string().uuid(),\n folder_id: z.string().uuid().nullish(),\n file_name: z.string().min(1).max(255),\n file_data: z.string(), // base64\n mime_type: z.string().optional(),\n file_size: z.number().int().nonnegative().optional(),\n resource_file_tags: z.array(z.string()).optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const updateOrgResourceFileBody = z.object({\n resource_file_title: z.string().min(1).max(255).optional(),\n folder_id: z.string().uuid().nullish(),\n order_index: z.number().int().nonnegative().optional(),\n enabled: z.boolean().optional(),\n resource_file_tags: z.array(z.string()).optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\n/**\n * Bulk-materialize an org skill resource from a ZIP containing SKILL.md and\n * supporting files. Mirrors the hub-side `uploadSkillZipBody` shape, scoped\n * via the route `:id` param + `organization_id` query.\n */\nexport const uploadOrgSkillZipBody = z.object({\n zip_data: z.string().min(1),\n replace_existing: z.boolean().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Body schemas — hub linking\n// ---------------------------------------------------------------------------\n\nexport const linkOrgResourceBody = z.object({\n org_resource_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred input types\n// ---------------------------------------------------------------------------\n\nexport type CreateOrgResourceInput = z.infer<typeof createOrgResourceBody>;\nexport type UpdateOrgResourceInput = z.infer<typeof updateOrgResourceBody>;\nexport type CreateOrgResourceFolderInput = z.infer<typeof createOrgResourceFolderBody>;\nexport type UpdateOrgResourceFolderInput = z.infer<typeof updateOrgResourceFolderBody>;\nexport type UploadOrgResourceFileInput = z.infer<typeof uploadOrgResourceFileBody>;\nexport type UpdateOrgResourceFileInput = z.infer<typeof updateOrgResourceFileBody>;\nexport type UploadOrgSkillZipInput = z.infer<typeof uploadOrgSkillZipBody>;\nexport type LinkOrgResourceInput = z.infer<typeof linkOrgResourceBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface OrgResourceResponse {\n org_resource_id: string;\n organization_id: string;\n resource_name: string;\n resource_description: string | null;\n resource_type: 'knowledge' | 'skill';\n /** Set only when resource_type='skill'. */\n skill_name: string | null;\n /** Set only when resource_type='skill'. Defaults to '1.0.0'. */\n skill_version: string | null;\n folder_metadata_schema: Record<string, unknown>;\n file_metadata_schema: Record<string, unknown>;\n enabled: boolean;\n user_browsable: boolean;\n tags: string[];\n environment: 'preview' | 'production' | 'all';\n created_by: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface OrgResourceFileResponse {\n org_resource_file_id: string;\n org_resource_id: string;\n resource_file_title: string;\n resource_file_tags: string[];\n folder_id: string | null;\n file_id: string;\n file_path: string;\n file_name: string;\n mime_type: string | null;\n file_size: number | null;\n file_hash: string | null;\n order_index: number;\n enabled: boolean;\n metadata: Record<string, unknown>;\n created_by: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface OrgResourceFolderResponse {\n org_resource_folder_id: string;\n org_resource_id: string;\n folder_name: string;\n folder_description: string | null;\n parent_folder_id: string | null;\n order_index: number;\n enabled: boolean;\n metadata: Record<string, unknown>;\n created_by: string;\n created_at: string;\n updated_at: string;\n}\n\n/**\n * One entry of `GET /api/setup/hubs/:hub_id/org-resources/`. Combines the org\n * resource shape with link state for this hub. `policy_match` lets the UI\n * surface a warning when a previously-linked resource no longer matches the\n * hub's tag/environment policy.\n */\nexport interface HubOrgResourceEntry extends OrgResourceResponse {\n linked: boolean;\n linked_at: string | null;\n policy_match: 'ok' | 'stale_tags' | 'stale_env';\n}\n\nexport interface ListOrgResourcesResponse {\n data: OrgResourceResponse[];\n}\n\nexport interface GetOrgResourceResponse {\n data: OrgResourceResponse;\n}\n\nexport interface CreateOrgResourceResponse {\n data: OrgResourceResponse;\n}\n\nexport interface UpdateOrgResourceResponse {\n data: OrgResourceResponse;\n}\n\nexport interface DeleteOrgResourceResponse {\n data: { deleted: true; id: string };\n}\n\nexport interface ListOrgResourceFilesResponse {\n data: OrgResourceFileResponse[];\n}\n\nexport interface UploadOrgResourceFileResponse {\n data: OrgResourceFileResponse;\n}\n\n/**\n * Response from `POST /api/setup/organization-resources/:id/files/upload-zip`.\n * Structurally identical to the hub-side `UploadSkillZipResponse` — same fields,\n * same semantics; aliased so a change to either flows to both.\n */\nexport type UploadOrgSkillZipResponse = UploadSkillZipResponse;\n\nexport interface UpdateOrgResourceFileResponse {\n data: OrgResourceFileResponse;\n}\n\nexport interface DeleteOrgResourceFileResponse {\n data: { deleted: true; id: string };\n}\n\nexport interface ListOrgResourceFoldersResponse {\n data: OrgResourceFolderResponse[];\n}\n\nexport interface CreateOrgResourceFolderResponse {\n data: OrgResourceFolderResponse;\n}\n\nexport interface UpdateOrgResourceFolderResponse {\n data: OrgResourceFolderResponse;\n}\n\nexport interface DeleteOrgResourceFolderResponse {\n data: { deleted: true; id: string };\n}\n\nexport interface ListHubOrgResourcesResponse {\n data: HubOrgResourceEntry[];\n}\n\nexport interface LinkOrgResourceResponse {\n data: { resource_id: string; linked: true };\n}\n\nexport interface UnlinkOrgResourceResponse {\n data: { deleted: true; org_resource_id: string; hub_id: string };\n}\n\n/**\n * Returned by `GET /api/setup/organization-resources/files/:file_id/content`\n * for admin preview of an org-resource file. Provides a short-lived signed\n * URL the browser can fetch directly — avoids streaming bytes through the\n * worker and keeps the existing `/files/auth/...` org-membership check on\n * the signed-URL serving route.\n */\nexport interface OrgResourceFileContentResponse {\n data: {\n file_id: string;\n file_name: string;\n mime_type: string | null;\n file_size: number | null;\n signed_url: string;\n expires_in_seconds: number;\n };\n}\n","import { z } from 'zod';\nimport { uuidSchema } from '../common';\n\n// =============================================================================\n// Resource params & queries\n// =============================================================================\n\nexport const resourceIdParam = z.object({ id: uuidSchema });\n\nexport const listResourcesQuery = z.object({\n hub_id: uuidSchema,\n enabled: z.enum(['true', 'false']).optional(),\n resource_type: z.enum(['knowledge', 'skill']).optional(),\n search: z.string().optional(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n});\n\nexport const createResourceBody = z.object({\n hub_id: uuidSchema,\n resource_name: z.string().min(1),\n resource_description: z.string().optional(),\n enabled: z.boolean().optional(),\n folder_metadata_schema: z.record(z.unknown()).optional(),\n file_metadata_schema: z.record(z.unknown()).optional(),\n resource_type: z.enum(['knowledge', 'skill']).optional(),\n skill_name: z.string().optional(),\n skill_version: z.string().optional(),\n user_browsable: z.boolean().optional(),\n});\n\nexport const updateResourceBody = z.object({\n resource_name: z.string().min(1).optional(),\n resource_description: z.string().optional(),\n enabled: z.boolean().optional(),\n folder_metadata_schema: z.record(z.unknown()).optional(),\n file_metadata_schema: z.record(z.unknown()).optional(),\n skill_name: z.string().optional(),\n skill_version: z.string().optional(),\n anthropic_skill_id: z.string().optional(),\n anthropic_version: z.string().optional(),\n user_browsable: z.boolean().optional(),\n});\n\nexport const syncSkillsBody = z.object({\n hub_id: uuidSchema,\n connection_id: uuidSchema.optional(),\n});\n\n// =============================================================================\n// Resource File params & queries\n// =============================================================================\n\nexport const resourceFileIdParam = z.object({ id: uuidSchema });\n\nexport const listResourceFilesQuery = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema.optional(),\n folder_id: z.string().optional(), // 'null' for root, UUID for specific folder\n search: z.string().optional(),\n tags: z.string().optional(), // comma-separated\n enabled: z.enum(['true', 'false']).optional(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n include_root_files: z.enum(['true', 'false']).optional(),\n});\n\nexport const createResourceFileBody = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n file_id: uuidSchema,\n folder_id: uuidSchema.nullable().optional(),\n resource_file_title: z.string().optional(),\n resource_file_tags: z.array(z.string()).optional(),\n order_index: z.number().optional(),\n enabled: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const updateResourceFileBody = z.object({\n resource_file_title: z.string().optional(),\n resource_file_tags: z.array(z.string()).optional(),\n folder_id: uuidSchema.nullable().optional(),\n order_index: z.number().optional(),\n enabled: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const uploadResourceFileBody = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n folder_id: uuidSchema.nullable().optional(),\n file_name: z.string().min(1),\n file_data: z.string().min(1),\n mime_type: z.string().optional(),\n file_size: z.number().optional(),\n tags: z.array(z.string()).optional(),\n});\n\nexport const uploadSkillZipBody = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n zip_data: z.string().min(1),\n replace_existing: z.boolean().optional(),\n});\n\n// =============================================================================\n// Resource Folder params & queries\n// =============================================================================\n\nexport const resourceFolderIdParam = z.object({ id: uuidSchema });\n\nexport const listResourceFoldersQuery = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n parent_folder_id: z.string().optional(), // 'null' for root folders\n enabled: z.enum(['true', 'false']).optional(),\n});\n\nexport const createResourceFolderBody = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n folder_name: z.string().min(1),\n folder_description: z.string().optional(),\n parent_folder_id: uuidSchema.nullable().optional(),\n order_index: z.number().optional(),\n enabled: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const updateResourceFolderBody = z.object({\n folder_name: z.string().min(1).optional(),\n folder_description: z.string().optional(),\n parent_folder_id: uuidSchema.nullable().optional(),\n order_index: z.number().optional(),\n enabled: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\n// =============================================================================\n// Agent Resource params & queries\n// =============================================================================\n\nexport const agentResourceQuery = z.object({\n hub_id: uuidSchema,\n agent_id: uuidSchema.optional(),\n resource_id: uuidSchema.optional(),\n}).refine(data => data.agent_id || data.resource_id, {\n message: 'Either agent_id or resource_id is required',\n});\n\nexport const hubResourceQuery = z.object({ hub_id: uuidSchema });\n\nexport const linkAgentResourceBody = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n agent_id: uuidSchema,\n priority: z.number().optional(),\n use_native_integration: z.boolean().optional(),\n include_structure_in_prompt: z.boolean().optional(),\n write_enabled: z.boolean().optional(),\n});\n\nexport const updateAgentResourceBody = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n agent_id: uuidSchema,\n use_native_integration: z.boolean().optional(),\n include_structure_in_prompt: z.boolean().optional(),\n enabled: z.boolean().optional(),\n priority: z.number().optional(),\n write_enabled: z.boolean().optional(),\n});\n\nexport const unlinkAgentResourceQuery = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n agent_id: uuidSchema,\n});\n\n// =============================================================================\n// Inferred types\n// =============================================================================\n\nexport type CreateResourceInput = z.infer<typeof createResourceBody>;\nexport type UpdateResourceInput = z.infer<typeof updateResourceBody>;\nexport type CreateResourceFileInput = z.infer<typeof createResourceFileBody>;\nexport type UpdateResourceFileInput = z.infer<typeof updateResourceFileBody>;\nexport type UploadResourceFileInput = z.infer<typeof uploadResourceFileBody>;\nexport type UploadSkillZipInput = z.infer<typeof uploadSkillZipBody>;\nexport type CreateResourceFolderInput = z.infer<typeof createResourceFolderBody>;\nexport type UpdateResourceFolderInput = z.infer<typeof updateResourceFolderBody>;\nexport type LinkAgentResourceInput = z.infer<typeof linkAgentResourceBody>;\nexport type UpdateAgentResourceInput = z.infer<typeof updateAgentResourceBody>;\n\n// =============================================================================\n// RESPONSE TYPES — Resource\n// =============================================================================\n\n/** A single resource row (select *) */\nexport interface ResourceResponse {\n resource_id: string;\n created_at: string;\n updated_at: string;\n resource_name: string;\n resource_description: string | null;\n hub_id: string;\n created_by: string;\n enabled: boolean;\n user_browsable: boolean;\n folder_metadata_schema: Record<string, unknown> | null;\n file_metadata_schema: Record<string, unknown> | null;\n resource_type: 'knowledge' | 'skill';\n skill_name: string | null;\n skill_version: string | null;\n}\n\nexport interface ListResourcesResponse {\n success: true;\n data: ResourceResponse[];\n total_count: number;\n}\n\nexport interface GetResourceResponse {\n success: true;\n data: ResourceResponse;\n}\n\nexport interface CreateResourceResponse {\n success: true;\n data: ResourceResponse;\n}\n\nexport interface UpdateResourceResponse {\n success: true;\n data: ResourceResponse;\n}\n\nexport interface DeleteResourceResponse {\n success: true;\n message: string;\n}\n\n// =============================================================================\n// RESPONSE TYPES — Resource File\n// =============================================================================\n\n/** Joined file metadata returned with resource_file list queries */\nexport interface ResourceFileJoinedFile {\n file_id: string;\n file_name: string;\n file_path: string;\n bucket: string;\n mime_type: string;\n file_size: number;\n}\n\n/** Joined file metadata returned with resource_file read queries (includes file_text) */\nexport interface ResourceFileJoinedFileWithText extends ResourceFileJoinedFile {\n file_text: string | null;\n}\n\n/** A resource_file row with joined file data (list variant) */\nexport interface ResourceFileResponse {\n resource_file_id: string;\n created_at: string;\n updated_at: string;\n resource_file_title: string;\n resource_file_tags: string[] | null;\n created_by: string;\n enabled: boolean;\n folder_id: string | null;\n file_id: string;\n order_index: number;\n resource_id: string;\n metadata: Record<string, unknown> | null;\n file_path: string | null;\n file: ResourceFileJoinedFile | null;\n}\n\n/** A resource_file row with joined file data (read variant — includes file_text) */\nexport interface ResourceFileDetailResponse {\n resource_file_id: string;\n created_at: string;\n updated_at: string;\n resource_file_title: string;\n resource_file_tags: string[] | null;\n created_by: string;\n enabled: boolean;\n folder_id: string | null;\n file_id: string;\n order_index: number;\n resource_id: string;\n metadata: Record<string, unknown> | null;\n file_path: string | null;\n file: ResourceFileJoinedFileWithText | null;\n}\n\n/** A resource_file row without joined file data (create/update return select *) */\nexport interface ResourceFileRowResponse {\n resource_file_id: string;\n created_at: string;\n updated_at: string;\n resource_file_title: string;\n resource_file_tags: string[] | null;\n created_by: string;\n enabled: boolean;\n folder_id: string | null;\n file_id: string;\n order_index: number;\n resource_id: string;\n metadata: Record<string, unknown> | null;\n file_path: string | null;\n}\n\nexport interface ListResourceFilesResponse {\n success: true;\n data: ResourceFileResponse[];\n total_count: number;\n}\n\nexport interface GetResourceFileResponse {\n success: true;\n data: ResourceFileDetailResponse;\n}\n\nexport interface CreateResourceFileResponse {\n success: true;\n data: ResourceFileRowResponse;\n}\n\nexport interface UpdateResourceFileResponse {\n success: true;\n data: ResourceFileRowResponse;\n}\n\nexport interface DeleteResourceFileResponse {\n success: true;\n message: string;\n}\n\nexport interface UploadResourceFileResponse {\n success: true;\n data: {\n fileId: string;\n fileName: string;\n fileUrl: string;\n resourceFileId: string;\n };\n}\n\nexport interface UploadSkillZipResponse {\n success: boolean;\n files_uploaded: number;\n folders_created: number;\n frontmatter: Record<string, string | undefined>;\n errors: string[];\n warnings: string[];\n root_folder_stripped?: string;\n}\n\n// =============================================================================\n// RESPONSE TYPES — Resource Folder\n// =============================================================================\n\n/** A single resource_folder row (select *) */\nexport interface ResourceFolderResponse {\n resource_folder_id: string;\n created_at: string;\n updated_at: string;\n folder_name: string;\n folder_description: string | null;\n order_index: number;\n parent_folder_id: string | null;\n resource_id: string;\n created_by: string;\n enabled: boolean;\n metadata: Record<string, unknown> | null;\n}\n\nexport interface ListResourceFoldersResponse {\n success: true;\n data: ResourceFolderResponse[];\n total_count: number;\n}\n\nexport interface GetResourceFolderResponse {\n success: true;\n data: ResourceFolderResponse;\n}\n\nexport interface CreateResourceFolderResponse {\n success: true;\n data: ResourceFolderResponse;\n}\n\nexport interface UpdateResourceFolderResponse {\n success: true;\n data: ResourceFolderResponse;\n}\n\nexport interface DeleteResourceFolderResponse {\n success: true;\n message: string;\n}\n\n// =============================================================================\n// RESPONSE TYPES — Agent Resource\n// =============================================================================\n\n/** A single agent_resource row (select *) */\nexport interface AgentResourceRowResponse {\n agent_resource_id: string;\n agent_id: string;\n resource_id: string;\n priority: number;\n enabled: boolean;\n created_at: string;\n use_native_integration: boolean;\n include_structure_in_prompt: boolean;\n write_enabled?: boolean;\n}\n\n/** Provider sync info for a skill resource (flattened from nested join) */\nexport interface AgentResourceProviderSync {\n sync_id: string;\n sync_status: 'pending' | 'synced' | 'failed';\n last_sync_at: string | null;\n service_name: string;\n}\n\n/** Flattened agent-resource with resource details (returned by getAgentResources) */\nexport interface AgentResourceLink {\n agent_resource_id: string;\n resource_id: string;\n resource_name: string;\n resource_description: string | null;\n resource_type: 'knowledge' | 'skill';\n priority: number;\n enabled: boolean;\n use_native_integration: boolean;\n include_structure_in_prompt: boolean;\n write_enabled?: boolean;\n provider_syncs?: AgentResourceProviderSync[];\n}\n\n/** Agent info attached to a resource (returned by getResourceAgents) */\nexport interface ResourceAgentLink {\n agent_id: string;\n priority: number;\n enabled: boolean;\n agent: {\n agent_id: string;\n agent_name: string;\n agent_role: string;\n } | null;\n}\n\nexport interface GetAgentResourcesResponse {\n success: true;\n resources: AgentResourceLink[];\n}\n\nexport interface GetResourceAgentsResponse {\n data: ResourceAgentLink[];\n}\n\n/** Hub resource summary (for selection dropdowns) */\nexport interface HubResourceSummary {\n resource_id: string;\n resource_name: string;\n resource_description: string | null;\n resource_type: 'knowledge' | 'skill';\n enabled: boolean;\n}\n\nexport interface ListHubResourcesResponse {\n success: true;\n resources: HubResourceSummary[];\n total_count: number;\n}\n\nexport interface LinkAgentResourceResponse {\n success: true;\n link: AgentResourceRowResponse;\n}\n\nexport interface UpdateAgentResourceResponse {\n success: true;\n link: AgentResourceRowResponse;\n}\n\nexport interface UnlinkAgentResourceResponse {\n success: true;\n message: string;\n}\n\n// =============================================================================\n// RESPONSE TYPES — Skill Sync\n// =============================================================================\n\nexport interface SyncSkillsResultItem {\n connection_id: string;\n connection_name: string;\n uploaded: number;\n failed: number;\n errors: string[];\n}\n\nexport interface SyncSkillsResponse {\n success: true;\n message: string;\n results: SyncSkillsResultItem[];\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Live Update Navigation\n// ---------------------------------------------------------------------------\n\n// User-facing nav values only. `chat_task` is an internal cache-sharing\n// fetch mode (never a persisted nav state), so it is intentionally excluded.\nexport const navItemSchema = z.enum(['chat', 'support', 'task']);\n\nexport const hubCountResetBody = z.object({\n hub_id: z.string().uuid(),\n nav_item: navItemSchema,\n conversation_id: z.string().uuid().optional(),\n hub_user_id: z.string().optional(),\n current_team_user_id: z.string().optional(),\n});\n\nexport const navItemCountResetBody = z.object({\n nav_item: navItemSchema,\n});\n\n// ---------------------------------------------------------------------------\n// Typing Indicator\n// ---------------------------------------------------------------------------\n\nexport const typingBody = z.object({\n conversationId: z.string().uuid(),\n hubId: z.string().uuid(),\n action: z.enum(['start', 'stop']),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type HubCountResetBody = z.infer<typeof hubCountResetBody>;\nexport type NavItemCountResetBody = z.infer<typeof navItemCountResetBody>;\nexport type TypingBody = z.infer<typeof typingBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface NavigationCounts {\n chat_count: number;\n support_count: number;\n task_count: number;\n}\n\n/** GET /counts */\nexport interface GetNavigationCountsResponse {\n success: true;\n data: NavigationCounts;\n}\n\n/** POST /reset-hub */\nexport interface ResetHubCountResponse {\n success: true;\n message: string;\n updated: boolean;\n}\n\n/** POST /reset-nav */\nexport interface ResetNavItemCountResponse {\n success: true;\n message: string;\n}\n\n/** POST /typing */\nexport interface TypingResponse {\n success: true;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Analytics Schema & Hubs\n// ---------------------------------------------------------------------------\n\n// No request schema needed for GET /schema (no params)\n\nexport const analyticsHubIdParam = z.object({\n hubId: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Variables\n// ---------------------------------------------------------------------------\n\nexport const analyticsVariableIdParam = z.object({\n variableId: z.string().uuid(),\n});\n\n// Variable names produced by default message_evaluator (PR1). Source of truth for chip-bar seeding + default badge — keep in sync with DEFAULT_EVALUATOR_PARAMETERS in hub-do.ts.\nexport const DEFAULT_EVALUATOR_VARIABLES = [\n 'goal_achieved',\n 'user_sentiment',\n 'conversation_summary',\n] as const;\n\nexport const updateVariablePinBody = z.object({\n pin: z.union([z.boolean(), z.string()]),\n});\n\n// ---------------------------------------------------------------------------\n// Analytics view (chip bar selection — shared across hub admins)\n// ---------------------------------------------------------------------------\n\nexport const updateAnalyticsViewBody = z.object({\n // 64 covers UUIDs (36) and the `sys:{name}` synthetic IDs for system variables.\n selected_variable_ids: z.array(z.string().min(1).max(64)).max(200),\n});\n\n// ---------------------------------------------------------------------------\n// Filter & aggregation literals (single source of truth — drives Zod schemas\n// below and is re-exported for runtime use by clients like the CLI).\n// ---------------------------------------------------------------------------\n\nexport const NUMERIC_FILTER_OPS = ['eq', 'neq', 'gt', 'gte', 'lt', 'lte'] as const;\nexport const TEXT_FILTER_OPS = ['equals', 'not_equals', 'contains', 'not_contains', 'starts_with', 'ends_with'] as const;\nexport const CATEGORICAL_FILTER_OPS = ['is', 'is_not', 'in', 'not_in'] as const;\nexport const VARIABLE_FILTER_OPS = [\n ...NUMERIC_FILTER_OPS,\n ...TEXT_FILTER_OPS,\n ...CATEGORICAL_FILTER_OPS,\n] as const;\n\nexport const STRUCTURED_QUERY_OPS = ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'in', 'not_in', 'like'] as const;\nexport const STRUCTURED_QUERY_AGGREGATIONS = ['avg', 'sum', 'min', 'max', 'count', 'quantile', 'stddevPop', 'corr', 'uniq'] as const;\n\n// ---------------------------------------------------------------------------\n// Conversations\n// ---------------------------------------------------------------------------\n\nconst filterValueSchema = z.object({\n variable_id: z.string(),\n filter_type: z.enum(VARIABLE_FILTER_OPS),\n filter_value: z.union([z.string(), z.number()]),\n});\n\nexport const conversationsBody = z.object({\n hub_id: z.string().uuid(),\n time_interval: z.object({\n start: z.string().optional(),\n end: z.string().optional(),\n }).optional(),\n filters: z.array(filterValueSchema).optional(),\n limit: z.number().int().positive().max(500).default(50),\n offset: z.number().int().min(0).default(0),\n});\n\n// ---------------------------------------------------------------------------\n// Conversation Messages\n// ---------------------------------------------------------------------------\n\nexport const analyticsConversationIdParam = z.object({\n conversationId: z.string().uuid(),\n});\n\nexport const messagesQuery = z.object({\n hub_id: z.string().uuid(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Conversation Detail Data\n// ---------------------------------------------------------------------------\n\nexport const conversationDetailDataQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\nexport type ConversationDetailDataQuery = z.infer<typeof conversationDetailDataQuery>;\n\n// ---------------------------------------------------------------------------\n// Analytics Data\n// ---------------------------------------------------------------------------\n\nexport const analyticsDataBody = z.object({\n hub_id: z.string().uuid(),\n periodicity: z.enum(['daily', 'weekly', 'monthly', 'yearly']),\n time_interval: z.object({\n start: z.string(),\n end: z.string(),\n }),\n trend_analysis: z.boolean(),\n filters: z.array(filterValueSchema).optional(),\n selected_variables: z.array(z.string()),\n include_summary: z.boolean().optional(),\n include_variables: z.boolean().optional(),\n variable_origin: z.enum(['agent', 'system']).optional(),\n variable_category: z.string().optional(),\n variables_only: z.boolean().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Structured Query\n// ---------------------------------------------------------------------------\n\nexport const structuredQueryBody = z.object({\n hub_id: z.string().uuid(),\n metrics: z.array(z.object({\n column: z.string(),\n aggregation: z.enum(STRUCTURED_QUERY_AGGREGATIONS),\n alias: z.string().optional(),\n corr_with: z.string().optional(),\n quantile_level: z.number().min(0).max(1).optional(),\n })).min(1),\n group_by: z.array(z.string()).optional(),\n order_by: z.array(z.object({\n column: z.string(),\n direction: z.enum(['asc', 'desc']).optional(),\n })).optional(),\n filters: z.array(z.object({\n column: z.string(),\n operator: z.enum(STRUCTURED_QUERY_OPS),\n value: z.union([z.string(), z.number(), z.boolean()]),\n })).optional(),\n time_range: z.object({\n start: z.string(),\n end: z.string(),\n }).optional(),\n limit: z.number().int().positive().max(10000).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Read-only SQL (CLI agent surface — POST /sql, GET /sql/schema)\n// ---------------------------------------------------------------------------\n\nexport const analyticsSqlBody = z.object({\n hub_id: z.string().uuid(),\n // Hard size cap before the validator runs — keeps lex/parse work bounded.\n sql: z.string().min(1).max(8000),\n limit: z.number().int().positive().max(10000).optional(),\n});\n\nexport const analyticsSqlSchemaQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type AnalyticsHubIdParam = z.infer<typeof analyticsHubIdParam>;\nexport type AnalyticsVariableIdParam = z.infer<typeof analyticsVariableIdParam>;\nexport type UpdateVariablePinBody = z.infer<typeof updateVariablePinBody>;\nexport type UpdateAnalyticsViewBody = z.infer<typeof updateAnalyticsViewBody>;\nexport type ConversationsBody = z.infer<typeof conversationsBody>;\nexport type AnalyticsConversationIdParam = z.infer<typeof analyticsConversationIdParam>;\nexport type MessagesQuery = z.infer<typeof messagesQuery>;\nexport type AnalyticsDataBody = z.infer<typeof analyticsDataBody>;\nexport type StructuredQueryBody = z.infer<typeof structuredQueryBody>;\nexport type AnalyticsSqlBody = z.infer<typeof analyticsSqlBody>;\nexport type AnalyticsSqlSchemaQuery = z.infer<typeof analyticsSqlSchemaQuery>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n// ---------------------------------------------------------------------------\n// Shared primitives (used across multiple responses)\n// ---------------------------------------------------------------------------\n\nexport type NumericFilterType = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte';\nexport type TextFilterType = 'equals' | 'not_equals' | 'contains' | 'not_contains' | 'starts_with' | 'ends_with';\nexport type CategoricalFilterType = 'is' | 'is_not' | 'in' | 'not_in';\nexport type FilterType = NumericFilterType | TextFilterType | CategoricalFilterType;\n\nexport type VariableOrigin = 'agent' | 'system';\nexport type Periodicity = 'daily' | 'weekly' | 'monthly' | 'yearly';\n\nexport interface TimeInterval {\n start: string;\n end: string;\n}\n\nexport interface VariableFilter {\n variable_id: string;\n filter_type: FilterType;\n filter_value: string | number;\n}\n\n// ---------------------------------------------------------------------------\n// GET /schema — analytics hierarchy\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsSchemaResponse {\n data: {\n flat: {\n organizations: Array<{ id: string; name: string }>;\n hubsByOrg: Record<string, Array<{ id: string; name: string }>>;\n };\n lastUpdated: string;\n };\n}\n\n// ---------------------------------------------------------------------------\n// GET /hubs — hubs list\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsHubInfo {\n hub_id: string;\n hub_name: string;\n hub_description: string | null;\n}\n\nexport interface AnalyticsHubsListResponse {\n success: true;\n hubs: AnalyticsHubInfo[];\n}\n\n// ---------------------------------------------------------------------------\n// GET /hubs/:hubId/variables — variables by hub\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsCategoryInfo {\n category: string;\n label: string;\n variableCount: number;\n}\n\nexport interface AnalyticsConversationVariable {\n variable_id: string;\n variable_name: string;\n variable_description?: string;\n variable_label?: string;\n variable_type: 'numeric' | 'categorical' | 'text';\n variable_origin: string;\n variable_category: string;\n variable_enum: unknown[];\n pin: boolean;\n hub_id?: string;\n}\n\nexport interface AnalyticsVariablesByHubResponse {\n success: true;\n data: {\n categories: AnalyticsCategoryInfo[];\n variablesByCategory: Record<string, AnalyticsConversationVariable[]>;\n };\n}\n\n// ---------------------------------------------------------------------------\n// PATCH /variables/:variableId/pin — update pin status\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsUpdatePinResponse {\n success: true;\n data: {\n variable_id: string;\n pin: boolean;\n };\n}\n\n// ---------------------------------------------------------------------------\n// GET / PUT /hubs/:hubId/selection — analytics view (chip bar) selection\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsViewResponse {\n success: true;\n data: {\n selected_variable_ids: string[];\n seeded: boolean;\n };\n}\n\n// ---------------------------------------------------------------------------\n// POST /conversations — conversation list\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsConversationListItem {\n conversation_id: string;\n created_at?: string;\n updated_at?: string;\n message_count?: number;\n message_text?: string;\n participant_name?: string;\n participant_phone?: string;\n hub_name?: string;\n user_name?: string;\n user_sentiment?: string;\n goal_achieved?: string;\n [key: string]: unknown;\n}\n\nexport interface AnalyticsConversationsListResponse {\n success: true;\n conversations: AnalyticsConversationListItem[];\n total: number;\n offset: number;\n limit: number;\n /**\n * True when ClickHouse was cold and the response is a provisional empty\n * result — the client should keep polling until this flag disappears.\n */\n cold?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// GET /conversations/:conversationId/messages — messages\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsConversationMessage {\n message_id: string;\n message_key?: string;\n created_at: string;\n message_text?: string;\n message_type: string;\n sender_type: string;\n receiver_type: string;\n channel_type: string;\n sender_name?: string;\n}\n\nexport interface AnalyticsConversationMessagesResponse {\n success: true;\n messages?: AnalyticsConversationMessage[];\n conversation?: {\n conversation_id: string;\n participant_name?: string;\n };\n}\n\n// ---------------------------------------------------------------------------\n// GET /conversations/:conversationId/data — conversation detail data\n// ---------------------------------------------------------------------------\n\nexport interface ConversationDetailVariableValue {\n name: string;\n value: string | number | null;\n label?: string;\n description?: string;\n type?: 'numeric' | 'categorical' | 'text';\n category?: string;\n variable_enum?: unknown[];\n}\n\nexport interface ConversationDetailDataResponse {\n success: true;\n conversation_id: string;\n hub_id: string;\n system: ConversationDetailVariableValue[];\n variables: ConversationDetailVariableValue[];\n meta: Record<string, string | number | null>;\n /**\n * True when ClickHouse was cold and the response is a provisional empty\n * result — the client should keep polling until this flag disappears.\n */\n cold?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// POST /data — analytics data (numeric, categorical, text)\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsTrendDataPoint {\n period: string;\n value: number | string | Record<string, number>;\n}\n\nexport interface AnalyticsMetrics {\n average: number;\n sum: number;\n minimum: number;\n maximum: number;\n count?: number;\n median?: number;\n}\n\nexport interface AnalyticsDataItem {\n variable: string;\n variable_id: string;\n type: 'numeric' | 'categorical' | 'text';\n data?: AnalyticsTrendDataPoint[];\n metrics?: AnalyticsMetrics;\n distribution?: Record<string, number>;\n}\n\nexport interface AnalyticsSummaryTrendData {\n period: string;\n total_conversations: number;\n ai_only_rate: number;\n avg_response_time: number;\n assistant_response_time: number;\n support_response_time: number;\n user_response_time: number;\n}\n\nexport interface AnalyticsSummaryData {\n total_conversations: number;\n ai_only_rate: number;\n avg_response_time: number;\n assistant_response_time: number;\n support_response_time: number;\n user_response_time: number;\n data?: AnalyticsSummaryTrendData[];\n}\n\n/** Response for variables_only=true requests */\nexport interface AnalyticsVariablesOnlyResponse {\n variables: unknown[];\n}\n\n/** Full analytics data response (POST /data) */\nexport interface AnalyticsDataResponse {\n analytics: AnalyticsDataItem[];\n summary?: AnalyticsSummaryData;\n variables?: unknown[];\n /**\n * True when any of the parallel fan-out queries (numeric / categorical /\n * text / summary) returned a cold-start outcome. The frontend uses this\n * single flag to flip the cold store and show the cold-start banner.\n */\n cold?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// POST /query — structured analytics query\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsStructuredQueryResponse {\n success: true;\n data: Record<string, unknown>[];\n statistics?: {\n elapsed: number;\n rows_read: number;\n bytes_read: number;\n };\n}\n\n// ---------------------------------------------------------------------------\n// POST /sql — read-only SQL (CLI agent surface). Same shape as /query plus a\n// `cold` flag so the agent can distinguish a genuine empty result from a\n// ClickHouse cold-start (mirrors the existing analytics cold-start contract\n// on `/conversations`, `/data`, `/conversations/:id/data`).\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsSqlResponse {\n success: true;\n data: Record<string, unknown>[];\n statistics?: {\n elapsed: number;\n rows_read: number;\n bytes_read: number;\n };\n cold?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// GET /sql/schema — column + variable-path catalog the agent can introspect\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsSqlSchemaPath {\n path: string;\n type: 'numeric' | 'categorical' | 'text' | 'unknown';\n origin: 'system' | 'agent';\n category?: string;\n description?: string;\n}\n\nexport interface AnalyticsSqlSchemaResponse {\n success: true;\n data: {\n table: 'conversation';\n top_level: Array<{ column: string; type: string }>;\n paths: AnalyticsSqlSchemaPath[];\n };\n}\n","import { z } from 'zod';\nimport { PACING_INTERVAL_MAX_MS, PACING_INTERVAL_MIN_MS, EVAL_RUN_DEADLINE_MIN_MS, EVAL_RUN_DEADLINE_MAX_MS } from '../eval-pacing';\n\n// ---------------------------------------------------------------------------\n// Common\n// ---------------------------------------------------------------------------\n\nconst paginationSchema = z.object({\n limit: z.number().int().positive().max(1000).default(50),\n offset: z.number().int().min(0).default(0),\n}).optional();\n\nconst evalIdParam = z.object({\n id: z.string().uuid(),\n});\n\nconst sessionIdParam = z.object({\n id: z.string().uuid(),\n});\n\nconst scenarioSetIdParam = z.object({\n id: z.string().uuid(),\n});\n\nconst hubIdQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Eval CRUD\n// ---------------------------------------------------------------------------\n\nexport const createEvalBody = z.object({\n eval: z.record(z.unknown()),\n});\n\nexport const updateEvalBody = z.object({\n eval: z.record(z.unknown()),\n});\n\nexport const getEvalsQuery = z.object({\n hub_id: z.string().uuid(),\n agent_id: z.string().uuid().optional(),\n enabled: z.string().regex(/^(true|false)$/).optional(),\n search: z.string().optional(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Toggle / Bulk Toggle\n// ---------------------------------------------------------------------------\n\nexport const toggleEvalBody = z.object({\n enabled: z.boolean(),\n});\n\nexport const bulkToggleEvalsBody = z.object({\n hub_id: z.string().uuid(),\n enabled: z.boolean(),\n filters: z.object({\n agent_id: z.string().uuid().optional(),\n search: z.string().optional(),\n }).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Sessions\n// ---------------------------------------------------------------------------\n\nexport const pacingConfigSchema = z.object({\n preset: z.enum(['conservative', 'custom']),\n custom_interval_ms: z.number().int().min(PACING_INTERVAL_MIN_MS).max(PACING_INTERVAL_MAX_MS).optional(),\n}).refine(\n (v) => v.preset !== 'custom' || typeof v.custom_interval_ms === 'number',\n { message: 'custom_interval_ms required when preset is \"custom\"' },\n);\n\n// `pacing` is the only client-supplied session_config field today; the backend\n// also writes `agent` and `scenario_set_id` snapshots during run-session.\n// `passthrough()` on both layers preserves those server-managed fields and\n// keeps room for future client-side keys without contract churn.\nexport const sessionConfigSchema = z.object({\n pacing: pacingConfigSchema.optional(),\n // Per-run finalization deadline for the HubDO watchdog (gh #2591). A started\n // run idle past this many ms is reaped to `failed`. Omitted → backend default\n // (`EVAL_DEFAULT_RUN_DEADLINE_MS`).\n run_deadline_ms: z.number().int().min(EVAL_RUN_DEADLINE_MIN_MS).max(EVAL_RUN_DEADLINE_MAX_MS).optional(),\n}).passthrough();\n\nexport const createSessionBody = z.object({\n session: z.object({\n session_config: sessionConfigSchema.optional(),\n }).passthrough(),\n});\n\nexport const getSessionsQuery = z.object({\n hub_id: z.string().uuid(),\n status: z.string().optional(),\n search: z.string().optional(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Results & Runs\n// ---------------------------------------------------------------------------\n\nexport const getSessionResultsQuery = z.object({\n hub_id: z.string().uuid(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n});\n\nexport const getSessionRunsQuery = z.object({\n hub_id: z.string().uuid(),\n eval_id: z.string().uuid().optional(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Analytics\n// ---------------------------------------------------------------------------\n\nexport const evalAnalyticsQuery = z.object({\n hub_id: z.string().uuid(),\n start_date: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n end_date: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n periodicity: z.enum(['daily', 'weekly', 'monthly']).optional(),\n eval_id: z.string().uuid().optional(),\n session_id: z.string().uuid().optional(),\n});\n\nexport const getSessionCostQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Compare sessions\n// ---------------------------------------------------------------------------\n\nexport const compareSessionsQuery = z.object({\n hub_id: z.string().uuid(),\n session_a: z.string().uuid(),\n session_b: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Read-only SQL (CLI agent surface — POST /sql, GET /sql/schema)\n// Scopes the conversation table to `is_eval = true` (mirrors /api/analytics/sql).\n// ---------------------------------------------------------------------------\n\nexport const evalsSqlBody = z.object({\n hub_id: z.string().uuid(),\n // Hard size cap before the validator runs — keeps lex/parse work bounded.\n sql: z.string().min(1).max(8000),\n limit: z.number().int().positive().max(10000).optional(),\n});\n\nexport const evalsSqlSchemaQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Export\n// ---------------------------------------------------------------------------\n\nexport const exportResultsQuery = z.object({\n format: z.enum(['csv', 'json']).default('csv'),\n});\n\n// ---------------------------------------------------------------------------\n// Validate\n// ---------------------------------------------------------------------------\n\nexport const validateEvalBody = z.object({\n eval: z.record(z.unknown()),\n});\n\n// ---------------------------------------------------------------------------\n// Hub Agents\n// ---------------------------------------------------------------------------\n\nexport const hubAgentsQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Scenario sets\n// ---------------------------------------------------------------------------\n\nexport const createScenarioSetBody = z.object({\n hub_id: z.string().uuid(),\n set_name: z.string().min(1).max(200),\n description: z.string().max(1000).optional(),\n enabled: z.boolean().optional(),\n});\n\nexport const updateScenarioSetBody = z.object({\n set_name: z.string().min(1).max(200).optional(),\n description: z.string().max(1000).nullable().optional(),\n enabled: z.boolean().optional(),\n});\n\nexport const scenarioSetsHubQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Production replay — create scenario from a real conversation\n// ---------------------------------------------------------------------------\n\nexport const createScenarioFromConversationBody = z.object({\n hub_id: z.string().uuid(),\n conversation_id: z.string().uuid(),\n scenario_set_id: z.string().uuid(),\n scenario_name: z.string().min(1).max(200),\n evaluator_instructions: z.string().max(4000).optional(),\n});\n\n// Re-export param schemas\nexport { evalIdParam, sessionIdParam, scenarioSetIdParam, hubIdQuery };\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type EvalIdParam = z.infer<typeof evalIdParam>;\nexport type SessionIdParam = z.infer<typeof sessionIdParam>;\nexport type ScenarioSetIdParam = z.infer<typeof scenarioSetIdParam>;\nexport type CreateEvalBody = z.infer<typeof createEvalBody>;\nexport type UpdateEvalBody = z.infer<typeof updateEvalBody>;\nexport type GetEvalsQuery = z.infer<typeof getEvalsQuery>;\nexport type ToggleEvalBody = z.infer<typeof toggleEvalBody>;\nexport type BulkToggleEvalsBody = z.infer<typeof bulkToggleEvalsBody>;\nexport type CreateSessionBody = z.infer<typeof createSessionBody>;\nexport type GetSessionsQuery = z.infer<typeof getSessionsQuery>;\nexport type GetSessionResultsQuery = z.infer<typeof getSessionResultsQuery>;\nexport type GetSessionRunsQuery = z.infer<typeof getSessionRunsQuery>;\nexport type EvalAnalyticsQuery = z.infer<typeof evalAnalyticsQuery>;\nexport type ExportResultsQuery = z.infer<typeof exportResultsQuery>;\nexport type ValidateEvalBody = z.infer<typeof validateEvalBody>;\nexport type HubAgentsQuery = z.infer<typeof hubAgentsQuery>;\nexport type CreateScenarioSetBody = z.infer<typeof createScenarioSetBody>;\nexport type UpdateScenarioSetBody = z.infer<typeof updateScenarioSetBody>;\nexport type ScenarioSetsHubQuery = z.infer<typeof scenarioSetsHubQuery>;\nexport type CompareSessionsQuery = z.infer<typeof compareSessionsQuery>;\nexport type CreateScenarioFromConversationBody = z.infer<typeof createScenarioFromConversationBody>;\nexport type EvalsSqlBody = z.infer<typeof evalsSqlBody>;\nexport type EvalsSqlSchemaQuery = z.infer<typeof evalsSqlSchemaQuery>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n// -- Status types --\n\nexport type EvalStatus = 'enabled' | 'disabled';\nexport type SessionStatus = 'draft' | 'agents_responding' | 'awaiting_review' | 'completed' | 'failed' | 'cancelled';\nexport type RunStatus = 'pending' | 'running' | 'agent_responded' | 'completed' | 'failed';\n\n// -- Tool call structures --\n\nexport interface ToolCallResponse {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n// -- Message structures --\n\nexport interface MessageHistoryItemResponse {\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string | null;\n tool_calls?: ToolCallResponse[];\n tool_call_id?: string;\n}\n\nexport interface ExpectedResponseData {\n role: 'assistant';\n content: string | null;\n tool_calls?: ToolCallResponse[];\n}\n\nexport interface EvalResponseData {\n role: 'assistant';\n content: string;\n /**\n * The tool calls the agent made this turn (name + arguments). Present for\n * tool-call evals so `eval-results --runs` is self-contained — the verdict,\n * the reasoning, AND the actual call — without opening the conversation\n * (gh #2597). Omitted when the agent made no tool calls. Same shape as\n * `ExpectedResponseData.tool_calls` so expected vs. actual can be diffed.\n */\n tool_calls?: ToolCallResponse[];\n metadata?: {\n response_time_ms?: number;\n model_used?: string;\n tokens_used?: number;\n };\n}\n\n// -- Entity response types --\n\n/** Full eval row as returned by the eval table. Scenarios MUST belong to a scenario set. */\nexport interface EvalResponse {\n eval_id: string;\n created_at: string;\n updated_at: string;\n hub_id: string;\n user_id: string;\n responder_agent_id: string;\n eval_name: string;\n scenario_set_id: string;\n evaluator_instructions?: string;\n message_history: MessageHistoryItemResponse[];\n message_text: MessageHistoryItemResponse;\n message_expected_response: ExpectedResponseData;\n number_of_runs: number;\n enabled: boolean;\n created_by: string;\n}\n\n/** Frozen agent configuration captured at session-launch time. */\nexport interface AgentConfigSnapshot {\n agent_id: string;\n agent_name: string | null;\n agent_role: string | null;\n instructions: string | null;\n response_format: string | null;\n schema_name: string | null;\n schema_json: unknown;\n agent_settings: unknown;\n enabled: boolean;\n connection: { connection_id: string | null; connector_id: string | null; model_name: string | null } | null;\n tools: Array<Record<string, unknown>>;\n resources: Array<{ resource_id: string; version?: string | null }>;\n}\n\n/** Frozen scenario content captured per `eval_session_run`. */\nexport interface ScenarioSnapshot {\n message_text: unknown;\n message_expected_response: unknown;\n message_history: unknown;\n evaluator_instructions: string | null;\n}\n\n/** Internal RPC input for `HubDO.completeEvalRun` (not a public route). */\nexport interface CompleteEvalRunInput {\n run_id: string;\n status: 'completed' | 'failed';\n agent_response?: string;\n /** Tool calls the agent made this turn — persisted alongside `agent_response` (gh #2597). */\n agent_tool_calls?: ToolCallResponse[];\n execution_time_ms: number;\n error_message?: string;\n score_dimensions?: Record<string, unknown>;\n response_match?: boolean | null;\n}\n\n/** Eval scenario set row. */\nexport interface ScenarioSetResponse {\n scenario_set_id: string;\n set_name: string;\n description?: string | null;\n enabled: boolean;\n created_by?: string | null;\n created_at: string;\n updated_at?: string;\n}\n\n/** Eval with joined agent data, as returned by list endpoint */\nexport interface EvalWithAgentResponse extends EvalResponse {\n agent?: {\n agent_id: string;\n agent_name: string;\n agent_role: string;\n } | null;\n}\n\n/** Eval session row */\nexport interface EvalSessionResponse {\n eval_session_id: string;\n created_at: string;\n updated_at: string;\n hub_id: string;\n session_name: string;\n session_description?: string;\n session_status: SessionStatus;\n started_at?: string;\n completed_at?: string;\n total_evals: number;\n total_runs: number;\n successful_runs: number;\n failed_runs: number;\n created_by: string;\n /** Optional — sessions created pre-PR2 may not have this. */\n scenario_set_id?: string | null;\n /**\n * Snapshot of the responder agent + scenario_set_id captured at session-launch time.\n * `agent` may be missing on sessions created pre-PR2; consumers must render gracefully.\n */\n session_config?: {\n agent?: AgentConfigSnapshot;\n scenario_set_id?: string;\n pacing?: {\n preset: 'conservative' | 'custom';\n custom_interval_ms?: number;\n };\n };\n}\n\n/** Session result row with optional joined eval */\nexport interface EvalSessionResultResponse {\n eval_session_result_id: string;\n created_at: string;\n updated_at: string;\n eval_session_id: string;\n eval_id: string;\n total_runs: number;\n successful_runs: number;\n failed_runs: number;\n pending_runs: number;\n running_runs: number;\n avg_execution_time_ms?: number;\n min_execution_time_ms?: number;\n max_execution_time_ms?: number;\n aggregated_scores?: Record<string, { avg: number; min: number; max: number }>;\n success_rate: number;\n eval_status: RunStatus;\n started_at?: string;\n completed_at?: string;\n eval?: EvalResponse | null;\n}\n\n/** Individual run result row with optional joined eval */\nexport interface EvalSessionRunResponse {\n eval_session_run_id: string;\n created_at: string;\n updated_at: string;\n eval_session_id: string;\n eval_id: string;\n conversation_id?: string;\n run_number: number;\n eval_response: EvalResponseData;\n response_match: boolean | null;\n response_comment?: string;\n execution_time_ms?: number;\n run_status: RunStatus;\n error_message?: string;\n started_at?: string;\n completed_at?: string;\n scores?: Record<string, number>;\n metadata?: Record<string, unknown>;\n eval?: {\n eval_id: string;\n eval_name: string;\n responder_agent_id: string;\n } | null;\n}\n\n// -- Analytics response types --\n\nexport interface AgentPerformanceResponse {\n agent_id: string;\n agent_name: string;\n success_rate: number;\n total_runs: number;\n avg_execution_time: number;\n}\n\nexport interface TrendDataResponse {\n date: string;\n success_rate: number;\n total_runs: number;\n avg_execution_time: number;\n}\n\nexport interface ScoreDimensionData {\n dimension: string;\n avg_score: number;\n min_score: number;\n max_score: number;\n count: number;\n}\n\nexport interface EvalAnalyticsData {\n totalEvals: number;\n enabledEvals: number;\n totalSessions: number;\n completedSessions: number;\n overallSuccessRate: number;\n avgExecutionTime: number;\n topPerformingAgents: AgentPerformanceResponse[];\n recentTrends: TrendDataResponse[];\n scoreDimensions: ScoreDimensionData[];\n}\n\n// -- Reference types (for dropdowns) --\n\nexport interface EvalAgentReference {\n agent_id: string;\n agent_name: string;\n agent_role: string;\n}\n\nexport interface EvalHubReference {\n hub_id: string;\n hub_name: string;\n hub_description?: string;\n}\n\n// -- Pagination --\n\nexport interface EvalPaginationResponse {\n limit: number;\n offset: number;\n has_more: boolean;\n}\n\n// =============================================================================\n// ENDPOINT RESPONSE WRAPPERS\n// =============================================================================\n\nexport interface GetEvalsResponse {\n success: true;\n data: {\n evals: EvalWithAgentResponse[];\n total_count: number;\n pagination?: EvalPaginationResponse;\n };\n}\n\nexport interface CreateEvalResponse {\n success: true;\n data: { eval: EvalResponse };\n message: string;\n}\n\nexport interface UpdateEvalResponse {\n success: true;\n data: { eval: EvalResponse };\n message: string;\n}\n\nexport interface DeleteEvalResponse {\n success: true;\n message: string;\n}\n\nexport interface DeleteEvalErrorResponse {\n success: false;\n error: 'not_found';\n message: string;\n}\n\nexport interface ToggleEvalResponse {\n success: true;\n data: { eval: EvalResponse };\n message: string;\n}\n\nexport interface BulkToggleEvalsResponse {\n success: true;\n data: {\n updated_count: number;\n updated_eval_ids: string[];\n };\n message: string;\n}\n\nexport interface GetSessionsResponse {\n success: true;\n data: {\n sessions: EvalSessionResponse[];\n total_count: number;\n pagination?: EvalPaginationResponse;\n };\n}\n\nexport interface CreateSessionResponse {\n success: true;\n data: { session: EvalSessionResponse };\n message: string;\n}\n\nexport interface RunSessionResponse {\n success: true;\n data: { session: EvalSessionResponse };\n message: string;\n}\n\nexport interface StopSessionResponse {\n success: true;\n data: { session: EvalSessionResponse };\n message: string;\n}\n\nexport interface DeleteSessionResponse {\n success: true;\n message: string;\n}\n\nexport interface GetSessionDetailsResponse {\n success: true;\n data: {\n session: EvalSessionResponse;\n results: EvalSessionResultResponse[];\n };\n}\n\nexport interface GetSessionResultsResponse {\n success: true;\n data: {\n results: EvalSessionResultResponse[];\n total_count: number;\n pagination?: EvalPaginationResponse;\n };\n}\n\nexport interface GetSessionRunsResponse {\n success: true;\n data: {\n runs: EvalSessionRunResponse[];\n total_count: number;\n session_id: string;\n pagination?: EvalPaginationResponse;\n };\n}\n\n/** Per-session resource cost — sums tokens and billable operations over the\n * unified `conversation` table where `is_eval = true AND eval_session_id = ?`.\n * `billable_operations_total` matches the OrgDO billing increment.\n * `cold` indicates ClickHouse cold-start; on cold, all numeric fields fall back to 0\n * and the client may retry. */\nexport interface EvalSessionCost {\n conversations_count: number;\n tokens_total: number;\n tokens_input: number;\n tokens_output: number;\n billable_operations_total: number;\n}\n\nexport interface GetEvalSessionCostResponse {\n success: true;\n data: {\n cost: EvalSessionCost;\n cold?: true;\n };\n}\n\nexport interface GetEvalAnalyticsResponse {\n success: true;\n data: {\n analytics: EvalAnalyticsData;\n };\n}\n\nexport interface ExportSessionResultsResponse {\n success: true;\n data: {\n download_url: string;\n filename: string;\n format: string;\n };\n message: string;\n}\n\nexport interface ValidateEvalResponse {\n success: true;\n data: {\n is_valid: boolean;\n validation_errors: string[];\n suggestions?: string[];\n };\n}\n\nexport interface GetHubAgentsResponse {\n success: true;\n data: {\n agents: EvalAgentReference[];\n };\n}\n\nexport interface GetHubsListResponse {\n success: true;\n data: {\n hubs: EvalHubReference[];\n };\n}\n\n// -- Scenario set wrappers --\n\nexport interface GetScenarioSetsResponse {\n success: true;\n data: {\n scenario_sets: ScenarioSetResponse[];\n total_count: number;\n };\n}\n\nexport interface GetScenarioSetResponse {\n success: true;\n data: { scenario_set: ScenarioSetResponse };\n}\n\nexport interface CreateScenarioSetResponse {\n success: true;\n data: { scenario_set: ScenarioSetResponse };\n message: string;\n}\n\nexport interface UpdateScenarioSetResponse {\n success: true;\n data: { scenario_set: ScenarioSetResponse };\n message: string;\n}\n\nexport interface DeleteScenarioSetResponse {\n success: true;\n message: string;\n}\n\nexport interface DeleteScenarioSetConflictResponse {\n success: false;\n error: 'scenario_set_not_empty';\n scenario_count: number;\n message: string;\n}\n\nexport interface ListScenariosBySetResponse {\n success: true;\n data: {\n scenarios: EvalResponse[];\n total_count: number;\n };\n}\n\n// -- Compare sessions --\n\n/** Per-scenario stats for a single session in a comparison. */\nexport interface CompareScenarioStats {\n total_runs: number;\n success_rate: number;\n avg_execution_time_ms: number;\n /** Per-dimension averages from `data.eval_scores.*` (excludes meta dimensions). */\n score_dimensions: Record<string, number>;\n}\n\n/** Aggregate session-level summary for the compare summary bar. */\nexport interface CompareSessionSummary {\n eval_session_id: string;\n session_name: string;\n scenario_set_id: string | null;\n scenario_set_name: string | null;\n agent: AgentConfigSnapshot | null;\n total_runs: number;\n success_rate: number;\n avg_execution_time_ms: number;\n tokens_total: number;\n billable_operations_total: number;\n}\n\n/** Per-scenario row in the diff table — only scenarios present in BOTH sessions. */\nexport interface CompareScenarioRow {\n eval_id: string;\n scenario_name: string;\n a: CompareScenarioStats;\n b: CompareScenarioStats;\n /** `b.success_rate - a.success_rate` (signed delta). */\n delta_success_rate: number;\n}\n\nexport interface CompareSessionsResponse {\n success: true;\n data: {\n session_a: CompareSessionSummary;\n session_b: CompareSessionSummary;\n per_scenario: CompareScenarioRow[];\n /** True when session A and B targeted different scenario sets — UI shows a warning. */\n scenario_sets_match: boolean;\n /** `cold` flags ClickHouse cold-start; numeric fields fall back to zeros and the client may retry. */\n cold?: true;\n };\n}\n\n// -- Production replay (create scenario from conversation) --\n\nexport interface CreateScenarioFromConversationResponse {\n success: true;\n data: { eval: EvalResponse };\n message: string;\n}\n\n// -- Read-only SQL (CLI agent surface) --\n\nexport interface EvalsSqlResponse {\n success: true;\n data: Record<string, unknown>[];\n statistics?: {\n elapsed: number;\n rows_read: number;\n bytes_read: number;\n };\n cold?: boolean;\n}\n\nexport interface EvalsSqlSchemaPath {\n path: string;\n type: 'numeric' | 'categorical' | 'text' | 'unknown';\n origin: 'system' | 'eval_scores';\n category?: string;\n description?: string;\n}\n\nexport interface EvalsSqlSchemaResponse {\n success: true;\n data: {\n table: 'conversation';\n top_level: Array<{ column: string; type: string }>;\n paths: EvalsSqlSchemaPath[];\n };\n}\n","/**\n * Eval session run pacing — controls how aggressively `scheduleEvalRuns`\n * stages evaluation runs. Default `conservative` leaves headroom for\n * production traffic on shared LLM API keys (provider rate limits are\n * org-scoped, not key-scoped, so the same key serving prod conversations\n * shares a budget with eval traffic).\n */\n\nexport const EVAL_PACING_PRESETS = {\n conservative: { base_delay_ms: 5000, run_interval_ms: 3000 },\n} as const;\n\nexport type EvalPacingPreset = 'conservative' | 'custom';\n\nexport const DEFAULT_PACING_PRESET: EvalPacingPreset = 'conservative';\n\nexport const PACING_INTERVAL_MIN_MS = 50;\nexport const PACING_INTERVAL_MAX_MS = 60000;\n\n/**\n * Hard ceiling on the total runs a single eval session may materialize\n * (Σ `number_of_runs` over a set's enabled scenarios). Per-scenario runs are\n * capped at 100 (create/update eval), but the scenario *count* is unbounded —\n * so without this a large set can materialize a session bigger than one\n * dispatch invocation can deliver. `scheduleEvalRuns` fans out from a single\n * Worker invocation making 2 ConversationDO RPCs per run; 1000 runs ≈ 2000\n * subrequests, comfortably under the 10k/invocation default with ~5× headroom,\n * and keeps the HubDO watchdog's never-started deadline (`total_runs × pacing\n * + grace + run_deadline`) bounded. Enforced server-side at session run\n * (reject, never clamp — silent truncation would misreport coverage).\n */\nexport const EVAL_MAX_SESSION_RUNS = 1000;\n\n/**\n * Per-run finalization deadline for the HubDO eval watchdog (gh #2591). A run\n * idle past this window (`now - eval_session_run.updated_at`) is reaped to\n * `failed`. The lease clock measures INACTIVITY, not total turn duration: it's\n * renewed at turn start, on each tool call within the agentic loop, and on every\n * rate-limit retry reschedule — so a legitimately long multi-step turn (many\n * LLM/tool calls) or a retrying run is never falsely reaped; only a genuinely\n * stalled turn (no progress — a tool/LLM call that never returns, a DO reset\n * mid-turn) trips it. The lease is renewed before AND after each tool call, so\n * the gap between two renewals is a single in-flight operation: one LLM round\n * (bounded at the 120s stream timeout) or one tool call. The default sits above\n * that 120s ceiling so a normal LLM round always clears. The residual is a\n * single tool call that itself exceeds the deadline — external tool fetches\n * currently have no execution timeout — which would reap a still-running turn;\n * the generous default + per-session `session_config.run_deadline_ms` override\n * are the mitigation until tool fetches are bounded.\n */\nexport const EVAL_DEFAULT_RUN_DEADLINE_MS = 180_000;\n\n/**\n * Buffer added on top of the computed pacing-dispatch span when deciding a run\n * that never started (`started_at IS NULL`) is overdue. The never-started\n * deadline is `session.started_at + dispatchSpan + grace + run_deadline`, where\n * `dispatchSpan` is derived from `total_runs × pacing` — so a legitimately\n * not-yet-dispatched paced run is never reaped. (A future per-run `dispatched_at`\n * makes this per-run-precise; this session-level estimate is correct meanwhile.)\n */\nexport const EVAL_SESSION_DISPATCH_GRACE_MS = 60_000;\n\n/** Clamp bounds for a session-configured `run_deadline_ms`. */\nexport const EVAL_RUN_DEADLINE_MIN_MS = 1_000;\nexport const EVAL_RUN_DEADLINE_MAX_MS = 1_800_000; // 30 min\n\nexport interface PacingConfig {\n preset: EvalPacingPreset;\n custom_interval_ms?: number;\n}\n\nexport interface ResolvedPacing {\n base_delay_ms: number;\n run_interval_ms: number;\n}\n\nexport function resolvePacing(config: PacingConfig | null | undefined): ResolvedPacing {\n if (!config || config.preset === 'conservative') {\n return EVAL_PACING_PRESETS.conservative;\n }\n if (config.preset === 'custom') {\n const raw = typeof config.custom_interval_ms === 'number' ? config.custom_interval_ms : EVAL_PACING_PRESETS.conservative.run_interval_ms;\n const clamped = Math.min(PACING_INTERVAL_MAX_MS, Math.max(PACING_INTERVAL_MIN_MS, Math.floor(raw)));\n return { base_delay_ms: EVAL_PACING_PRESETS.conservative.base_delay_ms, run_interval_ms: clamped };\n }\n return EVAL_PACING_PRESETS.conservative;\n}\n","import { z } from 'zod';\nimport type { AiMode } from '../constants';\nimport type { StateResponse } from './setup/states';\n\n// ---------------------------------------------------------------------------\n// Chat Conversations\n// ---------------------------------------------------------------------------\n\n// 'chat_task' is an internal combined-fetch value — /chat and /task share a\n// single cache keyed on this; the response carries both hub_type values and\n// the frontend filters client-side. Keeping it in the enum keeps typed\n// clients (Hono RPC, MCP, CLI) aware of the shape.\nexport const getConversationsQuery = z.object({\n nav_item: z.enum(['chat', 'task', 'support', 'chat_task']),\n hub_team_user_id: z.string().optional(),\n hub_user_id: z.string().optional(),\n search_filter: z.string().optional(),\n hub_id: z.string().uuid().optional(),\n conversation_id: z.string().uuid().optional(),\n // 'ended' = recently-closed, served warm from the HubDO index (≤ retention\n // window). 'archived' = the full closed-conversation history from ClickHouse.\n status: z.enum(['active', 'agent', 'team', 'ended', 'archived']).optional(),\n page: z.string().regex(/^\\d+$/).optional(),\n page_size: z.string().regex(/^\\d+$/).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Chat Messages\n// ---------------------------------------------------------------------------\n\nexport const getMessagesQuery = z.object({\n hub_id: z.string().uuid(),\n hub_team_user_id: z.string().optional(),\n hub_user_id: z.string().optional(),\n conversation_id: z.string().uuid().optional(),\n message_id: z.string().uuid().optional(),\n page: z.string().regex(/^\\d+$/).optional(),\n page_size: z.string().regex(/^\\d+$/).optional(),\n /**\n * When true AND the caller has support access (hub admin or hub team member),\n * internal messages (tool calls, tool results) are included in the response.\n * Silently ignored for non-support callers — it's a view preference, not an\n * authorization boundary.\n */\n include_internal: z\n .union([z.literal('true'), z.literal('false'), z.boolean()])\n .optional()\n .transform((v) => v === true || v === 'true'),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type GetConversationsQuery = z.infer<typeof getConversationsQuery>;\nexport type GetMessagesQuery = z.infer<typeof getMessagesQuery>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\n/** Team reference in a conversation */\nexport interface ConversationTeamRef {\n hub_team_id: string;\n team_name: string;\n}\n\n/** Agent reference in a conversation */\nexport interface ConversationAgentRef {\n agent_id: string;\n agent_name: string;\n}\n\n/** Browsable resource reference in a conversation */\nexport interface ConversationBrowsableResource {\n resource_id: string;\n resource_name: string;\n resource_description?: string;\n}\n\n/** Kanban status configuration item */\nexport interface ConversationKanbanStatus {\n slug: string;\n name: string;\n color: string;\n isTerminalStatus?: boolean;\n allowed_next_statuses?: string[];\n [key: string]: unknown;\n}\n\n/** Task hub available in metadata */\nexport interface AvailableTaskHub {\n hub_id: string;\n hub_name: string;\n app_channel_id: string | null;\n hub_environment?: 'preview' | 'production';\n}\n\n// Derived server-side from the viewer's user_id vs the conversation's claimer.\nexport type ClaimStatus = 'unclaimed' | 'claimed_by_this_user' | 'claimed_by_other_user';\n\n/** The nav slice a conversation belongs to for a given viewer. */\nexport type SourceNav = 'chat' | 'task' | 'support';\n\n/** Single conversation item returned by the get_conversations RPC */\nexport interface ConversationItemResponse {\n hub_id: string;\n user_id?: string;\n hub_team_user_id?: string;\n conversation_id: string;\n user_name?: string;\n hub_name?: string;\n hub_type?: 'task' | 'chat';\n hub_description?: string;\n hub_contexts?: string[];\n hub_environment?: 'preview' | 'production';\n is_support_hub?: boolean;\n kanban_statuses?: ConversationKanbanStatus[];\n project_name?: string;\n message_text?: string;\n message_status?: 'pending' | 'sent' | 'delivered' | 'read' | 'failed' | null;\n created_at?: string;\n sender_type?: string;\n receiver_type?: string;\n conversation_status?: string;\n /** Channel type of the last message — may be `app` for a team reply. */\n channel_type?: string;\n /** The conversation's bound customer channel (whatsapp/instagram/...) — distinct from `channel_type`. Feeds the support composer's 24h messaging-window gate. */\n current_channel_type?: string;\n /** Timestamp of the last customer (user) inbound message — feeds the 24h messaging-window gate. */\n last_inbound_at?: string;\n app_channel_id?: string;\n search_text?: string;\n sender_description?: string;\n receiver_description?: string;\n channel_description?: string;\n current_hub_team_id?: string;\n current_agent_id?: string;\n current_team_user_id?: string;\n current_responder_type?: string;\n /** Per-contact channel access: 'approved' | 'pending' | 'blocked'. Drives the support badge + composer gating. */\n access_status?: string;\n available_teams: ConversationTeamRef[];\n available_agents: ConversationAgentRef[];\n unread_message_count?: number;\n claim_status?: ClaimStatus;\n kanban_status?: string;\n ended_at?: string;\n // Set when conversation has been archived to R2. Null when ended_at is set\n // but archival hasn't completed (still in DO buffer). The frontend uses this\n // to decide between the archive endpoint and the active /messages endpoint.\n archived_at?: string | null;\n // Evaluator variables\n user_sentiment?: string;\n goal_achieved?: string;\n conversation_summary?: string;\n browsable_resources?: ConversationBrowsableResource[];\n is_flagged?: boolean;\n flag_source?: FlagSource;\n // Nav slices the row belongs to for this viewer. A conversation can belong to\n // more than one (e.g. a viewer who is both the end user AND a team member of a\n // hub sees it in BOTH the owner nav and /support — the roles are orthogonal).\n // The backend emits the row into each matching slice; per-slice it carries the\n // single-element set for that slice, and the frontend unions them by id.\n source_navs?: SourceNav[];\n}\n\n/** Source of a conversation flag. Set by evaluator or monitor background agents. */\nexport type FlagSource = 'evaluator' | 'monitor' | 'both' | null;\n\n/**\n * Merge an incoming flag source with an existing one.\n * Null/same-source → incoming; different existing source → 'both'.\n * Used by ConversationDO and HubDO to keep flag state consistent when the\n * same conversation is flagged by both evaluator and monitor.\n */\nexport function mergeFlagSource(\n existing: FlagSource,\n incoming: 'evaluator' | 'monitor',\n): Exclude<FlagSource, null> {\n if (existing === null || existing === incoming) return incoming;\n return 'both';\n}\n\n/** Hub metadata included in the conversations response */\nexport interface HubItemResponse {\n hub_id: string;\n hub_name?: string;\n hub_type?: 'chat' | 'task';\n hub_description?: string;\n hub_environment?: 'preview' | 'production';\n is_support_hub?: boolean;\n /** Routing/responder policy. Drives UI affordances like \"Transfer to Agent\". */\n ai_mode?: AiMode;\n /** Hub's IANA timezone — the lens the UI renders message timestamps in. */\n timezone?: string;\n /** Hub language (en|pt|es) — localizes the pending-access notice + backend-sent text. */\n language?: string;\n /** Who may approve/block pending contacts: 'admin' (default) or 'team'. Drives the approve/block UI gating. */\n access_approval_role?: 'admin' | 'team';\n /** Per-hub override for the pending-access notice text (null ⇒ localized default). */\n access_request_message?: string;\n app_channel_id?: string;\n kanban_statuses?: Array<{ slug: string; name: string; color: string; allowed_next_statuses?: string[]; isTerminalStatus?: boolean }>;\n available_teams: Array<{ hub_team_id: string; team_name: string }>;\n available_agents?: Array<{ agent_id: string; agent_name: string }>;\n /**\n * Whether the snapshot's user is an enabled hub admin on this hub. Drives\n * admin-only UI affordances (e.g. destructive deletes). Backend remains the\n * authoritative gate — this is a UI-visibility hint, not an auth decision.\n */\n is_current_user_admin?: boolean;\n // Pre-seeds Settings → States tab so it renders without a network round-trip.\n // Optional: omitted by older Worker versions; new clients fall back to a fetch.\n states?: StateResponse[];\n}\n\n/** RPC response from get_conversations (returned as JSON from the RPC) */\nexport interface GetConversationsRpcResponse {\n conversations: ConversationItemResponse[];\n hubs?: HubItemResponse[];\n metadata: {\n available_task_hubs?: AvailableTaskHub[];\n /** Pagination fields (present when status=ended) */\n total?: number;\n page?: number;\n page_size?: number;\n };\n /**\n * True when ClickHouse was cold and the response is a provisional empty\n * result — the client should keep polling until this flag disappears.\n */\n cold?: boolean;\n}\n\n/** File attachment in a message */\nexport interface MessageFileResponse {\n file_id?: string;\n bucket?: string;\n mime_type: string;\n file_name: string;\n file_short_name?: string;\n mime_category?: string;\n file_path: string;\n file_signed_url?: string;\n file_type?: string;\n file_size?: number;\n}\n\n/**\n * Diagnostic codes surfaced when AI message processing fails due to hub\n * misconfiguration. Each code has i18n copy (title + action) rendered in the\n * support view to guide the admin to a fix. `internal_error` is the\n * unknown-failure fallback and is the only code that logs at `error` level and\n * reaches Sentry.\n */\nexport type DiagnosticCode =\n | 'missing_pilot_connection'\n | 'hub_config_not_found'\n | 'credential_resolution_failed'\n | 'missing_api_key'\n | 'llm_provider_rejected'\n | 'rate_limit_exhausted'\n | 'internal_error';\n\nexport const DIAGNOSTIC_CODES: readonly DiagnosticCode[] = [\n 'missing_pilot_connection',\n 'hub_config_not_found',\n 'credential_resolution_failed',\n 'missing_api_key',\n 'llm_provider_rejected',\n 'rate_limit_exhausted',\n 'internal_error',\n] as const;\n\n/** Metadata shape for support-only error diagnostic messages (sender=system, receiver=team). */\nexport interface MessageErrorMetadata {\n is_error: true;\n error_code: DiagnosticCode;\n args?: Record<string, string>;\n}\n\n/** Single message item returned by the get_messages RPC */\nexport interface MessageItemResponse {\n message_key: string;\n message_id: string;\n conversation_id: string;\n message_text: string;\n message_status?: 'pending' | 'sent' | 'delivered' | 'read' | 'failed' | null;\n sender_type: string;\n receiver_type: string;\n created_at: string;\n conversation_created_at?: string;\n hub_type?: string;\n channel_type?: string;\n channel_id?: string;\n is_last_message?: boolean;\n files: MessageFileResponse[];\n sender_description?: string;\n receiver_description?: string;\n channel_description?: string;\n conversation_start?: boolean;\n metadata?: Record<string, unknown> | null;\n}\n\n// ---------------------------------------------------------------------------\n// ConversationDO composite read: ChatView\n// ---------------------------------------------------------------------------\n\n/**\n * Raw file row as stored in ConversationDO's `conversation_file` table,\n * returned attached to the owning message inside `ChatView.messages`.\n * Shape mirrors the SQLite row so the route layer can map it to\n * `MessageFileResponse` without additional DO round-trips.\n */\nexport interface ChatViewFile {\n file_id: string;\n message_id: string;\n /** Only populated by `getFiles` (archival read); omitted when the row is\n * joined onto a message in `getMessages` / `getChatView` to keep payloads small. */\n conversation_id?: string | null;\n file_name: string | null;\n file_path: string | null;\n bucket: string | null;\n mime_type: string | null;\n file_size: number | null;\n created_at: string | null;\n}\n\n/**\n * Raw message row plus any files joined by `message_id`.\n * `files` is always populated — an empty array when the message has no\n * attachments. This removes the `files=[]` fallback at route level because\n * the DO now joins the two tables in a single SQL transaction.\n */\nexport interface ChatViewMessage {\n message_id: string;\n conversation_id: string | null;\n message_text: string | null;\n message_type: string | null;\n sender_type: string | null;\n sender_id: string | null;\n sender_name: string | null;\n receiver_type: string | null;\n receiver_id: string | null;\n channel_type: string | null;\n channel_message_sid: string | null;\n keep_in_history: number | boolean | null;\n agent_id: string | null;\n agent_role: string | null;\n message_status: string | null;\n metadata: string | Record<string, unknown> | null;\n created_at: string;\n files: ChatViewFile[];\n}\n\n/**\n * Minimal conversation metadata returned by `getChatView`.\n * Only the fields used by the chat route to render the header / gate hub\n * ownership are returned — keeps the RPC payload small while still\n * eliminating a second DO round-trip per chat load.\n */\nexport interface ChatViewConversation {\n conversation_id: string;\n hub_id: string | null;\n user_id: string | null;\n status: string | null;\n current_responder_type: string | null;\n current_agent_id: string | null;\n current_channel_id: string | null;\n current_channel_type: string | null;\n kanban_status: string | null;\n created_at: string | null;\n updated_at: string | null;\n hub_type: string | null;\n // current_team_user_id is a platform user_id, not a hub_team_user_id.\n current_hub_team_id: string | null;\n current_team_user_id: string | null;\n}\n\n/**\n * Composite read response returned by `ConversationDO.getChatView`.\n * Combines messages (with joined files) and conversation metadata in a\n * single DO round-trip, replacing the legacy 2-fetch pattern\n * (v2GetMessages + v2GetConversation).\n */\nexport interface ChatView {\n conversation: ChatViewConversation | null;\n messages: ChatViewMessage[];\n total: number;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Update User\n// ---------------------------------------------------------------------------\n\nexport const updateUserBody = z.object({\n user_language: z.string().optional(),\n ui_dark_mode: z.boolean().optional(),\n profile_name: z.string().optional(),\n link_email_to_identities: z.boolean().optional(),\n}).refine(\n (data) => Object.values(data).some((v) => v !== undefined),\n { message: 'At least one field must be provided' },\n);\n\n// ---------------------------------------------------------------------------\n// Update Profile\n// ---------------------------------------------------------------------------\n\nexport const updateProfileBody = z.object({\n display_name: z.string().optional(),\n avatar_url: z.string().optional(),\n preferences: z.record(z.unknown()).optional(),\n}).refine(\n (data) => Object.values(data).some((v) => v !== undefined),\n { message: 'At least one field must be provided' },\n);\n\n// ---------------------------------------------------------------------------\n// Update Preferences (PATCH /users/preferences)\n// ---------------------------------------------------------------------------\n\n// Pathnames only. Leading `/` required; `(?!\\/)` rejects `//evil.com` scheme-relative URLs.\nconst pathnameRegex = /^\\/(?!\\/)[A-Za-z0-9\\-._~!$&'()*+,;=:@/?%]*$/;\n\nexport const updatePreferencesBody = z.object({\n last_viewed_nav: z.string().regex(pathnameRegex, 'Must be a URL pathname').max(2048).optional(),\n dismissed_agentic_shortcut: z.boolean().optional(),\n}).passthrough();\n\nexport type UpdatePreferencesBody = z.infer<typeof updatePreferencesBody>;\n\n// ---------------------------------------------------------------------------\n// Activity\n// ---------------------------------------------------------------------------\n\nexport const activityQuery = z.object({\n limit: z.coerce.number().int().min(1).max(100).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Account Deletion\n// ---------------------------------------------------------------------------\n\n/** Two modes — Scheduled (30-day grace, undoable) or Immediate (no undo). */\nexport const deletionModeSchema = z.enum(['scheduled', 'immediate']);\n\nexport const deletionRequestBody = z.object({\n mode: deletionModeSchema,\n /** User-supplied reason captured in the audit log; bounded to bound logged PII. */\n reason: z.string().max(500).optional(),\n /** Type-to-confirm value; must equal the user's email (constant-time compared). */\n email_confirmation: z.string().min(1).max(320),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type UpdateUserBody = z.infer<typeof updateUserBody>;\nexport type UpdateProfileBody = z.infer<typeof updateProfileBody>;\nexport type ActivityQuery = z.infer<typeof activityQuery>;\nexport type DeletionMode = z.infer<typeof deletionModeSchema>;\nexport type DeletionRequestBody = z.infer<typeof deletionRequestBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\n/** Navigation hints — which dashboard sections the user has hub access for */\nexport interface NavHints {\n has_chat: boolean;\n has_task: boolean;\n has_support: boolean;\n}\n\n/** Account deletion lifecycle as seen by the user-facing API. */\nexport type DeletionStatus = 'none' | 'grace' | 'purging' | 'purged';\n\n/** User data returned by GET/PATCH /users/me */\nexport interface UserDataResponse {\n user_id: string;\n user_language: string | null;\n ui_dark_mode: boolean | null;\n profile_name: string | null;\n link_email_to_identities: boolean | null;\n is_platform_admin: boolean;\n created_at: string;\n user_name: string | null;\n account_age_hours: number;\n team_ids: string[];\n nav_hints: NavHints;\n dismissed_agentic_shortcut: boolean;\n /** Active deletion lifecycle; `'none'` for the common case. */\n deletion_status: DeletionStatus;\n /** ISO-8601 timestamp when the cron will purge; null unless status='grace'. */\n deletion_scheduled_purge_at: string | null;\n}\n\n/** GET /users/me or PATCH /users/me */\nexport interface GetUserResponse {\n success: true;\n data: UserDataResponse;\n}\n\n/** Profile data returned by GET/PATCH /users/profile */\nexport interface ProfileDataResponse {\n user_id: string;\n display_name: string | null;\n email: string | null;\n avatar_url: string | null;\n preferences: Record<string, unknown> | null;\n created_at: string;\n updated_at: string | null;\n}\n\n/** GET /users/profile or PATCH /users/profile */\nexport interface GetProfileResponse {\n data: ProfileDataResponse;\n}\n\nexport interface UserPreferences {\n last_viewed_nav?: string;\n dismissed_agentic_shortcut?: boolean;\n [key: string]: unknown;\n}\n\n/** GET /users/preferences */\nexport interface GetPreferencesResponse {\n data: UserPreferences;\n}\n\n/** PATCH /users/preferences */\nexport interface UpdatePreferencesResponse {\n data: UserPreferences;\n}\n\n/** Activity log item */\nexport interface ActivityLogItem {\n activity_id: string;\n action: string;\n entity_type: string;\n entity_id: string;\n metadata: Record<string, unknown> | null;\n created_at: string;\n}\n\n/** GET /users/activity */\nexport interface GetActivityResponse {\n data: ActivityLogItem[];\n}\n\n// ---------------------------------------------------------------------------\n// Account Deletion — responses\n// ---------------------------------------------------------------------------\n\n/** Why the deletion preflight blocks the user from proceeding. */\nexport type DeletionBlocker =\n | {\n type: 'org_owner';\n org_id: string;\n org_name: string;\n has_active_subscription: boolean;\n }\n | {\n type: 'sole_admin';\n org_id: string;\n org_name: string;\n has_active_subscription: boolean;\n };\n\nexport interface DeletionSimpleRemoval {\n org_id: string;\n org_name: string;\n}\n\nexport interface DeletionHubGrant {\n hub_id: string;\n hub_name: string | null;\n role: 'admin' | 'user' | 'team_user';\n}\n\n/** GET /api/users/me/deletion/preflight */\nexport interface DeletionPreflightResponse {\n blocking: DeletionBlocker[];\n /** Orgs where the user is one admin among several — losing the user is a simple grant removal. */\n simple_removals: DeletionSimpleRemoval[];\n /** Hub-level grants without an associated admin role on the parent org. */\n hub_only_grants: DeletionHubGrant[];\n identity_count: number;\n conversation_count_estimate: number;\n}\n\n/** POST /api/users/me/deletion — accepted; describes the resulting state. */\nexport interface DeletionRequestResponse {\n status: Extract<DeletionStatus, 'grace' | 'purging'>;\n scheduled_purge_at: string | null;\n}\n\n/** DELETE /api/users/me/deletion — undo response. */\nexport interface DeletionAbortResponse {\n status: 'none';\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Archive Conversations\n// ---------------------------------------------------------------------------\n\nexport const archiveHubIdParam = z.object({\n hubId: z.string().uuid(),\n});\n\nexport const archiveConversationParams = z.object({\n hubId: z.string().uuid(),\n conversationId: z.string().uuid(),\n});\n\nexport const archiveListQuery = z.object({\n user_id: z.string().optional(),\n start: z.string().optional(),\n end: z.string().optional(),\n page: z.string().regex(/^\\d+$/).optional(),\n page_size: z.string().regex(/^\\d+$/).optional(),\n});\n\nexport const archiveMessageObservabilityParams = archiveConversationParams.extend({\n messageId: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type ArchiveHubIdParam = z.infer<typeof archiveHubIdParam>;\nexport type ArchiveConversationParams = z.infer<typeof archiveConversationParams>;\nexport type ArchiveListQuery = z.infer<typeof archiveListQuery>;\nexport type ArchiveMessageObservabilityParams = z.infer<typeof archiveMessageObservabilityParams>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface ArchivedConversationItem {\n conversation_id: string;\n user_id: string;\n hub_type: string;\n subject: string;\n conversation_status: string;\n kanban_status: string | null;\n created_at: string;\n ended_at: string | null;\n archived_at: string | null;\n message_count: number;\n}\n\n/** GET /:hubId/conversations */\nexport interface ArchiveListResponse {\n conversations: ArchivedConversationItem[];\n total: number;\n page: number;\n page_size: number;\n}\n\n/**\n * GET /:hubId/conversations/:conversationId\n *\n * The detail payload is an opaque JSON blob written by the archive job.\n * We type it as `Record<string, unknown>` since the shape is not\n * constrained at the API contract level.\n */\nexport type ArchiveDetailResponse = Record<string, unknown>;\n","import { z } from 'zod';\nimport { SAFE_USER_ID_REGEX } from '../constants';\nimport type { FlagSource } from './chat';\n\n// ---------------------------------------------------------------------------\n// Common param\n// ---------------------------------------------------------------------------\n\nexport const conversationIdParam = z.object({\n id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Claim\n// ---------------------------------------------------------------------------\n\nexport const claimBody = z.object({\n hub_id: z.string().uuid(),\n new_team_id: z.string().uuid(),\n new_status: z.string().default('team'),\n new_hub_team_user_id: z.string().optional(),\n new_responder_type: z.string().default('team'),\n previous_status: z.string().optional(),\n previous_responder_type: z.string().optional(),\n previous_agent_id: z.string().uuid().optional(),\n previous_team_id: z.string().uuid().optional(),\n previous_hub_team_user_id: z.string().optional(),\n channel_id: z.string().uuid().optional(),\n hub_type: z.enum(['chat', 'task']).default('chat'),\n // SAFE_USER_ID_REGEX bounds alphabet+length (1–64 of [A-Za-z0-9_-]) so\n // SQL/path/scope-key injection vectors can't reach downstream consumers.\n // Matches `deleteUserConversationsBody.user_id` below.\n user_id: z.string().regex(SAFE_USER_ID_REGEX).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Release\n// ---------------------------------------------------------------------------\n\nexport const releaseBody = z.object({\n hub_id: z.string().uuid(),\n new_status: z.string().optional(),\n new_hub_team_user_id: z.string().optional(),\n new_team_id: z.string().uuid().optional(),\n new_responder_type: z.string().optional(),\n previous_status: z.string().optional(),\n previous_responder_type: z.string().optional(),\n previous_agent_id: z.string().uuid().optional(),\n previous_team_id: z.string().uuid().optional(),\n previous_hub_team_user_id: z.string().optional(),\n channel_id: z.string().uuid().optional(),\n hub_type: z.enum(['chat', 'task']).default('chat'),\n user_id: z.string().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Transfer\n// ---------------------------------------------------------------------------\n\nexport const transferBody = z.object({\n hub_id: z.string().uuid(),\n new_status: z.string().optional(),\n new_responder_type: z.string().optional(),\n new_agent_id: z.string().uuid().optional(),\n new_team_id: z.string().uuid().optional(),\n new_hub_team_user_id: z.string().optional(),\n previous_status: z.string().optional(),\n previous_responder_type: z.string().optional(),\n previous_agent_id: z.string().uuid().optional(),\n previous_team_id: z.string().uuid().optional(),\n previous_hub_team_user_id: z.string().optional(),\n channel_id: z.string().uuid().optional(),\n hub_type: z.enum(['chat', 'task']).default('chat'),\n user_id: z.string().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Close\n// ---------------------------------------------------------------------------\n\nexport const closeBody = z.object({\n hub_id: z.string().uuid(),\n previous_status: z.string().optional(),\n previous_responder_type: z.string().optional(),\n previous_agent_id: z.string().uuid().optional(),\n previous_team_id: z.string().uuid().optional(),\n previous_hub_team_user_id: z.string().optional(),\n channel_id: z.string().uuid().optional(),\n hub_type: z.enum(['chat', 'task']).default('chat'),\n user_id: z.string().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Kanban Update\n// ---------------------------------------------------------------------------\n\n/**\n * Wire payload for `kanbanUpdateBody.additional_context` and the equivalent\n * MCP `update_kanban_status` tool input. Server-side validates the payload\n * shape against the target kanban status's `additional_context_schema`\n * (a JSON Schema). Bounded to 16 KB JSON-serialized — mirrors the same cap\n * on the schema field itself in `setup/kanban.ts`.\n *\n * Single source of truth for the `additional_context` shape: consumed by\n * `kanbanUpdateBody` below (the REST `PATCH /:id/kanban` contract). Exported\n * so any client constructing the same payload validates against one schema.\n */\nexport const additionalContextPayloadSchema = z\n .record(z.unknown())\n .refine((r) => JSON.stringify(r).length <= 16384, {\n message: 'additional_context payload must be at most 16384 bytes when JSON-serialized',\n });\n\nexport const kanbanUpdateBody = z.object({\n hub_id: z.string().uuid(),\n // 50-char slug cap + headroom; bounds the \"unknown kanban status\" 400 echo.\n new_kanban_status: z.string().max(64),\n previous_kanban_status: z.string().max(64).optional(),\n channel_id: z.string().uuid().optional(),\n hub_type: z.enum(['chat', 'task']).default('chat'),\n user_id: z.string().optional(),\n scheduled_event_date: z.string().optional(),\n additional_context: additionalContextPayloadSchema.optional(),\n event_description: z.string().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Observability\n// ---------------------------------------------------------------------------\n\nexport const observabilityParams = z.object({\n conversationId: z.string().uuid(),\n messageId: z.string().uuid(),\n});\n\n// List variant — same conversationId shape as `observabilityParams`, derived\n// via `.pick` so the field stays in lockstep with the single-message route.\nexport const observabilityListParams = observabilityParams.pick({ conversationId: true });\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type ConversationIdParam = z.infer<typeof conversationIdParam>;\nexport type ClaimBody = z.infer<typeof claimBody>;\nexport type ReleaseBody = z.infer<typeof releaseBody>;\nexport type TransferBody = z.infer<typeof transferBody>;\nexport type CloseBody = z.infer<typeof closeBody>;\nexport type KanbanUpdateBody = z.infer<typeof kanbanUpdateBody>;\nexport type ObservabilityParams = z.infer<typeof observabilityParams>;\nexport type ObservabilityListParams = z.infer<typeof observabilityListParams>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\n/** Result of a conversation operation (claim, release, transfer, close) */\nexport interface ConversationOperationResponse {\n success: true;\n operation_id: string;\n operation_type: 'claim' | 'release' | 'transfer' | 'close';\n conversation_id: string;\n}\n\n/** Result of a kanban status update operation */\nexport interface KanbanUpdateResponse {\n success: true;\n operation_id: string;\n operation_type: 'update_kanban_status';\n conversation_id: string;\n kanban_status_updated_at?: string;\n /** Set when the new kanban_status is terminal and the conversation auto-closed. */\n closed?: boolean;\n}\n\n/** Result of a conversation reopen operation */\nexport interface ReopenConversationResponse {\n data: Record<string, unknown>;\n}\n\n/** Observability data for a message */\nexport interface ObservabilityResponse {\n data: import('../observability/types').LLMObservabilityRecord;\n}\n\n/**\n * List of per-message observability summaries for a conversation.\n * Carries metadata.json contents only (timestamp, latency, agent, tool counts)\n * — drill into a specific message for full provider/model/tokens/messages.\n */\nexport interface ObservabilityListResponse {\n data: {\n hub_id: string;\n conversation_id: string;\n entries: import('../observability/types').WayAIMetadataRecord[];\n truncated: boolean;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Delete User Conversations\n//\n// Hub-admin only. `mode='current'` wipes a single conversation; `mode='all'`\n// wipes every conversation for the target user on this hub. Deletion is\n// hub-scoped — same `user_id` on a sibling hub is untouched. Permanent.\n// ---------------------------------------------------------------------------\n\nexport const deleteUserConversationsBody = z.discriminatedUnion('mode', [\n z.object({\n hub_id: z.string().uuid(),\n user_id: z.string().regex(SAFE_USER_ID_REGEX),\n mode: z.literal('all'),\n }),\n z.object({\n hub_id: z.string().uuid(),\n user_id: z.string().regex(SAFE_USER_ID_REGEX),\n mode: z.literal('current'),\n conversation_id: z.string().uuid(),\n }),\n]);\nexport type DeleteUserConversationsBody = z.infer<typeof deleteUserConversationsBody>;\n\nexport interface DeleteUserConversationsResponse {\n success: true;\n deleted_count: number;\n}\n\n// ---------------------------------------------------------------------------\n// Send Message (preview hub testing)\n// ---------------------------------------------------------------------------\n\nexport const sendMessageBody = z.object({\n hub_id: z.string().uuid(),\n message: z.string().min(1).max(50000),\n /** For chat hubs: optional — automatically continues the user's active conversation (or creates one).\n * For task hubs: required to continue an existing conversation. Omit to start a new task conversation. */\n conversation_id: z.string().uuid().optional(),\n});\nexport type SendMessageBody = z.infer<typeof sendMessageBody>;\n\nexport interface SendMessageResponse {\n conversation_id: string;\n hub_type: 'chat' | 'task';\n user_message_id: string;\n agent_reply: {\n message_id: string;\n message_text: string;\n } | null;\n status: 'replied' | 'skipped' | 'error' | 'empty_response';\n status_reason?: string;\n}\n\n// ---------------------------------------------------------------------------\n// List Conversations (admin)\n// ---------------------------------------------------------------------------\n\nexport const listConversationsQuery = z.object({\n hub_id: z.string().uuid(),\n status: z.enum(['agent', 'team', 'ended']).optional(),\n limit: z.coerce.number().int().min(1).max(100).default(20),\n offset: z.coerce.number().int().min(0).default(0),\n});\nexport type ListConversationsQuery = z.infer<typeof listConversationsQuery>;\n\nexport interface GetConversationsResponse {\n conversations: Array<{\n conversation_id: string;\n conversation_status: string;\n current_responder_type: string | null;\n kanban_status: string | null;\n created_at: string;\n updated_at: string | null;\n user_name: string | null;\n user_email: string | null;\n is_flagged: boolean;\n flag_source: FlagSource;\n }>;\n total: number;\n}\n\n// ---------------------------------------------------------------------------\n// Get Conversation Detail (with messages)\n// ---------------------------------------------------------------------------\n\nexport const getConversationDetailParams = z.object({\n id: z.string().uuid(),\n});\nexport type GetConversationDetailParams = z.infer<typeof getConversationDetailParams>;\n\nexport const getConversationDetailQuery = z.object({\n hub_id: z.string().uuid(),\n limit: z.coerce.number().int().min(1).max(200).default(50),\n offset: z.coerce.number().int().min(0).default(0),\n});\nexport type GetConversationDetailQuery = z.infer<typeof getConversationDetailQuery>;\n\nexport interface GetConversationDetailResponse {\n conversation: {\n conversation_id: string;\n conversation_status: string;\n current_responder_type: string | null;\n access_status: string;\n kanban_status: string | null;\n created_at: string;\n updated_at: string | null;\n user_name: string | null;\n user_email: string | null;\n is_flagged: boolean;\n flag_source: FlagSource;\n };\n messages: Array<{\n message_id: string;\n message_text: string | null;\n sender_type: string;\n receiver_type: string | null;\n created_at: string;\n message_type?: string;\n channel_type?: string | null;\n keep_in_history?: boolean;\n agent_id?: string | null;\n sender_id?: string | null;\n receiver_id?: string | null;\n sender_description?: string;\n receiver_description?: string;\n metadata?: Record<string, unknown> | null;\n message_status?: string | null;\n }>;\n total_messages: number;\n}\n\n// ---------------------------------------------------------------------------\n// WhatsApp template picker (closed-window team re-engagement)\n//\n// When a WhatsApp conversation is past Meta's 24h messaging window, a free-form\n// team reply is blocked. An approved WhatsApp template is the only compliant\n// re-engagement path. These contracts back the picker: list the conversation's\n// approved templates, then send one with body variables filled in.\n// ---------------------------------------------------------------------------\n\nexport const listWhatsAppTemplatesQuery = z.object({\n hub_id: z.string().uuid(),\n});\nexport type ListWhatsAppTemplatesQuery = z.infer<typeof listWhatsAppTemplatesQuery>;\n\nexport const sendWhatsAppTemplateBody = z.object({\n hub_id: z.string().uuid(),\n /** HubDO outbound_template.template_id. */\n template_id: z.string().min(1).max(128),\n /** The conversation's end user (customer). Bounded like `claimBody.user_id`. */\n user_receiver_id: z.string().regex(SAFE_USER_ID_REGEX),\n /** Body-variable values: positional array or key→value record. Bounded so an\n * authenticated caller can't post an oversized payload to the transcript. */\n variables: z\n .union([\n z.array(z.string().max(2048)).max(50),\n z\n .record(z.string().max(128), z.string().max(2048))\n .refine((r) => Object.keys(r).length <= 50, 'too many variables'),\n ])\n .optional(),\n});\nexport type SendWhatsAppTemplateBody = z.infer<typeof sendWhatsAppTemplateBody>;\n\n/** One approved WhatsApp template, shaped for the picker UI. */\nexport interface WhatsAppTemplatePickerItem {\n template_id: string;\n display_name: string;\n category: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION';\n language: string;\n /** BODY component text, with `{{N}}` / `{{name}}` placeholders intact. */\n body_text: string;\n parameter_format: 'POSITIONAL' | 'NAMED';\n /** Distinct variable keys in render order — drives the fill-in form. */\n variables: string[];\n}\n\nexport interface ListWhatsAppTemplatesResponse {\n data: WhatsAppTemplatePickerItem[];\n}\n\n/**\n * Send result on success. Failures return a non-2xx with the standard error\n * envelope (`{ error, message }`) whose `error` carries a stable code the\n * picker maps to a message — e.g. `template_not_approved`, `conversation_ended`,\n * `missing_variables`, `meta_rejected:<n>`.\n */\nexport interface SendWhatsAppTemplateResponse {\n data: { message_id: string; channel_message_sid: string | null; rendered_text: string };\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Params\n// ---------------------------------------------------------------------------\n\nexport const billingOrgIdParam = z.object({\n organizationId: z.string().uuid(),\n});\n\nexport const subscriptionItemParams = z.object({\n organizationId: z.string().uuid(),\n itemId: z.string(),\n});\n\n// ---------------------------------------------------------------------------\n// Bodies\n// ---------------------------------------------------------------------------\n\nexport const spendCapBody = z.object({\n enabled: z.boolean(),\n});\n\nexport const growthPacksBody = z.object({\n quantity: z.number().int().min(1).max(100).default(1),\n});\n\nexport const portalSessionBody = z.object({\n return_url: z.string().url().optional(),\n});\n\nexport const checkoutSessionBody = z.object({\n tier: z.enum(['solo', 'team']),\n});\n\nexport const updateBillingCurrencyBody = z.object({\n currency: z.enum(['USD', 'BRL']),\n});\n\n// ---------------------------------------------------------------------------\n// Queries\n// ---------------------------------------------------------------------------\n\nexport const invoicesQuery = z.object({\n limit: z.string().regex(/^\\d+$/).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type BillingOrgIdParam = z.infer<typeof billingOrgIdParam>;\nexport type SubscriptionItemParams = z.infer<typeof subscriptionItemParams>;\nexport type SpendCapBody = z.infer<typeof spendCapBody>;\nexport type GrowthPacksBody = z.infer<typeof growthPacksBody>;\nexport type PortalSessionBody = z.infer<typeof portalSessionBody>;\nexport type CheckoutSessionBody = z.infer<typeof checkoutSessionBody>;\nexport type UpdateBillingCurrencyBody = z.infer<typeof updateBillingCurrencyBody>;\nexport type InvoicesQuery = z.infer<typeof invoicesQuery>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface BillingOrganizationItem {\n organization_id: string;\n organization_name: string;\n billing_currency: string;\n created_at: string;\n organization_admin_user: {\n is_owner: boolean;\n enabled: boolean;\n }[];\n}\n\nexport interface BillingOrganizationsResponse {\n success: true;\n data: BillingOrganizationItem[];\n}\n\nexport interface BillingRecord {\n organization_id: string;\n stripe_customer_id: string | null;\n stripe_subscription_id: string | null;\n plan_type: 'free' | 'paid';\n plan_key: 'free' | 'solo' | 'team';\n plan_kind: 'free' | 'base' | 'addon';\n billing_cycle: 'monthly' | 'annual';\n display_name?: string;\n period_start: string | null;\n period_end: string | null;\n spend_cap_enabled: boolean;\n billing_status: 'active' | 'past_due' | 'cancelled';\n created_at: string;\n updated_at: string;\n}\n\nexport interface BillingMetric {\n billing_metric_id: string;\n organization_id: string;\n metric_type: 'messages' | 'users' | 'storage' | 'api_calls';\n monthly_included: number;\n consumed_subscription: number;\n alert_80_sent: boolean;\n alert_95_sent: boolean;\n alert_100_sent: boolean;\n last_consumed_at: string | null;\n last_reset_at: string | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface BillingMetricsHistory {\n history_id: string;\n organization_id: string;\n period_start: string;\n period_end: string;\n metric_type: 'messages' | 'users' | 'storage' | 'api_calls';\n monthly_included: number;\n consumed_subscription: number;\n created_at: string;\n}\n\nexport interface BillingData {\n billing: BillingRecord;\n metrics: BillingMetric[] | null;\n history: BillingMetricsHistory[] | null;\n is_owner: boolean;\n billing_currency: string;\n}\n\nexport interface GetBillingDataResponse {\n success: true;\n data: BillingData;\n}\n\nexport interface UpdateSpendCapResponse {\n success: true;\n data: { spend_cap_enabled: boolean };\n}\n\nexport interface AddGrowthPackResponse {\n success: true;\n data: {\n subscription_item_id: string;\n quantity: number;\n messages_added: number;\n seats_added: number;\n };\n}\n\nexport interface UpdateBillingCurrencyResponse {\n success: true;\n data: { currency: 'USD' | 'BRL' };\n}\n\nexport interface RemoveSubscriptionItemResponse {\n success: true;\n data: { removed: string };\n}\n\nexport interface PortalSessionResponse {\n success: true;\n data: { url: string };\n}\n\nexport interface Invoice {\n id: string;\n amount: number;\n currency: string;\n status: 'draft' | 'open' | 'paid' | 'uncollectible' | 'void' | null;\n created: number;\n period_start: number;\n period_end: number;\n invoice_pdf: string | null | undefined;\n hosted_invoice_url: string | null | undefined;\n}\n\nexport interface GetInvoicesResponse {\n success: true;\n data: Invoice[];\n}\n\nexport interface CheckoutSessionResponse {\n success: true;\n data: { url: string | null; mode: 'portal' | 'checkout'; session_id?: string };\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Download\n// ---------------------------------------------------------------------------\n\nexport const downloadBody = z.object({\n type: z.enum(['workspace', 'agent_instructions']),\n agent_id: z.string().uuid().optional(),\n organization_name: z.string().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Upload\n// ---------------------------------------------------------------------------\n\nexport const uploadQuery = z.object({\n type: z.enum(['agent_instructions']),\n agent_id: z.string().uuid(),\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Sign URL\n// ---------------------------------------------------------------------------\n\nexport const signUrlBody = z.object({\n bucket: z.string(),\n filePath: z.string(),\n expiresIn: z.number().int().positive().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type DownloadBody = z.infer<typeof downloadBody>;\nexport type UploadQuery = z.infer<typeof uploadQuery>;\nexport type SignUrlBody = z.infer<typeof signUrlBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\n/** Shared base for all download responses */\ninterface DownloadResponseBase {\n success: true;\n download_url: string;\n expires_in: number;\n}\n\n/** POST /download (type=workspace) */\nexport interface DownloadWorkspaceResponse extends DownloadResponseBase {\n summary: {\n organization?: string;\n organizations?: number;\n hubs: number;\n files: number;\n };\n}\n\n/** POST /download (type=agent_instructions) */\nexport interface DownloadAgentInstructionsResponse extends DownloadResponseBase {\n summary: { files: number };\n}\n\n/** Union of all download responses */\nexport type DownloadResponse =\n | DownloadWorkspaceResponse\n | DownloadAgentInstructionsResponse;\n\n/** POST /upload */\nexport interface UploadResponse {\n success: true;\n file_id: string;\n file_path: string;\n}\n\n/** POST /sign */\nexport interface SignUrlResponse {\n signedUrl: string;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Completions\n// ---------------------------------------------------------------------------\n\nexport const completionsBody = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n model: z.string(),\n prompt: z.string(),\n system_prompt: z.string().optional(),\n temperature: z.number().min(0).max(2).default(1),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type CompletionsBody = z.infer<typeof completionsBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\n/** POST / */\nexport interface CompletionsResponse {\n content: string;\n error?: string;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Outbound Schema\n// ---------------------------------------------------------------------------\n\nexport const outboundSchemaQuery = z.object({\n type: z.enum(['whatsapp', 'email', 'app', 'all']).default('all'),\n});\n\n// ---------------------------------------------------------------------------\n// Template Params & Queries\n// ---------------------------------------------------------------------------\n\nexport const templateIdParam = z.object({\n id: z.string().uuid(),\n});\n\nexport const listTemplatesQuery = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n});\n\nexport const deleteTemplateQuery = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n});\n\nexport const templateStatusQuery = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n});\n\nexport const createTemplateBody = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n}).passthrough();\n\nexport const updateTemplateBody = z.object({}).passthrough();\n\nexport const submitTemplateBody = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n}).passthrough();\n\nexport const testTemplateBody = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n}).passthrough();\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type OutboundSchemaQuery = z.infer<typeof outboundSchemaQuery>;\nexport type TemplateIdParam = z.infer<typeof templateIdParam>;\nexport type ListTemplatesQuery = z.infer<typeof listTemplatesQuery>;\nexport type DeleteTemplateQuery = z.infer<typeof deleteTemplateQuery>;\nexport type TemplateStatusQuery = z.infer<typeof templateStatusQuery>;\nexport type CreateTemplateBody = z.infer<typeof createTemplateBody>;\nexport type UpdateTemplateBody = z.infer<typeof updateTemplateBody>;\nexport type SubmitTemplateBody = z.infer<typeof submitTemplateBody>;\nexport type TestTemplateBody = z.infer<typeof testTemplateBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\n/** Connection entry in the outbound schema */\nexport interface OutboundSchemaConnection {\n connection_id: string;\n connector_name: string;\n connection_display_name?: string;\n connector_type: string;\n service_name: string;\n hub_id: string;\n enabled: boolean;\n}\n\n/** Template operation result — returned by all template endpoints */\nexport interface TemplateOperationResult {\n [key: string]: unknown;\n}\n\n/** POST /templates — create template (when a template_id is returned) */\nexport interface CreateTemplateResponse {\n template_id: string;\n}\n\n/** GET /schema */\nexport interface GetOutboundSchemaResponse {\n data: {\n flat: {\n organizations: Array<{\n organization_id: string;\n organization_name: string;\n }>;\n hubsByOrg: Record<string, Array<{\n hub_id: string;\n hub_name: string;\n }>>;\n connectionsByHub: Record<string, OutboundSchemaConnection[]>;\n };\n lastUpdated: string;\n };\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Params & Queries\n// ---------------------------------------------------------------------------\n\nexport const contactIdParam = z.object({\n id: z.string().uuid(),\n});\n\nexport const listContactsQuery = z.object({\n hub_id: z.string().uuid(),\n search: z.string().optional(),\n tags: z.string().optional(), // comma-separated\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(100).default(25),\n});\n\nexport const createContactBody = z.object({\n hub_id: z.string().uuid(),\n contact_name: z.string().min(1),\n phone: z.string().optional(),\n email: z.string().email().optional(),\n instagram_sid: z.string().optional(),\n hub_user_id: z.string().uuid().optional(),\n tags: z.array(z.string()).default([]),\n metadata: z.record(z.unknown()).default({}),\n enabled: z.boolean().default(true),\n}).refine(\n (data) => data.phone || data.email || data.instagram_sid,\n { message: 'At least one channel (phone, email, or instagram_sid) is required' }\n);\n\nexport const updateContactBody = z.object({\n contact_name: z.string().min(1).optional(),\n phone: z.string().nullable().optional(),\n email: z.string().email().nullable().optional(),\n instagram_sid: z.string().nullable().optional(),\n hub_user_id: z.string().uuid().nullable().optional(),\n tags: z.array(z.string()).optional(),\n metadata: z.record(z.unknown()).optional(),\n enabled: z.boolean().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type ContactIdParam = z.infer<typeof contactIdParam>;\nexport type ListContactsQuery = z.infer<typeof listContactsQuery>;\nexport type CreateContactBody = z.infer<typeof createContactBody>;\nexport type UpdateContactBody = z.infer<typeof updateContactBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface OutboundContact {\n contact_id: string;\n hub_id: string;\n hub_user_id: string | null;\n contact_name: string;\n phone: string | null;\n email: string | null;\n instagram_sid: string | null;\n tags: string[];\n metadata: Record<string, unknown>;\n enabled: boolean;\n created_at: string;\n updated_at: string;\n}\n\nexport interface ListContactsResponse {\n contacts: OutboundContact[];\n total: number;\n page: number;\n per_page: number;\n}\n\nexport interface CreateContactResponse {\n contact_id: string;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Params & Queries\n// ---------------------------------------------------------------------------\n\nexport const listIdParam = z.object({\n id: z.string().uuid(),\n});\n\nexport const listListsQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\nexport const listListContactsQuery = z.object({\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(100).default(25),\n});\n\nexport const createListBody = z.object({\n hub_id: z.string().uuid(),\n list_name: z.string().min(1),\n description: z.string().nullable().optional(),\n});\n\nexport const updateListBody = z.object({\n list_name: z.string().min(1).optional(),\n description: z.string().nullable().optional(),\n});\n\nexport const addListContactsBody = z.object({\n contact_ids: z.array(z.string().uuid()).min(1),\n});\n\nexport const removeListContactsBody = z.object({\n contact_ids: z.array(z.string().uuid()).min(1),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type ListIdParam = z.infer<typeof listIdParam>;\nexport type ListListsQuery = z.infer<typeof listListsQuery>;\nexport type ListListContactsQuery = z.infer<typeof listListContactsQuery>;\nexport type CreateListBody = z.infer<typeof createListBody>;\nexport type UpdateListBody = z.infer<typeof updateListBody>;\nexport type AddListContactsBody = z.infer<typeof addListContactsBody>;\nexport type RemoveListContactsBody = z.infer<typeof removeListContactsBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface OutboundList {\n list_id: string;\n hub_id: string;\n list_name: string;\n description: string | null;\n contact_count: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface ListListsResponse {\n lists: OutboundList[];\n}\n\nexport interface CreateListResponse {\n list_id: string;\n}\n\nexport interface ListContactEntry {\n list_contact_id: string;\n contact_id: string;\n contact_name: string;\n phone: string | null;\n email: string | null;\n instagram_sid: string | null;\n enabled: boolean;\n added_at: string;\n}\n\nexport interface ListListContactsResponse {\n contacts: ListContactEntry[];\n total: number;\n page: number;\n per_page: number;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Params & Queries\n// ---------------------------------------------------------------------------\n\nexport const scheduleIdParam = z.object({\n id: z.string().uuid(),\n});\n\nexport const listSchedulesQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\nexport const listExecutionsQuery = z.object({\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(50).default(10),\n});\n\nexport const createScheduleBody = z.object({\n hub_id: z.string().uuid(),\n schedule_name: z.string().min(1),\n description: z.string().nullable().optional(),\n cron_expression: z.string().min(1),\n timezone: z.string().default('UTC'),\n list_id: z.string().uuid(),\n channel_type: z.enum(['whatsapp', 'instagram', 'email', 'app']),\n connection_id: z.string().uuid().nullable().optional(),\n execution_mode: z.enum(['direct_message', 'agent_trigger']).default('direct_message'),\n template_whatsapp_id: z.string().uuid().nullable().optional(),\n initial_message: z.string().nullable().optional(),\n agent_id: z.string().uuid().nullable().optional(),\n trigger_message: z.string().nullable().optional(),\n});\n\nexport const updateScheduleBody = z.object({\n schedule_name: z.string().min(1).optional(),\n description: z.string().nullable().optional(),\n cron_expression: z.string().min(1).optional(),\n timezone: z.string().optional(),\n list_id: z.string().uuid().optional(),\n channel_type: z.enum(['whatsapp', 'instagram', 'email', 'app']).optional(),\n connection_id: z.string().uuid().nullable().optional(),\n execution_mode: z.enum(['direct_message', 'agent_trigger']).optional(),\n template_whatsapp_id: z.string().uuid().nullable().optional(),\n initial_message: z.string().nullable().optional(),\n agent_id: z.string().uuid().nullable().optional(),\n trigger_message: z.string().nullable().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type ScheduleIdParam = z.infer<typeof scheduleIdParam>;\nexport type ListSchedulesQuery = z.infer<typeof listSchedulesQuery>;\nexport type ListExecutionsQuery = z.infer<typeof listExecutionsQuery>;\nexport type CreateScheduleBody = z.infer<typeof createScheduleBody>;\nexport type UpdateScheduleBody = z.infer<typeof updateScheduleBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface OutboundSchedule {\n schedule_id: string;\n hub_id: string;\n schedule_name: string;\n description: string | null;\n enabled: boolean;\n cron_expression: string;\n timezone: string;\n list_id: string;\n channel_type: string;\n connection_id: string | null;\n execution_mode: string;\n template_whatsapp_id: string | null;\n initial_message: string | null;\n agent_id: string | null;\n trigger_message: string | null;\n last_run_at: string | null;\n next_run_at: string | null;\n total_runs: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface ListSchedulesResponse {\n schedules: OutboundSchedule[];\n}\n\nexport interface CreateScheduleResponse {\n schedule_id: string;\n}\n\nexport interface ScheduleExecution {\n execution_id: string;\n schedule_id: string;\n started_at: string;\n completed_at: string | null;\n status: string;\n total_contacts: number;\n succeeded: number;\n failed: number;\n skipped: number;\n}\n\nexport interface ListExecutionsResponse {\n executions: ScheduleExecution[];\n total: number;\n page: number;\n per_page: number;\n}\n","/**\n * Shared CI/GitOps types — contract between backend and CLI.\n *\n * Source of truth: workers/backend/src/routes/api/ci/types.ts\n * The backend may have extra optional fields (e.g. connection_id, target_id)\n * that the CLI ignores — this file carries the full (superset) definitions.\n */\n\nimport { z } from 'zod';\nimport {\n validateToolInputSchema,\n containsKanbanPlaceholders,\n extractToolParameters,\n} from '../tool-schema-validator';\nimport { kanbanStatusesArraySchema } from './setup/kanban';\n\n// =============================================\n// Kanban status types\n// Field names match the existing JSONB schema in the database and frontend\n// (KanbanStatusCard.tsx, FollowupCard.tsx). The mixed casing (camelCase booleans,\n// snake_case strings) is inherited from the original frontend implementation.\n// =============================================\n\nexport interface HubAsCodeKanbanFollowup {\n id?: string;\n order: number;\n type: 'inactivity' | 'before_event';\n threshold: number;\n timeUnit: 'seconds' | 'minutes' | 'hours' | 'days';\n instructions: string;\n excludedWeekDays?: number[];\n excludeHolidays?: boolean;\n excludedTimeStart?: string;\n excludedTimeEnd?: string;\n /** 'agent_generated' (default) feeds `instructions` to the LLM; 'direct' sends `direct_text` verbatim. */\n delivery_mode?: 'agent_generated' | 'direct';\n /** Verbatim user-facing text. Required when `delivery_mode='direct'`. */\n direct_text?: string;\n /** Approved Meta WhatsApp template id; consulted only outside the WA 24h window. */\n template_whatsapp_id?: string | null;\n /** Default `'route_to_team'` when omitted. Only consulted on `direct` mode + windowed channels outside the window. */\n outside_window_policy?: 'route_to_team' | 'skip';\n /** Default true — followup turn includes tool schemas. Set to false to strip them and save tokens. No effect on `direct` mode. */\n include_tools?: boolean;\n}\n\nexport interface HubAsCodeKanbanStatus {\n /** Stable identifier — set once at create, never edited. Lowercase slug, used in\n * `conversation.kanban_status`, ClickHouse `data.meta.kanban_status`, tool params,\n * and `allowed_next_statuses` references. */\n slug: string;\n /** Display label — shown in UI and tool descriptions. Freely editable. */\n name: string;\n order?: number;\n color?: string;\n isInitialStatus?: boolean;\n triggersAgentResponse?: boolean;\n allowsAgentUpdate?: boolean;\n isTerminalStatus?: boolean;\n isSchedulingStatus?: boolean;\n eventName?: string;\n /** Template prose injected into the agent turn on transition. Supports\n * `{{path.to.field}}` placeholders (dotted, whitespace-tolerant) and the\n * reserved `{{additional_data}}` placeholder which expands to the full\n * payload as 2-space-indented JSON. */\n additional_instructions?: string;\n /** JSON Schema (Draft 2020-12) defining the form fields collected at\n * transition time. The collected payload is interpolated into\n * `additional_instructions` and emitted to the agent as a\n * `<system_additional_instructions>` block. Top-level property name\n * `additional_data` is reserved (collides with the dump placeholder).\n * Capped at 16 KB when JSON-serialized. */\n additional_context_schema?: Record<string, unknown>;\n followups?: HubAsCodeKanbanFollowup[];\n /** Slugs this status can transition to. `undefined` = unrestricted (any next).\n * Empty array is rejected by the validator — use `isTerminalStatus: true` for\n * no outbound transitions. */\n allowed_next_statuses?: string[];\n}\n\n// =============================================\n// HubAsCode payload — JSON representation of hub.yaml + agents/*.yaml\n// =============================================\n\nexport interface HubAsCodePayload {\n version: number;\n hub_id: string;\n hub_environment: string;\n preview_label?: string | null;\n branch_name?: string | null;\n\n hub: {\n name: string;\n description?: string;\n hub_type?: string;\n ai_mode?: string;\n timezone?: string;\n /** Hub language (en|pt|es) — localizes the channel-contact-access pending notice. */\n language?: string;\n /** Gate for who may approve/block channel contacts: 'admin' (default) | 'team'. */\n access_approval_role?: string;\n /** Override text for the one-time \"your access is pending\" notice (else localized default). */\n access_request_message?: string | null;\n non_app_permission?: string;\n mcp_access?: string;\n kanban_statuses?: HubAsCodeKanbanStatus[];\n // flag_conditions relocated to the conversation_evaluator AGENT (see HubAsCodeAgent.flag_conditions).\n // summarization_threshold_tokens relocated to the summarizer AGENT (see HubAsCodeAgent.summarization_threshold_tokens).\n // monitor_config relocated to the monitor AGENT (see HubAsCodeAgent.monitor_config).\n /** Days of inactivity (no user/team messages) before a conversation is force-closed.\n * Range 1..180, default 7. Mandatory across every hub. */\n auto_close_inactive_days?: number;\n /** Org tag slug names (not UUIDs). Resolved against OrgDO `org_tag` on push;\n * unknown names are rejected. Hub tags gate which org credentials this hub\n * can resolve via the symmetric overlap rule (see SKILL connections doc). */\n tags?: string[];\n };\n\n agents?: HubAsCodeAgent[];\n resources?: HubAsCodeResource[];\n states?: HubAsCodeState[];\n teams?: HubAsCodeTeam[];\n evals?: HubAsCodeEval[];\n outbound_contacts?: HubAsCodeOutboundContact[];\n outbound_lists?: HubAsCodeOutboundList[];\n outbound_schedules?: HubAsCodeOutboundSchedule[];\n\n /** Connections serve as reference targets for `connection_id` fields on agents\n * and custom tools. Non-secret configuration fields (base_url, headers, settings,\n * etc.) are round-trippable via pull/push. The bound org credential round-trips\n * by name via `credential`; the raw secret is never exported. */\n connections?: Array<{\n id?: string;\n name: string;\n type: string;\n service?: string;\n /** Pin an org credential by display name (round-trips on pull). */\n credential?: string;\n /** Bearer Token org credential for dual-credential (API Key + access token)\n * connectors. Push-only: not round-tripped on pull (the connection row stores\n * a single credential id, so only the primary `credential` is re-emitted). */\n access_token_credential?: string;\n /** Opt into a deliberately unauthenticated connection for optional-auth connectors\n * (e.g. a no-auth MCP server). Suppresses the \"created without authentication\"\n * push warning. Must not be combined with `credential`. */\n no_auth?: boolean;\n base_url?: string;\n headers?: Record<string, string>;\n settings?: Record<string, unknown>;\n account_sid?: string;\n enabled?: boolean;\n authentication_type?: string;\n }>;\n}\n\nexport interface HubAsCodeAgent {\n id?: string;\n name: string;\n role: string;\n connection: string;\n connection_id?: string;\n instructions?: string;\n additional_context_template?: string;\n enabled?: boolean;\n include_message_timestamps?: boolean;\n settings?: Record<string, unknown>;\n response_format?: {\n type: string;\n schema_name: string;\n schema_json: Record<string, unknown>;\n };\n tools?: {\n native?: Array<string | HubAsCodeNativeTool>;\n delegation?: Array<{\n id?: string;\n type: string;\n tool: string;\n target: string;\n target_id?: string;\n }>;\n custom?: HubAsCodeCustomTool[];\n /**\n * MCP tools discovered from a `Tool - MCP` connection, assigned to this agent.\n * Identity key is `(connection, name)` (an MCP tool name is unique per server).\n *\n * **Omitted vs present (mirrors `evaluation_variables`):** when the `mcp` key\n * is OMITTED, existing MCP tool rows on the agent are left untouched (so tools\n * assigned in the Platform UI survive a push that doesn't manage them). When\n * PRESENT (even as `[]`), the list is AUTHORITATIVE — listed-but-missing tools\n * are created, unlisted MCP tools are removed, matched ones kept. This differs\n * from `native`/`custom` (whose absence deletes them) because MCP tools are\n * dual-origin (UI + GitOps).\n *\n * Push discovers the connection's tools on demand (equivalent to the UI's\n * \"Sync MCP tools\" action), so a single push can create the connection AND\n * assign its tools — the MCP server must be reachable.\n */\n mcp?: HubAsCodeMcpTool[];\n };\n resources?: HubAsCodeAgentResource[];\n /**\n * Evaluation variables (a.k.a. agent parameters) — the structured fields an\n * evaluator agent writes per conversation/message. Round-trippable via\n * pull/push. Identity key is `name` (unique per agent). When the key is\n * OMITTED from YAML, existing variables are left untouched; when PRESENT\n * (even as `[]`), the list is treated as authoritative and replaces the\n * agent's current variables. Primarily used by `conversation_evaluator` /\n * `message_evaluator` agents.\n */\n evaluation_variables?: HubAsCodeEvaluationVariable[];\n /**\n * Conversation-flagging conditions evaluated post-close (OR semantics). A true\n * agent parameter on the `conversation_evaluator` agent (relocated from the hub\n * section). Round-trippable via pull/push. Meaningful only on the\n * `conversation_evaluator` agent; ignored elsewhere.\n */\n flag_conditions?: Array<{ variable: string; operator: '=' | '!='; value: string | number }>;\n /**\n * Token threshold that fires the rolling summarizer (effective tokens =\n * input + cache_read + cache_creation; default 120000). A true agent parameter\n * on the `summarizer` agent (relocated from the hub section). Round-trippable via\n * pull/push. Meaningful only on the `summarizer` agent; ignored elsewhere.\n */\n summarization_threshold_tokens?: number;\n /**\n * Monitor scheduling + flagging config ({delay_seconds, flag_conditions}). A true\n * agent parameter on the `monitor` agent (relocated from the hub section).\n * Round-trippable via pull/push. `delay_seconds` >= 10. Meaningful only on the\n * `monitor` agent; ignored elsewhere.\n */\n monitor_config?: {\n delay_seconds: number;\n flag_conditions?: Array<{ variable: string; operator: '=' | '!='; value: string | number }>;\n } | null;\n}\n\n// Canonical key lists for HubAsCodeAgent and its `tools` block, co-located with\n// the interface so the two are edited together. The CI diff engine derives its\n// unknown-key warnings (gh #2505) from these — without a single source of truth,\n// a hand-maintained copy silently drifts and emits false \"unknown key\" warnings\n// on valid configs once a new field lands. The config validator is `.passthrough()`\n// (no runtime schema to reflect), so parity is enforced at COMPILE time below:\n// - `satisfies readonly (keyof …)[]` rejects typo'd/extra entries\n// - `_Expect<_Exhaustive<…>>` rejects a key present on the interface but missing here\n// Add a field to the interface → tsc fails until it's added to the matching list.\ntype _Expect<T extends true> = T;\ntype _Exhaustive<Keys extends PropertyKey, Listed extends PropertyKey> =\n Exclude<Keys, Listed> extends never ? true : false;\n\nexport const HUB_AS_CODE_AGENT_KEYS = [\n 'id', 'name', 'role', 'connection', 'connection_id', 'instructions',\n 'additional_context_template', 'enabled', 'include_message_timestamps',\n 'settings', 'response_format', 'tools', 'resources', 'evaluation_variables',\n 'flag_conditions', 'summarization_threshold_tokens', 'monitor_config',\n] as const satisfies readonly (keyof HubAsCodeAgent)[];\ntype _AgentKeysExhaustive = _Expect<_Exhaustive<keyof HubAsCodeAgent, (typeof HUB_AS_CODE_AGENT_KEYS)[number]>>;\n\nexport const HUB_AS_CODE_AGENT_TOOL_KEYS = [\n 'native', 'delegation', 'custom', 'mcp',\n] as const satisfies readonly (keyof NonNullable<HubAsCodeAgent['tools']>)[];\ntype _AgentToolKeysExhaustive = _Expect<_Exhaustive<keyof NonNullable<HubAsCodeAgent['tools']>, (typeof HUB_AS_CODE_AGENT_TOOL_KEYS)[number]>>;\n\n/**\n * One evaluation variable on an agent. Maps to a HubDO `agent_parameter` row.\n * Defaults on read (push): `type` → 'string', `required` → true,\n * `is_summary` → false, everything else unset/empty. The emit side (pull)\n * omits any field equal to its default so round-trips stay clean.\n */\nexport interface HubAsCodeEvaluationVariable {\n /** Variable name the agent writes — unique within the agent. Required. */\n name: string;\n /** 'string' (default) | 'number' | 'boolean' | 'integer' | 'enum'. */\n type?: string;\n description?: string;\n /** Human-facing display label (Analytics columns, UI). */\n label?: string;\n /** Allowed values when `type: enum`. Ignored for other types. */\n enum?: string[];\n /** Defaults to true when omitted (mirrors the UI's new-variable default). */\n required?: boolean;\n /**\n * Analytics grouping. Conventional values: quality | satisfaction |\n * compliance | categorization. Free-form to preserve system-internal\n * markers (e.g. `eval` on message-evaluator defaults) across round-trips.\n */\n category?: string | null;\n /**\n * Marks the rolling conversation-summary field. Only honored for\n * `type: string`; coerced to false otherwise.\n */\n is_summary?: boolean;\n}\n\n/**\n * Native tool entry. The string form (e.g. `\"send_text_message\"`) keeps the\n * platform/catalog defaults. The object form lets users override per-instance\n * fields — only `keep_in_history` and `expose_schema_to_llm` are user-managed;\n * other native-tool fields (schema, instructions, operation) come from the\n * catalog and are not round-tripped. Override fields are diff-applied only\n * when explicitly present in YAML — omitted means \"leave as is\".\n */\nexport interface HubAsCodeNativeTool {\n id?: string;\n name: string;\n keep_in_history?: boolean;\n expose_schema_to_llm?: boolean;\n}\n\n/**\n * An MCP tool assigned to an agent (under `tools.mcp`). The tool's schema,\n * description, and config come from the connection's discovered `mcp_tool`\n * catalog — only the reference round-trips through YAML. `connection` (display\n * name) disambiguates which MCP server the tool comes from; `connection_id` and\n * `id` (the tool-row id) are emitted on pull for stable matching.\n */\nexport interface HubAsCodeMcpTool {\n id?: string;\n name: string;\n connection?: string;\n connection_id?: string;\n}\n\nexport interface HubAsCodeCustomTool {\n id?: string;\n name: string;\n description?: string;\n method?: string;\n path?: string;\n body_format?: string;\n connection?: string;\n connection_id?: string;\n headers?: Record<string, unknown>;\n query_params?: Record<string, unknown>;\n body_params?: Record<string, unknown>;\n config?: Record<string, unknown>; // OpenAI function schema (tool_config)\n keep_in_history?: boolean; // default false; controls whether tool call+result remain in LLM history\n instructions?: string;\n composed_tools?: Array<{\n tool_name: string;\n mappings: Record<string, string | { source: string; type?: string; description?: string }>;\n appended_description?: string;\n success_path?: string;\n }> | null;\n enabled?: boolean;\n expose_schema_to_llm?: boolean;\n}\n\nexport interface HubAsCodeState {\n id?: string;\n /**\n * Stable slug — immutable wire identifier. CI diff uses (slug, scope) as the\n * identity key so renaming `name` is detected as an in-place edit rather than\n * a delete + create. Optional on the wire: when omitted the push pipeline\n * derives slugify(name) (the documented hub.yaml shape authors states with\n * only a `name`). Typed `string` because every resolved state carries one.\n */\n slug: string;\n name: string;\n scope: string;\n description?: string;\n enabled?: boolean;\n inject_in_last_message?: boolean;\n json_schema?: Record<string, unknown>;\n initial_value?: Record<string, unknown> | null;\n}\n\nexport interface HubAsCodeTeam {\n id?: string; // hub_team_id (stable, set by pull)\n name: string; // team_name\n access_rule?: 'anytime' | 'anytime_if_delegated_once' | 'only_while_delegated';\n initial_team?: boolean;\n display_only_if_claimed?: boolean; // conversation_display_only_if_claimed\n}\n\nexport interface HubAsCodeResource {\n id?: string;\n name: string;\n type?: string; // 'knowledge' (default) | 'skill'\n description?: string;\n enabled?: boolean;\n user_browsable?: boolean;\n skill_name?: string; // skill-only: slugified unique name (auto-derived from name if omitted)\n files?: HubAsCodeResourceFile[];\n}\n\nexport interface HubAsCodeResourceFile {\n id?: string; // resource_file_id (stable, set by pull)\n path: string; // relative path within resource, e.g. \"images/logo.png\"\n title?: string; // display name (defaults to filename)\n content?: string; // text file content (push: inlined, pull: inlined)\n content_base64?: string; // binary file content (push only)\n download_url?: string; // signed R2 URL (pull only, binary files)\n mime_type?: string;\n file_size?: number;\n hash?: string; // SHA-256\n}\n\nexport interface HubAsCodeAgentResource {\n name: string; // resource display name\n resource_id?: string; // stable ID\n priority?: number;\n enabled?: boolean;\n include_structure_in_prompt?: boolean;\n use_native_integration?: boolean; // skill-only: tool-based (false) vs provider-native (true)\n write_enabled?: boolean; // grants the agent edit access (download_file/upload_file)\n}\n\n// =============================================================================\n// ORG-AS-CODE — organization-scoped resources synced via `wayai org push/pull`\n// (CLI `org/` directory ⇄ `/api/ci/org-resources/*`). Org resources are the\n// org-level analog of hub resources: managed in OrgDO, shadowed into linked\n// hubs. They carry no agent links (hubs link the shadow), but DO carry\n// `environment`/`tags` (which gate hub eligibility) and explicit folders (org\n// folders are a real table with metadata, unlike path-implicit hub folders).\n// =============================================================================\n\nexport interface OrgAsCodeResourceFolder {\n id?: string; // org_resource_folder_id (stable, set by pull)\n path: string; // folder path relative to resource root, e.g. \"docs/guides\"\n description?: string; // folder_description\n}\n\nexport interface OrgAsCodeResource {\n id?: string; // org_resource_id (stable, set by pull)\n name: string;\n type?: string; // 'knowledge' (default) | 'skill'\n description?: string;\n enabled?: boolean;\n user_browsable?: boolean;\n skill_name?: string; // skill-only: slugified unique name (auto-derived from name if omitted)\n environment?: 'all' | 'preview' | 'production'; // which hub environments may link this resource\n tags?: string[]; // org_tag UUIDs gating hub eligibility\n folders?: OrgAsCodeResourceFolder[]; // explicit folders (preserves empty/described folders)\n files?: HubAsCodeResourceFile[]; // identical shape to hub resource files\n}\n\nexport interface OrgResourcesPayload {\n version: 1;\n organization_id?: string;\n resources?: OrgAsCodeResource[];\n}\n\nexport interface HubAsCodeOutboundContact {\n id?: string;\n name: string;\n phone?: string;\n email?: string;\n instagram_sid?: string;\n tags?: string[];\n enabled?: boolean;\n}\n\nexport interface HubAsCodeOutboundList {\n id?: string;\n name: string;\n description?: string;\n contacts?: string[]; // contact names\n}\n\nexport interface HubAsCodeOutboundSchedule {\n id?: string;\n name: string;\n description?: string;\n cron_expression: string;\n timezone?: string;\n list: string; // list name reference\n list_id?: string;\n channel_type: string;\n connection?: string; // connection name reference\n connection_id?: string;\n execution_mode?: string;\n template_whatsapp?: string; // template name reference\n template_whatsapp_id?: string;\n initial_message?: string;\n agent?: string; // agent name reference\n agent_id?: string;\n trigger_message?: string;\n enabled?: boolean;\n}\n\nexport interface HubAsCodeEval {\n id?: string;\n name: string;\n path?: string | null;\n agent: string; // agent display name\n agent_id?: string; // stable agent UUID\n runs?: number; // default 1\n enabled?: boolean; // default true\n history?: Array<{ role: string; content?: string | null; tool_calls?: unknown; tool_call_id?: string }>;\n input: { role: string; content?: string | null; tool_calls?: unknown };\n expected: { role: string; content?: string | null; tool_calls?: unknown };\n evaluator_instructions?: string;\n}\n\n// =============================================\n// Zod request schemas\n// =============================================\n\nconst uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nconst ciUuidSchema = z.string().regex(uuidPattern, 'must be a valid UUID');\n\n/**\n * Walk `agents[].tools.custom[].config.parameters` and add draft-2020-12\n * violations as Zod issues (gh #1542). Placeholder-token cases are skipped\n * — see the matching logic in contracts/setup/tools.ts.\n */\nfunction refineHubAsCodeCustomTools(\n config: unknown,\n ctx: z.RefinementCtx,\n): void {\n const agents = (config as { agents?: unknown }).agents;\n if (!Array.isArray(agents)) return;\n\n for (let a = 0; a < agents.length; a++) {\n const agent = agents[a] as { tools?: { custom?: unknown } } | null | undefined;\n const custom = agent?.tools?.custom;\n if (!Array.isArray(custom)) continue;\n\n for (let c = 0; c < custom.length; c++) {\n const tool = custom[c] as { name?: string; config?: unknown } | null | undefined;\n const raw = tool?.config;\n if (raw == null) continue;\n\n const params = extractToolParameters(raw);\n if (params === undefined) {\n // Either `config` is not an object shape, or there's no `parameters`\n // field. Only the former is an error.\n const looksLikeObject = raw !== null\n && typeof raw === 'object'\n && !Array.isArray(raw)\n || (typeof raw === 'string' && (() => {\n try { const parsed = JSON.parse(raw); return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed); }\n catch { return false; }\n })());\n if (!looksLikeObject) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['agents', a, 'tools', 'custom', c, 'config'],\n message: `custom tool \"${tool?.name ?? '<unnamed>'}\": config must be an object`,\n });\n }\n continue;\n }\n\n if (containsKanbanPlaceholders(params)) continue;\n\n const result = validateToolInputSchema(params);\n if (!result.ok) {\n for (const err of result.errors) {\n const tail = err.path.split('.').filter(Boolean);\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['agents', a, 'tools', 'custom', c, 'config', 'parameters', ...tail],\n message: `custom tool \"${tool?.name ?? '<unnamed>'}\": ${err.message}${err.suggestion ? ` — ${err.suggestion}` : ''}`,\n });\n }\n }\n }\n }\n}\n\n/**\n * Walk `hub.kanban_statuses` and re-path each `kanbanStatusesArraySchema`\n * issue under `['hub', 'kanban_statuses', ...]` so the CLI surfaces field-level\n * errors (e.g. \"config.hub.kanban_statuses[2].triggersAgentResponse: …\").\n *\n * The schema enforces cross-field invariants (mutually-exclusive flags, exactly\n * one initial status, unique names). See contracts/setup/kanban.ts.\n */\nfunction refineHubAsCodeKanbanStatuses(\n config: unknown,\n ctx: z.RefinementCtx,\n): void {\n const hub = (config as { hub?: { kanban_statuses?: unknown } }).hub;\n if (hub == null || !('kanban_statuses' in hub)) return;\n const statuses = hub.kanban_statuses;\n if (!Array.isArray(statuses)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['hub', 'kanban_statuses'],\n message:\n statuses === null\n ? 'kanban_statuses must be an array; use `[]` to clear or omit the key to leave it unchanged'\n : 'kanban_statuses must be an array',\n });\n return;\n }\n\n const result = kanbanStatusesArraySchema.safeParse(statuses);\n if (!result.success) {\n for (const issue of result.error.issues) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['hub', 'kanban_statuses', ...issue.path],\n message: issue.message,\n });\n }\n }\n}\n\n/**\n * Lightweight schema for HubAsCode config — validates structural requirements\n * (version, hub.name) + draft-2020-12 check on every custom tool's config\n * parameters (gh #1542) + kanban_statuses cross-field invariants.\n *\n * Both refines are combined in a single `.superRefine` because Zod's\n * `.superRefine` returns `ZodEffects`, which can't be re-chained without\n * `.pipe()`.\n */\nconst hubAsCodeConfigSchema = z.object({\n version: z.literal(1),\n hub: z.object({\n name: z.string().min(1, 'config.hub.name is required'),\n }).passthrough(),\n}).passthrough().superRefine((config, ctx) => {\n refineHubAsCodeCustomTools(config, ctx);\n refineHubAsCodeKanbanStatuses(config, ctx);\n});\n\n// --- Param schemas ---\n\nexport const ciPullHubIdParam = z.object({\n hub_id: ciUuidSchema,\n});\n\nexport const ciBranchParam = z.object({\n branch: z.string().min(1),\n});\n\n// --- Query schemas ---\n\nexport const ciPullQuery = z.object({\n organization_id: ciUuidSchema.optional(),\n});\n\nexport const ciHubsQuery = z.object({\n organization_id: ciUuidSchema,\n});\n\nexport const ciLookupQuery = z.object({\n path: z.string().min(1, 'path query parameter is required'),\n organization_id: ciUuidSchema.optional(),\n});\n\nexport const ciBranchesQuery = z.object({\n hub_id: ciUuidSchema,\n});\n\n// --- Body schemas ---\n\nexport const ciSyncBody = z.object({\n hub_id: ciUuidSchema,\n branch_name: z.string().min(1, 'branch_name is required'),\n config: hubAsCodeConfigSchema,\n commit_sha: z.string().optional(),\n});\n\nexport const ciPushBody = z.object({\n hub_id: ciUuidSchema,\n config: hubAsCodeConfigSchema,\n organization_id: ciUuidSchema.optional(),\n});\n\nexport const ciDiffBody = z.object({\n hub_id: ciUuidSchema,\n config: hubAsCodeConfigSchema,\n direction: z.enum(['push', 'pull']).default('push'),\n organization_id: ciUuidSchema.optional(),\n});\n\nexport const ciPublishBody = z.object({\n hub_id: ciUuidSchema,\n branch_name: z.string().min(1, 'branch_name is required'),\n});\n\nexport const ciPublishPreviewBody = z.object({\n hub_id: ciUuidSchema,\n});\n\n/**\n * POST /api/ci/sync-mcp — re-discover an MCP connection's tool/resource catalog.\n * `connection` is the display name (as written in `connections[].name`) or the\n * connection UUID; the route resolves either against the hub.\n */\nexport const ciSyncMcpBody = z.object({\n hub_id: ciUuidSchema,\n connection: z.string().min(1, 'connection is required'),\n organization_id: ciUuidSchema.optional(),\n});\n\n// --- Org-as-code (org-resources) schemas ---\n\nexport const ciOrgResourcesParam = z.object({\n org_id: ciUuidSchema,\n});\n\n/**\n * Lightweight passthrough schema for the org-resources payload — mirrors\n * `hubAsCodeConfigSchema`'s approach (validate structural requirements only;\n * the apply path does the authoritative shape work). Requires `version` and,\n * when present, `resources` to be an array.\n */\nconst orgResourcesConfigSchema = z.object({\n version: z.literal(1),\n resources: z.array(z.object({ name: z.string().min(1) }).passthrough()).optional(),\n}).passthrough();\n\nexport const ciOrgResourcesPushBody = z.object({\n organization_id: ciUuidSchema,\n config: orgResourcesConfigSchema,\n});\n\nexport const ciOrgResourcesDiffBody = z.object({\n organization_id: ciUuidSchema,\n config: orgResourcesConfigSchema,\n direction: z.enum(['push', 'pull']).default('push'),\n});\n\n// =============================================================================\n// INFERRED TYPES\n// =============================================================================\n\nexport type CiSyncInput = z.infer<typeof ciSyncBody>;\nexport type CiPushInput = z.infer<typeof ciPushBody>;\nexport type CiDiffInput = z.infer<typeof ciDiffBody>;\nexport type CiPublishInput = z.infer<typeof ciPublishBody>;\nexport type CiPublishPreviewInput = z.infer<typeof ciPublishPreviewBody>;\nexport type CiSyncMcpInput = z.infer<typeof ciSyncMcpBody>;\nexport type CiOrgResourcesPushInput = z.infer<typeof ciOrgResourcesPushBody>;\nexport type CiOrgResourcesDiffInput = z.infer<typeof ciOrgResourcesDiffBody>;\n\n// =============================================\n// Response types\n// =============================================\n\nexport interface CiDiffResponse {\n has_changes: boolean;\n direction: 'push' | 'pull';\n summary: string;\n diff: unknown;\n /**\n * Non-fatal skip reasons surfaced by the diff engine (e.g. native/delegation\n * tools dropped because their connector has no connection on the hub).\n * Populated independently of `has_changes` so the CLI can display them even\n * when every change was silently dropped. Always present (possibly empty),\n * symmetric with `DiffResult.warnings`. See gh #1538.\n */\n warnings: string[];\n}\n\nexport interface CiLookupResponse {\n hub_id: string;\n hub_name: string;\n hub_environment: string;\n preview_label?: string | null;\n branch_name?: string | null;\n}\n\nexport interface CiOrganizationsResponse {\n organizations: Array<{ id: string; name: string }>;\n}\n\nexport interface CiCreateOrganizationResponse {\n organization: {\n id: string;\n name: string;\n /** Resolved DO placement region (auto-detected from the request edge, or the\n * caller's explicit `primary_region`). Surfaced so the CLI can show it. */\n region: string | null;\n /** True when the caller passed an explicit region; false when auto-detected\n * (closest Cloudflare PoP). Lets the CLI phrase \"closest to you\" vs \"as requested\". */\n region_explicit: boolean;\n };\n}\n\nexport interface CiHubListItem {\n hub_id: string;\n hub_name: string;\n hub_environment: string;\n preview_label: string | null;\n branch_name: string | null;\n production_hub_id: string | null;\n}\n\nexport interface CiHubListResponse {\n hubs: CiHubListItem[];\n}\n\nexport interface CiSyncResponse {\n preview_hub_id: string;\n created: boolean;\n changes: {\n hub_updated: boolean;\n connections_created: number;\n connections_updated: number;\n connections_deleted: number;\n agents_created: number;\n agents_updated: number;\n agents_deleted: number;\n tools_created: number;\n tools_updated: number;\n tools_deleted: number;\n states_created: number;\n states_updated: number;\n states_deleted: number;\n teams_created: number;\n teams_updated: number;\n teams_deleted: number;\n resources_created: number;\n resources_updated: number;\n resources_deleted: number;\n resource_files_uploaded: number;\n resource_files_deleted: number;\n resource_links_created: number;\n resource_links_updated: number;\n resource_links_deleted: number;\n evals_created: number;\n evals_updated: number;\n evals_deleted: number;\n outbound_contacts_created: number;\n outbound_contacts_updated: number;\n outbound_contacts_deleted: number;\n outbound_lists_created: number;\n outbound_lists_updated: number;\n outbound_lists_deleted: number;\n outbound_schedules_created: number;\n outbound_schedules_updated: number;\n outbound_schedules_deleted: number;\n };\n errors?: string[];\n /** Non-blocking lint warnings (e.g. unreachable kanban statuses). Same\n * `KanbanLintWarning` shape returned by REST `/hubs` endpoints so the CLI\n * can render structured details (code, slug, message). */\n warnings?: Array<{ code: string; slug: string; name: string; message: string }>;\n}\n\nexport interface CiPublishResponse {\n synced: boolean;\n production_hub_id: string;\n}\n\nexport interface CiSyncMcpResponse {\n success: boolean;\n connection_id: string;\n connection_name: string;\n tools_count?: number;\n resources_count?: number;\n message?: string;\n warnings?: string[];\n}\n\nexport interface CiPublishPreviewResponse {\n synced: boolean;\n production_hub_id?: string;\n}\n\nexport interface CiBranchInfo {\n branch_name: string;\n preview_hub_id: string;\n last_ci_activity_at: string | null;\n ci_commit_sha: string | null;\n}\n\nexport interface CiBranchListResponse {\n branches: CiBranchInfo[];\n}\n\nexport interface CiBranchDeleteResponse {\n deleted: boolean;\n message?: string;\n}\n\n/** Pull returns the org-resources payload directly (CLI writes it to `org/`). */\nexport type CiOrgResourcesPullResponse = OrgResourcesPayload;\n\nexport interface CiOrgResourcesPushResponse {\n changes: {\n resources_created: number;\n resources_updated: number;\n resources_deleted: number;\n resource_files_uploaded: number;\n resource_files_deleted: number;\n resource_folders_created: number;\n resource_folders_deleted: number;\n };\n /** Aggregate awaited fan-out to linked hub shadows across all changed resources. */\n fanout: { hubs: number; failures: number };\n errors?: string[];\n}\n","import { z } from 'zod';\nimport { uuidSchema } from './common';\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\n// --- Param schemas ---\n\nexport const adminOrgIdParam = z.object({\n orgId: uuidSchema,\n});\n\nexport const adminOrgAdminIdParam = z.object({\n orgId: uuidSchema,\n adminId: uuidSchema,\n});\n\nexport const adminUserIdParam = z.object({\n userId: uuidSchema,\n});\n\nexport const adminPlanIdParam = z.object({\n planId: uuidSchema,\n});\n\n// --- Query schemas ---\n\nexport const adminOrganizationsQuery = z.object({\n page: z.coerce.number().int().min(1).default(1),\n limit: z.coerce.number().int().min(1).max(100).default(20),\n search: z.string().optional().default(''),\n});\n\nexport const adminUserSearchQuery = z.object({\n email: z.string().min(3, 'email query parameter must be at least 3 characters'),\n});\n\n// One-time kanban slug migration query. Default is dry-run for safety.\nexport const kanbanSlugMigrationQuery = z.object({\n dry_run: z.enum(['true', 'false']).optional(),\n});\n\n// --- Body schemas ---\n\nexport const adjustQuotaBody = z.object({\n metric_type: z.string().min(1, 'metric_type is required'),\n action: z.enum(['add', 'set']),\n value: z.number().int().min(0, 'value must be a non-negative number'),\n});\n\nexport const updatePlanBody = z.object({\n plan_type: z.enum(['free', 'paid']),\n});\n\nexport const addAdminUserBody = z.object({\n user_email: z.string().email('user_email must be a valid email address'),\n});\n\nexport const updatePlatformConfigBody = z.object({\n free_plan_message_allowance: z.number().int().min(0).optional(),\n free_plan_reset_type: z.string().optional(),\n free_plan_max_free_orgs_per_user: z.number().int().min(0).optional(),\n /** Kill switch for admin debug-read endpoints. 0 = off, 1 = on. */\n debug_read_enabled: z.number().int().min(0).max(1).optional(),\n}).strip().refine(\n (data) => Object.keys(data).length > 0,\n { message: 'No fields to update' }\n);\n\nexport const updateFreeOrgLimitBody = z.object({\n max_free_orgs_override: z.number().int().min(0).nullable(),\n});\n\nexport const updatePricingPlanBody = z.object({\n display_name: z.string().min(1).optional(),\n stripe_product_id: z.string().optional(),\n lookup_key_prefix: z.string().optional(),\n messages_per_unit: z.number().int().min(1, 'messages_per_unit must be a positive integer').optional(),\n seats_per_unit: z.number().int().min(1, 'seats_per_unit must be a positive integer').optional(),\n seats_scaling: z.enum(['fixed', 'per_quantity']).optional(),\n is_active: z.boolean().optional(),\n}).strip().refine(\n (data) => Object.keys(data).length > 0,\n { message: 'No fields to update' }\n);\n\n// =============================================================================\n// INFERRED TYPES\n// =============================================================================\n\nexport type AdjustQuotaInput = z.infer<typeof adjustQuotaBody>;\nexport type UpdatePlanInput = z.infer<typeof updatePlanBody>;\nexport type AddAdminUserInput = z.infer<typeof addAdminUserBody>;\nexport type UpdatePlatformConfigInput = z.infer<typeof updatePlatformConfigBody>;\nexport type UpdateFreeOrgLimitInput = z.infer<typeof updateFreeOrgLimitBody>;\nexport type UpdatePricingPlanInput = z.infer<typeof updatePricingPlanBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n/** GET /admin/check */\nexport interface AdminCheckResponse {\n is_platform_admin: true;\n}\n\n/** Billing metric row returned inside organization list/detail */\nexport interface AdminBillingMetric {\n organization_id: string;\n metric_type: string;\n monthly_included: number;\n consumed_subscription: number;\n}\n\n/** Organization item in the paginated list */\nexport interface AdminOrganizationItem {\n organization_id: string;\n organization_name: string;\n created_at: string;\n plan_type: string;\n billing_status: string;\n has_subscription: boolean;\n period_end: string | null;\n owner_email: string | null;\n admin_users: Array<{\n organization_admin_user_id: string;\n user_email: string;\n is_owner: boolean;\n }>;\n metrics: AdminBillingMetric[];\n}\n\n/** Pagination metadata */\nexport interface AdminPaginationMeta {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n}\n\n/** GET /admin/organizations */\nexport interface AdminOrganizationsListResponse {\n data: AdminOrganizationItem[];\n pagination: AdminPaginationMeta;\n}\n\n/** POST /admin/organizations/:orgId/resync-registry */\nexport interface AdminResyncOrgRegistryResponse {\n ok: true;\n org_id: string;\n patched_fields: string[];\n}\n\n/** POST /admin/dev/backfill-org-registry */\nexport interface AdminBackfillOrgRegistryResponse {\n processed: number;\n succeeded: number;\n failed: number;\n failures: Array<{ org_id: string; error: string }>;\n}\n\n/** GET /admin/organizations/:orgId */\nexport interface AdminOrganizationDetailResponse {\n data: {\n organization_id: string;\n billing: Record<string, unknown> | null;\n metrics: AdminBillingMetric[];\n admin_users: Array<{\n organization_admin_user_id: string;\n user_email: string;\n is_owner: boolean;\n }>;\n };\n}\n\n/** POST /admin/organizations/:orgId/admins */\nexport interface AdminAddAdminUserResponse {\n data: {\n organization_admin_user_id: string;\n user_email: string;\n is_owner: boolean;\n };\n}\n\n/** GET /admin/config, PATCH /admin/config */\nexport interface AdminConfigResponse {\n data: Record<string, unknown>;\n}\n\n/** User search result item */\nexport interface AdminUserSearchItem {\n user_id: string;\n user_email: string;\n profile_name: string | null;\n max_free_orgs_override: number | null;\n}\n\n/** GET /admin/users/search */\nexport interface AdminUserSearchResponse {\n data: AdminUserSearchItem[];\n}\n\n/** PATCH /admin/users/:userId/free-org-limit */\nexport interface AdminUpdateFreeOrgLimitResponse {\n data: AdminUserSearchItem;\n}\n\n/** GET /admin/pricing-plans */\nexport interface AdminPricingPlansListResponse {\n data: Array<Record<string, unknown>>;\n}\n\n/** PATCH /admin/pricing-plans/:planId */\nexport interface AdminUpdatePricingPlanResponse {\n data: Record<string, unknown>;\n}\n\n// One-time kanban slug migration result.\nexport interface KanbanSlugMigrationResult {\n dry_run: boolean;\n total_hubs: number;\n migrated: number;\n already_migrated: number;\n skipped: Array<{ hub_id: string; reason: string }>;\n}\n\n/** POST /admin/migrate/kanban-slugs */\nexport interface KanbanSlugMigrationResponse {\n data: KanbanSlugMigrationResult;\n}\n\n// =============================================================================\n// DATA EXPLORER — Request Schemas\n// =============================================================================\n\nexport const dataExplorerSearchQuery = z.object({\n q: z.string().min(1, 'search query is required'),\n type: z.enum(['org', 'hub', 'user']).optional(),\n});\n\nexport const dataExplorerOrgIdParam = z.object({ orgId: uuidSchema });\nexport const dataExplorerHubIdParam = z.object({ hubId: uuidSchema });\nexport const dataExplorerConvIdParam = z.object({ convId: uuidSchema });\n\nexport const dataExplorerDoInstancesQuery = z.object({\n cursor: z.string().optional(),\n limit: z.coerce.number().int().min(1).max(100).default(50),\n orphans_only: z.coerce.boolean().optional().default(false),\n /** Direct lookup by entity UUID (hub_id/org_id/user_id/conversation_id). When set, bypasses pagination and returns a synthesized entry via idFromName. */\n search: z.string().optional(),\n});\n\nexport const dataExplorerNsIdParam = z.object({\n nsId: z.string().min(1, 'namespace ID is required'),\n});\n\nexport const dataExplorerKvKeysQuery = z.object({\n prefix: z.string().optional(),\n cursor: z.string().optional(),\n limit: z.coerce.number().int().min(1).max(100).default(50),\n});\n\nexport const dataExplorerKvKeyParam = z.object({\n nsId: z.string().min(1),\n key: z.string().min(1, 'key is required'),\n});\n\n/** Accepts UUID or Cloudflare DO hex ID (for orphan deletion) */\nconst uuidOrHexId = z.string().min(1);\nexport const dataExplorerDeleteOrgParam = z.object({ orgId: uuidOrHexId });\nexport const dataExplorerDeleteHubParam = z.object({ hubId: uuidOrHexId });\nexport const dataExplorerDeleteConvParam = z.object({ convId: uuidOrHexId });\nexport const dataExplorerDeleteUserParam = z.object({ userId: uuidOrHexId });\n\nexport const dataExplorerDeleteQuery = z.object({\n confirmation: z.string().min(1, 'confirmation is required'),\n cascade: z.coerce.boolean().optional().default(false),\n});\n\nexport const dataExplorerKvDeleteQuery = z.object({\n confirmation: z.string().min(1, 'confirmation is required'),\n});\n\n// =============================================================================\n// DATA EXPLORER — Inferred Types\n// =============================================================================\n\nexport type DataExplorerSearchInput = z.infer<typeof dataExplorerSearchQuery>;\nexport type DataExplorerDeleteInput = z.infer<typeof dataExplorerDeleteQuery>;\n\n// =============================================================================\n// DATA EXPLORER — Response Types\n// =============================================================================\n\n/** Hub entry in org entity tree */\nexport interface DataExplorerHubEntry {\n hub_id: string;\n hub_name: string;\n hub_type: string;\n hub_environment: string;\n production_hub_id: string | null;\n dashboard_url: string | null;\n}\n\n/** Search result item */\nexport interface DataExplorerSearchResultItem {\n type: 'org' | 'hub' | 'user';\n id: string;\n name: string;\n /** Extra context (e.g., org name for hub results, email for user results) */\n context?: string;\n}\n\n/** GET /data-explorer/search */\nexport interface DataExplorerSearchResponse {\n data: DataExplorerSearchResultItem[];\n}\n\n/** GET /data-explorer/entity/org/:orgId */\nexport interface DataExplorerOrgEntityResponse {\n data: {\n organization_id: string;\n organization_name: string;\n dashboard_url: string | null;\n hubs: DataExplorerHubEntry[];\n billing: Record<string, unknown> | null;\n };\n}\n\n/** GET /data-explorer/entity/hub/:hubId */\nexport interface DataExplorerHubEntityResponse {\n data: {\n hub_id: string;\n hub_name: string;\n hub_type: string;\n dashboard_url: string | null;\n conversation_count: number;\n };\n}\n\n/** GET /data-explorer/entity/conversation/:convId */\nexport interface DataExplorerConvEntityResponse {\n data: {\n conversation_id: string;\n dashboard_url: string | null;\n conversation: Record<string, unknown> | null;\n };\n}\n\n/** DO namespace item */\nexport interface DataExplorerDoNamespace {\n id: string;\n name: string;\n class: string;\n}\n\n/** GET /data-explorer/do/namespaces */\nexport interface DataExplorerDoNamespacesResponse {\n data: DataExplorerDoNamespace[];\n}\n\n/** DO instance item */\nexport interface DataExplorerDoInstance {\n id: string;\n name: string | null;\n /** `null` means the backend did not probe CF for storage state (e.g., direct search by UUID) */\n hasStoredData: boolean | null;\n dashboard_url: string;\n /** The domain entity ID (e.g., org_id, hub_id) used in idFromName — null if unknown */\n entity_id?: string | null;\n /** Resolved domain name (e.g., org name) — null if not resolved */\n resolved_name?: string | null;\n /** Whether this instance is an orphan (not in any known hierarchy) */\n is_orphan?: boolean;\n}\n\n/** GET /data-explorer/do/namespaces/:nsId/instances */\nexport interface DataExplorerDoInstancesResponse {\n data: DataExplorerDoInstance[];\n cursor?: string;\n}\n\n/** KV namespace item */\nexport interface DataExplorerKvNamespace {\n name: string;\n id: string;\n}\n\n/** GET /data-explorer/kv/namespaces */\nexport interface DataExplorerKvNamespacesResponse {\n data: DataExplorerKvNamespace[];\n}\n\n/** KV key item */\nexport interface DataExplorerKvKeyItem {\n name: string;\n metadata: Record<string, unknown> | null;\n expiration?: number;\n}\n\n/** GET /data-explorer/kv/namespaces/:nsId/keys */\nexport interface DataExplorerKvKeysResponse {\n data: DataExplorerKvKeyItem[];\n cursor?: string;\n}\n\n/** GET /data-explorer/kv/namespaces/:nsId/keys/:key */\nexport interface DataExplorerKvValueResponse {\n data: {\n key: string;\n value: string | null;\n masked: boolean;\n };\n}\n\n/** DELETE responses */\nexport interface DataExplorerDeleteResult {\n deleted: string[];\n failed: Array<{ id: string; error: string }>;\n}\n\nexport interface DataExplorerDeleteResponse {\n data: DataExplorerDeleteResult;\n}\n\n// =============================================================================\n// PITR (Point-in-Time Recovery) — Request Schemas\n// =============================================================================\n\n/** Valid DO namespace names for PITR operations */\nexport const pitrDoNamespace = z.enum(['HUB_DO', 'CONVERSATION_DO', 'ORG_DO', 'USER_DO', 'PLATFORM_DO']);\n\n/** GET /admin/pitr/:namespace/:instanceId/bookmark */\nexport const pitrBookmarkParam = z.object({\n namespace: pitrDoNamespace,\n instanceId: z.string().min(1, 'instanceId is required'),\n});\n\n/** POST /admin/pitr/:namespace/:instanceId/restore — reuses bookmark param shape */\nexport const pitrRestoreParam = pitrBookmarkParam;\n\n/** Body for restore request */\nexport const pitrRestoreBody = z.object({\n /** ISO 8601 timestamp to restore to (must be within last 30 days) */\n target_timestamp: z.string().datetime('target_timestamp must be a valid ISO 8601 datetime'),\n /** Must match the instanceId for confirmation */\n confirmation: z.string().min(1, 'confirmation is required'),\n /** If true, only fetch the bookmark without performing the restore (default: true) */\n dry_run: z.boolean().default(true),\n});\n\n// =============================================================================\n// PITR — Inferred Types\n// =============================================================================\n\nexport type PitrDoNamespace = z.infer<typeof pitrDoNamespace>;\nexport type PitrRestoreInput = z.infer<typeof pitrRestoreBody>;\n\n// =============================================================================\n// PITR — Response Types\n// =============================================================================\n\n/** GET /admin/pitr/:namespace/:instanceId/bookmark */\nexport interface PitrBookmarkResponse {\n data: {\n namespace: string;\n instance_id: string;\n current_bookmark: string;\n };\n}\n\n/** POST /admin/pitr/:namespace/:instanceId/restore */\nexport interface PitrRestoreResponse {\n data: {\n namespace: string;\n instance_id: string;\n target_timestamp: string;\n target_bookmark: string;\n current_bookmark: string;\n /** Bookmark that can be used to undo this restore */\n undo_bookmark: string | null;\n dry_run: boolean;\n restore_scheduled: boolean;\n };\n}\n\n// =============================================================================\n// DO Health Validation — Response Types\n// =============================================================================\n\nexport interface HealthValidationIssue {\n table: string;\n check: 'existence' | 'row_count' | 'json_validity';\n severity: 'error' | 'warning';\n message: string;\n}\n\nexport interface HealthValidationResponse {\n data: {\n status: 'pass' | 'fail';\n tables_checked: number;\n tables_passed: number;\n issues: HealthValidationIssue[];\n checked_at: string;\n };\n}\n\n// =============================================================================\n// Health Sampling — Request Schemas\n// =============================================================================\n\n/** POST /admin/health-sampling — trigger body */\nexport const healthSamplingTriggerBody = z.object({\n /** Number of instances to sample per DO type (default: 10) */\n sample_size: z.number().int().min(1).max(100).default(10),\n /** Filter to specific DO types (default: all) */\n do_types: z.array(pitrDoNamespace).optional(),\n});\n\nexport type HealthSamplingTriggerInput = z.infer<typeof healthSamplingTriggerBody>;\n\n// =============================================================================\n// DATA EXPLORER DEBUG READS — Request Schemas\n// =============================================================================\n//\n// Platform-admin-only read-only inspection of DO SQLite state. Gated by\n// platformAdminMiddleware + strict rate limit + kill switch + column redaction.\n// See workers/backend/src/durable-objects/debug-redaction.ts for the central\n// allowlist and redaction rules.\n\n/** Valid DO types for debug reads. Shared source of truth — re-exported as `DoType` in debug-redaction.ts. */\nexport const dataExplorerDebugDoType = z.enum(['hub', 'org', 'conversation', 'user', 'platform']);\n\n/** Hard cap on `limit` query param — applied in both Zod and the DO RPC. */\nexport const DEBUG_READ_MAX_LIMIT = 100;\n/** Default `limit` when the caller omits it. */\nexport const DEBUG_READ_DEFAULT_LIMIT = 20;\n\nexport const DEBUG_DO_HEX_PREFIX = 'hex:';\n\n/**\n * `hex:<64-hex>` is resolved via `idFromString` (raw CF DO id — for inspecting\n * DOs discovered without a reverse path, e.g. orphan-audit). All other forms\n * go through `idFromName`.\n */\nconst debugDoEntityId = z\n .string()\n .min(1, 'entity id is required')\n .max(68)\n .refine(\n (v) => !v.startsWith(DEBUG_DO_HEX_PREFIX) || /^hex:[0-9a-f]{64}$/.test(v),\n { message: 'hex: prefix must be followed by exactly 64 lowercase hex chars' },\n );\n\n/**\n * Table name param. Two-layer injection defense: regex here + assertTableAllowed()\n * against a frozen allowlist in the DO RPC. Table names are NEVER string-interpolated\n * into SQL — they're looked up in a constant map.\n */\nconst debugTableName = z.string().regex(\n /^[a-z][a-z0-9_]{0,63}$/,\n 'table name must be lowercase letters, digits, underscores (<=64 chars)',\n);\n\n/** GET /api/admin/data-explorer/debug/do/:type/:id/tables */\nexport const dataExplorerDebugTablesParam = z.object({\n type: dataExplorerDebugDoType,\n id: debugDoEntityId,\n});\n\n/** GET /api/admin/data-explorer/debug/do/:type/:id/tables/:name/rows */\nexport const dataExplorerDebugRowsParam = z.object({\n type: dataExplorerDebugDoType,\n id: debugDoEntityId,\n name: debugTableName,\n});\n\nexport const dataExplorerDebugRowsQuery = z.object({\n limit: z.coerce.number().int().min(1).max(DEBUG_READ_MAX_LIMIT).default(DEBUG_READ_DEFAULT_LIMIT),\n /** Optional lookup by primary key value — typed as string since PKs are all TEXT UUIDs */\n id: z.string().min(1).max(256).optional(),\n});\n\n// =============================================================================\n// DATA EXPLORER DEBUG READS — Inferred Types\n// =============================================================================\n\nexport type DataExplorerDebugDoType = z.infer<typeof dataExplorerDebugDoType>;\nexport type DataExplorerDebugRowsQueryInput = z.infer<typeof dataExplorerDebugRowsQuery>;\n\n// =============================================================================\n// DATA EXPLORER DEBUG READS — Response Types\n// =============================================================================\n\n/** GET /api/admin/data-explorer/debug/do/:type/:id/tables */\nexport interface DataExplorerDebugTablesResponse {\n data: {\n do_type: DataExplorerDebugDoType;\n do_id: string;\n /** Tables present in the DO that are also in the debug allowlist */\n tables: string[];\n };\n}\n\n/** GET /api/admin/data-explorer/debug/do/:type/:id/tables/:name/rows */\nexport interface DataExplorerDebugRowsResponse {\n data: {\n do_type: DataExplorerDebugDoType;\n do_id: string;\n table: string;\n /** Rows with sensitive columns replaced by the string \"[REDACTED]\" */\n rows: Record<string, unknown>[];\n /** Column names that were redacted in this response (for operator awareness) */\n redacted_columns: string[];\n /** True if the result was capped at `limit` and more rows may exist */\n truncated: boolean;\n /** Applied limit — echoes the query param or its default */\n limit: number;\n };\n}\n\n// =============================================================================\n// DATA EXPLORER DEBUG READS — ClickHouse analytics tables\n// =============================================================================\n//\n// Same gates as the DO debug surface: platform-admin, audit, rate-limit, kill\n// switch. CH tables are queried via parameterized SQL (`{key:Type}` placeholders)\n// — never string-interpolated. Allowlist + redaction live in\n// workers/backend/src/clickhouse/debug-redaction.ts.\n\n/** Tables an admin can read via `wayai admin analytics`. */\nexport const dataExplorerDebugAnalyticsTable = z.enum([\n 'conversation',\n 'message',\n 'billing_event',\n 'schedule_event',\n]);\nexport type DataExplorerDebugAnalyticsTable = z.infer<typeof dataExplorerDebugAnalyticsTable>;\n\n/** UUID validator reused for filter values. Any non-UUID input is rejected before reaching CH. */\nconst debugUuid = z.string().uuid();\n\n/** GET /api/admin/data-explorer/debug/analytics/:table/rows */\nexport const dataExplorerDebugAnalyticsRowsParam = z.object({\n table: dataExplorerDebugAnalyticsTable,\n});\n\nexport const dataExplorerDebugAnalyticsRowsQuery = z.object({\n conversation_id: debugUuid.optional(),\n hub_id: debugUuid.optional(),\n message_id: debugUuid.optional(),\n limit: z.coerce.number().int().min(1).max(DEBUG_READ_MAX_LIMIT).default(DEBUG_READ_DEFAULT_LIMIT),\n});\n\nexport type DataExplorerDebugAnalyticsRowsQueryInput = z.infer<typeof dataExplorerDebugAnalyticsRowsQuery>;\n\n/** GET /api/admin/data-explorer/debug/analytics/tables */\nexport interface DataExplorerDebugAnalyticsTablesResponse {\n data: {\n tables: DataExplorerDebugAnalyticsTable[];\n };\n}\n\n/** GET /api/admin/data-explorer/debug/analytics/:table/rows */\nexport interface DataExplorerDebugAnalyticsRowsResponse {\n data: {\n table: DataExplorerDebugAnalyticsTable;\n rows: Record<string, unknown>[];\n /** Redacted column names or dotted JSON paths (e.g. \"data\", \"data.meta.last_message_text\"). */\n redacted_columns: string[];\n truncated: boolean;\n limit: number;\n };\n}\n\n// =============================================================================\n// DATA EXPLORER DEBUG READS — R2 archive\n// =============================================================================\n//\n// Admin-gated counterpart to `GET /api/archive/:hubId/conversations/:conversationId`.\n// Same archive blob, but reachable only by platform admins and audited as\n// `admin_debug_read`. Does not provision access — admins still need the blob to\n// exist in R2.\n\n// Hub+conversation pair shared by both debug-archive and debug-observability\n// param schemas — keep them as one source of truth so route paths stay aligned.\nconst debugHubConvParam = z.object({\n hubId: debugUuid,\n conversationId: debugUuid,\n});\n\n// Optional message_id filter — same semantics for archive and observability\n// (server returns the matching message; otherwise the full set).\nconst debugMessageIdQuery = z.object({\n message_id: debugUuid.optional(),\n});\n\nexport const dataExplorerDebugArchiveParam = debugHubConvParam;\nexport const dataExplorerDebugArchiveQuery = debugMessageIdQuery;\n\nexport type DataExplorerDebugArchiveQueryInput = z.infer<typeof dataExplorerDebugArchiveQuery>;\n\n/** GET /api/admin/data-explorer/debug/archive/:hubId/conversations/:conversationId */\nexport interface DataExplorerDebugArchiveResponse {\n data: {\n hub_id: string;\n conversation_id: string;\n /** The full archive blob written by the archive job, optionally with `messages` filtered server-side. */\n archive: Record<string, unknown>;\n /** True when ?message_id= filtered the messages array. */\n message_filtered: boolean;\n };\n}\n\n// =============================================================================\n// DATA EXPLORER DEBUG READS — R2 LLM observability\n// =============================================================================\n//\n// Admin-gated read of per-message OpenTelemetry GenAI records (full prompts,\n// completions, tool calls, tokens, latency). The hub-scoped equivalent at\n// `/api/conversations/:conversationId/...` enforces hub-user / team-member\n// access; this debug variant requires `platform:admin` instead so an operator\n// can inspect any hub for incident response. Same data shape both ways.\n\nexport const dataExplorerDebugObservabilityParam = debugHubConvParam;\nexport const dataExplorerDebugObservabilityQuery = debugMessageIdQuery;\n\nexport type DataExplorerDebugObservabilityQueryInput = z.infer<typeof dataExplorerDebugObservabilityQuery>;\n\n/**\n * GET /api/admin/data-explorer/debug/observability/:hubId/conversations/:conversationId\n *\n * Discriminated by `kind` so TypeScript callers narrow without non-null assertions:\n * - `kind: 'list'` (no ?message_id) — `entries` is populated.\n * - `kind: 'single'` (with ?message_id) — `record` is populated.\n */\nexport type DataExplorerDebugObservabilityResponse =\n | {\n data: {\n kind: 'list';\n hub_id: string;\n conversation_id: string;\n entries: import('../observability/types').WayAIMetadataRecord[];\n /** True when the list was truncated by the server cap. */\n truncated: boolean;\n };\n }\n | {\n data: {\n kind: 'single';\n hub_id: string;\n conversation_id: string;\n record: import('../observability/types').LLMObservabilityRecord;\n };\n };\n\n// =============================================================================\n// Health Sampling — Response Types\n// =============================================================================\n\nexport interface HealthSamplingInstanceResult {\n namespace: string;\n instance_id: string;\n status: 'pass' | 'fail' | 'error';\n issues: HealthValidationIssue[];\n error?: string;\n}\n\nexport interface HealthSamplingReport {\n data: {\n status: 'pass' | 'fail';\n triggered_at: string;\n completed_at: string;\n commit?: string;\n sample_size: number;\n results: HealthSamplingInstanceResult[];\n summary: {\n total_instances: number;\n passed: number;\n failed: number;\n errors: number;\n };\n };\n}\n","import { z } from 'zod';\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\nexport const whatsappCallbackBody = z.object({\n state: z.string().min(1, 'state is required'),\n code: z.string().optional(),\n access_token: z.string().optional(),\n user_id: z.string().optional(),\n}).refine(\n (data) => !!data.access_token || !!data.code,\n { message: 'Missing required parameters: state and either access_token or code' }\n);\n\n// =============================================================================\n// AUTH ME — GET /api/auth/me\n// =============================================================================\n\nexport const authMeResponse = z.object({\n user_id: z.string(),\n email: z.string(),\n org_id: z.string().nullable(),\n is_platform_admin: z.boolean(),\n});\n\nexport type AuthMeResponse = z.infer<typeof authMeResponse>;\n\n// =============================================================================\n// WS TICKET — POST /api/auth/ws-ticket\n// =============================================================================\n\nexport const wsTicketResponse = z.object({\n ticket: z.string(),\n /** Seconds until the ticket expires if unconsumed. */\n expires_in: z.number(),\n});\n\nexport type WsTicketResponse = z.infer<typeof wsTicketResponse>;\n\n// =============================================================================\n// SESSION CHECK — GET /api/auth/session-check\n// =============================================================================\n\nexport const sessionCheckResponse = z.object({\n valid: z.literal(true),\n});\n\nexport type SessionCheckResponse = z.infer<typeof sessionCheckResponse>;\n\n// =============================================================================\n// LOGOUT — POST /api/auth/logout\n// =============================================================================\n\nexport const logoutResponse = z.object({\n success: z.literal(true),\n});\n\nexport type LogoutResponse = z.infer<typeof logoutResponse>;\n\n// =============================================================================\n// INFERRED TYPES\n// =============================================================================\n\nexport type WhatsappCallbackInput = z.infer<typeof whatsappCallbackBody>;\n","import { z } from 'zod';\nimport { uuidSchema } from './common';\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\nexport const browserParams = z.object({\n hubId: uuidSchema,\n resourceId: uuidSchema,\n});\n\nexport const browserFoldersQuery = z.object({\n parent_folder_id: uuidSchema.optional(),\n search: z.string().max(100).optional(),\n});\n\nexport const browserFilesQuery = z.object({\n folder_id: uuidSchema.optional(),\n search: z.string().max(100).optional(),\n limit: z.coerce.number().int().min(1).max(100).default(50),\n offset: z.coerce.number().int().min(0).max(10000).default(0),\n});\n\n// =============================================================================\n// INFERRED TYPES\n// =============================================================================\n\nexport type BrowserParams = z.infer<typeof browserParams>;\nexport type BrowserFoldersQuery = z.infer<typeof browserFoldersQuery>;\nexport type BrowserFilesQuery = z.infer<typeof browserFilesQuery>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\nexport interface BrowserFolderItem {\n folder_id: string;\n folder_name: string;\n folder_description: string | null;\n parent_folder_id: string | null;\n metadata: Record<string, unknown>;\n file_count: number;\n subfolder_count: number;\n resource_id: string;\n resource_name: string;\n}\n\nexport interface BrowserFileItem {\n file_id: string;\n file_name: string;\n file_description: string | null;\n mime_type: string | null;\n file_size: number | null;\n folder_id: string | null;\n metadata: Record<string, unknown>;\n resource_id: string;\n resource_name: string;\n}\n\nexport interface BrowserFoldersResponse {\n success: boolean;\n folders: BrowserFolderItem[];\n total_count: number;\n}\n\nexport interface BrowserFilesResponse {\n success: boolean;\n files: BrowserFileItem[];\n total_count: number;\n}\n","import { z } from 'zod';\nimport { slugSchema } from './setup/slug';\n\n// ---------------------------------------------------------------------------\n// State Operations (via state_operations RPC)\n// ---------------------------------------------------------------------------\n\nexport const stateOperationBody = z.object({\n hub_id: z.string().uuid(),\n operation: z.enum(['get', 'update', 'set_path', 'reset']),\n state_slug: slugSchema,\n /**\n * Deprecated and ignored. Scope is derived from the hub's state definition.\n * Kept on the schema so legacy bodies still validate.\n */\n state_scope: z.enum(['conversation', 'user']).optional(),\n updates: z.record(z.unknown()).optional(),\n path: z.array(z.string()).optional(),\n value: z.unknown().optional(),\n});\n\nexport type StateOperationBody = z.infer<typeof stateOperationBody>;\n\nexport interface StateOperationResponse {\n ok: true;\n data: unknown;\n}\n","import { z } from 'zod';\n\nexport const conversationListResourcesQuery = z.object({\n hub_id: z.string().uuid(),\n agent_id: z.string().uuid().optional(),\n});\n\nexport const conversationReadResourceQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\nexport type ConversationListResourcesQuery = z.infer<typeof conversationListResourcesQuery>;\nexport type ConversationReadResourceQuery = z.infer<typeof conversationReadResourceQuery>;\n\nexport type ConversationListResourcesResponse = {\n ok: true;\n data: Array<{\n file_id: string;\n file_name: string;\n mime_type: string;\n file_size: number | null;\n }>;\n} | { ok: false; error: string };\n\nexport type ConversationReadResourceResponse = {\n ok: true;\n data: {\n file_id: string;\n file_name: string;\n content: string;\n mime_type: string;\n };\n} | { ok: false; error: string };\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Params & Queries\n// ---------------------------------------------------------------------------\n\nexport const listPendingSchedulesQuery = z.object({\n hub_id: z.string().uuid(),\n conversation_id: z.string().uuid().optional(),\n user_id: z.string().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type ListPendingSchedulesQuery = z.infer<typeof listPendingSchedulesQuery>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface PendingScheduleEntry {\n conversation_schedule_id: string;\n schedule_type: string;\n run_at: string;\n message_text: string;\n conversation_id: string | null;\n user_id: string | null;\n hub_id: string;\n hub_type: string;\n agent_id: string | null;\n receiver_type: string;\n followup_order: number | null;\n followup_source: 'kanban' | 'default_open' | 'default_closed' | null;\n followup_type: 'inactivity' | 'before_event' | null;\n end_conversation: boolean;\n sender_type: string | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface ListPendingSchedulesResponse {\n entries: PendingScheduleEntry[];\n total: number;\n}\n\n// ---------------------------------------------------------------------------\n// Hub-admin aggregate view (SCHEDULE_INDEX KV)\n// ---------------------------------------------------------------------------\n\nexport const listHubAggregateSchedulesQuery = z.object({\n hub_id: z.string().uuid(),\n limit: z.coerce.number().int().min(1).max(1000).optional(),\n});\n\nexport type ListHubAggregateSchedulesQuery = z.infer<typeof listHubAggregateSchedulesQuery>;\n\nexport interface HubAggregateScheduleEntry {\n schedule_id: string;\n kind: 'conversation' | 'hub';\n schedule_type: string;\n run_at: string;\n conversation_id: string | null;\n}\n\nexport interface ListHubAggregateSchedulesResponse {\n entries: HubAggregateScheduleEntry[];\n total: number;\n list_complete: boolean;\n}\n","import { z } from 'zod';\n\n// =============================================================================\n// SHARED ENUMS — kept in sync with PlatformDO schema CHECK constraints\n// =============================================================================\n\n// `source` = origin/channel: who/what filed the report.\n// sentry — production runtime error (Sentry webhook)\n// cli — human via `wayai report create`\n// review — code agent, during the review loop\n// security_audit — code agent, during the /security-screening skill\nexport const reportSourceSchema = z.enum(['sentry', 'cli', 'review', 'security_audit']);\nexport type ReportSource = z.infer<typeof reportSourceSchema>;\n\n// Narrowed source set accepted at the CLI intake endpoint. Excludes `sentry`\n// so a `way_`-token caller can't forge a Sentry-origin row.\nexport const intakeReportSourceSchema = z.enum(['cli', 'review', 'security_audit']);\nexport type IntakeReportSource = z.infer<typeof intakeReportSourceSchema>;\n\n// `classification` = nature of the report. Drives the GitHub label on escalation\n// and the dedup-fingerprint strategy. Orthogonal to `source`.\nexport const reportClassificationSchema = z.enum(['bug', 'flaky_test', 'security']);\nexport type ReportClassification = z.infer<typeof reportClassificationSchema>;\n\n// `shipped` and `contested` are the agent-interactive loop states (see the report\n// lifecycle in the report-triage skill): the fixer marks a fix `shipped` (awaiting the\n// reporter), and the reporter `contested` a fix or a dismissal back to triage.\nexport const reportStatusSchema = z.enum([\n 'pending',\n 'grouped',\n 'escalated',\n 'shipped',\n 'contested',\n 'addressed',\n 'dismissed',\n]);\nexport type ReportStatus = z.infer<typeof reportStatusSchema>;\n\nexport const reportLocaleSchema = z.enum(['en', 'pt', 'es']);\nexport type ReportLocale = z.infer<typeof reportLocaleSchema>;\n\n// Author of a `report_message` thread entry. The thread is the reporter-facing narrative\n// channel (the loop's memory across rounds); every entry here is reporter-safe — internal\n// triage reasoning (`ai_verdict`) is NOT mirrored into it.\nexport const reportMessageAuthorRoleSchema = z.enum(['reporter', 'triage', 'fixer', 'system']);\nexport type ReportMessageAuthorRole = z.infer<typeof reportMessageAuthorRoleSchema>;\n\nexport interface ReportMessage {\n message_id: string;\n author_role: ReportMessageAuthorRole;\n /** The status transition this note accompanied (e.g. 'shipped'); null for a free/system note. */\n transition: string | null;\n body: string;\n created_at: number;\n /**\n * Visibility: `false` = reporter-facing (the default for every narrative entry); `true` =\n * triage-internal (e.g. a `hold` rationale) — surfaced to platform admins only and NEVER\n * returned on the reporter read path. The reporter's `GET /api/reports/:id` filters these out.\n */\n internal: boolean;\n}\n\n// `sentry_ref_status` = result of cross-checking a Sentry-sourced report's\n// captured issue reference (`raw_payload.issue_id` / `short_id`) against the\n// live Sentry API at escalation time. Null for non-sentry reports or before the\n// check has run. Gates the GH-webhook auto-resolve: only a `valid` reference is\n// resolved on issue close, so a fabricated/dead/mismatched ref can never resolve\n// the wrong live issue (the failure #2438 documents).\n// valid — issue_id resolves AND the captured short_id matches the live issue\n// not_found — issue_id does not resolve (dead/fabricated reference)\n// mismatch — issue_id resolves but the captured short_id ≠ the live short_id\n// unverified — could not check (no SENTRY_API_TOKEN, or a Sentry API error)\nexport const sentryRefStatusSchema = z.enum(['valid', 'not_found', 'mismatch', 'unverified']);\nexport type SentryRefStatus = z.infer<typeof sentryRefStatusSchema>;\n\n// =============================================================================\n// INTAKE — POST /api/reports (CLI only)\n//\n// Replaces /api/bug-reports. MCP `report_bug` tool has been removed entirely;\n// reporting is a code-agent (CLI) workflow.\n// =============================================================================\n\nexport const createReportBody = z.object({\n title: z.string().min(5).max(256),\n description: z.string().min(10).max(5000),\n steps_to_reproduce: z.string().max(3000).optional(),\n error_message: z.string().max(2000).optional(),\n\n // Taxonomy (server defaults: source=cli, classification=bug when absent).\n source: intakeReportSourceSchema.optional(),\n classification: reportClassificationSchema.optional(),\n // Stable dedup key (e.g. \"<file>::<test>\" for flaky, \"<file>:<line>\" for\n // security). When present, the fingerprint uses it instead of the body hash.\n dedup_key: z.string().min(1).max(256).optional(),\n\n // Context fields (auto-captured by the CLI)\n organization_id: z.string().optional(),\n hub_id: z.string().uuid().optional(),\n hub_name: z.string().max(256).optional(),\n conversation_id: z.string().uuid().optional(),\n agent_id: z.string().uuid().optional(),\n agent_name: z.string().max(256).optional(),\n client_version: z.string().max(64).optional(),\n additional_context: z.string().max(2000).optional(),\n});\nexport type CreateReportBody = z.infer<typeof createReportBody>;\n\nexport interface CreateReportResponse {\n report_id: string;\n status: ReportStatus;\n /** True if this submission created a new row; false if it merged into an existing fingerprint. */\n created: boolean;\n}\n\n// =============================================================================\n// EDIT — PATCH /api/reports/:id (reporter) and PATCH /api/admin/reports/:id (admin)\n//\n// Amends the mutable content fields of an already-filed report. The fields live\n// inside `raw_payload`; the dedup `fingerprint` is FROZEN at creation and is\n// never recomputed on edit (editing the same 5 fields the fingerprint hashes\n// would otherwise let an edit collide with another row's fingerprint or silently\n// change the dedup identity). `.strict()` so nothing outside these 5 keys can\n// reach the merge; `.refine` rejects a no-op edit (empty body). The 3 optional\n// fields accept an empty string to clear them (stored as null, matching create).\n// =============================================================================\n\nexport const editReportBody = z\n .object({\n title: z.string().min(5).max(256).optional(),\n description: z.string().min(10).max(5000).optional(),\n steps_to_reproduce: z.string().max(3000).optional(),\n error_message: z.string().max(2000).optional(),\n additional_context: z.string().max(2000).optional(),\n })\n .strict()\n .refine((b) => Object.keys(b).length > 0, {\n message: 'at least one field must be provided',\n });\nexport type EditReportBody = z.infer<typeof editReportBody>;\n\nexport interface EditReportResponse {\n report_id: string;\n status: ReportStatus;\n /** Epoch ms of this edit (also stamped on the row's edited_at column). */\n edited_at: number | null;\n /** The merged content blob after the edit. */\n raw_payload: unknown;\n}\n\n// =============================================================================\n// REPORTER — read-back + verification loop (own `cli` reports only)\n//\n// GET /api/reports — list the caller's own reports\n// GET /api/reports/:id — one own report + its message thread\n// POST /api/reports/:id/accept — shipped → addressed (accept the fix)\n// POST /api/reports/:id/contest — {shipped|dismissed} → contested (reason required)\n//\n// The reporter-facing summary deliberately WITHHOLDS internal fields (`gh_issue_url`,\n// `ai_verdict`) — the private GitHub URL is never surfaced to a reporter (same discipline as\n// the escalation email), and triage's internal reasoning stays internal. Reporter-facing\n// narrative (fixer's shipped note, dismissal reason, contest reasons, system notices) lives\n// in the `messages` thread.\n// =============================================================================\n\nexport interface ReporterReportSummary {\n report_id: string;\n classification: ReportClassification;\n status: ReportStatus;\n created_at: number;\n triaged_at: number | null;\n resolved_at: number | null;\n /** How many times the reporter has contested (gates the hard cap). */\n contest_count: number;\n /** True once triage issued a non-contestable (final) dismissal. */\n dismissal_final: boolean;\n}\n\nexport interface ReporterListResponse {\n data: ReporterReportSummary[];\n}\n\nexport interface GetReportResponse {\n report: ReporterReportSummary;\n messages: ReportMessage[];\n}\n\n/** Returned by /accept and /contest — the updated reporter-facing summary. */\nexport interface ReporterTransitionResponse {\n report: ReporterReportSummary;\n}\n\nexport const contestReportBody = z.object({\n reason: z.string().min(1).max(1000),\n});\nexport type ContestReportBody = z.infer<typeof contestReportBody>;\n\nexport const reporterListQuery = z.object({\n status: reportStatusSchema.optional(),\n});\nexport type ReporterListQuery = z.infer<typeof reporterListQuery>;\n\n// Hard cap on reporter contests (across both fix- and dismissal-disputes). Once\n// `contest_count` reaches this, the next contest is refused (409) and the report is flagged\n// for human routing — this is what bounds the converge loop now that `dismissed` is\n// contestable. Shared so the route, the DO-adjacent logic, and tests agree on one number.\nexport const REPORT_CONTEST_CAP = 3;\n\n// =============================================================================\n// ADMIN — read views\n// =============================================================================\n\nexport const listReportsQuery = z.object({\n status: reportStatusSchema.optional(),\n source: reportSourceSchema.optional(),\n limit: z.coerce.number().int().min(1).max(200).optional(),\n offset: z.coerce.number().int().min(0).optional(),\n /** ISO 8601 lower bound on created_at. */\n since: z.string().datetime().optional(),\n});\nexport type ListReportsQuery = z.infer<typeof listReportsQuery>;\n\nexport interface AdminReportSummary {\n report_id: string;\n source: ReportSource;\n classification: ReportClassification;\n status: ReportStatus;\n fingerprint: string;\n group_id: string | null;\n gh_issue_url: string | null;\n ai_verdict: string | null;\n dismissal_reason: string | null;\n /** Live-Sentry cross-check result for sentry-sourced reports (set at escalation). Null otherwise. */\n sentry_ref_status: SentryRefStatus | null;\n user_id: string | null;\n org_id: string | null;\n reporter_email: string | null;\n reporter_locale: string | null;\n created_at: number;\n triaged_at: number | null;\n resolved_at: number | null;\n /** Set when a content edit amended this report; null if never edited. */\n edited_at: number | null;\n /** user_id of the last editor (reporter or platform admin); null if never edited. */\n edited_by: string | null;\n /** Times the reporter contested a fix or dismissal (gates the hard cap). */\n contest_count: number;\n /** True once triage issued a non-contestable (final) dismissal. */\n dismissal_final: boolean;\n /** Times triage held (deferred) this row by a cycle — the explicit \"how many cycles\" signal. */\n hold_count: number;\n /** Epoch ms of the most recent hold; null if never held. */\n last_held_at: number | null;\n}\n\nexport interface AdminReportDetail extends AdminReportSummary {\n raw_payload: unknown;\n group_members: AdminReportSummary[];\n notified_at_escalated: number | null;\n notified_at_addressed: number | null;\n notified_at_dismissed: number | null;\n notified_at_shipped: number | null;\n /** Reporter-facing narrative thread (also visible to admins). */\n messages: ReportMessage[];\n}\n\nexport interface AdminReportListResponse {\n data: AdminReportSummary[];\n total: number;\n}\n\n// =============================================================================\n// ADMIN — mutations (state-machine RPC)\n// =============================================================================\n\n// z.string().url() accepts `javascript:` — constrain to https://github.com/<owner>/<repo>/issues/<N> for email-safe href.\nexport const GITHUB_ISSUE_URL_REGEX = /^https:\\/\\/github\\.com\\/[^/]+\\/[^/]+\\/issues\\/\\d+(?:[/?#]|$)/;\nconst githubIssueUrlSchema = z\n .string()\n .url()\n .refine((u) => GITHUB_ISSUE_URL_REGEX.test(u), {\n message: 'must be an https://github.com/<owner>/<repo>/issues/<number> URL',\n });\n\n// Admin /transition surface (triage + fixer). Note: `contested` is intentionally absent —\n// only the reporter sets it, via the dedicated reporter-owned /accept and /contest endpoints\n// (a reporter MUST NOT reach the admin adjudication targets). `shipped` is the fixer's\n// hand-back with a reporter-facing `note`; `final` makes a dismissal non-contestable.\nexport const transitionReportBody = z.discriminatedUnion('target', [\n z.object({\n target: z.literal('escalated'),\n gh_issue_url: githubIssueUrlSchema,\n ai_verdict: z.string().max(500).optional(),\n }),\n z.object({\n target: z.literal('shipped'),\n note: z.string().min(1).max(2000).optional(),\n }),\n z.object({\n target: z.literal('addressed'),\n }),\n z.object({\n target: z.literal('dismissed'),\n dismissal_reason: z.string().min(1).max(1000),\n ai_verdict: z.string().max(500).optional(),\n final: z.boolean().optional(),\n }),\n]);\nexport type TransitionReportBody = z.infer<typeof transitionReportBody>;\n\nexport interface TransitionReportResponse {\n report: AdminReportSummary;\n cascaded_report_ids: string[];\n}\n\nexport const groupReportsBody = z.object({\n member_ids: z.array(z.string().uuid()).min(1).max(100),\n});\nexport type GroupReportsBody = z.infer<typeof groupReportsBody>;\n\n/**\n * A member that could not be absorbed into the group, with the reason:\n * - `not_found` — member id does not exist\n * - `terminal` — member is already `addressed`/`dismissed` (detail = the status)\n * - `grouped_elsewhere` — member already belongs to another canonical (detail = its group_id)\n * - `different_gh_issue` — member is linked to a GitHub issue other than the\n * canonical's (detail = the member's gh_issue_url); absorbing it would orphan that issue\n */\nexport interface GroupReportSkip {\n report_id: string;\n reason: 'not_found' | 'terminal' | 'grouped_elsewhere' | 'different_gh_issue';\n detail?: string;\n}\n\nexport interface GroupReportsResponse {\n canonical_id: string;\n grouped: number;\n skipped: GroupReportSkip[];\n}\n\n// =============================================================================\n// ADMIN — ungroup (detach a grouped member, inverse of group)\n// =============================================================================\n\n/**\n * Response for POST /api/admin/reports/:id/ungroup. The detached member is\n * returned to `pending` with its `group_id` cleared. Note: grouping cleared the\n * member's `gh_issue_url` (the canonical owns the issue), so detach cannot\n * restore it — the member re-enters triage as if freshly filed.\n */\nexport interface UngroupReportResponse {\n report: AdminReportSummary;\n}\n\n// =============================================================================\n// ADMIN — hold (defer a decision one triage cycle)\n//\n// Records \"I looked at this `pending` row and chose to wait one more cycle\" without\n// transitioning it: bumps `hold_count` + `last_held_at` (the explicit cycle counter) and\n// appends a triage-internal note (the rationale) to the message thread. Silent for ALL\n// sources — never emails, even a `cli` row — and the note is internal (reporter never sees\n// it). The reason is required: a hold with no recorded rationale defeats the purpose.\n// =============================================================================\n\nexport const holdReportBody = z.object({\n reason: z.string().min(1).max(1000),\n});\nexport type HoldReportBody = z.infer<typeof holdReportBody>;\n\nexport interface HoldReportResponse {\n report: AdminReportSummary;\n}\n\n// =============================================================================\n// REPORT TRANSITION STATE MACHINE — validity matrix (single source of truth)\n// =============================================================================\n\nexport type ReportTransitionTarget =\n | 'escalated'\n | 'shipped'\n | 'contested'\n | 'addressed'\n | 'dismissed';\n\n// Statuses from which a given target is a hard reject (operator error). Excludes\n// idempotent no-ops (target already reached, or escalate-from-addressed), which\n// `transitionReport` short-circuits to a no-op rather than rejecting. Mirrors the\n// branch guards in `PlatformDO.transitionReport` — kept here as the one place\n// both the route (to return a clean 4xx) and the DO (as a backstop) agree on.\n//\n// Allowed (non-reject, non-no-op) sources per target, for the agent-interactive loop:\n// escalated ← pending (first triage) · contested (triage re-escalates); addressed is an\n// idempotent no-op (not a real re-escalation)\n// shipped ← escalated (fixer marks the fix shipped)\n// contested ← shipped (reporter rejects the fix) · dismissed (reporter disputes the dismissal)\n// addressed ← escalated (non-cli auto-close) · shipped (reporter accepts) · contested (triage agrees)\n// dismissed ← pending (untriaged) · escalated (false-positive) · contested (dispute rejected)\nconst REPORT_TRANSITION_REJECT: Record<ReportTransitionTarget, ReadonlySet<ReportStatus>> = {\n escalated: new Set<ReportStatus>(['grouped', 'shipped', 'dismissed']),\n shipped: new Set<ReportStatus>(['pending', 'grouped', 'contested', 'addressed', 'dismissed']),\n contested: new Set<ReportStatus>(['pending', 'grouped', 'escalated', 'addressed']),\n addressed: new Set<ReportStatus>(['pending', 'grouped', 'dismissed']),\n dismissed: new Set<ReportStatus>(['grouped', 'shipped', 'addressed']),\n};\n\n/**\n * Returns an operator-facing rejection message if transitioning a report in\n * `status` to `target` is invalid, or `null` if it is allowed (including\n * idempotent no-ops). Pure — no I/O. The route throws ConflictError(409) on a\n * non-null result so an invalid transition surfaces as a clean 4xx instead of a\n * 500 (a plain Error thrown inside the DO loses its AppError brand across RPC).\n */\nexport function getReportTransitionRejection(\n report: { status: ReportStatus; group_id?: string | null },\n target: ReportTransitionTarget,\n): string | null {\n if (!REPORT_TRANSITION_REJECT[target].has(report.status)) return null;\n if (report.status === 'grouped') {\n const ref = report.group_id ? ` under ${report.group_id}` : '';\n return (\n `Report is grouped${ref} and cannot be ${target} directly. ` +\n `Detach it first (\\`wayai admin report ungroup <id>\\`), or transition the ` +\n `canonical so the outcome cascades to its members.`\n );\n }\n return `Report cannot be ${target} from status '${report.status}'.`;\n}\n\n// =============================================================================\n// REPORT EDIT — non-terminal-state gate (single source of truth)\n// =============================================================================\n\nexport type ReportEditRole = 'reporter' | 'admin';\n\n// Statuses from which a content edit is allowed, by role. A reporter may only\n// fix their report before triage (`pending`); once it has been escalated into a\n// GitHub issue, only a platform admin may refine it (`escalated`). `grouped`\n// (duplicate, subsumed by a canonical) and the terminal states are frozen for\n// everyone. The DO uses the `admin` set as its data-integrity backstop — the\n// per-role narrowing is the route's authorization concern.\nconst REPORT_EDITABLE_STATUSES: Record<ReportEditRole, ReadonlySet<ReportStatus>> = {\n reporter: new Set<ReportStatus>(['pending']),\n admin: new Set<ReportStatus>(['pending', 'escalated']),\n};\n\n/**\n * Returns an operator-facing rejection message if editing a report in `status`\n * is not allowed for `role`, or `null` if the edit is permitted. Pure — no I/O.\n * Both edit routes throw ConflictError(409) on a non-null result; the DO's\n * `editReportContent` calls it with role `'admin'` (most permissive) as a\n * backstop so a terminal/grouped row can never be mutated at the data layer.\n */\nexport function getReportEditRejection(\n report: { status: ReportStatus; group_id?: string | null },\n role: ReportEditRole,\n): string | null {\n if (REPORT_EDITABLE_STATUSES[role].has(report.status)) return null;\n if (report.status === 'grouped') {\n const ref = report.group_id ? ` under ${report.group_id}` : '';\n return (\n `Report is grouped${ref} and cannot be edited directly. ` +\n `Detach it first (\\`wayai admin report ungroup <id>\\`) or edit the canonical.`\n );\n }\n if (role === 'reporter' && report.status === 'escalated') {\n return (\n `Report has been escalated to a GitHub issue and can no longer be edited ` +\n `by the reporter; contact a platform admin to refine it.`\n );\n }\n return `Report cannot be edited from status '${report.status}'.`;\n}\n\n// =============================================================================\n// REPORT HOLD — defer-one-cycle gate (single source of truth)\n// =============================================================================\n\n// A hold only makes sense before the first triage decision: it defers escalate/dismiss by a\n// cycle. Once a row has moved past `pending` (grouped under a canonical, escalated into an\n// issue, in the agent-interactive loop, or terminal) there is no \"wait one cycle\" decision left\n// to defer — re-adjudicate it through the proper transition instead.\nconst REPORT_HOLDABLE_STATUSES: ReadonlySet<ReportStatus> = new Set<ReportStatus>(['pending']);\n\n/**\n * Returns an operator-facing rejection message if a `pending`-only hold is not allowed for a\n * report in `status`, or `null` if the hold is permitted. Pure — no I/O. The route throws\n * ConflictError(409) on a non-null result; the DO's `holdReport` calls it as a data-integrity\n * backstop so a non-pending row can never accrue a phantom hold.\n */\nexport function getReportHoldRejection(report: { status: ReportStatus; group_id?: string | null }): string | null {\n if (REPORT_HOLDABLE_STATUSES.has(report.status)) return null;\n if (report.status === 'grouped') {\n const ref = report.group_id ? ` under ${report.group_id}` : '';\n return (\n `Report is grouped${ref} and cannot be held — it is a duplicate subsumed by its canonical. ` +\n `Hold (or transition) the canonical instead.`\n );\n }\n return `Report cannot be held from status '${report.status}' — hold only defers a 'pending' row by a cycle.`;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// ClickHouse readiness probe\n// ---------------------------------------------------------------------------\n\n/**\n * Polled by the frontend cold-start banner while it believes CH is cold.\n * `ready: true` means a fresh `SELECT 1` succeeded (or was cached via KV for\n * 60s); `ready: false` means the probe aborted or errored. Once the banner\n * sees `ready: true` it dispatches a `clickhouse:warm` event so data\n * consumers refetch.\n */\nexport const clickhouseReadyResponse = z.object({\n ready: z.boolean(),\n});\n\nexport type ClickHouseReadyResponse = z.infer<typeof clickhouseReadyResponse>;\n","import { z } from 'zod';\nimport type {\n ConversationItemResponse,\n HubItemResponse,\n MessageItemResponse,\n AvailableTaskHub,\n} from './chat';\nimport type { NavigationCounts } from './live-updates';\nimport type { UserDataResponse } from './users';\nimport type { HubAlert } from './hub-alerts';\nimport type { PlatformNotice } from './notices';\n\n// ---------------------------------------------------------------------------\n// GET /users/me/bootstrap — query\n// ---------------------------------------------------------------------------\n\n/**\n * Bootstrap query — optional active URL hints resolved by the RSC.\n *\n * Route-level RSC parses the current URL (e.g. /chat/[hubId]/[conversationId])\n * and passes hints to the backend so the snapshot can pre-load the active\n * conversation's first-page messages.\n */\nexport const bootstrapQuery = z.object({\n active_hub_id: z.string().uuid().optional(),\n active_conversation_id: z.string().uuid().optional(),\n active_nav: z.enum(['chat', 'task', 'support']).optional(),\n});\n\nexport type BootstrapQuery = z.infer<typeof bootstrapQuery>;\n\n// ---------------------------------------------------------------------------\n// WebSocket — request_snapshot_chunk (cursor-paged follow-up)\n// ---------------------------------------------------------------------------\n\nexport const requestSnapshotChunkMessage = z.object({\n type: z.literal('request_snapshot_chunk'),\n cursor: z.string(),\n});\n\nexport type RequestSnapshotChunkMessage = z.infer<typeof requestSnapshotChunkMessage>;\n\n// ---------------------------------------------------------------------------\n// Response shape — shared between HTTP (/bootstrap) and WS (session_snapshot)\n// ---------------------------------------------------------------------------\n\n/**\n * Per-nav conversation slice. Arrays so the RSC-serialized payload crosses\n * the Next.js boundary without Map serialization issues; client hydrator\n * feeds these into Zustand Map setters.\n */\nexport interface SessionSnapshotConversations {\n chat: ConversationItemResponse[];\n task: ConversationItemResponse[];\n support: ConversationItemResponse[];\n}\n\n/**\n * Active conversation pre-loaded by the RSC. Present only when the URL\n * resolved to a specific conversation the user has access to.\n */\nexport interface SessionSnapshotActiveConversation {\n conversation: ConversationItemResponse;\n messages: MessageItemResponse[];\n}\n\n/**\n * Per-user session snapshot. Built once in\n * `workers/backend/src/live-updates/session-snapshot.ts` and consumed by both:\n * - HTTP: `GET /api/users/me/bootstrap` (RSC first paint)\n * - WS: `LiveUpdateSession.getSessionSnapshot()` RPC (on auth_ok)\n */\nexport interface SessionSnapshot {\n user: UserDataResponse;\n hubs: HubItemResponse[];\n available_task_hubs: AvailableTaskHub[];\n conversations: SessionSnapshotConversations;\n active_conversation: SessionSnapshotActiveConversation | null;\n nav_counts: NavigationCounts;\n /**\n * Maps hub_id → the viewer's hub-scoped user_id (PK of HubDO's local `user`\n * table) for each hub where the viewer is an end user. Optional: a Worker\n * that predates this field omits it. Hubs with no resolvable\n * `hub_user.user_id` are absent from the map.\n */\n hub_user_ids_by_hub?: Record<string, string>;\n /**\n * Hub ids where the viewer has team/admin (support) access — i.e. the\n * `teamHubIds` set the builder uses for the support scope. Drives the live\n * update path's per-recipient `source_navs` inference (a recipient adds\n * `'support'` membership for a conversation whose hub is in this set).\n * Optional: a Worker that predates this field omits it.\n */\n support_hub_ids?: string[];\n /**\n * Active Status & Notices hub-health alerts across the hubs the viewer admins\n * (hub-local + org-derived union, body-free, each stamped with `hub_id`). Seeds the\n * app-shell banner + the cross-hub aggregate without a separate fetch — \"always\n * live\". Optional: a Worker that predates this field omits it.\n *\n * NOTE: a shared org credential backing M connections in one hub yields M entries\n * with the SAME `alert_id` (distinct `connection_id`) — the fan-out that surfaces the\n * one org alert against each linking connection. Consumers MUST key by the composite\n * `${alert_id}:${connection_id}` (not `alert_id` alone), as the Status tab does.\n */\n active_alerts?: HubAlert[];\n /**\n * Active platform broadcasts (Status & Notices feed 2) visible to this viewer —\n * `global`-scoped, within their display window, minus the ones they've acknowledged.\n * The same set `GET /api/notices` returns; seeds the notice banner + the account\n * aggregate without a separate fetch (\"always live\"). Optional: a Worker that\n * predates this field omits it. Consumers key by `notice_id`.\n */\n active_notices?: PlatformNotice[];\n /**\n * Serialized size ceiling guard — when the full payload exceeds the\n * snapshot size budget, the builder paginates via cursor. `null` = done.\n */\n cursor: string | null;\n}\n\nexport interface BootstrapResponse {\n success: true;\n data: SessionSnapshot;\n}\n\n// ---------------------------------------------------------------------------\n// WebSocket — session_snapshot message (emitted after auth_ok)\n// ---------------------------------------------------------------------------\n\nexport interface SessionSnapshotMessage {\n type: 'session_snapshot';\n payload: SessionSnapshot;\n}\n","import { z } from 'zod';\nimport { idParamSchema } from './common';\n\nconst MAX_NAME_LENGTH = 100;\nconst MAX_VALUE_LENGTH = 32 * 1024; // 32 Ki UTF-16 code units\nconst MAX_TAGS = 20;\nconst MAX_TAG_LENGTH = 50;\nconst MAX_SCOPE_HUBS = 100;\nconst MAX_SCOPE_TAGS = 50;\n\nexport const vaultSecretScopeSchema = z.object({\n hubs: z.array(z.string().min(1)).max(MAX_SCOPE_HUBS).optional(),\n tags: z.array(z.string().min(1).max(MAX_TAG_LENGTH)).max(MAX_SCOPE_TAGS).optional(),\n}).strict();\n\nexport const vaultCreateBody = z.object({\n name: z.string().trim().min(1, 'name is required').max(MAX_NAME_LENGTH, `name must be ${MAX_NAME_LENGTH} characters or fewer`),\n value: z.string().min(1, 'value is required').max(MAX_VALUE_LENGTH, `value must be ${MAX_VALUE_LENGTH} characters or fewer`),\n tags: z.array(z.string().min(1).max(MAX_TAG_LENGTH, `Tag must be ${MAX_TAG_LENGTH} characters or fewer`)).max(MAX_TAGS, `Maximum ${MAX_TAGS} tags allowed`).optional().default([]),\n scope: vaultSecretScopeSchema.optional().default({}),\n}).strict();\n\nexport const vaultUpdateBody = z.object({\n name: z.string().trim().min(1).max(MAX_NAME_LENGTH).optional(),\n value: z.string().min(1).max(MAX_VALUE_LENGTH).optional(),\n tags: z.array(z.string().min(1).max(MAX_TAG_LENGTH)).max(MAX_TAGS).optional(),\n scope: vaultSecretScopeSchema.optional(),\n}).strict();\n\nexport const vaultIdParam = idParamSchema;\n\nexport type VaultCreateBody = z.infer<typeof vaultCreateBody>;\nexport type VaultUpdateBody = z.infer<typeof vaultUpdateBody>;\nexport type VaultIdParam = z.infer<typeof vaultIdParam>;\n\nexport const VAULT_LIMITS = {\n MAX_NAME_LENGTH,\n MAX_VALUE_LENGTH,\n MAX_TAGS,\n MAX_TAG_LENGTH,\n MAX_SCOPE_HUBS,\n MAX_SCOPE_TAGS,\n} as const;\n","import { z } from 'zod';\nimport { PERMISSIONS } from '../auth/permissions';\nimport { idParamSchema, uuidSchema } from './common';\n\nconst MAX_NAME_LENGTH = 100;\nconst MAX_HUBS_PER_GRANT = 50;\nconst MAX_HUB_TAGS_PER_GRANT = 20;\nconst MAX_GRANTS = 20;\n\nconst permissionEnum = z.enum(PERMISSIONS).refine(\n (p) => p !== 'platform:admin',\n { message: 'platform:admin cannot be delegated via token creation' },\n);\n\nconst grantScopeSchema = z.object({\n // Required: every token grant must declare its org tenancy. The handler\n // also strict-checks this as defense-in-depth, but failing at the Zod\n // boundary keeps the generated client type honest (org_id: string).\n org_id: z.string().min(1),\n hubs: z.array(z.string().min(1)).min(1, 'Each grant must have scope.hubs as a non-empty array').max(MAX_HUBS_PER_GRANT),\n hub_tags: z.array(z.string().min(1)).min(1, 'scope.hub_tags must be a non-empty array if provided').max(MAX_HUB_TAGS_PER_GRANT).optional(),\n environments: z.array(z.enum(['production', 'preview'])).min(1, 'scope.environments must be a non-empty array if provided').optional(),\n}).strict();\n\nconst grantSchema = z.object({\n scope: grantScopeSchema,\n permissions: z.array(permissionEnum).min(1, 'Each grant must have permissions as a non-empty array'),\n}).strict();\n\nexport const createTokenBody = z.object({\n name: z.string().trim().min(1, 'name is required').max(MAX_NAME_LENGTH, `name must be ${MAX_NAME_LENGTH} characters or fewer`),\n grants: z.array(grantSchema).min(1, 'grants must be a non-empty array').max(MAX_GRANTS),\n expires_at: z.string().datetime({ message: 'expires_at must be a valid ISO 8601 date' }).refine(\n (s) => new Date(s).getTime() > Date.now(),\n { message: 'expires_at must be in the future' },\n ).optional(),\n});\n\nexport const tokenIdParam = idParamSchema;\n\n// Governance route param. NOT idParamSchema / setup's orgIdParam (both key\n// `id`); the route segment is `:orgId`, so the param bag must carry `orgId`.\nexport const tokenOrgIdParam = z.object({ orgId: uuidSchema });\n\n// --- Response contracts ---------------------------------------------------\n// Stored/returned grants always carry a concrete scope.org_id (the create\n// handler strictly requires it before persisting).\nconst tokenGrantScopeSchema = z.object({\n org_id: z.string().min(1),\n hubs: z.array(z.string().min(1)).min(1),\n hub_tags: z.array(z.string().min(1)).min(1).optional(),\n environments: z.array(z.enum(['production', 'preview'])).min(1).optional(),\n});\n\nexport const tokenGrantSchema = z.object({\n scope: tokenGrantScopeSchema,\n permissions: z.array(z.enum(PERMISSIONS)).min(1),\n});\n\nexport const tokenMetadataSchema = z.object({\n token_id: z.string(),\n name: z.string(),\n token_prefix: z.string(),\n grants: z.array(tokenGrantSchema),\n created_at: z.string(),\n expires_at: z.string().optional(),\n last_used_at: z.string().optional(),\n});\n\nexport const listTokensResponse = z.object({\n data: z.array(tokenMetadataSchema),\n});\n\nexport const createTokenResponse = z.object({\n data: z.object({\n token: z.string(),\n token_id: z.string(),\n name: z.string(),\n expires_at: z.string().optional(),\n }),\n});\n\nexport const orgTokenSummarySchema = z.object({\n token_id: z.string(),\n name: z.string(),\n token_prefix: z.string(),\n owner_user_id: z.string(),\n created_at: z.string(),\n expires_at: z.string().optional(),\n last_used_at: z.string().optional(),\n grants_for_org: z.array(tokenGrantSchema),\n});\n\nexport const listOrgTokensResponse = z.object({\n data: z.array(orgTokenSummarySchema),\n});\n\nexport type CreateTokenBody = z.infer<typeof createTokenBody>;\nexport type TokenIdParam = z.infer<typeof tokenIdParam>;\nexport type TokenOrgIdParam = z.infer<typeof tokenOrgIdParam>;\nexport type TokenGrant = z.infer<typeof tokenGrantSchema>;\nexport type TokenMetadata = z.infer<typeof tokenMetadataSchema>;\nexport type OrgTokenSummary = z.infer<typeof orgTokenSummarySchema>;\n\nexport const TOKEN_LIMITS = {\n MAX_NAME_LENGTH,\n MAX_HUBS_PER_GRANT,\n MAX_HUB_TAGS_PER_GRANT,\n MAX_GRANTS,\n} as const;\n","/**\n * WayAI permission types and auth context definitions.\n *\n * Permissions follow the pattern `resource:action`.\n * Grants use scope-based matching with OR semantics for hub_tags.\n *\n * User types and org requirements:\n * - Platform Admin: needs org, has `platform:admin` permission\n * - Org Owner/Admin: needs org, org-scoped grants with `org:admin`\n * - Hub Admin: org-scoped, has `hub:admin` on specific hubs\n * - Hub Team User: NO org needed, hub-scoped grants only\n * - Hub End User: NO org needed, hub-scoped grants only\n */\n\nexport const PERMISSIONS = [\n 'hub:read',\n 'hub:write',\n 'hub:admin',\n 'conversation:read',\n 'conversation:write',\n 'analytics:read',\n 'billing:read',\n 'billing:write',\n 'org:read',\n 'org:write',\n 'org:admin',\n 'platform:admin',\n '*',\n] as const;\n\nexport type Permission = (typeof PERMISSIONS)[number];\n\n/** All user-level permissions — excludes `'*'` (superuser) and `'platform:admin'`. */\nexport const USER_PERMISSIONS: Permission[] = [\n 'hub:read',\n 'hub:write',\n 'hub:admin',\n 'conversation:read',\n 'conversation:write',\n 'analytics:read',\n 'billing:read',\n 'billing:write',\n 'org:read',\n 'org:write',\n 'org:admin',\n];\n\n/** Hub-admin-only permissions — for users who admin a hub but are NOT org members. */\nexport const HUB_ADMIN_PERMISSIONS: Permission[] = [\n 'hub:read',\n 'hub:write',\n 'hub:admin',\n 'conversation:read',\n 'conversation:write',\n 'analytics:read',\n];\n\nexport interface Grant {\n scope: {\n /** Organization this grant applies to. undefined = unscoped (hub-only users). */\n org_id?: string;\n /** Hub IDs this grant applies to. ['*'] = all hubs in the org. */\n hubs: string[];\n /**\n * Hub tags for tag-based scoping (replaces project grouping).\n * OR matching: user has access if hub has ANY of these tags.\n * To require multiple tags, use separate grants.\n */\n hub_tags?: string[];\n /** Environment filter. undefined = all environments. */\n environments?: ('production' | 'preview')[];\n };\n permissions: Permission[];\n}\n\nexport interface AuthContext {\n /** Platform org ID. Optional — hub-only users (end users, team users) don't have one. */\n org_id?: string;\n /** WorkOS user ID. Present for human sessions, absent for service tokens. */\n user_id?: string;\n /** User email. Present for human sessions (set during auth key generation). */\n email?: string;\n /** WorkOS session id (sid). Present for sessions minted from an authenticated browser/CLI login. */\n session_id?: string;\n /** Scoped API token id. Present only when caller authenticated with a `way_` token. */\n token_id?: string;\n /** Parent token expiry (ISO 8601). Present only when the `way_` parent has a finite lifetime; used to cap child expiries. */\n token_expires_at?: string;\n grants: Grant[];\n}\n\n/**\n * Parse the comma-separated PLATFORM_ADMIN_EMAILS env var into a deduplicated\n * lowercase list. Shared by `checkPlatformAdminEmail` and live-update\n * recipient resolution so the membership boundary can't drift between them.\n */\nexport function parsePlatformAdminEmails(raw: string | undefined): string[] {\n if (!raw) return [];\n return Array.from(\n new Set(raw.split(',').map((e) => e.trim().toLowerCase()).filter(Boolean)),\n );\n}\n\n/**\n * Check if an email matches PLATFORM_ADMIN_EMAILS env var.\n * Case-insensitive, filters empty entries from trailing commas.\n * Returns false if either argument is falsy.\n */\nexport function checkPlatformAdminEmail(email: string | undefined, platformAdminEmails: string | undefined): boolean {\n if (!email || !platformAdminEmails) return false;\n return parsePlatformAdminEmails(platformAdminEmails).includes(email.toLowerCase());\n}\n","import { z } from 'zod';\n\n// =============================================================================\n// INVITE PREVIEW — GET /api/invites/preview\n// Public (unauthenticated) endpoint. Returns enough display info for the signup\n// page to render personalized copy. Does NOT echo the invitee's email back —\n// the user just opened their email at that address, no need to reflect it,\n// and not echoing reduces leakage if the URL ends up in browser history,\n// referrer logs, or client-side telemetry.\n// =============================================================================\n\nexport const invitePreviewQuery = z.object({\n token: z.string().min(1).max(2048),\n});\n\nexport const invitePreviewResponse = z.object({\n inviter_name: z.string(),\n entity_id: z.string().uuid(),\n entity_name: z.string(),\n entity_type: z.enum(['org', 'hub']),\n role: z.enum(['org_admin', 'admin', 'team_user', 'user']),\n expires_at: z.string().datetime(),\n});\n\nexport type InvitePreviewResponse = z.infer<typeof invitePreviewResponse>;\n","import { z } from 'zod';\n\n// =============================================================================\n// Discord Linked Roles — tier/cycle/admin metadata pushed to Discord\n// =============================================================================\n\nexport const discordTier = z.enum(['free', 'pro', 'pro_plus']);\nexport type DiscordTier = z.infer<typeof discordTier>;\n\nexport const discordBillingCycle = z.enum(['monthly', 'annual']);\nexport type DiscordBillingCycle = z.infer<typeof discordBillingCycle>;\n\nexport const discordMetadata = z.object({\n tier: discordTier,\n billing_cycle: discordBillingCycle,\n is_admin: z.boolean(),\n});\nexport type DiscordMetadata = z.infer<typeof discordMetadata>;\n\n// =============================================================================\n// GET /api/discord/oauth/start\n// =============================================================================\n\nexport const discordOAuthStartResponse = z.object({\n url: z.string().url(),\n});\nexport type DiscordOAuthStartResponse = z.infer<typeof discordOAuthStartResponse>;\n\n// =============================================================================\n// POST /api/discord/oauth/finalize\n// =============================================================================\n\nexport const discordOAuthFinalizeBody = z.object({\n code: z.string().min(1, 'code is required'),\n state: z.string().min(1, 'state is required'),\n});\nexport type DiscordOAuthFinalizeBody = z.infer<typeof discordOAuthFinalizeBody>;\n\n/**\n * Finalize returns 200 in two shapes:\n * - `{ ok: true, … }` — link stored + metadata pushed to Discord successfully\n * - `{ ok: false, push_error, metadata }` — link stored, but Discord rejected\n * the metadata push. The link persists; the next admin-grant change or\n * Stripe webhook will retry. Frontend renders an error variant.\n *\n * 4xx responses indicate the link was NOT stored (bad_state, user_mismatch,\n * etc.) and use the standard ApiErrorResponse shape.\n */\nexport const discordOAuthFinalizeResponse = z.discriminatedUnion('ok', [\n z.object({\n ok: z.literal(true),\n discord_user_id: z.string(),\n metadata: discordMetadata,\n }),\n z.object({\n ok: z.literal(false),\n push_error: z.literal('discord_unreachable'),\n metadata: discordMetadata,\n }),\n]);\nexport type DiscordOAuthFinalizeResponse = z.infer<typeof discordOAuthFinalizeResponse>;\n\n// =============================================================================\n// POST /api/discord/disconnect\n// =============================================================================\n\nexport const discordDisconnectResponse = z.object({\n ok: z.literal(true),\n});\nexport type DiscordDisconnectResponse = z.infer<typeof discordDisconnectResponse>;\n","import { z } from 'zod';\nimport { slugSchema } from './setup/slug';\n\n// ---------------------------------------------------------------------------\n// User Context Panel — admin-facing identity + state inspection/mutation.\n// ---------------------------------------------------------------------------\n\n// A JSON Schema describing a state's shape. Kept as `record(z.unknown())`\n// because the panel renders it as JSON (we don't constrain user-authored\n// schemas here).\nconst jsonSchemaSchema = z.record(z.unknown());\n\n// Identity is sourced from the `user` table (the conversation's end user).\n// hub_user-only fields (hub_user_id, enabled, hub_team_id, source) are present\n// only when an access-grant row exists (account-mode); optional otherwise.\nconst hubUserIdentity = z.object({\n user_id: z.string().nullable(),\n user_name: z.string().nullable(),\n user_email: z.string().nullable(),\n user_name_locked: z.boolean(),\n created_at: z.string(),\n updated_at: z.string().nullable(),\n hub_user_id: z.string().optional(),\n enabled: z.boolean().optional(),\n hub_team_id: z.string().nullable().optional(),\n source: z.enum(['grant', 'auto']).optional(),\n});\n\nconst stateValueEntry = z.object({\n state_slug: z.string(),\n state_name: z.string(),\n state_description: z.string().nullable().optional(),\n scope: z.enum(['user', 'conversation']),\n json_schema: jsonSchemaSchema,\n initial_value: z.unknown(),\n value: z.unknown(),\n is_reserved: z.boolean(),\n});\n\nexport const getHubUserContextResponse = z.object({\n user: hubUserIdentity,\n user_states: z.array(stateValueEntry),\n conversation_states: z.array(stateValueEntry),\n});\n\nexport type GetHubUserContextResponse = z.infer<typeof getHubUserContextResponse>;\nexport type HubUserIdentity = z.infer<typeof hubUserIdentity>;\nexport type StateValueEntry = z.infer<typeof stateValueEntry>;\n\nexport const updateHubUserBody = z.object({\n // Non-empty, non-null. `.nullable()` here would bypass `.min(1)` and let an\n // admin arm the lock on a null name — see hub-do.ts updateHubUser null-guard.\n user_name: z.string().min(1).max(120),\n});\n\nexport const updateHubUserResponse = z.object({\n user: hubUserIdentity,\n});\n\nexport type UpdateHubUserBody = z.infer<typeof updateHubUserBody>;\nexport type UpdateHubUserResponse = z.infer<typeof updateHubUserResponse>;\n\nexport const unlockHubUserNameResponse = z.object({\n user: hubUserIdentity,\n});\n\nexport type UnlockHubUserNameResponse = z.infer<typeof unlockHubUserNameResponse>;\n\nexport const stateResetParams = z.object({\n stateSlug: slugSchema,\n});\n\nexport const stateResetResponse = z.object({\n ok: z.literal(true),\n});\n\nexport type StateResetParams = z.infer<typeof stateResetParams>;\nexport type StateResetResponse = z.infer<typeof stateResetResponse>;\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Hub operational alerts (Status & Notices) — read surface.\n// GET /api/hubs/:hubId/alerts returns the hub's currently-active, tenant-actionable\n// connection/credential alerts. Never carries the provider error body (it can embed\n// a key fragment) — only provider + status_code + category + counts + timestamps.\n// ---------------------------------------------------------------------------\n\nexport const hubAlertsParam = z.object({\n hubId: z.string().uuid(),\n});\nexport type HubAlertsParam = z.infer<typeof hubAlertsParam>;\n\nexport const hubAlertSeverity = z.enum(['critical', 'warn', 'info']);\nexport type HubAlertSeverity = z.infer<typeof hubAlertSeverity>;\n\nexport const hubAlert = z.object({\n alert_id: z.string(),\n // The hub this alert belongs to — stamped at read time (the per-hub HubDO row\n // doesn't store it). Drives the banner/aggregate deep-link to the hub's Status tab.\n hub_id: z.string(),\n connection_id: z.string().nullable(),\n channel_id: z.string().nullable(),\n // Open string (not an enum): producers define categories as they're wired, and the\n // read surface must not reject a category that ships before this contract updates.\n category: z.string(),\n provider: z.string().nullable(),\n status_code: z.number().nullable(),\n severity: hubAlertSeverity,\n status: z.enum(['active', 'resolved']),\n count: z.number(),\n first_seen_at: z.string(),\n last_seen_at: z.string(),\n last_notified_at: z.string().nullable(),\n resolved_at: z.string().nullable(),\n // Set when this alert is rolled up at the shared org credential (one org_alert shown\n // against every hub linking it) — the fix lives at the org level, not the hub. Null\n // for hub-local alerts.\n org_credential_id: z.string().nullable(),\n});\nexport type HubAlert = z.infer<typeof hubAlert>;\n\nexport const hubAlertsListResponse = z.object({\n alerts: z.array(hubAlert),\n});\nexport type HubAlertsListResponse = z.infer<typeof hubAlertsListResponse>;\n","import { z } from 'zod';\n\n// =============================================================================\n// Platform notices (feed 2) — operator-authored broadcasts (\"Gemini degraded\",\n// \"Analytics delayed\"). Informational: the admin can't *act*, but needs to *know*\n// so they don't burn an hour assuming their setup broke. Authored by platform\n// admins; lives in PlatformDO `platform_notice`. Kept in sync with the DO schema\n// CHECK constraints.\n// =============================================================================\n\n// Severity — same vocabulary as hub alerts (anti banner-blindness): only\n// `critical` is a persistent banner; `warn`/`info` are quiet.\nexport const noticeSeveritySchema = z.enum(['critical', 'warn', 'info']);\nexport type NoticeSeverity = z.infer<typeof noticeSeveritySchema>;\n\nexport const noticeStatusSchema = z.enum(['active', 'resolved']);\nexport type NoticeStatus = z.infer<typeof noticeStatusSchema>;\n\n// Scope — who sees the broadcast. v1 authors `global` (everyone); `provider:<x>`\n// and `service:<x>` are accepted and stored opaquely now, resolved to recipients\n// at delivery time (a later slice). The regex is the security boundary: scope is\n// interpolated into recipient resolution, so it must be a constrained token.\nexport const NOTICE_SCOPE_REGEX = /^(global|provider:[a-z0-9_-]{1,40}|service:[a-z0-9_-]{1,40})$/;\nexport const noticeScopeSchema = z\n .string()\n .regex(NOTICE_SCOPE_REGEX, \"scope must be 'global', 'provider:<x>', or 'service:<x>'\");\n\n// `link` is rendered as an href in the banner — z.string().url() alone accepts\n// `javascript:`, so constrain to http(s) for a safe href.\nconst noticeLinkSchema = z\n .string()\n .url()\n .refine((u) => /^https?:\\/\\//i.test(u), { message: 'link must be an http(s) URL' });\n\n// The wire shape. Timestamps are ISO-8601 UTC strings (DO SQLite TEXT — same\n// representation end-to-end, per the timestamp convention).\nexport interface PlatformNotice {\n notice_id: string;\n severity: NoticeSeverity;\n scope: string;\n title: string;\n body: string | null;\n link: string | null;\n status: NoticeStatus;\n starts_at: string;\n ends_at: string | null;\n resolved_at: string | null;\n created_by: string | null;\n created_at: string;\n updated_at: string;\n}\n\n// =============================================================================\n// Admin authoring\n// =============================================================================\n\nexport const createNoticeBody = z.object({\n severity: noticeSeveritySchema.default('info'),\n scope: noticeScopeSchema.default('global'),\n title: z.string().trim().min(1).max(200),\n body: z.string().max(2000).optional(),\n link: noticeLinkSchema.optional(),\n starts_at: z.string().datetime().optional(),\n ends_at: z.string().datetime().optional(),\n});\nexport type CreateNoticeBody = z.infer<typeof createNoticeBody>;\n\n// Partial update. Nullable fields (`body`, `link`, `ends_at`) accept `null` to\n// clear; omitted keys are left unchanged.\nexport const updateNoticeBody = z\n .object({\n severity: noticeSeveritySchema.optional(),\n scope: noticeScopeSchema.optional(),\n title: z.string().trim().min(1).max(200).optional(),\n body: z.string().max(2000).nullable().optional(),\n link: noticeLinkSchema.nullable().optional(),\n starts_at: z.string().datetime().optional(),\n ends_at: z.string().datetime().nullable().optional(),\n })\n .refine((b) => Object.keys(b).length > 0, { message: 'at least one field must be provided' });\nexport type UpdateNoticeBody = z.infer<typeof updateNoticeBody>;\n\nexport const listNoticesQuery = z.object({\n status: noticeStatusSchema.optional(),\n limit: z.coerce.number().int().min(1).max(200).optional(),\n offset: z.coerce.number().int().min(0).optional(),\n});\n\nexport const noticeIdParamSchema = z.object({ id: z.string().min(1) });\n\nexport interface AdminNoticeListResponse {\n data: PlatformNotice[];\n total: number;\n}\n\nexport interface AdminNoticeResponse {\n data: PlatformNotice;\n}\n\n// =============================================================================\n// Consumer aggregate (any authenticated user)\n// =============================================================================\n\n// The current user's active broadcasts (within their display window, scoped to\n// them, minus the ones they've acknowledged). v1 surfaces `global`-scoped notices\n// to everyone; provider/service-scoped recipient resolution lands with delivery.\nexport interface NoticesAggregateResponse {\n notices: PlatformNotice[];\n}\n\nexport interface AckNoticeResponse {\n acked: true;\n}\n","/**\n * Canonical timestamp helpers — WayAI's single representation of an instant.\n *\n * Standard (see root CLAUDE.md › Database Conventions › Timestamps):\n * • Instants are STORED (DO SQLite) and TRANSMITTED (API/wire) as ISO-8601 UTC,\n * millisecond precision, `Z` suffix: `2026-06-02T15:54:00.123Z`.\n * • The DO-store value and the wire value are byte-identical — one serializer,\n * no stripping of the `Z`, so `new Date(value)` parses the same on every path.\n * • Conversion to a human timezone happens ONLY at the display edge\n * (frontend `formatInstant`, ClickHouse `toTimeZone(...)` bucketing).\n *\n * Never store or send a naive (timezone-less) timestamp. SQLite `datetime('now')`\n * (which yields `YYYY-MM-DD HH:MM:SS`, no `T`/`Z`) is banned for new columns —\n * a UTC instant without its marker gets re-parsed as local time. Use a\n * `strftime('%Y-%m-%dT%H:%M:%fZ','now')` default or write an explicit value.\n */\n\n/** ISO-8601 UTC string, millisecond precision, `Z` suffix. The canonical form. */\nexport type IsoTimestamp = string;\n\n/** Matches the canonical form exactly: `YYYY-MM-DDTHH:MM:SS.sssZ`. */\nexport const ISO_UTC_RE = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\n\n/** Convert epoch milliseconds to the canonical ISO-8601 UTC string. */\nexport function toIso(epochMs: number): IsoTimestamp {\n return new Date(epochMs).toISOString();\n}\n\n/** Parse a canonical ISO timestamp back to epoch milliseconds. */\nexport function fromIso(iso: IsoTimestamp): number {\n return new Date(iso).getTime();\n}\n\n/** Current instant as a canonical ISO-8601 UTC string. */\nexport function nowIso(): IsoTimestamp {\n return new Date().toISOString();\n}\n\n/** True when `value` is exactly the canonical ISO-8601-UTC-with-`Z` form. */\nexport function isIsoTimestamp(value: unknown): value is IsoTimestamp {\n return typeof value === 'string' && ISO_UTC_RE.test(value);\n}\n","/**\n * Grant-based authorization for WayAI.\n *\n * Ported from Rekor with adaptations:\n * - workspaces -> hubs\n * - collections -> hub_tags (OR matching)\n * - WayAI-specific Permission type\n */\n\nimport type { AuthContext, Grant } from './permissions';\n\nexport interface AccessRequest {\n org_id?: string;\n hub?: string;\n hub_tag?: string;\n environment?: 'production' | 'preview';\n permission: string;\n}\n\n/**\n * Check if an auth context allows a specific access request.\n * Uses union semantics: returns true if ANY grant matches.\n */\nexport function hasAccess(auth: AuthContext, req: AccessRequest): boolean {\n for (const grant of auth.grants) {\n if (grantMatches(grant, req)) {\n return true;\n }\n }\n return false;\n}\n\nfunction grantMatches(grant: Grant, req: AccessRequest): boolean {\n // Check org scope — if both request and grant specify an org, they must match\n if (req.org_id && grant.scope.org_id) {\n if (req.org_id !== grant.scope.org_id) {\n return false;\n }\n }\n\n // Check hub scope\n if (req.hub) {\n if (!matchesScope(grant.scope.hubs, req.hub)) {\n return false;\n }\n }\n\n // Check hub_tag scope (undefined on grant = all tags allowed)\n if (req.hub_tag && grant.scope.hub_tags) {\n if (!matchesScope(grant.scope.hub_tags, req.hub_tag)) {\n return false;\n }\n }\n\n // Check environment scope (undefined on grant = all environments allowed)\n if (req.environment && grant.scope.environments) {\n if (!grant.scope.environments.includes(req.environment)) {\n return false;\n }\n }\n\n // Check permission\n if (!matchesScope(grant.permissions as string[], req.permission)) {\n return false;\n }\n\n return true;\n}\n\nfunction matchesScope(allowed: string[], value: string): boolean {\n return allowed.includes('*') || allowed.includes(value);\n}\n\n/**\n * Hub-coverage context: everything `grantCoversHub` needs to decide whether\n * a grant covers a specific hub. The hub's actual `org_id` is required —\n * relying on caller-supplied org context lets a wildcard grant in one org\n * silently cover hubs in any other org.\n */\nexport interface HubScopeContext {\n id: string;\n org_id: string;\n tags?: string[];\n environment?: 'production' | 'preview';\n}\n\n/**\n * Single source of truth for \"does this grant cover this hub?\". Open-coding\n * `grant.scope.hubs.includes(...)` elsewhere risks pairing either branch\n * with no `org_id` check, which lets one org's grant cover any hub in any\n * org.\n *\n * Scope rule (uniform): every grant MUST declare a `scope.org_id` that\n * matches the hub's org. Wildcards without org context would match any\n * hub in any org; specific hub ids without org context let an org-A\n * admin mint a token for a known hub UUID in org B (cross-org bypass).\n *\n * Returns true iff the grant's `scope.org_id` matches the hub's org, the\n * grant covers the hub by id (or wildcard), AND the grant's tag/environment\n * filters all match the hub.\n */\nexport function grantCoversHub(grant: Grant, hub: HubScopeContext): boolean {\n if (grant.scope.org_id !== hub.org_id) return false;\n if (!grant.scope.hubs.includes('*') && !grant.scope.hubs.includes(hub.id)) {\n return false;\n }\n\n // Hub-tag filter: grant restricts to certain tags → hub must have at least one.\n if (grant.scope.hub_tags && grant.scope.hub_tags.length > 0) {\n const tags = hub.tags ?? [];\n if (tags.length === 0) return false;\n const overlap = grant.scope.hub_tags.some(t => t === '*' || tags.includes(t));\n if (!overlap) return false;\n }\n\n // Environment filter: grant restricts to certain envs → hub must match.\n if (hub.environment && grant.scope.environments && !grant.scope.environments.includes(hub.environment)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Check if child grants are a subset of parent grants.\n * Used to enforce privilege ceiling on token creation.\n * Every access the child grants must also be allowed by the parent.\n */\nexport function isSubsetOf(parentAuth: AuthContext, childGrants: Grant[]): boolean {\n for (const child of childGrants) {\n // Without scope.org_id, hasAccess can't enforce the org boundary —\n // any minted token would cover hubs cross-org.\n if (!child.scope.org_id) {\n return false;\n }\n\n const parentCoversOrg = parentAuth.grants.some(\n g => !g.scope.org_id || g.scope.org_id === child.scope.org_id,\n );\n if (!parentCoversOrg) {\n return false;\n }\n\n // Every hub in child must be covered by parent\n if (!child.scope.hubs.includes('*')) {\n for (const hub of child.scope.hubs) {\n for (const perm of child.permissions) {\n if (!hasAccess(parentAuth, { org_id: child.scope.org_id, hub, permission: perm })) {\n return false;\n }\n }\n }\n } else {\n // Child wants wildcard hubs — parent must also have wildcard hub access for each permission\n for (const perm of child.permissions) {\n if (!hasAccess(parentAuth, { org_id: child.scope.org_id, permission: perm })) {\n return false;\n }\n const parentHasWildcard = parentAuth.grants.some(\n g =>\n g.scope.hubs.includes('*') &&\n (!g.scope.org_id || g.scope.org_id === child.scope.org_id) &&\n matchesScope(g.permissions as string[], perm),\n );\n if (!parentHasWildcard) {\n return false;\n }\n }\n }\n\n // Check hub_tag scope escalation\n if (!child.scope.hub_tags || child.scope.hub_tags.includes('*')) {\n // Wildcard-including list is equivalent to undefined: matchesScope(['*'], tag)\n // always returns true at runtime, so both forms grant every tag.\n // Empty hub list is wildcard scope (mirrors the environment block below):\n // collapse to ['*'] so a hub-less child still requires parent all-tag coverage.\n const hubs =\n child.scope.hubs.includes('*') || child.scope.hubs.length === 0\n ? ['*']\n : child.scope.hubs;\n for (const hub of hubs) {\n for (const perm of child.permissions) {\n const parentCoversAllTags = parentAuth.grants.some(\n g =>\n (!g.scope.org_id || g.scope.org_id === child.scope.org_id) &&\n matchesScope(g.scope.hubs, hub) &&\n !g.scope.hub_tags &&\n matchesScope(g.permissions as string[], perm),\n );\n if (!parentCoversAllTags) {\n return false;\n }\n }\n }\n } else {\n const hubs =\n child.scope.hubs.includes('*') || child.scope.hubs.length === 0\n ? ['*']\n : child.scope.hubs;\n for (const tag of child.scope.hub_tags) {\n for (const perm of child.permissions) {\n for (const hub of hubs) {\n // org_id is required: grantMatches only enforces the org boundary\n // when the request carries it, so a different-org parent grant\n // covering the same hub/tag/perm would otherwise satisfy this.\n if (\n !hasAccess(parentAuth, {\n org_id: child.scope.org_id,\n hub: hub === '*' ? undefined : hub,\n hub_tag: tag,\n permission: perm,\n })\n ) {\n return false;\n }\n }\n }\n }\n }\n\n // Check environment scope escalation\n if (!child.scope.environments) {\n // Empty hub list is wildcard scope: requires the parent to hold an\n // all-hub, all-env grant, not a vacuous pass.\n const hubs =\n child.scope.hubs.includes('*') || child.scope.hubs.length === 0\n ? ['*']\n : child.scope.hubs;\n for (const hub of hubs) {\n const parentCoversAllEnvs = parentAuth.grants.some(\n g =>\n (!g.scope.org_id || g.scope.org_id === child.scope.org_id) &&\n !g.scope.environments &&\n matchesScope(g.scope.hubs, hub) &&\n child.permissions.every(p => matchesScope(g.permissions as string[], p)),\n );\n if (!parentCoversAllEnvs) {\n return false;\n }\n }\n }\n }\n\n return true;\n}\n","/**\n * Token hashing utility for secure KV storage.\n *\n * Tokens are stored in KV using their SHA-256 hash as the key,\n * prefixed with \"th_\" to distinguish from legacy raw-token keys.\n */\n\n/**\n * Hash a raw API token using SHA-256 for secure KV storage.\n * Returns \"th_\" + hex(SHA-256(rawToken)).\n */\nexport async function hashToken(rawToken: string): Promise<string> {\n const encoded = new TextEncoder().encode(rawToken);\n const hash = await crypto.subtle.digest('SHA-256', encoded);\n const hex = Array.from(new Uint8Array(hash))\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n return `th_${hex}`;\n}\n","/**\n * JWT verification for WorkOS AuthKit tokens.\n *\n * Used by backend middleware, MCP server, and conversations MCP\n * to verify OAuth 2.1 access tokens issued by AuthKit.\n */\n\nimport { jwtVerify, createRemoteJWKSet } from 'jose';\nimport type { JWTPayload, JWTVerifyOptions } from 'jose';\n\nexport interface AuthKitJwtPayload {\n /** WorkOS user ID (JWT `sub` claim) */\n sub: string;\n /** User email */\n email?: string;\n /** WorkOS organization ID — present in JWT but ignored by all auth flows (org resolved from UserDO instead) */\n org_id?: string;\n /** WorkOS session ID (JWT `sid` claim) — identifies the device/session for revocation. */\n session_id?: string;\n}\n\n// Module-level JWKS cache — one per isolate, reused across requests.\n// `createRemoteJWKSet` handles HTTP caching and key rotation internally.\nconst jwksCache = new Map<string, ReturnType<typeof createRemoteJWKSet>>();\n\nfunction getJWKS(jwksUrl: string) {\n let jwks = jwksCache.get(jwksUrl);\n if (!jwks) {\n jwks = createRemoteJWKSet(new URL(jwksUrl));\n jwksCache.set(jwksUrl, jwks);\n }\n return jwks;\n}\n\n/**\n * Verify a JWT issued by WorkOS AuthKit.\n *\n * Audience binding (RFC 8707 Resource Indicators): MCP servers pass their resource URL\n * as `expectedAudience`, which enforces that CLI- or web-issued tokens cannot be used\n * against MCP. The backend API path omits `expectedAudience` — any authenticated token\n * is accepted there, which is safe because backend and MCP resolve the same grants\n * from the same `sub` via `buildUserGrants`, so there is no privilege escalation vector.\n *\n * @param token - The raw JWT string\n * @param authkitDomain - AuthKit domain (e.g., `https://<subdomain>.authkit.app`)\n * @param expectedAudience - If provided, requires the `aud` claim to match.\n * @returns Parsed payload with user identity\n * @throws On invalid, expired, malformed, or audience-mismatched tokens\n */\nexport async function verifyAuthKitJwt(\n token: string,\n authkitDomain: string,\n expectedAudience?: string,\n): Promise<AuthKitJwtPayload> {\n const jwksUrl = `${authkitDomain}/oauth2/jwks`;\n const jwks = getJWKS(jwksUrl);\n\n const options: JWTVerifyOptions = { issuer: authkitDomain };\n if (expectedAudience !== undefined) options.audience = expectedAudience;\n\n const { payload } = await jwtVerify(token, jwks, options);\n\n if (!payload.sub) {\n throw new Error('JWT missing sub claim');\n }\n\n return {\n sub: payload.sub,\n email: (payload as JWTPayload & { email?: string }).email,\n org_id: (payload as JWTPayload & { org_id?: string }).org_id,\n session_id: (payload as JWTPayload & { sid?: string }).sid,\n };\n}\n","/**\n * Dual-auth utilities shared across backend, MCP server, and conversations MCP.\n *\n * Supports two token types:\n * - JWT (from WorkOS AuthKit OAuth 2.1) — verified via JWKS\n * - way_ token (scoped API token) — validated via KV lookup\n */\n\nexport type TokenType = 'jwt' | 'way_token' | 'unknown';\n\n/**\n * Extract bearer token from an HTTP request's Authorization header.\n */\nexport function extractBearerToken(request: Request): string | null {\n const authHeader = request.headers.get('Authorization');\n if (!authHeader?.startsWith('Bearer ')) {\n return null;\n }\n return authHeader.slice(7);\n}\n\n/**\n * Identify the token type by prefix.\n * - `way_` prefix → scoped API token (KV-backed)\n * - `eyJ` prefix → JWT (base64-encoded JSON header)\n */\nexport function identifyTokenType(token: string): TokenType {\n if (token.startsWith('way_')) return 'way_token';\n if (token.startsWith('eyJ')) return 'jwt';\n return 'unknown';\n}\n\n/**\n * Build a RFC 9728 WWW-Authenticate header for 401 responses.\n *\n * Includes `resource_metadata` so MCP clients can discover\n * the authorization server automatically.\n */\nexport function buildWwwAuthenticateHeader(\n resourceMetadataUrl: string,\n errorDescription = 'Authorization required',\n): string {\n return [\n 'Bearer error=\"unauthorized\"',\n `error_description=\"${errorDescription}\"`,\n `resource_metadata=\"${resourceMetadataUrl}\"`,\n ].join(', ');\n}\n","/**\n * Token generation utility — single source of truth.\n *\n * Consolidates the three identical generateApiKey() copies that existed\n * in internal-auth.ts, auth/index.ts, and tokens.ts.\n */\n\n/**\n * Generate a cryptographically random opaque token with the given prefix.\n * Format: `<prefix>_` + 32 bytes base64url-encoded.\n */\nexport function generateOpaqueToken(prefix: string): string {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n const base64 = btoa(String.fromCharCode(...bytes))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n return `${prefix}_${base64}`;\n}\n\n/** Generate a cryptographically random `way_` API token. */\nexport function generateApiKey(): string {\n return generateOpaqueToken('way');\n}\n","/**\n * Envelope encryption using AES-256-GCM via Web Crypto API.\n *\n * Format: \"enc:v1:<iv1_b64>:<ciphertext_b64>:<iv2_b64>:<wrappedDek_b64>\"\n *\n * Each secret gets its own DEK (Data Encryption Key), wrapped by the master key.\n * Key rotation only re-wraps DEKs — no need to re-encrypt every secret.\n */\n\nconst ENVELOPE_PREFIX = 'enc:v1:';\n\nfunction base64Encode(buffer: ArrayBuffer): string {\n return btoa(String.fromCharCode(...new Uint8Array(buffer)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n}\n\nfunction base64Decode(str: string): Uint8Array {\n const padded = str.replace(/-/g, '+').replace(/_/g, '/');\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\nasync function importKey(rawKeyBase64: string): Promise<CryptoKey> {\n const keyBytes = base64Decode(rawKeyBase64);\n return crypto.subtle.importKey(\n 'raw',\n keyBytes as BufferSource,\n { name: 'AES-GCM' },\n false,\n ['encrypt', 'decrypt'],\n );\n}\n\nasync function aesEncrypt(key: CryptoKey, iv: Uint8Array, plaintext: Uint8Array): Promise<ArrayBuffer> {\n return crypto.subtle.encrypt({ name: 'AES-GCM', iv: iv as BufferSource }, key, plaintext as BufferSource);\n}\n\nasync function aesDecrypt(key: CryptoKey, iv: Uint8Array, ciphertext: Uint8Array): Promise<ArrayBuffer> {\n return crypto.subtle.decrypt({ name: 'AES-GCM', iv: iv as BufferSource }, key, ciphertext as BufferSource);\n}\n\n/**\n * Generate a cryptographically secure secret (32 bytes, base64url encoded).\n * Use this instead of uuidv7() or crypto.randomUUID() for secrets.\n */\nexport function generateSecret(): string {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n return base64Encode(bytes.buffer);\n}\n\n/**\n * Generate a master key for envelope encryption (32 bytes, base64 encoded).\n * Run once to create the MASTER_KEY value for wrangler secrets.\n */\nexport function generateMasterKey(): string {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n return btoa(String.fromCharCode(...bytes));\n}\n\n/**\n * Encrypt a plaintext string using envelope encryption (AES-256-GCM).\n *\n * 1. Generate a random DEK (Data Encryption Key)\n * 2. Encrypt plaintext with DEK\n * 3. Wrap (encrypt) the DEK with the master key\n * 4. Return all components as a prefixed string\n */\nexport async function encrypt(masterKeyBase64: string, plaintext: string): Promise<string> {\n const masterKey = await importKey(masterKeyBase64);\n\n // Generate DEK\n const dek = new Uint8Array(32);\n crypto.getRandomValues(dek);\n const dekKey = await crypto.subtle.importKey('raw', dek, { name: 'AES-GCM' }, true, ['encrypt']);\n\n // Encrypt plaintext with DEK\n const iv1 = new Uint8Array(12);\n crypto.getRandomValues(iv1);\n const ciphertext = await aesEncrypt(dekKey, iv1, new TextEncoder().encode(plaintext));\n\n // Wrap DEK with master key\n const iv2 = new Uint8Array(12);\n crypto.getRandomValues(iv2);\n const wrappedDek = await aesEncrypt(masterKey, iv2, dek);\n\n return `${ENVELOPE_PREFIX}${base64Encode(iv1.buffer)}:${base64Encode(ciphertext)}:${base64Encode(iv2.buffer)}:${base64Encode(wrappedDek)}`;\n}\n\n/**\n * Decrypt an envelope-encrypted string.\n *\n * 1. Unwrap the DEK using the master key\n * 2. Decrypt the ciphertext using the DEK\n */\nexport async function decrypt(masterKeyBase64: string, encrypted: string): Promise<string> {\n if (!encrypted.startsWith(ENVELOPE_PREFIX)) {\n throw new Error('Invalid encrypted format: missing enc:v1: prefix');\n }\n\n const parts = encrypted.slice(ENVELOPE_PREFIX.length).split(':');\n if (parts.length !== 4) {\n throw new Error('Invalid encrypted format: expected 4 components');\n }\n\n const [iv1B64, ciphertextB64, iv2B64, wrappedDekB64] = parts as [string, string, string, string];\n const iv1 = base64Decode(iv1B64);\n const ciphertext = base64Decode(ciphertextB64);\n const iv2 = base64Decode(iv2B64);\n const wrappedDek = base64Decode(wrappedDekB64);\n\n const masterKey = await importKey(masterKeyBase64);\n\n // Unwrap DEK\n const dekBytes = await aesDecrypt(masterKey, iv2, wrappedDek);\n const dekKey = await crypto.subtle.importKey('raw', dekBytes, { name: 'AES-GCM' }, false, ['decrypt']);\n\n // Decrypt ciphertext\n const plainBytes = await aesDecrypt(dekKey, iv1, ciphertext);\n return new TextDecoder().decode(plainBytes);\n}\n\n/**\n * Check whether a value is already envelope-encrypted.\n */\nexport function isEncrypted(value: string): boolean {\n return value.startsWith(ENVELOPE_PREFIX);\n}\n\n/**\n * Constant-time string comparison to prevent timing attacks.\n *\n * On length mismatch, compares `a` against itself to maintain constant time\n * (avoids leaking length information through early return).\n */\nexport function timingSafeEqual(a: string, b: string): boolean {\n const lengthMatch = a.length === b.length;\n if (!lengthMatch) {\n b = a;\n }\n\n let result = lengthMatch ? 0 : 1;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n}\n\nexport function timingSafeEqualBytes(a: Uint8Array, b: Uint8Array): boolean {\n const lengthMatch = a.length === b.length;\n if (!lengthMatch) {\n b = a; // avoid early-return timing oracle on length mismatch\n }\n\n let result = lengthMatch ? 0 : 1;\n for (let i = 0; i < a.length; i++) {\n result |= a[i] ^ b[i];\n }\n return result === 0;\n}\n","/**\n * Markdown-to-channel format converters.\n *\n * LLMs output standard Markdown. These pure functions convert it to each\n * channel's native formatting before external delivery. The original markdown\n * is stored unchanged — conversion happens at the delivery layer only.\n *\n * Key: process **bold** before *italic* to avoid double-conversion.\n *\n * Channel senders accept only the branded types defined here. A raw string\n * cannot be sent — callers must produce a branded value via a formatter\n * (markdown → native), a plain helper (text → escaped native), or an\n * explicit `as*Unsafe` escape hatch. This makes Telegram HTML injection and\n * similar encoding bugs a compile error, not a runtime audit.\n */\n\n// ---------------------------------------------------------------------------\n// Branded types — only constructable via the helpers below\n// ---------------------------------------------------------------------------\n\ndeclare const __channelBrand: unique symbol;\n\ntype Brand<Tag extends string> = string & { readonly [__channelBrand]: Tag };\n\n/** WhatsApp message body. Native syntax: *bold* _italic_ ~strike~ ```code```. */\nexport type WhatsAppText = Brand<'whatsapp'>;\n/** Instagram message body. Plain text — no native formatting. */\nexport type InstagramText = Brand<'instagram'>;\n/** Email message body. Fragment HTML (no `<!doctype>` wrapper). */\nexport type EmailHtml = Brand<'email'>;\n/** Telegram message body. HTML subset: `<b>`, `<i>`, `<s>`, `<code>`, `<pre>`, `<a>`. Always sent with `parse_mode: 'HTML'`. */\nexport type TelegramHtml = Brand<'telegram'>;\n/** App channel body. Stored markdown, rendered client-side. */\nexport type AppText = Brand<'app'>;\n/** System channel body. Internal-only. */\nexport type SystemText = Brand<'system'>;\n\nexport type ChannelFormatted = WhatsAppText | InstagramText | EmailHtml | TelegramHtml | AppText | SystemText;\n\n/** Sanitize URL for safe use in HTML href/src attributes — block javascript:, data:, vbscript: */\nfunction sanitizeUrl(url: string): string {\n // Normalize: strip control characters, decode HTML entities (browsers do this before scheme resolution),\n // then check for dangerous protocols. Entity decoding handles both &#NNN; and &#xHH; forms,\n // plus &amp; chains from our own entity escaping step.\n const normalized = url\n .replace(/[\\x00-\\x1f\\x7f]/g, '')\n .replace(/&amp;/gi, '&')\n .replace(/&#(\\d+);/g, (_m, code) => String.fromCharCode(Number(code)))\n .replace(/&#x([\\da-f]+);/gi, (_m, hex) => String.fromCharCode(parseInt(hex, 16)))\n .replace(/%([0-9a-f]{2})/gi, (_m, hex) => String.fromCharCode(parseInt(hex, 16)))\n .trim()\n .toLowerCase();\n if (normalized.startsWith('javascript:') || normalized.startsWith('data:') || normalized.startsWith('vbscript:')) {\n return '';\n }\n return url;\n}\n\n// ---------------------------------------------------------------------------\n// WhatsApp: *bold* _italic_ ~strike~ ```code```\n// ---------------------------------------------------------------------------\n\nexport function markdownToWhatsApp(text: string): WhatsAppText {\n let result = text;\n\n // Code blocks: ```lang\\ncode\\n``` → ```code``` (preserve, WhatsApp supports natively)\n result = result.replace(/```[\\w]*\\n?([\\s\\S]*?)```/g, '```$1```');\n\n // Bold+italic: ***text*** → *_text_*\n result = result.replace(/\\*\\*\\*(.+?)\\*\\*\\*/g, '*_$1_*');\n\n // Bold: **text** → *text* (must come before italic)\n result = result.replace(/\\*\\*(.+?)\\*\\*/g, '*$1*');\n\n // Italic: _text_ stays as _text_ (WhatsApp native)\n // Italic: *text* → _text_ (only single asterisks that aren't part of bold)\n // After bold conversion, remaining single * pairs are italic\n // We need to be careful not to match the bold markers we just created\n // Skip this — single * is already used for bold in WhatsApp. Markdown italic *text*\n // becomes WhatsApp bold, which is an acceptable tradeoff.\n\n // Strikethrough: ~~text~~ → ~text~\n result = result.replace(/~~(.+?)~~/g, '~$1~');\n\n // Headers: # Heading → *Heading* (bold as substitute)\n result = result.replace(/^#{1,6}\\s+(.+)$/gm, '*$1*');\n\n // Images: ![alt](url) → alt (url) (must come before links)\n result = result.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, '$1 ($2)');\n\n // Links: [text](url) → text (url)\n result = result.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '$1 ($2)');\n\n return result as WhatsAppText;\n}\n\n// ---------------------------------------------------------------------------\n// Plain text (Instagram): strip all formatting\n// ---------------------------------------------------------------------------\n\nexport function markdownToPlainText(text: string): InstagramText {\n let result = text;\n\n // Code blocks: ```lang\\ncode\\n``` → code\n result = result.replace(/```[\\w]*\\n?([\\s\\S]*?)```/g, '$1');\n\n // Inline code: `code` → code\n result = result.replace(/`([^`]+)`/g, '$1');\n\n // Bold+italic: ***text*** → text\n result = result.replace(/\\*\\*\\*(.+?)\\*\\*\\*/g, '$1');\n\n // Bold: **text** or __text__ → text\n result = result.replace(/\\*\\*(.+?)\\*\\*/g, '$1');\n result = result.replace(/__(.+?)__/g, '$1');\n\n // Italic: *text* or _text_ → text\n result = result.replace(/\\*(.+?)\\*/g, '$1');\n result = result.replace(/(?<!\\w)_(.+?)_(?!\\w)/g, '$1');\n\n // Strikethrough: ~~text~~ → text\n result = result.replace(/~~(.+?)~~/g, '$1');\n\n // Headers: # Heading → Heading\n result = result.replace(/^#{1,6}\\s+(.+)$/gm, '$1');\n\n // Links: [text](url) → text (url)\n result = result.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '$1 ($2)');\n\n // Images: ![alt](url) → alt (url)\n result = result.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, '$1 ($2)');\n\n // Horizontal rules: --- or *** → empty line\n result = result.replace(/^[-*_]{3,}$/gm, '');\n\n return result as InstagramText;\n}\n\n// ---------------------------------------------------------------------------\n// HTML (Email): fragment HTML — no <!DOCTYPE> wrapper\n// ---------------------------------------------------------------------------\n\nexport function markdownToHtml(text: string): EmailHtml {\n // Escape HTML entities first (including \" for safe attribute values)\n let result = text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n\n // Code blocks: extract and replace with placeholders to protect from further processing\n const codeBlocks: string[] = [];\n result = result.replace(/```[\\w]*\\n?([\\s\\S]*?)```/g, (_match, code) => {\n codeBlocks.push(`<pre><code>${code}</code></pre>`);\n return `\\x00CODE${codeBlocks.length - 1}\\x00`;\n });\n\n // Inline code: `code` → <code>code</code>\n result = result.replace(/`([^`]+)`/g, '<code>$1</code>');\n\n // Images: ![alt](url) → <img> (before links to avoid conflict, URL sanitized)\n result = result.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (_m, alt, url) => {\n const safe = sanitizeUrl(url);\n return safe ? `<img src=\"${safe}\" alt=\"${alt}\" style=\"max-width:100%\">` : alt;\n });\n\n // Links: [text](url) → <a> (URL sanitized)\n result = result.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (_m, text, url) => {\n const safe = sanitizeUrl(url);\n return safe ? `<a href=\"${safe}\">${text}</a>` : text;\n });\n\n // Headers: # Heading → <h1>-<h6>\n result = result.replace(/^######\\s+(.+)$/gm, '<h6>$1</h6>');\n result = result.replace(/^#####\\s+(.+)$/gm, '<h5>$1</h5>');\n result = result.replace(/^####\\s+(.+)$/gm, '<h4>$1</h4>');\n result = result.replace(/^###\\s+(.+)$/gm, '<h3>$1</h3>');\n result = result.replace(/^##\\s+(.+)$/gm, '<h2>$1</h2>');\n result = result.replace(/^#\\s+(.+)$/gm, '<h1>$1</h1>');\n\n // Bold+italic: ***text*** → <strong><em>text</em></strong>\n result = result.replace(/\\*\\*\\*(.+?)\\*\\*\\*/g, '<strong><em>$1</em></strong>');\n\n // Bold: **text** → <strong>text</strong>\n result = result.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>');\n\n // Italic: *text* → <em>text</em>\n result = result.replace(/\\*(.+?)\\*/g, '<em>$1</em>');\n\n // Strikethrough: ~~text~~ → <s>text</s>\n result = result.replace(/~~(.+?)~~/g, '<s>$1</s>');\n\n // Horizontal rules: --- → <hr>\n result = result.replace(/^[-*_]{3,}$/gm, '<hr>');\n\n // Unordered lists: use UL-specific markers to avoid confusion with ordered lists\n result = result.replace(/^[-*+]\\s+(.+)$/gm, '\\x00UL-LI\\x00$1\\x00/UL-LI\\x00');\n result = result.replace(/((?:\\x00UL-LI\\x00.*?\\x00\\/UL-LI\\x00\\n?)+)/g, (_m, items) => {\n const lis = items.replace(/\\x00UL-LI\\x00(.*?)\\x00\\/UL-LI\\x00/g, '<li>$1</li>');\n return `<ul>${lis}</ul>\\n`;\n });\n\n // Ordered lists: use OL-specific markers\n result = result.replace(/^\\d+\\.\\s+(.+)$/gm, '\\x00OL-LI\\x00$1\\x00/OL-LI\\x00');\n result = result.replace(/((?:\\x00OL-LI\\x00.*?\\x00\\/OL-LI\\x00\\n?)+)/g, (_m, items) => {\n const lis = items.replace(/\\x00OL-LI\\x00(.*?)\\x00\\/OL-LI\\x00/g, '<li>$1</li>');\n return `<ol>${lis}</ol>\\n`;\n });\n\n // Paragraphs: double newlines → <br><br>, single newlines → <br>\n result = result.replace(/\\n\\n/g, '<br><br>');\n result = result.replace(/\\n/g, '<br>');\n\n // Remove spurious <br> after block-level elements (they already create visual breaks)\n result = result.replace(/(<\\/(?:ul|ol|h[1-6]|pre|blockquote)>|<hr>)<br>/g, '$1');\n\n // Restore code blocks (newlines preserved inside <pre>)\n result = result.replace(/\\x00CODE(\\d+)\\x00/g, (_match, idx) => codeBlocks[Number(idx)]);\n\n return result as EmailHtml;\n}\n\n// ---------------------------------------------------------------------------\n// Telegram HTML: <b>, <i>, <s>, <code>, <pre>, <a>\n// Telegram only supports a subset of HTML tags.\n// ---------------------------------------------------------------------------\n\nexport function markdownToTelegramHtml(text: string): TelegramHtml {\n // Escape HTML entities first (Telegram requires this, including \" for attributes)\n let result = text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n\n // Code blocks: extract and replace with placeholders to protect from further processing\n const codeBlocks: string[] = [];\n result = result.replace(/```[\\w]*\\n?([\\s\\S]*?)```/g, (_match, code) => {\n codeBlocks.push(`<pre>${code}</pre>`);\n return `\\x00CODE${codeBlocks.length - 1}\\x00`;\n });\n\n // Inline code: `code` → <code>code</code>\n result = result.replace(/`([^`]+)`/g, '<code>$1</code>');\n\n // Links: [text](url) → <a href=\"url\">text</a> (URL sanitized)\n result = result.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (_m, text, url) => {\n const safe = sanitizeUrl(url);\n return safe ? `<a href=\"${safe}\">${text}</a>` : text;\n });\n\n // Images: ![alt](url) → alt (url) (Telegram doesn't support inline images in HTML mode)\n result = result.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, '$1 ($2)');\n\n // Headers: # Heading → <b>Heading</b> (Telegram has no heading tags)\n result = result.replace(/^#{1,6}\\s+(.+)$/gm, '<b>$1</b>');\n\n // Bold+italic: ***text*** → <b><i>text</i></b>\n result = result.replace(/\\*\\*\\*(.+?)\\*\\*\\*/g, '<b><i>$1</i></b>');\n\n // Bold: **text** → <b>text</b>\n result = result.replace(/\\*\\*(.+?)\\*\\*/g, '<b>$1</b>');\n\n // Italic: *text* → <i>text</i>\n result = result.replace(/\\*(.+?)\\*/g, '<i>$1</i>');\n\n // Strikethrough: ~~text~~ → <s>text</s>\n result = result.replace(/~~(.+?)~~/g, '<s>$1</s>');\n\n // Horizontal rules: --- → (empty, no equivalent)\n result = result.replace(/^[-*_]{3,}$/gm, '');\n\n // Restore code blocks\n result = result.replace(/\\x00CODE(\\d+)\\x00/g, (_match, idx) => codeBlocks[Number(idx)]);\n\n return result as TelegramHtml;\n}\n\n// ---------------------------------------------------------------------------\n// Plain-text helpers — escape free-form text into channel-native format.\n// Use these for content that is NOT markdown: hard-coded UI strings with\n// interpolated user/admin/agent data, system messages, channel forwarders.\n// ---------------------------------------------------------------------------\n\n/**\n * Escape free-form text for Telegram HTML mode.\n * Required for ANY interpolation that reaches `sendTelegramMessage`, because\n * Telegram parses `<`, `>`, `&`, `\"` as HTML control characters when\n * `parse_mode: 'HTML'` is set.\n */\nexport function telegramPlain(text: string): TelegramHtml {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;') as TelegramHtml;\n}\n\n/**\n * Escape free-form text for Email HTML mode.\n * Mirrors the inline escape that previously lived in `sendEmailMessage`.\n */\nexport function emailPlain(text: string): EmailHtml {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/\\n/g, '<br>') as EmailHtml;\n}\n\n// Note: WhatsApp and Instagram have no `*Plain` helpers because neither has a\n// reliable escape mechanism — WhatsApp still parses native markup (`*bold*`,\n// `_italic_`, `~strike~`, `` `code` ``) inside any text, and Instagram has\n// no formatting. Callers that need to pass plain text to these channels use\n// `asWhatsAppTextUnsafe` / `asInstagramTextUnsafe` and own the visual quirks.\n\n// ---------------------------------------------------------------------------\n// Escape hatches — text the caller asserts is channel-native (no further\n// escaping). Used for:\n// - the `agent.auto_format = false` opt-out, where the agent emits\n// pre-formatted channel-native output\n// - WhatsApp / Instagram, which have no robust plain-text escape\n// Grep for `Unsafe` to audit every callsite.\n// ---------------------------------------------------------------------------\n\nexport function asTelegramHtmlUnsafe(text: string): TelegramHtml { return text as TelegramHtml; }\nexport function asEmailHtmlUnsafe(text: string): EmailHtml { return text as EmailHtml; }\nexport function asWhatsAppTextUnsafe(text: string): WhatsAppText { return text as WhatsAppText; }\nexport function asInstagramTextUnsafe(text: string): InstagramText { return text as InstagramText; }\n\n// ---------------------------------------------------------------------------\n// Dispatcher\n// ---------------------------------------------------------------------------\n\nexport function formatForChannel(channelType: 'whatsapp', text: string): WhatsAppText;\nexport function formatForChannel(channelType: 'instagram', text: string): InstagramText;\nexport function formatForChannel(channelType: 'email', text: string): EmailHtml;\nexport function formatForChannel(channelType: 'telegram', text: string): TelegramHtml;\nexport function formatForChannel(channelType: 'app' | 'system', text: string): AppText | SystemText;\nexport function formatForChannel(channelType: string, text: string): ChannelFormatted;\nexport function formatForChannel(channelType: string, text: string): ChannelFormatted {\n switch (channelType) {\n case 'whatsapp':\n return markdownToWhatsApp(text);\n case 'instagram':\n return markdownToPlainText(text);\n case 'email':\n return markdownToHtml(text);\n case 'telegram':\n return markdownToTelegramHtml(text);\n case 'system':\n return text as SystemText;\n case 'app':\n default:\n return text as AppText;\n }\n}\n","export type ReasoningTagName = 'thinking' | 'scratchpad' | 'reasoning';\n\n// Backreference `\\1` is case-insensitive under `i` so `<Thinking>...</thinking>` pairs.\nconst REASONING_BLOCK_PATTERN = /<(thinking|scratchpad|reasoning)\\b[^>]*>[\\s\\S]*?<\\/\\1\\s*>/gi;\n\nexport interface StripReasoningTagsResult {\n text: string;\n removed: boolean;\n kinds: ReasoningTagName[];\n originalLength: number;\n strippedLength: number;\n}\n\nexport function stripReasoningTags(input: string): StripReasoningTagsResult {\n const originalLength = input.length;\n\n if (input.indexOf('<') === -1) {\n return { text: input, removed: false, kinds: [], originalLength, strippedLength: originalLength };\n }\n\n const matchedKinds = new Set<ReasoningTagName>();\n const replaced = input.replace(REASONING_BLOCK_PATTERN, (_match, kind: string) => {\n matchedKinds.add(kind.toLowerCase() as ReasoningTagName);\n return '';\n });\n\n if (matchedKinds.size === 0) {\n return { text: input, removed: false, kinds: [], originalLength, strippedLength: originalLength };\n }\n\n const cleaned = replaced.replace(/\\n{3,}/g, '\\n\\n').trim();\n\n return {\n text: cleaned,\n removed: true,\n kinds: Array.from(matchedKinds),\n originalLength,\n strippedLength: cleaned.length,\n };\n}\n","import type { GetConversationDetailResponse } from './contracts/conversations';\n\ntype Message = GetConversationDetailResponse['messages'][number];\n\n/**\n * Renders a single conversation message as a markdown block for debug/admin\n * surfaces (CLI, MCP `get_conversation`). Tool calls/results/errors get\n * labelled fenced-code bodies so hub builders can see arguments and\n * responses; system events and normal bubbles use their sender→receiver\n * routing description.\n */\nexport function formatConversationEventAsMarkdown(msg: Message): string {\n const time = new Date(msg.created_at).toLocaleString();\n const meta = (msg.metadata ?? {}) as {\n tool_name?: unknown;\n arguments?: unknown;\n result?: unknown;\n is_error?: unknown;\n };\n const toolName = typeof meta.tool_name === 'string' ? meta.tool_name : undefined;\n const isToolCall = msg.sender_type === 'agent' && msg.receiver_type === 'tool' && toolName;\n const isToolResult = msg.sender_type === 'tool' && msg.receiver_type === 'agent' && toolName;\n\n if (isToolCall) {\n return `**[tool_call: ${toolName}]** (${time})${fenced(meta.arguments)}\\n`;\n }\n if (isToolResult) {\n const label = meta.is_error === true ? 'tool_error' : 'tool_result';\n const body = meta.result !== undefined ? meta.result : msg.message_text;\n return `**[${label}: ${toolName}]** (${time})${fenced(body)}\\n`;\n }\n if (msg.sender_type === 'system') {\n const to = msg.receiver_type ?? '-';\n return `**[system → ${to}]** (${time})\\n${msg.message_text || '_[No text content]_'}\\n\\n`;\n }\n const from = msg.sender_description || msg.sender_type;\n const to = msg.receiver_description || msg.receiver_type;\n const routing = to ? `${from} → ${to}` : from;\n return `**[${routing}]** (${time})\\n${msg.message_text || '_[No text content]_'}\\n\\n`;\n}\n\nfunction fenced(value: unknown): string {\n // Every event ends with a blank-line separator (`\\n\\n`). When there's no\n // value to render, return `\\n` so the trailing `\\n` in the caller's\n // template produces the same two-newline ending as the other branches.\n if (value === undefined || value === null) return '\\n';\n const text = typeof value === 'string' ? value : JSON.stringify(value, null, 2);\n return `\\n\\`\\`\\`\\n${text}\\n\\`\\`\\`\\n`;\n}\n","/**\n * LLM Streaming Types\n *\n * Normalized streaming event types shared between backend providers\n * and frontend SSE consumer. Provider-agnostic — each provider's\n * callAPIStream() maps its native SSE format to these events.\n */\n\n/**\n * Token usage tracking (duplicated from backend llm/types.ts to avoid\n * circular dependency — shared package must not import from backend)\n */\n/** Provider whose container/code-execution counters populated a usage block. */\nexport type ContainerProvider = 'anthropic' | 'openai';\n\nexport interface StreamTokenUsage {\n input_tokens: number;\n output_tokens: number;\n /**\n * Does NOT include cache tokens — the conversation-level analytics total\n * (`data.system.tokens_total`) adds cache_read + cache_creation on top.\n * See `compute-conversation-metrics.ts`. Don't substitute one for the other.\n */\n total_tokens: number;\n /** Input tokens served from prompt cache (cache hit). */\n cache_read_input_tokens?: number;\n /** Input tokens written to prompt cache (Anthropic only — billed higher than reads). */\n cache_creation_input_tokens?: number;\n /** Anthropic: `usage.server_tool_use.code_execution_requests` from this response. Omitted when web_search/web_fetch is in the same request (code execution is free in that case per Anthropic pricing). */\n code_execution_requests?: number;\n /** OpenAI: count of NEW container lifecycles observed in this response (ids not present in `provider_session.openai`). */\n container_sessions?: number;\n /** Provider whose container counters are populated above. */\n container_provider?: ContainerProvider;\n}\n\n/**\n * Normalize provider-reported input_tokens to the Anthropic convention\n * (\"regular billable input only\", excluding cached portion).\n *\n * OpenAI / Gemini / OpenRouter all return prompt_tokens that *include* cached\n * tokens; Anthropic returns input_tokens that *exclude* both cache reads and\n * cache writes. Subtract so cost math (cache_read priced separately) doesn't\n * double-count. Returns 0 if the subtraction would go negative.\n */\nexport function normalizeBillableInputTokens(promptTotal: number, cacheRead: number): number {\n return Math.max(0, (promptTotal || 0) - (cacheRead || 0));\n}\n\n/**\n * Normalized stream event types emitted by provider callAPIStream()\n * and forwarded to the frontend via SSE.\n *\n * Event lifecycle for a typical completion:\n * message_start → content_delta* → message_end → stream_end\n *\n * With tool calls:\n * message_start → content_delta* → tool_call_start → tool_call_delta* → tool_call_end\n * → tool_executing → tool_result → content_delta* → message_end → stream_end\n *\n * With immediate reinvoke (agent transfer):\n * message_start → content_delta* → tool_call_start → ... → stream_discard\n */\nexport type StreamEvent =\n /** Text content chunk from the LLM */\n | { type: 'content_delta'; delta: string }\n /** Tool call started — contains tool ID and name */\n | { type: 'tool_call_start'; toolCall: { id: string; name: string } }\n /** Partial JSON argument fragment for a tool call */\n | { type: 'tool_call_delta'; toolCallId: string; argsDelta: string }\n /** Tool call arguments fully received */\n | { type: 'tool_call_end'; toolCallId: string }\n /** Tool is being executed server-side (informational, for UI indicators) */\n | { type: 'tool_executing'; toolName: string; toolCallId: string }\n /** Tool execution completed (informational) */\n | { type: 'tool_result'; toolName: string; toolCallId: string }\n /** Token usage from the provider (emitted at end of each LLM turn) */\n | { type: 'usage'; usage: StreamTokenUsage }\n /** LLM response started */\n | { type: 'message_start'; messageId: string }\n /** LLM response ended (one turn — may be followed by tool execution + new turn) */\n | { type: 'message_end'; stopReason: string }\n /** Provider session data (e.g., Anthropic container_id for reuse) */\n | { type: 'session'; session: Record<string, unknown> }\n /** Immediate reinvoke — discard all accumulated text (agent transfer) */\n | { type: 'stream_discard' }\n /** Stream fully complete — contains final message ID and full content */\n | { type: 'stream_end'; messageId: string; content: string }\n /** Internal: consolidated reasoning/thinking content blocks emitted once at end of stream.\n * Used to round-trip provider-specific reasoning blocks (Anthropic thinking, OpenRouter\n * reasoning_details) across tool-loop iterations. Not forwarded to client.\n * Typed `readonly` to enforce the \"unmodified round-trip\" contract at compile time. */\n | { type: 'reasoning_blocks'; blocks: readonly unknown[] }\n /** Error during streaming */\n | { type: 'error'; error: string }\n /** Turn was rate-limited and rescheduled via the DO alarm. Client should expect\n * the response to arrive on the next live-update push, not on this stream. */\n | { type: 'rescheduled'; retry_after_ms: number };\n","import { SLUG_REGEX } from './contracts/setup/slug';\n\n/**\n * Fold combining diacritical marks onto their ASCII base letter so accented\n * text survives slugging — \"Negociação\" -> \"negociacao\", not \"negocia_o\".\n * MUST be applied BEFORE any `[^a-z0-9]` stripping, otherwise the accented\n * letter is dropped to a separator instead of its base letter.\n */\nexport function foldDiacritics(input: string): string {\n return input.normalize('NFKD').replace(/[̀-ͯ]/g, '');\n}\n\n/**\n * THE canonical kebab-case slug producer for URL/folder/file names\n * (`[a-z0-9-]`). Every kebab caller — frontend tag/skill inputs, the shared\n * `slugifySkillName`, both backend hub-folder paths, and the mirrored CLI\n * `slugify` — MUST produce identical output for the same input. Do not\n * reimplement; route through this (or, for the CLI which can't import the\n * shared runtime, mirror it and pin with the drift-guard test).\n *\n * NFKD (via `foldDiacritics`) so accents fold to their base letter AND\n * compatibility chars collapse toward ASCII (\"Clínica Médica\" -> \"clinica-medica\",\n * \"Efficient\" -> \"efficient\"). Then lowercase, runs of non-alphanumerics -> one\n * hyphen, cap, and trim edge hyphens AFTER the cut (a mid-separator cut must not\n * leave a trailing hyphen).\n *\n * `maxLength` is a parameter, not a constant: tags cap at 50, skill names and\n * hub-folder slugs at 64. The CLI⇄backend hub-folder cap is 64 — both sides\n * MUST pass the same value or folder resolution diverges.\n *\n * This is distinct from `slugify` below, which produces snake_case identifier\n * slugs for state/kanban (`[a-z0-9_]`, must start with a letter) because those\n * become ClickHouse JSON paths where hyphens are invalid. The two are not\n * interchangeable.\n */\nexport function slugifyKebab(input: string, maxLength = 64): string {\n if (typeof input !== 'string') return '';\n return foldDiacritics(input)\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/-+/g, '-')\n .slice(0, maxLength)\n .replace(/^-|-$/g, ''); // trim AFTER slicing — a mid-separator cut must not leave an edge hyphen\n}\n\nexport function slugify(name: string): string {\n if (typeof name !== 'string') return 'state';\n let s = foldDiacritics(name)\n .toLowerCase()\n .replace(/[^a-z0-9_]/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_+|_+$/g, '');\n s = s.replace(/^[^a-z]+/, '');\n if (s.length === 0) s = 'state';\n // Trim AFTER slicing — a cap landing on a separator must not leave a trailing '_'.\n if (s.length > 50) s = s.slice(0, 50).replace(/_+$/g, '');\n if (!SLUG_REGEX.test(s)) s = `state_${s}`.slice(0, 50).replace(/_+$/g, '');\n return s;\n}\n\n// Mutates `used` by adding the chosen slug.\nexport function ensureUniqueSlug(slug: string, used: Set<string>): string {\n if (!used.has(slug)) {\n used.add(slug);\n return slug;\n }\n for (let i = 2; i < 1_000_000; i++) {\n const suffix = `_${i}`;\n const baseLen = Math.max(1, 50 - suffix.length);\n const candidate = `${slug.slice(0, baseLen)}${suffix}`;\n if (!used.has(candidate)) {\n used.add(candidate);\n return candidate;\n }\n }\n throw new Error(`slug collision space exhausted for \"${slug}\"`);\n}\n","/**\n * Canonical on-disk layout for hub-as-code in a user's repo.\n *\n * Hub config lives under a product-namespaced root at the repo's git root:\n *\n * wayai-ws/\n * org/ # org-as-code (shared resources)\n * hubs/<hub>/ # one folder per preview hub\n *\n * This is the single source of truth for the directory NAMES, shared between\n * the backend `download_workspace` endpoint and the CLI. The CLI imports this\n * directly and bundles it at build time (tsup `noExternal` inlines `@wayai/core`\n * into the shipped binary), spreading it into `apps/cli/src/lib/layout.ts`\n * `WAYAI_LAYOUT` alongside its legacy fallback. A second product (Rekor) is a\n * second descriptor.\n */\nexport const WAYAI_WORKSPACE_LAYOUT = {\n /** Product-namespaced root dir at the git root. */\n wsDir: 'wayai-ws',\n /** Subdir of `wsDir` holding hub folders. */\n hubsSubdir: 'hubs',\n /** Subdir of `wsDir` holding org-as-code. */\n orgSubdir: 'org',\n} as const;\n\nexport type WorkspaceLayoutNames = typeof WAYAI_WORKSPACE_LAYOUT;\n","/**\n * Resource validation and utility functions.\n *\n * Shared domain logic for resource/skill operations used by both\n * the UI setup endpoints (`/api/setup/resources/*`) and the CI push\n * endpoint (`/api/ci/push`). Follows the agent-settings.ts pattern:\n * pure functions with no IO — callers handle persistence.\n */\n\nimport { slugifyKebab } from './slugify';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Maximum file size for individual resource file uploads (10 MB). */\nexport const MAX_RESOURCE_FILE_SIZE = 10 * 1024 * 1024;\n\n/** Known binary file extensions (lowercase, no dot). */\nexport const BINARY_EXTENSIONS = new Set([\n 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'ico',\n 'mp3', 'mp4', 'wav', 'zip', 'tar', 'gz',\n 'woff', 'woff2', 'ttf', 'eot',\n]);\n\n// ---------------------------------------------------------------------------\n// Skill name\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a valid skill_name slug from a display name.\n *\n * Thin wrapper over the canonical `slugifyKebab` producer (NFKD-normalized,\n * diacritics folded, 64-char cap). Kept as a named export because callers refer\n * to it by intent (\"skill name\"); the algorithm lives in one place so the UI\n * preview, CLI push, and backend persistence can never disagree.\n */\nexport function slugifySkillName(name: string): string {\n return slugifyKebab(name, 64);\n}\n\n/**\n * Validate a skill_name against the platform specification.\n * Returns an array of error strings (empty = valid).\n *\n * Rules: 2-64 chars, lowercase alphanumeric + hyphens,\n * cannot start/end with hyphen, no consecutive hyphens.\n */\nexport function validateSkillName(name: string): string[] {\n const errors: string[] = [];\n if (name.length < 2 || name.length > 64) {\n errors.push('skill_name must be 2-64 characters');\n }\n const pattern = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;\n if (!pattern.test(name)) {\n errors.push(\n 'skill_name must contain only lowercase letters, numbers, and hyphens, and cannot start or end with a hyphen',\n );\n }\n if (name.includes('--')) {\n errors.push('skill_name cannot contain consecutive hyphens');\n }\n return errors;\n}\n\n// ---------------------------------------------------------------------------\n// SKILL.md validation\n// ---------------------------------------------------------------------------\n\n/**\n * Validate SKILL.md content (frontmatter format and required fields).\n * Used during both individual file upload (UI) and bulk push (CI).\n */\nexport function validateSkillMd(\n content: string,\n): { valid: boolean; errors: string[]; warnings: string[] } {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!content.startsWith('---')) {\n errors.push('SKILL.md must start with YAML frontmatter (---)');\n return { valid: false, errors, warnings };\n }\n\n const frontmatterEnd = content.indexOf('---', 3);\n if (frontmatterEnd === -1) {\n errors.push('SKILL.md frontmatter is not properly closed');\n return { valid: false, errors, warnings };\n }\n\n const frontmatter = content.substring(3, frontmatterEnd).trim();\n\n if (!frontmatter.includes('name:')) {\n errors.push('SKILL.md frontmatter must include a name field');\n }\n if (!frontmatter.includes('description:')) {\n warnings.push('SKILL.md frontmatter should include a description field');\n }\n\n return { valid: errors.length === 0, errors, warnings };\n}\n\n// ---------------------------------------------------------------------------\n// Path safety\n// ---------------------------------------------------------------------------\n\n/**\n * Check whether a file path is safe (no traversal escaping root, no absolute).\n * Uses depth tracking to allow `a/b/../c.txt` but reject `../../etc/passwd`.\n */\nexport function isPathSafe(filePath: string): boolean {\n if (filePath.startsWith('/')) return false;\n const segments = filePath.split('/');\n let depth = 0;\n for (const segment of segments) {\n if (segment === '..') {\n depth--;\n if (depth < 0) return false;\n } else if (segment !== '.' && segment !== '') {\n depth++;\n }\n }\n return true;\n}\n\n// ---------------------------------------------------------------------------\n// File type detection\n// ---------------------------------------------------------------------------\n\n/**\n * Check whether a file path has a known binary extension.\n * Case-insensitive.\n */\nexport function isBinaryExtension(filePath: string): boolean {\n const ext = filePath.split('.').pop()?.toLowerCase() || '';\n return BINARY_EXTENSIONS.has(ext);\n}\n\n// ---------------------------------------------------------------------------\n// File metadata\n// ---------------------------------------------------------------------------\n\n/** Canonical metadata shape stored in HubDO `resource_file.metadata`. */\nexport interface FileMetadata {\n file_name: string;\n mime_type: string;\n file_size: number;\n file_hash?: string | null;\n bucket: 'resource';\n}\n\n/**\n * Build a canonical FileMetadata object for a resource file.\n * File content lives in R2 — metadata only stores descriptive fields.\n * Omits `file_hash` when null to keep metadata compact.\n */\nexport function buildFileMetadata(opts: {\n fileName: string;\n filePath: string;\n mimeType: string;\n fileSize: number;\n fileHash?: string | null;\n}): FileMetadata {\n const fileHash = opts.fileHash ?? null;\n\n const meta: FileMetadata = {\n file_name: opts.fileName,\n mime_type: opts.mimeType,\n file_size: opts.fileSize,\n file_hash: fileHash,\n bucket: 'resource',\n };\n\n // Omit null fields to keep metadata compact\n if (meta.file_hash === null) delete (meta as unknown as Record<string, unknown>).file_hash;\n\n return meta;\n}\n","/**\n * Path-based placeholder resolver for agent instructions and scheduled messages.\n *\n * Supports the full set documented in\n * `frontend/src/components/Settings/constants/placeholders.ts`:\n *\n * {{now()}}, {{now().weekday}}, {{now().time_of_day}}, {{now().date}},\n * {{now().time}}, {{now(America/New_York)}}\n * {{week_horizon()}}, {{week_horizon(N)}}\n * {{user_info()}}, {{user_info().user_name|.user_email|.user_phone|...}}\n * {{user_name()}}\n * {{current_conversation_id()}}\n * {{previous_conversations(N)}}\n * {{state()}}, {{state(conversation)}}, {{state(user)}}\n * {{state(conversation, NAME)}}, {{state(user, NAME)}}, {{state(scope, NAME).field}}\n * {{event_info()}}, {{event_info(scheduled)}}, {{event_info().event_name|...}}\n * {{resources()}}, {{resources('kb')}}, {{resources('skill')}}\n * {{resource_content(NAME)}}\n * {{agent_settings(NAME)}}\n * {{agent_skills()}}\n *\n * Context is assembled by the caller (typically ConversationDO, which has all\n * this data locally). Unresolvable placeholders are returned unchanged so the\n * message isn't silently corrupted if context is missing.\n */\n\nexport interface PlaceholderUser {\n user_id?: string;\n user_name?: string;\n user_email?: string;\n user_phone?: string;\n user_language?: string;\n user_timezone?: string;\n [extra: string]: unknown;\n}\n\nexport interface PlaceholderEventInfo {\n event_name?: string;\n event_date?: string; // ISO\n datetime_formatted?: string;\n days_until?: number;\n status?: string; // 'scheduled' | 'completed' | ...\n [extra: string]: unknown;\n}\n\nexport interface PlaceholderResource {\n resource_id: string;\n name: string;\n resource_type: 'knowledge' | 'skill';\n enabled: boolean;\n}\n\nexport interface PlaceholderAgentSettings {\n agent_name: string;\n agent_role: string;\n instructions: string;\n [extra: string]: unknown;\n}\n\nexport interface PlaceholderContext {\n /** Hub timezone (fallback when `now(TZ)` doesn't specify one). */\n timezone?: string;\n /** Current conversation. */\n conversation?: {\n conversation_id?: string;\n kanban_status?: string;\n created_at?: string;\n };\n /** End user participating in the conversation. */\n user?: PlaceholderUser;\n /** Per-scope state, keyed by state_slug. `{{state(scope, slug)}}` reads state[scope][slug]. */\n state?: {\n conversation?: Record<string, unknown>;\n user?: Record<string, unknown>;\n };\n /** Previous closed conversations — newest first, each with `messages` summary. */\n previous_conversations?: Array<{\n conversation_id: string;\n summary?: string;\n ended_at?: string;\n }>;\n /** Event associated with the conversation (from kanban event_name + scheduled date). */\n event_info?: PlaceholderEventInfo;\n /** Hub-wide resource catalog. */\n resources?: PlaceholderResource[];\n /** Resource contents keyed by resource name. */\n resource_content?: Record<string, string>;\n /** Agent settings indexed by agent_name. */\n agent_settings?: Record<string, PlaceholderAgentSettings>;\n /** Agent skills indexed by agent_name. */\n agent_skills?: Record<string, string[]>;\n}\n\n/** Hard cap for `{{previous_conversations(N)}}` — bounds per-turn token cost\n * when a hub author writes a large N. */\nexport const PREVIOUS_CONVERSATIONS_MAX = 20;\n\n/** Default span and hard cap (in days, including today) for `{{week_horizon(N)}}`\n * — bounds per-turn token cost when a hub author writes a large N. */\nexport const WEEK_HORIZON_DEFAULT_DAYS = 8;\nexport const WEEK_HORIZON_MAX_DAYS = 31;\n\n/** Returns `null` when the placeholder is absent — producer should skip the\n * CH query in that case. */\nexport function parseMaxPreviousConversationsN(template: string | undefined): number | null {\n if (!template || !template.includes('previous_conversations(')) return null;\n const re = /\\{\\{\\s*previous_conversations\\(\\s*(\\d+)\\s*\\)\\s*\\}\\}/g;\n let max = 0;\n for (const m of template.matchAll(re)) {\n const n = parseInt(m[1], 10);\n if (Number.isFinite(n) && n > max) max = n;\n }\n if (max <= 0) return null;\n return Math.min(max, PREVIOUS_CONVERSATIONS_MAX);\n}\n\n/**\n * Resolve all placeholders in `template` using `context`. Placeholders that\n * cannot be resolved are left literal.\n */\nexport function resolvePlaceholders(template: string, context: PlaceholderContext = {}): string {\n if (!template || !template.includes('{{')) return template;\n\n return template.replace(/\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g, (match, raw: string) => {\n const resolved = resolveOne(raw.trim(), context);\n return resolved ?? match;\n });\n}\n\n/** Resolve a single placeholder expression (no surrounding braces). */\nfunction resolveOne(expr: string, ctx: PlaceholderContext): string | null {\n const parsed = parseExpr(expr);\n if (!parsed) return null;\n\n const { fn, args, path } = parsed;\n const base = callFn(fn, args, ctx);\n if (base === null) return null;\n\n if (!path.length) return stringifyValue(base);\n const walked = walkPath(base, path);\n return walked === null ? null : stringifyValue(walked);\n}\n\ninterface ParsedExpr {\n fn: string;\n args: string[];\n path: string[];\n}\n\n/** Parse \"fn(a, b).a.b[0]\" into { fn, args, path }. */\nfunction parseExpr(expr: string): ParsedExpr | null {\n const fnMatch = expr.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\((.*?)\\)\\s*(?:\\.(.*))?$/);\n if (!fnMatch) return null;\n\n const [, fn, rawArgs, rawPath] = fnMatch;\n const trimmedArgs = rawArgs.trim();\n const args = trimmedArgs\n ? trimmedArgs.split(',').map((s) => stripQuotes(s.trim()))\n : [];\n\n const path = rawPath ? rawPath.split('.').flatMap((seg) => {\n const indexed: string[] = [];\n seg.replace(/([^\\[\\]]+)|\\[(\\d+)\\]/g, (_, prop, idx) => {\n if (prop) indexed.push(prop);\n else if (idx !== undefined) indexed.push(idx);\n return '';\n });\n return indexed;\n }) : [];\n\n return { fn, args, path };\n}\n\nfunction stripQuotes(s: string): string {\n if ((s.startsWith('\"') && s.endsWith('\"')) || (s.startsWith(\"'\") && s.endsWith(\"'\"))) {\n return s.slice(1, -1);\n }\n return s;\n}\n\nfunction walkPath(base: unknown, path: string[]): unknown {\n let cur: unknown = base;\n for (const key of path) {\n if (cur == null) return null;\n if (Array.isArray(cur)) {\n const idx = parseInt(key, 10);\n cur = Number.isFinite(idx) ? cur[idx] : null;\n } else if (typeof cur === 'object') {\n cur = (cur as Record<string, unknown>)[key];\n } else {\n return null;\n }\n }\n return cur ?? null;\n}\n\nfunction stringifyValue(v: unknown): string {\n if (v === null || v === undefined) return '';\n if (typeof v === 'string') return v;\n if (typeof v === 'number' || typeof v === 'boolean') return String(v);\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Function dispatch\n// ---------------------------------------------------------------------------\n\nfunction callFn(fn: string, args: string[], ctx: PlaceholderContext): unknown {\n const arg0 = args[0] ?? null;\n switch (fn) {\n case 'now':\n return buildNow(arg0 ?? ctx.timezone);\n case 'week_horizon':\n return buildWeekHorizon(parseHorizonDays(arg0), ctx.timezone);\n case 'user_info':\n return ctx.user ?? null;\n case 'user_name':\n return ctx.user?.user_name ?? null;\n case 'current_conversation_id':\n return ctx.conversation?.conversation_id ?? null;\n case 'previous_conversations':\n return takeN(ctx.previous_conversations, arg0);\n case 'state': {\n // Three forms:\n // {{state()}} → conversation-scope object (back-compat: prior\n // implementations only loaded conversation scope).\n // {{state(scope)}} → that scope's full object.\n // {{state(scope, name)}} → individual state value (or null → literal).\n if (args.length === 0) return ctx.state?.conversation ?? {};\n if (args.length === 1) {\n const scope = arg0 as 'conversation' | 'user' | string;\n if (scope === 'conversation' || scope === 'user') return ctx.state?.[scope] ?? {};\n return null;\n }\n const scope = args[0] as 'conversation' | 'user' | string;\n const name = args[1];\n if ((scope !== 'conversation' && scope !== 'user') || !name) return null;\n return ctx.state?.[scope]?.[name] ?? null;\n }\n case 'event_info':\n // arg may be a status filter (\"scheduled\") — we currently return the same\n // event_info regardless; arg is documented but not acted on.\n return ctx.event_info ?? null;\n case 'resources':\n return filterResources(ctx.resources, arg0);\n case 'resource_content':\n return arg0 ? ctx.resource_content?.[arg0] ?? null : null;\n case 'agent_settings':\n return arg0 ? ctx.agent_settings?.[arg0] ?? null : null;\n case 'agent_skills':\n return ctx.agent_skills ?? {};\n default:\n return null;\n }\n}\n\nfunction takeN(list: unknown[] | undefined, arg: string | null): unknown[] {\n const n = arg ? parseInt(arg, 10) : 0;\n if (!list || !Number.isFinite(n) || n <= 0) return [];\n return list.slice(0, n);\n}\n\nfunction filterResources(resources: PlaceholderResource[] | undefined, kind: string | null): PlaceholderResource[] {\n if (!resources) return [];\n if (!kind) return resources;\n if (kind === 'kb') return resources.filter((r) => r.resource_type === 'knowledge');\n if (kind === 'skill') return resources.filter((r) => r.resource_type === 'skill');\n return resources;\n}\n\n// ---------------------------------------------------------------------------\n// now() helpers\n// ---------------------------------------------------------------------------\n\ninterface NowResult {\n iso: string;\n weekday: string;\n time_of_day: string;\n date: string;\n time: string;\n [extra: string]: unknown;\n}\n\nfunction buildNow(timezone?: string | null): NowResult {\n const now = new Date();\n\n const parts = makeIntl(timezone, {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n weekday: 'long',\n }).formatToParts(now);\n\n const year = pickPart(parts, 'year');\n const month = pickPart(parts, 'month');\n const day = pickPart(parts, 'day');\n let hourStr = pickPart(parts, 'hour');\n if (hourStr === '24') hourStr = '00';\n const minute = pickPart(parts, 'minute');\n const weekday = pickPart(parts, 'weekday');\n\n const hour = parseInt(hourStr, 10);\n const result: NowResult = {\n iso: now.toISOString(),\n weekday,\n time_of_day: partOfDay(hour),\n date: `${year}-${month}-${day}`,\n time: `${hourStr}:${minute}`,\n };\n // Default stringification of the object returns the ISO string for the common\n // `{{now()}}` usage via JSON fallback. Provide a toString override for clarity.\n Object.defineProperty(result, 'toString', { value: () => result.iso });\n return result;\n}\n\nfunction partOfDay(hour: number): string {\n if (hour < 5) return 'night';\n if (hour < 12) return 'morning';\n if (hour < 17) return 'afternoon';\n if (hour < 21) return 'evening';\n return 'night';\n}\n\n/**\n * Build an `Intl.DateTimeFormat` in the given IANA timezone, falling back to the\n * runtime zone when `timeZone` is missing or invalid. Constructing the formatter\n * is the expensive (ICU) step, so this validates and builds in one shot — and it\n * honors slash-less zones like `UTC`/`GMT` that a prior `includes('/')` heuristic\n * wrongly dropped to the runtime zone (broke `UTC`-configured hubs).\n */\nfunction makeIntl(\n timeZone: string | null | undefined,\n options: Intl.DateTimeFormatOptions,\n): Intl.DateTimeFormat {\n try {\n return new Intl.DateTimeFormat('en-US', { timeZone: timeZone || undefined, ...options });\n } catch {\n return new Intl.DateTimeFormat('en-US', options);\n }\n}\n\n/** Extract a formatted part by type from `formatToParts` output. */\nfunction pickPart(parts: Intl.DateTimeFormatPart[], type: string): string {\n return parts.find((p) => p.type === type)?.value ?? '';\n}\n\n// ---------------------------------------------------------------------------\n// week_horizon() helpers\n// ---------------------------------------------------------------------------\n\nconst WEEKDAY_NAMES = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n] as const;\n\n/** Parse the day-count arg; default on missing/invalid/≤0, clamp to the cap. */\nfunction parseHorizonDays(arg: string | null): number {\n const n = arg ? parseInt(arg, 10) : NaN;\n if (!Number.isFinite(n) || n <= 0) return WEEK_HORIZON_DEFAULT_DAYS;\n return Math.min(n, WEEK_HORIZON_MAX_DAYS);\n}\n\n/**\n * Rolling `date → weekday` table for the next `days` calendar days (including\n * today), in the hub timezone. The model looks up the weekday instead of\n * deriving it from a date — which LLMs do unreliably.\n *\n * Weekday is read from the calendar date via `getUTCDay()` on a UTC-anchored\n * value, so no instant→tz conversion can shift the day; the timezone only\n * selects which calendar day is \"today\".\n */\nfunction buildWeekHorizon(days: number, timezone?: string | null): string {\n const parts = makeIntl(timezone, {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n }).formatToParts(new Date());\n\n const year = parseInt(pickPart(parts, 'year'), 10);\n const month = parseInt(pickPart(parts, 'month'), 10);\n const day = parseInt(pickPart(parts, 'day'), 10);\n\n const base = Date.UTC(year, month - 1, day);\n const lines: string[] = [];\n for (let i = 0; i < days; i++) {\n const d = new Date(base + i * 86_400_000);\n const y = d.getUTCFullYear();\n const m = String(d.getUTCMonth() + 1).padStart(2, '0');\n const dd = String(d.getUTCDate()).padStart(2, '0');\n const weekday = WEEKDAY_NAMES[d.getUTCDay()];\n const label = i === 0 ? 'today: ' : i === 1 ? 'tomorrow: ' : '';\n lines.push(`${label}${y}-${m}-${dd}/${weekday}`);\n }\n return lines.join('\\n');\n}\n","/**\n * WhatsApp message-template body-variable parsing & substitution.\n *\n * WhatsApp templates carry placeholders in their BODY text — either positional\n * (`{{1}}`, `{{2}}`) or named (`{{customer_name}}`). A template uses one format\n * throughout; `parameter_format` is POSITIONAL or NAMED.\n *\n * Single source of truth for placeholder detection: the outbound template ops\n * `detectParameterFormat` delegates here, and the closed-window team-send path\n * uses both functions to (a) tell the picker which variables a template needs\n * and (b) render the substituted transcript text.\n */\n\n/** Matches `{{1}}` / `{{customer_name}}` — word chars only (same alphabet as the legacy `detectParameterFormat`). */\nconst PLACEHOLDER_RE = /\\{\\{(\\w+)\\}\\}/g;\n\nexport interface ParsedTemplateBody {\n parameter_format: 'POSITIONAL' | 'NAMED';\n /** Distinct variable keys in render order. POSITIONAL: numeric ascending; NAMED: first-seen order. */\n variables: string[];\n}\n\n/**\n * Parse a template BODY text into its parameter format and ordered variable\n * keys. A body with no placeholders is POSITIONAL with an empty list. Format is\n * decided by the first placeholder (all-digits ⇒ POSITIONAL) — identical to the\n * legacy `detectParameterFormat`.\n */\nexport function parseTemplateBodyVariables(bodyText: string | null | undefined): ParsedTemplateBody {\n if (!bodyText) return { parameter_format: 'POSITIONAL', variables: [] };\n\n const seen: string[] = [];\n for (const match of bodyText.matchAll(PLACEHOLDER_RE)) {\n if (!seen.includes(match[1])) seen.push(match[1]);\n }\n if (seen.length === 0) return { parameter_format: 'POSITIONAL', variables: [] };\n\n if (/^\\d+$/.test(seen[0])) {\n return {\n parameter_format: 'POSITIONAL',\n variables: [...seen].sort((a, b) => Number(a) - Number(b)),\n };\n }\n return { parameter_format: 'NAMED', variables: seen };\n}\n\n/**\n * Substitute `{{key}}` placeholders in a template BODY with caller values.\n * A missing or empty value leaves the raw `{{key}}` token in place (so a\n * preview shows what is still unfilled). `values` may be a positional array\n * (index 0 → `{{1}}`) or a key→value record.\n */\nexport function substituteTemplateBody(\n bodyText: string | null | undefined,\n values: string[] | Record<string, string> | null | undefined,\n): string {\n if (!bodyText) return '';\n if (!values) return bodyText;\n\n const lookup = (key: string): string | undefined => {\n if (Array.isArray(values)) {\n const idx = Number(key);\n return Number.isInteger(idx) && idx >= 1 ? values[idx - 1] : undefined;\n }\n return values[key];\n };\n\n return bodyText.replace(PLACEHOLDER_RE, (raw, key: string) => {\n const value = lookup(key);\n return value === undefined || value === '' ? raw : value;\n });\n}\n","/**\n * Workspace layout descriptor + resolver.\n *\n * The CLI lays out hub-as-code under a single, product-namespaced root in the\n * user's git repo:\n *\n * wayai-ws/\n * org/ # org-as-code (shared resources)\n * hubs/<hub>/ # one folder per preview hub\n *\n * This replaces the legacy split layout (`workspace/<hub>/` for hubs + a\n * root-level `org/`). `resolveLayout` reads EITHER layout so existing repos —\n * and their CI that runs `wayai push` against a committed `workspace/` — keep\n * working until `wayai migrate` relocates them. New/fresh repos get the new\n * layout. We never read both at once (no split-brain): the new layout wins.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { WAYAI_WORKSPACE_LAYOUT } from '@wayai/core';\n\nexport interface WorkspaceLayout {\n /** Product-namespaced root dir at the git root, e.g. 'wayai-ws'. */\n wsDir: string;\n /** Subdir of `wsDir` holding hub folders, e.g. 'hubs'. */\n hubsSubdir: string;\n /** Subdir of `wsDir` holding org-as-code, e.g. 'org'. */\n orgSubdir: string;\n /** Pre-migration locations to fall back to on read. */\n legacy: { wsDir: string; orgAtRoot: string };\n}\n\n/**\n * The active CLI layout: the canonical dir NAMES from `@wayai/core`\n * (`WAYAI_WORKSPACE_LAYOUT`, shared with the backend `download_workspace`\n * endpoint) plus the CLI-only `legacy` fallback locations. The CLI bundles\n * `@wayai/core` at build time (tsup `noExternal`), so this is a direct import —\n * no hand-copied literal, no drift-guard needed.\n *\n * A second product (Rekor) is a second descriptor (`rekor-ws`), not a fork.\n */\nexport const WAYAI_LAYOUT: WorkspaceLayout = {\n ...WAYAI_WORKSPACE_LAYOUT,\n legacy: { wsDir: 'workspace', orgAtRoot: 'org' },\n};\n\nexport interface ResolvedLayout {\n /** Absolute dir whose direct children are hub folders. */\n hubsDir: string;\n /** Absolute dir for org-as-code (`resources.yaml` + `resources/`). */\n orgDir: string;\n /** True when reading the pre-migration layout (`workspace/` + root `org/`). */\n isLegacy: boolean;\n /** True when the new layout is active but stale legacy dirs ALSO exist. */\n legacyAlsoPresent: boolean;\n}\n\n/** True when `p` exists and is a directory (swallows ENOENT/EACCES). */\nexport function isDirectory(p: string): boolean {\n try {\n return fs.statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve the active hub + org directories for a repo, handling the legacy\n * layout. Pure (no side effects) so it's trivially testable — call\n * `warnLayoutOnce` separately for the user-facing nudge.\n */\nexport function resolveLayout(\n gitRoot: string,\n layout: WorkspaceLayout = WAYAI_LAYOUT,\n): ResolvedLayout {\n const newWs = path.join(gitRoot, layout.wsDir);\n const legacyWs = path.join(gitRoot, layout.legacy.wsDir);\n const legacyOrg = path.join(gitRoot, layout.legacy.orgAtRoot);\n\n const newExists = isDirectory(newWs);\n const legacyExists = isDirectory(legacyWs) || isDirectory(legacyOrg);\n\n if (newExists) {\n return {\n hubsDir: path.join(newWs, layout.hubsSubdir),\n orgDir: path.join(newWs, layout.orgSubdir),\n isLegacy: false,\n legacyAlsoPresent: legacyExists,\n };\n }\n\n if (legacyExists) {\n return {\n hubsDir: legacyWs,\n orgDir: legacyOrg,\n isLegacy: true,\n legacyAlsoPresent: false,\n };\n }\n\n // Fresh repo → new layout (materialized on demand by init/pull/org).\n return {\n hubsDir: path.join(newWs, layout.hubsSubdir),\n orgDir: path.join(newWs, layout.orgSubdir),\n isLegacy: false,\n legacyAlsoPresent: false,\n };\n}\n\n/** Convenience: the dir whose direct children are hub folders. */\nexport function resolveHubsDir(gitRoot: string): string {\n return resolveLayout(gitRoot).hubsDir;\n}\n\n/** Convenience: the org-as-code dir. */\nexport function resolveOrgDir(gitRoot: string): string {\n return resolveLayout(gitRoot).orgDir;\n}\n\n/**\n * Display label for the hubs dir relative to the git root (e.g. \"wayai-ws/hubs\",\n * or \"workspace\" for a legacy repo) — for user-facing messages. Falls back to the\n * canonical new-layout label (derived from WAYAI_LAYOUT, never a bare literal)\n * when not in a git repo.\n */\nexport function hubsDirLabel(gitRoot: string | null): string {\n if (!gitRoot) return path.join(WAYAI_LAYOUT.wsDir, WAYAI_LAYOUT.hubsSubdir);\n return path.relative(gitRoot, resolveLayout(gitRoot).hubsDir);\n}\n\nlet _layoutWarned = false;\n\n/** Reset the one-time warning guard (test-only). */\nexport function _resetLayoutWarning(): void {\n _layoutWarned = false;\n}\n\n/**\n * Emit a user-facing nudge about the layout, at most once per process for the\n * interactive case. When stale legacy dirs sit alongside the new layout, warn\n * LOUDLY on every run in non-TTY/CI — a CI `wayai push` that silently ignores\n * edits to a committed `workspace/` is a footgun. Callers must commit\n * `wayai migrate` in the same change that updates their CI.\n */\nexport function warnLayoutOnce(gitRoot: string): void {\n const r = resolveLayout(gitRoot);\n\n if (r.legacyAlsoPresent) {\n const msg =\n `Warning: both ${WAYAI_LAYOUT.wsDir}/ and legacy ${WAYAI_LAYOUT.legacy.wsDir}/ ` +\n `(or root ${WAYAI_LAYOUT.legacy.orgAtRoot}/) exist. The legacy dirs are IGNORED. ` +\n `Finish \\`wayai migrate\\` and delete them.`;\n // Non-TTY (CI): always loud, never suppressed.\n if (!process.stdout.isTTY) {\n console.warn(msg);\n return;\n }\n if (!_layoutWarned) {\n _layoutWarned = true;\n console.warn(msg);\n }\n return;\n }\n\n if (r.isLegacy && !_layoutWarned) {\n _layoutWarned = true;\n console.warn(\n `Note: using the legacy ${WAYAI_LAYOUT.legacy.wsDir}/ layout. ` +\n `Run \\`wayai migrate\\` to move to ${WAYAI_LAYOUT.wsDir}/.`,\n );\n }\n}\n","/**\n * Workspace detection and hub resolution for workspace-aware CLI commands.\n *\n * Hub folders live directly under the resolved \"hubs dir\" — `wayai-ws/hubs/`\n * on the current layout, or the legacy `workspace/` for un-migrated repos (see\n * `layout.ts` / `resolveLayout`). Each hub folder has a `hub.yaml` (or legacy\n * `wayai.yaml`) file. `WorkspaceInfo.workspaceDir` IS that hubs dir.\n */\n\nimport { execFileSync } from 'node:child_process';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as yaml from 'js-yaml';\nimport { slugify, UUID_RE } from './utils.js';\nimport { resolveLayout, hubsDirLabel, isDirectory } from './layout.js';\n\nexport interface HubLocation {\n hubFolder: string;\n hubId: string;\n hubEnvironment: string;\n}\n\n/** A hub folder where hub.yaml exists but has no hub_id yet (not created on platform). */\nexport interface NewHubLocation {\n hubFolder: string;\n hubName: string;\n hubType?: string;\n}\n\nexport interface WorkspaceInfo {\n gitRoot: string;\n workspaceDir: string;\n}\n\n/**\n * Find the git repository root. Returns null if not inside a git repo.\n */\nexport function findGitRoot(): string | null {\n try {\n return execFileSync('git', ['rev-parse', '--show-toplevel'], {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n } catch {\n return null;\n }\n}\n\n/**\n * Detect the hubs directory for the active layout (`wayai-ws/hubs/`, or the\n * legacy `workspace/`). Returns null if not in a git repo or the dir doesn't\n * exist yet (fresh repo before the first pull/init).\n */\nexport function detectWorkspace(): WorkspaceInfo | null {\n const gitRoot = findGitRoot();\n if (!gitRoot) return null;\n\n const { hubsDir } = resolveLayout(gitRoot);\n if (!fs.existsSync(hubsDir) || !fs.statSync(hubsDir).isDirectory()) {\n return null;\n }\n\n return { gitRoot, workspaceDir: hubsDir };\n}\n\n/**\n * Read hub metadata from a hub.yaml (or wayai.yaml) file.\n * Returns null if the file doesn't exist or lacks required fields.\n */\nfunction readHubYaml(yamlPath: string): { hubId: string; hubEnvironment: string } | null {\n if (!fs.existsSync(yamlPath)) return null;\n\n try {\n const content = fs.readFileSync(yamlPath, 'utf-8');\n const config = yaml.load(content) as { hub_id?: string; hub_environment?: string } | undefined;\n if (!config?.hub_id || !config.hub_environment) return null;\n return { hubId: config.hub_id, hubEnvironment: config.hub_environment };\n } catch {\n return null;\n }\n}\n\n/** Scan `workspace/<hub>/hub.yaml` for hubs already created on the platform. */\nexport function scanWorkspaceHubs(workspaceDir: string): HubLocation[] {\n const hubs: HubLocation[] = [];\n\n for (const top of safeReaddir(workspaceDir)) {\n const topDir = path.join(workspaceDir, top);\n if (!isDirectory(topDir)) continue;\n\n const meta = readHubYaml(path.join(topDir, 'hub.yaml'))\n || readHubYaml(path.join(topDir, 'wayai.yaml'));\n if (meta) {\n hubs.push({ hubFolder: topDir, hubId: meta.hubId, hubEnvironment: meta.hubEnvironment });\n }\n }\n\n return hubs;\n}\n\n/**\n * Read hub metadata from a hub.yaml that has NO hub_id yet (new hub).\n * Returns the hub name and optional hub_type. Returns null if hub_id is present or hub.name is missing.\n */\nfunction readNewHubYaml(yamlPath: string): { hubName: string; hubType?: string } | null {\n if (!fs.existsSync(yamlPath)) return null;\n\n try {\n const content = fs.readFileSync(yamlPath, 'utf-8');\n const config = yaml.load(content) as { hub_id?: string; hub?: { name?: string; hub_type?: string } } | undefined;\n // Skip if hub_id is present (already created on platform)\n if (config?.hub_id) return null;\n // Must have hub.name to be a valid new hub\n if (!config?.hub?.name) return null;\n return { hubName: config.hub.name, hubType: config.hub.hub_type };\n } catch {\n return null;\n }\n}\n\n/** Scan `workspace/<hub>/hub.yaml` for hubs not yet created on the platform (no `hub_id`). */\nexport function scanNewHubs(workspaceDir: string): NewHubLocation[] {\n const hubs: NewHubLocation[] = [];\n\n for (const top of safeReaddir(workspaceDir)) {\n const topDir = path.join(workspaceDir, top);\n if (!isDirectory(topDir)) continue;\n\n const meta = readNewHubYaml(path.join(topDir, 'hub.yaml'))\n || readNewHubYaml(path.join(topDir, 'wayai.yaml'));\n if (meta) {\n hubs.push({ hubFolder: topDir, hubName: meta.hubName, hubType: meta.hubType });\n }\n }\n\n return hubs;\n}\n\n/**\n * Compute the hub folder slug with preview disambiguation.\n * Production: slugify(hubName)\n * Preview: slugify(hubName) + \"-\" + slugify(previewLabel || branchName || hubId[0:8])\n *\n * IMPORTANT: This must produce identical output to the backend's computeHubSlug\n * (apps/backend/src/routes/api/ci/lookup.ts) and getHubFolderSlug\n * (apps/backend/src/routes/api/files/index.ts). All three now resolve to the\n * SAME canonical implementation: `slugify` here is a re-export of @wayai/core's\n * `slugifySkillName` (= `slugifyKebab(name, 64)`), which the backend imports\n * directly — no separate copy to keep in lockstep.\n */\nexport function getHubFolderSlug(\n hubName: string,\n hubEnvironment: string,\n hubId: string,\n previewLabel?: string | null,\n branchName?: string | null\n): string {\n const base = slugify(hubName);\n if (hubEnvironment !== 'preview') return base;\n const suffix = previewLabel || branchName || hubId.slice(0, 8);\n return `${base}-${slugify(suffix)}`;\n}\n\n/**\n * Resolve a hub folder in the workspace by hub_id match (handles folder renames),\n * falling back to a flat slugified hub path with preview disambiguation.\n */\nexport function resolveHubFolder(\n workspaceDir: string,\n hubId: string | undefined,\n hubName: string,\n hubEnvironment: string,\n previewLabel?: string | null,\n branchName?: string | null\n): string {\n // First: try to find by hub_id match (handles folder renames)\n if (hubId) {\n const allHubs = scanWorkspaceHubs(workspaceDir);\n const match = allHubs.find((h) => h.hubId === hubId);\n if (match) return match.hubFolder;\n }\n\n // Fallback: flat slugified path with preview disambiguation\n const hubFolderSlug = getHubFolderSlug(hubName, hubEnvironment, hubId || '', previewLabel, branchName);\n return path.join(workspaceDir, hubFolderSlug);\n}\n\n/**\n * Resolve the on-disk folder for a known hub_id by scanning the workspace.\n * Returns null when no workspace exists or the hub isn't materialized locally.\n */\nexport function findLocalHubFolder(hubId: string): string | null {\n const workspace = detectWorkspace();\n const gitRoot = findGitRoot();\n const workspaceDir = workspace?.workspaceDir ?? (gitRoot ? resolveLayout(gitRoot).hubsDir : null);\n if (!workspaceDir || !fs.existsSync(workspaceDir)) return null;\n const match = scanWorkspaceHubs(workspaceDir).find((h) => h.hubId === hubId);\n return match ? match.hubFolder : null;\n}\n\n/**\n * Get hub folders with uncommitted changes via `git status`.\n * Filters to hub.yaml, wayai.yaml, and agents/*.yaml/md files under workspace/.\n * Unlike the GitHub Action, does NOT filter by hub_environment.\n */\nexport function getChangedHubs(workspaceDir: string): HubLocation[] {\n const gitRoot = findGitRoot();\n if (!gitRoot) return [];\n\n // Get workspace path relative to git root for the git status query\n const relWorkspace = path.relative(gitRoot, workspaceDir);\n\n // Ensure the workspace is inside the git root (no path traversal)\n const normalizedRel = path.normalize(relWorkspace);\n if (normalizedRel.startsWith('..') || path.isAbsolute(normalizedRel)) {\n return [];\n }\n\n let statusOutput: string;\n try {\n statusOutput = execFileSync('git', ['status', '--porcelain', '-u', '--', `${relWorkspace}/`], {\n encoding: 'utf-8',\n cwd: gitRoot,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n } catch {\n return [];\n }\n\n // Split into lines, preserving leading spaces (porcelain status prefix uses them)\n const lines = statusOutput.split('\\n').filter((l) => l.length > 0);\n\n // Extract file paths from porcelain output (skip the 2-char status + space prefix)\n const changedFiles = lines.map((line) => {\n // Porcelain format: \"XY file\" or \"XY orig -> file\" (for renames)\n const filePart = line.slice(3);\n // Handle renames: \"orig -> dest\"\n const arrowIdx = filePart.indexOf(' -> ');\n return arrowIdx >= 0 ? filePart.slice(arrowIdx + 4) : filePart;\n });\n\n // Filter to hub config files (hub.yaml, wayai.yaml, agents/*.yaml, agents/*.md)\n const hubFiles = changedFiles.filter((file) => {\n return file.endsWith('/hub.yaml') || file.endsWith('hub.yaml')\n || file.endsWith('/wayai.yaml') || file.endsWith('wayai.yaml')\n || /\\/agents\\/[^/]+\\.(md|yaml)$/.test(file);\n });\n\n if (hubFiles.length === 0) return [];\n\n // Extract unique hub folder paths (absolute)\n const hubFolders = new Set<string>();\n\n for (const file of hubFiles) {\n const absFile = path.resolve(gitRoot, file);\n if (file.endsWith('hub.yaml') || file.endsWith('wayai.yaml')) {\n hubFolders.add(path.dirname(absFile));\n } else if (file.includes('/agents/')) {\n const agentsIndex = absFile.lastIndexOf('/agents/');\n hubFolders.add(absFile.substring(0, agentsIndex));\n }\n }\n\n // Read each hub folder's hub.yaml (or wayai.yaml)\n const hubs: HubLocation[] = [];\n\n for (const hubFolder of hubFolders) {\n const meta = readHubYaml(path.join(hubFolder, 'hub.yaml'))\n || readHubYaml(path.join(hubFolder, 'wayai.yaml'));\n if (meta) {\n hubs.push({ hubFolder, hubId: meta.hubId, hubEnvironment: meta.hubEnvironment });\n }\n }\n\n return hubs;\n}\n\nexport interface ResolvedHubPath {\n hubId: string;\n hubFolder: string;\n hubEnvironment: string;\n}\n\nexport interface UnresolvedSegments {\n orgPrefix?: string;\n hub: string;\n}\n\n/**\n * Parse a hub path (hub, or org/hub), resolve it locally if possible, and\n * return the parsed segments for API fallback if local resolution fails.\n *\n * Returns `{ resolved }` if found locally, or `{ segments }` for API lookup.\n */\nexport function resolveExplicitHubPath(\n hubPath: string\n): { resolved: ResolvedHubPath } | { segments: UnresolvedSegments } {\n const parts = hubPath.split('/');\n\n let hubSegment: string;\n let orgPrefix: string | undefined;\n\n if (parts.length === 1) {\n hubSegment = parts[0];\n } else if (parts.length === 2) {\n [orgPrefix, hubSegment] = parts;\n } else {\n throw new Error('Hub path must be hub or org/hub');\n }\n\n // Try local workspace resolution first (avoids API call, handles slugified folder names)\n const workspace = detectWorkspace();\n if (workspace) {\n const local = findHubByFolderName(workspace.workspaceDir, hubSegment);\n if (local) {\n return {\n resolved: {\n hubId: local.hubId,\n hubFolder: local.hubFolder,\n hubEnvironment: local.hubEnvironment,\n },\n };\n }\n }\n\n return { segments: { orgPrefix, hub: hubSegment } };\n}\n\n/** Find a hub in `workspace/<hub>/` whose folder basename matches the given name. */\nexport function findHubByFolderName(\n workspaceDir: string,\n hubFolderName: string,\n): HubLocation | null {\n const all = scanWorkspaceHubs(workspaceDir);\n return all.find((h) => path.basename(h.hubFolder) === hubFolderName) ?? null;\n}\n\n/**\n * Auto-rename a hub folder when the hub name has changed.\n * Compares current folder name against the expected slug and renames if different.\n * Returns the new folder path (or same path if no rename occurred).\n */\nexport function autoRenameHubFolder(\n currentFolder: string,\n hubName: string,\n hubEnvironment: string,\n hubId: string,\n previewLabel?: string | null,\n branchName?: string | null\n): string {\n const expectedSlug = getHubFolderSlug(hubName, hubEnvironment, hubId, previewLabel, branchName);\n const currentSlug = path.basename(currentFolder);\n\n if (currentSlug === expectedSlug) return currentFolder;\n\n const targetFolder = path.join(path.dirname(currentFolder), expectedSlug);\n\n if (fs.existsSync(targetFolder)) {\n console.warn(` Warning: skipping hub folder rename ${currentSlug} → ${expectedSlug} (target already exists)`);\n return currentFolder;\n }\n\n try {\n fs.renameSync(currentFolder, targetFolder);\n } catch (err) {\n console.warn(` Warning: could not rename ${currentSlug} → ${expectedSlug}: ${err instanceof Error ? err.message : String(err)}`);\n return currentFolder;\n }\n console.log(` Renamed hub folder ${currentSlug} → ${expectedSlug}`);\n console.log(` Note: stage this rename in git before committing (e.g. git add -A)`);\n return targetFolder;\n}\n\n/**\n * Walk from `process.cwd()` up to (and including) `workspaceDir`, returning\n * the first directory whose `hub.yaml` (or legacy `wayai.yaml`) carries a\n * valid `hub_id`/`hub_environment`. Returns null if no enclosing hub folder\n * is found before reaching the workspace root.\n */\nexport function findEnclosingHubFolder(workspaceDir: string): HubLocation | null {\n let current = process.cwd();\n const stop = path.resolve(workspaceDir);\n\n while (true) {\n const meta = readHubYaml(path.join(current, 'hub.yaml'))\n || readHubYaml(path.join(current, 'wayai.yaml'));\n if (meta) {\n return { hubFolder: current, hubId: meta.hubId, hubEnvironment: meta.hubEnvironment };\n }\n if (current === stop) return null;\n const parent = path.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n}\n\n/**\n * Resolve the active hub for a workspace-scoped command.\n *\n * Resolution order:\n * 1. `--hub <uuid|folder-name>` flag in args (and consumed from args[])\n * 2. cwd is inside a hub folder\n * 3. exactly one hub in workspace/\n * 4. otherwise: error and exit\n *\n * Returns the hub's `hub_id`. Mutates `args` to remove the consumed `--hub` pair.\n */\nexport function resolveActiveHubId(args: string[]): string {\n // Parse and remove --hub <value> from args\n let selector: string | undefined;\n const hubIdx = args.indexOf('--hub');\n if (hubIdx !== -1) {\n const next = args[hubIdx + 1];\n if (!next || next.startsWith('--')) {\n console.error('--hub requires a value (uuid or workspace folder name).');\n process.exit(1);\n }\n selector = next;\n args.splice(hubIdx, 2);\n }\n\n const workspace = detectWorkspace();\n const gitRoot = findGitRoot();\n const workspaceDir = workspace?.workspaceDir ?? (gitRoot ? resolveLayout(gitRoot).hubsDir : null);\n // Display label for messages: e.g. \"wayai-ws/hubs\" (new) or \"workspace\" (legacy).\n const wsLabel = hubsDirLabel(gitRoot);\n\n if (!workspaceDir || !fs.existsSync(workspaceDir)) {\n if (selector && UUID_RE.test(selector)) return selector;\n console.error(`No ${wsLabel}/ directory found. Run \\`wayai pull --hub <uuid>\\` to fetch a hub, or pass --hub <uuid>.`);\n process.exit(1);\n }\n\n const allHubs = scanWorkspaceHubs(workspaceDir);\n\n if (selector) {\n const match = allHubs.find((h) =>\n h.hubId === selector || path.basename(h.hubFolder) === selector,\n );\n if (match) return match.hubId;\n\n // Allow raw UUID even when not materialized locally — useful for read-only commands.\n if (UUID_RE.test(selector)) return selector;\n\n console.error(`No hub matching --hub ${selector} found in ${wsLabel}/.`);\n process.exit(1);\n }\n\n const enclosing = findEnclosingHubFolder(workspaceDir);\n if (enclosing) return enclosing.hubId;\n\n if (allHubs.length === 1) return allHubs[0].hubId;\n\n if (allHubs.length === 0) {\n console.error(`No hub folders found in ${wsLabel}/. Run \\`wayai pull --hub <uuid>\\` to fetch a hub for the first time, or pass --hub <uuid>.`);\n process.exit(1);\n }\n\n console.error(`Multiple hubs in ${wsLabel}/. Pass --hub <uuid|folder-name> or run from inside a hub folder:`);\n for (const h of allHubs) {\n console.error(` ${path.basename(h.hubFolder)} (${h.hubId})`);\n }\n process.exit(1);\n}\n\nfunction safeReaddir(dir: string): string[] {\n try {\n return fs.readdirSync(dir).filter((entry) => !entry.startsWith('.'));\n } catch {\n return [];\n }\n}\n","/**\n * Repo-level configuration — .wayai.yaml at git root\n * Scopes the workspace to a single organization. Hubs self-identify via\n * `hub_id` inside their own `hub.yaml`; the repo config carries only org info.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as yaml from 'js-yaml';\nimport { findGitRoot } from './workspace.js';\nimport { UUID_RE } from './utils.js';\n\nexport interface RepoConfig {\n organization_id: string;\n organization_name?: string;\n}\n\nconst LEGACY_FIELDS = ['project_id', 'project_name', 'hub_id', 'hub_name'] as const;\nlet legacyFieldsWarned = false;\n\nfunction warnAboutLegacyFields(found: readonly string[]): void {\n if (legacyFieldsWarned || found.length === 0) return;\n legacyFieldsWarned = true;\n console.warn(\n `Note: .wayai.yaml contains deprecated field(s) ${found.join(', ')}. ` +\n `These are ignored — only organization_id is used now. You can remove them.`,\n );\n}\n\n/**\n * Read .wayai.yaml from the git root. Returns null if not found or invalid.\n * Legacy fields (project_id, project_name, hub_id, hub_name) are tolerated and\n * ignored, with a one-time deprecation notice printed to stderr.\n */\nexport function readRepoConfig(root?: string): RepoConfig | null {\n const gitRoot = root ?? findGitRoot();\n if (!gitRoot) return null;\n\n const configPath = path.join(gitRoot, '.wayai.yaml');\n if (!fs.existsSync(configPath)) return null;\n\n try {\n const content = fs.readFileSync(configPath, 'utf-8');\n const config = yaml.load(content) as Record<string, unknown> | undefined;\n if (!config?.organization_id || typeof config.organization_id !== 'string') {\n // Detect old format: organization (name) instead of organization_id (UUID)\n if (config?.organization && typeof config.organization === 'string') {\n console.error(\n '.wayai.yaml uses the old format (organization: name). ' +\n 'Replace it with organization_id: <uuid>.'\n );\n }\n return null;\n }\n if (!UUID_RE.test(config.organization_id)) return null;\n\n const presentLegacy = LEGACY_FIELDS.filter((f) => config[f] !== undefined);\n warnAboutLegacyFields(presentLegacy);\n\n const organizationName = typeof config.organization_name === 'string' && config.organization_name.trim()\n ? config.organization_name.trim()\n : undefined;\n\n return {\n organization_id: config.organization_id,\n organization_name: organizationName,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Read .wayai.yaml from the git root. Exits with an error if not found or invalid.\n */\nexport function requireRepoConfig(root?: string): RepoConfig {\n const config = readRepoConfig(root);\n if (!config) {\n console.error('Missing or invalid .wayai.yaml at the repository root.');\n console.error('The file must contain organization_id:');\n console.error('');\n console.error(' organization_id: <your-org-uuid>');\n console.error('');\n console.error('Run `wayai init` to set up the workspace.');\n process.exit(1);\n }\n return config;\n}\n\n/**\n * Write .wayai.yaml to the git root.\n */\nexport function writeRepoConfig(config: RepoConfig, root?: string): string {\n const gitRoot = root ?? findGitRoot();\n if (!gitRoot) {\n throw new Error('Not inside a git repository. Run `git init` first.');\n }\n\n const configPath = path.join(gitRoot, '.wayai.yaml');\n const doc: Record<string, unknown> = { organization_id: config.organization_id };\n if (config.organization_name?.trim()) doc.organization_name = config.organization_name.trim();\n\n const content = yaml.dump(doc, { quotingType: '\"', forceQuotes: false });\n fs.writeFileSync(configPath, content, 'utf-8');\n\n return configPath;\n}\n","/**\n * Shared utility functions\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { slugifySkillName } from '@wayai/core';\nimport * as readline from 'node:readline';\n\nexport const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/**\n * Prompt the user for free-text input.\n */\nexport function prompt(question: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Prompt the user for yes/no confirmation. Returns true if they answer 'y'.\n */\nexport function confirm(question: string): Promise<boolean> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(`${question} [y/N]: `, (answer) => {\n rl.close();\n resolve(answer.trim().toLowerCase() === 'y');\n });\n });\n}\n\n/** Prompt for a secret, masking typed characters with `*`. */\nexport function promptSecret(question: string): Promise<string> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n\n // Mute output by replacing _writeToOutput\n const originalWrite = (rl as unknown as { _writeToOutput: (s: string) => void })._writeToOutput;\n let firstWrite = true;\n (rl as unknown as { _writeToOutput: (s: string) => void })._writeToOutput = function (s: string) {\n if (firstWrite) {\n // Let the prompt question through\n originalWrite.call(rl, s);\n firstWrite = false;\n } else {\n // Replace typed characters with *\n originalWrite.call(rl, '*'.repeat(s.replace(/[\\r\\n]/g, '').length));\n }\n };\n\n rl.question(question, (answer) => {\n // Restore and print newline\n (rl as unknown as { _writeToOutput: (s: string) => void })._writeToOutput = originalWrite;\n process.stdout.write('\\n');\n rl.close();\n resolve(answer);\n });\n });\n}\n\n/** Read all of stdin as a single trimmed string (for piped input). */\nexport function readStdin(): Promise<string> {\n return new Promise((resolve, reject) => {\n let data = '';\n process.stdin.setEncoding('utf-8');\n process.stdin.on('data', (chunk) => { data += chunk; });\n process.stdin.on('end', () => resolve(data.trim()));\n process.stdin.on('error', reject);\n });\n}\n\n/**\n * Kebab/snake slug for hub folders + skill names — the canonical\n * `slugifySkillName` from @wayai/core. The CLI now bundles @wayai/core (tsup\n * `noExternal`), so this is a real runtime import, not a hand-kept copy.\n */\nexport const slugify = slugifySkillName;\n\n/**\n * Resolve the hub YAML path in a folder: tries hub.yaml first, falls back to wayai.yaml.\n * Returns the full path if found, null otherwise.\n */\nexport function resolveHubYamlPath(hubFolder: string): string | null {\n for (const filename of ['hub.yaml', 'wayai.yaml']) {\n const yamlPath = path.join(hubFolder, filename);\n if (fs.existsSync(yamlPath)) return yamlPath;\n }\n return null;\n}\n\n/**\n * Try to detect hub_id from hub.yaml (or wayai.yaml) in the current working directory.\n * Returns null if no config file exists or it lacks hub_id.\n */\nexport async function detectHubFromCwd(): Promise<{ hubId: string; hubFolder: string } | null> {\n const yaml = await import('js-yaml');\n\n const cwd = process.cwd();\n const yamlPath = resolveHubYamlPath(cwd);\n if (!yamlPath) return null;\n\n const content = fs.readFileSync(yamlPath, 'utf-8');\n const config = yaml.load(content) as Record<string, unknown> | undefined;\n if (config?.hub_id && typeof config.hub_id === 'string') {\n return { hubId: config.hub_id, hubFolder: cwd };\n }\n\n return null;\n}\n\n/**\n * Parse a shorthand period string (e.g. \"7d\", \"4w\", \"3m\", \"1y\") into\n * { start, end, periodicity } for analytics queries.\n */\nexport function parsePeriod(period: string): { start: string; end: string; periodicity: string } {\n const match = period.match(/^(\\d+)([hdwmy])$/);\n if (!match) {\n throw new Error(`Invalid period \"${period}\". Use format like 24h, 7d, 4w, 3m, 1y.`);\n }\n\n const amount = parseInt(match[1], 10);\n const unit = match[2];\n\n if (amount <= 0) {\n throw new Error(`Invalid period \"${period}\". Amount must be greater than 0.`);\n }\n\n const now = new Date();\n const start = new Date(now);\n\n switch (unit) {\n case 'h':\n start.setHours(start.getHours() - amount);\n break;\n case 'd':\n start.setDate(start.getDate() - amount);\n break;\n case 'w':\n start.setDate(start.getDate() - amount * 7);\n break;\n case 'm':\n start.setMonth(start.getMonth() - amount);\n break;\n case 'y':\n start.setFullYear(start.getFullYear() - amount);\n break;\n }\n\n const periodicityMap: Record<string, string> = {\n h: 'daily',\n d: 'daily',\n w: 'weekly',\n m: 'monthly',\n y: 'yearly',\n };\n\n return {\n start: start.toISOString(),\n end: now.toISOString(),\n periodicity: periodicityMap[unit],\n };\n}\n\n/**\n * Parse --from/--to date strings into ISO format.\n * Accepts YYYY-MM-DD or full ISO datetime. Appends time suffix if needed.\n */\nexport function parseDateArg(date: string, position: 'from' | 'to'): string {\n if (date.includes('T')) {\n if (!/^\\d{4}-\\d{2}-\\d{2}T/.test(date) || isNaN(new Date(date).getTime())) {\n throw new Error(`Invalid date format \"${date}\". Use YYYY-MM-DD or full ISO datetime.`);\n }\n // Verify the date portion doesn't overflow (e.g., Feb 31 → Mar 3)\n const datePart = date.slice(0, 10);\n const [year, month, day] = datePart.split('-').map(Number);\n const parsed = new Date(Date.UTC(year, month - 1, day));\n if (parsed.getUTCFullYear() !== year || parsed.getUTCMonth() !== month - 1 || parsed.getUTCDate() !== day) {\n throw new Error(`Invalid date \"${date}\". Not a valid calendar date.`);\n }\n return date;\n }\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\n throw new Error(`Invalid date format \"${date}\". Use YYYY-MM-DD (e.g., 2026-01-01).`);\n }\n // Verify the date components are valid (JS Date silently overflows, e.g., Feb 31 → Mar 3)\n const [year, month, day] = date.split('-').map(Number);\n const parsed = new Date(Date.UTC(year, month - 1, day));\n if (parsed.getUTCFullYear() !== year || parsed.getUTCMonth() !== month - 1 || parsed.getUTCDate() !== day) {\n throw new Error(`Invalid date \"${date}\". Not a valid calendar date.`);\n }\n return position === 'from' ? `${date}T00:00:00Z` : `${date}T23:59:59Z`;\n}\n\n/**\n * Resolve organization_id from: --org flag → .wayai.yaml → single-org auto-select.\n * Returns { organizationId, organizationName } or exits with an error.\n */\nexport async function resolveOrganizationId(\n client: { organizations(): Promise<{ organizations: Array<{ id: string; name: string }> }> },\n orgIdFlag?: string,\n): Promise<{ organizationId: string; organizationName?: string }> {\n if (orgIdFlag) {\n if (!UUID_RE.test(orgIdFlag)) {\n console.error('Invalid --org value. Expected a UUID.');\n process.exit(1);\n }\n return { organizationId: orgIdFlag };\n }\n\n // Try .wayai.yaml\n // Lazy import to avoid circular dependency\n const { readRepoConfig } = await import('./repo-config.js');\n const repoConfig = readRepoConfig();\n if (repoConfig) {\n return { organizationId: repoConfig.organization_id, organizationName: repoConfig.organization_name };\n }\n\n // Fetch orgs and auto-select if single\n const { organizations } = await client.organizations();\n if (organizations.length === 0) {\n console.error('No organizations found. Create one in the WayAI platform first.');\n process.exit(1);\n }\n if (organizations.length === 1) {\n console.log(`Organization: ${organizations[0].name}`);\n return { organizationId: organizations[0].id, organizationName: organizations[0].name };\n }\n\n console.error('Multiple organizations found. Specify one with --org <uuid>:');\n for (const org of organizations) {\n console.error(` ${org.id} ${org.name}`);\n }\n process.exit(1);\n}\n\nexport function parsePositiveIntFlag(name: string, raw: string | undefined): number {\n if (raw === undefined) {\n console.error(`${name} requires a value`);\n process.exit(1);\n }\n const n = Number(raw);\n if (!Number.isFinite(n) || n <= 0 || !Number.isInteger(n)) {\n console.error(`${name} must be a positive integer.`);\n process.exit(1);\n }\n return n;\n}\n\n/**\n * Low-level predicate: true when `--help`/`-h` appears anywhere in args.\n *\n * The match is deliberately broad (and so fail-safe — printing help is\n * non-destructive). The one realistic command that takes a free-text value that\n * could *equal* `--help` is `report` (`report create --description \"--help\"`),\n * and that command owns its help handling so it's excluded from interception by\n * `shouldInterceptHelp` — its own parser sees the value verbatim. Used both to\n * gate that interception and to skip the update check on any help invocation.\n */\nexport function wantsHelp(args: string[]): boolean {\n return args.includes('--help') || args.includes('-h');\n}\n\n/**\n * Whether the top-level entry should short-circuit to the GLOBAL help BEFORE\n * dispatching `command`. This stops side-effecting subcommands (e.g.\n * `run-eval`, which would otherwise create + run a billable eval session) from\n * executing on a `--help`/`-h` request.\n *\n * Returns false — i.e. falls through to the command's own handler — for:\n * - the top-level `help` slot (handled by the dispatch switch itself),\n * - an absent command, and\n * - commands in `ownHelpCommands` (e.g. `eval`, `admin`, `report`), which\n * render their own richer command-specific help; intercepting them here would\n * downgrade that to the global help.\n */\nexport function shouldInterceptHelp(\n command: string | undefined,\n args: string[],\n ownHelpCommands: ReadonlySet<string>,\n): boolean {\n if (!command || command === 'help') return false;\n if (ownHelpCommands.has(command)) return false;\n return wantsHelp(args);\n}\n\n/** Returns true if `latest` is a newer semver than `current` */\nexport function isNewerVersion(latest: string, current: string): boolean {\n const strip = (v: string) => v.replace(/[-+].*$/, '');\n const l = strip(latest).split('.').map(Number);\n const c = strip(current).split('.').map(Number);\n for (let i = 0; i < Math.max(l.length, c.length); i++) {\n const lv = l[i] ?? 0;\n const cv = c[i] ?? 0;\n if (lv > cv) return true;\n if (lv < cv) return false;\n }\n return false;\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\n\nexport const MAX_AGE_24H_MS = 24 * 60 * 60 * 1000;\n\nexport const CLI_CACHE_FILE = 'update-check.json';\nexport const SKILL_CACHE_FILE = 'skill-update-check.json';\n\nexport interface VersionCache {\n lastCheck: number;\n latest: string | null;\n}\n\nexport function getVersionCachePath(filename: string = CLI_CACHE_FILE): string {\n return join(homedir(), '.wayai', filename);\n}\n\nexport function readVersionCache(filename: string = CLI_CACHE_FILE): VersionCache | null {\n try {\n const path = getVersionCachePath(filename);\n if (!existsSync(path)) return null;\n const parsed = JSON.parse(readFileSync(path, 'utf-8')) as VersionCache;\n if (typeof parsed.lastCheck !== 'number') return null;\n if (parsed.latest !== null && typeof parsed.latest !== 'string') return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport function readCachedLatest(\n filename: string = CLI_CACHE_FILE,\n maxAgeMs: number = MAX_AGE_24H_MS,\n): string | null {\n const cache = readVersionCache(filename);\n if (!cache?.latest) return null;\n if (Date.now() - cache.lastCheck > maxAgeMs) return null;\n return cache.latest;\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport * as yaml from 'js-yaml';\nimport { isNewerVersion } from './utils.js';\n\n// Path must match the destination layout written by `.github/workflows/sync-public-skill.yml`.\nexport const DEFAULT_SKILL_RAW_URL =\n 'https://raw.githubusercontent.com/wayai-pro/wayai-skill/main/skills/wayai/SKILL.md';\n\nexport const SKILL_INSTALL_PATHS = [\n '.claude/skills/wayai/SKILL.md',\n '.opencode/skills/wayai/SKILL.md',\n '.agents/skills/wayai/SKILL.md',\n] as const;\n\nexport interface InstalledSkill {\n path: string;\n version: string | null;\n}\n\nexport function parseFrontmatterVersion(content: string): string | null {\n const match = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---(?:\\r?\\n|$)/.exec(content);\n if (!match) return null;\n let parsed: unknown;\n try {\n parsed = yaml.load(match[1]);\n } catch {\n return null;\n }\n if (!parsed || typeof parsed !== 'object') return null;\n const v = (parsed as Record<string, unknown>).version;\n return typeof v === 'string' ? v : null;\n}\n\nexport function findInstalledSkills(projectRoot: string): InstalledSkill[] {\n const found: InstalledSkill[] = [];\n for (const rel of SKILL_INSTALL_PATHS) {\n const path = join(projectRoot, rel);\n if (!existsSync(path)) continue;\n let version: string | null = null;\n try {\n version = parseFrontmatterVersion(readFileSync(path, 'utf-8'));\n } catch {\n // Unreadable\n }\n found.push({ path, version });\n }\n return found;\n}\n\nexport function lowestInstalledVersion(installs: InstalledSkill[]): string | null {\n const versions = installs\n .map((i) => i.version)\n .filter((v): v is string => v !== null);\n if (versions.length === 0) return null;\n return versions.reduce((lowest, v) => (isNewerVersion(lowest, v) ? v : lowest));\n}\n","/**\n * CLI configuration — non-secret metadata at ~/.wayai/config.json.\n *\n * Tokens themselves live in the OS keyring (see token-store.ts). This file\n * holds only metadata that survives a logout/login cycle gracefully if needed.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\n\n/**\n * Non-secret CLI configuration. Token fields removed in v0.4.0 — they now live\n * in the OS keyring. token_expires_at is metadata (timestamp, not a secret) and\n * stays here so the refresh path can decide when to refresh without unlocking\n * the keyring just to read the expiry.\n */\nexport interface CliConfig {\n api_url: string;\n /** ISO 8601 expiry of the OAuth access token (metadata, not secret). */\n token_expires_at?: string;\n /**\n * Report-action nudge dedup keys the user has already been nudged about, so the login/status\n * reminder fires once per notifiable event. Shipped keys are `<report_id>:shipped:<contest_count>`\n * (one per shipment — a re-shipped fix re-nudges, matching the re-firing shipped email); dismissed\n * keys are `<report_id>:dismissed` (once-ever, matching the once-ever dismissed email). Capped to\n * the most-recent entries by the writer.\n */\n nudged_report_ids?: string[];\n}\n\n// Resolved per-call so tests can redirect via $HOME and any runtime HOME change\n// (e.g., su -) is picked up. Frozen module-level constants previously made tests\n// write to the user's real ~/.wayai/.\nfunction configDir(): string { return path.join(os.homedir(), '.wayai'); }\nfunction configPath(): string { return path.join(configDir(), 'config.json'); }\n\nexport function getConfigPath(): string {\n return configPath();\n}\n\n/**\n * Read the metadata config. Tokens are NOT included — fetch them via\n * `getToken()` from token-store. Returns null only when the user has never\n * logged in (no config file at all).\n */\nexport function readConfig(): CliConfig | null {\n if (!fs.existsSync(configPath())) return null;\n\n try {\n const content = fs.readFileSync(configPath(), 'utf-8');\n const parsed = JSON.parse(content);\n if (!parsed.api_url) return null;\n return {\n api_url: parsed.api_url,\n token_expires_at: parsed.token_expires_at,\n nudged_report_ids: Array.isArray(parsed.nudged_report_ids)\n ? parsed.nudged_report_ids.filter((x: unknown): x is string => typeof x === 'string')\n : undefined,\n };\n } catch {\n return null;\n }\n}\n\nexport function writeConfig(config: CliConfig): void {\n if (!fs.existsSync(configDir())) {\n fs.mkdirSync(configDir(), { recursive: true });\n }\n\n // Preserve any existing metadata fields (e.g., user_id) that may be added later.\n let existing: Record<string, unknown> = {};\n if (fs.existsSync(configPath())) {\n try {\n existing = JSON.parse(fs.readFileSync(configPath(), 'utf-8'));\n } catch { /* corrupt — overwrite */ }\n }\n // Drop any legacy plaintext token fields that may still be present.\n delete existing.token;\n delete existing.access_token;\n delete existing.refresh_token;\n\n Object.assign(existing, config);\n\n fs.writeFileSync(configPath(), JSON.stringify(existing, null, 2) + '\\n', {\n mode: 0o600, // owner-only read/write\n });\n}\n\nexport function deleteConfig(): void {\n if (fs.existsSync(configPath())) {\n fs.unlinkSync(configPath());\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\n\n// Canonical token-type classification from @wayai/core. The CLI now bundles\n// @wayai/core (tsup `noExternal`), so this is a real runtime import — no copy.\nimport { identifyTokenType } from '@wayai/core';\nexport { identifyTokenType };\nexport type { TokenType } from '@wayai/core';\n\nconst KEYRING_SERVICE = 'wayai';\nconst KEY_WAY_TOKEN = 'way_token';\nconst KEY_OAUTH_ACCESS = 'oauth_access_token';\nconst KEY_OAUTH_REFRESH = 'oauth_refresh_token';\n\n// Resolved per-call (not at module load) so tests can redirect via $HOME and\n// production code picks up any runtime HOME changes (e.g., su -).\nfunction configDir(): string { return path.join(os.homedir(), '.wayai'); }\nfunction configPath(): string { return path.join(configDir(), 'config.json'); }\n\nexport type ResolvedToken =\n | { kind: 'way'; token: string }\n | { kind: 'oauth'; access_token: string; refresh_token?: string; expires_at?: string };\n\nlet keyringCache: KeyringBinding | null | undefined;\ninterface KeyringBinding {\n getPassword(service: string, account: string): Promise<string | null>;\n setPassword(service: string, account: string, password: string): Promise<void>;\n deletePassword(service: string, account: string): Promise<boolean>;\n}\n\n// Cross-platform manual cleanup hint. @napi-rs/keyring targets macOS Keychain,\n// libsecret on Linux, and Windows Credential Manager — the shell command to\n// evict a stuck entry differs per OS, so we tailor the message rather than\n// printing a macOS-only `security` invocation to Linux/Windows users.\nfunction manualCleanupCommand(account: string): string {\n if (process.platform === 'darwin') {\n return `security delete-generic-password -s ${KEYRING_SERVICE} -a ${account}`;\n }\n if (process.platform === 'win32') {\n return `cmdkey /delete:${KEYRING_SERVICE}/${account}`;\n }\n if (process.platform === 'linux') {\n return `secret-tool clear service ${KEYRING_SERVICE} account ${account}`;\n }\n return `(remove the entry with service=\"${KEYRING_SERVICE}\" account=\"${account}\" from your OS credential store)`;\n}\n\n/**\n * A keyring slot was deleted but a subsequent getPassword still returned a\n * value — the underlying secret store accepted the delete call without\n * actually removing the entry. Typically a macOS Keychain ACL surviving\n * from a prior login. Until the slot is cleared, writes to other slots\n * cannot reliably override what reads pick up first.\n */\nexport class StaleKeyringSlotError extends Error {\n constructor(public readonly account: string) {\n super(\n `Stale credential remains in OS keyring slot \"${account}\" after delete. ` +\n `This usually means a prior login left an ACL the current process can't override. ` +\n `Clean it up manually and retry:\\n` +\n ` ${manualCleanupCommand(account)}`,\n );\n this.name = 'StaleKeyringSlotError';\n }\n}\n\nasync function clearSlot(keyring: KeyringBinding, account: string): Promise<boolean> {\n await keyring.deletePassword(KEYRING_SERVICE, account);\n // A throw from getPassword (locked keychain, libsecret hiccup) means we\n // cannot confirm the slot is empty — treat the same as \"stale entry\n // survived\" so callers throw StaleKeyringSlotError rather than degrading\n // to file fallback (which would write OAuth alongside a possibly-stuck\n // way_, reproducing the masked-credential bug this helper exists to stop).\n try {\n return (await keyring.getPassword(KEYRING_SERVICE, account)) === null;\n } catch {\n return false;\n }\n}\n\nasync function getKeyring(): Promise<KeyringBinding | null> {\n if (keyringCache !== undefined) return keyringCache;\n try {\n const mod = await import('@napi-rs/keyring');\n const Entry = mod.Entry;\n keyringCache = {\n async getPassword(service, account) {\n try { return new Entry(service, account).getPassword(); } catch { return null; }\n },\n async setPassword(service, account, password) {\n new Entry(service, account).setPassword(password);\n },\n async deletePassword(service, account) {\n try { return new Entry(service, account).deletePassword(); } catch { return false; }\n },\n };\n } catch {\n keyringCache = null;\n }\n return keyringCache;\n}\n\ninterface LegacyConfigWithTokens {\n api_url?: string;\n token?: string;\n access_token?: string;\n refresh_token?: string;\n token_expires_at?: string;\n}\n\nfunction readLegacyConfigFile(): LegacyConfigWithTokens | null {\n if (!fs.existsSync(configPath())) return null;\n try {\n return JSON.parse(fs.readFileSync(configPath(), 'utf-8')) as LegacyConfigWithTokens;\n } catch {\n return null;\n }\n}\n\nfunction stripTokensFromFile(): void {\n const legacy = readLegacyConfigFile();\n if (!legacy) return;\n // token_expires_at is a timestamp, not a secret — keep it as metadata so the\n // refresh path can decide when to refresh without reading the keyring.\n const cleaned: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(legacy)) {\n if (k === 'token' || k === 'access_token' || k === 'refresh_token') continue;\n cleaned[k] = v;\n }\n fs.writeFileSync(configPath(), JSON.stringify(cleaned, null, 2) + '\\n', { mode: 0o600 });\n}\n\nexport async function migrateLegacyTokens(): Promise<ResolvedToken | null> {\n const legacy = readLegacyConfigFile();\n if (!legacy) return null;\n if (!legacy.token && !legacy.access_token) return null;\n\n const keyring = await getKeyring();\n\n if (legacy.token) {\n if (keyring) {\n try {\n await keyring.setPassword(KEYRING_SERVICE, KEY_WAY_TOKEN, legacy.token);\n // Strip failure leaves plaintext on disk until the next CLI invocation\n // re-attempts — keyring write was successful, so functionally OK.\n try { stripTokensFromFile(); } catch (err) {\n console.warn(`wayai: failed to strip legacy token from ~/.wayai/config.json (${(err as Error).message}); will retry next run.`);\n }\n } catch (err) {\n // Keyring write failed (locked keychain, etc.); leave the legacy file\n // intact so the file-fallback read keeps working and the next CLI run\n // can retry the migration.\n console.warn(`wayai: keyring migration failed (${(err as Error).message}); continuing with file-backed token.`);\n }\n }\n return { kind: 'way', token: legacy.token };\n }\n\n if (legacy.access_token) {\n if (keyring) {\n try {\n await keyring.setPassword(KEYRING_SERVICE, KEY_OAUTH_ACCESS, legacy.access_token);\n if (legacy.refresh_token) {\n await keyring.setPassword(KEYRING_SERVICE, KEY_OAUTH_REFRESH, legacy.refresh_token);\n }\n try { stripTokensFromFile(); } catch (err) {\n console.warn(`wayai: failed to strip legacy tokens from ~/.wayai/config.json (${(err as Error).message}); will retry next run.`);\n }\n } catch (err) {\n console.warn(`wayai: keyring migration failed (${(err as Error).message}); continuing with file-backed tokens.`);\n }\n }\n return {\n kind: 'oauth',\n access_token: legacy.access_token,\n refresh_token: legacy.refresh_token,\n expires_at: legacy.token_expires_at,\n };\n }\n\n return null;\n}\n\nexport async function getToken(): Promise<ResolvedToken | null> {\n // Env override has highest precedence — supports CI, container, op-run injection.\n const envToken = process.env.WAYAI_TOKEN;\n if (envToken) {\n if (identifyTokenType(envToken) === 'way_token') {\n return { kind: 'way', token: envToken };\n }\n return { kind: 'oauth', access_token: envToken };\n }\n\n const keyring = await getKeyring();\n\n if (keyring) {\n const wayToken = await keyring.getPassword(KEYRING_SERVICE, KEY_WAY_TOKEN);\n if (wayToken) return { kind: 'way', token: wayToken };\n\n const accessToken = await keyring.getPassword(KEYRING_SERVICE, KEY_OAUTH_ACCESS);\n if (accessToken) {\n const refreshToken = await keyring.getPassword(KEYRING_SERVICE, KEY_OAUTH_REFRESH);\n const expiresAt = readMetadataExpiresAt();\n return {\n kind: 'oauth',\n access_token: accessToken,\n refresh_token: refreshToken ?? undefined,\n expires_at: expiresAt ?? undefined,\n };\n }\n }\n\n const legacy = readLegacyConfigFile();\n if (!legacy) return null;\n if (legacy.token) return { kind: 'way', token: legacy.token };\n if (legacy.access_token) {\n return {\n kind: 'oauth',\n access_token: legacy.access_token,\n refresh_token: legacy.refresh_token,\n expires_at: legacy.token_expires_at,\n };\n }\n return null;\n}\n\nexport async function setWayToken(token: string): Promise<void> {\n const keyring = await getKeyring();\n if (keyring) {\n try {\n await keyring.setPassword(KEYRING_SERVICE, KEY_WAY_TOKEN, token);\n clearMetadataExpiresAt();\n // Read precedence favors way_ over OAuth, so a leftover OAuth credential\n // won't shadow this token — but `wayai logout` then misses it. Warn so\n // the user can sweep it manually. Slots are independent — parallelize.\n const [accessCleared, refreshCleared] = await Promise.all([\n clearSlot(keyring, KEY_OAUTH_ACCESS),\n clearSlot(keyring, KEY_OAUTH_REFRESH),\n ]);\n const stuck = [\n accessCleared ? null : KEY_OAUTH_ACCESS,\n refreshCleared ? null : KEY_OAUTH_REFRESH,\n ].filter((a): a is string => a !== null);\n if (stuck.length > 0) {\n console.warn(\n [\n `wayai: stale OAuth credential persists in OS keyring after delete. Commands work, but \\`wayai logout\\` won't fully clear. Manually:`,\n ...stuck.map((a) => ` ${manualCleanupCommand(a)}`),\n ].join('\\n'),\n );\n }\n return;\n } catch (err) {\n // Runtime keyring failure (locked keychain, broken libsecret session, etc.) —\n // degrade to file storage. Visible warning so users notice the downgrade.\n console.warn(`wayai: keyring write failed (${(err as Error).message}); falling back to file storage.`);\n }\n }\n writeFileFallback({ token });\n}\n\nexport async function setOAuthTokens(\n access_token: string,\n refresh_token: string | undefined,\n expires_at: string,\n): Promise<void> {\n const keyring = await getKeyring();\n if (keyring) {\n try {\n // way_ wins the read race, so a leftover way_ would silently mask the\n // OAuth tokens we're about to write — every subsequent API call would\n // send the dead way_ and the backend would reject it. Verify the slot\n // is actually empty after deletePassword and fail loudly otherwise.\n if (!(await clearSlot(keyring, KEY_WAY_TOKEN))) {\n throw new StaleKeyringSlotError(KEY_WAY_TOKEN);\n }\n await keyring.setPassword(KEYRING_SERVICE, KEY_OAUTH_ACCESS, access_token);\n if (refresh_token) {\n await keyring.setPassword(KEYRING_SERVICE, KEY_OAUTH_REFRESH, refresh_token);\n }\n writeMetadataExpiresAt(expires_at);\n return;\n } catch (err) {\n // StaleKeyringSlotError propagates — file fallback can't help because\n // the next read still hits the stuck keyring slot first.\n if (err instanceof StaleKeyringSlotError) throw err;\n console.warn(`wayai: keyring write failed (${(err as Error).message}); falling back to file storage.`);\n }\n }\n writeFileFallback({ access_token, refresh_token, token_expires_at: expires_at });\n}\n\nexport async function clearTokens(): Promise<void> {\n const keyring = await getKeyring();\n if (keyring) {\n // Slots are independent — run all three in parallel (3 keyring RPCs vs 6).\n const slots = [KEY_WAY_TOKEN, KEY_OAUTH_ACCESS, KEY_OAUTH_REFRESH] as const;\n const cleared = await Promise.all(slots.map((account) => clearSlot(keyring, account)));\n for (const [i, ok] of cleared.entries()) {\n if (!ok) {\n const account = slots[i]!;\n console.warn(\n `wayai: could not clear keyring slot \"${account}\". Subsequent commands may still pick the stale token. Manually:\\n` +\n ` ${manualCleanupCommand(account)}`,\n );\n }\n }\n }\n if (fs.existsSync(configPath())) {\n fs.unlinkSync(configPath());\n }\n}\n\nfunction readMetadataExpiresAt(): string | null {\n const legacy = readLegacyConfigFile();\n return legacy?.token_expires_at ?? null;\n}\n\nfunction writeMetadataExpiresAt(expires_at: string): void {\n const existing = readLegacyConfigFile() ?? {};\n delete existing.token;\n delete existing.access_token;\n delete existing.refresh_token;\n existing.token_expires_at = expires_at;\n ensureConfigDir();\n fs.writeFileSync(configPath(), JSON.stringify(existing, null, 2) + '\\n', { mode: 0o600 });\n}\n\nfunction clearMetadataExpiresAt(): void {\n const existing = readLegacyConfigFile();\n if (!existing) return;\n // Strip any orphan token fields from prior file-fallback sessions while we're\n // here — keeps the metadata file token-free once keyring is in use.\n delete existing.token;\n delete existing.access_token;\n delete existing.refresh_token;\n delete existing.token_expires_at;\n ensureConfigDir();\n fs.writeFileSync(configPath(), JSON.stringify(existing, null, 2) + '\\n', { mode: 0o600 });\n}\n\nfunction ensureConfigDir(): void {\n if (!fs.existsSync(configDir())) {\n fs.mkdirSync(configDir(), { recursive: true });\n }\n}\n\nfunction writeFileFallback(tokens: Partial<LegacyConfigWithTokens>): void {\n const existing = readLegacyConfigFile() ?? {};\n // Strip ALL token fields before merging — without this, a mode switch in the\n // no-keyring path (way → OAuth or vice versa) would leave the old mode's\n // fields on disk and `getToken` would return the stale value because the\n // file-fallback read checks `token` before `access_token`.\n delete existing.token;\n delete existing.access_token;\n delete existing.refresh_token;\n delete existing.token_expires_at;\n Object.assign(existing, tokens);\n ensureConfigDir();\n fs.writeFileSync(configPath(), JSON.stringify(existing, null, 2) + '\\n', { mode: 0o600 });\n}\n\n/** Test hook — production code must not call this. */\nexport function __setKeyringForTesting(binding: KeyringBinding | null): void {\n keyringCache = binding;\n}\n\n/** Test hook — production code must not call this. */\nexport function __resetKeyringForTesting(): void {\n keyringCache = undefined;\n}\n","/**\n * Authentication — OAuth 2.1 + PKCE browser login + way_ token fallback\n *\n * Two login paths:\n * 1. Browser login (default): OAuth 2.1 with PKCE → JWT + refresh token\n * 2. Token login (--token): User pastes a way_ scoped token directly\n *\n * The CLI exchanges codes directly with AuthKit's token endpoint.\n */\n\nimport * as crypto from 'node:crypto';\nimport * as http from 'node:http';\nimport { readConfig, writeConfig } from './config.js';\nimport type { CliConfig } from './config.js';\nimport { getToken, setOAuthTokens, clearTokens, migrateLegacyTokens } from './token-store.js';\nimport { setSentryUser } from './sentry.js';\n\n// =============================================================================\n// PKCE Utilities\n// =============================================================================\n\nexport function generateCodeVerifier(): string {\n return crypto.randomBytes(32).toString('base64url');\n}\n\nexport async function generateCodeChallenge(verifier: string): Promise<string> {\n const hash = crypto.createHash('sha256').update(verifier).digest();\n return hash.toString('base64url');\n}\n\nexport function generateState(): string {\n return crypto.randomBytes(16).toString('base64url');\n}\n\n// =============================================================================\n// AuthKit Token Exchange\n// =============================================================================\n\n/**\n * Convert a token lifetime in seconds (as returned by AuthKit) into an absolute\n * ISO 8601 timestamp suitable for `token_expires_at` in the CLI config.\n */\nexport function expiresInToIso(expiresInSeconds: number): string {\n return new Date(Date.now() + expiresInSeconds * 1000).toISOString();\n}\n\nexport async function exchangeCodeForTokens(\n authkitDomain: string,\n clientId: string,\n code: string,\n codeVerifier: string,\n redirectUri: string,\n): Promise<{ access_token: string; refresh_token?: string; expires_in: number }> {\n const response = await fetch(`${authkitDomain}/oauth2/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n code_verifier: codeVerifier,\n redirect_uri: redirectUri,\n client_id: clientId,\n }).toString(),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Token exchange failed (${response.status}): ${body}`);\n }\n\n return response.json() as Promise<{\n access_token: string;\n refresh_token?: string;\n expires_in: number;\n }>;\n}\n\nexport async function refreshAccessToken(\n authkitDomain: string,\n clientId: string,\n refreshToken: string,\n): Promise<{ access_token: string; refresh_token?: string; expires_in: number }> {\n const response = await fetch(`${authkitDomain}/oauth2/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n client_id: clientId,\n }).toString(),\n });\n\n if (!response.ok) {\n const status = response.status;\n const body = await response.text();\n\n if (status === 400 || status === 401) {\n let isInvalidGrant = false;\n try {\n const parsed = JSON.parse(body);\n if (parsed.error === 'invalid_grant') isInvalidGrant = true;\n } catch { /* non-JSON body */ }\n if (isInvalidGrant) throw new Error('SESSION_EXPIRED');\n }\n\n throw new Error(`Token refresh failed (${status}): ${body}`);\n }\n\n return response.json() as Promise<{\n access_token: string;\n refresh_token?: string;\n expires_in: number;\n }>;\n}\n\nexport async function validateToken(apiUrl: string, token: string): Promise<void> {\n const response = await fetch(`${apiUrl}/api/auth/me`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!response.ok) {\n throw new Error(`Token validation failed (${response.status})`);\n }\n}\n\n// =============================================================================\n// Callback Server\n// =============================================================================\n\n/** Fixed port for OAuth callback — must match the redirect URI registered in WorkOS */\nexport const OAUTH_CALLBACK_PORT = 3829;\n\nexport function startCallbackServer(\n port: number,\n expectedState: string,\n timeoutMs: number = 120_000\n): Promise<{ code: string; port: number }> {\n return new Promise((resolve, reject) => {\n const server = http.createServer((req, res) => {\n const url = new URL(req.url || '/', `http://127.0.0.1:${port}`);\n\n if (url.pathname === '/callback') {\n const code = url.searchParams.get('code');\n const state = url.searchParams.get('state');\n const error = url.searchParams.get('error');\n const errorDescription = url.searchParams.get('error_description');\n\n if (error) {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(`<html><body><h2>Login failed</h2><p>${errorDescription || error}</p></body></html>`);\n server.close();\n reject(new Error(`OAuth callback error: ${errorDescription || error}`));\n return;\n }\n\n if (state !== expectedState) {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end('<html><body><h2>Login failed</h2><p>Invalid state parameter</p></body></html>');\n server.close();\n reject(new Error('OAuth state mismatch — possible CSRF attack'));\n return;\n }\n\n if (code) {\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end('<html><body><h2>Login successful!</h2><p>You can close this tab and return to your terminal.</p></body></html>');\n server.close();\n resolve({ code, port });\n } else {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end('<html><body><h2>Login failed</h2><p>No authorization code received</p></body></html>');\n server.close();\n reject(new Error('No authorization code received'));\n }\n } else {\n res.writeHead(404);\n res.end();\n }\n });\n\n const timeout = setTimeout(() => {\n server.close();\n reject(new Error('Timed out waiting for login. Run `wayai login` again.'));\n }, timeoutMs);\n\n server.on('close', () => clearTimeout(timeout));\n server.listen(port, '127.0.0.1');\n\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n reject(new Error(`Port ${port} is in use. Try again.`));\n } else {\n reject(err);\n }\n });\n });\n}\n\n// =============================================================================\n// Token Resolution (for API calls)\n// =============================================================================\n\nconst AUTHKIT_DOMAIN = 'https://sprightly-comic-51.authkit.app';\nconst AUTHKIT_CLIENT_ID = 'client_01KMZHB50KENM5SV90ZA80VXK4'; // WayAI CLI Connect app (public, PKCE)\n\nexport function getAuthKitDomain(): string {\n return process.env.WAYAI_AUTHKIT_DOMAIN || AUTHKIT_DOMAIN;\n}\n\nexport function getAuthKitClientId(): string {\n return process.env.WAYAI_AUTHKIT_CLIENT_ID || AUTHKIT_CLIENT_ID;\n}\n\n/**\n * Get a valid access token. Reads from the keyring (or env/file fallback) and\n * handles OAuth refresh transparently when nearing expiry.\n *\n * `config` is passed in for `api_url` access and to support the SESSION_EXPIRED\n * recovery path. Token data does NOT live in config anymore — it's resolved\n * from token-store.\n */\nexport async function getAccessToken(config: CliConfig): Promise<string> {\n // One-time migration from legacy plaintext config (versions < 0.4.0). Idempotent.\n await migrateLegacyTokens();\n\n const resolved = await getToken();\n if (!resolved) {\n throw new Error('No token found. Run `wayai login` to authenticate.');\n }\n\n // way_ token path — no refresh needed\n if (resolved.kind === 'way') {\n return resolved.token;\n }\n\n // OAuth JWT path — check expiry and refresh if needed\n const expiresAt = resolved.expires_at;\n if (!expiresAt) {\n return resolved.access_token;\n }\n\n if (new Date(expiresAt).getTime() > Date.now() + 60_000) {\n return resolved.access_token;\n }\n\n if (!resolved.refresh_token) {\n throw new Error('Access token expired and no refresh token available. Run `wayai login` again.');\n }\n\n // Token expired — refresh\n try {\n const result = await refreshAccessToken(\n getAuthKitDomain(),\n getAuthKitClientId(),\n resolved.refresh_token,\n );\n\n const newExpiresAt = expiresInToIso(result.expires_in);\n // setOAuthTokens persists token_expires_at to the metadata file — no need to\n // writeConfig again here (would double-write the same file).\n await setOAuthTokens(result.access_token, result.refresh_token ?? resolved.refresh_token, newExpiresAt);\n return result.access_token;\n } catch (err) {\n if (err instanceof Error && err.message === 'SESSION_EXPIRED') {\n await clearTokens();\n writeConfig({ api_url: config.api_url });\n throw new Error('Session expired. Please run `wayai login` again.');\n }\n throw err;\n }\n}\n\nexport async function requireAuth(): Promise<{ config: CliConfig; accessToken: string }> {\n const config = readConfig();\n if (!config) {\n console.error('Not logged in. Run `wayai login` first.');\n process.exit(1);\n }\n\n try {\n const accessToken = await getAccessToken(config);\n setSentryUser(accessToken);\n return { config, accessToken };\n } catch (err) {\n console.error(`Authentication failed: ${err instanceof Error ? err.message : String(err)}`);\n console.error('Run `wayai login` to re-authenticate.');\n process.exit(1);\n }\n}\n","/**\n * API client — authenticated requests to the WayAI backend\n */\n\nimport type {\n HubAsCodePayload,\n CiDiffResponse,\n CiLookupResponse,\n CiSyncResponse,\n CiOrganizationsResponse,\n CiCreateOrganizationResponse,\n CiHubListResponse,\n CiSyncMcpResponse,\n SyncSkillsResponse,\n OrgResourcesPayload,\n CiOrgResourcesPushResponse,\n} from './types.js';\nimport type {\n AnalyticsSqlBody,\n AnalyticsSqlResponse,\n AnalyticsSqlSchemaResponse,\n AnalyticsStructuredQueryResponse,\n AuthMeResponse,\n DataExplorerDebugDoType,\n DataExplorerDebugAnalyticsTable,\n DataExplorerDebugObservabilityResponse,\n DeleteUserConversationsBody,\n DeleteUserConversationsResponse,\n ObservabilityListResponse,\n ObservabilityResponse,\n EvalsSqlBody,\n EvalsSqlResponse,\n EvalsSqlSchemaResponse,\n StructuredQueryBody,\n AdminReportListResponse,\n AdminReportDetail,\n TransitionReportResponse,\n GroupReportsResponse,\n UngroupReportResponse,\n HoldReportResponse,\n TransitionReportBody,\n EditReportBody,\n EditReportResponse,\n GetReportResponse,\n ReporterListResponse,\n ReporterTransitionResponse,\n ListOrgCredentialsResponse,\n CreateOrgCredentialResponse,\n CreateOrgCredentialInput,\n UpdateOrgCredentialResponse,\n UpdateOrgCredentialInput,\n ListOrgTagsResponse,\n ToolCallResponse,\n AdminNoticeListResponse,\n AdminNoticeResponse,\n CreateNoticeBody,\n} from '@wayai/core/contracts';\nimport { addApiBreadcrumb } from './sentry.js';\n\nexport class ApiError extends Error {\n readonly status: number;\n readonly body: string;\n\n constructor(method: string, path: string, status: number, body: string) {\n super(`API request failed: ${method} ${path} (${status}): ${body}`);\n this.name = 'ApiError';\n this.status = status;\n this.body = body;\n }\n\n /** True when the status code is a 4xx client error (expected user-facing condition, not a bug). */\n get isExpected(): boolean {\n return this.status >= 400 && this.status < 500;\n }\n}\n\nexport interface ApiClientOptions {\n apiUrl: string;\n accessToken: string;\n /**\n * Optional re-auth hook. When a request comes back 401, the client invokes\n * this to obtain a fresh token, swaps it in, and retries the request exactly\n * once (mirroring the frontend `fetchWithAuth` single-refresh-then-retry).\n *\n * Long-running commands whose lifetime can exceed a short-lived OAuth JWT —\n * `run-eval`'s poll being the only one — pass `() => getAccessToken(config)`\n * so a token that rotates/expires mid-command self-heals instead of aborting\n * (gh #2605). Short-lived commands omit it and keep the throw-on-401 behavior.\n */\n onUnauthorized?: () => Promise<string>;\n}\n\nexport class ApiClient {\n private apiUrl: string;\n private accessToken: string;\n private onUnauthorized?: () => Promise<string>;\n\n constructor(options: ApiClientOptions) {\n this.apiUrl = options.apiUrl;\n this.accessToken = options.accessToken;\n this.onUnauthorized = options.onUnauthorized;\n }\n\n async pull(hubId: string, organizationId?: string): Promise<HubAsCodePayload> {\n const qs = organizationId ? `?${new URLSearchParams({ organization_id: organizationId })}` : '';\n return this.request<HubAsCodePayload>('GET', `/api/ci/pull/${hubId}${qs}`);\n }\n\n async diff(hubId: string, config: HubAsCodePayload, direction: 'push' | 'pull' = 'push', organizationId?: string): Promise<CiDiffResponse> {\n return this.request<CiDiffResponse>('POST', '/api/ci/diff', {\n hub_id: hubId,\n config,\n direction,\n ...(organizationId && { organization_id: organizationId }),\n });\n }\n\n async push(hubId: string, config: HubAsCodePayload, organizationId?: string): Promise<CiSyncResponse> {\n return this.request<CiSyncResponse>('POST', '/api/ci/push', {\n hub_id: hubId,\n config,\n ...(organizationId && { organization_id: organizationId }),\n });\n }\n\n async sync(hubId: string, branchName: string, config: HubAsCodePayload, commitSha?: string): Promise<CiSyncResponse> {\n return this.request<CiSyncResponse>('POST', '/api/ci/sync', {\n hub_id: hubId,\n branch_name: branchName,\n config,\n commit_sha: commitSha,\n });\n }\n\n /**\n * Re-discover an MCP connection's tool/resource catalog (refreshes stale\n * input schemas that `push` leaves untouched). `connection` is the display\n * name or the connection UUID.\n */\n async syncMcp(hubId: string, connection: string, organizationId?: string): Promise<CiSyncMcpResponse> {\n return this.request<CiSyncMcpResponse>('POST', '/api/ci/sync-mcp', {\n hub_id: hubId,\n connection,\n ...(organizationId && { organization_id: organizationId }),\n });\n }\n\n async lookup(path: string, opts?: { organizationId?: string }): Promise<CiLookupResponse> {\n const params = new URLSearchParams({ path });\n if (opts?.organizationId) params.set('organization_id', opts.organizationId);\n return this.request<CiLookupResponse>('GET', `/api/ci/lookup?${params.toString()}`);\n }\n\n async organizations(): Promise<CiOrganizationsResponse> {\n return this.request<CiOrganizationsResponse>('GET', '/api/ci/organizations');\n }\n\n /** Create a new organization (the caller becomes its owner). */\n async createOrganization(name: string, region?: string): Promise<CiCreateOrganizationResponse> {\n return this.request<CiCreateOrganizationResponse>('POST', '/api/ci/organizations', {\n organization_name: name,\n ...(region ? { primary_region: region } : {}),\n });\n }\n\n // ---- Org-as-code (org-scoped resources) ----\n\n async pullOrgResources(orgId: string): Promise<OrgResourcesPayload> {\n return this.request<OrgResourcesPayload>('GET', `/api/ci/org-resources/${orgId}`);\n }\n\n async diffOrgResources(\n orgId: string,\n config: OrgResourcesPayload,\n direction: 'push' | 'pull' = 'push',\n ): Promise<CiDiffResponse> {\n return this.request<CiDiffResponse>('POST', '/api/ci/org-resources/diff', {\n organization_id: orgId,\n config,\n direction,\n });\n }\n\n async pushOrgResources(orgId: string, config: OrgResourcesPayload): Promise<CiOrgResourcesPushResponse> {\n return this.request<CiOrgResourcesPushResponse>('POST', '/api/ci/org-resources/push', {\n organization_id: orgId,\n config,\n });\n }\n\n async me(): Promise<AuthMeResponse> {\n return this.request<AuthMeResponse>('GET', '/api/auth/me');\n }\n\n async syncSkills(hubId: string, connectionId?: string): Promise<SyncSkillsResponse> {\n return this.request<SyncSkillsResponse>('POST', '/api/setup/resources/sync-skills', {\n hub_id: hubId,\n ...(connectionId && { connection_id: connectionId }),\n });\n }\n\n async listHubs(organizationId: string): Promise<CiHubListResponse> {\n const params = new URLSearchParams({ organization_id: organizationId });\n return this.request<CiHubListResponse>('GET', `/api/ci/hubs?${params.toString()}`);\n }\n\n async sendMessage(hubId: string, message: string, opts?: { conversationId?: string }): Promise<{\n conversation_id: string;\n hub_type: string;\n user_message_id: string;\n agent_reply: { message_id: string; message_text: string } | null;\n status: string;\n status_reason?: string;\n }> {\n return this.request('POST', '/api/conversations/send-message', {\n hub_id: hubId,\n message,\n ...(opts?.conversationId && { conversation_id: opts.conversationId }),\n });\n }\n\n async deleteHistory(\n hubId: string,\n opts: { userId: string } & ({ mode: 'all' } | { mode: 'current'; conversationId: string }),\n ): Promise<DeleteUserConversationsResponse> {\n const body: DeleteUserConversationsBody = opts.mode === 'current'\n ? { hub_id: hubId, user_id: opts.userId, mode: 'current', conversation_id: opts.conversationId }\n : { hub_id: hubId, user_id: opts.userId, mode: 'all' };\n return this.request<DeleteUserConversationsResponse>('POST', '/api/conversations/delete-user-history', body);\n }\n\n async getConversations(hubId: string, opts?: { status?: string; limit?: number; offset?: number }): Promise<{\n conversations: Array<{\n conversation_id: string;\n conversation_status: string;\n current_responder_type: string | null;\n kanban_status: string | null;\n created_at: string;\n updated_at: string | null;\n user_name: string | null;\n user_email: string | null;\n }>;\n total: number;\n }> {\n const params = new URLSearchParams({ hub_id: hubId });\n if (opts?.status) params.set('status', opts.status);\n if (opts?.limit) params.set('limit', String(opts.limit));\n if (opts?.offset) params.set('offset', String(opts.offset));\n return this.request('GET', `/api/conversations?${params.toString()}`);\n }\n\n // ---------------------------------------------------------------------------\n // Evals\n // ---------------------------------------------------------------------------\n\n async getEvals(hubId: string, opts?: { enabled?: string }): Promise<{\n success: true;\n data: {\n evals: Array<{\n eval_id: string;\n eval_name: string;\n enabled: boolean;\n number_of_runs: number;\n responder_agent_id: string;\n scenario_set_id: string;\n hub_id: string;\n agent?: { agent_id: string; agent_name: string; agent_role: string } | null;\n }>;\n total_count: number;\n };\n }> {\n const params = new URLSearchParams({ hub_id: hubId });\n if (opts?.enabled) params.set('enabled', opts.enabled);\n return this.request('GET', `/api/evals?${params.toString()}`);\n }\n\n async getEvalSessions(hubId: string, opts?: { status?: string }): Promise<{\n success: true;\n data: {\n sessions: Array<{\n eval_session_id: string;\n session_name: string;\n session_status: string;\n hub_id: string;\n total_evals: number;\n total_runs: number;\n successful_runs: number;\n failed_runs: number;\n started_at?: string;\n completed_at?: string;\n created_at: string;\n }>;\n total_count: number;\n };\n }> {\n const params = new URLSearchParams({ hub_id: hubId });\n if (opts?.status) params.set('status', opts.status);\n return this.request('GET', `/api/evals/sessions?${params.toString()}`);\n }\n\n async createEvalSession(hubId: string, sessionName: string, scenarioSetId?: string): Promise<{\n success: true;\n data: {\n session: {\n eval_session_id: string;\n session_name: string;\n session_status: string;\n hub_id: string;\n };\n };\n message: string;\n }> {\n return this.request('POST', '/api/evals/sessions', {\n session: {\n hub_id: hubId,\n session_name: sessionName,\n // Binding the set at create time targets a specific set (multi-set hubs);\n // when omitted, the run endpoint resolves the hub's sole enabled set.\n ...(scenarioSetId ? { scenario_set_id: scenarioSetId } : {}),\n },\n });\n }\n\n async runEvalSession(hubId: string, sessionId: string): Promise<{\n success: true;\n data: { session: { eval_session_id: string; session_status: string } };\n message: string;\n }> {\n const params = new URLSearchParams({ hub_id: hubId });\n return this.request('POST', `/api/evals/sessions/${sessionId}/run?${params.toString()}`);\n }\n\n async getEvalSessionDetails(hubId: string, sessionId: string): Promise<{\n success: true;\n data: {\n session: {\n eval_session_id: string;\n session_name: string;\n session_status: string;\n started_at?: string;\n completed_at?: string;\n };\n results: Array<{\n eval_session_result_id: string;\n eval_id: string;\n total_runs: number;\n successful_runs: number;\n failed_runs: number;\n pending_runs: number;\n running_runs: number;\n success_rate: number;\n avg_execution_time_ms?: number;\n aggregated_scores?: Record<string, { avg: number; min: number; max: number }>;\n eval_status: string;\n eval?: { eval_id: string; eval_name: string; responder_agent_id: string } | null;\n }>;\n };\n }> {\n const params = new URLSearchParams({ hub_id: hubId });\n return this.request('GET', `/api/evals/sessions/${sessionId}?${params.toString()}`);\n }\n\n async getEvalSessionRuns(hubId: string, sessionId: string, opts?: { evalId?: string; limit?: number }): Promise<{\n success: true;\n data: {\n runs: Array<{\n eval_session_run_id: string;\n eval_id: string;\n run_number: number;\n eval_response: {\n role: string;\n content: string;\n tool_calls?: ToolCallResponse[];\n } | null;\n response_match: boolean | null;\n response_comment?: string;\n execution_time_ms?: number;\n run_status: string;\n scores?: Record<string, number>;\n eval?: { eval_id: string; eval_name: string; responder_agent_id: string } | null;\n }>;\n total_count: number;\n session_id: string;\n };\n }> {\n const params = new URLSearchParams({ hub_id: hubId });\n if (opts?.evalId) params.set('eval_id', opts.evalId);\n if (opts?.limit) params.set('limit', String(opts.limit));\n return this.request('GET', `/api/evals/sessions/${sessionId}/runs?${params.toString()}`);\n }\n\n async listScenarioSets(hubId: string): Promise<{\n success: true;\n data: {\n scenario_sets: Array<{\n scenario_set_id: string;\n set_name: string;\n description?: string | null;\n enabled: boolean;\n }>;\n total_count: number;\n };\n }> {\n const params = new URLSearchParams({ hub_id: hubId });\n return this.request('GET', `/api/evals/scenario-sets?${params.toString()}`);\n }\n\n async createScenarioSet(hubId: string, setName: string): Promise<{\n success: true;\n data: {\n scenario_set: {\n scenario_set_id: string;\n set_name: string;\n };\n };\n }> {\n return this.request('POST', '/api/evals/scenario-sets', {\n hub_id: hubId,\n set_name: setName,\n });\n }\n\n async runEvalsSql(body: EvalsSqlBody): Promise<EvalsSqlResponse> {\n return this.request<EvalsSqlResponse>('POST', '/api/evals/sql', body);\n }\n\n async getEvalsSqlSchema(hubId: string): Promise<EvalsSqlSchemaResponse> {\n const params = new URLSearchParams({ hub_id: hubId });\n return this.request<EvalsSqlSchemaResponse>('GET', `/api/evals/sql/schema?${params.toString()}`);\n }\n\n async createScenarioFromConversation(input: {\n hub_id: string;\n conversation_id: string;\n scenario_set_id: string;\n scenario_name: string;\n evaluator_instructions?: string;\n }): Promise<{\n success: true;\n data: {\n eval: {\n eval_id: string;\n eval_name: string;\n scenario_set_id: string;\n responder_agent_id: string;\n message_text: { role: string; content?: string | null; tool_calls?: unknown };\n message_expected_response: { role: string; content?: string | null; tool_calls?: unknown };\n message_history: Array<{ role: string; content?: string | null; tool_calls?: unknown }>;\n evaluator_instructions?: string;\n number_of_runs: number;\n enabled: boolean;\n };\n };\n message: string;\n }> {\n return this.request('POST', '/api/evals/scenarios/from-conversation', input);\n }\n\n // ---------------------------------------------------------------------------\n // Analytics\n // ---------------------------------------------------------------------------\n\n async getAnalyticsVariables(hubId: string): Promise<{\n success: true;\n data: {\n categories: Array<{\n category: string;\n label: string;\n variableCount: number;\n }>;\n variablesByCategory: Record<string, Array<{\n variable_id: string;\n variable_name: string;\n variable_description?: string;\n variable_label?: string;\n variable_type: 'numeric' | 'categorical' | 'text';\n variable_origin: string;\n variable_category: string;\n variable_enum: unknown[];\n pin: boolean;\n }>>;\n };\n }> {\n return this.request('GET', `/api/analytics/hubs/${hubId}/variables`);\n }\n\n async getAnalyticsData(body: {\n hub_id: string;\n selected_variables: string[];\n time_interval: { start: string; end: string };\n periodicity: string;\n trend_analysis: boolean;\n include_summary: boolean;\n filters?: Array<{ variable_id: string; filter_type: string; filter_value: string | number }>;\n }): Promise<{\n analytics: Array<{\n variable: string;\n variable_id: string;\n type: 'numeric' | 'categorical' | 'text';\n data?: Array<{ period: string; value: number | string | Record<string, number> }>;\n metrics?: { average: number; sum: number; minimum: number; maximum: number; count?: number; median?: number };\n distribution?: Record<string, number>;\n }>;\n summary?: {\n total_conversations: number;\n ai_only_rate: number;\n avg_response_time: number;\n assistant_response_time: number;\n support_response_time: number;\n user_response_time: number;\n };\n }> {\n return this.request('POST', '/api/analytics/data', body);\n }\n\n async runAnalyticsQuery(body: StructuredQueryBody): Promise<AnalyticsStructuredQueryResponse> {\n return this.request<AnalyticsStructuredQueryResponse>('POST', '/api/analytics/query', body);\n }\n\n async runAnalyticsSql(body: AnalyticsSqlBody): Promise<AnalyticsSqlResponse> {\n return this.request<AnalyticsSqlResponse>('POST', '/api/analytics/sql', body);\n }\n\n async getAnalyticsSqlSchema(hubId: string): Promise<AnalyticsSqlSchemaResponse> {\n const params = new URLSearchParams({ hub_id: hubId });\n return this.request<AnalyticsSqlSchemaResponse>('GET', `/api/analytics/sql/schema?${params.toString()}`);\n }\n\n async getAnalyticsConversations(body: {\n hub_id: string;\n time_interval?: { start: string; end: string };\n filters?: Array<{ variable_id: string; filter_type: string; filter_value: string | number }>;\n limit: number;\n offset: number;\n }): Promise<{\n success: true;\n conversations: Array<{\n conversation_id: string;\n created_at?: string;\n updated_at?: string;\n message_count?: number;\n participant_name?: string;\n participant_phone?: string;\n }>;\n total: number;\n offset: number;\n limit: number;\n // Set when ClickHouse was cold/transiently unavailable and the listing is a\n // provisional empty response rather than a real \"no conversations\" result.\n // The CLI surfaces this distinctly instead of rendering empty (gh #2452).\n cold?: boolean;\n }> {\n return this.request('POST', '/api/analytics/conversations', body);\n }\n\n async getConversation(\n hubId: string,\n conversationId: string,\n opts?: { limit?: number; offset?: number },\n ): Promise<{\n conversation: {\n conversation_id: string;\n conversation_status: string;\n current_responder_type: string | null;\n kanban_status: string | null;\n created_at: string;\n updated_at: string | null;\n user_name: string | null;\n user_email: string | null;\n };\n messages: Array<{\n message_id: string;\n message_text: string | null;\n sender_type: string;\n receiver_type: string | null;\n created_at: string;\n message_type?: string;\n channel_type?: string | null;\n keep_in_history?: boolean;\n agent_id?: string | null;\n sender_id?: string | null;\n receiver_id?: string | null;\n sender_description?: string;\n receiver_description?: string;\n metadata?: Record<string, unknown> | null;\n message_status?: string | null;\n }>;\n total_messages: number;\n }> {\n const params = new URLSearchParams({ hub_id: hubId });\n if (opts?.limit) params.set('limit', String(opts.limit));\n if (opts?.offset) params.set('offset', String(opts.offset));\n return this.request('GET', `/api/conversations/${conversationId}/detail?${params.toString()}`);\n }\n\n // ---------------------------------------------------------------------------\n // Setup: Organization Credentials, Hubs\n // ---------------------------------------------------------------------------\n\n async createOrgCredential(body: {\n organization_id: string;\n credential_display_name: string;\n authentication_type: 'api_key' | 'bearer' | 'basic_auth';\n credential_description?: string;\n api_key?: string;\n access_token?: string;\n username?: string;\n password?: string;\n tags?: string[];\n environment?: CreateOrgCredentialInput['environment'];\n }): Promise<CreateOrgCredentialResponse> {\n return this.request('POST', '/api/setup/organization-credentials', body);\n }\n\n async listOrgCredentials(organizationId: string): Promise<ListOrgCredentialsResponse> {\n const qs = new URLSearchParams({ organization_id: organizationId });\n return this.request('GET', `/api/setup/organization-credentials?${qs.toString()}`);\n }\n\n async updateOrgCredential(\n credentialId: string,\n organizationId: string,\n body: UpdateOrgCredentialInput,\n ): Promise<UpdateOrgCredentialResponse> {\n const qs = new URLSearchParams({ organization_id: organizationId });\n return this.request('PUT', `/api/setup/organization-credentials/${credentialId}?${qs.toString()}`, body);\n }\n\n async listOrgTags(organizationId: string): Promise<ListOrgTagsResponse> {\n const qs = new URLSearchParams({ organization_id: organizationId });\n return this.request('GET', `/api/setup/organization-tags?${qs.toString()}`);\n }\n\n async createHub(organizationId: string, hubName: string, hubType?: string, hubDescription?: string): Promise<{\n data: Array<{\n hub_id: string;\n hub_name: string;\n hub_environment: string;\n hub_type: string;\n [key: string]: unknown;\n }>;\n }> {\n return this.request('POST', '/api/setup/hubs', {\n organization_id: organizationId,\n hub_name: hubName,\n ...(hubType && { hub_type: hubType }),\n ...(hubDescription && { hub_description: hubDescription }),\n });\n }\n\n // ---------------------------------------------------------------------------\n // Reports (platform_report triage queue)\n // ---------------------------------------------------------------------------\n\n async submitReport(params: {\n title: string;\n description: string;\n source?: string;\n classification?: string;\n dedup_key?: string;\n organization_id?: string;\n hub_id?: string;\n conversation_id?: string;\n agent_id?: string;\n agent_name?: string;\n error_message?: string;\n steps_to_reproduce?: string;\n additional_context?: string;\n client_version?: string;\n }): Promise<{ report_id: string; status: string; created: boolean }> {\n return this.request('POST', '/api/reports', params);\n }\n\n /** Reporter content edit of an own `cli` report (PATCH /api/reports/:id). */\n async editReport(reportId: string, patch: EditReportBody): Promise<EditReportResponse> {\n return this.request('PATCH', `/api/reports/${encodeURIComponent(reportId)}`, patch);\n }\n\n /** Reporter read-back — own reports, newest first (GET /api/reports[?status=]). */\n async listMyReports(status?: string): Promise<ReporterListResponse> {\n const qs = status ? `?status=${encodeURIComponent(status)}` : '';\n return this.request('GET', `/api/reports${qs}`);\n }\n\n /** Reporter read-back — one own report + its message thread (GET /api/reports/:id). */\n async getMyReport(reportId: string): Promise<GetReportResponse> {\n return this.request('GET', `/api/reports/${encodeURIComponent(reportId)}`);\n }\n\n /** Reporter accepts a shipped fix → addressed (POST /api/reports/:id/accept). */\n async acceptReport(reportId: string): Promise<ReporterTransitionResponse> {\n return this.request('POST', `/api/reports/${encodeURIComponent(reportId)}/accept`);\n }\n\n /** Reporter contests a fix or dismissal → contested (POST /api/reports/:id/contest). */\n async contestReport(reportId: string, reason: string): Promise<ReporterTransitionResponse> {\n return this.request('POST', `/api/reports/${encodeURIComponent(reportId)}/contest`, { reason });\n }\n\n async listAdminReports(params: {\n status?: string;\n source?: string;\n limit?: number;\n offset?: number;\n since?: string;\n } = {}): Promise<AdminReportListResponse> {\n const qs = new URLSearchParams();\n if (params.status) qs.set('status', params.status);\n if (params.source) qs.set('source', params.source);\n if (params.limit != null) qs.set('limit', String(params.limit));\n if (params.offset != null) qs.set('offset', String(params.offset));\n if (params.since) qs.set('since', params.since);\n const suffix = qs.toString();\n return this.request('GET', `/api/admin/reports${suffix ? '?' + suffix : ''}`);\n }\n\n async getAdminReport(reportId: string): Promise<{ data: AdminReportDetail }> {\n return this.request('GET', `/api/admin/reports/${encodeURIComponent(reportId)}`);\n }\n\n async transitionAdminReport(\n reportId: string,\n body: TransitionReportBody,\n ): Promise<TransitionReportResponse> {\n return this.request('PATCH', `/api/admin/reports/${encodeURIComponent(reportId)}/transition`, body);\n }\n\n async groupAdminReports(\n canonicalId: string,\n memberIds: string[],\n ): Promise<GroupReportsResponse> {\n return this.request('POST', `/api/admin/reports/${encodeURIComponent(canonicalId)}/group`, {\n member_ids: memberIds,\n });\n }\n\n async ungroupAdminReport(memberId: string): Promise<UngroupReportResponse> {\n return this.request('POST', `/api/admin/reports/${encodeURIComponent(memberId)}/ungroup`);\n }\n\n /** Hold a pending report one triage cycle (POST /api/admin/reports/:id/hold). Silent; internal note. */\n async holdAdminReport(reportId: string, reason: string): Promise<HoldReportResponse> {\n return this.request('POST', `/api/admin/reports/${encodeURIComponent(reportId)}/hold`, { reason });\n }\n\n /** Admin content edit of any report (PATCH /api/admin/reports/:id). */\n async updateAdminReport(reportId: string, patch: EditReportBody): Promise<EditReportResponse> {\n return this.request('PATCH', `/api/admin/reports/${encodeURIComponent(reportId)}`, patch);\n }\n\n // ---------------------------------------------------------------------------\n // Platform notices (feed 2) — operator-authored broadcasts (platform-admin only)\n // ---------------------------------------------------------------------------\n\n async listAdminNotices(params: {\n status?: string;\n limit?: number;\n offset?: number;\n } = {}): Promise<AdminNoticeListResponse> {\n const qs = new URLSearchParams();\n if (params.status) qs.set('status', params.status);\n if (params.limit != null) qs.set('limit', String(params.limit));\n if (params.offset != null) qs.set('offset', String(params.offset));\n const suffix = qs.toString();\n return this.request('GET', `/api/admin/notices${suffix ? '?' + suffix : ''}`);\n }\n\n async createAdminNotice(body: CreateNoticeBody): Promise<AdminNoticeResponse> {\n return this.request('POST', '/api/admin/notices', body);\n }\n\n // NOTE: no updateAdminNotice here — the PATCH /api/admin/notices/:id route exists\n // (CRUD-complete, tested) for the future /admin/notices authoring UI, which uses the\n // frontend client. The CLI exposes create/list/resolve only; add an update wrapper if\n // a `wayai admin notice update` subcommand is ever wired.\n async resolveAdminNotice(noticeId: string): Promise<AdminNoticeResponse> {\n return this.request('POST', `/api/admin/notices/${encodeURIComponent(noticeId)}/resolve`);\n }\n\n async getPendingSchedules(hubId: string, conversationId: string): Promise<{\n entries: Array<{\n conversation_schedule_id: string;\n schedule_type: string;\n run_at: string;\n message_text: string;\n followup_order: number | null;\n followup_source: string | null;\n end_conversation: boolean;\n }>;\n total: number;\n }> {\n const params = new URLSearchParams({ hub_id: hubId, conversation_id: conversationId });\n return this.request('GET', `/api/conversations/schedules?${params.toString()}`);\n }\n\n // ---------------------------------------------------------------------------\n // Admin debug reads (platform-admin only — 403 for everyone else)\n // ---------------------------------------------------------------------------\n\n async debugListTables(\n doType: DataExplorerDebugDoType,\n doId: string,\n ): Promise<{\n data: { do_type: string; do_id: string; tables: string[] };\n }> {\n return this.request(\n 'GET',\n `/api/admin/data-explorer/debug/do/${doType}/${encodeURIComponent(doId)}/tables`,\n );\n }\n\n async debugReadTable(\n doType: DataExplorerDebugDoType,\n doId: string,\n table: string,\n opts?: { limit?: number; id?: string },\n ): Promise<{\n data: {\n do_type: string;\n do_id: string;\n table: string;\n rows: Array<Record<string, unknown>>;\n redacted_columns: string[];\n truncated: boolean;\n limit: number;\n };\n }> {\n const params = new URLSearchParams();\n if (opts?.limit !== undefined) params.set('limit', String(opts.limit));\n if (opts?.id) params.set('id', opts.id);\n const qs = params.toString() ? `?${params.toString()}` : '';\n return this.request(\n 'GET',\n `/api/admin/data-explorer/debug/do/${doType}/${encodeURIComponent(doId)}/tables/${encodeURIComponent(table)}/rows${qs}`,\n );\n }\n\n async debugListAnalyticsTables(): Promise<{\n data: { tables: DataExplorerDebugAnalyticsTable[] };\n }> {\n return this.request('GET', '/api/admin/data-explorer/debug/analytics/tables');\n }\n\n async debugReadAnalyticsTable(\n table: DataExplorerDebugAnalyticsTable,\n opts?: { conversationId?: string; hubId?: string; messageId?: string; limit?: number },\n ): Promise<{\n data: {\n table: DataExplorerDebugAnalyticsTable;\n rows: Array<Record<string, unknown>>;\n redacted_columns: string[];\n truncated: boolean;\n limit: number;\n };\n }> {\n const params = new URLSearchParams();\n if (opts?.conversationId) params.set('conversation_id', opts.conversationId);\n if (opts?.hubId) params.set('hub_id', opts.hubId);\n if (opts?.messageId) params.set('message_id', opts.messageId);\n if (opts?.limit !== undefined) params.set('limit', String(opts.limit));\n const qs = params.toString() ? `?${params.toString()}` : '';\n return this.request(\n 'GET',\n `/api/admin/data-explorer/debug/analytics/${encodeURIComponent(table)}/rows${qs}`,\n );\n }\n\n async debugReadArchive(\n hubId: string,\n conversationId: string,\n opts?: { messageId?: string },\n ): Promise<{\n data: {\n hub_id: string;\n conversation_id: string;\n archive: Record<string, unknown>;\n message_filtered: boolean;\n };\n }> {\n const params = new URLSearchParams();\n if (opts?.messageId) params.set('message_id', opts.messageId);\n const qs = params.toString() ? `?${params.toString()}` : '';\n return this.request(\n 'GET',\n `/api/admin/data-explorer/debug/archive/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}${qs}`,\n );\n }\n\n /** List per-message observability metadata summaries for a conversation (hub-scoped auth). */\n async listConversationObservability(conversationId: string): Promise<ObservabilityListResponse> {\n return this.request(\n 'GET',\n `/api/conversations/${encodeURIComponent(conversationId)}/observability`,\n );\n }\n\n /** Fetch the full observability record for a single message (hub-scoped auth). */\n async getMessageObservability(conversationId: string, messageId: string): Promise<ObservabilityResponse> {\n return this.request(\n 'GET',\n `/api/conversations/${encodeURIComponent(conversationId)}/messages/${encodeURIComponent(messageId)}/observability`,\n );\n }\n\n async listArchivedConversationObservability(\n hubId: string,\n conversationId: string,\n ): Promise<ObservabilityListResponse> {\n return this.request(\n 'GET',\n `/api/archive/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}/observability`,\n );\n }\n\n async getArchivedMessageObservability(\n hubId: string,\n conversationId: string,\n messageId: string,\n ): Promise<ObservabilityResponse> {\n return this.request(\n 'GET',\n `/api/archive/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}/messages/${encodeURIComponent(messageId)}/observability`,\n );\n }\n\n /** Platform-admin debug read of LLM observability records (list or single via messageId). */\n async debugReadObservability(\n hubId: string,\n conversationId: string,\n opts?: { messageId?: string },\n ): Promise<DataExplorerDebugObservabilityResponse> {\n const params = new URLSearchParams();\n if (opts?.messageId) params.set('message_id', opts.messageId);\n const qs = params.toString() ? `?${params.toString()}` : '';\n return this.request(\n 'GET',\n `/api/admin/data-explorer/debug/observability/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}${qs}`,\n );\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n addApiBreadcrumb(method, path);\n\n const url = `${this.apiUrl}${path}`;\n let response = await this.send(url, method, body);\n\n // Single-refresh-then-retry on 401: a token that rotated/expired mid-command\n // (e.g. run-eval's long poll outliving a short-lived OAuth JWT) self-heals\n // rather than tearing down the command (gh #2605). One retry only — no loop.\n if (response.status === 401 && this.onUnauthorized) {\n let refreshed: string | undefined;\n try {\n refreshed = await this.onUnauthorized();\n } catch {\n // Refresh failed (e.g. SESSION_EXPIRED) — fall through and surface the\n // original 401 to the caller below.\n }\n if (refreshed) {\n this.accessToken = refreshed;\n response = await this.send(url, method, body);\n }\n }\n\n if (!response.ok) {\n const errorBody = await response.text();\n throw new ApiError(method, path, response.status, errorBody);\n }\n\n return response.json() as Promise<T>;\n }\n\n /** Issue a single authenticated request with the client's current token. */\n private send(url: string, method: string, body?: unknown): Promise<Response> {\n return fetch(url, {\n method,\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n 'Content-Type': 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n}\n","/**\n * Report-action nudge — a once-per-report reminder that the caller has reports awaiting their\n * verification. Surfaced only on `wayai login` and `wayai status` (both already authenticated and\n * infrequent), so there is no per-command polling and thus no rate-limit pressure.\n *\n * Actionable states for a reporter:\n * - `shipped` → accept or contest the fix\n * - `dismissed` (not final, < cap) → contest the dismissal\n * (`addressed` is terminal — nothing to do.)\n *\n * Dedup: each `<report_id>:<status>` is shown once, tracked in ~/.wayai/config.json. The shipped\n * EMAIL is the primary, reliable channel; this is a best-effort secondary reminder for CLI users.\n */\n\nimport { ApiClient } from './api-client.js';\nimport { readConfig, writeConfig } from './config.js';\n\nconst MAX_TRACKED = 200;\n\n/**\n * Print a one-time nudge for reports awaiting the caller's accept/contest, if any are new.\n * Best-effort and interactive-only: never throws, never prints in non-TTY/CI/JSON contexts\n * (the caller passes a TTY-resolved `accessToken`; this also self-guards on `process.stdout.isTTY`).\n */\nexport async function nudgeReportActions(apiUrl: string, accessToken: string): Promise<void> {\n if (!process.stdout.isTTY || process.env.CI) return;\n try {\n const client = new ApiClient({ apiUrl, accessToken });\n const [shipped, dismissed] = await Promise.all([\n client.listMyReports('shipped'),\n client.listMyReports('dismissed'),\n ]);\n\n const actionable = [\n // Shipped re-fires per shipment: a contested fix that's re-shipped is a NEW actionable event\n // (the backend clears notified_at_shipped on `contested`, so the email re-fires too). Key on\n // `contest_count` — it increments once per re-ship cycle (shipped → contested → re-ship) — so\n // the CLI nudge tracks the email channel rather than going silent after the first shipment.\n ...shipped.data.map((r) => ({\n id: r.report_id,\n status: r.status,\n key: `${r.report_id}:shipped:${r.contest_count}`,\n verb: 'accept or contest',\n })),\n // A `final` dismissal can't be contested — don't nudge for it. (`dismissal_final` is the\n // reporter-facing contestability gate; triage sets it precisely when further contest is\n // refused, so we don't need the server-side contest cap here.) Keyed once-ever\n // (no shipment discriminator) to match the dismissed email, whose slot is never re-armed.\n ...dismissed.data\n .filter((r) => !r.dismissal_final)\n .map((r) => ({ id: r.report_id, status: r.status, key: `${r.report_id}:dismissed`, verb: 'contest' })),\n ];\n if (actionable.length === 0) return;\n\n const config = readConfig();\n if (!config) return;\n const seen = new Set(config.nudged_report_ids ?? []);\n const fresh = actionable.filter((a) => !seen.has(a.key));\n if (fresh.length === 0) return;\n\n const n = fresh.length;\n console.error(`\\n📬 ${n} report${n > 1 ? 's' : ''} awaiting your review:`);\n for (const a of fresh) {\n console.error(` • ${a.id} (${a.status}) — ${a.verb}`);\n }\n console.error(' → `wayai report list --status shipped`, then `wayai report accept <id>` or `wayai report contest <id> --reason \"...\"`');\n\n const updated = [...seen, ...fresh.map((a) => a.key)];\n writeConfig({ ...config, nudged_report_ids: updated.slice(-MAX_TRACKED) });\n } catch {\n /* best-effort: a nudge must never break login/status */\n }\n}\n","/**\n * wayai login — OAuth 2.1 + PKCE browser flow (default) or --token fallback\n *\n * Browser login: Opens AuthKit authorize → PKCE flow → JWT + refresh token\n * Token login: User pastes a way_ scoped token directly\n */\n\nimport * as readline from 'node:readline';\nimport {\n generateState,\n generateCodeVerifier,\n generateCodeChallenge,\n startCallbackServer,\n exchangeCodeForTokens,\n expiresInToIso,\n validateToken,\n getAuthKitDomain,\n getAuthKitClientId,\n OAUTH_CALLBACK_PORT,\n} from '../lib/auth.js';\nimport { writeConfig } from '../lib/config.js';\nimport { setOAuthTokens, setWayToken, identifyTokenType } from '../lib/token-store.js';\nimport { nudgeReportActions } from '../lib/report-inbox.js';\n\nfunction prompt(question: string, defaultValue?: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const display = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;\n return new Promise((resolve) => {\n rl.question(display, (answer) => {\n rl.close();\n resolve(answer.trim() || defaultValue || '');\n });\n });\n}\n\nconst DEFAULT_API_URL = 'https://api.wayai.pro';\n\nexport function parseApiUrl(args: string[]): string {\n const idx = args.indexOf('--api-url');\n if (idx !== -1 && args[idx + 1]) {\n return args[idx + 1];\n }\n return DEFAULT_API_URL;\n}\n\nexport async function loginCommand(args: string[]): Promise<void> {\n const useToken = args.includes('--token');\n const apiUrl = parseApiUrl(args);\n\n if (useToken) {\n await loginWithToken(apiUrl);\n } else {\n await loginWithBrowser(apiUrl);\n }\n}\n\nasync function loginWithBrowser(apiUrl: string): Promise<void> {\n console.log('\\nConnecting to WayAI...');\n\n const authkitDomain = getAuthKitDomain();\n const clientId = getAuthKitClientId();\n\n // Generate PKCE parameters\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = await generateCodeChallenge(codeVerifier);\n const state = generateState();\n\n // Fixed port so the redirect URI matches what's registered in WorkOS\n const port = OAUTH_CALLBACK_PORT;\n const redirectUri = `http://127.0.0.1:${port}/callback`;\n\n // Build AuthKit authorization URL with PKCE\n const authorizeUrl = new URL(`${authkitDomain}/oauth2/authorize`);\n authorizeUrl.searchParams.set('client_id', clientId);\n authorizeUrl.searchParams.set('redirect_uri', redirectUri);\n authorizeUrl.searchParams.set('response_type', 'code');\n authorizeUrl.searchParams.set('code_challenge', codeChallenge);\n authorizeUrl.searchParams.set('code_challenge_method', 'S256');\n authorizeUrl.searchParams.set('state', state);\n // offline_access is required for AuthKit to issue a refresh_token alongside the JWT;\n // without it, the CLI would re-prompt login every time the access token expires (~1h).\n authorizeUrl.searchParams.set('scope', 'openid profile email offline_access');\n\n try {\n // Start callback server before opening browser\n const callbackPromise = startCallbackServer(port, state);\n\n // Try to open browser\n const openedBrowser = await tryOpenBrowser(authorizeUrl.toString());\n if (!openedBrowser) {\n console.log(`\\nOpen this URL in your browser to log in:\\n\\n ${authorizeUrl.toString()}\\n`);\n } else {\n console.log('Opening browser for login...');\n }\n\n const { code } = await callbackPromise;\n\n console.log('Exchanging authorization code...');\n const tokens = await exchangeCodeForTokens(\n authkitDomain,\n clientId,\n code,\n codeVerifier,\n redirectUri,\n );\n\n // Match the defensive pattern in getAccessToken's refresh path: only persist\n // refresh_token when AuthKit returned one (it's gated on the `offline_access`\n // scope, so a missing value would mean scope config regressed).\n const expiresAt = expiresInToIso(tokens.expires_in);\n await setOAuthTokens(tokens.access_token, tokens.refresh_token, expiresAt);\n writeConfig({ api_url: apiUrl, token_expires_at: expiresAt });\n\n console.log('\\nLogin successful!');\n console.log('Token stored in OS keyring; metadata at ~/.wayai/config.json');\n\n // Best-effort: remind the reporter of any reports awaiting their accept/contest.\n await nudgeReportActions(apiUrl, tokens.access_token);\n } catch (err) {\n console.error(`\\nLogin failed: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n}\n\nasync function loginWithToken(apiUrl: string): Promise<void> {\n const token = await prompt('API Token (way_...)');\n\n if (!token) {\n console.error('Token is required.');\n process.exit(1);\n }\n\n if (identifyTokenType(token) !== 'way_token') {\n console.error('Invalid token format. Tokens start with \"way_\".');\n process.exit(1);\n }\n\n console.log('\\nValidating token...');\n\n try {\n await validateToken(apiUrl, token);\n } catch (err) {\n console.error(`Token validation failed: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n\n await setWayToken(token);\n writeConfig({ api_url: apiUrl });\n\n console.log('\\nLogin successful! Token stored in OS keyring; metadata at ~/.wayai/config.json');\n\n // Best-effort: remind the reporter of any reports awaiting their accept/contest.\n await nudgeReportActions(apiUrl, token);\n}\n\nasync function tryOpenBrowser(url: string): Promise<boolean> {\n if (process.env.SSH_CONNECTION || process.env.SSH_TTY) {\n return false;\n }\n\n try {\n const { execFile } = await import('node:child_process');\n const platform = process.platform;\n\n let cmd: string;\n let args: string[];\n if (platform === 'darwin') {\n cmd = 'open';\n args = [url];\n } else if (platform === 'win32') {\n cmd = 'cmd';\n args = ['/c', 'start', '', url];\n } else {\n cmd = 'xdg-open';\n args = [url];\n }\n\n return new Promise((resolve) => {\n execFile(cmd, args, (err) => resolve(!err));\n });\n } catch {\n return false;\n }\n}\n","import { clearTokens, getToken } from '../lib/token-store.js';\n\nexport async function logoutCommand(): Promise<void> {\n const token = await getToken();\n\n if (!token) {\n console.log('Not logged in.');\n return;\n }\n\n // WAYAI_TOKEN env override survives clearTokens — surface that so the user\n // knows the current shell is still authenticated.\n const envOverrideActive = !!process.env.WAYAI_TOKEN;\n\n await clearTokens();\n\n if (envOverrideActive) {\n console.log('Tokens cleared from keyring and file. Note: WAYAI_TOKEN env var is still set in this shell — unset it to fully log out.');\n } else {\n console.log('Logged out. Tokens cleared.');\n }\n}\n","// Tripwire only: agents/users can override via `wayai unlock`.\n\nimport { execFileSync } from 'node:child_process';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { UUID_RE } from './utils.js';\n\nconst LOCK_FILENAME = 'wayai-lock';\n\n// Cache keyed by cwd so tests that chdir between checkouts re-resolve.\nlet _lockPathCache: { cwd: string; lockPath: string | null } | undefined;\n\nexport function getLockPath(): string | null {\n const cwd = process.cwd();\n if (_lockPathCache && _lockPathCache.cwd === cwd) return _lockPathCache.lockPath;\n\n let gitDir: string;\n try {\n gitDir = execFileSync('git', ['rev-parse', '--git-dir'], {\n cwd,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n } catch {\n _lockPathCache = { cwd, lockPath: null };\n return null;\n }\n const lockPath = gitDir ? path.resolve(cwd, gitDir, LOCK_FILENAME) : null;\n _lockPathCache = { cwd, lockPath };\n return lockPath;\n}\n\n// Surfaces non-ENOENT errors (EACCES) so unreadable locks don't masquerade as unlocked.\nexport function readLock(): string | null {\n const lockPath = getLockPath();\n if (!lockPath) return null;\n let raw: string;\n try {\n raw = fs.readFileSync(lockPath, 'utf-8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw err;\n }\n const trimmed = raw.trim();\n return UUID_RE.test(trimmed) ? trimmed : null;\n}\n\nexport function writeLock(hubId: string): void {\n if (!UUID_RE.test(hubId)) {\n throw new Error(`Invalid hub_id (must be a UUID): ${hubId}`);\n }\n const lockPath = getLockPath();\n if (!lockPath) {\n throw new Error('Not inside a git repository — cannot write hub lock.');\n }\n fs.writeFileSync(lockPath, `${hubId}\\n`, 'utf-8');\n}\n\n// Returns true if a lock existed and was removed, false if absent. Surfaces non-ENOENT errors.\nexport function clearLock(): boolean {\n const lockPath = getLockPath();\n if (!lockPath) return false;\n try {\n fs.unlinkSync(lockPath);\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return false;\n throw err;\n }\n}\n\nexport function assertHubMatchesLock(resolvedHubId: string, hubLabel?: string): void {\n const locked = readLock();\n if (!locked) return;\n if (locked === resolvedHubId) return;\n\n const target = hubLabel ? `${hubLabel} (${resolvedHubId})` : resolvedHubId;\n console.error(\n [\n `This worktree is locked to hub ${locked}, but the command resolved to ${target}.`,\n '',\n 'This usually means a prompt was routed to the wrong worktree.',\n 'Confirm with the user before unlocking. To override:',\n ' wayai unlock # clear the lock for this worktree',\n ` wayai use ${resolvedHubId} # rebind this worktree to the new hub`,\n ].join('\\n'),\n );\n process.exit(1);\n}\n\n// Best-effort: errors don't fail the parent operation (which already succeeded).\nexport function autoLockIfUnlocked(hubId: string): boolean {\n try {\n if (readLock()) return false;\n writeLock(hubId);\n console.log(`Worktree locked to hub ${hubId} (run \\`wayai unlock\\` to clear).`);\n return true;\n } catch (err) {\n console.warn(` Warning: could not auto-lock worktree (${err instanceof Error ? err.message : String(err)})`);\n return false;\n }\n}\n\n// Fail-secure: readLock errors propagate (matches assertHubMatchesLock).\nexport function assertNoLockBlocksHubCreation(newHubName: string): void {\n const locked = readLock();\n if (!locked) return;\n\n console.error(\n [\n `This worktree is locked to hub ${locked}, but you're about to create a new hub \"${newHubName}\" here.`,\n '',\n 'This usually means a prompt was routed to the wrong worktree.',\n 'Confirm with the user before unlocking. To override:',\n ' wayai unlock # clear the lock for this worktree',\n ].join('\\n'),\n );\n process.exit(1);\n}\n","/**\n * wayai status — show current auth/config status and repo scope\n *\n * Usage:\n * wayai status # human-readable output\n * wayai status --json # structured output for agents/scripts\n *\n * The --json shape is the canonical state snapshot consumed by the WayAI skill\n * during agentic onboarding. Fields are nullable so the agent can branch\n * cleanly from any starting state (no config / no org / no workspace / etc.).\n */\n\nimport * as path from 'node:path';\nimport { readConfig } from '../lib/config.js';\nimport { getAccessToken } from '../lib/auth.js';\nimport { readRepoConfig, type RepoConfig } from '../lib/repo-config.js';\nimport { detectWorkspace, findGitRoot, scanWorkspaceHubs } from '../lib/workspace.js';\nimport { readLock } from '../lib/hub-lock.js';\nimport { ApiClient, ApiError } from '../lib/api-client.js';\nimport { CLI_CACHE_FILE, SKILL_CACHE_FILE, readCachedLatest } from '../lib/version-cache.js';\nimport {\n findInstalledSkills,\n lowestInstalledVersion,\n} from '../lib/skill-version.js';\nimport { isNewerVersion } from '../lib/utils.js';\nimport { nudgeReportActions } from '../lib/report-inbox.js';\n\nexport function parseArgs(args: string[]): { json: boolean } {\n return { json: args.includes('--json') };\n}\n\ninterface StatusSnapshot {\n logged_in: boolean;\n token_valid: boolean | null;\n api_url: string | null;\n repo_scope: { organization_id: string; organization_name: string | null } | null;\n cli: { version: string; latest: string | null };\n skill: {\n installed: boolean;\n version: string | null;\n latest: string | null;\n paths: string[];\n };\n auth: { logged_in: boolean; user_email: string | null };\n orgs: Array<{ id: string; name: string }>;\n active_org: { id: string; name: string } | null;\n workspace: { scoped: boolean; path: string | null; hub_count: number };\n worktree_lock: { hub_id: string | null };\n}\n\nfunction buildSkillState(): StatusSnapshot['skill'] {\n const projectRoot = findGitRoot() ?? process.cwd();\n const installs = findInstalledSkills(projectRoot);\n if (installs.length === 0) {\n return { installed: false, version: null, latest: null, paths: [] };\n }\n const version = lowestInstalledVersion(installs);\n const cached = readCachedLatest(SKILL_CACHE_FILE);\n // Field semantics: \"newer available, or null\". The cache can lag the\n // installed version (24h TTL; `npx skills add ...` doesn't invalidate it),\n // so suppress the field unless it actually advertises an upgrade.\n const latest = cached && version && isNewerVersion(cached, version) ? cached : null;\n return {\n installed: true,\n version,\n latest,\n paths: installs.map((i) => i.path),\n };\n}\n\nfunction buildWorkspaceState(repoConfig: RepoConfig | null): { scoped: boolean; path: string | null; hub_count: number } {\n if (!repoConfig) return { scoped: false, path: null, hub_count: 0 };\n\n const ws = detectWorkspace();\n const gitRoot = ws?.gitRoot ?? findGitRoot();\n const hubCount = ws ? scanWorkspaceHubs(ws.workspaceDir).length : 0;\n const yamlPath = gitRoot ? path.join(gitRoot, '.wayai.yaml') : null;\n return { scoped: true, path: yamlPath, hub_count: hubCount };\n}\n\nexport async function statusCommand(\n args: string[],\n pkg: { version: string }\n): Promise<void> {\n const { json } = parseArgs(args);\n const config = readConfig();\n const repoConfig = readRepoConfig();\n const workspace = buildWorkspaceState(repoConfig);\n // Same \"newer available, or null\" gate as buildSkillState.\n const cachedCliLatest = readCachedLatest(CLI_CACHE_FILE);\n const cliLatest = cachedCliLatest && isNewerVersion(cachedCliLatest, pkg.version)\n ? cachedCliLatest\n : null;\n const skill = buildSkillState();\n // Status is a diagnostic command — never crash on a lockfile read error.\n let lockedHubId: string | null = null;\n try {\n lockedHubId = readLock();\n } catch {\n lockedHubId = null;\n }\n\n // Cold-start path: no config at all.\n if (!config) {\n const snapshot: StatusSnapshot = {\n logged_in: false,\n token_valid: null,\n api_url: null,\n repo_scope: null,\n cli: { version: pkg.version, latest: cliLatest },\n skill,\n auth: { logged_in: false, user_email: null },\n orgs: [],\n active_org: null,\n workspace,\n worktree_lock: { hub_id: lockedHubId },\n };\n\n if (json) {\n console.log(JSON.stringify(snapshot, null, 2));\n } else {\n console.log('Not logged in. Run `wayai login`.');\n }\n return;\n }\n\n // Logged-in path: validate token against the backend, then enrich with data.\n // token_valid reflects backend acceptance (not just storage load) so users\n // can't be fooled into thinking auth works when API calls 401.\n let accessToken: string | null = null;\n let tokenLoaded = false;\n try {\n accessToken = await getAccessToken(config);\n tokenLoaded = true;\n } catch {\n tokenLoaded = false;\n }\n\n let userEmail: string | null = null;\n let orgs: Array<{ id: string; name: string }> = [];\n // An empty-string accessToken bypasses the API-call branch below, so flag\n // it as definitively-invalid up front rather than leaving it as the\n // \"validity unknown\" sentinel.\n let tokenValid: boolean | null = tokenLoaded && accessToken ? null : false;\n\n if (tokenLoaded && accessToken) {\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n const [meResult, orgsResult] = await Promise.allSettled([\n client.me(),\n client.organizations(),\n ]);\n if (meResult.status === 'fulfilled') {\n userEmail = meResult.value.email || null;\n tokenValid = true;\n } else if (meResult.reason instanceof ApiError && meResult.reason.isExpected) {\n // Any 4xx is the backend deciding \"this token isn't acceptable\" — 401\n // (invalid/expired/stale), 403 (scope revoked, deletion-pending),\n // 404 (user gone). Treat all as definitive rejection.\n tokenValid = false;\n }\n // Other failures (network unreachable, 5xx) leave tokenValid as null —\n // \"couldn't determine\" is more truthful than \"valid\" or \"invalid\".\n if (orgsResult.status === 'fulfilled') {\n orgs = orgsResult.value.organizations.map((o) => ({ id: o.id, name: o.name }));\n }\n }\n\n const activeOrg = repoConfig\n ? {\n id: repoConfig.organization_id,\n name:\n orgs.find((o) => o.id === repoConfig.organization_id)?.name\n ?? repoConfig.organization_name\n ?? repoConfig.organization_id,\n }\n : null;\n\n const snapshot: StatusSnapshot = {\n logged_in: true,\n token_valid: tokenValid,\n api_url: config.api_url,\n repo_scope: repoConfig\n ? {\n organization_id: repoConfig.organization_id,\n organization_name: repoConfig.organization_name ?? null,\n }\n : null,\n cli: { version: pkg.version, latest: cliLatest },\n skill,\n auth: { logged_in: true, user_email: userEmail },\n orgs,\n active_org: activeOrg,\n workspace,\n worktree_lock: { hub_id: lockedHubId },\n };\n\n if (json) {\n console.log(JSON.stringify(snapshot, null, 2));\n return;\n }\n\n // Human-readable output.\n const tokenStatus =\n tokenValid === true\n ? 'token valid'\n : tokenValid === false\n ? 'token rejected — run `wayai login` to re-authenticate'\n : 'token validity unknown — backend unreachable';\n console.log(`Logged in${userEmail ? ` as ${userEmail}` : ''} — ${tokenStatus}`);\n\n if (config.api_url !== 'https://api.wayai.pro') {\n console.log(`API: ${config.api_url}`);\n }\n\n if (cliLatest) {\n console.log(`CLI: ${pkg.version} (latest: ${cliLatest} — run \\`wayai update\\`)`);\n }\n\n if (skill.installed && skill.latest) {\n console.log(\n `Skill: ${skill.version} (latest: ${skill.latest} — run \\`npx skills add wayai-pro/wayai-skill -y\\`)`\n );\n }\n\n if (orgs.length > 0) {\n console.log(`Organizations: ${orgs.length}`);\n }\n\n if (repoConfig) {\n const orgLine = repoConfig.organization_name\n ? `${repoConfig.organization_name} (${repoConfig.organization_id})`\n : repoConfig.organization_id;\n console.log(`Repository scope:`);\n console.log(` Organization: ${orgLine}`);\n console.log(` Hubs: ${workspace.hub_count}`);\n } else {\n console.log('No .wayai.yaml found — run `wayai init` to scope this repo to an organization.');\n }\n\n if (lockedHubId) {\n console.log(`Worktree lock: ${lockedHubId} (run \\`wayai unlock\\` to clear)`);\n }\n\n // Best-effort, non-JSON path only (the --json branch returned above): remind the reporter of\n // any reports awaiting their accept/contest. Self-guards on TTY; only runs with a valid token.\n if (tokenValid === true && accessToken) {\n await nudgeReportActions(config.api_url, accessToken);\n }\n}\n","/**\n * wayai whoami — show the authenticated identity\n *\n * Usage:\n * wayai whoami # human-readable output\n * wayai whoami --json # structured output for agents/scripts\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { ApiClient } from '../lib/api-client.js';\n\nexport function parseArgs(args: string[]): { json: boolean } {\n return { json: args.includes('--json') };\n}\n\nexport async function whoamiCommand(args: string[]): Promise<void> {\n const { json } = parseArgs(args);\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n const me = await client.me();\n\n if (json) {\n console.log(JSON.stringify(me, null, 2));\n return;\n }\n\n console.log(`email: ${me.email || '(unknown)'}`);\n console.log(`user_id: ${me.user_id}`);\n console.log(`org_id: ${me.org_id ?? '(none)'}`);\n console.log(`is_platform_admin: ${me.is_platform_admin}`);\n if (me.is_platform_admin) {\n console.log('\\nPlatform-admin diagnostics available: `wayai admin`');\n }\n}\n","/**\n * wayai init [--org <uuid>] — set up .wayai.yaml to scope this repo to an organization\n *\n * Interactive mode: prompts user to pick an org (or auto-selects if only one).\n * Direct mode: --org <uuid> sets the org without prompting.\n *\n * Hubs self-identify via `hub.yaml` inside their folder; this file only carries\n * org context so that push/pull know which org to talk to.\n */\n\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { requireAuth } from '../lib/auth.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { readRepoConfig, writeRepoConfig } from '../lib/repo-config.js';\nimport { findGitRoot } from '../lib/workspace.js';\nimport { resolveLayout } from '../lib/layout.js';\nimport { UUID_RE, prompt } from '../lib/utils.js';\n\nexport const SKILL_INSTALL_CMD = 'npx skills add wayai-pro/wayai-skill -y';\n\nconst AGENTS_MD = `# WayAI Workspace\n\nThis is a WayAI hub-as-code workspace. Hub configuration is stored as files (\\`hub.yaml\\`, \\`agents/*.yaml\\`, \\`agents/*.md\\`) and synced bidirectionally with the WayAI platform via the \\`wayai\\` CLI.\n\n**Always start by reading the WayAI skill.** Install it with \\`${SKILL_INSTALL_CMD}\\` if you haven't already; the skill covers:\n- Platform entities, hub types, AI modes, agent roles, connection types\n- Workflow (\\`wayai update\\` → \\`wayai pull\\` → edit → \\`wayai push\\`)\n- Common CLI commands and the decision matrix (CLI vs UI)\n- Repository structure and YAML shapes (\\`hub.yaml\\`, \\`agents/<slug>.yaml\\`)\n- Pointers to per-domain references (Connections, Agents, Resources, States, Outbound, Evals, Analytics, Templates)\n\nProject-specific overrides live in \\`AGENTS.local.md\\` — read it after the skill if it exists.\n\nThis file is created once on \\`wayai init\\` and never overwritten — edit freely.\n`;\n\nconst CLAUDE_MD = `@AGENTS.md\n@AGENTS.local.md\n`;\n\nconst AGENTS_LOCAL_MD = `# Project-specific instructions\n\nThis file holds project-specific overrides and additional instructions for AI coding agents working on this hub. It is **never overwritten by \\`wayai\\` commands** — edit freely.\n\nUse it for things like:\n\n- Domain glossary and terminology specific to this hub\n- Business rules the AI should always apply\n- Conventions or constraints that override defaults in \\`AGENTS.md\\`\n- Notes about external systems, integrations, or quirks\n- Pointers to other repo files the agent should read first\n\nLeave this file empty (or delete its body) if you have nothing to add — \\`AGENTS.md\\` is sufficient on its own.\n`;\n\nconst SHIM_FILES: Array<{ name: string; content: string }> = [\n { name: 'AGENTS.md', content: AGENTS_MD },\n { name: 'CLAUDE.md', content: CLAUDE_MD },\n { name: 'AGENTS.local.md', content: AGENTS_LOCAL_MD },\n];\n\nexport function writeWorkspaceFiles(gitRoot: string): string[] {\n const created: string[] = [];\n for (const { name, content } of SHIM_FILES) {\n const filePath = path.join(gitRoot, name);\n if (!existsSync(filePath)) {\n writeFileSync(filePath, content);\n created.push(name);\n }\n }\n // Create the hubs dir for the active layout (`wayai-ws/hubs/` on a fresh repo;\n // the legacy `workspace/` if this repo predates migration).\n const hubsDir = resolveLayout(gitRoot).hubsDir;\n if (!existsSync(hubsDir)) {\n mkdirSync(hubsDir, { recursive: true });\n created.push(`${path.relative(gitRoot, hubsDir)}/`);\n }\n return created;\n}\n\nexport function parseArgs(args: string[]): { orgId: string | undefined; autoConfirm: boolean } {\n let orgId: string | undefined;\n let autoConfirm = false;\n const orgIdx = args.indexOf('--org');\n if (orgIdx !== -1 && args[orgIdx + 1]) {\n orgId = args[orgIdx + 1];\n }\n for (const arg of args) {\n if (arg === '--yes' || arg === '-y') {\n autoConfirm = true;\n }\n }\n return { orgId, autoConfirm };\n}\n\nexport async function initCommand(args: string[]): Promise<void> {\n const { orgId: directOrgId, autoConfirm } = parseArgs(args);\n\n // Warn if .wayai.yaml already exists\n const existing = readRepoConfig();\n if (existing) {\n const scopeLabel = existing.organization_name\n ? `${existing.organization_name} (${existing.organization_id})`\n : existing.organization_id;\n console.log(`Current scope: ${scopeLabel}`);\n if (!autoConfirm) {\n const answer = await prompt('Overwrite? [y/N]: ');\n if (answer.toLowerCase() !== 'y') {\n console.log('Cancelled.');\n return;\n }\n }\n }\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n if (directOrgId) {\n await initDirect(client, directOrgId);\n } else {\n await initInteractive(client, autoConfirm);\n }\n\n // Write workspace shim files (AGENTS.md, CLAUDE.md, AGENTS.local.md) and create the hubs dir.\n // Files are only written if absent — never overwritten on subsequent inits.\n const gitRoot = findGitRoot();\n if (gitRoot) {\n const created = writeWorkspaceFiles(gitRoot);\n if (created.length > 0) {\n console.log(`Created ${created.join(', ')}`);\n }\n }\n\n console.log(\n `Run \\`${SKILL_INSTALL_CMD}\\` to install the WayAI skill in your AI harness, then \\`wayai pull\\` to fetch hub configuration.`,\n );\n}\n\nasync function initDirect(client: ApiClient, orgId: string): Promise<void> {\n if (!UUID_RE.test(orgId)) {\n console.error('Invalid organization ID. Expected a UUID.');\n process.exit(1);\n }\n\n console.log('Looking up organization...');\n const { organizations } = await client.organizations();\n const match = organizations.find((o) => o.id === orgId);\n\n if (!match) {\n console.error(`Organization ${orgId} not found among the orgs you can access.`);\n process.exit(1);\n }\n\n const configPath = writeRepoConfig({\n organization_id: match.id,\n organization_name: match.name,\n });\n\n console.log(`Found: ${match.name}`);\n console.log(`\\nWrote ${configPath}`);\n}\n\nasync function initInteractive(client: ApiClient, autoConfirm: boolean): Promise<void> {\n console.log('Fetching organizations...');\n let organizations = (await client.organizations()).organizations;\n\n if (organizations.length === 0) {\n // No org yet — create one inline rather than bouncing to the web UI. In\n // non-interactive mode (-y / CI) there's no one to prompt, so direct the\n // caller to the scriptable primitive instead of hanging on stdin.\n if (autoConfirm) {\n console.error('No organizations found. Create one with `wayai org create \"<name>\"`, then re-run `wayai init`.');\n process.exit(1);\n }\n console.log('\\nNo organizations found.');\n const name = (await prompt('Name your first organization (blank to cancel): ')).trim();\n if (!name) {\n console.error('Cancelled. Create one later with `wayai org create \"<name>\"`.');\n process.exit(1);\n }\n const { organization } = await client.createOrganization(name);\n console.log(`Created organization: ${organization.name} (${organization.id})`);\n if (organization.region && !organization.region_explicit) {\n console.log(` Region: ${organization.region} (closest to you — re-create with \\`wayai org create --region\\` to change)`);\n }\n organizations = [{ id: organization.id, name: organization.name }];\n }\n\n let selectedOrg: { id: string; name: string };\n\n if (organizations.length === 1) {\n selectedOrg = organizations[0];\n console.log(`Organization: ${selectedOrg.name}`);\n } else {\n console.log('\\nOrganizations:');\n for (let i = 0; i < organizations.length; i++) {\n console.log(` ${i + 1}. ${organizations[i].name}`);\n }\n const orgAnswer = await prompt(`\\nSelect organization [1-${organizations.length}]: `);\n const orgIdx = parseInt(orgAnswer, 10) - 1;\n if (isNaN(orgIdx) || orgIdx < 0 || orgIdx >= organizations.length) {\n console.error('Invalid selection.');\n process.exit(1);\n }\n selectedOrg = organizations[orgIdx];\n }\n\n const configPath = writeRepoConfig({\n organization_id: selectedOrg.id,\n organization_name: selectedOrg.name,\n });\n\n console.log(`\\nWrote ${configPath}`);\n}\n","/**\n * Resource file-tree primitives shared by hub-as-code and org-as-code.\n *\n * Both surfaces represent a resource's files as a directory tree on disk\n * (`<root>/<slug>/...`), scan them into `HubAsCodeResourceFile[]` (text inline,\n * binary as base64, SHA-256 hashes), and write them back. Extracted here so\n * the binary/hash/orphan-cleanup rules live in exactly one place.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as crypto from 'node:crypto';\nimport type { HubAsCodeResourceFile } from './types.js';\n\nexport const BINARY_EXTENSIONS = new Set([\n 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'ico',\n 'mp3', 'mp4', 'wav', 'zip', 'tar', 'gz',\n 'woff', 'woff2', 'ttf', 'eot',\n]);\n\nexport const MAX_RESOURCE_FILE_SIZE = 10 * 1024 * 1024; // 10MB\n\nexport function isBinaryFile(filename: string): boolean {\n const ext = filename.split('.').pop()?.toLowerCase() || '';\n return BINARY_EXTENSIONS.has(ext);\n}\n\nexport function guessMimeType(filename: string): string | undefined {\n const ext = filename.split('.').pop()?.toLowerCase() || '';\n const mimeMap: Record<string, string> = {\n md: 'text/markdown', txt: 'text/plain', json: 'application/json',\n yaml: 'text/yaml', yml: 'text/yaml', html: 'text/html', css: 'text/css',\n js: 'text/javascript', ts: 'text/typescript', xml: 'text/xml', csv: 'text/csv',\n pdf: 'application/pdf', png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg',\n gif: 'image/gif', webp: 'image/webp', svg: 'image/svg+xml', ico: 'image/x-icon',\n mp3: 'audio/mpeg', mp4: 'video/mp4', wav: 'audio/wav',\n zip: 'application/zip', tar: 'application/x-tar', gz: 'application/gzip',\n woff: 'font/woff', woff2: 'font/woff2', ttf: 'font/ttf', eot: 'application/vnd.ms-fontobject',\n };\n return mimeMap[ext];\n}\n\nexport function computeHash(data: Buffer): string {\n return crypto.createHash('sha256').update(data).digest('hex');\n}\n\n/** Recursively scan a resource directory into file entries (text inline, binary base64). */\nexport function scanResourceFiles(dir: string, prefix = ''): HubAsCodeResourceFile[] {\n const files: HubAsCodeResourceFile[] = [];\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;\n\n if (entry.isDirectory()) {\n files.push(...scanResourceFiles(path.join(dir, entry.name), relPath));\n } else if (entry.isFile()) {\n const fullPath = path.join(dir, entry.name);\n const stat = fs.statSync(fullPath);\n\n if (stat.size > MAX_RESOURCE_FILE_SIZE) {\n console.warn(` Warning: skipping ${relPath} (${(stat.size / 1024 / 1024).toFixed(1)}MB exceeds 10MB limit)`);\n continue;\n }\n\n const fileEntry: HubAsCodeResourceFile = {\n path: relPath,\n mime_type: guessMimeType(entry.name),\n file_size: stat.size,\n };\n\n const data = fs.readFileSync(fullPath);\n fileEntry.hash = computeHash(data);\n\n if (isBinaryFile(entry.name)) {\n fileEntry.content_base64 = data.toString('base64');\n } else {\n fileEntry.content = data.toString('utf-8');\n }\n\n files.push(fileEntry);\n }\n }\n\n return files;\n}\n\n/**\n * Write a resource's files into `resDir`, then prune orphans. Text and base64\n * content land synchronously; files carrying only `download_url` are left for\n * the caller's async download pass but still counted as written (not orphaned).\n */\nexport function writeResourceFileTree(resDir: string, files: HubAsCodeResourceFile[]): void {\n if (files.length === 0) {\n if (fs.existsSync(resDir)) cleanOrphanFiles(resDir, '', new Set<string>());\n return;\n }\n\n const writtenPaths = new Set<string>();\n for (const file of files) {\n const filePath = path.join(resDir, file.path);\n // Guard against path traversal (e.g. \"../../../.bashrc\")\n if (!filePath.startsWith(resDir + path.sep) && filePath !== resDir) {\n console.warn(` Warning: skipping ${file.path} (path traversal detected)`);\n continue;\n }\n const fileDir = path.dirname(filePath);\n if (!fs.existsSync(fileDir)) fs.mkdirSync(fileDir, { recursive: true });\n writtenPaths.add(file.path);\n\n if (file.content !== undefined) {\n fs.writeFileSync(filePath, file.content, 'utf-8');\n } else if (file.content_base64) {\n fs.writeFileSync(filePath, Buffer.from(file.content_base64, 'base64'));\n }\n // download_url files are written later by downloadBinaryFiles\n }\n\n if (fs.existsSync(resDir)) cleanOrphanFiles(resDir, '', writtenPaths);\n}\n\n/** Recursively remove files not in `writtenPaths`, plus any directories left empty. */\nexport function cleanOrphanFiles(dir: string, prefix: string, writtenPaths: Set<string>): void {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n cleanOrphanFiles(fullPath, relPath, writtenPaths);\n if (fs.readdirSync(fullPath).length === 0) fs.rmdirSync(fullPath);\n } else if (!writtenPaths.has(relPath)) {\n fs.unlinkSync(fullPath);\n }\n }\n}\n\n/**\n * Download binary files (those carrying `download_url` and no inline content)\n * into `resDir`. Returns the count downloaded. Path-traversal guarded.\n */\nexport async function downloadBinaryFiles(resDir: string, files: HubAsCodeResourceFile[]): Promise<number> {\n let count = 0;\n for (const file of files) {\n if (!file.download_url || file.content !== undefined) continue;\n try {\n const filePath = path.join(resDir, file.path);\n if (!filePath.startsWith(resDir + path.sep) && filePath !== resDir) {\n console.warn(` Warning: skipping ${file.path} (path traversal detected)`);\n continue;\n }\n const response = await fetch(file.download_url);\n if (!response.ok) {\n console.warn(` Warning: failed to download ${file.path} (${response.status})`);\n continue;\n }\n const buffer = Buffer.from(await response.arrayBuffer());\n const fileDir = path.dirname(filePath);\n if (!fs.existsSync(fileDir)) fs.mkdirSync(fileDir, { recursive: true });\n fs.writeFileSync(filePath, buffer);\n count++;\n } catch (err) {\n console.warn(` Warning: failed to download ${file.path} (${err instanceof Error ? err.message : String(err)})`);\n }\n }\n return count;\n}\n","/**\n * YAML writer — converts HubAsCodePayload to hub.yaml + agents/<slug>.yaml + agents/<slug>.md files\n * Reverse of parser.ts\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as yaml from 'js-yaml';\nimport { slugify } from './utils.js';\nimport { writeResourceFileTree } from './resource-files.js';\nimport type { HubAsCodePayload, HubAsCodeAgent, HubAsCodeResource, HubAsCodeEval } from './types.js';\n\nexport const YAML_DUMP_OPTIONS: yaml.DumpOptions = {\n lineWidth: -1, // don't wrap lines\n noRefs: true, // don't use YAML anchors\n quotingType: '\"',\n forceQuotes: false,\n sortKeys: false,\n};\n\n// Shared between writeEvalYamlFiles (pull) and `wayai eval capture` so the on-disk shape stays identical.\nexport function buildEvalYamlObject(evalEntry: HubAsCodeEval, slug: string): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n if (evalEntry.id) out.id = evalEntry.id;\n if (evalEntry.name !== slug) out.name = evalEntry.name;\n out.agent = evalEntry.agent;\n if (evalEntry.agent_id) out.agent_id = evalEntry.agent_id;\n if (typeof evalEntry.runs === 'number' && evalEntry.runs !== 1) {\n out.runs = evalEntry.runs;\n }\n if (evalEntry.enabled === false) {\n out.enabled = false;\n }\n if (evalEntry.history && evalEntry.history.length > 0) {\n out.history = evalEntry.history;\n }\n out.input = evalEntry.input;\n out.expected = evalEntry.expected;\n if (evalEntry.evaluator_instructions) {\n out.evaluator_instructions = evalEntry.evaluator_instructions;\n }\n return out;\n}\n\n/**\n * Write a HubAsCodePayload to disk as hub.yaml + agents/<slug>.yaml + agents/<slug>.md files.\n *\n * - Creates `hub.yaml` with hub config (no agents section)\n * - Creates `agents/<slug>.yaml` for each agent (all config except instructions)\n * - Creates `agents/<slug>.md` for each agent with instructions\n * - Removes orphan .yaml and .md files in agents/ that don't match any current agent\n * - Deletes old `wayai.yaml` if present (migration)\n */\nexport function writeHubFolder(hubFolder: string, payload: HubAsCodePayload): void {\n // Ensure directories exist\n const agentsDir = path.join(hubFolder, 'agents');\n if (!fs.existsSync(hubFolder)) {\n fs.mkdirSync(hubFolder, { recursive: true });\n }\n if (!fs.existsSync(agentsDir)) {\n fs.mkdirSync(agentsDir, { recursive: true });\n }\n\n // Build YAML-safe payload (no agents section)\n const yamlPayload = buildYamlPayload(payload);\n const agentFiles = extractAgentFiles(payload);\n\n // Write hub.yaml\n const yamlContent = yaml.dump(yamlPayload, YAML_DUMP_OPTIONS);\n fs.writeFileSync(path.join(hubFolder, 'hub.yaml'), yamlContent, 'utf-8');\n\n // Init-only: 1-line Claude Code shim that imports the hub's AGENTS.md.\n // Skipped if the user has edited it. Other harnesses load AGENTS.md natively.\n const claudeShimPath = path.join(hubFolder, 'CLAUDE.md');\n if (!fs.existsSync(claudeShimPath)) {\n fs.writeFileSync(claudeShimPath, '@AGENTS.md\\n', 'utf-8');\n }\n\n // Delete old wayai.yaml if it exists (migration)\n const oldYamlPath = path.join(hubFolder, 'wayai.yaml');\n if (fs.existsSync(oldYamlPath)) {\n fs.unlinkSync(oldYamlPath);\n }\n\n // Write agent YAML config files + instruction files\n // Track .yaml and .md slugs separately so agents without instructions get their .md cleaned up\n const yamlSlugs = writeAgentYamlFiles(agentsDir, payload.agents || []);\n const mdSlugs = new Set<string>();\n for (const { slug, content } of agentFiles) {\n mdSlugs.add(slug);\n fs.writeFileSync(path.join(agentsDir, `${slug}.md`), content, 'utf-8');\n }\n\n // Remove orphan .yaml and .md files\n const existingFiles = fs.readdirSync(agentsDir);\n for (const file of existingFiles) {\n if (file.endsWith('.yaml')) {\n const slug = file.slice(0, -5);\n if (!yamlSlugs.has(slug)) {\n fs.unlinkSync(path.join(agentsDir, file));\n }\n } else if (file.endsWith('.md')) {\n const slug = file.slice(0, -3);\n if (!mdSlugs.has(slug)) {\n fs.unlinkSync(path.join(agentsDir, file));\n }\n }\n }\n\n // Write resource files\n writeResourceFiles(hubFolder, payload.resources || []);\n\n // Write eval scenario files (always run — handles transition from \"evals exist\" to \"no evals\")\n writeEvalYamlFiles(hubFolder, payload.evals || []);\n}\n\n/**\n * Build the YAML-safe version of the payload (hub config only, no agents).\n * Agents are written to separate files by writeAgentYamlFiles().\n */\nfunction buildYamlPayload(payload: HubAsCodePayload): Record<string, unknown> {\n const result: Record<string, unknown> = {\n version: payload.version,\n hub_id: payload.hub_id,\n hub_environment: payload.hub_environment,\n };\n\n // Include preview_label for preview hubs (read-only metadata)\n if (payload.preview_label) {\n result.preview_label = payload.preview_label;\n }\n\n result.hub = payload.hub;\n\n // Agents are NOT included in hub.yaml — they live in agents/<slug>.yaml\n\n if (payload.resources && payload.resources.length > 0) {\n // Strip files from resource entries — filesystem is source of truth\n result.resources = payload.resources.map((r) => {\n const { files, ...rest } = r;\n return rest;\n });\n }\n\n if (payload.states && payload.states.length > 0) {\n result.states = payload.states;\n }\n\n if (payload.teams && payload.teams.length > 0) {\n result.teams = payload.teams;\n }\n\n if (payload.connections && payload.connections.length > 0) {\n result.connections = payload.connections;\n }\n\n if (payload.outbound_contacts && payload.outbound_contacts.length > 0) {\n result.outbound_contacts = payload.outbound_contacts;\n }\n\n if (payload.outbound_lists && payload.outbound_lists.length > 0) {\n result.outbound_lists = payload.outbound_lists;\n }\n\n if (payload.outbound_schedules && payload.outbound_schedules.length > 0) {\n result.outbound_schedules = payload.outbound_schedules;\n }\n\n return result;\n}\n\n/**\n * Write per-agent YAML config files to agents/ directory.\n * Each agent gets agents/<slug>.yaml with all config except instructions.\n * Returns the set of slugs written (for orphan cleanup).\n */\nfunction writeAgentYamlFiles(agentsDir: string, agents: HubAsCodeAgent[]): Set<string> {\n const slugs = new Set<string>();\n for (const agent of agents) {\n const slug = slugify(agent.name);\n slugs.add(slug);\n const entry: Record<string, unknown> = { ...agent };\n\n // Instructions go to .md file, not .yaml\n delete entry.instructions;\n\n const yamlContent = yaml.dump(entry, YAML_DUMP_OPTIONS);\n fs.writeFileSync(path.join(agentsDir, `${slug}.yaml`), yamlContent, 'utf-8');\n }\n return slugs;\n}\n\n/**\n * Extract agent instruction files from the payload.\n */\nfunction extractAgentFiles(\n payload: HubAsCodePayload\n): Array<{ slug: string; content: string }> {\n const files: Array<{ slug: string; content: string }> = [];\n\n for (const agent of payload.agents || []) {\n if (agent.instructions) {\n files.push({\n slug: slugify(agent.name),\n content: agent.instructions,\n });\n }\n }\n\n return files;\n}\n\n// Writes evals/<slug>.yaml (root) or evals/<set>/<slug>.yaml; removes orphan .yaml files and empty set folders.\nfunction writeEvalYamlFiles(hubFolder: string, evals: HubAsCodeEval[]): void {\n const evalsDir = path.join(hubFolder, 'evals');\n\n // No evals: clean the directory if it exists, otherwise no-op.\n if (evals.length === 0) {\n if (fs.existsSync(evalsDir)) {\n cleanEvalOrphans(evalsDir, new Set<string>());\n // Remove the now-empty top-level dir for tidiness.\n try {\n if (fs.readdirSync(evalsDir).length === 0) fs.rmdirSync(evalsDir);\n } catch { /* keep dir if non-empty (e.g. user-added files) */ }\n }\n return;\n }\n\n if (!fs.existsSync(evalsDir)) {\n fs.mkdirSync(evalsDir, { recursive: true });\n }\n\n // Track relative paths written (e.g. \"greeting.yaml\", \"set-a/foo.yaml\") for orphan cleanup.\n const writtenRelPaths = new Set<string>();\n\n for (const evalEntry of evals) {\n const slug = slugify(evalEntry.name);\n const setName = evalEntry.path && evalEntry.path.trim().length > 0 ? evalEntry.path : null;\n const relPath = setName ? `${setName}/${slug}.yaml` : `${slug}.yaml`;\n const targetPath = path.join(evalsDir, relPath);\n\n // Defense-in-depth: the backend's `validateScenarioSetName` doesn't\n // restrict path separators, so refuse to write any path that escapes\n // evals/. Same pattern as `cleanOrphanFiles` for resource files.\n if (!targetPath.startsWith(evalsDir + path.sep)) {\n console.warn(` Warning: skipping eval \"${evalEntry.name}\" (scenario set \"${setName}\" escapes evals/ — possible bad backend data)`);\n continue;\n }\n\n if (setName) {\n const setDir = path.join(evalsDir, setName);\n if (!fs.existsSync(setDir)) {\n fs.mkdirSync(setDir, { recursive: true });\n }\n }\n\n const yamlContent = yaml.dump(buildEvalYamlObject(evalEntry, slug), YAML_DUMP_OPTIONS);\n fs.writeFileSync(targetPath, yamlContent, 'utf-8');\n writtenRelPaths.add(relPath);\n }\n\n cleanEvalOrphans(evalsDir, writtenRelPaths);\n}\n\n// Only touches .yaml files (user-added READMEs/notes are preserved); empty set subfolders are pruned.\nfunction cleanEvalOrphans(evalsDir: string, writtenRelPaths: Set<string>): void {\n const entries = fs.readdirSync(evalsDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(evalsDir, entry.name);\n\n if (entry.isFile()) {\n if (entry.name.endsWith('.yaml') && !writtenRelPaths.has(entry.name)) {\n fs.unlinkSync(fullPath);\n }\n continue;\n }\n\n if (entry.isDirectory()) {\n const setName = entry.name;\n const subEntries = fs.readdirSync(fullPath, { withFileTypes: true });\n for (const sub of subEntries) {\n if (sub.isFile() && sub.name.endsWith('.yaml')) {\n const relPath = `${setName}/${sub.name}`;\n if (!writtenRelPaths.has(relPath)) {\n fs.unlinkSync(path.join(fullPath, sub.name));\n }\n }\n // Nested directories aren't valid eval layout — leave them alone.\n }\n // Remove now-empty scenario-set folder.\n try {\n if (fs.readdirSync(fullPath).length === 0) fs.rmdirSync(fullPath);\n } catch { /* ignore — non-empty (e.g. user notes) */ }\n }\n }\n}\n\n/**\n * Write resource files to disk and clean up orphan resource directories.\n */\nfunction writeResourceFiles(hubFolder: string, resources: HubAsCodeResource[]): void {\n const resourcesDir = path.join(hubFolder, 'resources');\n\n // Track current resource slugs for orphan cleanup\n const currentSlugs = new Set<string>();\n\n for (const resource of resources) {\n const resSlug = slugify(resource.name);\n currentSlugs.add(resSlug);\n const resDir = path.join(resourcesDir, resSlug);\n writeResourceFileTree(resDir, resource.files || []);\n }\n\n // Remove orphan resource directories\n if (fs.existsSync(resourcesDir)) {\n const existingDirs = fs.readdirSync(resourcesDir, { withFileTypes: true });\n for (const entry of existingDirs) {\n if (entry.isDirectory() && !currentSlugs.has(entry.name)) {\n fs.rmSync(path.join(resourcesDir, entry.name), { recursive: true, force: true });\n }\n }\n }\n}\n","/**\n * Parse hub.yaml + agents/<slug>.yaml + agents/*.md into HubAsCodePayload.\n * Falls back to wayai.yaml for backward compatibility.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as yaml from 'js-yaml';\nimport { slugify, resolveHubYamlPath } from './utils.js';\nimport { scanResourceFiles } from './resource-files.js';\nimport type { HubAsCodePayload, HubAsCodeResource, HubAsCodeEval } from './types.js';\n\n/** Tag an Error as user-facing so the CLI prints just the message (no stack). */\nfunction expected(message: string): Error {\n const err = new Error(message);\n (err as Error & { isExpected: boolean }).isExpected = true;\n return err;\n}\n\ninterface WayaiYaml {\n version?: number;\n hub_id: string;\n hub_environment: string;\n preview_label?: string;\n hub: Record<string, unknown>;\n agents?: Array<Record<string, unknown>>;\n resources?: Array<Record<string, unknown>>;\n states?: Array<Record<string, unknown>>;\n teams?: Array<Record<string, unknown>>;\n connections?: Array<{\n name: string; type: string; service?: string; credential?: string; access_token_credential?: string;\n no_auth?: boolean; base_url?: string; headers?: Record<string, string>; settings?: Record<string, unknown>;\n account_sid?: string; enabled?: boolean; authentication_type?: string;\n }>;\n outbound_contacts?: Array<Record<string, unknown>>;\n outbound_lists?: Array<Record<string, unknown>>;\n outbound_schedules?: Array<Record<string, unknown>>;\n}\n\n/**\n * Parse a hub folder into a HubAsCodePayload.\n * Reads hub.yaml (or wayai.yaml for backward compat) and resolves agents from\n * agents/<slug>.yaml files (or inline agents array for old format).\n * Resolves agent instructions from companion .md files.\n */\nexport interface ParseHubFolderOptions {\n /** When true, allow hub_id and hub_environment to be absent (for new hubs not yet created on platform). */\n allowNewHub?: boolean;\n}\n\nexport function parseHubFolder(hubFolder: string, opts?: ParseHubFolderOptions): HubAsCodePayload {\n const yamlPath = resolveHubYamlPath(hubFolder);\n if (!yamlPath) {\n const err = new Error(`hub.yaml not found in ${hubFolder}`);\n (err as Error & { isExpected: boolean }).isExpected = true;\n throw err;\n }\n\n const yamlContent = fs.readFileSync(yamlPath, 'utf-8');\n let config: WayaiYaml;\n try {\n config = yaml.load(yamlContent) as WayaiYaml;\n } catch (err) {\n if (err instanceof yaml.YAMLException) {\n const userError = new Error(`Invalid YAML in ${yamlPath}: ${err.message}`);\n (userError as Error & { isExpected: boolean }).isExpected = true;\n throw userError;\n }\n throw err;\n }\n\n if (!config || typeof config !== 'object') {\n const invalidError = new Error(`Invalid YAML in ${yamlPath}`);\n (invalidError as Error & { isExpected: boolean }).isExpected = true;\n throw invalidError;\n }\n\n if (!opts?.allowNewHub) {\n if (!config.hub_id) {\n const err = new Error(`Missing hub_id in ${yamlPath}`);\n (err as Error & { isExpected: boolean }).isExpected = true;\n throw err;\n }\n\n if (!config.hub_environment) {\n const err = new Error(`Missing hub_environment in ${yamlPath}`);\n (err as Error & { isExpected: boolean }).isExpected = true;\n throw err;\n }\n }\n\n // Resolve agents: try per-agent YAML files first, fall back to inline agents\n const agentYamlFiles = scanAgentYamlFiles(hubFolder);\n const rawAgents = agentYamlFiles.length > 0 ? agentYamlFiles : config.agents;\n\n // Resolve agent instructions from .md files\n const agents = rawAgents?.map((agent) => {\n const resolved = { ...agent };\n\n if (typeof resolved.instructions === 'string' && resolved.instructions.endsWith('.md')) {\n // Explicit path: \"agents/pilot.md\" or \"pilot.md\" (legacy)\n const instrValue = resolved.instructions as string;\n const instructionsPath = instrValue.startsWith('agents/')\n ? path.join(hubFolder, instrValue)\n : path.join(hubFolder, 'agents', instrValue);\n\n if (fs.existsSync(instructionsPath)) {\n resolved.instructions = fs.readFileSync(instructionsPath, 'utf-8');\n } else {\n const err = new Error(\n `Agent instructions file not found: ${instructionsPath} (referenced by agent \"${agent.name}\")`\n );\n (err as Error & { isExpected: boolean }).isExpected = true;\n throw err;\n }\n } else if (resolved.instructions === undefined && typeof agent.name === 'string') {\n // Convention-based: derive path from agent name slug\n const conventionPath = path.join(hubFolder, 'agents', `${slugify(agent.name)}.md`);\n if (fs.existsSync(conventionPath)) {\n resolved.instructions = fs.readFileSync(conventionPath, 'utf-8');\n }\n }\n\n return resolved;\n });\n\n // Resolve resource files from disk\n const resources = parseResources(hubFolder, (config.resources || []) as Array<Record<string, unknown>>);\n\n const payload: HubAsCodePayload = {\n version: config.version || 1,\n hub_id: config.hub_id || '',\n hub_environment: config.hub_environment || 'preview',\n hub: config.hub as HubAsCodePayload['hub'],\n };\n\n // Read-only metadata from preview hubs\n if (config.preview_label) {\n payload.preview_label = config.preview_label;\n }\n\n if (agents && agents.length > 0) {\n payload.agents = agents as unknown as HubAsCodePayload['agents'];\n }\n\n if (resources.length > 0) {\n payload.resources = resources;\n }\n\n if (config.states && config.states.length > 0) {\n payload.states = config.states as unknown as HubAsCodePayload['states'];\n }\n\n if (config.teams && config.teams.length > 0) {\n payload.teams = config.teams as unknown as HubAsCodePayload['teams'];\n }\n\n // Emit `connections` whenever it's an array — INCLUDING an empty `[]` — so a\n // hub.yaml that removes its last connection block (present-but-empty) deletes\n // it on push. Unlike other entities (which `|| []` on the diff side, treating\n // absent == empty), the connection delete guard distinguishes an ABSENT key\n // (no-op) from a present `[]` (delete all unreferenced); the parser must\n // preserve that. A valueless `connections:` (js-yaml null) is intentionally\n // omitted → treated as absent (safe no-op).\n if (Array.isArray(config.connections)) {\n payload.connections = config.connections;\n }\n\n if (config.outbound_contacts && config.outbound_contacts.length > 0) {\n payload.outbound_contacts = config.outbound_contacts as unknown as HubAsCodePayload['outbound_contacts'];\n }\n\n if (config.outbound_lists && config.outbound_lists.length > 0) {\n payload.outbound_lists = config.outbound_lists as unknown as HubAsCodePayload['outbound_lists'];\n }\n\n if (config.outbound_schedules && config.outbound_schedules.length > 0) {\n payload.outbound_schedules = config.outbound_schedules as unknown as HubAsCodePayload['outbound_schedules'];\n }\n\n const evals = scanEvalYamlFiles(hubFolder);\n if (evals.length > 0) {\n payload.evals = evals;\n }\n\n return payload;\n}\n\n// Scan evals/<slug>.yaml (root, path=null) and evals/<set>/<slug>.yaml (one level deep only — flat-set model).\nfunction scanEvalYamlFiles(hubFolder: string): HubAsCodeEval[] {\n const evalsDir = path.join(hubFolder, 'evals');\n if (!fs.existsSync(evalsDir)) return [];\n\n const evals: HubAsCodeEval[] = [];\n const seen = new Set<string>(); // composite key \"<name>|<path>\" — must be unique\n\n const topEntries = fs.readdirSync(evalsDir, { withFileTypes: true })\n .sort((a, b) => a.name.localeCompare(b.name));\n\n for (const entry of topEntries) {\n if (entry.isFile() && entry.name.endsWith('.yaml')) {\n // Root-level scenario (no scenario set)\n collectEval(evals, seen, path.join(evalsDir, entry.name), `evals/${entry.name}`, null);\n } else if (entry.isDirectory()) {\n // Scenario-set subfolder (one level deep only)\n const setName = entry.name;\n const setDir = path.join(evalsDir, setName);\n const setEntries = fs.readdirSync(setDir, { withFileTypes: true })\n .sort((a, b) => a.name.localeCompare(b.name));\n for (const sub of setEntries) {\n if (sub.isDirectory()) {\n throw expected(\n `Nested scenario sets are not supported: ${path.relative(hubFolder, path.join(setDir, sub.name))}. ` +\n `Move scenarios up to evals/${setName}/.`,\n );\n }\n if (sub.isFile() && sub.name.endsWith('.yaml')) {\n collectEval(evals, seen, path.join(setDir, sub.name), `evals/${setName}/${sub.name}`, setName);\n }\n }\n }\n }\n\n return evals;\n}\n\nfunction collectEval(\n evals: HubAsCodeEval[],\n seen: Set<string>,\n filePath: string,\n relPath: string,\n setName: string | null,\n): void {\n const evalEntry = parseEvalYaml(filePath, relPath, setName);\n if (!evalEntry) return;\n const key = `${evalEntry.name}|${setName ?? ''}`;\n if (seen.has(key)) {\n const where = setName ? `scenario set \"${setName}\"` : 'root';\n throw expected(\n `Duplicate eval at ${where}: \"${evalEntry.name}\" (in ${path.basename(filePath)}). ` +\n `Each (name, scenario set) pair must be unique.`,\n );\n }\n seen.add(key);\n evals.push(evalEntry);\n}\n\n// Returns null on soft failures (empty/malformed file, warning logged); throws expected() on hard validation.\nfunction parseEvalYaml(filePath: string, relPath: string, setName: string | null): HubAsCodeEval | null {\n const content = fs.readFileSync(filePath, 'utf-8');\n let raw: unknown;\n try {\n raw = yaml.load(content);\n } catch (err) {\n if (err instanceof yaml.YAMLException) {\n throw expected(`Invalid YAML in ${relPath}: ${err.message}`);\n }\n throw err;\n }\n\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n console.warn(` Warning: skipping ${relPath} (not a YAML object)`);\n return null;\n }\n\n const data = raw as Record<string, unknown>;\n const fileSlug = path.basename(filePath, '.yaml');\n const evalName = typeof data.name === 'string' && data.name.trim().length > 0 ? data.name : fileSlug;\n\n // Required fields: agent, input, expected\n if (typeof data.agent !== 'string' || data.agent.trim().length === 0) {\n throw expected(`Eval \"${evalName}\" in ${relPath}: missing required field \"agent\" (string).`);\n }\n if (!data.input || typeof data.input !== 'object' || Array.isArray(data.input)) {\n throw expected(`Eval \"${evalName}\" in ${relPath}: missing required field \"input\" (object).`);\n }\n if (!data.expected || typeof data.expected !== 'object' || Array.isArray(data.expected)) {\n throw expected(`Eval \"${evalName}\" in ${relPath}: missing required field \"expected\" (object).`);\n }\n\n const evalEntry: HubAsCodeEval = {\n name: evalName,\n agent: data.agent,\n path: setName,\n input: data.input as HubAsCodeEval['input'],\n expected: data.expected as HubAsCodeEval['expected'],\n };\n\n if (typeof data.id === 'string') evalEntry.id = data.id;\n if (typeof data.agent_id === 'string') evalEntry.agent_id = data.agent_id;\n if (typeof data.runs === 'number') evalEntry.runs = data.runs;\n if (data.enabled === false) evalEntry.enabled = false;\n if (Array.isArray(data.history)) {\n evalEntry.history = data.history as HubAsCodeEval['history'];\n }\n if (typeof data.evaluator_instructions === 'string') {\n evalEntry.evaluator_instructions = data.evaluator_instructions;\n }\n\n return evalEntry;\n}\n\n/**\n * Scan agents/ directory for per-agent YAML config files.\n * Returns agent configs sorted alphabetically by filename.\n * Resolves instructions from companion .md files.\n */\nfunction scanAgentYamlFiles(hubFolder: string): Array<Record<string, unknown>> {\n const agentsDir = path.join(hubFolder, 'agents');\n if (!fs.existsSync(agentsDir)) return [];\n\n const yamlFiles = fs.readdirSync(agentsDir)\n .filter((f) => f.endsWith('.yaml'))\n .sort();\n\n if (yamlFiles.length === 0) return [];\n\n const agents: Array<Record<string, unknown>> = [];\n for (const file of yamlFiles) {\n const filePath = path.join(agentsDir, file);\n const content = fs.readFileSync(filePath, 'utf-8');\n let agent: Record<string, unknown>;\n try {\n agent = yaml.load(content) as Record<string, unknown>;\n } catch (err) {\n if (err instanceof yaml.YAMLException) {\n const userError = new Error(`Invalid YAML in agents/${file}: ${err.message}`);\n (userError as Error & { isExpected: boolean }).isExpected = true;\n throw userError;\n }\n throw err;\n }\n if (!agent || typeof agent !== 'object') continue;\n if (!agent.name) {\n console.warn(` Warning: skipping ${file} (missing 'name' field)`);\n continue;\n }\n agents.push(agent);\n }\n\n return agents;\n}\n\n/**\n * Scan resource directories and populate file entries with content and hashes.\n */\nfunction parseResources(\n hubFolder: string,\n configResources: Array<Record<string, unknown>>\n): HubAsCodeResource[] {\n const resourcesDir = path.join(hubFolder, 'resources');\n const results: HubAsCodeResource[] = [];\n\n for (const res of configResources) {\n const resource: HubAsCodeResource = {\n name: res.name as string,\n };\n if (res.id) resource.id = res.id as string;\n if (res.type) resource.type = res.type as string;\n if (res.description) resource.description = res.description as string;\n if (res.enabled === false) resource.enabled = false;\n if (res.user_browsable) resource.user_browsable = res.user_browsable as boolean;\n if (res.skill_name) resource.skill_name = res.skill_name as string;\n\n // Scan filesystem for files\n const resSlug = slugify(resource.name);\n const resDir = path.join(resourcesDir, resSlug);\n\n if (fs.existsSync(resDir)) {\n const files = scanResourceFiles(resDir, '');\n if (files.length > 0) {\n resource.files = files;\n }\n }\n\n results.push(resource);\n }\n\n return results;\n}\n","/**\n * Colored terminal output from diff summary markdown\n */\n\n/**\n * Print a diff summary to the terminal with ANSI colors.\n * Parses the markdown summary from the backend diff endpoint.\n */\nexport function printDiff(summary: string): void {\n const lines = summary.split('\\n');\n\n for (const line of lines) {\n if (line.startsWith('**') && line.endsWith('**')) {\n // Section header\n console.log(`\\n\\x1b[1m${line.replace(/\\*\\*/g, '')}\\x1b[0m`);\n } else if (line.trimStart().startsWith('+ ')) {\n // Addition — green\n console.log(`\\x1b[32m${line}\\x1b[0m`);\n } else if (line.trimStart().startsWith('- ')) {\n // Deletion — red\n console.log(`\\x1b[31m${line}\\x1b[0m`);\n } else if (line.trimStart().startsWith('~ ')) {\n // Modification — yellow\n console.log(`\\x1b[33m${line}\\x1b[0m`);\n } else if (line.includes('(no changes)')) {\n // No changes — dim\n console.log(`\\x1b[2m${line}\\x1b[0m`);\n } else {\n console.log(line);\n }\n }\n console.log(); // trailing newline\n}\n","/**\n * wayai pull [--hub <id|name>] [-y] — fetch hub config from the platform and write local files\n *\n * The hub is derived from the workspace:\n * - cwd is inside a hub folder → use that hub\n * - exactly one hub in the hubs dir → use it\n * - multiple hubs → require `--hub <uuid|folder-name>` to disambiguate\n *\n * For first-time pulls in an empty workspace, pass `--hub <uuid>` to fetch and\n * materialize the hub at `wayai-ws/hubs/<hub-slug>/` (or the legacy\n * `workspace/<hub-slug>/` for un-migrated repos — see `layout.ts`).\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { requireAuth } from '../lib/auth.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { writeHubFolder } from '../lib/yaml-writer.js';\nimport { parseHubFolder } from '../lib/parser.js';\nimport { printDiff } from '../lib/diff-display.js';\nimport { confirm, slugify, UUID_RE } from '../lib/utils.js';\nimport { downloadBinaryFiles } from '../lib/resource-files.js';\nimport {\n autoRenameHubFolder,\n detectWorkspace,\n findGitRoot,\n findEnclosingHubFolder,\n resolveHubFolder,\n scanWorkspaceHubs,\n} from '../lib/workspace.js';\nimport { resolveLayout, warnLayoutOnce, hubsDirLabel } from '../lib/layout.js';\nimport { requireRepoConfig } from '../lib/repo-config.js';\nimport { assertHubMatchesLock, autoLockIfUnlocked } from '../lib/hub-lock.js';\nimport type { HubAsCodePayload } from '../lib/types.js';\n\ninterface ParsedArgs {\n autoConfirm: boolean;\n hubSelector?: string;\n}\n\nfunction parseArgs(args: string[]): ParsedArgs {\n let autoConfirm = false;\n let hubSelector: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--yes' || arg === '-y') {\n autoConfirm = true;\n } else if (arg === '--hub' && args[i + 1]) {\n hubSelector = args[++i];\n }\n }\n\n return { autoConfirm, hubSelector };\n}\n\n/** Resolve the target hub for the pull. May return a not-yet-materialized hub_id. */\nfunction resolveHubTarget(\n workspaceDir: string,\n selector: string | undefined,\n): { hubId: string; hubFolder: string | null } {\n const wsLabel = hubsDirLabel(findGitRoot());\n const allHubs = scanWorkspaceHubs(workspaceDir);\n\n if (selector) {\n // Match against existing folders by hubId or basename\n const match = allHubs.find((h) =>\n h.hubId === selector || path.basename(h.hubFolder) === selector,\n );\n if (match) return { hubId: match.hubId, hubFolder: match.hubFolder };\n\n // Selector might be a UUID for a hub that hasn't been materialized yet.\n if (UUID_RE.test(selector)) return { hubId: selector, hubFolder: null };\n\n console.error(`No hub matching --hub ${selector} found in ${wsLabel}/. Pass a UUID for first-time pulls.`);\n process.exit(1);\n }\n\n const enclosing = findEnclosingHubFolder(workspaceDir);\n if (enclosing) return { hubId: enclosing.hubId, hubFolder: enclosing.hubFolder };\n\n if (allHubs.length === 1) return { hubId: allHubs[0].hubId, hubFolder: allHubs[0].hubFolder };\n\n if (allHubs.length === 0) {\n console.error(`No hub folders found in ${wsLabel}/. Pass --hub <uuid> to fetch a hub for the first time.`);\n process.exit(1);\n }\n\n console.error(`Multiple hubs found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);\n for (const h of allHubs) {\n console.error(` ${path.basename(h.hubFolder)} (${h.hubId})`);\n }\n process.exit(1);\n}\n\nexport async function pullCommand(args: string[]): Promise<void> {\n const { autoConfirm, hubSelector } = parseArgs(args);\n const repoConfig = requireRepoConfig();\n const { organization_id: organizationId } = repoConfig;\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n // Determine the hubs directory for the active layout.\n let workspaceDir: string;\n const workspace = detectWorkspace();\n const gitRoot = findGitRoot();\n if (workspace) {\n workspaceDir = workspace.workspaceDir;\n } else {\n if (!gitRoot) {\n console.error('Not inside a git repository.');\n process.exit(1);\n }\n workspaceDir = resolveLayout(gitRoot).hubsDir;\n }\n if (gitRoot) warnLayoutOnce(gitRoot);\n\n const { hubId, hubFolder: existingFolder } = resolveHubTarget(workspaceDir, hubSelector);\n\n assertHubMatchesLock(hubId);\n\n // Fetch remote hub config\n console.log('Fetching hub configuration...');\n const payload = await client.pull(hubId, organizationId);\n\n if (payload.hub_environment === 'production') {\n console.log('Skipping production hub — production hubs are not tracked in the repository. Edit the linked preview hub instead.');\n return;\n }\n\n let hubFolder = existingFolder;\n let wroteFiles = false;\n\n // If no existing folder, create path for first pull\n if (!hubFolder) {\n hubFolder = resolveHubFolder(\n workspaceDir,\n hubId,\n payload.hub.name,\n payload.hub_environment,\n payload.preview_label,\n payload.branch_name,\n );\n // Ensure parent directories exist\n fs.mkdirSync(path.dirname(hubFolder), { recursive: true });\n\n console.log('Writing hub configuration...');\n writeHubFolder(hubFolder, payload);\n await downloadBinaryResourceFiles(hubFolder, payload);\n const finalFolder = autoRenameHubFolder(hubFolder, payload.hub.name, payload.hub_environment, payload.hub_id, payload.preview_label, payload.branch_name);\n console.log(`Hub configuration written to ${finalFolder}`);\n wroteFiles = true;\n } else {\n // Hub folder exists — show diff before overwriting\n let cancelled = false;\n try {\n const localPayload = parseHubFolder(hubFolder);\n const diffResult = await client.diff(hubId, localPayload, 'pull', organizationId);\n\n // Connections are read-only references excluded from the diff engine.\n // Compare them separately so new/removed connections trigger a pull write.\n const connectionsChanged = !connectionsEqual(localPayload.connections, payload.connections);\n\n if (!diffResult.has_changes && !connectionsChanged) {\n // No semantic changes, but still write the remote payload to sync\n // metadata (tool IDs, connection IDs, etc.) that the diff engine ignores.\n writeHubFolder(hubFolder, payload);\n await downloadBinaryResourceFiles(hubFolder, payload);\n const finalFolder = autoRenameHubFolder(hubFolder, payload.hub.name, payload.hub_environment, payload.hub_id, payload.preview_label, payload.branch_name);\n wroteFiles = true;\n if (finalFolder === hubFolder) {\n console.log('Metadata synced — no config changes.');\n } else {\n console.log('Metadata synced; folder renamed.');\n }\n } else {\n console.log('\\nChanges to apply locally:');\n if (connectionsChanged) {\n console.log('**Connections:** updated');\n }\n printDiff(diffResult.summary);\n\n if (!autoConfirm) {\n const ok = await confirm('Apply these changes?');\n if (!ok) {\n console.log('Cancelled.');\n cancelled = true;\n }\n }\n\n if (!cancelled) {\n writeHubFolder(hubFolder, payload);\n await downloadBinaryResourceFiles(hubFolder, payload);\n const finalFolder = autoRenameHubFolder(hubFolder, payload.hub.name, payload.hub_environment, payload.hub_id, payload.preview_label, payload.branch_name);\n console.log(`Hub configuration written to ${finalFolder}`);\n wroteFiles = true;\n }\n }\n } catch {\n // Local files can't be parsed — overwrite\n console.log('Writing hub configuration...');\n writeHubFolder(hubFolder, payload);\n await downloadBinaryResourceFiles(hubFolder, payload);\n const finalFolder = autoRenameHubFolder(hubFolder, payload.hub.name, payload.hub_environment, payload.hub_id, payload.preview_label, payload.branch_name);\n console.log(`Hub configuration written to ${finalFolder}`);\n wroteFiles = true;\n }\n\n if (cancelled) return;\n }\n\n // Auto-lock the worktree to this hub on first successful pull. No-op if a\n // lock already exists (even pointing at the same hub) or if not in git.\n if (wroteFiles) autoLockIfUnlocked(hubId);\n}\n\n/**\n * Download binary resource files that have download_url but no inline content.\n */\nexport async function downloadBinaryResourceFiles(hubFolder: string, payload: HubAsCodePayload): Promise<void> {\n const resources = payload.resources || [];\n let downloadCount = 0;\n\n for (const resource of resources) {\n if (!resource.files) continue;\n const resDir = path.join(hubFolder, 'resources', slugify(resource.name));\n downloadCount += await downloadBinaryFiles(resDir, resource.files);\n }\n\n if (downloadCount > 0) {\n console.log(`Downloaded ${downloadCount} binary resource file(s).`);\n }\n}\n\n/**\n * Compare two connection arrays by id set.\n * Connections are read-only references — we only care whether the set changed\n * (added, removed, or renamed), not about field-level diffs.\n */\ntype ConnectionRef = { id?: string; name: string; type: string; service?: string };\nexport function connectionsEqual(\n a: ConnectionRef[] | undefined,\n b: ConnectionRef[] | undefined,\n): boolean {\n const listA = a || [];\n const listB = b || [];\n if (listA.length !== listB.length) return false;\n\n // Build a comparable key per connection (id if available, otherwise name+type+service)\n const key = (c: ConnectionRef) =>\n c.id || `${c.name}|${c.type}|${c.service || ''}`;\n\n const setA = new Set(listA.map(key));\n const setB = new Set(listB.map(key));\n if (setA.size !== setB.size) return false;\n for (const k of setA) {\n if (!setB.has(k)) return false;\n }\n return true;\n}\n","/**\n * wayai push [--hub <id|name>] [-y] — parse local files, diff remote, sync to preview\n *\n * The hub is derived from the workspace:\n * - cwd is inside a hub folder → use that hub\n * - exactly one hub in the hubs dir → use it\n * - multiple hubs → require `--hub <uuid|folder-name>` to disambiguate\n *\n * If a hub folder has hub.yaml without a `hub_id`, push creates the hub on the\n * platform first, then pushes its config.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as yaml from 'js-yaml';\nimport { requireAuth } from '../lib/auth.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { parseHubFolder } from '../lib/parser.js';\nimport { writeHubFolder } from '../lib/yaml-writer.js';\nimport { downloadBinaryResourceFiles } from './pull.js';\nimport { printDiff } from '../lib/diff-display.js';\nimport { confirm, slugify, resolveHubYamlPath, UUID_RE } from '../lib/utils.js';\nimport {\n autoRenameHubFolder,\n scanWorkspaceHubs,\n scanNewHubs,\n detectWorkspace,\n findGitRoot,\n findEnclosingHubFolder,\n type HubLocation,\n type NewHubLocation,\n} from '../lib/workspace.js';\nimport { resolveLayout, warnLayoutOnce, hubsDirLabel } from '../lib/layout.js';\nimport { requireRepoConfig } from '../lib/repo-config.js';\nimport { assertHubMatchesLock, assertNoLockBlocksHubCreation, autoLockIfUnlocked } from '../lib/hub-lock.js';\nimport type { CiSyncResponse, HubAsCodePayload } from '../lib/types.js';\n\ninterface ParsedArgs {\n autoConfirm: boolean;\n hubSelector?: string;\n}\n\nfunction parseArgs(args: string[]): ParsedArgs {\n let autoConfirm = false;\n let hubSelector: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--yes' || arg === '-y') {\n autoConfirm = true;\n } else if (arg === '--hub' && args[i + 1]) {\n hubSelector = args[++i];\n }\n }\n\n return { autoConfirm, hubSelector };\n}\n\nexport function printSyncResult(result: CiSyncResponse): void {\n console.log(`\\nSync complete. Preview hub: ${result.preview_hub_id}`);\n const c = result.changes;\n const parts: string[] = [];\n if (c.hub_updated) parts.push('hub updated');\n if (c.connections_created > 0) parts.push(`${c.connections_created} connection(s) created`);\n if (c.connections_updated > 0) parts.push(`${c.connections_updated} connection(s) updated`);\n if (c.connections_deleted > 0) parts.push(`${c.connections_deleted} connection(s) deleted`);\n if (c.agents_created > 0) parts.push(`${c.agents_created} agent(s) created`);\n if (c.agents_updated > 0) parts.push(`${c.agents_updated} agent(s) updated`);\n if (c.agents_deleted > 0) parts.push(`${c.agents_deleted} agent(s) deleted`);\n if (c.tools_created > 0) parts.push(`${c.tools_created} tool(s) created`);\n if (c.tools_updated > 0) parts.push(`${c.tools_updated} tool(s) updated`);\n if (c.tools_deleted > 0) parts.push(`${c.tools_deleted} tool(s) deleted`);\n if (c.states_created > 0) parts.push(`${c.states_created} state(s) created`);\n if (c.states_updated > 0) parts.push(`${c.states_updated} state(s) updated`);\n if (c.states_deleted > 0) parts.push(`${c.states_deleted} state(s) deleted`);\n if (c.teams_created > 0) parts.push(`${c.teams_created} team(s) created`);\n if (c.teams_updated > 0) parts.push(`${c.teams_updated} team(s) updated`);\n if (c.teams_deleted > 0) parts.push(`${c.teams_deleted} team(s) deleted`);\n if (c.resources_created > 0) parts.push(`${c.resources_created} resource(s) created`);\n if (c.resources_updated > 0) parts.push(`${c.resources_updated} resource(s) updated`);\n if (c.resources_deleted > 0) parts.push(`${c.resources_deleted} resource(s) deleted`);\n if (c.resource_files_uploaded > 0) parts.push(`${c.resource_files_uploaded} resource file(s) uploaded`);\n if (c.resource_files_deleted > 0) parts.push(`${c.resource_files_deleted} resource file(s) deleted`);\n if (c.resource_links_created > 0) parts.push(`${c.resource_links_created} resource link(s) created`);\n if (c.resource_links_updated > 0) parts.push(`${c.resource_links_updated} resource link(s) updated`);\n if (c.resource_links_deleted > 0) parts.push(`${c.resource_links_deleted} resource link(s) deleted`);\n if (c.outbound_contacts_created > 0) parts.push(`${c.outbound_contacts_created} outbound contact(s) created`);\n if (c.outbound_contacts_updated > 0) parts.push(`${c.outbound_contacts_updated} outbound contact(s) updated`);\n if (c.outbound_contacts_deleted > 0) parts.push(`${c.outbound_contacts_deleted} outbound contact(s) deleted`);\n if (c.outbound_lists_created > 0) parts.push(`${c.outbound_lists_created} outbound list(s) created`);\n if (c.outbound_lists_updated > 0) parts.push(`${c.outbound_lists_updated} outbound list(s) updated`);\n if (c.outbound_lists_deleted > 0) parts.push(`${c.outbound_lists_deleted} outbound list(s) deleted`);\n if (c.outbound_schedules_created > 0) parts.push(`${c.outbound_schedules_created} outbound schedule(s) created`);\n if (c.outbound_schedules_updated > 0) parts.push(`${c.outbound_schedules_updated} outbound schedule(s) updated`);\n if (c.outbound_schedules_deleted > 0) parts.push(`${c.outbound_schedules_deleted} outbound schedule(s) deleted`);\n if (parts.length > 0) {\n console.log(`Changes: ${parts.join(', ')}`);\n }\n\n if (result.errors && result.errors.length > 0) {\n printWarnings(result.errors);\n }\n if (result.warnings && result.warnings.length > 0) {\n printWarnings(result.warnings.map((w) => w.message));\n }\n}\n\n/** Render a yellow-highlighted \"Warnings (N)\" block. Shared by push + sync output. */\nexport function printWarnings(warnings: string[]): void {\n if (warnings.length === 0) return;\n console.log(`\\n\\x1b[33mWarnings (${warnings.length}):\\x1b[0m`);\n for (const w of warnings) {\n console.log(` \\x1b[33m! ${w}\\x1b[0m`);\n }\n}\n\n/**\n * Auto-rename agent .yaml and .md files when agents have been renamed (matched by ID).\n * Compares local agent names against remote agent names via pull,\n * then renames old-slug.yaml → new-slug.yaml and old-slug.md → new-slug.md.\n * Handles slug swaps via temp files.\n * Also updates explicit `instructions` paths in the hub YAML to match.\n */\nexport async function autoRenameAgentFiles(\n client: ApiClient,\n hubId: string,\n hubFolder: string,\n organizationId?: string\n): Promise<void> {\n // Collect agents with IDs from per-agent YAML files or main YAML\n const agentsDir = path.join(hubFolder, 'agents');\n let agentsWithIds: Array<{ id: string; name: string }> = [];\n\n // Try per-agent YAML files first\n if (fs.existsSync(agentsDir)) {\n const yamlFiles = fs.readdirSync(agentsDir).filter((f) => f.endsWith('.yaml'));\n for (const file of yamlFiles) {\n try {\n const content = fs.readFileSync(path.join(agentsDir, file), 'utf-8');\n const agent = yaml.load(content) as { id?: string; name?: string } | undefined;\n if (agent?.id && agent.name) {\n agentsWithIds.push({ id: agent.id, name: agent.name });\n }\n } catch {\n console.warn(` Warning: could not parse agents/${file}, skipping`);\n }\n }\n }\n\n // Fall back to inline agents from main YAML\n if (agentsWithIds.length === 0) {\n const yamlPath = resolveHubYamlPath(hubFolder);\n if (!yamlPath) return;\n\n const yamlContent = fs.readFileSync(yamlPath, 'utf-8');\n const config = yaml.load(yamlContent) as { agents?: Array<{ id?: string; name?: string }> };\n agentsWithIds = (config.agents || []).filter((a): a is { id: string; name: string } => !!a.id && !!a.name);\n }\n\n if (agentsWithIds.length === 0) return;\n\n // Fetch remote state to detect renames (extra round-trip, only when agents have IDs)\n console.log('Checking for agent renames...');\n let remote: HubAsCodePayload;\n try {\n remote = await client.pull(hubId, organizationId);\n } catch (err) {\n console.warn(` Warning: could not fetch remote state for auto-rename (${err instanceof Error ? err.message : String(err)}). File renames skipped.`);\n return;\n }\n\n // Build remote agent id → name map\n const remoteAgentNames = new Map<string, string>();\n for (const agent of remote.agents || []) {\n if (agent.id) {\n remoteAgentNames.set(agent.id, agent.name);\n }\n }\n\n // Collect renames needed (old slug → new slug)\n const renames: Array<{ oldSlug: string; newSlug: string }> = [];\n for (const agent of agentsWithIds) {\n const remoteName = remoteAgentNames.get(agent.id!);\n if (!remoteName || remoteName === agent.name) continue;\n\n const oldSlug = slugify(remoteName);\n const newSlug = slugify(agent.name!);\n if (oldSlug !== newSlug) {\n renames.push({ oldSlug, newSlug });\n }\n }\n\n if (renames.length === 0) return;\n\n if (!fs.existsSync(agentsDir)) return;\n\n // Clean up orphaned temp files from a previous interrupted rename\n for (const file of fs.readdirSync(agentsDir)) {\n if (file.startsWith('__rename_temp_') && (file.endsWith('.md') || file.endsWith('.yaml'))) {\n console.warn(` Warning: removing orphaned temp file agents/${file}`);\n fs.unlinkSync(path.join(agentsDir, file));\n }\n }\n\n // Helper to rename a file if it exists (for both .yaml and .md extensions)\n const renameFileIfExists = (dir: string, oldName: string, newName: string): boolean => {\n const oldPath = path.join(dir, oldName);\n const newPath = path.join(dir, newName);\n if (!fs.existsSync(oldPath)) return false;\n fs.renameSync(oldPath, newPath);\n return true;\n };\n\n // Detect slug swaps: if newSlug matches another rename's oldSlug\n const oldSlugs = new Set(renames.map((r) => r.oldSlug));\n const newSlugs = new Set(renames.map((r) => r.newSlug));\n const hasConflicts = renames.some((r) => oldSlugs.has(r.newSlug)) || newSlugs.size !== renames.length;\n\n // Track which renames actually completed (file existed and was moved)\n const completedRenames: Array<{ oldSlug: string; newSlug: string }> = [];\n const extensions = ['.yaml', '.md'];\n\n if (hasConflicts) {\n // Rename through temp files to avoid collisions\n const tempRenames: Array<{ oldSlug: string; tempName: string; newSlug: string }> = [];\n for (const { oldSlug, newSlug } of renames) {\n const tempName = `__rename_temp_${oldSlug}_${Date.now()}`;\n tempRenames.push({ oldSlug, tempName, newSlug });\n }\n\n // Step 1: old → temp (both extensions)\n for (const { oldSlug, tempName } of tempRenames) {\n for (const ext of extensions) {\n renameFileIfExists(agentsDir, `${oldSlug}${ext}`, `${tempName}${ext}`);\n }\n }\n\n // Step 2: temp → new (both extensions)\n for (const { oldSlug, tempName, newSlug } of tempRenames) {\n let anyRenamed = false;\n for (const ext of extensions) {\n if (renameFileIfExists(agentsDir, `${tempName}${ext}`, `${newSlug}${ext}`)) {\n anyRenamed = true;\n }\n }\n if (anyRenamed) {\n completedRenames.push({ oldSlug, newSlug });\n console.log(` Renamed agents/${oldSlug}.* → agents/${newSlug}.*`);\n }\n }\n } else {\n // No conflicts — direct renames\n for (const { oldSlug, newSlug } of renames) {\n // Check if any file with old slug exists\n const hasOldFile = extensions.some((ext) => fs.existsSync(path.join(agentsDir, `${oldSlug}${ext}`)));\n if (!hasOldFile) continue;\n\n // Check for target conflicts\n const hasNewFile = extensions.some((ext) => fs.existsSync(path.join(agentsDir, `${newSlug}${ext}`)));\n if (hasNewFile) {\n console.warn(` Warning: skipping rename agents/${oldSlug}.* → agents/${newSlug}.* (target already exists)`);\n continue;\n }\n\n for (const ext of extensions) {\n renameFileIfExists(agentsDir, `${oldSlug}${ext}`, `${newSlug}${ext}`);\n }\n completedRenames.push({ oldSlug, newSlug });\n console.log(` Renamed agents/${oldSlug}.* → agents/${newSlug}.*`);\n }\n }\n\n if (completedRenames.length === 0) return;\n\n // Update explicit instructions paths in hub YAML for completed renames only.\n const mainYamlPath = resolveHubYamlPath(hubFolder);\n if (mainYamlPath) {\n const mainYamlContent = fs.readFileSync(mainYamlPath, 'utf-8');\n const substitutionMap = new Map<string, string>();\n for (const { oldSlug, newSlug } of completedRenames) {\n substitutionMap.set(`agents/${oldSlug}.md`, `agents/${newSlug}.md`);\n }\n const escapedKeys = Array.from(substitutionMap.keys())\n .map((k) => k.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'));\n const updatedYaml = mainYamlContent.replace(\n new RegExp(`(instructions:\\\\s+)(${escapedKeys.join('|')})`, 'g'),\n (_match, prefix: string, pathMatch: string) => `${prefix}${substitutionMap.get(pathMatch) ?? pathMatch}`,\n );\n if (updatedYaml !== mainYamlContent) {\n fs.writeFileSync(mainYamlPath, updatedYaml, 'utf-8');\n console.log(` Updated instructions paths in ${path.basename(mainYamlPath)}`);\n }\n }\n}\n\n/** Pull remote config after push, sync local files, and rename hub folder if needed. */\nasync function syncAfterPush(\n client: ApiClient,\n hubId: string,\n hubFolder: string,\n organizationId?: string\n): Promise<void> {\n try {\n const remoteConfig = await client.pull(hubId, organizationId);\n writeHubFolder(hubFolder, remoteConfig);\n await downloadBinaryResourceFiles(hubFolder, remoteConfig);\n console.log('Local files synced with server.');\n\n const finalFolder = autoRenameHubFolder(hubFolder, remoteConfig.hub.name, remoteConfig.hub_environment, hubId, remoteConfig.preview_label, remoteConfig.branch_name);\n if (finalFolder !== hubFolder) {\n console.log(`Hub folder is now ${finalFolder}`);\n }\n } catch (err) {\n console.warn(`Warning: could not sync local files after push (${err instanceof Error ? err.message : String(err)})`);\n }\n}\n\nasync function pushSingleHub(\n client: ApiClient,\n hubId: string,\n hubFolder: string,\n autoConfirm: boolean,\n organizationId?: string,\n opts?: { skipAgentRename?: boolean }\n): Promise<boolean> {\n if (!opts?.skipAgentRename) {\n // Auto-rename agent .md files if agents were renamed (before parsing)\n await autoRenameAgentFiles(client, hubId, hubFolder, organizationId);\n }\n\n console.log('Parsing local configuration...');\n const localConfig = parseHubFolder(hubFolder);\n\n console.log('Computing diff...');\n const diffResult = await client.diff(hubId, localConfig, 'push', organizationId);\n\n // Render diff-time warnings (e.g. native/delegation tools dropped due to\n // missing connections) before any short-circuit. Without this, a push where\n // every change was silently dropped would just say \"No changes to push\". See\n // gh #1538.\n printWarnings(diffResult.warnings);\n\n if (!diffResult.has_changes) {\n // Still rename folder if hub name changed (content matches but folder slug is stale)\n const finalFolder = autoRenameHubFolder(hubFolder, localConfig.hub.name, localConfig.hub_environment, hubId, localConfig.preview_label, localConfig.branch_name);\n if (finalFolder === hubFolder) {\n console.log('No changes to push.');\n } else {\n console.log('No changes to push; folder renamed.');\n }\n autoLockIfUnlocked(hubId);\n return true;\n }\n\n console.log('\\nChanges to push:');\n printDiff(diffResult.summary);\n\n if (!autoConfirm) {\n const ok = await confirm('Push these changes?');\n if (!ok) {\n console.log('Cancelled.');\n return false;\n }\n }\n\n console.log('Pushing changes...');\n const result = await client.push(hubId, localConfig, organizationId);\n printSyncResult(result);\n\n await syncAfterPush(client, hubId, hubFolder, organizationId);\n\n autoLockIfUnlocked(hubId);\n return true;\n}\n\nfunction resolveWorkspaceDir(): string {\n const workspace = detectWorkspace();\n if (workspace) return workspace.workspaceDir;\n\n const gitRoot = findGitRoot();\n if (!gitRoot) {\n console.error('Not inside a git repository.');\n process.exit(1);\n }\n return resolveLayout(gitRoot).hubsDir;\n}\n\nfunction selectExistingHub(\n workspaceDir: string,\n allHubs: HubLocation[],\n selector: string | undefined,\n wsLabel: string,\n): HubLocation | null {\n if (selector) {\n const match = allHubs.find((h) =>\n h.hubId === selector || path.basename(h.hubFolder) === selector,\n );\n if (!match) {\n console.error(`No hub matching --hub ${selector} found in ${wsLabel}/.`);\n process.exit(1);\n }\n return match;\n }\n\n const enclosing = findEnclosingHubFolder(workspaceDir);\n if (enclosing) return enclosing;\n\n if (allHubs.length === 1) return allHubs[0];\n return null;\n}\n\nfunction selectNewHub(newHubs: NewHubLocation[], selector: string | undefined): NewHubLocation | null {\n if (selector) {\n const match = newHubs.find((h) => path.basename(h.hubFolder) === selector);\n if (!match) return null;\n return match;\n }\n\n // Try cwd\n const cwd = process.cwd();\n const cwdMatch = newHubs.find((h) => path.resolve(h.hubFolder) === path.resolve(cwd));\n if (cwdMatch) return cwdMatch;\n\n if (newHubs.length === 1) return newHubs[0];\n return null;\n}\n\nexport async function pushCommand(args: string[]): Promise<void> {\n const { autoConfirm, hubSelector } = parseArgs(args);\n const repoConfig = requireRepoConfig();\n const { organization_id: organizationId } = repoConfig;\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n const workspaceDir = resolveWorkspaceDir();\n const gitRoot = findGitRoot();\n const wsLabel = hubsDirLabel(gitRoot);\n if (gitRoot) warnLayoutOnce(gitRoot);\n if (!fs.existsSync(workspaceDir)) {\n console.error(`No ${wsLabel}/ directory found. Run \\`wayai pull\\` first or create hub files in ${wsLabel}/<hub>/hub.yaml.`);\n process.exit(1);\n }\n\n // Scan once and reuse — both existing- and new-hub flows share these arrays\n const existingHubs = scanWorkspaceHubs(workspaceDir);\n const newHubs = scanNewHubs(workspaceDir);\n\n // Existing hub flow first — prefer hubs that already have hub_id\n const existing = selectExistingHub(workspaceDir, existingHubs, hubSelector, wsLabel);\n if (existing) {\n assertHubMatchesLock(existing.hubId, path.basename(existing.hubFolder));\n await pushSingleHub(client, existing.hubId, existing.hubFolder, autoConfirm, organizationId);\n return;\n }\n\n // No existing hub matched — try the new-hub flow\n const newHub = selectNewHub(newHubs, hubSelector);\n if (!newHub) {\n if (existingHubs.length === 0 && newHubs.length === 0) {\n console.error(`No hub folders found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \\`hub: { name: ... }\\` and run \\`wayai push\\`.`);\n process.exit(1);\n }\n\n console.error(`Multiple hub folders found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);\n for (const h of existingHubs) {\n console.error(` ${path.basename(h.hubFolder)} (${h.hubId})`);\n }\n for (const h of newHubs) {\n console.error(` ${path.basename(h.hubFolder)} (new — \"${h.hubName}\")`);\n }\n process.exit(1);\n }\n\n assertNoLockBlocksHubCreation(newHub.hubName);\n\n const hubType = newHub.hubType || 'chat';\n console.log(`\\nNew hub detected: \"${newHub.hubName}\" (${hubType})`);\n\n if (!autoConfirm) {\n const ok = await confirm('Create this hub on the platform?');\n if (!ok) {\n console.log('Cancelled.');\n return;\n }\n }\n\n const hubYamlPath = resolveHubYamlPath(newHub.hubFolder);\n if (!hubYamlPath) {\n console.error(`hub.yaml not found in ${newHub.hubFolder}. Cannot proceed with hub creation.`);\n process.exit(1);\n }\n\n console.log('Creating hub...');\n const createResult = await client.createHub(organizationId, newHub.hubName, hubType);\n const createdHub = createResult.data[0];\n const hubId = createdHub.hub_id;\n\n if (!UUID_RE.test(hubId)) {\n console.error(`Invalid hub_id received from server: ${hubId}`);\n process.exit(1);\n }\n\n console.log(`Hub created: ${createdHub.hub_name} (${hubId})`);\n\n // Update hub.yaml with hub_id and hub_environment\n const content = fs.readFileSync(hubYamlPath, 'utf-8');\n const hasVersion = content.match(/^version:\\s/m);\n let updated: string;\n if (hasVersion) {\n updated = content.replace(\n /^(version:\\s.*\\n)/m,\n `$1hub_id: \"${hubId}\"\\nhub_environment: preview\\n`\n );\n } else {\n updated = `version: 1\\nhub_id: \"${hubId}\"\\nhub_environment: preview\\n${content}`;\n }\n fs.writeFileSync(hubYamlPath, updated, 'utf-8');\n\n // Auto-lock only after hub.yaml is persisted, so a write failure can't\n // leave a lock pointing at a hub with no local files.\n autoLockIfUnlocked(hubId);\n\n // Push the new hub (skip autoRenameAgentFiles — no remote agents exist)\n await pushSingleHub(client, hubId, newHub.hubFolder, autoConfirm, organizationId, { skipAgentRename: true });\n}\n","// wayai use <hub> — bind this worktree to a specific hub (UUID or folder name).\n\nimport * as path from 'node:path';\nimport { writeLock, readLock } from '../lib/hub-lock.js';\nimport { detectWorkspace, findGitRoot, findHubByFolderName, scanWorkspaceHubs } from '../lib/workspace.js';\nimport { resolveLayout, hubsDirLabel } from '../lib/layout.js';\nimport { UUID_RE } from '../lib/utils.js';\n\nexport async function useCommand(args: string[]): Promise<void> {\n const target = args[0];\n if (!target || target.startsWith('-')) {\n console.error('Usage: wayai use <hub_uuid|folder-name>');\n process.exit(1);\n }\n\n let hubId: string;\n\n if (UUID_RE.test(target)) {\n hubId = target;\n } else {\n // Resolve folder name → hub_id from the hubs dir.\n const workspace = detectWorkspace();\n const gitRoot = findGitRoot();\n const workspaceDir = workspace?.workspaceDir ?? (gitRoot ? resolveLayout(gitRoot).hubsDir : null);\n if (!workspaceDir) {\n console.error('Not inside a git repository, and no UUID provided.');\n process.exit(1);\n }\n const wsLabel = hubsDirLabel(gitRoot);\n\n const match = findHubByFolderName(workspaceDir, target);\n if (!match) {\n console.error(`No hub matching \"${target}\" found in ${wsLabel}/. Pass a UUID or a folder name from:`);\n for (const h of scanWorkspaceHubs(workspaceDir)) {\n console.error(` ${path.basename(h.hubFolder)} (${h.hubId})`);\n }\n process.exit(1);\n }\n hubId = match.hubId;\n }\n\n const previous = readLock();\n if (previous === hubId) {\n console.log(`Worktree already locked to ${hubId}.`);\n return;\n }\n\n try {\n writeLock(hubId);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n\n if (previous) {\n console.log(`Worktree rebound: ${previous} → ${hubId}`);\n } else {\n console.log(`Worktree locked to hub ${hubId}.`);\n }\n}\n","/**\n * wayai migrate — relocate a legacy repo to the `wayai-ws/{hubs,org}` layout.\n *\n * workspace/<hub>/ → wayai-ws/hubs/<hub>/\n * org/ → wayai-ws/org/\n *\n * Idempotent: a no-op when there's nothing legacy left to move. Uses `git mv`\n * (preserving history) for tracked dirs, falling back to a filesystem rename for\n * untracked / partially-tracked dirs or non-git repos. `.wayai.yaml` and the\n * init shim files (AGENTS.md, …) stay at the root and are untouched.\n */\n\nimport { execFileSync } from 'node:child_process';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { findGitRoot } from '../lib/workspace.js';\nimport { WAYAI_LAYOUT, isDirectory } from '../lib/layout.js';\n\n/** True when at least one tracked file lives at/under `p`. */\nfunction isTracked(gitRoot: string, p: string): boolean {\n try {\n execFileSync('git', ['ls-files', '--error-unmatch', '--', path.relative(gitRoot, p)], {\n cwd: gitRoot,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Move `from` → `to`, creating `to`'s parent. Prefers `git mv` for tracked\n * sources (history-preserving, staged); falls back to `fs.rename` when the\n * source is untracked or `git mv` errors (e.g. mixed tracked/untracked\n * contents). Returns which mechanism was used.\n */\nfunction moveDir(gitRoot: string, from: string, to: string): 'git' | 'fs' {\n fs.mkdirSync(path.dirname(to), { recursive: true });\n\n if (isTracked(gitRoot, from)) {\n try {\n execFileSync('git', ['mv', path.relative(gitRoot, from), path.relative(gitRoot, to)], {\n cwd: gitRoot,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n return 'git';\n } catch {\n // Fall through — e.g. the dir mixes tracked and untracked children.\n }\n }\n\n fs.renameSync(from, to);\n return 'fs';\n}\n\nexport async function migrateCommand(_args: string[]): Promise<void> {\n const gitRoot = findGitRoot();\n if (!gitRoot) {\n console.error('Not inside a git repository.');\n process.exit(1);\n }\n\n const rel = (p: string) => path.relative(gitRoot, p);\n\n const newWs = path.join(gitRoot, WAYAI_LAYOUT.wsDir);\n const legacyWs = path.join(gitRoot, WAYAI_LAYOUT.legacy.wsDir);\n const legacyOrg = path.join(gitRoot, WAYAI_LAYOUT.legacy.orgAtRoot);\n const newHubs = path.join(newWs, WAYAI_LAYOUT.hubsSubdir);\n const newOrg = path.join(newWs, WAYAI_LAYOUT.orgSubdir);\n\n const hasLegacyWs = isDirectory(legacyWs);\n const hasLegacyOrg = isDirectory(legacyOrg);\n\n if (!hasLegacyWs && !hasLegacyOrg) {\n console.log(`Already migrated — no legacy ${WAYAI_LAYOUT.legacy.wsDir}/ or ${WAYAI_LAYOUT.legacy.orgAtRoot}/ to move.`);\n return;\n }\n\n // Validate ALL targets before moving ANYTHING. Checking per-dir inline would\n // let the workspace move succeed and then abort on an org-target collision,\n // leaving a half-migrated repo that a re-run can't cleanly recover.\n if (hasLegacyWs && isDirectory(newHubs)) {\n console.error(\n `Cannot migrate: target ${rel(newHubs)}/ already exists alongside legacy ${WAYAI_LAYOUT.legacy.wsDir}/. ` +\n `Merge them manually, then re-run \\`wayai migrate\\`.`,\n );\n process.exit(1);\n }\n if (hasLegacyOrg && isDirectory(newOrg)) {\n console.error(\n `Cannot migrate: target ${rel(newOrg)}/ already exists alongside legacy ${WAYAI_LAYOUT.legacy.orgAtRoot}/. ` +\n `Merge them manually, then re-run \\`wayai migrate\\`.`,\n );\n process.exit(1);\n }\n\n const moved: string[] = [];\n let usedFsFallback = false;\n\n if (hasLegacyWs) {\n const how = moveDir(gitRoot, legacyWs, newHubs);\n usedFsFallback ||= how === 'fs';\n moved.push(`${WAYAI_LAYOUT.legacy.wsDir}/ → ${rel(newHubs)}/`);\n }\n\n if (hasLegacyOrg) {\n const how = moveDir(gitRoot, legacyOrg, newOrg);\n usedFsFallback ||= how === 'fs';\n moved.push(`${WAYAI_LAYOUT.legacy.orgAtRoot}/ → ${rel(newOrg)}/`);\n }\n\n console.log(`Migrated to the ${WAYAI_LAYOUT.wsDir}/ layout:`);\n for (const m of moved) console.log(` ${m}`);\n if (usedFsFallback) {\n console.log('\\n(Some dirs were moved on disk, not via git — they will show as untracked.)');\n }\n console.log('\\nNext steps:');\n console.log(' git add -A && git commit -m \"chore: migrate to wayai-ws layout\"');\n console.log(' If your CI runs `wayai push`, commit this migration in the same change that updates CI.');\n}\n","// wayai unlock — clear the per-worktree hub lock.\n\nimport { clearLock, readLock } from '../lib/hub-lock.js';\n\nexport async function unlockCommand(_args: string[]): Promise<void> {\n const previous = readLock();\n if (!previous) {\n console.log('No worktree lock to clear.');\n return;\n }\n\n // ENOENT between read and unlink is fine — lock is already gone.\n clearLock();\n console.log(`Worktree unlocked (was: ${previous}).`);\n}\n","/**\n * wayai send-message — send a test message to a preview hub and get the agent reply\n *\n * Chat hubs: automatically continues the active conversation (or creates one).\n * Task hubs: creates a new conversation by default. Use -c to continue an existing one.\n *\n * Usage:\n * wayai send-message \"Hello, I need help\" # send message\n * wayai send-message -c <conversation_id> \"Follow up\" # continue conversation\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { requireRepoConfig } from '../lib/repo-config.js';\nimport { resolveActiveHubId } from '../lib/workspace.js';\nimport { ApiClient } from '../lib/api-client.js';\n\nexport async function sendMessageCommand(args: string[]): Promise<void> {\n const hubId = resolveActiveHubId(args);\n const { config, accessToken } = await requireAuth();\n requireRepoConfig();\n\n // Parse args\n let conversationId: string | undefined;\n let message: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '-c' || arg === '--conversation') {\n conversationId = args[++i];\n } else if (!arg.startsWith('-')) {\n message = arg;\n }\n }\n\n if (!message) {\n console.error('Usage: wayai send-message [options] \"message text\"');\n console.error('');\n console.error('Options:');\n console.error(' -c, --conversation <id> Continue an existing conversation');\n console.error('');\n console.error('The hub type (chat/task) is determined automatically from the hub.');\n console.error('Chat hubs auto-continue the active conversation (or create one).');\n console.error('Task hubs create a new conversation unless -c is provided.');\n process.exit(1);\n }\n\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n const result = await client.sendMessage(hubId, message, {\n conversationId,\n });\n\n // Print result\n console.log(`Conversation: ${result.conversation_id}`);\n console.log(`Status: ${result.status}`);\n\n if (result.status_reason) {\n console.log(`Reason: ${result.status_reason}`);\n }\n\n if (result.agent_reply) {\n console.log('');\n console.log(result.agent_reply.message_text);\n } else if (result.status === 'skipped') {\n console.log('(Agent did not respond)');\n } else if (result.status === 'error') {\n console.log('(Agent processing failed — user message was stored)');\n }\n}\n","/**\n * Shared output helpers for `wayai conversations <id> observability` (hub-scoped)\n * and `wayai admin observability <hub> <conv>` (platform-admin). Output shape is\n * identical so an operator switching between the two commands sees the same\n * format — only the data source (and the API path) differs.\n */\n\nimport type { ApiClient } from '../lib/api-client.js';\nimport { ApiError } from '../lib/api-client.js';\nimport type { LLMObservabilityRecord, WayAIMetadataRecord } from '@wayai/core';\n\ninterface RenderOptions {\n messageId?: string;\n jsonOutput: boolean;\n}\n\nexport async function runConversationObservability(\n client: ApiClient,\n hubId: string,\n conversationId: string,\n opts: RenderOptions,\n): Promise<void> {\n // Live route resolves hub via ConversationDO, which is cleaned up 24h after\n // archival. R2 records outlive the DO, so on 404 we retry through the\n // archive route (CH+HubDO auth) before declaring the data missing.\n if (opts.messageId) {\n const result = await fallbackOn404(\n () => client.getMessageObservability(conversationId, opts.messageId!),\n () => client.getArchivedMessageObservability(hubId, conversationId, opts.messageId!),\n );\n renderRecord(result.data, opts.jsonOutput);\n return;\n }\n\n const result = await fallbackOn404(\n () => client.listConversationObservability(conversationId),\n () => client.listArchivedConversationObservability(hubId, conversationId),\n );\n renderList({\n hubId: result.data.hub_id,\n conversationId: result.data.conversation_id,\n entries: result.data.entries,\n truncated: result.data.truncated,\n jsonOutput: opts.jsonOutput,\n });\n}\n\nasync function fallbackOn404<T>(primary: () => Promise<T>, fallback: () => Promise<T>): Promise<T> {\n try {\n return await primary();\n } catch (err) {\n if (err instanceof ApiError && err.status === 404) {\n return await fallback();\n }\n throw err;\n }\n}\n\nexport async function runDebugObservability(\n client: ApiClient,\n hubId: string,\n conversationId: string,\n opts: RenderOptions,\n): Promise<void> {\n const result = await client.debugReadObservability(hubId, conversationId, {\n messageId: opts.messageId,\n });\n\n if (result.data.kind === 'single') {\n renderRecord(result.data.record, opts.jsonOutput);\n return;\n }\n\n if (opts.messageId) {\n // Defensive — backend returns 404 in this case, but guard against contract drift.\n throw new ApiError('GET', '/observability', 404, 'Observability record missing');\n }\n\n renderList({\n hubId: result.data.hub_id,\n conversationId: result.data.conversation_id,\n entries: result.data.entries,\n truncated: result.data.truncated,\n jsonOutput: opts.jsonOutput,\n });\n}\n\nfunction renderRecord(data: LLMObservabilityRecord, jsonOutput: boolean): void {\n if (jsonOutput) {\n console.log(JSON.stringify(data, null, 2));\n return;\n }\n\n // Default mode prints a compact summary so the terminal isn't flooded with\n // multi-KB system prompts. --json gets the full record.\n const obs = data.observability;\n const meta = data.metadata;\n\n const provider = obs['gen_ai.system'] ?? '-';\n const requestModel = obs['gen_ai.request.model'] ?? '-';\n const responseModel = obs['gen_ai.response.model'];\n const inputTokens = obs['gen_ai.usage.input_tokens'] ?? 0;\n const outputTokens = obs['gen_ai.usage.output_tokens'] ?? 0;\n const cacheRead = obs['gen_ai.usage.cache_read_input_tokens'];\n const cacheWrite = obs['gen_ai.usage.cache_creation_input_tokens'];\n\n console.log(`message_id: ${meta.message_id ?? '-'}`);\n console.log(`timestamp: ${meta.timestamp ?? '-'}`);\n console.log(`agent: ${meta.agent_id ?? '-'}${meta.agent_role ? ` (${meta.agent_role})` : ''}`);\n console.log(`provider: ${provider}`);\n console.log(`model: ${requestModel}${responseModel && responseModel !== requestModel ? ` (responded as ${responseModel})` : ''}`);\n console.log(`tokens: in=${inputTokens} out=${outputTokens}${cacheRead != null ? ` cache_read=${cacheRead}` : ''}${cacheWrite != null ? ` cache_write=${cacheWrite}` : ''}`);\n console.log(`latency_ms: ${meta.latency_ms ?? '-'}`);\n if (meta.tool_iterations != null) console.log(`tool_iters: ${meta.tool_iterations}`);\n if (meta.tool_calls_total != null) console.log(`tool_calls: ${meta.tool_calls_total}`);\n if (meta.system_reinvoke) console.log('reinvoke: yes');\n if (meta.error) console.log(`error: ${meta.error}`);\n\n console.log('');\n console.log('Pass --json for full prompt/completion/tool-call payloads.');\n}\n\ninterface RenderListArgs {\n hubId: string;\n conversationId: string;\n entries: WayAIMetadataRecord[];\n truncated: boolean;\n jsonOutput: boolean;\n}\n\nfunction renderList(args: RenderListArgs): void {\n if (args.jsonOutput) {\n console.log(JSON.stringify({\n hub_id: args.hubId,\n conversation_id: args.conversationId,\n entries: args.entries,\n truncated: args.truncated,\n }, null, 2));\n return;\n }\n\n console.log(`hub_id: ${args.hubId}`);\n console.log(`conversation_id:${args.conversationId}`);\n console.log(`messages: ${args.entries.length}${args.truncated ? ' (truncated)' : ''}`);\n\n if (args.entries.length === 0) {\n console.log('');\n console.log('(no observability records — only assistant LLM turns produce them)');\n return;\n }\n\n console.log('');\n console.log('timestamp | message_id | agent_role | latency_ms | tool_calls | error');\n console.log('-------------------------|---------------------------------------|-------------------|------------|------------|------');\n for (const e of args.entries) {\n const ts = (e.timestamp ?? '-').padEnd(24);\n const mid = (e.message_id ?? '-').padEnd(36);\n const role = (e.agent_role ?? '-').slice(0, 17).padEnd(17);\n const latency = String(e.latency_ms ?? '-').padStart(10);\n const toolCalls = String(e.tool_calls_total ?? '-').padStart(10);\n const err = e.error ? 'yes' : '';\n console.log(`${ts} | ${mid} | ${role} | ${latency} | ${toolCalls} | ${err}`);\n }\n console.log('');\n console.log('Drill in: --message-id <id> (for full prompt/completion/tool-calls; add --json for raw)');\n}\n","/**\n * wayai conversations — list conversations or show conversation detail\n *\n * Usage:\n * wayai conversations # list conversations\n * wayai conversations <conversation_id> # show detail + messages\n * wayai conversations <conversation_id> observability # list per-message LLM traces\n * wayai conversations <conversation_id> observability --message-id <id>\n * wayai conversations --status ended # filter by status\n * wayai conversations --period 7d # analytics-powered list\n * wayai conversations --from 2026-01-01 --to 2026-01-31\n * wayai conversations --json # raw JSON output\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { requireRepoConfig } from '../lib/repo-config.js';\nimport { resolveActiveHubId } from '../lib/workspace.js';\nimport { ApiClient, ApiError } from '../lib/api-client.js';\nimport { parsePeriod, parseDateArg } from '../lib/utils.js';\nimport { runConversationObservability } from './observability.js';\n\nexport async function conversationsCommand(args: string[]): Promise<void> {\n const hubId = resolveActiveHubId(args);\n const { config, accessToken } = await requireAuth();\n requireRepoConfig();\n\n // Parse args\n let status: 'agent' | 'team' | 'ended' | undefined;\n let conversationId: string | undefined;\n let subcommand: string | undefined;\n let messageId: string | undefined;\n let limit: number | undefined;\n let offset: number | undefined;\n let period: string | undefined;\n let from: string | undefined;\n let to: string | undefined;\n let jsonOutput = false;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--status') {\n const val = args[++i];\n if (val === 'agent' || val === 'team' || val === 'ended') {\n status = val;\n } else {\n console.error(`Invalid status: ${val}. Must be 'agent', 'team', or 'ended'.`);\n process.exit(1);\n }\n } else if (arg === '--limit') {\n limit = parseInt(args[++i], 10);\n } else if (arg === '--offset') {\n offset = parseInt(args[++i], 10);\n } else if (arg === '--message-id') {\n if (i + 1 >= args.length) { console.error('--message-id requires a value'); process.exit(1); }\n messageId = args[++i];\n } else if (arg === '--period') {\n if (i + 1 >= args.length) { console.error('--period requires a value'); process.exit(1); }\n period = args[++i];\n } else if (arg === '--from') {\n if (i + 1 >= args.length) { console.error('--from requires a value'); process.exit(1); }\n from = args[++i];\n } else if (arg === '--to') {\n if (i + 1 >= args.length) { console.error('--to requires a value'); process.exit(1); }\n to = args[++i];\n } else if (arg === '--json') {\n jsonOutput = true;\n } else if (!arg.startsWith('-')) {\n // Position 1: conversation_id. Position 2: subcommand (e.g. `observability`).\n // If the user puts the subcommand first (\"wayai conversations observability\"),\n // promote it to subcommand directly — that yields a clearer \"missing\n // conversation_id\" error instead of pretending `observability` is a UUID.\n if (conversationId === undefined && arg === 'observability') {\n subcommand = arg;\n } else if (conversationId === undefined) {\n conversationId = arg;\n } else if (subcommand === undefined) {\n subcommand = arg;\n } else {\n console.error(`Unexpected positional argument: ${arg}`);\n process.exit(1);\n }\n }\n }\n\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n const hasAnalyticsFlags = !!(period || from || to);\n\n if (subcommand === 'observability') {\n if (!conversationId) {\n console.error('Usage: wayai conversations <conversation_id> observability [--message-id X] [--json]');\n process.exit(1);\n }\n try {\n await runConversationObservability(client, hubId, conversationId, { messageId, jsonOutput });\n } catch (err) {\n // Raw ApiError text isn't user-friendly at the CLI surface.\n if (err instanceof ApiError && err.status === 404) {\n console.error('Observability data not found. Either the conversation has no LLM turns yet, or R2 entries were purged.');\n process.exit(1);\n }\n throw err;\n }\n return;\n }\n\n if (subcommand) {\n console.error(`Unknown conversations subcommand: ${subcommand}`);\n process.exit(1);\n }\n\n // `--message-id` is only meaningful with the `observability` subcommand.\n // Reject it elsewhere so a user typo (e.g. `wayai conversations <id> --message-id X`,\n // forgetting the subcommand) doesn't silently drop the flag.\n if (messageId !== undefined) {\n console.error('--message-id is only valid with the `observability` subcommand. Did you mean: wayai conversations <id> observability --message-id ' + messageId + '?');\n process.exit(1);\n }\n\n if (conversationId) {\n const [result, schedules] = await Promise.all([\n client.getConversation(hubId, conversationId, { limit, offset }),\n client.getPendingSchedules(hubId, conversationId).catch(() => ({ entries: [], total: 0 })),\n ]);\n\n if (jsonOutput) {\n console.log(JSON.stringify({ ...result, pending_schedules: schedules }, null, 2));\n return;\n }\n\n console.log(`Conversation: ${result.conversation.conversation_id}`);\n console.log(`Status: ${result.conversation.conversation_status}`);\n if (result.conversation.kanban_status) {\n console.log(`Kanban: ${result.conversation.kanban_status}`);\n }\n const user = result.conversation.user_name || result.conversation.user_email;\n if (user) {\n console.log(`User: ${user}`);\n }\n console.log(`Messages: ${result.total_messages}`);\n console.log('');\n\n for (const msg of result.messages) {\n const time = new Date(msg.created_at).toLocaleString();\n const meta = (msg.metadata ?? {}) as { tool_name?: unknown; arguments?: unknown; result?: unknown; is_error?: unknown };\n const toolName = typeof meta.tool_name === 'string' ? meta.tool_name : undefined;\n const isToolCall = msg.sender_type === 'agent' && msg.receiver_type === 'tool' && toolName;\n const isToolResult = msg.sender_type === 'tool' && msg.receiver_type === 'agent' && toolName;\n\n if (isToolCall) {\n console.log(`[tool_call: ${toolName}] (${time})`);\n if (meta.arguments !== undefined) {\n console.log(JSON.stringify(meta.arguments, null, 2));\n }\n } else if (isToolResult) {\n const label = meta.is_error === true ? 'tool_error' : 'tool_result';\n console.log(`[${label}: ${toolName}] (${time})`);\n if (meta.result !== undefined) {\n console.log(typeof meta.result === 'string' ? meta.result : JSON.stringify(meta.result, null, 2));\n } else if (msg.message_text) {\n console.log(msg.message_text);\n }\n } else if (msg.sender_type === 'system') {\n console.log(`[system → ${msg.receiver_type ?? '-'}] (${time})`);\n console.log(msg.message_text || '(no text)');\n } else {\n const from = msg.sender_description || msg.sender_type;\n const to = msg.receiver_description || msg.receiver_type;\n const routing = to ? `${from} → ${to}` : from;\n console.log(`[${routing}] (${time})`);\n console.log(msg.message_text || '(no text)');\n }\n console.log('');\n }\n\n // Show pending scheduled actions\n if (schedules.entries.length > 0) {\n console.log(`Pending Scheduled Actions (${schedules.entries.length}):`);\n for (const entry of schedules.entries) {\n const type = entry.schedule_type;\n const time = new Date(entry.run_at).toLocaleString();\n const order = entry.followup_order ? `#${entry.followup_order}` : '';\n const preview = entry.message_text.length > 50\n ? entry.message_text.slice(0, 47) + '...'\n : entry.message_text;\n console.log(` ${type} ${order} — ${time}`);\n console.log(` \"${preview}\"`);\n }\n console.log('');\n }\n } else if (hasAnalyticsFlags) {\n // Analytics-powered list\n if (status) {\n console.error('The --status flag is not supported with --period/--from/--to. Without these flags, --status works as before.');\n process.exit(1);\n }\n\n if ((from && !to) || (!from && to)) {\n console.error('--from and --to must both be provided together.');\n process.exit(1);\n }\n\n let start: string;\n let end: string;\n\n try {\n if (from && to) {\n start = parseDateArg(from, 'from');\n end = parseDateArg(to, 'to');\n if (new Date(start).getTime() >= new Date(end).getTime()) {\n console.error('--from must be before --to.');\n process.exit(1);\n }\n } else {\n const parsed = parsePeriod(period || '7d');\n start = parsed.start;\n end = parsed.end;\n }\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n\n const result = await client.getAnalyticsConversations({\n hub_id: hubId,\n time_interval: { start, end },\n limit: limit ?? 50,\n offset: offset ?? 0,\n });\n\n if (jsonOutput) {\n // Emit the full payload (the `cold` flag is part of it) so machine\n // consumers can inspect it, then exit non-zero on cold so batch/automation\n // pipelines treat a degraded listing as retryable rather than as a\n // complete \"no conversations\" result (gh #2452).\n console.log(JSON.stringify(result, null, 2));\n if (result.cold) process.exit(1);\n return;\n }\n\n // A cold result is a transient ClickHouse cold-start, NOT an empty hub.\n // Surface it distinctly — silently printing \"No conversations found.\" here\n // is what made dozens of real ended conversations look undiscoverable in\n // gh #2452.\n if (result.cold) {\n console.error(\n 'ClickHouse is warming up (cold start); the ended-conversation list is temporarily unavailable. Retry in a few seconds.',\n );\n process.exit(1);\n }\n\n if (result.conversations.length === 0) {\n console.log('No conversations found.');\n return;\n }\n\n console.log(`Conversations (${result.conversations.length} of ${result.total}):\\n`);\n\n for (const conv of result.conversations) {\n const participant = conv.participant_name || conv.participant_phone || 'unknown';\n const updated = conv.updated_at ? new Date(conv.updated_at).toLocaleString() : '-';\n const msgs = conv.message_count != null ? `${conv.message_count} msgs` : '';\n console.log(` ${conv.conversation_id} ${participant.padEnd(20)} ${msgs.padEnd(10)} ${updated}`);\n }\n } else {\n // Original list path (backward compat)\n const result = await client.getConversations(hubId, { status, limit, offset });\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (result.conversations.length === 0) {\n console.log('No conversations found.');\n return;\n }\n\n console.log(`Conversations (${result.conversations.length} of ${result.total}):\\n`);\n\n for (const conv of result.conversations) {\n const user = conv.user_name || conv.user_email || 'unknown';\n const updated = conv.updated_at ? new Date(conv.updated_at).toLocaleString() : '-';\n console.log(` ${conv.conversation_id} ${conv.conversation_status.padEnd(7)} ${user.padEnd(20)} ${updated}`);\n }\n }\n}\n","/**\n * wayai delete-history — delete conversation history on a hub\n *\n * Destructive and irreversible — use to reset test data during development.\n * Preview hubs allow deleting any user (defaults to the caller). Production\n * hubs only allow deleting your own end-user profile; pass --user-id with\n * your own platform user_id in that case.\n *\n * Usage:\n * wayai delete-history # caller's full history on this hub\n * wayai delete-history -y # skip confirmation\n * wayai delete-history --user-id <id> # target a specific user\n * wayai delete-history --conversation-id <id> # delete just one conversation\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { requireRepoConfig } from '../lib/repo-config.js';\nimport { resolveActiveHubId } from '../lib/workspace.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { confirm } from '../lib/utils.js';\n\nfunction parseStringFlag(args: string[], flag: string): string | undefined {\n const idx = args.findIndex((a) => a === flag);\n if (idx !== -1) {\n const next = args[idx + 1];\n if (next && !next.startsWith('-')) return next;\n }\n const prefix = `${flag}=`;\n const inline = args.find((a) => a.startsWith(prefix));\n if (inline) return inline.slice(prefix.length);\n return undefined;\n}\n\nexport async function deleteHistoryCommand(args: string[]): Promise<void> {\n const hubId = resolveActiveHubId(args);\n const { config, accessToken } = await requireAuth();\n requireRepoConfig();\n\n const skipConfirm = args.includes('-y') || args.includes('--yes');\n const userIdFlag = parseStringFlag(args, '--user-id');\n const conversationId = parseStringFlag(args, '--conversation-id');\n\n // Resolve target user_id before prompting — if me() fails (401/5xx), surface\n // it before the user commits to a destructive confirmation.\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n const userId = userIdFlag ?? (await client.me()).user_id;\n\n if (!skipConfirm) {\n const confirmed = await confirm(\n 'This will permanently delete conversation history on this hub. Continue?'\n );\n if (!confirmed) {\n console.log('Aborted.');\n return;\n }\n }\n\n const result = await (conversationId\n ? client.deleteHistory(hubId, { userId, mode: 'current', conversationId })\n : client.deleteHistory(hubId, { userId, mode: 'all' }));\n\n console.log(`Deleted ${result.deleted_count} conversation(s).`);\n}\n","/**\n * wayai sync-skills [--connection-id <uuid>] — sync skills to Anthropic/OpenAI provider connections\n *\n * Triggers provider-side skill sync for the hub specified in .wayai.yaml.\n * Useful after `wayai push` when the hub uses native skill integration (Anthropic or OpenAI).\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { requireRepoConfig } from '../lib/repo-config.js';\nimport { resolveActiveHubId } from '../lib/workspace.js';\nimport type { SyncSkillsResponse, SyncSkillsResultItem } from '../lib/types.js';\n\nexport function parseArgs(args: string[]): { connectionId: string | undefined } {\n let connectionId: string | undefined;\n const idx = args.indexOf('--connection-id');\n if (idx !== -1 && args[idx + 1]) {\n connectionId = args[idx + 1];\n }\n return { connectionId };\n}\n\nfunction printSyncResults(response: SyncSkillsResponse): void {\n console.log(response.message);\n\n for (const item of response.results) {\n const parts: string[] = [`${item.connection_name}:`];\n if (item.uploaded > 0) parts.push(`${item.uploaded} uploaded`);\n if (item.failed > 0) parts.push(`${item.failed} failed`);\n if (item.uploaded === 0 && item.failed === 0) parts.push('no changes');\n console.log(` ${parts.join(' ')}`);\n\n for (const err of item.errors) {\n console.log(` \\x1b[33m! ${err}\\x1b[0m`);\n }\n }\n}\n\nexport async function syncSkillsCommand(args: string[]): Promise<void> {\n const hubId = resolveActiveHubId(args);\n const { connectionId } = parseArgs(args);\n requireRepoConfig();\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n console.log('Syncing skills...');\n const response = await client.syncSkills(hubId, connectionId);\n printSyncResults(response);\n\n const hasFailed = response.results.some((r: SyncSkillsResultItem) => r.failed > 0);\n if (hasFailed) {\n process.exit(1);\n }\n}\n","/**\n * wayai sync-mcp --connection <name> [--hub <id|name>] — re-discover an MCP\n * connection's tool/resource catalog.\n *\n * `wayai push` only discovers MCP tools that are *new* to the hub catalog; it\n * never refreshes the cached input-schema of tools already catalogued. When an\n * external MCP server changes a tool's schema (e.g. adds typed params), the\n * agent keeps calling the stale schema until the catalog is re-synced. This is\n * the explicit, connection-level refresh for that case (gh #2548).\n *\n * Preview-only — production hubs are read-only (changes flow preview → sync).\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { requireRepoConfig } from '../lib/repo-config.js';\nimport { resolveActiveHubId } from '../lib/workspace.js';\nimport { printWarnings } from './push.js';\n\nexport function parseArgs(args: string[]): { connection: string | undefined } {\n let connection: string | undefined;\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--connection' && args[i + 1]) {\n connection = args[++i];\n }\n }\n return { connection };\n}\n\nexport async function syncMcpCommand(args: string[]): Promise<void> {\n // resolveActiveHubId parses and removes `--hub <value>` from args.\n const hubId = resolveActiveHubId(args);\n const { connection } = parseArgs(args);\n\n if (!connection) {\n console.error('Usage: wayai sync-mcp --connection <name> [--hub <uuid|folder-name>]');\n console.error('');\n console.error('Re-discovers the MCP connection\\'s tools/resources and refreshes their');\n console.error('cached input schemas. `--connection` accepts the connection display name');\n console.error('(as in connections[].name) or its UUID.');\n process.exit(1);\n }\n\n const { organization_id: organizationId } = requireRepoConfig();\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n console.log(`Syncing MCP tools for connection \"${connection}\"...`);\n const result = await client.syncMcp(hubId, connection, organizationId);\n\n console.log(\n result.message ??\n `Synced ${result.tools_count ?? 0} tool(s) and ${result.resources_count ?? 0} resource(s) from MCP server`,\n );\n\n if (result.warnings && result.warnings.length > 0) {\n printWarnings(result.warnings);\n }\n}\n","// Shared row + schema printers for `wayai analytics sql` and `wayai evals sql`.\n\nexport function printQueryRows(rows: Array<Record<string, unknown>>): void {\n if (rows.length === 0) {\n console.log('(no rows)');\n return;\n }\n const columns = Object.keys(rows[0]);\n const widths = columns.map((c) => Math.max(c.length, ...rows.map((r) => formatCell(r[c]).length)));\n\n const header = columns.map((c, i) => c.padEnd(widths[i])).join(' ');\n console.log(header);\n console.log(columns.map((_, i) => '-'.repeat(widths[i])).join(' '));\n for (const row of rows) {\n console.log(columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(' '));\n }\n}\n\ninterface SqlSchemaPath {\n path: string;\n type: string;\n origin: string;\n category?: string;\n description?: string;\n}\n\nexport function printSqlSchema(\n data: {\n table: string;\n top_level: Array<{ column: string; type: string }>;\n paths: SqlSchemaPath[];\n },\n pathsHeader: string,\n): void {\n console.log(`Table: ${data.table}\\n`);\n console.log('Top-level columns:');\n for (const c of data.top_level) {\n console.log(` ${c.column.padEnd(24)} ${c.type}`);\n }\n console.log(`\\n${pathsHeader}`);\n const byCat = new Map<string, SqlSchemaPath[]>();\n for (const p of data.paths) {\n const key = p.category || p.origin;\n const arr = byCat.get(key) || [];\n arr.push(p);\n byCat.set(key, arr);\n }\n const cats = [...byCat.keys()].sort();\n for (const cat of cats) {\n console.log(`\\n [${cat}]`);\n for (const p of byCat.get(cat)!) {\n const desc = p.description ? ` — ${p.description}` : '';\n console.log(` ${p.path.padEnd(48)} ${p.type}${desc}`);\n }\n }\n}\n\nfunction formatCell(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'number') return Number.isInteger(value) ? String(value) : value.toFixed(4);\n if (typeof value === 'object') return JSON.stringify(value);\n return String(value);\n}\n","/**\n * wayai evals — list evaluation scenarios for the current hub, or query eval\n * results stored in ClickHouse.\n *\n * Usage:\n * wayai evals # list all evals\n * wayai evals --enabled # show only enabled evals\n * wayai evals --disabled # show only disabled evals\n *\n * wayai evals sql \"SELECT count() FROM conversation\"\n * wayai evals sql \"SELECT eval_id, count() FROM conversation GROUP BY 1\" --json\n * wayai evals sql --schema # column + eval-score-path catalog\n * wayai evals sql \"...\" --limit 500\n *\n * `sql` is a thin wrapper over POST /api/evals/sql — server enforces hub_id +\n * is_eval=true scoping (CTE shadow), single-SELECT only, function/keyword\n * denylist, 10k row cap. `--schema` calls GET /api/evals/sql/schema and\n * returns top-level columns + system variable paths + dynamically discovered\n * `data.eval_scores.*` dimensions.\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { requireRepoConfig } from '../lib/repo-config.js';\nimport { resolveActiveHubId } from '../lib/workspace.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { printQueryRows, printSqlSchema } from '../lib/sql-output.js';\nimport { parsePositiveIntFlag } from '../lib/utils.js';\n\nexport async function evalsCommand(args: string[]): Promise<void> {\n if (args[0] === 'sql') {\n return evalsSqlSubcommand(args.slice(1));\n }\n return evalsListCommand(args);\n}\n\n// ---------------------------------------------------------------------------\n// Default list command (GET /api/evals)\n// ---------------------------------------------------------------------------\n\nasync function evalsListCommand(args: string[]): Promise<void> {\n const hubId = resolveActiveHubId(args);\n const { config, accessToken } = await requireAuth();\n requireRepoConfig();\n\n let enabledFilter: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--enabled') {\n enabledFilter = 'true';\n } else if (arg === '--disabled') {\n enabledFilter = 'false';\n }\n }\n\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n const result = await client.getEvals(hubId, { enabled: enabledFilter });\n\n if (result.data.evals.length === 0) {\n console.log('No evals found.');\n return;\n }\n\n console.log(`Evals (${result.data.evals.length}):\\n`);\n\n for (const eval_ of result.data.evals) {\n const status = eval_.enabled ? 'enabled' : 'disabled';\n const runs = `${eval_.number_of_runs} run${eval_.number_of_runs === 1 ? '' : 's'}`;\n const agentName = eval_.agent?.agent_name || 'unknown';\n console.log(` ${eval_.eval_name.padEnd(20)} ${eval_.eval_id.slice(0, 8)} ${status.padEnd(9)} ${runs.padEnd(7)} Agent: ${agentName}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// `wayai evals sql` — POST /api/evals/sql (read-only, server-scoped to is_eval = true)\n// ---------------------------------------------------------------------------\n\nasync function evalsSqlSubcommand(args: string[]): Promise<void> {\n const hubId = resolveActiveHubId(args);\n const { config, accessToken } = await requireAuth();\n requireRepoConfig();\n\n let sql: string | undefined;\n let limit: number | undefined;\n let jsonOutput = false;\n let schemaOnly = false;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--limit') {\n limit = parsePositiveIntFlag('--limit', args[++i]);\n } else if (arg === '--json') {\n jsonOutput = true;\n } else if (arg === '--schema') {\n schemaOnly = true;\n } else if (!arg.startsWith('--') && sql === undefined) {\n sql = arg;\n } else {\n console.error(`Unknown flag for \\`evals sql\\`: ${arg}`);\n process.exit(1);\n }\n }\n\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n if (schemaOnly) {\n const schema = await client.getEvalsSqlSchema(hubId);\n if (jsonOutput) {\n console.log(JSON.stringify(schema.data, null, 2));\n return;\n }\n printSqlSchema(schema.data, 'Variable paths (data.system.* + data.eval_scores.*):');\n return;\n }\n\n if (!sql) {\n console.error('Provide a SQL string. Example: wayai evals sql \"SELECT count() FROM conversation\"');\n console.error('Or run: wayai evals sql --schema to list available columns and paths.');\n process.exit(1);\n }\n\n const result = await client.runEvalsSql({\n hub_id: hubId,\n sql,\n ...(limit !== undefined && { limit }),\n });\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n printQueryRows(result.data);\n}\n","/**\n * Shared formatting helpers for eval results display.\n */\n\ninterface ResultRow {\n eval_id: string;\n total_runs: number;\n successful_runs: number;\n failed_runs: number;\n // Non-terminal run counts. Present on the session-details payload; optional so\n // older/partial payloads still render (treated as zero in-progress).\n pending_runs?: number;\n running_runs?: number;\n avg_execution_time_ms?: number;\n aggregated_scores?: Record<string, { avg: number; min: number; max: number }>;\n eval?: { eval_id: string; eval_name: string } | null;\n}\n\n/**\n * Print a results table and overall summary.\n *\n * @param mode - 'compact': scores show avg only (used by run-eval summary)\n * 'detailed': scores show avg/min/max (used by eval-results)\n */\nexport function printResultsTable(\n results: ResultRow[],\n mode: 'compact' | 'detailed'\n): void {\n let totalPassed = 0;\n let totalTerminal = 0;\n let totalInProgress = 0;\n\n for (const r of results) {\n const evalName = r.eval?.eval_name || r.eval_id.slice(0, 8);\n // Denominator = completed runs (`successful + failed`, = the backend's\n // `completed` count). Counting still-running runs against it understates the\n // pass rate mid-run (gh #2604); in-progress runs are surfaced separately.\n // (`completed` includes unevaluated/errored rows, per `failed_runs`;\n // `success_rate` uses the narrower evaluated-only denominator.)\n const terminalRuns = r.successful_runs + r.failed_runs;\n const inProgress = (r.running_runs ?? 0) + (r.pending_runs ?? 0);\n const passed = inProgress > 0\n ? `${r.successful_runs}/${terminalRuns} passed (+${inProgress} in progress)`\n : `${r.successful_runs}/${terminalRuns} passed`;\n const avgTime = r.avg_execution_time_ms != null ? `avg ${(r.avg_execution_time_ms / 1000).toFixed(1)}s` : '';\n\n let scoresStr = '';\n if (r.aggregated_scores) {\n const parts = Object.entries(r.aggregated_scores).map(([key, val]) =>\n mode === 'compact'\n ? `${key}: ${Math.round(val.avg * 100)}%`\n : `${key}: avg ${Math.round(val.avg * 100)}%, min ${Math.round(val.min * 100)}%, max ${Math.round(val.max * 100)}%`\n );\n if (parts.length > 0) scoresStr = ' ' + parts.join(' ');\n }\n\n console.log(` ${evalName.padEnd(20)} ${passed.padEnd(14)} ${avgTime}${scoresStr}`);\n\n totalPassed += r.successful_runs;\n totalTerminal += terminalRuns;\n totalInProgress += inProgress;\n }\n\n const pct = totalTerminal > 0 ? ((totalPassed / totalTerminal) * 100).toFixed(1) : '0.0';\n const inProgressNote = totalInProgress > 0 ? ` — ${totalInProgress} in progress` : '';\n console.log(`\\nOverall: ${totalPassed}/${totalTerminal} passed (${pct}%)${inProgressNote}`);\n}\n","/**\n * wayai run-eval — run a scenario set's enabled evals and show results\n *\n * Creates a session, runs it, polls until completion, prints summary. A session\n * targets exactly one scenario set. With no flag the run endpoint resolves the\n * hub's sole enabled set; on multi-set hubs, pick one with `--set` / `--eval`.\n *\n * Usage:\n * wayai run-eval # run the hub's enabled set and wait for results\n * wayai run-eval --set <name> # run the named scenario set\n * wayai run-eval --eval <name> # run the set the named eval belongs to\n * wayai run-eval --no-wait # start session and exit (prints session ID)\n * wayai run-eval --timeout 120 # wait max 2 minutes\n */\n\nimport { requireAuth, getAccessToken } from '../lib/auth.js';\nimport { requireRepoConfig } from '../lib/repo-config.js';\nimport { resolveActiveHubId } from '../lib/workspace.js';\nimport { ApiClient, ApiError } from '../lib/api-client.js';\nimport { printResultsTable } from '../lib/eval-format.js';\n\nconst TERMINAL_STATUSES = new Set(['completed', 'failed', 'cancelled', 'awaiting_review']);\nconst POLL_INTERVAL_MS = 3000;\nconst DEFAULT_TIMEOUT_S = 600;\n// How many consecutive poll failures to ride out before giving up on the live\n// view. At POLL_INTERVAL_MS this is ~15s of tolerance — enough to absorb a token\n// rotation, KV propagation lag, or a network blip, while still failing fast on a\n// genuinely broken connection rather than spinning silently until the deadline.\nconst MAX_CONSECUTIVE_POLL_ERRORS = 5;\n\nexport async function runEvalCommand(args: string[]): Promise<void> {\n const hubId = resolveActiveHubId(args);\n const { config, accessToken } = await requireAuth();\n requireRepoConfig();\n\n // Parse args\n let noWait = false;\n let timeoutSeconds = DEFAULT_TIMEOUT_S;\n let setName: string | undefined;\n let evalName: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--no-wait') {\n noWait = true;\n } else if (arg === '--timeout') {\n timeoutSeconds = parseInt(args[++i], 10);\n if (isNaN(timeoutSeconds) || timeoutSeconds <= 0) {\n console.error('--timeout must be a positive number (seconds)');\n process.exit(1);\n }\n } else if (arg === '--set') {\n setName = args[++i];\n if (!setName) {\n console.error('--set requires a scenario set name');\n process.exit(1);\n }\n } else if (arg === '--eval') {\n evalName = args[++i];\n if (!evalName) {\n console.error('--eval requires an eval name');\n process.exit(1);\n }\n }\n }\n\n if (setName && evalName) {\n console.error('Specify only one of --set or --eval.');\n process.exit(1);\n }\n\n // The poll below can run for minutes — longer than a short-lived OAuth JWT.\n // Re-resolving the token on a 401 (refreshing if needed; way_ tokens pass\n // through unchanged) lets the client self-heal a mid-run expiry rather than\n // aborting the whole command (gh #2605).\n const client = new ApiClient({\n apiUrl: config.api_url,\n accessToken,\n onUnauthorized: () => getAccessToken(config),\n });\n\n // 1. Verify hub has enabled evals\n const evalsResult = await client.getEvals(hubId, { enabled: 'true' });\n const enabledCount = evalsResult.data.evals.length;\n\n if (enabledCount === 0) {\n console.error('No enabled evals found for this hub. Enable evals in the platform UI first.');\n process.exit(1);\n }\n\n console.log(`Found ${enabledCount} enabled eval${enabledCount === 1 ? '' : 's'}`);\n\n // 2. Resolve the scenario set to bind. A session targets exactly one set; on\n // multi-set hubs `--set`/`--eval` disambiguates. Without a flag we leave it\n // unbound and the run endpoint resolves the hub's sole enabled set.\n let scenarioSetId: string | undefined;\n if (setName) {\n const setsResult = await client.listScenarioSets(hubId);\n const match = setsResult.data.scenario_sets.find((s) => s.set_name === setName);\n if (!match) {\n const available = setsResult.data.scenario_sets.map((s) => s.set_name).join(', ') || '(none)';\n console.error(`Scenario set \"${setName}\" not found. Available: ${available}`);\n process.exit(1);\n }\n scenarioSetId = match.scenario_set_id;\n } else if (evalName) {\n const match = evalsResult.data.evals.find((e) => e.eval_name === evalName);\n if (!match) {\n console.error(`No enabled eval named \"${evalName}\". Run \\`wayai evals\\` to list (it may be disabled).`);\n process.exit(1);\n }\n scenarioSetId = match.scenario_set_id;\n }\n\n // 3. Create session\n const now = new Date();\n const sessionName = `CLI run ${now.toISOString().slice(0, 16).replace('T', ' ')}`;\n const createResult = await client.createEvalSession(hubId, sessionName, scenarioSetId);\n const sessionId = createResult.data.session.eval_session_id;\n\n console.log(`Created session: ${sessionName} (${sessionId})`);\n\n // 4. Run session — surface backend resolution errors (e.g. a multi-set hub\n // with no `--set`) instead of leaking a raw ApiError stack.\n try {\n await client.runEvalSession(hubId, sessionId);\n } catch (err) {\n console.error(`\\nFailed to start session: ${extractApiMessage(err)}`);\n process.exit(1);\n }\n console.log('Session started');\n\n // 5. If --no-wait, print session ID and exit\n if (noWait) {\n console.log(`\\nSession ID: ${sessionId}`);\n console.log('Use `wayai eval-results --session ' + sessionId + '` to check results.');\n return;\n }\n\n // 6. Poll until terminal status\n const deadline = Date.now() + timeoutSeconds * 1000;\n let consecutivePollErrors = 0;\n\n while (Date.now() < deadline) {\n await sleep(POLL_INTERVAL_MS);\n\n // A single poll throwing must not tear down the live view — the session\n // keeps running server-side regardless. Ride out transient failures (token\n // rotation that survives the client refresh, KV propagation, network blip);\n // only give up once they persist past MAX_CONSECUTIVE_POLL_ERRORS (gh #2605).\n let details;\n try {\n details = await client.getEvalSessionDetails(hubId, sessionId);\n consecutivePollErrors = 0;\n } catch (err) {\n if (++consecutivePollErrors >= MAX_CONSECUTIVE_POLL_ERRORS) {\n console.error(`\\n\\nLost connection to the eval session: ${extractApiMessage(err)}`);\n console.error(`The session may still be running. Check results: wayai eval-results --session ${sessionId}`);\n process.exit(1);\n }\n continue;\n }\n\n const session = details.data.session;\n const results = details.data.results;\n\n // Calculate progress\n const totalRuns = results.reduce((sum, r) => sum + r.total_runs, 0);\n const completedRuns = results.reduce((sum, r) => sum + r.successful_runs + r.failed_runs, 0);\n\n if (TERMINAL_STATUSES.has(session.session_status)) {\n console.log('');\n console.log(`Session ${session.session_status}: ${session.session_name} (${session.eval_session_id})\\n`);\n printResultsTable(results, 'compact');\n return;\n }\n\n process.stdout.write(`\\rRunning... ${completedRuns}/${totalRuns} completed`);\n }\n\n console.log(`\\n\\nTimeout after ${timeoutSeconds}s. Session is still running.`);\n console.log(`Check results: wayai eval-results --session ${sessionId}`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** Pull the human-facing `message` out of a JSON error body, falling back to the raw text. */\nfunction extractApiMessage(err: unknown): string {\n if (err instanceof ApiError) {\n try {\n const parsed = JSON.parse(err.body) as { message?: string; error?: string };\n if (parsed.message) return parsed.message;\n if (parsed.error) return parsed.error;\n } catch {\n // body wasn't JSON — fall through to the raw text\n }\n return err.body || err.message;\n }\n return err instanceof Error ? err.message : String(err);\n}\n","/**\n * wayai eval-results — view results from a completed eval session\n *\n * Usage:\n * wayai eval-results --session <id> # show aggregate results\n * wayai eval-results --session <id> --runs # show individual run details\n * wayai eval-results --session <id> --json # raw JSON output\n * wayai eval-results --eval \"Test Greeting\" # latest session results for an eval\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { requireRepoConfig } from '../lib/repo-config.js';\nimport { resolveActiveHubId } from '../lib/workspace.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { printResultsTable } from '../lib/eval-format.js';\n\nexport async function evalResultsCommand(args: string[]): Promise<void> {\n const hubId = resolveActiveHubId(args);\n const { config, accessToken } = await requireAuth();\n requireRepoConfig();\n\n // Parse args\n let sessionId: string | undefined;\n let evalName: string | undefined;\n let showRuns = false;\n let jsonOutput = false;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--session') {\n if (i + 1 >= args.length) { console.error('--session requires a value'); process.exit(1); }\n sessionId = args[++i];\n } else if (arg === '--eval') {\n if (i + 1 >= args.length) { console.error('--eval requires a value'); process.exit(1); }\n evalName = args[++i];\n } else if (arg === '--runs') {\n showRuns = true;\n } else if (arg === '--json') {\n jsonOutput = true;\n }\n }\n\n if (!sessionId && !evalName) {\n console.error('Usage: wayai eval-results --session <id> [--runs] [--json]');\n console.error(' wayai eval-results --eval <name> [--runs] [--json]');\n process.exit(1);\n }\n\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n // If --eval, find the latest completed session containing that eval\n if (evalName && !sessionId) {\n sessionId = await findLatestSessionForEval(client, hubId, evalName);\n }\n\n if (!sessionId) {\n // findLatestSessionForEval already printed the error\n return;\n }\n\n if (showRuns) {\n await showRunDetails(client, hubId, sessionId, evalName, jsonOutput);\n } else {\n await showAggregateResults(client, hubId, sessionId, jsonOutput);\n }\n}\n\nasync function findLatestSessionForEval(\n client: ApiClient,\n hubId: string,\n evalName: string\n): Promise<string | undefined> {\n // Fetch evals and completed sessions in parallel\n const [evalsResult, sessionsResult] = await Promise.all([\n client.getEvals(hubId),\n client.getEvalSessions(hubId, { status: 'completed' }),\n ]);\n\n const matchingEval = evalsResult.data.evals.find(\n (e) => e.eval_name.toLowerCase() === evalName.toLowerCase()\n );\n\n if (!matchingEval) {\n console.error(`Eval \"${evalName}\" not found in this hub.`);\n process.exit(1);\n }\n\n const completedSessions = sessionsResult.data.sessions;\n\n if (completedSessions.length === 0) {\n console.error('No completed sessions found for this hub.');\n process.exit(1);\n }\n\n // Sessions are ordered by created_at desc, so first match is the latest\n for (const session of completedSessions) {\n const details = await client.getEvalSessionDetails(hubId, session.eval_session_id);\n const hasEval = details.data.results.some((r) => r.eval_id === matchingEval.eval_id);\n if (hasEval) {\n return session.eval_session_id;\n }\n }\n\n console.error(`No completed session found containing eval \"${evalName}\".`);\n process.exit(1);\n}\n\nasync function showAggregateResults(\n client: ApiClient,\n hubId: string,\n sessionId: string,\n jsonOutput: boolean\n): Promise<void> {\n const details = await client.getEvalSessionDetails(hubId, sessionId);\n\n if (jsonOutput) {\n console.log(JSON.stringify(details.data, null, 2));\n return;\n }\n\n const session = details.data.session;\n const results = details.data.results;\n\n console.log(`Session: ${session.session_name} (${session.session_status})`);\n if (session.started_at) {\n console.log(`Started: ${new Date(session.started_at).toLocaleString()}`);\n }\n if (session.completed_at && session.started_at) {\n const durationMs = new Date(session.completed_at).getTime() - new Date(session.started_at).getTime();\n console.log(`Duration: ${(durationMs / 1000).toFixed(0)}s`);\n }\n console.log('');\n\n printResultsTable(results, 'detailed');\n}\n\nasync function showRunDetails(\n client: ApiClient,\n hubId: string,\n sessionId: string,\n evalNameFilter: string | undefined,\n jsonOutput: boolean\n): Promise<void> {\n // Fetch session details (for header + eval name resolution) once\n const details = await client.getEvalSessionDetails(hubId, sessionId);\n\n // If filtering by eval name, resolve eval_id from the already-fetched details\n let evalId: string | undefined;\n if (evalNameFilter) {\n const matchingResult = details.data.results.find(\n (r) => r.eval?.eval_name?.toLowerCase() === evalNameFilter.toLowerCase()\n );\n if (matchingResult) {\n evalId = matchingResult.eval_id;\n }\n }\n\n const runsResult = await client.getEvalSessionRuns(hubId, sessionId, { evalId });\n\n if (jsonOutput) {\n console.log(JSON.stringify(runsResult.data, null, 2));\n return;\n }\n\n console.log(`Session: ${details.data.session.session_name} (${details.data.session.session_status})\\n`);\n\n if (runsResult.data.runs.length === 0) {\n console.log('No runs found.');\n return;\n }\n\n for (const run of runsResult.data.runs) {\n const evalName = run.eval?.eval_name || run.eval_id.slice(0, 8);\n const status = run.response_match === true ? 'PASS' : run.response_match === false ? 'FAIL' : 'PENDING';\n const time = run.execution_time_ms != null ? `(${(run.execution_time_ms / 1000).toFixed(1)}s)` : '';\n\n console.log(`${evalName} — Run #${run.run_number} [${status}] ${time}`);\n\n if (run.eval_response?.content) {\n console.log(` Response: \"${truncate(run.eval_response.content, 80)}\"`);\n }\n\n // Surface the agent's actual tool calls so tool-call evals are diagnosable\n // here, without opening the conversation (gh #2597).\n if (run.eval_response?.tool_calls && run.eval_response.tool_calls.length > 0) {\n console.log(' Tool calls:');\n for (const tc of run.eval_response.tool_calls) {\n console.log(` ${tc.function.name}(${truncate(tc.function.arguments, 80)})`);\n }\n }\n\n if (run.response_comment) {\n console.log(` Comment: ${run.response_comment}`);\n }\n\n if (run.scores && Object.keys(run.scores).length > 0) {\n const scoresStr = Object.entries(run.scores)\n .map(([key, val]) => `${key}: ${Math.round(val * 100)}%`)\n .join(', ');\n console.log(` Scores: ${scoresStr}`);\n }\n\n console.log('');\n }\n}\n\nfunction truncate(str: string, maxLen: number): string {\n if (str.length <= maxLen) return str;\n return str.slice(0, maxLen - 3) + '...';\n}\n","// wayai eval capture <conversation_id> — POST a real conversation to /api/evals/scenarios/from-conversation and write the result as eval YAML.\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as yaml from 'js-yaml';\nimport { requireAuth } from '../lib/auth.js';\nimport { requireRepoConfig } from '../lib/repo-config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { findLocalHubFolder, resolveActiveHubId } from '../lib/workspace.js';\nimport { slugify, UUID_RE } from '../lib/utils.js';\nimport { YAML_DUMP_OPTIONS, buildEvalYamlObject } from '../lib/yaml-writer.js';\nimport type { HubAsCodeEval } from '../lib/types.js';\n\ninterface ParsedArgs {\n conversationId: string;\n setName: string | null;\n evalName: string | null;\n evaluatorInstructions: string | null;\n}\n\n// Scenario sets are single folder names — reject separators and traversal so they fit the parser's flat-set model.\nfunction isValidSetName(name: string): boolean {\n if (name.length === 0 || name === '.' || name === '..') return false;\n if (name.startsWith('.')) return false;\n return !/[\\/\\\\\\0]/.test(name);\n}\n\nfunction parseArgs(args: string[]): ParsedArgs {\n if (args.length === 0 || args[0].startsWith('-')) {\n console.error('Usage: wayai eval capture <conversation_id> [--set <name>] [--name <eval_name>] [--instructions <text>]');\n process.exit(1);\n }\n\n const conversationId = args[0];\n if (!UUID_RE.test(conversationId)) {\n console.error(`Invalid conversation ID \"${conversationId}\". Expected a UUID.`);\n process.exit(1);\n }\n\n let setName: string | null = null;\n let evalName: string | null = null;\n let evaluatorInstructions: string | null = null;\n\n for (let i = 1; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--set') {\n setName = args[++i] ?? '';\n if (!setName) { console.error('--set requires a value.'); process.exit(1); }\n if (!isValidSetName(setName)) {\n console.error(`Invalid --set value \"${setName}\". Scenario set names must be a single folder name (no slashes, no '.', no '..', no leading dot).`);\n process.exit(1);\n }\n } else if (arg === '--name') {\n evalName = args[++i] ?? '';\n if (!evalName) { console.error('--name requires a value.'); process.exit(1); }\n } else if (arg === '--instructions') {\n evaluatorInstructions = args[++i] ?? '';\n if (!evaluatorInstructions) { console.error('--instructions requires a value.'); process.exit(1); }\n } else {\n console.error(`Unknown argument: ${arg}`);\n process.exit(1);\n }\n }\n\n return { conversationId, setName, evalName, evaluatorInstructions };\n}\n\nexport async function evalCaptureCommand(args: string[]): Promise<void> {\n // Resolve hub before parseArgs in case parseArgs rejects unknown flags\n const hubId = resolveActiveHubId(args);\n const parsed = parseArgs(args);\n const { config, accessToken } = await requireAuth();\n requireRepoConfig();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n const hubFolder = findLocalHubFolder(hubId);\n if (!hubFolder) {\n console.error('Could not find a local hub folder for this hub. Run `wayai pull` first.');\n process.exit(1);\n }\n\n // Fall back to 'Default' on both sides so the local path and platform set agree.\n const targetSetName = parsed.setName ?? 'Default';\n const setFolderName = targetSetName;\n const scenarioName = parsed.evalName ?? `Capture ${parsed.conversationId.slice(0, 8)}`;\n const slug = slugify(scenarioName);\n const evalsDir = path.join(hubFolder, 'evals');\n const targetDir = path.join(evalsDir, setFolderName);\n const targetPath = path.join(targetDir, `${slug}.yaml`);\n // Defense-in-depth: refuse paths escaping evals/, mirroring writeEvalYamlFiles.\n if (!targetPath.startsWith(evalsDir + path.sep)) {\n console.error(`Resolved path \"${path.relative(hubFolder, targetPath)}\" escapes evals/. Aborting.`);\n process.exit(1);\n }\n if (fs.existsSync(targetPath)) {\n console.error(`File already exists: ${path.relative(hubFolder, targetPath)}. Use --name to choose a different name.`);\n process.exit(1);\n }\n\n // 2. Resolve scenario_set_id (find or create by name).\n console.log('Resolving scenario set...');\n const sets = await client.listScenarioSets(hubId);\n let scenarioSetId = sets.data.scenario_sets.find((s) => s.set_name === targetSetName)?.scenario_set_id;\n\n if (!scenarioSetId) {\n console.log(`Creating scenario set \"${targetSetName}\"...`);\n const created = await client.createScenarioSet(hubId, targetSetName);\n scenarioSetId = created.data.scenario_set.scenario_set_id;\n }\n\n // 3. Capture from conversation.\n console.log(`Capturing conversation ${parsed.conversationId}...`);\n const result = await client.createScenarioFromConversation({\n hub_id: hubId,\n conversation_id: parsed.conversationId,\n scenario_set_id: scenarioSetId,\n scenario_name: scenarioName,\n ...(parsed.evaluatorInstructions ? { evaluator_instructions: parsed.evaluatorInstructions } : {}),\n });\n\n const captured = result.data.eval;\n\n // 4. Build the on-disk YAML via the shared eval-writer logic so capture and\n // pull produce identical shapes. The display name is initially the agent_id\n // — `wayai pull` resolves it to the proper name on next sync.\n const evalEntry: HubAsCodeEval = {\n id: captured.eval_id,\n name: scenarioName,\n agent: captured.responder_agent_id,\n agent_id: captured.responder_agent_id,\n path: setFolderName,\n history: captured.message_history,\n input: captured.message_text,\n expected: captured.message_expected_response,\n ...(captured.evaluator_instructions ? { evaluator_instructions: captured.evaluator_instructions } : {}),\n };\n const yamlObj = buildEvalYamlObject(evalEntry, slug);\n\n fs.mkdirSync(targetDir, { recursive: true });\n fs.writeFileSync(targetPath, yaml.dump(yamlObj, YAML_DUMP_OPTIONS), 'utf-8');\n\n const relPath = path.relative(process.cwd(), targetPath);\n console.log(`\\nWrote ${relPath}`);\n console.log('Run `wayai pull` to refresh the agent display name, then commit. The scenario is already on the platform.');\n}\n","// wayai eval — dispatcher for imperative eval actions (authoring is file-driven via wayai push/pull).\nexport async function evalCommand(args: string[]): Promise<void> {\n const [sub, ...rest] = args;\n\n if (!sub) {\n printHelp();\n process.exit(1);\n }\n\n switch (sub) {\n case 'capture': {\n const { evalCaptureCommand } = await import('./eval-capture.js');\n await evalCaptureCommand(rest);\n return;\n }\n case 'help':\n case '--help':\n case '-h':\n printHelp();\n return;\n default:\n console.error(`Unknown eval subcommand: ${sub}`);\n printHelp();\n process.exit(1);\n }\n}\n\nfunction printHelp(): void {\n console.log(`\nwayai eval — eval scenario operations\n\nUsage:\n wayai eval <subcommand> [options]\n\nSubcommands:\n capture <conversation_id> Capture a real conversation as a scenario YAML\n in the workspace evals/ folder.\n\nCapture flags:\n --set <name> Scenario set folder (created if missing). Default: \"Default\".\n --name <eval_name> Scenario name. Default: derived from conversation ID.\n --instructions <text> Evaluator instructions for the scoring agent.\n\nExamples:\n wayai eval capture 11111111-2222-3333-4444-555555555555\n wayai eval capture <conv_id> --set regression-suite --name \"Cancel order\"\n\nAuthoring evals (create/update/delete) is file-driven — edit YAML in\nevals/ and run \\`wayai push\\`. This command is for production replay only.\n`.trim());\n}\n","import { z } from 'zod';\n\nexport const uuidSchema = z.string().uuid();\n\nexport const paginationSchema = z.object({\n limit: z.coerce.number().int().min(1).max(100).default(50),\n offset: z.coerce.number().int().min(0).default(0),\n});\n\nexport const timestampSchema = z.string().datetime();\n\nexport const idParamSchema = z.object({\n id: uuidSchema,\n});\n\n// =============================================================================\n// UTILITY TYPES\n// =============================================================================\n\n/** Generic JSON-compatible value (replaces the old Supabase-generated Json type) */\nexport type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[];\n\n// =============================================================================\n// RESPONSE TYPE WRAPPERS\n// =============================================================================\n\nexport interface ApiErrorResponse {\n error: string;\n message: string;\n details?: Record<string, unknown>;\n}\n\nexport interface ApiDataResponse<T> {\n data: T;\n}\n\nexport interface ApiListResponse<T> {\n data: T[];\n}\n\nexport interface ApiSuccessResponse {\n success: true;\n}\n","import { z } from 'zod';\nimport { uuidSchema } from '../common';\n\n// 9 Cloudflare DurableObject location hints. `sam`, `afr`, `me` currently route\n// to the nearest supported region (CF doesn't yet spawn DOs there) — see\n// https://developers.cloudflare.com/durable-objects/reference/data-location/\n// The customer-stored value takes effect natively once CF expands support.\nexport const primaryRegionSchema = z.enum([\n 'wnam', 'enam', 'sam', 'weur', 'eeur', 'apac', 'oc', 'afr', 'me',\n]);\nexport type PrimaryRegion = z.infer<typeof primaryRegionSchema>;\n\n// Source of the placement_region value resolved by the backend cascade.\nexport const placementSourceSchema = z.enum([\n 'hub_config', 'org_config', 'parent_cascade',\n 'cf_colo', 'country', 'fallback',\n]);\nexport type PlacementSource = z.infer<typeof placementSourceSchema>;\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\nexport const orgIdParam = z.object({\n id: uuidSchema,\n});\n\nexport const orgAdminIdParam = z.object({\n id: uuidSchema,\n adminId: z.string().min(1),\n});\n\nexport const createOrganizationBody = z.object({\n organization_name: z.string().min(1, 'organization_name is required'),\n // Write-once at creation; updateOrganizationBody does not accept this.\n primary_region: primaryRegionSchema.optional(),\n});\n\nexport const updateOrganizationBody = z.object({\n organization_name: z.string().min(1).optional(),\n organization_avatar_url: z.string().url().nullable().optional(),\n timezone: z.string().optional(),\n business_hours: z.unknown().optional(),\n}).passthrough();\n\nexport const addOrgAdminBody = z.object({\n user_email: z.string().email('valid email is required'),\n});\n\n// =============================================================================\n// INFERRED TYPES (for consumers that need request types without importing zod)\n// =============================================================================\n\nexport type CreateOrganizationInput = z.infer<typeof createOrganizationBody>;\nexport type UpdateOrganizationInput = z.infer<typeof updateOrganizationBody>;\nexport type AddOrgAdminInput = z.infer<typeof addOrgAdminBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\nexport interface OrganizationResponse {\n organization_id: string;\n created_at: string;\n organization_name: string;\n updated_at: string;\n created_by: string;\n billing_currency: string;\n primary_region: PrimaryRegion | null;\n placement_region: PrimaryRegion | null;\n placement_source: PlacementSource | null;\n}\n\nexport interface OrganizationAdminUserResponse {\n organization_admin_user_id: string;\n organization_id: string;\n created_at: string;\n updated_at: string;\n user_id: string | null;\n enabled: boolean;\n user_email: string;\n is_owner: boolean;\n}\n\nexport interface GetOrganizationResponse {\n data: {\n organization: OrganizationResponse;\n admin_users: OrganizationAdminUserResponse[];\n };\n}\n\nexport interface CreateOrganizationResponse {\n data: OrganizationResponse[];\n}\n\nexport interface UpdateOrganizationResponse {\n data: OrganizationResponse[];\n}\n\nexport interface AddOrgAdminResponse {\n data: OrganizationAdminUserResponse[];\n}\n\n// Composite org-view endpoint — returns everything OrganizationDetailView needs\n// (organization + admins + tags) in one request to collapse the 2–3 parallel\n// fetches that would otherwise fire on every org-settings entry.\nexport interface GetOrganizationViewResponse {\n data: {\n organization: OrganizationResponse;\n admin_users: OrganizationAdminUserResponse[];\n tags: Array<{\n tag_id: string;\n name: string;\n display_name: string | null;\n color: string | null;\n organization_id: string;\n created_at: string;\n updated_at: string;\n }>;\n };\n}\n","import { z } from 'zod';\nimport { uuidSchema } from '../common';\nimport { AGENT_ROLES, type AgentRole } from '../../constants';\nimport { SUMMARIZATION_THRESHOLD_MIN, SUMMARIZATION_THRESHOLD_MAX } from '../../summarizer';\n\n// Relocated from the hub (`updateHubBody`) to the summarizer agent — preserve the\n// original int+range guard on the write paths that set it. `.passthrough()` keeps\n// other agent keys flowing; this explicit key restores validation for this one.\nconst summarizationThresholdField = z\n .number()\n .int()\n .min(SUMMARIZATION_THRESHOLD_MIN)\n .max(SUMMARIZATION_THRESHOLD_MAX)\n .nullable()\n .optional();\n\n// Relocated from the hub (`updateHubBody`) to the monitor agent — restore the\n// guards the hub UI enforced (`delay_seconds >= 10`) on every write path so a caller\n// (REST/CLI/MCP) can't persist an invalid monitor schedule. JSON object on the monitor\n// agent column; `.passthrough()` keeps other agent keys flowing. Meaningful only on\n// `monitor` agents. `flag_conditions` mirrors the FlagCondition shape used elsewhere.\nconst monitorConfigField = z\n .object({\n delay_seconds: z.number().int().min(10),\n flag_conditions: z\n .array(\n z.object({\n variable: z.string(),\n operator: z.enum(['=', '!=']),\n value: z.union([z.string(), z.number()]),\n }),\n )\n .optional(),\n })\n .passthrough()\n .nullable()\n .optional();\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\nexport const agentIdParam = z.object({\n id: uuidSchema,\n});\n\nexport const listAgentsQuery = z.object({\n hub_id: uuidSchema,\n});\n\nexport const agentConnectionsQuery = z.object({\n hub_id: uuidSchema,\n});\n\nexport const createAgentBody = z.object({\n agent_name: z.string().min(1),\n hub_id: uuidSchema,\n agent_role: z.enum(AGENT_ROLES),\n additional_context_template: z.string().max(20000).optional(),\n summarization_threshold_tokens: summarizationThresholdField,\n monitor_config: monitorConfigField,\n}).passthrough();\n\nexport const updateAgentBody = z.object({\n additional_context_template: z.string().max(20000).optional(),\n summarization_threshold_tokens: summarizationThresholdField,\n monitor_config: monitorConfigField,\n}).passthrough();\n\n// =============================================================================\n// INFERRED TYPES (for consumers that need request types without importing zod)\n// =============================================================================\n\nexport type CreateAgentInput = z.infer<typeof createAgentBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n/** Full agent row as returned by select('*') on the agent table */\nexport interface AgentResponse {\n agent_id: string;\n agent_name: string;\n created_at: string;\n agent_sid: string | null;\n instructions: string;\n response_format: string;\n updated_at: string | null;\n hub_id: string;\n connection_id: string;\n agent_role: AgentRole;\n schema_json: Record<string, unknown> | null;\n schema_name: string | null;\n agent_settings: Record<string, unknown> | null;\n instructions_file_id: string | null;\n additional_context_template: string;\n enabled: boolean;\n include_message_timestamps: boolean;\n auto_format: boolean;\n /** Conversation-flagging conditions, evaluated post-close by the\n * `conversation_evaluator` agent (relocated from the hub column). Only\n * meaningful on `conversation_evaluator` agents; null/omitted elsewhere. */\n flag_conditions: Array<{ variable: string; operator: '=' | '!='; value: string | number }> | null;\n /** Token threshold that fires the rolling summarizer (sum of input + cache_read +\n * cache_creation). A `summarizer` agent setting (relocated from the hub column).\n * Only meaningful on `summarizer` agents; null/omitted elsewhere → falls back to\n * DEFAULT_SUMMARIZATION_THRESHOLD_TOKENS at the read site. */\n summarization_threshold_tokens?: number | null;\n /** Monitor scheduling + flagging config ({delay_seconds, flag_conditions}). A\n * `monitor` agent setting (relocated from the hub column). Only meaningful on\n * `monitor` agents; null/omitted elsewhere. The monitor is NOT auto-provisioned. */\n monitor_config?: {\n delay_seconds: number;\n flag_conditions?: Array<{ variable: string; operator: '=' | '!='; value: string | number }>;\n } | null;\n}\n\n/** Agent parameter row */\nexport interface AgentParameterResponse {\n agent_parameter_id: string;\n created_at: string;\n agent_id: string;\n parameter_name: string;\n parameter_type: 'string' | 'number' | 'boolean' | 'integer' | 'enum';\n parameter_description: string;\n parameter_label: string | null;\n parameter_enum: string[] | null;\n parameter_required: boolean;\n variable_category: 'quality' | 'satisfaction' | 'compliance' | 'categorization' | null;\n is_summary: boolean;\n}\n\n/** Simplified agent connection detail returned by fetchAgentById */\nexport interface AgentConnectionDetail {\n connection_id: string;\n connection_display_name: string | null;\n connector_id: string;\n agent_settings_schema: Record<string, unknown> | null;\n}\n\n/** Connection with nested connector, returned by the /connections endpoint */\nexport interface AgentConnectionWithConnector {\n connection_id: string;\n created_at: string;\n service_name: string | null;\n api_key: string | null;\n updated_at: string | null;\n hub_id: string;\n access_token: string | null;\n access_token_expires_at: string | null;\n access_token_secret_id: string | null;\n account_sid: string | null;\n api_key_secret_id: string | null;\n authentication_type: string;\n enabled: boolean;\n connector_id: string;\n connector_name: string;\n password: string | null;\n password_secret_id: string | null;\n connection_display_name: string | null;\n connector_type: string;\n refresh_token: string | null;\n refresh_token_expires_at: string | null;\n refresh_token_secret_id: string | null;\n state: Record<string, unknown> | null;\n username: string | null;\n base_url: string | null;\n connection_headers: Record<string, unknown> | null;\n settings: Record<string, unknown> | null;\n token_refresh_config: Record<string, unknown> | null;\n next_access_token_refresh_at: string | null;\n next_refresh_token_renewal_at: string | null;\n last_token_refresh_at: string | null;\n last_token_refresh_error: string | null;\n organization_credential_id: string | null;\n connector: {\n connector_id: string;\n created_at: string;\n service_name: string;\n authentication_type: string;\n init_endpoint: string | null;\n connector_type: string;\n connector_name: string;\n unique_per_hub: boolean;\n account_sid_placeholder: string | null;\n models: string[] | null;\n is_internal: boolean;\n connector_module: string | null;\n enabled: boolean;\n connector_settings_schema: Record<string, unknown> | null;\n agent_settings_schema: Record<string, unknown> | null;\n channel_settings_schema: Record<string, unknown> | null;\n tool_settings_schema: Record<string, unknown> | null;\n connector_credential_schema: Record<string, unknown> | null;\n token_refresh_config: Record<string, unknown>;\n connector_description: string | null;\n } | null;\n}\n\n// -- Endpoint response wrappers --\n\nexport interface ListAgentsResponse {\n data: AgentResponse[];\n}\n\nexport interface GetAgentResponse {\n data: {\n agent: AgentResponse;\n agent_connections: AgentConnectionDetail[];\n agent_parameters: AgentParameterResponse[];\n };\n}\n\nexport interface CreateAgentResponse {\n data: AgentResponse[];\n}\n\nexport interface UpdateAgentResponse {\n data: AgentResponse[];\n}\n\nexport interface ListAgentConnectionsResponse {\n data: AgentConnectionWithConnector[];\n}\n\nexport interface ListAgentParametersResponse {\n data: AgentParameterResponse[];\n}\n\nexport interface CreateAgentParametersResponse {\n data: AgentParameterResponse[];\n}\n","/**\n * Shared constants for WayAI Workers\n */\n\n/** Meta (Facebook) Graph API version used for WhatsApp and Instagram integrations */\nexport const META_API_VERSION = 'v25.0';\n\n// ---------------------------------------------------------------------------\n// Tool Execution\n// ---------------------------------------------------------------------------\n\n/**\n * Hard ceiling (ms) on a single AI-triggered external/MCP/native tool HTTP fetch\n * during an agent turn. Bounds tool execution so a slow or hung endpoint can't\n * wedge the turn indefinitely (gh #2599).\n *\n * 60s is generous for legitimate slow tool APIs yet well under the eval watchdog\n * default (`EVAL_DEFAULT_RUN_DEADLINE_MS`, 180s): a single hung tool fetch fails\n * fast instead of consuming the whole run budget and falsely reaping a still-\n * progressing eval run. Applied to ALL conversations, not just eval runs.\n */\nexport const EXTERNAL_TOOL_FETCH_TIMEOUT_MS = 60_000;\n\n// ---------------------------------------------------------------------------\n// Authentication Types\n// ---------------------------------------------------------------------------\n\n/** Canonical lowercase auth type codes used in seed data, DB storage, and all comparisons. */\nexport const AUTH_TYPE = {\n OAUTH: 'oauth',\n API_KEY: 'api_key',\n BASIC_AUTH: 'basic_auth',\n BEARER: 'bearer',\n NONE: 'none',\n} as const;\n\nexport type AuthTypeCode = (typeof AUTH_TYPE)[keyof typeof AUTH_TYPE];\n\n/** Auth types valid for organization credentials (excludes OAuth and None). */\nexport const ORG_CREDENTIAL_AUTH_TYPES = [\n AUTH_TYPE.API_KEY,\n AUTH_TYPE.BEARER,\n AUTH_TYPE.BASIC_AUTH,\n] as const;\n\nexport type OrgCredentialAuthType = (typeof ORG_CREDENTIAL_AUTH_TYPES)[number];\n\n/** Maps lowercase code to human-readable display label. */\nexport const AUTH_TYPE_DISPLAY: Record<string, string> = {\n [AUTH_TYPE.OAUTH]: 'OAuth',\n [AUTH_TYPE.API_KEY]: 'API Key',\n [AUTH_TYPE.BASIC_AUTH]: 'Basic Auth',\n [AUTH_TYPE.BEARER]: 'Bearer Token',\n [AUTH_TYPE.NONE]: 'No Authentication',\n};\n\n/** Maps old capitalized display names to canonical lowercase codes. */\nconst LEGACY_AUTH_TYPE_MAP: Record<string, AuthTypeCode> = {\n 'OAuth': AUTH_TYPE.OAUTH,\n 'API Key': AUTH_TYPE.API_KEY,\n 'Basic Auth': AUTH_TYPE.BASIC_AUTH,\n 'Bearer Token': AUTH_TYPE.BEARER,\n 'No authentication': AUTH_TYPE.NONE,\n // Also handle the old DISPLAY_TO_CODE bug where 'basic' was used instead of 'basic_auth'\n 'basic': AUTH_TYPE.BASIC_AUTH,\n};\n\nconst VALID_AUTH_TYPES = new Set<string>(Object.values(AUTH_TYPE));\n\n/** Normalizes any auth type string (legacy capitalized or already lowercase) to canonical code. */\nexport function normalizeAuthType(raw: string): AuthTypeCode {\n if (VALID_AUTH_TYPES.has(raw)) return raw as AuthTypeCode;\n return LEGACY_AUTH_TYPE_MAP[raw] ?? (raw as AuthTypeCode);\n}\n\n// ---------------------------------------------------------------------------\n// Agent Roles\n// ---------------------------------------------------------------------------\n\nexport const AGENT_ROLES = [\n 'pilot', 'copilot',\n 'pilot_specialist', 'copilot_specialist',\n 'pilot_advisor', 'copilot_advisor',\n 'monitor', 'conversation_evaluator', 'message_evaluator',\n 'summarizer',\n] as const;\n\nexport type AgentRole = (typeof AGENT_ROLES)[number];\n\nexport const BACKGROUND_AGENT_ROLES: readonly AgentRole[] = ['conversation_evaluator', 'message_evaluator', 'monitor', 'summarizer'];\nexport const PILOT_TRACK_ROLES: readonly AgentRole[] = ['pilot', 'pilot_specialist'];\nexport const COPILOT_TRACK_ROLES: readonly AgentRole[] = ['copilot', 'copilot_specialist'];\n\n/** Maps agent role to human-readable display label. */\nexport const AGENT_ROLE_DISPLAY: Record<AgentRole, string> = {\n pilot: 'Pilot',\n copilot: 'Copilot',\n pilot_specialist: 'Pilot Specialist',\n copilot_specialist: 'Copilot Specialist',\n pilot_advisor: 'Pilot Advisor',\n copilot_advisor: 'Copilot Advisor',\n monitor: 'Monitor',\n conversation_evaluator: 'Conversation Evaluator',\n message_evaluator: 'Message Evaluator',\n summarizer: 'Summarizer',\n};\n\n// ---------------------------------------------------------------------------\n// AI Modes\n// ---------------------------------------------------------------------------\n\nexport const AI_MODES = ['pilot', 'copilot', 'pilot+copilot', 'turned_off'] as const;\n\nexport type AiMode = (typeof AI_MODES)[number];\n\nexport const COPILOT_MODES: readonly AiMode[] = ['pilot+copilot', 'copilot'];\n\n/** Maps AI mode to human-readable display label. */\nexport const AI_MODE_DISPLAY: Record<AiMode, string> = {\n pilot: 'Pilot',\n copilot: 'Copilot',\n 'pilot+copilot': 'Pilot+Copilot',\n turned_off: 'Turned Off',\n};\n\n// ---------------------------------------------------------------------------\n// Identifier validation\n// ---------------------------------------------------------------------------\n\n/**\n * Injection-safe whitelist for `user_id` values that may appear in URL paths,\n * R2 key prefixes, ScheduleSession scope keys, and interpolated SQL. Accepts\n * both HubDO-generated UUIDs and WorkOS-style ids (e.g. `user_01KMR9AZ...`)\n * while excluding every character that could break out of a single-quoted SQL\n * literal or create structural ambiguity in `:`-delimited keys.\n */\nexport const SAFE_USER_ID_REGEX = /^[A-Za-z0-9_-]{1,64}$/;\n\n// ---------------------------------------------------------------------------\n// Supported UI locales — proxy-to-backend auth-locale contract\n// ---------------------------------------------------------------------------\n\n// Single source of truth for frontend cookie + backend header locale validation.\nexport const SUPPORTED_LOCALES = ['en', 'pt', 'es'] as const;\nexport type SupportedLocale = (typeof SUPPORTED_LOCALES)[number];\n\nexport function isSupportedLocale(value: string): value is SupportedLocale {\n return (SUPPORTED_LOCALES as readonly string[]).includes(value);\n}\n\n/** Header set by the same-origin proxy from the auth-locale cookie. */\nexport const AUTH_LOCALE_HEADER = 'x-wayai-auth-locale';\n","// Summarizer constants — shared across HubDO, ConversationDO, and buildAgentSettings.\n\nexport const RESERVED_SUMMARY_STATE_SLUG = 'conversation_summary' as const;\nexport const DEFAULT_SUMMARIZATION_THRESHOLD_TOKENS = 120000;\nexport const SUMMARIZATION_THRESHOLD_MIN = 1000;\nexport const SUMMARIZATION_THRESHOLD_MAX = 1_000_000;\nexport const SUMMARIZER_FAILURE_THRESHOLD = 3;\nexport const SUMMARIZER_DEBOUNCE_MS = 60_000;\n\n/** Strict invariant — load-bearing for expand_summary. Extra fields allowed; anchors are not. */\nexport const SUMMARIZER_INVARIANT_SCHEMA = {\n type: 'object',\n required: ['sections'],\n properties: {\n sections: {\n type: 'array',\n items: {\n type: 'object',\n required: ['id', 'message_id_start', 'message_id_end'],\n properties: {\n id: { type: 'string', minLength: 1 },\n message_id_start: { type: 'string', minLength: 1 },\n message_id_end: { type: 'string', minLength: 1 },\n },\n },\n },\n },\n} as const;\n\n/** Default user-editable schema seeded for new hubs. */\nexport const SUMMARIZER_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['sections'],\n properties: {\n sections: {\n type: 'array',\n description: 'Topically-grouped summary units covering the conversation up to the verbatim tail. Each section carries a message-range anchor used by expand_summary.',\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['id', 'topic', 'summary', 'message_id_start', 'message_id_end'],\n properties: {\n id: {\n type: 'string',\n minLength: 1,\n description: 'Stable identifier for this section (e.g. \"sec_01\"). Used by expand_summary to fetch original messages.',\n },\n topic: {\n type: 'string',\n minLength: 1,\n description: 'Short topic label (1-5 words) describing what this section covers.',\n },\n summary: {\n type: 'string',\n minLength: 1,\n description: 'Concise prose summary of what happened in this section. Preserve concrete details (names, prices, decisions); compress filler.',\n },\n message_id_start: {\n type: 'string',\n minLength: 1,\n description: 'message_id of the FIRST message included in this section.',\n },\n message_id_end: {\n type: 'string',\n minLength: 1,\n description: 'message_id of the LAST message included in this section.',\n },\n key_decisions: {\n type: 'array',\n items: { type: 'string' },\n description: 'Decisions or commitments made in this section (e.g. \"agreed price: $79/yr\").',\n },\n open_threads: {\n type: 'array',\n items: { type: 'string' },\n description: 'Unresolved threads opened in this section that may need follow-up.',\n },\n },\n },\n },\n },\n} as const;\n\n/** System prompt for the summarizer agent. */\nexport const SUMMARIZER_INSTRUCTIONS = `You are the conversation summarizer. Your job is to compress older messages of a conversation into a structured JSON summary while preserving everything that matters for the agents who will continue the conversation.\n\nRules:\n1. Read the entire input. Each message has a \\`message_id\\` attribute — record them exactly.\n2. Group messages into topical sections. A section is one coherent thread (a question being resolved, a topic being discussed, a decision being made). Aim for one section per topic; don't fragment.\n3. For each section, set:\n - \\`id\\`: a short stable identifier (e.g. \"sec_01\", \"sec_02\"). Use sequential numbering.\n - \\`topic\\`: 1–5 words naming the thread.\n - \\`summary\\`: concise prose. Preserve concrete details (exact names, prices, IDs, decisions, commitments, dates). Compress filler. Do NOT invent facts.\n - \\`message_id_start\\` and \\`message_id_end\\`: the exact message_id of the FIRST and LAST messages you included in this section. These are load-bearing — they must reference real messages from the input.\n - \\`key_decisions\\`: decisions or commitments made (optional).\n - \\`open_threads\\`: unresolved items that may need follow-up (optional).\n4. If a prior summary is provided, the new summary should fold it in: re-use stable section ids where the underlying messages are unchanged, add new sections for the new messages. Replace the prior summary in its entirety with your output.\n5. Emit ONLY valid JSON matching the schema. No prose preamble, no markdown fences.\n6. Tone: factual, third-person, terse.`;\n\n/** Appended to non-background agents' system prompt when the hub has a conversation_summary state. */\nexport const SUMMARIZER_PROMPT_ADDENDUM = `\n---\n**Conversation summary available.** Older parts of this conversation may have been compressed into a structured summary delivered as a \\`<conversation_summary>\\` block prepended to the message history. Each section in that summary carries an \\`id\\` and a message-range anchor.\n\nIf a section's summary is insufficient for your current task — for example, you need the user's exact wording, the precise text of a previous decision, or details that aren't captured in the prose — call the \\`expand_summary\\` tool with the section's \\`id\\` to retrieve the original messages. Don't confabulate from a compressed summary when the originals are one tool call away.`;\n","// Slug primitive shared by kanban_status and state — strict subset of ClickHouse VALID_JSON_PATH_REGEX so analytics paths never need quoting.\n\nimport { z } from 'zod';\n\nexport const SLUG_REGEX = /^[a-z][a-z0-9_]{0,49}$/;\n\nexport const slugSchema = z\n .string()\n .regex(\n SLUG_REGEX,\n 'slug must be lowercase, start with a letter, contain only [a-z0-9_], and be 1–50 characters',\n );\n\nconst INVISIBLE_NAME_CHARS = /[\\s\\p{Default_Ignorable_Code_Point}]/gu;\n\nexport function visibleLength(s: string): number {\n return s.replace(INVISIBLE_NAME_CHARS, '').length;\n}\n","/**\n * Zod schemas for kanban status configuration on a hub.\n *\n * Single source of truth for cross-field validation invariants enforced on\n * every write path that lands `kanban_statuses` in HubDO SQLite:\n * - REST: createHubBody / updateHubBody (workers/shared/src/contracts/setup/hubs.ts)\n * - CI: hubAsCodeConfigSchema (workers/shared/src/contracts/ci.ts)\n *\n * Field shapes mirror the existing TypeScript interfaces:\n * - HubAsCodeKanbanStatus / HubAsCodeKanbanFollowup (contracts/ci.ts)\n * - KanbanStatusConfig / FollowupConfig (backend/scheduling/types.ts)\n *\n * Human-facing constraint summary lives in skills/wayai/SKILL.md \"Kanban &\n * States — Constraints\".\n *\n * `additional_context_schema` is a JSON Schema (Draft 2020-12). Structural\n * shape is gated here (size, reserved-name); semantic well-formedness\n * (`ajv.validateSchema`) runs at the backend route handler so AJV does not\n * leak into shared/frontend bundles.\n */\n\nimport { z } from 'zod';\nimport { SLUG_REGEX, slugSchema, visibleLength } from './slug';\n\n// Defensive bounds. Typical hubs have 3–10 statuses with 0–3 followups each;\n// caps are generous on intent and tight enough that the per-request\n// superRefine cost stays bounded. Mirrors MAX_GRANTS in contracts/tokens.ts.\nconst MAX_KANBAN_STATUSES = 50;\nconst MAX_FOLLOWUPS_PER_STATUS = 20;\nexport const MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES = 16384;\n\n/**\n * Reserved placeholder name in `additional_instructions` templates: dumps the\n * full payload as JSON. Schemas may not declare this as a top-level property.\n */\nexport const RESERVED_TEMPLATE_DUMP_NAME = 'additional_data';\n\n/** Matches `{{path}}` and `{{ path.to.field }}` in templates. */\nconst PLACEHOLDER_RE = /\\{\\{\\s*([a-zA-Z_][a-zA-Z0-9_.]*)\\s*\\}\\}/g;\n\n/**\n * Kanban slug — alias of the shared SLUG_REGEX. Used as the immutable runtime\n * identifier (`conversation.kanban_status`, ClickHouse `data.meta.kanban_status`,\n * native tool params, transition refs).\n */\nexport const KANBAN_SLUG_REGEX = SLUG_REGEX;\nexport const kanbanStatusSlugSchema = slugSchema;\n\n// =============================================================================\n// FOLLOWUP SCHEMA\n// =============================================================================\n\nexport const followupSchema = z\n .object({\n id: z.string().optional(),\n order: z.number().int().nonnegative(),\n type: z.enum(['inactivity', 'before_event']),\n threshold: z.number().int().positive(),\n timeUnit: z.enum(['seconds', 'minutes', 'hours', 'days']),\n instructions: z.string().optional(),\n excludedWeekDays: z.array(z.number().int().min(0).max(6)).optional(),\n excludeHolidays: z.boolean().optional(),\n excludedTimeStart: z.string().optional(),\n excludedTimeEnd: z.string().optional(),\n delivery_mode: z.enum(['agent_generated', 'direct']).optional(),\n direct_text: z.string().optional(),\n template_whatsapp_id: z.string().nullable().optional(),\n outside_window_policy: z.enum(['route_to_team', 'skip']).optional(),\n include_tools: z.boolean().optional(),\n })\n .passthrough()\n .superRefine((followup, ctx) => {\n if (followup.delivery_mode === 'direct' && !followup.direct_text?.trim()) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['direct_text'],\n message: 'direct_text is required and must be non-empty when delivery_mode=\"direct\"',\n });\n }\n });\n\n// =============================================================================\n// PER-STATUS SCHEMA\n// =============================================================================\n\n/**\n * Mutually-exclusive boolean flag pairs. Order within each pair is purely for\n * the error path: the issue is anchored on the second flag (the one the user\n * most recently toggled in typical UI flows).\n */\nconst EXCLUSIVE_FLAG_PAIRS = [\n ['isInitialStatus', 'triggersAgentResponse'],\n ['isInitialStatus', 'allowsAgentUpdate'],\n ['isInitialStatus', 'isTerminalStatus'],\n ['isInitialStatus', 'isSchedulingStatus'],\n ['triggersAgentResponse', 'allowsAgentUpdate'],\n ['triggersAgentResponse', 'isTerminalStatus'],\n] as const;\n\nexport const kanbanStatusSchema = z\n .object({\n slug: kanbanStatusSlugSchema,\n name: z\n .string()\n .min(1, 'name is required')\n .max(100, 'name must be 100 characters or fewer')\n .refine((v) => visibleLength(v) > 0, 'name must not be blank'),\n order: z.number().int().nonnegative().optional(),\n color: z.string().optional(),\n isInitialStatus: z.boolean().optional(),\n triggersAgentResponse: z.boolean().optional(),\n allowsAgentUpdate: z.boolean().optional(),\n isTerminalStatus: z.boolean().optional(),\n isSchedulingStatus: z.boolean().optional(),\n eventName: z.string().optional(),\n additional_instructions: z.string().optional(),\n additional_context_schema: z\n .record(z.unknown())\n .refine(\n (s) => JSON.stringify(s).length <= MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES,\n `additional_context_schema must be at most ${MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES} bytes when JSON-serialized`,\n )\n .optional(),\n followups: z\n .array(followupSchema)\n .max(MAX_FOLLOWUPS_PER_STATUS, `followups must have at most ${MAX_FOLLOWUPS_PER_STATUS} entries`)\n .optional(),\n /** Slugs this status may transition to. `undefined` = unrestricted (any\n * next status). Empty array `[]` is rejected — author must use\n * `isTerminalStatus: true` to express \"no outbound transitions\". */\n allowed_next_statuses: z\n .array(z.string())\n .min(1, 'allowed_next_statuses cannot be empty — use isTerminalStatus: true for no outbound transitions')\n .optional(),\n })\n .passthrough()\n .superRefine((status, ctx) => {\n const label = status.name ? `\"${status.name}\"` : status.slug ? `\"${status.slug}\"` : '<unnamed>';\n\n for (const [a, b] of EXCLUSIVE_FLAG_PAIRS) {\n if (status[a] === true && status[b] === true) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [b],\n message: `kanban status ${label}: ${a} and ${b} cannot both be true`,\n });\n }\n }\n\n if (status.isSchedulingStatus === true && !status.eventName?.trim()) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['eventName'],\n message: `kanban status ${label}: eventName is required when isSchedulingStatus=true`,\n });\n }\n\n if (\n Array.isArray(status.followups) &&\n status.followups.some((f) => f?.type === 'before_event') &&\n status.isSchedulingStatus !== true\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['followups'],\n message: `kanban status ${label}: before_event followups require isSchedulingStatus=true on the parent status`,\n });\n }\n\n // Reserved-name collision: `additional_data` is the magic dump placeholder.\n if (status.additional_context_schema && typeof status.additional_context_schema === 'object') {\n const schema = status.additional_context_schema as Record<string, unknown>;\n const props = schema.properties;\n if (props && typeof props === 'object' && RESERVED_TEMPLATE_DUMP_NAME in (props as object)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['additional_context_schema', 'properties', RESERVED_TEMPLATE_DUMP_NAME],\n message: `kanban status ${label}: \"${RESERVED_TEMPLATE_DUMP_NAME}\" is a reserved template placeholder name and cannot be used as a top-level schema property`,\n });\n }\n }\n });\n\n// =============================================================================\n// ARRAY SCHEMA — cross-status invariants\n// =============================================================================\n\nexport const kanbanStatusesArraySchema = z\n .array(kanbanStatusSchema)\n .max(MAX_KANBAN_STATUSES, `kanban_statuses must have at most ${MAX_KANBAN_STATUSES} entries`)\n .superRefine((statuses, ctx) => {\n if (statuses.length === 0) return;\n\n const initialIndices = statuses\n .map((s, i) => ({ s, i }))\n .filter(({ s }) => s.isInitialStatus === true);\n\n if (initialIndices.length === 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [],\n message: 'kanban_statuses: exactly one status must have isInitialStatus=true (found 0)',\n });\n } else if (initialIndices.length > 1) {\n const slugs = initialIndices.map(({ s }) => s.slug).join(', ');\n for (const { i } of initialIndices) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [i, 'isInitialStatus'],\n message: `kanban_statuses: only one status may have isInitialStatus=true (found ${initialIndices.length}: ${slugs})`,\n });\n }\n }\n\n // Unique slugs (slugs are the runtime identifier — duplicates corrupt routing).\n const seenSlugs = new Map<string, number[]>();\n statuses.forEach((s, i) => {\n const key = s.slug;\n if (!key) return;\n const arr = seenSlugs.get(key) ?? [];\n arr.push(i);\n seenSlugs.set(key, arr);\n });\n for (const [slug, indices] of seenSlugs) {\n if (indices.length > 1) {\n for (const i of indices) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [i, 'slug'],\n message: `kanban_statuses: duplicate slug \"${slug}\"`,\n });\n }\n }\n }\n\n // allowed_next_statuses entries must reference sibling slugs.\n const validSlugs = new Set(statuses.map((s) => s.slug).filter(Boolean));\n statuses.forEach((s, i) => {\n if (!Array.isArray(s.allowed_next_statuses)) return;\n s.allowed_next_statuses.forEach((target, j) => {\n if (typeof target !== 'string' || target.length === 0) return;\n if (!validSlugs.has(target)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [i, 'allowed_next_statuses', j],\n message: `kanban_statuses[${i}] (slug \"${s.slug}\"): allowed_next_statuses references unknown slug \"${target}\"`,\n });\n }\n });\n });\n });\n\n// =============================================================================\n// LINT — non-blocking warnings (returned alongside successful saves)\n// =============================================================================\n\nexport interface KanbanLintWarning {\n code: 'unreachable' | 'placeholder_unresolved';\n slug: string;\n name: string;\n message: string;\n}\n\n/**\n * Lint pass for kanban_statuses. Returns warnings that don't block save.\n *\n * - `unreachable`: a non-initial status that no other status lists in its\n * `allowed_next_statuses`. Conversations cannot reach it.\n * - `placeholder_unresolved`: an `{{path}}` placeholder in `additional_instructions`\n * that does not match any path in the declared `additional_context_schema`.\n *\n * Run after Zod validation succeeds; surface in the response so authors can\n * see warnings without being blocked mid-edit.\n */\nexport function lintKanbanStatuses(statuses: KanbanStatusInput[]): KanbanLintWarning[] {\n if (!Array.isArray(statuses) || statuses.length === 0) return [];\n\n const slugs = statuses.map((s) => s.slug).filter(Boolean);\n if (slugs.length === 0) return [];\n\n // -- Reachability ---------------------------------------------------------\n const allSlugs = new Set(slugs);\n const inboundFromAny = new Set<string>();\n const inboundExplicit = new Map<string, Set<string>>();\n\n for (const s of statuses) {\n if (!s.slug) continue;\n if (s.isTerminalStatus === true) continue;\n if (s.allowed_next_statuses === undefined) {\n for (const other of allSlugs) {\n if (other !== s.slug) inboundFromAny.add(other);\n }\n } else {\n for (const target of s.allowed_next_statuses) {\n if (!allSlugs.has(target)) continue;\n const set = inboundExplicit.get(target) ?? new Set<string>();\n set.add(s.slug);\n inboundExplicit.set(target, set);\n }\n }\n }\n\n const warnings: KanbanLintWarning[] = [];\n for (const s of statuses) {\n if (!s.slug) continue;\n if (s.isInitialStatus === true) continue;\n const hasInbound = inboundFromAny.has(s.slug) || (inboundExplicit.get(s.slug)?.size ?? 0) > 0;\n if (!hasInbound) {\n warnings.push({\n code: 'unreachable',\n slug: s.slug,\n name: s.name,\n message: `kanban status \"${s.slug}\" is unreachable — no other status transitions to it and it is not isInitialStatus`,\n });\n }\n }\n\n // -- Placeholder paths vs schema -----------------------------------------\n for (const s of statuses) {\n if (!s.slug || !s.additional_instructions) continue;\n const paths = extractPlaceholderPaths(s.additional_instructions);\n if (paths.length === 0) continue;\n const schema = s.additional_context_schema;\n for (const path of paths) {\n if (path === RESERVED_TEMPLATE_DUMP_NAME) continue;\n if (!schema || !isPathInJsonSchema(schema, path)) {\n warnings.push({\n code: 'placeholder_unresolved',\n slug: s.slug,\n name: s.name,\n message: `kanban status \"${s.slug}\": template placeholder \"{{${path}}}\" does not match any path in additional_context_schema`,\n });\n }\n }\n }\n\n return warnings;\n}\n\nfunction extractPlaceholderPaths(template: string): string[] {\n const out = new Set<string>();\n for (const match of template.matchAll(PLACEHOLDER_RE)) {\n out.add(match[1]);\n }\n return Array.from(out);\n}\n\n/**\n * Lint-side path resolver against a JSON Schema (Draft 2020-12 subset).\n * Walks `properties` for objects and `items` for arrays. Numeric segments\n * after an array indirect into `items`. Refs / oneOf / unknown shapes\n * return false (lint is best-effort; runtime renders empty string anyway).\n *\n * Treats an absent `type` as object-like when `properties` is present\n * (legal per JSON Schema spec — type is not required) and array-like when\n * `items` is present. Without these, schemas authored as raw YAML by CLI/MCP\n * users (who often omit `type`) would false-positive every placeholder.\n */\nfunction isPathInJsonSchema(schema: unknown, path: string): boolean {\n if (typeof schema !== 'object' || schema === null) return false;\n const segments = path.split('.');\n let cur: unknown = schema;\n for (const seg of segments) {\n if (typeof cur !== 'object' || cur === null) return false;\n const obj = cur as Record<string, unknown>;\n const propsObj = obj.properties && typeof obj.properties === 'object' ? (obj.properties as Record<string, unknown>) : null;\n const itemsObj = obj.items && typeof obj.items === 'object' ? (obj.items as Record<string, unknown>) : null;\n const isObjectLike = obj.type === 'object' || (obj.type === undefined && propsObj !== null);\n const isArrayLike = obj.type === 'array' || (obj.type === undefined && itemsObj !== null && propsObj === null);\n if (isObjectLike && propsObj) {\n if (!(seg in propsObj)) return false;\n cur = propsObj[seg];\n } else if (isArrayLike && itemsObj) {\n if (!/^\\d+$/.test(seg)) return false;\n cur = itemsObj;\n } else {\n return false;\n }\n }\n return true;\n}\n\n// =============================================================================\n// INFERRED TYPES\n// =============================================================================\n\nexport type FollowupInput = z.infer<typeof followupSchema>;\nexport type KanbanStatusInput = z.infer<typeof kanbanStatusSchema>;\nexport type KanbanStatusesInput = z.infer<typeof kanbanStatusesArraySchema>;\n","import { z } from 'zod';\nimport { uuidSchema } from '../common';\nimport type { AiMode } from '../../constants';\nimport { kanbanStatusesArraySchema, type KanbanLintWarning } from './kanban';\nimport { primaryRegionSchema, type PrimaryRegion, type PlacementSource } from './organizations';\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\n// Param schemas\nexport const hubIdParam = z.object({ id: uuidSchema });\nexport const hubAdminIdParam = z.object({ id: uuidSchema, adminId: uuidSchema });\nexport const hubUserIdParam = z.object({ id: uuidSchema, hubUserId: uuidSchema });\nexport const hubIdentityIdParam = z.object({ id: uuidSchema, identityId: uuidSchema });\nexport const hubTeamIdParam = z.object({ id: uuidSchema, teamId: uuidSchema });\nexport const hubTeamUserDeleteParam = z.object({ id: uuidSchema, teamUserId: uuidSchema });\n// Query schemas\nexport const hubSchemaQuery = z.object({ hub_id: uuidSchema });\n\n// Body schemas\nexport const createHubBody = z.object({\n organization_id: uuidSchema,\n hub_name: z.string().min(1, 'hub_name is required'),\n hub_description: z.string().optional(),\n kanban_statuses: kanbanStatusesArraySchema.nullable().optional(),\n // Write-once at creation; updateHubBody does not accept this.\n primary_region: primaryRegionSchema.optional(),\n}).passthrough();\n\n// Enum fields validated; other fields pass through to the backend updateHub() allowlist.\nexport const updateHubBody = z.object({\n support_model: z.enum(['conversation', 'account']).optional(),\n unassigned_policy: z\n .enum(['default_team', 'auto_assign_random', 'auto_assign_round_robin', 'pull_queue'])\n .optional(),\n default_hub_team_id: uuidSchema.nullable().optional(),\n kanban_statuses: kanbanStatusesArraySchema.nullable().optional(),\n // summarization_threshold_tokens relocated to the summarizer AGENT (PR4) — validated/\n // persisted via the agent path (.passthrough() agent body → HubDO column), not here.\n auto_close_inactive_days: z.number().int().min(1).max(180).optional(),\n // Channel contact access control. Enum-validated explicitly (not via passthrough)\n // so `language`/`access_approval_role` can't reach the DB with an invalid value.\n language: z.enum(['en', 'pt', 'es']).optional(),\n access_request_message: z.string().max(1000).nullable().optional(),\n access_approval_role: z.enum(['admin', 'team']).optional(),\n}).passthrough();\n\nexport const addHubAdminBody = z.object({\n user_email: z.string().email('valid email is required'),\n});\n\nexport const addHubIdentityAuthorizationBody = z.object({\n identity_value: z.string().min(1),\n identity_type: z.string().min(1),\n channel_type: z.string().min(1),\n});\n\n// Channel contact access control: approve / block / unblock a contact. The row is\n// located by `contact_access_id` OR the (identity_type, identity_value, channel_type)\n// tuple; block/unblock may also carry the conversation's user_id so open conversations\n// can be transitioned even before a contact_access row exists (block on `everyone`).\nexport const contactDecisionBody = z.object({\n contact_access_id: uuidSchema.optional(),\n identity_type: z.string().min(1).optional(),\n identity_value: z.string().min(1).optional(),\n channel_type: z.string().min(1).optional(),\n channel_id: uuidSchema.optional(),\n connection_id: uuidSchema.optional(),\n user_id: uuidSchema.optional(),\n sender_display_name: z.string().max(200).optional(),\n});\n\nexport const approveContactBody = contactDecisionBody.extend({\n user_name: z.string().min(1).max(120).optional(),\n});\n\nexport const listContactAccessQuery = z.object({\n status: z.enum(['pending', 'blocked']).optional(),\n});\n\nexport const createHubTeamBody = z.object({\n team_name: z.string().min(1, 'team_name is required'),\n});\n\nexport const updateHubTeamBody = z.object({\n team_name: z.string().min(1).optional(),\n}).passthrough();\n\nexport const addHubTeamUserBody = z.object({\n user_email: z.string().email('valid email is required'),\n});\n\n/** Account-mode: reassign a hub_user to a different team (or clear via null). */\nexport const reassignHubUserBody = z.object({\n hub_team_id: uuidSchema.nullable(),\n});\n\nexport const replicatePreviewBody = z.object({\n preview_label: z\n .string()\n .max(60)\n .optional()\n .nullable()\n .transform((v) => {\n if (v == null) return null;\n const trimmed = v.trim();\n return trimmed || null;\n }),\n});\n\n// =============================================================================\n// INFERRED TYPES (for consumers that need request types without importing zod)\n// =============================================================================\n\nexport type CreateHubInput = z.infer<typeof createHubBody>;\nexport type UpdateHubInput = z.infer<typeof updateHubBody>;\nexport type AddHubAdminInput = z.infer<typeof addHubAdminBody>;\nexport type AddHubIdentityAuthorizationInput = z.infer<typeof addHubIdentityAuthorizationBody>;\nexport type ContactDecisionInput = z.infer<typeof contactDecisionBody>;\nexport type ApproveContactInput = z.infer<typeof approveContactBody>;\nexport type ListContactAccessQuery = z.infer<typeof listContactAccessQuery>;\nexport type CreateHubTeamInput = z.infer<typeof createHubTeamBody>;\nexport type UpdateHubTeamInput = z.infer<typeof updateHubTeamBody>;\nexport type AddHubTeamUserInput = z.infer<typeof addHubTeamUserBody>;\nexport type ReplicatePreviewInput = z.infer<typeof replicatePreviewBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n// --- Hub entity responses ---\n\n/** Resolves a hub_id to its owning organization (used by direct-link redirect). */\nexport interface GetHubOrganizationResponse {\n data: {\n hub_id: string;\n organization_id: string;\n };\n}\n\n/** Organization nested inside a hub join. */\nexport interface HubListOrganizationResponse {\n organization_id: string;\n name: string;\n}\n\n// --- Channel contact access control responses ---\n\n/** approve / block / unblock result (HubDO ContactTransitionResult, success branch). */\nexport interface ContactTransitionResult {\n ok: true;\n user_id: string | null;\n conversation_ids: string[];\n next_access_status: 'approved' | 'pending' | 'blocked';\n hub_user_id?: string;\n identity_type?: string;\n identity_value?: string;\n channel_type?: string;\n}\n\nexport interface ContactDecisionResponse {\n data: ContactTransitionResult;\n}\n\n/** A contact_access row (pending / blocked) for the admin review surface. */\nexport interface ContactAccessRowResponse {\n contact_access_id: string;\n channel_id: string | null;\n connection_id: string | null;\n identity_type: string;\n identity_value: string;\n channel_type: string;\n user_id: string | null;\n status: 'pending' | 'blocked';\n sender_display_name: string | null;\n last_message_preview: string | null;\n notified_at: string | null;\n requested_at: string;\n last_seen_at: string;\n decided_at: string | null;\n decided_by_user_id: string | null;\n}\n\nexport interface ListContactAccessResponse {\n data: { contacts: ContactAccessRowResponse[] };\n}\n\n/** Hub row as returned by list hubs (subset with joined organization). */\nexport interface HubListItemResponse {\n hub_id: string;\n name: string;\n description: string | null;\n created_at: string;\n organization: HubListOrganizationResponse | HubListOrganizationResponse[] | null;\n}\n\n/** Full hub row as returned by get hub by ID. */\nexport interface HubResponse {\n hub_id: string;\n created_at: string;\n updated_at: string;\n hub_name: string;\n hub_type: string;\n hub_description: string | null;\n ai_mode: AiMode;\n non_app_permission: string;\n created_by: string;\n hub_contexts: string[] | null;\n hub_course_name: string | null;\n is_platform_hub: boolean;\n template_id: string;\n kanban_statuses: Record<string, unknown>[] | null;\n timezone: string | null;\n mcp_access: string;\n hub_environment: string;\n production_hub_id: string | null;\n branch_name: string | null;\n last_ci_activity_at: string | null;\n ci_commit_sha: string | null;\n preview_label: string | null;\n is_support_hub: boolean;\n support_model: 'conversation' | 'account';\n unassigned_policy: 'default_team' | 'auto_assign_random' | 'auto_assign_round_robin' | 'pull_queue';\n default_hub_team_id: string | null;\n welcome_message: string | null;\n storage_retention_months: number | null;\n // flag_conditions relocated to the conversation_evaluator AGENT (AgentResponse.flag_conditions).\n // summarization_threshold_tokens relocated to the summarizer AGENT (AgentResponse.summarization_threshold_tokens).\n // monitor_config relocated to the monitor AGENT (AgentResponse.monitor_config).\n auto_close_inactive_days: number;\n tags: string[];\n holidays: string[] | null;\n org_id: string;\n primary_region: PrimaryRegion | null;\n placement_region: PrimaryRegion | null;\n placement_source: PlacementSource | null;\n}\n\n// --- Hub admin user ---\n\nexport interface HubAdminUserResponse {\n hub_admin_user_id: string;\n hub_id: string;\n created_at: string;\n user_id: string | null;\n enabled: boolean;\n user_email: string;\n}\n\n// --- Hub user ---\n\nexport interface HubUserResponse {\n hub_user_id: string;\n hub_id: string;\n created_at: string;\n updated_at: string;\n user_id: string;\n user_name: string | null;\n user_email: string | null;\n enabled: boolean;\n /** Account-mode: the team that owns this end user (\"the account\"). */\n hub_team_id: string | null;\n /** 'grant' = pre-authorized access row. 'auto' = created on inbound in account-mode hubs (no platform access). */\n source: 'grant' | 'auto';\n}\n\n/** Hub user with linked identities (as returned by fetchHubById). */\nexport interface HubUserWithIdentitiesResponse extends HubUserResponse {\n identities: HubUserLinkedIdentityResponse[];\n}\n\nexport interface HubUserLinkedIdentityResponse {\n hub_user_identity_id: string;\n identity_value: string;\n identity_type: string;\n channel_type: string;\n user_identity_id: string | null;\n}\n\n// --- Hub user identity (pre-authorized) ---\n\nexport interface HubUserIdentityResponse {\n hub_user_identity_id: string;\n hub_user_id: string | null;\n user_identity_id: string | null;\n identity_value: string;\n identity_type: string;\n channel_type: string;\n created_at: string;\n updated_at: string;\n hub_id: string;\n}\n\n// --- Hub team ---\n\nexport interface HubTeamResponse {\n hub_team_id: string;\n created_at: string;\n team_name: string;\n hub_id: string;\n conversation_display_only_if_claimed: boolean;\n team_access_rule: string;\n initial_team: boolean | null;\n}\n\n/** Team with nested team users (as returned by fetchHubById). */\nexport interface HubTeamWithUsersResponse extends HubTeamResponse {\n team_users: HubTeamUserResponse[];\n}\n\n// --- Hub team user ---\n\nexport interface HubTeamUserResponse {\n hub_team_user_id: string;\n hub_team_id: string;\n created_at: string;\n user_id: string | null;\n enabled: boolean;\n user_email: string;\n}\n\n// --- Composite hub responses ---\n\n/** GET /:id — hub with agents, connections, tools. */\nexport interface GetHubResponse {\n data: HubResponse & {\n agents: Record<string, unknown>[];\n connections: Record<string, unknown>[];\n tools: Record<string, unknown>[];\n };\n}\n\n/** GET /:id/users — hub with admin users, hub users, teams, pre-authorized identities. */\nexport interface GetHubUsersResponse {\n data: {\n hub: HubResponse;\n admin_users: HubAdminUserResponse[];\n users: HubUserWithIdentitiesResponse[];\n pre_authorized_identities: HubUserIdentityResponse[];\n teams: HubTeamWithUsersResponse[];\n };\n}\n\n/** GET / — list of hubs. */\nexport interface ListHubsResponse {\n data: HubListItemResponse[];\n}\n\n/** POST / — create hub returns array with single hub plus optional kanban warnings. */\nexport interface CreateHubResponse {\n data: HubResponse[];\n /** Non-blocking lint warnings (e.g. unreachable kanban statuses). Empty when no warnings apply. */\n warnings?: KanbanLintWarning[];\n}\n\n/** PATCH /:id — update hub returns array with single hub plus optional kanban warnings. */\nexport interface UpdateHubResponse {\n data: HubResponse[];\n warnings?: KanbanLintWarning[];\n}\n\n// --- Hub admin user operations ---\n\nexport interface AddHubAdminResponse {\n data: HubAdminUserResponse[];\n}\n\n// --- Hub user identity operations ---\n\nexport interface AddHubIdentityAuthorizationResponse {\n data: HubUserIdentityResponse[];\n}\n\n// --- Hub team operations ---\n\nexport interface CreateHubTeamResponse {\n data: HubTeamResponse[];\n}\n\nexport interface UpdateHubTeamResponse {\n data: HubTeamResponse[];\n}\n\n// --- Hub team user operations ---\n\nexport interface AddHubTeamUserResponse {\n data: HubTeamUserResponse[];\n}\n\n// --- Hub branching responses ---\n\n/** GET /:id/diff */\nexport interface DiffEntry {\n name: string;\n type?: string;\n status: 'added' | 'removed' | 'updated';\n}\n\nexport interface HubDiffResult {\n has_changes: boolean;\n is_first_publish: boolean;\n hub_changed: boolean;\n agents: DiffEntry[];\n connections: DiffEntry[];\n tools: DiffEntry[];\n channels: DiffEntry[];\n states: DiffEntry[];\n resources: DiffEntry[];\n}\n\nexport interface GetHubDiffResponse {\n data: HubDiffResult;\n}\n\n/** POST /:id/publish */\nexport interface PublishHubResponse {\n data: {\n production_hub_id: string;\n };\n}\n\n/** POST /:id/sync */\nexport interface SyncHubResponse {\n data: {\n synced: boolean;\n };\n}\n\n/** POST /:id/replicate-preview */\nexport interface ReplicatePreviewHubResponse {\n data: {\n preview_hub_id: string;\n };\n}\n\n// --- Hub schema response ---\n\nexport interface HubSchemaAgentToolResponse {\n tool_id: string;\n tool_name: string;\n tool_description: string | null;\n is_native: boolean;\n enabled: boolean;\n tool_group: string | null;\n tool_native_id: string | null;\n connector_id: string | null;\n connector_name: string | null;\n}\n\nexport interface HubSchemaAgentResponse {\n agent_id: string;\n agent_name: string;\n agent_role: string | null;\n agent_settings: unknown;\n instructions: string | null;\n tools: HubSchemaAgentToolResponse[];\n}\n\nexport interface HubSchemaConnectionResponse {\n connection_id: string;\n connection_display_name: string;\n connector_id: string | null;\n connector_name: string | null;\n connector_type: string;\n connector_description: string | null;\n enabled: boolean;\n}\n\nexport interface HubSchemaNativeToolInstallationResponse {\n agent_id: string;\n tool_id: string;\n enabled: boolean;\n}\n\nexport interface HubSchemaNativeToolResponse {\n tool_native_id: string;\n tool_name: string;\n tool_description: string | null;\n is_delegation: boolean;\n installations: HubSchemaNativeToolInstallationResponse[];\n}\n\nexport interface HubSchemaTeamResponse {\n hub_team_id: string;\n team_name: string;\n team_access_rule: string;\n initial_team: boolean;\n conversation_display_only_if_claimed: boolean;\n}\n\nexport interface HubSchemaHubResponse {\n hub_id: string;\n hub_name: string;\n hub_description: string | null;\n ai_mode: AiMode | null;\n created_at: string;\n}\n\nexport interface GetHubSchemaResponse {\n data: {\n hub: HubSchemaHubResponse;\n agents: HubSchemaAgentResponse[];\n connections: HubSchemaConnectionResponse[];\n teams: HubSchemaTeamResponse[];\n native_tools: HubSchemaNativeToolResponse[];\n };\n}\n\n// --- Claim codes (preview hub tester registration) ---\n\nexport const claimCodeChannelParam = z.object({\n id: uuidSchema,\n channelId: uuidSchema,\n});\nexport type ClaimCodeChannelParam = z.infer<typeof claimCodeChannelParam>;\n\nexport const claimCodeDeleteParam = z.object({\n id: uuidSchema,\n channelId: uuidSchema,\n code: z.string().regex(/^[A-Za-z0-9]{6}$/, 'Invalid claim code format').transform((s) => s.toUpperCase()),\n});\nexport type ClaimCodeDeleteParam = z.infer<typeof claimCodeDeleteParam>;\n\nexport interface ClaimCodeSummaryResponse {\n code: string;\n created_at: string;\n created_by: string;\n}\n\nexport interface GenerateClaimCodeResponse {\n data: {\n code: string;\n expires_at: string;\n channel_type: string;\n };\n}\n\nexport interface ListClaimCodesResponse {\n data: {\n codes: ClaimCodeSummaryResponse[];\n };\n}\n\n// --- User + Hub schema responses (scoped fetches for Settings) ---\n\ninterface SchemaEntityItem {\n id: string;\n name: string;\n [key: string]: unknown;\n}\n\n/** GET /api/setup/user-schema — orgs + hubs hierarchy, no agents/tools. */\nexport interface GetUserSchemaResponse {\n data: {\n connectors: unknown[];\n native_tools: unknown[];\n flat: {\n organizations: SchemaEntityItem[];\n hubsByOrg: Record<string, SchemaEntityItem[]>;\n };\n lastUpdated: string;\n };\n}\n\n/** GET /api/setup/hub-schema/:hubId — agents + tools + states for a single hub. */\nexport interface GetHubDetailSchemaResponse {\n data: {\n hub_id: string;\n agents: SchemaEntityItem[];\n toolsByAgent: Record<string, SchemaEntityItem[]>;\n states: SchemaEntityItem[];\n };\n}\n","import { z } from 'zod';\nimport { uuidSchema } from '../common';\nimport type { Connector } from '../../catalog/types';\n\nexport const connectionIdParam = z.object({ id: uuidSchema });\nexport const connectorIdParam = z.object({ id: uuidSchema });\n\nexport const listConnectionsQuery = z.object({ hub_id: uuidSchema });\n\nexport const deleteConnectionQuery = z.object({ hub_id: uuidSchema });\n\nexport const addConnectionBody = z.object({\n hub_id: uuidSchema,\n connector_id: uuidSchema,\n authentication_type: z.string().optional(),\n inbound_mode: z.enum(['wayai', 'resend']).optional(),\n inbound_address: z.string().email().optional(),\n}).passthrough().superRefine((data, ctx) => {\n if (data.inbound_mode === 'resend' && !data.inbound_address) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Receiving email address is required when using Resend inbound mode',\n path: ['inbound_address'],\n });\n }\n});\n\nexport const editConnectionBody = z.object({\n hub_id: uuidSchema,\n}).passthrough();\n\nexport const registerWhatsappQuery = z.object({ hub_id: uuidSchema });\n\nexport const registerWhatsappBody = z.object({\n pin: z.string().optional(),\n});\n\nexport type AddConnectionInput = z.infer<typeof addConnectionBody>;\nexport type EditConnectionInput = z.infer<typeof editConnectionBody>;\nexport type RegisterWhatsappInput = z.infer<typeof registerWhatsappBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n/** Single connection item as returned by the `get_connections` RPC. */\nexport interface ConnectionItemResponse {\n connection_id: string | null;\n hub_id: string;\n account_sid: string | null;\n connection_display_name: string | null;\n username: string | null;\n state: Record<string, unknown> | null;\n settings: Record<string, unknown> | null;\n organization_credential_id: string | null;\n organization_credential_token_id: string | null;\n connector_id: string;\n connector_name: string;\n connector_type: string;\n service_name: string;\n authentication_type: string;\n authentication_types: string[];\n unique_per_hub: boolean;\n account_sid_placeholder: string | null;\n init_endpoint: string | null;\n connector_credential_schema: Record<string, unknown> | null;\n connector_settings_schema: Record<string, unknown> | null;\n agent_settings_schema: Record<string, unknown> | null;\n available_action: 'Add' | 'Edit' | 'Remove' | 'Enable' | 'Disable';\n enabled: boolean;\n base_url: string | null;\n connection_headers: Record<string, unknown> | null;\n}\n\n/** Full connection row with nested connector, returned by GET /connections/:id. */\nexport interface ConnectionWithConnectorResponse {\n connection_id: string;\n created_at: string;\n service_name: string | null;\n api_key: string | null;\n updated_at: string | null;\n hub_id: string;\n access_token: string | null;\n access_token_expires_at: string | null;\n access_token_secret_id: string | null;\n account_sid: string | null;\n api_key_secret_id: string | null;\n authentication_type: string;\n enabled: boolean;\n connector_id: string;\n connector_name: string;\n password: string | null;\n password_secret_id: string | null;\n connection_display_name: string | null;\n connector_type: string;\n refresh_token: string | null;\n refresh_token_expires_at: string | null;\n refresh_token_secret_id: string | null;\n state: Record<string, unknown> | null;\n username: string | null;\n base_url: string | null;\n connection_headers: Record<string, unknown> | null;\n settings: Record<string, unknown> | null;\n token_refresh_config: Record<string, unknown> | null;\n next_access_token_refresh_at: string | null;\n next_refresh_token_renewal_at: string | null;\n last_token_refresh_at: string | null;\n last_token_refresh_error: string | null;\n organization_credential_id: string | null;\n organization_credential_token_id: string | null;\n available_action: 'Add' | 'Edit' | 'Remove' | 'Enable' | 'Disable';\n connector_credential_schema: Record<string, unknown> | null;\n connector_settings_schema: Record<string, unknown> | null;\n agent_settings_schema: Record<string, unknown> | null;\n connector: ConnectorResponse;\n}\n\n/** Connector row returned by GET /connectors/:id and as nested data. */\nexport type ConnectorResponse = Connector;\n\n/** GET /connections?hub_id=... */\nexport interface ListConnectionsResponse {\n connections: ConnectionItemResponse[];\n}\n\n/** GET /connections/:id */\nexport interface GetConnectionResponse {\n data: ConnectionWithConnectorResponse;\n}\n\n/** POST /connections (add connection — may return OAuth redirect) */\nexport interface AddConnectionResponse {\n connections: ConnectionItemResponse[];\n warnings?: string[];\n oauth_url?: string;\n state?: string;\n}\n\n/** PATCH /connections/:id (edit connection) */\nexport interface EditConnectionResponse {\n connections: ConnectionItemResponse[];\n warnings?: string[];\n}\n\n/** POST /connections/:id/enable */\nexport interface EnableConnectionResponse {\n connections: ConnectionItemResponse[];\n warnings?: string[];\n}\n\n/** POST /connections/:id/disable */\nexport interface DisableConnectionResponse {\n connections: ConnectionItemResponse[];\n}\n\n/** DELETE /connections/:id */\nexport interface DeleteConnectionResponse {\n connections: ConnectionItemResponse[];\n}\n\n/** GET /connections/:id/channel-info */\nexport interface ChannelInfoResponse {\n channel: Record<string, unknown> | null;\n connection: Record<string, unknown>;\n}\n\n/** POST /connections/:id/sync-mcp */\nexport interface SyncMcpConnectionResponse {\n success: boolean;\n tools_count?: number;\n resources_count?: number;\n message?: string;\n warnings?: string[];\n}\n\n/** POST /connections/:id/register-whatsapp */\nexport interface RegisterWhatsappResponse {\n success: boolean;\n message?: string;\n error?: string;\n}\n\n/** GET /connectors/:id */\nexport interface GetConnectorResponse {\n data: ConnectorResponse;\n}\n\n// =============================================================================\n// ASYNC PROVISIONING RETRY\n// =============================================================================\n\n/** POST /connections/:id/retry-provisioning — query */\nexport const retryProvisioningQuery = z.object({ hub_id: uuidSchema });\n\n/** POST /connections/:id/retry-provisioning — response */\nexport interface RetryProvisioningResponse {\n success: true;\n connection_id: string;\n}\n\n// =============================================================================\n// RESEND DOMAIN VERIFICATION\n// =============================================================================\n\nexport const resendDomainStatusQuery = z.object({ hub_id: uuidSchema });\n\nexport interface ResendDnsRecord {\n record: string;\n name: string;\n type: string;\n ttl: string;\n status: string;\n value: string;\n priority?: number;\n}\n\n/** GET /connections/:id/domain-status */\nexport interface ResendDomainStatusResponse {\n verified: boolean;\n domain_id: string | null;\n domain_name: string | null;\n status: string;\n records: ResendDnsRecord[];\n inbound_address: string | null;\n inbound_mode: 'wayai' | 'resend' | null;\n}\n\n/** POST /connections/:id/verify-domain */\nexport interface ResendVerifyDomainResponse {\n domain_id: string;\n status: string;\n}\n","import { z } from 'zod';\nimport { uuidSchema } from '../common';\nimport {\n validateToolInputSchema,\n containsKanbanPlaceholders,\n extractToolParameters,\n} from '../../tool-schema-validator';\n\n/**\n * Configure-time guard for `tool_config.parameters` on REST custom-tool\n * routes (gh #1542). Adds draft-2020-12 violations to the Zod context so the\n * Hono handler emits a 400 with structured messages before we cross the\n * HubDO boundary. The HubDO chokepoint re-validates as defense in depth.\n *\n * IMPORTANT: unresolved `[KANBAN_STATUS_*]` placeholder tokens are SKIPPED\n * here. They would otherwise block legitimate template pushes — the chokepoint\n * renders them first, then validates.\n */\nfunction refineToolConfig(value: Record<string, unknown>, ctx: z.RefinementCtx): void {\n const raw = value.tool_config;\n if (raw == null) return;\n\n const params = extractToolParameters(raw);\n if (params === undefined) {\n // Either tool_config is not an object shape, or there's no `parameters`\n // field to validate. Only the former is an error.\n const looksLikeObject = raw !== null\n && typeof raw === 'object'\n && !Array.isArray(raw)\n || (typeof raw === 'string' && (() => {\n try { const parsed = JSON.parse(raw); return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed); }\n catch { return false; }\n })());\n if (!looksLikeObject) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['tool_config'],\n message: 'tool_config must be an object',\n });\n }\n return;\n }\n\n if (containsKanbanPlaceholders(params)) return;\n\n const result = validateToolInputSchema(params);\n if (!result.ok) {\n for (const err of result.errors) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['tool_config', 'parameters', ...err.path.split('.').filter(Boolean)],\n message: err.suggestion ? `${err.message} — ${err.suggestion}` : err.message,\n });\n }\n }\n}\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\nexport const toolIdParam = z.object({ id: uuidSchema });\n\nexport const listToolsQuery = z.object({ agent_id: uuidSchema, hub_id: uuidSchema });\n\nexport const toolAgentQuery = z.object({ agent_id: uuidSchema, hub_id: uuidSchema });\n\nexport const deleteToolQuery = z.object({ agent_id: uuidSchema.optional(), hub_id: uuidSchema });\n\nexport const toolConnectionsQuery = z.object({ hub_id: uuidSchema });\n\nexport const nativeToolIdSchema = z.string().regex(/^nt-\\d{3,}$/, 'Invalid native tool id');\n\nexport const addNativeToolBody = z.object({\n agent_id: uuidSchema,\n hub_id: uuidSchema,\n tool_native_id: nativeToolIdSchema,\n delegation_type: z.enum(['team', 'agent']).optional(),\n delegation_id: z.string().optional(),\n delegation_name: z.string().optional(),\n resource_config: z.object({\n access_mode: z.enum(['all', 'selected', 'none']),\n enabled_resources: z.array(z.string()).optional(),\n }).optional(),\n});\n\nexport const addMcpToolBody = z.object({\n agent_id: uuidSchema,\n hub_id: uuidSchema,\n mcp_tool_id: uuidSchema,\n});\n\nexport const createCustomToolBody = z.object({\n agent_id: uuidSchema,\n hub_id: uuidSchema,\n}).passthrough().superRefine(refineToolConfig);\n\nexport const updateCustomToolBody = z.object({\n hub_id: uuidSchema.optional(),\n}).passthrough().superRefine(refineToolConfig);\n\nexport const updateToolExecutionConfigBody = z.object({\n agent_id: uuidSchema,\n hub_id: uuidSchema,\n execution_config: z.object({\n keep_in_history: z.boolean().optional(),\n }).nullable(),\n});\n\nexport function resolveKeepInHistory(\n ec: { keep_in_history?: boolean } | null | undefined,\n): boolean {\n return ec?.keep_in_history === true;\n}\n\n/** Coerce a SQL `keep_in_history` value (0|1|null|boolean) to the \"kept\" boolean. */\nexport function isMessageKept(v: number | boolean | null | undefined): boolean {\n return v !== 0 && v !== false;\n}\n\n/** Coerce an optional boolean `keep_in_history` to the SQL integer value (default = kept). */\nexport function keepInHistoryToInt(v: boolean | undefined | null): 0 | 1 {\n return v === false ? 0 : 1;\n}\n\n// =============================================================================\n// INFERRED TYPES\n// =============================================================================\n\nexport type AddNativeToolInput = z.infer<typeof addNativeToolBody>;\nexport type AddMcpToolInput = z.infer<typeof addMcpToolBody>;\nexport type CreateCustomToolInput = z.infer<typeof createCustomToolBody>;\nexport type UpdateToolExecutionConfigInput = z.infer<typeof updateToolExecutionConfigBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n/** A native tool item as returned by the get_native_tools RPC */\nexport interface NativeToolResponse {\n tool_id: string | null;\n tool_display_name: string;\n tool_name: string;\n tool_description: string | null;\n tool_config: Record<string, unknown> | null;\n enabled: boolean | null;\n is_native: boolean;\n operation: string | null;\n created_at: string;\n available_action: 'Add' | 'Enable' | 'Disable';\n tool_native_id: string | null;\n connection_display_name: string;\n connector_name: string;\n is_delegation: boolean;\n tool_group: string;\n keep_in_history: boolean;\n}\n\n/** An MCP external tool item as returned by the get_native_tools RPC */\nexport interface McpToolResponse {\n // Installed-only fields (the \"Add\" catalog branch of getNativeTools omits\n // them); mirrors the optionality of the frontend MCPTool type.\n tool_id?: string | null;\n mcp_tool_id: string;\n tool_display_name: string;\n tool_name: string;\n tool_description: string | null;\n // The LLM function-spec rendered LIVE from the `mcp_tool` catalog (source of\n // truth), not the frozen assignment snapshot — what the agent actually\n // receives (report 1876b8be).\n tool_config?: Record<string, unknown> | null;\n /** When the catalog row was last refreshed by `sync-mcp` (`mcp_tool.updated_at`),\n * surfaced as a \"last synced\" indicator. */\n synced_at?: string | null;\n enabled?: boolean | null;\n created_at?: string;\n available_action: 'Add' | 'Enable' | 'Disable';\n connection_display_name: string;\n connection_id: string;\n keep_in_history?: boolean;\n}\n\n/** A delegation entity (team or agent) */\nexport interface DelegationEntityResponse {\n id: string;\n name: string;\n type: string;\n}\n\n/** A resource available for tool configuration */\nexport interface ToolResourceResponse {\n resource_id: string;\n resource_name: string;\n resource_description: string | null;\n hub_id: string;\n}\n\n/** Full response from the get_native_tools RPC (list tools endpoint) */\nexport interface ListToolsResponse {\n tools: NativeToolResponse[];\n mcp_tools: McpToolResponse[];\n available_delegation_teams: DelegationEntityResponse[];\n available_delegation_agents: DelegationEntityResponse[];\n available_consultant_agents: DelegationEntityResponse[];\n available_resources: ToolResourceResponse[];\n}\n\n/** Tool row as stored in the database */\nexport interface ToolRowResponse {\n tool_id: string;\n created_at: string;\n tool_method: string | null;\n connection_id: string;\n tool_display_name: string;\n hub_id: string;\n agent_id: string;\n delegated_agent_id: string | null;\n delegated_hub_team_id: string | null;\n enabled: boolean;\n tool_description: string | null;\n tool_group: string;\n tool_headers: Record<string, unknown> | null;\n tool_name: string | null;\n tool_native_id: string | null;\n tool_path: string | null;\n is_native: boolean;\n operation: string | null;\n is_delegation: boolean;\n updated_at: string | null;\n tool_config: Record<string, unknown>;\n tool_instructions: string | null;\n resource_config: Record<string, unknown> | null;\n additional_body_params: Record<string, unknown> | null;\n tool_query_params: Record<string, unknown> | null;\n mcp_tool_id: string | null;\n composed_tools: Array<{\n tool_name: string;\n mappings: Record<string, string | { source: string; type?: string; description?: string }>;\n appended_description?: string;\n success_path?: string;\n }> | null;\n execution_config: Record<string, unknown> | null;\n tool_body_format: string;\n expose_schema_to_llm: boolean;\n}\n\n/** Agent row shape used in tool get-by-id join */\nexport interface ToolAgentResponse {\n agent_id: string;\n agent_name: string;\n created_at: string;\n agent_sid: string | null;\n instructions: string;\n response_format: string;\n updated_at: string | null;\n hub_id: string;\n connection_id: string;\n agent_role: string;\n schema_json: Record<string, unknown> | null;\n schema_name: string | null;\n agent_settings: Record<string, unknown> | null;\n instructions_file_id: string | null;\n enabled: boolean;\n include_message_timestamps: boolean;\n}\n\n/** Native tool row shape used in tool get-by-id join */\nexport interface ToolNativeResponse {\n tool_native_id: string;\n created_at: string;\n tool_display_name: string;\n operation: string;\n tool_method: string;\n tool_description: string;\n tool_name: string;\n connector_id: string;\n tool_group: string;\n is_delegation: boolean;\n is_auto_set: boolean;\n tool_config: Record<string, unknown> | null;\n tool_instructions: string | null;\n execution_config: Record<string, unknown> | null;\n}\n\n/** Connection row shape used in tool get-by-id join */\nexport interface ToolConnectionResponse {\n connection_id: string;\n created_at: string;\n service_name: string | null;\n api_key: string | null;\n updated_at: string | null;\n hub_id: string;\n access_token: string | null;\n access_token_expires_at: string | null;\n access_token_secret_id: string | null;\n account_sid: string | null;\n api_key_secret_id: string | null;\n authentication_type: string;\n enabled: boolean;\n connector_id: string;\n connector_name: string;\n password: string | null;\n password_secret_id: string | null;\n connection_display_name: string | null;\n connector_type: string;\n refresh_token: string | null;\n refresh_token_expires_at: string | null;\n refresh_token_secret_id: string | null;\n state: Record<string, unknown> | null;\n username: string | null;\n base_url: string | null;\n connection_headers: Record<string, unknown> | null;\n settings: Record<string, unknown> | null;\n token_refresh_config: Record<string, unknown> | null;\n next_access_token_refresh_at: string | null;\n next_refresh_token_renewal_at: string | null;\n last_token_refresh_at: string | null;\n last_token_refresh_error: string | null;\n organization_credential_id: string | null;\n}\n\n/** Response for GET /tools/:id */\nexport interface GetToolResponse {\n data: {\n tool: ToolRowResponse & {\n agent: ToolAgentResponse;\n native_tool: ToolNativeResponse | null;\n connection: ToolConnectionResponse;\n };\n };\n}\n\n/** Connector subset in tool connections response */\nexport interface ToolConnectionConnectorResponse {\n connector_type: string;\n connector_name: string;\n}\n\n/** Connection item in the tool connections list */\nexport interface ToolConnectionItemResponse {\n connection_id: string;\n connector_name: string;\n connection_display_name: string | null;\n enabled: boolean;\n connector: ToolConnectionConnectorResponse;\n}\n\n/** Response for GET /tools/connections */\nexport interface ListToolConnectionsResponse {\n data: ToolConnectionItemResponse[];\n}\n\n/** Response for POST /tools/native (add native tool) */\nexport interface AddNativeToolResponse {\n data: Record<string, unknown>;\n}\n\n/** Response for POST /tools/mcp (add MCP tool) */\nexport interface AddMcpToolResponse {\n data: Record<string, unknown>;\n}\n\n/** Response for POST /tools/custom (create custom tool) */\nexport interface CreateCustomToolResponse {\n data: ToolRowResponse[];\n}\n\n/** Response for PATCH /tools/:id (update custom tool) */\nexport interface UpdateCustomToolResponse {\n data: ToolRowResponse[];\n}\n\n/** Response for DELETE /tools/:id without agent_id */\nexport interface DeleteToolResponse {\n ok: true;\n}\n","/**\n * Minimal JSON Schema draft 2020-12 linter for LLM tool `input_schema`.\n *\n * Targets the failure modes we've seen Anthropic reject in practice, not\n * full spec conformance. A permissive `ajv` build ships ~40KB gzipped and\n * fights Workers' eval restrictions; a hand-rolled linter tailored to the\n * ~8 observed violations gives better error messages at ~3KB with no deps.\n *\n * Used by:\n * - Zod `superRefine` on tool CRUD contracts (configure-time gate)\n * - HubDO `createTool`/`updateTool` (defense-in-depth at the write boundary)\n * - `buildAgentSettings.buildAgentToolsForLLM` (runtime drop — logs error,\n * does not throw)\n *\n * Pure — no side effects.\n */\n\nexport const PLACEHOLDER_TOKENS = [\n '[KANBAN_STATUS_VALUES]',\n '[KANBAN_STATUS_NAMES]',\n '[SCHEDULING_STATUS_NAMES]',\n '[STATE_SLUG_VALUES]',\n] as const;\n\n/**\n * True if `value` serializes to a JSON blob containing any kanban placeholder\n * token. Callers use this to skip strict JSON Schema validation on template\n * configs that the HubDO chokepoint will render before validating.\n */\nexport function containsKanbanPlaceholders(value: unknown): boolean {\n if (value == null) return false;\n const serialized = typeof value === 'string' ? value : JSON.stringify(value);\n for (const token of PLACEHOLDER_TOKENS) {\n if (serialized.includes(token)) return true;\n }\n return false;\n}\n\n/**\n * Parse a `tool_config` (object or JSON string) and return its `parameters`\n * field, or `undefined` if the config isn't a non-array object or doesn't\n * carry one. Shared by the HubDO chokepoint and both zod `superRefine`s so\n * they all agree on what \"has a schema to validate\" means.\n */\nexport function extractToolParameters(toolConfig: unknown): unknown {\n let cfg: unknown = toolConfig;\n if (typeof cfg === 'string') {\n try { cfg = JSON.parse(cfg); } catch { return undefined; }\n }\n if (!cfg || typeof cfg !== 'object' || Array.isArray(cfg)) return undefined;\n return (cfg as Record<string, unknown>).parameters;\n}\n\nconst ALLOWED_PRIMITIVE_TYPES = new Set(['string', 'number', 'integer', 'boolean', 'null']);\nconst ALLOWED_TYPES = new Set(['string', 'number', 'integer', 'boolean', 'object', 'array', 'null']);\n\n// Keyword positions whose value is itself a subschema (or a boolean schema in\n// draft 2020-12). The validator MUST descend these — a structurally-invalid\n// subschema buried in a composition/`$defs`/conditional keyword would otherwise\n// reach the LLM provider and 400 the whole agent turn. `properties` and `items`\n// have dedicated blocks below (richer error messages / type-guarded), so they\n// are intentionally absent here.\nconst SUBSCHEMA_OBJECT_KEYWORDS = [\n 'additionalProperties', 'unevaluatedProperties', 'additionalItems', 'unevaluatedItems',\n 'contains', 'propertyNames', 'not', 'if', 'then', 'else',\n] as const;\nconst SUBSCHEMA_LIST_KEYWORDS = ['allOf', 'anyOf', 'oneOf', 'prefixItems'] as const;\nconst SUBSCHEMA_MAP_KEYWORDS = ['$defs', 'definitions', 'patternProperties', 'dependentSchemas'] as const;\n\nexport interface SchemaViolation {\n path: string;\n message: string;\n suggestion?: string;\n}\n\nexport type ValidationResult =\n | { ok: true }\n | { ok: false; errors: SchemaViolation[] };\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nfunction isPrimitive(v: unknown): boolean {\n return v === null || ['string', 'number', 'boolean'].includes(typeof v);\n}\n\nfunction typeMatches(typeField: unknown, allowed: Set<string>): boolean {\n if (typeof typeField === 'string') return allowed.has(typeField);\n if (Array.isArray(typeField)) return typeField.every(t => typeof t === 'string' && allowed.has(t));\n return false;\n}\n\n/** Max recursion depth. Anthropic's own validator caps nesting well below\n * this; we add our own floor to keep a pathological user-supplied schema\n * from exhausting the Worker call stack. */\nexport const MAX_SCHEMA_DEPTH = 20;\n\nfunction validateSchema(\n schema: unknown,\n path: string,\n errors: SchemaViolation[],\n opts: { isRoot?: boolean; depth?: number } = {},\n): void {\n // A boolean is a valid subschema in draft 2020-12 (`true` = match-anything,\n // `false` = match-nothing) — legal in any nested position (`anyOf` element,\n // tuple `items` element, `$defs`/`additionalProperties` value, …). The\n // truncation sanitizer preserves these booleans verbatim, so rejecting them\n // here would silently drop an otherwise-valid tool (the sanitizer-preserves /\n // validator-rejects class this validator was hardened against). A boolean is a\n // leaf — no children, so depth is irrelevant. The object-only root constraint\n // is still enforced upstream in `validateToolInputSchema`.\n if (typeof schema === 'boolean') return;\n\n const depth = opts.depth ?? 0;\n if (depth > MAX_SCHEMA_DEPTH) {\n errors.push({\n path: path || '<root>',\n message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH} levels`,\n suggestion: 'Flatten the schema; LLM providers reject deeply nested tool input_schemas.',\n });\n return;\n }\n\n if (!isRecord(schema)) {\n errors.push({\n path,\n message: `expected object, got ${schema === null ? 'null' : typeof schema}`,\n });\n return;\n }\n\n // Root schemas must be objects specifically (not just any allowed type).\n // This check replaces the earlier duplicate root-type check in\n // `validateToolInputSchema` — keeping both produced two errors per bad root.\n if (opts.isRoot) {\n if ('type' in schema && schema.type !== 'object') {\n errors.push({\n path: path ? `${path}.type` : 'type',\n message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,\n suggestion: \"Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`.\",\n });\n }\n } else if ('type' in schema && !typeMatches(schema.type, ALLOWED_TYPES)) {\n errors.push({\n path: `${path}.type`,\n message: `type must be one of ${[...ALLOWED_TYPES].join('/')} or an array of those, got ${JSON.stringify(schema.type)}`,\n });\n }\n\n if ('enum' in schema) {\n const e = schema.enum;\n if (typeof e === 'string') {\n const isPlaceholder = PLACEHOLDER_TOKENS.includes(e as (typeof PLACEHOLDER_TOKENS)[number]);\n errors.push({\n path: `${path}.enum`,\n message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,\n suggestion: isPlaceholder\n ? \"Set `operation: 'update_kanban_status'` on the tool and ensure at least one hub.kanban_status has `allowsAgentUpdate: true` so the platform can render the placeholder into a valid array.\"\n : 'Wrap the value in an array: `enum: [\"value\"]`.',\n });\n } else if (!Array.isArray(e)) {\n errors.push({\n path: `${path}.enum`,\n message: `enum must be a non-empty array of primitives, got ${typeof e}`,\n });\n } else if (e.length === 0) {\n errors.push({\n path: `${path}.enum`,\n message: 'enum must not be empty',\n });\n } else {\n for (let i = 0; i < e.length; i++) {\n if (!isPrimitive(e[i])) {\n errors.push({\n path: `${path}.enum[${i}]`,\n message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`,\n });\n }\n }\n }\n }\n\n for (const key of ['exclusiveMinimum', 'exclusiveMaximum'] as const) {\n if (key in schema && typeof schema[key] === 'boolean') {\n errors.push({\n path: `${path}.${key}`,\n message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,\n suggestion: `Replace with the numeric bound, e.g. \\`${key}: 0\\`.`,\n });\n }\n }\n\n if ('properties' in schema) {\n if (!isRecord(schema.properties)) {\n errors.push({\n path: `${path}.properties`,\n message: `properties must be an object, got ${Array.isArray(schema.properties) ? 'array' : typeof schema.properties}`,\n });\n } else {\n for (const [propName, propSchema] of Object.entries(schema.properties)) {\n validateSchema(propSchema, `${path}.properties.${propName}`, errors, { depth: depth + 1 });\n }\n }\n }\n\n if (schemaTypeIncludes(schema, 'array') && 'items' in schema) {\n // `items` straddles two forms: a single subschema (2020-12) or a tuple array\n // of subschemas (draft-07). MCP servers emit both, and the truncation\n // sanitizer preserves the tuple array — validating it as a single schema\n // would reject the whole tool (\"expected object, got object\") and silently\n // drop a valid tool from the agent. Validate each tuple element instead.\n if (Array.isArray(schema.items)) {\n schema.items.forEach((sub, i) => validateSchema(sub, `${path}.items[${i}]`, errors, { depth: depth + 1 }));\n } else {\n validateSchema(schema.items, `${path}.items`, errors, { depth: depth + 1 });\n }\n }\n\n // Descend the remaining subschema-bearing keywords (composition, `$defs`,\n // conditional, pattern/additional). Booleans are valid subschemas in draft\n // 2020-12 (e.g. `additionalProperties: false`) — only object/array forms carry\n // a nested schema, so skip the rest.\n for (const key of SUBSCHEMA_OBJECT_KEYWORDS) {\n if (key in schema && isRecord(schema[key])) {\n validateSchema(schema[key], `${path}.${key}`, errors, { depth: depth + 1 });\n }\n }\n for (const key of SUBSCHEMA_LIST_KEYWORDS) {\n const list = schema[key];\n if (Array.isArray(list)) {\n list.forEach((sub, i) => validateSchema(sub, `${path}.${key}[${i}]`, errors, { depth: depth + 1 }));\n }\n }\n for (const key of SUBSCHEMA_MAP_KEYWORDS) {\n const map = schema[key];\n if (isRecord(map)) {\n for (const [name, sub] of Object.entries(map)) {\n validateSchema(sub, `${path}.${key}.${name}`, errors, { depth: depth + 1 });\n }\n }\n }\n\n // Flag unresolved placeholder literals on any string-valued field, but skip\n // fields the `enum` block above already reported on — otherwise a string\n // enum set to e.g. \"[KANBAN_STATUS_VALUES]\" would produce two errors for\n // the same path.\n const reportedPaths = new Set(errors.map(e => e.path));\n for (const [k, v] of Object.entries(schema)) {\n if (typeof v !== 'string') continue;\n const fieldPath = `${path}.${k}`;\n if (reportedPaths.has(fieldPath)) continue;\n for (const token of PLACEHOLDER_TOKENS) {\n if (v === token) {\n errors.push({\n path: fieldPath,\n message: `unresolved placeholder ${JSON.stringify(token)}`,\n suggestion: \"The platform renders this placeholder at tool-creation time. Ensure `operation: 'update_kanban_status'` is set and the hub has at least one kanban_status with `allowsAgentUpdate: true`.\",\n });\n }\n }\n }\n}\n\n/**\n * True when `schema.type` is `wanted` either as the scalar value or as an\n * entry in a type-array (draft 2020-12's union-type syntax, e.g. `[\"array\",\"null\"]`).\n */\nfunction schemaTypeIncludes(schema: Record<string, unknown>, wanted: string): boolean {\n const t = schema.type;\n if (typeof t === 'string') return t === wanted;\n if (Array.isArray(t)) return t.includes(wanted);\n return false;\n}\n\n// Keyword positions whose valid value is a string or array — NEVER an object.\n// zod→JSON-Schema serializers sometimes emit an empty object `{}` here (e.g.\n// `type:{}` for a `z.string()`, `enum:{}` for a `z.enum()`, nested inside array\n// items — gh #2554). The empty object carries zero constraint yet makes the\n// schema structurally INVALID, so the LLM provider 400s the turn / the tool is\n// dropped at runtime — total capability loss for a tool that is otherwise fine.\n// MUST stay in sync with `EMPTY_OBJECT_ARTIFACT_KEYS` in\n// `workers/backend/src/utils/sanitize-mcp-tool.ts` (the ingestion-boundary\n// repair); a drift-guard test pins the two behaviours together.\nconst EMPTY_OBJECT_ARTIFACT_KEYS = new Set(['type', 'enum', 'required']);\n// Proto-pollution keys never copied onto the repaired tree. Inlined (not\n// imported from the backend `nested-path` util) to keep this shared module\n// dependency-free.\nconst REPAIR_UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n// Absolute recursion backstop. The structure-aware walk only descends recognized\n// subschema positions (unknown keywords are copied verbatim, so they can't drive\n// unbounded recursion), and validated schemas are already ≤ MAX_SCHEMA_DEPTH —\n// but the runtime read may see rows persisted before that gate, so keep a stack\n// backstop well above any real schema. Past the cap a node is returned verbatim.\nconst MAX_REPAIR_DEPTH = 200;\n\nfunction isEmptyPlainObject(v: unknown): boolean {\n return isRecord(v) && Object.keys(v).length === 0;\n}\n\nfunction includesKey(keys: readonly string[], k: string): boolean {\n return keys.includes(k);\n}\n\n/**\n * Normalize known third-party JSON-Schema serialization artifacts so the result\n * is structurally valid: an empty-object value in a string/array-only KEYWORD\n * position (`type`/`enum`/`required`) — a meaningless zod→JSON-Schema artifact\n * (gh #2554) whose removal is lossless. ONLY the empty-object case is repaired; a\n * non-empty object there is ambiguous and left for `validateToolInputSchema` to\n * reject.\n *\n * The traversal MIRRORS `validateSchema` (and the ingestion-boundary\n * `capSchemaNode`): it descends ONLY genuine subschema positions, so a property\n * literally NAMED `type`/`enum`/`required` (a key inside `properties`/`$defs`/…\n * whose value is a sub-schema) is preserved, never mistaken for a keyword\n * artifact. Keyword VALUES and data (`enum` arrays, `const`, `default`,\n * `examples`, descriptions, …) are copied verbatim — unknown keywords too.\n *\n * Pure. On the clean path the result tree is NOT deep-cloned — an unchanged\n * subtree returns its original reference (structural sharing), so the per-turn hot\n * path pays a walk plus transient per-node scratch objects, not a full clone.\n * `repaired` is true iff something was dropped (`result !== schema`). Used at the\n * runtime snapshot read (`buildAgentToolsForLLM`) to heal rows persisted before\n * #2552 hardened the validator's composition-keyword descent.\n */\nexport function repairToolInputSchemaArtifacts(schema: unknown): { schema: unknown; repaired: boolean } {\n // Recurse a subschema-MAP value (`properties`/`$defs`/…): keys are names, values\n // are subschemas — recurse the values only; a name is never a keyword artifact.\n const repairMap = (v: unknown, depth: number): unknown => {\n if (!isRecord(v)) return v;\n let changed = false;\n const out: Record<string, unknown> = {};\n for (const [name, sub] of Object.entries(v)) {\n if (REPAIR_UNSAFE_KEYS.has(name)) { changed = true; continue; }\n const r = repairNode(sub, depth + 1);\n if (r !== sub) changed = true;\n out[name] = r;\n }\n return changed ? out : v;\n };\n\n // Recurse a subschema-LIST value (`anyOf`/`oneOf`/`allOf`/`prefixItems`, or a\n // draft-07 tuple `items`): an array of subschemas.\n const repairList = (arr: unknown[], depth: number): unknown[] => {\n let changed = false;\n const out = arr.map((e) => {\n const r = repairNode(e, depth + 1);\n if (r !== e) changed = true;\n return r;\n });\n return changed ? out : arr;\n };\n\n function repairNode(node: unknown, depth: number): unknown {\n if (depth >= MAX_REPAIR_DEPTH) return node;\n // Booleans are valid subschemas (draft 2020-12); a non-object/array in a\n // schema position is malformed server output — return verbatim (the validator\n // flags it), never descend.\n if (!isRecord(node)) return node;\n\n let changed = false;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(node)) {\n if (REPAIR_UNSAFE_KEYS.has(k)) { changed = true; continue; }\n if (EMPTY_OBJECT_ARTIFACT_KEYS.has(k) && isEmptyPlainObject(v)) {\n changed = true; // drop the empty-object artifact keyword\n continue;\n }\n let nv: unknown;\n if (k === 'properties' || includesKey(SUBSCHEMA_MAP_KEYWORDS, k)) {\n nv = repairMap(v, depth);\n } else if (k === 'items') {\n nv = Array.isArray(v) ? repairList(v, depth) : repairNode(v, depth + 1);\n } else if (includesKey(SUBSCHEMA_OBJECT_KEYWORDS, k)) {\n nv = repairNode(v, depth + 1);\n } else if (includesKey(SUBSCHEMA_LIST_KEYWORDS, k)) {\n nv = Array.isArray(v) ? repairList(v, depth) : v;\n } else {\n nv = v; // keyword value / data / unknown keyword — verbatim\n }\n if (nv !== v) changed = true;\n out[k] = nv;\n }\n return changed ? out : node;\n }\n\n const result = repairNode(schema, 0);\n return { schema: result, repaired: result !== schema };\n}\n\n/**\n * Non-mutating structural rewrite of a JSON-Schema tree (draft 2020-12).\n *\n * Descends the SAME subschema positions `validateSchema` and\n * `repairToolInputSchemaArtifacts` recognize — via the shared `SUBSCHEMA_*`\n * taxonomy — so a rewrite (e.g. a provider-subset filter) can't miss a keyword\n * the validator accepts. Children are rewritten first (post-order); each schema\n * NODE is then handed to `transform` with its children already rewritten.\n * `transform` returns the node's replacement keyword-set (typically a filtered\n * copy of its OWN keywords) and MUST NOT recurse — descent is handled here.\n *\n * Subschema-MAP positions (`properties`/`$defs`/`patternProperties`/\n * `dependentSchemas`) recurse VALUES only, so a property/definition NAMED like a\n * keyword (e.g. a param literally named `default`) is preserved, never mistaken\n * for the keyword. List positions (`allOf`/`anyOf`/`oneOf`/`prefixItems` and the\n * draft-07 tuple `items` array) recurse each element. Booleans / non-records are\n * valid leaf subschemas and pass through verbatim. Depth-bounded + proto-safe,\n * mirroring the repair walk (kept separate: repair optimizes for structural\n * sharing + a `repaired` flag; this always returns fresh nodes).\n */\nexport function mapSchemaTree(\n schema: unknown,\n transform: (node: Record<string, unknown>) => Record<string, unknown>,\n): unknown {\n function walk(node: unknown, depth: number): unknown {\n if (depth >= MAX_REPAIR_DEPTH) return node;\n if (!isRecord(node)) return node; // boolean / malformed leaf — verbatim\n\n const rewritten: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(node)) {\n if (REPAIR_UNSAFE_KEYS.has(k)) continue;\n if (k === 'properties' || includesKey(SUBSCHEMA_MAP_KEYWORDS, k)) {\n if (isRecord(v)) {\n const out: Record<string, unknown> = {};\n for (const [name, sub] of Object.entries(v)) {\n if (REPAIR_UNSAFE_KEYS.has(name)) continue;\n out[name] = walk(sub, depth + 1);\n }\n rewritten[k] = out;\n } else {\n rewritten[k] = v;\n }\n } else if (k === 'items') {\n rewritten[k] = Array.isArray(v)\n ? v.map((e) => walk(e, depth + 1))\n : walk(v, depth + 1);\n } else if (includesKey(SUBSCHEMA_OBJECT_KEYWORDS, k)) {\n rewritten[k] = walk(v, depth + 1);\n } else if (includesKey(SUBSCHEMA_LIST_KEYWORDS, k)) {\n rewritten[k] = Array.isArray(v) ? v.map((e) => walk(e, depth + 1)) : v;\n } else {\n rewritten[k] = v; // keyword value / data / unknown keyword — verbatim\n }\n }\n return transform(rewritten);\n }\n return walk(schema, 0);\n}\n\n/**\n * Validate a tool's `input_schema` (the value of `parameters` on an OpenAI\n * function tool, or `input_schema` on an Anthropic custom tool).\n *\n * Returns `{ ok: true }` on success, or `{ ok: false, errors }` with one\n * entry per distinct violation. Returns multiple errors per call to let\n * the CLI render them all at once, rather than one-per-push.\n */\nexport function validateToolInputSchema(schema: unknown): ValidationResult {\n const errors: SchemaViolation[] = [];\n\n if (!isRecord(schema)) {\n errors.push({\n path: '',\n message: `expected object at root, got ${schema === null ? 'null' : typeof schema}`,\n });\n return { ok: false, errors };\n }\n\n // `isRoot: true` enforces the stricter \"root must be object\" constraint\n // inside `validateSchema` (vs the ALLOWED_TYPES set used for nested\n // schemas). Consolidating the check here avoids the previous double-report\n // at paths `type` and `.type` when the root had an invalid type.\n validateSchema(schema, '', errors, { isRoot: true });\n\n return errors.length === 0 ? { ok: true } : { ok: false, errors };\n}\n","import { z } from 'zod';\nimport { SLUG_REGEX, slugSchema, visibleLength } from './slug';\n\n// state_slug = immutable wire identifier (LLM tool args, ClickHouse path, placeholder lookup, prompt-tag attribute). state_name = freely editable display label.\n\n// {} and null collapse to null at the contract boundary; undefined stays undefined so PATCH partial-update guards still work.\nconst initialValueCreateSchema = z\n .record(z.unknown())\n .nullish()\n .transform((v) => (v && Object.keys(v).length > 0 ? v : null));\n\nconst initialValueUpdateSchema = z\n .record(z.unknown())\n .nullish()\n .transform((v) => (v === undefined ? undefined : v && Object.keys(v).length > 0 ? v : null));\n\n// Param schemas\nexport const stateIdParam = z.object({\n id: z.string().uuid(),\n});\n\n// Query schemas\nexport const listStatesQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\nexport const stateNameSchema = z\n .string()\n .min(1, 'state_name is required')\n .max(100, 'state_name must be 100 characters or fewer')\n .refine((v) => visibleLength(v) > 0, 'state_name must not be blank');\n\n// Body schemas\nexport const createStateBody = z.object({\n hub_id: z.string().uuid(),\n state_slug: slugSchema,\n state_name: stateNameSchema,\n state_scope: z.enum(['conversation', 'user']),\n state_description: z.string().max(1000).nullish(),\n json_schema: z.record(z.unknown()).default({}),\n initial_value: initialValueCreateSchema,\n display_order: z.number().int().nonnegative().optional(),\n is_enabled: z.boolean().default(true),\n inject_in_last_message: z.boolean().default(true),\n});\n\nexport const updateStateBody = z.object({\n // state_slug is immutable after first persist — not accepted here.\n state_name: stateNameSchema.optional(),\n state_scope: z.enum(['conversation', 'user']).optional(),\n state_description: z.string().max(1000).nullish(),\n json_schema: z.record(z.unknown()).optional(),\n initial_value: initialValueUpdateSchema,\n display_order: z.number().int().nonnegative().optional(),\n is_enabled: z.boolean().optional(),\n inject_in_last_message: z.boolean().optional(),\n});\n\nexport const reorderStatesBody = z.object({\n states: z.array(z.object({\n state_id: z.string().uuid(),\n display_order: z.number().int().nonnegative(),\n })).min(1),\n});\n\n// Re-export the slug regex under a state-specific name for callers that want\n// to validate ad-hoc (migrations, slugify helpers).\nexport const STATE_SLUG_REGEX = SLUG_REGEX;\n\n// Inferred types\nexport type CreateStateInput = z.infer<typeof createStateBody>;\nexport type UpdateStateInput = z.infer<typeof updateStateBody>;\nexport type ReorderStatesInput = z.infer<typeof reorderStatesBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\nexport interface StateResponse {\n state_id: string;\n created_at: string;\n updated_at: string;\n hub_id: string;\n state_slug: string;\n state_name: string;\n state_scope: 'conversation' | 'user';\n state_description: string | null;\n json_schema: Record<string, unknown>;\n initial_value: Record<string, unknown> | null;\n display_order: number;\n is_enabled: boolean;\n inject_in_last_message: boolean;\n}\n\nexport interface ListStatesResponse {\n data: StateResponse[];\n}\n\nexport interface GetStateResponse {\n data: StateResponse;\n}\n\nexport interface CreateStateResponse {\n data: StateResponse;\n}\n\nexport interface UpdateStateResponse {\n data: StateResponse;\n}\n","import { z } from 'zod';\n\n// Param schemas\nexport const orgTagIdParam = z.object({\n id: z.string().uuid(),\n});\n\n// Query schemas\nexport const listOrgTagsQuery = z.object({\n organization_id: z.string().uuid(),\n});\n\n// Body schemas\nexport const createOrgTagBody = z.object({\n organization_id: z.string().uuid(),\n name: z.string().min(1).max(50).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, {\n message: 'Must be lowercase alphanumeric with hyphens (e.g. \"my-tag\")',\n }),\n display_name: z.string().max(100).nullish(),\n color: z.string().max(20).nullish(),\n});\n\nexport const updateOrgTagBody = z.object({\n // Required so the route targets the org the UI is managing (which may differ\n // from the token's default `auth.org_id` for multi-org users) — mirrors create/list.\n organization_id: z.string().uuid(),\n name: z.string().min(1).max(50).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, {\n message: 'Must be lowercase alphanumeric with hyphens (e.g. \"my-tag\")',\n }).optional(),\n display_name: z.string().max(100).nullish(),\n color: z.string().max(20).nullish(),\n});\n\n// Inferred types\nexport type CreateOrgTagInput = z.infer<typeof createOrgTagBody>;\nexport type UpdateOrgTagInput = z.infer<typeof updateOrgTagBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\nexport interface OrgTagResponse {\n tag_id: string;\n name: string;\n display_name: string | null;\n color: string | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface ListOrgTagsResponse {\n data: OrgTagResponse[];\n}\n\nexport interface CreateOrgTagResponse {\n data: OrgTagResponse;\n}\n\nexport interface UpdateOrgTagResponse {\n data: OrgTagResponse;\n}\n","import { z } from 'zod';\nimport { normalizeAuthType } from '../../constants';\n\n// Param schemas\nexport const orgCredentialIdParam = z.object({\n id: z.string().uuid(),\n});\n\n// Query schemas\nexport const listOrgCredentialsQuery = z.object({\n organization_id: z.string().uuid(),\n hub_id: z.string().uuid().optional(),\n});\n\n// Body schemas — accept both lowercase (canonical) and legacy capitalized values\nexport const createOrgCredentialBody = z.object({\n organization_id: z.string().uuid(),\n credential_display_name: z.string().min(1).max(255),\n credential_description: z.string().max(1000).nullish(),\n authentication_type: z.enum(['api_key', 'bearer', 'basic_auth']).or(\n z.enum(['API Key', 'Bearer Token', 'Basic Auth']).transform((v) => normalizeAuthType(v) as 'api_key' | 'bearer' | 'basic_auth')\n ),\n api_key: z.string().optional(),\n access_token: z.string().optional(),\n username: z.string().optional(),\n password: z.string().optional(),\n tags: z.array(z.string().uuid()).optional(),\n environment: z.enum(['preview', 'production', 'all']).optional(),\n});\n\nexport const updateOrgCredentialBody = z.object({\n credential_display_name: z.string().min(1).max(255).optional(),\n credential_description: z.string().max(1000).nullish(),\n api_key: z.string().optional(),\n access_token: z.string().optional(),\n username: z.string().optional(),\n password: z.string().optional(),\n tags: z.array(z.string().uuid()).optional(),\n environment: z.enum(['preview', 'production', 'all']).optional(),\n});\n\n// Inferred types\nexport type CreateOrgCredentialInput = z.infer<typeof createOrgCredentialBody>;\nexport type UpdateOrgCredentialInput = z.infer<typeof updateOrgCredentialBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\nexport interface OrgCredentialResponse {\n organization_credential_id: string;\n created_at: string;\n updated_at: string;\n organization_id: string;\n credential_display_name: string;\n credential_description: string | null;\n authentication_type: 'api_key' | 'bearer' | 'basic_auth';\n tags: string[];\n environment: 'preview' | 'production' | 'all';\n}\n\nexport interface ListOrgCredentialsResponse {\n data: OrgCredentialResponse[];\n}\n\nexport interface GetOrgCredentialResponse {\n data: OrgCredentialResponse;\n}\n\nexport interface CreateOrgCredentialResponse {\n data: OrgCredentialResponse;\n}\n\nexport interface UpdateOrgCredentialResponse {\n data: OrgCredentialResponse;\n}\n","/**\n * Organization-scoped shared resources — Zod schemas + response types.\n *\n * Org resources are linked into hubs as read-only shadow rows. The link surface\n * lives at `/api/setup/hubs/:hub_id/org-resources/*`; the canonical CRUD lives\n * at `/api/setup/organization-resources/*`. Skill resources are out of scope\n * for v1 — only `resource_type = 'knowledge'` is accepted.\n */\n\nimport { z } from 'zod';\nimport type { UploadSkillZipResponse } from './resources';\n\n// ---------------------------------------------------------------------------\n// Param schemas\n// ---------------------------------------------------------------------------\n\nexport const orgResourceIdParam = z.object({\n id: z.string().uuid(),\n});\n\nexport const orgResourceFileIdParam = z.object({\n file_id: z.string().uuid(),\n});\n\nexport const orgResourceFolderIdParam = z.object({\n folder_id: z.string().uuid(),\n});\n\n/**\n * `:id` is the hub id, `:org_resource_id` is the org resource being unlinked.\n * Used by `DELETE /api/setup/hubs/:id/org-resources/:org_resource_id`.\n */\nexport const hubOrgResourceParam = z.object({\n id: z.string().uuid(),\n org_resource_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Query schemas\n// ---------------------------------------------------------------------------\n\nexport const listOrgResourcesQuery = z.object({\n organization_id: z.string().uuid(),\n hub_id: z.string().uuid().optional(),\n});\n\nexport const orgIdQuery = z.object({\n organization_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Body schemas — canonical CRUD\n// ---------------------------------------------------------------------------\n\nexport const createOrgResourceBody = z.object({\n organization_id: z.string().uuid(),\n resource_name: z.string().min(1).max(255),\n resource_description: z.string().max(1000).nullish(),\n resource_type: z.enum(['knowledge', 'skill']).default('knowledge'),\n // Skill-only fields. Required for `resource_type = 'skill'` (validated in\n // the route layer since cross-field refinement complicates the inferred\n // input type for callers). Ignored for `knowledge`.\n skill_name: z.string().min(1).max(255).nullish(),\n skill_version: z.string().max(50).nullish(),\n folder_metadata_schema: z.record(z.unknown()).optional(),\n file_metadata_schema: z.record(z.unknown()).optional(),\n enabled: z.boolean().optional(),\n user_browsable: z.boolean().optional(),\n tags: z.array(z.string().uuid()).optional(),\n environment: z.enum(['preview', 'production', 'all']).optional(),\n});\n\nexport const updateOrgResourceBody = z.object({\n resource_name: z.string().min(1).max(255).optional(),\n resource_description: z.string().max(1000).nullish(),\n skill_name: z.string().min(1).max(255).nullish(),\n skill_version: z.string().max(50).nullish(),\n folder_metadata_schema: z.record(z.unknown()).optional(),\n file_metadata_schema: z.record(z.unknown()).optional(),\n enabled: z.boolean().optional(),\n user_browsable: z.boolean().optional(),\n tags: z.array(z.string().uuid()).optional(),\n environment: z.enum(['preview', 'production', 'all']).optional(),\n});\n\nexport const createOrgResourceFolderBody = z.object({\n org_resource_id: z.string().uuid(),\n folder_name: z.string().min(1).max(255),\n folder_description: z.string().max(1000).nullish(),\n parent_folder_id: z.string().uuid().nullish(),\n order_index: z.number().int().nonnegative().optional(),\n enabled: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const updateOrgResourceFolderBody = z.object({\n folder_name: z.string().min(1).max(255).optional(),\n folder_description: z.string().max(1000).nullish(),\n parent_folder_id: z.string().uuid().nullish(),\n order_index: z.number().int().nonnegative().optional(),\n enabled: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const uploadOrgResourceFileBody = z.object({\n org_resource_id: z.string().uuid(),\n folder_id: z.string().uuid().nullish(),\n file_name: z.string().min(1).max(255),\n file_data: z.string(), // base64\n mime_type: z.string().optional(),\n file_size: z.number().int().nonnegative().optional(),\n resource_file_tags: z.array(z.string()).optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const updateOrgResourceFileBody = z.object({\n resource_file_title: z.string().min(1).max(255).optional(),\n folder_id: z.string().uuid().nullish(),\n order_index: z.number().int().nonnegative().optional(),\n enabled: z.boolean().optional(),\n resource_file_tags: z.array(z.string()).optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\n/**\n * Bulk-materialize an org skill resource from a ZIP containing SKILL.md and\n * supporting files. Mirrors the hub-side `uploadSkillZipBody` shape, scoped\n * via the route `:id` param + `organization_id` query.\n */\nexport const uploadOrgSkillZipBody = z.object({\n zip_data: z.string().min(1),\n replace_existing: z.boolean().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Body schemas — hub linking\n// ---------------------------------------------------------------------------\n\nexport const linkOrgResourceBody = z.object({\n org_resource_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred input types\n// ---------------------------------------------------------------------------\n\nexport type CreateOrgResourceInput = z.infer<typeof createOrgResourceBody>;\nexport type UpdateOrgResourceInput = z.infer<typeof updateOrgResourceBody>;\nexport type CreateOrgResourceFolderInput = z.infer<typeof createOrgResourceFolderBody>;\nexport type UpdateOrgResourceFolderInput = z.infer<typeof updateOrgResourceFolderBody>;\nexport type UploadOrgResourceFileInput = z.infer<typeof uploadOrgResourceFileBody>;\nexport type UpdateOrgResourceFileInput = z.infer<typeof updateOrgResourceFileBody>;\nexport type UploadOrgSkillZipInput = z.infer<typeof uploadOrgSkillZipBody>;\nexport type LinkOrgResourceInput = z.infer<typeof linkOrgResourceBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface OrgResourceResponse {\n org_resource_id: string;\n organization_id: string;\n resource_name: string;\n resource_description: string | null;\n resource_type: 'knowledge' | 'skill';\n /** Set only when resource_type='skill'. */\n skill_name: string | null;\n /** Set only when resource_type='skill'. Defaults to '1.0.0'. */\n skill_version: string | null;\n folder_metadata_schema: Record<string, unknown>;\n file_metadata_schema: Record<string, unknown>;\n enabled: boolean;\n user_browsable: boolean;\n tags: string[];\n environment: 'preview' | 'production' | 'all';\n created_by: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface OrgResourceFileResponse {\n org_resource_file_id: string;\n org_resource_id: string;\n resource_file_title: string;\n resource_file_tags: string[];\n folder_id: string | null;\n file_id: string;\n file_path: string;\n file_name: string;\n mime_type: string | null;\n file_size: number | null;\n file_hash: string | null;\n order_index: number;\n enabled: boolean;\n metadata: Record<string, unknown>;\n created_by: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface OrgResourceFolderResponse {\n org_resource_folder_id: string;\n org_resource_id: string;\n folder_name: string;\n folder_description: string | null;\n parent_folder_id: string | null;\n order_index: number;\n enabled: boolean;\n metadata: Record<string, unknown>;\n created_by: string;\n created_at: string;\n updated_at: string;\n}\n\n/**\n * One entry of `GET /api/setup/hubs/:hub_id/org-resources/`. Combines the org\n * resource shape with link state for this hub. `policy_match` lets the UI\n * surface a warning when a previously-linked resource no longer matches the\n * hub's tag/environment policy.\n */\nexport interface HubOrgResourceEntry extends OrgResourceResponse {\n linked: boolean;\n linked_at: string | null;\n policy_match: 'ok' | 'stale_tags' | 'stale_env';\n}\n\nexport interface ListOrgResourcesResponse {\n data: OrgResourceResponse[];\n}\n\nexport interface GetOrgResourceResponse {\n data: OrgResourceResponse;\n}\n\nexport interface CreateOrgResourceResponse {\n data: OrgResourceResponse;\n}\n\nexport interface UpdateOrgResourceResponse {\n data: OrgResourceResponse;\n}\n\nexport interface DeleteOrgResourceResponse {\n data: { deleted: true; id: string };\n}\n\nexport interface ListOrgResourceFilesResponse {\n data: OrgResourceFileResponse[];\n}\n\nexport interface UploadOrgResourceFileResponse {\n data: OrgResourceFileResponse;\n}\n\n/**\n * Response from `POST /api/setup/organization-resources/:id/files/upload-zip`.\n * Structurally identical to the hub-side `UploadSkillZipResponse` — same fields,\n * same semantics; aliased so a change to either flows to both.\n */\nexport type UploadOrgSkillZipResponse = UploadSkillZipResponse;\n\nexport interface UpdateOrgResourceFileResponse {\n data: OrgResourceFileResponse;\n}\n\nexport interface DeleteOrgResourceFileResponse {\n data: { deleted: true; id: string };\n}\n\nexport interface ListOrgResourceFoldersResponse {\n data: OrgResourceFolderResponse[];\n}\n\nexport interface CreateOrgResourceFolderResponse {\n data: OrgResourceFolderResponse;\n}\n\nexport interface UpdateOrgResourceFolderResponse {\n data: OrgResourceFolderResponse;\n}\n\nexport interface DeleteOrgResourceFolderResponse {\n data: { deleted: true; id: string };\n}\n\nexport interface ListHubOrgResourcesResponse {\n data: HubOrgResourceEntry[];\n}\n\nexport interface LinkOrgResourceResponse {\n data: { resource_id: string; linked: true };\n}\n\nexport interface UnlinkOrgResourceResponse {\n data: { deleted: true; org_resource_id: string; hub_id: string };\n}\n\n/**\n * Returned by `GET /api/setup/organization-resources/files/:file_id/content`\n * for admin preview of an org-resource file. Provides a short-lived signed\n * URL the browser can fetch directly — avoids streaming bytes through the\n * worker and keeps the existing `/files/auth/...` org-membership check on\n * the signed-URL serving route.\n */\nexport interface OrgResourceFileContentResponse {\n data: {\n file_id: string;\n file_name: string;\n mime_type: string | null;\n file_size: number | null;\n signed_url: string;\n expires_in_seconds: number;\n };\n}\n","import { z } from 'zod';\nimport { uuidSchema } from '../common';\n\n// =============================================================================\n// Resource params & queries\n// =============================================================================\n\nexport const resourceIdParam = z.object({ id: uuidSchema });\n\nexport const listResourcesQuery = z.object({\n hub_id: uuidSchema,\n enabled: z.enum(['true', 'false']).optional(),\n resource_type: z.enum(['knowledge', 'skill']).optional(),\n search: z.string().optional(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n});\n\nexport const createResourceBody = z.object({\n hub_id: uuidSchema,\n resource_name: z.string().min(1),\n resource_description: z.string().optional(),\n enabled: z.boolean().optional(),\n folder_metadata_schema: z.record(z.unknown()).optional(),\n file_metadata_schema: z.record(z.unknown()).optional(),\n resource_type: z.enum(['knowledge', 'skill']).optional(),\n skill_name: z.string().optional(),\n skill_version: z.string().optional(),\n user_browsable: z.boolean().optional(),\n});\n\nexport const updateResourceBody = z.object({\n resource_name: z.string().min(1).optional(),\n resource_description: z.string().optional(),\n enabled: z.boolean().optional(),\n folder_metadata_schema: z.record(z.unknown()).optional(),\n file_metadata_schema: z.record(z.unknown()).optional(),\n skill_name: z.string().optional(),\n skill_version: z.string().optional(),\n anthropic_skill_id: z.string().optional(),\n anthropic_version: z.string().optional(),\n user_browsable: z.boolean().optional(),\n});\n\nexport const syncSkillsBody = z.object({\n hub_id: uuidSchema,\n connection_id: uuidSchema.optional(),\n});\n\n// =============================================================================\n// Resource File params & queries\n// =============================================================================\n\nexport const resourceFileIdParam = z.object({ id: uuidSchema });\n\nexport const listResourceFilesQuery = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema.optional(),\n folder_id: z.string().optional(), // 'null' for root, UUID for specific folder\n search: z.string().optional(),\n tags: z.string().optional(), // comma-separated\n enabled: z.enum(['true', 'false']).optional(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n include_root_files: z.enum(['true', 'false']).optional(),\n});\n\nexport const createResourceFileBody = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n file_id: uuidSchema,\n folder_id: uuidSchema.nullable().optional(),\n resource_file_title: z.string().optional(),\n resource_file_tags: z.array(z.string()).optional(),\n order_index: z.number().optional(),\n enabled: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const updateResourceFileBody = z.object({\n resource_file_title: z.string().optional(),\n resource_file_tags: z.array(z.string()).optional(),\n folder_id: uuidSchema.nullable().optional(),\n order_index: z.number().optional(),\n enabled: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const uploadResourceFileBody = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n folder_id: uuidSchema.nullable().optional(),\n file_name: z.string().min(1),\n file_data: z.string().min(1),\n mime_type: z.string().optional(),\n file_size: z.number().optional(),\n tags: z.array(z.string()).optional(),\n});\n\nexport const uploadSkillZipBody = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n zip_data: z.string().min(1),\n replace_existing: z.boolean().optional(),\n});\n\n// =============================================================================\n// Resource Folder params & queries\n// =============================================================================\n\nexport const resourceFolderIdParam = z.object({ id: uuidSchema });\n\nexport const listResourceFoldersQuery = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n parent_folder_id: z.string().optional(), // 'null' for root folders\n enabled: z.enum(['true', 'false']).optional(),\n});\n\nexport const createResourceFolderBody = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n folder_name: z.string().min(1),\n folder_description: z.string().optional(),\n parent_folder_id: uuidSchema.nullable().optional(),\n order_index: z.number().optional(),\n enabled: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport const updateResourceFolderBody = z.object({\n folder_name: z.string().min(1).optional(),\n folder_description: z.string().optional(),\n parent_folder_id: uuidSchema.nullable().optional(),\n order_index: z.number().optional(),\n enabled: z.boolean().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\n\n// =============================================================================\n// Agent Resource params & queries\n// =============================================================================\n\nexport const agentResourceQuery = z.object({\n hub_id: uuidSchema,\n agent_id: uuidSchema.optional(),\n resource_id: uuidSchema.optional(),\n}).refine(data => data.agent_id || data.resource_id, {\n message: 'Either agent_id or resource_id is required',\n});\n\nexport const hubResourceQuery = z.object({ hub_id: uuidSchema });\n\nexport const linkAgentResourceBody = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n agent_id: uuidSchema,\n priority: z.number().optional(),\n use_native_integration: z.boolean().optional(),\n include_structure_in_prompt: z.boolean().optional(),\n write_enabled: z.boolean().optional(),\n});\n\nexport const updateAgentResourceBody = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n agent_id: uuidSchema,\n use_native_integration: z.boolean().optional(),\n include_structure_in_prompt: z.boolean().optional(),\n enabled: z.boolean().optional(),\n priority: z.number().optional(),\n write_enabled: z.boolean().optional(),\n});\n\nexport const unlinkAgentResourceQuery = z.object({\n hub_id: uuidSchema,\n resource_id: uuidSchema,\n agent_id: uuidSchema,\n});\n\n// =============================================================================\n// Inferred types\n// =============================================================================\n\nexport type CreateResourceInput = z.infer<typeof createResourceBody>;\nexport type UpdateResourceInput = z.infer<typeof updateResourceBody>;\nexport type CreateResourceFileInput = z.infer<typeof createResourceFileBody>;\nexport type UpdateResourceFileInput = z.infer<typeof updateResourceFileBody>;\nexport type UploadResourceFileInput = z.infer<typeof uploadResourceFileBody>;\nexport type UploadSkillZipInput = z.infer<typeof uploadSkillZipBody>;\nexport type CreateResourceFolderInput = z.infer<typeof createResourceFolderBody>;\nexport type UpdateResourceFolderInput = z.infer<typeof updateResourceFolderBody>;\nexport type LinkAgentResourceInput = z.infer<typeof linkAgentResourceBody>;\nexport type UpdateAgentResourceInput = z.infer<typeof updateAgentResourceBody>;\n\n// =============================================================================\n// RESPONSE TYPES — Resource\n// =============================================================================\n\n/** A single resource row (select *) */\nexport interface ResourceResponse {\n resource_id: string;\n created_at: string;\n updated_at: string;\n resource_name: string;\n resource_description: string | null;\n hub_id: string;\n created_by: string;\n enabled: boolean;\n user_browsable: boolean;\n folder_metadata_schema: Record<string, unknown> | null;\n file_metadata_schema: Record<string, unknown> | null;\n resource_type: 'knowledge' | 'skill';\n skill_name: string | null;\n skill_version: string | null;\n}\n\nexport interface ListResourcesResponse {\n success: true;\n data: ResourceResponse[];\n total_count: number;\n}\n\nexport interface GetResourceResponse {\n success: true;\n data: ResourceResponse;\n}\n\nexport interface CreateResourceResponse {\n success: true;\n data: ResourceResponse;\n}\n\nexport interface UpdateResourceResponse {\n success: true;\n data: ResourceResponse;\n}\n\nexport interface DeleteResourceResponse {\n success: true;\n message: string;\n}\n\n// =============================================================================\n// RESPONSE TYPES — Resource File\n// =============================================================================\n\n/** Joined file metadata returned with resource_file list queries */\nexport interface ResourceFileJoinedFile {\n file_id: string;\n file_name: string;\n file_path: string;\n bucket: string;\n mime_type: string;\n file_size: number;\n}\n\n/** Joined file metadata returned with resource_file read queries (includes file_text) */\nexport interface ResourceFileJoinedFileWithText extends ResourceFileJoinedFile {\n file_text: string | null;\n}\n\n/** A resource_file row with joined file data (list variant) */\nexport interface ResourceFileResponse {\n resource_file_id: string;\n created_at: string;\n updated_at: string;\n resource_file_title: string;\n resource_file_tags: string[] | null;\n created_by: string;\n enabled: boolean;\n folder_id: string | null;\n file_id: string;\n order_index: number;\n resource_id: string;\n metadata: Record<string, unknown> | null;\n file_path: string | null;\n file: ResourceFileJoinedFile | null;\n}\n\n/** A resource_file row with joined file data (read variant — includes file_text) */\nexport interface ResourceFileDetailResponse {\n resource_file_id: string;\n created_at: string;\n updated_at: string;\n resource_file_title: string;\n resource_file_tags: string[] | null;\n created_by: string;\n enabled: boolean;\n folder_id: string | null;\n file_id: string;\n order_index: number;\n resource_id: string;\n metadata: Record<string, unknown> | null;\n file_path: string | null;\n file: ResourceFileJoinedFileWithText | null;\n}\n\n/** A resource_file row without joined file data (create/update return select *) */\nexport interface ResourceFileRowResponse {\n resource_file_id: string;\n created_at: string;\n updated_at: string;\n resource_file_title: string;\n resource_file_tags: string[] | null;\n created_by: string;\n enabled: boolean;\n folder_id: string | null;\n file_id: string;\n order_index: number;\n resource_id: string;\n metadata: Record<string, unknown> | null;\n file_path: string | null;\n}\n\nexport interface ListResourceFilesResponse {\n success: true;\n data: ResourceFileResponse[];\n total_count: number;\n}\n\nexport interface GetResourceFileResponse {\n success: true;\n data: ResourceFileDetailResponse;\n}\n\nexport interface CreateResourceFileResponse {\n success: true;\n data: ResourceFileRowResponse;\n}\n\nexport interface UpdateResourceFileResponse {\n success: true;\n data: ResourceFileRowResponse;\n}\n\nexport interface DeleteResourceFileResponse {\n success: true;\n message: string;\n}\n\nexport interface UploadResourceFileResponse {\n success: true;\n data: {\n fileId: string;\n fileName: string;\n fileUrl: string;\n resourceFileId: string;\n };\n}\n\nexport interface UploadSkillZipResponse {\n success: boolean;\n files_uploaded: number;\n folders_created: number;\n frontmatter: Record<string, string | undefined>;\n errors: string[];\n warnings: string[];\n root_folder_stripped?: string;\n}\n\n// =============================================================================\n// RESPONSE TYPES — Resource Folder\n// =============================================================================\n\n/** A single resource_folder row (select *) */\nexport interface ResourceFolderResponse {\n resource_folder_id: string;\n created_at: string;\n updated_at: string;\n folder_name: string;\n folder_description: string | null;\n order_index: number;\n parent_folder_id: string | null;\n resource_id: string;\n created_by: string;\n enabled: boolean;\n metadata: Record<string, unknown> | null;\n}\n\nexport interface ListResourceFoldersResponse {\n success: true;\n data: ResourceFolderResponse[];\n total_count: number;\n}\n\nexport interface GetResourceFolderResponse {\n success: true;\n data: ResourceFolderResponse;\n}\n\nexport interface CreateResourceFolderResponse {\n success: true;\n data: ResourceFolderResponse;\n}\n\nexport interface UpdateResourceFolderResponse {\n success: true;\n data: ResourceFolderResponse;\n}\n\nexport interface DeleteResourceFolderResponse {\n success: true;\n message: string;\n}\n\n// =============================================================================\n// RESPONSE TYPES — Agent Resource\n// =============================================================================\n\n/** A single agent_resource row (select *) */\nexport interface AgentResourceRowResponse {\n agent_resource_id: string;\n agent_id: string;\n resource_id: string;\n priority: number;\n enabled: boolean;\n created_at: string;\n use_native_integration: boolean;\n include_structure_in_prompt: boolean;\n write_enabled?: boolean;\n}\n\n/** Provider sync info for a skill resource (flattened from nested join) */\nexport interface AgentResourceProviderSync {\n sync_id: string;\n sync_status: 'pending' | 'synced' | 'failed';\n last_sync_at: string | null;\n service_name: string;\n}\n\n/** Flattened agent-resource with resource details (returned by getAgentResources) */\nexport interface AgentResourceLink {\n agent_resource_id: string;\n resource_id: string;\n resource_name: string;\n resource_description: string | null;\n resource_type: 'knowledge' | 'skill';\n priority: number;\n enabled: boolean;\n use_native_integration: boolean;\n include_structure_in_prompt: boolean;\n write_enabled?: boolean;\n provider_syncs?: AgentResourceProviderSync[];\n}\n\n/** Agent info attached to a resource (returned by getResourceAgents) */\nexport interface ResourceAgentLink {\n agent_id: string;\n priority: number;\n enabled: boolean;\n agent: {\n agent_id: string;\n agent_name: string;\n agent_role: string;\n } | null;\n}\n\nexport interface GetAgentResourcesResponse {\n success: true;\n resources: AgentResourceLink[];\n}\n\nexport interface GetResourceAgentsResponse {\n data: ResourceAgentLink[];\n}\n\n/** Hub resource summary (for selection dropdowns) */\nexport interface HubResourceSummary {\n resource_id: string;\n resource_name: string;\n resource_description: string | null;\n resource_type: 'knowledge' | 'skill';\n enabled: boolean;\n}\n\nexport interface ListHubResourcesResponse {\n success: true;\n resources: HubResourceSummary[];\n total_count: number;\n}\n\nexport interface LinkAgentResourceResponse {\n success: true;\n link: AgentResourceRowResponse;\n}\n\nexport interface UpdateAgentResourceResponse {\n success: true;\n link: AgentResourceRowResponse;\n}\n\nexport interface UnlinkAgentResourceResponse {\n success: true;\n message: string;\n}\n\n// =============================================================================\n// RESPONSE TYPES — Skill Sync\n// =============================================================================\n\nexport interface SyncSkillsResultItem {\n connection_id: string;\n connection_name: string;\n uploaded: number;\n failed: number;\n errors: string[];\n}\n\nexport interface SyncSkillsResponse {\n success: true;\n message: string;\n results: SyncSkillsResultItem[];\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Live Update Navigation\n// ---------------------------------------------------------------------------\n\n// User-facing nav values only. `chat_task` is an internal cache-sharing\n// fetch mode (never a persisted nav state), so it is intentionally excluded.\nexport const navItemSchema = z.enum(['chat', 'support', 'task']);\n\nexport const hubCountResetBody = z.object({\n hub_id: z.string().uuid(),\n nav_item: navItemSchema,\n conversation_id: z.string().uuid().optional(),\n hub_user_id: z.string().optional(),\n current_team_user_id: z.string().optional(),\n});\n\nexport const navItemCountResetBody = z.object({\n nav_item: navItemSchema,\n});\n\n// ---------------------------------------------------------------------------\n// Typing Indicator\n// ---------------------------------------------------------------------------\n\nexport const typingBody = z.object({\n conversationId: z.string().uuid(),\n hubId: z.string().uuid(),\n action: z.enum(['start', 'stop']),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type HubCountResetBody = z.infer<typeof hubCountResetBody>;\nexport type NavItemCountResetBody = z.infer<typeof navItemCountResetBody>;\nexport type TypingBody = z.infer<typeof typingBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface NavigationCounts {\n chat_count: number;\n support_count: number;\n task_count: number;\n}\n\n/** GET /counts */\nexport interface GetNavigationCountsResponse {\n success: true;\n data: NavigationCounts;\n}\n\n/** POST /reset-hub */\nexport interface ResetHubCountResponse {\n success: true;\n message: string;\n updated: boolean;\n}\n\n/** POST /reset-nav */\nexport interface ResetNavItemCountResponse {\n success: true;\n message: string;\n}\n\n/** POST /typing */\nexport interface TypingResponse {\n success: true;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Analytics Schema & Hubs\n// ---------------------------------------------------------------------------\n\n// No request schema needed for GET /schema (no params)\n\nexport const analyticsHubIdParam = z.object({\n hubId: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Variables\n// ---------------------------------------------------------------------------\n\nexport const analyticsVariableIdParam = z.object({\n variableId: z.string().uuid(),\n});\n\n// Variable names produced by default message_evaluator (PR1). Source of truth for chip-bar seeding + default badge — keep in sync with DEFAULT_EVALUATOR_PARAMETERS in hub-do.ts.\nexport const DEFAULT_EVALUATOR_VARIABLES = [\n 'goal_achieved',\n 'user_sentiment',\n 'conversation_summary',\n] as const;\n\nexport const updateVariablePinBody = z.object({\n pin: z.union([z.boolean(), z.string()]),\n});\n\n// ---------------------------------------------------------------------------\n// Analytics view (chip bar selection — shared across hub admins)\n// ---------------------------------------------------------------------------\n\nexport const updateAnalyticsViewBody = z.object({\n // 64 covers UUIDs (36) and the `sys:{name}` synthetic IDs for system variables.\n selected_variable_ids: z.array(z.string().min(1).max(64)).max(200),\n});\n\n// ---------------------------------------------------------------------------\n// Filter & aggregation literals (single source of truth — drives Zod schemas\n// below and is re-exported for runtime use by clients like the CLI).\n// ---------------------------------------------------------------------------\n\nexport const NUMERIC_FILTER_OPS = ['eq', 'neq', 'gt', 'gte', 'lt', 'lte'] as const;\nexport const TEXT_FILTER_OPS = ['equals', 'not_equals', 'contains', 'not_contains', 'starts_with', 'ends_with'] as const;\nexport const CATEGORICAL_FILTER_OPS = ['is', 'is_not', 'in', 'not_in'] as const;\nexport const VARIABLE_FILTER_OPS = [\n ...NUMERIC_FILTER_OPS,\n ...TEXT_FILTER_OPS,\n ...CATEGORICAL_FILTER_OPS,\n] as const;\n\nexport const STRUCTURED_QUERY_OPS = ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'in', 'not_in', 'like'] as const;\nexport const STRUCTURED_QUERY_AGGREGATIONS = ['avg', 'sum', 'min', 'max', 'count', 'quantile', 'stddevPop', 'corr', 'uniq'] as const;\n\n// ---------------------------------------------------------------------------\n// Conversations\n// ---------------------------------------------------------------------------\n\nconst filterValueSchema = z.object({\n variable_id: z.string(),\n filter_type: z.enum(VARIABLE_FILTER_OPS),\n filter_value: z.union([z.string(), z.number()]),\n});\n\nexport const conversationsBody = z.object({\n hub_id: z.string().uuid(),\n time_interval: z.object({\n start: z.string().optional(),\n end: z.string().optional(),\n }).optional(),\n filters: z.array(filterValueSchema).optional(),\n limit: z.number().int().positive().max(500).default(50),\n offset: z.number().int().min(0).default(0),\n});\n\n// ---------------------------------------------------------------------------\n// Conversation Messages\n// ---------------------------------------------------------------------------\n\nexport const analyticsConversationIdParam = z.object({\n conversationId: z.string().uuid(),\n});\n\nexport const messagesQuery = z.object({\n hub_id: z.string().uuid(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Conversation Detail Data\n// ---------------------------------------------------------------------------\n\nexport const conversationDetailDataQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\nexport type ConversationDetailDataQuery = z.infer<typeof conversationDetailDataQuery>;\n\n// ---------------------------------------------------------------------------\n// Analytics Data\n// ---------------------------------------------------------------------------\n\nexport const analyticsDataBody = z.object({\n hub_id: z.string().uuid(),\n periodicity: z.enum(['daily', 'weekly', 'monthly', 'yearly']),\n time_interval: z.object({\n start: z.string(),\n end: z.string(),\n }),\n trend_analysis: z.boolean(),\n filters: z.array(filterValueSchema).optional(),\n selected_variables: z.array(z.string()),\n include_summary: z.boolean().optional(),\n include_variables: z.boolean().optional(),\n variable_origin: z.enum(['agent', 'system']).optional(),\n variable_category: z.string().optional(),\n variables_only: z.boolean().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Structured Query\n// ---------------------------------------------------------------------------\n\nexport const structuredQueryBody = z.object({\n hub_id: z.string().uuid(),\n metrics: z.array(z.object({\n column: z.string(),\n aggregation: z.enum(STRUCTURED_QUERY_AGGREGATIONS),\n alias: z.string().optional(),\n corr_with: z.string().optional(),\n quantile_level: z.number().min(0).max(1).optional(),\n })).min(1),\n group_by: z.array(z.string()).optional(),\n order_by: z.array(z.object({\n column: z.string(),\n direction: z.enum(['asc', 'desc']).optional(),\n })).optional(),\n filters: z.array(z.object({\n column: z.string(),\n operator: z.enum(STRUCTURED_QUERY_OPS),\n value: z.union([z.string(), z.number(), z.boolean()]),\n })).optional(),\n time_range: z.object({\n start: z.string(),\n end: z.string(),\n }).optional(),\n limit: z.number().int().positive().max(10000).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Read-only SQL (CLI agent surface — POST /sql, GET /sql/schema)\n// ---------------------------------------------------------------------------\n\nexport const analyticsSqlBody = z.object({\n hub_id: z.string().uuid(),\n // Hard size cap before the validator runs — keeps lex/parse work bounded.\n sql: z.string().min(1).max(8000),\n limit: z.number().int().positive().max(10000).optional(),\n});\n\nexport const analyticsSqlSchemaQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type AnalyticsHubIdParam = z.infer<typeof analyticsHubIdParam>;\nexport type AnalyticsVariableIdParam = z.infer<typeof analyticsVariableIdParam>;\nexport type UpdateVariablePinBody = z.infer<typeof updateVariablePinBody>;\nexport type UpdateAnalyticsViewBody = z.infer<typeof updateAnalyticsViewBody>;\nexport type ConversationsBody = z.infer<typeof conversationsBody>;\nexport type AnalyticsConversationIdParam = z.infer<typeof analyticsConversationIdParam>;\nexport type MessagesQuery = z.infer<typeof messagesQuery>;\nexport type AnalyticsDataBody = z.infer<typeof analyticsDataBody>;\nexport type StructuredQueryBody = z.infer<typeof structuredQueryBody>;\nexport type AnalyticsSqlBody = z.infer<typeof analyticsSqlBody>;\nexport type AnalyticsSqlSchemaQuery = z.infer<typeof analyticsSqlSchemaQuery>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n// ---------------------------------------------------------------------------\n// Shared primitives (used across multiple responses)\n// ---------------------------------------------------------------------------\n\nexport type NumericFilterType = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte';\nexport type TextFilterType = 'equals' | 'not_equals' | 'contains' | 'not_contains' | 'starts_with' | 'ends_with';\nexport type CategoricalFilterType = 'is' | 'is_not' | 'in' | 'not_in';\nexport type FilterType = NumericFilterType | TextFilterType | CategoricalFilterType;\n\nexport type VariableOrigin = 'agent' | 'system';\nexport type Periodicity = 'daily' | 'weekly' | 'monthly' | 'yearly';\n\nexport interface TimeInterval {\n start: string;\n end: string;\n}\n\nexport interface VariableFilter {\n variable_id: string;\n filter_type: FilterType;\n filter_value: string | number;\n}\n\n// ---------------------------------------------------------------------------\n// GET /schema — analytics hierarchy\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsSchemaResponse {\n data: {\n flat: {\n organizations: Array<{ id: string; name: string }>;\n hubsByOrg: Record<string, Array<{ id: string; name: string }>>;\n };\n lastUpdated: string;\n };\n}\n\n// ---------------------------------------------------------------------------\n// GET /hubs — hubs list\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsHubInfo {\n hub_id: string;\n hub_name: string;\n hub_description: string | null;\n}\n\nexport interface AnalyticsHubsListResponse {\n success: true;\n hubs: AnalyticsHubInfo[];\n}\n\n// ---------------------------------------------------------------------------\n// GET /hubs/:hubId/variables — variables by hub\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsCategoryInfo {\n category: string;\n label: string;\n variableCount: number;\n}\n\nexport interface AnalyticsConversationVariable {\n variable_id: string;\n variable_name: string;\n variable_description?: string;\n variable_label?: string;\n variable_type: 'numeric' | 'categorical' | 'text';\n variable_origin: string;\n variable_category: string;\n variable_enum: unknown[];\n pin: boolean;\n hub_id?: string;\n}\n\nexport interface AnalyticsVariablesByHubResponse {\n success: true;\n data: {\n categories: AnalyticsCategoryInfo[];\n variablesByCategory: Record<string, AnalyticsConversationVariable[]>;\n };\n}\n\n// ---------------------------------------------------------------------------\n// PATCH /variables/:variableId/pin — update pin status\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsUpdatePinResponse {\n success: true;\n data: {\n variable_id: string;\n pin: boolean;\n };\n}\n\n// ---------------------------------------------------------------------------\n// GET / PUT /hubs/:hubId/selection — analytics view (chip bar) selection\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsViewResponse {\n success: true;\n data: {\n selected_variable_ids: string[];\n seeded: boolean;\n };\n}\n\n// ---------------------------------------------------------------------------\n// POST /conversations — conversation list\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsConversationListItem {\n conversation_id: string;\n created_at?: string;\n updated_at?: string;\n message_count?: number;\n message_text?: string;\n participant_name?: string;\n participant_phone?: string;\n hub_name?: string;\n user_name?: string;\n user_sentiment?: string;\n goal_achieved?: string;\n [key: string]: unknown;\n}\n\nexport interface AnalyticsConversationsListResponse {\n success: true;\n conversations: AnalyticsConversationListItem[];\n total: number;\n offset: number;\n limit: number;\n /**\n * True when ClickHouse was cold and the response is a provisional empty\n * result — the client should keep polling until this flag disappears.\n */\n cold?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// GET /conversations/:conversationId/messages — messages\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsConversationMessage {\n message_id: string;\n message_key?: string;\n created_at: string;\n message_text?: string;\n message_type: string;\n sender_type: string;\n receiver_type: string;\n channel_type: string;\n sender_name?: string;\n}\n\nexport interface AnalyticsConversationMessagesResponse {\n success: true;\n messages?: AnalyticsConversationMessage[];\n conversation?: {\n conversation_id: string;\n participant_name?: string;\n };\n}\n\n// ---------------------------------------------------------------------------\n// GET /conversations/:conversationId/data — conversation detail data\n// ---------------------------------------------------------------------------\n\nexport interface ConversationDetailVariableValue {\n name: string;\n value: string | number | null;\n label?: string;\n description?: string;\n type?: 'numeric' | 'categorical' | 'text';\n category?: string;\n variable_enum?: unknown[];\n}\n\nexport interface ConversationDetailDataResponse {\n success: true;\n conversation_id: string;\n hub_id: string;\n system: ConversationDetailVariableValue[];\n variables: ConversationDetailVariableValue[];\n meta: Record<string, string | number | null>;\n /**\n * True when ClickHouse was cold and the response is a provisional empty\n * result — the client should keep polling until this flag disappears.\n */\n cold?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// POST /data — analytics data (numeric, categorical, text)\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsTrendDataPoint {\n period: string;\n value: number | string | Record<string, number>;\n}\n\nexport interface AnalyticsMetrics {\n average: number;\n sum: number;\n minimum: number;\n maximum: number;\n count?: number;\n median?: number;\n}\n\nexport interface AnalyticsDataItem {\n variable: string;\n variable_id: string;\n type: 'numeric' | 'categorical' | 'text';\n data?: AnalyticsTrendDataPoint[];\n metrics?: AnalyticsMetrics;\n distribution?: Record<string, number>;\n}\n\nexport interface AnalyticsSummaryTrendData {\n period: string;\n total_conversations: number;\n ai_only_rate: number;\n avg_response_time: number;\n assistant_response_time: number;\n support_response_time: number;\n user_response_time: number;\n}\n\nexport interface AnalyticsSummaryData {\n total_conversations: number;\n ai_only_rate: number;\n avg_response_time: number;\n assistant_response_time: number;\n support_response_time: number;\n user_response_time: number;\n data?: AnalyticsSummaryTrendData[];\n}\n\n/** Response for variables_only=true requests */\nexport interface AnalyticsVariablesOnlyResponse {\n variables: unknown[];\n}\n\n/** Full analytics data response (POST /data) */\nexport interface AnalyticsDataResponse {\n analytics: AnalyticsDataItem[];\n summary?: AnalyticsSummaryData;\n variables?: unknown[];\n /**\n * True when any of the parallel fan-out queries (numeric / categorical /\n * text / summary) returned a cold-start outcome. The frontend uses this\n * single flag to flip the cold store and show the cold-start banner.\n */\n cold?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// POST /query — structured analytics query\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsStructuredQueryResponse {\n success: true;\n data: Record<string, unknown>[];\n statistics?: {\n elapsed: number;\n rows_read: number;\n bytes_read: number;\n };\n}\n\n// ---------------------------------------------------------------------------\n// POST /sql — read-only SQL (CLI agent surface). Same shape as /query plus a\n// `cold` flag so the agent can distinguish a genuine empty result from a\n// ClickHouse cold-start (mirrors the existing analytics cold-start contract\n// on `/conversations`, `/data`, `/conversations/:id/data`).\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsSqlResponse {\n success: true;\n data: Record<string, unknown>[];\n statistics?: {\n elapsed: number;\n rows_read: number;\n bytes_read: number;\n };\n cold?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// GET /sql/schema — column + variable-path catalog the agent can introspect\n// ---------------------------------------------------------------------------\n\nexport interface AnalyticsSqlSchemaPath {\n path: string;\n type: 'numeric' | 'categorical' | 'text' | 'unknown';\n origin: 'system' | 'agent';\n category?: string;\n description?: string;\n}\n\nexport interface AnalyticsSqlSchemaResponse {\n success: true;\n data: {\n table: 'conversation';\n top_level: Array<{ column: string; type: string }>;\n paths: AnalyticsSqlSchemaPath[];\n };\n}\n","import { z } from 'zod';\nimport { PACING_INTERVAL_MAX_MS, PACING_INTERVAL_MIN_MS, EVAL_RUN_DEADLINE_MIN_MS, EVAL_RUN_DEADLINE_MAX_MS } from '../eval-pacing';\n\n// ---------------------------------------------------------------------------\n// Common\n// ---------------------------------------------------------------------------\n\nconst paginationSchema = z.object({\n limit: z.number().int().positive().max(1000).default(50),\n offset: z.number().int().min(0).default(0),\n}).optional();\n\nconst evalIdParam = z.object({\n id: z.string().uuid(),\n});\n\nconst sessionIdParam = z.object({\n id: z.string().uuid(),\n});\n\nconst scenarioSetIdParam = z.object({\n id: z.string().uuid(),\n});\n\nconst hubIdQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Eval CRUD\n// ---------------------------------------------------------------------------\n\nexport const createEvalBody = z.object({\n eval: z.record(z.unknown()),\n});\n\nexport const updateEvalBody = z.object({\n eval: z.record(z.unknown()),\n});\n\nexport const getEvalsQuery = z.object({\n hub_id: z.string().uuid(),\n agent_id: z.string().uuid().optional(),\n enabled: z.string().regex(/^(true|false)$/).optional(),\n search: z.string().optional(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Toggle / Bulk Toggle\n// ---------------------------------------------------------------------------\n\nexport const toggleEvalBody = z.object({\n enabled: z.boolean(),\n});\n\nexport const bulkToggleEvalsBody = z.object({\n hub_id: z.string().uuid(),\n enabled: z.boolean(),\n filters: z.object({\n agent_id: z.string().uuid().optional(),\n search: z.string().optional(),\n }).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Sessions\n// ---------------------------------------------------------------------------\n\nexport const pacingConfigSchema = z.object({\n preset: z.enum(['conservative', 'custom']),\n custom_interval_ms: z.number().int().min(PACING_INTERVAL_MIN_MS).max(PACING_INTERVAL_MAX_MS).optional(),\n}).refine(\n (v) => v.preset !== 'custom' || typeof v.custom_interval_ms === 'number',\n { message: 'custom_interval_ms required when preset is \"custom\"' },\n);\n\n// `pacing` is the only client-supplied session_config field today; the backend\n// also writes `agent` and `scenario_set_id` snapshots during run-session.\n// `passthrough()` on both layers preserves those server-managed fields and\n// keeps room for future client-side keys without contract churn.\nexport const sessionConfigSchema = z.object({\n pacing: pacingConfigSchema.optional(),\n // Per-run finalization deadline for the HubDO watchdog (gh #2591). A started\n // run idle past this many ms is reaped to `failed`. Omitted → backend default\n // (`EVAL_DEFAULT_RUN_DEADLINE_MS`).\n run_deadline_ms: z.number().int().min(EVAL_RUN_DEADLINE_MIN_MS).max(EVAL_RUN_DEADLINE_MAX_MS).optional(),\n}).passthrough();\n\nexport const createSessionBody = z.object({\n session: z.object({\n session_config: sessionConfigSchema.optional(),\n }).passthrough(),\n});\n\nexport const getSessionsQuery = z.object({\n hub_id: z.string().uuid(),\n status: z.string().optional(),\n search: z.string().optional(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Results & Runs\n// ---------------------------------------------------------------------------\n\nexport const getSessionResultsQuery = z.object({\n hub_id: z.string().uuid(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n});\n\nexport const getSessionRunsQuery = z.object({\n hub_id: z.string().uuid(),\n eval_id: z.string().uuid().optional(),\n limit: z.string().regex(/^\\d+$/).optional(),\n offset: z.string().regex(/^\\d+$/).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Analytics\n// ---------------------------------------------------------------------------\n\nexport const evalAnalyticsQuery = z.object({\n hub_id: z.string().uuid(),\n start_date: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n end_date: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n periodicity: z.enum(['daily', 'weekly', 'monthly']).optional(),\n eval_id: z.string().uuid().optional(),\n session_id: z.string().uuid().optional(),\n});\n\nexport const getSessionCostQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Compare sessions\n// ---------------------------------------------------------------------------\n\nexport const compareSessionsQuery = z.object({\n hub_id: z.string().uuid(),\n session_a: z.string().uuid(),\n session_b: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Read-only SQL (CLI agent surface — POST /sql, GET /sql/schema)\n// Scopes the conversation table to `is_eval = true` (mirrors /api/analytics/sql).\n// ---------------------------------------------------------------------------\n\nexport const evalsSqlBody = z.object({\n hub_id: z.string().uuid(),\n // Hard size cap before the validator runs — keeps lex/parse work bounded.\n sql: z.string().min(1).max(8000),\n limit: z.number().int().positive().max(10000).optional(),\n});\n\nexport const evalsSqlSchemaQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Export\n// ---------------------------------------------------------------------------\n\nexport const exportResultsQuery = z.object({\n format: z.enum(['csv', 'json']).default('csv'),\n});\n\n// ---------------------------------------------------------------------------\n// Validate\n// ---------------------------------------------------------------------------\n\nexport const validateEvalBody = z.object({\n eval: z.record(z.unknown()),\n});\n\n// ---------------------------------------------------------------------------\n// Hub Agents\n// ---------------------------------------------------------------------------\n\nexport const hubAgentsQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Scenario sets\n// ---------------------------------------------------------------------------\n\nexport const createScenarioSetBody = z.object({\n hub_id: z.string().uuid(),\n set_name: z.string().min(1).max(200),\n description: z.string().max(1000).optional(),\n enabled: z.boolean().optional(),\n});\n\nexport const updateScenarioSetBody = z.object({\n set_name: z.string().min(1).max(200).optional(),\n description: z.string().max(1000).nullable().optional(),\n enabled: z.boolean().optional(),\n});\n\nexport const scenarioSetsHubQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Production replay — create scenario from a real conversation\n// ---------------------------------------------------------------------------\n\nexport const createScenarioFromConversationBody = z.object({\n hub_id: z.string().uuid(),\n conversation_id: z.string().uuid(),\n scenario_set_id: z.string().uuid(),\n scenario_name: z.string().min(1).max(200),\n evaluator_instructions: z.string().max(4000).optional(),\n});\n\n// Re-export param schemas\nexport { evalIdParam, sessionIdParam, scenarioSetIdParam, hubIdQuery };\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type EvalIdParam = z.infer<typeof evalIdParam>;\nexport type SessionIdParam = z.infer<typeof sessionIdParam>;\nexport type ScenarioSetIdParam = z.infer<typeof scenarioSetIdParam>;\nexport type CreateEvalBody = z.infer<typeof createEvalBody>;\nexport type UpdateEvalBody = z.infer<typeof updateEvalBody>;\nexport type GetEvalsQuery = z.infer<typeof getEvalsQuery>;\nexport type ToggleEvalBody = z.infer<typeof toggleEvalBody>;\nexport type BulkToggleEvalsBody = z.infer<typeof bulkToggleEvalsBody>;\nexport type CreateSessionBody = z.infer<typeof createSessionBody>;\nexport type GetSessionsQuery = z.infer<typeof getSessionsQuery>;\nexport type GetSessionResultsQuery = z.infer<typeof getSessionResultsQuery>;\nexport type GetSessionRunsQuery = z.infer<typeof getSessionRunsQuery>;\nexport type EvalAnalyticsQuery = z.infer<typeof evalAnalyticsQuery>;\nexport type ExportResultsQuery = z.infer<typeof exportResultsQuery>;\nexport type ValidateEvalBody = z.infer<typeof validateEvalBody>;\nexport type HubAgentsQuery = z.infer<typeof hubAgentsQuery>;\nexport type CreateScenarioSetBody = z.infer<typeof createScenarioSetBody>;\nexport type UpdateScenarioSetBody = z.infer<typeof updateScenarioSetBody>;\nexport type ScenarioSetsHubQuery = z.infer<typeof scenarioSetsHubQuery>;\nexport type CompareSessionsQuery = z.infer<typeof compareSessionsQuery>;\nexport type CreateScenarioFromConversationBody = z.infer<typeof createScenarioFromConversationBody>;\nexport type EvalsSqlBody = z.infer<typeof evalsSqlBody>;\nexport type EvalsSqlSchemaQuery = z.infer<typeof evalsSqlSchemaQuery>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n// -- Status types --\n\nexport type EvalStatus = 'enabled' | 'disabled';\nexport type SessionStatus = 'draft' | 'agents_responding' | 'awaiting_review' | 'completed' | 'failed' | 'cancelled';\nexport type RunStatus = 'pending' | 'running' | 'agent_responded' | 'completed' | 'failed';\n\n// -- Tool call structures --\n\nexport interface ToolCallResponse {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n// -- Message structures --\n\nexport interface MessageHistoryItemResponse {\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string | null;\n tool_calls?: ToolCallResponse[];\n tool_call_id?: string;\n}\n\nexport interface ExpectedResponseData {\n role: 'assistant';\n content: string | null;\n tool_calls?: ToolCallResponse[];\n}\n\nexport interface EvalResponseData {\n role: 'assistant';\n content: string;\n /**\n * The tool calls the agent made this turn (name + arguments). Present for\n * tool-call evals so `eval-results --runs` is self-contained — the verdict,\n * the reasoning, AND the actual call — without opening the conversation\n * (gh #2597). Omitted when the agent made no tool calls. Same shape as\n * `ExpectedResponseData.tool_calls` so expected vs. actual can be diffed.\n */\n tool_calls?: ToolCallResponse[];\n metadata?: {\n response_time_ms?: number;\n model_used?: string;\n tokens_used?: number;\n };\n}\n\n// -- Entity response types --\n\n/** Full eval row as returned by the eval table. Scenarios MUST belong to a scenario set. */\nexport interface EvalResponse {\n eval_id: string;\n created_at: string;\n updated_at: string;\n hub_id: string;\n user_id: string;\n responder_agent_id: string;\n eval_name: string;\n scenario_set_id: string;\n evaluator_instructions?: string;\n message_history: MessageHistoryItemResponse[];\n message_text: MessageHistoryItemResponse;\n message_expected_response: ExpectedResponseData;\n number_of_runs: number;\n enabled: boolean;\n created_by: string;\n}\n\n/** Frozen agent configuration captured at session-launch time. */\nexport interface AgentConfigSnapshot {\n agent_id: string;\n agent_name: string | null;\n agent_role: string | null;\n instructions: string | null;\n response_format: string | null;\n schema_name: string | null;\n schema_json: unknown;\n agent_settings: unknown;\n enabled: boolean;\n connection: { connection_id: string | null; connector_id: string | null; model_name: string | null } | null;\n tools: Array<Record<string, unknown>>;\n resources: Array<{ resource_id: string; version?: string | null }>;\n}\n\n/** Frozen scenario content captured per `eval_session_run`. */\nexport interface ScenarioSnapshot {\n message_text: unknown;\n message_expected_response: unknown;\n message_history: unknown;\n evaluator_instructions: string | null;\n}\n\n/** Internal RPC input for `HubDO.completeEvalRun` (not a public route). */\nexport interface CompleteEvalRunInput {\n run_id: string;\n status: 'completed' | 'failed';\n agent_response?: string;\n /** Tool calls the agent made this turn — persisted alongside `agent_response` (gh #2597). */\n agent_tool_calls?: ToolCallResponse[];\n execution_time_ms: number;\n error_message?: string;\n score_dimensions?: Record<string, unknown>;\n response_match?: boolean | null;\n}\n\n/** Eval scenario set row. */\nexport interface ScenarioSetResponse {\n scenario_set_id: string;\n set_name: string;\n description?: string | null;\n enabled: boolean;\n created_by?: string | null;\n created_at: string;\n updated_at?: string;\n}\n\n/** Eval with joined agent data, as returned by list endpoint */\nexport interface EvalWithAgentResponse extends EvalResponse {\n agent?: {\n agent_id: string;\n agent_name: string;\n agent_role: string;\n } | null;\n}\n\n/** Eval session row */\nexport interface EvalSessionResponse {\n eval_session_id: string;\n created_at: string;\n updated_at: string;\n hub_id: string;\n session_name: string;\n session_description?: string;\n session_status: SessionStatus;\n started_at?: string;\n completed_at?: string;\n total_evals: number;\n total_runs: number;\n successful_runs: number;\n failed_runs: number;\n created_by: string;\n /** Optional — sessions created pre-PR2 may not have this. */\n scenario_set_id?: string | null;\n /**\n * Snapshot of the responder agent + scenario_set_id captured at session-launch time.\n * `agent` may be missing on sessions created pre-PR2; consumers must render gracefully.\n */\n session_config?: {\n agent?: AgentConfigSnapshot;\n scenario_set_id?: string;\n pacing?: {\n preset: 'conservative' | 'custom';\n custom_interval_ms?: number;\n };\n };\n}\n\n/** Session result row with optional joined eval */\nexport interface EvalSessionResultResponse {\n eval_session_result_id: string;\n created_at: string;\n updated_at: string;\n eval_session_id: string;\n eval_id: string;\n total_runs: number;\n successful_runs: number;\n failed_runs: number;\n pending_runs: number;\n running_runs: number;\n avg_execution_time_ms?: number;\n min_execution_time_ms?: number;\n max_execution_time_ms?: number;\n aggregated_scores?: Record<string, { avg: number; min: number; max: number }>;\n success_rate: number;\n eval_status: RunStatus;\n started_at?: string;\n completed_at?: string;\n eval?: EvalResponse | null;\n}\n\n/** Individual run result row with optional joined eval */\nexport interface EvalSessionRunResponse {\n eval_session_run_id: string;\n created_at: string;\n updated_at: string;\n eval_session_id: string;\n eval_id: string;\n conversation_id?: string;\n run_number: number;\n eval_response: EvalResponseData;\n response_match: boolean | null;\n response_comment?: string;\n execution_time_ms?: number;\n run_status: RunStatus;\n error_message?: string;\n started_at?: string;\n completed_at?: string;\n scores?: Record<string, number>;\n metadata?: Record<string, unknown>;\n eval?: {\n eval_id: string;\n eval_name: string;\n responder_agent_id: string;\n } | null;\n}\n\n// -- Analytics response types --\n\nexport interface AgentPerformanceResponse {\n agent_id: string;\n agent_name: string;\n success_rate: number;\n total_runs: number;\n avg_execution_time: number;\n}\n\nexport interface TrendDataResponse {\n date: string;\n success_rate: number;\n total_runs: number;\n avg_execution_time: number;\n}\n\nexport interface ScoreDimensionData {\n dimension: string;\n avg_score: number;\n min_score: number;\n max_score: number;\n count: number;\n}\n\nexport interface EvalAnalyticsData {\n totalEvals: number;\n enabledEvals: number;\n totalSessions: number;\n completedSessions: number;\n overallSuccessRate: number;\n avgExecutionTime: number;\n topPerformingAgents: AgentPerformanceResponse[];\n recentTrends: TrendDataResponse[];\n scoreDimensions: ScoreDimensionData[];\n}\n\n// -- Reference types (for dropdowns) --\n\nexport interface EvalAgentReference {\n agent_id: string;\n agent_name: string;\n agent_role: string;\n}\n\nexport interface EvalHubReference {\n hub_id: string;\n hub_name: string;\n hub_description?: string;\n}\n\n// -- Pagination --\n\nexport interface EvalPaginationResponse {\n limit: number;\n offset: number;\n has_more: boolean;\n}\n\n// =============================================================================\n// ENDPOINT RESPONSE WRAPPERS\n// =============================================================================\n\nexport interface GetEvalsResponse {\n success: true;\n data: {\n evals: EvalWithAgentResponse[];\n total_count: number;\n pagination?: EvalPaginationResponse;\n };\n}\n\nexport interface CreateEvalResponse {\n success: true;\n data: { eval: EvalResponse };\n message: string;\n}\n\nexport interface UpdateEvalResponse {\n success: true;\n data: { eval: EvalResponse };\n message: string;\n}\n\nexport interface DeleteEvalResponse {\n success: true;\n message: string;\n}\n\nexport interface DeleteEvalErrorResponse {\n success: false;\n error: 'not_found';\n message: string;\n}\n\nexport interface ToggleEvalResponse {\n success: true;\n data: { eval: EvalResponse };\n message: string;\n}\n\nexport interface BulkToggleEvalsResponse {\n success: true;\n data: {\n updated_count: number;\n updated_eval_ids: string[];\n };\n message: string;\n}\n\nexport interface GetSessionsResponse {\n success: true;\n data: {\n sessions: EvalSessionResponse[];\n total_count: number;\n pagination?: EvalPaginationResponse;\n };\n}\n\nexport interface CreateSessionResponse {\n success: true;\n data: { session: EvalSessionResponse };\n message: string;\n}\n\nexport interface RunSessionResponse {\n success: true;\n data: { session: EvalSessionResponse };\n message: string;\n}\n\nexport interface StopSessionResponse {\n success: true;\n data: { session: EvalSessionResponse };\n message: string;\n}\n\nexport interface DeleteSessionResponse {\n success: true;\n message: string;\n}\n\nexport interface GetSessionDetailsResponse {\n success: true;\n data: {\n session: EvalSessionResponse;\n results: EvalSessionResultResponse[];\n };\n}\n\nexport interface GetSessionResultsResponse {\n success: true;\n data: {\n results: EvalSessionResultResponse[];\n total_count: number;\n pagination?: EvalPaginationResponse;\n };\n}\n\nexport interface GetSessionRunsResponse {\n success: true;\n data: {\n runs: EvalSessionRunResponse[];\n total_count: number;\n session_id: string;\n pagination?: EvalPaginationResponse;\n };\n}\n\n/** Per-session resource cost — sums tokens and billable operations over the\n * unified `conversation` table where `is_eval = true AND eval_session_id = ?`.\n * `billable_operations_total` matches the OrgDO billing increment.\n * `cold` indicates ClickHouse cold-start; on cold, all numeric fields fall back to 0\n * and the client may retry. */\nexport interface EvalSessionCost {\n conversations_count: number;\n tokens_total: number;\n tokens_input: number;\n tokens_output: number;\n billable_operations_total: number;\n}\n\nexport interface GetEvalSessionCostResponse {\n success: true;\n data: {\n cost: EvalSessionCost;\n cold?: true;\n };\n}\n\nexport interface GetEvalAnalyticsResponse {\n success: true;\n data: {\n analytics: EvalAnalyticsData;\n };\n}\n\nexport interface ExportSessionResultsResponse {\n success: true;\n data: {\n download_url: string;\n filename: string;\n format: string;\n };\n message: string;\n}\n\nexport interface ValidateEvalResponse {\n success: true;\n data: {\n is_valid: boolean;\n validation_errors: string[];\n suggestions?: string[];\n };\n}\n\nexport interface GetHubAgentsResponse {\n success: true;\n data: {\n agents: EvalAgentReference[];\n };\n}\n\nexport interface GetHubsListResponse {\n success: true;\n data: {\n hubs: EvalHubReference[];\n };\n}\n\n// -- Scenario set wrappers --\n\nexport interface GetScenarioSetsResponse {\n success: true;\n data: {\n scenario_sets: ScenarioSetResponse[];\n total_count: number;\n };\n}\n\nexport interface GetScenarioSetResponse {\n success: true;\n data: { scenario_set: ScenarioSetResponse };\n}\n\nexport interface CreateScenarioSetResponse {\n success: true;\n data: { scenario_set: ScenarioSetResponse };\n message: string;\n}\n\nexport interface UpdateScenarioSetResponse {\n success: true;\n data: { scenario_set: ScenarioSetResponse };\n message: string;\n}\n\nexport interface DeleteScenarioSetResponse {\n success: true;\n message: string;\n}\n\nexport interface DeleteScenarioSetConflictResponse {\n success: false;\n error: 'scenario_set_not_empty';\n scenario_count: number;\n message: string;\n}\n\nexport interface ListScenariosBySetResponse {\n success: true;\n data: {\n scenarios: EvalResponse[];\n total_count: number;\n };\n}\n\n// -- Compare sessions --\n\n/** Per-scenario stats for a single session in a comparison. */\nexport interface CompareScenarioStats {\n total_runs: number;\n success_rate: number;\n avg_execution_time_ms: number;\n /** Per-dimension averages from `data.eval_scores.*` (excludes meta dimensions). */\n score_dimensions: Record<string, number>;\n}\n\n/** Aggregate session-level summary for the compare summary bar. */\nexport interface CompareSessionSummary {\n eval_session_id: string;\n session_name: string;\n scenario_set_id: string | null;\n scenario_set_name: string | null;\n agent: AgentConfigSnapshot | null;\n total_runs: number;\n success_rate: number;\n avg_execution_time_ms: number;\n tokens_total: number;\n billable_operations_total: number;\n}\n\n/** Per-scenario row in the diff table — only scenarios present in BOTH sessions. */\nexport interface CompareScenarioRow {\n eval_id: string;\n scenario_name: string;\n a: CompareScenarioStats;\n b: CompareScenarioStats;\n /** `b.success_rate - a.success_rate` (signed delta). */\n delta_success_rate: number;\n}\n\nexport interface CompareSessionsResponse {\n success: true;\n data: {\n session_a: CompareSessionSummary;\n session_b: CompareSessionSummary;\n per_scenario: CompareScenarioRow[];\n /** True when session A and B targeted different scenario sets — UI shows a warning. */\n scenario_sets_match: boolean;\n /** `cold` flags ClickHouse cold-start; numeric fields fall back to zeros and the client may retry. */\n cold?: true;\n };\n}\n\n// -- Production replay (create scenario from conversation) --\n\nexport interface CreateScenarioFromConversationResponse {\n success: true;\n data: { eval: EvalResponse };\n message: string;\n}\n\n// -- Read-only SQL (CLI agent surface) --\n\nexport interface EvalsSqlResponse {\n success: true;\n data: Record<string, unknown>[];\n statistics?: {\n elapsed: number;\n rows_read: number;\n bytes_read: number;\n };\n cold?: boolean;\n}\n\nexport interface EvalsSqlSchemaPath {\n path: string;\n type: 'numeric' | 'categorical' | 'text' | 'unknown';\n origin: 'system' | 'eval_scores';\n category?: string;\n description?: string;\n}\n\nexport interface EvalsSqlSchemaResponse {\n success: true;\n data: {\n table: 'conversation';\n top_level: Array<{ column: string; type: string }>;\n paths: EvalsSqlSchemaPath[];\n };\n}\n","/**\n * Eval session run pacing — controls how aggressively `scheduleEvalRuns`\n * stages evaluation runs. Default `conservative` leaves headroom for\n * production traffic on shared LLM API keys (provider rate limits are\n * org-scoped, not key-scoped, so the same key serving prod conversations\n * shares a budget with eval traffic).\n */\n\nexport const EVAL_PACING_PRESETS = {\n conservative: { base_delay_ms: 5000, run_interval_ms: 3000 },\n} as const;\n\nexport type EvalPacingPreset = 'conservative' | 'custom';\n\nexport const DEFAULT_PACING_PRESET: EvalPacingPreset = 'conservative';\n\nexport const PACING_INTERVAL_MIN_MS = 50;\nexport const PACING_INTERVAL_MAX_MS = 60000;\n\n/**\n * Hard ceiling on the total runs a single eval session may materialize\n * (Σ `number_of_runs` over a set's enabled scenarios). Per-scenario runs are\n * capped at 100 (create/update eval), but the scenario *count* is unbounded —\n * so without this a large set can materialize a session bigger than one\n * dispatch invocation can deliver. `scheduleEvalRuns` fans out from a single\n * Worker invocation making 2 ConversationDO RPCs per run; 1000 runs ≈ 2000\n * subrequests, comfortably under the 10k/invocation default with ~5× headroom,\n * and keeps the HubDO watchdog's never-started deadline (`total_runs × pacing\n * + grace + run_deadline`) bounded. Enforced server-side at session run\n * (reject, never clamp — silent truncation would misreport coverage).\n */\nexport const EVAL_MAX_SESSION_RUNS = 1000;\n\n/**\n * Per-run finalization deadline for the HubDO eval watchdog (gh #2591). A run\n * idle past this window (`now - eval_session_run.updated_at`) is reaped to\n * `failed`. The lease clock measures INACTIVITY, not total turn duration: it's\n * renewed at turn start, on each tool call within the agentic loop, and on every\n * rate-limit retry reschedule — so a legitimately long multi-step turn (many\n * LLM/tool calls) or a retrying run is never falsely reaped; only a genuinely\n * stalled turn (no progress — a tool/LLM call that never returns, a DO reset\n * mid-turn) trips it. The lease is renewed before AND after each tool call, so\n * the gap between two renewals is a single in-flight operation: one LLM round\n * (bounded at the 120s stream timeout) or one tool call. The default sits above\n * that 120s ceiling so a normal LLM round always clears. The residual is a\n * single tool call that itself exceeds the deadline — external tool fetches\n * currently have no execution timeout — which would reap a still-running turn;\n * the generous default + per-session `session_config.run_deadline_ms` override\n * are the mitigation until tool fetches are bounded.\n */\nexport const EVAL_DEFAULT_RUN_DEADLINE_MS = 180_000;\n\n/**\n * Buffer added on top of the computed pacing-dispatch span when deciding a run\n * that never started (`started_at IS NULL`) is overdue. The never-started\n * deadline is `session.started_at + dispatchSpan + grace + run_deadline`, where\n * `dispatchSpan` is derived from `total_runs × pacing` — so a legitimately\n * not-yet-dispatched paced run is never reaped. (A future per-run `dispatched_at`\n * makes this per-run-precise; this session-level estimate is correct meanwhile.)\n */\nexport const EVAL_SESSION_DISPATCH_GRACE_MS = 60_000;\n\n/** Clamp bounds for a session-configured `run_deadline_ms`. */\nexport const EVAL_RUN_DEADLINE_MIN_MS = 1_000;\nexport const EVAL_RUN_DEADLINE_MAX_MS = 1_800_000; // 30 min\n\nexport interface PacingConfig {\n preset: EvalPacingPreset;\n custom_interval_ms?: number;\n}\n\nexport interface ResolvedPacing {\n base_delay_ms: number;\n run_interval_ms: number;\n}\n\nexport function resolvePacing(config: PacingConfig | null | undefined): ResolvedPacing {\n if (!config || config.preset === 'conservative') {\n return EVAL_PACING_PRESETS.conservative;\n }\n if (config.preset === 'custom') {\n const raw = typeof config.custom_interval_ms === 'number' ? config.custom_interval_ms : EVAL_PACING_PRESETS.conservative.run_interval_ms;\n const clamped = Math.min(PACING_INTERVAL_MAX_MS, Math.max(PACING_INTERVAL_MIN_MS, Math.floor(raw)));\n return { base_delay_ms: EVAL_PACING_PRESETS.conservative.base_delay_ms, run_interval_ms: clamped };\n }\n return EVAL_PACING_PRESETS.conservative;\n}\n","import { z } from 'zod';\nimport type { AiMode } from '../constants';\nimport type { StateResponse } from './setup/states';\n\n// ---------------------------------------------------------------------------\n// Chat Conversations\n// ---------------------------------------------------------------------------\n\n// 'chat_task' is an internal combined-fetch value — /chat and /task share a\n// single cache keyed on this; the response carries both hub_type values and\n// the frontend filters client-side. Keeping it in the enum keeps typed\n// clients (Hono RPC, MCP, CLI) aware of the shape.\nexport const getConversationsQuery = z.object({\n nav_item: z.enum(['chat', 'task', 'support', 'chat_task']),\n hub_team_user_id: z.string().optional(),\n hub_user_id: z.string().optional(),\n search_filter: z.string().optional(),\n hub_id: z.string().uuid().optional(),\n conversation_id: z.string().uuid().optional(),\n // 'ended' = recently-closed, served warm from the HubDO index (≤ retention\n // window). 'archived' = the full closed-conversation history from ClickHouse.\n status: z.enum(['active', 'agent', 'team', 'ended', 'archived']).optional(),\n page: z.string().regex(/^\\d+$/).optional(),\n page_size: z.string().regex(/^\\d+$/).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Chat Messages\n// ---------------------------------------------------------------------------\n\nexport const getMessagesQuery = z.object({\n hub_id: z.string().uuid(),\n hub_team_user_id: z.string().optional(),\n hub_user_id: z.string().optional(),\n conversation_id: z.string().uuid().optional(),\n message_id: z.string().uuid().optional(),\n page: z.string().regex(/^\\d+$/).optional(),\n page_size: z.string().regex(/^\\d+$/).optional(),\n /**\n * When true AND the caller has support access (hub admin or hub team member),\n * internal messages (tool calls, tool results) are included in the response.\n * Silently ignored for non-support callers — it's a view preference, not an\n * authorization boundary.\n */\n include_internal: z\n .union([z.literal('true'), z.literal('false'), z.boolean()])\n .optional()\n .transform((v) => v === true || v === 'true'),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type GetConversationsQuery = z.infer<typeof getConversationsQuery>;\nexport type GetMessagesQuery = z.infer<typeof getMessagesQuery>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\n/** Team reference in a conversation */\nexport interface ConversationTeamRef {\n hub_team_id: string;\n team_name: string;\n}\n\n/** Agent reference in a conversation */\nexport interface ConversationAgentRef {\n agent_id: string;\n agent_name: string;\n}\n\n/** Browsable resource reference in a conversation */\nexport interface ConversationBrowsableResource {\n resource_id: string;\n resource_name: string;\n resource_description?: string;\n}\n\n/** Kanban status configuration item */\nexport interface ConversationKanbanStatus {\n slug: string;\n name: string;\n color: string;\n isTerminalStatus?: boolean;\n allowed_next_statuses?: string[];\n [key: string]: unknown;\n}\n\n/** Task hub available in metadata */\nexport interface AvailableTaskHub {\n hub_id: string;\n hub_name: string;\n app_channel_id: string | null;\n hub_environment?: 'preview' | 'production';\n}\n\n// Derived server-side from the viewer's user_id vs the conversation's claimer.\nexport type ClaimStatus = 'unclaimed' | 'claimed_by_this_user' | 'claimed_by_other_user';\n\n/** The nav slice a conversation belongs to for a given viewer. */\nexport type SourceNav = 'chat' | 'task' | 'support';\n\n/** Single conversation item returned by the get_conversations RPC */\nexport interface ConversationItemResponse {\n hub_id: string;\n user_id?: string;\n hub_team_user_id?: string;\n conversation_id: string;\n user_name?: string;\n hub_name?: string;\n hub_type?: 'task' | 'chat';\n hub_description?: string;\n hub_contexts?: string[];\n hub_environment?: 'preview' | 'production';\n is_support_hub?: boolean;\n kanban_statuses?: ConversationKanbanStatus[];\n project_name?: string;\n message_text?: string;\n message_status?: 'pending' | 'sent' | 'delivered' | 'read' | 'failed' | null;\n created_at?: string;\n sender_type?: string;\n receiver_type?: string;\n conversation_status?: string;\n /** Channel type of the last message — may be `app` for a team reply. */\n channel_type?: string;\n /** The conversation's bound customer channel (whatsapp/instagram/...) — distinct from `channel_type`. Feeds the support composer's 24h messaging-window gate. */\n current_channel_type?: string;\n /** Timestamp of the last customer (user) inbound message — feeds the 24h messaging-window gate. */\n last_inbound_at?: string;\n app_channel_id?: string;\n search_text?: string;\n sender_description?: string;\n receiver_description?: string;\n channel_description?: string;\n current_hub_team_id?: string;\n current_agent_id?: string;\n current_team_user_id?: string;\n current_responder_type?: string;\n /** Per-contact channel access: 'approved' | 'pending' | 'blocked'. Drives the support badge + composer gating. */\n access_status?: string;\n available_teams: ConversationTeamRef[];\n available_agents: ConversationAgentRef[];\n unread_message_count?: number;\n claim_status?: ClaimStatus;\n kanban_status?: string;\n ended_at?: string;\n // Set when conversation has been archived to R2. Null when ended_at is set\n // but archival hasn't completed (still in DO buffer). The frontend uses this\n // to decide between the archive endpoint and the active /messages endpoint.\n archived_at?: string | null;\n // Evaluator variables\n user_sentiment?: string;\n goal_achieved?: string;\n conversation_summary?: string;\n browsable_resources?: ConversationBrowsableResource[];\n is_flagged?: boolean;\n flag_source?: FlagSource;\n // Nav slices the row belongs to for this viewer. A conversation can belong to\n // more than one (e.g. a viewer who is both the end user AND a team member of a\n // hub sees it in BOTH the owner nav and /support — the roles are orthogonal).\n // The backend emits the row into each matching slice; per-slice it carries the\n // single-element set for that slice, and the frontend unions them by id.\n source_navs?: SourceNav[];\n}\n\n/** Source of a conversation flag. Set by evaluator or monitor background agents. */\nexport type FlagSource = 'evaluator' | 'monitor' | 'both' | null;\n\n/**\n * Merge an incoming flag source with an existing one.\n * Null/same-source → incoming; different existing source → 'both'.\n * Used by ConversationDO and HubDO to keep flag state consistent when the\n * same conversation is flagged by both evaluator and monitor.\n */\nexport function mergeFlagSource(\n existing: FlagSource,\n incoming: 'evaluator' | 'monitor',\n): Exclude<FlagSource, null> {\n if (existing === null || existing === incoming) return incoming;\n return 'both';\n}\n\n/** Hub metadata included in the conversations response */\nexport interface HubItemResponse {\n hub_id: string;\n hub_name?: string;\n hub_type?: 'chat' | 'task';\n hub_description?: string;\n hub_environment?: 'preview' | 'production';\n is_support_hub?: boolean;\n /** Routing/responder policy. Drives UI affordances like \"Transfer to Agent\". */\n ai_mode?: AiMode;\n /** Hub's IANA timezone — the lens the UI renders message timestamps in. */\n timezone?: string;\n /** Hub language (en|pt|es) — localizes the pending-access notice + backend-sent text. */\n language?: string;\n /** Who may approve/block pending contacts: 'admin' (default) or 'team'. Drives the approve/block UI gating. */\n access_approval_role?: 'admin' | 'team';\n /** Per-hub override for the pending-access notice text (null ⇒ localized default). */\n access_request_message?: string;\n app_channel_id?: string;\n kanban_statuses?: Array<{ slug: string; name: string; color: string; allowed_next_statuses?: string[]; isTerminalStatus?: boolean }>;\n available_teams: Array<{ hub_team_id: string; team_name: string }>;\n available_agents?: Array<{ agent_id: string; agent_name: string }>;\n /**\n * Whether the snapshot's user is an enabled hub admin on this hub. Drives\n * admin-only UI affordances (e.g. destructive deletes). Backend remains the\n * authoritative gate — this is a UI-visibility hint, not an auth decision.\n */\n is_current_user_admin?: boolean;\n // Pre-seeds Settings → States tab so it renders without a network round-trip.\n // Optional: omitted by older Worker versions; new clients fall back to a fetch.\n states?: StateResponse[];\n}\n\n/** RPC response from get_conversations (returned as JSON from the RPC) */\nexport interface GetConversationsRpcResponse {\n conversations: ConversationItemResponse[];\n hubs?: HubItemResponse[];\n metadata: {\n available_task_hubs?: AvailableTaskHub[];\n /** Pagination fields (present when status=ended) */\n total?: number;\n page?: number;\n page_size?: number;\n };\n /**\n * True when ClickHouse was cold and the response is a provisional empty\n * result — the client should keep polling until this flag disappears.\n */\n cold?: boolean;\n}\n\n/** File attachment in a message */\nexport interface MessageFileResponse {\n file_id?: string;\n bucket?: string;\n mime_type: string;\n file_name: string;\n file_short_name?: string;\n mime_category?: string;\n file_path: string;\n file_signed_url?: string;\n file_type?: string;\n file_size?: number;\n}\n\n/**\n * Diagnostic codes surfaced when AI message processing fails due to hub\n * misconfiguration. Each code has i18n copy (title + action) rendered in the\n * support view to guide the admin to a fix. `internal_error` is the\n * unknown-failure fallback and is the only code that logs at `error` level and\n * reaches Sentry.\n */\nexport type DiagnosticCode =\n | 'missing_pilot_connection'\n | 'hub_config_not_found'\n | 'credential_resolution_failed'\n | 'missing_api_key'\n | 'llm_provider_rejected'\n | 'rate_limit_exhausted'\n | 'internal_error';\n\nexport const DIAGNOSTIC_CODES: readonly DiagnosticCode[] = [\n 'missing_pilot_connection',\n 'hub_config_not_found',\n 'credential_resolution_failed',\n 'missing_api_key',\n 'llm_provider_rejected',\n 'rate_limit_exhausted',\n 'internal_error',\n] as const;\n\n/** Metadata shape for support-only error diagnostic messages (sender=system, receiver=team). */\nexport interface MessageErrorMetadata {\n is_error: true;\n error_code: DiagnosticCode;\n args?: Record<string, string>;\n}\n\n/** Single message item returned by the get_messages RPC */\nexport interface MessageItemResponse {\n message_key: string;\n message_id: string;\n conversation_id: string;\n message_text: string;\n message_status?: 'pending' | 'sent' | 'delivered' | 'read' | 'failed' | null;\n sender_type: string;\n receiver_type: string;\n created_at: string;\n conversation_created_at?: string;\n hub_type?: string;\n channel_type?: string;\n channel_id?: string;\n is_last_message?: boolean;\n files: MessageFileResponse[];\n sender_description?: string;\n receiver_description?: string;\n channel_description?: string;\n conversation_start?: boolean;\n metadata?: Record<string, unknown> | null;\n}\n\n// ---------------------------------------------------------------------------\n// ConversationDO composite read: ChatView\n// ---------------------------------------------------------------------------\n\n/**\n * Raw file row as stored in ConversationDO's `conversation_file` table,\n * returned attached to the owning message inside `ChatView.messages`.\n * Shape mirrors the SQLite row so the route layer can map it to\n * `MessageFileResponse` without additional DO round-trips.\n */\nexport interface ChatViewFile {\n file_id: string;\n message_id: string;\n /** Only populated by `getFiles` (archival read); omitted when the row is\n * joined onto a message in `getMessages` / `getChatView` to keep payloads small. */\n conversation_id?: string | null;\n file_name: string | null;\n file_path: string | null;\n bucket: string | null;\n mime_type: string | null;\n file_size: number | null;\n created_at: string | null;\n}\n\n/**\n * Raw message row plus any files joined by `message_id`.\n * `files` is always populated — an empty array when the message has no\n * attachments. This removes the `files=[]` fallback at route level because\n * the DO now joins the two tables in a single SQL transaction.\n */\nexport interface ChatViewMessage {\n message_id: string;\n conversation_id: string | null;\n message_text: string | null;\n message_type: string | null;\n sender_type: string | null;\n sender_id: string | null;\n sender_name: string | null;\n receiver_type: string | null;\n receiver_id: string | null;\n channel_type: string | null;\n channel_message_sid: string | null;\n keep_in_history: number | boolean | null;\n agent_id: string | null;\n agent_role: string | null;\n message_status: string | null;\n metadata: string | Record<string, unknown> | null;\n created_at: string;\n files: ChatViewFile[];\n}\n\n/**\n * Minimal conversation metadata returned by `getChatView`.\n * Only the fields used by the chat route to render the header / gate hub\n * ownership are returned — keeps the RPC payload small while still\n * eliminating a second DO round-trip per chat load.\n */\nexport interface ChatViewConversation {\n conversation_id: string;\n hub_id: string | null;\n user_id: string | null;\n status: string | null;\n current_responder_type: string | null;\n current_agent_id: string | null;\n current_channel_id: string | null;\n current_channel_type: string | null;\n kanban_status: string | null;\n created_at: string | null;\n updated_at: string | null;\n hub_type: string | null;\n // current_team_user_id is a platform user_id, not a hub_team_user_id.\n current_hub_team_id: string | null;\n current_team_user_id: string | null;\n}\n\n/**\n * Composite read response returned by `ConversationDO.getChatView`.\n * Combines messages (with joined files) and conversation metadata in a\n * single DO round-trip, replacing the legacy 2-fetch pattern\n * (v2GetMessages + v2GetConversation).\n */\nexport interface ChatView {\n conversation: ChatViewConversation | null;\n messages: ChatViewMessage[];\n total: number;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Update User\n// ---------------------------------------------------------------------------\n\nexport const updateUserBody = z.object({\n user_language: z.string().optional(),\n ui_dark_mode: z.boolean().optional(),\n profile_name: z.string().optional(),\n link_email_to_identities: z.boolean().optional(),\n}).refine(\n (data) => Object.values(data).some((v) => v !== undefined),\n { message: 'At least one field must be provided' },\n);\n\n// ---------------------------------------------------------------------------\n// Update Profile\n// ---------------------------------------------------------------------------\n\nexport const updateProfileBody = z.object({\n display_name: z.string().optional(),\n avatar_url: z.string().optional(),\n preferences: z.record(z.unknown()).optional(),\n}).refine(\n (data) => Object.values(data).some((v) => v !== undefined),\n { message: 'At least one field must be provided' },\n);\n\n// ---------------------------------------------------------------------------\n// Update Preferences (PATCH /users/preferences)\n// ---------------------------------------------------------------------------\n\n// Pathnames only. Leading `/` required; `(?!\\/)` rejects `//evil.com` scheme-relative URLs.\nconst pathnameRegex = /^\\/(?!\\/)[A-Za-z0-9\\-._~!$&'()*+,;=:@/?%]*$/;\n\nexport const updatePreferencesBody = z.object({\n last_viewed_nav: z.string().regex(pathnameRegex, 'Must be a URL pathname').max(2048).optional(),\n dismissed_agentic_shortcut: z.boolean().optional(),\n}).passthrough();\n\nexport type UpdatePreferencesBody = z.infer<typeof updatePreferencesBody>;\n\n// ---------------------------------------------------------------------------\n// Activity\n// ---------------------------------------------------------------------------\n\nexport const activityQuery = z.object({\n limit: z.coerce.number().int().min(1).max(100).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Account Deletion\n// ---------------------------------------------------------------------------\n\n/** Two modes — Scheduled (30-day grace, undoable) or Immediate (no undo). */\nexport const deletionModeSchema = z.enum(['scheduled', 'immediate']);\n\nexport const deletionRequestBody = z.object({\n mode: deletionModeSchema,\n /** User-supplied reason captured in the audit log; bounded to bound logged PII. */\n reason: z.string().max(500).optional(),\n /** Type-to-confirm value; must equal the user's email (constant-time compared). */\n email_confirmation: z.string().min(1).max(320),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type UpdateUserBody = z.infer<typeof updateUserBody>;\nexport type UpdateProfileBody = z.infer<typeof updateProfileBody>;\nexport type ActivityQuery = z.infer<typeof activityQuery>;\nexport type DeletionMode = z.infer<typeof deletionModeSchema>;\nexport type DeletionRequestBody = z.infer<typeof deletionRequestBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\n/** Navigation hints — which dashboard sections the user has hub access for */\nexport interface NavHints {\n has_chat: boolean;\n has_task: boolean;\n has_support: boolean;\n}\n\n/** Account deletion lifecycle as seen by the user-facing API. */\nexport type DeletionStatus = 'none' | 'grace' | 'purging' | 'purged';\n\n/** User data returned by GET/PATCH /users/me */\nexport interface UserDataResponse {\n user_id: string;\n user_language: string | null;\n ui_dark_mode: boolean | null;\n profile_name: string | null;\n link_email_to_identities: boolean | null;\n is_platform_admin: boolean;\n created_at: string;\n user_name: string | null;\n account_age_hours: number;\n team_ids: string[];\n nav_hints: NavHints;\n dismissed_agentic_shortcut: boolean;\n /** Active deletion lifecycle; `'none'` for the common case. */\n deletion_status: DeletionStatus;\n /** ISO-8601 timestamp when the cron will purge; null unless status='grace'. */\n deletion_scheduled_purge_at: string | null;\n}\n\n/** GET /users/me or PATCH /users/me */\nexport interface GetUserResponse {\n success: true;\n data: UserDataResponse;\n}\n\n/** Profile data returned by GET/PATCH /users/profile */\nexport interface ProfileDataResponse {\n user_id: string;\n display_name: string | null;\n email: string | null;\n avatar_url: string | null;\n preferences: Record<string, unknown> | null;\n created_at: string;\n updated_at: string | null;\n}\n\n/** GET /users/profile or PATCH /users/profile */\nexport interface GetProfileResponse {\n data: ProfileDataResponse;\n}\n\nexport interface UserPreferences {\n last_viewed_nav?: string;\n dismissed_agentic_shortcut?: boolean;\n [key: string]: unknown;\n}\n\n/** GET /users/preferences */\nexport interface GetPreferencesResponse {\n data: UserPreferences;\n}\n\n/** PATCH /users/preferences */\nexport interface UpdatePreferencesResponse {\n data: UserPreferences;\n}\n\n/** Activity log item */\nexport interface ActivityLogItem {\n activity_id: string;\n action: string;\n entity_type: string;\n entity_id: string;\n metadata: Record<string, unknown> | null;\n created_at: string;\n}\n\n/** GET /users/activity */\nexport interface GetActivityResponse {\n data: ActivityLogItem[];\n}\n\n// ---------------------------------------------------------------------------\n// Account Deletion — responses\n// ---------------------------------------------------------------------------\n\n/** Why the deletion preflight blocks the user from proceeding. */\nexport type DeletionBlocker =\n | {\n type: 'org_owner';\n org_id: string;\n org_name: string;\n has_active_subscription: boolean;\n }\n | {\n type: 'sole_admin';\n org_id: string;\n org_name: string;\n has_active_subscription: boolean;\n };\n\nexport interface DeletionSimpleRemoval {\n org_id: string;\n org_name: string;\n}\n\nexport interface DeletionHubGrant {\n hub_id: string;\n hub_name: string | null;\n role: 'admin' | 'user' | 'team_user';\n}\n\n/** GET /api/users/me/deletion/preflight */\nexport interface DeletionPreflightResponse {\n blocking: DeletionBlocker[];\n /** Orgs where the user is one admin among several — losing the user is a simple grant removal. */\n simple_removals: DeletionSimpleRemoval[];\n /** Hub-level grants without an associated admin role on the parent org. */\n hub_only_grants: DeletionHubGrant[];\n identity_count: number;\n conversation_count_estimate: number;\n}\n\n/** POST /api/users/me/deletion — accepted; describes the resulting state. */\nexport interface DeletionRequestResponse {\n status: Extract<DeletionStatus, 'grace' | 'purging'>;\n scheduled_purge_at: string | null;\n}\n\n/** DELETE /api/users/me/deletion — undo response. */\nexport interface DeletionAbortResponse {\n status: 'none';\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Archive Conversations\n// ---------------------------------------------------------------------------\n\nexport const archiveHubIdParam = z.object({\n hubId: z.string().uuid(),\n});\n\nexport const archiveConversationParams = z.object({\n hubId: z.string().uuid(),\n conversationId: z.string().uuid(),\n});\n\nexport const archiveListQuery = z.object({\n user_id: z.string().optional(),\n start: z.string().optional(),\n end: z.string().optional(),\n page: z.string().regex(/^\\d+$/).optional(),\n page_size: z.string().regex(/^\\d+$/).optional(),\n});\n\nexport const archiveMessageObservabilityParams = archiveConversationParams.extend({\n messageId: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type ArchiveHubIdParam = z.infer<typeof archiveHubIdParam>;\nexport type ArchiveConversationParams = z.infer<typeof archiveConversationParams>;\nexport type ArchiveListQuery = z.infer<typeof archiveListQuery>;\nexport type ArchiveMessageObservabilityParams = z.infer<typeof archiveMessageObservabilityParams>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface ArchivedConversationItem {\n conversation_id: string;\n user_id: string;\n hub_type: string;\n subject: string;\n conversation_status: string;\n kanban_status: string | null;\n created_at: string;\n ended_at: string | null;\n archived_at: string | null;\n message_count: number;\n}\n\n/** GET /:hubId/conversations */\nexport interface ArchiveListResponse {\n conversations: ArchivedConversationItem[];\n total: number;\n page: number;\n page_size: number;\n}\n\n/**\n * GET /:hubId/conversations/:conversationId\n *\n * The detail payload is an opaque JSON blob written by the archive job.\n * We type it as `Record<string, unknown>` since the shape is not\n * constrained at the API contract level.\n */\nexport type ArchiveDetailResponse = Record<string, unknown>;\n","import { z } from 'zod';\nimport { SAFE_USER_ID_REGEX } from '../constants';\nimport type { FlagSource } from './chat';\n\n// ---------------------------------------------------------------------------\n// Common param\n// ---------------------------------------------------------------------------\n\nexport const conversationIdParam = z.object({\n id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Claim\n// ---------------------------------------------------------------------------\n\nexport const claimBody = z.object({\n hub_id: z.string().uuid(),\n new_team_id: z.string().uuid(),\n new_status: z.string().default('team'),\n new_hub_team_user_id: z.string().optional(),\n new_responder_type: z.string().default('team'),\n previous_status: z.string().optional(),\n previous_responder_type: z.string().optional(),\n previous_agent_id: z.string().uuid().optional(),\n previous_team_id: z.string().uuid().optional(),\n previous_hub_team_user_id: z.string().optional(),\n channel_id: z.string().uuid().optional(),\n hub_type: z.enum(['chat', 'task']).default('chat'),\n // SAFE_USER_ID_REGEX bounds alphabet+length (1–64 of [A-Za-z0-9_-]) so\n // SQL/path/scope-key injection vectors can't reach downstream consumers.\n // Matches `deleteUserConversationsBody.user_id` below.\n user_id: z.string().regex(SAFE_USER_ID_REGEX).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Release\n// ---------------------------------------------------------------------------\n\nexport const releaseBody = z.object({\n hub_id: z.string().uuid(),\n new_status: z.string().optional(),\n new_hub_team_user_id: z.string().optional(),\n new_team_id: z.string().uuid().optional(),\n new_responder_type: z.string().optional(),\n previous_status: z.string().optional(),\n previous_responder_type: z.string().optional(),\n previous_agent_id: z.string().uuid().optional(),\n previous_team_id: z.string().uuid().optional(),\n previous_hub_team_user_id: z.string().optional(),\n channel_id: z.string().uuid().optional(),\n hub_type: z.enum(['chat', 'task']).default('chat'),\n user_id: z.string().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Transfer\n// ---------------------------------------------------------------------------\n\nexport const transferBody = z.object({\n hub_id: z.string().uuid(),\n new_status: z.string().optional(),\n new_responder_type: z.string().optional(),\n new_agent_id: z.string().uuid().optional(),\n new_team_id: z.string().uuid().optional(),\n new_hub_team_user_id: z.string().optional(),\n previous_status: z.string().optional(),\n previous_responder_type: z.string().optional(),\n previous_agent_id: z.string().uuid().optional(),\n previous_team_id: z.string().uuid().optional(),\n previous_hub_team_user_id: z.string().optional(),\n channel_id: z.string().uuid().optional(),\n hub_type: z.enum(['chat', 'task']).default('chat'),\n user_id: z.string().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Close\n// ---------------------------------------------------------------------------\n\nexport const closeBody = z.object({\n hub_id: z.string().uuid(),\n previous_status: z.string().optional(),\n previous_responder_type: z.string().optional(),\n previous_agent_id: z.string().uuid().optional(),\n previous_team_id: z.string().uuid().optional(),\n previous_hub_team_user_id: z.string().optional(),\n channel_id: z.string().uuid().optional(),\n hub_type: z.enum(['chat', 'task']).default('chat'),\n user_id: z.string().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Kanban Update\n// ---------------------------------------------------------------------------\n\n/**\n * Wire payload for `kanbanUpdateBody.additional_context` and the equivalent\n * MCP `update_kanban_status` tool input. Server-side validates the payload\n * shape against the target kanban status's `additional_context_schema`\n * (a JSON Schema). Bounded to 16 KB JSON-serialized — mirrors the same cap\n * on the schema field itself in `setup/kanban.ts`.\n *\n * Single source of truth for the `additional_context` shape: consumed by\n * `kanbanUpdateBody` below (the REST `PATCH /:id/kanban` contract). Exported\n * so any client constructing the same payload validates against one schema.\n */\nexport const additionalContextPayloadSchema = z\n .record(z.unknown())\n .refine((r) => JSON.stringify(r).length <= 16384, {\n message: 'additional_context payload must be at most 16384 bytes when JSON-serialized',\n });\n\nexport const kanbanUpdateBody = z.object({\n hub_id: z.string().uuid(),\n // 50-char slug cap + headroom; bounds the \"unknown kanban status\" 400 echo.\n new_kanban_status: z.string().max(64),\n previous_kanban_status: z.string().max(64).optional(),\n channel_id: z.string().uuid().optional(),\n hub_type: z.enum(['chat', 'task']).default('chat'),\n user_id: z.string().optional(),\n scheduled_event_date: z.string().optional(),\n additional_context: additionalContextPayloadSchema.optional(),\n event_description: z.string().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Observability\n// ---------------------------------------------------------------------------\n\nexport const observabilityParams = z.object({\n conversationId: z.string().uuid(),\n messageId: z.string().uuid(),\n});\n\n// List variant — same conversationId shape as `observabilityParams`, derived\n// via `.pick` so the field stays in lockstep with the single-message route.\nexport const observabilityListParams = observabilityParams.pick({ conversationId: true });\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type ConversationIdParam = z.infer<typeof conversationIdParam>;\nexport type ClaimBody = z.infer<typeof claimBody>;\nexport type ReleaseBody = z.infer<typeof releaseBody>;\nexport type TransferBody = z.infer<typeof transferBody>;\nexport type CloseBody = z.infer<typeof closeBody>;\nexport type KanbanUpdateBody = z.infer<typeof kanbanUpdateBody>;\nexport type ObservabilityParams = z.infer<typeof observabilityParams>;\nexport type ObservabilityListParams = z.infer<typeof observabilityListParams>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\n/** Result of a conversation operation (claim, release, transfer, close) */\nexport interface ConversationOperationResponse {\n success: true;\n operation_id: string;\n operation_type: 'claim' | 'release' | 'transfer' | 'close';\n conversation_id: string;\n}\n\n/** Result of a kanban status update operation */\nexport interface KanbanUpdateResponse {\n success: true;\n operation_id: string;\n operation_type: 'update_kanban_status';\n conversation_id: string;\n kanban_status_updated_at?: string;\n /** Set when the new kanban_status is terminal and the conversation auto-closed. */\n closed?: boolean;\n}\n\n/** Result of a conversation reopen operation */\nexport interface ReopenConversationResponse {\n data: Record<string, unknown>;\n}\n\n/** Observability data for a message */\nexport interface ObservabilityResponse {\n data: import('../observability/types').LLMObservabilityRecord;\n}\n\n/**\n * List of per-message observability summaries for a conversation.\n * Carries metadata.json contents only (timestamp, latency, agent, tool counts)\n * — drill into a specific message for full provider/model/tokens/messages.\n */\nexport interface ObservabilityListResponse {\n data: {\n hub_id: string;\n conversation_id: string;\n entries: import('../observability/types').WayAIMetadataRecord[];\n truncated: boolean;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Delete User Conversations\n//\n// Hub-admin only. `mode='current'` wipes a single conversation; `mode='all'`\n// wipes every conversation for the target user on this hub. Deletion is\n// hub-scoped — same `user_id` on a sibling hub is untouched. Permanent.\n// ---------------------------------------------------------------------------\n\nexport const deleteUserConversationsBody = z.discriminatedUnion('mode', [\n z.object({\n hub_id: z.string().uuid(),\n user_id: z.string().regex(SAFE_USER_ID_REGEX),\n mode: z.literal('all'),\n }),\n z.object({\n hub_id: z.string().uuid(),\n user_id: z.string().regex(SAFE_USER_ID_REGEX),\n mode: z.literal('current'),\n conversation_id: z.string().uuid(),\n }),\n]);\nexport type DeleteUserConversationsBody = z.infer<typeof deleteUserConversationsBody>;\n\nexport interface DeleteUserConversationsResponse {\n success: true;\n deleted_count: number;\n}\n\n// ---------------------------------------------------------------------------\n// Send Message (preview hub testing)\n// ---------------------------------------------------------------------------\n\nexport const sendMessageBody = z.object({\n hub_id: z.string().uuid(),\n message: z.string().min(1).max(50000),\n /** For chat hubs: optional — automatically continues the user's active conversation (or creates one).\n * For task hubs: required to continue an existing conversation. Omit to start a new task conversation. */\n conversation_id: z.string().uuid().optional(),\n});\nexport type SendMessageBody = z.infer<typeof sendMessageBody>;\n\nexport interface SendMessageResponse {\n conversation_id: string;\n hub_type: 'chat' | 'task';\n user_message_id: string;\n agent_reply: {\n message_id: string;\n message_text: string;\n } | null;\n status: 'replied' | 'skipped' | 'error' | 'empty_response';\n status_reason?: string;\n}\n\n// ---------------------------------------------------------------------------\n// List Conversations (admin)\n// ---------------------------------------------------------------------------\n\nexport const listConversationsQuery = z.object({\n hub_id: z.string().uuid(),\n status: z.enum(['agent', 'team', 'ended']).optional(),\n limit: z.coerce.number().int().min(1).max(100).default(20),\n offset: z.coerce.number().int().min(0).default(0),\n});\nexport type ListConversationsQuery = z.infer<typeof listConversationsQuery>;\n\nexport interface GetConversationsResponse {\n conversations: Array<{\n conversation_id: string;\n conversation_status: string;\n current_responder_type: string | null;\n kanban_status: string | null;\n created_at: string;\n updated_at: string | null;\n user_name: string | null;\n user_email: string | null;\n is_flagged: boolean;\n flag_source: FlagSource;\n }>;\n total: number;\n}\n\n// ---------------------------------------------------------------------------\n// Get Conversation Detail (with messages)\n// ---------------------------------------------------------------------------\n\nexport const getConversationDetailParams = z.object({\n id: z.string().uuid(),\n});\nexport type GetConversationDetailParams = z.infer<typeof getConversationDetailParams>;\n\nexport const getConversationDetailQuery = z.object({\n hub_id: z.string().uuid(),\n limit: z.coerce.number().int().min(1).max(200).default(50),\n offset: z.coerce.number().int().min(0).default(0),\n});\nexport type GetConversationDetailQuery = z.infer<typeof getConversationDetailQuery>;\n\nexport interface GetConversationDetailResponse {\n conversation: {\n conversation_id: string;\n conversation_status: string;\n current_responder_type: string | null;\n access_status: string;\n kanban_status: string | null;\n created_at: string;\n updated_at: string | null;\n user_name: string | null;\n user_email: string | null;\n is_flagged: boolean;\n flag_source: FlagSource;\n };\n messages: Array<{\n message_id: string;\n message_text: string | null;\n sender_type: string;\n receiver_type: string | null;\n created_at: string;\n message_type?: string;\n channel_type?: string | null;\n keep_in_history?: boolean;\n agent_id?: string | null;\n sender_id?: string | null;\n receiver_id?: string | null;\n sender_description?: string;\n receiver_description?: string;\n metadata?: Record<string, unknown> | null;\n message_status?: string | null;\n }>;\n total_messages: number;\n}\n\n// ---------------------------------------------------------------------------\n// WhatsApp template picker (closed-window team re-engagement)\n//\n// When a WhatsApp conversation is past Meta's 24h messaging window, a free-form\n// team reply is blocked. An approved WhatsApp template is the only compliant\n// re-engagement path. These contracts back the picker: list the conversation's\n// approved templates, then send one with body variables filled in.\n// ---------------------------------------------------------------------------\n\nexport const listWhatsAppTemplatesQuery = z.object({\n hub_id: z.string().uuid(),\n});\nexport type ListWhatsAppTemplatesQuery = z.infer<typeof listWhatsAppTemplatesQuery>;\n\nexport const sendWhatsAppTemplateBody = z.object({\n hub_id: z.string().uuid(),\n /** HubDO outbound_template.template_id. */\n template_id: z.string().min(1).max(128),\n /** The conversation's end user (customer). Bounded like `claimBody.user_id`. */\n user_receiver_id: z.string().regex(SAFE_USER_ID_REGEX),\n /** Body-variable values: positional array or key→value record. Bounded so an\n * authenticated caller can't post an oversized payload to the transcript. */\n variables: z\n .union([\n z.array(z.string().max(2048)).max(50),\n z\n .record(z.string().max(128), z.string().max(2048))\n .refine((r) => Object.keys(r).length <= 50, 'too many variables'),\n ])\n .optional(),\n});\nexport type SendWhatsAppTemplateBody = z.infer<typeof sendWhatsAppTemplateBody>;\n\n/** One approved WhatsApp template, shaped for the picker UI. */\nexport interface WhatsAppTemplatePickerItem {\n template_id: string;\n display_name: string;\n category: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION';\n language: string;\n /** BODY component text, with `{{N}}` / `{{name}}` placeholders intact. */\n body_text: string;\n parameter_format: 'POSITIONAL' | 'NAMED';\n /** Distinct variable keys in render order — drives the fill-in form. */\n variables: string[];\n}\n\nexport interface ListWhatsAppTemplatesResponse {\n data: WhatsAppTemplatePickerItem[];\n}\n\n/**\n * Send result on success. Failures return a non-2xx with the standard error\n * envelope (`{ error, message }`) whose `error` carries a stable code the\n * picker maps to a message — e.g. `template_not_approved`, `conversation_ended`,\n * `missing_variables`, `meta_rejected:<n>`.\n */\nexport interface SendWhatsAppTemplateResponse {\n data: { message_id: string; channel_message_sid: string | null; rendered_text: string };\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Params\n// ---------------------------------------------------------------------------\n\nexport const billingOrgIdParam = z.object({\n organizationId: z.string().uuid(),\n});\n\nexport const subscriptionItemParams = z.object({\n organizationId: z.string().uuid(),\n itemId: z.string(),\n});\n\n// ---------------------------------------------------------------------------\n// Bodies\n// ---------------------------------------------------------------------------\n\nexport const spendCapBody = z.object({\n enabled: z.boolean(),\n});\n\nexport const growthPacksBody = z.object({\n quantity: z.number().int().min(1).max(100).default(1),\n});\n\nexport const portalSessionBody = z.object({\n return_url: z.string().url().optional(),\n});\n\nexport const checkoutSessionBody = z.object({\n tier: z.enum(['solo', 'team']),\n});\n\nexport const updateBillingCurrencyBody = z.object({\n currency: z.enum(['USD', 'BRL']),\n});\n\n// ---------------------------------------------------------------------------\n// Queries\n// ---------------------------------------------------------------------------\n\nexport const invoicesQuery = z.object({\n limit: z.string().regex(/^\\d+$/).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type BillingOrgIdParam = z.infer<typeof billingOrgIdParam>;\nexport type SubscriptionItemParams = z.infer<typeof subscriptionItemParams>;\nexport type SpendCapBody = z.infer<typeof spendCapBody>;\nexport type GrowthPacksBody = z.infer<typeof growthPacksBody>;\nexport type PortalSessionBody = z.infer<typeof portalSessionBody>;\nexport type CheckoutSessionBody = z.infer<typeof checkoutSessionBody>;\nexport type UpdateBillingCurrencyBody = z.infer<typeof updateBillingCurrencyBody>;\nexport type InvoicesQuery = z.infer<typeof invoicesQuery>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface BillingOrganizationItem {\n organization_id: string;\n organization_name: string;\n billing_currency: string;\n created_at: string;\n organization_admin_user: {\n is_owner: boolean;\n enabled: boolean;\n }[];\n}\n\nexport interface BillingOrganizationsResponse {\n success: true;\n data: BillingOrganizationItem[];\n}\n\nexport interface BillingRecord {\n organization_id: string;\n stripe_customer_id: string | null;\n stripe_subscription_id: string | null;\n plan_type: 'free' | 'paid';\n plan_key: 'free' | 'solo' | 'team';\n plan_kind: 'free' | 'base' | 'addon';\n billing_cycle: 'monthly' | 'annual';\n display_name?: string;\n period_start: string | null;\n period_end: string | null;\n spend_cap_enabled: boolean;\n billing_status: 'active' | 'past_due' | 'cancelled';\n created_at: string;\n updated_at: string;\n}\n\nexport interface BillingMetric {\n billing_metric_id: string;\n organization_id: string;\n metric_type: 'messages' | 'users' | 'storage' | 'api_calls';\n monthly_included: number;\n consumed_subscription: number;\n alert_80_sent: boolean;\n alert_95_sent: boolean;\n alert_100_sent: boolean;\n last_consumed_at: string | null;\n last_reset_at: string | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface BillingMetricsHistory {\n history_id: string;\n organization_id: string;\n period_start: string;\n period_end: string;\n metric_type: 'messages' | 'users' | 'storage' | 'api_calls';\n monthly_included: number;\n consumed_subscription: number;\n created_at: string;\n}\n\nexport interface BillingData {\n billing: BillingRecord;\n metrics: BillingMetric[] | null;\n history: BillingMetricsHistory[] | null;\n is_owner: boolean;\n billing_currency: string;\n}\n\nexport interface GetBillingDataResponse {\n success: true;\n data: BillingData;\n}\n\nexport interface UpdateSpendCapResponse {\n success: true;\n data: { spend_cap_enabled: boolean };\n}\n\nexport interface AddGrowthPackResponse {\n success: true;\n data: {\n subscription_item_id: string;\n quantity: number;\n messages_added: number;\n seats_added: number;\n };\n}\n\nexport interface UpdateBillingCurrencyResponse {\n success: true;\n data: { currency: 'USD' | 'BRL' };\n}\n\nexport interface RemoveSubscriptionItemResponse {\n success: true;\n data: { removed: string };\n}\n\nexport interface PortalSessionResponse {\n success: true;\n data: { url: string };\n}\n\nexport interface Invoice {\n id: string;\n amount: number;\n currency: string;\n status: 'draft' | 'open' | 'paid' | 'uncollectible' | 'void' | null;\n created: number;\n period_start: number;\n period_end: number;\n invoice_pdf: string | null | undefined;\n hosted_invoice_url: string | null | undefined;\n}\n\nexport interface GetInvoicesResponse {\n success: true;\n data: Invoice[];\n}\n\nexport interface CheckoutSessionResponse {\n success: true;\n data: { url: string | null; mode: 'portal' | 'checkout'; session_id?: string };\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Download\n// ---------------------------------------------------------------------------\n\nexport const downloadBody = z.object({\n type: z.enum(['workspace', 'agent_instructions']),\n agent_id: z.string().uuid().optional(),\n organization_name: z.string().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Upload\n// ---------------------------------------------------------------------------\n\nexport const uploadQuery = z.object({\n type: z.enum(['agent_instructions']),\n agent_id: z.string().uuid(),\n hub_id: z.string().uuid(),\n});\n\n// ---------------------------------------------------------------------------\n// Sign URL\n// ---------------------------------------------------------------------------\n\nexport const signUrlBody = z.object({\n bucket: z.string(),\n filePath: z.string(),\n expiresIn: z.number().int().positive().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type DownloadBody = z.infer<typeof downloadBody>;\nexport type UploadQuery = z.infer<typeof uploadQuery>;\nexport type SignUrlBody = z.infer<typeof signUrlBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\n/** Shared base for all download responses */\ninterface DownloadResponseBase {\n success: true;\n download_url: string;\n expires_in: number;\n}\n\n/** POST /download (type=workspace) */\nexport interface DownloadWorkspaceResponse extends DownloadResponseBase {\n summary: {\n organization?: string;\n organizations?: number;\n hubs: number;\n files: number;\n };\n}\n\n/** POST /download (type=agent_instructions) */\nexport interface DownloadAgentInstructionsResponse extends DownloadResponseBase {\n summary: { files: number };\n}\n\n/** Union of all download responses */\nexport type DownloadResponse =\n | DownloadWorkspaceResponse\n | DownloadAgentInstructionsResponse;\n\n/** POST /upload */\nexport interface UploadResponse {\n success: true;\n file_id: string;\n file_path: string;\n}\n\n/** POST /sign */\nexport interface SignUrlResponse {\n signedUrl: string;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Completions\n// ---------------------------------------------------------------------------\n\nexport const completionsBody = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n model: z.string(),\n prompt: z.string(),\n system_prompt: z.string().optional(),\n temperature: z.number().min(0).max(2).default(1),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type CompletionsBody = z.infer<typeof completionsBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\n/** POST / */\nexport interface CompletionsResponse {\n content: string;\n error?: string;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Outbound Schema\n// ---------------------------------------------------------------------------\n\nexport const outboundSchemaQuery = z.object({\n type: z.enum(['whatsapp', 'email', 'app', 'all']).default('all'),\n});\n\n// ---------------------------------------------------------------------------\n// Template Params & Queries\n// ---------------------------------------------------------------------------\n\nexport const templateIdParam = z.object({\n id: z.string().uuid(),\n});\n\nexport const listTemplatesQuery = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n});\n\nexport const deleteTemplateQuery = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n});\n\nexport const templateStatusQuery = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n});\n\nexport const createTemplateBody = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n}).passthrough();\n\nexport const updateTemplateBody = z.object({}).passthrough();\n\nexport const submitTemplateBody = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n}).passthrough();\n\nexport const testTemplateBody = z.object({\n hub_id: z.string().uuid(),\n connection_id: z.string().uuid(),\n}).passthrough();\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type OutboundSchemaQuery = z.infer<typeof outboundSchemaQuery>;\nexport type TemplateIdParam = z.infer<typeof templateIdParam>;\nexport type ListTemplatesQuery = z.infer<typeof listTemplatesQuery>;\nexport type DeleteTemplateQuery = z.infer<typeof deleteTemplateQuery>;\nexport type TemplateStatusQuery = z.infer<typeof templateStatusQuery>;\nexport type CreateTemplateBody = z.infer<typeof createTemplateBody>;\nexport type UpdateTemplateBody = z.infer<typeof updateTemplateBody>;\nexport type SubmitTemplateBody = z.infer<typeof submitTemplateBody>;\nexport type TestTemplateBody = z.infer<typeof testTemplateBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\n/** Connection entry in the outbound schema */\nexport interface OutboundSchemaConnection {\n connection_id: string;\n connector_name: string;\n connection_display_name?: string;\n connector_type: string;\n service_name: string;\n hub_id: string;\n enabled: boolean;\n}\n\n/** Template operation result — returned by all template endpoints */\nexport interface TemplateOperationResult {\n [key: string]: unknown;\n}\n\n/** POST /templates — create template (when a template_id is returned) */\nexport interface CreateTemplateResponse {\n template_id: string;\n}\n\n/** GET /schema */\nexport interface GetOutboundSchemaResponse {\n data: {\n flat: {\n organizations: Array<{\n organization_id: string;\n organization_name: string;\n }>;\n hubsByOrg: Record<string, Array<{\n hub_id: string;\n hub_name: string;\n }>>;\n connectionsByHub: Record<string, OutboundSchemaConnection[]>;\n };\n lastUpdated: string;\n };\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Params & Queries\n// ---------------------------------------------------------------------------\n\nexport const contactIdParam = z.object({\n id: z.string().uuid(),\n});\n\nexport const listContactsQuery = z.object({\n hub_id: z.string().uuid(),\n search: z.string().optional(),\n tags: z.string().optional(), // comma-separated\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(100).default(25),\n});\n\nexport const createContactBody = z.object({\n hub_id: z.string().uuid(),\n contact_name: z.string().min(1),\n phone: z.string().optional(),\n email: z.string().email().optional(),\n instagram_sid: z.string().optional(),\n hub_user_id: z.string().uuid().optional(),\n tags: z.array(z.string()).default([]),\n metadata: z.record(z.unknown()).default({}),\n enabled: z.boolean().default(true),\n}).refine(\n (data) => data.phone || data.email || data.instagram_sid,\n { message: 'At least one channel (phone, email, or instagram_sid) is required' }\n);\n\nexport const updateContactBody = z.object({\n contact_name: z.string().min(1).optional(),\n phone: z.string().nullable().optional(),\n email: z.string().email().nullable().optional(),\n instagram_sid: z.string().nullable().optional(),\n hub_user_id: z.string().uuid().nullable().optional(),\n tags: z.array(z.string()).optional(),\n metadata: z.record(z.unknown()).optional(),\n enabled: z.boolean().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type ContactIdParam = z.infer<typeof contactIdParam>;\nexport type ListContactsQuery = z.infer<typeof listContactsQuery>;\nexport type CreateContactBody = z.infer<typeof createContactBody>;\nexport type UpdateContactBody = z.infer<typeof updateContactBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface OutboundContact {\n contact_id: string;\n hub_id: string;\n hub_user_id: string | null;\n contact_name: string;\n phone: string | null;\n email: string | null;\n instagram_sid: string | null;\n tags: string[];\n metadata: Record<string, unknown>;\n enabled: boolean;\n created_at: string;\n updated_at: string;\n}\n\nexport interface ListContactsResponse {\n contacts: OutboundContact[];\n total: number;\n page: number;\n per_page: number;\n}\n\nexport interface CreateContactResponse {\n contact_id: string;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Params & Queries\n// ---------------------------------------------------------------------------\n\nexport const listIdParam = z.object({\n id: z.string().uuid(),\n});\n\nexport const listListsQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\nexport const listListContactsQuery = z.object({\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(100).default(25),\n});\n\nexport const createListBody = z.object({\n hub_id: z.string().uuid(),\n list_name: z.string().min(1),\n description: z.string().nullable().optional(),\n});\n\nexport const updateListBody = z.object({\n list_name: z.string().min(1).optional(),\n description: z.string().nullable().optional(),\n});\n\nexport const addListContactsBody = z.object({\n contact_ids: z.array(z.string().uuid()).min(1),\n});\n\nexport const removeListContactsBody = z.object({\n contact_ids: z.array(z.string().uuid()).min(1),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type ListIdParam = z.infer<typeof listIdParam>;\nexport type ListListsQuery = z.infer<typeof listListsQuery>;\nexport type ListListContactsQuery = z.infer<typeof listListContactsQuery>;\nexport type CreateListBody = z.infer<typeof createListBody>;\nexport type UpdateListBody = z.infer<typeof updateListBody>;\nexport type AddListContactsBody = z.infer<typeof addListContactsBody>;\nexport type RemoveListContactsBody = z.infer<typeof removeListContactsBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface OutboundList {\n list_id: string;\n hub_id: string;\n list_name: string;\n description: string | null;\n contact_count: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface ListListsResponse {\n lists: OutboundList[];\n}\n\nexport interface CreateListResponse {\n list_id: string;\n}\n\nexport interface ListContactEntry {\n list_contact_id: string;\n contact_id: string;\n contact_name: string;\n phone: string | null;\n email: string | null;\n instagram_sid: string | null;\n enabled: boolean;\n added_at: string;\n}\n\nexport interface ListListContactsResponse {\n contacts: ListContactEntry[];\n total: number;\n page: number;\n per_page: number;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Params & Queries\n// ---------------------------------------------------------------------------\n\nexport const scheduleIdParam = z.object({\n id: z.string().uuid(),\n});\n\nexport const listSchedulesQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\nexport const listExecutionsQuery = z.object({\n page: z.coerce.number().int().min(1).default(1),\n per_page: z.coerce.number().int().min(1).max(50).default(10),\n});\n\nexport const createScheduleBody = z.object({\n hub_id: z.string().uuid(),\n schedule_name: z.string().min(1),\n description: z.string().nullable().optional(),\n cron_expression: z.string().min(1),\n timezone: z.string().default('UTC'),\n list_id: z.string().uuid(),\n channel_type: z.enum(['whatsapp', 'instagram', 'email', 'app']),\n connection_id: z.string().uuid().nullable().optional(),\n execution_mode: z.enum(['direct_message', 'agent_trigger']).default('direct_message'),\n template_whatsapp_id: z.string().uuid().nullable().optional(),\n initial_message: z.string().nullable().optional(),\n agent_id: z.string().uuid().nullable().optional(),\n trigger_message: z.string().nullable().optional(),\n});\n\nexport const updateScheduleBody = z.object({\n schedule_name: z.string().min(1).optional(),\n description: z.string().nullable().optional(),\n cron_expression: z.string().min(1).optional(),\n timezone: z.string().optional(),\n list_id: z.string().uuid().optional(),\n channel_type: z.enum(['whatsapp', 'instagram', 'email', 'app']).optional(),\n connection_id: z.string().uuid().nullable().optional(),\n execution_mode: z.enum(['direct_message', 'agent_trigger']).optional(),\n template_whatsapp_id: z.string().uuid().nullable().optional(),\n initial_message: z.string().nullable().optional(),\n agent_id: z.string().uuid().nullable().optional(),\n trigger_message: z.string().nullable().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type ScheduleIdParam = z.infer<typeof scheduleIdParam>;\nexport type ListSchedulesQuery = z.infer<typeof listSchedulesQuery>;\nexport type ListExecutionsQuery = z.infer<typeof listExecutionsQuery>;\nexport type CreateScheduleBody = z.infer<typeof createScheduleBody>;\nexport type UpdateScheduleBody = z.infer<typeof updateScheduleBody>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface OutboundSchedule {\n schedule_id: string;\n hub_id: string;\n schedule_name: string;\n description: string | null;\n enabled: boolean;\n cron_expression: string;\n timezone: string;\n list_id: string;\n channel_type: string;\n connection_id: string | null;\n execution_mode: string;\n template_whatsapp_id: string | null;\n initial_message: string | null;\n agent_id: string | null;\n trigger_message: string | null;\n last_run_at: string | null;\n next_run_at: string | null;\n total_runs: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface ListSchedulesResponse {\n schedules: OutboundSchedule[];\n}\n\nexport interface CreateScheduleResponse {\n schedule_id: string;\n}\n\nexport interface ScheduleExecution {\n execution_id: string;\n schedule_id: string;\n started_at: string;\n completed_at: string | null;\n status: string;\n total_contacts: number;\n succeeded: number;\n failed: number;\n skipped: number;\n}\n\nexport interface ListExecutionsResponse {\n executions: ScheduleExecution[];\n total: number;\n page: number;\n per_page: number;\n}\n","/**\n * Shared CI/GitOps types — contract between backend and CLI.\n *\n * Source of truth: workers/backend/src/routes/api/ci/types.ts\n * The backend may have extra optional fields (e.g. connection_id, target_id)\n * that the CLI ignores — this file carries the full (superset) definitions.\n */\n\nimport { z } from 'zod';\nimport {\n validateToolInputSchema,\n containsKanbanPlaceholders,\n extractToolParameters,\n} from '../tool-schema-validator';\nimport { kanbanStatusesArraySchema } from './setup/kanban';\n\n// =============================================\n// Kanban status types\n// Field names match the existing JSONB schema in the database and frontend\n// (KanbanStatusCard.tsx, FollowupCard.tsx). The mixed casing (camelCase booleans,\n// snake_case strings) is inherited from the original frontend implementation.\n// =============================================\n\nexport interface HubAsCodeKanbanFollowup {\n id?: string;\n order: number;\n type: 'inactivity' | 'before_event';\n threshold: number;\n timeUnit: 'seconds' | 'minutes' | 'hours' | 'days';\n instructions: string;\n excludedWeekDays?: number[];\n excludeHolidays?: boolean;\n excludedTimeStart?: string;\n excludedTimeEnd?: string;\n /** 'agent_generated' (default) feeds `instructions` to the LLM; 'direct' sends `direct_text` verbatim. */\n delivery_mode?: 'agent_generated' | 'direct';\n /** Verbatim user-facing text. Required when `delivery_mode='direct'`. */\n direct_text?: string;\n /** Approved Meta WhatsApp template id; consulted only outside the WA 24h window. */\n template_whatsapp_id?: string | null;\n /** Default `'route_to_team'` when omitted. Only consulted on `direct` mode + windowed channels outside the window. */\n outside_window_policy?: 'route_to_team' | 'skip';\n /** Default true — followup turn includes tool schemas. Set to false to strip them and save tokens. No effect on `direct` mode. */\n include_tools?: boolean;\n}\n\nexport interface HubAsCodeKanbanStatus {\n /** Stable identifier — set once at create, never edited. Lowercase slug, used in\n * `conversation.kanban_status`, ClickHouse `data.meta.kanban_status`, tool params,\n * and `allowed_next_statuses` references. */\n slug: string;\n /** Display label — shown in UI and tool descriptions. Freely editable. */\n name: string;\n order?: number;\n color?: string;\n isInitialStatus?: boolean;\n triggersAgentResponse?: boolean;\n allowsAgentUpdate?: boolean;\n isTerminalStatus?: boolean;\n isSchedulingStatus?: boolean;\n eventName?: string;\n /** Template prose injected into the agent turn on transition. Supports\n * `{{path.to.field}}` placeholders (dotted, whitespace-tolerant) and the\n * reserved `{{additional_data}}` placeholder which expands to the full\n * payload as 2-space-indented JSON. */\n additional_instructions?: string;\n /** JSON Schema (Draft 2020-12) defining the form fields collected at\n * transition time. The collected payload is interpolated into\n * `additional_instructions` and emitted to the agent as a\n * `<system_additional_instructions>` block. Top-level property name\n * `additional_data` is reserved (collides with the dump placeholder).\n * Capped at 16 KB when JSON-serialized. */\n additional_context_schema?: Record<string, unknown>;\n followups?: HubAsCodeKanbanFollowup[];\n /** Slugs this status can transition to. `undefined` = unrestricted (any next).\n * Empty array is rejected by the validator — use `isTerminalStatus: true` for\n * no outbound transitions. */\n allowed_next_statuses?: string[];\n}\n\n// =============================================\n// HubAsCode payload — JSON representation of hub.yaml + agents/*.yaml\n// =============================================\n\nexport interface HubAsCodePayload {\n version: number;\n hub_id: string;\n hub_environment: string;\n preview_label?: string | null;\n branch_name?: string | null;\n\n hub: {\n name: string;\n description?: string;\n hub_type?: string;\n ai_mode?: string;\n timezone?: string;\n /** Hub language (en|pt|es) — localizes the channel-contact-access pending notice. */\n language?: string;\n /** Gate for who may approve/block channel contacts: 'admin' (default) | 'team'. */\n access_approval_role?: string;\n /** Override text for the one-time \"your access is pending\" notice (else localized default). */\n access_request_message?: string | null;\n non_app_permission?: string;\n mcp_access?: string;\n kanban_statuses?: HubAsCodeKanbanStatus[];\n // flag_conditions relocated to the conversation_evaluator AGENT (see HubAsCodeAgent.flag_conditions).\n // summarization_threshold_tokens relocated to the summarizer AGENT (see HubAsCodeAgent.summarization_threshold_tokens).\n // monitor_config relocated to the monitor AGENT (see HubAsCodeAgent.monitor_config).\n /** Days of inactivity (no user/team messages) before a conversation is force-closed.\n * Range 1..180, default 7. Mandatory across every hub. */\n auto_close_inactive_days?: number;\n /** Org tag slug names (not UUIDs). Resolved against OrgDO `org_tag` on push;\n * unknown names are rejected. Hub tags gate which org credentials this hub\n * can resolve via the symmetric overlap rule (see SKILL connections doc). */\n tags?: string[];\n };\n\n agents?: HubAsCodeAgent[];\n resources?: HubAsCodeResource[];\n states?: HubAsCodeState[];\n teams?: HubAsCodeTeam[];\n evals?: HubAsCodeEval[];\n outbound_contacts?: HubAsCodeOutboundContact[];\n outbound_lists?: HubAsCodeOutboundList[];\n outbound_schedules?: HubAsCodeOutboundSchedule[];\n\n /** Connections serve as reference targets for `connection_id` fields on agents\n * and custom tools. Non-secret configuration fields (base_url, headers, settings,\n * etc.) are round-trippable via pull/push. The bound org credential round-trips\n * by name via `credential`; the raw secret is never exported. */\n connections?: Array<{\n id?: string;\n name: string;\n type: string;\n service?: string;\n /** Pin an org credential by display name (round-trips on pull). */\n credential?: string;\n /** Bearer Token org credential for dual-credential (API Key + access token)\n * connectors. Push-only: not round-tripped on pull (the connection row stores\n * a single credential id, so only the primary `credential` is re-emitted). */\n access_token_credential?: string;\n /** Opt into a deliberately unauthenticated connection for optional-auth connectors\n * (e.g. a no-auth MCP server). Suppresses the \"created without authentication\"\n * push warning. Must not be combined with `credential`. */\n no_auth?: boolean;\n base_url?: string;\n headers?: Record<string, string>;\n settings?: Record<string, unknown>;\n account_sid?: string;\n enabled?: boolean;\n authentication_type?: string;\n }>;\n}\n\nexport interface HubAsCodeAgent {\n id?: string;\n name: string;\n role: string;\n connection: string;\n connection_id?: string;\n instructions?: string;\n additional_context_template?: string;\n enabled?: boolean;\n include_message_timestamps?: boolean;\n settings?: Record<string, unknown>;\n response_format?: {\n type: string;\n schema_name: string;\n schema_json: Record<string, unknown>;\n };\n tools?: {\n native?: Array<string | HubAsCodeNativeTool>;\n delegation?: Array<{\n id?: string;\n type: string;\n tool: string;\n target: string;\n target_id?: string;\n }>;\n custom?: HubAsCodeCustomTool[];\n /**\n * MCP tools discovered from a `Tool - MCP` connection, assigned to this agent.\n * Identity key is `(connection, name)` (an MCP tool name is unique per server).\n *\n * **Omitted vs present (mirrors `evaluation_variables`):** when the `mcp` key\n * is OMITTED, existing MCP tool rows on the agent are left untouched (so tools\n * assigned in the Platform UI survive a push that doesn't manage them). When\n * PRESENT (even as `[]`), the list is AUTHORITATIVE — listed-but-missing tools\n * are created, unlisted MCP tools are removed, matched ones kept. This differs\n * from `native`/`custom` (whose absence deletes them) because MCP tools are\n * dual-origin (UI + GitOps).\n *\n * Push discovers the connection's tools on demand (equivalent to the UI's\n * \"Sync MCP tools\" action), so a single push can create the connection AND\n * assign its tools — the MCP server must be reachable.\n */\n mcp?: HubAsCodeMcpTool[];\n };\n resources?: HubAsCodeAgentResource[];\n /**\n * Evaluation variables (a.k.a. agent parameters) — the structured fields an\n * evaluator agent writes per conversation/message. Round-trippable via\n * pull/push. Identity key is `name` (unique per agent). When the key is\n * OMITTED from YAML, existing variables are left untouched; when PRESENT\n * (even as `[]`), the list is treated as authoritative and replaces the\n * agent's current variables. Primarily used by `conversation_evaluator` /\n * `message_evaluator` agents.\n */\n evaluation_variables?: HubAsCodeEvaluationVariable[];\n /**\n * Conversation-flagging conditions evaluated post-close (OR semantics). A true\n * agent parameter on the `conversation_evaluator` agent (relocated from the hub\n * section). Round-trippable via pull/push. Meaningful only on the\n * `conversation_evaluator` agent; ignored elsewhere.\n */\n flag_conditions?: Array<{ variable: string; operator: '=' | '!='; value: string | number }>;\n /**\n * Token threshold that fires the rolling summarizer (effective tokens =\n * input + cache_read + cache_creation; default 120000). A true agent parameter\n * on the `summarizer` agent (relocated from the hub section). Round-trippable via\n * pull/push. Meaningful only on the `summarizer` agent; ignored elsewhere.\n */\n summarization_threshold_tokens?: number;\n /**\n * Monitor scheduling + flagging config ({delay_seconds, flag_conditions}). A true\n * agent parameter on the `monitor` agent (relocated from the hub section).\n * Round-trippable via pull/push. `delay_seconds` >= 10. Meaningful only on the\n * `monitor` agent; ignored elsewhere.\n */\n monitor_config?: {\n delay_seconds: number;\n flag_conditions?: Array<{ variable: string; operator: '=' | '!='; value: string | number }>;\n } | null;\n}\n\n// Canonical key lists for HubAsCodeAgent and its `tools` block, co-located with\n// the interface so the two are edited together. The CI diff engine derives its\n// unknown-key warnings (gh #2505) from these — without a single source of truth,\n// a hand-maintained copy silently drifts and emits false \"unknown key\" warnings\n// on valid configs once a new field lands. The config validator is `.passthrough()`\n// (no runtime schema to reflect), so parity is enforced at COMPILE time below:\n// - `satisfies readonly (keyof …)[]` rejects typo'd/extra entries\n// - `_Expect<_Exhaustive<…>>` rejects a key present on the interface but missing here\n// Add a field to the interface → tsc fails until it's added to the matching list.\ntype _Expect<T extends true> = T;\ntype _Exhaustive<Keys extends PropertyKey, Listed extends PropertyKey> =\n Exclude<Keys, Listed> extends never ? true : false;\n\nexport const HUB_AS_CODE_AGENT_KEYS = [\n 'id', 'name', 'role', 'connection', 'connection_id', 'instructions',\n 'additional_context_template', 'enabled', 'include_message_timestamps',\n 'settings', 'response_format', 'tools', 'resources', 'evaluation_variables',\n 'flag_conditions', 'summarization_threshold_tokens', 'monitor_config',\n] as const satisfies readonly (keyof HubAsCodeAgent)[];\ntype _AgentKeysExhaustive = _Expect<_Exhaustive<keyof HubAsCodeAgent, (typeof HUB_AS_CODE_AGENT_KEYS)[number]>>;\n\nexport const HUB_AS_CODE_AGENT_TOOL_KEYS = [\n 'native', 'delegation', 'custom', 'mcp',\n] as const satisfies readonly (keyof NonNullable<HubAsCodeAgent['tools']>)[];\ntype _AgentToolKeysExhaustive = _Expect<_Exhaustive<keyof NonNullable<HubAsCodeAgent['tools']>, (typeof HUB_AS_CODE_AGENT_TOOL_KEYS)[number]>>;\n\n/**\n * One evaluation variable on an agent. Maps to a HubDO `agent_parameter` row.\n * Defaults on read (push): `type` → 'string', `required` → true,\n * `is_summary` → false, everything else unset/empty. The emit side (pull)\n * omits any field equal to its default so round-trips stay clean.\n */\nexport interface HubAsCodeEvaluationVariable {\n /** Variable name the agent writes — unique within the agent. Required. */\n name: string;\n /** 'string' (default) | 'number' | 'boolean' | 'integer' | 'enum'. */\n type?: string;\n description?: string;\n /** Human-facing display label (Analytics columns, UI). */\n label?: string;\n /** Allowed values when `type: enum`. Ignored for other types. */\n enum?: string[];\n /** Defaults to true when omitted (mirrors the UI's new-variable default). */\n required?: boolean;\n /**\n * Analytics grouping. Conventional values: quality | satisfaction |\n * compliance | categorization. Free-form to preserve system-internal\n * markers (e.g. `eval` on message-evaluator defaults) across round-trips.\n */\n category?: string | null;\n /**\n * Marks the rolling conversation-summary field. Only honored for\n * `type: string`; coerced to false otherwise.\n */\n is_summary?: boolean;\n}\n\n/**\n * Native tool entry. The string form (e.g. `\"send_text_message\"`) keeps the\n * platform/catalog defaults. The object form lets users override per-instance\n * fields — only `keep_in_history` and `expose_schema_to_llm` are user-managed;\n * other native-tool fields (schema, instructions, operation) come from the\n * catalog and are not round-tripped. Override fields are diff-applied only\n * when explicitly present in YAML — omitted means \"leave as is\".\n */\nexport interface HubAsCodeNativeTool {\n id?: string;\n name: string;\n keep_in_history?: boolean;\n expose_schema_to_llm?: boolean;\n}\n\n/**\n * An MCP tool assigned to an agent (under `tools.mcp`). The tool's schema,\n * description, and config come from the connection's discovered `mcp_tool`\n * catalog — only the reference round-trips through YAML. `connection` (display\n * name) disambiguates which MCP server the tool comes from; `connection_id` and\n * `id` (the tool-row id) are emitted on pull for stable matching.\n */\nexport interface HubAsCodeMcpTool {\n id?: string;\n name: string;\n connection?: string;\n connection_id?: string;\n}\n\nexport interface HubAsCodeCustomTool {\n id?: string;\n name: string;\n description?: string;\n method?: string;\n path?: string;\n body_format?: string;\n connection?: string;\n connection_id?: string;\n headers?: Record<string, unknown>;\n query_params?: Record<string, unknown>;\n body_params?: Record<string, unknown>;\n config?: Record<string, unknown>; // OpenAI function schema (tool_config)\n keep_in_history?: boolean; // default false; controls whether tool call+result remain in LLM history\n instructions?: string;\n composed_tools?: Array<{\n tool_name: string;\n mappings: Record<string, string | { source: string; type?: string; description?: string }>;\n appended_description?: string;\n success_path?: string;\n }> | null;\n enabled?: boolean;\n expose_schema_to_llm?: boolean;\n}\n\nexport interface HubAsCodeState {\n id?: string;\n /**\n * Stable slug — immutable wire identifier. CI diff uses (slug, scope) as the\n * identity key so renaming `name` is detected as an in-place edit rather than\n * a delete + create. Optional on the wire: when omitted the push pipeline\n * derives slugify(name) (the documented hub.yaml shape authors states with\n * only a `name`). Typed `string` because every resolved state carries one.\n */\n slug: string;\n name: string;\n scope: string;\n description?: string;\n enabled?: boolean;\n inject_in_last_message?: boolean;\n json_schema?: Record<string, unknown>;\n initial_value?: Record<string, unknown> | null;\n}\n\nexport interface HubAsCodeTeam {\n id?: string; // hub_team_id (stable, set by pull)\n name: string; // team_name\n access_rule?: 'anytime' | 'anytime_if_delegated_once' | 'only_while_delegated';\n initial_team?: boolean;\n display_only_if_claimed?: boolean; // conversation_display_only_if_claimed\n}\n\nexport interface HubAsCodeResource {\n id?: string;\n name: string;\n type?: string; // 'knowledge' (default) | 'skill'\n description?: string;\n enabled?: boolean;\n user_browsable?: boolean;\n skill_name?: string; // skill-only: slugified unique name (auto-derived from name if omitted)\n files?: HubAsCodeResourceFile[];\n}\n\nexport interface HubAsCodeResourceFile {\n id?: string; // resource_file_id (stable, set by pull)\n path: string; // relative path within resource, e.g. \"images/logo.png\"\n title?: string; // display name (defaults to filename)\n content?: string; // text file content (push: inlined, pull: inlined)\n content_base64?: string; // binary file content (push only)\n download_url?: string; // signed R2 URL (pull only, binary files)\n mime_type?: string;\n file_size?: number;\n hash?: string; // SHA-256\n}\n\nexport interface HubAsCodeAgentResource {\n name: string; // resource display name\n resource_id?: string; // stable ID\n priority?: number;\n enabled?: boolean;\n include_structure_in_prompt?: boolean;\n use_native_integration?: boolean; // skill-only: tool-based (false) vs provider-native (true)\n write_enabled?: boolean; // grants the agent edit access (download_file/upload_file)\n}\n\n// =============================================================================\n// ORG-AS-CODE — organization-scoped resources synced via `wayai org push/pull`\n// (CLI `org/` directory ⇄ `/api/ci/org-resources/*`). Org resources are the\n// org-level analog of hub resources: managed in OrgDO, shadowed into linked\n// hubs. They carry no agent links (hubs link the shadow), but DO carry\n// `environment`/`tags` (which gate hub eligibility) and explicit folders (org\n// folders are a real table with metadata, unlike path-implicit hub folders).\n// =============================================================================\n\nexport interface OrgAsCodeResourceFolder {\n id?: string; // org_resource_folder_id (stable, set by pull)\n path: string; // folder path relative to resource root, e.g. \"docs/guides\"\n description?: string; // folder_description\n}\n\nexport interface OrgAsCodeResource {\n id?: string; // org_resource_id (stable, set by pull)\n name: string;\n type?: string; // 'knowledge' (default) | 'skill'\n description?: string;\n enabled?: boolean;\n user_browsable?: boolean;\n skill_name?: string; // skill-only: slugified unique name (auto-derived from name if omitted)\n environment?: 'all' | 'preview' | 'production'; // which hub environments may link this resource\n tags?: string[]; // org_tag UUIDs gating hub eligibility\n folders?: OrgAsCodeResourceFolder[]; // explicit folders (preserves empty/described folders)\n files?: HubAsCodeResourceFile[]; // identical shape to hub resource files\n}\n\nexport interface OrgResourcesPayload {\n version: 1;\n organization_id?: string;\n resources?: OrgAsCodeResource[];\n}\n\nexport interface HubAsCodeOutboundContact {\n id?: string;\n name: string;\n phone?: string;\n email?: string;\n instagram_sid?: string;\n tags?: string[];\n enabled?: boolean;\n}\n\nexport interface HubAsCodeOutboundList {\n id?: string;\n name: string;\n description?: string;\n contacts?: string[]; // contact names\n}\n\nexport interface HubAsCodeOutboundSchedule {\n id?: string;\n name: string;\n description?: string;\n cron_expression: string;\n timezone?: string;\n list: string; // list name reference\n list_id?: string;\n channel_type: string;\n connection?: string; // connection name reference\n connection_id?: string;\n execution_mode?: string;\n template_whatsapp?: string; // template name reference\n template_whatsapp_id?: string;\n initial_message?: string;\n agent?: string; // agent name reference\n agent_id?: string;\n trigger_message?: string;\n enabled?: boolean;\n}\n\nexport interface HubAsCodeEval {\n id?: string;\n name: string;\n path?: string | null;\n agent: string; // agent display name\n agent_id?: string; // stable agent UUID\n runs?: number; // default 1\n enabled?: boolean; // default true\n history?: Array<{ role: string; content?: string | null; tool_calls?: unknown; tool_call_id?: string }>;\n input: { role: string; content?: string | null; tool_calls?: unknown };\n expected: { role: string; content?: string | null; tool_calls?: unknown };\n evaluator_instructions?: string;\n}\n\n// =============================================\n// Zod request schemas\n// =============================================\n\nconst uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nconst ciUuidSchema = z.string().regex(uuidPattern, 'must be a valid UUID');\n\n/**\n * Walk `agents[].tools.custom[].config.parameters` and add draft-2020-12\n * violations as Zod issues (gh #1542). Placeholder-token cases are skipped\n * — see the matching logic in contracts/setup/tools.ts.\n */\nfunction refineHubAsCodeCustomTools(\n config: unknown,\n ctx: z.RefinementCtx,\n): void {\n const agents = (config as { agents?: unknown }).agents;\n if (!Array.isArray(agents)) return;\n\n for (let a = 0; a < agents.length; a++) {\n const agent = agents[a] as { tools?: { custom?: unknown } } | null | undefined;\n const custom = agent?.tools?.custom;\n if (!Array.isArray(custom)) continue;\n\n for (let c = 0; c < custom.length; c++) {\n const tool = custom[c] as { name?: string; config?: unknown } | null | undefined;\n const raw = tool?.config;\n if (raw == null) continue;\n\n const params = extractToolParameters(raw);\n if (params === undefined) {\n // Either `config` is not an object shape, or there's no `parameters`\n // field. Only the former is an error.\n const looksLikeObject = raw !== null\n && typeof raw === 'object'\n && !Array.isArray(raw)\n || (typeof raw === 'string' && (() => {\n try { const parsed = JSON.parse(raw); return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed); }\n catch { return false; }\n })());\n if (!looksLikeObject) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['agents', a, 'tools', 'custom', c, 'config'],\n message: `custom tool \"${tool?.name ?? '<unnamed>'}\": config must be an object`,\n });\n }\n continue;\n }\n\n if (containsKanbanPlaceholders(params)) continue;\n\n const result = validateToolInputSchema(params);\n if (!result.ok) {\n for (const err of result.errors) {\n const tail = err.path.split('.').filter(Boolean);\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['agents', a, 'tools', 'custom', c, 'config', 'parameters', ...tail],\n message: `custom tool \"${tool?.name ?? '<unnamed>'}\": ${err.message}${err.suggestion ? ` — ${err.suggestion}` : ''}`,\n });\n }\n }\n }\n }\n}\n\n/**\n * Walk `hub.kanban_statuses` and re-path each `kanbanStatusesArraySchema`\n * issue under `['hub', 'kanban_statuses', ...]` so the CLI surfaces field-level\n * errors (e.g. \"config.hub.kanban_statuses[2].triggersAgentResponse: …\").\n *\n * The schema enforces cross-field invariants (mutually-exclusive flags, exactly\n * one initial status, unique names). See contracts/setup/kanban.ts.\n */\nfunction refineHubAsCodeKanbanStatuses(\n config: unknown,\n ctx: z.RefinementCtx,\n): void {\n const hub = (config as { hub?: { kanban_statuses?: unknown } }).hub;\n if (hub == null || !('kanban_statuses' in hub)) return;\n const statuses = hub.kanban_statuses;\n if (!Array.isArray(statuses)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['hub', 'kanban_statuses'],\n message:\n statuses === null\n ? 'kanban_statuses must be an array; use `[]` to clear or omit the key to leave it unchanged'\n : 'kanban_statuses must be an array',\n });\n return;\n }\n\n const result = kanbanStatusesArraySchema.safeParse(statuses);\n if (!result.success) {\n for (const issue of result.error.issues) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['hub', 'kanban_statuses', ...issue.path],\n message: issue.message,\n });\n }\n }\n}\n\n/**\n * Lightweight schema for HubAsCode config — validates structural requirements\n * (version, hub.name) + draft-2020-12 check on every custom tool's config\n * parameters (gh #1542) + kanban_statuses cross-field invariants.\n *\n * Both refines are combined in a single `.superRefine` because Zod's\n * `.superRefine` returns `ZodEffects`, which can't be re-chained without\n * `.pipe()`.\n */\nconst hubAsCodeConfigSchema = z.object({\n version: z.literal(1),\n hub: z.object({\n name: z.string().min(1, 'config.hub.name is required'),\n }).passthrough(),\n}).passthrough().superRefine((config, ctx) => {\n refineHubAsCodeCustomTools(config, ctx);\n refineHubAsCodeKanbanStatuses(config, ctx);\n});\n\n// --- Param schemas ---\n\nexport const ciPullHubIdParam = z.object({\n hub_id: ciUuidSchema,\n});\n\nexport const ciBranchParam = z.object({\n branch: z.string().min(1),\n});\n\n// --- Query schemas ---\n\nexport const ciPullQuery = z.object({\n organization_id: ciUuidSchema.optional(),\n});\n\nexport const ciHubsQuery = z.object({\n organization_id: ciUuidSchema,\n});\n\nexport const ciLookupQuery = z.object({\n path: z.string().min(1, 'path query parameter is required'),\n organization_id: ciUuidSchema.optional(),\n});\n\nexport const ciBranchesQuery = z.object({\n hub_id: ciUuidSchema,\n});\n\n// --- Body schemas ---\n\nexport const ciSyncBody = z.object({\n hub_id: ciUuidSchema,\n branch_name: z.string().min(1, 'branch_name is required'),\n config: hubAsCodeConfigSchema,\n commit_sha: z.string().optional(),\n});\n\nexport const ciPushBody = z.object({\n hub_id: ciUuidSchema,\n config: hubAsCodeConfigSchema,\n organization_id: ciUuidSchema.optional(),\n});\n\nexport const ciDiffBody = z.object({\n hub_id: ciUuidSchema,\n config: hubAsCodeConfigSchema,\n direction: z.enum(['push', 'pull']).default('push'),\n organization_id: ciUuidSchema.optional(),\n});\n\nexport const ciPublishBody = z.object({\n hub_id: ciUuidSchema,\n branch_name: z.string().min(1, 'branch_name is required'),\n});\n\nexport const ciPublishPreviewBody = z.object({\n hub_id: ciUuidSchema,\n});\n\n/**\n * POST /api/ci/sync-mcp — re-discover an MCP connection's tool/resource catalog.\n * `connection` is the display name (as written in `connections[].name`) or the\n * connection UUID; the route resolves either against the hub.\n */\nexport const ciSyncMcpBody = z.object({\n hub_id: ciUuidSchema,\n connection: z.string().min(1, 'connection is required'),\n organization_id: ciUuidSchema.optional(),\n});\n\n// --- Org-as-code (org-resources) schemas ---\n\nexport const ciOrgResourcesParam = z.object({\n org_id: ciUuidSchema,\n});\n\n/**\n * Lightweight passthrough schema for the org-resources payload — mirrors\n * `hubAsCodeConfigSchema`'s approach (validate structural requirements only;\n * the apply path does the authoritative shape work). Requires `version` and,\n * when present, `resources` to be an array.\n */\nconst orgResourcesConfigSchema = z.object({\n version: z.literal(1),\n resources: z.array(z.object({ name: z.string().min(1) }).passthrough()).optional(),\n}).passthrough();\n\nexport const ciOrgResourcesPushBody = z.object({\n organization_id: ciUuidSchema,\n config: orgResourcesConfigSchema,\n});\n\nexport const ciOrgResourcesDiffBody = z.object({\n organization_id: ciUuidSchema,\n config: orgResourcesConfigSchema,\n direction: z.enum(['push', 'pull']).default('push'),\n});\n\n// =============================================================================\n// INFERRED TYPES\n// =============================================================================\n\nexport type CiSyncInput = z.infer<typeof ciSyncBody>;\nexport type CiPushInput = z.infer<typeof ciPushBody>;\nexport type CiDiffInput = z.infer<typeof ciDiffBody>;\nexport type CiPublishInput = z.infer<typeof ciPublishBody>;\nexport type CiPublishPreviewInput = z.infer<typeof ciPublishPreviewBody>;\nexport type CiSyncMcpInput = z.infer<typeof ciSyncMcpBody>;\nexport type CiOrgResourcesPushInput = z.infer<typeof ciOrgResourcesPushBody>;\nexport type CiOrgResourcesDiffInput = z.infer<typeof ciOrgResourcesDiffBody>;\n\n// =============================================\n// Response types\n// =============================================\n\nexport interface CiDiffResponse {\n has_changes: boolean;\n direction: 'push' | 'pull';\n summary: string;\n diff: unknown;\n /**\n * Non-fatal skip reasons surfaced by the diff engine (e.g. native/delegation\n * tools dropped because their connector has no connection on the hub).\n * Populated independently of `has_changes` so the CLI can display them even\n * when every change was silently dropped. Always present (possibly empty),\n * symmetric with `DiffResult.warnings`. See gh #1538.\n */\n warnings: string[];\n}\n\nexport interface CiLookupResponse {\n hub_id: string;\n hub_name: string;\n hub_environment: string;\n preview_label?: string | null;\n branch_name?: string | null;\n}\n\nexport interface CiOrganizationsResponse {\n organizations: Array<{ id: string; name: string }>;\n}\n\nexport interface CiCreateOrganizationResponse {\n organization: {\n id: string;\n name: string;\n /** Resolved DO placement region (auto-detected from the request edge, or the\n * caller's explicit `primary_region`). Surfaced so the CLI can show it. */\n region: string | null;\n /** True when the caller passed an explicit region; false when auto-detected\n * (closest Cloudflare PoP). Lets the CLI phrase \"closest to you\" vs \"as requested\". */\n region_explicit: boolean;\n };\n}\n\nexport interface CiHubListItem {\n hub_id: string;\n hub_name: string;\n hub_environment: string;\n preview_label: string | null;\n branch_name: string | null;\n production_hub_id: string | null;\n}\n\nexport interface CiHubListResponse {\n hubs: CiHubListItem[];\n}\n\nexport interface CiSyncResponse {\n preview_hub_id: string;\n created: boolean;\n changes: {\n hub_updated: boolean;\n connections_created: number;\n connections_updated: number;\n connections_deleted: number;\n agents_created: number;\n agents_updated: number;\n agents_deleted: number;\n tools_created: number;\n tools_updated: number;\n tools_deleted: number;\n states_created: number;\n states_updated: number;\n states_deleted: number;\n teams_created: number;\n teams_updated: number;\n teams_deleted: number;\n resources_created: number;\n resources_updated: number;\n resources_deleted: number;\n resource_files_uploaded: number;\n resource_files_deleted: number;\n resource_links_created: number;\n resource_links_updated: number;\n resource_links_deleted: number;\n evals_created: number;\n evals_updated: number;\n evals_deleted: number;\n outbound_contacts_created: number;\n outbound_contacts_updated: number;\n outbound_contacts_deleted: number;\n outbound_lists_created: number;\n outbound_lists_updated: number;\n outbound_lists_deleted: number;\n outbound_schedules_created: number;\n outbound_schedules_updated: number;\n outbound_schedules_deleted: number;\n };\n errors?: string[];\n /** Non-blocking lint warnings (e.g. unreachable kanban statuses). Same\n * `KanbanLintWarning` shape returned by REST `/hubs` endpoints so the CLI\n * can render structured details (code, slug, message). */\n warnings?: Array<{ code: string; slug: string; name: string; message: string }>;\n}\n\nexport interface CiPublishResponse {\n synced: boolean;\n production_hub_id: string;\n}\n\nexport interface CiSyncMcpResponse {\n success: boolean;\n connection_id: string;\n connection_name: string;\n tools_count?: number;\n resources_count?: number;\n message?: string;\n warnings?: string[];\n}\n\nexport interface CiPublishPreviewResponse {\n synced: boolean;\n production_hub_id?: string;\n}\n\nexport interface CiBranchInfo {\n branch_name: string;\n preview_hub_id: string;\n last_ci_activity_at: string | null;\n ci_commit_sha: string | null;\n}\n\nexport interface CiBranchListResponse {\n branches: CiBranchInfo[];\n}\n\nexport interface CiBranchDeleteResponse {\n deleted: boolean;\n message?: string;\n}\n\n/** Pull returns the org-resources payload directly (CLI writes it to `org/`). */\nexport type CiOrgResourcesPullResponse = OrgResourcesPayload;\n\nexport interface CiOrgResourcesPushResponse {\n changes: {\n resources_created: number;\n resources_updated: number;\n resources_deleted: number;\n resource_files_uploaded: number;\n resource_files_deleted: number;\n resource_folders_created: number;\n resource_folders_deleted: number;\n };\n /** Aggregate awaited fan-out to linked hub shadows across all changed resources. */\n fanout: { hubs: number; failures: number };\n errors?: string[];\n}\n","import { z } from 'zod';\nimport { uuidSchema } from './common';\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\n// --- Param schemas ---\n\nexport const adminOrgIdParam = z.object({\n orgId: uuidSchema,\n});\n\nexport const adminOrgAdminIdParam = z.object({\n orgId: uuidSchema,\n adminId: uuidSchema,\n});\n\nexport const adminUserIdParam = z.object({\n userId: uuidSchema,\n});\n\nexport const adminPlanIdParam = z.object({\n planId: uuidSchema,\n});\n\n// --- Query schemas ---\n\nexport const adminOrganizationsQuery = z.object({\n page: z.coerce.number().int().min(1).default(1),\n limit: z.coerce.number().int().min(1).max(100).default(20),\n search: z.string().optional().default(''),\n});\n\nexport const adminUserSearchQuery = z.object({\n email: z.string().min(3, 'email query parameter must be at least 3 characters'),\n});\n\n// One-time kanban slug migration query. Default is dry-run for safety.\nexport const kanbanSlugMigrationQuery = z.object({\n dry_run: z.enum(['true', 'false']).optional(),\n});\n\n// --- Body schemas ---\n\nexport const adjustQuotaBody = z.object({\n metric_type: z.string().min(1, 'metric_type is required'),\n action: z.enum(['add', 'set']),\n value: z.number().int().min(0, 'value must be a non-negative number'),\n});\n\nexport const updatePlanBody = z.object({\n plan_type: z.enum(['free', 'paid']),\n});\n\nexport const addAdminUserBody = z.object({\n user_email: z.string().email('user_email must be a valid email address'),\n});\n\nexport const updatePlatformConfigBody = z.object({\n free_plan_message_allowance: z.number().int().min(0).optional(),\n free_plan_reset_type: z.string().optional(),\n free_plan_max_free_orgs_per_user: z.number().int().min(0).optional(),\n /** Kill switch for admin debug-read endpoints. 0 = off, 1 = on. */\n debug_read_enabled: z.number().int().min(0).max(1).optional(),\n}).strip().refine(\n (data) => Object.keys(data).length > 0,\n { message: 'No fields to update' }\n);\n\nexport const updateFreeOrgLimitBody = z.object({\n max_free_orgs_override: z.number().int().min(0).nullable(),\n});\n\nexport const updatePricingPlanBody = z.object({\n display_name: z.string().min(1).optional(),\n stripe_product_id: z.string().optional(),\n lookup_key_prefix: z.string().optional(),\n messages_per_unit: z.number().int().min(1, 'messages_per_unit must be a positive integer').optional(),\n seats_per_unit: z.number().int().min(1, 'seats_per_unit must be a positive integer').optional(),\n seats_scaling: z.enum(['fixed', 'per_quantity']).optional(),\n is_active: z.boolean().optional(),\n}).strip().refine(\n (data) => Object.keys(data).length > 0,\n { message: 'No fields to update' }\n);\n\n// =============================================================================\n// INFERRED TYPES\n// =============================================================================\n\nexport type AdjustQuotaInput = z.infer<typeof adjustQuotaBody>;\nexport type UpdatePlanInput = z.infer<typeof updatePlanBody>;\nexport type AddAdminUserInput = z.infer<typeof addAdminUserBody>;\nexport type UpdatePlatformConfigInput = z.infer<typeof updatePlatformConfigBody>;\nexport type UpdateFreeOrgLimitInput = z.infer<typeof updateFreeOrgLimitBody>;\nexport type UpdatePricingPlanInput = z.infer<typeof updatePricingPlanBody>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\n/** GET /admin/check */\nexport interface AdminCheckResponse {\n is_platform_admin: true;\n}\n\n/** Billing metric row returned inside organization list/detail */\nexport interface AdminBillingMetric {\n organization_id: string;\n metric_type: string;\n monthly_included: number;\n consumed_subscription: number;\n}\n\n/** Organization item in the paginated list */\nexport interface AdminOrganizationItem {\n organization_id: string;\n organization_name: string;\n created_at: string;\n plan_type: string;\n billing_status: string;\n has_subscription: boolean;\n period_end: string | null;\n owner_email: string | null;\n admin_users: Array<{\n organization_admin_user_id: string;\n user_email: string;\n is_owner: boolean;\n }>;\n metrics: AdminBillingMetric[];\n}\n\n/** Pagination metadata */\nexport interface AdminPaginationMeta {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n}\n\n/** GET /admin/organizations */\nexport interface AdminOrganizationsListResponse {\n data: AdminOrganizationItem[];\n pagination: AdminPaginationMeta;\n}\n\n/** POST /admin/organizations/:orgId/resync-registry */\nexport interface AdminResyncOrgRegistryResponse {\n ok: true;\n org_id: string;\n patched_fields: string[];\n}\n\n/** POST /admin/dev/backfill-org-registry */\nexport interface AdminBackfillOrgRegistryResponse {\n processed: number;\n succeeded: number;\n failed: number;\n failures: Array<{ org_id: string; error: string }>;\n}\n\n/** GET /admin/organizations/:orgId */\nexport interface AdminOrganizationDetailResponse {\n data: {\n organization_id: string;\n billing: Record<string, unknown> | null;\n metrics: AdminBillingMetric[];\n admin_users: Array<{\n organization_admin_user_id: string;\n user_email: string;\n is_owner: boolean;\n }>;\n };\n}\n\n/** POST /admin/organizations/:orgId/admins */\nexport interface AdminAddAdminUserResponse {\n data: {\n organization_admin_user_id: string;\n user_email: string;\n is_owner: boolean;\n };\n}\n\n/** GET /admin/config, PATCH /admin/config */\nexport interface AdminConfigResponse {\n data: Record<string, unknown>;\n}\n\n/** User search result item */\nexport interface AdminUserSearchItem {\n user_id: string;\n user_email: string;\n profile_name: string | null;\n max_free_orgs_override: number | null;\n}\n\n/** GET /admin/users/search */\nexport interface AdminUserSearchResponse {\n data: AdminUserSearchItem[];\n}\n\n/** PATCH /admin/users/:userId/free-org-limit */\nexport interface AdminUpdateFreeOrgLimitResponse {\n data: AdminUserSearchItem;\n}\n\n/** GET /admin/pricing-plans */\nexport interface AdminPricingPlansListResponse {\n data: Array<Record<string, unknown>>;\n}\n\n/** PATCH /admin/pricing-plans/:planId */\nexport interface AdminUpdatePricingPlanResponse {\n data: Record<string, unknown>;\n}\n\n// One-time kanban slug migration result.\nexport interface KanbanSlugMigrationResult {\n dry_run: boolean;\n total_hubs: number;\n migrated: number;\n already_migrated: number;\n skipped: Array<{ hub_id: string; reason: string }>;\n}\n\n/** POST /admin/migrate/kanban-slugs */\nexport interface KanbanSlugMigrationResponse {\n data: KanbanSlugMigrationResult;\n}\n\n// =============================================================================\n// DATA EXPLORER — Request Schemas\n// =============================================================================\n\nexport const dataExplorerSearchQuery = z.object({\n q: z.string().min(1, 'search query is required'),\n type: z.enum(['org', 'hub', 'user']).optional(),\n});\n\nexport const dataExplorerOrgIdParam = z.object({ orgId: uuidSchema });\nexport const dataExplorerHubIdParam = z.object({ hubId: uuidSchema });\nexport const dataExplorerConvIdParam = z.object({ convId: uuidSchema });\n\nexport const dataExplorerDoInstancesQuery = z.object({\n cursor: z.string().optional(),\n limit: z.coerce.number().int().min(1).max(100).default(50),\n orphans_only: z.coerce.boolean().optional().default(false),\n /** Direct lookup by entity UUID (hub_id/org_id/user_id/conversation_id). When set, bypasses pagination and returns a synthesized entry via idFromName. */\n search: z.string().optional(),\n});\n\nexport const dataExplorerNsIdParam = z.object({\n nsId: z.string().min(1, 'namespace ID is required'),\n});\n\nexport const dataExplorerKvKeysQuery = z.object({\n prefix: z.string().optional(),\n cursor: z.string().optional(),\n limit: z.coerce.number().int().min(1).max(100).default(50),\n});\n\nexport const dataExplorerKvKeyParam = z.object({\n nsId: z.string().min(1),\n key: z.string().min(1, 'key is required'),\n});\n\n/** Accepts UUID or Cloudflare DO hex ID (for orphan deletion) */\nconst uuidOrHexId = z.string().min(1);\nexport const dataExplorerDeleteOrgParam = z.object({ orgId: uuidOrHexId });\nexport const dataExplorerDeleteHubParam = z.object({ hubId: uuidOrHexId });\nexport const dataExplorerDeleteConvParam = z.object({ convId: uuidOrHexId });\nexport const dataExplorerDeleteUserParam = z.object({ userId: uuidOrHexId });\n\nexport const dataExplorerDeleteQuery = z.object({\n confirmation: z.string().min(1, 'confirmation is required'),\n cascade: z.coerce.boolean().optional().default(false),\n});\n\nexport const dataExplorerKvDeleteQuery = z.object({\n confirmation: z.string().min(1, 'confirmation is required'),\n});\n\n// =============================================================================\n// DATA EXPLORER — Inferred Types\n// =============================================================================\n\nexport type DataExplorerSearchInput = z.infer<typeof dataExplorerSearchQuery>;\nexport type DataExplorerDeleteInput = z.infer<typeof dataExplorerDeleteQuery>;\n\n// =============================================================================\n// DATA EXPLORER — Response Types\n// =============================================================================\n\n/** Hub entry in org entity tree */\nexport interface DataExplorerHubEntry {\n hub_id: string;\n hub_name: string;\n hub_type: string;\n hub_environment: string;\n production_hub_id: string | null;\n dashboard_url: string | null;\n}\n\n/** Search result item */\nexport interface DataExplorerSearchResultItem {\n type: 'org' | 'hub' | 'user';\n id: string;\n name: string;\n /** Extra context (e.g., org name for hub results, email for user results) */\n context?: string;\n}\n\n/** GET /data-explorer/search */\nexport interface DataExplorerSearchResponse {\n data: DataExplorerSearchResultItem[];\n}\n\n/** GET /data-explorer/entity/org/:orgId */\nexport interface DataExplorerOrgEntityResponse {\n data: {\n organization_id: string;\n organization_name: string;\n dashboard_url: string | null;\n hubs: DataExplorerHubEntry[];\n billing: Record<string, unknown> | null;\n };\n}\n\n/** GET /data-explorer/entity/hub/:hubId */\nexport interface DataExplorerHubEntityResponse {\n data: {\n hub_id: string;\n hub_name: string;\n hub_type: string;\n dashboard_url: string | null;\n conversation_count: number;\n };\n}\n\n/** GET /data-explorer/entity/conversation/:convId */\nexport interface DataExplorerConvEntityResponse {\n data: {\n conversation_id: string;\n dashboard_url: string | null;\n conversation: Record<string, unknown> | null;\n };\n}\n\n/** DO namespace item */\nexport interface DataExplorerDoNamespace {\n id: string;\n name: string;\n class: string;\n}\n\n/** GET /data-explorer/do/namespaces */\nexport interface DataExplorerDoNamespacesResponse {\n data: DataExplorerDoNamespace[];\n}\n\n/** DO instance item */\nexport interface DataExplorerDoInstance {\n id: string;\n name: string | null;\n /** `null` means the backend did not probe CF for storage state (e.g., direct search by UUID) */\n hasStoredData: boolean | null;\n dashboard_url: string;\n /** The domain entity ID (e.g., org_id, hub_id) used in idFromName — null if unknown */\n entity_id?: string | null;\n /** Resolved domain name (e.g., org name) — null if not resolved */\n resolved_name?: string | null;\n /** Whether this instance is an orphan (not in any known hierarchy) */\n is_orphan?: boolean;\n}\n\n/** GET /data-explorer/do/namespaces/:nsId/instances */\nexport interface DataExplorerDoInstancesResponse {\n data: DataExplorerDoInstance[];\n cursor?: string;\n}\n\n/** KV namespace item */\nexport interface DataExplorerKvNamespace {\n name: string;\n id: string;\n}\n\n/** GET /data-explorer/kv/namespaces */\nexport interface DataExplorerKvNamespacesResponse {\n data: DataExplorerKvNamespace[];\n}\n\n/** KV key item */\nexport interface DataExplorerKvKeyItem {\n name: string;\n metadata: Record<string, unknown> | null;\n expiration?: number;\n}\n\n/** GET /data-explorer/kv/namespaces/:nsId/keys */\nexport interface DataExplorerKvKeysResponse {\n data: DataExplorerKvKeyItem[];\n cursor?: string;\n}\n\n/** GET /data-explorer/kv/namespaces/:nsId/keys/:key */\nexport interface DataExplorerKvValueResponse {\n data: {\n key: string;\n value: string | null;\n masked: boolean;\n };\n}\n\n/** DELETE responses */\nexport interface DataExplorerDeleteResult {\n deleted: string[];\n failed: Array<{ id: string; error: string }>;\n}\n\nexport interface DataExplorerDeleteResponse {\n data: DataExplorerDeleteResult;\n}\n\n// =============================================================================\n// PITR (Point-in-Time Recovery) — Request Schemas\n// =============================================================================\n\n/** Valid DO namespace names for PITR operations */\nexport const pitrDoNamespace = z.enum(['HUB_DO', 'CONVERSATION_DO', 'ORG_DO', 'USER_DO', 'PLATFORM_DO']);\n\n/** GET /admin/pitr/:namespace/:instanceId/bookmark */\nexport const pitrBookmarkParam = z.object({\n namespace: pitrDoNamespace,\n instanceId: z.string().min(1, 'instanceId is required'),\n});\n\n/** POST /admin/pitr/:namespace/:instanceId/restore — reuses bookmark param shape */\nexport const pitrRestoreParam = pitrBookmarkParam;\n\n/** Body for restore request */\nexport const pitrRestoreBody = z.object({\n /** ISO 8601 timestamp to restore to (must be within last 30 days) */\n target_timestamp: z.string().datetime('target_timestamp must be a valid ISO 8601 datetime'),\n /** Must match the instanceId for confirmation */\n confirmation: z.string().min(1, 'confirmation is required'),\n /** If true, only fetch the bookmark without performing the restore (default: true) */\n dry_run: z.boolean().default(true),\n});\n\n// =============================================================================\n// PITR — Inferred Types\n// =============================================================================\n\nexport type PitrDoNamespace = z.infer<typeof pitrDoNamespace>;\nexport type PitrRestoreInput = z.infer<typeof pitrRestoreBody>;\n\n// =============================================================================\n// PITR — Response Types\n// =============================================================================\n\n/** GET /admin/pitr/:namespace/:instanceId/bookmark */\nexport interface PitrBookmarkResponse {\n data: {\n namespace: string;\n instance_id: string;\n current_bookmark: string;\n };\n}\n\n/** POST /admin/pitr/:namespace/:instanceId/restore */\nexport interface PitrRestoreResponse {\n data: {\n namespace: string;\n instance_id: string;\n target_timestamp: string;\n target_bookmark: string;\n current_bookmark: string;\n /** Bookmark that can be used to undo this restore */\n undo_bookmark: string | null;\n dry_run: boolean;\n restore_scheduled: boolean;\n };\n}\n\n// =============================================================================\n// DO Health Validation — Response Types\n// =============================================================================\n\nexport interface HealthValidationIssue {\n table: string;\n check: 'existence' | 'row_count' | 'json_validity';\n severity: 'error' | 'warning';\n message: string;\n}\n\nexport interface HealthValidationResponse {\n data: {\n status: 'pass' | 'fail';\n tables_checked: number;\n tables_passed: number;\n issues: HealthValidationIssue[];\n checked_at: string;\n };\n}\n\n// =============================================================================\n// Health Sampling — Request Schemas\n// =============================================================================\n\n/** POST /admin/health-sampling — trigger body */\nexport const healthSamplingTriggerBody = z.object({\n /** Number of instances to sample per DO type (default: 10) */\n sample_size: z.number().int().min(1).max(100).default(10),\n /** Filter to specific DO types (default: all) */\n do_types: z.array(pitrDoNamespace).optional(),\n});\n\nexport type HealthSamplingTriggerInput = z.infer<typeof healthSamplingTriggerBody>;\n\n// =============================================================================\n// DATA EXPLORER DEBUG READS — Request Schemas\n// =============================================================================\n//\n// Platform-admin-only read-only inspection of DO SQLite state. Gated by\n// platformAdminMiddleware + strict rate limit + kill switch + column redaction.\n// See workers/backend/src/durable-objects/debug-redaction.ts for the central\n// allowlist and redaction rules.\n\n/** Valid DO types for debug reads. Shared source of truth — re-exported as `DoType` in debug-redaction.ts. */\nexport const dataExplorerDebugDoType = z.enum(['hub', 'org', 'conversation', 'user', 'platform']);\n\n/** Hard cap on `limit` query param — applied in both Zod and the DO RPC. */\nexport const DEBUG_READ_MAX_LIMIT = 100;\n/** Default `limit` when the caller omits it. */\nexport const DEBUG_READ_DEFAULT_LIMIT = 20;\n\nexport const DEBUG_DO_HEX_PREFIX = 'hex:';\n\n/**\n * `hex:<64-hex>` is resolved via `idFromString` (raw CF DO id — for inspecting\n * DOs discovered without a reverse path, e.g. orphan-audit). All other forms\n * go through `idFromName`.\n */\nconst debugDoEntityId = z\n .string()\n .min(1, 'entity id is required')\n .max(68)\n .refine(\n (v) => !v.startsWith(DEBUG_DO_HEX_PREFIX) || /^hex:[0-9a-f]{64}$/.test(v),\n { message: 'hex: prefix must be followed by exactly 64 lowercase hex chars' },\n );\n\n/**\n * Table name param. Two-layer injection defense: regex here + assertTableAllowed()\n * against a frozen allowlist in the DO RPC. Table names are NEVER string-interpolated\n * into SQL — they're looked up in a constant map.\n */\nconst debugTableName = z.string().regex(\n /^[a-z][a-z0-9_]{0,63}$/,\n 'table name must be lowercase letters, digits, underscores (<=64 chars)',\n);\n\n/** GET /api/admin/data-explorer/debug/do/:type/:id/tables */\nexport const dataExplorerDebugTablesParam = z.object({\n type: dataExplorerDebugDoType,\n id: debugDoEntityId,\n});\n\n/** GET /api/admin/data-explorer/debug/do/:type/:id/tables/:name/rows */\nexport const dataExplorerDebugRowsParam = z.object({\n type: dataExplorerDebugDoType,\n id: debugDoEntityId,\n name: debugTableName,\n});\n\nexport const dataExplorerDebugRowsQuery = z.object({\n limit: z.coerce.number().int().min(1).max(DEBUG_READ_MAX_LIMIT).default(DEBUG_READ_DEFAULT_LIMIT),\n /** Optional lookup by primary key value — typed as string since PKs are all TEXT UUIDs */\n id: z.string().min(1).max(256).optional(),\n});\n\n// =============================================================================\n// DATA EXPLORER DEBUG READS — Inferred Types\n// =============================================================================\n\nexport type DataExplorerDebugDoType = z.infer<typeof dataExplorerDebugDoType>;\nexport type DataExplorerDebugRowsQueryInput = z.infer<typeof dataExplorerDebugRowsQuery>;\n\n// =============================================================================\n// DATA EXPLORER DEBUG READS — Response Types\n// =============================================================================\n\n/** GET /api/admin/data-explorer/debug/do/:type/:id/tables */\nexport interface DataExplorerDebugTablesResponse {\n data: {\n do_type: DataExplorerDebugDoType;\n do_id: string;\n /** Tables present in the DO that are also in the debug allowlist */\n tables: string[];\n };\n}\n\n/** GET /api/admin/data-explorer/debug/do/:type/:id/tables/:name/rows */\nexport interface DataExplorerDebugRowsResponse {\n data: {\n do_type: DataExplorerDebugDoType;\n do_id: string;\n table: string;\n /** Rows with sensitive columns replaced by the string \"[REDACTED]\" */\n rows: Record<string, unknown>[];\n /** Column names that were redacted in this response (for operator awareness) */\n redacted_columns: string[];\n /** True if the result was capped at `limit` and more rows may exist */\n truncated: boolean;\n /** Applied limit — echoes the query param or its default */\n limit: number;\n };\n}\n\n// =============================================================================\n// DATA EXPLORER DEBUG READS — ClickHouse analytics tables\n// =============================================================================\n//\n// Same gates as the DO debug surface: platform-admin, audit, rate-limit, kill\n// switch. CH tables are queried via parameterized SQL (`{key:Type}` placeholders)\n// — never string-interpolated. Allowlist + redaction live in\n// workers/backend/src/clickhouse/debug-redaction.ts.\n\n/** Tables an admin can read via `wayai admin analytics`. */\nexport const dataExplorerDebugAnalyticsTable = z.enum([\n 'conversation',\n 'message',\n 'billing_event',\n 'schedule_event',\n]);\nexport type DataExplorerDebugAnalyticsTable = z.infer<typeof dataExplorerDebugAnalyticsTable>;\n\n/** UUID validator reused for filter values. Any non-UUID input is rejected before reaching CH. */\nconst debugUuid = z.string().uuid();\n\n/** GET /api/admin/data-explorer/debug/analytics/:table/rows */\nexport const dataExplorerDebugAnalyticsRowsParam = z.object({\n table: dataExplorerDebugAnalyticsTable,\n});\n\nexport const dataExplorerDebugAnalyticsRowsQuery = z.object({\n conversation_id: debugUuid.optional(),\n hub_id: debugUuid.optional(),\n message_id: debugUuid.optional(),\n limit: z.coerce.number().int().min(1).max(DEBUG_READ_MAX_LIMIT).default(DEBUG_READ_DEFAULT_LIMIT),\n});\n\nexport type DataExplorerDebugAnalyticsRowsQueryInput = z.infer<typeof dataExplorerDebugAnalyticsRowsQuery>;\n\n/** GET /api/admin/data-explorer/debug/analytics/tables */\nexport interface DataExplorerDebugAnalyticsTablesResponse {\n data: {\n tables: DataExplorerDebugAnalyticsTable[];\n };\n}\n\n/** GET /api/admin/data-explorer/debug/analytics/:table/rows */\nexport interface DataExplorerDebugAnalyticsRowsResponse {\n data: {\n table: DataExplorerDebugAnalyticsTable;\n rows: Record<string, unknown>[];\n /** Redacted column names or dotted JSON paths (e.g. \"data\", \"data.meta.last_message_text\"). */\n redacted_columns: string[];\n truncated: boolean;\n limit: number;\n };\n}\n\n// =============================================================================\n// DATA EXPLORER DEBUG READS — R2 archive\n// =============================================================================\n//\n// Admin-gated counterpart to `GET /api/archive/:hubId/conversations/:conversationId`.\n// Same archive blob, but reachable only by platform admins and audited as\n// `admin_debug_read`. Does not provision access — admins still need the blob to\n// exist in R2.\n\n// Hub+conversation pair shared by both debug-archive and debug-observability\n// param schemas — keep them as one source of truth so route paths stay aligned.\nconst debugHubConvParam = z.object({\n hubId: debugUuid,\n conversationId: debugUuid,\n});\n\n// Optional message_id filter — same semantics for archive and observability\n// (server returns the matching message; otherwise the full set).\nconst debugMessageIdQuery = z.object({\n message_id: debugUuid.optional(),\n});\n\nexport const dataExplorerDebugArchiveParam = debugHubConvParam;\nexport const dataExplorerDebugArchiveQuery = debugMessageIdQuery;\n\nexport type DataExplorerDebugArchiveQueryInput = z.infer<typeof dataExplorerDebugArchiveQuery>;\n\n/** GET /api/admin/data-explorer/debug/archive/:hubId/conversations/:conversationId */\nexport interface DataExplorerDebugArchiveResponse {\n data: {\n hub_id: string;\n conversation_id: string;\n /** The full archive blob written by the archive job, optionally with `messages` filtered server-side. */\n archive: Record<string, unknown>;\n /** True when ?message_id= filtered the messages array. */\n message_filtered: boolean;\n };\n}\n\n// =============================================================================\n// DATA EXPLORER DEBUG READS — R2 LLM observability\n// =============================================================================\n//\n// Admin-gated read of per-message OpenTelemetry GenAI records (full prompts,\n// completions, tool calls, tokens, latency). The hub-scoped equivalent at\n// `/api/conversations/:conversationId/...` enforces hub-user / team-member\n// access; this debug variant requires `platform:admin` instead so an operator\n// can inspect any hub for incident response. Same data shape both ways.\n\nexport const dataExplorerDebugObservabilityParam = debugHubConvParam;\nexport const dataExplorerDebugObservabilityQuery = debugMessageIdQuery;\n\nexport type DataExplorerDebugObservabilityQueryInput = z.infer<typeof dataExplorerDebugObservabilityQuery>;\n\n/**\n * GET /api/admin/data-explorer/debug/observability/:hubId/conversations/:conversationId\n *\n * Discriminated by `kind` so TypeScript callers narrow without non-null assertions:\n * - `kind: 'list'` (no ?message_id) — `entries` is populated.\n * - `kind: 'single'` (with ?message_id) — `record` is populated.\n */\nexport type DataExplorerDebugObservabilityResponse =\n | {\n data: {\n kind: 'list';\n hub_id: string;\n conversation_id: string;\n entries: import('../observability/types').WayAIMetadataRecord[];\n /** True when the list was truncated by the server cap. */\n truncated: boolean;\n };\n }\n | {\n data: {\n kind: 'single';\n hub_id: string;\n conversation_id: string;\n record: import('../observability/types').LLMObservabilityRecord;\n };\n };\n\n// =============================================================================\n// Health Sampling — Response Types\n// =============================================================================\n\nexport interface HealthSamplingInstanceResult {\n namespace: string;\n instance_id: string;\n status: 'pass' | 'fail' | 'error';\n issues: HealthValidationIssue[];\n error?: string;\n}\n\nexport interface HealthSamplingReport {\n data: {\n status: 'pass' | 'fail';\n triggered_at: string;\n completed_at: string;\n commit?: string;\n sample_size: number;\n results: HealthSamplingInstanceResult[];\n summary: {\n total_instances: number;\n passed: number;\n failed: number;\n errors: number;\n };\n };\n}\n","import { z } from 'zod';\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\nexport const whatsappCallbackBody = z.object({\n state: z.string().min(1, 'state is required'),\n code: z.string().optional(),\n access_token: z.string().optional(),\n user_id: z.string().optional(),\n}).refine(\n (data) => !!data.access_token || !!data.code,\n { message: 'Missing required parameters: state and either access_token or code' }\n);\n\n// =============================================================================\n// AUTH ME — GET /api/auth/me\n// =============================================================================\n\nexport const authMeResponse = z.object({\n user_id: z.string(),\n email: z.string(),\n org_id: z.string().nullable(),\n is_platform_admin: z.boolean(),\n});\n\nexport type AuthMeResponse = z.infer<typeof authMeResponse>;\n\n// =============================================================================\n// WS TICKET — POST /api/auth/ws-ticket\n// =============================================================================\n\nexport const wsTicketResponse = z.object({\n ticket: z.string(),\n /** Seconds until the ticket expires if unconsumed. */\n expires_in: z.number(),\n});\n\nexport type WsTicketResponse = z.infer<typeof wsTicketResponse>;\n\n// =============================================================================\n// SESSION CHECK — GET /api/auth/session-check\n// =============================================================================\n\nexport const sessionCheckResponse = z.object({\n valid: z.literal(true),\n});\n\nexport type SessionCheckResponse = z.infer<typeof sessionCheckResponse>;\n\n// =============================================================================\n// LOGOUT — POST /api/auth/logout\n// =============================================================================\n\nexport const logoutResponse = z.object({\n success: z.literal(true),\n});\n\nexport type LogoutResponse = z.infer<typeof logoutResponse>;\n\n// =============================================================================\n// INFERRED TYPES\n// =============================================================================\n\nexport type WhatsappCallbackInput = z.infer<typeof whatsappCallbackBody>;\n","import { z } from 'zod';\nimport { uuidSchema } from './common';\n\n// =============================================================================\n// REQUEST SCHEMAS\n// =============================================================================\n\nexport const browserParams = z.object({\n hubId: uuidSchema,\n resourceId: uuidSchema,\n});\n\nexport const browserFoldersQuery = z.object({\n parent_folder_id: uuidSchema.optional(),\n search: z.string().max(100).optional(),\n});\n\nexport const browserFilesQuery = z.object({\n folder_id: uuidSchema.optional(),\n search: z.string().max(100).optional(),\n limit: z.coerce.number().int().min(1).max(100).default(50),\n offset: z.coerce.number().int().min(0).max(10000).default(0),\n});\n\n// =============================================================================\n// INFERRED TYPES\n// =============================================================================\n\nexport type BrowserParams = z.infer<typeof browserParams>;\nexport type BrowserFoldersQuery = z.infer<typeof browserFoldersQuery>;\nexport type BrowserFilesQuery = z.infer<typeof browserFilesQuery>;\n\n// =============================================================================\n// RESPONSE TYPES\n// =============================================================================\n\nexport interface BrowserFolderItem {\n folder_id: string;\n folder_name: string;\n folder_description: string | null;\n parent_folder_id: string | null;\n metadata: Record<string, unknown>;\n file_count: number;\n subfolder_count: number;\n resource_id: string;\n resource_name: string;\n}\n\nexport interface BrowserFileItem {\n file_id: string;\n file_name: string;\n file_description: string | null;\n mime_type: string | null;\n file_size: number | null;\n folder_id: string | null;\n metadata: Record<string, unknown>;\n resource_id: string;\n resource_name: string;\n}\n\nexport interface BrowserFoldersResponse {\n success: boolean;\n folders: BrowserFolderItem[];\n total_count: number;\n}\n\nexport interface BrowserFilesResponse {\n success: boolean;\n files: BrowserFileItem[];\n total_count: number;\n}\n","import { z } from 'zod';\nimport { slugSchema } from './setup/slug';\n\n// ---------------------------------------------------------------------------\n// State Operations (via state_operations RPC)\n// ---------------------------------------------------------------------------\n\nexport const stateOperationBody = z.object({\n hub_id: z.string().uuid(),\n operation: z.enum(['get', 'update', 'set_path', 'reset']),\n state_slug: slugSchema,\n /**\n * Deprecated and ignored. Scope is derived from the hub's state definition.\n * Kept on the schema so legacy bodies still validate.\n */\n state_scope: z.enum(['conversation', 'user']).optional(),\n updates: z.record(z.unknown()).optional(),\n path: z.array(z.string()).optional(),\n value: z.unknown().optional(),\n});\n\nexport type StateOperationBody = z.infer<typeof stateOperationBody>;\n\nexport interface StateOperationResponse {\n ok: true;\n data: unknown;\n}\n","import { z } from 'zod';\n\nexport const conversationListResourcesQuery = z.object({\n hub_id: z.string().uuid(),\n agent_id: z.string().uuid().optional(),\n});\n\nexport const conversationReadResourceQuery = z.object({\n hub_id: z.string().uuid(),\n});\n\nexport type ConversationListResourcesQuery = z.infer<typeof conversationListResourcesQuery>;\nexport type ConversationReadResourceQuery = z.infer<typeof conversationReadResourceQuery>;\n\nexport type ConversationListResourcesResponse = {\n ok: true;\n data: Array<{\n file_id: string;\n file_name: string;\n mime_type: string;\n file_size: number | null;\n }>;\n} | { ok: false; error: string };\n\nexport type ConversationReadResourceResponse = {\n ok: true;\n data: {\n file_id: string;\n file_name: string;\n content: string;\n mime_type: string;\n };\n} | { ok: false; error: string };\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Params & Queries\n// ---------------------------------------------------------------------------\n\nexport const listPendingSchedulesQuery = z.object({\n hub_id: z.string().uuid(),\n conversation_id: z.string().uuid().optional(),\n user_id: z.string().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type ListPendingSchedulesQuery = z.infer<typeof listPendingSchedulesQuery>;\n\n// ---------------------------------------------------------------------------\n// Response types\n// ---------------------------------------------------------------------------\n\nexport interface PendingScheduleEntry {\n conversation_schedule_id: string;\n schedule_type: string;\n run_at: string;\n message_text: string;\n conversation_id: string | null;\n user_id: string | null;\n hub_id: string;\n hub_type: string;\n agent_id: string | null;\n receiver_type: string;\n followup_order: number | null;\n followup_source: 'kanban' | 'default_open' | 'default_closed' | null;\n followup_type: 'inactivity' | 'before_event' | null;\n end_conversation: boolean;\n sender_type: string | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface ListPendingSchedulesResponse {\n entries: PendingScheduleEntry[];\n total: number;\n}\n\n// ---------------------------------------------------------------------------\n// Hub-admin aggregate view (SCHEDULE_INDEX KV)\n// ---------------------------------------------------------------------------\n\nexport const listHubAggregateSchedulesQuery = z.object({\n hub_id: z.string().uuid(),\n limit: z.coerce.number().int().min(1).max(1000).optional(),\n});\n\nexport type ListHubAggregateSchedulesQuery = z.infer<typeof listHubAggregateSchedulesQuery>;\n\nexport interface HubAggregateScheduleEntry {\n schedule_id: string;\n kind: 'conversation' | 'hub';\n schedule_type: string;\n run_at: string;\n conversation_id: string | null;\n}\n\nexport interface ListHubAggregateSchedulesResponse {\n entries: HubAggregateScheduleEntry[];\n total: number;\n list_complete: boolean;\n}\n","import { z } from 'zod';\n\n// =============================================================================\n// SHARED ENUMS — kept in sync with PlatformDO schema CHECK constraints\n// =============================================================================\n\n// `source` = origin/channel: who/what filed the report.\n// sentry — production runtime error (Sentry webhook)\n// cli — human via `wayai report create`\n// review — code agent, during the review loop\n// security_audit — code agent, during the /security-screening skill\nexport const reportSourceSchema = z.enum(['sentry', 'cli', 'review', 'security_audit']);\nexport type ReportSource = z.infer<typeof reportSourceSchema>;\n\n// Narrowed source set accepted at the CLI intake endpoint. Excludes `sentry`\n// so a `way_`-token caller can't forge a Sentry-origin row.\nexport const intakeReportSourceSchema = z.enum(['cli', 'review', 'security_audit']);\nexport type IntakeReportSource = z.infer<typeof intakeReportSourceSchema>;\n\n// `classification` = nature of the report. Drives the GitHub label on escalation\n// and the dedup-fingerprint strategy. Orthogonal to `source`.\nexport const reportClassificationSchema = z.enum(['bug', 'flaky_test', 'security']);\nexport type ReportClassification = z.infer<typeof reportClassificationSchema>;\n\n// `shipped` and `contested` are the agent-interactive loop states (see the report\n// lifecycle in the report-triage skill): the fixer marks a fix `shipped` (awaiting the\n// reporter), and the reporter `contested` a fix or a dismissal back to triage.\nexport const reportStatusSchema = z.enum([\n 'pending',\n 'grouped',\n 'escalated',\n 'shipped',\n 'contested',\n 'addressed',\n 'dismissed',\n]);\nexport type ReportStatus = z.infer<typeof reportStatusSchema>;\n\nexport const reportLocaleSchema = z.enum(['en', 'pt', 'es']);\nexport type ReportLocale = z.infer<typeof reportLocaleSchema>;\n\n// Author of a `report_message` thread entry. The thread is the reporter-facing narrative\n// channel (the loop's memory across rounds); every entry here is reporter-safe — internal\n// triage reasoning (`ai_verdict`) is NOT mirrored into it.\nexport const reportMessageAuthorRoleSchema = z.enum(['reporter', 'triage', 'fixer', 'system']);\nexport type ReportMessageAuthorRole = z.infer<typeof reportMessageAuthorRoleSchema>;\n\nexport interface ReportMessage {\n message_id: string;\n author_role: ReportMessageAuthorRole;\n /** The status transition this note accompanied (e.g. 'shipped'); null for a free/system note. */\n transition: string | null;\n body: string;\n created_at: number;\n /**\n * Visibility: `false` = reporter-facing (the default for every narrative entry); `true` =\n * triage-internal (e.g. a `hold` rationale) — surfaced to platform admins only and NEVER\n * returned on the reporter read path. The reporter's `GET /api/reports/:id` filters these out.\n */\n internal: boolean;\n}\n\n// `sentry_ref_status` = result of cross-checking a Sentry-sourced report's\n// captured issue reference (`raw_payload.issue_id` / `short_id`) against the\n// live Sentry API at escalation time. Null for non-sentry reports or before the\n// check has run. Gates the GH-webhook auto-resolve: only a `valid` reference is\n// resolved on issue close, so a fabricated/dead/mismatched ref can never resolve\n// the wrong live issue (the failure #2438 documents).\n// valid — issue_id resolves AND the captured short_id matches the live issue\n// not_found — issue_id does not resolve (dead/fabricated reference)\n// mismatch — issue_id resolves but the captured short_id ≠ the live short_id\n// unverified — could not check (no SENTRY_API_TOKEN, or a Sentry API error)\nexport const sentryRefStatusSchema = z.enum(['valid', 'not_found', 'mismatch', 'unverified']);\nexport type SentryRefStatus = z.infer<typeof sentryRefStatusSchema>;\n\n// =============================================================================\n// INTAKE — POST /api/reports (CLI only)\n//\n// Replaces /api/bug-reports. MCP `report_bug` tool has been removed entirely;\n// reporting is a code-agent (CLI) workflow.\n// =============================================================================\n\nexport const createReportBody = z.object({\n title: z.string().min(5).max(256),\n description: z.string().min(10).max(5000),\n steps_to_reproduce: z.string().max(3000).optional(),\n error_message: z.string().max(2000).optional(),\n\n // Taxonomy (server defaults: source=cli, classification=bug when absent).\n source: intakeReportSourceSchema.optional(),\n classification: reportClassificationSchema.optional(),\n // Stable dedup key (e.g. \"<file>::<test>\" for flaky, \"<file>:<line>\" for\n // security). When present, the fingerprint uses it instead of the body hash.\n dedup_key: z.string().min(1).max(256).optional(),\n\n // Context fields (auto-captured by the CLI)\n organization_id: z.string().optional(),\n hub_id: z.string().uuid().optional(),\n hub_name: z.string().max(256).optional(),\n conversation_id: z.string().uuid().optional(),\n agent_id: z.string().uuid().optional(),\n agent_name: z.string().max(256).optional(),\n client_version: z.string().max(64).optional(),\n additional_context: z.string().max(2000).optional(),\n});\nexport type CreateReportBody = z.infer<typeof createReportBody>;\n\nexport interface CreateReportResponse {\n report_id: string;\n status: ReportStatus;\n /** True if this submission created a new row; false if it merged into an existing fingerprint. */\n created: boolean;\n}\n\n// =============================================================================\n// EDIT — PATCH /api/reports/:id (reporter) and PATCH /api/admin/reports/:id (admin)\n//\n// Amends the mutable content fields of an already-filed report. The fields live\n// inside `raw_payload`; the dedup `fingerprint` is FROZEN at creation and is\n// never recomputed on edit (editing the same 5 fields the fingerprint hashes\n// would otherwise let an edit collide with another row's fingerprint or silently\n// change the dedup identity). `.strict()` so nothing outside these 5 keys can\n// reach the merge; `.refine` rejects a no-op edit (empty body). The 3 optional\n// fields accept an empty string to clear them (stored as null, matching create).\n// =============================================================================\n\nexport const editReportBody = z\n .object({\n title: z.string().min(5).max(256).optional(),\n description: z.string().min(10).max(5000).optional(),\n steps_to_reproduce: z.string().max(3000).optional(),\n error_message: z.string().max(2000).optional(),\n additional_context: z.string().max(2000).optional(),\n })\n .strict()\n .refine((b) => Object.keys(b).length > 0, {\n message: 'at least one field must be provided',\n });\nexport type EditReportBody = z.infer<typeof editReportBody>;\n\nexport interface EditReportResponse {\n report_id: string;\n status: ReportStatus;\n /** Epoch ms of this edit (also stamped on the row's edited_at column). */\n edited_at: number | null;\n /** The merged content blob after the edit. */\n raw_payload: unknown;\n}\n\n// =============================================================================\n// REPORTER — read-back + verification loop (own `cli` reports only)\n//\n// GET /api/reports — list the caller's own reports\n// GET /api/reports/:id — one own report + its message thread\n// POST /api/reports/:id/accept — shipped → addressed (accept the fix)\n// POST /api/reports/:id/contest — {shipped|dismissed} → contested (reason required)\n//\n// The reporter-facing summary deliberately WITHHOLDS internal fields (`gh_issue_url`,\n// `ai_verdict`) — the private GitHub URL is never surfaced to a reporter (same discipline as\n// the escalation email), and triage's internal reasoning stays internal. Reporter-facing\n// narrative (fixer's shipped note, dismissal reason, contest reasons, system notices) lives\n// in the `messages` thread.\n// =============================================================================\n\nexport interface ReporterReportSummary {\n report_id: string;\n classification: ReportClassification;\n status: ReportStatus;\n created_at: number;\n triaged_at: number | null;\n resolved_at: number | null;\n /** How many times the reporter has contested (gates the hard cap). */\n contest_count: number;\n /** True once triage issued a non-contestable (final) dismissal. */\n dismissal_final: boolean;\n}\n\nexport interface ReporterListResponse {\n data: ReporterReportSummary[];\n}\n\nexport interface GetReportResponse {\n report: ReporterReportSummary;\n messages: ReportMessage[];\n}\n\n/** Returned by /accept and /contest — the updated reporter-facing summary. */\nexport interface ReporterTransitionResponse {\n report: ReporterReportSummary;\n}\n\nexport const contestReportBody = z.object({\n reason: z.string().min(1).max(1000),\n});\nexport type ContestReportBody = z.infer<typeof contestReportBody>;\n\nexport const reporterListQuery = z.object({\n status: reportStatusSchema.optional(),\n});\nexport type ReporterListQuery = z.infer<typeof reporterListQuery>;\n\n// Hard cap on reporter contests (across both fix- and dismissal-disputes). Once\n// `contest_count` reaches this, the next contest is refused (409) and the report is flagged\n// for human routing — this is what bounds the converge loop now that `dismissed` is\n// contestable. Shared so the route, the DO-adjacent logic, and tests agree on one number.\nexport const REPORT_CONTEST_CAP = 3;\n\n// =============================================================================\n// ADMIN — read views\n// =============================================================================\n\nexport const listReportsQuery = z.object({\n status: reportStatusSchema.optional(),\n source: reportSourceSchema.optional(),\n limit: z.coerce.number().int().min(1).max(200).optional(),\n offset: z.coerce.number().int().min(0).optional(),\n /** ISO 8601 lower bound on created_at. */\n since: z.string().datetime().optional(),\n});\nexport type ListReportsQuery = z.infer<typeof listReportsQuery>;\n\nexport interface AdminReportSummary {\n report_id: string;\n source: ReportSource;\n classification: ReportClassification;\n status: ReportStatus;\n fingerprint: string;\n group_id: string | null;\n gh_issue_url: string | null;\n ai_verdict: string | null;\n dismissal_reason: string | null;\n /** Live-Sentry cross-check result for sentry-sourced reports (set at escalation). Null otherwise. */\n sentry_ref_status: SentryRefStatus | null;\n user_id: string | null;\n org_id: string | null;\n reporter_email: string | null;\n reporter_locale: string | null;\n created_at: number;\n triaged_at: number | null;\n resolved_at: number | null;\n /** Set when a content edit amended this report; null if never edited. */\n edited_at: number | null;\n /** user_id of the last editor (reporter or platform admin); null if never edited. */\n edited_by: string | null;\n /** Times the reporter contested a fix or dismissal (gates the hard cap). */\n contest_count: number;\n /** True once triage issued a non-contestable (final) dismissal. */\n dismissal_final: boolean;\n /** Times triage held (deferred) this row by a cycle — the explicit \"how many cycles\" signal. */\n hold_count: number;\n /** Epoch ms of the most recent hold; null if never held. */\n last_held_at: number | null;\n}\n\nexport interface AdminReportDetail extends AdminReportSummary {\n raw_payload: unknown;\n group_members: AdminReportSummary[];\n notified_at_escalated: number | null;\n notified_at_addressed: number | null;\n notified_at_dismissed: number | null;\n notified_at_shipped: number | null;\n /** Reporter-facing narrative thread (also visible to admins). */\n messages: ReportMessage[];\n}\n\nexport interface AdminReportListResponse {\n data: AdminReportSummary[];\n total: number;\n}\n\n// =============================================================================\n// ADMIN — mutations (state-machine RPC)\n// =============================================================================\n\n// z.string().url() accepts `javascript:` — constrain to https://github.com/<owner>/<repo>/issues/<N> for email-safe href.\nexport const GITHUB_ISSUE_URL_REGEX = /^https:\\/\\/github\\.com\\/[^/]+\\/[^/]+\\/issues\\/\\d+(?:[/?#]|$)/;\nconst githubIssueUrlSchema = z\n .string()\n .url()\n .refine((u) => GITHUB_ISSUE_URL_REGEX.test(u), {\n message: 'must be an https://github.com/<owner>/<repo>/issues/<number> URL',\n });\n\n// Admin /transition surface (triage + fixer). Note: `contested` is intentionally absent —\n// only the reporter sets it, via the dedicated reporter-owned /accept and /contest endpoints\n// (a reporter MUST NOT reach the admin adjudication targets). `shipped` is the fixer's\n// hand-back with a reporter-facing `note`; `final` makes a dismissal non-contestable.\nexport const transitionReportBody = z.discriminatedUnion('target', [\n z.object({\n target: z.literal('escalated'),\n gh_issue_url: githubIssueUrlSchema,\n ai_verdict: z.string().max(500).optional(),\n }),\n z.object({\n target: z.literal('shipped'),\n note: z.string().min(1).max(2000).optional(),\n }),\n z.object({\n target: z.literal('addressed'),\n }),\n z.object({\n target: z.literal('dismissed'),\n dismissal_reason: z.string().min(1).max(1000),\n ai_verdict: z.string().max(500).optional(),\n final: z.boolean().optional(),\n }),\n]);\nexport type TransitionReportBody = z.infer<typeof transitionReportBody>;\n\nexport interface TransitionReportResponse {\n report: AdminReportSummary;\n cascaded_report_ids: string[];\n}\n\nexport const groupReportsBody = z.object({\n member_ids: z.array(z.string().uuid()).min(1).max(100),\n});\nexport type GroupReportsBody = z.infer<typeof groupReportsBody>;\n\n/**\n * A member that could not be absorbed into the group, with the reason:\n * - `not_found` — member id does not exist\n * - `terminal` — member is already `addressed`/`dismissed` (detail = the status)\n * - `grouped_elsewhere` — member already belongs to another canonical (detail = its group_id)\n * - `different_gh_issue` — member is linked to a GitHub issue other than the\n * canonical's (detail = the member's gh_issue_url); absorbing it would orphan that issue\n */\nexport interface GroupReportSkip {\n report_id: string;\n reason: 'not_found' | 'terminal' | 'grouped_elsewhere' | 'different_gh_issue';\n detail?: string;\n}\n\nexport interface GroupReportsResponse {\n canonical_id: string;\n grouped: number;\n skipped: GroupReportSkip[];\n}\n\n// =============================================================================\n// ADMIN — ungroup (detach a grouped member, inverse of group)\n// =============================================================================\n\n/**\n * Response for POST /api/admin/reports/:id/ungroup. The detached member is\n * returned to `pending` with its `group_id` cleared. Note: grouping cleared the\n * member's `gh_issue_url` (the canonical owns the issue), so detach cannot\n * restore it — the member re-enters triage as if freshly filed.\n */\nexport interface UngroupReportResponse {\n report: AdminReportSummary;\n}\n\n// =============================================================================\n// ADMIN — hold (defer a decision one triage cycle)\n//\n// Records \"I looked at this `pending` row and chose to wait one more cycle\" without\n// transitioning it: bumps `hold_count` + `last_held_at` (the explicit cycle counter) and\n// appends a triage-internal note (the rationale) to the message thread. Silent for ALL\n// sources — never emails, even a `cli` row — and the note is internal (reporter never sees\n// it). The reason is required: a hold with no recorded rationale defeats the purpose.\n// =============================================================================\n\nexport const holdReportBody = z.object({\n reason: z.string().min(1).max(1000),\n});\nexport type HoldReportBody = z.infer<typeof holdReportBody>;\n\nexport interface HoldReportResponse {\n report: AdminReportSummary;\n}\n\n// =============================================================================\n// REPORT TRANSITION STATE MACHINE — validity matrix (single source of truth)\n// =============================================================================\n\nexport type ReportTransitionTarget =\n | 'escalated'\n | 'shipped'\n | 'contested'\n | 'addressed'\n | 'dismissed';\n\n// Statuses from which a given target is a hard reject (operator error). Excludes\n// idempotent no-ops (target already reached, or escalate-from-addressed), which\n// `transitionReport` short-circuits to a no-op rather than rejecting. Mirrors the\n// branch guards in `PlatformDO.transitionReport` — kept here as the one place\n// both the route (to return a clean 4xx) and the DO (as a backstop) agree on.\n//\n// Allowed (non-reject, non-no-op) sources per target, for the agent-interactive loop:\n// escalated ← pending (first triage) · contested (triage re-escalates); addressed is an\n// idempotent no-op (not a real re-escalation)\n// shipped ← escalated (fixer marks the fix shipped)\n// contested ← shipped (reporter rejects the fix) · dismissed (reporter disputes the dismissal)\n// addressed ← escalated (non-cli auto-close) · shipped (reporter accepts) · contested (triage agrees)\n// dismissed ← pending (untriaged) · escalated (false-positive) · contested (dispute rejected)\nconst REPORT_TRANSITION_REJECT: Record<ReportTransitionTarget, ReadonlySet<ReportStatus>> = {\n escalated: new Set<ReportStatus>(['grouped', 'shipped', 'dismissed']),\n shipped: new Set<ReportStatus>(['pending', 'grouped', 'contested', 'addressed', 'dismissed']),\n contested: new Set<ReportStatus>(['pending', 'grouped', 'escalated', 'addressed']),\n addressed: new Set<ReportStatus>(['pending', 'grouped', 'dismissed']),\n dismissed: new Set<ReportStatus>(['grouped', 'shipped', 'addressed']),\n};\n\n/**\n * Returns an operator-facing rejection message if transitioning a report in\n * `status` to `target` is invalid, or `null` if it is allowed (including\n * idempotent no-ops). Pure — no I/O. The route throws ConflictError(409) on a\n * non-null result so an invalid transition surfaces as a clean 4xx instead of a\n * 500 (a plain Error thrown inside the DO loses its AppError brand across RPC).\n */\nexport function getReportTransitionRejection(\n report: { status: ReportStatus; group_id?: string | null },\n target: ReportTransitionTarget,\n): string | null {\n if (!REPORT_TRANSITION_REJECT[target].has(report.status)) return null;\n if (report.status === 'grouped') {\n const ref = report.group_id ? ` under ${report.group_id}` : '';\n return (\n `Report is grouped${ref} and cannot be ${target} directly. ` +\n `Detach it first (\\`wayai admin report ungroup <id>\\`), or transition the ` +\n `canonical so the outcome cascades to its members.`\n );\n }\n return `Report cannot be ${target} from status '${report.status}'.`;\n}\n\n// =============================================================================\n// REPORT EDIT — non-terminal-state gate (single source of truth)\n// =============================================================================\n\nexport type ReportEditRole = 'reporter' | 'admin';\n\n// Statuses from which a content edit is allowed, by role. A reporter may only\n// fix their report before triage (`pending`); once it has been escalated into a\n// GitHub issue, only a platform admin may refine it (`escalated`). `grouped`\n// (duplicate, subsumed by a canonical) and the terminal states are frozen for\n// everyone. The DO uses the `admin` set as its data-integrity backstop — the\n// per-role narrowing is the route's authorization concern.\nconst REPORT_EDITABLE_STATUSES: Record<ReportEditRole, ReadonlySet<ReportStatus>> = {\n reporter: new Set<ReportStatus>(['pending']),\n admin: new Set<ReportStatus>(['pending', 'escalated']),\n};\n\n/**\n * Returns an operator-facing rejection message if editing a report in `status`\n * is not allowed for `role`, or `null` if the edit is permitted. Pure — no I/O.\n * Both edit routes throw ConflictError(409) on a non-null result; the DO's\n * `editReportContent` calls it with role `'admin'` (most permissive) as a\n * backstop so a terminal/grouped row can never be mutated at the data layer.\n */\nexport function getReportEditRejection(\n report: { status: ReportStatus; group_id?: string | null },\n role: ReportEditRole,\n): string | null {\n if (REPORT_EDITABLE_STATUSES[role].has(report.status)) return null;\n if (report.status === 'grouped') {\n const ref = report.group_id ? ` under ${report.group_id}` : '';\n return (\n `Report is grouped${ref} and cannot be edited directly. ` +\n `Detach it first (\\`wayai admin report ungroup <id>\\`) or edit the canonical.`\n );\n }\n if (role === 'reporter' && report.status === 'escalated') {\n return (\n `Report has been escalated to a GitHub issue and can no longer be edited ` +\n `by the reporter; contact a platform admin to refine it.`\n );\n }\n return `Report cannot be edited from status '${report.status}'.`;\n}\n\n// =============================================================================\n// REPORT HOLD — defer-one-cycle gate (single source of truth)\n// =============================================================================\n\n// A hold only makes sense before the first triage decision: it defers escalate/dismiss by a\n// cycle. Once a row has moved past `pending` (grouped under a canonical, escalated into an\n// issue, in the agent-interactive loop, or terminal) there is no \"wait one cycle\" decision left\n// to defer — re-adjudicate it through the proper transition instead.\nconst REPORT_HOLDABLE_STATUSES: ReadonlySet<ReportStatus> = new Set<ReportStatus>(['pending']);\n\n/**\n * Returns an operator-facing rejection message if a `pending`-only hold is not allowed for a\n * report in `status`, or `null` if the hold is permitted. Pure — no I/O. The route throws\n * ConflictError(409) on a non-null result; the DO's `holdReport` calls it as a data-integrity\n * backstop so a non-pending row can never accrue a phantom hold.\n */\nexport function getReportHoldRejection(report: { status: ReportStatus; group_id?: string | null }): string | null {\n if (REPORT_HOLDABLE_STATUSES.has(report.status)) return null;\n if (report.status === 'grouped') {\n const ref = report.group_id ? ` under ${report.group_id}` : '';\n return (\n `Report is grouped${ref} and cannot be held — it is a duplicate subsumed by its canonical. ` +\n `Hold (or transition) the canonical instead.`\n );\n }\n return `Report cannot be held from status '${report.status}' — hold only defers a 'pending' row by a cycle.`;\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// ClickHouse readiness probe\n// ---------------------------------------------------------------------------\n\n/**\n * Polled by the frontend cold-start banner while it believes CH is cold.\n * `ready: true` means a fresh `SELECT 1` succeeded (or was cached via KV for\n * 60s); `ready: false` means the probe aborted or errored. Once the banner\n * sees `ready: true` it dispatches a `clickhouse:warm` event so data\n * consumers refetch.\n */\nexport const clickhouseReadyResponse = z.object({\n ready: z.boolean(),\n});\n\nexport type ClickHouseReadyResponse = z.infer<typeof clickhouseReadyResponse>;\n","import { z } from 'zod';\nimport type {\n ConversationItemResponse,\n HubItemResponse,\n MessageItemResponse,\n AvailableTaskHub,\n} from './chat';\nimport type { NavigationCounts } from './live-updates';\nimport type { UserDataResponse } from './users';\nimport type { HubAlert } from './hub-alerts';\nimport type { PlatformNotice } from './notices';\n\n// ---------------------------------------------------------------------------\n// GET /users/me/bootstrap — query\n// ---------------------------------------------------------------------------\n\n/**\n * Bootstrap query — optional active URL hints resolved by the RSC.\n *\n * Route-level RSC parses the current URL (e.g. /chat/[hubId]/[conversationId])\n * and passes hints to the backend so the snapshot can pre-load the active\n * conversation's first-page messages.\n */\nexport const bootstrapQuery = z.object({\n active_hub_id: z.string().uuid().optional(),\n active_conversation_id: z.string().uuid().optional(),\n active_nav: z.enum(['chat', 'task', 'support']).optional(),\n});\n\nexport type BootstrapQuery = z.infer<typeof bootstrapQuery>;\n\n// ---------------------------------------------------------------------------\n// WebSocket — request_snapshot_chunk (cursor-paged follow-up)\n// ---------------------------------------------------------------------------\n\nexport const requestSnapshotChunkMessage = z.object({\n type: z.literal('request_snapshot_chunk'),\n cursor: z.string(),\n});\n\nexport type RequestSnapshotChunkMessage = z.infer<typeof requestSnapshotChunkMessage>;\n\n// ---------------------------------------------------------------------------\n// Response shape — shared between HTTP (/bootstrap) and WS (session_snapshot)\n// ---------------------------------------------------------------------------\n\n/**\n * Per-nav conversation slice. Arrays so the RSC-serialized payload crosses\n * the Next.js boundary without Map serialization issues; client hydrator\n * feeds these into Zustand Map setters.\n */\nexport interface SessionSnapshotConversations {\n chat: ConversationItemResponse[];\n task: ConversationItemResponse[];\n support: ConversationItemResponse[];\n}\n\n/**\n * Active conversation pre-loaded by the RSC. Present only when the URL\n * resolved to a specific conversation the user has access to.\n */\nexport interface SessionSnapshotActiveConversation {\n conversation: ConversationItemResponse;\n messages: MessageItemResponse[];\n}\n\n/**\n * Per-user session snapshot. Built once in\n * `workers/backend/src/live-updates/session-snapshot.ts` and consumed by both:\n * - HTTP: `GET /api/users/me/bootstrap` (RSC first paint)\n * - WS: `LiveUpdateSession.getSessionSnapshot()` RPC (on auth_ok)\n */\nexport interface SessionSnapshot {\n user: UserDataResponse;\n hubs: HubItemResponse[];\n available_task_hubs: AvailableTaskHub[];\n conversations: SessionSnapshotConversations;\n active_conversation: SessionSnapshotActiveConversation | null;\n nav_counts: NavigationCounts;\n /**\n * Maps hub_id → the viewer's hub-scoped user_id (PK of HubDO's local `user`\n * table) for each hub where the viewer is an end user. Optional: a Worker\n * that predates this field omits it. Hubs with no resolvable\n * `hub_user.user_id` are absent from the map.\n */\n hub_user_ids_by_hub?: Record<string, string>;\n /**\n * Hub ids where the viewer has team/admin (support) access — i.e. the\n * `teamHubIds` set the builder uses for the support scope. Drives the live\n * update path's per-recipient `source_navs` inference (a recipient adds\n * `'support'` membership for a conversation whose hub is in this set).\n * Optional: a Worker that predates this field omits it.\n */\n support_hub_ids?: string[];\n /**\n * Active Status & Notices hub-health alerts across the hubs the viewer admins\n * (hub-local + org-derived union, body-free, each stamped with `hub_id`). Seeds the\n * app-shell banner + the cross-hub aggregate without a separate fetch — \"always\n * live\". Optional: a Worker that predates this field omits it.\n *\n * NOTE: a shared org credential backing M connections in one hub yields M entries\n * with the SAME `alert_id` (distinct `connection_id`) — the fan-out that surfaces the\n * one org alert against each linking connection. Consumers MUST key by the composite\n * `${alert_id}:${connection_id}` (not `alert_id` alone), as the Status tab does.\n */\n active_alerts?: HubAlert[];\n /**\n * Active platform broadcasts (Status & Notices feed 2) visible to this viewer —\n * `global`-scoped, within their display window, minus the ones they've acknowledged.\n * The same set `GET /api/notices` returns; seeds the notice banner + the account\n * aggregate without a separate fetch (\"always live\"). Optional: a Worker that\n * predates this field omits it. Consumers key by `notice_id`.\n */\n active_notices?: PlatformNotice[];\n /**\n * Serialized size ceiling guard — when the full payload exceeds the\n * snapshot size budget, the builder paginates via cursor. `null` = done.\n */\n cursor: string | null;\n}\n\nexport interface BootstrapResponse {\n success: true;\n data: SessionSnapshot;\n}\n\n// ---------------------------------------------------------------------------\n// WebSocket — session_snapshot message (emitted after auth_ok)\n// ---------------------------------------------------------------------------\n\nexport interface SessionSnapshotMessage {\n type: 'session_snapshot';\n payload: SessionSnapshot;\n}\n","import { z } from 'zod';\nimport { idParamSchema } from './common';\n\nconst MAX_NAME_LENGTH = 100;\nconst MAX_VALUE_LENGTH = 32 * 1024; // 32 Ki UTF-16 code units\nconst MAX_TAGS = 20;\nconst MAX_TAG_LENGTH = 50;\nconst MAX_SCOPE_HUBS = 100;\nconst MAX_SCOPE_TAGS = 50;\n\nexport const vaultSecretScopeSchema = z.object({\n hubs: z.array(z.string().min(1)).max(MAX_SCOPE_HUBS).optional(),\n tags: z.array(z.string().min(1).max(MAX_TAG_LENGTH)).max(MAX_SCOPE_TAGS).optional(),\n}).strict();\n\nexport const vaultCreateBody = z.object({\n name: z.string().trim().min(1, 'name is required').max(MAX_NAME_LENGTH, `name must be ${MAX_NAME_LENGTH} characters or fewer`),\n value: z.string().min(1, 'value is required').max(MAX_VALUE_LENGTH, `value must be ${MAX_VALUE_LENGTH} characters or fewer`),\n tags: z.array(z.string().min(1).max(MAX_TAG_LENGTH, `Tag must be ${MAX_TAG_LENGTH} characters or fewer`)).max(MAX_TAGS, `Maximum ${MAX_TAGS} tags allowed`).optional().default([]),\n scope: vaultSecretScopeSchema.optional().default({}),\n}).strict();\n\nexport const vaultUpdateBody = z.object({\n name: z.string().trim().min(1).max(MAX_NAME_LENGTH).optional(),\n value: z.string().min(1).max(MAX_VALUE_LENGTH).optional(),\n tags: z.array(z.string().min(1).max(MAX_TAG_LENGTH)).max(MAX_TAGS).optional(),\n scope: vaultSecretScopeSchema.optional(),\n}).strict();\n\nexport const vaultIdParam = idParamSchema;\n\nexport type VaultCreateBody = z.infer<typeof vaultCreateBody>;\nexport type VaultUpdateBody = z.infer<typeof vaultUpdateBody>;\nexport type VaultIdParam = z.infer<typeof vaultIdParam>;\n\nexport const VAULT_LIMITS = {\n MAX_NAME_LENGTH,\n MAX_VALUE_LENGTH,\n MAX_TAGS,\n MAX_TAG_LENGTH,\n MAX_SCOPE_HUBS,\n MAX_SCOPE_TAGS,\n} as const;\n","import { z } from 'zod';\nimport { PERMISSIONS } from '../auth/permissions';\nimport { idParamSchema, uuidSchema } from './common';\n\nconst MAX_NAME_LENGTH = 100;\nconst MAX_HUBS_PER_GRANT = 50;\nconst MAX_HUB_TAGS_PER_GRANT = 20;\nconst MAX_GRANTS = 20;\n\nconst permissionEnum = z.enum(PERMISSIONS).refine(\n (p) => p !== 'platform:admin',\n { message: 'platform:admin cannot be delegated via token creation' },\n);\n\nconst grantScopeSchema = z.object({\n // Required: every token grant must declare its org tenancy. The handler\n // also strict-checks this as defense-in-depth, but failing at the Zod\n // boundary keeps the generated client type honest (org_id: string).\n org_id: z.string().min(1),\n hubs: z.array(z.string().min(1)).min(1, 'Each grant must have scope.hubs as a non-empty array').max(MAX_HUBS_PER_GRANT),\n hub_tags: z.array(z.string().min(1)).min(1, 'scope.hub_tags must be a non-empty array if provided').max(MAX_HUB_TAGS_PER_GRANT).optional(),\n environments: z.array(z.enum(['production', 'preview'])).min(1, 'scope.environments must be a non-empty array if provided').optional(),\n}).strict();\n\nconst grantSchema = z.object({\n scope: grantScopeSchema,\n permissions: z.array(permissionEnum).min(1, 'Each grant must have permissions as a non-empty array'),\n}).strict();\n\nexport const createTokenBody = z.object({\n name: z.string().trim().min(1, 'name is required').max(MAX_NAME_LENGTH, `name must be ${MAX_NAME_LENGTH} characters or fewer`),\n grants: z.array(grantSchema).min(1, 'grants must be a non-empty array').max(MAX_GRANTS),\n expires_at: z.string().datetime({ message: 'expires_at must be a valid ISO 8601 date' }).refine(\n (s) => new Date(s).getTime() > Date.now(),\n { message: 'expires_at must be in the future' },\n ).optional(),\n});\n\nexport const tokenIdParam = idParamSchema;\n\n// Governance route param. NOT idParamSchema / setup's orgIdParam (both key\n// `id`); the route segment is `:orgId`, so the param bag must carry `orgId`.\nexport const tokenOrgIdParam = z.object({ orgId: uuidSchema });\n\n// --- Response contracts ---------------------------------------------------\n// Stored/returned grants always carry a concrete scope.org_id (the create\n// handler strictly requires it before persisting).\nconst tokenGrantScopeSchema = z.object({\n org_id: z.string().min(1),\n hubs: z.array(z.string().min(1)).min(1),\n hub_tags: z.array(z.string().min(1)).min(1).optional(),\n environments: z.array(z.enum(['production', 'preview'])).min(1).optional(),\n});\n\nexport const tokenGrantSchema = z.object({\n scope: tokenGrantScopeSchema,\n permissions: z.array(z.enum(PERMISSIONS)).min(1),\n});\n\nexport const tokenMetadataSchema = z.object({\n token_id: z.string(),\n name: z.string(),\n token_prefix: z.string(),\n grants: z.array(tokenGrantSchema),\n created_at: z.string(),\n expires_at: z.string().optional(),\n last_used_at: z.string().optional(),\n});\n\nexport const listTokensResponse = z.object({\n data: z.array(tokenMetadataSchema),\n});\n\nexport const createTokenResponse = z.object({\n data: z.object({\n token: z.string(),\n token_id: z.string(),\n name: z.string(),\n expires_at: z.string().optional(),\n }),\n});\n\nexport const orgTokenSummarySchema = z.object({\n token_id: z.string(),\n name: z.string(),\n token_prefix: z.string(),\n owner_user_id: z.string(),\n created_at: z.string(),\n expires_at: z.string().optional(),\n last_used_at: z.string().optional(),\n grants_for_org: z.array(tokenGrantSchema),\n});\n\nexport const listOrgTokensResponse = z.object({\n data: z.array(orgTokenSummarySchema),\n});\n\nexport type CreateTokenBody = z.infer<typeof createTokenBody>;\nexport type TokenIdParam = z.infer<typeof tokenIdParam>;\nexport type TokenOrgIdParam = z.infer<typeof tokenOrgIdParam>;\nexport type TokenGrant = z.infer<typeof tokenGrantSchema>;\nexport type TokenMetadata = z.infer<typeof tokenMetadataSchema>;\nexport type OrgTokenSummary = z.infer<typeof orgTokenSummarySchema>;\n\nexport const TOKEN_LIMITS = {\n MAX_NAME_LENGTH,\n MAX_HUBS_PER_GRANT,\n MAX_HUB_TAGS_PER_GRANT,\n MAX_GRANTS,\n} as const;\n","/**\n * WayAI permission types and auth context definitions.\n *\n * Permissions follow the pattern `resource:action`.\n * Grants use scope-based matching with OR semantics for hub_tags.\n *\n * User types and org requirements:\n * - Platform Admin: needs org, has `platform:admin` permission\n * - Org Owner/Admin: needs org, org-scoped grants with `org:admin`\n * - Hub Admin: org-scoped, has `hub:admin` on specific hubs\n * - Hub Team User: NO org needed, hub-scoped grants only\n * - Hub End User: NO org needed, hub-scoped grants only\n */\n\nexport const PERMISSIONS = [\n 'hub:read',\n 'hub:write',\n 'hub:admin',\n 'conversation:read',\n 'conversation:write',\n 'analytics:read',\n 'billing:read',\n 'billing:write',\n 'org:read',\n 'org:write',\n 'org:admin',\n 'platform:admin',\n '*',\n] as const;\n\nexport type Permission = (typeof PERMISSIONS)[number];\n\n/** All user-level permissions — excludes `'*'` (superuser) and `'platform:admin'`. */\nexport const USER_PERMISSIONS: Permission[] = [\n 'hub:read',\n 'hub:write',\n 'hub:admin',\n 'conversation:read',\n 'conversation:write',\n 'analytics:read',\n 'billing:read',\n 'billing:write',\n 'org:read',\n 'org:write',\n 'org:admin',\n];\n\n/** Hub-admin-only permissions — for users who admin a hub but are NOT org members. */\nexport const HUB_ADMIN_PERMISSIONS: Permission[] = [\n 'hub:read',\n 'hub:write',\n 'hub:admin',\n 'conversation:read',\n 'conversation:write',\n 'analytics:read',\n];\n\nexport interface Grant {\n scope: {\n /** Organization this grant applies to. undefined = unscoped (hub-only users). */\n org_id?: string;\n /** Hub IDs this grant applies to. ['*'] = all hubs in the org. */\n hubs: string[];\n /**\n * Hub tags for tag-based scoping (replaces project grouping).\n * OR matching: user has access if hub has ANY of these tags.\n * To require multiple tags, use separate grants.\n */\n hub_tags?: string[];\n /** Environment filter. undefined = all environments. */\n environments?: ('production' | 'preview')[];\n };\n permissions: Permission[];\n}\n\nexport interface AuthContext {\n /** Platform org ID. Optional — hub-only users (end users, team users) don't have one. */\n org_id?: string;\n /** WorkOS user ID. Present for human sessions, absent for service tokens. */\n user_id?: string;\n /** User email. Present for human sessions (set during auth key generation). */\n email?: string;\n /** WorkOS session id (sid). Present for sessions minted from an authenticated browser/CLI login. */\n session_id?: string;\n /** Scoped API token id. Present only when caller authenticated with a `way_` token. */\n token_id?: string;\n /** Parent token expiry (ISO 8601). Present only when the `way_` parent has a finite lifetime; used to cap child expiries. */\n token_expires_at?: string;\n grants: Grant[];\n}\n\n/**\n * Parse the comma-separated PLATFORM_ADMIN_EMAILS env var into a deduplicated\n * lowercase list. Shared by `checkPlatformAdminEmail` and live-update\n * recipient resolution so the membership boundary can't drift between them.\n */\nexport function parsePlatformAdminEmails(raw: string | undefined): string[] {\n if (!raw) return [];\n return Array.from(\n new Set(raw.split(',').map((e) => e.trim().toLowerCase()).filter(Boolean)),\n );\n}\n\n/**\n * Check if an email matches PLATFORM_ADMIN_EMAILS env var.\n * Case-insensitive, filters empty entries from trailing commas.\n * Returns false if either argument is falsy.\n */\nexport function checkPlatformAdminEmail(email: string | undefined, platformAdminEmails: string | undefined): boolean {\n if (!email || !platformAdminEmails) return false;\n return parsePlatformAdminEmails(platformAdminEmails).includes(email.toLowerCase());\n}\n","import { z } from 'zod';\n\n// =============================================================================\n// INVITE PREVIEW — GET /api/invites/preview\n// Public (unauthenticated) endpoint. Returns enough display info for the signup\n// page to render personalized copy. Does NOT echo the invitee's email back —\n// the user just opened their email at that address, no need to reflect it,\n// and not echoing reduces leakage if the URL ends up in browser history,\n// referrer logs, or client-side telemetry.\n// =============================================================================\n\nexport const invitePreviewQuery = z.object({\n token: z.string().min(1).max(2048),\n});\n\nexport const invitePreviewResponse = z.object({\n inviter_name: z.string(),\n entity_id: z.string().uuid(),\n entity_name: z.string(),\n entity_type: z.enum(['org', 'hub']),\n role: z.enum(['org_admin', 'admin', 'team_user', 'user']),\n expires_at: z.string().datetime(),\n});\n\nexport type InvitePreviewResponse = z.infer<typeof invitePreviewResponse>;\n","import { z } from 'zod';\n\n// =============================================================================\n// Discord Linked Roles — tier/cycle/admin metadata pushed to Discord\n// =============================================================================\n\nexport const discordTier = z.enum(['free', 'pro', 'pro_plus']);\nexport type DiscordTier = z.infer<typeof discordTier>;\n\nexport const discordBillingCycle = z.enum(['monthly', 'annual']);\nexport type DiscordBillingCycle = z.infer<typeof discordBillingCycle>;\n\nexport const discordMetadata = z.object({\n tier: discordTier,\n billing_cycle: discordBillingCycle,\n is_admin: z.boolean(),\n});\nexport type DiscordMetadata = z.infer<typeof discordMetadata>;\n\n// =============================================================================\n// GET /api/discord/oauth/start\n// =============================================================================\n\nexport const discordOAuthStartResponse = z.object({\n url: z.string().url(),\n});\nexport type DiscordOAuthStartResponse = z.infer<typeof discordOAuthStartResponse>;\n\n// =============================================================================\n// POST /api/discord/oauth/finalize\n// =============================================================================\n\nexport const discordOAuthFinalizeBody = z.object({\n code: z.string().min(1, 'code is required'),\n state: z.string().min(1, 'state is required'),\n});\nexport type DiscordOAuthFinalizeBody = z.infer<typeof discordOAuthFinalizeBody>;\n\n/**\n * Finalize returns 200 in two shapes:\n * - `{ ok: true, … }` — link stored + metadata pushed to Discord successfully\n * - `{ ok: false, push_error, metadata }` — link stored, but Discord rejected\n * the metadata push. The link persists; the next admin-grant change or\n * Stripe webhook will retry. Frontend renders an error variant.\n *\n * 4xx responses indicate the link was NOT stored (bad_state, user_mismatch,\n * etc.) and use the standard ApiErrorResponse shape.\n */\nexport const discordOAuthFinalizeResponse = z.discriminatedUnion('ok', [\n z.object({\n ok: z.literal(true),\n discord_user_id: z.string(),\n metadata: discordMetadata,\n }),\n z.object({\n ok: z.literal(false),\n push_error: z.literal('discord_unreachable'),\n metadata: discordMetadata,\n }),\n]);\nexport type DiscordOAuthFinalizeResponse = z.infer<typeof discordOAuthFinalizeResponse>;\n\n// =============================================================================\n// POST /api/discord/disconnect\n// =============================================================================\n\nexport const discordDisconnectResponse = z.object({\n ok: z.literal(true),\n});\nexport type DiscordDisconnectResponse = z.infer<typeof discordDisconnectResponse>;\n","import { z } from 'zod';\nimport { slugSchema } from './setup/slug';\n\n// ---------------------------------------------------------------------------\n// User Context Panel — admin-facing identity + state inspection/mutation.\n// ---------------------------------------------------------------------------\n\n// A JSON Schema describing a state's shape. Kept as `record(z.unknown())`\n// because the panel renders it as JSON (we don't constrain user-authored\n// schemas here).\nconst jsonSchemaSchema = z.record(z.unknown());\n\n// Identity is sourced from the `user` table (the conversation's end user).\n// hub_user-only fields (hub_user_id, enabled, hub_team_id, source) are present\n// only when an access-grant row exists (account-mode); optional otherwise.\nconst hubUserIdentity = z.object({\n user_id: z.string().nullable(),\n user_name: z.string().nullable(),\n user_email: z.string().nullable(),\n user_name_locked: z.boolean(),\n created_at: z.string(),\n updated_at: z.string().nullable(),\n hub_user_id: z.string().optional(),\n enabled: z.boolean().optional(),\n hub_team_id: z.string().nullable().optional(),\n source: z.enum(['grant', 'auto']).optional(),\n});\n\nconst stateValueEntry = z.object({\n state_slug: z.string(),\n state_name: z.string(),\n state_description: z.string().nullable().optional(),\n scope: z.enum(['user', 'conversation']),\n json_schema: jsonSchemaSchema,\n initial_value: z.unknown(),\n value: z.unknown(),\n is_reserved: z.boolean(),\n});\n\nexport const getHubUserContextResponse = z.object({\n user: hubUserIdentity,\n user_states: z.array(stateValueEntry),\n conversation_states: z.array(stateValueEntry),\n});\n\nexport type GetHubUserContextResponse = z.infer<typeof getHubUserContextResponse>;\nexport type HubUserIdentity = z.infer<typeof hubUserIdentity>;\nexport type StateValueEntry = z.infer<typeof stateValueEntry>;\n\nexport const updateHubUserBody = z.object({\n // Non-empty, non-null. `.nullable()` here would bypass `.min(1)` and let an\n // admin arm the lock on a null name — see hub-do.ts updateHubUser null-guard.\n user_name: z.string().min(1).max(120),\n});\n\nexport const updateHubUserResponse = z.object({\n user: hubUserIdentity,\n});\n\nexport type UpdateHubUserBody = z.infer<typeof updateHubUserBody>;\nexport type UpdateHubUserResponse = z.infer<typeof updateHubUserResponse>;\n\nexport const unlockHubUserNameResponse = z.object({\n user: hubUserIdentity,\n});\n\nexport type UnlockHubUserNameResponse = z.infer<typeof unlockHubUserNameResponse>;\n\nexport const stateResetParams = z.object({\n stateSlug: slugSchema,\n});\n\nexport const stateResetResponse = z.object({\n ok: z.literal(true),\n});\n\nexport type StateResetParams = z.infer<typeof stateResetParams>;\nexport type StateResetResponse = z.infer<typeof stateResetResponse>;\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Hub operational alerts (Status & Notices) — read surface.\n// GET /api/hubs/:hubId/alerts returns the hub's currently-active, tenant-actionable\n// connection/credential alerts. Never carries the provider error body (it can embed\n// a key fragment) — only provider + status_code + category + counts + timestamps.\n// ---------------------------------------------------------------------------\n\nexport const hubAlertsParam = z.object({\n hubId: z.string().uuid(),\n});\nexport type HubAlertsParam = z.infer<typeof hubAlertsParam>;\n\nexport const hubAlertSeverity = z.enum(['critical', 'warn', 'info']);\nexport type HubAlertSeverity = z.infer<typeof hubAlertSeverity>;\n\nexport const hubAlert = z.object({\n alert_id: z.string(),\n // The hub this alert belongs to — stamped at read time (the per-hub HubDO row\n // doesn't store it). Drives the banner/aggregate deep-link to the hub's Status tab.\n hub_id: z.string(),\n connection_id: z.string().nullable(),\n channel_id: z.string().nullable(),\n // Open string (not an enum): producers define categories as they're wired, and the\n // read surface must not reject a category that ships before this contract updates.\n category: z.string(),\n provider: z.string().nullable(),\n status_code: z.number().nullable(),\n severity: hubAlertSeverity,\n status: z.enum(['active', 'resolved']),\n count: z.number(),\n first_seen_at: z.string(),\n last_seen_at: z.string(),\n last_notified_at: z.string().nullable(),\n resolved_at: z.string().nullable(),\n // Set when this alert is rolled up at the shared org credential (one org_alert shown\n // against every hub linking it) — the fix lives at the org level, not the hub. Null\n // for hub-local alerts.\n org_credential_id: z.string().nullable(),\n});\nexport type HubAlert = z.infer<typeof hubAlert>;\n\nexport const hubAlertsListResponse = z.object({\n alerts: z.array(hubAlert),\n});\nexport type HubAlertsListResponse = z.infer<typeof hubAlertsListResponse>;\n","import { z } from 'zod';\n\n// =============================================================================\n// Platform notices (feed 2) — operator-authored broadcasts (\"Gemini degraded\",\n// \"Analytics delayed\"). Informational: the admin can't *act*, but needs to *know*\n// so they don't burn an hour assuming their setup broke. Authored by platform\n// admins; lives in PlatformDO `platform_notice`. Kept in sync with the DO schema\n// CHECK constraints.\n// =============================================================================\n\n// Severity — same vocabulary as hub alerts (anti banner-blindness): only\n// `critical` is a persistent banner; `warn`/`info` are quiet.\nexport const noticeSeveritySchema = z.enum(['critical', 'warn', 'info']);\nexport type NoticeSeverity = z.infer<typeof noticeSeveritySchema>;\n\nexport const noticeStatusSchema = z.enum(['active', 'resolved']);\nexport type NoticeStatus = z.infer<typeof noticeStatusSchema>;\n\n// Scope — who sees the broadcast. v1 authors `global` (everyone); `provider:<x>`\n// and `service:<x>` are accepted and stored opaquely now, resolved to recipients\n// at delivery time (a later slice). The regex is the security boundary: scope is\n// interpolated into recipient resolution, so it must be a constrained token.\nexport const NOTICE_SCOPE_REGEX = /^(global|provider:[a-z0-9_-]{1,40}|service:[a-z0-9_-]{1,40})$/;\nexport const noticeScopeSchema = z\n .string()\n .regex(NOTICE_SCOPE_REGEX, \"scope must be 'global', 'provider:<x>', or 'service:<x>'\");\n\n// `link` is rendered as an href in the banner — z.string().url() alone accepts\n// `javascript:`, so constrain to http(s) for a safe href.\nconst noticeLinkSchema = z\n .string()\n .url()\n .refine((u) => /^https?:\\/\\//i.test(u), { message: 'link must be an http(s) URL' });\n\n// The wire shape. Timestamps are ISO-8601 UTC strings (DO SQLite TEXT — same\n// representation end-to-end, per the timestamp convention).\nexport interface PlatformNotice {\n notice_id: string;\n severity: NoticeSeverity;\n scope: string;\n title: string;\n body: string | null;\n link: string | null;\n status: NoticeStatus;\n starts_at: string;\n ends_at: string | null;\n resolved_at: string | null;\n created_by: string | null;\n created_at: string;\n updated_at: string;\n}\n\n// =============================================================================\n// Admin authoring\n// =============================================================================\n\nexport const createNoticeBody = z.object({\n severity: noticeSeveritySchema.default('info'),\n scope: noticeScopeSchema.default('global'),\n title: z.string().trim().min(1).max(200),\n body: z.string().max(2000).optional(),\n link: noticeLinkSchema.optional(),\n starts_at: z.string().datetime().optional(),\n ends_at: z.string().datetime().optional(),\n});\nexport type CreateNoticeBody = z.infer<typeof createNoticeBody>;\n\n// Partial update. Nullable fields (`body`, `link`, `ends_at`) accept `null` to\n// clear; omitted keys are left unchanged.\nexport const updateNoticeBody = z\n .object({\n severity: noticeSeveritySchema.optional(),\n scope: noticeScopeSchema.optional(),\n title: z.string().trim().min(1).max(200).optional(),\n body: z.string().max(2000).nullable().optional(),\n link: noticeLinkSchema.nullable().optional(),\n starts_at: z.string().datetime().optional(),\n ends_at: z.string().datetime().nullable().optional(),\n })\n .refine((b) => Object.keys(b).length > 0, { message: 'at least one field must be provided' });\nexport type UpdateNoticeBody = z.infer<typeof updateNoticeBody>;\n\nexport const listNoticesQuery = z.object({\n status: noticeStatusSchema.optional(),\n limit: z.coerce.number().int().min(1).max(200).optional(),\n offset: z.coerce.number().int().min(0).optional(),\n});\n\nexport const noticeIdParamSchema = z.object({ id: z.string().min(1) });\n\nexport interface AdminNoticeListResponse {\n data: PlatformNotice[];\n total: number;\n}\n\nexport interface AdminNoticeResponse {\n data: PlatformNotice;\n}\n\n// =============================================================================\n// Consumer aggregate (any authenticated user)\n// =============================================================================\n\n// The current user's active broadcasts (within their display window, scoped to\n// them, minus the ones they've acknowledged). v1 surfaces `global`-scoped notices\n// to everyone; provider/service-scoped recipient resolution lands with delivery.\nexport interface NoticesAggregateResponse {\n notices: PlatformNotice[];\n}\n\nexport interface AckNoticeResponse {\n acked: true;\n}\n","// Canonical analytics filter / structured-query ops — re-exported from\n// @wayai/core. The CLI now bundles @wayai/core (tsup `noExternal`), so this is\n// a real runtime import rather than a hand-kept copy pinned by a drift-guard.\nexport {\n NUMERIC_FILTER_OPS,\n TEXT_FILTER_OPS,\n CATEGORICAL_FILTER_OPS,\n VARIABLE_FILTER_OPS,\n STRUCTURED_QUERY_OPS,\n STRUCTURED_QUERY_AGGREGATIONS,\n} from '@wayai/core/contracts';\n","/**\n * wayai analytics — show analytics summary and metrics for the current hub\n *\n * Usage:\n * wayai analytics # summary for last 7d\n * wayai analytics --period 30d # summary for last 30 days\n * wayai analytics --from 2026-01-01 --to 2026-01-31 # explicit date range\n * wayai analytics --metric tokens_total,first_response_time\n * wayai analytics --filter \"tokens_total gt 5000\" # repeat for AND'd filters\n * wayai analytics --filter \"user_sentiment is positive\"\n * wayai analytics --list-metrics # list available metrics\n * wayai analytics --json # raw JSON output\n *\n * wayai analytics query \\\n * --metric \"col=data.system.tokens_total,agg=avg,alias=avg_tokens\" \\\n * --metric \"col=data.system.tokens_total,agg=corr,corr_with=data.system.avg_agent_response_time,alias=tok_resp\" \\\n * --group-by data.meta.kanban_status \\\n * --filter \"data.system.tokens_total gt 0\" \\\n * --order-by avg_tokens:desc --limit 50 --from 2026-01-01 --to 2026-01-31\n *\n * `query` is a thin wrapper over POST /api/analytics/query — supports aggregations\n * (avg|sum|min|max|count|quantile|stddevPop|corr|uniq), group_by, order_by, raw\n * column filters (eq|neq|gt|gte|lt|lte|in|not_in|like) and correlation via corr_with.\n *\n * wayai analytics sql \"SELECT count() FROM conversation\"\n * wayai analytics sql \"SELECT data.meta.kanban_status, count() FROM conversation GROUP BY 1\" --json\n * wayai analytics sql --schema # column + variable-path catalog\n * wayai analytics sql \"...\" --limit 500\n *\n * `sql` is a thin wrapper over POST /api/analytics/sql — server enforces hub_id +\n * is_eval=false scoping (CTE shadow), single-SELECT only, function/keyword\n * denylist, 10k row cap. `--schema` calls GET /api/analytics/sql/schema.\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { requireRepoConfig } from '../lib/repo-config.js';\nimport { resolveActiveHubId } from '../lib/workspace.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { parsePeriod, parseDateArg, parsePositiveIntFlag } from '../lib/utils.js';\nimport { printQueryRows, printSqlSchema } from '../lib/sql-output.js';\nimport {\n NUMERIC_FILTER_OPS,\n TEXT_FILTER_OPS,\n CATEGORICAL_FILTER_OPS,\n VARIABLE_FILTER_OPS,\n STRUCTURED_QUERY_OPS,\n STRUCTURED_QUERY_AGGREGATIONS,\n} from '../lib/analytics-constants.js';\n\ntype VariableType = 'numeric' | 'categorical' | 'text';\ntype StructuredAggregation = (typeof STRUCTURED_QUERY_AGGREGATIONS)[number];\ntype StructuredOp = (typeof STRUCTURED_QUERY_OPS)[number];\n\ninterface AnalyticsVariable {\n variable_id: string;\n variable_name: string;\n variable_type: VariableType;\n}\n\nconst NUMERIC_OPS = new Set<string>(NUMERIC_FILTER_OPS);\nconst TEXT_OPS = new Set<string>(TEXT_FILTER_OPS);\nconst CATEGORICAL_OPS = new Set<string>(CATEGORICAL_FILTER_OPS);\nconst ALL_DATA_OPS = new Set<string>(VARIABLE_FILTER_OPS);\nconst STRUCTURED_OPS = new Set<string>(STRUCTURED_QUERY_OPS);\nconst STRUCTURED_AGGREGATIONS = new Set<string>(STRUCTURED_QUERY_AGGREGATIONS);\n\nexport async function analyticsCommand(args: string[]): Promise<void> {\n if (args[0] === 'query') {\n return analyticsQuerySubcommand(args.slice(1));\n }\n if (args[0] === 'sql') {\n return analyticsSqlSubcommand(args.slice(1));\n }\n return analyticsSummaryCommand(args);\n}\n\n// ---------------------------------------------------------------------------\n// Default summary command (POST /api/analytics/data)\n// ---------------------------------------------------------------------------\n\nasync function analyticsSummaryCommand(args: string[]): Promise<void> {\n const hubId = resolveActiveHubId(args);\n const { config, accessToken } = await requireAuth();\n requireRepoConfig();\n\n let period: string | undefined;\n let from: string | undefined;\n let to: string | undefined;\n let metricNames: string[] | undefined;\n const filterArgs: string[] = [];\n let listMetrics = false;\n let jsonOutput = false;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--period') {\n if (i + 1 >= args.length) { console.error('--period requires a value'); process.exit(1); }\n period = args[++i];\n } else if (arg === '--from') {\n if (i + 1 >= args.length) { console.error('--from requires a value'); process.exit(1); }\n from = args[++i];\n } else if (arg === '--to') {\n if (i + 1 >= args.length) { console.error('--to requires a value'); process.exit(1); }\n to = args[++i];\n } else if (arg === '--metric') {\n if (i + 1 >= args.length) { console.error('--metric requires a value'); process.exit(1); }\n metricNames = args[++i].split(',').map((s) => s.trim()).filter(Boolean);\n } else if (arg === '--filter') {\n if (i + 1 >= args.length) { console.error('--filter requires a value'); process.exit(1); }\n filterArgs.push(args[++i]);\n } else if (arg === '--list-metrics') {\n listMetrics = true;\n } else if (arg === '--json') {\n jsonOutput = true;\n }\n }\n\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n if (listMetrics) {\n const result = await client.getAnalyticsVariables(hubId);\n if (jsonOutput) {\n console.log(JSON.stringify(result.data, null, 2));\n return;\n }\n printVariablesByCategory(result.data);\n return;\n }\n\n if ((from && !to) || (!from && to)) {\n console.error('--from and --to must both be provided together.');\n process.exit(1);\n }\n\n let start: string;\n let end: string;\n let periodicity: string;\n\n try {\n if (from && to) {\n start = parseDateArg(from, 'from');\n end = parseDateArg(to, 'to');\n if (new Date(start).getTime() >= new Date(end).getTime()) {\n console.error('--from must be before --to.');\n process.exit(1);\n }\n const rangeMs = new Date(end).getTime() - new Date(start).getTime();\n const rangeDays = rangeMs / (1000 * 60 * 60 * 24);\n if (rangeDays > 365) periodicity = 'yearly';\n else if (rangeDays > 90) periodicity = 'monthly';\n else if (rangeDays > 14) periodicity = 'weekly';\n else periodicity = 'daily';\n } else {\n const parsed = parsePeriod(period || '7d');\n start = parsed.start;\n end = parsed.end;\n periodicity = parsed.periodicity;\n }\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n\n // Resolve --metric and --filter against the variable catalog (single fetch).\n let allVars: AnalyticsVariable[] | undefined;\n let variableNameMap: Map<string, string> | undefined;\n\n const needsCatalog = (metricNames && metricNames.length > 0) || filterArgs.length > 0;\n if (needsCatalog) {\n const varsResult = await client.getAnalyticsVariables(hubId);\n allVars = Object.values(varsResult.data.variablesByCategory).flat();\n variableNameMap = new Map(allVars.map((v) => [v.variable_id, v.variable_name]));\n }\n\n let selectedVariables: string[] = [];\n if (metricNames && metricNames.length > 0 && allVars) {\n const notFound: string[] = [];\n for (const name of metricNames) {\n const match = allVars.find((v) => v.variable_name === name);\n if (match) selectedVariables.push(match.variable_id);\n else notFound.push(name);\n }\n if (notFound.length > 0) {\n const available = allVars.map((v) => v.variable_name).sort();\n console.error(`Unknown metric(s): ${notFound.join(', ')}`);\n console.error(`\\nAvailable metrics:\\n ${available.join('\\n ')}`);\n process.exit(1);\n }\n }\n\n let parsedFilters: Array<{ variable_id: string; filter_type: string; filter_value: string | number }> | undefined;\n if (filterArgs.length > 0 && allVars) {\n parsedFilters = filterArgs.map((raw) => parseFilterByName(raw, allVars!));\n }\n\n const result = await client.getAnalyticsData({\n hub_id: hubId,\n selected_variables: selectedVariables,\n time_interval: { start, end },\n periodicity,\n trend_analysis: false,\n include_summary: true,\n ...(parsedFilters && { filters: parsedFilters }),\n });\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const label = from && to ? `${from} to ${to}` : `last ${period || '7d'}`;\n console.log(`Hub Analytics (${label})\\n`);\n\n if (result.summary) {\n const s = result.summary;\n console.log('Summary:');\n console.log(` Total conversations: ${s.total_conversations}`);\n console.log(` AI-only rate: ${(s.ai_only_rate * 100).toFixed(1)}%`);\n console.log(` Avg response time: ${formatMinutes(s.avg_response_time)}`);\n console.log(` AI response time: ${formatMinutes(s.assistant_response_time)}`);\n console.log(` Support response time: ${formatMinutes(s.support_response_time)}`);\n }\n\n if (result.analytics && result.analytics.length > 0) {\n console.log('\\nMetrics:');\n for (const item of result.analytics) {\n const name = variableNameMap?.get(item.variable_id) || item.variable;\n console.log(` ${name}:`);\n if (item.type === 'numeric' && item.metrics) {\n const m = item.metrics;\n const parts: string[] = [];\n parts.push(`Average: ${fmt(m.average)}`);\n if (m.median !== undefined) parts.push(`Median: ${fmt(m.median)}`);\n parts.push(`Min: ${fmt(m.minimum)}`);\n parts.push(`Max: ${fmt(m.maximum)}`);\n if (m.count !== undefined) parts.push(`Count: ${m.count}`);\n console.log(` ${parts.join(' ')}`);\n } else if (item.type === 'categorical' && item.distribution) {\n for (const [cat, count] of Object.entries(item.distribution)) {\n console.log(` ${cat}: ${count}`);\n }\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// `wayai analytics query` — POST /api/analytics/query (structured)\n// ---------------------------------------------------------------------------\n\nasync function analyticsQuerySubcommand(args: string[]): Promise<void> {\n const hubId = resolveActiveHubId(args);\n const { config, accessToken } = await requireAuth();\n requireRepoConfig();\n\n const metricArgs: string[] = [];\n const orderByArgs: string[] = [];\n const filterArgs: string[] = [];\n let groupByRaw: string | undefined;\n let from: string | undefined;\n let to: string | undefined;\n let limit: number | undefined;\n let jsonOutput = false;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--metric') {\n if (i + 1 >= args.length) { console.error('--metric requires a value'); process.exit(1); }\n metricArgs.push(args[++i]);\n } else if (arg === '--group-by') {\n if (i + 1 >= args.length) { console.error('--group-by requires a value'); process.exit(1); }\n groupByRaw = args[++i];\n } else if (arg === '--order-by') {\n if (i + 1 >= args.length) { console.error('--order-by requires a value'); process.exit(1); }\n orderByArgs.push(args[++i]);\n } else if (arg === '--filter') {\n if (i + 1 >= args.length) { console.error('--filter requires a value'); process.exit(1); }\n filterArgs.push(args[++i]);\n } else if (arg === '--from') {\n if (i + 1 >= args.length) { console.error('--from requires a value'); process.exit(1); }\n from = args[++i];\n } else if (arg === '--to') {\n if (i + 1 >= args.length) { console.error('--to requires a value'); process.exit(1); }\n to = args[++i];\n } else if (arg === '--limit') {\n limit = parsePositiveIntFlag('--limit', args[++i]);\n } else if (arg === '--json') {\n jsonOutput = true;\n } else {\n console.error(`Unknown flag for \\`analytics query\\`: ${arg}`);\n process.exit(1);\n }\n }\n\n if (metricArgs.length === 0) {\n console.error('At least one --metric is required for `analytics query`.');\n console.error('Example: --metric \"col=data.system.tokens_total,agg=avg,alias=avg_tokens\"');\n process.exit(1);\n }\n\n if ((from && !to) || (!from && to)) {\n console.error('--from and --to must both be provided together.');\n process.exit(1);\n }\n\n let timeRange: { start: string; end: string } | undefined;\n if (from && to) {\n try {\n const start = parseDateArg(from, 'from');\n const end = parseDateArg(to, 'to');\n if (new Date(start).getTime() >= new Date(end).getTime()) {\n console.error('--from must be before --to.');\n process.exit(1);\n }\n timeRange = { start, end };\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n }\n\n const metrics = metricArgs.map(parseMetricSpec);\n const filters = filterArgs.map(parseStructuredFilter);\n const orderBy = orderByArgs.map(parseOrderBy);\n const groupBy = groupByRaw ? groupByRaw.split(',').map((s) => s.trim()).filter(Boolean) : undefined;\n\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n const result = await client.runAnalyticsQuery({\n hub_id: hubId,\n metrics,\n ...(groupBy && groupBy.length > 0 && { group_by: groupBy }),\n ...(orderBy.length > 0 && { order_by: orderBy }),\n ...(filters.length > 0 && { filters }),\n ...(timeRange && { time_range: timeRange }),\n ...(limit !== undefined && { limit }),\n });\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n printQueryRows(result.data);\n}\n\n// ---------------------------------------------------------------------------\n// `wayai analytics sql` — POST /api/analytics/sql (read-only, server-scoped)\n// ---------------------------------------------------------------------------\n\nasync function analyticsSqlSubcommand(args: string[]): Promise<void> {\n const hubId = resolveActiveHubId(args);\n const { config, accessToken } = await requireAuth();\n requireRepoConfig();\n\n let sql: string | undefined;\n let limit: number | undefined;\n let jsonOutput = false;\n let schemaOnly = false;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--limit') {\n limit = parsePositiveIntFlag('--limit', args[++i]);\n } else if (arg === '--json') {\n jsonOutput = true;\n } else if (arg === '--schema') {\n schemaOnly = true;\n } else if (!arg.startsWith('--') && sql === undefined) {\n sql = arg;\n } else {\n console.error(`Unknown flag for \\`analytics sql\\`: ${arg}`);\n process.exit(1);\n }\n }\n\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n if (schemaOnly) {\n const schema = await client.getAnalyticsSqlSchema(hubId);\n if (jsonOutput) {\n console.log(JSON.stringify(schema.data, null, 2));\n return;\n }\n printSqlSchema(schema.data, 'Variable paths (data.system.* + data.variables.*):');\n return;\n }\n\n if (!sql) {\n console.error('Provide a SQL string. Example: wayai analytics sql \"SELECT count() FROM conversation\"');\n console.error('Or run: wayai analytics sql --schema to list available columns and paths.');\n process.exit(1);\n }\n\n const result = await client.runAnalyticsSql({\n hub_id: hubId,\n sql,\n ...(limit !== undefined && { limit }),\n });\n\n if (jsonOutput) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n printQueryRows(result.data);\n}\n\n// ---------------------------------------------------------------------------\n// Parsing helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Split a \"<lhs> <op> <value...>\" filter expression. Value may contain spaces\n * (e.g. \"feedback contains good service\"). Exits the process on malformed input.\n */\nfunction splitFilterExpr(raw: string, shape: string): { lhs: string; op: string; value: string } {\n const parts = raw.trim().split(/\\s+/);\n if (parts.length < 3) {\n console.error(`Invalid --filter \"${raw}\". Expected: \"${shape}\".`);\n process.exit(1);\n }\n const [lhs, op, ...rest] = parts;\n return { lhs, op, value: rest.join(' ') };\n}\n\n/**\n * Parse `--filter \"name op value\"` for the variable-aware /data endpoint.\n * `name` resolves to a variable_id; `op` is validated against the variable's type.\n */\nfunction parseFilterByName(raw: string, allVars: AnalyticsVariable[]): {\n variable_id: string; filter_type: string; filter_value: string | number;\n} {\n const { lhs: name, op, value } = splitFilterExpr(raw, '<name> <op> <value>');\n\n const variable = allVars.find((v) => v.variable_name === name);\n if (!variable) {\n const available = allVars.map((v) => v.variable_name).sort();\n console.error(`Unknown variable in --filter: ${name}`);\n console.error(`\\nAvailable variables:\\n ${available.join('\\n ')}`);\n process.exit(1);\n }\n\n if (!ALL_DATA_OPS.has(op)) {\n console.error(`Invalid filter operator: ${op}`);\n console.error('Numeric ops: eq, neq, gt, gte, lt, lte');\n console.error('Text ops: equals, not_equals, contains, not_contains, starts_with, ends_with');\n console.error('Categorical ops: is, is_not, in, not_in');\n process.exit(1);\n }\n\n const expectedSet =\n variable.variable_type === 'numeric' ? NUMERIC_OPS :\n variable.variable_type === 'text' ? TEXT_OPS :\n CATEGORICAL_OPS;\n if (!expectedSet.has(op)) {\n console.error(`Operator \"${op}\" is not valid for ${variable.variable_type} variable \"${name}\".`);\n console.error(`Valid operators: ${[...expectedSet].join(', ')}`);\n process.exit(1);\n }\n\n let filterValue: string | number;\n if (variable.variable_type === 'numeric') {\n const n = Number(value);\n if (!Number.isFinite(n)) {\n console.error(`Numeric filter value must be a number, got: \"${value}\"`);\n process.exit(1);\n }\n filterValue = n;\n } else {\n filterValue = value;\n }\n\n return { variable_id: variable.variable_id, filter_type: op, filter_value: filterValue };\n}\n\n/**\n * Parse `--metric \"col=...,agg=...[,alias=...][,corr_with=...][,level=...]\"`.\n * Order doesn't matter; unknown keys are rejected so typos surface immediately.\n */\nfunction parseMetricSpec(raw: string): {\n column: string; aggregation: StructuredAggregation; alias?: string; corr_with?: string; quantile_level?: number;\n} {\n const fields = raw.split(',').map((s) => s.trim()).filter(Boolean);\n const map = new Map<string, string>();\n for (const field of fields) {\n const eq = field.indexOf('=');\n if (eq < 0) {\n console.error(`Invalid --metric segment \"${field}\". Expected key=value pairs.`);\n process.exit(1);\n }\n const key = field.slice(0, eq).trim();\n const val = field.slice(eq + 1).trim();\n if (map.has(key)) {\n console.error(`Duplicate key \"${key}\" in --metric \"${raw}\".`);\n process.exit(1);\n }\n map.set(key, val);\n }\n\n const knownKeys = new Set(['col', 'agg', 'alias', 'corr_with', 'level']);\n for (const key of map.keys()) {\n if (!knownKeys.has(key)) {\n console.error(`Unknown --metric key: \"${key}\". Allowed: ${[...knownKeys].join(', ')}`);\n process.exit(1);\n }\n }\n\n const column = map.get('col');\n const aggregation = map.get('agg');\n if (!column || !aggregation) {\n console.error(`--metric requires col and agg, got: \"${raw}\"`);\n process.exit(1);\n }\n if (!STRUCTURED_AGGREGATIONS.has(aggregation)) {\n console.error(`Invalid aggregation: \"${aggregation}\". Allowed: ${[...STRUCTURED_AGGREGATIONS].join(', ')}`);\n process.exit(1);\n }\n if (aggregation === 'corr' && !map.has('corr_with')) {\n console.error(`--metric agg=corr requires corr_with=<column>.`);\n process.exit(1);\n }\n\n const spec: { column: string; aggregation: StructuredAggregation; alias?: string; corr_with?: string; quantile_level?: number } = {\n column, aggregation: aggregation as StructuredAggregation,\n };\n if (map.has('alias')) spec.alias = map.get('alias');\n if (map.has('corr_with')) spec.corr_with = map.get('corr_with');\n if (map.has('level')) {\n const lvl = Number(map.get('level'));\n if (!Number.isFinite(lvl) || lvl < 0 || lvl > 1) {\n console.error(`--metric level must be a number between 0 and 1, got \"${map.get('level')}\"`);\n process.exit(1);\n }\n spec.quantile_level = lvl;\n }\n return spec;\n}\n\n/**\n * Parse `--filter \"<col> <op> <value>\"` for the structured /query endpoint.\n * Columns are raw paths/identifiers — no name lookup.\n */\nfunction parseStructuredFilter(raw: string): { column: string; operator: StructuredOp; value: string | number } {\n const { lhs: column, op: operator, value } = splitFilterExpr(raw, '<column> <op> <value>');\n if (!STRUCTURED_OPS.has(operator)) {\n console.error(`Invalid operator \"${operator}\". Allowed: ${[...STRUCTURED_OPS].join(', ')}`);\n process.exit(1);\n }\n // Equality and ordering operators forward numeric values as numbers when the\n // input parses as one; falls back to string for non-numeric eq/neq targets.\n // `value !== ''` guards `Number('') === 0` from coercing missing input.\n const parsedNum = Number(value);\n const isOrderOp = operator === 'gt' || operator === 'gte' || operator === 'lt' || operator === 'lte';\n const isEqualityOp = operator === 'eq' || operator === 'neq';\n const isFiniteValue = value !== '' && Number.isFinite(parsedNum);\n if (isOrderOp && !isFiniteValue) {\n console.error(`Filter value for \"${operator}\" must be numeric, got: \"${value}\"`);\n process.exit(1);\n }\n const coerceToNumber = isOrderOp || (isEqualityOp && isFiniteValue);\n return {\n column,\n operator: operator as StructuredOp,\n value: coerceToNumber ? parsedNum : value,\n };\n}\n\nfunction parseOrderBy(raw: string): { column: string; direction: 'asc' | 'desc' } {\n const [column, dirRaw = 'asc'] = raw.split(':').map((s) => s.trim());\n if (!column) {\n console.error(`Invalid --order-by \"${raw}\". Expected: \"<column>[:asc|desc]\".`);\n process.exit(1);\n }\n const dir = dirRaw.toLowerCase();\n if (dir !== 'asc' && dir !== 'desc') {\n console.error(`Invalid --order-by direction \"${dirRaw}\". Use asc or desc.`);\n process.exit(1);\n }\n return { column, direction: dir as 'asc' | 'desc' };\n}\n\n// ---------------------------------------------------------------------------\n// Output helpers\n// ---------------------------------------------------------------------------\n\nfunction printVariablesByCategory(data: {\n categories: Array<{ category: string; label: string; variableCount: number }>;\n variablesByCategory: Record<string, Array<{\n variable_id: string;\n variable_name: string;\n variable_description?: string;\n variable_type: string;\n variable_origin: string;\n }>>;\n}): void {\n console.log('Analytics Variables\\n');\n for (const category of data.categories) {\n const variables = data.variablesByCategory[category.category] || [];\n console.log(`${category.label} (${category.variableCount}):`);\n if (variables.length === 0) {\n console.log(' (none)\\n');\n continue;\n }\n for (const v of variables) {\n const desc = v.variable_description ? ` — ${v.variable_description}` : '';\n console.log(` ${v.variable_name} (${v.variable_type})${desc}`);\n }\n console.log('');\n }\n}\n\nfunction formatMinutes(minutes: number | null | undefined): string {\n if (minutes == null) return 'N/A';\n if (minutes < 1) return `${(minutes * 60).toFixed(1)}s`;\n return `${minutes.toFixed(1)}min`;\n}\n\nfunction fmt(n: number | null | undefined): string {\n if (n == null) return 'N/A';\n return Number.isInteger(n) ? String(n) : n.toFixed(2);\n}\n","/**\n * Shared helpers for the org-credential CLI commands (create-credential,\n * update-credential).\n */\n\nexport const VALID_AUTH_TYPES = ['api_key', 'bearer', 'basic_auth'] as const;\nexport type AuthType = typeof VALID_AUTH_TYPES[number];\n\n/** Maps legacy display names to canonical lowercase codes for backward compat. */\nexport const LEGACY_AUTH_TYPE_MAP: Record<string, AuthType> = {\n 'API Key': 'api_key',\n 'Bearer Token': 'bearer',\n 'Basic Auth': 'basic_auth',\n};\n\n/** Normalize a user-supplied auth type, accepting legacy display names. */\nexport function normalizeCliAuthType(type: string): AuthType | null {\n const normalized = LEGACY_AUTH_TYPE_MAP[type] ?? type;\n return VALID_AUTH_TYPES.includes(normalized as AuthType) ? (normalized as AuthType) : null;\n}\n\nexport const VALID_ENVIRONMENTS = ['preview', 'production', 'all'] as const;\nexport type Environment = typeof VALID_ENVIRONMENTS[number];\n\n/** Validate a user-supplied credential environment; returns null when invalid. */\nexport function normalizeCliEnvironment(env: string): Environment | null {\n return VALID_ENVIRONMENTS.includes(env as Environment) ? (env as Environment) : null;\n}\n\n/**\n * Map a single secret string (read from stdin) to the credential body fields\n * the backend expects for the given auth type. Basic Auth expects\n * `username:password`. Throws on malformed Basic Auth input.\n */\nexport function mapSecretToCredentialFields(\n authType: AuthType,\n secret: string,\n): Record<string, string> {\n switch (authType) {\n case 'bearer':\n return { access_token: secret };\n case 'api_key':\n return { api_key: secret };\n case 'basic_auth': {\n const colonIdx = secret.indexOf(':');\n if (colonIdx === -1) {\n throw new Error('Basic Auth stdin format: username:password');\n }\n return {\n username: secret.slice(0, colonIdx),\n password: secret.slice(colonIdx + 1),\n };\n }\n }\n}\n\nexport interface OrgTagLike {\n tag_id: string;\n name: string;\n}\n\n/**\n * Resolve a list of tag references (names, or raw tag UUIDs) to tag UUIDs using\n * the org's tag registry. Accepts names primarily (the human-facing identifier);\n * a value that is already a known tag_id passes through. Unknown references throw\n * with the list of available tag names. Empty/whitespace entries are skipped.\n */\nexport function resolveTagIds(tagRefs: string[], orgTags: OrgTagLike[]): string[] {\n const byName = new Map(orgTags.map((t) => [t.name, t.tag_id]));\n const byId = new Set(orgTags.map((t) => t.tag_id));\n const ids: string[] = [];\n const missing: string[] = [];\n\n for (const raw of tagRefs) {\n const ref = raw.trim();\n if (!ref) continue;\n const resolved = byName.get(ref);\n if (resolved) {\n ids.push(resolved);\n } else if (byId.has(ref)) {\n ids.push(ref);\n } else {\n missing.push(ref);\n }\n }\n\n if (missing.length > 0) {\n const available = orgTags.map((t) => t.name).join(', ') || '(none)';\n throw new Error(\n `Unknown tag(s): ${missing.join(', ')}. Available org tags: ${available}`,\n );\n }\n\n // De-dup while preserving order.\n return [...new Set(ids)];\n}\n\n/**\n * Split repeatable + comma-separated `--tag` values into a flat list of refs.\n * `['a,b', 'c']` → `['a', 'b', 'c']`.\n */\nexport function splitTagRefs(rawValues: string[]): string[] {\n return rawValues\n .flatMap((v) => v.split(','))\n .map((v) => v.trim())\n .filter((v) => v.length > 0);\n}\n","/**\n * wayai create-credential — create an organization credential (API key, token, or basic auth)\n *\n * Usage:\n * wayai create-credential --name \"openai-key\" --type \"Bearer Token\"\n * wayai create-credential --name \"my-api\" --type \"Basic Auth\" --org <uuid>\n * echo \"$SECRET\" | wayai create-credential --name \"openai-key\" --type \"Bearer Token\" --stdin\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { ApiClient, ApiError } from '../lib/api-client.js';\nimport { prompt, promptSecret, readStdin, resolveOrganizationId } from '../lib/utils.js';\nimport {\n VALID_AUTH_TYPES,\n VALID_ENVIRONMENTS,\n type Environment,\n normalizeCliAuthType,\n normalizeCliEnvironment,\n mapSecretToCredentialFields,\n resolveTagIds,\n splitTagRefs,\n} from '../lib/credential-utils.js';\n\ninterface ParsedArgs {\n name: string | undefined;\n type: string | undefined;\n orgId: string | undefined;\n description: string | undefined;\n tags: string[];\n environment: string | undefined;\n stdin: boolean;\n}\n\nexport function parseArgs(args: string[]): ParsedArgs {\n let name: string | undefined;\n let type: string | undefined;\n let orgId: string | undefined;\n let description: string | undefined;\n const tags: string[] = [];\n let environment: string | undefined;\n let stdin = false;\n\n for (let i = 0; i < args.length; i++) {\n if (args[i] === '--name' && args[i + 1]) {\n name = args[++i];\n } else if (args[i] === '--type' && args[i + 1]) {\n type = args[++i];\n } else if (args[i] === '--org' && args[i + 1]) {\n orgId = args[++i];\n } else if (args[i] === '--description' && args[i + 1]) {\n description = args[++i];\n } else if (args[i] === '--tag' && args[i + 1]) {\n tags.push(args[++i]);\n } else if (args[i] === '--environment' && args[i + 1]) {\n environment = args[++i];\n } else if (args[i] === '--stdin') {\n stdin = true;\n }\n }\n\n return { name, type, orgId, description, tags: splitTagRefs(tags), environment, stdin };\n}\n\nexport async function createCredentialCommand(args: string[]): Promise<void> {\n const parsed = parseArgs(args);\n\n if (!parsed.name) {\n console.error('Missing required flag: --name <credential-name>');\n console.error('Usage: wayai create-credential --name \"openai-key\" --type \"Bearer Token\"');\n process.exit(1);\n }\n\n if (!parsed.type) {\n console.error('Missing required flag: --type <auth-type>');\n console.error(`Supported types: ${VALID_AUTH_TYPES.join(', ')}`);\n process.exit(1);\n }\n\n // Normalize legacy display names (e.g. \"Bearer Token\" → \"bearer\") for backward compat\n const authType = normalizeCliAuthType(parsed.type);\n if (!authType) {\n console.error(`Invalid authentication type: \"${parsed.type}\"`);\n console.error(`Supported types: ${VALID_AUTH_TYPES.join(', ')}`);\n process.exit(1);\n }\n\n if (parsed.environment && !normalizeCliEnvironment(parsed.environment)) {\n console.error(`Invalid environment: \"${parsed.environment}\"`);\n console.error(`Supported environments: ${VALID_ENVIRONMENTS.join(', ')}`);\n process.exit(1);\n }\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n const { organizationId } = await resolveOrganizationId(client, parsed.orgId);\n\n // Resolve tag names → tag UUIDs (the backend stores credential tags as UUIDs).\n let tagIds: string[] | undefined;\n if (parsed.tags.length > 0) {\n const orgTags = await client.listOrgTags(organizationId);\n tagIds = resolveTagIds(parsed.tags, orgTags.data || []);\n }\n\n // Collect secret(s) based on auth type\n const secrets: Record<string, string> = {};\n\n if (parsed.stdin) {\n if (process.stdin.isTTY) {\n console.error('--stdin requires piped input. Example: echo \"$SECRET\" | wayai create-credential --name \"key\" --type \"Bearer Token\" --stdin');\n process.exit(1);\n }\n const input = await readStdin();\n if (!input) {\n console.error('No input received from stdin.');\n process.exit(1);\n }\n\n try {\n Object.assign(secrets, mapSecretToCredentialFields(authType, input));\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n } else {\n // Interactive prompt with masked input\n switch (authType) {\n case 'bearer':\n secrets.access_token = await promptSecret('Enter access token: ');\n break;\n case 'api_key':\n secrets.api_key = await promptSecret('Enter API key: ');\n break;\n case 'basic_auth':\n secrets.username = await prompt('Enter username: ');\n secrets.password = await promptSecret('Enter password: ');\n break;\n }\n\n // Validate secrets are not empty\n for (const [key, value] of Object.entries(secrets)) {\n if (!value) {\n console.error(`${key} cannot be empty.`);\n process.exit(1);\n }\n }\n }\n\n console.log(`Creating credential \"${parsed.name}\" (${authType})...`);\n\n let result;\n try {\n result = await client.createOrgCredential({\n organization_id: organizationId,\n credential_display_name: parsed.name,\n authentication_type: authType,\n ...(parsed.description && { credential_description: parsed.description }),\n ...(tagIds && tagIds.length > 0 && { tags: tagIds }),\n ...(parsed.environment && { environment: parsed.environment as Environment }),\n ...secrets,\n });\n } catch (err) {\n if (err instanceof ApiError && err.status === 409) {\n console.error(`\\nA credential named \"${parsed.name}\" already exists in this organization.`);\n console.error(`To rotate its secret or change its tags, use:\\n wayai update-credential --name \"${parsed.name}\" --stdin`);\n process.exit(1);\n }\n throw err;\n }\n\n console.log(`\\nCredential created: ${result.data.credential_display_name}`);\n console.log(` ID: ${result.data.organization_credential_id}`);\n console.log(` Type: ${result.data.authentication_type}`);\n}\n","/**\n * wayai update-credential — update / rotate an existing organization credential.\n *\n * Targets a credential by its display name (org credentials are resolved by name\n * everywhere), then maps to the existing `PUT /api/setup/organization-credentials/:id`.\n * The backend propagates a rotated secret to every linked connection.\n *\n * Usage:\n * echo \"$NEW_TOKEN\" | wayai update-credential --name \"clinica-medica-mcp\" --stdin\n * wayai update-credential --name \"openai-key\" --tag clinica-medica\n * wayai update-credential --name \"old-name\" --rename \"new-name\"\n * wayai update-credential --name \"my-api\" --description \"Rotated 2026-06\" --environment production\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { ApiClient, ApiError } from '../lib/api-client.js';\nimport { promptSecret, prompt, readStdin, resolveOrganizationId } from '../lib/utils.js';\nimport {\n type AuthType,\n VALID_ENVIRONMENTS,\n type Environment,\n normalizeCliEnvironment,\n mapSecretToCredentialFields,\n resolveTagIds,\n splitTagRefs,\n} from '../lib/credential-utils.js';\nimport type { UpdateOrgCredentialInput } from '@wayai/core/contracts';\n\ninterface ParsedArgs {\n name: string | undefined;\n rename: string | undefined;\n orgId: string | undefined;\n description: string | undefined;\n tags: string[];\n hasTagFlag: boolean;\n environment: string | undefined;\n /** --stdin: read the new secret from a pipe. */\n stdin: boolean;\n /** --secret: prompt for the new secret interactively (masked). */\n secretPrompt: boolean;\n}\n\nexport function parseArgs(args: string[]): ParsedArgs {\n let name: string | undefined;\n let rename: string | undefined;\n let orgId: string | undefined;\n let description: string | undefined;\n const tags: string[] = [];\n let hasTagFlag = false;\n let environment: string | undefined;\n let stdin = false;\n let secretPrompt = false;\n\n for (let i = 0; i < args.length; i++) {\n if (args[i] === '--name' && args[i + 1]) {\n name = args[++i];\n } else if (args[i] === '--rename' && args[i + 1]) {\n rename = args[++i];\n } else if (args[i] === '--org' && args[i + 1]) {\n orgId = args[++i];\n } else if (args[i] === '--description' && args[i + 1]) {\n description = args[++i];\n } else if (args[i] === '--tag' && args[i + 1]) {\n hasTagFlag = true;\n tags.push(args[++i]);\n } else if (args[i] === '--environment' && args[i + 1]) {\n environment = args[++i];\n } else if (args[i] === '--stdin') {\n stdin = true;\n } else if (args[i] === '--secret') {\n secretPrompt = true;\n }\n }\n\n return { name, rename, orgId, description, tags: splitTagRefs(tags), hasTagFlag, environment, stdin, secretPrompt };\n}\n\nexport async function updateCredentialCommand(args: string[]): Promise<void> {\n const parsed = parseArgs(args);\n\n if (!parsed.name) {\n console.error('Missing required flag: --name <credential-name>');\n console.error('Usage: wayai update-credential --name \"my-key\" --stdin');\n process.exit(1);\n }\n\n if (parsed.environment && !normalizeCliEnvironment(parsed.environment)) {\n console.error(`Invalid environment: \"${parsed.environment}\"`);\n console.error(`Supported environments: ${VALID_ENVIRONMENTS.join(', ')}`);\n process.exit(1);\n }\n\n const wantsSecret = parsed.stdin || parsed.secretPrompt;\n\n if (!wantsSecret && !parsed.rename && parsed.description === undefined && !parsed.hasTagFlag && !parsed.environment) {\n console.error('Nothing to update. Provide at least one of: --stdin/--secret, --rename, --description, --tag, --environment');\n process.exit(1);\n }\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n const { organizationId } = await resolveOrganizationId(client, parsed.orgId);\n\n // Resolve the credential by display name.\n const list = await client.listOrgCredentials(organizationId);\n const matches = (list.data || []).filter((c) => c.credential_display_name === parsed.name);\n\n if (matches.length === 0) {\n console.error(`No credential named \"${parsed.name}\" found in this organization.`);\n const available = (list.data || []).map((c) => c.credential_display_name);\n if (available.length > 0) {\n console.error(`Available credentials: ${available.join(', ')}`);\n }\n process.exit(1);\n }\n if (matches.length > 1) {\n console.error(\n `${matches.length} credentials are named \"${parsed.name}\" (ids: ${matches.map((c) => c.organization_credential_id).join(', ')}).`,\n );\n console.error('Names are ambiguous — resolve the duplicates in Settings → Organization → Credentials before updating by name.');\n process.exit(1);\n }\n\n const credential = matches[0];\n const authType = credential.authentication_type as AuthType;\n\n const body: UpdateOrgCredentialInput = {};\n\n // Secret rotation — map the piped/prompted value to the right field(s) for this\n // credential's auth type.\n if (wantsSecret) {\n let input: string;\n if (parsed.stdin) {\n if (process.stdin.isTTY) {\n console.error('--stdin requires piped input. Use --secret for an interactive masked prompt.');\n process.exit(1);\n }\n input = await readStdin();\n } else if (authType === 'basic_auth') {\n const username = await prompt('Enter username: ');\n const password = await promptSecret('Enter password: ');\n input = `${username}:${password}`;\n } else {\n input = await promptSecret(authType === 'bearer' ? 'Enter access token: ' : 'Enter API key: ');\n }\n if (!input) {\n console.error('No secret provided.');\n process.exit(1);\n }\n try {\n Object.assign(body, mapSecretToCredentialFields(authType, input));\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n }\n\n if (parsed.rename) body.credential_display_name = parsed.rename;\n if (parsed.description !== undefined) body.credential_description = parsed.description;\n if (parsed.environment) body.environment = parsed.environment as Environment;\n if (parsed.hasTagFlag) {\n const orgTags = await client.listOrgTags(organizationId);\n body.tags = resolveTagIds(parsed.tags, orgTags.data || []);\n }\n\n console.log(`Updating credential \"${parsed.name}\"...`);\n\n let result;\n try {\n result = await client.updateOrgCredential(credential.organization_credential_id, organizationId, body);\n } catch (err) {\n if (err instanceof ApiError && err.status === 409) {\n console.error(`\\nCannot rename: a credential named \"${parsed.rename}\" already exists in this organization.`);\n process.exit(1);\n }\n throw err;\n }\n\n console.log(`\\nCredential updated: ${result.data.credential_display_name}`);\n console.log(` ID: ${result.data.organization_credential_id}`);\n console.log(` Type: ${result.data.authentication_type}`);\n if (wantsSecret) {\n console.log(' Secret rotated — linked connections updated.');\n }\n}\n","/**\n * Org-as-code workspace — the org dir for the active layout (`wayai-ws/org/`,\n * or the legacy root-level `org/` for un-migrated repos; see `layout.ts`).\n *\n * <orgDir>/\n * resources.yaml # resource metadata (files stripped, like hub.yaml)\n * resources/<slug>/... # file trees (SKILL.md, docs/…, binaries)\n *\n * Sits beside the hub folders under the same `wayai-ws/` root. One org per repo\n * (org id comes from `.wayai.yaml`). Reuses the shared resource file-tree\n * primitives so binary/hash/orphan rules match hub-as-code exactly.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as yaml from 'js-yaml';\nimport { slugify } from './utils.js';\nimport { resolveLayout } from './layout.js';\nimport { scanResourceFiles, writeResourceFileTree, downloadBinaryFiles } from './resource-files.js';\nimport { YAML_DUMP_OPTIONS } from './yaml-writer.js';\nimport type { OrgResourcesPayload, OrgAsCodeResource } from './types.js';\n\nexport const ORG_MANIFEST_NAME = 'resources.yaml';\n\nexport function getOrgDir(gitRoot: string): string {\n return resolveLayout(gitRoot).orgDir;\n}\n\nexport function orgManifestExists(orgDir: string): boolean {\n return fs.existsSync(path.join(orgDir, ORG_MANIFEST_NAME));\n}\n\n/** Read `org/resources.yaml` + scan `org/resources/<slug>/` into a payload. */\nexport function parseOrgResources(orgDir: string): OrgResourcesPayload {\n const manifestPath = path.join(orgDir, ORG_MANIFEST_NAME);\n let manifest: Record<string, unknown> = {};\n if (fs.existsSync(manifestPath)) {\n manifest = (yaml.load(fs.readFileSync(manifestPath, 'utf-8')) as Record<string, unknown>) ?? {};\n }\n const rawResources = Array.isArray(manifest.resources)\n ? (manifest.resources as Array<Record<string, unknown>>)\n : [];\n const resourcesDir = path.join(orgDir, 'resources');\n\n const resources: OrgAsCodeResource[] = rawResources.map((res) => {\n const resource: OrgAsCodeResource = { name: res.name as string };\n if (res.id) resource.id = res.id as string;\n if (res.type) resource.type = res.type as string;\n if (res.description) resource.description = res.description as string;\n if (res.enabled === false) resource.enabled = false;\n if (res.user_browsable) resource.user_browsable = res.user_browsable as boolean;\n if (res.skill_name) resource.skill_name = res.skill_name as string;\n if (res.environment) resource.environment = res.environment as OrgAsCodeResource['environment'];\n if (Array.isArray(res.tags)) resource.tags = res.tags as string[];\n if (Array.isArray(res.folders)) resource.folders = res.folders as OrgAsCodeResource['folders'];\n\n const resDir = path.join(resourcesDir, slugify(resource.name));\n if (fs.existsSync(resDir)) {\n const files = scanResourceFiles(resDir, '');\n if (files.length > 0) resource.files = files;\n }\n return resource;\n });\n\n return { version: 1, resources };\n}\n\n/** Write `resources.yaml` (files stripped) + file trees + orphan-dir cleanup. */\nexport function writeOrgResources(orgDir: string, payload: OrgResourcesPayload): void {\n fs.mkdirSync(orgDir, { recursive: true });\n const resources = payload.resources ?? [];\n\n // Manifest carries metadata + folders; file content lives on disk.\n const manifestResources = resources.map((r) => {\n const { files: _files, ...rest } = r;\n return rest;\n });\n fs.writeFileSync(\n path.join(orgDir, ORG_MANIFEST_NAME),\n yaml.dump({ version: 1, resources: manifestResources }, YAML_DUMP_OPTIONS),\n 'utf-8',\n );\n\n const resourcesDir = path.join(orgDir, 'resources');\n const currentSlugs = new Set<string>();\n for (const resource of resources) {\n const resSlug = slugify(resource.name);\n currentSlugs.add(resSlug);\n writeResourceFileTree(path.join(resourcesDir, resSlug), resource.files || []);\n }\n\n // Remove orphan resource directories.\n if (fs.existsSync(resourcesDir)) {\n for (const entry of fs.readdirSync(resourcesDir, { withFileTypes: true })) {\n if (entry.isDirectory() && !currentSlugs.has(entry.name)) {\n fs.rmSync(path.join(resourcesDir, entry.name), { recursive: true, force: true });\n }\n }\n }\n}\n\n/** Download binary files (download_url, no inline content) into `org/resources/<slug>/`. */\nexport async function downloadOrgBinaryFiles(orgDir: string, payload: OrgResourcesPayload): Promise<void> {\n let count = 0;\n for (const resource of payload.resources ?? []) {\n if (!resource.files) continue;\n const resDir = path.join(orgDir, 'resources', slugify(resource.name));\n count += await downloadBinaryFiles(resDir, resource.files);\n }\n if (count > 0) console.log(`Downloaded ${count} binary resource file(s).`);\n}\n","/**\n * wayai org <create|pull|push|diff> — manage organizations and org-scoped resources.\n *\n * wayai org create \"<name>\" — create a new organization (you become its owner)\n *\n * The pull/push/diff subcommands sync ORG-scoped resources as code (the org-level\n * analog of hub resources, shared across hubs). They live in the org dir for the\n * active layout (`wayai-ws/org/`, or the legacy root-level `org/`), as\n * `resources.yaml` + `resources/<slug>/`; one org per repo (org id from\n * `.wayai.yaml`). Hub config (`wayai-ws/hubs/`) is untouched.\n *\n * wayai org pull — fetch org resources → <orgDir>/\n * wayai org diff — preview what `org push` would change on the platform\n * wayai org push — apply local org resources to the platform (fans out to linked hubs)\n *\n * `create` is git-agnostic (no repo/scope required — it's the first-org bootstrap);\n * pull/push/diff require a scoped repo.\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { requireRepoConfig } from '../lib/repo-config.js';\nimport { findGitRoot } from '../lib/workspace.js';\nimport { warnLayoutOnce } from '../lib/layout.js';\nimport { confirm } from '../lib/utils.js';\nimport { printDiff } from '../lib/diff-display.js';\nimport {\n getOrgDir,\n orgManifestExists,\n parseOrgResources,\n writeOrgResources,\n downloadOrgBinaryFiles,\n} from '../lib/org-workspace.js';\n\ninterface OrgContext {\n orgId: string;\n orgDir: string;\n client: ApiClient;\n}\n\nfunction parseFlags(args: string[]): { autoConfirm: boolean } {\n return { autoConfirm: args.includes('--yes') || args.includes('-y') };\n}\n\nasync function resolveContext(): Promise<OrgContext> {\n const { organization_id: orgId } = requireRepoConfig();\n const gitRoot = findGitRoot();\n if (!gitRoot) {\n console.error('Not inside a git repository.');\n process.exit(1);\n }\n warnLayoutOnce(gitRoot);\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n return { orgId, orgDir: getOrgDir(gitRoot), client };\n}\n\nexport async function orgCommand(args: string[]): Promise<void> {\n const sub = args[0];\n const rest = args.slice(1);\n switch (sub) {\n case 'create':\n return orgCreate(rest);\n case 'pull':\n return orgPull(rest);\n case 'diff':\n return orgDiff(rest);\n case 'push':\n return orgPush(rest);\n default:\n console.error('Usage: wayai org <create|pull|push|diff> [-y]');\n process.exit(1);\n }\n}\n\n/** First non-flag token, skipping the value consumed by `--region`. */\nfunction firstPositional(args: string[]): string | undefined {\n for (let i = 0; i < args.length; i++) {\n const a = args[i];\n if (a.startsWith('-')) {\n if (a === '--region') i++; // skip its value\n continue;\n }\n return a;\n }\n return undefined;\n}\n\nfunction getFlagValue(args: string[], flag: string): string | undefined {\n const idx = args.indexOf(flag);\n return idx !== -1 ? args[idx + 1] : undefined;\n}\n\n/**\n * wayai org create \"<name>\" [--region <region>] [--json]\n *\n * Creates an organization and makes the caller its owner. Deliberately does NOT\n * require a git repo or `.wayai.yaml` — this is the bootstrap step a brand-new\n * user runs before they have anything scoped. Follow with `wayai init`.\n */\nasync function orgCreate(args: string[]): Promise<void> {\n const json = args.includes('--json');\n const name = firstPositional(args);\n if (!name) {\n console.error('Usage: wayai org create \"<name>\" [--region <region>] [--json]');\n process.exit(1);\n }\n const region = getFlagValue(args, '--region');\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n if (!json) console.log(`Creating organization \"${name}\"...`);\n const { organization } = await client.createOrganization(name, region);\n\n if (json) {\n console.log(JSON.stringify(organization, null, 2));\n return;\n }\n console.log(`Created organization: ${organization.name} (${organization.id})`);\n if (organization.region) {\n const note = organization.region_explicit ? 'as requested' : 'closest to you — pass --region to override';\n console.log(` Region: ${organization.region} (${note})`);\n }\n console.log(`\\nScope a repo to it with \\`wayai init --org ${organization.id}\\`.`);\n}\n\nasync function orgPull(args: string[]): Promise<void> {\n const { autoConfirm } = parseFlags(args);\n const { orgId, orgDir, client } = await resolveContext();\n\n console.log('Fetching organization resources...');\n const payload = await client.pullOrgResources(orgId);\n\n // If org/ already has content, preview what pulling would overwrite locally.\n if (orgManifestExists(orgDir) && !autoConfirm) {\n const local = parseOrgResources(orgDir);\n const diff = await client.diffOrgResources(orgId, local, 'push');\n if (diff.has_changes) {\n console.log('\\nLocal org/ differs from the platform. Pulling overwrites local with the platform state:');\n printDiff(diff.summary);\n const ok = await confirm('Overwrite local org/ with platform state?');\n if (!ok) {\n console.log('Cancelled.');\n return;\n }\n }\n }\n\n writeOrgResources(orgDir, payload);\n await downloadOrgBinaryFiles(orgDir, payload);\n console.log(`Organization resources written to ${orgDir}`);\n}\n\nasync function orgDiff(args: string[]): Promise<void> {\n void args;\n const { orgId, orgDir, client } = await resolveContext();\n if (!orgManifestExists(orgDir)) {\n console.error(`No ${orgDir}/resources.yaml found. Run \\`wayai org pull\\` first.`);\n process.exit(1);\n }\n const local = parseOrgResources(orgDir);\n const diff = await client.diffOrgResources(orgId, local, 'push');\n if (!diff.has_changes) {\n console.log('No changes — org/ matches the platform.');\n return;\n }\n console.log('Changes `wayai org push` would apply:');\n printDiff(diff.summary);\n}\n\nasync function orgPush(args: string[]): Promise<void> {\n const { autoConfirm } = parseFlags(args);\n const { orgId, orgDir, client } = await resolveContext();\n if (!orgManifestExists(orgDir)) {\n console.error(`No ${orgDir}/resources.yaml found. Run \\`wayai org pull\\` first.`);\n process.exit(1);\n }\n\n const local = parseOrgResources(orgDir);\n const diff = await client.diffOrgResources(orgId, local, 'push');\n\n if (!diff.has_changes) {\n console.log('No changes — org/ already matches the platform.');\n return;\n }\n\n console.log('Changes to apply:');\n printDiff(diff.summary);\n\n if (!autoConfirm) {\n const ok = await confirm('Apply these changes to the organization?');\n if (!ok) {\n console.log('Cancelled.');\n return;\n }\n }\n\n const result = await client.pushOrgResources(orgId, local);\n const c = result.changes;\n console.log(\n `Pushed: ${c.resources_created} created, ${c.resources_updated} updated, ${c.resources_deleted} deleted; ` +\n `${c.resource_files_uploaded} file(s) uploaded, ${c.resource_files_deleted} deleted.`,\n );\n if (result.fanout.hubs > 0) {\n const failed = result.fanout.failures > 0 ? ` (${result.fanout.failures} failed)` : '';\n console.log(`Synced to ${result.fanout.hubs} linked hub shadow(s)${failed}.`);\n }\n if (result.errors?.length) {\n console.warn('\\nCompleted with errors:');\n for (const e of result.errors) console.warn(` - ${e}`);\n }\n\n // Re-pull so server-assigned ids land in the local manifest (matches `wayai push`).\n const refreshed = await client.pullOrgResources(orgId);\n writeOrgResources(orgDir, refreshed);\n await downloadOrgBinaryFiles(orgDir, refreshed);\n}\n","/**\n * wayai list — list organizations and hubs\n *\n * Usage:\n * wayai list # all orgs → hubs\n * wayai list --org <id> # filter to one org\n * wayai list --json # structured output for agents/scripts\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { ApiClient } from '../lib/api-client.js';\n\nexport function parseArgs(args: string[]): { orgId: string | undefined; json: boolean } {\n let orgId: string | undefined;\n let json = false;\n for (let i = 0; i < args.length; i++) {\n if (args[i] === '--org' && args[i + 1]) {\n orgId = args[++i];\n } else if (args[i] === '--json') {\n json = true;\n }\n }\n return { orgId, json };\n}\n\nexport async function listCommand(args: string[]): Promise<void> {\n const { orgId, json } = parseArgs(args);\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n const { organizations } = await client.organizations();\n\n const orgsToList = orgId\n ? organizations.filter((o) => o.id === orgId)\n : organizations;\n\n if (orgsToList.length === 0) {\n if (json) {\n console.log(JSON.stringify({ organizations: [] }, null, 2));\n } else {\n console.log(orgId ? `Organization ${orgId} not found.` : 'No organizations found.');\n }\n return;\n }\n\n // Fetch hubs for all orgs in parallel\n const results = await Promise.all(\n orgsToList.map((org) => client.listHubs(org.id).then((r) => ({ org, hubs: r.hubs })))\n );\n\n if (json) {\n const payload = {\n organizations: results.map(({ org, hubs }) => ({\n organization_id: org.id,\n organization_name: org.name,\n hubs: hubs.map((h) => ({\n hub_id: h.hub_id,\n hub_name: h.hub_name,\n preview_label: h.preview_label ?? null,\n })),\n })),\n };\n console.log(JSON.stringify(payload, null, 2));\n return;\n }\n\n for (const { org, hubs } of results) {\n console.log(`\\n${org.name} (${org.id})`);\n\n if (hubs.length === 0) {\n console.log(' (no hubs)');\n continue;\n }\n\n for (const hub of hubs) {\n const label = hub.preview_label ? ` (${hub.preview_label})` : '';\n console.log(` ${hub.hub_name}${label} ${hub.hub_id}`);\n }\n }\n}\n","/**\n * Shared arg parser for the report content-edit commands — `wayai report edit`\n * (reporter) and `wayai admin report update` (admin). Both amend the same five\n * content fields of an EditReportBody, so the flag→key mapping and the\n * missing-value handling live in one place.\n *\n * Critically, this distinguishes a flag given WITHOUT a value (an error) from a\n * flag given an explicit empty string (a deliberate clear, e.g. `--error \"\"`).\n * The generic `parseReportFlags` in admin.ts cannot — it collapses a value-less\n * flag to the string `\"true\"`, which would silently persist `\"true\"` into a\n * content field. Hence a dedicated parser for the value-bearing content flags.\n */\n\nimport type { EditReportBody } from '@wayai/core/contracts';\n\ntype ContentKey = keyof EditReportBody;\n\n// Long + short flag aliases → EditReportBody key. `error`/`steps`/`context` map\n// to the raw_payload field names (error_message/steps_to_reproduce/additional_context).\nconst FLAG_TO_KEY: Record<string, ContentKey> = {\n '-t': 'title',\n '--title': 'title',\n '-d': 'description',\n '--description': 'description',\n '-e': 'error_message',\n '--error': 'error_message',\n '-s': 'steps_to_reproduce',\n '--steps': 'steps_to_reproduce',\n '--context': 'additional_context',\n};\n\nexport interface ParsedReportEdit {\n /** First non-flag positional argument (the report id), if present. */\n reportId?: string;\n patch: EditReportBody;\n /** Set when parsing failed (unknown flag / missing value). Callers print + exit. */\n error?: string;\n}\n\n/**\n * Parse `[<id>] [--flag value ...]` into a report id + content patch. A content\n * flag with no following token errors (`--<flag> requires a value`); an explicit\n * empty string is kept (it clears the field server-side). An unknown `-`/`--`\n * flag errors rather than being silently dropped.\n */\nexport function parseReportEditArgs(args: string[]): ParsedReportEdit {\n const patch: EditReportBody = {};\n let reportId: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n const key = FLAG_TO_KEY[arg];\n if (key) {\n const value = args[i + 1];\n if (value === undefined) {\n return { reportId, patch, error: `${arg} requires a value` };\n }\n patch[key] = value;\n i++; // consume the value (may be \"\" → clears the field)\n } else if (arg.startsWith('-')) {\n return { reportId, patch, error: `Unknown flag: ${arg}` };\n } else if (reportId === undefined) {\n reportId = arg;\n }\n // Extra positionals beyond the id are ignored.\n }\n\n return { reportId, patch };\n}\n","// Platform-admin DO read-only inspection — audits to Loki as admin_debug_read; 403 non-admin; 60/hour.\nimport { requireAuth } from '../lib/auth.js';\nimport { ApiClient, ApiError } from '../lib/api-client.js';\nimport { runDebugObservability } from './observability.js';\nimport { parseReportEditArgs } from '../lib/report-edit-args.js';\nimport {\n dataExplorerDebugDoType,\n dataExplorerDebugAnalyticsTable,\n} from '@wayai/core/contracts';\nimport type {\n DataExplorerDebugDoType,\n DataExplorerDebugAnalyticsTable,\n CreateNoticeBody,\n NoticeSeverity,\n} from '@wayai/core/contracts';\n\ntype DoType = DataExplorerDebugDoType;\ntype AnalyticsTable = DataExplorerDebugAnalyticsTable;\n// Single source of truth: the contract enums the backend allowlist also derives\n// from. The CLI bundles @wayai/core at build (tsup `noExternal`), so importing\n// the runtime enum is free — no hand-copied literal, no drift to guard.\nconst VALID_TYPES = dataExplorerDebugDoType.options;\nconst VALID_ANALYTICS_TABLES = dataExplorerDebugAnalyticsTable.options;\n\nexport async function adminCommand(args: string[]): Promise<void> {\n const [group, ...afterGroup] = args;\n\n if (!group) {\n printHelp();\n process.exit(1);\n }\n\n if (group === 'archive') {\n // `archive` has no sub — all remaining args are positional/flags.\n const { positional, flagArgs } = splitArgs(afterGroup);\n await runArchiveRead(positional, flagArgs);\n return;\n }\n\n if (group === 'observability') {\n const { positional, flagArgs } = splitArgs(afterGroup);\n await runObservabilityRead(positional, flagArgs);\n return;\n }\n\n const [sub, ...rest] = afterGroup;\n const { positional, flagArgs } = splitArgs(rest);\n\n if (group === 'do') {\n if (!sub) { printHelp(); process.exit(1); }\n switch (sub) {\n case 'tables': await runDoTables(positional); return;\n case 'read': await runDoRead(positional, flagArgs); return;\n default: printHelp(); process.exit(1);\n }\n }\n\n if (group === 'analytics') {\n if (!sub) { printHelp(); process.exit(1); }\n switch (sub) {\n case 'tables': await runAnalyticsTables(); return;\n case 'read': await runAnalyticsRead(positional, flagArgs); return;\n default: printHelp(); process.exit(1);\n }\n }\n\n if (group === 'report') {\n if (!sub) { printHelp(); process.exit(1); }\n switch (sub) {\n case 'list': await runReportList(flagArgs); return;\n case 'show': await runReportShow(positional); return;\n case 'group': await runReportGroup(positional); return;\n case 'ungroup': await runReportUngroup(positional); return;\n case 'escalate': await runReportEscalate(positional, flagArgs); return;\n case 'shipped': await runReportShipped(positional, flagArgs); return;\n case 'addressed': await runReportAddressed(positional); return;\n case 'dismiss': await runReportDismiss(positional, flagArgs); return;\n case 'hold': await runReportHold(positional, flagArgs); return;\n case 'update': await runReportUpdate(positional, flagArgs); return;\n default: printHelp(); process.exit(1);\n }\n }\n\n if (group === 'notice') {\n if (!sub) { printHelp(); process.exit(1); }\n switch (sub) {\n case 'create': await runNoticeCreate(flagArgs); return;\n case 'list': await runNoticeList(flagArgs); return;\n case 'resolve': await runNoticeResolve(positional); return;\n default: printHelp(); process.exit(1);\n }\n }\n\n printHelp();\n process.exit(1);\n}\n\nfunction splitArgs(args: string[]): { positional: string[]; flagArgs: string[] } {\n const positional: string[] = [];\n const flagArgs: string[] = [];\n for (const a of args) {\n if (a.startsWith('--') || flagArgs.length > 0) {\n flagArgs.push(a);\n } else {\n positional.push(a);\n }\n }\n return { positional, flagArgs };\n}\n\n// ---------------------------------------------------------------------------\n// Subcommands — DO\n// ---------------------------------------------------------------------------\n\nasync function runDoTables(positional: string[]): Promise<void> {\n if (positional.length < 2) {\n console.error('wayai admin do tables <type> <id>');\n process.exit(1);\n }\n const type = validateType(positional[0]);\n const id = positional[1];\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n let response;\n try {\n response = await client.debugListTables(type, id);\n } catch (err) {\n exitOnApiError(err);\n throw err; // unreachable\n }\n\n const { tables } = response.data;\n if (tables.length === 0) {\n console.log('(no allowlisted tables found on this DO)');\n return;\n }\n for (const t of tables) console.log(t);\n}\n\nasync function runDoRead(positional: string[], flagArgs: string[]): Promise<void> {\n if (positional.length < 3) {\n console.error('wayai admin do read <type> <id> <table> [--limit N] [--id X] [--json]');\n process.exit(1);\n }\n const type = validateType(positional[0]);\n const id = positional[1];\n const table = positional[2];\n\n const { limit, filterId, jsonOutput } = parseFlags(flagArgs, ['--limit', '--id', '--json']);\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n let response;\n try {\n response = await client.debugReadTable(type, id, table, { limit, id: filterId });\n } catch (err) {\n exitOnApiError(err);\n throw err;\n }\n\n printDebugRowsResult(response.data, jsonOutput);\n}\n\n// ---------------------------------------------------------------------------\n// Subcommands — Analytics (ClickHouse)\n// ---------------------------------------------------------------------------\n\nasync function runAnalyticsTables(): Promise<void> {\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n let response;\n try {\n response = await client.debugListAnalyticsTables();\n } catch (err) {\n exitOnApiError(err);\n throw err;\n }\n\n const { tables } = response.data;\n if (tables.length === 0) {\n console.log('(no analytics tables available)');\n return;\n }\n for (const t of tables) console.log(t);\n}\n\nasync function runAnalyticsRead(positional: string[], flagArgs: string[]): Promise<void> {\n if (positional.length < 1) {\n console.error('wayai admin analytics read <table> [--conversation-id X] [--hub-id Y] [--message-id Z] [--limit N] [--json]');\n process.exit(1);\n }\n const table = validateAnalyticsTable(positional[0]);\n\n const flags = parseFlags(flagArgs, ['--limit', '--json', '--conversation-id', '--hub-id', '--message-id']);\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n let response;\n try {\n response = await client.debugReadAnalyticsTable(table, {\n conversationId: flags.conversationId,\n hubId: flags.hubId,\n messageId: flags.messageId,\n limit: flags.limit,\n });\n } catch (err) {\n exitOnApiError(err);\n throw err;\n }\n\n printDebugRowsResult(response.data, flags.jsonOutput);\n}\n\n// ---------------------------------------------------------------------------\n// Subcommands — Archive (R2)\n// ---------------------------------------------------------------------------\n\nasync function runArchiveRead(positional: string[], flagArgs: string[]): Promise<void> {\n if (positional.length < 2) {\n console.error('wayai admin archive <hub_id> <conversation_id> [--message-id X] [--json]');\n process.exit(1);\n }\n const hubId = positional[0];\n const conversationId = positional[1];\n\n const flags = parseFlags(flagArgs, ['--json', '--message-id']);\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n let response;\n try {\n response = await client.debugReadArchive(hubId, conversationId, {\n messageId: flags.messageId,\n });\n } catch (err) {\n // Archive-specific 404 copy: an admin reading an archive expects \"purged or never written\"\n // rather than a generic \"not found.\" Only this subcommand has the context to say that.\n if (err instanceof ApiError && err.status === 404) {\n console.error('Archive not found. The conversation may not be ended yet, or the R2 blob may have been purged.');\n process.exit(1);\n }\n exitOnApiError(err);\n throw err;\n }\n\n const data = response.data;\n\n if (flags.jsonOutput) {\n console.log(JSON.stringify(data, null, 2));\n return;\n }\n\n // Default pretty-print: archive metadata + a one-line message digest.\n // Admins who need full content pass --json.\n const archive = data.archive;\n console.log(`hub_id: ${data.hub_id}`);\n console.log(`conversation_id:${data.conversation_id}`);\n if (data.message_filtered) console.log('(messages filtered by --message-id)');\n\n const messages = Array.isArray(archive.messages) ? (archive.messages as Array<Record<string, unknown>>) : [];\n const files = Array.isArray(archive.files) ? archive.files.length : 0;\n console.log(`messages: ${messages.length}`);\n console.log(`files: ${files}`);\n\n if (messages.length > 0) {\n console.log('');\n console.log('messages (id | sender | created_at | text):');\n for (const m of messages) {\n const id = String(m.message_id ?? '');\n const sender = String(m.sender_type ?? '');\n const ts = String(m.created_at ?? '');\n const text = truncate(String(m.message_text ?? ''), 80);\n console.log(` ${id} | ${sender} | ${ts} | ${text}`);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Subcommands — Observability (R2)\n// ---------------------------------------------------------------------------\n\nasync function runObservabilityRead(positional: string[], flagArgs: string[]): Promise<void> {\n if (positional.length < 2) {\n console.error('wayai admin observability <hub_id> <conversation_id> [--message-id X] [--json]');\n process.exit(1);\n }\n const hubId = positional[0];\n const conversationId = positional[1];\n\n const flags = parseFlags(flagArgs, ['--json', '--message-id']);\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n try {\n await runDebugObservability(client, hubId, conversationId, {\n messageId: flags.messageId,\n jsonOutput: flags.jsonOutput,\n });\n } catch (err) {\n if (err instanceof ApiError && err.status === 404) {\n console.error('Observability data not found. Either the conversation has no LLM turns yet, or R2 entries were purged.');\n process.exit(1);\n }\n exitOnApiError(err);\n throw err;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction validateType(raw: string | undefined): DoType {\n if (!raw || !VALID_TYPES.includes(raw as DoType)) {\n console.error(`type must be one of: ${VALID_TYPES.join(', ')}`);\n process.exit(1);\n }\n return raw as DoType;\n}\n\nfunction validateAnalyticsTable(raw: string | undefined): AnalyticsTable {\n if (!raw || !VALID_ANALYTICS_TABLES.includes(raw as AnalyticsTable)) {\n console.error(`table must be one of: ${VALID_ANALYTICS_TABLES.join(', ')}`);\n process.exit(1);\n }\n return raw as AnalyticsTable;\n}\n\ninterface ParsedFlags {\n limit?: number;\n filterId?: string;\n conversationId?: string;\n hubId?: string;\n messageId?: string;\n jsonOutput: boolean;\n}\n\nfunction parseFlags(flagArgs: string[], allowed: readonly string[]): ParsedFlags {\n const out: ParsedFlags = { jsonOutput: false };\n for (let i = 0; i < flagArgs.length; i++) {\n const arg = flagArgs[i];\n if (!allowed.includes(arg)) {\n console.error(`Unknown flag: ${arg}`);\n process.exit(1);\n }\n if (arg === '--json') {\n out.jsonOutput = true;\n continue;\n }\n const v = flagArgs[++i];\n if (!v) { console.error(`${arg} requires a value`); process.exit(1); }\n if (arg === '--limit') {\n const n = Number.parseInt(v, 10);\n if (!Number.isFinite(n)) { console.error('--limit must be an integer'); process.exit(1); }\n if (n < 1) { console.error('--limit must be >= 1'); process.exit(1); }\n out.limit = n;\n } else if (arg === '--id') {\n out.filterId = v;\n } else if (arg === '--conversation-id') {\n out.conversationId = v;\n } else if (arg === '--hub-id') {\n out.hubId = v;\n } else if (arg === '--message-id') {\n out.messageId = v;\n }\n }\n return out;\n}\n\nfunction exitOnApiError(err: unknown): void {\n if (err instanceof ApiError) {\n if (err.status === 401) {\n console.error('Authentication failed. Run `wayai login` again.');\n process.exit(1);\n }\n if (err.status === 403) {\n console.error('Access denied. `wayai admin` requires platform-admin access.');\n console.error('Run `wayai whoami` to check your identity and platform-admin status.');\n process.exit(1);\n }\n if (err.status === 404) {\n console.error('Not found.');\n process.exit(1);\n }\n if (err.status === 429) {\n console.error('Rate limited. `wayai admin` is capped at 60 reads/hour per user.');\n process.exit(1);\n }\n if (err.status === 503) {\n console.error('Admin debug reads are currently disabled (platform kill switch).');\n process.exit(1);\n }\n if (err.status === 400) {\n console.error(`Bad request: ${err.body || err.message}`);\n process.exit(1);\n }\n console.error(err.message);\n process.exit(1);\n }\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n}\n\n/**\n * Render the standard debug rows result: --json passes through the raw payload;\n * default mode prints the table + footer with row count, truncation marker, and\n * the redacted-columns summary.\n */\nfunction printDebugRowsResult(\n data: {\n rows: Array<Record<string, unknown>>;\n redacted_columns: string[];\n truncated: boolean;\n limit: number;\n },\n jsonOutput: boolean,\n): void {\n if (jsonOutput) {\n console.log(JSON.stringify(data, null, 2));\n return;\n }\n\n if (data.rows.length === 0) {\n console.log('(no rows)');\n if (data.redacted_columns.length > 0) {\n console.log(`\\nredacted columns: ${data.redacted_columns.join(', ')}`);\n }\n return;\n }\n\n printRowsTable(data.rows);\n console.log('');\n console.log(`rows: ${data.rows.length}${data.truncated ? ` (truncated to ${data.limit})` : ''}`);\n if (data.redacted_columns.length > 0) {\n console.log(`redacted columns: ${data.redacted_columns.join(', ')}`);\n }\n}\n\n/**\n * Pretty-print rows as a columnar text table. Columns are the union of keys\n * across all rows, ordered by first appearance. Values are coerced to strings\n * and truncated at a per-column width so a single row with a huge blob doesn't\n * blow up the whole table.\n */\nfunction printRowsTable(rows: Array<Record<string, unknown>>): void {\n const COL_MAX = 80;\n const cols: string[] = [];\n for (const row of rows) for (const k of Object.keys(row)) if (!cols.includes(k)) cols.push(k);\n\n const widths: Record<string, number> = {};\n for (const c of cols) widths[c] = Math.min(COL_MAX, Math.max(c.length, ...rows.map((r) => formatValue(r[c]).length)));\n\n const header = cols.map((c) => c.padEnd(widths[c])).join(' | ');\n const divider = cols.map((c) => '-'.repeat(widths[c])).join('-+-');\n console.log(header);\n console.log(divider);\n for (const row of rows) {\n console.log(cols.map((c) => truncate(formatValue(row[c]), widths[c]).padEnd(widths[c])).join(' | '));\n }\n}\n\nfunction formatValue(v: unknown): string {\n if (v === null || v === undefined) return 'null';\n if (typeof v === 'string') return v;\n return JSON.stringify(v);\n}\n\nfunction truncate(s: string, n: number): string {\n return s.length > n ? s.slice(0, Math.max(1, n - 1)) + '…' : s;\n}\n\n// ---------------------------------------------------------------------------\n// Subcommands — Report (platform_report triage queue)\n//\n// Consumed by Claude Code Desktop's 15-min triage routine and by humans\n// running ad-hoc triage. Mutations (group/escalate/addressed/dismiss) drive\n// the state machine in PlatformDO, which is the sole owner of email side\n// effects (escalation, resolution, dismissal — `cli` (human) rows only).\n// ---------------------------------------------------------------------------\n\nfunction parseReportFlags(flagArgs: string[]): Record<string, string> {\n const out: Record<string, string> = {};\n for (let i = 0; i < flagArgs.length; i++) {\n const flag = flagArgs[i];\n if (!flag.startsWith('--')) continue;\n const key = flag.slice(2);\n const next = flagArgs[i + 1];\n if (next === undefined || next.startsWith('--')) {\n out[key] = 'true';\n } else {\n out[key] = next;\n i++;\n }\n }\n return out;\n}\n\nasync function runReportList(flagArgs: string[]): Promise<void> {\n const flags = parseReportFlags(flagArgs);\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n try {\n const result = await client.listAdminReports({\n status: flags.status,\n source: flags.source,\n limit: flags.limit ? Number(flags.limit) : undefined,\n offset: flags.offset ? Number(flags.offset) : undefined,\n since: flags.since,\n });\n\n if (flags.json === 'true') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n console.log(`Reports: ${result.data.length}/${result.total}`);\n for (const r of result.data) {\n const age = Math.floor((Date.now() - r.created_at) / 1000 / 60);\n const meta = [\n r.source,\n r.status,\n // Surface a broken Sentry reference (set at escalation) — these never auto-resolve.\n r.sentry_ref_status && r.sentry_ref_status !== 'valid' ? `sentry_ref:${r.sentry_ref_status}` : null,\n r.gh_issue_url ? `gh:${r.gh_issue_url}` : null,\n ]\n .filter(Boolean)\n .join(' · ');\n console.log(` ${r.report_id} [${meta}] ${age}m ago`);\n }\n } catch (err) {\n exitOnApiError(err);\n }\n}\n\nasync function runReportShow(positional: string[]): Promise<void> {\n const reportId = positional[0];\n if (!reportId) {\n console.error('wayai admin report show <report_id>');\n process.exit(1);\n }\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.getAdminReport(reportId);\n console.log(JSON.stringify(result.data, null, 2));\n } catch (err) {\n exitOnApiError(err);\n }\n}\n\nasync function runReportGroup(positional: string[]): Promise<void> {\n const [canonicalId, ...memberIds] = positional;\n if (!canonicalId || memberIds.length === 0) {\n console.error('wayai admin report group <canonical_id> <member_id> [<member_id> ...]');\n process.exit(1);\n }\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.groupAdminReports(canonicalId, memberIds);\n console.log(`Grouped ${result.grouped} member(s) under ${result.canonical_id}`);\n for (const s of result.skipped) {\n const reason =\n s.reason === 'different_gh_issue'\n ? `linked to a different GitHub issue (${s.detail})`\n : s.reason === 'grouped_elsewhere'\n ? `already grouped under ${s.detail}`\n : s.reason === 'terminal'\n ? `already ${s.detail} (terminal)`\n : 'not found';\n console.log(` skipped ${s.report_id} — ${reason}`);\n }\n } catch (err) {\n exitOnApiError(err);\n }\n}\n\nasync function runReportUngroup(positional: string[]): Promise<void> {\n const memberId = positional[0];\n if (!memberId) {\n console.error('wayai admin report ungroup <member_id>');\n process.exit(1);\n }\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.ungroupAdminReport(memberId);\n console.log(`Detached ${result.report.report_id} → ${result.report.status}`);\n } catch (err) {\n exitOnApiError(err);\n }\n}\n\nasync function runReportEscalate(positional: string[], flagArgs: string[]): Promise<void> {\n const reportId = positional[0];\n const flags = parseReportFlags(flagArgs);\n const ghUrl = flags.gh;\n if (!reportId || !ghUrl) {\n console.error('wayai admin report escalate <report_id> --gh <github_issue_url> [--verdict <text>]');\n process.exit(1);\n }\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.transitionAdminReport(reportId, {\n target: 'escalated',\n gh_issue_url: ghUrl,\n ai_verdict: flags.verdict,\n });\n console.log(`Report ${result.report.report_id} → ${result.report.status}`);\n // The backend cross-checks a sentry-sourced report's captured reference\n // against the live Sentry issue at escalation. A broken ref still escalates\n // (the bug may be real) but won't auto-resolve on close — flag it loudly.\n const refStatus = result.report.sentry_ref_status;\n if (refStatus === 'not_found') {\n console.log(` ⚠ Sentry reference not_found — the cited issue does not exist on Sentry. Auto-resolve on close is skipped; verify the reference.`);\n } else if (refStatus === 'mismatch') {\n console.log(` ⚠ Sentry reference mismatch — issue_id resolves but its short_id ≠ the captured one. Auto-resolve on close is skipped.`);\n } else if (refStatus === 'unverified') {\n console.log(` ℹ Sentry reference unverified — could not reach Sentry (no token / API error). Auto-resolve on close is skipped.`);\n }\n } catch (err) {\n exitOnApiError(err);\n }\n}\n\nasync function runReportShipped(positional: string[], flagArgs: string[]): Promise<void> {\n const reportId = positional[0];\n const flags = parseReportFlags(flagArgs);\n if (!reportId) {\n console.error('wayai admin report shipped <report_id> [--note <what shipped, for the reporter>]');\n process.exit(1);\n }\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n // `--note` is a value-flag; if omitted, parseReportFlags leaves it undefined and the\n // backend records a default. Don't pass the literal \"true\" from a value-less `--note`.\n const note = flags.note && flags.note !== 'true' ? flags.note : undefined;\n const result = await client.transitionAdminReport(reportId, { target: 'shipped', note });\n console.log(`Report ${result.report.report_id} → ${result.report.status} (awaiting reporter verification)`);\n } catch (err) {\n exitOnApiError(err);\n }\n}\n\nasync function runReportAddressed(positional: string[]): Promise<void> {\n const reportId = positional[0];\n if (!reportId) {\n console.error('wayai admin report addressed <report_id>');\n process.exit(1);\n }\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.transitionAdminReport(reportId, { target: 'addressed' });\n console.log(`Report ${result.report.report_id} → ${result.report.status}`);\n if (result.cascaded_report_ids.length > 0) {\n console.log(`Cascaded ${result.cascaded_report_ids.length} grouped member(s).`);\n }\n } catch (err) {\n exitOnApiError(err);\n }\n}\n\nasync function runReportDismiss(positional: string[], flagArgs: string[]): Promise<void> {\n const reportId = positional[0];\n const flags = parseReportFlags(flagArgs);\n const reason = flags.reason;\n if (!reportId || !reason) {\n console.error('wayai admin report dismiss <report_id> --reason <text> [--verdict <text>] [--final]');\n process.exit(1);\n }\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n // `--final` makes the dismissal non-contestable (the reporter can't dispute it). Use it to\n // settle a clearly-wrong reporter without waiting for the contest cap.\n const result = await client.transitionAdminReport(reportId, {\n target: 'dismissed',\n dismissal_reason: reason,\n ai_verdict: flags.verdict,\n final: flags.final === 'true',\n });\n console.log(`Report ${result.report.report_id} → ${result.report.status}${flags.final === 'true' ? ' (final — non-contestable)' : ''}`);\n } catch (err) {\n exitOnApiError(err);\n }\n}\n\nasync function runReportHold(positional: string[], flagArgs: string[]): Promise<void> {\n const reportId = positional[0];\n const flags = parseReportFlags(flagArgs);\n const reason = flags.reason;\n // Reason is mandatory: a hold with no recorded rationale defeats the whole point (an\n // auditable, dateable record of *why* this row is waiting another cycle).\n if (!reportId || !reason || reason === 'true') {\n console.error('wayai admin report hold <report_id> --reason <text>');\n console.error('Defers a pending report one triage cycle (records a note + bumps hold_count). Silent — no email.');\n process.exit(1);\n }\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.holdAdminReport(reportId, reason);\n console.log(\n `Report ${result.report.report_id} held (cycle ${result.report.hold_count}) — remains ${result.report.status}.`,\n );\n } catch (err) {\n exitOnApiError(err);\n }\n}\n\nasync function runReportUpdate(positional: string[], flagArgs: string[]): Promise<void> {\n const reportId = positional[0];\n // Use the dedicated content-flag parser (not parseReportFlags): it errors on a\n // value-less flag and keeps an explicit \"\" as a clear, so a malformed\n // `--error` can't silently persist the literal \"true\" into a content field.\n const { patch, error } = parseReportEditArgs(flagArgs);\n\n if (error) {\n console.error(error);\n process.exit(1);\n }\n if (!reportId || Object.keys(patch).length === 0) {\n console.error('wayai admin report update <report_id> [--title <t>] [--description <d>] [--error <e>] [--steps <s>] [--context <c>]');\n console.error('At least one field to change is required. Pass \"\" to clear error/steps/context.');\n process.exit(1);\n }\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.updateAdminReport(reportId, patch);\n console.log(`Report ${result.report_id} content updated (status: ${result.status}).`);\n if (result.status === 'escalated') {\n console.log('Note: this edit is queue-local — the linked GitHub issue body is NOT updated.');\n }\n console.log(JSON.stringify(result.raw_payload, null, 2));\n } catch (err) {\n exitOnApiError(err);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Subcommands — Notices (platform broadcasts, feed 2)\n// ---------------------------------------------------------------------------\n\nconst VALID_NOTICE_SEVERITIES = ['critical', 'warn', 'info'] as const satisfies readonly NoticeSeverity[];\n\nasync function runNoticeCreate(flagArgs: string[]): Promise<void> {\n const flags = parseReportFlags(flagArgs);\n const title = flags.title;\n if (!title || title === 'true') {\n console.error('wayai admin notice create --title <text> [--severity critical|warn|info] [--scope <scope>] [--body <text>] [--link <url>] [--starts <ISO>] [--ends <ISO>]');\n console.error('Authors a platform broadcast (feed 2). Severity defaults to info, scope to global.');\n process.exit(1);\n }\n const severity = (flags.severity ?? 'info') as NoticeSeverity;\n if (!VALID_NOTICE_SEVERITIES.includes(severity)) {\n console.error(`--severity must be one of: ${VALID_NOTICE_SEVERITIES.join(', ')}`);\n process.exit(1);\n }\n // Guard the value-less-flag sentinel (parseReportFlags maps a bare `--scope` to 'true')\n // so it fails locally with a clear message instead of as a backend regex 400.\n if (flags.scope === 'true') {\n console.error('--scope requires a value (e.g. global, provider:gemini, service:analytics)');\n process.exit(1);\n }\n\n const body: CreateNoticeBody = {\n severity,\n scope: flags.scope ?? 'global',\n title,\n ...(flags.body && flags.body !== 'true' ? { body: flags.body } : {}),\n ...(flags.link && flags.link !== 'true' ? { link: flags.link } : {}),\n ...(flags.starts && flags.starts !== 'true' ? { starts_at: flags.starts } : {}),\n ...(flags.ends && flags.ends !== 'true' ? { ends_at: flags.ends } : {}),\n };\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.createAdminNotice(body);\n const n = result.data;\n console.log(`Created notice ${n.notice_id} — [${n.severity} · ${n.scope}] ${n.title}`);\n } catch (err) {\n exitOnApiError(err);\n }\n}\n\nasync function runNoticeList(flagArgs: string[]): Promise<void> {\n const flags = parseReportFlags(flagArgs);\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.listAdminNotices({\n status: flags.status,\n limit: flags.limit ? Number(flags.limit) : undefined,\n offset: flags.offset ? Number(flags.offset) : undefined,\n });\n\n if (flags.json === 'true') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n console.log(`Notices: ${result.data.length}/${result.total}`);\n for (const n of result.data) {\n const meta = [n.severity, n.scope, n.status, n.ends_at ? `ends:${n.ends_at}` : null]\n .filter(Boolean)\n .join(' · ');\n console.log(` ${n.notice_id} [${meta}] ${n.title}`);\n }\n } catch (err) {\n exitOnApiError(err);\n }\n}\n\nasync function runNoticeResolve(positional: string[]): Promise<void> {\n const noticeId = positional[0];\n if (!noticeId) {\n console.error('wayai admin notice resolve <notice_id>');\n process.exit(1);\n }\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.resolveAdminNotice(noticeId);\n console.log(`Notice ${result.data.notice_id} resolved.`);\n } catch (err) {\n exitOnApiError(err);\n }\n}\n\nfunction printHelp(): void {\n console.error(`\nwayai admin — platform-admin diagnostic commands\n\nUsage:\n wayai admin do tables <type> <id>\n wayai admin do read <type> <id> <table> [--limit N] [--id X] [--json]\n\n wayai admin analytics tables\n wayai admin analytics read <table> [--conversation-id X] [--hub-id Y] [--message-id Z] [--limit N] [--json]\n\n wayai admin archive <hub_id> <conversation_id> [--message-id X] [--json]\n\n wayai admin observability <hub_id> <conversation_id> [--message-id X] [--json]\n\n wayai admin report list [--status STATUS] [--source SOURCE] [--limit N] [--offset N] [--since ISO] [--json]\n wayai admin report show <report_id>\n wayai admin report group <canonical_id> <member_id> [<member_id> ...]\n wayai admin report ungroup <member_id>\n wayai admin report escalate <report_id> --gh <github_issue_url> [--verdict <text>]\n wayai admin report shipped <report_id> [--note <what shipped, for the reporter>]\n wayai admin report addressed <report_id>\n wayai admin report dismiss <report_id> --reason <text> [--verdict <text>] [--final]\n wayai admin report hold <report_id> --reason <text>\n wayai admin report update <report_id> [--title <t>] [--description <d>] [--error <e>] [--steps <s>] [--context <c>]\n\n wayai admin notice create --title <text> [--severity critical|warn|info] [--scope <scope>] [--body <text>] [--link <url>] [--starts <ISO>] [--ends <ISO>]\n wayai admin notice list [--status active|resolved] [--limit N] [--offset N] [--json]\n wayai admin notice resolve <notice_id>\n\nSources:\n do Live DO SQLite (existing conversation, hub config, etc.).\n analytics ClickHouse projections (conversation, message, billing_event, schedule_event).\n archive R2 archive blob — canonical content for ended conversations after DO cleanup.\n observability R2 LLM observability — per-message OTel GenAI records (prompts, completions,\n tool calls, tokens, latency). Default lists all records for the conversation;\n --message-id drills into one. Use this admin variant when the caller has no\n hub access; otherwise prefer \\`wayai conversations <id> observability\\`.\n report platform_report triage queue. \\`list/show\\` are reads; \\`group/ungroup/\n escalate/addressed/dismiss\\` drive the state machine (which owns email\n fanout for cli (human) rows). \\`ungroup\\` detaches a grouped member back\n to pending (inverse of \\`group\\`). \\`hold\\` defers a pending row one cycle\n (records an internal note + bumps hold_count) without transitioning it —\n silent for every source. \\`update\\` amends content fields\n (title/description/error/steps/context) while pending/escalated — the\n dedup fingerprint stays frozen and no email fires. Agent/Sentry rows\n never trigger emails.\n notice platform_notice broadcasts (Status & Notices feed 2) — operator-authored\n \"Gemini degraded\" / \"Analytics delayed\" notices. \\`create\\` authors one\n (severity defaults to info, scope to global); \\`list\\` reads them\n (--status active|resolved); \\`resolve\\` ends an active notice.\n\nTypes (do): ${VALID_TYPES.join(' | ')}\nTables (analytics): ${VALID_ANALYTICS_TABLES.join(' | ')}\n\nEntity id forms (do):\n <uuid> Domain entity id (hub_id, org_id, conversation_id, user_id) —\n hashed via idFromName, same path as every other route.\n hex:<64-hex> Raw CF DO hex id — resolved via idFromString. Use when you\n only have the CF-level id (e.g. from orphan-audit logs, CF\n traces, zombie instances with no registry entry).\n platform Singleton — literal string, hex: form not supported.\n\nExamples:\n wayai admin do tables hub 018fab...\n wayai admin do read conversation <conv-id> message --limit 5 --json\n wayai admin analytics read message --conversation-id <conv-id>\n wayai admin analytics read conversation --conversation-id <conv-id>\n wayai admin archive <hub-id> <conv-id>\n wayai admin archive <hub-id> <conv-id> --message-id <msg-id> --json\n wayai admin observability <hub-id> <conv-id>\n wayai admin observability <hub-id> <conv-id> --message-id <msg-id> --json\n\nAudit + rate limit:\n Every successful read is logged as admin_debug_read (queryable in Grafana\n Loki — info-level events are NOT sent to Sentry). Capped at 60 reads/hour/user\n across all sources. Platform-admin grant required.\n`.trim());\n}\n","/**\n * wayai report create — submit a platform bug report to the triage queue.\n *\n * Usage:\n * wayai report create --title \"Title\" --description \"Description\"\n * wayai report create -t \"Title\" -d \"Description\" --hub <uuid> --error \"Error msg\"\n *\n * Auto-captures hub/org context from .wayai.yaml if present.\n *\n * The report lands in the platform_report queue (status=pending). A Claude\n * Code Desktop routine triages on a 15-min cadence: groups by root cause,\n * dismisses noise, escalates actionable clusters by opening one GitHub issue\n * per group. You'll receive a follow-up email on escalation, on resolution\n * (fix shipped), or on dismissal (polite-no with the reason). If your report\n * is silently grouped as a duplicate of another, you won't get a separate\n * email — you'll only hear from us when the underlying issue is resolved.\n */\n\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { requireAuth } from '../lib/auth.js';\nimport { readRepoConfig } from '../lib/repo-config.js';\nimport { ApiClient, ApiError } from '../lib/api-client.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nfunction getCliVersion(): string {\n try {\n const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'package.json'), 'utf-8'));\n return `cli@${pkg.version}`;\n } catch {\n return 'cli@unknown';\n }\n}\n\nexport async function reportCreateCommand(args: string[]): Promise<void> {\n // Parse args\n let title: string | undefined;\n let description: string | undefined;\n let source: string | undefined;\n let classification: string | undefined;\n let dedupKey: string | undefined;\n let hubId: string | undefined;\n let conversationId: string | undefined;\n let errorMessage: string | undefined;\n let steps: string | undefined;\n let context: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--title' || arg === '-t') {\n title = args[++i];\n } else if (arg === '--description' || arg === '-d') {\n description = args[++i];\n } else if (arg === '--source') {\n source = args[++i];\n } else if (arg === '--classification') {\n classification = args[++i];\n } else if (arg === '--dedup-key') {\n dedupKey = args[++i];\n } else if (arg === '--hub') {\n hubId = args[++i];\n } else if (arg === '--conversation') {\n conversationId = args[++i];\n } else if (arg === '--error' || arg === '-e') {\n errorMessage = args[++i];\n } else if (arg === '--steps' || arg === '-s') {\n steps = args[++i];\n } else if (arg === '--context') {\n context = args[++i];\n }\n }\n\n if (!title || !description) {\n console.error('Usage: wayai report create --title \"Title\" --description \"Description\"');\n console.error('');\n console.error('Required:');\n console.error(' -t, --title <text> Bug title');\n console.error(' -d, --description <text> Detailed description');\n console.error('');\n console.error('Optional:');\n console.error(' --source <value> Origin: cli (default) | review | security_audit');\n console.error(' --classification <value> Nature: bug (default) | flaky_test | security');\n console.error(' --dedup-key <text> Stable dedup key (e.g. \"<file>::<test>\")');\n console.error(' --hub <uuid> Hub ID (optional context for the bug report)');\n console.error(' --conversation <uuid> Conversation ID');\n console.error(' -e, --error <text> Error message or stack trace');\n console.error(' -s, --steps <text> Steps to reproduce');\n console.error(' --context <text> Additional context');\n process.exit(1);\n }\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n // Auto-capture from .wayai.yaml (optional — don't fail if missing)\n const repoConfig = readRepoConfig();\n const organizationId = repoConfig?.organization_id;\n\n try {\n const result = await client.submitReport({\n title,\n description,\n source,\n classification,\n dedup_key: dedupKey,\n organization_id: organizationId,\n hub_id: hubId,\n conversation_id: conversationId,\n error_message: errorMessage,\n steps_to_reproduce: steps,\n additional_context: context,\n client_version: getCliVersion(),\n });\n\n if (result.created) {\n console.log(`Report submitted: ${result.report_id}`);\n } else {\n console.log(`Report merged with existing: ${result.report_id}`);\n }\n console.log('A WayAI engineer (or one of our AI agents) will triage your report.');\n console.log('You\\'ll get an email on escalation, resolution, or dismissal — if your');\n console.log('report is silently grouped as a duplicate, you won\\'t get a separate email.');\n } catch (err) {\n if (err instanceof ApiError) {\n if (err.status === 429) {\n console.error('Rate limit exceeded. Please try again later.');\n } else if (err.status === 503) {\n console.error('Report submission is not currently available.');\n } else {\n console.error(`Failed to submit report: ${err.message}`);\n }\n process.exit(1);\n }\n throw err;\n }\n}\n","/**\n * wayai report — manage your own platform reports.\n *\n * Subcommands:\n * wayai report create <--title|-t> <--description|-d> [--error|-e] [--steps|-s] [--context] ...\n * wayai report edit <id> [--title|-t] [--description|-d] [--error|-e]\n * [--steps|-s] [--context]\n *\n * `create` submits a new report to the triage queue. `edit` amends the mutable\n * content of a report you filed via `wayai report create`\n * (title/description/error/steps/context), provided it is still `pending` (not\n * yet triaged). Editing never changes the dedup fingerprint and never re-emails\n * you. Once a report has been escalated/grouped/resolved, only a platform admin\n * can amend it — see `wayai admin report update`.\n */\n\nimport { requireAuth } from '../lib/auth.js';\nimport { ApiClient, ApiError } from '../lib/api-client.js';\nimport { parseReportEditArgs } from '../lib/report-edit-args.js';\nimport { reportCreateCommand } from './report-create.js';\n\nexport async function reportCommand(args: string[]): Promise<void> {\n const sub = args[0];\n switch (sub) {\n case 'create':\n await reportCreateCommand(args.slice(1));\n return;\n case 'edit':\n await reportEditCommand(args.slice(1));\n return;\n case 'list':\n await reportListCommand(args.slice(1));\n return;\n case 'get':\n await reportGetCommand(args.slice(1));\n return;\n case 'accept':\n await reportAcceptCommand(args.slice(1));\n return;\n case 'contest':\n await reportContestCommand(args.slice(1));\n return;\n default:\n printReportHelp();\n process.exit(1);\n }\n}\n\nfunction printReportHelp(): void {\n console.error(`\nwayai report — manage your own platform reports\n\nUsage:\n wayai report create <OPTIONS> Submit a new report to the triage queue\n wayai report edit <report_id> <OPTIONS> Amend your own pending report\n wayai report list [--status <s>] [--json] List your reports (newest first)\n wayai report get <report_id> [--json] Show a report's status + message thread\n wayai report accept <report_id> Accept a shipped fix (→ addressed)\n wayai report contest <report_id> --reason <text>\n Contest a shipped fix or a dismissal (→ triage)\n\nCreate options (--title and --description required):\n -t, --title <text> Bug title\n -d, --description <text> Detailed description\n -e, --error <text> Error message or stack trace\n -s, --steps <text> Steps to reproduce\n --context <text> Additional context\n (run \\`wayai report create\\` with no args for the full option list)\n\nEdit options (at least one required):\n -t, --title <text> New title\n -d, --description <text> New description\n -e, --error <text> New error message / stack trace (\"\" clears it)\n -s, --steps <text> New steps to reproduce (\"\" clears them)\n --context <text> New additional context (\"\" clears it)\n\nThe verification loop:\n After triage escalates and the fix ships, your report moves to 'shipped'. Poll\n \\`wayai report list --status shipped\\` to find it, then \\`accept\\` if the fix works or\n \\`contest --reason \"...\"\\` if it doesn't. You can also \\`contest\\` a 'dismissed' report\n you believe is real — it goes back to triage. Contests are bounded (a cap, and a\n triage 'final' dismissal); past those, contact support.\n\nNotes:\n Only your own \\`wayai report create\\` submissions can be read/acted on. Editing is\n allowed only while 'pending'; the dedup fingerprint stays frozen and no email is\n sent on an edit.\n`.trim());\n}\n\nasync function reportEditCommand(args: string[]): Promise<void> {\n const { reportId, patch, error } = parseReportEditArgs(args);\n\n if (error) {\n console.error(error);\n process.exit(1);\n }\n if (!reportId || Object.keys(patch).length === 0) {\n console.error('Usage: wayai report edit <report_id> [--title|-t] [--description|-d] [--error|-e] [--steps|-s] [--context]');\n console.error('At least one field to change is required. Pass \"\" to clear error/steps/context.');\n process.exit(1);\n }\n\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n\n try {\n const result = await client.editReport(reportId, patch);\n console.log(`Report updated: ${result.report_id} (status: ${result.status})`);\n console.log('The dedup fingerprint is unchanged and no notification was sent.');\n } catch (err) {\n if (err instanceof ApiError) {\n if (err.status === 400) {\n console.error(`Invalid edit: ${err.message}`);\n } else if (err.status === 404) {\n console.error('Report not found, or it was not filed by you.');\n } else if (err.status === 403) {\n console.error('This report is agent-authored and can only be edited by a platform admin.');\n } else if (err.status === 409) {\n console.error(`Cannot edit: ${err.message}`);\n } else if (err.status === 429) {\n console.error('Rate limit exceeded. Please try again later.');\n } else {\n console.error(`Failed to edit report: ${err.message}`);\n }\n process.exit(1);\n }\n throw err;\n }\n}\n\nasync function reportListCommand(args: string[]): Promise<void> {\n const status = flagValue(args, '--status');\n const json = args.includes('--json');\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.listMyReports(status);\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n if (result.data.length === 0) {\n console.log('No reports found.');\n return;\n }\n for (const r of result.data) {\n console.log(`${r.report_id} ${r.status.padEnd(10)} ${r.classification}`);\n }\n } catch (err) {\n reportActionError(err);\n }\n}\n\nasync function reportGetCommand(args: string[]): Promise<void> {\n const reportId = args.find((a) => !a.startsWith('--'));\n const json = args.includes('--json');\n if (!reportId) {\n console.error('Usage: wayai report get <report_id> [--json]');\n process.exit(1);\n }\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.getMyReport(reportId);\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n const { report, messages } = result;\n console.log(`Report ${report.report_id}`);\n console.log(` status: ${report.status}`);\n console.log(` classification: ${report.classification}`);\n if (report.contest_count > 0) console.log(` contests: ${report.contest_count}`);\n if (report.dismissal_final) console.log(' dismissal: final (non-contestable)');\n if (messages.length > 0) {\n console.log('\\n Thread:');\n for (const m of messages) {\n console.log(` [${m.author_role}] ${m.body}`);\n }\n }\n if (report.status === 'shipped') {\n console.log(`\\n This fix is shipped. Run \\`wayai report accept ${report.report_id}\\` if it works,`);\n console.log(` or \\`wayai report contest ${report.report_id} --reason \"...\"\\` if it does not.`);\n }\n } catch (err) {\n reportActionError(err);\n }\n}\n\nasync function reportAcceptCommand(args: string[]): Promise<void> {\n const reportId = args.find((a) => !a.startsWith('--'));\n if (!reportId) {\n console.error('Usage: wayai report accept <report_id>');\n process.exit(1);\n }\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.acceptReport(reportId);\n console.log(`Accepted. Report ${result.report.report_id} → ${result.report.status}.`);\n } catch (err) {\n reportActionError(err);\n }\n}\n\nasync function reportContestCommand(args: string[]): Promise<void> {\n const reportId = args.find((a) => !a.startsWith('--'));\n const reason = flagValue(args, '--reason');\n if (!reportId || !reason) {\n console.error('Usage: wayai report contest <report_id> --reason \"<why the fix/dismissal is wrong>\"');\n process.exit(1);\n }\n const { config, accessToken } = await requireAuth();\n const client = new ApiClient({ apiUrl: config.api_url, accessToken });\n try {\n const result = await client.contestReport(reportId, reason);\n console.log(`Contested. Report ${result.report.report_id} → ${result.report.status} (back to triage).`);\n } catch (err) {\n reportActionError(err);\n }\n}\n\n// Read the value following `flag` in argv (e.g. `--status shipped`).\nfunction flagValue(args: string[], flag: string): string | undefined {\n const i = args.indexOf(flag);\n return i >= 0 && i + 1 < args.length ? args[i + 1] : undefined;\n}\n\n// Shared ApiError → friendly message + exit for the reporter verbs (get/list/accept/contest).\nfunction reportActionError(err: unknown): never {\n if (err instanceof ApiError) {\n if (err.status === 404) {\n console.error('Report not found, or it was not filed by you.');\n } else if (err.status === 403) {\n console.error('This report is agent-authored and can only be handled by a platform admin.');\n } else if (err.status === 409) {\n // Conflict carries the actionable reason (wrong status, final dismissal, cap reached).\n console.error(err.message);\n } else if (err.status === 429) {\n console.error('Rate limit exceeded. Please try again later.');\n } else {\n console.error(`Request failed: ${err.message}`);\n }\n process.exit(1);\n }\n throw err;\n}\n","/**\n * wayai update — update CLI to the latest version\n */\n\nimport { execFileSync } from 'node:child_process';\nimport { captureException, closeSentry } from '../lib/sentry.js';\n\nexport async function updateCommand(pkg: { version: string }): Promise<void> {\n console.log(`Current version: ${pkg.version}`);\n console.log('Checking for updates...');\n try {\n // shell: true required for Windows where npm is a .cmd script\n const latest = execFileSync('npm', ['view', '@wayai/cli', 'version'], {\n timeout: 10000,\n shell: true,\n }).toString().trim();\n if (latest === pkg.version) {\n console.log(`Already on the latest version (${pkg.version}).`);\n } else {\n console.log(`Updating ${pkg.version} → ${latest}...`);\n execFileSync('npm', ['install', '-g', '@wayai/cli@latest'], {\n timeout: 60000,\n shell: true,\n stdio: 'inherit',\n });\n console.log(`Updated to ${latest}.`);\n }\n } catch (err) {\n captureException(err);\n await closeSentry();\n console.error('Update failed:', err instanceof Error ? err.message : String(err));\n console.error('Try manually: npm install -g @wayai/cli');\n process.exit(1);\n }\n}\n","#!/usr/bin/env node\n\n/**\n * @wayai/cli — sync hub configuration between local files and the platform\n *\n * Commands:\n * wayai login — authenticate via OAuth (browser)\n * wayai login --token — authenticate via API token (headless)\n * wayai logout — clear stored credentials\n * wayai status — show current auth and config status\n * wayai whoami — show the authenticated identity (--json supported)\n * wayai init — set up .wayai.yaml (pick organization)\n * wayai create-credential — create an organization credential\n * wayai update-credential — update / rotate an organization credential\n * wayai pull — fetch hub config and write local files\n * wayai push — parse local files, diff, and sync to preview (creates hub if new)\n * wayai org create — create a new organization (you become its owner)\n * wayai org <pull|push|diff> — sync org-scoped resources as code (org/ at repo root)\n * wayai use <hub> — lock this worktree to a specific hub\n * wayai unlock — clear the worktree hub lock\n * wayai sync-skills — sync skills to Anthropic/OpenAI provider connections\n * wayai sync-mcp — re-discover an MCP connection's tool/resource catalog\n * wayai analytics — show analytics summary and metrics\n * wayai delete-history — delete your conversations on a hub (--conversation-id <id> deletes just one)\n * wayai list — list organizations and hubs\n * wayai report create — report a platform bug (submits to the triage queue)\n * wayai update — update CLI to the latest version\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { execFile } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { initSentry, captureException, shouldReportToSentry, closeSentry } from './lib/sentry.js';\nimport { isNewerVersion, wantsHelp, shouldInterceptHelp } from './lib/utils.js';\nimport {\n CLI_CACHE_FILE,\n SKILL_CACHE_FILE,\n getVersionCachePath,\n readVersionCache,\n} from './lib/version-cache.js';\nimport {\n DEFAULT_SKILL_RAW_URL,\n findInstalledSkills,\n lowestInstalledVersion,\n parseFrontmatterVersion,\n} from './lib/skill-version.js';\nimport { findGitRoot } from './lib/workspace.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));\n\nconst [,, command, ...args] = process.argv;\n\n// Subcommands that render their own richer `--help`/`-h` output (and never run a\n// side effect on it). These fall through to their handler so the global-help\n// interception in main() doesn't shadow their command-specific help:\n// eval → commands/eval.ts (explicit case '--help')\n// admin → commands/admin.ts (fall-through printHelp)\n// report → commands/report.ts (fall-through printReportHelp)\nconst OWN_HELP_COMMANDS = new Set(['eval', 'admin', 'report']);\n\n// Initialize Sentry early (before any command runs)\ninitSentry(command);\n\nasync function main(): Promise<void> {\n // Intercept `--help`/`-h` for a side-effecting subcommand BEFORE dispatch, so\n // e.g. `wayai run-eval --help` prints help instead of executing the command\n // (which would create + run a billable eval session). Commands that render\n // their own command-specific help (OWN_HELP_COMMANDS) fall through to their\n // handler so their richer help isn't shadowed by the global help.\n if (shouldInterceptHelp(command, args, OWN_HELP_COMMANDS)) {\n printHelp();\n return;\n }\n\n switch (command) {\n case 'login': {\n const { loginCommand } = await import('./commands/login.js');\n await loginCommand(args);\n break;\n }\n case 'logout': {\n const { logoutCommand } = await import('./commands/logout.js');\n await logoutCommand();\n break;\n }\n case 'status': {\n const { statusCommand } = await import('./commands/status.js');\n await statusCommand(args, pkg);\n break;\n }\n case 'whoami': {\n const { whoamiCommand } = await import('./commands/whoami.js');\n await whoamiCommand(args);\n break;\n }\n case 'init': {\n const { initCommand } = await import('./commands/init.js');\n await initCommand(args);\n break;\n }\n case 'pull': {\n const { pullCommand } = await import('./commands/pull.js');\n await pullCommand(args);\n break;\n }\n case 'push': {\n const { pushCommand } = await import('./commands/push.js');\n await pushCommand(args);\n break;\n }\n case 'use': {\n const { useCommand } = await import('./commands/use.js');\n await useCommand(args);\n break;\n }\n case 'migrate': {\n const { migrateCommand } = await import('./commands/migrate.js');\n await migrateCommand(args);\n break;\n }\n case 'unlock': {\n const { unlockCommand } = await import('./commands/unlock.js');\n await unlockCommand(args);\n break;\n }\n case 'send-message': {\n const { sendMessageCommand } = await import('./commands/send-message.js');\n await sendMessageCommand(args);\n break;\n }\n case 'conversations': {\n const { conversationsCommand } = await import('./commands/conversations.js');\n await conversationsCommand(args);\n break;\n }\n case 'delete-history': {\n const { deleteHistoryCommand } = await import('./commands/delete-history.js');\n await deleteHistoryCommand(args);\n break;\n }\n case 'sync-skills': {\n const { syncSkillsCommand } = await import('./commands/sync-skills.js');\n await syncSkillsCommand(args);\n break;\n }\n case 'sync-mcp': {\n const { syncMcpCommand } = await import('./commands/sync-mcp.js');\n await syncMcpCommand(args);\n break;\n }\n case 'evals': {\n const { evalsCommand } = await import('./commands/evals.js');\n await evalsCommand(args);\n break;\n }\n case 'run-eval': {\n const { runEvalCommand } = await import('./commands/run-eval.js');\n await runEvalCommand(args);\n break;\n }\n case 'eval-results': {\n const { evalResultsCommand } = await import('./commands/eval-results.js');\n await evalResultsCommand(args);\n break;\n }\n case 'eval': {\n const { evalCommand } = await import('./commands/eval.js');\n await evalCommand(args);\n break;\n }\n case 'analytics': {\n const { analyticsCommand } = await import('./commands/analytics.js');\n await analyticsCommand(args);\n break;\n }\n case 'create-credential': {\n const { createCredentialCommand } = await import('./commands/create-credential.js');\n await createCredentialCommand(args);\n break;\n }\n case 'update-credential': {\n const { updateCredentialCommand } = await import('./commands/update-credential.js');\n await updateCredentialCommand(args);\n break;\n }\n case 'org': {\n const { orgCommand } = await import('./commands/org.js');\n await orgCommand(args);\n break;\n }\n case 'list': {\n const { listCommand } = await import('./commands/list.js');\n await listCommand(args);\n break;\n }\n case 'admin': {\n const { adminCommand } = await import('./commands/admin.js');\n await adminCommand(args);\n break;\n }\n case 'report': {\n const { reportCommand } = await import('./commands/report.js');\n await reportCommand(args);\n break;\n }\n case 'update': {\n const { updateCommand } = await import('./commands/update.js');\n await updateCommand(pkg);\n break;\n }\n case 'help':\n case '--help':\n case '-h':\n case undefined:\n printHelp();\n break;\n case '--version':\n case '-v':\n console.log(pkg.version);\n break;\n default:\n console.error(`Unknown command: ${command}`);\n printHelp();\n process.exit(1);\n }\n}\n\nfunction printHelp(): void {\n console.log(`\nwayai — WayAI CLI\n\nUsage:\n wayai <command> [options]\n\nCommands:\n login Authenticate via OAuth (opens browser)\n login --token Authenticate via API token (for headless/CI)\n logout Clear stored credentials\n status Show current auth and config status\n whoami Show the authenticated identity (supports --json)\n init Set up .wayai.yaml (pick organization)\n create-credential Create an organization credential (API key, token, etc.)\n update-credential Update / rotate an organization credential (by name)\n pull Fetch hub config and write local files\n push Parse local files, show diff, sync to preview (creates hub if new)\n org create Create a new organization (you become its owner)\n org <pull|push|diff> Sync org-scoped resources as code (wayai-ws/org/)\n use <hub> Lock this worktree to a specific hub (UUID or folder name)\n migrate Move a legacy repo to the wayai-ws/{hubs,org} layout\n unlock Clear the worktree hub lock\n send-message Send a test message to a preview hub\n conversations List or inspect conversations\n analytics Show analytics summary and metrics (use \\`analytics query\\` for structured ClickHouse queries)\n delete-history Delete your conversations on a hub (--conversation-id <id> for just one)\n evals List evaluation scenarios for the current hub (use \\`evals sql\\` for read-only SQL on eval results)\n run-eval Run all enabled evals and show results\n eval-results View results from a completed eval session\n eval capture Capture a real conversation as a scenario YAML\n sync-skills Sync skills to Anthropic/OpenAI provider connections\n sync-mcp Re-discover an MCP connection's tools (refresh stale schemas)\n list List organizations and hubs\n report create Report a platform bug (submits to the triage queue)\n report edit Amend your own pending report (title/description/error/steps/context)\n update Update CLI to the latest version\n\nFlags:\n --yes, -y Skip confirmation prompts (useful for CI and scripting)\n --hub <uuid|name> Target hub when the workspace has more than one (push, pull)\n --name <name> Credential name (create-credential; target for update-credential)\n --type <auth-type> Auth type: \"api_key\", \"bearer\", \"basic_auth\" (create-credential)\n --rename <name> New name for the credential (update-credential)\n --tag <name> Org tag to scope the credential — repeatable or comma-separated (create/update-credential)\n --environment <env> Credential environment: \"preview\", \"production\", \"all\" (create/update-credential)\n --stdin Read secret from stdin pipe (create/update-credential)\n --secret Prompt for the new secret interactively (update-credential)\n --org <uuid> Organization ID (create-credential, update-credential, list)\n --region <region> DO placement hint for a new org (org create) — e.g. wnam, weur, sam, apac\n --connection-id <uuid> Limit sync-skills to a specific connection\n --connection <name> MCP connection to re-sync — display name or UUID (sync-mcp)\n --enabled/--disabled Filter evals by status (evals)\n --no-wait Don't wait for eval session to complete (run-eval)\n --timeout <seconds> Max wait time for eval session (default: 600)\n --session <uuid> Specify eval session ID (eval-results)\n --eval <name> Filter by eval name (eval-results)\n --runs Show individual run details (eval-results)\n --json Output raw JSON (status, whoami, list, org create, eval-results, analytics, conversations)\n --period <period> Time period: 24h, 7d, 30d, 3m, 1y (analytics, conversations)\n --from <date> Start date ISO (2026-01-01) (analytics, conversations)\n --to <date> End date ISO (2026-01-31) (analytics, conversations)\n --metric <names> Comma-separated metric names (analytics) — for \\`analytics query\\` use \"col=...,agg=...[,alias=...,corr_with=...,level=...]\"\n --filter <expr> Filter expression (repeatable). \\`analytics\\`: \"<name> <op> <value>\". \\`analytics query\\`: \"<column> <op> <value>\"\n --group-by <cols> Comma-separated column paths (analytics query)\n --order-by <expr> \"<column>:asc|desc\" (analytics query, repeatable)\n --limit <n> Max rows (analytics query, max 10000)\n --list-metrics List available metrics for the hub (analytics)\n --version, -v Show CLI version\n\nOrg-scoped mode:\n Each repository is scoped to a single organization via .wayai.yaml\n (only \\`organization_id\\` is required). Hubs self-identify via \\`hub.yaml\\`\n inside their folder under \\`workspace/\\`.\n\n Run \\`wayai init\\` to pick the organization (add -y to skip prompts).\n pull/push operate on the single hub in the workspace, or pass\n \\`--hub <uuid|name>\\` to disambiguate when multiple hubs exist.\n\nWorktree hub lock:\n Each git checkout (main or linked worktree) can be locked to a single hub.\n push/pull refuse to run against a different hub once locked. The lock is\n auto-set on first successful pull (or new-hub creation) into an unlocked\n checkout. Use \\`wayai use <hub>\\` to bind manually and \\`wayai unlock\\` to clear.\n The lock lives at \\`<git-dir>/wayai-lock\\` and is naturally per-checkout.\n\nExamples:\n wayai login\n wayai init\n wayai pull\n wayai push\n wayai push -y\n `.trim());\n}\n\nconst SKIP_UPDATE_CHECK = ['--version', '-v', '--help', '-h', 'help', 'update'];\nconst UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours\n\nfunction isUpdateCheckDisabled(): boolean {\n return Boolean(\n process.env.NO_UPDATE_NOTIFIER ||\n process.env.WAYAI_NO_UPDATE_CHECK ||\n process.env.CI\n );\n}\n\nfunction checkForUpdates(): void {\n if (isUpdateCheckDisabled()) return;\n try {\n const cachePath = getVersionCachePath(CLI_CACHE_FILE);\n const cacheDir = dirname(cachePath);\n\n const cache = readVersionCache(CLI_CACHE_FILE);\n\n if (cache && Date.now() - cache.lastCheck < UPDATE_CHECK_INTERVAL_MS) {\n if (cache.latest && isNewerVersion(cache.latest, pkg.version)) {\n console.error(\n `\\nUpdate available: ${pkg.version} → ${cache.latest}\\nRun \\`wayai update\\` to update.`\n );\n }\n return;\n }\n\n // Write sentinel so concurrent/rapid runs don't spawn duplicate npm processes\n try {\n if (!existsSync(cacheDir)) mkdirSync(cacheDir, { recursive: true });\n writeFileSync(cachePath, JSON.stringify({ lastCheck: Date.now(), latest: cache?.latest ?? null }));\n } catch { /* ignore — check still runs, just without dedup */ }\n\n // shell: true required for Windows where npm is a .cmd script\n execFile(\n 'npm',\n ['view', '@wayai/cli', 'version'],\n { timeout: 5000, shell: true },\n (err, stdout) => {\n if (err) return;\n const latest = stdout.trim();\n try {\n writeFileSync(cachePath, JSON.stringify({ lastCheck: Date.now(), latest }));\n } catch { /* ignore cache write failures */ }\n if (latest && isNewerVersion(latest, pkg.version)) {\n console.error(\n `\\nUpdate available: ${pkg.version} → ${latest}\\nRun \\`wayai update\\` to update.`\n );\n }\n }\n );\n } catch { /* never block the CLI on update check failures */ }\n}\n\nfunction checkForSkillUpdates(): void {\n if (isUpdateCheckDisabled()) return;\n try {\n const projectRoot = findGitRoot() ?? process.cwd();\n const installs = findInstalledSkills(projectRoot);\n if (installs.length === 0) return;\n\n const localVersion = lowestInstalledVersion(installs);\n if (!localVersion) return;\n\n const cachePath = getVersionCachePath(SKILL_CACHE_FILE);\n const cacheDir = dirname(cachePath);\n const cache = readVersionCache(SKILL_CACHE_FILE);\n\n if (cache && Date.now() - cache.lastCheck < UPDATE_CHECK_INTERVAL_MS) {\n if (cache.latest && isNewerVersion(cache.latest, localVersion)) {\n console.error(\n `\\nSkill update available: ${localVersion} → ${cache.latest}\\nRun \\`npx skills add wayai-pro/wayai-skill -y\\` to update.`\n );\n }\n return;\n }\n\n // Sentinel so concurrent runs don't all hit GitHub\n try {\n if (!existsSync(cacheDir)) mkdirSync(cacheDir, { recursive: true });\n writeFileSync(cachePath, JSON.stringify({ lastCheck: Date.now(), latest: cache?.latest ?? null }));\n } catch { /* ignore */ }\n\n const url = process.env.WAYAI_SKILL_RAW_URL || DEFAULT_SKILL_RAW_URL;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 5000);\n fetch(url, { signal: controller.signal })\n .then((res) => res.ok ? res.text() : null)\n .then((text) => {\n clearTimeout(timer);\n if (!text) return;\n const latest = parseFrontmatterVersion(text);\n if (!latest) return;\n try {\n writeFileSync(cachePath, JSON.stringify({ lastCheck: Date.now(), latest }));\n } catch { /* ignore */ }\n if (isNewerVersion(latest, localVersion)) {\n console.error(\n `\\nSkill update available: ${localVersion} → ${latest}\\nRun \\`npx skills add wayai-pro/wayai-skill -y\\` to update.`\n );\n }\n })\n .catch(() => { clearTimeout(timer); /* network failure: silent */ });\n } catch { /* never block the CLI on skill check failures */ }\n}\n\nmain()\n .then(async () => {\n if (command && !SKIP_UPDATE_CHECK.includes(command) && !wantsHelp(args)) {\n checkForUpdates();\n checkForSkillUpdates();\n }\n await closeSentry();\n })\n .catch(async (err) => {\n if (shouldReportToSentry(err)) {\n captureException(err);\n }\n await closeSentry();\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n });\n"],"mappings":"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","names":["__dirname","pkg","command","captureException","path","util","objectUtil","path","errorUtil","errorMap","args","r","path","ctx","result","issues","elements","processed","ZodFirstPartyTypeKind","path","z","custom","paginationSchema","MAX_NAME_LENGTH","fs","path","args","fs","path","yaml","configPath","fs","path","resolve","year","month","day","parsed","readRepoConfig","args","command","existsSync","readFileSync","join","homedir","path","existsSync","readFileSync","join","yaml","path","fs","path","fs","path","os","configDir","configPath","crypto","resolve","path","readline","prompt","resolve","args","execFile","platform","execFileSync","fs","path","path","args","pkg","snapshot","parseArgs","args","parseArgs","existsSync","mkdirSync","writeFileSync","path","args","configPath","fs","path","crypto","MAX_RESOURCE_FILE_SIZE","fs","path","yaml","fs","path","yaml","fs","path","parseArgs","args","fs","path","yaml","parseArgs","args","path","args","execFileSync","fs","path","args","result","args","args","from","to","args","parseArgs","args","parseArgs","args","args","args","resolve","args","fs","path","yaml","parseArgs","args","args","evalCaptureCommand","normalizeAuthType","VALID_AUTH_TYPES","LEGACY_AUTH_TYPE_MAP","visibleLength","INVISIBLE_NAME_CHARS","containsKanbanPlaceholders","PLACEHOLDER_TOKENS","extractToolParameters","isRecord","isPrimitive","typeMatches","validateSchema","path","MAX_SCHEMA_DEPTH","ALLOWED_TYPES","schemaTypeIncludes","SUBSCHEMA_OBJECT_KEYWORDS","SUBSCHEMA_LIST_KEYWORDS","SUBSCHEMA_MAP_KEYWORDS","validateToolInputSchema","refineToolConfig","z","refineHubAsCodeCustomTools","custom","refineHubAsCodeKanbanStatuses","kanbanStatusesArraySchema","uuidSchema","paginationSchema","timestampSchema","idParamSchema","primaryRegionSchema","placementSourceSchema","orgIdParam","orgAdminIdParam","createOrganizationBody","updateOrganizationBody","addOrgAdminBody","AUTH_TYPE","ORG_CREDENTIAL_AUTH_TYPES","AUTH_TYPE_DISPLAY","AGENT_ROLES","SAFE_USER_ID_REGEX","SUMMARIZATION_THRESHOLD_MIN","SUMMARIZATION_THRESHOLD_MAX","summarizationThresholdField","monitorConfigField","agentIdParam","listAgentsQuery","agentConnectionsQuery","createAgentBody","updateAgentBody","SLUG_REGEX","slugSchema","MAX_KANBAN_STATUSES","MAX_FOLLOWUPS_PER_STATUS","MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES","RESERVED_TEMPLATE_DUMP_NAME","kanbanStatusSlugSchema","followupSchema","EXCLUSIVE_FLAG_PAIRS","kanbanStatusSchema","hubIdParam","hubAdminIdParam","hubUserIdParam","hubIdentityIdParam","hubTeamIdParam","hubTeamUserDeleteParam","hubSchemaQuery","createHubBody","updateHubBody","addHubAdminBody","addHubIdentityAuthorizationBody","contactDecisionBody","approveContactBody","listContactAccessQuery","createHubTeamBody","updateHubTeamBody","addHubTeamUserBody","reassignHubUserBody","replicatePreviewBody","claimCodeChannelParam","claimCodeDeleteParam","connectionIdParam","connectorIdParam","listConnectionsQuery","deleteConnectionQuery","addConnectionBody","editConnectionBody","registerWhatsappQuery","registerWhatsappBody","retryProvisioningQuery","resendDomainStatusQuery","toolIdParam","listToolsQuery","toolAgentQuery","deleteToolQuery","toolConnectionsQuery","nativeToolIdSchema","addNativeToolBody","addMcpToolBody","createCustomToolBody","updateCustomToolBody","updateToolExecutionConfigBody","initialValueCreateSchema","initialValueUpdateSchema","stateIdParam","listStatesQuery","stateNameSchema","createStateBody","updateStateBody","reorderStatesBody","orgTagIdParam","listOrgTagsQuery","createOrgTagBody","updateOrgTagBody","orgCredentialIdParam","listOrgCredentialsQuery","createOrgCredentialBody","updateOrgCredentialBody","orgResourceIdParam","orgResourceFileIdParam","orgResourceFolderIdParam","hubOrgResourceParam","listOrgResourcesQuery","orgIdQuery","createOrgResourceBody","updateOrgResourceBody","createOrgResourceFolderBody","updateOrgResourceFolderBody","uploadOrgResourceFileBody","updateOrgResourceFileBody","uploadOrgSkillZipBody","linkOrgResourceBody","resourceIdParam","listResourcesQuery","createResourceBody","updateResourceBody","syncSkillsBody","resourceFileIdParam","listResourceFilesQuery","createResourceFileBody","updateResourceFileBody","uploadResourceFileBody","uploadSkillZipBody","resourceFolderIdParam","listResourceFoldersQuery","createResourceFolderBody","updateResourceFolderBody","agentResourceQuery","hubResourceQuery","linkAgentResourceBody","updateAgentResourceBody","unlinkAgentResourceQuery","navItemSchema","hubCountResetBody","navItemCountResetBody","typingBody","analyticsHubIdParam","analyticsVariableIdParam","updateVariablePinBody","updateAnalyticsViewBody","NUMERIC_FILTER_OPS","TEXT_FILTER_OPS","CATEGORICAL_FILTER_OPS","VARIABLE_FILTER_OPS","STRUCTURED_QUERY_OPS","STRUCTURED_QUERY_AGGREGATIONS","filterValueSchema","conversationsBody","analyticsConversationIdParam","messagesQuery","conversationDetailDataQuery","analyticsDataBody","structuredQueryBody","analyticsSqlBody","analyticsSqlSchemaQuery","PACING_INTERVAL_MIN_MS","PACING_INTERVAL_MAX_MS","EVAL_RUN_DEADLINE_MIN_MS","EVAL_RUN_DEADLINE_MAX_MS","evalIdParam","sessionIdParam","scenarioSetIdParam","hubIdQuery","createEvalBody","updateEvalBody","getEvalsQuery","toggleEvalBody","bulkToggleEvalsBody","pacingConfigSchema","sessionConfigSchema","createSessionBody","getSessionsQuery","getSessionResultsQuery","getSessionRunsQuery","evalAnalyticsQuery","getSessionCostQuery","compareSessionsQuery","evalsSqlBody","evalsSqlSchemaQuery","exportResultsQuery","validateEvalBody","hubAgentsQuery","createScenarioSetBody","updateScenarioSetBody","scenarioSetsHubQuery","createScenarioFromConversationBody","getConversationsQuery","getMessagesQuery","updateUserBody","updateProfileBody","pathnameRegex","updatePreferencesBody","activityQuery","deletionModeSchema","deletionRequestBody","archiveHubIdParam","archiveConversationParams","archiveListQuery","archiveMessageObservabilityParams","conversationIdParam","claimBody","releaseBody","transferBody","closeBody","additionalContextPayloadSchema","kanbanUpdateBody","observabilityParams","observabilityListParams","deleteUserConversationsBody","sendMessageBody","listConversationsQuery","getConversationDetailParams","getConversationDetailQuery","listWhatsAppTemplatesQuery","sendWhatsAppTemplateBody","billingOrgIdParam","subscriptionItemParams","spendCapBody","growthPacksBody","portalSessionBody","checkoutSessionBody","updateBillingCurrencyBody","invoicesQuery","downloadBody","uploadQuery","signUrlBody","completionsBody","outboundSchemaQuery","templateIdParam","listTemplatesQuery","deleteTemplateQuery","templateStatusQuery","createTemplateBody","updateTemplateBody","submitTemplateBody","testTemplateBody","contactIdParam","listContactsQuery","createContactBody","updateContactBody","listIdParam","listListsQuery","listListContactsQuery","createListBody","updateListBody","addListContactsBody","removeListContactsBody","scheduleIdParam","listSchedulesQuery","listExecutionsQuery","createScheduleBody","updateScheduleBody","uuidPattern","ciUuidSchema","hubAsCodeConfigSchema","ciPullHubIdParam","ciBranchParam","ciPullQuery","ciHubsQuery","ciLookupQuery","ciBranchesQuery","ciSyncBody","ciPushBody","ciDiffBody","ciPublishBody","ciPublishPreviewBody","ciSyncMcpBody","ciOrgResourcesParam","orgResourcesConfigSchema","ciOrgResourcesPushBody","ciOrgResourcesDiffBody","adminOrgIdParam","adminOrgAdminIdParam","adminUserIdParam","adminPlanIdParam","adminOrganizationsQuery","adminUserSearchQuery","kanbanSlugMigrationQuery","adjustQuotaBody","updatePlanBody","addAdminUserBody","updatePlatformConfigBody","updateFreeOrgLimitBody","updatePricingPlanBody","dataExplorerSearchQuery","dataExplorerOrgIdParam","dataExplorerHubIdParam","dataExplorerConvIdParam","dataExplorerDoInstancesQuery","dataExplorerNsIdParam","dataExplorerKvKeysQuery","dataExplorerKvKeyParam","uuidOrHexId","dataExplorerDeleteOrgParam","dataExplorerDeleteHubParam","dataExplorerDeleteConvParam","dataExplorerDeleteUserParam","dataExplorerDeleteQuery","dataExplorerKvDeleteQuery","pitrDoNamespace","pitrBookmarkParam","pitrRestoreBody","healthSamplingTriggerBody","dataExplorerDebugDoType","DEBUG_READ_MAX_LIMIT","DEBUG_READ_DEFAULT_LIMIT","DEBUG_DO_HEX_PREFIX","debugDoEntityId","debugTableName","dataExplorerDebugTablesParam","dataExplorerDebugRowsParam","dataExplorerDebugRowsQuery","dataExplorerDebugAnalyticsTable","debugUuid","dataExplorerDebugAnalyticsRowsParam","dataExplorerDebugAnalyticsRowsQuery","debugHubConvParam","debugMessageIdQuery","whatsappCallbackBody","authMeResponse","wsTicketResponse","sessionCheckResponse","logoutResponse","browserParams","browserFoldersQuery","browserFilesQuery","stateOperationBody","conversationListResourcesQuery","conversationReadResourceQuery","listPendingSchedulesQuery","listHubAggregateSchedulesQuery","reportSourceSchema","intakeReportSourceSchema","reportClassificationSchema","reportStatusSchema","reportLocaleSchema","reportMessageAuthorRoleSchema","sentryRefStatusSchema","createReportBody","editReportBody","contestReportBody","reporterListQuery","listReportsQuery","GITHUB_ISSUE_URL_REGEX","githubIssueUrlSchema","transitionReportBody","groupReportsBody","holdReportBody","clickhouseReadyResponse","bootstrapQuery","requestSnapshotChunkMessage","MAX_NAME_LENGTH","MAX_VALUE_LENGTH","MAX_TAGS","MAX_TAG_LENGTH","MAX_SCOPE_HUBS","MAX_SCOPE_TAGS","vaultSecretScopeSchema","vaultCreateBody","vaultUpdateBody","PERMISSIONS","MAX_HUBS_PER_GRANT","MAX_HUB_TAGS_PER_GRANT","MAX_GRANTS","permissionEnum","grantScopeSchema","grantSchema","createTokenBody","tokenOrgIdParam","tokenGrantScopeSchema","tokenGrantSchema","tokenMetadataSchema","listTokensResponse","createTokenResponse","orgTokenSummarySchema","listOrgTokensResponse","invitePreviewQuery","invitePreviewResponse","discordTier","discordBillingCycle","discordMetadata","discordOAuthStartResponse","discordOAuthFinalizeBody","discordOAuthFinalizeResponse","discordDisconnectResponse","jsonSchemaSchema","hubUserIdentity","stateValueEntry","getHubUserContextResponse","updateHubUserBody","updateHubUserResponse","unlockHubUserNameResponse","stateResetParams","stateResetResponse","hubAlertsParam","hubAlertSeverity","hubAlert","hubAlertsListResponse","noticeSeveritySchema","noticeStatusSchema","NOTICE_SCOPE_REGEX","noticeScopeSchema","noticeLinkSchema","createNoticeBody","updateNoticeBody","listNoticesQuery","noticeIdParamSchema","args","result","NUMERIC_FILTER_OPS","TEXT_FILTER_OPS","CATEGORICAL_FILTER_OPS","VARIABLE_FILTER_OPS","STRUCTURED_QUERY_OPS","STRUCTURED_QUERY_AGGREGATIONS","LEGACY_AUTH_TYPE_MAP","VALID_AUTH_TYPES","parseArgs","args","VALID_AUTH_TYPES","parseArgs","args","fs","path","yaml","args","parseArgs","args","args","args","printHelp","positional","flagArgs","parseFlags","truncate","dataExplorerDebugDoType","dataExplorerDebugAnalyticsTable","readFileSync","dirname","join","fileURLToPath","pkg","args","args","execFileSync","pkg","captureException","readFileSync","writeFileSync","existsSync","mkdirSync","fileURLToPath","dirname","join","__dirname","printHelp","loginCommand","logoutCommand","statusCommand","whoamiCommand","initCommand","pullCommand","pushCommand","useCommand","migrateCommand","unlockCommand","sendMessageCommand","conversationsCommand","deleteHistoryCommand","syncSkillsCommand","syncMcpCommand","evalsCommand","runEvalCommand","evalResultsCommand","evalCommand","analyticsCommand","createCredentialCommand","updateCredentialCommand","orgCommand","listCommand","adminCommand","reportCommand","updateCommand","captureException"]}