@auggieteo/dsh-mcp-adapter 0.2.0 → 0.2.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/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@ All notable changes to this project are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [v0.2.1] - 2026-09-06
8
+
9
+ ### Added
10
+
11
+ - `scripts/patch-dsh-settings-nav-icon.mjs`: patches the installed DSH settings shell so the `mcp` nav row in Settings shows a connection icon (`IconLinkOutline16`) instead of the generic settings-gear fallback. The icon mapping is DSH shell chrome that this plugin cannot reach through the `settings.section` slot (it accepts only `id`, `order`, `label`). The insert is idempotent and marked `// dsh-mcp-adapter`; `--revert` restores the original bytes. A DSH upgrade replaces the patched file, so re-run the script afterwards, then restart `dsh web` and refresh the page.
12
+
13
+ ### Changed
14
+
15
+ - Settings > MCP has a single Add Server entry point: the dialog now offers an Input fields mode for one Server and a Paste JSON mode for a standard `mcpServers` object (existing names are replaced), replacing the separate Import JSON button and dialog in both the toolbar and the empty state.
16
+
17
+ ### Fixed
18
+
19
+ - The plugin failed to load on DSH 0.1.2-rc.1 with `failed to apply loader entry … cannot get property "remote.settings" without inject`: the runner mounts the settings namespace as the traced dotted service `remote.settings`, so the plain `ctx.remote?.settings` read is governed and throws for plugins that do not declare it — while declaring it would park the plugin forever on 0.1.1-rc.2, where the namespace is never mounted. The write face is now resolved through the inject-free `ctx.get('remote.settings')`, which works on both generations ([ADR 0009](docs/adr/0009-dual-generation-settings-api.md)).
20
+ - The Add Server and Import JSON dialogs follow the host dialog theme again: the modal card now surfaces on `bg-layer-2` with the shared `--dsw-elevation-prominent` treatment and the overlay mask blurs like the host Modal primitive, instead of the off-palette `bg-overlay` fill and a hardcoded drop shadow.
21
+
7
22
  ## [v0.2.0] - 2026-09-05
8
23
 
9
24
  Everything from v0.1.2 through this release: the six deferred v1 features (#8–#12, #14), the dual-generation DSH compatibility fix, and the standard-readme documentation pass.
@@ -4,6 +4,8 @@ The Adapter's client bundle once read `ctx.connection.api.settings` directly. DS
4
4
 
5
5
  We resolve the write face at apply time (`src/client/settings-api.js`) and prefer `ctx.remote.settings` when it exists; otherwise we fall back to the 0.1.1-rc.2 `ctx.connection.api.settings` face. Both normalize to the controller's existing contract — `update`/`mutate` take one request object and answer `{ result: { ok, value | error } }` — so `McpSettingsController` and the host stay generation-agnostic. The client declares `remote` in its `inject` (the service exists in both generations; `remote.settings` does not exist on 0.1.1-rc.2 and stays undeclared, so the runner never parks waiting for it), and `package.json` adds `@deepseek-ai/dsh-api-remotes` to `dsh.client.inject` so the typed settings namespace mounts before consumers apply. On the host, `MCP_SETTINGS_NAMESPACE` becomes the plain `'mcp'` string: branding was type-only on 0.1.1-rc.2, and 0.1.2-rc.1 accepts the validated raw string. The peer dependency widens to `^0.1.1-rc.2 || ^0.1.2-rc.1`.
6
6
 
7
+ *Correction:* the original resolution read the rc.1 face as `ctx.remote?.settings`, assuming a plain property. The rc.1 runner instead mounts the namespace as the traced dotted service `remote.settings`: reading through `ctx.remote` composes that key, and cordis throws `cannot get property "remote.settings" without inject` for any plugin that did not declare the dotted service — which crashed this plugin at apply with a failed loader entry. Declaring it is not an option either: a declared-but-never-mounted service keeps the fiber from ever applying, which is exactly the 0.1.1-rc.2 case. The face is therefore resolved through cordis's inject-free `ctx.get('remote.settings')`, which answers the mounted namespace on 0.1.2-rc.1 via the root isolate and undefined on 0.1.1-rc.2, keeping the fallback reachable on both generations; the plain-property read remains as a legacy fallback for runners that expose the face as a plain property.
8
+
7
9
  Considered options: shipping a 0.1.2-only release and telling 0.1.1-rc.2 users to upgrade was rejected because the harness is in flux and plugin releases should not force harness moves; probing `ctx.remote.$host` or version strings was rejected because face presence is the actual capability signal and survives future renames better. A hard failure with upgrade guidance is kept for a hypothetical third shape, so a future break surfaces as one clear message instead of an `undefined` read.
8
10
 
9
11
  Consequences: the `apply`-level test suite (`test/client-apply.test.js`) compiles the real client entry and drives both fake generations, locking the fallback contract. When DSH drops 0.1.1-rc.2 support, the fallback branch, the legacy fake, and the README note are the removal surface — the controller and host need no changes.
package/lib/client.js CHANGED
@@ -647,6 +647,7 @@ function useEscapeClose(onClose) {
647
647
  }, [onClose]);
648
648
  }
649
649
  function AddServerDialog({ controller, busy, onClose }) {
650
+ const [mode, setMode] = (0, import_react.useState)("form");
650
651
  const [name, setName] = (0, import_react.useState)("");
651
652
  const [transport, setTransport] = (0, import_react.useState)("stdio");
652
653
  const [command, setCommand] = (0, import_react.useState)("");
@@ -654,11 +655,28 @@ function AddServerDialog({ controller, busy, onClose }) {
654
655
  const [argsText, setArgsText] = (0, import_react.useState)("[]");
655
656
  const [auth, setAuth] = (0, import_react.useState)("headers");
656
657
  const [scopesText, setScopesText] = (0, import_react.useState)("");
658
+ const [jsonText, setJsonText] = (0, import_react.useState)('{\n "mcpServers": {\n \n }\n}');
657
659
  const [error, setError] = (0, import_react.useState)();
658
660
  useEscapeClose(onClose);
661
+ const switchMode = (next) => {
662
+ setMode(next);
663
+ setError(void 0);
664
+ };
659
665
  const submit = async (event) => {
660
666
  event.preventDefault();
661
667
  setError(void 0);
668
+ if (mode === "json") {
669
+ try {
670
+ parseMcpImport(jsonText);
671
+ } catch (nextError) {
672
+ setError(nextError instanceof Error ? nextError.message : String(nextError));
673
+ return;
674
+ }
675
+ const result = await controller.importJson(jsonText);
676
+ if (result) onClose();
677
+ else setError("The Host rejected this import. Review the page error and retry.");
678
+ return;
679
+ }
662
680
  let config;
663
681
  try {
664
682
  config = normalizeServerConfig(
@@ -677,170 +695,165 @@ function AddServerDialog({ controller, busy, onClose }) {
677
695
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mcp-card-head", children: [
678
696
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
679
697
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "mcp-modal-title", children: "Add Server" }),
680
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mcp-muted", children: "Configure one stdio command or one HTTP URL." })
698
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mcp-muted", children: "Fill in the fields for one Server, or paste an mcpServers JSON." })
681
699
  ] }),
682
700
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "mcp-button", onClick: onClose, children: "Close" })
683
701
  ] }),
684
- error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mcp-error", role: "alert", children: error }),
685
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mcp-field", children: [
686
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "Name" }),
702
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mcp-dialog-tabs", role: "tablist", "aria-label": "Add Server input mode", children: [
687
703
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
688
- "input",
704
+ "button",
689
705
  {
690
- autoFocus: true,
691
- className: "mcp-input",
692
- value: name,
706
+ type: "button",
707
+ role: "tab",
708
+ "aria-selected": mode === "form",
709
+ className: mode === "form" ? "mcp-dialog-tab mcp-dialog-tab-active" : "mcp-dialog-tab",
693
710
  disabled: busy,
694
- onChange: (event) => setName(event.target.value),
695
- placeholder: "github"
711
+ onClick: () => switchMode("form"),
712
+ children: "Input fields"
713
+ }
714
+ ),
715
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
716
+ "button",
717
+ {
718
+ type: "button",
719
+ role: "tab",
720
+ "aria-selected": mode === "json",
721
+ className: mode === "json" ? "mcp-dialog-tab mcp-dialog-tab-active" : "mcp-dialog-tab",
722
+ disabled: busy,
723
+ onClick: () => switchMode("json"),
724
+ children: "Paste JSON"
696
725
  }
697
726
  )
698
727
  ] }),
699
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mcp-field", children: [
700
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "Transport" }),
701
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
702
- "select",
728
+ error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mcp-error", role: "alert", children: error }),
729
+ mode === "json" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mcp-field", children: [
730
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "MCP Config JSON" }),
731
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
732
+ "textarea",
703
733
  {
704
- className: "mcp-select",
705
- value: transport,
734
+ autoFocus: true,
735
+ className: "mcp-textarea",
736
+ style: { minHeight: 280 },
737
+ value: jsonText,
706
738
  disabled: busy,
707
- onChange: (event) => setTransport(event.target.value),
708
- children: [
709
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "stdio", children: "stdio" }),
710
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "http", children: "Streamable HTTP" })
711
- ]
739
+ spellCheck: false,
740
+ onChange: (event) => setJsonText(event.target.value)
712
741
  }
713
- )
742
+ ),
743
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-muted", children: "One or more Servers. A name that already exists is replaced." })
714
744
  ] }),
715
- transport === "stdio" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
745
+ mode === "form" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
716
746
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mcp-field", children: [
717
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "Command" }),
747
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "Name" }),
718
748
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
719
749
  "input",
720
750
  {
751
+ autoFocus: true,
721
752
  className: "mcp-input",
722
- value: command,
753
+ value: name,
723
754
  disabled: busy,
724
- onChange: (event) => setCommand(event.target.value),
725
- placeholder: "npx"
755
+ onChange: (event) => setName(event.target.value),
756
+ placeholder: "github"
726
757
  }
727
758
  )
728
759
  ] }),
729
760
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mcp-field", children: [
730
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "Args as a JSON array" }),
731
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
732
- "textarea",
761
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "Transport" }),
762
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
763
+ "select",
733
764
  {
734
- className: "mcp-textarea",
735
- value: argsText,
765
+ className: "mcp-select",
766
+ value: transport,
736
767
  disabled: busy,
737
- placeholder: '["-y", "@modelcontextprotocol/server-github"]',
738
- onChange: (event) => setArgsText(event.target.value),
739
- spellCheck: false
740
- }
741
- )
742
- ] })
743
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
744
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mcp-field", children: [
745
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "URL" }),
746
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
747
- "input",
748
- {
749
- className: "mcp-input",
750
- value: url,
751
- disabled: busy,
752
- onChange: (event) => setUrl(event.target.value),
753
- placeholder: "https://example.com/mcp"
768
+ onChange: (event) => setTransport(event.target.value),
769
+ children: [
770
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "stdio", children: "stdio" }),
771
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "http", children: "Streamable HTTP" })
772
+ ]
754
773
  }
755
774
  )
756
775
  ] }),
757
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mcp-field-row", children: [
776
+ transport === "stdio" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
758
777
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mcp-field", children: [
759
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "HTTP authentication" }),
760
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
761
- "select",
778
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "Command" }),
779
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
780
+ "input",
762
781
  {
763
- className: "mcp-select",
764
- value: auth,
782
+ className: "mcp-input",
783
+ value: command,
765
784
  disabled: busy,
766
- title: "Static headers send fixed values on every request. OAuth 2.0 with PKCE signs in through the provider in your browser.",
767
- onChange: (event) => setAuth(event.target.value),
768
- children: [
769
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "headers", children: "Static headers" }),
770
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "oauth", children: "OAuth 2.0 with PKCE" })
771
- ]
785
+ onChange: (event) => setCommand(event.target.value),
786
+ placeholder: "npx"
772
787
  }
773
788
  )
774
789
  ] }),
775
- auth === "oauth" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mcp-field", children: [
776
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "OAuth scopes (optional, comma-separated)" }),
790
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mcp-field", children: [
791
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "Args as a JSON array" }),
792
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
793
+ "textarea",
794
+ {
795
+ className: "mcp-textarea",
796
+ value: argsText,
797
+ disabled: busy,
798
+ placeholder: '["-y", "@modelcontextprotocol/server-github"]',
799
+ onChange: (event) => setArgsText(event.target.value),
800
+ spellCheck: false
801
+ }
802
+ )
803
+ ] })
804
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
805
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mcp-field", children: [
806
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "URL" }),
777
807
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
778
808
  "input",
779
809
  {
780
810
  className: "mcp-input",
781
- value: scopesText,
811
+ value: url,
782
812
  disabled: busy,
783
- placeholder: "read write",
784
- title: "Optional. Leave empty when the provider defines no scopes \u2014 for example Context7. Request only scopes the provider grants.",
785
- onChange: (event) => setScopesText(event.target.value)
813
+ onChange: (event) => setUrl(event.target.value),
814
+ placeholder: "https://example.com/mcp"
786
815
  }
787
- ),
788
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-muted", children: "Leave empty unless the provider requires scopes." })
789
- ] })
790
- ] }),
791
- auth === "oauth" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mcp-muted", children: "OAuth signs in through your browser. The Sign in button appears on the Server panel after you save." })
792
- ] }),
793
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mcp-actions", children: [
794
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "submit", className: "mcp-button mcp-button-primary", disabled: busy, children: busy ? "Adding\u2026" : "Add Server" }),
795
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "mcp-button", disabled: busy, onClick: onClose, children: "Cancel" })
796
- ] })
797
- ] }) });
798
- }
799
- function ImportDialog({ controller, busy, onClose }) {
800
- const [text, setText] = (0, import_react.useState)('{\n "mcpServers": {\n \n }\n}');
801
- const [error, setError] = (0, import_react.useState)();
802
- useEscapeClose(onClose);
803
- const submit = async (event) => {
804
- event.preventDefault();
805
- setError(void 0);
806
- try {
807
- parseMcpImport(text);
808
- } catch (nextError) {
809
- setError(nextError instanceof Error ? nextError.message : String(nextError));
810
- return;
811
- }
812
- const result = await controller.importJson(text);
813
- if (result) onClose();
814
- else setError("The Host rejected this import. Review the page error and retry.");
815
- };
816
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mcp-overlay", role: "presentation", onMouseDown: (event) => {
817
- if (event.target === event.currentTarget) onClose();
818
- }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { className: "mcp-modal-card", "aria-label": "Import MCP Servers", onSubmit: submit, children: [
819
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mcp-card-head", children: [
820
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
821
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "mcp-modal-title", children: "Import JSON" }),
822
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mcp-muted", children: "Paste a standard object with an mcpServers property." })
823
- ] }),
824
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "mcp-button", onClick: onClose, children: "Close" })
825
- ] }),
826
- error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mcp-error", role: "alert", children: error }),
827
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mcp-field", children: [
828
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "MCP Config JSON" }),
829
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
830
- "textarea",
831
- {
832
- autoFocus: true,
833
- className: "mcp-textarea",
834
- style: { minHeight: 280 },
835
- value: text,
836
- disabled: busy,
837
- spellCheck: false,
838
- onChange: (event) => setText(event.target.value)
839
- }
840
- )
816
+ )
817
+ ] }),
818
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mcp-field-row", children: [
819
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mcp-field", children: [
820
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "HTTP authentication" }),
821
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
822
+ "select",
823
+ {
824
+ className: "mcp-select",
825
+ value: auth,
826
+ disabled: busy,
827
+ title: "Static headers send fixed values on every request. OAuth 2.0 with PKCE signs in through the provider in your browser.",
828
+ onChange: (event) => setAuth(event.target.value),
829
+ children: [
830
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "headers", children: "Static headers" }),
831
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "oauth", children: "OAuth 2.0 with PKCE" })
832
+ ]
833
+ }
834
+ )
835
+ ] }),
836
+ auth === "oauth" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mcp-field", children: [
837
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-label", children: "OAuth scopes (optional, comma-separated)" }),
838
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
839
+ "input",
840
+ {
841
+ className: "mcp-input",
842
+ value: scopesText,
843
+ disabled: busy,
844
+ placeholder: "read write",
845
+ title: "Optional. Leave empty when the provider defines no scopes \u2014 for example Context7. Request only scopes the provider grants.",
846
+ onChange: (event) => setScopesText(event.target.value)
847
+ }
848
+ ),
849
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mcp-muted", children: "Leave empty unless the provider requires scopes." })
850
+ ] })
851
+ ] }),
852
+ auth === "oauth" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mcp-muted", children: "OAuth signs in through your browser. The Sign in button appears on the Server panel after you save." })
853
+ ] })
841
854
  ] }),
842
855
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mcp-actions", children: [
843
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "submit", className: "mcp-button mcp-button-primary", disabled: busy, children: busy ? "Importing\u2026" : "Import Servers" }),
856
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "submit", className: "mcp-button mcp-button-primary", disabled: busy, children: busy ? mode === "json" ? "Importing\u2026" : "Adding\u2026" : mode === "json" ? "Import Servers" : "Add Server" }),
844
857
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "mcp-button", disabled: busy, onClick: onClose, children: "Cancel" })
845
858
  ] })
846
859
  ] }) });
@@ -1303,56 +1316,32 @@ function McpSettingsPage({ controller }) {
1303
1316
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { className: "mcp-title", children: "MCP" }),
1304
1317
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mcp-intro", children: "Connect MCP Servers and choose how their tools reach the Agent." })
1305
1318
  ] }),
1306
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mcp-actions", children: [
1307
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1308
- "button",
1309
- {
1310
- type: "button",
1311
- className: "mcp-button",
1312
- disabled: snapshot.busy || !settings.writable,
1313
- onClick: () => setDialog("import"),
1314
- children: "Import JSON"
1315
- }
1316
- ),
1317
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1318
- "button",
1319
- {
1320
- type: "button",
1321
- className: "mcp-button mcp-button-primary",
1322
- disabled: snapshot.busy || !settings.writable,
1323
- onClick: () => setDialog("add"),
1324
- children: "Add Server"
1325
- }
1326
- )
1327
- ] })
1319
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mcp-actions", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1320
+ "button",
1321
+ {
1322
+ type: "button",
1323
+ className: "mcp-button mcp-button-primary",
1324
+ disabled: snapshot.busy || !settings.writable,
1325
+ onClick: () => setDialog("add"),
1326
+ children: "Add Server"
1327
+ }
1328
+ ) })
1328
1329
  ] }),
1329
1330
  !settings.writable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mcp-warning", children: "The active Settings Provider is read-only." }),
1330
1331
  snapshot.error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mcp-error", role: "alert", children: snapshot.error }),
1331
1332
  names.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mcp-empty", children: [
1332
1333
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "mcp-card-title", children: "No MCP Servers" }),
1333
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mcp-muted", children: "Add a Server or import an existing mcpServers Config." }),
1334
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mcp-actions", children: [
1335
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1336
- "button",
1337
- {
1338
- type: "button",
1339
- className: "mcp-button mcp-button-primary",
1340
- disabled: snapshot.busy || !settings.writable,
1341
- onClick: () => setDialog("add"),
1342
- children: "Add Server"
1343
- }
1344
- ),
1345
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1346
- "button",
1347
- {
1348
- type: "button",
1349
- className: "mcp-button",
1350
- disabled: snapshot.busy || !settings.writable,
1351
- onClick: () => setDialog("import"),
1352
- children: "Import JSON"
1353
- }
1354
- )
1355
- ] })
1334
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mcp-muted", children: "Add a Server through its input fields, or paste an existing mcpServers JSON." }),
1335
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mcp-actions", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1336
+ "button",
1337
+ {
1338
+ type: "button",
1339
+ className: "mcp-button mcp-button-primary",
1340
+ disabled: snapshot.busy || !settings.writable,
1341
+ onClick: () => setDialog("add"),
1342
+ children: "Add Server"
1343
+ }
1344
+ ) })
1356
1345
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mcp-layout", children: [
1357
1346
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("nav", { className: "mcp-sidebar", "aria-label": "MCP Servers", children: names.map((name) => {
1358
1347
  const status = statusFor(snapshot.overview, name);
@@ -1395,14 +1384,13 @@ function McpSettingsPage({ controller }) {
1395
1384
  selected
1396
1385
  )
1397
1386
  ] }),
1398
- dialog === "add" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AddServerDialog, { controller, busy: snapshot.busy, onClose: () => setDialog() }),
1399
- dialog === "import" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ImportDialog, { controller, busy: snapshot.busy, onClose: () => setDialog() })
1387
+ dialog === "add" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AddServerDialog, { controller, busy: snapshot.busy, onClose: () => setDialog() })
1400
1388
  ] });
1401
1389
  }
1402
1390
 
1403
1391
  // src/client/settings-api.js
1404
1392
  function createSettingsApi(ctx) {
1405
- const remoteSettings = ctx.remote?.settings;
1393
+ const remoteSettings = readRemoteSettings(ctx);
1406
1394
  if (remoteSettings !== void 0) return remoteSettingsApi(remoteSettings);
1407
1395
  const connectionSettings = ctx.connection?.api?.settings;
1408
1396
  if (connectionSettings !== void 0) return connectionSettings;
@@ -1410,6 +1398,20 @@ function createSettingsApi(ctx) {
1410
1398
  "No DSH settings write API: expected ctx.remote.settings (DSH 0.1.2+) or ctx.connection.api.settings (DSH 0.1.1-rc.2). Upgrade @auggieteo/dsh-mcp-adapter to a release supporting this harness."
1411
1399
  );
1412
1400
  }
1401
+ function readRemoteSettings(ctx) {
1402
+ if (typeof ctx.get === "function") {
1403
+ try {
1404
+ const mounted = ctx.get("remote.settings");
1405
+ if (mounted !== void 0) return mounted;
1406
+ } catch {
1407
+ }
1408
+ }
1409
+ try {
1410
+ return ctx.remote?.settings;
1411
+ } catch {
1412
+ }
1413
+ return void 0;
1414
+ }
1413
1415
  function remoteSettingsApi(remote) {
1414
1416
  return {
1415
1417
  async update({ ns, patch, expectedRevision }) {
@@ -1493,11 +1495,17 @@ var MCP_SETTINGS_CSS = `
1493
1495
  .mcp-promotion-name{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:var(--dsw-alias-label-primary);overflow-wrap:anywhere}
1494
1496
  .mcp-promotion-description{display:block;color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:17px}
1495
1497
  .mcp-empty{padding:30px 20px;text-align:center;display:flex;align-items:center;flex-direction:column;gap:10px}
1496
- .mcp-overlay{position:fixed;inset:0;background:var(--dsw-alias-bg-mask-1);display:flex;align-items:center;justify-content:center;padding:20px;z-index:1200;animation:mcp-fade .12s ease}
1497
- .mcp-modal-card{width:min(560px,100%);max-height:min(760px,90vh);overflow:auto;padding:18px;display:flex;flex-direction:column;gap:13px;border:1px solid var(--dsw-alias-border-l1);border-radius:14px;background:var(--dsw-alias-bg-overlay);box-shadow:0 18px 60px rgba(0,0,0,.32);animation:mcp-pop .16s ease}
1498
+ .mcp-overlay{position:fixed;inset:0;background:var(--dsw-alias-bg-mask-1);backdrop-filter:var(--dsw-mask-blur);display:flex;align-items:center;justify-content:center;padding:20px;z-index:1200;animation:mcp-fade .12s ease}
1499
+ .mcp-modal-card{width:min(560px,100%);max-height:min(760px,90vh);overflow:auto;padding:18px;display:flex;flex-direction:column;gap:13px;border:0;border-radius:14px;background:var(--dsw-alias-bg-layer-2);box-shadow:var(--dsw-elevation-prominent);animation:mcp-pop .16s ease}
1498
1500
  @keyframes mcp-fade{from{opacity:0}to{opacity:1}}
1499
1501
  @keyframes mcp-pop{from{opacity:0;transform:translateY(6px) scale(.98)}to{opacity:1;transform:none}}
1500
1502
  .mcp-modal-title{margin:0;font-size:15px;line-height:22px;font-weight:600}
1503
+ .mcp-dialog-tabs{display:inline-flex;gap:2px;align-self:flex-start;border:1px solid var(--dsw-alias-border-l2);border-radius:16px;padding:2px;background:var(--dsw-alias-bg-layer-3)}
1504
+ .mcp-dialog-tab{height:26px;border:0;border-radius:14px;background:transparent;color:var(--dsw-alias-label-secondary);padding:0 12px;font:inherit;font-size:12px;cursor:pointer;transition:background .12s ease,color .12s ease}
1505
+ .mcp-dialog-tab:hover:not(:disabled):not(.mcp-dialog-tab-active){color:var(--dsw-alias-label-primary)}
1506
+ .mcp-dialog-tab:disabled{cursor:not-allowed;opacity:.5}
1507
+ .mcp-dialog-tab-active{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}
1508
+ .mcp-dialog-tab:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}
1501
1509
  .mcp-confirm{border-radius:8px;padding:10px;display:flex;flex-direction:column;gap:8px;background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent)}
1502
1510
  @container (max-width:660px){.mcp-layout{grid-template-columns:minmax(0,1fr)}.mcp-sidebar{position:static;flex-direction:row;overflow-x:auto;padding-bottom:2px}.mcp-server-button{width:auto;flex:none;white-space:nowrap}}
1503
1511
  @container (max-width:480px){.mcp-field-row{grid-template-columns:minmax(0,1fr)}.mcp-secret-row{grid-template-columns:minmax(0,1fr) auto}.mcp-secret-row .mcp-input:first-child{grid-column:1 / -1}.mcp-card-head .mcp-actions{margin-left:0;width:100%}.mcp-toolbar{align-items:flex-start}}
package/lib/client.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/client/index.jsx", "../src/client/McpSettingsPage.jsx", "../src/client/settings-controller.js", "../src/client/settings-api.js", "../src/client/styles.js"],
4
- "sourcesContent": ["import { McpSettingsPage } from './McpSettingsPage.jsx'\nimport {\n MCP_RPC_CHANNEL,\n MCP_SETTINGS_NAMESPACE,\n McpSettingsController,\n} from './settings-controller.js'\nimport { createSettingsApi } from './settings-api.js'\nimport { installMcpSettingsStyles } from './styles.js'\n\n// `remote` rides the 0.1.2-rc.1+ settings write surface (see settings-api.js);\n// it exists on every harness generation, while `connection.api` only on\n// 0.1.1-rc.2, so both stay declared and the resolution happens at apply time.\nexport const inject = ['slots', 'settingsScope', 'connection', 'remote']\n\nexport function apply(ctx) {\n const scope = ctx.settingsScope.bind({ namespace: MCP_SETTINGS_NAMESPACE })\n const describe = ctx.settingsScope.describe()\n const controller = new McpSettingsController({\n scope,\n describe,\n settingsApi: createSettingsApi(ctx),\n rpc: (endpoint, payload, signal) =>\n ctx.connection.rpc.call(MCP_RPC_CHANNEL, endpoint, payload, signal),\n })\n\n ctx.effect(() => installMcpSettingsStyles(), 'mcp-adapter: Settings styles')\n ctx.effect(() => () => controller.dispose(), 'mcp-adapter: Settings controller')\n ctx.slots.inject('settings.section', () =>\n ctx.slots.register(\n {\n name: 'settings.section',\n id: 'mcp',\n order: 30,\n label: 'MCP',\n inject: () => ({ controller }),\n },\n McpSettingsPage,\n ),\n )\n}\n", "import React, { useEffect, useMemo, useState, useSyncExternalStore } from 'react'\n\nimport {\n normalizeServerConfig,\n parseArgs,\n parseMcpImport,\n parseScopes,\n secretKeysFromView,\n secretRowOps,\n serverSource,\n} from './settings-controller.js'\n\nfunction statusFor(overview, name) {\n return overview.status.servers.find((entry) => entry.name === name) ?? {\n name,\n state: 'disconnected',\n toolCount: 0,\n }\n}\n\nfunction catalogFor(overview, name) {\n return overview.catalog.servers.find((entry) => entry.name === name)?.tools ?? []\n}\n\nfunction statusClass(state) {\n if (state === 'connected') return 'mcp-status-connected'\n if (state === 'connecting') return 'mcp-status-connecting'\n if (state === 'error') return 'mcp-status-error'\n if (state === 'disabled') return 'mcp-status-disabled'\n return ''\n}\n\nfunction secretRows(keys) {\n return keys.map((key) => ({ originalKey: key, key, value: '' }))\n}\n\nfunction SecretEditor({ field, rows, onChange, disabled }) {\n const label = field === 'env' ? 'Environment variables' : 'HTTP headers'\n const add = () => onChange([...rows, { key: '', value: '' }])\n const update = (index, patch) => {\n onChange(rows.map((row, position) => position === index ? { ...row, ...patch } : row))\n }\n const remove = (index) => onChange(rows.filter((_, position) => position !== index))\n\n return (\n <div className=\"mcp-section\">\n <div>\n <h4 className=\"mcp-section-title\">{label}</h4>\n <p className=\"mcp-muted\">\n Existing secret values stay saved when their value field remains blank.\n </p>\n </div>\n {rows.map((row, index) => (\n <div className=\"mcp-secret-row\" key={`${row.originalKey ?? 'new'}-${index}`}>\n <input\n className=\"mcp-input\"\n aria-label={`${label} key ${index + 1}`}\n placeholder={field === 'env' ? 'API_TOKEN' : 'Authorization'}\n value={row.key}\n disabled={disabled}\n onChange={(event) => update(index, { key: event.target.value })}\n />\n <input\n className=\"mcp-input\"\n aria-label={`${label} value ${index + 1}`}\n type={field === 'env' ? 'password' : 'text'}\n autoComplete=\"off\"\n placeholder={row.originalKey === undefined ? 'Value' : 'Saved value'}\n value={row.value}\n disabled={disabled}\n onChange={(event) => update(index, { value: event.target.value })}\n />\n <button\n type=\"button\"\n className=\"mcp-button mcp-button-danger\"\n disabled={disabled}\n onClick={() => remove(index)}\n >\n Remove\n </button>\n </div>\n ))}\n <div>\n <button type=\"button\" className=\"mcp-button\" disabled={disabled} onClick={add}>\n Add {field === 'env' ? 'variable' : 'header'}\n </button>\n </div>\n </div>\n )\n}\n\nfunction useEscapeClose(onClose) {\n useEffect(() => {\n const onKey = (event) => {\n if (event.key === 'Escape') onClose()\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [onClose])\n}\n\nfunction AddServerDialog({ controller, busy, onClose }) {\n const [name, setName] = useState('')\n const [transport, setTransport] = useState('stdio')\n const [command, setCommand] = useState('')\n const [url, setUrl] = useState('')\n const [argsText, setArgsText] = useState('[]')\n const [auth, setAuth] = useState('headers')\n const [scopesText, setScopesText] = useState('')\n const [error, setError] = useState()\n useEscapeClose(onClose)\n const submit = async (event) => {\n event.preventDefault()\n setError(undefined)\n let config\n try {\n config = normalizeServerConfig(\n name,\n transport === 'stdio'\n ? { command, args: parseArgs(argsText) }\n : { url, auth, scopes: auth === 'oauth' ? parseScopes(scopesText) : [] },\n )\n } catch (nextError) {\n setError(nextError instanceof Error ? nextError.message : String(nextError))\n return\n }\n if (await controller.addServer(name, config)) onClose()\n }\n\n return (\n <div className=\"mcp-overlay\" role=\"presentation\" onMouseDown={(event) => {\n if (event.target === event.currentTarget) onClose()\n }}>\n <form className=\"mcp-modal-card\" aria-label=\"Add MCP Server\" onSubmit={submit}>\n <div className=\"mcp-card-head\">\n <div>\n <h3 className=\"mcp-modal-title\">Add Server</h3>\n <p className=\"mcp-muted\">Configure one stdio command or one HTTP URL.</p>\n </div>\n <button type=\"button\" className=\"mcp-button\" onClick={onClose}>Close</button>\n </div>\n {error !== undefined && <div className=\"mcp-error\" role=\"alert\">{error}</div>}\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Name</span>\n <input\n autoFocus\n className=\"mcp-input\"\n value={name}\n disabled={busy}\n onChange={(event) => setName(event.target.value)}\n placeholder=\"github\"\n />\n </label>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Transport</span>\n <select\n className=\"mcp-select\"\n value={transport}\n disabled={busy}\n onChange={(event) => setTransport(event.target.value)}\n >\n <option value=\"stdio\">stdio</option>\n <option value=\"http\">Streamable HTTP</option>\n </select>\n </label>\n {transport === 'stdio' ? (\n <>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Command</span>\n <input\n className=\"mcp-input\"\n value={command}\n disabled={busy}\n onChange={(event) => setCommand(event.target.value)}\n placeholder=\"npx\"\n />\n </label>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Args as a JSON array</span>\n <textarea\n className=\"mcp-textarea\"\n value={argsText}\n disabled={busy}\n placeholder={'[\"-y\", \"@modelcontextprotocol/server-github\"]'}\n onChange={(event) => setArgsText(event.target.value)}\n spellCheck={false}\n />\n </label>\n </>\n ) : (\n <>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">URL</span>\n <input\n className=\"mcp-input\"\n value={url}\n disabled={busy}\n onChange={(event) => setUrl(event.target.value)}\n placeholder=\"https://example.com/mcp\"\n />\n </label>\n <div className=\"mcp-field-row\">\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">HTTP authentication</span>\n <select\n className=\"mcp-select\"\n value={auth}\n disabled={busy}\n title=\"Static headers send fixed values on every request. OAuth 2.0 with PKCE signs in through the provider in your browser.\"\n onChange={(event) => setAuth(event.target.value)}\n >\n <option value=\"headers\">Static headers</option>\n <option value=\"oauth\">OAuth 2.0 with PKCE</option>\n </select>\n </label>\n {auth === 'oauth' && (\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">OAuth scopes (optional, comma-separated)</span>\n <input\n className=\"mcp-input\"\n value={scopesText}\n disabled={busy}\n placeholder=\"read write\"\n title=\"Optional. Leave empty when the provider defines no scopes \u2014 for example Context7. Request only scopes the provider grants.\"\n onChange={(event) => setScopesText(event.target.value)}\n />\n <span className=\"mcp-muted\">Leave empty unless the provider requires scopes.</span>\n </label>\n )}\n </div>\n {auth === 'oauth' && (\n <p className=\"mcp-muted\">\n OAuth signs in through your browser. The Sign in button appears\n on the Server panel after you save.\n </p>\n )}\n </>\n )}\n <div className=\"mcp-actions\">\n <button type=\"submit\" className=\"mcp-button mcp-button-primary\" disabled={busy}>\n {busy ? 'Adding\u2026' : 'Add Server'}\n </button>\n <button type=\"button\" className=\"mcp-button\" disabled={busy} onClick={onClose}>\n Cancel\n </button>\n </div>\n </form>\n </div>\n )\n}\n\nfunction ImportDialog({ controller, busy, onClose }) {\n const [text, setText] = useState('{\\n \"mcpServers\": {\\n \\n }\\n}')\n const [error, setError] = useState()\n useEscapeClose(onClose)\n const submit = async (event) => {\n event.preventDefault()\n setError(undefined)\n try {\n parseMcpImport(text)\n } catch (nextError) {\n setError(nextError instanceof Error ? nextError.message : String(nextError))\n return\n }\n const result = await controller.importJson(text)\n if (result) onClose()\n else setError('The Host rejected this import. Review the page error and retry.')\n }\n\n return (\n <div className=\"mcp-overlay\" role=\"presentation\" onMouseDown={(event) => {\n if (event.target === event.currentTarget) onClose()\n }}>\n <form className=\"mcp-modal-card\" aria-label=\"Import MCP Servers\" onSubmit={submit}>\n <div className=\"mcp-card-head\">\n <div>\n <h3 className=\"mcp-modal-title\">Import JSON</h3>\n <p className=\"mcp-muted\">Paste a standard object with an mcpServers property.</p>\n </div>\n <button type=\"button\" className=\"mcp-button\" onClick={onClose}>Close</button>\n </div>\n {error !== undefined && <div className=\"mcp-error\" role=\"alert\">{error}</div>}\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">MCP Config JSON</span>\n <textarea\n autoFocus\n className=\"mcp-textarea\"\n style={{ minHeight: 280 }}\n value={text}\n disabled={busy}\n spellCheck={false}\n onChange={(event) => setText(event.target.value)}\n />\n </label>\n <div className=\"mcp-actions\">\n <button type=\"submit\" className=\"mcp-button mcp-button-primary\" disabled={busy}>\n {busy ? 'Importing\u2026' : 'Import Servers'}\n </button>\n <button type=\"button\" className=\"mcp-button\" disabled={busy} onClick={onClose}>\n Cancel\n </button>\n </div>\n </form>\n </div>\n )\n}\n\n/**\n * OAuth sign-in/sign-out section, shared by the editable detail and the\n * read-only workspace detail. Sign-in works for workspace-defined Servers\n * too: the Adapter resolves the Server through the merged Config.\n */\nfunction OAuthSection({ controller, snapshot, name }) {\n const oauthStatus = snapshot.oauthStatuses?.[name]\n const oauthSignedIn =\n oauthStatus !== undefined &&\n oauthStatus.signedIn === true &&\n (oauthStatus.expiresAt === undefined || oauthStatus.expiresAt > Date.now())\n const oauthState = oauthStatus?.configured\n ? oauthSignedIn\n ? 'Signed in'\n : oauthStatus.expiresAt !== undefined\n ? 'Signed out (token expired)'\n : 'Signed out'\n : 'Signed out'\n const signIn = async () => {\n const result = await controller.signIn(name)\n if (result?.authorizationUrl) window.open(result.authorizationUrl, '_blank')\n }\n\n return (\n <div className=\"mcp-section\">\n <div>\n <h3 className=\"mcp-section-title\">OAuth</h3>\n <p className=\"mcp-muted\">\n OAuth 2.0 with PKCE. {oauthState}. Sign-in opens the authorization\n page in your browser; the Adapter completes the flow in the\n background and reconnects with the fresh tokens. If no tab opens,\n allow pop-ups for this page or run /mcp-auth.\n </p>\n {oauthStatus !== undefined && oauthStatus.configured === true && !oauthSignedIn && (\n <div className=\"mcp-warning\">This Server cannot connect until you sign in.</div>\n )}\n </div>\n <div className=\"mcp-actions\">\n <button\n type=\"button\"\n className=\"mcp-button mcp-button-primary\"\n disabled={snapshot.busy}\n title=\"Opens the provider's authorization page in a new browser tab. The Adapter finishes the flow in the background and reconnects.\"\n onClick={() => void signIn()}\n >\n Sign in\n </button>\n <button\n type=\"button\"\n className=\"mcp-button\"\n disabled={snapshot.busy}\n title=\"Deletes the stored tokens and disconnects this Server.\"\n onClick={() => void controller.signOut(name)}\n >\n Sign out\n </button>\n </div>\n </div>\n )\n}\n\n/**\n * Read-only detail for a Server defined only in the workspace `.dsh/mcp.json`.\n * Edits write the global Config layer, which the workspace file overrides, so\n * the panel shows the sanitized workspace Config and, for OAuth Servers, the\n * sign-in actions.\n */\nfunction WorkspaceServerDetail({ controller, snapshot, name, server }) {\n const status = statusFor(snapshot.overview, name)\n return (\n <div className=\"mcp-card\">\n <div className=\"mcp-card-head\">\n <div>\n <div className=\"mcp-row\">\n <span className={`mcp-status-dot ${statusClass(status.state)}`} />\n <h2 className=\"mcp-card-title\">{name}</h2>\n <span className={`mcp-badge ${statusClass(status.state)}`}>{status.state}</span>\n <span className=\"mcp-badge mcp-badge-workspace\">workspace</span>\n </div>\n <p className=\"mcp-muted\">\n {status.toolCount} {status.toolCount === 1 ? 'tool' : 'tools'} cached\n {status.transport === undefined ? '' : ` \u00B7 ${status.transport}`}\n </p>\n </div>\n </div>\n <div className=\"mcp-layer-notice\">\n Read-only: defined by the workspace .dsh/mcp.json file. Edit that file\n to change this Server.\n </div>\n <div className=\"mcp-section\">\n <h3 className=\"mcp-section-title\">Config</h3>\n <p className=\"mcp-muted\">\n {typeof server.command === 'string'\n ? `stdio: ${server.command}${(server.args ?? []).length > 0 ? ` ${server.args.join(' ')}` : ''}`\n : `HTTP: ${server.url}`}{' '}\n \u00B7 lifecycle {server.lifecycle ?? 'lazy'} \u00B7 {server.autoAllow ? 'auto-allow' : 'asks per call'}\n </p>\n </div>\n {typeof server.url === 'string' && server.auth === 'oauth' && (\n <OAuthSection controller={controller} snapshot={snapshot} name={name} />\n )}\n <div className=\"mcp-section\">\n <h3 className=\"mcp-section-title\">Promotions</h3>\n <p className=\"mcp-muted\">\n Promotions for a workspace Server are managed in the workspace file\n through its promotedTools list.\n </p>\n </div>\n </div>\n )\n}\n\nfunction ServerDetail({ controller, snapshot, name, server }) {\n const status = statusFor(snapshot.overview, name)\n const tools = catalogFor(snapshot.overview, name)\n const workspaceSourced = serverSource(snapshot.layers, name) === 'workspace'\n const transport = typeof server.command === 'string' ? 'stdio' : 'http'\n const [draft, setDraft] = useState(() => ({\n transport,\n command: server.command ?? '',\n url: server.url ?? '',\n argsText: JSON.stringify(server.args ?? [], null, 2),\n auth: server.auth ?? 'headers',\n scopesText: (server.scopes ?? []).join(', '),\n disabled: server.disabled === true,\n autoAllow: server.autoAllow === true,\n idleTimeoutMinutes: String(server.idleTimeoutMinutes ?? 10),\n }))\n const [rowSets, setRowSets] = useState(() => ({\n env: secretRows(secretKeysFromView(snapshot.settingsDocument.view, name, 'env')),\n headers: secretRows(secretKeysFromView(snapshot.settingsDocument.view, name, 'headers')),\n }))\n const activeSecretField = draft.transport === 'stdio' ? 'env' : 'headers'\n const rows = rowSets[activeSecretField]\n const [dirty, setDirty] = useState(false)\n const [formError, setFormError] = useState()\n const [confirmDelete, setConfirmDelete] = useState(false)\n\n useEffect(() => {\n if (dirty) return\n const nextTransport = typeof server.command === 'string' ? 'stdio' : 'http'\n setDraft({\n transport: nextTransport,\n command: server.command ?? '',\n url: server.url ?? '',\n argsText: JSON.stringify(server.args ?? [], null, 2),\n auth: server.auth ?? 'headers',\n scopesText: (server.scopes ?? []).join(', '),\n disabled: server.disabled === true,\n autoAllow: server.autoAllow === true,\n idleTimeoutMinutes: String(server.idleTimeoutMinutes ?? 10),\n })\n setRowSets({\n env: secretRows(secretKeysFromView(snapshot.settingsDocument.view, name, 'env')),\n headers: secretRows(secretKeysFromView(snapshot.settingsDocument.view, name, 'headers')),\n })\n }, [dirty, name, server, snapshot.settingsDocument.view])\n\n const changeDraft = (patch) => {\n setDirty(true)\n setDraft((current) => ({ ...current, ...patch }))\n }\n const changeRows = (next) => {\n setDirty(true)\n setRowSets((current) => ({ ...current, [activeSecretField]: next }))\n }\n const save = async (event) => {\n event.preventDefault()\n setFormError(undefined)\n try {\n const nextTransport = draft.transport\n normalizeServerConfig(name, {\n ...(nextTransport === 'stdio'\n ? { command: draft.command, args: parseArgs(draft.argsText) }\n : { url: draft.url }),\n auth: nextTransport === 'http' ? draft.auth : 'headers',\n scopes: nextTransport === 'http' ? parseScopes(draft.scopesText) : [],\n disabled: draft.disabled,\n autoAllow: draft.autoAllow,\n idleTimeoutMinutes: Number(draft.idleTimeoutMinutes),\n promotedTools: server.promotedTools,\n })\n const field = nextTransport === 'stdio' ? 'env' : 'headers'\n secretRowOps(\n name,\n field,\n rows,\n secretKeysFromView(snapshot.settingsDocument.view, name, field),\n )\n } catch (nextError) {\n setFormError(nextError instanceof Error ? nextError.message : String(nextError))\n return\n }\n if (await controller.saveServer(name, draft, rows)) {\n setRowSets((current) => ({\n ...current,\n [activeSecretField]: rows.map((row) => ({\n originalKey: row.key.trim(),\n key: row.key.trim(),\n value: '',\n })),\n }))\n setDirty(false)\n }\n }\n const remove = async () => {\n if (await controller.deleteServer(name)) setConfirmDelete(false)\n }\n\n return (\n <div className=\"mcp-card\">\n <div className=\"mcp-card-head\">\n <div>\n <div className=\"mcp-row\">\n <span className={`mcp-status-dot ${statusClass(status.state)}`} />\n <h2 className=\"mcp-card-title\">{name}</h2>\n <span className={`mcp-badge ${statusClass(status.state)}`}>{status.state}</span>\n {workspaceSourced && (\n <span className=\"mcp-badge mcp-badge-workspace\">workspace</span>\n )}\n </div>\n <p className=\"mcp-muted\">\n {status.toolCount} {status.toolCount === 1 ? 'tool' : 'tools'} cached\n {status.transport === undefined ? '' : ` \u00B7 ${status.transport}`}\n </p>\n </div>\n <div className=\"mcp-actions\">\n <button\n type=\"button\"\n className=\"mcp-button\"\n disabled={snapshot.busy || draft.disabled}\n onClick={() => void controller.reconnect(name)}\n >\n Reconnect\n </button>\n <button\n type=\"button\"\n className=\"mcp-button mcp-button-danger\"\n disabled={snapshot.busy}\n onClick={() => setConfirmDelete(true)}\n >\n Delete\n </button>\n </div>\n </div>\n\n {workspaceSourced && (\n <div className=\"mcp-layer-notice\" role=\"note\">\n This Server is defined or overridden by the workspace .dsh/mcp.json.\n Edits here write the global layer, which the workspace file overrides.\n </div>\n )}\n {status.message !== undefined && status.state === 'error' && (\n <div className=\"mcp-error\" role=\"alert\">{status.message}</div>\n )}\n {confirmDelete && (\n <div className=\"mcp-confirm\">\n <strong>Delete {name}?</strong>\n <span className=\"mcp-muted\">This removes its Config and disconnects the Server.</span>\n <div className=\"mcp-actions\">\n <button\n type=\"button\"\n className=\"mcp-button mcp-button-danger\"\n disabled={snapshot.busy}\n onClick={() => void remove()}\n >\n Confirm delete\n </button>\n <button type=\"button\" className=\"mcp-button\" onClick={() => setConfirmDelete(false)}>\n Cancel\n </button>\n </div>\n </div>\n )}\n\n <form className=\"mcp-form\" onSubmit={save}>\n {formError !== undefined && <div className=\"mcp-error\" role=\"alert\">{formError}</div>}\n <div className=\"mcp-field-row\">\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Name</span>\n <input className=\"mcp-input\" value={name} readOnly />\n </label>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Transport</span>\n <select\n className=\"mcp-select\"\n value={draft.transport}\n disabled={snapshot.busy}\n onChange={(event) => changeDraft({ transport: event.target.value })}\n >\n <option value=\"stdio\">stdio</option>\n <option value=\"http\">Streamable HTTP</option>\n </select>\n </label>\n </div>\n\n {draft.transport === 'stdio' ? (\n <>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Command</span>\n <input\n className=\"mcp-input\"\n value={draft.command}\n disabled={snapshot.busy}\n onChange={(event) => changeDraft({ command: event.target.value })}\n />\n </label>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Args as a JSON array</span>\n <textarea\n className=\"mcp-textarea\"\n value={draft.argsText}\n disabled={snapshot.busy}\n spellCheck={false}\n onChange={(event) => changeDraft({ argsText: event.target.value })}\n />\n </label>\n <SecretEditor field=\"env\" rows={rows} onChange={changeRows} disabled={snapshot.busy} />\n </>\n ) : (\n <>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">URL</span>\n <input\n className=\"mcp-input\"\n value={draft.url}\n disabled={snapshot.busy}\n onChange={(event) => changeDraft({ url: event.target.value })}\n />\n </label>\n <div className=\"mcp-field-row\">\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">HTTP authentication</span>\n <select\n className=\"mcp-select\"\n value={draft.auth ?? 'headers'}\n disabled={snapshot.busy}\n title=\"Static headers send fixed values on every request. OAuth 2.0 with PKCE signs in through the provider in your browser.\"\n onChange={(event) => changeDraft({ auth: event.target.value })}\n >\n <option value=\"headers\">Static headers</option>\n <option value=\"oauth\">OAuth 2.0 with PKCE</option>\n </select>\n </label>\n {draft.auth === 'oauth' && (\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">OAuth scopes (optional, comma-separated)</span>\n <input\n className=\"mcp-input\"\n value={draft.scopesText}\n disabled={snapshot.busy}\n placeholder=\"read write\"\n title=\"Optional. Leave empty when the provider defines no scopes \u2014 for example Context7. Request only scopes the provider grants.\"\n onChange={(event) => changeDraft({ scopesText: event.target.value })}\n />\n <span className=\"mcp-muted\">Leave empty unless the provider requires scopes.</span>\n </label>\n )}\n </div>\n {draft.auth === 'oauth' && (\n <p className=\"mcp-muted\">\n OAuth signs in through your browser. The Sign in button appears\n after you save this Server.\n </p>\n )}\n <SecretEditor field=\"headers\" rows={rows} onChange={changeRows} disabled={snapshot.busy} />\n </>\n )}\n\n <div className=\"mcp-field-row\">\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Idle timeout in minutes</span>\n <input\n className=\"mcp-input\"\n type=\"number\"\n min=\"0.1\"\n step=\"0.1\"\n value={draft.idleTimeoutMinutes}\n disabled={snapshot.busy}\n onChange={(event) => changeDraft({ idleTimeoutMinutes: event.target.value })}\n />\n </label>\n <div className=\"mcp-field\">\n <span className=\"mcp-label\">Call policy</span>\n <label className=\"mcp-checkbox\">\n <input\n type=\"checkbox\"\n checked={draft.autoAllow}\n disabled={snapshot.busy}\n onChange={(event) => changeDraft({ autoAllow: event.target.checked })}\n />\n Auto-allow calls from this Server\n </label>\n </div>\n </div>\n <label className=\"mcp-checkbox\">\n <input\n type=\"checkbox\"\n checked={draft.disabled}\n disabled={snapshot.busy}\n onChange={(event) => changeDraft({ disabled: event.target.checked })}\n />\n Disable this Server\n </label>\n <div className=\"mcp-actions\">\n <button\n type=\"submit\"\n className=\"mcp-button mcp-button-primary\"\n disabled={workspaceSourced || snapshot.busy || !dirty}\n >\n {snapshot.busy ? 'Saving\u2026' : 'Save Server'}\n </button>\n {dirty && !workspaceSourced && <span className=\"mcp-muted\">Unsaved changes</span>}\n {workspaceSourced && <span className=\"mcp-muted\">Read-only: defined by the workspace</span>}\n </div>\n </form>\n\n {typeof server.url === 'string' && server.auth === 'oauth' && (\n <OAuthSection controller={controller} snapshot={snapshot} name={name} />\n )}\n\n <div className=\"mcp-section\">\n <div>\n <h3 className=\"mcp-section-title\">Promotions</h3>\n <p className=\"mcp-muted\">\n Promote selected MCP tools as native tools named {name}__tool.\n </p>\n </div>\n {tools.length === 0 ? (\n <div className=\"mcp-warning\">\n No cached tools are available. Reconnect to discover this Server.\n </div>\n ) : (\n <div className=\"mcp-promotion-list\">\n {tools.map((tool) => {\n const checked = (server.promotedTools ?? []).includes(tool.name)\n return (\n <label className=\"mcp-promotion\" key={tool.name}>\n <input\n type=\"checkbox\"\n checked={checked}\n disabled={snapshot.busy}\n onChange={() => void controller.togglePromotion(name, tool.name)}\n />\n <span>\n <span className=\"mcp-promotion-name\">{tool.name}</span>\n {tool.description !== undefined && (\n <span className=\"mcp-promotion-description\">{tool.description}</span>\n )}\n </span>\n </label>\n )\n })}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport function McpSettingsPage({ controller }) {\n const snapshot = useSyncExternalStore(controller.subscribe, controller.getSnapshot)\n const [selected, setSelected] = useState()\n const [dialog, setDialog] = useState()\n const settings = snapshot.settings\n const servers = settings.value?.mcpServers ?? {}\n // Workspace-only Servers (absent from the global namespace) still surface:\n // the sidebar unions both sources and the detail renders read-only.\n const workspaceServers = snapshot.layers?.servers ?? {}\n const names = useMemo(\n () => [...new Set([...Object.keys(servers), ...Object.keys(workspaceServers)])].sort(),\n [servers, workspaceServers],\n )\n\n useEffect(() => controller.mount(), [controller])\n useEffect(() => {\n if (\n selected === undefined ||\n (!Object.hasOwn(servers, selected) && !Object.hasOwn(workspaceServers, selected))\n ) {\n setSelected(names[0])\n }\n }, [names, selected, servers, workspaceServers])\n\n if (settings.status === 'loading') {\n return <section className=\"mcp-settings\"><p className=\"mcp-muted\">Loading MCP Settings\u2026</p></section>\n }\n if (settings.status !== 'ready') {\n return (\n <section className=\"mcp-settings\">\n <h1 className=\"mcp-title\">MCP</h1>\n <div className=\"mcp-error\" role=\"alert\">\n {settings.error?.message ?? 'MCP Settings are unavailable.'}\n </div>\n </section>\n )\n }\n\n return (\n <section className=\"mcp-settings\">\n <div className=\"mcp-toolbar\">\n <div>\n <h1 className=\"mcp-title\">MCP</h1>\n <p className=\"mcp-intro\">Connect MCP Servers and choose how their tools reach the Agent.</p>\n </div>\n <div className=\"mcp-actions\">\n <button\n type=\"button\"\n className=\"mcp-button\"\n disabled={snapshot.busy || !settings.writable}\n onClick={() => setDialog('import')}\n >\n Import JSON\n </button>\n <button\n type=\"button\"\n className=\"mcp-button mcp-button-primary\"\n disabled={snapshot.busy || !settings.writable}\n onClick={() => setDialog('add')}\n >\n Add Server\n </button>\n </div>\n </div>\n\n {!settings.writable && (\n <div className=\"mcp-warning\">The active Settings Provider is read-only.</div>\n )}\n {snapshot.error !== undefined && (\n <div className=\"mcp-error\" role=\"alert\">{snapshot.error}</div>\n )}\n\n {names.length === 0 ? (\n <div className=\"mcp-empty\">\n <h2 className=\"mcp-card-title\">No MCP Servers</h2>\n <p className=\"mcp-muted\">Add a Server or import an existing mcpServers Config.</p>\n <div className=\"mcp-actions\">\n <button\n type=\"button\"\n className=\"mcp-button mcp-button-primary\"\n disabled={snapshot.busy || !settings.writable}\n onClick={() => setDialog('add')}\n >\n Add Server\n </button>\n <button\n type=\"button\"\n className=\"mcp-button\"\n disabled={snapshot.busy || !settings.writable}\n onClick={() => setDialog('import')}\n >\n Import JSON\n </button>\n </div>\n </div>\n ) : (\n <div className=\"mcp-layout\">\n <nav className=\"mcp-sidebar\" aria-label=\"MCP Servers\">\n {names.map((name) => {\n const status = statusFor(snapshot.overview, name)\n const workspaceSourced = serverSource(snapshot.layers, name) === 'workspace'\n return (\n <button\n type=\"button\"\n className=\"mcp-server-button\"\n aria-current={name === selected}\n key={name}\n onClick={() => setSelected(name)}\n >\n <span className={`mcp-status-dot ${statusClass(status.state)}`} />\n <span className=\"mcp-server-name\">{name}</span>\n {workspaceSourced && (\n <span className=\"mcp-badge mcp-badge-workspace\">workspace</span>\n )}\n <span className=\"mcp-server-count\">{status.toolCount}</span>\n </button>\n )\n })}\n </nav>\n {selected !== undefined && servers[selected] !== undefined && (\n <ServerDetail\n key={selected}\n controller={controller}\n snapshot={snapshot}\n name={selected}\n server={servers[selected]}\n />\n )}\n {selected !== undefined && servers[selected] === undefined && workspaceServers[selected] !== undefined && (\n <WorkspaceServerDetail\n key={selected}\n controller={controller}\n snapshot={snapshot}\n name={selected}\n server={workspaceServers[selected]}\n />\n )}\n </div>\n )}\n\n {dialog === 'add' && (\n <AddServerDialog controller={controller} busy={snapshot.busy} onClose={() => setDialog()} />\n )}\n {dialog === 'import' && (\n <ImportDialog controller={controller} busy={snapshot.busy} onClose={() => setDialog()} />\n )}\n </section>\n )\n}\n", "export const MCP_SETTINGS_NAMESPACE = 'mcp'\nexport const MCP_RPC_CHANNEL = '/mcp-adapter'\n\nconst SERVER_FIELDS = new Set([\n 'command',\n 'args',\n 'env',\n 'url',\n 'headers',\n 'auth',\n 'scopes',\n 'disabled',\n 'autoAllow',\n 'lifecycle',\n 'idleTimeoutMinutes',\n 'promotedTools',\n])\n\nfunction isRecord(value) {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction messageOf(error) {\n return error instanceof Error ? error.message : String(error)\n}\n\nfunction requireStringRecord(value, label) {\n if (value === undefined) return {}\n if (!isRecord(value)) throw new Error(`${label} must be an object of string values`)\n for (const [key, entry] of Object.entries(value)) {\n if (key.trim() === '' || typeof entry !== 'string') {\n throw new Error(`${label} must contain non-empty keys and string values`)\n }\n }\n return value\n}\n\nexport function normalizeServerConfig(name, input) {\n if (typeof name !== 'string' || name.trim() === '') {\n throw new Error('Server name cannot be empty')\n }\n if (!isRecord(input)) throw new Error(`Server ${JSON.stringify(name)} must be an object`)\n for (const key of Object.keys(input)) {\n if (!SERVER_FIELDS.has(key)) {\n throw new Error(`Server ${JSON.stringify(name)} has unknown field ${JSON.stringify(key)}`)\n }\n }\n\n const hasCommand = typeof input.command === 'string'\n const hasUrl = typeof input.url === 'string'\n if (hasCommand === hasUrl) {\n throw new Error(`Server ${JSON.stringify(name)} needs exactly one of command or url`)\n }\n if (hasCommand && input.command.trim() === '') {\n throw new Error(`Server ${JSON.stringify(name)} command cannot be empty`)\n }\n if (hasUrl) {\n let url\n try {\n url = new URL(input.url)\n } catch {\n throw new Error(`Server ${JSON.stringify(name)} URL must be absolute`)\n }\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new Error(`Server ${JSON.stringify(name)} URL must use HTTP or HTTPS`)\n }\n }\n\n const args = input.args ?? []\n if (!Array.isArray(args) || args.some((entry) => typeof entry !== 'string')) {\n throw new Error(`Server ${JSON.stringify(name)} args must be an array of strings`)\n }\n const env = requireStringRecord(input.env, `Server ${JSON.stringify(name)} env`)\n const headers = requireStringRecord(input.headers, `Server ${JSON.stringify(name)} headers`)\n if (hasCommand && Object.keys(headers).length > 0) {\n throw new Error(`Server ${JSON.stringify(name)} headers require HTTP transport`)\n }\n if (hasUrl && (args.length > 0 || Object.keys(env).length > 0)) {\n throw new Error(`Server ${JSON.stringify(name)} args and env require stdio transport`)\n }\n\n const idleTimeoutMinutes = input.idleTimeoutMinutes ?? 10\n if (!Number.isFinite(idleTimeoutMinutes) || idleTimeoutMinutes <= 0) {\n throw new Error(`Server ${JSON.stringify(name)} idle timeout must be positive`)\n }\n\n const auth = input.auth ?? 'headers'\n if (auth !== 'headers' && auth !== 'oauth') {\n throw new Error(`Server ${JSON.stringify(name)} auth must be \"headers\" or \"oauth\"`)\n }\n if (auth === 'oauth' && !hasUrl) {\n throw new Error(`Server ${JSON.stringify(name)} OAuth requires the HTTP Transport (url)`)\n }\n const scopes = input.scopes ?? []\n if (\n !Array.isArray(scopes) ||\n scopes.some((entry) => typeof entry !== 'string' || entry.trim() === '')\n ) {\n throw new Error(`Server ${JSON.stringify(name)} scopes must be an array of scope strings`)\n }\n if (scopes.length > 0 && auth !== 'oauth') {\n throw new Error(`Server ${JSON.stringify(name)} scopes require OAuth authentication`)\n }\n\n const promotedTools = input.promotedTools ?? []\n if (\n !Array.isArray(promotedTools) ||\n promotedTools.some((entry) => typeof entry !== 'string' || entry.trim() === '') ||\n new Set(promotedTools).size !== promotedTools.length\n ) {\n throw new Error(`Server ${JSON.stringify(name)} promotedTools must contain unique names`)\n }\n\n return {\n ...(hasCommand ? { command: input.command.trim(), args, env } : {\n url: input.url.trim(),\n headers,\n }),\n auth,\n scopes,\n disabled: input.disabled === true,\n autoAllow: input.autoAllow === true,\n lifecycle: 'lazy',\n idleTimeoutMinutes,\n promotedTools,\n }\n}\n\n/** Parse comma-separated OAuth scope text into a clean string array. */\nexport function parseScopes(text) {\n return String(text ?? '')\n .split(',')\n .map((entry) => entry.trim())\n .filter((entry) => entry !== '')\n}\n\nexport function parseMcpImport(text) {\n let parsed\n try {\n parsed = JSON.parse(text)\n } catch (error) {\n throw new Error(`Invalid JSON: ${messageOf(error)}`)\n }\n if (!isRecord(parsed) || !isRecord(parsed.mcpServers)) {\n throw new Error('Import JSON must contain an mcpServers object')\n }\n const servers = {}\n for (const [name, config] of Object.entries(parsed.mcpServers)) {\n servers[name] = normalizeServerConfig(name, config)\n }\n if (Object.keys(servers).length === 0) {\n throw new Error('Import JSON contains no Servers')\n }\n return servers\n}\n\nexport function parseArgs(text) {\n let parsed\n try {\n parsed = JSON.parse(text)\n } catch (error) {\n throw new Error(`Args must be a JSON array: ${messageOf(error)}`)\n }\n if (!Array.isArray(parsed) || parsed.some((entry) => typeof entry !== 'string')) {\n throw new Error('Args must be a JSON array of strings')\n }\n return parsed\n}\n\nexport function secretKeysFromView(view, serverName, field) {\n const namespace = view?.namespaces?.find((entry) => entry.ns === MCP_SETTINGS_NAMESPACE)\n if (namespace === undefined) return []\n return namespace.secrets\n .filter(\n (secret) =>\n secret.set === true &&\n secret.path.length === 4 &&\n secret.path[0] === 'mcpServers' &&\n secret.path[1] === serverName &&\n secret.path[2] === field,\n )\n .map((secret) => secret.path[3])\n .sort()\n}\n\nexport function secretRowOps(serverName, field, rows, existingKeys) {\n const unsetKeys = new Set()\n const sets = []\n const retained = new Set()\n for (const row of rows) {\n const originalKey = typeof row.originalKey === 'string' ? row.originalKey : undefined\n const key = typeof row.key === 'string' ? row.key.trim() : ''\n const value = typeof row.value === 'string' ? row.value : ''\n if (row.removed) {\n if (originalKey !== undefined) unsetKeys.add(originalKey)\n continue\n }\n if (key === '') throw new Error(`${field} keys cannot be empty`)\n if (retained.has(key)) throw new Error(`${field} key ${JSON.stringify(key)} is duplicated`)\n retained.add(key)\n if (originalKey !== undefined && originalKey !== key) {\n unsetKeys.add(originalKey)\n if (value === '') {\n throw new Error(`Enter a new value when renaming secret key ${JSON.stringify(originalKey)}`)\n }\n }\n if (value !== '') {\n sets.push({ op: 'set', path: ['mcpServers', serverName, field, key], value })\n } else if (originalKey === undefined && !existingKeys.includes(key)) {\n throw new Error(`Enter a value for new ${field} key ${JSON.stringify(key)}`)\n }\n }\n for (const key of existingKeys) {\n if (!rows.some((row) => row.originalKey === key || (!row.removed && row.key === key))) {\n unsetKeys.add(key)\n }\n }\n return [\n ...[...unsetKeys].map((key) => ({\n op: 'unset',\n path: ['mcpServers', serverName, field, key],\n })),\n ...sets,\n ]\n}\n\nfunction overviewEmpty() {\n return { status: { servers: [] }, catalog: { servers: [] } }\n}\n\n/**\n * Resolve the Config source of one Server from the workspace layer snapshot\n * delivered by the `layers` Connection RPC endpoint. Without a snapshot \u2014\n * for example an older Host \u2014 every Server reads as global.\n */\nexport function serverSource(layers, name) {\n return layers?.source?.[name] === 'workspace' ? 'workspace' : 'global'\n}\n\nexport class McpSettingsController {\n constructor({ scope, describe, settingsApi, rpc, pollIntervalMs = 3_000 }) {\n this.scope = scope\n this.describe = describe\n this.settingsApi = settingsApi\n this.rpc = rpc\n this.pollIntervalMs = pollIntervalMs\n this.listeners = new Set()\n this.overview = overviewEmpty()\n this.oauthStatuses = {}\n this.actionError = undefined\n this.overviewError = undefined\n this.layers = undefined\n this.pendingWrites = 0\n this.mounted = 0\n this.stopPoll = undefined\n this.loadingOverview = undefined\n this.loadingLayers = undefined\n this.tail = Promise.resolve()\n this.disposed = false\n this.unsubscribeScope = scope.subscribe(() => {\n this.publish()\n if (this.mounted > 0) {\n void this.loadOverview()\n void this.loadLayers()\n }\n })\n this.unsubscribeDescribe = describe.subscribe(() => this.publish())\n this.snapshot = this.projection()\n\n this.subscribe = (listener) => {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n this.getSnapshot = () => this.snapshot\n }\n\n projection() {\n return {\n settings: this.scope.getSnapshot(),\n settingsDocument: this.describe.getSnapshot(),\n overview: this.overview,\n layers: this.layers,\n oauthStatuses: this.oauthStatuses,\n error: this.actionError ?? this.overviewError,\n busy: this.pendingWrites > 0,\n }\n }\n\n publish() {\n this.snapshot = this.projection()\n for (const listener of this.listeners) listener()\n }\n\n mount() {\n if (this.disposed) return () => {}\n this.mounted += 1\n if (this.mounted === 1) {\n void this.describe.ensure().catch((error) => {\n this.actionError = `Could not load MCP Settings: ${messageOf(error)}`\n this.publish()\n })\n void this.loadOverview()\n void this.loadLayers()\n const id = setInterval(() => {\n void this.loadOverview()\n void this.loadLayers()\n }, this.pollIntervalMs)\n this.stopPoll = () => clearInterval(id)\n }\n return () => {\n this.mounted -= 1\n if (this.mounted === 0) {\n this.stopPoll?.()\n this.stopPoll = undefined\n }\n }\n }\n\n async loadOverview() {\n if (this.disposed) return\n if (this.loadingOverview !== undefined) return this.loadingOverview\n const request = (async () => {\n try {\n const result = await this.rpc('overview', {})\n if (!result.ok) throw new Error(result.error.message)\n this.overview = result.value\n this.overviewError = undefined\n await this.loadOauthStatuses()\n } catch (error) {\n this.overviewError = `Could not load MCP status: ${messageOf(error)}`\n } finally {\n this.loadingOverview = undefined\n this.publish()\n }\n })()\n this.loadingOverview = request\n return request\n }\n\n async loadLayers() {\n if (this.disposed) return\n if (this.loadingLayers !== undefined) return this.loadingLayers\n const request = (async () => {\n try {\n const result = await this.rpc('layers', {})\n if (!result.ok) throw new Error(result.error.message)\n this.layers = result.value\n } catch {\n // The layer snapshot is auxiliary; without it every Server reads as global.\n this.layers = undefined\n } finally {\n this.loadingLayers = undefined\n this.publish()\n }\n })()\n this.loadingLayers = request\n return request\n }\n\n /** Fetch `oauth-status` for every Server configured with OAuth. */\n async loadOauthStatuses() {\n if (this.disposed) return\n // Names come from the merged Config view: the global namespace plus the\n // sanitized workspace layer, so workspace-defined Servers are signable.\n const globalServers = this.scope.getSnapshot().value?.mcpServers ?? {}\n const workspaceServers = this.layers?.servers ?? {}\n const names = new Set()\n for (const [name, config] of Object.entries(globalServers)) {\n if (config?.auth === 'oauth' && typeof config.url === 'string') names.add(name)\n }\n for (const [name, config] of Object.entries(workspaceServers)) {\n if (config?.auth === 'oauth' && typeof config.url === 'string') names.add(name)\n }\n const statuses = {}\n await Promise.all(\n [...names].map(async (name) => {\n try {\n const result = await this.rpc('oauth-status', { server: name })\n if (result.ok) statuses[name] = result.value\n } catch {\n // A failed status probe leaves the Server out of the snapshot.\n }\n }),\n )\n this.oauthStatuses = statuses\n this.publish()\n }\n\n enqueue(label, operation) {\n this.pendingWrites += 1\n this.actionError = undefined\n this.publish()\n const run = this.tail.then(async () => {\n try {\n await operation()\n await Promise.all([this.loadOverview(), this.loadLayers()])\n return true\n } catch (error) {\n this.actionError = `${label}: ${messageOf(error)}`\n return false\n } finally {\n this.pendingWrites -= 1\n this.publish()\n }\n })\n this.tail = run.then(() => undefined)\n return run\n }\n\n async settingsWrite(method, input) {\n const revision = this.scope.getSnapshot().revision\n if (revision === undefined) throw new Error('Settings have not loaded yet')\n const response = await this.settingsApi[method]({\n ns: MCP_SETTINGS_NAMESPACE,\n ...input,\n expectedRevision: revision,\n })\n if (!response.result.ok) throw new Error(response.result.error.message)\n this.describe.acceptView(response.result.value)\n }\n\n addServer(name, config) {\n return this.enqueue('Could not add Server', async () => {\n const normalizedName = name.trim()\n const current = this.scope.getSnapshot().value?.mcpServers ?? {}\n if (Object.hasOwn(current, normalizedName)) {\n throw new Error(`Server ${JSON.stringify(normalizedName)} already exists`)\n }\n const server = normalizeServerConfig(normalizedName, config)\n await this.settingsWrite('update', {\n patch: { mcpServers: { [normalizedName]: server } },\n })\n })\n }\n\n importJson(text) {\n return this.enqueue('Could not import Servers', async () => {\n const servers = parseMcpImport(text)\n const current = this.scope.getSnapshot().value?.mcpServers ?? {}\n const replacesExisting = Object.keys(servers).some((name) => Object.hasOwn(current, name))\n if (!replacesExisting) {\n await this.settingsWrite('update', { patch: { mcpServers: servers } })\n return\n }\n await this.settingsWrite('mutate', {\n ops: Object.entries(servers).map(([name, server]) => ({\n op: 'set',\n path: ['mcpServers', name],\n value: server,\n })),\n })\n })\n }\n\n deleteServer(name) {\n return this.enqueue('Could not delete Server', () =>\n this.settingsWrite('mutate', {\n ops: [{ op: 'unset', path: ['mcpServers', name] }],\n }),\n )\n }\n\n setServerField(name, field, value) {\n return this.enqueue(`Could not update ${field}`, () =>\n this.settingsWrite('mutate', {\n ops: [{ op: 'set', path: ['mcpServers', name, field], value }],\n }),\n )\n }\n\n saveServer(name, draft, secretRows) {\n return this.enqueue('Could not save Server', async () => {\n const existing = this.scope.getSnapshot().value?.mcpServers?.[name]\n if (existing === undefined) throw new Error(`Server ${JSON.stringify(name)} no longer exists`)\n const args = draft.transport === 'stdio' ? parseArgs(draft.argsText) : []\n const scopes = draft.transport === 'http' ? parseScopes(draft.scopesText) : []\n const candidate = normalizeServerConfig(name, {\n ...(draft.transport === 'stdio'\n ? { command: draft.command, args, env: {} }\n : { url: draft.url, headers: {} }),\n auth: draft.transport === 'http' ? (draft.auth ?? 'headers') : 'headers',\n scopes,\n disabled: draft.disabled,\n autoAllow: draft.autoAllow,\n idleTimeoutMinutes: Number(draft.idleTimeoutMinutes),\n promotedTools: existing.promotedTools,\n })\n const ops = [\n { op: 'set', path: ['mcpServers', name, 'disabled'], value: candidate.disabled },\n { op: 'set', path: ['mcpServers', name, 'autoAllow'], value: candidate.autoAllow },\n {\n op: 'set',\n path: ['mcpServers', name, 'idleTimeoutMinutes'],\n value: candidate.idleTimeoutMinutes,\n },\n { op: 'set', path: ['mcpServers', name, 'auth'], value: candidate.auth },\n { op: 'set', path: ['mcpServers', name, 'scopes'], value: candidate.scopes },\n ]\n if (draft.transport === 'stdio') {\n ops.push(\n { op: 'set', path: ['mcpServers', name, 'command'], value: candidate.command },\n { op: 'set', path: ['mcpServers', name, 'args'], value: candidate.args },\n { op: 'unset', path: ['mcpServers', name, 'url'] },\n { op: 'unset', path: ['mcpServers', name, 'headers'] },\n ...secretRowOps(name, 'env', secretRows, secretKeysFromView(\n this.describe.getSnapshot().view,\n name,\n 'env',\n )),\n )\n } else {\n ops.push(\n { op: 'set', path: ['mcpServers', name, 'url'], value: candidate.url },\n { op: 'unset', path: ['mcpServers', name, 'command'] },\n { op: 'unset', path: ['mcpServers', name, 'args'] },\n { op: 'unset', path: ['mcpServers', name, 'env'] },\n ...secretRowOps(name, 'headers', secretRows, secretKeysFromView(\n this.describe.getSnapshot().view,\n name,\n 'headers',\n )),\n )\n }\n await this.settingsWrite('mutate', { ops })\n })\n }\n\n togglePromotion(name, toolName) {\n const tools = this.scope.getSnapshot().value?.mcpServers?.[name]?.promotedTools ?? []\n const next = tools.includes(toolName)\n ? tools.filter((entry) => entry !== toolName)\n : [...tools, toolName]\n return this.setServerField(name, 'promotedTools', next)\n }\n\n reconnect(name) {\n return this.enqueue('Could not reconnect Server', async () => {\n const result = await this.rpc('reconnect', { server: name })\n if (!result.ok) {\n await this.loadOverview()\n throw new Error(result.error.message)\n }\n this.overview = result.value\n })\n }\n\n /**\n * Start the OAuth flow for one Server. Resolves with the RPC value\n * (`{ authorizationUrl }`); the caller opens the URL in the browser.\n */\n async signIn(name) {\n this.pendingWrites += 1\n this.actionError = undefined\n this.publish()\n try {\n const result = await this.rpc('oauth-login', { server: name })\n if (!result.ok) throw new Error(result.error.message)\n return result.value\n } catch (error) {\n this.actionError = `Could not start sign-in: ${messageOf(error)}`\n return undefined\n } finally {\n this.pendingWrites -= 1\n this.publish()\n }\n }\n\n signOut(name) {\n return this.enqueue('Could not sign out', async () => {\n const result = await this.rpc('oauth-logout', { server: name })\n if (!result.ok) throw new Error(result.error.message)\n })\n }\n\n async dispose() {\n if (this.disposed) return\n this.disposed = true\n this.stopPoll?.()\n this.unsubscribeScope?.()\n this.unsubscribeDescribe?.()\n await this.tail\n this.listeners.clear()\n }\n}\n", "/**\n * Resolve the Settings write face across DSH harness generations.\n *\n * DSH 0.1.2-rc.1 removed the `connection` service's `api` face, moving the\n * settings write surface onto the `remote` service (its `settings` namespace is\n * mounted by the @deepseek-ai/dsh-api-remotes client bundle). The new face\n * takes positional `(ns, patch | ops, expectedRevision)` arguments and answers\n * a flat `{ ok, value | error }` envelope. DSH 0.1.1-rc.2 keeps the write\n * surface on `connection.api.settings`, with one request-object argument and a\n * `{ result: { ok, value | error } }` envelope.\n *\n * Both faces normalize to the controller's contract: `update` and `mutate`\n * take one request object and answer `{ result: { ok, value, error } }`, so\n * callers stay unaware of which harness generation is running. Prefer the\n * `remote` face when it exists: it is the only one DSH 0.1.2-rc.1 provides.\n */\nexport function createSettingsApi(ctx) {\n const remoteSettings = ctx.remote?.settings\n if (remoteSettings !== undefined) return remoteSettingsApi(remoteSettings)\n\n const connectionSettings = ctx.connection?.api?.settings\n if (connectionSettings !== undefined) return connectionSettings\n\n throw new Error(\n 'No DSH settings write API: expected ctx.remote.settings (DSH 0.1.2+) '\n + 'or ctx.connection.api.settings (DSH 0.1.1-rc.2). Upgrade '\n + '@auggieteo/dsh-mcp-adapter to a release supporting this harness.',\n )\n}\n\n/** Wrap the 0.1.2-rc.1 `remote.settings` face in the controller's contract. */\nfunction remoteSettingsApi(remote) {\n return {\n async update({ ns, patch, expectedRevision }) {\n return { result: await remote.update(ns, patch, expectedRevision) }\n },\n async mutate({ ns, ops, expectedRevision }) {\n return { result: await remote.mutate(ns, ops, expectedRevision) }\n },\n }\n}\n", "export const MCP_SETTINGS_CSS = `\n.mcp-settings{width:100%;max-width:980px;min-width:0;container-type:inline-size;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:14px}\n.mcp-settings *{box-sizing:border-box}\n.mcp-title{margin:0;font-size:16px;line-height:24px;font-weight:600}\n.mcp-intro,.mcp-muted{margin:0;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}\n.mcp-toolbar,.mcp-actions,.mcp-row,.mcp-card-head{display:flex;align-items:center;gap:8px}\n.mcp-toolbar{justify-content:space-between;flex-wrap:wrap}\n.mcp-actions{flex-wrap:wrap}\n.mcp-button{height:32px;border:1px solid var(--dsw-alias-border-l2);border-radius:16px;background:transparent;color:var(--dsw-alias-label-primary);padding:0 13px;font:inherit;font-size:12px;cursor:pointer;transition:background .12s ease,border-color .12s ease,color .12s ease}\n.mcp-button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.mcp-button:active:not(:disabled){background:var(--dsw-alias-interactive-bg-active)}\n.mcp-button:disabled{cursor:not-allowed;opacity:.5}\n.mcp-button-primary{border-color:transparent;background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}\n.mcp-button-primary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}\n.mcp-button-danger{color:var(--dsw-alias-state-error-primary)}\n.mcp-button-danger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}\n.mcp-button:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}\n.mcp-error,.mcp-warning{border-radius:8px;padding:9px 11px;font-size:12px;line-height:18px}\n.mcp-error{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);color:var(--dsw-alias-state-error-primary)}\n.mcp-warning{background:var(--dsw-alias-state-warn-tertiary);color:var(--dsw-alias-state-warn-label)}\n.mcp-layout{display:grid;grid-template-columns:208px minmax(0,1fr);gap:14px;align-items:start;min-width:0}\n.mcp-card,.mcp-empty{border:1px solid var(--dsw-alias-border-l1);border-radius:12px;background:var(--dsw-alias-bg-layer-2)}\n.mcp-sidebar{display:flex;flex-direction:column;gap:2px;position:sticky;top:12px}\n.mcp-server-button{width:100%;border:0;border-radius:8px;background:transparent;color:var(--dsw-alias-label-secondary);padding:8px 10px;display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;gap:8px;align-items:center;text-align:left;cursor:pointer;font:inherit;transition:background .12s ease,color .12s ease}\n.mcp-server-button:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.mcp-server-button[aria-current=true]{background:var(--dsw-alias-button-ghost-active-fill);color:var(--dsw-alias-label-primary)}\n.mcp-server-name{min-width:0;overflow:hidden;text-overflow:ellipsis;font-size:13px;font-weight:500}\n.mcp-server-count{color:var(--dsw-alias-label-tertiary);font-size:11px}\n.mcp-status-dot{width:7px;height:7px;border-radius:50%;background:var(--dsw-alias-label-dimmed);flex:none}\n.mcp-status-connected{background:var(--dsw-alias-state-success-primary)}\n.mcp-status-connecting{background:var(--dsw-alias-state-warn-primary)}\n.mcp-status-dot.mcp-status-connecting{animation:mcp-pulse 1.2s ease-in-out infinite}\n@keyframes mcp-pulse{0%,100%{opacity:1}50%{opacity:.35}}\n.mcp-status-error{background:var(--dsw-alias-state-error-primary)}\n.mcp-status-disabled{background:var(--dsw-alias-label-dimmed)}\n.mcp-card{padding:16px;display:flex;flex-direction:column;gap:14px;min-width:0}\n.mcp-card-head{align-items:flex-start;flex-wrap:wrap}\n.mcp-card-head > div:first-child{flex:1 1 200px;min-width:0}\n.mcp-card-title{margin:0;font-size:15px;line-height:22px;font-weight:600;overflow-wrap:anywhere}\n.mcp-card-head .mcp-actions{margin-left:auto;justify-content:flex-end;flex:none}\n.mcp-badge{border:1px solid var(--dsw-alias-border-l2);border-radius:5px;padding:1px 7px;color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px;background:transparent}\n.mcp-badge.mcp-status-connected{color:var(--dsw-alias-state-success-primary);border-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 35%, transparent);background:transparent}\n.mcp-badge.mcp-status-connecting{color:var(--dsw-alias-state-warn-label);border-color:color-mix(in srgb, var(--dsw-alias-state-warn-primary) 35%, transparent);background:transparent}\n.mcp-badge.mcp-status-error{color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 35%, transparent);background:transparent}\n.mcp-badge.mcp-status-disabled{color:var(--dsw-alias-label-dimmed);background:transparent}\n.mcp-badge-workspace{color:var(--dsw-alias-state-business-primary);border-color:color-mix(in srgb, var(--dsw-alias-state-business-primary) 35%, transparent);background:transparent}\n.mcp-layer-notice{border:1px solid color-mix(in srgb, var(--dsw-alias-state-business-primary) 35%, transparent);border-radius:8px;padding:9px 11px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}\n.mcp-form{display:flex;flex-direction:column;gap:12px}\n.mcp-field{display:flex;flex-direction:column;gap:5px;min-width:0}\n.mcp-field-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px}\n.mcp-label{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:500;line-height:18px}\n.mcp-input,.mcp-select,.mcp-textarea{width:100%;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;outline:none;transition:border-color .12s ease,background .12s ease}\n.mcp-input,.mcp-select{height:34px;padding:0 10px}\n.mcp-textarea{min-height:76px;padding:8px 10px;resize:vertical;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:18px}\n.mcp-input:hover:not(:focus):not(:disabled),.mcp-select:hover:not(:focus):not(:disabled),.mcp-textarea:hover:not(:focus):not(:disabled){border-color:var(--dsw-alias-border-l3)}\n.mcp-input:focus,.mcp-select:focus,.mcp-textarea:focus{border-color:var(--dsw-alias-state-business-primary)}\n.mcp-input:read-only{background:transparent;border-color:transparent;color:var(--dsw-alias-label-tertiary)}\n.mcp-input::placeholder,.mcp-textarea::placeholder{color:var(--dsw-alias-label-dimmed)}\n.mcp-settings input[type=checkbox],.mcp-settings input[type=number]{accent-color:var(--dsw-alias-state-business-primary)}\n.mcp-checkbox{display:flex;align-items:flex-start;gap:8px;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px}\n.mcp-checkbox input{margin-top:3px}\n.mcp-section{border-top:1px solid var(--dsw-alias-border-l1);padding-top:12px;display:flex;flex-direction:column;gap:9px}\n.mcp-section-title{margin:0;font-size:12px;font-weight:600;line-height:18px;color:var(--dsw-alias-label-secondary)}\n.mcp-secret-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.2fr) auto;gap:7px;align-items:center}\n.mcp-secret-row > *{min-width:0}\n.mcp-promotion-list{display:flex;flex-direction:column;gap:2px;max-height:240px;overflow:auto}\n.mcp-promotion{border-radius:8px;padding:8px 10px;display:grid;grid-template-columns:auto minmax(0,1fr);gap:9px;align-items:start;cursor:pointer;transition:background .12s ease}\n.mcp-promotion:hover{background:var(--dsw-alias-interactive-bg-hover)}\n.mcp-promotion-name{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:var(--dsw-alias-label-primary);overflow-wrap:anywhere}\n.mcp-promotion-description{display:block;color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:17px}\n.mcp-empty{padding:30px 20px;text-align:center;display:flex;align-items:center;flex-direction:column;gap:10px}\n.mcp-overlay{position:fixed;inset:0;background:var(--dsw-alias-bg-mask-1);display:flex;align-items:center;justify-content:center;padding:20px;z-index:1200;animation:mcp-fade .12s ease}\n.mcp-modal-card{width:min(560px,100%);max-height:min(760px,90vh);overflow:auto;padding:18px;display:flex;flex-direction:column;gap:13px;border:1px solid var(--dsw-alias-border-l1);border-radius:14px;background:var(--dsw-alias-bg-overlay);box-shadow:0 18px 60px rgba(0,0,0,.32);animation:mcp-pop .16s ease}\n@keyframes mcp-fade{from{opacity:0}to{opacity:1}}\n@keyframes mcp-pop{from{opacity:0;transform:translateY(6px) scale(.98)}to{opacity:1;transform:none}}\n.mcp-modal-title{margin:0;font-size:15px;line-height:22px;font-weight:600}\n.mcp-confirm{border-radius:8px;padding:10px;display:flex;flex-direction:column;gap:8px;background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent)}\n@container (max-width:660px){.mcp-layout{grid-template-columns:minmax(0,1fr)}.mcp-sidebar{position:static;flex-direction:row;overflow-x:auto;padding-bottom:2px}.mcp-server-button{width:auto;flex:none;white-space:nowrap}}\n@container (max-width:480px){.mcp-field-row{grid-template-columns:minmax(0,1fr)}.mcp-secret-row{grid-template-columns:minmax(0,1fr) auto}.mcp-secret-row .mcp-input:first-child{grid-column:1 / -1}.mcp-card-head .mcp-actions{margin-left:0;width:100%}.mcp-toolbar{align-items:flex-start}}\n`\n\nexport function installMcpSettingsStyles() {\n const id = 'dsh-mcp-adapter-settings'\n const existing = document.querySelector(`style[data-plugin-css=\"${id}\"]`)\n if (existing !== null) return () => {}\n const style = document.createElement('style')\n style.dataset.pluginCss = id\n style.textContent = MCP_SETTINGS_CSS\n document.head.appendChild(style)\n return () => style.remove()\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { McpSettingsPage } from './McpSettingsPage.jsx'\nimport {\n MCP_RPC_CHANNEL,\n MCP_SETTINGS_NAMESPACE,\n McpSettingsController,\n} from './settings-controller.js'\nimport { createSettingsApi } from './settings-api.js'\nimport { installMcpSettingsStyles } from './styles.js'\n\n// `remote` rides the 0.1.2-rc.1+ settings write surface (see settings-api.js);\n// it exists on every harness generation, while `connection.api` only on\n// 0.1.1-rc.2, so both stay declared and the resolution happens at apply time.\n// `remote.settings` deliberately stays UNDECLARED: on 0.1.2-rc.1 it is a\n// mounted dotted service read through the inject-free `ctx.get`, and\n// declaring it would park the plugin forever on 0.1.1-rc.2, where the\n// namespace is never mounted.\nexport const inject = ['slots', 'settingsScope', 'connection', 'remote']\n\nexport function apply(ctx) {\n const scope = ctx.settingsScope.bind({ namespace: MCP_SETTINGS_NAMESPACE })\n const describe = ctx.settingsScope.describe()\n const controller = new McpSettingsController({\n scope,\n describe,\n settingsApi: createSettingsApi(ctx),\n rpc: (endpoint, payload, signal) =>\n ctx.connection.rpc.call(MCP_RPC_CHANNEL, endpoint, payload, signal),\n })\n\n ctx.effect(() => installMcpSettingsStyles(), 'mcp-adapter: Settings styles')\n ctx.effect(() => () => controller.dispose(), 'mcp-adapter: Settings controller')\n ctx.slots.inject('settings.section', () =>\n ctx.slots.register(\n {\n name: 'settings.section',\n id: 'mcp',\n order: 30,\n label: 'MCP',\n inject: () => ({ controller }),\n },\n McpSettingsPage,\n ),\n )\n}\n", "import React, { useEffect, useMemo, useState, useSyncExternalStore } from 'react'\n\nimport {\n normalizeServerConfig,\n parseArgs,\n parseMcpImport,\n parseScopes,\n secretKeysFromView,\n secretRowOps,\n serverSource,\n} from './settings-controller.js'\n\nfunction statusFor(overview, name) {\n return overview.status.servers.find((entry) => entry.name === name) ?? {\n name,\n state: 'disconnected',\n toolCount: 0,\n }\n}\n\nfunction catalogFor(overview, name) {\n return overview.catalog.servers.find((entry) => entry.name === name)?.tools ?? []\n}\n\nfunction statusClass(state) {\n if (state === 'connected') return 'mcp-status-connected'\n if (state === 'connecting') return 'mcp-status-connecting'\n if (state === 'error') return 'mcp-status-error'\n if (state === 'disabled') return 'mcp-status-disabled'\n return ''\n}\n\nfunction secretRows(keys) {\n return keys.map((key) => ({ originalKey: key, key, value: '' }))\n}\n\nfunction SecretEditor({ field, rows, onChange, disabled }) {\n const label = field === 'env' ? 'Environment variables' : 'HTTP headers'\n const add = () => onChange([...rows, { key: '', value: '' }])\n const update = (index, patch) => {\n onChange(rows.map((row, position) => position === index ? { ...row, ...patch } : row))\n }\n const remove = (index) => onChange(rows.filter((_, position) => position !== index))\n\n return (\n <div className=\"mcp-section\">\n <div>\n <h4 className=\"mcp-section-title\">{label}</h4>\n <p className=\"mcp-muted\">\n Existing secret values stay saved when their value field remains blank.\n </p>\n </div>\n {rows.map((row, index) => (\n <div className=\"mcp-secret-row\" key={`${row.originalKey ?? 'new'}-${index}`}>\n <input\n className=\"mcp-input\"\n aria-label={`${label} key ${index + 1}`}\n placeholder={field === 'env' ? 'API_TOKEN' : 'Authorization'}\n value={row.key}\n disabled={disabled}\n onChange={(event) => update(index, { key: event.target.value })}\n />\n <input\n className=\"mcp-input\"\n aria-label={`${label} value ${index + 1}`}\n type={field === 'env' ? 'password' : 'text'}\n autoComplete=\"off\"\n placeholder={row.originalKey === undefined ? 'Value' : 'Saved value'}\n value={row.value}\n disabled={disabled}\n onChange={(event) => update(index, { value: event.target.value })}\n />\n <button\n type=\"button\"\n className=\"mcp-button mcp-button-danger\"\n disabled={disabled}\n onClick={() => remove(index)}\n >\n Remove\n </button>\n </div>\n ))}\n <div>\n <button type=\"button\" className=\"mcp-button\" disabled={disabled} onClick={add}>\n Add {field === 'env' ? 'variable' : 'header'}\n </button>\n </div>\n </div>\n )\n}\n\nfunction useEscapeClose(onClose) {\n useEffect(() => {\n const onKey = (event) => {\n if (event.key === 'Escape') onClose()\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [onClose])\n}\n\n/**\n * The single entry point for adding Servers: an Input fields mode for one\n * Server, or a Paste JSON mode for a standard `mcpServers` object.\n */\nfunction AddServerDialog({ controller, busy, onClose }) {\n const [mode, setMode] = useState('form')\n const [name, setName] = useState('')\n const [transport, setTransport] = useState('stdio')\n const [command, setCommand] = useState('')\n const [url, setUrl] = useState('')\n const [argsText, setArgsText] = useState('[]')\n const [auth, setAuth] = useState('headers')\n const [scopesText, setScopesText] = useState('')\n const [jsonText, setJsonText] = useState('{\\n \"mcpServers\": {\\n \\n }\\n}')\n const [error, setError] = useState()\n useEscapeClose(onClose)\n const switchMode = (next) => {\n setMode(next)\n setError(undefined)\n }\n const submit = async (event) => {\n event.preventDefault()\n setError(undefined)\n if (mode === 'json') {\n try {\n parseMcpImport(jsonText)\n } catch (nextError) {\n setError(nextError instanceof Error ? nextError.message : String(nextError))\n return\n }\n const result = await controller.importJson(jsonText)\n if (result) onClose()\n else setError('The Host rejected this import. Review the page error and retry.')\n return\n }\n let config\n try {\n config = normalizeServerConfig(\n name,\n transport === 'stdio'\n ? { command, args: parseArgs(argsText) }\n : { url, auth, scopes: auth === 'oauth' ? parseScopes(scopesText) : [] },\n )\n } catch (nextError) {\n setError(nextError instanceof Error ? nextError.message : String(nextError))\n return\n }\n if (await controller.addServer(name, config)) onClose()\n }\n\n return (\n <div className=\"mcp-overlay\" role=\"presentation\" onMouseDown={(event) => {\n if (event.target === event.currentTarget) onClose()\n }}>\n <form className=\"mcp-modal-card\" aria-label=\"Add MCP Server\" onSubmit={submit}>\n <div className=\"mcp-card-head\">\n <div>\n <h3 className=\"mcp-modal-title\">Add Server</h3>\n <p className=\"mcp-muted\">Fill in the fields for one Server, or paste an mcpServers JSON.</p>\n </div>\n <button type=\"button\" className=\"mcp-button\" onClick={onClose}>Close</button>\n </div>\n <div className=\"mcp-dialog-tabs\" role=\"tablist\" aria-label=\"Add Server input mode\">\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={mode === 'form'}\n className={mode === 'form' ? 'mcp-dialog-tab mcp-dialog-tab-active' : 'mcp-dialog-tab'}\n disabled={busy}\n onClick={() => switchMode('form')}\n >\n Input fields\n </button>\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={mode === 'json'}\n className={mode === 'json' ? 'mcp-dialog-tab mcp-dialog-tab-active' : 'mcp-dialog-tab'}\n disabled={busy}\n onClick={() => switchMode('json')}\n >\n Paste JSON\n </button>\n </div>\n {error !== undefined && <div className=\"mcp-error\" role=\"alert\">{error}</div>}\n {mode === 'json' && (\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">MCP Config JSON</span>\n <textarea\n autoFocus\n className=\"mcp-textarea\"\n style={{ minHeight: 280 }}\n value={jsonText}\n disabled={busy}\n spellCheck={false}\n onChange={(event) => setJsonText(event.target.value)}\n />\n <span className=\"mcp-muted\">\n One or more Servers. A name that already exists is replaced.\n </span>\n </label>\n )}\n {mode === 'form' && (\n <>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Name</span>\n <input\n autoFocus\n className=\"mcp-input\"\n value={name}\n disabled={busy}\n onChange={(event) => setName(event.target.value)}\n placeholder=\"github\"\n />\n </label>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Transport</span>\n <select\n className=\"mcp-select\"\n value={transport}\n disabled={busy}\n onChange={(event) => setTransport(event.target.value)}\n >\n <option value=\"stdio\">stdio</option>\n <option value=\"http\">Streamable HTTP</option>\n </select>\n </label>\n {transport === 'stdio' ? (\n <>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Command</span>\n <input\n className=\"mcp-input\"\n value={command}\n disabled={busy}\n onChange={(event) => setCommand(event.target.value)}\n placeholder=\"npx\"\n />\n </label>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Args as a JSON array</span>\n <textarea\n className=\"mcp-textarea\"\n value={argsText}\n disabled={busy}\n placeholder={'[\"-y\", \"@modelcontextprotocol/server-github\"]'}\n onChange={(event) => setArgsText(event.target.value)}\n spellCheck={false}\n />\n </label>\n </>\n ) : (\n <>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">URL</span>\n <input\n className=\"mcp-input\"\n value={url}\n disabled={busy}\n onChange={(event) => setUrl(event.target.value)}\n placeholder=\"https://example.com/mcp\"\n />\n </label>\n <div className=\"mcp-field-row\">\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">HTTP authentication</span>\n <select\n className=\"mcp-select\"\n value={auth}\n disabled={busy}\n title=\"Static headers send fixed values on every request. OAuth 2.0 with PKCE signs in through the provider in your browser.\"\n onChange={(event) => setAuth(event.target.value)}\n >\n <option value=\"headers\">Static headers</option>\n <option value=\"oauth\">OAuth 2.0 with PKCE</option>\n </select>\n </label>\n {auth === 'oauth' && (\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">OAuth scopes (optional, comma-separated)</span>\n <input\n className=\"mcp-input\"\n value={scopesText}\n disabled={busy}\n placeholder=\"read write\"\n title=\"Optional. Leave empty when the provider defines no scopes \u2014 for example Context7. Request only scopes the provider grants.\"\n onChange={(event) => setScopesText(event.target.value)}\n />\n <span className=\"mcp-muted\">Leave empty unless the provider requires scopes.</span>\n </label>\n )}\n </div>\n {auth === 'oauth' && (\n <p className=\"mcp-muted\">\n OAuth signs in through your browser. The Sign in button appears\n on the Server panel after you save.\n </p>\n )}\n </>\n )}\n </>\n )}\n <div className=\"mcp-actions\">\n <button type=\"submit\" className=\"mcp-button mcp-button-primary\" disabled={busy}>\n {busy\n ? mode === 'json' ? 'Importing\u2026' : 'Adding\u2026'\n : mode === 'json' ? 'Import Servers' : 'Add Server'}\n </button>\n <button type=\"button\" className=\"mcp-button\" disabled={busy} onClick={onClose}>\n Cancel\n </button>\n </div>\n </form>\n </div>\n )\n}\n\n/**\n * OAuth sign-in/sign-out section, shared by the editable detail and the\n * read-only workspace detail. Sign-in works for workspace-defined Servers\n * too: the Adapter resolves the Server through the merged Config.\n */\nfunction OAuthSection({ controller, snapshot, name }) {\n const oauthStatus = snapshot.oauthStatuses?.[name]\n const oauthSignedIn =\n oauthStatus !== undefined &&\n oauthStatus.signedIn === true &&\n (oauthStatus.expiresAt === undefined || oauthStatus.expiresAt > Date.now())\n const oauthState = oauthStatus?.configured\n ? oauthSignedIn\n ? 'Signed in'\n : oauthStatus.expiresAt !== undefined\n ? 'Signed out (token expired)'\n : 'Signed out'\n : 'Signed out'\n const signIn = async () => {\n const result = await controller.signIn(name)\n if (result?.authorizationUrl) window.open(result.authorizationUrl, '_blank')\n }\n\n return (\n <div className=\"mcp-section\">\n <div>\n <h3 className=\"mcp-section-title\">OAuth</h3>\n <p className=\"mcp-muted\">\n OAuth 2.0 with PKCE. {oauthState}. Sign-in opens the authorization\n page in your browser; the Adapter completes the flow in the\n background and reconnects with the fresh tokens. If no tab opens,\n allow pop-ups for this page or run /mcp-auth.\n </p>\n {oauthStatus !== undefined && oauthStatus.configured === true && !oauthSignedIn && (\n <div className=\"mcp-warning\">This Server cannot connect until you sign in.</div>\n )}\n </div>\n <div className=\"mcp-actions\">\n <button\n type=\"button\"\n className=\"mcp-button mcp-button-primary\"\n disabled={snapshot.busy}\n title=\"Opens the provider's authorization page in a new browser tab. The Adapter finishes the flow in the background and reconnects.\"\n onClick={() => void signIn()}\n >\n Sign in\n </button>\n <button\n type=\"button\"\n className=\"mcp-button\"\n disabled={snapshot.busy}\n title=\"Deletes the stored tokens and disconnects this Server.\"\n onClick={() => void controller.signOut(name)}\n >\n Sign out\n </button>\n </div>\n </div>\n )\n}\n\n/**\n * Read-only detail for a Server defined only in the workspace `.dsh/mcp.json`.\n * Edits write the global Config layer, which the workspace file overrides, so\n * the panel shows the sanitized workspace Config and, for OAuth Servers, the\n * sign-in actions.\n */\nfunction WorkspaceServerDetail({ controller, snapshot, name, server }) {\n const status = statusFor(snapshot.overview, name)\n return (\n <div className=\"mcp-card\">\n <div className=\"mcp-card-head\">\n <div>\n <div className=\"mcp-row\">\n <span className={`mcp-status-dot ${statusClass(status.state)}`} />\n <h2 className=\"mcp-card-title\">{name}</h2>\n <span className={`mcp-badge ${statusClass(status.state)}`}>{status.state}</span>\n <span className=\"mcp-badge mcp-badge-workspace\">workspace</span>\n </div>\n <p className=\"mcp-muted\">\n {status.toolCount} {status.toolCount === 1 ? 'tool' : 'tools'} cached\n {status.transport === undefined ? '' : ` \u00B7 ${status.transport}`}\n </p>\n </div>\n </div>\n <div className=\"mcp-layer-notice\">\n Read-only: defined by the workspace .dsh/mcp.json file. Edit that file\n to change this Server.\n </div>\n <div className=\"mcp-section\">\n <h3 className=\"mcp-section-title\">Config</h3>\n <p className=\"mcp-muted\">\n {typeof server.command === 'string'\n ? `stdio: ${server.command}${(server.args ?? []).length > 0 ? ` ${server.args.join(' ')}` : ''}`\n : `HTTP: ${server.url}`}{' '}\n \u00B7 lifecycle {server.lifecycle ?? 'lazy'} \u00B7 {server.autoAllow ? 'auto-allow' : 'asks per call'}\n </p>\n </div>\n {typeof server.url === 'string' && server.auth === 'oauth' && (\n <OAuthSection controller={controller} snapshot={snapshot} name={name} />\n )}\n <div className=\"mcp-section\">\n <h3 className=\"mcp-section-title\">Promotions</h3>\n <p className=\"mcp-muted\">\n Promotions for a workspace Server are managed in the workspace file\n through its promotedTools list.\n </p>\n </div>\n </div>\n )\n}\n\nfunction ServerDetail({ controller, snapshot, name, server }) {\n const status = statusFor(snapshot.overview, name)\n const tools = catalogFor(snapshot.overview, name)\n const workspaceSourced = serverSource(snapshot.layers, name) === 'workspace'\n const transport = typeof server.command === 'string' ? 'stdio' : 'http'\n const [draft, setDraft] = useState(() => ({\n transport,\n command: server.command ?? '',\n url: server.url ?? '',\n argsText: JSON.stringify(server.args ?? [], null, 2),\n auth: server.auth ?? 'headers',\n scopesText: (server.scopes ?? []).join(', '),\n disabled: server.disabled === true,\n autoAllow: server.autoAllow === true,\n idleTimeoutMinutes: String(server.idleTimeoutMinutes ?? 10),\n }))\n const [rowSets, setRowSets] = useState(() => ({\n env: secretRows(secretKeysFromView(snapshot.settingsDocument.view, name, 'env')),\n headers: secretRows(secretKeysFromView(snapshot.settingsDocument.view, name, 'headers')),\n }))\n const activeSecretField = draft.transport === 'stdio' ? 'env' : 'headers'\n const rows = rowSets[activeSecretField]\n const [dirty, setDirty] = useState(false)\n const [formError, setFormError] = useState()\n const [confirmDelete, setConfirmDelete] = useState(false)\n\n useEffect(() => {\n if (dirty) return\n const nextTransport = typeof server.command === 'string' ? 'stdio' : 'http'\n setDraft({\n transport: nextTransport,\n command: server.command ?? '',\n url: server.url ?? '',\n argsText: JSON.stringify(server.args ?? [], null, 2),\n auth: server.auth ?? 'headers',\n scopesText: (server.scopes ?? []).join(', '),\n disabled: server.disabled === true,\n autoAllow: server.autoAllow === true,\n idleTimeoutMinutes: String(server.idleTimeoutMinutes ?? 10),\n })\n setRowSets({\n env: secretRows(secretKeysFromView(snapshot.settingsDocument.view, name, 'env')),\n headers: secretRows(secretKeysFromView(snapshot.settingsDocument.view, name, 'headers')),\n })\n }, [dirty, name, server, snapshot.settingsDocument.view])\n\n const changeDraft = (patch) => {\n setDirty(true)\n setDraft((current) => ({ ...current, ...patch }))\n }\n const changeRows = (next) => {\n setDirty(true)\n setRowSets((current) => ({ ...current, [activeSecretField]: next }))\n }\n const save = async (event) => {\n event.preventDefault()\n setFormError(undefined)\n try {\n const nextTransport = draft.transport\n normalizeServerConfig(name, {\n ...(nextTransport === 'stdio'\n ? { command: draft.command, args: parseArgs(draft.argsText) }\n : { url: draft.url }),\n auth: nextTransport === 'http' ? draft.auth : 'headers',\n scopes: nextTransport === 'http' ? parseScopes(draft.scopesText) : [],\n disabled: draft.disabled,\n autoAllow: draft.autoAllow,\n idleTimeoutMinutes: Number(draft.idleTimeoutMinutes),\n promotedTools: server.promotedTools,\n })\n const field = nextTransport === 'stdio' ? 'env' : 'headers'\n secretRowOps(\n name,\n field,\n rows,\n secretKeysFromView(snapshot.settingsDocument.view, name, field),\n )\n } catch (nextError) {\n setFormError(nextError instanceof Error ? nextError.message : String(nextError))\n return\n }\n if (await controller.saveServer(name, draft, rows)) {\n setRowSets((current) => ({\n ...current,\n [activeSecretField]: rows.map((row) => ({\n originalKey: row.key.trim(),\n key: row.key.trim(),\n value: '',\n })),\n }))\n setDirty(false)\n }\n }\n const remove = async () => {\n if (await controller.deleteServer(name)) setConfirmDelete(false)\n }\n\n return (\n <div className=\"mcp-card\">\n <div className=\"mcp-card-head\">\n <div>\n <div className=\"mcp-row\">\n <span className={`mcp-status-dot ${statusClass(status.state)}`} />\n <h2 className=\"mcp-card-title\">{name}</h2>\n <span className={`mcp-badge ${statusClass(status.state)}`}>{status.state}</span>\n {workspaceSourced && (\n <span className=\"mcp-badge mcp-badge-workspace\">workspace</span>\n )}\n </div>\n <p className=\"mcp-muted\">\n {status.toolCount} {status.toolCount === 1 ? 'tool' : 'tools'} cached\n {status.transport === undefined ? '' : ` \u00B7 ${status.transport}`}\n </p>\n </div>\n <div className=\"mcp-actions\">\n <button\n type=\"button\"\n className=\"mcp-button\"\n disabled={snapshot.busy || draft.disabled}\n onClick={() => void controller.reconnect(name)}\n >\n Reconnect\n </button>\n <button\n type=\"button\"\n className=\"mcp-button mcp-button-danger\"\n disabled={snapshot.busy}\n onClick={() => setConfirmDelete(true)}\n >\n Delete\n </button>\n </div>\n </div>\n\n {workspaceSourced && (\n <div className=\"mcp-layer-notice\" role=\"note\">\n This Server is defined or overridden by the workspace .dsh/mcp.json.\n Edits here write the global layer, which the workspace file overrides.\n </div>\n )}\n {status.message !== undefined && status.state === 'error' && (\n <div className=\"mcp-error\" role=\"alert\">{status.message}</div>\n )}\n {confirmDelete && (\n <div className=\"mcp-confirm\">\n <strong>Delete {name}?</strong>\n <span className=\"mcp-muted\">This removes its Config and disconnects the Server.</span>\n <div className=\"mcp-actions\">\n <button\n type=\"button\"\n className=\"mcp-button mcp-button-danger\"\n disabled={snapshot.busy}\n onClick={() => void remove()}\n >\n Confirm delete\n </button>\n <button type=\"button\" className=\"mcp-button\" onClick={() => setConfirmDelete(false)}>\n Cancel\n </button>\n </div>\n </div>\n )}\n\n <form className=\"mcp-form\" onSubmit={save}>\n {formError !== undefined && <div className=\"mcp-error\" role=\"alert\">{formError}</div>}\n <div className=\"mcp-field-row\">\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Name</span>\n <input className=\"mcp-input\" value={name} readOnly />\n </label>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Transport</span>\n <select\n className=\"mcp-select\"\n value={draft.transport}\n disabled={snapshot.busy}\n onChange={(event) => changeDraft({ transport: event.target.value })}\n >\n <option value=\"stdio\">stdio</option>\n <option value=\"http\">Streamable HTTP</option>\n </select>\n </label>\n </div>\n\n {draft.transport === 'stdio' ? (\n <>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Command</span>\n <input\n className=\"mcp-input\"\n value={draft.command}\n disabled={snapshot.busy}\n onChange={(event) => changeDraft({ command: event.target.value })}\n />\n </label>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Args as a JSON array</span>\n <textarea\n className=\"mcp-textarea\"\n value={draft.argsText}\n disabled={snapshot.busy}\n spellCheck={false}\n onChange={(event) => changeDraft({ argsText: event.target.value })}\n />\n </label>\n <SecretEditor field=\"env\" rows={rows} onChange={changeRows} disabled={snapshot.busy} />\n </>\n ) : (\n <>\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">URL</span>\n <input\n className=\"mcp-input\"\n value={draft.url}\n disabled={snapshot.busy}\n onChange={(event) => changeDraft({ url: event.target.value })}\n />\n </label>\n <div className=\"mcp-field-row\">\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">HTTP authentication</span>\n <select\n className=\"mcp-select\"\n value={draft.auth ?? 'headers'}\n disabled={snapshot.busy}\n title=\"Static headers send fixed values on every request. OAuth 2.0 with PKCE signs in through the provider in your browser.\"\n onChange={(event) => changeDraft({ auth: event.target.value })}\n >\n <option value=\"headers\">Static headers</option>\n <option value=\"oauth\">OAuth 2.0 with PKCE</option>\n </select>\n </label>\n {draft.auth === 'oauth' && (\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">OAuth scopes (optional, comma-separated)</span>\n <input\n className=\"mcp-input\"\n value={draft.scopesText}\n disabled={snapshot.busy}\n placeholder=\"read write\"\n title=\"Optional. Leave empty when the provider defines no scopes \u2014 for example Context7. Request only scopes the provider grants.\"\n onChange={(event) => changeDraft({ scopesText: event.target.value })}\n />\n <span className=\"mcp-muted\">Leave empty unless the provider requires scopes.</span>\n </label>\n )}\n </div>\n {draft.auth === 'oauth' && (\n <p className=\"mcp-muted\">\n OAuth signs in through your browser. The Sign in button appears\n after you save this Server.\n </p>\n )}\n <SecretEditor field=\"headers\" rows={rows} onChange={changeRows} disabled={snapshot.busy} />\n </>\n )}\n\n <div className=\"mcp-field-row\">\n <label className=\"mcp-field\">\n <span className=\"mcp-label\">Idle timeout in minutes</span>\n <input\n className=\"mcp-input\"\n type=\"number\"\n min=\"0.1\"\n step=\"0.1\"\n value={draft.idleTimeoutMinutes}\n disabled={snapshot.busy}\n onChange={(event) => changeDraft({ idleTimeoutMinutes: event.target.value })}\n />\n </label>\n <div className=\"mcp-field\">\n <span className=\"mcp-label\">Call policy</span>\n <label className=\"mcp-checkbox\">\n <input\n type=\"checkbox\"\n checked={draft.autoAllow}\n disabled={snapshot.busy}\n onChange={(event) => changeDraft({ autoAllow: event.target.checked })}\n />\n Auto-allow calls from this Server\n </label>\n </div>\n </div>\n <label className=\"mcp-checkbox\">\n <input\n type=\"checkbox\"\n checked={draft.disabled}\n disabled={snapshot.busy}\n onChange={(event) => changeDraft({ disabled: event.target.checked })}\n />\n Disable this Server\n </label>\n <div className=\"mcp-actions\">\n <button\n type=\"submit\"\n className=\"mcp-button mcp-button-primary\"\n disabled={workspaceSourced || snapshot.busy || !dirty}\n >\n {snapshot.busy ? 'Saving\u2026' : 'Save Server'}\n </button>\n {dirty && !workspaceSourced && <span className=\"mcp-muted\">Unsaved changes</span>}\n {workspaceSourced && <span className=\"mcp-muted\">Read-only: defined by the workspace</span>}\n </div>\n </form>\n\n {typeof server.url === 'string' && server.auth === 'oauth' && (\n <OAuthSection controller={controller} snapshot={snapshot} name={name} />\n )}\n\n <div className=\"mcp-section\">\n <div>\n <h3 className=\"mcp-section-title\">Promotions</h3>\n <p className=\"mcp-muted\">\n Promote selected MCP tools as native tools named {name}__tool.\n </p>\n </div>\n {tools.length === 0 ? (\n <div className=\"mcp-warning\">\n No cached tools are available. Reconnect to discover this Server.\n </div>\n ) : (\n <div className=\"mcp-promotion-list\">\n {tools.map((tool) => {\n const checked = (server.promotedTools ?? []).includes(tool.name)\n return (\n <label className=\"mcp-promotion\" key={tool.name}>\n <input\n type=\"checkbox\"\n checked={checked}\n disabled={snapshot.busy}\n onChange={() => void controller.togglePromotion(name, tool.name)}\n />\n <span>\n <span className=\"mcp-promotion-name\">{tool.name}</span>\n {tool.description !== undefined && (\n <span className=\"mcp-promotion-description\">{tool.description}</span>\n )}\n </span>\n </label>\n )\n })}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport function McpSettingsPage({ controller }) {\n const snapshot = useSyncExternalStore(controller.subscribe, controller.getSnapshot)\n const [selected, setSelected] = useState()\n const [dialog, setDialog] = useState()\n const settings = snapshot.settings\n const servers = settings.value?.mcpServers ?? {}\n // Workspace-only Servers (absent from the global namespace) still surface:\n // the sidebar unions both sources and the detail renders read-only.\n const workspaceServers = snapshot.layers?.servers ?? {}\n const names = useMemo(\n () => [...new Set([...Object.keys(servers), ...Object.keys(workspaceServers)])].sort(),\n [servers, workspaceServers],\n )\n\n useEffect(() => controller.mount(), [controller])\n useEffect(() => {\n if (\n selected === undefined ||\n (!Object.hasOwn(servers, selected) && !Object.hasOwn(workspaceServers, selected))\n ) {\n setSelected(names[0])\n }\n }, [names, selected, servers, workspaceServers])\n\n if (settings.status === 'loading') {\n return <section className=\"mcp-settings\"><p className=\"mcp-muted\">Loading MCP Settings\u2026</p></section>\n }\n if (settings.status !== 'ready') {\n return (\n <section className=\"mcp-settings\">\n <h1 className=\"mcp-title\">MCP</h1>\n <div className=\"mcp-error\" role=\"alert\">\n {settings.error?.message ?? 'MCP Settings are unavailable.'}\n </div>\n </section>\n )\n }\n\n return (\n <section className=\"mcp-settings\">\n <div className=\"mcp-toolbar\">\n <div>\n <h1 className=\"mcp-title\">MCP</h1>\n <p className=\"mcp-intro\">Connect MCP Servers and choose how their tools reach the Agent.</p>\n </div>\n <div className=\"mcp-actions\">\n <button\n type=\"button\"\n className=\"mcp-button mcp-button-primary\"\n disabled={snapshot.busy || !settings.writable}\n onClick={() => setDialog('add')}\n >\n Add Server\n </button>\n </div>\n </div>\n\n {!settings.writable && (\n <div className=\"mcp-warning\">The active Settings Provider is read-only.</div>\n )}\n {snapshot.error !== undefined && (\n <div className=\"mcp-error\" role=\"alert\">{snapshot.error}</div>\n )}\n\n {names.length === 0 ? (\n <div className=\"mcp-empty\">\n <h2 className=\"mcp-card-title\">No MCP Servers</h2>\n <p className=\"mcp-muted\">\n Add a Server through its input fields, or paste an existing mcpServers JSON.\n </p>\n <div className=\"mcp-actions\">\n <button\n type=\"button\"\n className=\"mcp-button mcp-button-primary\"\n disabled={snapshot.busy || !settings.writable}\n onClick={() => setDialog('add')}\n >\n Add Server\n </button>\n </div>\n </div>\n ) : (\n <div className=\"mcp-layout\">\n <nav className=\"mcp-sidebar\" aria-label=\"MCP Servers\">\n {names.map((name) => {\n const status = statusFor(snapshot.overview, name)\n const workspaceSourced = serverSource(snapshot.layers, name) === 'workspace'\n return (\n <button\n type=\"button\"\n className=\"mcp-server-button\"\n aria-current={name === selected}\n key={name}\n onClick={() => setSelected(name)}\n >\n <span className={`mcp-status-dot ${statusClass(status.state)}`} />\n <span className=\"mcp-server-name\">{name}</span>\n {workspaceSourced && (\n <span className=\"mcp-badge mcp-badge-workspace\">workspace</span>\n )}\n <span className=\"mcp-server-count\">{status.toolCount}</span>\n </button>\n )\n })}\n </nav>\n {selected !== undefined && servers[selected] !== undefined && (\n <ServerDetail\n key={selected}\n controller={controller}\n snapshot={snapshot}\n name={selected}\n server={servers[selected]}\n />\n )}\n {selected !== undefined && servers[selected] === undefined && workspaceServers[selected] !== undefined && (\n <WorkspaceServerDetail\n key={selected}\n controller={controller}\n snapshot={snapshot}\n name={selected}\n server={workspaceServers[selected]}\n />\n )}\n </div>\n )}\n\n {dialog === 'add' && (\n <AddServerDialog controller={controller} busy={snapshot.busy} onClose={() => setDialog()} />\n )}\n </section>\n )\n}\n", "export const MCP_SETTINGS_NAMESPACE = 'mcp'\nexport const MCP_RPC_CHANNEL = '/mcp-adapter'\n\nconst SERVER_FIELDS = new Set([\n 'command',\n 'args',\n 'env',\n 'url',\n 'headers',\n 'auth',\n 'scopes',\n 'disabled',\n 'autoAllow',\n 'lifecycle',\n 'idleTimeoutMinutes',\n 'promotedTools',\n])\n\nfunction isRecord(value) {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction messageOf(error) {\n return error instanceof Error ? error.message : String(error)\n}\n\nfunction requireStringRecord(value, label) {\n if (value === undefined) return {}\n if (!isRecord(value)) throw new Error(`${label} must be an object of string values`)\n for (const [key, entry] of Object.entries(value)) {\n if (key.trim() === '' || typeof entry !== 'string') {\n throw new Error(`${label} must contain non-empty keys and string values`)\n }\n }\n return value\n}\n\nexport function normalizeServerConfig(name, input) {\n if (typeof name !== 'string' || name.trim() === '') {\n throw new Error('Server name cannot be empty')\n }\n if (!isRecord(input)) throw new Error(`Server ${JSON.stringify(name)} must be an object`)\n for (const key of Object.keys(input)) {\n if (!SERVER_FIELDS.has(key)) {\n throw new Error(`Server ${JSON.stringify(name)} has unknown field ${JSON.stringify(key)}`)\n }\n }\n\n const hasCommand = typeof input.command === 'string'\n const hasUrl = typeof input.url === 'string'\n if (hasCommand === hasUrl) {\n throw new Error(`Server ${JSON.stringify(name)} needs exactly one of command or url`)\n }\n if (hasCommand && input.command.trim() === '') {\n throw new Error(`Server ${JSON.stringify(name)} command cannot be empty`)\n }\n if (hasUrl) {\n let url\n try {\n url = new URL(input.url)\n } catch {\n throw new Error(`Server ${JSON.stringify(name)} URL must be absolute`)\n }\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new Error(`Server ${JSON.stringify(name)} URL must use HTTP or HTTPS`)\n }\n }\n\n const args = input.args ?? []\n if (!Array.isArray(args) || args.some((entry) => typeof entry !== 'string')) {\n throw new Error(`Server ${JSON.stringify(name)} args must be an array of strings`)\n }\n const env = requireStringRecord(input.env, `Server ${JSON.stringify(name)} env`)\n const headers = requireStringRecord(input.headers, `Server ${JSON.stringify(name)} headers`)\n if (hasCommand && Object.keys(headers).length > 0) {\n throw new Error(`Server ${JSON.stringify(name)} headers require HTTP transport`)\n }\n if (hasUrl && (args.length > 0 || Object.keys(env).length > 0)) {\n throw new Error(`Server ${JSON.stringify(name)} args and env require stdio transport`)\n }\n\n const idleTimeoutMinutes = input.idleTimeoutMinutes ?? 10\n if (!Number.isFinite(idleTimeoutMinutes) || idleTimeoutMinutes <= 0) {\n throw new Error(`Server ${JSON.stringify(name)} idle timeout must be positive`)\n }\n\n const auth = input.auth ?? 'headers'\n if (auth !== 'headers' && auth !== 'oauth') {\n throw new Error(`Server ${JSON.stringify(name)} auth must be \"headers\" or \"oauth\"`)\n }\n if (auth === 'oauth' && !hasUrl) {\n throw new Error(`Server ${JSON.stringify(name)} OAuth requires the HTTP Transport (url)`)\n }\n const scopes = input.scopes ?? []\n if (\n !Array.isArray(scopes) ||\n scopes.some((entry) => typeof entry !== 'string' || entry.trim() === '')\n ) {\n throw new Error(`Server ${JSON.stringify(name)} scopes must be an array of scope strings`)\n }\n if (scopes.length > 0 && auth !== 'oauth') {\n throw new Error(`Server ${JSON.stringify(name)} scopes require OAuth authentication`)\n }\n\n const promotedTools = input.promotedTools ?? []\n if (\n !Array.isArray(promotedTools) ||\n promotedTools.some((entry) => typeof entry !== 'string' || entry.trim() === '') ||\n new Set(promotedTools).size !== promotedTools.length\n ) {\n throw new Error(`Server ${JSON.stringify(name)} promotedTools must contain unique names`)\n }\n\n return {\n ...(hasCommand ? { command: input.command.trim(), args, env } : {\n url: input.url.trim(),\n headers,\n }),\n auth,\n scopes,\n disabled: input.disabled === true,\n autoAllow: input.autoAllow === true,\n lifecycle: 'lazy',\n idleTimeoutMinutes,\n promotedTools,\n }\n}\n\n/** Parse comma-separated OAuth scope text into a clean string array. */\nexport function parseScopes(text) {\n return String(text ?? '')\n .split(',')\n .map((entry) => entry.trim())\n .filter((entry) => entry !== '')\n}\n\nexport function parseMcpImport(text) {\n let parsed\n try {\n parsed = JSON.parse(text)\n } catch (error) {\n throw new Error(`Invalid JSON: ${messageOf(error)}`)\n }\n if (!isRecord(parsed) || !isRecord(parsed.mcpServers)) {\n throw new Error('Import JSON must contain an mcpServers object')\n }\n const servers = {}\n for (const [name, config] of Object.entries(parsed.mcpServers)) {\n servers[name] = normalizeServerConfig(name, config)\n }\n if (Object.keys(servers).length === 0) {\n throw new Error('Import JSON contains no Servers')\n }\n return servers\n}\n\nexport function parseArgs(text) {\n let parsed\n try {\n parsed = JSON.parse(text)\n } catch (error) {\n throw new Error(`Args must be a JSON array: ${messageOf(error)}`)\n }\n if (!Array.isArray(parsed) || parsed.some((entry) => typeof entry !== 'string')) {\n throw new Error('Args must be a JSON array of strings')\n }\n return parsed\n}\n\nexport function secretKeysFromView(view, serverName, field) {\n const namespace = view?.namespaces?.find((entry) => entry.ns === MCP_SETTINGS_NAMESPACE)\n if (namespace === undefined) return []\n return namespace.secrets\n .filter(\n (secret) =>\n secret.set === true &&\n secret.path.length === 4 &&\n secret.path[0] === 'mcpServers' &&\n secret.path[1] === serverName &&\n secret.path[2] === field,\n )\n .map((secret) => secret.path[3])\n .sort()\n}\n\nexport function secretRowOps(serverName, field, rows, existingKeys) {\n const unsetKeys = new Set()\n const sets = []\n const retained = new Set()\n for (const row of rows) {\n const originalKey = typeof row.originalKey === 'string' ? row.originalKey : undefined\n const key = typeof row.key === 'string' ? row.key.trim() : ''\n const value = typeof row.value === 'string' ? row.value : ''\n if (row.removed) {\n if (originalKey !== undefined) unsetKeys.add(originalKey)\n continue\n }\n if (key === '') throw new Error(`${field} keys cannot be empty`)\n if (retained.has(key)) throw new Error(`${field} key ${JSON.stringify(key)} is duplicated`)\n retained.add(key)\n if (originalKey !== undefined && originalKey !== key) {\n unsetKeys.add(originalKey)\n if (value === '') {\n throw new Error(`Enter a new value when renaming secret key ${JSON.stringify(originalKey)}`)\n }\n }\n if (value !== '') {\n sets.push({ op: 'set', path: ['mcpServers', serverName, field, key], value })\n } else if (originalKey === undefined && !existingKeys.includes(key)) {\n throw new Error(`Enter a value for new ${field} key ${JSON.stringify(key)}`)\n }\n }\n for (const key of existingKeys) {\n if (!rows.some((row) => row.originalKey === key || (!row.removed && row.key === key))) {\n unsetKeys.add(key)\n }\n }\n return [\n ...[...unsetKeys].map((key) => ({\n op: 'unset',\n path: ['mcpServers', serverName, field, key],\n })),\n ...sets,\n ]\n}\n\nfunction overviewEmpty() {\n return { status: { servers: [] }, catalog: { servers: [] } }\n}\n\n/**\n * Resolve the Config source of one Server from the workspace layer snapshot\n * delivered by the `layers` Connection RPC endpoint. Without a snapshot \u2014\n * for example an older Host \u2014 every Server reads as global.\n */\nexport function serverSource(layers, name) {\n return layers?.source?.[name] === 'workspace' ? 'workspace' : 'global'\n}\n\nexport class McpSettingsController {\n constructor({ scope, describe, settingsApi, rpc, pollIntervalMs = 3_000 }) {\n this.scope = scope\n this.describe = describe\n this.settingsApi = settingsApi\n this.rpc = rpc\n this.pollIntervalMs = pollIntervalMs\n this.listeners = new Set()\n this.overview = overviewEmpty()\n this.oauthStatuses = {}\n this.actionError = undefined\n this.overviewError = undefined\n this.layers = undefined\n this.pendingWrites = 0\n this.mounted = 0\n this.stopPoll = undefined\n this.loadingOverview = undefined\n this.loadingLayers = undefined\n this.tail = Promise.resolve()\n this.disposed = false\n this.unsubscribeScope = scope.subscribe(() => {\n this.publish()\n if (this.mounted > 0) {\n void this.loadOverview()\n void this.loadLayers()\n }\n })\n this.unsubscribeDescribe = describe.subscribe(() => this.publish())\n this.snapshot = this.projection()\n\n this.subscribe = (listener) => {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n this.getSnapshot = () => this.snapshot\n }\n\n projection() {\n return {\n settings: this.scope.getSnapshot(),\n settingsDocument: this.describe.getSnapshot(),\n overview: this.overview,\n layers: this.layers,\n oauthStatuses: this.oauthStatuses,\n error: this.actionError ?? this.overviewError,\n busy: this.pendingWrites > 0,\n }\n }\n\n publish() {\n this.snapshot = this.projection()\n for (const listener of this.listeners) listener()\n }\n\n mount() {\n if (this.disposed) return () => {}\n this.mounted += 1\n if (this.mounted === 1) {\n void this.describe.ensure().catch((error) => {\n this.actionError = `Could not load MCP Settings: ${messageOf(error)}`\n this.publish()\n })\n void this.loadOverview()\n void this.loadLayers()\n const id = setInterval(() => {\n void this.loadOverview()\n void this.loadLayers()\n }, this.pollIntervalMs)\n this.stopPoll = () => clearInterval(id)\n }\n return () => {\n this.mounted -= 1\n if (this.mounted === 0) {\n this.stopPoll?.()\n this.stopPoll = undefined\n }\n }\n }\n\n async loadOverview() {\n if (this.disposed) return\n if (this.loadingOverview !== undefined) return this.loadingOverview\n const request = (async () => {\n try {\n const result = await this.rpc('overview', {})\n if (!result.ok) throw new Error(result.error.message)\n this.overview = result.value\n this.overviewError = undefined\n await this.loadOauthStatuses()\n } catch (error) {\n this.overviewError = `Could not load MCP status: ${messageOf(error)}`\n } finally {\n this.loadingOverview = undefined\n this.publish()\n }\n })()\n this.loadingOverview = request\n return request\n }\n\n async loadLayers() {\n if (this.disposed) return\n if (this.loadingLayers !== undefined) return this.loadingLayers\n const request = (async () => {\n try {\n const result = await this.rpc('layers', {})\n if (!result.ok) throw new Error(result.error.message)\n this.layers = result.value\n } catch {\n // The layer snapshot is auxiliary; without it every Server reads as global.\n this.layers = undefined\n } finally {\n this.loadingLayers = undefined\n this.publish()\n }\n })()\n this.loadingLayers = request\n return request\n }\n\n /** Fetch `oauth-status` for every Server configured with OAuth. */\n async loadOauthStatuses() {\n if (this.disposed) return\n // Names come from the merged Config view: the global namespace plus the\n // sanitized workspace layer, so workspace-defined Servers are signable.\n const globalServers = this.scope.getSnapshot().value?.mcpServers ?? {}\n const workspaceServers = this.layers?.servers ?? {}\n const names = new Set()\n for (const [name, config] of Object.entries(globalServers)) {\n if (config?.auth === 'oauth' && typeof config.url === 'string') names.add(name)\n }\n for (const [name, config] of Object.entries(workspaceServers)) {\n if (config?.auth === 'oauth' && typeof config.url === 'string') names.add(name)\n }\n const statuses = {}\n await Promise.all(\n [...names].map(async (name) => {\n try {\n const result = await this.rpc('oauth-status', { server: name })\n if (result.ok) statuses[name] = result.value\n } catch {\n // A failed status probe leaves the Server out of the snapshot.\n }\n }),\n )\n this.oauthStatuses = statuses\n this.publish()\n }\n\n enqueue(label, operation) {\n this.pendingWrites += 1\n this.actionError = undefined\n this.publish()\n const run = this.tail.then(async () => {\n try {\n await operation()\n await Promise.all([this.loadOverview(), this.loadLayers()])\n return true\n } catch (error) {\n this.actionError = `${label}: ${messageOf(error)}`\n return false\n } finally {\n this.pendingWrites -= 1\n this.publish()\n }\n })\n this.tail = run.then(() => undefined)\n return run\n }\n\n async settingsWrite(method, input) {\n const revision = this.scope.getSnapshot().revision\n if (revision === undefined) throw new Error('Settings have not loaded yet')\n const response = await this.settingsApi[method]({\n ns: MCP_SETTINGS_NAMESPACE,\n ...input,\n expectedRevision: revision,\n })\n if (!response.result.ok) throw new Error(response.result.error.message)\n this.describe.acceptView(response.result.value)\n }\n\n addServer(name, config) {\n return this.enqueue('Could not add Server', async () => {\n const normalizedName = name.trim()\n const current = this.scope.getSnapshot().value?.mcpServers ?? {}\n if (Object.hasOwn(current, normalizedName)) {\n throw new Error(`Server ${JSON.stringify(normalizedName)} already exists`)\n }\n const server = normalizeServerConfig(normalizedName, config)\n await this.settingsWrite('update', {\n patch: { mcpServers: { [normalizedName]: server } },\n })\n })\n }\n\n importJson(text) {\n return this.enqueue('Could not import Servers', async () => {\n const servers = parseMcpImport(text)\n const current = this.scope.getSnapshot().value?.mcpServers ?? {}\n const replacesExisting = Object.keys(servers).some((name) => Object.hasOwn(current, name))\n if (!replacesExisting) {\n await this.settingsWrite('update', { patch: { mcpServers: servers } })\n return\n }\n await this.settingsWrite('mutate', {\n ops: Object.entries(servers).map(([name, server]) => ({\n op: 'set',\n path: ['mcpServers', name],\n value: server,\n })),\n })\n })\n }\n\n deleteServer(name) {\n return this.enqueue('Could not delete Server', () =>\n this.settingsWrite('mutate', {\n ops: [{ op: 'unset', path: ['mcpServers', name] }],\n }),\n )\n }\n\n setServerField(name, field, value) {\n return this.enqueue(`Could not update ${field}`, () =>\n this.settingsWrite('mutate', {\n ops: [{ op: 'set', path: ['mcpServers', name, field], value }],\n }),\n )\n }\n\n saveServer(name, draft, secretRows) {\n return this.enqueue('Could not save Server', async () => {\n const existing = this.scope.getSnapshot().value?.mcpServers?.[name]\n if (existing === undefined) throw new Error(`Server ${JSON.stringify(name)} no longer exists`)\n const args = draft.transport === 'stdio' ? parseArgs(draft.argsText) : []\n const scopes = draft.transport === 'http' ? parseScopes(draft.scopesText) : []\n const candidate = normalizeServerConfig(name, {\n ...(draft.transport === 'stdio'\n ? { command: draft.command, args, env: {} }\n : { url: draft.url, headers: {} }),\n auth: draft.transport === 'http' ? (draft.auth ?? 'headers') : 'headers',\n scopes,\n disabled: draft.disabled,\n autoAllow: draft.autoAllow,\n idleTimeoutMinutes: Number(draft.idleTimeoutMinutes),\n promotedTools: existing.promotedTools,\n })\n const ops = [\n { op: 'set', path: ['mcpServers', name, 'disabled'], value: candidate.disabled },\n { op: 'set', path: ['mcpServers', name, 'autoAllow'], value: candidate.autoAllow },\n {\n op: 'set',\n path: ['mcpServers', name, 'idleTimeoutMinutes'],\n value: candidate.idleTimeoutMinutes,\n },\n { op: 'set', path: ['mcpServers', name, 'auth'], value: candidate.auth },\n { op: 'set', path: ['mcpServers', name, 'scopes'], value: candidate.scopes },\n ]\n if (draft.transport === 'stdio') {\n ops.push(\n { op: 'set', path: ['mcpServers', name, 'command'], value: candidate.command },\n { op: 'set', path: ['mcpServers', name, 'args'], value: candidate.args },\n { op: 'unset', path: ['mcpServers', name, 'url'] },\n { op: 'unset', path: ['mcpServers', name, 'headers'] },\n ...secretRowOps(name, 'env', secretRows, secretKeysFromView(\n this.describe.getSnapshot().view,\n name,\n 'env',\n )),\n )\n } else {\n ops.push(\n { op: 'set', path: ['mcpServers', name, 'url'], value: candidate.url },\n { op: 'unset', path: ['mcpServers', name, 'command'] },\n { op: 'unset', path: ['mcpServers', name, 'args'] },\n { op: 'unset', path: ['mcpServers', name, 'env'] },\n ...secretRowOps(name, 'headers', secretRows, secretKeysFromView(\n this.describe.getSnapshot().view,\n name,\n 'headers',\n )),\n )\n }\n await this.settingsWrite('mutate', { ops })\n })\n }\n\n togglePromotion(name, toolName) {\n const tools = this.scope.getSnapshot().value?.mcpServers?.[name]?.promotedTools ?? []\n const next = tools.includes(toolName)\n ? tools.filter((entry) => entry !== toolName)\n : [...tools, toolName]\n return this.setServerField(name, 'promotedTools', next)\n }\n\n reconnect(name) {\n return this.enqueue('Could not reconnect Server', async () => {\n const result = await this.rpc('reconnect', { server: name })\n if (!result.ok) {\n await this.loadOverview()\n throw new Error(result.error.message)\n }\n this.overview = result.value\n })\n }\n\n /**\n * Start the OAuth flow for one Server. Resolves with the RPC value\n * (`{ authorizationUrl }`); the caller opens the URL in the browser.\n */\n async signIn(name) {\n this.pendingWrites += 1\n this.actionError = undefined\n this.publish()\n try {\n const result = await this.rpc('oauth-login', { server: name })\n if (!result.ok) throw new Error(result.error.message)\n return result.value\n } catch (error) {\n this.actionError = `Could not start sign-in: ${messageOf(error)}`\n return undefined\n } finally {\n this.pendingWrites -= 1\n this.publish()\n }\n }\n\n signOut(name) {\n return this.enqueue('Could not sign out', async () => {\n const result = await this.rpc('oauth-logout', { server: name })\n if (!result.ok) throw new Error(result.error.message)\n })\n }\n\n async dispose() {\n if (this.disposed) return\n this.disposed = true\n this.stopPoll?.()\n this.unsubscribeScope?.()\n this.unsubscribeDescribe?.()\n await this.tail\n this.listeners.clear()\n }\n}\n", "/**\n * Resolve the Settings write face across DSH harness generations.\n *\n * DSH 0.1.2-rc.1 removed the `connection` service's `api` face, moving the\n * settings write surface onto the `remote` service (its `settings` namespace is\n * mounted by the @deepseek-ai/dsh-api-remotes client bundle). The new face\n * takes positional `(ns, patch | ops, expectedRevision)` arguments and answers\n * a flat `{ ok, value | error }` envelope. DSH 0.1.1-rc.2 keeps the write\n * surface on `connection.api.settings`, with one request-object argument and a\n * `{ result: { ok, value | error } }` envelope.\n *\n * Both faces normalize to the controller's contract: `update` and `mutate`\n * take one request object and answer `{ result: { ok, value, error } }`, so\n * callers stay unaware of which harness generation is running. Prefer the\n * `remote` face when it exists: it is the only one DSH 0.1.2-rc.1 provides.\n */\nexport function createSettingsApi(ctx) {\n const remoteSettings = readRemoteSettings(ctx)\n if (remoteSettings !== undefined) return remoteSettingsApi(remoteSettings)\n\n const connectionSettings = ctx.connection?.api?.settings\n if (connectionSettings !== undefined) return connectionSettings\n\n throw new Error(\n 'No DSH settings write API: expected ctx.remote.settings (DSH 0.1.2+) '\n + 'or ctx.connection.api.settings (DSH 0.1.1-rc.2). Upgrade '\n + '@auggieteo/dsh-mcp-adapter to a release supporting this harness.',\n )\n}\n\n/**\n * Read the mounted `remote.settings` namespace across generations without\n * declaring it in `inject`.\n *\n * On DSH 0.1.2-rc.1 the namespace is a traced dotted service: reading it as\n * `ctx.remote.settings` makes cordis compose the `remote.settings` key and\n * throw `cannot get property \"remote.settings\" without inject` unless the\n * plugin declares that exact service. It must stay undeclared anyway \u2014 on\n * 0.1.1-rc.2 the namespace is never mounted, and a declared-but-missing\n * service keeps the plugin fiber from ever applying. `ctx.get` is cordis's\n * documented inject-free read: on 0.1.2-rc.1 it resolves the mounted\n * namespace through the root isolate; on 0.1.1-rc.2 it answers undefined,\n * leaving the `connection.api.settings` fallback reachable. The direct\n * `ctx.remote?.settings` read stays as the fallback for runner generations\n * that expose the face as a plain property (and for test doubles).\n */\nfunction readRemoteSettings(ctx) {\n if (typeof ctx.get === 'function') {\n try {\n const mounted = ctx.get('remote.settings')\n if (mounted !== undefined) return mounted\n } catch { /* fall through to the direct read */ }\n }\n try {\n return ctx.remote?.settings\n } catch { /* the governed dotted read on 0.1.2-rc.1 \u2014 ctx.get already covered it */ }\n return undefined\n}\n\n/** Wrap the 0.1.2-rc.1 `remote.settings` face in the controller's contract. */\nfunction remoteSettingsApi(remote) {\n return {\n async update({ ns, patch, expectedRevision }) {\n return { result: await remote.update(ns, patch, expectedRevision) }\n },\n async mutate({ ns, ops, expectedRevision }) {\n return { result: await remote.mutate(ns, ops, expectedRevision) }\n },\n }\n}\n", "export const MCP_SETTINGS_CSS = `\n.mcp-settings{width:100%;max-width:980px;min-width:0;container-type:inline-size;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:14px}\n.mcp-settings *{box-sizing:border-box}\n.mcp-title{margin:0;font-size:16px;line-height:24px;font-weight:600}\n.mcp-intro,.mcp-muted{margin:0;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}\n.mcp-toolbar,.mcp-actions,.mcp-row,.mcp-card-head{display:flex;align-items:center;gap:8px}\n.mcp-toolbar{justify-content:space-between;flex-wrap:wrap}\n.mcp-actions{flex-wrap:wrap}\n.mcp-button{height:32px;border:1px solid var(--dsw-alias-border-l2);border-radius:16px;background:transparent;color:var(--dsw-alias-label-primary);padding:0 13px;font:inherit;font-size:12px;cursor:pointer;transition:background .12s ease,border-color .12s ease,color .12s ease}\n.mcp-button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.mcp-button:active:not(:disabled){background:var(--dsw-alias-interactive-bg-active)}\n.mcp-button:disabled{cursor:not-allowed;opacity:.5}\n.mcp-button-primary{border-color:transparent;background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}\n.mcp-button-primary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}\n.mcp-button-danger{color:var(--dsw-alias-state-error-primary)}\n.mcp-button-danger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}\n.mcp-button:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}\n.mcp-error,.mcp-warning{border-radius:8px;padding:9px 11px;font-size:12px;line-height:18px}\n.mcp-error{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);color:var(--dsw-alias-state-error-primary)}\n.mcp-warning{background:var(--dsw-alias-state-warn-tertiary);color:var(--dsw-alias-state-warn-label)}\n.mcp-layout{display:grid;grid-template-columns:208px minmax(0,1fr);gap:14px;align-items:start;min-width:0}\n.mcp-card,.mcp-empty{border:1px solid var(--dsw-alias-border-l1);border-radius:12px;background:var(--dsw-alias-bg-layer-2)}\n.mcp-sidebar{display:flex;flex-direction:column;gap:2px;position:sticky;top:12px}\n.mcp-server-button{width:100%;border:0;border-radius:8px;background:transparent;color:var(--dsw-alias-label-secondary);padding:8px 10px;display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;gap:8px;align-items:center;text-align:left;cursor:pointer;font:inherit;transition:background .12s ease,color .12s ease}\n.mcp-server-button:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.mcp-server-button[aria-current=true]{background:var(--dsw-alias-button-ghost-active-fill);color:var(--dsw-alias-label-primary)}\n.mcp-server-name{min-width:0;overflow:hidden;text-overflow:ellipsis;font-size:13px;font-weight:500}\n.mcp-server-count{color:var(--dsw-alias-label-tertiary);font-size:11px}\n.mcp-status-dot{width:7px;height:7px;border-radius:50%;background:var(--dsw-alias-label-dimmed);flex:none}\n.mcp-status-connected{background:var(--dsw-alias-state-success-primary)}\n.mcp-status-connecting{background:var(--dsw-alias-state-warn-primary)}\n.mcp-status-dot.mcp-status-connecting{animation:mcp-pulse 1.2s ease-in-out infinite}\n@keyframes mcp-pulse{0%,100%{opacity:1}50%{opacity:.35}}\n.mcp-status-error{background:var(--dsw-alias-state-error-primary)}\n.mcp-status-disabled{background:var(--dsw-alias-label-dimmed)}\n.mcp-card{padding:16px;display:flex;flex-direction:column;gap:14px;min-width:0}\n.mcp-card-head{align-items:flex-start;flex-wrap:wrap}\n.mcp-card-head > div:first-child{flex:1 1 200px;min-width:0}\n.mcp-card-title{margin:0;font-size:15px;line-height:22px;font-weight:600;overflow-wrap:anywhere}\n.mcp-card-head .mcp-actions{margin-left:auto;justify-content:flex-end;flex:none}\n.mcp-badge{border:1px solid var(--dsw-alias-border-l2);border-radius:5px;padding:1px 7px;color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px;background:transparent}\n.mcp-badge.mcp-status-connected{color:var(--dsw-alias-state-success-primary);border-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 35%, transparent);background:transparent}\n.mcp-badge.mcp-status-connecting{color:var(--dsw-alias-state-warn-label);border-color:color-mix(in srgb, var(--dsw-alias-state-warn-primary) 35%, transparent);background:transparent}\n.mcp-badge.mcp-status-error{color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 35%, transparent);background:transparent}\n.mcp-badge.mcp-status-disabled{color:var(--dsw-alias-label-dimmed);background:transparent}\n.mcp-badge-workspace{color:var(--dsw-alias-state-business-primary);border-color:color-mix(in srgb, var(--dsw-alias-state-business-primary) 35%, transparent);background:transparent}\n.mcp-layer-notice{border:1px solid color-mix(in srgb, var(--dsw-alias-state-business-primary) 35%, transparent);border-radius:8px;padding:9px 11px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}\n.mcp-form{display:flex;flex-direction:column;gap:12px}\n.mcp-field{display:flex;flex-direction:column;gap:5px;min-width:0}\n.mcp-field-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px}\n.mcp-label{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:500;line-height:18px}\n.mcp-input,.mcp-select,.mcp-textarea{width:100%;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;outline:none;transition:border-color .12s ease,background .12s ease}\n.mcp-input,.mcp-select{height:34px;padding:0 10px}\n.mcp-textarea{min-height:76px;padding:8px 10px;resize:vertical;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:18px}\n.mcp-input:hover:not(:focus):not(:disabled),.mcp-select:hover:not(:focus):not(:disabled),.mcp-textarea:hover:not(:focus):not(:disabled){border-color:var(--dsw-alias-border-l3)}\n.mcp-input:focus,.mcp-select:focus,.mcp-textarea:focus{border-color:var(--dsw-alias-state-business-primary)}\n.mcp-input:read-only{background:transparent;border-color:transparent;color:var(--dsw-alias-label-tertiary)}\n.mcp-input::placeholder,.mcp-textarea::placeholder{color:var(--dsw-alias-label-dimmed)}\n.mcp-settings input[type=checkbox],.mcp-settings input[type=number]{accent-color:var(--dsw-alias-state-business-primary)}\n.mcp-checkbox{display:flex;align-items:flex-start;gap:8px;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px}\n.mcp-checkbox input{margin-top:3px}\n.mcp-section{border-top:1px solid var(--dsw-alias-border-l1);padding-top:12px;display:flex;flex-direction:column;gap:9px}\n.mcp-section-title{margin:0;font-size:12px;font-weight:600;line-height:18px;color:var(--dsw-alias-label-secondary)}\n.mcp-secret-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.2fr) auto;gap:7px;align-items:center}\n.mcp-secret-row > *{min-width:0}\n.mcp-promotion-list{display:flex;flex-direction:column;gap:2px;max-height:240px;overflow:auto}\n.mcp-promotion{border-radius:8px;padding:8px 10px;display:grid;grid-template-columns:auto minmax(0,1fr);gap:9px;align-items:start;cursor:pointer;transition:background .12s ease}\n.mcp-promotion:hover{background:var(--dsw-alias-interactive-bg-hover)}\n.mcp-promotion-name{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:var(--dsw-alias-label-primary);overflow-wrap:anywhere}\n.mcp-promotion-description{display:block;color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:17px}\n.mcp-empty{padding:30px 20px;text-align:center;display:flex;align-items:center;flex-direction:column;gap:10px}\n.mcp-overlay{position:fixed;inset:0;background:var(--dsw-alias-bg-mask-1);backdrop-filter:var(--dsw-mask-blur);display:flex;align-items:center;justify-content:center;padding:20px;z-index:1200;animation:mcp-fade .12s ease}\n.mcp-modal-card{width:min(560px,100%);max-height:min(760px,90vh);overflow:auto;padding:18px;display:flex;flex-direction:column;gap:13px;border:0;border-radius:14px;background:var(--dsw-alias-bg-layer-2);box-shadow:var(--dsw-elevation-prominent);animation:mcp-pop .16s ease}\n@keyframes mcp-fade{from{opacity:0}to{opacity:1}}\n@keyframes mcp-pop{from{opacity:0;transform:translateY(6px) scale(.98)}to{opacity:1;transform:none}}\n.mcp-modal-title{margin:0;font-size:15px;line-height:22px;font-weight:600}\n.mcp-dialog-tabs{display:inline-flex;gap:2px;align-self:flex-start;border:1px solid var(--dsw-alias-border-l2);border-radius:16px;padding:2px;background:var(--dsw-alias-bg-layer-3)}\n.mcp-dialog-tab{height:26px;border:0;border-radius:14px;background:transparent;color:var(--dsw-alias-label-secondary);padding:0 12px;font:inherit;font-size:12px;cursor:pointer;transition:background .12s ease,color .12s ease}\n.mcp-dialog-tab:hover:not(:disabled):not(.mcp-dialog-tab-active){color:var(--dsw-alias-label-primary)}\n.mcp-dialog-tab:disabled{cursor:not-allowed;opacity:.5}\n.mcp-dialog-tab-active{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}\n.mcp-dialog-tab:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}\n.mcp-confirm{border-radius:8px;padding:10px;display:flex;flex-direction:column;gap:8px;background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent)}\n@container (max-width:660px){.mcp-layout{grid-template-columns:minmax(0,1fr)}.mcp-sidebar{position:static;flex-direction:row;overflow-x:auto;padding-bottom:2px}.mcp-server-button{width:auto;flex:none;white-space:nowrap}}\n@container (max-width:480px){.mcp-field-row{grid-template-columns:minmax(0,1fr)}.mcp-secret-row{grid-template-columns:minmax(0,1fr) auto}.mcp-secret-row .mcp-input:first-child{grid-column:1 / -1}.mcp-card-head .mcp-actions{margin-left:0;width:100%}.mcp-toolbar{align-items:flex-start}}\n`\n\nexport function installMcpSettingsStyles() {\n const id = 'dsh-mcp-adapter-settings'\n const existing = document.querySelector(`style[data-plugin-css=\"${id}\"]`)\n if (existing !== null) return () => {}\n const style = document.createElement('style')\n style.dataset.pluginCss = id\n style.textContent = MCP_SETTINGS_CSS\n document.head.appendChild(style)\n return () => style.remove()\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAA0E;;;ACAnE,IAAM,yBAAyB;AAC/B,IAAM,kBAAkB;AAE/B,IAAM,gBAAgB,oBAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,SAAS,OAAO;AACvB,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,UAAU,OAAO;AACxB,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAEA,SAAS,oBAAoB,OAAO,OAAO;AACzC,MAAI,UAAU,OAAW,QAAO,CAAC;AACjC,MAAI,CAAC,SAAS,KAAK,EAAG,OAAM,IAAI,MAAM,GAAG,KAAK,qCAAqC;AACnF,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,IAAI,KAAK,MAAM,MAAM,OAAO,UAAU,UAAU;AAClD,YAAM,IAAI,MAAM,GAAG,KAAK,gDAAgD;AAAA,IAC1E;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,sBAAsB,MAAM,OAAO;AACjD,MAAI,OAAO,SAAS,YAAY,KAAK,KAAK,MAAM,IAAI;AAClD,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AACA,MAAI,CAAC,SAAS,KAAK,EAAG,OAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,oBAAoB;AACxF,aAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AACpC,QAAI,CAAC,cAAc,IAAI,GAAG,GAAG;AAC3B,YAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,sBAAsB,KAAK,UAAU,GAAG,CAAC,EAAE;AAAA,IAC3F;AAAA,EACF;AAEA,QAAM,aAAa,OAAO,MAAM,YAAY;AAC5C,QAAM,SAAS,OAAO,MAAM,QAAQ;AACpC,MAAI,eAAe,QAAQ;AACzB,UAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,sCAAsC;AAAA,EACtF;AACA,MAAI,cAAc,MAAM,QAAQ,KAAK,MAAM,IAAI;AAC7C,UAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,0BAA0B;AAAA,EAC1E;AACA,MAAI,QAAQ;AACV,QAAI;AACJ,QAAI;AACF,YAAM,IAAI,IAAI,MAAM,GAAG;AAAA,IACzB,QAAQ;AACN,YAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,uBAAuB;AAAA,IACvE;AACA,QAAI,IAAI,aAAa,WAAW,IAAI,aAAa,UAAU;AACzD,YAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,6BAA6B;AAAA,IAC7E;AAAA,EACF;AAEA,QAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,MAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,KAAK,KAAK,CAAC,UAAU,OAAO,UAAU,QAAQ,GAAG;AAC3E,UAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,mCAAmC;AAAA,EACnF;AACA,QAAM,MAAM,oBAAoB,MAAM,KAAK,UAAU,KAAK,UAAU,IAAI,CAAC,MAAM;AAC/E,QAAM,UAAU,oBAAoB,MAAM,SAAS,UAAU,KAAK,UAAU,IAAI,CAAC,UAAU;AAC3F,MAAI,cAAc,OAAO,KAAK,OAAO,EAAE,SAAS,GAAG;AACjD,UAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,iCAAiC;AAAA,EACjF;AACA,MAAI,WAAW,KAAK,SAAS,KAAK,OAAO,KAAK,GAAG,EAAE,SAAS,IAAI;AAC9D,UAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,uCAAuC;AAAA,EACvF;AAEA,QAAM,qBAAqB,MAAM,sBAAsB;AACvD,MAAI,CAAC,OAAO,SAAS,kBAAkB,KAAK,sBAAsB,GAAG;AACnE,UAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,gCAAgC;AAAA,EAChF;AAEA,QAAM,OAAO,MAAM,QAAQ;AAC3B,MAAI,SAAS,aAAa,SAAS,SAAS;AAC1C,UAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,oCAAoC;AAAA,EACpF;AACA,MAAI,SAAS,WAAW,CAAC,QAAQ;AAC/B,UAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,0CAA0C;AAAA,EAC1F;AACA,QAAM,SAAS,MAAM,UAAU,CAAC;AAChC,MACE,CAAC,MAAM,QAAQ,MAAM,KACrB,OAAO,KAAK,CAAC,UAAU,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,EAAE,GACvE;AACA,UAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,2CAA2C;AAAA,EAC3F;AACA,MAAI,OAAO,SAAS,KAAK,SAAS,SAAS;AACzC,UAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,sCAAsC;AAAA,EACtF;AAEA,QAAM,gBAAgB,MAAM,iBAAiB,CAAC;AAC9C,MACE,CAAC,MAAM,QAAQ,aAAa,KAC5B,cAAc,KAAK,CAAC,UAAU,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,EAAE,KAC9E,IAAI,IAAI,aAAa,EAAE,SAAS,cAAc,QAC9C;AACA,UAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,0CAA0C;AAAA,EAC1F;AAEA,SAAO;AAAA,IACL,GAAI,aAAa,EAAE,SAAS,MAAM,QAAQ,KAAK,GAAG,MAAM,IAAI,IAAI;AAAA,MAC9D,KAAK,MAAM,IAAI,KAAK;AAAA,MACpB;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,MAAM,aAAa;AAAA,IAC7B,WAAW,MAAM,cAAc;AAAA,IAC/B,WAAW;AAAA,IACX;AAAA,IACA;AAAA,EACF;AACF;AAGO,SAAS,YAAY,MAAM;AAChC,SAAO,OAAO,QAAQ,EAAE,EACrB,MAAM,GAAG,EACT,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAC3B,OAAO,CAAC,UAAU,UAAU,EAAE;AACnC;AAEO,SAAS,eAAe,MAAM;AACnC,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,IAAI;AAAA,EAC1B,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,iBAAiB,UAAU,KAAK,CAAC,EAAE;AAAA,EACrD;AACA,MAAI,CAAC,SAAS,MAAM,KAAK,CAAC,SAAS,OAAO,UAAU,GAAG;AACrD,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AACA,QAAM,UAAU,CAAC;AACjB,aAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,OAAO,UAAU,GAAG;AAC9D,YAAQ,IAAI,IAAI,sBAAsB,MAAM,MAAM;AAAA,EACpD;AACA,MAAI,OAAO,KAAK,OAAO,EAAE,WAAW,GAAG;AACrC,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AACA,SAAO;AACT;AAEO,SAAS,UAAU,MAAM;AAC9B,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,IAAI;AAAA,EAC1B,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,8BAA8B,UAAU,KAAK,CAAC,EAAE;AAAA,EAClE;AACA,MAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,OAAO,KAAK,CAAC,UAAU,OAAO,UAAU,QAAQ,GAAG;AAC/E,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AACA,SAAO;AACT;AAEO,SAAS,mBAAmB,MAAM,YAAY,OAAO;AAC1D,QAAM,YAAY,MAAM,YAAY,KAAK,CAAC,UAAU,MAAM,OAAO,sBAAsB;AACvF,MAAI,cAAc,OAAW,QAAO,CAAC;AACrC,SAAO,UAAU,QACd;AAAA,IACC,CAAC,WACC,OAAO,QAAQ,QACf,OAAO,KAAK,WAAW,KACvB,OAAO,KAAK,CAAC,MAAM,gBACnB,OAAO,KAAK,CAAC,MAAM,cACnB,OAAO,KAAK,CAAC,MAAM;AAAA,EACvB,EACC,IAAI,CAAC,WAAW,OAAO,KAAK,CAAC,CAAC,EAC9B,KAAK;AACV;AAEO,SAAS,aAAa,YAAY,OAAO,MAAM,cAAc;AAClE,QAAM,YAAY,oBAAI,IAAI;AAC1B,QAAM,OAAO,CAAC;AACd,QAAM,WAAW,oBAAI,IAAI;AACzB,aAAW,OAAO,MAAM;AACtB,UAAM,cAAc,OAAO,IAAI,gBAAgB,WAAW,IAAI,cAAc;AAC5E,UAAM,MAAM,OAAO,IAAI,QAAQ,WAAW,IAAI,IAAI,KAAK,IAAI;AAC3D,UAAM,QAAQ,OAAO,IAAI,UAAU,WAAW,IAAI,QAAQ;AAC1D,QAAI,IAAI,SAAS;AACf,UAAI,gBAAgB,OAAW,WAAU,IAAI,WAAW;AACxD;AAAA,IACF;AACA,QAAI,QAAQ,GAAI,OAAM,IAAI,MAAM,GAAG,KAAK,uBAAuB;AAC/D,QAAI,SAAS,IAAI,GAAG,EAAG,OAAM,IAAI,MAAM,GAAG,KAAK,QAAQ,KAAK,UAAU,GAAG,CAAC,gBAAgB;AAC1F,aAAS,IAAI,GAAG;AAChB,QAAI,gBAAgB,UAAa,gBAAgB,KAAK;AACpD,gBAAU,IAAI,WAAW;AACzB,UAAI,UAAU,IAAI;AAChB,cAAM,IAAI,MAAM,8CAA8C,KAAK,UAAU,WAAW,CAAC,EAAE;AAAA,MAC7F;AAAA,IACF;AACA,QAAI,UAAU,IAAI;AAChB,WAAK,KAAK,EAAE,IAAI,OAAO,MAAM,CAAC,cAAc,YAAY,OAAO,GAAG,GAAG,MAAM,CAAC;AAAA,IAC9E,WAAW,gBAAgB,UAAa,CAAC,aAAa,SAAS,GAAG,GAAG;AACnE,YAAM,IAAI,MAAM,yBAAyB,KAAK,QAAQ,KAAK,UAAU,GAAG,CAAC,EAAE;AAAA,IAC7E;AAAA,EACF;AACA,aAAW,OAAO,cAAc;AAC9B,QAAI,CAAC,KAAK,KAAK,CAAC,QAAQ,IAAI,gBAAgB,OAAQ,CAAC,IAAI,WAAW,IAAI,QAAQ,GAAI,GAAG;AACrF,gBAAU,IAAI,GAAG;AAAA,IACnB;AAAA,EACF;AACA,SAAO;AAAA,IACL,GAAG,CAAC,GAAG,SAAS,EAAE,IAAI,CAAC,SAAS;AAAA,MAC9B,IAAI;AAAA,MACJ,MAAM,CAAC,cAAc,YAAY,OAAO,GAAG;AAAA,IAC7C,EAAE;AAAA,IACF,GAAG;AAAA,EACL;AACF;AAEA,SAAS,gBAAgB;AACvB,SAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,GAAG,SAAS,EAAE,SAAS,CAAC,EAAE,EAAE;AAC7D;AAOO,SAAS,aAAa,QAAQ,MAAM;AACzC,SAAO,QAAQ,SAAS,IAAI,MAAM,cAAc,cAAc;AAChE;AAEO,IAAM,wBAAN,MAA4B;AAAA,EACjC,YAAY,EAAE,OAAO,UAAU,aAAa,KAAK,iBAAiB,IAAM,GAAG;AACzE,SAAK,QAAQ;AACb,SAAK,WAAW;AAChB,SAAK,cAAc;AACnB,SAAK,MAAM;AACX,SAAK,iBAAiB;AACtB,SAAK,YAAY,oBAAI,IAAI;AACzB,SAAK,WAAW,cAAc;AAC9B,SAAK,gBAAgB,CAAC;AACtB,SAAK,cAAc;AACnB,SAAK,gBAAgB;AACrB,SAAK,SAAS;AACd,SAAK,gBAAgB;AACrB,SAAK,UAAU;AACf,SAAK,WAAW;AAChB,SAAK,kBAAkB;AACvB,SAAK,gBAAgB;AACrB,SAAK,OAAO,QAAQ,QAAQ;AAC5B,SAAK,WAAW;AAChB,SAAK,mBAAmB,MAAM,UAAU,MAAM;AAC5C,WAAK,QAAQ;AACb,UAAI,KAAK,UAAU,GAAG;AACpB,aAAK,KAAK,aAAa;AACvB,aAAK,KAAK,WAAW;AAAA,MACvB;AAAA,IACF,CAAC;AACD,SAAK,sBAAsB,SAAS,UAAU,MAAM,KAAK,QAAQ,CAAC;AAClE,SAAK,WAAW,KAAK,WAAW;AAEhC,SAAK,YAAY,CAAC,aAAa;AAC7B,WAAK,UAAU,IAAI,QAAQ;AAC3B,aAAO,MAAM,KAAK,UAAU,OAAO,QAAQ;AAAA,IAC7C;AACA,SAAK,cAAc,MAAM,KAAK;AAAA,EAChC;AAAA,EAEA,aAAa;AACX,WAAO;AAAA,MACL,UAAU,KAAK,MAAM,YAAY;AAAA,MACjC,kBAAkB,KAAK,SAAS,YAAY;AAAA,MAC5C,UAAU,KAAK;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,eAAe,KAAK;AAAA,MACpB,OAAO,KAAK,eAAe,KAAK;AAAA,MAChC,MAAM,KAAK,gBAAgB;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,UAAU;AACR,SAAK,WAAW,KAAK,WAAW;AAChC,eAAW,YAAY,KAAK,UAAW,UAAS;AAAA,EAClD;AAAA,EAEA,QAAQ;AACN,QAAI,KAAK,SAAU,QAAO,MAAM;AAAA,IAAC;AACjC,SAAK,WAAW;AAChB,QAAI,KAAK,YAAY,GAAG;AACtB,WAAK,KAAK,SAAS,OAAO,EAAE,MAAM,CAAC,UAAU;AAC3C,aAAK,cAAc,gCAAgC,UAAU,KAAK,CAAC;AACnE,aAAK,QAAQ;AAAA,MACf,CAAC;AACD,WAAK,KAAK,aAAa;AACvB,WAAK,KAAK,WAAW;AACrB,YAAM,KAAK,YAAY,MAAM;AAC3B,aAAK,KAAK,aAAa;AACvB,aAAK,KAAK,WAAW;AAAA,MACvB,GAAG,KAAK,cAAc;AACtB,WAAK,WAAW,MAAM,cAAc,EAAE;AAAA,IACxC;AACA,WAAO,MAAM;AACX,WAAK,WAAW;AAChB,UAAI,KAAK,YAAY,GAAG;AACtB,aAAK,WAAW;AAChB,aAAK,WAAW;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,eAAe;AACnB,QAAI,KAAK,SAAU;AACnB,QAAI,KAAK,oBAAoB,OAAW,QAAO,KAAK;AACpD,UAAM,WAAW,YAAY;AAC3B,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,IAAI,YAAY,CAAC,CAAC;AAC5C,YAAI,CAAC,OAAO,GAAI,OAAM,IAAI,MAAM,OAAO,MAAM,OAAO;AACpD,aAAK,WAAW,OAAO;AACvB,aAAK,gBAAgB;AACrB,cAAM,KAAK,kBAAkB;AAAA,MAC/B,SAAS,OAAO;AACd,aAAK,gBAAgB,8BAA8B,UAAU,KAAK,CAAC;AAAA,MACrE,UAAE;AACA,aAAK,kBAAkB;AACvB,aAAK,QAAQ;AAAA,MACf;AAAA,IACF,GAAG;AACH,SAAK,kBAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aAAa;AACjB,QAAI,KAAK,SAAU;AACnB,QAAI,KAAK,kBAAkB,OAAW,QAAO,KAAK;AAClD,UAAM,WAAW,YAAY;AAC3B,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,IAAI,UAAU,CAAC,CAAC;AAC1C,YAAI,CAAC,OAAO,GAAI,OAAM,IAAI,MAAM,OAAO,MAAM,OAAO;AACpD,aAAK,SAAS,OAAO;AAAA,MACvB,QAAQ;AAEN,aAAK,SAAS;AAAA,MAChB,UAAE;AACA,aAAK,gBAAgB;AACrB,aAAK,QAAQ;AAAA,MACf;AAAA,IACF,GAAG;AACH,SAAK,gBAAgB;AACrB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,oBAAoB;AACxB,QAAI,KAAK,SAAU;AAGnB,UAAM,gBAAgB,KAAK,MAAM,YAAY,EAAE,OAAO,cAAc,CAAC;AACrE,UAAM,mBAAmB,KAAK,QAAQ,WAAW,CAAC;AAClD,UAAM,QAAQ,oBAAI,IAAI;AACtB,eAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,aAAa,GAAG;AAC1D,UAAI,QAAQ,SAAS,WAAW,OAAO,OAAO,QAAQ,SAAU,OAAM,IAAI,IAAI;AAAA,IAChF;AACA,eAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,gBAAgB,GAAG;AAC7D,UAAI,QAAQ,SAAS,WAAW,OAAO,OAAO,QAAQ,SAAU,OAAM,IAAI,IAAI;AAAA,IAChF;AACA,UAAM,WAAW,CAAC;AAClB,UAAM,QAAQ;AAAA,MACZ,CAAC,GAAG,KAAK,EAAE,IAAI,OAAO,SAAS;AAC7B,YAAI;AACF,gBAAM,SAAS,MAAM,KAAK,IAAI,gBAAgB,EAAE,QAAQ,KAAK,CAAC;AAC9D,cAAI,OAAO,GAAI,UAAS,IAAI,IAAI,OAAO;AAAA,QACzC,QAAQ;AAAA,QAER;AAAA,MACF,CAAC;AAAA,IACH;AACA,SAAK,gBAAgB;AACrB,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,QAAQ,OAAO,WAAW;AACxB,SAAK,iBAAiB;AACtB,SAAK,cAAc;AACnB,SAAK,QAAQ;AACb,UAAM,MAAM,KAAK,KAAK,KAAK,YAAY;AACrC,UAAI;AACF,cAAM,UAAU;AAChB,cAAM,QAAQ,IAAI,CAAC,KAAK,aAAa,GAAG,KAAK,WAAW,CAAC,CAAC;AAC1D,eAAO;AAAA,MACT,SAAS,OAAO;AACd,aAAK,cAAc,GAAG,KAAK,KAAK,UAAU,KAAK,CAAC;AAChD,eAAO;AAAA,MACT,UAAE;AACA,aAAK,iBAAiB;AACtB,aAAK,QAAQ;AAAA,MACf;AAAA,IACF,CAAC;AACD,SAAK,OAAO,IAAI,KAAK,MAAM,MAAS;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,QAAQ,OAAO;AACjC,UAAM,WAAW,KAAK,MAAM,YAAY,EAAE;AAC1C,QAAI,aAAa,OAAW,OAAM,IAAI,MAAM,8BAA8B;AAC1E,UAAM,WAAW,MAAM,KAAK,YAAY,MAAM,EAAE;AAAA,MAC9C,IAAI;AAAA,MACJ,GAAG;AAAA,MACH,kBAAkB;AAAA,IACpB,CAAC;AACD,QAAI,CAAC,SAAS,OAAO,GAAI,OAAM,IAAI,MAAM,SAAS,OAAO,MAAM,OAAO;AACtE,SAAK,SAAS,WAAW,SAAS,OAAO,KAAK;AAAA,EAChD;AAAA,EAEA,UAAU,MAAM,QAAQ;AACtB,WAAO,KAAK,QAAQ,wBAAwB,YAAY;AACtD,YAAM,iBAAiB,KAAK,KAAK;AACjC,YAAM,UAAU,KAAK,MAAM,YAAY,EAAE,OAAO,cAAc,CAAC;AAC/D,UAAI,OAAO,OAAO,SAAS,cAAc,GAAG;AAC1C,cAAM,IAAI,MAAM,UAAU,KAAK,UAAU,cAAc,CAAC,iBAAiB;AAAA,MAC3E;AACA,YAAM,SAAS,sBAAsB,gBAAgB,MAAM;AAC3D,YAAM,KAAK,cAAc,UAAU;AAAA,QACjC,OAAO,EAAE,YAAY,EAAE,CAAC,cAAc,GAAG,OAAO,EAAE;AAAA,MACpD,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,WAAW,MAAM;AACf,WAAO,KAAK,QAAQ,4BAA4B,YAAY;AAC1D,YAAM,UAAU,eAAe,IAAI;AACnC,YAAM,UAAU,KAAK,MAAM,YAAY,EAAE,OAAO,cAAc,CAAC;AAC/D,YAAM,mBAAmB,OAAO,KAAK,OAAO,EAAE,KAAK,CAAC,SAAS,OAAO,OAAO,SAAS,IAAI,CAAC;AACzF,UAAI,CAAC,kBAAkB;AACrB,cAAM,KAAK,cAAc,UAAU,EAAE,OAAO,EAAE,YAAY,QAAQ,EAAE,CAAC;AACrE;AAAA,MACF;AACA,YAAM,KAAK,cAAc,UAAU;AAAA,QACjC,KAAK,OAAO,QAAQ,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,MAAM,OAAO;AAAA,UACpD,IAAI;AAAA,UACJ,MAAM,CAAC,cAAc,IAAI;AAAA,UACzB,OAAO;AAAA,QACT,EAAE;AAAA,MACJ,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,aAAa,MAAM;AACjB,WAAO,KAAK;AAAA,MAAQ;AAAA,MAA2B,MAC7C,KAAK,cAAc,UAAU;AAAA,QAC3B,KAAK,CAAC,EAAE,IAAI,SAAS,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC;AAAA,MACnD,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,eAAe,MAAM,OAAO,OAAO;AACjC,WAAO,KAAK;AAAA,MAAQ,oBAAoB,KAAK;AAAA,MAAI,MAC/C,KAAK,cAAc,UAAU;AAAA,QAC3B,KAAK,CAAC,EAAE,IAAI,OAAO,MAAM,CAAC,cAAc,MAAM,KAAK,GAAG,MAAM,CAAC;AAAA,MAC/D,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,WAAW,MAAM,OAAOA,aAAY;AAClC,WAAO,KAAK,QAAQ,yBAAyB,YAAY;AACvD,YAAM,WAAW,KAAK,MAAM,YAAY,EAAE,OAAO,aAAa,IAAI;AAClE,UAAI,aAAa,OAAW,OAAM,IAAI,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,mBAAmB;AAC7F,YAAM,OAAO,MAAM,cAAc,UAAU,UAAU,MAAM,QAAQ,IAAI,CAAC;AACxE,YAAM,SAAS,MAAM,cAAc,SAAS,YAAY,MAAM,UAAU,IAAI,CAAC;AAC7E,YAAM,YAAY,sBAAsB,MAAM;AAAA,QAC5C,GAAI,MAAM,cAAc,UACpB,EAAE,SAAS,MAAM,SAAS,MAAM,KAAK,CAAC,EAAE,IACxC,EAAE,KAAK,MAAM,KAAK,SAAS,CAAC,EAAE;AAAA,QAClC,MAAM,MAAM,cAAc,SAAU,MAAM,QAAQ,YAAa;AAAA,QAC/D;AAAA,QACA,UAAU,MAAM;AAAA,QAChB,WAAW,MAAM;AAAA,QACjB,oBAAoB,OAAO,MAAM,kBAAkB;AAAA,QACnD,eAAe,SAAS;AAAA,MAC1B,CAAC;AACD,YAAM,MAAM;AAAA,QACV,EAAE,IAAI,OAAO,MAAM,CAAC,cAAc,MAAM,UAAU,GAAG,OAAO,UAAU,SAAS;AAAA,QAC/E,EAAE,IAAI,OAAO,MAAM,CAAC,cAAc,MAAM,WAAW,GAAG,OAAO,UAAU,UAAU;AAAA,QACjF;AAAA,UACE,IAAI;AAAA,UACJ,MAAM,CAAC,cAAc,MAAM,oBAAoB;AAAA,UAC/C,OAAO,UAAU;AAAA,QACnB;AAAA,QACA,EAAE,IAAI,OAAO,MAAM,CAAC,cAAc,MAAM,MAAM,GAAG,OAAO,UAAU,KAAK;AAAA,QACvE,EAAE,IAAI,OAAO,MAAM,CAAC,cAAc,MAAM,QAAQ,GAAG,OAAO,UAAU,OAAO;AAAA,MAC7E;AACA,UAAI,MAAM,cAAc,SAAS;AAC/B,YAAI;AAAA,UACF,EAAE,IAAI,OAAO,MAAM,CAAC,cAAc,MAAM,SAAS,GAAG,OAAO,UAAU,QAAQ;AAAA,UAC7E,EAAE,IAAI,OAAO,MAAM,CAAC,cAAc,MAAM,MAAM,GAAG,OAAO,UAAU,KAAK;AAAA,UACvE,EAAE,IAAI,SAAS,MAAM,CAAC,cAAc,MAAM,KAAK,EAAE;AAAA,UACjD,EAAE,IAAI,SAAS,MAAM,CAAC,cAAc,MAAM,SAAS,EAAE;AAAA,UACrD,GAAG,aAAa,MAAM,OAAOA,aAAY;AAAA,YACvC,KAAK,SAAS,YAAY,EAAE;AAAA,YAC5B;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,YAAI;AAAA,UACF,EAAE,IAAI,OAAO,MAAM,CAAC,cAAc,MAAM,KAAK,GAAG,OAAO,UAAU,IAAI;AAAA,UACrE,EAAE,IAAI,SAAS,MAAM,CAAC,cAAc,MAAM,SAAS,EAAE;AAAA,UACrD,EAAE,IAAI,SAAS,MAAM,CAAC,cAAc,MAAM,MAAM,EAAE;AAAA,UAClD,EAAE,IAAI,SAAS,MAAM,CAAC,cAAc,MAAM,KAAK,EAAE;AAAA,UACjD,GAAG,aAAa,MAAM,WAAWA,aAAY;AAAA,YAC3C,KAAK,SAAS,YAAY,EAAE;AAAA,YAC5B;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AACA,YAAM,KAAK,cAAc,UAAU,EAAE,IAAI,CAAC;AAAA,IAC5C,CAAC;AAAA,EACH;AAAA,EAEA,gBAAgB,MAAM,UAAU;AAC9B,UAAM,QAAQ,KAAK,MAAM,YAAY,EAAE,OAAO,aAAa,IAAI,GAAG,iBAAiB,CAAC;AACpF,UAAM,OAAO,MAAM,SAAS,QAAQ,IAChC,MAAM,OAAO,CAAC,UAAU,UAAU,QAAQ,IAC1C,CAAC,GAAG,OAAO,QAAQ;AACvB,WAAO,KAAK,eAAe,MAAM,iBAAiB,IAAI;AAAA,EACxD;AAAA,EAEA,UAAU,MAAM;AACd,WAAO,KAAK,QAAQ,8BAA8B,YAAY;AAC5D,YAAM,SAAS,MAAM,KAAK,IAAI,aAAa,EAAE,QAAQ,KAAK,CAAC;AAC3D,UAAI,CAAC,OAAO,IAAI;AACd,cAAM,KAAK,aAAa;AACxB,cAAM,IAAI,MAAM,OAAO,MAAM,OAAO;AAAA,MACtC;AACA,WAAK,WAAW,OAAO;AAAA,IACzB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,MAAM;AACjB,SAAK,iBAAiB;AACtB,SAAK,cAAc;AACnB,SAAK,QAAQ;AACb,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,IAAI,eAAe,EAAE,QAAQ,KAAK,CAAC;AAC7D,UAAI,CAAC,OAAO,GAAI,OAAM,IAAI,MAAM,OAAO,MAAM,OAAO;AACpD,aAAO,OAAO;AAAA,IAChB,SAAS,OAAO;AACd,WAAK,cAAc,4BAA4B,UAAU,KAAK,CAAC;AAC/D,aAAO;AAAA,IACT,UAAE;AACA,WAAK,iBAAiB;AACtB,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA,EAEA,QAAQ,MAAM;AACZ,WAAO,KAAK,QAAQ,sBAAsB,YAAY;AACpD,YAAM,SAAS,MAAM,KAAK,IAAI,gBAAgB,EAAE,QAAQ,KAAK,CAAC;AAC9D,UAAI,CAAC,OAAO,GAAI,OAAM,IAAI,MAAM,OAAO,MAAM,OAAO;AAAA,IACtD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAU;AACd,QAAI,KAAK,SAAU;AACnB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,mBAAmB;AACxB,SAAK,sBAAsB;AAC3B,UAAM,KAAK;AACX,SAAK,UAAU,MAAM;AAAA,EACvB;AACF;;;ADzhBM;AAlCN,SAAS,UAAU,UAAU,MAAM;AACjC,SAAO,SAAS,OAAO,QAAQ,KAAK,CAAC,UAAU,MAAM,SAAS,IAAI,KAAK;AAAA,IACrE;AAAA,IACA,OAAO;AAAA,IACP,WAAW;AAAA,EACb;AACF;AAEA,SAAS,WAAW,UAAU,MAAM;AAClC,SAAO,SAAS,QAAQ,QAAQ,KAAK,CAAC,UAAU,MAAM,SAAS,IAAI,GAAG,SAAS,CAAC;AAClF;AAEA,SAAS,YAAY,OAAO;AAC1B,MAAI,UAAU,YAAa,QAAO;AAClC,MAAI,UAAU,aAAc,QAAO;AACnC,MAAI,UAAU,QAAS,QAAO;AAC9B,MAAI,UAAU,WAAY,QAAO;AACjC,SAAO;AACT;AAEA,SAAS,WAAW,MAAM;AACxB,SAAO,KAAK,IAAI,CAAC,SAAS,EAAE,aAAa,KAAK,KAAK,OAAO,GAAG,EAAE;AACjE;AAEA,SAAS,aAAa,EAAE,OAAO,MAAM,UAAU,SAAS,GAAG;AACzD,QAAM,QAAQ,UAAU,QAAQ,0BAA0B;AAC1D,QAAM,MAAM,MAAM,SAAS,CAAC,GAAG,MAAM,EAAE,KAAK,IAAI,OAAO,GAAG,CAAC,CAAC;AAC5D,QAAM,SAAS,CAAC,OAAO,UAAU;AAC/B,aAAS,KAAK,IAAI,CAAC,KAAK,aAAa,aAAa,QAAQ,EAAE,GAAG,KAAK,GAAG,MAAM,IAAI,GAAG,CAAC;AAAA,EACvF;AACA,QAAM,SAAS,CAAC,UAAU,SAAS,KAAK,OAAO,CAAC,GAAG,aAAa,aAAa,KAAK,CAAC;AAEnF,SACE,6CAAC,SAAI,WAAU,eACb;AAAA,iDAAC,SACC;AAAA,kDAAC,QAAG,WAAU,qBAAqB,iBAAM;AAAA,MACzC,4CAAC,OAAE,WAAU,aAAY,qFAEzB;AAAA,OACF;AAAA,IACC,KAAK,IAAI,CAAC,KAAK,UACd,6CAAC,SAAI,WAAU,kBACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,cAAY,GAAG,KAAK,QAAQ,QAAQ,CAAC;AAAA,UACrC,aAAa,UAAU,QAAQ,cAAc;AAAA,UAC7C,OAAO,IAAI;AAAA,UACX;AAAA,UACA,UAAU,CAAC,UAAU,OAAO,OAAO,EAAE,KAAK,MAAM,OAAO,MAAM,CAAC;AAAA;AAAA,MAChE;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,cAAY,GAAG,KAAK,UAAU,QAAQ,CAAC;AAAA,UACvC,MAAM,UAAU,QAAQ,aAAa;AAAA,UACrC,cAAa;AAAA,UACb,aAAa,IAAI,gBAAgB,SAAY,UAAU;AAAA,UACvD,OAAO,IAAI;AAAA,UACX;AAAA,UACA,UAAU,CAAC,UAAU,OAAO,OAAO,EAAE,OAAO,MAAM,OAAO,MAAM,CAAC;AAAA;AAAA,MAClE;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV;AAAA,UACA,SAAS,MAAM,OAAO,KAAK;AAAA,UAC5B;AAAA;AAAA,MAED;AAAA,SA1BmC,GAAG,IAAI,eAAe,KAAK,IAAI,KAAK,EA2BzE,CACD;AAAA,IACD,4CAAC,SACC,uDAAC,YAAO,MAAK,UAAS,WAAU,cAAa,UAAoB,SAAS,KAAK;AAAA;AAAA,MACxE,UAAU,QAAQ,aAAa;AAAA,OACtC,GACF;AAAA,KACF;AAEJ;AAEA,SAAS,eAAe,SAAS;AAC/B,8BAAU,MAAM;AACd,UAAM,QAAQ,CAAC,UAAU;AACvB,UAAI,MAAM,QAAQ,SAAU,SAAQ;AAAA,IACtC;AACA,WAAO,iBAAiB,WAAW,KAAK;AACxC,WAAO,MAAM,OAAO,oBAAoB,WAAW,KAAK;AAAA,EAC1D,GAAG,CAAC,OAAO,CAAC;AACd;AAMA,SAAS,gBAAgB,EAAE,YAAY,MAAM,QAAQ,GAAG;AACtD,QAAM,CAAC,MAAM,OAAO,QAAI,uBAAS,MAAM;AACvC,QAAM,CAAC,MAAM,OAAO,QAAI,uBAAS,EAAE;AACnC,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,OAAO;AAClD,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,EAAE;AACzC,QAAM,CAAC,KAAK,MAAM,QAAI,uBAAS,EAAE;AACjC,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,IAAI;AAC7C,QAAM,CAAC,MAAM,OAAO,QAAI,uBAAS,SAAS;AAC1C,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAS,EAAE;AAC/C,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,oCAAoC;AAC7E,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAS;AACnC,iBAAe,OAAO;AACtB,QAAM,aAAa,CAAC,SAAS;AAC3B,YAAQ,IAAI;AACZ,aAAS,MAAS;AAAA,EACpB;AACA,QAAM,SAAS,OAAO,UAAU;AAC9B,UAAM,eAAe;AACrB,aAAS,MAAS;AAClB,QAAI,SAAS,QAAQ;AACnB,UAAI;AACF,uBAAe,QAAQ;AAAA,MACzB,SAAS,WAAW;AAClB,iBAAS,qBAAqB,QAAQ,UAAU,UAAU,OAAO,SAAS,CAAC;AAC3E;AAAA,MACF;AACA,YAAM,SAAS,MAAM,WAAW,WAAW,QAAQ;AACnD,UAAI,OAAQ,SAAQ;AAAA,UACf,UAAS,iEAAiE;AAC/E;AAAA,IACF;AACA,QAAI;AACJ,QAAI;AACF,eAAS;AAAA,QACP;AAAA,QACA,cAAc,UACV,EAAE,SAAS,MAAM,UAAU,QAAQ,EAAE,IACrC,EAAE,KAAK,MAAM,QAAQ,SAAS,UAAU,YAAY,UAAU,IAAI,CAAC,EAAE;AAAA,MAC3E;AAAA,IACF,SAAS,WAAW;AAClB,eAAS,qBAAqB,QAAQ,UAAU,UAAU,OAAO,SAAS,CAAC;AAC3E;AAAA,IACF;AACA,QAAI,MAAM,WAAW,UAAU,MAAM,MAAM,EAAG,SAAQ;AAAA,EACxD;AAEA,SACE,4CAAC,SAAI,WAAU,eAAc,MAAK,gBAAe,aAAa,CAAC,UAAU;AACvE,QAAI,MAAM,WAAW,MAAM,cAAe,SAAQ;AAAA,EACpD,GACE,uDAAC,UAAK,WAAU,kBAAiB,cAAW,kBAAiB,UAAU,QACrE;AAAA,iDAAC,SAAI,WAAU,iBACb;AAAA,mDAAC,SACC;AAAA,oDAAC,QAAG,WAAU,mBAAkB,wBAAU;AAAA,QAC1C,4CAAC,OAAE,WAAU,aAAY,6EAA+D;AAAA,SAC1F;AAAA,MACA,4CAAC,YAAO,MAAK,UAAS,WAAU,cAAa,SAAS,SAAS,mBAAK;AAAA,OACtE;AAAA,IACA,6CAAC,SAAI,WAAU,mBAAkB,MAAK,WAAU,cAAW,yBACzD;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,MAAK;AAAA,UACL,iBAAe,SAAS;AAAA,UACxB,WAAW,SAAS,SAAS,yCAAyC;AAAA,UACtE,UAAU;AAAA,UACV,SAAS,MAAM,WAAW,MAAM;AAAA,UACjC;AAAA;AAAA,MAED;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,MAAK;AAAA,UACL,iBAAe,SAAS;AAAA,UACxB,WAAW,SAAS,SAAS,yCAAyC;AAAA,UACtE,UAAU;AAAA,UACV,SAAS,MAAM,WAAW,MAAM;AAAA,UACjC;AAAA;AAAA,MAED;AAAA,OACF;AAAA,IACC,UAAU,UAAa,4CAAC,SAAI,WAAU,aAAY,MAAK,SAAS,iBAAM;AAAA,IACtE,SAAS,UACR,6CAAC,WAAM,WAAU,aACf;AAAA,kDAAC,UAAK,WAAU,aAAY,6BAAe;AAAA,MAC3C;AAAA,QAAC;AAAA;AAAA,UACC,WAAS;AAAA,UACT,WAAU;AAAA,UACV,OAAO,EAAE,WAAW,IAAI;AAAA,UACxB,OAAO;AAAA,UACP,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,UAAU,CAAC,UAAU,YAAY,MAAM,OAAO,KAAK;AAAA;AAAA,MACrD;AAAA,MACA,4CAAC,UAAK,WAAU,aAAY,0EAE5B;AAAA,OACF;AAAA,IAED,SAAS,UACR,4EACF;AAAA,mDAAC,WAAM,WAAU,aACf;AAAA,oDAAC,UAAK,WAAU,aAAY,kBAAI;AAAA,QAChC;AAAA,UAAC;AAAA;AAAA,YACC,WAAS;AAAA,YACT,WAAU;AAAA,YACV,OAAO;AAAA,YACP,UAAU;AAAA,YACV,UAAU,CAAC,UAAU,QAAQ,MAAM,OAAO,KAAK;AAAA,YAC/C,aAAY;AAAA;AAAA,QACd;AAAA,SACF;AAAA,MACA,6CAAC,WAAM,WAAU,aACf;AAAA,oDAAC,UAAK,WAAU,aAAY,uBAAS;AAAA,QACrC;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,YACP,UAAU;AAAA,YACV,UAAU,CAAC,UAAU,aAAa,MAAM,OAAO,KAAK;AAAA,YAEpD;AAAA,0DAAC,YAAO,OAAM,SAAQ,mBAAK;AAAA,cAC3B,4CAAC,YAAO,OAAM,QAAO,6BAAe;AAAA;AAAA;AAAA,QACtC;AAAA,SACF;AAAA,MACC,cAAc,UACb,4EACE;AAAA,qDAAC,WAAM,WAAU,aACf;AAAA,sDAAC,UAAK,WAAU,aAAY,qBAAO;AAAA,UACnC;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,cACP,UAAU;AAAA,cACV,UAAU,CAAC,UAAU,WAAW,MAAM,OAAO,KAAK;AAAA,cAClD,aAAY;AAAA;AAAA,UACd;AAAA,WACF;AAAA,QACA,6CAAC,WAAM,WAAU,aACf;AAAA,sDAAC,UAAK,WAAU,aAAY,kCAAoB;AAAA,UAChD;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,cACP,UAAU;AAAA,cACV,aAAa;AAAA,cACb,UAAU,CAAC,UAAU,YAAY,MAAM,OAAO,KAAK;AAAA,cACnD,YAAY;AAAA;AAAA,UACd;AAAA,WACF;AAAA,SACF,IAEA,4EACE;AAAA,qDAAC,WAAM,WAAU,aACf;AAAA,sDAAC,UAAK,WAAU,aAAY,iBAAG;AAAA,UAC/B;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,cACP,UAAU;AAAA,cACV,UAAU,CAAC,UAAU,OAAO,MAAM,OAAO,KAAK;AAAA,cAC9C,aAAY;AAAA;AAAA,UACd;AAAA,WACF;AAAA,QACA,6CAAC,SAAI,WAAU,iBACb;AAAA,uDAAC,WAAM,WAAU,aACf;AAAA,wDAAC,UAAK,WAAU,aAAY,iCAAmB;AAAA,YAC/C;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO;AAAA,gBACP,UAAU;AAAA,gBACV,OAAM;AAAA,gBACN,UAAU,CAAC,UAAU,QAAQ,MAAM,OAAO,KAAK;AAAA,gBAE/C;AAAA,8DAAC,YAAO,OAAM,WAAU,4BAAc;AAAA,kBACtC,4CAAC,YAAO,OAAM,SAAQ,iCAAmB;AAAA;AAAA;AAAA,YAC3C;AAAA,aACF;AAAA,UACC,SAAS,WACR,6CAAC,WAAM,WAAU,aACf;AAAA,wDAAC,UAAK,WAAU,aAAY,sDAAwC;AAAA,YACpE;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO;AAAA,gBACP,UAAU;AAAA,gBACV,aAAY;AAAA,gBACZ,OAAM;AAAA,gBACN,UAAU,CAAC,UAAU,cAAc,MAAM,OAAO,KAAK;AAAA;AAAA,YACvD;AAAA,YACA,4CAAC,UAAK,WAAU,aAAY,8DAAgD;AAAA,aAC9E;AAAA,WAEJ;AAAA,QACC,SAAS,WACR,4CAAC,OAAE,WAAU,aAAY,iHAGzB;AAAA,SAEJ;AAAA,OAEF;AAAA,IAEA,6CAAC,SAAI,WAAU,eACb;AAAA,kDAAC,YAAO,MAAK,UAAS,WAAU,iCAAgC,UAAU,MACvE,iBACG,SAAS,SAAS,oBAAe,iBACjC,SAAS,SAAS,mBAAmB,cAC3C;AAAA,MACA,4CAAC,YAAO,MAAK,UAAS,WAAU,cAAa,UAAU,MAAM,SAAS,SAAS,oBAE/E;AAAA,OACF;AAAA,KACF,GACF;AAEJ;AAOA,SAAS,aAAa,EAAE,YAAY,UAAU,KAAK,GAAG;AACpD,QAAM,cAAc,SAAS,gBAAgB,IAAI;AACjD,QAAM,gBACJ,gBAAgB,UAChB,YAAY,aAAa,SACxB,YAAY,cAAc,UAAa,YAAY,YAAY,KAAK,IAAI;AAC3E,QAAM,aAAa,aAAa,aAC5B,gBACE,cACA,YAAY,cAAc,SACxB,+BACA,eACJ;AACJ,QAAM,SAAS,YAAY;AACzB,UAAM,SAAS,MAAM,WAAW,OAAO,IAAI;AAC3C,QAAI,QAAQ,iBAAkB,QAAO,KAAK,OAAO,kBAAkB,QAAQ;AAAA,EAC7E;AAEA,SACE,6CAAC,SAAI,WAAU,eACb;AAAA,iDAAC,SACC;AAAA,kDAAC,QAAG,WAAU,qBAAoB,mBAAK;AAAA,MACvC,6CAAC,OAAE,WAAU,aAAY;AAAA;AAAA,QACD;AAAA,QAAW;AAAA,SAInC;AAAA,MACC,gBAAgB,UAAa,YAAY,eAAe,QAAQ,CAAC,iBAChE,4CAAC,SAAI,WAAU,eAAc,2DAA6C;AAAA,OAE9E;AAAA,IACA,6CAAC,SAAI,WAAU,eACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,SAAS;AAAA,UACnB,OAAM;AAAA,UACN,SAAS,MAAM,KAAK,OAAO;AAAA,UAC5B;AAAA;AAAA,MAED;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,SAAS;AAAA,UACnB,OAAM;AAAA,UACN,SAAS,MAAM,KAAK,WAAW,QAAQ,IAAI;AAAA,UAC5C;AAAA;AAAA,MAED;AAAA,OACF;AAAA,KACF;AAEJ;AAQA,SAAS,sBAAsB,EAAE,YAAY,UAAU,MAAM,OAAO,GAAG;AACrE,QAAM,SAAS,UAAU,SAAS,UAAU,IAAI;AAChD,SACE,6CAAC,SAAI,WAAU,YACb;AAAA,gDAAC,SAAI,WAAU,iBACb,uDAAC,SACC;AAAA,mDAAC,SAAI,WAAU,WACb;AAAA,oDAAC,UAAK,WAAW,kBAAkB,YAAY,OAAO,KAAK,CAAC,IAAI;AAAA,QAChE,4CAAC,QAAG,WAAU,kBAAkB,gBAAK;AAAA,QACrC,4CAAC,UAAK,WAAW,aAAa,YAAY,OAAO,KAAK,CAAC,IAAK,iBAAO,OAAM;AAAA,QACzE,4CAAC,UAAK,WAAU,iCAAgC,uBAAS;AAAA,SAC3D;AAAA,MACA,6CAAC,OAAE,WAAU,aACV;AAAA,eAAO;AAAA,QAAU;AAAA,QAAE,OAAO,cAAc,IAAI,SAAS;AAAA,QAAQ;AAAA,QAC7D,OAAO,cAAc,SAAY,KAAK,SAAM,OAAO,SAAS;AAAA,SAC/D;AAAA,OACF,GACF;AAAA,IACA,4CAAC,SAAI,WAAU,oBAAmB,2GAGlC;AAAA,IACA,6CAAC,SAAI,WAAU,eACb;AAAA,kDAAC,QAAG,WAAU,qBAAoB,oBAAM;AAAA,MACxC,6CAAC,OAAE,WAAU,aACV;AAAA,eAAO,OAAO,YAAY,WACvB,UAAU,OAAO,OAAO,IAAI,OAAO,QAAQ,CAAC,GAAG,SAAS,IAAI,IAAI,OAAO,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,KAC5F,SAAS,OAAO,GAAG;AAAA,QAAI;AAAA,QAAI;AAAA,QAClB,OAAO,aAAa;AAAA,QAAO;AAAA,QAAI,OAAO,YAAY,eAAe;AAAA,SAChF;AAAA,OACF;AAAA,IACC,OAAO,OAAO,QAAQ,YAAY,OAAO,SAAS,WACjD,4CAAC,gBAAa,YAAwB,UAAoB,MAAY;AAAA,IAExE,6CAAC,SAAI,WAAU,eACb;AAAA,kDAAC,QAAG,WAAU,qBAAoB,wBAAU;AAAA,MAC5C,4CAAC,OAAE,WAAU,aAAY,iHAGzB;AAAA,OACF;AAAA,KACF;AAEJ;AAEA,SAAS,aAAa,EAAE,YAAY,UAAU,MAAM,OAAO,GAAG;AAC5D,QAAM,SAAS,UAAU,SAAS,UAAU,IAAI;AAChD,QAAM,QAAQ,WAAW,SAAS,UAAU,IAAI;AAChD,QAAM,mBAAmB,aAAa,SAAS,QAAQ,IAAI,MAAM;AACjE,QAAM,YAAY,OAAO,OAAO,YAAY,WAAW,UAAU;AACjE,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAS,OAAO;AAAA,IACxC;AAAA,IACA,SAAS,OAAO,WAAW;AAAA,IAC3B,KAAK,OAAO,OAAO;AAAA,IACnB,UAAU,KAAK,UAAU,OAAO,QAAQ,CAAC,GAAG,MAAM,CAAC;AAAA,IACnD,MAAM,OAAO,QAAQ;AAAA,IACrB,aAAa,OAAO,UAAU,CAAC,GAAG,KAAK,IAAI;AAAA,IAC3C,UAAU,OAAO,aAAa;AAAA,IAC9B,WAAW,OAAO,cAAc;AAAA,IAChC,oBAAoB,OAAO,OAAO,sBAAsB,EAAE;AAAA,EAC5D,EAAE;AACF,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,OAAO;AAAA,IAC5C,KAAK,WAAW,mBAAmB,SAAS,iBAAiB,MAAM,MAAM,KAAK,CAAC;AAAA,IAC/E,SAAS,WAAW,mBAAmB,SAAS,iBAAiB,MAAM,MAAM,SAAS,CAAC;AAAA,EACzF,EAAE;AACF,QAAM,oBAAoB,MAAM,cAAc,UAAU,QAAQ;AAChE,QAAM,OAAO,QAAQ,iBAAiB;AACtC,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAS,KAAK;AACxC,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS;AAC3C,QAAM,CAAC,eAAe,gBAAgB,QAAI,uBAAS,KAAK;AAExD,8BAAU,MAAM;AACd,QAAI,MAAO;AACX,UAAM,gBAAgB,OAAO,OAAO,YAAY,WAAW,UAAU;AACrE,aAAS;AAAA,MACP,WAAW;AAAA,MACX,SAAS,OAAO,WAAW;AAAA,MAC3B,KAAK,OAAO,OAAO;AAAA,MACnB,UAAU,KAAK,UAAU,OAAO,QAAQ,CAAC,GAAG,MAAM,CAAC;AAAA,MACnD,MAAM,OAAO,QAAQ;AAAA,MACrB,aAAa,OAAO,UAAU,CAAC,GAAG,KAAK,IAAI;AAAA,MAC3C,UAAU,OAAO,aAAa;AAAA,MAC9B,WAAW,OAAO,cAAc;AAAA,MAChC,oBAAoB,OAAO,OAAO,sBAAsB,EAAE;AAAA,IAC5D,CAAC;AACD,eAAW;AAAA,MACT,KAAK,WAAW,mBAAmB,SAAS,iBAAiB,MAAM,MAAM,KAAK,CAAC;AAAA,MAC/E,SAAS,WAAW,mBAAmB,SAAS,iBAAiB,MAAM,MAAM,SAAS,CAAC;AAAA,IACzF,CAAC;AAAA,EACH,GAAG,CAAC,OAAO,MAAM,QAAQ,SAAS,iBAAiB,IAAI,CAAC;AAExD,QAAM,cAAc,CAAC,UAAU;AAC7B,aAAS,IAAI;AACb,aAAS,CAAC,aAAa,EAAE,GAAG,SAAS,GAAG,MAAM,EAAE;AAAA,EAClD;AACA,QAAM,aAAa,CAAC,SAAS;AAC3B,aAAS,IAAI;AACb,eAAW,CAAC,aAAa,EAAE,GAAG,SAAS,CAAC,iBAAiB,GAAG,KAAK,EAAE;AAAA,EACrE;AACA,QAAM,OAAO,OAAO,UAAU;AAC5B,UAAM,eAAe;AACrB,iBAAa,MAAS;AACtB,QAAI;AACF,YAAM,gBAAgB,MAAM;AAC5B,4BAAsB,MAAM;AAAA,QAC1B,GAAI,kBAAkB,UAClB,EAAE,SAAS,MAAM,SAAS,MAAM,UAAU,MAAM,QAAQ,EAAE,IAC1D,EAAE,KAAK,MAAM,IAAI;AAAA,QACrB,MAAM,kBAAkB,SAAS,MAAM,OAAO;AAAA,QAC9C,QAAQ,kBAAkB,SAAS,YAAY,MAAM,UAAU,IAAI,CAAC;AAAA,QACpE,UAAU,MAAM;AAAA,QAChB,WAAW,MAAM;AAAA,QACjB,oBAAoB,OAAO,MAAM,kBAAkB;AAAA,QACnD,eAAe,OAAO;AAAA,MACxB,CAAC;AACD,YAAM,QAAQ,kBAAkB,UAAU,QAAQ;AAClD;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA,mBAAmB,SAAS,iBAAiB,MAAM,MAAM,KAAK;AAAA,MAChE;AAAA,IACF,SAAS,WAAW;AAClB,mBAAa,qBAAqB,QAAQ,UAAU,UAAU,OAAO,SAAS,CAAC;AAC/E;AAAA,IACF;AACA,QAAI,MAAM,WAAW,WAAW,MAAM,OAAO,IAAI,GAAG;AAClD,iBAAW,CAAC,aAAa;AAAA,QACvB,GAAG;AAAA,QACH,CAAC,iBAAiB,GAAG,KAAK,IAAI,CAAC,SAAS;AAAA,UACtC,aAAa,IAAI,IAAI,KAAK;AAAA,UAC1B,KAAK,IAAI,IAAI,KAAK;AAAA,UAClB,OAAO;AAAA,QACT,EAAE;AAAA,MACJ,EAAE;AACF,eAAS,KAAK;AAAA,IAChB;AAAA,EACF;AACA,QAAM,SAAS,YAAY;AACzB,QAAI,MAAM,WAAW,aAAa,IAAI,EAAG,kBAAiB,KAAK;AAAA,EACjE;AAEA,SACE,6CAAC,SAAI,WAAU,YACb;AAAA,iDAAC,SAAI,WAAU,iBACb;AAAA,mDAAC,SACC;AAAA,qDAAC,SAAI,WAAU,WACb;AAAA,sDAAC,UAAK,WAAW,kBAAkB,YAAY,OAAO,KAAK,CAAC,IAAI;AAAA,UAChE,4CAAC,QAAG,WAAU,kBAAkB,gBAAK;AAAA,UACrC,4CAAC,UAAK,WAAW,aAAa,YAAY,OAAO,KAAK,CAAC,IAAK,iBAAO,OAAM;AAAA,UACxE,oBACC,4CAAC,UAAK,WAAU,iCAAgC,uBAAS;AAAA,WAE7D;AAAA,QACA,6CAAC,OAAE,WAAU,aACV;AAAA,iBAAO;AAAA,UAAU;AAAA,UAAE,OAAO,cAAc,IAAI,SAAS;AAAA,UAAQ;AAAA,UAC7D,OAAO,cAAc,SAAY,KAAK,SAAM,OAAO,SAAS;AAAA,WAC/D;AAAA,SACF;AAAA,MACA,6CAAC,SAAI,WAAU,eACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,UAAU,SAAS,QAAQ,MAAM;AAAA,YACjC,SAAS,MAAM,KAAK,WAAW,UAAU,IAAI;AAAA,YAC9C;AAAA;AAAA,QAED;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,UAAU,SAAS;AAAA,YACnB,SAAS,MAAM,iBAAiB,IAAI;AAAA,YACrC;AAAA;AAAA,QAED;AAAA,SACF;AAAA,OACF;AAAA,IAEC,oBACC,4CAAC,SAAI,WAAU,oBAAmB,MAAK,QAAO,yJAG9C;AAAA,IAED,OAAO,YAAY,UAAa,OAAO,UAAU,WAChD,4CAAC,SAAI,WAAU,aAAY,MAAK,SAAS,iBAAO,SAAQ;AAAA,IAEzD,iBACC,6CAAC,SAAI,WAAU,eACb;AAAA,mDAAC,YAAO;AAAA;AAAA,QAAQ;AAAA,QAAK;AAAA,SAAC;AAAA,MACtB,4CAAC,UAAK,WAAU,aAAY,iEAAmD;AAAA,MAC/E,6CAAC,SAAI,WAAU,eACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,UAAU,SAAS;AAAA,YACnB,SAAS,MAAM,KAAK,OAAO;AAAA,YAC5B;AAAA;AAAA,QAED;AAAA,QACA,4CAAC,YAAO,MAAK,UAAS,WAAU,cAAa,SAAS,MAAM,iBAAiB,KAAK,GAAG,oBAErF;AAAA,SACF;AAAA,OACF;AAAA,IAGF,6CAAC,UAAK,WAAU,YAAW,UAAU,MAClC;AAAA,oBAAc,UAAa,4CAAC,SAAI,WAAU,aAAY,MAAK,SAAS,qBAAU;AAAA,MAC/E,6CAAC,SAAI,WAAU,iBACb;AAAA,qDAAC,WAAM,WAAU,aACf;AAAA,sDAAC,UAAK,WAAU,aAAY,kBAAI;AAAA,UAChC,4CAAC,WAAM,WAAU,aAAY,OAAO,MAAM,UAAQ,MAAC;AAAA,WACrD;AAAA,QACA,6CAAC,WAAM,WAAU,aACf;AAAA,sDAAC,UAAK,WAAU,aAAY,uBAAS;AAAA,UACrC;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,MAAM;AAAA,cACb,UAAU,SAAS;AAAA,cACnB,UAAU,CAAC,UAAU,YAAY,EAAE,WAAW,MAAM,OAAO,MAAM,CAAC;AAAA,cAElE;AAAA,4DAAC,YAAO,OAAM,SAAQ,mBAAK;AAAA,gBAC3B,4CAAC,YAAO,OAAM,QAAO,6BAAe;AAAA;AAAA;AAAA,UACtC;AAAA,WACF;AAAA,SACF;AAAA,MAEC,MAAM,cAAc,UACnB,4EACE;AAAA,qDAAC,WAAM,WAAU,aACf;AAAA,sDAAC,UAAK,WAAU,aAAY,qBAAO;AAAA,UACnC;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,MAAM;AAAA,cACb,UAAU,SAAS;AAAA,cACnB,UAAU,CAAC,UAAU,YAAY,EAAE,SAAS,MAAM,OAAO,MAAM,CAAC;AAAA;AAAA,UAClE;AAAA,WACF;AAAA,QACA,6CAAC,WAAM,WAAU,aACf;AAAA,sDAAC,UAAK,WAAU,aAAY,kCAAoB;AAAA,UAChD;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,MAAM;AAAA,cACb,UAAU,SAAS;AAAA,cACnB,YAAY;AAAA,cACZ,UAAU,CAAC,UAAU,YAAY,EAAE,UAAU,MAAM,OAAO,MAAM,CAAC;AAAA;AAAA,UACnE;AAAA,WACF;AAAA,QACA,4CAAC,gBAAa,OAAM,OAAM,MAAY,UAAU,YAAY,UAAU,SAAS,MAAM;AAAA,SACvF,IAEA,4EACE;AAAA,qDAAC,WAAM,WAAU,aACf;AAAA,sDAAC,UAAK,WAAU,aAAY,iBAAG;AAAA,UAC/B;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,MAAM;AAAA,cACb,UAAU,SAAS;AAAA,cACnB,UAAU,CAAC,UAAU,YAAY,EAAE,KAAK,MAAM,OAAO,MAAM,CAAC;AAAA;AAAA,UAC9D;AAAA,WACF;AAAA,QACA,6CAAC,SAAI,WAAU,iBACb;AAAA,uDAAC,WAAM,WAAU,aACf;AAAA,wDAAC,UAAK,WAAU,aAAY,iCAAmB;AAAA,YAC/C;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,MAAM,QAAQ;AAAA,gBACrB,UAAU,SAAS;AAAA,gBACnB,OAAM;AAAA,gBACN,UAAU,CAAC,UAAU,YAAY,EAAE,MAAM,MAAM,OAAO,MAAM,CAAC;AAAA,gBAE7D;AAAA,8DAAC,YAAO,OAAM,WAAU,4BAAc;AAAA,kBACtC,4CAAC,YAAO,OAAM,SAAQ,iCAAmB;AAAA;AAAA;AAAA,YAC3C;AAAA,aACF;AAAA,UACC,MAAM,SAAS,WACd,6CAAC,WAAM,WAAU,aACf;AAAA,wDAAC,UAAK,WAAU,aAAY,sDAAwC;AAAA,YACpE;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,MAAM;AAAA,gBACb,UAAU,SAAS;AAAA,gBACnB,aAAY;AAAA,gBACZ,OAAM;AAAA,gBACN,UAAU,CAAC,UAAU,YAAY,EAAE,YAAY,MAAM,OAAO,MAAM,CAAC;AAAA;AAAA,YACrE;AAAA,YACA,4CAAC,UAAK,WAAU,aAAY,8DAAgD;AAAA,aAC9E;AAAA,WAEJ;AAAA,QACC,MAAM,SAAS,WACd,4CAAC,OAAE,WAAU,aAAY,yGAGzB;AAAA,QAEF,4CAAC,gBAAa,OAAM,WAAU,MAAY,UAAU,YAAY,UAAU,SAAS,MAAM;AAAA,SAC3F;AAAA,MAGF,6CAAC,SAAI,WAAU,iBACb;AAAA,qDAAC,WAAM,WAAU,aACf;AAAA,sDAAC,UAAK,WAAU,aAAY,qCAAuB;AAAA,UACnD;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,MAAK;AAAA,cACL,KAAI;AAAA,cACJ,MAAK;AAAA,cACL,OAAO,MAAM;AAAA,cACb,UAAU,SAAS;AAAA,cACnB,UAAU,CAAC,UAAU,YAAY,EAAE,oBAAoB,MAAM,OAAO,MAAM,CAAC;AAAA;AAAA,UAC7E;AAAA,WACF;AAAA,QACA,6CAAC,SAAI,WAAU,aACb;AAAA,sDAAC,UAAK,WAAU,aAAY,yBAAW;AAAA,UACvC,6CAAC,WAAM,WAAU,gBACf;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS,MAAM;AAAA,gBACf,UAAU,SAAS;AAAA,gBACnB,UAAU,CAAC,UAAU,YAAY,EAAE,WAAW,MAAM,OAAO,QAAQ,CAAC;AAAA;AAAA,YACtE;AAAA,YAAE;AAAA,aAEJ;AAAA,WACF;AAAA,SACF;AAAA,MACA,6CAAC,WAAM,WAAU,gBACf;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM;AAAA,YACf,UAAU,SAAS;AAAA,YACnB,UAAU,CAAC,UAAU,YAAY,EAAE,UAAU,MAAM,OAAO,QAAQ,CAAC;AAAA;AAAA,QACrE;AAAA,QAAE;AAAA,SAEJ;AAAA,MACA,6CAAC,SAAI,WAAU,eACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,UAAU,oBAAoB,SAAS,QAAQ,CAAC;AAAA,YAE/C,mBAAS,OAAO,iBAAY;AAAA;AAAA,QAC/B;AAAA,QACC,SAAS,CAAC,oBAAoB,4CAAC,UAAK,WAAU,aAAY,6BAAe;AAAA,QACzE,oBAAoB,4CAAC,UAAK,WAAU,aAAY,iDAAmC;AAAA,SACtF;AAAA,OACF;AAAA,IAEC,OAAO,OAAO,QAAQ,YAAY,OAAO,SAAS,WACjD,4CAAC,gBAAa,YAAwB,UAAoB,MAAY;AAAA,IAGxE,6CAAC,SAAI,WAAU,eACb;AAAA,mDAAC,SACC;AAAA,oDAAC,QAAG,WAAU,qBAAoB,wBAAU;AAAA,QAC5C,6CAAC,OAAE,WAAU,aAAY;AAAA;AAAA,UAC2B;AAAA,UAAK;AAAA,WACzD;AAAA,SACF;AAAA,MACC,MAAM,WAAW,IAChB,4CAAC,SAAI,WAAU,eAAc,+EAE7B,IAEA,4CAAC,SAAI,WAAU,sBACZ,gBAAM,IAAI,CAAC,SAAS;AACnB,cAAM,WAAW,OAAO,iBAAiB,CAAC,GAAG,SAAS,KAAK,IAAI;AAC/D,eACE,6CAAC,WAAM,WAAU,iBACf;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL;AAAA,cACA,UAAU,SAAS;AAAA,cACnB,UAAU,MAAM,KAAK,WAAW,gBAAgB,MAAM,KAAK,IAAI;AAAA;AAAA,UACjE;AAAA,UACA,6CAAC,UACC;AAAA,wDAAC,UAAK,WAAU,sBAAsB,eAAK,MAAK;AAAA,YAC/C,KAAK,gBAAgB,UACpB,4CAAC,UAAK,WAAU,6BAA6B,eAAK,aAAY;AAAA,aAElE;AAAA,aAZoC,KAAK,IAa3C;AAAA,MAEJ,CAAC,GACH;AAAA,OAEJ;AAAA,KACF;AAEJ;AAEO,SAAS,gBAAgB,EAAE,WAAW,GAAG;AAC9C,QAAM,eAAW,mCAAqB,WAAW,WAAW,WAAW,WAAW;AAClF,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS;AACzC,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS;AACrC,QAAM,WAAW,SAAS;AAC1B,QAAM,UAAU,SAAS,OAAO,cAAc,CAAC;AAG/C,QAAM,mBAAmB,SAAS,QAAQ,WAAW,CAAC;AACtD,QAAM,YAAQ;AAAA,IACZ,MAAM,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,OAAO,GAAG,GAAG,OAAO,KAAK,gBAAgB,CAAC,CAAC,CAAC,EAAE,KAAK;AAAA,IACrF,CAAC,SAAS,gBAAgB;AAAA,EAC5B;AAEA,8BAAU,MAAM,WAAW,MAAM,GAAG,CAAC,UAAU,CAAC;AAChD,8BAAU,MAAM;AACd,QACE,aAAa,UACZ,CAAC,OAAO,OAAO,SAAS,QAAQ,KAAK,CAAC,OAAO,OAAO,kBAAkB,QAAQ,GAC/E;AACA,kBAAY,MAAM,CAAC,CAAC;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,OAAO,UAAU,SAAS,gBAAgB,CAAC;AAE/C,MAAI,SAAS,WAAW,WAAW;AACjC,WAAO,4CAAC,aAAQ,WAAU,gBAAe,sDAAC,OAAE,WAAU,aAAY,wCAAqB,GAAI;AAAA,EAC7F;AACA,MAAI,SAAS,WAAW,SAAS;AAC/B,WACE,6CAAC,aAAQ,WAAU,gBACjB;AAAA,kDAAC,QAAG,WAAU,aAAY,iBAAG;AAAA,MAC7B,4CAAC,SAAI,WAAU,aAAY,MAAK,SAC7B,mBAAS,OAAO,WAAW,iCAC9B;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,6CAAC,aAAQ,WAAU,gBACjB;AAAA,iDAAC,SAAI,WAAU,eACb;AAAA,mDAAC,SACC;AAAA,oDAAC,QAAG,WAAU,aAAY,iBAAG;AAAA,QAC7B,4CAAC,OAAE,WAAU,aAAY,6EAA+D;AAAA,SAC1F;AAAA,MACA,4CAAC,SAAI,WAAU,eACb;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,SAAS,QAAQ,CAAC,SAAS;AAAA,UACrC,SAAS,MAAM,UAAU,KAAK;AAAA,UAC/B;AAAA;AAAA,MAED,GACF;AAAA,OACF;AAAA,IAEC,CAAC,SAAS,YACT,4CAAC,SAAI,WAAU,eAAc,wDAA0C;AAAA,IAExE,SAAS,UAAU,UAClB,4CAAC,SAAI,WAAU,aAAY,MAAK,SAAS,mBAAS,OAAM;AAAA,IAGzD,MAAM,WAAW,IAChB,6CAAC,SAAI,WAAU,aACb;AAAA,kDAAC,QAAG,WAAU,kBAAiB,4BAAc;AAAA,MAC7C,4CAAC,OAAE,WAAU,aAAY,0FAEzB;AAAA,MACA,4CAAC,SAAI,WAAU,eACb;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,SAAS,QAAQ,CAAC,SAAS;AAAA,UACrC,SAAS,MAAM,UAAU,KAAK;AAAA,UAC/B;AAAA;AAAA,MAED,GACF;AAAA,OACF,IAEA,6CAAC,SAAI,WAAU,cACb;AAAA,kDAAC,SAAI,WAAU,eAAc,cAAW,eACrC,gBAAM,IAAI,CAAC,SAAS;AACnB,cAAM,SAAS,UAAU,SAAS,UAAU,IAAI;AAChD,cAAM,mBAAmB,aAAa,SAAS,QAAQ,IAAI,MAAM;AACjE,eACE;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,gBAAc,SAAS;AAAA,YAEvB,SAAS,MAAM,YAAY,IAAI;AAAA,YAE/B;AAAA,0DAAC,UAAK,WAAW,kBAAkB,YAAY,OAAO,KAAK,CAAC,IAAI;AAAA,cAChE,4CAAC,UAAK,WAAU,mBAAmB,gBAAK;AAAA,cACvC,oBACC,4CAAC,UAAK,WAAU,iCAAgC,uBAAS;AAAA,cAE3D,4CAAC,UAAK,WAAU,oBAAoB,iBAAO,WAAU;AAAA;AAAA;AAAA,UARhD;AAAA,QASP;AAAA,MAEJ,CAAC,GACH;AAAA,MACC,aAAa,UAAa,QAAQ,QAAQ,MAAM,UAC/C;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,QAAQ,QAAQ,QAAQ;AAAA;AAAA,QAJnB;AAAA,MAKP;AAAA,MAED,aAAa,UAAa,QAAQ,QAAQ,MAAM,UAAa,iBAAiB,QAAQ,MAAM,UAC3F;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,QAAQ,iBAAiB,QAAQ;AAAA;AAAA,QAJ5B;AAAA,MAKP;AAAA,OAEJ;AAAA,IAGD,WAAW,SACV,4CAAC,mBAAgB,YAAwB,MAAM,SAAS,MAAM,SAAS,MAAM,UAAU,GAAG;AAAA,KAE9F;AAEJ;;;AE73BO,SAAS,kBAAkB,KAAK;AACrC,QAAM,iBAAiB,mBAAmB,GAAG;AAC7C,MAAI,mBAAmB,OAAW,QAAO,kBAAkB,cAAc;AAEzE,QAAM,qBAAqB,IAAI,YAAY,KAAK;AAChD,MAAI,uBAAuB,OAAW,QAAO;AAE7C,QAAM,IAAI;AAAA,IACR;AAAA,EAGF;AACF;AAkBA,SAAS,mBAAmB,KAAK;AAC/B,MAAI,OAAO,IAAI,QAAQ,YAAY;AACjC,QAAI;AACF,YAAM,UAAU,IAAI,IAAI,iBAAiB;AACzC,UAAI,YAAY,OAAW,QAAO;AAAA,IACpC,QAAQ;AAAA,IAAwC;AAAA,EAClD;AACA,MAAI;AACF,WAAO,IAAI,QAAQ;AAAA,EACrB,QAAQ;AAAA,EAA4E;AACpF,SAAO;AACT;AAGA,SAAS,kBAAkB,QAAQ;AACjC,SAAO;AAAA,IACL,MAAM,OAAO,EAAE,IAAI,OAAO,iBAAiB,GAAG;AAC5C,aAAO,EAAE,QAAQ,MAAM,OAAO,OAAO,IAAI,OAAO,gBAAgB,EAAE;AAAA,IACpE;AAAA,IACA,MAAM,OAAO,EAAE,IAAI,KAAK,iBAAiB,GAAG;AAC1C,aAAO,EAAE,QAAQ,MAAM,OAAO,OAAO,IAAI,KAAK,gBAAgB,EAAE;AAAA,IAClE;AAAA,EACF;AACF;;;ACrEO,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuFzB,SAAS,2BAA2B;AACzC,QAAM,KAAK;AACX,QAAM,WAAW,SAAS,cAAc,0BAA0B,EAAE,IAAI;AACxE,MAAI,aAAa,KAAM,QAAO,MAAM;AAAA,EAAC;AACrC,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,QAAQ,YAAY;AAC1B,QAAM,cAAc;AACpB,WAAS,KAAK,YAAY,KAAK;AAC/B,SAAO,MAAM,MAAM,OAAO;AAC5B;;;AJhFO,IAAM,SAAS,CAAC,SAAS,iBAAiB,cAAc,QAAQ;AAEhE,SAAS,MAAM,KAAK;AACzB,QAAM,QAAQ,IAAI,cAAc,KAAK,EAAE,WAAW,uBAAuB,CAAC;AAC1E,QAAM,WAAW,IAAI,cAAc,SAAS;AAC5C,QAAM,aAAa,IAAI,sBAAsB;AAAA,IAC3C;AAAA,IACA;AAAA,IACA,aAAa,kBAAkB,GAAG;AAAA,IAClC,KAAK,CAAC,UAAU,SAAS,WACvB,IAAI,WAAW,IAAI,KAAK,iBAAiB,UAAU,SAAS,MAAM;AAAA,EACtE,CAAC;AAED,MAAI,OAAO,MAAM,yBAAyB,GAAG,8BAA8B;AAC3E,MAAI,OAAO,MAAM,MAAM,WAAW,QAAQ,GAAG,kCAAkC;AAC/E,MAAI,MAAM;AAAA,IAAO;AAAA,IAAoB,MACnC,IAAI,MAAM;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO;AAAA,QACP,QAAQ,OAAO,EAAE,WAAW;AAAA,MAC9B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;",
6
6
  "names": ["secretRows"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auggieteo/dsh-mcp-adapter",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "DSH plugin connecting the agent to MCP servers through one mcp proxy tool and a Settings > MCP page.",
5
5
  "type": "module",
6
6
  "license": "MIT",