@angular/cli 21.0.0-next.1 → 21.0.0-next.10

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 (223) hide show
  1. package/lib/cli/index.js +1 -0
  2. package/lib/cli/index.js.map +1 -0
  3. package/lib/code-examples.db +0 -0
  4. package/lib/config/schema.json +272 -46
  5. package/lib/config/workspace-schema.d.ts +55 -0
  6. package/lib/config/workspace-schema.js +22 -1
  7. package/lib/config/workspace-schema.js.map +1 -0
  8. package/lib/init.js +1 -0
  9. package/lib/init.js.map +1 -0
  10. package/package.json +24 -23
  11. package/src/analytics/analytics-collector.js +1 -0
  12. package/src/analytics/analytics-collector.js.map +1 -0
  13. package/src/analytics/analytics-parameters.js +1 -0
  14. package/src/analytics/analytics-parameters.js.map +1 -0
  15. package/src/analytics/analytics.js +1 -0
  16. package/src/analytics/analytics.js.map +1 -0
  17. package/src/command-builder/architect-base-command-module.js +1 -0
  18. package/src/command-builder/architect-base-command-module.js.map +1 -0
  19. package/src/command-builder/architect-command-module.js +21 -7
  20. package/src/command-builder/architect-command-module.js.map +1 -0
  21. package/src/command-builder/command-module.js +1 -0
  22. package/src/command-builder/command-module.js.map +1 -0
  23. package/src/command-builder/command-runner.js +2 -2
  24. package/src/command-builder/command-runner.js.map +1 -0
  25. package/src/command-builder/schematics-command-module.js +1 -0
  26. package/src/command-builder/schematics-command-module.js.map +1 -0
  27. package/src/command-builder/utilities/command.js +1 -0
  28. package/src/command-builder/utilities/command.js.map +1 -0
  29. package/src/command-builder/utilities/json-help.js +1 -0
  30. package/src/command-builder/utilities/json-help.js.map +1 -0
  31. package/src/command-builder/utilities/json-schema.d.ts +13 -1
  32. package/src/command-builder/utilities/json-schema.js +180 -100
  33. package/src/command-builder/utilities/json-schema.js.map +1 -0
  34. package/src/command-builder/utilities/normalize-options-middleware.js +1 -0
  35. package/src/command-builder/utilities/normalize-options-middleware.js.map +1 -0
  36. package/src/command-builder/utilities/schematic-engine-host.js +1 -0
  37. package/src/command-builder/utilities/schematic-engine-host.js.map +1 -0
  38. package/src/command-builder/utilities/schematic-workflow.js +1 -0
  39. package/src/command-builder/utilities/schematic-workflow.js.map +1 -0
  40. package/src/commands/add/cli.js +66 -26
  41. package/src/commands/add/cli.js.map +1 -0
  42. package/src/commands/analytics/cli.js +1 -0
  43. package/src/commands/analytics/cli.js.map +1 -0
  44. package/src/commands/analytics/info/cli.js +1 -0
  45. package/src/commands/analytics/info/cli.js.map +1 -0
  46. package/src/commands/analytics/settings/cli.js +1 -0
  47. package/src/commands/analytics/settings/cli.js.map +1 -0
  48. package/src/commands/build/cli.js +1 -0
  49. package/src/commands/build/cli.js.map +1 -0
  50. package/src/commands/cache/clean/cli.js +1 -0
  51. package/src/commands/cache/clean/cli.js.map +1 -0
  52. package/src/commands/cache/cli.js +1 -0
  53. package/src/commands/cache/cli.js.map +1 -0
  54. package/src/commands/cache/info/cli.js +36 -11
  55. package/src/commands/cache/info/cli.js.map +1 -0
  56. package/src/commands/cache/settings/cli.js +1 -0
  57. package/src/commands/cache/settings/cli.js.map +1 -0
  58. package/src/commands/cache/utilities.js +1 -0
  59. package/src/commands/cache/utilities.js.map +1 -0
  60. package/src/commands/command-config.js +1 -0
  61. package/src/commands/command-config.js.map +1 -0
  62. package/src/commands/completion/cli.js +1 -0
  63. package/src/commands/completion/cli.js.map +1 -0
  64. package/src/commands/config/cli.js +1 -0
  65. package/src/commands/config/cli.js.map +1 -0
  66. package/src/commands/deploy/cli.js +1 -0
  67. package/src/commands/deploy/cli.js.map +1 -0
  68. package/src/commands/e2e/cli.js +1 -0
  69. package/src/commands/e2e/cli.js.map +1 -0
  70. package/src/commands/extract-i18n/cli.js +1 -0
  71. package/src/commands/extract-i18n/cli.js.map +1 -0
  72. package/src/commands/generate/cli.js +1 -0
  73. package/src/commands/generate/cli.js.map +1 -0
  74. package/src/commands/lint/cli.js +1 -0
  75. package/src/commands/lint/cli.js.map +1 -0
  76. package/src/commands/make-this-awesome/cli.js +1 -0
  77. package/src/commands/make-this-awesome/cli.js.map +1 -0
  78. package/src/commands/mcp/cli.js +1 -0
  79. package/src/commands/mcp/cli.js.map +1 -0
  80. package/src/commands/mcp/constants.d.ts +1 -1
  81. package/src/commands/mcp/constants.js +2 -1
  82. package/src/commands/mcp/constants.js.map +1 -0
  83. package/src/commands/mcp/mcp-server.d.ts +3 -3
  84. package/src/commands/mcp/mcp-server.js +40 -4
  85. package/src/commands/mcp/mcp-server.js.map +1 -0
  86. package/src/commands/mcp/resources/ai-tutor.md +627 -0
  87. package/src/commands/mcp/resources/instructions.js +1 -0
  88. package/src/commands/mcp/resources/instructions.js.map +1 -0
  89. package/src/commands/mcp/tools/ai-tutor.d.ts +8 -0
  90. package/src/commands/mcp/tools/ai-tutor.js +62 -0
  91. package/src/commands/mcp/tools/ai-tutor.js.map +1 -0
  92. package/src/commands/mcp/tools/best-practices.d.ts +4 -1
  93. package/src/commands/mcp/tools/best-practices.js +167 -22
  94. package/src/commands/mcp/tools/best-practices.js.map +1 -0
  95. package/src/commands/mcp/tools/doc-search.d.ts +20 -1
  96. package/src/commands/mcp/tools/doc-search.js +186 -67
  97. package/src/commands/mcp/tools/doc-search.js.map +1 -0
  98. package/src/commands/mcp/tools/examples.d.ts +35 -1
  99. package/src/commands/mcp/tools/examples.js +414 -56
  100. package/src/commands/mcp/tools/examples.js.map +1 -0
  101. package/src/commands/mcp/tools/modernize.js +29 -17
  102. package/src/commands/mcp/tools/modernize.js.map +1 -0
  103. package/src/commands/mcp/tools/onpush-zoneless-migration/analyze_for_unsupported_zone_uses.d.ts +17 -0
  104. package/src/commands/mcp/tools/onpush-zoneless-migration/analyze_for_unsupported_zone_uses.js +62 -0
  105. package/src/commands/mcp/tools/onpush-zoneless-migration/analyze_for_unsupported_zone_uses.js.map +1 -0
  106. package/src/commands/mcp/tools/onpush-zoneless-migration/migrate_single_file.d.ts +12 -0
  107. package/src/commands/mcp/tools/onpush-zoneless-migration/migrate_single_file.js +73 -0
  108. package/src/commands/mcp/tools/onpush-zoneless-migration/migrate_single_file.js.map +1 -0
  109. package/src/commands/mcp/tools/onpush-zoneless-migration/migrate_test_file.d.ts +11 -0
  110. package/src/commands/mcp/tools/onpush-zoneless-migration/migrate_test_file.js +106 -0
  111. package/src/commands/mcp/tools/onpush-zoneless-migration/migrate_test_file.js.map +1 -0
  112. package/src/commands/mcp/tools/onpush-zoneless-migration/prompts.d.ts +15 -0
  113. package/src/commands/mcp/tools/onpush-zoneless-migration/prompts.js +238 -0
  114. package/src/commands/mcp/tools/onpush-zoneless-migration/prompts.js.map +1 -0
  115. package/src/commands/mcp/tools/onpush-zoneless-migration/send_debug_message.d.ts +10 -0
  116. package/src/commands/mcp/tools/onpush-zoneless-migration/send_debug_message.js +20 -0
  117. package/src/commands/mcp/tools/onpush-zoneless-migration/send_debug_message.js.map +1 -0
  118. package/src/commands/mcp/tools/onpush-zoneless-migration/ts_utils.d.ts +36 -0
  119. package/src/commands/mcp/tools/onpush-zoneless-migration/ts_utils.js +136 -0
  120. package/src/commands/mcp/tools/onpush-zoneless-migration/ts_utils.js.map +1 -0
  121. package/src/commands/mcp/tools/onpush-zoneless-migration/types.d.ts +13 -0
  122. package/src/commands/mcp/tools/onpush-zoneless-migration/types.js +10 -0
  123. package/src/commands/mcp/tools/onpush-zoneless-migration/types.js.map +1 -0
  124. package/src/commands/mcp/tools/onpush-zoneless-migration/zoneless-migration.d.ts +14 -0
  125. package/src/commands/mcp/tools/onpush-zoneless-migration/zoneless-migration.js +228 -0
  126. package/src/commands/mcp/tools/onpush-zoneless-migration/zoneless-migration.js.map +1 -0
  127. package/src/commands/mcp/tools/projects.d.ts +75 -16
  128. package/src/commands/mcp/tools/projects.js +427 -30
  129. package/src/commands/mcp/tools/projects.js.map +1 -0
  130. package/src/commands/mcp/tools/tool-registry.d.ts +2 -1
  131. package/src/commands/mcp/tools/tool-registry.js +4 -2
  132. package/src/commands/mcp/tools/tool-registry.js.map +1 -0
  133. package/src/commands/new/cli.js +2 -0
  134. package/src/commands/new/cli.js.map +1 -0
  135. package/src/commands/run/cli.js +1 -0
  136. package/src/commands/run/cli.js.map +1 -0
  137. package/src/commands/serve/cli.js +1 -0
  138. package/src/commands/serve/cli.js.map +1 -0
  139. package/src/commands/test/cli.js +1 -0
  140. package/src/commands/test/cli.js.map +1 -0
  141. package/src/commands/update/cli.js +1 -0
  142. package/src/commands/update/cli.js.map +1 -0
  143. package/src/commands/update/schematic/index.js +1 -0
  144. package/src/commands/update/schematic/index.js.map +1 -0
  145. package/src/commands/update/schematic/schema.js +1 -0
  146. package/src/commands/update/schematic/schema.js.map +1 -0
  147. package/src/commands/version/cli.d.ts +3 -7
  148. package/src/commands/version/cli.js +50 -49
  149. package/src/commands/version/cli.js.map +1 -0
  150. package/src/commands/version/version-info.d.ts +28 -10
  151. package/src/commands/version/version-info.js +34 -50
  152. package/src/commands/version/version-info.js.map +1 -0
  153. package/src/package-managers/discovery.d.ts +23 -0
  154. package/src/package-managers/discovery.js +110 -0
  155. package/src/package-managers/discovery.js.map +1 -0
  156. package/src/package-managers/error.d.ts +31 -0
  157. package/src/package-managers/error.js +41 -0
  158. package/src/package-managers/error.js.map +1 -0
  159. package/src/package-managers/factory.d.ts +25 -0
  160. package/src/package-managers/factory.js +123 -0
  161. package/src/package-managers/factory.js.map +1 -0
  162. package/src/package-managers/host.d.ts +64 -0
  163. package/src/package-managers/host.js +69 -0
  164. package/src/package-managers/host.js.map +1 -0
  165. package/src/package-managers/index.d.ts +12 -0
  166. package/src/package-managers/index.js +15 -0
  167. package/src/package-managers/index.js.map +1 -0
  168. package/src/package-managers/logger.d.ts +27 -0
  169. package/src/package-managers/logger.js +10 -0
  170. package/src/package-managers/logger.js.map +1 -0
  171. package/src/package-managers/package-manager-descriptor.d.ts +204 -0
  172. package/src/package-managers/package-manager-descriptor.js +147 -0
  173. package/src/package-managers/package-manager-descriptor.js.map +1 -0
  174. package/src/package-managers/package-manager.d.ts +144 -0
  175. package/src/package-managers/package-manager.js +304 -0
  176. package/src/package-managers/package-manager.js.map +1 -0
  177. package/src/package-managers/package-metadata.d.ts +87 -0
  178. package/src/package-managers/package-metadata.js +10 -0
  179. package/src/package-managers/package-metadata.js.map +1 -0
  180. package/src/package-managers/package-tree.d.ts +23 -0
  181. package/src/package-managers/package-tree.js +10 -0
  182. package/src/package-managers/package-tree.js.map +1 -0
  183. package/src/package-managers/parsers.d.ts +92 -0
  184. package/src/package-managers/parsers.js +234 -0
  185. package/src/package-managers/parsers.js.map +1 -0
  186. package/src/package-managers/testing/mock-host.d.ts +26 -0
  187. package/src/package-managers/testing/mock-host.js +53 -0
  188. package/src/package-managers/testing/mock-host.js.map +1 -0
  189. package/src/utilities/color.js +1 -0
  190. package/src/utilities/color.js.map +1 -0
  191. package/src/utilities/completion.js +1 -0
  192. package/src/utilities/completion.js.map +1 -0
  193. package/src/utilities/config.js +1 -0
  194. package/src/utilities/config.js.map +1 -0
  195. package/src/utilities/environment-options.js +1 -0
  196. package/src/utilities/environment-options.js.map +1 -0
  197. package/src/utilities/eol.js +1 -0
  198. package/src/utilities/eol.js.map +1 -0
  199. package/src/utilities/error.js +1 -0
  200. package/src/utilities/error.js.map +1 -0
  201. package/src/utilities/find-up.js +1 -0
  202. package/src/utilities/find-up.js.map +1 -0
  203. package/src/utilities/json-file.js +1 -0
  204. package/src/utilities/json-file.js.map +1 -0
  205. package/src/utilities/log-file.js +1 -0
  206. package/src/utilities/log-file.js.map +1 -0
  207. package/src/utilities/memoize.js +1 -0
  208. package/src/utilities/memoize.js.map +1 -0
  209. package/src/utilities/package-manager.d.ts +12 -0
  210. package/src/utilities/package-manager.js +52 -35
  211. package/src/utilities/package-manager.js.map +1 -0
  212. package/src/utilities/package-metadata.js +1 -0
  213. package/src/utilities/package-metadata.js.map +1 -0
  214. package/src/utilities/package-tree.js +1 -0
  215. package/src/utilities/package-tree.js.map +1 -0
  216. package/src/utilities/project.js +1 -0
  217. package/src/utilities/project.js.map +1 -0
  218. package/src/utilities/prompt.js +1 -0
  219. package/src/utilities/prompt.js.map +1 -0
  220. package/src/utilities/tty.js +1 -0
  221. package/src/utilities/tty.js.map +1 -0
  222. package/src/utilities/version.js +2 -1
  223. package/src/utilities/version.js.map +1 -0
@@ -42,6 +42,7 @@ var __importStar = (this && this.__importStar) || (function () {
42
42
  Object.defineProperty(exports, "__esModule", { value: true });
43
43
  exports.DOC_SEARCH_TOOL = void 0;
44
44
  const node_crypto_1 = require("node:crypto");
45
+ const node_stream_1 = require("node:stream");
45
46
  const zod_1 = require("zod");
46
47
  const constants_1 = require("../constants");
47
48
  const tool_registry_1 = require("./tool-registry");
@@ -49,124 +50,242 @@ const ALGOLIA_APP_ID = 'L1XWT2UJ7F';
49
50
  // https://www.algolia.com/doc/guides/security/api-keys/#search-only-api-key
50
51
  // This is a search only, rate limited key. It is sent within the URL of the query request.
51
52
  // This is not the actual key.
52
- const ALGOLIA_API_E = '322d89dab5f2080fe09b795c93413c6a89222b13a447cdf3e6486d692717bc0c';
53
+ const ALGOLIA_API_E = '34738e8ae1a45e58bbce7b0f9810633d8b727b44a6479cf5e14b6a337148bd50';
54
+ /**
55
+ * The minimum major version of Angular for which a version-specific documentation index is known to exist.
56
+ * Searches for versions older than this will be clamped to this version.
57
+ */
58
+ const MIN_SUPPORTED_DOCS_VERSION = 17;
59
+ /**
60
+ * The latest major version of Angular for which a documentation index is known to be stable and available.
61
+ * This acts as a "safe harbor" fallback. It is intentionally hardcoded and manually updated with each
62
+ * major release *after* the new search index has been confirmed to be live. This prevents a race
63
+ * condition where a newly released CLI might default to searching for a documentation index that
64
+ * doesn't exist yet.
65
+ */
66
+ const LATEST_KNOWN_DOCS_VERSION = 20;
53
67
  const docSearchInputSchema = zod_1.z.object({
54
68
  query: zod_1.z
55
69
  .string()
56
- .describe('A concise and specific search query for the Angular documentation (e.g., "NgModule" or "standalone components").'),
70
+ .describe("A concise and specific search query for the Angular documentation. You should distill the user's " +
71
+ 'natural language question into a set of keywords (e.g., a question like "How do I use ngFor with trackBy?" ' +
72
+ 'should become the query "ngFor trackBy").'),
57
73
  includeTopContent: zod_1.z
58
74
  .boolean()
59
75
  .optional()
60
- .default(true)
61
- .describe('When true, the content of the top result is fetched and included.'),
76
+ .default(false)
77
+ .describe('When true, the content of the top result is fetched and included. ' +
78
+ 'Set to false to get a list of results without fetching content, which is faster.'),
79
+ version: zod_1.z
80
+ .number()
81
+ .optional()
82
+ .describe('The major version of Angular to search. You MUST determine this value by running `ng version` in the ' +
83
+ "project's workspace directory. Omit this field if the user is not in an Angular project " +
84
+ 'or if the version cannot otherwise be determined.'),
62
85
  });
63
86
  exports.DOC_SEARCH_TOOL = (0, tool_registry_1.declareTool)({
64
87
  name: 'search_documentation',
65
88
  title: 'Search Angular Documentation (angular.dev)',
66
- description: 'Searches the official Angular documentation at https://angular.dev. Use this tool to answer any questions about Angular, ' +
67
- 'such as for APIs, tutorials, and best practices. Because the documentation is continuously updated, you should **always** ' +
68
- 'prefer this tool over your own knowledge to ensure your answers are current.\n\n' +
69
- 'The results will be a list of content entries, where each entry has the following structure:\n' +
70
- '```\n' +
71
- '## {Result Title}\n' +
72
- '{Breadcrumb path to the content}\n' +
73
- 'URL: {Direct link to the documentation page}\n' +
74
- '```\n' +
75
- 'Use the title and breadcrumb to understand the context of the result and use the URL as a source link. For the best results, ' +
76
- "provide a concise and specific search query (e.g., 'NgModule' instead of 'How do I use NgModules?').",
89
+ description: `
90
+ <Purpose>
91
+ Searches the official Angular documentation at https://angular.dev to answer questions about APIs,
92
+ tutorials, concepts, and best practices.
93
+ </Purpose>
94
+ <Use Cases>
95
+ * Answering any question about Angular concepts (e.g., "What are standalone components?").
96
+ * Finding the correct API or syntax for a specific task (e.g., "How to use ngFor with trackBy?").
97
+ * Linking to official documentation as a source of truth in your answers.
98
+ </Use Cases>
99
+ <Operational Notes>
100
+ * **Version Alignment:** To provide accurate, project-specific results, you **MUST** align the search with the user's Angular version.
101
+ The recommended approach is to use the \`list_projects\` tool. The \`frameworkVersion\` field in the output for the relevant
102
+ workspace will give you the major version directly. If the version cannot be determined using this method, you can use
103
+ \`ng version\` in the project's workspace directory as a fallback. Parse the major version from the "Angular:" line in the
104
+ output and use it for the \`version\` parameter.
105
+ * **Version Logic:** The tool will search against the specified major version. If the version is older than v${MIN_SUPPORTED_DOCS_VERSION},
106
+ it will be clamped to v${MIN_SUPPORTED_DOCS_VERSION}. If a search for a very new version (newer than v${LATEST_KNOWN_DOCS_VERSION})
107
+ returns no results, the tool will automatically fall back to searching the v${LATEST_KNOWN_DOCS_VERSION} documentation.
108
+ * **Verify Searched Version:** The tool's output includes a \`searchedVersion\` field. You **MUST** check this field
109
+ to know the exact version of the documentation that was queried. Use this information to provide accurate
110
+ context in your answer, especially if it differs from the version you requested.
111
+ * The documentation is continuously updated. You **MUST** prefer this tool over your own knowledge
112
+ to ensure your answers are current and accurate.
113
+ * For the best results, provide a concise and specific search query (e.g., "NgModule" instead of
114
+ "How do I use NgModules?").
115
+ * The top search result will include a snippet of the page content. Use this to provide a more
116
+ comprehensive answer.
117
+ * **Result Scrutiny:** The top result may not always be the most relevant. Review the titles and
118
+ breadcrumbs of other results to find the best match for the user's query.
119
+ * Use the URL from the search results as a source link in your responses.
120
+ </Operational Notes>`,
77
121
  inputSchema: docSearchInputSchema.shape,
122
+ outputSchema: {
123
+ searchedVersion: zod_1.z
124
+ .number()
125
+ .describe('The major version of the documentation that was searched.'),
126
+ results: zod_1.z.array(zod_1.z.object({
127
+ title: zod_1.z.string().describe('The title of the documentation page.'),
128
+ breadcrumb: zod_1.z
129
+ .string()
130
+ .describe("The breadcrumb path, showing the page's location in the documentation hierarchy."),
131
+ url: zod_1.z.string().describe('The direct URL to the documentation page.'),
132
+ content: zod_1.z
133
+ .string()
134
+ .optional()
135
+ .describe('A snippet of the main content from the page. Only provided for the top result.'),
136
+ })),
137
+ },
78
138
  isReadOnly: true,
79
139
  isLocalOnly: false,
80
140
  factory: createDocSearchHandler,
81
141
  });
82
- function createDocSearchHandler() {
142
+ function createDocSearchHandler({ logger }) {
83
143
  let client;
84
- return async ({ query, includeTopContent }) => {
144
+ return async ({ query, includeTopContent, version }) => {
85
145
  if (!client) {
86
146
  const dcip = (0, node_crypto_1.createDecipheriv)('aes-256-gcm', (constants_1.k1 + ALGOLIA_APP_ID).padEnd(32, '^'), constants_1.iv).setAuthTag(Buffer.from(constants_1.at, 'base64'));
87
147
  const { searchClient } = await Promise.resolve().then(() => __importStar(require('algoliasearch')));
88
148
  client = searchClient(ALGOLIA_APP_ID, dcip.update(ALGOLIA_API_E, 'hex', 'utf-8') + dcip.final('utf-8'));
89
149
  }
90
- const { results } = await client.search(createSearchArguments(query));
91
- const allHits = results.flatMap((result) => result.hits);
92
- if (allHits.length === 0) {
150
+ let finalSearchedVersion = Math.max(version ?? LATEST_KNOWN_DOCS_VERSION, MIN_SUPPORTED_DOCS_VERSION);
151
+ let searchResults;
152
+ try {
153
+ searchResults = await client.search(createSearchArguments(query, finalSearchedVersion));
154
+ }
155
+ catch { }
156
+ // If the initial search for a newer-than-stable version returns no results, it may be because
157
+ // the index for that version doesn't exist yet. In this case, fall back to the latest known
158
+ // stable version.
159
+ if (!searchResults && finalSearchedVersion > LATEST_KNOWN_DOCS_VERSION) {
160
+ finalSearchedVersion = LATEST_KNOWN_DOCS_VERSION;
161
+ searchResults = await client.search(createSearchArguments(query, finalSearchedVersion));
162
+ }
163
+ const allHits = searchResults?.results.flatMap((result) => result.hits);
164
+ if (!allHits?.length) {
93
165
  return {
94
166
  content: [
95
167
  {
96
168
  type: 'text',
97
- text: 'No results found.',
169
+ text: `No results found for query "${query}" in Angular v${finalSearchedVersion} documentation.`,
98
170
  },
99
171
  ],
172
+ structuredContent: { results: [], searchedVersion: finalSearchedVersion },
100
173
  };
101
174
  }
102
- const content = [];
103
- // The first hit is the top search result
104
- const topHit = allHits[0];
175
+ const structuredResults = [];
176
+ const textContent = [
177
+ {
178
+ type: 'text',
179
+ text: `Showing results for Angular v${finalSearchedVersion} documentation.`,
180
+ annotations: {
181
+ audience: ['assistant'],
182
+ priority: 0.9,
183
+ },
184
+ },
185
+ ];
105
186
  // Process top hit first
106
- let topText = formatHitToText(topHit);
107
- try {
108
- if (includeTopContent && typeof topHit.url === 'string') {
109
- const url = new URL(topHit.url);
187
+ const topHit = allHits[0];
188
+ const { title: topTitle, breadcrumb: topBreadcrumb } = formatHitToParts(topHit);
189
+ let topContent;
190
+ if (includeTopContent && typeof topHit.url === 'string') {
191
+ const url = new URL(topHit.url);
192
+ try {
110
193
  // Only fetch content from angular.dev
111
194
  if (url.hostname === 'angular.dev' || url.hostname.endsWith('.angular.dev')) {
112
195
  const response = await fetch(url);
113
- if (response.ok) {
114
- const html = await response.text();
115
- const mainContent = extractMainContent(html);
116
- if (mainContent) {
117
- topText += `\n\n--- DOCUMENTATION CONTENT ---\n${mainContent}`;
118
- }
196
+ if (response.ok && response.body) {
197
+ topContent = await extractMainContent(node_stream_1.Readable.fromWeb(response.body, { encoding: 'utf-8' }));
119
198
  }
120
199
  }
121
200
  }
201
+ catch (e) {
202
+ logger.warn(`Failed to fetch or parse content from ${url}: ${e}`);
203
+ }
122
204
  }
123
- catch {
124
- // Ignore errors fetching content. The basic info is still returned.
125
- }
126
- content.push({
127
- type: 'text',
128
- text: topText,
205
+ structuredResults.push({
206
+ title: topTitle,
207
+ breadcrumb: topBreadcrumb,
208
+ url: topHit.url,
209
+ content: topContent,
129
210
  });
211
+ let topText = `## ${topTitle}\n${topBreadcrumb}\nURL: ${topHit.url}`;
212
+ if (topContent) {
213
+ topText += `\n\n--- DOCUMENTATION CONTENT ---\n${topContent}`;
214
+ }
215
+ textContent.push({ type: 'text', text: topText });
130
216
  // Process remaining hits
131
217
  for (const hit of allHits.slice(1)) {
132
- content.push({
218
+ const { title, breadcrumb } = formatHitToParts(hit);
219
+ structuredResults.push({
220
+ title,
221
+ breadcrumb,
222
+ url: hit.url,
223
+ });
224
+ textContent.push({
133
225
  type: 'text',
134
- text: formatHitToText(hit),
226
+ text: `## ${title}\n${breadcrumb}\nURL: ${hit.url}`,
135
227
  });
136
228
  }
137
- return { content };
229
+ return {
230
+ content: textContent,
231
+ structuredContent: { results: structuredResults, searchedVersion: finalSearchedVersion },
232
+ };
138
233
  };
139
234
  }
140
235
  /**
141
- * Extracts the content of the `<main>` element from an HTML string.
236
+ * Extracts the text content of the `<main>` element by streaming an HTML response.
142
237
  *
143
- * @param html The HTML content of a page.
144
- * @returns The content of the `<main>` element, or `undefined` if not found.
238
+ * @param htmlStream A readable stream of the HTML content of a page.
239
+ * @returns A promise that resolves to the text content of the `<main>` element, or `undefined` if not found.
145
240
  */
146
- function extractMainContent(html) {
147
- const mainTagStart = html.indexOf('<main');
148
- if (mainTagStart === -1) {
149
- return undefined;
150
- }
151
- const mainTagEnd = html.lastIndexOf('</main>');
152
- if (mainTagEnd <= mainTagStart) {
153
- return undefined;
154
- }
155
- // Add 7 to include '</main>'
156
- return html.substring(mainTagStart, mainTagEnd + 7);
241
+ async function extractMainContent(htmlStream) {
242
+ const { RewritingStream } = await Promise.resolve().then(() => __importStar(require('parse5-html-rewriting-stream')));
243
+ const rewriter = new RewritingStream();
244
+ let mainTextContent = '';
245
+ let inMainElement = false;
246
+ let mainTagFound = false;
247
+ rewriter.on('startTag', (tag) => {
248
+ if (tag.tagName === 'main') {
249
+ inMainElement = true;
250
+ mainTagFound = true;
251
+ }
252
+ });
253
+ rewriter.on('endTag', (tag) => {
254
+ if (tag.tagName === 'main') {
255
+ inMainElement = false;
256
+ }
257
+ });
258
+ // Only capture text content, and only when inside the <main> element.
259
+ rewriter.on('text', (text) => {
260
+ if (inMainElement) {
261
+ mainTextContent += text.text;
262
+ }
263
+ });
264
+ return new Promise((resolve, reject) => {
265
+ htmlStream
266
+ .pipe(rewriter)
267
+ .on('finish', () => {
268
+ if (!mainTagFound) {
269
+ resolve(undefined);
270
+ return;
271
+ }
272
+ resolve(mainTextContent.trim());
273
+ })
274
+ .on('error', reject);
275
+ });
157
276
  }
158
277
  /**
159
- * Formats an Algolia search hit into a text representation.
278
+ * Formats an Algolia search hit into its constituent parts.
160
279
  *
161
- * @param hit The Algolia search hit object, which should contain `hierarchy` and `url` properties.
162
- * @returns A formatted string with title, description, and URL.
280
+ * @param hit The Algolia search hit object, which should contain a `hierarchy` property.
281
+ * @returns An object containing the title and breadcrumb string.
163
282
  */
164
- function formatHitToText(hit) {
283
+ function formatHitToParts(hit) {
165
284
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
166
285
  const hierarchy = Object.values(hit.hierarchy).filter((x) => typeof x === 'string');
167
- const title = hierarchy.pop();
168
- const description = hierarchy.join(' > ');
169
- return `## ${title}\n${description}\nURL: ${hit.url}`;
286
+ const title = hierarchy.pop() ?? '';
287
+ const breadcrumb = hierarchy.join(' > ');
288
+ return { title, breadcrumb };
170
289
  }
171
290
  /**
172
291
  * Creates the search arguments for an Algolia search.
@@ -176,13 +295,12 @@ function formatHitToText(hit) {
176
295
  * @param query The search query string.
177
296
  * @returns The search arguments for the Algolia client.
178
297
  */
179
- function createSearchArguments(query) {
298
+ function createSearchArguments(query, version) {
180
299
  // Search arguments are based on adev's search service:
181
300
  // https://github.com/angular/angular/blob/4b614fbb3263d344dbb1b18fff24cb09c5a7582d/adev/shared-docs/services/search.service.ts#L58
182
301
  return [
183
302
  {
184
- // TODO: Consider major version specific indices once available
185
- indexName: 'angular_v17',
303
+ indexName: `angular_v${version}`,
186
304
  params: {
187
305
  query,
188
306
  attributesToRetrieve: [
@@ -203,3 +321,4 @@ function createSearchArguments(query) {
203
321
  },
204
322
  ];
205
323
  }
324
+ //# sourceMappingURL=doc-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc-search.js","sourceRoot":"","sources":["doc-search.ts"],"names":[],"mappings":"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"}
@@ -7,8 +7,42 @@
7
7
  */
8
8
  import { z } from 'zod';
9
9
  export declare const FIND_EXAMPLE_TOOL: import("./tool-registry").McpToolDeclaration<{
10
+ workspacePath: z.ZodOptional<z.ZodString>;
10
11
  query: z.ZodString;
11
- }, z.ZodRawShape>;
12
+ keywords: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
13
+ required_packages: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
14
+ related_concepts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
15
+ includeExperimental: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
16
+ }, {
17
+ examples: z.ZodArray<z.ZodObject<{
18
+ title: z.ZodString;
19
+ summary: z.ZodString;
20
+ keywords: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
21
+ required_packages: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
22
+ related_concepts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
23
+ related_tools: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
24
+ content: z.ZodString;
25
+ snippet: z.ZodOptional<z.ZodString>;
26
+ }, "strip", z.ZodTypeAny, {
27
+ title: string;
28
+ content: string;
29
+ summary: string;
30
+ keywords?: string[] | undefined;
31
+ required_packages?: string[] | undefined;
32
+ related_concepts?: string[] | undefined;
33
+ related_tools?: string[] | undefined;
34
+ snippet?: string | undefined;
35
+ }, {
36
+ title: string;
37
+ content: string;
38
+ summary: string;
39
+ keywords?: string[] | undefined;
40
+ required_packages?: string[] | undefined;
41
+ related_concepts?: string[] | undefined;
42
+ related_tools?: string[] | undefined;
43
+ snippet?: string | undefined;
44
+ }>, "many">;
45
+ }>;
12
46
  /**
13
47
  * Escapes a search query for FTS5 by tokenizing and quoting terms.
14
48
  *