@clawmasons/mason 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/dist/acp/bridge.d.ts +92 -0
  2. package/dist/acp/bridge.d.ts.map +1 -0
  3. package/dist/acp/bridge.js +266 -0
  4. package/dist/acp/bridge.js.map +1 -0
  5. package/dist/acp/logger.d.ts +18 -0
  6. package/dist/acp/logger.d.ts.map +1 -0
  7. package/dist/acp/logger.js +35 -0
  8. package/dist/acp/logger.js.map +1 -0
  9. package/dist/acp/matcher.d.ts +60 -0
  10. package/dist/acp/matcher.d.ts.map +1 -0
  11. package/dist/acp/matcher.js +101 -0
  12. package/dist/acp/matcher.js.map +1 -0
  13. package/dist/acp/rewriter.d.ts +35 -0
  14. package/dist/acp/rewriter.d.ts.map +1 -0
  15. package/dist/acp/rewriter.js +46 -0
  16. package/dist/acp/rewriter.js.map +1 -0
  17. package/dist/acp/session.d.ts +202 -0
  18. package/dist/acp/session.d.ts.map +1 -0
  19. package/dist/acp/session.js +444 -0
  20. package/dist/acp/session.js.map +1 -0
  21. package/dist/acp/warnings.d.ts +24 -0
  22. package/dist/acp/warnings.d.ts.map +1 -0
  23. package/dist/acp/warnings.js +32 -0
  24. package/dist/acp/warnings.js.map +1 -0
  25. package/dist/cli/bin.d.ts +3 -0
  26. package/dist/cli/bin.d.ts.map +1 -0
  27. package/dist/cli/bin.js +4 -0
  28. package/dist/cli/bin.js.map +1 -0
  29. package/dist/cli/commands/build.d.ts +22 -0
  30. package/dist/cli/commands/build.d.ts.map +1 -0
  31. package/dist/cli/commands/build.js +107 -0
  32. package/dist/cli/commands/build.js.map +1 -0
  33. package/dist/cli/commands/docker-utils.d.ts +16 -0
  34. package/dist/cli/commands/docker-utils.d.ts.map +1 -0
  35. package/dist/cli/commands/docker-utils.js +54 -0
  36. package/dist/cli/commands/docker-utils.js.map +1 -0
  37. package/dist/cli/commands/index.d.ts +11 -0
  38. package/dist/cli/commands/index.d.ts.map +1 -0
  39. package/dist/cli/commands/index.js +89 -0
  40. package/dist/cli/commands/index.js.map +1 -0
  41. package/dist/cli/commands/list.d.ts +8 -0
  42. package/dist/cli/commands/list.d.ts.map +1 -0
  43. package/dist/cli/commands/list.js +60 -0
  44. package/dist/cli/commands/list.js.map +1 -0
  45. package/dist/cli/commands/package.d.ts +14 -0
  46. package/dist/cli/commands/package.d.ts.map +1 -0
  47. package/dist/cli/commands/package.js +252 -0
  48. package/dist/cli/commands/package.js.map +1 -0
  49. package/dist/cli/commands/permissions.d.ts +8 -0
  50. package/dist/cli/commands/permissions.d.ts.map +1 -0
  51. package/dist/cli/commands/permissions.js +60 -0
  52. package/dist/cli/commands/permissions.js.map +1 -0
  53. package/dist/cli/commands/proxy.d.ts +12 -0
  54. package/dist/cli/commands/proxy.d.ts.map +1 -0
  55. package/dist/cli/commands/proxy.js +253 -0
  56. package/dist/cli/commands/proxy.js.map +1 -0
  57. package/dist/cli/commands/run-agent.d.ts +171 -0
  58. package/dist/cli/commands/run-agent.d.ts.map +1 -0
  59. package/dist/cli/commands/run-agent.js +1180 -0
  60. package/dist/cli/commands/run-agent.js.map +1 -0
  61. package/dist/cli/commands/validate.d.ts +10 -0
  62. package/dist/cli/commands/validate.d.ts.map +1 -0
  63. package/dist/cli/commands/validate.js +138 -0
  64. package/dist/cli/commands/validate.js.map +1 -0
  65. package/dist/cli/index.d.ts +5 -0
  66. package/dist/cli/index.d.ts.map +1 -0
  67. package/dist/cli/index.js +18 -0
  68. package/dist/cli/index.js.map +1 -0
  69. package/dist/cli/proxy-entry.d.ts +8 -0
  70. package/dist/cli/proxy-entry.d.ts.map +1 -0
  71. package/dist/cli/proxy-entry.js +25 -0
  72. package/dist/cli/proxy-entry.js.map +1 -0
  73. package/dist/generator/agent-dockerfile.d.ts +38 -0
  74. package/dist/generator/agent-dockerfile.d.ts.map +1 -0
  75. package/dist/generator/agent-dockerfile.js +129 -0
  76. package/dist/generator/agent-dockerfile.js.map +1 -0
  77. package/dist/generator/credential-service-dockerfile.d.ts +14 -0
  78. package/dist/generator/credential-service-dockerfile.d.ts.map +1 -0
  79. package/dist/generator/credential-service-dockerfile.js +44 -0
  80. package/dist/generator/credential-service-dockerfile.js.map +1 -0
  81. package/dist/generator/index.d.ts +6 -0
  82. package/dist/generator/index.d.ts.map +1 -0
  83. package/dist/generator/index.js +6 -0
  84. package/dist/generator/index.js.map +1 -0
  85. package/dist/generator/mount-volumes.d.ts +30 -0
  86. package/dist/generator/mount-volumes.d.ts.map +1 -0
  87. package/dist/generator/mount-volumes.js +39 -0
  88. package/dist/generator/mount-volumes.js.map +1 -0
  89. package/dist/generator/proxy-dockerfile.d.ts +19 -0
  90. package/dist/generator/proxy-dockerfile.d.ts.map +1 -0
  91. package/dist/generator/proxy-dockerfile.js +59 -0
  92. package/dist/generator/proxy-dockerfile.js.map +1 -0
  93. package/dist/index.d.ts +8 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +8 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/materializer/common.d.ts +17 -0
  98. package/dist/materializer/common.d.ts.map +1 -0
  99. package/dist/materializer/common.js +37 -0
  100. package/dist/materializer/common.js.map +1 -0
  101. package/dist/materializer/docker-generator.d.ts +258 -0
  102. package/dist/materializer/docker-generator.d.ts.map +1 -0
  103. package/dist/materializer/docker-generator.js +529 -0
  104. package/dist/materializer/docker-generator.js.map +1 -0
  105. package/dist/materializer/index.d.ts +9 -0
  106. package/dist/materializer/index.d.ts.map +1 -0
  107. package/dist/materializer/index.js +7 -0
  108. package/dist/materializer/index.js.map +1 -0
  109. package/dist/materializer/proxy-dependencies.d.ts +43 -0
  110. package/dist/materializer/proxy-dependencies.d.ts.map +1 -0
  111. package/dist/materializer/proxy-dependencies.js +452 -0
  112. package/dist/materializer/proxy-dependencies.js.map +1 -0
  113. package/dist/materializer/role-materializer.d.ts +56 -0
  114. package/dist/materializer/role-materializer.d.ts.map +1 -0
  115. package/dist/materializer/role-materializer.js +119 -0
  116. package/dist/materializer/role-materializer.js.map +1 -0
  117. package/dist/materializer/types.d.ts +2 -0
  118. package/dist/materializer/types.d.ts.map +1 -0
  119. package/dist/materializer/types.js +2 -0
  120. package/dist/materializer/types.js.map +1 -0
  121. package/dist/proxy-bundle.cjs +17 -4
  122. package/dist/proxy-bundle.cjs.map +4 -4
  123. package/dist/resolver/discover.d.ts +7 -0
  124. package/dist/resolver/discover.d.ts.map +1 -0
  125. package/dist/resolver/discover.js +102 -0
  126. package/dist/resolver/discover.js.map +1 -0
  127. package/dist/resolver/errors.d.ts +35 -0
  128. package/dist/resolver/errors.d.ts.map +1 -0
  129. package/dist/resolver/errors.js +62 -0
  130. package/dist/resolver/errors.js.map +1 -0
  131. package/dist/resolver/index.d.ts +5 -0
  132. package/dist/resolver/index.d.ts.map +1 -0
  133. package/dist/resolver/index.js +4 -0
  134. package/dist/resolver/index.js.map +1 -0
  135. package/dist/resolver/resolve.d.ts +8 -0
  136. package/dist/resolver/resolve.d.ts.map +1 -0
  137. package/dist/resolver/resolve.js +177 -0
  138. package/dist/resolver/resolve.js.map +1 -0
  139. package/dist/runtime/gitignore.d.ts +16 -0
  140. package/dist/runtime/gitignore.d.ts.map +1 -0
  141. package/dist/runtime/gitignore.js +37 -0
  142. package/dist/runtime/gitignore.js.map +1 -0
  143. package/dist/validator/index.d.ts +3 -0
  144. package/dist/validator/index.d.ts.map +1 -0
  145. package/dist/validator/index.js +2 -0
  146. package/dist/validator/index.js.map +1 -0
  147. package/dist/validator/types.d.ts +48 -0
  148. package/dist/validator/types.d.ts.map +1 -0
  149. package/dist/validator/types.js +2 -0
  150. package/dist/validator/types.js.map +1 -0
  151. package/dist/validator/validate.d.ts +8 -0
  152. package/dist/validator/validate.d.ts.map +1 -0
  153. package/dist/validator/validate.js +217 -0
  154. package/dist/validator/validate.js.map +1 -0
  155. package/package.json +10 -9
@@ -0,0 +1,444 @@
1
+ /**
2
+ * ACP Session — Docker Session Orchestration for ACP
3
+ *
4
+ * Manages Docker Compose sessions for ACP mode. All services (proxy,
5
+ * agent) live in a single compose file so they share a Docker network.
6
+ * The credential service runs in-process on the host. The lifecycle is:
7
+ *
8
+ * 1. `startInfrastructure()` — `docker compose up -d` proxy
9
+ * 2. `startAgentProcess(cwd)` — `docker compose run` (foreground, piped stdio)
10
+ * or `startAgent(cwd)` — `docker compose run -d` (legacy detached mode)
11
+ * 3. `stopAgent()` — stops/kills the agent container
12
+ * 4. `stop()` — `docker compose down` everything
13
+ *
14
+ * PRD refs: REQ-005 (Docker Session Lifecycle, ACP Session CWD Support)
15
+ */
16
+ import * as crypto from "node:crypto";
17
+ import * as child_process from "node:child_process";
18
+ import * as fs from "node:fs";
19
+ import * as path from "node:path";
20
+ import { checkDockerCompose } from "../cli/commands/docker-utils.js";
21
+ import { resolveRoleMountVolumes } from "../generator/mount-volumes.js";
22
+ // ── Local Utilities ──────────────────────────────────────────────────
23
+ /**
24
+ * Generate a short random session identifier.
25
+ */
26
+ function generateSessionId() {
27
+ return crypto.randomBytes(4).toString("hex");
28
+ }
29
+ /**
30
+ * Execute a `docker compose` command against a compose file.
31
+ * Returns the exit code (0 = success).
32
+ */
33
+ function execComposeCommand(composeFile, args, opts) {
34
+ const baseArgs = ["compose", "-f", composeFile, ...args];
35
+ const stdio = opts?.interactive ? "inherit" : "ignore";
36
+ return new Promise((resolve) => {
37
+ const child = child_process.spawn("docker", baseArgs, { stdio });
38
+ child.on("close", (code) => resolve(code ?? 0));
39
+ child.on("error", () => resolve(1));
40
+ });
41
+ }
42
+ // ── Constants ────────────────────────────────────────────────────────
43
+ const PROJECT_MOUNT_PATH = "/home/mason/workspace/project";
44
+ // ── Compose Generation ────────────────────────────────────────────────
45
+ /**
46
+ * Generate a docker-compose.yml with proxy and agent services.
47
+ * The credential service runs in-process on the host, not in Docker.
48
+ *
49
+ * The agent service is defined with `profiles: ["agent"]` so that
50
+ * `docker compose up -d` only starts the proxy.
51
+ * The agent is started later via `docker compose run`.
52
+ *
53
+ * Docker build layout (project-local):
54
+ * .mason/docker/ ← dockerDir (shared, has node_modules)
55
+ * {role-name}/ ← dockerBuildDir
56
+ * mcp-proxy/Dockerfile
57
+ * {agent-type}/Dockerfile
58
+ */
59
+ export function generateAcpComposeYml(opts) {
60
+ const { dockerBuildDir, dockerDir, projectDir, agent, role, logsDir, proxyToken, credentialProxyToken, proxyPort, acpClient, acpCommand, roleMounts, credentialKeys, } = opts;
61
+ // Proxy: context is the shared dockerDir (has node_modules),
62
+ // dockerfile is the role-specific mcp-proxy/Dockerfile.
63
+ const proxyDockerfile = path.relative(dockerDir, path.join(dockerBuildDir, "mcp-proxy", "Dockerfile"));
64
+ // Agent: context is the shared dockerDir (has node_modules),
65
+ // dockerfile is the role-specific {agent-type}/Dockerfile.
66
+ const agentDockerfile = path.relative(dockerDir, path.join(dockerBuildDir, agent, "Dockerfile"));
67
+ const proxyServiceName = `proxy-${role}`;
68
+ const agentServiceName = `agent-${role}`;
69
+ // Build proxy environment lines (include ACP metadata)
70
+ const proxyEnvLines = [
71
+ ` - CHAPTER_PROXY_TOKEN=${proxyToken}`,
72
+ ` - CREDENTIAL_PROXY_TOKEN=${credentialProxyToken}`,
73
+ ` - CHAPTER_SESSION_TYPE=acp`,
74
+ ` - PROJECT_DIR=${PROJECT_MOUNT_PATH}`,
75
+ ];
76
+ if (acpClient) {
77
+ proxyEnvLines.push(` - CHAPTER_ACP_CLIENT=${acpClient}`);
78
+ }
79
+ if (credentialKeys && credentialKeys.length > 0) {
80
+ proxyEnvLines.push(` - CHAPTER_DECLARED_CREDENTIALS=${JSON.stringify(credentialKeys)}`);
81
+ }
82
+ // Build proxy ports (expose to host for in-process credential service WSClient)
83
+ const proxyPortsSection = proxyPort
84
+ ? `\n ports:\n - "${proxyPort}:9090"`
85
+ : "";
86
+ // Build agent environment lines
87
+ const agentEnvLines = [
88
+ ` - MCP_PROXY_TOKEN=${proxyToken}`,
89
+ ` - MCP_PROXY_URL=http://${proxyServiceName}:9090`,
90
+ ];
91
+ if (credentialKeys && credentialKeys.length > 0) {
92
+ agentEnvLines.push(` - AGENT_CREDENTIALS=${JSON.stringify(credentialKeys)}`);
93
+ }
94
+ // Build agent volume lines
95
+ const agentVolumeLines = [];
96
+ // Workspace mount — provides agent-launch.json at /home/mason/workspace/agent-launch.json
97
+ const workspacePath = path.join(dockerBuildDir, agent, "workspace");
98
+ agentVolumeLines.push(` - "${workspacePath}:/home/mason/workspace"`);
99
+ // Per-file overlay mounts — inject config files into /home/mason/workspace/project/
100
+ const buildWorkspaceProjectDir = path.join(dockerBuildDir, agent, "build", "workspace", "project");
101
+ if (fs.existsSync(buildWorkspaceProjectDir)) {
102
+ for (const entry of fs.readdirSync(buildWorkspaceProjectDir)) {
103
+ agentVolumeLines.push(` - "${path.join(buildWorkspaceProjectDir, entry)}:/home/mason/workspace/project/${entry}"`);
104
+ }
105
+ }
106
+ for (const vol of resolveRoleMountVolumes(roleMounts)) {
107
+ agentVolumeLines.push(` - "${vol}"`);
108
+ }
109
+ const agentVolumesSection = agentVolumeLines.length > 0
110
+ ? `\n volumes:\n${agentVolumeLines.join("\n")}`
111
+ : "";
112
+ // Build command line (overrides Dockerfile CMD / appends to ENTRYPOINT)
113
+ const commandLine = acpCommand
114
+ ? `\n command: ${JSON.stringify(acpCommand)}`
115
+ : "";
116
+ // Build proxy volume lines
117
+ const cacheDir = path.join(dockerBuildDir, "mcp-proxy", ".cache");
118
+ const proxyVolumeLines = [` - "${logsDir}:/logs"`];
119
+ if (projectDir) {
120
+ proxyVolumeLines.push(` - "${projectDir}:${PROJECT_MOUNT_PATH}"`);
121
+ }
122
+ proxyVolumeLines.push(` - "${cacheDir}:/app/.cache"`);
123
+ // Unique compose project name derived from project or build directory
124
+ const nameSource = projectDir ?? dockerBuildDir;
125
+ const projectHash = crypto.createHash("sha256").update(nameSource).digest("hex").slice(0, 8);
126
+ const composeName = `mason-${projectHash}`;
127
+ return `# Generated by chapter acp-session
128
+ name: ${composeName}
129
+ services:
130
+ ${proxyServiceName}:
131
+ build:
132
+ context: "${dockerDir}"
133
+ dockerfile: "${proxyDockerfile}"
134
+ volumes:
135
+ ${proxyVolumeLines.join("\n")}
136
+ environment:
137
+ ${proxyEnvLines.join("\n")}${proxyPortsSection}
138
+ restart: "no"
139
+
140
+ ${agentServiceName}:
141
+ build:
142
+ context: "${dockerDir}"
143
+ dockerfile: "${agentDockerfile}"${agentVolumesSection}
144
+ depends_on:
145
+ - ${proxyServiceName}
146
+ environment:
147
+ ${agentEnvLines.join("\n")}${commandLine}
148
+ init: true
149
+ restart: "no"
150
+ profiles:
151
+ - agent
152
+ `;
153
+ }
154
+ // ── AcpSession ────────────────────────────────────────────────────────
155
+ export class AcpSession {
156
+ config;
157
+ deps;
158
+ running = false;
159
+ sessionInfo = null;
160
+ // Split lifecycle state
161
+ infraInfo = null;
162
+ infraRunning = false;
163
+ agentInfo = null;
164
+ agentRunning = false;
165
+ agentChild = null;
166
+ constructor(config, deps) {
167
+ this.config = config;
168
+ const noopLogger = { log() { }, error() { }, close() { } };
169
+ this.deps = {
170
+ execComposeFn: deps?.execComposeFn ?? execComposeCommand,
171
+ generateSessionIdFn: deps?.generateSessionIdFn ?? generateSessionId,
172
+ checkDockerComposeFn: deps?.checkDockerComposeFn ?? checkDockerCompose,
173
+ spawnFn: deps?.spawnFn ?? child_process.spawn,
174
+ logger: deps?.logger ?? noopLogger,
175
+ };
176
+ }
177
+ /**
178
+ * Start the ACP Docker session (legacy all-at-once mode).
179
+ * Starts all services including the agent in a single compose up.
180
+ */
181
+ async start() {
182
+ if (this.running) {
183
+ throw new Error("ACP session is already running");
184
+ }
185
+ const { projectDir, agent, role, dockerBuildDir, dockerDir } = this.config;
186
+ // Pre-flight checks
187
+ this.deps.checkDockerComposeFn();
188
+ // Generate session directory
189
+ const sessionId = this.deps.generateSessionIdFn();
190
+ const sessionDir = path.join(projectDir, ".mason", "sessions", sessionId, "docker");
191
+ fs.mkdirSync(sessionDir, { recursive: true });
192
+ const logsDir = path.join(sessionDir, "logs");
193
+ fs.mkdirSync(logsDir, { recursive: true });
194
+ // Generate tokens
195
+ const proxyToken = crypto.randomBytes(32).toString("hex");
196
+ const credentialProxyToken = crypto.randomBytes(32).toString("hex");
197
+ // Generate compose file
198
+ const composeContent = generateAcpComposeYml({
199
+ dockerBuildDir,
200
+ dockerDir,
201
+ projectDir,
202
+ agent,
203
+ role,
204
+ logsDir,
205
+ proxyToken,
206
+ credentialProxyToken,
207
+ proxyPort: this.config.proxyPort,
208
+ acpClient: this.config.acpClient,
209
+ acpCommand: this.config.acpCommand,
210
+ credentialKeys: this.config.credentialKeys,
211
+ });
212
+ const composeFile = path.join(sessionDir, "docker-compose.yml");
213
+ fs.writeFileSync(composeFile, composeContent);
214
+ // Start all services including agent profile
215
+ const exitCode = await this.deps.execComposeFn(composeFile, ["--profile", "agent", "up", "-d"]);
216
+ if (exitCode !== 0) {
217
+ throw new Error(`Failed to start ACP session (docker compose exit code ${exitCode})`);
218
+ }
219
+ const proxyServiceName = `proxy-${role}`;
220
+ const agentServiceName = `agent-${role}`;
221
+ this.sessionInfo = {
222
+ sessionId,
223
+ sessionDir,
224
+ composeFile,
225
+ proxyServiceName,
226
+ agentServiceName,
227
+ };
228
+ this.running = true;
229
+ return this.sessionInfo;
230
+ }
231
+ /**
232
+ * Start infrastructure services only (proxy).
233
+ * These are long-lived and shared across agent sessions.
234
+ * The agent service is in the same compose file but behind a profile,
235
+ * so `up -d` skips it.
236
+ */
237
+ async startInfrastructure() {
238
+ if (this.infraRunning) {
239
+ throw new Error("Infrastructure is already running");
240
+ }
241
+ const { projectDir, agent, role, dockerBuildDir, dockerDir } = this.config;
242
+ // Pre-flight checks
243
+ this.deps.checkDockerComposeFn();
244
+ // Generate session directory
245
+ const sessionId = this.deps.generateSessionIdFn();
246
+ const sessionDir = path.join(projectDir, ".mason", "sessions", sessionId, "docker");
247
+ fs.mkdirSync(sessionDir, { recursive: true });
248
+ const logsDir = path.join(sessionDir, "logs");
249
+ fs.mkdirSync(logsDir, { recursive: true });
250
+ // Generate tokens
251
+ const proxyToken = crypto.randomBytes(32).toString("hex");
252
+ const credentialProxyToken = crypto.randomBytes(32).toString("hex");
253
+ // Generate single compose file with all services
254
+ const composeContent = generateAcpComposeYml({
255
+ dockerBuildDir,
256
+ dockerDir,
257
+ projectDir,
258
+ agent,
259
+ role,
260
+ logsDir,
261
+ proxyToken,
262
+ credentialProxyToken,
263
+ proxyPort: this.config.proxyPort,
264
+ acpClient: this.config.acpClient,
265
+ acpCommand: this.config.acpCommand,
266
+ credentialKeys: this.config.credentialKeys,
267
+ });
268
+ const composeFile = path.join(sessionDir, "docker-compose.yml");
269
+ fs.writeFileSync(composeFile, composeContent);
270
+ // Start only infra services (agent is behind "agent" profile, skipped)
271
+ this.deps.logger.log(`[session] docker compose -f ${composeFile} up -d`);
272
+ const exitCode = await this.deps.execComposeFn(composeFile, ["up", "-d"]);
273
+ this.deps.logger.log(`[session] docker compose up exit code: ${exitCode}`);
274
+ if (exitCode !== 0) {
275
+ throw new Error(`Failed to start infrastructure (docker compose exit code ${exitCode})`);
276
+ }
277
+ const proxyServiceName = `proxy-${role}`;
278
+ const agentServiceName = `agent-${role}`;
279
+ this.infraInfo = {
280
+ sessionId,
281
+ sessionDir,
282
+ composeFile,
283
+ proxyServiceName,
284
+ agentServiceName,
285
+ proxyToken,
286
+ credentialProxyToken,
287
+ dockerBuildDir,
288
+ };
289
+ this.infraRunning = true;
290
+ return this.infraInfo;
291
+ }
292
+ /**
293
+ * Start an agent container for a specific project directory.
294
+ * Uses `docker compose run -d` on the agent service from the
295
+ * same compose file, so it shares the network with infra.
296
+ *
297
+ * @param projectDir The project directory to mount into the container.
298
+ */
299
+ async startAgent(projectDir) {
300
+ if (!this.infraRunning || !this.infraInfo) {
301
+ throw new Error("Infrastructure must be running before starting an agent. Call startInfrastructure() first.");
302
+ }
303
+ if (this.agentRunning) {
304
+ throw new Error("Agent is already running. Call stopAgent() first.");
305
+ }
306
+ const agentServiceName = this.infraInfo.agentServiceName;
307
+ // Use docker compose run with a volume override for this session's CWD
308
+ const runArgs = ["run", "-d", "--rm", "--build", "-v", `${projectDir}:${PROJECT_MOUNT_PATH}`, agentServiceName];
309
+ this.deps.logger.log(`[session] docker compose -f ${this.infraInfo.composeFile} ${runArgs.join(" ")}`);
310
+ const exitCode = await this.deps.execComposeFn(this.infraInfo.composeFile, runArgs);
311
+ this.deps.logger.log(`[session] docker compose run exit code: ${exitCode}`);
312
+ if (exitCode !== 0) {
313
+ throw new Error(`Failed to start agent (docker compose exit code ${exitCode})`);
314
+ }
315
+ this.agentInfo = {
316
+ sessionId: this.infraInfo.sessionId,
317
+ sessionDir: this.infraInfo.sessionDir,
318
+ composeFile: this.infraInfo.composeFile,
319
+ agentServiceName,
320
+ projectDir,
321
+ };
322
+ this.agentRunning = true;
323
+ return this.agentInfo;
324
+ }
325
+ /**
326
+ * Start an agent container as a foreground child process with piped stdio.
327
+ *
328
+ * Unlike `startAgent()` (which uses `docker compose run -d`), this method
329
+ * spawns `docker compose run` without `-d` so the child process's
330
+ * stdin/stdout can be wrapped with `ndJsonStream()` for direct ACP
331
+ * communication. No port mapping or container ID discovery is needed.
332
+ *
333
+ * @param projectDir The project directory to mount into the container.
334
+ * @returns The spawned child process and agent session info.
335
+ */
336
+ async startAgentProcess(projectDir) {
337
+ if (!this.infraRunning || !this.infraInfo) {
338
+ throw new Error("Infrastructure must be running before starting an agent. Call startInfrastructure() first.");
339
+ }
340
+ if (this.agentRunning) {
341
+ throw new Error("Agent is already running. Call stopAgent() first.");
342
+ }
343
+ const agentServiceName = this.infraInfo.agentServiceName;
344
+ // Pre-build the agent image so build output goes to the logger,
345
+ // not into the piped ndjson stream used for ACP protocol messages.
346
+ this.deps.logger.log(`[session] docker compose -f ${this.infraInfo.composeFile} build ${agentServiceName}`);
347
+ const buildExitCode = await this.deps.execComposeFn(this.infraInfo.composeFile, ["build", agentServiceName]);
348
+ if (buildExitCode !== 0) {
349
+ throw new Error(`Failed to build agent image (docker compose build exit code ${buildExitCode})`);
350
+ }
351
+ // Spawn docker compose run as a foreground process with piped stdio.
352
+ // No -d flag, no --build: the child process IS the transport.
353
+ const composeArgs = [
354
+ "compose", "-f", this.infraInfo.composeFile,
355
+ "run", "--rm",
356
+ "-v", `${projectDir}:${PROJECT_MOUNT_PATH}`,
357
+ agentServiceName,
358
+ ];
359
+ this.deps.logger.log(`[session] docker ${composeArgs.join(" ")}`);
360
+ const child = this.deps.spawnFn("docker", composeArgs, {
361
+ stdio: ["pipe", "pipe", "pipe"],
362
+ });
363
+ this.agentInfo = {
364
+ sessionId: this.infraInfo.sessionId,
365
+ sessionDir: this.infraInfo.sessionDir,
366
+ composeFile: this.infraInfo.composeFile,
367
+ agentServiceName,
368
+ projectDir,
369
+ };
370
+ this.agentChild = child;
371
+ this.agentRunning = true;
372
+ return { child, agentInfo: this.agentInfo };
373
+ }
374
+ /**
375
+ * Stop only the agent container. Infrastructure remains running.
376
+ * Idempotent — calling when agent is not running is a no-op.
377
+ *
378
+ * If a child process exists (from `startAgentProcess()`), it is killed.
379
+ * Otherwise, the agent service is stopped via compose commands.
380
+ */
381
+ async stopAgent() {
382
+ if (!this.agentRunning || !this.agentInfo) {
383
+ return;
384
+ }
385
+ // If we have a child process (from startAgentProcess), kill it
386
+ if (this.agentChild) {
387
+ this.deps.logger.log(`[session] Killing agent child process`);
388
+ this.agentChild.kill();
389
+ this.agentChild = null;
390
+ }
391
+ else {
392
+ // Legacy path: stop via compose commands (from startAgent)
393
+ this.deps.logger.log(`[session] Stopping agent service ${this.agentInfo.agentServiceName}`);
394
+ await this.deps.execComposeFn(this.agentInfo.composeFile, ["--profile", "agent", "stop", this.agentInfo.agentServiceName]);
395
+ await this.deps.execComposeFn(this.agentInfo.composeFile, ["--profile", "agent", "rm", "-f", this.agentInfo.agentServiceName]);
396
+ }
397
+ this.deps.logger.log("[session] Agent stopped and removed");
398
+ this.agentRunning = false;
399
+ this.agentInfo = null;
400
+ }
401
+ /**
402
+ * Stop all services (infrastructure + agent).
403
+ * Idempotent — calling stop when not running is a no-op.
404
+ */
405
+ async stop() {
406
+ // Kill child process if one exists (from startAgentProcess)
407
+ if (this.agentChild) {
408
+ this.agentChild.kill();
409
+ this.agentChild = null;
410
+ }
411
+ // Stop infrastructure + agent via compose down
412
+ if (this.infraRunning && this.infraInfo) {
413
+ await this.deps.execComposeFn(this.infraInfo.composeFile, ["--profile", "agent", "down"]);
414
+ this.infraRunning = false;
415
+ this.infraInfo = null;
416
+ this.agentRunning = false;
417
+ this.agentInfo = null;
418
+ }
419
+ // Stop legacy session
420
+ if (this.running && this.sessionInfo) {
421
+ await this.deps.execComposeFn(this.sessionInfo.composeFile, ["--profile", "agent", "down"]);
422
+ this.running = false;
423
+ }
424
+ }
425
+ /**
426
+ * Check if the session is currently running (legacy mode).
427
+ */
428
+ isRunning() {
429
+ return this.running;
430
+ }
431
+ /**
432
+ * Check if infrastructure is currently running.
433
+ */
434
+ isInfrastructureRunning() {
435
+ return this.infraRunning;
436
+ }
437
+ /**
438
+ * Check if an agent is currently running.
439
+ */
440
+ isAgentRunning() {
441
+ return this.agentRunning;
442
+ }
443
+ }
444
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/acp/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { UnmatchedServer } from "./matcher.js";
2
+ /**
3
+ * Format a single warning message for a dropped MCP server.
4
+ *
5
+ * Produces a multi-line string matching the PRD REQ-004 format:
6
+ * ```
7
+ * [mason run-acp-agent] WARNING: Dropping unmatched MCP server "<name>"
8
+ * -> No chapter App matches server name, command, or URL
9
+ * -> Agent will not have access to tools from this server
10
+ * -> To govern this server, create a chapter App package for it
11
+ * ```
12
+ *
13
+ * @param server - The unmatched server to format a warning for
14
+ * @returns A formatted multi-line warning string
15
+ */
16
+ export declare function formatWarning(server: UnmatchedServer): string;
17
+ /**
18
+ * Generate warning messages for all unmatched/dropped MCP servers.
19
+ *
20
+ * @param unmatched - The unmatched servers from the matcher
21
+ * @returns An array of formatted warning strings (empty if no unmatched servers)
22
+ */
23
+ export declare function generateWarnings(unmatched: UnmatchedServer[]): string[];
24
+ //# sourceMappingURL=warnings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"warnings.d.ts","sourceRoot":"","sources":["../../src/acp/warnings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAO7D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,CAEvE"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Format a single warning message for a dropped MCP server.
3
+ *
4
+ * Produces a multi-line string matching the PRD REQ-004 format:
5
+ * ```
6
+ * [mason run-acp-agent] WARNING: Dropping unmatched MCP server "<name>"
7
+ * -> No chapter App matches server name, command, or URL
8
+ * -> Agent will not have access to tools from this server
9
+ * -> To govern this server, create a chapter App package for it
10
+ * ```
11
+ *
12
+ * @param server - The unmatched server to format a warning for
13
+ * @returns A formatted multi-line warning string
14
+ */
15
+ export function formatWarning(server) {
16
+ return [
17
+ `[mason run-acp-agent] WARNING: Dropping unmatched MCP server "${server.name}"`,
18
+ ` \u2192 ${server.reason}`,
19
+ ` \u2192 Agent will not have access to tools from this server`,
20
+ ` \u2192 To govern this server, create a chapter App package for it`,
21
+ ].join("\n");
22
+ }
23
+ /**
24
+ * Generate warning messages for all unmatched/dropped MCP servers.
25
+ *
26
+ * @param unmatched - The unmatched servers from the matcher
27
+ * @returns An array of formatted warning strings (empty if no unmatched servers)
28
+ */
29
+ export function generateWarnings(unmatched) {
30
+ return unmatched.map(formatWarning);
31
+ }
32
+ //# sourceMappingURL=warnings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"warnings.js","sourceRoot":"","sources":["../../src/acp/warnings.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,MAAuB;IACnD,OAAO;QACL,iEAAiE,MAAM,CAAC,IAAI,GAAG;QAC/E,YAAY,MAAM,CAAC,MAAM,EAAE;QAC3B,+DAA+D;QAC/D,qEAAqE;KACtE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAA4B;IAC3D,OAAO,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { run } from "./index.js";
3
+ run();
4
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEjC,GAAG,EAAE,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `chapter build` command — generates project-local Docker build artifacts.
3
+ *
4
+ * Discovers roles in the current workspace, resolves their agent types,
5
+ * and generates Docker build directories at `.mason/docker/<role-name>/`.
6
+ *
7
+ * This replaces the old build pipeline that used lodge-based paths.
8
+ */
9
+ import type { Command } from "commander";
10
+ /**
11
+ * Run the build for one or all roles in the workspace.
12
+ *
13
+ * @param projectDir - Absolute path to the project root
14
+ * @param roleName - Optional role name to build (builds all if omitted)
15
+ * @param agentTypeOverride - Optional agent type override (e.g., "mcp-agent")
16
+ */
17
+ export declare function runBuild(projectDir: string, roleName?: string, agentTypeOverride?: string): Promise<void>;
18
+ /**
19
+ * Register the `build` subcommand under `chapter`.
20
+ */
21
+ export declare function registerBuildCommand(program: Command): void;
22
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/build.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqCzC;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC,CAkEf;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkB3D"}