@agentdocumentformat/cli 0.7.8 → 0.8.1
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 +1 -1
- package/dist/adf.mjs +59 -8
- package/dist/chunks/{APEv2Parser-2CNNHMXV.mjs → APEv2Parser-WIXRJLHB.mjs} +2 -2
- package/dist/chunks/{AiffParser-7BR4RL6G.mjs → AiffParser-ZC4QFOVJ.mjs} +5 -5
- package/dist/chunks/{App-7RIIOHJJ.mjs → App-4AZZJNN2.mjs} +917 -826
- package/dist/chunks/{DsdiffParser-CMD4AX7A.mjs → DsdiffParser-UAPAJHFX.mjs} +5 -5
- package/dist/chunks/{DsfParser-UOGZDS2M.mjs → DsfParser-NNYZK2QX.mjs} +6 -6
- package/dist/chunks/{FlacParser-HB3T3CD4.mjs → FlacParser-MW2W4LO3.mjs} +6 -6
- package/dist/chunks/{MP4Parser-66HBRUSX.mjs → MP4Parser-Z57SYOOQ.mjs} +4 -4
- package/dist/chunks/{MpegParser-YW6LIUEW.mjs → MpegParser-XIIPAZVM.mjs} +7 -7
- package/dist/chunks/{MusepackParser-PAUSXP7D.mjs → MusepackParser-QWNDEYHJ.mjs} +6 -6
- package/dist/chunks/{OggParser-NUBV3GWC.mjs → OggParser-WRX53F77.mjs} +9 -9
- package/dist/chunks/{WavPackParser-WQAGT7TC.mjs → WavPackParser-MJ7WCSJ5.mjs} +2 -2
- package/dist/chunks/{WaveParser-EWLQVDX4.mjs → WaveParser-RAVLHZ5S.mjs} +7 -7
- package/dist/chunks/{adf-schema-US4NFHMR.mjs → adf-schema-AIPBQTR2.mjs} +9 -3
- package/dist/chunks/auth-manager-AJ32FZWS.mjs +19 -0
- package/dist/chunks/auth-manager-C5OBEQK2.mjs +18 -0
- package/dist/chunks/auth-manager-TBNKCJ45.mjs +17 -0
- package/dist/chunks/{chatgpt-subscription-E4MXTIAT.mjs → chatgpt-subscription-MMGNW5KJ.mjs} +5 -2
- package/dist/chunks/chunk-2Z7X3UUR.mjs +678 -0
- package/dist/chunks/chunk-3UGZFWIF.mjs +26 -0
- package/dist/chunks/{chunk-XNPZBLYL.mjs → chunk-75DC5EWN.mjs} +13 -2
- package/dist/chunks/{chunk-5PO5PKRV.mjs → chunk-7JZXMDDF.mjs} +158 -67
- package/dist/chunks/chunk-AEAJDCVK.mjs +517 -0
- package/dist/chunks/{chunk-6VQEXLE2.mjs → chunk-BHY7QDCM.mjs} +41 -3
- package/dist/chunks/{chunk-CD3ATSXE.mjs → chunk-BR3AD5QZ.mjs} +8 -2
- package/dist/chunks/chunk-BS3USVEA.mjs +301 -0
- package/dist/chunks/chunk-C2S64Y6F.mjs +203 -0
- package/dist/chunks/chunk-D7A77SNL.mjs +976 -0
- package/dist/chunks/chunk-DDTTSKGG.mjs +2443 -0
- package/dist/chunks/{chunk-VAUOM3IN.mjs → chunk-DLWCKKIO.mjs} +1 -1
- package/dist/chunks/{chunk-G6PH7RPW.mjs → chunk-E7LC6SHP.mjs} +3 -3
- package/dist/chunks/{chunk-ZESQMP66.mjs → chunk-F3WSCAJD.mjs} +3 -3
- package/dist/chunks/{chunk-KXEF4F4E.mjs → chunk-GAZO6UMI.mjs} +1 -1
- package/dist/chunks/{chunk-XYTWGHFS.mjs → chunk-H3XLRWVE.mjs} +1 -1
- package/dist/chunks/{chunk-7T2YMTWL.mjs → chunk-H4C65MTP.mjs} +4 -4
- package/dist/chunks/chunk-HBOFZRUS.mjs +738 -0
- package/dist/chunks/{chunk-VN7UH7I5.mjs → chunk-IMVMSU3A.mjs} +251 -68
- package/dist/chunks/{chunk-XYV3VCIX.mjs → chunk-JZFONJSL.mjs} +79 -20
- package/dist/chunks/chunk-KCIRFUZH.mjs +12799 -0
- package/dist/chunks/chunk-KDDVQKCG.mjs +65 -0
- package/dist/chunks/chunk-KRPKWOMB.mjs +290 -0
- package/dist/chunks/chunk-LKFHERRV.mjs +145 -0
- package/dist/chunks/chunk-LTX74NU6.mjs +29 -0
- package/dist/chunks/{chunk-HSBV6YFU.mjs → chunk-LVF2DRBR.mjs} +634 -99
- package/dist/chunks/chunk-M2F7C2UJ.mjs +425 -0
- package/dist/chunks/{chunk-62NE4LG4.mjs → chunk-MQAMI5BF.mjs} +5 -5
- package/dist/chunks/chunk-MZRXFWPQ.mjs +278 -0
- package/dist/chunks/{chunk-PRMGZZM5.mjs → chunk-NZLEPJ5M.mjs} +2 -0
- package/dist/chunks/{chunk-I3UYSITV.mjs → chunk-O7XKQ6CH.mjs} +1 -1
- package/dist/chunks/chunk-P3RG5LQA.mjs +244 -0
- package/dist/chunks/chunk-PAK5JCO2.mjs +48 -0
- package/dist/chunks/chunk-PC63YFB7.mjs +34 -0
- package/dist/chunks/{daemon-control-HKFVSQTQ.mjs → chunk-RHBGCOS3.mjs} +67 -26
- package/dist/chunks/{chunk-J74STFKE.mjs → chunk-RJDOVMM4.mjs} +362 -58
- package/dist/chunks/{chunk-QPLEAE6V.mjs → chunk-SOSPQPEN.mjs} +167 -650
- package/dist/chunks/{chunk-LFMB4PAA.mjs → chunk-TKXIH27X.mjs} +974 -113
- package/dist/chunks/{chunk-5W7KES6P.mjs → chunk-UZPDETEU.mjs} +1 -1
- package/dist/chunks/chunk-V3MM6PCH.mjs +366 -0
- package/dist/chunks/chunk-VENQBMOA.mjs +62 -0
- package/dist/chunks/chunk-WJGPNHGX.mjs +67 -0
- package/dist/chunks/{chunk-Y5ZLKFLE.mjs → chunk-XNNJQCZP.mjs} +196 -165
- package/dist/chunks/{chunk-HDBPBORT.mjs → chunk-YRBFIDLB.mjs} +46 -10
- package/dist/chunks/{chunk-BNXUAOO4.mjs → chunk-ZGXUOAWZ.mjs} +3186 -959
- package/dist/chunks/chunk-ZPB3HYM7.mjs +45 -0
- package/dist/chunks/claude-subscription-EB4LAAVV.mjs +29 -0
- package/dist/chunks/{cli-NMFIAR7Z.mjs → cli-PCVFB6B4.mjs} +797 -56
- package/dist/chunks/{commands-KPJWFRUE.mjs → commands-KOMPXJZS.mjs} +4 -3
- package/dist/chunks/{daemon-YDIK3AAM.mjs → daemon-BVDB565V.mjs} +83142 -64424
- package/dist/chunks/daemon-control-MKN7G5M3.mjs +59 -0
- package/dist/chunks/{daemon-token-WRSULP7G.mjs → daemon-token-L5QKTHU5.mjs} +3 -1
- package/dist/chunks/{discord-DSP4HUWI.mjs → discord-IR62565M.mjs} +3 -52
- package/dist/chunks/{email-BRG7KUO2.mjs → email-KHHTJBDW.mjs} +4 -2
- package/dist/chunks/{grok-subscription-4PYX7TBF.mjs → grok-subscription-E74FS5EG.mjs} +5 -2
- package/dist/chunks/{layout-EPJQNFAI.mjs → layout-ECWGJF6M.mjs} +2 -2
- package/dist/chunks/{lib-N7FCZWKH.mjs → lib-L27L5PXM.mjs} +22 -22
- package/dist/chunks/{open-VAU7PXT6.mjs → open-3OR6WT4T.mjs} +6 -6
- package/dist/chunks/{parser-JVY2PWSM.mjs → parser-7GARNT5L.mjs} +1 -1
- package/dist/chunks/{pipeline-executor-O77NTGLP.mjs → pipeline-executor-DRYEEFDR.mjs} +6 -5
- package/dist/chunks/prompt-RRHZX4YT.mjs +13 -0
- package/dist/chunks/remote-access-cli-GLEEP7DI.mjs +268 -0
- package/dist/chunks/remote-hello-UFWUBDQI.mjs +37 -0
- package/dist/chunks/sdk-OJOAF4DP.mjs +30014 -0
- package/dist/chunks/{slack-OCNNF4DX.mjs → slack-IYC5RAB5.mjs} +3 -4
- package/dist/chunks/{store-HUVDJPYN.mjs → store-55CQSAOX.mjs} +7 -3
- package/dist/chunks/tailscale-WLJATFMB.mjs +25 -0
- package/dist/chunks/{theme-SFE3JMA2.mjs → theme-HLBDTF6F.mjs} +1 -1
- package/dist/chunks/{themes-YLXLOIJF.mjs → themes-BQ72P446.mjs} +2 -2
- package/dist/chunks/{token-6G3HCMNX.mjs → token-6D22WECM.mjs} +20 -16
- package/dist/chunks/{token-util-UXYSDQIW.mjs → token-util-YF3ZWBZ4.mjs} +1 -2
- package/dist/chunks/{tui-UQJLK7XI.mjs → tui-RAUVFOYY.mjs} +21 -18
- package/dist/chunks/{welcome-XHXFV7SH.mjs → welcome-J5JZZAM5.mjs} +1 -1
- package/dist/chunks/{whatsapp-AJMRQBT7.mjs → whatsapp-YJFFVN4Q.mjs} +9 -9
- package/package.json +1 -1
- package/dist/chunks/chunk-GKKCMXIZ.mjs +0 -94
- package/dist/chunks/chunk-IHDDCZBS.mjs +0 -112
- package/dist/chunks/chunk-KWFOS5WC.mjs +0 -41
- package/dist/chunks/chunk-UEZR2CNS.mjs +0 -65
- package/dist/chunks/chunk-VMHTYDH4.mjs +0 -172
- package/dist/chunks/chunk-Y2QA53AN.mjs +0 -259
- package/dist/chunks/{chunk-NBTUWMGP.mjs → chunk-2MTE22CR.mjs} +3 -3
- package/dist/chunks/{chunk-APRU6PHC.mjs → chunk-JZ7AQNPM.mjs} +3 -3
- package/dist/chunks/{telegram-2EFGKIVK.mjs → telegram-JYY2VDTI.mjs} +5 -5
|
@@ -4,385 +4,163 @@ import { dirname as __adfDirname } from 'node:path';
|
|
|
4
4
|
const require = __adfCreateRequire(import.meta.url);
|
|
5
5
|
const __filename = __adfFileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = __adfDirname(__filename);
|
|
7
|
-
import {
|
|
8
|
-
require_jsx_runtime
|
|
9
|
-
} from "./chunk-7CV2SA3H.mjs";
|
|
10
|
-
import {
|
|
11
|
-
WELCOME_OVERLAY
|
|
12
|
-
} from "./chunk-I3UYSITV.mjs";
|
|
13
|
-
import {
|
|
14
|
-
cjs
|
|
15
|
-
} from "./chunk-SGUTYISF.mjs";
|
|
16
|
-
import {
|
|
17
|
-
mcp_config_exports
|
|
18
|
-
} from "./chunk-VMHTYDH4.mjs";
|
|
19
|
-
import {
|
|
20
|
-
Box_default,
|
|
21
|
-
Text
|
|
22
|
-
} from "./chunk-3AT7IIP7.mjs";
|
|
23
|
-
import {
|
|
24
|
-
useTheme
|
|
25
|
-
} from "./chunk-PRMGZZM5.mjs";
|
|
26
|
-
import {
|
|
27
|
-
require_react
|
|
28
|
-
} from "./chunk-6GJ4QHRI.mjs";
|
|
29
|
-
import {
|
|
30
|
-
adapter_registry_exports
|
|
31
|
-
} from "./chunk-UYY5M2PB.mjs";
|
|
32
7
|
import {
|
|
33
8
|
external_exports
|
|
34
9
|
} from "./chunk-ZJKXHM4Q.mjs";
|
|
35
10
|
import {
|
|
36
|
-
__export
|
|
37
|
-
__toESM
|
|
11
|
+
__export
|
|
38
12
|
} from "./chunk-M2RX3S2T.mjs";
|
|
39
13
|
|
|
40
|
-
// src/
|
|
41
|
-
var
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
wheel(event, context) {
|
|
82
|
-
let best = null;
|
|
83
|
-
for (let binding of wheels) {
|
|
84
|
-
if (!binding.active.current || binding.layer === "overlay" !== context.overlayOpen) continue;
|
|
85
|
-
let rect = elementRect(binding.ref.current);
|
|
86
|
-
if (!rect || !rectContains(rect, event.x, event.y)) continue;
|
|
87
|
-
let area = rect.width * rect.height;
|
|
88
|
-
(!best || area <= best.area) && (best = { binding, area });
|
|
89
|
-
}
|
|
90
|
-
return !best || event.delta === 0 ? !!best : (best.binding.handler.current(event.delta, event), !0);
|
|
91
|
-
},
|
|
92
|
-
register(layer, handler, active) {
|
|
93
|
-
let binding = { id: nextId++, layer, handler, active };
|
|
94
|
-
return bindings.push(binding), () => {
|
|
95
|
-
let index = bindings.indexOf(binding);
|
|
96
|
-
index >= 0 && bindings.splice(index, 1);
|
|
97
|
-
};
|
|
98
|
-
},
|
|
99
|
-
dispatch(input, key, context) {
|
|
100
|
-
let order = context.overlayOpen ? ["overlay", "global"] : context.focus === "input" || context.focus === "tabs" ? [context.focus, "global"] : [context.focus, "view", "global"];
|
|
101
|
-
for (let layer of order) {
|
|
102
|
-
let candidates = bindings.filter((b) => b.layer === layer && b.active.current);
|
|
103
|
-
for (let i = candidates.length - 1; i >= 0; i--)
|
|
104
|
-
if (candidates[i].handler.current(input, key) === !0) return !0;
|
|
105
|
-
}
|
|
106
|
-
return !1;
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
var KeyRouterContext = (0, import_react.createContext)(null);
|
|
111
|
-
function KeyRouterProvider({ router, children }) {
|
|
112
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KeyRouterContext.Provider, { value: router, children });
|
|
113
|
-
}
|
|
114
|
-
function useKeyRouter() {
|
|
115
|
-
let router = (0, import_react.useContext)(KeyRouterContext);
|
|
116
|
-
if (!router) throw new Error("useKeys must be used inside the TUI shell");
|
|
117
|
-
return router;
|
|
118
|
-
}
|
|
119
|
-
function useKeys(handler, options) {
|
|
120
|
-
let router = useKeyRouter(), handlerRef = (0, import_react.useRef)(handler), activeRef = (0, import_react.useRef)(options.active !== !1);
|
|
121
|
-
handlerRef.current = handler, activeRef.current = options.active !== !1, (0, import_react.useEffect)(() => router.register(options.layer, handlerRef, activeRef), [router, options.layer]);
|
|
122
|
-
}
|
|
123
|
-
var WHEEL_STEP = 3;
|
|
124
|
-
function useWheel(ref, onWheel, options = {}) {
|
|
125
|
-
let router = useKeyRouter(), handler = (0, import_react.useRef)(onWheel), active = (0, import_react.useRef)(options.active !== !1);
|
|
126
|
-
handler.current = onWheel, active.current = options.active !== !1;
|
|
127
|
-
let layer = options.layer ?? "main";
|
|
128
|
-
(0, import_react.useEffect)(() => router.registerWheel({ layer, ref, handler, active }), [router, layer, ref]);
|
|
129
|
-
}
|
|
130
|
-
function useClick(ref, onClick, options = {}) {
|
|
131
|
-
let router = useKeyRouter(), handler = (0, import_react.useRef)(onClick), active = (0, import_react.useRef)(options.active !== !1);
|
|
132
|
-
handler.current = onClick, active.current = options.active !== !1, (0, import_react.useEffect)(() => router.registerClick({ ref, handler, active }), [router, ref]);
|
|
133
|
-
}
|
|
134
|
-
function keyLabel(spec) {
|
|
135
|
-
let parts = spec.split("+"), ctrl = parts.some((p) => p.toLowerCase() === "ctrl");
|
|
136
|
-
return parts.map((part) => {
|
|
137
|
-
let p = part.toLowerCase();
|
|
138
|
-
return p === "ctrl" ? "Ctrl+" : p === "alt" || p === "meta" ? "Alt+" : p === "shift" ? "Shift+" : p === "cmd" || p === "super" ? "Cmd+" : p === "backspace" ? "Backspace" : p === "delete" || p === "del" ? "Delete" : p === "home" ? "Home" : p === "end" ? "End" : p === "enter" || p === "return" ? "Enter" : p === "esc" || p === "escape" ? "Esc" : p === "tab" ? "Tab" : p === "up" ? "\u2191" : p === "down" ? "\u2193" : p === "left" ? "\u2190" : p === "right" ? "\u2192" : p === "pgup" || p === "pageup" ? "PgUp" : p === "pgdn" || p === "pagedown" ? "PgDn" : part.length === 1 && ctrl ? part.toUpperCase() : part;
|
|
139
|
-
}).join("");
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// src/main/tui/ui/KeyHint.tsx
|
|
143
|
-
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
144
|
-
function KeyHint({ keys, label }) {
|
|
145
|
-
let theme = useTheme();
|
|
146
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
|
|
147
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { bold: !0, color: theme.color.accent, children: keys.split(" ").map(keyLabel).join("/") }),
|
|
148
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { color: theme.color.muted, children: [
|
|
149
|
-
" ",
|
|
150
|
-
label
|
|
151
|
-
] })
|
|
152
|
-
] });
|
|
153
|
-
}
|
|
154
|
-
function KeyHints({ hints }) {
|
|
155
|
-
let theme = useTheme();
|
|
156
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { wrap: "truncate-end", children: hints.map((hint, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react2.Fragment, { children: [
|
|
157
|
-
index > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { color: theme.color.dim, children: [
|
|
158
|
-
" ",
|
|
159
|
-
theme.glyph.sep,
|
|
160
|
-
" "
|
|
161
|
-
] }) : null,
|
|
162
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(KeyHint, { ...hint })
|
|
163
|
-
] }, `${hint.keys}:${hint.label}`)) });
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// src/main/tui/identity/model.ts
|
|
167
|
-
var IDENTITY_OVERLAY = "identity", NEW_AGENT_OVERLAY = "new-agent", IDENTITY_BANNER_KEY = "shell.identity.banner";
|
|
168
|
-
var SAVED_WORD = "saved";
|
|
169
|
-
function shortDid(did, keep = 6) {
|
|
170
|
-
if (!did) return "";
|
|
171
|
-
let m = did.match(/^(did:[a-z0-9]+:)(.*)$/i);
|
|
172
|
-
if (!m) return did.length > 16 ? `${did.slice(0, 10)}\u2026${did.slice(-4)}` : did;
|
|
173
|
-
let id = m[2];
|
|
174
|
-
return id.length > keep + 5 ? `${m[1]}${id.slice(0, keep)}\u2026${id.slice(-4)}` : did;
|
|
175
|
-
}
|
|
176
|
-
function normalizePhrase(text) {
|
|
177
|
-
return phraseWords(text).join(" ");
|
|
178
|
-
}
|
|
179
|
-
function phraseWords(text) {
|
|
180
|
-
return text.toLowerCase().split(/[\s,;]+/).map((w) => w.replace(/^\d+[.):-]?$/, "").replace(/^\d+[.):-]/, "").replace(/[^a-z]/g, "")).filter(Boolean);
|
|
181
|
-
}
|
|
182
|
-
function isLoopbackUrl(url) {
|
|
183
|
-
try {
|
|
184
|
-
let host = new URL(url).hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
185
|
-
return host === "localhost" || host === "::1" || /^127\./.test(host) || host.startsWith("::ffff:127.");
|
|
186
|
-
} catch {
|
|
187
|
-
return !1;
|
|
188
|
-
}
|
|
14
|
+
// src/shared/utils/mcp-config.ts
|
|
15
|
+
var mcp_config_exports = {};
|
|
16
|
+
__export(mcp_config_exports, {
|
|
17
|
+
MCP_EXECUTABLE_IDENTITY_FIELDS: () => MCP_EXECUTABLE_IDENTITY_FIELDS,
|
|
18
|
+
buildEnvSchemaFromKeys: () => buildEnvSchemaFromKeys,
|
|
19
|
+
buildHeaderEnvSchemaFromEntries: () => buildHeaderEnvSchemaFromEntries,
|
|
20
|
+
buildMcpServerConfigFromRegistration: () => buildMcpServerConfigFromRegistration,
|
|
21
|
+
deriveRegistrationTestPlan: () => deriveRegistrationTestPlan,
|
|
22
|
+
getMcpRegistrationEnvKeys: () => getMcpRegistrationEnvKeys,
|
|
23
|
+
isRegistrationAgentVisible: () => isRegistrationAgentVisible,
|
|
24
|
+
isSensitiveMcpHeader: () => isSensitiveMcpHeader,
|
|
25
|
+
mcpCredentialNamespace: () => mcpCredentialNamespace,
|
|
26
|
+
mcpCredentialRef: () => mcpCredentialRef,
|
|
27
|
+
pinServerConfigToRegistration: () => pinServerConfigToRegistration,
|
|
28
|
+
reconcileHostApprovedRegistrations: () => reconcileHostApprovedRegistrations,
|
|
29
|
+
registrationSourceIdentity: () => registrationSourceIdentity,
|
|
30
|
+
sameExecutableIdentity: () => sameExecutableIdentity,
|
|
31
|
+
suggestedAgentVisible: () => suggestedAgentVisible
|
|
32
|
+
});
|
|
33
|
+
function sourcePackage(source) {
|
|
34
|
+
let s = source;
|
|
35
|
+
return s.npm_package ?? s.npmPackage ?? s.pypi_package ?? s.pypiPackage;
|
|
36
|
+
}
|
|
37
|
+
function mcpCredentialNamespace(source) {
|
|
38
|
+
return sourcePackage(source) ?? source.name;
|
|
39
|
+
}
|
|
40
|
+
function mcpCredentialRef(source, key) {
|
|
41
|
+
return `mcp:${mcpCredentialNamespace(source)}:${key}`;
|
|
42
|
+
}
|
|
43
|
+
function isSensitiveMcpHeader(header) {
|
|
44
|
+
let normalized = header.trim().toLowerCase();
|
|
45
|
+
return normalized === "authorization" || normalized === "proxy-authorization" || normalized === "x-api-key" || normalized === "api-key" || normalized === "apikey" || normalized === "x-auth-token" || normalized === "x-access-token" || normalized.includes("token") || normalized.includes("secret") || normalized.includes("credential");
|
|
46
|
+
}
|
|
47
|
+
function buildEnvSchemaFromKeys(source, keys, scope, requiredKeys = keys) {
|
|
48
|
+
let required = new Set(requiredKeys);
|
|
49
|
+
return [...new Set(keys.filter(Boolean))].map((key) => ({
|
|
50
|
+
key,
|
|
51
|
+
scope,
|
|
52
|
+
required: required.has(key) || void 0,
|
|
53
|
+
credential_ref: scope === "app" ? mcpCredentialRef(source, key) : void 0
|
|
54
|
+
}));
|
|
189
55
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
case "wrong_passphrase":
|
|
198
|
-
return "Wrong passphrase.";
|
|
199
|
-
case "weak_passphrase":
|
|
200
|
-
return "Choose a passphrase of at least 8 characters.";
|
|
201
|
-
case "passphrase_required":
|
|
202
|
-
return "This machine keeps the identity in a passphrase-protected file: enter the passphrase.";
|
|
203
|
-
case "loopback_only":
|
|
204
|
-
return LOOPBACK_ONLY_TEXT;
|
|
205
|
-
case "identity_exists":
|
|
206
|
-
return "An owner identity already exists here; nothing was created.";
|
|
207
|
-
case "nothing_to_unlock":
|
|
208
|
-
return "There is nothing to unlock yet: create or restore an identity.";
|
|
209
|
-
default:
|
|
210
|
-
return fallback;
|
|
211
|
-
}
|
|
56
|
+
function buildHeaderEnvSchemaFromEntries(source, entries, appScoped = !0) {
|
|
57
|
+
return entries.filter((entry) => entry.header && entry.env).map((entry) => ({
|
|
58
|
+
header: entry.header,
|
|
59
|
+
env: entry.env,
|
|
60
|
+
required: !0,
|
|
61
|
+
credential_ref: appScoped ? mcpCredentialRef(source, entry.env) : void 0
|
|
62
|
+
}));
|
|
212
63
|
}
|
|
213
|
-
function
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
return { text: "owner locked", tone: "warn" };
|
|
220
|
-
case "restore-needed":
|
|
221
|
-
return { text: "owner: restore", tone: "warn" };
|
|
222
|
-
default:
|
|
223
|
-
return { text: "no owner", tone: "warn" };
|
|
224
|
-
}
|
|
64
|
+
function getMcpRegistrationEnvKeys(registration) {
|
|
65
|
+
return [.../* @__PURE__ */ new Set([
|
|
66
|
+
...(registration.env ?? []).map((entry) => entry.key).filter(Boolean),
|
|
67
|
+
...registration.bearerTokenEnvVar ? [registration.bearerTokenEnvVar] : [],
|
|
68
|
+
...(registration.headerEnv ?? []).map((entry) => entry.value).filter(Boolean)
|
|
69
|
+
])];
|
|
225
70
|
}
|
|
226
|
-
function
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
71
|
+
function buildMcpServerConfigFromRegistration(registration) {
|
|
72
|
+
let isHttp = registration.type === "http" || !!registration.url, serverCfg = {
|
|
73
|
+
name: registration.name,
|
|
74
|
+
transport: isHttp ? "http" : "stdio"
|
|
75
|
+
};
|
|
76
|
+
if (isHttp) {
|
|
77
|
+
serverCfg.url = registration.url, serverCfg.source = registration.url ? `http:${registration.url}` : "http";
|
|
78
|
+
let staticHeaders = {};
|
|
79
|
+
for (let { key, value } of registration.headers ?? [])
|
|
80
|
+
key && value && !isSensitiveMcpHeader(key) && (staticHeaders[key] = value);
|
|
81
|
+
Object.keys(staticHeaders).length && (serverCfg.headers = staticHeaders), registration.headerEnv?.length && (serverCfg.header_env = buildHeaderEnvSchemaFromEntries(
|
|
82
|
+
registration,
|
|
83
|
+
registration.headerEnv.map(({ key, value }) => ({ header: key, env: value })),
|
|
84
|
+
(registration.credentialStorage ?? "app") !== "agent"
|
|
85
|
+
)), registration.oauth ? serverCfg.oauth = !0 : registration.bearerTokenEnvVar && (serverCfg.bearer_token_env_var = registration.bearerTokenEnvVar);
|
|
86
|
+
} else registration.npmPackage ? (serverCfg.source = `npm:${registration.npmPackage}`, serverCfg.npm_package = registration.npmPackage) : registration.pypiPackage ? (serverCfg.source = `uvx:${registration.pypiPackage}`, serverCfg.pypi_package = registration.pypiPackage) : (serverCfg.source = "custom", serverCfg.command = registration.command, serverCfg.args = registration.args);
|
|
87
|
+
isHttp || (registration.command && (serverCfg.command = registration.command), registration.args?.length && (serverCfg.args = registration.args));
|
|
88
|
+
let envKeys = getMcpRegistrationEnvKeys(registration);
|
|
89
|
+
if (envKeys.length) {
|
|
90
|
+
let scope = (registration.credentialStorage ?? "app") === "agent" ? "agent" : "app";
|
|
91
|
+
scope === "agent" && (serverCfg.env_keys = envKeys), serverCfg.env_schema = buildEnvSchemaFromKeys(registration, envKeys, scope);
|
|
239
92
|
}
|
|
93
|
+
return registration.toolCallTimeout && (serverCfg.tool_call_timeout_ms = registration.toolCallTimeout * 1e3), !isHttp && registration.runLocation && (serverCfg.run_location = registration.runLocation), registration.credentialFiles?.length && (serverCfg.credential_files = registration.credentialFiles.map((f) => ({
|
|
94
|
+
path: f.path,
|
|
95
|
+
...f.required !== void 0 ? { required: f.required } : {},
|
|
96
|
+
...f.writeBack !== void 0 ? { write_back: f.writeBack } : {}
|
|
97
|
+
}))), serverCfg;
|
|
98
|
+
}
|
|
99
|
+
function pinServerConfigToRegistration(connCfg, registration) {
|
|
100
|
+
let canonical = buildMcpServerConfigFromRegistration(registration), agentEnvSchema = (connCfg.env_schema ?? []).filter((e) => e.scope === "agent"), mergedEnvSchema = [
|
|
101
|
+
...canonical.env_schema ?? [],
|
|
102
|
+
...agentEnvSchema.filter(
|
|
103
|
+
(a) => !(canonical.env_schema ?? []).some((c) => c.key === a.key && c.scope === a.scope)
|
|
104
|
+
)
|
|
105
|
+
];
|
|
106
|
+
return {
|
|
107
|
+
...canonical,
|
|
108
|
+
// Agent-owned state kept from the .adf copy:
|
|
109
|
+
env: connCfg.env,
|
|
110
|
+
env_keys: connCfg.env_keys,
|
|
111
|
+
available_tools: connCfg.available_tools,
|
|
112
|
+
restricted: connCfg.restricted,
|
|
113
|
+
...mergedEnvSchema.length ? { env_schema: mergedEnvSchema } : {}
|
|
114
|
+
};
|
|
240
115
|
}
|
|
241
|
-
function
|
|
242
|
-
|
|
243
|
-
case "none":
|
|
244
|
-
return [
|
|
245
|
-
{ key: "c", label: "Create new", mode: "create" },
|
|
246
|
-
{ key: "r", label: "Restore from seed phrase", mode: "restore" }
|
|
247
|
-
];
|
|
248
|
-
case "restore-needed":
|
|
249
|
-
return [{ key: "r", label: "Restore from seed phrase", mode: "restore" }];
|
|
250
|
-
case "locked":
|
|
251
|
-
return identity.storage === "file" && identity.passphraseRequired ? [{ key: "u", label: "Unlock with passphrase", mode: "unlock" }] : [];
|
|
252
|
-
default:
|
|
253
|
-
return [];
|
|
254
|
-
}
|
|
116
|
+
function suggestedAgentVisible(reg) {
|
|
117
|
+
return reg.type === "http" || !!reg.url ? !0 : reg.runLocation !== "host";
|
|
255
118
|
}
|
|
256
|
-
function
|
|
257
|
-
return
|
|
119
|
+
function isRegistrationAgentVisible(reg) {
|
|
120
|
+
return reg.agentVisible ?? suggestedAgentVisible(reg);
|
|
258
121
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
store.actions.pushOverlay({ kind: IDENTITY_OVERLAY, props: { ...props } });
|
|
122
|
+
var MCP_EXECUTABLE_IDENTITY_FIELDS = ["type", "url", "command", "args", "npmPackage", "pypiPackage"];
|
|
123
|
+
function sameExecutableIdentity(a, b) {
|
|
124
|
+
let argsA = a.args ?? [], argsB = b.args ?? [];
|
|
125
|
+
return a.type === b.type && a.url === b.url && a.command === b.command && a.npmPackage === b.npmPackage && a.pypiPackage === b.pypiPackage && argsA.length === argsB.length && argsA.every((arg, i) => arg === argsB[i]);
|
|
264
126
|
}
|
|
265
|
-
function
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
return;
|
|
127
|
+
function deriveRegistrationTestPlan(reg, opts) {
|
|
128
|
+
if (reg.type === "http" || !!reg.url) {
|
|
129
|
+
let notes2 = reg.oauth ? ["Interactive OAuth sign-in runs in a browser during this test."] : [];
|
|
130
|
+
return { location: "remote http", authMode: reg.oauth ? "run" : "none", materializeFiles: !1, notes: notes2 };
|
|
270
131
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
-
function needsAttention(identity) {
|
|
277
|
-
return !!identity && (identity.status !== "ready" || !identity.backupConfirmed);
|
|
278
|
-
}
|
|
279
|
-
function identityKey(store, identity, input, panel) {
|
|
280
|
-
if (!identity) return !1;
|
|
281
|
-
if (input === "i")
|
|
282
|
-
return openIdentity(store), !0;
|
|
283
|
-
if (input === "I" && !panel && needsAttention(identity))
|
|
284
|
-
return store.actions.setViewState(IDENTITY_BANNER_KEY, bannerKeyOf(identity)), !0;
|
|
285
|
-
if (!panel) return !1;
|
|
286
|
-
let choice = onboardingChoices(identity).find((c) => c.key === input);
|
|
287
|
-
return choice ? (openIdentity(store, { mode: choice.mode }), !0) : !1;
|
|
288
|
-
}
|
|
289
|
-
function IdentityOnboarding({ identity, width, focused }) {
|
|
290
|
-
let theme = useTheme(), { title, next } = onboardingLines(identity), choices = onboardingChoices(identity), inner = Math.max(30, Math.min(width - 2, 72));
|
|
291
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", width: inner, marginTop: 1, children: [
|
|
292
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { bold: !0, color: theme.color.accent, children: [
|
|
293
|
-
theme.glyph.wordmark,
|
|
294
|
-
" ",
|
|
295
|
-
title
|
|
296
|
-
] }),
|
|
297
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: " " }),
|
|
298
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { wrap: "wrap", color: theme.color.text, children: IDENTITY_EXPLAINER }),
|
|
299
|
-
next ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { wrap: "wrap", color: theme.color.muted, children: next }) : null,
|
|
300
|
-
identity.status === "locked" && choices.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { wrap: "wrap", color: theme.color.warn, children: identity.message }) : null,
|
|
301
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: " " }),
|
|
302
|
-
choices.map((c) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { children: [
|
|
303
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { bold: !0, color: theme.color.accent, children: [
|
|
304
|
-
" [",
|
|
305
|
-
c.key,
|
|
306
|
-
"]"
|
|
307
|
-
] }),
|
|
308
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: theme.color.text, children: [
|
|
309
|
-
" ",
|
|
310
|
-
c.label
|
|
311
|
-
] })
|
|
312
|
-
] }, c.key)),
|
|
313
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: " " }),
|
|
314
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(KeyHints, { hints: focused ? [{ keys: "i", label: "details" }, { keys: "o", label: "load an existing .adf" }] : [{ keys: "shift+tab", label: "focus here to choose" }] })
|
|
315
|
-
] });
|
|
316
|
-
}
|
|
317
|
-
function IdentityBanner({ identity, width }) {
|
|
318
|
-
let theme = useTheme(), text = identity.status === "ready" ? `Seed phrase backup not confirmed for ${shortDid(identity.ownerDid, 4)}. Make sure the 12 words are written down.` : identity.status === "locked" ? "Owner identity locked: new agents cannot be created until it is unlocked." : identity.status === "restore-needed" ? `Restore owner ${shortDid(identity.ownerDid, 4)} from its 12 words to create agents here.` : "No owner identity yet: set one up to create agents.";
|
|
319
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { wrap: "truncate-end", children: [
|
|
320
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: theme.color.warn, children: [
|
|
321
|
-
theme.glyph.warn,
|
|
322
|
-
" ",
|
|
323
|
-
text.slice(0, Math.max(10, width - 24))
|
|
324
|
-
] }),
|
|
325
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: theme.color.dim, children: " " }),
|
|
326
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { bold: !0, color: theme.color.accent, children: "i" }),
|
|
327
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: theme.color.muted, children: " open" }),
|
|
328
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: theme.color.dim, children: [
|
|
329
|
-
" ",
|
|
330
|
-
theme.glyph.sep,
|
|
331
|
-
" "
|
|
332
|
-
] }),
|
|
333
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { bold: !0, color: theme.color.accent, children: "I" }),
|
|
334
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: theme.color.muted, children: " hide" })
|
|
335
|
-
] });
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// src/main/tui/setup/channels.ts
|
|
339
|
-
var { ADAPTER_REGISTRY } = cjs(adapter_registry_exports), CHANNELS_OVERLAY = "channels", CHANNEL_ORDER = ["telegram", "discord", "slack", "email", "whatsapp"];
|
|
340
|
-
function channelEntries() {
|
|
341
|
-
let byType = new Map(ADAPTER_REGISTRY.map((e) => [e.type, e]));
|
|
342
|
-
return CHANNEL_ORDER.map((t) => byType.get(t)).filter((e) => !!e);
|
|
343
|
-
}
|
|
344
|
-
function findChannel(type) {
|
|
345
|
-
if (!type) return;
|
|
346
|
-
let wanted = type.trim().toLowerCase();
|
|
347
|
-
return channelEntries().find((e) => e.type === wanted || e.displayName.toLowerCase() === wanted);
|
|
348
|
-
}
|
|
349
|
-
function credentialFields(entry) {
|
|
350
|
-
return entry.credentials ?? [
|
|
351
|
-
...entry.requiredEnvKeys.map((key) => ({ key, label: key, required: !0 })),
|
|
352
|
-
...(entry.optionalEnvKeys ?? []).map((key) => ({ key, label: key, required: !1 }))
|
|
353
|
-
];
|
|
354
|
-
}
|
|
355
|
-
var DEFAULT_ADAPTER_CONFIG = { enabled: !0, policy: { dm: "all", groups: "mention" } }, SHAPES = {
|
|
356
|
-
TELEGRAM_BOT_TOKEN: { test: /^\d{5,}:[A-Za-z0-9_-]{30,}$/, message: "A bot token looks like 123456789:AA\u2026 (digits, a colon, then 30+ characters)." },
|
|
357
|
-
DISCORD_BOT_TOKEN: { test: /^[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{20,}$/, message: "A Discord bot token has three dot-separated parts (Bot page \u2192 Reset Token)." },
|
|
358
|
-
DISCORD_APPLICATION_ID: { test: /^\d{15,22}$/, message: "The application ID is a long number (General Information page)." },
|
|
359
|
-
SLACK_APP_TOKEN: { test: /^xapp-/, message: "The app-level token starts with xapp- (Socket Mode page)." },
|
|
360
|
-
SLACK_BOT_TOKEN: { test: /^xoxb-/, message: "The bot token starts with xoxb- (Install App page)." },
|
|
361
|
-
EMAIL_USERNAME: { test: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: "Enter the full email address." }
|
|
362
|
-
};
|
|
363
|
-
function validateCredentials(entry, values) {
|
|
364
|
-
let errors = {};
|
|
365
|
-
for (let field of credentialFields(entry)) {
|
|
366
|
-
let value = (values[field.key] ?? "").trim();
|
|
367
|
-
if (!value) {
|
|
368
|
-
field.required && (errors[field.key] = `${field.label} is required.`);
|
|
369
|
-
continue;
|
|
132
|
+
if (reg.runLocation === "host") {
|
|
133
|
+
if (!opts?.hostAccessEnabled) {
|
|
134
|
+
let notes2 = ["Host access is disabled app-wide \u2014 this test ran in the shared container. Turn on Host access in Settings \u2192 Compute to test on the host."];
|
|
135
|
+
return reg.auth && notes2.push("Authorization for containerized servers happens per-agent when an agent attaches this server."), { location: "shared container", authMode: reg.auth ? "skip" : "none", materializeFiles: !1, notes: notes2 };
|
|
370
136
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
137
|
+
return {
|
|
138
|
+
location: "host",
|
|
139
|
+
authMode: reg.auth ? "run" : "none",
|
|
140
|
+
materializeFiles: !0,
|
|
141
|
+
notes: []
|
|
142
|
+
};
|
|
377
143
|
}
|
|
378
|
-
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
return
|
|
383
|
-
}
|
|
384
|
-
function
|
|
385
|
-
|
|
144
|
+
let notes = [];
|
|
145
|
+
return reg.auth && notes.push("Authorization for containerized servers happens per-agent when an agent attaches this server."), reg.credentialFiles?.length && notes.push("Credential files for containerized servers are captured per-agent at attach; this test verifies the package launches and lists tools."), { location: "shared container", authMode: reg.auth ? "skip" : "none", materializeFiles: !1, notes };
|
|
146
|
+
}
|
|
147
|
+
function registrationSourceIdentity(reg) {
|
|
148
|
+
return reg.type === "http" || reg.url ? reg.url ? `http:${reg.url}` : "http" : reg.npmPackage ? `npm:${reg.npmPackage}` : reg.pypiPackage ? `uvx:${reg.pypiPackage}` : "custom";
|
|
149
|
+
}
|
|
150
|
+
function reconcileHostApprovedRegistrations(prev, next, approved, approvedSources) {
|
|
151
|
+
let result = [...approved], sources = { ...approvedSources ?? {} }, prevByName = new Map(prev.filter((r) => r.name).map((r) => [r.name, r])), nextByName = new Map(next.filter((r) => r.name).map((r) => [r.name, r])), add = (name, reg) => {
|
|
152
|
+
result.includes(name) || result.push(name), sources[name] = registrationSourceIdentity(reg);
|
|
153
|
+
}, remove = (name) => {
|
|
154
|
+
let i = result.indexOf(name);
|
|
155
|
+
i >= 0 && result.splice(i, 1), delete sources[name];
|
|
156
|
+
};
|
|
157
|
+
for (let [name, reg] of nextByName) {
|
|
158
|
+
let wasHost = prevByName.get(name)?.runLocation === "host", isHost = reg.runLocation === "host" && reg.type !== "http";
|
|
159
|
+
isHost && !wasHost ? add(name, reg) : !isHost && wasHost ? remove(name) : isHost && wasHost && result.includes(name) && (sources[name] = registrationSourceIdentity(reg));
|
|
160
|
+
}
|
|
161
|
+
for (let [name, reg] of prevByName)
|
|
162
|
+
!nextByName.has(name) && reg.runLocation === "host" && remove(name);
|
|
163
|
+
return { approved: result, sources };
|
|
386
164
|
}
|
|
387
165
|
|
|
388
166
|
// src/shared/constants/provider-catalog.ts
|
|
@@ -442,6 +220,15 @@ var PROVIDER_CATALOG_GROUPS = [
|
|
|
442
220
|
modelPlaceholder: "e.g. grok-4.5",
|
|
443
221
|
iconKey: "x"
|
|
444
222
|
},
|
|
223
|
+
{
|
|
224
|
+
key: "claude-subscription",
|
|
225
|
+
label: "Claude",
|
|
226
|
+
type: "claude-subscription",
|
|
227
|
+
group: "subscription",
|
|
228
|
+
description: "Use your Claude Pro or Max plan, via Claude Code.",
|
|
229
|
+
modelPlaceholder: "e.g. claude-sonnet-5-5",
|
|
230
|
+
iconKey: "anthropic"
|
|
231
|
+
},
|
|
445
232
|
// ---- First-party APIs -----------------------------------------------------
|
|
446
233
|
{
|
|
447
234
|
key: "anthropic",
|
|
@@ -555,62 +342,12 @@ function providerTypeHint(type) {
|
|
|
555
342
|
return "ChatGPT subscription (OAuth)";
|
|
556
343
|
case "grok-subscription":
|
|
557
344
|
return "Grok subscription (OAuth)";
|
|
345
|
+
case "claude-subscription":
|
|
346
|
+
return "Claude subscription (via Claude Code)";
|
|
558
347
|
}
|
|
559
348
|
}
|
|
560
349
|
function isSubscriptionType(type) {
|
|
561
|
-
return type === "chatgpt-subscription" || type === "grok-subscription";
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
// src/main/tui/setup/provider.ts
|
|
565
|
-
var { PROVIDER_CATALOG: PROVIDER_CATALOG2 } = cjs(provider_catalog_exports), PROVIDER_OVERLAY = "provider.add", API_TYPES = /* @__PURE__ */ new Set(["anthropic", "openai", "openrouter", "openai-compatible"]);
|
|
566
|
-
function providerRows() {
|
|
567
|
-
let order = { subscription: 0, api: 1, local: 2, other: 3 };
|
|
568
|
-
return [...PROVIDER_CATALOG2].filter((e) => e.group === "subscription" || API_TYPES.has(e.type)).sort((a, b) => (order[a.group] ?? 9) - (order[b.group] ?? 9)).map((entry) => ({
|
|
569
|
-
entry,
|
|
570
|
-
...entry.type === "chatgpt-subscription" ? { signIn: "chatgpt" } : entry.type === "grok-subscription" ? { signIn: "grok" } : {}
|
|
571
|
-
}));
|
|
572
|
-
}
|
|
573
|
-
function findProviderRow(key) {
|
|
574
|
-
if (!key) return;
|
|
575
|
-
let wanted = key.trim().toLowerCase();
|
|
576
|
-
return providerRows().find((r) => r.entry.key === wanted || r.entry.label.toLowerCase() === wanted || r.entry.type === wanted);
|
|
577
|
-
}
|
|
578
|
-
function keyOptional(entry) {
|
|
579
|
-
return entry.keyOptional === !0 || entry.group === "other";
|
|
580
|
-
}
|
|
581
|
-
function needsBaseUrl(entry) {
|
|
582
|
-
return entry.type === "openai-compatible";
|
|
583
|
-
}
|
|
584
|
-
function validateProvider(entry, v) {
|
|
585
|
-
let errors = {};
|
|
586
|
-
if (needsBaseUrl(entry)) {
|
|
587
|
-
let url = v.baseUrl.trim();
|
|
588
|
-
if (!url) errors.baseUrl = "The server\u2019s base URL, e.g. http://localhost:11434/v1.";
|
|
589
|
-
else if (/YOUR_[A-Z_]+/.test(url)) errors.baseUrl = "Replace the YOUR_\u2026 part of the URL with your own value.";
|
|
590
|
-
else
|
|
591
|
-
try {
|
|
592
|
-
let parsed = new URL(url);
|
|
593
|
-
parsed.protocol !== "http:" && parsed.protocol !== "https:" && (errors.baseUrl = "Use an http(s) URL.");
|
|
594
|
-
} catch {
|
|
595
|
-
errors.baseUrl = "Not a URL.";
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
let key = v.apiKey.trim();
|
|
599
|
-
return !key && !keyOptional(entry) ? errors.apiKey = "Paste the API key." : /\s/.test(key) && (errors.apiKey = "No spaces: paste the key exactly."), errors;
|
|
600
|
-
}
|
|
601
|
-
function providerInput(entry, v) {
|
|
602
|
-
let key = v.apiKey.trim();
|
|
603
|
-
return {
|
|
604
|
-
type: entry.type,
|
|
605
|
-
name: v.name.trim() || entry.label,
|
|
606
|
-
...needsBaseUrl(entry) ? { baseUrl: v.baseUrl.trim() } : {},
|
|
607
|
-
...v.defaultModel.trim() ? { defaultModel: v.defaultModel.trim() } : {},
|
|
608
|
-
preset: entry.key,
|
|
609
|
-
...key ? { apiKey: key } : {}
|
|
610
|
-
};
|
|
611
|
-
}
|
|
612
|
-
function keyStorageText(storage) {
|
|
613
|
-
return storage === "file" ? "the daemon\u2019s passphrase-protected secret file" : "the OS keychain";
|
|
350
|
+
return type === "chatgpt-subscription" || type === "grok-subscription" || type === "claude-subscription";
|
|
614
351
|
}
|
|
615
352
|
|
|
616
353
|
// src/shared/constants/mcp-registry.ts
|
|
@@ -2233,240 +1970,20 @@ function findRegistryEntryByUrl(url) {
|
|
|
2233
1970
|
return MCP_REGISTRY.find((e) => e.url === url);
|
|
2234
1971
|
}
|
|
2235
1972
|
|
|
2236
|
-
// src/main/tui/setup/mcp.ts
|
|
2237
|
-
var { MCP_REGISTRY: MCP_REGISTRY2, registrationFromRegistryEntry: registrationFromRegistryEntry2, hasUnresolvedPlaceholderArgs: hasUnresolvedPlaceholderArgs2, REGISTRY_ARG_PLACEHOLDER_RE: REGISTRY_ARG_PLACEHOLDER_RE2 } = cjs(mcp_registry_exports), { buildMcpServerConfigFromRegistration, mcpCredentialNamespace } = cjs(mcp_config_exports), MCP_OVERLAY = "mcp";
|
|
2238
|
-
function mcpSourceRows() {
|
|
2239
|
-
let custom = [
|
|
2240
|
-
{ kind: "npm", label: "npm package", detail: "Any MCP server published to npm (e.g. @modelcontextprotocol/server-everything)" },
|
|
2241
|
-
{ kind: "python", label: "Python package (uvx)", detail: "Any MCP server on PyPI, run with uvx (e.g. mcp-server-fetch)" },
|
|
2242
|
-
{ kind: "http", label: "Remote server (URL)", detail: "A Streamable HTTP MCP endpoint; token from an env var" }
|
|
2243
|
-
], catalog = MCP_REGISTRY2.filter((e) => !e.deprecated).map((entry) => ({ kind: "catalog", entry, label: entry.displayName, detail: entry.description }));
|
|
2244
|
-
return [...custom, ...catalog];
|
|
2245
|
-
}
|
|
2246
|
-
function parseAddTarget(arg) {
|
|
2247
|
-
let raw = (arg ?? "").trim();
|
|
2248
|
-
if (!raw) return {};
|
|
2249
|
-
let rows = mcpSourceRows();
|
|
2250
|
-
if (/^https?:\/\//i.test(raw)) {
|
|
2251
|
-
let known = rows.find((r) => r.entry?.url === raw);
|
|
2252
|
-
return known ? { row: known } : { row: rows.find((r) => r.kind === "http"), value: raw };
|
|
2253
|
-
}
|
|
2254
|
-
let prefixed = raw.match(/^(npm|python|uvx|pip):(.+)$/i);
|
|
2255
|
-
if (prefixed) {
|
|
2256
|
-
let kind = prefixed[1].toLowerCase() === "npm" ? "npm" : "python";
|
|
2257
|
-
return { row: rows.find((r) => r.kind === kind), value: prefixed[2].trim() };
|
|
2258
|
-
}
|
|
2259
|
-
let wanted = raw.toLowerCase(), entry = rows.find((r) => r.entry && (r.entry.name === wanted || r.entry.npmPackage === raw || r.entry.pypiPackage === raw || r.entry.displayName.toLowerCase() === wanted));
|
|
2260
|
-
return entry ? { row: entry } : { row: rows.find((r) => r.kind === "npm"), value: raw };
|
|
2261
|
-
}
|
|
2262
|
-
function sanitizeServerName(value) {
|
|
2263
|
-
return value.toLowerCase().replace(/^@[^/]+\//, "").replace(/^mcp-server-|-mcp-server$|^server-|-mcp$|^mcp-/g, "").replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
|
|
2264
|
-
}
|
|
2265
|
-
function defaultServerName(row, value = "") {
|
|
2266
|
-
if (row.entry) return row.entry.name;
|
|
2267
|
-
if (row.kind === "http")
|
|
2268
|
-
try {
|
|
2269
|
-
return sanitizeServerName(new URL(value).hostname.split(".").slice(-2, -1)[0] ?? "");
|
|
2270
|
-
} catch {
|
|
2271
|
-
return "";
|
|
2272
|
-
}
|
|
2273
|
-
return sanitizeServerName(value.split("/").pop() ?? value);
|
|
2274
|
-
}
|
|
2275
|
-
function envKeysOf(row) {
|
|
2276
|
-
let e = row.entry;
|
|
2277
|
-
if (!e) return row.kind === "http" ? [{ key: "MCP_TOKEN", required: !1 }] : [];
|
|
2278
|
-
let keys = [
|
|
2279
|
-
...e.requiredEnvKeys.map((key) => ({ key, required: !0 })),
|
|
2280
|
-
...(e.optionalEnvKeys ?? []).map((key) => ({ key, required: !1 })),
|
|
2281
|
-
...e.bearerTokenEnvVar ? [{ key: e.bearerTokenEnvVar, required: !!e.url && !e.oauth }] : [],
|
|
2282
|
-
...(e.headerEnv ?? []).map((h) => ({ key: h.env, required: !0 }))
|
|
2283
|
-
];
|
|
2284
|
-
return keys.filter((k, i) => keys.findIndex((x) => x.key === k.key) === i);
|
|
2285
|
-
}
|
|
2286
|
-
function studioOnlyReason(row) {
|
|
2287
|
-
let e = row.entry;
|
|
2288
|
-
return e ? e.url && e.oauth && !e.bearerTokenEnvVar && !e.headerEnv?.length ? `${e.displayName} signs in with OAuth in the browser, which only ADF Studio runs today. Add it in Studio (Settings \u2192 MCP \u2192 ${e.displayName}, Connect), then it shows up here.` : e.auth || (e.credentialFiles?.length ?? 0) > 0 ? `${e.displayName} needs a one-time sign-in step (it writes a credential file), which ADF Studio runs. Add it in Studio (Settings \u2192 MCP), then it shows up here.` : null : null;
|
|
2289
|
-
}
|
|
2290
|
-
function validateMcpForm(row, form, taken) {
|
|
2291
|
-
let errors = {};
|
|
2292
|
-
if (form.name ? form.name !== sanitizeServerName(form.name) || !/^[a-z0-9][a-z0-9_-]*$/.test(form.name) ? errors.name = "Lowercase letters, digits, - and _ only." : taken.includes(form.name) && (errors.name = `This agent already has a server named ${form.name}.`) : errors.name = "Give it a name (letters, digits, - and _).", !row.entry) {
|
|
2293
|
-
let source = form.source.trim();
|
|
2294
|
-
if (!source) errors.source = row.kind === "http" ? "The server URL." : "The package name.";
|
|
2295
|
-
else if (row.kind === "http")
|
|
2296
|
-
try {
|
|
2297
|
-
/^https?:$/.test(new URL(source).protocol) || (errors.source = "Use an http(s) URL.");
|
|
2298
|
-
} catch {
|
|
2299
|
-
errors.source = "Not a URL.";
|
|
2300
|
-
}
|
|
2301
|
-
else /\s/.test(source) && (errors.source = "One package name, no spaces.");
|
|
2302
|
-
}
|
|
2303
|
-
hasUnresolvedPlaceholderArgs2(splitArgs(form.args)) && (errors.args = "Fill in the {placeholders}.");
|
|
2304
|
-
for (let { key, required } of envKeysOf(row))
|
|
2305
|
-
required && !(form.env[key] ?? "").trim() && (errors[`env:${key}`] = `${key} is required.`);
|
|
2306
|
-
return errors;
|
|
2307
|
-
}
|
|
2308
|
-
function splitArgs(text) {
|
|
2309
|
-
let out = [], pattern = /"((?:[^"\\]|\\.)*)"|'([^']*)'|(\S+)/g, m;
|
|
2310
|
-
for (; m = pattern.exec(text); ) out.push(m[1] !== void 0 ? m[1].replace(/\\(.)/g, "$1") : m[2] ?? m[3]);
|
|
2311
|
-
return out;
|
|
2312
|
-
}
|
|
2313
|
-
function joinArgs(args) {
|
|
2314
|
-
return (args ?? []).map((a) => /\s/.test(a) ? `"${a.replace(/"/g, '\\"')}"` : a).join(" ");
|
|
2315
|
-
}
|
|
2316
|
-
function registrationFor(row, form) {
|
|
2317
|
-
let envKeys = envKeysOf(row).map((k) => k.key), base = row.entry ? registrationFromRegistryEntry2(row.entry, `tui:${form.name}`) : row.kind === "http" ? { id: `tui:${form.name}`, name: form.name, type: "http", url: form.source.trim(), ...form.env.MCP_TOKEN?.trim() ? { bearerTokenEnvVar: "MCP_TOKEN" } : {} } : row.kind === "python" ? { id: `tui:${form.name}`, name: form.name, type: "uvx", pypiPackage: form.source.trim(), managed: !0 } : { id: `tui:${form.name}`, name: form.name, type: "npm", npmPackage: form.source.trim(), managed: !0 }, isHttp = base.type === "http", args = splitArgs(form.args), keysWithValues = envKeys.filter((k) => (form.env[k] ?? "").trim());
|
|
2318
|
-
return {
|
|
2319
|
-
...base,
|
|
2320
|
-
name: form.name,
|
|
2321
|
-
credentialStorage: "agent",
|
|
2322
|
-
// Keys only: values go to the agent's identity store.
|
|
2323
|
-
env: (row.entry ? envKeys : keysWithValues).map((key) => ({ key, value: "" })),
|
|
2324
|
-
// Remote catalog entries that also take a token: the token path (OAuth runs in Studio only).
|
|
2325
|
-
...isHttp && base.oauth && base.bearerTokenEnvVar ? { oauth: !1 } : {},
|
|
2326
|
-
...isHttp ? {} : { args: args.length ? args : void 0 },
|
|
2327
|
-
// Container unless the user picked the host (a catalog entry's host default is only a preselection).
|
|
2328
|
-
runLocation: !isHttp && form.runOn === "host" ? "host" : void 0
|
|
2329
|
-
};
|
|
2330
|
-
}
|
|
2331
|
-
function serverConfigFor(row, form) {
|
|
2332
|
-
return buildMcpServerConfigFromRegistration(registrationFor(row, form));
|
|
2333
|
-
}
|
|
2334
|
-
function credentialNamespace(server) {
|
|
2335
|
-
return mcpCredentialNamespace(server);
|
|
2336
|
-
}
|
|
2337
|
-
function packageToInstall(server) {
|
|
2338
|
-
return server.transport === "http" ? null : server.npm_package ? { kind: "npm", name: server.npm_package } : server.pypi_package ? { kind: "python", name: server.pypi_package } : null;
|
|
2339
|
-
}
|
|
2340
|
-
function serverEnvKeys(server) {
|
|
2341
|
-
return [.../* @__PURE__ */ new Set([
|
|
2342
|
-
...server.env_keys ?? [],
|
|
2343
|
-
...(server.env_schema ?? []).map((e) => e.key),
|
|
2344
|
-
...server.bearer_token_env_var ? [server.bearer_token_env_var] : [],
|
|
2345
|
-
...(server.header_env ?? []).map((h) => h.env)
|
|
2346
|
-
])];
|
|
2347
|
-
}
|
|
2348
|
-
function runsOnText(server, location) {
|
|
2349
|
-
return location || (server ? server.transport === "http" ? "remote" : server.run_location === "host" ? "host" : server.run_location === "shared" ? "shared container" : "container" : "");
|
|
2350
|
-
}
|
|
2351
|
-
function serverToolDecls(tools, server) {
|
|
2352
|
-
let prefix = `mcp_${server}_`;
|
|
2353
|
-
return (tools ?? []).filter((t) => t.name.startsWith(prefix)).map((t) => ({ name: t.name, tool: t.name.slice(prefix.length), enabled: t.enabled !== !1 }));
|
|
2354
|
-
}
|
|
2355
|
-
|
|
2356
|
-
// src/main/tui/setup/open.ts
|
|
2357
|
-
function channelsIdentityReady(store) {
|
|
2358
|
-
let identity = store.getState().identity;
|
|
2359
|
-
return !identity || identity.status === "ready";
|
|
2360
|
-
}
|
|
2361
|
-
function secretStoreReady(store) {
|
|
2362
|
-
let identity = store.getState().identity;
|
|
2363
|
-
return identity ? identity.storage === "keychain" ? identity.status !== "locked" : identity.status === "ready" : !0;
|
|
2364
|
-
}
|
|
2365
|
-
function openChannels(store, props = {}) {
|
|
2366
|
-
let state = store.getState(), agentId = props.agentId ?? state.selectedAgentId;
|
|
2367
|
-
if (!agentId || !state.agents[agentId]) {
|
|
2368
|
-
store.actions.toast("Select an agent first (sidebar or /agent), or create one with /new", "warn");
|
|
2369
|
-
return;
|
|
2370
|
-
}
|
|
2371
|
-
let next = { agentId, ...props.channel ? { channel: props.channel } : {} };
|
|
2372
|
-
if (props.channel && !channelsIdentityReady(store)) {
|
|
2373
|
-
identityFirst(store, CHANNELS_OVERLAY, next, "Channel credentials are sealed under your owner identity: set it up first, then the channel setup follows.");
|
|
2374
|
-
return;
|
|
2375
|
-
}
|
|
2376
|
-
store.actions.pushOverlay({ kind: CHANNELS_OVERLAY, props: { ...next } });
|
|
2377
|
-
}
|
|
2378
|
-
function openProviderAdd(store, props = {}) {
|
|
2379
|
-
if (!secretStoreReady(store)) {
|
|
2380
|
-
identityFirst(store, PROVIDER_OVERLAY, { ...props }, "API keys go into the daemon\u2019s secret store, which is protected by your owner identity here: set it up or unlock it first.");
|
|
2381
|
-
return;
|
|
2382
|
-
}
|
|
2383
|
-
store.actions.pushOverlay({ kind: PROVIDER_OVERLAY, props: { ...props } });
|
|
2384
|
-
}
|
|
2385
|
-
function openMcp(store, props = {}) {
|
|
2386
|
-
let state = store.getState(), agentId = props.agentId ?? state.selectedAgentId;
|
|
2387
|
-
if (!agentId || !state.agents[agentId]) {
|
|
2388
|
-
store.actions.toast("Select an agent first (sidebar or /agent), or create one with /new", "warn");
|
|
2389
|
-
return;
|
|
2390
|
-
}
|
|
2391
|
-
store.actions.pushOverlay({ kind: MCP_OVERLAY, props: { ...props, agentId } });
|
|
2392
|
-
}
|
|
2393
|
-
function openWelcome(store) {
|
|
2394
|
-
store.actions.pushOverlay({ id: WELCOME_OVERLAY, kind: WELCOME_OVERLAY });
|
|
2395
|
-
}
|
|
2396
|
-
function identityFirst(store, then, thenProps, reason) {
|
|
2397
|
-
openIdentity(store, { mode: "status", then, thenProps, reason });
|
|
2398
|
-
}
|
|
2399
|
-
|
|
2400
1973
|
export {
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
normalizePhrase,
|
|
2417
|
-
phraseWords,
|
|
2418
|
-
isLoopbackUrl,
|
|
2419
|
-
LOOPBACK_ONLY_TEXT,
|
|
2420
|
-
IDENTITY_EXPLAINER,
|
|
2421
|
-
identityErrorText,
|
|
2422
|
-
identityBadge,
|
|
2423
|
-
onboardingLines,
|
|
2424
|
-
onboardingChoices,
|
|
2425
|
-
passphraseProblem,
|
|
2426
|
-
KeyHints,
|
|
2427
|
-
openIdentity,
|
|
2428
|
-
openNewAgent,
|
|
2429
|
-
bannerKeyOf,
|
|
2430
|
-
needsAttention,
|
|
2431
|
-
identityKey,
|
|
2432
|
-
IdentityOnboarding,
|
|
2433
|
-
IdentityBanner,
|
|
2434
|
-
CHANNELS_OVERLAY,
|
|
2435
|
-
CHANNEL_ORDER,
|
|
2436
|
-
channelEntries,
|
|
2437
|
-
findChannel,
|
|
2438
|
-
credentialFields,
|
|
2439
|
-
DEFAULT_ADAPTER_CONFIG,
|
|
2440
|
-
validateCredentials,
|
|
2441
|
-
adapterLiveState,
|
|
2442
|
-
configuredChannels,
|
|
2443
|
-
PROVIDER_OVERLAY,
|
|
2444
|
-
providerRows,
|
|
2445
|
-
findProviderRow,
|
|
2446
|
-
keyOptional,
|
|
2447
|
-
needsBaseUrl,
|
|
2448
|
-
validateProvider,
|
|
2449
|
-
providerInput,
|
|
2450
|
-
keyStorageText,
|
|
2451
|
-
MCP_OVERLAY,
|
|
2452
|
-
mcpSourceRows,
|
|
2453
|
-
parseAddTarget,
|
|
2454
|
-
defaultServerName,
|
|
2455
|
-
envKeysOf,
|
|
2456
|
-
studioOnlyReason,
|
|
2457
|
-
validateMcpForm,
|
|
2458
|
-
joinArgs,
|
|
2459
|
-
serverConfigFor,
|
|
2460
|
-
credentialNamespace,
|
|
2461
|
-
packageToInstall,
|
|
2462
|
-
serverEnvKeys,
|
|
2463
|
-
runsOnText,
|
|
2464
|
-
serverToolDecls,
|
|
2465
|
-
channelsIdentityReady,
|
|
2466
|
-
secretStoreReady,
|
|
2467
|
-
openChannels,
|
|
2468
|
-
openProviderAdd,
|
|
2469
|
-
openMcp,
|
|
2470
|
-
openWelcome,
|
|
2471
|
-
identityFirst
|
|
1974
|
+
mcpCredentialRef,
|
|
1975
|
+
isSensitiveMcpHeader,
|
|
1976
|
+
buildEnvSchemaFromKeys,
|
|
1977
|
+
buildHeaderEnvSchemaFromEntries,
|
|
1978
|
+
buildMcpServerConfigFromRegistration,
|
|
1979
|
+
pinServerConfigToRegistration,
|
|
1980
|
+
isRegistrationAgentVisible,
|
|
1981
|
+
deriveRegistrationTestPlan,
|
|
1982
|
+
mcp_config_exports,
|
|
1983
|
+
isSubscriptionType,
|
|
1984
|
+
provider_catalog_exports,
|
|
1985
|
+
parseMcpRegistryDocument,
|
|
1986
|
+
MCP_REGISTRY,
|
|
1987
|
+
BUNDLED_REGISTRY_UPDATED_AT,
|
|
1988
|
+
mcp_registry_exports
|
|
2472
1989
|
};
|