@milkdown/crepe 7.20.0 → 7.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/builder.js +1 -0
- package/lib/cjs/builder.js.map +1 -1
- package/lib/cjs/feature/ai/index.js +1492 -0
- package/lib/cjs/feature/ai/index.js.map +1 -0
- package/lib/cjs/feature/block-edit/index.js +1 -0
- package/lib/cjs/feature/block-edit/index.js.map +1 -1
- package/lib/cjs/feature/code-mirror/index.js +1 -0
- package/lib/cjs/feature/code-mirror/index.js.map +1 -1
- package/lib/cjs/feature/cursor/index.js +1 -0
- package/lib/cjs/feature/cursor/index.js.map +1 -1
- package/lib/cjs/feature/image-block/index.js +1 -0
- package/lib/cjs/feature/image-block/index.js.map +1 -1
- package/lib/cjs/feature/latex/index.js +2 -0
- package/lib/cjs/feature/latex/index.js.map +1 -1
- package/lib/cjs/feature/link-tooltip/index.js +1 -0
- package/lib/cjs/feature/link-tooltip/index.js.map +1 -1
- package/lib/cjs/feature/list-item/index.js +1 -0
- package/lib/cjs/feature/list-item/index.js.map +1 -1
- package/lib/cjs/feature/placeholder/index.js +1 -0
- package/lib/cjs/feature/placeholder/index.js.map +1 -1
- package/lib/cjs/feature/table/index.js +1 -0
- package/lib/cjs/feature/table/index.js.map +1 -1
- package/lib/cjs/feature/toolbar/index.js +488 -3
- package/lib/cjs/feature/toolbar/index.js.map +1 -1
- package/lib/cjs/feature/top-bar/index.js +1 -0
- package/lib/cjs/feature/top-bar/index.js.map +1 -1
- package/lib/cjs/index.js +1424 -25
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/llm-providers/anthropic/index.js +147 -0
- package/lib/cjs/llm-providers/anthropic/index.js.map +1 -0
- package/lib/cjs/llm-providers/openai/index.js +138 -0
- package/lib/cjs/llm-providers/openai/index.js.map +1 -0
- package/lib/esm/builder.js +1 -0
- package/lib/esm/builder.js.map +1 -1
- package/lib/esm/feature/ai/index.js +1487 -0
- package/lib/esm/feature/ai/index.js.map +1 -0
- package/lib/esm/feature/block-edit/index.js +1 -0
- package/lib/esm/feature/block-edit/index.js.map +1 -1
- package/lib/esm/feature/code-mirror/index.js +1 -0
- package/lib/esm/feature/code-mirror/index.js.map +1 -1
- package/lib/esm/feature/cursor/index.js +1 -0
- package/lib/esm/feature/cursor/index.js.map +1 -1
- package/lib/esm/feature/image-block/index.js +1 -0
- package/lib/esm/feature/image-block/index.js.map +1 -1
- package/lib/esm/feature/latex/index.js +2 -0
- package/lib/esm/feature/latex/index.js.map +1 -1
- package/lib/esm/feature/link-tooltip/index.js +1 -0
- package/lib/esm/feature/link-tooltip/index.js.map +1 -1
- package/lib/esm/feature/list-item/index.js +1 -0
- package/lib/esm/feature/list-item/index.js.map +1 -1
- package/lib/esm/feature/placeholder/index.js +1 -0
- package/lib/esm/feature/placeholder/index.js.map +1 -1
- package/lib/esm/feature/table/index.js +1 -0
- package/lib/esm/feature/table/index.js.map +1 -1
- package/lib/esm/feature/toolbar/index.js +490 -5
- package/lib/esm/feature/toolbar/index.js.map +1 -1
- package/lib/esm/feature/top-bar/index.js +1 -0
- package/lib/esm/feature/top-bar/index.js.map +1 -1
- package/lib/esm/index.js +1414 -15
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/llm-providers/anthropic/index.js +145 -0
- package/lib/esm/llm-providers/anthropic/index.js.map +1 -0
- package/lib/esm/llm-providers/openai/index.js +136 -0
- package/lib/esm/llm-providers/openai/index.js.map +1 -0
- package/lib/theme/common/ai.css +446 -0
- package/lib/theme/common/code-mirror.css +14 -0
- package/lib/theme/common/diff.css +177 -0
- package/lib/theme/common/style.css +2 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/feature/ai/ai.spec.d.ts +2 -0
- package/lib/types/feature/ai/ai.spec.d.ts.map +1 -0
- package/lib/types/feature/ai/commands.d.ts +24 -0
- package/lib/types/feature/ai/commands.d.ts.map +1 -0
- package/lib/types/feature/ai/context.d.ts +4 -0
- package/lib/types/feature/ai/context.d.ts.map +1 -0
- package/lib/types/feature/ai/diff-actions/index.d.ts +12 -0
- package/lib/types/feature/ai/diff-actions/index.d.ts.map +1 -0
- package/lib/types/feature/ai/diff-actions/view.d.ts +21 -0
- package/lib/types/feature/ai/diff-actions/view.d.ts.map +1 -0
- package/lib/types/feature/ai/index.d.ts +7 -0
- package/lib/types/feature/ai/index.d.ts.map +1 -0
- package/lib/types/feature/ai/instruction-tooltip/component.d.ts +26 -0
- package/lib/types/feature/ai/instruction-tooltip/component.d.ts.map +1 -0
- package/lib/types/feature/ai/instruction-tooltip/index.d.ts +17 -0
- package/lib/types/feature/ai/instruction-tooltip/index.d.ts.map +1 -0
- package/lib/types/feature/ai/instruction-tooltip/suggestions.d.ts +50 -0
- package/lib/types/feature/ai/instruction-tooltip/suggestions.d.ts.map +1 -0
- package/lib/types/feature/ai/instruction-tooltip/view.d.ts +19 -0
- package/lib/types/feature/ai/instruction-tooltip/view.d.ts.map +1 -0
- package/lib/types/feature/ai/streaming-indicator.d.ts +9 -0
- package/lib/types/feature/ai/streaming-indicator.d.ts.map +1 -0
- package/lib/types/feature/ai/types.d.ts +58 -0
- package/lib/types/feature/ai/types.d.ts.map +1 -0
- package/lib/types/feature/index.d.ts +4 -1
- package/lib/types/feature/index.d.ts.map +1 -1
- package/lib/types/feature/latex/inline-tooltip/inline-tooltip.spec.d.ts +2 -0
- package/lib/types/feature/latex/inline-tooltip/inline-tooltip.spec.d.ts.map +1 -0
- package/lib/types/feature/latex/inline-tooltip/view.d.ts.map +1 -1
- package/lib/types/feature/loader.d.ts.map +1 -1
- package/lib/types/feature/toolbar/config.d.ts.map +1 -1
- package/lib/types/feature/toolbar/index.d.ts +1 -0
- package/lib/types/feature/toolbar/index.d.ts.map +1 -1
- package/lib/types/icons/ai.d.ts +2 -0
- package/lib/types/icons/ai.d.ts.map +1 -0
- package/lib/types/icons/chevron-left.d.ts +2 -0
- package/lib/types/icons/chevron-left.d.ts.map +1 -0
- package/lib/types/icons/chevron-right.d.ts +2 -0
- package/lib/types/icons/chevron-right.d.ts.map +1 -0
- package/lib/types/icons/enter-key.d.ts +2 -0
- package/lib/types/icons/enter-key.d.ts.map +1 -0
- package/lib/types/icons/grammar-check.d.ts +2 -0
- package/lib/types/icons/grammar-check.d.ts.map +1 -0
- package/lib/types/icons/index.d.ts +11 -0
- package/lib/types/icons/index.d.ts.map +1 -1
- package/lib/types/icons/longer.d.ts +2 -0
- package/lib/types/icons/longer.d.ts.map +1 -0
- package/lib/types/icons/retry.d.ts +2 -0
- package/lib/types/icons/retry.d.ts.map +1 -0
- package/lib/types/icons/send-prompt.d.ts +2 -0
- package/lib/types/icons/send-prompt.d.ts.map +1 -0
- package/lib/types/icons/send.d.ts +2 -0
- package/lib/types/icons/send.d.ts.map +1 -0
- package/lib/types/icons/shorter.d.ts +2 -0
- package/lib/types/icons/shorter.d.ts.map +1 -0
- package/lib/types/icons/translate.d.ts +2 -0
- package/lib/types/icons/translate.d.ts.map +1 -0
- package/lib/types/llm-providers/anthropic/index.d.ts +21 -0
- package/lib/types/llm-providers/anthropic/index.d.ts.map +1 -0
- package/lib/types/llm-providers/openai/index.d.ts +15 -0
- package/lib/types/llm-providers/openai/index.d.ts.map +1 -0
- package/lib/types/llm-providers/providers.spec.d.ts +2 -0
- package/lib/types/llm-providers/providers.spec.d.ts.map +1 -0
- package/lib/types/llm-providers/shared.d.ts +16 -0
- package/lib/types/llm-providers/shared.d.ts.map +1 -0
- package/package.json +18 -2
- package/src/feature/ai/ai.spec.ts +742 -0
- package/src/feature/ai/commands.ts +257 -0
- package/src/feature/ai/context.ts +45 -0
- package/src/feature/ai/diff-actions/index.ts +95 -0
- package/src/feature/ai/diff-actions/view.ts +237 -0
- package/src/feature/ai/index.ts +118 -0
- package/src/feature/ai/instruction-tooltip/component.tsx +414 -0
- package/src/feature/ai/instruction-tooltip/index.ts +101 -0
- package/src/feature/ai/instruction-tooltip/suggestions.ts +249 -0
- package/src/feature/ai/instruction-tooltip/view.ts +159 -0
- package/src/feature/ai/streaming-indicator.ts +183 -0
- package/src/feature/ai/types.ts +178 -0
- package/src/feature/index.ts +8 -2
- package/src/feature/latex/inline-tooltip/inline-tooltip.spec.ts +81 -0
- package/src/feature/latex/inline-tooltip/view.ts +2 -0
- package/src/feature/loader.ts +4 -0
- package/src/feature/toolbar/config.ts +27 -1
- package/src/feature/toolbar/index.ts +1 -0
- package/src/icons/ai.ts +14 -0
- package/src/icons/chevron-left.ts +15 -0
- package/src/icons/chevron-right.ts +15 -0
- package/src/icons/enter-key.ts +13 -0
- package/src/icons/grammar-check.ts +13 -0
- package/src/icons/index.ts +11 -0
- package/src/icons/longer.ts +13 -0
- package/src/icons/retry.ts +13 -0
- package/src/icons/send-prompt.ts +13 -0
- package/src/icons/send.ts +13 -0
- package/src/icons/shorter.ts +13 -0
- package/src/icons/translate.ts +13 -0
- package/src/llm-providers/anthropic/index.ts +132 -0
- package/src/llm-providers/openai/index.ts +109 -0
- package/src/llm-providers/providers.spec.ts +472 -0
- package/src/llm-providers/shared.ts +160 -0
- package/src/theme/common/ai.css +430 -0
- package/src/theme/common/code-mirror.css +14 -0
- package/src/theme/common/diff.css +196 -0
- package/src/theme/common/style.css +2 -0
package/lib/esm/index.js
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
import { defaultsDeep } from 'lodash-es';
|
|
2
2
|
import { languages } from '@codemirror/language-data';
|
|
3
3
|
import { oneDark } from '@codemirror/theme-one-dark';
|
|
4
|
-
import {
|
|
4
|
+
import { diffComponentConfig, diffComponent } from '@milkdown/kit/component/diff';
|
|
5
|
+
import { diffPluginKey, clearDiffReviewCmd, acceptAllDiffsCmd, diffConfig, diff } from '@milkdown/kit/plugin/diff';
|
|
6
|
+
import { streamingPluginKey, startStreamingCmd, abortStreamingCmd, pushChunkCmd, endStreamingCmd, streamingConfig, streaming } from '@milkdown/kit/plugin/streaming';
|
|
5
7
|
import { createSlice } from '@milkdown/kit/ctx';
|
|
6
|
-
import {
|
|
8
|
+
import { editorViewCtx, serializerCtx, commandsCtx, editorCtx, EditorStatus, Editor, rootCtx, defaultValueCtx, editorViewOptionsCtx } from '@milkdown/kit/core';
|
|
9
|
+
import { aiBuildContextError, aiProviderError } from '@milkdown/kit/exception';
|
|
10
|
+
import { $ctx, $command, $prose, $nodeSchema, $inputRule, $remark, getMarkdown } from '@milkdown/kit/utils';
|
|
11
|
+
import { TextSelection, PluginKey, Plugin, NodeSelection, EditorState } from '@milkdown/kit/prose/state';
|
|
12
|
+
import DOMPurify from 'dompurify';
|
|
13
|
+
import { TooltipProvider, tooltipFactory } from '@milkdown/kit/plugin/tooltip';
|
|
14
|
+
import { posToDOMRect, findParent, findNodeInSelection, nodeRule } from '@milkdown/kit/prose';
|
|
15
|
+
import { defineComponent, ref, watch, computed, h, nextTick, createApp, watchEffect, onUnmounted, Fragment, shallowRef, onMounted } from 'vue';
|
|
16
|
+
import { Icon } from '@milkdown/kit/component';
|
|
17
|
+
import { DecorationSet, Decoration, EditorView } from '@milkdown/kit/prose/view';
|
|
18
|
+
import { blockConfig, block, BlockProvider } from '@milkdown/kit/plugin/block';
|
|
7
19
|
import { paragraphSchema, clearTextInCurrentBlockCommand, setBlockTypeCommand, headingSchema, blockquoteSchema, wrapInBlockTypeCommand, hrSchema, addBlockTypeCommand, bulletListSchema, orderedListSchema, listItemSchema, codeBlockSchema, selectTextNearPosCommand, toggleStrongCommand, isMarkSelectedCommand, strongSchema, toggleEmphasisCommand, emphasisSchema, toggleInlineCodeCommand, inlineCodeSchema, isNodeSelectedCommand, linkSchema, commonmark } from '@milkdown/kit/preset/commonmark';
|
|
8
|
-
import { findParent, findNodeInSelection, nodeRule } from '@milkdown/kit/prose';
|
|
9
|
-
import { TextSelection, NodeSelection, EditorState, Plugin, PluginKey } from '@milkdown/kit/prose/state';
|
|
10
|
-
import { defineComponent, ref, computed, watch, watchEffect, onUnmounted, h, createApp, Fragment, shallowRef, onMounted } from 'vue';
|
|
11
20
|
import { slashFactory, SlashProvider } from '@milkdown/kit/plugin/slash';
|
|
12
|
-
import { $ctx, $prose, $nodeSchema, $command, $inputRule, $remark, getMarkdown } from '@milkdown/kit/utils';
|
|
13
|
-
import { Icon } from '@milkdown/kit/component';
|
|
14
21
|
import { imageBlockSchema, imageBlockConfig, imageBlockComponent } from '@milkdown/kit/component/image-block';
|
|
15
22
|
import { createTable, toggleStrikethroughCommand, strikethroughSchema, gfm } from '@milkdown/kit/preset/gfm';
|
|
16
23
|
import { defaultKeymap, indentWithTab } from '@codemirror/commands';
|
|
@@ -21,11 +28,9 @@ import { dropIndicatorConfig, cursor as cursor$1 } from '@milkdown/kit/plugin/cu
|
|
|
21
28
|
import { createVirtualCursor } from 'prosemirror-virtual-cursor';
|
|
22
29
|
import { inlineImageConfig, imageInlineComponent } from '@milkdown/kit/component/image-inline';
|
|
23
30
|
import katex from 'katex';
|
|
24
|
-
import { tooltipFactory, TooltipProvider } from '@milkdown/kit/plugin/tooltip';
|
|
25
31
|
import { redo, undo } from '@milkdown/kit/prose/history';
|
|
26
32
|
import { keymap as keymap$1 } from '@milkdown/kit/prose/keymap';
|
|
27
33
|
import { Schema } from '@milkdown/kit/prose/model';
|
|
28
|
-
import { EditorView, DecorationSet, Decoration } from '@milkdown/kit/prose/view';
|
|
29
34
|
import { textblockTypeInputRule } from '@milkdown/kit/prose/inputrules';
|
|
30
35
|
import remarkMath from 'remark-math';
|
|
31
36
|
import { visit } from 'unist-util-visit';
|
|
@@ -52,6 +57,7 @@ var CrepeFeature = /* @__PURE__ */ ((CrepeFeature2) => {
|
|
|
52
57
|
CrepeFeature2["Table"] = "table";
|
|
53
58
|
CrepeFeature2["Latex"] = "latex";
|
|
54
59
|
CrepeFeature2["TopBar"] = "top-bar";
|
|
60
|
+
CrepeFeature2["AI"] = "ai";
|
|
55
61
|
return CrepeFeature2;
|
|
56
62
|
})(CrepeFeature || {});
|
|
57
63
|
const defaultFeatures = {
|
|
@@ -65,9 +71,25 @@ const defaultFeatures = {
|
|
|
65
71
|
["code-mirror" /* CodeMirror */]: true,
|
|
66
72
|
["table" /* Table */]: true,
|
|
67
73
|
["latex" /* Latex */]: true,
|
|
68
|
-
["top-bar" /* TopBar */]: false
|
|
74
|
+
["top-bar" /* TopBar */]: false,
|
|
75
|
+
["ai" /* AI */]: false
|
|
69
76
|
};
|
|
70
77
|
|
|
78
|
+
const aiIcon = `
|
|
79
|
+
<svg
|
|
80
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
81
|
+
width="24"
|
|
82
|
+
height="24"
|
|
83
|
+
viewBox="0 0 24 24"
|
|
84
|
+
>
|
|
85
|
+
<path
|
|
86
|
+
fill="currentColor"
|
|
87
|
+
d="M19 9l1.25-2.75L23 5l-2.75-1.25L19 1l-1.25 2.75L15 5l2.75 1.25zm0 14l1.25-2.75L23 19l-2.75-1.25L19 15l-1.25 2.75L15 19l2.75 1.25zM9 20l3-6.5L18 10l-6-3.5L9 0L6 6.5L0 10l6 3.5z"
|
|
88
|
+
transform="translate(3 3) scale(0.75)"
|
|
89
|
+
/>
|
|
90
|
+
</svg>
|
|
91
|
+
`;
|
|
92
|
+
|
|
71
93
|
const alignCenterIcon = `
|
|
72
94
|
<svg
|
|
73
95
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -229,6 +251,38 @@ const chevronDownIcon = `
|
|
|
229
251
|
</svg>
|
|
230
252
|
`;
|
|
231
253
|
|
|
254
|
+
const chevronLeftIcon = `
|
|
255
|
+
<svg
|
|
256
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
257
|
+
fill="none"
|
|
258
|
+
viewBox="0 0 24 24"
|
|
259
|
+
stroke-width="1.5"
|
|
260
|
+
stroke="currentColor"
|
|
261
|
+
>
|
|
262
|
+
<path
|
|
263
|
+
stroke-linecap="round"
|
|
264
|
+
stroke-linejoin="round"
|
|
265
|
+
d="M15.75 19.5L8.25 12l7.5-7.5"
|
|
266
|
+
/>
|
|
267
|
+
</svg>
|
|
268
|
+
`;
|
|
269
|
+
|
|
270
|
+
const chevronRightIcon = `
|
|
271
|
+
<svg
|
|
272
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
273
|
+
fill="none"
|
|
274
|
+
viewBox="0 0 24 24"
|
|
275
|
+
stroke-width="1.5"
|
|
276
|
+
stroke="currentColor"
|
|
277
|
+
>
|
|
278
|
+
<path
|
|
279
|
+
stroke-linecap="round"
|
|
280
|
+
stroke-linejoin="round"
|
|
281
|
+
d="M8.25 4.5l7.5 7.5-7.5 7.5"
|
|
282
|
+
/>
|
|
283
|
+
</svg>
|
|
284
|
+
`;
|
|
285
|
+
|
|
232
286
|
const clearIcon = `
|
|
233
287
|
<svg
|
|
234
288
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -373,6 +427,34 @@ const editIcon = `
|
|
|
373
427
|
</svg>
|
|
374
428
|
`;
|
|
375
429
|
|
|
430
|
+
const enterKeyIcon = `
|
|
431
|
+
<svg
|
|
432
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
433
|
+
width="24"
|
|
434
|
+
height="24"
|
|
435
|
+
viewBox="0 0 24 24"
|
|
436
|
+
>
|
|
437
|
+
<path
|
|
438
|
+
fill="currentColor"
|
|
439
|
+
d="M9 16l-5-5l5-5l1.4 1.4L7.825 10H18V6h2v6H7.825l2.575 2.6z"
|
|
440
|
+
/>
|
|
441
|
+
</svg>
|
|
442
|
+
`;
|
|
443
|
+
|
|
444
|
+
const grammarCheckIcon = `
|
|
445
|
+
<svg
|
|
446
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
447
|
+
width="24"
|
|
448
|
+
height="24"
|
|
449
|
+
viewBox="0 0 24 24"
|
|
450
|
+
>
|
|
451
|
+
<path
|
|
452
|
+
fill="currentColor"
|
|
453
|
+
d="M9.55 17.575L4.225 12.25l1.4-1.425L9.55 14.75l8.825-8.825l1.4 1.425z"
|
|
454
|
+
/>
|
|
455
|
+
</svg>
|
|
456
|
+
`;
|
|
457
|
+
|
|
376
458
|
const h1Icon = `
|
|
377
459
|
<svg
|
|
378
460
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -539,6 +621,20 @@ const linkIcon = `
|
|
|
539
621
|
</svg>
|
|
540
622
|
`;
|
|
541
623
|
|
|
624
|
+
const longerIcon = `
|
|
625
|
+
<svg
|
|
626
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
627
|
+
width="24"
|
|
628
|
+
height="24"
|
|
629
|
+
viewBox="0 0 24 24"
|
|
630
|
+
>
|
|
631
|
+
<path
|
|
632
|
+
fill="currentColor"
|
|
633
|
+
d="M3 18v-2h13v2zm0-5v-2h18v2zm0-5V6h18v2zm15 13v-3h-3v-2h3v-3h2v3h3v2h-3v3z"
|
|
634
|
+
/>
|
|
635
|
+
</svg>
|
|
636
|
+
`;
|
|
637
|
+
|
|
542
638
|
const menuIcon = `
|
|
543
639
|
<svg
|
|
544
640
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -632,6 +728,20 @@ const removeIcon = `
|
|
|
632
728
|
</svg>
|
|
633
729
|
`;
|
|
634
730
|
|
|
731
|
+
const retryIcon = `
|
|
732
|
+
<svg
|
|
733
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
734
|
+
width="24"
|
|
735
|
+
height="24"
|
|
736
|
+
viewBox="0 0 24 24"
|
|
737
|
+
>
|
|
738
|
+
<path
|
|
739
|
+
fill="currentColor"
|
|
740
|
+
d="M12 20q-3.35 0-5.675-2.325T4 12q0-3.35 2.325-5.675T12 4q1.725 0 3.3.713T18 6.75V4h2v7h-7V9h4.2q-.8-1.4-2.187-2.2T12 6Q9.5 6 7.75 7.75T6 12q0 2.5 1.75 4.25T12 18q1.925 0 3.475-1.1T17.65 14h2.1q-.7 2.65-2.85 4.325T12 20"
|
|
741
|
+
/>
|
|
742
|
+
</svg>
|
|
743
|
+
`;
|
|
744
|
+
|
|
635
745
|
const searchIcon = `
|
|
636
746
|
<svg
|
|
637
747
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -649,6 +759,48 @@ const searchIcon = `
|
|
|
649
759
|
</svg>
|
|
650
760
|
`;
|
|
651
761
|
|
|
762
|
+
const sendIcon = `
|
|
763
|
+
<svg
|
|
764
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
765
|
+
width="24"
|
|
766
|
+
height="24"
|
|
767
|
+
viewBox="0 0 24 24"
|
|
768
|
+
>
|
|
769
|
+
<path
|
|
770
|
+
fill="currentColor"
|
|
771
|
+
d="M11 20V7.825l-5.6 5.6L4 12l8-8l8 8l-1.4 1.425l-5.6-5.6V20z"
|
|
772
|
+
/>
|
|
773
|
+
</svg>
|
|
774
|
+
`;
|
|
775
|
+
|
|
776
|
+
const sendPromptIcon = `
|
|
777
|
+
<svg
|
|
778
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
779
|
+
width="24"
|
|
780
|
+
height="24"
|
|
781
|
+
viewBox="0 0 24 24"
|
|
782
|
+
>
|
|
783
|
+
<path
|
|
784
|
+
fill="currentColor"
|
|
785
|
+
d="M3 20v-6l8-2l-8-2V4l19 8z"
|
|
786
|
+
/>
|
|
787
|
+
</svg>
|
|
788
|
+
`;
|
|
789
|
+
|
|
790
|
+
const shorterIcon = `
|
|
791
|
+
<svg
|
|
792
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
793
|
+
width="24"
|
|
794
|
+
height="24"
|
|
795
|
+
viewBox="0 0 24 24"
|
|
796
|
+
>
|
|
797
|
+
<path
|
|
798
|
+
fill="currentColor"
|
|
799
|
+
d="M5 13v-2h14v2z"
|
|
800
|
+
/>
|
|
801
|
+
</svg>
|
|
802
|
+
`;
|
|
803
|
+
|
|
652
804
|
const strikethroughIcon = `
|
|
653
805
|
<svg
|
|
654
806
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -715,6 +867,20 @@ const todoListIcon = `
|
|
|
715
867
|
</svg>
|
|
716
868
|
`;
|
|
717
869
|
|
|
870
|
+
const translateIcon = `
|
|
871
|
+
<svg
|
|
872
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
873
|
+
width="24"
|
|
874
|
+
height="24"
|
|
875
|
+
viewBox="0 0 24 24"
|
|
876
|
+
>
|
|
877
|
+
<path
|
|
878
|
+
fill="currentColor"
|
|
879
|
+
d="m12.9 16l-2.55-2.5l.05-.05q1.45-1.6 2.262-3.117T13.95 7H16V5h-6V3H8v2H2v2h9.1q-.5 1.2-1.225 2.387T8 11.7q-.6-.6-1.187-1.412T5.85 8.6H3.85q.5 1.4 1.3 2.7T6.95 13.7L2.85 17.75L4.25 19.15L8 15.4L10.55 17.95zM18.5 22h-2L21 10h2l4.5 12h-2l-1.05-3h-4.9zm1.6-5h3.6l-1.8-5.1z"
|
|
880
|
+
/>
|
|
881
|
+
</svg>
|
|
882
|
+
`;
|
|
883
|
+
|
|
718
884
|
const functionsIcon = `
|
|
719
885
|
<svg
|
|
720
886
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -774,6 +940,1223 @@ function crepeFeatureConfig(feature) {
|
|
|
774
940
|
};
|
|
775
941
|
}
|
|
776
942
|
|
|
943
|
+
function defaultBuildContext(ctx, instruction) {
|
|
944
|
+
var _a;
|
|
945
|
+
const view = ctx.get(editorViewCtx);
|
|
946
|
+
const serializer = ctx.get(serializerCtx);
|
|
947
|
+
const { state } = view;
|
|
948
|
+
const document = serializer(state.doc);
|
|
949
|
+
let selection = "";
|
|
950
|
+
if (!state.selection.empty) {
|
|
951
|
+
const { from, to } = state.selection;
|
|
952
|
+
const slice = state.doc.slice(from, to);
|
|
953
|
+
const { schema } = state.doc.type;
|
|
954
|
+
let wrapper = schema.topNodeType.createAndFill(null, slice.content);
|
|
955
|
+
if (!wrapper) {
|
|
956
|
+
const paragraph = (_a = schema.nodes.paragraph) == null ? void 0 : _a.createAndFill(
|
|
957
|
+
null,
|
|
958
|
+
slice.content
|
|
959
|
+
);
|
|
960
|
+
if (paragraph) wrapper = schema.topNodeType.createAndFill(null, paragraph);
|
|
961
|
+
}
|
|
962
|
+
selection = wrapper ? serializer(wrapper) : state.doc.textBetween(from, to);
|
|
963
|
+
}
|
|
964
|
+
return { document, selection, instruction };
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
const aiProviderConfig = $ctx(
|
|
968
|
+
{
|
|
969
|
+
provider: void 0,
|
|
970
|
+
buildContext: void 0,
|
|
971
|
+
diffReviewOnEnd: true,
|
|
972
|
+
onError: (error) => {
|
|
973
|
+
console.error(`[milkdown/ai] [${error.code}]`, error);
|
|
974
|
+
},
|
|
975
|
+
aiIcon: void 0
|
|
976
|
+
},
|
|
977
|
+
"aiProviderConfig"
|
|
978
|
+
);
|
|
979
|
+
const aiSessionCtx = $ctx(
|
|
980
|
+
{
|
|
981
|
+
abortController: null,
|
|
982
|
+
label: "",
|
|
983
|
+
lastInstruction: "",
|
|
984
|
+
lastLabel: void 0,
|
|
985
|
+
lastFrom: -1,
|
|
986
|
+
lastTo: -1,
|
|
987
|
+
diffOwnedByAI: false
|
|
988
|
+
},
|
|
989
|
+
"aiSession"
|
|
990
|
+
);
|
|
991
|
+
function emitAIError(ctx, error) {
|
|
992
|
+
const config = ctx.get(aiProviderConfig.key);
|
|
993
|
+
try {
|
|
994
|
+
config.onError(error);
|
|
995
|
+
} catch (handlerError) {
|
|
996
|
+
console.error("[milkdown/ai] onError handler failed:", handlerError);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
function clearActiveSession(ctx) {
|
|
1000
|
+
const current = ctx.get(aiSessionCtx.key);
|
|
1001
|
+
ctx.set(aiSessionCtx.key, {
|
|
1002
|
+
...current,
|
|
1003
|
+
abortController: null,
|
|
1004
|
+
label: ""
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
1007
|
+
async function runProvider(ctx, provider, promptContext, abortController) {
|
|
1008
|
+
try {
|
|
1009
|
+
const iterable = provider(promptContext, abortController.signal);
|
|
1010
|
+
const commands = ctx.get(commandsCtx);
|
|
1011
|
+
for await (const chunk of iterable) {
|
|
1012
|
+
if (abortController.signal.aborted) break;
|
|
1013
|
+
commands.call(pushChunkCmd.key, chunk);
|
|
1014
|
+
}
|
|
1015
|
+
if (abortController.signal.aborted) return;
|
|
1016
|
+
const config = ctx.get(aiProviderConfig.key);
|
|
1017
|
+
if (config.diffReviewOnEnd) {
|
|
1018
|
+
const cur = ctx.get(aiSessionCtx.key);
|
|
1019
|
+
ctx.set(aiSessionCtx.key, { ...cur, diffOwnedByAI: true });
|
|
1020
|
+
}
|
|
1021
|
+
const dispatched = commands.call(endStreamingCmd.key, {
|
|
1022
|
+
diffReview: config.diffReviewOnEnd
|
|
1023
|
+
});
|
|
1024
|
+
if (config.diffReviewOnEnd && !dispatched) {
|
|
1025
|
+
const cur = ctx.get(aiSessionCtx.key);
|
|
1026
|
+
ctx.set(aiSessionCtx.key, { ...cur, diffOwnedByAI: false });
|
|
1027
|
+
}
|
|
1028
|
+
} catch (error) {
|
|
1029
|
+
if (abortController.signal.aborted) return;
|
|
1030
|
+
const milkdownError = aiProviderError(error);
|
|
1031
|
+
emitAIError(ctx, milkdownError);
|
|
1032
|
+
const commands = ctx.get(commandsCtx);
|
|
1033
|
+
commands.call(abortStreamingCmd.key, { keep: false });
|
|
1034
|
+
} finally {
|
|
1035
|
+
const current = ctx.get(aiSessionCtx.key);
|
|
1036
|
+
if (current.abortController === abortController) {
|
|
1037
|
+
clearActiveSession(ctx);
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
const runAICmd = $command("RunAI", (ctx) => {
|
|
1042
|
+
return (options) => (state, dispatch) => {
|
|
1043
|
+
var _a, _b, _c, _d;
|
|
1044
|
+
if (!(options == null ? void 0 : options.instruction)) return false;
|
|
1045
|
+
const config = ctx.get(aiProviderConfig.key);
|
|
1046
|
+
if (!config.provider) return false;
|
|
1047
|
+
const session = ctx.get(aiSessionCtx.key);
|
|
1048
|
+
if (session.abortController) return false;
|
|
1049
|
+
if ((_a = streamingPluginKey.getState(state)) == null ? void 0 : _a.active) return false;
|
|
1050
|
+
if ((_b = diffPluginKey.getState(state)) == null ? void 0 : _b.active) return false;
|
|
1051
|
+
if (!dispatch) return true;
|
|
1052
|
+
const abortController = new AbortController();
|
|
1053
|
+
const { from, to } = state.selection;
|
|
1054
|
+
ctx.set(aiSessionCtx.key, {
|
|
1055
|
+
abortController,
|
|
1056
|
+
label: (_c = options.label) != null ? _c : "",
|
|
1057
|
+
lastInstruction: options.instruction,
|
|
1058
|
+
lastLabel: options.label,
|
|
1059
|
+
lastFrom: from,
|
|
1060
|
+
lastTo: to,
|
|
1061
|
+
// Reset every run; only the success path that hands off to diff
|
|
1062
|
+
// review flips it back on.
|
|
1063
|
+
diffOwnedByAI: false
|
|
1064
|
+
});
|
|
1065
|
+
const commands = ctx.get(commandsCtx);
|
|
1066
|
+
const insertAt = state.selection.empty ? "cursor" : "selection";
|
|
1067
|
+
if (!commands.call(startStreamingCmd.key, { insertAt })) {
|
|
1068
|
+
clearActiveSession(ctx);
|
|
1069
|
+
return false;
|
|
1070
|
+
}
|
|
1071
|
+
let promptContext;
|
|
1072
|
+
try {
|
|
1073
|
+
const buildContext = (_d = config.buildContext) != null ? _d : defaultBuildContext;
|
|
1074
|
+
promptContext = buildContext(ctx, options.instruction);
|
|
1075
|
+
} catch (error) {
|
|
1076
|
+
const milkdownError = aiBuildContextError(error);
|
|
1077
|
+
emitAIError(ctx, milkdownError);
|
|
1078
|
+
commands.call(abortStreamingCmd.key, { keep: false });
|
|
1079
|
+
clearActiveSession(ctx);
|
|
1080
|
+
return false;
|
|
1081
|
+
}
|
|
1082
|
+
void runProvider(ctx, config.provider, promptContext, abortController);
|
|
1083
|
+
return true;
|
|
1084
|
+
};
|
|
1085
|
+
});
|
|
1086
|
+
const abortAICmd = $command("AbortAI", (ctx) => {
|
|
1087
|
+
return (options) => (state, dispatch) => {
|
|
1088
|
+
var _a;
|
|
1089
|
+
const session = ctx.get(aiSessionCtx.key);
|
|
1090
|
+
if (!dispatch) return !!session.abortController;
|
|
1091
|
+
if (!session.abortController) return false;
|
|
1092
|
+
session.abortController.abort();
|
|
1093
|
+
clearActiveSession(ctx);
|
|
1094
|
+
if ((_a = streamingPluginKey.getState(state)) == null ? void 0 : _a.active) {
|
|
1095
|
+
const commands = ctx.get(commandsCtx);
|
|
1096
|
+
commands.call(abortStreamingCmd.key, options);
|
|
1097
|
+
}
|
|
1098
|
+
return true;
|
|
1099
|
+
};
|
|
1100
|
+
});
|
|
1101
|
+
|
|
1102
|
+
var __typeError$a = (msg) => {
|
|
1103
|
+
throw TypeError(msg);
|
|
1104
|
+
};
|
|
1105
|
+
var __accessCheck$a = (obj, member, msg) => member.has(obj) || __typeError$a("Cannot " + msg);
|
|
1106
|
+
var __privateGet$a = (obj, member, getter) => (__accessCheck$a(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
1107
|
+
var __privateAdd$a = (obj, member, value) => member.has(obj) ? __typeError$a("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1108
|
+
var __privateSet$a = (obj, member, value, setter) => (__accessCheck$a(obj, member, "write to private field"), member.set(obj, value), value);
|
|
1109
|
+
var __privateMethod = (obj, member, method) => (__accessCheck$a(obj, member, "access private method"), method);
|
|
1110
|
+
var _panel, _host, _retryBtn, _config, _visible, _diffActive, _diffStartDoc, _ownedByAI, _DiffActionsPanelView_instances, findHost_fn, makeButton_fn, makeShortcutChip_fn, _retry, canRetry_fn, _rejectAll, _acceptAll;
|
|
1111
|
+
const PANEL_CLASS = "milkdown-ai-diff-actions";
|
|
1112
|
+
function setSanitizedIcon(host, svg) {
|
|
1113
|
+
host.innerHTML = DOMPurify.sanitize(svg.trim());
|
|
1114
|
+
}
|
|
1115
|
+
function createIcon(svg) {
|
|
1116
|
+
const span = document.createElement("span");
|
|
1117
|
+
span.className = `${PANEL_CLASS}-icon`;
|
|
1118
|
+
setSanitizedIcon(span, svg);
|
|
1119
|
+
return span;
|
|
1120
|
+
}
|
|
1121
|
+
class DiffActionsPanelView {
|
|
1122
|
+
constructor(ctx, view, config) {
|
|
1123
|
+
this.ctx = ctx;
|
|
1124
|
+
__privateAdd$a(this, _DiffActionsPanelView_instances);
|
|
1125
|
+
__privateAdd$a(this, _panel);
|
|
1126
|
+
__privateAdd$a(this, _host);
|
|
1127
|
+
__privateAdd$a(this, _retryBtn);
|
|
1128
|
+
__privateAdd$a(this, _config);
|
|
1129
|
+
__privateAdd$a(this, _visible, false);
|
|
1130
|
+
/// Tracks the diff plugin's `active` flag across transactions so we
|
|
1131
|
+
/// can detect false→true / true→false edges independently of whether
|
|
1132
|
+
/// the panel is actually being shown.
|
|
1133
|
+
__privateAdd$a(this, _diffActive, false);
|
|
1134
|
+
/// Doc snapshot at the moment diff review activated. If the live doc
|
|
1135
|
+
/// drifts from this snapshot the user has accepted some per-change
|
|
1136
|
+
/// diffs and the stored `lastFrom`/`lastTo` no longer point at the
|
|
1137
|
+
/// original range — Retry is unsafe at that point.
|
|
1138
|
+
__privateAdd$a(this, _diffStartDoc, null);
|
|
1139
|
+
/// Whether the active diff review came from this AI session's
|
|
1140
|
+
/// streaming hand-off (vs being started manually via
|
|
1141
|
+
/// `startDiffReviewCmd`). Captured at the false→true transition.
|
|
1142
|
+
/// The panel only renders when this is true so it doesn't take over
|
|
1143
|
+
/// non-AI diff flows that exist independently of the AI feature.
|
|
1144
|
+
__privateAdd$a(this, _ownedByAI, false);
|
|
1145
|
+
__privateAdd$a(this, _retry, () => {
|
|
1146
|
+
const session = this.ctx.get(aiSessionCtx.key);
|
|
1147
|
+
if (!session.lastInstruction) return;
|
|
1148
|
+
if (!__privateGet$a(this, _ownedByAI) || !__privateMethod(this, _DiffActionsPanelView_instances, canRetry_fn).call(this)) return;
|
|
1149
|
+
const commands = this.ctx.get(commandsCtx);
|
|
1150
|
+
commands.call(clearDiffReviewCmd.key);
|
|
1151
|
+
const editorView = this.ctx.get(editorViewCtx);
|
|
1152
|
+
const { doc } = editorView.state;
|
|
1153
|
+
const from = Math.min(Math.max(session.lastFrom, 0), doc.content.size);
|
|
1154
|
+
const to = Math.min(Math.max(session.lastTo, 0), doc.content.size);
|
|
1155
|
+
editorView.dispatch(
|
|
1156
|
+
editorView.state.tr.setSelection(
|
|
1157
|
+
TextSelection.create(editorView.state.doc, from, to)
|
|
1158
|
+
)
|
|
1159
|
+
);
|
|
1160
|
+
commands.call(runAICmd.key, {
|
|
1161
|
+
instruction: session.lastInstruction,
|
|
1162
|
+
label: session.lastLabel
|
|
1163
|
+
});
|
|
1164
|
+
});
|
|
1165
|
+
__privateAdd$a(this, _rejectAll, () => {
|
|
1166
|
+
this.ctx.get(commandsCtx).call(clearDiffReviewCmd.key);
|
|
1167
|
+
});
|
|
1168
|
+
__privateAdd$a(this, _acceptAll, () => {
|
|
1169
|
+
this.ctx.get(commandsCtx).call(acceptAllDiffsCmd.key);
|
|
1170
|
+
});
|
|
1171
|
+
__privateSet$a(this, _config, config);
|
|
1172
|
+
__privateSet$a(this, _host, __privateMethod(this, _DiffActionsPanelView_instances, findHost_fn).call(this, view));
|
|
1173
|
+
const panel = document.createElement("div");
|
|
1174
|
+
panel.className = PANEL_CLASS;
|
|
1175
|
+
panel.dataset.show = "false";
|
|
1176
|
+
__privateSet$a(this, _retryBtn, __privateMethod(this, _DiffActionsPanelView_instances, makeButton_fn).call(this, "retry", config.retryIcon, config.retryLabel, __privateGet$a(this, _retry)));
|
|
1177
|
+
panel.appendChild(__privateGet$a(this, _retryBtn));
|
|
1178
|
+
panel.appendChild(
|
|
1179
|
+
__privateMethod(this, _DiffActionsPanelView_instances, makeButton_fn).call(this, "reject", config.rejectIcon, config.rejectAllLabel, __privateGet$a(this, _rejectAll))
|
|
1180
|
+
);
|
|
1181
|
+
const acceptBtn = __privateMethod(this, _DiffActionsPanelView_instances, makeButton_fn).call(this, "accept", config.acceptIcon, config.acceptAllLabel, __privateGet$a(this, _acceptAll));
|
|
1182
|
+
acceptBtn.appendChild(__privateMethod(this, _DiffActionsPanelView_instances, makeShortcutChip_fn).call(this));
|
|
1183
|
+
panel.appendChild(acceptBtn);
|
|
1184
|
+
__privateSet$a(this, _panel, panel);
|
|
1185
|
+
__privateGet$a(this, _host).appendChild(panel);
|
|
1186
|
+
this.update(view);
|
|
1187
|
+
}
|
|
1188
|
+
update(view) {
|
|
1189
|
+
var _a;
|
|
1190
|
+
const diffActive = !!((_a = diffPluginKey.getState(view.state)) == null ? void 0 : _a.active);
|
|
1191
|
+
if (diffActive !== __privateGet$a(this, _diffActive)) {
|
|
1192
|
+
__privateSet$a(this, _diffActive, diffActive);
|
|
1193
|
+
if (diffActive) {
|
|
1194
|
+
const session = this.ctx.get(aiSessionCtx.key);
|
|
1195
|
+
__privateSet$a(this, _ownedByAI, session.diffOwnedByAI);
|
|
1196
|
+
__privateSet$a(this, _diffStartDoc, view.state.doc);
|
|
1197
|
+
} else {
|
|
1198
|
+
__privateSet$a(this, _ownedByAI, false);
|
|
1199
|
+
__privateSet$a(this, _diffStartDoc, null);
|
|
1200
|
+
const session = this.ctx.get(aiSessionCtx.key);
|
|
1201
|
+
if (session.diffOwnedByAI) {
|
|
1202
|
+
this.ctx.set(aiSessionCtx.key, {
|
|
1203
|
+
...session,
|
|
1204
|
+
diffOwnedByAI: false
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
const shouldShow = diffActive && __privateGet$a(this, _ownedByAI);
|
|
1210
|
+
if (shouldShow !== __privateGet$a(this, _visible)) {
|
|
1211
|
+
__privateSet$a(this, _visible, shouldShow);
|
|
1212
|
+
__privateGet$a(this, _panel).dataset.show = shouldShow ? "true" : "false";
|
|
1213
|
+
}
|
|
1214
|
+
if (shouldShow) {
|
|
1215
|
+
const session = this.ctx.get(aiSessionCtx.key);
|
|
1216
|
+
const docUntouched = !!__privateGet$a(this, _diffStartDoc) && view.state.doc.eq(__privateGet$a(this, _diffStartDoc));
|
|
1217
|
+
__privateGet$a(this, _retryBtn).disabled = !session.lastInstruction || !docUntouched;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
destroy() {
|
|
1221
|
+
__privateGet$a(this, _panel).remove();
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
_panel = new WeakMap();
|
|
1225
|
+
_host = new WeakMap();
|
|
1226
|
+
_retryBtn = new WeakMap();
|
|
1227
|
+
_config = new WeakMap();
|
|
1228
|
+
_visible = new WeakMap();
|
|
1229
|
+
_diffActive = new WeakMap();
|
|
1230
|
+
_diffStartDoc = new WeakMap();
|
|
1231
|
+
_ownedByAI = new WeakMap();
|
|
1232
|
+
_DiffActionsPanelView_instances = new WeakSet();
|
|
1233
|
+
findHost_fn = function(view) {
|
|
1234
|
+
var _a;
|
|
1235
|
+
return (_a = view.dom.closest(".milkdown")) != null ? _a : document.body;
|
|
1236
|
+
};
|
|
1237
|
+
makeButton_fn = function(variant, icon, label, onClick) {
|
|
1238
|
+
const btn = document.createElement("button");
|
|
1239
|
+
btn.type = "button";
|
|
1240
|
+
btn.className = `${PANEL_CLASS}-btn ${PANEL_CLASS}-btn-${variant}`;
|
|
1241
|
+
btn.appendChild(createIcon(icon));
|
|
1242
|
+
const text = document.createElement("span");
|
|
1243
|
+
text.textContent = label;
|
|
1244
|
+
btn.appendChild(text);
|
|
1245
|
+
btn.addEventListener("mousedown", (e) => e.preventDefault());
|
|
1246
|
+
btn.addEventListener("click", (e) => {
|
|
1247
|
+
e.preventDefault();
|
|
1248
|
+
e.stopPropagation();
|
|
1249
|
+
onClick();
|
|
1250
|
+
});
|
|
1251
|
+
return btn;
|
|
1252
|
+
};
|
|
1253
|
+
makeShortcutChip_fn = function() {
|
|
1254
|
+
const shortcut = document.createElement("span");
|
|
1255
|
+
shortcut.className = `${PANEL_CLASS}-shortcut`;
|
|
1256
|
+
const cmd = document.createElement("span");
|
|
1257
|
+
cmd.textContent = __privateGet$a(this, _config).modSymbol;
|
|
1258
|
+
const enter = document.createElement("span");
|
|
1259
|
+
enter.className = `${PANEL_CLASS}-shortcut-icon`;
|
|
1260
|
+
setSanitizedIcon(enter, __privateGet$a(this, _config).enterKeyIcon);
|
|
1261
|
+
shortcut.append(cmd, enter);
|
|
1262
|
+
return shortcut;
|
|
1263
|
+
};
|
|
1264
|
+
_retry = new WeakMap();
|
|
1265
|
+
canRetry_fn = function() {
|
|
1266
|
+
if (!__privateGet$a(this, _diffStartDoc)) return false;
|
|
1267
|
+
const editorView = this.ctx.get(editorViewCtx);
|
|
1268
|
+
return editorView.state.doc.eq(__privateGet$a(this, _diffStartDoc));
|
|
1269
|
+
};
|
|
1270
|
+
_rejectAll = new WeakMap();
|
|
1271
|
+
_acceptAll = new WeakMap();
|
|
1272
|
+
|
|
1273
|
+
const diffActionsPanelKey = new PluginKey("CREPE_AI_DIFF_ACTIONS_PANEL");
|
|
1274
|
+
const DEFAULT_DIFF_ACTIONS_RETRY_LABEL = "Retry";
|
|
1275
|
+
const DEFAULT_DIFF_ACTIONS_REJECT_ALL_LABEL = "Reject all";
|
|
1276
|
+
const DEFAULT_DIFF_ACTIONS_ACCEPT_ALL_LABEL = "Accept all";
|
|
1277
|
+
function detectModSymbol() {
|
|
1278
|
+
var _a, _b, _c, _d;
|
|
1279
|
+
if (typeof navigator === "undefined") return "\u2318";
|
|
1280
|
+
const ua = navigator;
|
|
1281
|
+
const platform = (_d = (_c = (_b = (_a = ua.userAgentData) == null ? void 0 : _a.platform) != null ? _b : ua.platform) != null ? _c : ua.userAgent) != null ? _d : "";
|
|
1282
|
+
return /mac|iphone|ipad|ipod/i.test(platform) ? "\u2318" : "Ctrl";
|
|
1283
|
+
}
|
|
1284
|
+
const DEFAULT_DIFF_ACTIONS_MOD_SYMBOL = detectModSymbol();
|
|
1285
|
+
function resolveDiffActionsConfig(options) {
|
|
1286
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1287
|
+
const { config, enterKeyIcon: enterKeyIcon$1 } = options;
|
|
1288
|
+
return {
|
|
1289
|
+
retryLabel: (_a = config == null ? void 0 : config.retryLabel) != null ? _a : DEFAULT_DIFF_ACTIONS_RETRY_LABEL,
|
|
1290
|
+
rejectAllLabel: (_b = config == null ? void 0 : config.rejectAllLabel) != null ? _b : DEFAULT_DIFF_ACTIONS_REJECT_ALL_LABEL,
|
|
1291
|
+
acceptAllLabel: (_c = config == null ? void 0 : config.acceptAllLabel) != null ? _c : DEFAULT_DIFF_ACTIONS_ACCEPT_ALL_LABEL,
|
|
1292
|
+
retryIcon: (_d = config == null ? void 0 : config.retryIcon) != null ? _d : retryIcon,
|
|
1293
|
+
rejectIcon: (_e = config == null ? void 0 : config.rejectIcon) != null ? _e : clearIcon,
|
|
1294
|
+
acceptIcon: (_f = config == null ? void 0 : config.acceptIcon) != null ? _f : confirmIcon,
|
|
1295
|
+
enterKeyIcon: enterKeyIcon$1 != null ? enterKeyIcon$1 : enterKeyIcon,
|
|
1296
|
+
modSymbol: (_g = config == null ? void 0 : config.modSymbol) != null ? _g : DEFAULT_DIFF_ACTIONS_MOD_SYMBOL
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
1299
|
+
function diffActionsPanelPlugin(options = {}) {
|
|
1300
|
+
const resolved = resolveDiffActionsConfig(options);
|
|
1301
|
+
return $prose((ctx) => {
|
|
1302
|
+
return new Plugin({
|
|
1303
|
+
key: diffActionsPanelKey,
|
|
1304
|
+
view(view) {
|
|
1305
|
+
return new DiffActionsPanelView(ctx, view, resolved);
|
|
1306
|
+
},
|
|
1307
|
+
props: {
|
|
1308
|
+
handleKeyDown(view, event) {
|
|
1309
|
+
var _a;
|
|
1310
|
+
if (event.key !== "Enter") return false;
|
|
1311
|
+
if (!(event.metaKey || event.ctrlKey)) return false;
|
|
1312
|
+
if (!((_a = diffPluginKey.getState(view.state)) == null ? void 0 : _a.active)) return false;
|
|
1313
|
+
if (!ctx.get(aiSessionCtx.key).diffOwnedByAI) return false;
|
|
1314
|
+
event.preventDefault();
|
|
1315
|
+
const commands = ctx.get(commandsCtx);
|
|
1316
|
+
commands.call(acceptAllDiffsCmd.key);
|
|
1317
|
+
return true;
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
});
|
|
1321
|
+
});
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
var __typeError$9 = (msg) => {
|
|
1325
|
+
throw TypeError(msg);
|
|
1326
|
+
};
|
|
1327
|
+
var __accessCheck$9 = (obj, member, msg) => member.has(obj) || __typeError$9("Cannot " + msg);
|
|
1328
|
+
var __privateGet$9 = (obj, member, getter) => (__accessCheck$9(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
1329
|
+
var __privateAdd$9 = (obj, member, value) => member.has(obj) ? __typeError$9("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1330
|
+
var __privateSet$9 = (obj, member, value, setter) => (__accessCheck$9(obj, member, "write to private field"), member.set(obj, value), value);
|
|
1331
|
+
var _nodes, _removeById;
|
|
1332
|
+
function createSubmenuBuilder(node) {
|
|
1333
|
+
const builder = {
|
|
1334
|
+
addItem: (id, item) => {
|
|
1335
|
+
node.items.set(id, item);
|
|
1336
|
+
return builder;
|
|
1337
|
+
},
|
|
1338
|
+
removeItem: (id) => {
|
|
1339
|
+
node.items.delete(id);
|
|
1340
|
+
return builder;
|
|
1341
|
+
},
|
|
1342
|
+
getItem: (id) => node.items.get(id),
|
|
1343
|
+
clear: () => {
|
|
1344
|
+
node.items.clear();
|
|
1345
|
+
return builder;
|
|
1346
|
+
}
|
|
1347
|
+
};
|
|
1348
|
+
return builder;
|
|
1349
|
+
}
|
|
1350
|
+
class AISuggestionsBuilder {
|
|
1351
|
+
constructor() {
|
|
1352
|
+
__privateAdd$9(this, _nodes, []);
|
|
1353
|
+
this.addItem = (id, item) => {
|
|
1354
|
+
__privateGet$9(this, _removeById).call(this, id);
|
|
1355
|
+
__privateGet$9(this, _nodes).push({ kind: "item", id, item });
|
|
1356
|
+
return this;
|
|
1357
|
+
};
|
|
1358
|
+
/// Add a submenu. Populate items via the optional `build` callback,
|
|
1359
|
+
/// or call `getSubmenu(id)` afterward. Returns `this` so calls can be
|
|
1360
|
+
/// chained at the parent level alongside `addItem`.
|
|
1361
|
+
this.addSubmenu = (id, def, build) => {
|
|
1362
|
+
__privateGet$9(this, _removeById).call(this, id);
|
|
1363
|
+
const node = { def, items: /* @__PURE__ */ new Map() };
|
|
1364
|
+
if (build) build(createSubmenuBuilder(node));
|
|
1365
|
+
__privateGet$9(this, _nodes).push({ kind: "submenu", id, node });
|
|
1366
|
+
return this;
|
|
1367
|
+
};
|
|
1368
|
+
this.removeItem = (id) => {
|
|
1369
|
+
__privateGet$9(this, _removeById).call(this, id);
|
|
1370
|
+
return this;
|
|
1371
|
+
};
|
|
1372
|
+
this.getItem = (id) => {
|
|
1373
|
+
const node = __privateGet$9(this, _nodes).find((n) => n.kind === "item" && n.id === id);
|
|
1374
|
+
return (node == null ? void 0 : node.kind) === "item" ? node.item : void 0;
|
|
1375
|
+
};
|
|
1376
|
+
/// Return a builder that mutates the submenu's items in place.
|
|
1377
|
+
/// Multiple calls return distinct builder objects backed by the same
|
|
1378
|
+
/// underlying node, so changes are always visible.
|
|
1379
|
+
this.getSubmenu = (id) => {
|
|
1380
|
+
const node = __privateGet$9(this, _nodes).find((n) => n.kind === "submenu" && n.id === id);
|
|
1381
|
+
return (node == null ? void 0 : node.kind) === "submenu" ? createSubmenuBuilder(node.node) : void 0;
|
|
1382
|
+
};
|
|
1383
|
+
this.clear = () => {
|
|
1384
|
+
__privateSet$9(this, _nodes, []);
|
|
1385
|
+
return this;
|
|
1386
|
+
};
|
|
1387
|
+
this.build = () => {
|
|
1388
|
+
const main = [];
|
|
1389
|
+
const submenus = {};
|
|
1390
|
+
for (const node of __privateGet$9(this, _nodes)) {
|
|
1391
|
+
if (node.kind === "item") {
|
|
1392
|
+
main.push({ kind: "item", id: node.id, item: node.item });
|
|
1393
|
+
} else {
|
|
1394
|
+
main.push({ kind: "submenu", id: node.id, def: node.node.def });
|
|
1395
|
+
submenus[node.id] = {
|
|
1396
|
+
def: node.node.def,
|
|
1397
|
+
items: Array.from(node.node.items.entries()).map(([id, item]) => ({
|
|
1398
|
+
id,
|
|
1399
|
+
item
|
|
1400
|
+
}))
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
return { main, submenus };
|
|
1405
|
+
};
|
|
1406
|
+
__privateAdd$9(this, _removeById, (id) => {
|
|
1407
|
+
__privateSet$9(this, _nodes, __privateGet$9(this, _nodes).filter((n) => n.id !== id));
|
|
1408
|
+
});
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
_nodes = new WeakMap();
|
|
1412
|
+
_removeById = new WeakMap();
|
|
1413
|
+
function applyDefaultSuggestions(builder) {
|
|
1414
|
+
builder.addItem("improve", {
|
|
1415
|
+
icon: aiIcon,
|
|
1416
|
+
label: "Improve writing",
|
|
1417
|
+
streamingLabel: "Improving writing",
|
|
1418
|
+
prompt: "Improve the writing while preserving the original meaning."
|
|
1419
|
+
}).addItem("grammar", {
|
|
1420
|
+
icon: grammarCheckIcon,
|
|
1421
|
+
label: "Fix grammar & spelling",
|
|
1422
|
+
streamingLabel: "Fixing grammar & spelling",
|
|
1423
|
+
prompt: "Fix any grammar and spelling errors without changing the meaning."
|
|
1424
|
+
}).addItem("shorter", {
|
|
1425
|
+
icon: shorterIcon,
|
|
1426
|
+
label: "Make shorter",
|
|
1427
|
+
streamingLabel: "Making shorter",
|
|
1428
|
+
prompt: "Make this shorter while preserving the key information."
|
|
1429
|
+
}).addItem("longer", {
|
|
1430
|
+
icon: longerIcon,
|
|
1431
|
+
label: "Make longer",
|
|
1432
|
+
streamingLabel: "Expanding",
|
|
1433
|
+
prompt: "Expand this with more detail and examples."
|
|
1434
|
+
});
|
|
1435
|
+
builder.addSubmenu(
|
|
1436
|
+
"tone",
|
|
1437
|
+
{
|
|
1438
|
+
icon: editIcon,
|
|
1439
|
+
label: "Change tone\u2026",
|
|
1440
|
+
title: "Change tone",
|
|
1441
|
+
searchPlaceholder: "Search tones\u2026"
|
|
1442
|
+
},
|
|
1443
|
+
(sub) => {
|
|
1444
|
+
const tones = [
|
|
1445
|
+
["professional", "Professional"],
|
|
1446
|
+
["casual", "Casual"],
|
|
1447
|
+
["confident", "Confident"],
|
|
1448
|
+
["friendly", "Friendly"],
|
|
1449
|
+
["direct", "Direct"],
|
|
1450
|
+
["formal", "Formal"]
|
|
1451
|
+
];
|
|
1452
|
+
for (const [id, label] of tones) {
|
|
1453
|
+
sub.addItem(id, {
|
|
1454
|
+
icon: editIcon,
|
|
1455
|
+
label,
|
|
1456
|
+
streamingLabel: "Adjusting tone",
|
|
1457
|
+
prompt: `Rewrite this in a ${label.toLowerCase()} tone.`
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
);
|
|
1462
|
+
builder.addSubmenu(
|
|
1463
|
+
"translate",
|
|
1464
|
+
{
|
|
1465
|
+
icon: translateIcon,
|
|
1466
|
+
label: "Translate\u2026",
|
|
1467
|
+
title: "Translate",
|
|
1468
|
+
searchPlaceholder: "Search languages\u2026"
|
|
1469
|
+
},
|
|
1470
|
+
(sub) => {
|
|
1471
|
+
const languages = [
|
|
1472
|
+
["english", "English", "English"],
|
|
1473
|
+
["chinese", "Chinese", "Chinese (Simplified)"],
|
|
1474
|
+
["japanese", "Japanese", "Japanese"],
|
|
1475
|
+
["korean", "Korean", "Korean"],
|
|
1476
|
+
["spanish", "Spanish", "Spanish"],
|
|
1477
|
+
["french", "French", "French"],
|
|
1478
|
+
["german", "German", "German"]
|
|
1479
|
+
];
|
|
1480
|
+
for (const [id, label, promptName] of languages) {
|
|
1481
|
+
sub.addItem(id, {
|
|
1482
|
+
icon: translateIcon,
|
|
1483
|
+
label,
|
|
1484
|
+
streamingLabel: `Translating to ${label}`,
|
|
1485
|
+
prompt: `Translate this to ${promptName}.`
|
|
1486
|
+
});
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
);
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
function keepAlive(..._args) {
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
keepAlive(h);
|
|
1496
|
+
function renderHighlighted(label, query) {
|
|
1497
|
+
const q = query.trim();
|
|
1498
|
+
if (!q) return [label];
|
|
1499
|
+
const lower = label.toLowerCase();
|
|
1500
|
+
const lq = q.toLowerCase();
|
|
1501
|
+
const idx = lower.indexOf(lq);
|
|
1502
|
+
if (idx === -1) return [label];
|
|
1503
|
+
return [
|
|
1504
|
+
label.slice(0, idx),
|
|
1505
|
+
h("mark", null, label.slice(idx, idx + q.length)),
|
|
1506
|
+
label.slice(idx + q.length)
|
|
1507
|
+
];
|
|
1508
|
+
}
|
|
1509
|
+
const AIInstructionInput = defineComponent({
|
|
1510
|
+
props: {
|
|
1511
|
+
placeholder: { type: Object, required: true },
|
|
1512
|
+
resetSignal: { type: Object, required: true },
|
|
1513
|
+
suggestions: { type: Object, required: true },
|
|
1514
|
+
chrome: { type: Object, required: true },
|
|
1515
|
+
onConfirm: { type: Function, required: true },
|
|
1516
|
+
onCancel: { type: Function, required: true }
|
|
1517
|
+
},
|
|
1518
|
+
setup({
|
|
1519
|
+
placeholder,
|
|
1520
|
+
resetSignal,
|
|
1521
|
+
suggestions,
|
|
1522
|
+
chrome,
|
|
1523
|
+
onConfirm,
|
|
1524
|
+
onCancel
|
|
1525
|
+
}) {
|
|
1526
|
+
const inputValue = ref("");
|
|
1527
|
+
const view = ref({ kind: "main" });
|
|
1528
|
+
const selectedIndex = ref(0);
|
|
1529
|
+
const inputRef = ref(null);
|
|
1530
|
+
const listRef = ref(null);
|
|
1531
|
+
const listboxId = `ai-instruction-list-${Math.random().toString(36).slice(2, 9)}`;
|
|
1532
|
+
const optionId = (idx) => `${listboxId}-opt-${idx}`;
|
|
1533
|
+
watch(resetSignal, () => {
|
|
1534
|
+
inputValue.value = "";
|
|
1535
|
+
view.value = { kind: "main" };
|
|
1536
|
+
selectedIndex.value = 0;
|
|
1537
|
+
});
|
|
1538
|
+
const allItems = computed(() => {
|
|
1539
|
+
if (view.value.kind === "submenu") {
|
|
1540
|
+
const submenu = suggestions.submenus[view.value.id];
|
|
1541
|
+
if (!submenu) return [];
|
|
1542
|
+
return submenu.items.map(({ id, item }) => ({
|
|
1543
|
+
id,
|
|
1544
|
+
icon: item.icon,
|
|
1545
|
+
label: item.label,
|
|
1546
|
+
hasSubmenu: false,
|
|
1547
|
+
prompt: { text: item.prompt, streamingLabel: item.streamingLabel }
|
|
1548
|
+
}));
|
|
1549
|
+
}
|
|
1550
|
+
return suggestions.main.map((entry) => {
|
|
1551
|
+
if (entry.kind === "item") {
|
|
1552
|
+
return {
|
|
1553
|
+
id: entry.id,
|
|
1554
|
+
icon: entry.item.icon,
|
|
1555
|
+
label: entry.item.label,
|
|
1556
|
+
hasSubmenu: false,
|
|
1557
|
+
prompt: {
|
|
1558
|
+
text: entry.item.prompt,
|
|
1559
|
+
streamingLabel: entry.item.streamingLabel
|
|
1560
|
+
}
|
|
1561
|
+
};
|
|
1562
|
+
}
|
|
1563
|
+
return {
|
|
1564
|
+
id: entry.id,
|
|
1565
|
+
icon: entry.def.icon,
|
|
1566
|
+
label: entry.def.label,
|
|
1567
|
+
hasSubmenu: true
|
|
1568
|
+
};
|
|
1569
|
+
});
|
|
1570
|
+
});
|
|
1571
|
+
const currentSubmenuDef = computed(() => {
|
|
1572
|
+
var _a, _b;
|
|
1573
|
+
if (view.value.kind !== "submenu") return null;
|
|
1574
|
+
return (_b = (_a = suggestions.submenus[view.value.id]) == null ? void 0 : _a.def) != null ? _b : null;
|
|
1575
|
+
});
|
|
1576
|
+
const filteredItems = computed(() => {
|
|
1577
|
+
const q = inputValue.value.trim().toLowerCase();
|
|
1578
|
+
if (!q) return allItems.value;
|
|
1579
|
+
return allItems.value.filter(
|
|
1580
|
+
(item) => item.label.toLowerCase().includes(q)
|
|
1581
|
+
);
|
|
1582
|
+
});
|
|
1583
|
+
const showSendAsPrompt = computed(() => inputValue.value.trim().length > 0);
|
|
1584
|
+
const totalItems = computed(
|
|
1585
|
+
() => filteredItems.value.length + (showSendAsPrompt.value ? 1 : 0)
|
|
1586
|
+
);
|
|
1587
|
+
watch([filteredItems, view, showSendAsPrompt], () => {
|
|
1588
|
+
selectedIndex.value = showSendAsPrompt.value ? filteredItems.value.length : 0;
|
|
1589
|
+
});
|
|
1590
|
+
const focusInput = () => {
|
|
1591
|
+
void nextTick(() => {
|
|
1592
|
+
var _a;
|
|
1593
|
+
return (_a = inputRef.value) == null ? void 0 : _a.focus();
|
|
1594
|
+
});
|
|
1595
|
+
};
|
|
1596
|
+
const enterSubmenu = (id) => {
|
|
1597
|
+
view.value = { kind: "submenu", id };
|
|
1598
|
+
inputValue.value = "";
|
|
1599
|
+
selectedIndex.value = 0;
|
|
1600
|
+
focusInput();
|
|
1601
|
+
};
|
|
1602
|
+
const exitSubmenu = () => {
|
|
1603
|
+
view.value = { kind: "main" };
|
|
1604
|
+
inputValue.value = "";
|
|
1605
|
+
selectedIndex.value = 0;
|
|
1606
|
+
focusInput();
|
|
1607
|
+
};
|
|
1608
|
+
const runItem = (item) => {
|
|
1609
|
+
if (item.hasSubmenu) {
|
|
1610
|
+
enterSubmenu(item.id);
|
|
1611
|
+
} else if (item.prompt) {
|
|
1612
|
+
onConfirm(item.prompt.text, item.prompt.streamingLabel);
|
|
1613
|
+
inputValue.value = "";
|
|
1614
|
+
}
|
|
1615
|
+
};
|
|
1616
|
+
const submitRaw = () => {
|
|
1617
|
+
const v = inputValue.value.trim();
|
|
1618
|
+
if (!v) return;
|
|
1619
|
+
onConfirm(v);
|
|
1620
|
+
inputValue.value = "";
|
|
1621
|
+
};
|
|
1622
|
+
const onSelectCurrent = () => {
|
|
1623
|
+
const idx = selectedIndex.value;
|
|
1624
|
+
const items = filteredItems.value;
|
|
1625
|
+
if (idx < items.length) {
|
|
1626
|
+
runItem(items[idx]);
|
|
1627
|
+
} else if (showSendAsPrompt.value) {
|
|
1628
|
+
submitRaw();
|
|
1629
|
+
}
|
|
1630
|
+
};
|
|
1631
|
+
const scrollToSelected = () => {
|
|
1632
|
+
void nextTick(() => {
|
|
1633
|
+
const list = listRef.value;
|
|
1634
|
+
if (!list) return;
|
|
1635
|
+
const el = list.querySelector(
|
|
1636
|
+
`[data-index="${selectedIndex.value}"]`
|
|
1637
|
+
);
|
|
1638
|
+
el == null ? void 0 : el.scrollIntoView({ block: "nearest" });
|
|
1639
|
+
});
|
|
1640
|
+
};
|
|
1641
|
+
const onKeydown = (e) => {
|
|
1642
|
+
e.stopPropagation();
|
|
1643
|
+
if (e.key === "ArrowDown") {
|
|
1644
|
+
e.preventDefault();
|
|
1645
|
+
if (totalItems.value === 0) return;
|
|
1646
|
+
selectedIndex.value = (selectedIndex.value + 1) % totalItems.value;
|
|
1647
|
+
scrollToSelected();
|
|
1648
|
+
return;
|
|
1649
|
+
}
|
|
1650
|
+
if (e.key === "ArrowUp") {
|
|
1651
|
+
e.preventDefault();
|
|
1652
|
+
if (totalItems.value === 0) return;
|
|
1653
|
+
selectedIndex.value = (selectedIndex.value - 1 + totalItems.value) % totalItems.value;
|
|
1654
|
+
scrollToSelected();
|
|
1655
|
+
return;
|
|
1656
|
+
}
|
|
1657
|
+
if (e.key === "Enter") {
|
|
1658
|
+
e.preventDefault();
|
|
1659
|
+
onSelectCurrent();
|
|
1660
|
+
return;
|
|
1661
|
+
}
|
|
1662
|
+
if (e.key === "Escape") {
|
|
1663
|
+
e.preventDefault();
|
|
1664
|
+
if (view.value.kind === "submenu") exitSubmenu();
|
|
1665
|
+
else onCancel();
|
|
1666
|
+
return;
|
|
1667
|
+
}
|
|
1668
|
+
if (e.key === "Backspace" && inputValue.value === "" && view.value.kind === "submenu") {
|
|
1669
|
+
e.preventDefault();
|
|
1670
|
+
exitSubmenu();
|
|
1671
|
+
}
|
|
1672
|
+
};
|
|
1673
|
+
const onItemPointerDown = (e) => {
|
|
1674
|
+
e.preventDefault();
|
|
1675
|
+
};
|
|
1676
|
+
return () => {
|
|
1677
|
+
const items = filteredItems.value;
|
|
1678
|
+
const showPrompt = showSendAsPrompt.value;
|
|
1679
|
+
const submenuDef = currentSubmenuDef.value;
|
|
1680
|
+
return /* @__PURE__ */ h("div", { class: "ai-instruction" }, /* @__PURE__ */ h("div", { class: "ai-instruction-input" }, /* @__PURE__ */ h("span", { class: "ai-instruction-input-prefix" }, /* @__PURE__ */ h(Icon, { icon: chrome.aiIcon })), /* @__PURE__ */ h(
|
|
1681
|
+
"input",
|
|
1682
|
+
{
|
|
1683
|
+
ref: inputRef,
|
|
1684
|
+
class: "ai-instruction-input-field",
|
|
1685
|
+
role: "combobox",
|
|
1686
|
+
"aria-expanded": "true",
|
|
1687
|
+
"aria-autocomplete": "list",
|
|
1688
|
+
"aria-controls": listboxId,
|
|
1689
|
+
"aria-activedescendant": totalItems.value > 0 ? optionId(selectedIndex.value) : void 0,
|
|
1690
|
+
placeholder: submenuDef ? submenuDef.searchPlaceholder : placeholder.value,
|
|
1691
|
+
value: inputValue.value,
|
|
1692
|
+
onInput: (e) => {
|
|
1693
|
+
inputValue.value = e.target.value;
|
|
1694
|
+
},
|
|
1695
|
+
onKeydown
|
|
1696
|
+
}
|
|
1697
|
+
), /* @__PURE__ */ h(
|
|
1698
|
+
"button",
|
|
1699
|
+
{
|
|
1700
|
+
type: "button",
|
|
1701
|
+
class: "ai-instruction-submit",
|
|
1702
|
+
"aria-label": chrome.submitButtonLabel,
|
|
1703
|
+
disabled: !showPrompt,
|
|
1704
|
+
onMousedown: onItemPointerDown,
|
|
1705
|
+
onClick: submitRaw
|
|
1706
|
+
},
|
|
1707
|
+
/* @__PURE__ */ h(Icon, { icon: chrome.sendIcon })
|
|
1708
|
+
)), /* @__PURE__ */ h(
|
|
1709
|
+
"div",
|
|
1710
|
+
{
|
|
1711
|
+
class: "ai-instruction-list",
|
|
1712
|
+
ref: listRef,
|
|
1713
|
+
id: listboxId,
|
|
1714
|
+
role: "listbox",
|
|
1715
|
+
"aria-label": chrome.listboxLabel
|
|
1716
|
+
},
|
|
1717
|
+
submenuDef && /* @__PURE__ */ h(
|
|
1718
|
+
"button",
|
|
1719
|
+
{
|
|
1720
|
+
type: "button",
|
|
1721
|
+
class: "ai-instruction-back",
|
|
1722
|
+
onMousedown: onItemPointerDown,
|
|
1723
|
+
onClick: exitSubmenu
|
|
1724
|
+
},
|
|
1725
|
+
/* @__PURE__ */ h("span", { class: "ai-instruction-back-icon", "aria-hidden": "true" }, /* @__PURE__ */ h(Icon, { icon: chrome.chevronLeftIcon })),
|
|
1726
|
+
/* @__PURE__ */ h("span", null, submenuDef.title)
|
|
1727
|
+
),
|
|
1728
|
+
items.length > 0 && /* @__PURE__ */ h("div", { class: "ai-instruction-section" }, /* @__PURE__ */ h("div", { class: "ai-instruction-section-header" }, chrome.suggestionsHeaderLabel), items.map((item, idx) => /* @__PURE__ */ h(
|
|
1729
|
+
"div",
|
|
1730
|
+
{
|
|
1731
|
+
key: item.id,
|
|
1732
|
+
id: optionId(idx),
|
|
1733
|
+
"data-index": idx,
|
|
1734
|
+
role: "option",
|
|
1735
|
+
"aria-selected": idx === selectedIndex.value,
|
|
1736
|
+
class: [
|
|
1737
|
+
"ai-instruction-item",
|
|
1738
|
+
idx === selectedIndex.value ? "active" : ""
|
|
1739
|
+
],
|
|
1740
|
+
onMousedown: onItemPointerDown,
|
|
1741
|
+
onClick: () => runItem(item),
|
|
1742
|
+
onPointerenter: () => {
|
|
1743
|
+
selectedIndex.value = idx;
|
|
1744
|
+
}
|
|
1745
|
+
},
|
|
1746
|
+
/* @__PURE__ */ h("span", { class: "ai-instruction-item-icon" }, /* @__PURE__ */ h(Icon, { icon: item.icon })),
|
|
1747
|
+
/* @__PURE__ */ h("span", { class: "ai-instruction-item-label" }, renderHighlighted(item.label, inputValue.value)),
|
|
1748
|
+
item.hasSubmenu && /* @__PURE__ */ h("span", { class: "ai-instruction-item-arrow" }, /* @__PURE__ */ h(Icon, { icon: chrome.chevronRightIcon }))
|
|
1749
|
+
))),
|
|
1750
|
+
showPrompt && /* @__PURE__ */ h("div", { class: "ai-instruction-section" }, /* @__PURE__ */ h("div", { class: "ai-instruction-section-header" }, chrome.sendAsPromptHeaderLabel), /* @__PURE__ */ h(
|
|
1751
|
+
"div",
|
|
1752
|
+
{
|
|
1753
|
+
id: optionId(items.length),
|
|
1754
|
+
"data-index": items.length,
|
|
1755
|
+
role: "option",
|
|
1756
|
+
"aria-selected": selectedIndex.value === items.length,
|
|
1757
|
+
class: [
|
|
1758
|
+
"ai-instruction-item",
|
|
1759
|
+
"ai-instruction-item-prompt",
|
|
1760
|
+
selectedIndex.value === items.length ? "active" : ""
|
|
1761
|
+
],
|
|
1762
|
+
onMousedown: onItemPointerDown,
|
|
1763
|
+
onClick: submitRaw,
|
|
1764
|
+
onPointerenter: () => {
|
|
1765
|
+
selectedIndex.value = items.length;
|
|
1766
|
+
}
|
|
1767
|
+
},
|
|
1768
|
+
/* @__PURE__ */ h("span", { class: "ai-instruction-item-icon" }, /* @__PURE__ */ h(Icon, { icon: chrome.sendPromptIcon })),
|
|
1769
|
+
/* @__PURE__ */ h("span", { class: "ai-instruction-item-label" }, chrome.sendAsPromptLabel, " ", /* @__PURE__ */ h("span", { class: "ai-instruction-item-quote" }, '"', inputValue.value, '"')),
|
|
1770
|
+
/* @__PURE__ */ h("span", { class: "ai-instruction-item-shortcut" }, /* @__PURE__ */ h(Icon, { icon: chrome.enterKeyIcon }))
|
|
1771
|
+
))
|
|
1772
|
+
));
|
|
1773
|
+
};
|
|
1774
|
+
}
|
|
1775
|
+
});
|
|
1776
|
+
|
|
1777
|
+
var __typeError$8 = (msg) => {
|
|
1778
|
+
throw TypeError(msg);
|
|
1779
|
+
};
|
|
1780
|
+
var __accessCheck$8 = (obj, member, msg) => member.has(obj) || __typeError$8("Cannot " + msg);
|
|
1781
|
+
var __privateGet$8 = (obj, member, getter) => (__accessCheck$8(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
1782
|
+
var __privateAdd$8 = (obj, member, value) => member.has(obj) ? __typeError$8("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1783
|
+
var __privateSet$8 = (obj, member, value, setter) => (__accessCheck$8(obj, member, "write to private field"), member.set(obj, value), value);
|
|
1784
|
+
var _content$4, _provider$2, _app$5, _placeholder, _resetSignal, _from, _to, _wantsShow, _onConfirm, _onCancel;
|
|
1785
|
+
class AIInstructionTooltipView {
|
|
1786
|
+
constructor(ctx, view, config) {
|
|
1787
|
+
this.ctx = ctx;
|
|
1788
|
+
__privateAdd$8(this, _content$4);
|
|
1789
|
+
__privateAdd$8(this, _provider$2);
|
|
1790
|
+
__privateAdd$8(this, _app$5);
|
|
1791
|
+
__privateAdd$8(this, _placeholder);
|
|
1792
|
+
__privateAdd$8(this, _resetSignal);
|
|
1793
|
+
__privateAdd$8(this, _from, -1);
|
|
1794
|
+
__privateAdd$8(this, _to, -1);
|
|
1795
|
+
/// Source of truth for "should the palette currently be showing".
|
|
1796
|
+
/// `TooltipProvider.shouldShow` reads this so that forwarding `update()`
|
|
1797
|
+
/// to the provider on every editor transition (needed to keep the
|
|
1798
|
+
/// floating position in sync with layout changes) doesn't dismiss the
|
|
1799
|
+
/// palette behind our back.
|
|
1800
|
+
__privateAdd$8(this, _wantsShow, false);
|
|
1801
|
+
__privateAdd$8(this, _onConfirm, (instruction, label) => {
|
|
1802
|
+
if (!instruction.trim()) return;
|
|
1803
|
+
const commands = this.ctx.get(commandsCtx);
|
|
1804
|
+
const accepted = commands.call(runAICmd.key, { instruction, label });
|
|
1805
|
+
if (!accepted) return;
|
|
1806
|
+
__privateSet$8(this, _wantsShow, false);
|
|
1807
|
+
__privateGet$8(this, _provider$2).hide();
|
|
1808
|
+
});
|
|
1809
|
+
__privateAdd$8(this, _onCancel, () => {
|
|
1810
|
+
__privateSet$8(this, _wantsShow, false);
|
|
1811
|
+
__privateGet$8(this, _provider$2).hide();
|
|
1812
|
+
});
|
|
1813
|
+
this.show = (from, to) => {
|
|
1814
|
+
__privateSet$8(this, _from, from);
|
|
1815
|
+
__privateSet$8(this, _to, to);
|
|
1816
|
+
__privateGet$8(this, _resetSignal).value++;
|
|
1817
|
+
__privateSet$8(this, _wantsShow, true);
|
|
1818
|
+
const view = this.ctx.get(editorViewCtx);
|
|
1819
|
+
__privateGet$8(this, _provider$2).show(
|
|
1820
|
+
{ getBoundingClientRect: () => posToDOMRect(view, from, to) },
|
|
1821
|
+
view
|
|
1822
|
+
);
|
|
1823
|
+
requestAnimationFrame(() => {
|
|
1824
|
+
var _a;
|
|
1825
|
+
(_a = __privateGet$8(this, _content$4).querySelector("input")) == null ? void 0 : _a.focus();
|
|
1826
|
+
});
|
|
1827
|
+
};
|
|
1828
|
+
this.update = (view, prevState) => {
|
|
1829
|
+
const { selection } = view.state;
|
|
1830
|
+
const isTextSelection = selection instanceof TextSelection;
|
|
1831
|
+
const movedRange = selection.from !== __privateGet$8(this, _from) || selection.to !== __privateGet$8(this, _to);
|
|
1832
|
+
if (!isTextSelection || movedRange) {
|
|
1833
|
+
__privateSet$8(this, _wantsShow, false);
|
|
1834
|
+
__privateGet$8(this, _provider$2).hide();
|
|
1835
|
+
return;
|
|
1836
|
+
}
|
|
1837
|
+
__privateGet$8(this, _provider$2).update(view, prevState);
|
|
1838
|
+
};
|
|
1839
|
+
this.destroy = () => {
|
|
1840
|
+
__privateGet$8(this, _app$5).unmount();
|
|
1841
|
+
__privateGet$8(this, _provider$2).destroy();
|
|
1842
|
+
__privateGet$8(this, _content$4).remove();
|
|
1843
|
+
};
|
|
1844
|
+
__privateSet$8(this, _placeholder, ref(config.placeholder));
|
|
1845
|
+
__privateSet$8(this, _resetSignal, ref(0));
|
|
1846
|
+
const content = document.createElement("div");
|
|
1847
|
+
content.className = "milkdown-ai-instruction";
|
|
1848
|
+
const app = createApp(AIInstructionInput, {
|
|
1849
|
+
placeholder: __privateGet$8(this, _placeholder),
|
|
1850
|
+
resetSignal: __privateGet$8(this, _resetSignal),
|
|
1851
|
+
suggestions: config.suggestions,
|
|
1852
|
+
chrome: config.chrome,
|
|
1853
|
+
onConfirm: __privateGet$8(this, _onConfirm),
|
|
1854
|
+
onCancel: __privateGet$8(this, _onCancel)
|
|
1855
|
+
});
|
|
1856
|
+
app.mount(content);
|
|
1857
|
+
__privateSet$8(this, _app$5, app);
|
|
1858
|
+
__privateSet$8(this, _content$4, content);
|
|
1859
|
+
__privateSet$8(this, _provider$2, new TooltipProvider({
|
|
1860
|
+
content,
|
|
1861
|
+
debounce: 0,
|
|
1862
|
+
offset: 10,
|
|
1863
|
+
shouldShow: () => __privateGet$8(this, _wantsShow),
|
|
1864
|
+
floatingUIOptions: {
|
|
1865
|
+
placement: "bottom"
|
|
1866
|
+
}
|
|
1867
|
+
}));
|
|
1868
|
+
__privateGet$8(this, _provider$2).onHide = () => {
|
|
1869
|
+
__privateSet$8(this, _wantsShow, false);
|
|
1870
|
+
requestAnimationFrame(() => {
|
|
1871
|
+
try {
|
|
1872
|
+
const root = __privateGet$8(this, _content$4).getRootNode();
|
|
1873
|
+
const active = root.activeElement;
|
|
1874
|
+
if (!active || !__privateGet$8(this, _content$4).contains(active)) return;
|
|
1875
|
+
const v = this.ctx.get(editorViewCtx);
|
|
1876
|
+
v.dom.focus({ preventScroll: true });
|
|
1877
|
+
} catch (e) {
|
|
1878
|
+
}
|
|
1879
|
+
});
|
|
1880
|
+
};
|
|
1881
|
+
__privateGet$8(this, _provider$2).update(view);
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
_content$4 = new WeakMap();
|
|
1885
|
+
_provider$2 = new WeakMap();
|
|
1886
|
+
_app$5 = new WeakMap();
|
|
1887
|
+
_placeholder = new WeakMap();
|
|
1888
|
+
_resetSignal = new WeakMap();
|
|
1889
|
+
_from = new WeakMap();
|
|
1890
|
+
_to = new WeakMap();
|
|
1891
|
+
_wantsShow = new WeakMap();
|
|
1892
|
+
_onConfirm = new WeakMap();
|
|
1893
|
+
_onCancel = new WeakMap();
|
|
1894
|
+
|
|
1895
|
+
const defaultAPI = {
|
|
1896
|
+
show: () => {
|
|
1897
|
+
}
|
|
1898
|
+
};
|
|
1899
|
+
const aiInstructionTooltipAPI = $ctx(
|
|
1900
|
+
{ ...defaultAPI },
|
|
1901
|
+
"aiInstructionTooltipAPI"
|
|
1902
|
+
);
|
|
1903
|
+
const aiInstructionTooltip = tooltipFactory("CREPE_AI_INSTRUCTION");
|
|
1904
|
+
const DEFAULT_SUGGESTIONS_HEADER_LABEL = "SUGGESTIONS";
|
|
1905
|
+
const DEFAULT_SEND_AS_PROMPT_HEADER_LABEL = "SEND AS PROMPT";
|
|
1906
|
+
const DEFAULT_SEND_AS_PROMPT_LABEL = "Ask AI:";
|
|
1907
|
+
const DEFAULT_SUBMIT_BUTTON_LABEL = "Send prompt";
|
|
1908
|
+
const DEFAULT_LISTBOX_LABEL = "AI suggestions";
|
|
1909
|
+
const DEFAULT_INSTRUCTION_PLACEHOLDER = "Tell AI what to do with the selection\u2026";
|
|
1910
|
+
function resolveChrome(config) {
|
|
1911
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
1912
|
+
return {
|
|
1913
|
+
aiIcon: (_a = config == null ? void 0 : config.aiIcon) != null ? _a : aiIcon,
|
|
1914
|
+
sendIcon: (_b = config == null ? void 0 : config.sendIcon) != null ? _b : sendIcon,
|
|
1915
|
+
sendPromptIcon: (_c = config == null ? void 0 : config.sendPromptIcon) != null ? _c : sendPromptIcon,
|
|
1916
|
+
enterKeyIcon: (_d = config == null ? void 0 : config.enterKeyIcon) != null ? _d : enterKeyIcon,
|
|
1917
|
+
chevronLeftIcon: (_e = config == null ? void 0 : config.chevronLeftIcon) != null ? _e : chevronLeftIcon,
|
|
1918
|
+
chevronRightIcon: (_f = config == null ? void 0 : config.chevronRightIcon) != null ? _f : chevronRightIcon,
|
|
1919
|
+
suggestionsHeaderLabel: (_g = config == null ? void 0 : config.suggestionsHeaderLabel) != null ? _g : DEFAULT_SUGGESTIONS_HEADER_LABEL,
|
|
1920
|
+
sendAsPromptHeaderLabel: (_h = config == null ? void 0 : config.sendAsPromptHeaderLabel) != null ? _h : DEFAULT_SEND_AS_PROMPT_HEADER_LABEL,
|
|
1921
|
+
sendAsPromptLabel: (_i = config == null ? void 0 : config.sendAsPromptLabel) != null ? _i : DEFAULT_SEND_AS_PROMPT_LABEL,
|
|
1922
|
+
submitButtonLabel: (_j = config == null ? void 0 : config.submitButtonLabel) != null ? _j : DEFAULT_SUBMIT_BUTTON_LABEL,
|
|
1923
|
+
listboxLabel: (_k = config == null ? void 0 : config.listboxLabel) != null ? _k : DEFAULT_LISTBOX_LABEL
|
|
1924
|
+
};
|
|
1925
|
+
}
|
|
1926
|
+
function resolveViewConfig(config) {
|
|
1927
|
+
var _a, _b;
|
|
1928
|
+
const builder = new AISuggestionsBuilder();
|
|
1929
|
+
applyDefaultSuggestions(builder);
|
|
1930
|
+
(_a = config == null ? void 0 : config.buildAISuggestions) == null ? void 0 : _a.call(config, builder);
|
|
1931
|
+
return {
|
|
1932
|
+
placeholder: (_b = config == null ? void 0 : config.instructionPlaceholder) != null ? _b : DEFAULT_INSTRUCTION_PLACEHOLDER,
|
|
1933
|
+
chrome: resolveChrome(config),
|
|
1934
|
+
suggestions: builder.build()
|
|
1935
|
+
};
|
|
1936
|
+
}
|
|
1937
|
+
function configureAIInstructionTooltip(config) {
|
|
1938
|
+
return (ctx) => {
|
|
1939
|
+
const viewConfig = resolveViewConfig(config);
|
|
1940
|
+
let tooltipView = null;
|
|
1941
|
+
ctx.update(aiInstructionTooltipAPI.key, (api) => ({
|
|
1942
|
+
...api,
|
|
1943
|
+
show: (from, to) => {
|
|
1944
|
+
tooltipView == null ? void 0 : tooltipView.show(from, to);
|
|
1945
|
+
}
|
|
1946
|
+
}));
|
|
1947
|
+
ctx.set(aiInstructionTooltip.key, {
|
|
1948
|
+
view: (view) => {
|
|
1949
|
+
tooltipView = new AIInstructionTooltipView(ctx, view, viewConfig);
|
|
1950
|
+
return tooltipView;
|
|
1951
|
+
}
|
|
1952
|
+
});
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
var __typeError$7 = (msg) => {
|
|
1957
|
+
throw TypeError(msg);
|
|
1958
|
+
};
|
|
1959
|
+
var __accessCheck$7 = (obj, member, msg) => member.has(obj) || __typeError$7("Cannot " + msg);
|
|
1960
|
+
var __privateGet$7 = (obj, member, getter) => (__accessCheck$7(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
1961
|
+
var __privateAdd$7 = (obj, member, value) => member.has(obj) ? __typeError$7("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1962
|
+
var __privateSet$7 = (obj, member, value, setter) => (__accessCheck$7(obj, member, "write to private field"), member.set(obj, value), value);
|
|
1963
|
+
var _spinner, _label, _fallbackLabel, _start, _lastLabelText, _rafId, _tick;
|
|
1964
|
+
const CLASS_PREFIX = "milkdown-ai-streaming";
|
|
1965
|
+
const SPINNER_PERIOD_MS = 800;
|
|
1966
|
+
const DEFAULT_STREAMING_FALLBACK_LABEL = "Generating";
|
|
1967
|
+
const DEFAULT_STREAMING_CANCEL_HINT = "Esc to cancel";
|
|
1968
|
+
const indicatorKey = new PluginKey(
|
|
1969
|
+
"CREPE_AI_STREAMING_INDICATOR"
|
|
1970
|
+
);
|
|
1971
|
+
class IndicatorWidget {
|
|
1972
|
+
constructor(ctx, fallbackLabel, cancelHint) {
|
|
1973
|
+
__privateAdd$7(this, _spinner);
|
|
1974
|
+
__privateAdd$7(this, _label);
|
|
1975
|
+
__privateAdd$7(this, _fallbackLabel);
|
|
1976
|
+
__privateAdd$7(this, _start, performance.now());
|
|
1977
|
+
__privateAdd$7(this, _lastLabelText, "");
|
|
1978
|
+
__privateAdd$7(this, _rafId, 0);
|
|
1979
|
+
__privateAdd$7(this, _tick, () => {
|
|
1980
|
+
const elapsed = performance.now() - __privateGet$7(this, _start);
|
|
1981
|
+
const angle = elapsed / SPINNER_PERIOD_MS * 360;
|
|
1982
|
+
__privateGet$7(this, _spinner).style.transform = `rotate(${angle}deg)`;
|
|
1983
|
+
__privateSet$7(this, _rafId, requestAnimationFrame(__privateGet$7(this, _tick)));
|
|
1984
|
+
});
|
|
1985
|
+
__privateSet$7(this, _fallbackLabel, fallbackLabel);
|
|
1986
|
+
const dom = document.createElement("span");
|
|
1987
|
+
dom.className = `${CLASS_PREFIX}-indicator`;
|
|
1988
|
+
dom.contentEditable = "false";
|
|
1989
|
+
dom.setAttribute("role", "status");
|
|
1990
|
+
dom.setAttribute("aria-live", "polite");
|
|
1991
|
+
const spinner = document.createElement("span");
|
|
1992
|
+
spinner.className = `${CLASS_PREFIX}-spinner`;
|
|
1993
|
+
spinner.setAttribute("aria-hidden", "true");
|
|
1994
|
+
dom.appendChild(spinner);
|
|
1995
|
+
const label = document.createElement("span");
|
|
1996
|
+
label.className = `${CLASS_PREFIX}-label`;
|
|
1997
|
+
dom.appendChild(label);
|
|
1998
|
+
const escHint = document.createElement("span");
|
|
1999
|
+
escHint.className = `${CLASS_PREFIX}-esc`;
|
|
2000
|
+
escHint.textContent = cancelHint;
|
|
2001
|
+
dom.appendChild(escHint);
|
|
2002
|
+
this.dom = dom;
|
|
2003
|
+
__privateSet$7(this, _spinner, spinner);
|
|
2004
|
+
__privateSet$7(this, _label, label);
|
|
2005
|
+
this.setLabel(ctx);
|
|
2006
|
+
__privateGet$7(this, _tick).call(this);
|
|
2007
|
+
}
|
|
2008
|
+
setLabel(ctx) {
|
|
2009
|
+
const session = ctx.get(aiSessionCtx.key);
|
|
2010
|
+
const text = `${session.label || __privateGet$7(this, _fallbackLabel)}\u2026`;
|
|
2011
|
+
if (text === __privateGet$7(this, _lastLabelText)) return;
|
|
2012
|
+
__privateSet$7(this, _lastLabelText, text);
|
|
2013
|
+
__privateGet$7(this, _label).textContent = text;
|
|
2014
|
+
}
|
|
2015
|
+
destroy() {
|
|
2016
|
+
if (__privateGet$7(this, _rafId)) cancelAnimationFrame(__privateGet$7(this, _rafId));
|
|
2017
|
+
__privateSet$7(this, _rafId, 0);
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
_spinner = new WeakMap();
|
|
2021
|
+
_label = new WeakMap();
|
|
2022
|
+
_fallbackLabel = new WeakMap();
|
|
2023
|
+
_start = new WeakMap();
|
|
2024
|
+
_lastLabelText = new WeakMap();
|
|
2025
|
+
_rafId = new WeakMap();
|
|
2026
|
+
_tick = new WeakMap();
|
|
2027
|
+
function streamingIndicatorPlugin(options = {}) {
|
|
2028
|
+
var _a, _b;
|
|
2029
|
+
const { config } = options;
|
|
2030
|
+
const fallbackLabel = (_a = config == null ? void 0 : config.fallbackLabel) != null ? _a : DEFAULT_STREAMING_FALLBACK_LABEL;
|
|
2031
|
+
const cancelHint = (_b = config == null ? void 0 : config.cancelHint) != null ? _b : DEFAULT_STREAMING_CANCEL_HINT;
|
|
2032
|
+
return $prose((ctx) => {
|
|
2033
|
+
let widget = null;
|
|
2034
|
+
function ensureWidget() {
|
|
2035
|
+
if (!widget) widget = new IndicatorWidget(ctx, fallbackLabel, cancelHint);
|
|
2036
|
+
else widget.setLabel(ctx);
|
|
2037
|
+
return widget;
|
|
2038
|
+
}
|
|
2039
|
+
function dropWidget() {
|
|
2040
|
+
if (widget) {
|
|
2041
|
+
widget.destroy();
|
|
2042
|
+
widget = null;
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
function buildSet(doc, insertEndPos) {
|
|
2046
|
+
const pos = Math.min(insertEndPos, doc.content.size);
|
|
2047
|
+
const decoration = Decoration.widget(pos, ensureWidget().dom, {
|
|
2048
|
+
side: 1,
|
|
2049
|
+
key: "ai-streaming-indicator"
|
|
2050
|
+
});
|
|
2051
|
+
return DecorationSet.create(doc, [decoration]);
|
|
2052
|
+
}
|
|
2053
|
+
return new Plugin({
|
|
2054
|
+
key: indicatorKey,
|
|
2055
|
+
state: {
|
|
2056
|
+
init: () => DecorationSet.empty,
|
|
2057
|
+
apply(tr, decorations, _oldState, newState) {
|
|
2058
|
+
const streaming = streamingPluginKey.getState(newState);
|
|
2059
|
+
if (!(streaming == null ? void 0 : streaming.active) || streaming.insertEndPos == null) {
|
|
2060
|
+
dropWidget();
|
|
2061
|
+
return DecorationSet.empty;
|
|
2062
|
+
}
|
|
2063
|
+
if (tr.getMeta(streamingPluginKey) || tr.docChanged) {
|
|
2064
|
+
return buildSet(newState.doc, streaming.insertEndPos);
|
|
2065
|
+
}
|
|
2066
|
+
return decorations.map(tr.mapping, tr.doc);
|
|
2067
|
+
}
|
|
2068
|
+
},
|
|
2069
|
+
view() {
|
|
2070
|
+
return {
|
|
2071
|
+
destroy() {
|
|
2072
|
+
dropWidget();
|
|
2073
|
+
}
|
|
2074
|
+
};
|
|
2075
|
+
},
|
|
2076
|
+
props: {
|
|
2077
|
+
decorations(state) {
|
|
2078
|
+
var _a2;
|
|
2079
|
+
return (_a2 = indicatorKey.getState(state)) != null ? _a2 : DecorationSet.empty;
|
|
2080
|
+
},
|
|
2081
|
+
handleKeyDown(view, event) {
|
|
2082
|
+
var _a2;
|
|
2083
|
+
if (event.key !== "Escape") return false;
|
|
2084
|
+
const commands = ctx.get(commandsCtx);
|
|
2085
|
+
if (ctx.get(aiSessionCtx.key).abortController) {
|
|
2086
|
+
event.preventDefault();
|
|
2087
|
+
commands.call(abortAICmd.key, { keep: true });
|
|
2088
|
+
return true;
|
|
2089
|
+
}
|
|
2090
|
+
if ((_a2 = streamingPluginKey.getState(view.state)) == null ? void 0 : _a2.active) {
|
|
2091
|
+
event.preventDefault();
|
|
2092
|
+
commands.call(abortStreamingCmd.key, { keep: true });
|
|
2093
|
+
return true;
|
|
2094
|
+
}
|
|
2095
|
+
return false;
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
});
|
|
2099
|
+
});
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2102
|
+
const CREPE_CUSTOM_BLOCK_TYPES = ["table", "image-block", "code_block"];
|
|
2103
|
+
const CREPE_IGNORE_ATTRS = { heading: ["id"] };
|
|
2104
|
+
const ai = (editor, config) => {
|
|
2105
|
+
var _a, _b;
|
|
2106
|
+
const diffCfg = (_a = config == null ? void 0 : config.diff) != null ? _a : {};
|
|
2107
|
+
const streamingCfg = (_b = config == null ? void 0 : config.streaming) != null ? _b : {};
|
|
2108
|
+
editor.config(crepeFeatureConfig(CrepeFeature.AI)).config((ctx) => {
|
|
2109
|
+
ctx.update(diffConfig.key, (prev) => {
|
|
2110
|
+
var _a2;
|
|
2111
|
+
return {
|
|
2112
|
+
...prev,
|
|
2113
|
+
ignoreAttrs: (_a2 = diffCfg.ignoreAttrs) != null ? _a2 : CREPE_IGNORE_ATTRS
|
|
2114
|
+
};
|
|
2115
|
+
});
|
|
2116
|
+
const { ignoreAttrs: _, ...componentConfig } = diffCfg;
|
|
2117
|
+
ctx.update(diffComponentConfig.key, (prev) => {
|
|
2118
|
+
var _a2;
|
|
2119
|
+
return {
|
|
2120
|
+
...prev,
|
|
2121
|
+
customBlockTypes: (_a2 = componentConfig.customBlockTypes) != null ? _a2 : CREPE_CUSTOM_BLOCK_TYPES,
|
|
2122
|
+
...componentConfig
|
|
2123
|
+
};
|
|
2124
|
+
});
|
|
2125
|
+
}).use(diff).use(diffComponent).config((ctx) => {
|
|
2126
|
+
ctx.update(streamingConfig.key, (prev) => {
|
|
2127
|
+
var _a2;
|
|
2128
|
+
return {
|
|
2129
|
+
...prev,
|
|
2130
|
+
...streamingCfg,
|
|
2131
|
+
ignoreAttrs: (_a2 = streamingCfg.ignoreAttrs) != null ? _a2 : CREPE_IGNORE_ATTRS,
|
|
2132
|
+
// Wire diffReviewOnEnd into the streaming plugin so manual
|
|
2133
|
+
// endStreamingCmd calls (outside runAICmd) also respect it.
|
|
2134
|
+
// Only override if the user explicitly set it — otherwise
|
|
2135
|
+
// keep the streaming plugin's own default so tests and
|
|
2136
|
+
// manual-streaming use cases aren't surprised.
|
|
2137
|
+
...(config == null ? void 0 : config.diffReviewOnEnd) !== void 0 ? { diffReviewOnEnd: config.diffReviewOnEnd } : {}
|
|
2138
|
+
};
|
|
2139
|
+
});
|
|
2140
|
+
}).use(streaming).config((ctx) => {
|
|
2141
|
+
ctx.update(aiProviderConfig.key, (prev) => {
|
|
2142
|
+
var _a2;
|
|
2143
|
+
return {
|
|
2144
|
+
...prev,
|
|
2145
|
+
...(config == null ? void 0 : config.provider) !== void 0 ? { provider: config.provider } : {},
|
|
2146
|
+
...(config == null ? void 0 : config.buildContext) !== void 0 ? { buildContext: config.buildContext } : {},
|
|
2147
|
+
diffReviewOnEnd: (_a2 = config == null ? void 0 : config.diffReviewOnEnd) != null ? _a2 : prev.diffReviewOnEnd,
|
|
2148
|
+
...(config == null ? void 0 : config.onError) !== void 0 ? { onError: config.onError } : {},
|
|
2149
|
+
...(config == null ? void 0 : config.aiIcon) !== void 0 ? { aiIcon: config.aiIcon } : {}
|
|
2150
|
+
};
|
|
2151
|
+
});
|
|
2152
|
+
}).use(aiProviderConfig).use(aiSessionCtx).use(runAICmd).use(abortAICmd).config(configureAIInstructionTooltip(config)).use(aiInstructionTooltipAPI).use(aiInstructionTooltip).use(streamingIndicatorPlugin({ config: config == null ? void 0 : config.streamingIndicator })).use(
|
|
2153
|
+
diffActionsPanelPlugin({
|
|
2154
|
+
config: config == null ? void 0 : config.diffActions,
|
|
2155
|
+
enterKeyIcon: config == null ? void 0 : config.enterKeyIcon
|
|
2156
|
+
})
|
|
2157
|
+
);
|
|
2158
|
+
};
|
|
2159
|
+
|
|
777
2160
|
function isInCodeBlock(selection) {
|
|
778
2161
|
const type = selection.$from.parent.type;
|
|
779
2162
|
return type.name === "code_block";
|
|
@@ -837,9 +2220,6 @@ class GroupBuilder {
|
|
|
837
2220
|
_groups = new WeakMap();
|
|
838
2221
|
_getGroupInstance = new WeakMap();
|
|
839
2222
|
|
|
840
|
-
function keepAlive(..._args) {
|
|
841
|
-
}
|
|
842
|
-
|
|
843
2223
|
function getGroups$2(filter, config, ctx) {
|
|
844
2224
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb;
|
|
845
2225
|
const flags = ctx && useCrepeFeatures(ctx).get();
|
|
@@ -1830,6 +3210,7 @@ class LatexInlineTooltip {
|
|
|
1830
3210
|
});
|
|
1831
3211
|
__privateAdd$3(this, _shouldShow, (view) => {
|
|
1832
3212
|
const shouldShow = () => {
|
|
3213
|
+
if (!view.editable) return false;
|
|
1833
3214
|
const { selection, schema } = view.state;
|
|
1834
3215
|
if (selection.empty) return false;
|
|
1835
3216
|
if (!(selection instanceof NodeSelection)) return false;
|
|
@@ -2130,7 +3511,7 @@ const table = (editor, config) => {
|
|
|
2130
3511
|
};
|
|
2131
3512
|
|
|
2132
3513
|
function getGroups$1(config, ctx) {
|
|
2133
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
3514
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
2134
3515
|
const groupBuilder = new GroupBuilder();
|
|
2135
3516
|
groupBuilder.addGroup("formatting", "Formatting").addItem("bold", {
|
|
2136
3517
|
icon: (_a = config == null ? void 0 : config.boldIcon) != null ? _a : boldIcon,
|
|
@@ -2213,7 +3594,22 @@ function getGroups$1(config, ctx) {
|
|
|
2213
3594
|
commands.call(toggleLinkCommand.key);
|
|
2214
3595
|
}
|
|
2215
3596
|
});
|
|
2216
|
-
(
|
|
3597
|
+
if (ctx && (flags == null ? void 0 : flags.includes(CrepeFeature.AI))) {
|
|
3598
|
+
const aiCfg = ctx.get(aiProviderConfig.key);
|
|
3599
|
+
if (aiCfg.provider) {
|
|
3600
|
+
functionGroup.addItem("ai", {
|
|
3601
|
+
icon: (_h = (_g = config == null ? void 0 : config.aiIcon) != null ? _g : aiCfg.aiIcon) != null ? _h : aiIcon,
|
|
3602
|
+
active: () => false,
|
|
3603
|
+
onRun: (ctx2) => {
|
|
3604
|
+
const api = ctx2.get(aiInstructionTooltipAPI.key);
|
|
3605
|
+
const view = ctx2.get(editorViewCtx);
|
|
3606
|
+
const { from, to } = view.state.selection;
|
|
3607
|
+
api.show(from, to);
|
|
3608
|
+
}
|
|
3609
|
+
});
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
(_i = config == null ? void 0 : config.buildToolbar) == null ? void 0 : _i.call(config, groupBuilder);
|
|
2217
3613
|
return groupBuilder.build();
|
|
2218
3614
|
}
|
|
2219
3615
|
|
|
@@ -2836,6 +4232,9 @@ function loadFeature(feature, editor, config) {
|
|
|
2836
4232
|
case CrepeFeature.TopBar: {
|
|
2837
4233
|
return topBar(editor, config);
|
|
2838
4234
|
}
|
|
4235
|
+
case CrepeFeature.AI: {
|
|
4236
|
+
return ai(editor, config);
|
|
4237
|
+
}
|
|
2839
4238
|
}
|
|
2840
4239
|
}
|
|
2841
4240
|
|