@xrkseek/harness-cli 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +20 -9
- package/dist/commands/serve.js.map +1 -1
- package/dist/parse-args.d.ts.map +1 -1
- package/dist/parse-args.js +4 -3
- package/dist/parse-args.js.map +1 -1
- package/node_modules/@xrkseek/core-agent-loop/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/core-agent-loop/dist/index.js +8 -2
- package/node_modules/@xrkseek/core-agent-loop/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/core-system-prompt/README.md +2 -2
- package/node_modules/@xrkseek/core-system-prompt/dist/index.d.ts +1 -1
- package/node_modules/@xrkseek/core-system-prompt/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/core-system-prompt/dist/index.js +1 -1
- package/node_modules/@xrkseek/core-system-prompt/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/core-system-prompt/dist/three-layer.d.ts +22 -4
- package/node_modules/@xrkseek/core-system-prompt/dist/three-layer.d.ts.map +1 -1
- package/node_modules/@xrkseek/core-system-prompt/dist/three-layer.js +21 -8
- package/node_modules/@xrkseek/core-system-prompt/dist/three-layer.js.map +1 -1
- package/node_modules/@xrkseek/exec-web/dist/fetch-http.js +1 -1
- package/node_modules/@xrkseek/exec-web/dist/index.d.ts +5 -1
- package/node_modules/@xrkseek/exec-web/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-web/dist/index.js +6 -6
- package/node_modules/@xrkseek/exec-web/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/exec-web/dist/search-providers.d.ts +20 -3
- package/node_modules/@xrkseek/exec-web/dist/search-providers.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-web/dist/search-providers.js +67 -28
- package/node_modules/@xrkseek/exec-web/dist/search-providers.js.map +1 -1
- package/node_modules/@xrkseek/preset-harness/dist/preset.d.ts +4 -0
- package/node_modules/@xrkseek/preset-harness/dist/preset.d.ts.map +1 -1
- package/node_modules/@xrkseek/preset-harness/dist/preset.js +1 -1
- package/node_modules/@xrkseek/preset-harness/dist/preset.js.map +1 -1
- package/node_modules/@xrkseek/preset-harness/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@xrkseek/preset-minimal/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@xrkseek/preset-server/dist/preset.d.ts.map +1 -1
- package/node_modules/@xrkseek/preset-server/dist/preset.js +2 -1
- package/node_modules/@xrkseek/preset-server/dist/preset.js.map +1 -1
- package/node_modules/@xrkseek/preset-server/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@xrkseek/protocol/dist/token-usage.d.ts +7 -1
- package/node_modules/@xrkseek/protocol/dist/token-usage.d.ts.map +1 -1
- package/node_modules/@xrkseek/protocol/dist/token-usage.js +49 -24
- package/node_modules/@xrkseek/protocol/dist/token-usage.js.map +1 -1
- package/node_modules/@xrkseek/server-config/dist/index.js +1 -1
- package/node_modules/@xrkseek/server-face/dist/context.d.ts +6 -5
- package/node_modules/@xrkseek/server-face/dist/context.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/context.js +1 -3
- package/node_modules/@xrkseek/server-face/dist/context.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/face-schema.d.ts +3 -2
- package/node_modules/@xrkseek/server-face/dist/face-schema.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/face-schema.js +16 -4
- package/node_modules/@xrkseek/server-face/dist/face-schema.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/handlers/catalog.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/handlers/catalog.js +26 -12
- package/node_modules/@xrkseek/server-face/dist/handlers/catalog.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/handlers/session.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/handlers/session.js +19 -24
- package/node_modules/@xrkseek/server-face/dist/handlers/session.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/index.d.ts +3 -3
- package/node_modules/@xrkseek/server-face/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/index.js +3 -3
- package/node_modules/@xrkseek/server-face/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/llm-provider-context.d.ts +44 -6
- package/node_modules/@xrkseek/server-face/dist/llm-provider-context.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/llm-provider-context.js +220 -34
- package/node_modules/@xrkseek/server-face/dist/llm-provider-context.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/llm-resolve.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/llm-resolve.js +4 -7
- package/node_modules/@xrkseek/server-face/dist/llm-resolve.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/model-catalog.d.ts +1 -1
- package/node_modules/@xrkseek/server-face/dist/model-catalog.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/model-catalog.js +23 -26
- package/node_modules/@xrkseek/server-face/dist/model-catalog.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/presets-catalog.d.ts +13 -1
- package/node_modules/@xrkseek/server-face/dist/presets-catalog.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/presets-catalog.js +24 -9
- package/node_modules/@xrkseek/server-face/dist/presets-catalog.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-credentials.d.ts +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-credentials.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-credentials.js +116 -14
- package/node_modules/@xrkseek/server-face/dist/settings-credentials.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-document.d.ts +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-document.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-document.js +25 -22
- package/node_modules/@xrkseek/server-face/dist/settings-document.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-layers.d.ts +3 -0
- package/node_modules/@xrkseek/server-face/dist/settings-layers.d.ts.map +1 -0
- package/node_modules/@xrkseek/server-face/dist/settings-layers.js +19 -0
- package/node_modules/@xrkseek/server-face/dist/settings-layers.js.map +1 -0
- package/node_modules/@xrkseek/server-face/dist/settings-schemas.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-schemas.js +18 -2
- package/node_modules/@xrkseek/server-face/dist/settings-schemas.js.map +1 -1
- package/node_modules/@xrkseek/server-host/dist/index.d.ts +11 -2
- package/node_modules/@xrkseek/server-host/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-host/dist/index.js +67 -16
- package/node_modules/@xrkseek/server-host/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/server-host/dist/mcp-wire.d.ts +9 -4
- package/node_modules/@xrkseek/server-host/dist/mcp-wire.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-host/dist/mcp-wire.js +42 -7
- package/node_modules/@xrkseek/server-host/dist/mcp-wire.js.map +1 -1
- package/package.json +1 -1
- package/product-web/boot.json +1 -1
- package/product-web/plugins/@xrkseek/client-locale/client.js +3 -3
- package/product-web/plugins/@xrkseek/client-ui-agent-preset/client.js +35 -35
- package/product-web/plugins/@xrkseek/client-ui-commands/client.js +6 -6
- package/product-web/plugins/@xrkseek/client-ui-conversation/client.js +160 -160
- package/product-web/plugins/@xrkseek/client-ui-deliverables/client.js +6 -6
- package/product-web/plugins/@xrkseek/client-ui-directory-picker-browse/client.js +29 -29
- package/product-web/plugins/@xrkseek/client-ui-goal/client.js +6 -6
- package/product-web/plugins/@xrkseek/client-ui-input-trigger/client.js +5 -5
- package/product-web/plugins/@xrkseek/client-ui-jobs/client.js +7 -7
- package/product-web/plugins/@xrkseek/client-ui-layout/client.js +3 -3
- package/product-web/plugins/@xrkseek/client-ui-message-feedback/client.js +5 -5
- package/product-web/plugins/@xrkseek/client-ui-model-selection/client.js +18 -18
- package/product-web/plugins/@xrkseek/client-ui-permission-presets/client.js +2 -2
- package/product-web/plugins/@xrkseek/client-ui-plan/client.js +3 -3
- package/product-web/plugins/@xrkseek/client-ui-settings/client.js +7 -1
- package/product-web/plugins/@xrkseek/client-ui-settings-general/client.js +15 -15
- package/product-web/plugins/@xrkseek/client-ui-settings-models/client.js +57 -57
- package/product-web/plugins/@xrkseek/client-ui-settings-plugin-inventory/client.js +12 -12
- package/product-web/plugins/@xrkseek/client-ui-settings-plugins/client.js +651 -163
- package/product-web/plugins/@xrkseek/client-ui-sidebar/client.js +12 -12
- package/product-web/plugins/@xrkseek/client-ui-skill/client.js +11 -11
- package/product-web/plugins/@xrkseek/client-ui-subagent/client.js +19 -19
- package/product-web/plugins/@xrkseek/client-ui-theme/client.js +1 -1
- package/product-web/plugins/@xrkseek/client-ui-tool/client.js +37 -37
- package/product-web/plugins/@xrkseek/client-ui-trajectory/client.js +143 -143
- package/product-web/plugins/@xrkseek/client-ui-user-questions/client.js +26 -26
- package/product-web/plugins/@xrkseek/client-ui-workflow-run/client.js +17 -17
- package/product-web/plugins/@xrkseek/client-ui-workspace/client.js +55 -55
|
@@ -10,7 +10,7 @@ window.__ModuleLoader__.load({
|
|
|
10
10
|
let _xrkseek_client_ui_primitives = require("@xrkseek/client-ui-primitives");
|
|
11
11
|
let _xrkseek_client_runtime_client = require("@xrkseek/client-runtime/client");
|
|
12
12
|
//#region \0xrk-css:C:\Users\sunflowerss\Desktop\XRKgrocery\XRK-harness\packages\client\ui-settings-plugins\src\client\fields.module.css.mjs
|
|
13
|
-
const css$3 = ".MiE2dW_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.MiE2dW_field+.MiE2dW_field{border-top:1px solid var(--dsw-alias-border-l2)}.MiE2dW_head{align-items:center;gap:8px;display:flex}.MiE2dW_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.MiE2dW_badges{align-items:center;gap:8px;display:inline-flex}.MiE2dW_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.MiE2dW_badgeMuted{white-space:nowrap;color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:1px 8px;font-size:11px;line-height:17px}.MiE2dW_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.MiE2dW_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.MiE2dW_reset:disabled{cursor:default}.MiE2dW_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l3,var(--dsw-alias-border-l2));background:var(--dsw-alias-bg-layer-1);width:100%;height:32px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 10px;font-size:13px;line-height:1.5}.MiE2dW_input::placeholder{color:var(--dsw-alias-label-dimmed)}.MiE2dW_input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.MiE2dW_input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.MiE2dW_input:-webkit-autofill,.MiE2dW_input:-webkit-autofill:hover,.MiE2dW_input:-webkit-autofill:focus{-webkit-text-fill-color:var(--dsw-alias-label-primary);caret-color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l3,var(--dsw-alias-border-l2));box-shadow:0 0 0 1000px var(--dsw-alias-bg-layer-1) inset;transition:background-color 99999s ease-out}.MiE2dW_select{cursor:pointer;max-width:none;}.MiE2dW_inputInvalid{border-color:var(--dsw-alias-label-error)
|
|
13
|
+
const css$3 = ".MiE2dW_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.MiE2dW_field+.MiE2dW_field{border-top:1px solid var(--dsw-alias-border-l2)}.MiE2dW_head{align-items:center;gap:8px;display:flex}.MiE2dW_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.MiE2dW_badges{align-items:center;gap:8px;display:inline-flex}.MiE2dW_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.MiE2dW_badgeMuted{white-space:nowrap;color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:1px 8px;font-size:11px;line-height:17px}.MiE2dW_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.MiE2dW_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.MiE2dW_reset:disabled{cursor:default}.MiE2dW_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l3,var(--dsw-alias-border-l2));background:var(--dsw-alias-bg-layer-1);width:100%;height:32px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 10px;font-size:13px;line-height:1.5}.MiE2dW_input::placeholder{color:var(--dsw-alias-label-dimmed)}.MiE2dW_input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.MiE2dW_input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.MiE2dW_input:-webkit-autofill,.MiE2dW_input:-webkit-autofill:hover,.MiE2dW_input:-webkit-autofill:focus{-webkit-text-fill-color:var(--dsw-alias-label-primary);caret-color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l3,var(--dsw-alias-border-l2));box-shadow:0 0 0 1000px var(--dsw-alias-bg-layer-1) inset;transition:background-color 99999s ease-out}.MiE2dW_select{appearance:none;cursor:pointer;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");background-position:right 12px center;background-repeat:no-repeat;background-size:12px 12px;max-width:none;padding-right:32px}.MiE2dW_inputInvalid{border-color:var(--dsw-alias-label-error)}.MiE2dW_invalid{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}.MiE2dW_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}";
|
|
14
14
|
const tagId$3 = "@xrkseek/client-ui-settings-plugins/fields.module.css";
|
|
15
15
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
16
16
|
const tag = document.createElement("style");
|
|
@@ -21,17 +21,17 @@ window.__ModuleLoader__.load({
|
|
|
21
21
|
}
|
|
22
22
|
var fields_module_css_default = {
|
|
23
23
|
"label": "MiE2dW_label",
|
|
24
|
+
"reset": "MiE2dW_reset",
|
|
24
25
|
"input": "MiE2dW_input",
|
|
26
|
+
"inputInvalid": "MiE2dW_inputInvalid",
|
|
27
|
+
"badgeMuted": "MiE2dW_badgeMuted",
|
|
25
28
|
"invalid": "MiE2dW_invalid",
|
|
26
|
-
"badge": "MiE2dW_badge",
|
|
27
|
-
"reset": "MiE2dW_reset",
|
|
28
29
|
"field": "MiE2dW_field",
|
|
30
|
+
"hint": "MiE2dW_hint",
|
|
29
31
|
"head": "MiE2dW_head",
|
|
30
|
-
"
|
|
31
|
-
"badgeMuted": "MiE2dW_badgeMuted",
|
|
32
|
+
"badge": "MiE2dW_badge",
|
|
32
33
|
"select": "MiE2dW_select",
|
|
33
|
-
"
|
|
34
|
-
"hint": "MiE2dW_hint"
|
|
34
|
+
"badges": "MiE2dW_badges"
|
|
35
35
|
};
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region src/client/fields.tsx
|
|
@@ -42,6 +42,36 @@ window.__ModuleLoader__.load({
|
|
|
42
42
|
* layer. Nothing here writes: a control reports what the user typed, and the
|
|
43
43
|
* card's save is the single point where a draft becomes a document mutation.
|
|
44
44
|
*/
|
|
45
|
+
/** Same chrome as PlainField, for a short option list (MCP transport). */
|
|
46
|
+
function SelectField(props) {
|
|
47
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
48
|
+
className: fields_module_css_default.field,
|
|
49
|
+
children: [
|
|
50
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
51
|
+
className: fields_module_css_default.label,
|
|
52
|
+
htmlFor: props.id,
|
|
53
|
+
children: props.label
|
|
54
|
+
}),
|
|
55
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
56
|
+
id: props.id,
|
|
57
|
+
className: `${fields_module_css_default.input} ${fields_module_css_default.select}`,
|
|
58
|
+
value: props.value,
|
|
59
|
+
disabled: props.disabled,
|
|
60
|
+
onChange: (event) => {
|
|
61
|
+
props.onChange(event.target.value);
|
|
62
|
+
},
|
|
63
|
+
children: props.options.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
64
|
+
value: option.value,
|
|
65
|
+
children: option.label
|
|
66
|
+
}, option.value))
|
|
67
|
+
}),
|
|
68
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
69
|
+
className: fields_module_css_default.hint,
|
|
70
|
+
children: props.hint
|
|
71
|
+
})
|
|
72
|
+
]
|
|
73
|
+
});
|
|
74
|
+
}
|
|
45
75
|
/**
|
|
46
76
|
* A staged value field. `numeric` only hints the keypad: which drafts a field
|
|
47
77
|
* accepts is decided by its spec, so the control never silently rewrites what
|
|
@@ -75,7 +105,7 @@ window.__ModuleLoader__.load({
|
|
|
75
105
|
}),
|
|
76
106
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
77
107
|
id: props.id,
|
|
78
|
-
className: props.invalid ? fields_module_css_default.inputInvalid : fields_module_css_default.input,
|
|
108
|
+
className: props.invalid ? `${fields_module_css_default.input} ${fields_module_css_default.inputInvalid}` : fields_module_css_default.input,
|
|
79
109
|
type: "text",
|
|
80
110
|
...props.numeric === true ? { inputMode: "numeric" } : {},
|
|
81
111
|
...props.invalid ? { "aria-invalid": true } : {},
|
|
@@ -93,6 +123,49 @@ window.__ModuleLoader__.load({
|
|
|
93
123
|
]
|
|
94
124
|
});
|
|
95
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* A write-only credential control. The value never rides a response, so the
|
|
128
|
+
* control reports only whether one is configured and starts blank; a blank
|
|
129
|
+
* draft writes nothing, which keeps the stored key rather than clearing it.
|
|
130
|
+
* @param props - the field's copy, its staged text, and the configured state.
|
|
131
|
+
* @returns the labelled control.
|
|
132
|
+
*/
|
|
133
|
+
function SecretField(props) {
|
|
134
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
135
|
+
className: fields_module_css_default.field,
|
|
136
|
+
children: [
|
|
137
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
138
|
+
className: fields_module_css_default.head,
|
|
139
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
140
|
+
className: fields_module_css_default.label,
|
|
141
|
+
htmlFor: props.id,
|
|
142
|
+
children: props.label
|
|
143
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
144
|
+
className: fields_module_css_default.badges,
|
|
145
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
146
|
+
className: props.configured ? fields_module_css_default.badge : fields_module_css_default.badgeMuted,
|
|
147
|
+
children: props.stateLabel
|
|
148
|
+
})
|
|
149
|
+
})]
|
|
150
|
+
}),
|
|
151
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
152
|
+
id: props.id,
|
|
153
|
+
className: fields_module_css_default.input,
|
|
154
|
+
type: "password",
|
|
155
|
+
autoComplete: "off",
|
|
156
|
+
value: props.text,
|
|
157
|
+
disabled: props.disabled,
|
|
158
|
+
onChange: (event) => {
|
|
159
|
+
props.onEdit(event.target.value);
|
|
160
|
+
}
|
|
161
|
+
}),
|
|
162
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
163
|
+
className: fields_module_css_default.hint,
|
|
164
|
+
children: props.hint
|
|
165
|
+
})
|
|
166
|
+
]
|
|
167
|
+
});
|
|
168
|
+
}
|
|
96
169
|
//#endregion
|
|
97
170
|
//#region ../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
|
|
98
171
|
function r(e) {
|
|
@@ -120,21 +193,21 @@ window.__ModuleLoader__.load({
|
|
|
120
193
|
document.head.appendChild(tag);
|
|
121
194
|
}
|
|
122
195
|
var PluginCard_module_css_default = {
|
|
123
|
-
"headText": "YRvGva_headText",
|
|
124
|
-
"failed": "YRvGva_failed",
|
|
125
|
-
"chevronOpen": "YRvGva_chevronOpen",
|
|
126
196
|
"header": "YRvGva_header",
|
|
127
|
-
"save": "YRvGva_save",
|
|
128
|
-
"body": "YRvGva_body",
|
|
129
|
-
"readOnly": "YRvGva_readOnly",
|
|
130
|
-
"name": "YRvGva_name",
|
|
131
197
|
"card": "YRvGva_card",
|
|
132
|
-
"description": "YRvGva_description",
|
|
133
|
-
"chevron": "YRvGva_chevron",
|
|
134
198
|
"discard": "YRvGva_discard",
|
|
199
|
+
"description": "YRvGva_description",
|
|
200
|
+
"save": "YRvGva_save",
|
|
201
|
+
"readOnly": "YRvGva_readOnly",
|
|
135
202
|
"pending": "YRvGva_pending",
|
|
203
|
+
"chevron": "YRvGva_chevron",
|
|
204
|
+
"footer": "YRvGva_footer",
|
|
136
205
|
"cardOpen": "YRvGva_cardOpen",
|
|
137
|
-
"
|
|
206
|
+
"name": "YRvGva_name",
|
|
207
|
+
"body": "YRvGva_body",
|
|
208
|
+
"failed": "YRvGva_failed",
|
|
209
|
+
"headText": "YRvGva_headText",
|
|
210
|
+
"chevronOpen": "YRvGva_chevronOpen"
|
|
138
211
|
};
|
|
139
212
|
//#endregion
|
|
140
213
|
//#region src/client/PluginCard.tsx
|
|
@@ -329,14 +402,14 @@ window.__ModuleLoader__.load({
|
|
|
329
402
|
document.head.appendChild(tag);
|
|
330
403
|
}
|
|
331
404
|
var PluginsSettingsSection_module_css_default = {
|
|
332
|
-
"
|
|
405
|
+
"heading": "ha2I9q_heading",
|
|
406
|
+
"empty": "ha2I9q_empty",
|
|
333
407
|
"tab": "ha2I9q_tab",
|
|
408
|
+
"tabs": "ha2I9q_tabs",
|
|
409
|
+
"intro": "ha2I9q_intro",
|
|
334
410
|
"cards": "ha2I9q_cards",
|
|
335
|
-
"empty": "ha2I9q_empty",
|
|
336
411
|
"section": "ha2I9q_section",
|
|
337
|
-
"
|
|
338
|
-
"panel": "ha2I9q_panel",
|
|
339
|
-
"intro": "ha2I9q_intro"
|
|
412
|
+
"panel": "ha2I9q_panel"
|
|
340
413
|
};
|
|
341
414
|
//#endregion
|
|
342
415
|
//#region src/client/ConfigurablePluginsTab.tsx
|
|
@@ -367,7 +440,7 @@ window.__ModuleLoader__.load({
|
|
|
367
440
|
}
|
|
368
441
|
//#endregion
|
|
369
442
|
//#region \0xrk-css:C:\Users\sunflowerss\Desktop\XRKgrocery\XRK-harness\packages\client\ui-settings-plugins\src\client\McpCard.module.css.mjs
|
|
370
|
-
const css = ".FVl50a_block+.FVl50a_block{border-top:1px solid var(--dsw-alias-border-l2);margin-top:4px;padding-top:4px}.FVl50a_heading{color:var(--dsw-alias-label-primary);margin:0;padding:12px 0 4px;font-size:13px;font-weight:600;line-height:1.5}.FVl50a_note{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.FVl50a_empty{border:1px dashed var(--dsw-alias-border-l3,var(--dsw-alias-border-l2));text-align:center;color:var(--dsw-alias-label-tertiary);border-radius:8px;margin:8px 0 0;padding:12px;font-size:12px;line-height:1.5}.FVl50a_invalid{color:var(--dsw-alias-label-error);margin:8px 0 0;font-size:12px;line-height:1.5}.FVl50a_connectedList{flex-direction:column;gap:6px;margin:8px 0 0;padding:0;list-style:none;display:flex}.FVl50a_connectedRow{flex-wrap:wrap;align-items:center;gap:8px;padding:6px 0;display:flex}.FVl50a_connectedName{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500}.FVl50a_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.FVl50a_badgeMuted{color:var(--dsw-alias-label-tertiary);font-weight:400
|
|
443
|
+
const css = ".FVl50a_block+.FVl50a_block{border-top:1px solid var(--dsw-alias-border-l2);margin-top:4px;padding-top:4px}.FVl50a_heading{color:var(--dsw-alias-label-primary);margin:0;padding:12px 0 4px;font-size:13px;font-weight:600;line-height:1.5}.FVl50a_note{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.FVl50a_empty{border:1px dashed var(--dsw-alias-border-l3,var(--dsw-alias-border-l2));text-align:center;color:var(--dsw-alias-label-tertiary);border-radius:8px;margin:8px 0 0;padding:12px;font-size:12px;line-height:1.5}.FVl50a_invalid{color:var(--dsw-alias-label-error);margin:8px 0 0;font-size:12px;line-height:1.5}.FVl50a_connectedList{flex-direction:column;gap:6px;margin:8px 0 0;padding:0;list-style:none;display:flex}.FVl50a_connectedRow{flex-wrap:wrap;align-items:center;gap:8px;padding:6px 0;display:flex}.FVl50a_connectedName{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500}.FVl50a_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.FVl50a_badgeMuted{color:var(--dsw-alias-label-tertiary);font-weight:400}.FVl50a_badgeError{color:var(--dsw-alias-label-error)}.FVl50a_badgeOk{color:var(--dsw-alias-state-success-primary,var(--dsw-alias-label-secondary))}.FVl50a_badgeWarn{color:var(--dsw-alias-state-warning-primary,var(--dsw-alias-label-tertiary))}.FVl50a_allowRow{color:var(--dsw-alias-label-primary);cursor:pointer;align-items:flex-start;gap:10px;margin:12px 0 4px;font-size:13px;line-height:1.4;display:flex}.FVl50a_allowRow input{margin-top:3px}.FVl50a_allowTitle{font-weight:600;display:block}.FVl50a_allowHint{color:var(--dsw-alias-label-tertiary);margin-top:2px;font-size:12px;display:block}.FVl50a_entryTitleRow{flex-wrap:wrap;align-items:center;gap:8px;min-width:0;display:flex}.FVl50a_statusDot{background:currentColor;border-radius:50%;flex-shrink:0;width:8px;height:8px;padding:0}.FVl50a_list{flex-direction:column;gap:0;margin-top:4px;display:flex}.FVl50a_entry{border:none;border-top:1px solid var(--dsw-alias-border-l2);background:0 0;border-radius:0;padding:4px 0 8px}.FVl50a_entry:first-child{border-top:none;padding-top:0}.FVl50a_entryHead{background:0 0;border:none;justify-content:space-between;align-items:center;gap:8px;padding:8px 0 0;display:flex}.FVl50a_entryTitle{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary);margin:0;font-size:13px;font-weight:600;line-height:1.5;overflow:hidden}.FVl50a_remove{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex-shrink:0;justify-content:center;align-items:center;padding:0;display:inline-flex}.FVl50a_remove:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger,var(--dsw-alias-bg-module-platform));color:var(--dsw-alias-state-error-primary,var(--dsw-alias-label-error))}.FVl50a_remove:disabled{opacity:.4;cursor:default}.FVl50a_entryBody{padding:0}.FVl50a_pasteLabel{color:var(--dsw-alias-label-primary);margin:12px 0 6px;font-size:13px;font-weight:500;line-height:1.5}.FVl50a_paste{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l3,var(--dsw-alias-border-l2));background:var(--dsw-alias-bg-layer-1);width:100%;min-height:96px;font:inherit;color:var(--dsw-alias-label-primary);resize:vertical;border-radius:8px;padding:8px 10px;font-size:12px;line-height:1.5}.FVl50a_paste::placeholder{color:var(--dsw-alias-label-dimmed)}.FVl50a_paste:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.FVl50a_paste:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.FVl50a_add{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l3,var(--dsw-alias-border-l2));height:28px;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;background:0 0;border-radius:14px;align-self:flex-start;align-items:center;gap:4px;margin-top:8px;padding:0 10px;font-size:12px;line-height:18px;display:inline-flex}.FVl50a_add:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-module-platform))}.FVl50a_add:disabled{opacity:.4;cursor:default}";
|
|
371
444
|
const tagId = "@xrkseek/client-ui-settings-plugins/McpCard.module.css";
|
|
372
445
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
373
446
|
const tag = document.createElement("style");
|
|
@@ -377,30 +450,37 @@ window.__ModuleLoader__.load({
|
|
|
377
450
|
document.head.appendChild(tag);
|
|
378
451
|
}
|
|
379
452
|
var McpCard_module_css_default = {
|
|
380
|
-
"remove": "FVl50a_remove",
|
|
381
|
-
"badgeError": "FVl50a_badgeError",
|
|
382
|
-
"entry": "FVl50a_entry",
|
|
383
|
-
"entryTitle": "FVl50a_entryTitle",
|
|
384
|
-
"paste": "FVl50a_paste",
|
|
385
|
-
"badgeMuted": "FVl50a_badgeMuted",
|
|
386
|
-
"note": "FVl50a_note",
|
|
387
|
-
"block": "FVl50a_block",
|
|
388
|
-
"empty": "FVl50a_empty",
|
|
389
|
-
"entryHead": "FVl50a_entryHead",
|
|
390
|
-
"badge": "FVl50a_badge",
|
|
391
|
-
"add": "FVl50a_add",
|
|
392
|
-
"invalid": "FVl50a_invalid",
|
|
393
|
-
"connectedList": "FVl50a_connectedList",
|
|
394
453
|
"list": "FVl50a_list",
|
|
454
|
+
"pasteLabel": "FVl50a_pasteLabel",
|
|
455
|
+
"add": "FVl50a_add",
|
|
456
|
+
"empty": "FVl50a_empty",
|
|
395
457
|
"connectedRow": "FVl50a_connectedRow",
|
|
458
|
+
"entryTitleRow": "FVl50a_entryTitleRow",
|
|
396
459
|
"connectedName": "FVl50a_connectedName",
|
|
460
|
+
"badgeError": "FVl50a_badgeError",
|
|
461
|
+
"badgeWarn": "FVl50a_badgeWarn",
|
|
462
|
+
"block": "FVl50a_block",
|
|
463
|
+
"note": "FVl50a_note",
|
|
464
|
+
"allowHint": "FVl50a_allowHint",
|
|
465
|
+
"entry": "FVl50a_entry",
|
|
397
466
|
"heading": "FVl50a_heading",
|
|
467
|
+
"invalid": "FVl50a_invalid",
|
|
468
|
+
"entryHead": "FVl50a_entryHead",
|
|
469
|
+
"badgeMuted": "FVl50a_badgeMuted",
|
|
470
|
+
"badgeOk": "FVl50a_badgeOk",
|
|
471
|
+
"allowTitle": "FVl50a_allowTitle",
|
|
472
|
+
"statusDot": "FVl50a_statusDot",
|
|
473
|
+
"allowRow": "FVl50a_allowRow",
|
|
474
|
+
"entryTitle": "FVl50a_entryTitle",
|
|
475
|
+
"connectedList": "FVl50a_connectedList",
|
|
476
|
+
"remove": "FVl50a_remove",
|
|
398
477
|
"entryBody": "FVl50a_entryBody",
|
|
399
|
-
"
|
|
478
|
+
"badge": "FVl50a_badge",
|
|
479
|
+
"paste": "FVl50a_paste"
|
|
400
480
|
};
|
|
401
481
|
//#endregion
|
|
402
482
|
//#region src/client/McpCard.tsx
|
|
403
|
-
/** MCP desired-server card:
|
|
483
|
+
/** MCP desired-server card: allow toggle, per-row status, JSON paste. */
|
|
404
484
|
/**
|
|
405
485
|
* Render the MCP card.
|
|
406
486
|
* @param props - locale copy, the card snapshot, and its form actions.
|
|
@@ -435,43 +515,23 @@ window.__ModuleLoader__.load({
|
|
|
435
515
|
role: "note",
|
|
436
516
|
children: state.note
|
|
437
517
|
}) : null,
|
|
438
|
-
|
|
439
|
-
className: McpCard_module_css_default.
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
className: McpCard_module_css_default.connectedName,
|
|
456
|
-
children: entry.serverName
|
|
457
|
-
}),
|
|
458
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
459
|
-
className: statusClass,
|
|
460
|
-
children: statusLabel
|
|
461
|
-
}),
|
|
462
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
463
|
-
className: McpCard_module_css_default.badgeMuted,
|
|
464
|
-
children: [
|
|
465
|
-
entry.toolCount,
|
|
466
|
-
" ",
|
|
467
|
-
t("mcpToolsLabel")
|
|
468
|
-
]
|
|
469
|
-
})
|
|
470
|
-
]
|
|
471
|
-
}, entry.id);
|
|
472
|
-
})
|
|
473
|
-
})]
|
|
474
|
-
}) : null,
|
|
518
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
519
|
+
className: McpCard_module_css_default.allowRow,
|
|
520
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
521
|
+
type: "checkbox",
|
|
522
|
+
checked: state.allowConnect,
|
|
523
|
+
disabled,
|
|
524
|
+
onChange: (event) => {
|
|
525
|
+
props.setAllowConnect(event.target.checked);
|
|
526
|
+
}
|
|
527
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
528
|
+
className: McpCard_module_css_default.allowTitle,
|
|
529
|
+
children: t("mcpAllowConnect")
|
|
530
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
531
|
+
className: McpCard_module_css_default.allowHint,
|
|
532
|
+
children: t("mcpAllowConnectHint")
|
|
533
|
+
})] })]
|
|
534
|
+
}),
|
|
475
535
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
476
536
|
className: McpCard_module_css_default.block,
|
|
477
537
|
"aria-label": t("mcpServersHeading"),
|
|
@@ -528,20 +588,69 @@ window.__ModuleLoader__.load({
|
|
|
528
588
|
]
|
|
529
589
|
});
|
|
530
590
|
}
|
|
591
|
+
function statusCopy(t, status) {
|
|
592
|
+
switch (status) {
|
|
593
|
+
case "connected": return t("mcpStatusConnected");
|
|
594
|
+
case "reconnecting": return t("mcpStatusReconnecting");
|
|
595
|
+
case "gave-up": return t("mcpStatusGaveUp");
|
|
596
|
+
case "parked": return t("mcpStatusParked");
|
|
597
|
+
case "failed": return t("mcpStatusFailed");
|
|
598
|
+
default: return t("mcpStatusIdle");
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
function statusTone(status) {
|
|
602
|
+
if (status === "connected") return McpCard_module_css_default.badgeOk;
|
|
603
|
+
if (status === "failed" || status === "gave-up") return McpCard_module_css_default.badgeError;
|
|
604
|
+
if (status === "parked") return McpCard_module_css_default.badgeWarn;
|
|
605
|
+
return McpCard_module_css_default.badgeMuted;
|
|
606
|
+
}
|
|
607
|
+
function statusBadge(status) {
|
|
608
|
+
return `${McpCard_module_css_default.badge} ${statusTone(status)}`;
|
|
609
|
+
}
|
|
531
610
|
function ServerSummary({ t, row, disabled, onRemove }) {
|
|
532
611
|
const summary = row.transport === "http" ? row.url : [row.command, row.args].filter((part) => part.trim()).join(" ");
|
|
533
612
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
|
|
534
613
|
className: McpCard_module_css_default.entry,
|
|
535
614
|
"aria-label": row.serverName,
|
|
615
|
+
"data-mcp-status": row.status,
|
|
536
616
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
537
617
|
className: McpCard_module_css_default.entryHead,
|
|
538
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
618
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
619
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
620
|
+
className: McpCard_module_css_default.entryTitleRow,
|
|
621
|
+
children: [
|
|
622
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
623
|
+
className: `${McpCard_module_css_default.statusDot} ${statusTone(row.status)}`,
|
|
624
|
+
"aria-hidden": true
|
|
625
|
+
}),
|
|
626
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
627
|
+
className: McpCard_module_css_default.entryTitle,
|
|
628
|
+
children: row.serverName
|
|
629
|
+
}),
|
|
630
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
631
|
+
className: statusBadge(row.status),
|
|
632
|
+
children: statusCopy(t, row.status)
|
|
633
|
+
}),
|
|
634
|
+
row.toolCount > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
635
|
+
className: `${McpCard_module_css_default.badge} ${McpCard_module_css_default.badgeMuted}`,
|
|
636
|
+
children: [
|
|
637
|
+
row.toolCount,
|
|
638
|
+
" ",
|
|
639
|
+
t("mcpToolsLabel")
|
|
640
|
+
]
|
|
641
|
+
}) : null
|
|
642
|
+
]
|
|
643
|
+
}),
|
|
644
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
645
|
+
className: McpCard_module_css_default.empty,
|
|
646
|
+
children: summary || t("mcpServerRow").replace("{index}", "")
|
|
647
|
+
}),
|
|
648
|
+
row.failureMessage ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
649
|
+
className: McpCard_module_css_default.invalid,
|
|
650
|
+
role: "status",
|
|
651
|
+
children: row.failureMessage
|
|
652
|
+
}) : null
|
|
653
|
+
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
545
654
|
type: "button",
|
|
546
655
|
className: McpCard_module_css_default.remove,
|
|
547
656
|
"aria-label": `${t("mcpRemoveServer")} ${row.serverName}`,
|
|
@@ -554,6 +663,100 @@ window.__ModuleLoader__.load({
|
|
|
554
663
|
});
|
|
555
664
|
}
|
|
556
665
|
//#endregion
|
|
666
|
+
//#region src/client/WebSearchCard.tsx
|
|
667
|
+
/**
|
|
668
|
+
* Render the web-search card.
|
|
669
|
+
* @param props - locale copy, the card snapshot, and its form actions.
|
|
670
|
+
* @returns the card.
|
|
671
|
+
*/
|
|
672
|
+
function WebSearchCard(props) {
|
|
673
|
+
const { t } = props;
|
|
674
|
+
const state = props.useWebSearchCard((snapshot) => snapshot);
|
|
675
|
+
const disabled = !state.writable;
|
|
676
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(PluginCard, {
|
|
677
|
+
t,
|
|
678
|
+
titleKey: "webSearchTitle",
|
|
679
|
+
descriptionKey: "webSearchDescription",
|
|
680
|
+
state,
|
|
681
|
+
onSave: props.save,
|
|
682
|
+
onDiscard: props.discard,
|
|
683
|
+
children: [
|
|
684
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectField, {
|
|
685
|
+
id: "plugin-config-web-search-provider",
|
|
686
|
+
label: t("webSearchProvider"),
|
|
687
|
+
hint: t("webSearchProviderHint"),
|
|
688
|
+
disabled,
|
|
689
|
+
value: state.provider.text || "auto",
|
|
690
|
+
options: [
|
|
691
|
+
{
|
|
692
|
+
value: "auto",
|
|
693
|
+
label: t("webSearchProviderAuto")
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
value: "tavily",
|
|
697
|
+
label: t("webSearchProviderTavily")
|
|
698
|
+
},
|
|
699
|
+
{
|
|
700
|
+
value: "brave",
|
|
701
|
+
label: t("webSearchProviderBrave")
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
value: "parallel-free",
|
|
705
|
+
label: t("webSearchProviderParallel")
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
value: "duckduckgo",
|
|
709
|
+
label: t("webSearchProviderDuckduckgo")
|
|
710
|
+
}
|
|
711
|
+
],
|
|
712
|
+
onChange: (value) => {
|
|
713
|
+
props.edit("provider", value);
|
|
714
|
+
}
|
|
715
|
+
}),
|
|
716
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SecretField, {
|
|
717
|
+
id: "plugin-config-web-search-tavily",
|
|
718
|
+
label: t("webSearchTavilyKey"),
|
|
719
|
+
hint: t("webSearchTavilyKeyHint"),
|
|
720
|
+
disabled: !state.tavilyWritable,
|
|
721
|
+
text: state.tavilyApiKey.text,
|
|
722
|
+
configured: state.tavilyConfigured,
|
|
723
|
+
stateLabel: state.tavilyConfigured ? t("webSearchKeySet") : t("webSearchKeyUnset"),
|
|
724
|
+
onEdit: (text) => {
|
|
725
|
+
props.edit("tavilyApiKey", text);
|
|
726
|
+
}
|
|
727
|
+
}),
|
|
728
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SecretField, {
|
|
729
|
+
id: "plugin-config-web-search-brave",
|
|
730
|
+
label: t("webSearchBraveKey"),
|
|
731
|
+
hint: t("webSearchBraveKeyHint"),
|
|
732
|
+
disabled: !state.braveWritable,
|
|
733
|
+
text: state.braveApiKey.text,
|
|
734
|
+
configured: state.braveConfigured,
|
|
735
|
+
stateLabel: state.braveConfigured ? t("webSearchKeySet") : t("webSearchKeyUnset"),
|
|
736
|
+
onEdit: (text) => {
|
|
737
|
+
props.edit("braveApiKey", text);
|
|
738
|
+
}
|
|
739
|
+
}),
|
|
740
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ValueField, {
|
|
741
|
+
id: "plugin-config-web-search-region",
|
|
742
|
+
label: t("webSearchRegion"),
|
|
743
|
+
hint: t("webSearchRegionHint"),
|
|
744
|
+
overriddenLabel: t("overridden"),
|
|
745
|
+
resetLabel: t("reset"),
|
|
746
|
+
invalidLabel: t("invalidNumber"),
|
|
747
|
+
disabled,
|
|
748
|
+
...state.region,
|
|
749
|
+
onEdit: (text) => {
|
|
750
|
+
props.edit("region", text);
|
|
751
|
+
},
|
|
752
|
+
onReset: () => {
|
|
753
|
+
props.resetField("region");
|
|
754
|
+
}
|
|
755
|
+
})
|
|
756
|
+
]
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
//#endregion
|
|
557
760
|
//#region src/client/PluginsSettingsSection.tsx
|
|
558
761
|
/** Plugins settings section: localized tabs around feature-owned pages. */
|
|
559
762
|
/** Render one Plugins page whose contents arrive from feature-owned tabs. */
|
|
@@ -670,6 +873,25 @@ window.__ModuleLoader__.load({
|
|
|
670
873
|
};
|
|
671
874
|
}
|
|
672
875
|
/**
|
|
876
|
+
* A free-text field. An empty draft clears the field, so emptying the control
|
|
877
|
+
* and saving is the same gesture as resetting it.
|
|
878
|
+
* @param field - field name inside the namespace section.
|
|
879
|
+
* @returns the field's conversion spec.
|
|
880
|
+
*/
|
|
881
|
+
function textField(field) {
|
|
882
|
+
return {
|
|
883
|
+
field,
|
|
884
|
+
format: (value) => typeof value === "string" ? value : "",
|
|
885
|
+
parse: (text) => {
|
|
886
|
+
const trimmed = text.trim();
|
|
887
|
+
return trimmed === "" ? { kind: "clear" } : {
|
|
888
|
+
kind: "set",
|
|
889
|
+
value: trimmed
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
673
895
|
* Stages one card's edits over one settings namespace and writes them on save.
|
|
674
896
|
*
|
|
675
897
|
* The form publishes through a snapshot store because slot components read
|
|
@@ -958,6 +1180,9 @@ window.__ModuleLoader__.load({
|
|
|
958
1180
|
scope;
|
|
959
1181
|
store;
|
|
960
1182
|
rows = [];
|
|
1183
|
+
allowConnect = false;
|
|
1184
|
+
/** True after the user toggles Allow connect (so save respects an explicit park). */
|
|
1185
|
+
allowTouched = false;
|
|
961
1186
|
seeded = false;
|
|
962
1187
|
saving = false;
|
|
963
1188
|
failed = false;
|
|
@@ -979,11 +1204,13 @@ window.__ModuleLoader__.load({
|
|
|
979
1204
|
return;
|
|
980
1205
|
}
|
|
981
1206
|
if (!this.seeded || force && !this.dirty()) {
|
|
982
|
-
this.rows = serversOf(snapshot).map(rowToUi);
|
|
1207
|
+
this.rows = serversOf(snapshot).map((draft) => rowToUi(draft, snapshot));
|
|
1208
|
+
this.allowConnect = allowOf(snapshot);
|
|
1209
|
+
this.allowTouched = false;
|
|
983
1210
|
this.seeded = true;
|
|
984
1211
|
this.failed = false;
|
|
985
1212
|
this.showErrors = false;
|
|
986
|
-
}
|
|
1213
|
+
} else this.rows = this.rows.map((row) => enrichRowStatus(row, snapshot));
|
|
987
1214
|
this.publish();
|
|
988
1215
|
}
|
|
989
1216
|
projection() {
|
|
@@ -999,7 +1226,7 @@ window.__ModuleLoader__.load({
|
|
|
999
1226
|
saving: this.saving,
|
|
1000
1227
|
failed: this.failed,
|
|
1001
1228
|
rows: this.rows,
|
|
1002
|
-
|
|
1229
|
+
allowConnect: this.allowConnect,
|
|
1003
1230
|
note: noteOf(snapshot)
|
|
1004
1231
|
};
|
|
1005
1232
|
}
|
|
@@ -1007,6 +1234,7 @@ window.__ModuleLoader__.load({
|
|
|
1007
1234
|
if (!this.seeded) return false;
|
|
1008
1235
|
const snapshot = this.scope.getSnapshot();
|
|
1009
1236
|
if (snapshot.status !== "ready") return false;
|
|
1237
|
+
if (this.allowConnect !== allowOf(snapshot)) return true;
|
|
1010
1238
|
return JSON.stringify(this.rows.map(rowFromUi)) !== JSON.stringify(serversOf(snapshot));
|
|
1011
1239
|
}
|
|
1012
1240
|
publish() {
|
|
@@ -1023,6 +1251,9 @@ window.__ModuleLoader__.load({
|
|
|
1023
1251
|
removeRow: (index) => {
|
|
1024
1252
|
this.removeRow(index);
|
|
1025
1253
|
},
|
|
1254
|
+
setAllowConnect: (allow) => {
|
|
1255
|
+
this.setAllowConnect(allow);
|
|
1256
|
+
},
|
|
1026
1257
|
edit: () => {},
|
|
1027
1258
|
resetField: () => {},
|
|
1028
1259
|
save: () => {
|
|
@@ -1033,6 +1264,12 @@ window.__ModuleLoader__.load({
|
|
|
1033
1264
|
}
|
|
1034
1265
|
};
|
|
1035
1266
|
}
|
|
1267
|
+
setAllowConnect(allow) {
|
|
1268
|
+
this.allowConnect = allow;
|
|
1269
|
+
this.allowTouched = true;
|
|
1270
|
+
this.failed = false;
|
|
1271
|
+
this.publish();
|
|
1272
|
+
}
|
|
1036
1273
|
editRow(index, patch) {
|
|
1037
1274
|
const row = this.rows[index];
|
|
1038
1275
|
if (row === void 0) return;
|
|
@@ -1059,7 +1296,9 @@ window.__ModuleLoader__.load({
|
|
|
1059
1296
|
if (!raw) return "empty";
|
|
1060
1297
|
const imported = rowsFromMcpPaste(raw);
|
|
1061
1298
|
if (imported.length === 0) return "invalid";
|
|
1062
|
-
|
|
1299
|
+
const snapshot = this.scope.getSnapshot();
|
|
1300
|
+
this.rows = mergeRowsByName(this.rows, imported).map((row) => enrichRowStatus(row, snapshot));
|
|
1301
|
+
this.allowConnect = true;
|
|
1063
1302
|
this.failed = false;
|
|
1064
1303
|
this.publish();
|
|
1065
1304
|
return "ok";
|
|
@@ -1067,6 +1306,10 @@ window.__ModuleLoader__.load({
|
|
|
1067
1306
|
removeRow(index) {
|
|
1068
1307
|
if (index < 0 || index >= this.rows.length) return;
|
|
1069
1308
|
this.rows = this.rows.toSpliced(index, 1);
|
|
1309
|
+
if (this.rows.length === 0) {
|
|
1310
|
+
this.allowConnect = false;
|
|
1311
|
+
this.allowTouched = false;
|
|
1312
|
+
}
|
|
1070
1313
|
this.failed = false;
|
|
1071
1314
|
if (!this.rows.some((r) => validateRow(r) !== void 0)) this.showErrors = false;
|
|
1072
1315
|
this.publish();
|
|
@@ -1074,7 +1317,9 @@ window.__ModuleLoader__.load({
|
|
|
1074
1317
|
discard() {
|
|
1075
1318
|
const snapshot = this.scope.getSnapshot();
|
|
1076
1319
|
if (snapshot.status !== "ready") return;
|
|
1077
|
-
this.rows = serversOf(snapshot).map(rowToUi);
|
|
1320
|
+
this.rows = serversOf(snapshot).map((draft) => rowToUi(draft, snapshot));
|
|
1321
|
+
this.allowConnect = allowOf(snapshot);
|
|
1322
|
+
this.allowTouched = false;
|
|
1078
1323
|
this.failed = false;
|
|
1079
1324
|
this.showErrors = false;
|
|
1080
1325
|
this.publish();
|
|
@@ -1093,12 +1338,20 @@ window.__ModuleLoader__.load({
|
|
|
1093
1338
|
this.showErrors = false;
|
|
1094
1339
|
this.publish();
|
|
1095
1340
|
const payload = this.rows.map(rowFromUi);
|
|
1341
|
+
const wantAllow = payload.length === 0 ? false : this.allowTouched ? this.allowConnect : true;
|
|
1342
|
+
this.allowConnect = wantAllow;
|
|
1343
|
+
await this.scope.set("allowConnect", wantAllow);
|
|
1096
1344
|
await this.scope.set("servers", payload);
|
|
1097
1345
|
const after = this.scope.getSnapshot();
|
|
1098
|
-
const landed = after.status === "ready" && JSON.stringify(serversOf(after)) === JSON.stringify(payload);
|
|
1346
|
+
const landed = after.status === "ready" && allowOf(after) === wantAllow && JSON.stringify(serversOf(after)) === JSON.stringify(payload);
|
|
1099
1347
|
this.saving = false;
|
|
1100
1348
|
this.failed = !landed;
|
|
1101
|
-
if (landed)
|
|
1349
|
+
if (landed) {
|
|
1350
|
+
this.seeded = true;
|
|
1351
|
+
this.allowTouched = false;
|
|
1352
|
+
this.rows = serversOf(after).map((draft) => rowToUi(draft, after));
|
|
1353
|
+
this.allowConnect = allowOf(after);
|
|
1354
|
+
}
|
|
1102
1355
|
this.publish();
|
|
1103
1356
|
}
|
|
1104
1357
|
};
|
|
@@ -1106,36 +1359,94 @@ window.__ModuleLoader__.load({
|
|
|
1106
1359
|
const raw = snapshot.value?.servers;
|
|
1107
1360
|
return Array.isArray(raw) ? raw.map(normalizeStoredRow) : [];
|
|
1108
1361
|
}
|
|
1109
|
-
function
|
|
1110
|
-
|
|
1111
|
-
if (!Array.isArray(raw)) return [];
|
|
1112
|
-
return raw.filter(isConnectedEntry);
|
|
1362
|
+
function allowOf(snapshot) {
|
|
1363
|
+
return snapshot.value?.allowConnect === true;
|
|
1113
1364
|
}
|
|
1114
1365
|
function noteOf(snapshot) {
|
|
1115
|
-
|
|
1366
|
+
const note = snapshot.value?.note;
|
|
1367
|
+
return typeof note === "string" ? note : "";
|
|
1368
|
+
}
|
|
1369
|
+
function connectedMap(snapshot) {
|
|
1370
|
+
const map = /* @__PURE__ */ new Map();
|
|
1371
|
+
const raw = snapshot.value?.connected;
|
|
1372
|
+
if (!Array.isArray(raw)) return map;
|
|
1373
|
+
for (const entry of raw) if (isConnectedEntry(entry)) map.set(entry.serverName, entry);
|
|
1374
|
+
return map;
|
|
1375
|
+
}
|
|
1376
|
+
function failureMap(snapshot) {
|
|
1377
|
+
const map = /* @__PURE__ */ new Map();
|
|
1378
|
+
const raw = snapshot.value?.connectFailures;
|
|
1379
|
+
if (!Array.isArray(raw)) return map;
|
|
1380
|
+
for (const entry of raw) {
|
|
1381
|
+
if (!entry || typeof entry !== "object") continue;
|
|
1382
|
+
const name = entry.serverName;
|
|
1383
|
+
const message = entry.message;
|
|
1384
|
+
if (typeof name === "string" && name && typeof message === "string") map.set(name, message);
|
|
1385
|
+
}
|
|
1386
|
+
return map;
|
|
1387
|
+
}
|
|
1388
|
+
function parkedSet(snapshot) {
|
|
1389
|
+
const raw = snapshot.value?.parked;
|
|
1390
|
+
return new Set(Array.isArray(raw) ? raw.filter((x) => typeof x === "string") : []);
|
|
1391
|
+
}
|
|
1392
|
+
function resolveRowStatus(serverName, snapshot) {
|
|
1393
|
+
const live = connectedMap(snapshot).get(serverName);
|
|
1394
|
+
if (live) return {
|
|
1395
|
+
status: live.status ?? "connected",
|
|
1396
|
+
toolCount: live.toolCount
|
|
1397
|
+
};
|
|
1398
|
+
const failure = failureMap(snapshot).get(serverName);
|
|
1399
|
+
if (failure !== void 0) return {
|
|
1400
|
+
status: "failed",
|
|
1401
|
+
toolCount: 0,
|
|
1402
|
+
failureMessage: failure
|
|
1403
|
+
};
|
|
1404
|
+
if (!allowOf(snapshot) || parkedSet(snapshot).has(serverName)) return {
|
|
1405
|
+
status: "parked",
|
|
1406
|
+
toolCount: 0
|
|
1407
|
+
};
|
|
1408
|
+
return {
|
|
1409
|
+
status: "idle",
|
|
1410
|
+
toolCount: 0
|
|
1411
|
+
};
|
|
1412
|
+
}
|
|
1413
|
+
function enrichRowStatus(row, snapshot) {
|
|
1414
|
+
const resolved = resolveRowStatus(row.serverName, snapshot);
|
|
1415
|
+
return {
|
|
1416
|
+
...row,
|
|
1417
|
+
...resolved
|
|
1418
|
+
};
|
|
1116
1419
|
}
|
|
1117
1420
|
function isConnectedEntry(value) {
|
|
1118
|
-
|
|
1421
|
+
if (!value || typeof value !== "object") return false;
|
|
1422
|
+
const row = value;
|
|
1423
|
+
return typeof row.id === "string" && typeof row.serverName === "string" && typeof row.kind === "string" && typeof row.toolCount === "number";
|
|
1119
1424
|
}
|
|
1120
|
-
function normalizeStoredRow(
|
|
1121
|
-
const
|
|
1122
|
-
const
|
|
1425
|
+
function normalizeStoredRow(raw) {
|
|
1426
|
+
const serverName = typeof raw.serverName === "string" ? raw.serverName.trim() : "";
|
|
1427
|
+
const url = typeof raw.url === "string" ? raw.url.trim() : "";
|
|
1428
|
+
const command = typeof raw.command === "string" ? raw.command.trim() : "";
|
|
1429
|
+
const cwd = typeof raw.cwd === "string" ? raw.cwd.trim() : "";
|
|
1430
|
+
const args = Array.isArray(raw.args) ? raw.args.filter((part) => typeof part === "string") : void 0;
|
|
1123
1431
|
return {
|
|
1124
|
-
serverName
|
|
1125
|
-
...url ? { url } :
|
|
1126
|
-
...
|
|
1127
|
-
...
|
|
1432
|
+
serverName,
|
|
1433
|
+
...url ? { url } : {},
|
|
1434
|
+
...command ? { command } : {},
|
|
1435
|
+
...args && args.length > 0 ? { args } : {},
|
|
1436
|
+
...cwd ? { cwd } : {}
|
|
1128
1437
|
};
|
|
1129
1438
|
}
|
|
1130
|
-
function rowToUi(
|
|
1131
|
-
const
|
|
1439
|
+
function rowToUi(draft, snapshot) {
|
|
1440
|
+
const transport = draft.url ? "http" : "stdio";
|
|
1441
|
+
const resolved = resolveRowStatus(draft.serverName, snapshot);
|
|
1132
1442
|
return {
|
|
1133
|
-
serverName:
|
|
1134
|
-
transport
|
|
1135
|
-
command:
|
|
1136
|
-
url,
|
|
1137
|
-
args:
|
|
1138
|
-
cwd:
|
|
1443
|
+
serverName: draft.serverName,
|
|
1444
|
+
transport,
|
|
1445
|
+
command: draft.command ?? "",
|
|
1446
|
+
url: draft.url ?? "",
|
|
1447
|
+
args: (draft.args ?? []).join(", "),
|
|
1448
|
+
cwd: draft.cwd ?? "",
|
|
1449
|
+
...resolved
|
|
1139
1450
|
};
|
|
1140
1451
|
}
|
|
1141
1452
|
function rowFromUi(row) {
|
|
@@ -1144,7 +1455,7 @@ window.__ModuleLoader__.load({
|
|
|
1144
1455
|
serverName,
|
|
1145
1456
|
url: row.url.trim()
|
|
1146
1457
|
};
|
|
1147
|
-
const args = row.args.split(",").map((part) => part.trim()).filter(
|
|
1458
|
+
const args = row.args.split(",").map((part) => part.trim()).filter(Boolean);
|
|
1148
1459
|
const cwd = row.cwd.trim();
|
|
1149
1460
|
return {
|
|
1150
1461
|
serverName,
|
|
@@ -1153,34 +1464,17 @@ window.__ModuleLoader__.load({
|
|
|
1153
1464
|
...cwd ? { cwd } : {}
|
|
1154
1465
|
};
|
|
1155
1466
|
}
|
|
1156
|
-
|
|
1467
|
+
function validateRow(row) {
|
|
1468
|
+
if (!row.serverName.trim()) return "name";
|
|
1469
|
+
if (row.transport === "http") return row.url.trim() ? void 0 : "url";
|
|
1470
|
+
return row.command.trim() ? void 0 : "command";
|
|
1471
|
+
}
|
|
1157
1472
|
function mergeRowsByName(existing, imported) {
|
|
1158
1473
|
const byName = new Map(existing.map((row) => [row.serverName, row]));
|
|
1159
1474
|
for (const row of imported) byName.set(row.serverName, row);
|
|
1160
|
-
|
|
1161
|
-
for (const row of existing) if (!order.includes(row.serverName)) order.push(row.serverName);
|
|
1162
|
-
for (const row of imported) if (!order.includes(row.serverName)) order.push(row.serverName);
|
|
1163
|
-
return order.map((name) => byName.get(name)).filter(Boolean);
|
|
1164
|
-
}
|
|
1165
|
-
function namedRowToUi(name, row) {
|
|
1166
|
-
const serverName = name.trim();
|
|
1167
|
-
if (!serverName) return void 0;
|
|
1168
|
-
const url = typeof row.url === "string" ? row.url.trim() : "";
|
|
1169
|
-
const command = typeof row.command === "string" ? row.command.trim() : "";
|
|
1170
|
-
if (!url && !command) return void 0;
|
|
1171
|
-
return {
|
|
1172
|
-
serverName,
|
|
1173
|
-
transport: url ? "http" : "stdio",
|
|
1174
|
-
command,
|
|
1175
|
-
url,
|
|
1176
|
-
args: Array.isArray(row.args) ? row.args.map(String).join(", ") : "",
|
|
1177
|
-
cwd: typeof row.cwd === "string" ? row.cwd : ""
|
|
1178
|
-
};
|
|
1475
|
+
return [...byName.values()];
|
|
1179
1476
|
}
|
|
1180
|
-
/**
|
|
1181
|
-
* Cursor / Trae / Claude Desktop paste: `{ "mcpServers": { "name": { "command", "args" } } }`.
|
|
1182
|
-
* Also accepts a bare name map or a Face array of `{ serverName, command }`.
|
|
1183
|
-
*/
|
|
1477
|
+
/** Parse Cursor/Trae `{ mcpServers: { name: { command|url, args? } } }` into rows. */
|
|
1184
1478
|
function rowsFromMcpPaste(raw) {
|
|
1185
1479
|
let parsed;
|
|
1186
1480
|
try {
|
|
@@ -1188,32 +1482,169 @@ window.__ModuleLoader__.load({
|
|
|
1188
1482
|
} catch {
|
|
1189
1483
|
return [];
|
|
1190
1484
|
}
|
|
1191
|
-
if (Array.isArray(parsed))
|
|
1192
|
-
const out = [];
|
|
1193
|
-
for (const row of parsed) {
|
|
1194
|
-
if (!row || typeof row !== "object" || Array.isArray(row)) continue;
|
|
1195
|
-
const o = row;
|
|
1196
|
-
const mapped = namedRowToUi(String(o.serverName ?? ""), o);
|
|
1197
|
-
if (mapped) out.push(mapped);
|
|
1198
|
-
}
|
|
1199
|
-
return out;
|
|
1200
|
-
}
|
|
1201
|
-
if (!parsed || typeof parsed !== "object") return [];
|
|
1485
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return [];
|
|
1202
1486
|
const root = parsed;
|
|
1203
|
-
const
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
const
|
|
1208
|
-
if (
|
|
1487
|
+
const block = root.mcpServers ?? root.servers;
|
|
1488
|
+
if (!block || typeof block !== "object" || Array.isArray(block)) return [];
|
|
1489
|
+
const rows = [];
|
|
1490
|
+
for (const [name, value] of Object.entries(block)) {
|
|
1491
|
+
const serverName = name.trim();
|
|
1492
|
+
if (!serverName || !value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
1493
|
+
const entry = value;
|
|
1494
|
+
const url = typeof entry.url === "string" ? entry.url.trim() : "";
|
|
1495
|
+
const command = typeof entry.command === "string" ? entry.command.trim() : "";
|
|
1496
|
+
const cwd = typeof entry.cwd === "string" ? entry.cwd.trim() : "";
|
|
1497
|
+
const argsList = Array.isArray(entry.args) ? entry.args.filter((part) => typeof part === "string") : [];
|
|
1498
|
+
if (url) {
|
|
1499
|
+
rows.push({
|
|
1500
|
+
serverName,
|
|
1501
|
+
transport: "http",
|
|
1502
|
+
command: "",
|
|
1503
|
+
url,
|
|
1504
|
+
args: "",
|
|
1505
|
+
cwd: "",
|
|
1506
|
+
status: "idle",
|
|
1507
|
+
toolCount: 0
|
|
1508
|
+
});
|
|
1509
|
+
continue;
|
|
1510
|
+
}
|
|
1511
|
+
if (!command) continue;
|
|
1512
|
+
rows.push({
|
|
1513
|
+
serverName,
|
|
1514
|
+
transport: "stdio",
|
|
1515
|
+
command,
|
|
1516
|
+
url: "",
|
|
1517
|
+
args: argsList.join(", "),
|
|
1518
|
+
cwd,
|
|
1519
|
+
status: "idle",
|
|
1520
|
+
toolCount: 0
|
|
1521
|
+
});
|
|
1209
1522
|
}
|
|
1210
|
-
return
|
|
1523
|
+
return rows;
|
|
1211
1524
|
}
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1525
|
+
//#endregion
|
|
1526
|
+
//#region src/client/web-search-card-controller.ts
|
|
1527
|
+
/** Namespace Host serves for web_search provider preference. */
|
|
1528
|
+
const WEB_SEARCH_NS = "web-search";
|
|
1529
|
+
/** Credential refs Face emits on `credentials/updated` (envVar of the slot). */
|
|
1530
|
+
const WEB_SEARCH_TAVILY_REF = "XRK_TAVILY_API_KEY";
|
|
1531
|
+
const WEB_SEARCH_BRAVE_REF = "XRK_BRAVE_SEARCH_API_KEY";
|
|
1532
|
+
const TAVILY_FIELD = "tavilyApiKey";
|
|
1533
|
+
const BRAVE_FIELD = "braveApiKey";
|
|
1534
|
+
const PROVIDERS = [
|
|
1535
|
+
"auto",
|
|
1536
|
+
"tavily",
|
|
1537
|
+
"brave",
|
|
1538
|
+
"parallel-free",
|
|
1539
|
+
"duckduckgo"
|
|
1540
|
+
];
|
|
1541
|
+
function providerField() {
|
|
1542
|
+
return {
|
|
1543
|
+
field: "provider",
|
|
1544
|
+
format: (value) => typeof value === "string" && value ? value : "auto",
|
|
1545
|
+
parse: (text) => {
|
|
1546
|
+
const trimmed = text.trim() || "auto";
|
|
1547
|
+
if (!PROVIDERS.includes(trimmed)) return void 0;
|
|
1548
|
+
return {
|
|
1549
|
+
kind: "set",
|
|
1550
|
+
value: trimmed
|
|
1551
|
+
};
|
|
1552
|
+
}
|
|
1553
|
+
};
|
|
1216
1554
|
}
|
|
1555
|
+
/** Bridges the `web-search` scope and Tavily/Brave credentials onto the card. */
|
|
1556
|
+
var WebSearchCardController = class {
|
|
1557
|
+
api;
|
|
1558
|
+
form;
|
|
1559
|
+
store;
|
|
1560
|
+
tavily = {
|
|
1561
|
+
configured: false,
|
|
1562
|
+
writable: true
|
|
1563
|
+
};
|
|
1564
|
+
brave = {
|
|
1565
|
+
configured: false,
|
|
1566
|
+
writable: true
|
|
1567
|
+
};
|
|
1568
|
+
/**
|
|
1569
|
+
* @param scope - the bound settings scope for the `web-search` namespace.
|
|
1570
|
+
* @param api - wire face for Credentials (keys never ride settings).
|
|
1571
|
+
*/
|
|
1572
|
+
constructor(scope, api) {
|
|
1573
|
+
this.api = api;
|
|
1574
|
+
this.form = new CardForm(scope, [providerField(), textField("region")], [{
|
|
1575
|
+
field: TAVILY_FIELD,
|
|
1576
|
+
write: (text) => this.writeKey(WEB_SEARCH_TAVILY_REF, text)
|
|
1577
|
+
}, {
|
|
1578
|
+
field: BRAVE_FIELD,
|
|
1579
|
+
write: (text) => this.writeKey(WEB_SEARCH_BRAVE_REF, text)
|
|
1580
|
+
}]);
|
|
1581
|
+
this.store = this.form.bind(() => this.projection());
|
|
1582
|
+
this.readCredentials();
|
|
1583
|
+
}
|
|
1584
|
+
projection() {
|
|
1585
|
+
return {
|
|
1586
|
+
...this.form.shell(),
|
|
1587
|
+
provider: this.form.field("provider"),
|
|
1588
|
+
region: this.form.field("region"),
|
|
1589
|
+
tavilyApiKey: this.form.field(TAVILY_FIELD),
|
|
1590
|
+
braveApiKey: this.form.field(BRAVE_FIELD),
|
|
1591
|
+
tavilyConfigured: this.tavily.configured,
|
|
1592
|
+
tavilyWritable: this.tavily.writable,
|
|
1593
|
+
braveConfigured: this.brave.configured,
|
|
1594
|
+
braveWritable: this.brave.writable
|
|
1595
|
+
};
|
|
1596
|
+
}
|
|
1597
|
+
/** Ask the credentials domain about Tavily + Brave slots. */
|
|
1598
|
+
async readCredentials() {
|
|
1599
|
+
let response;
|
|
1600
|
+
try {
|
|
1601
|
+
response = await this.api.credentials.describe({ refs: [WEB_SEARCH_TAVILY_REF, WEB_SEARCH_BRAVE_REF] });
|
|
1602
|
+
} catch {
|
|
1603
|
+
return;
|
|
1604
|
+
}
|
|
1605
|
+
if (!response.result.ok) return;
|
|
1606
|
+
const map = response.result.value.credentials;
|
|
1607
|
+
const nextTavily = {
|
|
1608
|
+
configured: map["XRK_TAVILY_API_KEY"]?.configured ?? false,
|
|
1609
|
+
writable: map["XRK_TAVILY_API_KEY"]?.writable ?? true
|
|
1610
|
+
};
|
|
1611
|
+
const nextBrave = {
|
|
1612
|
+
configured: map["XRK_BRAVE_SEARCH_API_KEY"]?.configured ?? false,
|
|
1613
|
+
writable: map["XRK_BRAVE_SEARCH_API_KEY"]?.writable ?? true
|
|
1614
|
+
};
|
|
1615
|
+
if (nextTavily.configured === this.tavily.configured && nextTavily.writable === this.tavily.writable && nextBrave.configured === this.brave.configured && nextBrave.writable === this.brave.writable) return;
|
|
1616
|
+
this.tavily = nextTavily;
|
|
1617
|
+
this.brave = nextBrave;
|
|
1618
|
+
this.store.set(this.projection());
|
|
1619
|
+
}
|
|
1620
|
+
/**
|
|
1621
|
+
* Re-read when Host reports a watched credential changed (e.g. Credentials page).
|
|
1622
|
+
* @param ref - envVar / slot ref from `credentials/updated`.
|
|
1623
|
+
*/
|
|
1624
|
+
refreshCredential(ref) {
|
|
1625
|
+
if (ref !== "XRK_TAVILY_API_KEY" && ref !== "XRK_BRAVE_SEARCH_API_KEY") return;
|
|
1626
|
+
this.readCredentials();
|
|
1627
|
+
}
|
|
1628
|
+
/** @returns the card's snapshot and its form actions. */
|
|
1629
|
+
inject() {
|
|
1630
|
+
return {
|
|
1631
|
+
hooks: { webSearchCard: this.store },
|
|
1632
|
+
...this.form.actions()
|
|
1633
|
+
};
|
|
1634
|
+
}
|
|
1635
|
+
async writeKey(ref, value) {
|
|
1636
|
+
try {
|
|
1637
|
+
await this.api.credentials.set({
|
|
1638
|
+
ref,
|
|
1639
|
+
value
|
|
1640
|
+
});
|
|
1641
|
+
} catch {}
|
|
1642
|
+
await this.readCredentials();
|
|
1643
|
+
if (ref === "XRK_TAVILY_API_KEY") return this.tavily.configured;
|
|
1644
|
+
if (ref === "XRK_BRAVE_SEARCH_API_KEY") return this.brave.configured;
|
|
1645
|
+
return false;
|
|
1646
|
+
}
|
|
1647
|
+
};
|
|
1217
1648
|
//#endregion
|
|
1218
1649
|
//#region src/client/tab-store.ts
|
|
1219
1650
|
/** Reads the served namespaces and pairs them with the cards that claim them. */
|
|
@@ -1319,7 +1750,7 @@ window.__ModuleLoader__.load({
|
|
|
1319
1750
|
agentLoopMaxParallel: "Parallel tool calls",
|
|
1320
1751
|
agentLoopMaxParallelHint: "Upper bound on parallel-safe calls running at once within one step.",
|
|
1321
1752
|
mcpTitle: "MCP servers",
|
|
1322
|
-
mcpDescription: "Paste Cursor / Trae style JSON
|
|
1753
|
+
mcpDescription: "Paste Cursor / Trae style JSON, then save — servers mount on save (no separate env step).",
|
|
1323
1754
|
mcpConnectedHeading: "Connected now",
|
|
1324
1755
|
mcpServersHeading: "Servers",
|
|
1325
1756
|
mcpServersEmpty: "No servers yet. Paste a JSON block below and add.",
|
|
@@ -1346,9 +1777,31 @@ window.__ModuleLoader__.load({
|
|
|
1346
1777
|
mcpCwdHint: "Optional. Leave blank to use the Host default.",
|
|
1347
1778
|
mcpRowInvalid: "Each server needs a name and a command or URL.",
|
|
1348
1779
|
mcpToolsLabel: "tools",
|
|
1780
|
+
mcpAllowConnect: "Allow connect",
|
|
1781
|
+
mcpAllowConnectHint: "Saving a non-empty list connects automatically. Turn off and save to keep the list without mounting tools.",
|
|
1349
1782
|
mcpStatusConnected: "Connected",
|
|
1350
1783
|
mcpStatusReconnecting: "Reconnecting",
|
|
1351
|
-
mcpStatusGaveUp: "Gave up"
|
|
1784
|
+
mcpStatusGaveUp: "Gave up",
|
|
1785
|
+
mcpStatusParked: "Parked",
|
|
1786
|
+
mcpStatusFailed: "Failed",
|
|
1787
|
+
mcpStatusIdle: "Not connected",
|
|
1788
|
+
webSearchTitle: "Web search",
|
|
1789
|
+
webSearchDescription: "Provider and keys for the web_search tool. Keys save through Credentials, not settings.yaml.",
|
|
1790
|
+
webSearchProvider: "Provider",
|
|
1791
|
+
webSearchProviderHint: "Auto picks Tavily or Brave when a key is set, otherwise parallel-free → DuckDuckGo.",
|
|
1792
|
+
webSearchProviderAuto: "Auto",
|
|
1793
|
+
webSearchProviderTavily: "Tavily",
|
|
1794
|
+
webSearchProviderBrave: "Brave",
|
|
1795
|
+
webSearchProviderParallel: "Parallel free",
|
|
1796
|
+
webSearchProviderDuckduckgo: "DuckDuckGo",
|
|
1797
|
+
webSearchRegion: "DuckDuckGo region",
|
|
1798
|
+
webSearchRegionHint: "Optional kl region (for example us-en). Used when DuckDuckGo runs.",
|
|
1799
|
+
webSearchTavilyKey: "Tavily API key",
|
|
1800
|
+
webSearchTavilyKeyHint: "Required when provider is Tavily (or Auto with this key set). Leave blank to keep the stored key.",
|
|
1801
|
+
webSearchBraveKey: "Brave Search API key",
|
|
1802
|
+
webSearchBraveKeyHint: "Required when provider is Brave (or Auto with this key set). Leave blank to keep the stored key.",
|
|
1803
|
+
webSearchKeySet: "Configured",
|
|
1804
|
+
webSearchKeyUnset: "Not set"
|
|
1352
1805
|
};
|
|
1353
1806
|
/** Simplified Chinese copy. */
|
|
1354
1807
|
const zh = {
|
|
@@ -1380,7 +1833,7 @@ window.__ModuleLoader__.load({
|
|
|
1380
1833
|
agentLoopMaxParallel: "并行工具调用数",
|
|
1381
1834
|
agentLoopMaxParallelHint: "同一步内最多同时运行多少个可并行的调用。",
|
|
1382
1835
|
mcpTitle: "MCP 服务器",
|
|
1383
|
-
mcpDescription: "
|
|
1836
|
+
mcpDescription: "粘贴 Trae / Cursor 风格 mcpServers JSON,保存后会挂载(不必再先开环境变量)。",
|
|
1384
1837
|
mcpConnectedHeading: "当前已连接",
|
|
1385
1838
|
mcpServersHeading: "服务器",
|
|
1386
1839
|
mcpServersEmpty: "还没有服务器。在下方粘贴 JSON 块后点添加。",
|
|
@@ -1407,9 +1860,31 @@ window.__ModuleLoader__.load({
|
|
|
1407
1860
|
mcpCwdHint: "可选。留空使用 Host 默认。",
|
|
1408
1861
|
mcpRowInvalid: "每条服务器需要名称,以及命令或 URL。",
|
|
1409
1862
|
mcpToolsLabel: "个工具",
|
|
1863
|
+
mcpAllowConnect: "允许连接",
|
|
1864
|
+
mcpAllowConnectHint: "列表非空时保存会自动连接。关掉此项再保存可只保留列表、不挂载工具。",
|
|
1410
1865
|
mcpStatusConnected: "已连接",
|
|
1411
1866
|
mcpStatusReconnecting: "重连中",
|
|
1412
|
-
mcpStatusGaveUp: "已放弃"
|
|
1867
|
+
mcpStatusGaveUp: "已放弃",
|
|
1868
|
+
mcpStatusParked: "已停放",
|
|
1869
|
+
mcpStatusFailed: "失败",
|
|
1870
|
+
mcpStatusIdle: "未连接",
|
|
1871
|
+
webSearchTitle: "网页搜索",
|
|
1872
|
+
webSearchDescription: "web_search 工具的提供方与密钥。密钥经「凭据」落盘,不写入 settings.yaml。",
|
|
1873
|
+
webSearchProvider: "提供方",
|
|
1874
|
+
webSearchProviderHint: "自动:有密钥用 Tavily/Brave,否则 parallel-free → DuckDuckGo。",
|
|
1875
|
+
webSearchProviderAuto: "自动",
|
|
1876
|
+
webSearchProviderTavily: "Tavily",
|
|
1877
|
+
webSearchProviderBrave: "Brave",
|
|
1878
|
+
webSearchProviderParallel: "Parallel 免费",
|
|
1879
|
+
webSearchProviderDuckduckgo: "DuckDuckGo",
|
|
1880
|
+
webSearchRegion: "DuckDuckGo 区域",
|
|
1881
|
+
webSearchRegionHint: "可选 kl 区域(如 us-en),仅 DuckDuckGo 时生效。",
|
|
1882
|
+
webSearchTavilyKey: "Tavily API 密钥",
|
|
1883
|
+
webSearchTavilyKeyHint: "提供方为 Tavily(或自动且已配置此密钥)时需要。留空表示保留已存密钥。",
|
|
1884
|
+
webSearchBraveKey: "Brave Search API 密钥",
|
|
1885
|
+
webSearchBraveKeyHint: "提供方为 Brave(或自动且已配置此密钥)时需要。留空表示保留已存密钥。",
|
|
1886
|
+
webSearchKeySet: "已配置",
|
|
1887
|
+
webSearchKeyUnset: "未设置"
|
|
1413
1888
|
};
|
|
1414
1889
|
//#endregion
|
|
1415
1890
|
//#region src/client/index.ts
|
|
@@ -1437,6 +1912,7 @@ window.__ModuleLoader__.load({
|
|
|
1437
1912
|
const bash = new BashCardController(ctx.settingsScope.bind({ namespace: SHELL_NS }));
|
|
1438
1913
|
const agentLoop = new AgentLoopCardController(ctx.settingsScope.bind({ namespace: AGENT_LOOP_NS }));
|
|
1439
1914
|
const mcp = new McpCardController(ctx.settingsScope.bind({ namespace: "mcp" }));
|
|
1915
|
+
const webSearch = new WebSearchCardController(ctx.settingsScope.bind({ namespace: WEB_SEARCH_NS }), api);
|
|
1440
1916
|
const configurable = new ConfigurablePluginsTabController(api, () => ctx.slots.entries("settings.plugin.item"));
|
|
1441
1917
|
ctx.effect(() => () => {
|
|
1442
1918
|
configurable.dispose();
|
|
@@ -1447,6 +1923,9 @@ window.__ModuleLoader__.load({
|
|
|
1447
1923
|
ctx.effect(() => ctx.on("connection/reset", () => {
|
|
1448
1924
|
configurable.load();
|
|
1449
1925
|
}), "ui-settings-plugins: served-namespace reconnect");
|
|
1926
|
+
ctx.effect(() => ctx.remote.$on("credentials/updated", (ref) => {
|
|
1927
|
+
if (ref === "XRK_TAVILY_API_KEY" || ref === "XRK_BRAVE_SEARCH_API_KEY") webSearch.refreshCredential(ref);
|
|
1928
|
+
}), "ui-settings-plugins: web-search credential invalidations");
|
|
1450
1929
|
ctx.effect(() => ctx.slots.subscribe("settings.plugin.item", () => {
|
|
1451
1930
|
configurable.refresh();
|
|
1452
1931
|
}), "ui-settings-plugins: card ledger");
|
|
@@ -1510,6 +1989,12 @@ window.__ModuleLoader__.load({
|
|
|
1510
1989
|
locale: NS,
|
|
1511
1990
|
inject: () => mcp.inject()
|
|
1512
1991
|
}, McpCard);
|
|
1992
|
+
yield ctx.slots.register({
|
|
1993
|
+
name: "settings.plugin.item",
|
|
1994
|
+
key: WEB_SEARCH_NS,
|
|
1995
|
+
locale: NS,
|
|
1996
|
+
inject: () => webSearch.inject()
|
|
1997
|
+
}, WebSearchCard);
|
|
1513
1998
|
yield ctx.slots.register({
|
|
1514
1999
|
name: "settings.plugin.item",
|
|
1515
2000
|
key: SHELL_NS,
|
|
@@ -1525,6 +2010,9 @@ window.__ModuleLoader__.load({
|
|
|
1525
2010
|
});
|
|
1526
2011
|
}
|
|
1527
2012
|
//#endregion
|
|
2013
|
+
exports.WEB_SEARCH_BRAVE_REF = WEB_SEARCH_BRAVE_REF;
|
|
2014
|
+
exports.WEB_SEARCH_NS = WEB_SEARCH_NS;
|
|
2015
|
+
exports.WEB_SEARCH_TAVILY_REF = WEB_SEARCH_TAVILY_REF;
|
|
1528
2016
|
exports.apply = apply;
|
|
1529
2017
|
exports.inject = inject;
|
|
1530
2018
|
return module.exports;
|