@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,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.localServerAvailability = localServerAvailability;
4
+ exports.requireLocalServer = requireLocalServer;
5
+ async function localServerAvailability(context) {
6
+ if (!context.services.localServer) {
7
+ return { available: false, reason: "local server client is not configured" };
8
+ }
9
+ return context.services.localServer.availability();
10
+ }
11
+ async function requireLocalServer(context) {
12
+ const availability = await localServerAvailability(context);
13
+ return {
14
+ server: availability.available ? context.services.localServer : undefined,
15
+ availability,
16
+ };
17
+ }
@@ -0,0 +1,22 @@
1
+ import { type OperationRisk, type OperationType } from "./operation-result";
2
+ export declare function requireExecutePolicy(type: OperationType, risk: OperationRisk, safetyMessage: string): {
3
+ reason: string;
4
+ errorCode?: import("../../errors/error-codes").McpErrorCode | undefined;
5
+ operation: {
6
+ status: import("./operation-result").ControlledStatus;
7
+ type: OperationType;
8
+ risk: OperationRisk;
9
+ safetyMessage: string;
10
+ };
11
+ } | null;
12
+ export declare function requireWritePolicy(risk: OperationRisk, safetyMessage: string): {
13
+ reason: string;
14
+ errorCode?: import("../../errors/error-codes").McpErrorCode | undefined;
15
+ operation: {
16
+ status: import("./operation-result").ControlledStatus;
17
+ type: OperationType;
18
+ risk: OperationRisk;
19
+ safetyMessage: string;
20
+ };
21
+ } | null;
22
+ export declare function requiredEnv(type: OperationType): string[];
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.requireExecutePolicy = requireExecutePolicy;
4
+ exports.requireWritePolicy = requireWritePolicy;
5
+ exports.requiredEnv = requiredEnv;
6
+ const operation_result_1 = require("./operation-result");
7
+ const error_codes_1 = require("../../errors/error-codes");
8
+ const mcp_tool_error_1 = require("../../errors/mcp-tool-error");
9
+ const permission_service_1 = require("../../services/permission.service");
10
+ const permission = new permission_service_1.PermissionService();
11
+ function toActionType(type) {
12
+ return type === "write" ? "write" : "execute";
13
+ }
14
+ function blockedByEnvPolicy(type, risk, safetyMessage, error) {
15
+ const detail = error.detail;
16
+ const envName = detail?.requires?.[0] ?? (type === "write" ? "NGM_MCP_ALLOW_WRITE" : "NGM_MCP_ALLOW_EXECUTE");
17
+ return (0, operation_result_1.blocked)(type, risk, safetyMessage, error.message, {
18
+ requires: detail?.requires ?? [envName],
19
+ policy: {
20
+ env: envName,
21
+ requiredValue: "true",
22
+ currentValue: process.env[envName] ? "[set-but-not-enabled]" : "[unset]",
23
+ },
24
+ }, error.errorCode);
25
+ }
26
+ function requireExecutePolicy(type, risk, safetyMessage) {
27
+ try {
28
+ permission.assertAllowed(toActionType(type));
29
+ return null;
30
+ }
31
+ catch (error) {
32
+ if (error instanceof mcp_tool_error_1.McpToolError)
33
+ return blockedByEnvPolicy(type, risk, safetyMessage, error);
34
+ return (0, operation_result_1.blocked)(type, risk, safetyMessage, "confirmed execute operation is not allowed", {}, error_codes_1.McpErrorCodes.EXECUTE_NOT_ALLOWED);
35
+ }
36
+ }
37
+ function requireWritePolicy(risk, safetyMessage) {
38
+ try {
39
+ permission.assertAllowed("write");
40
+ return null;
41
+ }
42
+ catch (error) {
43
+ if (error instanceof mcp_tool_error_1.McpToolError)
44
+ return blockedByEnvPolicy("write", risk, safetyMessage, error);
45
+ return (0, operation_result_1.blocked)("write", risk, safetyMessage, "confirmed write operation is not allowed", {}, error_codes_1.McpErrorCodes.WRITE_NOT_ALLOWED);
46
+ }
47
+ }
48
+ function requiredEnv(type) {
49
+ return permission.getRequiredEnv(toActionType(type));
50
+ }
@@ -0,0 +1,30 @@
1
+ import type { McpErrorCode } from "../../errors/error-codes";
2
+ export type ControlledStatus = "preview" | "executed" | "blocked" | "failed";
3
+ export type OperationType = "write" | "execute" | "service-control";
4
+ export type OperationRisk = "low" | "medium" | "high";
5
+ export type ControlledAction = "preview" | "write" | "execute";
6
+ export declare function isConfirmed(args: {
7
+ confirm?: boolean;
8
+ dryRun?: boolean;
9
+ }): boolean;
10
+ export declare function operation(status: ControlledStatus, type: OperationType, risk: OperationRisk, safetyMessage: string): {
11
+ status: ControlledStatus;
12
+ type: OperationType;
13
+ risk: OperationRisk;
14
+ safetyMessage: string;
15
+ };
16
+ export declare function controlledFields(type: OperationType, confirmed: boolean, requires?: string[]): {
17
+ action: ControlledAction;
18
+ confirmed: boolean;
19
+ requires?: string[];
20
+ };
21
+ export declare function blocked(type: OperationType, risk: OperationRisk, safetyMessage: string, reason: string, data?: Record<string, unknown>, errorCode?: McpErrorCode): {
22
+ reason: string;
23
+ errorCode?: McpErrorCode | undefined;
24
+ operation: {
25
+ status: ControlledStatus;
26
+ type: OperationType;
27
+ risk: OperationRisk;
28
+ safetyMessage: string;
29
+ };
30
+ };
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isConfirmed = isConfirmed;
4
+ exports.operation = operation;
5
+ exports.controlledFields = controlledFields;
6
+ exports.blocked = blocked;
7
+ function isConfirmed(args) {
8
+ return args.confirm === true && args.dryRun !== true;
9
+ }
10
+ function operation(status, type, risk, safetyMessage) {
11
+ return {
12
+ status,
13
+ type,
14
+ risk,
15
+ safetyMessage,
16
+ };
17
+ }
18
+ function controlledFields(type, confirmed, requires = []) {
19
+ const action = confirmed ? (type === "write" ? "write" : "execute") : "preview";
20
+ return {
21
+ action,
22
+ confirmed,
23
+ ...(requires.length ? { requires } : {}),
24
+ };
25
+ }
26
+ function blocked(type, risk, safetyMessage, reason, data, errorCode) {
27
+ return {
28
+ operation: operation("blocked", type, risk, safetyMessage),
29
+ ...(errorCode ? { errorCode } : {}),
30
+ reason,
31
+ ...(data ?? {}),
32
+ };
33
+ }
@@ -0,0 +1,159 @@
1
+ import { z } from "zod";
2
+ export declare const confirmSchema: {
3
+ confirm: z.ZodOptional<z.ZodBoolean>;
4
+ dryRun: z.ZodOptional<z.ZodBoolean>;
5
+ };
6
+ export declare const runScriptSchema: z.ZodObject<{
7
+ confirm: z.ZodOptional<z.ZodBoolean>;
8
+ dryRun: z.ZodOptional<z.ZodBoolean>;
9
+ projectId: z.ZodString;
10
+ script: z.ZodString;
11
+ waitMs: z.ZodOptional<z.ZodNumber>;
12
+ }, "strict", z.ZodTypeAny, {
13
+ projectId: string;
14
+ script: string;
15
+ waitMs?: number | undefined;
16
+ confirm?: boolean | undefined;
17
+ dryRun?: boolean | undefined;
18
+ }, {
19
+ projectId: string;
20
+ script: string;
21
+ waitMs?: number | undefined;
22
+ confirm?: boolean | undefined;
23
+ dryRun?: boolean | undefined;
24
+ }>;
25
+ export declare const projectIdSchema: {
26
+ projectId: z.ZodString;
27
+ };
28
+ export declare const stopProjectSchema: z.ZodObject<{
29
+ confirm: z.ZodOptional<z.ZodBoolean>;
30
+ dryRun: z.ZodOptional<z.ZodBoolean>;
31
+ projectId: z.ZodOptional<z.ZodString>;
32
+ taskId: z.ZodOptional<z.ZodString>;
33
+ script: z.ZodOptional<z.ZodString>;
34
+ }, "strict", z.ZodTypeAny, {
35
+ projectId?: string | undefined;
36
+ script?: string | undefined;
37
+ confirm?: boolean | undefined;
38
+ dryRun?: boolean | undefined;
39
+ taskId?: string | undefined;
40
+ }, {
41
+ projectId?: string | undefined;
42
+ script?: string | undefined;
43
+ confirm?: boolean | undefined;
44
+ dryRun?: boolean | undefined;
45
+ taskId?: string | undefined;
46
+ }>;
47
+ export declare const runtimeConfigSchema: z.ZodObject<{
48
+ type: z.ZodEnum<["system", "managed", "custom"]>;
49
+ name: z.ZodOptional<z.ZodString>;
50
+ version: z.ZodOptional<z.ZodString>;
51
+ nodePath: z.ZodOptional<z.ZodString>;
52
+ packageManager: z.ZodOptional<z.ZodEnum<["npm", "pnpm", "yarn"]>>;
53
+ }, "strict", z.ZodTypeAny, {
54
+ type: "custom" | "system" | "managed";
55
+ version?: string | undefined;
56
+ name?: string | undefined;
57
+ nodePath?: string | undefined;
58
+ packageManager?: "npm" | "pnpm" | "yarn" | undefined;
59
+ }, {
60
+ type: "custom" | "system" | "managed";
61
+ version?: string | undefined;
62
+ name?: string | undefined;
63
+ nodePath?: string | undefined;
64
+ packageManager?: "npm" | "pnpm" | "yarn" | undefined;
65
+ }>;
66
+ export declare const setRuntimeSchema: z.ZodObject<{
67
+ confirm: z.ZodOptional<z.ZodBoolean>;
68
+ dryRun: z.ZodOptional<z.ZodBoolean>;
69
+ runtime: z.ZodObject<{
70
+ type: z.ZodEnum<["system", "managed", "custom"]>;
71
+ name: z.ZodOptional<z.ZodString>;
72
+ version: z.ZodOptional<z.ZodString>;
73
+ nodePath: z.ZodOptional<z.ZodString>;
74
+ packageManager: z.ZodOptional<z.ZodEnum<["npm", "pnpm", "yarn"]>>;
75
+ }, "strict", z.ZodTypeAny, {
76
+ type: "custom" | "system" | "managed";
77
+ version?: string | undefined;
78
+ name?: string | undefined;
79
+ nodePath?: string | undefined;
80
+ packageManager?: "npm" | "pnpm" | "yarn" | undefined;
81
+ }, {
82
+ type: "custom" | "system" | "managed";
83
+ version?: string | undefined;
84
+ name?: string | undefined;
85
+ nodePath?: string | undefined;
86
+ packageManager?: "npm" | "pnpm" | "yarn" | undefined;
87
+ }>;
88
+ projectId: z.ZodString;
89
+ }, "strict", z.ZodTypeAny, {
90
+ runtime: {
91
+ type: "custom" | "system" | "managed";
92
+ version?: string | undefined;
93
+ name?: string | undefined;
94
+ nodePath?: string | undefined;
95
+ packageManager?: "npm" | "pnpm" | "yarn" | undefined;
96
+ };
97
+ projectId: string;
98
+ confirm?: boolean | undefined;
99
+ dryRun?: boolean | undefined;
100
+ }, {
101
+ runtime: {
102
+ type: "custom" | "system" | "managed";
103
+ version?: string | undefined;
104
+ name?: string | undefined;
105
+ nodePath?: string | undefined;
106
+ packageManager?: "npm" | "pnpm" | "yarn" | undefined;
107
+ };
108
+ projectId: string;
109
+ confirm?: boolean | undefined;
110
+ dryRun?: boolean | undefined;
111
+ }>;
112
+ export declare const nginxReloadSchema: z.ZodObject<{
113
+ confirm: z.ZodOptional<z.ZodBoolean>;
114
+ dryRun: z.ZodOptional<z.ZodBoolean>;
115
+ }, "strict", z.ZodTypeAny, {
116
+ confirm?: boolean | undefined;
117
+ dryRun?: boolean | undefined;
118
+ }, {
119
+ confirm?: boolean | undefined;
120
+ dryRun?: boolean | undefined;
121
+ }>;
122
+ export declare const nginxProxySaveSchema: z.ZodObject<{
123
+ confirm: z.ZodOptional<z.ZodBoolean>;
124
+ dryRun: z.ZodOptional<z.ZodBoolean>;
125
+ serverId: z.ZodOptional<z.ZodString>;
126
+ name: z.ZodOptional<z.ZodString>;
127
+ listen: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
128
+ domains: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
129
+ target: z.ZodString;
130
+ locationPath: z.ZodOptional<z.ZodString>;
131
+ enabled: z.ZodOptional<z.ZodBoolean>;
132
+ reloadAfterSave: z.ZodOptional<z.ZodBoolean>;
133
+ }, "strict", z.ZodTypeAny, {
134
+ target: string;
135
+ name?: string | undefined;
136
+ confirm?: boolean | undefined;
137
+ dryRun?: boolean | undefined;
138
+ serverId?: string | undefined;
139
+ listen?: string[] | undefined;
140
+ domains?: string[] | undefined;
141
+ locationPath?: string | undefined;
142
+ enabled?: boolean | undefined;
143
+ reloadAfterSave?: boolean | undefined;
144
+ }, {
145
+ target: string;
146
+ name?: string | undefined;
147
+ confirm?: boolean | undefined;
148
+ dryRun?: boolean | undefined;
149
+ serverId?: string | undefined;
150
+ listen?: string[] | undefined;
151
+ domains?: string[] | undefined;
152
+ locationPath?: string | undefined;
153
+ enabled?: boolean | undefined;
154
+ reloadAfterSave?: boolean | undefined;
155
+ }>;
156
+ export type RuntimeConfigArgs = z.infer<typeof runtimeConfigSchema>;
157
+ export type SetRuntimeArgs = z.infer<typeof setRuntimeSchema>;
158
+ export type StopProjectArgs = z.infer<typeof stopProjectSchema>;
159
+ export type NginxProxySaveArgs = z.infer<typeof nginxProxySaveSchema>;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nginxProxySaveSchema = exports.nginxReloadSchema = exports.setRuntimeSchema = exports.runtimeConfigSchema = exports.stopProjectSchema = exports.projectIdSchema = exports.runScriptSchema = exports.confirmSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.confirmSchema = {
6
+ confirm: zod_1.z.boolean().optional(),
7
+ dryRun: zod_1.z.boolean().optional(),
8
+ };
9
+ exports.runScriptSchema = zod_1.z.object({
10
+ projectId: zod_1.z.string().trim().min(1),
11
+ script: zod_1.z.string().trim().min(1),
12
+ waitMs: zod_1.z.number().int().min(0).max(10000).optional(),
13
+ ...exports.confirmSchema,
14
+ }).strict();
15
+ exports.projectIdSchema = {
16
+ projectId: zod_1.z.string().trim().min(1),
17
+ };
18
+ exports.stopProjectSchema = zod_1.z.object({
19
+ projectId: zod_1.z.string().trim().min(1).optional(),
20
+ taskId: zod_1.z.string().trim().min(1).optional(),
21
+ script: zod_1.z.string().trim().min(1).optional(),
22
+ ...exports.confirmSchema,
23
+ }).strict();
24
+ exports.runtimeConfigSchema = zod_1.z.object({
25
+ type: zod_1.z.enum(["system", "managed", "custom"]),
26
+ name: zod_1.z.string().trim().min(1).optional(),
27
+ version: zod_1.z.string().trim().min(1).optional(),
28
+ nodePath: zod_1.z.string().trim().min(1).optional(),
29
+ packageManager: zod_1.z.enum(["npm", "pnpm", "yarn"]).optional(),
30
+ }).strict();
31
+ exports.setRuntimeSchema = zod_1.z.object({
32
+ ...exports.projectIdSchema,
33
+ runtime: exports.runtimeConfigSchema,
34
+ ...exports.confirmSchema,
35
+ }).strict();
36
+ exports.nginxReloadSchema = zod_1.z.object({
37
+ ...exports.confirmSchema,
38
+ }).strict();
39
+ exports.nginxProxySaveSchema = zod_1.z.object({
40
+ serverId: zod_1.z.string().trim().min(1).optional(),
41
+ name: zod_1.z.string().trim().min(1).optional(),
42
+ listen: zod_1.z.array(zod_1.z.string().trim().min(1)).min(1).optional(),
43
+ domains: zod_1.z.array(zod_1.z.string().trim().min(1)).min(1).optional(),
44
+ target: zod_1.z.string().trim().min(1),
45
+ locationPath: zod_1.z.string().trim().min(1).optional(),
46
+ enabled: zod_1.z.boolean().optional(),
47
+ reloadAfterSave: zod_1.z.boolean().optional(),
48
+ ...exports.confirmSchema,
49
+ }).strict();
@@ -0,0 +1 @@
1
+ export { controlledTools } from "./controlled";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.controlledTools = void 0;
4
+ var controlled_1 = require("./controlled");
5
+ Object.defineProperty(exports, "controlledTools", { enumerable: true, get: function () { return controlled_1.controlledTools; } });
@@ -0,0 +1,2 @@
1
+ import type { McpToolDefinition } from "./index";
2
+ export declare function fileWriteTools(): McpToolDefinition[];
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fileWriteTools = fileWriteTools;
4
+ const zod_1 = require("zod");
5
+ const operation_result_1 = require("./controlled/operation-result");
6
+ const operation_policy_1 = require("./controlled/operation-policy");
7
+ const project_files_1 = require("../filesystem/project-files");
8
+ const result_1 = require("../utils/result");
9
+ const path_guard_service_1 = require("../services/path-guard.service");
10
+ const project_resolver_service_1 = require("../services/project-resolver.service");
11
+ const errors_1 = require("../utils/errors");
12
+ const tool_names_1 = require("../registry/tool-names");
13
+ const fileWriteSchema = zod_1.z.object({
14
+ projectId: zod_1.z.string().trim().min(1),
15
+ relativePath: zod_1.z.string().trim().min(1),
16
+ content: zod_1.z.string(),
17
+ confirm: zod_1.z.boolean().optional(),
18
+ dryRun: zod_1.z.boolean().optional(),
19
+ }).strict();
20
+ function pathGuard(context) {
21
+ return context.services.pathGuard ?? new path_guard_service_1.PathGuardService();
22
+ }
23
+ function projectResolver(context) {
24
+ return context.services.projectResolver ?? new project_resolver_service_1.ProjectResolverService(context.services.core.project);
25
+ }
26
+ function fileWriteTools() {
27
+ return [
28
+ {
29
+ name: tool_names_1.MCP_TOOL_NAMES.NGM_FILE_WRITE,
30
+ description: "Controlled write for text files inside a registered ng-manager project. Use this instead of direct filesystem writes when the target is an ng-manager project: it accepts projectId plus project-relative relativePath only, rejects absolute paths and traversal, previews by default, and confirmed writes require NGM_MCP_ALLOW_WRITE=true and are audit logged.",
31
+ riskLevel: "write",
32
+ allowPreviewWhenBlocked: true,
33
+ deferPolicyToHandler: true,
34
+ isConfirmed: operation_result_1.isConfirmed,
35
+ inputSchema: fileWriteSchema,
36
+ async handler(args, context) {
37
+ const confirmed = (0, operation_result_1.isConfirmed)(args);
38
+ const project = await projectResolver(context).resolveProject(args.projectId);
39
+ const safetyMessage = `Write project file "${args.relativePath}" for managed project "${project.name}".`;
40
+ let target;
41
+ try {
42
+ target = pathGuard(context).resolveInsideProject(project.root, args.relativePath);
43
+ }
44
+ catch (error) {
45
+ return (0, result_1.fail)(tool_names_1.MCP_TOOL_NAMES.NGM_FILE_WRITE, (0, errors_1.errorMessage)(error), (0, errors_1.errorMetadata)(error));
46
+ }
47
+ const relativePath = (0, project_files_1.projectRelativePath)(project.root, target);
48
+ const preview = {
49
+ ...(0, operation_result_1.controlledFields)("write", confirmed, (0, operation_policy_1.requiredEnv)("write")),
50
+ operation: (0, operation_result_1.operation)("preview", "write", "medium", safetyMessage),
51
+ project: { id: project.id, name: project.name, path: project.root },
52
+ relativePath,
53
+ bytes: Buffer.byteLength(args.content, "utf-8"),
54
+ };
55
+ if (!confirmed)
56
+ return (0, result_1.ok)(tool_names_1.MCP_TOOL_NAMES.NGM_FILE_WRITE, preview);
57
+ const policyBlock = (0, operation_policy_1.requireWritePolicy)("medium", safetyMessage);
58
+ if (policyBlock)
59
+ return (0, result_1.ok)(tool_names_1.MCP_TOOL_NAMES.NGM_FILE_WRITE, policyBlock);
60
+ await (0, project_files_1.writeTextFile)(target, args.content);
61
+ return (0, result_1.ok)(tool_names_1.MCP_TOOL_NAMES.NGM_FILE_WRITE, {
62
+ ...preview,
63
+ ...(0, operation_result_1.controlledFields)("write", true, (0, operation_policy_1.requiredEnv)("write")),
64
+ operation: (0, operation_result_1.operation)("executed", "write", "medium", safetyMessage),
65
+ changedFiles: [relativePath],
66
+ });
67
+ },
68
+ },
69
+ ];
70
+ }
@@ -3,6 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.gitTools = gitTools;
4
4
  const zod_1 = require("zod");
5
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 git_validator_1 = require("../standard/validators/git.validator");
6
9
  const gitProjectSchema = zod_1.z.object({
7
10
  projectId: zod_1.z.string().trim().min(1).optional(),
8
11
  projectPath: zod_1.z.string().trim().min(1).optional(),
@@ -10,26 +13,124 @@ const gitProjectSchema = zod_1.z.object({
10
13
  const gitDiffSchema = gitProjectSchema.extend({
11
14
  maxBytes: zod_1.z.number().int().min(1).max(200000).optional(),
12
15
  }).strict();
16
+ const branchNameSchema = gitProjectSchema.extend({
17
+ branchName: zod_1.z.string().trim().min(1),
18
+ }).strict();
19
+ const commitMessageSchema = gitProjectSchema.extend({
20
+ message: zod_1.z.string().trim().min(1),
21
+ }).strict();
22
+ const generateCommitMessageSchema = gitProjectSchema.extend({
23
+ type: zod_1.z.string().trim().min(1).optional(),
24
+ scope: zod_1.z.string().trim().min(1).optional(),
25
+ summary: zod_1.z.string().trim().min(1),
26
+ }).strict();
27
+ const reviewSummarySchema = gitProjectSchema.extend({
28
+ changedFiles: zod_1.z.array(zod_1.z.string().trim().min(1)).optional(),
29
+ }).strict();
30
+ async function normalizeGitArgs(context, args) {
31
+ if (!args.projectId)
32
+ return args;
33
+ const project = await (0, project_files_1.resolveProjectRoot)(context, args);
34
+ return { projectId: args.projectId, projectPath: project.projectRoot };
35
+ }
36
+ async function standardFor(context, args) {
37
+ const project = await (0, project_files_1.resolveProjectRoot)(context, args);
38
+ return (0, frontend_standard_service_1.loadFrontendStandard)(project);
39
+ }
40
+ async function optionalGitValue(read, fallback) {
41
+ if (!read)
42
+ return fallback;
43
+ try {
44
+ return await read();
45
+ }
46
+ catch {
47
+ return fallback;
48
+ }
49
+ }
13
50
  function gitTools() {
14
51
  return [
15
52
  {
16
- name: "ngm.git.status",
17
- description: "Read Git working tree status for a project. This MVP uses a core Git service stub.",
53
+ name: "ngm_git_status",
54
+ description: "Read Git working tree status for a project using fixed read-only git status/branch commands.",
18
55
  riskLevel: "read",
19
56
  inputSchema: gitProjectSchema,
20
57
  async handler(args, context) {
21
- const data = await context.services.git.status(args);
22
- return (0, result_1.ok)("ngm.git.status", data);
58
+ const data = await context.services.git.status(await normalizeGitArgs(context, args));
59
+ return (0, result_1.ok)("ngm_git_status", data);
23
60
  },
24
61
  },
25
62
  {
26
- name: "ngm.git.diff",
27
- description: "Read Git diff for a project. This MVP uses a core Git service stub.",
63
+ name: "ngm_git_diff",
64
+ description: "Read Git diff for a project using a fixed read-only git diff command.",
28
65
  riskLevel: "read",
29
66
  inputSchema: gitDiffSchema,
30
67
  async handler(args, context) {
31
- const data = await context.services.git.diff(args);
32
- return (0, result_1.ok)("ngm.git.diff", data);
68
+ const data = await context.services.git.diff(await normalizeGitArgs(context, args));
69
+ return (0, result_1.ok)("ngm_git_diff", data);
70
+ },
71
+ },
72
+ {
73
+ name: "ngm_git_validate_branch_name",
74
+ description: "Validate a branch name against the configured frontend standard.",
75
+ riskLevel: "read",
76
+ inputSchema: branchNameSchema,
77
+ async handler(args, context) {
78
+ const loaded = await standardFor(context, args);
79
+ return (0, result_1.ok)("ngm_git_validate_branch_name", {
80
+ standardSource: loaded.source,
81
+ ...(0, git_validator_1.validateBranchName)(args.branchName, loaded.standard),
82
+ });
83
+ },
84
+ },
85
+ {
86
+ name: "ngm_git_validate_commit_message",
87
+ description: "Validate a commit message against the configured frontend standard.",
88
+ riskLevel: "read",
89
+ inputSchema: commitMessageSchema,
90
+ async handler(args, context) {
91
+ const loaded = await standardFor(context, args);
92
+ return (0, result_1.ok)("ngm_git_validate_commit_message", {
93
+ standardSource: loaded.source,
94
+ ...(0, git_validator_1.validateCommitMessage)(args.message, loaded.standard),
95
+ });
96
+ },
97
+ },
98
+ {
99
+ name: "ngm_git_generate_commit_message",
100
+ description: "Generate a commit message that follows the configured frontend standard.",
101
+ riskLevel: "read",
102
+ inputSchema: generateCommitMessageSchema,
103
+ async handler(args, context) {
104
+ const loaded = await standardFor(context, args);
105
+ const message = (0, git_validator_1.generateCommitMessage)({
106
+ type: args.type,
107
+ scope: args.scope,
108
+ summary: args.summary,
109
+ }, loaded.standard);
110
+ return (0, result_1.ok)("ngm_git_generate_commit_message", {
111
+ message,
112
+ validation: (0, git_validator_1.validateCommitMessage)(message, loaded.standard),
113
+ });
114
+ },
115
+ },
116
+ {
117
+ name: "ngm_git_generate_review_summary",
118
+ description: "Generate a compact review summary from changed files and read-only Git context.",
119
+ riskLevel: "read",
120
+ inputSchema: reviewSummarySchema,
121
+ async handler(args, context) {
122
+ const gitArgs = await normalizeGitArgs(context, args);
123
+ const changedFiles = args.changedFiles ?? await optionalGitValue(context.services.git.changedFiles ? () => context.services.git.changedFiles(gitArgs) : undefined, []);
124
+ const branch = await optionalGitValue(context.services.git.currentBranch ? () => context.services.git.currentBranch(gitArgs) : undefined, undefined);
125
+ const latest = await optionalGitValue(context.services.git.latestLog ? () => context.services.git.latestLog(gitArgs) : undefined, undefined);
126
+ return (0, result_1.ok)("ngm_git_generate_review_summary", {
127
+ branch,
128
+ latest,
129
+ changedFiles,
130
+ summary: changedFiles.length
131
+ ? `Review ${changedFiles.length} changed file(s): ${changedFiles.slice(0, 8).join(", ")}${changedFiles.length > 8 ? "..." : ""}`
132
+ : "No changed files detected.",
133
+ });
33
134
  },
34
135
  },
35
136
  ];
@@ -1,4 +1,4 @@
1
- import type { HubV2ResolvedContext } from "./config";
1
+ import type { HubV2ResolvedContext } from "./config/index";
2
2
  export type HttpMethod = "GET" | "POST" | "PATCH" | "DELETE";
3
3
  export declare class HubV2Client {
4
4
  private readonly context;
@@ -9,6 +9,11 @@ export declare class HubV2Client {
9
9
  preserveNull?: boolean;
10
10
  }): Promise<T>;
11
11
  multipart<T = unknown>(method: "POST", url: string, body: FormData): Promise<T>;
12
+ raw(method: "GET", url: string): Promise<{
13
+ content: Buffer;
14
+ contentType: string;
15
+ contentDisposition: string | null;
16
+ }>;
12
17
  private queryUrl;
13
18
  }
14
19
  export declare function compact(values: Record<string, unknown>): Record<string, unknown>;
@@ -42,6 +42,21 @@ class HubV2Client {
42
42
  }
43
43
  return (parsed ?? { code: "OK", data: null });
44
44
  }
45
+ async raw(method, url) {
46
+ const response = await fetch(url, {
47
+ method,
48
+ headers: { Authorization: `Bearer ${this.context.token}` },
49
+ });
50
+ if (!response.ok) {
51
+ const text = await response.text();
52
+ throw (0, errors_1.toHubV2HttpError)(response.status, response.statusText, parseResponseBody(text));
53
+ }
54
+ return {
55
+ content: Buffer.from(await response.arrayBuffer()),
56
+ contentType: response.headers.get("content-type") ?? "application/octet-stream",
57
+ contentDisposition: response.headers.get("content-disposition"),
58
+ };
59
+ }
45
60
  queryUrl(prefix, suffix, query) {
46
61
  let url = `${this.context.baseUrl}/${prefix}/projects/${encodeURIComponent(this.context.projectKey)}${suffix}`;
47
62
  const queryString = toQueryString(query ?? {});
@@ -0,0 +1,2 @@
1
+ export declare function resolveAgentConnectionsPath(): string;
2
+ export declare function configSearchPaths(pathValue?: string): string[];
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveAgentConnectionsPath = resolveAgentConnectionsPath;
4
+ exports.configSearchPaths = configSearchPaths;
5
+ const os_1 = require("os");
6
+ const path_1 = require("path");
7
+ const env_1 = require("./env");
8
+ function resolveAgentConnectionsPath() {
9
+ const envConfig = (0, env_1.envValue)("HUB_V2_CONFIG");
10
+ if (envConfig) {
11
+ return (0, path_1.resolve)(envConfig);
12
+ }
13
+ return (0, path_1.join)((0, os_1.homedir)(), ".ng-manager", "agent-connections.json");
14
+ }
15
+ function configSearchPaths(pathValue) {
16
+ return pathValue ? [(0, path_1.resolve)(pathValue)] : [resolveAgentConnectionsPath()];
17
+ }
@@ -0,0 +1 @@
1
+ export declare function envValue(...names: string[]): string | undefined;