@4onstudios/iris-agent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +690 -0
- package/dist/api/acp/acpServer.d.ts +23 -0
- package/dist/api/acp/acpServer.js +814 -0
- package/dist/api/acp/index.d.ts +2 -0
- package/dist/api/acp/index.js +2 -0
- package/dist/api/acp/irisClient.d.ts +58 -0
- package/dist/api/acp/irisClient.js +214 -0
- package/dist/api/agent.d.ts +14 -0
- package/dist/api/agent.js +4171 -0
- package/dist/api/backendService.d.ts +4 -0
- package/dist/api/backendService.js +14 -0
- package/dist/api/core/agent/host/AgentContract.d.ts +82 -0
- package/dist/api/core/agent/host/AgentContract.js +1 -0
- package/dist/api/core/agent/host/AgentRegistry.d.ts +24 -0
- package/dist/api/core/agent/host/AgentRegistry.js +125 -0
- package/dist/api/core/agent/host/defaultRegistry.d.ts +15 -0
- package/dist/api/core/agent/host/defaultRegistry.js +46 -0
- package/dist/api/core/agent/host/externalAgentLifecycle.d.ts +65 -0
- package/dist/api/core/agent/host/externalAgentLifecycle.js +117 -0
- package/dist/api/core/agent/host/hostSessionManager.d.ts +111 -0
- package/dist/api/core/agent/host/hostSessionManager.js +352 -0
- package/dist/api/core/agent/host/index.d.ts +5 -0
- package/dist/api/core/agent/host/index.js +5 -0
- package/dist/api/core/agent/index.d.ts +87 -0
- package/dist/api/core/agent/index.js +1024 -0
- package/dist/api/core/agent/publicContracts.d.ts +35 -0
- package/dist/api/core/agent/publicContracts.js +103 -0
- package/dist/api/core/agent/tools/applyDiff.d.ts +51 -0
- package/dist/api/core/agent/tools/applyDiff.js +131 -0
- package/dist/api/core/agent/tools/backgroundTasks.d.ts +240 -0
- package/dist/api/core/agent/tools/backgroundTasks.js +313 -0
- package/dist/api/core/agent/tools/createDirectory.d.ts +43 -0
- package/dist/api/core/agent/tools/createDirectory.js +77 -0
- package/dist/api/core/agent/tools/deleteFile.d.ts +37 -0
- package/dist/api/core/agent/tools/deleteFile.js +66 -0
- package/dist/api/core/agent/tools/editFile.d.ts +73 -0
- package/dist/api/core/agent/tools/editFile.js +173 -0
- package/dist/api/core/agent/tools/executeCommand.d.ts +59 -0
- package/dist/api/core/agent/tools/executeCommand.js +250 -0
- package/dist/api/core/agent/tools/fileContent.d.ts +54 -0
- package/dist/api/core/agent/tools/fileContent.js +227 -0
- package/dist/api/core/agent/tools/findDefinition.d.ts +72 -0
- package/dist/api/core/agent/tools/findDefinition.js +109 -0
- package/dist/api/core/agent/tools/findReferences.d.ts +86 -0
- package/dist/api/core/agent/tools/findReferences.js +135 -0
- package/dist/api/core/agent/tools/formatDocument.d.ts +67 -0
- package/dist/api/core/agent/tools/formatDocument.js +90 -0
- package/dist/api/core/agent/tools/getCodeActions.d.ts +77 -0
- package/dist/api/core/agent/tools/getCodeActions.js +97 -0
- package/dist/api/core/agent/tools/getCodeCompletion.d.ts +77 -0
- package/dist/api/core/agent/tools/getCodeCompletion.js +174 -0
- package/dist/api/core/agent/tools/getCodeContext.d.ts +14 -0
- package/dist/api/core/agent/tools/getCodeContext.js +282 -0
- package/dist/api/core/agent/tools/getSignatureHelp.d.ts +61 -0
- package/dist/api/core/agent/tools/getSignatureHelp.js +85 -0
- package/dist/api/core/agent/tools/getSymbols.d.ts +50 -0
- package/dist/api/core/agent/tools/getSymbols.js +164 -0
- package/dist/api/core/agent/tools/getSymbolsLSP.d.ts +58 -0
- package/dist/api/core/agent/tools/getSymbolsLSP.js +147 -0
- package/dist/api/core/agent/tools/getTypeInfo.d.ts +70 -0
- package/dist/api/core/agent/tools/getTypeInfo.js +84 -0
- package/dist/api/core/agent/tools/getWorkspaceInfo.d.ts +80 -0
- package/dist/api/core/agent/tools/getWorkspaceInfo.js +281 -0
- package/dist/api/core/agent/tools/getWorkspaceSymbols.d.ts +53 -0
- package/dist/api/core/agent/tools/getWorkspaceSymbols.js +97 -0
- package/dist/api/core/agent/tools/grepSearch.d.ts +100 -0
- package/dist/api/core/agent/tools/grepSearch.js +211 -0
- package/dist/api/core/agent/tools/languageModelToolsIntegration.d.ts +13 -0
- package/dist/api/core/agent/tools/languageModelToolsIntegration.js +22 -0
- package/dist/api/core/agent/tools/listDirectory.d.ts +66 -0
- package/dist/api/core/agent/tools/listDirectory.js +161 -0
- package/dist/api/core/agent/tools/mcpTools.d.ts +48 -0
- package/dist/api/core/agent/tools/mcpTools.js +442 -0
- package/dist/api/core/agent/tools/queryKnowledgeGraph.d.ts +120 -0
- package/dist/api/core/agent/tools/queryKnowledgeGraph.js +306 -0
- package/dist/api/core/agent/tools/readFile.d.ts +92 -0
- package/dist/api/core/agent/tools/readFile.js +337 -0
- package/dist/api/core/agent/tools/renameFile.d.ts +49 -0
- package/dist/api/core/agent/tools/renameFile.js +86 -0
- package/dist/api/core/agent/tools/renameSymbol.d.ts +70 -0
- package/dist/api/core/agent/tools/renameSymbol.js +106 -0
- package/dist/api/core/agent/tools/runTerminalCommand.d.ts +72 -0
- package/dist/api/core/agent/tools/runTerminalCommand.js +69 -0
- package/dist/api/core/agent/tools/searchFiles.d.ts +82 -0
- package/dist/api/core/agent/tools/searchFiles.js +280 -0
- package/dist/api/core/agent/tools/terminalAutoApprove.d.ts +3 -0
- package/dist/api/core/agent/tools/terminalAutoApprove.js +676 -0
- package/dist/api/core/agent/tools/treeTraversal.d.ts +60 -0
- package/dist/api/core/agent/tools/treeTraversal.js +217 -0
- package/dist/api/core/agent/tools/webSearch.d.ts +37 -0
- package/dist/api/core/agent/tools/webSearch.js +80 -0
- package/dist/api/core/agent/tools/writeFile.d.ts +59 -0
- package/dist/api/core/agent/tools/writeFile.js +97 -0
- package/dist/api/core/agent/utils/capturedWorkspaceMutationBridge.d.ts +12 -0
- package/dist/api/core/agent/utils/capturedWorkspaceMutationBridge.js +67 -0
- package/dist/api/core/agent/utils/diffUtils.d.ts +14 -0
- package/dist/api/core/agent/utils/diffUtils.js +39 -0
- package/dist/api/core/agent/utils/environmentSnapshot.d.ts +42 -0
- package/dist/api/core/agent/utils/environmentSnapshot.js +213 -0
- package/dist/api/core/agent/utils/errorRecovery.d.ts +49 -0
- package/dist/api/core/agent/utils/errorRecovery.js +229 -0
- package/dist/api/core/agent/utils/multimodalTokenLimiter.d.ts +8 -0
- package/dist/api/core/agent/utils/multimodalTokenLimiter.js +238 -0
- package/dist/api/core/agent/utils/openRouterModelSettings.d.ts +12 -0
- package/dist/api/core/agent/utils/openRouterModelSettings.js +34 -0
- package/dist/api/core/agent/utils/pathRecovery.d.ts +1 -0
- package/dist/api/core/agent/utils/pathRecovery.js +29 -0
- package/dist/api/core/agent/utils/repoMapIndex.d.ts +3 -0
- package/dist/api/core/agent/utils/repoMapIndex.js +197 -0
- package/dist/api/core/agent/utils/skillsDiscovery.d.ts +10 -0
- package/dist/api/core/agent/utils/skillsDiscovery.js +50 -0
- package/dist/api/core/agent/utils/toolCallBudget.d.ts +9 -0
- package/dist/api/core/agent/utils/toolCallBudget.js +55 -0
- package/dist/api/core/agent/utils/toolLifecycle.d.ts +30 -0
- package/dist/api/core/agent/utils/toolLifecycle.js +361 -0
- package/dist/api/core/agent/utils/toolResultSafetyProcessor.d.ts +12 -0
- package/dist/api/core/agent/utils/toolResultSafetyProcessor.js +57 -0
- package/dist/api/core/agent/utils/workspaceMutationBridge.d.ts +13 -0
- package/dist/api/core/agent/utils/workspaceMutationBridge.js +149 -0
- package/dist/api/core/agent/utils/workspacePathGuard.d.ts +7 -0
- package/dist/api/core/agent/utils/workspacePathGuard.js +79 -0
- package/dist/api/core/containers/chat/toolResultSerialization.d.ts +8 -0
- package/dist/api/core/containers/chat/toolResultSerialization.js +71 -0
- package/dist/api/core/library/BrowserManager.d.ts +11 -0
- package/dist/api/core/library/BrowserManager.js +66 -0
- package/dist/api/core/library/desktopWorkspace.d.ts +1 -0
- package/dist/api/core/library/desktopWorkspace.js +3 -0
- package/dist/api/core/library/extensionManager.d.ts +10 -0
- package/dist/api/core/library/extensionManager.js +27 -0
- package/dist/api/core/library/knowledgeGraph.d.ts +268 -0
- package/dist/api/core/library/knowledgeGraph.js +989 -0
- package/dist/api/core/library/languageModelTools.d.ts +141 -0
- package/dist/api/core/library/languageModelTools.js +207 -0
- package/dist/api/core/library/localRuntime.d.ts +23 -0
- package/dist/api/core/library/localRuntime.js +144 -0
- package/dist/api/core/library/lsp/coreLsp.d.ts +367 -0
- package/dist/api/core/library/lsp/coreLsp.js +2076 -0
- package/dist/api/core/library/lsp/protocol.d.ts +25 -0
- package/dist/api/core/library/lsp/protocol.js +1 -0
- package/dist/api/core/library/lsp/serverManager.d.ts +37 -0
- package/dist/api/core/library/lsp/serverManager.js +427 -0
- package/dist/api/core/library/mcpServerProvider.d.ts +69 -0
- package/dist/api/core/library/mcpServerProvider.js +152 -0
- package/dist/api/core/library/mcpSettings.d.ts +20 -0
- package/dist/api/core/library/mcpSettings.js +131 -0
- package/dist/api/core/library/patternMatcher.d.ts +66 -0
- package/dist/api/core/library/patternMatcher.js +284 -0
- package/dist/api/core/library/regexEscape.d.ts +4 -0
- package/dist/api/core/library/regexEscape.js +4 -0
- package/dist/api/core/library/runtimeEventBus.d.ts +27 -0
- package/dist/api/core/library/runtimeEventBus.js +78 -0
- package/dist/api/core/library/safetyMiddleware.d.ts +98 -0
- package/dist/api/core/library/safetyMiddleware.js +215 -0
- package/dist/api/core/library/tauri.d.ts +71 -0
- package/dist/api/core/library/tauri.js +222 -0
- package/dist/api/core/library/tauriImport.d.ts +5 -0
- package/dist/api/core/library/tauriImport.js +7 -0
- package/dist/api/core/library/terminalAutoApproveSettings.d.ts +32 -0
- package/dist/api/core/library/terminalAutoApproveSettings.js +529 -0
- package/dist/api/core/library/workspaceIdentity.d.ts +10 -0
- package/dist/api/core/library/workspaceIdentity.js +49 -0
- package/dist/api/core/library/workspaceSummary.d.ts +19 -0
- package/dist/api/core/library/workspaceSummary.js +35 -0
- package/dist/api/core/skills/agent-customization/SKILL.md +27 -0
- package/dist/api/core/skills/bug-fix/SKILL.md +21 -0
- package/dist/api/core/skills/create-pr/SKILL.md +32 -0
- package/dist/api/core/skills/dev-server/SKILL.md +20 -0
- package/dist/api/core/skills/fix-suggestions/SKILL.md +21 -0
- package/dist/api/core/skills/github-search/SKILL.md +21 -0
- package/dist/api/core/skills/github-summary/SKILL.md +25 -0
- package/dist/api/core/skills/integration-tests/SKILL.md +29 -0
- package/dist/api/core/skills/pr-comments/SKILL.md +23 -0
- package/dist/api/core/skills/project-setup/SKILL.md +20 -0
- package/dist/api/core/skills/search-integration/SKILL.md +19 -0
- package/dist/api/core/skills/search-results/SKILL.md +19 -0
- package/dist/api/core/skills/typescript-upgrade/SKILL.md +21 -0
- package/dist/api/data/runStore.d.ts +46 -0
- package/dist/api/data/runStore.js +244 -0
- package/dist/api/helpers/agentUtils.d.ts +11 -0
- package/dist/api/helpers/agentUtils.js +23 -0
- package/dist/api/helpers/modelTokenLimits.d.ts +2 -0
- package/dist/api/helpers/modelTokenLimits.js +158 -0
- package/dist/api/helpers/observationalMemory.d.ts +10 -0
- package/dist/api/helpers/observationalMemory.js +36 -0
- package/dist/api/helpers/promptBudget.d.ts +30 -0
- package/dist/api/helpers/promptBudget.js +216 -0
- package/dist/api/helpers/resolveImageMessageParts.d.ts +9 -0
- package/dist/api/helpers/resolveImageMessageParts.js +140 -0
- package/dist/api/helpers/slashCommands.d.ts +31 -0
- package/dist/api/helpers/slashCommands.js +129 -0
- package/dist/api/helpers/tokenUsage.d.ts +19 -0
- package/dist/api/helpers/tokenUsage.js +81 -0
- package/dist/api/routes/fileRoutes.d.ts +2 -0
- package/dist/api/routes/fileRoutes.js +108 -0
- package/dist/api/routes/lspDocumentRoutes.d.ts +4 -0
- package/dist/api/routes/lspDocumentRoutes.js +84 -0
- package/dist/api/routes/lspHierarchyRoutes.d.ts +4 -0
- package/dist/api/routes/lspHierarchyRoutes.js +122 -0
- package/dist/api/routes/lspPositionRoutes.d.ts +4 -0
- package/dist/api/routes/lspPositionRoutes.js +263 -0
- package/dist/api/routes/lspQueryRoutes.d.ts +4 -0
- package/dist/api/routes/lspQueryRoutes.js +679 -0
- package/dist/api/routes/lspResolveRoutes.d.ts +4 -0
- package/dist/api/routes/lspResolveRoutes.js +143 -0
- package/dist/api/routes/lspSemanticDocumentRoutes.d.ts +4 -0
- package/dist/api/routes/lspSemanticDocumentRoutes.js +98 -0
- package/dist/api/routes/semanticRoutes.d.ts +2 -0
- package/dist/api/routes/semanticRoutes.js +126 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +160 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +38 -0
- package/package.json +100 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type JsonRpcId = number;
|
|
2
|
+
export type PendingRequestHandlers = {
|
|
3
|
+
resolve: (value: unknown) => void;
|
|
4
|
+
reject: (reason?: unknown) => void;
|
|
5
|
+
};
|
|
6
|
+
export type LspMessage = {
|
|
7
|
+
id?: JsonRpcId;
|
|
8
|
+
method?: string;
|
|
9
|
+
result?: unknown;
|
|
10
|
+
error?: {
|
|
11
|
+
message?: string;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export type LspPosition = {
|
|
15
|
+
line: number;
|
|
16
|
+
character: number;
|
|
17
|
+
};
|
|
18
|
+
export type LspSemanticLegend = {
|
|
19
|
+
tokenTypes: string[];
|
|
20
|
+
tokenModifiers: string[];
|
|
21
|
+
};
|
|
22
|
+
export type LspSemanticTokensResult = {
|
|
23
|
+
resultId?: string;
|
|
24
|
+
data?: number[];
|
|
25
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type ServerLaunchSpec = {
|
|
2
|
+
serverId: string;
|
|
3
|
+
languageId: string;
|
|
4
|
+
version: string;
|
|
5
|
+
source: "workspace" | "approved-registry";
|
|
6
|
+
signatureVerified: boolean;
|
|
7
|
+
sha256: string;
|
|
8
|
+
command: string;
|
|
9
|
+
args: string[];
|
|
10
|
+
cwd?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare class ServerManager {
|
|
13
|
+
private workspaceRoot;
|
|
14
|
+
private serverCacheRoot;
|
|
15
|
+
private inventoryPath;
|
|
16
|
+
private manifestsDir;
|
|
17
|
+
private auditLogPath;
|
|
18
|
+
constructor();
|
|
19
|
+
setWorkspaceRoot(rootPath: string | null): void;
|
|
20
|
+
resolveLaunchSpec(languageId: string): Promise<ServerLaunchSpec | null>;
|
|
21
|
+
recordServerStarted(languageId: string, sha256?: string): Promise<void>;
|
|
22
|
+
recordServerStopped(languageId: string, sha256?: string): Promise<void>;
|
|
23
|
+
ensureOptionalServers(): Promise<void>;
|
|
24
|
+
private getWorkspaceRoot;
|
|
25
|
+
private getWorkspaceId;
|
|
26
|
+
private getPolicy;
|
|
27
|
+
private getLocalBinaryPath;
|
|
28
|
+
private resolveNodeLanguageServer;
|
|
29
|
+
private resolveSystemServer;
|
|
30
|
+
private resolveSystemBinaryPath;
|
|
31
|
+
private resolveCopilotLanguageServer;
|
|
32
|
+
private writeManifest;
|
|
33
|
+
private readInventory;
|
|
34
|
+
private audit;
|
|
35
|
+
}
|
|
36
|
+
export declare const serverManager: ServerManager;
|
|
37
|
+
export default ServerManager;
|
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
import { existsSync } from "fs";
|
|
2
|
+
import fs from "fs/promises";
|
|
3
|
+
import os from "os";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { createHash } from "crypto";
|
|
6
|
+
import { execFile } from "child_process";
|
|
7
|
+
import { promisify } from "util";
|
|
8
|
+
import { runtimeEventBus } from "../runtimeEventBus.js";
|
|
9
|
+
import { extensionManager } from "../extensionManager.js";
|
|
10
|
+
const execFileAsync = promisify(execFile);
|
|
11
|
+
const AUDIT_EVENT_BUS_TOPIC = "audit:language_server";
|
|
12
|
+
const getHomeCacheRoot = () => path.join(os.homedir(), ".iris", "language-servers");
|
|
13
|
+
const isBundledDesktopRuntime = () => process.env.TAURI_BUNDLED === "1";
|
|
14
|
+
const getApprovedChecksumMap = () => {
|
|
15
|
+
const raw = process.env.IRIS_LSP_APPROVED_SHA256_JSON;
|
|
16
|
+
if (!raw) {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const parsed = JSON.parse(raw);
|
|
21
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return {};
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const getSystemServerOverrideMap = () => {
|
|
28
|
+
const raw = process.env.IRIS_LSP_SYSTEM_SERVER_OVERRIDE_JSON;
|
|
29
|
+
if (!raw) {
|
|
30
|
+
return {};
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const parsed = JSON.parse(raw);
|
|
34
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const LANGUAGE_SERVER_POLICIES = {
|
|
41
|
+
python: {
|
|
42
|
+
id: "pyright",
|
|
43
|
+
languageId: "python",
|
|
44
|
+
command: "pyright-langserver",
|
|
45
|
+
args: ["--stdio"],
|
|
46
|
+
version: "1.1.405",
|
|
47
|
+
packageName: "pyright",
|
|
48
|
+
source: "approved-registry",
|
|
49
|
+
},
|
|
50
|
+
typescript: {
|
|
51
|
+
id: "typescript-language-server",
|
|
52
|
+
languageId: "typescript",
|
|
53
|
+
command: "typescript-language-server",
|
|
54
|
+
args: ["--stdio"],
|
|
55
|
+
version: "4.4.0",
|
|
56
|
+
source: "approved-registry",
|
|
57
|
+
},
|
|
58
|
+
javascript: {
|
|
59
|
+
id: "typescript-language-server",
|
|
60
|
+
languageId: "javascript",
|
|
61
|
+
command: "typescript-language-server",
|
|
62
|
+
args: ["--stdio"],
|
|
63
|
+
version: "4.4.0",
|
|
64
|
+
source: "approved-registry",
|
|
65
|
+
},
|
|
66
|
+
go: {
|
|
67
|
+
id: "gopls",
|
|
68
|
+
languageId: "go",
|
|
69
|
+
command: "gopls",
|
|
70
|
+
args: [],
|
|
71
|
+
version: "system",
|
|
72
|
+
source: "approved-registry",
|
|
73
|
+
},
|
|
74
|
+
rust: {
|
|
75
|
+
id: "rust-analyzer",
|
|
76
|
+
languageId: "rust",
|
|
77
|
+
command: "rust-analyzer",
|
|
78
|
+
args: [],
|
|
79
|
+
version: "system",
|
|
80
|
+
source: "approved-registry",
|
|
81
|
+
},
|
|
82
|
+
gdscript: {
|
|
83
|
+
id: "godot",
|
|
84
|
+
languageId: "gdscript",
|
|
85
|
+
command: "godot",
|
|
86
|
+
args: ["--headless", "--lsp"],
|
|
87
|
+
version: "system",
|
|
88
|
+
source: "approved-registry",
|
|
89
|
+
},
|
|
90
|
+
cpp: {
|
|
91
|
+
id: "clangd",
|
|
92
|
+
languageId: "cpp",
|
|
93
|
+
command: "clangd",
|
|
94
|
+
args: ["--background-index"],
|
|
95
|
+
version: "system",
|
|
96
|
+
source: "approved-registry",
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
const ensureDirectory = async (dirPath) => {
|
|
100
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
101
|
+
};
|
|
102
|
+
const sha256File = async (filePath) => {
|
|
103
|
+
const fileBuffer = await fs.readFile(filePath);
|
|
104
|
+
return createHash("sha256").update(fileBuffer).digest("hex");
|
|
105
|
+
};
|
|
106
|
+
export class ServerManager {
|
|
107
|
+
workspaceRoot = null;
|
|
108
|
+
serverCacheRoot;
|
|
109
|
+
inventoryPath;
|
|
110
|
+
manifestsDir;
|
|
111
|
+
auditLogPath;
|
|
112
|
+
constructor() {
|
|
113
|
+
this.serverCacheRoot = getHomeCacheRoot();
|
|
114
|
+
this.inventoryPath = path.join(this.serverCacheRoot, "inventory.json");
|
|
115
|
+
this.manifestsDir = path.join(this.serverCacheRoot, "manifests");
|
|
116
|
+
this.auditLogPath = path.join(this.serverCacheRoot, "audit.log");
|
|
117
|
+
}
|
|
118
|
+
setWorkspaceRoot(rootPath) {
|
|
119
|
+
this.workspaceRoot = rootPath;
|
|
120
|
+
if (extensionManager.isCopilotLanguageServerEnabled()) {
|
|
121
|
+
void this.ensureOptionalServers();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async resolveLaunchSpec(languageId) {
|
|
125
|
+
const policy = this.getPolicy(languageId);
|
|
126
|
+
if (!policy) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
switch (languageId) {
|
|
130
|
+
case "typescript":
|
|
131
|
+
case "typescriptreact":
|
|
132
|
+
case "javascript":
|
|
133
|
+
case "javascriptreact":
|
|
134
|
+
case "python":
|
|
135
|
+
return this.resolveNodeLanguageServer(policy);
|
|
136
|
+
case "go":
|
|
137
|
+
case "cpp":
|
|
138
|
+
case "c":
|
|
139
|
+
case "objc":
|
|
140
|
+
case "objcpp":
|
|
141
|
+
case "rust":
|
|
142
|
+
case "gdscript":
|
|
143
|
+
return this.resolveSystemServer(policy);
|
|
144
|
+
default:
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async recordServerStarted(languageId, sha256 = "unknown") {
|
|
149
|
+
const policy = this.getPolicy(languageId);
|
|
150
|
+
if (!policy) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
await this.audit("language_server_started", {
|
|
154
|
+
language: policy.languageId,
|
|
155
|
+
server_id: policy.id,
|
|
156
|
+
server_version: policy.version,
|
|
157
|
+
sha256,
|
|
158
|
+
outcome: "success",
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
async recordServerStopped(languageId, sha256 = "unknown") {
|
|
162
|
+
const policy = this.getPolicy(languageId);
|
|
163
|
+
if (!policy) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
await this.audit("language_server_stopped", {
|
|
167
|
+
language: policy.languageId,
|
|
168
|
+
server_id: policy.id,
|
|
169
|
+
server_version: policy.version,
|
|
170
|
+
sha256,
|
|
171
|
+
outcome: "success",
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
async ensureOptionalServers() {
|
|
175
|
+
if (!extensionManager.isCopilotLanguageServerEnabled()) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
try {
|
|
179
|
+
await this.resolveCopilotLanguageServer();
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
console.warn("Failed to prepare Copilot language server:", error);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
getWorkspaceRoot() {
|
|
186
|
+
return this.workspaceRoot || process.cwd();
|
|
187
|
+
}
|
|
188
|
+
getWorkspaceId() {
|
|
189
|
+
return this.getWorkspaceRoot();
|
|
190
|
+
}
|
|
191
|
+
getPolicy(languageId) {
|
|
192
|
+
if (languageId === "typescriptreact") {
|
|
193
|
+
return LANGUAGE_SERVER_POLICIES.typescript;
|
|
194
|
+
}
|
|
195
|
+
if (languageId === "javascriptreact") {
|
|
196
|
+
return LANGUAGE_SERVER_POLICIES.javascript;
|
|
197
|
+
}
|
|
198
|
+
if (languageId === "c" || languageId === "objc" || languageId === "objcpp") {
|
|
199
|
+
return LANGUAGE_SERVER_POLICIES.cpp;
|
|
200
|
+
}
|
|
201
|
+
return LANGUAGE_SERVER_POLICIES[languageId] || null;
|
|
202
|
+
}
|
|
203
|
+
getLocalBinaryPath(binaryName) {
|
|
204
|
+
const binDir = path.join(this.getWorkspaceRoot(), "node_modules", ".bin");
|
|
205
|
+
if (process.platform === "win32") {
|
|
206
|
+
for (const ext of [".cmd", ".exe", ""]) {
|
|
207
|
+
const candidate = path.join(binDir, `${binaryName}${ext}`);
|
|
208
|
+
if (existsSync(candidate)) {
|
|
209
|
+
return candidate;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return path.join(binDir, `${binaryName}.cmd`);
|
|
213
|
+
}
|
|
214
|
+
return path.join(binDir, binaryName);
|
|
215
|
+
}
|
|
216
|
+
async resolveNodeLanguageServer(policy) {
|
|
217
|
+
const packageName = policy.packageName || policy.id;
|
|
218
|
+
const localBinaryPath = this.getLocalBinaryPath(policy.command);
|
|
219
|
+
if (existsSync(localBinaryPath)) {
|
|
220
|
+
const checksum = await sha256File(localBinaryPath);
|
|
221
|
+
await this.writeManifest({
|
|
222
|
+
id: policy.id,
|
|
223
|
+
language: policy.languageId,
|
|
224
|
+
version: policy.version,
|
|
225
|
+
command: localBinaryPath,
|
|
226
|
+
sha256: checksum,
|
|
227
|
+
source: policy.source,
|
|
228
|
+
installed_at: new Date().toISOString(),
|
|
229
|
+
signature_verified: true,
|
|
230
|
+
});
|
|
231
|
+
await this.audit("language_server_signature_verified", {
|
|
232
|
+
language: policy.languageId,
|
|
233
|
+
server_id: policy.id,
|
|
234
|
+
server_version: policy.version,
|
|
235
|
+
sha256: checksum,
|
|
236
|
+
outcome: "success",
|
|
237
|
+
});
|
|
238
|
+
return {
|
|
239
|
+
serverId: policy.id,
|
|
240
|
+
languageId: policy.languageId,
|
|
241
|
+
version: policy.version,
|
|
242
|
+
source: "workspace",
|
|
243
|
+
signatureVerified: true,
|
|
244
|
+
sha256: checksum,
|
|
245
|
+
command: localBinaryPath,
|
|
246
|
+
args: policy.args,
|
|
247
|
+
cwd: this.getWorkspaceRoot(),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
if (isBundledDesktopRuntime()) {
|
|
251
|
+
const details = `Missing workspace binary '${policy.command}' for ${policy.languageId} in bundled desktop mode; ` +
|
|
252
|
+
"npx fallback is disabled";
|
|
253
|
+
await this.audit("language_server_install_failed", {
|
|
254
|
+
language: policy.languageId,
|
|
255
|
+
server_id: policy.id,
|
|
256
|
+
server_version: policy.version,
|
|
257
|
+
sha256: "missing-workspace-binary",
|
|
258
|
+
outcome: "failure",
|
|
259
|
+
details,
|
|
260
|
+
});
|
|
261
|
+
throw new Error(`Missing workspace dependency '${policy.command}'. Install '${packageName}@${policy.version}' in this workspace to enable ${policy.languageId} LSP in desktop mode.`);
|
|
262
|
+
}
|
|
263
|
+
await this.audit("language_server_install_requested", {
|
|
264
|
+
language: policy.languageId,
|
|
265
|
+
server_id: policy.id,
|
|
266
|
+
server_version: policy.version,
|
|
267
|
+
sha256: "npm",
|
|
268
|
+
outcome: "success",
|
|
269
|
+
});
|
|
270
|
+
await this.writeManifest({
|
|
271
|
+
id: policy.id,
|
|
272
|
+
language: policy.languageId,
|
|
273
|
+
version: policy.version,
|
|
274
|
+
command: policy.command,
|
|
275
|
+
sha256: "npm-integrity",
|
|
276
|
+
source: policy.source,
|
|
277
|
+
installed_at: new Date().toISOString(),
|
|
278
|
+
signature_verified: true,
|
|
279
|
+
});
|
|
280
|
+
await this.audit("language_server_signature_verified", {
|
|
281
|
+
language: policy.languageId,
|
|
282
|
+
server_id: policy.id,
|
|
283
|
+
server_version: policy.version,
|
|
284
|
+
sha256: "npm-integrity",
|
|
285
|
+
outcome: "success",
|
|
286
|
+
details: "npm package integrity is delegated to npm registry and client verification",
|
|
287
|
+
});
|
|
288
|
+
await this.audit("language_server_installed", {
|
|
289
|
+
language: policy.languageId,
|
|
290
|
+
server_id: policy.id,
|
|
291
|
+
server_version: policy.version,
|
|
292
|
+
sha256: "npm-integrity",
|
|
293
|
+
outcome: "success",
|
|
294
|
+
});
|
|
295
|
+
return {
|
|
296
|
+
serverId: policy.id,
|
|
297
|
+
languageId: policy.languageId,
|
|
298
|
+
version: policy.version,
|
|
299
|
+
source: policy.source,
|
|
300
|
+
signatureVerified: true,
|
|
301
|
+
sha256: "npm-integrity",
|
|
302
|
+
command: "npx",
|
|
303
|
+
args: ["-y", "-p", `${packageName}@${policy.version}`, policy.command, ...policy.args],
|
|
304
|
+
cwd: this.getWorkspaceRoot(),
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
async resolveSystemServer(policy) {
|
|
308
|
+
const approvedHashes = getApprovedChecksumMap();
|
|
309
|
+
const binaryPath = await this.resolveSystemBinaryPath(policy);
|
|
310
|
+
const checksum = await sha256File(binaryPath);
|
|
311
|
+
const approvedHash = approvedHashes[policy.id] || approvedHashes[policy.languageId];
|
|
312
|
+
if (!approvedHash || approvedHash !== checksum) {
|
|
313
|
+
await this.audit("language_server_signature_failed", {
|
|
314
|
+
language: policy.languageId,
|
|
315
|
+
server_id: policy.id,
|
|
316
|
+
server_version: policy.version,
|
|
317
|
+
sha256: checksum,
|
|
318
|
+
outcome: "failure",
|
|
319
|
+
details: approvedHash
|
|
320
|
+
? `checksum mismatch for ${policy.id}`
|
|
321
|
+
: `missing approved checksum for ${policy.id}`,
|
|
322
|
+
});
|
|
323
|
+
throw new Error(approvedHash
|
|
324
|
+
? `Checksum verification failed for ${policy.id}`
|
|
325
|
+
: `Approved checksum not configured for ${policy.id}`);
|
|
326
|
+
}
|
|
327
|
+
await this.writeManifest({
|
|
328
|
+
id: policy.id,
|
|
329
|
+
language: policy.languageId,
|
|
330
|
+
version: policy.version,
|
|
331
|
+
command: binaryPath,
|
|
332
|
+
sha256: checksum,
|
|
333
|
+
source: policy.source,
|
|
334
|
+
installed_at: new Date().toISOString(),
|
|
335
|
+
signature_verified: true,
|
|
336
|
+
});
|
|
337
|
+
await this.audit("language_server_signature_verified", {
|
|
338
|
+
language: policy.languageId,
|
|
339
|
+
server_id: policy.id,
|
|
340
|
+
server_version: policy.version,
|
|
341
|
+
sha256: checksum,
|
|
342
|
+
outcome: "success",
|
|
343
|
+
details: "system binary launch requires explicit allowlist entry",
|
|
344
|
+
});
|
|
345
|
+
return {
|
|
346
|
+
serverId: policy.id,
|
|
347
|
+
languageId: policy.languageId,
|
|
348
|
+
version: policy.version,
|
|
349
|
+
source: policy.source,
|
|
350
|
+
signatureVerified: true,
|
|
351
|
+
sha256: checksum,
|
|
352
|
+
command: binaryPath,
|
|
353
|
+
args: policy.args,
|
|
354
|
+
cwd: this.getWorkspaceRoot(),
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
async resolveSystemBinaryPath(policy) {
|
|
358
|
+
const overrideMap = getSystemServerOverrideMap();
|
|
359
|
+
const overridePath = overrideMap[policy.id] || overrideMap[policy.languageId];
|
|
360
|
+
if (overridePath) {
|
|
361
|
+
return path.resolve(overridePath);
|
|
362
|
+
}
|
|
363
|
+
if (path.isAbsolute(policy.command) && existsSync(policy.command)) {
|
|
364
|
+
return policy.command;
|
|
365
|
+
}
|
|
366
|
+
const resolver = process.platform === "win32" ? "where" : "which";
|
|
367
|
+
const result = await execFileAsync(resolver, [policy.command]);
|
|
368
|
+
const firstPath = result.stdout
|
|
369
|
+
.split(/\r?\n/)
|
|
370
|
+
.map((line) => line.trim())
|
|
371
|
+
.find((line) => line.length > 0);
|
|
372
|
+
if (!firstPath) {
|
|
373
|
+
throw new Error(`Unable to resolve system binary path for ${policy.command}`);
|
|
374
|
+
}
|
|
375
|
+
return firstPath;
|
|
376
|
+
}
|
|
377
|
+
async resolveCopilotLanguageServer() {
|
|
378
|
+
const command = this.getLocalBinaryPath("copilot-language-server");
|
|
379
|
+
const checksum = existsSync(command) ? await sha256File(command) : "disabled";
|
|
380
|
+
return {
|
|
381
|
+
serverId: "copilot-language-server",
|
|
382
|
+
languageId: "copilot",
|
|
383
|
+
version: "workspace",
|
|
384
|
+
source: "workspace",
|
|
385
|
+
signatureVerified: existsSync(command),
|
|
386
|
+
sha256: checksum,
|
|
387
|
+
command: existsSync(command) ? command : "npx",
|
|
388
|
+
args: existsSync(command)
|
|
389
|
+
? ["--stdio"]
|
|
390
|
+
: ["-y", "-p", "@github/copilot-language-server", "copilot-language-server", "--stdio"],
|
|
391
|
+
cwd: this.getWorkspaceRoot(),
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
async writeManifest(manifest) {
|
|
395
|
+
await ensureDirectory(this.manifestsDir);
|
|
396
|
+
const manifestPath = path.join(this.manifestsDir, `${manifest.id}-${manifest.language}.json`);
|
|
397
|
+
await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2), "utf8");
|
|
398
|
+
const inventory = await this.readInventory();
|
|
399
|
+
const key = `${manifest.id}:${manifest.language}`;
|
|
400
|
+
inventory[key] = manifest;
|
|
401
|
+
await fs.writeFile(this.inventoryPath, JSON.stringify(inventory, null, 2), "utf8");
|
|
402
|
+
}
|
|
403
|
+
async readInventory() {
|
|
404
|
+
try {
|
|
405
|
+
const raw = await fs.readFile(this.inventoryPath, "utf8");
|
|
406
|
+
const parsed = JSON.parse(raw);
|
|
407
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
408
|
+
}
|
|
409
|
+
catch {
|
|
410
|
+
return {};
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
async audit(eventName, payload) {
|
|
414
|
+
const event = {
|
|
415
|
+
event_name: eventName,
|
|
416
|
+
occurred_at: new Date().toISOString(),
|
|
417
|
+
actor_type: "system",
|
|
418
|
+
workspace_id: this.getWorkspaceId(),
|
|
419
|
+
...payload,
|
|
420
|
+
};
|
|
421
|
+
await ensureDirectory(this.serverCacheRoot);
|
|
422
|
+
await fs.appendFile(this.auditLogPath, `${JSON.stringify(event)}\n`, "utf8");
|
|
423
|
+
runtimeEventBus.emit(AUDIT_EVENT_BUS_TOPIC, event);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
export const serverManager = new ServerManager();
|
|
427
|
+
export default ServerManager;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server Definition Provider
|
|
3
|
+
* Provides MCP servers from application settings
|
|
4
|
+
*/
|
|
5
|
+
import type { McpServerConfig } from "./mcpSettings.js";
|
|
6
|
+
import type { McpServerDefinitionProvider } from "./languageModelTools.js";
|
|
7
|
+
import { EventEmitter } from "events";
|
|
8
|
+
/**
|
|
9
|
+
* Default MCP Server Provider
|
|
10
|
+
* Provides servers from application settings/configuration
|
|
11
|
+
*/
|
|
12
|
+
export declare class DefaultMcpServerProvider extends EventEmitter implements McpServerDefinitionProvider {
|
|
13
|
+
private servers;
|
|
14
|
+
private changeListeners;
|
|
15
|
+
constructor(servers?: McpServerConfig[]);
|
|
16
|
+
/**
|
|
17
|
+
* Update the list of available servers
|
|
18
|
+
*/
|
|
19
|
+
updateServers(servers: McpServerConfig[]): void;
|
|
20
|
+
/**
|
|
21
|
+
* Provide available MCP servers
|
|
22
|
+
*/
|
|
23
|
+
provideMcpServerDefinitions(signal?: AbortSignal): Promise<McpServerConfig[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Optional: resolve server before starting
|
|
26
|
+
* Can be used for authentication, validation, etc.
|
|
27
|
+
*/
|
|
28
|
+
resolveMcpServerDefinition(server: McpServerConfig, signal?: AbortSignal): Promise<McpServerConfig>;
|
|
29
|
+
/**
|
|
30
|
+
* Listen for server changes
|
|
31
|
+
*/
|
|
32
|
+
onDidChangeMcpServerDefinitions(listener: () => void): () => void;
|
|
33
|
+
/**
|
|
34
|
+
* Notify listeners of changes
|
|
35
|
+
*/
|
|
36
|
+
private notifyChange;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Dynamic MCP Server Provider
|
|
40
|
+
* Can discover servers from various sources
|
|
41
|
+
*/
|
|
42
|
+
export declare class DynamicMcpServerProvider extends EventEmitter implements McpServerDefinitionProvider {
|
|
43
|
+
private discoveryFunctions;
|
|
44
|
+
private changeListeners;
|
|
45
|
+
/**
|
|
46
|
+
* Register a discovery function
|
|
47
|
+
*/
|
|
48
|
+
registerDiscovery(fn: (signal?: AbortSignal) => Promise<McpServerConfig[]>): () => void;
|
|
49
|
+
/**
|
|
50
|
+
* Provide available MCP servers by running all discovery functions
|
|
51
|
+
*/
|
|
52
|
+
provideMcpServerDefinitions(signal?: AbortSignal): Promise<McpServerConfig[]>;
|
|
53
|
+
/**
|
|
54
|
+
* Listen for server changes
|
|
55
|
+
*/
|
|
56
|
+
onDidChangeMcpServerDefinitions(listener: () => void): () => void;
|
|
57
|
+
/**
|
|
58
|
+
* Notify listeners of changes
|
|
59
|
+
*/
|
|
60
|
+
notifyChange(): void;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Create a default provider from static configuration
|
|
64
|
+
*/
|
|
65
|
+
export declare function createDefaultProvider(servers: McpServerConfig[]): DefaultMcpServerProvider;
|
|
66
|
+
/**
|
|
67
|
+
* Create a dynamic provider for runtime discovery
|
|
68
|
+
*/
|
|
69
|
+
export declare function createDynamicProvider(): DynamicMcpServerProvider;
|