@aexol/opencode-wizard 0.1.14 → 0.1.16

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/tui.js CHANGED
@@ -9,7 +9,7 @@ import { createElement as _$createElement } from "@opentui/solid";
9
9
  /** @jsxImportSource @opentui/solid */
10
10
 
11
11
  import { createEffect, createMemo, createSignal } from 'solid-js';
12
- import { PLUGIN_ID, resolvePluginStatusSnapshotWithAuthBootstrap } from './server.js';
12
+ import { PLUGIN_ID, resolvePluginStatusSnapshotWithAuthBootstrap, setPublishedSkillInstalled, setPublishedSkillIgnored } from './server.js';
13
13
  const STATUS_TIMEOUT_MS = 5_000;
14
14
  const STATUS_REFRESH_INTERVAL_MS = 5_000;
15
15
  const MAX_STATUS_MESSAGE_LENGTH = 80;
@@ -214,40 +214,122 @@ const getSkillTags = skill => {
214
214
  if (tagLabels.length === 0) return 'no tags';
215
215
  return tagLabels.join(', ');
216
216
  };
217
- const getSkillMeta = skill => `${skill.policyLabel} · ${skill.contextKind} · ${getSkillTags(skill)}`;
217
+ const getSkillMeta = (skill, state) => `${skill.policyLabel} · ${state} · ${getSkillTags(skill)}`;
218
+ const getRowStateLabel = row => {
219
+ if (row.ignored) return 'ignored';
220
+ if (row.state === 'installable') return 'not installed';
221
+ return row.state === 'installed-global' ? 'installed global' : 'installed project';
222
+ };
223
+ const getErrorMessage = error => {
224
+ if (error instanceof Error && error.message) return error.message;
225
+ return 'Preference update failed. Check plugin auth/backend status and try again.';
226
+ };
218
227
  const SkillCatalogRow = props => {
219
- const description = getSkillDescription(props.skill);
228
+ const skill = props.row.skill;
229
+ const description = getSkillDescription(skill);
230
+ const canUninstall = skill.assignmentSource === 'USER_GLOBAL' || skill.assignmentSource === 'USER_WORKSPACE';
220
231
  return (() => {
221
232
  var _el$18 = _$createElement("box"),
222
- _el$19 = _$createElement("text"),
223
- _el$20 = _$createElement("b"),
224
- _el$21 = _$createElement("text");
233
+ _el$19 = _$createElement("box"),
234
+ _el$20 = _$createElement("text"),
235
+ _el$21 = _$createElement("b"),
236
+ _el$22 = _$createTextNode(` (`),
237
+ _el$24 = _$createTextNode(`)`),
238
+ _el$25 = _$createElement("box"),
239
+ _el$26 = _$createElement("text");
225
240
  _$insertNode(_el$18, _el$19);
226
- _$insertNode(_el$18, _el$21);
241
+ _$insertNode(_el$18, _el$26);
227
242
  _$setProp(_el$18, "width", "100%");
228
243
  _$setProp(_el$18, "flexDirection", "column");
229
244
  _$setProp(_el$18, "overflow", "hidden");
230
245
  _$setProp(_el$18, "marginBottom", 1);
231
246
  _$insertNode(_el$19, _el$20);
232
- _$setProp(_el$19, "wrapMode", "none");
247
+ _$insertNode(_el$19, _el$25);
248
+ _$setProp(_el$19, "width", "100%");
249
+ _$setProp(_el$19, "flexDirection", "row");
250
+ _$setProp(_el$19, "justifyContent", "space-between");
233
251
  _$setProp(_el$19, "overflow", "hidden");
234
- _$insert(_el$20, () => compactSkillName(getSkillDisplayName(props.skill)));
235
- _$setProp(_el$21, "wrapMode", "none");
236
- _$setProp(_el$21, "overflow", "hidden");
237
- _$insert(_el$21, () => compactSkillMeta(getSkillMeta(props.skill)));
252
+ _$insertNode(_el$20, _el$21);
253
+ _$insertNode(_el$20, _el$22);
254
+ _$insertNode(_el$20, _el$24);
255
+ _$setProp(_el$20, "wrapMode", "none");
256
+ _$setProp(_el$20, "overflow", "hidden");
257
+ _$insert(_el$21, () => compactSkillName(getSkillDisplayName(skill)));
258
+ _$insert(_el$20, () => getRowStateLabel(props.row), _el$24);
259
+ _$setProp(_el$25, "flexDirection", "row");
260
+ _$setProp(_el$25, "flexShrink", 0);
261
+ _$insert(_el$25, (() => {
262
+ var _c$ = _$memo(() => props.row.state === 'installable');
263
+ return () => _c$() ? [(() => {
264
+ var _el$27 = _$createElement("box"),
265
+ _el$28 = _$createElement("text");
266
+ _$insertNode(_el$27, _el$28);
267
+ _$setProp(_el$27, "onMouseUp", () => props.onInstall(props.row, 'global'));
268
+ _$setProp(_el$27, "flexShrink", 0);
269
+ _$insertNode(_el$28, _$createTextNode(`Global`));
270
+ _$setProp(_el$28, "wrapMode", "none");
271
+ _$effect(_$p => _$setProp(_el$28, "fg", props.theme.textMuted, _$p));
272
+ return _el$27;
273
+ })(), (() => {
274
+ var _el$30 = _$createElement("text");
275
+ _$insertNode(_el$30, _$createTextNode(` / `));
276
+ _$setProp(_el$30, "wrapMode", "none");
277
+ _$effect(_$p => _$setProp(_el$30, "fg", props.theme.textMuted, _$p));
278
+ return _el$30;
279
+ })(), (() => {
280
+ var _el$32 = _$createElement("box"),
281
+ _el$33 = _$createElement("text");
282
+ _$insertNode(_el$32, _el$33);
283
+ _$setProp(_el$32, "onMouseUp", () => props.onInstall(props.row, 'project'));
284
+ _$setProp(_el$32, "flexShrink", 0);
285
+ _$insertNode(_el$33, _$createTextNode(`Project`));
286
+ _$setProp(_el$33, "wrapMode", "none");
287
+ _$effect(_$p => _$setProp(_el$33, "fg", props.theme.textMuted, _$p));
288
+ return _el$32;
289
+ })()] : [(() => {
290
+ var _el$35 = _$createElement("box"),
291
+ _el$36 = _$createElement("text");
292
+ _$insertNode(_el$35, _el$36);
293
+ _$setProp(_el$35, "onMouseUp", () => props.onIgnore(props.row));
294
+ _$setProp(_el$35, "flexShrink", 0);
295
+ _$setProp(_el$36, "wrapMode", "none");
296
+ _$insert(_el$36, () => props.row.ignored ? 'Unignore' : 'Ignore');
297
+ _$effect(_$p => _$setProp(_el$36, "fg", props.theme.textMuted, _$p));
298
+ return _el$35;
299
+ })(), canUninstall ? [(() => {
300
+ var _el$37 = _$createElement("text");
301
+ _$insertNode(_el$37, _$createTextNode(` / `));
302
+ _$setProp(_el$37, "wrapMode", "none");
303
+ _$effect(_$p => _$setProp(_el$37, "fg", props.theme.textMuted, _$p));
304
+ return _el$37;
305
+ })(), (() => {
306
+ var _el$39 = _$createElement("box"),
307
+ _el$40 = _$createElement("text");
308
+ _$insertNode(_el$39, _el$40);
309
+ _$setProp(_el$39, "onMouseUp", () => props.onUninstall(props.row));
310
+ _$setProp(_el$39, "flexShrink", 0);
311
+ _$insertNode(_el$40, _$createTextNode(`Uninstall`));
312
+ _$setProp(_el$40, "wrapMode", "none");
313
+ _$effect(_$p => _$setProp(_el$40, "fg", props.theme.textMuted, _$p));
314
+ return _el$39;
315
+ })()] : null];
316
+ })());
317
+ _$setProp(_el$26, "wrapMode", "none");
318
+ _$setProp(_el$26, "overflow", "hidden");
319
+ _$insert(_el$26, () => compactSkillMeta(getSkillMeta(skill, props.row.state)));
238
320
  _$insert(_el$18, description ? (() => {
239
- var _el$22 = _$createElement("text");
240
- _$setProp(_el$22, "wrapMode", "none");
241
- _$setProp(_el$22, "overflow", "hidden");
242
- _$insert(_el$22, () => compactSkillDescription(description));
243
- _$effect(_$p => _$setProp(_el$22, "fg", props.theme.text, _$p));
244
- return _el$22;
321
+ var _el$42 = _$createElement("text");
322
+ _$setProp(_el$42, "wrapMode", "none");
323
+ _$setProp(_el$42, "overflow", "hidden");
324
+ _$insert(_el$42, () => compactSkillDescription(description));
325
+ _$effect(_$p => _$setProp(_el$42, "fg", props.theme.text, _$p));
326
+ return _el$42;
245
327
  })() : null, null);
246
328
  _$effect(_p$ => {
247
- var _v$6 = props.theme.text,
329
+ var _v$6 = props.row.ignored ? props.theme.textMuted : props.theme.text,
248
330
  _v$7 = props.theme.textMuted;
249
- _v$6 !== _p$.e && (_p$.e = _$setProp(_el$19, "fg", _v$6, _p$.e));
250
- _v$7 !== _p$.t && (_p$.t = _$setProp(_el$21, "fg", _v$7, _p$.t));
331
+ _v$6 !== _p$.e && (_p$.e = _$setProp(_el$20, "fg", _v$6, _p$.e));
332
+ _v$7 !== _p$.t && (_p$.t = _$setProp(_el$26, "fg", _v$7, _p$.t));
251
333
  return _p$;
252
334
  }, {
253
335
  e: undefined,
@@ -262,46 +344,61 @@ const WizardSkillsDialogContent = props => {
262
344
  const currentStatus = props.status();
263
345
  if (currentStatus.kind === 'loading') {
264
346
  return (() => {
265
- var _el$23 = _$createElement("text");
266
- _$insertNode(_el$23, _$createTextNode(`Refreshing published skills…`));
267
- _$setProp(_el$23, "wrapMode", "none");
268
- _$setProp(_el$23, "overflow", "hidden");
269
- _$effect(_$p => _$setProp(_el$23, "fg", props.theme.textMuted, _$p));
270
- return _el$23;
347
+ var _el$43 = _$createElement("text");
348
+ _$insertNode(_el$43, _$createTextNode(`Refreshing published skills…`));
349
+ _$setProp(_el$43, "wrapMode", "none");
350
+ _$setProp(_el$43, "overflow", "hidden");
351
+ _$effect(_$p => _$setProp(_el$43, "fg", props.theme.textMuted, _$p));
352
+ return _el$43;
271
353
  })();
272
354
  }
273
355
  if (currentStatus.kind === 'error') {
274
356
  return (() => {
275
- var _el$25 = _$createElement("text"),
276
- _el$26 = _$createTextNode(`unavailable: `);
277
- _$insertNode(_el$25, _el$26);
278
- _$setProp(_el$25, "wrapMode", "none");
279
- _$setProp(_el$25, "overflow", "hidden");
280
- _$insert(_el$25, () => compactStatusMessage(currentStatus.message), null);
281
- _$effect(_$p => _$setProp(_el$25, "fg", props.theme.warning, _$p));
282
- return _el$25;
357
+ var _el$45 = _$createElement("text"),
358
+ _el$46 = _$createTextNode(`unavailable: `);
359
+ _$insertNode(_el$45, _el$46);
360
+ _$setProp(_el$45, "wrapMode", "none");
361
+ _$setProp(_el$45, "overflow", "hidden");
362
+ _$insert(_el$45, () => compactStatusMessage(currentStatus.message), null);
363
+ _$effect(_$p => _$setProp(_el$45, "fg", props.theme.warning, _$p));
364
+ return _el$45;
283
365
  })();
284
366
  }
285
367
  if (!currentStatus.snapshot.catalog) {
286
368
  return (() => {
287
- var _el$27 = _$createElement("text"),
288
- _el$28 = _$createTextNode(`catalog `);
289
- _$insertNode(_el$27, _el$28);
290
- _$setProp(_el$27, "wrapMode", "none");
291
- _$setProp(_el$27, "overflow", "hidden");
292
- _$insert(_el$27, () => formatSkillsCatalogUnavailableMessage(currentStatus.snapshot), null);
293
- _$effect(_$p => _$setProp(_el$27, "fg", props.theme.textMuted, _$p));
294
- return _el$27;
369
+ var _el$47 = _$createElement("text"),
370
+ _el$48 = _$createTextNode(`catalog `);
371
+ _$insertNode(_el$47, _el$48);
372
+ _$setProp(_el$47, "wrapMode", "none");
373
+ _$setProp(_el$47, "overflow", "hidden");
374
+ _$insert(_el$47, () => formatSkillsCatalogUnavailableMessage(currentStatus.snapshot), null);
375
+ _$effect(_$p => _$setProp(_el$47, "fg", props.theme.textMuted, _$p));
376
+ return _el$47;
295
377
  })();
296
378
  }
297
379
  const {
298
380
  catalog
299
381
  } = currentStatus.snapshot;
300
- const totalPages = Math.max(1, Math.ceil(catalog.skills.length / SKILLS_PAGE_SIZE));
382
+ const activeSkillSlugs = new Set(catalog.skills.map(skill => skill.skillSlug));
383
+ const ignoredSkillSlugs = new Set(currentStatus.snapshot.ignoredPublishedSkills.skills.map(skill => skill.skillSlug));
384
+ const rows = [...catalog.skills.map(skill => ({
385
+ skill,
386
+ ignored: false,
387
+ state: skill.contextKind === 'global' ? 'installed-global' : 'installed-project'
388
+ })), ...currentStatus.snapshot.ignoredPublishedSkills.skills.map(skill => ({
389
+ skill,
390
+ ignored: true,
391
+ state: skill.contextKind === 'global' ? 'installed-global' : 'installed-project'
392
+ })), ...(currentStatus.snapshot.installableCatalog?.skills ?? []).filter(skill => !activeSkillSlugs.has(skill.skillSlug) && !ignoredSkillSlugs.has(skill.skillSlug)).map(skill => ({
393
+ skill,
394
+ ignored: false,
395
+ state: 'installable'
396
+ }))];
397
+ const totalPages = Math.max(1, Math.ceil(rows.length / SKILLS_PAGE_SIZE));
301
398
  const currentPage = Math.min(page(), totalPages - 1);
302
399
  const startIndex = currentPage * SKILLS_PAGE_SIZE;
303
- const endIndex = Math.min(startIndex + SKILLS_PAGE_SIZE, catalog.skills.length);
304
- const visibleSkills = catalog.skills.slice(startIndex, endIndex);
400
+ const endIndex = Math.min(startIndex + SKILLS_PAGE_SIZE, rows.length);
401
+ const visibleRows = rows.slice(startIndex, endIndex);
305
402
  const canGoBack = currentPage > 0;
306
403
  const canGoForward = currentPage < totalPages - 1;
307
404
  const goBack = () => {
@@ -313,94 +410,109 @@ const WizardSkillsDialogContent = props => {
313
410
  setPage(currentPage + 1);
314
411
  };
315
412
  return (() => {
316
- var _el$29 = _$createElement("box"),
317
- _el$30 = _$createElement("box"),
318
- _el$31 = _$createElement("text"),
319
- _el$32 = _$createElement("b"),
320
- _el$33 = _$createTextNode(` skills`),
321
- _el$34 = _$createTextNode(`&nbsp;· `),
322
- _el$35 = _$createTextNode(` global · `),
323
- _el$36 = _$createTextNode(` workspace`),
324
- _el$37 = _$createElement("text"),
325
- _el$38 = _$createTextNode(`page `),
326
- _el$39 = _$createTextNode(`/`),
327
- _el$40 = _$createElement("box"),
328
- _el$41 = _$createElement("box"),
329
- _el$42 = _$createElement("box"),
330
- _el$43 = _$createElement("text"),
331
- _el$45 = _$createElement("text"),
332
- _el$46 = _$createTextNode(` shown`),
333
- _el$47 = _$createElement("box"),
334
- _el$48 = _$createElement("text");
335
- _$insertNode(_el$29, _el$30);
336
- _$insertNode(_el$29, _el$40);
337
- _$insertNode(_el$29, _el$41);
338
- _$setProp(_el$29, "width", "100%");
339
- _$setProp(_el$29, "flexDirection", "column");
340
- _$setProp(_el$29, "overflow", "hidden");
341
- _$insertNode(_el$30, _el$31);
342
- _$insertNode(_el$30, _el$37);
343
- _$setProp(_el$30, "width", "100%");
344
- _$setProp(_el$30, "flexDirection", "row");
345
- _$setProp(_el$30, "justifyContent", "space-between");
346
- _$setProp(_el$30, "overflow", "hidden");
347
- _$insertNode(_el$31, _el$32);
348
- _$insertNode(_el$31, _el$34);
349
- _$insertNode(_el$31, _el$35);
350
- _$insertNode(_el$31, _el$36);
351
- _$setProp(_el$31, "wrapMode", "none");
352
- _$setProp(_el$31, "overflow", "hidden");
353
- _$insertNode(_el$32, _el$33);
354
- _$insert(_el$32, () => catalog.publishedSkillCount, _el$33);
355
- _$insert(_el$31, () => catalog.assignmentCounts.global, _el$35);
356
- _$insert(_el$31, () => catalog.assignmentCounts.project, _el$36);
357
- _$insertNode(_el$37, _el$38);
358
- _$insertNode(_el$37, _el$39);
359
- _$setProp(_el$37, "wrapMode", "none");
360
- _$insert(_el$37, currentPage + 1, _el$39);
361
- _$insert(_el$37, totalPages, null);
362
- _$setProp(_el$40, "width", "100%");
363
- _$setProp(_el$40, "flexDirection", "column");
364
- _$setProp(_el$40, "marginTop", 1);
365
- _$setProp(_el$40, "overflow", "hidden");
366
- _$insert(_el$40, () => visibleSkills.map(skill => _$createComponent(SkillCatalogRow, {
367
- skill: skill,
413
+ var _el$49 = _$createElement("box"),
414
+ _el$50 = _$createElement("box"),
415
+ _el$51 = _$createElement("text"),
416
+ _el$52 = _$createElement("b"),
417
+ _el$53 = _$createTextNode(` skills`),
418
+ _el$54 = _$createTextNode(`&nbsp;· `),
419
+ _el$55 = _$createTextNode(` global · `),
420
+ _el$56 = _$createTextNode(` workspace &nbsp;· `),
421
+ _el$57 = _$createTextNode(` ignored &nbsp;· `),
422
+ _el$58 = _$createTextNode(` installable`),
423
+ _el$59 = _$createElement("text"),
424
+ _el$60 = _$createTextNode(`page `),
425
+ _el$61 = _$createTextNode(`/`),
426
+ _el$62 = _$createElement("box"),
427
+ _el$63 = _$createElement("box"),
428
+ _el$64 = _$createElement("box"),
429
+ _el$65 = _$createElement("text"),
430
+ _el$67 = _$createElement("text"),
431
+ _el$68 = _$createTextNode(` shown`),
432
+ _el$69 = _$createElement("box"),
433
+ _el$70 = _$createElement("text");
434
+ _$insertNode(_el$49, _el$50);
435
+ _$insertNode(_el$49, _el$62);
436
+ _$insertNode(_el$49, _el$63);
437
+ _$setProp(_el$49, "width", "100%");
438
+ _$setProp(_el$49, "flexDirection", "column");
439
+ _$setProp(_el$49, "overflow", "hidden");
440
+ _$insertNode(_el$50, _el$51);
441
+ _$insertNode(_el$50, _el$59);
442
+ _$setProp(_el$50, "width", "100%");
443
+ _$setProp(_el$50, "flexDirection", "row");
444
+ _$setProp(_el$50, "justifyContent", "space-between");
445
+ _$setProp(_el$50, "overflow", "hidden");
446
+ _$insertNode(_el$51, _el$52);
447
+ _$insertNode(_el$51, _el$54);
448
+ _$insertNode(_el$51, _el$55);
449
+ _$insertNode(_el$51, _el$56);
450
+ _$insertNode(_el$51, _el$57);
451
+ _$insertNode(_el$51, _el$58);
452
+ _$setProp(_el$51, "wrapMode", "none");
453
+ _$setProp(_el$51, "overflow", "hidden");
454
+ _$insertNode(_el$52, _el$53);
455
+ _$insert(_el$52, () => catalog.publishedSkillCount, _el$53);
456
+ _$insert(_el$51, () => catalog.assignmentCounts.global, _el$55);
457
+ _$insert(_el$51, () => catalog.assignmentCounts.project, _el$56);
458
+ _$insert(_el$51, () => currentStatus.snapshot.ignoredPublishedSkills.count, _el$57);
459
+ _$insert(_el$51, () => currentStatus.snapshot.installableCatalog?.count ?? 0, _el$58);
460
+ _$insertNode(_el$59, _el$60);
461
+ _$insertNode(_el$59, _el$61);
462
+ _$setProp(_el$59, "wrapMode", "none");
463
+ _$insert(_el$59, currentPage + 1, _el$61);
464
+ _$insert(_el$59, totalPages, null);
465
+ _$setProp(_el$62, "width", "100%");
466
+ _$setProp(_el$62, "flexDirection", "column");
467
+ _$setProp(_el$62, "marginTop", 1);
468
+ _$setProp(_el$62, "overflow", "hidden");
469
+ _$insert(_el$62, () => visibleRows.map(row => _$createComponent(SkillCatalogRow, {
470
+ row: row,
368
471
  get theme() {
369
472
  return props.theme;
473
+ },
474
+ get onIgnore() {
475
+ return props.onIgnoreSkill;
476
+ },
477
+ get onInstall() {
478
+ return props.onInstallSkill;
479
+ },
480
+ get onUninstall() {
481
+ return props.onUninstallSkill;
370
482
  }
371
483
  })));
372
- _$insertNode(_el$41, _el$42);
373
- _$insertNode(_el$41, _el$45);
374
- _$insertNode(_el$41, _el$47);
375
- _$setProp(_el$41, "width", "100%");
376
- _$setProp(_el$41, "flexDirection", "row");
377
- _$setProp(_el$41, "justifyContent", "space-between");
378
- _$setProp(_el$41, "overflow", "hidden");
379
- _$insertNode(_el$42, _el$43);
380
- _$setProp(_el$42, "onMouseUp", goBack);
381
- _$setProp(_el$42, "flexShrink", 0);
382
- _$insertNode(_el$43, _$createTextNode(`← Prev`));
383
- _$setProp(_el$43, "wrapMode", "none");
384
- _$insertNode(_el$45, _el$46);
385
- _$setProp(_el$45, "wrapMode", "none");
386
- _$setProp(_el$45, "overflow", "hidden");
387
- _$insert(_el$45, () => visibleSkills.length, _el$46);
388
- _$insertNode(_el$47, _el$48);
389
- _$setProp(_el$47, "onMouseUp", goForward);
390
- _$setProp(_el$47, "flexShrink", 0);
391
- _$insertNode(_el$48, _$createTextNode(`Next →`));
392
- _$setProp(_el$48, "wrapMode", "none");
484
+ _$insertNode(_el$63, _el$64);
485
+ _$insertNode(_el$63, _el$67);
486
+ _$insertNode(_el$63, _el$69);
487
+ _$setProp(_el$63, "width", "100%");
488
+ _$setProp(_el$63, "flexDirection", "row");
489
+ _$setProp(_el$63, "justifyContent", "space-between");
490
+ _$setProp(_el$63, "overflow", "hidden");
491
+ _$insertNode(_el$64, _el$65);
492
+ _$setProp(_el$64, "onMouseUp", goBack);
493
+ _$setProp(_el$64, "flexShrink", 0);
494
+ _$insertNode(_el$65, _$createTextNode(`← Prev`));
495
+ _$setProp(_el$65, "wrapMode", "none");
496
+ _$insertNode(_el$67, _el$68);
497
+ _$setProp(_el$67, "wrapMode", "none");
498
+ _$setProp(_el$67, "overflow", "hidden");
499
+ _$insert(_el$67, () => visibleRows.length, _el$68);
500
+ _$insertNode(_el$69, _el$70);
501
+ _$setProp(_el$69, "onMouseUp", goForward);
502
+ _$setProp(_el$69, "flexShrink", 0);
503
+ _$insertNode(_el$70, _$createTextNode(`Next →`));
504
+ _$setProp(_el$70, "wrapMode", "none");
393
505
  _$effect(_p$ => {
394
506
  var _v$8 = props.theme.text,
395
507
  _v$9 = props.theme.textMuted,
396
508
  _v$0 = canGoBack ? props.theme.text : props.theme.textMuted,
397
509
  _v$1 = props.theme.textMuted,
398
510
  _v$10 = canGoForward ? props.theme.text : props.theme.textMuted;
399
- _v$8 !== _p$.e && (_p$.e = _$setProp(_el$31, "fg", _v$8, _p$.e));
400
- _v$9 !== _p$.t && (_p$.t = _$setProp(_el$37, "fg", _v$9, _p$.t));
401
- _v$0 !== _p$.a && (_p$.a = _$setProp(_el$43, "fg", _v$0, _p$.a));
402
- _v$1 !== _p$.o && (_p$.o = _$setProp(_el$45, "fg", _v$1, _p$.o));
403
- _v$10 !== _p$.i && (_p$.i = _$setProp(_el$48, "fg", _v$10, _p$.i));
511
+ _v$8 !== _p$.e && (_p$.e = _$setProp(_el$51, "fg", _v$8, _p$.e));
512
+ _v$9 !== _p$.t && (_p$.t = _$setProp(_el$59, "fg", _v$9, _p$.t));
513
+ _v$0 !== _p$.a && (_p$.a = _$setProp(_el$65, "fg", _v$0, _p$.a));
514
+ _v$1 !== _p$.o && (_p$.o = _$setProp(_el$67, "fg", _v$1, _p$.o));
515
+ _v$10 !== _p$.i && (_p$.i = _$setProp(_el$70, "fg", _v$10, _p$.i));
404
516
  return _p$;
405
517
  }, {
406
518
  e: undefined,
@@ -409,10 +521,36 @@ const WizardSkillsDialogContent = props => {
409
521
  o: undefined,
410
522
  i: undefined
411
523
  });
412
- return _el$29;
524
+ return _el$49;
413
525
  })();
414
526
  };
415
- return _$memo(content);
527
+ return (() => {
528
+ var _el$72 = _$createElement("box");
529
+ _$setProp(_el$72, "width", "100%");
530
+ _$setProp(_el$72, "flexDirection", "column");
531
+ _$setProp(_el$72, "overflow", "hidden");
532
+ _$insert(_el$72, _$createComponent(PreferenceActionNoticeRow, {
533
+ get notice() {
534
+ return props.actionNotice();
535
+ },
536
+ get theme() {
537
+ return props.theme;
538
+ }
539
+ }), null);
540
+ _$insert(_el$72, content, null);
541
+ return _el$72;
542
+ })();
543
+ };
544
+ const PreferenceActionNoticeRow = props => {
545
+ if (props.notice.kind === 'idle') return null;
546
+ return (() => {
547
+ var _el$73 = _$createElement("text");
548
+ _$setProp(_el$73, "wrapMode", "none");
549
+ _$setProp(_el$73, "overflow", "hidden");
550
+ _$insert(_el$73, () => compactStatusMessage(props.notice.message));
551
+ _$effect(_$p => _$setProp(_el$73, "fg", props.notice.kind === 'error' ? props.theme.warning : props.theme.textMuted, _$p));
552
+ return _el$73;
553
+ })();
416
554
  };
417
555
  const ReadyRows = props => {
418
556
  const statusRows = [_$createComponent(Row, {
@@ -440,12 +578,12 @@ const ReadyRows = props => {
440
578
  })];
441
579
  if (!props.snapshot.catalog) {
442
580
  return (() => {
443
- var _el$50 = _$createElement("box");
444
- _$setProp(_el$50, "width", "100%");
445
- _$setProp(_el$50, "flexDirection", "column");
446
- _$setProp(_el$50, "overflow", "hidden");
447
- _$insert(_el$50, statusRows, null);
448
- _$insert(_el$50, _$createComponent(Row, {
581
+ var _el$74 = _$createElement("box");
582
+ _$setProp(_el$74, "width", "100%");
583
+ _$setProp(_el$74, "flexDirection", "column");
584
+ _$setProp(_el$74, "overflow", "hidden");
585
+ _$insert(_el$74, statusRows, null);
586
+ _$insert(_el$74, _$createComponent(Row, {
449
587
  label: "catalog",
450
588
  get value() {
451
589
  return formatSkillsCatalogUnavailableMessage(props.snapshot);
@@ -457,22 +595,22 @@ const ReadyRows = props => {
457
595
  return props.theme.text;
458
596
  }
459
597
  }), null);
460
- return _el$50;
598
+ return _el$74;
461
599
  })();
462
600
  }
463
601
  const counts = props.snapshot.catalog.assignmentCounts;
464
602
  return (() => {
465
- var _el$51 = _$createElement("box"),
466
- _el$52 = _$createElement("text");
467
- _$insertNode(_el$51, _el$52);
468
- _$setProp(_el$51, "width", "100%");
469
- _$setProp(_el$51, "flexDirection", "column");
470
- _$setProp(_el$51, "overflow", "hidden");
471
- _$insert(_el$51, statusRows, _el$52);
472
- _$insertNode(_el$52, _$createTextNode(`catalog:`));
473
- _$setProp(_el$52, "wrapMode", "none");
474
- _$setProp(_el$52, "overflow", "hidden");
475
- _$insert(_el$51, _$createComponent(CatalogBullet, {
603
+ var _el$75 = _$createElement("box"),
604
+ _el$76 = _$createElement("text");
605
+ _$insertNode(_el$75, _el$76);
606
+ _$setProp(_el$75, "width", "100%");
607
+ _$setProp(_el$75, "flexDirection", "column");
608
+ _$setProp(_el$75, "overflow", "hidden");
609
+ _$insert(_el$75, statusRows, _el$76);
610
+ _$insertNode(_el$76, _$createTextNode(`catalog:`));
611
+ _$setProp(_el$76, "wrapMode", "none");
612
+ _$setProp(_el$76, "overflow", "hidden");
613
+ _$insert(_el$75, _$createComponent(CatalogBullet, {
476
614
  get value() {
477
615
  return `${props.snapshot.catalog.publishedSkillCount} loaded`;
478
616
  },
@@ -480,7 +618,7 @@ const ReadyRows = props => {
480
618
  return props.theme;
481
619
  }
482
620
  }), null);
483
- _$insert(_el$51, _$createComponent(CatalogBullet, {
621
+ _$insert(_el$75, _$createComponent(CatalogBullet, {
484
622
  get value() {
485
623
  return `${counts.global} global`;
486
624
  },
@@ -488,7 +626,7 @@ const ReadyRows = props => {
488
626
  return props.theme;
489
627
  }
490
628
  }), null);
491
- _$insert(_el$51, _$createComponent(CatalogBullet, {
629
+ _$insert(_el$75, _$createComponent(CatalogBullet, {
492
630
  get value() {
493
631
  return `${counts.project} workspace`;
494
632
  },
@@ -496,70 +634,159 @@ const ReadyRows = props => {
496
634
  return props.theme;
497
635
  }
498
636
  }), null);
499
- _$effect(_$p => _$setProp(_el$52, "fg", props.theme.textMuted, _$p));
500
- return _el$51;
637
+ _$insert(_el$75, _$createComponent(CatalogBullet, {
638
+ get value() {
639
+ return `${props.snapshot.ignoredPublishedSkills.count} ignored`;
640
+ },
641
+ get theme() {
642
+ return props.theme;
643
+ }
644
+ }), null);
645
+ _$effect(_$p => _$setProp(_el$76, "fg", props.theme.textMuted, _$p));
646
+ return _el$75;
501
647
  })();
502
648
  };
503
649
  const WizardSkillsDialog = props => {
504
650
  const theme = createMemo(() => props.api.theme.current);
651
+ const [actionNotice, setActionNotice] = createSignal({
652
+ kind: 'idle'
653
+ });
654
+ const refreshAfterPreferenceChange = message => {
655
+ setActionNotice({
656
+ kind: 'success',
657
+ message
658
+ });
659
+ props.refreshStatus({
660
+ showLoading: false
661
+ });
662
+ requestRender(props.api);
663
+ };
664
+ const showPreferenceFailure = error => {
665
+ setActionNotice({
666
+ kind: 'error',
667
+ message: getErrorMessage(error)
668
+ });
669
+ props.refreshStatus({
670
+ showLoading: false
671
+ });
672
+ requestRender(props.api);
673
+ };
674
+ const ignoreSkill = row => {
675
+ const currentStatus = props.status();
676
+ if (currentStatus.kind !== 'ready') return;
677
+ const scopeKey = currentStatus.snapshot.ignoredPublishedSkills.scopeKey;
678
+ setActionNotice({
679
+ kind: 'pending',
680
+ message: row.ignored ? 'Removing ignore preference…' : 'Ignoring skill…'
681
+ });
682
+ requestRender(props.api);
683
+ void setPublishedSkillIgnored({
684
+ worktree: props.api.state.path.worktree,
685
+ directory: props.api.state.path.directory,
686
+ scopeKey,
687
+ skillSlug: row.skill.skillSlug,
688
+ ignored: !row.ignored,
689
+ preferenceScope: row.state === 'installed-global' ? 'global' : 'project'
690
+ }).then(() => refreshAfterPreferenceChange(row.ignored ? 'Skill is no longer ignored.' : 'Skill ignored.')).catch(showPreferenceFailure);
691
+ };
692
+ const installSkill = (row, preferenceScope) => {
693
+ const currentStatus = props.status();
694
+ if (currentStatus.kind !== 'ready') return;
695
+ const scopeKey = currentStatus.snapshot.ignoredPublishedSkills.scopeKey;
696
+ setActionNotice({
697
+ kind: 'pending',
698
+ message: `Installing skill for ${preferenceScope}…`
699
+ });
700
+ requestRender(props.api);
701
+ void setPublishedSkillInstalled({
702
+ worktree: props.api.state.path.worktree,
703
+ directory: props.api.state.path.directory,
704
+ scopeKey,
705
+ skillSlug: row.skill.skillSlug,
706
+ installed: true,
707
+ preferenceScope
708
+ }).then(() => refreshAfterPreferenceChange(`Skill installed for ${preferenceScope}.`)).catch(showPreferenceFailure);
709
+ };
710
+ const uninstallSkill = row => {
711
+ const currentStatus = props.status();
712
+ if (currentStatus.kind !== 'ready') return;
713
+ const scopeKey = currentStatus.snapshot.ignoredPublishedSkills.scopeKey;
714
+ setActionNotice({
715
+ kind: 'pending',
716
+ message: 'Uninstalling skill…'
717
+ });
718
+ requestRender(props.api);
719
+ void setPublishedSkillInstalled({
720
+ worktree: props.api.state.path.worktree,
721
+ directory: props.api.state.path.directory,
722
+ scopeKey,
723
+ skillSlug: row.skill.skillSlug,
724
+ installed: false,
725
+ preferenceScope: row.state === 'installed-global' ? 'global' : 'project'
726
+ }).then(() => refreshAfterPreferenceChange('Skill uninstalled.')).catch(showPreferenceFailure);
727
+ };
505
728
  createEffect(() => {
506
729
  props.api.ui?.dialog?.setSize?.('xlarge');
507
730
  });
508
731
  return (() => {
509
- var _el$54 = _$createElement("box"),
510
- _el$55 = _$createElement("box"),
511
- _el$56 = _$createElement("text"),
512
- _el$57 = _$createElement("b"),
513
- _el$59 = _$createElement("box"),
514
- _el$60 = _$createElement("text"),
515
- _el$62 = _$createElement("box");
516
- _$insertNode(_el$54, _el$55);
517
- _$insertNode(_el$54, _el$62);
518
- _$setProp(_el$54, "width", "100%");
519
- _$setProp(_el$54, "flexDirection", "column");
520
- _$setProp(_el$54, "paddingLeft", 1);
521
- _$setProp(_el$54, "paddingRight", 1);
522
- _$setProp(_el$54, "paddingBottom", 1);
523
- _$insertNode(_el$55, _el$56);
524
- _$insertNode(_el$55, _el$59);
525
- _$setProp(_el$55, "width", "100%");
526
- _$setProp(_el$55, "flexDirection", "row");
527
- _$setProp(_el$55, "justifyContent", "space-between");
528
- _$setProp(_el$55, "overflow", "hidden");
529
- _$insertNode(_el$56, _el$57);
530
- _$setProp(_el$56, "wrapMode", "none");
531
- _$setProp(_el$56, "overflow", "hidden");
532
- _$insertNode(_el$57, _$createTextNode(`Wizard Skills`));
533
- _$insertNode(_el$59, _el$60);
534
- _$setProp(_el$59, "flexShrink", 0);
535
- _$insertNode(_el$60, _$createTextNode(`Close`));
536
- _$setProp(_el$60, "wrapMode", "none");
537
- _$setProp(_el$62, "width", "100%");
538
- _$setProp(_el$62, "flexDirection", "column");
539
- _$setProp(_el$62, "marginTop", 1);
540
- _$setProp(_el$62, "overflow", "hidden");
541
- _$insert(_el$62, _$createComponent(WizardSkillsDialogContent, {
732
+ var _el$78 = _$createElement("box"),
733
+ _el$79 = _$createElement("box"),
734
+ _el$80 = _$createElement("text"),
735
+ _el$81 = _$createElement("b"),
736
+ _el$83 = _$createElement("box"),
737
+ _el$84 = _$createElement("text"),
738
+ _el$86 = _$createElement("box");
739
+ _$insertNode(_el$78, _el$79);
740
+ _$insertNode(_el$78, _el$86);
741
+ _$setProp(_el$78, "width", "100%");
742
+ _$setProp(_el$78, "flexDirection", "column");
743
+ _$setProp(_el$78, "paddingLeft", 1);
744
+ _$setProp(_el$78, "paddingRight", 1);
745
+ _$setProp(_el$78, "paddingBottom", 1);
746
+ _$insertNode(_el$79, _el$80);
747
+ _$insertNode(_el$79, _el$83);
748
+ _$setProp(_el$79, "width", "100%");
749
+ _$setProp(_el$79, "flexDirection", "row");
750
+ _$setProp(_el$79, "justifyContent", "space-between");
751
+ _$setProp(_el$79, "overflow", "hidden");
752
+ _$insertNode(_el$80, _el$81);
753
+ _$setProp(_el$80, "wrapMode", "none");
754
+ _$setProp(_el$80, "overflow", "hidden");
755
+ _$insertNode(_el$81, _$createTextNode(`Wizard Skills`));
756
+ _$insertNode(_el$83, _el$84);
757
+ _$setProp(_el$83, "flexShrink", 0);
758
+ _$insertNode(_el$84, _$createTextNode(`Close`));
759
+ _$setProp(_el$84, "wrapMode", "none");
760
+ _$setProp(_el$86, "width", "100%");
761
+ _$setProp(_el$86, "flexDirection", "column");
762
+ _$setProp(_el$86, "marginTop", 1);
763
+ _$setProp(_el$86, "overflow", "hidden");
764
+ _$insert(_el$86, _$createComponent(WizardSkillsDialogContent, {
542
765
  get status() {
543
766
  return props.status;
544
767
  },
768
+ actionNotice: actionNotice,
545
769
  get theme() {
546
770
  return theme();
547
- }
771
+ },
772
+ onIgnoreSkill: ignoreSkill,
773
+ onInstallSkill: installSkill,
774
+ onUninstallSkill: uninstallSkill
548
775
  }));
549
776
  _$effect(_p$ => {
550
777
  var _v$11 = theme().text,
551
778
  _v$12 = props.onClose,
552
779
  _v$13 = theme().textMuted;
553
- _v$11 !== _p$.e && (_p$.e = _$setProp(_el$56, "fg", _v$11, _p$.e));
554
- _v$12 !== _p$.t && (_p$.t = _$setProp(_el$59, "onMouseUp", _v$12, _p$.t));
555
- _v$13 !== _p$.a && (_p$.a = _$setProp(_el$60, "fg", _v$13, _p$.a));
780
+ _v$11 !== _p$.e && (_p$.e = _$setProp(_el$80, "fg", _v$11, _p$.e));
781
+ _v$12 !== _p$.t && (_p$.t = _$setProp(_el$83, "onMouseUp", _v$12, _p$.t));
782
+ _v$13 !== _p$.a && (_p$.a = _$setProp(_el$84, "fg", _v$13, _p$.a));
556
783
  return _p$;
557
784
  }, {
558
785
  e: undefined,
559
786
  t: undefined,
560
787
  a: undefined
561
788
  });
562
- return _el$54;
789
+ return _el$78;
563
790
  })();
564
791
  };
565
792
  const openWizardSkillsDialog = (api, status, refreshStatus) => {
@@ -571,6 +798,7 @@ const openWizardSkillsDialog = (api, status, refreshStatus) => {
571
798
  dialog.replace(() => _$createComponent(WizardSkillsDialog, {
572
799
  api: api,
573
800
  status: status,
801
+ refreshStatus: refreshStatus,
574
802
  onClose: () => {
575
803
  dialog.clear?.();
576
804
  requestRender(api);