@june-ai/june-ui 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,8 +1,11 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentProps, Component, ReactNode, ErrorInfo, CSSProperties } from 'react';
3
- import { Renderer, createLibrary, defineComponent } from '@openuidev/react-lang';
3
+ import * as _openuidev_react_lang from '@openuidev/react-lang';
4
+ import { Renderer, createLibrary, defineComponent, Library } from '@openuidev/react-lang';
5
+ import * as _openuidev_lang_core from '@openuidev/lang-core';
6
+ import { z } from 'zod/v4';
4
7
 
5
- type JuneErrorCode = "PARSE_ERROR" | "RENDER_ERROR" | "STREAM_ERROR" | "STREAM_ABORTED" | "STREAM_EMPTY" | "NETWORK_ERROR" | "ACTION_ERROR" | "ACTION_VALIDATION_ERROR" | "ACTION_REJECTED" | "LIBRARY_ERROR";
8
+ type JuneErrorCode = "PARSE_ERROR" | "RENDER_ERROR" | "STREAM_ERROR" | "STREAM_ABORTED" | "STREAM_EMPTY" | "NETWORK_ERROR" | "ACTION_ERROR" | "ACTION_VALIDATION_ERROR" | "ACTION_REJECTED" | "LIBRARY_ERROR" | "DOCUMENT_ERROR" | "EXPORT_ERROR";
6
9
  interface JuneErrorOptions {
7
10
  cause?: unknown;
8
11
  details?: unknown;
@@ -88,6 +91,138 @@ interface RunActionOptions {
88
91
  declare function runAction(event: OpenUIActionEvent, options: RunActionOptions): Promise<ActionOutcome>;
89
92
  declare function createActionHandler(options: RunActionOptions): (event: OpenUIActionEvent) => void;
90
93
 
94
+ interface PendingUpdate {
95
+ json: DocJSON;
96
+ title: string;
97
+ /** AI changes merged in, with the user's version kept where both changed the same blocks. */
98
+ merged: DocJSON;
99
+ conflicts: number;
100
+ }
101
+ interface DocumentRecord {
102
+ id: string;
103
+ title: string;
104
+ documentType?: string;
105
+ status?: string;
106
+ /** What the user currently sees. */
107
+ json: DocJSON;
108
+ /** The last AI version that was accepted. Used as the merge base. */
109
+ baseJson: DocJSON;
110
+ baseTitle: string;
111
+ lastIncomingKey: string;
112
+ /** Increments whenever `json` changes. */
113
+ revision: number;
114
+ /** Which editor (or "external") produced the latest change. */
115
+ origin: string;
116
+ pending: PendingUpdate | null;
117
+ updatedAt: number;
118
+ }
119
+ interface IncomingDocument {
120
+ id: string;
121
+ title: string;
122
+ json: DocJSON;
123
+ documentType?: string;
124
+ status?: string;
125
+ }
126
+ type ReceiveOutcome = "created" | "unchanged" | "applied" | "merged" | "conflict";
127
+ type ResolveChoice = "merge" | "replace" | "keep";
128
+ interface DocumentStore {
129
+ get(id: string): DocumentRecord | undefined;
130
+ list(): DocumentRecord[];
131
+ subscribe(listener: () => void): () => void;
132
+ /** An AI version arrived. Applies it, merges it with user edits, or records a conflict. */
133
+ receive(incoming: IncomingDocument): ReceiveOutcome;
134
+ /** Seed or replace a document, for example from your database. */
135
+ hydrate(doc: IncomingDocument): void;
136
+ edit(id: string, json: DocJSON, origin: string): void;
137
+ setTitle(id: string, title: string): void;
138
+ resolve(id: string, choice: ResolveChoice): void;
139
+ remove(id: string): void;
140
+ }
141
+ declare function createDocumentStore(): DocumentStore;
142
+ /** The shared in-memory store used when none is provided. Documents are keyed by documentId. */
143
+ declare function getDefaultDocumentStore(): DocumentStore;
144
+
145
+ /** Structural type of a Tiptap / ProseMirror JSON node. Dependency-free on purpose. */
146
+ interface DocNode {
147
+ type: string;
148
+ attrs?: Record<string, unknown>;
149
+ content?: DocNode[];
150
+ marks?: {
151
+ type: string;
152
+ attrs?: Record<string, unknown>;
153
+ }[];
154
+ text?: string;
155
+ }
156
+ /** Canonical document format: a Tiptap JSON document. */
157
+ interface DocJSON {
158
+ type: "doc";
159
+ content?: DocNode[];
160
+ }
161
+ type DocumentExportFormat = "html" | "markdown" | "txt" | "docx" | "pdf";
162
+ declare const ALL_EXPORT_FORMATS: readonly DocumentExportFormat[];
163
+ interface DocumentSnapshot {
164
+ documentId: string;
165
+ title: string;
166
+ documentType?: string;
167
+ status?: string;
168
+ json: DocJSON;
169
+ }
170
+ interface DocumentChange extends DocumentSnapshot {
171
+ /** user = typed in the editor, ai = new AI version applied, merge = AI merged with user edits, resolve = conflict resolved. */
172
+ source: "user" | "ai" | "merge" | "resolve";
173
+ }
174
+ interface DocumentSavePayload extends DocumentSnapshot {
175
+ html: string;
176
+ markdown: string;
177
+ }
178
+ interface DocumentExportEvent {
179
+ documentId: string;
180
+ format: string;
181
+ filename: string;
182
+ mimeType: string;
183
+ blob?: Blob;
184
+ text?: string;
185
+ /** True when the exporter delivered the file itself (for example the PDF print dialog). */
186
+ handled?: boolean;
187
+ }
188
+ interface DocumentConflict {
189
+ documentId: string;
190
+ title: string;
191
+ /** Number of regions that both the user and the assistant changed. */
192
+ conflicts: number;
193
+ }
194
+ interface JuneDocumentOptions {
195
+ /** Share one store across editors. Defaults to a global in-memory store, keyed by documentId. */
196
+ store?: DocumentStore;
197
+ /** Debounce for autosave in ms (default 1500). 0 or less disables autosave. */
198
+ autosaveDelay?: number;
199
+ onDocumentChange?: (change: DocumentChange) => void;
200
+ /** Persist the document. Called by autosave, the Save button and Ctrl/Cmd+S. */
201
+ onSave?: (payload: DocumentSavePayload) => void | Promise<void>;
202
+ onExport?: (event: DocumentExportEvent) => void;
203
+ onDocumentReady?: (snapshot: DocumentSnapshot) => void;
204
+ onConflict?: (conflict: DocumentConflict) => void;
205
+ onError?: (error: JuneError) => void;
206
+ }
207
+ interface DocumentEditorProps {
208
+ documentId: string;
209
+ title?: string;
210
+ /** Markdown, a Tiptap JSON string, or a Tiptap JSON object. */
211
+ content?: string | DocJSON;
212
+ documentType?: string;
213
+ /** Default "draft". Drafts show an "AI draft" badge. */
214
+ status?: string;
215
+ editable?: boolean;
216
+ exportFormats?: string[];
217
+ /** "auto" follows the June theme context. */
218
+ theme?: "auto" | "light" | "dark";
219
+ className?: string;
220
+ /** Show the drafting placeholder instead of the editor (use while content is streaming). */
221
+ generating?: boolean;
222
+ /** Callbacks and store. Merged over the values provided through JuneUI's `documents` prop. */
223
+ options?: JuneDocumentOptions;
224
+ }
225
+
91
226
  type JuneThemeVars = Record<string, string>;
92
227
  /** Colors only. June never sets fonts, radii or backgrounds. */
93
228
  declare const lightTheme: JuneThemeVars;
@@ -120,14 +255,17 @@ type JuneRendererProps = Omit<OpenUIRendererProps, "library" | "response" | "isS
120
255
  /** Accumulated model output. OpenUI does the incremental parsing. */
121
256
  response: string | null;
122
257
  isStreaming?: boolean;
123
- /**
124
- * Render prose around OpenUI statements (default true). The response may be
125
- * plain OpenUI Lang, or prose + OpenUI Lang, optionally inside ``` fences.
126
- * Set false to hand the response to OpenUI untouched.
127
- */
258
+ /** Allow prose around OpenUI statements (default true). */
128
259
  mixedContent?: boolean;
129
260
  /** Custom renderer for prose segments. Default: <p className="june-text">. */
130
261
  renderText?: (text: string, index: number) => ReactNode;
262
+ /**
263
+ * Rewrite common model mistakes after streaming ends (default true):
264
+ * Grid and shorthand Card calls, and charts or tables left off root.
265
+ * Set false to hand the program to OpenUI unchanged.
266
+ */
267
+ repair?: boolean;
268
+ /** Omit to inherit the host app's look. "light" | "dark" | "system" opt in to June's colors. */
131
269
  theme?: JuneThemeMode;
132
270
  themeVars?: JuneThemeVars;
133
271
  className?: string;
@@ -139,8 +277,10 @@ type JuneRendererProps = Omit<OpenUIRendererProps, "library" | "response" | "isS
139
277
  onAction?: (event: OpenUIActionEvent) => void;
140
278
  /** Raw OpenUI errors (called with [] when they resolve). */
141
279
  onError?: (errors: unknown[]) => void;
142
- /** Structured errors: parse, render, and action failures. */
280
+ /** Structured errors: parse, render, action, document and export failures. */
143
281
  onJuneError?: (error: JuneError) => void;
282
+ /** Document editor callbacks and store. Memoize this object. */
283
+ documents?: JuneDocumentOptions;
144
284
  loadingFallback?: ReactNode;
145
285
  emptyFallback?: ReactNode;
146
286
  errorFallback?: ReactNode | ((args: FallbackArgs) => ReactNode);
@@ -170,6 +310,12 @@ interface JuneContextValue {
170
310
  theme: JuneResolvedTheme;
171
311
  }
172
312
  declare function useJuneTheme(): JuneContextValue;
313
+ interface JuneRuntimeValue {
314
+ /** True while the response is still streaming. Custom components use it to defer heavy work. */
315
+ isStreaming: boolean;
316
+ }
317
+ declare const JuneRuntimeContext: react.Context<JuneRuntimeValue>;
318
+ declare function useJuneRuntime(): JuneRuntimeValue;
173
319
 
174
320
  /** Re-export of OpenUI's component definer under a June name. */
175
321
  declare const defineJuneComponent: typeof defineComponent;
@@ -252,10 +398,107 @@ declare function sseToText(source: StreamSource, options?: SseOptions & {
252
398
  */
253
399
  declare function jsonFieldExtractor(path: string): (data: string) => string | null;
254
400
 
401
+ /** Standalone editor. While a June response is still streaming, shows a placeholder instead of mounting Tiptap. */
402
+ declare function DocumentEditor(props: DocumentEditorProps): react.JSX.Element;
403
+ declare const JuneDocumentEditorComponent: _openuidev_react_lang.DefinedComponent<z.ZodObject<{
404
+ documentId: z.ZodString;
405
+ title: z.ZodString;
406
+ content: z.ZodString;
407
+ documentType: z.ZodOptional<z.ZodString>;
408
+ status: z.ZodOptional<z.ZodString>;
409
+ editable: z.ZodOptional<z.ZodBoolean>;
410
+ exportFormats: z.ZodOptional<z.ZodArray<z.ZodString>>;
411
+ }, z.core.$strip>>;
412
+ type Extendable = Library & {
413
+ extend: NonNullable<Library["extend"]>;
414
+ };
415
+ /**
416
+ * Returns a library that contains every component of `library` plus DocumentEditor,
417
+ * and allows DocumentEditor inside Card (Stack already accepts any child).
418
+ * The library must include Card, which both OpenUI libraries do.
419
+ */
420
+ declare function withDocumentEditor(library: Extendable): Required<_openuidev_lang_core.Library<_openuidev_react_lang.ComponentRenderer<any>, _openuidev_lang_core.DefinedAction<any, string>>>;
421
+
422
+ declare const JuneDocumentContext: react.Context<JuneDocumentOptions>;
423
+ declare function useDocumentOptions(): JuneDocumentOptions;
424
+
425
+ declare function mergeDocuments(base: DocJSON, local: DocJSON, incoming: DocJSON): {
426
+ doc: DocJSON;
427
+ conflicts: number;
428
+ };
429
+
430
+ interface ExportContext {
431
+ documentId: string;
432
+ title: string;
433
+ json: DocJSON;
434
+ /** File name without extension. */
435
+ basename: string;
436
+ }
437
+ interface ExportResult {
438
+ filename: string;
439
+ mimeType: string;
440
+ blob?: Blob;
441
+ text?: string;
442
+ /** True when the exporter delivered the file itself, for example the print dialog for PDF. */
443
+ handled?: boolean;
444
+ }
445
+ type DocumentExporter = (context: ExportContext) => ExportResult | Promise<ExportResult>;
446
+ /** Adds or replaces an export format. */
447
+ declare function registerDocumentExporter(format: string, exporter: DocumentExporter): void;
448
+ declare function listDocumentExporters(): string[];
449
+ declare function exportDocument(format: string, doc: {
450
+ documentId: string;
451
+ title: string;
452
+ json: DocJSON;
453
+ }): Promise<ExportResult>;
454
+ /** Starts a browser download for results that carry a Blob. */
455
+ declare function downloadResult(result: ExportResult): void;
456
+ /** Copies rich text and plain text. Returns false if the browser refuses. */
457
+ declare function copyDocumentToClipboard(doc: {
458
+ title: string;
459
+ json: DocJSON;
460
+ }): Promise<boolean>;
461
+
462
+ interface DocumentInstructionOptions {
463
+ /** Examples of document types for your product. Default covers common business documents. */
464
+ documentTypes?: string[];
465
+ /** Extra rules appended after the built-in ones (tone, legal disclaimers, language, ...). */
466
+ extraRules?: string[];
467
+ /** Name of the component in your library. Default "DocumentEditor". */
468
+ componentName?: string;
469
+ }
470
+ /** Rules for the model. Pass them through your backend to any agent. */
471
+ declare function getDocumentEditorRules(options?: DocumentInstructionOptions): string[];
472
+ /** Text block you can paste into any agent's system prompt. */
473
+ declare function getDocumentEditorInstructions(options?: DocumentInstructionOptions): string;
474
+ /**
475
+ * Options for OpenUI's `library.prompt(options)`. Merge these with your own PromptOptions.
476
+ * Example: library.prompt({ ...documentPromptOptions(), preamble: "..." })
477
+ */
478
+ declare function documentPromptOptions(options?: DocumentInstructionOptions): {
479
+ additionalRules: string[];
480
+ examples: string[];
481
+ };
482
+
483
+ /**
484
+ * Serialises the documents the user currently has (including their edits) as Markdown,
485
+ * ready to attach to the next message so the agent can edit the right text.
486
+ */
487
+ declare function serializeDocumentsForAgent(options?: {
488
+ store?: DocumentStore;
489
+ ids?: string[];
490
+ }): Promise<string>;
491
+
255
492
  type JuneUIProps = Omit<JuneRendererProps, "library"> & {
256
- /** Defaults to OpenUI's built-in library (same behaviour as 0.1.0). */
493
+ /** Defaults to June's library: OpenUI's components plus DocumentEditor. */
257
494
  library?: OpenUILibrary;
258
495
  };
259
496
  declare function JuneUI({ library, ...props }: JuneUIProps): react.JSX.Element;
260
497
 
261
- export { type ActionEventParser, type ActionOutcome, type ConfirmAction, type ConsumeStreamOptions, type FallbackArgs, type FetchStreamOptions, type JuneAction, type JuneActionContext, type JuneActionDefinition, type JuneActionMap, JuneError, JuneErrorBoundary, type JuneErrorBoundaryProps, type JuneErrorCode, type JuneErrorOptions, type JuneLibraryOptions, JuneRenderer, type JuneRendererProps, type JuneResolvedTheme, type JuneStreamState, type JuneThemeMode, JuneThemeProvider, type JuneThemeProviderProps, type JuneThemeVars, JuneUI, type JuneUIProps, type OpenUIActionEvent, type OpenUILibrary, type OpenUIRendererProps, type ParsedActionEvent, type RunActionOptions, type SchemaLike, type SseOptions, type StreamChunk, type StreamSource, type StreamStarter, type StreamStatus, type UseJuneStreamOptions, type UseJuneStreamResult, consumeStream, createActionHandler, createJuneLibrary, darkTheme, defaultParseActionEvent, defineJuneAction, defineJuneComponent, fetchStream, isJuneError, jsonFieldExtractor, lightTheme, runAction, sseToText, toJuneError, useJuneStream, useJuneTheme, useResolvedTheme };
498
+ /**
499
+ * June's default library: every OpenUI component plus DocumentEditor.
500
+ * Created once so its reference stays stable.
501
+ */
502
+ declare const juneLibrary: Required<_openuidev_lang_core.Library<_openuidev_react_lang.ComponentRenderer<any>, _openuidev_lang_core.DefinedAction<any, string>>>;
503
+
504
+ export { ALL_EXPORT_FORMATS, type ActionEventParser, type ActionOutcome, type ConfirmAction, type ConsumeStreamOptions, type DocJSON, type DocNode, type DocumentChange, type DocumentConflict, DocumentEditor, type DocumentEditorProps, type DocumentExportEvent, type DocumentExportFormat, type DocumentExporter, type DocumentInstructionOptions, type DocumentRecord, type DocumentSavePayload, type DocumentSnapshot, type DocumentStore, type ExportContext, type ExportResult, type FallbackArgs, type FetchStreamOptions, type JuneAction, type JuneActionContext, type JuneActionDefinition, type JuneActionMap, JuneDocumentContext, JuneDocumentEditorComponent, type JuneDocumentOptions, JuneError, JuneErrorBoundary, type JuneErrorBoundaryProps, type JuneErrorCode, type JuneErrorOptions, type JuneLibraryOptions, JuneRenderer, type JuneRendererProps, type JuneResolvedTheme, JuneRuntimeContext, type JuneStreamState, type JuneThemeMode, JuneThemeProvider, type JuneThemeProviderProps, type JuneThemeVars, JuneUI, type JuneUIProps, type OpenUIActionEvent, type OpenUILibrary, type OpenUIRendererProps, type ParsedActionEvent, type RunActionOptions, type SchemaLike, type SseOptions, type StreamChunk, type StreamSource, type StreamStarter, type StreamStatus, type UseJuneStreamOptions, type UseJuneStreamResult, consumeStream, copyDocumentToClipboard, createActionHandler, createDocumentStore, createJuneLibrary, darkTheme, defaultParseActionEvent, defineJuneAction, defineJuneComponent, documentPromptOptions, downloadResult, exportDocument, fetchStream, getDefaultDocumentStore, getDocumentEditorInstructions, getDocumentEditorRules, isJuneError, jsonFieldExtractor, juneLibrary, lightTheme, listDocumentExporters, mergeDocuments, registerDocumentExporter, runAction, serializeDocumentsForAgent, sseToText, toJuneError, useDocumentOptions, useJuneRuntime, useJuneStream, useJuneTheme, useResolvedTheme, withDocumentEditor };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentProps, Component, ReactNode, ErrorInfo, CSSProperties } from 'react';
3
- import { Renderer, createLibrary, defineComponent } from '@openuidev/react-lang';
3
+ import * as _openuidev_react_lang from '@openuidev/react-lang';
4
+ import { Renderer, createLibrary, defineComponent, Library } from '@openuidev/react-lang';
5
+ import * as _openuidev_lang_core from '@openuidev/lang-core';
6
+ import { z } from 'zod/v4';
4
7
 
5
- type JuneErrorCode = "PARSE_ERROR" | "RENDER_ERROR" | "STREAM_ERROR" | "STREAM_ABORTED" | "STREAM_EMPTY" | "NETWORK_ERROR" | "ACTION_ERROR" | "ACTION_VALIDATION_ERROR" | "ACTION_REJECTED" | "LIBRARY_ERROR";
8
+ type JuneErrorCode = "PARSE_ERROR" | "RENDER_ERROR" | "STREAM_ERROR" | "STREAM_ABORTED" | "STREAM_EMPTY" | "NETWORK_ERROR" | "ACTION_ERROR" | "ACTION_VALIDATION_ERROR" | "ACTION_REJECTED" | "LIBRARY_ERROR" | "DOCUMENT_ERROR" | "EXPORT_ERROR";
6
9
  interface JuneErrorOptions {
7
10
  cause?: unknown;
8
11
  details?: unknown;
@@ -88,6 +91,138 @@ interface RunActionOptions {
88
91
  declare function runAction(event: OpenUIActionEvent, options: RunActionOptions): Promise<ActionOutcome>;
89
92
  declare function createActionHandler(options: RunActionOptions): (event: OpenUIActionEvent) => void;
90
93
 
94
+ interface PendingUpdate {
95
+ json: DocJSON;
96
+ title: string;
97
+ /** AI changes merged in, with the user's version kept where both changed the same blocks. */
98
+ merged: DocJSON;
99
+ conflicts: number;
100
+ }
101
+ interface DocumentRecord {
102
+ id: string;
103
+ title: string;
104
+ documentType?: string;
105
+ status?: string;
106
+ /** What the user currently sees. */
107
+ json: DocJSON;
108
+ /** The last AI version that was accepted. Used as the merge base. */
109
+ baseJson: DocJSON;
110
+ baseTitle: string;
111
+ lastIncomingKey: string;
112
+ /** Increments whenever `json` changes. */
113
+ revision: number;
114
+ /** Which editor (or "external") produced the latest change. */
115
+ origin: string;
116
+ pending: PendingUpdate | null;
117
+ updatedAt: number;
118
+ }
119
+ interface IncomingDocument {
120
+ id: string;
121
+ title: string;
122
+ json: DocJSON;
123
+ documentType?: string;
124
+ status?: string;
125
+ }
126
+ type ReceiveOutcome = "created" | "unchanged" | "applied" | "merged" | "conflict";
127
+ type ResolveChoice = "merge" | "replace" | "keep";
128
+ interface DocumentStore {
129
+ get(id: string): DocumentRecord | undefined;
130
+ list(): DocumentRecord[];
131
+ subscribe(listener: () => void): () => void;
132
+ /** An AI version arrived. Applies it, merges it with user edits, or records a conflict. */
133
+ receive(incoming: IncomingDocument): ReceiveOutcome;
134
+ /** Seed or replace a document, for example from your database. */
135
+ hydrate(doc: IncomingDocument): void;
136
+ edit(id: string, json: DocJSON, origin: string): void;
137
+ setTitle(id: string, title: string): void;
138
+ resolve(id: string, choice: ResolveChoice): void;
139
+ remove(id: string): void;
140
+ }
141
+ declare function createDocumentStore(): DocumentStore;
142
+ /** The shared in-memory store used when none is provided. Documents are keyed by documentId. */
143
+ declare function getDefaultDocumentStore(): DocumentStore;
144
+
145
+ /** Structural type of a Tiptap / ProseMirror JSON node. Dependency-free on purpose. */
146
+ interface DocNode {
147
+ type: string;
148
+ attrs?: Record<string, unknown>;
149
+ content?: DocNode[];
150
+ marks?: {
151
+ type: string;
152
+ attrs?: Record<string, unknown>;
153
+ }[];
154
+ text?: string;
155
+ }
156
+ /** Canonical document format: a Tiptap JSON document. */
157
+ interface DocJSON {
158
+ type: "doc";
159
+ content?: DocNode[];
160
+ }
161
+ type DocumentExportFormat = "html" | "markdown" | "txt" | "docx" | "pdf";
162
+ declare const ALL_EXPORT_FORMATS: readonly DocumentExportFormat[];
163
+ interface DocumentSnapshot {
164
+ documentId: string;
165
+ title: string;
166
+ documentType?: string;
167
+ status?: string;
168
+ json: DocJSON;
169
+ }
170
+ interface DocumentChange extends DocumentSnapshot {
171
+ /** user = typed in the editor, ai = new AI version applied, merge = AI merged with user edits, resolve = conflict resolved. */
172
+ source: "user" | "ai" | "merge" | "resolve";
173
+ }
174
+ interface DocumentSavePayload extends DocumentSnapshot {
175
+ html: string;
176
+ markdown: string;
177
+ }
178
+ interface DocumentExportEvent {
179
+ documentId: string;
180
+ format: string;
181
+ filename: string;
182
+ mimeType: string;
183
+ blob?: Blob;
184
+ text?: string;
185
+ /** True when the exporter delivered the file itself (for example the PDF print dialog). */
186
+ handled?: boolean;
187
+ }
188
+ interface DocumentConflict {
189
+ documentId: string;
190
+ title: string;
191
+ /** Number of regions that both the user and the assistant changed. */
192
+ conflicts: number;
193
+ }
194
+ interface JuneDocumentOptions {
195
+ /** Share one store across editors. Defaults to a global in-memory store, keyed by documentId. */
196
+ store?: DocumentStore;
197
+ /** Debounce for autosave in ms (default 1500). 0 or less disables autosave. */
198
+ autosaveDelay?: number;
199
+ onDocumentChange?: (change: DocumentChange) => void;
200
+ /** Persist the document. Called by autosave, the Save button and Ctrl/Cmd+S. */
201
+ onSave?: (payload: DocumentSavePayload) => void | Promise<void>;
202
+ onExport?: (event: DocumentExportEvent) => void;
203
+ onDocumentReady?: (snapshot: DocumentSnapshot) => void;
204
+ onConflict?: (conflict: DocumentConflict) => void;
205
+ onError?: (error: JuneError) => void;
206
+ }
207
+ interface DocumentEditorProps {
208
+ documentId: string;
209
+ title?: string;
210
+ /** Markdown, a Tiptap JSON string, or a Tiptap JSON object. */
211
+ content?: string | DocJSON;
212
+ documentType?: string;
213
+ /** Default "draft". Drafts show an "AI draft" badge. */
214
+ status?: string;
215
+ editable?: boolean;
216
+ exportFormats?: string[];
217
+ /** "auto" follows the June theme context. */
218
+ theme?: "auto" | "light" | "dark";
219
+ className?: string;
220
+ /** Show the drafting placeholder instead of the editor (use while content is streaming). */
221
+ generating?: boolean;
222
+ /** Callbacks and store. Merged over the values provided through JuneUI's `documents` prop. */
223
+ options?: JuneDocumentOptions;
224
+ }
225
+
91
226
  type JuneThemeVars = Record<string, string>;
92
227
  /** Colors only. June never sets fonts, radii or backgrounds. */
93
228
  declare const lightTheme: JuneThemeVars;
@@ -120,14 +255,17 @@ type JuneRendererProps = Omit<OpenUIRendererProps, "library" | "response" | "isS
120
255
  /** Accumulated model output. OpenUI does the incremental parsing. */
121
256
  response: string | null;
122
257
  isStreaming?: boolean;
123
- /**
124
- * Render prose around OpenUI statements (default true). The response may be
125
- * plain OpenUI Lang, or prose + OpenUI Lang, optionally inside ``` fences.
126
- * Set false to hand the response to OpenUI untouched.
127
- */
258
+ /** Allow prose around OpenUI statements (default true). */
128
259
  mixedContent?: boolean;
129
260
  /** Custom renderer for prose segments. Default: <p className="june-text">. */
130
261
  renderText?: (text: string, index: number) => ReactNode;
262
+ /**
263
+ * Rewrite common model mistakes after streaming ends (default true):
264
+ * Grid and shorthand Card calls, and charts or tables left off root.
265
+ * Set false to hand the program to OpenUI unchanged.
266
+ */
267
+ repair?: boolean;
268
+ /** Omit to inherit the host app's look. "light" | "dark" | "system" opt in to June's colors. */
131
269
  theme?: JuneThemeMode;
132
270
  themeVars?: JuneThemeVars;
133
271
  className?: string;
@@ -139,8 +277,10 @@ type JuneRendererProps = Omit<OpenUIRendererProps, "library" | "response" | "isS
139
277
  onAction?: (event: OpenUIActionEvent) => void;
140
278
  /** Raw OpenUI errors (called with [] when they resolve). */
141
279
  onError?: (errors: unknown[]) => void;
142
- /** Structured errors: parse, render, and action failures. */
280
+ /** Structured errors: parse, render, action, document and export failures. */
143
281
  onJuneError?: (error: JuneError) => void;
282
+ /** Document editor callbacks and store. Memoize this object. */
283
+ documents?: JuneDocumentOptions;
144
284
  loadingFallback?: ReactNode;
145
285
  emptyFallback?: ReactNode;
146
286
  errorFallback?: ReactNode | ((args: FallbackArgs) => ReactNode);
@@ -170,6 +310,12 @@ interface JuneContextValue {
170
310
  theme: JuneResolvedTheme;
171
311
  }
172
312
  declare function useJuneTheme(): JuneContextValue;
313
+ interface JuneRuntimeValue {
314
+ /** True while the response is still streaming. Custom components use it to defer heavy work. */
315
+ isStreaming: boolean;
316
+ }
317
+ declare const JuneRuntimeContext: react.Context<JuneRuntimeValue>;
318
+ declare function useJuneRuntime(): JuneRuntimeValue;
173
319
 
174
320
  /** Re-export of OpenUI's component definer under a June name. */
175
321
  declare const defineJuneComponent: typeof defineComponent;
@@ -252,10 +398,107 @@ declare function sseToText(source: StreamSource, options?: SseOptions & {
252
398
  */
253
399
  declare function jsonFieldExtractor(path: string): (data: string) => string | null;
254
400
 
401
+ /** Standalone editor. While a June response is still streaming, shows a placeholder instead of mounting Tiptap. */
402
+ declare function DocumentEditor(props: DocumentEditorProps): react.JSX.Element;
403
+ declare const JuneDocumentEditorComponent: _openuidev_react_lang.DefinedComponent<z.ZodObject<{
404
+ documentId: z.ZodString;
405
+ title: z.ZodString;
406
+ content: z.ZodString;
407
+ documentType: z.ZodOptional<z.ZodString>;
408
+ status: z.ZodOptional<z.ZodString>;
409
+ editable: z.ZodOptional<z.ZodBoolean>;
410
+ exportFormats: z.ZodOptional<z.ZodArray<z.ZodString>>;
411
+ }, z.core.$strip>>;
412
+ type Extendable = Library & {
413
+ extend: NonNullable<Library["extend"]>;
414
+ };
415
+ /**
416
+ * Returns a library that contains every component of `library` plus DocumentEditor,
417
+ * and allows DocumentEditor inside Card (Stack already accepts any child).
418
+ * The library must include Card, which both OpenUI libraries do.
419
+ */
420
+ declare function withDocumentEditor(library: Extendable): Required<_openuidev_lang_core.Library<_openuidev_react_lang.ComponentRenderer<any>, _openuidev_lang_core.DefinedAction<any, string>>>;
421
+
422
+ declare const JuneDocumentContext: react.Context<JuneDocumentOptions>;
423
+ declare function useDocumentOptions(): JuneDocumentOptions;
424
+
425
+ declare function mergeDocuments(base: DocJSON, local: DocJSON, incoming: DocJSON): {
426
+ doc: DocJSON;
427
+ conflicts: number;
428
+ };
429
+
430
+ interface ExportContext {
431
+ documentId: string;
432
+ title: string;
433
+ json: DocJSON;
434
+ /** File name without extension. */
435
+ basename: string;
436
+ }
437
+ interface ExportResult {
438
+ filename: string;
439
+ mimeType: string;
440
+ blob?: Blob;
441
+ text?: string;
442
+ /** True when the exporter delivered the file itself, for example the print dialog for PDF. */
443
+ handled?: boolean;
444
+ }
445
+ type DocumentExporter = (context: ExportContext) => ExportResult | Promise<ExportResult>;
446
+ /** Adds or replaces an export format. */
447
+ declare function registerDocumentExporter(format: string, exporter: DocumentExporter): void;
448
+ declare function listDocumentExporters(): string[];
449
+ declare function exportDocument(format: string, doc: {
450
+ documentId: string;
451
+ title: string;
452
+ json: DocJSON;
453
+ }): Promise<ExportResult>;
454
+ /** Starts a browser download for results that carry a Blob. */
455
+ declare function downloadResult(result: ExportResult): void;
456
+ /** Copies rich text and plain text. Returns false if the browser refuses. */
457
+ declare function copyDocumentToClipboard(doc: {
458
+ title: string;
459
+ json: DocJSON;
460
+ }): Promise<boolean>;
461
+
462
+ interface DocumentInstructionOptions {
463
+ /** Examples of document types for your product. Default covers common business documents. */
464
+ documentTypes?: string[];
465
+ /** Extra rules appended after the built-in ones (tone, legal disclaimers, language, ...). */
466
+ extraRules?: string[];
467
+ /** Name of the component in your library. Default "DocumentEditor". */
468
+ componentName?: string;
469
+ }
470
+ /** Rules for the model. Pass them through your backend to any agent. */
471
+ declare function getDocumentEditorRules(options?: DocumentInstructionOptions): string[];
472
+ /** Text block you can paste into any agent's system prompt. */
473
+ declare function getDocumentEditorInstructions(options?: DocumentInstructionOptions): string;
474
+ /**
475
+ * Options for OpenUI's `library.prompt(options)`. Merge these with your own PromptOptions.
476
+ * Example: library.prompt({ ...documentPromptOptions(), preamble: "..." })
477
+ */
478
+ declare function documentPromptOptions(options?: DocumentInstructionOptions): {
479
+ additionalRules: string[];
480
+ examples: string[];
481
+ };
482
+
483
+ /**
484
+ * Serialises the documents the user currently has (including their edits) as Markdown,
485
+ * ready to attach to the next message so the agent can edit the right text.
486
+ */
487
+ declare function serializeDocumentsForAgent(options?: {
488
+ store?: DocumentStore;
489
+ ids?: string[];
490
+ }): Promise<string>;
491
+
255
492
  type JuneUIProps = Omit<JuneRendererProps, "library"> & {
256
- /** Defaults to OpenUI's built-in library (same behaviour as 0.1.0). */
493
+ /** Defaults to June's library: OpenUI's components plus DocumentEditor. */
257
494
  library?: OpenUILibrary;
258
495
  };
259
496
  declare function JuneUI({ library, ...props }: JuneUIProps): react.JSX.Element;
260
497
 
261
- export { type ActionEventParser, type ActionOutcome, type ConfirmAction, type ConsumeStreamOptions, type FallbackArgs, type FetchStreamOptions, type JuneAction, type JuneActionContext, type JuneActionDefinition, type JuneActionMap, JuneError, JuneErrorBoundary, type JuneErrorBoundaryProps, type JuneErrorCode, type JuneErrorOptions, type JuneLibraryOptions, JuneRenderer, type JuneRendererProps, type JuneResolvedTheme, type JuneStreamState, type JuneThemeMode, JuneThemeProvider, type JuneThemeProviderProps, type JuneThemeVars, JuneUI, type JuneUIProps, type OpenUIActionEvent, type OpenUILibrary, type OpenUIRendererProps, type ParsedActionEvent, type RunActionOptions, type SchemaLike, type SseOptions, type StreamChunk, type StreamSource, type StreamStarter, type StreamStatus, type UseJuneStreamOptions, type UseJuneStreamResult, consumeStream, createActionHandler, createJuneLibrary, darkTheme, defaultParseActionEvent, defineJuneAction, defineJuneComponent, fetchStream, isJuneError, jsonFieldExtractor, lightTheme, runAction, sseToText, toJuneError, useJuneStream, useJuneTheme, useResolvedTheme };
498
+ /**
499
+ * June's default library: every OpenUI component plus DocumentEditor.
500
+ * Created once so its reference stays stable.
501
+ */
502
+ declare const juneLibrary: Required<_openuidev_lang_core.Library<_openuidev_react_lang.ComponentRenderer<any>, _openuidev_lang_core.DefinedAction<any, string>>>;
503
+
504
+ export { ALL_EXPORT_FORMATS, type ActionEventParser, type ActionOutcome, type ConfirmAction, type ConsumeStreamOptions, type DocJSON, type DocNode, type DocumentChange, type DocumentConflict, DocumentEditor, type DocumentEditorProps, type DocumentExportEvent, type DocumentExportFormat, type DocumentExporter, type DocumentInstructionOptions, type DocumentRecord, type DocumentSavePayload, type DocumentSnapshot, type DocumentStore, type ExportContext, type ExportResult, type FallbackArgs, type FetchStreamOptions, type JuneAction, type JuneActionContext, type JuneActionDefinition, type JuneActionMap, JuneDocumentContext, JuneDocumentEditorComponent, type JuneDocumentOptions, JuneError, JuneErrorBoundary, type JuneErrorBoundaryProps, type JuneErrorCode, type JuneErrorOptions, type JuneLibraryOptions, JuneRenderer, type JuneRendererProps, type JuneResolvedTheme, JuneRuntimeContext, type JuneStreamState, type JuneThemeMode, JuneThemeProvider, type JuneThemeProviderProps, type JuneThemeVars, JuneUI, type JuneUIProps, type OpenUIActionEvent, type OpenUILibrary, type OpenUIRendererProps, type ParsedActionEvent, type RunActionOptions, type SchemaLike, type SseOptions, type StreamChunk, type StreamSource, type StreamStarter, type StreamStatus, type UseJuneStreamOptions, type UseJuneStreamResult, consumeStream, copyDocumentToClipboard, createActionHandler, createDocumentStore, createJuneLibrary, darkTheme, defaultParseActionEvent, defineJuneAction, defineJuneComponent, documentPromptOptions, downloadResult, exportDocument, fetchStream, getDefaultDocumentStore, getDocumentEditorInstructions, getDocumentEditorRules, isJuneError, jsonFieldExtractor, juneLibrary, lightTheme, listDocumentExporters, mergeDocuments, registerDocumentExporter, runAction, serializeDocumentsForAgent, sseToText, toJuneError, useDocumentOptions, useJuneRuntime, useJuneStream, useJuneTheme, useResolvedTheme, withDocumentEditor };