@clawmasons/mason 0.1.1 → 0.1.2

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 (153) 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 +15 -0
  46. package/dist/cli/commands/package.d.ts.map +1 -0
  47. package/dist/cli/commands/package.js +241 -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 +149 -0
  58. package/dist/cli/commands/run-agent.d.ts.map +1 -0
  59. package/dist/cli/commands/run-agent.js +1072 -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 +120 -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/resolver/discover.d.ts +7 -0
  122. package/dist/resolver/discover.d.ts.map +1 -0
  123. package/dist/resolver/discover.js +102 -0
  124. package/dist/resolver/discover.js.map +1 -0
  125. package/dist/resolver/errors.d.ts +35 -0
  126. package/dist/resolver/errors.d.ts.map +1 -0
  127. package/dist/resolver/errors.js +62 -0
  128. package/dist/resolver/errors.js.map +1 -0
  129. package/dist/resolver/index.d.ts +5 -0
  130. package/dist/resolver/index.d.ts.map +1 -0
  131. package/dist/resolver/index.js +4 -0
  132. package/dist/resolver/index.js.map +1 -0
  133. package/dist/resolver/resolve.d.ts +8 -0
  134. package/dist/resolver/resolve.d.ts.map +1 -0
  135. package/dist/resolver/resolve.js +177 -0
  136. package/dist/resolver/resolve.js.map +1 -0
  137. package/dist/runtime/gitignore.d.ts +16 -0
  138. package/dist/runtime/gitignore.d.ts.map +1 -0
  139. package/dist/runtime/gitignore.js +37 -0
  140. package/dist/runtime/gitignore.js.map +1 -0
  141. package/dist/validator/index.d.ts +3 -0
  142. package/dist/validator/index.d.ts.map +1 -0
  143. package/dist/validator/index.js +2 -0
  144. package/dist/validator/index.js.map +1 -0
  145. package/dist/validator/types.d.ts +48 -0
  146. package/dist/validator/types.d.ts.map +1 -0
  147. package/dist/validator/types.js +2 -0
  148. package/dist/validator/types.js.map +1 -0
  149. package/dist/validator/validate.d.ts +8 -0
  150. package/dist/validator/validate.d.ts.map +1 -0
  151. package/dist/validator/validate.js +217 -0
  152. package/dist/validator/validate.js.map +1 -0
  153. package/package.json +10 -9
@@ -0,0 +1,92 @@
1
+ /**
2
+ * ACP SDK Bridge — Dual-Connection ACP Protocol Mediator
3
+ *
4
+ * The bridge presents an AgentSideConnection to the editor (via ndjson
5
+ * on provided streams) and a ClientSideConnection to the container agent
6
+ * (via docker compose run piped stdio). It handles deferred startup:
7
+ * `initialize` responds immediately with local capabilities, `session/new`
8
+ * starts the container, and subsequent messages are forwarded bidirectionally.
9
+ *
10
+ * PRD refs: REQ-SDK-002, REQ-SDK-003, REQ-SDK-004, REQ-SDK-009,
11
+ * REQ-SDK-010, REQ-SDK-013
12
+ */
13
+ import type { ChildProcess } from "node:child_process";
14
+ import type { AcpLogger } from "./logger.js";
15
+ export interface AcpSdkBridgeConfig {
16
+ /**
17
+ * Callback invoked when `session/new` arrives with a `cwd` field.
18
+ * Must start the container process and return a ChildProcess with
19
+ * piped stdin/stdout for ACP ndjson communication.
20
+ */
21
+ onSessionNew: (cwd: string) => ChildProcess | Promise<ChildProcess>;
22
+ /** Optional logger for diagnostics. */
23
+ logger?: AcpLogger;
24
+ }
25
+ export declare class AcpSdkBridge {
26
+ private readonly config;
27
+ private readonly logger?;
28
+ private editorConnection;
29
+ private containerConnection;
30
+ private childProcess;
31
+ private initializeParams;
32
+ private sessionActive;
33
+ constructor(config: AcpSdkBridgeConfig);
34
+ /**
35
+ * Start the bridge with the given editor-facing streams.
36
+ * Creates an AgentSideConnection that handles the ACP protocol
37
+ * with the editor.
38
+ */
39
+ start(editorInput: ReadableStream<Uint8Array>, editorOutput: WritableStream<Uint8Array>): void;
40
+ /**
41
+ * Promise that resolves when the editor connection closes.
42
+ */
43
+ get closed(): Promise<void>;
44
+ /**
45
+ * Stop the bridge: clean up container and editor connections.
46
+ */
47
+ stop(): Promise<void>;
48
+ private createEditorAgent;
49
+ /**
50
+ * Handle `initialize` from the editor.
51
+ * Returns capabilities locally without starting a container. (REQ-SDK-004)
52
+ */
53
+ private handleInitialize;
54
+ /**
55
+ * Handle `session/new` from the editor.
56
+ * Starts the container, creates ClientSideConnection, forwards
57
+ * initialize + session/new, returns the container's response. (REQ-SDK-004)
58
+ */
59
+ private handleNewSession;
60
+ /**
61
+ * Handle `prompt` from the editor.
62
+ * Forwards to the container and returns its response.
63
+ */
64
+ private handlePrompt;
65
+ /**
66
+ * Handle `cancel` from the editor.
67
+ * Forwards cancel notification to the container. (REQ-SDK-010)
68
+ */
69
+ private handleCancel;
70
+ /**
71
+ * Handle `authenticate` from the editor.
72
+ * Forwards to the container if connected, otherwise returns empty.
73
+ */
74
+ private handleAuthenticate;
75
+ /**
76
+ * Create a Client implementation for the ClientSideConnection.
77
+ * Forwards notifications from the container back to the editor. (REQ-SDK-010)
78
+ */
79
+ private createContainerClient;
80
+ private forwardSessionUpdate;
81
+ private forwardRequestPermission;
82
+ private forwardReadTextFile;
83
+ private forwardWriteTextFile;
84
+ private forwardCreateTerminal;
85
+ private forwardTerminalOutput;
86
+ private forwardReleaseTerminal;
87
+ private forwardWaitForTerminalExit;
88
+ private forwardKillTerminal;
89
+ private handleContainerDisconnect;
90
+ private cleanupContainer;
91
+ }
92
+ //# sourceMappingURL=bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/acp/bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAoCvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACpE,uCAAuC;IACvC,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAY;IAEpC,OAAO,CAAC,gBAAgB,CAAoC;IAC5D,OAAO,CAAC,mBAAmB,CAAqC;IAChE,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,aAAa,CAAS;gBAElB,MAAM,EAAE,kBAAkB;IAKtC;;;;OAIG;IACH,KAAK,CACH,WAAW,EAAE,cAAc,CAAC,UAAU,CAAC,EACvC,YAAY,EAAE,cAAc,CAAC,UAAU,CAAC,GACvC,IAAI;IAmBP;;OAEG;IACH,IAAI,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAK1B;IAED;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,OAAO,CAAC,iBAAiB;IAUzB;;;OAGG;YACW,gBAAgB;IAY9B;;;;OAIG;YACW,gBAAgB;IAmE9B;;;OAGG;YACW,YAAY;IAY1B;;;OAGG;YACW,YAAY;IAU1B;;;OAGG;YACW,kBAAkB;IAShC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;YAcf,oBAAoB;YAMpB,wBAAwB;YAQxB,mBAAmB;YAOnB,oBAAoB;YAOpB,qBAAqB;YASrB,qBAAqB;YAOrB,sBAAsB;YAKtB,0BAA0B;YAO1B,mBAAmB;IAOjC,OAAO,CAAC,yBAAyB;YAQnB,gBAAgB;CAW/B"}
@@ -0,0 +1,266 @@
1
+ /**
2
+ * ACP SDK Bridge — Dual-Connection ACP Protocol Mediator
3
+ *
4
+ * The bridge presents an AgentSideConnection to the editor (via ndjson
5
+ * on provided streams) and a ClientSideConnection to the container agent
6
+ * (via docker compose run piped stdio). It handles deferred startup:
7
+ * `initialize` responds immediately with local capabilities, `session/new`
8
+ * starts the container, and subsequent messages are forwarded bidirectionally.
9
+ *
10
+ * PRD refs: REQ-SDK-002, REQ-SDK-003, REQ-SDK-004, REQ-SDK-009,
11
+ * REQ-SDK-010, REQ-SDK-013
12
+ */
13
+ import { Readable, Writable } from "node:stream";
14
+ import { AgentSideConnection, ClientSideConnection, ndJsonStream, PROTOCOL_VERSION, RequestError, } from "@agentclientprotocol/sdk";
15
+ // ── AcpSdkBridge ─────────────────────────────────────────────────────
16
+ export class AcpSdkBridge {
17
+ config;
18
+ logger;
19
+ editorConnection = null;
20
+ containerConnection = null;
21
+ childProcess = null;
22
+ initializeParams = null;
23
+ sessionActive = false;
24
+ constructor(config) {
25
+ this.config = config;
26
+ this.logger = config.logger;
27
+ }
28
+ /**
29
+ * Start the bridge with the given editor-facing streams.
30
+ * Creates an AgentSideConnection that handles the ACP protocol
31
+ * with the editor.
32
+ */
33
+ start(editorInput, editorOutput) {
34
+ if (this.editorConnection)
35
+ return;
36
+ const stream = ndJsonStream(editorOutput, editorInput);
37
+ this.editorConnection = new AgentSideConnection((conn) => this.createEditorAgent(conn), stream);
38
+ this.logger?.log("[bridge] AgentSideConnection started for editor");
39
+ // Monitor editor connection lifecycle (REQ-SDK-009)
40
+ void this.editorConnection.closed.then(() => {
41
+ this.logger?.log("[bridge] Editor connection closed");
42
+ void this.cleanupContainer();
43
+ });
44
+ }
45
+ /**
46
+ * Promise that resolves when the editor connection closes.
47
+ */
48
+ get closed() {
49
+ if (!this.editorConnection) {
50
+ return Promise.resolve();
51
+ }
52
+ return this.editorConnection.closed;
53
+ }
54
+ /**
55
+ * Stop the bridge: clean up container and editor connections.
56
+ */
57
+ async stop() {
58
+ await this.cleanupContainer();
59
+ this.editorConnection = null;
60
+ this.logger?.log("[bridge] Bridge stopped");
61
+ }
62
+ // ── Editor-Facing Agent Implementation ──────────────────────────────
63
+ createEditorAgent(_conn) {
64
+ return {
65
+ initialize: (params) => this.handleInitialize(params),
66
+ newSession: (params) => this.handleNewSession(params),
67
+ prompt: (params) => this.handlePrompt(params),
68
+ cancel: (params) => this.handleCancel(params),
69
+ authenticate: (params) => this.handleAuthenticate(params),
70
+ };
71
+ }
72
+ /**
73
+ * Handle `initialize` from the editor.
74
+ * Returns capabilities locally without starting a container. (REQ-SDK-004)
75
+ */
76
+ async handleInitialize(params) {
77
+ this.logger?.log("[bridge] initialize from editor");
78
+ // Store for forwarding to container later
79
+ this.initializeParams = params;
80
+ return {
81
+ protocolVersion: params.protocolVersion ?? PROTOCOL_VERSION,
82
+ agentCapabilities: {},
83
+ agentInfo: { name: "mason", version: "1.0.0" },
84
+ };
85
+ }
86
+ /**
87
+ * Handle `session/new` from the editor.
88
+ * Starts the container, creates ClientSideConnection, forwards
89
+ * initialize + session/new, returns the container's response. (REQ-SDK-004)
90
+ */
91
+ async handleNewSession(params) {
92
+ const cwd = params.cwd ?? process.cwd();
93
+ this.logger?.log(`[bridge] session/new from editor — cwd: "${cwd}"`);
94
+ if (this.sessionActive) {
95
+ this.logger?.log("[bridge] Cleaning up previous session");
96
+ await this.cleanupContainer();
97
+ }
98
+ // Start the container process
99
+ const child = await Promise.resolve(this.config.onSessionNew(cwd));
100
+ this.childProcess = child;
101
+ if (!child.stdin || !child.stdout) {
102
+ throw RequestError.internalError(undefined, "Container process missing stdin/stdout");
103
+ }
104
+ // Create ClientSideConnection to the container (REQ-SDK-003)
105
+ const containerOutput = Writable.toWeb(child.stdin);
106
+ const containerInput = Readable.toWeb(child.stdout);
107
+ const containerStream = ndJsonStream(containerOutput, containerInput);
108
+ this.containerConnection = new ClientSideConnection((agent) => this.createContainerClient(agent), containerStream);
109
+ this.sessionActive = true;
110
+ // Monitor container connection lifecycle (REQ-SDK-013)
111
+ void this.containerConnection.closed.then(() => {
112
+ this.logger?.log("[bridge] Container connection closed");
113
+ this.handleContainerDisconnect();
114
+ });
115
+ // Monitor child process exit (REQ-SDK-013)
116
+ child.on("exit", (code, signal) => {
117
+ this.logger?.log(`[bridge] Container process exited (code=${code}, signal=${signal})`);
118
+ this.handleContainerDisconnect();
119
+ });
120
+ child.on("error", (err) => {
121
+ this.logger?.error(`[bridge] Container process error: ${err.message}`);
122
+ this.handleContainerDisconnect();
123
+ });
124
+ // Pipe container stderr to logger
125
+ if (child.stderr) {
126
+ child.stderr.on("data", (chunk) => {
127
+ this.logger?.log(`[container] ${chunk.toString().trimEnd()}`);
128
+ });
129
+ }
130
+ // Forward initialize to the container
131
+ const initParams = this.initializeParams ?? {
132
+ protocolVersion: PROTOCOL_VERSION,
133
+ };
134
+ this.logger?.log("[bridge] Forwarding initialize to container");
135
+ await this.containerConnection.initialize(initParams);
136
+ // Forward session/new to the container
137
+ this.logger?.log("[bridge] Forwarding session/new to container");
138
+ const response = await this.containerConnection.newSession(params);
139
+ return response;
140
+ }
141
+ /**
142
+ * Handle `prompt` from the editor.
143
+ * Forwards to the container and returns its response.
144
+ */
145
+ async handlePrompt(params) {
146
+ if (!this.containerConnection) {
147
+ throw RequestError.internalError(undefined, "No active session — send session/new first");
148
+ }
149
+ this.logger?.log("[bridge] Forwarding prompt to container");
150
+ return this.containerConnection.prompt(params);
151
+ }
152
+ /**
153
+ * Handle `cancel` from the editor.
154
+ * Forwards cancel notification to the container. (REQ-SDK-010)
155
+ */
156
+ async handleCancel(params) {
157
+ if (!this.containerConnection) {
158
+ this.logger?.log("[bridge] cancel received but no container connection");
159
+ return;
160
+ }
161
+ this.logger?.log("[bridge] Forwarding cancel to container");
162
+ await this.containerConnection.cancel(params);
163
+ }
164
+ /**
165
+ * Handle `authenticate` from the editor.
166
+ * Forwards to the container if connected, otherwise returns empty.
167
+ */
168
+ async handleAuthenticate(params) {
169
+ if (!this.containerConnection) {
170
+ return {};
171
+ }
172
+ return this.containerConnection.authenticate(params);
173
+ }
174
+ // ── Container-Facing Client Implementation ──────────────────────────
175
+ /**
176
+ * Create a Client implementation for the ClientSideConnection.
177
+ * Forwards notifications from the container back to the editor. (REQ-SDK-010)
178
+ */
179
+ createContainerClient(_agent) {
180
+ return {
181
+ requestPermission: (params) => this.forwardRequestPermission(params),
182
+ sessionUpdate: (params) => this.forwardSessionUpdate(params),
183
+ readTextFile: (params) => this.forwardReadTextFile(params),
184
+ writeTextFile: (params) => this.forwardWriteTextFile(params),
185
+ createTerminal: (params) => this.forwardCreateTerminal(params),
186
+ terminalOutput: (params) => this.forwardTerminalOutput(params),
187
+ releaseTerminal: (params) => this.forwardReleaseTerminal(params),
188
+ waitForTerminalExit: (params) => this.forwardWaitForTerminalExit(params),
189
+ killTerminal: (params) => this.forwardKillTerminal(params),
190
+ };
191
+ }
192
+ async forwardSessionUpdate(params) {
193
+ if (!this.editorConnection)
194
+ return;
195
+ this.logger?.log("[bridge] Forwarding sessionUpdate to editor");
196
+ await this.editorConnection.sessionUpdate(params);
197
+ }
198
+ async forwardRequestPermission(params) {
199
+ if (!this.editorConnection) {
200
+ throw RequestError.internalError(undefined, "Editor connection not available");
201
+ }
202
+ this.logger?.log("[bridge] Forwarding requestPermission to editor");
203
+ return this.editorConnection.requestPermission(params);
204
+ }
205
+ async forwardReadTextFile(params) {
206
+ if (!this.editorConnection) {
207
+ throw RequestError.internalError(undefined, "Editor connection not available");
208
+ }
209
+ return this.editorConnection.readTextFile(params);
210
+ }
211
+ async forwardWriteTextFile(params) {
212
+ if (!this.editorConnection) {
213
+ throw RequestError.internalError(undefined, "Editor connection not available");
214
+ }
215
+ return this.editorConnection.writeTextFile(params);
216
+ }
217
+ async forwardCreateTerminal(params) {
218
+ if (!this.editorConnection) {
219
+ throw RequestError.internalError(undefined, "Editor connection not available");
220
+ }
221
+ // createTerminal returns a TerminalHandle; extract the terminalId for the raw response
222
+ const handle = await this.editorConnection.createTerminal(params);
223
+ return { terminalId: handle.id };
224
+ }
225
+ async forwardTerminalOutput(params) {
226
+ if (!this.editorConnection) {
227
+ throw RequestError.internalError(undefined, "Editor connection not available");
228
+ }
229
+ return this.editorConnection.extMethod("terminal/output", params);
230
+ }
231
+ async forwardReleaseTerminal(params) {
232
+ if (!this.editorConnection)
233
+ return;
234
+ return this.editorConnection.extMethod("terminal/release", params);
235
+ }
236
+ async forwardWaitForTerminalExit(params) {
237
+ if (!this.editorConnection) {
238
+ throw RequestError.internalError(undefined, "Editor connection not available");
239
+ }
240
+ return this.editorConnection.extMethod("terminal/waitForExit", params);
241
+ }
242
+ async forwardKillTerminal(params) {
243
+ if (!this.editorConnection)
244
+ return;
245
+ return this.editorConnection.extMethod("terminal/kill", params);
246
+ }
247
+ // ── Container Lifecycle ─────────────────────────────────────────────
248
+ handleContainerDisconnect() {
249
+ if (!this.sessionActive)
250
+ return;
251
+ this.logger?.log("[bridge] Container disconnected — cleaning up for next session");
252
+ this.containerConnection = null;
253
+ this.childProcess = null;
254
+ this.sessionActive = false;
255
+ }
256
+ async cleanupContainer() {
257
+ this.sessionActive = false;
258
+ if (this.childProcess) {
259
+ this.logger?.log("[bridge] Killing container child process");
260
+ this.childProcess.kill();
261
+ this.childProcess = null;
262
+ }
263
+ this.containerConnection = null;
264
+ }
265
+ }
266
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/acp/bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * File-based logger for ACP runtime.
3
+ *
4
+ * Writes timestamped log lines to `{logDir}/acp.log`.
5
+ * Used in both stdio and HTTP transport modes so that diagnostic
6
+ * output never pollutes stdout (which stdio transport needs for JSON-RPC).
7
+ */
8
+ export interface AcpLogger {
9
+ log(...args: unknown[]): void;
10
+ error(...args: unknown[]): void;
11
+ close(): void;
12
+ }
13
+ /**
14
+ * Create a file-appending logger that writes to `{logDir}/acp.log`.
15
+ * Creates the directory if it doesn't exist.
16
+ */
17
+ export declare function createFileLogger(logDir: string): AcpLogger;
18
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/acp/logger.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChC,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAuB1D"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * File-based logger for ACP runtime.
3
+ *
4
+ * Writes timestamped log lines to `{logDir}/acp.log`.
5
+ * Used in both stdio and HTTP transport modes so that diagnostic
6
+ * output never pollutes stdout (which stdio transport needs for JSON-RPC).
7
+ */
8
+ import * as fs from "node:fs";
9
+ import * as path from "node:path";
10
+ /**
11
+ * Create a file-appending logger that writes to `{logDir}/acp.log`.
12
+ * Creates the directory if it doesn't exist.
13
+ */
14
+ export function createFileLogger(logDir) {
15
+ fs.mkdirSync(logDir, { recursive: true });
16
+ const logPath = path.join(logDir, "acp.log");
17
+ const stream = fs.createWriteStream(logPath, { flags: "a" });
18
+ function write(level, args) {
19
+ const ts = new Date().toISOString();
20
+ const msg = args.map((a) => (typeof a === "string" ? a : JSON.stringify(a))).join(" ");
21
+ stream.write(`${ts} [${level}] ${msg}\n`);
22
+ }
23
+ return {
24
+ log(...args) {
25
+ write("INFO", args);
26
+ },
27
+ error(...args) {
28
+ write("ERROR", args);
29
+ },
30
+ close() {
31
+ stream.end();
32
+ },
33
+ };
34
+ }
35
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/acp/logger.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAQlC;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IAE7D,SAAS,KAAK,CAAC,KAAa,EAAE,IAAe;QAC3C,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvF,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,KAAK,KAAK,GAAG,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO;QACL,GAAG,CAAC,GAAG,IAAe;YACpB,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACtB,CAAC;QACD,KAAK,CAAC,GAAG,IAAe;YACtB,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACvB,CAAC;QACD,KAAK;YACH,MAAM,CAAC,GAAG,EAAE,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,60 @@
1
+ import type { ResolvedApp } from "@clawmasons/shared";
2
+ /**
3
+ * An MCP server configuration from an ACP client's mcpServers map.
4
+ */
5
+ export interface McpServerConfig {
6
+ command?: string;
7
+ args?: string[];
8
+ url?: string;
9
+ env?: Record<string, string>;
10
+ headers?: Record<string, string>;
11
+ }
12
+ /**
13
+ * A matched MCP server linked to its chapter App.
14
+ */
15
+ export interface MatchedServer {
16
+ /** The mcpServers key (e.g., "github") */
17
+ name: string;
18
+ /** The original MCP server config from the ACP client */
19
+ config: McpServerConfig;
20
+ /** The chapter App that matched */
21
+ app: ResolvedApp;
22
+ /** The app's short name (e.g., "github") */
23
+ appShortName: string;
24
+ }
25
+ /**
26
+ * An unmatched MCP server with a reason for not matching.
27
+ */
28
+ export interface UnmatchedServer {
29
+ /** The mcpServers key */
30
+ name: string;
31
+ /** The original MCP server config from the ACP client */
32
+ config: McpServerConfig;
33
+ /** Human-readable explanation of why no match was found */
34
+ reason: string;
35
+ }
36
+ /**
37
+ * The result of matching ACP client mcpServers against chapter Apps.
38
+ */
39
+ export interface MatchResult {
40
+ matched: MatchedServer[];
41
+ unmatched: UnmatchedServer[];
42
+ }
43
+ /**
44
+ * Build a case-insensitive index from app short names to their ResolvedApp objects.
45
+ * Multiple apps can share the same short name (handled by disambiguation).
46
+ */
47
+ export declare function buildAppShortNameIndex(apps: ResolvedApp[]): Map<string, ResolvedApp[]>;
48
+ /**
49
+ * Match ACP client mcpServers entries against chapter's resolved Apps.
50
+ *
51
+ * Matching uses `getAppShortName()` as the primary key (case-insensitive).
52
+ * When multiple apps share the same short name, command+args or URL
53
+ * are used as secondary disambiguation signals.
54
+ *
55
+ * @param mcpServers - The ACP client's mcpServers configuration map
56
+ * @param apps - The resolved Apps from the agent dependency graph
57
+ * @returns A MatchResult with matched and unmatched server lists
58
+ */
59
+ export declare function matchServers(mcpServers: Record<string, McpServerConfig>, apps: ResolvedApp[]): MatchResult;
60
+ //# sourceMappingURL=matcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher.d.ts","sourceRoot":"","sources":["../../src/acp/matcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,MAAM,EAAE,eAAe,CAAC;IACxB,mCAAmC;IACnC,GAAG,EAAE,WAAW,CAAC;IACjB,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,MAAM,EAAE,eAAe,CAAC;IACxB,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,SAAS,EAAE,eAAe,EAAE,CAAC;CAC9B;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,WAAW,EAAE,GAClB,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAY5B;AAgDD;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,EAC3C,IAAI,EAAE,WAAW,EAAE,GAClB,WAAW,CAgCb"}
@@ -0,0 +1,101 @@
1
+ import { getAppShortName } from "@clawmasons/shared";
2
+ /**
3
+ * Build a case-insensitive index from app short names to their ResolvedApp objects.
4
+ * Multiple apps can share the same short name (handled by disambiguation).
5
+ */
6
+ export function buildAppShortNameIndex(apps) {
7
+ const index = new Map();
8
+ for (const app of apps) {
9
+ const shortName = getAppShortName(app.name).toLowerCase();
10
+ let list = index.get(shortName);
11
+ if (!list) {
12
+ list = [];
13
+ index.set(shortName, list);
14
+ }
15
+ list.push(app);
16
+ }
17
+ return index;
18
+ }
19
+ /**
20
+ * Check if command+args match between an mcpServers entry and an app.
21
+ */
22
+ function commandMatches(config, app) {
23
+ if (!config.command || !app.command)
24
+ return false;
25
+ if (config.command !== app.command)
26
+ return false;
27
+ const configArgs = config.args ?? [];
28
+ const appArgs = app.args ?? [];
29
+ if (configArgs.length !== appArgs.length)
30
+ return false;
31
+ return configArgs.every((arg, i) => arg === appArgs[i]);
32
+ }
33
+ /**
34
+ * Check if URL matches between an mcpServers entry and an app.
35
+ */
36
+ function urlMatches(config, app) {
37
+ if (!config.url || !app.url)
38
+ return false;
39
+ return config.url === app.url;
40
+ }
41
+ /**
42
+ * Disambiguate among multiple apps that share the same short name,
43
+ * using command+args or URL as secondary signals.
44
+ */
45
+ function disambiguate(config, candidates) {
46
+ // Try command+args match
47
+ for (const app of candidates) {
48
+ if (commandMatches(config, app))
49
+ return app;
50
+ }
51
+ // Try URL match
52
+ for (const app of candidates) {
53
+ if (urlMatches(config, app))
54
+ return app;
55
+ }
56
+ // No disambiguation possible — return first candidate
57
+ // candidates is guaranteed non-empty by the caller
58
+ const fallback = candidates[0];
59
+ if (!fallback)
60
+ throw new Error("Unexpected empty candidates array");
61
+ return fallback;
62
+ }
63
+ /**
64
+ * Match ACP client mcpServers entries against chapter's resolved Apps.
65
+ *
66
+ * Matching uses `getAppShortName()` as the primary key (case-insensitive).
67
+ * When multiple apps share the same short name, command+args or URL
68
+ * are used as secondary disambiguation signals.
69
+ *
70
+ * @param mcpServers - The ACP client's mcpServers configuration map
71
+ * @param apps - The resolved Apps from the agent dependency graph
72
+ * @returns A MatchResult with matched and unmatched server lists
73
+ */
74
+ export function matchServers(mcpServers, apps) {
75
+ const index = buildAppShortNameIndex(apps);
76
+ const matched = [];
77
+ const unmatched = [];
78
+ for (const [name, config] of Object.entries(mcpServers)) {
79
+ const key = name.toLowerCase();
80
+ const candidates = index.get(key);
81
+ if (!candidates || candidates.length === 0) {
82
+ unmatched.push({
83
+ name,
84
+ config,
85
+ reason: `No matching chapter App found for server "${name}"`,
86
+ });
87
+ continue;
88
+ }
89
+ const app = candidates.length === 1
90
+ ? (candidates[0] ?? disambiguate(config, candidates))
91
+ : disambiguate(config, candidates);
92
+ matched.push({
93
+ name,
94
+ config,
95
+ app,
96
+ appShortName: getAppShortName(app.name),
97
+ });
98
+ }
99
+ return { matched, unmatched };
100
+ }
101
+ //# sourceMappingURL=matcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher.js","sourceRoot":"","sources":["../../src/acp/matcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { MatchResult, MatchedServer, McpServerConfig } from "./matcher.js";
2
+ /**
3
+ * The result of rewriting ACP client mcpServers for the agent container.
4
+ */
5
+ export interface RewriteResult {
6
+ /** The rewritten mcpServers config with a single `chapter` proxy entry */
7
+ mcpServers: Record<string, McpServerConfig>;
8
+ /** Credentials extracted from matched servers' env fields (for credential-service session overrides) */
9
+ extractedCredentials: Record<string, string>;
10
+ }
11
+ /**
12
+ * Extract all credential key-value pairs from matched servers' env fields.
13
+ *
14
+ * Merges all env records into a single flat record. If two servers provide
15
+ * the same key, the later one wins (iteration order of matched array).
16
+ *
17
+ * @param matched - The matched servers from the matcher
18
+ * @returns A flat record of all credential key-value pairs
19
+ */
20
+ export declare function extractCredentials(matched: MatchedServer[]): Record<string, string>;
21
+ /**
22
+ * Rewrite the ACP client's mcpServers config for the agent container.
23
+ *
24
+ * Replaces all matched MCP server entries with a single `chapter` entry
25
+ * pointing to the chapter proxy's streamable-http endpoint. Extracts
26
+ * credentials from matched servers' env fields for injection into the
27
+ * credential-service as session overrides.
28
+ *
29
+ * @param matchResult - The result from matchServers()
30
+ * @param proxyUrl - The chapter proxy URL inside the Docker network (e.g., "http://proxy:3000/mcp")
31
+ * @param sessionToken - The session authentication token
32
+ * @returns The rewritten mcpServers config and extracted credentials
33
+ */
34
+ export declare function rewriteMcpConfig(matchResult: MatchResult, proxyUrl: string, sessionToken: string): RewriteResult;
35
+ //# sourceMappingURL=rewriter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rewriter.d.ts","sourceRoot":"","sources":["../../src/acp/rewriter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5C,wGAAwG;IACxG,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,aAAa,EAAE,GACvB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,aAAa,CAaf"}