@angular/cli 21.0.0-next.0 → 21.0.0-next.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.
Files changed (43) hide show
  1. package/lib/code-examples.db +0 -0
  2. package/lib/config/schema.json +37 -5
  3. package/lib/config/workspace-schema.d.ts +41 -2
  4. package/lib/config/workspace-schema.js +13 -2
  5. package/package.json +19 -19
  6. package/src/command-builder/architect-command-module.js +11 -5
  7. package/src/command-builder/schematics-command-module.js +7 -2
  8. package/src/command-builder/utilities/json-schema.js +5 -1
  9. package/src/command-builder/utilities/schematic-engine-host.js +4 -6
  10. package/src/commands/add/cli.d.ts +2 -1
  11. package/src/commands/add/cli.js +178 -94
  12. package/src/commands/mcp/mcp-server.d.ts +12 -2
  13. package/src/commands/mcp/mcp-server.js +6 -1
  14. package/src/commands/mcp/tools/best-practices.js +15 -5
  15. package/src/commands/mcp/tools/doc-search.d.ts +18 -1
  16. package/src/commands/mcp/tools/doc-search.js +94 -37
  17. package/src/commands/mcp/tools/examples.d.ts +9 -1
  18. package/src/commands/mcp/tools/examples.js +38 -12
  19. package/src/commands/mcp/tools/modernize.js +28 -27
  20. package/src/commands/mcp/tools/onpush-zoneless-migration/analyze_for_unsupported_zone_uses.d.ts +17 -0
  21. package/src/commands/mcp/tools/onpush-zoneless-migration/analyze_for_unsupported_zone_uses.js +61 -0
  22. package/src/commands/mcp/tools/onpush-zoneless-migration/migrate_single_file.d.ts +12 -0
  23. package/src/commands/mcp/tools/onpush-zoneless-migration/migrate_single_file.js +72 -0
  24. package/src/commands/mcp/tools/onpush-zoneless-migration/migrate_test_file.d.ts +11 -0
  25. package/src/commands/mcp/tools/onpush-zoneless-migration/migrate_test_file.js +105 -0
  26. package/src/commands/mcp/tools/onpush-zoneless-migration/prompts.d.ts +15 -0
  27. package/src/commands/mcp/tools/onpush-zoneless-migration/prompts.js +236 -0
  28. package/src/commands/mcp/tools/onpush-zoneless-migration/send_debug_message.d.ts +10 -0
  29. package/src/commands/mcp/tools/onpush-zoneless-migration/send_debug_message.js +19 -0
  30. package/src/commands/mcp/tools/onpush-zoneless-migration/ts_utils.d.ts +36 -0
  31. package/src/commands/mcp/tools/onpush-zoneless-migration/ts_utils.js +135 -0
  32. package/src/commands/mcp/tools/onpush-zoneless-migration/types.d.ts +13 -0
  33. package/src/commands/mcp/tools/onpush-zoneless-migration/types.js +9 -0
  34. package/src/commands/mcp/tools/onpush-zoneless-migration/zoneless-migration.d.ts +14 -0
  35. package/src/commands/mcp/tools/onpush-zoneless-migration/zoneless-migration.js +205 -0
  36. package/src/commands/mcp/tools/projects.d.ts +47 -16
  37. package/src/commands/mcp/tools/projects.js +155 -30
  38. package/src/commands/mcp/tools/tool-registry.d.ts +2 -1
  39. package/src/commands/mcp/tools/tool-registry.js +3 -2
  40. package/src/commands/update/schematic/schema.d.ts +0 -1
  41. package/src/commands/update/schematic/schema.js +0 -1
  42. package/src/commands/update/schematic/schema.json +1 -1
  43. package/src/utilities/version.js +1 -1
@@ -43,7 +43,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
43
43
  return (mod && mod.__esModule) ? mod : { "default": mod };
44
44
  };
45
45
  Object.defineProperty(exports, "__esModule", { value: true });
46
- const tools_1 = require("@angular-devkit/schematics/tools");
47
46
  const listr2_1 = require("listr2");
48
47
  const node_assert_1 = __importDefault(require("node:assert"));
49
48
  const node_module_1 = require("node:module");
@@ -69,6 +68,17 @@ const packageVersionExclusions = {
69
68
  // @angular/material@7.x versions have unbounded peer dependency ranges (>=7.0.0).
70
69
  '@angular/material': '7.x',
71
70
  };
71
+ const DEFAULT_CONFLICT_DISPLAY_LIMIT = 5;
72
+ /**
73
+ * A map of packages to built-in schematics.
74
+ * This is used for packages that do not have a native `ng-add` schematic.
75
+ */
76
+ const BUILT_IN_SCHEMATICS = {
77
+ tailwindcss: {
78
+ collection: '@schematics/angular',
79
+ name: 'tailwind',
80
+ },
81
+ };
72
82
  class AddCommandModule extends schematics_command_module_1.SchematicsCommandModule {
73
83
  command = 'add <collection>';
74
84
  describe = 'Adds support for an external library to your project.';
@@ -76,6 +86,7 @@ class AddCommandModule extends schematics_command_module_1.SchematicsCommandModu
76
86
  allowPrivateSchematics = true;
77
87
  schematicName = 'ng-add';
78
88
  rootRequire = (0, node_module_1.createRequire)(this.context.root + '/');
89
+ #projectVersionCache = new Map();
79
90
  async builder(argv) {
80
91
  const localYargs = (await super.builder(argv))
81
92
  .positional('collection', {
@@ -117,6 +128,7 @@ class AddCommandModule extends schematics_command_module_1.SchematicsCommandModu
117
128
  return localYargs;
118
129
  }
119
130
  async run(options) {
131
+ this.#projectVersionCache.clear();
120
132
  const { logger } = this.context;
121
133
  const { collection, skipConfirmation } = options;
122
134
  let packageIdentifier;
@@ -141,7 +153,8 @@ class AddCommandModule extends schematics_command_module_1.SchematicsCommandModu
141
153
  const taskContext = {
142
154
  packageIdentifier,
143
155
  executeSchematic: this.executeSchematic.bind(this),
144
- hasMismatchedPeer: this.hasMismatchedPeer.bind(this),
156
+ getPeerDependencyConflicts: this.getPeerDependencyConflicts.bind(this),
157
+ dryRun: options.dryRun,
145
158
  };
146
159
  const tasks = new listr2_1.Listr([
147
160
  {
@@ -162,11 +175,18 @@ class AddCommandModule extends schematics_command_module_1.SchematicsCommandModu
162
175
  },
163
176
  {
164
177
  title: 'Confirming installation',
165
- enabled: !skipConfirmation,
178
+ enabled: !skipConfirmation && !options.dryRun,
166
179
  task: (context, task) => this.confirmInstallationTask(context, task),
167
180
  rendererOptions: { persistentOutput: true },
168
181
  },
169
182
  {
183
+ title: 'Installing package',
184
+ skip: (context) => {
185
+ if (context.dryRun) {
186
+ return `Skipping package installation. Would install package ${listr2_1.color.blue(context.packageIdentifier.toString())}.`;
187
+ }
188
+ return false;
189
+ },
170
190
  task: (context, task) => this.installPackageTask(context, task, options),
171
191
  rendererOptions: { bottomBar: Infinity },
172
192
  },
@@ -177,6 +197,48 @@ class AddCommandModule extends schematics_command_module_1.SchematicsCommandModu
177
197
  try {
178
198
  const result = await tasks.run(taskContext);
179
199
  (0, node_assert_1.default)(result.collectionName, 'Collection name should always be available');
200
+ // Check if the installed package has actual add actions and not just schematic support
201
+ if (result.hasSchematics && !options.dryRun) {
202
+ const workflow = this.getOrCreateWorkflowForBuilder(result.collectionName);
203
+ const collection = workflow.engine.createCollection(result.collectionName);
204
+ // listSchematicNames cannot be used here since it does not list private schematics.
205
+ // Most `ng-add` schematics are marked as private.
206
+ // TODO: Consider adding a `hasSchematic` helper to the schematic collection object.
207
+ try {
208
+ collection.createSchematic(this.schematicName, true);
209
+ }
210
+ catch {
211
+ result.hasSchematics = false;
212
+ }
213
+ }
214
+ if (!result.hasSchematics) {
215
+ // Fallback to a built-in schematic if the package does not have an `ng-add` schematic
216
+ const packageName = result.packageIdentifier.name;
217
+ if (packageName) {
218
+ const builtInSchematic = BUILT_IN_SCHEMATICS[packageName];
219
+ if (builtInSchematic) {
220
+ logger.info(`The ${listr2_1.color.blue(packageName)} package does not provide \`ng add\` actions.`);
221
+ logger.info('The Angular CLI will use built-in actions to add it to your project.');
222
+ return this.executeSchematic({
223
+ ...options,
224
+ collection: builtInSchematic.collection,
225
+ schematicName: builtInSchematic.name,
226
+ });
227
+ }
228
+ }
229
+ let message = options.dryRun
230
+ ? 'The package does not provide any `ng add` actions, so no further actions would be taken.'
231
+ : 'Package installed successfully. The package does not provide any `ng add` actions, so no further actions were taken.';
232
+ if (result.homepage) {
233
+ message += `\nFor more information about this package, visit its homepage at ${result.homepage}`;
234
+ }
235
+ logger.info(message);
236
+ return;
237
+ }
238
+ if (options.dryRun) {
239
+ logger.info("The package's `ng add` actions would be executed next.");
240
+ return;
241
+ }
180
242
  return this.executeSchematic({ ...options, collection: result.collectionName });
181
243
  }
182
244
  catch (e) {
@@ -210,60 +272,79 @@ class AddCommandModule extends schematics_command_module_1.SchematicsCommandModu
210
272
  (0, error_1.assertIsError)(e);
211
273
  throw new CommandError(`Unable to load package information from registry: ${e.message}`);
212
274
  }
275
+ const rejectionReasons = [];
213
276
  // Start with the version tagged as `latest` if it exists
214
277
  const latestManifest = packageMetadata.tags['latest'];
215
278
  if (latestManifest) {
216
- context.packageIdentifier = npm_package_arg_1.default.resolve(latestManifest.name, latestManifest.version);
217
- }
218
- // Adjust the version based on name and peer dependencies
219
- if (latestManifest?.peerDependencies &&
220
- Object.keys(latestManifest.peerDependencies).length === 0) {
221
- task.output = `Found compatible package version: ${listr2_1.color.blue(latestManifest.version)}.`;
222
- }
223
- else if (!latestManifest || (await context.hasMismatchedPeer(latestManifest))) {
224
- // 'latest' is invalid so search for most recent matching package
225
- // Allow prelease versions if the CLI itself is a prerelease
226
- const allowPrereleases = (0, semver_1.prerelease)(version_1.VERSION.full);
227
- const versionExclusions = packageVersionExclusions[packageMetadata.name];
228
- const versionManifests = Object.values(packageMetadata.versions).filter((value) => {
229
- // Prerelease versions are not stable and should not be considered by default
230
- if (!allowPrereleases && (0, semver_1.prerelease)(value.version)) {
231
- return false;
232
- }
233
- // Deprecated versions should not be used or considered
234
- if (value.deprecated) {
235
- return false;
236
- }
237
- // Excluded package versions should not be considered
238
- if (versionExclusions &&
239
- (0, semver_1.satisfies)(value.version, versionExclusions, { includePrerelease: true })) {
240
- return false;
241
- }
242
- return true;
243
- });
244
- // Sort in reverse SemVer order so that the newest compatible version is chosen
245
- versionManifests.sort((a, b) => (0, semver_1.compare)(b.version, a.version, true));
246
- let found = false;
247
- for (const versionManifest of versionManifests) {
248
- const mismatch = await context.hasMismatchedPeer(versionManifest);
249
- if (mismatch) {
250
- continue;
251
- }
252
- context.packageIdentifier = npm_package_arg_1.default.resolve(versionManifest.name, versionManifest.version);
253
- found = true;
254
- break;
255
- }
256
- if (!found) {
257
- task.output = "Unable to find compatible package. Using 'latest' tag.";
279
+ const latestConflicts = await this.getPeerDependencyConflicts(latestManifest);
280
+ if (latestConflicts) {
281
+ // 'latest' is invalid so search for most recent matching package
282
+ rejectionReasons.push(...latestConflicts);
258
283
  }
259
284
  else {
260
- task.output = `Found compatible package version: ${listr2_1.color.blue(context.packageIdentifier.toString())}.`;
285
+ context.packageIdentifier = npm_package_arg_1.default.resolve(latestManifest.name, latestManifest.version);
286
+ task.output = `Found compatible package version: ${listr2_1.color.blue(latestManifest.version)}.`;
287
+ return;
261
288
  }
262
289
  }
290
+ // Allow prelease versions if the CLI itself is a prerelease
291
+ const allowPrereleases = !!(0, semver_1.prerelease)(version_1.VERSION.full);
292
+ const versionManifests = this.#getPotentialVersionManifests(packageMetadata, allowPrereleases);
293
+ let found = false;
294
+ for (const versionManifest of versionManifests) {
295
+ // Already checked the 'latest' version
296
+ if (latestManifest?.version === versionManifest.version) {
297
+ continue;
298
+ }
299
+ const conflicts = await this.getPeerDependencyConflicts(versionManifest);
300
+ if (conflicts) {
301
+ if (options.verbose || rejectionReasons.length < DEFAULT_CONFLICT_DISPLAY_LIMIT) {
302
+ rejectionReasons.push(...conflicts);
303
+ }
304
+ continue;
305
+ }
306
+ context.packageIdentifier = npm_package_arg_1.default.resolve(versionManifest.name, versionManifest.version);
307
+ found = true;
308
+ break;
309
+ }
310
+ if (!found) {
311
+ let message = `Unable to find compatible package. Using 'latest' tag.`;
312
+ if (rejectionReasons.length > 0) {
313
+ message +=
314
+ '\nThis is often because of incompatible peer dependencies.\n' +
315
+ 'These versions were rejected due to the following conflicts:\n' +
316
+ rejectionReasons
317
+ .slice(0, options.verbose ? undefined : DEFAULT_CONFLICT_DISPLAY_LIMIT)
318
+ .map((r) => ` - ${r}`)
319
+ .join('\n');
320
+ }
321
+ task.output = message;
322
+ }
263
323
  else {
264
324
  task.output = `Found compatible package version: ${listr2_1.color.blue(context.packageIdentifier.toString())}.`;
265
325
  }
266
326
  }
327
+ #getPotentialVersionManifests(packageMetadata, allowPrereleases) {
328
+ const versionExclusions = packageVersionExclusions[packageMetadata.name];
329
+ const versionManifests = Object.values(packageMetadata.versions).filter((value) => {
330
+ // Prerelease versions are not stable and should not be considered by default
331
+ if (!allowPrereleases && (0, semver_1.prerelease)(value.version)) {
332
+ return false;
333
+ }
334
+ // Deprecated versions should not be used or considered
335
+ if (value.deprecated) {
336
+ return false;
337
+ }
338
+ // Excluded package versions should not be considered
339
+ if (versionExclusions &&
340
+ (0, semver_1.satisfies)(value.version, versionExclusions, { includePrerelease: true })) {
341
+ return false;
342
+ }
343
+ return true;
344
+ });
345
+ // Sort in reverse SemVer order so that the newest compatible version is chosen
346
+ return versionManifests.sort((a, b) => (0, semver_1.compare)(b.version, a.version, true));
347
+ }
267
348
  async loadPackageInfoTask(context, task, options) {
268
349
  const { logger } = this.context;
269
350
  const { verbose, registry } = options;
@@ -279,9 +360,11 @@ class AddCommandModule extends schematics_command_module_1.SchematicsCommandModu
279
360
  (0, error_1.assertIsError)(e);
280
361
  throw new CommandError(`Unable to fetch package information for '${context.packageIdentifier}': ${e.message}`);
281
362
  }
363
+ context.hasSchematics = !!manifest.schematics;
282
364
  context.savePackage = manifest['ng-add']?.save;
283
365
  context.collectionName = manifest.name;
284
- if (await context.hasMismatchedPeer(manifest)) {
366
+ context.homepage = manifest.homepage;
367
+ if (await this.getPeerDependencyConflicts(manifest)) {
285
368
  task.output = listr2_1.color.yellow(listr2_1.figures.warning +
286
369
  ' Package has unmet peer dependencies. Adding the package may not succeed.');
287
370
  }
@@ -385,32 +468,26 @@ class AddCommandModule extends schematics_command_module_1.SchematicsCommandModu
385
468
  }
386
469
  return false;
387
470
  }
388
- async executeSchematic(options) {
389
- try {
390
- const { verbose, skipConfirmation, interactive, force, dryRun, registry, defaults, collection: collectionName, ...schematicOptions } = options;
391
- return await this.runSchematic({
392
- schematicOptions,
393
- schematicName: this.schematicName,
394
- collectionName,
395
- executionOptions: {
396
- interactive,
397
- force,
398
- dryRun,
399
- defaults,
400
- packageRegistry: registry,
401
- },
402
- });
403
- }
404
- catch (e) {
405
- if (e instanceof tools_1.NodePackageDoesNotSupportSchematics) {
406
- this.context.logger.error('The package that you are trying to add does not support schematics.' +
407
- 'You can try using a different version of the package or contact the package author to add ng-add support.');
408
- return 1;
409
- }
410
- throw e;
411
- }
471
+ executeSchematic(options) {
472
+ const { verbose, skipConfirmation, interactive, force, dryRun, registry, defaults, collection: collectionName, schematicName, ...schematicOptions } = options;
473
+ return this.runSchematic({
474
+ schematicOptions,
475
+ schematicName: schematicName ?? this.schematicName,
476
+ collectionName,
477
+ executionOptions: {
478
+ interactive,
479
+ force,
480
+ dryRun,
481
+ defaults,
482
+ packageRegistry: registry,
483
+ },
484
+ });
412
485
  }
413
486
  async findProjectVersion(name) {
487
+ const cachedVersion = this.#projectVersionCache.get(name);
488
+ if (cachedVersion !== undefined) {
489
+ return cachedVersion;
490
+ }
414
491
  const { logger, root } = this.context;
415
492
  let installedPackage;
416
493
  try {
@@ -420,6 +497,7 @@ class AddCommandModule extends schematics_command_module_1.SchematicsCommandModu
420
497
  if (installedPackage) {
421
498
  try {
422
499
  const installed = await (0, package_metadata_1.fetchPackageManifest)((0, node_path_1.dirname)(installedPackage), logger);
500
+ this.#projectVersionCache.set(name, installed.version);
423
501
  return installed.version;
424
502
  }
425
503
  catch { }
@@ -432,44 +510,50 @@ class AddCommandModule extends schematics_command_module_1.SchematicsCommandModu
432
510
  if (projectManifest) {
433
511
  const version = projectManifest.dependencies?.[name] || projectManifest.devDependencies?.[name];
434
512
  if (version) {
513
+ this.#projectVersionCache.set(name, version);
435
514
  return version;
436
515
  }
437
516
  }
517
+ this.#projectVersionCache.set(name, null);
438
518
  return null;
439
519
  }
440
- async hasMismatchedPeer(manifest) {
441
- for (const peer in manifest.peerDependencies) {
520
+ async getPeerDependencyConflicts(manifest) {
521
+ if (!manifest.peerDependencies) {
522
+ return false;
523
+ }
524
+ const checks = Object.entries(manifest.peerDependencies).map(async ([peer, range]) => {
442
525
  let peerIdentifier;
443
526
  try {
444
- peerIdentifier = npm_package_arg_1.default.resolve(peer, manifest.peerDependencies[peer]);
527
+ peerIdentifier = npm_package_arg_1.default.resolve(peer, range);
445
528
  }
446
529
  catch {
447
530
  this.context.logger.warn(`Invalid peer dependency ${peer} found in package.`);
448
- continue;
531
+ return null;
449
532
  }
450
- if (peerIdentifier.type === 'version' || peerIdentifier.type === 'range') {
451
- try {
452
- const version = await this.findProjectVersion(peer);
453
- if (!version) {
454
- continue;
455
- }
456
- const options = { includePrerelease: true };
457
- if (!(0, semver_1.intersects)(version, peerIdentifier.rawSpec, options) &&
458
- !(0, semver_1.satisfies)(version, peerIdentifier.rawSpec, options)) {
459
- return true;
460
- }
533
+ if (peerIdentifier.type !== 'version' && peerIdentifier.type !== 'range') {
534
+ // type === 'tag' | 'file' | 'directory' | 'remote' | 'git'
535
+ // Cannot accurately compare these as the tag/location may have changed since install.
536
+ return null;
537
+ }
538
+ try {
539
+ const version = await this.findProjectVersion(peer);
540
+ if (!version) {
541
+ return null;
461
542
  }
462
- catch {
463
- // Not found or invalid so ignore
464
- continue;
543
+ const options = { includePrerelease: true };
544
+ if (!(0, semver_1.intersects)(version, peerIdentifier.rawSpec, options) &&
545
+ !(0, semver_1.satisfies)(version, peerIdentifier.rawSpec, options)) {
546
+ return (`Package "${manifest.name}@${manifest.version}" has an incompatible peer dependency to "` +
547
+ `${peer}@${peerIdentifier.rawSpec}" (requires "${version}" in project).`);
465
548
  }
466
549
  }
467
- else {
468
- // type === 'tag' | 'file' | 'directory' | 'remote' | 'git'
469
- // Cannot accurately compare these as the tag/location may have changed since install
550
+ catch {
551
+ // Not found or invalid so ignore
470
552
  }
471
- }
472
- return false;
553
+ return null;
554
+ });
555
+ const conflicts = (await Promise.all(checks)).filter((result) => !!result);
556
+ return conflicts.length > 0 && conflicts;
473
557
  }
474
558
  }
475
559
  exports.default = AddCommandModule;
@@ -14,11 +14,21 @@ import { AnyMcpToolDeclaration } from './tools/tool-registry';
14
14
  */
15
15
  export declare const EXPERIMENTAL_TOOLS: readonly [import("./tools/tool-registry").McpToolDeclaration<{
16
16
  query: import("zod").ZodString;
17
- }, import("zod").ZodRawShape>, import("./tools/tool-registry").McpToolDeclaration<{
17
+ }, {
18
+ examples: import("zod").ZodArray<import("zod").ZodObject<{
19
+ content: import("zod").ZodString;
20
+ }, "strip", import("zod").ZodTypeAny, {
21
+ content: string;
22
+ }, {
23
+ content: string;
24
+ }>, "many">;
25
+ }>, import("./tools/tool-registry").McpToolDeclaration<{
18
26
  transformations: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodEnum<[string, ...string[]]>, "many">>;
19
27
  }, {
20
28
  instructions: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString, "many">>;
21
- }>];
29
+ }>, import("./tools/tool-registry").McpToolDeclaration<{
30
+ fileOrDirPath: import("zod").ZodString;
31
+ }, import("zod").ZodRawShape>];
22
32
  export declare function createMcpServer(options: {
23
33
  workspace?: AngularWorkspace;
24
34
  readOnly?: boolean;
@@ -21,6 +21,7 @@ const best_practices_1 = require("./tools/best-practices");
21
21
  const doc_search_1 = require("./tools/doc-search");
22
22
  const examples_1 = require("./tools/examples");
23
23
  const modernize_1 = require("./tools/modernize");
24
+ const zoneless_migration_1 = require("./tools/onpush-zoneless-migration/zoneless-migration");
24
25
  const projects_1 = require("./tools/projects");
25
26
  const tool_registry_1 = require("./tools/tool-registry");
26
27
  /**
@@ -32,7 +33,11 @@ const STABLE_TOOLS = [best_practices_1.BEST_PRACTICES_TOOL, doc_search_1.DOC_SEA
32
33
  * The set of tools that are available but not enabled by default.
33
34
  * These tools are considered experimental and may have limitations.
34
35
  */
35
- exports.EXPERIMENTAL_TOOLS = [examples_1.FIND_EXAMPLE_TOOL, modernize_1.MODERNIZE_TOOL];
36
+ exports.EXPERIMENTAL_TOOLS = [
37
+ examples_1.FIND_EXAMPLE_TOOL,
38
+ modernize_1.MODERNIZE_TOOL,
39
+ zoneless_migration_1.ZONELESS_MIGRATION_TOOL,
40
+ ];
36
41
  async function createMcpServer(options, logger) {
37
42
  const server = new mcp_js_1.McpServer({
38
43
  name: 'angular-cli-server',
@@ -17,11 +17,21 @@ const tool_registry_1 = require("./tool-registry");
17
17
  exports.BEST_PRACTICES_TOOL = (0, tool_registry_1.declareTool)({
18
18
  name: 'get_best_practices',
19
19
  title: 'Get Angular Coding Best Practices Guide',
20
- description: 'You **MUST** use this tool to retrieve the Angular Best Practices Guide ' +
21
- 'before any interaction with Angular code (creating, analyzing, modifying). ' +
22
- 'It is mandatory to follow this guide to ensure all code adheres to ' +
23
- 'modern standards, including standalone components, typed forms, and ' +
24
- 'modern control flow. This is the first step for any Angular task.',
20
+ description: `
21
+ <Purpose>
22
+ Retrieves the official Angular Best Practices Guide. This guide contains the essential rules and conventions
23
+ that **MUST** be followed for any task involving the creation, analysis, or modification of Angular code.
24
+ </Purpose>
25
+ <Use Cases>
26
+ * As a mandatory first step before writing or modifying any Angular code to ensure adherence to modern standards.
27
+ * To learn about key concepts like standalone components, typed forms, and modern control flow syntax (@if, @for, @switch).
28
+ * To verify that existing code aligns with current Angular conventions before making changes.
29
+ </Use Cases>
30
+ <Operational Notes>
31
+ * The content of this guide is non-negotiable and reflects the official, up-to-date standards for Angular development.
32
+ * You **MUST** internalize and apply the principles from this guide in all subsequent Angular-related tasks.
33
+ * Failure to adhere to these best practices will result in suboptimal and outdated code.
34
+ </Operational Notes>`,
25
35
  isReadOnly: true,
26
36
  isLocalOnly: true,
27
37
  factory: () => {
@@ -9,4 +9,21 @@ import { z } from 'zod';
9
9
  export declare const DOC_SEARCH_TOOL: import("./tool-registry").McpToolDeclaration<{
10
10
  query: z.ZodString;
11
11
  includeTopContent: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
12
- }, z.ZodRawShape>;
12
+ }, {
13
+ results: z.ZodArray<z.ZodObject<{
14
+ title: z.ZodString;
15
+ breadcrumb: z.ZodString;
16
+ url: z.ZodString;
17
+ content: z.ZodOptional<z.ZodString>;
18
+ }, "strip", z.ZodTypeAny, {
19
+ title: string;
20
+ breadcrumb: string;
21
+ url: string;
22
+ content?: string | undefined;
23
+ }, {
24
+ title: string;
25
+ breadcrumb: string;
26
+ url: string;
27
+ content?: string | undefined;
28
+ }>, "many">;
29
+ }>;