fix(team): notify lead on task create with startImmediately
Extract sendUserTaskStartNotification as reusable private method. When a task is created via UI directly in "In Progress" column (startImmediately=true), the controller's maybeNotifyAssignedOwner skips the lead. Now createTask sends the notification to the lead with full description, prompt, and task_get instructions.
This commit is contained in:
parent
58f3ccd4b4
commit
bd90de8e81
1 changed files with 54 additions and 33 deletions
|
|
@ -877,6 +877,19 @@ export class TeamDataService {
|
|||
...(shouldStart ? { startImmediately: true } : {}),
|
||||
}) as TeamTask;
|
||||
|
||||
// Controller's maybeNotifyAssignedOwner skips the lead (owner === lead).
|
||||
// For user-created tasks with startImmediately, ensure the lead also gets notified.
|
||||
if (shouldStart) {
|
||||
try {
|
||||
const leadName = await this.resolveLeadName(teamName);
|
||||
if (this.isLeadOwner(task.owner!, leadName)) {
|
||||
await this.sendUserTaskStartNotification(teamName, task);
|
||||
}
|
||||
} catch {
|
||||
/* best-effort */
|
||||
}
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
|
|
@ -945,44 +958,52 @@ export class TeamDataService {
|
|||
this.getController(teamName).tasks.startTask(taskId, 'user');
|
||||
|
||||
if (task.owner) {
|
||||
try {
|
||||
const parts = [
|
||||
`**start working on task now** ${this.getTaskLabel(task)} "${task.subject}"`,
|
||||
];
|
||||
if (task.description?.trim()) {
|
||||
parts.push(`\nDetails:\n${task.description.trim()}`);
|
||||
}
|
||||
if (task.prompt?.trim()) {
|
||||
parts.push(`\nInstructions:\n${task.prompt.trim()}`);
|
||||
}
|
||||
parts.push(
|
||||
'',
|
||||
wrapAgentBlock(
|
||||
[
|
||||
`Begin work on this task immediately. Keep it moving until it is completed or clearly blocked. Do not leave it idle.`,
|
||||
`To fetch the full task context (description, comments, attachments) use:`,
|
||||
`task_get { teamName: "${teamName}", taskId: "${task.id}" }`,
|
||||
`When done, update task status:`,
|
||||
`task_complete { teamName: "${teamName}", taskId: "${task.id}" }`,
|
||||
].join('\n')
|
||||
)
|
||||
);
|
||||
await this.sendMessage(teamName, {
|
||||
member: task.owner,
|
||||
from: 'user',
|
||||
text: parts.join('\n'),
|
||||
taskRefs: task.descriptionTaskRefs,
|
||||
summary: `Start working on ${this.getTaskLabel(task)}`,
|
||||
source: 'system_notification',
|
||||
});
|
||||
} catch {
|
||||
// Best-effort notification
|
||||
}
|
||||
await this.sendUserTaskStartNotification(teamName, task);
|
||||
}
|
||||
|
||||
return { notifiedOwner: !!task.owner };
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a task start notification from the user to the task owner.
|
||||
* Includes description, prompt, and task_get/task_complete instructions.
|
||||
* Used by startTaskByUser and createTask (startImmediately).
|
||||
*/
|
||||
private async sendUserTaskStartNotification(teamName: string, task: TeamTask): Promise<void> {
|
||||
if (!task.owner) return;
|
||||
try {
|
||||
const parts = [`**start working on task now** ${this.getTaskLabel(task)} "${task.subject}"`];
|
||||
if (task.description?.trim()) {
|
||||
parts.push(`\nDetails:\n${task.description.trim()}`);
|
||||
}
|
||||
if (task.prompt?.trim()) {
|
||||
parts.push(`\nInstructions:\n${task.prompt.trim()}`);
|
||||
}
|
||||
parts.push(
|
||||
'',
|
||||
wrapAgentBlock(
|
||||
[
|
||||
`Begin work on this task immediately. Keep it moving until it is completed or clearly blocked. Do not leave it idle.`,
|
||||
`To fetch the full task context (description, comments, attachments) use:`,
|
||||
`task_get { teamName: "${teamName}", taskId: "${task.id}" }`,
|
||||
`When done, update task status:`,
|
||||
`task_complete { teamName: "${teamName}", taskId: "${task.id}" }`,
|
||||
].join('\n')
|
||||
)
|
||||
);
|
||||
await this.sendMessage(teamName, {
|
||||
member: task.owner,
|
||||
from: 'user',
|
||||
text: parts.join('\n'),
|
||||
taskRefs: task.descriptionTaskRefs,
|
||||
summary: `Start working on ${this.getTaskLabel(task)}`,
|
||||
source: 'system_notification',
|
||||
});
|
||||
} catch {
|
||||
// Best-effort notification
|
||||
}
|
||||
}
|
||||
|
||||
async updateTaskStatus(
|
||||
teamName: string,
|
||||
taskId: string,
|
||||
|
|
|
|||
Loading…
Reference in a new issue