@plannotator/ui 0.28.0 → 0.29.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/README.md +6 -0
- package/components/AISettingsTab.tsx +5 -4
- package/components/ActionMenu.tsx +5 -1
- package/components/AgentsTab.tsx +10 -23
- package/components/AnnotationPanel.tsx +9 -5
- package/components/AnnotationToolbar.tsx +5 -13
- package/components/AnnotationToolstrip.tsx +2 -2
- package/components/ApproveDropdown.tsx +1 -1
- package/components/BlockRenderer.tsx +1 -1
- package/components/CodeFilePopout.tsx +5 -4
- package/components/CommentPopover.tsx +391 -65
- package/components/DocBadges.tsx +29 -11
- package/components/ExportModal.tsx +16 -8
- package/components/GraphvizBlock.tsx +1 -1
- package/components/InlineMarkdown.tsx +30 -13
- package/components/KeyboardShortcuts.tsx +37 -2
- package/components/Landing.tsx +7 -7
- package/components/MenuVersionSection.tsx +4 -4
- package/components/MermaidBlock.tsx +1 -1
- package/components/ModeToggle.tsx +7 -6
- package/components/OpenInAppButton.tsx +2 -5
- package/components/PinpointOverlay.tsx +9 -7
- package/components/PlanHeaderMenu.tsx +8 -8
- package/components/PopoutDialog.tsx +6 -1
- package/components/ResizeHandle.tsx +1 -0
- package/components/Settings.tsx +172 -12
- package/components/SkillReferenceMenu.tsx +260 -0
- package/components/StickyHeaderLane.tsx +7 -0
- package/components/ThemeProvider.tsx +131 -32
- package/components/ThemeTab.tsx +123 -77
- package/components/ToolbarButtons.tsx +29 -8
- package/components/Viewer.tsx +396 -130
- package/components/VimKeyHud.tsx +695 -0
- package/components/VimModeAnnouncementDialog.tsx +557 -0
- package/components/VimModeOverlay.tsx +235 -0
- package/components/VimTargetReticle.tsx +284 -0
- package/components/ai/DocumentAIChatPanel.tsx +1 -1
- package/components/blocks/CodeBlock.tsx +18 -18
- package/components/blocks/TablePopout.tsx +7 -8
- package/components/blocks/TableToolbar.tsx +7 -8
- package/components/goal-setup/GoalSetupSurface.tsx +16 -3
- package/components/html-viewer/HtmlViewer.tsx +450 -47
- package/components/html-viewer/annotationNumbering.ts +37 -0
- package/components/html-viewer/bridge-script.ts +4051 -298
- package/components/html-viewer/composerYield.ts +51 -0
- package/components/html-viewer/srcdoc.ts +18 -3
- package/components/html-viewer/useHtmlAnnotation.ts +457 -32
- package/components/icons/themeIcons.tsx +1 -1
- package/components/plan-diff/PlanCleanDiffView.tsx +9 -9
- package/components/plan-diff/PlanDiffBadge.tsx +22 -1
- package/components/settings/HooksTab.tsx +12 -8
- package/components/sidebar/FileBrowser.tsx +4 -1
- package/components/themeModes.tsx +28 -0
- package/config/configStore.ts +76 -1
- package/config/settings.ts +152 -0
- package/configure.ts +9 -0
- package/globals.d.ts +7 -1
- package/hooks/useAIChat.ts +5 -2
- package/hooks/useAIProviderActivation.ts +47 -0
- package/hooks/useAIProviderConfig.ts +5 -1
- package/hooks/useAgentSettings.ts +64 -23
- package/hooks/useAgents.ts +4 -4
- package/hooks/useAnnotationHighlighter.ts +100 -3
- package/hooks/useArchive.ts +2 -1
- package/hooks/useFenceTheme.ts +17 -0
- package/hooks/useLinkedDoc.ts +68 -1
- package/hooks/usePinpoint.ts +76 -75
- package/hooks/usePlanDiff.ts +73 -2
- package/hooks/useSkillReferenceAutocomplete.ts +239 -0
- package/hooks/useUpdateCheck.ts +1 -2
- package/hooks/useVimDocumentFocus.ts +116 -0
- package/hooks/useVimSelection.ts +1063 -0
- package/package.json +4 -4
- package/print.css +14 -13
- package/shortcuts/core.ts +38 -13
- package/shortcuts/index.ts +10 -0
- package/shortcuts/plan-review/commentPopover.shortcuts.ts +7 -0
- package/shortcuts/plan-review/vimSelection.shortcuts.ts +251 -0
- package/shortcuts/runtime.ts +111 -12
- package/styles.css +1 -1
- package/theme.css +504 -0
- package/themes/colorblind.css +89 -0
- package/themes/plannotator.css +2 -2
- package/types.ts +93 -10
- package/utils/agentSwitch.ts +33 -7
- package/utils/blockTargeting.ts +462 -178
- package/utils/clipboard.ts +110 -0
- package/utils/codeBlockMark.ts +50 -0
- package/utils/codeHighlight.ts +293 -0
- package/utils/codexModels.ts +79 -0
- package/utils/domSelection.ts +84 -0
- package/utils/htmlChrome.ts +73 -0
- package/utils/inputMethod.ts +79 -6
- package/utils/parser.ts +517 -21
- package/utils/preferenceTtl.ts +15 -0
- package/utils/sharing.ts +0 -1
- package/utils/skillCatalog.ts +269 -0
- package/utils/skillReferences.ts +475 -0
- package/utils/syntaxTheme.ts +83 -0
- package/utils/themeRegistry.ts +154 -0
- package/utils/vimHud.ts +263 -0
- package/utils/vimModeAnnouncement.ts +23 -0
- package/utils/vimNavigation.ts +417 -0
- package/utils/vimReticle.ts +88 -0
- package/utils/vimScroll.ts +162 -0
package/README.md
CHANGED
|
@@ -24,6 +24,8 @@ configurePlannotatorUI({
|
|
|
24
24
|
draftTransport,
|
|
25
25
|
externalAnnotationTransport, // live/agent comments
|
|
26
26
|
aiTransport,
|
|
27
|
+
skillCatalogTransport, // skill-reference catalog for comment composers
|
|
28
|
+
skillContentTransport, // human-only skill contents for feedback injection
|
|
27
29
|
serverSync,
|
|
28
30
|
});
|
|
29
31
|
```
|
|
@@ -78,6 +80,10 @@ Requires `@plannotator/markdown-editor ^0.3.2` and `@plannotator/atomic-editor ^
|
|
|
78
80
|
|
|
79
81
|
Requires `@plannotator/markdown-editor ^0.4.0` and `@plannotator/atomic-editor ^0.8.0` (which adds a `@codemirror/merge` peer — declared by this package). See HANDOFF.md § "Frozen markdown diff (0.28.0)".
|
|
80
82
|
|
|
83
|
+
### Raw-HTML annotation viewer (`HtmlViewer`)
|
|
84
|
+
|
|
85
|
+
`components/html-viewer` is supported host surface as of 0.29.0: the overlay-projection annotation viewer for raw HTML (placed comment markers, pinpoint element anchors, shift-click multi-target comments). Its contract is **props plus the validated iframe message protocol** — not `configurePlannotatorUI()`, which only governs the backend surfaces around it. Drive the `annotations` prop (marker numbering derives from its array order); `readOnly` keeps markers painted and clickable while disabling all authoring. **0.29.0 also carries a breaking migration:** highlight.js is gone and `.hljs` selectors are inert — style code via the exported `pn-code` class (`CODE_BLOCK_CLASS` in `utils/codeHighlight`). See HANDOFF.md § "Raw-HTML annotation viewer + syntax-highlighting migration (0.29.0)" before upgrading from 0.28.0.
|
|
86
|
+
|
|
81
87
|
## Consuming it (e.g. from Workspaces)
|
|
82
88
|
|
|
83
89
|
```bash
|
|
@@ -2,7 +2,6 @@ import type React from 'react';
|
|
|
2
2
|
import { getProviderMeta } from './ProviderIcons';
|
|
3
3
|
import {
|
|
4
4
|
getAIProviderSettings,
|
|
5
|
-
resolveAIModelForProvider,
|
|
6
5
|
resolveAIProviderSelection,
|
|
7
6
|
saveAIProviderSelection,
|
|
8
7
|
savePreferredModel,
|
|
@@ -37,9 +36,11 @@ export const AISettingsTab: React.FC<AISettingsTabProps> = ({
|
|
|
37
36
|
|
|
38
37
|
const handleSelectProvider = (providerId: string) => {
|
|
39
38
|
onProviderChange(providerId);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
// Persist only the provider choice. Writing the resolved model here would
|
|
40
|
+
// clobber a saved preference the currently-advertised model list doesn't
|
|
41
|
+
// include (e.g. before deferred Codex discovery has run) with the static
|
|
42
|
+
// fallback id — the saved model only changes when the user picks one.
|
|
43
|
+
saveAIProviderSelection({ providerId, model: null, origin });
|
|
43
44
|
};
|
|
44
45
|
|
|
45
46
|
const handleModelChange = (providerId: string, modelId: string) => {
|
|
@@ -3,6 +3,7 @@ import React, { useEffect, useRef, useState } from 'react';
|
|
|
3
3
|
interface ActionMenuProps {
|
|
4
4
|
className?: string;
|
|
5
5
|
panelClassName?: string;
|
|
6
|
+
panelWidth?: 'default' | 'wide';
|
|
6
7
|
renderTrigger: (props: {
|
|
7
8
|
isOpen: boolean;
|
|
8
9
|
toggleMenu: () => void;
|
|
@@ -13,6 +14,7 @@ interface ActionMenuProps {
|
|
|
13
14
|
export const ActionMenu: React.FC<ActionMenuProps> = ({
|
|
14
15
|
className,
|
|
15
16
|
panelClassName,
|
|
17
|
+
panelWidth = 'default',
|
|
16
18
|
renderTrigger,
|
|
17
19
|
children,
|
|
18
20
|
}) => {
|
|
@@ -50,7 +52,9 @@ export const ActionMenu: React.FC<ActionMenuProps> = ({
|
|
|
50
52
|
})}
|
|
51
53
|
|
|
52
54
|
{isOpen && (
|
|
53
|
-
<div
|
|
55
|
+
<div
|
|
56
|
+
className={panelClassName ?? `absolute top-full right-0 mt-1 ${panelWidth === 'wide' ? 'w-64' : 'w-56'} rounded-lg border border-border bg-popover py-1 shadow-xl z-[70]`}
|
|
57
|
+
>
|
|
54
58
|
{children({ closeMenu: () => setIsOpen(false) })}
|
|
55
59
|
</div>
|
|
56
60
|
)}
|
package/components/AgentsTab.tsx
CHANGED
|
@@ -22,6 +22,7 @@ import { useAgentSettings } from '../hooks/useAgentSettings';
|
|
|
22
22
|
import type { AgentEngine, AgentMode, ReviewEngine } from '../hooks/useAgentSettings';
|
|
23
23
|
import type { AgentLaunchParams } from '../hooks/useAgentJobs';
|
|
24
24
|
import { ConfigRow, SegmentedPicker, Toggle, SelectMenu } from './AgentControls';
|
|
25
|
+
import { CODEX_MODELS, CODEX_EFFORT_LABELS, codexReasoningOptions } from '../utils/codexModels';
|
|
25
26
|
|
|
26
27
|
export type { AgentLaunchParams } from '../hooks/useAgentJobs';
|
|
27
28
|
|
|
@@ -29,6 +30,7 @@ export type { AgentLaunchParams } from '../hooks/useAgentJobs';
|
|
|
29
30
|
|
|
30
31
|
export const CLAUDE_MODELS: Array<{ value: string; label: string }> = [
|
|
31
32
|
{ value: 'claude-fable-5', label: 'Fable 5' },
|
|
33
|
+
{ value: 'claude-opus-5', label: 'Opus 5' },
|
|
32
34
|
{ value: 'claude-opus-4-8', label: 'Opus 4.8' },
|
|
33
35
|
{ value: 'claude-opus-4-8[1m]', label: 'Opus 4.8 (1M)' },
|
|
34
36
|
{ value: 'claude-sonnet-5', label: 'Sonnet 5' },
|
|
@@ -49,25 +51,10 @@ export const CLAUDE_EFFORT: Array<{ value: string; label: string }> = [
|
|
|
49
51
|
{ value: 'max', label: 'Max' },
|
|
50
52
|
];
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
{ value: 'gpt-5.3-codex-spark', label: 'GPT-5.3 Codex Spark' },
|
|
57
|
-
{ value: 'gpt-5.2-codex', label: 'GPT-5.2 Codex' },
|
|
58
|
-
{ value: 'gpt-5.2', label: 'GPT-5.2' },
|
|
59
|
-
{ value: 'gpt-5.1-codex-max', label: 'GPT-5.1 Codex Max' },
|
|
60
|
-
{ value: 'gpt-5.1-codex-mini', label: 'GPT-5.1 Codex Mini' },
|
|
61
|
-
{ value: 'gpt-5.4-mini', label: 'GPT-5.4 Mini' },
|
|
62
|
-
];
|
|
63
|
-
|
|
64
|
-
export const CODEX_REASONING: Array<{ value: string; label: string }> = [
|
|
65
|
-
{ value: 'minimal', label: 'Minimal' },
|
|
66
|
-
{ value: 'low', label: 'Low' },
|
|
67
|
-
{ value: 'medium', label: 'Medium' },
|
|
68
|
-
{ value: 'high', label: 'High' },
|
|
69
|
-
{ value: 'xhigh', label: 'XHigh' },
|
|
70
|
-
];
|
|
54
|
+
// Codex model catalog + per-model reasoning efforts live in
|
|
55
|
+
// utils/codexModels (useAgentSettings needs them too, for effort clamping);
|
|
56
|
+
// re-exported here so both launch surfaces keep one import site.
|
|
57
|
+
export { CODEX_MODELS, codexReasoningOptions } from '../utils/codexModels';
|
|
71
58
|
|
|
72
59
|
// Tour/guide Claude catalog: the CLI's latest-resolving aliases on top
|
|
73
60
|
// (verified against `claude --help`: "Provide an alias for the latest model
|
|
@@ -270,7 +257,7 @@ function formatEffort(value: string): string {
|
|
|
270
257
|
}
|
|
271
258
|
|
|
272
259
|
function formatReasoning(value: string): string {
|
|
273
|
-
return
|
|
260
|
+
return CODEX_EFFORT_LABELS[value] ?? value;
|
|
274
261
|
}
|
|
275
262
|
|
|
276
263
|
// --- Add-a-review dialog: a type-ahead picker over every discovered skill ---
|
|
@@ -1112,7 +1099,7 @@ export const AgentsTab: React.FC<AgentsTabProps> = ({
|
|
|
1112
1099
|
<SelectMenu value={codexModel} options={CODEX_MODELS} onChange={setCodexModel} />
|
|
1113
1100
|
</ConfigRow>
|
|
1114
1101
|
<ConfigRow label="Reasoning" stacked>
|
|
1115
|
-
<SegmentedPicker options={
|
|
1102
|
+
<SegmentedPicker options={codexReasoningOptions(codexModel)} value={codexReasoning} onChange={setCodexReasoning} />
|
|
1116
1103
|
</ConfigRow>
|
|
1117
1104
|
<ConfigRow label="Fast mode">
|
|
1118
1105
|
<Toggle checked={codexFast} onChange={setCodexFast} />
|
|
@@ -1155,7 +1142,7 @@ export const AgentsTab: React.FC<AgentsTabProps> = ({
|
|
|
1155
1142
|
{tourEngine === 'codex' && (
|
|
1156
1143
|
<>
|
|
1157
1144
|
<ConfigRow label="Reasoning" stacked>
|
|
1158
|
-
<SegmentedPicker options={
|
|
1145
|
+
<SegmentedPicker options={codexReasoningOptions(tourCodexModel)} value={tourCodexReasoning} onChange={setTourCodexReasoning} />
|
|
1159
1146
|
</ConfigRow>
|
|
1160
1147
|
<ConfigRow label="Fast mode">
|
|
1161
1148
|
<Toggle checked={tourCodexFast} onChange={setTourCodexFast} />
|
|
@@ -1190,7 +1177,7 @@ export const AgentsTab: React.FC<AgentsTabProps> = ({
|
|
|
1190
1177
|
deliberately not offered for guide. */}
|
|
1191
1178
|
{guideEngine === 'codex' && (
|
|
1192
1179
|
<ConfigRow label="Reasoning" stacked>
|
|
1193
|
-
<SegmentedPicker options={
|
|
1180
|
+
<SegmentedPicker options={codexReasoningOptions(guideCodexModel)} value={guideCodexReasoning} onChange={setGuideCodexReasoning} />
|
|
1194
1181
|
</ConfigRow>
|
|
1195
1182
|
)}
|
|
1196
1183
|
|
|
@@ -66,7 +66,10 @@ interface PanelProps {
|
|
|
66
66
|
editorAnnotations?: EditorAnnotation[];
|
|
67
67
|
onDeleteEditorAnnotation?: (id: string) => void;
|
|
68
68
|
onClose?: () => void;
|
|
69
|
-
|
|
69
|
+
/** Copy the full feedback payload. May resolve a success boolean; resolving
|
|
70
|
+
* `false` suppresses the "Copied" flash. A void resolution (existing hosts)
|
|
71
|
+
* is treated as success, preserving the original behavior. */
|
|
72
|
+
onQuickCopy?: () => Promise<void | boolean>;
|
|
70
73
|
onShare?: () => void;
|
|
71
74
|
otherFileAnnotations?: { count: number; files: number };
|
|
72
75
|
onOtherFileAnnotationsClick?: () => void;
|
|
@@ -77,7 +80,7 @@ interface PanelProps {
|
|
|
77
80
|
* resolve UI). The panel stays presentation-only; clicks inside the slot
|
|
78
81
|
* do not select the card. Default: nothing rendered. */
|
|
79
82
|
renderCardFooter?: (annotation: Annotation) => React.ReactNode;
|
|
80
|
-
/** Hide every mutation affordance (delete/edit
|
|
83
|
+
/** Hide every mutation affordance (delete/edit, direct-edit discard, and host card footers).
|
|
81
84
|
* Selection and scrolling still work. Default false — today's behavior. */
|
|
82
85
|
readOnly?: boolean;
|
|
83
86
|
}
|
|
@@ -178,7 +181,7 @@ export const AnnotationPanel: React.FC<PanelProps> = ({
|
|
|
178
181
|
<OverlayScrollArea className="flex-1 min-h-0">
|
|
179
182
|
<div ref={listRef} className="p-2 flex flex-col gap-1.5">
|
|
180
183
|
{directEdits?.map((item) => (
|
|
181
|
-
<DirectEditsCard key={item.id} {...item} />
|
|
184
|
+
<DirectEditsCard key={item.id} {...item} onDiscard={readOnly ? undefined : item.onDiscard} />
|
|
182
185
|
))}
|
|
183
186
|
{totalCount === 0 ? (
|
|
184
187
|
(!directEdits || directEdits.length === 0) && (
|
|
@@ -204,7 +207,7 @@ export const AnnotationPanel: React.FC<PanelProps> = ({
|
|
|
204
207
|
onDelete={() => onDelete(entry.annotation.id)}
|
|
205
208
|
onEdit={onEdit ? (updates: Partial<Annotation>) => onEdit(entry.annotation.id, updates) : undefined}
|
|
206
209
|
readOnly={readOnly}
|
|
207
|
-
footer={renderCardFooter?.(entry.annotation)}
|
|
210
|
+
footer={readOnly ? undefined : renderCardFooter?.(entry.annotation)}
|
|
208
211
|
/>
|
|
209
212
|
) : (
|
|
210
213
|
<CodeAnnotationCard
|
|
@@ -249,7 +252,8 @@ export const AnnotationPanel: React.FC<PanelProps> = ({
|
|
|
249
252
|
{onQuickCopy && (
|
|
250
253
|
<button
|
|
251
254
|
onClick={async () => {
|
|
252
|
-
await onQuickCopy();
|
|
255
|
+
const result = await onQuickCopy();
|
|
256
|
+
if (result === false) return;
|
|
253
257
|
setCopiedText(true);
|
|
254
258
|
setTimeout(() => setCopiedText(false), 2000);
|
|
255
259
|
}}
|
|
@@ -3,6 +3,7 @@ import { AnnotationType } from "../types";
|
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
4
|
import { useDismissOnOutsideAndEscape } from "../hooks/useDismissOnOutsideAndEscape";
|
|
5
5
|
import { type QuickLabel, getQuickLabels } from "../utils/quickLabels";
|
|
6
|
+
import { copyTextToClipboard } from "../utils/clipboard";
|
|
6
7
|
import { FloatingQuickLabelPicker } from "./FloatingQuickLabelPicker";
|
|
7
8
|
|
|
8
9
|
type PositionMode = 'center-above' | 'top-right';
|
|
@@ -72,19 +73,10 @@ export const AnnotationToolbar: React.FC<AnnotationToolbarProps> = ({
|
|
|
72
73
|
const codeEl = element.querySelector('code');
|
|
73
74
|
textToCopy = codeEl?.textContent || element.textContent || '';
|
|
74
75
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const textarea = document.createElement('textarea');
|
|
79
|
-
textarea.value = textToCopy;
|
|
80
|
-
textarea.style.cssText = 'position:fixed;opacity:0';
|
|
81
|
-
document.body.appendChild(textarea);
|
|
82
|
-
textarea.select();
|
|
83
|
-
document.execCommand('copy');
|
|
84
|
-
textarea.remove();
|
|
76
|
+
if (await copyTextToClipboard(textToCopy)) {
|
|
77
|
+
setCopied(true);
|
|
78
|
+
setTimeout(() => setCopied(false), 1500);
|
|
85
79
|
}
|
|
86
|
-
setCopied(true);
|
|
87
|
-
setTimeout(() => setCopied(false), 1500);
|
|
88
80
|
};
|
|
89
81
|
|
|
90
82
|
// Update position on scroll/resize
|
|
@@ -123,7 +115,7 @@ export const AnnotationToolbar: React.FC<AnnotationToolbarProps> = ({
|
|
|
123
115
|
// Type-to-comment + Alt+N / bare digit quick label shortcuts
|
|
124
116
|
useEffect(() => {
|
|
125
117
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
126
|
-
if (e.isComposing) return;
|
|
118
|
+
if (e.defaultPrevented || e.isComposing) return;
|
|
127
119
|
if (isEditableElement(e.target) || isEditableElement(document.activeElement)) return;
|
|
128
120
|
|
|
129
121
|
// When picker is open, let FloatingQuickLabelPicker own all keyboard input
|
|
@@ -210,8 +210,8 @@ export const AnnotationToolstrip: React.FC<AnnotationToolstripProps> = ({
|
|
|
210
210
|
width="100%"
|
|
211
211
|
height="100%"
|
|
212
212
|
src={helpTab === 'selection'
|
|
213
|
-
? 'https://www.youtube.com/embed/ZNt9jtfx9TY?autoplay=1'
|
|
214
|
-
: 'https://www.youtube.com/embed/a_AT7cEN_9I?autoplay=1'
|
|
213
|
+
? 'https://www.youtube-nocookie.com/embed/ZNt9jtfx9TY?autoplay=1'
|
|
214
|
+
: 'https://www.youtube-nocookie.com/embed/a_AT7cEN_9I?autoplay=1'
|
|
215
215
|
}
|
|
216
216
|
title={helpTab === 'selection' ? 'How Selection Modes Work' : 'How Plannotator Works'}
|
|
217
217
|
frameBorder="0"
|
|
@@ -36,7 +36,7 @@ export const ApproveDropdown: React.FC<ApproveDropdownProps> = ({
|
|
|
36
36
|
disabled = false,
|
|
37
37
|
isLoading = false,
|
|
38
38
|
}) => {
|
|
39
|
-
const [setting, setSetting] = useState<AgentSwitchSettings>(() => getAgentSwitchSettings());
|
|
39
|
+
const [setting, setSetting] = useState<AgentSwitchSettings>(() => getAgentSwitchSettings('plan'));
|
|
40
40
|
const [isOpen, setIsOpen] = useState(false);
|
|
41
41
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
42
42
|
|
|
@@ -106,7 +106,7 @@ export const BlockRenderer: React.FC<{
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
case 'code':
|
|
109
|
-
return <CodeBlock block={block}
|
|
109
|
+
return <CodeBlock block={block} isHovered={false} />;
|
|
110
110
|
|
|
111
111
|
case 'table':
|
|
112
112
|
return (
|
|
@@ -6,6 +6,7 @@ import { useTheme } from './ThemeProvider';
|
|
|
6
6
|
import { CommentPopover } from './CommentPopover';
|
|
7
7
|
import { ImageThumbnail } from './ImageThumbnail';
|
|
8
8
|
import type { CodeAnnotation, ImageAttachment } from '../types';
|
|
9
|
+
import { copyTextToClipboard } from '../utils/clipboard';
|
|
9
10
|
|
|
10
11
|
export interface CodeFileAnnotationInput {
|
|
11
12
|
filePath: string;
|
|
@@ -457,12 +458,11 @@ export const CodeFilePopout: React.FC<CodeFilePopoutProps> = ({
|
|
|
457
458
|
}, [onAddAnnotation, openCommentForRange]);
|
|
458
459
|
|
|
459
460
|
const handleCopy = async () => {
|
|
460
|
-
|
|
461
|
-
await navigator.clipboard.writeText(contents);
|
|
461
|
+
if (await copyTextToClipboard(contents)) {
|
|
462
462
|
setCopied(true);
|
|
463
463
|
setTimeout(() => setCopied(false), 1500);
|
|
464
|
-
}
|
|
465
|
-
console.error('Failed to copy
|
|
464
|
+
} else {
|
|
465
|
+
console.error('Failed to copy');
|
|
466
466
|
}
|
|
467
467
|
};
|
|
468
468
|
|
|
@@ -583,6 +583,7 @@ export const CodeFilePopout: React.FC<CodeFilePopoutProps> = ({
|
|
|
583
583
|
anchorRect={pendingComment.anchorRect}
|
|
584
584
|
contextText={pendingComment.contextText}
|
|
585
585
|
isGlobal={false}
|
|
586
|
+
skillReferences
|
|
586
587
|
onSubmit={(text, images) => {
|
|
587
588
|
onAddAnnotation({
|
|
588
589
|
filePath: filepath,
|