superdoc-macros 0.2.0 → 0.4.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.
@@ -1,5 +1,29 @@
1
- /* ---------- עזרים ---------- */
2
- const NOT_READY = { ok: false, message: 'אין מסמך פתוח', reason: 'not-ready' };
1
+ /**
2
+ * The `MacroHost` implementation on top of SuperDoc v2 in engine-only mode
3
+ * (`ui: false`) — the configuration otzaria-word-editor runs.
4
+ *
5
+ * The surfaces used, in order of preference:
6
+ * 1. `superdoc.ui.commands` — the controller's command catalog (execution + observation).
7
+ * 2. `superdoc.activeEditor.doc` — the public Document API (selection, insertion, blocks).
8
+ * 3. `superdoc.ui.search` — find/replace.
9
+ * 4. `superdoc.activeEditor.view` — the internal ProseMirror instance,
10
+ * **only** for gaps that have no public surface: backward deletion and
11
+ * the document's full text. Present in the browser, null headless.
12
+ *
13
+ * The types here are structural and do not import from superdoc: the toolkit
14
+ * does not depend on the package, and an engine version that changes a field
15
+ * fails closed (the function returns a failure) rather than crashing.
16
+ *
17
+ * Command observation for the recorder wraps `executeAsync` on the commands
18
+ * object. That covers every path that calls it — including otzaria's
19
+ * CommandAdapter — without changing the calling code. `dispose()` restores
20
+ * the original method.
21
+ */
22
+ import { macroMessages } from '../messages.js';
23
+ /* ---------- Helpers ---------- */
24
+ function notReady() {
25
+ return { ok: false, message: macroMessages().noDocument, reason: 'not-ready' };
26
+ }
3
27
  function failed(message, reason) {
4
28
  return { ok: false, message, reason };
5
29
  }
@@ -16,43 +40,104 @@ function receiptOutcome(receipt, failedAction) {
16
40
  function emptySelection() {
17
41
  return { text: '', hasRange: false, blockId: null, selectionTarget: null, empty: true };
18
42
  }
19
- /* ---------- המימוש ---------- */
43
+ /* ---------- The implementation ---------- */
20
44
  export function createSuperdocHost(options) {
21
45
  const { superdoc, container } = options;
22
- // נקראים ברגע השימוש ולא נשמרים: activeEditor מוחלף בכל פתיחת מסמך.
46
+ const viewFallback = options.viewFallback ?? true;
47
+ // Read at call time, never cached: activeEditor is replaced on every document open.
23
48
  const commands = () => superdoc.ui?.commands ?? null;
24
49
  const doc = () => superdoc.activeEditor?.doc ?? null;
25
- const view = () => superdoc.activeEditor?.view ?? null;
26
50
  const search = () => superdoc.ui?.search ?? null;
51
+ /**
52
+ * The single gate to the internal ProseMirror view. Every use of a
53
+ * non-public surface goes through here, so disabling the fallback (or a
54
+ * future engine that hides the view) degrades to closed failures in one
55
+ * place.
56
+ */
57
+ const view = () => viewFallback ? (superdoc.activeEditor?.view ?? null) : null;
27
58
  const commandListeners = new Set();
28
59
  const inputListeners = new Set();
29
- /* תצפית פקודות: עטיפת executeAsync, פעם אחת, עם שחזור ב-dispose. */
60
+ const emitInput = (mapped) => {
61
+ for (const listener of inputListeners) {
62
+ try {
63
+ listener(mapped);
64
+ }
65
+ catch (error) {
66
+ console.warn('[superdoc-macros] input listener threw', error);
67
+ }
68
+ }
69
+ };
70
+ /* Command observation: wrap executeAsync, once, restored on dispose.
71
+ Listeners are notified only after the engine reports success — a command
72
+ that was refused (not routed, or a failed receipt) must not enter a
73
+ recording, or replay would re-fail it or, worse, apply it in a context
74
+ where it now succeeds unintended. */
30
75
  const wrapped = commands();
31
76
  const originalExecuteAsync = wrapped?.executeAsync;
32
77
  if (wrapped && originalExecuteAsync) {
33
78
  wrapped.executeAsync = function (id, payload) {
34
- for (const listener of commandListeners) {
35
- try {
36
- listener(id, payload);
79
+ const result = originalExecuteAsync.call(wrapped, id, payload);
80
+ void Promise.resolve(result)
81
+ .then((value) => {
82
+ if (value === false)
83
+ return;
84
+ if (typeof value === 'object' && value !== null && value.success === false)
85
+ return;
86
+ for (const listener of commandListeners) {
87
+ try {
88
+ listener(id, payload);
89
+ }
90
+ catch (error) {
91
+ console.warn('[superdoc-macros] command listener threw', error);
92
+ }
37
93
  }
38
- catch (error) {
39
- console.warn('[superdoc-macros] מאזין פקודות זרק', error);
40
- }
41
- }
42
- return originalExecuteAsync.call(wrapped, id, payload);
94
+ })
95
+ .catch(() => undefined); // a thrown command is a failure — nothing to record.
96
+ return result;
43
97
  };
44
98
  }
45
- /* הקלדה: beforeinput על ה-container, בשלב הלכידה. */
99
+ /* Typing: beforeinput on the container, capture phase.
100
+
101
+ IME composition is folded to a single event: while composing, the
102
+ engine fires insertCompositionText repeatedly with the growing
103
+ candidate text, and mapping each one would record the word once per
104
+ keystroke. The events are suppressed during composition and the final
105
+ text is emitted once, from compositionend. */
106
+ let composing = false;
107
+ const onCompositionStart = () => {
108
+ composing = true;
109
+ };
110
+ const onCompositionEnd = (event) => {
111
+ composing = false;
112
+ const data = event.data;
113
+ if (typeof data === 'string' && data.length > 0)
114
+ emitInput({ kind: 'insert-text', text: data });
115
+ };
46
116
  const onBeforeInput = (event) => {
47
117
  const input = event;
48
118
  let mapped = null;
49
119
  switch (input.inputType) {
50
120
  case 'insertText':
51
121
  case 'insertCompositionText':
122
+ if (composing)
123
+ break; // the final text arrives from compositionend.
52
124
  if (typeof input.data === 'string' && input.data.length > 0) {
53
125
  mapped = { kind: 'insert-text', text: input.data };
54
126
  }
55
127
  break;
128
+ // Paste, drop and spellcheck replacement carry their text either in
129
+ // `data` or in a dataTransfer — without this branch a recording
130
+ // silently missed everything the user pasted.
131
+ case 'insertFromPaste':
132
+ case 'insertFromDrop':
133
+ case 'insertReplacementText': {
134
+ const text = typeof input.data === 'string' && input.data.length > 0
135
+ ? input.data
136
+ : input.dataTransfer?.getData('text/plain') ?? '';
137
+ if (text.length > 0)
138
+ mapped = { kind: 'insert-text', text };
139
+ break;
140
+ }
56
141
  case 'insertParagraph':
57
142
  mapped = { kind: 'insert-paragraph' };
58
143
  break;
@@ -65,29 +150,32 @@ export function createSuperdocHost(options) {
65
150
  default:
66
151
  break;
67
152
  }
68
- if (!mapped)
69
- return;
70
- for (const listener of inputListeners) {
71
- try {
72
- listener(mapped);
73
- }
74
- catch (error) {
75
- console.warn('[superdoc-macros] מאזין הקלדה זרק', error);
76
- }
77
- }
153
+ if (mapped)
154
+ emitInput(mapped);
78
155
  };
79
156
  container?.addEventListener('beforeinput', onBeforeInput, true);
80
- async function readSelection(includeText) {
157
+ container?.addEventListener('compositionstart', onCompositionStart, true);
158
+ container?.addEventListener('compositionend', onCompositionEnd, true);
159
+ /**
160
+ * `failed: true` means the engine call itself threw — as opposed to a
161
+ * clean "no selection" answer. Callers that write relative to the caret
162
+ * must fail closed on it: falling back to "no target" would send the text
163
+ * to the end of the document, far from where the user is looking.
164
+ */
165
+ async function readSelectionDetailed(includeText) {
81
166
  const current = doc()?.selection?.current;
82
167
  if (typeof current !== 'function')
83
- return emptySelection();
168
+ return { snapshot: emptySelection(), failed: false };
84
169
  let info;
85
170
  try {
86
171
  info = await current(includeText ? { includeText: true } : undefined);
87
172
  }
88
173
  catch {
89
- return emptySelection();
174
+ return { snapshot: emptySelection(), failed: true };
90
175
  }
176
+ return { snapshot: parseSelectionInfo(info), failed: false };
177
+ }
178
+ function parseSelectionInfo(info) {
91
179
  if (!info || typeof info !== 'object')
92
180
  return emptySelection();
93
181
  const segments = Array.isArray(info.target?.segments) ? info.target.segments : [];
@@ -119,23 +207,23 @@ export function createSuperdocHost(options) {
119
207
  async execute(id, payload) {
120
208
  const bus = commands();
121
209
  if (!bus)
122
- return NOT_READY;
210
+ return notReady();
123
211
  if (!bus.has(id))
124
- return failed(`הפקודה ${id} אינה מוכרת למנוע`, 'unknown-command');
212
+ return failed(macroMessages().unknownCommand(id), 'unknown-command');
125
213
  let result;
126
214
  try {
127
215
  result = await bus.executeAsync(id, payload);
128
216
  }
129
217
  catch (error) {
130
- return failed(error instanceof Error ? error.message : 'הפעולה נכשלה', 'threw');
218
+ return failed(error instanceof Error ? error.message : macroMessages().actionFailed, 'threw');
131
219
  }
132
- // false = ה-controller לא ניתב את הפקודה; מצב הפקד מסביר למה.
220
+ // false = the controller did not route the command; the command state explains why.
133
221
  if (result === false) {
134
222
  const reason = bus.get(id).getState().reason;
135
- return failed(reason ? `הפעולה נכשלה (${reason})` : 'הפעולה נכשלה', reason);
223
+ return failed(reason ? `${macroMessages().actionFailed} (${reason})` : macroMessages().actionFailed, reason);
136
224
  }
137
225
  if (typeof result === 'object' && result !== null) {
138
- return receiptOutcome(result, `הפקודה ${id} נכשלה`);
226
+ return receiptOutcome(result, macroMessages().commandFailed(id));
139
227
  }
140
228
  return { ok: true };
141
229
  },
@@ -143,21 +231,25 @@ export function createSuperdocHost(options) {
143
231
  async insertText(text) {
144
232
  const insert = doc()?.insert;
145
233
  if (typeof insert === 'function') {
146
- // בלי target ההכנסה נופלת לסוף המסמךלכן היעד נלקח מהבחירה החיה.
147
- const snapshot = await readSelection(false);
234
+ // Without a target the insertion falls to the end of the document so the target comes from the live selection.
235
+ const { snapshot, failed: selectionFailed } = await readSelectionDetailed(false);
236
+ // A failed read is not "no selection": inserting without a target
237
+ // would land the text at the end of the document. Fail closed.
238
+ if (selectionFailed)
239
+ return failed(macroMessages().selectionUnavailable, 'selection-read-failed');
148
240
  try {
149
241
  const receipt = await insert({
150
242
  value: text,
151
243
  type: 'text',
152
244
  ...(snapshot.selectionTarget ? { target: snapshot.selectionTarget } : {}),
153
245
  });
154
- return receiptOutcome(receipt, 'הכנסת הטקסט נכשלה');
246
+ return receiptOutcome(receipt, macroMessages().insertTextFailed);
155
247
  }
156
248
  catch (error) {
157
- return failed(error instanceof Error ? error.message : 'הכנסת הטקסט נכשלה', 'threw');
249
+ return failed(error instanceof Error ? error.message : macroMessages().insertTextFailed, 'threw');
158
250
  }
159
251
  }
160
- // נפילה לאחור: ProseMirror ישיר, כשה-Document API אינו זמין.
252
+ // Fallback: direct ProseMirror, when the Document API is unavailable.
161
253
  const pm = view();
162
254
  if (pm) {
163
255
  try {
@@ -168,16 +260,16 @@ export function createSuperdocHost(options) {
168
260
  return { ok: true };
169
261
  }
170
262
  catch (error) {
171
- return failed(error instanceof Error ? error.message : 'הכנסת הטקסט נכשלה', 'threw');
263
+ return failed(error instanceof Error ? error.message : macroMessages().insertTextFailed, 'threw');
172
264
  }
173
265
  }
174
- return NOT_READY;
266
+ return notReady();
175
267
  },
176
268
  async deleteBackward(count) {
177
- // אין משטח ציבורי למחיקהזה השימוש המרכזי ב-escape hatch של ProseMirror.
269
+ // No public deletion surfacethis is the main use of the ProseMirror escape hatch.
178
270
  const pm = view();
179
271
  if (!pm)
180
- return failed('מחיקה אינה זמינה במסמך הזה', 'view-unavailable');
272
+ return failed(macroMessages().deletionUnavailable, 'view-unavailable');
181
273
  try {
182
274
  const { from } = pm.state.selection;
183
275
  const start = Math.max(0, from - Math.max(0, Math.trunc(count)));
@@ -189,33 +281,56 @@ export function createSuperdocHost(options) {
189
281
  return { ok: true };
190
282
  }
191
283
  catch (error) {
192
- return failed(error instanceof Error ? error.message : 'המחיקה נכשלה', 'threw');
284
+ return failed(error instanceof Error ? error.message : macroMessages().deleteFailed, 'threw');
285
+ }
286
+ },
287
+ async deleteForward(count) {
288
+ const pm = view();
289
+ if (!pm)
290
+ return failed(macroMessages().deletionUnavailable, 'view-unavailable');
291
+ try {
292
+ const { from } = pm.state.selection;
293
+ const size = pm.state.doc.content.size;
294
+ const end = Math.min(size, from + Math.max(0, Math.trunc(count)));
295
+ if (end === from)
296
+ return { ok: true };
297
+ const tr = pm.state.tr;
298
+ tr.delete(from, end);
299
+ pm.dispatch(tr);
300
+ return { ok: true };
301
+ }
302
+ catch (error) {
303
+ return failed(error instanceof Error ? error.message : macroMessages().deleteFailed, 'threw');
193
304
  }
194
305
  },
195
- getSelection(options) {
196
- return readSelection(options?.includeText ?? false);
306
+ async getSelection(options) {
307
+ return (await readSelectionDetailed(options?.includeText ?? false)).snapshot;
197
308
  },
198
309
  async replaceAll(query, replacement) {
199
310
  const handle = search();
200
311
  if (!handle)
201
- return { ok: false, replaced: 0, message: 'החיפוש אינו זמין' };
312
+ return { ok: false, replaced: 0, message: macroMessages().searchUnavailable };
202
313
  try {
203
314
  handle.open?.();
204
315
  const slice = handle.search(query);
205
316
  if (slice?.available === false) {
206
- return { ok: false, replaced: 0, message: 'החיפוש אינו זמין במסמך הזה' };
317
+ return { ok: false, replaced: 0, message: macroMessages().searchUnavailableInDocument };
207
318
  }
208
319
  const total = typeof slice?.total === 'number' ? slice.total : 0;
209
320
  if (total === 0)
210
321
  return { ok: true, replaced: 0 };
211
322
  const result = await handle.replaceAll(replacement);
212
323
  if (result && result.ok === false) {
213
- return { ok: false, replaced: 0, message: `ההחלפה נכשלה${result.reason ? ` (${result.reason})` : ''}` };
324
+ return {
325
+ ok: false,
326
+ replaced: 0,
327
+ message: `${macroMessages().replaceFailed}${result.reason ? ` (${result.reason})` : ''}`,
328
+ };
214
329
  }
215
330
  return { ok: true, replaced: total };
216
331
  }
217
332
  catch (error) {
218
- return { ok: false, replaced: 0, message: error instanceof Error ? error.message : 'ההחלפה נכשלה' };
333
+ return { ok: false, replaced: 0, message: error instanceof Error ? error.message : macroMessages().replaceFailed };
219
334
  }
220
335
  finally {
221
336
  try {
@@ -223,7 +338,7 @@ export function createSuperdocHost(options) {
223
338
  handle.close?.();
224
339
  }
225
340
  catch {
226
- /* ניקוי בלבד */
341
+ /* cleanup only */
227
342
  }
228
343
  }
229
344
  },
@@ -250,6 +365,8 @@ export function createSuperdocHost(options) {
250
365
  if (wrapped && originalExecuteAsync)
251
366
  wrapped.executeAsync = originalExecuteAsync;
252
367
  container?.removeEventListener('beforeinput', onBeforeInput, true);
368
+ container?.removeEventListener('compositionstart', onCompositionStart, true);
369
+ container?.removeEventListener('compositionend', onCompositionEnd, true);
253
370
  commandListeners.clear();
254
371
  inputListeners.clear();
255
372
  },
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export type { MacroHost, MacroOutcome, MacroStep, RecordedMacro, SavedScript, SelectionSnapshot, Snippet, TextInputEvent, } from './types.js';
2
- export { MacroKit, type MacroKitOptions } from './manager.js';
2
+ export { MacroKit, type MacroKitOptions, type ShortcutValidation } from './manager.js';
3
+ export { ENGLISH_MESSAGES, HEBREW_MESSAGES, setMacroMessages, type MacroMessages, } from './messages.js';
3
4
  export { createSuperdocHost, type SuperdocHostOptions, type SuperdocLike, type SuperdocMacroHost } from './host/superdoc-host.js';
4
5
  export { createMacroApi, MacroError, type MacroApi, type MacroBridge, type ScriptSelection } from './scripting/macro-api.js';
5
6
  export { createEvalRunner } from './scripting/eval-runner.js';
@@ -8,5 +9,5 @@ export type { MacroRunner, MacroRunOptions, MacroRunResult } from './scripting/r
8
9
  export { MacroRecorder, replayMacro, type RecorderOptions, type ReplayOptions, type ReplayResult } from './recorder/recorder.js';
9
10
  export { renderSnippet, expandSnippet, usesSelection, type ExpandOptions, type RenderContext } from './snippets/snippets.js';
10
11
  export { AutoText, type AutoTextOptions } from './snippets/autotext.js';
11
- export { parseShortcut, eventMatches, bindShortcuts, type ParsedShortcut, type ShortcutBinding, type ShortcutTarget } from './shortcuts.js';
12
- export { createLocalStorage, createMemoryStorage, emptyState, parsePersistedState, DEFAULT_STORAGE_KEY, type MacroStorage, type PersistedMacroState, } from './storage.js';
12
+ export { parseShortcut, eventMatches, bindShortcuts, shortcutSignatures, hasBindingModifier, type ParsedShortcut, type ShortcutBinding, type ShortcutTarget, } from './shortcuts.js';
13
+ export { createLocalStorage, createMemoryStorage, emptyState, parsePersistedState, DEFAULT_STORAGE_KEY, IMPORT_LIMITS, type MacroStorage, type PersistedMacroState, } from './storage.js';
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { MacroKit } from './manager.js';
2
+ export { ENGLISH_MESSAGES, HEBREW_MESSAGES, setMacroMessages, } from './messages.js';
2
3
  export { createSuperdocHost } from './host/superdoc-host.js';
3
4
  export { createMacroApi, MacroError } from './scripting/macro-api.js';
4
5
  export { createEvalRunner } from './scripting/eval-runner.js';
@@ -6,5 +7,5 @@ export { createIframeRunner, SANDBOX_BOOTSTRAP, isProtocolMessage } from './scri
6
7
  export { MacroRecorder, replayMacro } from './recorder/recorder.js';
7
8
  export { renderSnippet, expandSnippet, usesSelection } from './snippets/snippets.js';
8
9
  export { AutoText } from './snippets/autotext.js';
9
- export { parseShortcut, eventMatches, bindShortcuts } from './shortcuts.js';
10
- export { createLocalStorage, createMemoryStorage, emptyState, parsePersistedState, DEFAULT_STORAGE_KEY, } from './storage.js';
10
+ export { parseShortcut, eventMatches, bindShortcuts, shortcutSignatures, hasBindingModifier, } from './shortcuts.js';
11
+ export { createLocalStorage, createMemoryStorage, emptyState, parsePersistedState, DEFAULT_STORAGE_KEY, IMPORT_LIMITS, } from './storage.js';
package/dist/manager.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * `MacroKit` — הפאסדה שמארח מתקין פעם אחת ומקבל את שלוש היכולות מחווטות:
3
- * סקריפטים (עם ארגז חול), מקליט, וקטעי טקסט עם השלמה אוטומטית — פלוס שמירה,
4
- * ייבוא/ייצוא וקיצורי מקלדת.
2
+ * `MacroKit` — the facade a host installs once to get all three capabilities
3
+ * wired together: scripts (sandboxed), the recorder, and snippets with
4
+ * auto-text plus persistence, import/export and keyboard shortcuts.
5
5
  *
6
- * כלל בטיחות אחד נאכף כאן: אין ריצה בזמן הקלטה ואין שתי ריצות במקביל.
7
- * ניגון או סקריפט שרצים תוך כדי הקלטה היו מוקלטים בעצמם ומכפילים את עצמם
8
- * בניגון הבא.
6
+ * One safety rule is enforced here: no running while recording, and no two
7
+ * runs at once. A replay or script running during a recording would be
8
+ * recorded itself and duplicate itself on the next replay.
9
9
  */
10
10
  import { type MacroApiOptions } from './scripting/macro-api.js';
11
11
  import type { MacroRunner, MacroRunOptions, MacroRunResult } from './scripting/runner.js';
@@ -17,20 +17,34 @@ import { type MacroStorage } from './storage.js';
17
17
  import type { MacroHost, RecordedMacro, SavedScript, Snippet } from './types.js';
18
18
  export interface MacroKitOptions {
19
19
  host: MacroHost;
20
- /** ברירת מחדל: localStorage. */
20
+ /** Default: localStorage. */
21
21
  storage?: MacroStorage;
22
22
  /**
23
- * `'iframe'` (ברירת המחדל) מריץ סקריפטים בארגז חול; `'eval'` מריץ ישירות —
24
- * ראו את האזהרה ב-eval-runner. אפשר גם למסור מריץ מותאם.
23
+ * `'iframe'` (the default) runs scripts in a sandbox; `'eval'` runs them
24
+ * directly see the warning in eval-runner. A custom runner can also be
25
+ * passed.
25
26
  */
26
27
  runner?: MacroRunner | 'iframe' | 'eval';
27
- /** אפשרויות ריצה לסקריפטים (זמן, תקרת קריאות). */
28
+ /** Run options for scripts (time, call cap). */
28
29
  runOptions?: MacroRunOptions;
29
- /** אפשרויות ההשלמה האוטומטית. */
30
+ /** Auto-text options. */
30
31
  autoText?: Omit<AutoTextOptions, 'onExpand' | 'onError'> & AutoTextOptions;
31
- /** יומן ריצה של `api.log`. */
32
+ /** Run log for `api.log`. */
32
33
  onLog?: MacroApiOptions['onLog'];
34
+ /**
35
+ * Shortcuts the host already owns (e.g. its ribbon registry). A saved
36
+ * binding that collides with any of these is rejected — otherwise the
37
+ * macro binding, attached in the capture phase, would silently shadow an
38
+ * editor shortcut. Unparseable entries are ignored.
39
+ */
40
+ reservedShortcuts?: readonly string[];
33
41
  }
42
+ export type ShortcutValidation = {
43
+ ok: true;
44
+ } | {
45
+ ok: false;
46
+ message: string;
47
+ };
34
48
  export declare class MacroKit {
35
49
  private readonly host;
36
50
  private readonly storage;
@@ -40,8 +54,20 @@ export declare class MacroKit {
40
54
  private state;
41
55
  private readonly recorder;
42
56
  private readonly autoText;
57
+ private readonly reservedSignatures;
43
58
  private running;
44
59
  constructor(options: MacroKitOptions);
60
+ /**
61
+ * Whether a shortcut is acceptable for a saved binding: parseable, carries
62
+ * a real modifier, not reserved by the host, and not already used by
63
+ * another saved item (`excludeId` skips the item being edited). Empty or
64
+ * undefined means "no shortcut" and is fine. The save paths enforce this;
65
+ * UIs call it directly to show the message before saving.
66
+ */
67
+ validateShortcut(shortcut: string | undefined, excludeId?: string): ShortcutValidation;
68
+ private findShortcutOwner;
69
+ /** Throws a MacroError when the shortcut is unacceptable. The save paths call this. */
70
+ private requireValidShortcut;
45
71
  listScripts(): readonly SavedScript[];
46
72
  saveScript(input: {
47
73
  id?: string;
@@ -51,17 +77,17 @@ export declare class MacroKit {
51
77
  }): SavedScript;
52
78
  removeScript(id: string): void;
53
79
  runScript(id: string): Promise<MacroRunResult>;
54
- /** מריצה סקריפט שלא נשמרלמשל מתוך עורך המאקרו לפני שמירה. */
80
+ /** Runs an unsaved scripte.g. from the macro editor before saving. */
55
81
  runSource(source: string): Promise<MacroRunResult>;
56
82
  get isRecording(): boolean;
57
83
  get recordedStepCount(): number;
58
84
  startRecording(): void;
59
- /** עוצרת ושומרת. `null` כשלא הוקלט אף צעדאין מה לשמור. */
85
+ /** Stops and saves. `null` when no step was recorded there is nothing to save. */
60
86
  stopRecording(name: string, shortcut?: string): RecordedMacro | null;
61
87
  cancelRecording(): void;
62
88
  listRecordings(): readonly RecordedMacro[];
63
89
  removeRecording(id: string): void;
64
- /** עדכון שם או קיצור של הקלטה קיימת. `null` כשההקלטה לא נמצאה. */
90
+ /** Renames a recording or edits its shortcut. `null` when the recording was not found. */
65
91
  updateRecording(input: {
66
92
  id: string;
67
93
  name?: string;
@@ -81,20 +107,22 @@ export declare class MacroKit {
81
107
  ok: boolean;
82
108
  message?: string;
83
109
  }>;
84
- /** מפעילה השלמה אוטומטית (trigger + רווח). מחזירה פונקציית כיבוי. */
110
+ /** Enables auto-text (trigger + space). Returns a disable function. */
85
111
  enableAutoText(): () => void;
86
112
  disableAutoText(): void;
87
113
  /**
88
- * קושרת את הקיצורים של כל מה ששמור (סקריפטים, הקלטות, קטעים) ליעד — בדרך
89
- * כלל ה-container של העורך או `window`. הרשימה חיה: שמירה חדשה נקלטת בלי
90
- * לקשור מחדש. מחזירה פונקציית ניתוק.
114
+ * Binds the shortcuts of everything saved (scripts, recordings, snippets)
115
+ * to a target usually the editor container or `window`. The list is
116
+ * live: a new save is picked up without rebinding. Returns a dispose
117
+ * function.
91
118
  */
92
119
  attachShortcuts(target: ShortcutTarget): () => void;
93
120
  private currentBindings;
94
121
  exportState(): string;
95
122
  /**
96
- * ייבוא מ-JSON שיוצא ב-`exportState`. במיזוג (`merge: true`) פריט מיובא עם
97
- * `id` קיים מחליף את הקיים; בלי מיזוג המצב כולו מוחלף.
123
+ * Imports JSON produced by `exportState`. With `merge: true` an imported
124
+ * item with an existing `id` replaces it; without merge the whole state is
125
+ * replaced.
98
126
  */
99
127
  importState(json: string, options?: {
100
128
  merge?: boolean;