agent-enderun 1.11.3 → 1.11.5

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 (170) hide show
  1. package/README.md +84 -277
  2. package/bin/validate-agent-army.js +0 -1
  3. package/dist/framework-mcp/src/index.js +11 -1
  4. package/dist/framework-mcp/src/index.js.map +1 -1
  5. package/dist/framework-mcp/src/tools/control_plane/locking.js +17 -3
  6. package/dist/framework-mcp/src/tools/control_plane/locking.js.map +1 -1
  7. package/dist/framework-mcp/src/tools/definitions.js +0 -10
  8. package/dist/framework-mcp/src/tools/definitions.js.map +1 -1
  9. package/dist/framework-mcp/src/tools/index.js +0 -2
  10. package/dist/framework-mcp/src/tools/index.js.map +1 -1
  11. package/dist/framework-mcp/src/tools/memory/get_insights.js +4 -4
  12. package/dist/framework-mcp/src/tools/memory/get_insights.js.map +1 -1
  13. package/dist/framework-mcp/src/tools/messaging/send_message.js +10 -5
  14. package/dist/framework-mcp/src/tools/messaging/send_message.js.map +1 -1
  15. package/dist/framework-mcp/src/tools/search/grep_search.js +2 -3
  16. package/dist/framework-mcp/src/tools/search/grep_search.js.map +1 -1
  17. package/dist/framework-mcp/src/utils/compliance.d.ts +1 -1
  18. package/dist/framework-mcp/src/utils/compliance.js +68 -19
  19. package/dist/framework-mcp/src/utils/compliance.js.map +1 -1
  20. package/dist/framework-mcp/tests/tools/messaging/send_message.test.js +7 -7
  21. package/dist/framework-mcp/tests/tools/messaging/send_message.test.js.map +1 -1
  22. package/dist/src/cli/adapters/scaffold.d.ts +1 -1
  23. package/dist/src/cli/adapters/scaffold.js +8 -8
  24. package/dist/src/cli/adapters/scaffold.js.map +1 -1
  25. package/dist/src/cli/commands/check.js +25 -40
  26. package/dist/src/cli/commands/check.js.map +1 -1
  27. package/dist/src/cli/commands/contract.d.ts +3 -1
  28. package/dist/src/cli/commands/contract.js +8 -2
  29. package/dist/src/cli/commands/contract.js.map +1 -1
  30. package/dist/src/cli/commands/init/scaffold-core.d.ts +1 -0
  31. package/dist/src/cli/commands/init/scaffold-core.js +14 -1
  32. package/dist/src/cli/commands/init/scaffold-core.js.map +1 -1
  33. package/dist/src/cli/commands/init/scaffold-ops.js +0 -2
  34. package/dist/src/cli/commands/init/scaffold-ops.js.map +1 -1
  35. package/dist/src/cli/commands/init.d.ts +1 -0
  36. package/dist/src/cli/commands/init.js +16 -7
  37. package/dist/src/cli/commands/init.js.map +1 -1
  38. package/dist/src/cli/commands/orchestrate.js +31 -3
  39. package/dist/src/cli/commands/orchestrate.js.map +1 -1
  40. package/dist/src/cli/commands/plan.js +1 -2
  41. package/dist/src/cli/commands/plan.js.map +1 -1
  42. package/dist/src/cli/commands/status.js.map +1 -1
  43. package/dist/src/cli/index.js +18 -21
  44. package/dist/src/cli/index.js.map +1 -1
  45. package/dist/src/cli/shims.js +39 -26
  46. package/dist/src/cli/shims.js.map +1 -1
  47. package/dist/src/cli/utils/compliance.d.ts +5 -1
  48. package/dist/src/cli/utils/compliance.js +90 -42
  49. package/dist/src/cli/utils/compliance.js.map +1 -1
  50. package/dist/src/cli/utils/ui.js +11 -11
  51. package/dist/src/cli/utils/ui.js.map +1 -1
  52. package/dist/src/modules/adapters/definitions.js +130 -113
  53. package/dist/src/modules/adapters/definitions.js.map +1 -1
  54. package/dist/src/modules/adapters/registry.d.ts +12 -0
  55. package/dist/src/modules/adapters/registry.js +19 -0
  56. package/dist/src/modules/adapters/registry.js.map +1 -0
  57. package/dist/src/modules/adapters/shared.js +5 -4
  58. package/dist/src/modules/adapters/shared.js.map +1 -1
  59. package/dist/src/modules/adapters/types.d.ts +1 -1
  60. package/dist/src/modules/adapters/types.js +1 -1
  61. package/dist/src/modules/adapters/types.js.map +1 -1
  62. package/dist/src/modules/agents/definitions.d.ts +6 -6
  63. package/dist/src/modules/agents/definitions.js +35 -18
  64. package/dist/src/modules/agents/definitions.js.map +1 -1
  65. package/dist/src/modules/agents/registry/analyst.js +1 -1
  66. package/dist/src/modules/agents/registry/analyst.js.map +1 -1
  67. package/dist/src/modules/agents/registry/architect.js +1 -1
  68. package/dist/src/modules/agents/registry/architect.js.map +1 -1
  69. package/dist/src/modules/agents/registry/backend.js +1 -1
  70. package/dist/src/modules/agents/registry/backend.js.map +1 -1
  71. package/dist/src/modules/agents/registry/database.js +1 -1
  72. package/dist/src/modules/agents/registry/database.js.map +1 -1
  73. package/dist/src/modules/agents/registry/devops.js +1 -1
  74. package/dist/src/modules/agents/registry/devops.js.map +1 -1
  75. package/dist/src/modules/agents/registry/explorer.js +1 -1
  76. package/dist/src/modules/agents/registry/explorer.js.map +1 -1
  77. package/dist/src/modules/agents/registry/frontend.js +1 -1
  78. package/dist/src/modules/agents/registry/frontend.js.map +1 -1
  79. package/dist/src/modules/agents/registry/git.js +1 -1
  80. package/dist/src/modules/agents/registry/git.js.map +1 -1
  81. package/dist/src/modules/agents/registry/manager.js +1 -2
  82. package/dist/src/modules/agents/registry/manager.js.map +1 -1
  83. package/dist/src/modules/agents/registry/mobile.js +1 -1
  84. package/dist/src/modules/agents/registry/mobile.js.map +1 -1
  85. package/dist/src/modules/agents/registry/quality.js +1 -1
  86. package/dist/src/modules/agents/registry/quality.js.map +1 -1
  87. package/dist/src/modules/agents/registry/security.js +1 -1
  88. package/dist/src/modules/agents/registry/security.js.map +1 -1
  89. package/dist/src/shared/constants.d.ts +5 -2
  90. package/dist/src/shared/constants.js +5 -0
  91. package/dist/src/shared/constants.js.map +1 -1
  92. package/dist/src/shared/fs.js +4 -3
  93. package/dist/src/shared/fs.js.map +1 -1
  94. package/dist/tests/agents-definitions.test.js +2 -1
  95. package/dist/tests/agents-definitions.test.js.map +1 -1
  96. package/dist/tests/approve.test.js +3 -1
  97. package/dist/tests/approve.test.js.map +1 -1
  98. package/dist/tests/integration/agent_flow.test.js +2 -0
  99. package/dist/tests/integration/agent_flow.test.js.map +1 -1
  100. package/dist/tests/integration/hermes_locking.test.d.ts +1 -0
  101. package/dist/tests/integration/hermes_locking.test.js +64 -0
  102. package/dist/tests/integration/hermes_locking.test.js.map +1 -0
  103. package/dist/tests/memory-utils.test.js +2 -0
  104. package/dist/tests/memory-utils.test.js.map +1 -1
  105. package/dist/tests/orchestrate.test.js +11 -6
  106. package/dist/tests/orchestrate.test.js.map +1 -1
  107. package/dist/tests/status.test.js +2 -0
  108. package/dist/tests/status.test.js.map +1 -1
  109. package/framework-mcp/dist/index.js +11 -1
  110. package/framework-mcp/dist/tools/control_plane/locking.js +17 -3
  111. package/framework-mcp/dist/tools/definitions.js +0 -10
  112. package/framework-mcp/dist/tools/index.js +0 -2
  113. package/framework-mcp/dist/tools/memory/get_insights.js +4 -4
  114. package/framework-mcp/dist/tools/messaging/send_message.js +10 -5
  115. package/framework-mcp/dist/tools/search/grep_search.js +2 -3
  116. package/framework-mcp/dist/utils/compliance.js +68 -19
  117. package/framework-mcp/node_modules/.package-lock.json +1179 -0
  118. package/framework-mcp/package-lock.json +1191 -0
  119. package/framework-mcp/package.json +2 -2
  120. package/framework-mcp/src/index.ts +13 -1
  121. package/framework-mcp/src/tools/control_plane/locking.ts +18 -4
  122. package/framework-mcp/src/tools/definitions.ts +0 -10
  123. package/framework-mcp/src/tools/index.ts +0 -2
  124. package/framework-mcp/src/tools/memory/get_insights.ts +4 -4
  125. package/framework-mcp/src/tools/messaging/send_message.ts +11 -5
  126. package/framework-mcp/src/tools/search/grep_search.ts +2 -3
  127. package/framework-mcp/src/utils/compliance.ts +83 -25
  128. package/framework-mcp/tests/tools/messaging/send_message.test.ts +7 -7
  129. package/package.json +5 -5
  130. package/src/cli/adapters/scaffold.ts +9 -8
  131. package/src/cli/commands/check.ts +26 -48
  132. package/src/cli/commands/contract.ts +5 -2
  133. package/src/cli/commands/init/scaffold-core.ts +18 -2
  134. package/src/cli/commands/init/scaffold-ops.ts +0 -3
  135. package/src/cli/commands/init.ts +19 -8
  136. package/src/cli/commands/orchestrate.ts +36 -3
  137. package/src/cli/commands/plan.ts +1 -2
  138. package/src/cli/commands/status.ts +0 -1
  139. package/src/cli/index.ts +18 -22
  140. package/src/cli/shims.ts +39 -26
  141. package/src/cli/utils/compliance.ts +101 -47
  142. package/src/cli/utils/ui.ts +11 -11
  143. package/src/modules/adapters/definitions.ts +102 -57
  144. package/src/modules/adapters/registry.ts +27 -0
  145. package/src/modules/adapters/shared.ts +5 -4
  146. package/src/modules/adapters/types.ts +1 -1
  147. package/src/modules/agents/definitions.ts +35 -17
  148. package/src/modules/agents/registry/analyst.ts +1 -1
  149. package/src/modules/agents/registry/architect.ts +1 -1
  150. package/src/modules/agents/registry/backend.ts +1 -1
  151. package/src/modules/agents/registry/database.ts +1 -1
  152. package/src/modules/agents/registry/devops.ts +1 -1
  153. package/src/modules/agents/registry/explorer.ts +1 -1
  154. package/src/modules/agents/registry/frontend.ts +1 -1
  155. package/src/modules/agents/registry/git.ts +1 -1
  156. package/src/modules/agents/registry/manager.ts +1 -2
  157. package/src/modules/agents/registry/mobile.ts +1 -1
  158. package/src/modules/agents/registry/quality.ts +1 -1
  159. package/src/modules/agents/registry/security.ts +1 -1
  160. package/src/shared/constants.ts +5 -0
  161. package/src/shared/fs.ts +4 -3
  162. package/templates/standards/frontend-standards.md +7 -2
  163. package/templates/standards/governance-standards.md +27 -1
  164. package/templates/standards/quality-standards.md +2 -1
  165. package/bin/enderun-dashboard.js +0 -25
  166. package/framework-mcp/src/tools/dashboard/start_dashboard.ts +0 -33
  167. package/src/cli/commands/dashboard/data-service.ts +0 -167
  168. package/src/cli/commands/dashboard/html-template.ts +0 -696
  169. package/src/cli/commands/dashboard/server.ts +0 -43
  170. package/src/cli/commands/dashboard.ts +0 -11
@@ -10,8 +10,8 @@ export const UI = {
10
10
  * Renders a strategic intent block similar to Gemini CLI's topic updates.
11
11
  */
12
12
  intent: (title: string, intent: string) => {
13
- console.warn(`\n${chalk.bold.cyan(title)}:`);
14
- console.warn(`${chalk.italic.gray(` ${intent}`)}\n`);
13
+ process.stdout.write(`\n${chalk.bold.cyan(title)}:\n`);
14
+ process.stdout.write(`${chalk.italic.gray(` ${intent}`)}\n\n`);
15
15
  },
16
16
 
17
17
  /**
@@ -21,39 +21,39 @@ export const UI = {
21
21
  const width = process.stdout.columns || 80;
22
22
  const line = "─".repeat(Math.max(0, width - 2));
23
23
 
24
- console.warn(chalk.gray(`╭${line}╮`));
24
+ process.stdout.write(chalk.gray(`╭${line}╮`) + "\n");
25
25
  const padding = Math.max(0, width - agentName.length - 27);
26
- console.warn(`${chalk.gray("│")} ${chalk.bold.yellow("≡")} ${chalk.white(`Running Agent: ${chalk.bold.green(agentName)}...`)} ${chalk.gray("(ctrl+o to expand)".padStart(padding))} ${chalk.gray("│")}`);
26
+ process.stdout.write(`${chalk.gray("│")} ${chalk.bold.yellow("≡")} ${chalk.white(`Running Agent: ${chalk.bold.green(agentName)}...`)} ${chalk.gray("(ctrl+o to expand)".padStart(padding))} ${chalk.gray("│")}\n`);
27
27
  if (action) {
28
28
  const paddingAction = Math.max(0, width - action.length - 6);
29
- console.warn(`${chalk.gray("│")} ${chalk.blue("!")} ${chalk.cyan(action)} ${" ".repeat(paddingAction)} ${chalk.gray("│")}`);
29
+ process.stdout.write(`${chalk.gray("│")} ${chalk.blue("!")} ${chalk.cyan(action)} ${" ".repeat(paddingAction)} ${chalk.gray("│")}\n`);
30
30
  }
31
31
  if (details) {
32
32
  const paddingDetails = Math.max(0, width - details.length - 7);
33
- console.warn(`${chalk.gray("│")} ${chalk.gray(details.slice(0, width - 10))} ${" ".repeat(paddingDetails)} ${chalk.gray("│")}`);
33
+ process.stdout.write(`${chalk.gray("│")} ${chalk.gray(details.slice(0, width - 10))} ${" ".repeat(paddingDetails)} ${chalk.gray("│")}\n`);
34
34
  }
35
- console.warn(chalk.gray(`╰${line}╯`));
35
+ process.stdout.write(chalk.gray(`╰${line}╯`) + "\n");
36
36
  },
37
37
 
38
38
  /**
39
39
  * Renders a success status message.
40
40
  */
41
41
  success: (msg: string) => {
42
- console.warn(`${chalk.bold.green("✅")} ${msg}`);
42
+ process.stdout.write(`${chalk.bold.green("✅")} ${msg}\n`);
43
43
  },
44
44
 
45
45
  /**
46
46
  * Renders an error status message.
47
47
  */
48
48
  error: (msg: string) => {
49
- console.error(`${chalk.bold.red("❌")} ${chalk.red(msg)}`);
49
+ process.stderr.write(`${chalk.bold.red("❌")} ${chalk.red(msg)}\n`);
50
50
  },
51
51
 
52
52
  /**
53
53
  * Renders a warning status message.
54
54
  */
55
55
  warning: (msg: string) => {
56
- console.warn(`${chalk.bold.yellow("⚠️")} ${chalk.yellow(msg)}`);
56
+ process.stdout.write(`${chalk.bold.yellow("⚠️")} ${chalk.yellow(msg)}\n`);
57
57
  },
58
58
 
59
59
  /**
@@ -61,6 +61,6 @@ export const UI = {
61
61
  */
62
62
  divider: () => {
63
63
  const width = process.stdout.columns || 80;
64
- console.warn(chalk.gray("─".repeat(width)));
64
+ process.stdout.write(chalk.gray("─".repeat(width)) + "\n");
65
65
  }
66
66
  };
@@ -3,13 +3,14 @@ import type { AdapterConfig, AdapterId } from "./types.js";
3
3
  import { addMcpServerToClaude, findClaudeConfigPath } from "../../cli/utils/claude.js";
4
4
  import { writeJsonFile } from "../../shared/fs.js";
5
5
  import { registerGlobalAntigravityPlugins } from "./shared.js";
6
- import { unifiedAdapterPath, UNIFIED_ADAPTER_SLUG } from "../../shared/constants.js";
6
+ import { registry } from "./registry.js";
7
+ import { UI } from "../../cli/utils/ui.js";
7
8
 
8
- /**
9
- * Mapped Adapter Configurations
10
- */
11
- export const ADAPTER_CONFIGS: Record<AdapterId, AdapterConfig> = {
12
- gemini: {
9
+ // ─── Register Core Adapters ──────────────────────────────────────────────────
10
+
11
+ // ♊ Gemini
12
+ registry.register(
13
+ {
13
14
  id: "gemini",
14
15
  frameworkDir: ".gemini",
15
16
  shimFile: "GEMINI.md",
@@ -17,10 +18,20 @@ export const ADAPTER_CONFIGS: Record<AdapterId, AdapterConfig> = {
17
18
  role: "commander",
18
19
  templateDir: ".enderun",
19
20
  nestedDirs: ["agents", "rules"],
20
- agentsDir: ".gemini/agents", // Use unified path
21
+ agentsDir: ".gemini/agents",
21
22
  agentsExt: ".md"
22
23
  },
23
- claude: {
24
+ (projectRoot, mcpBlock) => {
25
+ const frameworkDir = ".gemini";
26
+ writeJsonFile(path.join(projectRoot, frameworkDir, "mcp.json"), mcpBlock);
27
+ UI.success(`Gemini MCP registered → ${frameworkDir}/mcp.json`);
28
+ registerGlobalAntigravityPlugins(mcpBlock);
29
+ }
30
+ );
31
+
32
+ // 🚀 Claude
33
+ registry.register(
34
+ {
24
35
  id: "claude",
25
36
  frameworkDir: ".claude",
26
37
  shimFile: "CLAUDE.md",
@@ -31,7 +42,24 @@ export const ADAPTER_CONFIGS: Record<AdapterId, AdapterConfig> = {
31
42
  agentsDir: ".claude/agents",
32
43
  agentsExt: ".md"
33
44
  },
34
- grok: {
45
+ (projectRoot, mcpBlock) => {
46
+ const configPath = findClaudeConfigPath();
47
+ if (configPath) {
48
+ const block = mcpBlock as { mcpServers: Record<string, unknown> };
49
+ const mcpEntry = block.mcpServers["agent-enderun"] as Record<string, unknown>;
50
+ const ok = addMcpServerToClaude(configPath, "agent-enderun", mcpEntry);
51
+ if (ok) UI.success(`Claude MCP registered → ${configPath}`);
52
+ }
53
+ const frameworkDir = ".claude";
54
+ writeJsonFile(path.join(projectRoot, frameworkDir, "mcp_config.json"), mcpBlock);
55
+ writeJsonFile(path.join(projectRoot, ".mcp.json"), mcpBlock);
56
+ UI.success("Claude Code Project MCP → .mcp.json");
57
+ }
58
+ );
59
+
60
+ // 🤖 Grok
61
+ registry.register(
62
+ {
35
63
  id: "grok",
36
64
  frameworkDir: ".grok",
37
65
  shimFile: "GROK.md",
@@ -42,7 +70,16 @@ export const ADAPTER_CONFIGS: Record<AdapterId, AdapterConfig> = {
42
70
  agentsDir: ".grok/agents",
43
71
  agentsExt: ".md"
44
72
  },
45
- cursor: {
73
+ (projectRoot, mcpBlock) => {
74
+ const frameworkDir = ".grok";
75
+ writeJsonFile(path.join(projectRoot, frameworkDir, "mcp_config.json"), mcpBlock);
76
+ UI.success(`Grok MCP → ${frameworkDir}/mcp_config.json`);
77
+ }
78
+ );
79
+
80
+ // ✍️ Cursor
81
+ registry.register(
82
+ {
46
83
  id: "cursor",
47
84
  frameworkDir: ".cursor",
48
85
  shimFile: "CURSOR.md",
@@ -53,7 +90,16 @@ export const ADAPTER_CONFIGS: Record<AdapterId, AdapterConfig> = {
53
90
  agentsDir: ".cursor/rules",
54
91
  agentsExt: ".mdc"
55
92
  },
56
- codex: {
93
+ (projectRoot, mcpBlock) => {
94
+ const frameworkDir = ".cursor";
95
+ writeJsonFile(path.join(projectRoot, frameworkDir, "mcp.json"), mcpBlock);
96
+ UI.success(`Cursor IDE Project MCP → ${frameworkDir}/mcp.json`);
97
+ }
98
+ );
99
+
100
+ // 💡 Codex (Copilot)
101
+ registry.register(
102
+ {
57
103
  id: "codex",
58
104
  frameworkDir: ".agents",
59
105
  shimFile: "copilot-instructions.md",
@@ -64,7 +110,38 @@ export const ADAPTER_CONFIGS: Record<AdapterId, AdapterConfig> = {
64
110
  agentsDir: ".agents/instructions",
65
111
  agentsExt: ".md"
66
112
  },
67
- "antigravity-cli": {
113
+ (projectRoot, mcpBlock) => {
114
+ const frameworkDir = ".agents";
115
+ writeJsonFile(path.join(projectRoot, frameworkDir, "mcp_config.json"), mcpBlock);
116
+ writeJsonFile(path.join(projectRoot, ".vscode/mcp.json"), mcpBlock);
117
+ writeJsonFile(path.join(projectRoot, ".mcp.json"), mcpBlock);
118
+ UI.success("GitHub Copilot Project MCP → .vscode/mcp.json & .mcp.json");
119
+ }
120
+ );
121
+
122
+ // 🏠 Local LLM (Ollama / Private AI)
123
+ registry.register(
124
+ {
125
+ id: "local",
126
+ frameworkDir: ".enderun",
127
+ shimFile: "LOCAL_AI.md",
128
+ shimTemplate: "src/cli/shims/local.md",
129
+ role: "commander",
130
+ templateDir: ".enderun",
131
+ nestedDirs: ["agents", "rules"],
132
+ agentsDir: ".enderun/agents",
133
+ agentsExt: ".md"
134
+ },
135
+ (projectRoot, mcpBlock) => {
136
+ const frameworkDir = ".enderun";
137
+ writeJsonFile(path.join(projectRoot, frameworkDir, "mcp_config.json"), mcpBlock);
138
+ UI.success(`Local LLM MCP (Ollama/Private AI) registered → ${frameworkDir}/mcp_config.json`);
139
+ }
140
+ );
141
+
142
+ // 🛸 Antigravity
143
+ registry.register(
144
+ {
68
145
  id: "antigravity-cli",
69
146
  frameworkDir: ".antigravity",
70
147
  shimFile: "AGENTS.md",
@@ -74,53 +151,21 @@ export const ADAPTER_CONFIGS: Record<AdapterId, AdapterConfig> = {
74
151
  nestedDirs: ["agents", "plugins", "rules"],
75
152
  agentsDir: ".antigravity/agents",
76
153
  agentsExt: ".md"
154
+ },
155
+ (projectRoot, mcpBlock) => {
156
+ const frameworkDir = ".antigravity";
157
+ writeJsonFile(path.join(projectRoot, frameworkDir, "mcp_config.json"), mcpBlock);
158
+ UI.success(`Antigravity CLI MCP → ${frameworkDir}/mcp_config.json`);
159
+ registerGlobalAntigravityPlugins(mcpBlock);
77
160
  }
78
- };
161
+ );
162
+
163
+ /**
164
+ * Mapped Adapter Configurations
165
+ */
166
+ export const ADAPTER_CONFIGS: Record<AdapterId, AdapterConfig> = registry.getConfigs();
79
167
 
80
168
  /**
81
169
  * Post-Initialization Handlers for specific adapters
82
170
  */
83
- export const POST_INIT_HANDLERS: Record<AdapterId, (projectRoot: string, mcpBlock: unknown) => void> = {
84
- gemini: (projectRoot, mcpBlock) => {
85
- const frameworkDir = ADAPTER_CONFIGS.gemini.frameworkDir;
86
- writeJsonFile(path.join(projectRoot, frameworkDir, "mcp.json"), mcpBlock);
87
- console.warn(`✅ Gemini MCP registered → ${frameworkDir}/mcp.json`);
88
- registerGlobalAntigravityPlugins(mcpBlock);
89
- },
90
- claude: (projectRoot, mcpBlock) => {
91
- const configPath = findClaudeConfigPath();
92
- if (configPath) {
93
- const block = mcpBlock as { mcpServers: Record<string, unknown> };
94
- const mcpEntry = block.mcpServers["agent-enderun"] as Record<string, unknown>;
95
- const ok = addMcpServerToClaude(configPath, "agent-enderun", mcpEntry);
96
- if (ok) console.warn(`✅ Claude MCP registered → ${configPath}`);
97
- }
98
- const frameworkDir = ADAPTER_CONFIGS.claude.frameworkDir;
99
- writeJsonFile(path.join(projectRoot, frameworkDir, "mcp_config.json"), mcpBlock);
100
- writeJsonFile(path.join(projectRoot, ".mcp.json"), mcpBlock);
101
- console.warn("✅ Claude Code Project MCP → .mcp.json");
102
- },
103
- grok: (projectRoot, mcpBlock) => {
104
- const frameworkDir = ADAPTER_CONFIGS.grok.frameworkDir;
105
- writeJsonFile(path.join(projectRoot, frameworkDir, "mcp_config.json"), mcpBlock);
106
- console.warn(`✅ Grok MCP → ${frameworkDir}/mcp_config.json`);
107
- },
108
- cursor: (projectRoot, mcpBlock) => {
109
- const frameworkDir = ADAPTER_CONFIGS.cursor.frameworkDir;
110
- writeJsonFile(path.join(projectRoot, frameworkDir, "mcp.json"), mcpBlock);
111
- console.warn(`✅ Cursor IDE Project MCP → ${frameworkDir}/mcp.json`);
112
- },
113
- codex: (projectRoot, mcpBlock) => {
114
- const frameworkDir = ADAPTER_CONFIGS.codex.frameworkDir;
115
- writeJsonFile(path.join(projectRoot, frameworkDir, "mcp_config.json"), mcpBlock);
116
- writeJsonFile(path.join(projectRoot, ".vscode/mcp.json"), mcpBlock);
117
- writeJsonFile(path.join(projectRoot, ".mcp.json"), mcpBlock);
118
- console.warn("✅ GitHub Copilot Project MCP → .vscode/mcp.json & .mcp.json");
119
- },
120
- "antigravity-cli": (projectRoot, mcpBlock) => {
121
- const frameworkDir = ADAPTER_CONFIGS["antigravity-cli"].frameworkDir;
122
- writeJsonFile(path.join(projectRoot, frameworkDir, "mcp_config.json"), mcpBlock);
123
- console.warn(`✅ Antigravity CLI MCP → ${frameworkDir}/mcp_config.json`);
124
- registerGlobalAntigravityPlugins(mcpBlock);
125
- }
126
- };
171
+ export const POST_INIT_HANDLERS: Record<AdapterId, (projectRoot: string, mcpBlock: unknown) => void> = registry.getHandlers();
@@ -0,0 +1,27 @@
1
+ import { AdapterId, AdapterConfig } from "./types.js";
2
+
3
+ type PostInitHandler = (projectRoot: string, mcpBlock: unknown) => void;
4
+
5
+ class AdapterRegistry {
6
+ private configs: Map<string, AdapterConfig> = new Map();
7
+ private handlers: Map<string, PostInitHandler> = new Map();
8
+
9
+ register(config: AdapterConfig, handler: PostInitHandler) {
10
+ this.configs.set(config.id, config);
11
+ this.handlers.set(config.id, handler);
12
+ }
13
+
14
+ getConfigs(): Record<string, AdapterConfig> {
15
+ return Object.fromEntries(this.configs);
16
+ }
17
+
18
+ getHandlers(): Record<string, PostInitHandler> {
19
+ return Object.fromEntries(this.handlers);
20
+ }
21
+
22
+ getIds(): AdapterId[] {
23
+ return Array.from(this.configs.keys()) as AdapterId[];
24
+ }
25
+ }
26
+
27
+ export const registry = new AdapterRegistry();
@@ -6,6 +6,7 @@ import { writeJsonFile, writeTextFile } from "../../shared/fs.js";
6
6
  import { ALL_AGENTS, toAntigravityJson } from "../agents/definitions.js";
7
7
  import { CORE_SKILLS } from "../skills/definitions.js";
8
8
  import { getPackageRoot } from "../../cli/utils/pkg.js";
9
+ import { logger } from "../../shared/logger.js";
9
10
 
10
11
  export function registerGlobalAntigravityPlugins(mcpBlock: unknown): void {
11
12
  // Allow overriding via env var for different OS/Gemini CLI versions
@@ -20,7 +21,7 @@ export function registerGlobalAntigravityPlugins(mcpBlock: unknown): void {
20
21
  fs.mkdirSync(globalDir, { recursive: true });
21
22
  writeJsonFile(path.join(globalDir, "mcp.json"), mcpBlock);
22
23
  writeJsonFile(path.join(globalDir, "mcp_config.json"), mcpBlock);
23
- console.warn(`✅ Antigravity MCP registered → ${globalDir}/`);
24
+ logger.info(`Antigravity MCP registered → ${globalDir}/`);
24
25
 
25
26
  // Global Plugin configuration under plugins/agent-enderun/
26
27
  const globalPluginDir = path.join(globalDir, "plugins/agent-enderun");
@@ -103,17 +104,17 @@ ${ag.instructions.rules.map(r => `- ${r}`).join("\n")}
103
104
  // Scaffold optional empty hooks.json
104
105
  writeJsonFile(path.join(globalPluginDir, "hooks.json"), {});
105
106
 
106
- console.warn(`✅ Antigravity Plugin registered → ${globalPluginDir}/`);
107
+ logger.info(`Antigravity Plugin registered → ${globalPluginDir}/`);
107
108
 
108
109
  try {
109
110
  execSync(`agy plugin install "${globalPluginDir}"`, { stdio: "ignore" });
110
- console.warn(`✅ Antigravity Plugin installed in CLI.`);
111
+ logger.info("Antigravity Plugin installed in CLI.");
111
112
  } catch {
112
113
  // Ignore if agy is not in PATH or fails
113
114
  }
114
115
 
115
116
  } catch (e) {
116
- console.warn(`⚠️ Failed to register plugin/MCP in ${globalDir}:`, e);
117
+ logger.warn(`Failed to register plugin/MCP in ${globalDir}`, e);
117
118
  }
118
119
  }
119
120
  }
@@ -1,4 +1,4 @@
1
- export const ADAPTER_IDS = ["gemini", "claude", "grok", "cursor", "codex", "antigravity-cli"] as const;
1
+ export const ADAPTER_IDS = ["gemini", "claude", "grok", "cursor", "codex", "local", "antigravity-cli"] as const;
2
2
  export type AdapterId = (typeof ADAPTER_IDS)[number];
3
3
 
4
4
  export type AdapterRole = "commander" | "architect" | "researcher" | "implementer" | "general";
@@ -82,7 +82,6 @@ const CLAUDE_TOOL_MAP: Record<string, string> = {
82
82
  get_framework_status: "Bash",
83
83
  get_system_health: "Bash",
84
84
  check_active_ports: "Bash",
85
- start_dashboard: "Bash",
86
85
  update_contract_hash: "Write",
87
86
  acquire_lock: "Write",
88
87
  release_lock: "Write",
@@ -121,7 +120,6 @@ const GEMINI_TOOL_MAP: Record<string, string> = {
121
120
  get_framework_status: "run_shell_command",
122
121
  get_system_health: "run_shell_command",
123
122
  check_active_ports: "run_shell_command",
124
- start_dashboard: "run_shell_command",
125
123
  update_contract_hash: "write_file",
126
124
  acquire_lock: "write_file",
127
125
  release_lock: "write_file",
@@ -174,6 +172,7 @@ function buildSystemPrompt(
174
172
  ag: AgentDefinition,
175
173
  baseKnowledgeDir: string = path.join(getPackageRoot(), "templates/standards"),
176
174
  stripMetaComments = false,
175
+ paths: Record<string, string> = { backend: "apps/backend", frontend: "apps/web", mobile: "apps/mobile", docs: "docs" }
177
176
  ): string {
178
177
  const metaHeader = stripMetaComments ? [] : [
179
178
  `<!-- name: ${ag.name} -->`,
@@ -195,6 +194,13 @@ function buildSystemPrompt(
195
194
  `**Primary Role:** ${ag.role}`,
196
195
  `**Authority Tier:** ${ag.tier} (Capability: ${ag.capability}/10)`,
197
196
  "",
197
+ "## Project Structure",
198
+ "This project uses the following directory structure:",
199
+ `- **Backend:** \`${paths.backend}\``,
200
+ `- **Frontend:** \`${paths.frontend}\``,
201
+ `- **Mobile:** \`${paths.mobile}\``,
202
+ `- **Documentation:** \`${paths.docs}\``,
203
+ "",
198
204
  "## Chain of Thought Protocol",
199
205
  "> Follow these steps in strict order for every task:",
200
206
  "",
@@ -213,6 +219,7 @@ function buildSystemPrompt(
213
219
  "- Never perform irreversible operations (schema drops, bulk deletes) without @manager approval.",
214
220
  "- Prefer surgical edits (`replace_text`, `patch_file`) over full file rewrites.",
215
221
  "- Escalate ambiguity to @manager instead of guessing.",
222
+ `- Ensure all development happens exclusively inside \`${paths.backend}\`, \`${paths.frontend}\`, or \`${paths.mobile}\`.`,
216
223
  ];
217
224
 
218
225
  if (ag.instructions.knowledgeFiles?.length) {
@@ -237,7 +244,7 @@ function buildSystemPrompt(
237
244
  // Ref: https://docs.anthropic.com/en/docs/claude-code/sub-agents
238
245
  // ─────────────────────────────────────────────────────────────────────────────
239
246
 
240
- export function toClaudeCodeMd(ag: AgentDefinition, baseKnowledgeDir?: string): string {
247
+ export function toClaudeCodeMd(ag: AgentDefinition, baseKnowledgeDir?: string, paths?: Record<string, string>): string {
241
248
  const tools = [...new Set(ag.tools.map((t: string) => CLAUDE_TOOL_MAP[t] ?? t))];
242
249
  const model = resolveModel(ag.capability, "claude-code");
243
250
  const color = ag.tier === "supreme" ? "purple"
@@ -256,7 +263,7 @@ export function toClaudeCodeMd(ag: AgentDefinition, baseKnowledgeDir?: string):
256
263
  "---",
257
264
  ].join("\n");
258
265
 
259
- return `${frontmatter}\n\n${buildSystemPrompt(ag, baseKnowledgeDir)}`;
266
+ return `${frontmatter}\n\n${buildSystemPrompt(ag, baseKnowledgeDir, false, paths)}`;
260
267
  }
261
268
 
262
269
  // ─────────────────────────────────────────────────────────────────────────────
@@ -265,7 +272,7 @@ export function toClaudeCodeMd(ag: AgentDefinition, baseKnowledgeDir?: string):
265
272
  // Ref: https://ai.google.dev/gemini-api/docs/agents
266
273
  // ─────────────────────────────────────────────────────────────────────────────
267
274
 
268
- export function toGeminiCliMd(ag: AgentDefinition, baseKnowledgeDir?: string): string {
275
+ export function toGeminiCliMd(ag: AgentDefinition, baseKnowledgeDir?: string, paths?: Record<string, string>): string {
269
276
  const tools = [...new Set(ag.tools.map((t: string) => GEMINI_TOOL_MAP[t] ?? t))];
270
277
  const model = resolveModel(ag.capability, "gemini-cli");
271
278
 
@@ -280,7 +287,7 @@ export function toGeminiCliMd(ag: AgentDefinition, baseKnowledgeDir?: string): s
280
287
  "---",
281
288
  ].join("\n");
282
289
 
283
- const body = buildSystemPrompt(ag, baseKnowledgeDir, true);
290
+ const body = buildSystemPrompt(ag, baseKnowledgeDir, true, paths);
284
291
 
285
292
  const metaFooter = [
286
293
  "",
@@ -297,7 +304,7 @@ export function toGeminiCliMd(ag: AgentDefinition, baseKnowledgeDir?: string): s
297
304
  // Spec: Antigravity customAgentSpec JSON schema
298
305
  // ─────────────────────────────────────────────────────────────────────────────
299
306
 
300
- export function toAntigravityJson(ag: AgentDefinition, baseKnowledgeDir?: string): string {
307
+ export function toAntigravityJson(ag: AgentDefinition, baseKnowledgeDir?: string, paths?: Record<string, string>): string {
301
308
  const knowledgeBase = baseKnowledgeDir ?? path.join(getPackageRoot(), "templates/standards");
302
309
 
303
310
  // Embed actual file contents so the agent can read governance docs
@@ -321,6 +328,16 @@ export function toAntigravityJson(ag: AgentDefinition, baseKnowledgeDir?: string
321
328
  title: "Identity & Mission",
322
329
  content: `${ag.instructions.identity}\n\n**Mission:** ${ag.instructions.mission}`,
323
330
  },
331
+ {
332
+ title: "Project Structure",
333
+ content: [
334
+ "This project uses the following directory structure:",
335
+ `- Backend: ${paths?.backend || "apps/backend"}`,
336
+ `- Frontend: ${paths?.frontend || "apps/web"}`,
337
+ `- Mobile: ${paths?.mobile || "apps/mobile"}`,
338
+ `- Documentation: ${paths?.docs || "docs"}`,
339
+ ].join("\n"),
340
+ },
324
341
  {
325
342
  title: "Chain of Thought Protocol",
326
343
  content: ag.instructions.chainOfThought,
@@ -337,6 +354,7 @@ export function toAntigravityJson(ag: AgentDefinition, baseKnowledgeDir?: string
337
354
  "- Read PROJECT_MEMORY.md at session start.",
338
355
  "- Prefer surgical edits over full file rewrites.",
339
356
  "- Escalate high-risk operations to @manager.",
357
+ `- Ensure development happens inside ${paths?.backend || "apps/backend"}, ${paths?.frontend || "apps/web"}, or ${paths?.mobile || "apps/mobile"}.`,
340
358
  ].join("\n"),
341
359
  },
342
360
  ...knowledgeSections,
@@ -356,7 +374,7 @@ export const buildAgentJson = toAntigravityJson;
356
374
  // Valid fields: agent-type, display-name, when-to-use, model, allowed-tools
357
375
  // ─────────────────────────────────────────────────────────────────────────────
358
376
 
359
- export function toCodexMd(ag: AgentDefinition, baseKnowledgeDir?: string): string {
377
+ export function toCodexMd(ag: AgentDefinition, baseKnowledgeDir?: string, paths?: Record<string, string>): string {
360
378
  const model = resolveModel(ag.capability, "codex-cli");
361
379
  const tools = [...new Set(ag.tools.map((t: string) => {
362
380
  if (["read_file","view_file","list_dir","grep_search","get_memory_insights","read_project_memory","get_project_map","get_project_gaps","get_framework_status"].includes(t)) return "read";
@@ -375,7 +393,7 @@ export function toCodexMd(ag: AgentDefinition, baseKnowledgeDir?: string): strin
375
393
  "---",
376
394
  ].join("\n");
377
395
 
378
- const body = buildSystemPrompt(ag, baseKnowledgeDir, true);
396
+ const body = buildSystemPrompt(ag, baseKnowledgeDir, true, paths);
379
397
 
380
398
  const metaFooter = [
381
399
  "",
@@ -393,7 +411,7 @@ export function toCodexMd(ag: AgentDefinition, baseKnowledgeDir?: string): strin
393
411
  // Ref: https://docs.cursor.com/context/rules
394
412
  // ─────────────────────────────────────────────────────────────────────────────
395
413
 
396
- export function toCursorMdc(ag: AgentDefinition, baseKnowledgeDir?: string): string {
414
+ export function toCursorMdc(ag: AgentDefinition, baseKnowledgeDir?: string, paths?: Record<string, string>): string {
397
415
  const glob = CURSOR_AGENT_GLOBS[ag.name] || "**/*";
398
416
  // Only officially supported Cursor MDC frontmatter fields
399
417
  const frontmatter = [
@@ -404,7 +422,7 @@ export function toCursorMdc(ag: AgentDefinition, baseKnowledgeDir?: string): str
404
422
  "---",
405
423
  ].join("\n");
406
424
 
407
- return `${frontmatter}\n\n${buildSystemPrompt(ag, baseKnowledgeDir)}`;
425
+ return `${frontmatter}\n\n${buildSystemPrompt(ag, baseKnowledgeDir, false, paths)}`;
408
426
  }
409
427
 
410
428
  // ─────────────────────────────────────────────────────────────────────────────
@@ -418,19 +436,19 @@ export interface ExportedFile {
418
436
  content: string;
419
437
  }
420
438
 
421
- export function exportAllAgents(target: ExportTarget): ExportedFile[] {
439
+ export function exportAllAgents(target: ExportTarget, paths?: Record<string, string>): ExportedFile[] {
422
440
  return ALL_AGENTS.map(ag => {
423
441
  switch (target) {
424
442
  case "claude-code":
425
- return { path: `.claude/agents/${ag.name}.md`, content: toClaudeCodeMd(ag) };
443
+ return { path: `.claude/agents/${ag.name}.md`, content: toClaudeCodeMd(ag, undefined, paths) };
426
444
  case "gemini-cli":
427
- return { path: `.gemini/agents/${ag.name}.md`, content: toGeminiCliMd(ag) };
445
+ return { path: `.gemini/agents/${ag.name}.md`, content: toGeminiCliMd(ag, undefined, paths) };
428
446
  case "antigravity":
429
- return { path: `.agents/${ag.name}/agent.json`, content: toAntigravityJson(ag) };
447
+ return { path: `.agents/${ag.name}/agent.json`, content: toAntigravityJson(ag, undefined, paths) };
430
448
  case "codex-cli":
431
- return { path: `.agents/${ag.name}.md`, content: toCodexMd(ag) };
449
+ return { path: `.agents/${ag.name}.md`, content: toCodexMd(ag, undefined, paths) };
432
450
  case "cursor":
433
- return { path: `.cursor/rules/${ag.name}.mdc`, content: toCursorMdc(ag) };
451
+ return { path: `.cursor/rules/${ag.name}.mdc`, content: toCursorMdc(ag, undefined, paths) };
434
452
  }
435
453
  });
436
454
  }
@@ -39,6 +39,6 @@ export const analyst: AgentDefinition = {
39
39
  "VERSIONING INTEGRITY: Validate that all API versioning changes are correctly registered in 'contract.version.json'.",
40
40
  "LIVE AUDIT: Continuously audit business rules against the live implementation for drift.",
41
41
  ],
42
- knowledgeFiles: ["architecture-standards.md", "crud-governance.md"],
42
+ knowledgeFiles: ["architecture-standards.md", "crud-governance.md", "governance-standards.md", "quality-standards.md"],
43
43
  },
44
44
  };
@@ -42,6 +42,6 @@ export const architect: AgentDefinition = {
42
42
  "CONTRACT STABILITY: Validate 'contract.version.json' consistency before and after every schema change.",
43
43
  "GOVERNANCE READ: Always read architecture governance docs before making design decisions.",
44
44
  ],
45
- knowledgeFiles: ["architecture-standards.md"],
45
+ knowledgeFiles: ["architecture-standards.md", "governance-standards.md", "performance-standards.md"],
46
46
  },
47
47
  };
@@ -43,6 +43,6 @@ export const backend: AgentDefinition = {
43
43
  "HIGH-RISK OPS: Refuse User/Role management, bulk deletes, schema alterations, and billing changes autonomously. " +
44
44
  "Return a standard refusal, send a managerApproval request to @manager, and shift to WAITING status.",
45
45
  ],
46
- knowledgeFiles: ["crud-governance.md", "kysely-standards.md", "typeorm-standards.md"],
46
+ knowledgeFiles: ["crud-governance.md", "kysely-standards.md", "typeorm-standards.md", "auth-standards.md", "swagger-standards.md", "pino-standards.md"],
47
47
  },
48
48
  };
@@ -38,6 +38,6 @@ export const database: AgentDefinition = {
38
38
  "DETERMINISTIC MIGRATIONS: Every migration must be reversible and produce identical results across environments.",
39
39
  "PERFORMANCE FIRST: Design indexes proactively — never retroactively after a performance incident.",
40
40
  ],
41
- knowledgeFiles: ["kysely-standards.md", "typeorm-standards.md", "quality-standards.md"],
41
+ knowledgeFiles: ["kysely-standards.md", "typeorm-standards.md", "quality-standards.md", "performance-standards.md"],
42
42
  },
43
43
  };
@@ -39,6 +39,6 @@ export const devops: AgentDefinition = {
39
39
  "ENVIRONMENT ISOLATION: All variables managed via '.env' — hardcoded secrets trigger immediate escalation.",
40
40
  "NO UNTRACKED DEPLOYMENTS: Every deployment must be declared, versioned, and traceable.",
41
41
  ],
42
- knowledgeFiles: ["deployment-standards.md"],
42
+ knowledgeFiles: ["deployment-standards.md", "github-actions-standards.md", "observability-standards.md", "logging-and-secrets.md"],
43
43
  },
44
44
  };
@@ -36,6 +36,6 @@ export const explorer: AgentDefinition = {
36
36
  "DEPENDENCY MAP: Map all file dependencies and surface them to @manager in a structured report.",
37
37
  "RECON FIRST: No specialist should act on an unexplored codebase — flag absence of ADP as a phase blocker.",
38
38
  ],
39
- knowledgeFiles: ["architecture-standards.md"],
39
+ knowledgeFiles: ["architecture-standards.md", "observability-standards.md"],
40
40
  },
41
41
  };
@@ -43,6 +43,6 @@ export const frontend: AgentDefinition = {
43
43
  "OVERFLOW GUARD: Prevent horizontal scroll via proper box-sizing, max-width bounds, and container margins.",
44
44
  "ATOMIC UI: Create shared components exclusively in 'apps/web/src/components/ui/'.",
45
45
  ],
46
- knowledgeFiles: ["frontend-standards.md", "i18n-standards.md"],
46
+ knowledgeFiles: ["frontend-standards.md", "i18n-standards.md", "react-query-standards.md", "react-router-standards.md", "tailwind-standards.md", "performance-standards.md"],
47
47
  },
48
48
  };
@@ -36,6 +36,6 @@ export const git: AgentDefinition = {
36
36
  "NO FORCE PUSH: Force-pushing to any shared branch is unconditionally forbidden.",
37
37
  "GIT FLOW: Strictly follow git-flow branching conventions — feature, hotfix, release naming enforced.",
38
38
  ],
39
- knowledgeFiles: ["logging-and-secrets.md"],
39
+ knowledgeFiles: ["logging-and-secrets.md", "governance-standards.md"],
40
40
  },
41
41
  };
@@ -30,7 +30,6 @@ export const manager: AgentDefinition = {
30
30
  "get_framework_status",
31
31
  "get_system_health",
32
32
  "check_active_ports",
33
- "start_dashboard",
34
33
  ],
35
34
  instructions: {
36
35
  identity: "AL Management Assistant and Supreme Discipline Enforcer",
@@ -54,6 +53,6 @@ export const manager: AgentDefinition = {
54
53
  "MEMORY INTEGRITY: Synchronize 'PROJECT_MEMORY.md' after every single turn. Memory drift is treason.",
55
54
  "LOCKING PROTOCOL: Always acquire a lock via 'acquire_lock' on 'memory' resource before writing to PROJECT_MEMORY.md. Release immediately after write.",
56
55
  ],
57
- knowledgeFiles: ["governance-standards.md"],
56
+ knowledgeFiles: ["governance-standards.md", "llm-governance.md", "crud-governance.md"],
58
57
  },
59
58
  };
@@ -39,6 +39,6 @@ export const mobile: AgentDefinition = {
39
39
  "TOUCH TARGETS: All touchable components must have a minimum interactive area of 44dp × 44dp.",
40
40
  "OFFLINE FIRST: Implement caching via React Query and local storage for all critical data paths.",
41
41
  ],
42
- knowledgeFiles: ["mobile-standards.md"],
42
+ knowledgeFiles: ["mobile-standards.md", "performance-standards.md", "react-query-standards.md"],
43
43
  },
44
44
  };
@@ -41,6 +41,6 @@ export const quality: AgentDefinition = {
41
41
  "ZERO TOLERANCE: Reject any code containing lint errors, 'any' type usage, or hardcoded 'console.log'.",
42
42
  "TEST PATTERN: Enforce Given-When-Then pattern in all test suites without exception.",
43
43
  ],
44
- knowledgeFiles: ["quality-standards.md", "testing-standards.md"],
44
+ knowledgeFiles: ["quality-standards.md", "testing-standards.md", "vitest-standards.md", "playwright-standards.md"],
45
45
  },
46
46
  };
@@ -37,6 +37,6 @@ export const security: AgentDefinition = {
37
37
  "RAW SQL FORBIDDEN: Reject any query that bypasses Kysely — zero exceptions.",
38
38
  "AUDIT LOGS: Monitor and log all high-risk administrative actions via 'log_agent_action'.",
39
39
  ],
40
- knowledgeFiles: ["security-standards.md"],
40
+ knowledgeFiles: ["security-standards.md", "security-audit-standards.md", "auth-standards.md", "logging-and-secrets.md"],
41
41
  },
42
42
  };