morpheus-cli 0.5.5 → 0.5.6

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/dist/http/api.js CHANGED
@@ -248,6 +248,18 @@ export function createApiRouter(oracle) {
248
248
  res.status(500).json({ error: err.message });
249
249
  }
250
250
  });
251
+ router.post('/tasks/:id/cancel', (req, res) => {
252
+ try {
253
+ const ok = taskRepository.cancelTask(req.params.id);
254
+ if (!ok) {
255
+ return res.status(404).json({ error: 'Active task not found for cancellation' });
256
+ }
257
+ res.json({ success: true });
258
+ }
259
+ catch (err) {
260
+ res.status(500).json({ error: err.message });
261
+ }
262
+ });
251
263
  // Legacy /session/reset (keep for backward compat or redirect to POST /sessions)
252
264
  router.post('/session/reset', async (req, res) => {
253
265
  try {
@@ -43,10 +43,12 @@ export class TaskDispatcher {
43
43
  return;
44
44
  }
45
45
  if (task.origin_channel === 'ui') {
46
- const statusIcon = task.status === 'completed' ? '✅' : '❌';
46
+ const statusIcon = task.status === 'completed' ? '✅' : task.status === 'cancelled' ? '🚫' : '❌';
47
47
  const body = task.status === 'completed'
48
48
  ? (task.output && task.output.trim().length > 0 ? task.output : 'Task completed without output.')
49
- : (task.error && task.error.trim().length > 0 ? task.error : 'Task failed with unknown error.');
49
+ : task.status === 'cancelled'
50
+ ? 'Task was cancelled.'
51
+ : (task.error && task.error.trim().length > 0 ? task.error : 'Task failed with unknown error.');
50
52
  const content = `${statusIcon}\ Task \`${task.id.toUpperCase()}\`\n` +
51
53
  `Agent: \`${task.agent.toUpperCase()}\`\n` +
52
54
  `Status: \`${task.status.toUpperCase()}\`\n\n${body}`;
@@ -70,10 +72,12 @@ export class TaskDispatcher {
70
72
  if (!adapter) {
71
73
  throw new Error('Telegram adapter not connected');
72
74
  }
73
- const statusIcon = task.status === 'completed' ? '✅' : '❌';
75
+ const statusIcon = task.status === 'completed' ? '✅' : task.status === 'cancelled' ? '🚫' : '❌';
74
76
  const body = task.status === 'completed'
75
77
  ? (task.output && task.output.trim().length > 0 ? task.output : 'Task completed without output.')
76
- : (task.error && task.error.trim().length > 0 ? task.error : 'Task failed with unknown error.');
78
+ : task.status === 'cancelled'
79
+ ? 'Task was cancelled.'
80
+ : (task.error && task.error.trim().length > 0 ? task.error : 'Task failed with unknown error.');
77
81
  const header = `${statusIcon}\ Task \`${task.id.toUpperCase()}\`\n` +
78
82
  `Agent: \`${task.agent.toUpperCase()}\`\n` +
79
83
  `Status: \`${task.status.toUpperCase()}\``;
@@ -240,7 +240,7 @@ export class TaskRepository {
240
240
  notify_status = 'pending',
241
241
  notify_last_error = NULL,
242
242
  notified_at = NULL
243
- WHERE id = ?
243
+ WHERE id = ? AND status != 'cancelled'
244
244
  `).run(normalizedOutput.length > 0 ? normalizedOutput : 'Task completed without output.', now, now, id);
245
245
  }
246
246
  markFailed(id, error) {
@@ -253,9 +253,22 @@ export class TaskRepository {
253
253
  updated_at = ?,
254
254
  notify_status = 'pending',
255
255
  notified_at = NULL
256
- WHERE id = ?
256
+ WHERE id = ? AND status != 'cancelled'
257
257
  `).run(error, now, now, id);
258
258
  }
259
+ cancelTask(id) {
260
+ const now = Date.now();
261
+ const result = this.db.prepare(`
262
+ UPDATE tasks
263
+ SET status = 'cancelled',
264
+ finished_at = ?,
265
+ updated_at = ?,
266
+ notify_status = 'pending',
267
+ notified_at = NULL
268
+ WHERE id = ? AND status IN ('pending', 'running')
269
+ `).run(now, now, id);
270
+ return result.changes > 0;
271
+ }
259
272
  retryTask(id) {
260
273
  const now = Date.now();
261
274
  const result = this.db.prepare(`
@@ -306,7 +319,7 @@ export class TaskRepository {
306
319
  const row = this.db.prepare(`
307
320
  SELECT id
308
321
  FROM tasks
309
- WHERE status IN ('completed', 'failed')
322
+ WHERE status IN ('completed', 'failed', 'cancelled')
310
323
  AND notify_status = 'pending'
311
324
  AND finished_at IS NOT NULL
312
325
  AND finished_at <= ?
@@ -338,7 +351,7 @@ export class TaskRepository {
338
351
  SET notify_status = 'pending',
339
352
  notify_last_error = COALESCE(notify_last_error, 'Recovered notification queue state'),
340
353
  updated_at = ?
341
- WHERE status IN ('completed', 'failed')
354
+ WHERE status IN ('completed', 'failed', 'cancelled')
342
355
  AND (
343
356
  (notify_status = 'sending' AND updated_at <= ?)
344
357
  OR