@opengeni/contracts 5.6.0 → 5.7.0-canary.37111190284001

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 (60) hide show
  1. package/dist/agent-authored-durable-text.d.ts +9 -9
  2. package/dist/agent-config.d.ts +4 -1
  3. package/dist/atlassian.js +4 -3
  4. package/dist/bundled-skills.d.ts +3 -1
  5. package/dist/{chunk-HHZSZYYF.js → chunk-2ACYHZFB.js} +2 -1
  6. package/dist/chunk-2ACYHZFB.js.map +1 -0
  7. package/dist/chunk-TSCDAGET.js +75 -0
  8. package/dist/chunk-TSCDAGET.js.map +1 -0
  9. package/dist/{chunk-VYSAG53F.js → chunk-VUVXWYK7.js} +2 -2
  10. package/dist/{chunk-BHKAFQNX.js → chunk-Z6KUTGQS.js} +2967 -2793
  11. package/dist/chunk-Z6KUTGQS.js.map +1 -0
  12. package/dist/claude-subscription-usage.d.ts +94 -0
  13. package/dist/client-error-report.d.ts +80 -0
  14. package/dist/client-error-report.js +65 -1
  15. package/dist/client-error-report.js.map +1 -1
  16. package/dist/connect.js +4 -3
  17. package/dist/connect.js.map +1 -1
  18. package/dist/connection-authority.js +5 -4
  19. package/dist/direct-model-provider.d.ts +36 -0
  20. package/dist/google-drive.js +4 -3
  21. package/dist/google-drive.js.map +1 -1
  22. package/dist/host-mcp-bindings.js +5 -4
  23. package/dist/host-mcp-bindings.js.map +1 -1
  24. package/dist/index.d.ts +839 -44
  25. package/dist/index.js +62 -30
  26. package/dist/interaction.d.ts +4 -0
  27. package/dist/model-availability.d.ts +15 -0
  28. package/dist/model-context-inspector.d.ts +4 -0
  29. package/dist/organization-model-usage.d.ts +146 -0
  30. package/dist/organization-model-usage.js +67 -0
  31. package/dist/organization-model-usage.js.map +1 -0
  32. package/dist/organization-usage.d.ts +12 -0
  33. package/dist/personal-github.js +4 -3
  34. package/dist/personal-github.js.map +1 -1
  35. package/dist/remember.d.ts +2 -2
  36. package/dist/session-history-import.d.ts +4 -1
  37. package/dist/session-list-entries.d.ts +4 -0
  38. package/dist/session-list-entries.js +51 -0
  39. package/dist/session-list-entries.js.map +1 -0
  40. package/dist/session-titles.d.ts +1 -0
  41. package/dist/session-titles.js +3 -1
  42. package/package.json +9 -1
  43. package/src/agent-authored-durable-text.ts +14 -11
  44. package/src/agent-config.ts +5 -0
  45. package/src/bundled-skills.ts +1 -0
  46. package/src/claude-subscription-usage.ts +19 -0
  47. package/src/client-error-report.ts +144 -0
  48. package/src/company-brain-governed-writes.ts +2 -2
  49. package/src/direct-model-provider.ts +98 -0
  50. package/src/index.ts +277 -107
  51. package/src/interaction.ts +2 -0
  52. package/src/model-availability.ts +22 -0
  53. package/src/organization-model-usage.ts +72 -0
  54. package/src/organization-usage.ts +14 -0
  55. package/src/remember.ts +5 -6
  56. package/src/session-list-entries.ts +91 -0
  57. package/src/session-titles.ts +1 -1
  58. package/dist/chunk-BHKAFQNX.js.map +0 -1
  59. package/dist/chunk-HHZSZYYF.js.map +0 -1
  60. /package/dist/{chunk-VYSAG53F.js.map → chunk-VUVXWYK7.js.map} +0 -0
@@ -9,12 +9,12 @@
9
9
  * charter or global policy applies to every session in the workspace; a role
10
10
  * policy applies to every session bound to that role. At most three entries
11
11
  * compose at once (charter, global policy, matching role policy), so the
12
- * standing ceiling this budget implies is three times the per-entry cap.
12
+ * storage limit is shared with the human editor; prompt composition retains
13
+ * its separate UTF-8 byte bound.
13
14
  * - A preference is cheaper and in a different way: only its short title and
14
15
  * description descriptors are prompt-composed, while the full content is
15
16
  * retrieved on demand behind the exact attempt's retrieval handle. Its length
16
- * is therefore retrieval cost, not standing prompt cost, which is why it gets
17
- * more room rather than less.
17
+ * is therefore retrieval cost, not standing prompt cost.
18
18
  * - Organization identity and mission are always-on context for root sessions
19
19
  * across the whole organization. Historical company-profile list fields stay
20
20
  * in the storage contract for compatibility; nonempty values on an already-
@@ -22,18 +22,18 @@
22
22
  * label until an organization owner replaces the profile.
23
23
  * - Knowledge is retrieval evidence and never joins the always-composed prefix.
24
24
  *
25
- * These caps deliberately bind only agent-authored writes. The human-facing
26
- * limits (`WORKSPACE_INSTRUCTION_POLICY_CONTENT_MAX_CHARS`,
27
- * `PREFERENCE_REGISTRY_CONTENT_MAX_CHARS`, `COMPANY_PROFILE_SCALAR_MAX_CHARS`,
25
+ * Instruction writes share the human limit so localized edits can preserve
26
+ * existing long policies. The other caps bind only agent-authored writes.
27
+ * The human-facing limits (`PREFERENCE_REGISTRY_CONTENT_MAX_CHARS`, `COMPANY_PROFILE_SCALAR_MAX_CHARS`,
28
28
  * `COMPANY_PROFILE_ENTRY_MAX_CHARS`, `COMPANY_PROFILE_CONTENT_MAX_UTF8_BYTES`)
29
29
  * are unchanged: a person editing in the UI is making a deliberate, visible
30
30
  * choice, and lowering their limit would reject text they already typed.
31
31
  * Existing stored revisions are never rewritten; only new agent writes are
32
32
  * bounded.
33
33
  */
34
- /** One imperative rule, in 1-3 sentences, fits comfortably under this. */
35
- export declare const AGENT_AUTHORED_INSTRUCTION_POLICY_CONTENT_MAX_CHARS = 600;
36
- /** Retrieved on demand rather than always composed, so a little more room. */
34
+ /** Compatibility export: agents and humans use the same instruction storage limit. */
35
+ export declare const AGENT_AUTHORED_INSTRUCTION_POLICY_CONTENT_MAX_CHARS = 262144;
36
+ /** Retrieved on demand rather than always composed. */
37
37
  export declare const AGENT_AUTHORED_PREFERENCE_CONTENT_MAX_CHARS = 1200;
38
38
  /** `identity` and `mission`: a couple of sentences, not a positioning document. */
39
39
  export declare const AGENT_AUTHORED_COMPANY_PROFILE_SCALAR_MAX_CHARS = 400;
@@ -397,6 +397,8 @@ export declare const FIRST_PARTY_MCP_TOOL_CAPABILITIES: {
397
397
  readonly browser_act: "browser";
398
398
  readonly browser_clipboard: "browser";
399
399
  readonly browser_debug: "browser";
400
+ readonly browser_downloads: "browser";
401
+ readonly browser_download_save: "browser";
400
402
  readonly browser_auth: "browser";
401
403
  readonly interaction_request_human: "browser";
402
404
  readonly browser_identity: "browser";
@@ -586,7 +588,7 @@ export declare const AGENT_CAPABILITY_DESCRIPTIONS: Readonly<Record<AgentCapabil
586
588
  * when its capability or resource is present. The model-context inspector
587
589
  * reports them as metadata on the `operational_contract` layer.
588
590
  */
589
- export declare const AGENT_PROMPT_MODULE_IDS: readonly ["base_behavior", "runtime_mechanics", "renderer_markdown", "sandbox", "connected_machine", "repositories", "workspace_environment", "rig", "artifacts", "goals", "subagents", "knowledge", "skills", "admin", "attachments"];
591
+ export declare const AGENT_PROMPT_MODULE_IDS: readonly ["base_behavior", "runtime_mechanics", "renderer_markdown", "sandbox", "connected_machine", "repositories", "workspace_environment", "rig", "artifacts", "media", "goals", "subagents", "knowledge", "skills", "admin", "attachments"];
590
592
  export declare const AgentPromptModuleId: z.ZodEnum<{
591
593
  admin: "admin";
592
594
  artifacts: "artifacts";
@@ -595,6 +597,7 @@ export declare const AgentPromptModuleId: z.ZodEnum<{
595
597
  connected_machine: "connected_machine";
596
598
  goals: "goals";
597
599
  knowledge: "knowledge";
600
+ media: "media";
598
601
  renderer_markdown: "renderer_markdown";
599
602
  repositories: "repositories";
600
603
  rig: "rig";
package/dist/atlassian.js CHANGED
@@ -17,24 +17,25 @@ import {
17
17
  AtlassianSyncCadence,
18
18
  SaveAtlassianSourcesRequest,
19
19
  atlassianScopesAllowRead
20
- } from "./chunk-BHKAFQNX.js";
20
+ } from "./chunk-Z6KUTGQS.js";
21
21
  import "./chunk-4JGHSSB7.js";
22
22
  import "./chunk-5IXYF6XN.js";
23
- import "./chunk-HHZSZYYF.js";
24
23
  import "./chunk-NRMCVHAU.js";
25
24
  import "./chunk-WYBDERIY.js";
26
25
  import "./chunk-QR5D2IQC.js";
27
26
  import "./chunk-5Q54VCCH.js";
28
27
  import "./chunk-EK7NDGFR.js";
28
+ import "./chunk-2ACYHZFB.js";
29
29
  import "./chunk-KHHZTBP7.js";
30
- import "./chunk-O77VSFYZ.js";
31
30
  import "./chunk-NVJMJWLL.js";
32
31
  import "./chunk-SIOU2K4U.js";
33
32
  import "./chunk-YRKRZ6OF.js";
33
+ import "./chunk-O77VSFYZ.js";
34
34
  import "./chunk-YBW5JSA3.js";
35
35
  import "./chunk-3SIZGL3O.js";
36
36
  import "./chunk-RIY7GYQS.js";
37
37
  import "./chunk-JUFK3T4Q.js";
38
+ import "./chunk-TSCDAGET.js";
38
39
  import "./chunk-GRG7PHWQ.js";
39
40
  import "./chunk-YRXAWWCU.js";
40
41
  import "./chunk-BCS7WHCK.js";
@@ -6,6 +6,7 @@ export declare const BundledSkillId: z.ZodEnum<{
6
6
  "builtin:opengeni-help": "builtin:opengeni-help";
7
7
  "builtin:opengeni-presentations": "builtin:opengeni-presentations";
8
8
  "builtin:opengeni-projects": "builtin:opengeni-projects";
9
+ "builtin:opengeni-schedules": "builtin:opengeni-schedules";
9
10
  "builtin:opengeni-sites": "builtin:opengeni-sites";
10
11
  "builtin:opengeni-skills": "builtin:opengeni-skills";
11
12
  "builtin:opengeni-spreadsheets": "builtin:opengeni-spreadsheets";
@@ -20,12 +21,13 @@ export declare const BundledSkillSelection: z.ZodPipe<z.ZodArray<z.ZodEnum<{
20
21
  "builtin:opengeni-help": "builtin:opengeni-help";
21
22
  "builtin:opengeni-presentations": "builtin:opengeni-presentations";
22
23
  "builtin:opengeni-projects": "builtin:opengeni-projects";
24
+ "builtin:opengeni-schedules": "builtin:opengeni-schedules";
23
25
  "builtin:opengeni-sites": "builtin:opengeni-sites";
24
26
  "builtin:opengeni-skills": "builtin:opengeni-skills";
25
27
  "builtin:opengeni-spreadsheets": "builtin:opengeni-spreadsheets";
26
28
  "builtin:opengeni-video-generation": "builtin:opengeni-video-generation";
27
29
  "builtin:opengeni-visualize": "builtin:opengeni-visualize";
28
- }>>, z.ZodTransform<("builtin:document-parsing" | "builtin:opengeni-client" | "builtin:opengeni-documents" | "builtin:opengeni-help" | "builtin:opengeni-presentations" | "builtin:opengeni-projects" | "builtin:opengeni-sites" | "builtin:opengeni-skills" | "builtin:opengeni-spreadsheets" | "builtin:opengeni-video-generation" | "builtin:opengeni-visualize")[], ("builtin:document-parsing" | "builtin:opengeni-client" | "builtin:opengeni-documents" | "builtin:opengeni-help" | "builtin:opengeni-presentations" | "builtin:opengeni-projects" | "builtin:opengeni-sites" | "builtin:opengeni-skills" | "builtin:opengeni-spreadsheets" | "builtin:opengeni-video-generation" | "builtin:opengeni-visualize")[]>>;
30
+ }>>, z.ZodTransform<("builtin:document-parsing" | "builtin:opengeni-client" | "builtin:opengeni-documents" | "builtin:opengeni-help" | "builtin:opengeni-presentations" | "builtin:opengeni-projects" | "builtin:opengeni-schedules" | "builtin:opengeni-sites" | "builtin:opengeni-skills" | "builtin:opengeni-spreadsheets" | "builtin:opengeni-video-generation" | "builtin:opengeni-visualize")[], ("builtin:document-parsing" | "builtin:opengeni-client" | "builtin:opengeni-documents" | "builtin:opengeni-help" | "builtin:opengeni-presentations" | "builtin:opengeni-projects" | "builtin:opengeni-schedules" | "builtin:opengeni-sites" | "builtin:opengeni-skills" | "builtin:opengeni-spreadsheets" | "builtin:opengeni-video-generation" | "builtin:opengeni-visualize")[]>>;
29
31
  /** Undefined is defaults/inheritance; an explicit empty list disables bundles. */
30
32
  export declare function resolveBundledSkillSelection(requested: readonly BundledSkillId[] | undefined, parent: readonly BundledSkillId[] | undefined): BundledSkillId[] | undefined;
31
33
  export declare function withBundledSkillSelectionMetadata(metadata: Record<string, unknown>, ids: readonly BundledSkillId[] | undefined): Record<string, unknown>;
@@ -281,6 +281,7 @@ export {
281
281
  SESSION_TITLE_MAX_CHARACTERS,
282
282
  AUTOMATIC_SESSION_TITLE_MAX_GRAPHEMES,
283
283
  AUTOMATIC_SESSION_TITLE_FALLBACK,
284
+ PROMPT_PREVIEW_SCAN_MAX_CODE_UNITS,
284
285
  containsSensitiveAutomaticSessionTitleValue,
285
286
  boundAutomaticSessionTitle,
286
287
  normalizeAutomaticSessionTitle,
@@ -288,4 +289,4 @@ export {
288
289
  sessionTitleIsPending,
289
290
  deriveSessionDisplayTitle
290
291
  };
291
- //# sourceMappingURL=chunk-HHZSZYYF.js.map
292
+ //# sourceMappingURL=chunk-2ACYHZFB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/session-titles.ts"],"sourcesContent":["/** Human-authored session titles keep the existing public API ceiling. */\nexport const SESSION_TITLE_MAX_CHARACTERS = 200;\n\n/**\n * Automatic titles are intentionally much shorter than the manual rename\n * ceiling. This is measured in grapheme clusters so emoji and combining text\n * are never split into malformed display strings.\n */\nexport const AUTOMATIC_SESSION_TITLE_MAX_GRAPHEMES = 80;\n\n/**\n * Safe durable title used until semantic generation succeeds. It contains no\n * user prompt bytes, so provider failure/offline operation cannot leak a\n * credential or leave a raw prompt prefix in navigation surfaces.\n */\nexport const AUTOMATIC_SESSION_TITLE_FALLBACK = \"New conversation\";\n\n// Session creation accepts a body far larger than a navigation label. Bound\n// the source before any replace/split/normalization so a persisted large prompt\n// cannot amplify memory or CPU on every client render.\nexport const PROMPT_PREVIEW_SCAN_MAX_CODE_UNITS = 4_096;\n\nconst SESSION_ID_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;\n\nlet titleSegmenter: Intl.Segmenter | null | undefined;\n\nconst KNOWN_SENSITIVE_VALUE_PATTERNS = [\n /-----BEGIN [A-Z ]*PRIVATE KEY-----/iu,\n /\\bBearer\\s+[A-Za-z0-9._~+/=-]{8,}/iu,\n /\\b(?:sk-(?:proj-)?|gh[oprsu]_|github_pat_|glpat-|xox[baprs]-)[A-Za-z0-9_-]{8,}/iu,\n /\\bAKIA[0-9A-Z]{16}\\b/u,\n /\\bAIza[0-9A-Za-z_-]{20,}\\b/u,\n /\\beyJ[A-Za-z0-9_-]+\\.eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\b/u,\n /[?&](?:access_token|api_key|apikey|password|secret|token)=[^\\s&#]+/iu,\n] as const;\n\nconst URI_SCHEME_CANDIDATE_PATTERN = /\\b[a-z][a-z0-9+.-]*:\\S+/giu;\nconst WINDOWS_DRIVE_PATH_PATTERN = /^[a-z]:[\\\\/](?![\\\\/])[^:]*$/iu;\n\nconst SCHEMELESS_HOST_CANDIDATE_PATTERN =\n /\\b(?:www\\.)?(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?(?::\\d{1,5})?(?:[/?#][^\\s]*)?/giu;\n\nconst SCHEMELESS_LOCAL_NETWORK_PATTERNS = [\n /\\blocalhost(?:(?::\\d{1,5})(?:[/?#][^\\s]*)?|[/?#][^\\s]*)/iu,\n /\\b(?:(?:25[0-5]|2[0-4]\\d|1?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1?\\d?\\d)(?:(?::\\d{1,5})(?:[/?#][^\\s]*)?|[/?#][^\\s]*)/u,\n /\\[(?=[0-9a-f:.]*:[0-9a-f:.]*\\])[0-9a-f:.]+\\](?:(?::\\d{1,5})(?:[/?#][^\\s]*)?|[/?#][^\\s]*)/iu,\n] as const;\n\nconst FILE_LIKE_HOST_SUFFIXES = new Set([\n \"css\",\n \"html\",\n \"js\",\n \"json\",\n \"jsx\",\n \"lock\",\n \"md\",\n \"sql\",\n \"toml\",\n \"ts\",\n \"tsx\",\n \"xml\",\n \"yaml\",\n \"yml\",\n]);\n\n// These authorities are established framework/namespace notation whose exact\n// casing is meaningful. Keep this exception deliberately narrow: generic\n// PascalCase or uppercase authorities remain host-like because an uppercase\n// real domain (for example MICROSOFT.COM/Admin) must not bypass the URL gate.\nconst DOTTED_TECHNOLOGY_PATH_AUTHORITIES = new Set([\n \"ASP.NET\",\n \"AWS.SDK\",\n \"Microsoft.Extensions\",\n \"System.IO\",\n]);\n\nconst SECRET_ASSIGNMENT_CANDIDATE_PATTERN =\n /(?:^|[^A-Za-z0-9])(?:(['\"])([A-Za-z][A-Za-z0-9_. -]*)\\1|([A-Za-z][A-Za-z0-9_.-]*))\\s*[=:]\\s*[^\\s,;]+/gu;\n\nconst SECRET_LABEL_ASSIGNMENT_PATTERN =\n /\\b(?:api[ _-]?key|access[ _-]?token|auth[ _-]?token|credential|credentials|password|passwd|private[ _-]?key|secret|token)\\b\\s*[=:]\\s*[^\\s,;]+/iu;\n\nconst SENSITIVE_ASSIGNMENT_KEY_SUFFIXES = new Set([\n \"credential\",\n \"credentials\",\n \"password\",\n \"passwd\",\n \"secret\",\n \"token\",\n]);\n\nconst COMPACT_SENSITIVE_ASSIGNMENT_KEY_SUFFIXES = [\n \"apikey\",\n \"accesskey\",\n \"accesskeyid\",\n \"accesstoken\",\n \"authtoken\",\n \"credential\",\n \"credentials\",\n \"password\",\n \"passwd\",\n \"privatekey\",\n \"secret\",\n \"secretkey\",\n \"token\",\n] as const;\n\nconst SENSITIVE_ASSIGNMENT_KEY_WORD_SUFFIXES = [\n [\"api\", \"key\"],\n [\"access\", \"key\"],\n [\"access\", \"key\", \"id\"],\n [\"auth\", \"key\"],\n [\"private\", \"key\"],\n [\"secret\", \"key\"],\n] as const;\n\nfunction hasWordSuffix(words: readonly string[], suffix: readonly string[]): boolean {\n if (words.length < suffix.length) return false;\n const offset = words.length - suffix.length;\n return suffix.every((word, index) => words[offset + index] === word);\n}\n\nfunction containsSensitiveAssignment(value: string): boolean {\n for (const match of value.matchAll(SECRET_ASSIGNMENT_CANDIDATE_PATTERN)) {\n const key = match[2] ?? match[3];\n if (!key) continue;\n const words = key\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\")\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter(Boolean);\n const last = words.at(-1);\n if (last && SENSITIVE_ASSIGNMENT_KEY_SUFFIXES.has(last)) return true;\n if (last && COMPACT_SENSITIVE_ASSIGNMENT_KEY_SUFFIXES.some((suffix) => last.endsWith(suffix))) {\n return true;\n }\n if (SENSITIVE_ASSIGNMENT_KEY_WORD_SUFFIXES.some((suffix) => hasWordSuffix(words, suffix))) {\n return true;\n }\n }\n return false;\n}\n\nfunction containsUriScheme(value: string): boolean {\n for (const match of value.matchAll(URI_SCHEME_CANDIDATE_PATTERN)) {\n // A Windows drive path is the one scheme-shaped token accepted here. Keep\n // the exception exact: one separator after the drive letter and no later\n // colon, so x://host and a nested scheme remain rejected.\n if (!WINDOWS_DRIVE_PATH_PATTERN.test(match[0])) return true;\n }\n return false;\n}\n\nfunction isDottedTechnologyPath(candidate: string): boolean {\n if (/[?:#]/u.test(candidate)) return false;\n const [authority, ...pathSegments] = candidate.split(\"/\");\n if (!authority || pathSegments.length === 0 || pathSegments.some((segment) => !segment)) {\n return false;\n }\n if (\n !DOTTED_TECHNOLOGY_PATH_AUTHORITIES.has(authority) ||\n pathSegments.some((segment) => !/^[A-Z][A-Za-z0-9_-]*$/u.test(segment))\n ) {\n return false;\n }\n return true;\n}\n\nfunction containsSchemelessUrl(value: string): boolean {\n if (SCHEMELESS_LOCAL_NETWORK_PATTERNS.some((pattern) => pattern.test(value))) return true;\n\n for (const match of value.matchAll(SCHEMELESS_HOST_CANDIDATE_PATTERN)) {\n const candidate = match[0];\n if (candidate.toLowerCase().startsWith(\"www.\")) return true;\n if (!/[/?#]/u.test(candidate)) continue;\n\n const authority = candidate.split(/[/?#]/u, 1)[0] ?? \"\";\n const hostname = authority.replace(/:\\d{1,5}$/u, \"\");\n const suffix = hostname.split(\".\").at(-1)?.toLowerCase();\n if (suffix && FILE_LIKE_HOST_SUFFIXES.has(suffix)) continue;\n if (isDottedTechnologyPath(candidate)) continue;\n return true;\n }\n return false;\n}\n\nconst OPAQUE_IDENTIFIER_PATTERN =\n /\\b(?=[A-Za-z0-9_-]{32,}\\b)(?=[A-Za-z0-9_-]*[A-Za-z])(?=[A-Za-z0-9_-]*\\d)[A-Za-z0-9_-]+\\b/u;\n\nconst DEFAULT_IGNORABLE_CODE_POINTS = /\\p{Default_Ignorable_Code_Point}+/gu;\nconst ESCAPED_QUOTE_DELIMITERS = /\\\\+(?=[\"'])/gu;\n\nconst TITLE_LABEL_PATTERN =\n /^(?:(?:suggested|generated|concise)\\s+)?(?:(?:session|chat|conversation|task)\\s+)?title\\s*[:\\-–—]\\s*/iu;\n\nconst LEADING_BOILERPLATE_PATTERNS = [\n /^(?:hi|hello|hey)(?:\\s+there)?\\s*[,!:.\\-–—]*\\s*/iu,\n /^(?:i\\s+(?:would\\s+like|want|need)\\s+you\\s+to|i['’]d\\s+like\\s+you\\s+to)\\s+/iu,\n /^(?:please\\s+)?(?:can|could|would|will)\\s+you\\s+/iu,\n /^(?:your|the)\\s+(?:task|job)\\s+is\\s+to\\s+/iu,\n /^(?:please\\s+)?help\\s+me\\s+(?:to\\s+)?/iu,\n /^please(?:\\s*[,!:.\\-–—]+\\s*|\\s+|$)/iu,\n] as const;\n\nfunction automaticTitleDetectionValue(value: string): string {\n // Detection uses a compatibility-normalized shadow value so fullwidth\n // punctuation/letters, invisible token splits, and serialized quote\n // delimiters cannot evade the policy.\n // The accepted title itself stays byte-for-byte in the user's language and\n // emoji form; this shadow is never returned or persisted.\n return value\n .normalize(\"NFKC\")\n .replace(DEFAULT_IGNORABLE_CODE_POINTS, \"\")\n .replace(ESCAPED_QUOTE_DELIMITERS, \"\");\n}\n\nfunction hasVisibleAutomaticTitleContent(value: string): boolean {\n return automaticTitleDetectionValue(value).trim().length > 0;\n}\n\n/**\n * Whether a bounded automatic-title candidate contains a credential, URL, or\n * opaque identifier that must stay out of navigation and other display-title\n * surfaces. Callers handling an unbounded source must bound it before invoking\n * this helper.\n */\nexport function containsSensitiveAutomaticSessionTitleValue(value: string): boolean {\n const detectionValue = automaticTitleDetectionValue(value);\n\n if (KNOWN_SENSITIVE_VALUE_PATTERNS.some((pattern) => pattern.test(detectionValue))) return true;\n if (containsUriScheme(detectionValue)) return true;\n if (containsSchemelessUrl(detectionValue)) return true;\n if (SECRET_LABEL_ASSIGNMENT_PATTERN.test(detectionValue)) return true;\n if (containsSensitiveAssignment(detectionValue)) return true;\n if (OPAQUE_IDENTIFIER_PATTERN.test(detectionValue)) return true;\n return false;\n}\n\nfunction stripAutomaticTitleBoilerplate(value: string): string {\n let title = value;\n for (let pass = 0; pass < 4; pass += 1) {\n const before = title;\n title = title\n .replace(/^(?:```[^\\n]*|[\\s#>*_`\"'“”‘’\\-–—]+)+/u, \"\")\n .replace(TITLE_LABEL_PATTERN, \"\");\n for (const pattern of LEADING_BOILERPLATE_PATTERNS) {\n title = title.replace(pattern, \"\");\n }\n title = title.trim();\n if (title === before) break;\n }\n return title;\n}\n\nconst AUTOMATIC_TITLE_TRAILING_PUNCTUATION = /[\\s.!?,;:\\-–—]+$/u;\n\n// Closing quote and markdown marks, mapped to the distinct opening mark that\n// would pair with them inside the title.\nconst TRAILING_WRAPPER_MARKS = new Map<string, string | null>([\n ['\"', null],\n [\"'\", null],\n [\"`\", null],\n [\"*\", null],\n [\"”\", \"“\"],\n [\"’\", \"‘\"],\n [\"»\", \"«\"],\n]);\n\n/**\n * Remove trailing punctuation and a closing quote or markdown mark whose\n * opening counterpart was already stripped as a leading wrapper, so\n * `\"Pod Crash Debugging\"` and `**Pod Crash Debugging**` do not keep a dangling\n * closing mark. A mark that still pairs with one inside the title stays.\n */\nfunction trimAutomaticTitleEnd(value: string): string {\n let title = value;\n for (let pass = 0; pass < 4; pass += 1) {\n const before = title;\n title = title.replace(AUTOMATIC_TITLE_TRAILING_PUNCTUATION, \"\");\n const last = title.at(-1);\n const opening = last === undefined ? undefined : TRAILING_WRAPPER_MARKS.get(last);\n if (last !== undefined && opening !== undefined) {\n let rest = title;\n while (rest.endsWith(last)) rest = rest.slice(0, -last.length);\n if (!rest.includes(last) && (opening === null || !rest.includes(opening))) {\n title = rest;\n }\n }\n if (title === before) break;\n }\n return title.trim();\n}\n\nfunction automaticTitleGraphemes(value: string): string[] {\n if (titleSegmenter === undefined) {\n titleSegmenter =\n typeof Intl.Segmenter === \"function\"\n ? new Intl.Segmenter(undefined, { granularity: \"grapheme\" })\n : null;\n }\n if (titleSegmenter) {\n return Array.from(titleSegmenter.segment(value), (part) => part.segment);\n }\n\n // Older embedded runtimes may not ship Intl.Segmenter. Preserve surrogate\n // pairs plus common combining/emoji sequences instead of failing module load\n // or slicing UTF-16 code units.\n const graphemes: string[] = [];\n for (const point of value) {\n const prior = graphemes.at(-1);\n if (\n prior &&\n (/^[\\p{Mark}\\u{FE0E}\\u{FE0F}\\p{Emoji_Modifier}]$/u.test(point) ||\n point === \"\\u200d\" ||\n prior.endsWith(\"\\u200d\"))\n ) {\n graphemes[graphemes.length - 1] = `${prior}${point}`;\n } else {\n graphemes.push(point);\n }\n }\n return graphemes;\n}\n\n/** Bound an already-normalized automatic-title candidate without splitting graphemes. */\nexport function boundAutomaticSessionTitle(value: string): string {\n const words = value.split(/\\s+/u);\n const wordBounded = words.length > 10 ? words.slice(0, 10).join(\" \") : value;\n const graphemes = automaticTitleGraphemes(wordBounded);\n if (graphemes.length <= AUTOMATIC_SESSION_TITLE_MAX_GRAPHEMES) return wordBounded;\n\n const prefix = graphemes.slice(0, AUTOMATIC_SESSION_TITLE_MAX_GRAPHEMES).join(\"\");\n const lastWhitespace = prefix.search(/\\s+\\S*$/u);\n return (lastWhitespace >= 16 ? prefix.slice(0, lastWhitespace) : prefix).trimEnd();\n}\n\n/**\n * Normalize a model/system-authored title before it reaches durable session\n * metadata. Human renames intentionally do not use this path.\n *\n * Returns null when the candidate is empty, only boilerplate, or appears to\n * contain a credential/opaque prompt value. Callers should retain the current\n * title (normally {@link AUTOMATIC_SESSION_TITLE_FALLBACK}) in that case.\n */\nexport function normalizeAutomaticSessionTitle(value: string): string | null {\n const firstLine = value\n .replace(/[\\u0000-\\u001f\\u007f-\\u009f]+/gu, \"\\n\")\n .split(/\\n+/u)\n .map((line) => line.trim())\n .find(Boolean);\n if (\n !firstLine ||\n !hasVisibleAutomaticTitleContent(firstLine) ||\n containsSensitiveAutomaticSessionTitleValue(firstLine)\n ) {\n return null;\n }\n\n let title = trimAutomaticTitleEnd(\n stripAutomaticTitleBoilerplate(firstLine).replace(/\\s+/gu, \" \"),\n );\n if (\n !title ||\n !hasVisibleAutomaticTitleContent(title) ||\n containsSensitiveAutomaticSessionTitleValue(title)\n ) {\n return null;\n }\n\n title = trimAutomaticTitleEnd(boundAutomaticSessionTitle(title));\n if (!title || !hasVisibleAutomaticTitleContent(title)) return null;\n return title;\n}\n\nexport type SessionDisplayTitleInput = {\n id?: string | null | undefined;\n title?: string | null | undefined;\n titleSource?: \"user\" | \"agent\" | null | undefined;\n initialMessage?: string | null | undefined;\n metadata?: Readonly<Record<string, unknown>> | undefined;\n};\n\nexport type SessionDisplayTitleOptions = {\n /** Optional metadata fields to try before the opening-prompt preview. */\n metadataKeys?: readonly string[] | undefined;\n};\n\n/**\n * Derive a bounded, sensitive-safe preview from the opening prompt.\n *\n * Unsafe leading lines are skipped instead of forcing the whole session back\n * to a generic label. This covers prompts that begin with a pasted URL or\n * identifier followed by an ordinary natural-language request on the next\n * line, without putting the rejected value into navigation surfaces.\n */\nexport function deriveAutomaticSessionTitlePreview(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n\n const lines = value\n .slice(0, PROMPT_PREVIEW_SCAN_MAX_CODE_UNITS)\n .replace(/[\\u0000-\\u001f\\u007f-\\u009f]+/gu, \"\\n\")\n .split(/\\n+/u);\n\n for (const candidate of lines) {\n const line = candidate.trim();\n if (!line || containsSensitiveAutomaticSessionTitleValue(line)) continue;\n\n const preview = boundAutomaticSessionTitle(line.replace(/\\s+/gu, \" \"))\n .replace(/[\\s.!?,;:\\-–—]+$/u, \"\")\n .trim();\n if (preview) return preview;\n }\n\n return null;\n}\n\nfunction automaticSessionReferenceTitle(id: unknown): string {\n const sessionId = typeof id === \"string\" ? id.trim() : \"\";\n return SESSION_ID_PATTERN.test(sessionId)\n ? `Conversation ${sessionId.slice(0, 13)}`\n : AUTOMATIC_SESSION_TITLE_FALLBACK;\n}\n\n/**\n * Whether the durable title still represents the automatic-title pending state.\n * A user-authored title always wins, even when its literal value is the marker.\n */\nexport function sessionTitleIsPending(input: SessionDisplayTitleInput): boolean {\n const title = input.title?.trim() ?? \"\";\n return input.titleSource !== \"user\" && (!title || title === AUTOMATIC_SESSION_TITLE_FALLBACK);\n}\n\n/**\n * Derive the title a human-facing client should display for a session.\n *\n * A semantic agent title or human rename wins. While automatic naming is still\n * pending, clients show a short, sensitive-safe preview of the opening prompt.\n * If no safe prompt text exists, a UUID-derived reference keeps real sessions\n * distinguishable without exposing prompt bytes. The durable pending marker is\n * therefore an internal lifecycle value rather than the ordinary visible name.\n */\nexport function deriveSessionDisplayTitle(\n input: SessionDisplayTitleInput,\n options: SessionDisplayTitleOptions = {},\n): string {\n const title = input.title?.trim() ?? \"\";\n if (input.titleSource === \"user\") {\n return title || automaticSessionReferenceTitle(input.id);\n }\n if (title && !sessionTitleIsPending(input)) {\n return title;\n }\n\n for (const key of options.metadataKeys ?? []) {\n const value = input.metadata?.[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value.trim();\n }\n }\n\n return (\n deriveAutomaticSessionTitlePreview(input.initialMessage) ??\n automaticSessionReferenceTitle(input.id)\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,75 @@
1
+ // src/organization-usage.ts
2
+ import { z } from "zod";
3
+ var OrganizationUsagePeriod = z.enum(["today", "week", "month", "ytd"]);
4
+ var OrganizationUsageQuery = z.object({
5
+ period: OrganizationUsagePeriod.default("month")
6
+ });
7
+ var OrganizationUsageWorkspacePageQuery = OrganizationUsageQuery.extend({
8
+ until: z.string().datetime(),
9
+ afterWorkspaceId: z.string().uuid().optional()
10
+ });
11
+ var OrganizationUsageTotal = z.object({
12
+ eventType: z.string(),
13
+ unit: z.string(),
14
+ quantity: z.string().regex(/^-?\d+$/),
15
+ eventCount: z.string().regex(/^\d+$/)
16
+ });
17
+ var OrganizationUsagePersonalWorkspace = z.object({
18
+ membershipId: z.string().uuid(),
19
+ totals: z.array(OrganizationUsageTotal)
20
+ });
21
+ var OrganizationUsageSummary = z.object({
22
+ accountId: z.string().uuid(),
23
+ period: OrganizationUsagePeriod,
24
+ since: z.string().datetime(),
25
+ until: z.string().datetime(),
26
+ granularity: z.enum(["hour", "day"]),
27
+ totals: z.array(OrganizationUsageTotal),
28
+ buckets: z.array(z.object({ bucket: z.string(), totals: z.array(OrganizationUsageTotal) })),
29
+ workspaces: z.array(
30
+ z.object({
31
+ workspaceId: z.string().uuid(),
32
+ name: z.string().nullable(),
33
+ totals: z.array(OrganizationUsageTotal)
34
+ })
35
+ ).max(50),
36
+ nextWorkspaceCursor: z.string().uuid().nullable(),
37
+ /**
38
+ * Usage in each member's Personal workspace, keyed by the owner's
39
+ * organization membership: amounts only, never the workspace's id, name or
40
+ * content. Only Personal workspaces with usage in the period, the 50 that
41
+ * spent the most. Absent before migration 0543, hence the defaults.
42
+ */
43
+ personalWorkspaces: z.array(OrganizationUsagePersonalWorkspace).max(50).default([]),
44
+ /** How many Personal workspaces had usage in the period, listed or not. */
45
+ personalWorkspaceCount: z.number().int().nonnegative().default(0),
46
+ /** Other people's Only-me chats in shared workspaces: member amounts only. */
47
+ privateChats: z.array(
48
+ z.object({
49
+ workspaceId: z.string().uuid(),
50
+ membershipId: z.string().uuid().nullable(),
51
+ name: z.string().nullable(),
52
+ totals: z.array(OrganizationUsageTotal)
53
+ })
54
+ ).default([]),
55
+ privateChatsTruncated: z.boolean().default(false)
56
+ });
57
+ var OrganizationUsageWorkspacePage = OrganizationUsageSummary.omit({
58
+ totals: true,
59
+ buckets: true,
60
+ personalWorkspaces: true,
61
+ personalWorkspaceCount: true,
62
+ privateChats: true,
63
+ privateChatsTruncated: true
64
+ });
65
+
66
+ export {
67
+ OrganizationUsagePeriod,
68
+ OrganizationUsageQuery,
69
+ OrganizationUsageWorkspacePageQuery,
70
+ OrganizationUsageTotal,
71
+ OrganizationUsagePersonalWorkspace,
72
+ OrganizationUsageSummary,
73
+ OrganizationUsageWorkspacePage
74
+ };
75
+ //# sourceMappingURL=chunk-TSCDAGET.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/organization-usage.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const OrganizationUsagePeriod = z.enum([\"today\", \"week\", \"month\", \"ytd\"]);\nexport type OrganizationUsagePeriod = z.infer<typeof OrganizationUsagePeriod>;\nexport const OrganizationUsageQuery = z.object({\n period: OrganizationUsagePeriod.default(\"month\"),\n});\nexport const OrganizationUsageWorkspacePageQuery = OrganizationUsageQuery.extend({\n until: z.string().datetime(),\n afterWorkspaceId: z.string().uuid().optional(),\n});\n// PostgreSQL SUM(bigint) must never pass through a JavaScript number.\nexport const OrganizationUsageTotal = z.object({\n eventType: z.string(),\n unit: z.string(),\n quantity: z.string().regex(/^-?\\d+$/),\n eventCount: z.string().regex(/^\\d+$/),\n});\n/** One member's Personal workspace, as usage only. */\nexport const OrganizationUsagePersonalWorkspace = z.object({\n membershipId: z.string().uuid(),\n totals: z.array(OrganizationUsageTotal),\n});\nexport type OrganizationUsagePersonalWorkspace = z.infer<typeof OrganizationUsagePersonalWorkspace>;\nexport const OrganizationUsageSummary = z.object({\n accountId: z.string().uuid(),\n period: OrganizationUsagePeriod,\n since: z.string().datetime(),\n until: z.string().datetime(),\n granularity: z.enum([\"hour\", \"day\"]),\n totals: z.array(OrganizationUsageTotal),\n buckets: z.array(z.object({ bucket: z.string(), totals: z.array(OrganizationUsageTotal) })),\n workspaces: z\n .array(\n z.object({\n workspaceId: z.string().uuid(),\n name: z.string().nullable(),\n totals: z.array(OrganizationUsageTotal),\n }),\n )\n .max(50),\n nextWorkspaceCursor: z.string().uuid().nullable(),\n /**\n * Usage in each member's Personal workspace, keyed by the owner's\n * organization membership: amounts only, never the workspace's id, name or\n * content. Only Personal workspaces with usage in the period, the 50 that\n * spent the most. Absent before migration 0543, hence the defaults.\n */\n personalWorkspaces: z.array(OrganizationUsagePersonalWorkspace).max(50).default([]),\n /** How many Personal workspaces had usage in the period, listed or not. */\n personalWorkspaceCount: z.number().int().nonnegative().default(0),\n /** Other people's Only-me chats in shared workspaces: member amounts only. */\n privateChats: z\n .array(\n z.object({\n workspaceId: z.string().uuid(),\n membershipId: z.string().uuid().nullable(),\n name: z.string().nullable(),\n totals: z.array(OrganizationUsageTotal),\n }),\n )\n .default([]),\n privateChatsTruncated: z.boolean().default(false),\n});\nexport type OrganizationUsageSummary = z.infer<typeof OrganizationUsageSummary>;\n\n/**\n * A page deliberately excludes totals, charts and Personal rows: those are not\n * recomputed. Pages continue the shared workspaces only.\n */\nexport const OrganizationUsageWorkspacePage = OrganizationUsageSummary.omit({\n totals: true,\n buckets: true,\n personalWorkspaces: true,\n personalWorkspaceCount: true,\n privateChats: true,\n privateChatsTruncated: true,\n});\nexport type OrganizationUsageWorkspacePage = z.infer<typeof OrganizationUsageWorkspacePage>;\n"],"mappings":";AAAA,SAAS,SAAS;AAEX,IAAM,0BAA0B,EAAE,KAAK,CAAC,SAAS,QAAQ,SAAS,KAAK,CAAC;AAExE,IAAM,yBAAyB,EAAE,OAAO;AAAA,EAC7C,QAAQ,wBAAwB,QAAQ,OAAO;AACjD,CAAC;AACM,IAAM,sCAAsC,uBAAuB,OAAO;AAAA,EAC/E,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,kBAAkB,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAC/C,CAAC;AAEM,IAAM,yBAAyB,EAAE,OAAO;AAAA,EAC7C,WAAW,EAAE,OAAO;AAAA,EACpB,MAAM,EAAE,OAAO;AAAA,EACf,UAAU,EAAE,OAAO,EAAE,MAAM,SAAS;AAAA,EACpC,YAAY,EAAE,OAAO,EAAE,MAAM,OAAO;AACtC,CAAC;AAEM,IAAM,qCAAqC,EAAE,OAAO;AAAA,EACzD,cAAc,EAAE,OAAO,EAAE,KAAK;AAAA,EAC9B,QAAQ,EAAE,MAAM,sBAAsB;AACxC,CAAC;AAEM,IAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,WAAW,EAAE,OAAO,EAAE,KAAK;AAAA,EAC3B,QAAQ;AAAA,EACR,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,aAAa,EAAE,KAAK,CAAC,QAAQ,KAAK,CAAC;AAAA,EACnC,QAAQ,EAAE,MAAM,sBAAsB;AAAA,EACtC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,GAAG,QAAQ,EAAE,MAAM,sBAAsB,EAAE,CAAC,CAAC;AAAA,EAC1F,YAAY,EACT;AAAA,IACC,EAAE,OAAO;AAAA,MACP,aAAa,EAAE,OAAO,EAAE,KAAK;AAAA,MAC7B,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,MAC1B,QAAQ,EAAE,MAAM,sBAAsB;AAAA,IACxC,CAAC;AAAA,EACH,EACC,IAAI,EAAE;AAAA,EACT,qBAAqB,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhD,oBAAoB,EAAE,MAAM,kCAAkC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA,EAElF,wBAAwB,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC;AAAA;AAAA,EAEhE,cAAc,EACX;AAAA,IACC,EAAE,OAAO;AAAA,MACP,aAAa,EAAE,OAAO,EAAE,KAAK;AAAA,MAC7B,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,MACzC,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,MAC1B,QAAQ,EAAE,MAAM,sBAAsB;AAAA,IACxC,CAAC;AAAA,EACH,EACC,QAAQ,CAAC,CAAC;AAAA,EACb,uBAAuB,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAClD,CAAC;AAOM,IAAM,iCAAiC,yBAAyB,KAAK;AAAA,EAC1E,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,cAAc;AAAA,EACd,uBAAuB;AACzB,CAAC;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ConnectionKind,
3
3
  SessionTenancyVisibility
4
- } from "./chunk-BHKAFQNX.js";
4
+ } from "./chunk-Z6KUTGQS.js";
5
5
 
6
6
  // src/connection-authority.ts
7
7
  import { z } from "zod";
@@ -183,4 +183,4 @@ export {
183
183
  ConnectionUseAuditFact,
184
184
  ConnectionUseAuthorizationResult
185
185
  };
186
- //# sourceMappingURL=chunk-VYSAG53F.js.map
186
+ //# sourceMappingURL=chunk-VUVXWYK7.js.map