@appsoftwareltd/etherpk-extension-api 0.12.0 → 0.13.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/assets.d.ts +23 -0
- package/dist/assets.js +5 -0
- package/dist/context.d.ts +70 -5
- package/dist/documents.d.ts +146 -0
- package/dist/documents.js +12 -0
- package/dist/editor.d.ts +80 -0
- package/dist/index.d.ts +7 -3
- package/dist/menus.d.ts +24 -0
- package/dist/records.d.ts +29 -0
- package/dist/records.js +7 -0
- package/dist/settings-sections.d.ts +56 -0
- package/dist/settings-sections.js +1 -0
- package/package.json +1 -1
package/dist/assets.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Images an extension hands to the open graph (ADR 0147): made smaller the way a pasted image is,
|
|
3
|
+
* and kept as one of the graph's assets, so a document can show it.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* The open graph's assets, as far as an extension may add to them.
|
|
7
|
+
*
|
|
8
|
+
* @beta
|
|
9
|
+
*/
|
|
10
|
+
export interface ExtensionAssets {
|
|
11
|
+
/**
|
|
12
|
+
* An image made ready to send or keep, as a pasted image is: a large photo or screenshot is
|
|
13
|
+
* scaled down and re-encoded, and an image that is small enough comes back as it was. Rejects
|
|
14
|
+
* when the bytes are not an image the browser can read.
|
|
15
|
+
*/
|
|
16
|
+
prepareImage(image: Blob): Promise<Blob>;
|
|
17
|
+
/**
|
|
18
|
+
* Keep an image as one of the graph's assets, and answer the markdown that shows it in a
|
|
19
|
+
* document, such as ``. Null where the graph keeps no assets here,
|
|
20
|
+
* or the image was refused.
|
|
21
|
+
*/
|
|
22
|
+
saveImage(image: Blob, name: string): Promise<string | null>;
|
|
23
|
+
}
|
package/dist/assets.js
ADDED
package/dist/context.d.ts
CHANGED
|
@@ -7,14 +7,18 @@
|
|
|
7
7
|
* only through the index's answers and its own fences, and changes them only through its fences,
|
|
8
8
|
* the blocks it puts at the caret and the Client's Commands.
|
|
9
9
|
*/
|
|
10
|
+
import type { ExtensionAssets } from './assets';
|
|
10
11
|
import type { ExtensionAuth } from './auth';
|
|
11
12
|
import type { ExtensionDialogs } from './dialogs';
|
|
13
|
+
import type { ExtensionDocuments } from './documents';
|
|
12
14
|
import type { ExtensionEditor } from './editor';
|
|
13
15
|
import type { ExtensionEmbeds } from './embeds';
|
|
14
16
|
import type { ExtensionEvents } from './events';
|
|
15
17
|
import type { ExtensionIndex } from './graph-index';
|
|
16
18
|
import type { ExtensionJournalPanels } from './journal';
|
|
17
|
-
import type { CommandMenuItem, ContextMenuItem, GraphSidebarButton } from './menus';
|
|
19
|
+
import type { CommandBarButton, CommandMenuItem, ContextMenuItem, GraphSidebarButton } from './menus';
|
|
20
|
+
import type { ExtensionGraphRecords } from './records';
|
|
21
|
+
import type { SettingsSection } from './settings-sections';
|
|
18
22
|
import type { ViewContribution, ViewRef } from './views';
|
|
19
23
|
/**
|
|
20
24
|
* A Command's handler. What it returns, or resolves to, is what `execute` resolves to.
|
|
@@ -73,6 +77,16 @@ export interface ExtensionCommandMenu {
|
|
|
73
77
|
/** Add a row, its id under the extension's id. */
|
|
74
78
|
register(item: CommandMenuItem): () => void;
|
|
75
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Adding buttons to the Command Bar, the row of buttons across the bottom of a phone's screen:
|
|
82
|
+
* after the editing buttons that scroll, or in the pinned group at its right end.
|
|
83
|
+
*
|
|
84
|
+
* @beta
|
|
85
|
+
*/
|
|
86
|
+
export interface ExtensionCommandBar {
|
|
87
|
+
/** Add a button, its id under the extension's id. */
|
|
88
|
+
register(button: CommandBarButton): () => void;
|
|
89
|
+
}
|
|
76
90
|
/**
|
|
77
91
|
* Adding buttons to the Graph Sidebar's group of action buttons, after Search and today's date.
|
|
78
92
|
*
|
|
@@ -146,6 +160,26 @@ export interface ExtensionLayout {
|
|
|
146
160
|
activeDocument(): string | null;
|
|
147
161
|
/** True while the desktop presenter is showing, 1024 pixels wide and more. */
|
|
148
162
|
isDesktop(): boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Draw something over the whole EtherPK window, with a heading and a close button the Client
|
|
165
|
+
* draws, as a fence's widget opens over the window. One at a time: opening another closes the
|
|
166
|
+
* one before. The close button, Escape and `close` all close it, and `onClose` is told once.
|
|
167
|
+
*
|
|
168
|
+
* @beta
|
|
169
|
+
*/
|
|
170
|
+
openWindow(options: {
|
|
171
|
+
/** The heading the Client draws beside the close button. */
|
|
172
|
+
title: string;
|
|
173
|
+
/** Draw into `host`, which fills the window under the heading. */
|
|
174
|
+
mount(host: HTMLElement, window: {
|
|
175
|
+
close(): void;
|
|
176
|
+
}): {
|
|
177
|
+
destroy(): void;
|
|
178
|
+
};
|
|
179
|
+
onClose?(): void;
|
|
180
|
+
}): {
|
|
181
|
+
close(): void;
|
|
182
|
+
};
|
|
149
183
|
}
|
|
150
184
|
/**
|
|
151
185
|
* The rules for naming a concept, which every index answer follows.
|
|
@@ -203,15 +237,15 @@ export interface ExtensionSettings {
|
|
|
203
237
|
}
|
|
204
238
|
/**
|
|
205
239
|
* The extension's own records, kept with the person (ADR 0140): on this device, and where the
|
|
206
|
-
* person's account syncs a graph, in that account's
|
|
207
|
-
* person's own devices can read them. So a record follows the person to their other devices, as
|
|
240
|
+
* person's account syncs a graph, in that account's Settings Vault too, encrypted on the device so
|
|
241
|
+
* only the person's own devices can read them. So a record follows the person to their other devices, as
|
|
208
242
|
* Extension Settings do, such as what signing in to another service gave the extension. The person
|
|
209
243
|
* never sees these records, and uninstalling the extension clears them on every device.
|
|
210
244
|
*
|
|
211
245
|
* Each record is kept as JSON, at most 64 KB of it. Between two devices the later change to a
|
|
212
246
|
* record wins, record by record. A record is readable on the device by any code in the page, as
|
|
213
|
-
* localStorage is
|
|
214
|
-
* the
|
|
247
|
+
* localStorage is. A Headless Client signed in to the same account cannot read it: the Sync Server
|
|
248
|
+
* never gives an agent token the Settings Vault (ADR 0148).
|
|
215
249
|
*
|
|
216
250
|
* @public
|
|
217
251
|
*/
|
|
@@ -335,6 +369,12 @@ export interface ExtensionContext {
|
|
|
335
369
|
readonly commandMenu: ExtensionCommandMenu;
|
|
336
370
|
/** Adding buttons to the Graph Sidebar. */
|
|
337
371
|
readonly graphSidebar: ExtensionGraphSidebar;
|
|
372
|
+
/**
|
|
373
|
+
* Adding buttons to the phone's Command Bar.
|
|
374
|
+
*
|
|
375
|
+
* @beta
|
|
376
|
+
*/
|
|
377
|
+
readonly commandBar: ExtensionCommandBar;
|
|
338
378
|
/** Adding panels beneath each Journal Entry. */
|
|
339
379
|
readonly journalPanels: ExtensionJournalPanels;
|
|
340
380
|
/**
|
|
@@ -357,6 +397,24 @@ export interface ExtensionContext {
|
|
|
357
397
|
* @beta
|
|
358
398
|
*/
|
|
359
399
|
readonly index: ExtensionIndex;
|
|
400
|
+
/**
|
|
401
|
+
* Reading the open graph's documents, with every Protected Document left out, name and all.
|
|
402
|
+
*
|
|
403
|
+
* @beta
|
|
404
|
+
*/
|
|
405
|
+
readonly documents: ExtensionDocuments;
|
|
406
|
+
/**
|
|
407
|
+
* The extension's records for the open graph, kept on this device only.
|
|
408
|
+
*
|
|
409
|
+
* @beta
|
|
410
|
+
*/
|
|
411
|
+
readonly records: ExtensionGraphRecords;
|
|
412
|
+
/**
|
|
413
|
+
* Images kept as the open graph's assets.
|
|
414
|
+
*
|
|
415
|
+
* @beta
|
|
416
|
+
*/
|
|
417
|
+
readonly assets: ExtensionAssets;
|
|
360
418
|
/** Opening Views and documents. */
|
|
361
419
|
readonly layout: ExtensionLayout;
|
|
362
420
|
/**
|
|
@@ -402,4 +460,11 @@ export interface ExtensionModule {
|
|
|
402
460
|
* called after that, for anything else the extension holds.
|
|
403
461
|
*/
|
|
404
462
|
activate(context: ExtensionContext): void | (() => void);
|
|
463
|
+
/**
|
|
464
|
+
* Sections the extension adds to the Client's settings tabs, which the Client mounts while the
|
|
465
|
+
* extension is switched on, whether or not a graph is open.
|
|
466
|
+
*
|
|
467
|
+
* @beta
|
|
468
|
+
*/
|
|
469
|
+
settingsSections?: readonly SettingsSection[];
|
|
405
470
|
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading the open graph's documents, as a language model may read them for a person (ADR 0147).
|
|
3
|
+
*
|
|
4
|
+
* Every answer leaves out a [[Protected Document]] entirely: not its content, and not its name
|
|
5
|
+
* either, even while the person holds the Protection Key. That is stricter than the index's
|
|
6
|
+
* answers (`context.index`), which list a Protected Document by name, because what an extension
|
|
7
|
+
* reads here may be sent to a model provider. A document whose text holds an encrypted fence
|
|
8
|
+
* anywhere counts as protected here too.
|
|
9
|
+
*
|
|
10
|
+
* Every answer is bounded: a list is paged, and a document's text is cut at a cap and says so.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* A document as a listing names it.
|
|
14
|
+
*
|
|
15
|
+
* @beta
|
|
16
|
+
*/
|
|
17
|
+
export interface DocumentSummary {
|
|
18
|
+
/** The document's name: a page's title, or a journal entry's day, `YYYY-MM-DD`. */
|
|
19
|
+
name: string;
|
|
20
|
+
/** A page or a journal entry. */
|
|
21
|
+
kind: 'page' | 'journal';
|
|
22
|
+
/** The page's other names. */
|
|
23
|
+
aliases: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A document's text, as {@link ExtensionDocuments.read} answers.
|
|
27
|
+
*
|
|
28
|
+
* @beta
|
|
29
|
+
*/
|
|
30
|
+
export interface DocumentText extends DocumentSummary {
|
|
31
|
+
/** The body: the text after the frontmatter block, cut at the cap. */
|
|
32
|
+
text: string;
|
|
33
|
+
/** True when the text was cut at the cap. */
|
|
34
|
+
truncated: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* One document a search matched, with the lines that matched.
|
|
38
|
+
*
|
|
39
|
+
* @beta
|
|
40
|
+
*/
|
|
41
|
+
export interface DocumentSearchResult extends Omit<DocumentSummary, 'aliases'> {
|
|
42
|
+
/** How many lines matched. */
|
|
43
|
+
matches: number;
|
|
44
|
+
/** The matching lines, best first. */
|
|
45
|
+
hits: {
|
|
46
|
+
/** The line's number in the document's text, from 0. */
|
|
47
|
+
line: number;
|
|
48
|
+
/** The labels of the blocks the line sits under, outermost first. */
|
|
49
|
+
breadcrumb: string[];
|
|
50
|
+
/** The line's text around the match. */
|
|
51
|
+
snippet: string;
|
|
52
|
+
}[];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* One document whose text links to the concept asked about, with each place it does.
|
|
56
|
+
*
|
|
57
|
+
* @beta
|
|
58
|
+
*/
|
|
59
|
+
export interface DocumentBacklink extends Omit<DocumentSummary, 'aliases'> {
|
|
60
|
+
references: {
|
|
61
|
+
/** The line's number in the source's text, from 0. */
|
|
62
|
+
line: number;
|
|
63
|
+
/** The labels of the blocks the reference sits under, outermost first. */
|
|
64
|
+
breadcrumb: string[];
|
|
65
|
+
/** The block holding the link with its children, or the prose around it. */
|
|
66
|
+
text: string;
|
|
67
|
+
}[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* One task, as the Tasks View lists it.
|
|
71
|
+
*
|
|
72
|
+
* @beta
|
|
73
|
+
*/
|
|
74
|
+
export interface DocumentTask extends Omit<DocumentSummary, 'aliases'> {
|
|
75
|
+
/** The task's line in the document's text, from 0. */
|
|
76
|
+
line: number;
|
|
77
|
+
/** The task's words, without the checkbox. */
|
|
78
|
+
text: string;
|
|
79
|
+
status: 'open' | 'doing' | 'waiting' | 'done' | 'cancelled';
|
|
80
|
+
/** 1 is the highest; null when the task has none. */
|
|
81
|
+
priority: 1 | 2 | 3 | null;
|
|
82
|
+
/** `YYYY-MM-DD`, or null. */
|
|
83
|
+
due: string | null;
|
|
84
|
+
/** `YYYY-MM-DD`, or null. */
|
|
85
|
+
scheduled: string | null;
|
|
86
|
+
/** The labels of the blocks the task sits under, outermost first. */
|
|
87
|
+
breadcrumb: string[];
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Reading the open graph's documents.
|
|
91
|
+
*
|
|
92
|
+
* @beta
|
|
93
|
+
*/
|
|
94
|
+
export interface ExtensionDocuments {
|
|
95
|
+
/** Pages and journal entries, journals newest first and then pages by name, a page at a time. */
|
|
96
|
+
list(options?: {
|
|
97
|
+
kind?: 'page' | 'journal';
|
|
98
|
+
offset?: number;
|
|
99
|
+
limit?: number;
|
|
100
|
+
}): Promise<{
|
|
101
|
+
documents: DocumentSummary[];
|
|
102
|
+
total: number;
|
|
103
|
+
hasMore: boolean;
|
|
104
|
+
}>;
|
|
105
|
+
/**
|
|
106
|
+
* A document's text by its name or an alias, or null when there is no such document or it is
|
|
107
|
+
* protected. The text is the document as it is now, edits not yet saved included.
|
|
108
|
+
*/
|
|
109
|
+
read(name: string): Promise<DocumentText | null>;
|
|
110
|
+
/**
|
|
111
|
+
* The names of the documents a document's wikilinks name directly, in the order they first
|
|
112
|
+
* appear, each once. Names with no document, and protected documents, are left out. Null when
|
|
113
|
+
* the document cannot be read.
|
|
114
|
+
*/
|
|
115
|
+
links(name: string): Promise<string[] | null>;
|
|
116
|
+
/** The documents whose text matches the words, best first, a page at a time. */
|
|
117
|
+
search(query: string, options?: {
|
|
118
|
+
offset?: number;
|
|
119
|
+
limit?: number;
|
|
120
|
+
}): Promise<{
|
|
121
|
+
results: DocumentSearchResult[];
|
|
122
|
+
total: number;
|
|
123
|
+
hasMore: boolean;
|
|
124
|
+
}>;
|
|
125
|
+
/** The documents that link to a concept, or null when the concept is a protected document. */
|
|
126
|
+
backlinks(name: string): Promise<DocumentBacklink[] | null>;
|
|
127
|
+
/**
|
|
128
|
+
* How the graph's documents are written, as the Client describes it to agents: names and
|
|
129
|
+
* wikilinks, the outline, tasks and the rest of the syntax, in markdown. The same words the
|
|
130
|
+
* `AGENTS.md` of a graph folder carries, less what is about files on a disk, so a model reading
|
|
131
|
+
* the graph's text understands it and names documents as `[[Name]]`.
|
|
132
|
+
*/
|
|
133
|
+
formatGuide(): string;
|
|
134
|
+
/** Tasks, open ones unless asked otherwise, of one concept or of the whole graph, a page at a time. */
|
|
135
|
+
tasks(options?: {
|
|
136
|
+
/** Only the tasks that answer to this concept. */
|
|
137
|
+
concept?: string;
|
|
138
|
+
statuses?: DocumentTask['status'][];
|
|
139
|
+
offset?: number;
|
|
140
|
+
limit?: number;
|
|
141
|
+
}): Promise<{
|
|
142
|
+
tasks: DocumentTask[];
|
|
143
|
+
total: number;
|
|
144
|
+
hasMore: boolean;
|
|
145
|
+
}>;
|
|
146
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading the open graph's documents, as a language model may read them for a person (ADR 0147).
|
|
3
|
+
*
|
|
4
|
+
* Every answer leaves out a [[Protected Document]] entirely: not its content, and not its name
|
|
5
|
+
* either, even while the person holds the Protection Key. That is stricter than the index's
|
|
6
|
+
* answers (`context.index`), which list a Protected Document by name, because what an extension
|
|
7
|
+
* reads here may be sent to a model provider. A document whose text holds an encrypted fence
|
|
8
|
+
* anywhere counts as protected here too.
|
|
9
|
+
*
|
|
10
|
+
* Every answer is bounded: a list is paged, and a document's text is cut at a cap and says so.
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
package/dist/editor.d.ts
CHANGED
|
@@ -236,6 +236,72 @@ export interface FenceOptions {
|
|
|
236
236
|
*/
|
|
237
237
|
keepsHistory?: boolean;
|
|
238
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* A panel an extension draws in a document, beneath one of its lines, which is not part of the
|
|
241
|
+
* document's text: nothing of it is saved, synced or seen on another device (ADR 0147).
|
|
242
|
+
*
|
|
243
|
+
* The panel follows its line as the document changes, here or on another device, and moves with
|
|
244
|
+
* the editor when the editor is rebuilt (a Draft becoming a document, say). It closes when the
|
|
245
|
+
* person closes it, or when the document's editor closes for good: the panel lasts for the visit.
|
|
246
|
+
*
|
|
247
|
+
* @beta
|
|
248
|
+
*/
|
|
249
|
+
export interface InlinePanel {
|
|
250
|
+
/** The document the panel is in, by its concept. */
|
|
251
|
+
readonly document: string | null;
|
|
252
|
+
/** False once the panel has closed. */
|
|
253
|
+
readonly isOpen: boolean;
|
|
254
|
+
/**
|
|
255
|
+
* Put a block at the panel's line, by the rule {@link ExtensionEditor.insertBlock} follows at the
|
|
256
|
+
* caret: an empty line is replaced, an empty bullet takes an outline's place at its own
|
|
257
|
+
* indentation (or any other block as its content), and after any other line the block goes on new
|
|
258
|
+
* lines beneath at the line's content column. The panel then sits beneath the block, and the next
|
|
259
|
+
* block goes after it at the indentation of its first line. One undoable change. False where
|
|
260
|
+
* nothing was put in: the panel is closed, its editor has closed, or its line is now in the
|
|
261
|
+
* frontmatter, a fenced block or a table.
|
|
262
|
+
*/
|
|
263
|
+
insertBlock(text: string): boolean;
|
|
264
|
+
/** Bring the panel into view. */
|
|
265
|
+
focus(): void;
|
|
266
|
+
/**
|
|
267
|
+
* Give the panel a new height in CSS pixels, which its content scrolls inside: the lines below
|
|
268
|
+
* it move once. Grow it when there is more to show, rather than on every change.
|
|
269
|
+
*/
|
|
270
|
+
resize(height: number): void;
|
|
271
|
+
/**
|
|
272
|
+
* The outline around the panel's line, as the document writes it: the line's ancestors, each its
|
|
273
|
+
* own lines without its other children, and its siblings with their branches, the line's own
|
|
274
|
+
* branch among them while the line has text. A block the panel put in is left out. Null when
|
|
275
|
+
* the line is not a bullet, or the panel is closed or under the document's last line.
|
|
276
|
+
*/
|
|
277
|
+
outline(): string | null;
|
|
278
|
+
/** Close the panel. Its `onClose` is told. */
|
|
279
|
+
close(): void;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* What an inline panel is drawn with.
|
|
283
|
+
*
|
|
284
|
+
* @beta
|
|
285
|
+
*/
|
|
286
|
+
export interface InlinePanelOptions {
|
|
287
|
+
/**
|
|
288
|
+
* The panel's height in CSS pixels, which its content scrolls inside, so the lines below never
|
|
289
|
+
* move as its content grows. {@link InlinePanel.resize} changes it.
|
|
290
|
+
*/
|
|
291
|
+
height?: number;
|
|
292
|
+
/**
|
|
293
|
+
* Draw the panel into `host`, which the Client owns and places. Called once, when the panel is
|
|
294
|
+
* first drawn: the host keeps its content while the panel is scrolled out of view and when the
|
|
295
|
+
* editor is rebuilt, and `destroy` is called when the panel closes. Events inside the host are
|
|
296
|
+
* the panel's own: the editor neither types nor moves its caret for them, but Mod+Z and Mod+Y
|
|
297
|
+
* outside a text field undo and redo in the document.
|
|
298
|
+
*/
|
|
299
|
+
mount(host: HTMLElement, panel: InlinePanel): {
|
|
300
|
+
destroy(): void;
|
|
301
|
+
};
|
|
302
|
+
/** Told once, when the panel closes for any reason. */
|
|
303
|
+
onClose?(): void;
|
|
304
|
+
}
|
|
239
305
|
/**
|
|
240
306
|
* The document editor, as far as an extension may reach it.
|
|
241
307
|
*
|
|
@@ -263,4 +329,18 @@ export interface ExtensionEditor {
|
|
|
263
329
|
insertBlock(text: string, options?: {
|
|
264
330
|
focus?: boolean;
|
|
265
331
|
}): boolean;
|
|
332
|
+
/**
|
|
333
|
+
* Draw a panel beneath the caret's line in the editor the person is working in, from where the
|
|
334
|
+
* line's text starts, or beside the dot of an empty bullet, as a code block opened there is. With
|
|
335
|
+
* `at` `end`, it is drawn beneath the document's last line, at the editor's left edge, a line's
|
|
336
|
+
* height clear of it. With `caret-or-end`, at the caret while the person is typing in the
|
|
337
|
+
* document (the editor has the keyboard, as a Command Bar button leaves it), else at the end: for
|
|
338
|
+
* a button pressed from outside the text. Null where no panel can go: no editor, a Protected
|
|
339
|
+
* Document, or a caret in the frontmatter, a fenced block or a table.
|
|
340
|
+
*
|
|
341
|
+
* @beta
|
|
342
|
+
*/
|
|
343
|
+
openPanel(options: InlinePanelOptions & {
|
|
344
|
+
at?: 'caret' | 'end' | 'caret-or-end';
|
|
345
|
+
}): InlinePanel | null;
|
|
266
346
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,15 +14,19 @@
|
|
|
14
14
|
*
|
|
15
15
|
* @packageDocumentation
|
|
16
16
|
*/
|
|
17
|
-
export type { CommandHandler, ExtensionCommandMenu, ExtensionCommands, ExtensionConcepts, ExtensionContext, ExtensionContextMenu, ExtensionContributions, ExtensionGraphSidebar, ExtensionIcons, ExtensionKeybindings, ExtensionLayout, ExtensionModule, ExtensionPersonStorage, ExtensionSettings, ExtensionStorage, ExtensionTheme, ExtensionViews, IconMarkup, Keybinding, } from './context';
|
|
17
|
+
export type { CommandHandler, ExtensionCommandBar, ExtensionCommandMenu, ExtensionCommands, ExtensionConcepts, ExtensionContext, ExtensionContextMenu, ExtensionContributions, ExtensionGraphSidebar, ExtensionIcons, ExtensionKeybindings, ExtensionLayout, ExtensionModule, ExtensionPersonStorage, ExtensionSettings, ExtensionStorage, ExtensionTheme, ExtensionViews, IconMarkup, Keybinding, } from './context';
|
|
18
|
+
export type { ExtensionAssets } from './assets';
|
|
18
19
|
export type { AuthorizeOptions, ExtensionAuth } from './auth';
|
|
19
20
|
export type { ExtensionDialogs, PromptOptions } from './dialogs';
|
|
20
|
-
export type {
|
|
21
|
+
export type { DocumentBacklink, DocumentSearchResult, DocumentSummary, DocumentTask, DocumentText, ExtensionDocuments } from './documents';
|
|
22
|
+
export type { ExtensionEditor, FenceContext, FenceEdit, FenceInfo, FenceOptions, FencePresentation, FenceWidget, InlinePanel, InlinePanelOptions, MountedFence, PublishedFence, PublishFenceRequest, QuoteFenceRequest, } from './editor';
|
|
21
23
|
export type { ExtensionEmbeds, FrameOptions } from './embeds';
|
|
22
24
|
export type { ExtensionEventName, ExtensionEventPayloads, ExtensionEvents } from './events';
|
|
23
25
|
export type { ConceptCandidate, ConceptKind, ExtensionIndex, IndexUpdate, LinkGraph, LinkGraphConcept, LinkGraphLink } from './graph-index';
|
|
24
26
|
export type { ExtensionJournalPanels, JournalPanel, JournalPanelProps, MountedJournalPanel } from './journal';
|
|
25
27
|
export type { ExtensionIsolation, ExtensionManifest, ExtensionPackage, ReadExtensionPackageResult, SettingDeclaration, ViewDeclaration, ViewRegion, } from './manifest';
|
|
26
28
|
export { readExtensionPackage } from './manifest';
|
|
27
|
-
export type { CommandMenuContext, CommandMenuItem, ContextMenuItem, DocumentMenuTarget, ExtensionMenuTarget, GraphSidebarButton, MenuTarget, TabMenuTarget, WikilinkMenuTarget, } from './menus';
|
|
29
|
+
export type { CommandBarButton, CommandMenuContext, CommandMenuItem, ContextMenuItem, DocumentMenuTarget, ExtensionMenuTarget, GraphSidebarButton, MenuTarget, TabMenuTarget, WikilinkMenuTarget, } from './menus';
|
|
30
|
+
export type { ExtensionGraphRecords } from './records';
|
|
31
|
+
export type { MountedSettingsSection, SettingsSection, SettingsSectionContext, SettingsSectionTab } from './settings-sections';
|
|
28
32
|
export type { MountedView, ViewContribution, ViewMountProps, ViewRef, ViewVisibility } from './views';
|
package/dist/menus.d.ts
CHANGED
|
@@ -149,6 +149,30 @@ export interface CommandMenuItem {
|
|
|
149
149
|
*/
|
|
150
150
|
args?: unknown;
|
|
151
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* A button on the Command Bar, the row of buttons across the bottom of a phone's screen. Pressing
|
|
154
|
+
* it runs `command` and leaves the keyboard where it was, so a Command can tell whether the caret
|
|
155
|
+
* is in the document.
|
|
156
|
+
*
|
|
157
|
+
* @beta
|
|
158
|
+
*/
|
|
159
|
+
export interface CommandBarButton {
|
|
160
|
+
/** Under the extension's id. */
|
|
161
|
+
id: string;
|
|
162
|
+
/** The button's name, said to a screen reader and shown as its tooltip: the bar shows icons only. */
|
|
163
|
+
title: string;
|
|
164
|
+
/** Its icon: the extension's own or one of the Client's. */
|
|
165
|
+
icon: string;
|
|
166
|
+
/**
|
|
167
|
+
* In the bar's pinned group at its right end, which never scrolls away, rather than after the
|
|
168
|
+
* editing buttons that scroll. For an action a person reaches for often.
|
|
169
|
+
*/
|
|
170
|
+
pinned?: boolean;
|
|
171
|
+
/** The Command the button runs. */
|
|
172
|
+
command: string;
|
|
173
|
+
/** What the Command is given. */
|
|
174
|
+
args?: unknown;
|
|
175
|
+
}
|
|
152
176
|
/**
|
|
153
177
|
* A button in the Graph Sidebar's group of action buttons, after Search and today's date: a way in
|
|
154
178
|
* to what the extension shows for the whole graph, such as the Graph Map. Pressing it runs
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Records an extension keeps on this device for the open graph alone (ADR 0147): never synced,
|
|
3
|
+
* never seen by another device or another member, and deleted when the graph's data is removed
|
|
4
|
+
* from the device. For what is the person's work on this device, such as a chat they have not
|
|
5
|
+
* saved, rather than a preference that should follow them (`personStorage`).
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* The extension's records for the open graph on this device.
|
|
9
|
+
*
|
|
10
|
+
* Each record is stored as the browser's structured clone of the value, so it may hold a `Blob`,
|
|
11
|
+
* an `ArrayBuffer`, a `Date` or plain data, but no function. Records live in the browser's
|
|
12
|
+
* IndexedDB, which a private window or a full disk may refuse: a refused write rejects, and a
|
|
13
|
+
* refused read answers as if there were nothing.
|
|
14
|
+
*
|
|
15
|
+
* @beta
|
|
16
|
+
*/
|
|
17
|
+
export interface ExtensionGraphRecords {
|
|
18
|
+
/** The record under `key`, or undefined when there is none. */
|
|
19
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
20
|
+
/**
|
|
21
|
+
* Keep a record under `key`: letters, digits, `.`, `_`, `:` and `-`, at most 200 of them.
|
|
22
|
+
* Rejects when the key is not one of those or the browser refuses the write.
|
|
23
|
+
*/
|
|
24
|
+
set(key: string, value: unknown): Promise<void>;
|
|
25
|
+
/** Remove the record under `key`. */
|
|
26
|
+
remove(key: string): Promise<void>;
|
|
27
|
+
/** The keys of every record the extension keeps for the open graph, sorted. */
|
|
28
|
+
keys(): Promise<string[]>;
|
|
29
|
+
}
|
package/dist/records.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Records an extension keeps on this device for the open graph alone (ADR 0147): never synced,
|
|
3
|
+
* never seen by another device or another member, and deleted when the graph's data is removed
|
|
4
|
+
* from the device. For what is the person's work on this device, such as a chat they have not
|
|
5
|
+
* saved, rather than a preference that should follow them (`personStorage`).
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An extension's own section in one of the Client's settings tabs (ADR 0134, amended 2026-10-15),
|
|
3
|
+
* which the Client mounts with or without a graph open: on the Graphs page, and in a graph's
|
|
4
|
+
* settings. For settings that belong to the person and need more than the fields a manifest can
|
|
5
|
+
* declare, such as a list of accounts with a button that connects one.
|
|
6
|
+
*/
|
|
7
|
+
import type { ExtensionAuth } from './auth';
|
|
8
|
+
import type { ExtensionPersonStorage, ExtensionSettings, ExtensionTheme } from './context';
|
|
9
|
+
/**
|
|
10
|
+
* The tabs an extension's settings section can go in.
|
|
11
|
+
*
|
|
12
|
+
* @beta
|
|
13
|
+
*/
|
|
14
|
+
export type SettingsSectionTab = 'agents';
|
|
15
|
+
/**
|
|
16
|
+
* What a settings section is mounted with: what belongs to the person, and nothing from a graph,
|
|
17
|
+
* since there may be no graph open.
|
|
18
|
+
*
|
|
19
|
+
* @beta
|
|
20
|
+
*/
|
|
21
|
+
export interface SettingsSectionContext {
|
|
22
|
+
/** The extension's id, from its manifest. */
|
|
23
|
+
readonly extensionId: string;
|
|
24
|
+
/** The person's answers to the settings the manifest declares. */
|
|
25
|
+
readonly settings: ExtensionSettings;
|
|
26
|
+
/** The extension's records kept with the person. */
|
|
27
|
+
readonly personStorage: ExtensionPersonStorage;
|
|
28
|
+
/** Signing in to another service. */
|
|
29
|
+
readonly auth: ExtensionAuth;
|
|
30
|
+
/** The Client's light or dark theme. */
|
|
31
|
+
readonly theme: ExtensionTheme;
|
|
32
|
+
/** Say something in passing, as the Client's own notices do. */
|
|
33
|
+
notify(text: string): void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A section the section's host element shows, as the Client drives it.
|
|
37
|
+
*
|
|
38
|
+
* @beta
|
|
39
|
+
*/
|
|
40
|
+
export interface MountedSettingsSection {
|
|
41
|
+
/** The tab closed, or the extension was switched off. */
|
|
42
|
+
destroy(): void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* One settings section an extension adds.
|
|
46
|
+
*
|
|
47
|
+
* @beta
|
|
48
|
+
*/
|
|
49
|
+
export interface SettingsSection {
|
|
50
|
+
/** Unique within the extension. */
|
|
51
|
+
id: string;
|
|
52
|
+
/** The tab it goes in. */
|
|
53
|
+
tab: SettingsSectionTab;
|
|
54
|
+
/** Draw the section into `element`, which is empty and is the extension's alone. */
|
|
55
|
+
mount(element: HTMLElement, context: SettingsSectionContext): MountedSettingsSection;
|
|
56
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appsoftwareltd/etherpk-extension-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "The API an EtherPK extension is written against: the context it is started with, its manifest, and the contract its Views follow.",
|
|
6
6
|
"type": "module",
|