intools-cli 1.0.0 → 1.0.2

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 CHANGED
@@ -10,6 +10,7 @@ InTools 插件开发的命令行工具,帮助你快速创建、调试、构建
10
10
  - [插件开发指南](#插件开发指南)
11
11
  - [项目结构](#项目结构)
12
12
  - [manifest.json 配置](#manifestjson-配置)
13
+ - [动态功能入口](#动态功能入口)
13
14
  - [开发模式](#开发模式)
14
15
  - [使用第三方库](#使用第三方库)
15
16
  - [插件 API](#插件-api)
@@ -148,6 +149,8 @@ my-plugin/
148
149
  │ ├── index.html
149
150
  │ ├── main.tsx
150
151
  │ ├── App.tsx
152
+ │ ├── hooks/
153
+ │ │ └── useIntools.ts
151
154
  │ └── styles.css
152
155
  ├── dist/ # 后端构建输出
153
156
  │ └── main.js
@@ -175,6 +178,7 @@ my-plugin/
175
178
 
176
179
  ```json
177
180
  {
181
+ "id": "my-plugin",
178
182
  "name": "my-plugin",
179
183
  "version": "1.0.0",
180
184
  "displayName": "我的插件",
@@ -202,6 +206,7 @@ my-plugin/
202
206
  | `version` | string | ✅ | 语义化版本 (x.y.z) |
203
207
  | `displayName` | string | ✅ | 用户看到的名称 |
204
208
  | `description` | string | ✅ | 功能描述 |
209
+ | `id` | string | ✅ | 插件唯一 ID(推荐,优先于 name) |
205
210
  | `main` | string | ✅ | 后端入口文件路径 |
206
211
  | `ui` | string | ❌ | UI 文件路径(有界面时必填) |
207
212
  | `icon` | string/object | ❌ | 插件图标 |
@@ -242,6 +247,8 @@ my-plugin/
242
247
  | `code` | string | ✅ | 功能代码,传递给插件 |
243
248
  | `explain` | string | ✅ | 功能说明,显示给用户 |
244
249
  | `cmds` | array | ✅ | 触发命令列表 |
250
+ | `mode` | string | ❌ | `ui` / `silent` / `detached` |
251
+ | `route` | string | ❌ | UI 路由(用于子窗口或页内路由) |
245
252
 
246
253
  #### 触发命令类型 (cmds)
247
254
 
@@ -272,6 +279,26 @@ my-plugin/
272
279
 
273
280
  ---
274
281
 
282
+ ### 动态功能入口
283
+
284
+ 后端可以通过 `context.api.features` 动态添加/移除功能入口:
285
+
286
+ ```ts
287
+ export function onLoad(context?: any) {
288
+ const features = context?.api?.features
289
+ if (!features) return
290
+
291
+ features.setFeature({
292
+ code: 'dynamic:hello',
293
+ explain: '动态指令:hello',
294
+ mode: 'silent',
295
+ cmds: ['hello', { type: 'keyword', value: 'hi' }]
296
+ })
297
+ }
298
+ ```
299
+
300
+ ---
301
+
275
302
  ### 开发模式
276
303
 
277
304
  #### 启动开发服务器
@@ -337,6 +364,7 @@ npm run build
337
364
  ### 插件 API
338
365
 
339
366
  插件在沙箱中运行,通过 `context.api` 访问各种 API。
367
+ 完整类型请参考模板生成的 `src/types/intools.d.ts`。
340
368
 
341
369
  #### 剪贴板 API (clipboard)
342
370
 
@@ -410,10 +438,10 @@ await http.put(url, body?, headers?)
410
438
  await http.delete(url, headers?)
411
439
  ```
412
440
 
413
- #### 窗口 API (window)
441
+ #### 窗口 API (window,仅 UI)
414
442
 
415
443
  ```typescript
416
- const { window } = context.api
444
+ const { window } = window.intools
417
445
 
418
446
  // 设置窗口大小
419
447
  await window.setSize(600, 400)
@@ -422,6 +450,21 @@ await window.setSize(600, 400)
422
450
  await window.hide()
423
451
  ```
424
452
 
453
+ #### 输入 API (input,仅 UI)
454
+
455
+ ```typescript
456
+ const { input } = window.intools
457
+
458
+ await input.hideMainWindowPasteText('Hello')
459
+ await input.simulateKeyboardTap('A', 'cmd')
460
+ ```
461
+
462
+ #### 权限 API (permission,仅 UI)
463
+
464
+ ```typescript
465
+ const status = await window.intools?.permission?.getStatus('screen')
466
+ ```
467
+
425
468
  #### 文件系统 API (filesystem)
426
469
 
427
470
  ```typescript
@@ -768,7 +811,7 @@ A: 修改 `manifest.json` 中的 `version` 字段,重新打包后安装即可
768
811
 
769
812
  ### Q: 插件可以访问系统命令吗?
770
813
 
771
- A: 出于安全考虑,默认不开放 `shell` 权限。如需使用,请在 `manifest.json` `permissions` 中声明,并等待审核。
814
+ A: 前端通过 `window.intools.shell` 调用系统能力;后端运行在沙箱中,仅能使用 `context.api` 暴露的接口。具体能力以 `intools.d.ts` 为准。
772
815
 
773
816
  ---
774
817
 
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.copyDefaultIcon = copyDefaultIcon;
40
+ const fs = __importStar(require("fs-extra"));
41
+ const path = __importStar(require("path"));
42
+ const chalk_1 = __importDefault(require("chalk"));
43
+ function getAssetsDir() {
44
+ return path.resolve(__dirname, '../../../assets');
45
+ }
46
+ function copyDefaultIcon(targetDir) {
47
+ const defaultIconPath = path.join(getAssetsDir(), 'default-icon.png');
48
+ const targetIconPath = path.join(targetDir, 'icon.png');
49
+ if (fs.existsSync(defaultIconPath)) {
50
+ fs.copyFileSync(defaultIconPath, targetIconPath);
51
+ console.log(chalk_1.default.green(' ✓ icon.png'));
52
+ }
53
+ }
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.createBasicProject = createBasicProject;
40
+ const fs = __importStar(require("fs-extra"));
41
+ const path = __importStar(require("path"));
42
+ const chalk_1 = __importDefault(require("chalk"));
43
+ const assets_1 = require("./assets");
44
+ const basic_1 = require("./templates/basic");
45
+ async function createBasicProject(targetDir, name) {
46
+ fs.mkdirSync(targetDir, { recursive: true });
47
+ fs.mkdirSync(path.join(targetDir, 'src'));
48
+ (0, assets_1.copyDefaultIcon)(targetDir);
49
+ const manifest = (0, basic_1.buildBasicManifest)(name);
50
+ fs.writeJsonSync(path.join(targetDir, 'manifest.json'), manifest, { spaces: 2 });
51
+ console.log(chalk_1.default.green(' ✓ manifest.json'));
52
+ const pkg = (0, basic_1.buildBasicPackageJson)(name);
53
+ fs.writeJsonSync(path.join(targetDir, 'package.json'), pkg, { spaces: 2 });
54
+ console.log(chalk_1.default.green(' ✓ package.json'));
55
+ const mainTs = (0, basic_1.buildBasicMain)(name);
56
+ fs.writeFileSync(path.join(targetDir, 'src/main.ts'), mainTs);
57
+ console.log(chalk_1.default.green(' ✓ src/main.ts'));
58
+ }
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.create = create;
40
+ const fs = __importStar(require("fs-extra"));
41
+ const path = __importStar(require("path"));
42
+ const chalk_1 = __importDefault(require("chalk"));
43
+ const basic_1 = require("./basic");
44
+ const react_1 = require("./react");
45
+ async function create(name, options) {
46
+ const targetDir = path.resolve(process.cwd(), name);
47
+ if (fs.existsSync(targetDir)) {
48
+ console.log(chalk_1.default.red(`错误: 目录 ${name} 已存在`));
49
+ process.exit(1);
50
+ }
51
+ const template = options.template || 'react';
52
+ console.log(chalk_1.default.blue(`创建插件项目: ${name}`));
53
+ console.log(chalk_1.default.gray(`模板: ${template}`));
54
+ console.log();
55
+ if (template === 'react') {
56
+ await (0, react_1.createReactProject)(targetDir, name);
57
+ }
58
+ else {
59
+ await (0, basic_1.createBasicProject)(targetDir, name);
60
+ }
61
+ console.log();
62
+ console.log(chalk_1.default.green('插件创建成功!'));
63
+ console.log();
64
+ console.log('下一步:');
65
+ console.log(chalk_1.default.cyan(` cd ${name}`));
66
+ console.log(chalk_1.default.cyan(' npm install'));
67
+ console.log(chalk_1.default.cyan(' npm run dev'));
68
+ }
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.createReactProject = createReactProject;
40
+ const fs = __importStar(require("fs-extra"));
41
+ const path = __importStar(require("path"));
42
+ const chalk_1 = __importDefault(require("chalk"));
43
+ const assets_1 = require("./assets");
44
+ const react_1 = require("./templates/react");
45
+ async function createReactProject(targetDir, name) {
46
+ fs.mkdirSync(targetDir, { recursive: true });
47
+ fs.mkdirSync(path.join(targetDir, 'src'));
48
+ fs.mkdirSync(path.join(targetDir, 'src/ui'));
49
+ (0, assets_1.copyDefaultIcon)(targetDir);
50
+ createReactManifest(targetDir, name);
51
+ createReactPackageJson(targetDir, name);
52
+ createTsConfig(targetDir);
53
+ createViteConfig(targetDir);
54
+ createBackendMain(targetDir, name);
55
+ createReactUI(targetDir, name);
56
+ createIntoolsTypes(targetDir);
57
+ }
58
+ function createReactManifest(targetDir, name) {
59
+ const manifest = (0, react_1.buildReactManifest)(name);
60
+ fs.writeJsonSync(path.join(targetDir, 'manifest.json'), manifest, { spaces: 2 });
61
+ console.log(chalk_1.default.green(' ✓ manifest.json'));
62
+ }
63
+ function createReactPackageJson(targetDir, name) {
64
+ const pkg = (0, react_1.buildReactPackageJson)(name);
65
+ fs.writeJsonSync(path.join(targetDir, 'package.json'), pkg, { spaces: 2 });
66
+ console.log(chalk_1.default.green(' ✓ package.json'));
67
+ }
68
+ function createTsConfig(targetDir) {
69
+ const tsconfig = (0, react_1.buildTsConfig)();
70
+ fs.writeJsonSync(path.join(targetDir, 'tsconfig.json'), tsconfig, { spaces: 2 });
71
+ console.log(chalk_1.default.green(' ✓ tsconfig.json'));
72
+ }
73
+ function createViteConfig(targetDir) {
74
+ const viteConfig = (0, react_1.buildViteConfig)();
75
+ fs.writeFileSync(path.join(targetDir, 'vite.config.ts'), viteConfig);
76
+ console.log(chalk_1.default.green(' ✓ vite.config.ts'));
77
+ }
78
+ function createBackendMain(targetDir, name) {
79
+ const mainTs = (0, react_1.buildBackendMain)(name);
80
+ fs.writeFileSync(path.join(targetDir, 'src/main.ts'), mainTs);
81
+ console.log(chalk_1.default.green(' ✓ src/main.ts'));
82
+ }
83
+ function createReactUI(targetDir, name) {
84
+ fs.mkdirSync(path.join(targetDir, 'src/ui/hooks'), { recursive: true });
85
+ const indexHtml = (0, react_1.buildIndexHtml)(name);
86
+ fs.writeFileSync(path.join(targetDir, 'src/ui/index.html'), indexHtml);
87
+ console.log(chalk_1.default.green(' ✓ src/ui/index.html'));
88
+ const mainTsx = (0, react_1.buildMainTsx)();
89
+ fs.writeFileSync(path.join(targetDir, 'src/ui/main.tsx'), mainTsx);
90
+ console.log(chalk_1.default.green(' ✓ src/ui/main.tsx'));
91
+ const appTsx = (0, react_1.buildAppTsx)(name);
92
+ fs.writeFileSync(path.join(targetDir, 'src/ui/App.tsx'), appTsx);
93
+ console.log(chalk_1.default.green(' ✓ src/ui/App.tsx'));
94
+ const stylesCss = (0, react_1.buildStylesCss)();
95
+ fs.writeFileSync(path.join(targetDir, 'src/ui/styles.css'), stylesCss);
96
+ console.log(chalk_1.default.green(' ✓ src/ui/styles.css'));
97
+ const useIntools = (0, react_1.buildUseIntools)();
98
+ fs.writeFileSync(path.join(targetDir, 'src/ui/hooks/useIntools.ts'), useIntools);
99
+ console.log(chalk_1.default.green(' ✓ src/ui/hooks/useIntools.ts'));
100
+ }
101
+ function createIntoolsTypes(targetDir) {
102
+ fs.mkdirSync(path.join(targetDir, 'src/types'), { recursive: true });
103
+ const typesDts = (0, react_1.buildIntoolsTypes)();
104
+ fs.writeFileSync(path.join(targetDir, 'src/types/intools.d.ts'), typesDts);
105
+ console.log(chalk_1.default.green(' ✓ src/types/intools.d.ts'));
106
+ }
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildBasicManifest = buildBasicManifest;
4
+ exports.buildBasicPackageJson = buildBasicPackageJson;
5
+ exports.buildBasicMain = buildBasicMain;
6
+ function buildBasicManifest(name) {
7
+ return {
8
+ id: name,
9
+ name,
10
+ version: '1.0.0',
11
+ displayName: name,
12
+ description: '插件描述',
13
+ main: 'dist/main.js',
14
+ icon: 'icon.png',
15
+ // 独立窗口配置(可选)
16
+ // window: {
17
+ // width: 800, // 默认宽度
18
+ // height: 600, // 默认高度
19
+ // minWidth: 400, // 最小宽度
20
+ // minHeight: 300, // 最小高度
21
+ // maxWidth: 1200, // 最大宽度
22
+ // maxHeight: 900 // 最大高度
23
+ // },
24
+ features: [
25
+ {
26
+ code: 'main',
27
+ explain: '主功能',
28
+ cmds: [{ type: 'keyword', value: name }]
29
+ }
30
+ ]
31
+ };
32
+ }
33
+ function buildBasicPackageJson(name) {
34
+ return {
35
+ name,
36
+ version: '1.0.0',
37
+ scripts: {
38
+ build: 'esbuild src/main.ts --bundle --platform=node --outfile=dist/main.js',
39
+ dev: 'intools dev',
40
+ pack: 'intools pack'
41
+ },
42
+ devDependencies: {
43
+ esbuild: '^0.20.0',
44
+ typescript: '^5.0.0'
45
+ }
46
+ };
47
+ }
48
+ function buildBasicMain(name) {
49
+ return `interface PluginContext {
50
+ api: {
51
+ clipboard: {
52
+ readText: () => string
53
+ writeText: (text: string) => Promise<void>
54
+ readImage: () => ArrayBuffer | null
55
+ getFormat: () => string
56
+ }
57
+ notification: {
58
+ show: (message: string, type?: string) => void
59
+ }
60
+ }
61
+ input?: string
62
+ featureCode?: string
63
+ }
64
+
65
+ export function onLoad() {
66
+ console.log('[${name}] 插件已加载')
67
+ }
68
+
69
+ export function onUnload() {
70
+ console.log('[${name}] 插件已卸载')
71
+ }
72
+
73
+ export function onEnable() {
74
+ console.log('[${name}] 插件已启用')
75
+ }
76
+
77
+ export function onDisable() {
78
+ console.log('[${name}] 插件已禁用')
79
+ }
80
+
81
+ export async function run(context: PluginContext) {
82
+ const { clipboard, notification } = context.api
83
+ const text = context.input || clipboard.readText()
84
+
85
+ // 在这里实现你的逻辑
86
+ const result = text.toUpperCase()
87
+
88
+ await clipboard.writeText(result)
89
+ notification.show('处理完成')
90
+ }
91
+
92
+ const plugin = { onLoad, onUnload, onEnable, onDisable, run }
93
+ export default plugin
94
+ `;
95
+ }