hoomanjs 1.29.2 → 1.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +216 -69
- package/dist/acp/acp-agent.d.ts +5 -5
- package/dist/acp/acp-agent.js +55 -54
- package/dist/acp/acp-agent.js.map +1 -1
- package/dist/acp/approvals.d.ts +3 -3
- package/dist/acp/approvals.js +73 -115
- package/dist/acp/approvals.js.map +1 -1
- package/dist/acp/sessions/options.js +11 -25
- package/dist/acp/sessions/options.js.map +1 -1
- package/dist/acp/utils/tool-kind.js +1 -5
- package/dist/acp/utils/tool-kind.js.map +1 -1
- package/dist/chat/app.d.ts +5 -1
- package/dist/chat/app.js +322 -202
- package/dist/chat/app.js.map +1 -1
- package/dist/chat/approvals.d.ts +4 -3
- package/dist/chat/approvals.js +11 -45
- package/dist/chat/approvals.js.map +1 -1
- package/dist/chat/components/ChatMessage.d.ts +1 -2
- package/dist/chat/components/ChatMessage.js +4 -5
- package/dist/chat/components/ChatMessage.js.map +1 -1
- package/dist/chat/components/EmptyChatBanner.js +2 -3
- package/dist/chat/components/EmptyChatBanner.js.map +1 -1
- package/dist/chat/components/StatusBar.js +6 -2
- package/dist/chat/components/StatusBar.js.map +1 -1
- package/dist/chat/components/ThoughtEvent.d.ts +6 -0
- package/dist/chat/components/ThoughtEvent.js +30 -0
- package/dist/chat/components/ThoughtEvent.js.map +1 -0
- package/dist/chat/components/ToolEvent.js +1 -1
- package/dist/chat/components/ToolEvent.js.map +1 -1
- package/dist/chat/components/Transcript.d.ts +7 -2
- package/dist/chat/components/Transcript.js +6 -2
- package/dist/chat/components/Transcript.js.map +1 -1
- package/dist/chat/components/markdown/BlockRenderer.js +7 -7
- package/dist/chat/components/markdown/BlockRenderer.js.map +1 -1
- package/dist/chat/components/markdown/MarkdownMessage.js +1 -1
- package/dist/chat/components/markdown/MarkdownMessage.js.map +1 -1
- package/dist/chat/components/shared.js +2 -0
- package/dist/chat/components/shared.js.map +1 -1
- package/dist/chat/index.d.ts +4 -0
- package/dist/chat/index.js +17 -3
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/steering.d.ts +20 -0
- package/dist/chat/steering.js +67 -0
- package/dist/chat/steering.js.map +1 -0
- package/dist/chat/types.d.ts +5 -1
- package/dist/cli.js +91 -13
- package/dist/cli.js.map +1 -1
- package/dist/configure/app.d.ts +1 -1
- package/dist/configure/app.js +581 -303
- package/dist/configure/app.js.map +1 -1
- package/dist/configure/components/MenuScreen.d.ts +4 -2
- package/dist/configure/components/MenuScreen.js +33 -6
- package/dist/configure/components/MenuScreen.js.map +1 -1
- package/dist/configure/components/SelectMenuItem.d.ts +1 -0
- package/dist/configure/components/SelectMenuItem.js +19 -10
- package/dist/configure/components/SelectMenuItem.js.map +1 -1
- package/dist/configure/index.js +4 -2
- package/dist/configure/index.js.map +1 -1
- package/dist/configure/types.d.ts +14 -12
- package/dist/configure/utils.d.ts +2 -0
- package/dist/configure/utils.js +21 -2
- package/dist/configure/utils.js.map +1 -1
- package/dist/core/agent/index.d.ts +3 -3
- package/dist/core/agent/index.js +20 -25
- package/dist/core/agent/index.js.map +1 -1
- package/dist/core/agent/mode-aware-tool-registry.js +2 -1
- package/dist/core/agent/mode-aware-tool-registry.js.map +1 -1
- package/dist/core/approvals/intervention.d.ts +34 -0
- package/dist/core/approvals/intervention.js +94 -0
- package/dist/core/approvals/intervention.js.map +1 -0
- package/dist/core/config.d.ts +49 -28
- package/dist/core/config.js +85 -26
- package/dist/core/config.js.map +1 -1
- package/dist/core/context/index.d.ts +11 -2
- package/dist/core/context/index.js +54 -4
- package/dist/core/context/index.js.map +1 -1
- package/dist/core/context/model-extractor.d.ts +13 -0
- package/dist/core/context/model-extractor.js +98 -0
- package/dist/core/context/model-extractor.js.map +1 -0
- package/dist/core/index.d.ts +6 -2
- package/dist/core/index.js +6 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/mcp/config.d.ts +28 -0
- package/dist/core/mcp/index.d.ts +5 -3
- package/dist/core/mcp/index.js +4 -2
- package/dist/core/mcp/index.js.map +1 -1
- package/dist/core/mcp/manager.d.ts +14 -1
- package/dist/core/mcp/manager.js +76 -4
- package/dist/core/mcp/manager.js.map +1 -1
- package/dist/core/mcp/oauth/callback-server.d.ts +16 -0
- package/dist/core/mcp/oauth/callback-server.js +134 -0
- package/dist/core/mcp/oauth/callback-server.js.map +1 -0
- package/dist/core/mcp/oauth/identity.d.ts +9 -0
- package/dist/core/mcp/oauth/identity.js +31 -0
- package/dist/core/mcp/oauth/identity.js.map +1 -0
- package/dist/core/mcp/oauth/index.d.ts +11 -0
- package/dist/core/mcp/oauth/index.js +15 -0
- package/dist/core/mcp/oauth/index.js.map +1 -0
- package/dist/core/mcp/oauth/provider.d.ts +43 -0
- package/dist/core/mcp/oauth/provider.js +203 -0
- package/dist/core/mcp/oauth/provider.js.map +1 -0
- package/dist/core/mcp/oauth/service.d.ts +29 -0
- package/dist/core/mcp/oauth/service.js +139 -0
- package/dist/core/mcp/oauth/service.js.map +1 -0
- package/dist/core/mcp/oauth/store.d.ts +14 -0
- package/dist/core/mcp/oauth/store.js +86 -0
- package/dist/core/mcp/oauth/store.js.map +1 -0
- package/dist/core/mcp/oauth/types.d.ts +87 -0
- package/dist/core/mcp/oauth/types.js +45 -0
- package/dist/core/mcp/oauth/types.js.map +1 -0
- package/dist/core/mcp/types.d.ts +56 -0
- package/dist/core/mcp/types.js +3 -0
- package/dist/core/mcp/types.js.map +1 -1
- package/dist/core/memory/file-store.d.ts +24 -0
- package/dist/core/memory/file-store.js +151 -0
- package/dist/core/memory/file-store.js.map +1 -0
- package/dist/core/memory/index.d.ts +2 -5
- package/dist/core/memory/index.js +2 -3
- package/dist/core/memory/index.js.map +1 -1
- package/dist/core/memory/runtime.d.ts +4 -0
- package/dist/core/memory/runtime.js +37 -0
- package/dist/core/memory/runtime.js.map +1 -0
- package/dist/core/models/anthropic.js +24 -1
- package/dist/core/models/anthropic.js.map +1 -1
- package/dist/core/models/moonshot.js +33 -1
- package/dist/core/models/moonshot.js.map +1 -1
- package/dist/core/modes/definitions.d.ts +19 -0
- package/dist/core/modes/definitions.js +99 -0
- package/dist/core/modes/definitions.js.map +1 -0
- package/dist/core/modes/index.d.ts +3 -0
- package/dist/core/modes/index.js +4 -0
- package/dist/core/modes/index.js.map +1 -0
- package/dist/core/modes/registry.d.ts +9 -0
- package/dist/core/modes/registry.js +57 -0
- package/dist/core/modes/registry.js.map +1 -0
- package/dist/core/modes/schema.d.ts +5 -0
- package/dist/core/modes/schema.js +6 -0
- package/dist/core/modes/schema.js.map +1 -0
- package/dist/core/prompts/agents/research.md +8 -8
- package/dist/core/prompts/bundled.d.ts +3 -0
- package/dist/core/prompts/bundled.js +14 -0
- package/dist/core/prompts/bundled.js.map +1 -0
- package/dist/core/prompts/environment.d.ts +0 -1
- package/dist/core/prompts/environment.js +0 -2
- package/dist/core/prompts/environment.js.map +1 -1
- package/dist/core/prompts/index.d.ts +1 -4
- package/dist/core/prompts/index.js +1 -7
- package/dist/core/prompts/index.js.map +1 -1
- package/dist/core/prompts/modes/agent.md +3 -0
- package/dist/core/prompts/modes/ask.md +5 -3
- package/dist/core/prompts/modes/plan.md +2 -2
- package/dist/core/prompts/session-mode-appendix.d.ts +3 -9
- package/dist/core/prompts/session-mode-appendix.js +32 -69
- package/dist/core/prompts/session-mode-appendix.js.map +1 -1
- package/dist/core/prompts/static/environment.md +2 -2
- package/dist/core/prompts/static/init.md +25 -0
- package/dist/core/prompts/static/memory.md +9 -123
- package/dist/core/prompts/static/planning.md +1 -1
- package/dist/core/prompts/static/skills.md +6 -5
- package/dist/core/prompts/static/subagents.md +2 -2
- package/dist/core/prompts/static/web-search.md +2 -1
- package/dist/core/prompts/system.js +8 -22
- package/dist/core/prompts/system.js.map +1 -1
- package/dist/core/skills/built-in/hooman-config/SKILL.md +105 -32
- package/dist/core/skills/built-in/hooman-skills/SKILL.md +1 -1
- package/dist/core/skills/index.d.ts +1 -0
- package/dist/core/skills/index.js +1 -0
- package/dist/core/skills/index.js.map +1 -1
- package/dist/core/skills/plugin.d.ts +7 -0
- package/dist/core/skills/plugin.js +40 -0
- package/dist/core/skills/plugin.js.map +1 -0
- package/dist/core/state/agent-app-state.d.ts +1 -1
- package/dist/core/state/agent-app-state.js +1 -1
- package/dist/core/state/session-mode.d.ts +2 -9
- package/dist/core/state/session-mode.js +4 -12
- package/dist/core/state/session-mode.js.map +1 -1
- package/dist/core/state/tool-approvals.d.ts +4 -8
- package/dist/core/state/tool-approvals.js +14 -76
- package/dist/core/state/tool-approvals.js.map +1 -1
- package/dist/core/subagents/index.d.ts +3 -0
- package/dist/core/subagents/index.js +4 -0
- package/dist/core/subagents/index.js.map +1 -0
- package/dist/core/subagents/research.d.ts +16 -0
- package/dist/core/subagents/research.js +58 -0
- package/dist/core/subagents/research.js.map +1 -0
- package/dist/core/{agents → subagents}/runner.d.ts +6 -5
- package/dist/core/{agents → subagents}/runner.js +8 -10
- package/dist/core/subagents/runner.js.map +1 -0
- package/dist/core/{agents/tools.d.ts → subagents/tool.d.ts} +6 -6
- package/dist/core/{agents/tools.js → subagents/tool.js} +14 -16
- package/dist/core/subagents/tool.js.map +1 -0
- package/dist/core/tools/plan.js +2 -6
- package/dist/core/tools/plan.js.map +1 -1
- package/dist/core/tools/time.js +1 -1
- package/dist/core/tools/time.js.map +1 -1
- package/dist/core/utils/browser.d.ts +1 -0
- package/dist/core/utils/browser.js +25 -0
- package/dist/core/utils/browser.js.map +1 -0
- package/dist/core/utils/paths.d.ts +2 -4
- package/dist/core/utils/paths.js +2 -4
- package/dist/core/utils/paths.js.map +1 -1
- package/dist/daemon/approvals.d.ts +2 -2
- package/dist/daemon/approvals.js +51 -56
- package/dist/daemon/approvals.js.map +1 -1
- package/dist/daemon/index.js +9 -6
- package/dist/daemon/index.js.map +1 -1
- package/dist/exec/approvals.d.ts +2 -4
- package/dist/exec/approvals.js +16 -48
- package/dist/exec/approvals.js.map +1 -1
- package/dist/index.d.ts +13 -18
- package/dist/index.js +9 -11
- package/dist/index.js.map +1 -1
- package/package.json +5 -18
- package/dist/chat/components/ScrollView.d.ts +0 -106
- package/dist/chat/components/ScrollView.js +0 -80
- package/dist/chat/components/ScrollView.js.map +0 -1
- package/dist/chat/components/TranscriptViewport.d.ts +0 -9
- package/dist/chat/components/TranscriptViewport.js +0 -124
- package/dist/chat/components/TranscriptViewport.js.map +0 -1
- package/dist/core/agents/definitions.d.ts +0 -12
- package/dist/core/agents/definitions.js +0 -20
- package/dist/core/agents/definitions.js.map +0 -1
- package/dist/core/agents/index.d.ts +0 -4
- package/dist/core/agents/index.js +0 -5
- package/dist/core/agents/index.js.map +0 -1
- package/dist/core/agents/registry.d.ts +0 -5
- package/dist/core/agents/registry.js +0 -84
- package/dist/core/agents/registry.js.map +0 -1
- package/dist/core/agents/runner.js.map +0 -1
- package/dist/core/agents/tools.js.map +0 -1
- package/dist/core/inference/embedder.d.ts +0 -26
- package/dist/core/inference/embedder.js +0 -85
- package/dist/core/inference/embedder.js.map +0 -1
- package/dist/core/inference/index.d.ts +0 -9
- package/dist/core/inference/index.js +0 -13
- package/dist/core/inference/index.js.map +0 -1
- package/dist/core/inference/loader.d.ts +0 -16
- package/dist/core/inference/loader.js +0 -129
- package/dist/core/inference/loader.js.map +0 -1
- package/dist/core/inference/reranker.d.ts +0 -28
- package/dist/core/inference/reranker.js +0 -66
- package/dist/core/inference/reranker.js.map +0 -1
- package/dist/core/memory/brain.d.ts +0 -25
- package/dist/core/memory/brain.js +0 -137
- package/dist/core/memory/brain.js.map +0 -1
- package/dist/core/memory/database.d.ts +0 -4
- package/dist/core/memory/database.js +0 -87
- package/dist/core/memory/database.js.map +0 -1
- package/dist/core/memory/tools.d.ts +0 -16
- package/dist/core/memory/tools.js +0 -110
- package/dist/core/memory/tools.js.map +0 -1
- package/dist/core/memory/types.d.ts +0 -11
- package/dist/core/memory/types.js +0 -2
- package/dist/core/memory/types.js.map +0 -1
- package/dist/core/prompts/skills.d.ts +0 -15
- package/dist/core/prompts/skills.js +0 -92
- package/dist/core/prompts/skills.js.map +0 -1
- package/dist/core/prompts/static/wiki.md +0 -25
- package/dist/core/wiki/converters.d.ts +0 -12
- package/dist/core/wiki/converters.js +0 -73
- package/dist/core/wiki/converters.js.map +0 -1
- package/dist/core/wiki/database.d.ts +0 -39
- package/dist/core/wiki/database.js +0 -177
- package/dist/core/wiki/database.js.map +0 -1
- package/dist/core/wiki/index.d.ts +0 -7
- package/dist/core/wiki/index.js +0 -5
- package/dist/core/wiki/index.js.map +0 -1
- package/dist/core/wiki/storage.d.ts +0 -38
- package/dist/core/wiki/storage.js +0 -206
- package/dist/core/wiki/storage.js.map +0 -1
- package/dist/core/wiki/tools.d.ts +0 -5
- package/dist/core/wiki/tools.js +0 -32
- package/dist/core/wiki/tools.js.map +0 -1
package/dist/configure/app.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
3
3
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
-
import path from "node:path";
|
|
5
4
|
import { Box, Text, useApp, useInput } from "ink";
|
|
6
5
|
import { LlmProvider, } from "../core/config.js";
|
|
6
|
+
import { McpOAuthConfigSchema, } from "../core/mcp/oauth/types.js";
|
|
7
7
|
import { McpTransportSchema, } from "../core/mcp/types.js";
|
|
8
|
-
import { Storage } from "../core/wiki/storage.js";
|
|
9
8
|
import { basePath, configJsonPath, instructionsMdPath, mcpJsonPath, skillsPath, } from "../core/utils/paths.js";
|
|
10
9
|
import { BusyScreen } from "./components/BusyScreen.js";
|
|
11
10
|
import { HomeScreen } from "./components/HomeScreen.js";
|
|
12
11
|
import { MenuScreen } from "./components/MenuScreen.js";
|
|
13
12
|
import { PromptForm } from "./components/PromptForm.js";
|
|
14
13
|
import { openFileInEditor } from "./open-in-editor.js";
|
|
15
|
-
import { DEFAULT_INSTRUCTIONS, compactJson, folderNameForSkill, normalizeOptional, noticeColor, parseNumber, parseObjectRecord, maskSensitiveParamsForDisplay, parseStringArray, parseStringRecord, transportSummary, truncate, } from "./utils.js";
|
|
14
|
+
import { DEFAULT_INSTRUCTIONS, compactJson, folderNameForSkill, paramsPreview, normalizeOptional, noticeColor, parseOptionalBoolean, parseNumber, parseObjectRecord, maskSensitiveParamsForDisplay, parseStringArray, parseStringRecord, transportSummary, truncate, } from "./utils.js";
|
|
16
15
|
const PROMPT_LABELS = {
|
|
17
16
|
behaviour: "Behaviour",
|
|
18
17
|
communication: "Communication",
|
|
@@ -26,10 +25,39 @@ const SEARCH_PROVIDER_LABELS = {
|
|
|
26
25
|
serper: "Serper",
|
|
27
26
|
tavily: "Tavily",
|
|
28
27
|
};
|
|
28
|
+
const SUPPORTED_PROVIDER_TYPES = [
|
|
29
|
+
LlmProvider.Anthropic,
|
|
30
|
+
LlmProvider.Bedrock,
|
|
31
|
+
LlmProvider.Google,
|
|
32
|
+
LlmProvider.Groq,
|
|
33
|
+
LlmProvider.Moonshot,
|
|
34
|
+
LlmProvider.Ollama,
|
|
35
|
+
LlmProvider.OpenAI,
|
|
36
|
+
LlmProvider.Xai,
|
|
37
|
+
];
|
|
38
|
+
function providerParamsTemplate(provider) {
|
|
39
|
+
switch (provider) {
|
|
40
|
+
case LlmProvider.Anthropic:
|
|
41
|
+
return { apiKey: "" };
|
|
42
|
+
case LlmProvider.Bedrock:
|
|
43
|
+
return { region: "us-west-2" };
|
|
44
|
+
case LlmProvider.Google:
|
|
45
|
+
return { apiKey: "" };
|
|
46
|
+
case LlmProvider.Groq:
|
|
47
|
+
return { apiKey: "" };
|
|
48
|
+
case LlmProvider.Moonshot:
|
|
49
|
+
return { apiKey: "" };
|
|
50
|
+
case LlmProvider.Ollama:
|
|
51
|
+
return {};
|
|
52
|
+
case LlmProvider.OpenAI:
|
|
53
|
+
return { apiKey: "" };
|
|
54
|
+
case LlmProvider.Xai:
|
|
55
|
+
return { apiKey: "" };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
29
58
|
/** On/off display for tool rows (`Tool • Yes` / `Tool • No`). */
|
|
30
59
|
const yesNo = (on) => (on ? "Yes" : "No");
|
|
31
|
-
|
|
32
|
-
export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
60
|
+
export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, }) {
|
|
33
61
|
const { exit } = useApp();
|
|
34
62
|
const [screen, setScreen] = useState({ kind: "home" });
|
|
35
63
|
const [prompt, setPrompt] = useState(null);
|
|
@@ -38,13 +66,7 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
38
66
|
const [revision, setRevision] = useState(0);
|
|
39
67
|
const [installedSkills, setInstalledSkills] = useState([]);
|
|
40
68
|
const [searchResults, setSearchResults] = useState([]);
|
|
41
|
-
const [
|
|
42
|
-
status: "idle",
|
|
43
|
-
});
|
|
44
|
-
const [wikiDocsNonce, setWikiDocsNonce] = useState(0);
|
|
45
|
-
const bumpWikiDocs = useCallback(() => {
|
|
46
|
-
setWikiDocsNonce((n) => n + 1);
|
|
47
|
-
}, []);
|
|
69
|
+
const [mcpAuthStatuses, setMcpAuthStatuses] = useState({});
|
|
48
70
|
const refresh = useCallback(() => {
|
|
49
71
|
setRevision((value) => value + 1);
|
|
50
72
|
}, []);
|
|
@@ -72,38 +94,37 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
72
94
|
useEffect(() => {
|
|
73
95
|
void refreshSkills();
|
|
74
96
|
}, [refreshSkills]);
|
|
75
|
-
const wikiDocsPage = screen.kind === "config-wiki-docs" ? screen.page : null;
|
|
76
97
|
useEffect(() => {
|
|
77
|
-
if (wikiDocsPage == null) {
|
|
78
|
-
setWikiDocsList({ status: "idle" });
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
98
|
let cancelled = false;
|
|
82
|
-
|
|
83
|
-
void (async () => {
|
|
99
|
+
const loadStatuses = async () => {
|
|
84
100
|
try {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
await storage.close();
|
|
89
|
-
if (!cancelled) {
|
|
90
|
-
setWikiDocsList({ status: "ready", page: wikiDocsPage, result });
|
|
101
|
+
const rows = await mcpManager.listAuthStatuses();
|
|
102
|
+
if (cancelled) {
|
|
103
|
+
return;
|
|
91
104
|
}
|
|
105
|
+
setMcpAuthStatuses(Object.fromEntries(rows.map((row) => [row.name, row.status])));
|
|
92
106
|
}
|
|
93
|
-
catch
|
|
107
|
+
catch {
|
|
94
108
|
if (!cancelled) {
|
|
95
|
-
|
|
96
|
-
status: "error",
|
|
97
|
-
page: wikiDocsPage,
|
|
98
|
-
message: error instanceof Error ? error.message : String(error),
|
|
99
|
-
});
|
|
109
|
+
setMcpAuthStatuses({});
|
|
100
110
|
}
|
|
101
111
|
}
|
|
102
|
-
}
|
|
112
|
+
};
|
|
113
|
+
void loadStatuses();
|
|
103
114
|
return () => {
|
|
104
115
|
cancelled = true;
|
|
105
116
|
};
|
|
106
|
-
}, [
|
|
117
|
+
}, [mcpManager, revision]);
|
|
118
|
+
const configData = useMemo(() => ({
|
|
119
|
+
name: config.name,
|
|
120
|
+
providers: config.providers,
|
|
121
|
+
llms: config.llms,
|
|
122
|
+
search: config.search,
|
|
123
|
+
prompts: config.prompts,
|
|
124
|
+
tools: config.tools,
|
|
125
|
+
compaction: config.compaction,
|
|
126
|
+
}), [config, revision]);
|
|
127
|
+
const mcpServers = useMemo(() => mcpConfig.list(), [mcpConfig, revision]);
|
|
107
128
|
useInput((input, key) => {
|
|
108
129
|
if (key.ctrl && input.toLowerCase() === "c") {
|
|
109
130
|
onExit();
|
|
@@ -130,34 +151,31 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
130
151
|
setScreen({ kind: "config-llm-edit", name: screen.name });
|
|
131
152
|
return;
|
|
132
153
|
}
|
|
133
|
-
if (screen.kind === "config-
|
|
134
|
-
setScreen({ kind: "config-
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
if (screen.kind === "config-wiki-docs") {
|
|
138
|
-
setScreen({ kind: "config-wiki" });
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
if (screen.kind === "config-wiki") {
|
|
142
|
-
setScreen({ kind: "config-tools" });
|
|
154
|
+
if (screen.kind === "config-provider-delete-confirm") {
|
|
155
|
+
setScreen({ kind: "config-provider-edit", name: screen.name });
|
|
143
156
|
return;
|
|
144
157
|
}
|
|
145
158
|
if (screen.kind !== "home") {
|
|
146
159
|
setScreen({ kind: "home" });
|
|
147
160
|
}
|
|
148
161
|
}, { isActive: true });
|
|
149
|
-
const configData = useMemo(() => ({
|
|
150
|
-
name: config.name,
|
|
151
|
-
llms: config.llms,
|
|
152
|
-
search: config.search,
|
|
153
|
-
prompts: config.prompts,
|
|
154
|
-
tools: config.tools,
|
|
155
|
-
compaction: config.compaction,
|
|
156
|
-
}), [config, revision]);
|
|
157
|
-
const mcpServers = useMemo(() => mcpConfig.list(), [mcpConfig, revision]);
|
|
158
162
|
const setSuccess = useCallback((text) => {
|
|
159
163
|
setNotice({ kind: "success", text });
|
|
160
164
|
}, []);
|
|
165
|
+
const authenticateMcpServer = useCallback(async (name) => {
|
|
166
|
+
await runTask(`Authenticating MCP server "${name}"...`, async () => {
|
|
167
|
+
await mcpManager.authenticate(name);
|
|
168
|
+
refresh();
|
|
169
|
+
setSuccess(`Authenticated MCP server "${name}".`);
|
|
170
|
+
});
|
|
171
|
+
}, [mcpManager, refresh, runTask, setSuccess]);
|
|
172
|
+
const logoutMcpServer = useCallback(async (name) => {
|
|
173
|
+
await runTask(`Logging out MCP server "${name}"...`, async () => {
|
|
174
|
+
await mcpManager.logout(name);
|
|
175
|
+
refresh();
|
|
176
|
+
setSuccess(`Cleared OAuth credentials for "${name}".`);
|
|
177
|
+
});
|
|
178
|
+
}, [mcpManager, refresh, runTask, setSuccess]);
|
|
161
179
|
const updateConfig = useCallback((partial, message) => {
|
|
162
180
|
config.update(partial);
|
|
163
181
|
refresh();
|
|
@@ -171,7 +189,7 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
171
189
|
{
|
|
172
190
|
name,
|
|
173
191
|
options: {
|
|
174
|
-
provider: LlmProvider.Ollama,
|
|
192
|
+
provider: config.providers[0]?.name ?? LlmProvider.Ollama,
|
|
175
193
|
model: "gemma4:e4b",
|
|
176
194
|
params: {},
|
|
177
195
|
},
|
|
@@ -179,6 +197,39 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
179
197
|
},
|
|
180
198
|
], [config]);
|
|
181
199
|
const removeLlm = useCallback((name) => config.llms.filter((m) => m.name !== name), [config]);
|
|
200
|
+
const patchProvider = useCallback((name, patch) => config.providers.map((provider) => provider.name === name
|
|
201
|
+
? {
|
|
202
|
+
...provider,
|
|
203
|
+
options: {
|
|
204
|
+
...provider.options,
|
|
205
|
+
...patch,
|
|
206
|
+
params: patch.params ?? provider.options.params,
|
|
207
|
+
},
|
|
208
|
+
}
|
|
209
|
+
: provider), [config]);
|
|
210
|
+
const renameProvider = useCallback((oldName, newName) => ({
|
|
211
|
+
providers: config.providers.map((provider) => provider.name === oldName ? { ...provider, name: newName } : provider),
|
|
212
|
+
llms: config.llms.map((llm) => llm.options.provider === oldName
|
|
213
|
+
? {
|
|
214
|
+
...llm,
|
|
215
|
+
options: {
|
|
216
|
+
...llm.options,
|
|
217
|
+
provider: newName,
|
|
218
|
+
},
|
|
219
|
+
}
|
|
220
|
+
: llm),
|
|
221
|
+
}), [config]);
|
|
222
|
+
const addProvider = useCallback((name) => [
|
|
223
|
+
...config.providers,
|
|
224
|
+
{
|
|
225
|
+
name,
|
|
226
|
+
options: {
|
|
227
|
+
provider: LlmProvider.Ollama,
|
|
228
|
+
params: providerParamsTemplate(LlmProvider.Ollama),
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
], [config]);
|
|
232
|
+
const removeProvider = useCallback((name) => config.providers.filter((provider) => provider.name !== name), [config]);
|
|
182
233
|
const promptValue = useCallback((state) => {
|
|
183
234
|
setPrompt(state);
|
|
184
235
|
}, []);
|
|
@@ -260,6 +311,192 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
260
311
|
}, [mcpConfig, promptValue, refresh, setSuccess]);
|
|
261
312
|
const promptForRemote = useCallback((name, type, initial) => {
|
|
262
313
|
const mode = initial ? "Edit" : "Add";
|
|
314
|
+
const persistRemote = (url, headers, oauth) => {
|
|
315
|
+
const transport = McpTransportSchema.parse({
|
|
316
|
+
type,
|
|
317
|
+
url,
|
|
318
|
+
...(headers && Object.keys(headers).length > 0 ? { headers } : {}),
|
|
319
|
+
...(oauth ? { oauth } : {}),
|
|
320
|
+
});
|
|
321
|
+
if (initial) {
|
|
322
|
+
mcpConfig.update(name, transport);
|
|
323
|
+
setSuccess(`Updated MCP server "${name}".`);
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
mcpConfig.add(name, transport);
|
|
327
|
+
setSuccess(`Added MCP server "${name}".`);
|
|
328
|
+
}
|
|
329
|
+
setPrompt(null);
|
|
330
|
+
setScreen({ kind: "mcp" });
|
|
331
|
+
refresh();
|
|
332
|
+
};
|
|
333
|
+
const promptForOAuthDetails = (url, headers, oauthEnabled) => {
|
|
334
|
+
if (!oauthEnabled) {
|
|
335
|
+
persistRemote(url, headers, undefined);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
promptValue({
|
|
339
|
+
title: `${mode} ${type} server`,
|
|
340
|
+
label: "OAuth client ID (optional)",
|
|
341
|
+
initialValue: initial?.oauth?.clientId ?? "",
|
|
342
|
+
placeholder: "client-id",
|
|
343
|
+
onSubmit: async (clientIdValue) => {
|
|
344
|
+
promptValue({
|
|
345
|
+
title: `${mode} ${type} server`,
|
|
346
|
+
label: "OAuth client secret (optional)",
|
|
347
|
+
initialValue: initial?.oauth?.clientSecret ?? "",
|
|
348
|
+
placeholder: "secret",
|
|
349
|
+
note: "Stored in mcp.json only if you enter a value.",
|
|
350
|
+
onSubmit: async (clientSecretValue) => {
|
|
351
|
+
promptValue({
|
|
352
|
+
title: `${mode} ${type} server`,
|
|
353
|
+
label: "OAuth scopes (optional)",
|
|
354
|
+
initialValue: initial?.oauth?.scopes
|
|
355
|
+
? compactJson(initial.oauth.scopes)
|
|
356
|
+
: "",
|
|
357
|
+
placeholder: '["read","write"]',
|
|
358
|
+
onSubmit: async (scopesValue) => {
|
|
359
|
+
promptValue({
|
|
360
|
+
title: `${mode} ${type} server`,
|
|
361
|
+
label: "OAuth audiences (optional)",
|
|
362
|
+
initialValue: initial?.oauth?.audiences
|
|
363
|
+
? compactJson(initial.oauth.audiences)
|
|
364
|
+
: "",
|
|
365
|
+
placeholder: '["https://api.example.com"]',
|
|
366
|
+
onSubmit: async (audiencesValue) => {
|
|
367
|
+
promptValue({
|
|
368
|
+
title: `${mode} ${type} server`,
|
|
369
|
+
label: "OAuth callback port (optional)",
|
|
370
|
+
initialValue: initial?.oauth?.callbackPort !== undefined
|
|
371
|
+
? String(initial.oauth.callbackPort)
|
|
372
|
+
: "",
|
|
373
|
+
placeholder: "19876",
|
|
374
|
+
onSubmit: async (callbackPortValue) => {
|
|
375
|
+
promptValue({
|
|
376
|
+
title: `${mode} ${type} server`,
|
|
377
|
+
label: "OAuth redirect URI (optional)",
|
|
378
|
+
initialValue: initial?.oauth?.redirectUri ?? "",
|
|
379
|
+
placeholder: "http://127.0.0.1:19876/mcp/oauth/callback",
|
|
380
|
+
onSubmit: async (redirectUriValue) => {
|
|
381
|
+
promptValue({
|
|
382
|
+
title: `${mode} ${type} server`,
|
|
383
|
+
label: "OAuth issuer (optional)",
|
|
384
|
+
initialValue: initial?.oauth?.issuer ?? "",
|
|
385
|
+
placeholder: "https://auth.example.com",
|
|
386
|
+
onSubmit: async (issuerValue) => {
|
|
387
|
+
promptValue({
|
|
388
|
+
title: `${mode} ${type} server`,
|
|
389
|
+
label: "OAuth authorization URL override (optional)",
|
|
390
|
+
initialValue: initial?.oauth?.authorizationUrl ?? "",
|
|
391
|
+
placeholder: "https://auth.example.com/authorize",
|
|
392
|
+
onSubmit: async (authorizationUrlValue) => {
|
|
393
|
+
promptValue({
|
|
394
|
+
title: `${mode} ${type} server`,
|
|
395
|
+
label: "OAuth token URL override (optional)",
|
|
396
|
+
initialValue: initial?.oauth?.tokenUrl ?? "",
|
|
397
|
+
placeholder: "https://auth.example.com/token",
|
|
398
|
+
onSubmit: async (tokenUrlValue) => {
|
|
399
|
+
promptValue({
|
|
400
|
+
title: `${mode} ${type} server`,
|
|
401
|
+
label: "OAuth registration URL override (optional)",
|
|
402
|
+
initialValue: initial?.oauth
|
|
403
|
+
?.registrationUrl ?? "",
|
|
404
|
+
placeholder: "https://auth.example.com/register",
|
|
405
|
+
onSubmit: async (registrationUrlValue) => {
|
|
406
|
+
promptValue({
|
|
407
|
+
title: `${mode} ${type} server`,
|
|
408
|
+
label: "OAuth token param name (optional)",
|
|
409
|
+
initialValue: initial?.oauth
|
|
410
|
+
?.tokenParamName ?? "",
|
|
411
|
+
placeholder: "access_token",
|
|
412
|
+
onSubmit: async (tokenParamNameValue) => {
|
|
413
|
+
const scopes = parseStringArray(scopesValue, "OAuth scopes");
|
|
414
|
+
const audiences = parseStringArray(audiencesValue, "OAuth audiences");
|
|
415
|
+
const callbackPort = normalizeOptional(callbackPortValue) !== undefined
|
|
416
|
+
? parseNumber(callbackPortValue, "OAuth callback port", {
|
|
417
|
+
integer: true,
|
|
418
|
+
min: 1,
|
|
419
|
+
max: 65535,
|
|
420
|
+
})
|
|
421
|
+
: undefined;
|
|
422
|
+
const oauth = McpOAuthConfigSchema.parse({
|
|
423
|
+
enabled: true,
|
|
424
|
+
...(normalizeOptional(clientIdValue)
|
|
425
|
+
? {
|
|
426
|
+
clientId: normalizeOptional(clientIdValue),
|
|
427
|
+
}
|
|
428
|
+
: {}),
|
|
429
|
+
...(normalizeOptional(clientSecretValue)
|
|
430
|
+
? {
|
|
431
|
+
clientSecret: normalizeOptional(clientSecretValue),
|
|
432
|
+
}
|
|
433
|
+
: {}),
|
|
434
|
+
...(scopes.length > 0
|
|
435
|
+
? { scopes }
|
|
436
|
+
: {}),
|
|
437
|
+
...(audiences.length >
|
|
438
|
+
0
|
|
439
|
+
? { audiences }
|
|
440
|
+
: {}),
|
|
441
|
+
...(callbackPort !==
|
|
442
|
+
undefined
|
|
443
|
+
? { callbackPort }
|
|
444
|
+
: {}),
|
|
445
|
+
...(normalizeOptional(redirectUriValue)
|
|
446
|
+
? {
|
|
447
|
+
redirectUri: normalizeOptional(redirectUriValue),
|
|
448
|
+
}
|
|
449
|
+
: {}),
|
|
450
|
+
...(normalizeOptional(issuerValue)
|
|
451
|
+
? {
|
|
452
|
+
issuer: normalizeOptional(issuerValue),
|
|
453
|
+
}
|
|
454
|
+
: {}),
|
|
455
|
+
...(normalizeOptional(authorizationUrlValue)
|
|
456
|
+
? {
|
|
457
|
+
authorizationUrl: normalizeOptional(authorizationUrlValue),
|
|
458
|
+
}
|
|
459
|
+
: {}),
|
|
460
|
+
...(normalizeOptional(tokenUrlValue)
|
|
461
|
+
? {
|
|
462
|
+
tokenUrl: normalizeOptional(tokenUrlValue),
|
|
463
|
+
}
|
|
464
|
+
: {}),
|
|
465
|
+
...(normalizeOptional(registrationUrlValue)
|
|
466
|
+
? {
|
|
467
|
+
registrationUrl: normalizeOptional(registrationUrlValue),
|
|
468
|
+
}
|
|
469
|
+
: {}),
|
|
470
|
+
...(normalizeOptional(tokenParamNameValue)
|
|
471
|
+
? {
|
|
472
|
+
tokenParamName: normalizeOptional(tokenParamNameValue),
|
|
473
|
+
}
|
|
474
|
+
: {}),
|
|
475
|
+
});
|
|
476
|
+
persistRemote(url, headers, oauth);
|
|
477
|
+
},
|
|
478
|
+
});
|
|
479
|
+
},
|
|
480
|
+
});
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
},
|
|
484
|
+
});
|
|
485
|
+
},
|
|
486
|
+
});
|
|
487
|
+
},
|
|
488
|
+
});
|
|
489
|
+
},
|
|
490
|
+
});
|
|
491
|
+
},
|
|
492
|
+
});
|
|
493
|
+
},
|
|
494
|
+
});
|
|
495
|
+
},
|
|
496
|
+
});
|
|
497
|
+
},
|
|
498
|
+
});
|
|
499
|
+
};
|
|
263
500
|
promptValue({
|
|
264
501
|
title: `${mode} ${type} server`,
|
|
265
502
|
label: "URL",
|
|
@@ -277,24 +514,17 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
277
514
|
placeholder: '{"Authorization":"Bearer ..."}',
|
|
278
515
|
onSubmit: async (headersValue) => {
|
|
279
516
|
const headers = parseStringRecord(headersValue, "Headers");
|
|
280
|
-
|
|
281
|
-
type
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
517
|
+
promptValue({
|
|
518
|
+
title: `${mode} ${type} server`,
|
|
519
|
+
label: "Enable OAuth? (yes/no)",
|
|
520
|
+
initialValue: initial?.oauth ? "yes" : "no",
|
|
521
|
+
placeholder: "no",
|
|
522
|
+
note: "Choose yes for servers that use OAuth 2.0/2.1 or dynamic client registration.",
|
|
523
|
+
onSubmit: async (oauthEnabledValue) => {
|
|
524
|
+
const oauthEnabled = parseOptionalBoolean(oauthEnabledValue, "Enable OAuth");
|
|
525
|
+
promptForOAuthDetails(url, headers, oauthEnabled);
|
|
526
|
+
},
|
|
286
527
|
});
|
|
287
|
-
if (initial) {
|
|
288
|
-
mcpConfig.update(name, transport);
|
|
289
|
-
setSuccess(`Updated MCP server "${name}".`);
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
mcpConfig.add(name, transport);
|
|
293
|
-
setSuccess(`Added MCP server "${name}".`);
|
|
294
|
-
}
|
|
295
|
-
setPrompt(null);
|
|
296
|
-
setScreen({ kind: "mcp" });
|
|
297
|
-
refresh();
|
|
298
528
|
},
|
|
299
529
|
});
|
|
300
530
|
},
|
|
@@ -318,10 +548,24 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
318
548
|
},
|
|
319
549
|
});
|
|
320
550
|
}, [promptForRemote, promptForStdio, promptValue]);
|
|
551
|
+
const llmSummary = useCallback((entry) => {
|
|
552
|
+
const compactModelId = (model) => {
|
|
553
|
+
if (model.length <= 23) {
|
|
554
|
+
return model;
|
|
555
|
+
}
|
|
556
|
+
return `${model.slice(0, 10)}...${model.slice(-10)}`;
|
|
557
|
+
};
|
|
558
|
+
const resolved = config.resolveLlm(entry.name);
|
|
559
|
+
if (!resolved) {
|
|
560
|
+
return `${entry.options.provider}/${compactModelId(entry.options.model)}`;
|
|
561
|
+
}
|
|
562
|
+
return `${entry.options.provider} -> ${resolved.options.provider}/${compactModelId(resolved.options.model)}`;
|
|
563
|
+
}, [config]);
|
|
564
|
+
const providerUsageCount = useCallback((name) => config.llms.filter((llm) => llm.options.provider === name).length, [config]);
|
|
321
565
|
const renderHome = () => {
|
|
322
566
|
const items = [
|
|
323
567
|
{
|
|
324
|
-
label: `
|
|
568
|
+
label: `Inference • ${llmSummary(config.llms.find((m) => m.default) ?? config.llms[0])}`,
|
|
325
569
|
value: () => setScreen({ kind: "config" }),
|
|
326
570
|
},
|
|
327
571
|
{
|
|
@@ -392,6 +636,10 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
392
636
|
})(),
|
|
393
637
|
value: () => setScreen({ kind: "config-llms" }),
|
|
394
638
|
},
|
|
639
|
+
{
|
|
640
|
+
label: `Providers • ${config.providers.length} configured`,
|
|
641
|
+
value: () => setScreen({ kind: "config-providers" }),
|
|
642
|
+
},
|
|
395
643
|
{
|
|
396
644
|
label: `Prompts • ${enabledPrompts}/${totalPrompts} enabled`,
|
|
397
645
|
value: () => setScreen({ kind: "config-prompts" }),
|
|
@@ -526,24 +774,194 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
526
774
|
},
|
|
527
775
|
},
|
|
528
776
|
{
|
|
529
|
-
label: `
|
|
530
|
-
value: () =>
|
|
777
|
+
label: `Subagents tool • ${yesNo(configData.tools.agents.enabled)}`,
|
|
778
|
+
value: () => {
|
|
779
|
+
updateConfig({
|
|
780
|
+
tools: {
|
|
781
|
+
...config.tools,
|
|
782
|
+
agents: {
|
|
783
|
+
...config.tools.agents,
|
|
784
|
+
enabled: !configData.tools.agents.enabled,
|
|
785
|
+
},
|
|
786
|
+
},
|
|
787
|
+
}, `Subagents tool ${configData.tools.agents.enabled ? "disabled" : "enabled"}.`);
|
|
788
|
+
setScreen({ kind: "config-tools" });
|
|
789
|
+
},
|
|
790
|
+
},
|
|
791
|
+
{
|
|
792
|
+
label: "Back",
|
|
793
|
+
value: () => setScreen({ kind: "config" }),
|
|
531
794
|
},
|
|
795
|
+
];
|
|
796
|
+
return (_jsx(MenuScreen, { title: "Tools", description: "Enable, disable, and configure built-in tools.", items: items }));
|
|
797
|
+
};
|
|
798
|
+
const renderProvidersMenu = () => {
|
|
799
|
+
const providerItems = config.providers.map((provider) => ({
|
|
800
|
+
key: `provider:${provider.name}`,
|
|
801
|
+
label: `${provider.name} • ${provider.options.provider} • ${providerUsageCount(provider.name)} model(s)`,
|
|
802
|
+
boldSubstring: provider.name,
|
|
803
|
+
value: () => setScreen({ kind: "config-provider-edit", name: provider.name }),
|
|
804
|
+
}));
|
|
805
|
+
const items = [
|
|
532
806
|
{
|
|
533
|
-
label:
|
|
534
|
-
value: () =>
|
|
807
|
+
label: "Add provider",
|
|
808
|
+
value: () => promptValue({
|
|
809
|
+
title: "Add a new provider",
|
|
810
|
+
label: "Name",
|
|
811
|
+
placeholder: "openai-prod",
|
|
812
|
+
onSubmit: async (value) => {
|
|
813
|
+
const name = value.trim();
|
|
814
|
+
if (!name) {
|
|
815
|
+
throw new Error("Name is required.");
|
|
816
|
+
}
|
|
817
|
+
if (config.providers.some((provider) => provider.name === name)) {
|
|
818
|
+
throw new Error(`A provider named "${name}" already exists.`);
|
|
819
|
+
}
|
|
820
|
+
updateConfig({ providers: addProvider(name) }, `Added provider "${name}" with an Ollama scaffold.`);
|
|
821
|
+
setPrompt(null);
|
|
822
|
+
setScreen({ kind: "config-provider-edit", name });
|
|
823
|
+
},
|
|
824
|
+
}),
|
|
535
825
|
},
|
|
826
|
+
...providerItems,
|
|
536
827
|
{
|
|
537
828
|
label: "Back",
|
|
538
829
|
value: () => setScreen({ kind: "config" }),
|
|
539
830
|
},
|
|
540
831
|
];
|
|
541
|
-
return (_jsx(MenuScreen, { title: "
|
|
832
|
+
return (_jsx(MenuScreen, { title: "Providers", description: "Configure reusable provider credentials and shared params.", items: items }));
|
|
833
|
+
};
|
|
834
|
+
const renderProviderEditMenu = () => {
|
|
835
|
+
if (screen.kind !== "config-provider-edit") {
|
|
836
|
+
return null;
|
|
837
|
+
}
|
|
838
|
+
const { name } = screen;
|
|
839
|
+
const entry = config.providers.find((provider) => provider.name === name);
|
|
840
|
+
if (!entry) {
|
|
841
|
+
return null;
|
|
842
|
+
}
|
|
843
|
+
const usageCount = providerUsageCount(entry.name);
|
|
844
|
+
const items = [
|
|
845
|
+
{
|
|
846
|
+
label: `Name • ${entry.name}`,
|
|
847
|
+
value: () => promptValue({
|
|
848
|
+
title: "Rename provider",
|
|
849
|
+
label: "Name",
|
|
850
|
+
initialValue: entry.name,
|
|
851
|
+
onSubmit: async (value) => {
|
|
852
|
+
const next = value.trim();
|
|
853
|
+
if (!next) {
|
|
854
|
+
throw new Error("Name is required.");
|
|
855
|
+
}
|
|
856
|
+
if (next === entry.name) {
|
|
857
|
+
setPrompt(null);
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
860
|
+
if (config.providers.some((provider) => provider.name === next)) {
|
|
861
|
+
throw new Error(`A provider named "${next}" already exists.`);
|
|
862
|
+
}
|
|
863
|
+
updateConfig(renameProvider(entry.name, next), `Renamed provider "${entry.name}" to "${next}".`);
|
|
864
|
+
setPrompt(null);
|
|
865
|
+
setScreen({ kind: "config-provider-edit", name: next });
|
|
866
|
+
},
|
|
867
|
+
}),
|
|
868
|
+
},
|
|
869
|
+
{
|
|
870
|
+
label: `Type • ${entry.options.provider}`,
|
|
871
|
+
value: () => setScreen({ kind: "config-provider-type", name: entry.name }),
|
|
872
|
+
},
|
|
873
|
+
{
|
|
874
|
+
label: `Params • ${paramsPreview(entry.options.params)}`,
|
|
875
|
+
value: () => promptValue({
|
|
876
|
+
title: "Update provider params",
|
|
877
|
+
label: "Parameters",
|
|
878
|
+
initialValue: compactJson(entry.options.params),
|
|
879
|
+
placeholder: '{"apiKey":"..."}',
|
|
880
|
+
onSubmit: async (value) => {
|
|
881
|
+
const params = parseObjectRecord(value, "Provider params");
|
|
882
|
+
updateConfig({ providers: patchProvider(entry.name, { params }) }, "Updated provider params.");
|
|
883
|
+
setPrompt(null);
|
|
884
|
+
},
|
|
885
|
+
}),
|
|
886
|
+
},
|
|
887
|
+
...(usageCount > 0
|
|
888
|
+
? []
|
|
889
|
+
: [
|
|
890
|
+
{
|
|
891
|
+
label: `Delete "${entry.name}"`,
|
|
892
|
+
boldSubstring: entry.name,
|
|
893
|
+
value: () => setScreen({
|
|
894
|
+
kind: "config-provider-delete-confirm",
|
|
895
|
+
name: entry.name,
|
|
896
|
+
}),
|
|
897
|
+
},
|
|
898
|
+
]),
|
|
899
|
+
{
|
|
900
|
+
label: "Back",
|
|
901
|
+
value: () => setScreen({ kind: "config-providers" }),
|
|
902
|
+
},
|
|
903
|
+
];
|
|
904
|
+
return (_jsx(MenuScreen, { title: `Edit Provider • ${entry.name}`, description: usageCount > 0
|
|
905
|
+
? `Used by ${usageCount} model(s). Rename updates references automatically; delete is disabled while in use.`
|
|
906
|
+
: "Edit shared provider settings or delete this provider.", items: items }));
|
|
907
|
+
};
|
|
908
|
+
const renderProviderTypeMenu = () => {
|
|
909
|
+
if (screen.kind !== "config-provider-type") {
|
|
910
|
+
return null;
|
|
911
|
+
}
|
|
912
|
+
const { name } = screen;
|
|
913
|
+
const entry = config.providers.find((provider) => provider.name === name);
|
|
914
|
+
if (!entry) {
|
|
915
|
+
return null;
|
|
916
|
+
}
|
|
917
|
+
const items = [
|
|
918
|
+
...SUPPORTED_PROVIDER_TYPES.map((provider) => ({
|
|
919
|
+
label: provider === entry.options.provider
|
|
920
|
+
? `${provider} • current`
|
|
921
|
+
: provider,
|
|
922
|
+
value: () => {
|
|
923
|
+
updateConfig({
|
|
924
|
+
providers: patchProvider(entry.name, {
|
|
925
|
+
provider,
|
|
926
|
+
params: providerParamsTemplate(provider),
|
|
927
|
+
}),
|
|
928
|
+
}, `Updated provider type for "${entry.name}" to "${provider}" and scaffolded params.`);
|
|
929
|
+
setScreen({ kind: "config-provider-edit", name: entry.name });
|
|
930
|
+
},
|
|
931
|
+
})),
|
|
932
|
+
{
|
|
933
|
+
label: "Back",
|
|
934
|
+
value: () => setScreen({ kind: "config-provider-edit", name: entry.name }),
|
|
935
|
+
},
|
|
936
|
+
];
|
|
937
|
+
return (_jsx(MenuScreen, { title: `Choose Provider Type • ${entry.name}`, description: "Pick which runtime provider this shared config targets.", items: items }));
|
|
938
|
+
};
|
|
939
|
+
const renderProviderDeleteConfirm = () => {
|
|
940
|
+
if (screen.kind !== "config-provider-delete-confirm") {
|
|
941
|
+
return null;
|
|
942
|
+
}
|
|
943
|
+
const { name } = screen;
|
|
944
|
+
const items = [
|
|
945
|
+
{
|
|
946
|
+
key: `provider-del-cancel:${name}`,
|
|
947
|
+
label: "No — keep provider",
|
|
948
|
+
value: () => setScreen({ kind: "config-provider-edit", name }),
|
|
949
|
+
},
|
|
950
|
+
{
|
|
951
|
+
key: `provider-del-confirm:${name}`,
|
|
952
|
+
label: "Yes — remove provider",
|
|
953
|
+
value: () => {
|
|
954
|
+
updateConfig({ providers: removeProvider(name) }, `Deleted provider "${name}".`);
|
|
955
|
+
setScreen({ kind: "config-providers" });
|
|
956
|
+
},
|
|
957
|
+
},
|
|
958
|
+
];
|
|
959
|
+
return (_jsx(MenuScreen, { title: "Delete provider?", description: `Remove "${name}" from the configured providers?`, items: items }));
|
|
542
960
|
};
|
|
543
961
|
const renderLlmsMenu = () => {
|
|
544
962
|
const llmItems = config.llms.map((m) => ({
|
|
545
963
|
key: `llm:${m.name}`,
|
|
546
|
-
label: `${m.name} • ${m
|
|
964
|
+
label: `${m.name} • ${llmSummary(m)}${m.default ? " • default" : ""}`,
|
|
547
965
|
boldSubstring: m.name,
|
|
548
966
|
value: () => setScreen({ kind: "config-llm-edit", name: m.name }),
|
|
549
967
|
}));
|
|
@@ -562,6 +980,9 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
562
980
|
if (config.llms.some((m) => m.name === name)) {
|
|
563
981
|
throw new Error(`An LLM named "${name}" already exists.`);
|
|
564
982
|
}
|
|
983
|
+
if (config.providers.length === 0) {
|
|
984
|
+
throw new Error("Add at least one provider first so the model can reference it.");
|
|
985
|
+
}
|
|
565
986
|
updateConfig({ llms: addLlm(name) }, `Added LLM "${name}".`);
|
|
566
987
|
setPrompt(null);
|
|
567
988
|
setScreen({ kind: "config-llm-edit", name });
|
|
@@ -633,7 +1054,7 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
633
1054
|
}),
|
|
634
1055
|
},
|
|
635
1056
|
{
|
|
636
|
-
label: `Params • ${
|
|
1057
|
+
label: `Params • ${paramsPreview(entry.options.params)}`,
|
|
637
1058
|
value: () => promptValue({
|
|
638
1059
|
title: "Update LLM params",
|
|
639
1060
|
label: "Parameters",
|
|
@@ -688,12 +1109,12 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
688
1109
|
return null;
|
|
689
1110
|
}
|
|
690
1111
|
const items = [
|
|
691
|
-
...
|
|
692
|
-
label: provider === entry.options.provider
|
|
693
|
-
? `${provider} • current`
|
|
694
|
-
: provider
|
|
1112
|
+
...config.providers.map((provider) => ({
|
|
1113
|
+
label: provider.name === entry.options.provider
|
|
1114
|
+
? `${provider.name} • current`
|
|
1115
|
+
: `${provider.name} • ${provider.options.provider}`,
|
|
695
1116
|
value: () => {
|
|
696
|
-
updateConfig({ llms: patchLlm(entry.name, { provider }) }, `Updated provider for "${entry.name}" to "${provider}".`);
|
|
1117
|
+
updateConfig({ llms: patchLlm(entry.name, { provider: provider.name }) }, `Updated provider for "${entry.name}" to "${provider.name}".`);
|
|
697
1118
|
setScreen({ kind: "config-llm-edit", name: entry.name });
|
|
698
1119
|
},
|
|
699
1120
|
})),
|
|
@@ -702,7 +1123,7 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
702
1123
|
value: () => setScreen({ kind: "config-llm-edit", name: entry.name }),
|
|
703
1124
|
},
|
|
704
1125
|
];
|
|
705
|
-
return (_jsx(MenuScreen, { title: `Choose Provider • ${entry.name}`, description: "Pick which
|
|
1126
|
+
return (_jsx(MenuScreen, { title: `Choose Provider • ${entry.name}`, description: "Pick which shared provider config this LLM should use.", items: items }));
|
|
706
1127
|
};
|
|
707
1128
|
const renderLlmDeleteConfirm = () => {
|
|
708
1129
|
if (screen.kind !== "config-llm-delete-confirm") {
|
|
@@ -828,209 +1249,18 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
828
1249
|
];
|
|
829
1250
|
return (_jsx(MenuScreen, { title: "Search", description: "Configure web search provider and credentials.", items: items }));
|
|
830
1251
|
};
|
|
831
|
-
const renderLtmConfigMenu = () => {
|
|
832
|
-
const items = [
|
|
833
|
-
{
|
|
834
|
-
label: `Enabled • ${yesNo(configData.tools.memory.enabled)}`,
|
|
835
|
-
value: () => {
|
|
836
|
-
updateConfig({
|
|
837
|
-
tools: {
|
|
838
|
-
...config.tools,
|
|
839
|
-
memory: {
|
|
840
|
-
...config.tools.memory,
|
|
841
|
-
enabled: !configData.tools.memory.enabled,
|
|
842
|
-
},
|
|
843
|
-
},
|
|
844
|
-
}, `Memory tool ${configData.tools.memory.enabled ? "disabled" : "enabled"}.`);
|
|
845
|
-
setScreen({ kind: "config-ltm" });
|
|
846
|
-
},
|
|
847
|
-
},
|
|
848
|
-
{
|
|
849
|
-
label: "Back",
|
|
850
|
-
value: () => setScreen({ kind: "config-tools" }),
|
|
851
|
-
},
|
|
852
|
-
];
|
|
853
|
-
return (_jsx(MenuScreen, { title: "Memory tool", description: "Vectors live in ~/.hooman/memory.sqlite (sqlite-vec). Embedding model is fixed in code (DEFAULT_EMBED_MODEL).", items: items }));
|
|
854
|
-
};
|
|
855
|
-
const renderWikiConfigMenu = () => {
|
|
856
|
-
const items = [
|
|
857
|
-
{
|
|
858
|
-
label: `Tool • ${yesNo(configData.tools.wiki.enabled)}`,
|
|
859
|
-
value: () => {
|
|
860
|
-
updateConfig({
|
|
861
|
-
tools: {
|
|
862
|
-
...config.tools,
|
|
863
|
-
wiki: {
|
|
864
|
-
...config.tools.wiki,
|
|
865
|
-
enabled: !configData.tools.wiki.enabled,
|
|
866
|
-
},
|
|
867
|
-
},
|
|
868
|
-
}, `Wiki tool ${configData.tools.wiki.enabled ? "disabled" : "enabled"}.`);
|
|
869
|
-
setScreen({ kind: "config-wiki" });
|
|
870
|
-
},
|
|
871
|
-
},
|
|
872
|
-
{
|
|
873
|
-
label: "Manage documents",
|
|
874
|
-
value: () => setScreen({ kind: "config-wiki-docs", page: 1 }),
|
|
875
|
-
},
|
|
876
|
-
{
|
|
877
|
-
label: "Back",
|
|
878
|
-
value: () => setScreen({ kind: "config-tools" }),
|
|
879
|
-
},
|
|
880
|
-
];
|
|
881
|
-
return (_jsx(MenuScreen, { title: "Tool", description: "Turn wiki_search on or off for the agent, then open Manage documents to add or remove PDF/DOCX files under ~/.hooman/wiki. Embedding may download the model on first use.", items: items }));
|
|
882
|
-
};
|
|
883
|
-
const renderWikiDocsMenu = () => {
|
|
884
|
-
if (screen.kind !== "config-wiki-docs") {
|
|
885
|
-
return null;
|
|
886
|
-
}
|
|
887
|
-
const { page } = screen;
|
|
888
|
-
if (wikiDocsList.status === "loading" || wikiDocsList.status === "idle") {
|
|
889
|
-
return _jsx(BusyScreen, { message: "Loading documents\u2026" });
|
|
890
|
-
}
|
|
891
|
-
if (wikiDocsList.status === "error") {
|
|
892
|
-
return (_jsx(MenuScreen, { title: "Manage documents", description: `Could not load index: ${wikiDocsList.message}`, items: [
|
|
893
|
-
{
|
|
894
|
-
label: "Retry",
|
|
895
|
-
value: () => bumpWikiDocs(),
|
|
896
|
-
},
|
|
897
|
-
{
|
|
898
|
-
label: "Back",
|
|
899
|
-
value: () => setScreen({ kind: "config-wiki" }),
|
|
900
|
-
},
|
|
901
|
-
] }));
|
|
902
|
-
}
|
|
903
|
-
if (wikiDocsList.page !== page) {
|
|
904
|
-
return _jsx(BusyScreen, { message: "Loading documents\u2026" });
|
|
905
|
-
}
|
|
906
|
-
const { result } = wikiDocsList;
|
|
907
|
-
const totalPages = Math.max(1, Math.ceil(result.total / WIKI_DOCS_PAGE_SIZE));
|
|
908
|
-
const hasPrev = page > 1;
|
|
909
|
-
const hasNext = page < totalPages;
|
|
910
|
-
const formatUpdated = (ms) => {
|
|
911
|
-
try {
|
|
912
|
-
return new Date(ms).toLocaleString(undefined, {
|
|
913
|
-
dateStyle: "short",
|
|
914
|
-
timeStyle: "short",
|
|
915
|
-
});
|
|
916
|
-
}
|
|
917
|
-
catch {
|
|
918
|
-
return String(ms);
|
|
919
|
-
}
|
|
920
|
-
};
|
|
921
|
-
const docItems = result.items.map((doc) => {
|
|
922
|
-
const summary = truncate(`${doc.file_name} • ${formatUpdated(doc.updated_at_ms)} • ${doc.original_mime_type}`, 96);
|
|
923
|
-
return {
|
|
924
|
-
key: `wiki-remove:${doc.doc_id}`,
|
|
925
|
-
label: `Remove • ${summary}`,
|
|
926
|
-
boldSubstring: doc.file_name,
|
|
927
|
-
value: () => setScreen({
|
|
928
|
-
kind: "config-wiki-delete-confirm",
|
|
929
|
-
docId: doc.doc_id,
|
|
930
|
-
displayName: doc.file_name,
|
|
931
|
-
page,
|
|
932
|
-
}),
|
|
933
|
-
};
|
|
934
|
-
});
|
|
935
|
-
const items = [
|
|
936
|
-
{
|
|
937
|
-
label: "Add document (file path)",
|
|
938
|
-
value: () => promptValue({
|
|
939
|
-
title: "Index a file into the wiki",
|
|
940
|
-
label: "Absolute path",
|
|
941
|
-
placeholder: "/path/to/document.pdf",
|
|
942
|
-
note: "Only PDF and DOCX are supported (PDF needs Java 11+ for OpenDataLoader).",
|
|
943
|
-
onSubmit: async (value) => {
|
|
944
|
-
const raw = value.trim();
|
|
945
|
-
if (!raw) {
|
|
946
|
-
throw new Error("Path is required.");
|
|
947
|
-
}
|
|
948
|
-
const abs = path.resolve(raw);
|
|
949
|
-
if (!existsSync(abs)) {
|
|
950
|
-
throw new Error(`File not found: ${abs}`);
|
|
951
|
-
}
|
|
952
|
-
setPrompt(null);
|
|
953
|
-
await runTask(`Indexing "${path.basename(abs)}"…`, async () => {
|
|
954
|
-
const storage = Storage.create();
|
|
955
|
-
try {
|
|
956
|
-
await storage.warmup();
|
|
957
|
-
await storage.add({ filePath: abs });
|
|
958
|
-
}
|
|
959
|
-
finally {
|
|
960
|
-
await storage.close();
|
|
961
|
-
}
|
|
962
|
-
bumpWikiDocs();
|
|
963
|
-
setSuccess(`Indexed "${path.basename(abs)}".`);
|
|
964
|
-
});
|
|
965
|
-
setScreen({ kind: "config-wiki-docs", page: 1 });
|
|
966
|
-
},
|
|
967
|
-
}),
|
|
968
|
-
},
|
|
969
|
-
...docItems,
|
|
970
|
-
...(hasPrev
|
|
971
|
-
? [
|
|
972
|
-
{
|
|
973
|
-
label: "Previous page",
|
|
974
|
-
value: () => setScreen({ kind: "config-wiki-docs", page: page - 1 }),
|
|
975
|
-
},
|
|
976
|
-
]
|
|
977
|
-
: []),
|
|
978
|
-
...(hasNext
|
|
979
|
-
? [
|
|
980
|
-
{
|
|
981
|
-
label: "Next page",
|
|
982
|
-
value: () => setScreen({ kind: "config-wiki-docs", page: page + 1 }),
|
|
983
|
-
},
|
|
984
|
-
]
|
|
985
|
-
: []),
|
|
986
|
-
{
|
|
987
|
-
label: "Back",
|
|
988
|
-
value: () => setScreen({ kind: "config-wiki" }),
|
|
989
|
-
},
|
|
990
|
-
];
|
|
991
|
-
return (_jsx(MenuScreen, { title: `Manage documents · page ${page} of ${totalPages}`, description: result.items.length === 0
|
|
992
|
-
? "No documents yet. Add a PDF or DOCX path below (PDF needs Java 11+ on PATH)."
|
|
993
|
-
: `${result.total} document(s) total · ${result.items.length} on this page.`, items: items }));
|
|
994
|
-
};
|
|
995
|
-
const renderWikiDeleteConfirm = () => {
|
|
996
|
-
if (screen.kind !== "config-wiki-delete-confirm") {
|
|
997
|
-
return null;
|
|
998
|
-
}
|
|
999
|
-
const { docId, displayName, page } = screen;
|
|
1000
|
-
const items = [
|
|
1001
|
-
{
|
|
1002
|
-
key: `wiki-del-cancel:${docId}`,
|
|
1003
|
-
label: "No — keep document",
|
|
1004
|
-
value: () => setScreen({ kind: "config-wiki-docs", page }),
|
|
1005
|
-
},
|
|
1006
|
-
{
|
|
1007
|
-
key: `wiki-del-confirm:${docId}`,
|
|
1008
|
-
label: "Yes — remove from index",
|
|
1009
|
-
value: () => void runTask(`Removing "${displayName}"…`, async () => {
|
|
1010
|
-
const storage = Storage.create();
|
|
1011
|
-
try {
|
|
1012
|
-
await storage.warmup();
|
|
1013
|
-
const ok = await storage.remove(docId);
|
|
1014
|
-
if (!ok) {
|
|
1015
|
-
throw new Error("Document was already removed.");
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
finally {
|
|
1019
|
-
await storage.close();
|
|
1020
|
-
}
|
|
1021
|
-
bumpWikiDocs();
|
|
1022
|
-
setSuccess(`Removed "${displayName}" from the wiki index.`);
|
|
1023
|
-
setScreen({ kind: "config-wiki-docs", page });
|
|
1024
|
-
}),
|
|
1025
|
-
},
|
|
1026
|
-
];
|
|
1027
|
-
return (_jsx(MenuScreen, { title: "Remove wiki document?", description: `Drop "${displayName}" from the index and delete its stored copies under ~/.hooman/wiki? This cannot be undone.`, items: items }));
|
|
1028
|
-
};
|
|
1029
1252
|
const renderMcpMenu = () => {
|
|
1030
|
-
const serverItems = mcpServers.
|
|
1031
|
-
|
|
1032
|
-
|
|
1253
|
+
const serverItems = mcpServers.map((server) => {
|
|
1254
|
+
const oauthStatus = mcpAuthStatuses[server.name];
|
|
1255
|
+
return {
|
|
1256
|
+
key: `mcp-server:${server.name}`,
|
|
1257
|
+
label: `Edit ${server.name} • ${formatMcpServerLabel(server.transport, oauthStatus)}`,
|
|
1033
1258
|
boldSubstring: server.name,
|
|
1259
|
+
oauthStatus: oauthStatus === "authenticated" ||
|
|
1260
|
+
oauthStatus === "expired" ||
|
|
1261
|
+
oauthStatus === "unauthenticated"
|
|
1262
|
+
? oauthStatus
|
|
1263
|
+
: undefined,
|
|
1034
1264
|
value: () => {
|
|
1035
1265
|
if (server.transport.type === "stdio") {
|
|
1036
1266
|
promptForStdio(server.name, server.transport);
|
|
@@ -1039,13 +1269,8 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
1039
1269
|
promptForRemote(server.name, server.transport.type, server.transport);
|
|
1040
1270
|
}
|
|
1041
1271
|
},
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
label: `Delete ${server.name}`,
|
|
1045
|
-
boldSubstring: server.name,
|
|
1046
|
-
value: () => setScreen({ kind: "mcp-delete-confirm", name: server.name }),
|
|
1047
|
-
},
|
|
1048
|
-
]);
|
|
1272
|
+
};
|
|
1273
|
+
});
|
|
1049
1274
|
const items = [
|
|
1050
1275
|
{
|
|
1051
1276
|
label: "Add stdio server",
|
|
@@ -1073,7 +1298,29 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
1073
1298
|
value: () => setScreen({ kind: "home" }),
|
|
1074
1299
|
},
|
|
1075
1300
|
];
|
|
1076
|
-
return (_jsx(MenuScreen, { title: "MCP Servers", description: "Add, edit, or remove named MCP transports from ~/.hooman/mcp.json.", items: items
|
|
1301
|
+
return (_jsx(MenuScreen, { title: "MCP Servers", description: "Add, edit, or remove named MCP transports from ~/.hooman/mcp.json.", items: items, footerHint: (item) => formatMcpFooterHint(item, mcpServers, mcpAuthStatuses), onShortcut: async (input, item) => {
|
|
1302
|
+
const server = findMcpServerFromMenuItem(item, mcpServers);
|
|
1303
|
+
if (!server) {
|
|
1304
|
+
return;
|
|
1305
|
+
}
|
|
1306
|
+
const status = mcpAuthStatuses[server.name];
|
|
1307
|
+
const key = input.toLowerCase();
|
|
1308
|
+
if (key === "d") {
|
|
1309
|
+
setScreen({ kind: "mcp-delete-confirm", name: server.name });
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
if (key === "r" &&
|
|
1313
|
+
server.transport.type !== "stdio" &&
|
|
1314
|
+
status !== "unsupported") {
|
|
1315
|
+
await authenticateMcpServer(server.name);
|
|
1316
|
+
return;
|
|
1317
|
+
}
|
|
1318
|
+
if (key === "l" &&
|
|
1319
|
+
server.transport.type !== "stdio" &&
|
|
1320
|
+
(status === "authenticated" || status === "expired")) {
|
|
1321
|
+
await logoutMcpServer(server.name);
|
|
1322
|
+
}
|
|
1323
|
+
} }));
|
|
1077
1324
|
};
|
|
1078
1325
|
const renderSkillsMenu = () => {
|
|
1079
1326
|
const skillItems = installedSkills.map((skill) => {
|
|
@@ -1094,7 +1341,7 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
1094
1341
|
value: () => promptValue({
|
|
1095
1342
|
title: "Search skills catalog",
|
|
1096
1343
|
label: "Query",
|
|
1097
|
-
placeholder: "
|
|
1344
|
+
placeholder: "github, playwright, slack...",
|
|
1098
1345
|
onSubmit: async (value) => {
|
|
1099
1346
|
const query = value.trim();
|
|
1100
1347
|
if (query.length < 2) {
|
|
@@ -1239,6 +1486,14 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
1239
1486
|
return renderHome();
|
|
1240
1487
|
case "config":
|
|
1241
1488
|
return renderConfigMenu();
|
|
1489
|
+
case "config-providers":
|
|
1490
|
+
return renderProvidersMenu();
|
|
1491
|
+
case "config-provider-edit":
|
|
1492
|
+
return renderProviderEditMenu();
|
|
1493
|
+
case "config-provider-type":
|
|
1494
|
+
return renderProviderTypeMenu();
|
|
1495
|
+
case "config-provider-delete-confirm":
|
|
1496
|
+
return renderProviderDeleteConfirm();
|
|
1242
1497
|
case "config-llms":
|
|
1243
1498
|
return renderLlmsMenu();
|
|
1244
1499
|
case "config-llm-edit":
|
|
@@ -1255,14 +1510,6 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
1255
1510
|
return renderSearchConfigMenu();
|
|
1256
1511
|
case "config-search-provider":
|
|
1257
1512
|
return renderSearchProviderMenu();
|
|
1258
|
-
case "config-ltm":
|
|
1259
|
-
return renderLtmConfigMenu();
|
|
1260
|
-
case "config-wiki":
|
|
1261
|
-
return renderWikiConfigMenu();
|
|
1262
|
-
case "config-wiki-docs":
|
|
1263
|
-
return renderWikiDocsMenu();
|
|
1264
|
-
case "config-wiki-delete-confirm":
|
|
1265
|
-
return renderWikiDeleteConfirm();
|
|
1266
1513
|
case "mcp":
|
|
1267
1514
|
return renderMcpMenu();
|
|
1268
1515
|
case "mcp-delete-confirm":
|
|
@@ -1277,6 +1524,37 @@ export function ConfigureApp({ config, mcpConfig, skills, onExit, }) {
|
|
|
1277
1524
|
return null;
|
|
1278
1525
|
}
|
|
1279
1526
|
})();
|
|
1280
|
-
return (_jsxs(Box, { flexDirection: "column", width: "100%", paddingX: 1, children: [notice ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: noticeColor(notice.kind), children: notice.text }) })) : null, _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: `
|
|
1527
|
+
return (_jsxs(Box, { flexDirection: "column", width: "100%", paddingX: 1, children: [notice ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: noticeColor(notice.kind), children: notice.text }) })) : null, _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: `inference: ${llmSummary(config.llms.find((m) => m.default) ?? config.llms[0])} • mcp: ${mcpServers.length} • skills: ${installedSkills.length}` }) }), body] }));
|
|
1528
|
+
}
|
|
1529
|
+
function formatMcpServerLabel(transport, status) {
|
|
1530
|
+
const summary = transportSummary(transport);
|
|
1531
|
+
if ((status === "expired" || status === "unauthenticated") &&
|
|
1532
|
+
summary.endsWith(" • oauth")) {
|
|
1533
|
+
return `${summary.slice(0, -" • oauth".length)} • oauth needed`;
|
|
1534
|
+
}
|
|
1535
|
+
return summary;
|
|
1536
|
+
}
|
|
1537
|
+
function findMcpServerFromMenuItem(item, servers) {
|
|
1538
|
+
if (!item?.key?.startsWith("mcp-server:")) {
|
|
1539
|
+
return null;
|
|
1540
|
+
}
|
|
1541
|
+
const serverName = item.key.slice("mcp-server:".length);
|
|
1542
|
+
return servers.find((server) => server.name === serverName) ?? null;
|
|
1543
|
+
}
|
|
1544
|
+
function formatMcpFooterHint(item, servers, statuses) {
|
|
1545
|
+
const server = findMcpServerFromMenuItem(item, servers);
|
|
1546
|
+
const status = server ? statuses[server.name] : undefined;
|
|
1547
|
+
const parts = ["enter: edit"];
|
|
1548
|
+
if (server && server.transport.type !== "stdio" && status !== "unsupported") {
|
|
1549
|
+
parts.push(status === "authenticated" ? "r: re-auth" : "r: authenticate");
|
|
1550
|
+
if (status === "authenticated" || status === "expired") {
|
|
1551
|
+
parts.push("l: logout");
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
if (server) {
|
|
1555
|
+
parts.push("d: delete");
|
|
1556
|
+
}
|
|
1557
|
+
parts.push("esc: back", "ctrl+c: exit");
|
|
1558
|
+
return parts.join(" | ");
|
|
1281
1559
|
}
|
|
1282
1560
|
//# sourceMappingURL=app.js.map
|