formalconf 2.0.19 → 2.0.21
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/README.md +10 -4
- package/dist/formalconf.js +190 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -295,6 +295,11 @@ bun run theme <name>:<variant> # Apply a theme (e.g., catppuccin:dark, tokyo-ni
|
|
|
295
295
|
bun run theme --install-templates # Install/update default templates
|
|
296
296
|
bun run theme --template-status # Check template versions
|
|
297
297
|
bun run theme --migrate <name> # Migrate legacy theme to JSON format
|
|
298
|
+
bun run template update --all # Update all templates (persists mode metadata)
|
|
299
|
+
bun run template list # List installed templates with their type
|
|
300
|
+
bun run template check # Check for available template updates
|
|
301
|
+
bun run template lock <name> # Lock a template from updates
|
|
302
|
+
bun run template unlock <name> # Unlock a template for updates
|
|
298
303
|
bun run typecheck # Run TypeScript type checking
|
|
299
304
|
```
|
|
300
305
|
|
|
@@ -303,10 +308,11 @@ bun run typecheck # Run TypeScript type checking
|
|
|
303
308
|
```
|
|
304
309
|
src/
|
|
305
310
|
├── cli/ # Entry points (run directly with bun)
|
|
306
|
-
│ ├── formalconf.tsx
|
|
307
|
-
│ ├── config-manager.ts
|
|
308
|
-
│ ├── pkg-sync.ts
|
|
309
|
-
│
|
|
311
|
+
│ ├── formalconf.tsx # Main TUI app
|
|
312
|
+
│ ├── config-manager.ts # Stow operations
|
|
313
|
+
│ ├── pkg-sync.ts # Homebrew/MAS sync
|
|
314
|
+
│ ├── set-theme.ts # Theme switching
|
|
315
|
+
│ └── template-manager.ts # Template management
|
|
310
316
|
├── components/ # Ink React components
|
|
311
317
|
│ ├── layout/ # Layout primitives (Panel, Breadcrumb, Footer)
|
|
312
318
|
│ └── ui/ # UI elements (StatusIndicator, Divider)
|
package/dist/formalconf.js
CHANGED
|
@@ -3622,6 +3622,7 @@ function hexToColorVariable(hex) {
|
|
|
3622
3622
|
strip: normalized.slice(1),
|
|
3623
3623
|
rgb: `rgb(${r},${g},${b})`,
|
|
3624
3624
|
rgba: `rgba(${r},${g},${b},1)`,
|
|
3625
|
+
decimal: `${r},${g},${b}`,
|
|
3625
3626
|
r,
|
|
3626
3627
|
g,
|
|
3627
3628
|
b,
|
|
@@ -3946,6 +3947,8 @@ function applyModifier(color, modifier) {
|
|
|
3946
3947
|
return color.rgb;
|
|
3947
3948
|
case "rgba":
|
|
3948
3949
|
return color.rgba;
|
|
3950
|
+
case "decimal":
|
|
3951
|
+
return color.decimal;
|
|
3949
3952
|
case "r":
|
|
3950
3953
|
return String(color.r);
|
|
3951
3954
|
case "g":
|
|
@@ -3979,6 +3982,7 @@ var init_modifiers = __esm(() => {
|
|
|
3979
3982
|
"strip",
|
|
3980
3983
|
"rgb",
|
|
3981
3984
|
"rgba",
|
|
3985
|
+
"decimal",
|
|
3982
3986
|
"r",
|
|
3983
3987
|
"g",
|
|
3984
3988
|
"b",
|
|
@@ -4181,7 +4185,8 @@ async function installTemplate(templateName) {
|
|
|
4181
4185
|
manifest.templates[templateName] = {
|
|
4182
4186
|
version: bundledMeta.version,
|
|
4183
4187
|
installedAt: new Date().toISOString(),
|
|
4184
|
-
customOverride: false
|
|
4188
|
+
customOverride: false,
|
|
4189
|
+
mode: bundledMeta.mode
|
|
4185
4190
|
};
|
|
4186
4191
|
await saveTemplatesManifest(manifest);
|
|
4187
4192
|
}
|
|
@@ -4191,11 +4196,32 @@ async function installAllTemplates() {
|
|
|
4191
4196
|
await installTemplate(name);
|
|
4192
4197
|
}
|
|
4193
4198
|
}
|
|
4199
|
+
async function lockTemplate(templateName) {
|
|
4200
|
+
const manifest = await loadTemplatesManifest();
|
|
4201
|
+
if (!manifest.templates[templateName]) {
|
|
4202
|
+
throw new Error(`Template '${templateName}' is not installed`);
|
|
4203
|
+
}
|
|
4204
|
+
manifest.templates[templateName].customOverride = true;
|
|
4205
|
+
await saveTemplatesManifest(manifest);
|
|
4206
|
+
}
|
|
4207
|
+
async function unlockTemplate(templateName) {
|
|
4208
|
+
const manifest = await loadTemplatesManifest();
|
|
4209
|
+
if (!manifest.templates[templateName]) {
|
|
4210
|
+
throw new Error(`Template '${templateName}' is not installed`);
|
|
4211
|
+
}
|
|
4212
|
+
manifest.templates[templateName].customOverride = false;
|
|
4213
|
+
await saveTemplatesManifest(manifest);
|
|
4214
|
+
}
|
|
4194
4215
|
async function getTemplateType(filename) {
|
|
4195
|
-
const
|
|
4196
|
-
const
|
|
4197
|
-
if (
|
|
4198
|
-
return
|
|
4216
|
+
const installed = await loadTemplatesManifest();
|
|
4217
|
+
const installedMeta = installed.templates[filename];
|
|
4218
|
+
if (installedMeta?.mode) {
|
|
4219
|
+
return installedMeta.mode;
|
|
4220
|
+
}
|
|
4221
|
+
const bundled = await loadBundledManifest();
|
|
4222
|
+
const bundledMeta = bundled.templates[filename];
|
|
4223
|
+
if (bundledMeta?.mode) {
|
|
4224
|
+
return bundledMeta.mode;
|
|
4199
4225
|
}
|
|
4200
4226
|
if (filename.includes("-dark.") || filename.includes("-light.")) {
|
|
4201
4227
|
return "partial";
|
|
@@ -4218,9 +4244,14 @@ async function getOutputFilename(templateName) {
|
|
|
4218
4244
|
return templateName.replace(/\.template$/, "");
|
|
4219
4245
|
}
|
|
4220
4246
|
async function getTemplateTargets(templateName) {
|
|
4221
|
-
const
|
|
4222
|
-
const
|
|
4223
|
-
|
|
4247
|
+
const installed = await loadTemplatesManifest();
|
|
4248
|
+
const installedMeta = installed.templates[templateName];
|
|
4249
|
+
if (installedMeta?.targets) {
|
|
4250
|
+
return installedMeta.targets;
|
|
4251
|
+
}
|
|
4252
|
+
const bundled = await loadBundledManifest();
|
|
4253
|
+
const bundledMeta = bundled.templates[templateName];
|
|
4254
|
+
return bundledMeta?.targets ?? [];
|
|
4224
4255
|
}
|
|
4225
4256
|
async function listInstalledTemplates() {
|
|
4226
4257
|
if (!existsSync11(TEMPLATES_DIR)) {
|
|
@@ -5410,8 +5441,136 @@ var init_set_theme = __esm(() => {
|
|
|
5410
5441
|
}
|
|
5411
5442
|
});
|
|
5412
5443
|
|
|
5444
|
+
// src/cli/template-manager.ts
|
|
5445
|
+
var exports_template_manager = {};
|
|
5446
|
+
__export(exports_template_manager, {
|
|
5447
|
+
main: () => main5
|
|
5448
|
+
});
|
|
5449
|
+
import { parseArgs as parseArgs5 } from "util";
|
|
5450
|
+
function printHelp() {
|
|
5451
|
+
console.log(`
|
|
5452
|
+
${colors6.cyan}Template Manager - Manage formalconf templates${colors6.reset}
|
|
5453
|
+
|
|
5454
|
+
Usage:
|
|
5455
|
+
formalconf template <command> [options]
|
|
5456
|
+
|
|
5457
|
+
Commands:
|
|
5458
|
+
${colors6.blue}update${colors6.reset} [name] Update templates (all if no name specified)
|
|
5459
|
+
${colors6.blue}list${colors6.reset} List installed templates
|
|
5460
|
+
${colors6.blue}check${colors6.reset} Check for available updates
|
|
5461
|
+
${colors6.blue}lock${colors6.reset} <name> Lock a template from updates
|
|
5462
|
+
${colors6.blue}unlock${colors6.reset} <name> Unlock a template for updates
|
|
5463
|
+
|
|
5464
|
+
Options:
|
|
5465
|
+
-h, --help Show this help message
|
|
5466
|
+
--all Update all templates (with update command)
|
|
5467
|
+
|
|
5468
|
+
Examples:
|
|
5469
|
+
formalconf template update --all
|
|
5470
|
+
formalconf template check
|
|
5471
|
+
formalconf template lock neovim.lua.template
|
|
5472
|
+
`);
|
|
5473
|
+
}
|
|
5474
|
+
async function main5() {
|
|
5475
|
+
const { positionals, values } = parseArgs5({
|
|
5476
|
+
args: process.argv.slice(2),
|
|
5477
|
+
options: {
|
|
5478
|
+
help: { type: "boolean", short: "h" },
|
|
5479
|
+
all: { type: "boolean" }
|
|
5480
|
+
},
|
|
5481
|
+
allowPositionals: true,
|
|
5482
|
+
strict: false
|
|
5483
|
+
});
|
|
5484
|
+
const [subCommand, ...args] = positionals;
|
|
5485
|
+
if (values.help || !subCommand) {
|
|
5486
|
+
printHelp();
|
|
5487
|
+
process.exit(0);
|
|
5488
|
+
}
|
|
5489
|
+
switch (subCommand) {
|
|
5490
|
+
case "update":
|
|
5491
|
+
await handleUpdate(args[0], values.all);
|
|
5492
|
+
break;
|
|
5493
|
+
case "list":
|
|
5494
|
+
await handleList();
|
|
5495
|
+
break;
|
|
5496
|
+
case "check":
|
|
5497
|
+
await handleCheck();
|
|
5498
|
+
break;
|
|
5499
|
+
case "lock":
|
|
5500
|
+
if (!args[0]) {
|
|
5501
|
+
console.error(`${colors6.red}Error: Template name required${colors6.reset}`);
|
|
5502
|
+
process.exit(1);
|
|
5503
|
+
}
|
|
5504
|
+
await lockTemplate(args[0]);
|
|
5505
|
+
console.log(`${colors6.green}Locked ${args[0]}${colors6.reset}`);
|
|
5506
|
+
break;
|
|
5507
|
+
case "unlock":
|
|
5508
|
+
if (!args[0]) {
|
|
5509
|
+
console.error(`${colors6.red}Error: Template name required${colors6.reset}`);
|
|
5510
|
+
process.exit(1);
|
|
5511
|
+
}
|
|
5512
|
+
await unlockTemplate(args[0]);
|
|
5513
|
+
console.log(`${colors6.green}Unlocked ${args[0]}${colors6.reset}`);
|
|
5514
|
+
break;
|
|
5515
|
+
default:
|
|
5516
|
+
console.error(`${colors6.red}Unknown command: ${subCommand}${colors6.reset}`);
|
|
5517
|
+
printHelp();
|
|
5518
|
+
process.exit(1);
|
|
5519
|
+
}
|
|
5520
|
+
}
|
|
5521
|
+
async function handleUpdate(name, all) {
|
|
5522
|
+
if (all || !name) {
|
|
5523
|
+
console.log(`${colors6.cyan}Updating all templates...${colors6.reset}`);
|
|
5524
|
+
await installAllTemplates();
|
|
5525
|
+
console.log(`${colors6.green}All templates updated${colors6.reset}`);
|
|
5526
|
+
} else {
|
|
5527
|
+
console.log(`${colors6.cyan}Updating ${name}...${colors6.reset}`);
|
|
5528
|
+
await installTemplate(name);
|
|
5529
|
+
console.log(`${colors6.green}Updated ${name}${colors6.reset}`);
|
|
5530
|
+
}
|
|
5531
|
+
}
|
|
5532
|
+
async function handleList() {
|
|
5533
|
+
const templates = await listInstalledTemplates();
|
|
5534
|
+
console.log(`
|
|
5535
|
+
${colors6.cyan}Installed templates:${colors6.reset}`);
|
|
5536
|
+
for (const t of templates) {
|
|
5537
|
+
const typeLabel = t.type === "dual" ? colors6.blue + "dual" : t.type === "partial" ? colors6.yellow + "partial" : colors6.dim + "single";
|
|
5538
|
+
console.log(` ${colors6.blue}•${colors6.reset} ${t.name} (${typeLabel}${colors6.reset})`);
|
|
5539
|
+
}
|
|
5540
|
+
console.log();
|
|
5541
|
+
}
|
|
5542
|
+
async function handleCheck() {
|
|
5543
|
+
const updates = await checkTemplateUpdates();
|
|
5544
|
+
const available = updates.filter((u) => u.updateAvailable);
|
|
5545
|
+
if (available.length === 0) {
|
|
5546
|
+
console.log(`${colors6.green}All templates are up to date${colors6.reset}`);
|
|
5547
|
+
} else {
|
|
5548
|
+
console.log(`${colors6.yellow}Updates available:${colors6.reset}`);
|
|
5549
|
+
for (const u of available) {
|
|
5550
|
+
console.log(` ${u.name}: ${u.installedVersion} -> ${u.bundledVersion}`);
|
|
5551
|
+
}
|
|
5552
|
+
}
|
|
5553
|
+
}
|
|
5554
|
+
var colors6, isMainModule5;
|
|
5555
|
+
var init_template_manager = __esm(() => {
|
|
5556
|
+
init_versioning();
|
|
5557
|
+
colors6 = {
|
|
5558
|
+
red: "\x1B[0;31m",
|
|
5559
|
+
green: "\x1B[0;32m",
|
|
5560
|
+
blue: "\x1B[0;34m",
|
|
5561
|
+
yellow: "\x1B[1;33m",
|
|
5562
|
+
cyan: "\x1B[0;36m",
|
|
5563
|
+
dim: "\x1B[2m",
|
|
5564
|
+
reset: "\x1B[0m"
|
|
5565
|
+
};
|
|
5566
|
+
isMainModule5 = process.argv[1]?.includes("template-manager");
|
|
5567
|
+
if (isMainModule5) {
|
|
5568
|
+
main5().catch(console.error);
|
|
5569
|
+
}
|
|
5570
|
+
});
|
|
5571
|
+
|
|
5413
5572
|
// src/cli/formalconf.tsx
|
|
5414
|
-
import { parseArgs as
|
|
5573
|
+
import { parseArgs as parseArgs6 } from "node:util";
|
|
5415
5574
|
import { useState as useState11, useEffect as useEffect7 } from "react";
|
|
5416
5575
|
import { render, useApp as useApp2, useInput as useInput11 } from "ink";
|
|
5417
5576
|
import { Spinner as Spinner2 } from "@inkjs/ui";
|
|
@@ -5554,7 +5713,7 @@ function StatusIndicator({
|
|
|
5554
5713
|
// package.json
|
|
5555
5714
|
var package_default = {
|
|
5556
5715
|
name: "formalconf",
|
|
5557
|
-
version: "2.0.
|
|
5716
|
+
version: "2.0.21",
|
|
5558
5717
|
description: "Dotfiles management TUI for macOS and Linux - config management, package sync, and theme switching",
|
|
5559
5718
|
type: "module",
|
|
5560
5719
|
main: "./dist/formalconf.js",
|
|
@@ -7778,7 +7937,7 @@ function ThemeMenu({ onBack }) {
|
|
|
7778
7937
|
init_paths();
|
|
7779
7938
|
init_runtime();
|
|
7780
7939
|
import { jsxDEV as jsxDEV20 } from "react/jsx-dev-runtime";
|
|
7781
|
-
function
|
|
7940
|
+
function printHelp2() {
|
|
7782
7941
|
console.log(`
|
|
7783
7942
|
FormalConf - Dotfiles Management TUI
|
|
7784
7943
|
|
|
@@ -7787,6 +7946,7 @@ Usage:
|
|
|
7787
7946
|
formalconf theme <name> Apply a theme (e.g., nord:dark)
|
|
7788
7947
|
formalconf config <cmd> Config management (stow, unstow, status, list)
|
|
7789
7948
|
formalconf pkg-sync [flags] Sync packages from pkg-config.json
|
|
7949
|
+
formalconf template <cmd> Template management (update, list, check)
|
|
7790
7950
|
|
|
7791
7951
|
Options:
|
|
7792
7952
|
-h, --help Show this help message
|
|
@@ -7795,6 +7955,7 @@ Examples:
|
|
|
7795
7955
|
formalconf theme nord:dark
|
|
7796
7956
|
formalconf config stow nvim
|
|
7797
7957
|
formalconf pkg-sync --purge
|
|
7958
|
+
formalconf template update --all
|
|
7798
7959
|
`);
|
|
7799
7960
|
}
|
|
7800
7961
|
var BREADCRUMBS = {
|
|
@@ -7871,8 +8032,8 @@ function App() {
|
|
|
7871
8032
|
]
|
|
7872
8033
|
}, undefined, true, undefined, this);
|
|
7873
8034
|
}
|
|
7874
|
-
async function
|
|
7875
|
-
const { positionals, values } =
|
|
8035
|
+
async function main6() {
|
|
8036
|
+
const { positionals, values } = parseArgs6({
|
|
7876
8037
|
args: process.argv.slice(2),
|
|
7877
8038
|
options: {
|
|
7878
8039
|
help: { type: "boolean", short: "h" }
|
|
@@ -7882,36 +8043,42 @@ async function main5() {
|
|
|
7882
8043
|
});
|
|
7883
8044
|
const [subcommand] = positionals;
|
|
7884
8045
|
if (values.help && !subcommand) {
|
|
7885
|
-
|
|
8046
|
+
printHelp2();
|
|
7886
8047
|
process.exit(0);
|
|
7887
8048
|
}
|
|
7888
8049
|
if (subcommand) {
|
|
7889
8050
|
const scriptMap = {
|
|
7890
8051
|
theme: "set-theme",
|
|
7891
8052
|
config: "config-manager",
|
|
7892
|
-
"pkg-sync": "pkg-sync"
|
|
8053
|
+
"pkg-sync": "pkg-sync",
|
|
8054
|
+
template: "template-manager"
|
|
7893
8055
|
};
|
|
7894
8056
|
const scriptName = scriptMap[subcommand];
|
|
7895
8057
|
if (!scriptName) {
|
|
7896
8058
|
console.error(`Unknown subcommand: ${subcommand}`);
|
|
7897
|
-
|
|
8059
|
+
printHelp2();
|
|
7898
8060
|
process.exit(1);
|
|
7899
8061
|
}
|
|
7900
8062
|
process.argv = [process.argv[0], scriptName, ...process.argv.slice(3)];
|
|
7901
8063
|
switch (subcommand) {
|
|
7902
8064
|
case "theme": {
|
|
7903
|
-
const { main:
|
|
7904
|
-
await
|
|
8065
|
+
const { main: main7 } = await Promise.resolve().then(() => (init_set_theme(), exports_set_theme));
|
|
8066
|
+
await main7();
|
|
7905
8067
|
break;
|
|
7906
8068
|
}
|
|
7907
8069
|
case "config": {
|
|
7908
|
-
const { main:
|
|
7909
|
-
await
|
|
8070
|
+
const { main: main7 } = await Promise.resolve().then(() => (init_config_manager(), exports_config_manager));
|
|
8071
|
+
await main7();
|
|
7910
8072
|
break;
|
|
7911
8073
|
}
|
|
7912
8074
|
case "pkg-sync": {
|
|
7913
|
-
const { main:
|
|
7914
|
-
await
|
|
8075
|
+
const { main: main7 } = await Promise.resolve().then(() => (init_pkg_sync(), exports_pkg_sync));
|
|
8076
|
+
await main7();
|
|
8077
|
+
break;
|
|
8078
|
+
}
|
|
8079
|
+
case "template": {
|
|
8080
|
+
const { main: main7 } = await Promise.resolve().then(() => (init_template_manager(), exports_template_manager));
|
|
8081
|
+
await main7();
|
|
7915
8082
|
break;
|
|
7916
8083
|
}
|
|
7917
8084
|
}
|
|
@@ -7919,4 +8086,4 @@ async function main5() {
|
|
|
7919
8086
|
}
|
|
7920
8087
|
render(/* @__PURE__ */ jsxDEV20(App, {}, undefined, false, undefined, this));
|
|
7921
8088
|
}
|
|
7922
|
-
|
|
8089
|
+
main6();
|
package/package.json
CHANGED