@wipal/agent-team 1.2.2 → 1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipal/agent-team",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "CLI tool to add AI agent teams to existing projects with specialized roles, skills, and workflows (v2.1 with OpenFang patterns)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -45,8 +45,14 @@
45
45
  <span class="agent-role" x-text="agent.variants?.base_role || 'unknown'"></span>
46
46
  </div>
47
47
  <div class="agent-variants">
48
- <template x-for="(value, key) in agent.variants" :key="key">
49
- <span class="variant-tag" x-text="key + ': ' + value"></span>
48
+ <template x-for="(value, key) in agent.variants" :key="key + 'variant-' + key">
49
+ <template x-if="Array.isArray(value)">
50
+ <template x-for="v in value" :key="v">
51
+ <span class="variant-tag" x-text="key + ': ' + v"></span>
52
+ </template>
53
+ <template x-else>
54
+ <span class="variant-tag" x-text="key + ': ' + value"></span>
55
+ </template>
50
56
  </template>
51
57
  </div>
52
58
  <div class="agent-skills" x-show="agent.skills?.length">
@@ -93,20 +99,39 @@
93
99
  <small class="hint" x-show="selectedRoleDescription" x-text="selectedRoleDescription"></small>
94
100
  </div>
95
101
 
96
- <!-- Step 3: Select Variants (Dropdowns) -->
102
+ <!-- Step 3: Select Variants (Dropdowns or Checkboxes) -->
97
103
  <div x-show="newAgent.role && Object.keys(variantCategories).length > 0" x-cloak class="variants-section">
98
104
  <h3>Select Variants (Optional)</h3>
99
105
  <template x-for="(category, key) in variantCategories" :key="key">
100
106
  <div class="form-group">
101
107
  <label x-text="category.label"></label>
102
- <select class="input" @change="selectVariant(key, $event.target.value)">
103
- <option value="">-- Select --</option>
104
- <template x-for="option in category.options" :key="option.value">
105
- <option :value="option.value"
106
- :selected="newAgent.variants[key] === option.value"
107
- x-text="option.label"></option>
108
- </template>
109
- </select>
108
+
109
+ <!-- Multi-select (checkbox type) -->
110
+ <template x-if="category.type === 'checkbox'">
111
+ <div class="checkbox-group">
112
+ <template x-for="option in category.options" :key="option.value">
113
+ <label class="checkbox-label">
114
+ <input type="checkbox"
115
+ :value="option.value"
116
+ @change="selectVariant(key, option.value, true)"
117
+ :checked="isVariantSelected(key, option.value)">
118
+ <span x-text="option.label"></span>
119
+ </label>
120
+ </template>
121
+ </div>
122
+ </template>
123
+
124
+ <!-- Single-select (select type) -->
125
+ <template x-if="category.type !== 'checkbox'">
126
+ <select class="input" @change="selectVariant(key, $event.target.value, false)">
127
+ <option value="">-- Select --</option>
128
+ <template x-for="option in category.options" :key="option.value">
129
+ <option :value="option.value"
130
+ :selected="newAgent.variants[key] === option.value"
131
+ x-text="option.label"></option>
132
+ </template>
133
+ </select>
134
+ </template>
110
135
  </div>
111
136
  </template>
112
137
  </div>
@@ -236,12 +261,41 @@
236
261
  }
237
262
  },
238
263
 
239
- async selectVariant(category, value) {
240
- if (value) {
241
- this.newAgent.variants[category] = value;
264
+ isVariantSelected(category, value) {
265
+ const selected = this.newAgent.variants[category];
266
+ if (Array.isArray(selected)) {
267
+ return selected.includes(value);
268
+ }
269
+ return selected === value;
270
+ },
271
+
272
+ async selectVariant(category, value, isMulti = false) {
273
+ if (isMulti) {
274
+ // Multi-select: toggle value in array
275
+ if (!this.newAgent.variants[category]) {
276
+ this.newAgent.variants[category] = [];
277
+ }
278
+
279
+ const index = this.newAgent.variants[category].indexOf(value);
280
+ if (index > -1) {
281
+ // Remove if already selected
282
+ this.newAgent.variants[category].splice(index, 1);
283
+ if (this.newAgent.variants[category].length === 0) {
284
+ delete this.newAgent.variants[category];
285
+ }
286
+ } else {
287
+ // Add if not selected
288
+ this.newAgent.variants[category].push(value);
289
+ }
242
290
  } else {
243
- delete this.newAgent.variants[category];
291
+ // Single select: replace value
292
+ if (value) {
293
+ this.newAgent.variants[category] = value
294
+ } else {
295
+ delete this.newAgent.variants[category];
296
+ }
244
297
  }
298
+
245
299
  // Update skills preview
246
300
  await this.loadSkillsPreview();
247
301
  },
@@ -299,7 +353,9 @@
299
353
  this.newAgent = { name: '', role: '', variants: {} };
300
354
  this.variantCategories = {};
301
355
  this.previewSkills = [];
302
- }
356
+ // Force Alpine to re-render by reassigning
357
+ this.$forceUpdate();
358
+ },
303
359
  }
304
360
  }
305
361
  </script>
@@ -568,6 +568,60 @@ body {
568
568
  color: var(--text-muted);
569
569
  }
570
570
 
571
+ /* Checkbox group for multi-select variants */
572
+ .checkbox-group {
573
+ display: flex;
574
+ flex-wrap: wrap;
575
+ gap: 0.5rem;
576
+ margin-top: 0.5rem;
577
+ }
578
+
579
+ .checkbox-label {
580
+ display: flex;
581
+ align-items: center;
582
+ gap: 0.375rem;
583
+ padding: 0.5rem 0.75rem;
584
+ background: var(--bg);
585
+ border: 1px solid var(--border);
586
+ border-radius: 0.375rem;
587
+ cursor: pointer;
588
+ font-size: 0.875rem;
589
+ transition: all 0.2s;
590
+ user-select: none;
591
+ }
592
+
593
+ .checkbox-label:hover {
594
+ border-color: var(--primary);
595
+ background: rgba(59, 130, 246, 0.05);
596
+ }
597
+
598
+ .checkbox-label.checked {
599
+ background: var(--primary);
600
+ border-color: var(--primary);
601
+ color: white;
602
+ }
603
+
604
+ .checkbox-label input[type="checkbox"] {
605
+ position: absolute;
606
+ opacity: 0;
607
+ pointer-events: none;
608
+ }
609
+
610
+ /* Variant type badge */
611
+ .variant-type-badge {
612
+ font-size: 0.65rem;
613
+ padding: 0.125rem 0.375rem;
614
+ border-radius: 0.25rem;
615
+ background: var(--border);
616
+ color: var(--text-muted);
617
+ margin-left: 0.5rem;
618
+ }
619
+
620
+ .variant-type-badge.multi {
621
+ background: var(--success);
622
+ color: white;
623
+ }
624
+
571
625
  /* Responsive */
572
626
  @media (max-width: 768px) {
573
627
  .container {
@@ -542,14 +542,21 @@ export function resolveSkills(role, variants = {}) {
542
542
  result.role = [...ROLE_SKILL_MAP[role]];
543
543
  }
544
544
 
545
- // Add variant-specific skills
545
+ // Add variant-specific skills (supports both single values and arrays for multi-select)
546
546
  for (const [category, value] of Object.entries(variants)) {
547
547
  if (value) {
548
- const key = `${category}:${value}`;
549
- if (VARIANT_SKILL_MAP[key]) {
550
- for (const skill of VARIANT_SKILL_MAP[key]) {
551
- if (!result.variants.includes(skill) && !result.role.includes(skill)) {
552
- result.variants.push(skill);
548
+ // Handle both single value and array of values
549
+ const values = Array.isArray(value) ? value : [value];
550
+
551
+ for (const v of values) {
552
+ if (v) {
553
+ const key = `${category}:${v}`;
554
+ if (VARIANT_SKILL_MAP[key]) {
555
+ for (const skill of VARIANT_SKILL_MAP[key]) {
556
+ if (!result.variants.includes(skill) && !result.role.includes(skill)) {
557
+ result.variants.push(skill);
558
+ }
559
+ }
553
560
  }
554
561
  }
555
562
  }