@synergenius/flow-weaver-pack-weaver 0.9.200 → 0.9.201

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 (181) hide show
  1. package/dist/ai-chat-provider.js +5 -5
  2. package/dist/ai-chat-provider.js.map +1 -1
  3. package/dist/bot/acceptance-merge.d.ts +21 -0
  4. package/dist/bot/acceptance-merge.d.ts.map +1 -0
  5. package/dist/bot/acceptance-merge.js +46 -0
  6. package/dist/bot/acceptance-merge.js.map +1 -0
  7. package/dist/bot/ai-client.d.ts +14 -2
  8. package/dist/bot/ai-client.d.ts.map +1 -1
  9. package/dist/bot/ai-client.js +71 -24
  10. package/dist/bot/ai-client.js.map +1 -1
  11. package/dist/bot/assistant-tools.js +3 -3
  12. package/dist/bot/assistant-tools.js.map +1 -1
  13. package/dist/bot/audit-logger.d.ts.map +1 -1
  14. package/dist/bot/audit-logger.js +34 -14
  15. package/dist/bot/audit-logger.js.map +1 -1
  16. package/dist/bot/audit-trail.d.ts +67 -0
  17. package/dist/bot/audit-trail.d.ts.map +1 -0
  18. package/dist/bot/audit-trail.js +153 -0
  19. package/dist/bot/audit-trail.js.map +1 -0
  20. package/dist/bot/behavior-defaults.d.ts +1 -1
  21. package/dist/bot/behavior-defaults.d.ts.map +1 -1
  22. package/dist/bot/behavior-defaults.js +7 -3
  23. package/dist/bot/behavior-defaults.js.map +1 -1
  24. package/dist/bot/capability-registry.d.ts +9 -0
  25. package/dist/bot/capability-registry.d.ts.map +1 -1
  26. package/dist/bot/capability-registry.js +81 -27
  27. package/dist/bot/capability-registry.js.map +1 -1
  28. package/dist/bot/capability-types.d.ts +10 -0
  29. package/dist/bot/capability-types.d.ts.map +1 -1
  30. package/dist/bot/cli-provider.d.ts.map +1 -1
  31. package/dist/bot/cli-provider.js +8 -7
  32. package/dist/bot/cli-provider.js.map +1 -1
  33. package/dist/bot/preflight.d.ts +48 -0
  34. package/dist/bot/preflight.d.ts.map +1 -0
  35. package/dist/bot/preflight.js +247 -0
  36. package/dist/bot/preflight.js.map +1 -0
  37. package/dist/bot/provider-shim.d.ts +74 -0
  38. package/dist/bot/provider-shim.d.ts.map +1 -0
  39. package/dist/bot/provider-shim.js +176 -0
  40. package/dist/bot/provider-shim.js.map +1 -0
  41. package/dist/bot/runner.d.ts +2 -0
  42. package/dist/bot/runner.d.ts.map +1 -1
  43. package/dist/bot/runner.js +60 -17
  44. package/dist/bot/runner.js.map +1 -1
  45. package/dist/bot/step-executor.d.ts.map +1 -1
  46. package/dist/bot/step-executor.js +72 -115
  47. package/dist/bot/step-executor.js.map +1 -1
  48. package/dist/bot/swarm-controller.d.ts +2 -0
  49. package/dist/bot/swarm-controller.d.ts.map +1 -1
  50. package/dist/bot/swarm-controller.js +92 -20
  51. package/dist/bot/swarm-controller.js.map +1 -1
  52. package/dist/bot/task-create-handler.d.ts +37 -0
  53. package/dist/bot/task-create-handler.d.ts.map +1 -0
  54. package/dist/bot/task-create-handler.js +124 -0
  55. package/dist/bot/task-create-handler.js.map +1 -0
  56. package/dist/bot/task-store.d.ts +1 -0
  57. package/dist/bot/task-store.d.ts.map +1 -1
  58. package/dist/bot/task-store.js +61 -0
  59. package/dist/bot/task-store.js.map +1 -1
  60. package/dist/bot/types.d.ts +1 -1
  61. package/dist/bot/types.d.ts.map +1 -1
  62. package/dist/bot/weaver-tools.d.ts.map +1 -1
  63. package/dist/bot/weaver-tools.js +7 -39
  64. package/dist/bot/weaver-tools.js.map +1 -1
  65. package/dist/node-types/agent-execute.d.ts +25 -8
  66. package/dist/node-types/agent-execute.d.ts.map +1 -1
  67. package/dist/node-types/agent-execute.js +89 -23
  68. package/dist/node-types/agent-execute.js.map +1 -1
  69. package/dist/node-types/bot-report.d.ts.map +1 -1
  70. package/dist/node-types/bot-report.js +24 -3
  71. package/dist/node-types/bot-report.js.map +1 -1
  72. package/dist/node-types/plan-task.d.ts +8 -17
  73. package/dist/node-types/plan-task.d.ts.map +1 -1
  74. package/dist/node-types/plan-task.js +217 -256
  75. package/dist/node-types/plan-task.js.map +1 -1
  76. package/dist/node-types/review-result.js +8 -6
  77. package/dist/node-types/review-result.js.map +1 -1
  78. package/dist/palindrome.d.ts +9 -0
  79. package/dist/palindrome.d.ts.map +1 -0
  80. package/dist/palindrome.js +14 -0
  81. package/dist/palindrome.js.map +1 -0
  82. package/dist/ui/approval-card.js +91 -82
  83. package/dist/ui/bot-activity.js +73 -56
  84. package/dist/ui/bot-config.js +48 -31
  85. package/dist/ui/bot-dashboard.js +52 -36
  86. package/dist/ui/bot-panel.js +230 -228
  87. package/dist/ui/bot-slot-card.js +100 -90
  88. package/dist/ui/bot-status.js +37 -15
  89. package/dist/ui/budget-bar.js +57 -31
  90. package/dist/ui/capability-editor.js +447 -378
  91. package/dist/ui/chat-task-result.js +78 -71
  92. package/dist/ui/decision-log.js +68 -81
  93. package/dist/ui/genesis-block.js +86 -95
  94. package/dist/ui/instance-stream-view.js +722 -0
  95. package/dist/ui/profile-card.js +96 -221
  96. package/dist/ui/profile-editor.js +532 -575
  97. package/dist/ui/settings-section.js +41 -45
  98. package/dist/ui/swarm-controls.js +212 -135
  99. package/dist/ui/swarm-dashboard.js +3992 -2715
  100. package/dist/ui/task-detail-view.js +415 -521
  101. package/dist/ui/task-editor.js +339 -390
  102. package/dist/ui/task-pool-list.js +60 -55
  103. package/dist/workflows/src/palindrome.d.ts +11 -0
  104. package/dist/workflows/src/palindrome.d.ts.map +1 -0
  105. package/dist/workflows/src/palindrome.js +16 -0
  106. package/dist/workflows/src/palindrome.js.map +1 -0
  107. package/dist/workflows/tests/palindrome.test.d.ts +2 -0
  108. package/dist/workflows/tests/palindrome.test.d.ts.map +1 -0
  109. package/dist/workflows/tests/palindrome.test.js +41 -0
  110. package/dist/workflows/tests/palindrome.test.js.map +1 -0
  111. package/dist/workflows/weaver-bot-batch.js +1 -1
  112. package/dist/workflows/weaver-bot-batch.js.map +1 -1
  113. package/dist/workflows/weaver-bot.js +1 -1
  114. package/dist/workflows/weaver-bot.js.map +1 -1
  115. package/flowweaver.manifest.json +1 -1
  116. package/package.json +8 -2
  117. package/src/ai-chat-provider.ts +5 -5
  118. package/src/bot/acceptance-merge.ts +62 -0
  119. package/src/bot/ai-client.ts +77 -21
  120. package/src/bot/assistant-tools.ts +3 -3
  121. package/src/bot/audit-logger.ts +42 -14
  122. package/src/bot/audit-trail.ts +211 -0
  123. package/src/bot/behavior-defaults.ts +7 -2
  124. package/src/bot/capability-registry.ts +84 -28
  125. package/src/bot/capability-types.ts +11 -0
  126. package/src/bot/cli-provider.ts +8 -7
  127. package/src/bot/preflight.ts +285 -0
  128. package/src/bot/provider-shim.ts +218 -0
  129. package/src/bot/runner.ts +68 -20
  130. package/src/bot/step-executor.ts +69 -127
  131. package/src/bot/swarm-controller.ts +94 -20
  132. package/src/bot/task-create-handler.ts +164 -0
  133. package/src/bot/task-store.ts +76 -0
  134. package/src/bot/types.ts +4 -1
  135. package/src/bot/weaver-tools.ts +7 -45
  136. package/src/node-types/agent-execute.ts +102 -16
  137. package/src/node-types/bot-report.ts +24 -3
  138. package/src/node-types/plan-task.ts +238 -280
  139. package/src/node-types/review-result.ts +8 -6
  140. package/src/palindrome.ts +14 -0
  141. package/src/ui/approval-card.tsx +78 -62
  142. package/src/ui/bot-activity.tsx +12 -10
  143. package/src/ui/bot-config.tsx +12 -10
  144. package/src/ui/bot-dashboard.tsx +13 -11
  145. package/src/ui/bot-panel.tsx +189 -171
  146. package/src/ui/bot-slot-card.tsx +125 -70
  147. package/src/ui/bot-status.tsx +4 -4
  148. package/src/ui/budget-bar.tsx +86 -25
  149. package/src/ui/capability-editor.tsx +392 -257
  150. package/src/ui/chat-task-result.tsx +81 -78
  151. package/src/ui/decision-log.tsx +76 -73
  152. package/src/ui/genesis-block.tsx +91 -61
  153. package/src/ui/instance-stream-view.tsx +861 -0
  154. package/src/ui/profile-card.tsx +195 -168
  155. package/src/ui/profile-editor.tsx +453 -370
  156. package/src/ui/settings-section.tsx +46 -39
  157. package/src/ui/swarm-controls.tsx +252 -123
  158. package/src/ui/swarm-dashboard.tsx +999 -466
  159. package/src/ui/task-detail-view.tsx +485 -428
  160. package/src/ui/task-editor.tsx +329 -271
  161. package/src/ui/task-pool-list.tsx +68 -62
  162. package/src/workflows/src/palindrome.ts +16 -0
  163. package/src/workflows/tests/palindrome.test.ts +49 -0
  164. package/src/workflows/weaver-bot-batch.ts +1 -1
  165. package/src/workflows/weaver-bot.ts +1 -1
  166. package/dist/ui/bot-constants.d.ts +0 -14
  167. package/dist/ui/bot-constants.d.ts.map +0 -1
  168. package/dist/ui/bot-constants.js +0 -189
  169. package/dist/ui/bot-constants.js.map +0 -1
  170. package/dist/ui/steer-api.d.ts +0 -7
  171. package/dist/ui/steer-api.d.ts.map +0 -1
  172. package/dist/ui/steer-api.js +0 -11
  173. package/dist/ui/steer-api.js.map +0 -1
  174. package/dist/ui/trace-to-timeline.d.ts +0 -91
  175. package/dist/ui/trace-to-timeline.d.ts.map +0 -1
  176. package/dist/ui/trace-to-timeline.js +0 -116
  177. package/dist/ui/trace-to-timeline.js.map +0 -1
  178. package/dist/ui/use-stream-timeline.d.ts +0 -50
  179. package/dist/ui/use-stream-timeline.d.ts.map +0 -1
  180. package/dist/ui/use-stream-timeline.js +0 -245
  181. package/dist/ui/use-stream-timeline.js.map +0 -1
@@ -6,16 +6,12 @@
6
6
  * - Edit: loads task by ID on mount, saves via fw_weaver_task_update.
7
7
  *
8
8
  * Calls tool functions internally via usePackWorkspace.
9
- *
10
- * Pattern: CommonJS require for platform deps, ESM import for local files,
11
- * React.createElement throughout, module.exports at end.
12
9
  */
13
- const React = require('react');
14
- const { useState, useEffect, useCallback } = React;
15
- const {
10
+ import React, { useState, useEffect, useCallback } from 'react';
11
+ import {
16
12
  Flex, Typography, Input, Button, IconButton, Chip, Field,
17
13
  toast, usePackWorkspace,
18
- } = require('@fw/plugin-ui-kit');
14
+ } from '@fw/plugin-ui-kit';
19
15
 
20
16
  // ---------------------------------------------------------------------------
21
17
  // Types
@@ -319,11 +315,13 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }: TaskEditorProp
319
315
 
320
316
  // --- Loading state ---
321
317
  if (loading) {
322
- return React.createElement(Flex, {
323
- variant: 'column-center-center-nowrap-12',
324
- style: { padding: '24px 16px' },
325
- },
326
- React.createElement(Typography, { variant: 'caption-regular', color: 'color-text-subtle' }, 'Loading task...'),
318
+ return (
319
+ <Flex
320
+ variant="column-center-center-nowrap-12"
321
+ style={{ padding: '24px 16px' }}
322
+ >
323
+ <Typography variant="caption-regular" color="color-text-subtle">Loading task...</Typography>
324
+ </Flex>
327
325
  );
328
326
  }
329
327
 
@@ -334,267 +332,327 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }: TaskEditorProp
334
332
  ];
335
333
 
336
334
  // --- Render ---
337
- return React.createElement(Flex, {
338
- variant: 'column-stretch-start-nowrap-0',
339
- style: { width: '100%', height: '100%', overflow: 'hidden' },
340
- },
341
- // -- Header bar --
342
- React.createElement(Flex, {
343
- variant: 'row-center-space-between-nowrap-8',
344
- style: { padding: '8px 16px', flexShrink: 0, borderBottom: '1px solid var(--color-border-default)' },
345
- },
346
- React.createElement(Flex, { variant: 'row-center-start-nowrap-8' },
347
- React.createElement(IconButton, {
348
- icon: 'back', size: 'xs', variant: 'clear',
349
- onClick: handleBack,
350
- title: 'Back',
351
- }),
352
- React.createElement(Typography, { variant: 'caption-thick', color: 'color-text-high' },
353
- mode === 'create' ? 'Create Task' : 'Edit Task',
354
- ),
355
- ),
356
- mode === 'edit' && onDelete && React.createElement(IconButton, {
357
- icon: 'outlinedDelete', size: 'sm', variant: 'clear', color: 'danger',
358
- onClick: handleDelete,
359
- title: 'Cancel task',
360
- }),
361
- ),
362
-
363
- // -- Scrollable form body --
364
- React.createElement(Flex, {
365
- variant: 'column-stretch-start-nowrap-10',
366
- style: { flex: 1, minHeight: 0, overflow: 'auto', padding: '12px 16px' },
367
- },
368
-
369
- // -- Edit-only: Status tag --
370
- mode === 'edit' && taskData && React.createElement(Field, { label: 'Status' },
371
- React.createElement(Chip, {
372
- label: taskData.status,
373
- size: 'small',
374
- color: STATUS_COLOR[taskData.status] || 'color-brand-alt',
375
- }),
376
- ),
377
-
378
- // -- Title --
379
- React.createElement(Field, { label: 'Title' },
380
- React.createElement(Input, {
381
- type: 'text', size: 'small',
382
- placeholder: 'Task title (required)',
383
- value: title,
384
- onChange: (v: string) => setTitle(v),
385
- defaultBoxStyle: { flex: 1, minWidth: 0 },
386
- inputBoxStyle: { maxWidth: 'none' },
387
- }),
388
- ),
389
-
390
- // -- Description --
391
- React.createElement(Field, { label: 'Description' },
392
- React.createElement(Input, {
393
- type: 'text', size: 'small',
394
- placeholder: 'Detailed task description',
395
- value: description,
396
- onChange: (v: string) => setDescription(v),
397
- defaultBoxStyle: { flex: 1, minWidth: 0 },
398
- inputBoxStyle: { maxWidth: 'none' },
399
- }),
400
- ),
401
-
402
- // -- Priority --
403
- React.createElement(Field, { label: 'Priority' },
404
- React.createElement(Input, {
405
- type: 'select', size: 'small',
406
- options: PRIORITY_OPTIONS,
407
- optionId: priority,
408
- onChange: (id: string) => setPriority(id),
409
- defaultBoxStyle: { flex: 1, minWidth: 0 },
410
- }),
411
- ),
412
-
413
- // -- Complexity --
414
- React.createElement(Field, { label: 'Complexity' },
415
- React.createElement(Input, {
416
- type: 'select', size: 'small',
417
- options: COMPLEXITY_OPTIONS,
418
- optionId: complexity,
419
- onChange: (id: string) => setComplexity(id),
420
- defaultBoxStyle: { flex: 1, minWidth: 0 },
421
- }),
422
- ),
423
-
424
- // -- Assigned Profile --
425
- React.createElement(Field, { label: 'Profile' },
426
- React.createElement(Input, {
427
- type: 'select', size: 'small',
428
- options: profileOptions,
429
- optionId: assignedProfile,
430
- onChange: (id: string) => setAssignedProfile(id),
431
- placeholder: 'Select profile',
432
- defaultBoxStyle: { flex: 1, minWidth: 0 },
433
- }),
434
- ),
435
-
436
- // -- Budget Cost --
437
- React.createElement(Field, { label: 'Budget Cost' },
438
- React.createElement(Input, {
439
- type: 'number', size: 'small',
440
- placeholder: 'Optional cost limit (USD)',
441
- value: budgetCost,
442
- onChange: (v: string) => setBudgetCost(v),
443
- }),
444
- ),
445
-
446
- // -- Notes --
447
- React.createElement(Field, { label: 'Notes', align: 'start' },
448
- React.createElement(Input, {
449
- type: 'text', size: 'small',
450
- multiline: true,
451
- placeholder: 'Optional notes for context',
452
- value: notes,
453
- onChange: (v: string) => setNotes(v),
454
- defaultBoxStyle: { flex: 1, minWidth: 0 },
455
- inputBoxStyle: { maxWidth: 'none' },
456
- }),
457
- ),
458
-
459
- // -- Files --
460
- React.createElement(Field, { label: 'Files', align: 'start' },
461
- React.createElement(Flex, { variant: 'column-stretch-start-nowrap-6' },
462
- // File picker
463
- React.createElement(Input, {
464
- type: 'path', size: 'small',
465
- placeholder: 'Click to browse files',
466
- value: '',
467
- onClick: async () => {
468
- const selected = await ctx.browseFiles({ title: 'Select Files', multiple: true });
469
- if (selected.length > 0) {
470
- setFiles((prev: string[]) => {
471
- const unique = selected.filter((f: string) => !prev.includes(f));
472
- return [...prev, ...unique];
473
- });
474
- }
475
- },
476
- defaultBoxStyle: { flex: 1, minWidth: 0 },
477
- }),
478
- // File list
479
- ...files.map((file: string, idx: number) =>
480
- React.createElement(Flex, {
481
- key: `file-${idx}`,
482
- variant: 'row-center-start-nowrap-6',
483
- style: { paddingLeft: '4px' },
484
- },
485
- React.createElement(Typography, {
486
- variant: 'smallCaption-regular', color: 'color-text-high',
487
- style: { flex: 1, minWidth: 0, fontFamily: 'var(--font-mono, monospace)' },
488
- }, file),
489
- React.createElement(IconButton, {
490
- icon: 'close', size: 'xs', variant: 'clear', color: 'danger',
491
- onClick: () => handleRemoveFile(idx),
492
- }),
493
- ),
494
- ),
495
- ),
496
- ),
497
-
498
- // -- Dependencies --
499
- React.createElement(Field, { label: 'Dependencies', align: 'start' },
500
- React.createElement(Flex, { variant: 'column-stretch-start-nowrap-6' },
501
- // Add dependency row (create mode only)
502
- mode === 'create' && React.createElement(Flex, { variant: 'row-center-start-nowrap-4' },
503
- React.createElement(Input, {
504
- type: 'select', size: 'small',
505
- placeholder: 'Select a task',
506
- options: availableTasks
507
- .filter((t: { id: string }) => !dependsOn.includes(t.id) && t.id !== taskId)
508
- .map((t: { id: string; title: string }) => ({ id: t.id, label: t.title })),
509
- optionId: newDep,
510
- onChange: (v: string) => setNewDep(v),
511
- defaultBoxStyle: { flex: 1, minWidth: 0 },
512
- }),
513
- React.createElement(IconButton, {
514
- icon: 'add', size: 'sm', variant: 'outlined', color: 'primary',
515
- onClick: handleAddDep,
516
- disabled: !newDep.trim(),
517
- }),
518
- ),
519
- // Dependency list
520
- dependsOn.length > 0
521
- ? React.createElement(Flex, { variant: 'column-stretch-start-nowrap-4' },
522
- ...dependsOn.map((dep: string, idx: number) =>
523
- React.createElement(Flex, {
524
- key: `dep-${idx}`,
525
- variant: 'row-center-start-nowrap-6',
526
- style: { paddingLeft: '4px' },
527
- },
528
- React.createElement(Typography, {
529
- variant: 'smallCaption-regular', color: 'color-text-high',
530
- style: { flex: 1, minWidth: 0 },
531
- }, (() => { const t = availableTasks.find((t: { id: string }) => t.id === dep); return t ? t.title : dep; })()),
532
- mode === 'create' && React.createElement(IconButton, {
533
- icon: 'close', size: 'xs', variant: 'clear', color: 'danger',
534
- onClick: () => handleRemoveDep(idx),
535
- }),
536
- ),
537
- ),
335
+ return (
336
+ <Flex
337
+ variant="column-stretch-start-nowrap-0"
338
+ style={{ width: '100%', height: '100%', overflow: 'hidden' }}
339
+ >
340
+ {/* -- Header bar -- */}
341
+ <Flex
342
+ variant="row-center-space-between-nowrap-8"
343
+ style={{ padding: '8px 16px', flexShrink: 0, borderBottom: '1px solid var(--color-border-default)' }}
344
+ >
345
+ <Flex variant="row-center-start-nowrap-8">
346
+ <IconButton
347
+ icon="back"
348
+ size="xs"
349
+ variant="clear"
350
+ onClick={handleBack}
351
+ title="Back"
352
+ />
353
+ <Typography variant="caption-thick" color="color-text-high">
354
+ {mode === 'create' ? 'Create Task' : 'Edit Task'}
355
+ </Typography>
356
+ </Flex>
357
+ {mode === 'edit' && onDelete && (
358
+ <IconButton
359
+ icon="outlinedDelete"
360
+ size="sm"
361
+ variant="clear"
362
+ color="danger"
363
+ onClick={handleDelete}
364
+ title="Cancel task"
365
+ />
366
+ )}
367
+ </Flex>
368
+
369
+ {/* -- Scrollable form body -- */}
370
+ <Flex
371
+ variant="column-stretch-start-nowrap-10"
372
+ style={{ flex: 1, minHeight: 0, overflow: 'auto', padding: '12px 16px' }}
373
+ >
374
+ {/* -- Edit-only: Status tag -- */}
375
+ {mode === 'edit' && taskData && (
376
+ <Field label="Status">
377
+ <Chip
378
+ label={taskData.status}
379
+ size="small"
380
+ color={STATUS_COLOR[taskData.status] || 'color-brand-alt'}
381
+ />
382
+ </Field>
383
+ )}
384
+
385
+ {/* -- Title -- */}
386
+ <Field label="Title">
387
+ <Input
388
+ type="text"
389
+ size="small"
390
+ placeholder="Task title (required)"
391
+ value={title}
392
+ onChange={(v: string) => setTitle(v)}
393
+ defaultBoxStyle={{ flex: 1, minWidth: 0 }}
394
+ inputBoxStyle={{ maxWidth: 'none' }}
395
+ />
396
+ </Field>
397
+
398
+ {/* -- Description -- */}
399
+ <Field label="Description">
400
+ <Input
401
+ type="text"
402
+ size="small"
403
+ placeholder="Detailed task description"
404
+ value={description}
405
+ onChange={(v: string) => setDescription(v)}
406
+ defaultBoxStyle={{ flex: 1, minWidth: 0 }}
407
+ inputBoxStyle={{ maxWidth: 'none' }}
408
+ />
409
+ </Field>
410
+
411
+ {/* -- Priority -- */}
412
+ <Field label="Priority">
413
+ <Input
414
+ type="select"
415
+ size="small"
416
+ options={PRIORITY_OPTIONS}
417
+ optionId={priority}
418
+ onChange={(id: string) => setPriority(id)}
419
+ defaultBoxStyle={{ flex: 1, minWidth: 0 }}
420
+ />
421
+ </Field>
422
+
423
+ {/* -- Complexity -- */}
424
+ <Field label="Complexity">
425
+ <Input
426
+ type="select"
427
+ size="small"
428
+ options={COMPLEXITY_OPTIONS}
429
+ optionId={complexity}
430
+ onChange={(id: string) => setComplexity(id)}
431
+ defaultBoxStyle={{ flex: 1, minWidth: 0 }}
432
+ />
433
+ </Field>
434
+
435
+ {/* -- Assigned Profile -- */}
436
+ <Field label="Profile">
437
+ <Input
438
+ type="select"
439
+ size="small"
440
+ options={profileOptions}
441
+ optionId={assignedProfile}
442
+ onChange={(id: string) => setAssignedProfile(id)}
443
+ placeholder="Select profile"
444
+ defaultBoxStyle={{ flex: 1, minWidth: 0 }}
445
+ />
446
+ </Field>
447
+
448
+ {/* -- Budget Cost -- */}
449
+ <Field label="Budget Cost">
450
+ <Input
451
+ type="number"
452
+ size="small"
453
+ placeholder="Optional cost limit (USD)"
454
+ value={budgetCost}
455
+ onChange={(v: string) => setBudgetCost(v)}
456
+ />
457
+ </Field>
458
+
459
+ {/* -- Notes -- */}
460
+ <Field label="Notes" align="start">
461
+ <Input
462
+ type="text"
463
+ size="small"
464
+ multiline={true}
465
+ placeholder="Optional notes for context"
466
+ value={notes}
467
+ onChange={(v: string) => setNotes(v)}
468
+ defaultBoxStyle={{ flex: 1, minWidth: 0 }}
469
+ inputBoxStyle={{ maxWidth: 'none' }}
470
+ />
471
+ </Field>
472
+
473
+ {/* -- Files -- */}
474
+ <Field label="Files" align="start">
475
+ <Flex variant="column-stretch-start-nowrap-6">
476
+ <Input
477
+ type="path"
478
+ size="small"
479
+ placeholder="Click to browse files"
480
+ value=""
481
+ onClick={async () => {
482
+ const selected = await ctx.browseFiles({ title: 'Select Files', multiple: true });
483
+ if (selected.length > 0) {
484
+ setFiles((prev: string[]) => {
485
+ const unique = selected.filter((f: string) => !prev.includes(f));
486
+ return [...prev, ...unique];
487
+ });
488
+ }
489
+ }}
490
+ defaultBoxStyle={{ flex: 1, minWidth: 0 }}
491
+ />
492
+ {files.map((file: string, idx: number) => (
493
+ <Flex
494
+ key={`file-${idx}`}
495
+ variant="row-center-start-nowrap-6"
496
+ style={{ paddingLeft: '4px' }}
497
+ >
498
+ <Typography
499
+ variant="smallCaption-regular"
500
+ color="color-text-high"
501
+ style={{ flex: 1, minWidth: 0, fontFamily: 'var(--font-mono, monospace)' }}
502
+ >
503
+ {file}
504
+ </Typography>
505
+ <IconButton
506
+ icon="close"
507
+ size="xs"
508
+ variant="clear"
509
+ color="danger"
510
+ onClick={() => handleRemoveFile(idx)}
511
+ />
512
+ </Flex>
513
+ ))}
514
+ </Flex>
515
+ </Field>
516
+
517
+ {/* -- Dependencies -- */}
518
+ <Field label="Dependencies" align="start">
519
+ <Flex variant="column-stretch-start-nowrap-6">
520
+ {mode === 'create' && (
521
+ <Flex variant="row-center-start-nowrap-4">
522
+ <Input
523
+ type="select"
524
+ size="small"
525
+ placeholder="Select a task"
526
+ options={availableTasks
527
+ .filter((t: { id: string }) => !dependsOn.includes(t.id) && t.id !== taskId)
528
+ .map((t: { id: string; title: string }) => ({ id: t.id, label: t.title }))}
529
+ optionId={newDep}
530
+ onChange={(v: string) => setNewDep(v)}
531
+ defaultBoxStyle={{ flex: 1, minWidth: 0 }}
532
+ />
533
+ <IconButton
534
+ icon="add"
535
+ size="sm"
536
+ variant="outlined"
537
+ color="primary"
538
+ onClick={handleAddDep}
539
+ disabled={!newDep.trim()}
540
+ />
541
+ </Flex>
542
+ )}
543
+ {dependsOn.length > 0
544
+ ? (
545
+ <Flex variant="column-stretch-start-nowrap-4">
546
+ {dependsOn.map((dep: string, idx: number) => (
547
+ <Flex
548
+ key={`dep-${idx}`}
549
+ variant="row-center-start-nowrap-6"
550
+ style={{ paddingLeft: '4px' }}
551
+ >
552
+ <Typography
553
+ variant="smallCaption-regular"
554
+ color="color-text-high"
555
+ style={{ flex: 1, minWidth: 0 }}
556
+ >
557
+ {(() => { const t = availableTasks.find((t: { id: string }) => t.id === dep); return t ? t.title : dep; })()}
558
+ </Typography>
559
+ {mode === 'create' && (
560
+ <IconButton
561
+ icon="close"
562
+ size="xs"
563
+ variant="clear"
564
+ color="danger"
565
+ onClick={() => handleRemoveDep(idx)}
566
+ />
567
+ )}
568
+ </Flex>
569
+ ))}
570
+ </Flex>
538
571
  )
539
- : React.createElement(Typography, {
540
- variant: 'smallCaption-regular', color: 'color-text-subtle',
541
- style: { paddingLeft: '4px' },
542
- }, 'None'),
543
- mode === 'edit' && React.createElement(Typography, {
544
- variant: 'smallCaption-regular', color: 'color-text-subtle',
545
- style: { paddingLeft: '4px', fontStyle: 'italic' },
546
- }, 'Dependencies cannot be changed after creation'),
547
- ),
548
- ),
549
-
550
- // -- Edit-only: read-only metadata --
551
- mode === 'edit' && taskData && React.createElement(Flex, {
552
- variant: 'column-stretch-start-nowrap-10',
553
- style: { marginTop: 8, paddingTop: 12, borderTop: '1px solid var(--color-border-default)' },
554
- },
555
- React.createElement(Field, { label: 'Created by' },
556
- React.createElement(Typography, { variant: 'smallCaption-regular', color: 'color-text-medium' },
557
- taskData.createdBy || 'unknown'),
558
- ),
559
- React.createElement(Field, { label: 'Created at' },
560
- React.createElement(Typography, { variant: 'smallCaption-regular', color: 'color-text-medium' },
561
- taskData.createdAt ? new Date(taskData.createdAt).toLocaleString() : '-'),
562
- ),
563
- React.createElement(Field, { label: 'Updated at' },
564
- React.createElement(Typography, { variant: 'smallCaption-regular', color: 'color-text-medium' },
565
- taskData.updatedAt ? new Date(taskData.updatedAt).toLocaleString() : '-'),
566
- ),
567
- React.createElement(Field, { label: 'Tokens used' },
568
- React.createElement(Typography, { variant: 'smallCaption-regular', color: 'color-text-medium' },
569
- (taskData.tokensUsed ?? 0).toLocaleString()),
570
- ),
571
- React.createElement(Field, { label: 'Cost used' },
572
- React.createElement(Typography, { variant: 'smallCaption-regular', color: 'color-text-medium' },
573
- `$${(taskData.costUsed ?? 0).toFixed(3)}`),
574
- ),
575
- (taskData.context?.runHistory as Array<{ remainingWork?: string }> | undefined)?.slice(-1)?.[0]?.remainingWork && React.createElement(Field, { label: 'Remaining work', align: 'start' },
576
- React.createElement(Typography, {
577
- variant: 'smallCaption-regular', color: 'color-status-caution',
578
- style: { fontFamily: 'var(--font-mono, monospace)', whiteSpace: 'pre-wrap' },
579
- }, (taskData.context.runHistory as Array<{ remainingWork?: string }>).slice(-1)[0]?.remainingWork),
580
- ),
581
- ),
582
-
583
- ),
584
-
585
- // -- Footer bar with save button --
586
- React.createElement(Flex, {
587
- variant: 'row-center-end-nowrap-8',
588
- style: { padding: '8px 16px', flexShrink: 0, borderTop: '1px solid var(--color-border-default)' },
589
- },
590
- React.createElement(Button, {
591
- size: 'xs', variant: 'fill', color: 'primary',
592
- onClick: handleSave,
593
- disabled: !title.trim(),
594
- }, mode === 'create' ? 'Create' : 'Save'),
595
- ),
572
+ : (
573
+ <Typography
574
+ variant="smallCaption-regular"
575
+ color="color-text-subtle"
576
+ style={{ paddingLeft: '4px' }}
577
+ >
578
+ None
579
+ </Typography>
580
+ )}
581
+ {mode === 'edit' && (
582
+ <Typography
583
+ variant="smallCaption-regular"
584
+ color="color-text-subtle"
585
+ style={{ paddingLeft: '4px', fontStyle: 'italic' }}
586
+ >
587
+ Dependencies cannot be changed after creation
588
+ </Typography>
589
+ )}
590
+ </Flex>
591
+ </Field>
592
+
593
+ {/* -- Edit-only: read-only metadata -- */}
594
+ {mode === 'edit' && taskData && (
595
+ <Flex
596
+ variant="column-stretch-start-nowrap-10"
597
+ style={{ marginTop: 8, paddingTop: 12, borderTop: '1px solid var(--color-border-default)' }}
598
+ >
599
+ <Field label="Created by">
600
+ <Typography variant="smallCaption-regular" color="color-text-medium">
601
+ {taskData.createdBy || 'unknown'}
602
+ </Typography>
603
+ </Field>
604
+ <Field label="Created at">
605
+ <Typography variant="smallCaption-regular" color="color-text-medium">
606
+ {taskData.createdAt ? new Date(taskData.createdAt).toLocaleString() : '-'}
607
+ </Typography>
608
+ </Field>
609
+ <Field label="Updated at">
610
+ <Typography variant="smallCaption-regular" color="color-text-medium">
611
+ {taskData.updatedAt ? new Date(taskData.updatedAt).toLocaleString() : '-'}
612
+ </Typography>
613
+ </Field>
614
+ <Field label="Tokens used">
615
+ <Typography variant="smallCaption-regular" color="color-text-medium">
616
+ {(taskData.tokensUsed ?? 0).toLocaleString()}
617
+ </Typography>
618
+ </Field>
619
+ <Field label="Cost used">
620
+ <Typography variant="smallCaption-regular" color="color-text-medium">
621
+ {`$${(taskData.costUsed ?? 0).toFixed(3)}`}
622
+ </Typography>
623
+ </Field>
624
+ {(taskData.context?.runHistory as Array<{ remainingWork?: string }> | undefined)?.slice(-1)?.[0]?.remainingWork && (
625
+ <Field label="Remaining work" align="start">
626
+ <Typography
627
+ variant="smallCaption-regular"
628
+ color="color-status-caution"
629
+ style={{ fontFamily: 'var(--font-mono, monospace)', whiteSpace: 'pre-wrap' }}
630
+ >
631
+ {(taskData.context.runHistory as Array<{ remainingWork?: string }>).slice(-1)[0]?.remainingWork}
632
+ </Typography>
633
+ </Field>
634
+ )}
635
+ </Flex>
636
+ )}
637
+ </Flex>
638
+
639
+ {/* -- Footer bar with save button -- */}
640
+ <Flex
641
+ variant="row-center-end-nowrap-8"
642
+ style={{ padding: '8px 16px', flexShrink: 0, borderTop: '1px solid var(--color-border-default)' }}
643
+ >
644
+ <Button
645
+ size="xs"
646
+ variant="fill"
647
+ color="primary"
648
+ onClick={handleSave}
649
+ disabled={!title.trim()}
650
+ >
651
+ {mode === 'create' ? 'Create' : 'Save'}
652
+ </Button>
653
+ </Flex>
654
+ </Flex>
596
655
  );
597
656
  }
598
657
 
599
658
  export default TaskEditor;
600
- module.exports = TaskEditor;