@linkdesk/plugin-sdk 0.1.14 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -35
- package/package.json +1 -1
- package/schemas/icon-theme.schema.json +97 -97
- package/schemas/plugin.schema.json +169 -169
- package/schemas/theme.schema.json +109 -109
package/README.md
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
# @linkdesk/plugin-sdk
|
|
2
2
|
|
|
3
|
-
LinkDesk
|
|
3
|
+
The LinkDesk plugin author SDK — the counterpart to `@types/vscode`: install one package and get **`window.linkdesk.*` type hints + one-command builds of `.linkdesk-plugin` + plugin.json validation**. Zero dependency on the shell source.
|
|
4
4
|
|
|
5
|
-
>
|
|
6
|
-
>
|
|
5
|
+
> The source of truth for types = `@linkdesk/contracts` (this package re-exports it and does not copy the generated artifact — contract drift → your tsc turns red immediately).
|
|
6
|
+
> Plugin authors always write code against `window.linkdesk.*` (injected by the preload); **`import @src/core` is forbidden**.
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## Installation
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
npm install -D @linkdesk/plugin-sdk
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
## API
|
|
14
|
+
## API cheat sheet
|
|
15
15
|
|
|
16
16
|
<!-- BEGIN API-CHEATSHEET -->
|
|
17
17
|
|
|
18
18
|
> 自动生成,**勿手改**——由 `scripts/generate-api-cheatsheet.mjs` 从 `@linkdesk/contracts` 的 `linkdesk.d.ts` 现读产出,
|
|
19
19
|
> `npm run check` 机械盯漂。完整签名与逐方法说明见 `linkdesk.d.ts` 本体(IDE 里可直接跳转)。
|
|
20
20
|
|
|
21
|
-
**15 个域接口 → 46 个命名空间 / 243 个方法**,全部经 `window.linkdesk.<命名空间>.<方法>`
|
|
21
|
+
**15 个域接口 → 46 个命名空间 / 243 个方法**,全部经 `window.linkdesk.<命名空间>.<方法>` 调用。 (plus 1 deprecated alias/es `config`, not counted twice)
|
|
22
22
|
|
|
23
|
-
|
|
|
23
|
+
| Namespace | Methods | Method | Notes |
|
|
24
24
|
|:--|:--:|:--|:--|
|
|
25
25
|
| `commands` | 5 | `execute` `executeCommand` `registerCommand` `unregisterCommands` `getCommands` | 命令——对标 VS Code vscode.commands |
|
|
26
26
|
| `configuration` | 15 | `get` `set` `getSchema` `onChange` `getConfigurationContributions` `inspectConfiguration` `getUserSettings` `onDidChangeConfiguration` `onPluginLifecycleChange` `consumeSettingsGroup` `onRequestSettingsGroup` `consumeScrollToSetting` `onRequestScrollToSetting` `consumeOpenKeybindings` `onRequestOpenKeybindings` | 配置—新名——对标 VS Code vscode.workspace.getConfiguration |
|
|
@@ -62,91 +62,91 @@ npm install -D @linkdesk/plugin-sdk
|
|
|
62
62
|
| `window` | 11 | `minimize` `maximize` `unmaximize` `close` `setZoom` `toggleDevTools` `isMaximized` `onMaximizeChange` `setAlwaysOnTop` `isAlwaysOnTop` `onAlwaysOnTopChange` | 窗口控制——TitleBar 按钮映射,双端注入(11 方法同通道,共享模块 electron/window-name… |
|
|
63
63
|
| `shell` | 6 | `showItemInFolder` `openInTerminal` `pluginLocation` `openPluginFolder` `startDrag` `relaunch`° | 壳级命令——revealInOS / openInTerminal / startDrag / relaunch,双端… |
|
|
64
64
|
| `hotExit` ⚠️ | 3 | `save` `load` `clear` | 热退出暂存——编辑器未保存内容落盘(E5.7#53) |
|
|
65
|
-
| `getFilePath` | 0 |
|
|
65
|
+
| `getFilePath` | 0 | (top-level function)`getFilePath: (file: File) => string;` | OS 拖入文件路径获取——双端注入 |
|
|
66
66
|
| `panel` | 2 | `reveal` `revealFloating` | —— |
|
|
67
67
|
| `settings` | 3 | `list` `getActive` `setActive` | —— |
|
|
68
68
|
| `factorySlots` | 4 | `listRoles` `list` `getActive` `setActive` | —— |
|
|
69
69
|
| `app` | 1 | `getVersion` | app 命名空间——只读产品身份 |
|
|
70
70
|
| `update` | 1 | `getState` | update 命名空间——只读更新状态(供「关于」类插件读宿主版本/更新态) |
|
|
71
71
|
|
|
72
|
-
⚠️ =
|
|
73
|
-
° =
|
|
72
|
+
⚠️ = optional namespace in the contract (injected on one side only): `bridge` `hotExit` — check for existence before calling; on the other side it is undefined.
|
|
73
|
+
° = member marked `?` in the contract: injected in one side's preload only (almost always shell-side). **Your plugin runs in the pool** — check for existence before calling.
|
|
74
74
|
|
|
75
75
|
<!-- END API-CHEATSHEET -->
|
|
76
76
|
|
|
77
|
-
##
|
|
77
|
+
## Usage
|
|
78
78
|
|
|
79
|
-
### 1. tsconfig
|
|
79
|
+
### 1. tsconfig — give `window.linkdesk.` its types
|
|
80
80
|
|
|
81
81
|
```jsonc
|
|
82
82
|
{
|
|
83
83
|
"compilerOptions": {
|
|
84
|
-
"types": ["@linkdesk/plugin-sdk"], //
|
|
84
|
+
"types": ["@linkdesk/plugin-sdk"], // the global window.linkdesk declarations come in with the contracts
|
|
85
85
|
"jsx": "react-jsx"
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
Create no global.d.ts at all. In `.ts`/`.tsx`, `window.linkdesk.tabs.create({...})` gets parameter and return type checking directly.
|
|
91
91
|
|
|
92
|
-
### 2. plugin.json
|
|
92
|
+
### 2. plugin.json — declare the plugin (required `name` + `version`; comments and trailing commas allowed)
|
|
93
93
|
|
|
94
94
|
```jsonc
|
|
95
95
|
{
|
|
96
|
-
"name": "My Plugin", //
|
|
96
|
+
"name": "My Plugin", // display name
|
|
97
97
|
"version": "1.0.0",
|
|
98
|
-
"entry": "src/index.tsx", // view/card/protocol
|
|
98
|
+
"entry": "src/index.tsx", // required for view/card/protocol plugins
|
|
99
99
|
"contributes": { "i18n": { "en": "i18n/en.json" } }
|
|
100
100
|
}
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
### 3.
|
|
103
|
+
### 3. Build — produce the `.linkdesk-plugin` distributable
|
|
104
104
|
|
|
105
105
|
```bash
|
|
106
|
-
npm run build #
|
|
106
|
+
npm run build # the package ships its own bin; equivalent to linkdesk-plugin-sdk build
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
The build does all of this automatically: **validate plugin.json → Vite bundles `src/index.tsx` into `index.bundle.js` → gather manifest/icons/i18n/README into `dist/<id>.linkdesk-plugin/` → zip it into `<id>.linkdesk-plugin` at the project root**.
|
|
110
110
|
|
|
111
|
-
- `react` / `react-dom` / `react-i18next` / `i18next`
|
|
112
|
-
-
|
|
113
|
-
-
|
|
111
|
+
- `react` / `react-dom` / `react-i18next` / `i18next` are provided by the shell and are **not bundled** — every other dependency is inlined, so plugins are self-contained.
|
|
112
|
+
- Plugin id = the `pluginId` field of `plugin.json`; if it is not declared, the **project directory name** is used as a fallback (matching the shell's loading contract).
|
|
113
|
+
- To customize the entry, output directory, or extra externals:
|
|
114
114
|
```js
|
|
115
115
|
// vite.config.ts
|
|
116
116
|
import { defineLinkdeskPluginConfig } from "@linkdesk/plugin-sdk";
|
|
117
117
|
export default defineLinkdeskPluginConfig({ entry: "src/index.tsx", outDir: "dist" });
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
-
###
|
|
120
|
+
### Standalone validation
|
|
121
121
|
|
|
122
122
|
```bash
|
|
123
|
-
npm run validate #
|
|
123
|
+
npm run validate # or linkdesk-plugin-sdk validate ./plugin.json
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
###
|
|
126
|
+
### Theme/icon data file schemas (the npm channel for theme and icon authors)
|
|
127
127
|
|
|
128
|
-
`schemas/theme.schema.json` + `schemas/icon-theme.schema.json`
|
|
128
|
+
`schemas/theme.schema.json` + `schemas/icon-theme.schema.json` ship with the package (kept byte-synced with the repository's `public/schemas/`; drift is caught by `check-plugin-schema-sync`). Theme and icon authors reference `$schema` on the first line of their data JSON to get IntelliSense:
|
|
129
129
|
|
|
130
130
|
```jsonc
|
|
131
|
-
// themes/my-glass.json
|
|
131
|
+
// themes/my-glass.json (relative to the plugin root)
|
|
132
132
|
{
|
|
133
133
|
"$schema": "./node_modules/@linkdesk/plugin-sdk/schemas/theme.schema.json",
|
|
134
134
|
// …
|
|
135
135
|
}
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
-
|
|
138
|
+
Data files are **not JSONC** (strict JSON, loaded by the same engine). At build time or in CI, the validate family can catch format errors (the same schema files the repository's `check-theme-schema.mjs` uses, so the rules never drift):
|
|
139
139
|
|
|
140
140
|
```js
|
|
141
141
|
import { validateThemeJson, validateIconThemeJson } from "@linkdesk/plugin-sdk";
|
|
142
142
|
|
|
143
143
|
validateThemeJson("themes/my-glass.json"); // theme.schema.json
|
|
144
|
-
validateIconThemeJson("icons/my-icons.json"); // icon-theme.schema.json
|
|
144
|
+
validateIconThemeJson("icons/my-icons.json"); // icon-theme.schema.json (dual-form contract for the match table)
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
-
### index.bundle.js
|
|
147
|
+
### index.bundle.js conventions
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
The bundle `export default`s a React component — the shell renders it with `{ isActive }`:
|
|
150
150
|
|
|
151
151
|
```tsx
|
|
152
152
|
export default function MyView({ isActive }: { isActive: boolean }) {
|
|
@@ -154,7 +154,7 @@ export default function MyView({ isActive }: { isActive: boolean }) {
|
|
|
154
154
|
}
|
|
155
155
|
```
|
|
156
156
|
|
|
157
|
-
##
|
|
157
|
+
## Limitations
|
|
158
158
|
|
|
159
|
-
- **dev
|
|
160
|
-
- plugin.json
|
|
159
|
+
- **dev preview** (source glob loading inside the shell) parses plugin.json as strict JSON; this SDK's validate tolerating comments/trailing commas is a publish-time capability — if a plugin needs to run in dev preview, keep plugin.json free of comments.
|
|
160
|
+
- Dropping a commented plugin.json straight into the shell's `plugins/` dev directory breaks preview loading (jsonc support on the shell side is still to come).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linkdesk/plugin-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"description": "@linkdesk/plugin-sdk——LinkDesk 插件作者 SDK(对标 @types/vscode):window.linkdesk.* 类型 + 一键 build(.linkdesk-plugin) + dev 宿主 + plugin.json 验证 + eslint 门禁(E6#54d)。作者 npm i 后零壳源码依赖。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://linkdesk.local/schemas/icon-theme.schema.json",
|
|
4
|
-
"title": "LinkDesk
|
|
5
|
-
"description": "contributes.iconThemes
|
|
6
|
-
"type": "object",
|
|
7
|
-
"additionalProperties": false,
|
|
8
|
-
"properties": {
|
|
9
|
-
"$schema": {
|
|
10
|
-
"type": "string",
|
|
11
|
-
"description": "
|
|
12
|
-
},
|
|
13
|
-
"files": {
|
|
14
|
-
"$ref": "#/$defs/mappingTable",
|
|
15
|
-
"description": "
|
|
16
|
-
},
|
|
17
|
-
"extensions": {
|
|
18
|
-
"$ref": "#/$defs/mappingTable",
|
|
19
|
-
"description": "
|
|
20
|
-
},
|
|
21
|
-
"folders": {
|
|
22
|
-
"$ref": "#/$defs/mappingTable",
|
|
23
|
-
"description": "
|
|
24
|
-
},
|
|
25
|
-
"foldersExpanded": {
|
|
26
|
-
"$ref": "#/$defs/mappingTable",
|
|
27
|
-
"description": "
|
|
28
|
-
},
|
|
29
|
-
"file": {
|
|
30
|
-
"$ref": "#/$defs/iconMapping",
|
|
31
|
-
"description": "
|
|
32
|
-
},
|
|
33
|
-
"folder": {
|
|
34
|
-
"$ref": "#/$defs/iconMapping",
|
|
35
|
-
"description": "
|
|
36
|
-
},
|
|
37
|
-
"folderExpanded": {
|
|
38
|
-
"$ref": "#/$defs/iconMapping",
|
|
39
|
-
"description": "
|
|
40
|
-
},
|
|
41
|
-
"rootFolder": {
|
|
42
|
-
"$ref": "#/$defs/iconMapping",
|
|
43
|
-
"description": "
|
|
44
|
-
},
|
|
45
|
-
"rootFolderExpanded": {
|
|
46
|
-
"$ref": "#/$defs/iconMapping",
|
|
47
|
-
"description": "
|
|
48
|
-
},
|
|
49
|
-
"font": {
|
|
50
|
-
"$ref": "#/$defs/fontSpec",
|
|
51
|
-
"description": "
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
"$defs": {
|
|
55
|
-
"mappingTable": {
|
|
56
|
-
"type": "object",
|
|
57
|
-
"description": "
|
|
58
|
-
"additionalProperties": { "$ref": "#/$defs/iconMapping" }
|
|
59
|
-
},
|
|
60
|
-
"iconMapping": {
|
|
61
|
-
"title": "
|
|
62
|
-
"type": "object",
|
|
63
|
-
"anyOf": [
|
|
64
|
-
{
|
|
65
|
-
"title": "
|
|
66
|
-
"description": "CSS
|
|
67
|
-
"required": ["class"],
|
|
68
|
-
"properties": {
|
|
69
|
-
"class": { "type": "string", "description": "CSS
|
|
70
|
-
"color": { "type": "string", "description": "
|
|
71
|
-
},
|
|
72
|
-
"additionalProperties": false
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
"title": "
|
|
76
|
-
"description": "
|
|
77
|
-
"required": ["imagePath"],
|
|
78
|
-
"properties": {
|
|
79
|
-
"imagePath": { "type": "string", "description": "
|
|
80
|
-
},
|
|
81
|
-
"additionalProperties": false
|
|
82
|
-
}
|
|
83
|
-
]
|
|
84
|
-
},
|
|
85
|
-
"fontSpec": {
|
|
86
|
-
"type": "object",
|
|
87
|
-
"description": "
|
|
88
|
-
"required": ["path", "family"],
|
|
89
|
-
"additionalProperties": false,
|
|
90
|
-
"properties": {
|
|
91
|
-
"path": { "type": "string", "description": "
|
|
92
|
-
"family": { "type": "string", "description": "
|
|
93
|
-
"glyphs": { "type": "string", "description": "glyph
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://linkdesk.local/schemas/icon-theme.schema.json",
|
|
4
|
+
"title": "LinkDesk icon theme mappings data contract",
|
|
5
|
+
"description": "Contract for the mappings JSON file referenced by contributes.iconThemes — mirrors the engine's normalizeIconThemeMappings (src/pluginLoader/contributions/contributions.ts). Four mapping tables (files/extensions/folders/foldersExpanded) plus five top-level default icon keys (file/folder/folderExpanded/rootFolder/rootFolderExpanded); each entry takes one of two forms: a font glyph (class + optional color) or an image asset (imagePath, relative to the plugin root). An optional top-level font section declares a custom icon font. Validation: @linkdesk/plugin-sdk validateIconThemeJson on the npm side, check-theme-schema.mjs on the repo side (it scans every contributes.iconThemes entry).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"$schema": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "Editor IntelliSense reference (optional) — npm authors reference node_modules/@linkdesk/plugin-sdk/schemas/icon-theme.schema.json"
|
|
12
|
+
},
|
|
13
|
+
"files": {
|
|
14
|
+
"$ref": "#/$defs/mappingTable",
|
|
15
|
+
"description": "File name → icon entry (highest match priority; on a miss, extensions is consulted)"
|
|
16
|
+
},
|
|
17
|
+
"extensions": {
|
|
18
|
+
"$ref": "#/$defs/mappingTable",
|
|
19
|
+
"description": "Extension (including the dot, e.g. \".ts\"/\".jsx\") → icon entry"
|
|
20
|
+
},
|
|
21
|
+
"folders": {
|
|
22
|
+
"$ref": "#/$defs/mappingTable",
|
|
23
|
+
"description": "Folder name → icon entry (collapsed)"
|
|
24
|
+
},
|
|
25
|
+
"foldersExpanded": {
|
|
26
|
+
"$ref": "#/$defs/mappingTable",
|
|
27
|
+
"description": "Folder name → icon entry (expanded; defaults to reusing folders)"
|
|
28
|
+
},
|
|
29
|
+
"file": {
|
|
30
|
+
"$ref": "#/$defs/iconMapping",
|
|
31
|
+
"description": "Default file icon — used when files/extensions miss (default: the shell's fallback icon)"
|
|
32
|
+
},
|
|
33
|
+
"folder": {
|
|
34
|
+
"$ref": "#/$defs/iconMapping",
|
|
35
|
+
"description": "Default folder icon — used when folders misses (default: the shell's fallback)"
|
|
36
|
+
},
|
|
37
|
+
"folderExpanded": {
|
|
38
|
+
"$ref": "#/$defs/iconMapping",
|
|
39
|
+
"description": "Default expanded folder icon — used when foldersExpanded misses (default: the shell's fallback)"
|
|
40
|
+
},
|
|
41
|
+
"rootFolder": {
|
|
42
|
+
"$ref": "#/$defs/iconMapping",
|
|
43
|
+
"description": "Root folder icon (default: the shell's fallback)"
|
|
44
|
+
},
|
|
45
|
+
"rootFolderExpanded": {
|
|
46
|
+
"$ref": "#/$defs/iconMapping",
|
|
47
|
+
"description": "Expanded root folder icon (default: the shell's fallback)"
|
|
48
|
+
},
|
|
49
|
+
"font": {
|
|
50
|
+
"$ref": "#/$defs/fontSpec",
|
|
51
|
+
"description": "Custom icon font (optional) — once declared, the shell generates @font-face and the author supplies the glyph classes"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"$defs": {
|
|
55
|
+
"mappingTable": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"description": "Mapping table — name (file name / extension / folder name) → icon entry",
|
|
58
|
+
"additionalProperties": { "$ref": "#/$defs/iconMapping" }
|
|
59
|
+
},
|
|
60
|
+
"iconMapping": {
|
|
61
|
+
"title": "Icon entry — pick one of two forms",
|
|
62
|
+
"type": "object",
|
|
63
|
+
"anyOf": [
|
|
64
|
+
{
|
|
65
|
+
"title": "Font glyph form",
|
|
66
|
+
"description": "CSS class name — codicon as the fallback, or a custom icon font (when class is omitted, the icon font family's own class is used)",
|
|
67
|
+
"required": ["class"],
|
|
68
|
+
"properties": {
|
|
69
|
+
"class": { "type": "string", "description": "CSS class name (e.g. \"codicon codicon-typescript\" or \"myfont myfont-rust\")" },
|
|
70
|
+
"color": { "type": "string", "description": "Optional per-icon color (for colorful seti-style fonts; omit for plain monochrome fonts)" }
|
|
71
|
+
},
|
|
72
|
+
"additionalProperties": false
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"title": "Image asset form",
|
|
76
|
+
"description": "Image asset — any multicolor, skeuomorphic, or textured artwork",
|
|
77
|
+
"required": ["imagePath"],
|
|
78
|
+
"properties": {
|
|
79
|
+
"imagePath": { "type": "string", "description": "Path to the image asset relative to the plugin root (e.g. \"icons/js.svg\") — at render time the shell resolves it to an absolute linkdesk:// URL via getPluginAssetPath; absolute /assets/... paths are forbidden" }
|
|
80
|
+
},
|
|
81
|
+
"additionalProperties": false
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
"fontSpec": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"description": "Custom icon font metadata — path is relative to the plugin root or an absolute URL; the shell generates @font-face and the author writes the glyph class CSS",
|
|
88
|
+
"required": ["path", "family"],
|
|
89
|
+
"additionalProperties": false,
|
|
90
|
+
"properties": {
|
|
91
|
+
"path": { "type": "string", "description": "Font file path relative to the plugin root (or an absolute linkdesk:// / http(s):// / data: URL)" },
|
|
92
|
+
"family": { "type": "string", "description": "The family name the author writes in font-family in the glyph CSS" },
|
|
93
|
+
"glyphs": { "type": "string", "description": "Path to the glyph class CSS file relative to the plugin root (optional; default: @font-face only, no custom glyph classes)" }
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|