@loomweaver/mcp 0.7.4 → 0.7.6

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.
Files changed (2) hide show
  1. package/dist/main.mjs +51 -18
  2. package/package.json +1 -1
package/dist/main.mjs CHANGED
@@ -31006,7 +31006,7 @@ function isUnsafePath(path) {
31006
31006
  }
31007
31007
  function generate(recipe, input) {
31008
31008
  const files = recipe.build(input);
31009
- const unsafe = Object.keys(files).find(isUnsafePath);
31009
+ const unsafe = Object.keys(files).find((path) => isUnsafePath(path));
31010
31010
  if (unsafe !== void 0) {
31011
31011
  throw new Error(`Recipe "${recipe.id}" produced an unsafe path: "${unsafe}".`);
31012
31012
  }
@@ -31016,6 +31016,16 @@ function amendments(recipe, input) {
31016
31016
  return recipe.amend?.(input) ?? [];
31017
31017
  }
31018
31018
 
31019
+ // ../devkit/src/lib/amend/merge.ts
31020
+ function normalizeProjectRoot(value) {
31021
+ const rooted = value.replace(/^\.?\/*/, "");
31022
+ let end = rooted.length;
31023
+ while (end > 0 && rooted[end - 1] === "/") {
31024
+ end -= 1;
31025
+ }
31026
+ return rooted.slice(0, end);
31027
+ }
31028
+
31019
31029
  // ../devkit/src/lib/amend/describe.ts
31020
31030
  function describeAmendment(amendment) {
31021
31031
  if (amendment.kind === "postcss") {
@@ -31177,17 +31187,17 @@ function resolveMenuSlot(menu) {
31177
31187
  }
31178
31188
  return typeof menu === "string" && menu.length ? menu : void 0;
31179
31189
  }
31180
- var PLATFORM_BOUND_CHORD_TOKENS = [
31190
+ var PLATFORM_BOUND_CHORD_TOKENS = /* @__PURE__ */ new Set([
31181
31191
  "cmd",
31182
31192
  "command",
31183
31193
  "ctrl",
31184
31194
  "control",
31185
31195
  "meta"
31186
- ];
31196
+ ]);
31187
31197
  function assertPlatformNeutralChord(shortcut) {
31188
31198
  const tokens = shortcut.toLowerCase().split("+").map((token) => token.trim());
31189
31199
  const bound = tokens.find(
31190
- (token) => PLATFORM_BOUND_CHORD_TOKENS.includes(token)
31200
+ (token) => PLATFORM_BOUND_CHORD_TOKENS.has(token)
31191
31201
  );
31192
31202
  if (bound) {
31193
31203
  throw new Error(
@@ -32177,7 +32187,7 @@ import { provideProductIdentity } from '@loomweaver/plugin-sdk';
32177
32187
  'status-bar' (bar) are what the scaffolded weaver targets. */
32178
32188
  export const layout: ShellLayout = {
32179
32189
  regions: [
32180
- ${renderRegions(" ")}
32190
+ ${renderRegions(" ".repeat(4))}
32181
32191
  ],
32182
32192
  };
32183
32193
 
@@ -32362,7 +32372,7 @@ var angularDistribution = {
32362
32372
  return {
32363
32373
  "src/main.ts": mainTs(),
32364
32374
  "src/app/app.config.ts": appConfigTs(d),
32365
- ...d.withTests ? { "src/app/app.config.spec.ts": appConfigSpec() } : {},
32375
+ ...d.withTests && { "src/app/app.config.spec.ts": appConfigSpec() },
32366
32376
  "src/app/app.ts": appTs(),
32367
32377
  "src/app/app.html": appHtml(),
32368
32378
  "src/index.html": indexHtml(d),
@@ -32634,7 +32644,7 @@ import { ShellLayout } from '@loomweaver/shell';
32634
32644
 
32635
32645
  export const ${l.propertyName}Layout: ShellLayout = {
32636
32646
  regions: [
32637
- ${renderRegions(" ")}
32647
+ ${renderRegions(" ".repeat(4))}
32638
32648
  ],
32639
32649
  };
32640
32650
  `;
@@ -32650,7 +32660,7 @@ var layout = {
32650
32660
  // ../devkit/src/recipes/angular-weaver/amendments.ts
32651
32661
  function weaverAmendments(input, where) {
32652
32662
  const w = resolveWeaverInput(input);
32653
- const directory = (where ?? "").replace(/^\.?\/*/, "").replace(/\/+$/, "");
32663
+ const directory = normalizeProjectRoot(where ?? "");
32654
32664
  if (!directory) {
32655
32665
  return [];
32656
32666
  }
@@ -33117,6 +33127,14 @@ function validateEntry(raw, index, known) {
33117
33127
  }
33118
33128
  ];
33119
33129
  }
33130
+ return [
33131
+ ...validateEntryIdentity(raw, index),
33132
+ ...validateCapabilities2(raw["capabilities"], index, known),
33133
+ ...validateEntryMetadata(raw, index),
33134
+ ...validateEntryKeys(raw, index)
33135
+ ];
33136
+ }
33137
+ function validateEntryIdentity(raw, index) {
33120
33138
  const findings = [];
33121
33139
  if (typeof raw["id"] !== "string" || raw["id"].length === 0) {
33122
33140
  findings.push({
@@ -33158,7 +33176,10 @@ function validateEntry(raw, index, known) {
33158
33176
  path: at(index, "version")
33159
33177
  });
33160
33178
  }
33161
- findings.push(...validateCapabilities2(raw["capabilities"], index, known));
33179
+ return findings;
33180
+ }
33181
+ function validateEntryMetadata(raw, index) {
33182
+ const findings = [];
33162
33183
  if (raw["downloads"] !== void 0 && (typeof raw["downloads"] !== "number" || raw["downloads"] < 0)) {
33163
33184
  findings.push({
33164
33185
  level: "warning",
@@ -33183,6 +33204,10 @@ function validateEntry(raw, index, known) {
33183
33204
  path: at(index, "repository")
33184
33205
  });
33185
33206
  }
33207
+ return findings;
33208
+ }
33209
+ function validateEntryKeys(raw, index) {
33210
+ const findings = [];
33186
33211
  for (const key of Object.keys(raw)) {
33187
33212
  if (!CATALOG_ENTRY_KEYS.includes(key)) {
33188
33213
  findings.push({
@@ -33222,7 +33247,7 @@ function validateCatalog(catalog, known = KNOWN_CAPABILITIES) {
33222
33247
  }
33223
33248
  const findings = [];
33224
33249
  const seen = /* @__PURE__ */ new Set();
33225
- catalog.forEach((entry, index) => {
33250
+ for (const [index, entry] of catalog.entries()) {
33226
33251
  findings.push(...validateEntry(entry, index, known));
33227
33252
  const id = isPlainObject3(entry) ? entry["id"] : void 0;
33228
33253
  if (typeof id === "string" && id.length > 0) {
@@ -33236,7 +33261,7 @@ function validateCatalog(catalog, known = KNOWN_CAPABILITIES) {
33236
33261
  }
33237
33262
  seen.add(id);
33238
33263
  }
33239
- });
33264
+ }
33240
33265
  return findings;
33241
33266
  }
33242
33267
 
@@ -33248,7 +33273,7 @@ function ok(data) {
33248
33273
  };
33249
33274
  }
33250
33275
  function toolName(scaffold2) {
33251
- return `scaffold_${scaffold2.name.replace(/-/g, "_")}`;
33276
+ return `scaffold_${scaffold2.name.replaceAll("-", "_")}`;
33252
33277
  }
33253
33278
  function listGenerators() {
33254
33279
  return ok({
@@ -33273,10 +33298,10 @@ function valuesFor(scaffold2, args) {
33273
33298
  }
33274
33299
  function scaffold(scaffold2, args) {
33275
33300
  const values = valuesFor(scaffold2, args);
33276
- const remaining = (scaffold2.amend?.(values) ?? []).map(describeAmendment);
33301
+ const remaining = (scaffold2.amend?.(values) ?? []).map((amendment) => describeAmendment(amendment));
33277
33302
  return ok({
33278
33303
  files: scaffold2.build(values),
33279
- ...remaining.length > 0 ? { remaining } : {}
33304
+ ...remaining.length > 0 && { remaining }
33280
33305
  });
33281
33306
  }
33282
33307
  function validateManifestTool(a) {
@@ -33298,10 +33323,16 @@ function validateI18nTool(a) {
33298
33323
 
33299
33324
  // src/lib/server.ts
33300
33325
  var FILE_MAP_NOTE = 'Returns a file map (relative path -> content); write the files into your project. May also return "remaining": steps the workspace needs that this route cannot perform, each saying what it costs to skip. Carry them out, or the generated output builds and does not work.';
33326
+ function optionSchema(option) {
33327
+ if (option.type === "boolean") {
33328
+ return external_exports.boolean();
33329
+ }
33330
+ return option.choices ? external_exports.enum(option.choices) : external_exports.string();
33331
+ }
33301
33332
  function inputSchema(descriptor) {
33302
33333
  const shape = {};
33303
33334
  for (const option of portableOptions(descriptor)) {
33304
- const base = option.type === "boolean" ? external_exports.boolean() : option.choices ? external_exports.enum(option.choices) : external_exports.string();
33335
+ const base = optionSchema(option);
33305
33336
  const described = base.describe(option.description);
33306
33337
  shape[option.name] = option.required ? described : described.optional();
33307
33338
  }
@@ -33310,7 +33341,7 @@ function inputSchema(descriptor) {
33310
33341
  function createMcpServer() {
33311
33342
  const server = new McpServer({
33312
33343
  name: "loomweaver-devkit",
33313
- version: "0.7.4"
33344
+ version: "0.7.6"
33314
33345
  });
33315
33346
  server.registerTool(
33316
33347
  "list_generators",
@@ -33370,7 +33401,9 @@ async function main() {
33370
33401
  const server = createMcpServer();
33371
33402
  await server.connect(new StdioServerTransport());
33372
33403
  }
33373
- main().catch((error51) => {
33404
+ try {
33405
+ await main();
33406
+ } catch (error51) {
33374
33407
  console.error(error51);
33375
33408
  process.exit(1);
33376
- });
33409
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loomweaver/mcp",
3
- "version": "0.7.4",
3
+ "version": "0.7.6",
4
4
  "description": "LoomWeaver MCP server: exposes LoomWeaver's scaffolding and validation as MCP tools, so an AI assistant in any product repo can scaffold and validate weavers, distributions and integrations without a LoomWeaver checkout.",
5
5
  "keywords": [
6
6
  "loomweaver",