arkts-lsp-proxy 0.1.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/README.md ADDED
@@ -0,0 +1,162 @@
1
+ # ArkTS LSP Proxy
2
+
3
+ 将 DevEco Studio 内置的 ArkTS 语言服务器(ace-server)桥接出来,让 Claude Code 等支持 LSP 的工具获得 ArkTS 语言智能。
4
+
5
+ ## 解决什么问题
6
+
7
+ AI 编码工具把 ArkTS 当成普通 TypeScript,导致:
8
+
9
+ - 使用不存在的 Web/Node.js API(如 `document.getElementById`)
10
+ - 不了解 ArkTS 声明式 UI 语法(`@Component`、`@State`、`build()` 等)
11
+ - 不遵守 ArkTS 静态类型约束(禁止 `any`、禁止动态属性访问等)
12
+
13
+ ## 工作原理
14
+
15
+ ```
16
+ Claude Code (LSP Client)
17
+ │ stdio (JSON-RPC)
18
+
19
+ arkts-lsp-proxy (Node.js 进程)
20
+
21
+ ├── 1. 发现 DevEco Studio(环境变量 / 自动搜索)
22
+ ├── 2. 推导 SDK、ace-server、工具链路径
23
+ ├── 3. 解析 build-profile.json5,构造 modules 参数
24
+ ├── 4. 运行 hvigor --sync(生成依赖映射)
25
+ └── 5. 启动 ace-server,拦截 initialize 请求注入参数
26
+
27
+
28
+ ace-server (DevEco 官方语言服务)
29
+ ├── textDocument/diagnostics
30
+ ├── textDocument/completion
31
+ ├── textDocument/hover
32
+ ├── textDocument/definition
33
+ └── @Component/@State/@Prop 语义理解
34
+ ```
35
+
36
+ 代理不实现任何语言功能,只做消息转发和参数注入。
37
+
38
+ ## 前置条件
39
+
40
+ - **DevEco Studio** 已安装(ace-server 随 IDE 分发)
41
+ - **Node.js** >= 18
42
+
43
+ ## 安装
44
+
45
+ ### Claude Code 插件(推荐)
46
+
47
+ ```bash
48
+ # 注册 marketplace
49
+ /plugin marketplace add HelloiOS2014/harmony_arkts_lsp_proxy
50
+
51
+ # 安装插件(首次使用时自动安装 arkts-lsp-proxy)
52
+ /plugin install arkts-lsp
53
+ ```
54
+
55
+ ### npm 全局安装(手动 CLI 使用)
56
+
57
+ ```bash
58
+ npm install -g arkts-lsp-proxy
59
+ ```
60
+
61
+ ## 配置
62
+
63
+ ### 环境变量
64
+
65
+ ```bash
66
+ # macOS
67
+ export DEVECO_HOME=/Applications/DevEco-Studio.app
68
+
69
+ # Windows
70
+ set DEVECO_HOME=D:\Application\Huawei\DevEco Studio
71
+
72
+ # Linux
73
+ export DEVECO_HOME=/opt/DevEco-Studio
74
+ ```
75
+
76
+ 不设置也可以,会自动搜索各平台默认安装路径。
77
+
78
+ ## 使用
79
+
80
+ 插件安装后,打开 `.ets` 文件时 LSP 自动激活。首次启动会执行 `hvigor --sync` 初始化依赖映射(可能需要几分钟),后续有缓存会很快。
81
+
82
+ 也可以手动运行:
83
+
84
+ ```bash
85
+ cd /path/to/harmonyos/project
86
+ arkts-lsp-proxy
87
+ ```
88
+
89
+ ## 平台支持
90
+
91
+ | 平台 | 默认搜索路径 |
92
+ |------|-------------|
93
+ | macOS | `/Applications/DevEco-Studio.app`、`~/Applications/DevEco-Studio.app` |
94
+ | Windows | `D:\Application\Huawei\DevEco Studio`、`C:\Program Files\Huawei\DevEco Studio` |
95
+ | Linux | `/opt/DevEco-Studio`、`~/DevEco-Studio` |
96
+
97
+ macOS 自动处理 `.app/Contents` 层,用户只需设置 `.app` 路径。
98
+
99
+ ## 错误处理
100
+
101
+ | 场景 | 行为 |
102
+ |------|------|
103
+ | DevEco Studio 未安装 | stderr 输出安装指引,exit(1) |
104
+ | 项目目录无 `build-profile.json5` | stderr 输出提示,exit(1) |
105
+ | hvigor sync 失败 | stderr 输出警告,继续启动 ace-server |
106
+ | ace-server 启动失败 | 输出错误信息,exit(1) |
107
+ | ace-server 运行时崩溃 | 代理进程同步退出 |
108
+
109
+ ## 开发
110
+
111
+ ```bash
112
+ # 安装依赖
113
+ npm install
114
+
115
+ # 构建
116
+ npm run build
117
+
118
+ # 测试
119
+ npm test
120
+
121
+ # 本地链接
122
+ npm link
123
+ ```
124
+
125
+ ## 项目结构
126
+
127
+ ```
128
+ src/
129
+ ├── env.ts DevEco Studio 环境发现
130
+ ├── project.ts HarmonyOS 项目解析 + findProjectRoot 向上搜索
131
+ ├── hvigor.ts hvigor sync 缓存检查与执行
132
+ ├── ace-server.ts ace-server 子进程生命周期管理(onExit 回调)
133
+ ├── proxy.ts LSP 消息代理,拦截 initialize 注入参数
134
+ └── index.ts 入口,串联所有模块
135
+ .claude-plugin/
136
+ └── marketplace.json marketplace 清单 + lspServers 配置
137
+ plugins/
138
+ └── arkts-lsp/
139
+ ├── .claude-plugin/
140
+ │ └── plugin.json 插件清单
141
+ ├── .lsp.json LSP 服务器配置
142
+ └── README.md 插件文档
143
+ test/
144
+ ├── env.test.ts
145
+ ├── project.test.ts
146
+ ├── hvigor.test.ts
147
+ ├── ace-server.test.ts
148
+ ├── proxy.test.ts
149
+ ├── index.test.ts
150
+ └── fixtures/
151
+ ```
152
+
153
+ ## 技术栈
154
+
155
+ - TypeScript
156
+ - `vscode-jsonrpc` — LSP 消息解析与传输
157
+ - `json5` — 解析 `build-profile.json5`
158
+ - Vitest — 测试
159
+
160
+ ## License
161
+
162
+ MIT
@@ -0,0 +1,10 @@
1
+ import { type ChildProcess } from 'child_process';
2
+ import type { DevEcoEnv } from './env';
3
+ export type ExitHandler = (code: number | null, signal: string | null) => void;
4
+ export interface AceServerHandle {
5
+ process: ChildProcess;
6
+ kill: () => void;
7
+ onExit: (handler: ExitHandler) => void;
8
+ }
9
+ export declare function startAceServer(env: DevEcoEnv): AceServerHandle;
10
+ //# sourceMappingURL=ace-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ace-server.d.ts","sourceRoot":"","sources":["../src/ace-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;AAE/E,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,YAAY,CAAC;IACtB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;CACxC;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,GAAG,eAAe,CA8C9D"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startAceServer = startAceServer;
4
+ const child_process_1 = require("child_process");
5
+ function startAceServer(env) {
6
+ process.stderr.write(`[arkts-lsp] Starting ace-server: ${env.aceServerPath}\n`);
7
+ const child = (0, child_process_1.spawn)(env.nodeBin, [env.aceServerPath], {
8
+ stdio: ['pipe', 'pipe', 'pipe'],
9
+ windowsHide: true,
10
+ env: {
11
+ ...process.env,
12
+ DEVECO_SDK_HOME: env.sdkPath,
13
+ },
14
+ });
15
+ const exitHandlers = [];
16
+ child.stderr?.on('data', (data) => {
17
+ const msg = data.toString().trim();
18
+ if (msg && !msg.includes('heartbeat')) {
19
+ process.stderr.write(`[ace-server] ${msg}\n`);
20
+ }
21
+ });
22
+ child.on('error', (err) => {
23
+ process.stderr.write(`[arkts-lsp] ace-server error: ${err.message}\n`);
24
+ for (const handler of exitHandlers) {
25
+ handler(1, null);
26
+ }
27
+ });
28
+ child.on('exit', (code, signal) => {
29
+ process.stderr.write(`[arkts-lsp] ace-server exited (code=${code}, signal=${signal})\n`);
30
+ for (const handler of exitHandlers) {
31
+ handler(code, signal);
32
+ }
33
+ });
34
+ return {
35
+ process: child,
36
+ kill: () => {
37
+ if (child.exitCode === null) {
38
+ child.kill();
39
+ }
40
+ },
41
+ onExit: (handler) => {
42
+ exitHandlers.push(handler);
43
+ },
44
+ };
45
+ }
46
+ //# sourceMappingURL=ace-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ace-server.js","sourceRoot":"","sources":["../src/ace-server.ts"],"names":[],"mappings":";;AAWA,wCA8CC;AAzDD,iDAAyD;AAWzD,SAAgB,cAAc,CAAC,GAAc;IAC3C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,GAAG,CAAC,aAAa,IAAI,CAAC,CAAC;IAEhF,MAAM,KAAK,GAAG,IAAA,qBAAK,EAAC,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE;QACpD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAC/B,WAAW,EAAE,IAAI;QACjB,GAAG,EAAE;YACH,GAAG,OAAO,CAAC,GAAG;YACd,eAAe,EAAE,GAAG,CAAC,OAAO;SAC7B;KACF,CAAC,CAAC;IAEH,MAAM,YAAY,GAAkB,EAAE,CAAC;IAEvC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;QACvE,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;YACnC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,IAAI,YAAY,MAAM,KAAK,CAAC,CAAC;QACzF,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;YACnC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,GAAG,EAAE;YACT,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAC5B,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,CAAC;QACH,CAAC;QACD,MAAM,EAAE,CAAC,OAAoB,EAAE,EAAE;YAC/B,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC"}
package/dist/env.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export interface DevEcoEnv {
2
+ devecoHome: string;
3
+ sdkPath: string;
4
+ aceServerPath: string;
5
+ nodeBin: string;
6
+ hvigorPath: string;
7
+ }
8
+ export declare function findDevEcoEnv(): DevEcoEnv | null;
9
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AA4DD,wBAAgB,aAAa,IAAI,SAAS,GAAG,IAAI,CAgBhD"}
package/dist/env.js ADDED
@@ -0,0 +1,110 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.findDevEcoEnv = findDevEcoEnv;
37
+ const path = __importStar(require("path"));
38
+ const fs = __importStar(require("fs"));
39
+ const os = __importStar(require("os"));
40
+ const PLATFORM = process.platform;
41
+ const IS_MAC = PLATFORM === 'darwin';
42
+ const IS_WIN = PLATFORM === 'win32';
43
+ const DEFAULT_PATHS = {
44
+ darwin: [
45
+ '/Applications/DevEco-Studio.app',
46
+ '/Applications/DevEco Studio.app',
47
+ path.join(os.homedir(), 'Applications', 'DevEco-Studio.app'),
48
+ path.join(os.homedir(), 'Applications', 'DevEco Studio.app'),
49
+ ],
50
+ linux: [
51
+ '/opt/DevEco-Studio',
52
+ path.join(os.homedir(), 'DevEco-Studio'),
53
+ ],
54
+ win32: [
55
+ 'D:/Application/Huawei/DevEco Studio',
56
+ 'C:/Program Files/Huawei/DevEco Studio',
57
+ path.join(os.homedir(), 'AppData', 'Local', 'Huawei', 'DevecoStudio'),
58
+ ],
59
+ };
60
+ function resolveContentsPath(rawPath) {
61
+ const lower = rawPath.toLowerCase();
62
+ if (lower.endsWith('.app')) {
63
+ return path.join(rawPath, 'Contents');
64
+ }
65
+ if (fs.existsSync(path.join(rawPath, 'plugins'))) {
66
+ return rawPath;
67
+ }
68
+ if (path.basename(rawPath) === 'Contents') {
69
+ return rawPath;
70
+ }
71
+ return path.join(rawPath, 'Contents');
72
+ }
73
+ function validateDevEcoHome(candidate) {
74
+ const contentsPath = resolveContentsPath(candidate);
75
+ const aceServerPath = path.join(contentsPath, 'plugins', 'openharmony', 'ace-server', 'out', 'index.js');
76
+ if (!fs.existsSync(aceServerPath))
77
+ return null;
78
+ const sdkPkg = path.join(contentsPath, 'sdk', 'default', 'sdk-pkg.json');
79
+ if (!fs.existsSync(sdkPkg))
80
+ return null;
81
+ const nodeName = IS_WIN ? 'node.exe' : 'node';
82
+ const nodeBinDir = IS_WIN ? '' : 'bin';
83
+ const nodeBin = path.join(contentsPath, 'tools', 'node', nodeBinDir, nodeName);
84
+ const hvigorPath = path.join(contentsPath, 'tools', 'hvigor', 'bin', 'hvigorw.js');
85
+ return {
86
+ devecoHome: contentsPath,
87
+ sdkPath: path.join(contentsPath, 'sdk', 'default'),
88
+ aceServerPath,
89
+ nodeBin,
90
+ hvigorPath,
91
+ };
92
+ }
93
+ function findDevEcoEnv() {
94
+ const envHome = process.env.DEVECO_HOME;
95
+ if (envHome) {
96
+ const result = validateDevEcoHome(envHome.trim());
97
+ if (result)
98
+ return result;
99
+ // When DEVECO_HOME is explicitly set but invalid, don't fall through to defaults
100
+ return null;
101
+ }
102
+ const defaults = DEFAULT_PATHS[PLATFORM] || DEFAULT_PATHS.linux;
103
+ for (const p of defaults) {
104
+ const result = validateDevEcoHome(p);
105
+ if (result)
106
+ return result;
107
+ }
108
+ return null;
109
+ }
110
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DevEcoEnv } from './env';
2
+ export declare function runHvigorSync(env: DevEcoEnv, projectRoot: string): boolean;
3
+ //# sourceMappingURL=hvigor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hvigor.d.ts","sourceRoot":"","sources":["../src/hvigor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AA2BvC,wBAAgB,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAgD1E"}
package/dist/hvigor.js ADDED
@@ -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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runHvigorSync = runHvigorSync;
37
+ const path = __importStar(require("path"));
38
+ const fs = __importStar(require("fs"));
39
+ const child_process_1 = require("child_process");
40
+ const HVIGOR_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
41
+ const HVIGOR_FLAGS = [
42
+ '--sync',
43
+ '-p', 'product=default',
44
+ '--analyze=normal',
45
+ '--parallel',
46
+ '--incremental',
47
+ '-p', 'enforce-ohpm=true',
48
+ '--daemonjs',
49
+ ];
50
+ function isSyncFresh(projectRoot) {
51
+ const depMap = path.join(projectRoot, '.hvigor', 'dependencyMap', 'dependencyMap.json5');
52
+ if (!fs.existsSync(depMap))
53
+ return false;
54
+ try {
55
+ const stat = fs.statSync(depMap);
56
+ const ageMs = Date.now() - stat.mtimeMs;
57
+ return ageMs < 24 * 60 * 60 * 1000; // fresh if less than 24 hours old
58
+ }
59
+ catch {
60
+ return false;
61
+ }
62
+ }
63
+ function runHvigorSync(env, projectRoot) {
64
+ if (isSyncFresh(projectRoot)) {
65
+ process.stderr.write('[arkts-lsp] hvigor sync skipped (dependency map is fresh)\n');
66
+ return true;
67
+ }
68
+ if (!fs.existsSync(env.nodeBin)) {
69
+ process.stderr.write(`[arkts-lsp] DevEco node not found at: ${env.nodeBin}\n`);
70
+ return false;
71
+ }
72
+ if (!fs.existsSync(env.hvigorPath)) {
73
+ process.stderr.write(`[arkts-lsp] hvigorw.js not found at: ${env.hvigorPath}\n`);
74
+ return false;
75
+ }
76
+ process.stderr.write('[arkts-lsp] hvigor sync starting...\n');
77
+ const startTime = Date.now();
78
+ const result = (0, child_process_1.spawnSync)(env.nodeBin, [env.hvigorPath, ...HVIGOR_FLAGS], {
79
+ cwd: projectRoot,
80
+ timeout: HVIGOR_TIMEOUT_MS,
81
+ windowsHide: true,
82
+ encoding: 'utf8',
83
+ env: {
84
+ ...process.env,
85
+ DEVECO_SDK_HOME: env.sdkPath,
86
+ },
87
+ });
88
+ const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
89
+ if (result.error) {
90
+ if (result.error.code === 'ETIMEDOUT') {
91
+ process.stderr.write(`[arkts-lsp] hvigor sync timed out after ${HVIGOR_TIMEOUT_MS / 1000}s\n`);
92
+ return false;
93
+ }
94
+ process.stderr.write(`[arkts-lsp] hvigor sync error: ${result.error.message}\n`);
95
+ return false;
96
+ }
97
+ if (result.status !== 0) {
98
+ process.stderr.write(`[arkts-lsp] hvigor sync failed (exit ${result.status}, ${elapsed}s)\n`);
99
+ if (result.stderr)
100
+ process.stderr.write(result.stderr.slice(-500) + '\n');
101
+ return false;
102
+ }
103
+ process.stderr.write(`[arkts-lsp] hvigor sync completed (${elapsed}s)\n`);
104
+ return true;
105
+ }
106
+ //# sourceMappingURL=hvigor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hvigor.js","sourceRoot":"","sources":["../src/hvigor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const env_1 = require("./env");
5
+ const project_1 = require("./project");
6
+ const hvigor_1 = require("./hvigor");
7
+ const ace_server_1 = require("./ace-server");
8
+ const proxy_1 = require("./proxy");
9
+ function main() {
10
+ process.stderr.write('[arkts-lsp] Starting ArkTS LSP Proxy\n');
11
+ // Step 1: Find DevEco Studio
12
+ const env = (0, env_1.findDevEcoEnv)();
13
+ if (!env) {
14
+ process.stderr.write('==============================================\n');
15
+ process.stderr.write(' ArkTS LSP: DevEco Studio not found!\n\n');
16
+ process.stderr.write(' Set the environment variable:\n');
17
+ process.stderr.write(' export DEVECO_HOME=/Applications/DevEco-Studio.app\n');
18
+ process.stderr.write('==============================================\n');
19
+ process.exit(1);
20
+ }
21
+ process.stderr.write(`[arkts-lsp] DevEco: ${env.devecoHome}\n`);
22
+ // Step 2: Find project root
23
+ const cwd = process.cwd();
24
+ const projectRoot = (0, project_1.findProjectRoot)(cwd);
25
+ if (!projectRoot) {
26
+ process.stderr.write(`[arkts-lsp] No HarmonyOS project found at ${cwd}\n`);
27
+ process.stderr.write('[arkts-lsp] Expected build-profile.json5 in current or parent directory\n');
28
+ process.exit(1);
29
+ }
30
+ const project = (0, project_1.parseProject)(projectRoot, env.sdkPath);
31
+ if (!project) {
32
+ process.stderr.write(`[arkts-lsp] Failed to parse project at ${projectRoot}\n`);
33
+ process.exit(1);
34
+ }
35
+ process.stderr.write(`[arkts-lsp] Project: ${project.projectRoot}\n`);
36
+ process.stderr.write(`[arkts-lsp] Modules: ${project.modules.map(m => m.moduleName).join(', ')}\n`);
37
+ // Step 3: Run hvigor sync
38
+ const syncOk = (0, hvigor_1.runHvigorSync)(env, project.projectRoot);
39
+ if (!syncOk) {
40
+ process.stderr.write('[arkts-lsp] hvigor sync failed, continuing anyway\n');
41
+ }
42
+ // Step 4: Start ace-server
43
+ const ace = (0, ace_server_1.startAceServer)(env);
44
+ // Step 5: Set up LSP proxy
45
+ const proxy = (0, proxy_1.createProxy)(process.stdin, process.stdout, ace.process, {
46
+ rootUri: project.rootUri,
47
+ lspServerWorkspacePath: project.lspServerWorkspacePath,
48
+ modules: project.modules,
49
+ });
50
+ // Step 6: Handle cleanup
51
+ const cleanup = () => {
52
+ proxy.dispose();
53
+ ace.kill();
54
+ };
55
+ process.on('SIGINT', () => {
56
+ cleanup();
57
+ process.exit(0);
58
+ });
59
+ process.on('SIGTERM', () => {
60
+ cleanup();
61
+ process.exit(0);
62
+ });
63
+ process.stdin.on('end', () => {
64
+ cleanup();
65
+ });
66
+ ace.onExit((code) => {
67
+ proxy.dispose();
68
+ process.exit(code ?? 1);
69
+ });
70
+ }
71
+ main();
72
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,+BAAsC;AACtC,uCAA0D;AAC1D,qCAAyC;AACzC,6CAA8C;AAC9C,mCAAsC;AAEtC,SAAS,IAAI;IACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAE/D,6BAA6B;IAC7B,MAAM,GAAG,GAAG,IAAA,mBAAa,GAAE,CAAC;IAC5B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACzE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAClE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;QACjF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC;IAEhE,4BAA4B;IAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,WAAW,GAAG,IAAA,yBAAe,EAAC,GAAG,CAAC,CAAC;IACzC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6CAA6C,GAAG,IAAI,CAAC,CAAC;QAC3E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAClG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,OAAO,GAAG,IAAA,sBAAY,EAAC,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0CAA0C,WAAW,IAAI,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC;IACtE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEpG,0BAA0B;IAC1B,MAAM,MAAM,GAAG,IAAA,sBAAa,EAAC,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACvD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;IAC9E,CAAC;IAED,2BAA2B;IAC3B,MAAM,GAAG,GAAG,IAAA,2BAAc,EAAC,GAAG,CAAC,CAAC;IAEhC,2BAA2B;IAC3B,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE;QACpE,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,sBAAsB,EAAE,OAAO,CAAC,sBAAsB;QACtD,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC,CAAC;IAEH,yBAAyB;IACzB,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,KAAK,CAAC,OAAO,EAAE,CAAC;QAChB,GAAG,CAAC,IAAI,EAAE,CAAC;IACb,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,OAAO,EAAE,CAAC;QACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACzB,OAAO,EAAE,CAAC;QACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QAClB,KAAK,CAAC,OAAO,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC"}
@@ -0,0 +1,20 @@
1
+ export interface AceModule {
2
+ moduleName: string;
3
+ modulePath: string;
4
+ deviceType: string[];
5
+ aceLoaderPath: string;
6
+ jsComponentType: number;
7
+ sdkJsPath: string;
8
+ compatibleSdkLevel: string;
9
+ apiType: string;
10
+ }
11
+ export interface ProjectConfig {
12
+ projectRoot: string;
13
+ rootUri: string;
14
+ lspServerWorkspacePath: string;
15
+ modules: AceModule[];
16
+ }
17
+ export declare function extractCompatibleSdkLevel(version: string): string;
18
+ export declare function findProjectRoot(startDir: string): string | null;
19
+ export declare function parseProject(projectRoot: string, sdkPath: string): ProjectConfig | null;
20
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGjE;AA2BD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW/D;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAiDvF"}
@@ -0,0 +1,125 @@
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.extractCompatibleSdkLevel = extractCompatibleSdkLevel;
40
+ exports.findProjectRoot = findProjectRoot;
41
+ exports.parseProject = parseProject;
42
+ const path = __importStar(require("path"));
43
+ const fs = __importStar(require("fs"));
44
+ const json5_1 = __importDefault(require("json5"));
45
+ function extractCompatibleSdkLevel(version) {
46
+ const match = version.match(/\((\d+)\)/);
47
+ return match ? match[1] : '12';
48
+ }
49
+ function constructModule(name, srcPath, projectRoot, sdkPath, compatibleSdkLevel, deviceTypes) {
50
+ const modulePath = path.resolve(projectRoot, srcPath);
51
+ const deviceType = deviceTypes[0] || 'phone';
52
+ const sdkJsPath = path.join(sdkPath, 'js', 'api', deviceType) + path.sep;
53
+ const aceLoaderPath = path.join(sdkPath, 'js', 'framework', deviceType, 'ace-loader');
54
+ return {
55
+ moduleName: name,
56
+ modulePath,
57
+ deviceType: deviceTypes.length > 0 ? deviceTypes : ['phone'],
58
+ aceLoaderPath,
59
+ jsComponentType: 0,
60
+ sdkJsPath,
61
+ compatibleSdkLevel,
62
+ apiType: 'Stage',
63
+ };
64
+ }
65
+ function findProjectRoot(startDir) {
66
+ let current = path.resolve(startDir);
67
+ for (let i = 0; i < 10; i++) {
68
+ if (fs.existsSync(path.join(current, 'build-profile.json5'))) {
69
+ return current;
70
+ }
71
+ const parent = path.dirname(current);
72
+ if (parent === current)
73
+ break;
74
+ current = parent;
75
+ }
76
+ return null;
77
+ }
78
+ function parseProject(projectRoot, sdkPath) {
79
+ const profilePath = path.join(projectRoot, 'build-profile.json5');
80
+ if (!fs.existsSync(profilePath))
81
+ return null;
82
+ try {
83
+ const content = fs.readFileSync(profilePath, 'utf-8');
84
+ const profile = json5_1.default.parse(content);
85
+ const products = profile.app?.products || [];
86
+ const firstProduct = products[0];
87
+ const compatibleSdkLevel = firstProduct?.compatibleSdkVersion
88
+ ? extractCompatibleSdkLevel(firstProduct.compatibleSdkVersion)
89
+ : '12';
90
+ // Derive deviceType from product config, default to ['phone']
91
+ const deviceTypes = firstProduct?.compatibleDeviceType
92
+ ? (Array.isArray(firstProduct.compatibleDeviceType)
93
+ ? firstProduct.compatibleDeviceType
94
+ : [firstProduct.compatibleDeviceType])
95
+ : ['phone'];
96
+ const rawModules = profile.modules || [];
97
+ const modules = [];
98
+ for (const mod of rawModules) {
99
+ if (!mod.name || !mod.srcPath) {
100
+ process.stderr.write(`[arkts-lsp] Skipping module with missing name or srcPath\n`);
101
+ continue;
102
+ }
103
+ modules.push(constructModule(mod.name, mod.srcPath, projectRoot, sdkPath, compatibleSdkLevel, deviceTypes));
104
+ }
105
+ if (modules.length === 0)
106
+ return null;
107
+ return {
108
+ projectRoot,
109
+ rootUri: 'file://' + projectRoot,
110
+ lspServerWorkspacePath: projectRoot,
111
+ modules,
112
+ };
113
+ }
114
+ catch (e) {
115
+ process.stderr.write(`[arkts-lsp] Failed to parse build-profile.json5:\n`);
116
+ if (e instanceof Error) {
117
+ process.stderr.write(e.stack + '\n');
118
+ }
119
+ else {
120
+ process.stderr.write(String(e) + '\n');
121
+ }
122
+ return null;
123
+ }
124
+ }
125
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { ChildProcess } from 'child_process';
2
+ import type { AceModule } from './project';
3
+ export interface LspMessage {
4
+ jsonrpc?: string;
5
+ id?: number | string;
6
+ method?: string;
7
+ params?: Record<string, unknown>;
8
+ }
9
+ export interface InitializationPayload {
10
+ rootUri: string;
11
+ lspServerWorkspacePath: string;
12
+ modules: AceModule[];
13
+ }
14
+ export declare function injectInitializationOptions(message: LspMessage, payload: InitializationPayload): LspMessage;
15
+ export interface ProxyHandle {
16
+ dispose: () => void;
17
+ }
18
+ export declare function createProxy(clientIn: NodeJS.ReadableStream, clientOut: NodeJS.WritableStream, aceProcess: ChildProcess, payload: InitializationPayload): ProxyHandle;
19
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,qBAAqB,GAC7B,UAAU,CAYZ;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,CAAC,cAAc,EAC/B,SAAS,EAAE,MAAM,CAAC,cAAc,EAChC,UAAU,EAAE,YAAY,EACxB,OAAO,EAAE,qBAAqB,GAC7B,WAAW,CA6Db"}
package/dist/proxy.js ADDED
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.injectInitializationOptions = injectInitializationOptions;
4
+ exports.createProxy = createProxy;
5
+ const node_1 = require("vscode-jsonrpc/node");
6
+ function injectInitializationOptions(message, payload) {
7
+ if (message.method === 'initialize' && message.params) {
8
+ const params = { ...message.params };
9
+ params.initializationOptions = {
10
+ ...(params.initializationOptions || {}),
11
+ rootUri: payload.rootUri,
12
+ lspServerWorkspacePath: payload.lspServerWorkspacePath,
13
+ modules: payload.modules,
14
+ };
15
+ return { ...message, params };
16
+ }
17
+ return message;
18
+ }
19
+ function createProxy(clientIn, clientOut, aceProcess, payload) {
20
+ const aceIn = aceProcess.stdout;
21
+ const aceOut = aceProcess.stdin;
22
+ if (!aceIn || !aceOut) {
23
+ throw new Error('aceProcess must have both stdout and stdin streams');
24
+ }
25
+ const clientConn = (0, node_1.createMessageConnection)(new node_1.StreamMessageReader(clientIn), new node_1.StreamMessageWriter(clientOut));
26
+ const aceConn = (0, node_1.createMessageConnection)(new node_1.StreamMessageReader(aceIn), new node_1.StreamMessageWriter(aceOut));
27
+ clientConn.onNotification((method, params) => {
28
+ aceConn.sendNotification(method, params);
29
+ });
30
+ clientConn.onRequest((method, params, token) => {
31
+ if (method === 'initialize') {
32
+ const message = { method, params: params };
33
+ const modified = injectInitializationOptions(message, payload);
34
+ return aceConn.sendRequest(method, modified.params, token);
35
+ }
36
+ return aceConn.sendRequest(method, params, token);
37
+ });
38
+ aceConn.onNotification((method, params) => {
39
+ clientConn.sendNotification(method, params);
40
+ });
41
+ aceConn.onRequest((method, params, token) => {
42
+ return clientConn.sendRequest(method, params, token);
43
+ });
44
+ aceConn.onError(([err]) => {
45
+ process.stderr.write(`[arkts-lsp] ace connection error: ${err.message}\n`);
46
+ clientConn.dispose();
47
+ });
48
+ clientConn.onError(([err]) => {
49
+ process.stderr.write(`[arkts-lsp] client connection error: ${err.message}\n`);
50
+ aceConn.dispose();
51
+ });
52
+ aceProcess.on('exit', () => {
53
+ clientConn.dispose();
54
+ });
55
+ clientConn.listen();
56
+ aceConn.listen();
57
+ return {
58
+ dispose: () => {
59
+ clientConn.dispose();
60
+ aceConn.dispose();
61
+ },
62
+ };
63
+ }
64
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "arkts-lsp-proxy",
3
+ "version": "0.1.0",
4
+ "description": "ArkTS LSP Proxy — bridges DevEco Studio's ace-server to Claude Code",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "arkts-lsp-proxy": "dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "dev": "tsc --watch",
12
+ "test": "vitest run",
13
+ "test:watch": "vitest",
14
+ "lint": "eslint src/ test/",
15
+ "prepublishOnly": "npm run build && npm test"
16
+ },
17
+ "files": [
18
+ "dist/"
19
+ ],
20
+ "keywords": [
21
+ "arkts",
22
+ "lsp",
23
+ "harmonyos",
24
+ "deveco",
25
+ "claude-code"
26
+ ],
27
+ "author": "",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/HelloiOS2014/harmony_arkts_lsp_proxy.git"
32
+ },
33
+ "engines": {
34
+ "node": ">=18"
35
+ },
36
+ "dependencies": {
37
+ "json5": "^2.2.3",
38
+ "vscode-jsonrpc": "^8.2.1"
39
+ },
40
+ "devDependencies": {
41
+ "@eslint/js": "^10.0.1",
42
+ "@types/json5": "^0.0.30",
43
+ "@types/node": "^25.6.1",
44
+ "eslint": "^10.3.0",
45
+ "typescript": "^6.0.3",
46
+ "typescript-eslint": "^8.59.2",
47
+ "vitest": "^4.1.5"
48
+ }
49
+ }