@pixelbyte-software/pixcode 1.36.4 → 1.37.0

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 (45) hide show
  1. package/dist/assets/index-CfHK8y_H.css +32 -0
  2. package/dist/assets/{index-D-YjltED.js → index-D8uNxHf1.js} +163 -157
  3. package/dist/index.html +2 -2
  4. package/dist-server/server/database/db.js +4 -2
  5. package/dist-server/server/database/db.js.map +1 -1
  6. package/dist-server/server/index.js +3 -0
  7. package/dist-server/server/index.js.map +1 -1
  8. package/dist-server/server/modules/orchestration/tasks/orchestration-task.routes.js +10 -1
  9. package/dist-server/server/modules/orchestration/tasks/orchestration-task.routes.js.map +1 -1
  10. package/dist-server/server/modules/orchestration/tasks/orchestration-task.service.js +7 -0
  11. package/dist-server/server/modules/orchestration/tasks/orchestration-task.service.js.map +1 -1
  12. package/dist-server/server/modules/orchestration/workflows/workflow-runner.js +127 -24
  13. package/dist-server/server/modules/orchestration/workflows/workflow-runner.js.map +1 -1
  14. package/dist-server/server/routes/taskmaster.js +194 -0
  15. package/dist-server/server/routes/taskmaster.js.map +1 -1
  16. package/dist-server/server/services/install-jobs.js +1 -0
  17. package/dist-server/server/services/install-jobs.js.map +1 -1
  18. package/dist-server/server/services/notification-orchestrator.js +66 -9
  19. package/dist-server/server/services/notification-orchestrator.js.map +1 -1
  20. package/dist-server/server/services/telegram/control-center.js +144 -2
  21. package/dist-server/server/services/telegram/control-center.js.map +1 -1
  22. package/dist-server/server/services/telegram/translations.js +14 -2
  23. package/dist-server/server/services/telegram/translations.js.map +1 -1
  24. package/package.json +1 -1
  25. package/scripts/smoke/chat-realtime-hydration.mjs +44 -0
  26. package/scripts/smoke/multi-worker-slots.mjs +42 -0
  27. package/scripts/smoke/notification-center.mjs +63 -0
  28. package/scripts/smoke/orchestration-execution-dashboard.mjs +33 -0
  29. package/scripts/smoke/strict-handoff-compact.mjs +60 -0
  30. package/scripts/smoke/taskmaster-execution-telegram.mjs +52 -0
  31. package/scripts/smoke/taskmaster-onboarding.mjs +52 -0
  32. package/scripts/smoke/update-issue-progress.mjs +69 -0
  33. package/server/database/db.js +4 -2
  34. package/server/index.js +3 -0
  35. package/server/modules/orchestration/tasks/orchestration-task.routes.ts +10 -1
  36. package/server/modules/orchestration/tasks/orchestration-task.service.ts +7 -0
  37. package/server/modules/orchestration/tasks/orchestration-task.types.ts +3 -0
  38. package/server/modules/orchestration/workflows/workflow-runner.ts +132 -24
  39. package/server/modules/orchestration/workflows/workflow.types.ts +2 -0
  40. package/server/routes/taskmaster.js +201 -0
  41. package/server/services/install-jobs.js +1 -0
  42. package/server/services/notification-orchestrator.js +76 -8
  43. package/server/services/telegram/control-center.js +153 -2
  44. package/server/services/telegram/translations.js +14 -2
  45. package/dist/assets/index-CgF0-_6Z.css +0 -32
@@ -23,6 +23,11 @@ const PROVIDER_LABELS = {
23
23
 
24
24
  const recentEventKeys = new Map();
25
25
  const DEDUPE_WINDOW_MS = 20000;
26
+ let notificationWebSocketServer = null;
27
+
28
+ function setNotificationWebSocketServer(wss) {
29
+ notificationWebSocketServer = wss;
30
+ }
26
31
 
27
32
  const cleanupOldEventKeys = () => {
28
33
  const now = Date.now();
@@ -41,6 +46,22 @@ function shouldSendPush(preferences, event) {
41
46
  return webPushEnabled && eventEnabled;
42
47
  }
43
48
 
49
+ function shouldSendInApp(preferences, event) {
50
+ const inAppEnabled = preferences?.channels?.inApp !== false;
51
+ const prefEventKey = KIND_TO_PREF_KEY[event.kind];
52
+ const eventEnabled = prefEventKey ? preferences?.events?.[prefEventKey] !== false : true;
53
+
54
+ return inAppEnabled && eventEnabled;
55
+ }
56
+
57
+ function shouldSendTelegram(preferences, event) {
58
+ const telegramEnabled = preferences?.channels?.telegram !== false;
59
+ const prefEventKey = KIND_TO_PREF_KEY[event.kind];
60
+ const eventEnabled = prefEventKey ? preferences?.events?.[prefEventKey] !== false : true;
61
+
62
+ return telegramEnabled && eventEnabled;
63
+ }
64
+
44
65
  function isDuplicate(event) {
45
66
  cleanupOldEventKeys();
46
67
  const key = event.dedupeKey || `${event.provider}:${event.kind || 'info'}:${event.code || 'generic'}:${event.sessionId || 'none'}`;
@@ -149,6 +170,41 @@ function buildPushBody(event) {
149
170
  };
150
171
  }
151
172
 
173
+ function buildNotificationPayload(event) {
174
+ const pushBody = buildPushBody(event);
175
+ return {
176
+ id: event.dedupeKey || `${event.provider || 'system'}:${event.kind || 'info'}:${event.code || 'generic'}:${event.sessionId || 'none'}:${event.createdAt}`,
177
+ title: pushBody.title,
178
+ body: pushBody.body,
179
+ kind: event.kind || 'info',
180
+ code: event.code || 'generic.info',
181
+ severity: event.severity || 'info',
182
+ provider: event.provider || null,
183
+ sessionId: event.sessionId || null,
184
+ createdAt: event.createdAt,
185
+ requiresUserAction: Boolean(event.requiresUserAction),
186
+ data: pushBody.data
187
+ };
188
+ }
189
+
190
+ function broadcastInAppNotification(userId, event) {
191
+ if (!notificationWebSocketServer || !userId || !event) {
192
+ return;
193
+ }
194
+
195
+ const message = JSON.stringify({
196
+ type: 'notification:event',
197
+ notification: buildNotificationPayload(event)
198
+ });
199
+ const normalizedUserId = String(userId);
200
+
201
+ notificationWebSocketServer.clients.forEach((client) => {
202
+ if (client.readyState === 1 && String(client.userId || '') === normalizedUserId) {
203
+ client.send(message);
204
+ }
205
+ });
206
+ }
207
+
152
208
  async function sendWebPush(userId, event) {
153
209
  const subscriptions = pushSubscriptionsDb.getSubscriptions(userId);
154
210
  if (!subscriptions.length) return;
@@ -191,6 +247,14 @@ function notifyUserIfEnabled({ userId, event }) {
191
247
  return;
192
248
  }
193
249
 
250
+ if (shouldSendInApp(preferences, event)) {
251
+ try {
252
+ broadcastInAppNotification(userId, event);
253
+ } catch (err) {
254
+ console.error('In-app notification send error:', err);
255
+ }
256
+ }
257
+
194
258
  if (shouldSendPush(preferences, event)) {
195
259
  sendWebPush(userId, event).catch((err) => {
196
260
  console.error('Web push send error:', err);
@@ -203,14 +267,16 @@ function notifyUserIfEnabled({ userId, event }) {
203
267
  const providerLabel = PROVIDER_LABELS[event.provider] || event.provider || 'Session';
204
268
  const sessionTitle = event.meta?.sessionName || providerLabel;
205
269
  const errorText = event.meta?.error || '';
206
- notifyTelegramUser({
207
- userId,
208
- kind: event.kind,
209
- title: sessionTitle,
210
- error: errorText,
211
- }).catch((err) => {
212
- console.warn('[telegram] notify failed:', err?.message || err);
213
- });
270
+ if (shouldSendTelegram(preferences, event)) {
271
+ notifyTelegramUser({
272
+ userId,
273
+ kind: event.kind,
274
+ title: sessionTitle,
275
+ error: errorText,
276
+ }).catch((err) => {
277
+ console.warn('[telegram] notify failed:', err?.message || err);
278
+ });
279
+ }
214
280
  }
215
281
 
216
282
  function notifyRunStopped({ userId, provider, sessionId = null, stopReason = 'completed', sessionName = null }) {
@@ -247,6 +313,8 @@ function notifyRunFailed({ userId, provider, sessionId = null, error, sessionNam
247
313
 
248
314
  export {
249
315
  createNotificationEvent,
316
+ setNotificationWebSocketServer,
317
+ broadcastInAppNotification,
250
318
  notifyUserIfEnabled,
251
319
  notifyRunStopped,
252
320
  notifyRunFailed
@@ -49,6 +49,8 @@ const CONTROL_COMMANDS = new Set([
49
49
  '/workflows',
50
50
  '/orchestration',
51
51
  '/runs',
52
+ '/tasks',
53
+ '/task',
52
54
  '/settings',
53
55
  '/install',
54
56
  '/auth',
@@ -210,8 +212,9 @@ function mainMenuKeyboard(lang) {
210
212
  return [
211
213
  [button(t(lang, 'control.button.projects'), 'projects'), button(t(lang, 'control.button.provider'), 'providers')],
212
214
  [button(t(lang, 'control.button.models'), 'models'), button(t(lang, 'control.button.workflows'), 'workflows')],
213
- [button(t(lang, 'control.button.runs'), 'runs'), button(t(lang, 'control.button.install'), 'install_menu')],
214
- [button(t(lang, 'control.button.auth'), 'auth_menu'), button(t(lang, 'control.button.settings'), 'settings')],
215
+ [button(t(lang, 'control.button.tasks'), 'tasks'), button(t(lang, 'control.button.runs'), 'runs')],
216
+ [button(t(lang, 'control.button.install'), 'install_menu'), button(t(lang, 'control.button.auth'), 'auth_menu')],
217
+ [button(t(lang, 'control.button.settings'), 'settings')],
215
218
  ];
216
219
  }
217
220
 
@@ -344,6 +347,37 @@ async function showRuns({ bot, chatId, link, editMessageId }) {
344
347
  });
345
348
  }
346
349
 
350
+ async function showTaskMasterTasks({ bot, chatId, link, editMessageId }) {
351
+ const lang = languageFor(link);
352
+ const state = getState(link.user_id);
353
+ if (!state.selectedProjectName) {
354
+ await send(bot, chatId, t(lang, 'control.selectProjectFirst'), { editMessageId });
355
+ await showProjectMenu({ bot, chatId, link });
356
+ return;
357
+ }
358
+
359
+ const data = await localApi(link.user_id, `/api/taskmaster/tasks/${encodeURIComponent(state.selectedProjectName)}`);
360
+ const tasks = Array.isArray(data?.tasks) ? data.tasks : [];
361
+ const activeTasks = tasks.filter((task) => !['done', 'completed', 'cancelled', 'canceled'].includes(String(task.status || '').toLowerCase()));
362
+ if (activeTasks.length === 0) {
363
+ await send(bot, chatId, t(lang, 'control.noTaskMasterTasks'), {
364
+ editMessageId,
365
+ reply_markup: { inline_keyboard: [[button(t(lang, 'control.button.mainMenu'), 'menu')]] },
366
+ });
367
+ return;
368
+ }
369
+
370
+ const buttons = activeTasks.slice(0, 12).map((task) => button(
371
+ `#${task.id} ${compact(task.title, 38)}`,
372
+ 'task_run',
373
+ { taskId: String(task.id) },
374
+ ));
375
+ await send(bot, chatId, t(lang, 'control.pickTaskMasterTask'), {
376
+ editMessageId,
377
+ reply_markup: { inline_keyboard: rows(buttons, 1) },
378
+ });
379
+ }
380
+
347
381
  function extractAssistantText(response) {
348
382
  const messages = Array.isArray(response?.messages) ? response.messages : [];
349
383
  const chunks = [];
@@ -437,6 +471,10 @@ async function fetchRun(userId, runId) {
437
471
  return localApi(userId, `/api/orchestration/workflows/runs/${runId}`);
438
472
  }
439
473
 
474
+ async function fetchA2ATask(userId, taskId) {
475
+ return localApi(userId, `/a2a/tasks/${encodeURIComponent(taskId)}`);
476
+ }
477
+
440
478
  function summarizeRun(run, mode) {
441
479
  const lines = [
442
480
  `Run ${run.id}`,
@@ -485,6 +523,100 @@ async function monitorWorkflowRun({ bot, chatId, link, runId }) {
485
523
  }
486
524
  }
487
525
 
526
+ function extractA2ATaskText(task) {
527
+ const chunks = [];
528
+ const artifacts = Array.isArray(task?.artifacts) ? task.artifacts : [];
529
+ for (const artifact of artifacts) {
530
+ for (const part of Array.isArray(artifact?.parts) ? artifact.parts : []) {
531
+ if (part?.kind === 'text' && typeof part.text === 'string') chunks.push(part.text);
532
+ if (part?.type === 'text' && typeof part.text === 'string') chunks.push(part.text);
533
+ }
534
+ }
535
+ const history = Array.isArray(task?.history) ? task.history : [];
536
+ for (const message of history) {
537
+ if (message?.role !== 'assistant') continue;
538
+ for (const part of Array.isArray(message?.parts) ? message.parts : []) {
539
+ if (part?.kind === 'text' && typeof part.text === 'string') chunks.push(part.text);
540
+ if (part?.type === 'text' && typeof part.text === 'string') chunks.push(part.text);
541
+ }
542
+ }
543
+ return chunks.join('\n\n').trim();
544
+ }
545
+
546
+ function summarizeA2ATask(task) {
547
+ const text = extractA2ATaskText(task);
548
+ const error = task?.error?.message || task?.metadata?.error?.message || '';
549
+ return truncate([
550
+ `Task ${task?.id || ''}`,
551
+ `Status: ${task?.state || 'unknown'}`,
552
+ error ? `Error: ${error}` : '',
553
+ text,
554
+ ].filter(Boolean).join('\n\n'));
555
+ }
556
+
557
+ async function monitorA2ATask({ bot, chatId, link, taskId }) {
558
+ const key = `a2a:${taskId}`;
559
+ if (runMonitors.has(key)) return;
560
+ runMonitors.set(key, true);
561
+ const lang = languageFor(link);
562
+ try {
563
+ for (;;) {
564
+ await new Promise((resolve) => setTimeout(resolve, 5000));
565
+ const task = await fetchA2ATask(link.user_id, taskId);
566
+ if (TERMINAL_RUN_STATES.has(task?.state)) {
567
+ await send(bot, chatId, t(lang, 'control.taskFinished', {
568
+ taskId,
569
+ status: task.state,
570
+ summary: summarizeA2ATask(task),
571
+ }));
572
+ return;
573
+ }
574
+ }
575
+ } finally {
576
+ runMonitors.delete(key);
577
+ }
578
+ }
579
+
580
+ async function runTaskMasterTask({ bot, chatId, link, taskId }) {
581
+ const lang = languageFor(link);
582
+ const state = getState(link.user_id);
583
+ if (!state.remoteControlEnabled) {
584
+ await send(bot, chatId, t(lang, 'control.disabled'));
585
+ return;
586
+ }
587
+ if (!state.selectedProjectName) {
588
+ await send(bot, chatId, t(lang, 'control.selectProjectFirst'));
589
+ await showProjectMenu({ bot, chatId, link });
590
+ return;
591
+ }
592
+
593
+ const result = await localApi(
594
+ link.user_id,
595
+ `/api/taskmaster/execute/${encodeURIComponent(state.selectedProjectName)}/${encodeURIComponent(taskId)}`,
596
+ {
597
+ method: 'POST',
598
+ body: {
599
+ projectId: state.selectedProjectName,
600
+ adapterId: state.selectedProvider,
601
+ model: state.selectedModel || undefined,
602
+ isolation: 'worktree',
603
+ },
604
+ },
605
+ );
606
+ const a2aTaskId = result?.task?.a2aTaskId;
607
+ await send(bot, chatId, t(lang, 'control.taskStarted', {
608
+ taskId,
609
+ provider: state.selectedProvider,
610
+ a2aTaskId: a2aTaskId || result?.task?.id || 'unknown',
611
+ }));
612
+
613
+ if (a2aTaskId) {
614
+ monitorA2ATask({ bot, chatId, link, taskId: a2aTaskId }).catch((error) => {
615
+ console.warn('[telegram-control] task monitor failed:', error?.message || error);
616
+ });
617
+ }
618
+ }
619
+
488
620
  export async function startCliInstall({ bot, chatId, link, provider }) {
489
621
  const lang = languageFor(link);
490
622
  const data = await localApi(link.user_id, `/api/providers/${provider}/install`, { method: 'POST' });
@@ -568,6 +700,10 @@ async function handleAwaitingInput({ bot, chatId, link, text }) {
568
700
  await runWorkflow({ bot, chatId, link, input: text });
569
701
  return true;
570
702
  }
703
+ if (awaiting.type === 'task_id') {
704
+ await runTaskMasterTask({ bot, chatId, link, taskId: text });
705
+ return true;
706
+ }
571
707
  return false;
572
708
  }
573
709
 
@@ -605,6 +741,19 @@ async function handleCommand({ bot, chatId, link, text }) {
605
741
  await showRuns({ bot, chatId, link });
606
742
  return true;
607
743
  }
744
+ if (command === '/tasks') {
745
+ await showTaskMasterTasks({ bot, chatId, link });
746
+ return true;
747
+ }
748
+ if (command === '/task') {
749
+ if (!argText) {
750
+ updateTelegramControlState(link.user_id, { awaiting: { type: 'task_id' } });
751
+ await send(bot, chatId, t(lang, 'control.sendTaskId'));
752
+ return true;
753
+ }
754
+ await runTaskMasterTask({ bot, chatId, link, taskId: argText });
755
+ return true;
756
+ }
608
757
  if (command === '/settings') {
609
758
  await showSettings({ bot, chatId, link });
610
759
  return true;
@@ -728,6 +877,7 @@ export async function handleTelegramControlCallback({ bot, query, link }) {
728
877
  if (action === 'models_refresh') return showModelMenu({ bot, chatId, link, refresh: true, editMessageId });
729
878
  if (action === 'workflows') return showWorkflowMenu({ bot, chatId, link, editMessageId });
730
879
  if (action === 'runs') return showRuns({ bot, chatId, link, editMessageId });
880
+ if (action === 'tasks') return showTaskMasterTasks({ bot, chatId, link, editMessageId });
731
881
  if (action === 'install_menu') return showInstallMenu({ bot, chatId, link, editMessageId });
732
882
  if (action === 'auth_menu') return showAuthMenu({ bot, chatId, link, editMessageId });
733
883
  if (action === 'settings') return showSettings({ bot, chatId, link, editMessageId });
@@ -787,6 +937,7 @@ export async function handleTelegramControlCallback({ bot, query, link }) {
787
937
  await send(bot, chatId, t(languageFor(link), 'control.runStatus', { runId: run.id, status: run.status }), { editMessageId });
788
938
  return;
789
939
  }
940
+ if (action === 'task_run') return runTaskMasterTask({ bot, chatId, link, taskId: payload.taskId });
790
941
  if (action === 'install_provider') return startCliInstall({ bot, chatId, link, provider: payload.provider });
791
942
  if (action === 'auth_provider') {
792
943
  await send(bot, chatId, `${payload.provider} login:\n${AUTH_HELP[payload.provider] || t(languageFor(link), 'control.providerAuthFallback')}`, { editMessageId });
@@ -18,7 +18,7 @@ const EN = {
18
18
  'bridge.queued': '📨 Message forwarded to your latest session. I will reply when the agent responds.',
19
19
  'bridge.disabled': 'Message bridge is disabled. Enable it in Pixcode → Settings → Telegram.',
20
20
  'control.menu': 'Pixcode Telegram control center',
21
- 'control.help': 'Commands: /menu, /projects, /provider, /model, /workflows, /runs, /chat <prompt>, /workflow <prompt>, /install, /auth, /settings, /progress final|steps|all, /control on|off.',
21
+ 'control.help': 'Commands: /menu, /projects, /provider, /model, /workflows, /runs, /tasks, /task <id>, /chat <prompt>, /workflow <prompt>, /install, /auth, /settings, /progress final|steps|all, /control on|off.',
22
22
  'control.examples': 'Examples:\n/chat summarize this project\n/chat fix the last error\n/workflow review the current changes\n/settings to change language and progress mode',
23
23
  'control.unknownCommand': 'I do not know that command yet. Here are the available Pixcode commands:',
24
24
  'control.onboarding': 'How to start:\n/projects to pick a project\n/provider to pick the CLI\n/model to choose the model\n/chat <prompt> to run the current agent\n/workflow <prompt> to run orchestration\n/help to see all commands',
@@ -32,6 +32,7 @@ const EN = {
32
32
  'control.button.models': 'Models',
33
33
  'control.button.workflows': 'Workflows',
34
34
  'control.button.runs': 'Runs',
35
+ 'control.button.tasks': 'Tasks',
35
36
  'control.button.install': 'CLI install',
36
37
  'control.button.auth': 'Auth help',
37
38
  'control.button.settings': 'Settings',
@@ -54,6 +55,8 @@ const EN = {
54
55
  'control.pickWorkflow': 'Pick an orchestration workflow:',
55
56
  'control.noRuns': 'No orchestration runs yet.',
56
57
  'control.recentRuns': 'Recent orchestration runs:',
58
+ 'control.noTaskMasterTasks': 'No open TaskMaster tasks were found for the selected project.',
59
+ 'control.pickTaskMasterTask': 'Pick a TaskMaster task to run with the selected provider:',
57
60
  'control.disabled': 'Telegram remote control is disabled. Enable it in Pixcode → Settings → Telegram or send /control on.',
58
61
  'control.selectProjectFirst': 'Select a project first with /projects.',
59
62
  'control.selectWorkflowFirst': 'Select a workflow first.',
@@ -62,6 +65,8 @@ const EN = {
62
65
  'control.agentFailed': 'Failed: {{error}}',
63
66
  'control.noAssistantText': 'No assistant text returned.',
64
67
  'control.workflowStarted': 'Orchestration started: {{runId}}\nWorkflow: {{workflowId}}',
68
+ 'control.taskStarted': 'TaskMaster task #{{taskId}} started with {{provider}}.\nA2A task: {{a2aTaskId}}',
69
+ 'control.taskFinished': 'TaskMaster execution finished for {{taskId}}: {{status}}\n\n{{summary}}',
65
70
  'control.installMenu': 'Install or repair a provider CLI:',
66
71
  'control.authMenu': 'Pick a provider for OAuth/login instructions:',
67
72
  'control.manualInstall': 'Manual install for {{provider}}:\n{{manual}}',
@@ -78,6 +83,7 @@ const EN = {
78
83
  'control.workflowSelected': 'Workflow selected: {{workflow}}',
79
84
  'control.sendAgentPrompt': 'Send the agent prompt.',
80
85
  'control.sendWorkflowPrompt': 'Send the orchestration prompt.',
86
+ 'control.sendTaskId': 'Send the TaskMaster task id to run.',
81
87
  'control.remoteEnabled': 'Remote control enabled.',
82
88
  'control.remoteDisabled': 'Remote control disabled.',
83
89
  'control.progressUsage': 'Use /progress final, /progress steps, or /progress all.',
@@ -103,7 +109,7 @@ const TR = {
103
109
  'bridge.queued': '📨 Mesaj son oturumuna iletildi. Ajan cevap verince sana yazacağım.',
104
110
  'bridge.disabled': 'Mesaj köprüsü kapalı. Pixcode → Ayarlar → Telegram\'dan açabilirsin.',
105
111
  'control.menu': 'Pixcode Telegram kontrol merkezi',
106
- 'control.help': 'Komutlar: /menu, /projects, /provider, /model, /workflows, /runs, /chat <prompt>, /workflow <prompt>, /install, /auth, /settings, /progress final|steps|all, /control on|off.',
112
+ 'control.help': 'Komutlar: /menu, /projects, /provider, /model, /workflows, /runs, /tasks, /task <id>, /chat <prompt>, /workflow <prompt>, /install, /auth, /settings, /progress final|steps|all, /control on|off.',
107
113
  'control.examples': 'Örnekler:\n/chat bu projeyi özetle\n/chat son hatayı düzelt\n/workflow mevcut değişiklikleri incele\n/settings ile dil ve ilerleme modunu değiştir',
108
114
  'control.unknownCommand': 'Bu komutu henüz tanımıyorum. Kullanabileceğin Pixcode komutları:',
109
115
  'control.onboarding': 'Nasıl başlarsın:\n/projects ile proje seç\n/provider ile CLI seç\n/model ile modeli seç\n/chat <prompt> ile ajanı çalıştır\n/workflow <prompt> ile orkestrasyon başlat\n/help ile tüm komutları gör',
@@ -117,6 +123,7 @@ const TR = {
117
123
  'control.button.models': 'Modeller',
118
124
  'control.button.workflows': 'İş akışları',
119
125
  'control.button.runs': 'Çalışmalar',
126
+ 'control.button.tasks': 'Görevler',
120
127
  'control.button.install': 'CLI kur',
121
128
  'control.button.auth': 'Giriş yardımı',
122
129
  'control.button.settings': 'Ayarlar',
@@ -139,6 +146,8 @@ const TR = {
139
146
  'control.pickWorkflow': 'Bir orkestrasyon iş akışı seç:',
140
147
  'control.noRuns': 'Henüz orkestrasyon çalışması yok.',
141
148
  'control.recentRuns': 'Son orkestrasyon çalışmaları:',
149
+ 'control.noTaskMasterTasks': 'Seçili proje için açık TaskMaster görevi bulunamadı.',
150
+ 'control.pickTaskMasterTask': 'Seçili sağlayıcıyla çalıştırılacak TaskMaster görevini seç:',
142
151
  'control.disabled': 'Telegram uzaktan kontrol kapalı. Pixcode → Ayarlar → Telegram içinden aç veya /control on gönder.',
143
152
  'control.selectProjectFirst': 'Önce /projects ile proje seç.',
144
153
  'control.selectWorkflowFirst': 'Önce bir iş akışı seç.',
@@ -147,6 +156,8 @@ const TR = {
147
156
  'control.agentFailed': 'Başarısız: {{error}}',
148
157
  'control.noAssistantText': 'Asistan metni dönmedi.',
149
158
  'control.workflowStarted': 'Orkestrasyon başlatıldı: {{runId}}\nİş akışı: {{workflowId}}',
159
+ 'control.taskStarted': 'TaskMaster görevi #{{taskId}}, {{provider}} ile başlatıldı.\nA2A görevi: {{a2aTaskId}}',
160
+ 'control.taskFinished': '{{taskId}} için TaskMaster yürütmesi bitti: {{status}}\n\n{{summary}}',
150
161
  'control.installMenu': 'CLI kur veya onar:',
151
162
  'control.authMenu': 'OAuth/giriş yönergeleri için sağlayıcı seç:',
152
163
  'control.manualInstall': '{{provider}} manuel kurulum:\n{{manual}}',
@@ -163,6 +174,7 @@ const TR = {
163
174
  'control.workflowSelected': 'İş akışı seçildi: {{workflow}}',
164
175
  'control.sendAgentPrompt': 'Ajan promptunu gönder.',
165
176
  'control.sendWorkflowPrompt': 'Orkestrasyon promptunu gönder.',
177
+ 'control.sendTaskId': 'Çalıştırılacak TaskMaster görev id değerini gönder.',
166
178
  'control.remoteEnabled': 'Uzaktan kontrol açıldı.',
167
179
  'control.remoteDisabled': 'Uzaktan kontrol kapatıldı.',
168
180
  'control.progressUsage': '/progress final, /progress steps veya /progress all kullan.',