@a5c-ai/babysitter-sdk 0.0.181-staging.a4ae8ca8 → 0.0.181-staging.e06e9e2d
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/cli/commands/mcpServe.d.ts +9 -0
- package/dist/cli/commands/mcpServe.d.ts.map +1 -0
- package/dist/cli/commands/mcpServe.js +31 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +6 -0
- package/dist/cli/mcpServeEntry.d.ts +3 -0
- package/dist/cli/mcpServeEntry.d.ts.map +1 -0
- package/dist/cli/mcpServeEntry.js +8 -0
- package/dist/mcp/index.d.ts +7 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +50 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +21 -0
- package/dist/mcp/tools/discovery.d.ts +3 -0
- package/dist/mcp/tools/discovery.d.ts.map +1 -0
- package/dist/mcp/tools/discovery.js +113 -0
- package/dist/mcp/tools/runs.d.ts +3 -0
- package/dist/mcp/tools/runs.d.ts.map +1 -0
- package/dist/mcp/tools/runs.js +273 -0
- package/dist/mcp/tools/sessions.d.ts +3 -0
- package/dist/mcp/tools/sessions.d.ts.map +1 -0
- package/dist/mcp/tools/sessions.js +219 -0
- package/dist/mcp/tools/tasks.d.ts +3 -0
- package/dist/mcp/tools/tasks.d.ts.map +1 -0
- package/dist/mcp/tools/tasks.js +230 -0
- package/dist/mcp/util/errors.d.ts +14 -0
- package/dist/mcp/util/errors.d.ts.map +1 -0
- package/dist/mcp/util/errors.js +10 -0
- package/dist/mcp/util/resolve-run-dir.d.ts +6 -0
- package/dist/mcp/util/resolve-run-dir.d.ts.map +1 -0
- package/dist/mcp/util/resolve-run-dir.js +47 -0
- package/package.json +4 -2
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mcp:serve command - Launch the babysitter MCP server on stdio transport.
|
|
3
|
+
*
|
|
4
|
+
* stdout is reserved for MCP protocol messages; all logging goes to stderr.
|
|
5
|
+
*/
|
|
6
|
+
export declare function handleMcpServe(args: {
|
|
7
|
+
json: boolean;
|
|
8
|
+
}): Promise<number>;
|
|
9
|
+
//# sourceMappingURL=mcpServe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpServe.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/mcpServe.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,wBAAsB,cAAc,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA0B7E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* mcp:serve command - Launch the babysitter MCP server on stdio transport.
|
|
4
|
+
*
|
|
5
|
+
* stdout is reserved for MCP protocol messages; all logging goes to stderr.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.handleMcpServe = handleMcpServe;
|
|
9
|
+
const mcp_1 = require("../../mcp");
|
|
10
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
11
|
+
async function handleMcpServe(args) {
|
|
12
|
+
const server = (0, mcp_1.createBabysitterMcpServer)();
|
|
13
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
14
|
+
await server.connect(transport);
|
|
15
|
+
process.stderr.write(args.json
|
|
16
|
+
? JSON.stringify({ status: "running", transport: "stdio" }) + "\n"
|
|
17
|
+
: "Babysitter MCP server running on stdio\n");
|
|
18
|
+
// Graceful shutdown on SIGINT / SIGTERM
|
|
19
|
+
const shutdown = async () => {
|
|
20
|
+
process.stderr.write("Shutting down MCP server...\n");
|
|
21
|
+
await server.close();
|
|
22
|
+
process.exit(0);
|
|
23
|
+
};
|
|
24
|
+
process.on("SIGINT", () => void shutdown());
|
|
25
|
+
process.on("SIGTERM", () => void shutdown());
|
|
26
|
+
// Keep the process alive — the transport manages its own I/O loop.
|
|
27
|
+
// Return a code that the CLI runner will never actually see (we exit via signal).
|
|
28
|
+
return await new Promise(() => {
|
|
29
|
+
// intentionally never resolves
|
|
30
|
+
});
|
|
31
|
+
}
|
package/dist/cli/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,sBAAsB,IAAI,6BAA6B,EAAoB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,sBAAsB,IAAI,6BAA6B,EAAoB,MAAM,oBAAoB,CAAC;AAqiB/G;;;;;;;;;GASG;AACH,iBAAS,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CA8BlE;AAOD,2EAA2E;AAC3E,QAAA,MAAM,sBAAsB,sCAAgC,CAAC;AA0+C7D,OAAO,EAAE,aAAa,IAAI,cAAc,EAAE,sBAAsB,IAAI,uBAAuB,EAAE,CAAC;AAE9F,wBAAgB,mBAAmB;eAEf,MAAM,EAAE,GAA2B,OAAO,CAAC,MAAM,CAAC;kBAgRpD,MAAM;EAIvB"}
|
package/dist/cli/main.js
CHANGED
|
@@ -56,6 +56,7 @@ const health_1 = require("./commands/health");
|
|
|
56
56
|
const configure_1 = require("./commands/configure");
|
|
57
57
|
const session_1 = require("./commands/session");
|
|
58
58
|
const skill_1 = require("./commands/skill");
|
|
59
|
+
const mcpServe_1 = require("./commands/mcpServe");
|
|
59
60
|
const hookLog_1 = require("./commands/hookLog");
|
|
60
61
|
const hookRun_1 = require("./commands/hookRun");
|
|
61
62
|
const profile_1 = require("./commands/profile");
|
|
@@ -101,6 +102,7 @@ const USAGE = `Usage:
|
|
|
101
102
|
babysitter plugin:update-marketplace --marketplace-name <name> [--marketplace-branch <ref>] [--global|--project] [--json] [--verbose]
|
|
102
103
|
babysitter plugin:update-registry [<pluginName>] [--plugin-name <name>] [--plugin-version <ver>] [--global|--project] [--json] [--verbose]
|
|
103
104
|
babysitter plugin:remove-from-registry [<pluginName>] [--plugin-name <name>] [--global|--project] [--json] [--verbose]
|
|
105
|
+
babysitter mcp:serve [--json]
|
|
104
106
|
babysitter health [--json] [--verbose]
|
|
105
107
|
babysitter configure [show|validate|paths] [--json] [--defaults-only]
|
|
106
108
|
babysitter version
|
|
@@ -1823,6 +1825,7 @@ const VALID_COMMANDS = [
|
|
|
1823
1825
|
"plugin:update-marketplace",
|
|
1824
1826
|
"plugin:update-registry",
|
|
1825
1827
|
"plugin:remove-from-registry",
|
|
1828
|
+
"mcp:serve",
|
|
1826
1829
|
"health",
|
|
1827
1830
|
"configure",
|
|
1828
1831
|
"version",
|
|
@@ -2132,6 +2135,9 @@ function createBabysitterCli() {
|
|
|
2132
2135
|
return await (0, plugin_1.handlePluginRemoveFromRegistry)(pluginArgs);
|
|
2133
2136
|
}
|
|
2134
2137
|
}
|
|
2138
|
+
if (parsed.command === "mcp:serve") {
|
|
2139
|
+
return await (0, mcpServe_1.handleMcpServe)({ json: parsed.json });
|
|
2140
|
+
}
|
|
2135
2141
|
if (parsed.command === "health") {
|
|
2136
2142
|
return await (0, health_1.handleHealthCommand)({
|
|
2137
2143
|
json: parsed.json,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpServeEntry.d.ts","sourceRoot":"","sources":["../../src/cli/mcpServeEntry.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const mcpServe_1 = require("./commands/mcpServe");
|
|
5
|
+
(0, mcpServe_1.handleMcpServe)({ json: false }).catch((err) => {
|
|
6
|
+
process.stderr.write(`Fatal: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
7
|
+
process.exit(1);
|
|
8
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { createBabysitterMcpServer } from "./server";
|
|
2
|
+
/**
|
|
3
|
+
* Start the MCP server on stdio transport.
|
|
4
|
+
* This is the main entry point for running the babysitter MCP server.
|
|
5
|
+
*/
|
|
6
|
+
export declare function startStdioServer(): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAErD;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKtD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.createBabysitterMcpServer = void 0;
|
|
37
|
+
exports.startStdioServer = startStdioServer;
|
|
38
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
39
|
+
var server_1 = require("./server");
|
|
40
|
+
Object.defineProperty(exports, "createBabysitterMcpServer", { enumerable: true, get: function () { return server_1.createBabysitterMcpServer; } });
|
|
41
|
+
/**
|
|
42
|
+
* Start the MCP server on stdio transport.
|
|
43
|
+
* This is the main entry point for running the babysitter MCP server.
|
|
44
|
+
*/
|
|
45
|
+
async function startStdioServer() {
|
|
46
|
+
const { createBabysitterMcpServer } = await Promise.resolve().then(() => __importStar(require("./server")));
|
|
47
|
+
const server = createBabysitterMcpServer();
|
|
48
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
49
|
+
await server.connect(transport);
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASpE,wBAAgB,yBAAyB,IAAI,SAAS,CAUrD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createBabysitterMcpServer = createBabysitterMcpServer;
|
|
4
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
5
|
+
const runs_1 = require("./tools/runs");
|
|
6
|
+
const tasks_1 = require("./tools/tasks");
|
|
7
|
+
const sessions_1 = require("./tools/sessions");
|
|
8
|
+
const discovery_1 = require("./tools/discovery");
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
10
|
+
const pkg = require("../../package.json");
|
|
11
|
+
function createBabysitterMcpServer() {
|
|
12
|
+
const server = new mcp_js_1.McpServer({
|
|
13
|
+
name: "babysitter",
|
|
14
|
+
version: pkg.version
|
|
15
|
+
});
|
|
16
|
+
(0, runs_1.registerRunTools)(server);
|
|
17
|
+
(0, tasks_1.registerTaskTools)(server);
|
|
18
|
+
(0, sessions_1.registerSessionTools)(server);
|
|
19
|
+
(0, discovery_1.registerDiscoveryTools)(server);
|
|
20
|
+
return server;
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/discovery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOpE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwF9D"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.registerDiscoveryTools = registerDiscoveryTools;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const zod_1 = require("zod");
|
|
39
|
+
const health_1 = require("../../cli/commands/health");
|
|
40
|
+
const configure_1 = require("../../cli/commands/configure");
|
|
41
|
+
const skill_1 = require("../../cli/commands/skill");
|
|
42
|
+
const errors_1 = require("../util/errors");
|
|
43
|
+
function registerDiscoveryTools(server) {
|
|
44
|
+
// ── skill_discover ──────────────────────────────────────────────────
|
|
45
|
+
server.tool("skill_discover", "Discover available skills, agents, and process definitions", {
|
|
46
|
+
pluginRoot: zod_1.z
|
|
47
|
+
.string()
|
|
48
|
+
.describe("Plugin root directory to scan for skills"),
|
|
49
|
+
runId: zod_1.z
|
|
50
|
+
.string()
|
|
51
|
+
.optional()
|
|
52
|
+
.describe("Run ID for domain-scoped discovery"),
|
|
53
|
+
runsDir: zod_1.z.string().optional().describe("Override runs directory path"),
|
|
54
|
+
includeRemote: zod_1.z
|
|
55
|
+
.boolean()
|
|
56
|
+
.optional()
|
|
57
|
+
.describe("Include remote skill sources"),
|
|
58
|
+
processPath: zod_1.z
|
|
59
|
+
.string()
|
|
60
|
+
.optional()
|
|
61
|
+
.describe("Process file path for specialization scoping"),
|
|
62
|
+
}, async (args) => {
|
|
63
|
+
try {
|
|
64
|
+
const pluginRoot = path.resolve(args.pluginRoot);
|
|
65
|
+
const result = await (0, skill_1.discoverSkillsInternal)({
|
|
66
|
+
pluginRoot,
|
|
67
|
+
runId: args.runId,
|
|
68
|
+
runsDir: args.runsDir,
|
|
69
|
+
includeRemote: args.includeRemote,
|
|
70
|
+
processPath: args.processPath,
|
|
71
|
+
includeProcesses: true,
|
|
72
|
+
});
|
|
73
|
+
return (0, errors_1.toolResult)({
|
|
74
|
+
skills: result.skills,
|
|
75
|
+
agents: result.agents,
|
|
76
|
+
processes: result.processes,
|
|
77
|
+
summary: result.summary,
|
|
78
|
+
cached: result.cached,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
// ── health ──────────────────────────────────────────────────────────
|
|
86
|
+
server.tool("health", "Check the health and configuration status of the babysitter installation", {}, async () => {
|
|
87
|
+
try {
|
|
88
|
+
const result = await (0, health_1.runHealthCheck)({ json: true });
|
|
89
|
+
return (0, errors_1.toolResult)({
|
|
90
|
+
status: result.status,
|
|
91
|
+
summary: result.summary,
|
|
92
|
+
checks: result.checks,
|
|
93
|
+
nextSteps: result.nextSteps,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
// ── configure_show ──────────────────────────────────────────────────
|
|
101
|
+
server.tool("configure_show", "Show current babysitter configuration and environment", {}, () => {
|
|
102
|
+
try {
|
|
103
|
+
const result = (0, configure_1.configureShow)({});
|
|
104
|
+
return (0, errors_1.toolResult)({
|
|
105
|
+
values: result.values,
|
|
106
|
+
timestamp: result.timestamp,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/runs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAuFpE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAiNxD"}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.registerRunTools = registerRunTools;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const zod_1 = require("zod");
|
|
39
|
+
const runtime_1 = require("../../runtime");
|
|
40
|
+
const storage_1 = require("../../storage");
|
|
41
|
+
const stateCache_1 = require("../../runtime/replay/stateCache");
|
|
42
|
+
const errors_1 = require("../util/errors");
|
|
43
|
+
const resolve_run_dir_1 = require("../util/resolve-run-dir");
|
|
44
|
+
/**
|
|
45
|
+
* Parse an entrypoint specifier like "path/to/file.js#exportName" into its parts.
|
|
46
|
+
*/
|
|
47
|
+
function parseEntrypoint(entrypoint) {
|
|
48
|
+
const hashIndex = entrypoint.lastIndexOf("#");
|
|
49
|
+
if (hashIndex <= 0) {
|
|
50
|
+
return { importPath: entrypoint };
|
|
51
|
+
}
|
|
52
|
+
const importPath = entrypoint.slice(0, hashIndex);
|
|
53
|
+
const exportName = entrypoint.slice(hashIndex + 1) || undefined;
|
|
54
|
+
return { importPath, exportName };
|
|
55
|
+
}
|
|
56
|
+
const RUN_LIFECYCLE_TYPES = new Set(["RUN_CREATED", "RUN_COMPLETED", "RUN_FAILED"]);
|
|
57
|
+
function findLastLifecycleEvent(events) {
|
|
58
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
59
|
+
if (RUN_LIFECYCLE_TYPES.has(events[i].type)) {
|
|
60
|
+
return events[i];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
function deriveRunState(lastLifecycleEventType, pendingCount) {
|
|
66
|
+
if (lastLifecycleEventType === "RUN_COMPLETED")
|
|
67
|
+
return "completed";
|
|
68
|
+
if (lastLifecycleEventType === "RUN_FAILED")
|
|
69
|
+
return "failed";
|
|
70
|
+
if (pendingCount > 0)
|
|
71
|
+
return "waiting";
|
|
72
|
+
return "created";
|
|
73
|
+
}
|
|
74
|
+
function countPendingEffects(events) {
|
|
75
|
+
const requested = new Map();
|
|
76
|
+
const resolved = new Set();
|
|
77
|
+
for (const event of events) {
|
|
78
|
+
if (event.type === "EFFECT_REQUESTED") {
|
|
79
|
+
const data = event.data;
|
|
80
|
+
if (data.effectId) {
|
|
81
|
+
requested.set(data.effectId, {
|
|
82
|
+
effectId: data.effectId,
|
|
83
|
+
kind: data.kind ?? "unknown",
|
|
84
|
+
label: data.label,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else if (event.type === "EFFECT_RESOLVED") {
|
|
89
|
+
const data = event.data;
|
|
90
|
+
if (data.effectId) {
|
|
91
|
+
resolved.add(data.effectId);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const pendingEffects = [];
|
|
96
|
+
const pendingByKind = {};
|
|
97
|
+
for (const [effectId, info] of requested) {
|
|
98
|
+
if (!resolved.has(effectId)) {
|
|
99
|
+
pendingEffects.push(info);
|
|
100
|
+
pendingByKind[info.kind] = (pendingByKind[info.kind] ?? 0) + 1;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return { pendingEffects, pendingByKind };
|
|
104
|
+
}
|
|
105
|
+
function registerRunTools(server) {
|
|
106
|
+
// ── run_create ──────────────────────────────────────────────────────
|
|
107
|
+
server.tool("run_create", "Create a new babysitter run for a given process definition", {
|
|
108
|
+
processId: zod_1.z.string().describe("The process identifier to run"),
|
|
109
|
+
entrypoint: zod_1.z.string().describe("Path to the process JS entrypoint file (optionally path#exportName)"),
|
|
110
|
+
inputs: zod_1.z.string().optional().describe("JSON-encoded inputs for the process"),
|
|
111
|
+
runsDir: zod_1.z.string().optional().describe("Override runs directory path"),
|
|
112
|
+
prompt: zod_1.z.string().optional().describe("Prompt or description for the run"),
|
|
113
|
+
}, async (args) => {
|
|
114
|
+
try {
|
|
115
|
+
const { importPath, exportName } = parseEntrypoint(args.entrypoint);
|
|
116
|
+
const absoluteImportPath = path.resolve(importPath);
|
|
117
|
+
const runsDir = (0, resolve_run_dir_1.resolveRunDir)(args.runsDir);
|
|
118
|
+
let inputs;
|
|
119
|
+
if (args.inputs) {
|
|
120
|
+
try {
|
|
121
|
+
inputs = JSON.parse(args.inputs);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return (0, errors_1.toolError)("Invalid JSON in inputs parameter");
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const result = await (0, runtime_1.createRun)({
|
|
128
|
+
runsDir,
|
|
129
|
+
process: {
|
|
130
|
+
processId: args.processId,
|
|
131
|
+
importPath: absoluteImportPath,
|
|
132
|
+
exportName,
|
|
133
|
+
},
|
|
134
|
+
prompt: args.prompt,
|
|
135
|
+
inputs,
|
|
136
|
+
});
|
|
137
|
+
return (0, errors_1.toolResult)({
|
|
138
|
+
runId: result.runId,
|
|
139
|
+
runDir: result.runDir,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
// ── run_status ──────────────────────────────────────────────────────
|
|
147
|
+
server.tool("run_status", "Get the current status and metadata of a run", {
|
|
148
|
+
runId: zod_1.z.string().describe("The run ID to query"),
|
|
149
|
+
runsDir: zod_1.z.string().optional().describe("Override runs directory path"),
|
|
150
|
+
}, async (args) => {
|
|
151
|
+
try {
|
|
152
|
+
const runsDir = (0, resolve_run_dir_1.resolveRunDir)(args.runsDir);
|
|
153
|
+
const runDir = path.join(runsDir, args.runId);
|
|
154
|
+
const metadata = await (0, storage_1.readRunMetadata)(runDir);
|
|
155
|
+
const journal = await (0, storage_1.loadJournal)(runDir);
|
|
156
|
+
const lastLifecycleEvent = findLastLifecycleEvent(journal);
|
|
157
|
+
const { pendingEffects, pendingByKind } = countPendingEffects(journal);
|
|
158
|
+
const state = deriveRunState(lastLifecycleEvent?.type, pendingEffects.length);
|
|
159
|
+
const completionProof = state === "completed" ? metadata.completionProof : undefined;
|
|
160
|
+
return (0, errors_1.toolResult)({
|
|
161
|
+
runId: metadata.runId,
|
|
162
|
+
processId: metadata.processId,
|
|
163
|
+
state,
|
|
164
|
+
pendingEffects,
|
|
165
|
+
pendingByKind,
|
|
166
|
+
completionProof: completionProof ?? null,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
// ── run_iterate ─────────────────────────────────────────────────────
|
|
174
|
+
server.tool("run_iterate", "Execute one orchestration iteration for a run", {
|
|
175
|
+
runId: zod_1.z.string().describe("The run ID to iterate"),
|
|
176
|
+
runsDir: zod_1.z.string().optional().describe("Override runs directory path"),
|
|
177
|
+
}, async (args) => {
|
|
178
|
+
try {
|
|
179
|
+
const runsDir = (0, resolve_run_dir_1.resolveRunDir)(args.runsDir);
|
|
180
|
+
const runDir = path.join(runsDir, args.runId);
|
|
181
|
+
const result = await (0, runtime_1.orchestrateIteration)({ runDir });
|
|
182
|
+
if (result.status === "completed") {
|
|
183
|
+
const metadata = await (0, storage_1.readRunMetadata)(runDir);
|
|
184
|
+
const completionProof = metadata.completionProof ?? null;
|
|
185
|
+
return (0, errors_1.toolResult)({
|
|
186
|
+
status: "completed",
|
|
187
|
+
output: result.output,
|
|
188
|
+
completionProof,
|
|
189
|
+
metadata: result.metadata,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (result.status === "failed") {
|
|
193
|
+
return (0, errors_1.toolResult)({
|
|
194
|
+
status: "failed",
|
|
195
|
+
error: result.error instanceof Error ? result.error.message : result.error,
|
|
196
|
+
metadata: result.metadata,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
// status === "waiting"
|
|
200
|
+
return (0, errors_1.toolResult)({
|
|
201
|
+
status: "waiting",
|
|
202
|
+
nextActions: result.nextActions.map((action) => ({
|
|
203
|
+
effectId: action.effectId,
|
|
204
|
+
kind: action.kind,
|
|
205
|
+
label: action.label,
|
|
206
|
+
labels: action.labels,
|
|
207
|
+
taskId: action.taskId,
|
|
208
|
+
stepId: action.stepId,
|
|
209
|
+
})),
|
|
210
|
+
metadata: result.metadata,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
// ── run_events ──────────────────────────────────────────────────────
|
|
218
|
+
server.tool("run_events", "List journal events for a run", {
|
|
219
|
+
runId: zod_1.z.string().describe("The run ID to query"),
|
|
220
|
+
runsDir: zod_1.z.string().optional().describe("Override runs directory path"),
|
|
221
|
+
limit: zod_1.z.number().optional().describe("Maximum number of events to return"),
|
|
222
|
+
filterType: zod_1.z.string().optional().describe("Filter events by type (e.g. EFFECT_REQUESTED)"),
|
|
223
|
+
reverse: zod_1.z.boolean().optional().describe("Return events in reverse chronological order"),
|
|
224
|
+
}, async (args) => {
|
|
225
|
+
try {
|
|
226
|
+
const runsDir = (0, resolve_run_dir_1.resolveRunDir)(args.runsDir);
|
|
227
|
+
const runDir = path.join(runsDir, args.runId);
|
|
228
|
+
const journal = await (0, storage_1.loadJournal)(runDir);
|
|
229
|
+
// Apply type filter
|
|
230
|
+
const filterType = args.filterType?.toUpperCase();
|
|
231
|
+
const filtered = filterType
|
|
232
|
+
? journal.filter((event) => event.type.toUpperCase() === filterType)
|
|
233
|
+
: journal;
|
|
234
|
+
// Apply ordering
|
|
235
|
+
const ordered = args.reverse ? filtered.slice().reverse() : filtered;
|
|
236
|
+
// Apply limit
|
|
237
|
+
const limited = args.limit !== undefined ? ordered.slice(0, args.limit) : ordered;
|
|
238
|
+
return (0, errors_1.toolResult)({
|
|
239
|
+
total: journal.length,
|
|
240
|
+
matching: filtered.length,
|
|
241
|
+
showing: limited.length,
|
|
242
|
+
events: limited.map((event) => ({
|
|
243
|
+
seq: event.seq,
|
|
244
|
+
type: event.type,
|
|
245
|
+
recordedAt: event.recordedAt,
|
|
246
|
+
data: event.data,
|
|
247
|
+
})),
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
// ── run_rebuild_state ───────────────────────────────────────────────
|
|
255
|
+
server.tool("run_rebuild_state", "Rebuild the state cache for a run from its journal", {
|
|
256
|
+
runId: zod_1.z.string().describe("The run ID to rebuild state for"),
|
|
257
|
+
runsDir: zod_1.z.string().optional().describe("Override runs directory path"),
|
|
258
|
+
}, async (args) => {
|
|
259
|
+
try {
|
|
260
|
+
const runsDir = (0, resolve_run_dir_1.resolveRunDir)(args.runsDir);
|
|
261
|
+
const runDir = path.join(runsDir, args.runId);
|
|
262
|
+
const snapshot = await (0, stateCache_1.rebuildStateCache)(runDir);
|
|
263
|
+
return (0, errors_1.toolResult)({
|
|
264
|
+
success: true,
|
|
265
|
+
stateVersion: snapshot.stateVersion,
|
|
266
|
+
journalHead: snapshot.journalHead,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
catch (err) {
|
|
270
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/sessions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAcpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4N5D"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.registerSessionTools = registerSessionTools;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const zod_1 = require("zod");
|
|
39
|
+
const session_1 = require("../../session");
|
|
40
|
+
const storage_1 = require("../../storage");
|
|
41
|
+
const errors_1 = require("../util/errors");
|
|
42
|
+
const resolve_run_dir_1 = require("../util/resolve-run-dir");
|
|
43
|
+
function registerSessionTools(server) {
|
|
44
|
+
// ── session_init ────────────────────────────────────────────────────
|
|
45
|
+
server.tool("session_init", "Initialize a new session state for orchestration", {
|
|
46
|
+
sessionId: zod_1.z.string().describe("The session ID to initialize"),
|
|
47
|
+
stateDir: zod_1.z.string().describe("Directory to store session state files"),
|
|
48
|
+
maxIterations: zod_1.z
|
|
49
|
+
.number()
|
|
50
|
+
.optional()
|
|
51
|
+
.describe("Maximum number of iterations (default 256)"),
|
|
52
|
+
runId: zod_1.z
|
|
53
|
+
.string()
|
|
54
|
+
.optional()
|
|
55
|
+
.describe("Optional run ID to associate immediately"),
|
|
56
|
+
prompt: zod_1.z
|
|
57
|
+
.string()
|
|
58
|
+
.optional()
|
|
59
|
+
.describe("Optional prompt text for the session"),
|
|
60
|
+
}, async (args) => {
|
|
61
|
+
try {
|
|
62
|
+
const stateDir = path.resolve(args.stateDir);
|
|
63
|
+
const maxIterations = args.maxIterations ?? 256;
|
|
64
|
+
const runId = args.runId ?? "";
|
|
65
|
+
const prompt = args.prompt ?? "";
|
|
66
|
+
const filePath = (0, session_1.getSessionFilePath)(stateDir, args.sessionId);
|
|
67
|
+
// Check for existing session
|
|
68
|
+
if (await (0, session_1.sessionFileExists)(filePath)) {
|
|
69
|
+
try {
|
|
70
|
+
const existing = await (0, session_1.readSessionFile)(filePath);
|
|
71
|
+
if (existing.state.runId) {
|
|
72
|
+
return (0, errors_1.toolError)(`Session already associated with run: ${existing.state.runId}`);
|
|
73
|
+
}
|
|
74
|
+
return (0, errors_1.toolError)("A babysitter run is already active for this session");
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return (0, errors_1.toolError)("Session state file exists but could not be read");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const now = (0, session_1.getCurrentTimestamp)();
|
|
81
|
+
const state = {
|
|
82
|
+
active: true,
|
|
83
|
+
iteration: 1,
|
|
84
|
+
maxIterations,
|
|
85
|
+
runId,
|
|
86
|
+
startedAt: now,
|
|
87
|
+
lastIterationAt: now,
|
|
88
|
+
iterationTimes: [],
|
|
89
|
+
};
|
|
90
|
+
await (0, session_1.writeSessionFile)(filePath, state, prompt);
|
|
91
|
+
return (0, errors_1.toolResult)({
|
|
92
|
+
stateFile: filePath,
|
|
93
|
+
iteration: state.iteration,
|
|
94
|
+
maxIterations: state.maxIterations,
|
|
95
|
+
runId: state.runId,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
// ── session_associate ───────────────────────────────────────────────
|
|
103
|
+
server.tool("session_associate", "Associate a session with a run ID", {
|
|
104
|
+
sessionId: zod_1.z.string().describe("The session ID to associate"),
|
|
105
|
+
stateDir: zod_1.z.string().describe("Directory containing session state files"),
|
|
106
|
+
runId: zod_1.z.string().describe("The run ID to associate with"),
|
|
107
|
+
}, async (args) => {
|
|
108
|
+
try {
|
|
109
|
+
const stateDir = path.resolve(args.stateDir);
|
|
110
|
+
const filePath = (0, session_1.getSessionFilePath)(stateDir, args.sessionId);
|
|
111
|
+
let existing;
|
|
112
|
+
try {
|
|
113
|
+
existing = await (0, session_1.readSessionFile)(filePath);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return (0, errors_1.toolError)(`No active session found. Expected state file: ${filePath}`);
|
|
117
|
+
}
|
|
118
|
+
if (existing.state.runId) {
|
|
119
|
+
return (0, errors_1.toolError)(`Session already associated with run: ${existing.state.runId}`);
|
|
120
|
+
}
|
|
121
|
+
const updatedState = {
|
|
122
|
+
...existing.state,
|
|
123
|
+
runId: args.runId,
|
|
124
|
+
};
|
|
125
|
+
await (0, session_1.writeSessionFile)(filePath, updatedState, existing.prompt);
|
|
126
|
+
return (0, errors_1.toolResult)({
|
|
127
|
+
stateFile: filePath,
|
|
128
|
+
runId: args.runId,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
// ── session_resume ──────────────────────────────────────────────────
|
|
136
|
+
server.tool("session_resume", "Resume an existing run in a new session", {
|
|
137
|
+
sessionId: zod_1.z.string().describe("The session ID for the new session"),
|
|
138
|
+
stateDir: zod_1.z.string().describe("Directory to store session state files"),
|
|
139
|
+
runId: zod_1.z.string().describe("The run ID to resume"),
|
|
140
|
+
maxIterations: zod_1.z
|
|
141
|
+
.number()
|
|
142
|
+
.optional()
|
|
143
|
+
.describe("Maximum number of iterations (default 256)"),
|
|
144
|
+
runsDir: zod_1.z.string().optional().describe("Override runs directory path"),
|
|
145
|
+
}, async (args) => {
|
|
146
|
+
try {
|
|
147
|
+
const stateDir = path.resolve(args.stateDir);
|
|
148
|
+
const runsDir = (0, resolve_run_dir_1.resolveRunDir)(args.runsDir);
|
|
149
|
+
const runDir = path.join(runsDir, args.runId);
|
|
150
|
+
const maxIterations = args.maxIterations ?? 256;
|
|
151
|
+
// Check run state from journal
|
|
152
|
+
let runState = "unknown";
|
|
153
|
+
try {
|
|
154
|
+
const journal = await (0, storage_1.loadJournal)(runDir);
|
|
155
|
+
const hasCompleted = journal.some((e) => e.type === "RUN_COMPLETED");
|
|
156
|
+
const hasFailed = journal.some((e) => e.type === "RUN_FAILED");
|
|
157
|
+
if (hasCompleted)
|
|
158
|
+
runState = "completed";
|
|
159
|
+
else if (hasFailed)
|
|
160
|
+
runState = "failed";
|
|
161
|
+
else
|
|
162
|
+
runState = "waiting";
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return (0, errors_1.toolError)(`Run not found: ${args.runId}`);
|
|
166
|
+
}
|
|
167
|
+
if (runState === "completed") {
|
|
168
|
+
return (0, errors_1.toolError)(`Run is already completed. Cannot resume a completed run.`);
|
|
169
|
+
}
|
|
170
|
+
const filePath = (0, session_1.getSessionFilePath)(stateDir, args.sessionId);
|
|
171
|
+
const prompt = `Resume Babysitter run: ${args.runId}\nCurrent state: ${runState}\nContinue orchestration using run:iterate, task:post, etc.`;
|
|
172
|
+
const now = (0, session_1.getCurrentTimestamp)();
|
|
173
|
+
const state = {
|
|
174
|
+
active: true,
|
|
175
|
+
iteration: 1,
|
|
176
|
+
maxIterations,
|
|
177
|
+
runId: args.runId,
|
|
178
|
+
startedAt: now,
|
|
179
|
+
lastIterationAt: now,
|
|
180
|
+
iterationTimes: [],
|
|
181
|
+
};
|
|
182
|
+
await (0, session_1.writeSessionFile)(filePath, state, prompt);
|
|
183
|
+
return (0, errors_1.toolResult)({
|
|
184
|
+
stateFile: filePath,
|
|
185
|
+
runId: args.runId,
|
|
186
|
+
runState,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
catch (err) {
|
|
190
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
// ── session_state ───────────────────────────────────────────────────
|
|
194
|
+
server.tool("session_state", "Get the current state of a session", {
|
|
195
|
+
sessionId: zod_1.z.string().describe("The session ID to query"),
|
|
196
|
+
stateDir: zod_1.z.string().describe("Directory containing session state files"),
|
|
197
|
+
}, async (args) => {
|
|
198
|
+
try {
|
|
199
|
+
const stateDir = path.resolve(args.stateDir);
|
|
200
|
+
const filePath = (0, session_1.getSessionFilePath)(stateDir, args.sessionId);
|
|
201
|
+
if (!(await (0, session_1.sessionFileExists)(filePath))) {
|
|
202
|
+
return (0, errors_1.toolResult)({
|
|
203
|
+
found: false,
|
|
204
|
+
stateFile: filePath,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
const file = await (0, session_1.readSessionFile)(filePath);
|
|
208
|
+
return (0, errors_1.toolResult)({
|
|
209
|
+
found: true,
|
|
210
|
+
state: file.state,
|
|
211
|
+
prompt: file.prompt,
|
|
212
|
+
stateFile: filePath,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/tasks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAqFpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0KzD"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.registerTaskTools = registerTaskTools;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const zod_1 = require("zod");
|
|
39
|
+
const commitEffectResult_1 = require("../../runtime/commitEffectResult");
|
|
40
|
+
const storage_1 = require("../../storage");
|
|
41
|
+
const tasks_1 = require("../../storage/tasks");
|
|
42
|
+
const errors_1 = require("../util/errors");
|
|
43
|
+
const resolve_run_dir_1 = require("../util/resolve-run-dir");
|
|
44
|
+
/**
|
|
45
|
+
* Build a task list from journal events by tracking EFFECT_REQUESTED and
|
|
46
|
+
* EFFECT_RESOLVED events.
|
|
47
|
+
*/
|
|
48
|
+
function buildTaskList(events) {
|
|
49
|
+
const requested = new Map();
|
|
50
|
+
const resolved = new Map();
|
|
51
|
+
for (const event of events) {
|
|
52
|
+
if (event.type === "EFFECT_REQUESTED") {
|
|
53
|
+
const data = event.data;
|
|
54
|
+
if (data.effectId) {
|
|
55
|
+
requested.set(data.effectId, {
|
|
56
|
+
effectId: data.effectId,
|
|
57
|
+
kind: data.kind ?? "unknown",
|
|
58
|
+
label: data.label,
|
|
59
|
+
taskId: data.taskId,
|
|
60
|
+
requestedAt: event.recordedAt,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (event.type === "EFFECT_RESOLVED") {
|
|
65
|
+
const data = event.data;
|
|
66
|
+
if (data.effectId) {
|
|
67
|
+
resolved.set(data.effectId, { resolvedAt: event.recordedAt });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const tasks = [];
|
|
72
|
+
for (const [effectId, info] of requested) {
|
|
73
|
+
const resolvedInfo = resolved.get(effectId);
|
|
74
|
+
tasks.push({
|
|
75
|
+
effectId,
|
|
76
|
+
kind: info.kind,
|
|
77
|
+
status: resolvedInfo ? "resolved" : "pending",
|
|
78
|
+
label: info.label,
|
|
79
|
+
taskId: info.taskId,
|
|
80
|
+
requestedAt: info.requestedAt,
|
|
81
|
+
resolvedAt: resolvedInfo?.resolvedAt,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return tasks.sort((a, b) => a.effectId.localeCompare(b.effectId));
|
|
85
|
+
}
|
|
86
|
+
function registerTaskTools(server) {
|
|
87
|
+
// ── task_post ───────────────────────────────────────────────────────
|
|
88
|
+
server.tool("task_post", "Post a result for a pending task effect", {
|
|
89
|
+
runId: zod_1.z.string().describe("The run ID the task belongs to"),
|
|
90
|
+
effectId: zod_1.z.string().describe("The effect ID of the task to resolve"),
|
|
91
|
+
status: zod_1.z
|
|
92
|
+
.enum(["ok", "error"])
|
|
93
|
+
.describe("Result status: ok for success, error for failure"),
|
|
94
|
+
value: zod_1.z
|
|
95
|
+
.string()
|
|
96
|
+
.optional()
|
|
97
|
+
.describe("JSON-encoded result value (when status=ok)"),
|
|
98
|
+
error: zod_1.z
|
|
99
|
+
.string()
|
|
100
|
+
.optional()
|
|
101
|
+
.describe("JSON-encoded error payload (when status=error)"),
|
|
102
|
+
runsDir: zod_1.z.string().optional().describe("Override runs directory path"),
|
|
103
|
+
}, async (args) => {
|
|
104
|
+
try {
|
|
105
|
+
const runsDir = (0, resolve_run_dir_1.resolveRunDir)(args.runsDir);
|
|
106
|
+
const runDir = path.join(runsDir, args.runId);
|
|
107
|
+
let value;
|
|
108
|
+
let errorPayload;
|
|
109
|
+
if (args.status === "ok" && args.value) {
|
|
110
|
+
try {
|
|
111
|
+
value = JSON.parse(args.value);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return (0, errors_1.toolError)("Invalid JSON in value parameter");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (args.status === "error") {
|
|
118
|
+
if (args.error) {
|
|
119
|
+
try {
|
|
120
|
+
errorPayload = JSON.parse(args.error);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return (0, errors_1.toolError)("Invalid JSON in error parameter");
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
errorPayload = { name: "Error", message: "Task reported failure" };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const nowIso = new Date().toISOString();
|
|
131
|
+
const committed = await (0, commitEffectResult_1.commitEffectResult)({
|
|
132
|
+
runDir,
|
|
133
|
+
effectId: args.effectId,
|
|
134
|
+
result: args.status === "ok"
|
|
135
|
+
? {
|
|
136
|
+
status: "ok",
|
|
137
|
+
value,
|
|
138
|
+
startedAt: nowIso,
|
|
139
|
+
finishedAt: nowIso,
|
|
140
|
+
}
|
|
141
|
+
: {
|
|
142
|
+
status: "error",
|
|
143
|
+
error: errorPayload,
|
|
144
|
+
startedAt: nowIso,
|
|
145
|
+
finishedAt: nowIso,
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
return (0, errors_1.toolResult)({
|
|
149
|
+
status: args.status,
|
|
150
|
+
effectId: args.effectId,
|
|
151
|
+
resultRef: committed.resultRef ?? null,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
// ── task_list ───────────────────────────────────────────────────────
|
|
159
|
+
server.tool("task_list", "List all tasks for a run, optionally showing only pending tasks", {
|
|
160
|
+
runId: zod_1.z.string().describe("The run ID to list tasks for"),
|
|
161
|
+
pendingOnly: zod_1.z
|
|
162
|
+
.boolean()
|
|
163
|
+
.optional()
|
|
164
|
+
.describe("If true, only show pending (unresolved) tasks"),
|
|
165
|
+
runsDir: zod_1.z.string().optional().describe("Override runs directory path"),
|
|
166
|
+
}, async (args) => {
|
|
167
|
+
try {
|
|
168
|
+
const runsDir = (0, resolve_run_dir_1.resolveRunDir)(args.runsDir);
|
|
169
|
+
const runDir = path.join(runsDir, args.runId);
|
|
170
|
+
const journal = await (0, storage_1.loadJournal)(runDir);
|
|
171
|
+
const allTasks = buildTaskList(journal);
|
|
172
|
+
const tasks = args.pendingOnly
|
|
173
|
+
? allTasks.filter((t) => t.status === "pending")
|
|
174
|
+
: allTasks;
|
|
175
|
+
return (0, errors_1.toolResult)({
|
|
176
|
+
total: allTasks.length,
|
|
177
|
+
showing: tasks.length,
|
|
178
|
+
pendingCount: allTasks.filter((t) => t.status === "pending").length,
|
|
179
|
+
tasks,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
// ── task_show ───────────────────────────────────────────────────────
|
|
187
|
+
server.tool("task_show", "Show details of a specific task including its definition and result", {
|
|
188
|
+
runId: zod_1.z.string().describe("The run ID the task belongs to"),
|
|
189
|
+
effectId: zod_1.z.string().describe("The effect ID of the task"),
|
|
190
|
+
runsDir: zod_1.z.string().optional().describe("Override runs directory path"),
|
|
191
|
+
}, async (args) => {
|
|
192
|
+
try {
|
|
193
|
+
const runsDir = (0, resolve_run_dir_1.resolveRunDir)(args.runsDir);
|
|
194
|
+
const runDir = path.join(runsDir, args.runId);
|
|
195
|
+
// Get task status from journal
|
|
196
|
+
const journal = await (0, storage_1.loadJournal)(runDir);
|
|
197
|
+
const allTasks = buildTaskList(journal);
|
|
198
|
+
const taskEntry = allTasks.find((t) => t.effectId === args.effectId);
|
|
199
|
+
if (!taskEntry) {
|
|
200
|
+
return (0, errors_1.toolError)(`Effect ${args.effectId} not found in run ${args.runId}`);
|
|
201
|
+
}
|
|
202
|
+
// Read task definition
|
|
203
|
+
let taskDef = null;
|
|
204
|
+
try {
|
|
205
|
+
taskDef = await (0, tasks_1.readTaskDefinition)(runDir, args.effectId);
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
// Task definition might not exist yet
|
|
209
|
+
}
|
|
210
|
+
// Read task result if resolved
|
|
211
|
+
let taskResultData = null;
|
|
212
|
+
if (taskEntry.status === "resolved") {
|
|
213
|
+
try {
|
|
214
|
+
taskResultData = await (0, tasks_1.readTaskResult)(runDir, args.effectId);
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// Result file might not be readable
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return (0, errors_1.toolResult)({
|
|
221
|
+
effect: taskEntry,
|
|
222
|
+
task: taskDef,
|
|
223
|
+
result: taskResultData,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
catch (err) {
|
|
227
|
+
return (0, errors_1.toolError)(err instanceof Error ? err.message : String(err));
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function toolError(message: string): {
|
|
2
|
+
content: Array<{
|
|
3
|
+
type: "text";
|
|
4
|
+
text: string;
|
|
5
|
+
}>;
|
|
6
|
+
isError: true;
|
|
7
|
+
};
|
|
8
|
+
export declare function toolResult(data: unknown): {
|
|
9
|
+
content: Array<{
|
|
10
|
+
type: "text";
|
|
11
|
+
text: string;
|
|
12
|
+
}>;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/mcp/util/errors.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,CAE5G;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAE5F"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toolError = toolError;
|
|
4
|
+
exports.toolResult = toolResult;
|
|
5
|
+
function toolError(message) {
|
|
6
|
+
return { content: [{ type: "text", text: JSON.stringify({ error: message }) }], isError: true };
|
|
7
|
+
}
|
|
8
|
+
function toolResult(data) {
|
|
9
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-run-dir.d.ts","sourceRoot":"","sources":["../../../src/mcp/util/resolve-run-dir.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAK3D"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.resolveRunDir = resolveRunDir;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
/**
|
|
39
|
+
* Resolves the runs directory, defaulting to `.a5c/runs` under cwd.
|
|
40
|
+
* Accepts an optional override (e.g. from tool args or env).
|
|
41
|
+
*/
|
|
42
|
+
function resolveRunDir(overridePath) {
|
|
43
|
+
if (overridePath) {
|
|
44
|
+
return path.resolve(overridePath);
|
|
45
|
+
}
|
|
46
|
+
return path.resolve(process.env["BABYSITTER_RUNS_DIR"] ?? path.join(process.cwd(), ".a5c", "runs"));
|
|
47
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a5c-ai/babysitter-sdk",
|
|
3
|
-
"version": "0.0.181-staging.
|
|
3
|
+
"version": "0.0.181-staging.e06e9e2d",
|
|
4
4
|
"description": "Storage and run-registry primitives for event-sourced babysitter workflows.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "commonjs",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
9
|
"bin": {
|
|
10
|
-
"babysitter": "dist/cli/main.js"
|
|
10
|
+
"babysitter": "dist/cli/main.js",
|
|
11
|
+
"babysitter-mcp-server": "dist/cli/mcpServeEntry.js"
|
|
11
12
|
},
|
|
12
13
|
"files": [
|
|
13
14
|
"dist",
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
"smoke:cli": "node scripts/smoke-cli.js --runs-dir packages/sdk/test-fixtures/cli/runs/smoke"
|
|
23
24
|
},
|
|
24
25
|
"dependencies": {
|
|
26
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
25
27
|
"fs-extra": "^11.2.0",
|
|
26
28
|
"ulid": "^2.3.0"
|
|
27
29
|
},
|