@tryaura/aura-cli 0.3.0 → 0.3.2

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.
@@ -37,7 +37,7 @@ const contentSource = (path) => ({
37
37
  url: pluginContentUrl(import.meta.url, path)
38
38
  });
39
39
  var src_default = definePlugin({
40
- apiVersion: 1,
40
+ apiVersion: 2,
41
41
  id: "official",
42
42
  name: "Aura Official Content",
43
43
  mcpCatalog: [
@@ -312,19 +312,18 @@ function mcpServer(candidate, path, claimed) {
312
312
  const name = requiredString(server, "name", path);
313
313
  const nameProblem = mcpServerNameProblem(name);
314
314
  if (nameProblem !== void 0) throw invalid(`${path}.name`, nameProblem);
315
- const scope = server["scope"];
316
- if (scope !== "global" && scope !== "project") throw invalid(`${path}.scope`, "must be either \"global\" or \"project\"");
317
- const apps = targetApps(server["apps"], `${path}.apps`, name, scope, claimed);
315
+ const { scope, ...rest } = server;
316
+ const legacyScope = typeof scope === "string" ? scope : void 0;
317
+ const apps = targetApps(server["apps"], `${path}.apps`, name, claimed, legacyScope);
318
318
  const transport = parseMcpServerDefinition(server["transport"], `${path}.transport`);
319
319
  if ("error" in transport) throw invalid(transport.error.path, transport.error.message);
320
320
  const catalogId = server["catalogId"];
321
321
  if (catalogId !== void 0 && (typeof catalogId !== "string" || catalogId.length === 0)) throw invalid(`${path}.catalogId`, "must be a non-empty string");
322
322
  return Object.freeze({
323
- ...server,
323
+ ...rest,
324
324
  apps,
325
325
  ...catalogId === void 0 ? {} : { catalogId },
326
326
  name,
327
- scope,
328
327
  transport: transport.value
329
328
  });
330
329
  }
@@ -332,27 +331,38 @@ function mcpServer(candidate, path, claimed) {
332
331
  * Reads the applications one entry targets, refusing any that already has this server.
333
332
  *
334
333
  * `name` is the key written into each application's own configuration, so two entries claiming it
335
- * for the same application and scope describe two different desired states for one key. Convergence
334
+ * for the same application describe two different desired states for one key. Convergence
336
335
  * would resolve that by writing whichever came last, which is not a decision a manifest should
337
336
  * leave to iteration order. An entry that targets nothing is refused for a plainer reason: it
338
337
  * converges nowhere, and the user who wrote it is watching for it to take effect.
339
338
  */
340
- function targetApps(value, path, name, scope, claimed) {
339
+ function targetApps(value, path, name, claimed, legacyScope) {
341
340
  const entries = stringArray(value, path);
342
341
  if (entries.length === 0) throw invalid(path, "must name at least one application");
343
- const key = `${scope}${name}`;
344
- const owners = claimed.get(key) ?? /* @__PURE__ */ new Set();
345
- claimed.set(key, owners);
342
+ const owners = claimed.get(name) ?? /* @__PURE__ */ new Set();
343
+ claimed.set(name, owners);
346
344
  const seen = /* @__PURE__ */ new Set();
347
345
  for (const [index, entry] of entries.entries()) {
348
346
  if (entry.length === 0) throw invalid(`${path}[${String(index)}]`, "must be non-empty");
349
347
  if (seen.has(entry)) throw invalid(`${path}[${String(index)}]`, `duplicates ${entry}`);
350
- if (owners.has(entry)) throw invalid(`${path}[${String(index)}]`, `duplicates the ${scope} server "${name}" already declared for ${entry}`);
348
+ if (owners.has(entry)) throw invalid(`${path}[${String(index)}]`, duplicateReason(name, entry, legacyScope));
351
349
  seen.add(entry);
352
350
  owners.add(entry);
353
351
  }
354
352
  return entries;
355
353
  }
354
+ /**
355
+ * Why two entries claiming one name for one application cannot both stand.
356
+ *
357
+ * A manifest written before Aura went global-only could hold the same name twice for one
358
+ * application, once per scope, and those two entries are the one collision a person did not
359
+ * introduce themselves. Naming the removed property is what turns "duplicates" into something they
360
+ * can act on, because the entries look identical once it is gone.
361
+ */
362
+ function duplicateReason(name, appId, legacyScope) {
363
+ const duplicate = `duplicates the global server "${name}" already declared for ${appId}`;
364
+ return legacyScope === void 0 ? duplicate : `${duplicate}. Aura no longer separates MCP servers by scope, so a manifest holding this name at both global and project scope now declares it twice. Keep the entry you want and delete the other, along with its "scope" property`;
365
+ }
356
366
  //#endregion
357
367
  //#region ../core/src/manifest/schema-snippets.ts
358
368
  /**
@@ -445,7 +455,7 @@ function trustedPath(value, jsonPath) {
445
455
  const APP_ID_PATTERN = /^[a-z0-9][a-z0-9._-]*$/u;
446
456
  const MCP_CATALOG_ID_PATTERN = /^[a-z0-9][a-z0-9._-]*\/[a-zA-Z0-9][a-zA-Z0-9._-]*$/u;
447
457
  const SKILL_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
448
- const SKILL_SOURCE_PATTERN = /^(?:directory|driver|plugin):[^\s:]+$/u;
458
+ const SKILL_SOURCE_PATTERN = /^(?:directory|driver|plugin|repo):[^\s:]+$/u;
449
459
  const OVERRIDE_KEY_PATTERN = /^[a-z][a-zA-Z0-9]{0,63}$/u;
450
460
  /** Room for several future override kinds without leaving the forward-compat window unbounded. */
451
461
  const MAX_OVERRIDE_KEYS = 32;
@@ -537,9 +547,10 @@ function skills(value) {
537
547
  }
538
548
  function requiredSkillSource(value, path) {
539
549
  const source = requiredString(value, "source", path);
540
- if (!SKILL_SOURCE_PATTERN.test(source)) throw invalid(`${path}.source`, "must be a plugin:, directory:, or driver: source ID");
550
+ if (!SKILL_SOURCE_PATTERN.test(source)) throw invalid(`${path}.source`, "must be a plugin:, directory:, driver:, or repo: source ID");
541
551
  if (source.startsWith("plugin:")) return `plugin:${source.slice(7)}`;
542
552
  if (source.startsWith("directory:")) return `directory:${source.slice(10)}`;
553
+ if (source.startsWith("repo:")) return `repo:${source.slice(5)}`;
543
554
  return `driver:${source.slice(7)}`;
544
555
  }
545
556
  var UnsupportedAuraManifestVersionError = class extends Error {
@@ -1144,7 +1155,7 @@ function convergedPlan$1(app, skillId) {
1144
1155
  //#endregion
1145
1156
  //#region ../core/src/workspace/mcp-plan-manifest.ts
1146
1157
  /**
1147
- * Merges preset-required servers under the manifest's own, keyed by scope and name.
1158
+ * Merges preset-required servers under the manifest's own, keyed by name.
1148
1159
  *
1149
1160
  * The manifest is written last and wins, matching the layer precedence everywhere else. A preset
1150
1161
  * that requires a server the user already configured must not silently repoint its transport:
@@ -1152,9 +1163,8 @@ function convergedPlan$1(app, skillId) {
1152
1163
  */
1153
1164
  function desiredEntries(model, manifest, appId) {
1154
1165
  const result = /* @__PURE__ */ new Map();
1155
- for (const server of [...model.requiredMcpServers ?? [], ...manifest.mcpServers]) if (server.apps.includes(appId)) result.set(`${server.scope}\0${server.name}`, {
1166
+ for (const server of [...model.requiredMcpServers ?? [], ...manifest.mcpServers]) if (server.apps.includes(appId)) result.set(server.name, {
1156
1167
  name: server.name,
1157
- scope: server.scope,
1158
1168
  transport: server.transport
1159
1169
  });
1160
1170
  return Object.freeze([...result.values()]);
@@ -1178,7 +1188,7 @@ function withOwnership(manifest, appId, mcpServerNames) {
1178
1188
  /** Drops one application from a desired server, and the entry entirely once nobody wants it. */
1179
1189
  function withoutServer(manifest, server) {
1180
1190
  const mcpServers = manifest.mcpServers.flatMap((entry) => {
1181
- if (entry.name !== server.name || entry.scope !== server.scope) return [entry];
1191
+ if (entry.name !== server.name) return [entry];
1182
1192
  const apps = entry.apps.filter((appId) => appId !== server.appId);
1183
1193
  return apps.length === 0 ? [] : [{
1184
1194
  ...entry,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tryaura/aura-cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "The composable Aura CLI runtime and official plugin distribution.",
5
5
  "keywords": [
6
6
  "agent",
@@ -50,17 +50,17 @@
50
50
  "toml-eslint-parser": "^1.0.3",
51
51
  "typanion": "3.14.0",
52
52
  "undici": "7.29.0",
53
- "@tryaura/aura-sdk": "0.3.0"
53
+ "@tryaura/aura-sdk": "0.3.2"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/node": "24.13.3",
57
57
  "ajv": "8.20.0",
58
58
  "vitest": "4.1.10",
59
- "@tryaura/adapter-codex": "0.0.0",
60
59
  "@tryaura/adapter-claude-code": "0.0.0",
61
- "@tryaura/content-official": "0.0.0",
62
- "@tryaura/checks-core": "0.0.0",
60
+ "@tryaura/adapter-codex": "0.0.0",
63
61
  "@tryaura/adapter-cursor": "0.0.0",
62
+ "@tryaura/checks-core": "0.0.0",
63
+ "@tryaura/content-official": "0.0.0",
64
64
  "@tryaura/core": "0.0.0"
65
65
  },
66
66
  "engines": {