feat: add remote agent execution feature and notification for unblocked tasks

- Updated README to include a new TODO for remote agent execution via SSH.
- Implemented a notification system that alerts owners of blocked tasks when their dependencies are resolved, enhancing task management and collaboration.
This commit is contained in:
iliya 2026-03-21 14:21:13 +02:00
parent 7c9631c1b9
commit 67f38d8029
2 changed files with 74 additions and 2 deletions

View file

@ -237,6 +237,7 @@ pnpm dist # macOS + Windows + Linux
## TODO
- [ ] CLI runtime: Run not only on a local PC but in any headless/console environment (web UI), e.g. VPS, remote server, etc.
- [ ] Remote agent execution via SSH: launch and manage agent teams on remote machines over SSH (stream-json protocol over SSH channel, SFTP-based file monitoring for tasks/inboxes/config)
- [ ] 2 modes: current (agent teams), and a new mode: regular subagents (no communication between them)
- [ ] Visual workflow editor ([@xyflow/react](https://github.com/xyflow/xyflow)) for building and orchestrating agent pipelines with drag & drop
- [ ] Planning mode to organize agent plans before execution

View file

@ -231,8 +231,79 @@ function startTask(context, taskId, actor) {
return task;
}
function notifyUnblockedOwners(context, completedTask) {
const blockedIds = Array.isArray(completedTask.blocks) ? completedTask.blocks : [];
if (blockedIds.length === 0) return;
const completedLabel = `#${completedTask.displayId || completedTask.id}`;
for (const blockedId of blockedIds) {
try {
const blockedTask = taskStore.readTask(context.paths, blockedId, { includeDeleted: true });
if (blockedTask.status === 'deleted' || blockedTask.status === 'completed') continue;
if (!normalizeActorName(blockedTask.owner)) continue;
const allBlockerIds = Array.isArray(blockedTask.blockedBy) ? blockedTask.blockedBy : [];
const pendingBlockers = allBlockerIds.filter((id) => {
if (id === completedTask.id) return false;
try {
const t = taskStore.readTask(context.paths, id, { includeDeleted: true });
return t.status !== 'completed' && t.status !== 'deleted';
} catch { return false; }
});
const allResolved = pendingBlockers.length === 0;
const blockedLabel = `#${blockedTask.displayId || blockedTask.id}`;
let pendingList = '';
if (!allResolved) {
const refs = pendingBlockers.map((id) => {
try {
const t = taskStore.readTask(context.paths, id, { includeDeleted: true });
return `#${t.displayId || t.id}`;
} catch { return `#${id.slice(0, 8)}`; }
});
pendingList = refs.join(', ');
}
const lines = [
`**Dependency resolved** — task ${completedLabel} _${completedTask.subject}_ completed.`,
``,
allResolved
? `All blockers for ${blockedLabel} are resolved — this task is ready to start.`
: `${allBlockerIds.length - pendingBlockers.length} of ${allBlockerIds.length} blockers resolved. Still waiting on: ${pendingList}.`,
];
if (allResolved) {
lines.push(
``,
wrapAgentBlock(
`All dependencies for this task are now resolved.\n` +
`If you are idle, start working on it now:\n` +
`1. Check the full context: task_get { teamName: "${context.teamName}", taskId: "${blockedTask.id}" }\n` +
`2. Start the task: task_start { teamName: "${context.teamName}", taskId: "${blockedTask.id}" }`
)
);
}
addTaskComment(context, blockedTask.id, {
text: lines.join('\n'),
from: 'system',
});
} catch {
// Best-effort per blocked task: skip on failure
}
}
}
function completeTask(context, taskId, actor) {
return setTaskStatus(context, taskId, 'completed', actor);
const task = setTaskStatus(context, taskId, 'completed', actor);
try {
notifyUnblockedOwners(context, task, actor);
} catch {
// Best-effort: task completion succeeded, notification failure is non-fatal
}
return task;
}
function softDeleteTask(context, taskId, actor) {
@ -475,7 +546,7 @@ function buildMemberTaskProtocol(teamName) {
e) Do NOT set clarification to "user" yourself only the team lead escalates to the user.
13. DEPENDENCY AWARENESS:
When your task has blockedBy dependencies, check if they are completed before starting.
When you complete a task that blocks others, mention this in your completion message so blocked teammates can proceed.
When you complete a task that blocks others, blocked task owners are notified automatically via a task comment.
14. TASK QUEUE DISCIPLINE:
- Use task_briefing as a compact queue view of your assigned tasks.
- task_briefing may include full description/comments only for in_progress tasks; needsFix/pending/review/completed entries may be minimal on purpose.