@synergenius/flow-weaver-pack-weaver 0.9.199 → 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 +67 -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 +83 -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
@@ -24,6 +24,8 @@ __export(profile_editor_exports, {
24
24
  default: () => profile_editor_default
25
25
  });
26
26
  module.exports = __toCommonJS(profile_editor_exports);
27
+ var import_react = require("react");
28
+ var import_plugin_ui_kit = require("@fw/plugin-ui-kit");
27
29
 
28
30
  // src/ui/bot-constants.ts
29
31
  var ICON_CATALOG = [
@@ -227,7 +229,7 @@ var CAP_CORE = {
227
229
  prompt: `You are Weaver. Execute tasks by calling tools \u2014 do not describe what you would do.
228
230
 
229
231
  ## System Constraints
230
- - All file paths are relative to the workspace root. "../" is blocked.
232
+ - All file paths MUST be relative to the workspace root (e.g. "src/index.ts", not "/home/user/project/src/index.ts"). NEVER use absolute paths. "../" is blocked.
231
233
  - Writes that shrink a file >50% or write empty content are BLOCKED by the system.
232
234
  - Blocked shell commands: rm -rf, git push, npm publish, sudo, curl|sh.`
233
235
  };
@@ -235,45 +237,68 @@ var CAP_ROLE_ORCHESTRATOR = {
235
237
  name: "role-orchestrator",
236
238
  description: "Orchestrator role: decomposes objectives into subtask DAGs.",
237
239
  tools: [OP_TASK_CREATE, OP_LIST_FILES, OP_READ_FILE],
240
+ acceptance: [
241
+ { name: "subtasks-created", command: `python3 -c "import json; tasks=json.load(open('.weaver/tasks.json')); exit(0 if len(tasks)>=3 else 1)"` },
242
+ { name: "deps-defined", command: `python3 -c "import json; tasks=json.load(open('.weaver/tasks.json')); exit(0 if any(t.get('dependsOn') for t in tasks) else 1)"` }
243
+ ],
238
244
  prompt: `## YOUR ROLE: Orchestrator
239
245
  You decompose objectives into subtasks. You never write code or create files directly.
240
246
  Your only output is task_create calls + done.
241
247
 
242
- 1. Analyze the objective and list_files to understand the workspace.
243
- 2. Create subtasks via task_create with parentId: "@self".
244
- 3. Assign profiles: developer (code), reviewer (review), ops (infra/setup).
245
- 4. Set dependsOn using task titles (resolved to IDs automatically).
246
- 5. Add acceptance.checks \u2014 shell commands that exit 0 on success. The system runs them after each run.
247
- 6. Maximize parallelism: tasks with no shared files should not depend on each other.
248
- 7. Your LAST subtask: "Review & Steer" assigned to orchestrator, dependsOn all others.
248
+ ### Execution Planning Protocol
249
+ Before creating subtasks, you MUST:
250
+ 1. Use list_files and read_file to read every source file. Map the dependency graph (which files import which).
251
+ 2. IDENTIFY the critical path \u2014 the longest sequential chain. This is your bottleneck.
252
+ 3. GROUP tasks to match worker count (shown in context as maxConcurrent=N).
253
+ - Each dependency level should have at most N parallel tasks.
254
+ - Combine small independent files into single tasks to reduce overhead.
255
+ - Separate high-risk files (many bugs/complexity) from clean ones.
256
+ - Never create more sequential levels than necessary.
257
+ 4. SHOW YOUR REASONING in the first task_create description:
258
+ - Dependency graph you found
259
+ - Critical path identified
260
+ - Why you grouped tasks this way
249
261
 
250
- ### Design First
251
- For multi-file projects, your FIRST subtask should create a .design.md with:
252
- - Module map: which files, what each exports (function signatures with types)
253
- - Conventions: naming, error handling, patterns (e.g., factory functions for servers)
254
- All subsequent developer tasks must read .design.md before writing code.
262
+ ### Task Creation Rules
263
+ - Create subtasks via task_create with parentId: "@self".
264
+ - Assign profiles: developer (code), reviewer (review), ops (infra/setup).
265
+ - Set dependsOn using task titles (resolved to IDs automatically).
266
+ - Fewer tasks with more work each > many tiny serial tasks.
267
+ - A file and its only dependent CAN be in the same task.
268
+ - Tests can be combined with the last implementation task.
269
+ - Your LAST subtask: "Review & Steer" assigned to orchestrator, dependsOn all others.
255
270
 
256
271
  ### Acceptance Criteria
257
272
  Every subtask MUST have acceptance.checks \u2014 shell commands that verify "done" (exit 0 = pass).
273
+ Checks must test BEHAVIOR (run the code, import the module), not string patterns (grep for text).
258
274
  The system runs them automatically after each run. If any fail, the task stays open.
259
275
  Examples:
260
- - File exists: test -f url-shortener/src/store.ts
261
- - Compiles: cd url-shortener && npx tsc --noEmit
262
- - Tests pass: cd url-shortener && npx vitest run
263
- - Export exists: grep -q "export.*startServer" url-shortener/src/server.ts
276
+ - Compiles: npx tsc --noEmit
277
+ - Tests pass: npx vitest run
278
+ - Module works: node -e "import('./src/db.js').then(m => process.exit(m.getById ? 0 : 1))"
279
+ - File exists: test -f src/types.ts
280
+
281
+ ### Design First
282
+ For multi-file projects, your FIRST subtask should create a .design.md with:
283
+ - Module map: which files, what each exports (function signatures with types)
284
+ - Conventions: naming, error handling, patterns
285
+ All subsequent developer tasks must read .design.md before writing code.
264
286
 
265
287
  ### Steering Mode (when running a Review & Steer task)
266
288
  Read the sibling task list in your context \u2014 it shows status, run count, and check failures with error details.
267
289
  - All checks pass \u2192 done.
268
290
  - Tasks with 0 runs still open \u2192 they will be picked up, do not recreate them.
269
- - Checks failing \u2192 read the specific error in the check detail, then create a targeted fix task addressing that exact error. Do not create broad "fix everything" tasks.
291
+ - Checks failing \u2192 read the specific error in the check detail, then create a targeted fix task addressing that exact error.
270
292
  - Task stagnant (3+ failed runs) \u2192 redefine with smaller scope or reassign to different profile.
271
- - Before creating ANY task, check if an existing open sibling already covers the same work. If yes, do not create a duplicate \u2014 the existing task will be retried.
293
+ - Before creating ANY task, check if an existing open sibling already covers the same work.
272
294
  - After creating fix tasks, create one more Review & Steer depending on them, then done.`
273
295
  };
274
296
  var CAP_ROLE_DEVELOPER = {
275
297
  name: "role-developer",
276
298
  description: "Developer role: writes code, creates files, runs commands.",
299
+ acceptance: [
300
+ { name: "file-changes-produced", command: 'test $(find src tests -name "*.ts" -newer .weaver/swarm.json 2>/dev/null | wc -l) -gt 0 || test $(find src tests -name "*.js" -newer .weaver/swarm.json 2>/dev/null | wc -l) -gt 0', condition: "src" }
301
+ ],
277
302
  prompt: `## YOUR ROLE: Developer
278
303
  You write code and produce files. Execute the task directly \u2014 do not delegate.
279
304
 
@@ -321,8 +346,8 @@ var CAP_SHELL = {
321
346
  };
322
347
  var CAP_TASK_MGMT = {
323
348
  name: "task-mgmt",
324
- description: "Create swarm subtasks.",
325
- tools: [OP_TASK_CREATE],
349
+ description: "Create and inspect swarm subtasks.",
350
+ tools: [OP_TASK_CREATE, "task_list", "task_get", "task_update"],
326
351
  prompt: `## Task Management
327
352
  - task_create(title, description?, assignedProfile?, parentId?, dependsOn?, complexity?, acceptance?):
328
353
  Creates a subtask in the swarm task pool. Returns task ID.
@@ -331,6 +356,9 @@ var CAP_TASK_MGMT = {
331
356
  - assignedProfile: "developer" | "reviewer" | "ops" | "orchestrator". Omit for auto-routing.
332
357
  - parentId: "@self" to nest under current task. Omit for top-level.
333
358
  - dependsOn: Array of task titles. Resolved to IDs automatically.
359
+ - task_list(status?): List tasks in the swarm. Optionally filter by status (pending, in-progress, done, failed).
360
+ - task_get(id): Get full details of a specific task.
361
+ - task_update(id, notes?, files?, description?): Update a task's notes, files list, or description.
334
362
  - complexity: "trivial" | "simple" | "moderate" | "complex".
335
363
  - acceptance: { checks: [{ name: string, command: string }] } \u2014 shell commands that exit 0 on success.`
336
364
  };
@@ -435,17 +463,22 @@ var CAP_VERIFICATION = {
435
463
  name: "verification",
436
464
  description: "TypeScript compilation and test runner verification.",
437
465
  tools: [OP_RUN_SHELL],
466
+ acceptance: [
467
+ { name: "tsc-compiles", command: "npx tsc --noEmit", condition: "find src -name '*.ts' | head -1 | grep -q ." }
468
+ ],
438
469
  prompt: `## Verification
439
- - tsc_check: npx tsc --noEmit \u2014 returns TypeScript compilation errors or empty on success.
440
- - test_run: npx vitest run \u2014 returns test results with pass/fail counts.`
470
+ Use run_shell for compilation and test verification:
471
+ - npx tsc --noEmit \u2014 returns TypeScript compilation errors or empty on success.
472
+ - npx vitest run \u2014 returns test results with pass/fail counts.`
441
473
  };
442
474
  var CAP_CROSS_FILE_CHECK = {
443
475
  name: "cross-file-check",
444
476
  description: "Cross-file dependency verification.",
445
477
  tools: [OP_READ_FILE, OP_LIST_FILES, OP_RUN_SHELL],
446
478
  prompt: `## Cross-File Checks
447
- Use grep (via run_shell) to find all import/export references across files.
448
- Use read_file to verify import paths resolve to actual exports.`
479
+ Use list_files to find relevant files, read_file to inspect them,
480
+ and run_shell with grep to find all import/export references across files.
481
+ Verify import paths resolve to actual exports.`
449
482
  };
450
483
  var CAP_PROJECT_SETUP = {
451
484
  name: "project-setup",
@@ -460,7 +493,7 @@ var CAP_SECURITY = {
460
493
  description: "Security audit tools.",
461
494
  tools: [OP_READ_FILE, OP_LIST_FILES, OP_RUN_SHELL],
462
495
  prompt: `## Security
463
- Use grep (via run_shell) to scan for hardcoded secrets, eval(), shell injection patterns.
496
+ Use list_files to discover files, read_file to inspect them, and run_shell with grep to scan for hardcoded secrets, eval(), shell injection patterns.
464
497
  Use npm audit (via run_shell) for dependency vulnerabilities.
465
498
  Finding format: FILE:LINE | SEVERITY (critical/high/medium/low) | ISSUE.`
466
499
  };
@@ -537,29 +570,7 @@ var STRATEGY_BUDGETS = {
537
570
  };
538
571
 
539
572
  // src/ui/profile-editor.tsx
540
- var React = require("react");
541
- var { useState, useEffect, useCallback } = React;
542
- var {
543
- Flex,
544
- Typography,
545
- Input,
546
- Button,
547
- IconButton,
548
- Icon,
549
- SectionTitle,
550
- Checkbox,
551
- Chip,
552
- Field,
553
- Table,
554
- IconPicker,
555
- ColorPicker,
556
- Switch,
557
- ToggleGroup,
558
- CollapsibleSection,
559
- ScrollArea,
560
- toast,
561
- usePackWorkspace
562
- } = require("@fw/plugin-ui-kit");
573
+ var import_jsx_runtime = require("react/jsx-runtime");
563
574
  var DEFAULT_PHASES = [
564
575
  { name: "plan", label: "Plan", isLlmPhase: true },
565
576
  { name: "execute", label: "Execute", isLlmPhase: true },
@@ -602,28 +613,28 @@ function defaultBehaviorForStrategy(strategy, phases) {
602
613
  return state;
603
614
  }
604
615
  function ProfileEditor({ mode, profileId, bots, onSave, onCancel, onDelete }) {
605
- const ctx = usePackWorkspace();
616
+ const ctx = (0, import_plugin_ui_kit.usePackWorkspace)();
606
617
  const { callTool } = ctx;
607
- const [name, setName] = useState("");
608
- const [description, setDescription] = useState("");
609
- const [botId, setBotId] = useState(mode === "create" && bots.length > 0 ? bots[0].id : "");
610
- const [icon, setIcon] = useState("smartToy");
611
- const [color, setColor] = useState("color-node-blue-icon");
612
- const [costStrategy, setCostStrategy] = useState("balanced");
613
- const [preset, setPreset] = useState("balanced");
614
- const [capabilities, setCapabilities] = useState([]);
615
- const [capName, setCapName] = useState("");
616
- const [capDescription, setCapDescription] = useState("");
617
- const [instructions, setInstructions] = useState("");
618
- const [requireApproval, setRequireApproval] = useState(false);
619
- const [knowledgeCaps, setKnowledgeCaps] = useState(() => [...STRATEGY_CAPABILITIES.balanced]);
620
- const [budget, setBudget] = useState(STRATEGY_BUDGETS.balanced);
621
- const [behavior, setBehavior] = useState(defaultBehaviorForStrategy("balanced"));
622
- const [blockedInput, setBlockedInput] = useState("");
623
- const [allowedInput, setAllowedInput] = useState("");
624
- const [loading, setLoading] = useState(mode === "edit");
618
+ const [name, setName] = (0, import_react.useState)("");
619
+ const [description, setDescription] = (0, import_react.useState)("");
620
+ const [botId, setBotId] = (0, import_react.useState)(mode === "create" && bots.length > 0 ? bots[0].id : "");
621
+ const [icon, setIcon] = (0, import_react.useState)("smartToy");
622
+ const [color, setColor] = (0, import_react.useState)("color-node-blue-icon");
623
+ const [costStrategy, setCostStrategy] = (0, import_react.useState)("balanced");
624
+ const [preset, setPreset] = (0, import_react.useState)("balanced");
625
+ const [capabilities, setCapabilities] = (0, import_react.useState)([]);
626
+ const [capName, setCapName] = (0, import_react.useState)("");
627
+ const [capDescription, setCapDescription] = (0, import_react.useState)("");
628
+ const [instructions, setInstructions] = (0, import_react.useState)("");
629
+ const [requireApproval, setRequireApproval] = (0, import_react.useState)(false);
630
+ const [knowledgeCaps, setKnowledgeCaps] = (0, import_react.useState)(() => [...STRATEGY_CAPABILITIES.balanced]);
631
+ const [budget, setBudget] = (0, import_react.useState)(STRATEGY_BUDGETS.balanced);
632
+ const [behavior, setBehavior] = (0, import_react.useState)(defaultBehaviorForStrategy("balanced"));
633
+ const [blockedInput, setBlockedInput] = (0, import_react.useState)("");
634
+ const [allowedInput, setAllowedInput] = (0, import_react.useState)("");
635
+ const [loading, setLoading] = (0, import_react.useState)(mode === "edit");
625
636
  const isCustom = preset === "custom";
626
- const handlePresetChange = useCallback((value) => {
637
+ const handlePresetChange = (0, import_react.useCallback)((value) => {
627
638
  const p = value;
628
639
  setPreset(p);
629
640
  if (p !== "custom") {
@@ -633,18 +644,18 @@ function ProfileEditor({ mode, profileId, bots, onSave, onCancel, onDelete }) {
633
644
  setBudget(STRATEGY_BUDGETS[p]);
634
645
  }
635
646
  }, []);
636
- const updatePhase = useCallback((phase, field, value) => {
647
+ const updatePhase = (0, import_react.useCallback)((phase, field, value) => {
637
648
  setBehavior((prev) => ({
638
649
  ...prev,
639
650
  [phase]: { ...prev[phase], [field]: value }
640
651
  }));
641
652
  setPreset("custom");
642
653
  }, []);
643
- const updateEscalation = useCallback((field, value) => {
654
+ const updateEscalation = (0, import_react.useCallback)((field, value) => {
644
655
  setBehavior((prev) => ({ ...prev, [field]: value }));
645
656
  setPreset("custom");
646
657
  }, []);
647
- useEffect(() => {
658
+ (0, import_react.useEffect)(() => {
648
659
  if (mode !== "edit" || !profileId) return;
649
660
  let cancelled = false;
650
661
  (async () => {
@@ -655,7 +666,7 @@ function ProfileEditor({ mode, profileId, bots, onSave, onCancel, onDelete }) {
655
666
  const list = Array.isArray(data) ? data : [];
656
667
  const profile = list.find((p) => p.id === profileId);
657
668
  if (!profile) {
658
- toast("Profile not found", { type: "error" });
669
+ (0, import_plugin_ui_kit.toast)("Profile not found", { type: "error" });
659
670
  onCancel();
660
671
  return;
661
672
  }
@@ -711,7 +722,7 @@ function ProfileEditor({ mode, profileId, bots, onSave, onCancel, onDelete }) {
711
722
  setPreset(strat);
712
723
  }
713
724
  } catch {
714
- toast("Failed to load profile", { type: "error" });
725
+ (0, import_plugin_ui_kit.toast)("Failed to load profile", { type: "error" });
715
726
  onCancel();
716
727
  } finally {
717
728
  if (!cancelled) setLoading(false);
@@ -721,7 +732,7 @@ function ProfileEditor({ mode, profileId, bots, onSave, onCancel, onDelete }) {
721
732
  cancelled = true;
722
733
  };
723
734
  }, [mode, profileId, callTool, onCancel]);
724
- const handleAddCapability = useCallback(() => {
735
+ const handleAddCapability = (0, import_react.useCallback)(() => {
725
736
  const trimName = capName.trim();
726
737
  const trimDesc = capDescription.trim();
727
738
  if (!trimName || !trimDesc) return;
@@ -729,17 +740,17 @@ function ProfileEditor({ mode, profileId, bots, onSave, onCancel, onDelete }) {
729
740
  setCapName("");
730
741
  setCapDescription("");
731
742
  }, [capName, capDescription]);
732
- const handleRemoveCapability = useCallback((index) => {
743
+ const handleRemoveCapability = (0, import_react.useCallback)((index) => {
733
744
  setCapabilities((prev) => prev.filter((_, i) => i !== index));
734
745
  }, []);
735
- const handleToggleKnowledgeCap = useCallback((capName2) => {
746
+ const handleToggleKnowledgeCap = (0, import_react.useCallback)((capName2) => {
736
747
  setKnowledgeCaps((prev) => {
737
748
  if (capName2 === "core") return prev;
738
749
  return prev.includes(capName2) ? prev.filter((n) => n !== capName2) : [...prev, capName2];
739
750
  });
740
751
  setPreset("custom");
741
752
  }, []);
742
- const handleAddScopePath = useCallback((type) => {
753
+ const handleAddScopePath = (0, import_react.useCallback)((type) => {
743
754
  const input = type === "blocked" ? blockedInput : allowedInput;
744
755
  const trimmed = input.trim();
745
756
  if (!trimmed) return;
@@ -751,24 +762,24 @@ function ProfileEditor({ mode, profileId, bots, onSave, onCancel, onDelete }) {
751
762
  else setAllowedInput("");
752
763
  setPreset("custom");
753
764
  }, [blockedInput, allowedInput]);
754
- const handleRemoveScopePath = useCallback((type, index) => {
765
+ const handleRemoveScopePath = (0, import_react.useCallback)((type, index) => {
755
766
  setBehavior((prev) => ({
756
767
  ...prev,
757
768
  [type === "blocked" ? "blockedPaths" : "allowedPaths"]: (type === "blocked" ? prev.blockedPaths : prev.allowedPaths).filter((_, i) => i !== index)
758
769
  }));
759
770
  setPreset("custom");
760
771
  }, []);
761
- const handleSave = useCallback(async () => {
772
+ const handleSave = (0, import_react.useCallback)(async () => {
762
773
  if (!name.trim()) {
763
- toast("Profile name is required", { type: "error" });
774
+ (0, import_plugin_ui_kit.toast)("Profile name is required", { type: "error" });
764
775
  return;
765
776
  }
766
777
  if (!botId) {
767
- toast("Select a bot workflow", { type: "error" });
778
+ (0, import_plugin_ui_kit.toast)("Select a bot workflow", { type: "error" });
768
779
  return;
769
780
  }
770
781
  if (capabilities.length === 0) {
771
- toast("Add at least one capability", { type: "error" });
782
+ (0, import_plugin_ui_kit.toast)("Add at least one capability", { type: "error" });
772
783
  return;
773
784
  }
774
785
  const NON_PHASE_KEYS = /* @__PURE__ */ new Set(["maxAttempts", "onExhausted", "blockedPaths", "allowedPaths"]);
@@ -806,7 +817,7 @@ function ProfileEditor({ mode, profileId, bots, onSave, onCancel, onDelete }) {
806
817
  requireApproval,
807
818
  behavior: behaviorPayload
808
819
  });
809
- toast("Profile created", { type: "success" });
820
+ (0, import_plugin_ui_kit.toast)("Profile created", { type: "success" });
810
821
  } else {
811
822
  await callTool("fw_weaver_profile_update", {
812
823
  id: profileId,
@@ -820,14 +831,14 @@ function ProfileEditor({ mode, profileId, bots, onSave, onCancel, onDelete }) {
820
831
  requireApproval,
821
832
  behavior: behaviorPayload
822
833
  });
823
- toast("Profile updated", { type: "success" });
834
+ (0, import_plugin_ui_kit.toast)("Profile updated", { type: "success" });
824
835
  }
825
836
  onSave();
826
837
  } catch (err) {
827
- toast(err instanceof Error ? err.message : `Failed to ${mode} profile`, { type: "error" });
838
+ (0, import_plugin_ui_kit.toast)(err instanceof Error ? err.message : `Failed to ${mode} profile`, { type: "error" });
828
839
  }
829
840
  }, [mode, profileId, name, description, botId, icon, color, costStrategy, capabilities, knowledgeCaps, budget, instructions, requireApproval, behavior, callTool, onSave]);
830
- const handleDelete = useCallback(async () => {
841
+ const handleDelete = (0, import_react.useCallback)(async () => {
831
842
  if (!profileId) return;
832
843
  const ok = await ctx.confirm("Are you sure you want to delete this profile?", {
833
844
  title: "Delete Profile",
@@ -837,527 +848,473 @@ function ProfileEditor({ mode, profileId, bots, onSave, onCancel, onDelete }) {
837
848
  if (!ok) return;
838
849
  try {
839
850
  await callTool("fw_weaver_profile_delete", { id: profileId });
840
- toast("Profile deleted", { type: "success" });
851
+ (0, import_plugin_ui_kit.toast)("Profile deleted", { type: "success" });
841
852
  if (onDelete) onDelete();
842
853
  } catch (err) {
843
- toast(err instanceof Error ? err.message : "Failed to delete profile", { type: "error" });
854
+ (0, import_plugin_ui_kit.toast)(err instanceof Error ? err.message : "Failed to delete profile", { type: "error" });
844
855
  }
845
856
  }, [profileId, callTool, onDelete, ctx]);
846
857
  if (loading) {
847
- return React.createElement(
848
- Flex,
858
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
859
+ import_plugin_ui_kit.Flex,
849
860
  {
850
861
  variant: "column-center-center-nowrap-12",
851
- style: { padding: "24px 16px" }
852
- },
853
- React.createElement(Typography, { variant: "caption-regular", color: "color-text-subtle" }, "Loading profile...")
862
+ style: { padding: "24px 16px" },
863
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Typography, { variant: "caption-regular", color: "color-text-subtle", children: "Loading profile..." })
864
+ }
854
865
  );
855
866
  }
856
867
  const phaseRow = (phaseName, label, isLlmPhase) => {
857
868
  const phase = behavior[phaseName];
858
869
  const currentTier = phase.tier ?? "standard";
859
870
  const ro = !isCustom;
860
- return React.createElement(
861
- Flex,
871
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
872
+ import_plugin_ui_kit.Flex,
862
873
  {
863
- key: phaseName,
864
874
  variant: "row-center-space-between-nowrap-8",
865
- style: { minHeight: 30, padding: "2px 0" }
875
+ style: { minHeight: 30, padding: "2px 0" },
876
+ children: [
877
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-start-nowrap-8", style: { minWidth: 100 }, children: [
878
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
879
+ import_plugin_ui_kit.Switch,
880
+ {
881
+ checked: phase.enabled,
882
+ size: "small",
883
+ readOnly: ro,
884
+ onChange: ro ? void 0 : (v) => updatePhase(phaseName, "enabled", v)
885
+ }
886
+ ),
887
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
888
+ import_plugin_ui_kit.Typography,
889
+ {
890
+ variant: "smallCaption-regular",
891
+ color: phase.enabled ? "color-text-high" : "color-text-subtle",
892
+ children: label
893
+ }
894
+ )
895
+ ] }),
896
+ isLlmPhase && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
897
+ import_plugin_ui_kit.ToggleGroup,
898
+ {
899
+ options: [
900
+ { label: "Fast", value: "fast", icon: "speed", selected: currentTier === "fast", disabled: !phase.enabled },
901
+ { label: "Mid", value: "standard", icon: "balance", selected: currentTier === "standard", disabled: !phase.enabled },
902
+ { label: "Smart", value: "powerful", icon: "psychology", selected: currentTier === "powerful", disabled: !phase.enabled }
903
+ ],
904
+ onSelect: (v) => updatePhase(phaseName, "tier", v),
905
+ readOnly: ro,
906
+ size: "tiny"
907
+ }
908
+ )
909
+ ]
866
910
  },
867
- React.createElement(
868
- Flex,
869
- { variant: "row-center-start-nowrap-8", style: { minWidth: 100 } },
870
- React.createElement(Switch, {
871
- checked: phase.enabled,
872
- size: "small",
873
- readOnly: ro,
874
- onChange: ro ? void 0 : (v) => updatePhase(phaseName, "enabled", v)
875
- }),
876
- React.createElement(Typography, {
877
- variant: "smallCaption-regular",
878
- color: phase.enabled ? "color-text-high" : "color-text-subtle"
879
- }, label)
880
- ),
881
- isLlmPhase && React.createElement(ToggleGroup, {
882
- options: [
883
- { label: "Fast", value: "fast", icon: "speed", selected: currentTier === "fast", disabled: !phase.enabled },
884
- { label: "Mid", value: "standard", icon: "balance", selected: currentTier === "standard", disabled: !phase.enabled },
885
- { label: "Smart", value: "powerful", icon: "psychology", selected: currentTier === "powerful", disabled: !phase.enabled }
886
- ],
887
- onSelect: (v) => updatePhase(phaseName, "tier", v),
888
- readOnly: ro,
889
- size: "tiny"
890
- })
911
+ phaseName
891
912
  );
892
913
  };
893
- return React.createElement(
894
- Flex,
914
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
915
+ import_plugin_ui_kit.Flex,
895
916
  {
896
917
  variant: "column-stretch-start-nowrap-0",
897
- style: { width: "100%", height: "100%", overflow: "hidden" }
898
- },
899
- // ── Header bar ──
900
- React.createElement(
901
- Flex,
902
- {
903
- variant: "row-center-space-between-nowrap-8",
904
- style: { padding: "8px 16px", flexShrink: 0, borderBottom: "1px solid var(--color-border-default)" }
905
- },
906
- React.createElement(
907
- Flex,
908
- { variant: "row-center-start-nowrap-8" },
909
- React.createElement(IconButton, {
910
- icon: "back",
911
- size: "xs",
912
- variant: "clear",
913
- onClick: onCancel,
914
- title: "Back"
915
- }),
916
- React.createElement(
917
- Typography,
918
- { variant: "caption-thick", color: "color-text-high" },
919
- mode === "create" ? "Create Profile" : "Edit Profile"
920
- )
921
- ),
922
- mode === "edit" && onDelete && React.createElement(IconButton, {
923
- icon: "outlinedDelete",
924
- size: "sm",
925
- variant: "clear",
926
- color: "danger",
927
- onClick: handleDelete,
928
- title: "Delete profile"
929
- })
930
- ),
931
- // ── Scrollable form body ──
932
- React.createElement(
933
- ScrollArea,
934
- {
935
- style: { flex: 1, minHeight: 0 }
936
- },
937
- React.createElement(
938
- Flex,
939
- {
940
- variant: "column-stretch-start-nowrap-10",
941
- style: { padding: "12px 16px" }
942
- },
943
- // ── Name ──
944
- React.createElement(
945
- Field,
946
- { label: "Name" },
947
- React.createElement(Input, {
948
- type: "text",
949
- size: "small",
950
- placeholder: "Profile name",
951
- value: name,
952
- onChange: (v) => setName(v),
953
- defaultBoxStyle: { flex: 1, minWidth: 0 },
954
- inputBoxStyle: { maxWidth: "none" }
955
- })
956
- ),
957
- // ── Description ──
958
- React.createElement(
959
- Field,
960
- { label: "Description" },
961
- React.createElement(Input, {
962
- type: "text",
963
- size: "small",
964
- placeholder: "What does this profile do?",
965
- value: description,
966
- onChange: (v) => setDescription(v),
967
- defaultBoxStyle: { flex: 1, minWidth: 0 },
968
- inputBoxStyle: { maxWidth: "none" }
969
- })
970
- ),
971
- // ── Bot ──
972
- React.createElement(
973
- Field,
974
- { label: "Bot" },
975
- React.createElement(Input, {
976
- type: "select",
977
- size: "small",
978
- options: bots.map((b) => ({ id: b.id, label: b.name, icon: b.icon || "smartToy" })),
979
- optionId: botId,
980
- onChange: (id) => setBotId(id),
981
- disabled: mode === "edit",
982
- placeholder: "Select bot",
983
- defaultBoxStyle: { flex: 1, minWidth: 0 }
984
- })
985
- ),
986
- // ── Icon ──
987
- React.createElement(
988
- Field,
989
- { label: "Icon", align: "start" },
990
- React.createElement(IconPicker, {
991
- catalog: ICON_CATALOG,
992
- value: icon,
993
- onChange: (v) => setIcon(v),
994
- accentColor: color,
995
- variant: "inline"
996
- })
997
- ),
998
- // ── Color ──
999
- React.createElement(
1000
- Field,
1001
- { label: "Color", align: "start" },
1002
- React.createElement(ColorPicker, {
1003
- colors: BOT_COLORS,
1004
- value: color,
1005
- onChange: (v) => setColor(v),
1006
- variant: "inline"
1007
- })
1008
- ),
1009
- // ── Preset (ToggleGroup with Custom option) ──
1010
- React.createElement(
1011
- Field,
1012
- { label: "Preset", align: "start" },
1013
- React.createElement(ToggleGroup, {
1014
- options: [
1015
- { label: "Fast", value: "frugal", icon: "speed", selected: preset === "frugal" },
1016
- { label: "Mid", value: "balanced", icon: "balance", selected: preset === "balanced" },
1017
- { label: "Smart", value: "performance", icon: "psychology", selected: preset === "performance" },
1018
- { label: "Custom", value: "custom", icon: "settings", selected: preset === "custom" }
1019
- ],
1020
- onSelect: handlePresetChange,
1021
- size: "extraSmall"
1022
- })
918
+ style: { width: "100%", height: "100%", overflow: "hidden" },
919
+ children: [
920
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
921
+ import_plugin_ui_kit.Flex,
922
+ {
923
+ variant: "row-center-space-between-nowrap-8",
924
+ style: { padding: "8px 16px", flexShrink: 0, borderBottom: "1px solid var(--color-border-default)" },
925
+ children: [
926
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-start-nowrap-8", children: [
927
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
928
+ import_plugin_ui_kit.IconButton,
929
+ {
930
+ icon: "back",
931
+ size: "xs",
932
+ variant: "clear",
933
+ onClick: onCancel,
934
+ title: "Back"
935
+ }
936
+ ),
937
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Typography, { variant: "caption-thick", color: "color-text-high", children: mode === "create" ? "Create Profile" : "Edit Profile" })
938
+ ] }),
939
+ mode === "edit" && onDelete && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
940
+ import_plugin_ui_kit.IconButton,
941
+ {
942
+ icon: "outlinedDelete",
943
+ size: "sm",
944
+ variant: "clear",
945
+ color: "danger",
946
+ onClick: handleDelete,
947
+ title: "Delete profile"
948
+ }
949
+ )
950
+ ]
951
+ }
1023
952
  ),
1024
- // ── Knowledge Capabilities (checkbox grid) ──
1025
- React.createElement(
1026
- Field,
1027
- { label: "Knowledge", align: "start" },
1028
- React.createElement(
1029
- Flex,
1030
- { variant: "column-stretch-start-nowrap-2" },
1031
- ...BUILT_IN_CAPABILITIES.map(
1032
- (cap) => React.createElement(
1033
- Flex,
953
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.ScrollArea, { style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
954
+ import_plugin_ui_kit.Flex,
955
+ {
956
+ variant: "column-stretch-start-nowrap-10",
957
+ style: { padding: "12px 16px" },
958
+ children: [
959
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
960
+ import_plugin_ui_kit.Input,
961
+ {
962
+ type: "text",
963
+ size: "small",
964
+ placeholder: "Profile name",
965
+ value: name,
966
+ onChange: (v) => setName(v),
967
+ defaultBoxStyle: { flex: 1, minWidth: 0 },
968
+ inputBoxStyle: { maxWidth: "none" }
969
+ }
970
+ ) }),
971
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Description", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
972
+ import_plugin_ui_kit.Input,
973
+ {
974
+ type: "text",
975
+ size: "small",
976
+ placeholder: "What does this profile do?",
977
+ value: description,
978
+ onChange: (v) => setDescription(v),
979
+ defaultBoxStyle: { flex: 1, minWidth: 0 },
980
+ inputBoxStyle: { maxWidth: "none" }
981
+ }
982
+ ) }),
983
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Bot", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
984
+ import_plugin_ui_kit.Input,
985
+ {
986
+ type: "select",
987
+ size: "small",
988
+ options: bots.map((b) => ({ id: b.id, label: b.name, icon: b.icon || "smartToy" })),
989
+ optionId: botId,
990
+ onChange: (id) => setBotId(id),
991
+ disabled: mode === "edit",
992
+ placeholder: "Select bot",
993
+ defaultBoxStyle: { flex: 1, minWidth: 0 }
994
+ }
995
+ ) }),
996
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Icon", align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
997
+ import_plugin_ui_kit.IconPicker,
998
+ {
999
+ catalog: ICON_CATALOG,
1000
+ value: icon,
1001
+ onChange: (v) => setIcon(v),
1002
+ accentColor: color,
1003
+ variant: "inline"
1004
+ }
1005
+ ) }),
1006
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Color", align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1007
+ import_plugin_ui_kit.ColorPicker,
1008
+ {
1009
+ colors: BOT_COLORS,
1010
+ value: color,
1011
+ onChange: (v) => setColor(v),
1012
+ variant: "inline"
1013
+ }
1014
+ ) }),
1015
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Preset", align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1016
+ import_plugin_ui_kit.ToggleGroup,
1017
+ {
1018
+ options: [
1019
+ { label: "Fast", value: "frugal", icon: "speed", selected: preset === "frugal" },
1020
+ { label: "Mid", value: "balanced", icon: "balance", selected: preset === "balanced" },
1021
+ { label: "Smart", value: "performance", icon: "psychology", selected: preset === "performance" },
1022
+ { label: "Custom", value: "custom", icon: "settings", selected: preset === "custom" }
1023
+ ],
1024
+ onSelect: handlePresetChange,
1025
+ size: "extraSmall"
1026
+ }
1027
+ ) }),
1028
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Capabilities", align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Flex, { variant: "column-stretch-start-nowrap-2", children: BUILT_IN_CAPABILITIES.map((cap) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1029
+ import_plugin_ui_kit.Flex,
1034
1030
  {
1035
- key: cap.name,
1036
1031
  variant: "row-center-start-nowrap-8",
1037
- style: { minHeight: 28, padding: "1px 0" }
1032
+ style: { minHeight: 28, padding: "1px 0" },
1033
+ children: [
1034
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1035
+ import_plugin_ui_kit.Checkbox,
1036
+ {
1037
+ checked: knowledgeCaps.includes(cap.name),
1038
+ onChange: () => handleToggleKnowledgeCap(cap.name),
1039
+ disabled: cap.name === "core" || !isCustom,
1040
+ size: "sm"
1041
+ }
1042
+ ),
1043
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1044
+ import_plugin_ui_kit.Typography,
1045
+ {
1046
+ variant: "smallCaption-thick",
1047
+ color: knowledgeCaps.includes(cap.name) ? "color-text-high" : "color-text-subtle",
1048
+ style: { minWidth: 80 },
1049
+ children: cap.name
1050
+ }
1051
+ ),
1052
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1053
+ import_plugin_ui_kit.Typography,
1054
+ {
1055
+ variant: "smallCaption-regular",
1056
+ color: "color-text-subtle",
1057
+ style: { flex: 1 },
1058
+ children: cap.description
1059
+ }
1060
+ )
1061
+ ]
1038
1062
  },
1039
- React.createElement(Checkbox, {
1040
- checked: knowledgeCaps.includes(cap.name),
1041
- onChange: () => handleToggleKnowledgeCap(cap.name),
1042
- disabled: cap.name === "core" || !isCustom,
1043
- size: "sm"
1044
- }),
1045
- React.createElement(Typography, {
1046
- variant: "smallCaption-thick",
1047
- color: knowledgeCaps.includes(cap.name) ? "color-text-high" : "color-text-subtle",
1048
- style: { minWidth: 80 }
1049
- }, cap.name),
1050
- React.createElement(Typography, {
1051
- variant: "smallCaption-regular",
1052
- color: "color-text-subtle",
1053
- style: { flex: 1 }
1054
- }, cap.description)
1055
- )
1056
- )
1057
- )
1058
- ),
1059
- // ── Budget ──
1060
- React.createElement(
1061
- Field,
1062
- { label: "Budget", align: "center" },
1063
- React.createElement(
1064
- Flex,
1065
- { variant: "row-center-start-nowrap-6" },
1066
- React.createElement(Typography, {
1067
- variant: "smallCaption-regular",
1068
- color: "color-text-subtle"
1069
- }, "$"),
1070
- React.createElement(Input, {
1071
- type: "number",
1072
- size: "small",
1073
- value: String(budget),
1074
- readOnly: !isCustom,
1075
- onChange: isCustom ? (v) => {
1076
- const n = parseFloat(v);
1077
- if (!isNaN(n) && n >= 0) setBudget(n);
1078
- } : void 0,
1079
- defaultBoxStyle: { width: 80 }
1080
- }),
1081
- React.createElement(Typography, {
1082
- variant: "smallCaption-regular",
1083
- color: "color-text-subtle"
1084
- }, "/ task")
1085
- )
1086
- ),
1087
- // ── Phase Configuration (always visible, readOnly when preset) ──
1088
- React.createElement(
1089
- Field,
1090
- { label: "Phases", align: "start" },
1091
- React.createElement(
1092
- Flex,
1093
- {
1094
- variant: "column-stretch-start-nowrap-6"
1095
- },
1096
- ...Object.entries(behavior).filter(([k]) => !["maxAttempts", "onExhausted", "blockedPaths", "allowedPaths"].includes(k)).map(([phaseName, phase]) => {
1097
- const phaseObj = phase;
1098
- const isLlm = phaseObj.tier !== void 0;
1099
- const label = phaseName.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
1100
- return phaseRow(phaseName, label, isLlm);
1101
- })
1102
- )
1103
- ),
1104
- // ── Escalation (always visible, readOnly when preset) ──
1105
- React.createElement(
1106
- Field,
1107
- { label: "Retries", align: "start" },
1108
- React.createElement(
1109
- Flex,
1110
- {
1111
- variant: "column-stretch-start-nowrap-8"
1112
- },
1113
- React.createElement(
1114
- Field,
1115
- { label: "Max attempts", labelWidth: 100, align: "center" },
1116
- React.createElement(Input, {
1117
- type: "number",
1118
- size: "small",
1119
- value: String(behavior.maxAttempts),
1120
- readOnly: !isCustom,
1121
- onChange: isCustom ? (v) => updateEscalation("maxAttempts", Math.max(1, parseInt(v) || 1)) : void 0,
1122
- defaultBoxStyle: { width: 60 }
1123
- })
1124
- ),
1125
- React.createElement(
1126
- Field,
1127
- { label: "On exhausted", labelWidth: 100, align: "start" },
1128
- React.createElement(ToggleGroup, {
1129
- options: [
1130
- { label: "Block", value: "block", icon: "block", selected: behavior.onExhausted === "block" },
1131
- { label: "Reassign", value: "reassign", icon: "sync", selected: behavior.onExhausted === "reassign" },
1132
- { label: "Notify", value: "notify", icon: "notifications", selected: behavior.onExhausted === "notify" }
1133
- ],
1134
- onSelect: (v) => updateEscalation("onExhausted", v),
1135
- readOnly: !isCustom,
1136
- size: "extraSmall"
1137
- })
1138
- )
1139
- )
1140
- ),
1141
- // ── Scope Constraints (collapsible) ──
1142
- // ── Custom: Scope Constraints (inline) ──
1143
- isCustom && React.createElement(
1144
- Field,
1145
- { label: "Scope", align: "start" },
1146
- React.createElement(
1147
- Flex,
1148
- {
1149
- variant: "column-stretch-start-nowrap-8"
1150
- },
1151
- // Blocked paths
1152
- React.createElement(
1153
- Field,
1154
- { label: "Blocked", labelWidth: 70, align: "start" },
1155
- React.createElement(
1156
- Flex,
1157
- { variant: "column-stretch-start-nowrap-4" },
1158
- React.createElement(
1159
- Flex,
1160
- { variant: "row-center-start-nowrap-4" },
1161
- React.createElement(Input, {
1162
- type: "text",
1063
+ cap.name
1064
+ )) }) }),
1065
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Budget", align: "center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-start-nowrap-6", children: [
1066
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Typography, { variant: "smallCaption-regular", color: "color-text-subtle", children: "$" }),
1067
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1068
+ import_plugin_ui_kit.Input,
1069
+ {
1070
+ type: "number",
1163
1071
  size: "small",
1164
- placeholder: "e.g. src/",
1165
- value: blockedInput,
1166
- onChange: (v) => setBlockedInput(v),
1167
- onEnter: () => handleAddScopePath("blocked"),
1168
- defaultBoxStyle: { flex: 1, minWidth: 0 },
1169
- inputBoxStyle: { maxWidth: "none" }
1170
- }),
1171
- React.createElement(IconButton, {
1172
- icon: "add",
1173
- size: "sm",
1174
- variant: "outlined",
1175
- color: "primary",
1176
- onClick: () => handleAddScopePath("blocked"),
1177
- disabled: !blockedInput.trim()
1178
- })
1072
+ value: String(budget),
1073
+ readOnly: !isCustom,
1074
+ onChange: isCustom ? (v) => {
1075
+ const n = parseFloat(v);
1076
+ if (!isNaN(n) && n >= 0) setBudget(n);
1077
+ } : void 0,
1078
+ defaultBoxStyle: { width: 80 }
1079
+ }
1179
1080
  ),
1180
- ...behavior.blockedPaths.map(
1181
- (p, i) => React.createElement(
1182
- Flex,
1183
- { key: `b-${p}-${i}`, variant: "row-center-start-nowrap-6" },
1184
- React.createElement(Icon, { name: "block", size: 12, color: "color-status-negative" }),
1185
- React.createElement(Typography, { variant: "smallCaption-regular", color: "color-text-high", style: { flex: 1 } }, p),
1186
- React.createElement(IconButton, {
1187
- icon: "close",
1188
- size: "xs",
1189
- variant: "clear",
1190
- color: "danger",
1191
- onClick: () => handleRemoveScopePath("blocked", i)
1192
- })
1193
- )
1194
- )
1195
- )
1196
- ),
1197
- // Allowed paths
1198
- React.createElement(
1199
- Field,
1200
- { label: "Allowed", labelWidth: 70, align: "start" },
1201
- React.createElement(
1202
- Flex,
1203
- { variant: "column-stretch-start-nowrap-4" },
1204
- React.createElement(
1205
- Flex,
1206
- { variant: "row-center-start-nowrap-4" },
1207
- React.createElement(Input, {
1208
- type: "text",
1081
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Typography, { variant: "smallCaption-regular", color: "color-text-subtle", children: "/ task" })
1082
+ ] }) }),
1083
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Phases", align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Flex, { variant: "column-stretch-start-nowrap-6", children: Object.entries(behavior).filter(([k]) => !["maxAttempts", "onExhausted", "blockedPaths", "allowedPaths"].includes(k)).map(([phaseName, phase]) => {
1084
+ const phaseObj = phase;
1085
+ const isLlm = phaseObj.tier !== void 0;
1086
+ const label = phaseName.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
1087
+ return phaseRow(phaseName, label, isLlm);
1088
+ }) }) }),
1089
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Retries", align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "column-stretch-start-nowrap-8", children: [
1090
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Max attempts", labelWidth: 100, align: "center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1091
+ import_plugin_ui_kit.Input,
1092
+ {
1093
+ type: "number",
1209
1094
  size: "small",
1210
- placeholder: "e.g. config/",
1211
- value: allowedInput,
1212
- onChange: (v) => setAllowedInput(v),
1213
- onEnter: () => handleAddScopePath("allowed"),
1214
- defaultBoxStyle: { flex: 1, minWidth: 0 },
1215
- inputBoxStyle: { maxWidth: "none" }
1216
- }),
1217
- React.createElement(IconButton, {
1218
- icon: "add",
1219
- size: "sm",
1220
- variant: "outlined",
1221
- color: "primary",
1222
- onClick: () => handleAddScopePath("allowed"),
1223
- disabled: !allowedInput.trim()
1224
- })
1225
- ),
1226
- ...behavior.allowedPaths.map(
1227
- (p, i) => React.createElement(
1228
- Flex,
1229
- { key: `a-${p}-${i}`, variant: "row-center-start-nowrap-6" },
1230
- React.createElement(Icon, { name: "checkCircle", size: 12, color: "color-status-positive" }),
1231
- React.createElement(Typography, { variant: "smallCaption-regular", color: "color-text-high", style: { flex: 1 } }, p),
1232
- React.createElement(IconButton, {
1233
- icon: "close",
1234
- size: "xs",
1235
- variant: "clear",
1236
- color: "danger",
1237
- onClick: () => handleRemoveScopePath("allowed", i)
1238
- })
1095
+ value: String(behavior.maxAttempts),
1096
+ readOnly: !isCustom,
1097
+ onChange: isCustom ? (v) => updateEscalation("maxAttempts", Math.max(1, parseInt(v) || 1)) : void 0,
1098
+ defaultBoxStyle: { width: 60 }
1099
+ }
1100
+ ) }),
1101
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "On exhausted", labelWidth: 100, align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1102
+ import_plugin_ui_kit.ToggleGroup,
1103
+ {
1104
+ options: [
1105
+ { label: "Block", value: "block", icon: "block", selected: behavior.onExhausted === "block" },
1106
+ { label: "Reassign", value: "reassign", icon: "sync", selected: behavior.onExhausted === "reassign" },
1107
+ { label: "Notify", value: "notify", icon: "notifications", selected: behavior.onExhausted === "notify" }
1108
+ ],
1109
+ onSelect: (v) => updateEscalation("onExhausted", v),
1110
+ readOnly: !isCustom,
1111
+ size: "extraSmall"
1112
+ }
1113
+ ) })
1114
+ ] }) }),
1115
+ isCustom && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Scope", align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "column-stretch-start-nowrap-8", children: [
1116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Blocked", labelWidth: 70, align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "column-stretch-start-nowrap-4", children: [
1117
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-start-nowrap-4", children: [
1118
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1119
+ import_plugin_ui_kit.Input,
1120
+ {
1121
+ type: "text",
1122
+ size: "small",
1123
+ placeholder: "e.g. src/",
1124
+ value: blockedInput,
1125
+ onChange: (v) => setBlockedInput(v),
1126
+ onEnter: () => handleAddScopePath("blocked"),
1127
+ defaultBoxStyle: { flex: 1, minWidth: 0 },
1128
+ inputBoxStyle: { maxWidth: "none" }
1129
+ }
1130
+ ),
1131
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1132
+ import_plugin_ui_kit.IconButton,
1133
+ {
1134
+ icon: "add",
1135
+ size: "sm",
1136
+ variant: "outlined",
1137
+ color: "primary",
1138
+ onClick: () => handleAddScopePath("blocked"),
1139
+ disabled: !blockedInput.trim()
1140
+ }
1141
+ )
1142
+ ] }),
1143
+ behavior.blockedPaths.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-start-nowrap-6", children: [
1144
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Icon, { name: "block", size: 12, color: "color-status-negative" }),
1145
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Typography, { variant: "smallCaption-regular", color: "color-text-high", style: { flex: 1 }, children: p }),
1146
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1147
+ import_plugin_ui_kit.IconButton,
1148
+ {
1149
+ icon: "close",
1150
+ size: "xs",
1151
+ variant: "clear",
1152
+ color: "danger",
1153
+ onClick: () => handleRemoveScopePath("blocked", i)
1154
+ }
1155
+ )
1156
+ ] }, `b-${p}-${i}`))
1157
+ ] }) }),
1158
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Allowed", labelWidth: 70, align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "column-stretch-start-nowrap-4", children: [
1159
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-start-nowrap-4", children: [
1160
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1161
+ import_plugin_ui_kit.Input,
1162
+ {
1163
+ type: "text",
1164
+ size: "small",
1165
+ placeholder: "e.g. config/",
1166
+ value: allowedInput,
1167
+ onChange: (v) => setAllowedInput(v),
1168
+ onEnter: () => handleAddScopePath("allowed"),
1169
+ defaultBoxStyle: { flex: 1, minWidth: 0 },
1170
+ inputBoxStyle: { maxWidth: "none" }
1171
+ }
1172
+ ),
1173
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1174
+ import_plugin_ui_kit.IconButton,
1175
+ {
1176
+ icon: "add",
1177
+ size: "sm",
1178
+ variant: "outlined",
1179
+ color: "primary",
1180
+ onClick: () => handleAddScopePath("allowed"),
1181
+ disabled: !allowedInput.trim()
1182
+ }
1183
+ )
1184
+ ] }),
1185
+ behavior.allowedPaths.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-start-nowrap-6", children: [
1186
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Icon, { name: "checkCircle", size: 12, color: "color-status-positive" }),
1187
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Typography, { variant: "smallCaption-regular", color: "color-text-high", style: { flex: 1 }, children: p }),
1188
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1189
+ import_plugin_ui_kit.IconButton,
1190
+ {
1191
+ icon: "close",
1192
+ size: "xs",
1193
+ variant: "clear",
1194
+ color: "danger",
1195
+ onClick: () => handleRemoveScopePath("allowed", i)
1196
+ }
1197
+ )
1198
+ ] }, `a-${p}-${i}`))
1199
+ ] }) })
1200
+ ] }) }),
1201
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Capabilities", align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "column-stretch-start-nowrap-6", children: [
1202
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-start-nowrap-4", style: { minWidth: 0 }, children: [
1203
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1204
+ import_plugin_ui_kit.Input,
1205
+ {
1206
+ type: "text",
1207
+ size: "small",
1208
+ placeholder: "Name",
1209
+ value: capName,
1210
+ onChange: (v) => setCapName(v),
1211
+ defaultBoxStyle: { flex: "0 1 120px", minWidth: 0 },
1212
+ inputBoxStyle: { maxWidth: "none", minWidth: 0 }
1213
+ }
1214
+ ),
1215
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1216
+ import_plugin_ui_kit.Input,
1217
+ {
1218
+ type: "text",
1219
+ size: "small",
1220
+ placeholder: "Description",
1221
+ value: capDescription,
1222
+ onChange: (v) => setCapDescription(v),
1223
+ onEnter: handleAddCapability,
1224
+ defaultBoxStyle: { flex: "1 1 0", minWidth: 0 },
1225
+ inputBoxStyle: { maxWidth: "none", minWidth: 0 }
1226
+ }
1227
+ ),
1228
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1229
+ import_plugin_ui_kit.IconButton,
1230
+ {
1231
+ icon: "add",
1232
+ size: "sm",
1233
+ variant: "outlined",
1234
+ color: "primary",
1235
+ onClick: handleAddCapability,
1236
+ disabled: !capName.trim() || !capDescription.trim(),
1237
+ style: { flexShrink: 0 }
1238
+ }
1239
1239
  )
1240
+ ] }),
1241
+ capabilities.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1242
+ import_plugin_ui_kit.Table,
1243
+ {
1244
+ size: "compact",
1245
+ showHeader: false,
1246
+ data: capabilities,
1247
+ getRowKey: (_row, i) => `cap-${i}`,
1248
+ columns: [
1249
+ {
1250
+ key: "name",
1251
+ header: "Name",
1252
+ width: "30%",
1253
+ render: (val) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { lineHeight: "28px" }, children: String(val) })
1254
+ },
1255
+ {
1256
+ key: "description",
1257
+ header: "Description",
1258
+ render: (val) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { lineHeight: "28px" }, children: String(val) })
1259
+ },
1260
+ {
1261
+ key: "actions",
1262
+ header: "",
1263
+ width: "32px",
1264
+ align: "right",
1265
+ render: (_val, _row, idx) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1266
+ import_plugin_ui_kit.IconButton,
1267
+ {
1268
+ icon: "close",
1269
+ size: "xs",
1270
+ variant: "clear",
1271
+ color: "danger",
1272
+ onClick: () => handleRemoveCapability(idx)
1273
+ }
1274
+ )
1275
+ }
1276
+ ]
1277
+ }
1240
1278
  )
1241
- )
1242
- )
1243
- )
1244
- ),
1245
- // ── Capabilities ──
1246
- React.createElement(
1247
- Field,
1248
- { label: "Capabilities", align: "start" },
1249
- React.createElement(
1250
- Flex,
1251
- { variant: "column-stretch-start-nowrap-6" },
1252
- // Add row
1253
- React.createElement(
1254
- Flex,
1255
- { variant: "row-center-start-nowrap-4", style: { minWidth: 0 } },
1256
- React.createElement(Input, {
1257
- type: "text",
1258
- size: "small",
1259
- placeholder: "Name",
1260
- value: capName,
1261
- onChange: (v) => setCapName(v),
1262
- defaultBoxStyle: { flex: "0 1 120px", minWidth: 0 },
1263
- inputBoxStyle: { maxWidth: "none", minWidth: 0 }
1264
- }),
1265
- React.createElement(Input, {
1266
- type: "text",
1267
- size: "small",
1268
- placeholder: "Description",
1269
- value: capDescription,
1270
- onChange: (v) => setCapDescription(v),
1271
- onEnter: handleAddCapability,
1272
- defaultBoxStyle: { flex: "1 1 0", minWidth: 0 },
1273
- inputBoxStyle: { maxWidth: "none", minWidth: 0 }
1274
- }),
1275
- React.createElement(IconButton, {
1276
- icon: "add",
1277
- size: "sm",
1278
- variant: "outlined",
1279
- color: "primary",
1280
- onClick: handleAddCapability,
1281
- disabled: !capName.trim() || !capDescription.trim(),
1282
- style: { flexShrink: 0 }
1283
- })
1284
- ),
1285
- // Table
1286
- capabilities.length > 0 && React.createElement(Table, {
1287
- size: "compact",
1288
- showHeader: false,
1289
- data: capabilities,
1290
- getRowKey: (_row, i) => `cap-${i}`,
1291
- columns: [
1279
+ ] }) }),
1280
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Instructions", align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1281
+ import_plugin_ui_kit.Input,
1292
1282
  {
1293
- key: "name",
1294
- header: "Name",
1295
- width: "30%",
1296
- render: (val) => React.createElement("div", { style: { lineHeight: "28px" } }, String(val))
1297
- },
1283
+ type: "text",
1284
+ size: "small",
1285
+ multiline: true,
1286
+ placeholder: "Behavioral protocol for this profile (optional)",
1287
+ value: instructions,
1288
+ onChange: (v) => setInstructions(v),
1289
+ defaultBoxStyle: { flex: 1, minWidth: 0 },
1290
+ inputBoxStyle: { maxWidth: "none" }
1291
+ }
1292
+ ) }),
1293
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1294
+ import_plugin_ui_kit.Checkbox,
1298
1295
  {
1299
- key: "description",
1300
- header: "Description",
1301
- render: (val) => React.createElement("div", { style: { lineHeight: "28px" } }, String(val))
1302
- },
1296
+ checked: requireApproval,
1297
+ onChange: (v) => setRequireApproval(v),
1298
+ label: "Require approval",
1299
+ size: "sm"
1300
+ }
1301
+ ) }),
1302
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Flex, { variant: "row-center-end-nowrap-8", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1303
+ import_plugin_ui_kit.Button,
1303
1304
  {
1304
- key: "actions",
1305
- header: "",
1306
- width: "32px",
1307
- align: "right",
1308
- render: (_val, _row, idx) => React.createElement(IconButton, {
1309
- icon: "close",
1310
- size: "xs",
1311
- variant: "clear",
1312
- color: "danger",
1313
- onClick: () => handleRemoveCapability(idx)
1314
- })
1305
+ size: "xs",
1306
+ variant: "fill",
1307
+ color: "primary",
1308
+ onClick: handleSave,
1309
+ disabled: !name.trim() || !botId || capabilities.length === 0,
1310
+ children: mode === "create" ? "Create" : "Save"
1315
1311
  }
1316
- ]
1317
- })
1318
- )
1319
- ),
1320
- // ── Instructions (multiline) ──
1321
- React.createElement(
1322
- Field,
1323
- { label: "Instructions", align: "start" },
1324
- React.createElement(Input, {
1325
- type: "text",
1326
- size: "small",
1327
- multiline: true,
1328
- placeholder: "Behavioral protocol for this profile (optional)",
1329
- value: instructions,
1330
- onChange: (v) => setInstructions(v),
1331
- defaultBoxStyle: { flex: 1, minWidth: 0 },
1332
- inputBoxStyle: { maxWidth: "none" }
1333
- })
1334
- ),
1335
- // ── Require Approval ──
1336
- React.createElement(
1337
- Field,
1338
- { label: "" },
1339
- React.createElement(Checkbox, {
1340
- checked: requireApproval,
1341
- onChange: (v) => setRequireApproval(v),
1342
- label: "Require approval",
1343
- size: "sm"
1344
- })
1345
- ),
1346
- // ── Save button ──
1347
- React.createElement(
1348
- Flex,
1349
- { variant: "row-center-end-nowrap-8" },
1350
- React.createElement(Button, {
1351
- size: "xs",
1352
- variant: "fill",
1353
- color: "primary",
1354
- onClick: handleSave,
1355
- disabled: !name.trim() || !botId || capabilities.length === 0
1356
- }, mode === "create" ? "Create" : "Save")
1357
- )
1358
- )
1359
- )
1312
+ ) })
1313
+ ]
1314
+ }
1315
+ ) })
1316
+ ]
1317
+ }
1360
1318
  );
1361
1319
  }
1362
1320
  var profile_editor_default = ProfileEditor;
1363
- module.exports = ProfileEditor;