Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4e77bdb
feat: add workflow to polish CLI output with listr2 + chalk
khaliqgant Mar 18, 2026
959acd4
ci: add workflow validation and dry-run check on PR
khaliqgant Mar 18, 2026
fb69ea3
fix(ci): fetch full history for git diff, run dry-run on all workflow…
khaliqgant Mar 18, 2026
cefee35
feat(sdk): polish workflow CLI output with listr2 spinners and chalk …
khaliqgant Mar 18, 2026
9f25a69
test: add smoke test workflow for listr2 output rendering
khaliqgant Mar 18, 2026
53cd59f
fix: use ESM-compatible import for check-sdk step
khaliqgant Mar 18, 2026
fa4821b
feat(sdk): export createWorkflowRenderer for listr2 output in TS work…
khaliqgant Mar 18, 2026
1be278b
fix: pre-attach catch to prevent unhandled rejection on fast-failing …
khaliqgant Mar 18, 2026
730edad
fix: use worker preset for verify step, mute console during listr ren…
khaliqgant Mar 18, 2026
cadab2e
fix: filter [broker]/[workflow] noise, show observer URL, add unmount()
khaliqgant Mar 18, 2026
a9cd987
fix: add missing unhandled-rejection guards and output filter to YAML…
khaliqgant Mar 18, 2026
2f45767
fix: address PR review feedback for workflow output polish
khaliqgant Mar 18, 2026
ff23241
fix: CI failures and skipped-step visibility
khaliqgant Mar 18, 2026
3a8b77d
fix: detect claude CLI with inline args for MCP injection (#584)
khaliqgant Mar 18, 2026
f6b8765
chore(release): v3.2.8
actions-user Mar 18, 2026
463af4e
bump versions (#590)
khaliqgant Mar 19, 2026
ef7cf4d
chore(release): v3.2.9
actions-user Mar 19, 2026
18d8bb9
feat(sdk): polish workflow CLI output with listr2 spinners and chalk …
khaliqgant Mar 18, 2026
01bb7b5
Merge main into feature/polish-workflow-output
khaliqgant Mar 19, 2026
910326c
fix: regenerate lockfile with npm 11 for Node 24 ci compatibility
khaliqgant Mar 19, 2026
0cc1822
fix: address remaining workflow review feedback
khaliqgant Mar 19, 2026
d85c7b7
Merge main into feature/polish-workflow-output
khaliqgant Mar 19, 2026
23f9f91
fix: mark test-only MCP merge helpers as dead-code allowed
khaliqgant Mar 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 0 additions & 58 deletions .trajectories/active/traj_49mvfl01ogcy.json

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"task": {
"title": "Code review for assigned workflow changes"
},
"status": "abandoned",
"status": "active",
"startedAt": "2026-03-12T08:38:19.960Z",
"agents": [],
"chapters": [],
Expand All @@ -15,6 +15,5 @@
"_trace": {
"startRef": "4ce7ccf5e297e46ededaf74c2a997cfe0d2f88af",
"endRef": "4ce7ccf5e297e46ededaf74c2a997cfe0d2f88af"
},
"completedAt": "2026-03-19T13:58:52.857Z"
}
}
5 changes: 0 additions & 5 deletions .trajectories/completed/2026-03/traj_u6bndffr0b8g.md

This file was deleted.

15 changes: 1 addition & 14 deletions .trajectories/index.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"version": 1,
"lastUpdated": "2026-03-19T13:59:13.544Z",
"lastUpdated": "2026-03-14T21:19:05.674Z",
"trajectories": {
"traj_1b1dj40sl6jl": {
"title": "Revert aggressive retry logic in relay-pty-orchestrator",
Expand Down Expand Up @@ -835,19 +835,6 @@
"startedAt": "2026-03-14T21:15:58.670Z",
"completedAt": "2026-03-14T21:19:05.548Z",
"path": "/Users/khaliqgant/Projects/relay/.trajectories/completed/2026-03/traj_qu5fbj9hzhdz.json"
},
"traj_u6bndffr0b8g": {
"title": "Code review for assigned workflow changes",
"status": "abandoned",
"startedAt": "2026-03-12T08:38:19.960Z",
"completedAt": "2026-03-19T13:58:52.857Z",
"path": "/Users/khaliqgant/Projects/AgentWorkforce/relay/.trajectories/completed/2026-03/traj_u6bndffr0b8g.json"
},
"traj_49mvfl01ogcy": {
"title": "Fix MCP tools not available for agents spawned via agent_add",
"status": "active",
"startedAt": "2026-03-19T13:58:53.083Z",
"path": "/Users/khaliqgant/Projects/AgentWorkforce/relay/.trajectories/active/traj_49mvfl01ogcy.json"
}
}
}
2 changes: 2 additions & 0 deletions src/snippets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ pub fn relaycast_mcp_config_json_with_token(
///
/// Later sources override earlier ones (matching Claude's own precedence).
/// The relaycast entry always wins (prevents stale entries from overriding broker creds).
#[allow(dead_code)]
fn merge_relaycast_with_project_mcp(
relay_api_key: Option<&str>,
relay_base_url: Option<&str>,
Expand All @@ -289,6 +290,7 @@ fn merge_relaycast_with_project_mcp(
}

/// Inner implementation that accepts an explicit home directory for testability.
#[allow(dead_code)]
#[allow(clippy::too_many_arguments)]
fn merge_relaycast_with_project_mcp_inner(
relay_api_key: Option<&str>,
Expand Down
19 changes: 16 additions & 3 deletions workflows/polish-workflow-output.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { execSync } from 'node:child_process';
import { workflow, createWorkflowRenderer } from '@agent-relay/sdk/workflows';

const renderer = createWorkflowRenderer();

try {
execSync('npx trail start "Polish workflow output with listr2 + chalk"', { stdio: 'ignore' });
} catch {}
Comment on lines +6 to +8

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Trail left permanently in "active" state when workflow throws

trail start is called unconditionally at line 7, but trail complete/trail abandon at lines 255-261 are only reached if Promise.all on line 10 resolves successfully. The execute() method in packages/sdk/src/workflows/runner.ts:1793-1814 can throw before entering its internal try/catch (e.g., config validation failures, missing workflow name, path validation errors), which would cause Promise.all to reject. Since there is no try/catch around the await Promise.all(...) call, the rejection propagates as an unhandled error, skipping the trail finalization block entirely. The trajectory is left in "active" state indefinitely, polluting the trajectory index.

The fix is to wrap the Promise.all and subsequent logic in a try/catch/finally that ensures trail abandon is called when an exception occurs.

Prompt for agents
In workflows/polish-workflow-output.ts, the trail start at lines 6-8 and the trail complete/abandon at lines 254-261 are not connected by a try/finally, so if Promise.all on line 10 throws, the trail is never closed. Wrap the entire workflow execution (lines 10-262) in a try/catch/finally block so that trail abandon is always called on error. For example:

let result;
try {
  [result] = await Promise.all([
    workflow(...)
      ...run({ onEvent: renderer.onEvent }),
    renderer.start(),
  ]);
  renderer.unmount();
} catch (err) {
  renderer.unmount();
  try {
    execSync('npx trail abandon --reason "Workflow threw an unexpected error"', { stdio: 'ignore' });
  } catch {}
  throw err;
}

try {
  if (result.status === 'completed') {
    execSync('npx trail complete --summary "Polished workflow output with listr2 + chalk" --confidence 0.88', { stdio: 'ignore' });
  } else {
    execSync(`npx trail abandon --reason "Workflow ended with status: ${result.status}"`, { stdio: 'ignore' });
  }
} catch {}

console.log('Result:', result.status);

This ensures the trail is properly abandoned if Promise.all rejects.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


const [result] = await Promise.all([
workflow('polish-workflow-output')
.description('Replace plain console.log workflow output with listr2 + chalk for a polished CLI experience')
Expand Down Expand Up @@ -119,10 +124,10 @@ package.json). Use the latest chalk version (v5+) with standard ESM imports.
{{steps.read-package-json.output}}

Produce a detailed implementation plan covering:
1. Exact npm install command (listr2 version, chalk@4 pinned)
1. Exact npm install command (listr2 version, latest chalk with ESM imports)
2. Complete new implementation for \`cli.ts\` (write the full file)
3. Exact before/after replacements for the 3 runner.ts locations
4. TypeScript import style for chalk and listr2 in CJS context
4. TypeScript import style for chalk and listr2 in ESM context
5. How the listr2 task map is keyed (stepName → task) and updated per event
6. How step:owner-assigned, step:retrying, step:nudged events render as
subtask output lines rather than top-level tasks
Expand All @@ -135,7 +140,7 @@ PLAN_COMPLETE`,
.step('install-deps', {
type: 'deterministic',
dependsOn: ['plan'],
command: 'cd packages/sdk && npm install listr2 chalk@4 2>&1 && echo "exit=0"',
command: 'cd packages/sdk && npm install listr2 chalk 2>&1 && echo "exit=0"',
captureOutput: true,
failOnError: true,
})
Expand Down Expand Up @@ -246,4 +251,12 @@ Approve when the implementation is complete and working.`,
]);
renderer.unmount();

try {
if (result.status === 'completed') {
execSync('npx trail complete --summary "Polished workflow output with listr2 + chalk" --confidence 0.88', { stdio: 'ignore' });
} else {
execSync(`npx trail abandon --reason "Workflow ended with status: ${result.status}"`, { stdio: 'ignore' });
}
} catch {}

console.log('Result:', result.status);
Loading