@a5c-ai/tula 5.0.1-staging.daf8e165bc4a
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/README.md +34 -0
- package/dist/cli/amuxEventsFormatter.d.ts +26 -0
- package/dist/cli/amuxEventsFormatter.d.ts.map +1 -0
- package/dist/cli/amuxEventsFormatter.js +86 -0
- package/dist/cli/args/argFlags.d.ts +6 -0
- package/dist/cli/args/argFlags.d.ts.map +1 -0
- package/dist/cli/args/argFlags.js +72 -0
- package/dist/cli/args/argPositionals.d.ts +3 -0
- package/dist/cli/args/argPositionals.d.ts.map +1 -0
- package/dist/cli/args/argPositionals.js +18 -0
- package/dist/cli/args/index.d.ts +4 -0
- package/dist/cli/args/index.d.ts.map +1 -0
- package/dist/cli/args/index.js +75 -0
- package/dist/cli/args/types.d.ts +13 -0
- package/dist/cli/args/types.d.ts.map +1 -0
- package/dist/cli/args/types.js +2 -0
- package/dist/cli/commands/daemon.d.ts +31 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -0
- package/dist/cli/commands/daemon.js +156 -0
- package/dist/cli/commands/harness/createRun.d.ts +3 -0
- package/dist/cli/commands/harness/createRun.d.ts.map +1 -0
- package/dist/cli/commands/harness/createRun.js +8 -0
- package/dist/cli/commands/harness/resumeRun.d.ts +20 -0
- package/dist/cli/commands/harness/resumeRun.d.ts.map +1 -0
- package/dist/cli/commands/harness/resumeRun.js +341 -0
- package/dist/cli/commands/jsonlInteractive.d.ts +35 -0
- package/dist/cli/commands/jsonlInteractive.d.ts.map +1 -0
- package/dist/cli/commands/jsonlInteractive.js +302 -0
- package/dist/cli/commands/mcpServe.d.ts +18 -0
- package/dist/cli/commands/mcpServe.d.ts.map +1 -0
- package/dist/cli/commands/mcpServe.js +59 -0
- package/dist/cli/commands/session/history.d.ts +14 -0
- package/dist/cli/commands/session/history.d.ts.map +1 -0
- package/dist/cli/commands/session/history.js +100 -0
- package/dist/cli/commands/tui.d.ts +23 -0
- package/dist/cli/commands/tui.d.ts.map +1 -0
- package/dist/cli/commands/tui.js +183 -0
- package/dist/cli/dispatch.d.ts +4 -0
- package/dist/cli/dispatch.d.ts.map +1 -0
- package/dist/cli/dispatch.js +348 -0
- package/dist/cli/main.d.ts +7 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +41 -0
- package/dist/cli/program.d.ts +7 -0
- package/dist/cli/program.d.ts.map +1 -0
- package/dist/cli/program.js +8 -0
- package/dist/cli/ui.d.ts +9 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/ui.js +125 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/prompts/commandTemplates.d.ts +3 -0
- package/dist/prompts/commandTemplates.d.ts.map +1 -0
- package/dist/prompts/commandTemplates.js +238 -0
- package/package.json +76 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* start-server command - Launch the babysitter MCP server on stdio or WebSocket 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
|
+
transport?: string;
|
|
9
|
+
port?: number;
|
|
10
|
+
host?: string;
|
|
11
|
+
authToken?: string;
|
|
12
|
+
wsOptions?: {
|
|
13
|
+
pingIntervalMs?: number;
|
|
14
|
+
maxMessagesPerSecond?: number;
|
|
15
|
+
sessionGracePeriodMs?: number;
|
|
16
|
+
};
|
|
17
|
+
}): Promise<number>;
|
|
18
|
+
//# 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;AAWH,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE;QACV,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC;CACH,GAAG,OAAO,CAAC,MAAM,CAAC,CAwDlB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* start-server command - Launch the babysitter MCP server on stdio or WebSocket 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 babysitter_sdk_1 = require("@a5c-ai/babysitter-sdk");
|
|
10
|
+
const transport_1 = require("@a5c-ai/agent-platform/mcp/transport");
|
|
11
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
12
|
+
function installShutdownHandlers(shutdownFn) {
|
|
13
|
+
process.on("SIGINT", () => void shutdownFn());
|
|
14
|
+
process.on("SIGTERM", () => void shutdownFn());
|
|
15
|
+
}
|
|
16
|
+
async function handleMcpServe(args) {
|
|
17
|
+
const transportType = args.transport ?? "stdio";
|
|
18
|
+
if (transportType === "ws" || transportType === "websocket") {
|
|
19
|
+
const wsTransport = await (0, transport_1.createWebSocketTransport)({
|
|
20
|
+
port: args.port ?? 9600,
|
|
21
|
+
host: args.host ?? "127.0.0.1",
|
|
22
|
+
authToken: args.authToken,
|
|
23
|
+
pingIntervalMs: args.wsOptions?.pingIntervalMs,
|
|
24
|
+
maxMessagesPerSecond: args.wsOptions?.maxMessagesPerSecond,
|
|
25
|
+
sessionGracePeriodMs: args.wsOptions?.sessionGracePeriodMs,
|
|
26
|
+
});
|
|
27
|
+
// Each new WebSocket connection gets its own McpServer instance
|
|
28
|
+
wsTransport.onconnection = (connectionTransport) => {
|
|
29
|
+
const server = (0, babysitter_sdk_1.createBabysitterMcpServer)();
|
|
30
|
+
void server.connect(connectionTransport);
|
|
31
|
+
};
|
|
32
|
+
process.stderr.write(args.json
|
|
33
|
+
? JSON.stringify({
|
|
34
|
+
status: "running",
|
|
35
|
+
transport: "websocket",
|
|
36
|
+
port: wsTransport.port,
|
|
37
|
+
}) + "\n"
|
|
38
|
+
: `Babysitter MCP server running on WebSocket port ${wsTransport.port}\n`);
|
|
39
|
+
installShutdownHandlers(async () => {
|
|
40
|
+
process.stderr.write("Shutting down MCP server...\n");
|
|
41
|
+
await wsTransport.close();
|
|
42
|
+
process.exit(0);
|
|
43
|
+
});
|
|
44
|
+
return await new Promise(() => { });
|
|
45
|
+
}
|
|
46
|
+
// Default: stdio transport
|
|
47
|
+
const server = (0, babysitter_sdk_1.createBabysitterMcpServer)();
|
|
48
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
49
|
+
await server.connect(transport);
|
|
50
|
+
process.stderr.write(args.json
|
|
51
|
+
? JSON.stringify({ status: "running", transport: "stdio" }) + "\n"
|
|
52
|
+
: "Babysitter MCP server running on stdio\n");
|
|
53
|
+
installShutdownHandlers(async () => {
|
|
54
|
+
process.stderr.write("Shutting down MCP server...\n");
|
|
55
|
+
await server.close();
|
|
56
|
+
process.exit(0);
|
|
57
|
+
});
|
|
58
|
+
return await new Promise(() => { });
|
|
59
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session:history command — Browse session history (GAP-SESSION-002).
|
|
3
|
+
*
|
|
4
|
+
* Displays accumulated decisions, run summaries, and context snapshots
|
|
5
|
+
* for a session. Supports --json and --run-id filtering.
|
|
6
|
+
*/
|
|
7
|
+
export interface SessionHistoryArgs {
|
|
8
|
+
sessionId: string;
|
|
9
|
+
stateDir: string;
|
|
10
|
+
json?: boolean;
|
|
11
|
+
runId?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function handleSessionHistory(args: SessionHistoryArgs): Promise<number>;
|
|
14
|
+
//# sourceMappingURL=history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/session/history.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BpF"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* session:history command — Browse session history (GAP-SESSION-002).
|
|
4
|
+
*
|
|
5
|
+
* Displays accumulated decisions, run summaries, and context snapshots
|
|
6
|
+
* for a session. Supports --json and --run-id filtering.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.handleSessionHistory = handleSessionHistory;
|
|
10
|
+
const session_1 = require("@a5c-ai/agent-platform/session");
|
|
11
|
+
async function handleSessionHistory(args) {
|
|
12
|
+
const { sessionId, stateDir } = args;
|
|
13
|
+
if (!sessionId) {
|
|
14
|
+
console.error("[session:history] --session-id is required");
|
|
15
|
+
return 1;
|
|
16
|
+
}
|
|
17
|
+
if (!stateDir) {
|
|
18
|
+
console.error("[session:history] --state-dir is required");
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
const history = await (0, session_1.getSessionHistory)(stateDir, sessionId);
|
|
22
|
+
// Apply run-id filter if requested
|
|
23
|
+
const filtered = args.runId ? filterByRunId(history, args.runId) : history;
|
|
24
|
+
if (args.json) {
|
|
25
|
+
console.log(JSON.stringify(filtered, null, 2));
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
// Text mode
|
|
29
|
+
renderTextHistory(filtered);
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
function filterByRunId(history, runId) {
|
|
33
|
+
return {
|
|
34
|
+
notes: history.notes,
|
|
35
|
+
sharedKnowledge: history.sharedKnowledge,
|
|
36
|
+
worktree: history.worktree,
|
|
37
|
+
decisions: history.decisions.filter((d) => d.runId === runId),
|
|
38
|
+
runSummaries: history.runSummaries.filter((r) => r.runId === runId),
|
|
39
|
+
contextSnapshots: history.contextSnapshots.filter((s) => s.runId === runId),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function renderTextHistory(history) {
|
|
43
|
+
console.log("=== Session Context ===");
|
|
44
|
+
if (history.worktree?.workspacePath) {
|
|
45
|
+
const parts = [`workspace ${history.worktree.workspacePath}`];
|
|
46
|
+
if (history.worktree.currentPath)
|
|
47
|
+
parts.push(`current ${history.worktree.currentPath}`);
|
|
48
|
+
if (history.worktree.mode)
|
|
49
|
+
parts.push(`mode ${history.worktree.mode}`);
|
|
50
|
+
if (history.worktree.repoAlias)
|
|
51
|
+
parts.push(`repo ${history.worktree.repoAlias}`);
|
|
52
|
+
if (history.worktree.branch)
|
|
53
|
+
parts.push(`branch ${history.worktree.branch}`);
|
|
54
|
+
console.log(` ${parts.join(" | ")}`);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
console.log("(no worktree metadata)");
|
|
58
|
+
}
|
|
59
|
+
console.log("");
|
|
60
|
+
console.log("=== Decisions ===");
|
|
61
|
+
if (history.decisions.length === 0) {
|
|
62
|
+
console.log("(none)");
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
for (const d of history.decisions) {
|
|
66
|
+
const runPart = d.runId ? ` [${d.runId}]` : "";
|
|
67
|
+
const ratPart = d.rationale ? ` — ${d.rationale}` : "";
|
|
68
|
+
console.log(` ${d.timestamp}${runPart}: ${d.description}${ratPart}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
console.log("");
|
|
72
|
+
console.log("=== Run Summaries ===");
|
|
73
|
+
if (history.runSummaries.length === 0) {
|
|
74
|
+
console.log("(none)");
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
for (const r of history.runSummaries) {
|
|
78
|
+
const parts = [`${r.runId} (${r.processId})`, r.status, `started ${r.startedAt}`];
|
|
79
|
+
if (r.completedAt)
|
|
80
|
+
parts.push(`completed ${r.completedAt}`);
|
|
81
|
+
if (r.outcome)
|
|
82
|
+
parts.push(r.outcome);
|
|
83
|
+
if (r.score !== undefined)
|
|
84
|
+
parts.push(`score: ${r.score}`);
|
|
85
|
+
console.log(` ${parts.join(" | ")}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
console.log("");
|
|
89
|
+
console.log("=== Context Snapshots ===");
|
|
90
|
+
if (history.contextSnapshots.length === 0) {
|
|
91
|
+
console.log("(none)");
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
for (const s of history.contextSnapshots) {
|
|
95
|
+
const keys = Object.keys(s.snapshot).length;
|
|
96
|
+
const runPart = s.runId ? ` [${s.runId}]` : "";
|
|
97
|
+
console.log(` ${s.timestamp}${runPart}: ${keys} key(s)`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tui command -- stub redirecting to agent-mux TUI with babysitter plugins.
|
|
3
|
+
*
|
|
4
|
+
* The tula dashboard uses the agent-mux TUI
|
|
5
|
+
* with babysitter-tui-plugins instead (packages/babysitter-tui-plugins/).
|
|
6
|
+
*
|
|
7
|
+
* `babysitter tui --json` still works as a non-interactive JSON fallback
|
|
8
|
+
* for run listing / detail inspection.
|
|
9
|
+
*/
|
|
10
|
+
interface TuiArgs {
|
|
11
|
+
runsDir: string;
|
|
12
|
+
json?: boolean;
|
|
13
|
+
verbose?: boolean;
|
|
14
|
+
positional?: string[];
|
|
15
|
+
harness?: string;
|
|
16
|
+
workspace?: string;
|
|
17
|
+
prompt?: string;
|
|
18
|
+
runId?: string;
|
|
19
|
+
verbosity?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function handleTui(args: TuiArgs): Promise<number>;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=tui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/tui.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH,UAAU,OAAO;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAgJD,wBAAsB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAe9D"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* tui command -- stub redirecting to agent-mux TUI with babysitter plugins.
|
|
4
|
+
*
|
|
5
|
+
* The tula dashboard uses the agent-mux TUI
|
|
6
|
+
* with babysitter-tui-plugins instead (packages/babysitter-tui-plugins/).
|
|
7
|
+
*
|
|
8
|
+
* `babysitter tui --json` still works as a non-interactive JSON fallback
|
|
9
|
+
* for run listing / detail inspection.
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.handleTui = handleTui;
|
|
46
|
+
const path = __importStar(require("node:path"));
|
|
47
|
+
const node_fs_1 = require("node:fs");
|
|
48
|
+
const babysitter_sdk_1 = require("@a5c-ai/babysitter-sdk");
|
|
49
|
+
async function scanRunsForJson(runsDir) {
|
|
50
|
+
const resolvedDir = path.resolve(runsDir);
|
|
51
|
+
let entries;
|
|
52
|
+
try {
|
|
53
|
+
entries = await node_fs_1.promises.readdir(resolvedDir);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
const summaries = [];
|
|
59
|
+
for (const entry of entries) {
|
|
60
|
+
const runDir = path.join(resolvedDir, entry);
|
|
61
|
+
const metadataPath = path.join(runDir, "run.json");
|
|
62
|
+
try {
|
|
63
|
+
await node_fs_1.promises.access(metadataPath);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const metadata = await (0, babysitter_sdk_1.readRunMetadata)(runDir);
|
|
70
|
+
let journal = [];
|
|
71
|
+
try {
|
|
72
|
+
journal = await (0, babysitter_sdk_1.loadJournal)(runDir);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Journal may not exist yet
|
|
76
|
+
}
|
|
77
|
+
const lastLifecycleType = [...journal].reverse().find((e) => e.type === "RUN_COMPLETED" || e.type === "RUN_FAILED")?.type;
|
|
78
|
+
const pendingCount = journal.filter((e) => e.type === "EFFECT_REQUESTED").length
|
|
79
|
+
- journal.filter((e) => e.type === "EFFECT_RESOLVED").length;
|
|
80
|
+
let state;
|
|
81
|
+
if (lastLifecycleType === "RUN_COMPLETED")
|
|
82
|
+
state = "completed";
|
|
83
|
+
else if (lastLifecycleType === "RUN_FAILED")
|
|
84
|
+
state = "failed";
|
|
85
|
+
else if (pendingCount > 0)
|
|
86
|
+
state = "waiting";
|
|
87
|
+
else
|
|
88
|
+
state = "created";
|
|
89
|
+
summaries.push({
|
|
90
|
+
runId: metadata.runId ?? entry,
|
|
91
|
+
state,
|
|
92
|
+
processId: metadata.processId ?? "unknown",
|
|
93
|
+
createdAt: metadata.createdAt ?? "",
|
|
94
|
+
eventCount: journal.length,
|
|
95
|
+
pendingCount: Math.max(0, pendingCount),
|
|
96
|
+
prompt: metadata.prompt,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Skip malformed runs
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
summaries.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
104
|
+
return summaries;
|
|
105
|
+
}
|
|
106
|
+
async function handleJsonMode(args) {
|
|
107
|
+
const runIdArg = args.runId ?? args.positional?.[0];
|
|
108
|
+
if (runIdArg) {
|
|
109
|
+
const runDir = (0, babysitter_sdk_1.getRunDir)(args.runsDir, runIdArg);
|
|
110
|
+
try {
|
|
111
|
+
const metadata = await (0, babysitter_sdk_1.readRunMetadata)(runDir);
|
|
112
|
+
const journal = await (0, babysitter_sdk_1.loadJournal)(runDir);
|
|
113
|
+
const index = await (0, babysitter_sdk_1.buildEffectIndex)({ runDir, events: journal });
|
|
114
|
+
const lastLifecycleType = [...journal].reverse().find((e) => e.type === "RUN_COMPLETED" || e.type === "RUN_FAILED")?.type;
|
|
115
|
+
const pendingCount = journal.filter((e) => e.type === "EFFECT_REQUESTED").length
|
|
116
|
+
- journal.filter((e) => e.type === "EFFECT_RESOLVED").length;
|
|
117
|
+
let state;
|
|
118
|
+
if (lastLifecycleType === "RUN_COMPLETED")
|
|
119
|
+
state = "completed";
|
|
120
|
+
else if (lastLifecycleType === "RUN_FAILED")
|
|
121
|
+
state = "failed";
|
|
122
|
+
else if (pendingCount > 0)
|
|
123
|
+
state = "waiting";
|
|
124
|
+
else
|
|
125
|
+
state = "created";
|
|
126
|
+
const allEffects = index.listEffects();
|
|
127
|
+
const effects = allEffects.map((rec) => ({
|
|
128
|
+
effectId: rec.effectId,
|
|
129
|
+
kind: rec.kind ?? "unknown",
|
|
130
|
+
status: rec.status === "resolved_ok" || rec.status === "resolved_error"
|
|
131
|
+
? "completed" : rec.status === "requested" ? "pending" : "running",
|
|
132
|
+
title: rec.taskId ?? rec.effectId,
|
|
133
|
+
}));
|
|
134
|
+
console.log(JSON.stringify({
|
|
135
|
+
runId: runIdArg,
|
|
136
|
+
state,
|
|
137
|
+
processId: metadata.processId,
|
|
138
|
+
createdAt: metadata.createdAt,
|
|
139
|
+
events: journal.map((e) => ({
|
|
140
|
+
type: e.type,
|
|
141
|
+
recordedAt: e.recordedAt,
|
|
142
|
+
seq: e.seq,
|
|
143
|
+
})),
|
|
144
|
+
effects,
|
|
145
|
+
pendingCount: Math.max(0, pendingCount),
|
|
146
|
+
}, null, 2));
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
console.error(`[tui] unable to read run ${runIdArg}: ${err.message}`);
|
|
150
|
+
return 1;
|
|
151
|
+
}
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
154
|
+
const runs = await scanRunsForJson(args.runsDir);
|
|
155
|
+
console.log(JSON.stringify({
|
|
156
|
+
runs: runs.map((r) => ({
|
|
157
|
+
runId: r.runId,
|
|
158
|
+
state: r.state,
|
|
159
|
+
processId: r.processId,
|
|
160
|
+
createdAt: r.createdAt,
|
|
161
|
+
eventCount: r.eventCount,
|
|
162
|
+
pendingCount: r.pendingCount,
|
|
163
|
+
prompt: r.prompt,
|
|
164
|
+
})),
|
|
165
|
+
}, null, 2));
|
|
166
|
+
return 0;
|
|
167
|
+
}
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
// Main handler
|
|
170
|
+
// ---------------------------------------------------------------------------
|
|
171
|
+
async function handleTui(args) {
|
|
172
|
+
// JSON mode: non-interactive listing (retained for backward compat)
|
|
173
|
+
if (args.json) {
|
|
174
|
+
return handleJsonMode(args);
|
|
175
|
+
}
|
|
176
|
+
// Interactive TUI: redirect to agent-mux TUI
|
|
177
|
+
console.error("The tula TUI delegates to agent-mux.\n" +
|
|
178
|
+
"Use agent-mux TUI with babysitter plugins instead:\n" +
|
|
179
|
+
" npx agent-mux tui --workspace .\n" +
|
|
180
|
+
"\n" +
|
|
181
|
+
"For non-interactive run listing, use: tula tui --json");
|
|
182
|
+
return 1;
|
|
183
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/cli/dispatch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAuBhD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAkCnE;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsHvF"}
|