@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.
- package/dist/ai-chat-provider.js +5 -5
- package/dist/ai-chat-provider.js.map +1 -1
- package/dist/bot/acceptance-merge.d.ts +21 -0
- package/dist/bot/acceptance-merge.d.ts.map +1 -0
- package/dist/bot/acceptance-merge.js +46 -0
- package/dist/bot/acceptance-merge.js.map +1 -0
- package/dist/bot/ai-client.d.ts +14 -2
- package/dist/bot/ai-client.d.ts.map +1 -1
- package/dist/bot/ai-client.js +71 -24
- package/dist/bot/ai-client.js.map +1 -1
- package/dist/bot/assistant-tools.js +3 -3
- package/dist/bot/assistant-tools.js.map +1 -1
- package/dist/bot/audit-logger.d.ts.map +1 -1
- package/dist/bot/audit-logger.js +34 -14
- package/dist/bot/audit-logger.js.map +1 -1
- package/dist/bot/audit-trail.d.ts +67 -0
- package/dist/bot/audit-trail.d.ts.map +1 -0
- package/dist/bot/audit-trail.js +153 -0
- package/dist/bot/audit-trail.js.map +1 -0
- package/dist/bot/behavior-defaults.d.ts +1 -1
- package/dist/bot/behavior-defaults.d.ts.map +1 -1
- package/dist/bot/behavior-defaults.js +7 -3
- package/dist/bot/behavior-defaults.js.map +1 -1
- package/dist/bot/capability-registry.d.ts +9 -0
- package/dist/bot/capability-registry.d.ts.map +1 -1
- package/dist/bot/capability-registry.js +81 -27
- package/dist/bot/capability-registry.js.map +1 -1
- package/dist/bot/capability-types.d.ts +10 -0
- package/dist/bot/capability-types.d.ts.map +1 -1
- package/dist/bot/cli-provider.d.ts.map +1 -1
- package/dist/bot/cli-provider.js +8 -7
- package/dist/bot/cli-provider.js.map +1 -1
- package/dist/bot/preflight.d.ts +48 -0
- package/dist/bot/preflight.d.ts.map +1 -0
- package/dist/bot/preflight.js +247 -0
- package/dist/bot/preflight.js.map +1 -0
- package/dist/bot/provider-shim.d.ts +74 -0
- package/dist/bot/provider-shim.d.ts.map +1 -0
- package/dist/bot/provider-shim.js +176 -0
- package/dist/bot/provider-shim.js.map +1 -0
- package/dist/bot/runner.d.ts +2 -0
- package/dist/bot/runner.d.ts.map +1 -1
- package/dist/bot/runner.js +60 -17
- package/dist/bot/runner.js.map +1 -1
- package/dist/bot/step-executor.d.ts.map +1 -1
- package/dist/bot/step-executor.js +72 -115
- package/dist/bot/step-executor.js.map +1 -1
- package/dist/bot/swarm-controller.d.ts +2 -0
- package/dist/bot/swarm-controller.d.ts.map +1 -1
- package/dist/bot/swarm-controller.js +92 -20
- package/dist/bot/swarm-controller.js.map +1 -1
- package/dist/bot/task-create-handler.d.ts +37 -0
- package/dist/bot/task-create-handler.d.ts.map +1 -0
- package/dist/bot/task-create-handler.js +124 -0
- package/dist/bot/task-create-handler.js.map +1 -0
- package/dist/bot/task-store.d.ts +1 -0
- package/dist/bot/task-store.d.ts.map +1 -1
- package/dist/bot/task-store.js +67 -0
- package/dist/bot/task-store.js.map +1 -1
- package/dist/bot/types.d.ts +1 -1
- package/dist/bot/types.d.ts.map +1 -1
- package/dist/bot/weaver-tools.d.ts.map +1 -1
- package/dist/bot/weaver-tools.js +7 -39
- package/dist/bot/weaver-tools.js.map +1 -1
- package/dist/node-types/agent-execute.d.ts +25 -8
- package/dist/node-types/agent-execute.d.ts.map +1 -1
- package/dist/node-types/agent-execute.js +89 -23
- package/dist/node-types/agent-execute.js.map +1 -1
- package/dist/node-types/bot-report.d.ts.map +1 -1
- package/dist/node-types/bot-report.js +24 -3
- package/dist/node-types/bot-report.js.map +1 -1
- package/dist/node-types/plan-task.d.ts +8 -17
- package/dist/node-types/plan-task.d.ts.map +1 -1
- package/dist/node-types/plan-task.js +217 -256
- package/dist/node-types/plan-task.js.map +1 -1
- package/dist/node-types/review-result.js +8 -6
- package/dist/node-types/review-result.js.map +1 -1
- package/dist/palindrome.d.ts +9 -0
- package/dist/palindrome.d.ts.map +1 -0
- package/dist/palindrome.js +14 -0
- package/dist/palindrome.js.map +1 -0
- package/dist/ui/approval-card.js +91 -82
- package/dist/ui/bot-activity.js +73 -56
- package/dist/ui/bot-config.js +48 -31
- package/dist/ui/bot-dashboard.js +52 -36
- package/dist/ui/bot-panel.js +230 -228
- package/dist/ui/bot-slot-card.js +100 -90
- package/dist/ui/bot-status.js +37 -15
- package/dist/ui/budget-bar.js +57 -31
- package/dist/ui/capability-editor.js +447 -378
- package/dist/ui/chat-task-result.js +78 -71
- package/dist/ui/decision-log.js +68 -81
- package/dist/ui/genesis-block.js +86 -95
- package/dist/ui/instance-stream-view.js +722 -0
- package/dist/ui/profile-card.js +96 -221
- package/dist/ui/profile-editor.js +532 -575
- package/dist/ui/settings-section.js +41 -45
- package/dist/ui/swarm-controls.js +212 -135
- package/dist/ui/swarm-dashboard.js +3992 -2715
- package/dist/ui/task-detail-view.js +415 -521
- package/dist/ui/task-editor.js +339 -390
- package/dist/ui/task-pool-list.js +60 -55
- package/dist/workflows/src/palindrome.d.ts +11 -0
- package/dist/workflows/src/palindrome.d.ts.map +1 -0
- package/dist/workflows/src/palindrome.js +16 -0
- package/dist/workflows/src/palindrome.js.map +1 -0
- package/dist/workflows/tests/palindrome.test.d.ts +2 -0
- package/dist/workflows/tests/palindrome.test.d.ts.map +1 -0
- package/dist/workflows/tests/palindrome.test.js +41 -0
- package/dist/workflows/tests/palindrome.test.js.map +1 -0
- package/dist/workflows/weaver-bot-batch.js +1 -1
- package/dist/workflows/weaver-bot-batch.js.map +1 -1
- package/dist/workflows/weaver-bot.js +1 -1
- package/dist/workflows/weaver-bot.js.map +1 -1
- package/flowweaver.manifest.json +1 -1
- package/package.json +8 -2
- package/src/ai-chat-provider.ts +5 -5
- package/src/bot/acceptance-merge.ts +62 -0
- package/src/bot/ai-client.ts +77 -21
- package/src/bot/assistant-tools.ts +3 -3
- package/src/bot/audit-logger.ts +42 -14
- package/src/bot/audit-trail.ts +211 -0
- package/src/bot/behavior-defaults.ts +7 -2
- package/src/bot/capability-registry.ts +84 -28
- package/src/bot/capability-types.ts +11 -0
- package/src/bot/cli-provider.ts +8 -7
- package/src/bot/preflight.ts +285 -0
- package/src/bot/provider-shim.ts +218 -0
- package/src/bot/runner.ts +68 -20
- package/src/bot/step-executor.ts +69 -127
- package/src/bot/swarm-controller.ts +94 -20
- package/src/bot/task-create-handler.ts +164 -0
- package/src/bot/task-store.ts +83 -0
- package/src/bot/types.ts +4 -1
- package/src/bot/weaver-tools.ts +7 -45
- package/src/node-types/agent-execute.ts +102 -16
- package/src/node-types/bot-report.ts +24 -3
- package/src/node-types/plan-task.ts +238 -280
- package/src/node-types/review-result.ts +8 -6
- package/src/palindrome.ts +14 -0
- package/src/ui/approval-card.tsx +78 -62
- package/src/ui/bot-activity.tsx +12 -10
- package/src/ui/bot-config.tsx +12 -10
- package/src/ui/bot-dashboard.tsx +13 -11
- package/src/ui/bot-panel.tsx +189 -171
- package/src/ui/bot-slot-card.tsx +125 -70
- package/src/ui/bot-status.tsx +4 -4
- package/src/ui/budget-bar.tsx +86 -25
- package/src/ui/capability-editor.tsx +392 -257
- package/src/ui/chat-task-result.tsx +81 -78
- package/src/ui/decision-log.tsx +76 -73
- package/src/ui/genesis-block.tsx +91 -61
- package/src/ui/instance-stream-view.tsx +861 -0
- package/src/ui/profile-card.tsx +195 -168
- package/src/ui/profile-editor.tsx +453 -370
- package/src/ui/settings-section.tsx +46 -39
- package/src/ui/swarm-controls.tsx +252 -123
- package/src/ui/swarm-dashboard.tsx +999 -466
- package/src/ui/task-detail-view.tsx +485 -428
- package/src/ui/task-editor.tsx +329 -271
- package/src/ui/task-pool-list.tsx +68 -62
- package/src/workflows/src/palindrome.ts +16 -0
- package/src/workflows/tests/palindrome.test.ts +49 -0
- package/src/workflows/weaver-bot-batch.ts +1 -1
- package/src/workflows/weaver-bot.ts +1 -1
- package/dist/ui/bot-constants.d.ts +0 -14
- package/dist/ui/bot-constants.d.ts.map +0 -1
- package/dist/ui/bot-constants.js +0 -189
- package/dist/ui/bot-constants.js.map +0 -1
- package/dist/ui/steer-api.d.ts +0 -7
- package/dist/ui/steer-api.d.ts.map +0 -1
- package/dist/ui/steer-api.js +0 -11
- package/dist/ui/steer-api.js.map +0 -1
- package/dist/ui/trace-to-timeline.d.ts +0 -91
- package/dist/ui/trace-to-timeline.d.ts.map +0 -1
- package/dist/ui/trace-to-timeline.js +0 -116
- package/dist/ui/trace-to-timeline.js.map +0 -1
- package/dist/ui/use-stream-timeline.d.ts +0 -50
- package/dist/ui/use-stream-timeline.d.ts.map +0 -1
- package/dist/ui/use-stream-timeline.js +0 -245
- package/dist/ui/use-stream-timeline.js.map +0 -1
|
@@ -24,6 +24,8 @@ __export(capability_editor_exports, {
|
|
|
24
24
|
default: () => capability_editor_default
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(capability_editor_exports);
|
|
27
|
+
var import_react = require("react");
|
|
28
|
+
var import_plugin_ui_kit = require("@fw/plugin-ui-kit");
|
|
27
29
|
|
|
28
30
|
// src/bot/operations.ts
|
|
29
31
|
var OP_WRITE_FILE = "write_file";
|
|
@@ -56,7 +58,7 @@ var CAP_CORE = {
|
|
|
56
58
|
prompt: `You are Weaver. Execute tasks by calling tools \u2014 do not describe what you would do.
|
|
57
59
|
|
|
58
60
|
## System Constraints
|
|
59
|
-
- All file paths
|
|
61
|
+
- 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.
|
|
60
62
|
- Writes that shrink a file >50% or write empty content are BLOCKED by the system.
|
|
61
63
|
- Blocked shell commands: rm -rf, git push, npm publish, sudo, curl|sh.`
|
|
62
64
|
};
|
|
@@ -64,45 +66,68 @@ var CAP_ROLE_ORCHESTRATOR = {
|
|
|
64
66
|
name: "role-orchestrator",
|
|
65
67
|
description: "Orchestrator role: decomposes objectives into subtask DAGs.",
|
|
66
68
|
tools: [OP_TASK_CREATE, OP_LIST_FILES, OP_READ_FILE],
|
|
69
|
+
acceptance: [
|
|
70
|
+
{ name: "subtasks-created", command: `python3 -c "import json; tasks=json.load(open('.weaver/tasks.json')); exit(0 if len(tasks)>=3 else 1)"` },
|
|
71
|
+
{ 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)"` }
|
|
72
|
+
],
|
|
67
73
|
prompt: `## YOUR ROLE: Orchestrator
|
|
68
74
|
You decompose objectives into subtasks. You never write code or create files directly.
|
|
69
75
|
Your only output is task_create calls + done.
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
### Execution Planning Protocol
|
|
78
|
+
Before creating subtasks, you MUST:
|
|
79
|
+
1. Use list_files and read_file to read every source file. Map the dependency graph (which files import which).
|
|
80
|
+
2. IDENTIFY the critical path \u2014 the longest sequential chain. This is your bottleneck.
|
|
81
|
+
3. GROUP tasks to match worker count (shown in context as maxConcurrent=N).
|
|
82
|
+
- Each dependency level should have at most N parallel tasks.
|
|
83
|
+
- Combine small independent files into single tasks to reduce overhead.
|
|
84
|
+
- Separate high-risk files (many bugs/complexity) from clean ones.
|
|
85
|
+
- Never create more sequential levels than necessary.
|
|
86
|
+
4. SHOW YOUR REASONING in the first task_create description:
|
|
87
|
+
- Dependency graph you found
|
|
88
|
+
- Critical path identified
|
|
89
|
+
- Why you grouped tasks this way
|
|
78
90
|
|
|
79
|
-
###
|
|
80
|
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
|
|
91
|
+
### Task Creation Rules
|
|
92
|
+
- Create subtasks via task_create with parentId: "@self".
|
|
93
|
+
- Assign profiles: developer (code), reviewer (review), ops (infra/setup).
|
|
94
|
+
- Set dependsOn using task titles (resolved to IDs automatically).
|
|
95
|
+
- Fewer tasks with more work each > many tiny serial tasks.
|
|
96
|
+
- A file and its only dependent CAN be in the same task.
|
|
97
|
+
- Tests can be combined with the last implementation task.
|
|
98
|
+
- Your LAST subtask: "Review & Steer" assigned to orchestrator, dependsOn all others.
|
|
84
99
|
|
|
85
100
|
### Acceptance Criteria
|
|
86
101
|
Every subtask MUST have acceptance.checks \u2014 shell commands that verify "done" (exit 0 = pass).
|
|
102
|
+
Checks must test BEHAVIOR (run the code, import the module), not string patterns (grep for text).
|
|
87
103
|
The system runs them automatically after each run. If any fail, the task stays open.
|
|
88
104
|
Examples:
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
105
|
+
- Compiles: npx tsc --noEmit
|
|
106
|
+
- Tests pass: npx vitest run
|
|
107
|
+
- Module works: node -e "import('./src/db.js').then(m => process.exit(m.getById ? 0 : 1))"
|
|
108
|
+
- File exists: test -f src/types.ts
|
|
109
|
+
|
|
110
|
+
### Design First
|
|
111
|
+
For multi-file projects, your FIRST subtask should create a .design.md with:
|
|
112
|
+
- Module map: which files, what each exports (function signatures with types)
|
|
113
|
+
- Conventions: naming, error handling, patterns
|
|
114
|
+
All subsequent developer tasks must read .design.md before writing code.
|
|
93
115
|
|
|
94
116
|
### Steering Mode (when running a Review & Steer task)
|
|
95
117
|
Read the sibling task list in your context \u2014 it shows status, run count, and check failures with error details.
|
|
96
118
|
- All checks pass \u2192 done.
|
|
97
119
|
- Tasks with 0 runs still open \u2192 they will be picked up, do not recreate them.
|
|
98
|
-
- Checks failing \u2192 read the specific error in the check detail, then create a targeted fix task addressing that exact error.
|
|
120
|
+
- Checks failing \u2192 read the specific error in the check detail, then create a targeted fix task addressing that exact error.
|
|
99
121
|
- Task stagnant (3+ failed runs) \u2192 redefine with smaller scope or reassign to different profile.
|
|
100
|
-
- Before creating ANY task, check if an existing open sibling already covers the same work.
|
|
122
|
+
- Before creating ANY task, check if an existing open sibling already covers the same work.
|
|
101
123
|
- After creating fix tasks, create one more Review & Steer depending on them, then done.`
|
|
102
124
|
};
|
|
103
125
|
var CAP_ROLE_DEVELOPER = {
|
|
104
126
|
name: "role-developer",
|
|
105
127
|
description: "Developer role: writes code, creates files, runs commands.",
|
|
128
|
+
acceptance: [
|
|
129
|
+
{ 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" }
|
|
130
|
+
],
|
|
106
131
|
prompt: `## YOUR ROLE: Developer
|
|
107
132
|
You write code and produce files. Execute the task directly \u2014 do not delegate.
|
|
108
133
|
|
|
@@ -150,8 +175,8 @@ var CAP_SHELL = {
|
|
|
150
175
|
};
|
|
151
176
|
var CAP_TASK_MGMT = {
|
|
152
177
|
name: "task-mgmt",
|
|
153
|
-
description: "Create swarm subtasks.",
|
|
154
|
-
tools: [OP_TASK_CREATE],
|
|
178
|
+
description: "Create and inspect swarm subtasks.",
|
|
179
|
+
tools: [OP_TASK_CREATE, "task_list", "task_get", "task_update"],
|
|
155
180
|
prompt: `## Task Management
|
|
156
181
|
- task_create(title, description?, assignedProfile?, parentId?, dependsOn?, complexity?, acceptance?):
|
|
157
182
|
Creates a subtask in the swarm task pool. Returns task ID.
|
|
@@ -160,6 +185,9 @@ var CAP_TASK_MGMT = {
|
|
|
160
185
|
- assignedProfile: "developer" | "reviewer" | "ops" | "orchestrator". Omit for auto-routing.
|
|
161
186
|
- parentId: "@self" to nest under current task. Omit for top-level.
|
|
162
187
|
- dependsOn: Array of task titles. Resolved to IDs automatically.
|
|
188
|
+
- task_list(status?): List tasks in the swarm. Optionally filter by status (pending, in-progress, done, failed).
|
|
189
|
+
- task_get(id): Get full details of a specific task.
|
|
190
|
+
- task_update(id, notes?, files?, description?): Update a task's notes, files list, or description.
|
|
163
191
|
- complexity: "trivial" | "simple" | "moderate" | "complex".
|
|
164
192
|
- acceptance: { checks: [{ name: string, command: string }] } \u2014 shell commands that exit 0 on success.`
|
|
165
193
|
};
|
|
@@ -264,17 +292,22 @@ var CAP_VERIFICATION = {
|
|
|
264
292
|
name: "verification",
|
|
265
293
|
description: "TypeScript compilation and test runner verification.",
|
|
266
294
|
tools: [OP_RUN_SHELL],
|
|
295
|
+
acceptance: [
|
|
296
|
+
{ name: "tsc-compiles", command: "npx tsc --noEmit", condition: "find src -name '*.ts' | head -1 | grep -q ." }
|
|
297
|
+
],
|
|
267
298
|
prompt: `## Verification
|
|
268
|
-
|
|
269
|
-
-
|
|
299
|
+
Use run_shell for compilation and test verification:
|
|
300
|
+
- npx tsc --noEmit \u2014 returns TypeScript compilation errors or empty on success.
|
|
301
|
+
- npx vitest run \u2014 returns test results with pass/fail counts.`
|
|
270
302
|
};
|
|
271
303
|
var CAP_CROSS_FILE_CHECK = {
|
|
272
304
|
name: "cross-file-check",
|
|
273
305
|
description: "Cross-file dependency verification.",
|
|
274
306
|
tools: [OP_READ_FILE, OP_LIST_FILES, OP_RUN_SHELL],
|
|
275
307
|
prompt: `## Cross-File Checks
|
|
276
|
-
Use
|
|
277
|
-
|
|
308
|
+
Use list_files to find relevant files, read_file to inspect them,
|
|
309
|
+
and run_shell with grep to find all import/export references across files.
|
|
310
|
+
Verify import paths resolve to actual exports.`
|
|
278
311
|
};
|
|
279
312
|
var CAP_PROJECT_SETUP = {
|
|
280
313
|
name: "project-setup",
|
|
@@ -289,7 +322,7 @@ var CAP_SECURITY = {
|
|
|
289
322
|
description: "Security audit tools.",
|
|
290
323
|
tools: [OP_READ_FILE, OP_LIST_FILES, OP_RUN_SHELL],
|
|
291
324
|
prompt: `## Security
|
|
292
|
-
Use
|
|
325
|
+
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.
|
|
293
326
|
Use npm audit (via run_shell) for dependency vulnerabilities.
|
|
294
327
|
Finding format: FILE:LINE | SEVERITY (critical/high/medium/low) | ISSUE.`
|
|
295
328
|
};
|
|
@@ -362,24 +395,7 @@ function estimateTokens(text) {
|
|
|
362
395
|
}
|
|
363
396
|
|
|
364
397
|
// src/ui/capability-editor.tsx
|
|
365
|
-
var
|
|
366
|
-
var { useState, useCallback } = React;
|
|
367
|
-
var {
|
|
368
|
-
Flex,
|
|
369
|
-
Typography,
|
|
370
|
-
Input,
|
|
371
|
-
Button,
|
|
372
|
-
IconButton,
|
|
373
|
-
Icon,
|
|
374
|
-
Field,
|
|
375
|
-
Chip,
|
|
376
|
-
Checkbox,
|
|
377
|
-
Table,
|
|
378
|
-
CodeBlock,
|
|
379
|
-
ScrollArea,
|
|
380
|
-
toast,
|
|
381
|
-
usePackWorkspace
|
|
382
|
-
} = require("@fw/plugin-ui-kit");
|
|
398
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
383
399
|
var AVAILABLE_TOOLS = [...PLAN_OPERATIONS];
|
|
384
400
|
function CapabilityDetail({
|
|
385
401
|
cap,
|
|
@@ -388,207 +404,269 @@ function CapabilityDetail({
|
|
|
388
404
|
onBack,
|
|
389
405
|
onSubmit
|
|
390
406
|
}) {
|
|
391
|
-
const [name, setName] = useState(cap?.name ?? "");
|
|
392
|
-
const [description, setDescription] = useState(cap?.description ?? "");
|
|
393
|
-
const [prompt, setPrompt] = useState(cap?.prompt ?? "");
|
|
394
|
-
const [tools, setTools] = useState(cap?.tools ?? []);
|
|
407
|
+
const [name, setName] = (0, import_react.useState)(cap?.name ?? "");
|
|
408
|
+
const [description, setDescription] = (0, import_react.useState)(cap?.description ?? "");
|
|
409
|
+
const [prompt, setPrompt] = (0, import_react.useState)(cap?.prompt ?? "");
|
|
410
|
+
const [tools, setTools] = (0, import_react.useState)(cap?.tools ?? []);
|
|
411
|
+
const [acceptance, setAcceptance] = (0, import_react.useState)(cap?.acceptance ?? []);
|
|
395
412
|
const readOnly = mode === "view";
|
|
396
413
|
const isCreate = mode === "create";
|
|
397
|
-
const handleToggleTool = useCallback((tool) => {
|
|
414
|
+
const handleToggleTool = (0, import_react.useCallback)((tool) => {
|
|
398
415
|
setTools(
|
|
399
416
|
(prev) => prev.includes(tool) ? prev.filter((t) => t !== tool) : [...prev, tool]
|
|
400
417
|
);
|
|
401
418
|
}, []);
|
|
402
|
-
const handleSubmit = useCallback(() => {
|
|
419
|
+
const handleSubmit = (0, import_react.useCallback)(() => {
|
|
403
420
|
const trimName = name.trim().toLowerCase().replace(/\s+/g, "-");
|
|
404
421
|
if (!trimName || !description.trim()) {
|
|
405
|
-
toast("Name and description are required", { type: "error" });
|
|
422
|
+
(0, import_plugin_ui_kit.toast)("Name and description are required", { type: "error" });
|
|
406
423
|
return;
|
|
407
424
|
}
|
|
408
425
|
if (isCreate && allNames.includes(trimName)) {
|
|
409
|
-
toast(`Capability "${trimName}" already exists`, { type: "error" });
|
|
426
|
+
(0, import_plugin_ui_kit.toast)(`Capability "${trimName}" already exists`, { type: "error" });
|
|
410
427
|
return;
|
|
411
428
|
}
|
|
412
429
|
onSubmit({
|
|
413
430
|
name: isCreate ? trimName : cap?.name ?? trimName,
|
|
414
431
|
description: description.trim(),
|
|
415
432
|
prompt: prompt.trim() || `## ${description.trim()}`,
|
|
416
|
-
tools: tools.length > 0 ? tools : void 0
|
|
433
|
+
tools: tools.length > 0 ? tools : void 0,
|
|
434
|
+
acceptance: acceptance.length > 0 ? acceptance.filter((a) => a.name && a.command) : void 0
|
|
417
435
|
});
|
|
418
|
-
}, [name, description, prompt, tools, isCreate, allNames, cap, onSubmit]);
|
|
436
|
+
}, [name, description, prompt, tools, acceptance, isCreate, allNames, cap, onSubmit]);
|
|
419
437
|
const title = isCreate ? "New Capability" : readOnly ? cap?.name ?? "" : `Edit: ${cap?.name ?? ""}`;
|
|
420
|
-
return
|
|
421
|
-
Flex,
|
|
438
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
439
|
+
import_plugin_ui_kit.Flex,
|
|
422
440
|
{
|
|
423
441
|
variant: "column-stretch-start-nowrap-0",
|
|
424
|
-
style: { width: "100%", height: "100%", overflow: "hidden" }
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
size: "small",
|
|
447
|
-
color: "color-status-info"
|
|
448
|
-
})
|
|
449
|
-
)
|
|
450
|
-
),
|
|
451
|
-
// Scrollable form
|
|
452
|
-
React.createElement(
|
|
453
|
-
ScrollArea,
|
|
454
|
-
{ style: { flex: 1, minHeight: 0 } },
|
|
455
|
-
React.createElement(
|
|
456
|
-
Flex,
|
|
457
|
-
{
|
|
458
|
-
variant: "column-stretch-start-nowrap-10",
|
|
459
|
-
style: { padding: "12px 16px" }
|
|
460
|
-
},
|
|
461
|
-
// Name
|
|
462
|
-
React.createElement(
|
|
463
|
-
Field,
|
|
464
|
-
{ label: "Name" },
|
|
465
|
-
readOnly ? React.createElement(Typography, {
|
|
466
|
-
variant: "smallCaption-thick",
|
|
467
|
-
color: "color-text-high",
|
|
468
|
-
style: { padding: "4px 0" }
|
|
469
|
-
}, cap?.name) : React.createElement(Input, {
|
|
470
|
-
type: "text",
|
|
471
|
-
size: "small",
|
|
472
|
-
placeholder: "e.g. api-design",
|
|
473
|
-
value: name,
|
|
474
|
-
onChange: (v) => setName(v),
|
|
475
|
-
disabled: !isCreate,
|
|
476
|
-
defaultBoxStyle: { flex: 1, minWidth: 0 },
|
|
477
|
-
inputBoxStyle: { maxWidth: "none" }
|
|
478
|
-
})
|
|
479
|
-
),
|
|
480
|
-
// Description
|
|
481
|
-
React.createElement(
|
|
482
|
-
Field,
|
|
483
|
-
{ label: "Description" },
|
|
484
|
-
readOnly ? React.createElement(Typography, {
|
|
485
|
-
variant: "smallCaption-regular",
|
|
486
|
-
color: "color-text-medium",
|
|
487
|
-
style: { padding: "4px 0" }
|
|
488
|
-
}, cap?.description) : React.createElement(Input, {
|
|
489
|
-
type: "text",
|
|
490
|
-
size: "small",
|
|
491
|
-
placeholder: "What this capability provides",
|
|
492
|
-
value: description,
|
|
493
|
-
onChange: (v) => setDescription(v),
|
|
494
|
-
defaultBoxStyle: { flex: 1, minWidth: 0 },
|
|
495
|
-
inputBoxStyle: { maxWidth: "none" }
|
|
496
|
-
})
|
|
497
|
-
),
|
|
498
|
-
// Prompt
|
|
499
|
-
React.createElement(
|
|
500
|
-
Field,
|
|
501
|
-
{ label: "Prompt", align: "start" },
|
|
502
|
-
readOnly ? React.createElement(Typography, {
|
|
503
|
-
variant: "smallCaption-regular",
|
|
504
|
-
color: "color-text-medium",
|
|
505
|
-
style: { whiteSpace: "pre-wrap", lineHeight: 1.5 }
|
|
506
|
-
}, cap?.prompt) : React.createElement(Input, {
|
|
507
|
-
type: "text",
|
|
508
|
-
size: "small",
|
|
509
|
-
multiline: true,
|
|
510
|
-
placeholder: "Knowledge content (markdown) injected into the system prompt",
|
|
511
|
-
value: prompt,
|
|
512
|
-
onChange: (v) => setPrompt(v),
|
|
513
|
-
defaultBoxStyle: { flex: 1, minWidth: 0 },
|
|
514
|
-
inputBoxStyle: { maxWidth: "none", minHeight: 160 }
|
|
515
|
-
})
|
|
442
|
+
style: { width: "100%", height: "100%", overflow: "hidden" },
|
|
443
|
+
children: [
|
|
444
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
445
|
+
import_plugin_ui_kit.Flex,
|
|
446
|
+
{
|
|
447
|
+
variant: "row-center-space-between-nowrap-8",
|
|
448
|
+
style: { padding: "8px 16px", flexShrink: 0, borderBottom: "1px solid var(--color-border-default)" },
|
|
449
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-start-nowrap-8", children: [
|
|
450
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
451
|
+
import_plugin_ui_kit.IconButton,
|
|
452
|
+
{
|
|
453
|
+
icon: "back",
|
|
454
|
+
size: "xs",
|
|
455
|
+
variant: "clear",
|
|
456
|
+
onClick: onBack,
|
|
457
|
+
title: "Back to list"
|
|
458
|
+
}
|
|
459
|
+
),
|
|
460
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Typography, { variant: "caption-thick", color: "color-text-high", children: title }),
|
|
461
|
+
readOnly && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Chip, { label: "built-in", size: "small", color: "color-status-info" })
|
|
462
|
+
] })
|
|
463
|
+
}
|
|
516
464
|
),
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
"
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
"
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
465
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.ScrollArea, { style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
466
|
+
import_plugin_ui_kit.Flex,
|
|
467
|
+
{
|
|
468
|
+
variant: "column-stretch-start-nowrap-10",
|
|
469
|
+
style: { padding: "12px 16px" },
|
|
470
|
+
children: [
|
|
471
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Name", children: readOnly ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
472
|
+
import_plugin_ui_kit.Typography,
|
|
473
|
+
{
|
|
474
|
+
variant: "smallCaption-thick",
|
|
475
|
+
color: "color-text-high",
|
|
476
|
+
style: { padding: "4px 0" },
|
|
477
|
+
children: cap?.name
|
|
478
|
+
}
|
|
479
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
480
|
+
import_plugin_ui_kit.Input,
|
|
481
|
+
{
|
|
482
|
+
type: "text",
|
|
483
|
+
size: "small",
|
|
484
|
+
placeholder: "e.g. api-design",
|
|
485
|
+
value: name,
|
|
486
|
+
onChange: (v) => setName(v),
|
|
487
|
+
disabled: !isCreate,
|
|
488
|
+
defaultBoxStyle: { flex: 1, minWidth: 0 },
|
|
489
|
+
inputBoxStyle: { maxWidth: "none" }
|
|
490
|
+
}
|
|
491
|
+
) }),
|
|
492
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Description", children: readOnly ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
493
|
+
import_plugin_ui_kit.Typography,
|
|
494
|
+
{
|
|
495
|
+
variant: "smallCaption-regular",
|
|
496
|
+
color: "color-text-medium",
|
|
497
|
+
style: { padding: "4px 0" },
|
|
498
|
+
children: cap?.description
|
|
499
|
+
}
|
|
500
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
501
|
+
import_plugin_ui_kit.Input,
|
|
502
|
+
{
|
|
503
|
+
type: "text",
|
|
504
|
+
size: "small",
|
|
505
|
+
placeholder: "What this capability provides",
|
|
506
|
+
value: description,
|
|
507
|
+
onChange: (v) => setDescription(v),
|
|
508
|
+
defaultBoxStyle: { flex: 1, minWidth: 0 },
|
|
509
|
+
inputBoxStyle: { maxWidth: "none" }
|
|
510
|
+
}
|
|
511
|
+
) }),
|
|
512
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Prompt", align: "start", children: readOnly ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
513
|
+
import_plugin_ui_kit.Typography,
|
|
514
|
+
{
|
|
515
|
+
variant: "smallCaption-regular",
|
|
516
|
+
color: "color-text-medium",
|
|
517
|
+
style: { whiteSpace: "pre-wrap", lineHeight: 1.5 },
|
|
518
|
+
children: cap?.prompt
|
|
519
|
+
}
|
|
520
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
521
|
+
import_plugin_ui_kit.Input,
|
|
522
|
+
{
|
|
523
|
+
type: "text",
|
|
524
|
+
size: "small",
|
|
525
|
+
multiline: true,
|
|
526
|
+
placeholder: "Knowledge content (markdown) injected into the system prompt",
|
|
527
|
+
value: prompt,
|
|
528
|
+
onChange: (v) => setPrompt(v),
|
|
529
|
+
defaultBoxStyle: { flex: 1, minWidth: 0 },
|
|
530
|
+
inputBoxStyle: { maxWidth: "none", minHeight: 160 }
|
|
531
|
+
}
|
|
532
|
+
) }),
|
|
533
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Tools", align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
534
|
+
import_plugin_ui_kit.Table,
|
|
535
|
+
{
|
|
536
|
+
size: "compact",
|
|
537
|
+
showHeader: false,
|
|
538
|
+
data: AVAILABLE_TOOLS.map((t) => ({
|
|
539
|
+
tool: t,
|
|
540
|
+
active: (readOnly ? cap?.tools ?? [] : tools).includes(t)
|
|
541
|
+
})),
|
|
542
|
+
getRowKey: (row) => row.tool,
|
|
543
|
+
columns: [
|
|
544
|
+
{
|
|
545
|
+
key: "check",
|
|
546
|
+
header: "",
|
|
547
|
+
width: "28px",
|
|
548
|
+
render: (_v, row) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { height: 20, display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
549
|
+
import_plugin_ui_kit.Checkbox,
|
|
550
|
+
{
|
|
551
|
+
checked: row.active,
|
|
552
|
+
disabled: readOnly,
|
|
553
|
+
onChange: readOnly ? void 0 : () => handleToggleTool(row.tool),
|
|
554
|
+
size: "sm"
|
|
555
|
+
}
|
|
556
|
+
) })
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
key: "tool",
|
|
560
|
+
header: "Tool",
|
|
561
|
+
render: (_v, row) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { height: 20, display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
562
|
+
import_plugin_ui_kit.Typography,
|
|
563
|
+
{
|
|
564
|
+
variant: "smallCaption-regular",
|
|
565
|
+
color: row.active ? "color-text-high" : "color-text-subtle",
|
|
566
|
+
children: row.tool
|
|
567
|
+
}
|
|
568
|
+
) })
|
|
569
|
+
}
|
|
570
|
+
]
|
|
571
|
+
}
|
|
572
|
+
) }),
|
|
573
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Field, { label: "Acceptance Checks", children: [
|
|
574
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Typography, { variant: "smallCaption-regular", color: "color-text-subtle", style: { marginBottom: 4 }, children: "Shell commands that auto-run after every task using this capability. Exit 0 = pass." }),
|
|
575
|
+
(readOnly ? cap?.acceptance ?? [] : acceptance).map((check, idx) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-start-nowrap-4", style: { marginBottom: 4 }, children: [
|
|
576
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
577
|
+
import_plugin_ui_kit.Input,
|
|
578
|
+
{
|
|
579
|
+
size: "xs",
|
|
580
|
+
placeholder: "Check name",
|
|
581
|
+
value: check.name,
|
|
582
|
+
readOnly,
|
|
583
|
+
style: { width: 120 },
|
|
584
|
+
onChange: (e) => {
|
|
585
|
+
const updated = [...acceptance];
|
|
586
|
+
updated[idx] = { ...updated[idx], name: e.target.value };
|
|
587
|
+
setAcceptance(updated);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
),
|
|
591
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
592
|
+
import_plugin_ui_kit.Input,
|
|
593
|
+
{
|
|
594
|
+
size: "xs",
|
|
595
|
+
placeholder: "Shell command (exit 0 = pass)",
|
|
596
|
+
value: check.command,
|
|
597
|
+
readOnly,
|
|
598
|
+
style: { flex: 1 },
|
|
599
|
+
onChange: (e) => {
|
|
600
|
+
const updated = [...acceptance];
|
|
601
|
+
updated[idx] = { ...updated[idx], command: e.target.value };
|
|
602
|
+
setAcceptance(updated);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
),
|
|
606
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
607
|
+
import_plugin_ui_kit.Input,
|
|
608
|
+
{
|
|
609
|
+
size: "xs",
|
|
610
|
+
placeholder: "Condition (optional file)",
|
|
611
|
+
value: check.condition ?? "",
|
|
612
|
+
readOnly,
|
|
613
|
+
style: { width: 140 },
|
|
614
|
+
onChange: (e) => {
|
|
615
|
+
const updated = [...acceptance];
|
|
616
|
+
updated[idx] = { ...updated[idx], condition: e.target.value || void 0 };
|
|
617
|
+
setAcceptance(updated);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
),
|
|
621
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
622
|
+
import_plugin_ui_kit.IconButton,
|
|
623
|
+
{
|
|
624
|
+
size: "xs",
|
|
625
|
+
variant: "clear",
|
|
626
|
+
color: "danger",
|
|
627
|
+
onClick: () => setAcceptance(acceptance.filter((_, i) => i !== idx)),
|
|
628
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Icon, { name: "delete", size: 14 })
|
|
629
|
+
}
|
|
630
|
+
)
|
|
631
|
+
] }, idx)),
|
|
632
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
633
|
+
import_plugin_ui_kit.Button,
|
|
634
|
+
{
|
|
635
|
+
size: "xs",
|
|
636
|
+
variant: "clear",
|
|
637
|
+
color: "primary",
|
|
638
|
+
onClick: () => setAcceptance([...acceptance, { name: "", command: "" }]),
|
|
639
|
+
children: "+ Add check"
|
|
640
|
+
}
|
|
555
641
|
)
|
|
556
|
-
}
|
|
642
|
+
] }),
|
|
643
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Field, { label: "Est. tokens", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Typography, { variant: "smallCaption-regular", color: "color-text-subtle", children: `~${estimateTokens(readOnly ? cap?.prompt ?? "" : prompt)} tokens (approx.)` }) }),
|
|
644
|
+
!readOnly && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
645
|
+
import_plugin_ui_kit.Flex,
|
|
646
|
+
{
|
|
647
|
+
variant: "row-center-end-nowrap-8",
|
|
648
|
+
style: { paddingTop: 4 },
|
|
649
|
+
children: [
|
|
650
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Button, { size: "xs", variant: "clear", color: "secondary", onClick: onBack, children: "Cancel" }),
|
|
651
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
652
|
+
import_plugin_ui_kit.Button,
|
|
653
|
+
{
|
|
654
|
+
size: "xs",
|
|
655
|
+
variant: "fill",
|
|
656
|
+
color: "primary",
|
|
657
|
+
onClick: handleSubmit,
|
|
658
|
+
disabled: readOnly || !isCreate && !description.trim() || isCreate && (!name.trim() || !description.trim()),
|
|
659
|
+
children: isCreate ? "Create" : "Save"
|
|
660
|
+
}
|
|
661
|
+
)
|
|
662
|
+
]
|
|
663
|
+
}
|
|
664
|
+
)
|
|
557
665
|
]
|
|
558
|
-
}
|
|
559
|
-
)
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
Field,
|
|
563
|
-
{ label: "Est. tokens" },
|
|
564
|
-
React.createElement(Typography, {
|
|
565
|
-
variant: "smallCaption-regular",
|
|
566
|
-
color: "color-text-subtle"
|
|
567
|
-
}, `~${estimateTokens(readOnly ? cap?.prompt ?? "" : prompt)} tokens (approx.)`)
|
|
568
|
-
),
|
|
569
|
-
// Submit button (not for view mode)
|
|
570
|
-
!readOnly && React.createElement(
|
|
571
|
-
Flex,
|
|
572
|
-
{
|
|
573
|
-
variant: "row-center-end-nowrap-8",
|
|
574
|
-
style: { paddingTop: 4 }
|
|
575
|
-
},
|
|
576
|
-
React.createElement(Button, {
|
|
577
|
-
size: "xs",
|
|
578
|
-
variant: "clear",
|
|
579
|
-
color: "secondary",
|
|
580
|
-
onClick: onBack
|
|
581
|
-
}, "Cancel"),
|
|
582
|
-
React.createElement(Button, {
|
|
583
|
-
size: "xs",
|
|
584
|
-
variant: "fill",
|
|
585
|
-
color: "primary",
|
|
586
|
-
onClick: handleSubmit,
|
|
587
|
-
disabled: readOnly || !isCreate && !description.trim() || isCreate && (!name.trim() || !description.trim())
|
|
588
|
-
}, isCreate ? "Create" : "Save")
|
|
589
|
-
)
|
|
590
|
-
)
|
|
591
|
-
)
|
|
666
|
+
}
|
|
667
|
+
) })
|
|
668
|
+
]
|
|
669
|
+
}
|
|
592
670
|
);
|
|
593
671
|
}
|
|
594
672
|
function CapabilityList({
|
|
@@ -600,188 +678,179 @@ function CapabilityList({
|
|
|
600
678
|
onClose,
|
|
601
679
|
hasCustom
|
|
602
680
|
}) {
|
|
603
|
-
return
|
|
604
|
-
Flex,
|
|
681
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
682
|
+
import_plugin_ui_kit.Flex,
|
|
605
683
|
{
|
|
606
684
|
variant: "column-stretch-start-nowrap-0",
|
|
607
|
-
style: { width: "100%", height: "100%", overflow: "hidden" }
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
),
|
|
650
|
-
// Scrollable list
|
|
651
|
-
React.createElement(
|
|
652
|
-
ScrollArea,
|
|
653
|
-
{ style: { flex: 1, minHeight: 0 } },
|
|
654
|
-
React.createElement(
|
|
655
|
-
Flex,
|
|
656
|
-
{
|
|
657
|
-
variant: "column-stretch-start-nowrap-2",
|
|
658
|
-
style: { padding: "8px 16px" }
|
|
659
|
-
},
|
|
660
|
-
...allCaps.map(
|
|
661
|
-
(cap) => React.createElement(
|
|
662
|
-
Flex,
|
|
663
|
-
{
|
|
664
|
-
key: cap.name,
|
|
665
|
-
variant: "row-center-space-between-nowrap-8",
|
|
666
|
-
style: {
|
|
667
|
-
padding: "7px 10px",
|
|
668
|
-
borderRadius: 6,
|
|
669
|
-
cursor: "pointer",
|
|
670
|
-
border: "1px solid var(--color-border-default)",
|
|
671
|
-
transition: "background-color 0.1s"
|
|
672
|
-
},
|
|
673
|
-
onClick: () => onOpen(cap.name),
|
|
674
|
-
onMouseEnter: (e) => {
|
|
675
|
-
e.currentTarget.style.backgroundColor = "var(--color-surface-hover)";
|
|
676
|
-
},
|
|
677
|
-
onMouseLeave: (e) => {
|
|
678
|
-
e.currentTarget.style.backgroundColor = "transparent";
|
|
679
|
-
}
|
|
680
|
-
},
|
|
681
|
-
// Left: icon + name + description
|
|
682
|
-
React.createElement(
|
|
683
|
-
Flex,
|
|
684
|
-
{ variant: "row-center-start-nowrap-8", style: { flex: 1, minWidth: 0 } },
|
|
685
|
-
React.createElement(Icon, {
|
|
686
|
-
name: cap.builtIn ? "lock" : "edit",
|
|
687
|
-
size: 13,
|
|
688
|
-
color: cap.builtIn ? "color-text-subtle" : "color-brand-main"
|
|
689
|
-
}),
|
|
690
|
-
React.createElement(Typography, {
|
|
691
|
-
variant: "smallCaption-thick",
|
|
692
|
-
color: "color-text-high",
|
|
693
|
-
style: { minWidth: 80, flexShrink: 0 }
|
|
694
|
-
}, cap.name),
|
|
695
|
-
React.createElement(Typography, {
|
|
696
|
-
variant: "smallCaption-regular",
|
|
697
|
-
color: "color-text-subtle",
|
|
698
|
-
style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }
|
|
699
|
-
}, cap.description)
|
|
700
|
-
),
|
|
701
|
-
// Right: chips + actions
|
|
702
|
-
React.createElement(
|
|
703
|
-
Flex,
|
|
704
|
-
{ variant: "row-center-end-nowrap-4", style: { flexShrink: 0 } },
|
|
705
|
-
cap.tools && cap.tools.length > 0 && React.createElement(Chip, {
|
|
706
|
-
label: `${cap.tools.length} tools`,
|
|
707
|
-
size: "small",
|
|
708
|
-
color: "color-status-positive"
|
|
709
|
-
}),
|
|
710
|
-
!cap.builtIn && React.createElement(IconButton, {
|
|
711
|
-
icon: "outlinedDelete",
|
|
712
|
-
size: "xs",
|
|
713
|
-
variant: "clear",
|
|
714
|
-
color: "danger",
|
|
715
|
-
onClick: (e) => {
|
|
716
|
-
e.stopPropagation();
|
|
717
|
-
onDelete(cap.name);
|
|
685
|
+
style: { width: "100%", height: "100%", overflow: "hidden" },
|
|
686
|
+
children: [
|
|
687
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
688
|
+
import_plugin_ui_kit.Flex,
|
|
689
|
+
{
|
|
690
|
+
variant: "row-center-space-between-nowrap-8",
|
|
691
|
+
style: { padding: "8px 16px", flexShrink: 0, borderBottom: "1px solid var(--color-border-default)" },
|
|
692
|
+
children: [
|
|
693
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-start-nowrap-8", children: [
|
|
694
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.IconButton, { icon: "back", size: "xs", variant: "clear", onClick: onClose, title: "Back" }),
|
|
695
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Typography, { variant: "caption-thick", color: "color-text-high", children: "Capabilities" }),
|
|
696
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
697
|
+
import_plugin_ui_kit.Chip,
|
|
698
|
+
{
|
|
699
|
+
label: `${allCaps.length}`,
|
|
700
|
+
size: "small",
|
|
701
|
+
color: "color-brand-main"
|
|
702
|
+
}
|
|
703
|
+
)
|
|
704
|
+
] }),
|
|
705
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-end-nowrap-6", children: [
|
|
706
|
+
onSaveAll && hasCustom && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Button, { size: "xs", variant: "outlined", color: "primary", onClick: onSaveAll, children: "Save" }),
|
|
707
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Button, { size: "xs", variant: "fill", color: "primary", onClick: onCreate, children: "New" })
|
|
708
|
+
] })
|
|
709
|
+
]
|
|
710
|
+
}
|
|
711
|
+
),
|
|
712
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.ScrollArea, { style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
713
|
+
import_plugin_ui_kit.Flex,
|
|
714
|
+
{
|
|
715
|
+
variant: "column-stretch-start-nowrap-2",
|
|
716
|
+
style: { padding: "8px 16px" },
|
|
717
|
+
children: allCaps.map((cap) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
718
|
+
import_plugin_ui_kit.Flex,
|
|
719
|
+
{
|
|
720
|
+
variant: "row-center-space-between-nowrap-8",
|
|
721
|
+
style: {
|
|
722
|
+
padding: "7px 10px",
|
|
723
|
+
borderRadius: 6,
|
|
724
|
+
cursor: "pointer",
|
|
725
|
+
border: "1px solid var(--color-border-default)",
|
|
726
|
+
transition: "background-color 0.1s"
|
|
718
727
|
},
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
728
|
+
onClick: () => onOpen(cap.name),
|
|
729
|
+
onMouseEnter: (e) => {
|
|
730
|
+
e.currentTarget.style.backgroundColor = "var(--color-surface-hover)";
|
|
731
|
+
},
|
|
732
|
+
onMouseLeave: (e) => {
|
|
733
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
734
|
+
},
|
|
735
|
+
children: [
|
|
736
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-start-nowrap-8", style: { flex: 1, minWidth: 0 }, children: [
|
|
737
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
738
|
+
import_plugin_ui_kit.Typography,
|
|
739
|
+
{
|
|
740
|
+
variant: "smallCaption-thick",
|
|
741
|
+
color: "color-text-high",
|
|
742
|
+
style: { minWidth: 80, flexShrink: 0 },
|
|
743
|
+
children: cap.name
|
|
744
|
+
}
|
|
745
|
+
),
|
|
746
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
747
|
+
import_plugin_ui_kit.Typography,
|
|
748
|
+
{
|
|
749
|
+
variant: "smallCaption-regular",
|
|
750
|
+
color: "color-text-subtle",
|
|
751
|
+
style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" },
|
|
752
|
+
children: cap.description
|
|
753
|
+
}
|
|
754
|
+
)
|
|
755
|
+
] }),
|
|
756
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_plugin_ui_kit.Flex, { variant: "row-center-end-nowrap-4", style: { flexShrink: 0 }, children: [
|
|
757
|
+
cap.tools && cap.tools.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
758
|
+
import_plugin_ui_kit.Chip,
|
|
759
|
+
{
|
|
760
|
+
label: `${cap.tools.length} tools`,
|
|
761
|
+
size: "small",
|
|
762
|
+
color: "color-status-positive"
|
|
763
|
+
}
|
|
764
|
+
),
|
|
765
|
+
!cap.builtIn && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
766
|
+
import_plugin_ui_kit.IconButton,
|
|
767
|
+
{
|
|
768
|
+
icon: "outlinedDelete",
|
|
769
|
+
size: "xs",
|
|
770
|
+
variant: "clear",
|
|
771
|
+
color: "danger",
|
|
772
|
+
onClick: (e) => {
|
|
773
|
+
e.stopPropagation();
|
|
774
|
+
onDelete(cap.name);
|
|
775
|
+
},
|
|
776
|
+
title: "Delete capability"
|
|
777
|
+
}
|
|
778
|
+
),
|
|
779
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_plugin_ui_kit.Icon, { name: "chevronRight", size: 12, color: "color-text-subtle" })
|
|
780
|
+
] })
|
|
781
|
+
]
|
|
782
|
+
},
|
|
783
|
+
cap.name
|
|
784
|
+
))
|
|
785
|
+
}
|
|
786
|
+
) })
|
|
787
|
+
]
|
|
788
|
+
}
|
|
731
789
|
);
|
|
732
790
|
}
|
|
733
791
|
function CapabilityEditor({ customCapabilities = [], onSave, onClose }) {
|
|
734
|
-
const [customs, setCustoms] = useState(customCapabilities);
|
|
735
|
-
const [screen, setScreen] = useState("list");
|
|
792
|
+
const [customs, setCustoms] = (0, import_react.useState)(customCapabilities);
|
|
793
|
+
const [screen, setScreen] = (0, import_react.useState)("list");
|
|
736
794
|
const allCaps = [
|
|
737
795
|
...BUILT_IN_CAPABILITIES.map((c) => ({ ...c, builtIn: true })),
|
|
738
796
|
...customs.map((c) => ({ ...c, builtIn: false }))
|
|
739
797
|
];
|
|
740
798
|
const allNames = allCaps.map((c) => c.name);
|
|
741
|
-
const handleOpen = useCallback((name) => {
|
|
799
|
+
const handleOpen = (0, import_react.useCallback)((name) => {
|
|
742
800
|
const cap = allCaps.find((c) => c.name === name);
|
|
743
801
|
if (!cap) return;
|
|
744
|
-
setScreen({ mode:
|
|
802
|
+
setScreen({ mode: "edit", name });
|
|
745
803
|
}, [allCaps]);
|
|
746
|
-
const handleDelete = useCallback((name) => {
|
|
804
|
+
const handleDelete = (0, import_react.useCallback)((name) => {
|
|
747
805
|
setCustoms((prev) => prev.filter((c) => c.name !== name));
|
|
748
|
-
toast(`Capability "${name}" deleted`, { type: "success" });
|
|
806
|
+
(0, import_plugin_ui_kit.toast)(`Capability "${name}" deleted`, { type: "success" });
|
|
749
807
|
}, []);
|
|
750
|
-
const handleSubmit = useCallback((cap) => {
|
|
808
|
+
const handleSubmit = (0, import_react.useCallback)((cap) => {
|
|
751
809
|
if (typeof screen === "object" && screen.mode === "edit") {
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
810
|
+
const isExistingCustom = customs.some((c) => c.name === cap.name);
|
|
811
|
+
if (isExistingCustom) {
|
|
812
|
+
setCustoms(
|
|
813
|
+
(prev) => prev.map((c) => c.name === cap.name ? cap : c)
|
|
814
|
+
);
|
|
815
|
+
(0, import_plugin_ui_kit.toast)(`Capability "${cap.name}" updated`, { type: "success" });
|
|
816
|
+
} else {
|
|
817
|
+
setCustoms((prev) => [...prev, cap]);
|
|
818
|
+
(0, import_plugin_ui_kit.toast)(`Capability "${cap.name}" customized`, { type: "success" });
|
|
819
|
+
}
|
|
756
820
|
} else {
|
|
757
821
|
setCustoms((prev) => [...prev, cap]);
|
|
758
|
-
toast(`Capability "${cap.name}" created`, { type: "success" });
|
|
822
|
+
(0, import_plugin_ui_kit.toast)(`Capability "${cap.name}" created`, { type: "success" });
|
|
759
823
|
}
|
|
760
824
|
setScreen("list");
|
|
761
|
-
}, [screen]);
|
|
762
|
-
const handleSaveAll = useCallback(() => {
|
|
825
|
+
}, [screen, customs]);
|
|
826
|
+
const handleSaveAll = (0, import_react.useCallback)(() => {
|
|
763
827
|
onSave?.(customs);
|
|
764
|
-
toast("Capabilities saved", { type: "success" });
|
|
828
|
+
(0, import_plugin_ui_kit.toast)("Capabilities saved", { type: "success" });
|
|
765
829
|
}, [customs, onSave]);
|
|
766
830
|
if (typeof screen === "object") {
|
|
767
831
|
const cap = screen.name ? allCaps.find((c) => c.name === screen.name) : void 0;
|
|
768
|
-
return
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
832
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
833
|
+
CapabilityDetail,
|
|
834
|
+
{
|
|
835
|
+
cap,
|
|
836
|
+
mode: screen.mode,
|
|
837
|
+
allNames,
|
|
838
|
+
onBack: () => setScreen("list"),
|
|
839
|
+
onSubmit: handleSubmit
|
|
840
|
+
}
|
|
841
|
+
);
|
|
775
842
|
}
|
|
776
|
-
return
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
843
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
844
|
+
CapabilityList,
|
|
845
|
+
{
|
|
846
|
+
allCaps,
|
|
847
|
+
onOpen: handleOpen,
|
|
848
|
+
onDelete: handleDelete,
|
|
849
|
+
onCreate: () => setScreen({ mode: "create" }),
|
|
850
|
+
onSaveAll: onSave ? handleSaveAll : void 0,
|
|
851
|
+
onClose,
|
|
852
|
+
hasCustom: customs.length > 0
|
|
853
|
+
}
|
|
854
|
+
);
|
|
785
855
|
}
|
|
786
856
|
var capability_editor_default = CapabilityEditor;
|
|
787
|
-
module.exports = CapabilityEditor;
|