@bendyline/docblocks 2.7.3 → 2.7.5

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 (52) hide show
  1. package/THIRD_PARTY_NOTICES.txt +37 -6
  2. package/dist/{capabilities-r03EXSAi.d.ts → capabilities-DHwh4P4D.d.ts} +29 -3
  3. package/dist/{chunk-KQ6756AJ.js → chunk-3GSMJ4MQ.js} +1 -1
  4. package/dist/{chunk-YWYT6K6J.js → chunk-3LXXRIO2.js} +1 -1
  5. package/dist/{chunk-ZTSG7AC3.js → chunk-64733GFL.js} +35 -2
  6. package/dist/{chunk-UK7R3RC7.js → chunk-BC42VRYW.js} +1 -1
  7. package/dist/{chunk-DFMRE22M.js → chunk-EFGQUOTL.js} +17 -3
  8. package/dist/{chunk-IGB2VSRE.js → chunk-FIEMYP2N.js} +2 -2
  9. package/dist/{chunk-M5ZNQGR5.js → chunk-IYKGM3PV.js} +1 -1
  10. package/dist/{chunk-6UPO2GE6.js → chunk-K5HRMSXD.js} +3 -3
  11. package/dist/{chunk-UDEWLHQI.js → chunk-LDAG5NTQ.js} +3 -3
  12. package/dist/{chunk-7SN7YQL4.js → chunk-LJLQYXVL.js} +99 -3
  13. package/dist/{chunk-4I4AG2BH.js → chunk-P32NVUQL.js} +2 -2
  14. package/dist/{chunk-HKOOHM67.js → chunk-Q3OFZWJS.js} +3 -3
  15. package/dist/{chunk-AYWKIZLD.js → chunk-UTH3HYCZ.js} +5 -1
  16. package/dist/{chunk-QS5WTLUZ.js → chunk-XI2LYBRR.js} +167 -0
  17. package/dist/document/index.d.ts +2 -2
  18. package/dist/document/index.js +3 -3
  19. package/dist/filesystem/electron.d.ts +5 -5
  20. package/dist/filesystem/electron.js +4 -4
  21. package/dist/filesystem/host.d.ts +4 -4
  22. package/dist/filesystem/host.js +4 -4
  23. package/dist/filesystem/index.d.ts +27 -8
  24. package/dist/filesystem/index.js +22 -12
  25. package/dist/filesystem/indexeddb.d.ts +2 -2
  26. package/dist/filesystem/indexeddb.js +4 -4
  27. package/dist/filesystem/memory.d.ts +2 -2
  28. package/dist/filesystem/memory.js +4 -4
  29. package/dist/filesystem/native.d.ts +2 -2
  30. package/dist/filesystem/native.js +4 -4
  31. package/dist/{filesystem-v2-C8AdSXUN.d.ts → filesystem-v2-CXdAPR27.d.ts} +1 -1
  32. package/dist/host/index.d.ts +7 -5
  33. package/dist/host/index.js +1 -1
  34. package/dist/host/mobile.d.ts +2 -2
  35. package/dist/host/mobile.js +1 -1
  36. package/dist/{host-provider-v2-CV0joXaL.d.ts → host-provider-v2-DEWMPiRD.d.ts} +2 -2
  37. package/dist/index.d.ts +8 -7
  38. package/dist/index.js +23 -13
  39. package/dist/mcp/index.js +2 -2
  40. package/dist/mcp/zod.js +2 -2
  41. package/dist/reconcile-electron-Ci2lhAdW.d.ts +142 -0
  42. package/dist/{types-BvDnr3YU.d.ts → types-DLteNrK0.d.ts} +3 -1
  43. package/dist/{v2-BVnZZyd4.d.ts → v2-DwxWjFC0.d.ts} +12 -1
  44. package/dist/vscode/index.d.ts +28 -2
  45. package/dist/vscode/index.js +21 -3
  46. package/dist/workspace/index.d.ts +41 -141
  47. package/dist/workspace/index.js +16 -1
  48. package/dist/workspace-index/index.d.ts +3 -1
  49. package/dist/workspace-index/index.js +18 -2
  50. package/dist/workspace-settings/index.d.ts +1 -1
  51. package/dist/workspace-settings/index.js +3 -3
  52. package/package.json +2 -2
@@ -6,7 +6,7 @@ Run `npm run generate:notices` from the repository root.
6
6
  Resolved runtime and optional dependency closure declared by packages/core/package.json.
7
7
 
8
8
  Inventory source: package-lock.json.
9
- Components: 112.
9
+ Components: 113.
10
10
 
11
11
  This notice is included in the published npm tarball. Transitive packages installed by npm also retain their package-local license files.
12
12
 
@@ -14,7 +14,8 @@ This notice is included in the published npm tarball. Transitive packages instal
14
14
 
15
15
  | Package | Version | License | Source |
16
16
  | --- | --- | --- | --- |
17
- | @bendyline/squisq | 2.12.3 | MIT | https://github.com/bendyline/squisq |
17
+ | @bendyline/squisq | 2.13.0 | MIT | https://github.com/bendyline/squisq |
18
+ | @bendyline/squisq-graph | 2.13.0 | MIT | https://github.com/bendyline/squisq |
18
19
  | @types/debug | 4.1.12 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
19
20
  | @types/hast | 3.0.4 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
20
21
  | @types/katex | 0.16.8 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
@@ -132,8 +133,8 @@ This notice is included in the published npm tarball. Transitive packages instal
132
133
  Package-local license, copying, and notice files are reproduced below. Where a published package omits its repository license, the reviewed aggregate or README identified in `Source files` supplies the retained material.
133
134
 
134
135
  ==============================================================================
135
- Components: @bendyline/squisq@2.12.3
136
- Source files: node_modules/@bendyline/squisq/LICENSE
136
+ Components: @bendyline/squisq-graph@2.13.0, @bendyline/squisq@2.13.0
137
+ Source files: node_modules/@bendyline/squisq-graph/LICENSE, node_modules/@bendyline/squisq/LICENSE
137
138
  ==============================================================================
138
139
  MIT License
139
140
 
@@ -158,7 +159,37 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
158
159
  SOFTWARE.
159
160
 
160
161
  ==============================================================================
161
- Components: @bendyline/squisq@2.12.3
162
+ Components: @bendyline/squisq-graph@2.13.0
163
+ Source files: node_modules/@bendyline/squisq-graph/NOTICE.md
164
+ ==============================================================================
165
+ # Third-Party Notices for @bendyline/squisq-graph
166
+
167
+ This notice applies to the `@bendyline/squisq-graph` npm package.
168
+ Squisq-authored code is licensed under the MIT license in `LICENSE`.
169
+ Third-party components remain under their respective license terms.
170
+
171
+ ## Runtime dependencies
172
+
173
+ | Package | Version | License | Repository |
174
+ | ------- | ------- | ------- | ---------- |
175
+
176
+ This package has no third-party runtime dependencies. The layout engine and its
177
+ worker entry are Squisq-authored (MIT).
178
+
179
+ ==============================================================================
180
+ Components: @bendyline/squisq-graph@2.13.0
181
+ Source files: node_modules/@bendyline/squisq-graph/THIRD_PARTY_LICENSES.txt
182
+ ==============================================================================
183
+ THIRD-PARTY LICENSES FOR @bendyline/squisq-graph
184
+
185
+ Generated from the actual esbuild input graph. Package-local license, copying,
186
+ and notice files are reproduced verbatim. When an npm tarball omits its
187
+ repository license, the pinned upstream copy is vendored and identified below.
188
+
189
+ COMPONENTS
190
+
191
+ ==============================================================================
192
+ Components: @bendyline/squisq@2.13.0
162
193
  Source files: node_modules/@bendyline/squisq/NOTICE.md
163
194
  ==============================================================================
164
195
  # Third-Party Notices for @bendyline/squisq
@@ -189,7 +220,7 @@ third-party license texts for bundled code and data are shipped in
189
220
  THIRD_PARTY_LICENSES.txt.
190
221
 
191
222
  ==============================================================================
192
- Components: @bendyline/squisq@2.12.3
223
+ Components: @bendyline/squisq@2.13.0
193
224
  Source files: node_modules/@bendyline/squisq/THIRD_PARTY_LICENSES.txt
194
225
  ==============================================================================
195
226
  THIRD-PARTY LICENSES FOR @bendyline/squisq
@@ -1,5 +1,5 @@
1
- import { F as FileCommitResult, c as FileSystemEntry, b as FileMeta } from './types-BvDnr3YU.js';
2
- import { D as DocBlocksHostFsV2API } from './filesystem-v2-C8AdSXUN.js';
1
+ import { F as FileCommitResult, c as FileSystemEntry, b as FileMeta } from './types-DLteNrK0.js';
2
+ import { D as DocBlocksHostFsV2API } from './filesystem-v2-CXdAPR27.js';
3
3
 
4
4
  /** Provider-neutral catalog management. IDs never authorize filesystem access. */
5
5
  interface AiKnowledgeCatalog {
@@ -195,6 +195,18 @@ interface AiChatMessage {
195
195
  * and flashcards, made in many small calls with explicit caps) never does.
196
196
  */
197
197
  type AiChatPurpose = 'write' | 'review' | 'illustrate' | 'study' | 'chat';
198
+ /**
199
+ * Structured output: the reply should be one JSON value matching `schema`, a
200
+ * JSON Schema object. Hosts that can enforce it do (llama.cpp with a grammar,
201
+ * Apple's on-device model with guided generation); others ignore it. Callers
202
+ * still validate the reply.
203
+ */
204
+ interface AiResponseFormat {
205
+ readonly type: 'json_schema';
206
+ /** A short identifier for the shape, such as `presentation_slide`. */
207
+ readonly name: string;
208
+ readonly schema: Readonly<Record<string, unknown>>;
209
+ }
198
210
  interface AiChatRequest {
199
211
  readonly messages: readonly AiChatMessage[];
200
212
  /** Opaque provider model id. Omitted means "the host's current choice". */
@@ -203,6 +215,7 @@ interface AiChatRequest {
203
215
  /** Optional caller cap. Writing without one uses the host/model's available capacity. */
204
216
  readonly maxTokens?: number;
205
217
  readonly purpose: AiChatPurpose;
218
+ readonly responseFormat?: AiResponseFormat;
206
219
  }
207
220
  interface AiChatCompletion {
208
221
  readonly text: string;
@@ -892,6 +905,8 @@ interface HostExportTargetGrant {
892
905
  }
893
906
  /** Native export target selection and binary file writing. */
894
907
  interface DocBlocksHostExportAPI {
908
+ /** Open a successfully saved grant in its default app; Markdown opens in DocBlocks. */
909
+ openSaved?(documentId: string, grantId: string): Promise<void>;
895
910
  /** A share-sheet outcome is never a durable export target. Android can only report presentation. */
896
911
  share?(filename: string, data: ArrayBuffer | Uint8Array): Promise<'shared' | 'presented' | 'cancelled'>;
897
912
  /** Resolve an exact remembered grant or a display-only host suggestion. */
@@ -1001,6 +1016,14 @@ interface DocBlocksHostMenuAPI {
1001
1016
  * previously published list; send an empty array to clear the shortcuts.
1002
1017
  */
1003
1018
  setPinnedDocuments(documents: readonly HostPinnedDocument[]): void;
1019
+ /**
1020
+ * Whether DocBlocks keeps an icon in the macOS menu bar, the Windows
1021
+ * notification area, or the Linux system tray. Off until the user turns it
1022
+ * on. Absent on a host without one.
1023
+ */
1024
+ getTrayEnabled?(): Promise<boolean>;
1025
+ /** Show or remove the tray icon, remembered across launches; resolves with the saved value. */
1026
+ setTrayEnabled?(enabled: boolean): Promise<boolean>;
1004
1027
  }
1005
1028
  /**
1006
1029
  * OS open-file / deep-link event resolved by the host.
@@ -1188,10 +1211,13 @@ interface HostCapabilities {
1188
1211
  readonly exportDestinations: boolean;
1189
1212
  /** Remembered, re-resolvable export targets (`resolveTarget`/`pickTarget`). */
1190
1213
  readonly exportRememberedTargets: boolean;
1214
+ readonly openSavedExports: boolean;
1191
1215
  readonly externalResources: boolean;
1192
1216
  readonly openRequests: boolean;
1193
1217
  readonly menuCommands: boolean;
1194
1218
  readonly pinnedDocumentMirror: boolean;
1219
+ /** An opt-in tray / menu bar icon the user can turn on and off. */
1220
+ readonly trayIcon: boolean;
1195
1221
  readonly guardedClose: boolean;
1196
1222
  readonly git: boolean;
1197
1223
  readonly updater: boolean;
@@ -1250,4 +1276,4 @@ declare function parseHostEnvironment(value: unknown): HostEnvironment | null;
1250
1276
  */
1251
1277
  declare function deriveHostCapabilities(host: unknown): HostCapabilities;
1252
1278
 
1253
- export { type GitBranchInfo as $, type AiChatCompletion as A, type AiReviewMode as B, type AiSearchHit as C, type AiSearchQuery as D, type AiSearchResult as E, type AiSpeechAudio as F, type AiStatus as G, type AiSynthesizeRequest as H, type AiTranscribeRequest as I, type AiTranscript as J, type AiUnavailableReason as K, type DocBlocksHostAPI as L, type DocBlocksHostAiAPI as M, type DocBlocksHostClipboardAPI as N, type DocBlocksHostExportAPI as O, type DocBlocksHostExternalAPI as P, type DocBlocksHostFfmpegAPI as Q, type DocBlocksHostFsAPI as R, type DocBlocksHostGitAPI as S, type DocBlocksHostLifecycleAPI as T, type DocBlocksHostMenuAPI as U, type DocBlocksHostShellAPI as V, type DocBlocksHostSpeechAPI as W, type DocBlocksHostUpdaterAPI as X, type DocBlocksHostWorkspacesAPI as Y, type ElectronWorkspaceInfo as Z, type ExternalBinaryCommitResult as _, type AiChatEvent as a, type GitCapabilities as a0, type GitCloneHandle as a1, type GitCloneProgress as a2, type GitError as a3, type GitErrorCode as a4, type GitFileAtRevision as a5, type GitFileChange as a6, type GitFileStatusCode as a7, type GitLogEntry as a8, type GitLogOptions as a9, type SpeechModelKind as aA, type SpeechPreferences as aB, type SpeechPreferencesPatch as aC, type SpeechProgress as aD, type SpeechReadiness as aE, type SpeechReadinessState as aF, type SpeechResult as aG, type SpeechSegment as aH, type SpeechStatus as aI, type SpeechSynthesisHandle as aJ, type SpeechSynthesisSummary as aK, type SpeechSynthesizeEvent as aL, type SpeechSynthesizeRequest as aM, type SpeechTranscribeRequest as aN, type SpeechTranscript as aO, type SpeechVoiceInfo as aP, type SpeechWordTiming as aQ, type UpdateCheckResult as aR, type UpdateInstallResult as aS, type UpdaterStatus as aT, deriveHostCapabilities as aU, parseAiKnowledgeAction as aV, parseAiKnowledgeState as aW, parseHostEnvironment as aX, type GitRemoteInfo as aa, type GitRepoDetection as ab, type GitResult as ac, type GitRevision as ad, type GitStatus as ae, HOST_PLATFORMS as af, HOST_SURFACE_KINDS as ag, type HostCapabilities as ah, type HostCloseReason as ai, type HostEnvironment as aj, type HostExportTargetGrant as ak, type HostPinnedDocument as al, type HostPlatform as am, type HostPrepareCloseRequest as an, type HostPrepareCloseResult as ao, type HostSurfaceKind as ap, type MenuCommand as aq, NO_HOST_CAPABILITIES as ar, type OpenRequest as as, type SpeechAudioChunk as at, type SpeechCatalog as au, type SpeechError as av, type SpeechErrorCode as aw, type SpeechInstallEvent as ax, type SpeechInstallHandle as ay, type SpeechModelInfo as az, type AiChatHandle as b, type AiChatMessage as c, type AiChatProgress as d, type AiChatPurpose as e, type AiChatRequest as f, type AiConnectionStep as g, type AiEnsureWorkspaceHandle as h, type AiError as i, type AiErrorCode as j, type AiImageRequest as k, type AiImageResult as l, type AiKnowledgeAPI as m, type AiKnowledgeAction as n, type AiKnowledgeCatalog as o, type AiKnowledgeState as p, type AiModelDownloadInfo as q, type AiModelFit as r, type AiModelInfo as s, type AiModelInstallEvent as t, type AiModelInstallHandle as u, type AiPreferences as v, type AiPreferencesPatch as w, type AiProgress as x, type AiProviderInfo as y, type AiResult as z };
1279
+ export { type ExternalBinaryCommitResult as $, type AiChatCompletion as A, type AiResult as B, type AiReviewMode as C, type AiSearchHit as D, type AiSearchQuery as E, type AiSearchResult as F, type AiSpeechAudio as G, type AiStatus as H, type AiSynthesizeRequest as I, type AiTranscribeRequest as J, type AiTranscript as K, type AiUnavailableReason as L, type DocBlocksHostAPI as M, type DocBlocksHostAiAPI as N, type DocBlocksHostClipboardAPI as O, type DocBlocksHostExportAPI as P, type DocBlocksHostExternalAPI as Q, type DocBlocksHostFfmpegAPI as R, type DocBlocksHostFsAPI as S, type DocBlocksHostGitAPI as T, type DocBlocksHostLifecycleAPI as U, type DocBlocksHostMenuAPI as V, type DocBlocksHostShellAPI as W, type DocBlocksHostSpeechAPI as X, type DocBlocksHostUpdaterAPI as Y, type DocBlocksHostWorkspacesAPI as Z, type ElectronWorkspaceInfo as _, type AiChatEvent as a, type GitBranchInfo as a0, type GitCapabilities as a1, type GitCloneHandle as a2, type GitCloneProgress as a3, type GitError as a4, type GitErrorCode as a5, type GitFileAtRevision as a6, type GitFileChange as a7, type GitFileStatusCode as a8, type GitLogEntry as a9, type SpeechModelInfo as aA, type SpeechModelKind as aB, type SpeechPreferences as aC, type SpeechPreferencesPatch as aD, type SpeechProgress as aE, type SpeechReadiness as aF, type SpeechReadinessState as aG, type SpeechResult as aH, type SpeechSegment as aI, type SpeechStatus as aJ, type SpeechSynthesisHandle as aK, type SpeechSynthesisSummary as aL, type SpeechSynthesizeEvent as aM, type SpeechSynthesizeRequest as aN, type SpeechTranscribeRequest as aO, type SpeechTranscript as aP, type SpeechVoiceInfo as aQ, type SpeechWordTiming as aR, type UpdateCheckResult as aS, type UpdateInstallResult as aT, type UpdaterStatus as aU, deriveHostCapabilities as aV, parseAiKnowledgeAction as aW, parseAiKnowledgeState as aX, parseHostEnvironment as aY, type GitLogOptions as aa, type GitRemoteInfo as ab, type GitRepoDetection as ac, type GitResult as ad, type GitRevision as ae, type GitStatus as af, HOST_PLATFORMS as ag, HOST_SURFACE_KINDS as ah, type HostCapabilities as ai, type HostCloseReason as aj, type HostEnvironment as ak, type HostExportTargetGrant as al, type HostPinnedDocument as am, type HostPlatform as an, type HostPrepareCloseRequest as ao, type HostPrepareCloseResult as ap, type HostSurfaceKind as aq, type MenuCommand as ar, NO_HOST_CAPABILITIES as as, type OpenRequest as at, type SpeechAudioChunk as au, type SpeechCatalog as av, type SpeechError as aw, type SpeechErrorCode as ax, type SpeechInstallEvent as ay, type SpeechInstallHandle as az, type AiChatHandle as b, type AiChatMessage as c, type AiChatProgress as d, type AiChatPurpose as e, type AiChatRequest as f, type AiConnectionStep as g, type AiEnsureWorkspaceHandle as h, type AiError as i, type AiErrorCode as j, type AiImageRequest as k, type AiImageResult as l, type AiKnowledgeAPI as m, type AiKnowledgeAction as n, type AiKnowledgeCatalog as o, type AiKnowledgeState as p, type AiModelDownloadInfo as q, type AiModelFit as r, type AiModelInfo as s, type AiModelInstallEvent as t, type AiModelInstallHandle as u, type AiPreferences as v, type AiPreferencesPatch as w, type AiProgress as x, type AiProviderInfo as y, type AiResponseFormat as z };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  workspacePathDirname
3
- } from "./chunk-AYWKIZLD.js";
3
+ } from "./chunk-UTH3HYCZ.js";
4
4
 
5
5
  // src/filesystem/internal/parent-chain.ts
6
6
  function parentChain(path) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  tryParseWorkspacePath
3
- } from "./chunk-AYWKIZLD.js";
3
+ } from "./chunk-UTH3HYCZ.js";
4
4
 
5
5
  // src/mcp/types.ts
6
6
  var DOCBLOCKS_MCP_WIRE_VERSION = 1;
@@ -27,10 +27,12 @@ var NO_CAPABILITIES = Object.freeze({
27
27
  clipboard: false,
28
28
  exportDestinations: false,
29
29
  exportRememberedTargets: false,
30
+ openSavedExports: false,
30
31
  externalResources: false,
31
32
  openRequests: false,
32
33
  menuCommands: false,
33
34
  pinnedDocumentMirror: false,
35
+ trayIcon: false,
34
36
  guardedClose: false,
35
37
  git: false,
36
38
  updater: false,
@@ -103,10 +105,12 @@ function deriveHostCapabilities(host) {
103
105
  clipboard: hasMethod(host.clipboard, "writeText"),
104
106
  exportDestinations: hasMethod(exports, "save"),
105
107
  exportRememberedTargets: hasMethod(exports, "resolveTarget") && hasMethod(exports, "pickTarget"),
108
+ openSavedExports: hasMethod(exports, "openSaved"),
106
109
  externalResources: hasMethod(host.external, "readText"),
107
110
  openRequests: hasMethod(host, "onOpenRequest"),
108
111
  menuCommands: hasMethod(host, "onMenuCommand"),
109
112
  pinnedDocumentMirror: hasMethod(host.menu, "setPinnedDocuments"),
113
+ trayIcon: hasMethod(host.menu, "getTrayEnabled") && hasMethod(host.menu, "setTrayEnabled"),
110
114
  guardedClose: hasMethod(host.lifecycle, "onPrepareClose"),
111
115
  git: hasMethod(host.git, "status"),
112
116
  updater: hasMethod(host.updater, "checkForUpdates"),
@@ -141,6 +145,8 @@ var AI_WIRE_LIMITS = Object.freeze({
141
145
  completionCharacters: HOST_WIRE_LIMITS.documentCharacters,
142
146
  maxTokensCeiling: 32768,
143
147
  temperatureCeiling: 2,
148
+ /** A response schema describes a reply's shape; it is not another prompt. */
149
+ responseSchemaCharacters: 16 * 1024,
144
150
  verificationCodeCharacters: 16,
145
151
  progressPhaseCharacters: 64,
146
152
  modelEntries: 200,
@@ -363,9 +369,33 @@ function parseAiChatMessage(value) {
363
369
  if (!isBoundedString(value.content, AI_WIRE_LIMITS.promptCharacters)) return null;
364
370
  return { role: value.role, content: value.content };
365
371
  }
372
+ var RESPONSE_FORMAT_NAME = /^[A-Za-z0-9_-]{1,64}$/u;
373
+ function parseAiResponseFormat(value) {
374
+ if (!isRecord2(value)) return null;
375
+ if (!hasExactKeys(value, ["type", "name", "schema"])) return null;
376
+ if (value.type !== "json_schema") return null;
377
+ if (typeof value.name !== "string" || !RESPONSE_FORMAT_NAME.test(value.name)) return null;
378
+ if (!isRecord2(value.schema)) return null;
379
+ let serialized;
380
+ try {
381
+ serialized = JSON.stringify(value.schema);
382
+ } catch {
383
+ return null;
384
+ }
385
+ if (serialized.length > AI_WIRE_LIMITS.responseSchemaCharacters) return null;
386
+ return {
387
+ type: "json_schema",
388
+ name: value.name,
389
+ schema: JSON.parse(serialized)
390
+ };
391
+ }
366
392
  function parseAiChatRequest(value) {
367
393
  if (!isRecord2(value)) return null;
368
- if (!hasKeysWithin(value, ["messages", "purpose"], ["model", "temperature", "maxTokens"])) {
394
+ if (!hasKeysWithin(
395
+ value,
396
+ ["messages", "purpose"],
397
+ ["model", "temperature", "maxTokens", "responseFormat"]
398
+ )) {
369
399
  return null;
370
400
  }
371
401
  if (typeof value.purpose !== "string" || !CHAT_PURPOSES.has(value.purpose)) return null;
@@ -390,12 +420,15 @@ function parseAiChatRequest(value) {
390
420
  if (value.maxTokens !== void 0 && !isNonNegativeInteger(value.maxTokens, AI_WIRE_LIMITS.maxTokensCeiling)) {
391
421
  return null;
392
422
  }
423
+ const responseFormat = value.responseFormat === void 0 ? void 0 : parseAiResponseFormat(value.responseFormat);
424
+ if (responseFormat === null) return null;
393
425
  return {
394
426
  messages,
395
427
  purpose: value.purpose,
396
428
  ...value.model === void 0 ? {} : { model: value.model },
397
429
  ...value.temperature === void 0 ? {} : { temperature: value.temperature },
398
- ...value.maxTokens === void 0 ? {} : { maxTokens: value.maxTokens }
430
+ ...value.maxTokens === void 0 ? {} : { maxTokens: value.maxTokens },
431
+ ...responseFormat === void 0 ? {} : { responseFormat }
399
432
  };
400
433
  }
401
434
  function parseAiChatProgress(value) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseWorkspacePath
3
- } from "./chunk-AYWKIZLD.js";
3
+ } from "./chunk-UTH3HYCZ.js";
4
4
 
5
5
  // src/workspace-settings/settings.ts
6
6
  var WORKSPACE_SETTINGS_DIRECTORY = ".docblocks";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  FILE_SYSTEM_TRANSFER_LIMITS,
3
3
  maybeGetDocBlocksHost
4
- } from "./chunk-ZTSG7AC3.js";
4
+ } from "./chunk-64733GFL.js";
5
5
  import {
6
6
  parseFileSystemCapabilities
7
7
  } from "./chunk-245W57QP.js";
@@ -26,11 +26,12 @@ import {
26
26
  WORKSPACE_ROOT,
27
27
  deserializeFsError,
28
28
  fsErrorFromUnknown,
29
+ isFsErrorCode,
29
30
  isSerializedFsError,
30
31
  parseWorkspacePath,
31
32
  workspacePathBasename,
32
33
  workspacePathDirname
33
- } from "./chunk-AYWKIZLD.js";
34
+ } from "./chunk-UTH3HYCZ.js";
34
35
 
35
36
  // src/filesystem/host-provider-v2.ts
36
37
  var fallbackInstanceSequence = 0;
@@ -419,7 +420,13 @@ function normalizeEntry(entry) {
419
420
  if (!isNonNegativeSafeInteger(entry.size)) {
420
421
  throw new TypeError("Filesystem file size must be a non-negative safe integer.");
421
422
  }
422
- return Object.freeze({ ...common, kind: "file", size: entry.size });
423
+ const readIssue = normalizeReadIssue(entry.readIssue);
424
+ return Object.freeze({
425
+ ...common,
426
+ kind: "file",
427
+ size: entry.size,
428
+ ...readIssue ? { readIssue } : {}
429
+ });
423
430
  }
424
431
  if (entry.kind === "directory") {
425
432
  if (entry.size !== null) throw new TypeError("Filesystem directory size must be null.");
@@ -427,6 +434,13 @@ function normalizeEntry(entry) {
427
434
  }
428
435
  throw new TypeError("Unknown filesystem entry kind.");
429
436
  }
437
+ function normalizeReadIssue(value) {
438
+ if (value === void 0) return void 0;
439
+ if (!isRecord(value) || !isFsErrorCode(value.code) || !isBoundedString(value.message, HOST_WIRE_LIMITS.messageCharacters, 1)) {
440
+ throw new TypeError("Filesystem entry read issue is malformed.");
441
+ }
442
+ return Object.freeze({ code: value.code, message: value.message });
443
+ }
430
444
  function normalizeDirectoryListing(value, parent) {
431
445
  if (!Array.isArray(value)) throw new TypeError("Expected a filesystem directory listing.");
432
446
  const entries = value.map(normalizeEntry);
@@ -3,11 +3,11 @@ import {
3
3
  } from "./chunk-XAMILHQP.js";
4
4
  import {
5
5
  decodeUtf8Text
6
- } from "./chunk-M5ZNQGR5.js";
6
+ } from "./chunk-IYKGM3PV.js";
7
7
  import {
8
8
  FsError,
9
9
  parseWorkspacePath
10
- } from "./chunk-AYWKIZLD.js";
10
+ } from "./chunk-UTH3HYCZ.js";
11
11
 
12
12
  // src/filesystem/move-error.ts
13
13
  function locationFromPresence(source, destination) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  FsError
3
- } from "./chunk-AYWKIZLD.js";
3
+ } from "./chunk-UTH3HYCZ.js";
4
4
 
5
5
  // src/filesystem/utf8.ts
6
6
  function decodeUtf8Text(data, options = {}) {
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-DZB666V7.js";
4
4
  import {
5
5
  parentChain
6
- } from "./chunk-KQ6756AJ.js";
6
+ } from "./chunk-3GSMJ4MQ.js";
7
7
  import {
8
8
  bytesEqual,
9
9
  compareSnapshotsByName,
@@ -15,7 +15,7 @@ import {
15
15
  } from "./chunk-LPIJ6HKL.js";
16
16
  import {
17
17
  decodeUtf8Text
18
- } from "./chunk-M5ZNQGR5.js";
18
+ } from "./chunk-IYKGM3PV.js";
19
19
  import {
20
20
  FsError,
21
21
  WORKSPACE_ROOT,
@@ -25,7 +25,7 @@ import {
25
25
  workspacePathContains,
26
26
  workspacePathDirname,
27
27
  workspacePathJoin
28
- } from "./chunk-AYWKIZLD.js";
28
+ } from "./chunk-UTH3HYCZ.js";
29
29
 
30
30
  // src/filesystem/native-provider-v2.ts
31
31
  var NativeFileSystemMoveRecoveryError = class extends FsError {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parentChainWithRoot
3
- } from "./chunk-KQ6756AJ.js";
3
+ } from "./chunk-3GSMJ4MQ.js";
4
4
  import {
5
5
  compareSnapshotsByName,
6
6
  compareText,
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-LPIJ6HKL.js";
12
12
  import {
13
13
  decodeUtf8Text
14
- } from "./chunk-M5ZNQGR5.js";
14
+ } from "./chunk-IYKGM3PV.js";
15
15
  import {
16
16
  FsError,
17
17
  WORKSPACE_ROOT,
@@ -19,7 +19,7 @@ import {
19
19
  workspacePathBasename,
20
20
  workspacePathContains,
21
21
  workspacePathDirname
22
- } from "./chunk-AYWKIZLD.js";
22
+ } from "./chunk-UTH3HYCZ.js";
23
23
 
24
24
  // src/filesystem/memory-provider-v2.ts
25
25
  var MEMORY_CAPABILITIES = Object.freeze({
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  guessMimeType
3
- } from "./chunk-HKOOHM67.js";
3
+ } from "./chunk-Q3OFZWJS.js";
4
4
  import {
5
5
  bytesEqual,
6
6
  compareSnapshotsByName,
@@ -17,7 +17,7 @@ import {
17
17
  createFileSystemDocumentTarget,
18
18
  describeEntryMove,
19
19
  describePartialMove
20
- } from "./chunk-IGB2VSRE.js";
20
+ } from "./chunk-FIEMYP2N.js";
21
21
  import {
22
22
  getFileSystemProviderV2
23
23
  } from "./chunk-XAMILHQP.js";
@@ -31,7 +31,98 @@ import {
31
31
  workspacePathDirname,
32
32
  workspacePathJoin,
33
33
  workspacePathToLegacy
34
- } from "./chunk-AYWKIZLD.js";
34
+ } from "./chunk-UTH3HYCZ.js";
35
+
36
+ // src/filesystem/wiki-links.ts
37
+ var markdownModule = null;
38
+ function loadMarkdown() {
39
+ markdownModule ?? (markdownModule = import("@bendyline/squisq/markdown"));
40
+ return markdownModule;
41
+ }
42
+ async function suggestWikiArticles(files, directories, documentPath, query, extension = ".md", explicitExtensions = false) {
43
+ const { wikiLinkPath } = await loadMarkdown();
44
+ if (query.length > 2048 || query && !wikiLinkPath(`${query.trimEnd()}x`)) return [];
45
+ const source = parseWorkspacePath(documentPath);
46
+ const parent = workspacePathDirname(source);
47
+ const rootPrefix = parent ? `${parent}/` : "";
48
+ const slash = query.lastIndexOf("/");
49
+ const prefix = query.slice(0, slash + 1);
50
+ const needle = query.slice(slash + 1).toLowerCase();
51
+ const candidates = [];
52
+ const relative = (path) => {
53
+ if (!path.startsWith(rootPrefix)) return null;
54
+ const target = path.slice(rootPrefix.length);
55
+ if (!target.startsWith(prefix)) return null;
56
+ const name = target.slice(prefix.length);
57
+ return name && !name.includes("/") && name.toLowerCase().includes(needle) ? target : null;
58
+ };
59
+ for (const directory of directories) {
60
+ const target = relative(directory);
61
+ if (target && target.length < 2048 && wikiLinkPath(target))
62
+ candidates.push({
63
+ target: `${target}/`,
64
+ label: `${target.slice(prefix.length)}/`,
65
+ kind: "folder"
66
+ });
67
+ }
68
+ const articlePaths = new Set(files.map((file) => file.path));
69
+ for (const file of files) {
70
+ if (file.path === source || !/\.(?:md|html?)$/i.test(file.path)) continue;
71
+ const target = relative(file.path);
72
+ if (!target || !wikiLinkPath(target)) continue;
73
+ const stem = file.path.replace(/\.(?:md|html?)$/i, "");
74
+ const preferred = [`${stem}${extension}`, `${stem}.md`, `${stem}.html`, `${stem}.htm`].find(
75
+ (path) => articlePaths.has(path)
76
+ );
77
+ const insertion = !explicitExtensions && file.path === preferred ? target.replace(/\.(?:md|html?)$/i, "") : target;
78
+ candidates.push({ target: insertion, label: insertion.slice(prefix.length), kind: "article" });
79
+ }
80
+ return candidates.sort(
81
+ (a, b) => Number(b.kind === "folder") - Number(a.kind === "folder") || Number(b.label.toLowerCase().startsWith(needle)) - Number(a.label.toLowerCase().startsWith(needle)) || a.label.localeCompare(b.label) || a.target.localeCompare(b.target)
82
+ ).slice(0, 20);
83
+ }
84
+ async function resolveWikiArticlePath(documentPath, target, extension = ".md") {
85
+ const { wikiLinkPath } = await loadMarkdown();
86
+ const relative = wikiLinkPath(target, extension);
87
+ if (!relative) throw new FsError("invalid-path", "Invalid wiki article name.");
88
+ return workspacePathJoin(workspacePathDirname(parseWorkspacePath(documentPath)), relative);
89
+ }
90
+ async function findWikiArticle(provider, documentPath, target, extension = ".md") {
91
+ const { wikiLinkPath } = await loadMarkdown();
92
+ const preferred = await resolveWikiArticlePath(documentPath, target, extension);
93
+ const candidates = /\.(?:md|html?)$/i.test(target) ? [target] : [.../* @__PURE__ */ new Set([`${target}${extension}`, `${target}.md`, `${target}.html`, `${target}.htm`])];
94
+ for (const relativePath of candidates) {
95
+ const path = await resolveWikiArticlePath(documentPath, relativePath, extension);
96
+ if (await wikiArticleExists(provider, path)) return { path, relativePath, exists: true };
97
+ }
98
+ return { path: preferred, relativePath: wikiLinkPath(target, extension), exists: false };
99
+ }
100
+ async function wikiArticleExists(provider, path) {
101
+ const v2 = getFileSystemProviderV2(provider);
102
+ if (!v2) return await provider.stat(path) !== null;
103
+ const entry = await v2.stat(path);
104
+ if (entry && entry.kind !== "file")
105
+ throw new FsError("type-mismatch", "The article path is a folder.");
106
+ return entry !== null;
107
+ }
108
+ async function ensureWikiArticle(provider, path) {
109
+ if (await wikiArticleExists(provider, path)) return false;
110
+ const v2 = getFileSystemProviderV2(provider);
111
+ if (!v2) throw new FsError("not-supported", "This workspace cannot create articles safely.");
112
+ try {
113
+ await v2.writeFile(path, new Uint8Array(), {
114
+ mode: "create",
115
+ expectedVersion: null,
116
+ createParents: true
117
+ });
118
+ return true;
119
+ } catch (error) {
120
+ if (error instanceof FsError && (error.code === "already-exists" || error.code === "conflict")) {
121
+ if (await wikiArticleExists(provider, path)) return false;
122
+ }
123
+ throw error;
124
+ }
125
+ }
35
126
 
36
127
  // src/filesystem/legacy-v2-adapter.ts
37
128
  var EPOCH = (/* @__PURE__ */ new Date(0)).toISOString();
@@ -1104,6 +1195,11 @@ function createFileMediaProvider(container, markdownBasename) {
1104
1195
  }
1105
1196
 
1106
1197
  export {
1198
+ suggestWikiArticles,
1199
+ resolveWikiArticlePath,
1200
+ findWikiArticle,
1201
+ wikiArticleExists,
1202
+ ensureWikiArticle,
1107
1203
  LegacyFileSystemProviderV2Adapter,
1108
1204
  rewriteCompanionReferences,
1109
1205
  documentCompanionPath,
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  HostFileSystemProviderV2
3
- } from "./chunk-DFMRE22M.js";
3
+ } from "./chunk-EFGQUOTL.js";
4
4
  import {
5
5
  ELECTRON_FILE_SYSTEM_V2_CAPABILITIES,
6
6
  maybeGetDocBlocksHost
7
- } from "./chunk-ZTSG7AC3.js";
7
+ } from "./chunk-64733GFL.js";
8
8
 
9
9
  // src/filesystem/electron-provider-v2.ts
10
10
  var ElectronFileSystemProviderV2 = class extends HostFileSystemProviderV2 {
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-DZB666V7.js";
8
8
  import {
9
9
  parentChainWithRoot
10
- } from "./chunk-KQ6756AJ.js";
10
+ } from "./chunk-3GSMJ4MQ.js";
11
11
  import {
12
12
  isRecord
13
13
  } from "./chunk-73OOROXH.js";
@@ -22,7 +22,7 @@ import {
22
22
  } from "./chunk-LPIJ6HKL.js";
23
23
  import {
24
24
  decodeUtf8Text
25
- } from "./chunk-M5ZNQGR5.js";
25
+ } from "./chunk-IYKGM3PV.js";
26
26
  import {
27
27
  FsError,
28
28
  WORKSPACE_ROOT,
@@ -31,7 +31,7 @@ import {
31
31
  workspacePathBasename,
32
32
  workspacePathContains,
33
33
  workspacePathDirname
34
- } from "./chunk-AYWKIZLD.js";
34
+ } from "./chunk-UTH3HYCZ.js";
35
35
 
36
36
  // src/filesystem/indexeddb-provider-v2.ts
37
37
  var ENTRY_SCHEMA_VERSION = 1;
@@ -17,6 +17,9 @@ var FS_ERROR_CODES = /* @__PURE__ */ new Set([
17
17
  "aborted",
18
18
  "io"
19
19
  ]);
20
+ function isFsErrorCode(value) {
21
+ return typeof value === "string" && FS_ERROR_CODES.has(value);
22
+ }
20
23
  var FS_OPERATIONS = /* @__PURE__ */ new Set([
21
24
  "parse-path",
22
25
  "read",
@@ -109,7 +112,7 @@ function mapNodeErrorCodeToFsErrorCode(code) {
109
112
  function isSerializedFsError(value) {
110
113
  if (!value || typeof value !== "object") return false;
111
114
  const candidate = value;
112
- return candidate.name === "FsError" && typeof candidate.code === "string" && FS_ERROR_CODES.has(candidate.code) && typeof candidate.message === "string" && (candidate.operation === null || typeof candidate.operation === "string" && FS_OPERATIONS.has(candidate.operation)) && (candidate.path === null || typeof candidate.path === "string") && (candidate.destinationPath === null || typeof candidate.destinationPath === "string") && typeof candidate.retryable === "boolean";
115
+ return candidate.name === "FsError" && isFsErrorCode(candidate.code) && typeof candidate.message === "string" && (candidate.operation === null || typeof candidate.operation === "string" && FS_OPERATIONS.has(candidate.operation)) && (candidate.path === null || typeof candidate.path === "string") && (candidate.destinationPath === null || typeof candidate.destinationPath === "string") && typeof candidate.retryable === "boolean";
113
116
  }
114
117
  function deserializeFsError(value) {
115
118
  return new FsError(value.code, value.message, {
@@ -205,6 +208,7 @@ function invalidPath(path, message) {
205
208
  }
206
209
 
207
210
  export {
211
+ isFsErrorCode,
208
212
  FsError,
209
213
  mapDomExceptionToFsErrorCode,
210
214
  mapNodeErrorCodeToFsErrorCode,