@m6d/cortex-cli 0.1.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 (61) hide show
  1. package/README.md +175 -0
  2. package/bin/cortex.js +52 -0
  3. package/package.json +41 -0
  4. package/src/cc/client.ts +295 -0
  5. package/src/cc/flags.ts +135 -0
  6. package/src/cc/output.ts +77 -0
  7. package/src/cc/profiles.ts +105 -0
  8. package/src/cli.ts +56 -0
  9. package/src/commands/cc.ts +504 -0
  10. package/src/commands/graph.ts +229 -0
  11. package/src/commands/new.ts +333 -0
  12. package/src/commands/swagger.ts +261 -0
  13. package/src/config/load.ts +122 -0
  14. package/src/config/validate.ts +46 -0
  15. package/src/contracts/charts/chart-spec.ts +201 -0
  16. package/src/contracts/charts/index.ts +7 -0
  17. package/src/contracts/client-tools/index.ts +82 -0
  18. package/src/contracts/egress/index.ts +161 -0
  19. package/src/contracts/egress/scrub.ts +59 -0
  20. package/src/contracts/graph/clients/embed.ts +45 -0
  21. package/src/contracts/graph/clients/neo4j.ts +85 -0
  22. package/src/contracts/graph/helpers.ts +57 -0
  23. package/src/contracts/graph/index.ts +30 -0
  24. package/src/contracts/graph/schema.ts +65 -0
  25. package/src/contracts/graph/types.ts +125 -0
  26. package/src/contracts/markdown/index.ts +39 -0
  27. package/src/contracts/rich-text/index.ts +220 -0
  28. package/src/contracts/runtime/api.ts +328 -0
  29. package/src/contracts/runtime/auth.ts +41 -0
  30. package/src/contracts/runtime/dataset-sql-guide.ts +67 -0
  31. package/src/contracts/runtime/dataset-sql.ts +2522 -0
  32. package/src/contracts/runtime/datasets.fixtures.json +2849 -0
  33. package/src/contracts/runtime/datasets.ts +1391 -0
  34. package/src/contracts/runtime/grammar.ts +161 -0
  35. package/src/contracts/runtime/index.ts +14 -0
  36. package/src/contracts/runtime/signature.ts +237 -0
  37. package/src/contracts/runtime/sync.ts +172 -0
  38. package/src/contracts/runtime/triggers.ts +224 -0
  39. package/src/contracts/wire/index.ts +264 -0
  40. package/src/graph/expand-domains.ts +288 -0
  41. package/src/graph/generate-cypher.ts +201 -0
  42. package/src/graph/seed.ts +207 -0
  43. package/src/graph/validate.ts +78 -0
  44. package/src/scaffold/features.ts +190 -0
  45. package/src/scaffold/files.ts +411 -0
  46. package/src/scaffold/ports.ts +86 -0
  47. package/src/scaffold/templates/domains-README.md.txt +16 -0
  48. package/src/scaffold/templates/eslint.config.mjs.txt +20 -0
  49. package/src/scaffold/templates/fallowrc.jsonc.txt +42 -0
  50. package/src/scaffold/templates/gitignore.txt +19 -0
  51. package/src/scaffold/templates/index.ts.txt +18 -0
  52. package/src/scaffold/templates/prettier.config.mjs.txt +5 -0
  53. package/src/scaffold/templates/tsconfig.json.txt +25 -0
  54. package/src/swagger/extract-endpoints.ts +266 -0
  55. package/src/swagger/generated-block.ts +74 -0
  56. package/src/swagger/openapi-schema.ts +161 -0
  57. package/src/swagger/parse-response.ts +88 -0
  58. package/src/swagger/types.ts +25 -0
  59. package/src/ui/prompts.ts +125 -0
  60. package/src/ui/report.ts +107 -0
  61. package/tsconfig.json +46 -0
@@ -0,0 +1,224 @@
1
+ import { z } from "zod";
2
+ import { datasetIdentifierSchema } from "./datasets";
3
+ import {
4
+ agentSlugSchema,
5
+ localizedTextSchema,
6
+ mentionedToolSchema,
7
+ sha256HexSchema,
8
+ slugSchema,
9
+ } from "./grammar";
10
+
11
+ /*
12
+ * Triggers: named entry points on an agent. A firing is one invocation with a
13
+ * payload and starts at most one run. The end user's message is the built-in
14
+ * `message` trigger; every other trigger is fired by an external caller over
15
+ * `POST /agents/:agentSlug/triggers/:name` on the server with the trigger's
16
+ * own secret. Two directions live here: what cc publishes to the server
17
+ * (declarations, secret checks) and what the server answers a caller.
18
+ */
19
+
20
+ export const MESSAGE_TRIGGER_NAME = "message";
21
+
22
+ /**
23
+ * The first characters of a fire bearer say what it is: the secret callers
24
+ * hold, or a one-shot test token the console minted. A test token is a JWT
25
+ * the Control Center signed, so a server verifies it against the Control
26
+ * Center's JWKS before saying a word to it, and the Control Center then
27
+ * consumes it so it fires once.
28
+ */
29
+ export const TRIGGER_SECRET_PREFIXES = { live: "tr_live_", test: "tr_test_" } as const;
30
+ export const TRIGGER_TEST_TOKEN_AUDIENCE = "cortex:trigger-test";
31
+
32
+ /** The claims a test token carries beside the standard ones; the server checks them against the route it arrived on. */
33
+ export const triggerTestTokenClaimsSchema = z.object({
34
+ agent: agentSlugSchema,
35
+ trigger: slugSchema,
36
+ });
37
+
38
+ export const TRIGGER_OUTCOMES = [
39
+ "started",
40
+ /** The run parked on a tool that needs approval; `POST .../firings/:id/answer` resumes it. */
41
+ "awaiting_approval",
42
+ "completed",
43
+ "failed",
44
+ "rejected",
45
+ "dropped",
46
+ "disabled",
47
+ ] as const;
48
+ export type TriggerOutcome = (typeof TRIGGER_OUTCOMES)[number];
49
+
50
+ /** Why a firing was dropped: the thread was busy, or the daily budget was spent. */
51
+ export const TRIGGER_DROP_REASONS = ["busy", "budget"] as const;
52
+ export type TriggerDropReason = (typeof TRIGGER_DROP_REASONS)[number];
53
+
54
+ export const TRIGGER_SOURCES = ["code", "cc"] as const;
55
+ export type TriggerSource = (typeof TRIGGER_SOURCES)[number];
56
+
57
+ /**
58
+ * Which thread a firing lands in. `single`: one thread for the trigger.
59
+ * `per-firing`: a fresh thread every time. `ephemeral`: a fresh thread that
60
+ * is deleted once the run completes, for one-shot calls: the answer reaches
61
+ * the caller as the firing's output or through the live stream, and nothing
62
+ * else outlives the run; a failed run keeps its thread for inspection. `keyed`:
63
+ * one thread per distinct value at a JSON pointer into the payload (e.g.
64
+ * `/pull_request/number`).
65
+ */
66
+ export const triggerThreadPolicySchema = z.discriminatedUnion("policy", [
67
+ z.object({ policy: z.literal("single") }),
68
+ z.object({ policy: z.literal("per-firing") }),
69
+ z.object({ policy: z.literal("ephemeral") }),
70
+ z.object({ policy: z.literal("keyed"), key: z.string().regex(/^\//).max(256) }),
71
+ ]);
72
+ export type TriggerThreadPolicy = z.infer<typeof triggerThreadPolicySchema>;
73
+
74
+ /* cc publishes to the server. */
75
+
76
+ /**
77
+ * A tool a trigger's instructions mention. Most are sandbox bindings; one
78
+ * that parks for approval is declared to the model as a function call
79
+ * instead, so it carries what that takes, as a /resolve signature does: a run
80
+ * started by a trigger has no other way to learn it.
81
+ */
82
+ const triggerMentionedToolSchema = z.discriminatedUnion("requiresApproval", [
83
+ mentionedToolSchema.extend({ requiresApproval: z.literal(false) }),
84
+ mentionedToolSchema.extend({
85
+ requiresApproval: z.literal(true),
86
+ signature: z.string(),
87
+ inputSchema: z.record(z.string(), z.unknown()),
88
+ approvalMessage: localizedTextSchema.optional(),
89
+ }),
90
+ ]);
91
+
92
+ /** A trigger as both sides describe it. Secrets and credentials never cross this contract. */
93
+ export const triggerDeclarationSchema = z.object({
94
+ name: slugSchema,
95
+ description: z.string().max(500),
96
+ /** JSON Schema for the payload; cc triggers are validated from it on the server. */
97
+ input: z.record(z.string(), z.unknown()),
98
+ /**
99
+ * JSON Schema the run's answer must match, or null for a free-text run.
100
+ * The server asks the model for that shape, validates what comes back,
101
+ * and stores it as the firing's `output`; a run whose answer does not
102
+ * parse fails with reason `invalid_output`.
103
+ */
104
+ output: z.record(z.string(), z.unknown()).nullable(),
105
+ /**
106
+ * The prompt the run starts from, mentions already rendered to names by
107
+ * the console; `{{variables}}` and `{{/json/pointer}}` payload fields
108
+ * are the server's to fill per firing.
109
+ */
110
+ instructions: z.string().max(20_000),
111
+ /** Tools the instructions mention: sandbox bindings for the run, or declared to the model when they park for approval. */
112
+ mentionedTools: z.array(triggerMentionedToolSchema),
113
+ /** Datasets the instructions mention, listed in the run's context whatever the question. */
114
+ mentionedDatasets: z.array(datasetIdentifierSchema),
115
+ threadPolicy: triggerThreadPolicySchema,
116
+ budgetPerDay: z.number().int().positive().nullable(),
117
+ /** Consecutive failed or rejected firings before the trigger disables itself. */
118
+ disableAfterFailures: z.number().int().positive(),
119
+ hasCredential: z.boolean(),
120
+ /**
121
+ * sha256 of the fire secret, so a server checks a presented bearer in
122
+ * process; the Control Center hears only about console test secrets,
123
+ * which it alone can consume.
124
+ */
125
+ secretHash: sha256HexSchema,
126
+ });
127
+ export type TriggerDeclaration = z.infer<typeof triggerDeclarationSchema>;
128
+
129
+ /**
130
+ * `POST /api/runtime/agents/:agentSlug/triggers/:name/auth`: a server holding a
131
+ * bearer for a cc trigger asks cc whether it is the trigger's secret. Only the
132
+ * hash travels; a positive answer carries the trigger's credential, if any.
133
+ */
134
+ export const triggerAuthRequestSchema = z.object({
135
+ secretHash: sha256HexSchema,
136
+ });
137
+ export type TriggerAuthRequest = z.infer<typeof triggerAuthRequestSchema>;
138
+
139
+ export const triggerAuthResponseSchema = z.discriminatedUnion("ok", [
140
+ z.object({
141
+ ok: z.literal(true),
142
+ credential: z.string().nullable(),
143
+ /** The bearer was a single-use test secret, now spent: the server must not cache this verdict. */
144
+ oneShot: z.boolean(),
145
+ }),
146
+ z.object({ ok: z.literal(false) }),
147
+ ]);
148
+ export type TriggerAuthResponse = z.infer<typeof triggerAuthResponseSchema>;
149
+
150
+ /* The server answers a caller firing `POST /agents/:agentSlug/triggers/:name`. */
151
+
152
+ export const triggerFiringResponseSchema = z.discriminatedUnion("outcome", [
153
+ z.object({
154
+ firingId: z.uuid(),
155
+ outcome: z.literal("started"),
156
+ threadId: z.uuid(),
157
+ runId: z.string(),
158
+ }),
159
+ /* The shapes a caller that waited (`?wait=`) gets instead of `started`: the run ended, or it parked for a decision. */
160
+ z.object({
161
+ firingId: z.uuid(),
162
+ outcome: z.literal("awaiting_approval"),
163
+ threadId: z.uuid(),
164
+ runId: z.string(),
165
+ approvals: z.array(
166
+ z.object({ toolCallId: z.string(), toolName: z.string(), input: z.unknown() }),
167
+ ),
168
+ }),
169
+ z.object({
170
+ firingId: z.uuid(),
171
+ outcome: z.literal("completed"),
172
+ threadId: z.uuid(),
173
+ runId: z.string(),
174
+ /** The validated answer when the trigger declares an output schema, else null. */
175
+ output: z.unknown(),
176
+ }),
177
+ z.object({
178
+ firingId: z.uuid(),
179
+ outcome: z.literal("failed"),
180
+ threadId: z.uuid(),
181
+ runId: z.string(),
182
+ reason: z.string().nullable(),
183
+ }),
184
+ z.object({
185
+ firingId: z.uuid(),
186
+ outcome: z.literal("dropped"),
187
+ reason: z.enum(TRIGGER_DROP_REASONS),
188
+ threadId: z.uuid().nullable(),
189
+ }),
190
+ z.object({ firingId: z.uuid(), outcome: z.literal("disabled") }),
191
+ z.object({
192
+ firingId: z.uuid(),
193
+ outcome: z.literal("rejected"),
194
+ issues: z.array(z.object({ path: z.string(), message: z.string() })),
195
+ }),
196
+ ]);
197
+ export type TriggerFiringResponse = z.infer<typeof triggerFiringResponseSchema>;
198
+
199
+ /** `POST /agents/:agentSlug/triggers/:name/firings/:id/answer`: the decision on one parked call. */
200
+ export const triggerFiringAnswerSchema = z.object({
201
+ toolCallId: z.string().min(1).max(256),
202
+ approved: z.boolean(),
203
+ });
204
+ export type TriggerFiringAnswer = z.infer<typeof triggerFiringAnswerSchema>;
205
+
206
+ /** One row of `GET /agents/:agentSlug/triggers/:name/firings`, and the answer of `.../firings/:id`. */
207
+ export const triggerFiringRecordSchema = z.object({
208
+ id: z.uuid(),
209
+ triggerName: z.string(),
210
+ threadId: z.uuid().nullable(),
211
+ runId: z.string().nullable(),
212
+ outcome: z.enum(TRIGGER_OUTCOMES),
213
+ reason: z.string().nullable(),
214
+ /** Set once a run with an output schema completed; null otherwise. */
215
+ output: z.unknown(),
216
+ createdAt: z.iso.datetime(),
217
+ finishedAt: z.iso.datetime().nullable(),
218
+ });
219
+ export type TriggerFiringRecord = z.infer<typeof triggerFiringRecordSchema>;
220
+
221
+ export const triggerFiringListResponseSchema = z.object({
222
+ firings: z.array(triggerFiringRecordSchema),
223
+ });
224
+ export type TriggerFiringListResponse = z.infer<typeof triggerFiringListResponseSchema>;
@@ -0,0 +1,264 @@
1
+ /**
2
+ * The wire contract — every shape that crosses the HTTP/WebSocket boundary
3
+ * between `@m6d/cortex-server` and the client SDKs (`@m6d/cortex-angular`,
4
+ * `@m6d/cortex-react`).
5
+ *
6
+ * Nothing here has a runtime dependency, and nothing here may grow one: this
7
+ * file is compiled into an Angular library, a React library and a Bun server
8
+ * alike.
9
+ */
10
+
11
+ /** The UI locales every localized value is keyed by. */
12
+ export const LOCALES = ["en", "ar"] as const;
13
+ export type Locale = (typeof LOCALES)[number];
14
+
15
+ /** Where an embedded client tool renders: in the message flow or in a modal. */
16
+ export const TOOL_SURFACES = ["inline", "modal"] as const;
17
+ export type ToolSurface = (typeof TOOL_SURFACES)[number];
18
+
19
+ /** `trigger` rows hold a firing's rendered instructions; the model sees them as `user` turns. */
20
+ export const MESSAGE_ROLES = ["system", "user", "assistant", "trigger"] as const;
21
+ export type MessageRole = (typeof MESSAGE_ROLES)[number];
22
+
23
+ export const ATTACHMENT_MIME_TYPES = [
24
+ "image/png",
25
+ "image/jpeg",
26
+ "image/webp",
27
+ "application/pdf",
28
+ ] as const;
29
+
30
+ export const ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024;
31
+
32
+ export const MAX_ATTACHMENTS_PER_MESSAGE = 5;
33
+
34
+ export const ATTACHMENT_STATUSES = ["pending", "described", "failed", "skipped"] as const;
35
+
36
+ /** Who put the file in the thread: the user through the composer, or a tool mid-turn. */
37
+ export const ATTACHMENT_ORIGINS = ["upload", "tool"] as const;
38
+
39
+ export function checkAttachmentPolicy(contentType: string, sizeBytes: number) {
40
+ if (!ATTACHMENT_MIME_TYPES.some((type) => type === contentType)) return "type";
41
+ if (sizeBytes > ATTACHMENT_MAX_BYTES) return "size";
42
+ return "ok";
43
+ }
44
+
45
+ export type AttachmentStatus = (typeof ATTACHMENT_STATUSES)[number];
46
+
47
+ export type AttachmentOrigin = (typeof ATTACHMENT_ORIGINS)[number];
48
+
49
+ export type AttachmentSummary = {
50
+ id: string;
51
+ filename: string;
52
+ contentType: string;
53
+ sizeBytes: number;
54
+ status: AttachmentStatus;
55
+ origin: AttachmentOrigin;
56
+ description: string | null;
57
+ };
58
+
59
+ export type ThreadSummary = {
60
+ id: string;
61
+ title: string | null;
62
+ createdAt: string;
63
+ updatedAt: string;
64
+ isRunning: boolean;
65
+ /** Present on a headless thread a trigger owns. Widgets never list these. */
66
+ trigger?: { name: string };
67
+ };
68
+
69
+ /**
70
+ * Response of `POST /chat/:threadId/abort`. `aborted: false` means there was no
71
+ * live run to abort — the turn had already committed — so the caller must not
72
+ * present the turn as aborted and should read the settled state back instead.
73
+ */
74
+ export type AbortRunResult = {
75
+ aborted: boolean;
76
+ };
77
+
78
+ export type TokenUsage = {
79
+ input: {
80
+ noCache: number;
81
+ cacheRead: number;
82
+ cacheWrite: number;
83
+ total: number;
84
+ };
85
+ output: {
86
+ reasoning: number;
87
+ text: number;
88
+ total: number;
89
+ };
90
+ total: number;
91
+ };
92
+
93
+ /**
94
+ * How to launch one client tool: stamped by the server, per tool name, on
95
+ * the metadata of an assistant message that may carry its pending call. Kept in
96
+ * the message so the binding survives server restarts while a run is parked.
97
+ */
98
+ export type ClientToolBinding = {
99
+ toolId: string;
100
+ surface: ToolSurface;
101
+ embedOrigin: string;
102
+ /** Variables the initiate call's input reads. */
103
+ variables: string[];
104
+ };
105
+
106
+ /**
107
+ * What the server offers this agent's clients, fetched once at widget startup.
108
+ * The widget hides UI for anything absent; enforcement stays server-side.
109
+ */
110
+ export type AgentCapabilities = {
111
+ attachments: boolean;
112
+ /** False when the agent's `message` trigger is off: the widget hides its composer. */
113
+ messages: boolean;
114
+ /** Prompt chips on the blank-chat landing per locale; clicking one sends its `prompt` as the first message. */
115
+ suggestions: Suggestions;
116
+ /** Headline of the blank-chat landing per locale; "" falls back to the widget's built-in copy. */
117
+ greeting: Greeting;
118
+ };
119
+
120
+ export type MessageMetadata = {
121
+ /** ISO time the server stored the message; stamped from the row when a transcript is served. */
122
+ createdAt?: string;
123
+ modelId?: string;
124
+ providerMetadata?: unknown;
125
+ isAborted?: boolean;
126
+ tokenUsage?: TokenUsage;
127
+ attachments?: AttachmentSummary[];
128
+ clientTools?: Record<string, ClientToolBinding>;
129
+ /** Set on `trigger` messages: the firing that wrote them. */
130
+ trigger?: TriggerFiringSummary;
131
+ };
132
+
133
+ /**
134
+ * One landing-page chip: the widget shows `title` and sends `prompt` as the
135
+ * first message when clicked. The two may be the same text.
136
+ */
137
+ export type Suggestion = { title: string; prompt: string };
138
+
139
+ /** The runtime contract's `suggestionsSchema` and `greetingSchema` are built from these. */
140
+ export type Suggestions = Record<Locale, Suggestion[]>;
141
+ export type Greeting = Record<Locale, string>;
142
+
143
+ /** Author-written copy the widget shows verbatim, one string per locale. */
144
+ export type LocalizedText = Record<Locale, string>;
145
+
146
+ /**
147
+ * What cortex stamps on a tool-call part's `metadata.cortex`: the sentence
148
+ * the widget asks with when the call needs the user's approval, in the
149
+ * author's words rather than the function's name.
150
+ */
151
+ export type ToolCallMetadata = {
152
+ approval?: LocalizedText;
153
+ };
154
+
155
+ export type TriggerFiringSummary = {
156
+ name: string;
157
+ firingId: string;
158
+ firedAt: string;
159
+ payload: unknown;
160
+ };
161
+
162
+ /**
163
+ * A stored message as it is persisted and served. TanStack AI's `UIMessage`
164
+ * has no metadata field, so cortex owns the envelope: the SDK's parts plus the
165
+ * server-derived metadata the UI renders on settled messages.
166
+ *
167
+ * `TPart` stays generic so this file keeps its zero dependencies — both
168
+ * sides substitute the SDK's `MessagePart`.
169
+ */
170
+ export type CortexMessage<TPart = unknown> = {
171
+ id: string;
172
+ /** `trigger` rows carry a firing's instructions; the UIs render them as an event, not a bubble. */
173
+ role: MessageRole;
174
+ parts: TPart[];
175
+ metadata?: MessageMetadata;
176
+ };
177
+
178
+ /**
179
+ * Key under the AG-UI request's `forwardedProps` carrying the answers to
180
+ * parked client tool calls on a continuation request. The server owns the
181
+ * transcript (a continuation sends `messages: []`), so the answered assistant
182
+ * message itself never crosses the wire — the SDK's park-boundary snapshot
183
+ * does not preserve its id, and round-tripping it duplicated the stored
184
+ * message.
185
+ */
186
+ export const CLIENT_TOOL_ANSWERS_KEY = "clientToolAnswers";
187
+
188
+ /**
189
+ * One answered call, applied to the stored transcript server-side: a client
190
+ * tool's output (`complete` / `error`), or the user's decision on a server
191
+ * tool that asked for approval (`approved` / `denied`, output null).
192
+ */
193
+ export type ClientToolAnswer = {
194
+ toolCallId: string;
195
+ output: unknown;
196
+ state: "complete" | "error" | "approved" | "denied";
197
+ };
198
+
199
+ /**
200
+ * Response of `POST /chat/:threadId/tools/:toolCallId/initiate`. `embed:
201
+ * false` means the pending call is not a CC client tool — the widget
202
+ * falls back to its default rendering for the call. The payload is for the
203
+ * widget only; it never reaches the LLM.
204
+ */
205
+ export type ClientToolInitiateResult =
206
+ | { embed: false }
207
+ | {
208
+ embed: true;
209
+ embedUrl: string;
210
+ surface: ToolSurface;
211
+ embedOrigin: string;
212
+ };
213
+
214
+ export type ThreadCreatedEvent = {
215
+ type: "thread:created";
216
+ payload: { thread: ThreadSummary };
217
+ };
218
+
219
+ export type ThreadDeletedEvent = {
220
+ type: "thread:deleted";
221
+ payload: { threadId: string };
222
+ };
223
+
224
+ export type ThreadTitleUpdatedEvent = {
225
+ type: "thread:title-updated";
226
+ payload: { thread: ThreadSummary };
227
+ };
228
+
229
+ export type ThreadRunStartedEvent = {
230
+ type: "thread:run-started";
231
+ payload: { thread: ThreadSummary };
232
+ };
233
+
234
+ export type ThreadRunFinishedEvent = {
235
+ type: "thread:run-finished";
236
+ payload: { thread: ThreadSummary };
237
+ };
238
+
239
+ export type ThreadMessagesUpdatedEvent = {
240
+ type: "thread:messages-updated";
241
+ payload: { thread: ThreadSummary };
242
+ };
243
+
244
+ export type ToolProgressEvent = {
245
+ type: "thread:tool-progress";
246
+ payload: {
247
+ threadId: string;
248
+ toolCallId: string;
249
+ toolName: string;
250
+ status: "started" | "finished";
251
+ };
252
+ };
253
+
254
+ export type WsEvent =
255
+ | ThreadCreatedEvent
256
+ | ThreadDeletedEvent
257
+ | ThreadTitleUpdatedEvent
258
+ | ThreadRunStartedEvent
259
+ | ThreadRunFinishedEvent
260
+ | ThreadMessagesUpdatedEvent
261
+ | ToolProgressEvent;
262
+
263
+ /** The header the widget sends the browser's IANA time zone in; the turn reasons in that clock. */
264
+ export const TIMEZONE_HEADER = "X-Cortex-Timezone";