@agent-relay/sdk 3.2.9 → 3.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/bin/agent-relay-broker-darwin-arm64 +0 -0
  2. package/bin/agent-relay-broker-darwin-x64 +0 -0
  3. package/bin/agent-relay-broker-linux-arm64 +0 -0
  4. package/bin/agent-relay-broker-linux-x64 +0 -0
  5. package/dist/cli-registry.d.ts +42 -0
  6. package/dist/cli-registry.d.ts.map +1 -0
  7. package/dist/cli-registry.js +126 -0
  8. package/dist/cli-registry.js.map +1 -0
  9. package/dist/cli-resolver.d.ts +30 -0
  10. package/dist/cli-resolver.d.ts.map +1 -0
  11. package/dist/cli-resolver.js +132 -0
  12. package/dist/cli-resolver.js.map +1 -0
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +2 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/spawn-from-env.d.ts.map +1 -1
  18. package/dist/spawn-from-env.js +6 -15
  19. package/dist/spawn-from-env.js.map +1 -1
  20. package/dist/workflows/__tests__/cli-session-collector.test.d.ts +2 -0
  21. package/dist/workflows/__tests__/cli-session-collector.test.d.ts.map +1 -0
  22. package/dist/workflows/__tests__/cli-session-collector.test.js +54 -0
  23. package/dist/workflows/__tests__/cli-session-collector.test.js.map +1 -0
  24. package/dist/workflows/__tests__/collectors/claude.test.d.ts +2 -0
  25. package/dist/workflows/__tests__/collectors/claude.test.d.ts.map +1 -0
  26. package/dist/workflows/__tests__/collectors/claude.test.js +85 -0
  27. package/dist/workflows/__tests__/collectors/claude.test.js.map +1 -0
  28. package/dist/workflows/__tests__/collectors/codex.test.d.ts +2 -0
  29. package/dist/workflows/__tests__/collectors/codex.test.d.ts.map +1 -0
  30. package/dist/workflows/__tests__/collectors/codex.test.js +67 -0
  31. package/dist/workflows/__tests__/collectors/codex.test.js.map +1 -0
  32. package/dist/workflows/__tests__/collectors/opencode.test.d.ts +2 -0
  33. package/dist/workflows/__tests__/collectors/opencode.test.d.ts.map +1 -0
  34. package/dist/workflows/__tests__/collectors/opencode.test.js +119 -0
  35. package/dist/workflows/__tests__/collectors/opencode.test.js.map +1 -0
  36. package/dist/workflows/__tests__/run-summary-table.test.d.ts +2 -0
  37. package/dist/workflows/__tests__/run-summary-table.test.d.ts.map +1 -0
  38. package/dist/workflows/__tests__/run-summary-table.test.js +130 -0
  39. package/dist/workflows/__tests__/run-summary-table.test.js.map +1 -0
  40. package/dist/workflows/__tests__/step-cwd.test.d.ts +2 -0
  41. package/dist/workflows/__tests__/step-cwd.test.d.ts.map +1 -0
  42. package/dist/workflows/__tests__/step-cwd.test.js +42 -0
  43. package/dist/workflows/__tests__/step-cwd.test.js.map +1 -0
  44. package/dist/workflows/builder.d.ts +7 -0
  45. package/dist/workflows/builder.d.ts.map +1 -1
  46. package/dist/workflows/builder.js +40 -5
  47. package/dist/workflows/builder.js.map +1 -1
  48. package/dist/workflows/cli-session-collector.d.ts +39 -0
  49. package/dist/workflows/cli-session-collector.d.ts.map +1 -0
  50. package/dist/workflows/cli-session-collector.js +23 -0
  51. package/dist/workflows/cli-session-collector.js.map +1 -0
  52. package/dist/workflows/cli.js +228 -48
  53. package/dist/workflows/cli.js.map +1 -1
  54. package/dist/workflows/collectors/claude.d.ts +6 -0
  55. package/dist/workflows/collectors/claude.d.ts.map +1 -0
  56. package/dist/workflows/collectors/claude.js +330 -0
  57. package/dist/workflows/collectors/claude.js.map +1 -0
  58. package/dist/workflows/collectors/codex.d.ts +18 -0
  59. package/dist/workflows/collectors/codex.d.ts.map +1 -0
  60. package/dist/workflows/collectors/codex.js +265 -0
  61. package/dist/workflows/collectors/codex.js.map +1 -0
  62. package/dist/workflows/collectors/opencode.d.ts +6 -0
  63. package/dist/workflows/collectors/opencode.d.ts.map +1 -0
  64. package/dist/workflows/collectors/opencode.js +204 -0
  65. package/dist/workflows/collectors/opencode.js.map +1 -0
  66. package/dist/workflows/default-logger.d.ts +9 -0
  67. package/dist/workflows/default-logger.d.ts.map +1 -0
  68. package/dist/workflows/default-logger.js +104 -0
  69. package/dist/workflows/default-logger.js.map +1 -0
  70. package/dist/workflows/index.d.ts +4 -0
  71. package/dist/workflows/index.d.ts.map +1 -1
  72. package/dist/workflows/index.js +4 -0
  73. package/dist/workflows/index.js.map +1 -1
  74. package/dist/workflows/listr-renderer.d.ts +26 -0
  75. package/dist/workflows/listr-renderer.d.ts.map +1 -0
  76. package/dist/workflows/listr-renderer.js +232 -0
  77. package/dist/workflows/listr-renderer.js.map +1 -0
  78. package/dist/workflows/run-summary-table.d.ts +4 -0
  79. package/dist/workflows/run-summary-table.d.ts.map +1 -0
  80. package/dist/workflows/run-summary-table.js +98 -0
  81. package/dist/workflows/run-summary-table.js.map +1 -0
  82. package/dist/workflows/runner.d.ts +12 -1
  83. package/dist/workflows/runner.d.ts.map +1 -1
  84. package/dist/workflows/runner.js +107 -71
  85. package/dist/workflows/runner.js.map +1 -1
  86. package/dist/workflows/types.d.ts +2 -0
  87. package/dist/workflows/types.d.ts.map +1 -1
  88. package/dist/workflows/types.js.map +1 -1
  89. package/package.json +4 -2
@@ -0,0 +1,204 @@
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { createRequire } from 'node:module';
5
+ const require = createRequire(import.meta.url);
6
+ const OPENCODE_DB_PATH = path.join(os.homedir(), '.local', 'share', 'opencode', 'opencode.db');
7
+ const MATCH_WINDOW_GRACE_MS = 5_000;
8
+ const ERROR_LINE_PATTERN = /^(Error|error:|Command failed|FAIL)\b/;
9
+ function loadDatabaseConstructor() {
10
+ try {
11
+ return require('better-sqlite3');
12
+ }
13
+ catch {
14
+ // fall through
15
+ }
16
+ // Fall back to Node 22+ native node:sqlite (experimental)
17
+ try {
18
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
19
+ const { DatabaseSync } = require('node:sqlite');
20
+ return function NativeSqliteWrapper(filename, options) {
21
+ const db = new DatabaseSync(filename, { open: true, readOnly: options?.readonly ?? false });
22
+ return {
23
+ prepare(sql) {
24
+ const stmt = db.prepare(sql);
25
+ return {
26
+ get(params) {
27
+ return params != null ? stmt.get(params) : stmt.get();
28
+ },
29
+ all(params) {
30
+ return (params != null ? stmt.all(params) : stmt.all());
31
+ },
32
+ };
33
+ },
34
+ pragma(source) { db.exec(`PRAGMA ${source}`); return undefined; },
35
+ close() { db.close(); },
36
+ };
37
+ };
38
+ }
39
+ catch {
40
+ return null;
41
+ }
42
+ }
43
+ function parseJson(value) {
44
+ try {
45
+ return JSON.parse(value);
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ }
51
+ function toNumber(value) {
52
+ return typeof value === 'number' && Number.isFinite(value) ? value : 0;
53
+ }
54
+ function normalizeStatus(finish, hasErrors) {
55
+ if (finish === 'stop' || finish === 'completed') {
56
+ return 'completed';
57
+ }
58
+ if (finish === 'error' || finish === 'failed' || hasErrors) {
59
+ return 'failed';
60
+ }
61
+ return 'unknown';
62
+ }
63
+ function isToolPart(part) {
64
+ return !!part?.type && part.type.toLowerCase().includes('tool');
65
+ }
66
+ export class OpenCodeCollector {
67
+ canCollect() {
68
+ if (!fs.existsSync(OPENCODE_DB_PATH)) {
69
+ return false;
70
+ }
71
+ const Database = loadDatabaseConstructor();
72
+ if (!Database) {
73
+ return false;
74
+ }
75
+ let db = null;
76
+ try {
77
+ db = new Database(OPENCODE_DB_PATH, { readonly: true, fileMustExist: true });
78
+ db.pragma('query_only = ON');
79
+ db.prepare('SELECT 1').get();
80
+ return true;
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ finally {
86
+ db?.close();
87
+ }
88
+ }
89
+ async collect(query) {
90
+ const Database = loadDatabaseConstructor();
91
+ if (!Database) {
92
+ return null;
93
+ }
94
+ let db = null;
95
+ try {
96
+ db = new Database(OPENCODE_DB_PATH, { readonly: true, fileMustExist: true });
97
+ db.pragma('query_only = ON');
98
+ const session = db.prepare(`
99
+ SELECT id, directory, time_created
100
+ FROM session
101
+ WHERE directory = @cwd
102
+ AND time_created BETWEEN @startedAt AND @completedAt
103
+ ORDER BY time_created DESC
104
+ LIMIT 1
105
+ `).get({
106
+ cwd: query.cwd,
107
+ startedAt: query.startedAt - MATCH_WINDOW_GRACE_MS,
108
+ completedAt: query.completedAt,
109
+ });
110
+ if (!session) {
111
+ return null;
112
+ }
113
+ const messages = db.prepare(`
114
+ SELECT id, session_id, time_created, data
115
+ FROM message
116
+ WHERE session_id = ?
117
+ ORDER BY time_created ASC
118
+ `).all(session.id);
119
+ const parts = db.prepare(`
120
+ SELECT id, message_id, session_id, time_created, data
121
+ FROM part
122
+ WHERE session_id = ?
123
+ ORDER BY time_created ASC
124
+ `).all(session.id);
125
+ const parsedMessages = messages.map((message) => ({
126
+ ...message,
127
+ parsed: parseJson(message.data),
128
+ }));
129
+ const parsedParts = parts.map((part) => ({
130
+ ...part,
131
+ parsed: parseJson(part.data),
132
+ }));
133
+ const lastMessageWithMetadata = [...parsedMessages]
134
+ .reverse()
135
+ .find((message) => message.parsed?.modelID || message.parsed?.providerID || message.parsed?.finish);
136
+ const tokenTotals = parsedMessages.reduce((totals, message) => {
137
+ const tokens = message.parsed?.tokens;
138
+ totals.input += toNumber(tokens?.input);
139
+ totals.output += toNumber(tokens?.output);
140
+ totals.cacheRead += toNumber(tokens?.cache?.read);
141
+ return totals;
142
+ }, { input: 0, output: 0, cacheRead: 0 });
143
+ const hasCostData = parsedMessages.some((message) => typeof message.parsed?.cost === 'number' && Number.isFinite(message.parsed.cost));
144
+ const totalCost = parsedMessages.reduce((sum, message) => sum + toNumber(message.parsed?.cost), 0);
145
+ const toolCallCounts = new Map();
146
+ for (const part of parsedParts) {
147
+ if (!isToolPart(part.parsed)) {
148
+ continue;
149
+ }
150
+ const name = part.parsed.name?.trim();
151
+ if (!name) {
152
+ continue;
153
+ }
154
+ toolCallCounts.set(name, (toolCallCounts.get(name) ?? 0) + 1);
155
+ }
156
+ const errors = [];
157
+ for (const [index, part] of parsedParts.entries()) {
158
+ const text = part.parsed?.type === 'text' ? part.parsed.text : undefined;
159
+ if (!text) {
160
+ continue;
161
+ }
162
+ for (const line of text.split(/\r?\n/)) {
163
+ const trimmed = line.trim();
164
+ if (!trimmed || !ERROR_LINE_PATTERN.test(trimmed)) {
165
+ continue;
166
+ }
167
+ errors.push({ turn: index + 1, text: trimmed });
168
+ }
169
+ }
170
+ const summary = [...parsedParts]
171
+ .reverse()
172
+ .find((part) => part.parsed?.type === 'text' && part.parsed.text?.trim())?.parsed?.text?.trim() ?? null;
173
+ const turns = parsedMessages.filter((message) => message.parsed?.role === 'assistant' || message.parsed?.role === 'user').length || parsedMessages.length;
174
+ return {
175
+ cli: 'opencode',
176
+ sessionId: session.id,
177
+ model: lastMessageWithMetadata?.parsed?.modelID ?? null,
178
+ provider: lastMessageWithMetadata?.parsed?.providerID ?? null,
179
+ durationMs: parsedMessages.length > 0
180
+ ? Math.max(0, parsedMessages[parsedMessages.length - 1].time_created - session.time_created)
181
+ : null,
182
+ cost: hasCostData ? totalCost : null,
183
+ tokens: tokenTotals,
184
+ turns,
185
+ toolCalls: [...toolCallCounts.entries()].map(([name, count]) => ({ name, count })),
186
+ errors,
187
+ finalStatus: normalizeStatus(lastMessageWithMetadata?.parsed?.finish, errors.length > 0),
188
+ summary,
189
+ raw: {
190
+ session,
191
+ messages: parsedMessages.map(({ parsed, ...message }) => ({ ...message, data: parsed ?? message.data })),
192
+ parts: parsedParts.map(({ parsed, ...part }) => ({ ...part, data: parsed ?? part.data })),
193
+ },
194
+ };
195
+ }
196
+ catch {
197
+ return null;
198
+ }
199
+ finally {
200
+ db?.close();
201
+ }
202
+ }
203
+ }
204
+ //# sourceMappingURL=opencode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../../src/workflows/collectors/opencode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { WorkflowEventListener } from './runner.js';
2
+ export type LogLevel = 'verbose' | 'normal' | 'quiet' | false;
3
+ /**
4
+ * Create a default event logger that writes workflow progress to the console.
5
+ *
6
+ * @param level - Log verbosity: "verbose" | "normal" (default) | "quiet" | false (no-op)
7
+ */
8
+ export declare function createDefaultEventLogger(level?: LogLevel): WorkflowEventListener;
9
+ //# sourceMappingURL=default-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-logger.d.ts","sourceRoot":"","sources":["../../src/workflows/default-logger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAExE,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;AAI9D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,GAAE,QAAmB,GAAG,qBAAqB,CA2G1F"}
@@ -0,0 +1,104 @@
1
+ import chalk from 'chalk';
2
+ const noop = () => { };
3
+ /**
4
+ * Create a default event logger that writes workflow progress to the console.
5
+ *
6
+ * @param level - Log verbosity: "verbose" | "normal" (default) | "quiet" | false (no-op)
7
+ */
8
+ export function createDefaultEventLogger(level = 'normal') {
9
+ if (level === false)
10
+ return noop;
11
+ return (event) => {
12
+ switch (event.type) {
13
+ // ── Run lifecycle ──
14
+ case 'run:started':
15
+ if (level !== 'quiet') {
16
+ console.log(chalk.cyan(`[workflow] run ${event.runId.slice(0, 8)}...`));
17
+ }
18
+ break;
19
+ case 'run:completed':
20
+ console.log(chalk.green(`[workflow] completed`));
21
+ break;
22
+ case 'run:failed':
23
+ console.log(chalk.red(`[workflow] FAILED: ${event.error}`));
24
+ break;
25
+ case 'run:cancelled':
26
+ if (level !== 'quiet') {
27
+ console.log(chalk.yellow(`[workflow] cancelled`));
28
+ }
29
+ break;
30
+ // ── Step lifecycle ──
31
+ case 'step:started':
32
+ if (level !== 'quiet') {
33
+ console.log(chalk.blue(` ● ${event.stepName} — started`));
34
+ }
35
+ break;
36
+ case 'step:completed':
37
+ if (level !== 'quiet') {
38
+ console.log(chalk.green(` ✓ ${event.stepName} — completed`));
39
+ }
40
+ break;
41
+ case 'step:failed':
42
+ console.log(chalk.red(` ✗ ${event.stepName} — FAILED: ${event.error}`));
43
+ break;
44
+ case 'step:skipped':
45
+ if (level !== 'quiet') {
46
+ console.log(chalk.gray(` ○ ${event.stepName} — skipped`));
47
+ }
48
+ break;
49
+ case 'step:retrying':
50
+ if (level !== 'quiet') {
51
+ console.log(chalk.yellow(` ↻ ${event.stepName} — retrying (attempt ${event.attempt})`));
52
+ }
53
+ break;
54
+ case 'step:nudged':
55
+ if (level !== 'quiet') {
56
+ console.log(chalk.yellow(` ⚡ ${event.stepName} — nudged (${event.nudgeCount})`));
57
+ }
58
+ break;
59
+ case 'step:agent-report': {
60
+ if (level !== 'quiet') {
61
+ const r = event.report;
62
+ const parts = [];
63
+ if (r.model)
64
+ parts.push(r.model);
65
+ if (r.cost != null)
66
+ parts.push(`$${r.cost.toFixed(2)}`);
67
+ if (r.tokens)
68
+ parts.push(`${r.tokens.input}+${r.tokens.output} tokens`);
69
+ parts.push(`${r.errors.length} errors`);
70
+ console.log(chalk.dim(` 📊 ${event.stepName} — ${parts.join(' · ')}`));
71
+ }
72
+ break;
73
+ }
74
+ // ── Broker-level events (verbose only) ──
75
+ case 'broker:event':
76
+ if (level === 'verbose') {
77
+ console.log(chalk.dim(` [broker] ${JSON.stringify(event.event)}`));
78
+ }
79
+ break;
80
+ // ── Other events (verbose only) ──
81
+ case 'step:owner-assigned':
82
+ if (level === 'verbose') {
83
+ console.log(chalk.dim(` ${event.stepName} — owner: ${event.ownerName}, specialist: ${event.specialistName}`));
84
+ }
85
+ break;
86
+ case 'step:review-completed':
87
+ if (level === 'verbose') {
88
+ console.log(chalk.dim(` ${event.stepName} — review: ${event.decision} by ${event.reviewerName}`));
89
+ }
90
+ break;
91
+ case 'step:owner-timeout':
92
+ if (level !== 'quiet') {
93
+ console.log(chalk.yellow(` ⏱ ${event.stepName} — owner timeout (${event.ownerName})`));
94
+ }
95
+ break;
96
+ case 'step:force-released':
97
+ if (level === 'verbose') {
98
+ console.log(chalk.dim(` ${event.stepName} — force-released`));
99
+ }
100
+ break;
101
+ }
102
+ };
103
+ }
104
+ //# sourceMappingURL=default-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-logger.js","sourceRoot":"","sources":["../../src/workflows/default-logger.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  export * from './types.js';
2
2
  export * from './runner.js';
3
3
  export * from './custom-steps.js';
4
+ export * from './cli-session-collector.js';
5
+ export * from './run-summary-table.js';
4
6
  export { Models, ClaudeModels, CodexModels, GeminiModels, CursorModels, CLIs, CLIVersions, CLIRegistry, SwarmPatterns, } from '../models.js';
5
7
  export * from './memory-db.js';
6
8
  export * from './file-db.js';
@@ -12,4 +14,6 @@ export * from './state.js';
12
14
  export * from './templates.js';
13
15
  export { WorkflowTrajectory, type StepOutcome } from './trajectory.js';
14
16
  export { formatDryRunReport } from './dry-run-format.js';
17
+ export { createWorkflowRenderer, type WorkflowRenderer } from './listr-renderer.js';
18
+ export { createDefaultEventLogger } from './default-logger.js';
15
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workflows/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,MAAM,EACN,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,IAAI,EACJ,WAAW,EACX,WAAW,EACX,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workflows/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,OAAO,EACL,MAAM,EACN,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,IAAI,EACJ,WAAW,EACX,WAAW,EACX,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,6 +1,8 @@
1
1
  export * from './types.js';
2
2
  export * from './runner.js';
3
3
  export * from './custom-steps.js';
4
+ export * from './cli-session-collector.js';
5
+ export * from './run-summary-table.js';
4
6
  export { Models, ClaudeModels, CodexModels, GeminiModels, CursorModels, CLIs, CLIVersions, CLIRegistry, SwarmPatterns, } from '../models.js';
5
7
  export * from './memory-db.js';
6
8
  export * from './file-db.js';
@@ -12,4 +14,6 @@ export * from './state.js';
12
14
  export * from './templates.js';
13
15
  export { WorkflowTrajectory } from './trajectory.js';
14
16
  export { formatDryRunReport } from './dry-run-format.js';
17
+ export { createWorkflowRenderer } from './listr-renderer.js';
18
+ export { createDefaultEventLogger } from './default-logger.js';
15
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workflows/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,MAAM,EACN,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,IAAI,EACJ,WAAW,EACX,WAAW,EACX,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAoB,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workflows/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,OAAO,EACL,MAAM,EACN,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,IAAI,EACJ,WAAW,EACX,WAAW,EACX,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAoB,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAyB,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { WorkflowEventListener } from './runner.js';
2
+ export interface WorkflowRenderer {
3
+ /** Pass this to `.run({ onEvent })` in your TypeScript workflow. */
4
+ onEvent: WorkflowEventListener;
5
+ /** Start the listr renderer. Run this concurrently with your workflow. */
6
+ start: () => Promise<void>;
7
+ /** Restore console.log after the workflow finishes. */
8
+ unmount: () => void;
9
+ }
10
+ /**
11
+ * Creates a listr2-based renderer for TypeScript workflows.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { workflow, createWorkflowRenderer } from '@agent-relay/sdk/workflows';
16
+ *
17
+ * const renderer = createWorkflowRenderer();
18
+ * const [result] = await Promise.all([
19
+ * workflow('my-workflow').step(...).run({ onEvent: renderer.onEvent }),
20
+ * renderer.start(),
21
+ * ]);
22
+ * renderer.unmount();
23
+ * ```
24
+ */
25
+ export declare function createWorkflowRenderer(): WorkflowRenderer;
26
+ //# sourceMappingURL=listr-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listr-renderer.d.ts","sourceRoot":"","sources":["../../src/workflows/listr-renderer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAiB,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAmCxE,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,OAAO,EAAE,qBAAqB,CAAC;IAC/B,0EAA0E;IAC1E,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,uDAAuD;IACvD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAwNzD"}
@@ -0,0 +1,232 @@
1
+ import chalk from 'chalk';
2
+ // Filter console.log while listr owns the terminal.
3
+ // Blocks [broker] noise and [workflow HH:MM] timing lines, but lets the
4
+ // observer URL and channel name through so users can track the run.
5
+ function installOutputFilter() {
6
+ const orig = console.log.bind(console);
7
+ console.log = (...args) => {
8
+ const str = String(args[0] ?? '');
9
+ // Always show the observer URL and channel so users can follow the run
10
+ if (str.includes('Observer:') || str.includes('agentrelay.dev') || str.includes('Channel: wf-')) {
11
+ orig(...args);
12
+ return;
13
+ }
14
+ // Block [broker] lines and [workflow HH:MM] timing lines
15
+ if (/\[broker\]/.test(str) || /\[workflow\s+\d{2}:\d{2}\]/.test(str))
16
+ return;
17
+ orig(...args);
18
+ };
19
+ return () => {
20
+ console.log = orig;
21
+ };
22
+ }
23
+ /**
24
+ * Creates a listr2-based renderer for TypeScript workflows.
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * import { workflow, createWorkflowRenderer } from '@agent-relay/sdk/workflows';
29
+ *
30
+ * const renderer = createWorkflowRenderer();
31
+ * const [result] = await Promise.all([
32
+ * workflow('my-workflow').step(...).run({ onEvent: renderer.onEvent }),
33
+ * renderer.start(),
34
+ * ]);
35
+ * renderer.unmount();
36
+ * ```
37
+ */
38
+ export function createWorkflowRenderer() {
39
+ const stepHandles = new Map();
40
+ let resolveWorkflow;
41
+ let rejectWorkflow;
42
+ const workflowDone = new Promise((resolve, reject) => {
43
+ resolveWorkflow = resolve;
44
+ rejectWorkflow = reject;
45
+ });
46
+ // Prevent unhandled rejection if run:failed fires before the header task
47
+ // reaches `await workflowDone`.
48
+ workflowDone.catch(() => { });
49
+ let setHeader = () => { };
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ let listr = null;
52
+ const pendingAdds = [];
53
+ async function ensureListr() {
54
+ if (listr)
55
+ return listr;
56
+ const { Listr } = await import('listr2');
57
+ listr = new Listr([
58
+ {
59
+ title: chalk.dim('Workflow starting...'),
60
+ task: async (_ctx, task) => {
61
+ setHeader = (text) => {
62
+ task.title = text;
63
+ };
64
+ await workflowDone;
65
+ },
66
+ },
67
+ ], {
68
+ concurrent: true,
69
+ renderer: process.stdout.isTTY ? 'default' : 'verbose',
70
+ rendererOptions: {
71
+ collapseErrors: false,
72
+ showErrorMessage: true,
73
+ },
74
+ });
75
+ for (const task of pendingAdds)
76
+ listr.add(task);
77
+ pendingAdds.length = 0;
78
+ return listr;
79
+ }
80
+ const addTask = (task) => {
81
+ if (listr)
82
+ listr.add(task);
83
+ else
84
+ pendingAdds.push(task);
85
+ };
86
+ const onEvent = (event) => {
87
+ switch (event.type) {
88
+ case 'run:started': {
89
+ setHeader(chalk.dim(`[workflow] run ${event.runId.slice(0, 8)}...`));
90
+ break;
91
+ }
92
+ case 'step:started': {
93
+ let resolveStep;
94
+ let rejectStep;
95
+ let taskRef = null;
96
+ let skipped = false;
97
+ const done = new Promise((resolve, reject) => {
98
+ resolveStep = resolve;
99
+ rejectStep = reject;
100
+ });
101
+ // Prevent unhandled rejection if the step fails before the listr
102
+ // task function has started and reached `await done`.
103
+ done.catch(() => { });
104
+ stepHandles.set(event.stepName, {
105
+ resolve: resolveStep,
106
+ reject: rejectStep,
107
+ setOutput: (text) => {
108
+ if (taskRef)
109
+ taskRef.output = text;
110
+ },
111
+ markSkipped: () => {
112
+ skipped = true;
113
+ if (taskRef)
114
+ taskRef.title = chalk.dim(`${event.stepName} (skipped)`);
115
+ },
116
+ });
117
+ addTask({
118
+ title: chalk.white(event.stepName),
119
+ task: async (_ctx, task) => {
120
+ taskRef = task;
121
+ if (skipped)
122
+ taskRef.title = chalk.dim(`${event.stepName} (skipped)`);
123
+ await done;
124
+ },
125
+ rendererOptions: { persistentOutput: true },
126
+ });
127
+ break;
128
+ }
129
+ case 'step:owner-assigned': {
130
+ const handle = stepHandles.get(event.stepName);
131
+ if (handle) {
132
+ handle.setOutput(chalk.dim(`> Owner: ${event.ownerName}`) +
133
+ (event.specialistName ? chalk.dim(` · specialist: ${event.specialistName}`) : ''));
134
+ }
135
+ break;
136
+ }
137
+ case 'step:retrying': {
138
+ stepHandles.get(event.stepName)?.setOutput(chalk.yellow(`Retrying (attempt ${event.attempt})`));
139
+ break;
140
+ }
141
+ case 'step:nudged': {
142
+ stepHandles.get(event.stepName)?.setOutput(chalk.dim(`> Nudge #${event.nudgeCount}`));
143
+ break;
144
+ }
145
+ case 'step:force-released': {
146
+ stepHandles.get(event.stepName)?.setOutput(chalk.yellow('> Force-released'));
147
+ break;
148
+ }
149
+ case 'step:review-completed': {
150
+ stepHandles
151
+ .get(event.stepName)
152
+ ?.setOutput(chalk.dim(`> Review: ${event.decision} by ${event.reviewerName}`));
153
+ break;
154
+ }
155
+ case 'step:owner-timeout': {
156
+ stepHandles
157
+ .get(event.stepName)
158
+ ?.setOutput(chalk.red(`> Owner ${event.ownerName} timed out`));
159
+ break;
160
+ }
161
+ case 'step:agent-report': {
162
+ const handle = stepHandles.get(event.stepName);
163
+ if (handle) {
164
+ const model = event.report.model ? `:${event.report.model}` : '';
165
+ handle.setOutput(chalk.dim(`> Report collected (${event.report.cli}${model})`));
166
+ }
167
+ break;
168
+ }
169
+ case 'step:completed': {
170
+ stepHandles.get(event.stepName)?.resolve();
171
+ break;
172
+ }
173
+ case 'step:skipped': {
174
+ const handle = stepHandles.get(event.stepName);
175
+ if (handle) {
176
+ handle.markSkipped();
177
+ handle.resolve();
178
+ }
179
+ else {
180
+ // Step was skipped without ever being started (downstream of a failure).
181
+ addTask({
182
+ title: chalk.dim(`${event.stepName} (skipped)`),
183
+ task: async () => { },
184
+ rendererOptions: { persistentOutput: true },
185
+ });
186
+ }
187
+ break;
188
+ }
189
+ case 'step:failed': {
190
+ stepHandles.get(event.stepName)?.reject(new Error(event.error ?? 'Step failed'));
191
+ break;
192
+ }
193
+ case 'run:completed': {
194
+ setHeader(chalk.green('Workflow completed'));
195
+ resolveWorkflow();
196
+ break;
197
+ }
198
+ case 'run:failed': {
199
+ setHeader(chalk.red(`Workflow failed: ${event.error ?? 'unknown error'}`));
200
+ rejectWorkflow(new Error(event.error ?? 'Workflow failed'));
201
+ break;
202
+ }
203
+ case 'run:cancelled': {
204
+ setHeader(chalk.yellow('Workflow cancelled'));
205
+ resolveWorkflow();
206
+ break;
207
+ }
208
+ case 'broker:event':
209
+ break;
210
+ default: {
211
+ const _exhaustive = event;
212
+ void _exhaustive;
213
+ }
214
+ }
215
+ };
216
+ let restoreConsole;
217
+ return {
218
+ onEvent,
219
+ start: async () => {
220
+ restoreConsole = installOutputFilter();
221
+ const l = await ensureListr();
222
+ return l.run().catch(() => {
223
+ // Step failures are already represented in the workflow result.
224
+ });
225
+ },
226
+ unmount: () => {
227
+ restoreConsole?.();
228
+ restoreConsole = undefined;
229
+ },
230
+ };
231
+ }
232
+ //# sourceMappingURL=listr-renderer.js.map