@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,4 @@
|
|
|
1
|
+
import type { NextFunction, Request, Response, Router } from "express";
|
|
2
|
+
type AuthMiddleware = (req: Request, res: Response, next: NextFunction) => void;
|
|
3
|
+
export declare const registerLspResolveRoutes: (router: Router, requireDesktopAuth: AuthMiddleware) => void;
|
|
4
|
+
export {};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { coreLsp } from "../core/library/lsp/coreLsp.js";
|
|
3
|
+
const resolveAbsolutePath = (workspacePath, filePath) => {
|
|
4
|
+
if (typeof filePath !== "string" || filePath.length === 0) {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
return path.isAbsolute(filePath) ? filePath : path.join(workspacePath, filePath);
|
|
8
|
+
};
|
|
9
|
+
export const registerLspResolveRoutes = (router, requireDesktopAuth) => {
|
|
10
|
+
router.post("/lsp/completion/resolve", requireDesktopAuth, async (req, res) => {
|
|
11
|
+
try {
|
|
12
|
+
const { workspaceRoot, languageId, filePath, item } = req.body;
|
|
13
|
+
if (!item || typeof item !== "object") {
|
|
14
|
+
return res.status(400).json({ success: false, error: "item is required" });
|
|
15
|
+
}
|
|
16
|
+
const workspacePath = workspaceRoot || process.cwd();
|
|
17
|
+
coreLsp.setRootPath(workspacePath);
|
|
18
|
+
const absolutePath = resolveAbsolutePath(workspacePath, filePath);
|
|
19
|
+
const resolved = await coreLsp.resolveCompletionItem(item, typeof languageId === "string" ? languageId : undefined, absolutePath);
|
|
20
|
+
return res.json({ success: true, item: resolved });
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
const err = error;
|
|
24
|
+
return res
|
|
25
|
+
.status(500)
|
|
26
|
+
.json({ success: false, error: err.message || "Failed to resolve completion item" });
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
router.post("/lsp/code-action/resolve", requireDesktopAuth, async (req, res) => {
|
|
30
|
+
try {
|
|
31
|
+
const { workspaceRoot, languageId, filePath, item } = req.body;
|
|
32
|
+
if (!item || typeof item !== "object") {
|
|
33
|
+
return res.status(400).json({ success: false, error: "item is required" });
|
|
34
|
+
}
|
|
35
|
+
const workspacePath = workspaceRoot || process.cwd();
|
|
36
|
+
coreLsp.setRootPath(workspacePath);
|
|
37
|
+
const absolutePath = resolveAbsolutePath(workspacePath, filePath);
|
|
38
|
+
const resolved = await coreLsp.resolveCodeAction(item, typeof languageId === "string" ? languageId : undefined, absolutePath);
|
|
39
|
+
return res.json({ success: true, item: resolved });
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
const err = error;
|
|
43
|
+
return res
|
|
44
|
+
.status(500)
|
|
45
|
+
.json({ success: false, error: err.message || "Failed to resolve code action" });
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
router.post("/lsp/code-lens/resolve", requireDesktopAuth, async (req, res) => {
|
|
49
|
+
try {
|
|
50
|
+
const { workspaceRoot, languageId, filePath, item } = req.body;
|
|
51
|
+
if (!item || typeof item !== "object") {
|
|
52
|
+
return res.status(400).json({ success: false, error: "item is required" });
|
|
53
|
+
}
|
|
54
|
+
const workspacePath = workspaceRoot || process.cwd();
|
|
55
|
+
coreLsp.setRootPath(workspacePath);
|
|
56
|
+
const absolutePath = resolveAbsolutePath(workspacePath, filePath);
|
|
57
|
+
const resolved = await coreLsp.resolveCodeLens(item, typeof languageId === "string" ? languageId : undefined, absolutePath);
|
|
58
|
+
return res.json({ success: true, item: resolved });
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
const err = error;
|
|
62
|
+
return res
|
|
63
|
+
.status(500)
|
|
64
|
+
.json({ success: false, error: err.message || "Failed to resolve code lens" });
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
router.post("/lsp/document-link/resolve", requireDesktopAuth, async (req, res) => {
|
|
68
|
+
try {
|
|
69
|
+
const { workspaceRoot, languageId, filePath, item } = req.body;
|
|
70
|
+
if (!item || typeof item !== "object") {
|
|
71
|
+
return res.status(400).json({ success: false, error: "item is required" });
|
|
72
|
+
}
|
|
73
|
+
const workspacePath = workspaceRoot || process.cwd();
|
|
74
|
+
coreLsp.setRootPath(workspacePath);
|
|
75
|
+
const absolutePath = resolveAbsolutePath(workspacePath, filePath);
|
|
76
|
+
const resolved = await coreLsp.resolveDocumentLink(item, typeof languageId === "string" ? languageId : undefined, absolutePath);
|
|
77
|
+
return res.json({ success: true, item: resolved });
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
const err = error;
|
|
81
|
+
return res
|
|
82
|
+
.status(500)
|
|
83
|
+
.json({ success: false, error: err.message || "Failed to resolve document link" });
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
router.post("/lsp/workspace-symbol/resolve", requireDesktopAuth, async (req, res) => {
|
|
87
|
+
try {
|
|
88
|
+
const { workspaceRoot, languageId, item } = req.body;
|
|
89
|
+
if (!item || typeof item !== "object") {
|
|
90
|
+
return res.status(400).json({ success: false, error: "item is required" });
|
|
91
|
+
}
|
|
92
|
+
const workspacePath = workspaceRoot || process.cwd();
|
|
93
|
+
coreLsp.setRootPath(workspacePath);
|
|
94
|
+
const resolved = await coreLsp.resolveWorkspaceSymbol(item, typeof languageId === "string" ? languageId : undefined);
|
|
95
|
+
return res.json({ success: true, item: resolved });
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
const err = error;
|
|
99
|
+
return res
|
|
100
|
+
.status(500)
|
|
101
|
+
.json({ success: false, error: err.message || "Failed to resolve workspace symbol" });
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
router.post("/lsp/inlay-hint/resolve", requireDesktopAuth, async (req, res) => {
|
|
105
|
+
try {
|
|
106
|
+
const { workspaceRoot, languageId, filePath, item } = req.body;
|
|
107
|
+
if (!item || typeof item !== "object") {
|
|
108
|
+
return res.status(400).json({ success: false, error: "item is required" });
|
|
109
|
+
}
|
|
110
|
+
const workspacePath = workspaceRoot || process.cwd();
|
|
111
|
+
coreLsp.setRootPath(workspacePath);
|
|
112
|
+
const absolutePath = resolveAbsolutePath(workspacePath, filePath);
|
|
113
|
+
const resolved = await coreLsp.resolveInlayHint(item, typeof languageId === "string" ? languageId : undefined, absolutePath);
|
|
114
|
+
return res.json({ success: true, item: resolved });
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
const err = error;
|
|
118
|
+
return res
|
|
119
|
+
.status(500)
|
|
120
|
+
.json({ success: false, error: err.message || "Failed to resolve inlay hint" });
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
router.post("/lsp/inline-completion/resolve", requireDesktopAuth, async (req, res) => {
|
|
124
|
+
try {
|
|
125
|
+
const { workspaceRoot, languageId, filePath, item } = req.body;
|
|
126
|
+
if (!item || typeof item !== "object") {
|
|
127
|
+
return res.status(400).json({ success: false, error: "item is required" });
|
|
128
|
+
}
|
|
129
|
+
const workspacePath = workspaceRoot || process.cwd();
|
|
130
|
+
coreLsp.setRootPath(workspacePath);
|
|
131
|
+
const absolutePath = resolveAbsolutePath(workspacePath, filePath);
|
|
132
|
+
const resolved = await coreLsp.resolveInlineCompletionItem(item, typeof languageId === "string" ? languageId : undefined, absolutePath);
|
|
133
|
+
return res.json({ success: true, item: resolved });
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
const err = error;
|
|
137
|
+
return res.status(500).json({
|
|
138
|
+
success: false,
|
|
139
|
+
error: err.message || "Failed to resolve inline completion item",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { NextFunction, Request, Response, Router } from "express";
|
|
2
|
+
type AuthMiddleware = (req: Request, res: Response, next: NextFunction) => void;
|
|
3
|
+
export declare const registerLspSemanticDocumentRoutes: (router: Router, requireDesktopAuth: AuthMiddleware) => void;
|
|
4
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { coreLsp } from "../core/library/lsp/coreLsp.js";
|
|
3
|
+
const resolveAbsolutePath = (workspacePath, filePath) => path.isAbsolute(filePath) ? filePath : path.join(workspacePath, filePath);
|
|
4
|
+
export const registerLspSemanticDocumentRoutes = (router, requireDesktopAuth) => {
|
|
5
|
+
router.post("/lsp/semantic-tokens-range", requireDesktopAuth, async (req, res) => {
|
|
6
|
+
try {
|
|
7
|
+
const { filePath, workspaceRoot, startLine, startCharacter, endLine, endCharacter, } = req.body;
|
|
8
|
+
if (typeof filePath !== "string" || filePath.trim().length === 0) {
|
|
9
|
+
return res.status(400).json({ success: false, error: "filePath is required" });
|
|
10
|
+
}
|
|
11
|
+
if (typeof startLine !== "number" ||
|
|
12
|
+
typeof startCharacter !== "number" ||
|
|
13
|
+
typeof endLine !== "number" ||
|
|
14
|
+
typeof endCharacter !== "number") {
|
|
15
|
+
return res.status(400).json({
|
|
16
|
+
success: false,
|
|
17
|
+
error: "startLine, startCharacter, endLine, and endCharacter are required",
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
const workspacePath = workspaceRoot || process.cwd();
|
|
21
|
+
const absolutePath = resolveAbsolutePath(workspacePath, filePath);
|
|
22
|
+
coreLsp.setRootPath(workspacePath);
|
|
23
|
+
const semanticTokens = await coreLsp.getSemanticTokensRange(absolutePath, startLine, startCharacter, endLine, endCharacter);
|
|
24
|
+
if (!semanticTokens) {
|
|
25
|
+
return res.json({ success: false, error: "No semantic tokens available" });
|
|
26
|
+
}
|
|
27
|
+
return res.json({
|
|
28
|
+
success: true,
|
|
29
|
+
data: semanticTokens.data,
|
|
30
|
+
legend: semanticTokens.legend,
|
|
31
|
+
languageId: semanticTokens.languageId,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const err = error;
|
|
36
|
+
return res
|
|
37
|
+
.status(500)
|
|
38
|
+
.json({ success: false, error: err.message || "Failed to get semantic tokens" });
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
router.post("/lsp/semantic-tokens-full", requireDesktopAuth, async (req, res) => {
|
|
42
|
+
try {
|
|
43
|
+
const { filePath, workspaceRoot } = req.body;
|
|
44
|
+
if (typeof filePath !== "string" || filePath.trim().length === 0) {
|
|
45
|
+
return res.status(400).json({ success: false, error: "filePath is required" });
|
|
46
|
+
}
|
|
47
|
+
const workspacePath = workspaceRoot || process.cwd();
|
|
48
|
+
const absolutePath = resolveAbsolutePath(workspacePath, filePath);
|
|
49
|
+
coreLsp.setRootPath(workspacePath);
|
|
50
|
+
const semanticTokens = await coreLsp.getSemanticTokensFull(absolutePath);
|
|
51
|
+
if (!semanticTokens) {
|
|
52
|
+
return res.json({ success: false, error: "No semantic tokens available" });
|
|
53
|
+
}
|
|
54
|
+
return res.json({
|
|
55
|
+
success: true,
|
|
56
|
+
data: semanticTokens.data,
|
|
57
|
+
resultId: semanticTokens.resultId,
|
|
58
|
+
legend: semanticTokens.legend,
|
|
59
|
+
languageId: semanticTokens.languageId,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
const err = error;
|
|
64
|
+
return res
|
|
65
|
+
.status(500)
|
|
66
|
+
.json({ success: false, error: err.message || "Failed to get semantic tokens" });
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
router.post("/lsp/semantic-tokens-delta", requireDesktopAuth, async (req, res) => {
|
|
70
|
+
try {
|
|
71
|
+
const { filePath, workspaceRoot, previousResultId } = req.body;
|
|
72
|
+
if (typeof filePath !== "string" || filePath.trim().length === 0) {
|
|
73
|
+
return res.status(400).json({ success: false, error: "filePath is required" });
|
|
74
|
+
}
|
|
75
|
+
const workspacePath = workspaceRoot || process.cwd();
|
|
76
|
+
const absolutePath = resolveAbsolutePath(workspacePath, filePath);
|
|
77
|
+
coreLsp.setRootPath(workspacePath);
|
|
78
|
+
const semanticTokens = await coreLsp.getSemanticTokensDocumentDelta(absolutePath, typeof previousResultId === "string" ? previousResultId : undefined);
|
|
79
|
+
if (!semanticTokens) {
|
|
80
|
+
return res.json({ success: false, error: "No semantic token delta available" });
|
|
81
|
+
}
|
|
82
|
+
return res.json({
|
|
83
|
+
success: true,
|
|
84
|
+
data: semanticTokens.data,
|
|
85
|
+
resultId: semanticTokens.resultId,
|
|
86
|
+
edits: semanticTokens.edits,
|
|
87
|
+
legend: semanticTokens.legend,
|
|
88
|
+
languageId: semanticTokens.languageId,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
const err = error;
|
|
93
|
+
return res
|
|
94
|
+
.status(500)
|
|
95
|
+
.json({ success: false, error: err.message || "Failed to get semantic token delta" });
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { coreLsp } from "../core/library/lsp/coreLsp.js";
|
|
3
|
+
const LANGUAGE_ID_MAP = {
|
|
4
|
+
ts: "typescript",
|
|
5
|
+
tsx: "typescriptreact",
|
|
6
|
+
typescript: "typescript",
|
|
7
|
+
typescriptreact: "typescriptreact",
|
|
8
|
+
js: "javascript",
|
|
9
|
+
jsx: "javascriptreact",
|
|
10
|
+
javascript: "javascript",
|
|
11
|
+
javascriptreact: "javascriptreact",
|
|
12
|
+
py: "python",
|
|
13
|
+
python: "python",
|
|
14
|
+
};
|
|
15
|
+
const resolveSemanticLanguageId = (language) => LANGUAGE_ID_MAP[language.toLowerCase()];
|
|
16
|
+
const resolveSemanticFilePath = ({ filePath, workspacePath, languageId, }) => {
|
|
17
|
+
if (filePath) {
|
|
18
|
+
return path.isAbsolute(filePath) ? filePath : path.join(workspacePath, filePath);
|
|
19
|
+
}
|
|
20
|
+
return path.join(workspacePath, `.iris-semantic-preview.${languageId.startsWith("typescript")
|
|
21
|
+
? "ts"
|
|
22
|
+
: languageId === "python"
|
|
23
|
+
? "py"
|
|
24
|
+
: "js"}`);
|
|
25
|
+
};
|
|
26
|
+
export const registerSemanticRoutes = (router) => {
|
|
27
|
+
// POST /api/agent/semantic-tokens - Get semantic tokens for supported LSP snippets
|
|
28
|
+
router.post("/semantic-tokens", async (req, res) => {
|
|
29
|
+
try {
|
|
30
|
+
const { code, language, filePath, workspaceRoot } = req.body;
|
|
31
|
+
if (typeof code !== "string") {
|
|
32
|
+
return res.status(400).json({ success: false, error: "Code is required" });
|
|
33
|
+
}
|
|
34
|
+
if (typeof language !== "string" || language.length === 0) {
|
|
35
|
+
return res.status(400).json({ success: false, error: "Language is required" });
|
|
36
|
+
}
|
|
37
|
+
const languageId = resolveSemanticLanguageId(language);
|
|
38
|
+
if (!languageId) {
|
|
39
|
+
return res.status(400).json({
|
|
40
|
+
success: false,
|
|
41
|
+
error: `Semantic tokens are not supported for language: ${language}`,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
const workspacePath = workspaceRoot || process.cwd();
|
|
45
|
+
const semanticFilePath = resolveSemanticFilePath({
|
|
46
|
+
filePath,
|
|
47
|
+
workspacePath,
|
|
48
|
+
languageId,
|
|
49
|
+
});
|
|
50
|
+
coreLsp.setRootPath(workspacePath);
|
|
51
|
+
const semanticTokens = await coreLsp.getSemanticTokensForCode(semanticFilePath, languageId, code);
|
|
52
|
+
if (!semanticTokens) {
|
|
53
|
+
// Distinguish "the language server can never start here" from a
|
|
54
|
+
// transient cold-start miss so the client knows not to retry.
|
|
55
|
+
const unavailable = coreLsp.isLanguageUnavailable(languageId);
|
|
56
|
+
return res.json({
|
|
57
|
+
success: false,
|
|
58
|
+
unavailable,
|
|
59
|
+
error: unavailable
|
|
60
|
+
? `No language server available for ${languageId} in this workspace`
|
|
61
|
+
: "No semantic tokens available",
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return res.json({
|
|
65
|
+
success: true,
|
|
66
|
+
data: semanticTokens.data,
|
|
67
|
+
legend: semanticTokens.legend,
|
|
68
|
+
languageId: semanticTokens.languageId,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
const err = error;
|
|
73
|
+
console.error("Semantic tokens error:", error);
|
|
74
|
+
return res.status(500).json({
|
|
75
|
+
success: false,
|
|
76
|
+
error: err.message || "Failed to fetch semantic tokens",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
// POST /api/agent/semantic-tokens-delta - Get semantic token deltas for supported LSP snippets
|
|
81
|
+
router.post("/semantic-tokens-delta", async (req, res) => {
|
|
82
|
+
try {
|
|
83
|
+
const { code, language, filePath, workspaceRoot, previousResultId } = req.body;
|
|
84
|
+
if (typeof code !== "string") {
|
|
85
|
+
return res.status(400).json({ success: false, error: "Code is required" });
|
|
86
|
+
}
|
|
87
|
+
if (typeof language !== "string" || language.length === 0) {
|
|
88
|
+
return res.status(400).json({ success: false, error: "Language is required" });
|
|
89
|
+
}
|
|
90
|
+
const languageId = resolveSemanticLanguageId(language);
|
|
91
|
+
if (!languageId) {
|
|
92
|
+
return res.status(400).json({
|
|
93
|
+
success: false,
|
|
94
|
+
error: `Semantic tokens are not supported for language: ${language}`,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
const workspacePath = workspaceRoot || process.cwd();
|
|
98
|
+
const semanticFilePath = resolveSemanticFilePath({
|
|
99
|
+
filePath,
|
|
100
|
+
workspacePath,
|
|
101
|
+
languageId,
|
|
102
|
+
});
|
|
103
|
+
coreLsp.setRootPath(workspacePath);
|
|
104
|
+
const semanticTokens = await coreLsp.getSemanticTokensDelta(semanticFilePath, languageId, code, typeof previousResultId === "string" ? previousResultId : undefined);
|
|
105
|
+
if (!semanticTokens) {
|
|
106
|
+
return res.json({ success: false, error: "No semantic tokens available" });
|
|
107
|
+
}
|
|
108
|
+
return res.json({
|
|
109
|
+
success: true,
|
|
110
|
+
data: semanticTokens.data,
|
|
111
|
+
edits: semanticTokens.edits,
|
|
112
|
+
resultId: semanticTokens.resultId,
|
|
113
|
+
legend: semanticTokens.legend,
|
|
114
|
+
languageId: semanticTokens.languageId,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
const err = error;
|
|
119
|
+
console.error("Semantic tokens delta error:", error);
|
|
120
|
+
return res.status(500).json({
|
|
121
|
+
success: false,
|
|
122
|
+
error: err.message || "Failed to fetch semantic token delta",
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
};
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* iris-agent CLI with ACP (Agent Client Protocol) support
|
|
4
|
+
* Usage:
|
|
5
|
+
* iris-agent --workspace /path/to/workspace --modelId openrouter/openai/gpt-4o --acp
|
|
6
|
+
* iris-agent --workspace /path/to/workspace --modelId openrouter/openai/gpt-4o --chat
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* iris-agent CLI with ACP (Agent Client Protocol) support
|
|
4
|
+
* Usage:
|
|
5
|
+
* iris-agent --workspace /path/to/workspace --modelId openrouter/openai/gpt-4o --acp
|
|
6
|
+
* iris-agent --workspace /path/to/workspace --modelId openrouter/openai/gpt-4o --chat
|
|
7
|
+
*/
|
|
8
|
+
import yargs from "yargs";
|
|
9
|
+
import { hideBin } from "yargs/helpers";
|
|
10
|
+
import { createCodingAgent } from "./api/core/agent/index.js";
|
|
11
|
+
import { startAcpServer } from "./api/acp/acpServer.js";
|
|
12
|
+
const defaultModelId = process.env.MODEL_ID ||
|
|
13
|
+
process.env.OPENROUTER_MODEL ||
|
|
14
|
+
"openrouter/openai/gpt-4o";
|
|
15
|
+
const argv = yargs(hideBin(process.argv))
|
|
16
|
+
.option("workspace", {
|
|
17
|
+
alias: "w",
|
|
18
|
+
type: "string",
|
|
19
|
+
description: "Workspace root path",
|
|
20
|
+
required: true,
|
|
21
|
+
})
|
|
22
|
+
.option("acp", {
|
|
23
|
+
alias: "a",
|
|
24
|
+
type: "boolean",
|
|
25
|
+
description: "Start ACP (Agent Client Protocol) server mode",
|
|
26
|
+
default: false,
|
|
27
|
+
})
|
|
28
|
+
.option("chat", {
|
|
29
|
+
alias: "c",
|
|
30
|
+
type: "boolean",
|
|
31
|
+
description: "Interactive chat mode",
|
|
32
|
+
default: false,
|
|
33
|
+
})
|
|
34
|
+
.option("modelId", {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: "Language model identifier",
|
|
37
|
+
default: defaultModelId,
|
|
38
|
+
})
|
|
39
|
+
.help()
|
|
40
|
+
.parseSync();
|
|
41
|
+
async function main() {
|
|
42
|
+
const workspaceRoot = argv.workspace;
|
|
43
|
+
const modelId = argv.modelId;
|
|
44
|
+
if (argv.acp) {
|
|
45
|
+
const stderrLog = console.error.bind(console);
|
|
46
|
+
console.log = stderrLog;
|
|
47
|
+
console.debug = stderrLog;
|
|
48
|
+
console.info = stderrLog;
|
|
49
|
+
console.warn = stderrLog;
|
|
50
|
+
console.dir = stderrLog;
|
|
51
|
+
console.table = stderrLog;
|
|
52
|
+
console.trace = stderrLog;
|
|
53
|
+
console.group = stderrLog;
|
|
54
|
+
console.groupCollapsed = stderrLog;
|
|
55
|
+
console.groupEnd = stderrLog;
|
|
56
|
+
}
|
|
57
|
+
console.log(`š Iris Agent CLI`);
|
|
58
|
+
console.log(`š Workspace: ${workspaceRoot}`);
|
|
59
|
+
console.log(`š¤ Model: ${modelId}`);
|
|
60
|
+
if (argv.acp) {
|
|
61
|
+
console.log("š Starting ACP server over stdio...");
|
|
62
|
+
await startAcpServer((requestedModelId, targetWorkspace) => createCodingAgent(requestedModelId || modelId, targetWorkspace || workspaceRoot), workspaceRoot);
|
|
63
|
+
}
|
|
64
|
+
else if (argv.chat) {
|
|
65
|
+
// Interactive chat mode
|
|
66
|
+
const agent = await createCodingAgent(modelId, workspaceRoot);
|
|
67
|
+
console.log(`š¬ Entering chat mode (type "exit" to quit)`);
|
|
68
|
+
await startChatMode(agent, workspaceRoot);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Default: show help
|
|
72
|
+
yargs(hideBin(process.argv))
|
|
73
|
+
.showHelp();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function startChatMode(agent, workspaceRoot) {
|
|
77
|
+
const readline = await import("readline");
|
|
78
|
+
const rl = readline.createInterface({
|
|
79
|
+
input: process.stdin,
|
|
80
|
+
output: process.stdout,
|
|
81
|
+
});
|
|
82
|
+
const question = (prompt) => new Promise((resolve) => rl.question(prompt, resolve));
|
|
83
|
+
const threadId = `cli-chat-${Date.now()}`;
|
|
84
|
+
const resourceId = `cli-session`;
|
|
85
|
+
try {
|
|
86
|
+
while (true) {
|
|
87
|
+
const input = await question("\n> ");
|
|
88
|
+
const trimmedInput = input.trim();
|
|
89
|
+
if (!trimmedInput) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (trimmedInput.toLowerCase() === "exit" || trimmedInput.toLowerCase() === "quit") {
|
|
93
|
+
console.log("š Goodbye!");
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
console.log("š¤ Processing...\n");
|
|
98
|
+
const options = {
|
|
99
|
+
threadId,
|
|
100
|
+
resourceId,
|
|
101
|
+
maxSteps: 50,
|
|
102
|
+
workspaceRoot,
|
|
103
|
+
};
|
|
104
|
+
if (typeof agent.stream === "function") {
|
|
105
|
+
const streamResult = await agent.stream(trimmedInput, options);
|
|
106
|
+
const reader = streamResult.fullStream.getReader();
|
|
107
|
+
let hasOutput = false;
|
|
108
|
+
while (true) {
|
|
109
|
+
const { done, value } = await reader.read();
|
|
110
|
+
if (done)
|
|
111
|
+
break;
|
|
112
|
+
if (value?.type === "text-delta" || value?.type === "reasoning-delta") {
|
|
113
|
+
const text = String(value.payload?.text || "");
|
|
114
|
+
if (text) {
|
|
115
|
+
process.stdout.write(text);
|
|
116
|
+
hasOutput = true;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (value?.type === "tool-call") {
|
|
120
|
+
const toolName = typeof value.payload?.toolName === "string"
|
|
121
|
+
? value.payload.toolName
|
|
122
|
+
: "tool";
|
|
123
|
+
process.stdout.write(`\nāļø [Calling tool: ${toolName}]... `);
|
|
124
|
+
}
|
|
125
|
+
else if (value?.type === "tool-result") {
|
|
126
|
+
process.stdout.write(`done.\n`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (!hasOutput && streamResult.text) {
|
|
130
|
+
const final = await streamResult.text;
|
|
131
|
+
if (final) {
|
|
132
|
+
console.log(final);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
console.log();
|
|
136
|
+
}
|
|
137
|
+
else if (typeof agent.generate === "function") {
|
|
138
|
+
const result = await agent.generate(trimmedInput, options);
|
|
139
|
+
const text = typeof result === "string"
|
|
140
|
+
? result
|
|
141
|
+
: result?.text || JSON.stringify(result, null, 2);
|
|
142
|
+
console.log("\nā
Agent Response:\n" + text);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
throw new Error("Agent does not support streaming or text generation");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
console.error("ā Error:", error);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
rl.close();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
main().catch((error) => {
|
|
158
|
+
console.error("ā Fatal error:", error);
|
|
159
|
+
process.exit(1);
|
|
160
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./api/acp/index.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./api/acp/index.js";
|
package/dist/server.d.ts
ADDED
package/dist/server.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
import express from "express";
|
|
3
|
+
import agentRouter from "./api/agent.js";
|
|
4
|
+
const port = Number(process.env.PORT || 8080);
|
|
5
|
+
const allowedOrigins = new Set((process.env.AGENT_ALLOWED_ORIGINS || "")
|
|
6
|
+
.split(",")
|
|
7
|
+
.map((origin) => origin.trim())
|
|
8
|
+
.filter(Boolean));
|
|
9
|
+
export const app = express();
|
|
10
|
+
app.disable("x-powered-by");
|
|
11
|
+
app.use((req, res, next) => {
|
|
12
|
+
const origin = req.get("origin");
|
|
13
|
+
if (!origin) {
|
|
14
|
+
return next();
|
|
15
|
+
}
|
|
16
|
+
if (!allowedOrigins.has(origin)) {
|
|
17
|
+
return res.status(403).json({ error: "Origin is not allowed" });
|
|
18
|
+
}
|
|
19
|
+
res.setHeader("Access-Control-Allow-Origin", origin);
|
|
20
|
+
res.setHeader("Vary", "Origin");
|
|
21
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Desktop-Token");
|
|
22
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
|
23
|
+
if (req.method === "OPTIONS") {
|
|
24
|
+
return res.sendStatus(204);
|
|
25
|
+
}
|
|
26
|
+
return next();
|
|
27
|
+
});
|
|
28
|
+
app.use(express.json({ limit: "10mb" }));
|
|
29
|
+
app.use(express.urlencoded({ extended: true, limit: "10mb" }));
|
|
30
|
+
app.get("/health", (_req, res) => {
|
|
31
|
+
res.json({ status: "ok" });
|
|
32
|
+
});
|
|
33
|
+
app.use("/api/agent", agentRouter);
|
|
34
|
+
if (import.meta.url === new URL(process.argv[1], "file:").href) {
|
|
35
|
+
app.listen(port, () => {
|
|
36
|
+
console.log(`Iris Agent listening on port ${port}`);
|
|
37
|
+
});
|
|
38
|
+
}
|