@aexol/opencode-wizard 0.1.8 → 0.1.11

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
@@ -1,3 +1,4 @@
1
+ import { memo as _$memo } from "@opentui/solid";
1
2
  import { createComponent as _$createComponent } from "@opentui/solid";
2
3
  import { effect as _$effect } from "@opentui/solid";
3
4
  import { createTextNode as _$createTextNode } from "@opentui/solid";
@@ -7,31 +8,63 @@ import { setProp as _$setProp } from "@opentui/solid";
7
8
  import { createElement as _$createElement } from "@opentui/solid";
8
9
  /** @jsxImportSource @opentui/solid */
9
10
 
10
- import { createMemo, createSignal } from 'solid-js';
11
+ import { createEffect, createMemo, createSignal } from 'solid-js';
11
12
  import { PLUGIN_ID, resolvePluginStatusSnapshot } from './server.js';
12
13
  const STATUS_TIMEOUT_MS = 5_000;
13
- const getSkillDisplayName = skill => skill.artifactName || skill.skillName || skill.skillSlug;
14
- const getSkillPolicy = skill => skill.policyLabel || skill.installPolicy;
15
- const formatSkillTags = skill => {
16
- const tagNames = skill.tags.map(tag => tag.label || tag.slug).filter(tag => tag.length > 0);
17
- if (tagNames.length === 0) return 'none';
18
- return tagNames.join(', ');
14
+ const STATUS_REFRESH_INTERVAL_MS = 5_000;
15
+ const MAX_STATUS_MESSAGE_LENGTH = 80;
16
+ const MAX_SKILL_DESCRIPTION_LENGTH = 96;
17
+ const MAX_SKILL_NAME_LENGTH = 48;
18
+ const MAX_SKILL_META_LENGTH = 72;
19
+ const MAX_SKILL_TAGS = 4;
20
+ const SKILLS_PAGE_SIZE = 5;
21
+ const compactStatusMessage = message => {
22
+ if (message.length <= MAX_STATUS_MESSAGE_LENGTH) return message;
23
+ return `${message.slice(0, MAX_STATUS_MESSAGE_LENGTH - 1)}…`;
24
+ };
25
+ const compactSkillDescription = message => {
26
+ if (message.length <= MAX_SKILL_DESCRIPTION_LENGTH) return message;
27
+ return `${message.slice(0, MAX_SKILL_DESCRIPTION_LENGTH - 1)}…`;
28
+ };
29
+ const compactSkillName = name => {
30
+ if (name.length <= MAX_SKILL_NAME_LENGTH) return name;
31
+ return `${name.slice(0, MAX_SKILL_NAME_LENGTH - 1)}…`;
32
+ };
33
+ const compactSkillMeta = meta => {
34
+ if (meta.length <= MAX_SKILL_META_LENGTH) return meta;
35
+ return `${meta.slice(0, MAX_SKILL_META_LENGTH - 1)}…`;
19
36
  };
20
37
  const formatSkillsCatalogUnavailableMessage = snapshot => {
21
38
  if (!snapshot.catalog && snapshot.status === 'missing_auth') {
22
- return 'skills catalog locked until interactive fetch authenticates; configured GraphQL URL is shown, but no ping was made because auth is missing';
39
+ return 'locked (authenticate via status/fetch)';
23
40
  }
24
- if (!snapshot.catalog) return `skills catalog unavailable: ${snapshot.message ?? snapshot.status}`;
25
- return 'skills catalog unavailable';
26
- };
27
- const formatSkillOptionDescription = skill => {
28
- const description = skill.artifactDescription || skill.skillSlug;
29
- return `${skill.contextKind.toUpperCase()} · ${getSkillPolicy(skill)} · v${skill.version || 'unknown'} · ${skill.skillName || skill.skillSlug} · ${formatSkillTags(skill)} · ${description}`;
41
+ if (!snapshot.catalog && snapshot.message) return compactStatusMessage(snapshot.message);
42
+ if (!snapshot.catalog) return `unavailable (${snapshot.status})`;
43
+ return 'unavailable';
30
44
  };
31
45
  const formatAuthStatus = snapshot => {
32
46
  if (snapshot.authState.status !== 'authenticated') return snapshot.authState.status;
33
47
  if (!snapshot.authState.email) return 'authenticated';
34
- return `authenticated as ${snapshot.authState.email}`;
48
+ return snapshot.authState.email;
49
+ };
50
+ const formatBackendOriginLabel = backendOrigin => {
51
+ try {
52
+ const {
53
+ hostname
54
+ } = new URL(backendOrigin);
55
+ if (hostname === 'localhost' || hostname === '127.0.0.1') return 'localhost';
56
+ return 'opencode-wizard';
57
+ } catch {
58
+ if (backendOrigin.includes('localhost') || backendOrigin.includes('127.0.0.1')) return 'localhost';
59
+ return 'opencode-wizard';
60
+ }
61
+ };
62
+ const requestRender = api => {
63
+ try {
64
+ api.renderer?.requestRender?.();
65
+ } catch {
66
+ // Ignore render request failures; state is still updated.
67
+ }
35
68
  };
36
69
  const Row = props => (() => {
37
70
  var _el$ = _$createElement("box"),
@@ -65,115 +98,86 @@ const Row = props => (() => {
65
98
  })();
66
99
  const Panel = props => (() => {
67
100
  var _el$5 = _$createElement("box"),
68
- _el$6 = _$createElement("text"),
69
- _el$7 = _$createElement("b");
101
+ _el$6 = _$createElement("box"),
102
+ _el$7 = _$createElement("box"),
103
+ _el$8 = _$createElement("text"),
104
+ _el$9 = _$createElement("b"),
105
+ _el$0 = _$createElement("box"),
106
+ _el$1 = _$createElement("text");
70
107
  _$insertNode(_el$5, _el$6);
71
108
  _$setProp(_el$5, "width", "100%");
72
109
  _$setProp(_el$5, "flexDirection", "column");
73
110
  _$setProp(_el$5, "paddingRight", 1);
74
111
  _$insertNode(_el$6, _el$7);
75
- _$setProp(_el$6, "wrapMode", "none");
112
+ _$insertNode(_el$6, _el$0);
113
+ _$setProp(_el$6, "width", "100%");
114
+ _$setProp(_el$6, "flexDirection", "row");
115
+ _$setProp(_el$6, "justifyContent", "space-between");
76
116
  _$setProp(_el$6, "overflow", "hidden");
77
- _$insert(_el$7, () => props.title);
117
+ _$insertNode(_el$7, _el$8);
118
+ _$setProp(_el$7, "flexShrink", 0);
119
+ _$insertNode(_el$8, _el$9);
120
+ _$setProp(_el$8, "wrapMode", "none");
121
+ _$setProp(_el$8, "overflow", "hidden");
122
+ _$insert(_el$9, () => props.title);
123
+ _$insertNode(_el$0, _el$1);
124
+ _$setProp(_el$0, "flexShrink", 0);
125
+ _$insertNode(_el$1, _$createTextNode(`open`));
126
+ _$setProp(_el$1, "wrapMode", "none");
78
127
  _$insert(_el$5, () => props.children, null);
79
128
  _$effect(_p$ => {
80
- var _v$3 = props.onPress,
81
- _v$4 = props.theme.text;
129
+ var _v$3 = props.onOpen,
130
+ _v$4 = props.theme.text,
131
+ _v$5 = props.theme.textMuted;
82
132
  _v$3 !== _p$.e && (_p$.e = _$setProp(_el$5, "onMouseUp", _v$3, _p$.e));
83
- _v$4 !== _p$.t && (_p$.t = _$setProp(_el$6, "fg", _v$4, _p$.t));
133
+ _v$4 !== _p$.t && (_p$.t = _$setProp(_el$8, "fg", _v$4, _p$.t));
134
+ _v$5 !== _p$.a && (_p$.a = _$setProp(_el$1, "fg", _v$5, _p$.a));
84
135
  return _p$;
85
136
  }, {
86
137
  e: undefined,
87
- t: undefined
138
+ t: undefined,
139
+ a: undefined
88
140
  });
89
141
  return _el$5;
90
142
  })();
91
- const openSkillsDialog = (api, status) => {
92
- const theme = api.theme.current;
93
- if (status.kind === 'ready' && status.snapshot.catalog) {
94
- const options = status.snapshot.catalog.skills.map(skill => ({
95
- title: getSkillDisplayName(skill),
96
- value: skill.skillSlug,
97
- description: formatSkillOptionDescription(skill)
98
- }));
99
- api.ui.dialog.replace(() => _$createComponent(api.ui.DialogSelect, {
100
- title: "Wizard skills catalog",
101
- placeholder: "Filter loaded skills",
102
- options: options,
103
- onSelect: option => {
104
- const selectedSkill = status.snapshot.catalog?.skills.find(skill => skill.skillSlug === option.value);
105
- if (!selectedSkill) return;
106
- api.ui.dialog.clear();
107
- }
108
- }));
109
- return;
143
+ const StatusContent = props => {
144
+ if (props.status.kind === 'loading') {
145
+ return (() => {
146
+ var _el$11 = _$createElement("text");
147
+ _$insertNode(_el$11, _$createTextNode(`loading…`));
148
+ _$setProp(_el$11, "wrapMode", "none");
149
+ _$setProp(_el$11, "overflow", "hidden");
150
+ _$effect(_$p => _$setProp(_el$11, "fg", props.theme.textMuted, _$p));
151
+ return _el$11;
152
+ })();
110
153
  }
111
- const message = status.kind === 'loading' ? 'Skills catalog is loading. Try again after the catalog event completes.' : status.kind === 'error' ? `Skills catalog unavailable: ${status.message}` : status.snapshot.status === 'missing_auth' ? 'Skills catalog is locked until interactive fetch authenticates.' : status.snapshot.message ?? 'Skills catalog unavailable.';
112
- api.ui.dialog.replace(() => _$createComponent(api.ui.Dialog, {
113
- size: "medium",
114
- onClose: () => {
115
- api.ui.dialog.clear();
154
+ if (props.status.kind === 'error') {
155
+ return (() => {
156
+ var _el$13 = _$createElement("text"),
157
+ _el$14 = _$createTextNode(`unavailable: `);
158
+ _$insertNode(_el$13, _el$14);
159
+ _$setProp(_el$13, "wrapMode", "none");
160
+ _$setProp(_el$13, "overflow", "hidden");
161
+ _$insert(_el$13, () => compactStatusMessage(props.status.message), null);
162
+ _$effect(_$p => _$setProp(_el$13, "fg", props.theme.warning, _$p));
163
+ return _el$13;
164
+ })();
165
+ }
166
+ return _$createComponent(ReadyRows, {
167
+ get snapshot() {
168
+ return props.status.snapshot;
116
169
  },
117
- get children() {
118
- var _el$8 = _$createElement("box"),
119
- _el$9 = _$createElement("text"),
120
- _el$0 = _$createElement("b"),
121
- _el$10 = _$createElement("text");
122
- _$insertNode(_el$8, _el$9);
123
- _$insertNode(_el$8, _el$10);
124
- _$setProp(_el$8, "width", "100%");
125
- _$setProp(_el$8, "flexDirection", "column");
126
- _$setProp(_el$8, "paddingLeft", 1);
127
- _$setProp(_el$8, "paddingRight", 1);
128
- _$insertNode(_el$9, _el$0);
129
- _$setProp(_el$9, "wrapMode", "none");
130
- _$insertNode(_el$0, _$createTextNode(`Wizard skills catalog`));
131
- _$setProp(_el$10, "marginTop", 1);
132
- _$insert(_el$10, message);
133
- _$effect(_p$ => {
134
- var _v$5 = theme.text,
135
- _v$6 = theme.warning;
136
- _v$5 !== _p$.e && (_p$.e = _$setProp(_el$9, "fg", _v$5, _p$.e));
137
- _v$6 !== _p$.t && (_p$.t = _$setProp(_el$10, "fg", _v$6, _p$.t));
138
- return _p$;
139
- }, {
140
- e: undefined,
141
- t: undefined
142
- });
143
- return _el$8;
170
+ get theme() {
171
+ return props.theme;
144
172
  }
145
- }));
173
+ });
146
174
  };
147
175
  const SkillsRows = props => {
148
176
  const theme = createMemo(() => props.api.theme.current);
149
177
  const statusContent = () => {
150
178
  const currentStatus = props.status();
151
- if (currentStatus.kind === 'loading') {
152
- return (() => {
153
- var _el$11 = _$createElement("text");
154
- _$insertNode(_el$11, _$createTextNode(`loading wizard skills catalog…`));
155
- _$setProp(_el$11, "wrapMode", "none");
156
- _$setProp(_el$11, "overflow", "hidden");
157
- _$effect(_$p => _$setProp(_el$11, "fg", theme().textMuted, _$p));
158
- return _el$11;
159
- })();
160
- }
161
- if (currentStatus.kind === 'error') {
162
- return (() => {
163
- var _el$13 = _$createElement("text"),
164
- _el$14 = _$createTextNode(`skills catalog unavailable: `);
165
- _$insertNode(_el$13, _el$14);
166
- _$setProp(_el$13, "wrapMode", "none");
167
- _$setProp(_el$13, "overflow", "hidden");
168
- _$insert(_el$13, () => currentStatus.message, null);
169
- _$effect(_$p => _$setProp(_el$13, "fg", theme().warning, _$p));
170
- return _el$13;
171
- })();
172
- }
173
- return _$createComponent(ReadyRows, {
174
- get snapshot() {
175
- return currentStatus.snapshot;
176
- },
179
+ return _$createComponent(StatusContent, {
180
+ status: currentStatus,
177
181
  get theme() {
178
182
  return theme();
179
183
  }
@@ -198,22 +202,222 @@ const CatalogBullet = props => (() => {
198
202
  _$effect(_$p => _$setProp(_el$16, "fg", props.theme.text, _$p));
199
203
  return _el$16;
200
204
  })();
205
+ const getSkillDisplayName = skill => skill.artifactName || skill.skillName || skill.skillSlug;
206
+ const getSkillDescription = skill => {
207
+ if (skill.whenToUse) return skill.whenToUse;
208
+ if (skill.artifactDescription) return skill.artifactDescription;
209
+ return null;
210
+ };
211
+ const getSkillTags = skill => {
212
+ const tagLabels = skill.tags.map(tag => tag.label || tag.slug).filter(Boolean).slice(0, MAX_SKILL_TAGS);
213
+ if (tagLabels.length === 0) return 'no tags';
214
+ return tagLabels.join(', ');
215
+ };
216
+ const getSkillMeta = skill => `${skill.policyLabel} · ${skill.contextKind} · ${getSkillTags(skill)}`;
217
+ const SkillCatalogRow = props => {
218
+ const description = getSkillDescription(props.skill);
219
+ return (() => {
220
+ var _el$18 = _$createElement("box"),
221
+ _el$19 = _$createElement("text"),
222
+ _el$20 = _$createElement("b"),
223
+ _el$21 = _$createElement("text");
224
+ _$insertNode(_el$18, _el$19);
225
+ _$insertNode(_el$18, _el$21);
226
+ _$setProp(_el$18, "width", "100%");
227
+ _$setProp(_el$18, "flexDirection", "column");
228
+ _$setProp(_el$18, "overflow", "hidden");
229
+ _$setProp(_el$18, "marginBottom", 1);
230
+ _$insertNode(_el$19, _el$20);
231
+ _$setProp(_el$19, "wrapMode", "none");
232
+ _$setProp(_el$19, "overflow", "hidden");
233
+ _$insert(_el$20, () => compactSkillName(getSkillDisplayName(props.skill)));
234
+ _$setProp(_el$21, "wrapMode", "none");
235
+ _$setProp(_el$21, "overflow", "hidden");
236
+ _$insert(_el$21, () => compactSkillMeta(getSkillMeta(props.skill)));
237
+ _$insert(_el$18, description ? (() => {
238
+ var _el$22 = _$createElement("text");
239
+ _$setProp(_el$22, "wrapMode", "none");
240
+ _$setProp(_el$22, "overflow", "hidden");
241
+ _$insert(_el$22, () => compactSkillDescription(description));
242
+ _$effect(_$p => _$setProp(_el$22, "fg", props.theme.text, _$p));
243
+ return _el$22;
244
+ })() : null, null);
245
+ _$effect(_p$ => {
246
+ var _v$6 = props.theme.text,
247
+ _v$7 = props.theme.textMuted;
248
+ _v$6 !== _p$.e && (_p$.e = _$setProp(_el$19, "fg", _v$6, _p$.e));
249
+ _v$7 !== _p$.t && (_p$.t = _$setProp(_el$21, "fg", _v$7, _p$.t));
250
+ return _p$;
251
+ }, {
252
+ e: undefined,
253
+ t: undefined
254
+ });
255
+ return _el$18;
256
+ })();
257
+ };
258
+ const WizardSkillsDialogContent = props => {
259
+ const [page, setPage] = createSignal(0);
260
+ const content = () => {
261
+ const currentStatus = props.status();
262
+ if (currentStatus.kind === 'loading') {
263
+ return (() => {
264
+ var _el$23 = _$createElement("text");
265
+ _$insertNode(_el$23, _$createTextNode(`Refreshing published skills…`));
266
+ _$setProp(_el$23, "wrapMode", "none");
267
+ _$setProp(_el$23, "overflow", "hidden");
268
+ _$effect(_$p => _$setProp(_el$23, "fg", props.theme.textMuted, _$p));
269
+ return _el$23;
270
+ })();
271
+ }
272
+ if (currentStatus.kind === 'error') {
273
+ return (() => {
274
+ var _el$25 = _$createElement("text"),
275
+ _el$26 = _$createTextNode(`unavailable: `);
276
+ _$insertNode(_el$25, _el$26);
277
+ _$setProp(_el$25, "wrapMode", "none");
278
+ _$setProp(_el$25, "overflow", "hidden");
279
+ _$insert(_el$25, () => compactStatusMessage(currentStatus.message), null);
280
+ _$effect(_$p => _$setProp(_el$25, "fg", props.theme.warning, _$p));
281
+ return _el$25;
282
+ })();
283
+ }
284
+ if (!currentStatus.snapshot.catalog) {
285
+ return (() => {
286
+ var _el$27 = _$createElement("text"),
287
+ _el$28 = _$createTextNode(`catalog `);
288
+ _$insertNode(_el$27, _el$28);
289
+ _$setProp(_el$27, "wrapMode", "none");
290
+ _$setProp(_el$27, "overflow", "hidden");
291
+ _$insert(_el$27, () => formatSkillsCatalogUnavailableMessage(currentStatus.snapshot), null);
292
+ _$effect(_$p => _$setProp(_el$27, "fg", props.theme.textMuted, _$p));
293
+ return _el$27;
294
+ })();
295
+ }
296
+ const {
297
+ catalog
298
+ } = currentStatus.snapshot;
299
+ const totalPages = Math.max(1, Math.ceil(catalog.skills.length / SKILLS_PAGE_SIZE));
300
+ const currentPage = Math.min(page(), totalPages - 1);
301
+ const startIndex = currentPage * SKILLS_PAGE_SIZE;
302
+ const endIndex = Math.min(startIndex + SKILLS_PAGE_SIZE, catalog.skills.length);
303
+ const visibleSkills = catalog.skills.slice(startIndex, endIndex);
304
+ const canGoBack = currentPage > 0;
305
+ const canGoForward = currentPage < totalPages - 1;
306
+ const goBack = () => {
307
+ if (!canGoBack) return;
308
+ setPage(currentPage - 1);
309
+ };
310
+ const goForward = () => {
311
+ if (!canGoForward) return;
312
+ setPage(currentPage + 1);
313
+ };
314
+ return (() => {
315
+ var _el$29 = _$createElement("box"),
316
+ _el$30 = _$createElement("box"),
317
+ _el$31 = _$createElement("text"),
318
+ _el$32 = _$createElement("b"),
319
+ _el$33 = _$createTextNode(` skills`),
320
+ _el$34 = _$createTextNode(`&nbsp;· `),
321
+ _el$35 = _$createTextNode(` global · `),
322
+ _el$36 = _$createTextNode(` workspace`),
323
+ _el$37 = _$createElement("text"),
324
+ _el$38 = _$createTextNode(`page `),
325
+ _el$39 = _$createTextNode(`/`),
326
+ _el$40 = _$createElement("box"),
327
+ _el$41 = _$createElement("box"),
328
+ _el$42 = _$createElement("box"),
329
+ _el$43 = _$createElement("text"),
330
+ _el$45 = _$createElement("text"),
331
+ _el$46 = _$createTextNode(` shown`),
332
+ _el$47 = _$createElement("box"),
333
+ _el$48 = _$createElement("text");
334
+ _$insertNode(_el$29, _el$30);
335
+ _$insertNode(_el$29, _el$40);
336
+ _$insertNode(_el$29, _el$41);
337
+ _$setProp(_el$29, "width", "100%");
338
+ _$setProp(_el$29, "flexDirection", "column");
339
+ _$setProp(_el$29, "overflow", "hidden");
340
+ _$insertNode(_el$30, _el$31);
341
+ _$insertNode(_el$30, _el$37);
342
+ _$setProp(_el$30, "width", "100%");
343
+ _$setProp(_el$30, "flexDirection", "row");
344
+ _$setProp(_el$30, "justifyContent", "space-between");
345
+ _$setProp(_el$30, "overflow", "hidden");
346
+ _$insertNode(_el$31, _el$32);
347
+ _$insertNode(_el$31, _el$34);
348
+ _$insertNode(_el$31, _el$35);
349
+ _$insertNode(_el$31, _el$36);
350
+ _$setProp(_el$31, "wrapMode", "none");
351
+ _$setProp(_el$31, "overflow", "hidden");
352
+ _$insertNode(_el$32, _el$33);
353
+ _$insert(_el$32, () => catalog.publishedSkillCount, _el$33);
354
+ _$insert(_el$31, () => catalog.assignmentCounts.global, _el$35);
355
+ _$insert(_el$31, () => catalog.assignmentCounts.project, _el$36);
356
+ _$insertNode(_el$37, _el$38);
357
+ _$insertNode(_el$37, _el$39);
358
+ _$setProp(_el$37, "wrapMode", "none");
359
+ _$insert(_el$37, currentPage + 1, _el$39);
360
+ _$insert(_el$37, totalPages, null);
361
+ _$setProp(_el$40, "width", "100%");
362
+ _$setProp(_el$40, "flexDirection", "column");
363
+ _$setProp(_el$40, "marginTop", 1);
364
+ _$setProp(_el$40, "overflow", "hidden");
365
+ _$insert(_el$40, () => visibleSkills.map(skill => _$createComponent(SkillCatalogRow, {
366
+ skill: skill,
367
+ get theme() {
368
+ return props.theme;
369
+ }
370
+ })));
371
+ _$insertNode(_el$41, _el$42);
372
+ _$insertNode(_el$41, _el$45);
373
+ _$insertNode(_el$41, _el$47);
374
+ _$setProp(_el$41, "width", "100%");
375
+ _$setProp(_el$41, "flexDirection", "row");
376
+ _$setProp(_el$41, "justifyContent", "space-between");
377
+ _$setProp(_el$41, "overflow", "hidden");
378
+ _$insertNode(_el$42, _el$43);
379
+ _$setProp(_el$42, "onMouseUp", goBack);
380
+ _$setProp(_el$42, "flexShrink", 0);
381
+ _$insertNode(_el$43, _$createTextNode(`← Prev`));
382
+ _$setProp(_el$43, "wrapMode", "none");
383
+ _$insertNode(_el$45, _el$46);
384
+ _$setProp(_el$45, "wrapMode", "none");
385
+ _$setProp(_el$45, "overflow", "hidden");
386
+ _$insert(_el$45, () => visibleSkills.length, _el$46);
387
+ _$insertNode(_el$47, _el$48);
388
+ _$setProp(_el$47, "onMouseUp", goForward);
389
+ _$setProp(_el$47, "flexShrink", 0);
390
+ _$insertNode(_el$48, _$createTextNode(`Next →`));
391
+ _$setProp(_el$48, "wrapMode", "none");
392
+ _$effect(_p$ => {
393
+ var _v$8 = props.theme.text,
394
+ _v$9 = props.theme.textMuted,
395
+ _v$0 = canGoBack ? props.theme.text : props.theme.textMuted,
396
+ _v$1 = props.theme.textMuted,
397
+ _v$10 = canGoForward ? props.theme.text : props.theme.textMuted;
398
+ _v$8 !== _p$.e && (_p$.e = _$setProp(_el$31, "fg", _v$8, _p$.e));
399
+ _v$9 !== _p$.t && (_p$.t = _$setProp(_el$37, "fg", _v$9, _p$.t));
400
+ _v$0 !== _p$.a && (_p$.a = _$setProp(_el$43, "fg", _v$0, _p$.a));
401
+ _v$1 !== _p$.o && (_p$.o = _$setProp(_el$45, "fg", _v$1, _p$.o));
402
+ _v$10 !== _p$.i && (_p$.i = _$setProp(_el$48, "fg", _v$10, _p$.i));
403
+ return _p$;
404
+ }, {
405
+ e: undefined,
406
+ t: undefined,
407
+ a: undefined,
408
+ o: undefined,
409
+ i: undefined
410
+ });
411
+ return _el$29;
412
+ })();
413
+ };
414
+ return _$memo(content);
415
+ };
201
416
  const ReadyRows = props => {
202
417
  const statusRows = [_$createComponent(Row, {
203
- label: "backend",
204
- get value() {
205
- return props.snapshot.backendOrigin;
206
- },
207
- get labelColor() {
208
- return props.theme.textMuted;
209
- },
210
- get valueColor() {
211
- return props.theme.text;
212
- }
213
- }), _$createComponent(Row, {
214
- label: "graphql",
418
+ label: "url",
215
419
  get value() {
216
- return props.snapshot.graphqlUrl;
420
+ return formatBackendOriginLabel(props.snapshot.backendOrigin);
217
421
  },
218
422
  get labelColor() {
219
423
  return props.theme.textMuted;
@@ -235,12 +439,12 @@ const ReadyRows = props => {
235
439
  })];
236
440
  if (!props.snapshot.catalog) {
237
441
  return (() => {
238
- var _el$18 = _$createElement("box");
239
- _$setProp(_el$18, "width", "100%");
240
- _$setProp(_el$18, "flexDirection", "column");
241
- _$setProp(_el$18, "overflow", "hidden");
242
- _$insert(_el$18, statusRows, null);
243
- _$insert(_el$18, _$createComponent(Row, {
442
+ var _el$50 = _$createElement("box");
443
+ _$setProp(_el$50, "width", "100%");
444
+ _$setProp(_el$50, "flexDirection", "column");
445
+ _$setProp(_el$50, "overflow", "hidden");
446
+ _$insert(_el$50, statusRows, null);
447
+ _$insert(_el$50, _$createComponent(Row, {
244
448
  label: "catalog",
245
449
  get value() {
246
450
  return formatSkillsCatalogUnavailableMessage(props.snapshot);
@@ -252,22 +456,22 @@ const ReadyRows = props => {
252
456
  return props.theme.text;
253
457
  }
254
458
  }), null);
255
- return _el$18;
459
+ return _el$50;
256
460
  })();
257
461
  }
258
462
  const counts = props.snapshot.catalog.assignmentCounts;
259
463
  return (() => {
260
- var _el$19 = _$createElement("box"),
261
- _el$20 = _$createElement("text");
262
- _$insertNode(_el$19, _el$20);
263
- _$setProp(_el$19, "width", "100%");
264
- _$setProp(_el$19, "flexDirection", "column");
265
- _$setProp(_el$19, "overflow", "hidden");
266
- _$insert(_el$19, statusRows, _el$20);
267
- _$insertNode(_el$20, _$createTextNode(`catalog:`));
268
- _$setProp(_el$20, "wrapMode", "none");
269
- _$setProp(_el$20, "overflow", "hidden");
270
- _$insert(_el$19, _$createComponent(CatalogBullet, {
464
+ var _el$51 = _$createElement("box"),
465
+ _el$52 = _$createElement("text");
466
+ _$insertNode(_el$51, _el$52);
467
+ _$setProp(_el$51, "width", "100%");
468
+ _$setProp(_el$51, "flexDirection", "column");
469
+ _$setProp(_el$51, "overflow", "hidden");
470
+ _$insert(_el$51, statusRows, _el$52);
471
+ _$insertNode(_el$52, _$createTextNode(`catalog:`));
472
+ _$setProp(_el$52, "wrapMode", "none");
473
+ _$setProp(_el$52, "overflow", "hidden");
474
+ _$insert(_el$51, _$createComponent(CatalogBullet, {
271
475
  get value() {
272
476
  return `${props.snapshot.catalog.publishedSkillCount} loaded`;
273
477
  },
@@ -275,7 +479,7 @@ const ReadyRows = props => {
275
479
  return props.theme;
276
480
  }
277
481
  }), null);
278
- _$insert(_el$19, _$createComponent(CatalogBullet, {
482
+ _$insert(_el$51, _$createComponent(CatalogBullet, {
279
483
  get value() {
280
484
  return `${counts.global} global`;
281
485
  },
@@ -283,7 +487,7 @@ const ReadyRows = props => {
283
487
  return props.theme;
284
488
  }
285
489
  }), null);
286
- _$insert(_el$19, _$createComponent(CatalogBullet, {
490
+ _$insert(_el$51, _$createComponent(CatalogBullet, {
287
491
  get value() {
288
492
  return `${counts.project} workspace`;
289
493
  },
@@ -291,11 +495,91 @@ const ReadyRows = props => {
291
495
  return props.theme;
292
496
  }
293
497
  }), null);
294
- _$effect(_$p => _$setProp(_el$20, "fg", props.theme.textMuted, _$p));
295
- return _el$19;
498
+ _$effect(_$p => _$setProp(_el$52, "fg", props.theme.textMuted, _$p));
499
+ return _el$51;
296
500
  })();
297
501
  };
298
- const createWizardStatusSlot = (api, status) => ({
502
+ const WizardSkillsDialog = props => {
503
+ const theme = createMemo(() => props.api.theme.current);
504
+ createEffect(() => {
505
+ props.api.ui?.dialog?.setSize?.('xlarge');
506
+ });
507
+ return (() => {
508
+ var _el$54 = _$createElement("box"),
509
+ _el$55 = _$createElement("box"),
510
+ _el$56 = _$createElement("text"),
511
+ _el$57 = _$createElement("b"),
512
+ _el$59 = _$createElement("box"),
513
+ _el$60 = _$createElement("text"),
514
+ _el$62 = _$createElement("box");
515
+ _$insertNode(_el$54, _el$55);
516
+ _$insertNode(_el$54, _el$62);
517
+ _$setProp(_el$54, "width", "100%");
518
+ _$setProp(_el$54, "flexDirection", "column");
519
+ _$setProp(_el$54, "paddingLeft", 1);
520
+ _$setProp(_el$54, "paddingRight", 1);
521
+ _$setProp(_el$54, "paddingBottom", 1);
522
+ _$insertNode(_el$55, _el$56);
523
+ _$insertNode(_el$55, _el$59);
524
+ _$setProp(_el$55, "width", "100%");
525
+ _$setProp(_el$55, "flexDirection", "row");
526
+ _$setProp(_el$55, "justifyContent", "space-between");
527
+ _$setProp(_el$55, "overflow", "hidden");
528
+ _$insertNode(_el$56, _el$57);
529
+ _$setProp(_el$56, "wrapMode", "none");
530
+ _$setProp(_el$56, "overflow", "hidden");
531
+ _$insertNode(_el$57, _$createTextNode(`Wizard Skills`));
532
+ _$insertNode(_el$59, _el$60);
533
+ _$setProp(_el$59, "flexShrink", 0);
534
+ _$insertNode(_el$60, _$createTextNode(`Close`));
535
+ _$setProp(_el$60, "wrapMode", "none");
536
+ _$setProp(_el$62, "width", "100%");
537
+ _$setProp(_el$62, "flexDirection", "column");
538
+ _$setProp(_el$62, "marginTop", 1);
539
+ _$setProp(_el$62, "overflow", "hidden");
540
+ _$insert(_el$62, _$createComponent(WizardSkillsDialogContent, {
541
+ get status() {
542
+ return props.status;
543
+ },
544
+ get theme() {
545
+ return theme();
546
+ }
547
+ }));
548
+ _$effect(_p$ => {
549
+ var _v$11 = theme().text,
550
+ _v$12 = props.onClose,
551
+ _v$13 = theme().textMuted;
552
+ _v$11 !== _p$.e && (_p$.e = _$setProp(_el$56, "fg", _v$11, _p$.e));
553
+ _v$12 !== _p$.t && (_p$.t = _$setProp(_el$59, "onMouseUp", _v$12, _p$.t));
554
+ _v$13 !== _p$.a && (_p$.a = _$setProp(_el$60, "fg", _v$13, _p$.a));
555
+ return _p$;
556
+ }, {
557
+ e: undefined,
558
+ t: undefined,
559
+ a: undefined
560
+ });
561
+ return _el$54;
562
+ })();
563
+ };
564
+ const openWizardSkillsDialog = (api, status, refreshStatus) => {
565
+ const dialog = api.ui?.dialog;
566
+ if (!dialog?.replace) return;
567
+ refreshStatus({
568
+ showLoading: true
569
+ });
570
+ dialog.replace(() => _$createComponent(WizardSkillsDialog, {
571
+ api: api,
572
+ status: status,
573
+ onClose: () => {
574
+ dialog.clear?.();
575
+ requestRender(api);
576
+ }
577
+ }), () => {
578
+ requestRender(api);
579
+ });
580
+ requestRender(api);
581
+ };
582
+ const createWizardStatusSlot = (api, status, refreshStatus) => ({
299
583
  order: 240,
300
584
  slots: {
301
585
  home_bottom: () => _$createComponent(Panel, {
@@ -303,7 +587,7 @@ const createWizardStatusSlot = (api, status) => ({
303
587
  get theme() {
304
588
  return api.theme.current;
305
589
  },
306
- onPress: () => openSkillsDialog(api, status()),
590
+ onOpen: () => openWizardSkillsDialog(api, status, refreshStatus),
307
591
  get children() {
308
592
  return _$createComponent(SkillsRows, {
309
593
  api: api,
@@ -316,7 +600,7 @@ const createWizardStatusSlot = (api, status) => ({
316
600
  get theme() {
317
601
  return api.theme.current;
318
602
  },
319
- onPress: () => openSkillsDialog(api, status()),
603
+ onOpen: () => openWizardSkillsDialog(api, status, refreshStatus),
320
604
  get children() {
321
605
  return _$createComponent(SkillsRows, {
322
606
  api: api,
@@ -348,8 +632,21 @@ const tui = async api => {
348
632
  const [status, setStatus] = createSignal({
349
633
  kind: 'loading'
350
634
  });
351
- api.slots.register(createWizardStatusSlot(api, status));
352
- void loadStatus(api).then(setStatus);
635
+ const refreshStatus = options => {
636
+ if (options?.showLoading) {
637
+ setStatus({
638
+ kind: 'loading'
639
+ });
640
+ requestRender(api);
641
+ }
642
+ void loadStatus(api).then(nextStatus => {
643
+ setStatus(nextStatus);
644
+ requestRender(api);
645
+ });
646
+ };
647
+ api.slots.register(createWizardStatusSlot(api, status, refreshStatus));
648
+ refreshStatus();
649
+ setInterval(refreshStatus, STATUS_REFRESH_INTERVAL_MS);
353
650
  };
354
651
  export default {
355
652
  id: PLUGIN_ID,