@synergenius/flow-weaver-pack-weaver 0.9.82 → 0.9.83

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.
@@ -984,7 +984,7 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
984
984
  const ok = await ctx.confirm("Cancel this task? It cannot be undone.", {
985
985
  title: "Cancel Task",
986
986
  confirmLabel: "Cancel Task",
987
- state: "warning"
987
+ state: "danger"
988
988
  });
989
989
  if (!ok) return;
990
990
  setActionLoading("cancel");
@@ -1574,11 +1574,11 @@ var {
1574
1574
  usePackWorkspace: usePackWorkspace3
1575
1575
  } = require("@fw/plugin-ui-kit");
1576
1576
  var PRIORITY_OPTIONS = [
1577
- { id: "0", label: "0 \u2014 None" },
1578
- { id: "1", label: "1 \u2014 Low" },
1579
- { id: "2", label: "2 \u2014 Medium" },
1580
- { id: "3", label: "3 \u2014 High" },
1581
- { id: "4", label: "4 \u2014 Critical" }
1577
+ { id: "0", label: "0 - None" },
1578
+ { id: "1", label: "1 - Low" },
1579
+ { id: "2", label: "2 - Medium" },
1580
+ { id: "3", label: "3 - High" },
1581
+ { id: "4", label: "4 - Critical" }
1582
1582
  ];
1583
1583
  var COMPLEXITY_OPTIONS = [
1584
1584
  { id: "", label: "Not set" },
@@ -1665,7 +1665,24 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }) {
1665
1665
  return () => {
1666
1666
  cancelled = true;
1667
1667
  };
1668
- }, [mode, taskId, callTool, onCancel]);
1668
+ }, [mode, taskId, callTool]);
1669
+ const isDirty = useCallback3(() => {
1670
+ if (mode === "create") {
1671
+ return !!(title.trim() || description.trim() || notes.trim() || files.length > 0 || dependsOn.length > 0 || priority !== "0" || complexity || assignedProfile || maxAttempts !== "3" || budgetTokens || budgetCost);
1672
+ }
1673
+ if (!taskData) return false;
1674
+ return title.trim() !== (taskData.title || "") || description.trim() !== (taskData.description || "") || notes.trim() !== (taskData.context?.notes || "") || JSON.stringify(files) !== JSON.stringify(taskData.context?.files || []) || priority !== String(taskData.priority ?? 0) || complexity !== (taskData.complexity || "") || assignedProfile !== (taskData.assignedProfile || "") || maxAttempts !== String(taskData.maxAttempts ?? 3) || budgetTokens !== (taskData.budgetTokens != null ? String(taskData.budgetTokens) : "") || budgetCost !== (taskData.budgetCost != null ? String(taskData.budgetCost) : "");
1675
+ }, [mode, title, description, notes, files, dependsOn, priority, complexity, assignedProfile, maxAttempts, budgetTokens, budgetCost, taskData]);
1676
+ const handleBack = useCallback3(async () => {
1677
+ if (isDirty()) {
1678
+ const ok = await ctx.confirm("Discard unsaved changes?", {
1679
+ title: "Unsaved Changes",
1680
+ state: "warning"
1681
+ });
1682
+ if (!ok) return;
1683
+ }
1684
+ onCancel();
1685
+ }, [isDirty, ctx, onCancel]);
1669
1686
  const handleAddFile = useCallback3(() => {
1670
1687
  const trimmed = newFile.trim();
1671
1688
  if (!trimmed) return;
@@ -1702,13 +1719,20 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }) {
1702
1719
  if (budgetTokens) args.budgetTokens = parseInt(budgetTokens, 10);
1703
1720
  if (budgetCost) args.budgetCost = parseFloat(budgetCost);
1704
1721
  if (dependsOn.length > 0) args.dependsOn = dependsOn;
1705
- await callTool("fw_weaver_task_create", args);
1706
- toast3("Task created", { type: "success" });
1707
- if (notes.trim() || files.length > 0) {
1708
- try {
1709
- } catch {
1710
- }
1722
+ const result = await callTool("fw_weaver_task_create", args);
1723
+ const createData = typeof result === "string" ? JSON.parse(result) : result;
1724
+ const createdId = createData?.task?.id;
1725
+ if (createdId && (notes.trim() || files.length > 0)) {
1726
+ await callTool("fw_weaver_task_update", {
1727
+ id: createdId,
1728
+ context: {
1729
+ notes: notes.trim(),
1730
+ files,
1731
+ runSummaries: []
1732
+ }
1733
+ });
1711
1734
  }
1735
+ toast3("Task created", { type: "success" });
1712
1736
  } else {
1713
1737
  const patch = {
1714
1738
  id: taskId,
@@ -1793,7 +1817,7 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }) {
1793
1817
  icon: "back",
1794
1818
  size: "xs",
1795
1819
  variant: "clear",
1796
- onClick: onCancel,
1820
+ onClick: handleBack,
1797
1821
  title: "Back"
1798
1822
  }),
1799
1823
  React7.createElement(
@@ -2065,7 +2089,12 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }) {
2065
2089
  variant: "smallCaption-regular",
2066
2090
  color: "color-text-subtle",
2067
2091
  style: { paddingLeft: "4px" }
2068
- }, "None")
2092
+ }, "None"),
2093
+ mode === "edit" && React7.createElement(Typography6, {
2094
+ variant: "smallCaption-regular",
2095
+ color: "color-text-subtle",
2096
+ style: { paddingLeft: "4px", fontStyle: "italic" }
2097
+ }, "Dependencies cannot be changed after creation")
2069
2098
  )
2070
2099
  ),
2071
2100
  // -- Edit-only: read-only metadata --
@@ -2129,19 +2158,22 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }) {
2129
2158
  style: { fontFamily: "var(--font-mono, monospace)", whiteSpace: "pre-wrap" }
2130
2159
  }, taskData.context.lastError)
2131
2160
  )
2132
- ),
2133
- // -- Save button --
2134
- React7.createElement(
2135
- Flex6,
2136
- { variant: "row-center-end-nowrap-8", style: { paddingTop: 8 } },
2137
- React7.createElement(Button3, {
2138
- size: "xs",
2139
- variant: "fill",
2140
- color: "primary",
2141
- onClick: handleSave,
2142
- disabled: !title.trim()
2143
- }, mode === "create" ? "Create" : "Save")
2144
2161
  )
2162
+ ),
2163
+ // -- Footer bar with save button --
2164
+ React7.createElement(
2165
+ Flex6,
2166
+ {
2167
+ variant: "row-center-end-nowrap-8",
2168
+ style: { padding: "8px 16px", flexShrink: 0, borderTop: "1px solid var(--color-border-default)" }
2169
+ },
2170
+ React7.createElement(Button3, {
2171
+ size: "xs",
2172
+ variant: "fill",
2173
+ color: "primary",
2174
+ onClick: handleSave,
2175
+ disabled: !title.trim()
2176
+ }, mode === "create" ? "Create" : "Save")
2145
2177
  )
2146
2178
  );
2147
2179
  }
@@ -479,7 +479,7 @@ function TaskDetailView({ taskId, onBack, onEdit }) {
479
479
  const ok = await ctx.confirm("Cancel this task? It cannot be undone.", {
480
480
  title: "Cancel Task",
481
481
  confirmLabel: "Cancel Task",
482
- state: "warning"
482
+ state: "danger"
483
483
  });
484
484
  if (!ok) return;
485
485
  setActionLoading("cancel");
@@ -20,7 +20,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/ui/task-editor.tsx
21
21
  var task_editor_exports = {};
22
22
  __export(task_editor_exports, {
23
- TaskEditor: () => TaskEditor,
24
23
  default: () => task_editor_default
25
24
  });
26
25
  module.exports = __toCommonJS(task_editor_exports);
@@ -38,11 +37,11 @@ var {
38
37
  usePackWorkspace
39
38
  } = require("@fw/plugin-ui-kit");
40
39
  var PRIORITY_OPTIONS = [
41
- { id: "0", label: "0 \u2014 None" },
42
- { id: "1", label: "1 \u2014 Low" },
43
- { id: "2", label: "2 \u2014 Medium" },
44
- { id: "3", label: "3 \u2014 High" },
45
- { id: "4", label: "4 \u2014 Critical" }
40
+ { id: "0", label: "0 - None" },
41
+ { id: "1", label: "1 - Low" },
42
+ { id: "2", label: "2 - Medium" },
43
+ { id: "3", label: "3 - High" },
44
+ { id: "4", label: "4 - Critical" }
46
45
  ];
47
46
  var COMPLEXITY_OPTIONS = [
48
47
  { id: "", label: "Not set" },
@@ -129,7 +128,24 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }) {
129
128
  return () => {
130
129
  cancelled = true;
131
130
  };
132
- }, [mode, taskId, callTool, onCancel]);
131
+ }, [mode, taskId, callTool]);
132
+ const isDirty = useCallback(() => {
133
+ if (mode === "create") {
134
+ return !!(title.trim() || description.trim() || notes.trim() || files.length > 0 || dependsOn.length > 0 || priority !== "0" || complexity || assignedProfile || maxAttempts !== "3" || budgetTokens || budgetCost);
135
+ }
136
+ if (!taskData) return false;
137
+ return title.trim() !== (taskData.title || "") || description.trim() !== (taskData.description || "") || notes.trim() !== (taskData.context?.notes || "") || JSON.stringify(files) !== JSON.stringify(taskData.context?.files || []) || priority !== String(taskData.priority ?? 0) || complexity !== (taskData.complexity || "") || assignedProfile !== (taskData.assignedProfile || "") || maxAttempts !== String(taskData.maxAttempts ?? 3) || budgetTokens !== (taskData.budgetTokens != null ? String(taskData.budgetTokens) : "") || budgetCost !== (taskData.budgetCost != null ? String(taskData.budgetCost) : "");
138
+ }, [mode, title, description, notes, files, dependsOn, priority, complexity, assignedProfile, maxAttempts, budgetTokens, budgetCost, taskData]);
139
+ const handleBack = useCallback(async () => {
140
+ if (isDirty()) {
141
+ const ok = await ctx.confirm("Discard unsaved changes?", {
142
+ title: "Unsaved Changes",
143
+ state: "warning"
144
+ });
145
+ if (!ok) return;
146
+ }
147
+ onCancel();
148
+ }, [isDirty, ctx, onCancel]);
133
149
  const handleAddFile = useCallback(() => {
134
150
  const trimmed = newFile.trim();
135
151
  if (!trimmed) return;
@@ -166,13 +182,20 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }) {
166
182
  if (budgetTokens) args.budgetTokens = parseInt(budgetTokens, 10);
167
183
  if (budgetCost) args.budgetCost = parseFloat(budgetCost);
168
184
  if (dependsOn.length > 0) args.dependsOn = dependsOn;
169
- await callTool("fw_weaver_task_create", args);
170
- toast("Task created", { type: "success" });
171
- if (notes.trim() || files.length > 0) {
172
- try {
173
- } catch {
174
- }
185
+ const result = await callTool("fw_weaver_task_create", args);
186
+ const createData = typeof result === "string" ? JSON.parse(result) : result;
187
+ const createdId = createData?.task?.id;
188
+ if (createdId && (notes.trim() || files.length > 0)) {
189
+ await callTool("fw_weaver_task_update", {
190
+ id: createdId,
191
+ context: {
192
+ notes: notes.trim(),
193
+ files,
194
+ runSummaries: []
195
+ }
196
+ });
175
197
  }
198
+ toast("Task created", { type: "success" });
176
199
  } else {
177
200
  const patch = {
178
201
  id: taskId,
@@ -257,7 +280,7 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }) {
257
280
  icon: "back",
258
281
  size: "xs",
259
282
  variant: "clear",
260
- onClick: onCancel,
283
+ onClick: handleBack,
261
284
  title: "Back"
262
285
  }),
263
286
  React.createElement(
@@ -529,7 +552,12 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }) {
529
552
  variant: "smallCaption-regular",
530
553
  color: "color-text-subtle",
531
554
  style: { paddingLeft: "4px" }
532
- }, "None")
555
+ }, "None"),
556
+ mode === "edit" && React.createElement(Typography, {
557
+ variant: "smallCaption-regular",
558
+ color: "color-text-subtle",
559
+ style: { paddingLeft: "4px", fontStyle: "italic" }
560
+ }, "Dependencies cannot be changed after creation")
533
561
  )
534
562
  ),
535
563
  // -- Edit-only: read-only metadata --
@@ -593,19 +621,22 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }) {
593
621
  style: { fontFamily: "var(--font-mono, monospace)", whiteSpace: "pre-wrap" }
594
622
  }, taskData.context.lastError)
595
623
  )
596
- ),
597
- // -- Save button --
598
- React.createElement(
599
- Flex,
600
- { variant: "row-center-end-nowrap-8", style: { paddingTop: 8 } },
601
- React.createElement(Button, {
602
- size: "xs",
603
- variant: "fill",
604
- color: "primary",
605
- onClick: handleSave,
606
- disabled: !title.trim()
607
- }, mode === "create" ? "Create" : "Save")
608
624
  )
625
+ ),
626
+ // -- Footer bar with save button --
627
+ React.createElement(
628
+ Flex,
629
+ {
630
+ variant: "row-center-end-nowrap-8",
631
+ style: { padding: "8px 16px", flexShrink: 0, borderTop: "1px solid var(--color-border-default)" }
632
+ },
633
+ React.createElement(Button, {
634
+ size: "xs",
635
+ variant: "fill",
636
+ color: "primary",
637
+ onClick: handleSave,
638
+ disabled: !title.trim()
639
+ }, mode === "create" ? "Create" : "Save")
609
640
  )
610
641
  );
611
642
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synergenius/flow-weaver-pack-weaver",
3
- "version": "0.9.82",
3
+ "version": "0.9.83",
4
4
  "description": "AI bot for Flow Weaver. Execute tasks, run workflows, evolve autonomously.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -323,7 +323,7 @@ function TaskDetailView({ taskId, onBack, onEdit }: TaskDetailViewProps) {
323
323
  const ok = await ctx.confirm('Cancel this task? It cannot be undone.', {
324
324
  title: 'Cancel Task',
325
325
  confirmLabel: 'Cancel Task',
326
- state: 'warning',
326
+ state: 'danger',
327
327
  });
328
328
  if (!ok) return;
329
329
  setActionLoading('cancel');
@@ -61,11 +61,11 @@ interface TaskData {
61
61
  // ---------------------------------------------------------------------------
62
62
 
63
63
  const PRIORITY_OPTIONS = [
64
- { id: '0', label: '0 None' },
65
- { id: '1', label: '1 Low' },
66
- { id: '2', label: '2 Medium' },
67
- { id: '3', label: '3 High' },
68
- { id: '4', label: '4 Critical' },
64
+ { id: '0', label: '0 - None' },
65
+ { id: '1', label: '1 - Low' },
66
+ { id: '2', label: '2 - Medium' },
67
+ { id: '3', label: '3 - High' },
68
+ { id: '4', label: '4 - Critical' },
69
69
  ];
70
70
 
71
71
  const COMPLEXITY_OPTIONS = [
@@ -169,7 +169,38 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }: TaskEditorProp
169
169
  })();
170
170
 
171
171
  return () => { cancelled = true; };
172
- }, [mode, taskId, callTool, onCancel]);
172
+ }, [mode, taskId, callTool]);
173
+
174
+ // --- Dirty-form check on back/cancel ---
175
+ const isDirty = useCallback(() => {
176
+ if (mode === 'create') {
177
+ return !!(title.trim() || description.trim() || notes.trim() || files.length > 0 || dependsOn.length > 0
178
+ || priority !== '0' || complexity || assignedProfile || maxAttempts !== '3' || budgetTokens || budgetCost);
179
+ }
180
+ // Edit mode: compare against loaded data
181
+ if (!taskData) return false;
182
+ return title.trim() !== (taskData.title || '')
183
+ || description.trim() !== (taskData.description || '')
184
+ || notes.trim() !== (taskData.context?.notes || '')
185
+ || JSON.stringify(files) !== JSON.stringify(taskData.context?.files || [])
186
+ || priority !== String(taskData.priority ?? 0)
187
+ || complexity !== (taskData.complexity || '')
188
+ || assignedProfile !== (taskData.assignedProfile || '')
189
+ || maxAttempts !== String(taskData.maxAttempts ?? 3)
190
+ || budgetTokens !== (taskData.budgetTokens != null ? String(taskData.budgetTokens) : '')
191
+ || budgetCost !== (taskData.budgetCost != null ? String(taskData.budgetCost) : '');
192
+ }, [mode, title, description, notes, files, dependsOn, priority, complexity, assignedProfile, maxAttempts, budgetTokens, budgetCost, taskData]);
193
+
194
+ const handleBack = useCallback(async () => {
195
+ if (isDirty()) {
196
+ const ok = await ctx.confirm('Discard unsaved changes?', {
197
+ title: 'Unsaved Changes',
198
+ state: 'warning',
199
+ });
200
+ if (!ok) return;
201
+ }
202
+ onCancel();
203
+ }, [isDirty, ctx, onCancel]);
173
204
 
174
205
  // --- Files list ---
175
206
  const handleAddFile = useCallback(() => {
@@ -216,24 +247,23 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }: TaskEditorProp
216
247
  if (budgetCost) args.budgetCost = parseFloat(budgetCost);
217
248
  if (dependsOn.length > 0) args.dependsOn = dependsOn;
218
249
 
219
- await callTool('fw_weaver_task_create', args);
250
+ const result = await callTool('fw_weaver_task_create', args);
251
+ const createData = typeof result === 'string' ? JSON.parse(result) : result;
252
+ const createdId = createData?.task?.id;
253
+
254
+ // task_create doesn't support context fields — follow up with an update
255
+ if (createdId && (notes.trim() || files.length > 0)) {
256
+ await callTool('fw_weaver_task_update', {
257
+ id: createdId,
258
+ context: {
259
+ notes: notes.trim(),
260
+ files,
261
+ runSummaries: [],
262
+ },
263
+ });
264
+ }
220
265
 
221
- // If notes or files were provided, update context after creation
222
- // (CreateTaskInput doesn't support context.notes/files directly)
223
- // Actually the create result gives us the task id — let's update it
224
- // We'll handle this by doing a second call if needed
225
- // For now, notes/files require a task_update after creation
226
266
  toast('Task created', { type: 'success' });
227
-
228
- // If user added notes or files, update the task context
229
- if (notes.trim() || files.length > 0) {
230
- try {
231
- // Get the created task to find its ID
232
- // The create call returns the task — but we don't have direct access
233
- // We could parse it, but let's keep it simple for now
234
- // The user can edit after creation to add notes/files
235
- } catch { /* non-fatal */ }
236
- }
237
267
  } else {
238
268
  // Edit mode — build patch
239
269
  const patch: Record<string, unknown> = {
@@ -320,7 +350,7 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }: TaskEditorProp
320
350
  React.createElement(Flex, { variant: 'row-center-start-nowrap-8' },
321
351
  React.createElement(IconButton, {
322
352
  icon: 'back', size: 'xs', variant: 'clear',
323
- onClick: onCancel,
353
+ onClick: handleBack,
324
354
  title: 'Back',
325
355
  }),
326
356
  React.createElement(Typography, { variant: 'caption-thick', color: 'color-text-high' },
@@ -538,6 +568,10 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }: TaskEditorProp
538
568
  variant: 'smallCaption-regular', color: 'color-text-subtle',
539
569
  style: { paddingLeft: '4px' },
540
570
  }, 'None'),
571
+ mode === 'edit' && React.createElement(Typography, {
572
+ variant: 'smallCaption-regular', color: 'color-text-subtle',
573
+ style: { paddingLeft: '4px', fontStyle: 'italic' },
574
+ }, 'Dependencies cannot be changed after creation'),
541
575
  ),
542
576
  ),
543
577
 
@@ -574,18 +608,21 @@ function TaskEditor({ mode, taskId, onSave, onCancel, onDelete }: TaskEditorProp
574
608
  ),
575
609
  ),
576
610
 
577
- // -- Save button --
578
- React.createElement(Flex, { variant: 'row-center-end-nowrap-8', style: { paddingTop: 8 } },
579
- React.createElement(Button, {
580
- size: 'xs', variant: 'fill', color: 'primary',
581
- onClick: handleSave,
582
- disabled: !title.trim(),
583
- }, mode === 'create' ? 'Create' : 'Save'),
584
- ),
611
+ ),
612
+
613
+ // -- Footer bar with save button --
614
+ React.createElement(Flex, {
615
+ variant: 'row-center-end-nowrap-8',
616
+ style: { padding: '8px 16px', flexShrink: 0, borderTop: '1px solid var(--color-border-default)' },
617
+ },
618
+ React.createElement(Button, {
619
+ size: 'xs', variant: 'fill', color: 'primary',
620
+ onClick: handleSave,
621
+ disabled: !title.trim(),
622
+ }, mode === 'create' ? 'Create' : 'Save'),
585
623
  ),
586
624
  );
587
625
  }
588
626
 
589
- export { TaskEditor };
590
627
  export default TaskEditor;
591
628
  module.exports = TaskEditor;