@yinuo-ngm/mcp-server 0.1.1 → 0.1.3

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 (221) hide show
  1. package/README.md +225 -188
  2. package/lib/audit/audit-event.d.ts +14 -0
  3. package/lib/audit/audit-event.js +2 -0
  4. package/lib/audit/audit-log.service.d.ts +7 -0
  5. package/lib/audit/audit-log.service.js +187 -0
  6. package/lib/audit/redact.d.ts +3 -0
  7. package/lib/audit/redact.js +28 -0
  8. package/lib/catalog/capabilities/blocked-local-actions.d.ts +1 -0
  9. package/lib/catalog/capabilities/blocked-local-actions.js +18 -0
  10. package/lib/catalog/capabilities/frontend-standard.d.ts +2 -0
  11. package/lib/catalog/capabilities/frontend-standard.js +36 -0
  12. package/lib/catalog/capabilities/hub-v2.d.ts +2 -0
  13. package/lib/catalog/capabilities/hub-v2.js +34 -0
  14. package/lib/catalog/capabilities/nginx.d.ts +2 -0
  15. package/lib/catalog/capabilities/nginx.js +23 -0
  16. package/lib/catalog/capabilities/project.d.ts +2 -0
  17. package/lib/catalog/capabilities/project.js +23 -0
  18. package/lib/catalog/capabilities/router.d.ts +2 -0
  19. package/lib/catalog/capabilities/router.js +11 -0
  20. package/lib/catalog/capabilities/runtime.d.ts +2 -0
  21. package/lib/catalog/capabilities/runtime.js +17 -0
  22. package/lib/catalog/capabilities/workspace.d.ts +2 -0
  23. package/lib/catalog/capabilities/workspace.js +23 -0
  24. package/lib/catalog/helpers.d.ts +3 -0
  25. package/lib/catalog/helpers.js +42 -0
  26. package/lib/catalog/index.d.ts +4 -0
  27. package/lib/catalog/index.js +23 -0
  28. package/lib/catalog/tools/frontend-standard.d.ts +2 -0
  29. package/lib/catalog/tools/frontend-standard.js +166 -0
  30. package/lib/catalog/tools/hub-v2-api.d.ts +2 -0
  31. package/lib/catalog/tools/hub-v2-api.js +124 -0
  32. package/lib/catalog/tools/hub-v2-docs.d.ts +2 -0
  33. package/lib/catalog/tools/hub-v2-docs.js +40 -0
  34. package/lib/catalog/tools/nginx.d.ts +2 -0
  35. package/lib/catalog/tools/nginx.js +96 -0
  36. package/lib/catalog/tools/project.d.ts +2 -0
  37. package/lib/catalog/tools/project.js +138 -0
  38. package/lib/catalog/tools/router.d.ts +2 -0
  39. package/lib/catalog/tools/router.js +26 -0
  40. package/lib/catalog/tools/runtime.d.ts +2 -0
  41. package/lib/catalog/tools/runtime.js +47 -0
  42. package/lib/catalog/tools/workspace.d.ts +2 -0
  43. package/lib/catalog/tools/workspace.js +75 -0
  44. package/lib/catalog/types.d.ts +15 -0
  45. package/lib/catalog/types.js +2 -0
  46. package/lib/context/create-tool-context.js +11 -10
  47. package/lib/context/local-server-client.d.ts +2 -0
  48. package/lib/context/local-server-client.js +174 -0
  49. package/lib/context/tool-context.d.ts +36 -0
  50. package/lib/doctor.d.ts +8 -0
  51. package/lib/doctor.js +221 -0
  52. package/lib/errors/error-codes.d.ts +12 -0
  53. package/lib/errors/error-codes.js +14 -0
  54. package/lib/errors/mcp-tool-error.d.ts +8 -0
  55. package/lib/errors/mcp-tool-error.js +14 -0
  56. package/lib/filesystem/project-files.d.ts +18 -0
  57. package/lib/filesystem/project-files.js +112 -0
  58. package/lib/git/local-git-read-service.d.ts +2 -0
  59. package/lib/git/local-git-read-service.js +96 -0
  60. package/lib/index.d.ts +1 -0
  61. package/lib/index.js +4 -0
  62. package/lib/policy/assert-tool-policy.js +10 -1
  63. package/lib/register-tools.js +70 -9
  64. package/lib/registry/tool-names.d.ts +95 -0
  65. package/lib/registry/tool-names.js +97 -0
  66. package/lib/services/path-guard.service.d.ts +4 -0
  67. package/lib/services/path-guard.service.js +75 -0
  68. package/lib/services/permission.service.d.ts +5 -0
  69. package/lib/services/permission.service.js +38 -0
  70. package/lib/services/project-resolver.service.d.ts +32 -0
  71. package/lib/services/project-resolver.service.js +95 -0
  72. package/lib/standard/frontend-standard.default.d.ts +2 -0
  73. package/lib/standard/frontend-standard.default.js +51 -0
  74. package/lib/standard/frontend-standard.schema.d.ts +196 -0
  75. package/lib/standard/frontend-standard.schema.js +61 -0
  76. package/lib/standard/frontend-standard.service.d.ts +79 -0
  77. package/lib/standard/frontend-standard.service.js +115 -0
  78. package/lib/standard/project-scan.d.ts +9 -0
  79. package/lib/standard/project-scan.js +91 -0
  80. package/lib/standard/validators/angular-structure.validator.d.ts +4 -0
  81. package/lib/standard/validators/angular-structure.validator.js +75 -0
  82. package/lib/standard/validators/component.validator.d.ts +4 -0
  83. package/lib/standard/validators/component.validator.js +94 -0
  84. package/lib/standard/validators/git.validator.d.ts +8 -0
  85. package/lib/standard/validators/git.validator.js +32 -0
  86. package/lib/standard/validators/review.validator.d.ts +15 -0
  87. package/lib/standard/validators/review.validator.js +67 -0
  88. package/lib/standard/validators/test.validator.d.ts +19 -0
  89. package/lib/standard/validators/test.validator.js +89 -0
  90. package/lib/tool-catalog.d.ts +2 -0
  91. package/lib/tool-catalog.js +6 -0
  92. package/lib/tools/angular/angular-standard.tools.d.ts +2 -0
  93. package/lib/tools/angular/angular-standard.tools.js +53 -0
  94. package/lib/tools/angular/index.d.ts +1 -0
  95. package/lib/tools/angular/index.js +5 -0
  96. package/lib/tools/capability.tools.d.ts +2 -0
  97. package/lib/tools/capability.tools.js +205 -0
  98. package/lib/tools/controlled/index.d.ts +2 -0
  99. package/lib/tools/controlled/index.js +13 -0
  100. package/lib/tools/controlled/local-server.d.ts +6 -0
  101. package/lib/tools/controlled/local-server.js +17 -0
  102. package/lib/tools/controlled/operation-policy.d.ts +22 -0
  103. package/lib/tools/controlled/operation-policy.js +50 -0
  104. package/lib/tools/controlled/operation-result.d.ts +30 -0
  105. package/lib/tools/controlled/operation-result.js +33 -0
  106. package/lib/tools/controlled/schemas.d.ts +159 -0
  107. package/lib/tools/controlled/schemas.js +49 -0
  108. package/lib/tools/controlled.tools.d.ts +1 -0
  109. package/lib/tools/controlled.tools.js +5 -0
  110. package/lib/tools/file-write.tools.d.ts +2 -0
  111. package/lib/tools/file-write.tools.js +70 -0
  112. package/lib/tools/git.tools.js +109 -8
  113. package/lib/tools/hub-v2/client.d.ts +20 -0
  114. package/lib/tools/hub-v2/client.js +112 -0
  115. package/lib/tools/hub-v2/config/config-paths.d.ts +2 -0
  116. package/lib/tools/hub-v2/config/config-paths.js +17 -0
  117. package/lib/tools/hub-v2/config/env.d.ts +1 -0
  118. package/lib/tools/hub-v2/config/env.js +12 -0
  119. package/lib/tools/hub-v2/config/index.d.ts +8 -0
  120. package/lib/tools/hub-v2/config/index.js +18 -0
  121. package/lib/tools/hub-v2/config/jsonc.d.ts +5 -0
  122. package/lib/tools/hub-v2/config/jsonc.js +86 -0
  123. package/lib/tools/hub-v2/config/load-config.d.ts +18 -0
  124. package/lib/tools/hub-v2/config/load-config.js +93 -0
  125. package/lib/tools/hub-v2/config/project-selector.d.ts +5 -0
  126. package/lib/tools/hub-v2/config/project-selector.js +92 -0
  127. package/lib/tools/hub-v2/config/resolve-context.d.ts +13 -0
  128. package/lib/tools/hub-v2/config/resolve-context.js +33 -0
  129. package/lib/tools/hub-v2/docs.tools.d.ts +2 -0
  130. package/lib/tools/hub-v2/docs.tools.js +215 -0
  131. package/lib/tools/hub-v2/errors.d.ts +8 -0
  132. package/lib/tools/hub-v2/errors.js +27 -0
  133. package/lib/tools/hub-v2/index.d.ts +2 -0
  134. package/lib/tools/hub-v2/index.js +19 -0
  135. package/lib/tools/hub-v2/issues-workflow.tools.d.ts +2 -0
  136. package/lib/tools/hub-v2/issues-workflow.tools.js +199 -0
  137. package/lib/tools/hub-v2/issues.tools.d.ts +2 -0
  138. package/lib/tools/hub-v2/issues.tools.js +244 -0
  139. package/lib/tools/hub-v2/projects.tools.d.ts +2 -0
  140. package/lib/tools/hub-v2/projects.tools.js +41 -0
  141. package/lib/tools/hub-v2/raw.d.ts +8 -0
  142. package/lib/tools/hub-v2/raw.js +33 -0
  143. package/lib/tools/hub-v2/rd.tools.d.ts +2 -0
  144. package/lib/tools/hub-v2/rd.tools.js +361 -0
  145. package/lib/tools/hub-v2/schemas.d.ts +1182 -0
  146. package/lib/tools/hub-v2/schemas.js +318 -0
  147. package/lib/tools/hub-v2/upload.tools.d.ts +2 -0
  148. package/lib/tools/hub-v2/upload.tools.js +198 -0
  149. package/lib/tools/index.d.ts +3 -0
  150. package/lib/tools/index.js +24 -0
  151. package/lib/tools/log.tools.js +33 -6
  152. package/lib/tools/nginx/index.d.ts +1 -0
  153. package/lib/tools/nginx/index.js +5 -0
  154. package/lib/tools/nginx/nginx-control.tools.d.ts +2 -0
  155. package/lib/tools/nginx/nginx-control.tools.js +133 -0
  156. package/lib/tools/nginx/nginx-proxy.d.ts +24 -0
  157. package/lib/tools/nginx/nginx-proxy.js +154 -0
  158. package/lib/tools/nginx.tools.d.ts +2 -0
  159. package/lib/tools/nginx.tools.js +111 -0
  160. package/lib/tools/project/index.d.ts +2 -0
  161. package/lib/tools/project/index.js +7 -0
  162. package/lib/tools/project/launch-status.d.ts +10 -0
  163. package/lib/tools/project/launch-status.js +78 -0
  164. package/lib/tools/project/local-diagnostics.d.ts +19 -0
  165. package/lib/tools/project/local-diagnostics.js +97 -0
  166. package/lib/tools/project/observe-redaction.d.ts +3 -0
  167. package/lib/tools/project/observe-redaction.js +25 -0
  168. package/lib/tools/project/observe-runtime.d.ts +72 -0
  169. package/lib/tools/project/observe-runtime.js +147 -0
  170. package/lib/tools/project/project-control.tools.d.ts +2 -0
  171. package/lib/tools/project/project-control.tools.js +216 -0
  172. package/lib/tools/project/project-observe.tools.d.ts +2 -0
  173. package/lib/tools/project/project-observe.tools.js +191 -0
  174. package/lib/tools/project/runtime-config.d.ts +7 -0
  175. package/lib/tools/project/runtime-config.js +50 -0
  176. package/lib/tools/project-observe.tools.d.ts +1 -0
  177. package/lib/tools/project-observe.tools.js +5 -0
  178. package/lib/tools/project.tools.d.ts +8 -0
  179. package/lib/tools/project.tools.js +97 -6
  180. package/lib/tools/proxy.tools.js +4 -4
  181. package/lib/tools/review/index.d.ts +1 -0
  182. package/lib/tools/review/index.js +5 -0
  183. package/lib/tools/review/review.tools.d.ts +2 -0
  184. package/lib/tools/review/review.tools.js +152 -0
  185. package/lib/tools/runtime/index.d.ts +1 -0
  186. package/lib/tools/runtime/index.js +5 -0
  187. package/lib/tools/runtime/runtime-control.tools.d.ts +2 -0
  188. package/lib/tools/runtime/runtime-control.tools.js +89 -0
  189. package/lib/tools/runtime.tools.js +41 -4
  190. package/lib/tools/standard/index.d.ts +1 -0
  191. package/lib/tools/standard/index.js +5 -0
  192. package/lib/tools/standard/standard.tools.d.ts +2 -0
  193. package/lib/tools/standard/standard.tools.js +91 -0
  194. package/lib/tools/task.tools.js +44 -9
  195. package/lib/tools/test/index.d.ts +1 -0
  196. package/lib/tools/test/index.js +5 -0
  197. package/lib/tools/test/test-standard.tools.d.ts +2 -0
  198. package/lib/tools/test/test-standard.tools.js +51 -0
  199. package/lib/tools/tool-catalog.d.ts +2 -0
  200. package/lib/tools/tool-catalog.js +7 -0
  201. package/lib/tools/workflow/frontend-workflow.tools.d.ts +2 -0
  202. package/lib/tools/workflow/frontend-workflow.tools.js +364 -0
  203. package/lib/tools/workflow/index.d.ts +1 -0
  204. package/lib/tools/workflow/index.js +5 -0
  205. package/lib/tools/workspace-package.d.ts +22 -0
  206. package/lib/tools/workspace-package.js +130 -0
  207. package/lib/tools/workspace.tools.d.ts +7 -0
  208. package/lib/tools/workspace.tools.js +336 -0
  209. package/lib/utils/errors.d.ts +5 -0
  210. package/lib/utils/errors.js +17 -0
  211. package/lib/utils/result.d.ts +20 -2
  212. package/lib/utils/result.js +108 -3
  213. package/lib/workflow/frontend-task.schema.d.ts +83 -0
  214. package/lib/workflow/frontend-task.schema.js +25 -0
  215. package/lib/workflow/frontend-task.service.d.ts +57 -0
  216. package/lib/workflow/frontend-task.service.js +195 -0
  217. package/lib/workflow/workflow-status.d.ts +2 -0
  218. package/lib/workflow/workflow-status.js +14 -0
  219. package/lib/workflow/workflow-transition.d.ts +9 -0
  220. package/lib/workflow/workflow-transition.js +38 -0
  221. package/package.json +10 -4
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.validateComponentNaming = validateComponentNaming;
37
+ exports.validateComponentBoundary = validateComponentBoundary;
38
+ const path = __importStar(require("path"));
39
+ const frontend_standard_schema_1 = require("../frontend-standard.schema");
40
+ const angular_structure_validator_1 = require("./angular-structure.validator");
41
+ function isComponentTs(file) {
42
+ return file.path.endsWith(".component.ts") || file.path.endsWith(".page.ts");
43
+ }
44
+ function hasAllowedSuffix(filePath, standard) {
45
+ const base = path.basename(filePath).replace(/\.ts$/, "");
46
+ return standard.naming.componentSuffixes.some((suffix) => base.endsWith(`.${suffix}`) || base.endsWith(`-${suffix}`));
47
+ }
48
+ function validateComponentNaming(files, standard) {
49
+ const findings = files
50
+ .filter(isComponentTs)
51
+ .filter((file) => !hasAllowedSuffix(file.path, standard))
52
+ .map((file) => ({
53
+ ruleId: "angular.component-naming",
54
+ severity: "warning",
55
+ message: "Component file name does not use an expected page/component/dialog/drawer/table/form suffix.",
56
+ file: file.path,
57
+ suggestion: "Rename the component file or adjust naming.componentSuffixes in frontend-standard.json.",
58
+ }));
59
+ return (0, frontend_standard_schema_1.summarizeFindings)(findings);
60
+ }
61
+ function validateComponentBoundary(files, standard) {
62
+ const findings = [...(0, angular_structure_validator_1.validatePagePlacement)(files, standard)];
63
+ for (const file of files.filter((item) => item.path.endsWith(".ts"))) {
64
+ const text = file.text ?? "";
65
+ if (isComponentTs(file) && file.lineCount && file.lineCount > standard.structure.maxComponentFileLines) {
66
+ findings.push({
67
+ ruleId: "angular.component-size",
68
+ severity: "warning",
69
+ message: `Component file has ${file.lineCount} lines, above configured limit ${standard.structure.maxComponentFileLines}.`,
70
+ file: file.path,
71
+ suggestion: "Split large component logic into services, child components, or focused helpers.",
72
+ });
73
+ }
74
+ if (/\bany\b/.test(text)) {
75
+ findings.push({
76
+ ruleId: "typescript.no-obvious-any",
77
+ severity: "warning",
78
+ message: "File contains obvious any usage.",
79
+ file: file.path,
80
+ suggestion: "Replace any with explicit DTO, model, generic, or unknown at external boundaries.",
81
+ });
82
+ }
83
+ if (/https?:\/\/(?!127\.0\.0\.1|localhost|::1)[^\s'"`]+/.test(text)) {
84
+ findings.push({
85
+ ruleId: "angular.no-hardcoded-api-url",
86
+ severity: "warning",
87
+ message: "File appears to contain a hardcoded remote API URL.",
88
+ file: file.path,
89
+ suggestion: "Move API origins into environment/runtime configuration or an API client service.",
90
+ });
91
+ }
92
+ }
93
+ return (0, frontend_standard_schema_1.summarizeFindings)(findings);
94
+ }
@@ -0,0 +1,8 @@
1
+ import type { FrontendStandard } from "../frontend-standard.schema";
2
+ export declare function validateBranchName(branchName: string, standard: FrontendStandard): import("../frontend-standard.schema").StandardCheckResult;
3
+ export declare function validateCommitMessage(message: string, standard: FrontendStandard): import("../frontend-standard.schema").StandardCheckResult;
4
+ export declare function generateCommitMessage(input: {
5
+ type?: string;
6
+ scope?: string;
7
+ summary: string;
8
+ }, standard: FrontendStandard): string;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateBranchName = validateBranchName;
4
+ exports.validateCommitMessage = validateCommitMessage;
5
+ exports.generateCommitMessage = generateCommitMessage;
6
+ const frontend_standard_schema_1 = require("../frontend-standard.schema");
7
+ function validateBranchName(branchName, standard) {
8
+ const matched = standard.git.branchPatterns.some((pattern) => new RegExp(pattern).test(branchName));
9
+ const findings = matched ? [] : [{
10
+ ruleId: "git.branch-name",
11
+ severity: "error",
12
+ message: `Branch name does not match allowed frontend workflow patterns: ${branchName}`,
13
+ suggestion: "Use feature/{issueId}-{short-name}, fix/{issueId}-{short-name}, refactor/{module}-{short-name}, or hotfix/{date}-{short-name}.",
14
+ }];
15
+ return (0, frontend_standard_schema_1.summarizeFindings)(findings);
16
+ }
17
+ function validateCommitMessage(message, standard) {
18
+ const matched = new RegExp(standard.git.commitPattern).test(message);
19
+ const findings = matched ? [] : [{
20
+ ruleId: "git.commit-message",
21
+ severity: "error",
22
+ message: `Commit message does not match conventional frontend format: ${message}`,
23
+ suggestion: "Use feat(scope): message, fix(scope): message, refactor(scope): message, docs(scope): message, test(scope): message, or chore(scope): message.",
24
+ }];
25
+ return (0, frontend_standard_schema_1.summarizeFindings)(findings);
26
+ }
27
+ function generateCommitMessage(input, standard) {
28
+ const type = input.type && standard.naming.commitTypes.includes(input.type) ? input.type : "chore";
29
+ const scope = (input.scope ?? "frontend").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-|-$/g, "") || "frontend";
30
+ const summary = input.summary.trim().replace(/\s+/g, " ");
31
+ return `${type}(${scope}): ${summary}`;
32
+ }
@@ -0,0 +1,15 @@
1
+ import type { FrontendStandard, StandardFinding } from "../frontend-standard.schema";
2
+ import type { SourceFile } from "../project-scan";
3
+ export declare function detectReviewRisks(files: SourceFile[], changedFiles: string[], standard: FrontendStandard): import("../frontend-standard.schema").StandardCheckResult;
4
+ export declare function reviewChecklist(changedFiles: string[]): string[];
5
+ export declare function generateReviewMarkdown(input: {
6
+ taskId: string;
7
+ changedFiles: string[];
8
+ checks: Array<{
9
+ title: string;
10
+ status: string;
11
+ findings: StandardFinding[];
12
+ }>;
13
+ risks: StandardFinding[];
14
+ checklist: string[];
15
+ }): string;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectReviewRisks = detectReviewRisks;
4
+ exports.reviewChecklist = reviewChecklist;
5
+ exports.generateReviewMarkdown = generateReviewMarkdown;
6
+ const frontend_standard_schema_1 = require("../frontend-standard.schema");
7
+ function detectReviewRisks(files, changedFiles, standard) {
8
+ const changedSet = new Set(changedFiles.map((item) => item.replace(/\\/g, "/")));
9
+ const findings = [];
10
+ for (const file of files.filter((item) => changedSet.has(item.path))) {
11
+ const text = file.text ?? "";
12
+ for (const keyword of standard.review.riskKeywords) {
13
+ if (text.toLowerCase().includes(keyword.toLowerCase()) || file.path.toLowerCase().includes(keyword.toLowerCase())) {
14
+ findings.push({
15
+ ruleId: "review.risk-keyword",
16
+ severity: "warning",
17
+ message: `Changed file matches review risk keyword: ${keyword}`,
18
+ file: file.path,
19
+ suggestion: "Add explicit human review notes for permission, security, data loss, lifecycle, or migration impact.",
20
+ });
21
+ break;
22
+ }
23
+ }
24
+ if (file.path.endsWith("package.json")) {
25
+ findings.push({
26
+ ruleId: "review.package-json-change",
27
+ severity: "warning",
28
+ message: "package.json changed.",
29
+ file: file.path,
30
+ suggestion: "Confirm scripts, dependencies, package exports, and release impact.",
31
+ });
32
+ }
33
+ }
34
+ return (0, frontend_standard_schema_1.summarizeFindings)(findings);
35
+ }
36
+ function reviewChecklist(changedFiles) {
37
+ return [
38
+ "确认变更范围只覆盖本次任务需要的文件。",
39
+ "确认无 token/password/secret/cookie/authorization 泄漏。",
40
+ "确认 UI、API、任务运行时或配置写入契约没有意外破坏。",
41
+ "确认新增或变更逻辑已有对应测试计划。",
42
+ changedFiles.length > 0 ? `确认 ${changedFiles.length} 个变更文件都已人工扫过。` : "确认当前没有检测到 Git 变更文件。",
43
+ ];
44
+ }
45
+ function generateReviewMarkdown(input) {
46
+ const lines = [
47
+ `# Review Report ${input.taskId}`,
48
+ "",
49
+ "## Changed Files",
50
+ ...(input.changedFiles.length ? input.changedFiles.map((file) => `- ${file}`) : ["- No changed files detected."]),
51
+ "",
52
+ "## Automated Checks",
53
+ ];
54
+ for (const check of input.checks) {
55
+ lines.push(`- ${check.title}: ${check.status}`);
56
+ for (const finding of check.findings.slice(0, 20)) {
57
+ lines.push(` - [${finding.severity}] ${finding.file ? `${finding.file}: ` : ""}${finding.message}`);
58
+ }
59
+ }
60
+ lines.push("", "## Risks");
61
+ lines.push(...(input.risks.length ? input.risks.map((risk) => `- [${risk.severity}] ${risk.file ? `${risk.file}: ` : ""}${risk.message}`) : ["- No automated risks detected."]));
62
+ lines.push("", "## Suggestions");
63
+ lines.push(...input.checklist.map((item) => `- ${item}`));
64
+ lines.push("", "## Manual Confirmation");
65
+ lines.push("- [ ] Scope is correct.", "- [ ] Tests or verification are sufficient.", "- [ ] No sensitive data is included.");
66
+ return lines.join("\n");
67
+ }
@@ -0,0 +1,19 @@
1
+ import type { FrontendStandard, StandardFinding } from "../frontend-standard.schema";
2
+ import type { SourceFile } from "../project-scan";
3
+ export declare function detectMissingSpecs(files: SourceFile[], standard: FrontendStandard): import("../frontend-standard.schema").StandardCheckResult;
4
+ export declare function validateSpecNaming(files: SourceFile[]): import("../frontend-standard.schema").StandardCheckResult;
5
+ export declare function generateSpecPlan(files: SourceFile[], standard: FrontendStandard): {
6
+ plan: {
7
+ sourceFile: string | undefined;
8
+ suggestedSpecFile: string | undefined;
9
+ focus: string;
10
+ }[];
11
+ status: import("../frontend-standard.schema").CheckStatus;
12
+ findings: StandardFinding[];
13
+ summary: {
14
+ passed: number;
15
+ warnings: number;
16
+ errors: number;
17
+ nextSteps: string[];
18
+ };
19
+ };
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.detectMissingSpecs = detectMissingSpecs;
37
+ exports.validateSpecNaming = validateSpecNaming;
38
+ exports.generateSpecPlan = generateSpecPlan;
39
+ const path = __importStar(require("path"));
40
+ const frontend_standard_schema_1 = require("../frontend-standard.schema");
41
+ function specPathFor(filePath) {
42
+ return filePath.replace(/\.ts$/, ".spec.ts");
43
+ }
44
+ function hasFile(files, filePath) {
45
+ return files.some((file) => file.path === filePath);
46
+ }
47
+ function detectMissingSpecs(files, standard) {
48
+ const findings = [];
49
+ const tsFiles = files.filter((file) => file.path.endsWith(".ts") && !file.path.endsWith(".spec.ts"));
50
+ for (const file of tsFiles) {
51
+ const base = path.basename(file.path);
52
+ const needsServiceSpec = standard.testing.requireServiceSpec && base.endsWith(".service.ts");
53
+ const needsUtilSpec = standard.testing.requireUtilSpec && (base.endsWith(".util.ts") || base.endsWith(".utils.ts"));
54
+ const suggestsComponentSpec = standard.testing.suggestComponentSpec && base.endsWith(".component.ts") && (file.lineCount ?? 0) >= 120;
55
+ if ((needsServiceSpec || needsUtilSpec || suggestsComponentSpec) && !hasFile(files, specPathFor(file.path))) {
56
+ findings.push({
57
+ ruleId: needsServiceSpec ? "test.missing-service-spec" : needsUtilSpec ? "test.missing-util-spec" : "test.missing-component-spec",
58
+ severity: "warning",
59
+ message: `Missing suggested spec file for ${file.path}.`,
60
+ file: file.path,
61
+ suggestion: `Add ${specPathFor(file.path)} or document why this file is covered elsewhere.`,
62
+ });
63
+ }
64
+ }
65
+ return (0, frontend_standard_schema_1.summarizeFindings)(findings);
66
+ }
67
+ function validateSpecNaming(files) {
68
+ const findings = files
69
+ .filter((file) => file.path.endsWith(".test.ts") || file.path.endsWith(".tests.ts"))
70
+ .map((file) => ({
71
+ ruleId: "test.naming",
72
+ severity: "warning",
73
+ message: "Angular frontend tests should use .spec.ts naming.",
74
+ file: file.path,
75
+ suggestion: "Rename frontend test files to .spec.ts where Angular tooling expects it.",
76
+ }));
77
+ return (0, frontend_standard_schema_1.summarizeFindings)(findings);
78
+ }
79
+ function generateSpecPlan(files, standard) {
80
+ const missing = detectMissingSpecs(files, standard);
81
+ return {
82
+ ...missing,
83
+ plan: missing.findings.map((finding) => ({
84
+ sourceFile: finding.file,
85
+ suggestedSpecFile: finding.suggestion?.match(/Add ([^ ]+)/)?.[1],
86
+ focus: finding.ruleId.includes("service") ? "service behavior and API contracts" : finding.ruleId.includes("util") ? "pure utility inputs and edge cases" : "component inputs, outputs, and key rendering states",
87
+ })),
88
+ };
89
+ }
@@ -0,0 +1,2 @@
1
+ export { toolCatalog, capabilityCatalog, } from "./catalog";
2
+ export type { ToolCatalogEntry, CapabilityCatalogEntry, } from "./catalog/types";
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.capabilityCatalog = exports.toolCatalog = void 0;
4
+ var catalog_1 = require("./catalog");
5
+ Object.defineProperty(exports, "toolCatalog", { enumerable: true, get: function () { return catalog_1.toolCatalog; } });
6
+ Object.defineProperty(exports, "capabilityCatalog", { enumerable: true, get: function () { return catalog_1.capabilityCatalog; } });
@@ -0,0 +1,2 @@
1
+ import type { McpToolDefinition } from "../index";
2
+ export declare function angularStandardTools(): McpToolDefinition[];
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.angularStandardTools = angularStandardTools;
4
+ const zod_1 = require("zod");
5
+ const result_1 = require("../../utils/result");
6
+ const project_files_1 = require("../../filesystem/project-files");
7
+ const frontend_standard_service_1 = require("../../standard/frontend-standard.service");
8
+ const angular_structure_validator_1 = require("../../standard/validators/angular-structure.validator");
9
+ const component_validator_1 = require("../../standard/validators/component.validator");
10
+ const projectSchema = zod_1.z.object({
11
+ projectId: zod_1.z.string().trim().min(1).optional(),
12
+ projectPath: zod_1.z.string().trim().min(1).optional(),
13
+ }).strict();
14
+ function angularStandardTools() {
15
+ return [
16
+ {
17
+ name: "ngm_angular_validate_structure",
18
+ description: "Validate configured Angular pages/components/services/models directory structure.",
19
+ riskLevel: "read",
20
+ inputSchema: projectSchema,
21
+ async handler(args, context) {
22
+ const project = await (0, project_files_1.resolveProjectRoot)(context, args);
23
+ const loaded = await (0, frontend_standard_service_1.loadFrontendStandard)(project);
24
+ const files = await (0, frontend_standard_service_1.scanFrontendProject)(project.projectRoot);
25
+ return (0, result_1.ok)("ngm_angular_validate_structure", (0, angular_structure_validator_1.validateAngularStructure)(files, loaded.standard));
26
+ },
27
+ },
28
+ {
29
+ name: "ngm_angular_validate_component_naming",
30
+ description: "Validate Angular component file suffix naming for page/component/dialog/drawer/table/form conventions.",
31
+ riskLevel: "read",
32
+ inputSchema: projectSchema,
33
+ async handler(args, context) {
34
+ const project = await (0, project_files_1.resolveProjectRoot)(context, args);
35
+ const loaded = await (0, frontend_standard_service_1.loadFrontendStandard)(project);
36
+ const files = await (0, frontend_standard_service_1.scanFrontendProject)(project.projectRoot);
37
+ return (0, result_1.ok)("ngm_angular_validate_component_naming", (0, component_validator_1.validateComponentNaming)(files, loaded.standard));
38
+ },
39
+ },
40
+ {
41
+ name: "ngm_angular_validate_component_boundary",
42
+ description: "Detect large components, obvious any usage, hardcoded remote API URLs, and page placement issues.",
43
+ riskLevel: "read",
44
+ inputSchema: projectSchema,
45
+ async handler(args, context) {
46
+ const project = await (0, project_files_1.resolveProjectRoot)(context, args);
47
+ const loaded = await (0, frontend_standard_service_1.loadFrontendStandard)(project);
48
+ const files = await (0, frontend_standard_service_1.scanFrontendProject)(project.projectRoot);
49
+ return (0, result_1.ok)("ngm_angular_validate_component_boundary", (0, component_validator_1.validateComponentBoundary)(files, loaded.standard));
50
+ },
51
+ },
52
+ ];
53
+ }
@@ -0,0 +1 @@
1
+ export { angularStandardTools } from "./angular-standard.tools";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.angularStandardTools = void 0;
4
+ var angular_standard_tools_1 = require("./angular-standard.tools");
5
+ Object.defineProperty(exports, "angularStandardTools", { enumerable: true, get: function () { return angular_standard_tools_1.angularStandardTools; } });
@@ -0,0 +1,2 @@
1
+ import type { McpToolDefinition } from "./index";
2
+ export declare function capabilityTools(): McpToolDefinition[];
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.capabilityTools = capabilityTools;
4
+ const zod_1 = require("zod");
5
+ const result_1 = require("../utils/result");
6
+ const tool_catalog_1 = require("./tool-catalog");
7
+ const tool_policy_1 = require("../policy/tool-policy");
8
+ const tool_names_1 = require("../registry/tool-names");
9
+ const routeTaskSchema = zod_1.z.object({
10
+ query: zod_1.z.string().trim().min(1),
11
+ }).strict();
12
+ function hasAny(text, words) {
13
+ return words.some((word) => text.includes(word));
14
+ }
15
+ function unique(values) {
16
+ return [...new Set(values)];
17
+ }
18
+ function routeTask(query) {
19
+ const text = query.toLowerCase();
20
+ const localExecution = hasAny(text, [
21
+ "start",
22
+ "stop",
23
+ "restart",
24
+ "run script",
25
+ "package.json",
26
+ "npm",
27
+ "pnpm",
28
+ "yarn",
29
+ "启动",
30
+ "停止",
31
+ "重启",
32
+ "脚本",
33
+ "运行命令",
34
+ ]);
35
+ const runtime = hasAny(text, ["node", "runtime", "nvm", "volta", "version", "版本", "运行时"]);
36
+ const nginx = hasAny(text, ["nginx", "proxy", "upstream", "server block", "reload", "代理", "端口转发"]);
37
+ const workspace = hasAny(text, [
38
+ "workspace",
39
+ "monorepo",
40
+ "packages/",
41
+ "package",
42
+ "mcp",
43
+ "tool",
44
+ "codegraph",
45
+ "api debugging",
46
+ "api 调试",
47
+ "design handoff",
48
+ "代码上下文",
49
+ "工作区",
50
+ "仓库",
51
+ "能力",
52
+ ]);
53
+ const frontendStandard = hasAny(text, [
54
+ "frontend",
55
+ "angular",
56
+ "ng-zorro",
57
+ "standard",
58
+ "review",
59
+ "commit",
60
+ "branch",
61
+ "spec",
62
+ "workflow",
63
+ "前端",
64
+ "规范",
65
+ "评审",
66
+ "提交",
67
+ "分支",
68
+ "测试",
69
+ "组件",
70
+ "流程",
71
+ ]);
72
+ const hubV2 = hasAny(text, [
73
+ "issue",
74
+ "issues",
75
+ "rd",
76
+ "研发项",
77
+ "需求文档",
78
+ "项目文档",
79
+ "协作",
80
+ "project token",
81
+ "hub v2",
82
+ "hub-v2",
83
+ ]);
84
+ const hubDocs = hasAny(text, ["doc", "docs", "document", "文档", "需求文档", "项目文档"]);
85
+ if ((localExecution || runtime || nginx || workspace || frontendStandard) && !hasAny(text, ["查一下某个研发项的需求文档"])) {
86
+ const skills = ["ngm-router"];
87
+ const tools = [tool_names_1.MCP_TOOL_NAMES.NGM_CAPABILITIES];
88
+ if (workspace) {
89
+ skills.push("ngm-workspace");
90
+ tools.push(tool_names_1.MCP_TOOL_NAMES.NGM_WORKSPACE_SUMMARY, tool_names_1.MCP_TOOL_NAMES.NGM_WORKSPACE_MCP_TOOLS, tool_names_1.MCP_TOOL_NAMES.NGM_WORKSPACE_CAPABILITY_MAP);
91
+ }
92
+ if (localExecution) {
93
+ skills.push("ngm-project");
94
+ tools.push(tool_names_1.MCP_TOOL_NAMES.NGM_PROJECT_FIND, tool_names_1.MCP_TOOL_NAMES.NGM_PROJECT_READ_PACKAGE_JSON, tool_names_1.MCP_TOOL_NAMES.NGM_TASK_LIST);
95
+ }
96
+ if (runtime) {
97
+ skills.push("ngm-runtime");
98
+ tools.push(tool_names_1.MCP_TOOL_NAMES.NGM_RUNTIME_CURRENT, tool_names_1.MCP_TOOL_NAMES.NGM_RUNTIME_DETECT_REQUIREMENT, tool_names_1.MCP_TOOL_NAMES.NGM_RUNTIME_RESOLVE_FOR_PROJECT);
99
+ }
100
+ if (nginx) {
101
+ skills.push("ngm-nginx");
102
+ tools.push(tool_names_1.MCP_TOOL_NAMES.NGM_NGINX_STATUS, tool_names_1.MCP_TOOL_NAMES.NGM_NGINX_SERVERS_LIST, tool_names_1.MCP_TOOL_NAMES.NGM_NGINX_CONFIG_VALIDATE);
103
+ }
104
+ if (frontendStandard) {
105
+ skills.push("ngm-frontend-standard");
106
+ tools.push(tool_names_1.MCP_TOOL_NAMES.NGM_STANDARD_GET, tool_names_1.MCP_TOOL_NAMES.NGM_STANDARD_VALIDATE_PROJECT, tool_names_1.MCP_TOOL_NAMES.NGM_WORKFLOW_VALIDATE_BEFORE_WRITE, tool_names_1.MCP_TOOL_NAMES.NGM_REVIEW_GENERATE_CHECKLIST);
107
+ }
108
+ if (skills.length === 1) {
109
+ skills.push("ngm-workspace");
110
+ tools.push(tool_names_1.MCP_TOOL_NAMES.NGM_WORKSPACE_SUMMARY);
111
+ }
112
+ return {
113
+ skills: unique(skills),
114
+ tools: unique(tools),
115
+ reason: "The request mentions local ng-manager engineering control or workspace context.",
116
+ };
117
+ }
118
+ if (hubV2) {
119
+ const skills = ["ngm-router", "hub-v2-api"];
120
+ const tools = [tool_names_1.MCP_TOOL_NAMES.HUB_V2_PROJECTS_LIST];
121
+ if (hubDocs) {
122
+ skills.push("hub-v2-docs");
123
+ tools.push(tool_names_1.MCP_TOOL_NAMES.HUB_V2_DOCS_LIST, tool_names_1.MCP_TOOL_NAMES.HUB_V2_DOCS_GET, tool_names_1.MCP_TOOL_NAMES.HUB_V2_DOCS_GET_BY_SLUG);
124
+ }
125
+ if (hasAny(text, ["issue", "issues", "问题"])) {
126
+ tools.push(tool_names_1.MCP_TOOL_NAMES.HUB_V2_ISSUES_LIST, tool_names_1.MCP_TOOL_NAMES.HUB_V2_ISSUES_GET);
127
+ }
128
+ if (hasAny(text, ["rd", "研发项"])) {
129
+ tools.push(tool_names_1.MCP_TOOL_NAMES.HUB_V2_RD_LIST, tool_names_1.MCP_TOOL_NAMES.HUB_V2_RD_GET);
130
+ }
131
+ return {
132
+ skills: unique(skills),
133
+ tools: unique(tools),
134
+ reason: "The request appears to target Hub V2 collaboration data.",
135
+ };
136
+ }
137
+ return {
138
+ skills: ["ngm-router", "ngm-workspace"],
139
+ tools: [tool_names_1.MCP_TOOL_NAMES.NGM_CAPABILITIES, tool_names_1.MCP_TOOL_NAMES.NGM_WORKSPACE_SUMMARY, tool_names_1.MCP_TOOL_NAMES.NGM_WORKSPACE_CAPABILITY_MAP],
140
+ reason: "No narrower domain was detected; start with local workspace capability discovery.",
141
+ };
142
+ }
143
+ function capabilityTools() {
144
+ return [
145
+ {
146
+ name: tool_names_1.MCP_TOOL_NAMES.NGM_CAPABILITIES,
147
+ description: "List ng-manager MCP capability groups, matching skills, tool names, and currently blocked local actions.",
148
+ riskLevel: "read",
149
+ inputSchema: zod_1.z.object({}).strict(),
150
+ handler() {
151
+ return (0, result_1.ok)(tool_names_1.MCP_TOOL_NAMES.NGM_CAPABILITIES, {
152
+ capabilities: tool_catalog_1.capabilityCatalog,
153
+ tools: tool_catalog_1.toolCatalog,
154
+ blockedLocalActions: tool_catalog_1.blockedLocalActions,
155
+ });
156
+ },
157
+ },
158
+ {
159
+ name: tool_names_1.MCP_TOOL_NAMES.NGM_DOCTOR,
160
+ description: "Inspect ng-manager MCP server readiness, policy flags, Hub V2 configuration, and registered tool coverage. Prefer this read-only MCP diagnostic before shell checks because it reports the same controlled server/audit/policy view agents use.",
161
+ riskLevel: "read",
162
+ inputSchema: zod_1.z.object({}).strict(),
163
+ handler() {
164
+ const policy = (0, tool_policy_1.createDefaultToolPolicy)();
165
+ const counts = tool_catalog_1.toolCatalog.reduce((acc, tool) => {
166
+ acc[tool.riskLevel] = (acc[tool.riskLevel] ?? 0) + 1;
167
+ return acc;
168
+ }, {});
169
+ return (0, result_1.ok)(tool_names_1.MCP_TOOL_NAMES.NGM_DOCTOR, {
170
+ status: "OK",
171
+ runtime: {
172
+ node: process.version,
173
+ platform: `${process.platform} ${process.arch}`,
174
+ cwd: process.cwd(),
175
+ },
176
+ policy,
177
+ tools: {
178
+ total: tool_catalog_1.toolCatalog.length,
179
+ counts,
180
+ },
181
+ localServer: {
182
+ discovery: ["runtime lock file", "NGM_MCP_SERVER_URL", "NGM_SERVER_URL"],
183
+ },
184
+ notes: [
185
+ "Read tools are enabled by default.",
186
+ "Confirmed write tools require NGM_MCP_ALLOW_WRITE=true.",
187
+ "Confirmed execute tools require NGM_MCP_ALLOW_EXECUTE=true.",
188
+ ],
189
+ });
190
+ },
191
+ },
192
+ {
193
+ name: tool_names_1.MCP_TOOL_NAMES.NGM_ROUTE_TASK,
194
+ description: "Route a user request to Hub V2 or NGM local skills and recommend read-only MCP tools.",
195
+ riskLevel: "read",
196
+ inputSchema: routeTaskSchema,
197
+ handler(args) {
198
+ return (0, result_1.ok)(tool_names_1.MCP_TOOL_NAMES.NGM_ROUTE_TASK, {
199
+ query: args.query,
200
+ ...routeTask(args.query),
201
+ });
202
+ },
203
+ },
204
+ ];
205
+ }
@@ -0,0 +1,2 @@
1
+ import type { McpToolDefinition } from "../index";
2
+ export declare function controlledTools(): McpToolDefinition[];
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.controlledTools = controlledTools;
4
+ const nginx_control_tools_1 = require("../nginx/nginx-control.tools");
5
+ const project_control_tools_1 = require("../project/project-control.tools");
6
+ const runtime_control_tools_1 = require("../runtime/runtime-control.tools");
7
+ function controlledTools() {
8
+ return [
9
+ ...(0, project_control_tools_1.projectControlTools)(),
10
+ ...(0, runtime_control_tools_1.runtimeControlTools)(),
11
+ ...(0, nginx_control_tools_1.nginxControlTools)(),
12
+ ];
13
+ }
@@ -0,0 +1,6 @@
1
+ import type { LocalServerAvailability, LocalServerClient, ToolContext } from "../../context/tool-context";
2
+ export declare function localServerAvailability(context: ToolContext): Promise<LocalServerAvailability>;
3
+ export declare function requireLocalServer(context: ToolContext): Promise<{
4
+ server?: LocalServerClient;
5
+ availability: LocalServerAvailability;
6
+ }>;