@uniqueli/openwork 0.2.2 → 0.2.3

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.
@@ -12817,6 +12817,19 @@ const Send = createLucideIcon("Send", [
12817
12817
  ],
12818
12818
  ["path", { d: "m21.854 2.147-10.94 10.939", key: "12cjpa" }]
12819
12819
  ]);
12820
+ const Sparkles = createLucideIcon("Sparkles", [
12821
+ [
12822
+ "path",
12823
+ {
12824
+ d: "M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z",
12825
+ key: "4pj2yx"
12826
+ }
12827
+ ],
12828
+ ["path", { d: "M20 3v4", key: "1olli1" }],
12829
+ ["path", { d: "M22 5h-4", key: "1gvqau" }],
12830
+ ["path", { d: "M4 17v2", key: "vumght" }],
12831
+ ["path", { d: "M5 18H3", key: "zchphs" }]
12832
+ ]);
12820
12833
  const SquarePen = createLucideIcon("SquarePen", [
12821
12834
  ["path", { d: "M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7", key: "1m0v6g" }],
12822
12835
  [
@@ -76155,6 +76168,781 @@ function TabbedPanel({ threadId, showTabBar = true }) {
76155
76168
  ) })
76156
76169
  ] });
76157
76170
  }
76171
+ function Switch({ checked = false, onCheckedChange, disabled = false, className, onClick, ...props }) {
76172
+ const handleClick = (e) => {
76173
+ onClick?.(e);
76174
+ if (!disabled) {
76175
+ onCheckedChange?.(!checked);
76176
+ }
76177
+ };
76178
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
76179
+ "button",
76180
+ {
76181
+ type: "button",
76182
+ role: "switch",
76183
+ "aria-checked": checked,
76184
+ disabled,
76185
+ onClick: handleClick,
76186
+ className: cn(
76187
+ "relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-white/20 focus:ring-offset-2 focus:ring-offset-[#0D0D0F] disabled:cursor-not-allowed disabled:opacity-50",
76188
+ checked ? "bg-blue-500" : "bg-white/10",
76189
+ className
76190
+ ),
76191
+ ...props,
76192
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
76193
+ "span",
76194
+ {
76195
+ className: cn(
76196
+ "pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out",
76197
+ checked ? "translate-x-4" : "translate-x-0"
76198
+ )
76199
+ }
76200
+ )
76201
+ }
76202
+ );
76203
+ }
76204
+ const SKILL_TEMPLATES = [
76205
+ {
76206
+ id: "custom-code-language",
76207
+ name: "Programming Language Expert",
76208
+ description: "Create a skill for a specific programming language",
76209
+ category: "coding",
76210
+ prompt: `You are an expert in {{LANGUAGE}} programming. Your expertise includes:
76211
+
76212
+ ## Core {{LANGUAGE}} Knowledge
76213
+ - Language syntax and best practices
76214
+ - Standard library and common frameworks
76215
+ - Idiomatic {{LANGUAGE}} code patterns
76216
+ - Performance considerations specific to {{LANGUAGE}}
76217
+
76218
+ ## Code Style
76219
+ - Follow {{LANGUAGE}} community conventions
76220
+ - Write clear, readable code
76221
+ - Use meaningful variable and function names
76222
+ - Add comments only when necessary
76223
+
76224
+ ## Common Patterns
76225
+ {{COMMON_PATTERNS}}
76226
+
76227
+ ## Best Practices
76228
+ {{BEST_PRACTICES}}
76229
+
76230
+ ## Testing
76231
+ - Testing frameworks for {{LANGUAGE}}
76232
+ - Writing testable code
76233
+ - Test organization and structure
76234
+
76235
+ When helping with {{LANGUAGE}}:
76236
+ 1. Follow modern {{LANGUAGE}} conventions
76237
+ 2. Use appropriate libraries and frameworks
76238
+ 3. Write idiomatic, clean code
76239
+ 4. Explain {{LANGUAGE}}-specific concepts`,
76240
+ variables: [
76241
+ {
76242
+ name: "LANGUAGE",
76243
+ label: "Programming Language",
76244
+ placeholder: "e.g., Rust, Go, Ruby, PHP",
76245
+ required: true
76246
+ },
76247
+ {
76248
+ name: "COMMON_PATTERNS",
76249
+ label: "Common Patterns",
76250
+ placeholder: "Describe common patterns in this language...",
76251
+ required: false
76252
+ },
76253
+ {
76254
+ name: "BEST_PRACTICES",
76255
+ label: "Best Practices",
76256
+ placeholder: "Describe best practices for this language...",
76257
+ required: false
76258
+ }
76259
+ ]
76260
+ },
76261
+ {
76262
+ id: "custom-framework",
76263
+ name: "Framework Expert",
76264
+ description: "Create a skill for a specific framework (React, Vue, Django, etc.)",
76265
+ category: "coding",
76266
+ prompt: `You are an expert in {{FRAMEWORK}} development. Your expertise includes:
76267
+
76268
+ ## {{FRAMEWORK}} Fundamentals
76269
+ - Framework architecture and design patterns
76270
+ - Component/model/view/controller structure
76271
+ - State management approaches
76272
+ - Routing and navigation
76273
+
76274
+ ## Best Practices
76275
+ - {{FRAMEWORK}} conventions and patterns
76276
+ - Performance optimization
76277
+ - Code organization and structure
76278
+ - Testing strategies
76279
+
76280
+ ## Common Tasks
76281
+ {{COMMON_TASKS}}
76282
+
76283
+ ## Ecosystem
76284
+ - Popular libraries and tools
76285
+ - Development workflow
76286
+ - Build and deployment
76287
+
76288
+ When working with {{FRAMEWORK}}:
76289
+ 1. Follow framework conventions
76290
+ 2. Use recommended patterns
76291
+ 3. Consider performance implications
76292
+ 4. Write maintainable code`,
76293
+ variables: [
76294
+ {
76295
+ name: "FRAMEWORK",
76296
+ label: "Framework Name",
76297
+ placeholder: "e.g., Laravel, Spring Boot, Express.js",
76298
+ required: true
76299
+ },
76300
+ {
76301
+ name: "COMMON_TASKS",
76302
+ label: "Common Tasks",
76303
+ placeholder: "List common tasks for this framework...",
76304
+ required: false
76305
+ }
76306
+ ]
76307
+ },
76308
+ {
76309
+ id: "custom-domain",
76310
+ name: "Domain Expert",
76311
+ description: "Create a skill for a specific domain (finance, healthcare, education, etc.)",
76312
+ category: "custom",
76313
+ prompt: `You are an expert in {{DOMAIN}}. Your expertise includes:
76314
+
76315
+ ## Domain Knowledge
76316
+ - {{DOMAIN}} terminology and concepts
76317
+ - Industry standards and regulations
76318
+ - Best practices and workflows
76319
+ - Common tools and technologies
76320
+
76321
+ ## Problem Solving
76322
+ - Typical {{DOMAIN}} challenges
76323
+ - Analytical approaches
76324
+ - Solution strategies
76325
+ - Decision-making frameworks
76326
+
76327
+ ## Communication
76328
+ - Explain {{DOMAIN}} concepts clearly
76329
+ - Use appropriate terminology
76330
+ - Provide context for technical decisions
76331
+ - Consider stakeholder needs
76332
+
76333
+ When helping with {{DOMAIN}}:
76334
+ 1. Understand the specific context
76335
+ 2. Apply domain-relevant knowledge
76336
+ 3. Consider industry standards
76337
+ 4. Explain domain-specific concepts`,
76338
+ variables: [
76339
+ {
76340
+ name: "DOMAIN",
76341
+ label: "Domain Name",
76342
+ placeholder: "e.g., Finance, Healthcare, E-commerce",
76343
+ required: true
76344
+ }
76345
+ ]
76346
+ },
76347
+ {
76348
+ id: "custom-tool",
76349
+ name: "Tool/CLI Expert",
76350
+ description: "Create a skill for a specific command-line tool or software",
76351
+ category: "system",
76352
+ prompt: `You are an expert in {{TOOL_NAME}}. Your expertise includes:
76353
+
76354
+ ## {{TOOL_NAME}} Overview
76355
+ - Tool purpose and use cases
76356
+ - Installation and setup
76357
+ - Basic commands and operations
76358
+ - Advanced features
76359
+
76360
+ ## Common Commands
76361
+ {{COMMON_COMMANDS}}
76362
+
76363
+ ## Best Practices
76364
+ - Efficient workflows
76365
+ - Common pitfalls and how to avoid them
76366
+ - Performance considerations
76367
+ - Integration with other tools
76368
+
76369
+ ## Troubleshooting
76370
+ - Common issues and solutions
76371
+ - Debugging techniques
76372
+ - Error interpretation
76373
+
76374
+ When helping with {{TOOL_NAME}}:
76375
+ 1. Provide clear command examples
76376
+ 2. Explain flags and options
76377
+ 3. Show expected output
76378
+ 4. Include troubleshooting tips`,
76379
+ variables: [
76380
+ {
76381
+ name: "TOOL_NAME",
76382
+ label: "Tool Name",
76383
+ placeholder: "e.g., Docker, Kubernetes, Git",
76384
+ required: true
76385
+ },
76386
+ {
76387
+ name: "COMMON_COMMANDS",
76388
+ label: "Common Commands",
76389
+ placeholder: "List common commands with examples...",
76390
+ required: false
76391
+ }
76392
+ ]
76393
+ },
76394
+ {
76395
+ id: "custom-language-learning",
76396
+ name: "Language Learning Assistant",
76397
+ description: "Create a skill for learning a human language",
76398
+ category: "creative",
76399
+ prompt: `You are a {{LANGUAGE}} language learning assistant. Your expertise includes:
76400
+
76401
+ ## Language Skills
76402
+ - {{LANGUAGE}} grammar and syntax
76403
+ - Vocabulary and expressions
76404
+ - Pronunciation guidance
76405
+ - Cultural context and nuances
76406
+
76407
+ ## Teaching Approach
76408
+ - Explain concepts clearly
76409
+ - Provide examples and practice
76410
+ - Correct mistakes gently
76411
+ - Encourage conversation practice
76412
+
76413
+ ## Learning Resources
76414
+ - Common learning materials
76415
+ - Practice exercises
76416
+ - Real-world usage examples
76417
+ - Tips for effective learning
76418
+
76419
+ When helping with {{LANGUAGE}}:
76420
+ 1. Assess current skill level
76421
+ 2. Provide appropriate level instruction
76422
+ 3. Use natural examples
76423
+ 4. Encourage practice and immersion`,
76424
+ variables: [
76425
+ {
76426
+ name: "LANGUAGE",
76427
+ label: "Language",
76428
+ placeholder: "e.g., Spanish, Japanese, German",
76429
+ required: true
76430
+ }
76431
+ ]
76432
+ }
76433
+ ];
76434
+ function renderTemplate(template, values) {
76435
+ let rendered = template.prompt;
76436
+ for (const variable of template.variables || []) {
76437
+ const value = values[variable.name] || "";
76438
+ const placeholder = `{{${variable.name}}}`;
76439
+ rendered = rendered.replace(new RegExp(placeholder, "g"), value);
76440
+ }
76441
+ return rendered;
76442
+ }
76443
+ const categories = [
76444
+ { value: "coding", label: "Coding", description: "Programming and development tasks" },
76445
+ { value: "analysis", label: "Analysis", description: "Data analysis and research" },
76446
+ { value: "creative", label: "Creative", description: "Writing and creative work" },
76447
+ { value: "data", label: "Data", description: "Database and data management" },
76448
+ { value: "system", label: "System", description: "System operations and debugging" },
76449
+ { value: "custom", label: "Custom", description: "Other specialized skills" }
76450
+ ];
76451
+ function CreateSkillDialog({ open, onClose, onCreate }) {
76452
+ const [mode, setMode] = reactExports.useState("custom");
76453
+ const [selectedTemplate, setSelectedTemplate] = reactExports.useState(null);
76454
+ const [templateValues, setTemplateValues] = reactExports.useState({});
76455
+ const [name2, setName] = reactExports.useState("");
76456
+ const [description, setDescription] = reactExports.useState("");
76457
+ const [category, setCategory] = reactExports.useState("custom");
76458
+ const [prompt, setPrompt] = reactExports.useState("");
76459
+ reactExports.useEffect(() => {
76460
+ if (!open) {
76461
+ setMode("custom");
76462
+ setSelectedTemplate(null);
76463
+ setTemplateValues({});
76464
+ setName("");
76465
+ setDescription("");
76466
+ setCategory("custom");
76467
+ setPrompt("");
76468
+ }
76469
+ }, [open]);
76470
+ reactExports.useEffect(() => {
76471
+ if (mode === "template" && selectedTemplate) {
76472
+ const template = SKILL_TEMPLATES.find((t) => t.id === selectedTemplate);
76473
+ if (template) {
76474
+ setCategory(template.category);
76475
+ setName(template.name.replace(/{{.*?}}/g, "Custom"));
76476
+ setDescription(template.description);
76477
+ setPrompt(template.prompt);
76478
+ }
76479
+ }
76480
+ }, [selectedTemplate, mode]);
76481
+ const handleSubmit = (e) => {
76482
+ e.preventDefault();
76483
+ const finalPrompt = mode === "template" && selectedTemplate ? renderTemplate(SKILL_TEMPLATES.find((t) => t.id === selectedTemplate), templateValues) : prompt;
76484
+ if (!name2.trim() || !description.trim() || !finalPrompt.trim()) {
76485
+ return;
76486
+ }
76487
+ onCreate({
76488
+ name: name2.trim(),
76489
+ description: description.trim(),
76490
+ category,
76491
+ prompt: finalPrompt.trim()
76492
+ });
76493
+ setMode("custom");
76494
+ setSelectedTemplate(null);
76495
+ setTemplateValues({});
76496
+ setName("");
76497
+ setDescription("");
76498
+ setCategory("custom");
76499
+ setPrompt("");
76500
+ onClose();
76501
+ };
76502
+ const currentTemplate = SKILL_TEMPLATES.find((t) => t.id === selectedTemplate);
76503
+ if (!open) return null;
76504
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full max-w-3xl mx-4 bg-[#1A1A1D] rounded-lg shadow-xl border border-white/10", children: [
76505
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-white/5", children: [
76506
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-white", children: "Create Custom Skill" }),
76507
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76508
+ "button",
76509
+ {
76510
+ onClick: onClose,
76511
+ className: "text-gray-400 hover:text-white transition-colors",
76512
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
76513
+ }
76514
+ )
76515
+ ] }),
76516
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-6 py-3 border-b border-white/5", children: [
76517
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76518
+ "button",
76519
+ {
76520
+ type: "button",
76521
+ onClick: () => setMode("custom"),
76522
+ className: `px-4 py-2 text-sm font-medium rounded-md transition-colors ${mode === "custom" ? "bg-blue-500 text-white" : "bg-white/5 text-gray-400 hover:bg-white/10"}`,
76523
+ children: "Custom"
76524
+ }
76525
+ ),
76526
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76527
+ "button",
76528
+ {
76529
+ type: "button",
76530
+ onClick: () => setMode("template"),
76531
+ className: `px-4 py-2 text-sm font-medium rounded-md transition-colors ${mode === "template" ? "bg-blue-500 text-white" : "bg-white/5 text-gray-400 hover:bg-white/10"}`,
76532
+ children: "From Template"
76533
+ }
76534
+ )
76535
+ ] }),
76536
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("form", { onSubmit: handleSubmit, className: "p-6 space-y-4", children: [
76537
+ mode === "template" && /* Template Selection */
76538
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76539
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-300 mb-2", children: "Choose Template" }),
76540
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-2 max-h-48 overflow-y-auto", children: SKILL_TEMPLATES.map((template) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
76541
+ "button",
76542
+ {
76543
+ type: "button",
76544
+ onClick: () => setSelectedTemplate(template.id),
76545
+ className: `px-3 py-2 text-left text-sm rounded-md transition-colors ${selectedTemplate === template.id ? "bg-blue-500/20 text-blue-400 border border-blue-500/50" : "bg-white/5 text-gray-400 border border-white/10 hover:bg-white/10"}`,
76546
+ children: [
76547
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: template.name }),
76548
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs opacity-75", children: template.description })
76549
+ ]
76550
+ },
76551
+ template.id
76552
+ )) })
76553
+ ] }),
76554
+ mode === "template" && currentTemplate && currentTemplate.variables && currentTemplate.variables.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3 p-4 bg-white/5 rounded-lg border border-white/10", children: [
76555
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-medium text-white", children: "Customize Template" }),
76556
+ currentTemplate.variables.map((variable) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76557
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm text-gray-300 mb-1", children: [
76558
+ variable.label,
76559
+ variable.required && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: " *" })
76560
+ ] }),
76561
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76562
+ "input",
76563
+ {
76564
+ type: "text",
76565
+ value: templateValues[variable.name] || "",
76566
+ onChange: (e) => setTemplateValues({ ...templateValues, [variable.name]: e.target.value }),
76567
+ placeholder: variable.placeholder,
76568
+ className: "w-full px-3 py-2 text-sm text-white placeholder-gray-500 bg-white/5 border border-white/10 rounded-md focus:outline-none focus:border-blue-500",
76569
+ required: variable.required
76570
+ }
76571
+ )
76572
+ ] }, variable.name))
76573
+ ] }),
76574
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76575
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-300 mb-1", children: [
76576
+ "Skill Name ",
76577
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
76578
+ ] }),
76579
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76580
+ "input",
76581
+ {
76582
+ type: "text",
76583
+ value: name2,
76584
+ onChange: (e) => setName(e.target.value),
76585
+ placeholder: "e.g., React Expert, Python Specialist",
76586
+ className: "w-full px-3 py-2 text-sm text-white placeholder-gray-500 bg-white/5 border border-white/10 rounded-md focus:outline-none focus:border-blue-500",
76587
+ required: true
76588
+ }
76589
+ )
76590
+ ] }),
76591
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76592
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-300 mb-1", children: [
76593
+ "Description ",
76594
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
76595
+ ] }),
76596
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76597
+ "input",
76598
+ {
76599
+ type: "text",
76600
+ value: description,
76601
+ onChange: (e) => setDescription(e.target.value),
76602
+ placeholder: "Brief description of what this skill does",
76603
+ className: "w-full px-3 py-2 text-sm text-white placeholder-gray-500 bg-white/5 border border-white/10 rounded-md focus:outline-none focus:border-blue-500",
76604
+ required: true
76605
+ }
76606
+ )
76607
+ ] }),
76608
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76609
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-300 mb-2", children: "Category" }),
76610
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-3 gap-2", children: categories.map((cat) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
76611
+ "button",
76612
+ {
76613
+ type: "button",
76614
+ onClick: () => setCategory(cat.value),
76615
+ className: `px-3 py-2 text-left text-sm rounded-md transition-colors ${category === cat.value ? "bg-blue-500/20 text-blue-400 border border-blue-500/50" : "bg-white/5 text-gray-400 border border-white/10 hover:bg-white/10"}`,
76616
+ children: [
76617
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: cat.label }),
76618
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs opacity-75", children: cat.description })
76619
+ ]
76620
+ },
76621
+ cat.value
76622
+ )) })
76623
+ ] }),
76624
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76625
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-300 mb-1", children: [
76626
+ "Specialized Prompt ",
76627
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
76628
+ ] }),
76629
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76630
+ "textarea",
76631
+ {
76632
+ value: prompt,
76633
+ onChange: (e) => setPrompt(e.target.value),
76634
+ placeholder: "Enter the specialized instructions and expertise for this skill...",
76635
+ rows: 8,
76636
+ className: "w-full px-3 py-2 text-sm text-white placeholder-gray-500 bg-white/5 border border-white/10 rounded-md focus:outline-none focus:border-blue-500 resize-none",
76637
+ required: true
76638
+ }
76639
+ ),
76640
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-gray-500", children: "This prompt will be loaded when the agent activates this skill, providing specialized knowledge and instructions." })
76641
+ ] }),
76642
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-3 pt-4 border-t border-white/5", children: [
76643
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76644
+ "button",
76645
+ {
76646
+ type: "button",
76647
+ onClick: onClose,
76648
+ className: "px-4 py-2 text-sm text-gray-400 hover:text-white transition-colors",
76649
+ children: "Cancel"
76650
+ }
76651
+ ),
76652
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76653
+ "button",
76654
+ {
76655
+ type: "submit",
76656
+ disabled: !name2.trim() || !description.trim() || !prompt.trim(),
76657
+ className: "px-4 py-2 text-sm text-white bg-blue-500 hover:bg-blue-600 disabled:bg-gray-600 disabled:cursor-not-allowed rounded-md transition-colors",
76658
+ children: "Create Skill"
76659
+ }
76660
+ )
76661
+ ] })
76662
+ ] })
76663
+ ] }) });
76664
+ }
76665
+ const categoryColors = {
76666
+ coding: "bg-blue-500/10 text-blue-500 border-blue-500/20",
76667
+ analysis: "bg-purple-500/10 text-purple-500 border-purple-500/20",
76668
+ creative: "bg-pink-500/10 text-pink-500 border-pink-500/20",
76669
+ data: "bg-green-500/10 text-green-500 border-green-500/20",
76670
+ system: "bg-orange-500/10 text-orange-500 border-orange-500/20",
76671
+ custom: "bg-cyan-500/10 text-cyan-500 border-cyan-500/20"
76672
+ };
76673
+ function SkillDetailDialog({ skill, open, onClose, onToggle, onDelete }) {
76674
+ if (!open) return null;
76675
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full max-w-3xl mx-4 max-h-[80vh] bg-[#1A1A1D] rounded-lg shadow-xl border border-white/10 flex flex-col", children: [
76676
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between px-6 py-4 border-b border-white/5", children: [
76677
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
76678
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [
76679
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-xl font-semibold text-white", children: skill.name }),
76680
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76681
+ "span",
76682
+ {
76683
+ className: `px-2 py-0.5 text-xs font-medium rounded border ${categoryColors[skill.category] || categoryColors.custom}`,
76684
+ children: skill.category
76685
+ }
76686
+ ),
76687
+ skill.isBuiltin && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2 py-0.5 text-xs font-medium rounded bg-white/5 text-gray-400 border border-white/10", children: "Built-in" })
76688
+ ] }),
76689
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-400", children: skill.description })
76690
+ ] }),
76691
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76692
+ "button",
76693
+ {
76694
+ onClick: onClose,
76695
+ className: "ml-4 text-gray-400 hover:text-white transition-colors",
76696
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
76697
+ }
76698
+ )
76699
+ ] }),
76700
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto px-6 py-4", children: [
76701
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-4 mb-6", children: [
76702
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white/5 rounded-lg p-3 border border-white/5", children: [
76703
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 mb-1", children: "Status" }),
76704
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-medium text-white", children: skill.enabled ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-green-400", children: "Enabled" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-400", children: "Disabled" }) })
76705
+ ] }),
76706
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white/5 rounded-lg p-3 border border-white/5", children: [
76707
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 mb-1", children: "Type" }),
76708
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-medium text-white", children: skill.isBuiltin ? "Built-in Skill" : "Custom Skill" })
76709
+ ] })
76710
+ ] }),
76711
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [
76712
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium text-gray-300 mb-2", children: "Specialized Prompt" }),
76713
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-white/5 rounded-lg p-4 border border-white/5", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-sm text-gray-300 whitespace-pre-wrap font-mono", children: skill.prompt }) })
76714
+ ] }),
76715
+ skill.subSkills && skill.subSkills.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76716
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium text-gray-300 mb-2", children: "Sub Skills" }),
76717
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-2", children: skill.subSkills.map((subSkill) => /* @__PURE__ */ jsxRuntimeExports.jsx(
76718
+ "span",
76719
+ {
76720
+ className: "px-3 py-1 text-sm bg-white/5 text-gray-300 rounded-md border border-white/10",
76721
+ children: subSkill
76722
+ },
76723
+ subSkill
76724
+ )) })
76725
+ ] })
76726
+ ] }),
76727
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-t border-white/5", children: [
76728
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-gray-500", children: [
76729
+ "Created: ",
76730
+ new Date(skill.createdAt).toLocaleDateString(),
76731
+ " • Updated:",
76732
+ " ",
76733
+ new Date(skill.updatedAt).toLocaleDateString()
76734
+ ] }),
76735
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
76736
+ !skill.isBuiltin && onDelete && /* @__PURE__ */ jsxRuntimeExports.jsx(
76737
+ "button",
76738
+ {
76739
+ onClick: () => {
76740
+ if (confirm(`Are you sure you want to delete "${skill.name}"?`)) {
76741
+ onDelete(skill.id);
76742
+ onClose();
76743
+ }
76744
+ },
76745
+ className: "px-4 py-2 text-sm text-red-400 hover:text-red-300 hover:bg-red-500/10 rounded-md transition-colors",
76746
+ children: "Delete"
76747
+ }
76748
+ ),
76749
+ onToggle && /* @__PURE__ */ jsxRuntimeExports.jsx(
76750
+ "button",
76751
+ {
76752
+ onClick: () => onToggle(skill.id, !skill.enabled),
76753
+ className: `px-4 py-2 text-sm rounded-md transition-colors ${skill.enabled ? "bg-white/10 text-gray-300 hover:bg-white/15" : "bg-blue-500 text-white hover:bg-blue-600"}`,
76754
+ children: skill.enabled ? "Disable" : "Enable"
76755
+ }
76756
+ ),
76757
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76758
+ "button",
76759
+ {
76760
+ onClick: onClose,
76761
+ className: "px-4 py-2 text-sm text-white bg-white/10 hover:bg-white/15 rounded-md transition-colors",
76762
+ children: "Close"
76763
+ }
76764
+ )
76765
+ ] })
76766
+ ] })
76767
+ ] }) });
76768
+ }
76769
+ function SkillsPanel(_props) {
76770
+ const [skills, setSkills] = reactExports.useState([]);
76771
+ const [loading, setLoading] = reactExports.useState(true);
76772
+ const [filter, setFilter] = reactExports.useState("all");
76773
+ const [searchQuery, setSearchQuery] = reactExports.useState("");
76774
+ const [showCreateDialog, setShowCreateDialog] = reactExports.useState(false);
76775
+ const [selectedSkill, setSelectedSkill] = reactExports.useState(null);
76776
+ reactExports.useEffect(() => {
76777
+ loadSkills();
76778
+ }, []);
76779
+ const loadSkills = async () => {
76780
+ setLoading(true);
76781
+ try {
76782
+ const result = await window.api.skills.list();
76783
+ if (result.success && result.skills) {
76784
+ setSkills(result.skills);
76785
+ }
76786
+ } catch (error) {
76787
+ console.error("Failed to load skills:", error);
76788
+ } finally {
76789
+ setLoading(false);
76790
+ }
76791
+ };
76792
+ const toggleSkill = async (skillId, enabled) => {
76793
+ const result = await window.api.skills.toggle(skillId, enabled);
76794
+ if (result.success) {
76795
+ setSkills(
76796
+ (prev) => prev.map((s2) => s2.id === skillId ? { ...s2, enabled: result.enabled ?? false } : s2)
76797
+ );
76798
+ }
76799
+ };
76800
+ const handleCreateSkill = async (skill) => {
76801
+ const result = await window.api.skills.create(skill);
76802
+ if (result.success) {
76803
+ loadSkills();
76804
+ }
76805
+ };
76806
+ const handleDeleteSkill = async (skillId) => {
76807
+ const result = await window.api.skills.delete(skillId);
76808
+ if (result.success) {
76809
+ loadSkills();
76810
+ }
76811
+ };
76812
+ const filteredSkills = skills.filter((skill) => {
76813
+ if (searchQuery) {
76814
+ const query = searchQuery.toLowerCase();
76815
+ if (!skill.name.toLowerCase().includes(query) && !skill.description.toLowerCase().includes(query)) {
76816
+ return false;
76817
+ }
76818
+ }
76819
+ if (filter === "enabled") return skill.enabled;
76820
+ if (filter === "builtin") return skill.isBuiltin;
76821
+ if (filter === "user") return !skill.isBuiltin;
76822
+ return true;
76823
+ });
76824
+ const groupedSkills = filteredSkills.reduce(
76825
+ (acc, skill) => {
76826
+ if (!acc[skill.category]) {
76827
+ acc[skill.category] = [];
76828
+ }
76829
+ acc[skill.category].push(skill);
76830
+ return acc;
76831
+ },
76832
+ {}
76833
+ );
76834
+ const categoryColors2 = {
76835
+ coding: "bg-blue-500/10 text-blue-500",
76836
+ analysis: "bg-purple-500/10 text-purple-500",
76837
+ creative: "bg-pink-500/10 text-pink-500",
76838
+ data: "bg-green-500/10 text-green-500",
76839
+ system: "bg-orange-500/10 text-orange-500",
76840
+ custom: "bg-cyan-500/10 text-cyan-500"
76841
+ };
76842
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
76843
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full bg-[#0D0D0F]", children: [
76844
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-white/5", children: [
76845
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-white", children: "Skills" }),
76846
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
76847
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76848
+ "button",
76849
+ {
76850
+ onClick: () => setShowCreateDialog(true),
76851
+ className: "px-3 py-1 text-xs font-medium text-white bg-blue-500 hover:bg-blue-600 rounded-md transition-colors",
76852
+ children: "+ New Skill"
76853
+ }
76854
+ ),
76855
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-gray-400", children: [
76856
+ skills.filter((s2) => s2.enabled).length,
76857
+ " / ",
76858
+ skills.length,
76859
+ " enabled"
76860
+ ] })
76861
+ ] })
76862
+ ] }),
76863
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 px-4 py-3 border-b border-white/5", children: [
76864
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76865
+ "input",
76866
+ {
76867
+ type: "text",
76868
+ placeholder: "Search skills...",
76869
+ value: searchQuery,
76870
+ onChange: (e) => setSearchQuery(e.target.value),
76871
+ className: "w-full px-3 py-2 text-sm text-white placeholder-gray-500 bg-white/5 border border-white/10 rounded-md focus:outline-none focus:border-white/20"
76872
+ }
76873
+ ),
76874
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-2", children: ["all", "enabled", "builtin", "user"].map((f2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
76875
+ "button",
76876
+ {
76877
+ onClick: () => setFilter(f2),
76878
+ className: `px-3 py-1 text-xs rounded-md transition-colors ${filter === f2 ? "bg-white/10 text-white" : "text-gray-400 hover:text-white hover:bg-white/5"}`,
76879
+ children: f2.charAt(0).toUpperCase() + f2.slice(1)
76880
+ },
76881
+ f2
76882
+ )) })
76883
+ ] }),
76884
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4", children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-32", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-400", children: "Loading skills..." }) }) : filteredSkills.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col items-center justify-center h-32 text-gray-400", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: "No skills found" }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: Object.entries(groupedSkills).map(([category, categorySkills]) => {
76885
+ const skillsList = categorySkills;
76886
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76887
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium text-gray-300 mb-2 capitalize", children: category }),
76888
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: skillsList.map((skill) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
76889
+ "div",
76890
+ {
76891
+ onClick: () => setSelectedSkill(skill),
76892
+ className: "flex items-start justify-between p-3 rounded-lg bg-white/5 hover:bg-white/10 transition-colors cursor-pointer",
76893
+ children: [
76894
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
76895
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [
76896
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-medium text-white", children: skill.name }),
76897
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76898
+ Badge,
76899
+ {
76900
+ className: categoryColors2[skill.category] || categoryColors2.custom,
76901
+ children: skill.category
76902
+ }
76903
+ ),
76904
+ skill.isBuiltin && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { className: "bg-white/5 text-gray-400 text-xs", children: "Built-in" })
76905
+ ] }),
76906
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 line-clamp-2", children: skill.description })
76907
+ ] }),
76908
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76909
+ Switch,
76910
+ {
76911
+ checked: skill.enabled,
76912
+ onCheckedChange: (checked) => {
76913
+ toggleSkill(skill.id, checked);
76914
+ },
76915
+ onClick: (e) => e.stopPropagation(),
76916
+ className: "ml-3 flex-shrink-0"
76917
+ }
76918
+ )
76919
+ ]
76920
+ },
76921
+ skill.id
76922
+ )) })
76923
+ ] }, category);
76924
+ }) }) }) })
76925
+ ] }),
76926
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76927
+ CreateSkillDialog,
76928
+ {
76929
+ open: showCreateDialog,
76930
+ onClose: () => setShowCreateDialog(false),
76931
+ onCreate: handleCreateSkill
76932
+ }
76933
+ ),
76934
+ selectedSkill && /* @__PURE__ */ jsxRuntimeExports.jsx(
76935
+ SkillDetailDialog,
76936
+ {
76937
+ skill: selectedSkill,
76938
+ open: !!selectedSkill,
76939
+ onClose: () => setSelectedSkill(null),
76940
+ onToggle: toggleSkill,
76941
+ onDelete: handleDeleteSkill
76942
+ }
76943
+ )
76944
+ ] });
76945
+ }
76158
76946
  const HEADER_HEIGHT = 40;
76159
76947
  const HANDLE_HEIGHT = 6;
76160
76948
  const MIN_CONTENT_HEIGHT = 60;
@@ -76232,38 +77020,43 @@ function RightPanel() {
76232
77020
  const [tasksOpen, setTasksOpen] = reactExports.useState(true);
76233
77021
  const [filesOpen, setFilesOpen] = reactExports.useState(true);
76234
77022
  const [agentsOpen, setAgentsOpen] = reactExports.useState(true);
77023
+ const [skillsOpen, setSkillsOpen] = reactExports.useState(false);
76235
77024
  const [tasksHeight, setTasksHeight] = reactExports.useState(null);
76236
77025
  const [filesHeight, setFilesHeight] = reactExports.useState(null);
76237
77026
  const [agentsHeight, setAgentsHeight] = reactExports.useState(null);
77027
+ const [skillsHeight, setSkillsHeight] = reactExports.useState(null);
76238
77028
  const dragStartHeights = reactExports.useRef(null);
76239
77029
  const getAvailableContentHeight = reactExports.useCallback(() => {
76240
77030
  if (!containerRef.current) return 0;
76241
77031
  const totalHeight = containerRef.current.clientHeight;
76242
- let used = HEADER_HEIGHT * 3;
76243
- if (tasksOpen && (filesOpen || agentsOpen)) used += HANDLE_HEIGHT;
76244
- if (filesOpen && agentsOpen) used += HANDLE_HEIGHT;
77032
+ let used = HEADER_HEIGHT * 4;
77033
+ const openPanels = [tasksOpen, filesOpen, agentsOpen, skillsOpen].filter(Boolean).length;
77034
+ used += HANDLE_HEIGHT * (openPanels - 1);
76245
77035
  return Math.max(0, totalHeight - used);
76246
- }, [tasksOpen, filesOpen, agentsOpen]);
77036
+ }, [tasksOpen, filesOpen, agentsOpen, skillsOpen]);
76247
77037
  const getContentHeights = reactExports.useCallback(() => {
76248
77038
  const available = getAvailableContentHeight();
76249
- const openCount = [tasksOpen, filesOpen, agentsOpen].filter(Boolean).length;
77039
+ const openCount = [tasksOpen, filesOpen, agentsOpen, skillsOpen].filter(Boolean).length;
76250
77040
  if (openCount === 0) {
76251
- return { tasks: 0, files: 0, agents: 0 };
77041
+ return { tasks: 0, files: 0, agents: 0, skills: 0 };
76252
77042
  }
76253
77043
  const defaultHeight = available / openCount;
76254
77044
  return {
76255
77045
  tasks: tasksOpen ? tasksHeight ?? defaultHeight : 0,
76256
77046
  files: filesOpen ? filesHeight ?? defaultHeight : 0,
76257
- agents: agentsOpen ? agentsHeight ?? defaultHeight : 0
77047
+ agents: agentsOpen ? agentsHeight ?? defaultHeight : 0,
77048
+ skills: skillsOpen ? skillsHeight ?? defaultHeight : 0
76258
77049
  };
76259
77050
  }, [
76260
77051
  getAvailableContentHeight,
76261
77052
  tasksOpen,
76262
77053
  filesOpen,
76263
77054
  agentsOpen,
77055
+ skillsOpen,
76264
77056
  tasksHeight,
76265
77057
  filesHeight,
76266
- agentsHeight
77058
+ agentsHeight,
77059
+ skillsHeight
76267
77060
  ]);
76268
77061
  const handleTasksResize = reactExports.useCallback(
76269
77062
  (totalDelta) => {
@@ -76273,7 +77066,12 @@ function RightPanel() {
76273
77066
  }
76274
77067
  const start = dragStartHeights.current;
76275
77068
  const available = getAvailableContentHeight();
76276
- const otherStart = filesOpen ? start.files : start.agents;
77069
+ let nextPanel = null;
77070
+ if (filesOpen) nextPanel = "files";
77071
+ else if (agentsOpen) nextPanel = "agents";
77072
+ else if (skillsOpen) nextPanel = "skills";
77073
+ if (!nextPanel) return;
77074
+ const otherStart = start[nextPanel];
76277
77075
  let newTasksHeight = start.tasks + totalDelta;
76278
77076
  let newOtherHeight = otherStart - totalDelta;
76279
77077
  if (newTasksHeight < MIN_CONTENT_HEIGHT) {
@@ -76284,8 +77082,8 @@ function RightPanel() {
76284
77082
  newOtherHeight = MIN_CONTENT_HEIGHT;
76285
77083
  newTasksHeight = start.tasks + (otherStart - MIN_CONTENT_HEIGHT);
76286
77084
  }
76287
- const thirdPanelHeight = filesOpen && agentsOpen ? agentsHeight ?? available / 3 : 0;
76288
- const maxForTwo = available - thirdPanelHeight;
77085
+ const belowHeight = nextPanel === "files" && (agentsOpen || skillsOpen) ? (agentsOpen ? agentsHeight ?? available / 4 : 0) + (skillsOpen ? skillsHeight ?? available / 4 : 0) : nextPanel === "agents" && skillsOpen ? skillsHeight ?? available / 4 : 0;
77086
+ const maxForTwo = available - belowHeight;
76289
77087
  if (newTasksHeight + newOtherHeight > maxForTwo) {
76290
77088
  const excess = newTasksHeight + newOtherHeight - maxForTwo;
76291
77089
  if (totalDelta > 0) {
@@ -76295,20 +77093,19 @@ function RightPanel() {
76295
77093
  }
76296
77094
  }
76297
77095
  setTasksHeight(newTasksHeight);
76298
- if (filesOpen) {
76299
- setFilesHeight(newOtherHeight);
76300
- } else if (agentsOpen) {
76301
- setAgentsHeight(newOtherHeight);
76302
- }
77096
+ if (nextPanel === "files") setFilesHeight(newOtherHeight);
77097
+ else if (nextPanel === "agents") setAgentsHeight(newOtherHeight);
77098
+ else if (nextPanel === "skills") setSkillsHeight(newOtherHeight);
76303
77099
  if (newTasksHeight < COLLAPSE_THRESHOLD) {
76304
77100
  setTasksOpen(false);
76305
77101
  }
76306
77102
  if (newOtherHeight < COLLAPSE_THRESHOLD) {
76307
- if (filesOpen) setFilesOpen(false);
76308
- else if (agentsOpen) setAgentsOpen(false);
77103
+ if (nextPanel === "files") setFilesOpen(false);
77104
+ else if (nextPanel === "agents") setAgentsOpen(false);
77105
+ else if (nextPanel === "skills") setSkillsOpen(false);
76309
77106
  }
76310
77107
  },
76311
- [getContentHeights, getAvailableContentHeight, filesOpen, agentsOpen, agentsHeight]
77108
+ [getContentHeights, getAvailableContentHeight, filesOpen, agentsOpen, skillsOpen, agentsHeight, skillsHeight]
76312
77109
  );
76313
77110
  const handleFilesResize = reactExports.useCallback(
76314
77111
  (totalDelta) => {
@@ -76318,36 +77115,83 @@ function RightPanel() {
76318
77115
  }
76319
77116
  const start = dragStartHeights.current;
76320
77117
  const available = getAvailableContentHeight();
76321
- const tasksH = tasksOpen ? tasksHeight ?? available / 3 : 0;
76322
- const maxForFilesAndAgents = available - tasksH;
77118
+ const tasksH = tasksOpen ? tasksHeight ?? available / 4 : 0;
77119
+ let nextPanel = null;
77120
+ if (agentsOpen) nextPanel = "agents";
77121
+ else if (skillsOpen) nextPanel = "skills";
77122
+ if (!nextPanel) return;
77123
+ const maxForFilesAndNext = available - tasksH;
76323
77124
  let newFilesHeight = start.files + totalDelta;
76324
- let newAgentsHeight = start.agents - totalDelta;
77125
+ let newNextHeight = start[nextPanel] - totalDelta;
76325
77126
  if (newFilesHeight < MIN_CONTENT_HEIGHT) {
76326
77127
  newFilesHeight = MIN_CONTENT_HEIGHT;
76327
- newAgentsHeight = start.agents + (start.files - MIN_CONTENT_HEIGHT);
77128
+ newNextHeight = start[nextPanel] + (start.files - MIN_CONTENT_HEIGHT);
76328
77129
  }
76329
- if (newAgentsHeight < MIN_CONTENT_HEIGHT) {
76330
- newAgentsHeight = MIN_CONTENT_HEIGHT;
76331
- newFilesHeight = start.files + (start.agents - MIN_CONTENT_HEIGHT);
77130
+ if (newNextHeight < MIN_CONTENT_HEIGHT) {
77131
+ newNextHeight = MIN_CONTENT_HEIGHT;
77132
+ newFilesHeight = start.files + (start[nextPanel] - MIN_CONTENT_HEIGHT);
76332
77133
  }
76333
- if (newFilesHeight + newAgentsHeight > maxForFilesAndAgents) {
76334
- const excess = newFilesHeight + newAgentsHeight - maxForFilesAndAgents;
77134
+ if (newFilesHeight + newNextHeight > maxForFilesAndNext) {
77135
+ const excess = newFilesHeight + newNextHeight - maxForFilesAndNext;
76335
77136
  if (totalDelta > 0) {
76336
- newAgentsHeight = Math.max(MIN_CONTENT_HEIGHT, newAgentsHeight - excess);
77137
+ newNextHeight = Math.max(MIN_CONTENT_HEIGHT, newNextHeight - excess);
76337
77138
  } else {
76338
77139
  newFilesHeight = Math.max(MIN_CONTENT_HEIGHT, newFilesHeight - excess);
76339
77140
  }
76340
77141
  }
76341
77142
  setFilesHeight(newFilesHeight);
76342
- setAgentsHeight(newAgentsHeight);
77143
+ if (nextPanel === "agents") setAgentsHeight(newNextHeight);
77144
+ else if (nextPanel === "skills") setSkillsHeight(newNextHeight);
76343
77145
  if (newFilesHeight < COLLAPSE_THRESHOLD) {
76344
77146
  setFilesOpen(false);
76345
77147
  }
77148
+ if (newNextHeight < COLLAPSE_THRESHOLD) {
77149
+ if (nextPanel === "agents") setAgentsOpen(false);
77150
+ else if (nextPanel === "skills") setSkillsOpen(false);
77151
+ }
77152
+ },
77153
+ [getContentHeights, getAvailableContentHeight, tasksOpen, tasksHeight, agentsOpen, skillsOpen]
77154
+ );
77155
+ const handleAgentsResize = reactExports.useCallback(
77156
+ (totalDelta) => {
77157
+ if (!dragStartHeights.current) {
77158
+ const heights2 = getContentHeights();
77159
+ dragStartHeights.current = { ...heights2 };
77160
+ }
77161
+ const start = dragStartHeights.current;
77162
+ const available = getAvailableContentHeight();
77163
+ const tasksH = tasksOpen ? tasksHeight ?? available / 4 : 0;
77164
+ const filesH = filesOpen ? filesHeight ?? available / 4 : 0;
77165
+ const aboveHeight = tasksH + filesH;
77166
+ const maxForAgentsAndSkills = available - aboveHeight;
77167
+ let newAgentsHeight = start.agents + totalDelta;
77168
+ let newSkillsHeight = start.skills - totalDelta;
77169
+ if (newAgentsHeight < MIN_CONTENT_HEIGHT) {
77170
+ newAgentsHeight = MIN_CONTENT_HEIGHT;
77171
+ newSkillsHeight = start.skills + (start.agents - MIN_CONTENT_HEIGHT);
77172
+ }
77173
+ if (newSkillsHeight < MIN_CONTENT_HEIGHT) {
77174
+ newSkillsHeight = MIN_CONTENT_HEIGHT;
77175
+ newAgentsHeight = start.agents + (start.skills - MIN_CONTENT_HEIGHT);
77176
+ }
77177
+ if (newAgentsHeight + newSkillsHeight > maxForAgentsAndSkills) {
77178
+ const excess = newAgentsHeight + newSkillsHeight - maxForAgentsAndSkills;
77179
+ if (totalDelta > 0) {
77180
+ newSkillsHeight = Math.max(MIN_CONTENT_HEIGHT, newSkillsHeight - excess);
77181
+ } else {
77182
+ newAgentsHeight = Math.max(MIN_CONTENT_HEIGHT, newAgentsHeight - excess);
77183
+ }
77184
+ }
77185
+ setAgentsHeight(newAgentsHeight);
77186
+ setSkillsHeight(newSkillsHeight);
76346
77187
  if (newAgentsHeight < COLLAPSE_THRESHOLD) {
76347
77188
  setAgentsOpen(false);
76348
77189
  }
77190
+ if (newSkillsHeight < COLLAPSE_THRESHOLD) {
77191
+ setSkillsOpen(false);
77192
+ }
76349
77193
  },
76350
- [getContentHeights, getAvailableContentHeight, tasksOpen, tasksHeight]
77194
+ [getContentHeights, getAvailableContentHeight, tasksOpen, filesOpen, tasksHeight, filesHeight]
76351
77195
  );
76352
77196
  reactExports.useEffect(() => {
76353
77197
  const handleMouseUp = () => {
@@ -76360,8 +77204,9 @@ function RightPanel() {
76360
77204
  setTasksHeight(null);
76361
77205
  setFilesHeight(null);
76362
77206
  setAgentsHeight(null);
76363
- }, [tasksOpen, filesOpen, agentsOpen]);
76364
- const [heights, setHeights] = reactExports.useState({ tasks: 0, files: 0, agents: 0 });
77207
+ setSkillsHeight(null);
77208
+ }, [tasksOpen, filesOpen, agentsOpen, skillsOpen]);
77209
+ const [heights, setHeights] = reactExports.useState({ tasks: 0, files: 0, agents: 0, skills: 0 });
76365
77210
  reactExports.useEffect(() => {
76366
77211
  setHeights(getContentHeights());
76367
77212
  }, [getContentHeights]);
@@ -76384,7 +77229,7 @@ function RightPanel() {
76384
77229
  ),
76385
77230
  tasksOpen && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-auto", style: { height: heights.tasks }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(TasksContent, {}) })
76386
77231
  ] }),
76387
- tasksOpen && (filesOpen || agentsOpen) && /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle$1, { onDrag: handleTasksResize }),
77232
+ tasksOpen && (filesOpen || agentsOpen || skillsOpen) && /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle$1, { onDrag: handleTasksResize }),
76388
77233
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col shrink-0 border-b border-border", children: [
76389
77234
  /* @__PURE__ */ jsxRuntimeExports.jsx(
76390
77235
  SectionHeader,
@@ -76398,8 +77243,8 @@ function RightPanel() {
76398
77243
  ),
76399
77244
  filesOpen && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-auto", style: { height: heights.files }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(FilesContent, {}) })
76400
77245
  ] }),
76401
- filesOpen && agentsOpen && /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle$1, { onDrag: handleFilesResize }),
76402
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col shrink-0", children: [
77246
+ filesOpen && (agentsOpen || skillsOpen) && /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle$1, { onDrag: handleFilesResize }),
77247
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col shrink-0 border-b border-border", children: [
76403
77248
  /* @__PURE__ */ jsxRuntimeExports.jsx(
76404
77249
  SectionHeader,
76405
77250
  {
@@ -76411,6 +77256,19 @@ function RightPanel() {
76411
77256
  }
76412
77257
  ),
76413
77258
  agentsOpen && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-auto", style: { height: heights.agents }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(AgentsContent, {}) })
77259
+ ] }),
77260
+ agentsOpen && skillsOpen && /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle$1, { onDrag: handleAgentsResize }),
77261
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col shrink-0", children: [
77262
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
77263
+ SectionHeader,
77264
+ {
77265
+ title: "SKILLS",
77266
+ icon: Sparkles,
77267
+ isOpen: skillsOpen,
77268
+ onToggle: () => setSkillsOpen((prev) => !prev)
77269
+ }
77270
+ ),
77271
+ skillsOpen && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-auto", style: { height: heights.skills }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(SkillsContent, {}) })
76414
77272
  ] })
76415
77273
  ]
76416
77274
  }
@@ -76832,6 +77690,9 @@ function AgentsContent() {
76832
77690
  agent.description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground mt-1", children: agent.description })
76833
77691
  ] }, agent.id)) });
76834
77692
  }
77693
+ function SkillsContent() {
77694
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(SkillsPanel, {});
77695
+ }
76835
77696
  function formatSize(bytes) {
76836
77697
  if (bytes < 1024) return `${bytes}B`;
76837
77698
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
@@ -77259,7 +78120,7 @@ function App() {
77259
78120
  },
77260
78121
  children: [
77261
78122
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-name", children: "OPENWORK" }),
77262
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.2.2" })
78123
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.2.3" })
77263
78124
  ]
77264
78125
  }
77265
78126
  ),