@renseiai/agentfactory 0.8.19 → 0.8.21
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.
- package/dist/src/config/repository-config.d.ts +7 -0
- package/dist/src/config/repository-config.d.ts.map +1 -1
- package/dist/src/config/repository-config.js +15 -1
- package/dist/src/config/repository-config.test.js +1 -1
- package/dist/src/governor/decision-engine-adapter.js +5 -10
- package/dist/src/governor/decision-engine-adapter.test.js +13 -14
- package/dist/src/governor/decision-engine.js +3 -7
- package/dist/src/governor/decision-engine.test.js +5 -5
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/merge-queue/adapters/local.d.ts +68 -0
- package/dist/src/merge-queue/adapters/local.d.ts.map +1 -0
- package/dist/src/merge-queue/adapters/local.js +136 -0
- package/dist/src/merge-queue/adapters/local.test.d.ts +2 -0
- package/dist/src/merge-queue/adapters/local.test.d.ts.map +1 -0
- package/dist/src/merge-queue/adapters/local.test.js +176 -0
- package/dist/src/merge-queue/index.d.ts +13 -5
- package/dist/src/merge-queue/index.d.ts.map +1 -1
- package/dist/src/merge-queue/index.js +13 -6
- package/dist/src/merge-queue/merge-queue.integration.test.js +19 -0
- package/dist/src/merge-queue/merge-worker.d.ts.map +1 -1
- package/dist/src/merge-queue/merge-worker.js +29 -0
- package/dist/src/merge-queue/types.d.ts +1 -1
- package/dist/src/merge-queue/types.d.ts.map +1 -1
- package/dist/src/orchestrator/index.d.ts +4 -0
- package/dist/src/orchestrator/index.d.ts.map +1 -1
- package/dist/src/orchestrator/index.js +3 -0
- package/dist/src/orchestrator/orchestrator.d.ts +31 -0
- package/dist/src/orchestrator/orchestrator.d.ts.map +1 -1
- package/dist/src/orchestrator/orchestrator.js +263 -11
- package/dist/src/orchestrator/parse-work-result.d.ts.map +1 -1
- package/dist/src/orchestrator/parse-work-result.js +3 -1
- package/dist/src/orchestrator/parse-work-result.test.js +6 -0
- package/dist/src/orchestrator/quality-baseline.d.ts +83 -0
- package/dist/src/orchestrator/quality-baseline.d.ts.map +1 -0
- package/dist/src/orchestrator/quality-baseline.js +313 -0
- package/dist/src/orchestrator/quality-baseline.test.d.ts +2 -0
- package/dist/src/orchestrator/quality-baseline.test.d.ts.map +1 -0
- package/dist/src/orchestrator/quality-baseline.test.js +448 -0
- package/dist/src/orchestrator/quality-ratchet.d.ts +70 -0
- package/dist/src/orchestrator/quality-ratchet.d.ts.map +1 -0
- package/dist/src/orchestrator/quality-ratchet.js +162 -0
- package/dist/src/orchestrator/quality-ratchet.test.d.ts +2 -0
- package/dist/src/orchestrator/quality-ratchet.test.d.ts.map +1 -0
- package/dist/src/orchestrator/quality-ratchet.test.js +335 -0
- package/dist/src/orchestrator/types.d.ts +2 -0
- package/dist/src/orchestrator/types.d.ts.map +1 -1
- package/dist/src/providers/codex-app-server-provider.d.ts +37 -1
- package/dist/src/providers/codex-app-server-provider.d.ts.map +1 -1
- package/dist/src/providers/codex-app-server-provider.js +290 -35
- package/dist/src/providers/codex-app-server-provider.test.js +72 -12
- package/dist/src/providers/codex-approval-bridge.d.ts +49 -0
- package/dist/src/providers/codex-approval-bridge.d.ts.map +1 -0
- package/dist/src/providers/codex-approval-bridge.js +117 -0
- package/dist/src/providers/codex-approval-bridge.test.d.ts +2 -0
- package/dist/src/providers/codex-approval-bridge.test.d.ts.map +1 -0
- package/dist/src/providers/codex-approval-bridge.test.js +188 -0
- package/dist/src/providers/types.d.ts +25 -0
- package/dist/src/providers/types.d.ts.map +1 -1
- package/dist/src/routing/types.d.ts +1 -1
- package/dist/src/templates/adapters.d.ts +25 -0
- package/dist/src/templates/adapters.d.ts.map +1 -1
- package/dist/src/templates/adapters.js +70 -0
- package/dist/src/templates/adapters.test.js +49 -0
- package/dist/src/templates/index.d.ts +1 -0
- package/dist/src/templates/index.d.ts.map +1 -1
- package/dist/src/templates/registry.d.ts +8 -0
- package/dist/src/templates/registry.d.ts.map +1 -1
- package/dist/src/templates/registry.js +11 -0
- package/dist/src/templates/types.d.ts +22 -0
- package/dist/src/templates/types.d.ts.map +1 -1
- package/dist/src/templates/types.js +12 -0
- package/dist/src/tools/index.d.ts +2 -0
- package/dist/src/tools/index.d.ts.map +1 -1
- package/dist/src/tools/index.js +1 -0
- package/dist/src/tools/registry.d.ts +9 -1
- package/dist/src/tools/registry.d.ts.map +1 -1
- package/dist/src/tools/registry.js +13 -1
- package/dist/src/tools/stdio-server-entry.d.ts +25 -0
- package/dist/src/tools/stdio-server-entry.d.ts.map +1 -0
- package/dist/src/tools/stdio-server-entry.js +205 -0
- package/dist/src/tools/stdio-server.d.ts +87 -0
- package/dist/src/tools/stdio-server.d.ts.map +1 -0
- package/dist/src/tools/stdio-server.js +138 -0
- package/dist/src/workflow/workflow-types.d.ts +3 -3
- package/package.json +3 -2
|
@@ -114,6 +114,18 @@ export interface TemplateContext {
|
|
|
114
114
|
phaseOutputs?: Record<string, Record<string, unknown>>;
|
|
115
115
|
/** Linear project name for creating agent-improvement issues (from AGENT_BUG_BACKLOG env var) */
|
|
116
116
|
agentBugBacklog?: string;
|
|
117
|
+
/** When true, a merge queue (local or GitHub-native) handles rebase/merge — QA should not hard-fail on merge conflicts */
|
|
118
|
+
mergeQueueEnabled?: boolean;
|
|
119
|
+
/** Quality metrics baseline for delta checking. Injected by orchestrator when quality gates are enabled. */
|
|
120
|
+
qualityBaseline?: {
|
|
121
|
+
tests: {
|
|
122
|
+
total: number;
|
|
123
|
+
passed: number;
|
|
124
|
+
failed: number;
|
|
125
|
+
};
|
|
126
|
+
typecheckErrors: number;
|
|
127
|
+
lintErrors: number;
|
|
128
|
+
};
|
|
117
129
|
}
|
|
118
130
|
/**
|
|
119
131
|
* Translates abstract tool permissions to provider-native format.
|
|
@@ -231,6 +243,16 @@ export declare const TemplateContextSchema: z.ZodObject<{
|
|
|
231
243
|
validateCommand: z.ZodOptional<z.ZodString>;
|
|
232
244
|
phaseOutputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
233
245
|
agentBugBacklog: z.ZodOptional<z.ZodString>;
|
|
246
|
+
mergeQueueEnabled: z.ZodOptional<z.ZodBoolean>;
|
|
247
|
+
qualityBaseline: z.ZodOptional<z.ZodObject<{
|
|
248
|
+
tests: z.ZodObject<{
|
|
249
|
+
total: z.ZodNumber;
|
|
250
|
+
passed: z.ZodNumber;
|
|
251
|
+
failed: z.ZodNumber;
|
|
252
|
+
}, z.core.$strip>;
|
|
253
|
+
typecheckErrors: z.ZodNumber;
|
|
254
|
+
lintErrors: z.ZodNumber;
|
|
255
|
+
}, z.core.$strip>>;
|
|
234
256
|
}, z.core.$strip>;
|
|
235
257
|
/**
|
|
236
258
|
* Validate a parsed YAML object as a WorkflowTemplate.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/templates/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/templates/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -98,6 +98,18 @@ export const TemplateContextSchema = z.object({
|
|
|
98
98
|
phaseOutputs: z.record(z.string(), z.record(z.string(), z.unknown())).optional(),
|
|
99
99
|
// Agent improvement backlog
|
|
100
100
|
agentBugBacklog: z.string().optional(),
|
|
101
|
+
// Merge queue awareness
|
|
102
|
+
mergeQueueEnabled: z.boolean().optional(),
|
|
103
|
+
// Quality baseline (captured from main before agent starts)
|
|
104
|
+
qualityBaseline: z.object({
|
|
105
|
+
tests: z.object({
|
|
106
|
+
total: z.number().int().nonnegative(),
|
|
107
|
+
passed: z.number().int().nonnegative(),
|
|
108
|
+
failed: z.number().int().nonnegative(),
|
|
109
|
+
}),
|
|
110
|
+
typecheckErrors: z.number().int().nonnegative(),
|
|
111
|
+
lintErrors: z.number().int().nonnegative(),
|
|
112
|
+
}).optional(),
|
|
101
113
|
});
|
|
102
114
|
// ---------------------------------------------------------------------------
|
|
103
115
|
// Validation Helpers
|
|
@@ -3,4 +3,6 @@ export type { CreateServersResult } from './registry.js';
|
|
|
3
3
|
export type { ToolPlugin, ToolPluginContext } from './types.js';
|
|
4
4
|
export { classifyTool } from './tool-category.js';
|
|
5
5
|
export type { ToolCategory } from './tool-category.js';
|
|
6
|
+
export { createStdioServerConfigs, spawnStdioServer, } from './stdio-server.js';
|
|
7
|
+
export type { StdioMcpServerConfig, CreateStdioServersResult, StdioServerHandle, PluginBootstrap, } from './stdio-server.js';
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACxD,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACxD,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EACL,wBAAwB,EACxB,gBAAgB,GACjB,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,oBAAoB,EACpB,wBAAwB,EACxB,iBAAiB,EACjB,eAAe,GAChB,MAAM,mBAAmB,CAAA"}
|
package/dist/src/tools/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type McpSdkServerConfigWithInstance } from '@anthropic-ai/claude-agent-sdk';
|
|
2
2
|
import type { ToolPlugin, ToolPluginContext } from './types.js';
|
|
3
|
+
import { type CreateStdioServersResult } from './stdio-server.js';
|
|
3
4
|
export interface CreateServersResult {
|
|
4
5
|
servers: Record<string, McpSdkServerConfigWithInstance>;
|
|
5
6
|
/** Fully-qualified tool names: mcp__{serverName}__{toolName} */
|
|
@@ -8,7 +9,14 @@ export interface CreateServersResult {
|
|
|
8
9
|
export declare class ToolRegistry {
|
|
9
10
|
private plugins;
|
|
10
11
|
register(plugin: ToolPlugin): void;
|
|
11
|
-
/**
|
|
12
|
+
/** Get all registered plugins */
|
|
13
|
+
getPlugins(): ToolPlugin[];
|
|
14
|
+
/** Create in-process MCP servers for Claude provider */
|
|
12
15
|
createServers(context: ToolPluginContext): CreateServersResult;
|
|
16
|
+
/**
|
|
17
|
+
* Create stdio MCP server configurations for Codex provider (SUP-1743).
|
|
18
|
+
* Returns server configs that can be passed to Codex app-server via config/batchWrite.
|
|
19
|
+
*/
|
|
20
|
+
createStdioServerConfigs(context: ToolPluginContext): CreateStdioServersResult;
|
|
13
21
|
}
|
|
14
22
|
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,8BAA8B,EAAE,MAAM,gCAAgC,CAAA;AACxG,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,8BAA8B,EAAE,MAAM,gCAAgC,CAAA;AACxG,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,EAA4B,KAAK,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAE3F,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,8BAA8B,CAAC,CAAA;IACvD,gEAAgE;IAChE,SAAS,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAmB;IAElC,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAIlC,iCAAiC;IACjC,UAAU,IAAI,UAAU,EAAE;IAI1B,wDAAwD;IACxD,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,mBAAmB;IAe9D;;;OAGG;IACH,wBAAwB,CAAC,OAAO,EAAE,iBAAiB,GAAG,wBAAwB;CAG/E"}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { createSdkMcpServer } from '@anthropic-ai/claude-agent-sdk';
|
|
2
|
+
import { createStdioServerConfigs } from './stdio-server.js';
|
|
2
3
|
export class ToolRegistry {
|
|
3
4
|
plugins = [];
|
|
4
5
|
register(plugin) {
|
|
5
6
|
this.plugins.push(plugin);
|
|
6
7
|
}
|
|
7
|
-
/**
|
|
8
|
+
/** Get all registered plugins */
|
|
9
|
+
getPlugins() {
|
|
10
|
+
return [...this.plugins];
|
|
11
|
+
}
|
|
12
|
+
/** Create in-process MCP servers for Claude provider */
|
|
8
13
|
createServers(context) {
|
|
9
14
|
const servers = {};
|
|
10
15
|
const toolNames = [];
|
|
@@ -19,4 +24,11 @@ export class ToolRegistry {
|
|
|
19
24
|
}
|
|
20
25
|
return { servers, toolNames };
|
|
21
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Create stdio MCP server configurations for Codex provider (SUP-1743).
|
|
29
|
+
* Returns server configs that can be passed to Codex app-server via config/batchWrite.
|
|
30
|
+
*/
|
|
31
|
+
createStdioServerConfigs(context) {
|
|
32
|
+
return createStdioServerConfigs(this.plugins, context);
|
|
33
|
+
}
|
|
22
34
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Stdio MCP Server Entry Point (SUP-1743)
|
|
4
|
+
*
|
|
5
|
+
* This file is spawned as a child process by the orchestrator.
|
|
6
|
+
* It receives a PluginBootstrap message on stdin, then starts an
|
|
7
|
+
* @modelcontextprotocol/sdk McpServer with stdio transport, exposing
|
|
8
|
+
* the plugin's tools to any MCP client (e.g. Codex app-server).
|
|
9
|
+
*
|
|
10
|
+
* Protocol:
|
|
11
|
+
* 1. Parent sends JSON bootstrap message on first stdin line
|
|
12
|
+
* 2. Child creates McpServer with tool definitions from bootstrap
|
|
13
|
+
* 3. Child connects stdio transport — subsequent stdin/stdout is MCP protocol
|
|
14
|
+
*
|
|
15
|
+
* Tool handlers forward calls back to the parent via a simple
|
|
16
|
+
* request/response protocol over stderr (to avoid mixing with MCP on stdout).
|
|
17
|
+
* However, since the parent holds the ToolPlugin instances, we use a
|
|
18
|
+
* callback-based approach where the parent injects tool handlers.
|
|
19
|
+
*
|
|
20
|
+
* Simpler approach: The entry point re-creates the ToolPlugin from the
|
|
21
|
+
* plugin package and runs tools in-process. This means the child process
|
|
22
|
+
* has the same tool implementations as the parent.
|
|
23
|
+
*/
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=stdio-server-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio-server-entry.d.ts","sourceRoot":"","sources":["../../../src/tools/stdio-server-entry.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;GAqBG"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Stdio MCP Server Entry Point (SUP-1743)
|
|
4
|
+
*
|
|
5
|
+
* This file is spawned as a child process by the orchestrator.
|
|
6
|
+
* It receives a PluginBootstrap message on stdin, then starts an
|
|
7
|
+
* @modelcontextprotocol/sdk McpServer with stdio transport, exposing
|
|
8
|
+
* the plugin's tools to any MCP client (e.g. Codex app-server).
|
|
9
|
+
*
|
|
10
|
+
* Protocol:
|
|
11
|
+
* 1. Parent sends JSON bootstrap message on first stdin line
|
|
12
|
+
* 2. Child creates McpServer with tool definitions from bootstrap
|
|
13
|
+
* 3. Child connects stdio transport — subsequent stdin/stdout is MCP protocol
|
|
14
|
+
*
|
|
15
|
+
* Tool handlers forward calls back to the parent via a simple
|
|
16
|
+
* request/response protocol over stderr (to avoid mixing with MCP on stdout).
|
|
17
|
+
* However, since the parent holds the ToolPlugin instances, we use a
|
|
18
|
+
* callback-based approach where the parent injects tool handlers.
|
|
19
|
+
*
|
|
20
|
+
* Simpler approach: The entry point re-creates the ToolPlugin from the
|
|
21
|
+
* plugin package and runs tools in-process. This means the child process
|
|
22
|
+
* has the same tool implementations as the parent.
|
|
23
|
+
*/
|
|
24
|
+
import { createInterface } from 'node:readline';
|
|
25
|
+
// Dynamic imports for MCP SDK — these are peer dependencies
|
|
26
|
+
async function loadMcpSdk() {
|
|
27
|
+
const { McpServer } = await import('@modelcontextprotocol/sdk/server/mcp.js');
|
|
28
|
+
const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
30
|
+
const zod = await import('zod');
|
|
31
|
+
return { McpServer, StdioServerTransport, z: zod.z ?? zod };
|
|
32
|
+
}
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Bootstrap
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
async function main() {
|
|
37
|
+
// Read the bootstrap message from the first line of stdin
|
|
38
|
+
const bootstrap = await readBootstrap();
|
|
39
|
+
const { McpServer, StdioServerTransport, z } = await loadMcpSdk();
|
|
40
|
+
// Create the MCP server
|
|
41
|
+
const server = new McpServer({
|
|
42
|
+
name: bootstrap.pluginName,
|
|
43
|
+
version: '1.0.0',
|
|
44
|
+
});
|
|
45
|
+
// Load the actual plugin to get real tool handlers
|
|
46
|
+
const plugin = await loadPlugin(bootstrap.pluginName);
|
|
47
|
+
if (plugin) {
|
|
48
|
+
// We have the actual plugin — register real tool handlers
|
|
49
|
+
const tools = plugin.createTools(bootstrap.context);
|
|
50
|
+
for (const tool of tools) {
|
|
51
|
+
const inputSchema = extractZodSchema(tool, z);
|
|
52
|
+
server.tool(tool.name, tool.description ?? '', inputSchema, async (args) => {
|
|
53
|
+
try {
|
|
54
|
+
// Call the tool's handler directly
|
|
55
|
+
const result = await tool.handler(args);
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
return {
|
|
60
|
+
content: [{
|
|
61
|
+
type: 'text',
|
|
62
|
+
text: `Error: ${err instanceof Error ? err.message : String(err)}`,
|
|
63
|
+
}],
|
|
64
|
+
isError: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Fallback: register stub tools from serialized definitions
|
|
72
|
+
registerStubTools(server, bootstrap.tools, z);
|
|
73
|
+
}
|
|
74
|
+
// Connect stdio transport — from here, stdin/stdout is MCP protocol
|
|
75
|
+
const transport = new StdioServerTransport();
|
|
76
|
+
await server.connect(transport);
|
|
77
|
+
console.error(`[stdio-server:${bootstrap.pluginName}] MCP server ready with ${bootstrap.tools.length} tools`);
|
|
78
|
+
}
|
|
79
|
+
async function loadPlugin(name) {
|
|
80
|
+
// Try to import the plugin package based on naming convention
|
|
81
|
+
const pluginPackages = {
|
|
82
|
+
'af-linear': {
|
|
83
|
+
module: '@renseiai/agentfactory-linear/tools',
|
|
84
|
+
export: 'linearPlugin',
|
|
85
|
+
},
|
|
86
|
+
'af-code-intelligence': {
|
|
87
|
+
module: '@renseiai/agentfactory-code-intelligence/plugin',
|
|
88
|
+
export: 'codeIntelligencePlugin',
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
const pkg = pluginPackages[name];
|
|
92
|
+
if (!pkg)
|
|
93
|
+
return null;
|
|
94
|
+
try {
|
|
95
|
+
const mod = await import(pkg.module);
|
|
96
|
+
return mod[pkg.export] ?? null;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Plugin package not available in this process — fall back to stubs
|
|
100
|
+
console.error(`[stdio-server:${name}] Could not load plugin package, using stub handlers`);
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
// Zod Schema Extraction
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
/**
|
|
108
|
+
* Extract a Zod schema from an SDK tool definition for registration
|
|
109
|
+
* with @modelcontextprotocol/sdk McpServer.tool().
|
|
110
|
+
*/
|
|
111
|
+
function extractZodSchema(tool, z) {
|
|
112
|
+
// The SDK tool definitions may carry a zod schema or JSON Schema.
|
|
113
|
+
// For McpServer.tool(), we need a Zod schema object.
|
|
114
|
+
// Since tools from the SDK use z.string(), z.number(), etc., we try
|
|
115
|
+
// to extract the zod shape directly.
|
|
116
|
+
if (tool.inputSchema?.shape) {
|
|
117
|
+
return tool.inputSchema.shape;
|
|
118
|
+
}
|
|
119
|
+
// Fallback: return empty shape (no params)
|
|
120
|
+
return {};
|
|
121
|
+
}
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// Stub Tools (fallback when plugin package unavailable)
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
function registerStubTools(server, tools, z) {
|
|
126
|
+
for (const toolDef of tools) {
|
|
127
|
+
// Convert JSON Schema to basic Zod types
|
|
128
|
+
const zodSchema = jsonSchemaToZod(toolDef.inputSchema, z);
|
|
129
|
+
server.tool(toolDef.name, toolDef.description, zodSchema, async () => ({
|
|
130
|
+
content: [{
|
|
131
|
+
type: 'text',
|
|
132
|
+
text: 'Error: Tool handler not available. Plugin package could not be loaded in this process.',
|
|
133
|
+
}],
|
|
134
|
+
isError: true,
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function jsonSchemaToZod(schema, z) {
|
|
139
|
+
const properties = schema.properties;
|
|
140
|
+
if (!properties)
|
|
141
|
+
return {};
|
|
142
|
+
const required = new Set(schema.required ?? []);
|
|
143
|
+
const shape = {};
|
|
144
|
+
for (const [key, prop] of Object.entries(properties)) {
|
|
145
|
+
let zodType;
|
|
146
|
+
switch (prop.type) {
|
|
147
|
+
case 'string':
|
|
148
|
+
zodType = z.string();
|
|
149
|
+
break;
|
|
150
|
+
case 'number':
|
|
151
|
+
case 'integer':
|
|
152
|
+
zodType = z.number();
|
|
153
|
+
break;
|
|
154
|
+
case 'boolean':
|
|
155
|
+
zodType = z.boolean();
|
|
156
|
+
break;
|
|
157
|
+
case 'array':
|
|
158
|
+
zodType = z.array(z.any());
|
|
159
|
+
break;
|
|
160
|
+
default:
|
|
161
|
+
zodType = z.any();
|
|
162
|
+
}
|
|
163
|
+
if (prop.description) {
|
|
164
|
+
zodType = zodType.describe(prop.description);
|
|
165
|
+
}
|
|
166
|
+
if (!required.has(key)) {
|
|
167
|
+
zodType = zodType.optional();
|
|
168
|
+
}
|
|
169
|
+
shape[key] = zodType;
|
|
170
|
+
}
|
|
171
|
+
return shape;
|
|
172
|
+
}
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
// Bootstrap Reader
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
async function readBootstrap() {
|
|
177
|
+
return new Promise((resolve, reject) => {
|
|
178
|
+
const rl = createInterface({ input: process.stdin });
|
|
179
|
+
const timer = setTimeout(() => {
|
|
180
|
+
rl.close();
|
|
181
|
+
reject(new Error('Timeout waiting for bootstrap message'));
|
|
182
|
+
}, 10000);
|
|
183
|
+
rl.once('line', (line) => {
|
|
184
|
+
clearTimeout(timer);
|
|
185
|
+
rl.close();
|
|
186
|
+
try {
|
|
187
|
+
resolve(JSON.parse(line));
|
|
188
|
+
}
|
|
189
|
+
catch (err) {
|
|
190
|
+
reject(new Error(`Invalid bootstrap message: ${err}`));
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
rl.once('error', (err) => {
|
|
194
|
+
clearTimeout(timer);
|
|
195
|
+
reject(err);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
// ---------------------------------------------------------------------------
|
|
200
|
+
// Run
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
main().catch((err) => {
|
|
203
|
+
console.error(`[stdio-server] Fatal error: ${err.message}`);
|
|
204
|
+
process.exit(1);
|
|
205
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Stdio Server Abstraction Layer (SUP-1743)
|
|
3
|
+
*
|
|
4
|
+
* Converts ToolPlugin instances into standalone @modelcontextprotocol/sdk
|
|
5
|
+
* McpServer processes using stdio transport. This allows MCP clients like
|
|
6
|
+
* Codex to discover and invoke in-process tools (af_code_*, af_linear_*)
|
|
7
|
+
* through the standard MCP protocol over stdio.
|
|
8
|
+
*
|
|
9
|
+
* Architecture:
|
|
10
|
+
* ToolPlugin (in-process tools via @anthropic-ai/claude-agent-sdk)
|
|
11
|
+
* → StdioToolServer (standalone @modelcontextprotocol/sdk server)
|
|
12
|
+
* → Codex app-server (MCP client consuming tools)
|
|
13
|
+
*
|
|
14
|
+
* Each plugin becomes a separate stdio server child process so failures
|
|
15
|
+
* are isolated and Codex can manage them independently.
|
|
16
|
+
*/
|
|
17
|
+
import { type ChildProcess } from 'node:child_process';
|
|
18
|
+
import type { ToolPlugin, ToolPluginContext } from './types.js';
|
|
19
|
+
/** Configuration for a single stdio MCP server that Codex can consume */
|
|
20
|
+
export interface StdioMcpServerConfig {
|
|
21
|
+
/** Server name (matches plugin name, e.g. 'af-linear') */
|
|
22
|
+
name: string;
|
|
23
|
+
/** Command to spawn the server */
|
|
24
|
+
command: string;
|
|
25
|
+
/** Arguments to pass to the command */
|
|
26
|
+
args: string[];
|
|
27
|
+
/** Environment variables for the server process */
|
|
28
|
+
env: Record<string, string>;
|
|
29
|
+
/** Tool names provided by this server */
|
|
30
|
+
toolNames: string[];
|
|
31
|
+
}
|
|
32
|
+
/** Result from creating stdio server configs for all registered plugins */
|
|
33
|
+
export interface CreateStdioServersResult {
|
|
34
|
+
/** Per-server configurations keyed by plugin name */
|
|
35
|
+
servers: StdioMcpServerConfig[];
|
|
36
|
+
/** All tool names across all servers */
|
|
37
|
+
toolNames: string[];
|
|
38
|
+
}
|
|
39
|
+
/** A running stdio MCP server process */
|
|
40
|
+
export interface StdioServerHandle {
|
|
41
|
+
/** Plugin name */
|
|
42
|
+
name: string;
|
|
43
|
+
/** The child process */
|
|
44
|
+
process: ChildProcess;
|
|
45
|
+
/** Tool names served by this process */
|
|
46
|
+
toolNames: string[];
|
|
47
|
+
/** Stop the server */
|
|
48
|
+
stop(): Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Message protocol between parent (orchestrator) and stdio server child.
|
|
52
|
+
* The parent sends a JSON-serialized PluginBootstrap on the child's stdin
|
|
53
|
+
* on startup, then the child runs the MCP stdio transport loop.
|
|
54
|
+
*/
|
|
55
|
+
export interface PluginBootstrap {
|
|
56
|
+
/** Plugin name */
|
|
57
|
+
pluginName: string;
|
|
58
|
+
/** Serialized tool definitions (JSON-compatible subset) */
|
|
59
|
+
tools: SerializedToolDef[];
|
|
60
|
+
/** Plugin context for tool creation */
|
|
61
|
+
context: ToolPluginContext;
|
|
62
|
+
}
|
|
63
|
+
export interface SerializedToolDef {
|
|
64
|
+
name: string;
|
|
65
|
+
description: string;
|
|
66
|
+
inputSchema: Record<string, unknown>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create stdio MCP server configurations from ToolPlugin instances.
|
|
70
|
+
*
|
|
71
|
+
* This does NOT spawn processes — it returns the configuration that
|
|
72
|
+
* the Codex app-server needs to register and spawn the servers itself
|
|
73
|
+
* via `config/batchWrite`.
|
|
74
|
+
*
|
|
75
|
+
* The server entry point is `packages/core/src/tools/stdio-server-entry.ts`
|
|
76
|
+
* which is compiled to `dist/src/tools/stdio-server-entry.js`.
|
|
77
|
+
*/
|
|
78
|
+
export declare function createStdioServerConfigs(plugins: ToolPlugin[], context: ToolPluginContext): CreateStdioServersResult;
|
|
79
|
+
/**
|
|
80
|
+
* Spawn a stdio MCP server child process for a ToolPlugin.
|
|
81
|
+
*
|
|
82
|
+
* This is used by the orchestrator to create actual running servers
|
|
83
|
+
* that Codex can connect to. The child process runs the MCP protocol
|
|
84
|
+
* over its stdin/stdout.
|
|
85
|
+
*/
|
|
86
|
+
export declare function spawnStdioServer(plugin: ToolPlugin, context: ToolPluginContext): StdioServerHandle;
|
|
87
|
+
//# sourceMappingURL=stdio-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio-server.d.ts","sourceRoot":"","sources":["../../../src/tools/stdio-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAG7D,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAM/D,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACnC,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAA;IACZ,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,uCAAuC;IACvC,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3B,yCAAyC;IACzC,SAAS,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,2EAA2E;AAC3E,MAAM,WAAW,wBAAwB;IACvC,qDAAqD;IACrD,OAAO,EAAE,oBAAoB,EAAE,CAAA;IAC/B,wCAAwC;IACxC,SAAS,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,yCAAyC;AACzC,MAAM,WAAW,iBAAiB;IAChC,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,wBAAwB;IACxB,OAAO,EAAE,YAAY,CAAA;IACrB,wCAAwC;IACxC,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,sBAAsB;IACtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AAMD;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,KAAK,EAAE,iBAAiB,EAAE,CAAA;IAC1B,uCAAuC;IACvC,OAAO,EAAE,iBAAiB,CAAA;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC;AAMD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,iBAAiB,GACzB,wBAAwB,CAwB1B;AAmBD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,iBAAiB,GACzB,iBAAiB,CAoDnB"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Stdio Server Abstraction Layer (SUP-1743)
|
|
3
|
+
*
|
|
4
|
+
* Converts ToolPlugin instances into standalone @modelcontextprotocol/sdk
|
|
5
|
+
* McpServer processes using stdio transport. This allows MCP clients like
|
|
6
|
+
* Codex to discover and invoke in-process tools (af_code_*, af_linear_*)
|
|
7
|
+
* through the standard MCP protocol over stdio.
|
|
8
|
+
*
|
|
9
|
+
* Architecture:
|
|
10
|
+
* ToolPlugin (in-process tools via @anthropic-ai/claude-agent-sdk)
|
|
11
|
+
* → StdioToolServer (standalone @modelcontextprotocol/sdk server)
|
|
12
|
+
* → Codex app-server (MCP client consuming tools)
|
|
13
|
+
*
|
|
14
|
+
* Each plugin becomes a separate stdio server child process so failures
|
|
15
|
+
* are isolated and Codex can manage them independently.
|
|
16
|
+
*/
|
|
17
|
+
import { spawn } from 'node:child_process';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
import { dirname, join } from 'node:path';
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Registry Extension: Create stdio server configurations
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
/**
|
|
24
|
+
* Create stdio MCP server configurations from ToolPlugin instances.
|
|
25
|
+
*
|
|
26
|
+
* This does NOT spawn processes — it returns the configuration that
|
|
27
|
+
* the Codex app-server needs to register and spawn the servers itself
|
|
28
|
+
* via `config/batchWrite`.
|
|
29
|
+
*
|
|
30
|
+
* The server entry point is `packages/core/src/tools/stdio-server-entry.ts`
|
|
31
|
+
* which is compiled to `dist/src/tools/stdio-server-entry.js`.
|
|
32
|
+
*/
|
|
33
|
+
export function createStdioServerConfigs(plugins, context) {
|
|
34
|
+
const servers = [];
|
|
35
|
+
const allToolNames = [];
|
|
36
|
+
// Resolve path to the compiled server entry point
|
|
37
|
+
const entryPoint = resolveEntryPoint();
|
|
38
|
+
for (const plugin of plugins) {
|
|
39
|
+
const tools = plugin.createTools(context);
|
|
40
|
+
if (tools.length === 0)
|
|
41
|
+
continue;
|
|
42
|
+
const toolNames = tools.map(t => t.name);
|
|
43
|
+
allToolNames.push(...toolNames);
|
|
44
|
+
servers.push({
|
|
45
|
+
name: plugin.name,
|
|
46
|
+
command: 'node',
|
|
47
|
+
args: [entryPoint, '--plugin', plugin.name],
|
|
48
|
+
env: { ...context.env },
|
|
49
|
+
toolNames,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return { servers, toolNames: allToolNames };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Resolve the path to the compiled stdio server entry point.
|
|
56
|
+
* Works in both source (src/) and compiled (dist/) contexts.
|
|
57
|
+
*/
|
|
58
|
+
function resolveEntryPoint() {
|
|
59
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
60
|
+
const thisDir = dirname(thisFile);
|
|
61
|
+
// In compiled output: dist/src/tools/stdio-server.js → dist/src/tools/stdio-server-entry.js
|
|
62
|
+
// In source: src/tools/stdio-server.ts → need to compile first
|
|
63
|
+
return join(thisDir, 'stdio-server-entry.js');
|
|
64
|
+
}
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Spawn a stdio MCP server for a plugin
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
/**
|
|
69
|
+
* Spawn a stdio MCP server child process for a ToolPlugin.
|
|
70
|
+
*
|
|
71
|
+
* This is used by the orchestrator to create actual running servers
|
|
72
|
+
* that Codex can connect to. The child process runs the MCP protocol
|
|
73
|
+
* over its stdin/stdout.
|
|
74
|
+
*/
|
|
75
|
+
export function spawnStdioServer(plugin, context) {
|
|
76
|
+
const tools = plugin.createTools(context);
|
|
77
|
+
const toolNames = tools.map(t => t.name);
|
|
78
|
+
const entryPoint = resolveEntryPoint();
|
|
79
|
+
const child = spawn('node', [entryPoint, '--plugin', plugin.name], {
|
|
80
|
+
cwd: context.cwd,
|
|
81
|
+
env: { ...process.env, ...context.env },
|
|
82
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
83
|
+
});
|
|
84
|
+
// Send bootstrap message with serialized tool definitions
|
|
85
|
+
const bootstrap = {
|
|
86
|
+
pluginName: plugin.name,
|
|
87
|
+
tools: tools.map(t => ({
|
|
88
|
+
name: t.name,
|
|
89
|
+
description: t.description ?? '',
|
|
90
|
+
inputSchema: extractInputSchema(t),
|
|
91
|
+
})),
|
|
92
|
+
context,
|
|
93
|
+
};
|
|
94
|
+
child.stdin.write(JSON.stringify(bootstrap) + '\n');
|
|
95
|
+
child.on('error', (err) => {
|
|
96
|
+
console.error(`[stdio-server:${plugin.name}] Process error:`, err.message);
|
|
97
|
+
});
|
|
98
|
+
child.stderr?.on('data', (data) => {
|
|
99
|
+
const msg = data.toString().trim();
|
|
100
|
+
if (msg) {
|
|
101
|
+
console.error(`[stdio-server:${plugin.name}] ${msg}`);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
return {
|
|
105
|
+
name: plugin.name,
|
|
106
|
+
process: child,
|
|
107
|
+
toolNames,
|
|
108
|
+
async stop() {
|
|
109
|
+
if (!child.killed) {
|
|
110
|
+
child.kill('SIGTERM');
|
|
111
|
+
await new Promise((resolve) => {
|
|
112
|
+
child.once('exit', () => resolve());
|
|
113
|
+
setTimeout(() => {
|
|
114
|
+
if (!child.killed)
|
|
115
|
+
child.kill('SIGKILL');
|
|
116
|
+
resolve();
|
|
117
|
+
}, 3000);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Extract the JSON Schema input schema from an SDK tool definition.
|
|
125
|
+
* The SDK tool definitions use zod schemas internally, but expose
|
|
126
|
+
* a jsonSchema property for MCP protocol serialization.
|
|
127
|
+
*/
|
|
128
|
+
function extractInputSchema(tool) {
|
|
129
|
+
// The @anthropic-ai/claude-agent-sdk tool() function produces objects
|
|
130
|
+
// with an inputSchema property that is a JSON Schema object
|
|
131
|
+
if (tool.inputSchema && typeof tool.inputSchema === 'object') {
|
|
132
|
+
return tool.inputSchema;
|
|
133
|
+
}
|
|
134
|
+
if (tool.schema && typeof tool.schema === 'object') {
|
|
135
|
+
return tool.schema;
|
|
136
|
+
}
|
|
137
|
+
return { type: 'object', properties: {} };
|
|
138
|
+
}
|
|
@@ -701,9 +701,9 @@ export declare const WorkflowDefinitionSchema: z.ZodObject<{
|
|
|
701
701
|
export declare const WorkflowTriggerDefinitionSchema: z.ZodObject<{
|
|
702
702
|
name: z.ZodString;
|
|
703
703
|
type: z.ZodEnum<{
|
|
704
|
+
manual: "manual";
|
|
704
705
|
webhook: "webhook";
|
|
705
706
|
schedule: "schedule";
|
|
706
|
-
manual: "manual";
|
|
707
707
|
}>;
|
|
708
708
|
source: z.ZodOptional<z.ZodString>;
|
|
709
709
|
event: z.ZodOptional<z.ZodString>;
|
|
@@ -796,9 +796,9 @@ export declare const WorkflowDefinitionV2Schema: z.ZodObject<{
|
|
|
796
796
|
triggers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
797
797
|
name: z.ZodString;
|
|
798
798
|
type: z.ZodEnum<{
|
|
799
|
+
manual: "manual";
|
|
799
800
|
webhook: "webhook";
|
|
800
801
|
schedule: "schedule";
|
|
801
|
-
manual: "manual";
|
|
802
802
|
}>;
|
|
803
803
|
source: z.ZodOptional<z.ZodString>;
|
|
804
804
|
event: z.ZodOptional<z.ZodString>;
|
|
@@ -1131,9 +1131,9 @@ export declare const AnyWorkflowDefinitionSchema: z.ZodDiscriminatedUnion<[z.Zod
|
|
|
1131
1131
|
triggers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1132
1132
|
name: z.ZodString;
|
|
1133
1133
|
type: z.ZodEnum<{
|
|
1134
|
+
manual: "manual";
|
|
1134
1135
|
webhook: "webhook";
|
|
1135
1136
|
schedule: "schedule";
|
|
1136
|
-
manual: "manual";
|
|
1137
1137
|
}>;
|
|
1138
1138
|
source: z.ZodOptional<z.ZodString>;
|
|
1139
1139
|
event: z.ZodOptional<z.ZodString>;
|