@yinuo-ngm/mcp-server 0.1.2 → 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 (214) hide show
  1. package/README.md +191 -208
  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 +67 -10
  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 +6 -1
  114. package/lib/tools/hub-v2/client.js +15 -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.js +138 -4
  130. package/lib/tools/hub-v2/index.js +2 -0
  131. package/lib/tools/hub-v2/issues-workflow.tools.d.ts +2 -0
  132. package/lib/tools/hub-v2/issues-workflow.tools.js +199 -0
  133. package/lib/tools/hub-v2/issues.tools.js +96 -6
  134. package/lib/tools/hub-v2/projects.tools.js +16 -3
  135. package/lib/tools/hub-v2/raw.d.ts +8 -0
  136. package/lib/tools/hub-v2/raw.js +33 -0
  137. package/lib/tools/hub-v2/rd.tools.js +167 -8
  138. package/lib/tools/hub-v2/schemas.d.ts +668 -71
  139. package/lib/tools/hub-v2/schemas.js +152 -1
  140. package/lib/tools/hub-v2/upload.tools.js +53 -5
  141. package/lib/tools/index.d.ts +1 -0
  142. package/lib/tools/index.js +22 -0
  143. package/lib/tools/log.tools.js +33 -6
  144. package/lib/tools/nginx/index.d.ts +1 -0
  145. package/lib/tools/nginx/index.js +5 -0
  146. package/lib/tools/nginx/nginx-control.tools.d.ts +2 -0
  147. package/lib/tools/nginx/nginx-control.tools.js +133 -0
  148. package/lib/tools/nginx/nginx-proxy.d.ts +24 -0
  149. package/lib/tools/nginx/nginx-proxy.js +154 -0
  150. package/lib/tools/nginx.tools.d.ts +2 -0
  151. package/lib/tools/nginx.tools.js +111 -0
  152. package/lib/tools/project/index.d.ts +2 -0
  153. package/lib/tools/project/index.js +7 -0
  154. package/lib/tools/project/launch-status.d.ts +10 -0
  155. package/lib/tools/project/launch-status.js +78 -0
  156. package/lib/tools/project/local-diagnostics.d.ts +19 -0
  157. package/lib/tools/project/local-diagnostics.js +97 -0
  158. package/lib/tools/project/observe-redaction.d.ts +3 -0
  159. package/lib/tools/project/observe-redaction.js +25 -0
  160. package/lib/tools/project/observe-runtime.d.ts +72 -0
  161. package/lib/tools/project/observe-runtime.js +147 -0
  162. package/lib/tools/project/project-control.tools.d.ts +2 -0
  163. package/lib/tools/project/project-control.tools.js +216 -0
  164. package/lib/tools/project/project-observe.tools.d.ts +2 -0
  165. package/lib/tools/project/project-observe.tools.js +191 -0
  166. package/lib/tools/project/runtime-config.d.ts +7 -0
  167. package/lib/tools/project/runtime-config.js +50 -0
  168. package/lib/tools/project-observe.tools.d.ts +1 -0
  169. package/lib/tools/project-observe.tools.js +5 -0
  170. package/lib/tools/project.tools.d.ts +8 -0
  171. package/lib/tools/project.tools.js +97 -6
  172. package/lib/tools/proxy.tools.js +4 -4
  173. package/lib/tools/review/index.d.ts +1 -0
  174. package/lib/tools/review/index.js +5 -0
  175. package/lib/tools/review/review.tools.d.ts +2 -0
  176. package/lib/tools/review/review.tools.js +152 -0
  177. package/lib/tools/runtime/index.d.ts +1 -0
  178. package/lib/tools/runtime/index.js +5 -0
  179. package/lib/tools/runtime/runtime-control.tools.d.ts +2 -0
  180. package/lib/tools/runtime/runtime-control.tools.js +89 -0
  181. package/lib/tools/runtime.tools.js +41 -4
  182. package/lib/tools/standard/index.d.ts +1 -0
  183. package/lib/tools/standard/index.js +5 -0
  184. package/lib/tools/standard/standard.tools.d.ts +2 -0
  185. package/lib/tools/standard/standard.tools.js +91 -0
  186. package/lib/tools/task.tools.js +44 -9
  187. package/lib/tools/test/index.d.ts +1 -0
  188. package/lib/tools/test/index.js +5 -0
  189. package/lib/tools/test/test-standard.tools.d.ts +2 -0
  190. package/lib/tools/test/test-standard.tools.js +51 -0
  191. package/lib/tools/tool-catalog.d.ts +2 -0
  192. package/lib/tools/tool-catalog.js +7 -0
  193. package/lib/tools/workflow/frontend-workflow.tools.d.ts +2 -0
  194. package/lib/tools/workflow/frontend-workflow.tools.js +364 -0
  195. package/lib/tools/workflow/index.d.ts +1 -0
  196. package/lib/tools/workflow/index.js +5 -0
  197. package/lib/tools/workspace-package.d.ts +22 -0
  198. package/lib/tools/workspace-package.js +130 -0
  199. package/lib/tools/workspace.tools.d.ts +7 -0
  200. package/lib/tools/workspace.tools.js +336 -0
  201. package/lib/utils/errors.js +6 -1
  202. package/lib/utils/result.d.ts +9 -0
  203. package/lib/utils/result.js +9 -0
  204. package/lib/workflow/frontend-task.schema.d.ts +83 -0
  205. package/lib/workflow/frontend-task.schema.js +25 -0
  206. package/lib/workflow/frontend-task.service.d.ts +57 -0
  207. package/lib/workflow/frontend-task.service.js +195 -0
  208. package/lib/workflow/workflow-status.d.ts +2 -0
  209. package/lib/workflow/workflow-status.js +14 -0
  210. package/lib/workflow/workflow-transition.d.ts +9 -0
  211. package/lib/workflow/workflow-transition.js +38 -0
  212. package/package.json +5 -3
  213. package/lib/tools/hub-v2/config.d.ts +0 -34
  214. package/lib/tools/hub-v2/config.js +0 -297
@@ -0,0 +1,130 @@
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.toRelativeWorkspacePath = toRelativeWorkspacePath;
37
+ exports.readPackageJsonSummary = readPackageJsonSummary;
38
+ exports.readOptionalPackageJsonSummary = readOptionalPackageJsonSummary;
39
+ exports.listKnownWorkspacePackages = listKnownWorkspacePackages;
40
+ const fs = __importStar(require("fs/promises"));
41
+ const path = __importStar(require("path"));
42
+ function isRecord(value) {
43
+ return typeof value === "object" && value !== null && !Array.isArray(value);
44
+ }
45
+ function readStringMap(value) {
46
+ if (!isRecord(value))
47
+ return {};
48
+ const out = {};
49
+ for (const [key, item] of Object.entries(value)) {
50
+ if (typeof item === "string") {
51
+ out[key] = item;
52
+ }
53
+ }
54
+ return out;
55
+ }
56
+ function readUnknownMap(value) {
57
+ return isRecord(value) ? value : {};
58
+ }
59
+ function toRelativeWorkspacePath(workspaceRoot, filePath) {
60
+ return path.relative(workspaceRoot, filePath).replace(/\\/g, "/") || ".";
61
+ }
62
+ async function readPackageJsonSummary(workspaceRoot, packageDir) {
63
+ const resolvedDir = path.resolve(packageDir);
64
+ const packageJsonPath = path.join(resolvedDir, "package.json");
65
+ const raw = await fs.readFile(packageJsonPath, "utf-8");
66
+ const parsed = JSON.parse(raw);
67
+ if (!isRecord(parsed)) {
68
+ throw new Error(`package.json must be an object: ${packageJsonPath}`);
69
+ }
70
+ return {
71
+ name: typeof parsed.name === "string" ? parsed.name : undefined,
72
+ version: typeof parsed.version === "string" ? parsed.version : undefined,
73
+ private: typeof parsed.private === "boolean" ? parsed.private : undefined,
74
+ description: typeof parsed.description === "string" ? parsed.description : undefined,
75
+ path: toRelativeWorkspacePath(workspaceRoot, resolvedDir),
76
+ packageJsonPath: toRelativeWorkspacePath(workspaceRoot, packageJsonPath),
77
+ scripts: readStringMap(parsed.scripts),
78
+ engines: readUnknownMap(parsed.engines),
79
+ dependencies: readStringMap(parsed.dependencies),
80
+ devDependencies: readStringMap(parsed.devDependencies),
81
+ peerDependencies: readStringMap(parsed.peerDependencies),
82
+ workspaces: parsed.workspaces,
83
+ bin: parsed.bin,
84
+ main: typeof parsed.main === "string" ? parsed.main : undefined,
85
+ types: typeof parsed.types === "string" ? parsed.types : undefined,
86
+ exports: parsed.exports,
87
+ };
88
+ }
89
+ async function readOptionalPackageJsonSummary(workspaceRoot, packageDir) {
90
+ try {
91
+ return await readPackageJsonSummary(workspaceRoot, packageDir);
92
+ }
93
+ catch {
94
+ return null;
95
+ }
96
+ }
97
+ async function listKnownWorkspacePackages(workspaceRoot) {
98
+ const roots = new Set([
99
+ workspaceRoot,
100
+ path.join(workspaceRoot, "webapp"),
101
+ path.join(workspaceRoot, "desktop"),
102
+ path.join(workspaceRoot, "apps", "hub"),
103
+ path.join(workspaceRoot, "apps", "hub-v2"),
104
+ path.join(workspaceRoot, "apps", "site"),
105
+ ]);
106
+ const packagesDir = path.join(workspaceRoot, "packages");
107
+ try {
108
+ const entries = await fs.readdir(packagesDir, { withFileTypes: true });
109
+ for (const entry of entries) {
110
+ if (entry.isDirectory()) {
111
+ roots.add(path.join(packagesDir, entry.name));
112
+ }
113
+ }
114
+ }
115
+ catch {
116
+ }
117
+ const appsDir = path.join(workspaceRoot, "apps");
118
+ try {
119
+ const entries = await fs.readdir(appsDir, { withFileTypes: true });
120
+ for (const entry of entries) {
121
+ if (entry.isDirectory()) {
122
+ roots.add(path.join(appsDir, entry.name));
123
+ }
124
+ }
125
+ }
126
+ catch {
127
+ }
128
+ const packages = await Promise.all([...roots].map((root) => readOptionalPackageJsonSummary(workspaceRoot, root)));
129
+ return packages.filter((item) => item !== null).sort((a, b) => a.path.localeCompare(b.path));
130
+ }
@@ -0,0 +1,7 @@
1
+ import type { McpToolDefinition } from "./index";
2
+ export declare function truncateUtf8(text: string, maxBytes: number): {
3
+ text: string;
4
+ truncated: boolean;
5
+ };
6
+ export declare function workspaceTools(): McpToolDefinition[];
7
+ export declare function readWorkspacePackageJson(workspaceRoot: string, packageDir: string): Promise<import("./workspace-package").PackageJsonSummary>;
@@ -0,0 +1,336 @@
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.truncateUtf8 = truncateUtf8;
37
+ exports.workspaceTools = workspaceTools;
38
+ exports.readWorkspacePackageJson = readWorkspacePackageJson;
39
+ const path = __importStar(require("path"));
40
+ const zod_1 = require("zod");
41
+ const result_1 = require("../utils/result");
42
+ const project_files_1 = require("../filesystem/project-files");
43
+ const redact_1 = require("../audit/redact");
44
+ const tool_catalog_1 = require("./tool-catalog");
45
+ const workspace_package_1 = require("./workspace-package");
46
+ const getPackageSchema = zod_1.z.object({
47
+ name: zod_1.z.string().trim().min(1).optional(),
48
+ path: zod_1.z.string().trim().min(1).optional(),
49
+ }).strict();
50
+ const workspaceDiffSchema = zod_1.z.object({
51
+ projectId: zod_1.z.string().trim().min(1).optional(),
52
+ projectPath: zod_1.z.string().trim().min(1).optional(),
53
+ includePatch: zod_1.z.boolean().optional(),
54
+ maxBytes: zod_1.z.number().int().min(1).max(200000).optional(),
55
+ }).strict();
56
+ const patchPreviewSchema = zod_1.z.object({
57
+ projectId: zod_1.z.string().trim().min(1).optional(),
58
+ projectPath: zod_1.z.string().trim().min(1).optional(),
59
+ patch: zod_1.z.string().min(1),
60
+ }).strict();
61
+ function normalizePath(value) {
62
+ return value.replace(/\\/g, "/").replace(/^\.?\//, "").toLowerCase();
63
+ }
64
+ function isForbiddenWorkspacePath(filePath) {
65
+ const normalized = filePath.replace(/\\/g, "/").replace(/^\.?\//, "");
66
+ const parts = normalized.split("/");
67
+ return parts.some((part) => ["node_modules", "dist", "build", ".git", "coverage", ".cache", ".angular", ".idea"].includes(part))
68
+ || parts.some((part) => part === ".env" || part.startsWith(".env."))
69
+ || normalized.endsWith(".pem")
70
+ || normalized.endsWith(".key")
71
+ || normalized.endsWith(".p12")
72
+ || normalized.endsWith(".pfx")
73
+ || normalized.endsWith(".jks")
74
+ || normalized.endsWith(".keystore");
75
+ }
76
+ function assertWorkspaceReadablePath(projectRoot, filePath) {
77
+ const normalized = filePath.replace(/\\/g, "/").replace(/^a\//, "").replace(/^b\//, "");
78
+ if (!normalized || normalized === "/dev/null")
79
+ return normalized;
80
+ if (path.isAbsolute(normalized) || normalized.includes("..")) {
81
+ throw new Error(`Patch path is not project-relative: ${filePath}`);
82
+ }
83
+ if (isForbiddenWorkspacePath(normalized)) {
84
+ throw new Error(`Patch path is forbidden for workspace preview: ${filePath}`);
85
+ }
86
+ const resolved = path.resolve(projectRoot, normalized);
87
+ (0, project_files_1.assertPathInsideProject)(projectRoot, resolved);
88
+ return (0, project_files_1.projectRelativePath)(projectRoot, resolved);
89
+ }
90
+ function summarizeDiffText(diffText, projectRoot) {
91
+ if (/^GIT binary patch$/m.test(diffText) || /^Binary files\b/m.test(diffText)) {
92
+ throw new Error("Binary patch is not supported by workspace preview");
93
+ }
94
+ const changed = new Set();
95
+ let addedLines = 0;
96
+ let removedLines = 0;
97
+ for (const line of diffText.split(/\r?\n/)) {
98
+ const diffMatch = /^diff --git a\/(.+?) b\/(.+)$/.exec(line);
99
+ if (diffMatch) {
100
+ changed.add(assertWorkspaceReadablePath(projectRoot, diffMatch[2]));
101
+ continue;
102
+ }
103
+ const fileMatch = /^(?:---|\+\+\+) (?:a|b)\/(.+)$/.exec(line);
104
+ if (fileMatch) {
105
+ changed.add(assertWorkspaceReadablePath(projectRoot, fileMatch[1]));
106
+ continue;
107
+ }
108
+ if (line.startsWith("+++") || line.startsWith("---"))
109
+ continue;
110
+ if (line.startsWith("+"))
111
+ addedLines += 1;
112
+ if (line.startsWith("-"))
113
+ removedLines += 1;
114
+ }
115
+ const changedFiles = [...changed].filter((item) => item !== "/dev/null").sort();
116
+ return {
117
+ changedFiles,
118
+ addedLines,
119
+ removedLines,
120
+ summary: changedFiles.length
121
+ ? `${changedFiles.length} file(s), +${addedLines}/-${removedLines}`
122
+ : `0 file(s), +${addedLines}/-${removedLines}`,
123
+ };
124
+ }
125
+ function truncateUtf8(text, maxBytes) {
126
+ if (Buffer.byteLength(text, "utf-8") <= maxBytes) {
127
+ return { text, truncated: false };
128
+ }
129
+ let end = Math.min(text.length, maxBytes);
130
+ while (end > 0 && Buffer.byteLength(text.slice(0, end), "utf-8") > maxBytes) {
131
+ end -= 1;
132
+ }
133
+ while (end > 0) {
134
+ const last = text.charCodeAt(end - 1);
135
+ if (last < 0xd800 || last > 0xdbff)
136
+ break;
137
+ end -= 1;
138
+ }
139
+ return { text: text.slice(0, end), truncated: true };
140
+ }
141
+ function patchPreview(diffText, maxBytes) {
142
+ const redacted = (0, redact_1.redactText)(diffText);
143
+ const truncated = truncateUtf8(redacted, maxBytes);
144
+ return {
145
+ patchPreview: truncated.text,
146
+ truncated: truncated.truncated,
147
+ };
148
+ }
149
+ function capabilityMap() {
150
+ return [
151
+ {
152
+ area: "packages/mcp-server",
153
+ capability: "Agent-facing MCP adapter and tool exposure",
154
+ skill: "ngm-workspace",
155
+ notes: "Keep tools as thin adapters over core services where possible.",
156
+ },
157
+ {
158
+ area: "packages/project",
159
+ capability: "Local project records and workspace detection",
160
+ skill: "ngm-project",
161
+ },
162
+ {
163
+ area: "packages/task",
164
+ capability: "Package script task views, runtime state, and log streaming",
165
+ skill: "ngm-project",
166
+ },
167
+ {
168
+ area: "packages/node-runtime, packages/node-version",
169
+ capability: "Node runtime resolution and project Node requirement detection",
170
+ skill: "ngm-runtime",
171
+ },
172
+ {
173
+ area: "packages/nginx",
174
+ capability: "Local Nginx binding, server blocks, upstreams, validation, and logs",
175
+ skill: "ngm-nginx",
176
+ },
177
+ {
178
+ area: "packages/api, webapp/src/app/pages/api-client",
179
+ capability: "Local API debugging data and UI",
180
+ skill: "ngm-workspace",
181
+ },
182
+ {
183
+ area: "packages/design-handoff",
184
+ capability: "Design handoff package validation and task generation",
185
+ skill: "ngm-workspace",
186
+ },
187
+ {
188
+ area: "webapp",
189
+ capability: "Single frontend used by CLI and desktop launch modes",
190
+ skill: "ngm-workspace",
191
+ },
192
+ {
193
+ area: "packages/server",
194
+ capability: "Single local backend authority for runtime state and APIs",
195
+ skill: "ngm-workspace",
196
+ },
197
+ {
198
+ area: "packages/cli, desktop",
199
+ capability: "Thin local entry points for the same backend/frontend product",
200
+ skill: "ngm-workspace",
201
+ },
202
+ {
203
+ area: "apps/hub-v2",
204
+ capability: "Hub V2 collaboration platform server/web business logic",
205
+ skill: "hub-v2-api",
206
+ },
207
+ ];
208
+ }
209
+ function workspaceTools() {
210
+ return [
211
+ {
212
+ name: "ngm_workspace_summary",
213
+ description: "Summarize the local ng-manager workspace root, major app/package areas, and MCP read-only discovery status.",
214
+ riskLevel: "read",
215
+ inputSchema: zod_1.z.object({}).strict(),
216
+ async handler(_args, context) {
217
+ const packages = await (0, workspace_package_1.listKnownWorkspacePackages)(context.workspaceRoot);
218
+ return (0, result_1.ok)("ngm_workspace_summary", {
219
+ workspaceRoot: context.workspaceRoot,
220
+ dataDir: context.dataDir,
221
+ packageCount: packages.length,
222
+ packageNames: packages.map((item) => item.name).filter(Boolean),
223
+ majorAreas: capabilityMap(),
224
+ readOnlyPhase: true,
225
+ codeGraph: {
226
+ exposedByThisMcpServer: false,
227
+ guidance: "Use external CodeGraph MCP tools when available; this server exposes workspace and package metadata only.",
228
+ },
229
+ });
230
+ },
231
+ },
232
+ {
233
+ name: "ngm_workspace_list_packages",
234
+ description: "List package.json metadata from known ng-manager workspace package and app roots.",
235
+ riskLevel: "read",
236
+ inputSchema: zod_1.z.object({}).strict(),
237
+ async handler(_args, context) {
238
+ const packages = await (0, workspace_package_1.listKnownWorkspacePackages)(context.workspaceRoot);
239
+ return (0, result_1.ok)("ngm_workspace_list_packages", packages);
240
+ },
241
+ },
242
+ {
243
+ name: "ngm_workspace_get_package",
244
+ description: "Get package.json metadata for one known ng-manager workspace package or app by name or relative path.",
245
+ riskLevel: "read",
246
+ inputSchema: getPackageSchema,
247
+ async handler(args, context) {
248
+ if (!args.name && !args.path) {
249
+ throw new Error("name or path is required");
250
+ }
251
+ const packages = await (0, workspace_package_1.listKnownWorkspacePackages)(context.workspaceRoot);
252
+ const requestedPath = args.path ? normalizePath(args.path) : "";
253
+ const found = packages.find((item) => {
254
+ if (args.name && item.name === args.name)
255
+ return true;
256
+ if (!requestedPath)
257
+ return false;
258
+ return normalizePath(item.path) === requestedPath || normalizePath(item.packageJsonPath) === requestedPath;
259
+ });
260
+ if (!found) {
261
+ throw new Error(`Workspace package not found: ${args.name || args.path}`);
262
+ }
263
+ return (0, result_1.ok)("ngm_workspace_get_package", found);
264
+ },
265
+ },
266
+ {
267
+ name: "ngm_workspace_mcp_tools",
268
+ description: "List ng-manager MCP tools with skill, capability, and risk-level mapping.",
269
+ riskLevel: "read",
270
+ inputSchema: zod_1.z.object({}).strict(),
271
+ handler() {
272
+ return (0, result_1.ok)("ngm_workspace_mcp_tools", tool_catalog_1.toolCatalog);
273
+ },
274
+ },
275
+ {
276
+ name: "ngm_workspace_capability_map",
277
+ description: "Map ng-manager workspace areas and MCP capability groups to the correct NGM or Hub V2 skill.",
278
+ riskLevel: "read",
279
+ inputSchema: zod_1.z.object({}).strict(),
280
+ handler() {
281
+ return (0, result_1.ok)("ngm_workspace_capability_map", {
282
+ areas: capabilityMap(),
283
+ capabilities: tool_catalog_1.capabilityCatalog,
284
+ });
285
+ },
286
+ },
287
+ {
288
+ name: "ngm_workspace_diff",
289
+ description: "Read a safe Git diff summary for a project without exposing forbidden workspace paths.",
290
+ riskLevel: "read",
291
+ inputSchema: workspaceDiffSchema,
292
+ async handler(args, context) {
293
+ const project = await (0, project_files_1.resolveProjectRoot)(context, args);
294
+ const maxBytes = args.maxBytes ?? 20000;
295
+ const gitArgs = { ...args, projectPath: project.projectRoot };
296
+ const diff = await context.services.git.diff(gitArgs);
297
+ const diffText = typeof diff.diff === "string" ? diff.diff : JSON.stringify(diff);
298
+ const summary = summarizeDiffText(diffText, project.projectRoot);
299
+ const includePatch = args.includePatch === true;
300
+ const preview = includePatch ? patchPreview(diffText, maxBytes) : undefined;
301
+ return (0, result_1.ok)("ngm_workspace_diff", {
302
+ project,
303
+ ...summary,
304
+ ...(preview ? {
305
+ ...preview,
306
+ maxBytes,
307
+ truncated: Boolean(diff.truncated) || preview.truncated,
308
+ } : {}),
309
+ });
310
+ },
311
+ },
312
+ {
313
+ name: "ngm_workspace_apply_patch_preview",
314
+ description: "Preview a unified patch without writing files. It rejects forbidden paths and returns changed files plus added/removed line counts.",
315
+ riskLevel: "read",
316
+ inputSchema: patchPreviewSchema,
317
+ async handler(args, context) {
318
+ const project = await (0, project_files_1.resolveProjectRoot)(context, args);
319
+ const summary = summarizeDiffText(args.patch, project.projectRoot);
320
+ return (0, result_1.ok)("ngm_workspace_apply_patch_preview", {
321
+ project,
322
+ operation: {
323
+ status: "preview",
324
+ type: "write",
325
+ risk: "medium",
326
+ safetyMessage: "Patch preview only; no file writes are performed.",
327
+ },
328
+ ...summary,
329
+ });
330
+ },
331
+ },
332
+ ];
333
+ }
334
+ async function readWorkspacePackageJson(workspaceRoot, packageDir) {
335
+ return (0, workspace_package_1.readPackageJsonSummary)(workspaceRoot, path.resolve(packageDir));
336
+ }
@@ -13,8 +13,13 @@ function errorMetadata(error) {
13
13
  return {};
14
14
  }
15
15
  const record = error;
16
+ const code = typeof record.errorCode === "string"
17
+ ? record.errorCode
18
+ : typeof record.code === "string"
19
+ ? record.code
20
+ : undefined;
16
21
  return {
17
- code: typeof record.code === "string" ? record.code : undefined,
22
+ code,
18
23
  status: typeof record.status === "number" ? record.status : undefined,
19
24
  detail: record.detail,
20
25
  };
@@ -7,12 +7,17 @@ export type ToolErrorResult = {
7
7
  ok: false;
8
8
  tool: string;
9
9
  error: string;
10
+ errorCode?: string;
10
11
  code?: string;
11
12
  status?: number;
12
13
  detail?: unknown;
13
14
  };
14
15
  export type ToolResult<T = unknown> = (ToolSuccessResult<T> | ToolErrorResult) & {
15
16
  truncated?: true;
17
+ auditWarning?: {
18
+ code: string;
19
+ message: string;
20
+ };
16
21
  };
17
22
  export declare function ok<T>(tool: string, data: T): ToolSuccessResult<T>;
18
23
  export declare function fail(tool: string, error: string, metadata?: {
@@ -20,6 +25,10 @@ export declare function fail(tool: string, error: string, metadata?: {
20
25
  status?: number;
21
26
  detail?: unknown;
22
27
  }): ToolErrorResult;
28
+ export declare function withAuditWarning(result: ToolResult, warning: {
29
+ code: string;
30
+ message: string;
31
+ }): ToolResult;
23
32
  export declare function toMcpTextResult(result: ToolResult): {
24
33
  content: Array<{
25
34
  type: "text";
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ok = ok;
4
4
  exports.fail = fail;
5
+ exports.withAuditWarning = withAuditWarning;
5
6
  exports.toMcpTextResult = toMcpTextResult;
6
7
  function ok(tool, data) {
7
8
  return { ok: true, tool, data };
@@ -11,11 +12,18 @@ function fail(tool, error, metadata = {}) {
11
12
  ok: false,
12
13
  tool,
13
14
  error,
15
+ ...(metadata.code ? { errorCode: metadata.code } : {}),
14
16
  ...(metadata.code ? { code: metadata.code } : {}),
15
17
  ...(metadata.status ? { status: metadata.status } : {}),
16
18
  ...(metadata.detail !== undefined ? { detail: metadata.detail } : {}),
17
19
  };
18
20
  }
21
+ function withAuditWarning(result, warning) {
22
+ return {
23
+ ...result,
24
+ auditWarning: warning,
25
+ };
26
+ }
19
27
  function toMcpTextResult(result) {
20
28
  const maxChars = maxResultChars();
21
29
  const text = JSON.stringify(result, null, 2);
@@ -59,6 +67,7 @@ function buildTruncatedResult(result, originalLength, preview) {
59
67
  ok: false,
60
68
  tool: result.tool,
61
69
  error: result.error,
70
+ errorCode: result.errorCode ?? result.code,
62
71
  code: result.code,
63
72
  status: result.status,
64
73
  truncated: true,
@@ -0,0 +1,83 @@
1
+ import { z } from "zod";
2
+ export declare const workflowCheckStatusSchema: z.ZodEnum<["pending", "passed", "warning", "failed", "blocked"]>;
3
+ export declare const workflowChecksSchema: z.ZodObject<{
4
+ standard: z.ZodEnum<["pending", "passed", "warning", "failed", "blocked"]>;
5
+ test: z.ZodEnum<["pending", "passed", "warning", "failed", "blocked"]>;
6
+ review: z.ZodEnum<["pending", "passed", "warning", "failed", "blocked"]>;
7
+ build: z.ZodEnum<["pending", "passed", "warning", "failed", "blocked"]>;
8
+ }, "strict", z.ZodTypeAny, {
9
+ standard: "warning" | "passed" | "failed" | "blocked" | "pending";
10
+ review: "warning" | "passed" | "failed" | "blocked" | "pending";
11
+ test: "warning" | "passed" | "failed" | "blocked" | "pending";
12
+ build: "warning" | "passed" | "failed" | "blocked" | "pending";
13
+ }, {
14
+ standard: "warning" | "passed" | "failed" | "blocked" | "pending";
15
+ review: "warning" | "passed" | "failed" | "blocked" | "pending";
16
+ test: "warning" | "passed" | "failed" | "blocked" | "pending";
17
+ build: "warning" | "passed" | "failed" | "blocked" | "pending";
18
+ }>;
19
+ export declare const frontendTaskSchema: z.ZodObject<{
20
+ taskId: z.ZodString;
21
+ status: z.ZodEnum<["draft", "context-ready", "plan-ready", "patch-ready", "applied", "verified", "review-ready", "delivered", "failed"]>;
22
+ projectId: z.ZodOptional<z.ZodString>;
23
+ projectRoot: z.ZodString;
24
+ title: z.ZodString;
25
+ description: z.ZodString;
26
+ createdAt: z.ZodString;
27
+ updatedAt: z.ZodString;
28
+ designContextPath: z.ZodNullable<z.ZodString>;
29
+ changedFiles: z.ZodArray<z.ZodString, "many">;
30
+ checks: z.ZodObject<{
31
+ standard: z.ZodEnum<["pending", "passed", "warning", "failed", "blocked"]>;
32
+ test: z.ZodEnum<["pending", "passed", "warning", "failed", "blocked"]>;
33
+ review: z.ZodEnum<["pending", "passed", "warning", "failed", "blocked"]>;
34
+ build: z.ZodEnum<["pending", "passed", "warning", "failed", "blocked"]>;
35
+ }, "strict", z.ZodTypeAny, {
36
+ standard: "warning" | "passed" | "failed" | "blocked" | "pending";
37
+ review: "warning" | "passed" | "failed" | "blocked" | "pending";
38
+ test: "warning" | "passed" | "failed" | "blocked" | "pending";
39
+ build: "warning" | "passed" | "failed" | "blocked" | "pending";
40
+ }, {
41
+ standard: "warning" | "passed" | "failed" | "blocked" | "pending";
42
+ review: "warning" | "passed" | "failed" | "blocked" | "pending";
43
+ test: "warning" | "passed" | "failed" | "blocked" | "pending";
44
+ build: "warning" | "passed" | "failed" | "blocked" | "pending";
45
+ }>;
46
+ }, "strict", z.ZodTypeAny, {
47
+ status: "failed" | "draft" | "context-ready" | "plan-ready" | "patch-ready" | "applied" | "verified" | "review-ready" | "delivered";
48
+ projectRoot: string;
49
+ changedFiles: string[];
50
+ taskId: string;
51
+ description: string;
52
+ createdAt: string;
53
+ updatedAt: string;
54
+ title: string;
55
+ designContextPath: string | null;
56
+ checks: {
57
+ standard: "warning" | "passed" | "failed" | "blocked" | "pending";
58
+ review: "warning" | "passed" | "failed" | "blocked" | "pending";
59
+ test: "warning" | "passed" | "failed" | "blocked" | "pending";
60
+ build: "warning" | "passed" | "failed" | "blocked" | "pending";
61
+ };
62
+ projectId?: string | undefined;
63
+ }, {
64
+ status: "failed" | "draft" | "context-ready" | "plan-ready" | "patch-ready" | "applied" | "verified" | "review-ready" | "delivered";
65
+ projectRoot: string;
66
+ changedFiles: string[];
67
+ taskId: string;
68
+ description: string;
69
+ createdAt: string;
70
+ updatedAt: string;
71
+ title: string;
72
+ designContextPath: string | null;
73
+ checks: {
74
+ standard: "warning" | "passed" | "failed" | "blocked" | "pending";
75
+ review: "warning" | "passed" | "failed" | "blocked" | "pending";
76
+ test: "warning" | "passed" | "failed" | "blocked" | "pending";
77
+ build: "warning" | "passed" | "failed" | "blocked" | "pending";
78
+ };
79
+ projectId?: string | undefined;
80
+ }>;
81
+ export type FrontendTask = z.infer<typeof frontendTaskSchema>;
82
+ export type WorkflowCheckStatus = z.infer<typeof workflowCheckStatusSchema>;
83
+ export type WorkflowChecks = z.infer<typeof workflowChecksSchema>;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.frontendTaskSchema = exports.workflowChecksSchema = exports.workflowCheckStatusSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const workflow_status_1 = require("./workflow-status");
6
+ exports.workflowCheckStatusSchema = zod_1.z.enum(["pending", "passed", "warning", "failed", "blocked"]);
7
+ exports.workflowChecksSchema = zod_1.z.object({
8
+ standard: exports.workflowCheckStatusSchema,
9
+ test: exports.workflowCheckStatusSchema,
10
+ review: exports.workflowCheckStatusSchema,
11
+ build: exports.workflowCheckStatusSchema,
12
+ }).strict();
13
+ exports.frontendTaskSchema = zod_1.z.object({
14
+ taskId: zod_1.z.string().min(1),
15
+ status: zod_1.z.enum(workflow_status_1.frontendWorkflowStatuses),
16
+ projectId: zod_1.z.string().optional(),
17
+ projectRoot: zod_1.z.string(),
18
+ title: zod_1.z.string().min(1),
19
+ description: zod_1.z.string(),
20
+ createdAt: zod_1.z.string(),
21
+ updatedAt: zod_1.z.string(),
22
+ designContextPath: zod_1.z.string().nullable(),
23
+ changedFiles: zod_1.z.array(zod_1.z.string()),
24
+ checks: exports.workflowChecksSchema,
25
+ }).strict();