@company-semantics/contracts 9.1.0 → 9.2.0

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 (141) hide show
  1. package/package.json +4 -1
  2. package/src/__tests__/resource-keys.test.ts +30 -23
  3. package/src/admin/authz-simulate.ts +4 -4
  4. package/src/admin/direct-grants.ts +2 -2
  5. package/src/api/generated-spec-hash.ts +2 -2
  6. package/src/api/generated.ts +97 -0
  7. package/src/api/http/routes/ai-chat.ts +3 -3
  8. package/src/api/http/utils/resource-response.ts +5 -2
  9. package/src/api/index.ts +4 -4
  10. package/src/api/primitives.ts +6 -2
  11. package/src/auth/README.md +1 -0
  12. package/src/auth/index.ts +12 -5
  13. package/src/autotune.ts +5 -1
  14. package/src/billing/index.ts +1 -1
  15. package/src/billing/types.ts +1 -1
  16. package/src/chat/README.md +3 -0
  17. package/src/chat/__tests__/runtime-profile.test.ts +68 -48
  18. package/src/chat/index.ts +10 -4
  19. package/src/chat/runtime-profile.ts +25 -10
  20. package/src/chat/schemas.ts +49 -41
  21. package/src/chat/types.ts +48 -42
  22. package/src/ci-envelope/README.md +2 -0
  23. package/src/ci-envelope/__tests__/transitions.test.ts +56 -56
  24. package/src/ci-envelope/index.ts +2 -2
  25. package/src/ci-envelope/types.ts +20 -20
  26. package/src/ci-results/index.ts +2 -2
  27. package/src/ci-results/repo-ci-result.ts +15 -12
  28. package/src/compatibility.ts +6 -6
  29. package/src/content/index.ts +10 -4
  30. package/src/content/schemas.ts +42 -24
  31. package/src/dispatch/index.ts +18 -15
  32. package/src/email/__tests__/registry.test.ts +81 -77
  33. package/src/email/index.ts +3 -3
  34. package/src/email/registry.ts +25 -25
  35. package/src/email/types.ts +43 -43
  36. package/src/errors/index.ts +8 -8
  37. package/src/execution/__tests__/events.test.ts +42 -42
  38. package/src/execution/__tests__/lifecycle.test.ts +192 -190
  39. package/src/execution/__tests__/registry.test.ts +114 -114
  40. package/src/execution/audit-export.ts +4 -4
  41. package/src/execution/errors.ts +7 -7
  42. package/src/execution/event-metadata.ts +4 -4
  43. package/src/execution/events.ts +23 -21
  44. package/src/execution/expiry.ts +5 -5
  45. package/src/execution/hash-chain.ts +2 -2
  46. package/src/execution/index.ts +19 -28
  47. package/src/execution/kinds.ts +7 -7
  48. package/src/execution/lifecycle.ts +33 -33
  49. package/src/execution/registry.ts +63 -63
  50. package/src/execution/schemas.ts +31 -23
  51. package/src/execution/status.ts +45 -26
  52. package/src/execution/summary.ts +16 -17
  53. package/src/execution/timeline-ui.ts +9 -9
  54. package/src/execution/types.ts +31 -25
  55. package/src/generated/openapi-routes.ts +1 -0
  56. package/src/guards/config.ts +22 -18
  57. package/src/guards/index.ts +4 -4
  58. package/src/guards/types.ts +32 -24
  59. package/src/identity/__tests__/avatar.test.ts +68 -59
  60. package/src/identity/avatar.ts +8 -8
  61. package/src/identity/display-name.ts +3 -3
  62. package/src/identity/index.ts +8 -8
  63. package/src/identity/people-org-chart.ts +8 -4
  64. package/src/identity/schemas.ts +28 -18
  65. package/src/identity/types.ts +5 -5
  66. package/src/impersonation/index.ts +5 -5
  67. package/src/impersonation/schemas.ts +15 -9
  68. package/src/impersonation-events.ts +21 -21
  69. package/src/impersonation.ts +25 -24
  70. package/src/index.ts +118 -90
  71. package/src/interfaces/mcp/tools/help.ts +19 -19
  72. package/src/internal-admin.ts +6 -6
  73. package/src/mcp/README.md +2 -0
  74. package/src/mcp/__tests__/capability-graph.test.ts +290 -290
  75. package/src/mcp/capability-graph.ts +42 -40
  76. package/src/mcp/failure-context.ts +1 -3
  77. package/src/mcp/index.ts +57 -57
  78. package/src/mcp/resources.ts +9 -9
  79. package/src/meetings/index.ts +2 -2
  80. package/src/meetings/schemas.ts +51 -34
  81. package/src/message-parts/README.md +2 -0
  82. package/src/message-parts/__tests__/builder.test.ts +142 -142
  83. package/src/message-parts/__tests__/confirmation.test.ts +100 -86
  84. package/src/message-parts/__tests__/preview.test.ts +63 -63
  85. package/src/message-parts/__tests__/wire.test.ts +130 -124
  86. package/src/message-parts/builder.ts +23 -23
  87. package/src/message-parts/confirmation.ts +17 -14
  88. package/src/message-parts/execution.ts +7 -7
  89. package/src/message-parts/index.ts +10 -10
  90. package/src/message-parts/lifecycle.ts +25 -25
  91. package/src/message-parts/preview.ts +30 -30
  92. package/src/message-parts/types.ts +27 -27
  93. package/src/message-parts/wire.ts +24 -24
  94. package/src/mutations.ts +2 -2
  95. package/src/observability.ts +23 -11
  96. package/src/org/__tests__/org-units.test.ts +131 -96
  97. package/src/org/__tests__/tree-ordering.test.ts +57 -37
  98. package/src/org/__tests__/view-scopes.test.ts +40 -40
  99. package/src/org/domain.ts +9 -9
  100. package/src/org/index.ts +24 -21
  101. package/src/org/org-units.ts +34 -20
  102. package/src/org/schemas.ts +201 -127
  103. package/src/org/sharing.ts +17 -13
  104. package/src/org/tree-ordering.ts +3 -1
  105. package/src/org/types.ts +54 -47
  106. package/src/org/view-scopes.ts +9 -9
  107. package/src/permissions/access-levels.ts +7 -2
  108. package/src/permissions/access-source.ts +6 -6
  109. package/src/permissions/index.ts +5 -5
  110. package/src/permissions/orgchart-roles.ts +7 -7
  111. package/src/permissions/permission-introspection.ts +7 -5
  112. package/src/permissions/share-api.ts +19 -9
  113. package/src/pressure.ts +4 -4
  114. package/src/queryIntent.ts +21 -21
  115. package/src/ralph/__tests__/prd-groups.test.ts +159 -159
  116. package/src/ralph/__tests__/prd.test.ts +30 -30
  117. package/src/ralph/index.ts +3 -8
  118. package/src/ralph/prd.ts +33 -33
  119. package/src/ralph/progress.ts +1 -1
  120. package/src/rate-limit/README.md +4 -4
  121. package/src/rate-limit/index.ts +3 -3
  122. package/src/requests.ts +36 -8
  123. package/src/resource-keys.ts +207 -124
  124. package/src/resource-registry.ts +5 -5
  125. package/src/route-builder.ts +3 -3
  126. package/src/safe-mode.ts +2 -2
  127. package/src/security/index.ts +4 -4
  128. package/src/security/org-secrets.ts +13 -9
  129. package/src/security/secret.ts +3 -3
  130. package/src/sse.ts +3 -1
  131. package/src/system/README.md +3 -0
  132. package/src/system/capabilities.ts +22 -23
  133. package/src/system/diagram.ts +45 -45
  134. package/src/system/index.ts +14 -14
  135. package/src/tiers.ts +1 -1
  136. package/src/timeouts.ts +1 -1
  137. package/src/tracing.ts +30 -30
  138. package/src/types/analytics.ts +2 -2
  139. package/src/usage/README.md +3 -0
  140. package/src/usage/execution-types.ts +69 -69
  141. package/src/usage/types.ts +7 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@company-semantics/contracts",
3
- "version": "9.1.0",
3
+ "version": "9.2.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -79,6 +79,8 @@
79
79
  "typecheck": "tsc -b --noEmit",
80
80
  "typecheck:ci": "tsc -p scripts/ci/tsconfig.json",
81
81
  "lint:md": "markdownlint-cli2 '**/*.md' '#node_modules'",
82
+ "format": "prettier --write src/",
83
+ "format:check": "prettier --check src/",
82
84
  "lint:json": "node -e \"JSON.parse(require('fs').readFileSync('package.json'))\"",
83
85
  "prepare": "husky",
84
86
  "guard:export": "npx tsx scripts/ci/export-guard.ts",
@@ -118,6 +120,7 @@
118
120
  "lint-staged": "^17.0.7",
119
121
  "markdownlint-cli2": "^0.22.1",
120
122
  "openapi-typescript": "^7.13.0",
123
+ "prettier": "^3.8.3",
121
124
  "tsx": "^4.22.4",
122
125
  "typescript": "^5.8.3",
123
126
  "vitest": "^4.1.8",
@@ -1,55 +1,57 @@
1
- import { describe, it, expect } from 'vitest';
1
+ import { describe, it, expect } from "vitest";
2
2
  import {
3
3
  toQueryKey,
4
4
  fromQueryKey,
5
5
  matchesResourceKey,
6
6
  type ResourceKey,
7
- } from '../resource-keys.js';
7
+ } from "../resource-keys.js";
8
8
 
9
- const ORG_ID = '11111111-1111-4111-8111-111111111111';
9
+ const ORG_ID = "11111111-1111-4111-8111-111111111111";
10
10
 
11
- describe('resource-keys: orgUnitOwners (org-scoped)', () => {
12
- const key: ResourceKey = { type: 'orgUnitOwners', orgId: ORG_ID };
11
+ describe("resource-keys: orgUnitOwners (org-scoped)", () => {
12
+ const key: ResourceKey = { type: "orgUnitOwners", orgId: ORG_ID };
13
13
 
14
- it('toQueryKey produces [type, orgId] with no unitId', () => {
14
+ it("toQueryKey produces [type, orgId] with no unitId", () => {
15
15
  const qk = toQueryKey(key);
16
- expect(qk).toEqual(['orgUnitOwners', ORG_ID]);
16
+ expect(qk).toEqual(["orgUnitOwners", ORG_ID]);
17
17
  // org-scoped: exactly two segments, no per-unit identity
18
18
  expect(qk).toHaveLength(2);
19
19
  });
20
20
 
21
- it('roundtrips through fromQueryKey', () => {
21
+ it("roundtrips through fromQueryKey", () => {
22
22
  const parsed = fromQueryKey(toQueryKey(key));
23
23
  expect(parsed).toEqual(key);
24
- expect('unitId' in parsed).toBe(false);
24
+ expect("unitId" in parsed).toBe(false);
25
25
  });
26
26
 
27
- it('matchesResourceKey is org-scoped: rejects a different orgId', () => {
28
- const other = '22222222-2222-4222-8222-222222222222';
27
+ it("matchesResourceKey is org-scoped: rejects a different orgId", () => {
28
+ const other = "22222222-2222-4222-8222-222222222222";
29
29
  expect(matchesResourceKey(toQueryKey(key), key)).toBe(true);
30
- expect(matchesResourceKey(['orgUnitOwners', other], key)).toBe(false);
30
+ expect(matchesResourceKey(["orgUnitOwners", other], key)).toBe(false);
31
31
  });
32
32
  });
33
33
 
34
- describe('resource-keys: system-scoped internalAdmin* types', () => {
34
+ describe("resource-keys: system-scoped internalAdmin* types", () => {
35
35
  const systemTypes = [
36
- 'internalAdminAiProviders',
37
- 'internalAdminPrompts',
38
- 'internalAdminAiRuntimeDefaults',
36
+ "internalAdminAiProviders",
37
+ "internalAdminPrompts",
38
+ "internalAdminAiRuntimeDefaults",
39
+ "factoryFloor",
40
+ "factorySnapshot",
39
41
  ] as const;
40
42
 
41
43
  for (const type of systemTypes) {
42
- const key = { type, scope: 'system' } as ResourceKey;
44
+ const key = { type, scope: "system" } as ResourceKey;
43
45
 
44
46
  it(`${type}: toQueryKey produces [type, 'system']`, () => {
45
- expect(toQueryKey(key)).toEqual([type, 'system']);
47
+ expect(toQueryKey(key)).toEqual([type, "system"]);
46
48
  });
47
49
 
48
50
  it(`${type}: roundtrips through fromQueryKey with scope: 'system'`, () => {
49
51
  const parsed = fromQueryKey(toQueryKey(key));
50
52
  expect(parsed).toEqual(key);
51
- expect('orgId' in parsed).toBe(false);
52
- expect('userId' in parsed).toBe(false);
53
+ expect("orgId" in parsed).toBe(false);
54
+ expect("userId" in parsed).toBe(false);
53
55
  });
54
56
 
55
57
  it(`${type}: matchesResourceKey accepts a matching system key`, () => {
@@ -57,8 +59,13 @@ describe('resource-keys: system-scoped internalAdmin* types', () => {
57
59
  });
58
60
  }
59
61
 
60
- it('matchesResourceKey rejects a mismatched system type', () => {
61
- const target: ResourceKey = { type: 'internalAdminPrompts', scope: 'system' };
62
- expect(matchesResourceKey(['internalAdminAiProviders', 'system'], target)).toBe(false);
62
+ it("matchesResourceKey rejects a mismatched system type", () => {
63
+ const target: ResourceKey = {
64
+ type: "internalAdminPrompts",
65
+ scope: "system",
66
+ };
67
+ expect(
68
+ matchesResourceKey(["internalAdminAiProviders", "system"], target),
69
+ ).toBe(false);
63
70
  });
64
71
  });
@@ -6,21 +6,21 @@
6
6
  * admins can debug denials by reading evaluator name + reason rather than
7
7
  * guessing. See PRD-00544 and feedback_decision_logic_must_be_visible.md.
8
8
  */
9
- import { z } from 'zod';
9
+ import { z } from "zod";
10
10
 
11
11
  export const SimulateRequest = z.object({
12
12
  actor: z.object({
13
- type: z.enum(['user', 'agent']),
13
+ type: z.enum(["user", "agent"]),
14
14
  id: z.string().uuid(),
15
15
  }),
16
16
  scope: z.string(),
17
- resource_kind: z.enum(['system', 'org', 'team', 'member', 'doc']),
17
+ resource_kind: z.enum(["system", "org", "team", "member", "doc"]),
18
18
  resource_id: z.string().uuid().optional(),
19
19
  });
20
20
 
21
21
  export type SimulateRequest = z.infer<typeof SimulateRequest>;
22
22
 
23
- export const SimulateResponse = z.discriminatedUnion('allow', [
23
+ export const SimulateResponse = z.discriminatedUnion("allow", [
24
24
  z.object({
25
25
  allow: z.literal(true),
26
26
  matched_grant: z.unknown(),
@@ -6,7 +6,7 @@
6
6
  * body — it is set by the server from the authenticated actor (see PRD-00544
7
7
  * direct-grant-audit-trail and the `direct-grant-audit` CI guard).
8
8
  */
9
- import { z } from 'zod';
9
+ import { z } from "zod";
10
10
 
11
11
  export const DirectGrantCreate = z.object({
12
12
  subject_id: z.string().uuid(),
@@ -22,7 +22,7 @@ export const DirectGrant = z.object({
22
22
  org_id: z.string().uuid(),
23
23
  subject_id: z.string().uuid(),
24
24
  scope_pattern: z.string(),
25
- source: z.literal('direct'),
25
+ source: z.literal("direct"),
26
26
  granted_by: z.string().uuid(),
27
27
  granted_at: z.string().datetime(),
28
28
  expires_at: z.string().datetime().nullable(),
@@ -1,3 +1,3 @@
1
1
  // AUTO-GENERATED — do not edit. Run pnpm generate:spec-hash to regenerate.
2
- export const SPEC_HASH = '6afa08fcbf29' as const;
3
- export const SPEC_HASH_FULL = '6afa08fcbf29128df63d59525891ef1f6e8eb0e49b8e289b09d0150ce35a862e' as const;
2
+ export const SPEC_HASH = '1173d8fa2df9' as const;
3
+ export const SPEC_HASH_FULL = '1173d8fa2df90dbf7a46608635f61e69939616ed509f6109bdf478fc1cd4a9c0' as const;
@@ -2696,6 +2696,23 @@ export interface paths {
2696
2696
  patch?: never;
2697
2697
  trace?: never;
2698
2698
  };
2699
+ "/api/factory/snapshot": {
2700
+ parameters: {
2701
+ query?: never;
2702
+ header?: never;
2703
+ path?: never;
2704
+ cookie?: never;
2705
+ };
2706
+ /** Read the freshest software-factory PRD snapshot */
2707
+ get: operations["factorySnapshot"];
2708
+ put?: never;
2709
+ post?: never;
2710
+ delete?: never;
2711
+ options?: never;
2712
+ head?: never;
2713
+ patch?: never;
2714
+ trace?: never;
2715
+ };
2699
2716
  "/api/internal-admin/impersonate/start": {
2700
2717
  parameters: {
2701
2718
  query?: never;
@@ -4800,6 +4817,52 @@ export interface components {
4800
4817
  }[];
4801
4818
  }[];
4802
4819
  };
4820
+ FactorySnapshotResponse: {
4821
+ snapshot: {
4822
+ /** Format: date-time */
4823
+ generatedAt: string;
4824
+ host: string;
4825
+ counts: {
4826
+ ready: number;
4827
+ running: number;
4828
+ blocked: number;
4829
+ done: number;
4830
+ };
4831
+ /** @default [] */
4832
+ prds: {
4833
+ id: string;
4834
+ title: string;
4835
+ repo: string;
4836
+ /** @enum {string} */
4837
+ status: "active" | "completed";
4838
+ /** @enum {string} */
4839
+ kanban: "ready" | "running" | "blocked" | "done";
4840
+ progress: number;
4841
+ running?: {
4842
+ executor: string | null;
4843
+ feature: string | null;
4844
+ startedAt: string | null;
4845
+ branch: string | null;
4846
+ };
4847
+ /** @default [] */
4848
+ blockedBy: {
4849
+ target: string;
4850
+ reason?: string;
4851
+ }[];
4852
+ }[];
4853
+ /** @default [] */
4854
+ actors: {
4855
+ id: string;
4856
+ role: string;
4857
+ /** @enum {string} */
4858
+ status: "working" | "idle";
4859
+ workingOn?: string;
4860
+ feature?: string;
4861
+ detected: boolean;
4862
+ }[];
4863
+ } | null;
4864
+ receivedAt: string | null;
4865
+ };
4803
4866
  ImpersonationSessionResponse: {
4804
4867
  session: {
4805
4868
  impersonationSessionId: string;
@@ -9324,6 +9387,40 @@ export interface operations {
9324
9387
  };
9325
9388
  };
9326
9389
  };
9390
+ factorySnapshot: {
9391
+ parameters: {
9392
+ query?: never;
9393
+ header?: never;
9394
+ path?: never;
9395
+ cookie?: never;
9396
+ };
9397
+ requestBody?: never;
9398
+ responses: {
9399
+ /** @description Factory snapshot (freshest by generatedAt, null if none) */
9400
+ 200: {
9401
+ headers: {
9402
+ [name: string]: unknown;
9403
+ };
9404
+ content: {
9405
+ "application/json": components["schemas"]["FactorySnapshotResponse"];
9406
+ };
9407
+ };
9408
+ /** @description Not authenticated */
9409
+ 401: {
9410
+ headers: {
9411
+ [name: string]: unknown;
9412
+ };
9413
+ content?: never;
9414
+ };
9415
+ /** @description Not an internal admin */
9416
+ 403: {
9417
+ headers: {
9418
+ [name: string]: unknown;
9419
+ };
9420
+ content?: never;
9421
+ };
9422
+ };
9423
+ };
9327
9424
  startImpersonation: {
9328
9425
  parameters: {
9329
9426
  query?: never;
@@ -10,12 +10,12 @@
10
10
  * import { buildCapabilityGraph } from '@company-semantics/contracts'
11
11
  */
12
12
 
13
- import { buildCapabilityGraph } from '../../../mcp/capability-graph'
13
+ import { buildCapabilityGraph } from "../../../mcp/capability-graph";
14
14
  import type {
15
15
  MCPToolDescriptor,
16
16
  ToolDiscoveryResponse,
17
17
  CapabilityGraph,
18
- } from '../../../mcp/index'
18
+ } from "../../../mcp/index";
19
19
 
20
20
  /**
21
21
  * Build a ToolDiscoveryResponse, optionally including the capability graph.
@@ -33,5 +33,5 @@ export function buildToolDiscoveryResponse(
33
33
  return {
34
34
  tools,
35
35
  ...(includeGraph && { graph: buildCapabilityGraph(tools) }),
36
- }
36
+ };
37
37
  }
@@ -1,4 +1,4 @@
1
- import type { ResourceResponse } from '../../../resource-response';
1
+ import type { ResourceResponse } from "../../../resource-response";
2
2
 
3
3
  /**
4
4
  * Wrap resource data with version for cache invalidation.
@@ -6,6 +6,9 @@ import type { ResourceResponse } from '../../../resource-response';
6
6
  * @param version - MUST be entity.updatedAt or DB row version. NEVER Date.now().
7
7
  * Using request time defeats invalidation — race conditions reappear.
8
8
  */
9
- export function resourceResponse<T>(data: T, version: number): ResourceResponse<T> {
9
+ export function resourceResponse<T>(
10
+ data: T,
11
+ version: number,
12
+ ): ResourceResponse<T> {
10
13
  return { data, version };
11
14
  }
package/src/api/index.ts CHANGED
@@ -6,11 +6,11 @@
6
6
  */
7
7
 
8
8
  // OpenAPI generated types (from openapi/backend.yaml)
9
- export type { paths, components, operations } from './generated'
9
+ export type { paths, components, operations } from "./generated";
10
10
 
11
11
  // Spec hash (from openapi/backend.yaml SHA-256)
12
- export { SPEC_HASH, SPEC_HASH_FULL } from './generated-spec-hash'
12
+ export { SPEC_HASH, SPEC_HASH_FULL } from "./generated-spec-hash";
13
13
 
14
14
  // Reusable API primitive schemas (CursorPage, ErrorResponse)
15
- export { CursorPageSchema, ErrorResponseSchema } from './primitives'
16
- export type { CursorPage, ErrorResponse } from './primitives'
15
+ export { CursorPageSchema, ErrorResponseSchema } from "./primitives";
16
+ export type { CursorPage, ErrorResponse } from "./primitives";
@@ -1,4 +1,4 @@
1
- import { z } from 'zod';
1
+ import { z } from "zod";
2
2
 
3
3
  /** Generic factory for cursor-paginated responses. */
4
4
  export function CursorPageSchema<T extends z.ZodTypeAny>(itemSchema: T) {
@@ -19,5 +19,9 @@ export const ErrorResponseSchema = z.object({
19
19
  });
20
20
 
21
21
  // Inferred types
22
- export type CursorPage<T> = { items: T[]; nextCursor: string | null; hasMore: boolean };
22
+ export type CursorPage<T> = {
23
+ items: T[];
24
+ nextCursor: string | null;
25
+ hasMore: boolean;
26
+ };
23
27
  export type ErrorResponse = z.infer<typeof ErrorResponseSchema>;
@@ -12,6 +12,7 @@ Shared types for authentication flows across Company Semantics codebases. Define
12
12
  ## Public API
13
13
 
14
14
  **Types:**
15
+
15
16
  - `OTPErrorCode` — enum: `InvalidCode`, `Expired`, `AlreadyUsed`, `NotFound`
16
17
  - `AuthStartMode` — `'otp' | 'sso' | 'hybrid'`
17
18
  - `AuthStartResponse` — discriminated union describing auth flow entry point
package/src/auth/index.ts CHANGED
@@ -11,10 +11,10 @@
11
11
  * Frontend uses these to provide specific user messaging (e.g., expired vs invalid).
12
12
  */
13
13
  export enum OTPErrorCode {
14
- InvalidCode = 'invalid_code',
15
- Expired = 'expired',
16
- AlreadyUsed = 'already_used',
17
- NotFound = 'not_found',
14
+ InvalidCode = "invalid_code",
15
+ Expired = "expired",
16
+ AlreadyUsed = "already_used",
17
+ NotFound = "not_found",
18
18
  }
19
19
 
20
20
  export type AuthStartMode = "otp" | "sso" | "hybrid";
@@ -22,4 +22,11 @@ export type AuthStartMode = "otp" | "sso" | "hybrid";
22
22
  export type AuthStartResponse =
23
23
  | { mode: "otp"; devOtp?: string }
24
24
  | { mode: "sso"; providers: string[]; redirectUrl: string }
25
- | { mode: "hybrid"; providers: string[]; redirectUrl: string; recommendedProvider?: string; otpAllowed: true; devOtp?: string };
25
+ | {
26
+ mode: "hybrid";
27
+ providers: string[];
28
+ redirectUrl: string;
29
+ recommendedProvider?: string;
30
+ otpAllowed: true;
31
+ devOtp?: string;
32
+ };
package/src/autotune.ts CHANGED
@@ -85,6 +85,10 @@ export type ControllerInput = {
85
85
  */
86
86
  export type ControllerOutput<Min extends number, Max extends number> = {
87
87
  readonly value: Bounded<Min, Max>;
88
- readonly reason: 'deadband-hold' | 'window-hold' | 'adjusted' | 'bounded-clamp';
88
+ readonly reason:
89
+ | "deadband-hold"
90
+ | "window-hold"
91
+ | "adjusted"
92
+ | "bounded-clamp";
89
93
  readonly adjustmentWindowId: string;
90
94
  };
@@ -1 +1 @@
1
- export type { OrgPlanStatus, OrgBillingInfo } from './types';
1
+ export type { OrgPlanStatus, OrgBillingInfo } from "./types";
@@ -10,7 +10,7 @@
10
10
  /**
11
11
  * Organization plan status.
12
12
  */
13
- export type OrgPlanStatus = 'active' | 'trialing' | 'past_due' | 'canceled';
13
+ export type OrgPlanStatus = "active" | "trialing" | "past_due" | "canceled";
14
14
 
15
15
  /**
16
16
  * Read-only billing information for an organization.
@@ -16,6 +16,7 @@ Shared types for chat persistence, sharing, real-time events, and runtime profil
16
16
  ## Public API
17
17
 
18
18
  **Types:**
19
+
19
20
  - `ChatVisibility` — `'private' | 'public'` share visibility
20
21
  - `ChatSummary`, `ChatSummaryExtended` — list view models
21
22
  - `ChatShareInfo`, `SharedChatView`, `SharedChatMessage` — sharing types
@@ -25,11 +26,13 @@ Shared types for chat persistence, sharing, real-time events, and runtime profil
25
26
  - `ChatRuntimeProfileInfo` — profile metadata for UI rendering
26
27
 
27
28
  **SSE event types:**
29
+
28
30
  - `ChatCreatedEvent`, `ChatUpdatedEvent`, `ChatDeletedEvent` — domain events
29
31
  - `InvalidateChatEvent`, `InvalidateChatListEvent` — staleness signals
30
32
  - `ChatSseEvent` — union of all SSE event types
31
33
 
32
34
  **Runtime values:**
35
+
33
36
  - `CHAT_RUNTIME_PROFILES` — ordered array of profile info for UI rendering
34
37
  - `DEFAULT_CHAT_RUNTIME_PROFILE` — `'agentic'`
35
38
 
@@ -1,55 +1,75 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { CHAT_RUNTIME_PROFILES, DEFAULT_CHAT_RUNTIME_PROFILE } from '../runtime-profile.js'
1
+ import { describe, it, expect } from "vitest";
2
+ import {
3
+ CHAT_RUNTIME_PROFILES,
4
+ DEFAULT_CHAT_RUNTIME_PROFILE,
5
+ } from "../runtime-profile.js";
3
6
 
4
- describe('CHAT_RUNTIME_PROFILES golden snapshot', () => {
5
- it('exact values are frozen', () => {
7
+ describe("CHAT_RUNTIME_PROFILES golden snapshot", () => {
8
+ it("exact values are frozen", () => {
6
9
  expect(CHAT_RUNTIME_PROFILES).toStrictEqual([
7
- { id: 'fast', label: 'Fast', description: 'Single-step, no tools', model: 'gpt-3.5-turbo' },
8
- { id: 'balanced', label: 'Balanced', description: 'Multi-step with tools', model: 'gpt-4o' },
9
- { id: 'agentic', label: 'Agentic', description: 'Agent loop, full reasoning', model: 'claude-sonnet-4-20250514' },
10
- ])
11
- })
12
- })
13
-
14
- describe('CHAT_RUNTIME_PROFILES invariants', () => {
15
- it('covers all ChatRuntimeProfile values', () => {
16
- const ids = CHAT_RUNTIME_PROFILES.map(p => p.id)
17
- expect(ids).toContain('fast')
18
- expect(ids).toContain('balanced')
19
- expect(ids).toContain('agentic')
20
- })
21
-
22
- it('has no duplicate profile IDs', () => {
23
- const ids = CHAT_RUNTIME_PROFILES.map(p => p.id)
24
- expect(new Set(ids).size).toBe(ids.length)
25
- })
26
-
27
- it('all entries have non-empty label and description', () => {
10
+ {
11
+ id: "fast",
12
+ label: "Fast",
13
+ description: "Single-step, no tools",
14
+ model: "gpt-3.5-turbo",
15
+ },
16
+ {
17
+ id: "balanced",
18
+ label: "Balanced",
19
+ description: "Multi-step with tools",
20
+ model: "gpt-4o",
21
+ },
22
+ {
23
+ id: "agentic",
24
+ label: "Agentic",
25
+ description: "Agent loop, full reasoning",
26
+ model: "claude-sonnet-4-20250514",
27
+ },
28
+ ]);
29
+ });
30
+ });
31
+
32
+ describe("CHAT_RUNTIME_PROFILES invariants", () => {
33
+ it("covers all ChatRuntimeProfile values", () => {
34
+ const ids = CHAT_RUNTIME_PROFILES.map((p) => p.id);
35
+ expect(ids).toContain("fast");
36
+ expect(ids).toContain("balanced");
37
+ expect(ids).toContain("agentic");
38
+ });
39
+
40
+ it("has no duplicate profile IDs", () => {
41
+ const ids = CHAT_RUNTIME_PROFILES.map((p) => p.id);
42
+ expect(new Set(ids).size).toBe(ids.length);
43
+ });
44
+
45
+ it("all entries have non-empty label and description", () => {
28
46
  for (const profile of CHAT_RUNTIME_PROFILES) {
29
- expect(profile.label.length).toBeGreaterThan(0)
30
- expect(profile.description.length).toBeGreaterThan(0)
47
+ expect(profile.label.length).toBeGreaterThan(0);
48
+ expect(profile.description.length).toBeGreaterThan(0);
31
49
  }
32
- })
50
+ });
33
51
 
34
- it('all entries have non-empty model strings', () => {
52
+ it("all entries have non-empty model strings", () => {
35
53
  for (const profile of CHAT_RUNTIME_PROFILES) {
36
- expect(profile.model.length).toBeGreaterThan(0)
54
+ expect(profile.model.length).toBeGreaterThan(0);
37
55
  }
38
- })
39
- })
40
-
41
- describe('DEFAULT_CHAT_RUNTIME_PROFILE', () => {
42
- it('is agentic', () => {
43
- expect(DEFAULT_CHAT_RUNTIME_PROFILE).toBe('agentic')
44
- })
45
-
46
- it('exists in CHAT_RUNTIME_PROFILES', () => {
47
- const ids = CHAT_RUNTIME_PROFILES.map(p => p.id)
48
- expect(ids).toContain(DEFAULT_CHAT_RUNTIME_PROFILE)
49
- })
50
-
51
- it('is a valid ChatRuntimeProfile value', () => {
52
- const validIds = CHAT_RUNTIME_PROFILES.map(p => p.id) as readonly string[]
53
- expect(validIds).toContain(DEFAULT_CHAT_RUNTIME_PROFILE)
54
- })
55
- })
56
+ });
57
+ });
58
+
59
+ describe("DEFAULT_CHAT_RUNTIME_PROFILE", () => {
60
+ it("is agentic", () => {
61
+ expect(DEFAULT_CHAT_RUNTIME_PROFILE).toBe("agentic");
62
+ });
63
+
64
+ it("exists in CHAT_RUNTIME_PROFILES", () => {
65
+ const ids = CHAT_RUNTIME_PROFILES.map((p) => p.id);
66
+ expect(ids).toContain(DEFAULT_CHAT_RUNTIME_PROFILE);
67
+ });
68
+
69
+ it("is a valid ChatRuntimeProfile value", () => {
70
+ const validIds = CHAT_RUNTIME_PROFILES.map(
71
+ (p) => p.id,
72
+ ) as readonly string[];
73
+ expect(validIds).toContain(DEFAULT_CHAT_RUNTIME_PROFILE);
74
+ });
75
+ });
package/src/chat/index.ts CHANGED
@@ -49,7 +49,7 @@ export type {
49
49
  ChatMessage,
50
50
  ChatDetail,
51
51
  GetChatResponse,
52
- } from './types'
52
+ } from "./types";
53
53
 
54
54
  // =============================================================================
55
55
  // Schemas (Zod runtime validation)
@@ -87,8 +87,14 @@ export {
87
87
  ChatMessageSchema,
88
88
  ChatDetailSchema,
89
89
  GetChatResponseSchema,
90
- } from './schemas'
90
+ } from "./schemas";
91
91
 
92
92
  // Runtime profile types and constants
93
- export type { ChatRuntimeProfile, ChatRuntimeProfileInfo } from './runtime-profile'
94
- export { CHAT_RUNTIME_PROFILES, DEFAULT_CHAT_RUNTIME_PROFILE } from './runtime-profile'
93
+ export type {
94
+ ChatRuntimeProfile,
95
+ ChatRuntimeProfileInfo,
96
+ } from "./runtime-profile";
97
+ export {
98
+ CHAT_RUNTIME_PROFILES,
99
+ DEFAULT_CHAT_RUNTIME_PROFILE,
100
+ } from "./runtime-profile";
@@ -8,29 +8,44 @@
8
8
  * - balanced: Default. AiSdkOrchestrator + gpt-4o with tool support.
9
9
  * - agentic: Multi-turn agent loop. ClaudeAgentOrchestrator.
10
10
  */
11
- export type ChatRuntimeProfile = 'fast' | 'balanced' | 'agentic'
11
+ export type ChatRuntimeProfile = "fast" | "balanced" | "agentic";
12
12
 
13
13
  /**
14
14
  * Runtime profile metadata for UI rendering.
15
15
  * Labels and descriptions are user-facing — no vendor names.
16
16
  */
17
17
  export interface ChatRuntimeProfileInfo {
18
- id: ChatRuntimeProfile
19
- label: string
20
- description: string
21
- model: string
18
+ id: ChatRuntimeProfile;
19
+ label: string;
20
+ description: string;
21
+ model: string;
22
22
  }
23
23
 
24
24
  /**
25
25
  * Ordered list of available profiles for UI rendering.
26
26
  */
27
27
  export const CHAT_RUNTIME_PROFILES: readonly ChatRuntimeProfileInfo[] = [
28
- { id: 'fast', label: 'Fast', description: 'Single-step, no tools', model: 'gpt-3.5-turbo' },
29
- { id: 'balanced', label: 'Balanced', description: 'Multi-step with tools', model: 'gpt-4o' },
30
- { id: 'agentic', label: 'Agentic', description: 'Agent loop, full reasoning', model: 'claude-sonnet-4-20250514' },
31
- ] as const
28
+ {
29
+ id: "fast",
30
+ label: "Fast",
31
+ description: "Single-step, no tools",
32
+ model: "gpt-3.5-turbo",
33
+ },
34
+ {
35
+ id: "balanced",
36
+ label: "Balanced",
37
+ description: "Multi-step with tools",
38
+ model: "gpt-4o",
39
+ },
40
+ {
41
+ id: "agentic",
42
+ label: "Agentic",
43
+ description: "Agent loop, full reasoning",
44
+ model: "claude-sonnet-4-20250514",
45
+ },
46
+ ] as const;
32
47
 
33
48
  /**
34
49
  * Default profile when none is specified in the request.
35
50
  */
36
- export const DEFAULT_CHAT_RUNTIME_PROFILE: ChatRuntimeProfile = 'agentic'
51
+ export const DEFAULT_CHAT_RUNTIME_PROFILE: ChatRuntimeProfile = "agentic";