formalconf 2.0.3 → 2.0.5
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/formalconf.js +305 -75
- package/package.json +1 -1
package/dist/formalconf.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// src/cli/formalconf.tsx
|
|
3
|
-
import { useState as
|
|
4
|
-
import { render, useApp as useApp2, useInput as
|
|
3
|
+
import { useState as useState11, useEffect as useEffect6 } from "react";
|
|
4
|
+
import { render, useApp as useApp2, useInput as useInput11 } from "ink";
|
|
5
5
|
import { Spinner as Spinner2 } from "@inkjs/ui";
|
|
6
6
|
|
|
7
7
|
// src/components/layout/Layout.tsx
|
|
@@ -414,7 +414,7 @@ function StatusIndicator({
|
|
|
414
414
|
// package.json
|
|
415
415
|
var package_default = {
|
|
416
416
|
name: "formalconf",
|
|
417
|
-
version: "2.0.
|
|
417
|
+
version: "2.0.5",
|
|
418
418
|
description: "Dotfiles management TUI for macOS - config management, package sync, and theme switching",
|
|
419
419
|
type: "module",
|
|
420
420
|
main: "./dist/formalconf.js",
|
|
@@ -1674,8 +1674,8 @@ function ConfigMenu({ onBack }) {
|
|
|
1674
1674
|
}
|
|
1675
1675
|
|
|
1676
1676
|
// src/components/menus/PackageMenu.tsx
|
|
1677
|
-
import { useState as
|
|
1678
|
-
import { Box as
|
|
1677
|
+
import { useState as useState8, useCallback as useCallback2, useMemo as useMemo2, useRef } from "react";
|
|
1678
|
+
import { Box as Box14, Text as Text13, useInput as useInput9 } from "ink";
|
|
1679
1679
|
|
|
1680
1680
|
// src/components/ScrollableLog.tsx
|
|
1681
1681
|
import { useState as useState6, useEffect as useEffect3, useMemo } from "react";
|
|
@@ -1801,6 +1801,142 @@ function PromptInput({
|
|
|
1801
1801
|
}, undefined, false, undefined, this);
|
|
1802
1802
|
}
|
|
1803
1803
|
|
|
1804
|
+
// src/components/OrphanTable.tsx
|
|
1805
|
+
import { useState as useState7 } from "react";
|
|
1806
|
+
import { Box as Box13, Text as Text12, useInput as useInput8 } from "ink";
|
|
1807
|
+
import { jsxDEV as jsxDEV16 } from "react/jsx-dev-runtime";
|
|
1808
|
+
function OrphanTable({ result, onAction, onDismiss }) {
|
|
1809
|
+
const [selectedIndex, setSelectedIndex] = useState7(0);
|
|
1810
|
+
const { orphans } = result;
|
|
1811
|
+
useInput8((input, key) => {
|
|
1812
|
+
if (orphans.length > 0) {
|
|
1813
|
+
if (input === "j" || key.downArrow) {
|
|
1814
|
+
setSelectedIndex((i) => Math.min(i + 1, orphans.length - 1));
|
|
1815
|
+
}
|
|
1816
|
+
if (input === "k" || key.upArrow) {
|
|
1817
|
+
setSelectedIndex((i) => Math.max(i - 1, 0));
|
|
1818
|
+
}
|
|
1819
|
+
if (input === "a") {
|
|
1820
|
+
onAction("add", orphans[selectedIndex]);
|
|
1821
|
+
}
|
|
1822
|
+
if (input === "x") {
|
|
1823
|
+
onAction("uninstall", orphans[selectedIndex]);
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
if (key.escape || input === "h" || key.leftArrow) {
|
|
1827
|
+
onDismiss();
|
|
1828
|
+
}
|
|
1829
|
+
});
|
|
1830
|
+
const borderColor = orphans.length > 0 ? colors.warning : colors.success;
|
|
1831
|
+
return /* @__PURE__ */ jsxDEV16(Panel, {
|
|
1832
|
+
title: "Orphaned Packages",
|
|
1833
|
+
borderColor,
|
|
1834
|
+
children: [
|
|
1835
|
+
/* @__PURE__ */ jsxDEV16(Box13, {
|
|
1836
|
+
marginBottom: 1,
|
|
1837
|
+
children: /* @__PURE__ */ jsxDEV16(Text12, {
|
|
1838
|
+
dimColor: true,
|
|
1839
|
+
children: [
|
|
1840
|
+
"Config: ",
|
|
1841
|
+
result.configFormulas,
|
|
1842
|
+
" formulas, ",
|
|
1843
|
+
result.configCasks,
|
|
1844
|
+
" casks | Installed: ",
|
|
1845
|
+
result.installedLeaves,
|
|
1846
|
+
" leaves, ",
|
|
1847
|
+
result.installedCasks,
|
|
1848
|
+
" ",
|
|
1849
|
+
"casks"
|
|
1850
|
+
]
|
|
1851
|
+
}, undefined, true, undefined, this)
|
|
1852
|
+
}, undefined, false, undefined, this),
|
|
1853
|
+
orphans.length === 0 ? /* @__PURE__ */ jsxDEV16(Box13, {
|
|
1854
|
+
flexDirection: "column",
|
|
1855
|
+
children: [
|
|
1856
|
+
/* @__PURE__ */ jsxDEV16(Text12, {
|
|
1857
|
+
color: colors.success,
|
|
1858
|
+
children: "No orphaned packages found!"
|
|
1859
|
+
}, undefined, false, undefined, this),
|
|
1860
|
+
/* @__PURE__ */ jsxDEV16(Text12, {
|
|
1861
|
+
dimColor: true,
|
|
1862
|
+
children: "All installed packages are in your config."
|
|
1863
|
+
}, undefined, false, undefined, this)
|
|
1864
|
+
]
|
|
1865
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV16(Box13, {
|
|
1866
|
+
flexDirection: "column",
|
|
1867
|
+
children: [
|
|
1868
|
+
/* @__PURE__ */ jsxDEV16(Text12, {
|
|
1869
|
+
color: colors.warning,
|
|
1870
|
+
children: [
|
|
1871
|
+
"Found ",
|
|
1872
|
+
orphans.length,
|
|
1873
|
+
" orphaned package",
|
|
1874
|
+
orphans.length !== 1 ? "s" : "",
|
|
1875
|
+
":"
|
|
1876
|
+
]
|
|
1877
|
+
}, undefined, true, undefined, this),
|
|
1878
|
+
/* @__PURE__ */ jsxDEV16(Box13, {
|
|
1879
|
+
marginTop: 1,
|
|
1880
|
+
flexDirection: "column",
|
|
1881
|
+
children: [
|
|
1882
|
+
/* @__PURE__ */ jsxDEV16(Box13, {
|
|
1883
|
+
children: [
|
|
1884
|
+
/* @__PURE__ */ jsxDEV16(Text12, {
|
|
1885
|
+
bold: true,
|
|
1886
|
+
children: [
|
|
1887
|
+
" ",
|
|
1888
|
+
"Name"
|
|
1889
|
+
]
|
|
1890
|
+
}, undefined, true, undefined, this),
|
|
1891
|
+
/* @__PURE__ */ jsxDEV16(Text12, {
|
|
1892
|
+
bold: true,
|
|
1893
|
+
children: [
|
|
1894
|
+
" ".repeat(28),
|
|
1895
|
+
"Type"
|
|
1896
|
+
]
|
|
1897
|
+
}, undefined, true, undefined, this)
|
|
1898
|
+
]
|
|
1899
|
+
}, undefined, true, undefined, this),
|
|
1900
|
+
/* @__PURE__ */ jsxDEV16(Text12, {
|
|
1901
|
+
color: colors.border,
|
|
1902
|
+
children: "─".repeat(50)
|
|
1903
|
+
}, undefined, false, undefined, this),
|
|
1904
|
+
orphans.map((pkg, i) => {
|
|
1905
|
+
const isSelected = i === selectedIndex;
|
|
1906
|
+
return /* @__PURE__ */ jsxDEV16(Box13, {
|
|
1907
|
+
children: [
|
|
1908
|
+
/* @__PURE__ */ jsxDEV16(Text12, {
|
|
1909
|
+
color: isSelected ? colors.primary : undefined,
|
|
1910
|
+
children: [
|
|
1911
|
+
isSelected ? "❯ " : " ",
|
|
1912
|
+
pkg.name.padEnd(30)
|
|
1913
|
+
]
|
|
1914
|
+
}, undefined, true, undefined, this),
|
|
1915
|
+
/* @__PURE__ */ jsxDEV16(Text12, {
|
|
1916
|
+
color: pkg.type === "formula" ? colors.info : colors.accent,
|
|
1917
|
+
children: pkg.type
|
|
1918
|
+
}, undefined, false, undefined, this)
|
|
1919
|
+
]
|
|
1920
|
+
}, `${pkg.type}-${pkg.name}`, true, undefined, this);
|
|
1921
|
+
})
|
|
1922
|
+
]
|
|
1923
|
+
}, undefined, true, undefined, this)
|
|
1924
|
+
]
|
|
1925
|
+
}, undefined, true, undefined, this),
|
|
1926
|
+
/* @__PURE__ */ jsxDEV16(Box13, {
|
|
1927
|
+
marginTop: 1,
|
|
1928
|
+
children: orphans.length > 0 ? /* @__PURE__ */ jsxDEV16(Text12, {
|
|
1929
|
+
dimColor: true,
|
|
1930
|
+
children: "j/k navigate | a add to config | x uninstall | esc/h back | q quit"
|
|
1931
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV16(Text12, {
|
|
1932
|
+
dimColor: true,
|
|
1933
|
+
children: "esc/h back | q quit"
|
|
1934
|
+
}, undefined, false, undefined, this)
|
|
1935
|
+
}, undefined, false, undefined, this)
|
|
1936
|
+
]
|
|
1937
|
+
}, undefined, true, undefined, this);
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1804
1940
|
// src/cli/pkg-sync.ts
|
|
1805
1941
|
import { parseArgs as parseArgs2 } from "util";
|
|
1806
1942
|
|
|
@@ -2613,21 +2749,88 @@ if (isMainModule3) {
|
|
|
2613
2749
|
main3().catch(console.error);
|
|
2614
2750
|
}
|
|
2615
2751
|
|
|
2752
|
+
// src/lib/orphan-detector.ts
|
|
2753
|
+
function getPackageName(fullName) {
|
|
2754
|
+
const parts = fullName.split("/");
|
|
2755
|
+
return parts[parts.length - 1];
|
|
2756
|
+
}
|
|
2757
|
+
async function detectOrphanedPackages() {
|
|
2758
|
+
const config = await loadPkgConfig();
|
|
2759
|
+
const leavesResult = await exec(["brew", "leaves"]);
|
|
2760
|
+
const installedLeaves = leavesResult.success ? leavesResult.stdout.split(`
|
|
2761
|
+
`).filter(Boolean) : [];
|
|
2762
|
+
const casksResult = await exec(["brew", "list", "--cask"]);
|
|
2763
|
+
const installedCasks = casksResult.success ? casksResult.stdout.split(`
|
|
2764
|
+
`).filter(Boolean) : [];
|
|
2765
|
+
const orphans = [];
|
|
2766
|
+
const configPackages = config.packages.map((pkg) => ({
|
|
2767
|
+
full: pkg,
|
|
2768
|
+
short: getPackageName(pkg)
|
|
2769
|
+
}));
|
|
2770
|
+
for (const installed of installedLeaves) {
|
|
2771
|
+
const installedShort = getPackageName(installed);
|
|
2772
|
+
const isInConfig = configPackages.some((cfg) => installed === cfg.full || installed === cfg.short || installedShort === cfg.full || installedShort === cfg.short || installed.endsWith(`/${cfg.short}`));
|
|
2773
|
+
if (!isInConfig) {
|
|
2774
|
+
orphans.push({ name: installed, type: "formula" });
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
const configCasksSet = new Set(config.casks);
|
|
2778
|
+
for (const cask of installedCasks) {
|
|
2779
|
+
if (!configCasksSet.has(cask)) {
|
|
2780
|
+
orphans.push({ name: cask, type: "cask" });
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2783
|
+
orphans.sort((a, b) => {
|
|
2784
|
+
if (a.type !== b.type)
|
|
2785
|
+
return a.type === "formula" ? -1 : 1;
|
|
2786
|
+
return a.name.localeCompare(b.name);
|
|
2787
|
+
});
|
|
2788
|
+
return {
|
|
2789
|
+
orphans,
|
|
2790
|
+
configFormulas: config.packages.length,
|
|
2791
|
+
configCasks: config.casks.length,
|
|
2792
|
+
installedLeaves: installedLeaves.length,
|
|
2793
|
+
installedCasks: installedCasks.length
|
|
2794
|
+
};
|
|
2795
|
+
}
|
|
2796
|
+
async function addToConfig(pkg) {
|
|
2797
|
+
const config = await loadPkgConfig();
|
|
2798
|
+
if (pkg.type === "formula") {
|
|
2799
|
+
if (!config.packages.includes(pkg.name)) {
|
|
2800
|
+
config.packages.push(pkg.name);
|
|
2801
|
+
config.packages.sort();
|
|
2802
|
+
}
|
|
2803
|
+
} else {
|
|
2804
|
+
if (!config.casks.includes(pkg.name)) {
|
|
2805
|
+
config.casks.push(pkg.name);
|
|
2806
|
+
config.casks.sort();
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
await savePkgConfig(config);
|
|
2810
|
+
}
|
|
2811
|
+
async function uninstallPackage(pkg) {
|
|
2812
|
+
const cmd = pkg.type === "cask" ? ["brew", "uninstall", "--cask", pkg.name] : ["brew", "uninstall", pkg.name];
|
|
2813
|
+
const result = await exec(cmd);
|
|
2814
|
+
return result.success;
|
|
2815
|
+
}
|
|
2816
|
+
|
|
2616
2817
|
// src/components/menus/PackageMenu.tsx
|
|
2617
|
-
import { jsxDEV as
|
|
2818
|
+
import { jsxDEV as jsxDEV17 } from "react/jsx-dev-runtime";
|
|
2618
2819
|
function PackageMenu({ onBack }) {
|
|
2619
|
-
const [state, setState] =
|
|
2620
|
-
const [lines, setLines] =
|
|
2621
|
-
const [output, setOutput] =
|
|
2622
|
-
const [isStreamingOp, setIsStreamingOp] =
|
|
2623
|
-
const [pendingPrompt, setPendingPrompt] =
|
|
2624
|
-
const [success, setSuccess] =
|
|
2820
|
+
const [state, setState] = useState8("menu");
|
|
2821
|
+
const [lines, setLines] = useState8([]);
|
|
2822
|
+
const [output, setOutput] = useState8("");
|
|
2823
|
+
const [isStreamingOp, setIsStreamingOp] = useState8(true);
|
|
2824
|
+
const [pendingPrompt, setPendingPrompt] = useState8(null);
|
|
2825
|
+
const [success, setSuccess] = useState8(true);
|
|
2826
|
+
const [orphanResult, setOrphanResult] = useState8(null);
|
|
2827
|
+
const [isOrphanView, setIsOrphanView] = useState8(false);
|
|
2625
2828
|
const isRunningRef = useRef(false);
|
|
2626
|
-
|
|
2829
|
+
useInput9((input, key) => {
|
|
2627
2830
|
if (state === "menu" && (key.escape || key.leftArrow || input === "h")) {
|
|
2628
2831
|
onBack();
|
|
2629
2832
|
}
|
|
2630
|
-
if (state === "result") {
|
|
2833
|
+
if (state === "result" && !isOrphanView) {
|
|
2631
2834
|
setState("menu");
|
|
2632
2835
|
setLines([]);
|
|
2633
2836
|
}
|
|
@@ -2689,6 +2892,13 @@ function PackageMenu({ onBack }) {
|
|
|
2689
2892
|
result = await runPkgLock(["status"]);
|
|
2690
2893
|
setOutput(result.output);
|
|
2691
2894
|
break;
|
|
2895
|
+
case "orphans":
|
|
2896
|
+
setIsStreamingOp(false);
|
|
2897
|
+
setIsOrphanView(true);
|
|
2898
|
+
const orphanData = await detectOrphanedPackages();
|
|
2899
|
+
setOrphanResult(orphanData);
|
|
2900
|
+
result = { output: "", success: true };
|
|
2901
|
+
break;
|
|
2692
2902
|
default:
|
|
2693
2903
|
setIsStreamingOp(false);
|
|
2694
2904
|
result = { output: "Unknown action", success: false };
|
|
@@ -2700,17 +2910,17 @@ function PackageMenu({ onBack }) {
|
|
|
2700
2910
|
};
|
|
2701
2911
|
if (state === "running") {
|
|
2702
2912
|
if (!isStreamingOp) {
|
|
2703
|
-
return /* @__PURE__ */
|
|
2913
|
+
return /* @__PURE__ */ jsxDEV17(LoadingPanel, {
|
|
2704
2914
|
title: "Package Sync"
|
|
2705
2915
|
}, undefined, false, undefined, this);
|
|
2706
2916
|
}
|
|
2707
|
-
return /* @__PURE__ */
|
|
2917
|
+
return /* @__PURE__ */ jsxDEV17(Panel, {
|
|
2708
2918
|
title: "Package Sync",
|
|
2709
2919
|
children: [
|
|
2710
|
-
/* @__PURE__ */
|
|
2920
|
+
/* @__PURE__ */ jsxDEV17(ScrollableLog, {
|
|
2711
2921
|
lines
|
|
2712
2922
|
}, undefined, false, undefined, this),
|
|
2713
|
-
pendingPrompt && /* @__PURE__ */
|
|
2923
|
+
pendingPrompt && /* @__PURE__ */ jsxDEV17(PromptInput, {
|
|
2714
2924
|
question: pendingPrompt.question,
|
|
2715
2925
|
options: pendingPrompt.options,
|
|
2716
2926
|
onAnswer: handlePromptAnswer
|
|
@@ -2719,39 +2929,58 @@ function PackageMenu({ onBack }) {
|
|
|
2719
2929
|
}, undefined, true, undefined, this);
|
|
2720
2930
|
}
|
|
2721
2931
|
if (state === "result") {
|
|
2932
|
+
if (isOrphanView && orphanResult) {
|
|
2933
|
+
const handleOrphanAction = async (action, pkg) => {
|
|
2934
|
+
if (action === "add") {
|
|
2935
|
+
await addToConfig(pkg);
|
|
2936
|
+
} else {
|
|
2937
|
+
await uninstallPackage(pkg);
|
|
2938
|
+
}
|
|
2939
|
+
const updated = await detectOrphanedPackages();
|
|
2940
|
+
setOrphanResult(updated);
|
|
2941
|
+
};
|
|
2942
|
+
return /* @__PURE__ */ jsxDEV17(OrphanTable, {
|
|
2943
|
+
result: orphanResult,
|
|
2944
|
+
onAction: handleOrphanAction,
|
|
2945
|
+
onDismiss: () => {
|
|
2946
|
+
setIsOrphanView(false);
|
|
2947
|
+
setState("menu");
|
|
2948
|
+
}
|
|
2949
|
+
}, undefined, false, undefined, this);
|
|
2950
|
+
}
|
|
2722
2951
|
if (!isStreamingOp) {
|
|
2723
|
-
return /* @__PURE__ */
|
|
2952
|
+
return /* @__PURE__ */ jsxDEV17(CommandOutput, {
|
|
2724
2953
|
title: "Package Sync",
|
|
2725
2954
|
output,
|
|
2726
2955
|
success,
|
|
2727
2956
|
onDismiss: () => setState("menu")
|
|
2728
2957
|
}, undefined, false, undefined, this);
|
|
2729
2958
|
}
|
|
2730
|
-
return /* @__PURE__ */
|
|
2959
|
+
return /* @__PURE__ */ jsxDEV17(Panel, {
|
|
2731
2960
|
title: "Package Sync",
|
|
2732
2961
|
borderColor: success ? colors.success : colors.error,
|
|
2733
2962
|
children: [
|
|
2734
|
-
/* @__PURE__ */
|
|
2963
|
+
/* @__PURE__ */ jsxDEV17(ScrollableLog, {
|
|
2735
2964
|
lines,
|
|
2736
2965
|
autoScroll: false
|
|
2737
2966
|
}, undefined, false, undefined, this),
|
|
2738
|
-
/* @__PURE__ */
|
|
2967
|
+
/* @__PURE__ */ jsxDEV17(Box14, {
|
|
2739
2968
|
marginTop: 1,
|
|
2740
|
-
children: /* @__PURE__ */
|
|
2969
|
+
children: /* @__PURE__ */ jsxDEV17(Text13, {
|
|
2741
2970
|
color: success ? colors.success : colors.error,
|
|
2742
2971
|
children: success ? "Done" : "Failed"
|
|
2743
2972
|
}, undefined, false, undefined, this)
|
|
2744
2973
|
}, undefined, false, undefined, this),
|
|
2745
|
-
/* @__PURE__ */
|
|
2974
|
+
/* @__PURE__ */ jsxDEV17(Text13, {
|
|
2746
2975
|
dimColor: true,
|
|
2747
2976
|
children: "Press any key to continue..."
|
|
2748
2977
|
}, undefined, false, undefined, this)
|
|
2749
2978
|
]
|
|
2750
2979
|
}, undefined, true, undefined, this);
|
|
2751
2980
|
}
|
|
2752
|
-
return /* @__PURE__ */
|
|
2981
|
+
return /* @__PURE__ */ jsxDEV17(Panel, {
|
|
2753
2982
|
title: "Package Sync",
|
|
2754
|
-
children: /* @__PURE__ */
|
|
2983
|
+
children: /* @__PURE__ */ jsxDEV17(VimSelect, {
|
|
2755
2984
|
options: [
|
|
2756
2985
|
{ label: "Sync packages", value: "sync" },
|
|
2757
2986
|
{ label: "Sync with purge", value: "sync-purge" },
|
|
@@ -2759,6 +2988,7 @@ function PackageMenu({ onBack }) {
|
|
|
2759
2988
|
{ label: "Upgrade interactive", value: "upgrade-interactive" },
|
|
2760
2989
|
{ label: "Update lockfile", value: "lock-update" },
|
|
2761
2990
|
{ label: "Lockfile status", value: "lock-status" },
|
|
2991
|
+
{ label: "Find orphaned packages", value: "orphans" },
|
|
2762
2992
|
{ label: "Back", value: "back" }
|
|
2763
2993
|
],
|
|
2764
2994
|
onChange: handleAction
|
|
@@ -2767,14 +2997,14 @@ function PackageMenu({ onBack }) {
|
|
|
2767
2997
|
}
|
|
2768
2998
|
|
|
2769
2999
|
// src/components/menus/ThemeMenu.tsx
|
|
2770
|
-
import { useState as
|
|
2771
|
-
import { Box as
|
|
3000
|
+
import { useState as useState10, useEffect as useEffect5, useMemo as useMemo4 } from "react";
|
|
3001
|
+
import { Box as Box16, Text as Text15 } from "ink";
|
|
2772
3002
|
import { existsSync as existsSync7, readdirSync as readdirSync5 } from "fs";
|
|
2773
3003
|
import { join as join6 } from "path";
|
|
2774
3004
|
|
|
2775
3005
|
// src/components/ThemeCard.tsx
|
|
2776
|
-
import { Box as
|
|
2777
|
-
import { jsxDEV as
|
|
3006
|
+
import { Box as Box15, Text as Text14 } from "ink";
|
|
3007
|
+
import { jsxDEV as jsxDEV18 } from "react/jsx-dev-runtime";
|
|
2778
3008
|
function ThemeCard({ theme, isSelected, width }) {
|
|
2779
3009
|
const borderColor = isSelected ? colors.accent : colors.border;
|
|
2780
3010
|
const nameColor = isSelected ? colors.primary : colors.text;
|
|
@@ -2784,25 +3014,25 @@ function ThemeCard({ theme, isSelected, width }) {
|
|
|
2784
3014
|
if (theme.isLightMode)
|
|
2785
3015
|
indicators.push("light");
|
|
2786
3016
|
const indicatorText = indicators.length > 0 ? ` [${indicators.join(" ")}]` : "";
|
|
2787
|
-
return /* @__PURE__ */
|
|
3017
|
+
return /* @__PURE__ */ jsxDEV18(Box15, {
|
|
2788
3018
|
flexDirection: "column",
|
|
2789
3019
|
width,
|
|
2790
3020
|
borderStyle: borderStyles.panel,
|
|
2791
3021
|
borderColor,
|
|
2792
3022
|
paddingX: 1,
|
|
2793
|
-
children: /* @__PURE__ */
|
|
3023
|
+
children: /* @__PURE__ */ jsxDEV18(Box15, {
|
|
2794
3024
|
children: [
|
|
2795
|
-
/* @__PURE__ */
|
|
3025
|
+
/* @__PURE__ */ jsxDEV18(Text14, {
|
|
2796
3026
|
color: isSelected ? colors.accent : colors.primaryDim,
|
|
2797
3027
|
children: isSelected ? "● " : " "
|
|
2798
3028
|
}, undefined, false, undefined, this),
|
|
2799
|
-
/* @__PURE__ */
|
|
3029
|
+
/* @__PURE__ */ jsxDEV18(Text14, {
|
|
2800
3030
|
color: nameColor,
|
|
2801
3031
|
bold: true,
|
|
2802
3032
|
wrap: "truncate",
|
|
2803
3033
|
children: theme.name
|
|
2804
3034
|
}, undefined, false, undefined, this),
|
|
2805
|
-
/* @__PURE__ */
|
|
3035
|
+
/* @__PURE__ */ jsxDEV18(Text14, {
|
|
2806
3036
|
color: colors.primaryDim,
|
|
2807
3037
|
children: indicatorText
|
|
2808
3038
|
}, undefined, false, undefined, this)
|
|
@@ -2812,8 +3042,8 @@ function ThemeCard({ theme, isSelected, width }) {
|
|
|
2812
3042
|
}
|
|
2813
3043
|
|
|
2814
3044
|
// src/hooks/useThemeGrid.ts
|
|
2815
|
-
import { useState as
|
|
2816
|
-
import { useInput as
|
|
3045
|
+
import { useState as useState9, useEffect as useEffect4 } from "react";
|
|
3046
|
+
import { useInput as useInput10 } from "ink";
|
|
2817
3047
|
function useThemeGrid({
|
|
2818
3048
|
itemCount,
|
|
2819
3049
|
cardHeight = 3,
|
|
@@ -2824,8 +3054,8 @@ function useThemeGrid({
|
|
|
2824
3054
|
enabled = true
|
|
2825
3055
|
}) {
|
|
2826
3056
|
const { columns, rows } = useTerminalSize();
|
|
2827
|
-
const [selectedIndex, setSelectedIndex] =
|
|
2828
|
-
const [scrollOffset, setScrollOffset] =
|
|
3057
|
+
const [selectedIndex, setSelectedIndex] = useState9(0);
|
|
3058
|
+
const [scrollOffset, setScrollOffset] = useState9(0);
|
|
2829
3059
|
const availableWidth = columns - 6;
|
|
2830
3060
|
const cardsPerRow = Math.max(1, Math.floor(availableWidth / minCardWidth));
|
|
2831
3061
|
const cardWidth = Math.floor(availableWidth / cardsPerRow);
|
|
@@ -2840,7 +3070,7 @@ function useThemeGrid({
|
|
|
2840
3070
|
setScrollOffset(selectedRow - visibleRows + 1);
|
|
2841
3071
|
}
|
|
2842
3072
|
}, [selectedRow, scrollOffset, visibleRows]);
|
|
2843
|
-
|
|
3073
|
+
useInput10((input, key) => {
|
|
2844
3074
|
if (!enabled)
|
|
2845
3075
|
return;
|
|
2846
3076
|
if (key.escape && onBack) {
|
|
@@ -3135,10 +3365,10 @@ if (isMainModule4) {
|
|
|
3135
3365
|
}
|
|
3136
3366
|
|
|
3137
3367
|
// src/components/menus/ThemeMenu.tsx
|
|
3138
|
-
import { jsxDEV as
|
|
3368
|
+
import { jsxDEV as jsxDEV19 } from "react/jsx-dev-runtime";
|
|
3139
3369
|
function ThemeMenu({ onBack }) {
|
|
3140
|
-
const [themes, setThemes] =
|
|
3141
|
-
const [loading, setLoading] =
|
|
3370
|
+
const [themes, setThemes] = useState10([]);
|
|
3371
|
+
const [loading, setLoading] = useState10(true);
|
|
3142
3372
|
const { state, output, success, isRunning, isResult, execute, reset } = useMenuAction();
|
|
3143
3373
|
const grid = useThemeGrid({
|
|
3144
3374
|
itemCount: themes.length,
|
|
@@ -3175,13 +3405,13 @@ function ThemeMenu({ onBack }) {
|
|
|
3175
3405
|
return themes.slice(grid.visibleStartIndex, grid.visibleEndIndex);
|
|
3176
3406
|
}, [themes, grid.visibleStartIndex, grid.visibleEndIndex]);
|
|
3177
3407
|
if (loading || isRunning) {
|
|
3178
|
-
return /* @__PURE__ */
|
|
3408
|
+
return /* @__PURE__ */ jsxDEV19(LoadingPanel, {
|
|
3179
3409
|
title: "Select Theme",
|
|
3180
3410
|
label: loading ? "Loading themes..." : "Applying theme..."
|
|
3181
3411
|
}, undefined, false, undefined, this);
|
|
3182
3412
|
}
|
|
3183
3413
|
if (isResult) {
|
|
3184
|
-
return /* @__PURE__ */
|
|
3414
|
+
return /* @__PURE__ */ jsxDEV19(CommandOutput, {
|
|
3185
3415
|
title: "Select Theme",
|
|
3186
3416
|
output,
|
|
3187
3417
|
success,
|
|
@@ -3189,28 +3419,28 @@ function ThemeMenu({ onBack }) {
|
|
|
3189
3419
|
}, undefined, false, undefined, this);
|
|
3190
3420
|
}
|
|
3191
3421
|
if (themes.length === 0) {
|
|
3192
|
-
return /* @__PURE__ */
|
|
3422
|
+
return /* @__PURE__ */ jsxDEV19(Panel, {
|
|
3193
3423
|
title: "Select Theme",
|
|
3194
3424
|
children: [
|
|
3195
|
-
/* @__PURE__ */
|
|
3425
|
+
/* @__PURE__ */ jsxDEV19(Box16, {
|
|
3196
3426
|
flexDirection: "column",
|
|
3197
3427
|
children: [
|
|
3198
|
-
/* @__PURE__ */
|
|
3428
|
+
/* @__PURE__ */ jsxDEV19(Text15, {
|
|
3199
3429
|
color: colors.warning,
|
|
3200
3430
|
children: "No themes available."
|
|
3201
3431
|
}, undefined, false, undefined, this),
|
|
3202
|
-
/* @__PURE__ */
|
|
3432
|
+
/* @__PURE__ */ jsxDEV19(Text15, {
|
|
3203
3433
|
children: "This system is compatible with omarchy themes."
|
|
3204
3434
|
}, undefined, false, undefined, this),
|
|
3205
|
-
/* @__PURE__ */
|
|
3435
|
+
/* @__PURE__ */ jsxDEV19(Text15, {
|
|
3206
3436
|
dimColor: true,
|
|
3207
3437
|
children: "Add themes to ~/.config/formalconf/themes/"
|
|
3208
3438
|
}, undefined, false, undefined, this)
|
|
3209
3439
|
]
|
|
3210
3440
|
}, undefined, true, undefined, this),
|
|
3211
|
-
/* @__PURE__ */
|
|
3441
|
+
/* @__PURE__ */ jsxDEV19(Box16, {
|
|
3212
3442
|
marginTop: 1,
|
|
3213
|
-
children: /* @__PURE__ */
|
|
3443
|
+
children: /* @__PURE__ */ jsxDEV19(VimSelect, {
|
|
3214
3444
|
options: [{ label: "Back", value: "back" }],
|
|
3215
3445
|
onChange: () => onBack()
|
|
3216
3446
|
}, undefined, false, undefined, this)
|
|
@@ -3218,10 +3448,10 @@ function ThemeMenu({ onBack }) {
|
|
|
3218
3448
|
]
|
|
3219
3449
|
}, undefined, true, undefined, this);
|
|
3220
3450
|
}
|
|
3221
|
-
return /* @__PURE__ */
|
|
3451
|
+
return /* @__PURE__ */ jsxDEV19(Panel, {
|
|
3222
3452
|
title: "Select Theme",
|
|
3223
3453
|
children: [
|
|
3224
|
-
grid.showScrollUp && /* @__PURE__ */
|
|
3454
|
+
grid.showScrollUp && /* @__PURE__ */ jsxDEV19(Text15, {
|
|
3225
3455
|
dimColor: true,
|
|
3226
3456
|
children: [
|
|
3227
3457
|
" ",
|
|
@@ -3231,18 +3461,18 @@ function ThemeMenu({ onBack }) {
|
|
|
3231
3461
|
grid.scrollOffset > 1 ? "s" : ""
|
|
3232
3462
|
]
|
|
3233
3463
|
}, undefined, true, undefined, this),
|
|
3234
|
-
/* @__PURE__ */
|
|
3464
|
+
/* @__PURE__ */ jsxDEV19(Box16, {
|
|
3235
3465
|
flexDirection: "row",
|
|
3236
3466
|
flexWrap: "wrap",
|
|
3237
3467
|
height: grid.gridHeight,
|
|
3238
3468
|
overflow: "hidden",
|
|
3239
|
-
children: visibleThemes.map((theme, index) => /* @__PURE__ */
|
|
3469
|
+
children: visibleThemes.map((theme, index) => /* @__PURE__ */ jsxDEV19(ThemeCard, {
|
|
3240
3470
|
theme,
|
|
3241
3471
|
isSelected: grid.visibleStartIndex + index === grid.selectedIndex,
|
|
3242
3472
|
width: grid.cardWidth
|
|
3243
3473
|
}, theme.path, false, undefined, this))
|
|
3244
3474
|
}, undefined, false, undefined, this),
|
|
3245
|
-
grid.showScrollDown && /* @__PURE__ */
|
|
3475
|
+
grid.showScrollDown && /* @__PURE__ */ jsxDEV19(Text15, {
|
|
3246
3476
|
dimColor: true,
|
|
3247
3477
|
children: [
|
|
3248
3478
|
" ",
|
|
@@ -3252,9 +3482,9 @@ function ThemeMenu({ onBack }) {
|
|
|
3252
3482
|
grid.totalRows - grid.scrollOffset - grid.visibleRows > 1 ? "s" : ""
|
|
3253
3483
|
]
|
|
3254
3484
|
}, undefined, true, undefined, this),
|
|
3255
|
-
/* @__PURE__ */
|
|
3485
|
+
/* @__PURE__ */ jsxDEV19(Box16, {
|
|
3256
3486
|
marginTop: 1,
|
|
3257
|
-
children: /* @__PURE__ */
|
|
3487
|
+
children: /* @__PURE__ */ jsxDEV19(Text15, {
|
|
3258
3488
|
dimColor: true,
|
|
3259
3489
|
children: "←→↑↓/hjkl navigate • Enter select • Esc back"
|
|
3260
3490
|
}, undefined, false, undefined, this)
|
|
@@ -3264,7 +3494,7 @@ function ThemeMenu({ onBack }) {
|
|
|
3264
3494
|
}
|
|
3265
3495
|
|
|
3266
3496
|
// src/cli/formalconf.tsx
|
|
3267
|
-
import { jsxDEV as
|
|
3497
|
+
import { jsxDEV as jsxDEV20 } from "react/jsx-dev-runtime";
|
|
3268
3498
|
var BREADCRUMBS = {
|
|
3269
3499
|
main: ["Main"],
|
|
3270
3500
|
config: ["Main", "Config Manager"],
|
|
@@ -3272,11 +3502,11 @@ var BREADCRUMBS = {
|
|
|
3272
3502
|
themes: ["Main", "Themes"]
|
|
3273
3503
|
};
|
|
3274
3504
|
function App() {
|
|
3275
|
-
const [appState, setAppState] =
|
|
3276
|
-
const [missingDeps, setMissingDeps] =
|
|
3277
|
-
const [screen, setScreen] =
|
|
3505
|
+
const [appState, setAppState] = useState11("loading");
|
|
3506
|
+
const [missingDeps, setMissingDeps] = useState11([]);
|
|
3507
|
+
const [screen, setScreen] = useState11("main");
|
|
3278
3508
|
const { exit } = useApp2();
|
|
3279
|
-
|
|
3509
|
+
useInput11((input) => {
|
|
3280
3510
|
if (input === "q")
|
|
3281
3511
|
exit();
|
|
3282
3512
|
});
|
|
@@ -3299,44 +3529,44 @@ function App() {
|
|
|
3299
3529
|
init();
|
|
3300
3530
|
}, []);
|
|
3301
3531
|
if (appState === "loading") {
|
|
3302
|
-
return /* @__PURE__ */
|
|
3532
|
+
return /* @__PURE__ */ jsxDEV20(Layout, {
|
|
3303
3533
|
breadcrumb: ["Loading"],
|
|
3304
|
-
children: /* @__PURE__ */
|
|
3534
|
+
children: /* @__PURE__ */ jsxDEV20(Panel, {
|
|
3305
3535
|
title: "FormalConf",
|
|
3306
|
-
children: /* @__PURE__ */
|
|
3536
|
+
children: /* @__PURE__ */ jsxDEV20(Spinner2, {
|
|
3307
3537
|
label: "Checking prerequisites..."
|
|
3308
3538
|
}, undefined, false, undefined, this)
|
|
3309
3539
|
}, undefined, false, undefined, this)
|
|
3310
3540
|
}, undefined, false, undefined, this);
|
|
3311
3541
|
}
|
|
3312
3542
|
if (appState === "error") {
|
|
3313
|
-
return /* @__PURE__ */
|
|
3543
|
+
return /* @__PURE__ */ jsxDEV20(PrerequisiteError, {
|
|
3314
3544
|
missing: missingDeps,
|
|
3315
3545
|
onExit: exit
|
|
3316
3546
|
}, undefined, false, undefined, this);
|
|
3317
3547
|
}
|
|
3318
3548
|
if (appState === "onboarding") {
|
|
3319
|
-
return /* @__PURE__ */
|
|
3549
|
+
return /* @__PURE__ */ jsxDEV20(Onboarding, {
|
|
3320
3550
|
onComplete: () => setAppState("ready")
|
|
3321
3551
|
}, undefined, false, undefined, this);
|
|
3322
3552
|
}
|
|
3323
3553
|
const goBack = () => setScreen("main");
|
|
3324
|
-
return /* @__PURE__ */
|
|
3554
|
+
return /* @__PURE__ */ jsxDEV20(Layout, {
|
|
3325
3555
|
breadcrumb: BREADCRUMBS[screen],
|
|
3326
3556
|
children: [
|
|
3327
|
-
screen === "main" && /* @__PURE__ */
|
|
3557
|
+
screen === "main" && /* @__PURE__ */ jsxDEV20(MainMenu, {
|
|
3328
3558
|
onSelect: setScreen
|
|
3329
3559
|
}, undefined, false, undefined, this),
|
|
3330
|
-
screen === "config" && /* @__PURE__ */
|
|
3560
|
+
screen === "config" && /* @__PURE__ */ jsxDEV20(ConfigMenu, {
|
|
3331
3561
|
onBack: goBack
|
|
3332
3562
|
}, undefined, false, undefined, this),
|
|
3333
|
-
screen === "packages" && /* @__PURE__ */
|
|
3563
|
+
screen === "packages" && /* @__PURE__ */ jsxDEV20(PackageMenu, {
|
|
3334
3564
|
onBack: goBack
|
|
3335
3565
|
}, undefined, false, undefined, this),
|
|
3336
|
-
screen === "themes" && /* @__PURE__ */
|
|
3566
|
+
screen === "themes" && /* @__PURE__ */ jsxDEV20(ThemeMenu, {
|
|
3337
3567
|
onBack: goBack
|
|
3338
3568
|
}, undefined, false, undefined, this)
|
|
3339
3569
|
]
|
|
3340
3570
|
}, undefined, true, undefined, this);
|
|
3341
3571
|
}
|
|
3342
|
-
render(/* @__PURE__ */
|
|
3572
|
+
render(/* @__PURE__ */ jsxDEV20(App, {}, undefined, false, undefined, this));
|