Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/extensions/signals-dashboard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ The canvas also exposes actions Copilot can invoke directly:
`repo` is the default. At launch, Cairn asks Copilot for the enabled
plugin-scoped MCP inventory and disables those ambient servers for the topic
desk. User-, workspace-, organization-, and built-in resources are left alone.
If discovery fails, Cairn fails open to the connected tool surface.
If discovery fails, Copilot plugin MCP suppression fails open; Agency repo mode
still omits Agency's own default MCPs.

When Agency is installed, Cairn keeps the existing `agency copilot` launch and
adds Agency's `--no-default-mcps` in repo mode. Outside Agency, the same profile
Expand Down
19 changes: 8 additions & 11 deletions .github/extensions/signals-dashboard/extension.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -198,20 +198,17 @@ function terminateProcessTree(child) {
}
}

// Capture the machine-readable plugin MCP inventory through a trusted absolute
// executable resolved from PATH. Prefer Copilot directly; if Agency is the only
// installed entry point, use its existing Copilot resolver.
// Capture the underlying Copilot plugin inventory directly. Agency repo mode
// separately suppresses its own default/config plugins, so discovery does not
// need a wrapper process that can leave inherited pipes or descendants behind.
function capturePluginMcpJson(workshopDir, agent) {
return new Promise((resolve) => {
const command = agent.useAgency ? agent.agencyCommand : agent.copilotCommand;
const command = agent.copilotCommand;
if (!command) {
resolve(null);
return;
}
const args = agent.useAgency
? ["copilot", "--no-default-mcps",
"plugins", "list", "--kind", "mcp", "--scope", "plugin", "--json"]
: ["plugins", "list", "--kind", "mcp", "--scope", "plugin", "--json"];
const args = ["plugins", "list", "--kind", "mcp", "--scope", "plugin", "--json"];
const shim = process.platform === "win32" && /\.(cmd|bat)$/i.test(command);
if (shim && !isSafeWindowsCmdShim(command)) {
resolve(null);
Expand Down Expand Up @@ -271,8 +268,7 @@ function capturePluginMcpJson(workshopDir, agent) {
}

async function discoverPluginMcpNames(workshopDir, agent) {
const cacheKey = `${workshopDir}\0${agent.useAgency ? "agency" : "copilot"}\0` +
`${agent.useAgency ? agent.agencyCommand : agent.copilotCommand}`;
const cacheKey = `${workshopDir}\0${agent.copilotCommand || "missing"}`;
const cached = mcpDiscoveryCache.get(cacheKey);
if (cached && cached.expiresAt > Date.now()) return cached.value;

Expand All @@ -290,7 +286,8 @@ async function discoverPluginMcpNames(workshopDir, agent) {

// Preserve the existing Agency-aware launch and layer the repo profile on top.
// Repo mode suppresses ambient plugin MCPs; connected mode keeps today's tool
// surface. Discovery fails open to connected behavior.
// surface. Plugin discovery fails open, while Agency repo mode still suppresses
// Agency's own default MCPs.
async function deskAgentArgv(deskName, workshopDir, profile) {
const resolved = resolveDeskAgent(workshopDir);
if (!resolved) return null;
Expand Down
5 changes: 4 additions & 1 deletion .github/extensions/signals-dashboard/launch-profile.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,11 @@ export function buildDeskAgentArgv({
? [agencyCommand, "copilot"]
: [copilotCommand, "--name", deskName];

if (profile === "repo" && discoverySucceeded) {
if (profile === "repo") {
if (useAgency) argv.push("--no-default-mcps");
}

if (profile === "repo" && discoverySucceeded) {
for (const name of pluginMcpNames) {
if (SAFE_MCP_NAME.test(name)) argv.push("--disable-mcp-server", name);
}
Expand Down
4 changes: 2 additions & 2 deletions .github/extensions/signals-dashboard/launch-profile.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ test("builds a plain Copilot repo profile without Agency-only flags", () => {
]);
});

test("connected and discovery-failure launches preserve the existing tool surface", () => {
test("connected preserves tools while Agency discovery failure still removes defaults", () => {
assert.deepEqual(buildDeskAgentArgv({
deskName: "cost-desk",
workshopDir: "/workshop",
Expand All @@ -137,6 +137,6 @@ test("connected and discovery-failure launches preserve the existing tool surfac
pluginMcpNames: [],
discoverySucceeded: false,
}), [
"agency", "copilot", "--add-dir", "/workshop",
"agency", "copilot", "--no-default-mcps", "--add-dir", "/workshop",
]);
});
Loading