codesynapt 0.0.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/CHANGELOG.md +17 -0
- package/LICENSE +686 -0
- package/LICENSES.md +141 -0
- package/README.md +331 -0
- package/electron/main.cjs +2849 -0
- package/electron/plugin-loader.cjs +184 -0
- package/electron/preload.cjs +108 -0
- package/package.json +216 -0
- package/packages/core/bin/codesynapt-mcp.cjs +611 -0
- package/packages/core/bin/codesynapt.cjs +1933 -0
- package/packages/core/legacy.js +300 -0
- package/packages/core/lib/control-server.cjs +1539 -0
- package/packages/core/lib/embedding.cjs +89 -0
- package/packages/core/lib/logger.cjs +63 -0
- package/packages/core/lib/search-cache.cjs +140 -0
- package/packages/core/lib/search-worker.cjs +255 -0
- package/packages/core/lib/search.cjs +211 -0
- package/packages/core/lib/symbol-graph.cjs +402 -0
- package/packages/core/lib/symbol-parser-js.cjs +542 -0
- package/packages/core/lib/symbol-parser-misc.cjs +394 -0
- package/packages/core/lib/symbol-parser-py.cjs +215 -0
- package/packages/core/lib/symbol-parser-treesitter.cjs +658 -0
- package/packages/core/lib/symbol-parser-tsc.cjs +332 -0
- package/packages/core/monorepo.js +310 -0
- package/packages/core/parser.js +2234 -0
- package/packages/core/scanner.js +623 -0
- package/plugin-api/LICENSE +21 -0
- package/plugin-api/README.md +114 -0
- package/plugin-api/docs/01-getting-started.md +197 -0
- package/plugin-api/docs/02-concepts.md +269 -0
- package/plugin-api/docs/api-reference.md +463 -0
- package/plugin-api/docs/troubleshooting.md +332 -0
- package/plugin-api/docs/types/exporter.md +377 -0
- package/plugin-api/docs/types/theme.md +312 -0
- package/plugin-api/examples/hello-world-plugin/README.md +70 -0
- package/plugin-api/examples/hello-world-plugin/main.js +36 -0
- package/plugin-api/examples/hello-world-plugin/manifest.json +12 -0
- package/plugin-api/examples/mermaid-exporter/README.md +125 -0
- package/plugin-api/examples/mermaid-exporter/main.js +58 -0
- package/plugin-api/examples/mermaid-exporter/manifest.json +12 -0
- package/plugin-api/examples/rust-parser/README.md +71 -0
- package/plugin-api/examples/rust-parser/main.js +123 -0
- package/plugin-api/examples/rust-parser/manifest.json +12 -0
- package/plugin-api/examples/sunset-theme/README.md +95 -0
- package/plugin-api/examples/sunset-theme/manifest.json +12 -0
- package/plugin-api/examples/sunset-theme/theme.css +31 -0
- package/plugin-api/package.json +20 -0
- package/plugin-api/types.d.ts +395 -0
- package/public/app.js +6837 -0
- package/public/backend.js +285 -0
- package/public/index.html +647 -0
- package/public/plugin-host.js +321 -0
- package/public/style.css +4359 -0
- package/public/vendor/three.module.js +53044 -0
- package/scripts/competitor-watch.mjs +144 -0
- package/scripts/copy-vendor.js +21 -0
- package/scripts/download-bundled-node.cjs +53 -0
- package/scripts/fuses-after-pack.cjs +34 -0
- package/scripts/license-check.js +119 -0
- package/scripts/perf-test.js +200 -0
- package/server.js +132 -0
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
# API reference
|
|
2
|
+
|
|
3
|
+
Every method available to plugins, with signatures, parameters, return
|
|
4
|
+
values, and a small example.
|
|
5
|
+
|
|
6
|
+
For the raw TypeScript types, see [`../types.d.ts`](../types.d.ts) —
|
|
7
|
+
that file is the single source of truth. This page is the human-readable
|
|
8
|
+
companion.
|
|
9
|
+
|
|
10
|
+
## Quick index
|
|
11
|
+
|
|
12
|
+
| Namespace | Purpose |
|
|
13
|
+
|---|---|
|
|
14
|
+
| [`ctx`](#the-context-object) | The root object passed to `activate(ctx)` |
|
|
15
|
+
| [`ctx.graph`](#graph-api) | Read graph state |
|
|
16
|
+
| [`ctx.ui`](#ui-api) | Register panels, menu items, commands |
|
|
17
|
+
| [`ctx.exporters`](#exporter-registry) | Register export formats |
|
|
18
|
+
| [`ctx.parsers`](#parser-registry) | Register language parsers |
|
|
19
|
+
| [`ctx.layouts`](#layout-registry) | Register layout algorithms |
|
|
20
|
+
| [`ctx.events`](#event-bus) | Subscribe to app events |
|
|
21
|
+
| [`ctx.storage`](#plugin-storage) | Persistent per-plugin storage |
|
|
22
|
+
| [`ctx.toast`](#cxtoastmsg) | Show a toast notification |
|
|
23
|
+
| [`ctx.log`](#cxlog-args) | Log to the plugin console |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## The context object
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
ctx.manifest: PluginManifest // your plugin's own manifest
|
|
31
|
+
ctx.appVersion: string // host filegraph3d version (e.g. "0.11.0")
|
|
32
|
+
ctx.graph: GraphAPI // read graph state
|
|
33
|
+
ctx.ui: UIAPI // register UI items
|
|
34
|
+
ctx.exporters: ExporterRegistry
|
|
35
|
+
ctx.parsers: ParserRegistry
|
|
36
|
+
ctx.layouts: LayoutRegistry
|
|
37
|
+
ctx.events: EventBus // subscribe to events
|
|
38
|
+
ctx.storage: PluginStorage // persistent key-value store
|
|
39
|
+
ctx.toast(msg: string): void // show a toast
|
|
40
|
+
ctx.log(...args: unknown[]): void // log to console (prefixed)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Graph API
|
|
46
|
+
|
|
47
|
+
Read-only access to the current graph. All properties update live as
|
|
48
|
+
the graph changes — read them when you need them, don't cache.
|
|
49
|
+
|
|
50
|
+
### `graph.root: string`
|
|
51
|
+
|
|
52
|
+
The absolute path of the currently-opened folder.
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
ctx.log('User opened:', ctx.graph.root)
|
|
56
|
+
// → /Users/you/projects/filegraph3d
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### `graph.nodes: ReadonlyArray<GraphNode>`
|
|
60
|
+
|
|
61
|
+
Every file in the graph. Each node has:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
interface GraphNode {
|
|
65
|
+
id: string // file path relative to root, e.g. "src/index.js"
|
|
66
|
+
ext: string // extension without dot, e.g. "js"
|
|
67
|
+
size: number // bytes
|
|
68
|
+
loc: number // lines of code
|
|
69
|
+
hex: string // display color, e.g. "#F7DF1E"
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```js
|
|
74
|
+
const jsFiles = ctx.graph.nodes.filter((n) => n.ext === 'js')
|
|
75
|
+
ctx.log(`${jsFiles.length} JS files`)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### `graph.edges: ReadonlyArray<GraphEdge>`
|
|
79
|
+
|
|
80
|
+
Every import edge. Each edge:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
interface GraphEdge {
|
|
84
|
+
s: string // source node id (the file doing the importing)
|
|
85
|
+
t: string // target node id (the file being imported)
|
|
86
|
+
k: string // edge kind: 'import' | 'require' | 'dynamic' | 'css' | 'other'
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### `graph.selectedId: string | null`
|
|
91
|
+
|
|
92
|
+
The currently-selected node id, or `null` if none.
|
|
93
|
+
|
|
94
|
+
### `graph.activeSet: ReadonlySet<string> | null`
|
|
95
|
+
|
|
96
|
+
The currently-active file set (the user's curated "what's really in
|
|
97
|
+
use" list). `null` if the active set feature is turned off.
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
const active = ctx.graph.activeSet
|
|
101
|
+
if (active) {
|
|
102
|
+
ctx.log(`${active.size} active files`)
|
|
103
|
+
} else {
|
|
104
|
+
ctx.log('Active set is off')
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### `graph.getNode(id: string): GraphNode | null`
|
|
109
|
+
|
|
110
|
+
Look up a single node by id. Returns `null` if not found.
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
const node = ctx.graph.getNode('src/index.js')
|
|
114
|
+
if (node) ctx.log(`${node.loc} lines`)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### `graph.outgoing(id: string): GraphEdge[]`
|
|
118
|
+
|
|
119
|
+
Every edge starting from this node (i.e., files this file imports).
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
const deps = ctx.graph.outgoing('src/index.js')
|
|
123
|
+
ctx.log(`Imports ${deps.length} files`)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### `graph.incoming(id: string): GraphEdge[]`
|
|
127
|
+
|
|
128
|
+
Every edge ending at this node (i.e., files that import this file).
|
|
129
|
+
|
|
130
|
+
```js
|
|
131
|
+
const usages = ctx.graph.incoming('src/utils.js')
|
|
132
|
+
ctx.log(`Used by ${usages.length} files`)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### `graph.readFile(id: string): Promise<string>`
|
|
136
|
+
|
|
137
|
+
Read the contents of a file. **Requires `read-files` permission.**
|
|
138
|
+
|
|
139
|
+
```js
|
|
140
|
+
// In manifest.json:
|
|
141
|
+
// "permissions": ["read-files"]
|
|
142
|
+
|
|
143
|
+
const content = await ctx.graph.readFile('src/index.js')
|
|
144
|
+
const lineCount = content.split('\n').length
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Reading files is async because filegraph3d may need to load from disk
|
|
148
|
+
or wait for an in-flight read. Performance: ~5ms per file on average.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## UI API
|
|
153
|
+
|
|
154
|
+
### `ui.registerPanel(opts: PanelOptions): PanelHandle`
|
|
155
|
+
|
|
156
|
+
Add a side panel to the right rail. **Requires `ui-panel` permission.**
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
interface PanelOptions {
|
|
160
|
+
id: string // unique within your plugin
|
|
161
|
+
title: string // shown in the panel header
|
|
162
|
+
position?: 'right' | 'left' | 'bottom' // default: 'right'
|
|
163
|
+
render: (container: HTMLElement) => void
|
|
164
|
+
defaultVisible?: boolean // default: true
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
interface PanelHandle {
|
|
168
|
+
refresh(): void // force re-render
|
|
169
|
+
show(): void // make visible
|
|
170
|
+
hide(): void // hide without removing
|
|
171
|
+
dispose(): void // remove entirely
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```js
|
|
176
|
+
const panel = ctx.ui.registerPanel({
|
|
177
|
+
id: 'stats',
|
|
178
|
+
title: 'My Stats',
|
|
179
|
+
render(container) {
|
|
180
|
+
const node = ctx.graph.getNode(ctx.graph.selectedId)
|
|
181
|
+
container.innerHTML = node
|
|
182
|
+
? `<p>Selected: ${node.id}</p>`
|
|
183
|
+
: `<p>No selection</p>`
|
|
184
|
+
}
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
// Re-render when selection changes
|
|
188
|
+
ctx.events.on('selection:changed', () => panel.refresh())
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### `ui.registerContextMenuItem(opts): MenuItemHandle`
|
|
192
|
+
|
|
193
|
+
Add a right-click item to graph nodes. **Requires `context-menu` permission.**
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
interface ContextMenuOptions {
|
|
197
|
+
label: string // display text
|
|
198
|
+
icon?: string // single character/emoji
|
|
199
|
+
enabled?: (nodeId: string) => boolean // dynamic enable/disable
|
|
200
|
+
action: (nodeId: string) => void | Promise<void>
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
```js
|
|
205
|
+
ctx.ui.registerContextMenuItem({
|
|
206
|
+
label: 'Open in browser',
|
|
207
|
+
icon: '🌐',
|
|
208
|
+
enabled: (nodeId) => nodeId.endsWith('.html'),
|
|
209
|
+
action: (nodeId) => {
|
|
210
|
+
ctx.toast(`Would open ${nodeId}`)
|
|
211
|
+
}
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### `ui.registerCommand(opts): CommandHandle`
|
|
216
|
+
|
|
217
|
+
Register a named command. Reserved for future command-palette support.
|
|
218
|
+
|
|
219
|
+
```js
|
|
220
|
+
ctx.ui.registerCommand({
|
|
221
|
+
id: 'my-plugin.do-thing',
|
|
222
|
+
name: 'Do The Thing',
|
|
223
|
+
shortcut: 'Cmd+Shift+T', // suggestion only — not bound yet
|
|
224
|
+
action: () => ctx.toast('Did the thing!')
|
|
225
|
+
})
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Exporter registry
|
|
231
|
+
|
|
232
|
+
### `exporters.register(opts: ExporterOptions): ExporterHandle`
|
|
233
|
+
|
|
234
|
+
Add a new export format. **Requires `export` permission.**
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
interface ExporterOptions {
|
|
238
|
+
name: string // "Mermaid Diagram"
|
|
239
|
+
extension: string // "mmd" (no dot)
|
|
240
|
+
mimeType: string // "text/plain"
|
|
241
|
+
generate: (graph: GraphAPI) => string | Promise<string>
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Full guide and worked examples: [exporter.md](./types/exporter.md).
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Parser registry
|
|
250
|
+
|
|
251
|
+
### `parsers.register(opts: ParserOptions): ParserHandle`
|
|
252
|
+
|
|
253
|
+
Add support for a new file extension. **Requires `parse` permission.**
|
|
254
|
+
|
|
255
|
+
```ts
|
|
256
|
+
interface ParserOptions {
|
|
257
|
+
name: string // "Rust"
|
|
258
|
+
extensions: string[] // ["rs"] (no dot)
|
|
259
|
+
parse: (filePath: string, content: string) => ParseResult
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
interface ParseResult {
|
|
263
|
+
imports: ParseImport[]
|
|
264
|
+
loc?: number // optional override; defaults to newline count
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
interface ParseImport {
|
|
268
|
+
path: string // "./foo", "react", etc.
|
|
269
|
+
kind: 'import' | 'require' | 'dynamic' | 'css' | 'asset' | 'other'
|
|
270
|
+
line?: number // for debugging
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Parsers are called synchronously per file during scan. Keep them fast —
|
|
275
|
+
ideally under 1ms per file. Heavy parsing should use a worker (advanced
|
|
276
|
+
topic, not covered here).
|
|
277
|
+
|
|
278
|
+
```js
|
|
279
|
+
ctx.parsers.register({
|
|
280
|
+
name: 'Rust',
|
|
281
|
+
extensions: ['rs'],
|
|
282
|
+
parse(filePath, content) {
|
|
283
|
+
const imports = []
|
|
284
|
+
const useRegex = /^\s*use\s+([a-zA-Z_:][\w:]*)/gm
|
|
285
|
+
let m
|
|
286
|
+
while ((m = useRegex.exec(content)) !== null) {
|
|
287
|
+
imports.push({ path: m[1], kind: 'import' })
|
|
288
|
+
}
|
|
289
|
+
return { imports }
|
|
290
|
+
}
|
|
291
|
+
})
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
See the [rust-parser example](../examples/rust-parser/) for a fuller
|
|
295
|
+
implementation.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Layout registry
|
|
300
|
+
|
|
301
|
+
### `layouts.register(opts: LayoutOptions): LayoutHandle`
|
|
302
|
+
|
|
303
|
+
Add a graph layout algorithm. The user picks layouts from a future
|
|
304
|
+
settings panel (not yet wired up — registered layouts are stored but
|
|
305
|
+
not user-selectable yet).
|
|
306
|
+
|
|
307
|
+
```ts
|
|
308
|
+
interface LayoutOptions {
|
|
309
|
+
name: string // "Hierarchical"
|
|
310
|
+
id: string // unique
|
|
311
|
+
compute: (nodes, edges) =>
|
|
312
|
+
Map<string, { x: number; y: number; z: number }> |
|
|
313
|
+
Promise<Map<string, { x: number; y: number; z: number }>>
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
```js
|
|
318
|
+
ctx.layouts.register({
|
|
319
|
+
name: 'Random',
|
|
320
|
+
id: 'random',
|
|
321
|
+
compute(nodes, edges) {
|
|
322
|
+
const positions = new Map()
|
|
323
|
+
for (const node of nodes) {
|
|
324
|
+
positions.set(node.id, {
|
|
325
|
+
x: (Math.random() - 0.5) * 100,
|
|
326
|
+
y: (Math.random() - 0.5) * 100,
|
|
327
|
+
z: (Math.random() - 0.5) * 100,
|
|
328
|
+
})
|
|
329
|
+
}
|
|
330
|
+
return positions
|
|
331
|
+
}
|
|
332
|
+
})
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Event bus
|
|
338
|
+
|
|
339
|
+
### `events.on(name: EventName, handler: (payload) => void): () => void`
|
|
340
|
+
|
|
341
|
+
Subscribe to an app event. Returns an unsubscribe function — call it
|
|
342
|
+
to stop receiving the event.
|
|
343
|
+
|
|
344
|
+
| Event | Fires when | Payload |
|
|
345
|
+
|---|---|---|
|
|
346
|
+
| `snapshot:applied` | New graph data loaded | `{ root: string }` |
|
|
347
|
+
| `selection:changed` | User selects a node | `string \| null` |
|
|
348
|
+
| `filter:changed` | Search filter changes | (no payload) |
|
|
349
|
+
| `focus:changed` | Hover focus changes | `string \| null` |
|
|
350
|
+
| `graph:cleared` | Folder closed | (no payload) |
|
|
351
|
+
| `activeset:changed` | Active set / pipelines updated | (no payload) |
|
|
352
|
+
|
|
353
|
+
```js
|
|
354
|
+
const off = ctx.events.on('selection:changed', (id) => {
|
|
355
|
+
if (id) ctx.log('selected', id)
|
|
356
|
+
})
|
|
357
|
+
|
|
358
|
+
// Later:
|
|
359
|
+
off() // unsubscribe
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### `events.off(name, handler): void`
|
|
363
|
+
|
|
364
|
+
Alternative way to unsubscribe (the unsubscribe function returned by
|
|
365
|
+
`on` is usually cleaner).
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## Plugin storage
|
|
370
|
+
|
|
371
|
+
Per-plugin localStorage, namespaced under your plugin id.
|
|
372
|
+
|
|
373
|
+
### `storage.set<T>(key: string, value: T): void`
|
|
374
|
+
|
|
375
|
+
Store a value. Must be JSON-serializable.
|
|
376
|
+
|
|
377
|
+
```js
|
|
378
|
+
ctx.storage.set('lastUsed', Date.now())
|
|
379
|
+
ctx.storage.set('preferences', { showHidden: true, depth: 5 })
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### `storage.get<T>(key: string): T | null`
|
|
383
|
+
|
|
384
|
+
Retrieve a value. Returns `null` if the key doesn't exist.
|
|
385
|
+
|
|
386
|
+
```js
|
|
387
|
+
const prefs = ctx.storage.get('preferences')
|
|
388
|
+
if (prefs?.showHidden) { /* ... */ }
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### `storage.delete(key: string): void`
|
|
392
|
+
|
|
393
|
+
Remove a single key.
|
|
394
|
+
|
|
395
|
+
### `storage.clear(): void`
|
|
396
|
+
|
|
397
|
+
Remove all keys for this plugin.
|
|
398
|
+
|
|
399
|
+
### `storage.keys(): string[]`
|
|
400
|
+
|
|
401
|
+
List all keys this plugin has stored.
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## `ctx.toast(msg)`
|
|
406
|
+
|
|
407
|
+
Show a transient toast notification at the bottom of the screen.
|
|
408
|
+
Visible for a few seconds, then fades.
|
|
409
|
+
|
|
410
|
+
```js
|
|
411
|
+
ctx.toast('Export complete')
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Toast text is automatically prefixed with your plugin name, so the
|
|
415
|
+
user knows where it came from:
|
|
416
|
+
|
|
417
|
+
```
|
|
418
|
+
[my-plugin] Export complete
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
## `ctx.log(...args)`
|
|
422
|
+
|
|
423
|
+
Log to the browser console. Output is prefixed with `[plugin:<id>]`
|
|
424
|
+
so you can filter for it.
|
|
425
|
+
|
|
426
|
+
```js
|
|
427
|
+
ctx.log('Loaded', ctx.graph.nodes.length, 'nodes')
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Open DevTools (View → Toggle Developer Tools) to see the output.
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## Types — full TypeScript surface
|
|
435
|
+
|
|
436
|
+
The complete TypeScript types are in [`../types.d.ts`](../types.d.ts).
|
|
437
|
+
If you're using TypeScript or VS Code, install the package:
|
|
438
|
+
|
|
439
|
+
```sh
|
|
440
|
+
npm install --save-dev @filegraph3d/plugin-api
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
```ts
|
|
444
|
+
import type {
|
|
445
|
+
Plugin,
|
|
446
|
+
PluginContext,
|
|
447
|
+
GraphAPI,
|
|
448
|
+
// ... all the rest
|
|
449
|
+
} from '@filegraph3d/plugin-api'
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
You get IntelliSense for every method, parameter, and return value.
|
|
453
|
+
|
|
454
|
+
## Stability
|
|
455
|
+
|
|
456
|
+
Current version: **0.1.0** (pre-release).
|
|
457
|
+
|
|
458
|
+
Expect breaking changes until 1.0. After 1.0:
|
|
459
|
+
- **Minor versions** (1.x) are additive — old plugins keep working.
|
|
460
|
+
- **Major versions** (2.0, 3.0) may break — old plugins are loaded
|
|
461
|
+
with a deprecation warning so users can update.
|
|
462
|
+
|
|
463
|
+
Watch `CHANGELOG.md` (top-level filegraph3d repo) for changes.
|