@aexol/opencode-wizard 0.1.15 → 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.
@@ -0,0 +1,5 @@
1
+ export declare const PRIVATE_JSON_FILE_MODE = 384;
2
+ export declare const PRIVATE_JSON_DIRECTORY_MODE = 448;
3
+ export declare const readJsonFile: (filePath: string) => Promise<unknown | null>;
4
+ export declare const writePrivateJsonFile: (filePath: string, value: unknown) => Promise<void>;
5
+ export declare const deleteFileIfExists: (filePath: string) => Promise<void>;
@@ -0,0 +1,43 @@
1
+ import fs from 'node:fs/promises';
2
+ import crypto from 'node:crypto';
3
+ import path from 'node:path';
4
+ export const PRIVATE_JSON_FILE_MODE = 0o600;
5
+ export const PRIVATE_JSON_DIRECTORY_MODE = 0o700;
6
+ export const readJsonFile = async filePath => {
7
+ try {
8
+ const raw = await fs.readFile(filePath, 'utf8');
9
+ const parsed = JSON.parse(raw);
10
+ return parsed;
11
+ } catch {
12
+ return null;
13
+ }
14
+ };
15
+ export const writePrivateJsonFile = async (filePath, value) => {
16
+ const directoryPath = path.dirname(filePath);
17
+ const temporaryFilePath = path.join(directoryPath, `.${path.basename(filePath)}.${process.pid}.${crypto.randomUUID()}.tmp`);
18
+ await fs.mkdir(directoryPath, {
19
+ recursive: true,
20
+ mode: PRIVATE_JSON_DIRECTORY_MODE
21
+ });
22
+ try {
23
+ await fs.writeFile(temporaryFilePath, `${JSON.stringify(value, null, 2)}\n`, {
24
+ encoding: 'utf8',
25
+ mode: PRIVATE_JSON_FILE_MODE,
26
+ flag: 'w'
27
+ });
28
+ await fs.chmod(temporaryFilePath, PRIVATE_JSON_FILE_MODE).catch(() => undefined);
29
+ await fs.rename(temporaryFilePath, filePath);
30
+ await fs.chmod(filePath, PRIVATE_JSON_FILE_MODE).catch(() => undefined);
31
+ } catch (error) {
32
+ await fs.rm(temporaryFilePath, {
33
+ force: true
34
+ }).catch(() => undefined);
35
+ throw error;
36
+ }
37
+ };
38
+ export const deleteFileIfExists = async filePath => {
39
+ await fs.rm(filePath, {
40
+ force: true
41
+ });
42
+ };
43
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["fs","crypto","path","PRIVATE_JSON_FILE_MODE","PRIVATE_JSON_DIRECTORY_MODE","readJsonFile","filePath","raw","readFile","parsed","JSON","parse","writePrivateJsonFile","value","directoryPath","dirname","temporaryFilePath","join","basename","process","pid","randomUUID","mkdir","recursive","mode","writeFile","stringify","encoding","flag","chmod","catch","undefined","rename","error","rm","force","deleteFileIfExists"],"sources":["../src/storage.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport crypto from 'node:crypto';\nimport path from 'node:path';\n\nexport const PRIVATE_JSON_FILE_MODE = 0o600;\nexport const PRIVATE_JSON_DIRECTORY_MODE = 0o700;\n\nexport const readJsonFile = async (filePath: string): Promise<unknown | null> => {\n try {\n const raw = await fs.readFile(filePath, 'utf8');\n const parsed: unknown = JSON.parse(raw);\n return parsed;\n } catch {\n return null;\n }\n};\n\nexport const writePrivateJsonFile = async (filePath: string, value: unknown): Promise<void> => {\n const directoryPath = path.dirname(filePath);\n const temporaryFilePath = path.join(\n directoryPath,\n `.${path.basename(filePath)}.${process.pid}.${crypto.randomUUID()}.tmp`,\n );\n\n await fs.mkdir(directoryPath, { recursive: true, mode: PRIVATE_JSON_DIRECTORY_MODE });\n\n try {\n await fs.writeFile(temporaryFilePath, `${JSON.stringify(value, null, 2)}\\n`, {\n encoding: 'utf8',\n mode: PRIVATE_JSON_FILE_MODE,\n flag: 'w',\n });\n await fs.chmod(temporaryFilePath, PRIVATE_JSON_FILE_MODE).catch(() => undefined);\n await fs.rename(temporaryFilePath, filePath);\n await fs.chmod(filePath, PRIVATE_JSON_FILE_MODE).catch(() => undefined);\n } catch (error) {\n await fs.rm(temporaryFilePath, { force: true }).catch(() => undefined);\n throw error;\n }\n};\n\nexport const deleteFileIfExists = async (filePath: string): Promise<void> => {\n await fs.rm(filePath, { force: true });\n};\n"],"mappings":"AAAA,OAAOA,EAAE,MAAM,kBAAkB;AACjC,OAAOC,MAAM,MAAM,aAAa;AAChC,OAAOC,IAAI,MAAM,WAAW;AAE5B,OAAO,MAAMC,sBAAsB,GAAG,KAAK;AAC3C,OAAO,MAAMC,2BAA2B,GAAG,KAAK;AAEhD,OAAO,MAAMC,YAAY,GAAG,MAAOC,QAAgB,IAA8B;EAC/E,IAAI;IACF,MAAMC,GAAG,GAAG,MAAMP,EAAE,CAACQ,QAAQ,CAACF,QAAQ,EAAE,MAAM,CAAC;IAC/C,MAAMG,MAAe,GAAGC,IAAI,CAACC,KAAK,CAACJ,GAAG,CAAC;IACvC,OAAOE,MAAM;EACf,CAAC,CAAC,MAAM;IACN,OAAO,IAAI;EACb;AACF,CAAC;AAED,OAAO,MAAMG,oBAAoB,GAAG,MAAAA,CAAON,QAAgB,EAAEO,KAAc,KAAoB;EAC7F,MAAMC,aAAa,GAAGZ,IAAI,CAACa,OAAO,CAACT,QAAQ,CAAC;EAC5C,MAAMU,iBAAiB,GAAGd,IAAI,CAACe,IAAI,CACjCH,aAAa,EACb,IAAIZ,IAAI,CAACgB,QAAQ,CAACZ,QAAQ,CAAC,IAAIa,OAAO,CAACC,GAAG,IAAInB,MAAM,CAACoB,UAAU,CAAC,CAAC,MACnE,CAAC;EAED,MAAMrB,EAAE,CAACsB,KAAK,CAACR,aAAa,EAAE;IAAES,SAAS,EAAE,IAAI;IAAEC,IAAI,EAAEpB;EAA4B,CAAC,CAAC;EAErF,IAAI;IACF,MAAMJ,EAAE,CAACyB,SAAS,CAACT,iBAAiB,EAAE,GAAGN,IAAI,CAACgB,SAAS,CAACb,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;MAC3Ec,QAAQ,EAAE,MAAM;MAChBH,IAAI,EAAErB,sBAAsB;MAC5ByB,IAAI,EAAE;IACR,CAAC,CAAC;IACF,MAAM5B,EAAE,CAAC6B,KAAK,CAACb,iBAAiB,EAAEb,sBAAsB,CAAC,CAAC2B,KAAK,CAAC,MAAMC,SAAS,CAAC;IAChF,MAAM/B,EAAE,CAACgC,MAAM,CAAChB,iBAAiB,EAAEV,QAAQ,CAAC;IAC5C,MAAMN,EAAE,CAAC6B,KAAK,CAACvB,QAAQ,EAAEH,sBAAsB,CAAC,CAAC2B,KAAK,CAAC,MAAMC,SAAS,CAAC;EACzE,CAAC,CAAC,OAAOE,KAAK,EAAE;IACd,MAAMjC,EAAE,CAACkC,EAAE,CAAClB,iBAAiB,EAAE;MAAEmB,KAAK,EAAE;IAAK,CAAC,CAAC,CAACL,KAAK,CAAC,MAAMC,SAAS,CAAC;IACtE,MAAME,KAAK;EACb;AACF,CAAC;AAED,OAAO,MAAMG,kBAAkB,GAAG,MAAO9B,QAAgB,IAAoB;EAC3E,MAAMN,EAAE,CAACkC,EAAE,CAAC5B,QAAQ,EAAE;IAAE6B,KAAK,EAAE;EAAK,CAAC,CAAC;AACxC,CAAC","ignoreList":[]}
package/dist/tui.js CHANGED
@@ -220,6 +220,10 @@ const getRowStateLabel = row => {
220
220
  if (row.state === 'installable') return 'not installed';
221
221
  return row.state === 'installed-global' ? 'installed global' : 'installed project';
222
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
+ };
223
227
  const SkillCatalogRow = props => {
224
228
  const skill = props.row.skill;
225
229
  const description = getSkillDescription(skill);
@@ -520,7 +524,33 @@ const WizardSkillsDialogContent = props => {
520
524
  return _el$49;
521
525
  })();
522
526
  };
523
- 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
+ })();
524
554
  };
525
555
  const ReadyRows = props => {
526
556
  const statusRows = [_$createComponent(Row, {
@@ -548,12 +578,12 @@ const ReadyRows = props => {
548
578
  })];
549
579
  if (!props.snapshot.catalog) {
550
580
  return (() => {
551
- var _el$72 = _$createElement("box");
552
- _$setProp(_el$72, "width", "100%");
553
- _$setProp(_el$72, "flexDirection", "column");
554
- _$setProp(_el$72, "overflow", "hidden");
555
- _$insert(_el$72, statusRows, null);
556
- _$insert(_el$72, _$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, {
557
587
  label: "catalog",
558
588
  get value() {
559
589
  return formatSkillsCatalogUnavailableMessage(props.snapshot);
@@ -565,22 +595,22 @@ const ReadyRows = props => {
565
595
  return props.theme.text;
566
596
  }
567
597
  }), null);
568
- return _el$72;
598
+ return _el$74;
569
599
  })();
570
600
  }
571
601
  const counts = props.snapshot.catalog.assignmentCounts;
572
602
  return (() => {
573
- var _el$73 = _$createElement("box"),
574
- _el$74 = _$createElement("text");
575
- _$insertNode(_el$73, _el$74);
576
- _$setProp(_el$73, "width", "100%");
577
- _$setProp(_el$73, "flexDirection", "column");
578
- _$setProp(_el$73, "overflow", "hidden");
579
- _$insert(_el$73, statusRows, _el$74);
580
- _$insertNode(_el$74, _$createTextNode(`catalog:`));
581
- _$setProp(_el$74, "wrapMode", "none");
582
- _$setProp(_el$74, "overflow", "hidden");
583
- _$insert(_el$73, _$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, {
584
614
  get value() {
585
615
  return `${props.snapshot.catalog.publishedSkillCount} loaded`;
586
616
  },
@@ -588,7 +618,7 @@ const ReadyRows = props => {
588
618
  return props.theme;
589
619
  }
590
620
  }), null);
591
- _$insert(_el$73, _$createComponent(CatalogBullet, {
621
+ _$insert(_el$75, _$createComponent(CatalogBullet, {
592
622
  get value() {
593
623
  return `${counts.global} global`;
594
624
  },
@@ -596,7 +626,7 @@ const ReadyRows = props => {
596
626
  return props.theme;
597
627
  }
598
628
  }), null);
599
- _$insert(_el$73, _$createComponent(CatalogBullet, {
629
+ _$insert(_el$75, _$createComponent(CatalogBullet, {
600
630
  get value() {
601
631
  return `${counts.project} workspace`;
602
632
  },
@@ -604,7 +634,7 @@ const ReadyRows = props => {
604
634
  return props.theme;
605
635
  }
606
636
  }), null);
607
- _$insert(_el$73, _$createComponent(CatalogBullet, {
637
+ _$insert(_el$75, _$createComponent(CatalogBullet, {
608
638
  get value() {
609
639
  return `${props.snapshot.ignoredPublishedSkills.count} ignored`;
610
640
  },
@@ -612,13 +642,30 @@ const ReadyRows = props => {
612
642
  return props.theme;
613
643
  }
614
644
  }), null);
615
- _$effect(_$p => _$setProp(_el$74, "fg", props.theme.textMuted, _$p));
616
- return _el$73;
645
+ _$effect(_$p => _$setProp(_el$76, "fg", props.theme.textMuted, _$p));
646
+ return _el$75;
617
647
  })();
618
648
  };
619
649
  const WizardSkillsDialog = props => {
620
650
  const theme = createMemo(() => props.api.theme.current);
621
- const refreshAfterPreferenceChange = () => {
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
+ });
622
669
  props.refreshStatus({
623
670
  showLoading: false
624
671
  });
@@ -628,6 +675,11 @@ const WizardSkillsDialog = props => {
628
675
  const currentStatus = props.status();
629
676
  if (currentStatus.kind !== 'ready') return;
630
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);
631
683
  void setPublishedSkillIgnored({
632
684
  worktree: props.api.state.path.worktree,
633
685
  directory: props.api.state.path.directory,
@@ -635,12 +687,17 @@ const WizardSkillsDialog = props => {
635
687
  skillSlug: row.skill.skillSlug,
636
688
  ignored: !row.ignored,
637
689
  preferenceScope: row.state === 'installed-global' ? 'global' : 'project'
638
- }).then(refreshAfterPreferenceChange).catch(refreshAfterPreferenceChange);
690
+ }).then(() => refreshAfterPreferenceChange(row.ignored ? 'Skill is no longer ignored.' : 'Skill ignored.')).catch(showPreferenceFailure);
639
691
  };
640
692
  const installSkill = (row, preferenceScope) => {
641
693
  const currentStatus = props.status();
642
694
  if (currentStatus.kind !== 'ready') return;
643
695
  const scopeKey = currentStatus.snapshot.ignoredPublishedSkills.scopeKey;
696
+ setActionNotice({
697
+ kind: 'pending',
698
+ message: `Installing skill for ${preferenceScope}…`
699
+ });
700
+ requestRender(props.api);
644
701
  void setPublishedSkillInstalled({
645
702
  worktree: props.api.state.path.worktree,
646
703
  directory: props.api.state.path.directory,
@@ -648,12 +705,17 @@ const WizardSkillsDialog = props => {
648
705
  skillSlug: row.skill.skillSlug,
649
706
  installed: true,
650
707
  preferenceScope
651
- }).then(refreshAfterPreferenceChange).catch(refreshAfterPreferenceChange);
708
+ }).then(() => refreshAfterPreferenceChange(`Skill installed for ${preferenceScope}.`)).catch(showPreferenceFailure);
652
709
  };
653
710
  const uninstallSkill = row => {
654
711
  const currentStatus = props.status();
655
712
  if (currentStatus.kind !== 'ready') return;
656
713
  const scopeKey = currentStatus.snapshot.ignoredPublishedSkills.scopeKey;
714
+ setActionNotice({
715
+ kind: 'pending',
716
+ message: 'Uninstalling skill…'
717
+ });
718
+ requestRender(props.api);
657
719
  void setPublishedSkillInstalled({
658
720
  worktree: props.api.state.path.worktree,
659
721
  directory: props.api.state.path.directory,
@@ -661,48 +723,49 @@ const WizardSkillsDialog = props => {
661
723
  skillSlug: row.skill.skillSlug,
662
724
  installed: false,
663
725
  preferenceScope: row.state === 'installed-global' ? 'global' : 'project'
664
- }).then(refreshAfterPreferenceChange).catch(refreshAfterPreferenceChange);
726
+ }).then(() => refreshAfterPreferenceChange('Skill uninstalled.')).catch(showPreferenceFailure);
665
727
  };
666
728
  createEffect(() => {
667
729
  props.api.ui?.dialog?.setSize?.('xlarge');
668
730
  });
669
731
  return (() => {
670
- var _el$76 = _$createElement("box"),
671
- _el$77 = _$createElement("box"),
672
- _el$78 = _$createElement("text"),
673
- _el$79 = _$createElement("b"),
674
- _el$81 = _$createElement("box"),
675
- _el$82 = _$createElement("text"),
676
- _el$84 = _$createElement("box");
677
- _$insertNode(_el$76, _el$77);
678
- _$insertNode(_el$76, _el$84);
679
- _$setProp(_el$76, "width", "100%");
680
- _$setProp(_el$76, "flexDirection", "column");
681
- _$setProp(_el$76, "paddingLeft", 1);
682
- _$setProp(_el$76, "paddingRight", 1);
683
- _$setProp(_el$76, "paddingBottom", 1);
684
- _$insertNode(_el$77, _el$78);
685
- _$insertNode(_el$77, _el$81);
686
- _$setProp(_el$77, "width", "100%");
687
- _$setProp(_el$77, "flexDirection", "row");
688
- _$setProp(_el$77, "justifyContent", "space-between");
689
- _$setProp(_el$77, "overflow", "hidden");
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");
690
739
  _$insertNode(_el$78, _el$79);
691
- _$setProp(_el$78, "wrapMode", "none");
692
- _$setProp(_el$78, "overflow", "hidden");
693
- _$insertNode(_el$79, _$createTextNode(`Wizard Skills`));
694
- _$insertNode(_el$81, _el$82);
695
- _$setProp(_el$81, "flexShrink", 0);
696
- _$insertNode(_el$82, _$createTextNode(`Close`));
697
- _$setProp(_el$82, "wrapMode", "none");
698
- _$setProp(_el$84, "width", "100%");
699
- _$setProp(_el$84, "flexDirection", "column");
700
- _$setProp(_el$84, "marginTop", 1);
701
- _$setProp(_el$84, "overflow", "hidden");
702
- _$insert(_el$84, _$createComponent(WizardSkillsDialogContent, {
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, {
703
765
  get status() {
704
766
  return props.status;
705
767
  },
768
+ actionNotice: actionNotice,
706
769
  get theme() {
707
770
  return theme();
708
771
  },
@@ -714,16 +777,16 @@ const WizardSkillsDialog = props => {
714
777
  var _v$11 = theme().text,
715
778
  _v$12 = props.onClose,
716
779
  _v$13 = theme().textMuted;
717
- _v$11 !== _p$.e && (_p$.e = _$setProp(_el$78, "fg", _v$11, _p$.e));
718
- _v$12 !== _p$.t && (_p$.t = _$setProp(_el$81, "onMouseUp", _v$12, _p$.t));
719
- _v$13 !== _p$.a && (_p$.a = _$setProp(_el$82, "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));
720
783
  return _p$;
721
784
  }, {
722
785
  e: undefined,
723
786
  t: undefined,
724
787
  a: undefined
725
788
  });
726
- return _el$76;
789
+ return _el$78;
727
790
  })();
728
791
  };
729
792
  const openWizardSkillsDialog = (api, status, refreshStatus) => {