arkts-lsp-proxy 0.1.6 → 0.1.8

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
@@ -1,6 +1,6 @@
1
1
  # ArkTS LSP Proxy
2
2
 
3
- 将 DevEco Studio 内置的 ArkTS 语言服务器(ace-server)桥接出来,让 Claude Code 等支持 LSP 的工具获得 ArkTS 语言智能。
3
+ 将 DevEco Studio 内置的 ArkTS 语言服务器(ace-server)桥接出来,让 Claude Code 等支持 LSP 的工具获得 ArkTS 语言智能;同时提供 Codex MCP 适配器,让 Codex 通过工具调用使用 ArkTS hover、definition、symbols 和 diagnostics。
4
4
 
5
5
  ## 解决什么问题
6
6
 
@@ -35,7 +35,21 @@ arkts-lsp-proxy (Node.js 进程)
35
35
  └── @Component/@State/@Prop 语义理解
36
36
  ```
37
37
 
38
- 代理不实现 ArkTS 语义分析,只做启动适配、消息转发、参数注入和必要的 LSP 结果归一化。比如 DevEco ace-server 会把 hover 内容包成私有 JSON 字符串,代理会转换成标准 Markdown hover,方便 Claude Code 直接消费类型信息。DevEco ace-server 未提供的 symbol 能力由 proxy 做轻量 fallback。
38
+ Codex 侧不使用 Claude Code `.lsp.json` 自动激活模型,而是通过 `arkts-lsp-mcp` 启动 MCP server:
39
+
40
+ ```
41
+ Codex
42
+ │ MCP stdio (JSON-RPC lines)
43
+
44
+ arkts-lsp-mcp
45
+ ├── 轻量工具:project_info / document_symbols / workspace_symbols
46
+ └── LSP-backed 工具:hover / definition / references / signature_help / diagnostics
47
+
48
+
49
+ arkts-lsp-proxy → ace-server
50
+ ```
51
+
52
+ 代理不实现 ArkTS 语义分析,只做启动适配、消息转发、参数注入和必要的 LSP 结果归一化。比如 DevEco ace-server 会把 hover 内容包成私有 JSON 字符串,代理会转换成标准 Markdown hover,方便 Claude Code 或 Codex 直接消费类型信息。DevEco ace-server 未提供的 symbol 能力由 proxy/MCP 做轻量 fallback。
39
53
 
40
54
  ## 当前支持的核心能力
41
55
 
@@ -47,6 +61,7 @@ arkts-lsp-proxy (Node.js 进程)
47
61
  - `textDocument/documentSymbol`,基于打开文件文本解析 ArkTS/ArkUI 文件结构
48
62
  - `workspace/symbol`,基于项目根轻量扫描 `.ets/.ts/.d.ets/.d.ts`
49
63
  - diagnostics,来自 ace-server 的发布诊断
64
+ - Codex MCP tools:`arkts_project_info`、`arkts_document_symbols`、`arkts_workspace_symbols`、`arkts_hover`、`arkts_definition`、`arkts_references`、`arkts_signature_help`、`arkts_diagnostics`
50
65
 
51
66
  ## 前置条件
52
67
 
@@ -65,6 +80,57 @@ arkts-lsp-proxy (Node.js 进程)
65
80
  /plugin install arkts-lsp
66
81
  ```
67
82
 
83
+ ### Codex 项目级 MCP
84
+
85
+ Codex 不使用全局 marketplace 安装。为了避免所有项目都加载 ArkTS MCP 工具,
86
+ 请在需要启用 ArkTS 能力的 Codex 项目目录执行项目级安装脚本:
87
+
88
+ ```bash
89
+ npx -y --package arkts-lsp-proxy@latest arkts-lsp-codex-install
90
+ ```
91
+
92
+ 脚本只负责写入当前项目的 Codex 配置,不会判断该目录是不是 HarmonyOS 项目,也不会扫描
93
+ 子目录。它会写入:
94
+
95
+ ```text
96
+ <project>/.codex/config.toml
97
+ ```
98
+
99
+ 写入内容等价于:
100
+
101
+ ```toml
102
+ [mcp_servers.arkts-lsp]
103
+ command = "npx"
104
+ args = ["-y", "--package", "arkts-lsp-proxy@latest", "arkts-lsp-mcp"]
105
+
106
+ [mcp_servers.arkts-lsp.env]
107
+ ARKTS_LSP_SYNC = "auto"
108
+ ```
109
+
110
+ 这样 ArkTS MCP 只在该 Codex 项目中生效;其它项目没有这段项目级
111
+ `.codex/config.toml`,不会暴露 ArkTS tools,也不会占用工具上下文。真正的
112
+ HarmonyOS 项目识别由 MCP tools 在运行时根据文件路径、`projectRoot` 或 `startPath`
113
+ 完成。
114
+
115
+ 安装脚本会按当前项目状态处理:
116
+
117
+ | 场景 | 行为 |
118
+ |------|------|
119
+ | 没有 `.codex/config.toml` | 创建 `.codex/` 目录和新的 `config.toml` |
120
+ | 已有 `.codex/config.toml`,但没有 Codex MCP 配置 | 先备份原文件,再写入 `arkts-lsp` MCP 配置 |
121
+ | 已有 `.codex/config.toml`,且已有其它配置 | 先备份原文件,保留其它配置,只新增或替换 `[mcp_servers.arkts-lsp]` 相关配置 |
122
+
123
+ 备份文件位于同一目录,形如 `config.toml.bak-YYYYMMDDTHHMMSSZ`。安装脚本只清理
124
+ 自己生成的时间戳备份,默认保留最近 3 份;其它手工备份文件不会被删除。如果只是想
125
+ 预览将要写入的内容,可以先执行:
126
+
127
+ ```bash
128
+ npx -y --package arkts-lsp-proxy@latest arkts-lsp-codex-install --dry-run
129
+ ```
130
+
131
+ 注意:Codex 只会读取 trusted project 的项目级 `.codex/config.toml`。安装后请在
132
+ 该项目根目录启动 Codex,必要时重启当前 Codex 会话。
133
+
68
134
  ### npm 全局安装(手动 CLI 使用)
69
135
 
70
136
  ```bash
@@ -98,6 +164,12 @@ export DEVECO_HOME=/opt/DevEco-Studio
98
164
  arkts-lsp-proxy --project-root /path/to/harmonyos/project
99
165
  ```
100
166
 
167
+ 也可以手动启动 Codex MCP server:
168
+
169
+ ```bash
170
+ arkts-lsp-mcp
171
+ ```
172
+
101
173
  当从非鸿蒙目录启动时,默认不会立即校验项目;会等到 LSP 初始化请求到来后根据 `rootUri`/`workspaceFolders` 自动定位鸿蒙项目路径。
102
174
 
103
175
  ### Hvigor metadata sync
@@ -187,24 +259,32 @@ src/
187
259
  ├── hvigor.ts hvigor metadata 状态、sync 策略与后台执行
188
260
  ├── ace-server.ts ace-server 子进程生命周期管理(onExit 回调)
189
261
  ├── proxy.ts LSP 消息代理,拦截 initialize 注入参数
190
- └── index.ts 入口,串联所有模块
262
+ ├── arkts-client.ts Codex MCP 侧复用 proxy 的轻量 LSP client
263
+ ├── mcp-tools.ts ArkTS MCP tools 的实现
264
+ ├── mcp.ts MCP JSON-RPC 协议处理与 stdio server
265
+ ├── mcp-server.ts arkts-lsp-mcp 入口
266
+ ├── codex-install.ts Codex 项目级 MCP 安装脚本
267
+ └── index.ts arkts-lsp-proxy 入口
191
268
  .claude-plugin/
192
269
  └── marketplace.json marketplace 清单 + lspServers 配置
193
270
  plugins/
194
271
  └── arkts-lsp/
195
272
  ├── .claude-plugin/
196
- │ └── plugin.json 插件清单
273
+ │ └── plugin.json Claude Code 插件清单
197
274
  ├── hooks/
198
275
  │ └── hooks.json SessionStart 自动安装 hook
199
276
  ├── package.json npm 依赖声明(供 hook 自动安装)
200
277
  ├── .lsp.json LSP 服务器配置
201
- └── README.md 插件文档
278
+ └── README.md Claude Code 插件文档
202
279
  test/
280
+ ├── codex-install.test.ts
203
281
  ├── env.test.ts
204
282
  ├── project.test.ts
205
283
  ├── hvigor.test.ts
206
284
  ├── ace-server.test.ts
207
285
  ├── proxy.test.ts
286
+ ├── mcp.test.ts
287
+ ├── mcp-tools.test.ts
208
288
  ├── index.test.ts
209
289
  └── fixtures/
210
290
  ```
@@ -214,6 +294,7 @@ test/
214
294
  - TypeScript
215
295
  - `vscode-jsonrpc` — LSP 消息解析与传输
216
296
  - `json5` — 解析 `build-profile.json5`
297
+ - MCP stdio JSON-RPC — Codex 工具入口(零新增运行时依赖)
217
298
  - Vitest — 测试
218
299
 
219
300
  ## License
@@ -0,0 +1,43 @@
1
+ import { type DevEcoEnv } from './env';
2
+ import { type ProxyHandle } from './proxy';
3
+ export interface Position {
4
+ line: number;
5
+ character: number;
6
+ }
7
+ export interface ArktsRequest {
8
+ projectRoot?: string;
9
+ filePath: string;
10
+ position: Position;
11
+ text?: string;
12
+ }
13
+ export interface ArktsDiagnosticsRequest {
14
+ projectRoot?: string;
15
+ filePath: string;
16
+ text?: string;
17
+ timeoutMs?: number;
18
+ }
19
+ export type ProxyFactory = (clientIn: NodeJS.ReadableStream, clientOut: NodeJS.WritableStream, env: DevEcoEnv, options: {
20
+ env: DevEcoEnv;
21
+ projectRootHint?: string;
22
+ }) => ProxyHandle;
23
+ export interface ArktsLanguageClientOptions {
24
+ envFinder?: () => DevEcoEnv | null;
25
+ proxyFactory?: ProxyFactory;
26
+ }
27
+ export declare class ArktsLanguageClient {
28
+ private readonly envFinder;
29
+ private readonly proxyFactory;
30
+ private readonly sessions;
31
+ constructor(options?: ArktsLanguageClientOptions);
32
+ hover(request: ArktsRequest): Promise<unknown>;
33
+ definition(request: ArktsRequest): Promise<unknown>;
34
+ references(request: ArktsRequest): Promise<unknown>;
35
+ signatureHelp(request: ArktsRequest): Promise<unknown>;
36
+ diagnostics(request: ArktsDiagnosticsRequest): Promise<unknown[]>;
37
+ dispose(): void;
38
+ private sendPositionRequest;
39
+ private getSession;
40
+ private createSession;
41
+ private ensureDocument;
42
+ }
43
+ //# sourceMappingURL=arkts-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arkts-client.d.ts","sourceRoot":"","sources":["../src/arkts-client.ts"],"names":[],"mappings":"AAUA,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAGxD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD,MAAM,MAAM,YAAY,GAAG,CACzB,QAAQ,EAAE,MAAM,CAAC,cAAc,EAC/B,SAAS,EAAE,MAAM,CAAC,cAAc,EAChC,GAAG,EAAE,SAAS,EACd,OAAO,EAAE;IAAE,GAAG,EAAE,SAAS,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,KAClD,WAAW,CAAC;AAEjB,MAAM,WAAW,0BAA0B;IACzC,SAAS,CAAC,EAAE,MAAM,SAAS,GAAG,IAAI,CAAC;IACnC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAmCD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuC;gBAEpD,OAAO,GAAE,0BAA+B;IAK9C,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAI9C,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAInD,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAOnD,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAItD,WAAW,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAuBvE,OAAO,IAAI,IAAI;YAOD,mBAAmB;IAajC,OAAO,CAAC,UAAU;YAcJ,aAAa;YAyDb,cAAc;CAgC7B"}
@@ -0,0 +1,213 @@
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.ArktsLanguageClient = void 0;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const node_stream_1 = require("node:stream");
40
+ const node_url_1 = require("node:url");
41
+ const node_1 = require("vscode-jsonrpc/node");
42
+ const env_1 = require("./env");
43
+ const proxy_1 = require("./proxy");
44
+ const project_1 = require("./project");
45
+ const defaultProxyFactory = (clientIn, clientOut, env, options) => (0, proxy_1.createProxy)(clientIn, clientOut, env, options);
46
+ function resolveProjectRoot(projectRoot, filePath) {
47
+ const candidate = projectRoot ? path.resolve(projectRoot) : path.resolve(filePath);
48
+ const resolved = (0, project_1.findProjectRoot)(candidate);
49
+ if (!resolved) {
50
+ throw new Error(`No ArkTS project root found for ${candidate}`);
51
+ }
52
+ return resolved;
53
+ }
54
+ function readDocumentText(filePath, explicitText) {
55
+ if (typeof explicitText === 'string') {
56
+ return explicitText;
57
+ }
58
+ return fs.readFileSync(filePath, 'utf8');
59
+ }
60
+ class ArktsLanguageClient {
61
+ envFinder;
62
+ proxyFactory;
63
+ sessions = new Map();
64
+ constructor(options = {}) {
65
+ this.envFinder = options.envFinder ?? env_1.findDevEcoEnv;
66
+ this.proxyFactory = options.proxyFactory ?? defaultProxyFactory;
67
+ }
68
+ async hover(request) {
69
+ return this.sendPositionRequest('textDocument/hover', request);
70
+ }
71
+ async definition(request) {
72
+ return this.sendPositionRequest('textDocument/definition', request);
73
+ }
74
+ async references(request) {
75
+ return this.sendPositionRequest('textDocument/references', {
76
+ ...request,
77
+ context: { includeDeclaration: true },
78
+ });
79
+ }
80
+ async signatureHelp(request) {
81
+ return this.sendPositionRequest('textDocument/signatureHelp', request);
82
+ }
83
+ async diagnostics(request) {
84
+ const filePath = path.resolve(request.filePath);
85
+ const projectRoot = resolveProjectRoot(request.projectRoot, filePath);
86
+ const session = await this.getSession(projectRoot);
87
+ const uri = await this.ensureDocument(session, filePath, request.text);
88
+ const existing = session.diagnostics.get(uri);
89
+ if (existing) {
90
+ return existing;
91
+ }
92
+ return new Promise((resolve) => {
93
+ const timeout = setTimeout(() => {
94
+ resolve(session.diagnostics.get(uri) ?? []);
95
+ }, request.timeoutMs ?? 1500);
96
+ const pending = session.pendingDiagnostics.get(uri) ?? [];
97
+ pending.push((diagnostics) => {
98
+ clearTimeout(timeout);
99
+ resolve(diagnostics);
100
+ });
101
+ session.pendingDiagnostics.set(uri, pending);
102
+ });
103
+ }
104
+ dispose() {
105
+ for (const promise of this.sessions.values()) {
106
+ promise.then((session) => session.handle.dispose()).catch(() => undefined);
107
+ }
108
+ this.sessions.clear();
109
+ }
110
+ async sendPositionRequest(method, request) {
111
+ const filePath = path.resolve(request.filePath);
112
+ const projectRoot = resolveProjectRoot(request.projectRoot, filePath);
113
+ const session = await this.getSession(projectRoot);
114
+ const uri = await this.ensureDocument(session, filePath, request.text);
115
+ return session.connection.sendRequest(method, {
116
+ textDocument: { uri },
117
+ position: request.position,
118
+ ...(request.context ? { context: request.context } : {}),
119
+ });
120
+ }
121
+ getSession(projectRoot) {
122
+ const existing = this.sessions.get(projectRoot);
123
+ if (existing) {
124
+ return existing;
125
+ }
126
+ const created = this.createSession(projectRoot).catch((error) => {
127
+ this.sessions.delete(projectRoot);
128
+ throw error;
129
+ });
130
+ this.sessions.set(projectRoot, created);
131
+ return created;
132
+ }
133
+ async createSession(projectRoot) {
134
+ const env = this.envFinder();
135
+ if (!env) {
136
+ throw new Error('DevEco Studio not found. Set DEVECO_HOME or ARKTS_DEVECO_HOME.');
137
+ }
138
+ const clientIn = new node_stream_1.PassThrough();
139
+ const clientOut = new node_stream_1.PassThrough();
140
+ const handle = this.proxyFactory(clientIn, clientOut, env, { env, projectRootHint: projectRoot });
141
+ const connection = (0, node_1.createMessageConnection)(new node_1.StreamMessageReader(clientOut), new node_1.StreamMessageWriter(clientIn));
142
+ const session = {
143
+ projectRoot,
144
+ connection,
145
+ handle,
146
+ documents: new Map(),
147
+ diagnostics: new Map(),
148
+ pendingDiagnostics: new Map(),
149
+ };
150
+ connection.onNotification('textDocument/publishDiagnostics', (params) => {
151
+ const payload = params;
152
+ if (typeof payload.uri !== 'string') {
153
+ return;
154
+ }
155
+ const diagnostics = Array.isArray(payload.diagnostics) ? payload.diagnostics : [];
156
+ session.diagnostics.set(payload.uri, diagnostics);
157
+ const pending = session.pendingDiagnostics.get(payload.uri) ?? [];
158
+ session.pendingDiagnostics.delete(payload.uri);
159
+ for (const resolve of pending) {
160
+ resolve(diagnostics);
161
+ }
162
+ });
163
+ connection.listen();
164
+ await connection.sendRequest('initialize', {
165
+ processId: process.pid,
166
+ rootUri: (0, node_url_1.pathToFileURL)(projectRoot).toString(),
167
+ workspaceFolders: [
168
+ {
169
+ uri: (0, node_url_1.pathToFileURL)(projectRoot).toString(),
170
+ name: path.basename(projectRoot),
171
+ },
172
+ ],
173
+ capabilities: {
174
+ textDocument: {
175
+ hover: { contentFormat: ['markdown', 'plaintext'] },
176
+ },
177
+ },
178
+ });
179
+ connection.sendNotification('initialized', {});
180
+ return session;
181
+ }
182
+ async ensureDocument(session, filePath, explicitText) {
183
+ const uri = (0, node_url_1.pathToFileURL)(filePath).toString();
184
+ const text = readDocumentText(filePath, explicitText);
185
+ const opened = session.documents.get(uri);
186
+ if (!opened) {
187
+ session.documents.set(uri, { text, version: 1 });
188
+ session.connection.sendNotification('textDocument/didOpen', {
189
+ textDocument: {
190
+ uri,
191
+ languageId: 'arkts',
192
+ version: 1,
193
+ text,
194
+ },
195
+ });
196
+ return uri;
197
+ }
198
+ if (opened.text !== text) {
199
+ const next = { text, version: opened.version + 1 };
200
+ session.documents.set(uri, next);
201
+ session.connection.sendNotification('textDocument/didChange', {
202
+ textDocument: {
203
+ uri,
204
+ version: next.version,
205
+ },
206
+ contentChanges: [{ text }],
207
+ });
208
+ }
209
+ return uri;
210
+ }
211
+ }
212
+ exports.ArktsLanguageClient = ArktsLanguageClient;
213
+ //# sourceMappingURL=arkts-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arkts-client.js","sourceRoot":"","sources":["../src/arkts-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ export declare const CODEX_MCP_CONFIG_BLOCK = "[mcp_servers.arkts-lsp]\ncommand = \"npx\"\nargs = [\"-y\", \"--package\", \"arkts-lsp-proxy@latest\", \"arkts-lsp-mcp\"]\n\n[mcp_servers.arkts-lsp.env]\nARKTS_LSP_SYNC = \"auto\"\n";
3
+ interface InstallResult {
4
+ installRoot: string;
5
+ configPath: string;
6
+ backupPath?: string;
7
+ changed: boolean;
8
+ content: string;
9
+ }
10
+ export declare function upsertCodexMcpConfig(existing: string): string;
11
+ export declare function installCodexProjectConfig(startDir: string, dryRun?: boolean): InstallResult;
12
+ export {};
13
+ //# sourceMappingURL=codex-install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-install.d.ts","sourceRoot":"","sources":["../src/codex-install.ts"],"names":[],"mappings":";AASA,eAAO,MAAM,sBAAsB,0LAMlC,CAAC;AAQF,UAAU,aAAa;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAqFD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG7D;AAgDD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,aAAa,CA4BzF"}
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.CODEX_MCP_CONFIG_BLOCK = void 0;
38
+ exports.upsertCodexMcpConfig = upsertCodexMcpConfig;
39
+ exports.installCodexProjectConfig = installCodexProjectConfig;
40
+ const fs = __importStar(require("node:fs"));
41
+ const path = __importStar(require("node:path"));
42
+ const SERVER_NAME = 'arkts-lsp';
43
+ const CONFIG_RELATIVE_PATH = path.join('.codex', 'config.toml');
44
+ const MAX_GENERATED_BACKUPS = 3;
45
+ exports.CODEX_MCP_CONFIG_BLOCK = `[mcp_servers.${SERVER_NAME}]
46
+ command = "npx"
47
+ args = ["-y", "--package", "arkts-lsp-proxy@latest", "arkts-lsp-mcp"]
48
+
49
+ [mcp_servers.${SERVER_NAME}.env]
50
+ ARKTS_LSP_SYNC = "auto"
51
+ `;
52
+ function usage() {
53
+ return `Usage: arkts-lsp-codex-install [--cwd <path>] [--dry-run]
54
+
55
+ Install ArkTS LSP MCP into a Codex project .codex/config.toml.
56
+
57
+ Options:
58
+ --cwd <path> Project directory to install into, or a file inside it.
59
+ --dry-run Print the config path and content without writing files.
60
+ -h, --help Show this help.
61
+ `;
62
+ }
63
+ function parseArgs(argv) {
64
+ const options = {
65
+ startDir: process.cwd(),
66
+ dryRun: false,
67
+ help: false,
68
+ };
69
+ for (let i = 0; i < argv.length; i += 1) {
70
+ const arg = argv[i];
71
+ if (arg === '-h' || arg === '--help') {
72
+ options.help = true;
73
+ continue;
74
+ }
75
+ if (arg === '--dry-run') {
76
+ options.dryRun = true;
77
+ continue;
78
+ }
79
+ if ((arg === '--cwd' || arg === '--project-root') && argv[i + 1]) {
80
+ options.startDir = argv[i + 1];
81
+ i += 1;
82
+ continue;
83
+ }
84
+ if (arg.startsWith('--cwd=')) {
85
+ options.startDir = arg.slice('--cwd='.length);
86
+ continue;
87
+ }
88
+ if (arg.startsWith('--project-root=')) {
89
+ options.startDir = arg.slice('--project-root='.length);
90
+ continue;
91
+ }
92
+ throw new Error(`Unknown argument: ${arg}`);
93
+ }
94
+ return options;
95
+ }
96
+ function isExistingFile(filePath) {
97
+ try {
98
+ return fs.statSync(filePath).isFile();
99
+ }
100
+ catch {
101
+ return false;
102
+ }
103
+ }
104
+ function resolveInstallRoot(startDir) {
105
+ const resolved = path.resolve(startDir);
106
+ return isExistingFile(resolved) ? path.dirname(resolved) : resolved;
107
+ }
108
+ function isArktsServerTable(tableName) {
109
+ return tableName === `mcp_servers.${SERVER_NAME}` || tableName.startsWith(`mcp_servers.${SERVER_NAME}.`);
110
+ }
111
+ function stripExistingArktsServerBlock(existing) {
112
+ const lines = existing.split(/\r?\n/);
113
+ const kept = [];
114
+ let skipping = false;
115
+ for (const line of lines) {
116
+ const header = line.match(/^\s*\[([^\]]+)\]\s*$/);
117
+ if (header) {
118
+ skipping = isArktsServerTable(header[1]);
119
+ }
120
+ if (!skipping) {
121
+ kept.push(line);
122
+ }
123
+ }
124
+ return kept.join('\n').trimEnd();
125
+ }
126
+ function upsertCodexMcpConfig(existing) {
127
+ const withoutOldBlock = stripExistingArktsServerBlock(existing);
128
+ return `${withoutOldBlock ? `${withoutOldBlock}\n\n` : ''}${exports.CODEX_MCP_CONFIG_BLOCK}`;
129
+ }
130
+ function formatTimestamp(date = new Date()) {
131
+ return date.toISOString().replace(/[-:]/g, '').replace(/\.\d{3}Z$/, 'Z');
132
+ }
133
+ function nextBackupPath(configPath) {
134
+ const basePath = `${configPath}.bak-${formatTimestamp()}`;
135
+ let candidate = basePath;
136
+ let suffix = 1;
137
+ while (fs.existsSync(candidate)) {
138
+ candidate = `${basePath}.${suffix}`;
139
+ suffix += 1;
140
+ }
141
+ return candidate;
142
+ }
143
+ function escapeRegExp(value) {
144
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
145
+ }
146
+ function cleanupGeneratedBackups(configPath) {
147
+ const dir = path.dirname(configPath);
148
+ const basename = path.basename(configPath);
149
+ const backupPattern = new RegExp(`^${escapeRegExp(basename)}\\.bak-\\d{8}T\\d{6}Z(?:\\.\\d+)?$`);
150
+ let backups;
151
+ try {
152
+ backups = fs.readdirSync(dir).filter((name) => backupPattern.test(name)).sort();
153
+ }
154
+ catch {
155
+ return;
156
+ }
157
+ const staleBackups = backups.slice(0, Math.max(0, backups.length - MAX_GENERATED_BACKUPS));
158
+ for (const backup of staleBackups) {
159
+ try {
160
+ fs.unlinkSync(path.join(dir, backup));
161
+ }
162
+ catch {
163
+ // Best-effort cleanup only; installation has already preserved the current config.
164
+ }
165
+ }
166
+ }
167
+ function writeFileAtomically(filePath, content) {
168
+ const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
169
+ fs.writeFileSync(tempPath, content, 'utf8');
170
+ fs.renameSync(tempPath, filePath);
171
+ }
172
+ function installCodexProjectConfig(startDir, dryRun = false) {
173
+ const installRoot = resolveInstallRoot(startDir);
174
+ const codexDir = path.join(installRoot, '.codex');
175
+ const configPath = path.join(installRoot, CONFIG_RELATIVE_PATH);
176
+ const hadExistingConfig = fs.existsSync(configPath);
177
+ const existing = hadExistingConfig ? fs.readFileSync(configPath, 'utf8') : '';
178
+ const content = upsertCodexMcpConfig(existing);
179
+ const changed = existing !== content;
180
+ let backupPath;
181
+ if (!dryRun && changed) {
182
+ fs.mkdirSync(codexDir, { recursive: true });
183
+ if (hadExistingConfig) {
184
+ backupPath = nextBackupPath(configPath);
185
+ fs.copyFileSync(configPath, backupPath);
186
+ }
187
+ writeFileAtomically(configPath, content);
188
+ cleanupGeneratedBackups(configPath);
189
+ }
190
+ return {
191
+ installRoot,
192
+ configPath,
193
+ backupPath,
194
+ changed,
195
+ content,
196
+ };
197
+ }
198
+ function main() {
199
+ try {
200
+ const options = parseArgs(process.argv.slice(2));
201
+ if (options.help) {
202
+ process.stdout.write(usage());
203
+ return;
204
+ }
205
+ const result = installCodexProjectConfig(options.startDir, options.dryRun);
206
+ process.stdout.write(`[arkts-lsp] install root: ${result.installRoot}\n`);
207
+ process.stdout.write(`[arkts-lsp] codex config: ${result.configPath}\n`);
208
+ if (result.backupPath) {
209
+ process.stdout.write(`[arkts-lsp] backup: ${result.backupPath}\n`);
210
+ }
211
+ if (options.dryRun) {
212
+ process.stdout.write('\n');
213
+ process.stdout.write(result.content);
214
+ return;
215
+ }
216
+ process.stdout.write(result.changed
217
+ ? '[arkts-lsp] installed project-scoped Codex MCP config\n'
218
+ : '[arkts-lsp] project-scoped Codex MCP config already up to date\n');
219
+ }
220
+ catch (error) {
221
+ const message = error instanceof Error ? error.message : String(error);
222
+ process.stderr.write(`[arkts-lsp] ${message}\n`);
223
+ process.exit(1);
224
+ }
225
+ }
226
+ if (require.main === module) {
227
+ main();
228
+ }
229
+ //# sourceMappingURL=codex-install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-install.js","sourceRoot":"","sources":["../src/codex-install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=mcp-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const mcp_1 = require("./mcp");
5
+ const dispose = (0, mcp_1.startMcpServer)();
6
+ process.on('SIGINT', () => {
7
+ dispose();
8
+ process.exit(0);
9
+ });
10
+ process.on('SIGTERM', () => {
11
+ dispose();
12
+ process.exit(0);
13
+ });
14
+ //# sourceMappingURL=mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":";;;AAEA,+BAAuC;AAEvC,MAAM,OAAO,GAAG,IAAA,oBAAc,GAAE,CAAC;AAEjC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,EAAE,CAAC;IACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACzB,OAAO,EAAE,CAAC;IACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type ArktsDiagnosticsRequest, type ArktsRequest } from './arkts-client';
2
+ import type { ArktsMcpService } from './mcp';
3
+ interface ArktsLspClientLike {
4
+ hover: (request: ArktsRequest) => Promise<unknown>;
5
+ definition: (request: ArktsRequest) => Promise<unknown>;
6
+ references: (request: ArktsRequest) => Promise<unknown>;
7
+ signatureHelp: (request: ArktsRequest) => Promise<unknown>;
8
+ diagnostics: (request: ArktsDiagnosticsRequest) => Promise<unknown[]>;
9
+ dispose: () => void;
10
+ }
11
+ interface ServiceOptions {
12
+ lspClient?: ArktsLspClientLike;
13
+ }
14
+ export declare function createArktsMcpService(options?: ServiceOptions): ArktsMcpService;
15
+ export {};
16
+ //# sourceMappingURL=mcp-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-tools.d.ts","sourceRoot":"","sources":["../src/mcp-tools.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,uBAAuB,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAItG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAE7C,UAAU,kBAAkB;IAC1B,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,UAAU,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,UAAU,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,aAAa,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,WAAW,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACtE,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,UAAU,cAAc;IACtB,SAAS,CAAC,EAAE,kBAAkB,CAAC;CAChC;AAyED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,cAAmB,GAAG,eAAe,CAiEnF"}
@@ -0,0 +1,160 @@
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.createArktsMcpService = createArktsMcpService;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const node_url_1 = require("node:url");
40
+ const arkts_client_1 = require("./arkts-client");
41
+ const env_1 = require("./env");
42
+ const project_1 = require("./project");
43
+ const symbols_1 = require("./symbols");
44
+ function isPlainObject(value) {
45
+ return typeof value === 'object' && value !== null;
46
+ }
47
+ function getString(args, key) {
48
+ return typeof args[key] === 'string' && args[key].length > 0 ? args[key] : undefined;
49
+ }
50
+ function getNumber(args, key) {
51
+ return typeof args[key] === 'number' && Number.isFinite(args[key]) ? args[key] : undefined;
52
+ }
53
+ function uriToFilePath(uri) {
54
+ return uri.startsWith('file://') ? (0, node_url_1.fileURLToPath)(uri) : uri;
55
+ }
56
+ function resolveRoot(rawRoot, rawStart) {
57
+ const candidate = rawRoot ?? rawStart ?? process.cwd();
58
+ const normalized = candidate.startsWith('file://') ? uriToFilePath(candidate) : candidate;
59
+ const resolved = (0, project_1.findProjectRoot)(path.resolve(normalized));
60
+ if (!resolved) {
61
+ throw new Error(`No ArkTS project root found for ${normalized}`);
62
+ }
63
+ return resolved;
64
+ }
65
+ function readText(args) {
66
+ const text = getString(args, 'text');
67
+ if (text !== undefined) {
68
+ return text;
69
+ }
70
+ const rawFile = getString(args, 'filePath') ?? getString(args, 'uri');
71
+ if (!rawFile) {
72
+ throw new Error('Expected either text, filePath, or uri.');
73
+ }
74
+ return fs.readFileSync(uriToFilePath(rawFile), 'utf8');
75
+ }
76
+ function normalizePosition(args) {
77
+ const position = args.position;
78
+ if (isPlainObject(position)) {
79
+ const line = getNumber(position, 'line');
80
+ const character = getNumber(position, 'character');
81
+ if (line !== undefined && character !== undefined) {
82
+ return { line, character };
83
+ }
84
+ }
85
+ const line = getNumber(args, 'line');
86
+ const character = getNumber(args, 'character');
87
+ if (line === undefined || character === undefined) {
88
+ throw new Error('Expected position with line and character.');
89
+ }
90
+ return { line, character };
91
+ }
92
+ function normalizeLspRequest(args) {
93
+ const rawFile = getString(args, 'filePath') ?? getString(args, 'uri');
94
+ if (!rawFile) {
95
+ throw new Error('Expected filePath or uri.');
96
+ }
97
+ return {
98
+ projectRoot: getString(args, 'projectRoot'),
99
+ filePath: uriToFilePath(rawFile),
100
+ position: normalizePosition(args),
101
+ text: getString(args, 'text'),
102
+ };
103
+ }
104
+ function createArktsMcpService(options = {}) {
105
+ const lspClient = options.lspClient ?? new arkts_client_1.ArktsLanguageClient();
106
+ return {
107
+ async projectInfo(rawArgs) {
108
+ const args = isPlainObject(rawArgs) ? rawArgs : {};
109
+ const projectRoot = resolveRoot(getString(args, 'projectRoot'), getString(args, 'startPath'));
110
+ const sdkPath = getString(args, 'sdkPath') ?? (0, env_1.findDevEcoEnv)()?.sdkPath;
111
+ if (!sdkPath) {
112
+ throw new Error('DevEco Studio not found. Pass sdkPath or set DEVECO_HOME.');
113
+ }
114
+ const project = (0, project_1.parseProject)(projectRoot, sdkPath);
115
+ if (!project) {
116
+ throw new Error(`Unable to parse ArkTS project at ${projectRoot}`);
117
+ }
118
+ return project;
119
+ },
120
+ async documentSymbols(rawArgs) {
121
+ const args = isPlainObject(rawArgs) ? rawArgs : {};
122
+ return (0, symbols_1.parseDocumentSymbols)(readText(args));
123
+ },
124
+ async workspaceSymbols(rawArgs) {
125
+ const args = isPlainObject(rawArgs) ? rawArgs : {};
126
+ const query = getString(args, 'query') ?? '';
127
+ const projectRoot = resolveRoot(getString(args, 'projectRoot'), getString(args, 'startPath'));
128
+ return (0, symbols_1.parseWorkspaceSymbols)(projectRoot, query, {
129
+ maxFiles: getNumber(args, 'maxFiles'),
130
+ maxResults: getNumber(args, 'maxResults'),
131
+ });
132
+ },
133
+ async hover(rawArgs) {
134
+ return lspClient.hover(normalizeLspRequest(isPlainObject(rawArgs) ? rawArgs : {}));
135
+ },
136
+ async definition(rawArgs) {
137
+ return lspClient.definition(normalizeLspRequest(isPlainObject(rawArgs) ? rawArgs : {}));
138
+ },
139
+ async references(rawArgs) {
140
+ return lspClient.references(normalizeLspRequest(isPlainObject(rawArgs) ? rawArgs : {}));
141
+ },
142
+ async signatureHelp(rawArgs) {
143
+ return lspClient.signatureHelp(normalizeLspRequest(isPlainObject(rawArgs) ? rawArgs : {}));
144
+ },
145
+ async diagnostics(rawArgs) {
146
+ const args = isPlainObject(rawArgs) ? rawArgs : {};
147
+ const request = normalizeLspRequest(args);
148
+ return lspClient.diagnostics({
149
+ projectRoot: request.projectRoot,
150
+ filePath: request.filePath,
151
+ text: request.text,
152
+ timeoutMs: getNumber(args, 'timeoutMs'),
153
+ });
154
+ },
155
+ dispose() {
156
+ lspClient.dispose();
157
+ },
158
+ };
159
+ }
160
+ //# sourceMappingURL=mcp-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-tools.js","sourceRoot":"","sources":["../src/mcp-tools.ts"],"names":[],"mappings":"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"}
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ type JsonRpcId = string | number | null;
2
+ interface JsonRpcRequest {
3
+ jsonrpc?: string;
4
+ id?: JsonRpcId;
5
+ method?: string;
6
+ params?: unknown;
7
+ }
8
+ interface JsonRpcResponse {
9
+ jsonrpc: '2.0';
10
+ id: JsonRpcId;
11
+ result?: unknown;
12
+ error?: {
13
+ code: number;
14
+ message: string;
15
+ data?: unknown;
16
+ };
17
+ }
18
+ export interface McpTool {
19
+ name: string;
20
+ description: string;
21
+ inputSchema: Record<string, unknown>;
22
+ }
23
+ export interface ArktsMcpService {
24
+ projectInfo: (args: unknown) => Promise<unknown>;
25
+ documentSymbols: (args: unknown) => Promise<unknown>;
26
+ workspaceSymbols: (args: unknown) => Promise<unknown>;
27
+ hover: (args: unknown) => Promise<unknown>;
28
+ definition: (args: unknown) => Promise<unknown>;
29
+ references: (args: unknown) => Promise<unknown>;
30
+ signatureHelp: (args: unknown) => Promise<unknown>;
31
+ diagnostics: (args: unknown) => Promise<unknown>;
32
+ dispose: () => void;
33
+ }
34
+ export declare const ARKTS_MCP_TOOLS: McpTool[];
35
+ export declare function createMcpHandler(service?: ArktsMcpService): (message: JsonRpcRequest) => Promise<JsonRpcResponse | null>;
36
+ export declare function startMcpServer(input?: NodeJS.ReadableStream, output?: NodeJS.WritableStream, service?: ArktsMcpService): () => void;
37
+ export {};
38
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAGA,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAExC,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,SAAS,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,SAAS,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,gBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,UAAU,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,UAAU,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,aAAa,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,WAAW,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAqBD,eAAO,MAAM,eAAe,EAAE,OAAO,EA2FpC,CAAC;AA2CF,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,eAAyC,IAC1C,SAAS,cAAc,KAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAsDjG;AAyBD,wBAAgB,cAAc,CAC5B,KAAK,GAAE,MAAM,CAAC,cAA8B,EAC5C,MAAM,GAAE,MAAM,CAAC,cAA+B,EAC9C,OAAO,GAAE,eAAyC,GACjD,MAAM,IAAI,CAyBZ"}
package/dist/mcp.js ADDED
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ARKTS_MCP_TOOLS = void 0;
4
+ exports.createMcpHandler = createMcpHandler;
5
+ exports.startMcpServer = startMcpServer;
6
+ const node_readline_1 = require("node:readline");
7
+ const mcp_tools_1 = require("./mcp-tools");
8
+ const POSITION_SCHEMA = {
9
+ type: 'object',
10
+ properties: {
11
+ line: { type: 'number', description: 'Zero-based line number.' },
12
+ character: { type: 'number', description: 'Zero-based UTF-16 character offset.' },
13
+ },
14
+ required: ['line', 'character'],
15
+ };
16
+ const LSP_FILE_PROPERTIES = {
17
+ projectRoot: { type: 'string', description: 'HarmonyOS project root. If omitted, the server searches from filePath.' },
18
+ filePath: { type: 'string', description: 'ArkTS/ETS file path.' },
19
+ uri: { type: 'string', description: 'Optional file:// URI alternative to filePath.' },
20
+ text: { type: 'string', description: 'Optional in-memory file text. If omitted, the file is read from disk.' },
21
+ position: POSITION_SCHEMA,
22
+ line: { type: 'number', description: 'Alternative to position.line.' },
23
+ character: { type: 'number', description: 'Alternative to position.character.' },
24
+ };
25
+ exports.ARKTS_MCP_TOOLS = [
26
+ {
27
+ name: 'arkts_project_info',
28
+ description: 'Parse a HarmonyOS ArkTS project and return ace-server initialization metadata.',
29
+ inputSchema: {
30
+ type: 'object',
31
+ properties: {
32
+ projectRoot: { type: 'string', description: 'HarmonyOS project root containing build-profile.json5.' },
33
+ startPath: { type: 'string', description: 'Path used to search upward/downward for build-profile.json5.' },
34
+ sdkPath: { type: 'string', description: 'Optional DevEco SDK path override.' },
35
+ },
36
+ },
37
+ },
38
+ {
39
+ name: 'arkts_document_symbols',
40
+ description: 'Parse ArkTS/ArkUI document symbols from text or a file without starting DevEco.',
41
+ inputSchema: {
42
+ type: 'object',
43
+ properties: {
44
+ text: { type: 'string', description: 'ArkTS/ETS source text.' },
45
+ filePath: { type: 'string', description: 'Source file path.' },
46
+ uri: { type: 'string', description: 'Source file URI.' },
47
+ },
48
+ },
49
+ },
50
+ {
51
+ name: 'arkts_workspace_symbols',
52
+ description: 'Search lightweight ArkTS/ETS workspace symbols under a HarmonyOS project root.',
53
+ inputSchema: {
54
+ type: 'object',
55
+ properties: {
56
+ projectRoot: { type: 'string', description: 'HarmonyOS project root.' },
57
+ startPath: { type: 'string', description: 'Path used to discover the project root.' },
58
+ query: { type: 'string', description: 'Symbol name substring to search for.' },
59
+ maxFiles: { type: 'number', description: 'Optional scan file cap.' },
60
+ maxResults: { type: 'number', description: 'Optional result cap.' },
61
+ },
62
+ required: ['query'],
63
+ },
64
+ },
65
+ {
66
+ name: 'arkts_hover',
67
+ description: 'Ask DevEco ace-server for ArkTS hover/type information at a file position.',
68
+ inputSchema: {
69
+ type: 'object',
70
+ properties: LSP_FILE_PROPERTIES,
71
+ required: ['filePath', 'position'],
72
+ },
73
+ },
74
+ {
75
+ name: 'arkts_definition',
76
+ description: 'Ask DevEco ace-server for ArkTS definition locations at a file position.',
77
+ inputSchema: {
78
+ type: 'object',
79
+ properties: LSP_FILE_PROPERTIES,
80
+ required: ['filePath', 'position'],
81
+ },
82
+ },
83
+ {
84
+ name: 'arkts_references',
85
+ description: 'Ask DevEco ace-server for ArkTS references at a file position.',
86
+ inputSchema: {
87
+ type: 'object',
88
+ properties: LSP_FILE_PROPERTIES,
89
+ required: ['filePath', 'position'],
90
+ },
91
+ },
92
+ {
93
+ name: 'arkts_signature_help',
94
+ description: 'Ask DevEco ace-server for ArkTS signature help at a file position.',
95
+ inputSchema: {
96
+ type: 'object',
97
+ properties: LSP_FILE_PROPERTIES,
98
+ required: ['filePath', 'position'],
99
+ },
100
+ },
101
+ {
102
+ name: 'arkts_diagnostics',
103
+ description: 'Open an ArkTS file through DevEco ace-server and return published diagnostics.',
104
+ inputSchema: {
105
+ type: 'object',
106
+ properties: {
107
+ projectRoot: LSP_FILE_PROPERTIES.projectRoot,
108
+ filePath: LSP_FILE_PROPERTIES.filePath,
109
+ uri: LSP_FILE_PROPERTIES.uri,
110
+ text: LSP_FILE_PROPERTIES.text,
111
+ timeoutMs: { type: 'number', description: 'How long to wait for diagnostics. Default: 1500ms.' },
112
+ },
113
+ required: ['filePath'],
114
+ },
115
+ },
116
+ ];
117
+ function hasId(message) {
118
+ return Object.prototype.hasOwnProperty.call(message, 'id');
119
+ }
120
+ function result(id, value) {
121
+ return { jsonrpc: '2.0', id, result: value };
122
+ }
123
+ function error(id, code, message, data) {
124
+ return {
125
+ jsonrpc: '2.0',
126
+ id,
127
+ error: {
128
+ code,
129
+ message,
130
+ ...(data === undefined ? {} : { data }),
131
+ },
132
+ };
133
+ }
134
+ function isPlainObject(value) {
135
+ return typeof value === 'object' && value !== null;
136
+ }
137
+ function formatToolContent(value) {
138
+ return {
139
+ content: [
140
+ {
141
+ type: 'text',
142
+ text: JSON.stringify(value, null, 2),
143
+ },
144
+ ],
145
+ };
146
+ }
147
+ function getProtocolVersion(params) {
148
+ return isPlainObject(params) && typeof params.protocolVersion === 'string'
149
+ ? params.protocolVersion
150
+ : '2024-11-05';
151
+ }
152
+ function createMcpHandler(service = (0, mcp_tools_1.createArktsMcpService)()) {
153
+ return async function handleMcpRequest(message) {
154
+ if (!message.method) {
155
+ return hasId(message) ? error(message.id ?? null, -32600, 'Invalid Request') : null;
156
+ }
157
+ if (!hasId(message)) {
158
+ return null;
159
+ }
160
+ const id = message.id ?? null;
161
+ try {
162
+ if (message.method === 'initialize') {
163
+ return result(id, {
164
+ protocolVersion: getProtocolVersion(message.params),
165
+ capabilities: {
166
+ tools: {},
167
+ },
168
+ serverInfo: {
169
+ name: 'arkts-lsp-proxy',
170
+ version: '0.1.8',
171
+ },
172
+ });
173
+ }
174
+ if (message.method === 'tools/list') {
175
+ return result(id, { tools: exports.ARKTS_MCP_TOOLS });
176
+ }
177
+ if (message.method === 'tools/call') {
178
+ const params = isPlainObject(message.params) ? message.params : {};
179
+ const name = typeof params.name === 'string' ? params.name : '';
180
+ const args = params.arguments ?? {};
181
+ const handler = getToolHandler(service, name);
182
+ if (!handler) {
183
+ return error(id, -32601, `Unknown tool: ${name}`);
184
+ }
185
+ const value = await handler(args);
186
+ return result(id, formatToolContent(value));
187
+ }
188
+ return error(id, -32601, `Method not found: ${message.method}`);
189
+ }
190
+ catch (err) {
191
+ return result(id, {
192
+ content: [
193
+ {
194
+ type: 'text',
195
+ text: err instanceof Error ? err.message : String(err),
196
+ },
197
+ ],
198
+ isError: true,
199
+ });
200
+ }
201
+ };
202
+ }
203
+ function getToolHandler(service, name) {
204
+ switch (name) {
205
+ case 'arkts_project_info':
206
+ return service.projectInfo;
207
+ case 'arkts_document_symbols':
208
+ return service.documentSymbols;
209
+ case 'arkts_workspace_symbols':
210
+ return service.workspaceSymbols;
211
+ case 'arkts_hover':
212
+ return service.hover;
213
+ case 'arkts_definition':
214
+ return service.definition;
215
+ case 'arkts_references':
216
+ return service.references;
217
+ case 'arkts_signature_help':
218
+ return service.signatureHelp;
219
+ case 'arkts_diagnostics':
220
+ return service.diagnostics;
221
+ default:
222
+ return null;
223
+ }
224
+ }
225
+ function startMcpServer(input = process.stdin, output = process.stdout, service = (0, mcp_tools_1.createArktsMcpService)()) {
226
+ const handler = createMcpHandler(service);
227
+ const rl = (0, node_readline_1.createInterface)({ input });
228
+ rl.on('line', (line) => {
229
+ void (async () => {
230
+ let response;
231
+ try {
232
+ response = await handler(JSON.parse(line));
233
+ }
234
+ catch (err) {
235
+ response = error(null, -32700, 'Parse error', err instanceof Error ? err.message : String(err));
236
+ }
237
+ if (response) {
238
+ output.write(`${JSON.stringify(response)}\n`);
239
+ }
240
+ })();
241
+ });
242
+ const dispose = () => {
243
+ rl.close();
244
+ service.dispose();
245
+ };
246
+ rl.on('close', () => service.dispose());
247
+ return dispose;
248
+ }
249
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":";;;AAkMA,4CAuDC;AAyBD,wCA6BC;AA/SD,iDAAgD;AAChD,2CAAoD;AAwCpD,MAAM,eAAe,GAAG;IACtB,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yBAAyB,EAAE;QAChE,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;KAClF;IACD,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC;CAChC,CAAC;AAEF,MAAM,mBAAmB,GAAG;IAC1B,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wEAAwE,EAAE;IACtH,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE;IACjE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+CAA+C,EAAE;IACrF,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uEAAuE,EAAE;IAC9G,QAAQ,EAAE,eAAe;IACzB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+BAA+B,EAAE;IACtE,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oCAAoC,EAAE;CACjF,CAAC;AAEW,QAAA,eAAe,GAAc;IACxC;QACE,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,gFAAgF;QAC7F,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wDAAwD,EAAE;gBACtG,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8DAA8D,EAAE;gBAC1G,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oCAAoC,EAAE;aAC/E;SACF;KACF;IACD;QACE,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,iFAAiF;QAC9F,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wBAAwB,EAAE;gBAC/D,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mBAAmB,EAAE;gBAC9D,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE;aACzD;SACF;KACF;IACD;QACE,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EAAE,gFAAgF;QAC7F,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yBAAyB,EAAE;gBACvE,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;gBACrF,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sCAAsC,EAAE;gBAC9E,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yBAAyB,EAAE;gBACpE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE;aACpE;YACD,QAAQ,EAAE,CAAC,OAAO,CAAC;SACpB;KACF;IACD;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,4EAA4E;QACzF,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,mBAAmB;YAC/B,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;SACnC;KACF;IACD;QACE,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,0EAA0E;QACvF,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,mBAAmB;YAC/B,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;SACnC;KACF;IACD;QACE,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,gEAAgE;QAC7E,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,mBAAmB;YAC/B,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;SACnC;KACF;IACD;QACE,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,oEAAoE;QACjF,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,mBAAmB;YAC/B,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;SACnC;KACF;IACD;QACE,IAAI,EAAE,mBAAmB;QACzB,WAAW,EAAE,gFAAgF;QAC7F,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,mBAAmB,CAAC,WAAW;gBAC5C,QAAQ,EAAE,mBAAmB,CAAC,QAAQ;gBACtC,GAAG,EAAE,mBAAmB,CAAC,GAAG;gBAC5B,IAAI,EAAE,mBAAmB,CAAC,IAAI;gBAC9B,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oDAAoD,EAAE;aACjG;YACD,QAAQ,EAAE,CAAC,UAAU,CAAC;SACvB;KACF;CACF,CAAC;AAEF,SAAS,KAAK,CAAC,OAAuB;IACpC,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,MAAM,CAAC,EAAa,EAAE,KAAc;IAC3C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC/C,CAAC;AAED,SAAS,KAAK,CAAC,EAAa,EAAE,IAAY,EAAE,OAAe,EAAE,IAAc;IACzE,OAAO;QACL,OAAO,EAAE,KAAK;QACd,EAAE;QACF,KAAK,EAAE;YACL,IAAI;YACJ,OAAO;YACP,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;SACxC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;aACrC;SACF;KACF,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAe;IACzC,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,eAAe,KAAK,QAAQ;QACxE,CAAC,CAAC,MAAM,CAAC,eAAe;QACxB,CAAC,CAAC,YAAY,CAAC;AACnB,CAAC;AAED,SAAgB,gBAAgB,CAAC,UAA2B,IAAA,iCAAqB,GAAE;IACjF,OAAO,KAAK,UAAU,gBAAgB,CAAC,OAAuB;QAC5D,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACtF,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,IAAI,CAAC;QAE9B,IAAI,CAAC;YACH,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;gBACpC,OAAO,MAAM,CAAC,EAAE,EAAE;oBAChB,eAAe,EAAE,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC;oBACnD,YAAY,EAAE;wBACZ,KAAK,EAAE,EAAE;qBACV;oBACD,UAAU,EAAE;wBACV,IAAI,EAAE,iBAAiB;wBACvB,OAAO,EAAE,OAAO;qBACjB;iBACF,CAAC,CAAC;YACL,CAAC;YAED,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;gBACpC,OAAO,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,uBAAe,EAAE,CAAC,CAAC;YAChD,CAAC;YAED,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;gBACpC,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnE,MAAM,IAAI,GAAG,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChE,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;gBACpC,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,iBAAiB,IAAI,EAAE,CAAC,CAAC;gBACpD,CAAC;gBACD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;gBAClC,OAAO,MAAM,CAAC,EAAE,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC9C,CAAC;YAED,OAAO,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,qBAAqB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,MAAM,CAAC,EAAE,EAAE;gBAChB,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;qBACvD;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,OAAwB,EAAE,IAAY;IAC5D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,oBAAoB;YACvB,OAAO,OAAO,CAAC,WAAW,CAAC;QAC7B,KAAK,wBAAwB;YAC3B,OAAO,OAAO,CAAC,eAAe,CAAC;QACjC,KAAK,yBAAyB;YAC5B,OAAO,OAAO,CAAC,gBAAgB,CAAC;QAClC,KAAK,aAAa;YAChB,OAAO,OAAO,CAAC,KAAK,CAAC;QACvB,KAAK,kBAAkB;YACrB,OAAO,OAAO,CAAC,UAAU,CAAC;QAC5B,KAAK,kBAAkB;YACrB,OAAO,OAAO,CAAC,UAAU,CAAC;QAC5B,KAAK,sBAAsB;YACzB,OAAO,OAAO,CAAC,aAAa,CAAC;QAC/B,KAAK,mBAAmB;YACtB,OAAO,OAAO,CAAC,WAAW,CAAC;QAC7B;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAgB,cAAc,CAC5B,QAA+B,OAAO,CAAC,KAAK,EAC5C,SAAgC,OAAO,CAAC,MAAM,EAC9C,UAA2B,IAAA,iCAAqB,GAAE;IAElD,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,EAAE,GAAG,IAAA,+BAAe,EAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAEtC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACrB,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,QAAgC,CAAC;YACrC,IAAI,CAAC;gBACH,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAmB,CAAC,CAAC;YAC/D,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,QAAQ,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAClG,CAAC;YAED,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAChD,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,OAAO,EAAE,CAAC;IACpB,CAAC,CAAC;IACF,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACxC,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "arkts-lsp-proxy",
3
- "version": "0.1.6",
4
- "description": "ArkTS LSP Proxy — bridges DevEco Studio's ace-server to Claude Code",
3
+ "version": "0.1.8",
4
+ "description": "ArkTS LSP Proxy — bridges DevEco Studio's ace-server to Claude Code and project-scoped Codex MCP",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
7
- "arkts-lsp-proxy": "dist/index.js"
7
+ "arkts-lsp-proxy": "dist/index.js",
8
+ "arkts-lsp-mcp": "dist/mcp-server.js",
9
+ "arkts-lsp-codex-install": "dist/codex-install.js"
8
10
  },
9
11
  "scripts": {
10
12
  "build": "tsc",
@@ -22,13 +24,15 @@
22
24
  "lsp",
23
25
  "harmonyos",
24
26
  "deveco",
25
- "claude-code"
27
+ "claude-code",
28
+ "codex",
29
+ "mcp"
26
30
  ],
27
31
  "author": "",
28
32
  "license": "MIT",
29
33
  "repository": {
30
34
  "type": "git",
31
- "url": "https://github.com/HelloiOS2014/harmony_arkts_lsp_proxy.git"
35
+ "url": "git+https://github.com/HelloiOS2014/harmony_arkts_lsp_proxy.git"
32
36
  },
33
37
  "engines": {
34
38
  "node": ">=18"