@tryaura/aura-cli 0.3.1 → 0.4.0

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.
@@ -1,4 +1,4 @@
1
- import { A as displayPath, C as isRecord$4, D as SHARED_INSTRUCTIONS_TEMPLATE, E as AuraManifestError, S as errorMessage$1, T as resolveAuraManifestPath, _ as assertAuraManifestWritable, a as planDesiredMcpConvergence, b as parseAuraManifest, c as rememberMcpConvergence, d as sharedSkillsRoot, g as hashContent, h as stripLegacyManagedBlock, k as pluralize, m as planSharedSkillTreeUpdate, n as appendInstructionFragments, p as managedContentRevisionStatus, r as forgetMcpPlans, t as planSharedInstructionLink, u as planSkillDeployment, v as createAuraManifestWriteOperation, w as AURA_MANIFEST_PATH, x as errorCode, y as createEmptyAuraManifest } from "./shared-link-plan-AcSkw9bO.js";
1
+ import { A as displayPath, C as isRecord$4, D as SHARED_INSTRUCTIONS_TEMPLATE, E as AuraManifestError, S as errorMessage$1, T as resolveAuraManifestPath, _ as assertAuraManifestWritable, a as planDesiredMcpConvergence, b as parseAuraManifest, c as rememberMcpConvergence, d as sharedSkillsRoot, g as hashContent, h as stripLegacyManagedBlock, k as pluralize, m as planSharedSkillTreeUpdate, n as appendInstructionFragments, p as managedContentRevisionStatus, r as forgetMcpPlans, t as planSharedInstructionLink, u as planSkillDeployment, v as createAuraManifestWriteOperation, w as AURA_MANIFEST_PATH, x as errorCode, y as createEmptyAuraManifest } from "./shared-link-plan-DMijyUdG.js";
2
2
  import { COMMAND_NOT_FOUND_EXIT_CODE, DEFAULT_EXEC_TIMEOUT_MS, DEFAULT_HTTP_TIMEOUT_MS, MAX_EXEC_OUTPUT_CHARACTERS, MAX_EXEC_TIMEOUT_MS, MAX_HTTP_RESPONSE_BYTES, MAX_HTTP_TIMEOUT_MS, McpWriteError, NOT_EXECUTABLE_EXIT_CODE, OUTPUT_LIMIT_EXIT_CODE, SHARED_INSTRUCTIONS_TEMPLATE_TOKEN, TIMEOUT_EXIT_CODE, defineOwnProperty, detectExecutable, hasMcpRedaction, jsonPropertyPath, mcpEnvironmentVariableNames, mcpServerNameProblem, normalizeMcpServerDefinition, parseMcpServerDefinition, parseMcpServerManifest, parseMcpServerManifestValue, parseSkillFrontmatter, parseSkillReferences, resolveMcpSecretNameCollisions, resolveSkillDirectory, splitSourceLines } from "@tryaura/aura-sdk";
3
3
  import { basename, delimiter, dirname, isAbsolute, join, posix, relative, resolve, sep, win32 } from "node:path";
4
4
  import { Buffer as Buffer$1, isUtf8 } from "node:buffer";
@@ -931,25 +931,21 @@ function backupRoot(homeDir) {
931
931
  /**
932
932
  * Determines where a plan may write.
933
933
  *
934
- * The workspace is always one root. The rest are derived from what the detected adapters declared
935
- * as global-scope configuration, so the writable surface of the home directory is exactly the
934
+ * Roots are derived only from Aura's shared home directory and what detected adapters declared as
935
+ * global-scope configuration, so the writable surface of the home directory is exactly the
936
936
  * applications Aura found rather than a hardcoded guess. A declared file contributes its own
937
937
  * directory — `~/.claude/CLAUDE.md` yields `~/.claude`, not `~` — which keeps an adapter that reads
938
938
  * something under a shared directory such as `~/.config/<app>` from opening `~/.config` wholesale.
939
939
  */
940
- function resolveAllowedRoots(model, managedHomeRoots) {
940
+ function resolveAllowedRoots(model) {
941
941
  const homeDir = resolve(model.homeDir);
942
942
  const roots = /* @__PURE__ */ new Map();
943
- add(roots, {
944
- exact: false,
945
- path: resolve(model.projectRoot ?? model.cwd)
946
- });
947
943
  const sharedDirectory = dirname(resolve(model.sharedInstructions.path));
948
944
  if (isStrictDescendant(homeDir, sharedDirectory)) add(roots, {
949
945
  exact: false,
950
946
  path: sharedDirectory
951
947
  });
952
- for (const root of managedHomeRoots === void 0 ? deriveManagedHomeRoots(model, homeDir) : validateManagedHomeRoots(managedHomeRoots, homeDir)) add(roots, root);
948
+ for (const root of deriveManagedHomeRoots(model, homeDir)) add(roots, root);
953
949
  return Object.freeze([...roots.values()]);
954
950
  }
955
951
  /**
@@ -1002,17 +998,6 @@ function rootsForSpec(spec, homeDir) {
1002
998
  path
1003
999
  }];
1004
1000
  }
1005
- function validateManagedHomeRoots(managedHomeRoots, homeDir) {
1006
- return managedHomeRoots.map((candidate) => {
1007
- if (!isAbsolute(candidate)) throw new FixPlanError("invalid-options", `managedHomeRoots must contain absolute paths: ${candidate}`, { path: candidate });
1008
- const path = resolve(candidate);
1009
- if (!isStrictDescendant(homeDir, path)) throw new FixPlanError("invalid-options", `managedHomeRoots must sit strictly inside ${homeDir}: ${candidate}`, { path: candidate });
1010
- return {
1011
- exact: false,
1012
- path
1013
- };
1014
- });
1015
- }
1016
1001
  function add(roots, root) {
1017
1002
  const existing = roots.get(root.path);
1018
1003
  if (existing === void 0 || existing.exact && !root.exact) roots.set(root.path, root);
@@ -1109,12 +1094,12 @@ async function mapWithConcurrency(items, limit, run) {
1109
1094
  //#endregion
1110
1095
  //#region ../core/src/fix-plan/path-policy.ts
1111
1096
  /** Resolves the roots and filesystem traits a plan is validated against. */
1112
- async function createPathPolicy(model, managedHomeRoots) {
1097
+ async function createPathPolicy(model) {
1113
1098
  const sensitivity = await detectCaseSensitivity(resolve(model.projectRoot ?? model.cwd));
1114
1099
  return {
1115
1100
  caseInsensitive: sensitivity !== "sensitive",
1116
1101
  reservedRoots: Object.freeze([backupRoot(model.homeDir)]),
1117
- roots: resolveAllowedRoots(model, managedHomeRoots),
1102
+ roots: resolveAllowedRoots(model),
1118
1103
  rootsCaseInsensitive: sensitivity === "insensitive"
1119
1104
  };
1120
1105
  }
@@ -2878,7 +2863,7 @@ function decodeUtf8(content) {
2878
2863
  //#endregion
2879
2864
  //#region ../core/src/fix-plan/prepare.ts
2880
2865
  async function prepareOperations(options) {
2881
- const policy = await createPathPolicy(options.model, options.managedHomeRoots);
2866
+ const policy = await createPathPolicy(options.model);
2882
2867
  const validated = await validatePlanPaths(options.plan, policy);
2883
2868
  const budget = { remaining: MAX_RETAINED_PLAN_BYTES };
2884
2869
  const operations = [];
@@ -3397,7 +3382,7 @@ async function undoFixPlan(options) {
3397
3382
  if (options.backupId !== void 0) throw new FixPlanError("backup-error", `no undo journal entry named ${options.backupId}`);
3398
3383
  return Object.freeze({ status: "nothing-to-undo" });
3399
3384
  }
3400
- const policy = await createPathPolicy(options.model, options.managedHomeRoots);
3385
+ const policy = await createPathPolicy(options.model);
3401
3386
  return withJournalLock(root, options.now, async () => {
3402
3387
  const selection = await select(root, options);
3403
3388
  if (selection === void 0) return Object.freeze({ status: "nothing-to-undo" });
@@ -3748,50 +3733,32 @@ function portableSkillFilePathKey(path) {
3748
3733
  //#endregion
3749
3734
  //#region ../core/src/workspace/shared-links.ts
3750
3735
  const GLOBAL_PREFIX = "~/";
3751
- const PROJECT_PREFIX = "./";
3752
3736
  const SHARED_INSTRUCTIONS_SEGMENTS = Object.freeze(["agents", "AGENTS.md"]);
3753
3737
  const SHARED_INSTRUCTIONS_HOME_REFERENCE = "~/agents/AGENTS.md";
3754
- const PROJECT_SHARED_INSTRUCTIONS_FILE = "AGENTS.md";
3755
3738
  const SHARED_LINK_KINDS = /* @__PURE__ */ new Set([
3756
3739
  "import-line",
3757
3740
  "native-copy",
3758
3741
  "symlink"
3759
3742
  ]);
3760
- const GLOBAL_SLOT = Object.freeze({
3761
- name: "sharedLink",
3762
- scope: "global"
3763
- });
3764
- const PROJECT_SLOT = Object.freeze({
3765
- name: "projectSharedLink",
3766
- scope: "project"
3767
- });
3743
+ /** The one adapter field a shared-link declaration can come from. */
3744
+ const SLOT_NAME = "sharedLink";
3768
3745
  /** Canonical shared-instruction path for one captured environment. */
3769
3746
  function sharedInstructionsPath(environment) {
3770
3747
  return join(environment.homeDir, ...SHARED_INSTRUCTIONS_SEGMENTS);
3771
3748
  }
3772
3749
  /**
3773
- * Canonical project shared-instruction path for one checkout.
3750
+ * Returns every declarative problem in a shared-link contribution.
3774
3751
  *
3775
- * Exported because the setup wizard has to name the same file core links adapters to. Two packages
3776
- * each spelling out `AGENTS.md` is how a link ends up pointing at a file setup never wrote.
3752
+ * The `~/` prefix is required rather than merely accepted. A declaration naming `./something` is
3753
+ * what let a home-scoped check demand a file inside whichever repository the user was standing in,
3754
+ * written with their home directory spelled out absolutely; Aura links only the home entry now, so
3755
+ * the prefix is the whole statement of where the file lives.
3777
3756
  */
3778
- function projectSharedInstructionsPath(projectRoot, cwd) {
3779
- return join(projectRoot ?? cwd, PROJECT_SHARED_INSTRUCTIONS_FILE);
3780
- }
3781
- /**
3782
- * Returns every declarative problem in a shared-link contribution to the given scope.
3783
- *
3784
- * The prefix is checked against the slot rather than merely being one of the two: a global
3785
- * declaration naming `./something` is what let a home-scoped check demand a file inside whichever
3786
- * repository the user was standing in, written with their home directory spelled out absolutely.
3787
- * Which slot an adapter fills is the whole statement of where the file lives.
3788
- */
3789
- function sharedLinkViolations(link, scope) {
3757
+ function sharedLinkViolations(link) {
3790
3758
  const violations = [];
3791
3759
  if (!SHARED_LINK_KINDS.has(link.kind)) violations.push(`kind "${String(link.kind)}" is not supported`);
3792
- const prefix = entryPrefix(scope);
3793
- const relative = typeof link.entryPath === "string" && link.entryPath.startsWith(prefix) ? link.entryPath.slice(prefix.length) : void 0;
3794
- if (relative === void 0) violations.push(`entryPath must begin with "${prefix}" at ${scope} scope`);
3760
+ const relative = typeof link.entryPath === "string" && link.entryPath.startsWith(GLOBAL_PREFIX) ? link.entryPath.slice(2) : void 0;
3761
+ if (relative === void 0) violations.push(`entryPath must begin with "${GLOBAL_PREFIX}"`);
3795
3762
  else if (relative.length === 0 || relative.includes("\\") || relative.includes("\0") || relative.split("/").some((segment) => segment.length === 0 || segment === "." || segment === "..")) violations.push("entryPath must be a normalized portable path without traversal");
3796
3763
  if (link.kind === "symlink") {
3797
3764
  if (link.lineTemplate !== void 0) violations.push("symlink declarations must not provide lineTemplate");
@@ -3802,51 +3769,36 @@ function sharedLinkViolations(link, scope) {
3802
3769
  }
3803
3770
  /** Resolves and verifies one adapter's shared-link declaration against its read-side files. */
3804
3771
  function resolveAdapterSharedLink(adapter, environment, files) {
3805
- return resolveSharedLink(adapter.sharedLink, GLOBAL_SLOT, environment, files, () => SHARED_INSTRUCTIONS_HOME_REFERENCE);
3806
- }
3807
- function resolveAdapterProjectSharedLink(adapter, environment, files, projectRoot) {
3808
- const target = projectSharedInstructionsPath(projectRoot, environment.cwd);
3809
- return resolveSharedLink(adapter.projectSharedLink, PROJECT_SLOT, environment, files, (entryPath) => portableRelativePath(entryPath, target));
3772
+ return resolveSharedLink(adapter.sharedLink, environment, files);
3810
3773
  }
3811
3774
  /**
3812
- * Resolves one declaration, naming the shared source the way its own scope can survive.
3775
+ * Resolves one declaration, naming the shared source the way a home entry can survive.
3813
3776
  *
3814
- * A home entry names the source through `~`, which is the same string on every machine the user
3815
- * owns. A project entry names it relative to itself, so the file it produces is one the whole team
3816
- * can commit. Nothing here can write a machine-specific absolute path into a repository, because
3817
- * the slot decides both halves at once.
3777
+ * The entry names the source through `~`, which is the same string on every machine the user owns.
3818
3778
  */
3819
- function resolveSharedLink(declaration, slot, environment, files, targetReference) {
3779
+ function resolveSharedLink(declaration, environment, files) {
3820
3780
  if (declaration === void 0) return;
3821
- const entryPath = resolveSharedEntry(declaration, slot, environment, files);
3781
+ const entryPath = resolveSharedEntry(declaration, environment, files);
3822
3782
  if (declaration.kind === "symlink") return {
3823
3783
  entryPath,
3824
3784
  kind: declaration.kind,
3825
- scope: slot.scope
3785
+ scope: "global"
3826
3786
  };
3827
3787
  return {
3828
- content: declaration.lineTemplate?.replace(SHARED_INSTRUCTIONS_TEMPLATE_TOKEN, targetReference(entryPath)),
3788
+ content: declaration.lineTemplate?.replace(SHARED_INSTRUCTIONS_TEMPLATE_TOKEN, SHARED_INSTRUCTIONS_HOME_REFERENCE),
3829
3789
  entryPath,
3830
3790
  kind: declaration.kind,
3831
- scope: slot.scope
3791
+ scope: "global"
3832
3792
  };
3833
3793
  }
3834
- function resolveSharedEntry(declaration, slot, environment, files) {
3835
- const violations = sharedLinkViolations(declaration, slot.scope);
3836
- if (violations.length > 0) throw new Error(`declares an invalid ${slot.name}: ${violations.join("; ")}`);
3837
- const global = slot.scope === "global";
3838
- const relative = declaration.entryPath.slice(entryPrefix(slot.scope).length);
3839
- const entryPath = join(global ? environment.homeDir : environment.cwd, ...relative.split("/"));
3840
- if (![...files.values()].some((file) => resolve(file.spec.path) === resolve(entryPath) && file.spec.scope === slot.scope)) throw new Error(`declares ${slot.name} entry ${entryPath}, but its files() result did not declare that path at ${slot.scope} scope`);
3794
+ function resolveSharedEntry(declaration, environment, files) {
3795
+ const violations = sharedLinkViolations(declaration);
3796
+ if (violations.length > 0) throw new Error(`declares an invalid ${SLOT_NAME}: ${violations.join("; ")}`);
3797
+ const relative = declaration.entryPath.slice(2);
3798
+ const entryPath = join(environment.homeDir, ...relative.split("/"));
3799
+ if (![...files.values()].some((file) => resolve(file.spec.path) === resolve(entryPath) && file.spec.scope === "global")) throw new Error(`declares ${SLOT_NAME} entry ${entryPath}, but its files() result did not declare that path at global scope`);
3841
3800
  return entryPath;
3842
3801
  }
3843
- function portableRelativePath(entryPath, targetPath) {
3844
- const path = relative(dirname(entryPath), targetPath).replaceAll("\\", "/");
3845
- return path.startsWith(".") ? path : `./${path}`;
3846
- }
3847
- function entryPrefix(scope) {
3848
- return scope === "global" ? GLOBAL_PREFIX : PROJECT_PREFIX;
3849
- }
3850
3802
  function countToken(template) {
3851
3803
  return template.split(SHARED_INSTRUCTIONS_TEMPLATE_TOKEN).length - 1;
3852
3804
  }
@@ -3866,6 +3818,41 @@ function toSharedInstructions(path, contents) {
3866
3818
  problem
3867
3819
  };
3868
3820
  }
3821
+ //#endregion
3822
+ //#region ../core/src/plugin-validation-links.ts
3823
+ /**
3824
+ * Validates an adapter's shared-instruction link declaration.
3825
+ *
3826
+ * Two rules, because the contract removed one field and constrained the other. A plugin built
3827
+ * against the previous contract still carries `projectSharedLink`; `apiVersion` already refuses
3828
+ * that plugin, and naming the property is what tells its author which one to delete.
3829
+ */
3830
+ function collectSharedLinkDeclarationViolations(state, adapter, pluginLabel) {
3831
+ if ("projectSharedLink" in adapter) state.violations.push(`${pluginLabel} adapter "${adapter.id}" declares removed projectSharedLink; Aura manages only global shared-instruction links. Remove this property.`);
3832
+ if (adapter.sharedLink === void 0) return;
3833
+ for (const violation of sharedLinkViolations(adapter.sharedLink)) state.violations.push(`${pluginLabel} adapter "${adapter.id}" declares invalid sharedLink: ${violation}.`);
3834
+ }
3835
+ //#endregion
3836
+ //#region ../core/src/plugin-validation-skills.ts
3837
+ /** Rejects skill destinations that are empty, duplicated, or outside the user's home directory. */
3838
+ function collectSkillDirectoryViolations(state, adapter, pluginLabel) {
3839
+ const directories = adapter.capabilities?.skills?.directories;
3840
+ if (directories === void 0) return;
3841
+ if (directories.length === 0) {
3842
+ state.violations.push(`${pluginLabel} adapter "${adapter.id}" declares Agent Skills support without a global skills directory.`);
3843
+ return;
3844
+ }
3845
+ const ids = /* @__PURE__ */ new Set();
3846
+ for (const directory of directories) {
3847
+ if (ids.has(directory.id)) state.violations.push(`${pluginLabel} adapter "${adapter.id}" declares duplicate skills directory ID "${directory.id}".`);
3848
+ ids.add(directory.id);
3849
+ if (!isGlobalSkillPath(directory.entryPath)) state.violations.push(`${pluginLabel} adapter "${adapter.id}" declares invalid global skills directory ${directory.entryPath}.`);
3850
+ }
3851
+ }
3852
+ function isGlobalSkillPath(entryPath) {
3853
+ const relative = entryPath.startsWith("~/") ? entryPath.slice(2) : void 0;
3854
+ return relative !== void 0 && relative.length > 0 && !relative.includes("\\") && !relative.includes("\0") && relative.split("/").every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
3855
+ }
3869
3856
  /** Plugin ids become id namespaces, so `/` and anything shell- or path-surprising is refused. */
3870
3857
  const PLUGIN_ID_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
3871
3858
  function createRegistryState() {
@@ -3875,7 +3862,7 @@ function createRegistryState() {
3875
3862
  };
3876
3863
  }
3877
3864
  function isSupportedPlugin(candidate) {
3878
- return candidate.apiVersion === 1;
3865
+ return candidate.apiVersion === 2;
3879
3866
  }
3880
3867
  /** Validates each contribution's namespace and collects the ones that claimed their id. */
3881
3868
  function collectNamespaced(state, kind, contributions, plugin, collected) {
@@ -3913,15 +3900,8 @@ function collectAdapterViolations(state, adapters, plugin) {
3913
3900
  for (const adapter of adapters ?? []) {
3914
3901
  if (!PLUGIN_ID_PATTERN.test(adapter.id)) state.violations.push(`${formatPlugin(plugin)} contributes adapter ID "${adapter.id}", which is not a usable adapter ID; expected lowercase letters, digits, ".", "-", or "_", starting with a letter or digit.`);
3915
3902
  collectSharedLinkCapabilityViolations(state, adapter, plugin);
3916
- for (const [name, scope, link] of [[
3917
- "sharedLink",
3918
- "global",
3919
- adapter.sharedLink
3920
- ], [
3921
- "projectSharedLink",
3922
- "project",
3923
- adapter.projectSharedLink
3924
- ]]) if (link !== void 0) for (const violation of sharedLinkViolations(link, scope)) state.violations.push(`${formatPlugin(plugin)} adapter "${adapter.id}" declares invalid ${name}: ${violation}.`);
3903
+ collectSkillDirectoryViolations(state, adapter, formatPlugin(plugin));
3904
+ collectSharedLinkDeclarationViolations(state, adapter, formatPlugin(plugin));
3925
3905
  }
3926
3906
  }
3927
3907
  function collectSharedLinkCapabilityViolations(state, adapter, plugin) {
@@ -3954,8 +3934,8 @@ function claimId(state, kind, id, plugin) {
3954
3934
  return true;
3955
3935
  }
3956
3936
  function formatApiVersionViolation(candidate) {
3957
- const remedy = candidate.apiVersion > 1 ? "Upgrade Aura, or install a plugin release built against" : "Upgrade the plugin to a release built against";
3958
- return `${formatPlugin(candidate)} uses unsupported apiVersion ${candidate.apiVersion}; this Aura build supports apiVersion 1. ${remedy} apiVersion 1.`;
3937
+ const remedy = candidate.apiVersion > 2 ? "Upgrade Aura, or install a plugin release built against" : "Upgrade the plugin to a release built against";
3938
+ return `${formatPlugin(candidate)} uses unsupported apiVersion ${candidate.apiVersion}; this Aura build supports apiVersion 2. ${remedy} apiVersion 2.`;
3959
3939
  }
3960
3940
  function formatViolations(violations) {
3961
3941
  return [violations.length === 1 ? "Aura cannot build the plugin registry:" : `Aura cannot build the plugin registry (${violations.length} problems):`, ...violations.map((violation) => ` - ${violation}`)].join("\n");
@@ -5164,9 +5144,8 @@ function normalizeVersion(version) {
5164
5144
  /**
5165
5145
  * Splits desired servers into the ones Aura may write and the collisions a person has to settle.
5166
5146
  *
5167
- * Scope is part of identity here. A server named `docs` in a project `.mcp.json` is not the `docs`
5168
- * the manifest wants in user-level configuration, and treating them as one either blocks a write
5169
- * that would not have collided or skips one that never happened.
5147
+ * Desired servers are global-only. A server named `docs` in a project `.mcp.json` remains a
5148
+ * read-only observation and cannot collide with the global entry Aura manages.
5170
5149
  */
5171
5150
  function classifyDesired(desired, ledgerNames, state) {
5172
5151
  const ledger = new Set(ledgerNames);
@@ -5185,11 +5164,11 @@ function classifyDesired(desired, ledgerNames, state) {
5185
5164
  /** `owned` to write it, a blocker to refuse, `undefined` when the config already satisfies it. */
5186
5165
  function collisionBlocker(entry, ledger, state) {
5187
5166
  if (ledger.has(entry.name)) return "owned";
5188
- const sameName = (candidate) => candidate.name === entry.name && candidate.scope === entry.scope;
5167
+ const sameName = (candidate) => candidate.name === entry.name && candidate.scope === "global";
5189
5168
  const unusable = state.unusable.find(sameName);
5190
5169
  if (unusable !== void 0) return {
5191
- message: unusable.reason === "disabled" ? `MCP server ${entry.name} is already declared in this application's ${entry.scope} configuration but is turned off there. Remove or enable it, then run the fix again.` : `MCP server ${entry.name} is already declared in this application's ${entry.scope} configuration in a form Aura does not recognize, so Aura left it unchanged.`,
5192
- scope: entry.scope,
5170
+ message: unusable.reason === "disabled" ? `MCP server ${entry.name} is already declared in this application's global configuration but is turned off there. Remove or enable it, then run the fix again.` : `MCP server ${entry.name} is already declared in this application's global configuration in a form Aura does not recognize, so Aura left it unchanged.`,
5171
+ scope: "global",
5193
5172
  sourceId: unusable.sourceId
5194
5173
  };
5195
5174
  const existing = state.servers.filter(sameName);
@@ -5198,7 +5177,7 @@ function collisionBlocker(entry, ledger, state) {
5198
5177
  if ("message" in normalized) return normalized;
5199
5178
  return existing.every((server) => isDeepStrictEqual(server.transport, normalized.transport)) ? void 0 : {
5200
5179
  message: `MCP server ${entry.name} already exists outside Aura's ownership ledger and differs from the manifest.`,
5201
- scope: entry.scope
5180
+ scope: "global"
5202
5181
  };
5203
5182
  }
5204
5183
  /**
@@ -5213,7 +5192,7 @@ function normalizeDesired(entry) {
5213
5192
  } catch (error) {
5214
5193
  return {
5215
5194
  message: error instanceof McpWriteError ? `MCP server ${entry.name} cannot be written as the manifest defines it: ${error.message}` : `MCP server ${entry.name} has a manifest definition Aura cannot represent.`,
5216
- scope: entry.scope
5195
+ scope: "global"
5217
5196
  };
5218
5197
  }
5219
5198
  }
@@ -5227,28 +5206,25 @@ function createAppMcpConvergence(adapter, files, state) {
5227
5206
  const targets = [...files.values()].filter((file) => file.spec.kind === "mcp");
5228
5207
  const classified = classifyDesired(desired, ledgerNames, state);
5229
5208
  if (classified.blockers.length > 0) return blocked(classified.blockers);
5230
- const scopes = ["global", "project"].map((scope) => planScope$1(adapter, writer, targets, classified.owned, ledgerNames, scope, state.secretSightings));
5231
- const blockers = scopes.flatMap((result) => result.blockers);
5232
- const operations = scopes.flatMap((result) => result.operations);
5233
- return blockers.length > 0 ? blocked(blockers) : {
5209
+ const planned = planGlobalTarget(adapter, writer, targets, classified.owned, ledgerNames, state.secretSightings);
5210
+ return planned.blockers.length > 0 ? blocked(planned.blockers) : {
5234
5211
  blockers: [],
5235
- operations,
5212
+ operations: planned.operations,
5236
5213
  ownedNames: [...new Set(classified.owned.map((entry) => entry.name))].sort()
5237
5214
  };
5238
5215
  };
5239
5216
  }
5240
- function planScope$1(adapter, writer, targets, desired, ledgerNames, scope, sightings) {
5241
- const scopedDesired = desired.filter((entry) => entry.scope === scope);
5242
- const scopedTargets = targets.filter((target) => target.spec.scope === scope);
5243
- if (scopedDesired.length > 0 && scopedTargets.length === 0) return blockedScope(`${adapter.displayName} has no ${scope}-scope MCP configuration target.`, scope);
5244
- if (scopedTargets.length > 1) return blockedScope(`${adapter.displayName} declares more than one ${scope}-scope MCP write target.`, scope);
5245
- const target = scopedTargets[0];
5217
+ function planGlobalTarget(adapter, writer, targets, desired, ledgerNames, sightings) {
5218
+ const globalTargets = targets.filter((target) => target.spec.scope === "global");
5219
+ if (desired.length > 0 && globalTargets.length === 0) return blockedScope(`${adapter.displayName} has no global MCP configuration target.`, "global");
5220
+ if (globalTargets.length > 1) return blockedScope(`${adapter.displayName} declares more than one global MCP write target.`, "global");
5221
+ const target = globalTargets[0];
5246
5222
  return target === void 0 ? {
5247
5223
  blockers: [],
5248
5224
  operations: []
5249
- } : writeScopeTarget(adapter, writer, target, scopedDesired, ledgerNames, scope, sightings);
5225
+ } : writeGlobalTarget(adapter, writer, target, desired, ledgerNames, sightings);
5250
5226
  }
5251
- function writeScopeTarget(adapter, writer, target, desired, ledgerNames, scope, sightings) {
5227
+ function writeGlobalTarget(adapter, writer, target, desired, ledgerNames, sightings) {
5252
5228
  if (!needsTargetWrite(target, desired, ledgerNames)) return {
5253
5229
  blockers: [],
5254
5230
  operations: []
@@ -5257,7 +5233,7 @@ function writeScopeTarget(adapter, writer, target, desired, ledgerNames, scope,
5257
5233
  if (unwritable !== void 0) return {
5258
5234
  blockers: [{
5259
5235
  ...unwritable,
5260
- scope,
5236
+ scope: "global",
5261
5237
  sourceId: target.spec.id
5262
5238
  }],
5263
5239
  operations: []
@@ -5267,7 +5243,7 @@ function writeScopeTarget(adapter, writer, target, desired, ledgerNames, scope,
5267
5243
  blockers: [{
5268
5244
  message: written.refusal,
5269
5245
  path: target.spec.path,
5270
- scope,
5246
+ scope: "global",
5271
5247
  sourceId: target.spec.id
5272
5248
  }],
5273
5249
  operations: []
@@ -5276,14 +5252,14 @@ function writeScopeTarget(adapter, writer, target, desired, ledgerNames, scope,
5276
5252
  blockers: [{
5277
5253
  message: `${adapter.displayName}'s MCP configuration at ${target.spec.path} is larger than Aura will rewrite in one operation, so Aura left it unchanged.`,
5278
5254
  path: target.spec.path,
5279
- scope,
5255
+ scope: "global",
5280
5256
  sourceId: target.spec.id
5281
5257
  }],
5282
5258
  operations: []
5283
5259
  };
5284
5260
  const operation = {
5285
5261
  content: written.content,
5286
- mode: scope === "global" ? 384 : 420,
5262
+ mode: 384,
5287
5263
  path: target.spec.path,
5288
5264
  precondition: targetPrecondition(target),
5289
5265
  type: "write"
@@ -5526,11 +5502,9 @@ async function scanAdapter(adapter, context) {
5526
5502
  return { diagnostics: [failure$2(adapter, "files", error)] };
5527
5503
  }
5528
5504
  diagnostics.push(...discovery.diagnostics);
5529
- let projectSharedLink;
5530
5505
  let sharedLink;
5531
5506
  try {
5532
5507
  sharedLink = resolveAdapterSharedLink(adapter, context.environment, discovery.files);
5533
- projectSharedLink = resolveAdapterProjectSharedLink(adapter, context.environment, discovery.files, await context.projectRoot);
5534
5508
  } catch (error) {
5535
5509
  diagnostics.push(failure$2(adapter, "files", error));
5536
5510
  }
@@ -5554,9 +5528,8 @@ async function scanAdapter(adapter, context) {
5554
5528
  mcpServers,
5555
5529
  metadata: snapshot.metadata,
5556
5530
  skills: snapshot.skills,
5557
- skillDirectories: (adapter.capabilities?.skills?.directories ?? []).map((directory) => resolveSkillDirectory(directory, context.environment.homeDir, context.environment.cwd)),
5531
+ skillDirectories: (adapter.capabilities?.skills?.directories ?? []).map((directory) => resolveSkillDirectory(directory, context.environment.homeDir)),
5558
5532
  sourceFiles: [...discovery.files.values()].filter((file) => file.spec.kind !== "probe").map(toStatus),
5559
- ...projectSharedLink === void 0 ? {} : { projectSharedLink },
5560
5533
  ...sharedLink === void 0 ? {} : { sharedLink },
5561
5534
  support: evaluateSupport(adapter.supportedRange, detection.version),
5562
5535
  ...adapter.synthetic === void 0 ? {} : { synthetic: adapter.synthetic },
@@ -9389,7 +9362,7 @@ function applyRequiredMcpServers(model, config) {
9389
9362
  model
9390
9363
  };
9391
9364
  const manifest = model.manifest.value;
9392
- const configured = new Set(manifest.mcpServers.map((server) => `${server.scope}\0${server.name}`));
9365
+ const configured = new Set(manifest.mcpServers.map((server) => server.name));
9393
9366
  const configuredCatalogIds = new Set(manifest.mcpServers.flatMap((server) => server.catalogId === void 0 ? [] : [server.catalogId]));
9394
9367
  const diagnostics = [];
9395
9368
  const required = [];
@@ -9410,7 +9383,7 @@ function applyRequiredMcpServers(model, config) {
9410
9383
  continue;
9411
9384
  }
9412
9385
  const name = catalog.manifest.serverName;
9413
- if (configured.has(`global\0${name}`)) {
9386
+ if (configured.has(name)) {
9414
9387
  diagnostics.push(note(`is already configured as "${name}", so your own settings were kept`, catalog.id, selection));
9415
9388
  continue;
9416
9389
  }
@@ -9424,7 +9397,6 @@ function applyRequiredMcpServers(model, config) {
9424
9397
  catalogId: catalog.id,
9425
9398
  name,
9426
9399
  requiredBy: selection.provenance.label,
9427
- scope: "global",
9428
9400
  transport: catalog.manifest.transportTemplate
9429
9401
  }));
9430
9402
  }
@@ -9704,10 +9676,7 @@ function isBundledSkillSelection(skill) {
9704
9676
  /** Final instruction handling only; paths, sources, and duplicate choices stop here. */
9705
9677
  function instructionActions(selections) {
9706
9678
  if (selections === void 0) return [];
9707
- return [selections.global, ...selections.project === void 0 ? [] : [selections.project]].map(({ action, scope }) => ({
9708
- action,
9709
- scope
9710
- }));
9679
+ return [{ action: selections.global.action }];
9711
9680
  }
9712
9681
  /**
9713
9682
  * Per-check state and severity counts for every executed check, ordered by check ID.
@@ -13876,7 +13845,7 @@ function planLinks$1(context, scopeSelections, archived, ownership, manualSteps)
13876
13845
  }
13877
13846
  function planAppLinks(context, app, scopeSelections, archived, ownership, manualSteps) {
13878
13847
  return scopeSelections.flatMap((selection) => {
13879
- const link = selection.scope === "global" ? app.sharedLink : app.projectSharedLink;
13848
+ const link = app.sharedLink;
13880
13849
  if (link === void 0) return [];
13881
13850
  const outcome = planSharedInstructionLink(app, context.model, {
13882
13851
  link,
@@ -13903,12 +13872,12 @@ function planAppLinks(context, app, scopeSelections, archived, ownership, manual
13903
13872
  * only once that entry is merged here and archived. The wizard does not offer an entry already
13904
13873
  * pointing at the target, so leaving this to the selection strands the app on every run.
13905
13874
  */
13906
- function mandatoryEntryPaths(context, scope) {
13875
+ function mandatoryEntryPaths(context) {
13907
13876
  const managedIds = new Set(managedAppIdList(context));
13908
13877
  const paths = /* @__PURE__ */ new Set();
13909
13878
  for (const app of context.model.apps) {
13910
13879
  if (app.synthetic === true || !managedIds.has(app.adapterId)) continue;
13911
- const link = scope === "global" ? app.sharedLink : app.projectSharedLink;
13880
+ const link = app.sharedLink;
13912
13881
  if (link?.kind === "symlink") paths.add(resolve(link.entryPath));
13913
13882
  }
13914
13883
  return paths;
@@ -13920,7 +13889,7 @@ function mandatoryEntryPaths(context, scope) {
13920
13889
  * archives them.
13921
13890
  */
13922
13891
  function requiredEntries(context, selection, inventory) {
13923
- const required = mandatoryEntryPaths(context, selection.scope);
13892
+ const required = mandatoryEntryPaths(context);
13924
13893
  return inventory.filter((source) => source.scope === selection.scope && required.has(resolve(source.path)));
13925
13894
  }
13926
13895
  /** Folds the required entries into the selection, so the merge and the archive both see them. */
@@ -13955,7 +13924,7 @@ function canonicalSourcePath(document) {
13955
13924
  */
13956
13925
  function isAuraArtifact(document, model) {
13957
13926
  const path = resolve(document.path);
13958
- return model.apps.some((app) => [app.sharedLink, app.projectSharedLink].some((link) => link !== void 0 && resolve(link.entryPath) === path && matchesLink(document, link)));
13927
+ return model.apps.some((app) => app.sharedLink !== void 0 && resolve(app.sharedLink.entryPath) === path && matchesLink(document, app.sharedLink));
13959
13928
  }
13960
13929
  function matchesLink(document, link) {
13961
13930
  if (link.kind === "native-copy") return document.content === link.content;
@@ -13969,7 +13938,7 @@ function matchesLink(document, link) {
13969
13938
  * would otherwise re-walk every application to rediscover the same handful of links.
13970
13939
  */
13971
13940
  function importLineLinks(model) {
13972
- return model.apps.flatMap((app) => [app.sharedLink, app.projectSharedLink]).filter((link) => link?.kind === "import-line" && link.content !== void 0);
13941
+ return model.apps.map((app) => app.sharedLink).filter((link) => link?.kind === "import-line" && link.content !== void 0);
13973
13942
  }
13974
13943
  /** Removes legacy marked links and a plain import Aura appended at the declared entry path. */
13975
13944
  function stripAuraInstructionArtifacts(content, path, links) {
@@ -14105,17 +14074,14 @@ function removeRanges(content, ranges) {
14105
14074
  //#endregion
14106
14075
  //#region src/setup/instructions.ts
14107
14076
  function instructionTargets(model) {
14108
- return {
14109
- global: resolve(model.sharedInstructions.path),
14110
- project: resolve(projectSharedInstructionsPath(model.projectRoot, model.cwd))
14111
- };
14077
+ return { global: resolve(model.sharedInstructions.path) };
14112
14078
  }
14113
14079
  function instructionInventory(model) {
14114
14080
  const targets = instructionTargets(model);
14115
14081
  const owned = new Set(model.manifest.status === "ready" ? Object.values(model.manifest.value.ownership).flatMap((entry) => entry.files.map((path) => resolve(path))) : []);
14116
14082
  const documents = /* @__PURE__ */ new Map();
14117
14083
  for (const document of model.instructionFiles) {
14118
- if ([resolve(document.path), canonicalSourcePath(document)].some((candidate) => candidate === targets.global || candidate === targets.project || owned.has(candidate)) || isAuraArtifact(document, model)) continue;
14084
+ if ([resolve(document.path), canonicalSourcePath(document)].some((candidate) => candidate === targets.global || owned.has(candidate)) || isAuraArtifact(document, model)) continue;
14119
14085
  const key = canonicalSourcePath(document);
14120
14086
  const current = documents.get(key);
14121
14087
  if (current === void 0 || document.content.length > current.content.length) documents.set(key, document);
@@ -14216,10 +14182,8 @@ function planInstructions(context) {
14216
14182
  const ownership = /* @__PURE__ */ new Map();
14217
14183
  const inventory = instructionInventory(context.model);
14218
14184
  const clusters = duplicateClusters(context.findings ?? []);
14219
- const scopeSelections = [selections.global, selections.project].filter((selection) => selection !== void 0 && selection.action !== "blocked" && selection.action !== "skip");
14220
- const linked = [];
14221
- for (const selection of scopeSelections) if (planScope(context, selection, inventory, clusters, state)) linked.push(selection);
14222
- const linkOperations = planLinks$1(context, linked, state.archived, ownership, state.manualSteps);
14185
+ const selection = selections.global;
14186
+ const linkOperations = planLinks$1(context, selection.action !== "blocked" && planScope(context, selection, inventory, clusters, state) ? [selection] : [], state.archived, ownership, state.manualSteps);
14223
14187
  for (const [path, archive] of state.archived) {
14224
14188
  const linkIndex = linkOperations.findIndex((operation) => resolve(primaryPath(operation)) === path);
14225
14189
  const link = linkIndex === -1 ? void 0 : linkOperations.splice(linkIndex, 1)[0];
@@ -14261,14 +14225,10 @@ function planScope(context, requested, inventory, clusters, state) {
14261
14225
  if (selection.action !== "consolidate") return true;
14262
14226
  const content = composeConsolidatedInstructions(chosen, selection, clusters, context.model, existing);
14263
14227
  if (content.trim().length === 0) {
14264
- if (selection.scope === "global") {
14265
- state.blockers.push({
14266
- path: selection.targetPath,
14267
- reason: "No selected instruction content is available to consolidate. Select a source, or choose the starter template."
14268
- });
14269
- return false;
14270
- }
14271
- state.manualSteps.push(`Configure ${selection.targetPath} on the next run: select at least one project source to consolidate, or choose the starter template. Aura wrote nothing there.`);
14228
+ state.blockers.push({
14229
+ path: selection.targetPath,
14230
+ reason: "No selected instruction content is available to consolidate. Select a source, or choose the starter template."
14231
+ });
14272
14232
  return false;
14273
14233
  }
14274
14234
  planConsolidatedTarget(context, selection, existing, content, state);
@@ -14452,7 +14412,7 @@ function withRequiredOverrides(manifest, requiredIds, overriddenIds) {
14452
14412
  * was available to receive it.
14453
14413
  */
14454
14414
  function unconfiguredRequirement(context, id) {
14455
- return context.interactive ? `Required MCP catalog entry ${id} could not be selected for a managed compatible application.` : `Required MCP catalog entry ${id} is not configured yet. Run setup interactively to choose its name, scope, and applications; later non-interactive runs re-apply what the manifest records.`;
14415
+ return context.interactive ? `Required MCP catalog entry ${id} could not be selected for a managed compatible application.` : `Required MCP catalog entry ${id} is not configured yet. Run setup interactively to choose its name and applications; later non-interactive runs re-apply what the manifest records globally.`;
14456
14416
  }
14457
14417
  function withMcpOwnership(manifest, appId, names) {
14458
14418
  const previous = manifest.ownership[appId];
@@ -16603,7 +16563,6 @@ function excerpt(sources, path, startLine, endLine) {
16603
16563
  //#region src/setup/steps/instruction-stages.ts
16604
16564
  const TEMPLATE_VALUE = "template";
16605
16565
  const CONSOLIDATE_VALUE = "consolidate";
16606
- const SKIP_VALUE = "skip";
16607
16566
  /**
16608
16567
  * The target's current text when this scope has nothing left to decide, otherwise undefined.
16609
16568
  *
@@ -16634,13 +16593,13 @@ function scopeStages(input) {
16634
16593
  return [
16635
16594
  {
16636
16595
  isApplicable: () => !input.blocked,
16637
- label: input.scope === "global" ? "Global" : "Project",
16596
+ label: "Personal",
16638
16597
  apply: (state, answers) => update(state, { action: settled(answers[actionId], offered, fallback) }),
16639
16598
  questions: (state) => input.blocked ? void 0 : [{
16640
16599
  id: actionId,
16641
16600
  initial: [draft(state).action ?? fallback],
16642
16601
  kind: "select",
16643
- label: input.scope === "global" ? "Global" : "Project",
16602
+ label: "Personal",
16644
16603
  options,
16645
16604
  prompt: `How should Aura configure ${input.targetPath}?`
16646
16605
  }]
@@ -16659,7 +16618,7 @@ function scopeStages(input) {
16659
16618
  label: source.path,
16660
16619
  value: source.path
16661
16620
  })),
16662
- prompt: `Which ${input.scope} instruction files should Aura consolidate?`
16621
+ prompt: "Which personal instruction files should Aura consolidate?"
16663
16622
  }] : void 0
16664
16623
  },
16665
16624
  {
@@ -16696,10 +16655,8 @@ function settled(answer, offered, fallback) {
16696
16655
  * advice, the mark and the cursor on row `1.` together, and leaves the rest of the menu in the
16697
16656
  * order it was built. A scope with nothing to combine recommends nothing and keeps that order.
16698
16657
  *
16699
- * The opt-out is offered on the project scope only. Declining the global scope would leave INS-001
16700
- * and INS-002 firing at error severity, so setup could not end on green — an answer the wizard
16701
- * offers should not be one the closing checklist then fails the run over. The project tier has no
16702
- * error-severity counterpart, so a declined project scope still ends green.
16658
+ * Personal instructions cannot be skipped because setup must leave applications connected to the
16659
+ * global shared source.
16703
16660
  */
16704
16661
  function actionOptions(input) {
16705
16662
  const options = [];
@@ -16719,11 +16676,6 @@ function actionOptions(input) {
16719
16676
  label: "Use starter template",
16720
16677
  value: TEMPLATE_VALUE
16721
16678
  });
16722
- if (input.scope === "project") options.push({
16723
- description: hasTargetContent(input) ? `Aura writes nothing here and adds no project-level link; ${basename(input.targetPath)} and anything already linking to it stay as they are.` : "Aura writes nothing here and adds no project-level link.",
16724
- label: "Skip project instructions",
16725
- value: SKIP_VALUE
16726
- });
16727
16679
  return recommendedFirst(options);
16728
16680
  }
16729
16681
  function hasTargetContent(input) {
@@ -16732,7 +16684,7 @@ function hasTargetContent(input) {
16732
16684
  //#endregion
16733
16685
  //#region src/setup/steps/instructions.ts
16734
16686
  /**
16735
- * The instructions step: one back-navigable chain of forms across both scopes.
16687
+ * The instructions step: one back-navigable chain of forms for personal instructions.
16736
16688
  *
16737
16689
  * Each scope contributes action → sources → duplicate review stages; a stage whose precondition no
16738
16690
  * longer holds (a non-consolidate action, no duplicated paragraphs left) simply disappears from
@@ -16742,9 +16694,8 @@ function hasTargetContent(input) {
16742
16694
  const instructionsStep = {
16743
16695
  gather: async (context, io) => {
16744
16696
  const inputs = scopeInputs(context);
16745
- const scopes = scopeList(inputs);
16746
- if (context.revisited !== true) for (const input of scopes) emitScopeNotes(input, io);
16747
- const stages = scopes.flatMap(scopeStages);
16697
+ if (context.revisited !== true) emitScopeNotes(inputs.global, io);
16698
+ const stages = scopeStages(inputs.global);
16748
16699
  const result = await runFormChain(stages, initialState(context), io, {
16749
16700
  entry: context.enteredBackward === true ? "end" : "start",
16750
16701
  flow: context.flow
@@ -16758,55 +16709,34 @@ const instructionsStep = {
16758
16709
  telemetryCategory: "instructions",
16759
16710
  title: "Instructions"
16760
16711
  };
16761
- /** Both scopes in flow order, which is the order notes are emitted and stages are chained in. */
16762
- function scopeList(inputs) {
16763
- return inputs.project === void 0 ? [inputs.global] : [inputs.global, inputs.project];
16764
- }
16765
- /** Folds both scopes' drafts into the step's selections, unoffered when it asked nothing to do it. */
16712
+ /** Folds the personal draft into the step's selections, unoffered when it asked nothing to do it. */
16766
16713
  function settle(context, inputs, result, unoffered) {
16767
- const project = inputs.project === void 0 ? void 0 : scopeSelection(inputs.project, result.project);
16768
16714
  const selections = {
16769
16715
  ...context.selections,
16770
- instructions: {
16771
- global: scopeSelection(inputs.global, result.global),
16772
- ...project === void 0 ? {} : { project }
16773
- }
16716
+ instructions: { global: scopeSelection(inputs.global, result.global) }
16774
16717
  };
16775
16718
  return unoffered ? {
16776
16719
  selections,
16777
16720
  unoffered: true
16778
16721
  } : selections;
16779
16722
  }
16780
- /** Everything both scopes need from the workspace; project is absent when it has nothing to do. */
16723
+ /** Everything personal instruction setup needs from the workspace. */
16781
16724
  function scopeInputs(context) {
16782
16725
  const inventory = instructionInventory(context.model);
16783
16726
  const targets = instructionTargets(context.model);
16784
16727
  const clusters = duplicateClusters(context.findings ?? []);
16785
- const global = {
16728
+ return { global: {
16786
16729
  blocked: context.model.sharedInstructions.problem !== void 0,
16787
16730
  clusters,
16788
16731
  scope: "global",
16789
16732
  sources: inventory.filter((source) => source.scope === "global"),
16790
16733
  targetContentValue: instructionTargetContent(context.model, "global", targets.global),
16791
16734
  targetPath: targets.global
16792
- };
16793
- const projectSources = inventory.filter((source) => source.scope === "project");
16794
- const projectContent = instructionTargetContent(context.model, "project", targets.project);
16795
- return {
16796
- global,
16797
- project: projectSources.length === 0 && projectContent === void 0 ? void 0 : {
16798
- blocked: false,
16799
- clusters,
16800
- scope: "project",
16801
- sources: projectSources,
16802
- targetContentValue: projectContent,
16803
- targetPath: targets.project
16804
- }
16805
- };
16735
+ } };
16806
16736
  }
16807
16737
  function scopeSelection(input, draft) {
16808
16738
  if (input.blocked) return inactiveSelection(input, "blocked");
16809
- if (draft.action !== "consolidate") return inactiveSelection(input, inactiveAction(draft.action, input.scope));
16739
+ if (draft.action !== "consolidate") return inactiveSelection(input, inactiveAction(draft.action));
16810
16740
  const selectedSources = draft.selectedSources ?? [];
16811
16741
  const relevant = relevantDuplicateClusters(selectedSources, input.clusters);
16812
16742
  return {
@@ -16824,9 +16754,9 @@ function scopeSelection(input, draft) {
16824
16754
  * INS-002 firing at error severity, so the action menu never offers it there; this mapping is the
16825
16755
  * second half of that rule, keeping an action off the menu from becoming one the planner obeys.
16826
16756
  */
16827
- function inactiveAction(action, scope) {
16757
+ function inactiveAction(action) {
16828
16758
  if (action === "template") return "template";
16829
- return action === "skip" && scope === "project" ? "skip" : "keep";
16759
+ return "keep";
16830
16760
  }
16831
16761
  function inactiveSelection(input, action) {
16832
16762
  return {
@@ -16840,10 +16770,7 @@ function inactiveSelection(input, action) {
16840
16770
  /** A re-entered step resumes from what this run already decided, not from cold-start defaults. */
16841
16771
  function initialState(context) {
16842
16772
  const existing = context.selections.instructions;
16843
- return {
16844
- global: toDraft(existing?.global),
16845
- project: toDraft(existing?.project)
16846
- };
16773
+ return { global: toDraft(existing?.global) };
16847
16774
  }
16848
16775
  function toDraft(selection) {
16849
16776
  if (selection === void 0 || selection.action === "blocked") return {};
@@ -16865,10 +16792,10 @@ function emitScopeNotes(input, io) {
16865
16792
  path: input.targetPath,
16866
16793
  scope: input.scope
16867
16794
  });
16868
- io.note(`${input.scope === "global" ? "Global" : "Project"} instructions already live in ${input.targetPath} (${size}); Aura found nothing else to consolidate and leaves the file as it is.`);
16795
+ io.note(`Personal instructions already live in ${input.targetPath} (${size}); Aura found nothing else to consolidate and leaves the file as it is.`);
16869
16796
  return;
16870
16797
  }
16871
- if (input.sources.length > 0) io.note(`Found ${describeSources(input.sources)} for ${input.scope} consolidation.`);
16798
+ if (input.sources.length > 0) io.note(`Found ${describeSources(input.sources)} for personal consolidation.`);
16872
16799
  }
16873
16800
  function describeSources(sources) {
16874
16801
  return sources.map((source) => `${basename(source.path)} (${describeInstructionSource(source)})`).join(" and ");
@@ -17057,47 +16984,27 @@ async function configureEntry(context, entry, taken, io) {
17057
16984
  return SETUP_BACK;
17058
16985
  }
17059
16986
  const defaultName = seed?.name ?? catalog?.serverName ?? "custom";
17060
- const defaultScope = seed?.scope ?? (entry.repo === true ? "project" : "global");
17061
16987
  const apps = appChoices(context, catalog?.supportedApps, seed?.apps ?? []);
17062
16988
  if (apps.eligible.length === 0 && (seed?.apps.length ?? 0) === 0) {
17063
16989
  io.note("No detected, managed, compatible application can receive this MCP server.");
17064
16990
  return;
17065
16991
  }
17066
16992
  let name = defaultName;
17067
- let scope = defaultScope;
17068
16993
  let selectedApps = seed === void 0 || seed.apps.length === 0 ? apps.eligible : seed.apps;
17069
16994
  for (;;) {
17070
- const result = await io.ask([
17071
- textQuestion("mcp-name", "Name", "Configuration name", name),
17072
- {
17073
- id: "mcp-scope",
17074
- initial: [scope],
17075
- kind: "select",
17076
- label: "Scope",
17077
- options: [{
17078
- label: "Global",
17079
- value: "global"
17080
- }, {
17081
- label: "Project",
17082
- value: "project"
17083
- }],
17084
- prompt: "Where should applications configure this server?"
17085
- },
17086
- {
17087
- id: "mcp-apps",
17088
- initial: selectedApps,
17089
- kind: "multiselect",
17090
- label: "Applications",
17091
- options: apps.options,
17092
- prompt: "Which applications should enable this server?"
17093
- }
17094
- ]);
16995
+ const result = await io.ask([textQuestion("mcp-name", "Name", "Configuration name", name), {
16996
+ id: "mcp-apps",
16997
+ initial: selectedApps,
16998
+ kind: "multiselect",
16999
+ label: "Applications",
17000
+ options: apps.options,
17001
+ prompt: "Which applications should enable this server?"
17002
+ }]);
17095
17003
  if (result === "aborted") return SETUP_ABORTED;
17096
17004
  if (result === "back") return SETUP_BACK;
17097
17005
  name = answerText(result["mcp-name"]);
17098
- scope = selectedValues(result["mcp-scope"])[0] === "project" ? "project" : "global";
17099
17006
  selectedApps = selectedValues(result["mcp-apps"]);
17100
- const problem = entryProblem(name, scope, selectedApps, taken);
17007
+ const problem = entryProblem(name, selectedApps, taken);
17101
17008
  if (problem !== void 0) {
17102
17009
  io.note(problem);
17103
17010
  if (!context.interactive) return SETUP_ABORTED;
@@ -17107,7 +17014,6 @@ async function configureEntry(context, entry, taken, io) {
17107
17014
  apps: Object.freeze([...new Set(selectedApps)]),
17108
17015
  ...catalog === void 0 ? {} : { catalogId: catalog.id },
17109
17016
  name,
17110
- scope,
17111
17017
  transport
17112
17018
  });
17113
17019
  }
@@ -17120,12 +17026,12 @@ async function configureEntry(context, entry, taken, io) {
17120
17026
  * the form that is one line to re-type; caught at serialization it would end the run after every
17121
17027
  * question had been answered.
17122
17028
  */
17123
- function entryProblem(name, scope, apps, taken) {
17029
+ function entryProblem(name, apps, taken) {
17124
17030
  const nameProblem = mcpServerNameProblem(name);
17125
17031
  if (nameProblem !== void 0) return `MCP server $.name ${nameProblem}.`;
17126
17032
  if (apps.length === 0) return "MCP server $.apps must select at least one application.";
17127
17033
  const selected = new Set(apps);
17128
- return taken.some((server) => server.name === name && server.scope === scope && server.apps.some((app) => selected.has(app))) ? `MCP server $.name ${name} is already configured at ${scope} scope for an application selected here. Choose another name.` : void 0;
17034
+ return taken.some((server) => server.name === name && server.apps.some((app) => selected.has(app))) ? `MCP server $.name ${name} is already configured globally for an application selected here. Choose another name.` : void 0;
17129
17035
  }
17130
17036
  function appChoices(context, supportedApps, existingApps) {
17131
17037
  const managed = new Set(managedAppIdList(context));
@@ -17186,7 +17092,7 @@ function workingEntries(context) {
17186
17092
  }
17187
17093
  function matchesEntry(server, entry) {
17188
17094
  const existing = entry.existing;
17189
- if (existing !== void 0) return existing.catalogId === server.catalogId && existing.name === server.name && existing.scope === server.scope;
17095
+ if (existing !== void 0) return existing.catalogId === server.catalogId && existing.name === server.name;
17190
17096
  return entry.catalog?.id === server.catalogId;
17191
17097
  }
17192
17098
  function nextCustomKey(entries) {
@@ -17197,7 +17103,7 @@ function nextCustomKey(entries) {
17197
17103
  /**
17198
17104
  * A default name no other row has taken.
17199
17105
  *
17200
- * Two servers cannot share one name in one application and scope — the manifest refuses to record
17106
+ * Two servers cannot share one name in one application — the manifest refuses to record
17201
17107
  * it — so seeding every custom server with `custom` would turn "add two, accept the defaults" into
17202
17108
  * a plan the manifest declines to hold.
17203
17109
  */
@@ -17259,7 +17165,6 @@ async function gatherMcp(context, io) {
17259
17165
  const server = {
17260
17166
  apps: [],
17261
17167
  name: nextCustomName(entries),
17262
- scope: "global",
17263
17168
  transport
17264
17169
  };
17265
17170
  entries.push({