@arbidocs/blocks 0.4.70 → 0.4.71

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 (104) hide show
  1. package/README.md +90 -14
  2. package/bin/arbidocs-copy-pdf-assets.mjs +112 -0
  3. package/dist/{StreamedArtifactEditor-OPL4KXOT.js → StreamedArtifactEditor-HTNPG4NB.js} +3 -2
  4. package/dist/StreamedArtifactEditor-HTNPG4NB.js.map +1 -0
  5. package/dist/{StreamedArtifactEditor-RIKG6CJQ.cjs → StreamedArtifactEditor-IZWYNFMM.cjs} +3 -2
  6. package/dist/StreamedArtifactEditor-IZWYNFMM.cjs.map +1 -0
  7. package/dist/agents/index.cjs +1 -0
  8. package/dist/agents/index.js +1 -0
  9. package/dist/artifacts/editor/index.cjs +1 -0
  10. package/dist/artifacts/editor/index.js +1 -0
  11. package/dist/artifacts/index.cjs +1 -0
  12. package/dist/artifacts/index.js +1 -0
  13. package/dist/auth/index.cjs +1 -0
  14. package/dist/auth/index.js +1 -0
  15. package/dist/chat/index.cjs +1 -0
  16. package/dist/chat/index.js +1 -0
  17. package/dist/{chunk-CW4WXGEN.js → chunk-3TVTG7FK.js} +3 -3
  18. package/dist/{chunk-CW4WXGEN.js.map → chunk-3TVTG7FK.js.map} +1 -1
  19. package/dist/{chunk-EHXSBH6U.js → chunk-5HOAOKZL.js} +4 -2
  20. package/dist/chunk-5HOAOKZL.js.map +1 -0
  21. package/dist/chunk-DES3K4SD.cjs +18 -0
  22. package/dist/chunk-DES3K4SD.cjs.map +1 -0
  23. package/dist/{chunk-BR2CPKFU.cjs → chunk-LTA2IAQB.cjs} +6 -6
  24. package/dist/{chunk-BR2CPKFU.cjs.map → chunk-LTA2IAQB.cjs.map} +1 -1
  25. package/dist/{chunk-TLQQV7WW.cjs → chunk-THO7DZNN.cjs} +4 -2
  26. package/dist/chunk-THO7DZNN.cjs.map +1 -0
  27. package/dist/chunk-VUNV25KB.js +15 -0
  28. package/dist/chunk-VUNV25KB.js.map +1 -0
  29. package/dist/citations/index.cjs +1 -0
  30. package/dist/citations/index.js +1 -0
  31. package/dist/collaboration/index.cjs +1 -0
  32. package/dist/collaboration/index.js +1 -0
  33. package/dist/connect/docx.cjs +3 -2
  34. package/dist/connect/docx.cjs.map +1 -1
  35. package/dist/connect/docx.js +2 -1
  36. package/dist/connect/docx.js.map +1 -1
  37. package/dist/connect/index.cjs +25 -24
  38. package/dist/connect/index.cjs.map +1 -1
  39. package/dist/connect/index.js +6 -5
  40. package/dist/connect/index.js.map +1 -1
  41. package/dist/connection/ConnectionProvider.d.ts +5 -0
  42. package/dist/connection/types.d.ts +6 -0
  43. package/dist/document-tools/SignatureStatus.d.ts +4 -2
  44. package/dist/document-tools/index.cjs +10 -6
  45. package/dist/document-tools/index.cjs.map +1 -1
  46. package/dist/document-tools/index.js +11 -7
  47. package/dist/document-tools/index.js.map +1 -1
  48. package/dist/document-tools/production/ProductionSetDialog.d.ts +23 -0
  49. package/dist/document-tools/production/index.cjs +102 -0
  50. package/dist/document-tools/production/index.cjs.map +1 -0
  51. package/dist/document-tools/production/index.d.ts +1 -0
  52. package/dist/document-tools/production/index.js +100 -0
  53. package/dist/document-tools/production/index.js.map +1 -0
  54. package/dist/document-tools/viewer/index.cjs +1 -1
  55. package/dist/document-tools/viewer/index.js +1 -1
  56. package/dist/docx/index.cjs +1 -0
  57. package/dist/docx/index.cjs.map +1 -1
  58. package/dist/docx/index.js +1 -0
  59. package/dist/docx/index.js.map +1 -1
  60. package/dist/facts/index.cjs +1 -0
  61. package/dist/facts/index.cjs.map +1 -1
  62. package/dist/facts/index.js +1 -0
  63. package/dist/facts/index.js.map +1 -1
  64. package/dist/files/index.cjs +1 -0
  65. package/dist/files/index.cjs.map +1 -1
  66. package/dist/files/index.js +1 -0
  67. package/dist/files/index.js.map +1 -1
  68. package/dist/home/index.cjs +1 -0
  69. package/dist/home/index.cjs.map +1 -1
  70. package/dist/home/index.js +1 -0
  71. package/dist/home/index.js.map +1 -1
  72. package/dist/index.cjs +1 -0
  73. package/dist/index.cjs.map +1 -1
  74. package/dist/index.js +1 -0
  75. package/dist/index.js.map +1 -1
  76. package/dist/lib-6QPUXAQS.cjs +9674 -0
  77. package/dist/lib-6QPUXAQS.cjs.map +1 -0
  78. package/dist/lib-NRGL2JGF.js +9672 -0
  79. package/dist/lib-NRGL2JGF.js.map +1 -0
  80. package/dist/retrieval/index.cjs +1 -0
  81. package/dist/retrieval/index.js +1 -0
  82. package/dist/settings/index.cjs +1 -0
  83. package/dist/settings/index.cjs.map +1 -1
  84. package/dist/settings/index.js +1 -0
  85. package/dist/settings/index.js.map +1 -1
  86. package/dist/shell/index.cjs +1 -0
  87. package/dist/shell/index.js +1 -0
  88. package/dist/site/index.cjs +1 -0
  89. package/dist/site/index.js +1 -0
  90. package/dist/studio/index.cjs +5 -4
  91. package/dist/studio/index.cjs.map +1 -1
  92. package/dist/studio/index.js +3 -2
  93. package/dist/studio/index.js.map +1 -1
  94. package/dist/timeline/index.cjs +1 -0
  95. package/dist/timeline/index.js +1 -0
  96. package/dist/workspaces/index.cjs +1 -0
  97. package/dist/workspaces/index.cjs.map +1 -1
  98. package/dist/workspaces/index.js +1 -0
  99. package/dist/workspaces/index.js.map +1 -1
  100. package/package.json +16 -4
  101. package/dist/StreamedArtifactEditor-OPL4KXOT.js.map +0 -1
  102. package/dist/StreamedArtifactEditor-RIKG6CJQ.cjs.map +0 -1
  103. package/dist/chunk-EHXSBH6U.js.map +0 -1
  104. package/dist/chunk-TLQQV7WW.cjs.map +0 -1
package/README.md CHANGED
@@ -167,28 +167,49 @@ merged in), "Show original", "Download with markup", the notes about markup on a
167
167
  ("Copy open comments here") and about marks left in this browser, Freeze (a separate annotated or
168
168
  redacted copy, with a redaction log), e-signing (choose where the signature goes, sign with the
169
169
  password; only the signature and optionally the date are drawn), the signature details with "View
170
- certificate", the public certificate page, and the read-only version bar.
170
+ certificate", the public certificate page, the read-only version bar and production sets (Bates
171
+ numbering).
171
172
 
172
173
  | Import | What |
173
174
  | --- | --- |
174
- | `@arbidocs/react/document-tools` | `DocumentToolsProvider`, `useDocumentMarkup`, `createMarkupStore`, `fetchMarkupPdf`, `canAnnotate`, `useDocumentSignatures`, `useSignDocument`, `useSignatureVerification` |
175
+ | `@arbidocs/react/document-tools` | `DocumentToolsProvider`, `fetchDocumentPdf`, `fetchDocumentFile`, `useDocumentMarkup`, `createMarkupStore`, `fetchMarkupPdf`, `canAnnotate`, `useDocumentSignatures`, `useSignDocument`, `useSignatureVerification`, `buildProduction`, `saveProductionFiles` |
175
176
  | `@arbidocs/blocks/document-tools` | `AnnotateButton`, `ShowOriginalButton`, `DownloadMarkupButton`, `SignButton`, `MarkupNotices`, `MarkupViewNote`, `SignDocumentDialog`, `SignatureStatus`, `SignatureCertificate`, `VersionSnapshotBar` |
176
177
  | `@arbidocs/blocks/document-tools/viewer` | `AnnotatedPdfViewer`, `SignaturePlacementViewer` (load lazily: pdf-lib) |
178
+ | `@arbidocs/blocks/document-tools/production` | `ProductionSetDialog` (load lazily; pdf-lib and JSZip load on confirm) |
177
179
 
178
180
  What the host provides, once, around the viewer (the tools import no store, router or toast
179
181
  library of their own):
180
182
 
181
183
  - an ARBI API client signed in as the user: `arbi.getClient().fetch` from an `@arbidocs/sdk`
182
184
  `Arbi`, or `createArbiClient(...).fetch` from `@arbidocs/client`;
183
- - `deploymentDomain` (the one the user's keys are derived for) and `user: { name, email }`, for
184
- signing; without a user marks are authored as "You";
185
+ - `user: { name, email }` for signing (without a user marks are authored as "You") and the
186
+ `deploymentDomain` the user's keys are derived for. Inside an `ArbiProvider` (or
187
+ `ArbiAppProvider`, which mounts one) `deploymentDomain` defaults to the SDK's own,
188
+ `arbi.getDeploymentDomain()` (the `deploymentDomain` option, else the API URL's hostname), which
189
+ is also `useDeploymentDomain()` from `@arbidocs/react` and `deploymentDomain` on
190
+ `useConnection()`. Pass it only when the API is served from another host than the one users
191
+ registered on (`ArbiConnectionConfig.deploymentDomain` sets it for the whole app);
185
192
  - callbacks, all optional: `notify(message, kind, { description, action })`, `openDocument(ref)`
186
- (the copy just frozen, the signed copy), `onDocumentsChanged(ids, 'markup' | 'copy' | 'signed')`
187
- to refresh your lists, `emailDocument(ref)` (adds "Email it" after signing), `uploadDocument`,
188
- `saveFile` and `certificateUrl` (defaults: the API client, a download link, `/verify/{ref}`);
189
- - a React Query `QueryClientProvider`, the blocks styles (see Styles), and the pdf.js assets the
190
- kit `PdfViewer` loads (`/pdf.worker.min.mjs`, `/cmaps/`, `/standard_fonts/` by default) plus the
191
- optional peers `react-pdf`, `pdfjs-dist` and `pdf-lib`.
193
+ (the copy just frozen, the signed copy, a saved production), `onDocumentsChanged(ids, 'markup' |
194
+ 'copy' | 'signed')` to refresh your lists, `emailDocument(ref)` (adds "Email it" after signing),
195
+ `uploadDocument`, `saveFile` and `certificateUrl` (defaults: the API client, a download link, the
196
+ backend's certificate link; see Signature certificates);
197
+ - a React Query `QueryClientProvider`, the blocks styles (see Styles), the optional peers
198
+ `react-pdf`, `pdfjs-dist` and `pdf-lib`, and the pdf.js runtime (see below).
199
+
200
+ The PDF the tools draw on is the document's `/view` rendering (the file itself for a PDF, its PDF
201
+ rendering for a Word or text file). Fetch it with the function the tools use:
202
+
203
+ ```ts
204
+ import { fetchDocumentPdf } from '@arbidocs/react/document-tools'
205
+
206
+ // GET /v1/document/{id}/view?version= with Accept: application/pdf; a `doc-…@v2` reference
207
+ // names a version too. Throws a DocumentFetchError (with `status`) when there is no PDF yet.
208
+ const pdf = await fetchDocumentPdf(arbi.getClient().fetch, doc.external_id, { version: 2 })
209
+ ```
210
+
211
+ Put the version in your cache key: a document keeps its id across versions (a signed copy is the
212
+ next version), so a new version must never show the previous one's file.
192
213
 
193
214
  ```tsx
194
215
  import { lazy, Suspense, useState } from 'react'
@@ -199,11 +220,11 @@ const AnnotatedPdfViewer = lazy(() =>
199
220
 
200
221
  <DocumentToolsProvider
201
222
  client={arbi.getClient().fetch}
202
- deploymentDomain={deploymentDomain}
203
223
  user={{ name: 'Ana Lopez', email: 'ana@firm.example' }}
204
224
  notify={(message, kind) => toast[kind](message)}
205
225
  openDocument={(ref) => navigate(`/documents/${ref}`)}
206
226
  onDocumentsChanged={() => queryClient.invalidateQueries({ queryKey: ['documents'] })}
227
+ certificateUrl={(ref) => `${location.origin}/verify/${ref}`}
207
228
  >
208
229
  <DocumentPage doc={doc} pdf={pdfBlob} />
209
230
  </DocumentToolsProvider>
@@ -237,9 +258,64 @@ editor of a signed version ("Editing creates a new unsigned version").
237
258
 
238
259
  `AnnotatedPdfViewer` and `SignaturePlacementViewer` take your own binding of the kit viewer as
239
260
  `viewer` (for example one that reports the visible page); `SignaturePlacementViewer`'s
240
- `onContinue(appearance)` hands the box to `SignDocumentDialog`. Serve `SignatureCertificate` on a
241
- route that needs no sign-in (ARBI uses `/verify/:reference`), inside a `DocumentToolsProvider` with
242
- an unauthenticated client: it is the page the signature on a signed PDF links to.
261
+ `onContinue(appearance)` hands the box to `SignDocumentDialog`.
262
+
263
+ ### Signature certificates
264
+
265
+ Serve `SignatureCertificate` on a route that needs no sign-in (ARBI uses `/verify/:reference`),
266
+ inside a `DocumentToolsProvider` with an unauthenticated client. "View certificate" (in
267
+ `SignatureStatus`, and after signing) opens the provider's `certificateUrl(reference)` when you
268
+ give one, so it lands on your own page; without it, the `certificate_url` the backend returned,
269
+ else `/verify/{reference}` on this origin. The link drawn into the signed PDF itself is set by the
270
+ backend and always points at the deployment domain (`https://{DEPLOYMENT_DOMAIN}/verify/{ref}`):
271
+ serve the certificate page there too, or redirect that path to yours.
272
+
273
+ ### Production sets
274
+
275
+ `ProductionSetDialog` numbers the selected documents with Bates labels (optionally a QR code back
276
+ to each document and an index page), downloads the result (one PDF, or a ZIP with each file and an
277
+ `index.csv`) and saves it to the workspace as new documents derived from all their sources
278
+ (`derived_from` repeated, role `production`) in a Productions folder, shared only if every source
279
+ is. A PDF is numbered as stored, anything else through its `/view` PDF; media are left out. It uses
280
+ the provider's client, `uploadDocument`, `saveFile`, `notify`, `onDocumentsChanged(ids, 'copy')`
281
+ and `openDocument` (its "Open" action); you give it the selection and your deep link:
282
+
283
+ ```tsx
284
+ const ProductionSetDialog = lazy(() =>
285
+ import('@arbidocs/blocks/document-tools/production').then((m) => ({ default: m.ProductionSetDialog })))
286
+
287
+ <ProductionSetDialog open={open} onOpenChange={setOpen} documents={selectedDocs}
288
+ documentUrl={(id) => `${location.origin}/documents/${id}`} />
289
+ ```
290
+
291
+ A custom `uploadDocument` receives the upload query typed from the API schema
292
+ (`DocumentUploadQuery`: `derived_from` is a list, `shared` a boolean). If you post the upload
293
+ yourself (an XHR with progress), build the query string with `uploadQueryString(query)`, which
294
+ repeats `derived_from` for each source; the default, `clientUpload(client)`, does this already.
295
+
296
+ ### The pdf.js runtime
297
+
298
+ The kit `PdfViewer` loads the pdf.js worker and its data from your site: `/pdf.worker.min.mjs`,
299
+ `/cmaps/`, `/standard_fonts/` and `/wasm/` (the JPEG 2000 and JBIG2 decoders: without them
300
+ scanned PDFs render blank). `@arbidocs/blocks` ships a command that copies them from your installed
301
+ `pdfjs-dist` into your public directory, with shims for the newer built-ins pdf.js needs in older
302
+ browsers. It fails if your `pdfjs-dist` differs from the one `react-pdf` runs, which would break
303
+ every PDF with "API version does not match Worker version":
304
+
305
+ ```json
306
+ {
307
+ "scripts": {
308
+ "pdf-assets": "arbidocs-copy-pdf-assets public",
309
+ "predev": "npm run pdf-assets",
310
+ "prebuild": "npm run pdf-assets"
311
+ }
312
+ }
313
+ ```
314
+
315
+ Pin `pdfjs-dist` to the exact version `react-pdf` depends on, and keep the copied files out of
316
+ version control (`public/pdf.worker*.mjs`, `public/cmaps/`, `public/standard_fonts/`,
317
+ `public/wasm/`). `--images` also copies the pdf.js annotation icons to `/images/`. To serve them
318
+ elsewhere, pass `assets` (`workerSrc`, `cMapUrl`, `standardFontDataUrl`, `wasmUrl`) to the viewer.
243
319
 
244
320
  ## Editorial site parts
245
321
 
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * arbidocs-copy-pdf-assets <publicDir> [--images]
4
+ *
5
+ * Serve the pdf.js runtime the document tools' PDF viewer loads (the kit `PdfViewer` of
6
+ * @arbidocs/react/viewers, whose default asset paths these are):
7
+ *
8
+ * /pdf.worker.min.mjs, /pdf.worker.mjs the worker, with shims for newer built-ins
9
+ * /cmaps/ character maps (CJK and other non-embedded encodings)
10
+ * /standard_fonts/ the standard 14 fonts
11
+ * /wasm/ JPEG 2000 / JBIG2 / colour decoders: without them a
12
+ * scanned PDF renders blank white pages
13
+ * /images/ (with --images) pdf.js annotation icons
14
+ *
15
+ * Copied from the pdfjs-dist installed for the app (resolved from the current directory), so the
16
+ * worker always matches the library react-pdf runs: a mismatch fails every PDF with "API version
17
+ * does not match Worker version". Run it before dev and build, e.g. in `predev` / `prebuild`.
18
+ *
19
+ * The worker gets small shims for the newer built-ins pdf.js 5+ relies on (Uint8Array hex,
20
+ * Map.prototype.getOrInsertComputed, Math.sumPrecise); each steps aside where the browser has the
21
+ * real one. Without them older browsers fail to parse ("x.toHex is not a function") or draw no
22
+ * pages at all.
23
+ */
24
+
25
+ import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
26
+ import { createRequire } from 'node:module'
27
+ import { dirname, join, resolve } from 'node:path'
28
+
29
+ const args = process.argv.slice(2)
30
+ const withImages = args.includes('--images')
31
+ const target = args.find((arg) => !arg.startsWith('--'))
32
+ if (!target || args.includes('--help')) {
33
+ console.error('Usage: arbidocs-copy-pdf-assets <publicDir> [--images]')
34
+ process.exit(target ? 0 : 1)
35
+ }
36
+
37
+ // Resolve from the app (the current directory), not from this package: the app's pdfjs-dist is
38
+ // the one its bundle runs.
39
+ const appRequire = createRequire(join(process.cwd(), 'package.json'))
40
+ let pdfjsRoot
41
+ try {
42
+ pdfjsRoot = dirname(appRequire.resolve('pdfjs-dist/package.json'))
43
+ } catch {
44
+ console.error('arbidocs-copy-pdf-assets: pdfjs-dist is not installed (npm install pdfjs-dist)')
45
+ process.exit(1)
46
+ }
47
+ const versionOf = (dir) => JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')).version
48
+
49
+ // react-pdf may use a nested copy of pdfjs-dist; the worker must match that one.
50
+ try {
51
+ const reactPdfRequire = createRequire(appRequire.resolve('react-pdf'))
52
+ const reactPdfPdfjs = dirname(reactPdfRequire.resolve('pdfjs-dist/package.json'))
53
+ if (versionOf(reactPdfPdfjs) !== versionOf(pdfjsRoot)) {
54
+ console.error(
55
+ `arbidocs-copy-pdf-assets: pdfjs-dist ${versionOf(pdfjsRoot)} differs from the ` +
56
+ `${versionOf(reactPdfPdfjs)} react-pdf uses. Pin "pdfjs-dist" to ` +
57
+ `"${versionOf(reactPdfPdfjs)}" (no ^) in package.json and reinstall.`
58
+ )
59
+ process.exit(1)
60
+ }
61
+ } catch {
62
+ // No react-pdf installed: nothing to match.
63
+ }
64
+
65
+ const SHIMS = `
66
+ if (typeof Uint8Array.prototype.toHex !== 'function') {
67
+ Object.defineProperty(Uint8Array.prototype, 'toHex', { configurable: true, writable: true,
68
+ value() { let s = ''; for (let i = 0; i < this.length; i++) s += this[i].toString(16).padStart(2, '0'); return s; } });
69
+ }
70
+ if (typeof Uint8Array.fromHex !== 'function') {
71
+ Object.defineProperty(Uint8Array, 'fromHex', { configurable: true, writable: true,
72
+ value(hex) { const h = hex.replace(/\\s+/g, ''); if (h.length % 2) throw new SyntaxError('Uint8Array.fromHex: odd length');
73
+ const out = new Uint8Array(h.length / 2);
74
+ for (let i = 0; i < out.length; i++) { const b = parseInt(h.slice(i * 2, i * 2 + 2), 16);
75
+ if (Number.isNaN(b)) throw new SyntaxError('Uint8Array.fromHex: non-hex digit'); out[i] = b; }
76
+ return out; } });
77
+ }
78
+ if (typeof Map.prototype.getOrInsertComputed !== 'function') {
79
+ Object.defineProperty(Map.prototype, 'getOrInsertComputed', { configurable: true, writable: true,
80
+ value(key, make) { if (this.has(key)) return this.get(key); const v = make(key); this.set(key, v); return v; } });
81
+ }
82
+ if (typeof Math.sumPrecise !== 'function') {
83
+ Object.defineProperty(Math, 'sumPrecise', { configurable: true, writable: true,
84
+ value(values) { let sum = 0, c = 0; for (const v of values) { const t = sum + v;
85
+ c += Math.abs(sum) >= Math.abs(v) ? sum - t + v : v - t + sum; sum = t; } return sum + c; } });
86
+ }
87
+ `
88
+
89
+ const publicDir = resolve(target)
90
+ mkdirSync(publicDir, { recursive: true })
91
+ for (const name of ['pdf.worker.min.mjs', 'pdf.worker.mjs']) {
92
+ const source = readFileSync(join(pdfjsRoot, 'build', name), 'utf8')
93
+ writeFileSync(join(publicDir, name), SHIMS + source)
94
+ }
95
+ const dirs = [
96
+ ['cmaps', 'cmaps'],
97
+ ['standard_fonts', 'standard_fonts'],
98
+ ['wasm', 'wasm'],
99
+ ...(withImages ? [['web/images', 'images']] : []),
100
+ ]
101
+ for (const [from, to] of dirs) {
102
+ const source = join(pdfjsRoot, from)
103
+ if (!existsSync(source)) {
104
+ console.error(`arbidocs-copy-pdf-assets: pdfjs-dist ${versionOf(pdfjsRoot)} has no ${from}/`)
105
+ process.exit(1)
106
+ }
107
+ cpSync(source, join(publicDir, to), { recursive: true })
108
+ }
109
+ console.log(
110
+ `pdf.js ${versionOf(pdfjsRoot)} worker, ${dirs.map(([, to]) => `${to}/`).join(', ')} ` +
111
+ `copied to ${publicDir}`
112
+ )
@@ -3,6 +3,7 @@ import { ArtifactMarkdownEditor } from './chunk-NEFHQHQV.js';
3
3
  import { ArtifactEditor, ArtifactRedlineView } from './chunk-65HZ36MY.js';
4
4
  import './chunk-LOJVUGBJ.js';
5
5
  import './chunk-7F6CBP3Z.js';
6
+ import './chunk-VUNV25KB.js';
6
7
  import { useState } from 'react';
7
8
  import { Copy, Download } from 'lucide-react';
8
9
  import { Button, cn } from '@arbidocs/react/ui';
@@ -100,5 +101,5 @@ function StreamedArtifactEditor({
100
101
  }
101
102
 
102
103
  export { StreamedArtifactEditor as default };
103
- //# sourceMappingURL=StreamedArtifactEditor-OPL4KXOT.js.map
104
- //# sourceMappingURL=StreamedArtifactEditor-OPL4KXOT.js.map
104
+ //# sourceMappingURL=StreamedArtifactEditor-HTNPG4NB.js.map
105
+ //# sourceMappingURL=StreamedArtifactEditor-HTNPG4NB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connection/StreamedArtifactEditor.tsx"],"names":[],"mappings":"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","file":"StreamedArtifactEditor-HTNPG4NB.js","sourcesContent":["import { useState, type ReactNode } from 'react'\nimport { Copy, Download } from 'lucide-react'\nimport { Button, cn } from '@arbidocs/react/ui'\nimport { renderArtifactMarkdown, useArtifactSession } from '@arbidocs/react/artifacts'\nimport { ArtifactEditor, ArtifactRedlineView, type ArtifactEditorLabels } from '../artifacts'\nimport {\n ArtifactMarkdownEditor,\n type ArtifactMarkdownEditorProps,\n} from '../artifacts/editor/ArtifactMarkdownEditor'\n\nexport interface StreamedArtifactEditorProps {\n workspaceId: string | undefined\n /** The stored first version (the lineage's root as far as this panel goes). */\n docId: string\n /** File name for the versions saved from here. */\n title: string\n testId: string\n className?: string\n /** Extra props of the rich-text editor (`dictation`, labels). */\n editorProps?: Partial<Omit<ArtifactMarkdownEditorProps, 'markdown' | 'onChange' | 'onNormalized'>>\n /** Called after a version is saved. */\n onSaved?: (docId: string | undefined) => void\n onSaveError?: (error: unknown) => void\n /** Extra header actions next to the toolbar. */\n actions?: (ctx: { content: string; title: string }) => ReactNode\n /** Hide the default Copy and Download buttons. */\n hideDefaultActions?: boolean\n labels?: Partial<ArtifactEditorLabels>\n}\n\n/**\n * The editing stage of `StreamedArtifact`: `ArtifactEditor` bound to `useArtifactSession`. It is\n * a separate module because it pulls the rich-text editor (Lexical), which must stay behind a\n * `lazy()` boundary.\n */\nexport default function StreamedArtifactEditor({\n workspaceId,\n docId,\n title,\n testId,\n className,\n editorProps,\n onSaved,\n onSaveError,\n actions,\n hideDefaultActions,\n labels,\n}: StreamedArtifactEditorProps) {\n const [openId, setOpenId] = useState(docId)\n const s = useArtifactSession({\n workspaceId,\n docId: openId,\n title,\n onSaved: ({ docId: next }) => {\n if (next) setOpenId(next)\n onSaved?.(next)\n },\n onSaveError,\n })\n\n const copy = () => void navigator.clipboard.writeText(s.content)\n const download = () => {\n const url = URL.createObjectURL(new Blob([s.content], { type: 'text/markdown' }))\n const a = document.createElement('a')\n a.href = url\n a.download = `${title.replace(/\\.md$/i, '')}.md`\n a.click()\n URL.revokeObjectURL(url)\n }\n\n return (\n <div\n className={cn(\n 'flex min-h-[560px] flex-col rounded-xl border border-border bg-card',\n className\n )}\n data-testid={testId}\n >\n <ArtifactEditor\n {...s.view}\n className=\"min-h-[560px] flex-1\"\n labels={labels}\n onOpenVersion={setOpenId}\n renderMarkdown={renderArtifactMarkdown}\n editor={<ArtifactMarkdownEditor {...editorProps} {...s.editorProps} />}\n redline={\n <ArtifactRedlineView {...s.redlineProps} renderMarkdown={renderArtifactMarkdown} />\n }\n actions={\n <>\n {!hideDefaultActions && (\n <>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={copy}\n data-testid={`${testId}-copy`}\n className=\"pointer-coarse:min-h-11\"\n >\n <Copy className=\"size-4\" aria-hidden /> Copy\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={download}\n data-testid={`${testId}-download`}\n className=\"pointer-coarse:min-h-11\"\n >\n <Download className=\"size-4\" aria-hidden /> Download\n </Button>\n </>\n )}\n {actions?.({ content: s.content, title })}\n </>\n }\n />\n </div>\n )\n}\n"]}
@@ -5,6 +5,7 @@ var chunkQS4RV3MA_cjs = require('./chunk-QS4RV3MA.cjs');
5
5
  var chunkSVJQWLOF_cjs = require('./chunk-SVJQWLOF.cjs');
6
6
  require('./chunk-QVBZESYQ.cjs');
7
7
  require('./chunk-MHVNT4J3.cjs');
8
+ require('./chunk-DES3K4SD.cjs');
8
9
  var react = require('react');
9
10
  var lucideReact = require('lucide-react');
10
11
  var ui = require('@arbidocs/react/ui');
@@ -102,5 +103,5 @@ function StreamedArtifactEditor({
102
103
  }
103
104
 
104
105
  module.exports = StreamedArtifactEditor;
105
- //# sourceMappingURL=StreamedArtifactEditor-RIKG6CJQ.cjs.map
106
- //# sourceMappingURL=StreamedArtifactEditor-RIKG6CJQ.cjs.map
106
+ //# sourceMappingURL=StreamedArtifactEditor-IZWYNFMM.cjs.map
107
+ //# sourceMappingURL=StreamedArtifactEditor-IZWYNFMM.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connection/StreamedArtifactEditor.tsx"],"names":["useState","useArtifactSession","jsx","cn","ArtifactEditor","renderArtifactMarkdown","ArtifactMarkdownEditor","ArtifactRedlineView","jsxs","Fragment","Button","Copy","Download"],"mappings":"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","file":"StreamedArtifactEditor-IZWYNFMM.cjs","sourcesContent":["import { useState, type ReactNode } from 'react'\nimport { Copy, Download } from 'lucide-react'\nimport { Button, cn } from '@arbidocs/react/ui'\nimport { renderArtifactMarkdown, useArtifactSession } from '@arbidocs/react/artifacts'\nimport { ArtifactEditor, ArtifactRedlineView, type ArtifactEditorLabels } from '../artifacts'\nimport {\n ArtifactMarkdownEditor,\n type ArtifactMarkdownEditorProps,\n} from '../artifacts/editor/ArtifactMarkdownEditor'\n\nexport interface StreamedArtifactEditorProps {\n workspaceId: string | undefined\n /** The stored first version (the lineage's root as far as this panel goes). */\n docId: string\n /** File name for the versions saved from here. */\n title: string\n testId: string\n className?: string\n /** Extra props of the rich-text editor (`dictation`, labels). */\n editorProps?: Partial<Omit<ArtifactMarkdownEditorProps, 'markdown' | 'onChange' | 'onNormalized'>>\n /** Called after a version is saved. */\n onSaved?: (docId: string | undefined) => void\n onSaveError?: (error: unknown) => void\n /** Extra header actions next to the toolbar. */\n actions?: (ctx: { content: string; title: string }) => ReactNode\n /** Hide the default Copy and Download buttons. */\n hideDefaultActions?: boolean\n labels?: Partial<ArtifactEditorLabels>\n}\n\n/**\n * The editing stage of `StreamedArtifact`: `ArtifactEditor` bound to `useArtifactSession`. It is\n * a separate module because it pulls the rich-text editor (Lexical), which must stay behind a\n * `lazy()` boundary.\n */\nexport default function StreamedArtifactEditor({\n workspaceId,\n docId,\n title,\n testId,\n className,\n editorProps,\n onSaved,\n onSaveError,\n actions,\n hideDefaultActions,\n labels,\n}: StreamedArtifactEditorProps) {\n const [openId, setOpenId] = useState(docId)\n const s = useArtifactSession({\n workspaceId,\n docId: openId,\n title,\n onSaved: ({ docId: next }) => {\n if (next) setOpenId(next)\n onSaved?.(next)\n },\n onSaveError,\n })\n\n const copy = () => void navigator.clipboard.writeText(s.content)\n const download = () => {\n const url = URL.createObjectURL(new Blob([s.content], { type: 'text/markdown' }))\n const a = document.createElement('a')\n a.href = url\n a.download = `${title.replace(/\\.md$/i, '')}.md`\n a.click()\n URL.revokeObjectURL(url)\n }\n\n return (\n <div\n className={cn(\n 'flex min-h-[560px] flex-col rounded-xl border border-border bg-card',\n className\n )}\n data-testid={testId}\n >\n <ArtifactEditor\n {...s.view}\n className=\"min-h-[560px] flex-1\"\n labels={labels}\n onOpenVersion={setOpenId}\n renderMarkdown={renderArtifactMarkdown}\n editor={<ArtifactMarkdownEditor {...editorProps} {...s.editorProps} />}\n redline={\n <ArtifactRedlineView {...s.redlineProps} renderMarkdown={renderArtifactMarkdown} />\n }\n actions={\n <>\n {!hideDefaultActions && (\n <>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={copy}\n data-testid={`${testId}-copy`}\n className=\"pointer-coarse:min-h-11\"\n >\n <Copy className=\"size-4\" aria-hidden /> Copy\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={download}\n data-testid={`${testId}-download`}\n className=\"pointer-coarse:min-h-11\"\n >\n <Download className=\"size-4\" aria-hidden /> Download\n </Button>\n </>\n )}\n {actions?.({ content: s.content, title })}\n </>\n }\n />\n </div>\n )\n}\n"]}
@@ -20,6 +20,7 @@ require('../chunk-2ZTONLT5.cjs');
20
20
  require('../chunk-DCDVWPMB.cjs');
21
21
  require('../chunk-7UTB4PHM.cjs');
22
22
  require('../chunk-MHVNT4J3.cjs');
23
+ require('../chunk-DES3K4SD.cjs');
23
24
 
24
25
 
25
26
 
@@ -18,5 +18,6 @@ import '../chunk-CPMNAJLF.js';
18
18
  import '../chunk-TJMKFY5P.js';
19
19
  import '../chunk-AA3PT6KR.js';
20
20
  import '../chunk-7F6CBP3Z.js';
21
+ import '../chunk-VUNV25KB.js';
21
22
  //# sourceMappingURL=index.js.map
22
23
  //# sourceMappingURL=index.js.map
@@ -3,6 +3,7 @@
3
3
 
4
4
  var chunkQS4RV3MA_cjs = require('../../chunk-QS4RV3MA.cjs');
5
5
  require('../../chunk-MHVNT4J3.cjs');
6
+ require('../../chunk-DES3K4SD.cjs');
6
7
 
7
8
 
8
9
 
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  export { ArtifactMarkdownEditor, DEFAULT_ARTIFACT_MARKDOWN_EDITOR_LABELS } from '../../chunk-NEFHQHQV.js';
3
3
  import '../../chunk-7F6CBP3Z.js';
4
+ import '../../chunk-VUNV25KB.js';
4
5
  //# sourceMappingURL=index.js.map
5
6
  //# sourceMappingURL=index.js.map
@@ -4,6 +4,7 @@
4
4
  var chunkSVJQWLOF_cjs = require('../chunk-SVJQWLOF.cjs');
5
5
  var chunkQVBZESYQ_cjs = require('../chunk-QVBZESYQ.cjs');
6
6
  require('../chunk-MHVNT4J3.cjs');
7
+ require('../chunk-DES3K4SD.cjs');
7
8
 
8
9
 
9
10
 
@@ -2,5 +2,6 @@
2
2
  export { ArtifactCompareBar, ArtifactEditor, ArtifactEditorBody, ArtifactRedlineView, ArtifactToolbar, ArtifactVersionBar, DEFAULT_ARTIFACT_COMPARE_BAR_LABELS, DEFAULT_ARTIFACT_EDITOR_STATUS_LABELS, DEFAULT_ARTIFACT_TOOLBAR_LABELS, DEFAULT_ARTIFACT_VERSION_BAR_LABELS, DEFAULT_REDLINE_LABELS, DEFAULT_VERSION_TIMELINE_LABELS, RedlineComputing, RedlineDocument, RedlineFrame, RedlineHeader, RedlineMark, RedlineRevertGutter, RedlineStatus, VersionTimeline } from '../chunk-65HZ36MY.js';
3
3
  export { DEFAULT_STREAMED_ARTIFACT_FRAME_LABELS, StreamedArtifactFrame } from '../chunk-LOJVUGBJ.js';
4
4
  import '../chunk-7F6CBP3Z.js';
5
+ import '../chunk-VUNV25KB.js';
5
6
  //# sourceMappingURL=index.js.map
6
7
  //# sourceMappingURL=index.js.map
@@ -4,6 +4,7 @@
4
4
  var chunkWQFGG2BV_cjs = require('../chunk-WQFGG2BV.cjs');
5
5
  var chunkADOKTJHV_cjs = require('../chunk-ADOKTJHV.cjs');
6
6
  require('../chunk-MHVNT4J3.cjs');
7
+ require('../chunk-DES3K4SD.cjs');
7
8
 
8
9
 
9
10
 
@@ -2,5 +2,6 @@
2
2
  export { AccountRecoveryDialog, AuthAlert, AuthConsent, AuthDivider, AuthField, AuthFieldBadge, AuthFooterLinks, AuthHeading, AuthHero, AuthInput, AuthLayout, AuthLink, AuthNote, AuthOfflineBadge, AuthSubmitButton, AuthTabs, DEFAULT_ACCOUNT_RECOVERY_DIALOG_LABELS, DEFAULT_AUTH_CONSENT_LABELS, DEFAULT_AUTH_FOOTER_LINKS_LABELS, DEFAULT_AUTH_OFFLINE_BADGE_LABELS, DEFAULT_RECOVERY_KEY_DIALOG_LABELS, DEFAULT_REVEALABLE_PASSWORD_INPUT_LABELS, DEFAULT_SSO_LOGIN_BUTTON_LABELS, RecoveryKeyDialog, RevealablePasswordInput, SsoLoginButton } from '../chunk-SFXVNFES.js';
3
3
  export { DEFAULT_PASSWORD_STRENGTH_INPUT_LABELS, PasswordStrengthInput } from '../chunk-VILAPTCB.js';
4
4
  import '../chunk-7F6CBP3Z.js';
5
+ import '../chunk-VUNV25KB.js';
5
6
  //# sourceMappingURL=index.js.map
6
7
  //# sourceMappingURL=index.js.map
@@ -11,6 +11,7 @@ require('../chunk-PPCATBOY.cjs');
11
11
  require('../chunk-KDG6FER6.cjs');
12
12
  var chunk7UTB4PHM_cjs = require('../chunk-7UTB4PHM.cjs');
13
13
  require('../chunk-MHVNT4J3.cjs');
14
+ require('../chunk-DES3K4SD.cjs');
14
15
 
15
16
 
16
17
 
@@ -9,5 +9,6 @@ import '../chunk-NPLYHR2E.js';
9
9
  import '../chunk-OXF2IFXG.js';
10
10
  export { DEFAULT_MENTION_LABELS, MENTION_HREF_PREFIX, MentionChip, MentionMenu, extractMentions, filterMentionCandidates, findMentionQuery, insertMention, linkMentions, mentionFromHref, toMessageMentions, useListKeyNav } from '../chunk-AA3PT6KR.js';
11
11
  import '../chunk-7F6CBP3Z.js';
12
+ import '../chunk-VUNV25KB.js';
12
13
  //# sourceMappingURL=index.js.map
13
14
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { AssistantDock } from './chunk-DABEWNL2.js';
3
- import { useConnection } from './chunk-EHXSBH6U.js';
3
+ import { useConnection } from './chunk-5HOAOKZL.js';
4
4
  import { useCallback } from 'react';
5
5
  import { useAiTask, useWorkspaceDocs as useWorkspaceDocs$1, useSemanticSearch as useSemanticSearch$1, useWorkspaceUsers, useArbiChat } from '@arbidocs/react';
6
6
  export { redlineStats, textToArtifact, toRedlineMarkdown } from '@arbidocs/react';
@@ -64,5 +64,5 @@ function ConnectedAssistantDock(props) {
64
64
  }
65
65
 
66
66
  export { ConnectedAssistantDock, useConnectedAiTask, useConnectedChat, useSemanticSearch, useWorkspaceDocs };
67
- //# sourceMappingURL=chunk-CW4WXGEN.js.map
68
- //# sourceMappingURL=chunk-CW4WXGEN.js.map
67
+ //# sourceMappingURL=chunk-3TVTG7FK.js.map
68
+ //# sourceMappingURL=chunk-3TVTG7FK.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/connection/ai.tsx"],"names":["useKitAiTask","useKitWorkspaceDocs","useKitSemanticSearch"],"mappings":"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","file":"chunk-CW4WXGEN.js","sourcesContent":["/**\n * The connected agent hooks — thin adapters over the reusable AI kit in\n * `@arbidocs/react`. The streaming/accumulation/search plumbing lives once in\n * the SDK; these hooks only bind the *workspace source* (from the connection\n * context, falling back to the configured workspace) and inject the host's\n * default assistant *configuration* so call sites needn't know the config\n * ext_id. An explicit `opts.model` still wins.\n */\nimport { useCallback } from 'react'\nimport {\n useAiTask as useKitAiTask,\n useWorkspaceDocs as useKitWorkspaceDocs,\n useSemanticSearch as useKitSemanticSearch,\n useArbiChat,\n useWorkspaceUsers,\n type ArbiChat,\n type UseArbiChatOptions,\n type AiRunOptions,\n} from '@arbidocs/react'\nimport { useConnection } from './ConnectionProvider'\nimport { AssistantDock, type AssistantDockProps } from '../chat/AssistantDock'\nimport type { MentionCandidate } from '../chat/mentions'\n\nexport type { AiTaskStatus, AiRunOptions, SearchChunk, ArtifactEvent } from '@arbidocs/react'\n\n/** Client-side redlining, re-exported so a host app has one import surface. */\nexport { toRedlineMarkdown, redlineStats, textToArtifact } from '@arbidocs/react'\n\n/**\n * The kit's `useAiTask` with the host's default assistant configuration\n * injected, so call sites needn't know the config ext_id.\n */\nexport function useConnectedAiTask() {\n const { assistantConfig } = useConnection()\n const task = useKitAiTask()\n const kitRun = task.run\n const run = useCallback(\n (question: string, docIds: string[], opts?: AiRunOptions) =>\n kitRun(question, docIds, { ...opts, model: opts?.model ?? assistantConfig }),\n [kitRun, assistantConfig]\n )\n return { ...task, run }\n}\n\n/** Resolve the active workspace + its document ids (what we ground the agent on). */\nexport function useWorkspaceDocs() {\n const { workspaceId, fallbackWorkspaceId } = useConnection()\n return useKitWorkspaceDocs(workspaceId ?? fallbackWorkspaceId)\n}\n\n/** Search the active workspace's documents and return the top matching passages. */\nexport function useSemanticSearch() {\n const { docIds } = useWorkspaceDocs()\n return useKitSemanticSearch(docIds)\n}\n\n/**\n * The chat controller for `ChatPage` bound to the connection: the active workspace and the host's\n * default assistant configuration are injected, so a host writes\n * `<ChatPage chat={useConnectedChat()} />`.\n */\nexport function useConnectedChat(\n options?: Omit<UseArbiChatOptions, 'workspaceId'>\n): ArbiChat & { mentionCandidates: MentionCandidate[] } {\n const { workspaceId, fallbackWorkspaceId, assistantConfig, user, status, ensureWorkspaceOpen } =\n useConnection()\n const wsId = workspaceId ?? fallbackWorkspaceId\n const { data: members = [] } = useWorkspaceUsers(wsId, {\n enabled: status === 'authenticated' && !!wsId,\n beforeFetch: ensureWorkspaceOpen,\n })\n const mentionCandidates: MentionCandidate[] = [\n { id: 'assistant', kind: 'assistant', label: 'Assistant' },\n ...(status === 'authenticated' ? members : [])\n .filter(\n (member) =>\n !member.agent_ext_id &&\n member.user.external_id !== user?.externalId &&\n !member.user.external_id.startsWith('agt-')\n )\n .map((member) => ({\n id: member.user.external_id,\n kind: 'user' as const,\n label:\n [member.user.given_name, member.user.family_name].filter(Boolean).join(' ') ||\n member.user.email,\n description: member.user.email,\n }))\n .sort((a, b) => a.label.localeCompare(b.label)),\n ]\n const chat = useArbiChat({\n ...options,\n workspaceId: workspaceId ?? fallbackWorkspaceId,\n model: options?.model ?? assistantConfig,\n })\n return {\n ...chat,\n mentionCandidates,\n messages: chat.messages.map((message) => ({\n ...message,\n ...(message.authorId\n ? {\n senderName:\n message.authorId === user?.externalId\n ? user?.name || user?.email\n : mentionCandidates.find((candidate) => candidate.id === message.authorId)?.label,\n }\n : {}),\n })),\n }\n}\n\n/**\n * The assistant dock bound to the connection: mount it once in the layout (`Shell.Root`'s `aside`)\n * and put `AssistantDockToggle` in the topbar. Chat state lives here, so it survives closing the dock.\n */\nexport function ConnectedAssistantDock(props: Omit<AssistantDockProps, 'chat'>) {\n const chat = useConnectedChat()\n return <AssistantDock {...props} chat={chat} />\n}\n"]}
1
+ {"version":3,"sources":["../src/connection/ai.tsx"],"names":["useKitAiTask","useKitWorkspaceDocs","useKitSemanticSearch"],"mappings":";;;;;;;AAgCO,SAAS,kBAAA,GAAqB;AACnC,EAAA,MAAM,EAAE,eAAA,EAAgB,GAAI,aAAA,EAAc;AAC1C,EAAA,MAAM,OAAOA,SAAA,EAAa;AAC1B,EAAA,MAAM,SAAS,IAAA,CAAK,GAAA;AACpB,EAAA,MAAM,GAAA,GAAM,WAAA;AAAA,IACV,CAAC,QAAA,EAAkB,MAAA,EAAkB,IAAA,KACnC,OAAO,QAAA,EAAU,MAAA,EAAQ,EAAE,GAAG,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,KAAA,IAAS,iBAAiB,CAAA;AAAA,IAC7E,CAAC,QAAQ,eAAe;AAAA,GAC1B;AACA,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,GAAA,EAAI;AACxB;AAGO,SAAS,gBAAA,GAAmB;AACjC,EAAA,MAAM,EAAE,WAAA,EAAa,mBAAA,EAAoB,GAAI,aAAA,EAAc;AAC3D,EAAA,OAAOC,kBAAA,CAAoB,eAAe,mBAAmB,CAAA;AAC/D;AAGO,SAAS,iBAAA,GAAoB;AAClC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,gBAAA,EAAiB;AACpC,EAAA,OAAOC,oBAAqB,MAAM,CAAA;AACpC;AAOO,SAAS,iBACd,OAAA,EACsD;AACtD,EAAA,MAAM,EAAE,aAAa,mBAAA,EAAqB,eAAA,EAAiB,MAAM,MAAA,EAAQ,mBAAA,KACvE,aAAA,EAAc;AAChB,EAAA,MAAM,OAAO,WAAA,IAAe,mBAAA;AAC5B,EAAA,MAAM,EAAE,IAAA,EAAM,OAAA,GAAU,EAAC,EAAE,GAAI,kBAAkB,IAAA,EAAM;AAAA,IACrD,OAAA,EAAS,MAAA,KAAW,eAAA,IAAmB,CAAC,CAAC,IAAA;AAAA,IACzC,WAAA,EAAa;AAAA,GACd,CAAA;AACD,EAAA,MAAM,iBAAA,GAAwC;AAAA,IAC5C,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,WAAA,EAAa,OAAO,WAAA,EAAY;AAAA,IACzD,GAAA,CAAI,MAAA,KAAW,eAAA,GAAkB,OAAA,GAAU,EAAC,EACzC,MAAA;AAAA,MACC,CAAC,MAAA,KACC,CAAC,MAAA,CAAO,gBACR,MAAA,CAAO,IAAA,CAAK,WAAA,KAAgB,IAAA,EAAM,cAClC,CAAC,MAAA,CAAO,IAAA,CAAK,WAAA,CAAY,WAAW,MAAM;AAAA,KAC9C,CACC,GAAA,CAAI,CAAC,MAAA,MAAY;AAAA,MAChB,EAAA,EAAI,OAAO,IAAA,CAAK,WAAA;AAAA,MAChB,IAAA,EAAM,MAAA;AAAA,MACN,OACE,CAAC,MAAA,CAAO,IAAA,CAAK,UAAA,EAAY,OAAO,IAAA,CAAK,WAAW,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,IAC1E,OAAO,IAAA,CAAK,KAAA;AAAA,MACd,WAAA,EAAa,OAAO,IAAA,CAAK;AAAA,KAC3B,CAAE,CAAA,CACD,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,KAAA,CAAM,aAAA,CAAc,CAAA,CAAE,KAAK,CAAC;AAAA,GAClD;AACA,EAAA,MAAM,OAAO,WAAA,CAAY;AAAA,IACvB,GAAG,OAAA;AAAA,IACH,aAAa,WAAA,IAAe,mBAAA;AAAA,IAC5B,KAAA,EAAO,SAAS,KAAA,IAAS;AAAA,GAC1B,CAAA;AACD,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,iBAAA;AAAA,IACA,QAAA,EAAU,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,MAAa;AAAA,MACxC,GAAG,OAAA;AAAA,MACH,GAAI,QAAQ,QAAA,GACR;AAAA,QACE,YACE,OAAA,CAAQ,QAAA,KAAa,IAAA,EAAM,UAAA,GACvB,MAAM,IAAA,IAAQ,IAAA,EAAM,KAAA,GACpB,iBAAA,CAAkB,KAAK,CAAC,SAAA,KAAc,UAAU,EAAA,KAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAAA,UAElF;AAAC,KACP,CAAE;AAAA,GACJ;AACF;AAMO,SAAS,uBAAuB,KAAA,EAAyC;AAC9E,EAAA,MAAM,OAAO,gBAAA,EAAiB;AAC9B,EAAA,uBAAO,GAAA,CAAC,aAAA,EAAA,EAAe,GAAG,KAAA,EAAO,IAAA,EAAY,CAAA;AAC/C","file":"chunk-3TVTG7FK.js","sourcesContent":["/**\n * The connected agent hooks — thin adapters over the reusable AI kit in\n * `@arbidocs/react`. The streaming/accumulation/search plumbing lives once in\n * the SDK; these hooks only bind the *workspace source* (from the connection\n * context, falling back to the configured workspace) and inject the host's\n * default assistant *configuration* so call sites needn't know the config\n * ext_id. An explicit `opts.model` still wins.\n */\nimport { useCallback } from 'react'\nimport {\n useAiTask as useKitAiTask,\n useWorkspaceDocs as useKitWorkspaceDocs,\n useSemanticSearch as useKitSemanticSearch,\n useArbiChat,\n useWorkspaceUsers,\n type ArbiChat,\n type UseArbiChatOptions,\n type AiRunOptions,\n} from '@arbidocs/react'\nimport { useConnection } from './ConnectionProvider'\nimport { AssistantDock, type AssistantDockProps } from '../chat/AssistantDock'\nimport type { MentionCandidate } from '../chat/mentions'\n\nexport type { AiTaskStatus, AiRunOptions, SearchChunk, ArtifactEvent } from '@arbidocs/react'\n\n/** Client-side redlining, re-exported so a host app has one import surface. */\nexport { toRedlineMarkdown, redlineStats, textToArtifact } from '@arbidocs/react'\n\n/**\n * The kit's `useAiTask` with the host's default assistant configuration\n * injected, so call sites needn't know the config ext_id.\n */\nexport function useConnectedAiTask() {\n const { assistantConfig } = useConnection()\n const task = useKitAiTask()\n const kitRun = task.run\n const run = useCallback(\n (question: string, docIds: string[], opts?: AiRunOptions) =>\n kitRun(question, docIds, { ...opts, model: opts?.model ?? assistantConfig }),\n [kitRun, assistantConfig]\n )\n return { ...task, run }\n}\n\n/** Resolve the active workspace + its document ids (what we ground the agent on). */\nexport function useWorkspaceDocs() {\n const { workspaceId, fallbackWorkspaceId } = useConnection()\n return useKitWorkspaceDocs(workspaceId ?? fallbackWorkspaceId)\n}\n\n/** Search the active workspace's documents and return the top matching passages. */\nexport function useSemanticSearch() {\n const { docIds } = useWorkspaceDocs()\n return useKitSemanticSearch(docIds)\n}\n\n/**\n * The chat controller for `ChatPage` bound to the connection: the active workspace and the host's\n * default assistant configuration are injected, so a host writes\n * `<ChatPage chat={useConnectedChat()} />`.\n */\nexport function useConnectedChat(\n options?: Omit<UseArbiChatOptions, 'workspaceId'>\n): ArbiChat & { mentionCandidates: MentionCandidate[] } {\n const { workspaceId, fallbackWorkspaceId, assistantConfig, user, status, ensureWorkspaceOpen } =\n useConnection()\n const wsId = workspaceId ?? fallbackWorkspaceId\n const { data: members = [] } = useWorkspaceUsers(wsId, {\n enabled: status === 'authenticated' && !!wsId,\n beforeFetch: ensureWorkspaceOpen,\n })\n const mentionCandidates: MentionCandidate[] = [\n { id: 'assistant', kind: 'assistant', label: 'Assistant' },\n ...(status === 'authenticated' ? members : [])\n .filter(\n (member) =>\n !member.agent_ext_id &&\n member.user.external_id !== user?.externalId &&\n !member.user.external_id.startsWith('agt-')\n )\n .map((member) => ({\n id: member.user.external_id,\n kind: 'user' as const,\n label:\n [member.user.given_name, member.user.family_name].filter(Boolean).join(' ') ||\n member.user.email,\n description: member.user.email,\n }))\n .sort((a, b) => a.label.localeCompare(b.label)),\n ]\n const chat = useArbiChat({\n ...options,\n workspaceId: workspaceId ?? fallbackWorkspaceId,\n model: options?.model ?? assistantConfig,\n })\n return {\n ...chat,\n mentionCandidates,\n messages: chat.messages.map((message) => ({\n ...message,\n ...(message.authorId\n ? {\n senderName:\n message.authorId === user?.externalId\n ? user?.name || user?.email\n : mentionCandidates.find((candidate) => candidate.id === message.authorId)?.label,\n }\n : {}),\n })),\n }\n}\n\n/**\n * The assistant dock bound to the connection: mount it once in the layout (`Shell.Root`'s `aside`)\n * and put `AssistantDockToggle` in the topbar. Chat state lives here, so it survives closing the dock.\n */\nexport function ConnectedAssistantDock(props: Omit<AssistantDockProps, 'chat'>) {\n const chat = useConnectedChat()\n return <AssistantDock {...props} chat={chat} />\n}\n"]}
@@ -190,6 +190,7 @@ function ConnectionProvider({
190
190
  workspaceId,
191
191
  apiConfigured: isLiveConfigured,
192
192
  apiUrl: config.apiUrl,
193
+ deploymentDomain: isLiveConfigured ? arbi.getDeploymentDomain() : void 0,
193
194
  error,
194
195
  assistantConfig: config.assistantConfig,
195
196
  fallbackWorkspaceId: config.workspaceId,
@@ -206,6 +207,7 @@ function ConnectionProvider({
206
207
  workspaceId,
207
208
  isLiveConfigured,
208
209
  config.apiUrl,
210
+ arbi,
209
211
  config.assistantConfig,
210
212
  config.workspaceId,
211
213
  error,
@@ -226,5 +228,5 @@ function useConnection() {
226
228
  var isAuthenticated = (s) => s === "demo" || s === "authenticated";
227
229
 
228
230
  export { ConnectionProvider, SESSION_EXPIRED_MESSAGE, isAuthenticated, useConnection };
229
- //# sourceMappingURL=chunk-EHXSBH6U.js.map
230
- //# sourceMappingURL=chunk-EHXSBH6U.js.map
231
+ //# sourceMappingURL=chunk-5HOAOKZL.js.map
232
+ //# sourceMappingURL=chunk-5HOAOKZL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connection/ConnectionProvider.tsx"],"names":[],"mappings":"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","file":"chunk-5HOAOKZL.js","sourcesContent":["/**\n * The demo/live connection layer for a host app. Holds auth + workspace\n * selection state and exposes it via {@link useConnection}, so every surface\n * works identically whether it's talking to a live ARBI backend or the seeded\n * demo workspace. Host-specific values (backend URL, demo identity, default\n * workspace/assistant ids) arrive once through {@link ArbiConnectionConfig}.\n */\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react'\nimport { useArbi, type LoginProfile } from '@arbidocs/react'\nimport type { ArbiMode, ArbiUser, ConnectionStatus, ArbiConnectionConfig } from './types'\n\ninterface ConnectionValue {\n mode: ArbiMode\n status: ConnectionStatus\n user: ArbiUser | null\n workspaceId: string | null\n apiConfigured: boolean\n apiUrl: string\n /**\n * The deployment domain the user's keys are derived for (`arbi.getDeploymentDomain()`), for the\n * document tools' e-signing. `undefined` in demo mode.\n */\n deploymentDomain: string | undefined\n error: string | null\n /** Default assistant config ext_id (for the AI hooks). */\n assistantConfig?: string\n /** Fallback workspace ext_id when none is actively selected. */\n fallbackWorkspaceId?: string\n /** Authenticate. Live login when a backend is configured, otherwise the demo workspace. */\n login: (email: string, password: string) => Promise<void>\n /** One-click demo entry (no backend required). */\n enterDemo: () => void\n logout: () => void\n /**\n * Affirmatively select a workspace: opens it on the server (via the SDK),\n * updates the app-wide state, and persists the choice so it survives future\n * logins. This is the single entry point for \"the user is now in workspace X\".\n */\n setWorkspace: (id: string) => Promise<void>\n /**\n * Re-assert the selected workspace on the server session (idempotent `/open`).\n * Call before a workspace-scoped write when the session may have lost its open\n * workspace (token re-login, backend restart, session expiry) — the server\n * resolves the workspace from the session, so a dropped `/open` yields\n * \"No active workspace\" until it's re-opened.\n */\n ensureWorkspaceOpen: () => Promise<void>\n}\n\nconst ConnectionContext = createContext<ConnectionValue | null>(null)\n\n/**\n * Persist the affirmatively-selected workspace per backend AND per signed-in user, so a returning\n * user lands back in the workspace they last chose, while the next person on a shared browser\n * never starts from someone else's workspace id. Namespaced by apiUrl so distinct deployments\n * (and the demo workspace) don't clobber each other. Cleared on logout.\n */\nconst WORKSPACE_STORAGE_PREFIX = 'arbi:selectedWorkspace'\nconst sessionUserKey = (apiUrl: string) => `arbi:sessionUser:${apiUrl}`\nfunction rememberSessionUser(apiUrl: string, email: string | null) {\n try {\n if (email) window.localStorage.setItem(sessionUserKey(apiUrl), normalizeUserKey(email))\n else window.localStorage.removeItem(sessionUserKey(apiUrl))\n } catch {\n /* Storage may be unavailable. */\n }\n}\nconst normalizeUserKey = (email: string) => email.trim().toLowerCase()\n\n/** Exported for tests. */\nexport const workspaceStorageKey = (apiUrl: string, userKey: string) =>\n `${WORKSPACE_STORAGE_PREFIX}:${apiUrl || 'demo'}:${normalizeUserKey(userKey)}`\n\n/** The pre-isolation key (apiUrl only). Never read: removed so it cannot leak across users. */\nconst legacyWorkspaceStorageKey = (apiUrl: string) =>\n `${WORKSPACE_STORAGE_PREFIX}:${apiUrl || 'demo'}`\n\nfunction readPersistedWorkspace(apiUrl: string, userKey: string | null): string | null {\n if (!userKey) return null\n try {\n return window.localStorage.getItem(workspaceStorageKey(apiUrl, userKey))\n } catch {\n return null\n }\n}\n\nfunction persistWorkspace(apiUrl: string, userKey: string | null, id: string | null): void {\n if (!userKey) return\n try {\n if (id) window.localStorage.setItem(workspaceStorageKey(apiUrl, userKey), id)\n else window.localStorage.removeItem(workspaceStorageKey(apiUrl, userKey))\n window.localStorage.removeItem(legacyWorkspaceStorageKey(apiUrl))\n } catch {\n // Storage unavailable (private mode, SSR) — selection stays in-memory only.\n }\n}\n\n/** Shown on the sign-in screen after the session could not be recovered. */\nexport const SESSION_EXPIRED_MESSAGE = 'Your session expired. Sign in again.'\n\n/** The connection user for a profile: its full name, falling back to the email local part. */\nfunction userFromProfile(profile: LoginProfile, externalId?: string): ArbiUser {\n const fullName = [profile.givenName, profile.familyName]\n .map((part) => part?.trim())\n .filter(Boolean)\n .join(' ')\n return {\n name: fullName || profile.email.split('@')[0],\n email: profile.email,\n externalId,\n picture: profile.picture,\n }\n}\n\nexport function ConnectionProvider({\n config,\n children,\n}: {\n config: ArbiConnectionConfig\n children: ReactNode\n}) {\n const arbi = useArbi()\n const isLiveConfigured = config.apiUrl.length > 0\n const demoWorkspaceId = config.demoWorkspaceId ?? 'demo-workspace'\n\n const [status, setStatus] = useState<ConnectionStatus>(\n isLiveConfigured ? 'connecting' : 'disconnected'\n )\n const [user, setUser] = useState<ArbiUser | null>(null)\n const [workspaceId, setWorkspaceId] = useState<string | null>(null)\n const [mode, setMode] = useState<ArbiMode>('demo')\n const [error, setError] = useState<string | null>(null)\n // Who the persisted workspace belongs to; set at sign-in, cleared at logout.\n const storageUserRef = useRef<string | null>(null)\n\n // The SDK could not recover the session (token refused, workspace not re-openable): drop to\n // 'disconnected' with a plain message, so the host's gate sends the user to sign in instead of\n // every call failing with a raw backend error. The remembered workspace is kept for next login.\n useEffect(\n () =>\n arbi.onSessionExpired?.(() => {\n rememberSessionUser(config.apiUrl, null)\n storageUserRef.current = null\n setUser(null)\n setWorkspaceId(null)\n setStatus('disconnected')\n setError(SESSION_EXPIRED_MESSAGE)\n }),\n [arbi, config.apiUrl]\n )\n\n // A saved name, picture or email reaches every surface reading `useConnection().user`.\n useEffect(\n () =>\n arbi.user.onProfileChange?.((profile) =>\n setUser((current) => (current ? userFromProfile(profile, current.externalId) : current))\n ),\n [arbi]\n )\n\n const enterDemo = useCallback(() => {\n setMode('demo')\n setStatus('demo')\n setError(null)\n setUser({ name: config.demoUser.name, email: config.demoUser.email })\n setWorkspaceId(demoWorkspaceId)\n }, [config.demoUser.name, config.demoUser.email, demoWorkspaceId])\n\n const login = useCallback(\n async (email: string, password: string, restoring = false) => {\n setError(null)\n // No backend configured → run the seeded demo workspace.\n if (!isLiveConfigured) {\n enterDemo()\n return\n }\n setStatus('connecting')\n setMode('live')\n try {\n if (restoring) {\n if (!(await arbi.restoreSession(email))) {\n rememberSessionUser(config.apiUrl, null)\n setStatus('disconnected')\n return\n }\n } else await arbi.login(email, password)\n storageUserRef.current = normalizeUserKey(email)\n const workspaces = await arbi.workspaces.list()\n if (workspaces?.length) {\n // Prefer the workspace the user last affirmatively selected (persisted),\n // then the configured workspace (there may be several — e.g. a\n // marketing/KM workspace), then whichever happens to be first. Ternary\n // (not `&&`) so an empty value can't leak `\"\"` into `target`.\n const persisted = readPersistedWorkspace(config.apiUrl, storageUserRef.current)\n const preferred = persisted ?? config.workspaceId\n const target =\n (preferred ? workspaces.find((w) => w.external_id === preferred) : undefined) ??\n workspaces[0]\n await arbi.selectWorkspace(target.external_id)\n setWorkspaceId(target.external_id)\n persistWorkspace(config.apiUrl, storageUserRef.current, target.external_id)\n }\n // The profile (name + avatar) comes with the login response. A session restored without\n // a login has none, so fall back to finding ourselves in the workspace roster; the email\n // local part is only the last resort, never the answer when a profile name exists.\n let resolved: ArbiUser = { name: email.split('@')[0], email }\n const me = arbi.user.identity()\n const profile = arbi.user.profile?.()\n if (profile) {\n resolved = userFromProfile(profile, me?.externalId)\n } else {\n try {\n const members = await arbi.workspaces.listUsers()\n const self = members.find((m) => m.user.external_id === me?.externalId)?.user\n if (self) {\n const fullName = [self.given_name, self.family_name].filter(Boolean).join(' ').trim()\n resolved = {\n name: fullName || email.split('@')[0],\n email: self.email || email,\n externalId: self.external_id,\n picture: self.picture ?? null,\n }\n } else if (me?.externalId) {\n resolved.externalId = me.externalId\n }\n } catch {\n // Roster not available (e.g. no workspace) — keep the fallback identity.\n }\n }\n setUser(resolved)\n rememberSessionUser(config.apiUrl, email)\n setStatus('authenticated')\n } catch (e) {\n // Surface the real error — no silent fallback to a fake session.\n setError(e instanceof Error ? e.message : 'Sign-in failed. Check your credentials.')\n setStatus('error')\n }\n },\n [arbi, enterDemo, isLiveConfigured, config.workspaceId, config.apiUrl]\n )\n\n // Run once even under StrictMode; passwords and signing keys are never stored here.\n const recoveryStarted = useRef(false)\n useEffect(() => {\n if (recoveryStarted.current || !isLiveConfigured) return\n recoveryStarted.current = true\n let email: string | null = null\n try {\n email = window.localStorage.getItem(sessionUserKey(config.apiUrl))\n } catch {\n /* unavailable */\n }\n if (email) void login(email, '', true)\n else setStatus('disconnected')\n }, [isLiveConfigured, config.apiUrl, login])\n\n const logout = useCallback(() => {\n rememberSessionUser(config.apiUrl, null)\n if (mode === 'live') {\n void arbi.logout?.()\n }\n setUser(null)\n setWorkspaceId(null)\n persistWorkspace(config.apiUrl, storageUserRef.current, null)\n storageUserRef.current = null\n setStatus('disconnected')\n setError(null)\n }, [arbi, mode, config.apiUrl])\n\n // Affirmative selection: open the workspace on the server (live), then remember\n // it in state + storage so every surface — and the next login — is in sync.\n const setWorkspace = useCallback(\n async (id: string) => {\n if (mode === 'live' && arbi.isLoggedIn) {\n await arbi.selectWorkspace(id)\n }\n setWorkspaceId(id)\n persistWorkspace(config.apiUrl, storageUserRef.current, id)\n },\n [arbi, mode, config.apiUrl]\n )\n\n // Re-open the selected workspace on the session if the server may have dropped\n // it. Idempotent: re-running `/open` for the already-selected workspace is safe.\n const ensureWorkspaceOpen = useCallback(async () => {\n if (mode !== 'live' || !arbi.isLoggedIn) return\n const id =\n workspaceId ??\n readPersistedWorkspace(config.apiUrl, storageUserRef.current) ??\n config.workspaceId\n if (id) await arbi.selectWorkspace(id)\n }, [arbi, mode, workspaceId, config.apiUrl, config.workspaceId])\n\n const value = useMemo<ConnectionValue>(\n () => ({\n mode,\n status,\n user,\n workspaceId,\n apiConfigured: isLiveConfigured,\n apiUrl: config.apiUrl,\n deploymentDomain: isLiveConfigured ? arbi.getDeploymentDomain() : undefined,\n error,\n assistantConfig: config.assistantConfig,\n fallbackWorkspaceId: config.workspaceId,\n login,\n enterDemo,\n logout,\n setWorkspace,\n ensureWorkspaceOpen,\n }),\n [\n mode,\n status,\n user,\n workspaceId,\n isLiveConfigured,\n config.apiUrl,\n arbi,\n config.assistantConfig,\n config.workspaceId,\n error,\n login,\n enterDemo,\n logout,\n setWorkspace,\n ensureWorkspaceOpen,\n ]\n )\n\n return <ConnectionContext.Provider value={value}>{children}</ConnectionContext.Provider>\n}\n\nexport function useConnection(): ConnectionValue {\n const ctx = useContext(ConnectionContext)\n if (!ctx) throw new Error('useConnection must be used within ConnectionProvider')\n return ctx\n}\n\nexport const isAuthenticated = (s: ConnectionStatus) => s === 'demo' || s === 'authenticated'\n"]}
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
6
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
7
+ }) : x)(function(x) {
8
+ if (typeof require !== "undefined") return require.apply(this, arguments);
9
+ throw Error('Dynamic require of "' + x + '" is not supported');
10
+ });
11
+ var __commonJS = (cb, mod) => function __require2() {
12
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
13
+ };
14
+
15
+ exports.__commonJS = __commonJS;
16
+ exports.__require = __require;
17
+ //# sourceMappingURL=chunk-DES3K4SD.cjs.map
18
+ //# sourceMappingURL=chunk-DES3K4SD.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-DES3K4SD.cjs"}
@@ -2,13 +2,13 @@
2
2
  'use strict';
3
3
 
4
4
  var chunk5DM6VU4L_cjs = require('./chunk-5DM6VU4L.cjs');
5
- var chunkTLQQV7WW_cjs = require('./chunk-TLQQV7WW.cjs');
5
+ var chunkTHO7DZNN_cjs = require('./chunk-THO7DZNN.cjs');
6
6
  var react$1 = require('react');
7
7
  var react = require('@arbidocs/react');
8
8
  var jsxRuntime = require('react/jsx-runtime');
9
9
 
10
10
  function useConnectedAiTask() {
11
- const { assistantConfig } = chunkTLQQV7WW_cjs.useConnection();
11
+ const { assistantConfig } = chunkTHO7DZNN_cjs.useConnection();
12
12
  const task = react.useAiTask();
13
13
  const kitRun = task.run;
14
14
  const run = react$1.useCallback(
@@ -18,7 +18,7 @@ function useConnectedAiTask() {
18
18
  return { ...task, run };
19
19
  }
20
20
  function useWorkspaceDocs() {
21
- const { workspaceId, fallbackWorkspaceId } = chunkTLQQV7WW_cjs.useConnection();
21
+ const { workspaceId, fallbackWorkspaceId } = chunkTHO7DZNN_cjs.useConnection();
22
22
  return react.useWorkspaceDocs(workspaceId ?? fallbackWorkspaceId);
23
23
  }
24
24
  function useSemanticSearch() {
@@ -26,7 +26,7 @@ function useSemanticSearch() {
26
26
  return react.useSemanticSearch(docIds);
27
27
  }
28
28
  function useConnectedChat(options) {
29
- const { workspaceId, fallbackWorkspaceId, assistantConfig, user, status, ensureWorkspaceOpen } = chunkTLQQV7WW_cjs.useConnection();
29
+ const { workspaceId, fallbackWorkspaceId, assistantConfig, user, status, ensureWorkspaceOpen } = chunkTHO7DZNN_cjs.useConnection();
30
30
  const wsId = workspaceId ?? fallbackWorkspaceId;
31
31
  const { data: members = [] } = react.useWorkspaceUsers(wsId, {
32
32
  enabled: status === "authenticated" && !!wsId,
@@ -81,5 +81,5 @@ exports.useConnectedAiTask = useConnectedAiTask;
81
81
  exports.useConnectedChat = useConnectedChat;
82
82
  exports.useSemanticSearch = useSemanticSearch;
83
83
  exports.useWorkspaceDocs = useWorkspaceDocs;
84
- //# sourceMappingURL=chunk-BR2CPKFU.cjs.map
85
- //# sourceMappingURL=chunk-BR2CPKFU.cjs.map
84
+ //# sourceMappingURL=chunk-LTA2IAQB.cjs.map
85
+ //# sourceMappingURL=chunk-LTA2IAQB.cjs.map