@bastani/atomic 0.9.26-alpha.2 → 0.9.26-alpha.3
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 +18 -0
- package/dist/builtin/intercom/broker/spawn.ts +2 -0
- package/dist/builtin/intercom/index.bundle.mjs +1 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/native-client-licenses/NOTICE +2 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +4 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/keybindings.d.ts +5 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +1 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/extensions/mcp/cli.d.ts.map +1 -1
- package/dist/extensions/mcp/cli.js +4 -1
- package/dist/extensions/mcp/cli.js.map +1 -1
- package/dist/extensions/mcp/client/oauth/callback.d.ts +4 -2
- package/dist/extensions/mcp/client/oauth/callback.d.ts.map +1 -1
- package/dist/extensions/mcp/client/oauth/callback.js +12 -7
- package/dist/extensions/mcp/client/oauth/callback.js.map +1 -1
- package/dist/extensions/mcp/client/oauth/flow.d.ts +7 -1
- package/dist/extensions/mcp/client/oauth/flow.d.ts.map +1 -1
- package/dist/extensions/mcp/client/oauth/flow.js +20 -21
- package/dist/extensions/mcp/client/oauth/flow.js.map +1 -1
- package/dist/extensions/mcp/client/oauth/index.d.ts +1 -1
- package/dist/extensions/mcp/client/oauth/index.d.ts.map +1 -1
- package/dist/extensions/mcp/client/oauth/index.js.map +1 -1
- package/dist/extensions/mcp/client/oauth/provider.d.ts +5 -2
- package/dist/extensions/mcp/client/oauth/provider.d.ts.map +1 -1
- package/dist/extensions/mcp/client/oauth/provider.js +2 -0
- package/dist/extensions/mcp/client/oauth/provider.js.map +1 -1
- package/dist/extensions/mcp/config.d.ts +16 -4
- package/dist/extensions/mcp/config.d.ts.map +1 -1
- package/dist/extensions/mcp/config.js +50 -11
- package/dist/extensions/mcp/config.js.map +1 -1
- package/dist/extensions/mcp/index.d.ts +4 -1
- package/dist/extensions/mcp/index.d.ts.map +1 -1
- package/dist/extensions/mcp/index.js +80 -46
- package/dist/extensions/mcp/index.js.map +1 -1
- package/dist/extensions/mcp/oauth.d.ts.map +1 -1
- package/dist/extensions/mcp/oauth.js +9 -5
- package/dist/extensions/mcp/oauth.js.map +1 -1
- package/dist/extensions/mcp/ui.d.ts.map +1 -1
- package/dist/extensions/mcp/ui.js +8 -4
- package/dist/extensions/mcp/ui.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/chat-input-actions.js.map +1 -1
- package/dist/modes/interactive/components/auth-url.d.ts +10 -0
- package/dist/modes/interactive/components/auth-url.d.ts.map +1 -0
- package/dist/modes/interactive/components/auth-url.js +37 -0
- package/dist/modes/interactive/components/auth-url.js.map +1 -0
- package/dist/modes/interactive/components/index.d.ts +0 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +0 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +1 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +10 -5
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/interactive-auth-login.js +0 -1
- package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
- package/dist/modes/interactive/interactive-hotkeys-debug.js +1 -11
- package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -2
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js +0 -1
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +0 -5
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.js +0 -2
- package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-tui.js.map +1 -1
- package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-custom-ui.js +38 -2
- package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
- package/dist/modes/interactive-engine/protocol.d.ts +10 -0
- package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
- package/dist/modes/interactive-engine/protocol.js +10 -0
- package/dist/modes/interactive-engine/protocol.js.map +1 -1
- package/dist/modes/interactive-engine/remote-component.d.ts +2 -1
- package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -1
- package/dist/modes/interactive-engine/remote-component.js +23 -1
- package/dist/modes/interactive-engine/remote-component.js.map +1 -1
- package/docs/keybindings.md +3 -0
- package/docs/mcp-servers.md +13 -1
- package/docs/providers.md +2 -0
- package/npm-shrinkwrap.json +55 -33
- package/package.json +4 -3
- package/dist/modes/interactive/components/daxnuts.d.ts +0 -23
- package/dist/modes/interactive/components/daxnuts.d.ts.map +0 -1
- package/dist/modes/interactive/components/daxnuts.js +0 -140
- package/dist/modes/interactive/components/daxnuts.js.map +0 -1
|
@@ -26,8 +26,7 @@
|
|
|
26
26
|
* current session for registered servers.
|
|
27
27
|
*/
|
|
28
28
|
import { join, resolve } from "node:path";
|
|
29
|
-
import {
|
|
30
|
-
import { getAgentDir } from "../../config.js";
|
|
29
|
+
import { CONFIG_DIR_NAME, getAgentDir } from "../../config.js";
|
|
31
30
|
import { markNativeMcpToolDefinition, matchesMcpDirectToolSelection } from "../../core/mcp-child-policy.js";
|
|
32
31
|
import { mcpNamespace } from "../../core/mcp-servers.js";
|
|
33
32
|
import { openBrowser } from "../../utils/open-browser.js";
|
|
@@ -207,6 +206,8 @@ export function createMcpExtension(options = {}) {
|
|
|
207
206
|
/** Servers from `mcp.json`, which take precedence over registered servers of the same name. */
|
|
208
207
|
let configuredEntries = [];
|
|
209
208
|
let configErrors = [];
|
|
209
|
+
/** The trusted project's `mcp.json`, where `/mcp` saves project overrides of global servers. */
|
|
210
|
+
let projectConfig;
|
|
210
211
|
/** Registered servers that `mcp.json` overrides, shown in `/mcp`. */
|
|
211
212
|
let overridden = [];
|
|
212
213
|
let latestContext;
|
|
@@ -229,7 +230,10 @@ export function createMcpExtension(options = {}) {
|
|
|
229
230
|
let modelRegistry;
|
|
230
231
|
let serverLog;
|
|
231
232
|
const openUrl = options.openUrl ?? openBrowser;
|
|
232
|
-
const updateConfig = options.updateConfig ??
|
|
233
|
+
const updateConfig = options.updateConfig ??
|
|
234
|
+
((entry, patch) => updateMcpServerConfig(entry.override ?? entry.source, entry.name, patch, {
|
|
235
|
+
override: entry.override !== undefined,
|
|
236
|
+
}));
|
|
233
237
|
const listeners = new Set();
|
|
234
238
|
const emitChange = () => {
|
|
235
239
|
for (const listener of listeners)
|
|
@@ -534,18 +538,20 @@ export function createMcpExtension(options = {}) {
|
|
|
534
538
|
};
|
|
535
539
|
/**
|
|
536
540
|
* Save a config change; returns an error message when the file could not be updated. Changes to
|
|
537
|
-
* registered servers only apply to the current session.
|
|
541
|
+
* registered servers only apply to the current session. `inProject` adds a project override.
|
|
538
542
|
*/
|
|
539
|
-
const saveConfig = (server, patch) => {
|
|
540
|
-
|
|
543
|
+
const saveConfig = (server, patch, inProject = false) => {
|
|
544
|
+
const override = inProject ? projectConfig : server.entry.override;
|
|
545
|
+
const entry = override ? { ...server.entry, override } : server.entry;
|
|
546
|
+
if (entry.scope !== "extension") {
|
|
541
547
|
try {
|
|
542
|
-
updateConfig(
|
|
548
|
+
updateConfig(entry, patch);
|
|
543
549
|
}
|
|
544
550
|
catch (error) {
|
|
545
|
-
return `Could not update ${
|
|
551
|
+
return `Could not update ${entry.override ?? entry.source}: ${errorMessage(error)}`;
|
|
546
552
|
}
|
|
547
553
|
}
|
|
548
|
-
server.entry = { ...
|
|
554
|
+
server.entry = { ...entry, config: { ...entry.config, ...patch } };
|
|
549
555
|
return undefined;
|
|
550
556
|
};
|
|
551
557
|
const signIn = async (server, prompt) => {
|
|
@@ -600,8 +606,8 @@ export function createMcpExtension(options = {}) {
|
|
|
600
606
|
}
|
|
601
607
|
};
|
|
602
608
|
/** Returns an error message when the config could not be saved; connection errors show in the state. */
|
|
603
|
-
const setEnabled = async (server, enabled) => {
|
|
604
|
-
const failed = saveConfig(server, { enabled });
|
|
609
|
+
const setEnabled = async (server, enabled, inProject = false) => {
|
|
610
|
+
const failed = saveConfig(server, { enabled }, inProject);
|
|
605
611
|
if (failed)
|
|
606
612
|
return failed;
|
|
607
613
|
if (!enabled) {
|
|
@@ -647,9 +653,9 @@ export function createMcpExtension(options = {}) {
|
|
|
647
653
|
.map((server) => ({
|
|
648
654
|
value: server.entry.name,
|
|
649
655
|
label: server.entry.name,
|
|
650
|
-
description: `${describeState(server)} · ${exposureOf(server.entry)} · ${server.entry.scope ?? server.entry.source}`,
|
|
656
|
+
description: `${describeState(server)} · ${exposureOf(server.entry)} · ${server.entry.override ? "global, project override" : (server.entry.scope ?? server.entry.source)}`,
|
|
651
657
|
})),
|
|
652
|
-
empty: `No MCP servers configured. Add them to ${resolve(getAgentDir(), "mcp.json")} or
|
|
658
|
+
empty: `No MCP servers configured. Add them to ${resolve(getAgentDir(), "mcp.json")} or ${CONFIG_DIR_NAME}/mcp.json.`,
|
|
653
659
|
confirmLabel: "manage",
|
|
654
660
|
cancelLabel: "close",
|
|
655
661
|
});
|
|
@@ -667,12 +673,20 @@ export function createMcpExtension(options = {}) {
|
|
|
667
673
|
const { entry, connection } = server;
|
|
668
674
|
const saved = entry.scope === "extension"
|
|
669
675
|
? "for this session"
|
|
670
|
-
: entry.
|
|
671
|
-
?
|
|
672
|
-
:
|
|
676
|
+
: entry.override
|
|
677
|
+
? "saved to the project mcp.json"
|
|
678
|
+
: entry.scope
|
|
679
|
+
? `saved to the ${entry.scope} mcp.json`
|
|
680
|
+
: "saved to mcp.json";
|
|
681
|
+
// Global servers without an override can be turned on or off for the trusted project alone.
|
|
682
|
+
const inProject = entry.scope === "global" && !entry.override && projectConfig !== undefined;
|
|
683
|
+
const inProjectSaved = "saved to the project mcp.json";
|
|
673
684
|
const items = [];
|
|
674
685
|
if (!isEnabled(server)) {
|
|
675
686
|
items.push({ value: "enable", label: "Enable", description: saved });
|
|
687
|
+
if (inProject) {
|
|
688
|
+
items.push({ value: "enable-project", label: "Enable in this project", description: inProjectSaved });
|
|
689
|
+
}
|
|
676
690
|
}
|
|
677
691
|
else {
|
|
678
692
|
const state = connection?.state;
|
|
@@ -689,10 +703,14 @@ export function createMcpExtension(options = {}) {
|
|
|
689
703
|
}
|
|
690
704
|
items.push({ value: "exposure", label: "Exposure", description: exposureOf(entry) });
|
|
691
705
|
items.push({ value: "disable", label: "Disable", description: saved });
|
|
706
|
+
if (inProject) {
|
|
707
|
+
items.push({ value: "disable-project", label: "Disable in this project", description: inProjectSaved });
|
|
708
|
+
}
|
|
692
709
|
}
|
|
693
710
|
const details = [
|
|
694
711
|
describeTransport(entry),
|
|
695
712
|
`${entry.scope ?? "config"}: ${entry.source}`,
|
|
713
|
+
...(entry.override ? [`project override: ${entry.override}`] : []),
|
|
696
714
|
`State: ${describeState(server, false)}`,
|
|
697
715
|
];
|
|
698
716
|
const error = [server.message, connection?.state === "connected" ? undefined : connection?.error]
|
|
@@ -734,7 +752,7 @@ export function createMcpExtension(options = {}) {
|
|
|
734
752
|
title: `Exposure of ${server.entry.name}`,
|
|
735
753
|
details: server.entry.scope === "extension"
|
|
736
754
|
? `Applies to this session; the server is registered by ${server.entry.source}.`
|
|
737
|
-
: `Saved to ${server.entry.source}.`,
|
|
755
|
+
: `Saved to ${server.entry.override ?? server.entry.source}.`,
|
|
738
756
|
items: Object.keys(EXPOSURE_DESCRIPTIONS).map((exposure) => ({
|
|
739
757
|
value: exposure,
|
|
740
758
|
label: `${exposure === current ? "✓ " : " "}${exposure}`,
|
|
@@ -748,27 +766,29 @@ export function createMcpExtension(options = {}) {
|
|
|
748
766
|
return undefined;
|
|
749
767
|
return setExposure(server, choice);
|
|
750
768
|
};
|
|
769
|
+
const signInWithUi = (ui, server) => {
|
|
770
|
+
const title = `Sign in to ${server.entry.name}`;
|
|
771
|
+
let authorizationUrl = "";
|
|
772
|
+
ui.status(title, "Contacting the authorization server…");
|
|
773
|
+
return signIn(server, {
|
|
774
|
+
showAuthorizationUrl: (url) => {
|
|
775
|
+
authorizationUrl = url.href;
|
|
776
|
+
openUrl(url.href);
|
|
777
|
+
},
|
|
778
|
+
promptForRedirectUrl: async (signal) => {
|
|
779
|
+
const value = await ui.redirectUrl(title, authorizationUrl, signal);
|
|
780
|
+
ui.status(title, "Connecting…");
|
|
781
|
+
return value;
|
|
782
|
+
},
|
|
783
|
+
});
|
|
784
|
+
};
|
|
751
785
|
const runAction = async (ui, ctx, server, action) => {
|
|
752
786
|
const { name } = server.entry;
|
|
753
787
|
let message;
|
|
754
788
|
switch (action) {
|
|
755
|
-
case "signin":
|
|
756
|
-
|
|
757
|
-
let authorizationUrl = "";
|
|
758
|
-
ui.status(title, "Contacting the authorization server…");
|
|
759
|
-
message = await signIn(server, {
|
|
760
|
-
showAuthorizationUrl: (url) => {
|
|
761
|
-
authorizationUrl = url.href;
|
|
762
|
-
openUrl(url.href);
|
|
763
|
-
},
|
|
764
|
-
promptForRedirectUrl: async (signal) => {
|
|
765
|
-
const value = await ui.redirectUrl(title, authorizationUrl, signal);
|
|
766
|
-
ui.status(title, "Connecting…");
|
|
767
|
-
return value;
|
|
768
|
-
},
|
|
769
|
-
});
|
|
789
|
+
case "signin":
|
|
790
|
+
message = await signInWithUi(ui, server);
|
|
770
791
|
break;
|
|
771
|
-
}
|
|
772
792
|
case "reconnect":
|
|
773
793
|
// A failure shows as the connection's state and error.
|
|
774
794
|
ui.status(`MCP server ${name}`, "Reconnecting…");
|
|
@@ -785,9 +805,13 @@ export function createMcpExtension(options = {}) {
|
|
|
785
805
|
break;
|
|
786
806
|
case "enable":
|
|
787
807
|
case "disable":
|
|
788
|
-
|
|
789
|
-
|
|
808
|
+
case "enable-project":
|
|
809
|
+
case "disable-project": {
|
|
810
|
+
const enable = action.startsWith("enable");
|
|
811
|
+
ui.status(`MCP server ${name}`, enable ? "Connecting…" : "Disconnecting…");
|
|
812
|
+
message = await setEnabled(server, enable, action.endsWith("-project"));
|
|
790
813
|
break;
|
|
814
|
+
}
|
|
791
815
|
}
|
|
792
816
|
server.message = message;
|
|
793
817
|
ensureDiscoveryActive(ctx);
|
|
@@ -812,7 +836,7 @@ export function createMcpExtension(options = {}) {
|
|
|
812
836
|
// ---------------------------------------------------------------------------------------
|
|
813
837
|
const formatStatus = () => {
|
|
814
838
|
if (servers.length === 0 && configErrors.length === 0 && overridden.length === 0) {
|
|
815
|
-
return `No MCP servers configured. Add them to ${resolve(getAgentDir(), "mcp.json")} or
|
|
839
|
+
return `No MCP servers configured. Add them to ${resolve(getAgentDir(), "mcp.json")} or ${CONFIG_DIR_NAME}/mcp.json.`;
|
|
816
840
|
}
|
|
817
841
|
const lines = servers.map((server) => {
|
|
818
842
|
const { name } = server.entry;
|
|
@@ -872,16 +896,25 @@ export function createMcpExtension(options = {}) {
|
|
|
872
896
|
ctx.ui.notify(`Signing in to MCP server "${name}" requires interactive mode.`, "error");
|
|
873
897
|
return;
|
|
874
898
|
}
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
}
|
|
899
|
+
let failure;
|
|
900
|
+
if (ctx.mode === "tui") {
|
|
901
|
+
let completed = false;
|
|
902
|
+
await showMcpManager(ctx, async (ui) => {
|
|
903
|
+
failure = await signInWithUi(ui, server);
|
|
904
|
+
completed = true;
|
|
905
|
+
});
|
|
906
|
+
if (!completed)
|
|
907
|
+
return;
|
|
908
|
+
}
|
|
909
|
+
else {
|
|
910
|
+
failure = await signIn(server, {
|
|
911
|
+
showAuthorizationUrl: (url) => {
|
|
912
|
+
ctx.ui.notify(`Sign in to MCP server "${name}" in your browser:\n${url.href}`, "info");
|
|
913
|
+
openUrl(url.href);
|
|
914
|
+
},
|
|
915
|
+
promptForRedirectUrl: (signal) => ctx.ui.input(`Waiting for sign-in to "${name}". If the browser cannot reach this machine, paste the URL it was redirected to.`, "http://127.0.0.1:.../callback?code=...", { signal }),
|
|
916
|
+
});
|
|
917
|
+
}
|
|
885
918
|
if (failure) {
|
|
886
919
|
ctx.ui.notify(failure, failure === "Sign-in cancelled." ? "info" : "error");
|
|
887
920
|
return;
|
|
@@ -894,6 +927,7 @@ export function createMcpExtension(options = {}) {
|
|
|
894
927
|
subagentMcpDirectTools = ctx.subagentPolicy?.mcpDirectTools;
|
|
895
928
|
const loaded = (options.loadConfig ?? defaultLoadConfig)(ctx);
|
|
896
929
|
configErrors = loaded.errors;
|
|
930
|
+
projectConfig = loaded.projectConfig;
|
|
897
931
|
autoEnableCodemode = (ctx.subagentPolicy ? false : loaded.autoEnableCodemode) ?? true;
|
|
898
932
|
warnedUnreachable = false;
|
|
899
933
|
waitedForStartup = false;
|