@agimon-ai/po-task 0.0.0-alpha.4 → 0.0.0-alpha.41

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 (70) hide show
  1. package/LICENSE +149 -21
  2. package/README.md +12 -2
  3. package/dist/apiContracts.cjs +1 -0
  4. package/dist/apiContracts.cjs.map +1 -1
  5. package/dist/apiContracts.mjs +1 -0
  6. package/dist/apiContracts.mjs.map +1 -1
  7. package/dist/{delegation-Dsqf7fUM.mjs → delegation-CLcleXHi.mjs} +3 -2
  8. package/dist/{delegation-Dsqf7fUM.mjs.map → delegation-CLcleXHi.mjs.map} +1 -1
  9. package/dist/{delegation-frvEXhIz.cjs → delegation-DRp6iZid.cjs} +3 -2
  10. package/dist/{delegation-frvEXhIz.cjs.map → delegation-DRp6iZid.cjs.map} +1 -1
  11. package/dist/delegationManager.cjs +1 -1
  12. package/dist/delegationManager.d.mts +1 -1
  13. package/dist/delegationManager.mjs +1 -1
  14. package/dist/extensions/mcp.cjs +29 -27
  15. package/dist/extensions/mcp.cjs.map +1 -1
  16. package/dist/extensions/mcp.mjs +29 -27
  17. package/dist/extensions/mcp.mjs.map +1 -1
  18. package/dist/extensions/native.mjs +309 -207
  19. package/dist/extensions/native.mjs.map +1 -1
  20. package/dist/extensions/server.cjs +351 -122
  21. package/dist/extensions/server.cjs.map +1 -1
  22. package/dist/extensions/server.d.mts +2 -2
  23. package/dist/extensions/server.d.mts.map +1 -1
  24. package/dist/extensions/server.mjs +350 -121
  25. package/dist/extensions/server.mjs.map +1 -1
  26. package/dist/extensions/web.mjs +254 -206
  27. package/dist/extensions/web.mjs.map +1 -1
  28. package/dist/{index-DlmXKyhQ.d.mts → index-CdJx5tdI.d.mts} +2 -2
  29. package/dist/{index-DlmXKyhQ.d.mts.map → index-CdJx5tdI.d.mts.map} +1 -1
  30. package/dist/{index-B1JPJdpZ.d.mts → index-DrE00rrP.d.mts} +3 -3
  31. package/dist/{index-B1JPJdpZ.d.mts.map → index-DrE00rrP.d.mts.map} +1 -1
  32. package/dist/{index-B9QNwUBr.d.mts → index-Dyan0ai0.d.mts} +3 -3
  33. package/dist/{index-B9QNwUBr.d.mts.map → index-Dyan0ai0.d.mts.map} +1 -1
  34. package/dist/{index-qQGWsPum.d.mts → index-S77ZvGc-.d.mts} +2 -2
  35. package/dist/{index-qQGWsPum.d.mts.map → index-S77ZvGc-.d.mts.map} +1 -1
  36. package/dist/{index-CUWCvh-E.d.mts → index-nx0ueNkm.d.mts} +2 -2
  37. package/dist/{index-CUWCvh-E.d.mts.map → index-nx0ueNkm.d.mts.map} +1 -1
  38. package/dist/index.cjs +1 -1
  39. package/dist/index.d.mts +8 -8
  40. package/dist/index.mjs +1 -1
  41. package/dist/{logSinkTelemetry-BhbKdn-x.mjs → logSinkTelemetry-3GMazFYa.mjs} +2 -2
  42. package/dist/logSinkTelemetry-3GMazFYa.mjs.map +1 -0
  43. package/dist/{logSinkTelemetry-BGb8WQBz.cjs → logSinkTelemetry-DhzIQMsV.cjs} +3 -3
  44. package/dist/logSinkTelemetry-DhzIQMsV.cjs.map +1 -0
  45. package/dist/logSinkTelemetry.cjs +1 -1
  46. package/dist/logSinkTelemetry.d.mts +1 -1
  47. package/dist/logSinkTelemetry.mjs +1 -1
  48. package/dist/storeInvariants.d.mts +1 -1
  49. package/dist/storeReconcile.d.mts +1 -1
  50. package/dist/storeReducer.d.mts +1 -1
  51. package/dist/storeTaskGraph.d.mts +1 -1
  52. package/dist/storeTaskStore.d.mts +1 -1
  53. package/dist/storeTypes.d.mts +1 -1
  54. package/dist/{task-4HeGAS8o.d.mts → task--hlnpS7L.d.mts} +2 -2
  55. package/dist/{task-4HeGAS8o.d.mts.map → task--hlnpS7L.d.mts.map} +1 -1
  56. package/dist/task-CXF9VULl.cjs.map +1 -1
  57. package/dist/{task-DJpTteeJ.d.mts → task-DdTKZNtU.d.mts} +3 -1
  58. package/dist/task-DdTKZNtU.d.mts.map +1 -0
  59. package/dist/task-giCbpKzV.mjs.map +1 -1
  60. package/dist/{taskGraph-D0zFHF2p.d.mts → taskGraph-CB8ffMCz.d.mts} +2 -2
  61. package/dist/{taskGraph-D0zFHF2p.d.mts.map → taskGraph-CB8ffMCz.d.mts.map} +1 -1
  62. package/dist/toolResponseEnvelope.d.mts +1 -1
  63. package/dist/toolSchema.d.mts +1 -1
  64. package/llms.txt +11 -0
  65. package/package.json +17 -16
  66. package/src/prompts/codemode-how-to-task/SKILL.md +40 -0
  67. package/src/types/webTasks.ts +1 -0
  68. package/dist/logSinkTelemetry-BGb8WQBz.cjs.map +0 -1
  69. package/dist/logSinkTelemetry-BhbKdn-x.mjs.map +0 -1
  70. package/dist/task-DJpTteeJ.d.mts.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { defineActivityGroup, defineChannelFile, defineFill, defineNativePlugin, defineSessionStore, defineToolRenderer } from "@agimon-ai/po-core/native";
2
- import { Badge, Button, ChevronDownIcon, ChevronRightIcon, CodeBlock, Dot, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, EditIcon, Input, KebabIcon, Label, ListRow, MessageIcon, MessageItem, MessageItemBody, MessageItemHeader, MessageItemStatus, SegmentedControl, Sheet, SheetBody, SheetContent, SheetHeader, SheetTitle, StatusBadge, TaskIcon, Textarea, TrashIcon, toolTone } from "@agimon-ai/po-native-components";
2
+ import { AgentAvatar, Badge, Button, ChevronDownIcon, ChevronRightIcon, CodeBlock, Dot, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, EditIcon, Input, KebabIcon, Label, ListRow, MessageIcon, MessageItem, MessageItemBody, MessageItemHeader, MessageItemStatus, SegmentedControl, Sheet, SheetBody, SheetContent, SheetHeader, SheetTitle, TaskIcon, Textarea, TrashIcon, toolTone } from "@agimon-ai/po-native-components";
3
3
  import { createElement, useCallback, useState, useSyncExternalStore } from "react";
4
4
  import { View } from "react-native-unistyles/components/native/View";
5
5
  import { Text } from "react-native-unistyles/components/native/Text";
@@ -42,6 +42,7 @@ function parseTask(value) {
42
42
  if (isRecord$1(value.delegation)) {
43
43
  task.delegation = {};
44
44
  if (typeof value.delegation.agent === "string") task.delegation.agent = value.delegation.agent;
45
+ if (typeof value.delegation.identity === "string") task.delegation.identity = value.delegation.identity;
45
46
  if (typeof value.delegation.state === "string") task.delegation.state = value.delegation.state;
46
47
  }
47
48
  return task;
@@ -54,6 +55,11 @@ function parseTasksPayload(input) {
54
55
  rev: input.rev
55
56
  };
56
57
  }
58
+ /** Same first-name presentation as the Agents panel, without changing routing identity. */
59
+ function taskAgentName(delegation) {
60
+ const first = delegation?.identity?.split("-")[0];
61
+ return first ? first.charAt(0).toUpperCase() + first.slice(1) : delegation?.agent;
62
+ }
57
63
  function taskEditDraft(task) {
58
64
  return {
59
65
  subject: task.subject,
@@ -149,6 +155,15 @@ var tasks_native_default = defineActivityGroup({
149
155
  //#region src/extensions/workspaces/sessions/(frontend)/channel/task-graph.native.ts
150
156
  var task_graph_native_default = defineChannelFile(tasksChannel);
151
157
  //#endregion
158
+ //#region src/extensions/workspaces/sessions/(frontend)/fill/_lib/taskStatusTone.ts
159
+ const TASK_STATUS_TONE = {
160
+ pending: "muted",
161
+ in_progress: "green",
162
+ completed: "neutral",
163
+ failed: "red",
164
+ deleted: "muted"
165
+ };
166
+ //#endregion
152
167
  //#region src/extensions/workspaces/sessions/(frontend)/fill/_lib/TaskDetailSheet.native.tsx
153
168
  const STATUS_CHOICES = [
154
169
  "pending",
@@ -164,11 +179,18 @@ function Field({ label, children }) {
164
179
  children: [/* @__PURE__ */ jsx(Label, { children: label }), children]
165
180
  });
166
181
  }
167
- function ReadOnlyValue({ value, testID }) {
168
- return /* @__PURE__ */ jsx(Text, {
169
- testID,
170
- style: styles$2.value,
171
- children: value
182
+ /** One term and its value in the facts list. */
183
+ function Fact({ term, testID, children }) {
184
+ return /* @__PURE__ */ jsxs(View, {
185
+ style: styles$2.fact,
186
+ children: [/* @__PURE__ */ jsx(Text, {
187
+ style: styles$2.term,
188
+ children: term
189
+ }), /* @__PURE__ */ jsx(View, {
190
+ testID,
191
+ style: styles$2.factValue,
192
+ children
193
+ })]
172
194
  });
173
195
  }
174
196
  function SheetAction({ label, variant, testID, onPress }) {
@@ -180,49 +202,58 @@ function SheetAction({ label, variant, testID, onPress }) {
180
202
  });
181
203
  }
182
204
  function TaskFacts({ task }) {
205
+ const agent = taskAgentName(task.delegation);
183
206
  return /* @__PURE__ */ jsxs(View, {
184
207
  style: styles$2.facts,
185
208
  children: [
186
- /* @__PURE__ */ jsx(Field, {
187
- label: "Status",
188
- children: /* @__PURE__ */ jsx(ReadOnlyValue, {
189
- testID: "task-detail-status",
190
- value: task.status.replace("_", " ")
191
- })
192
- }),
193
- task.activeForm ? /* @__PURE__ */ jsx(Field, {
194
- label: "Active form",
195
- children: /* @__PURE__ */ jsx(ReadOnlyValue, {
196
- testID: "task-detail-active-form",
197
- value: task.activeForm
198
- })
209
+ agent ? /* @__PURE__ */ jsxs(Fact, {
210
+ term: "Agent",
211
+ testID: "task-detail-agent",
212
+ children: [
213
+ /* @__PURE__ */ jsx(AgentAvatar, {
214
+ name: agent,
215
+ size: "sm"
216
+ }),
217
+ /* @__PURE__ */ jsx(Text, {
218
+ style: styles$2.value,
219
+ children: agent
220
+ }),
221
+ task.delegation?.state ? /* @__PURE__ */ jsx(Text, {
222
+ style: styles$2.hint,
223
+ children: task.delegation.state
224
+ }) : null
225
+ ]
199
226
  }) : null,
200
- task.owner ? /* @__PURE__ */ jsx(Field, {
201
- label: "Owner",
202
- children: /* @__PURE__ */ jsx(ReadOnlyValue, {
203
- testID: "task-detail-owner",
204
- value: task.owner
227
+ task.activeForm ? /* @__PURE__ */ jsx(Fact, {
228
+ term: "Doing now",
229
+ testID: "task-detail-active-form",
230
+ children: /* @__PURE__ */ jsx(Text, {
231
+ style: styles$2.value,
232
+ children: task.activeForm
205
233
  })
206
234
  }) : null,
207
- task.delegation?.agent ? /* @__PURE__ */ jsx(Field, {
208
- label: "Delegated to",
209
- children: /* @__PURE__ */ jsx(ReadOnlyValue, {
210
- testID: "task-detail-agent",
211
- value: task.delegation.state ? `${task.delegation.agent} · ${task.delegation.state}` : task.delegation.agent
235
+ task.blockedBy.length > 0 ? /* @__PURE__ */ jsx(Fact, {
236
+ term: "Waits for",
237
+ testID: "task-detail-blocked-by",
238
+ children: /* @__PURE__ */ jsx(Text, {
239
+ style: styles$2.value,
240
+ children: task.blockedBy.map((id) => `#${id}`).join(", ")
212
241
  })
213
242
  }) : null,
214
- task.blockedBy.length > 0 ? /* @__PURE__ */ jsx(Field, {
215
- label: "Blocked by",
216
- children: /* @__PURE__ */ jsx(ReadOnlyValue, {
217
- testID: "task-detail-blocked-by",
218
- value: task.blockedBy.map((id) => `#${id}`).join(", ")
243
+ task.owner ? /* @__PURE__ */ jsx(Fact, {
244
+ term: "Owner",
245
+ testID: "task-detail-owner",
246
+ children: /* @__PURE__ */ jsx(Text, {
247
+ style: styles$2.value,
248
+ children: task.owner
219
249
  })
220
250
  }) : null,
221
- task.updatedAt ? /* @__PURE__ */ jsx(Field, {
222
- label: "Updated",
223
- children: /* @__PURE__ */ jsx(ReadOnlyValue, {
224
- testID: "task-detail-updated",
225
- value: task.updatedAt
251
+ task.updatedAt ? /* @__PURE__ */ jsx(Fact, {
252
+ term: "Updated",
253
+ testID: "task-detail-updated",
254
+ children: /* @__PURE__ */ jsx(Text, {
255
+ style: styles$2.value,
256
+ children: task.updatedAt
226
257
  })
227
258
  }) : null
228
259
  ]
@@ -238,6 +269,7 @@ function TaskDetailSheet({ task, sessionId, mode: initialMode, send, onClose })
238
269
  const [draft, setDraft] = useState(() => taskEditDraft(task));
239
270
  const [message, setMessage] = useState("");
240
271
  const agent = task.delegation?.agent;
272
+ const agentName = taskAgentName(task.delegation);
241
273
  const submitEdit = () => {
242
274
  if (requestTaskEdit(send, sessionId, task, draft)) onClose();
243
275
  };
@@ -261,24 +293,35 @@ function TaskDetailSheet({ task, sessionId, mode: initialMode, send, onClose })
261
293
  }), /* @__PURE__ */ jsxs(SheetBody, {
262
294
  testID: "task-detail-dialog",
263
295
  children: [
296
+ /* @__PURE__ */ jsxs(View, {
297
+ style: styles$2.status,
298
+ children: [/* @__PURE__ */ jsxs(Text, {
299
+ style: styles$2.id,
300
+ children: ["#", task.id]
301
+ }), /* @__PURE__ */ jsxs(Badge, {
302
+ testID: "task-detail-status",
303
+ children: [/* @__PURE__ */ jsx(Dot, {
304
+ tone: TASK_STATUS_TONE[task.status],
305
+ pulse: task.status === "in_progress"
306
+ }), task.status.replace("_", " ")]
307
+ })]
308
+ }),
264
309
  mode === "view" ? /* @__PURE__ */ jsxs(Fragment, { children: [
265
- /* @__PURE__ */ jsx(Field, {
266
- label: "Description",
267
- children: /* @__PURE__ */ jsx(ReadOnlyValue, {
268
- testID: "task-detail-description",
269
- value: task.description ?? "no description on this task"
270
- })
310
+ /* @__PURE__ */ jsx(Text, {
311
+ testID: "task-detail-description",
312
+ style: task.description ? styles$2.body : styles$2.hint,
313
+ children: task.description ?? "No description on this task."
271
314
  }),
272
315
  /* @__PURE__ */ jsx(TaskFacts, { task }),
273
316
  /* @__PURE__ */ jsxs(View, {
274
317
  style: styles$2.footer,
275
318
  children: [agent ? /* @__PURE__ */ jsx(SheetAction, {
276
- label: "message agent",
319
+ label: "Message agent",
277
320
  variant: "ghost",
278
321
  testID: "task-detail-open-message",
279
322
  onPress: () => setMode("message")
280
323
  }) : null, /* @__PURE__ */ jsx(SheetAction, {
281
- label: "edit",
324
+ label: "Edit",
282
325
  variant: "primary",
283
326
  testID: "task-detail-open-edit",
284
327
  onPress: () => setMode("edit")
@@ -306,7 +349,7 @@ function TaskDetailSheet({ task, sessionId, mode: initialMode, send, onClose })
306
349
  accessibilityLabel: "Description",
307
350
  numberOfLines: DESCRIPTION_LINES,
308
351
  value: draft.description,
309
- placeholder: "what this task covers",
352
+ placeholder: "What this task covers",
310
353
  onChangeText: (description) => setDraft({
311
354
  ...draft,
312
355
  description
@@ -332,17 +375,17 @@ function TaskDetailSheet({ task, sessionId, mode: initialMode, send, onClose })
332
375
  }),
333
376
  /* @__PURE__ */ jsx(Text, {
334
377
  style: styles$2.hint,
335
- children: "saved as one prompt naming only the fields you changed"
378
+ children: "Saved as one prompt naming only the fields you changed"
336
379
  }),
337
380
  /* @__PURE__ */ jsxs(View, {
338
381
  style: styles$2.footer,
339
382
  children: [/* @__PURE__ */ jsx(SheetAction, {
340
- label: "cancel",
383
+ label: "Cancel",
341
384
  variant: "ghost",
342
385
  testID: "task-detail-cancel",
343
386
  onPress: onClose
344
387
  }), /* @__PURE__ */ jsx(SheetAction, {
345
- label: "save",
388
+ label: "Save",
346
389
  variant: "primary",
347
390
  testID: "task-detail-save",
348
391
  onPress: submitEdit
@@ -351,30 +394,30 @@ function TaskDetailSheet({ task, sessionId, mode: initialMode, send, onClose })
351
394
  ] }) : null,
352
395
  mode === "message" && agent ? /* @__PURE__ */ jsxs(Fragment, { children: [
353
396
  /* @__PURE__ */ jsx(Field, {
354
- label: `Message to ${agent}`,
397
+ label: `Message to ${agentName}`,
355
398
  children: /* @__PURE__ */ jsx(Textarea, {
356
399
  testID: "task-detail-message-input",
357
400
  accessibilityLabel: "Message to agent",
358
401
  autoFocus: true,
359
402
  numberOfLines: MESSAGE_LINES,
360
403
  value: message,
361
- placeholder: "guidance for the run working on this task",
404
+ placeholder: "Guidance for the run working on this task",
362
405
  onChangeText: setMessage
363
406
  })
364
407
  }),
365
408
  /* @__PURE__ */ jsx(Text, {
366
409
  style: styles$2.hint,
367
- children: "steers the run, it does not edit the task"
410
+ children: "Steers the run, it does not edit the task"
368
411
  }),
369
412
  /* @__PURE__ */ jsxs(View, {
370
413
  style: styles$2.footer,
371
414
  children: [/* @__PURE__ */ jsx(SheetAction, {
372
- label: "cancel",
415
+ label: "Cancel",
373
416
  variant: "ghost",
374
417
  testID: "task-detail-cancel",
375
418
  onPress: onClose
376
419
  }), /* @__PURE__ */ jsx(SheetAction, {
377
- label: "send",
420
+ label: "Send",
378
421
  variant: "primary",
379
422
  testID: "task-detail-send",
380
423
  onPress: submitMessage
@@ -390,16 +433,53 @@ const styles$2 = StyleSheet.create((theme) => ({
390
433
  gap: theme.spacing(1.5),
391
434
  uni__dependencies: [0]
392
435
  },
436
+ status: {
437
+ flexDirection: "row",
438
+ alignItems: "center",
439
+ gap: theme.spacing(2),
440
+ uni__dependencies: [0]
441
+ },
442
+ id: {
443
+ fontSize: theme.fontSize.sm,
444
+ lineHeight: theme.lineHeight.sm,
445
+ color: theme.colors.faint,
446
+ uni__dependencies: [0]
447
+ },
448
+ body: {
449
+ fontSize: theme.fontSize.base,
450
+ lineHeight: theme.lineHeight.lg,
451
+ color: theme.colors.text,
452
+ uni__dependencies: [0]
453
+ },
393
454
  facts: {
455
+ gap: theme.spacing(2.5),
456
+ uni__dependencies: [0]
457
+ },
458
+ fact: {
459
+ flexDirection: "row",
460
+ alignItems: "center",
461
+ gap: theme.spacing(4),
462
+ uni__dependencies: [0]
463
+ },
464
+ term: {
465
+ width: theme.spacing(20),
466
+ fontSize: theme.fontSize.base,
467
+ lineHeight: theme.lineHeight.base,
468
+ color: theme.colors.dim,
469
+ uni__dependencies: [0]
470
+ },
471
+ factValue: {
472
+ flex: 1,
394
473
  flexDirection: "row",
474
+ alignItems: "center",
395
475
  flexWrap: "wrap",
396
- gap: theme.spacing(5),
476
+ gap: theme.spacing(1.5),
397
477
  uni__dependencies: [0]
398
478
  },
399
479
  value: {
400
480
  fontSize: theme.fontSize.base,
401
- lineHeight: theme.lineHeight.lg,
402
- color: theme.colors.dim,
481
+ lineHeight: theme.lineHeight.base,
482
+ color: theme.colors.text,
403
483
  uni__dependencies: [0]
404
484
  },
405
485
  hint: {
@@ -416,19 +496,9 @@ const styles$2 = StyleSheet.create((theme) => ({
416
496
  }
417
497
  }));
418
498
  //#endregion
419
- //#region src/extensions/workspaces/sessions/(frontend)/fill/_lib/taskStatusTone.ts
420
- const TASK_STATUS_TONE = {
421
- pending: "muted",
422
- in_progress: "yellow",
423
- completed: "green",
424
- failed: "red",
425
- deleted: "muted"
426
- };
427
- //#endregion
428
499
  //#region src/extensions/workspaces/sessions/(frontend)/fill/_lib/TasksActivitySection.native.tsx
429
500
  function titleInk(status) {
430
- if (status === "failed") return "red";
431
- return status === "completed" ? "dim" : "hi";
501
+ return status === "completed" || status === "failed" ? "dim" : "hi";
432
502
  }
433
503
  /** The session's tasks, read from the native store without @tanstack/react-store, which the app does not provide. */
434
504
  function useSessionTasks(sessionId) {
@@ -439,8 +509,9 @@ function useSessionTasks(sessionId) {
439
509
  return useSyncExternalStore(subscribe, () => tasks.select(tasks.store.state, sessionId).tasks);
440
510
  }
441
511
  function TaskRow({ task, sessionId, sendSessionFrame, openSheet }) {
442
- const detail = task.status === "in_progress" ? task.activeForm : task.description;
443
- const agent = task.delegation?.agent;
512
+ const doing = task.status === "in_progress" ? task.activeForm : void 0;
513
+ const agent = taskAgentName(task.delegation);
514
+ const detail = [doing, task.blockedBy.length > 0 ? `Waits for ${task.blockedBy.map((id) => `#${id}`).join(", ")}` : ""].filter(Boolean).join(" · ");
444
515
  return /* @__PURE__ */ jsx(View, {
445
516
  testID: `activity-task-${task.id}`,
446
517
  children: /* @__PURE__ */ jsx(ListRow, {
@@ -453,60 +524,67 @@ function TaskRow({ task, sessionId, sendSessionFrame, openSheet }) {
453
524
  testID: `activity-task-title-${task.id}`,
454
525
  accessibilityLabel: task.subject,
455
526
  onPress: () => openSheet("view"),
527
+ style: styles$1.titleButton,
456
528
  children: /* @__PURE__ */ jsxs(Text, {
457
- numberOfLines: 1,
529
+ numberOfLines: 2,
458
530
  style: styles$1.title(titleInk(task.status)),
459
531
  children: [
460
- "#",
461
- task.id,
532
+ /* @__PURE__ */ jsxs(Text, {
533
+ style: styles$1.id,
534
+ children: ["#", task.id]
535
+ }),
462
536
  " ",
463
537
  task.subject
464
538
  ]
465
539
  })
466
540
  }),
467
- description: detail || agent || task.blockedBy.length > 0 ? /* @__PURE__ */ jsxs(Text, {
468
- numberOfLines: 1,
469
- style: styles$1.meta,
541
+ description: agent || detail ? /* @__PURE__ */ jsxs(View, {
542
+ style: styles$1.line,
470
543
  children: [
471
- agent ? `[${agent}] ` : "",
472
- detail ?? "",
473
- task.blockedBy.length > 0 ? ` · blocked by ${task.blockedBy.map((id) => `#${id}`).join(", ")}` : ""
544
+ agent ? /* @__PURE__ */ jsx(AgentAvatar, {
545
+ name: agent,
546
+ size: "sm"
547
+ }) : null,
548
+ agent ? /* @__PURE__ */ jsx(Text, {
549
+ style: styles$1.agent,
550
+ children: agent
551
+ }) : null,
552
+ detail ? /* @__PURE__ */ jsx(Text, {
553
+ numberOfLines: 1,
554
+ style: styles$1.meta,
555
+ children: detail
556
+ }) : null
474
557
  ]
475
558
  }) : void 0,
476
- trailing: /* @__PURE__ */ jsxs(View, {
477
- style: styles$1.line,
478
- children: [/* @__PURE__ */ jsx(Text, {
479
- style: styles$1.meta,
480
- children: task.status.replace("_", " ")
481
- }), task.status !== "completed" && task.status !== "deleted" ? /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
482
- variant: "ghost",
483
- size: "icon",
484
- testID: `activity-task-menu-${task.id}`,
485
- accessibilityLabel: `task #${task.id} actions`,
486
- children: /* @__PURE__ */ jsx(KebabIcon, {})
487
- }), /* @__PURE__ */ jsxs(DropdownMenuContent, { children: [
488
- /* @__PURE__ */ jsxs(DropdownMenuItem, {
489
- onSelect: () => openSheet("edit"),
490
- children: [/* @__PURE__ */ jsx(EditIcon, {}), "Edit"]
491
- }),
492
- agent ? /* @__PURE__ */ jsxs(DropdownMenuItem, {
493
- onSelect: () => openSheet("message"),
494
- children: [/* @__PURE__ */ jsx(MessageIcon, {}), "Message agent"]
495
- }) : null,
496
- /* @__PURE__ */ jsxs(DropdownMenuItem, {
497
- variant: "destructive",
498
- onSelect: () => requestTaskRemoval(sendSessionFrame, sessionId, task.id),
499
- children: [/* @__PURE__ */ jsx(TrashIcon, { color: "red" }), "Remove"]
500
- })
501
- ] })] }) : null]
502
- })
559
+ trailing: task.status !== "completed" && task.status !== "deleted" ? /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
560
+ variant: "ghost",
561
+ size: "icon",
562
+ testID: `activity-task-menu-${task.id}`,
563
+ accessibilityLabel: `task #${task.id} actions`,
564
+ children: /* @__PURE__ */ jsx(KebabIcon, {})
565
+ }), /* @__PURE__ */ jsxs(DropdownMenuContent, { children: [
566
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
567
+ onSelect: () => openSheet("edit"),
568
+ children: [/* @__PURE__ */ jsx(EditIcon, {}), "Edit"]
569
+ }),
570
+ agent ? /* @__PURE__ */ jsxs(DropdownMenuItem, {
571
+ onSelect: () => openSheet("message"),
572
+ children: [/* @__PURE__ */ jsx(MessageIcon, {}), "Message agent"]
573
+ }) : null,
574
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
575
+ variant: "destructive",
576
+ onSelect: () => requestTaskRemoval(sendSessionFrame, sessionId, task.id),
577
+ children: [/* @__PURE__ */ jsx(TrashIcon, { color: "red" }), "Remove"]
578
+ })
579
+ ] })] }) : void 0
503
580
  })
504
581
  });
505
582
  }
506
583
  /**
507
584
  * The session task graph in the app's Activity list, mirroring the web
508
- * section: active rows first, finished ones behind a collapsed history, and a
509
- * sheet for reading or changing one task. Empty graphs render nothing.
585
+ * section: a done count, active rows, finished and failed ones folded away by
586
+ * default, and a sheet for reading or changing one task. Empty graphs render
587
+ * nothing.
510
588
  */
511
589
  function TasksActivitySection({ sessionId, sendSessionFrame }) {
512
590
  const sessionTasks = useSessionTasks(sessionId);
@@ -515,6 +593,9 @@ function TasksActivitySection({ sessionId, sendSessionFrame }) {
515
593
  if (sessionId === null || sessionTasks.length === 0) return null;
516
594
  const active = sessionTasks.filter((task) => task.status === "pending" || task.status === "in_progress");
517
595
  const history = sessionTasks.filter((task) => task.status === "completed" || task.status === "failed");
596
+ const failed = history.filter((task) => task.status === "failed").length;
597
+ const done = history.length - failed;
598
+ const total = active.length + history.length;
518
599
  const sheetTask = sheet ? sessionTasks.find((task) => task.id === sheet.taskId) : void 0;
519
600
  const row = (task) => /* @__PURE__ */ jsx(TaskRow, {
520
601
  task,
@@ -528,6 +609,29 @@ function TasksActivitySection({ sessionId, sendSessionFrame }) {
528
609
  return /* @__PURE__ */ jsxs(View, {
529
610
  style: styles$1.section,
530
611
  children: [
612
+ total > 0 ? /* @__PURE__ */ jsxs(View, {
613
+ testID: "activity-task-progress",
614
+ accessible: true,
615
+ accessibilityRole: "progressbar",
616
+ accessibilityValue: {
617
+ min: 0,
618
+ max: total,
619
+ now: done
620
+ },
621
+ style: styles$1.progress,
622
+ children: [/* @__PURE__ */ jsxs(Text, {
623
+ style: styles$1.meta,
624
+ children: [
625
+ done,
626
+ " of ",
627
+ total,
628
+ " done"
629
+ ]
630
+ }), /* @__PURE__ */ jsx(View, {
631
+ style: styles$1.track,
632
+ children: /* @__PURE__ */ jsx(View, { style: [styles$1.fill, { width: `${done / total * 100}%` }] })
633
+ })]
634
+ }) : null,
531
635
  active.length > 0 ? /* @__PURE__ */ jsx(View, {
532
636
  style: styles$1.group,
533
637
  children: active.map(row)
@@ -536,6 +640,7 @@ function TasksActivitySection({ sessionId, sendSessionFrame }) {
536
640
  style: styles$1.group,
537
641
  children: [/* @__PURE__ */ jsxs(Button, {
538
642
  variant: "ghost",
643
+ testID: "activity-task-history-toggle",
539
644
  accessibilityState: { expanded: historyOpen },
540
645
  onPress: () => setHistoryOpen((open) => !open),
541
646
  style: styles$1.historyToggle,
@@ -543,12 +648,16 @@ function TasksActivitySection({ sessionId, sendSessionFrame }) {
543
648
  /* @__PURE__ */ jsx(Fragment, { children: historyOpen ? /* @__PURE__ */ jsx(ChevronDownIcon, {}) : /* @__PURE__ */ jsx(ChevronRightIcon, {}) }),
544
649
  /* @__PURE__ */ jsx(Text, {
545
650
  style: styles$1.historyLabel,
546
- children: "Session"
651
+ children: "Finished"
547
652
  }),
548
- /* @__PURE__ */ jsx(Badge, { children: history.length })
653
+ /* @__PURE__ */ jsx(Badge, { children: history.length }),
654
+ failed > 0 ? /* @__PURE__ */ jsxs(Text, {
655
+ style: styles$1.failed,
656
+ children: [failed, " failed"]
657
+ }) : null
549
658
  ]
550
659
  }), historyOpen ? /* @__PURE__ */ jsx(View, {
551
- style: [styles$1.group, styles$1.history],
660
+ style: styles$1.group,
552
661
  children: history.map(row)
553
662
  }) : null]
554
663
  }) : null,
@@ -571,15 +680,21 @@ const styles$1 = StyleSheet.create((theme) => ({
571
680
  gap: theme.spacing(.5),
572
681
  uni__dependencies: [0]
573
682
  },
574
- history: {
575
- paddingLeft: theme.spacing(2),
683
+ progress: {
684
+ gap: theme.spacing(1.5),
685
+ paddingHorizontal: theme.spacing(1),
686
+ uni__dependencies: [0]
687
+ },
688
+ track: {
689
+ height: theme.spacing(1),
690
+ borderRadius: theme.borderRadius.full,
691
+ overflow: "hidden",
692
+ backgroundColor: theme.colors.deep,
576
693
  uni__dependencies: [0]
577
694
  },
578
- row: {
579
- gap: theme.spacing(1),
580
- paddingHorizontal: theme.spacing(1),
581
- paddingVertical: theme.spacing(1),
582
- borderRadius: theme.borderRadius.md,
695
+ fill: {
696
+ height: "100%",
697
+ backgroundColor: theme.colors.green,
583
698
  uni__dependencies: [0]
584
699
  },
585
700
  line: {
@@ -588,54 +703,60 @@ const styles$1 = StyleSheet.create((theme) => ({
588
703
  gap: theme.spacing(1.5),
589
704
  uni__dependencies: [0]
590
705
  },
706
+ titleButton: {
707
+ height: "auto",
708
+ justifyContent: "flex-start",
709
+ paddingHorizontal: 0,
710
+ paddingVertical: theme.spacing(.5),
711
+ uni__dependencies: [0]
712
+ },
591
713
  title: (ink) => ({
592
714
  fontSize: theme.fontSize.base,
593
715
  lineHeight: theme.lineHeight.base,
594
- fontWeight: "600",
716
+ fontWeight: "500",
595
717
  color: theme.colors[ink],
596
718
  uni__dependencies: [0]
597
719
  }),
598
720
  id: {
599
- color: theme.colors.dim,
721
+ fontSize: theme.fontSize.sm,
722
+ color: theme.colors.faint,
723
+ uni__dependencies: [0]
724
+ },
725
+ agent: {
726
+ fontSize: theme.fontSize.sm,
727
+ lineHeight: theme.lineHeight.sm,
728
+ color: theme.colors.text,
600
729
  uni__dependencies: [0]
601
730
  },
602
731
  meta: {
732
+ flexShrink: 1,
603
733
  fontSize: theme.fontSize.sm,
604
734
  lineHeight: theme.lineHeight.sm,
605
735
  color: theme.colors.dim,
606
736
  uni__dependencies: [0]
607
737
  },
608
- detail: {
609
- paddingLeft: theme.spacing(3),
738
+ failed: {
739
+ fontSize: theme.fontSize.sm,
740
+ lineHeight: theme.lineHeight.sm,
741
+ color: theme.colors.red,
610
742
  uni__dependencies: [0]
611
743
  },
612
744
  historyToggle: {
613
745
  flexDirection: "row",
614
746
  alignItems: "center",
747
+ justifyContent: "flex-start",
615
748
  gap: theme.spacing(1.5),
616
749
  minHeight: theme.spacing(11),
617
750
  paddingHorizontal: theme.spacing(1),
618
751
  borderRadius: theme.borderRadius.md,
619
752
  uni__dependencies: [0]
620
753
  },
621
- chevron: {
754
+ historyLabel: {
622
755
  fontSize: theme.fontSize.sm,
623
756
  lineHeight: theme.lineHeight.sm,
624
- color: theme.colors.faint,
625
- uni__dependencies: [0]
626
- },
627
- historyLabel: {
628
- fontSize: theme.fontSize.base,
629
- lineHeight: theme.lineHeight.base,
630
757
  fontWeight: "500",
631
758
  color: theme.colors.dim,
632
759
  uni__dependencies: [0]
633
- },
634
- count: {
635
- fontSize: theme.fontSize["2xs"],
636
- lineHeight: theme.lineHeight["2xs"],
637
- color: theme.colors.faint,
638
- uni__dependencies: [0]
639
760
  }
640
761
  }));
641
762
  //#endregion
@@ -643,6 +764,12 @@ const styles$1 = StyleSheet.create((theme) => ({
643
764
  var Tasks_activity_tasks_native_default = defineFill({ component: TasksActivitySection });
644
765
  //#endregion
645
766
  //#region src/extensions/workspaces/sessions/(frontend)/tool/_lib/taskToolFormat.ts
767
+ /**
768
+ * Pure view logic for the task tool card, the browser counterpart of
769
+ * the session frontend's shared format helpers (renderTaskCall, renderTaskResult). The plugin may reach
770
+ * only its own files and src/types, so the store shapes it reads are
771
+ * restated here as the wire JSON of a tool_execution frame.
772
+ */
646
773
  const STATUS_GLYPH = {
647
774
  pending: "○",
648
775
  in_progress: "◐",
@@ -714,6 +841,7 @@ function taskView(value) {
714
841
  if (isRecord(value.delegation)) {
715
842
  task.delegation = {};
716
843
  if (typeof value.delegation.agent === "string") task.delegation.agent = value.delegation.agent;
844
+ if (typeof value.delegation.identity === "string") task.delegation.identity = value.delegation.identity;
717
845
  if (typeof value.delegation.state === "string") task.delegation.state = value.delegation.state;
718
846
  }
719
847
  return task;
@@ -804,7 +932,8 @@ function taskRow(task) {
804
932
  closed: task.status === "completed" || task.status === "deleted",
805
933
  blockedBy: task.blockedBy ?? []
806
934
  };
807
- if (task.delegation?.agent) row.agent = inlineText(task.delegation.agent);
935
+ const agent = taskAgentName(task.delegation);
936
+ if (agent) row.agent = inlineText(agent);
808
937
  if (task.status === "in_progress" && task.activeForm) row.activeForm = inlineText(task.activeForm);
809
938
  return row;
810
939
  }
@@ -935,23 +1064,17 @@ function taskResultView(input) {
935
1064
  }
936
1065
  //#endregion
937
1066
  //#region src/extensions/workspaces/sessions/(frontend)/tool/_lib/TaskToolMessage.native.tsx
1067
+ /** One colour per row, on the dot only: jade while Po works on it, red only for a real failure. */
938
1068
  const STATUS_DOT = {
939
1069
  pending: "muted",
940
- in_progress: "yellow",
941
- completed: "green",
1070
+ in_progress: "green",
1071
+ completed: "neutral",
942
1072
  failed: "red",
943
1073
  deleted: "muted"
944
1074
  };
945
1075
  const CALL_INK = {
946
1076
  dim: "hi",
947
- accent: "blue"
948
- };
949
- const STATUS_TONE = {
950
- pending: "neutral",
951
- in_progress: "running",
952
- completed: "ok",
953
- failed: "error",
954
- deleted: "neutral"
1077
+ accent: "green"
955
1078
  };
956
1079
  const RESULT_TONE = {
957
1080
  running: "running",
@@ -959,60 +1082,42 @@ const RESULT_TONE = {
959
1082
  error: "error",
960
1083
  warning: "running"
961
1084
  };
962
- function subjectInk(row) {
963
- if (row.closed) return "dim";
964
- return row.status === "in_progress" ? "blue" : "hi";
965
- }
966
- /** One task row: status glyph, id, subject and chips on the left, the status label flushed right. */
1085
+ /** One task row: status dot, id and subject, with who is on it and what it waits for on a quiet line below. */
967
1086
  function TaskRowLine({ row }) {
1087
+ const waits = row.blockedBy.length > 0 ? `waits for ${row.blockedBy.map((id) => `#${id}`).join(", ")}` : "";
1088
+ const meta = [
1089
+ row.agent,
1090
+ row.activeForm,
1091
+ waits
1092
+ ].filter(Boolean).join(" · ");
968
1093
  return /* @__PURE__ */ jsxs(View, {
969
1094
  testID: "tool-result-task-row",
1095
+ accessible: true,
1096
+ accessibilityLabel: `task #${row.id}, ${row.subject}, ${STATUS_LABEL[row.status]}`,
970
1097
  style: styles.row,
971
- children: [
972
- /* @__PURE__ */ jsx(Dot, {
973
- tone: STATUS_DOT[row.status],
974
- pulse: row.status === "in_progress"
975
- }),
976
- /* @__PURE__ */ jsxs(Text, {
977
- style: styles.meta,
978
- children: ["#", row.id]
979
- }),
980
- /* @__PURE__ */ jsxs(Text, {
1098
+ children: [/* @__PURE__ */ jsx(Dot, {
1099
+ tone: STATUS_DOT[row.status],
1100
+ pulse: row.status === "in_progress",
1101
+ style: styles.dot
1102
+ }), /* @__PURE__ */ jsxs(View, {
1103
+ style: styles.rowText,
1104
+ children: [/* @__PURE__ */ jsxs(Text, {
981
1105
  numberOfLines: 1,
982
- style: [
983
- styles.rowSubject,
984
- styles.ink(subjectInk(row)),
985
- row.closed ? styles.struck : null
986
- ],
987
- children: [
988
- row.subject,
989
- row.agent ? /* @__PURE__ */ jsxs(Text, {
990
- style: styles.meta,
991
- children: [
992
- " [",
993
- row.agent,
994
- "]"
995
- ]
996
- }) : null,
997
- row.activeForm ? /* @__PURE__ */ jsxs(Text, {
998
- style: styles.meta,
999
- children: [
1000
- " (",
1001
- row.activeForm,
1002
- ")"
1003
- ]
1004
- }) : null,
1005
- row.blockedBy.length > 0 ? /* @__PURE__ */ jsxs(Text, {
1006
- style: styles.meta,
1007
- children: [" ⛓ ", row.blockedBy.map((id) => `#${id}`).join(",")]
1008
- }) : null
1009
- ]
1010
- }),
1011
- /* @__PURE__ */ jsx(StatusBadge, {
1012
- tone: STATUS_TONE[row.status],
1013
- children: STATUS_LABEL[row.status]
1014
- })
1015
- ]
1106
+ style: [styles.rowSubject, styles.ink(row.closed ? "dim" : "hi")],
1107
+ children: [/* @__PURE__ */ jsxs(Text, {
1108
+ style: styles.meta,
1109
+ children: [
1110
+ "#",
1111
+ row.id,
1112
+ " "
1113
+ ]
1114
+ }), row.subject]
1115
+ }), meta ? /* @__PURE__ */ jsx(Text, {
1116
+ numberOfLines: 1,
1117
+ style: styles.meta,
1118
+ children: meta
1119
+ }) : null]
1120
+ })]
1016
1121
  });
1017
1122
  }
1018
1123
  /**
@@ -1119,30 +1224,27 @@ const styles = StyleSheet.create((theme) => ({
1119
1224
  },
1120
1225
  row: {
1121
1226
  flexDirection: "row",
1122
- alignItems: "baseline",
1227
+ alignItems: "flex-start",
1123
1228
  gap: theme.spacing(2),
1124
1229
  uni__dependencies: [0]
1125
1230
  },
1231
+ dot: {
1232
+ marginTop: theme.spacing(1.5),
1233
+ uni__dependencies: [0]
1234
+ },
1235
+ rowText: { flex: 1 },
1126
1236
  rowSubject: {
1127
- flex: 1,
1128
1237
  fontSize: theme.fontSize.base,
1129
1238
  lineHeight: theme.lineHeight.base,
1130
- fontWeight: "600",
1239
+ fontWeight: "500",
1131
1240
  uni__dependencies: [0]
1132
1241
  },
1133
- struck: { textDecorationLine: "line-through" },
1134
1242
  meta: {
1135
1243
  fontSize: theme.fontSize.sm,
1136
1244
  lineHeight: theme.lineHeight.sm,
1137
1245
  color: theme.colors.dim,
1138
1246
  uni__dependencies: [0]
1139
1247
  },
1140
- statusGlyph: {
1141
- fontSize: theme.fontSize.sm,
1142
- lineHeight: theme.lineHeight.sm,
1143
- fontWeight: "600",
1144
- uni__dependencies: [0]
1145
- },
1146
1248
  ink: (token) => ({
1147
1249
  color: theme.colors[token],
1148
1250
  uni__dependencies: [0]