@loomweaver/mcp 0.9.0 → 0.9.1

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 +254 -8
  2. package/package.json +1 -1
package/dist/main.mjs CHANGED
@@ -31038,7 +31038,8 @@ function describeAmendment(amendment) {
31038
31038
  return `Add an @source entry for '${amendment.sourceRoot}' to the application's entry stylesheet, resolved from that stylesheet. Without it none of that code's utilities are emitted.`;
31039
31039
  }
31040
31040
  if (amendment.kind === "compose-plugin") {
31041
- return `Register ${amendment.id} in the composition root: import { ${amendment.symbol} }, provideTranslationNamespaces('${amendment.id}'), provideCapabilityGrants({ ${amendment.id}: [${amendment.capabilities.map((capability) => `'${capability}'`).join(
31041
+ const providers = (amendment.providers ?? []).map((provider) => provider.line.replace(/,$/, ""));
31042
+ return `Register ${amendment.id} in the composition root: import { ${amendment.symbol} }, ${providers.map((line) => `${line}, `).join("")}provideTranslationNamespaces('${amendment.id}'), provideCapabilityGrants({ ${amendment.id}: [${amendment.capabilities.map((capability) => `'${capability}'`).join(
31042
31043
  ", "
31043
31044
  )}] }) and ...providePlugins(${amendment.symbol}). Without it none of its contributions appear.`;
31044
31045
  }
@@ -31446,7 +31447,7 @@ function pause(): Promise<void> {
31446
31447
  }
31447
31448
 
31448
31449
  // ../devkit/src/recipes/angular-weaver/agent-files.ts
31449
- var AG_UI_ADAPTER_VERSION = "0.9.0";
31450
+ var AG_UI_ADAPTER_VERSION = "0.9.1";
31450
31451
  var AG_UI_PROTOCOL_VERSION = "0.0.x";
31451
31452
  function connectionFile(w) {
31452
31453
  return `import { signal } from '@angular/core';
@@ -32428,9 +32429,17 @@ var framePlugin = {
32428
32429
  }
32429
32430
  };
32430
32431
 
32432
+ // ../devkit/src/recipes/platform-version.ts
32433
+ var PLATFORM_VERSION = "0.9.1";
32434
+
32431
32435
  // ../devkit/src/recipes/angular-distribution/amendments.ts
32432
32436
  function distributionAmendments(d) {
32433
32437
  return [
32438
+ {
32439
+ kind: "package",
32440
+ name: "@loomweaver/frame-kit",
32441
+ version: `^${PLATFORM_VERSION}`
32442
+ },
32434
32443
  ...d.styles === "tailwind" ? [
32435
32444
  {
32436
32445
  kind: "postcss",
@@ -32968,6 +32977,7 @@ var angularDistribution = {
32968
32977
  };
32969
32978
 
32970
32979
  // ../devkit/src/recipes/auth-source/recipe.ts
32980
+ var SESSION_PLUGIN_ID = "session";
32971
32981
  function resolveAuthSourceInput(input) {
32972
32982
  if (!isKebabId(input.name)) {
32973
32983
  throw new Error(`Auth source name must be kebab-case (e.g. "dev"); got "${input.name}".`);
@@ -32975,9 +32985,13 @@ function resolveAuthSourceInput(input) {
32975
32985
  return {
32976
32986
  name: input.name,
32977
32987
  className: toPascalCase(input.name),
32978
- propertyName: toCamelCase(input.name)
32988
+ propertyName: toCamelCase(input.name),
32989
+ bare: input.bare ?? false
32979
32990
  };
32980
32991
  }
32992
+ function sessionPluginSymbol(a) {
32993
+ return `${a.propertyName}SessionPlugin`;
32994
+ }
32981
32995
  function moduleFile(a) {
32982
32996
  return `// Provider-neutral AuthSource. LoomWeaver owns no authentication \u2014 it only reacts to
32983
32997
  // a session snapshot. Wire it with: provideAuthSource(() => ${a.propertyName}AuthSource()).
@@ -33016,11 +33030,177 @@ export function cycle${a.className}User(): void {
33016
33030
  }
33017
33031
  `;
33018
33032
  }
33033
+ function pluginFile2(a) {
33034
+ return `// The verbs a user needs to operate the stand-in session: sign in, switch the account, sign
33035
+ // out, from a rail item whose menu carries them. This is presentation for a product that has no
33036
+ // backend yet; nothing here protects anything. Delete it once your own session arrives.
33037
+ import type { Disposable, Plugin, PluginContext } from '@loomweaver/plugin-sdk';
33038
+ import { cycle${a.className}User, ${a.propertyName}AuthSource } from './${a.name}-auth-source';
33039
+
33040
+ const MENU = 'session.account/menu';
33041
+ const snapshot = ${a.propertyName}AuthSource();
33042
+
33043
+ let drawn: Disposable[] = [];
33044
+
33045
+ function signIn(): void {
33046
+ if (!snapshot().authenticated) {
33047
+ cycle${a.className}User();
33048
+ }
33049
+ }
33050
+
33051
+ function switchAccount(): void {
33052
+ cycle${a.className}User();
33053
+ if (!snapshot().authenticated) {
33054
+ cycle${a.className}User();
33055
+ }
33056
+ }
33057
+
33058
+ function signOut(): void {
33059
+ while (snapshot().authenticated) {
33060
+ cycle${a.className}User();
33061
+ }
33062
+ }
33063
+
33064
+ function initialsOf(name: string): string {
33065
+ return name
33066
+ .split(' ')
33067
+ .map((word) => word[0] ?? '')
33068
+ .join('')
33069
+ .slice(0, 2)
33070
+ .toUpperCase();
33071
+ }
33072
+
33073
+ function draw(ctx: PluginContext): void {
33074
+ for (const part of drawn) {
33075
+ part.dispose();
33076
+ }
33077
+ const current = snapshot();
33078
+ const name = current.displayName ?? '';
33079
+ drawn = [
33080
+ ctx.registerRailItem({
33081
+ id: 'session.account',
33082
+ rail: 'primary',
33083
+ icon: 'account',
33084
+ title: current.authenticated ? name : 'session.signIn',
33085
+ anchor: 'bottom',
33086
+ order: 20,
33087
+ menu: MENU,
33088
+ menuTrigger: 'primary',
33089
+ ...(current.authenticated ? { initials: initialsOf(name) } : {}),
33090
+ menuHeader: current.authenticated
33091
+ ? {
33092
+ title: name,
33093
+ detail: \`session.role.\${current.roles.includes('admin') ? 'admin' : 'user'}\`,
33094
+ initials: initialsOf(name),
33095
+ }
33096
+ : { title: 'session.signedOut', icon: 'account' },
33097
+ }),
33098
+ ...(current.authenticated
33099
+ ? [
33100
+ ctx.registerMenuItem({
33101
+ id: 'session.menu.switch',
33102
+ menu: MENU,
33103
+ command: 'session.switchAccount',
33104
+ group: 'account',
33105
+ order: 10,
33106
+ }),
33107
+ ctx.registerMenuItem({
33108
+ id: 'session.menu.signOut',
33109
+ menu: MENU,
33110
+ command: 'session.signOut',
33111
+ group: 'account',
33112
+ order: 20,
33113
+ }),
33114
+ ]
33115
+ : [
33116
+ ctx.registerMenuItem({
33117
+ id: 'session.menu.signIn',
33118
+ menu: MENU,
33119
+ command: 'session.signIn',
33120
+ group: 'account',
33121
+ order: 10,
33122
+ }),
33123
+ ]),
33124
+ ];
33125
+ }
33126
+
33127
+ export const ${sessionPluginSymbol(a)}: Plugin = {
33128
+ manifest: { id: 'session', name: 'Account', capabilities: ['contributions'] },
33129
+ activate(ctx) {
33130
+ const then = (step: () => void) => () => {
33131
+ step();
33132
+ draw(ctx);
33133
+ };
33134
+ ctx.registerCommand({
33135
+ id: 'session.signIn',
33136
+ title: 'session.signIn',
33137
+ icon: 'account',
33138
+ access: { authenticated: false },
33139
+ run: then(signIn),
33140
+ });
33141
+ ctx.registerCommand({
33142
+ id: 'session.switchAccount',
33143
+ title: 'session.switchAccount',
33144
+ icon: 'account',
33145
+ access: { authenticated: true },
33146
+ run: then(switchAccount),
33147
+ });
33148
+ ctx.registerCommand({
33149
+ id: 'session.signOut',
33150
+ title: 'session.signOut',
33151
+ icon: 'signOut',
33152
+ access: { authenticated: true },
33153
+ run: then(signOut),
33154
+ });
33155
+ draw(ctx);
33156
+ },
33157
+ deactivate() {
33158
+ for (const part of drawn) {
33159
+ part.dispose();
33160
+ }
33161
+ drawn = [];
33162
+ },
33163
+ };
33164
+ `;
33165
+ }
33166
+ function indexFile2(a) {
33167
+ return `export { cycle${a.className}User, ${a.propertyName}AuthSource } from './${a.name}-auth-source';
33168
+ export { ${sessionPluginSymbol(a)} } from './${a.name}-session.plugin';
33169
+ `;
33170
+ }
33171
+ var I18N = {
33172
+ en: {
33173
+ signIn: "Sign in",
33174
+ switchAccount: "Switch account",
33175
+ signOut: "Sign out",
33176
+ signedOut: "Not signed in",
33177
+ role: { user: "User", admin: "Administrator" }
33178
+ },
33179
+ de: {
33180
+ signIn: "Anmelden",
33181
+ switchAccount: "Konto wechseln",
33182
+ signOut: "Abmelden",
33183
+ signedOut: "Nicht angemeldet",
33184
+ role: { user: "Benutzer", admin: "Administrator" }
33185
+ }
33186
+ };
33019
33187
  var authSource = {
33020
33188
  id: "auth-source",
33021
33189
  build(input) {
33022
33190
  const a = resolveAuthSourceInput(input);
33023
- return { [`${a.name}-auth-source.ts`]: moduleFile(a) };
33191
+ const source = { [`${a.name}-auth-source.ts`]: moduleFile(a) };
33192
+ if (a.bare) {
33193
+ return source;
33194
+ }
33195
+ return {
33196
+ ...source,
33197
+ [`${a.name}-session.plugin.ts`]: pluginFile2(a),
33198
+ "index.ts": indexFile2(a),
33199
+ "i18n/en.json": `${JSON.stringify(I18N.en, null, 2)}
33200
+ `,
33201
+ "i18n/de.json": `${JSON.stringify(I18N.de, null, 2)}
33202
+ `
33203
+ };
33024
33204
  }
33025
33205
  };
33026
33206
 
@@ -33285,6 +33465,54 @@ function weaverAmendments(input, where) {
33285
33465
  ];
33286
33466
  }
33287
33467
 
33468
+ // ../devkit/src/recipes/auth-source/recipe-amendments.ts
33469
+ function authSourceAmendments(input, where) {
33470
+ const a = resolveAuthSourceInput(input);
33471
+ const directory = normalizeProjectRoot(where ?? "");
33472
+ if (a.bare || !directory) {
33473
+ return [];
33474
+ }
33475
+ return [
33476
+ {
33477
+ kind: "build-target",
33478
+ styles: [],
33479
+ assets: [
33480
+ {
33481
+ glob: "**/*.json",
33482
+ input: `${directory}/i18n`,
33483
+ from: "workspace",
33484
+ output: `i18n/${SESSION_PLUGIN_ID}`
33485
+ }
33486
+ ]
33487
+ },
33488
+ {
33489
+ kind: "compose-plugin",
33490
+ id: SESSION_PLUGIN_ID,
33491
+ symbol: sessionPluginSymbol(a),
33492
+ capabilities: ["contributions"],
33493
+ sourceRoot: directory,
33494
+ providers: [
33495
+ {
33496
+ line: `provideAuthSource(() => ${a.propertyName}AuthSource()),`,
33497
+ shell: ["provideAuthSource"],
33498
+ own: [`${a.propertyName}AuthSource`],
33499
+ unless: "provideAuthSource("
33500
+ },
33501
+ {
33502
+ line: "provideIcons({ account: heroUserCircle, signOut: heroArrowRightStartOnRectangle }),",
33503
+ shell: ["provideIcons"],
33504
+ from: [
33505
+ {
33506
+ path: "@ng-icons/heroicons/outline",
33507
+ symbols: ["heroArrowRightStartOnRectangle", "heroUserCircle"]
33508
+ }
33509
+ ]
33510
+ }
33511
+ ]
33512
+ }
33513
+ ];
33514
+ }
33515
+
33288
33516
  // ../devkit/src/lib/scaffolds/inputs.ts
33289
33517
  function weaverInput(values) {
33290
33518
  return {
@@ -33362,6 +33590,9 @@ var APP_OPTION = {
33362
33590
  description: "Application to drop into. Inferred when the workspace has exactly one.",
33363
33591
  workspaceOnly: true
33364
33592
  };
33593
+ function authSourceInput(values) {
33594
+ return { name: str(values, "name") ?? "", bare: bool(values, "bare") };
33595
+ }
33365
33596
  var SCAFFOLDS = [
33366
33597
  {
33367
33598
  name: "weaver",
@@ -33519,7 +33750,7 @@ var SCAFFOLDS = [
33519
33750
  },
33520
33751
  {
33521
33752
  name: "auth-source",
33522
- summary: "a provider-neutral AuthSource that feeds the session",
33753
+ summary: "a stand-in session a user can operate: the AuthSource, the sign-in, switch and sign-out verbs in the rail, composed in",
33523
33754
  options: [
33524
33755
  {
33525
33756
  name: "name",
@@ -33528,9 +33759,22 @@ var SCAFFOLDS = [
33528
33759
  required: true,
33529
33760
  pattern: ID_PATTERN
33530
33761
  },
33531
- APP_OPTION
33762
+ {
33763
+ name: "bare",
33764
+ type: "boolean",
33765
+ description: "Write the AuthSource alone, without the verbs, for a product that maps a session of its own onto it.",
33766
+ default: false
33767
+ },
33768
+ APP_OPTION,
33769
+ {
33770
+ name: "directory",
33771
+ type: "string",
33772
+ description: "Where the files land, relative to the workspace root.",
33773
+ workspaceOnly: true
33774
+ }
33532
33775
  ],
33533
- build: (values) => generate(authSource, { name: str(values, "name") ?? "" })
33776
+ build: (values) => generate(authSource, authSourceInput(values)),
33777
+ amend: (values) => authSourceAmendments(authSourceInput(values), str(values, "directory"))
33534
33778
  },
33535
33779
  {
33536
33780
  name: "settings-store",
@@ -33586,6 +33830,8 @@ var SCAFFOLDS = [
33586
33830
  build: (values) => generate(layout, { name: str(values, "name") })
33587
33831
  }
33588
33832
  ];
33833
+
33834
+ // ../devkit/src/lib/scaffolds/surface.ts
33589
33835
  function portableOptions(scaffold2) {
33590
33836
  return scaffold2.options.filter((option) => !option.workspaceOnly);
33591
33837
  }
@@ -34140,7 +34386,7 @@ function inputSchema(descriptor) {
34140
34386
  function createMcpServer() {
34141
34387
  const server = new McpServer({
34142
34388
  name: "loomweaver-devkit",
34143
- version: "0.9.0"
34389
+ version: "0.9.1"
34144
34390
  });
34145
34391
  server.registerTool(
34146
34392
  "list_generators",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loomweaver/mcp",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "LoomWeaver: open-source plugin platform for Angular workbenches. The MCP server: scaffolding and validation as tools, so an AI assistant in any product repo can build weavers without a checkout.",
5
5
  "keywords": [
6
6
  "loomweaver",