clinkx 0.2.2 → 0.2.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 (63) hide show
  1. package/clinkx-workflows/dist/clink-client.js +35 -10
  2. package/clinkx-workflows/dist/clink-client.js.map +1 -1
  3. package/clinkx-workflows/dist/config.d.ts +10 -0
  4. package/clinkx-workflows/dist/config.js +18 -0
  5. package/clinkx-workflows/dist/config.js.map +1 -1
  6. package/clinkx-workflows/dist/council-expander.d.ts +43 -0
  7. package/clinkx-workflows/dist/council-expander.js +330 -0
  8. package/clinkx-workflows/dist/council-expander.js.map +1 -0
  9. package/clinkx-workflows/dist/index.d.ts +14 -0
  10. package/clinkx-workflows/dist/index.js +264 -16
  11. package/clinkx-workflows/dist/index.js.map +1 -1
  12. package/clinkx-workflows/dist/server.d.ts +8 -1
  13. package/clinkx-workflows/dist/server.js +87 -1
  14. package/clinkx-workflows/dist/server.js.map +1 -1
  15. package/clinkx-workflows/dist/shutdown.d.ts +5 -9
  16. package/clinkx-workflows/dist/shutdown.js +6 -23
  17. package/clinkx-workflows/dist/shutdown.js.map +1 -1
  18. package/clinkx-workflows/dist/state.d.ts +13 -0
  19. package/clinkx-workflows/dist/state.js +198 -2
  20. package/clinkx-workflows/dist/state.js.map +1 -1
  21. package/clinkx-workflows/dist/transport.js +24 -8
  22. package/clinkx-workflows/dist/transport.js.map +1 -1
  23. package/clinkx-workflows/dist/workflow-tools.d.ts +14 -1
  24. package/clinkx-workflows/dist/workflow-tools.js +173 -12
  25. package/clinkx-workflows/dist/workflow-tools.js.map +1 -1
  26. package/clinkx-workflows/dist/workflows/index.d.ts +4 -3
  27. package/clinkx-workflows/dist/workflows/index.js +4 -3
  28. package/clinkx-workflows/dist/workflows/index.js.map +1 -1
  29. package/clinkx-workflows/templates/council/answer-chairman.txt +49 -0
  30. package/clinkx-workflows/templates/council/answer-cross-reviewer.txt +37 -0
  31. package/clinkx-workflows/templates/council/answer-specialist.txt +40 -0
  32. package/clinkx-workflows/templates/council/chairman.txt +59 -0
  33. package/clinkx-workflows/templates/council/code-review-chairman.txt +57 -0
  34. package/clinkx-workflows/templates/council/code-review-cross-reviewer.txt +43 -0
  35. package/clinkx-workflows/templates/council/code-review-reviewer.txt +39 -0
  36. package/clinkx-workflows/templates/council/debug-chairman.txt +57 -0
  37. package/clinkx-workflows/templates/council/debug-cross-reviewer.txt +41 -0
  38. package/clinkx-workflows/templates/council/debug-debugger.txt +46 -0
  39. package/clinkx-workflows/templates/council/discover-analyst.txt +38 -0
  40. package/clinkx-workflows/templates/council/discover-chairman.txt +51 -0
  41. package/clinkx-workflows/templates/council/discover-cross-reviewer.txt +40 -0
  42. package/clinkx-workflows/templates/council/member.txt +48 -0
  43. package/clinkx-workflows/templates/council/reviewer.txt +57 -0
  44. package/clinkx-workflows/workflows/council-answer.yaml +147 -0
  45. package/clinkx-workflows/workflows/council-code-review.yaml +152 -0
  46. package/clinkx-workflows/workflows/council-debug.yaml +152 -0
  47. package/clinkx-workflows/workflows/council-default.yaml +147 -0
  48. package/clinkx-workflows/workflows/council-discover.yaml +147 -0
  49. package/dist/index.d.ts +11 -0
  50. package/dist/index.js +246 -14
  51. package/dist/index.js.map +1 -1
  52. package/dist/pipeline.d.ts +1 -1
  53. package/dist/pipeline.js +29 -5
  54. package/dist/pipeline.js.map +1 -1
  55. package/dist/runner.d.ts +2 -2
  56. package/dist/runner.js +24 -3
  57. package/dist/runner.js.map +1 -1
  58. package/dist/server.js +2 -1
  59. package/dist/server.js.map +1 -1
  60. package/package.json +5 -2
  61. package/clinkx-workflows/dist/workflows/council-default.d.ts +0 -123
  62. package/clinkx-workflows/dist/workflows/council-default.js +0 -141
  63. package/clinkx-workflows/dist/workflows/council-default.js.map +0 -1
@@ -11,32 +11,280 @@
11
11
  * for in-process integration (Option C).
12
12
  */
13
13
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
14
+ import { serializeMessage } from "@modelcontextprotocol/sdk/shared/stdio.js";
15
+ import { realpathSync } from "node:fs";
16
+ import { fileURLToPath, pathToFileURL } from "node:url";
14
17
  import { createWorkflowServer } from "./server.js";
15
18
  import { logger, assertStderrLogger } from "./logger.js";
19
+ import { shutdownCoordinator } from "./shutdown.js";
16
20
  export { registerWorkflowTools, getWorkflowToolDefinitions, handleWorkflowToolCall, WORKFLOW_TOOL_NAMES, } from "./workflow-tools.js";
17
21
  export { createWorkflowServer } from "./server.js";
22
+ const SHUTDOWN_DEADLINE_MS = 10_000;
23
+ const SEND_TIMEOUT_MS = 30_000;
24
+ const patchedTransports = new WeakSet();
25
+ function serializeError(err) {
26
+ return err instanceof Error ? err.message : String(err);
27
+ }
28
+ function toError(err) {
29
+ return err instanceof Error ? err : new Error(String(err));
30
+ }
31
+ function extractRpcMeta(msg) {
32
+ if ("method" in msg) {
33
+ return "id" in msg && msg.id !== undefined ? { id: msg.id, method: msg.method } : { method: msg.method };
34
+ }
35
+ if ("id" in msg && msg.id !== undefined)
36
+ return { id: msg.id };
37
+ return {};
38
+ }
39
+ export function patchTransportSend(transport, stdout = process.stdout, onBrokenStdout) {
40
+ if (patchedTransports.has(transport))
41
+ return;
42
+ patchedTransports.add(transport);
43
+ let brokenError;
44
+ let sendChain = Promise.resolve();
45
+ const pendingRejects = [];
46
+ let shuttingDown = false;
47
+ function markBroken(err) {
48
+ brokenError ??= err;
49
+ const rejects = pendingRejects.splice(0);
50
+ for (const reject of rejects) {
51
+ reject(brokenError);
52
+ }
53
+ if (!shuttingDown) {
54
+ shuttingDown = true;
55
+ stdout.off("error", onError);
56
+ onBrokenStdout?.();
57
+ }
58
+ }
59
+ function onError(err) {
60
+ markBroken(err);
61
+ }
62
+ stdout.on("error", onError);
63
+ function sendOne(message) {
64
+ if (brokenError !== undefined) {
65
+ return Promise.reject(brokenError);
66
+ }
67
+ const json = serializeMessage(message);
68
+ const payloadBytes = Buffer.byteLength(json, "utf8");
69
+ const { id: rpcId, method: rpcMethod } = extractRpcMeta(message);
70
+ return new Promise((resolve, reject) => {
71
+ if (brokenError !== undefined) {
72
+ reject(brokenError);
73
+ return;
74
+ }
75
+ let settled = false;
76
+ let drainAttached = false;
77
+ let drainStartedAt = 0;
78
+ const timeout = setTimeout(() => {
79
+ logger.error({ rpcId, rpcMethod, payloadBytes }, "transport:send:timeout");
80
+ markBroken(new Error(`stdout write timed out after ${SEND_TIMEOUT_MS}ms`));
81
+ }, SEND_TIMEOUT_MS);
82
+ timeout.unref();
83
+ function cleanup() {
84
+ clearTimeout(timeout);
85
+ const index = pendingRejects.indexOf(onStdoutError);
86
+ if (index !== -1) {
87
+ pendingRejects.splice(index, 1);
88
+ }
89
+ if (drainAttached) {
90
+ stdout.off("drain", onDrain);
91
+ }
92
+ }
93
+ function settleResolve() {
94
+ if (settled)
95
+ return;
96
+ settled = true;
97
+ const drainMs = drainStartedAt === 0 ? 0 : Date.now() - drainStartedAt;
98
+ cleanup();
99
+ logger.debug({ rpcId, rpcMethod, payloadBytes, drainMs }, "transport:send:ok");
100
+ resolve();
101
+ }
102
+ function settleReject(err) {
103
+ if (settled)
104
+ return;
105
+ settled = true;
106
+ cleanup();
107
+ reject(err);
108
+ }
109
+ function onStdoutError(err) {
110
+ settleReject(err);
111
+ }
112
+ function onDrain() {
113
+ settleResolve();
114
+ }
115
+ pendingRejects.push(onStdoutError);
116
+ try {
117
+ logger.debug({ rpcId, rpcMethod, payloadBytes, writableLength: stdout.writableLength }, "transport:send:start");
118
+ if (stdout.write(json)) {
119
+ settleResolve();
120
+ }
121
+ else {
122
+ drainAttached = true;
123
+ drainStartedAt = Date.now();
124
+ stdout.once("drain", onDrain);
125
+ }
126
+ }
127
+ catch (err) {
128
+ const error = toError(err);
129
+ const nodeError = error;
130
+ logger.error({
131
+ rpcId,
132
+ rpcMethod,
133
+ payloadBytes,
134
+ errCode: nodeError.code,
135
+ errSyscall: nodeError.syscall,
136
+ }, "transport:send:error");
137
+ markBroken(error);
138
+ settleReject(error);
139
+ }
140
+ });
141
+ }
142
+ transport.send = (message) => {
143
+ const send = sendChain.then(() => sendOne(message), () => sendOne(message));
144
+ sendChain = send.catch(() => undefined);
145
+ return send;
146
+ };
147
+ }
148
+ export function createShutdownOnce(server, options = {}) {
149
+ let shutdownStarted = false;
150
+ const cleanup = options.cleanup ?? (() => Promise.resolve());
151
+ const exit = options.exit ?? process.exit.bind(process);
152
+ return async function shutdownOnce(reason, exitCode) {
153
+ if (shutdownStarted) {
154
+ logger.warn({ reason }, "duplicate shutdown event ignored");
155
+ return;
156
+ }
157
+ shutdownStarted = true;
158
+ logger.info({ reason, exit_code: exitCode, pid: process.pid, writableLength: process.stdout.writableLength }, "clinkx-workflows:shutdown");
159
+ const deadline = new Promise((_, reject) => {
160
+ setTimeout(() => reject(new Error("shutdown deadline exceeded")), SHUTDOWN_DEADLINE_MS).unref();
161
+ });
162
+ try {
163
+ await Promise.race([
164
+ (async () => {
165
+ let effectiveExitCode = exitCode;
166
+ logger.info({ reason, exit_code: exitCode }, "shutdown requested");
167
+ try {
168
+ await cleanup(reason);
169
+ }
170
+ catch (err) {
171
+ effectiveExitCode = 1;
172
+ logger.error({ reason, err: serializeError(err) }, "shutdown cleanup failed");
173
+ }
174
+ try {
175
+ await server.close();
176
+ }
177
+ catch (err) {
178
+ effectiveExitCode = 1;
179
+ logger.error({ reason, err: serializeError(err) }, "server close failed during shutdown");
180
+ }
181
+ if (process.stdout.writableLength > 0 && process.stdout.writable) {
182
+ await new Promise((resolve) => {
183
+ const onDrain = () => {
184
+ clearTimeout(timer);
185
+ resolve();
186
+ };
187
+ const timer = setTimeout(() => {
188
+ process.stdout.off("drain", onDrain);
189
+ resolve();
190
+ }, 2_000);
191
+ timer.unref();
192
+ process.stdout.once("drain", onDrain);
193
+ });
194
+ }
195
+ exit(effectiveExitCode);
196
+ })(),
197
+ deadline,
198
+ ]);
199
+ }
200
+ catch {
201
+ try {
202
+ logger.error({ reason }, "shutdown deadline exceeded, forcing exit");
203
+ }
204
+ catch {
205
+ // Logger may be unavailable during stream failures.
206
+ }
207
+ process.exit(1);
208
+ }
209
+ };
210
+ }
211
+ export function installShutdownHandlers(shutdownOnce, targetProcess = process) {
212
+ const runShutdown = (reason, exitCode) => {
213
+ void shutdownOnce(reason, exitCode).catch((err) => {
214
+ try {
215
+ logger.fatal({ reason, err: serializeError(err) }, "shutdown failed");
216
+ }
217
+ catch {
218
+ // Logger may be unavailable during stream failures.
219
+ }
220
+ targetProcess.exit(1);
221
+ });
222
+ };
223
+ targetProcess.once("SIGTERM", () => runShutdown("SIGTERM", 0));
224
+ targetProcess.once("SIGINT", () => runShutdown("SIGINT", 0));
225
+ targetProcess.once("SIGHUP", () => runShutdown("SIGHUP", 0));
226
+ targetProcess.stdin.once("end", () => runShutdown("stdin:end", 0));
227
+ targetProcess.stdin.once("close", () => runShutdown("stdin:close", 0));
228
+ targetProcess.stdin.once("error", () => runShutdown("stdin:error", 1));
229
+ targetProcess.stderr.on("error", () => runShutdown("stderr:error", 0));
230
+ targetProcess.on("uncaughtException", (err) => {
231
+ try {
232
+ logger.fatal({ err }, "uncaught exception");
233
+ }
234
+ catch {
235
+ // Logger may be unavailable during fatal shutdown.
236
+ }
237
+ runShutdown("uncaughtException", 1);
238
+ });
239
+ targetProcess.on("unhandledRejection", (reason) => {
240
+ try {
241
+ logger.fatal({ err: reason }, "unhandled rejection");
242
+ }
243
+ catch {
244
+ // Logger may be unavailable during fatal shutdown.
245
+ }
246
+ runShutdown("unhandledRejection", 1);
247
+ });
248
+ }
18
249
  async function main() {
19
250
  assertStderrLogger();
20
251
  const server = createWorkflowServer();
21
252
  const transport = new StdioServerTransport();
22
253
  logger.info("clinkx-workflows MCP server starting (STDIO transport)");
254
+ logger.info({ pid: process.pid, ppid: process.ppid }, "clinkx-workflows:startup");
255
+ const shutdownOnce = createShutdownOnce(server, {
256
+ cleanup: (reason) => shutdownCoordinator.shutdown(reason),
257
+ });
258
+ patchTransportSend(transport, process.stdout, () => {
259
+ void shutdownOnce("stdout:error", 1).catch((err) => {
260
+ try {
261
+ logger.fatal({ reason: "stdout:error", err: serializeError(err) }, "shutdown failed");
262
+ }
263
+ catch {
264
+ // Logger may be unavailable during stream failures.
265
+ }
266
+ process.exit(1);
267
+ });
268
+ });
269
+ installShutdownHandlers(shutdownOnce);
23
270
  await server.connect(transport);
24
- // Graceful shutdown: coordinate with any in-flight workflow,
25
- // then close the server and exit.
26
- const shutdown = async (signal) => {
27
- logger.info({ signal }, "shutdown signal received");
28
- // ShutdownCoordinator handles in-flight workflow cancellation,
29
- // state persistence, and child termination via its own signal handlers.
30
- // We just need to close the MCP server transport cleanly.
31
- await server.close();
32
- process.exit(0);
33
- };
34
- process.once("SIGTERM", () => void shutdown("SIGTERM").catch(() => process.exit(1)));
35
- process.once("SIGINT", () => void shutdown("SIGINT").catch(() => process.exit(1)));
36
271
  logger.info("clinkx-workflows MCP server connected and ready");
37
272
  }
38
- main().catch((err) => {
39
- logger.fatal({ err }, "clinkx-workflows failed to start");
40
- process.exitCode = 1;
41
- });
273
+ function isCliEntrypoint() {
274
+ const entry = process.argv[1];
275
+ if (entry == null)
276
+ return false;
277
+ try {
278
+ return realpathSync(entry) === realpathSync(fileURLToPath(import.meta.url));
279
+ }
280
+ catch {
281
+ return import.meta.url === pathToFileURL(entry).href;
282
+ }
283
+ }
284
+ if (isCliEntrypoint()) {
285
+ main().catch((err) => {
286
+ logger.fatal({ err }, "clinkx-workflows failed to start");
287
+ process.exitCode = 1;
288
+ });
289
+ }
42
290
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAKzD,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,KAAK,UAAU,IAAI;IACjB,kBAAkB,EAAE,CAAC;IAErB,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,MAAM,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAC;IAEtE,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,6DAA6D;IAC7D,kCAAkC;IAClC,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;QACxC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,0BAA0B,CAAC,CAAC;QACpD,+DAA+D;QAC/D,wEAAwE;QACxE,0DAA0D;QAC1D,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrF,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEnF,MAAM,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;AACjE,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,kCAAkC,CAAC,CAAC;IAC1D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAE7E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAIpD,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,oBAAoB,GAAG,MAAM,CAAC;AACpC,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,MAAM,iBAAiB,GAAG,IAAI,OAAO,EAAwB,CAAC;AAe9D,SAAS,cAAc,CAAC,GAAY;IAClC,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,OAAO,CAAC,GAAY;IAC3B,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,cAAc,CAAC,GAAmB;IACzC,IAAI,QAAQ,IAAI,GAAG,EAAE,CAAC;QACpB,OAAO,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IAC3G,CAAC;IACD,IAAI,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,EAAE,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;IAC/D,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,SAA+B,EAC/B,SAAmB,OAAO,CAAC,MAAM,EACjC,cAA2B;IAE3B,IAAI,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO;IAC7C,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAEjC,IAAI,WAA8B,CAAC;IACnC,IAAI,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAClC,MAAM,cAAc,GAAgC,EAAE,CAAC;IACvD,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,SAAS,UAAU,CAAC,GAAU;QAC5B,WAAW,KAAK,GAAG,CAAC;QACpB,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACzC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,CAAC,WAAW,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,YAAY,GAAG,IAAI,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,cAAc,EAAE,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED,SAAS,OAAO,CAAC,GAAU;QACzB,UAAU,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAE5B,SAAS,OAAO,CAAC,OAAuB;QACtC,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACrC,CAAC;QAED,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACrD,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QAEjE,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC9B,MAAM,CAAC,WAAW,CAAC,CAAC;gBACpB,OAAO;YACT,CAAC;YAED,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,IAAI,aAAa,GAAG,KAAK,CAAC;YAC1B,IAAI,cAAc,GAAG,CAAC,CAAC;YAEvB,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC9B,MAAM,CAAC,KAAK,CACV,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,EAClC,wBAAwB,CACzB,CAAC;gBACF,UAAU,CAAC,IAAI,KAAK,CAAC,gCAAgC,eAAe,IAAI,CAAC,CAAC,CAAC;YAC7E,CAAC,EAAE,eAAe,CAAC,CAAC;YACpB,OAAO,CAAC,KAAK,EAAE,CAAC;YAEhB,SAAS,OAAO;gBACd,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;gBACpD,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;oBACjB,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAClC,CAAC;gBACD,IAAI,aAAa,EAAE,CAAC;oBAClB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC;YAED,SAAS,aAAa;gBACpB,IAAI,OAAO;oBAAE,OAAO;gBACpB,OAAO,GAAG,IAAI,CAAC;gBACf,MAAM,OAAO,GAAG,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC;gBACvE,OAAO,EAAE,CAAC;gBACV,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,mBAAmB,CAAC,CAAC;gBAC/E,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,SAAS,YAAY,CAAC,GAAU;gBAC9B,IAAI,OAAO;oBAAE,OAAO;gBACpB,OAAO,GAAG,IAAI,CAAC;gBACf,OAAO,EAAE,CAAC;gBACV,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC;YAED,SAAS,aAAa,CAAC,GAAU;gBAC/B,YAAY,CAAC,GAAG,CAAC,CAAC;YACpB,CAAC;YAED,SAAS,OAAO;gBACd,aAAa,EAAE,CAAC;YAClB,CAAC;YAED,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAEnC,IAAI,CAAC;gBACH,MAAM,CAAC,KAAK,CACV,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,EACzE,sBAAsB,CACvB,CAAC;gBACF,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBACvB,aAAa,EAAE,CAAC;gBAClB,CAAC;qBAAM,CAAC;oBACN,aAAa,GAAG,IAAI,CAAC;oBACrB,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBAC5B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;gBAC3B,MAAM,SAAS,GAAG,KAA8B,CAAC;gBACjD,MAAM,CAAC,KAAK,CACV;oBACE,KAAK;oBACL,SAAS;oBACT,YAAY;oBACZ,OAAO,EAAE,SAAS,CAAC,IAAI;oBACvB,UAAU,EAAE,SAAS,CAAC,OAAO;iBAC9B,EACD,sBAAsB,CACvB,CAAC;gBACF,UAAU,CAAC,KAAK,CAAC,CAAC;gBAClB,YAAY,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,CAAC,IAAI,GAAG,CAAC,OAAuB,EAAiB,EAAE;QAC1D,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CACzB,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EACtB,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CACvB,CAAC;QACF,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,MAAuB,EACvB,UAA2B,EAAE;IAE7B,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAExD,OAAO,KAAK,UAAU,YAAY,CAAC,MAAc,EAAE,QAAgB;QACjE,IAAI,eAAe,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,kCAAkC,CAAC,CAAC;YAC5D,OAAO;QACT,CAAC;QACD,eAAe,GAAG,IAAI,CAAC;QACvB,MAAM,CAAC,IAAI,CACT,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,EAChG,2BAA2B,CAC5B,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;YAChD,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC,KAAK,EAAE,CAAC;QAClG,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,IAAI,CAAC;gBACjB,CAAC,KAAK,IAAI,EAAE;oBACV,IAAI,iBAAiB,GAAG,QAAQ,CAAC;oBACjC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,oBAAoB,CAAC,CAAC;oBAEnE,IAAI,CAAC;wBACH,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;oBACxB,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,iBAAiB,GAAG,CAAC,CAAC;wBACtB,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,yBAAyB,CAAC,CAAC;oBAChF,CAAC;oBAED,IAAI,CAAC;wBACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;oBACvB,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,iBAAiB,GAAG,CAAC,CAAC;wBACtB,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,qCAAqC,CAAC,CAAC;oBAC5F,CAAC;oBAED,IAAI,OAAO,CAAC,MAAM,CAAC,cAAc,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;wBACjE,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;4BAClC,MAAM,OAAO,GAAG,GAAS,EAAE;gCACzB,YAAY,CAAC,KAAK,CAAC,CAAC;gCACpB,OAAO,EAAE,CAAC;4BACZ,CAAC,CAAC;4BACF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gCAC5B,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gCACrC,OAAO,EAAE,CAAC;4BACZ,CAAC,EAAE,KAAK,CAAC,CAAC;4BACV,KAAK,CAAC,KAAK,EAAE,CAAC;4BACd,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;wBACxC,CAAC,CAAC,CAAC;oBACL,CAAC;oBAED,IAAI,CAAC,iBAAiB,CAAC,CAAC;gBAC1B,CAAC,CAAC,EAAE;gBACJ,QAAQ;aACT,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC;gBACH,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,0CAA0C,CAAC,CAAC;YACvE,CAAC;YAAC,MAAM,CAAC;gBACP,oDAAoD;YACtD,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,YAA0B,EAC1B,gBAAgC,OAAO;IAEvC,MAAM,WAAW,GAAG,CAAC,MAAc,EAAE,QAAgB,EAAQ,EAAE;QAC7D,KAAK,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;YACzD,IAAI,CAAC;gBACH,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC;YACxE,CAAC;YAAC,MAAM,CAAC;gBACP,oDAAoD;YACtD,CAAC;YACD,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/D,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7D,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IAE7D,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IACnE,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;IACvE,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;IACvE,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC;IAEvE,aAAa,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAU,EAAE,EAAE;QACnD,IAAI,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,oBAAoB,CAAC,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,mDAAmD;QACrD,CAAC;QACD,WAAW,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,aAAa,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAe,EAAE,EAAE;QACzD,IAAI,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,mDAAmD;QACrD,CAAC;QACD,WAAW,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,kBAAkB,EAAE,CAAC;IAErB,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,MAAM,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAC;IACtE,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,0BAA0B,CAAC,CAAC;IAElF,MAAM,YAAY,GAAG,kBAAkB,CAAC,MAAM,EAAE;QAC9C,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,MAAM,CAAC;KAC1D,CAAC,CAAC;IAEH,kBAAkB,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE;QACjD,KAAK,YAAY,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;YAC1D,IAAI,CAAC;gBACH,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC;YACxF,CAAC;YAAC,MAAM,CAAC;gBACP,oDAAoD;YACtD,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,uBAAuB,CAAC,YAAY,CAAC,CAAC;IAEtC,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,MAAM,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,eAAe;IACtB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;IACvD,CAAC;AACH,CAAC;AAED,IAAI,eAAe,EAAE,EAAE,CAAC;IACtB,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QAC5B,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,kCAAkC,CAAC,CAAC;QAC1D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -12,5 +12,12 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
12
12
  * Registers three tools: run_workflow, resume_workflow, list_workflows.
13
13
  * Uses ClinkSession (child process) as the backend.
14
14
  * Does NOT connect transport — caller is responsible.
15
+ *
16
+ * When `availableCliNames` is not explicitly provided, attempts to
17
+ * discover adapter names from the child config path. This gives the
18
+ * standalone server schema enum injection and parse-time validation
19
+ * without requiring the caller to wire discovery manually.
15
20
  */
16
- export declare function createWorkflowServer(): Server;
21
+ export declare function createWorkflowServer(options?: {
22
+ availableCliNames?: readonly string[];
23
+ }): Server;
@@ -5,10 +5,84 @@
5
5
  * ClinkSession child process. For in-process integration, use
6
6
  * registerWorkflowTools() from workflow-tools.ts directly.
7
7
  */
8
+ import { readdirSync, readFileSync, statSync } from "node:fs";
9
+ import { join, extname } from "node:path";
8
10
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
11
+ import { getChildConfigPath } from "./config.js";
12
+ import { logger } from "./logger.js";
9
13
  import { ClinkSession } from "./transport.js";
10
14
  import { registerWorkflowTools } from "./workflow-tools.js";
11
15
  // ---------------------------------------------------------------------------
16
+ // Adapter name discovery
17
+ // ---------------------------------------------------------------------------
18
+ /**
19
+ * Best-effort adapter name discovery from child config path.
20
+ *
21
+ * Reads CLINKX_WORKFLOWS_CHILD_CONFIG_PATH — supports both directory
22
+ * (scan for .json files) and single-file paths, mirroring the path-
23
+ * resolution behavior of AdapterRegistry.loadFromPath.
24
+ *
25
+ * This performs lightweight structural validation (requires `name` +
26
+ * `command` fields) rather than full CliAdapterConfigSchema parsing,
27
+ * which lives in the root package and cannot be imported without
28
+ * creating a circular dependency. Runtime validation in the child
29
+ * process remains the authoritative gate. Returns undefined when no
30
+ * config path is set or no valid adapters are found.
31
+ */
32
+ function discoverChildAdapterNames() {
33
+ const configPath = getChildConfigPath();
34
+ if (configPath == null)
35
+ return undefined;
36
+ try {
37
+ const stat = statSync(configPath);
38
+ const names = [];
39
+ if (stat.isFile()) {
40
+ // Single-file config path
41
+ const name = extractAdapterName(configPath);
42
+ if (name != null)
43
+ names.push(name);
44
+ }
45
+ else if (stat.isDirectory()) {
46
+ // Directory config path — scan for .json files
47
+ const files = readdirSync(configPath).filter((f) => extname(f) === ".json");
48
+ for (const file of files) {
49
+ const name = extractAdapterName(join(configPath, file));
50
+ if (name != null)
51
+ names.push(name);
52
+ }
53
+ }
54
+ if (names.length > 0) {
55
+ logger.debug({ names, configPath }, "discovered child adapter names for standalone server");
56
+ return names;
57
+ }
58
+ }
59
+ catch (err) {
60
+ logger.debug({ configPath, err }, "could not enumerate child config path");
61
+ }
62
+ return undefined;
63
+ }
64
+ /**
65
+ * Extract the adapter name from a config JSON file.
66
+ *
67
+ * Requires both `name` (string) and `command` (string) fields to be
68
+ * present — the two mandatory fields in any valid adapter config.
69
+ * Skips files that don't meet this minimum bar.
70
+ */
71
+ function extractAdapterName(filePath) {
72
+ try {
73
+ const raw = readFileSync(filePath, "utf-8");
74
+ const parsed = JSON.parse(raw);
75
+ if (typeof parsed["name"] === "string" && parsed["name"] !== "" &&
76
+ typeof parsed["command"] === "string" && parsed["command"] !== "") {
77
+ return parsed["name"];
78
+ }
79
+ }
80
+ catch {
81
+ // Malformed config file — non-fatal
82
+ }
83
+ return undefined;
84
+ }
85
+ // ---------------------------------------------------------------------------
12
86
  // Server factory
13
87
  // ---------------------------------------------------------------------------
14
88
  /**
@@ -17,16 +91,28 @@ import { registerWorkflowTools } from "./workflow-tools.js";
17
91
  * Registers three tools: run_workflow, resume_workflow, list_workflows.
18
92
  * Uses ClinkSession (child process) as the backend.
19
93
  * Does NOT connect transport — caller is responsible.
94
+ *
95
+ * When `availableCliNames` is not explicitly provided, attempts to
96
+ * discover adapter names from the child config path. This gives the
97
+ * standalone server schema enum injection and parse-time validation
98
+ * without requiring the caller to wire discovery manually.
20
99
  */
21
- export function createWorkflowServer() {
100
+ export function createWorkflowServer(options) {
22
101
  const server = new Server({ name: "clinkx-workflows", version: "0.1.0" }, {
23
102
  capabilities: { tools: {} },
24
103
  instructions: "Orchestrates multi-stage workflows by delegating calls to CLI subagents via ClinkX. " +
25
104
  "Use run_workflow to start a new workflow, resume_workflow to continue a failed run, " +
26
105
  "or list_workflows to see available workflows.",
27
106
  });
107
+ // Normalize empty arrays to undefined — an empty list would suppress schema
108
+ // hints while still enabling validation (rejecting all adapter names).
109
+ const explicit = options?.availableCliNames;
110
+ const cliNames = (explicit != null && explicit.length > 0)
111
+ ? explicit
112
+ : discoverChildAdapterNames();
28
113
  registerWorkflowTools(server, {
29
114
  createBackend: (runId) => new ClinkSession({ runId }),
115
+ ...(cliNames != null ? { availableCliNames: cliNames } : {}),
30
116
  });
31
117
  return server;
32
118
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,OAAO,EAAE,EAC9C;QACE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAC3B,YAAY,EACV,sFAAsF;YACtF,sFAAsF;YACtF,+CAA+C;KAClD,CACF,CAAC;IAEF,qBAAqB,CAAC,MAAM,EAAE;QAC5B,aAAa,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,KAAK,EAAE,CAAC;KAC9D,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,8 @@
2
2
  * Shutdown coordinator for clinkx-workflows.
3
3
  *
4
4
  * Handles:
5
- * - SIGTERM/SIGINT: cancel in-flight calls, persist state (best-effort),
6
- * terminate child, exit
5
+ * - process shutdown: cancel in-flight calls, persist state (best-effort),
6
+ * terminate child
7
7
  * - MCP cancellation: propagate AbortSignal, cancel calls, persist cancelled,
8
8
  * no response
9
9
  *
@@ -17,9 +17,6 @@ type StatePersister = () => Promise<void>;
17
17
  export declare class ShutdownCoordinator {
18
18
  private state;
19
19
  private shuttingDown;
20
- private signalHandlersInstalled;
21
- private readonly boundHandleSignal;
22
- constructor();
23
20
  /**
24
21
  * Register the active session and abort controller for this run.
25
22
  * Call at the start of each workflow run.
@@ -41,13 +38,12 @@ export declare class ShutdownCoordinator {
41
38
  */
42
39
  cancelRun(): Promise<void>;
43
40
  /**
44
- * Handle SIGTERM/SIGINT.
45
- * Cancel, persist, terminate, exit.
41
+ * Handle process shutdown.
42
+ * Cancel, persist, and terminate. The entrypoint owns process.exit.
46
43
  */
47
- private handleSignalShutdown;
44
+ shutdown(signal: string): Promise<void>;
48
45
  private safePersistState;
49
46
  private safeTerminateSession;
50
- private installSignalHandlers;
51
47
  }
52
48
  /** Singleton shutdown coordinator. */
53
49
  export declare const shutdownCoordinator: ShutdownCoordinator;
@@ -2,8 +2,8 @@
2
2
  * Shutdown coordinator for clinkx-workflows.
3
3
  *
4
4
  * Handles:
5
- * - SIGTERM/SIGINT: cancel in-flight calls, persist state (best-effort),
6
- * terminate child, exit
5
+ * - process shutdown: cancel in-flight calls, persist state (best-effort),
6
+ * terminate child
7
7
  * - MCP cancellation: propagate AbortSignal, cancel calls, persist cancelled,
8
8
  * no response
9
9
  *
@@ -20,13 +20,6 @@ export class ShutdownCoordinator {
20
20
  persistState: null,
21
21
  };
22
22
  shuttingDown = false;
23
- signalHandlersInstalled = false;
24
- boundHandleSignal;
25
- constructor() {
26
- this.boundHandleSignal = (signal) => {
27
- void this.handleSignalShutdown(signal);
28
- };
29
- }
30
23
  /**
31
24
  * Register the active session and abort controller for this run.
32
25
  * Call at the start of each workflow run.
@@ -34,7 +27,6 @@ export class ShutdownCoordinator {
34
27
  register(session, controller, persistState) {
35
28
  this.state = { session, controller, persistState };
36
29
  this.shuttingDown = false;
37
- this.installSignalHandlers();
38
30
  }
39
31
  /**
40
32
  * Unregister the current run (on normal completion).
@@ -67,10 +59,10 @@ export class ShutdownCoordinator {
67
59
  await this.safeTerminateSession();
68
60
  }
69
61
  /**
70
- * Handle SIGTERM/SIGINT.
71
- * Cancel, persist, terminate, exit.
62
+ * Handle process shutdown.
63
+ * Cancel, persist, and terminate. The entrypoint owns process.exit.
72
64
  */
73
- async handleSignalShutdown(signal) {
65
+ async shutdown(signal) {
74
66
  if (this.shuttingDown) {
75
67
  logger.warn({ signal }, "duplicate shutdown signal ignored");
76
68
  return;
@@ -83,9 +75,7 @@ export class ShutdownCoordinator {
83
75
  await this.safePersistState();
84
76
  // 3. Terminate child session
85
77
  await this.safeTerminateSession();
86
- // 4. Exit
87
- logger.info({ signal }, "shutdown complete, exiting");
88
- process.exit(0);
78
+ logger.info({ signal }, "shutdown cleanup complete");
89
79
  }
90
80
  async safePersistState() {
91
81
  if (this.state.persistState == null)
@@ -107,13 +97,6 @@ export class ShutdownCoordinator {
107
97
  logger.error({ err: err instanceof Error ? err.message : String(err) }, "failed to terminate child session during shutdown");
108
98
  }
109
99
  }
110
- installSignalHandlers() {
111
- if (this.signalHandlersInstalled)
112
- return;
113
- this.signalHandlersInstalled = true;
114
- process.on("SIGTERM", () => this.boundHandleSignal("SIGTERM"));
115
- process.on("SIGINT", () => this.boundHandleSignal("SIGINT"));
116
- }
117
100
  }
118
101
  /** Singleton shutdown coordinator. */
119
102
  export const shutdownCoordinator = new ShutdownCoordinator();
@@ -1 +1 @@
1
- {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../src/shutdown.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../src/shutdown.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,17 @@
1
1
  import type { EngineHooks, EngineResumeState } from "./engine.js";
2
2
  import type { NormalizedWorkflowDefinition } from "./definition-normalizer.js";
3
3
  import type { RunState } from "./state-schema.js";
4
+ export type RunDirectoryClassification = "failed" | "cancelled" | "debug_kept" | "active_locked" | "running_or_pending" | "unknown";
5
+ export interface PruneRunDirectoriesOptions {
6
+ readonly retainFailedDays?: number | undefined;
7
+ readonly retainCancelledDays?: number | undefined;
8
+ readonly retainDebugDays?: number | undefined;
9
+ }
10
+ export interface PruneRunDirectoriesResult {
11
+ readonly pruned: number;
12
+ readonly skipped: number;
13
+ readonly errors: number;
14
+ }
4
15
  export interface CreateWorkflowStateOptions {
5
16
  readonly runId: string;
6
17
  readonly definition: NormalizedWorkflowDefinition;
@@ -13,6 +24,8 @@ export interface ResumeWorkflowStateOptions {
13
24
  readonly runDir?: string | undefined;
14
25
  readonly debugKeepArtifacts?: boolean | undefined;
15
26
  }
27
+ export declare function classifyRunDirectory(runDirPath: string): RunDirectoryClassification;
28
+ export declare function pruneRunDirectories(runsRootDir: string, options?: PruneRunDirectoriesOptions): Promise<PruneRunDirectoriesResult>;
16
29
  export declare class WorkflowStateStore {
17
30
  readonly runDir: string;
18
31
  readonly definition: NormalizedWorkflowDefinition;