@sutrata/editor 0.1.2 → 0.2.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/dist/ai/VoiceConfirmDialog.d.ts +1 -0
- package/dist/ai/VoiceConfirmDialog.js +6 -6
- package/dist/ai/VoiceToolbar.d.ts +1 -0
- package/dist/ai/VoiceToolbar.js +22 -16
- package/dist/ai/clean-response.d.ts +7 -0
- package/dist/ai/clean-response.js +58 -0
- package/dist/ai/format-transcript.d.ts +3 -0
- package/dist/ai/format-transcript.js +7 -0
- package/dist/ai/prompts.d.ts +8 -1
- package/dist/ai/prompts.js +34 -7
- package/dist/autocomplete/suggestions.js +1 -1
- package/dist/context/DocumentContext.d.ts +28 -4
- package/dist/context/DocumentContext.js +67 -37
- package/dist/editor/EditorView.js +32 -4
- package/dist/editor/SelectionMenu.js +5 -3
- package/dist/editor/external-decorations-plugin.d.ts +23 -0
- package/dist/editor/external-decorations-plugin.js +151 -0
- package/dist/editor/omitted-scene-plugin.d.ts +9 -0
- package/dist/editor/omitted-scene-plugin.js +44 -0
- package/dist/editor/plugins.js +4 -0
- package/dist/editor/private-metadata-plugin.d.ts +10 -0
- package/dist/editor/private-metadata-plugin.js +60 -0
- package/dist/editor/prosemirror-to-sutra.js +179 -74
- package/dist/editor/scene-heading-view.js +2 -0
- package/dist/editor/schema.js +69 -12
- package/dist/editor/sutra-to-prosemirror.d.ts +2 -0
- package/dist/editor/sutra-to-prosemirror.js +32 -34
- package/dist/extensions/ai-provider.d.ts +44 -0
- package/dist/extensions/ai-provider.js +27 -0
- package/dist/extensions/collab.d.ts +21 -0
- package/dist/extensions/collab.js +6 -0
- package/dist/extensions/command-registry.d.ts +49 -0
- package/dist/extensions/command-registry.js +28 -0
- package/dist/extensions/decorations.d.ts +48 -0
- package/dist/extensions/decorations.js +6 -0
- package/dist/extensions/export-registry.d.ts +59 -0
- package/dist/extensions/export-registry.js +10 -0
- package/dist/extensions/panel-registry.d.ts +30 -0
- package/dist/extensions/panel-registry.js +16 -0
- package/dist/extensions/registries.d.ts +15 -0
- package/dist/extensions/registries.js +12 -0
- package/dist/extensions/registry-store.d.ts +26 -0
- package/dist/extensions/registry-store.js +35 -0
- package/dist/extensions/session.d.ts +29 -0
- package/dist/extensions/session.js +20 -0
- package/dist/extensions/speech-provider.d.ts +35 -0
- package/dist/extensions/speech-provider.js +17 -0
- package/dist/file/builtin-exporters.d.ts +9 -0
- package/dist/file/builtin-exporters.js +72 -0
- package/dist/file/docx-exporter.js +7 -4
- package/dist/file/docx-importer.d.ts +9 -0
- package/dist/file/docx-importer.js +47 -19
- package/dist/file/scene-number.d.ts +5 -0
- package/dist/file/scene-number.js +8 -0
- package/dist/file/workflow-reports.js +13 -7
- package/dist/findreplace/FindReplace.js +5 -2
- package/dist/import/AIImportDialog.d.ts +11 -0
- package/dist/import/AIImportDialog.js +112 -0
- package/dist/import/ai-import.d.ts +51 -0
- package/dist/import/ai-import.js +200 -0
- package/dist/import/apply-import.d.ts +7 -0
- package/dist/import/apply-import.js +35 -0
- package/dist/import/extract.d.ts +17 -0
- package/dist/import/extract.js +18 -0
- package/dist/index.d.ts +17 -2
- package/dist/index.js +7 -0
- package/dist/locales/bn.json +8 -0
- package/dist/locales/en.json +8 -0
- package/dist/locales/gu.json +8 -0
- package/dist/locales/hi.json +8 -0
- package/dist/locales/kn.json +8 -0
- package/dist/locales/ml.json +8 -0
- package/dist/locales/mr.json +8 -0
- package/dist/locales/or.json +8 -0
- package/dist/locales/pa.json +8 -0
- package/dist/locales/si.json +8 -0
- package/dist/locales/ta.json +8 -0
- package/dist/locales/te.json +8 -0
- package/dist/navigator/SceneNavigator.js +125 -131
- package/dist/navigator/StatisticsDialog.js +5 -1
- package/dist/navigator/scene-edits.d.ts +18 -0
- package/dist/navigator/scene-edits.js +143 -0
- package/dist/navigator/scene-list.js +4 -4
- package/dist/navigator/scene-numbering.d.ts +37 -0
- package/dist/navigator/scene-numbering.js +88 -0
- package/dist/settings/SettingsDialog.js +8 -120
- package/dist/shell/AppBar.js +21 -2
- package/dist/shell/AppShell.js +18 -4
- package/dist/shell/ElementToolbar.d.ts +5 -0
- package/dist/shell/ElementToolbar.js +35 -25
- package/dist/shell/LanguageStatus.js +6 -0
- package/dist/shell/StatusBar.js +11 -6
- package/dist/shell/builtin-commands.d.ts +10 -0
- package/dist/shell/builtin-commands.js +43 -0
- package/dist/shell/icons.d.ts +6 -0
- package/dist/shell/icons.js +6 -0
- package/dist/shell/use-commands.d.ts +7 -0
- package/dist/shell/use-commands.js +24 -0
- package/dist/shell/use-panel-context.d.ts +3 -0
- package/dist/shell/use-panel-context.js +39 -0
- package/dist/source/SourceView.js +18 -1
- package/dist/styles/screenplay.css +113 -1
- package/dist/titlepage/ExportDialog.d.ts +5 -0
- package/dist/titlepage/ExportDialog.js +59 -96
- package/package.json +4 -4
- package/dist/ai/OnboardingDialog.d.ts +0 -6
- package/dist/ai/OnboardingDialog.js +0 -115
- package/dist/ai/ai-client.d.ts +0 -71
- package/dist/ai/ai-client.js +0 -494
- package/dist/ai/generated-providers.json +0 -3696
- package/dist/ai/voice-service.d.ts +0 -15
- package/dist/ai/voice-service.js +0 -81
- package/dist/editor/character-view.d.ts +0 -35
- package/dist/editor/character-view.js +0 -112
- package/dist/editor/transliterate-input.d.ts +0 -10
- package/dist/editor/transliterate-input.js +0 -88
- package/dist/extensions/types.d.ts +0 -73
- package/dist/extensions/types.js +0 -12
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface VoiceServiceCallbacks {
|
|
2
|
-
onResult: (text: string, isFinal: boolean) => void;
|
|
3
|
-
onError: (error: string) => void;
|
|
4
|
-
onEnd: () => void;
|
|
5
|
-
}
|
|
6
|
-
export declare class VoiceService {
|
|
7
|
-
private recognition;
|
|
8
|
-
private isListening;
|
|
9
|
-
constructor();
|
|
10
|
-
isSupported(): boolean;
|
|
11
|
-
start(lang: string, callbacks: VoiceServiceCallbacks): void;
|
|
12
|
-
stop(): void;
|
|
13
|
-
abort(): void;
|
|
14
|
-
}
|
|
15
|
-
export declare const voiceServiceInstance: VoiceService;
|
package/dist/ai/voice-service.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
export class VoiceService {
|
|
2
|
-
recognition = null;
|
|
3
|
-
isListening = false;
|
|
4
|
-
constructor() {
|
|
5
|
-
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
6
|
-
if (SpeechRecognition) {
|
|
7
|
-
this.recognition = new SpeechRecognition();
|
|
8
|
-
this.recognition.continuous = true;
|
|
9
|
-
this.recognition.interimResults = true;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
isSupported() {
|
|
13
|
-
return !!this.recognition;
|
|
14
|
-
}
|
|
15
|
-
start(lang, callbacks) {
|
|
16
|
-
if (!this.recognition) {
|
|
17
|
-
callbacks.onError('Web Speech API is not supported in this browser.');
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
if (this.isListening) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
this.recognition.lang = lang;
|
|
24
|
-
this.isListening = true;
|
|
25
|
-
this.recognition.onresult = (event) => {
|
|
26
|
-
let interimTranscript = '';
|
|
27
|
-
let finalTranscript = '';
|
|
28
|
-
for (let i = event.resultIndex; i < event.results.length; ++i) {
|
|
29
|
-
if (event.results[i].isFinal) {
|
|
30
|
-
finalTranscript += event.results[i][0].transcript;
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
interimTranscript += event.results[i][0].transcript;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
const text = finalTranscript || interimTranscript;
|
|
37
|
-
callbacks.onResult(text, finalTranscript.length > 0);
|
|
38
|
-
};
|
|
39
|
-
this.recognition.onerror = (event) => {
|
|
40
|
-
// Ignore 'no-speech' error to prevent crashing, just log it
|
|
41
|
-
if (event.error === 'no-speech') {
|
|
42
|
-
console.warn('Speech recognition: no speech detected');
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
callbacks.onError(event.error || 'Speech recognition error');
|
|
46
|
-
};
|
|
47
|
-
this.recognition.onend = () => {
|
|
48
|
-
this.isListening = false;
|
|
49
|
-
callbacks.onEnd();
|
|
50
|
-
};
|
|
51
|
-
try {
|
|
52
|
-
this.recognition.start();
|
|
53
|
-
}
|
|
54
|
-
catch (e) {
|
|
55
|
-
callbacks.onError(e.message || String(e));
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
stop() {
|
|
59
|
-
if (this.recognition && this.isListening) {
|
|
60
|
-
try {
|
|
61
|
-
this.recognition.stop();
|
|
62
|
-
}
|
|
63
|
-
catch (e) {
|
|
64
|
-
console.error('Failed to stop recognition:', e);
|
|
65
|
-
}
|
|
66
|
-
this.isListening = false;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
abort() {
|
|
70
|
-
if (this.recognition && this.isListening) {
|
|
71
|
-
try {
|
|
72
|
-
this.recognition.abort();
|
|
73
|
-
}
|
|
74
|
-
catch (e) {
|
|
75
|
-
console.error('Failed to abort recognition:', e);
|
|
76
|
-
}
|
|
77
|
-
this.isListening = false;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
export const voiceServiceInstance = new VoiceService();
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { Node as PmNode } from 'prosemirror-model';
|
|
2
|
-
import type { EditorView, NodeView, ViewMutationRecord } from 'prosemirror-view';
|
|
3
|
-
/**
|
|
4
|
-
* NodeView for character. Renders the name text (ProseMirror-managed) plus
|
|
5
|
-
* an editable extension input — "(V.O.)", "(O.S.)", etc. — on the right.
|
|
6
|
-
*
|
|
7
|
-
* Without this, character used the schema's plain static toDOM spec
|
|
8
|
-
* (['div', {class:'cs-character'}, 0]), whose content hole only renders
|
|
9
|
-
* PM's managed inline content (the name). extension is a real, populated
|
|
10
|
-
* node attr (captured correctly by the parser and carried correctly by
|
|
11
|
-
* sutra-to-prosemirror.ts/prosemirror-to-sutra.ts both ways) but nothing
|
|
12
|
-
* ever painted it to the screen — it was silently invisible. Mirrors
|
|
13
|
-
* SceneHeadingView's pattern for the same kind of "attr needs its own
|
|
14
|
-
* visible, editable-but-outside-the-PM-content-model widget" problem.
|
|
15
|
-
*
|
|
16
|
-
* The extension value is stored (and round-tripped to Sutra text) *with*
|
|
17
|
-
* its parentheses, e.g. "(V.O.)" — matching what the parser's CHARACTER
|
|
18
|
-
* regex captures — so a typed value without parens is auto-wrapped on commit.
|
|
19
|
-
*/
|
|
20
|
-
export declare class CharacterView implements NodeView {
|
|
21
|
-
dom: HTMLElement;
|
|
22
|
-
contentDOM: HTMLElement;
|
|
23
|
-
private input;
|
|
24
|
-
private pmView;
|
|
25
|
-
private getPos;
|
|
26
|
-
constructor(node: PmNode, view: EditorView, getPos: () => number | undefined);
|
|
27
|
-
private commit;
|
|
28
|
-
private focusEditorAfter;
|
|
29
|
-
private onInputKeydown;
|
|
30
|
-
private onInputBlur;
|
|
31
|
-
update(node: PmNode): boolean;
|
|
32
|
-
destroy(): void;
|
|
33
|
-
stopEvent(event: Event): boolean;
|
|
34
|
-
ignoreMutation(mutation: ViewMutationRecord): boolean;
|
|
35
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { TextSelection } from 'prosemirror-state';
|
|
2
|
-
/**
|
|
3
|
-
* NodeView for character. Renders the name text (ProseMirror-managed) plus
|
|
4
|
-
* an editable extension input — "(V.O.)", "(O.S.)", etc. — on the right.
|
|
5
|
-
*
|
|
6
|
-
* Without this, character used the schema's plain static toDOM spec
|
|
7
|
-
* (['div', {class:'cs-character'}, 0]), whose content hole only renders
|
|
8
|
-
* PM's managed inline content (the name). extension is a real, populated
|
|
9
|
-
* node attr (captured correctly by the parser and carried correctly by
|
|
10
|
-
* sutra-to-prosemirror.ts/prosemirror-to-sutra.ts both ways) but nothing
|
|
11
|
-
* ever painted it to the screen — it was silently invisible. Mirrors
|
|
12
|
-
* SceneHeadingView's pattern for the same kind of "attr needs its own
|
|
13
|
-
* visible, editable-but-outside-the-PM-content-model widget" problem.
|
|
14
|
-
*
|
|
15
|
-
* The extension value is stored (and round-tripped to Sutra text) *with*
|
|
16
|
-
* its parentheses, e.g. "(V.O.)" — matching what the parser's CHARACTER
|
|
17
|
-
* regex captures — so a typed value without parens is auto-wrapped on commit.
|
|
18
|
-
*/
|
|
19
|
-
export class CharacterView {
|
|
20
|
-
dom;
|
|
21
|
-
contentDOM;
|
|
22
|
-
input;
|
|
23
|
-
pmView;
|
|
24
|
-
getPos;
|
|
25
|
-
constructor(node, view, getPos) {
|
|
26
|
-
this.pmView = view;
|
|
27
|
-
this.getPos = getPos;
|
|
28
|
-
this.dom = document.createElement('div');
|
|
29
|
-
this.dom.className = 'cs-character';
|
|
30
|
-
this.contentDOM = document.createElement('span');
|
|
31
|
-
this.contentDOM.className = 'cs-character-text';
|
|
32
|
-
this.dom.appendChild(this.contentDOM);
|
|
33
|
-
this.input = document.createElement('input');
|
|
34
|
-
this.input.type = 'text';
|
|
35
|
-
this.input.className = 'cs-character-extension';
|
|
36
|
-
this.input.placeholder = '(V.O.)';
|
|
37
|
-
this.input.value = node.attrs['extension'] ?? '';
|
|
38
|
-
this.input.setAttribute('aria-label', 'Character extension, e.g. (V.O.) or (O.S.)');
|
|
39
|
-
this.input.spellcheck = false;
|
|
40
|
-
this.input.addEventListener('keydown', this.onInputKeydown);
|
|
41
|
-
this.input.addEventListener('blur', this.onInputBlur);
|
|
42
|
-
this.input.addEventListener('mousedown', (e) => e.stopPropagation());
|
|
43
|
-
this.dom.appendChild(this.input);
|
|
44
|
-
}
|
|
45
|
-
commit() {
|
|
46
|
-
const raw = this.input.value.trim();
|
|
47
|
-
let extension = raw === '' ? null : raw;
|
|
48
|
-
if (extension && !(extension.startsWith('(') && extension.endsWith(')'))) {
|
|
49
|
-
extension = `(${extension})`;
|
|
50
|
-
}
|
|
51
|
-
this.input.value = extension ?? '';
|
|
52
|
-
const pos = this.getPos();
|
|
53
|
-
if (pos === undefined)
|
|
54
|
-
return;
|
|
55
|
-
const node = this.pmView.state.doc.nodeAt(pos);
|
|
56
|
-
if (!node)
|
|
57
|
-
return;
|
|
58
|
-
if (node.attrs['extension'] === extension)
|
|
59
|
-
return;
|
|
60
|
-
const tr = this.pmView.state.tr.setNodeMarkup(pos, undefined, { ...node.attrs, extension });
|
|
61
|
-
this.pmView.dispatch(tr);
|
|
62
|
-
}
|
|
63
|
-
focusEditorAfter() {
|
|
64
|
-
const pos = this.getPos();
|
|
65
|
-
if (pos === undefined)
|
|
66
|
-
return;
|
|
67
|
-
const node = this.pmView.state.doc.nodeAt(pos);
|
|
68
|
-
if (!node)
|
|
69
|
-
return;
|
|
70
|
-
const endOfText = pos + node.nodeSize - 1;
|
|
71
|
-
const sel = TextSelection.near(this.pmView.state.doc.resolve(endOfText), -1);
|
|
72
|
-
this.pmView.dispatch(this.pmView.state.tr.setSelection(sel));
|
|
73
|
-
this.pmView.focus();
|
|
74
|
-
}
|
|
75
|
-
onInputKeydown = (e) => {
|
|
76
|
-
if (e.key === 'Escape') {
|
|
77
|
-
e.preventDefault();
|
|
78
|
-
e.stopPropagation();
|
|
79
|
-
this.input.value = this.pmView.state.doc.nodeAt(this.getPos() ?? 0)?.attrs['extension'] ?? '';
|
|
80
|
-
this.pmView.focus();
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
if (e.key === 'Enter' || e.key === 'Tab') {
|
|
84
|
-
e.preventDefault();
|
|
85
|
-
e.stopPropagation();
|
|
86
|
-
this.commit();
|
|
87
|
-
this.focusEditorAfter();
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
onInputBlur = () => {
|
|
92
|
-
this.commit();
|
|
93
|
-
};
|
|
94
|
-
update(node) {
|
|
95
|
-
if (node.type.name !== 'character')
|
|
96
|
-
return false;
|
|
97
|
-
if (document.activeElement !== this.input) {
|
|
98
|
-
this.input.value = node.attrs['extension'] ?? '';
|
|
99
|
-
}
|
|
100
|
-
return true;
|
|
101
|
-
}
|
|
102
|
-
destroy() {
|
|
103
|
-
this.input.removeEventListener('keydown', this.onInputKeydown);
|
|
104
|
-
this.input.removeEventListener('blur', this.onInputBlur);
|
|
105
|
-
}
|
|
106
|
-
stopEvent(event) {
|
|
107
|
-
return event.target === this.input || this.input.contains(event.target);
|
|
108
|
-
}
|
|
109
|
-
ignoreMutation(mutation) {
|
|
110
|
-
return this.input.contains(mutation.target) || mutation.target === this.input;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Plugin } from 'prosemirror-state';
|
|
2
|
-
/** Enable or disable transliteration mode. */
|
|
3
|
-
export declare function setTranslitMode(enabled: boolean, lang?: string): void;
|
|
4
|
-
/** Returns whether transliteration mode is active. */
|
|
5
|
-
export declare function isTranslitMode(): boolean;
|
|
6
|
-
/**
|
|
7
|
-
* ProseMirror plugin that intercepts text input and converts roman keystrokes
|
|
8
|
-
* to native script on word boundaries.
|
|
9
|
-
*/
|
|
10
|
-
export declare function createTranslitPlugin(): Plugin<any>;
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { Plugin } from 'prosemirror-state';
|
|
2
|
-
import { transliterate } from '@sutra/parser';
|
|
3
|
-
// Map BCP-47 codes to Script names used by the transliterate engine
|
|
4
|
-
const LANG_TO_SCRIPT = {
|
|
5
|
-
'hi': 'devanagari',
|
|
6
|
-
'mr': 'devanagari',
|
|
7
|
-
'sa': 'devanagari',
|
|
8
|
-
'ta': 'tamil',
|
|
9
|
-
'te': 'telugu',
|
|
10
|
-
'kn': 'kannada',
|
|
11
|
-
'ml': 'malayalam',
|
|
12
|
-
'bn': 'bengali',
|
|
13
|
-
'gu': 'gujarati',
|
|
14
|
-
'pa': 'gurmukhi',
|
|
15
|
-
'or': 'odia',
|
|
16
|
-
};
|
|
17
|
-
// Word boundary characters — trigger transliteration
|
|
18
|
-
const WORD_BOUNDARIES = new Set([' ', '\t', '\n', '.', ',', '?', '!', ':', ';', '-', '(', ')']);
|
|
19
|
-
const globalState = {
|
|
20
|
-
enabled: false,
|
|
21
|
-
buffer: '',
|
|
22
|
-
currentLang: 'hi',
|
|
23
|
-
};
|
|
24
|
-
/** Enable or disable transliteration mode. */
|
|
25
|
-
export function setTranslitMode(enabled, lang = 'hi') {
|
|
26
|
-
globalState.enabled = enabled;
|
|
27
|
-
globalState.currentLang = lang;
|
|
28
|
-
globalState.buffer = '';
|
|
29
|
-
}
|
|
30
|
-
/** Returns whether transliteration mode is active. */
|
|
31
|
-
export function isTranslitMode() {
|
|
32
|
-
return globalState.enabled;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* ProseMirror plugin that intercepts text input and converts roman keystrokes
|
|
36
|
-
* to native script on word boundaries.
|
|
37
|
-
*/
|
|
38
|
-
export function createTranslitPlugin() {
|
|
39
|
-
return new Plugin({
|
|
40
|
-
props: {
|
|
41
|
-
handleTextInput(view, _from, _to, text) {
|
|
42
|
-
if (!globalState.enabled)
|
|
43
|
-
return false;
|
|
44
|
-
const script = LANG_TO_SCRIPT[globalState.currentLang];
|
|
45
|
-
if (!script)
|
|
46
|
-
return false;
|
|
47
|
-
if (WORD_BOUNDARIES.has(text)) {
|
|
48
|
-
// Flush buffer: transliterate and replace
|
|
49
|
-
if (globalState.buffer.length > 0) {
|
|
50
|
-
const native = transliterate(globalState.buffer, script);
|
|
51
|
-
const { state, dispatch } = view;
|
|
52
|
-
const { from } = state.selection;
|
|
53
|
-
// Replace the buffered roman text with native script + boundary char
|
|
54
|
-
const bufferStart = from - globalState.buffer.length;
|
|
55
|
-
const tr = state.tr
|
|
56
|
-
.replaceWith(bufferStart, from, state.schema.text(native + text));
|
|
57
|
-
globalState.buffer = '';
|
|
58
|
-
dispatch(tr);
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
|
-
// Nothing buffered, let boundary char through
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
// Accumulate roman keystrokes in buffer
|
|
66
|
-
globalState.buffer += text;
|
|
67
|
-
// Let ProseMirror insert the roman char temporarily (user sees buffering)
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
handleKeyDown(_view, event) {
|
|
72
|
-
if (!globalState.enabled)
|
|
73
|
-
return false;
|
|
74
|
-
// Backspace: remove from buffer too
|
|
75
|
-
if (event.key === 'Backspace' && globalState.buffer.length > 0) {
|
|
76
|
-
globalState.buffer = globalState.buffer.slice(0, -1);
|
|
77
|
-
return false; // let PM handle the actual deletion
|
|
78
|
-
}
|
|
79
|
-
// Escape: clear buffer without inserting
|
|
80
|
-
if (event.key === 'Escape') {
|
|
81
|
-
globalState.buffer = '';
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
return false;
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type-only extension-point surface (OSS spec §11.5). These declare the shape
|
|
3
|
-
* embedders (Sutrata Cloud, third-party plugins) will implement, but nothing
|
|
4
|
-
* in @sutrata/editor is wired to them yet — ai-client.ts and voice-service.ts
|
|
5
|
-
* are still direct imports within this package, not injected. Promoting them
|
|
6
|
-
* to real dependency-injected providers (matching StorageAdapter's pattern in
|
|
7
|
-
* ./storage-adapter.ts) is future work; see docs/TODO.
|
|
8
|
-
*
|
|
9
|
-
* [P1 interface, stable by P2] per the OSS spec — these shapes may still
|
|
10
|
-
* change before they're load-bearing.
|
|
11
|
-
*/
|
|
12
|
-
/** LLM completion with streaming; declares capabilities and data-policy text for disclosure. */
|
|
13
|
-
export interface AIProvider {
|
|
14
|
-
id: string;
|
|
15
|
-
displayName: string;
|
|
16
|
-
dataPolicyText: string;
|
|
17
|
-
complete(prompt: string, opts?: {
|
|
18
|
-
stream?: boolean;
|
|
19
|
-
}): Promise<string>;
|
|
20
|
-
}
|
|
21
|
-
/** Speech-to-text. */
|
|
22
|
-
export interface SpeechProvider {
|
|
23
|
-
id: string;
|
|
24
|
-
displayName: string;
|
|
25
|
-
transcribe(audio: Blob, opts?: {
|
|
26
|
-
language?: string;
|
|
27
|
-
}): Promise<string>;
|
|
28
|
-
}
|
|
29
|
-
/** Current user identity, permissions (read-only, comment, edit), feature flags. */
|
|
30
|
-
export interface SessionContext {
|
|
31
|
-
userId: string | null;
|
|
32
|
-
displayName: string | null;
|
|
33
|
-
permission: 'read' | 'comment' | 'edit';
|
|
34
|
-
featureFlags: Record<string, boolean>;
|
|
35
|
-
}
|
|
36
|
-
/** Add side panels, inspector sections, and app-bar items; receives the AST and scene IDs. */
|
|
37
|
-
export interface PanelRegistry {
|
|
38
|
-
registerPanel(panel: {
|
|
39
|
-
id: string;
|
|
40
|
-
title: string;
|
|
41
|
-
render: () => unknown;
|
|
42
|
-
}): void;
|
|
43
|
-
}
|
|
44
|
-
/** Add commands, menu items, keyboard shortcuts. */
|
|
45
|
-
export interface CommandRegistry {
|
|
46
|
-
registerCommand(command: {
|
|
47
|
-
id: string;
|
|
48
|
-
label: string;
|
|
49
|
-
run: () => void;
|
|
50
|
-
shortcut?: string;
|
|
51
|
-
}): void;
|
|
52
|
-
}
|
|
53
|
-
/** Add export formats and report types. */
|
|
54
|
-
export interface ExportRegistry {
|
|
55
|
-
registerExporter(exporter: {
|
|
56
|
-
id: string;
|
|
57
|
-
label: string;
|
|
58
|
-
run: (text: string) => Promise<Blob>;
|
|
59
|
-
}): void;
|
|
60
|
-
}
|
|
61
|
-
/** Hook to bind the editor state to an external real-time sync provider (e.g. a Yjs document). */
|
|
62
|
-
export interface CollabBinding {
|
|
63
|
-
bind(): () => void;
|
|
64
|
-
}
|
|
65
|
-
/** Render external annotations (comments, breakdown highlights, revision marks) anchored to
|
|
66
|
-
* scene IDs and text ranges. */
|
|
67
|
-
export interface DecorationProvider {
|
|
68
|
-
getDecorations(sceneId: string): Array<{
|
|
69
|
-
from: number;
|
|
70
|
-
to: number;
|
|
71
|
-
className: string;
|
|
72
|
-
}>;
|
|
73
|
-
}
|
package/dist/extensions/types.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type-only extension-point surface (OSS spec §11.5). These declare the shape
|
|
3
|
-
* embedders (Sutrata Cloud, third-party plugins) will implement, but nothing
|
|
4
|
-
* in @sutrata/editor is wired to them yet — ai-client.ts and voice-service.ts
|
|
5
|
-
* are still direct imports within this package, not injected. Promoting them
|
|
6
|
-
* to real dependency-injected providers (matching StorageAdapter's pattern in
|
|
7
|
-
* ./storage-adapter.ts) is future work; see docs/TODO.
|
|
8
|
-
*
|
|
9
|
-
* [P1 interface, stable by P2] per the OSS spec — these shapes may still
|
|
10
|
-
* change before they're load-bearing.
|
|
11
|
-
*/
|
|
12
|
-
export {};
|