@dyyz1993/pi-coding-agent 0.74.24 → 0.74.25
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/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +3 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/extensions/agent-permissions/index.ts +235 -0
- package/dist/extensions/ask-tools/index.ts +115 -0
- package/dist/extensions/auto-memory/contract.d.ts +51 -0
- package/dist/extensions/auto-memory/contract.d.ts.map +1 -0
- package/dist/extensions/auto-memory/contract.js +2 -0
- package/dist/extensions/auto-memory/contract.js.map +1 -0
- package/dist/extensions/auto-memory/contract.ts +56 -0
- package/dist/extensions/auto-memory/index.ts +969 -0
- package/dist/extensions/auto-memory/prompts.ts +202 -0
- package/dist/extensions/auto-memory/skip-rules.ts +297 -0
- package/dist/extensions/auto-memory/utils.ts +208 -0
- package/dist/extensions/auto-session-title/index.ts +83 -0
- package/dist/extensions/bash-ext/contract.d.ts +79 -0
- package/dist/extensions/bash-ext/contract.d.ts.map +1 -0
- package/dist/extensions/bash-ext/contract.js +2 -0
- package/dist/extensions/bash-ext/contract.js.map +1 -0
- package/dist/extensions/bash-ext/contract.ts +69 -0
- package/dist/extensions/bash-ext/index.ts +858 -0
- package/dist/extensions/claude-hooks-compat/config-loader.ts +49 -0
- package/dist/extensions/claude-hooks-compat/handler-runner.ts +377 -0
- package/dist/extensions/claude-hooks-compat/if-parser.ts +53 -0
- package/dist/extensions/claude-hooks-compat/index.ts +178 -0
- package/dist/extensions/claude-hooks-compat/matcher.ts +17 -0
- package/dist/extensions/claude-hooks-compat/stdin-builder.ts +27 -0
- package/dist/extensions/claude-hooks-compat/types.ts +77 -0
- package/dist/extensions/compaction-manager/config.ts +47 -0
- package/dist/extensions/compaction-manager/context-fold.ts +63 -0
- package/dist/extensions/compaction-manager/index.ts +151 -0
- package/dist/extensions/compaction-manager/microcompact.ts +49 -0
- package/dist/extensions/compaction-manager/reactive.ts +9 -0
- package/dist/extensions/compaction-manager/session-memory.ts +48 -0
- package/dist/extensions/coordinator/INTEGRATION.md +376 -0
- package/dist/extensions/coordinator/handler.test.ts +277 -0
- package/dist/extensions/coordinator/handler.ts +189 -0
- package/dist/extensions/coordinator/index.ts +261 -0
- package/dist/extensions/coordinator/types.d.ts +100 -0
- package/dist/extensions/coordinator/types.d.ts.map +1 -0
- package/dist/extensions/coordinator/types.js +2 -0
- package/dist/extensions/coordinator/types.js.map +1 -0
- package/dist/extensions/coordinator/types.ts +72 -0
- package/dist/extensions/file-snapshot/index.ts +131 -0
- package/dist/extensions/file-time-guard/README.md +133 -0
- package/dist/extensions/file-time-guard/config.ts +13 -0
- package/dist/extensions/file-time-guard/index.ts +171 -0
- package/dist/extensions/hooks-engine/index.ts +117 -0
- package/dist/extensions/lsp/lsp/client/file-tracker.ts +70 -0
- package/dist/extensions/lsp/lsp/client/registry.ts +305 -0
- package/dist/extensions/lsp/lsp/client/runtime.ts +832 -0
- package/dist/extensions/lsp/lsp/config/resolver.ts +573 -0
- package/dist/extensions/lsp/lsp/contract.d.ts +101 -0
- package/dist/extensions/lsp/lsp/contract.d.ts.map +1 -0
- package/dist/extensions/lsp/lsp/contract.js +2 -0
- package/dist/extensions/lsp/lsp/contract.js.map +1 -0
- package/dist/extensions/lsp/lsp/contract.ts +103 -0
- package/dist/extensions/lsp/lsp/hooks/agent-end.ts +169 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts +10 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts.map +1 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js +30 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js.map +1 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.ts +41 -0
- package/dist/extensions/lsp/lsp/hooks/writethrough.ts +342 -0
- package/dist/extensions/lsp/lsp/index.ts +307 -0
- package/dist/extensions/lsp/lsp/lsp.test.ts +684 -0
- package/dist/extensions/lsp/lsp/monitoring/server-metrics.ts +176 -0
- package/dist/extensions/lsp/lsp/tools/lsp-tool.ts +402 -0
- package/dist/extensions/lsp/lsp/utils/dependency-resolver.ts +147 -0
- package/dist/extensions/lsp/lsp/utils/diagnostics-wait.ts +41 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts +20 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts.map +1 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.js +64 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.js.map +1 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.ts +76 -0
- package/dist/extensions/message-bridge/GUIDE.md +210 -0
- package/dist/extensions/message-bridge/index.ts +222 -0
- package/dist/extensions/output-guard/index.ts +384 -0
- package/dist/extensions/preview/index.ts +278 -0
- package/dist/extensions/rules-engine/MATCH_HISTORY_RECONCILIATION.md +111 -0
- package/dist/extensions/rules-engine/RULES-ENGINE-GUIDE.md +470 -0
- package/dist/extensions/rules-engine/cache.js +232 -0
- package/dist/extensions/rules-engine/cache.ts +38 -0
- package/dist/extensions/rules-engine/config.js +63 -0
- package/dist/extensions/rules-engine/config.ts +70 -0
- package/dist/extensions/rules-engine/index.js +1530 -0
- package/dist/extensions/rules-engine/index.ts +552 -0
- package/dist/extensions/rules-engine/injector.js +68 -0
- package/dist/extensions/rules-engine/injector.ts +74 -0
- package/dist/extensions/rules-engine/loader.js +179 -0
- package/dist/extensions/rules-engine/loader.ts +205 -0
- package/dist/extensions/rules-engine/matcher.js +534 -0
- package/dist/extensions/rules-engine/matcher.ts +52 -0
- package/dist/extensions/rules-engine/types.d.ts +156 -0
- package/dist/extensions/rules-engine/types.d.ts.map +1 -0
- package/dist/extensions/rules-engine/types.js +2 -0
- package/dist/extensions/rules-engine/types.js.map +1 -0
- package/dist/extensions/rules-engine/types.ts +169 -0
- package/dist/extensions/session-supervisor/checker.ts +116 -0
- package/dist/extensions/session-supervisor/config.ts +45 -0
- package/dist/extensions/session-supervisor/index.ts +726 -0
- package/dist/extensions/session-supervisor/prompts.ts +132 -0
- package/dist/extensions/session-supervisor/scheduler.ts +69 -0
- package/dist/extensions/session-supervisor/types.ts +215 -0
- package/dist/extensions/subagent/README.md +172 -0
- package/dist/extensions/subagent/agents/explorer.md +25 -0
- package/dist/extensions/subagent/agents/guide.md +27 -0
- package/dist/extensions/subagent/agents/planner.md +37 -0
- package/dist/extensions/subagent/agents/reviewer.md +35 -0
- package/dist/extensions/subagent/agents/scout.md +50 -0
- package/dist/extensions/subagent/agents/verification.md +35 -0
- package/dist/extensions/subagent/agents/worker.md +24 -0
- package/dist/extensions/subagent/agents.ts +25 -0
- package/dist/extensions/subagent/index.ts +987 -0
- package/dist/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/dist/extensions/subagent/prompts/implement.md +10 -0
- package/dist/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/dist/extensions/subagent-ext/contract.d.ts +2 -0
- package/dist/extensions/subagent-ext/contract.d.ts.map +1 -0
- package/dist/extensions/subagent-ext/contract.js +2 -0
- package/dist/extensions/subagent-ext/contract.js.map +1 -0
- package/dist/extensions/subagent-ext/contract.ts +1 -0
- package/dist/extensions/subagent-ext/index.ts +347 -0
- package/dist/extensions/subagent-shared/contract.d.ts +25 -0
- package/dist/extensions/subagent-shared/contract.d.ts.map +1 -0
- package/dist/extensions/subagent-shared/contract.js +2 -0
- package/dist/extensions/subagent-shared/contract.js.map +1 -0
- package/dist/extensions/subagent-shared/contract.ts +28 -0
- package/dist/extensions/subagent-shared/index.ts +4 -0
- package/dist/extensions/subagent-shared/render.ts +166 -0
- package/dist/extensions/subagent-shared/types.ts +35 -0
- package/dist/extensions/subagent-shared/utils.ts +112 -0
- package/dist/extensions/subagent-v2/contract.d.ts +2 -0
- package/dist/extensions/subagent-v2/contract.d.ts.map +1 -0
- package/dist/extensions/subagent-v2/contract.js +2 -0
- package/dist/extensions/subagent-v2/contract.js.map +1 -0
- package/dist/extensions/subagent-v2/contract.ts +1 -0
- package/dist/extensions/subagent-v2/index.ts +599 -0
- package/dist/extensions/todo-ext/contract.d.ts +27 -0
- package/dist/extensions/todo-ext/contract.d.ts.map +1 -0
- package/dist/extensions/todo-ext/contract.js +2 -0
- package/dist/extensions/todo-ext/contract.js.map +1 -0
- package/dist/extensions/todo-ext/contract.ts +30 -0
- package/dist/extensions/todo-ext/index.ts +419 -0
- package/package.json +6 -5
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
import { accessSync, constants, existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { delimiter, isAbsolute, join, resolve } from "node:path";
|
|
4
|
+
import { parse as parseYaml } from "yaml";
|
|
5
|
+
|
|
6
|
+
const DEFAULT_SERVER_CANDIDATES: Array<string | string[]> = [
|
|
7
|
+
["typescript-language-server", "--stdio"],
|
|
8
|
+
["vscode-eslint-language-server", "--stdio"],
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
const CONFIG_FILENAMES = ["lsp.json", "lsp.yaml", "lsp.yml"];
|
|
12
|
+
const DEFAULT_SERVER_NAME = "default";
|
|
13
|
+
|
|
14
|
+
interface LspConfigServerFile {
|
|
15
|
+
name?: string;
|
|
16
|
+
command?: string | string[];
|
|
17
|
+
serverCommand?: string | string[];
|
|
18
|
+
server?: string;
|
|
19
|
+
args?: string[];
|
|
20
|
+
fileTypes?: string[];
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface LspConfigFile {
|
|
25
|
+
serverCommand?: string | string[];
|
|
26
|
+
server?: string;
|
|
27
|
+
args?: string[];
|
|
28
|
+
serverCandidates?: string[];
|
|
29
|
+
servers?: Record<string, LspConfigServerFile> | LspConfigServerFile[];
|
|
30
|
+
maxOpenFiles?: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface NormalizedLspServerConfig {
|
|
34
|
+
name: string;
|
|
35
|
+
command?: string[];
|
|
36
|
+
fileTypes?: string[];
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface NormalizedLspConfig {
|
|
41
|
+
serverCommand?: string[];
|
|
42
|
+
serverCandidates?: string[];
|
|
43
|
+
servers?: NormalizedLspServerConfig[];
|
|
44
|
+
maxOpenFiles?: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface ResolvedLspServerConfig {
|
|
48
|
+
name: string;
|
|
49
|
+
command: string[];
|
|
50
|
+
fileTypes?: string[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface ResolvedLspConfig {
|
|
54
|
+
serverCommand: string[] | undefined;
|
|
55
|
+
servers: ResolvedLspServerConfig[];
|
|
56
|
+
maxOpenFiles: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface LspConfigResolver {
|
|
60
|
+
resolve(): ResolvedLspConfig;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface LspConfigResolverOptions {
|
|
64
|
+
cwd?: string;
|
|
65
|
+
homeDir?: string;
|
|
66
|
+
env?: NodeJS.ProcessEnv;
|
|
67
|
+
warn?: (message: string) => void;
|
|
68
|
+
debug?: (message: string) => void;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function createLspConfigResolver(options: LspConfigResolverOptions = {}): LspConfigResolver {
|
|
72
|
+
const cwd = options.cwd ?? process.cwd();
|
|
73
|
+
const homeDir = options.homeDir ?? homedir();
|
|
74
|
+
const env = options.env ?? process.env;
|
|
75
|
+
const warn = options.warn ?? ((message: string) => console.warn(message));
|
|
76
|
+
const debug = options.debug ?? ((message: string) => console.debug(message));
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
resolve(): ResolvedLspConfig {
|
|
80
|
+
const userConfig = loadUserConfig(homeDir, warn);
|
|
81
|
+
const projectConfig = loadConfigFromDir(join(cwd, ".pi"), warn);
|
|
82
|
+
const config = mergeConfig(userConfig, projectConfig);
|
|
83
|
+
const resolvedMaxOpenFiles = config.maxOpenFiles ?? 30;
|
|
84
|
+
|
|
85
|
+
const searchDirs = getSearchDirs(homeDir, env);
|
|
86
|
+
const resolvedServers = resolveServers(config.servers, searchDirs, cwd, homeDir, debug);
|
|
87
|
+
if (resolvedServers.length > 0) {
|
|
88
|
+
return {
|
|
89
|
+
serverCommand: resolvedServers[0]?.command,
|
|
90
|
+
servers: resolvedServers,
|
|
91
|
+
maxOpenFiles: resolvedMaxOpenFiles,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const explicitCommand = resolveCommand(config.serverCommand, searchDirs, cwd, homeDir);
|
|
96
|
+
if (explicitCommand) {
|
|
97
|
+
return {
|
|
98
|
+
serverCommand: explicitCommand,
|
|
99
|
+
servers: [{ name: DEFAULT_SERVER_NAME, command: explicitCommand }],
|
|
100
|
+
maxOpenFiles: resolvedMaxOpenFiles,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const candidates =
|
|
105
|
+
config.serverCandidates && config.serverCandidates.length > 0
|
|
106
|
+
? config.serverCandidates
|
|
107
|
+
: DEFAULT_SERVER_CANDIDATES;
|
|
108
|
+
|
|
109
|
+
const resolvedDefaultServers: NormalizedLspServerConfig[] = [];
|
|
110
|
+
for (const candidate of candidates) {
|
|
111
|
+
const candidateParts = typeof candidate === "string" ? [candidate] : candidate;
|
|
112
|
+
const resolvedCandidate = resolveCommand(candidateParts, searchDirs, cwd, homeDir);
|
|
113
|
+
if (resolvedCandidate) {
|
|
114
|
+
resolvedDefaultServers.push({
|
|
115
|
+
name: candidateParts[0],
|
|
116
|
+
command: resolvedCandidate,
|
|
117
|
+
fileTypes: undefined,
|
|
118
|
+
disabled: undefined,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (resolvedDefaultServers.length > 0) {
|
|
124
|
+
return {
|
|
125
|
+
serverCommand: resolvedDefaultServers[0]?.command,
|
|
126
|
+
servers: resolvedDefaultServers as ResolvedLspServerConfig[],
|
|
127
|
+
maxOpenFiles: resolvedMaxOpenFiles,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
serverCommand: undefined,
|
|
133
|
+
servers: [],
|
|
134
|
+
maxOpenFiles: resolvedMaxOpenFiles,
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function loadUserConfig(homeDir: string, warn: (message: string) => void): NormalizedLspConfig {
|
|
141
|
+
// `~/.pi/agent` is the coding-agent convention. `~/.pi` is supported as a lightweight fallback.
|
|
142
|
+
const userRootConfig = loadConfigFromDir(join(homeDir, ".pi"), warn);
|
|
143
|
+
const userAgentConfig = loadConfigFromDir(join(homeDir, ".pi", "agent"), warn);
|
|
144
|
+
return mergeConfig(userRootConfig, userAgentConfig);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function loadConfigFromDir(baseDir: string, warn: (message: string) => void): NormalizedLspConfig {
|
|
148
|
+
for (const filename of CONFIG_FILENAMES) {
|
|
149
|
+
const filePath = join(baseDir, filename);
|
|
150
|
+
if (!existsSync(filePath)) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const parsed = parseConfigFile(filePath, warn);
|
|
155
|
+
if (parsed) {
|
|
156
|
+
return normalizeConfig(parsed);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return {};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function parseConfigFile(filePath: string, warn: (message: string) => void): LspConfigFile | undefined {
|
|
164
|
+
try {
|
|
165
|
+
const content = readFileSync(filePath, "utf-8");
|
|
166
|
+
const parsed = filePath.endsWith(".json") ? JSON.parse(content) : parseYaml(content);
|
|
167
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
168
|
+
warn(`Ignoring non-object LSP config in ${filePath}`);
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
return parsed as LspConfigFile;
|
|
172
|
+
} catch (error) {
|
|
173
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
174
|
+
warn(`Failed to parse LSP config ${filePath}: ${message}`);
|
|
175
|
+
return undefined;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function normalizeConfig(config: LspConfigFile): NormalizedLspConfig {
|
|
180
|
+
const normalizedServerCommand = normalizeCommand(config.serverCommand) ?? normalizeServerWithArgs(config);
|
|
181
|
+
const normalizedCandidates = normalizeStringList(config.serverCandidates);
|
|
182
|
+
const normalizedServers = normalizeServers(config.servers);
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
serverCommand: normalizedServerCommand,
|
|
186
|
+
serverCandidates: normalizedCandidates,
|
|
187
|
+
servers: normalizedServers,
|
|
188
|
+
maxOpenFiles: typeof config.maxOpenFiles === "number" && config.maxOpenFiles > 0 ? config.maxOpenFiles : undefined,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function normalizeServerWithArgs(config: LspConfigFile): string[] | undefined {
|
|
193
|
+
if (typeof config.server !== "string") {
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const server = config.server.trim();
|
|
198
|
+
if (!server) {
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const args = normalizeStringList(config.args) ?? [];
|
|
203
|
+
return [server, ...args];
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function normalizeCommand(raw: string | string[] | undefined): string[] | undefined {
|
|
207
|
+
if (typeof raw === "string") {
|
|
208
|
+
const normalized = splitCommandString(raw);
|
|
209
|
+
return normalized.length > 0 ? normalized : undefined;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (!Array.isArray(raw)) {
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const normalized = raw.map((part) => (typeof part === "string" ? part.trim() : "")).filter(Boolean);
|
|
217
|
+
return normalized.length > 0 ? normalized : undefined;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function splitCommandString(raw: string): string[] {
|
|
221
|
+
const tokens: string[] = [];
|
|
222
|
+
let current = "";
|
|
223
|
+
let quote: '"' | "'" | undefined;
|
|
224
|
+
let escaped = false;
|
|
225
|
+
|
|
226
|
+
for (let index = 0; index < raw.length; index += 1) {
|
|
227
|
+
const char = raw[index];
|
|
228
|
+
|
|
229
|
+
if (escaped) {
|
|
230
|
+
current += char;
|
|
231
|
+
escaped = false;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (char === "\\" && quote !== "'") {
|
|
236
|
+
escaped = true;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (char === '"' || char === "'") {
|
|
241
|
+
if (!quote) {
|
|
242
|
+
quote = char;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (quote === char) {
|
|
246
|
+
quote = undefined;
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (!quote && /\s/.test(char)) {
|
|
252
|
+
if (current.length > 0) {
|
|
253
|
+
tokens.push(current);
|
|
254
|
+
current = "";
|
|
255
|
+
}
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
current += char;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (escaped) {
|
|
263
|
+
current += "\\";
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (current.length > 0) {
|
|
267
|
+
tokens.push(current);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return tokens;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function normalizeStringList(raw: string[] | undefined): string[] | undefined {
|
|
274
|
+
if (!Array.isArray(raw)) {
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
277
|
+
const normalized = raw.map((value) => (typeof value === "string" ? value.trim() : "")).filter(Boolean);
|
|
278
|
+
return normalized.length > 0 ? normalized : undefined;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function normalizeServers(
|
|
282
|
+
raw: Record<string, LspConfigServerFile> | LspConfigServerFile[] | undefined,
|
|
283
|
+
): NormalizedLspServerConfig[] | undefined {
|
|
284
|
+
if (!raw) {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const normalized: NormalizedLspServerConfig[] = [];
|
|
289
|
+
if (Array.isArray(raw)) {
|
|
290
|
+
for (const [index, server] of raw.entries()) {
|
|
291
|
+
const parsed = normalizeServerEntry(server, undefined, index);
|
|
292
|
+
if (parsed) {
|
|
293
|
+
normalized.push(parsed);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return normalized.length > 0 ? normalized : undefined;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
for (const [name, server] of Object.entries(raw)) {
|
|
300
|
+
const parsed = normalizeServerEntry(server, name, normalized.length);
|
|
301
|
+
if (parsed) {
|
|
302
|
+
normalized.push(parsed);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return normalized.length > 0 ? normalized : undefined;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function normalizeServerEntry(
|
|
309
|
+
server: LspConfigServerFile,
|
|
310
|
+
nameHint: string | undefined,
|
|
311
|
+
index: number,
|
|
312
|
+
): NormalizedLspServerConfig | undefined {
|
|
313
|
+
if (!server || typeof server !== "object" || Array.isArray(server)) {
|
|
314
|
+
return undefined;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const nameCandidate = typeof server.name === "string" ? server.name.trim() : "";
|
|
318
|
+
const name = nameCandidate || nameHint?.trim() || `server-${index + 1}`;
|
|
319
|
+
const command =
|
|
320
|
+
normalizeCommand(server.command) ??
|
|
321
|
+
normalizeCommand(server.serverCommand) ??
|
|
322
|
+
normalizeServerEntryWithArgs(server);
|
|
323
|
+
const fileTypes = normalizeStringList(server.fileTypes);
|
|
324
|
+
|
|
325
|
+
return {
|
|
326
|
+
name,
|
|
327
|
+
command,
|
|
328
|
+
fileTypes,
|
|
329
|
+
disabled: typeof server.disabled === "boolean" ? server.disabled : undefined,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function normalizeServerEntryWithArgs(server: LspConfigServerFile): string[] | undefined {
|
|
334
|
+
if (typeof server.server !== "string") {
|
|
335
|
+
return undefined;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const binary = server.server.trim();
|
|
339
|
+
if (!binary) {
|
|
340
|
+
return undefined;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const args = normalizeStringList(server.args) ?? [];
|
|
344
|
+
return [binary, ...args];
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function mergeConfig(base: NormalizedLspConfig, override: NormalizedLspConfig): NormalizedLspConfig {
|
|
348
|
+
return {
|
|
349
|
+
serverCommand: override.serverCommand ?? base.serverCommand,
|
|
350
|
+
serverCandidates: override.serverCandidates ?? base.serverCandidates,
|
|
351
|
+
servers: mergeServers(base.servers, override.servers),
|
|
352
|
+
maxOpenFiles: override.maxOpenFiles ?? base.maxOpenFiles,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function mergeServers(
|
|
357
|
+
base: NormalizedLspServerConfig[] | undefined,
|
|
358
|
+
override: NormalizedLspServerConfig[] | undefined,
|
|
359
|
+
): NormalizedLspServerConfig[] | undefined {
|
|
360
|
+
if (!base && !override) {
|
|
361
|
+
return undefined;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const merged = base ? [...base] : [];
|
|
365
|
+
if (!override) {
|
|
366
|
+
return merged.length > 0 ? merged : undefined;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
for (const entry of override) {
|
|
370
|
+
const existingIndex = merged.findIndex((candidate) => candidate.name === entry.name);
|
|
371
|
+
if (existingIndex === -1) {
|
|
372
|
+
merged.push(entry);
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const previous = merged[existingIndex];
|
|
377
|
+
merged[existingIndex] = {
|
|
378
|
+
name: entry.name,
|
|
379
|
+
command: entry.command ?? previous.command,
|
|
380
|
+
fileTypes: entry.fileTypes ?? previous.fileTypes,
|
|
381
|
+
disabled: entry.disabled ?? previous.disabled,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return merged.length > 0 ? merged : undefined;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function resolveServers(
|
|
389
|
+
servers: NormalizedLspServerConfig[] | undefined,
|
|
390
|
+
searchDirs: string[],
|
|
391
|
+
cwd: string,
|
|
392
|
+
homeDir: string,
|
|
393
|
+
debug: (message: string) => void,
|
|
394
|
+
): ResolvedLspServerConfig[] {
|
|
395
|
+
if (!servers) {
|
|
396
|
+
return [];
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
debug(`[lsp] Resolving ${servers.length} server(s), searchDirs: ${searchDirs.length}`);
|
|
400
|
+
|
|
401
|
+
const resolved: ResolvedLspServerConfig[] = [];
|
|
402
|
+
for (const server of servers) {
|
|
403
|
+
if (server.disabled === true || !server.command || server.command.length === 0) {
|
|
404
|
+
debug(`[lsp] Skipping server "${server.name}": disabled=${server.disabled}, command=${JSON.stringify(server.command)}`);
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
const command = resolveCommand(server.command, searchDirs, cwd, homeDir);
|
|
409
|
+
if (!command) {
|
|
410
|
+
debug(`[lsp] FAILED to resolve binary "${server.command[0]}" for server "${server.name}" — searched ${searchDirs.length} dirs`);
|
|
411
|
+
continue;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
debug(`[lsp] Resolved server "${server.name}": ${command.join(" ")}`);
|
|
415
|
+
resolved.push({
|
|
416
|
+
name: server.name,
|
|
417
|
+
command,
|
|
418
|
+
fileTypes: server.fileTypes,
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
debug(`[lsp] Resolved ${resolved.length}/${servers.length} server(s)`);
|
|
423
|
+
return resolved;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function getSearchDirs(homeDir: string, env: NodeJS.ProcessEnv): string[] {
|
|
427
|
+
const pathDirs = getPathDirs(env);
|
|
428
|
+
const masonDirs = getMasonDirs(homeDir, env);
|
|
429
|
+
const toolDirs = getCommonToolDirs(homeDir);
|
|
430
|
+
return dedupePaths([...masonDirs, ...toolDirs, ...pathDirs]);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
function getCommonToolDirs(homeDir: string): string[] {
|
|
434
|
+
return [
|
|
435
|
+
join(homeDir, ".cargo", "bin"), // Rust (rustup/rust-analyzer)
|
|
436
|
+
join(homeDir, "go", "bin"), // Go (gopls, etc.)
|
|
437
|
+
join(homeDir, ".local", "bin"), // General user binaries
|
|
438
|
+
join(homeDir, ".gvm", "bin"), // Go Version Manager
|
|
439
|
+
"/usr/local/go/bin", // System Go
|
|
440
|
+
"/usr/local/bin", // System local binaries
|
|
441
|
+
];
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function getPathDirs(env: NodeJS.ProcessEnv): string[] {
|
|
445
|
+
const pathKey = Object.keys(env).find((key) => key.toLowerCase() === "path");
|
|
446
|
+
const pathValue = pathKey ? env[pathKey] : undefined;
|
|
447
|
+
if (!pathValue) {
|
|
448
|
+
return [];
|
|
449
|
+
}
|
|
450
|
+
return pathValue.split(delimiter).filter(Boolean);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function getMasonDirs(homeDir: string, env: NodeJS.ProcessEnv): string[] {
|
|
454
|
+
const dirs = [
|
|
455
|
+
join(homeDir, ".local", "share", "nvim", "mason", "bin"),
|
|
456
|
+
join(homeDir, ".local", "share", "nvim-data", "mason", "bin"),
|
|
457
|
+
];
|
|
458
|
+
|
|
459
|
+
if (env.XDG_DATA_HOME) {
|
|
460
|
+
dirs.push(join(env.XDG_DATA_HOME, "nvim", "mason", "bin"));
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (env.LOCALAPPDATA) {
|
|
464
|
+
dirs.push(join(env.LOCALAPPDATA, "nvim-data", "mason", "bin"));
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return dirs;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function dedupePaths(values: string[]): string[] {
|
|
471
|
+
const seen = new Set<string>();
|
|
472
|
+
const result: string[] = [];
|
|
473
|
+
const isWindows = process.platform === "win32";
|
|
474
|
+
|
|
475
|
+
for (const value of values) {
|
|
476
|
+
const normalized = value.trim();
|
|
477
|
+
if (!normalized) {
|
|
478
|
+
continue;
|
|
479
|
+
}
|
|
480
|
+
const key = isWindows ? normalized.toLowerCase() : normalized;
|
|
481
|
+
if (seen.has(key)) {
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
seen.add(key);
|
|
485
|
+
result.push(normalized);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
return result;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
function resolveCommand(
|
|
492
|
+
command: string[] | undefined,
|
|
493
|
+
searchDirs: string[],
|
|
494
|
+
cwd: string,
|
|
495
|
+
homeDir: string,
|
|
496
|
+
): string[] | undefined {
|
|
497
|
+
if (!command || command.length === 0) {
|
|
498
|
+
return undefined;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
const [binary, ...args] = command;
|
|
502
|
+
const resolvedBinary = resolveBinary(binary, searchDirs, cwd, homeDir);
|
|
503
|
+
if (!resolvedBinary) {
|
|
504
|
+
return undefined;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
return [resolvedBinary, ...args];
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
function resolveBinary(binary: string, searchDirs: string[], cwd: string, homeDir: string): string | undefined {
|
|
511
|
+
const expandedBinary = expandHome(binary, homeDir);
|
|
512
|
+
|
|
513
|
+
if (isPathLike(expandedBinary)) {
|
|
514
|
+
const resolvedPath = isAbsolute(expandedBinary) ? expandedBinary : resolve(cwd, expandedBinary);
|
|
515
|
+
return isExecutable(resolvedPath) ? resolvedPath : undefined;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
for (const directory of searchDirs) {
|
|
519
|
+
for (const candidateName of executableCandidates(binary)) {
|
|
520
|
+
const fullPath = join(directory, candidateName);
|
|
521
|
+
if (isExecutable(fullPath)) {
|
|
522
|
+
return fullPath;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
return undefined;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
function expandHome(value: string, homeDir: string): string {
|
|
531
|
+
if (value === "~") {
|
|
532
|
+
return homeDir;
|
|
533
|
+
}
|
|
534
|
+
if (value.startsWith("~/") || value.startsWith("~\\")) {
|
|
535
|
+
return join(homeDir, value.slice(2));
|
|
536
|
+
}
|
|
537
|
+
return value;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
function isPathLike(value: string): boolean {
|
|
541
|
+
return value.includes("/") || value.includes("\\") || value.startsWith(".");
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
function executableCandidates(binary: string): string[] {
|
|
545
|
+
if (process.platform !== "win32") {
|
|
546
|
+
return [binary];
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
const lowerBinary = binary.toLowerCase();
|
|
550
|
+
const names = [binary];
|
|
551
|
+
if (!lowerBinary.endsWith(".exe")) names.push(`${binary}.exe`);
|
|
552
|
+
if (!lowerBinary.endsWith(".cmd")) names.push(`${binary}.cmd`);
|
|
553
|
+
if (!lowerBinary.endsWith(".bat")) names.push(`${binary}.bat`);
|
|
554
|
+
return names;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
function isExecutable(filePath: string): boolean {
|
|
558
|
+
if (!existsSync(filePath)) {
|
|
559
|
+
return false;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
if (process.platform === "win32") {
|
|
563
|
+
return true;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
try {
|
|
567
|
+
accessSync(filePath, constants.X_OK);
|
|
568
|
+
return true;
|
|
569
|
+
} catch (err) {
|
|
570
|
+
console.debug("[lsp] executable check failed:", err instanceof Error ? err.message : err);
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { ChannelContract } from "@dyyz1993/pi-coding-agent";
|
|
2
|
+
import type { DiagnosticsModeName } from "./hooks/diagnostics-mode.js";
|
|
3
|
+
import type { LspDiagnostic } from "./utils/lsp-helpers.js";
|
|
4
|
+
export declare const LSP_CHANNEL_NAME = "lsp";
|
|
5
|
+
export interface LspServerSummary {
|
|
6
|
+
name: string;
|
|
7
|
+
fileTypes?: string[];
|
|
8
|
+
state: string;
|
|
9
|
+
reason: string;
|
|
10
|
+
transport?: string;
|
|
11
|
+
activeCommand?: string[];
|
|
12
|
+
configuredCommand?: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface LspStatusResult {
|
|
15
|
+
state: string;
|
|
16
|
+
servers: LspServerSummary[];
|
|
17
|
+
mode: DiagnosticsModeName;
|
|
18
|
+
}
|
|
19
|
+
export interface LspSetModeResult {
|
|
20
|
+
ok: boolean;
|
|
21
|
+
mode?: DiagnosticsModeName;
|
|
22
|
+
}
|
|
23
|
+
export interface LspStartupServerEntry {
|
|
24
|
+
name: string;
|
|
25
|
+
state: string;
|
|
26
|
+
fileTypes?: string[];
|
|
27
|
+
}
|
|
28
|
+
export interface LspServerStatusEntry {
|
|
29
|
+
name: string;
|
|
30
|
+
fileTypes?: string[];
|
|
31
|
+
status: {
|
|
32
|
+
state: string;
|
|
33
|
+
reason: string;
|
|
34
|
+
transport?: string;
|
|
35
|
+
activeCommand?: string[];
|
|
36
|
+
configuredCommand?: string[];
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export interface LspChannelContract extends ChannelContract {
|
|
40
|
+
methods: {
|
|
41
|
+
"lsp.setMode": {
|
|
42
|
+
params: {
|
|
43
|
+
mode: string;
|
|
44
|
+
};
|
|
45
|
+
return: LspSetModeResult;
|
|
46
|
+
};
|
|
47
|
+
getActiveLanguages: {
|
|
48
|
+
params: Record<string, never>;
|
|
49
|
+
return: {
|
|
50
|
+
languages: string[];
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
getStatus: {
|
|
54
|
+
params: Record<string, never>;
|
|
55
|
+
return: LspStatusResult;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
events: {
|
|
59
|
+
diagnostics_update: {
|
|
60
|
+
event: "diagnostics_update";
|
|
61
|
+
timestamp: number;
|
|
62
|
+
filePath: string;
|
|
63
|
+
diagnostics: LspDiagnostic[];
|
|
64
|
+
};
|
|
65
|
+
mode_changed: {
|
|
66
|
+
event: "mode_changed";
|
|
67
|
+
timestamp: number;
|
|
68
|
+
mode: DiagnosticsModeName;
|
|
69
|
+
};
|
|
70
|
+
startup_begin: {
|
|
71
|
+
event: "startup_begin";
|
|
72
|
+
timestamp: number;
|
|
73
|
+
servers: LspStartupServerEntry[];
|
|
74
|
+
totalServers: number;
|
|
75
|
+
};
|
|
76
|
+
server_ready: {
|
|
77
|
+
event: "server_ready" | "server_error";
|
|
78
|
+
timestamp: number;
|
|
79
|
+
serverName: string;
|
|
80
|
+
servers: LspServerStatusEntry[];
|
|
81
|
+
};
|
|
82
|
+
language_activated: {
|
|
83
|
+
event: "language_activated";
|
|
84
|
+
timestamp: number;
|
|
85
|
+
serverName: string;
|
|
86
|
+
languages: string[];
|
|
87
|
+
};
|
|
88
|
+
status_changed: {
|
|
89
|
+
event: "status_changed";
|
|
90
|
+
timestamp: number;
|
|
91
|
+
servers: LspServerStatusEntry[];
|
|
92
|
+
state: string;
|
|
93
|
+
};
|
|
94
|
+
startup_complete: {
|
|
95
|
+
event: "startup_complete";
|
|
96
|
+
timestamp: number;
|
|
97
|
+
servers: LspServerStatusEntry[];
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,eAAO,MAAM,gBAAgB,QAAQ,CAAC;AAEtC,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,IAAI,EAAE,mBAAmB,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,mBAAmB,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC7B,CAAC;CACF;AAED,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IAC1D,OAAO,EAAE;QACR,aAAa,EAAE;YACd,MAAM,EAAE;gBAAE,IAAI,EAAE,MAAM,CAAA;aAAE,CAAC;YACzB,MAAM,EAAE,gBAAgB,CAAC;SACzB,CAAC;QACF,kBAAkB,EAAE;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC9B,MAAM,EAAE;gBAAE,SAAS,EAAE,MAAM,EAAE,CAAA;aAAE,CAAC;SAChC,CAAC;QACF,SAAS,EAAE;YACV,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC9B,MAAM,EAAE,eAAe,CAAC;SACxB,CAAC;KACF,CAAC;IACF,MAAM,EAAE;QACP,kBAAkB,EAAE;YACnB,KAAK,EAAE,oBAAoB,CAAC;YAC5B,SAAS,EAAE,MAAM,CAAC;YAClB,QAAQ,EAAE,MAAM,CAAC;YACjB,WAAW,EAAE,aAAa,EAAE,CAAC;SAC7B,CAAC;QACF,YAAY,EAAE;YACb,KAAK,EAAE,cAAc,CAAC;YACtB,SAAS,EAAE,MAAM,CAAC;YAClB,IAAI,EAAE,mBAAmB,CAAC;SAC1B,CAAC;QACF,aAAa,EAAE;YACd,KAAK,EAAE,eAAe,CAAC;YACvB,SAAS,EAAE,MAAM,CAAC;YAClB,OAAO,EAAE,qBAAqB,EAAE,CAAC;YACjC,YAAY,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,YAAY,EAAE;YACb,KAAK,EAAE,cAAc,GAAG,cAAc,CAAC;YACvC,SAAS,EAAE,MAAM,CAAC;YAClB,UAAU,EAAE,MAAM,CAAC;YACnB,OAAO,EAAE,oBAAoB,EAAE,CAAC;SAChC,CAAC;QACF,kBAAkB,EAAE;YACnB,KAAK,EAAE,oBAAoB,CAAC;YAC5B,SAAS,EAAE,MAAM,CAAC;YAClB,UAAU,EAAE,MAAM,CAAC;YACnB,SAAS,EAAE,MAAM,EAAE,CAAC;SACpB,CAAC;QACF,cAAc,EAAE;YACf,KAAK,EAAE,gBAAgB,CAAC;YACxB,SAAS,EAAE,MAAM,CAAC;YAClB,OAAO,EAAE,oBAAoB,EAAE,CAAC;YAChC,KAAK,EAAE,MAAM,CAAC;SACd,CAAC;QACF,gBAAgB,EAAE;YACjB,KAAK,EAAE,kBAAkB,CAAC;YAC1B,SAAS,EAAE,MAAM,CAAC;YAClB,OAAO,EAAE,oBAAoB,EAAE,CAAC;SAChC,CAAC;KACF,CAAC;CACF","sourcesContent":["import type { ChannelContract } from \"@dyyz1993/pi-coding-agent\";\nimport type { DiagnosticsModeName } from \"./hooks/diagnostics-mode.js\";\nimport type { LspDiagnostic } from \"./utils/lsp-helpers.js\";\n\nexport const LSP_CHANNEL_NAME = \"lsp\";\n\nexport interface LspServerSummary {\n\tname: string;\n\tfileTypes?: string[];\n\tstate: string;\n\treason: string;\n\ttransport?: string;\n\tactiveCommand?: string[];\n\tconfiguredCommand?: string[];\n}\n\nexport interface LspStatusResult {\n\tstate: string;\n\tservers: LspServerSummary[];\n\tmode: DiagnosticsModeName;\n}\n\nexport interface LspSetModeResult {\n\tok: boolean;\n\tmode?: DiagnosticsModeName;\n}\n\nexport interface LspStartupServerEntry {\n\tname: string;\n\tstate: string;\n\tfileTypes?: string[];\n}\n\nexport interface LspServerStatusEntry {\n\tname: string;\n\tfileTypes?: string[];\n\tstatus: {\n\t\tstate: string;\n\t\treason: string;\n\t\ttransport?: string;\n\t\tactiveCommand?: string[];\n\t\tconfiguredCommand?: string[];\n\t};\n}\n\nexport interface LspChannelContract extends ChannelContract {\n\tmethods: {\n\t\t\"lsp.setMode\": {\n\t\t\tparams: { mode: string };\n\t\t\treturn: LspSetModeResult;\n\t\t};\n\t\tgetActiveLanguages: {\n\t\t\tparams: Record<string, never>;\n\t\t\treturn: { languages: string[] };\n\t\t};\n\t\tgetStatus: {\n\t\t\tparams: Record<string, never>;\n\t\t\treturn: LspStatusResult;\n\t\t};\n\t};\n\tevents: {\n\t\tdiagnostics_update: {\n\t\t\tevent: \"diagnostics_update\";\n\t\t\ttimestamp: number;\n\t\t\tfilePath: string;\n\t\t\tdiagnostics: LspDiagnostic[];\n\t\t};\n\t\tmode_changed: {\n\t\t\tevent: \"mode_changed\";\n\t\t\ttimestamp: number;\n\t\t\tmode: DiagnosticsModeName;\n\t\t};\n\t\tstartup_begin: {\n\t\t\tevent: \"startup_begin\";\n\t\t\ttimestamp: number;\n\t\t\tservers: LspStartupServerEntry[];\n\t\t\ttotalServers: number;\n\t\t};\n\t\tserver_ready: {\n\t\t\tevent: \"server_ready\" | \"server_error\";\n\t\t\ttimestamp: number;\n\t\t\tserverName: string;\n\t\t\tservers: LspServerStatusEntry[];\n\t\t};\n\t\tlanguage_activated: {\n\t\t\tevent: \"language_activated\";\n\t\t\ttimestamp: number;\n\t\t\tserverName: string;\n\t\t\tlanguages: string[];\n\t\t};\n\t\tstatus_changed: {\n\t\t\tevent: \"status_changed\";\n\t\t\ttimestamp: number;\n\t\t\tservers: LspServerStatusEntry[];\n\t\t\tstate: string;\n\t\t};\n\t\tstartup_complete: {\n\t\t\tevent: \"startup_complete\";\n\t\t\ttimestamp: number;\n\t\t\tservers: LspServerStatusEntry[];\n\t\t};\n\t};\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["contract.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC","sourcesContent":["import type { ChannelContract } from \"@dyyz1993/pi-coding-agent\";\nimport type { DiagnosticsModeName } from \"./hooks/diagnostics-mode.js\";\nimport type { LspDiagnostic } from \"./utils/lsp-helpers.js\";\n\nexport const LSP_CHANNEL_NAME = \"lsp\";\n\nexport interface LspServerSummary {\n\tname: string;\n\tfileTypes?: string[];\n\tstate: string;\n\treason: string;\n\ttransport?: string;\n\tactiveCommand?: string[];\n\tconfiguredCommand?: string[];\n}\n\nexport interface LspStatusResult {\n\tstate: string;\n\tservers: LspServerSummary[];\n\tmode: DiagnosticsModeName;\n}\n\nexport interface LspSetModeResult {\n\tok: boolean;\n\tmode?: DiagnosticsModeName;\n}\n\nexport interface LspStartupServerEntry {\n\tname: string;\n\tstate: string;\n\tfileTypes?: string[];\n}\n\nexport interface LspServerStatusEntry {\n\tname: string;\n\tfileTypes?: string[];\n\tstatus: {\n\t\tstate: string;\n\t\treason: string;\n\t\ttransport?: string;\n\t\tactiveCommand?: string[];\n\t\tconfiguredCommand?: string[];\n\t};\n}\n\nexport interface LspChannelContract extends ChannelContract {\n\tmethods: {\n\t\t\"lsp.setMode\": {\n\t\t\tparams: { mode: string };\n\t\t\treturn: LspSetModeResult;\n\t\t};\n\t\tgetActiveLanguages: {\n\t\t\tparams: Record<string, never>;\n\t\t\treturn: { languages: string[] };\n\t\t};\n\t\tgetStatus: {\n\t\t\tparams: Record<string, never>;\n\t\t\treturn: LspStatusResult;\n\t\t};\n\t};\n\tevents: {\n\t\tdiagnostics_update: {\n\t\t\tevent: \"diagnostics_update\";\n\t\t\ttimestamp: number;\n\t\t\tfilePath: string;\n\t\t\tdiagnostics: LspDiagnostic[];\n\t\t};\n\t\tmode_changed: {\n\t\t\tevent: \"mode_changed\";\n\t\t\ttimestamp: number;\n\t\t\tmode: DiagnosticsModeName;\n\t\t};\n\t\tstartup_begin: {\n\t\t\tevent: \"startup_begin\";\n\t\t\ttimestamp: number;\n\t\t\tservers: LspStartupServerEntry[];\n\t\t\ttotalServers: number;\n\t\t};\n\t\tserver_ready: {\n\t\t\tevent: \"server_ready\" | \"server_error\";\n\t\t\ttimestamp: number;\n\t\t\tserverName: string;\n\t\t\tservers: LspServerStatusEntry[];\n\t\t};\n\t\tlanguage_activated: {\n\t\t\tevent: \"language_activated\";\n\t\t\ttimestamp: number;\n\t\t\tserverName: string;\n\t\t\tlanguages: string[];\n\t\t};\n\t\tstatus_changed: {\n\t\t\tevent: \"status_changed\";\n\t\t\ttimestamp: number;\n\t\t\tservers: LspServerStatusEntry[];\n\t\t\tstate: string;\n\t\t};\n\t\tstartup_complete: {\n\t\t\tevent: \"startup_complete\";\n\t\t\ttimestamp: number;\n\t\t\tservers: LspServerStatusEntry[];\n\t\t};\n\t};\n}\n"]}
|