formalconf 2.0.19 → 2.0.20
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 +178 -20
- 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
|
@@ -4181,7 +4181,8 @@ async function installTemplate(templateName) {
|
|
|
4181
4181
|
manifest.templates[templateName] = {
|
|
4182
4182
|
version: bundledMeta.version,
|
|
4183
4183
|
installedAt: new Date().toISOString(),
|
|
4184
|
-
customOverride: false
|
|
4184
|
+
customOverride: false,
|
|
4185
|
+
mode: bundledMeta.mode
|
|
4185
4186
|
};
|
|
4186
4187
|
await saveTemplatesManifest(manifest);
|
|
4187
4188
|
}
|
|
@@ -4191,11 +4192,32 @@ async function installAllTemplates() {
|
|
|
4191
4192
|
await installTemplate(name);
|
|
4192
4193
|
}
|
|
4193
4194
|
}
|
|
4195
|
+
async function lockTemplate(templateName) {
|
|
4196
|
+
const manifest = await loadTemplatesManifest();
|
|
4197
|
+
if (!manifest.templates[templateName]) {
|
|
4198
|
+
throw new Error(`Template '${templateName}' is not installed`);
|
|
4199
|
+
}
|
|
4200
|
+
manifest.templates[templateName].customOverride = true;
|
|
4201
|
+
await saveTemplatesManifest(manifest);
|
|
4202
|
+
}
|
|
4203
|
+
async function unlockTemplate(templateName) {
|
|
4204
|
+
const manifest = await loadTemplatesManifest();
|
|
4205
|
+
if (!manifest.templates[templateName]) {
|
|
4206
|
+
throw new Error(`Template '${templateName}' is not installed`);
|
|
4207
|
+
}
|
|
4208
|
+
manifest.templates[templateName].customOverride = false;
|
|
4209
|
+
await saveTemplatesManifest(manifest);
|
|
4210
|
+
}
|
|
4194
4211
|
async function getTemplateType(filename) {
|
|
4195
|
-
const
|
|
4196
|
-
const
|
|
4197
|
-
if (
|
|
4198
|
-
return
|
|
4212
|
+
const installed = await loadTemplatesManifest();
|
|
4213
|
+
const installedMeta = installed.templates[filename];
|
|
4214
|
+
if (installedMeta?.mode) {
|
|
4215
|
+
return installedMeta.mode;
|
|
4216
|
+
}
|
|
4217
|
+
const bundled = await loadBundledManifest();
|
|
4218
|
+
const bundledMeta = bundled.templates[filename];
|
|
4219
|
+
if (bundledMeta?.mode) {
|
|
4220
|
+
return bundledMeta.mode;
|
|
4199
4221
|
}
|
|
4200
4222
|
if (filename.includes("-dark.") || filename.includes("-light.")) {
|
|
4201
4223
|
return "partial";
|
|
@@ -5410,8 +5432,136 @@ var init_set_theme = __esm(() => {
|
|
|
5410
5432
|
}
|
|
5411
5433
|
});
|
|
5412
5434
|
|
|
5435
|
+
// src/cli/template-manager.ts
|
|
5436
|
+
var exports_template_manager = {};
|
|
5437
|
+
__export(exports_template_manager, {
|
|
5438
|
+
main: () => main5
|
|
5439
|
+
});
|
|
5440
|
+
import { parseArgs as parseArgs5 } from "util";
|
|
5441
|
+
function printHelp() {
|
|
5442
|
+
console.log(`
|
|
5443
|
+
${colors6.cyan}Template Manager - Manage formalconf templates${colors6.reset}
|
|
5444
|
+
|
|
5445
|
+
Usage:
|
|
5446
|
+
formalconf template <command> [options]
|
|
5447
|
+
|
|
5448
|
+
Commands:
|
|
5449
|
+
${colors6.blue}update${colors6.reset} [name] Update templates (all if no name specified)
|
|
5450
|
+
${colors6.blue}list${colors6.reset} List installed templates
|
|
5451
|
+
${colors6.blue}check${colors6.reset} Check for available updates
|
|
5452
|
+
${colors6.blue}lock${colors6.reset} <name> Lock a template from updates
|
|
5453
|
+
${colors6.blue}unlock${colors6.reset} <name> Unlock a template for updates
|
|
5454
|
+
|
|
5455
|
+
Options:
|
|
5456
|
+
-h, --help Show this help message
|
|
5457
|
+
--all Update all templates (with update command)
|
|
5458
|
+
|
|
5459
|
+
Examples:
|
|
5460
|
+
formalconf template update --all
|
|
5461
|
+
formalconf template check
|
|
5462
|
+
formalconf template lock neovim.lua.template
|
|
5463
|
+
`);
|
|
5464
|
+
}
|
|
5465
|
+
async function main5() {
|
|
5466
|
+
const { positionals, values } = parseArgs5({
|
|
5467
|
+
args: process.argv.slice(2),
|
|
5468
|
+
options: {
|
|
5469
|
+
help: { type: "boolean", short: "h" },
|
|
5470
|
+
all: { type: "boolean" }
|
|
5471
|
+
},
|
|
5472
|
+
allowPositionals: true,
|
|
5473
|
+
strict: false
|
|
5474
|
+
});
|
|
5475
|
+
const [subCommand, ...args] = positionals;
|
|
5476
|
+
if (values.help || !subCommand) {
|
|
5477
|
+
printHelp();
|
|
5478
|
+
process.exit(0);
|
|
5479
|
+
}
|
|
5480
|
+
switch (subCommand) {
|
|
5481
|
+
case "update":
|
|
5482
|
+
await handleUpdate(args[0], values.all);
|
|
5483
|
+
break;
|
|
5484
|
+
case "list":
|
|
5485
|
+
await handleList();
|
|
5486
|
+
break;
|
|
5487
|
+
case "check":
|
|
5488
|
+
await handleCheck();
|
|
5489
|
+
break;
|
|
5490
|
+
case "lock":
|
|
5491
|
+
if (!args[0]) {
|
|
5492
|
+
console.error(`${colors6.red}Error: Template name required${colors6.reset}`);
|
|
5493
|
+
process.exit(1);
|
|
5494
|
+
}
|
|
5495
|
+
await lockTemplate(args[0]);
|
|
5496
|
+
console.log(`${colors6.green}Locked ${args[0]}${colors6.reset}`);
|
|
5497
|
+
break;
|
|
5498
|
+
case "unlock":
|
|
5499
|
+
if (!args[0]) {
|
|
5500
|
+
console.error(`${colors6.red}Error: Template name required${colors6.reset}`);
|
|
5501
|
+
process.exit(1);
|
|
5502
|
+
}
|
|
5503
|
+
await unlockTemplate(args[0]);
|
|
5504
|
+
console.log(`${colors6.green}Unlocked ${args[0]}${colors6.reset}`);
|
|
5505
|
+
break;
|
|
5506
|
+
default:
|
|
5507
|
+
console.error(`${colors6.red}Unknown command: ${subCommand}${colors6.reset}`);
|
|
5508
|
+
printHelp();
|
|
5509
|
+
process.exit(1);
|
|
5510
|
+
}
|
|
5511
|
+
}
|
|
5512
|
+
async function handleUpdate(name, all) {
|
|
5513
|
+
if (all || !name) {
|
|
5514
|
+
console.log(`${colors6.cyan}Updating all templates...${colors6.reset}`);
|
|
5515
|
+
await installAllTemplates();
|
|
5516
|
+
console.log(`${colors6.green}All templates updated${colors6.reset}`);
|
|
5517
|
+
} else {
|
|
5518
|
+
console.log(`${colors6.cyan}Updating ${name}...${colors6.reset}`);
|
|
5519
|
+
await installTemplate(name);
|
|
5520
|
+
console.log(`${colors6.green}Updated ${name}${colors6.reset}`);
|
|
5521
|
+
}
|
|
5522
|
+
}
|
|
5523
|
+
async function handleList() {
|
|
5524
|
+
const templates = await listInstalledTemplates();
|
|
5525
|
+
console.log(`
|
|
5526
|
+
${colors6.cyan}Installed templates:${colors6.reset}`);
|
|
5527
|
+
for (const t of templates) {
|
|
5528
|
+
const typeLabel = t.type === "dual" ? colors6.blue + "dual" : t.type === "partial" ? colors6.yellow + "partial" : colors6.dim + "single";
|
|
5529
|
+
console.log(` ${colors6.blue}•${colors6.reset} ${t.name} (${typeLabel}${colors6.reset})`);
|
|
5530
|
+
}
|
|
5531
|
+
console.log();
|
|
5532
|
+
}
|
|
5533
|
+
async function handleCheck() {
|
|
5534
|
+
const updates = await checkTemplateUpdates();
|
|
5535
|
+
const available = updates.filter((u) => u.updateAvailable);
|
|
5536
|
+
if (available.length === 0) {
|
|
5537
|
+
console.log(`${colors6.green}All templates are up to date${colors6.reset}`);
|
|
5538
|
+
} else {
|
|
5539
|
+
console.log(`${colors6.yellow}Updates available:${colors6.reset}`);
|
|
5540
|
+
for (const u of available) {
|
|
5541
|
+
console.log(` ${u.name}: ${u.installedVersion} -> ${u.bundledVersion}`);
|
|
5542
|
+
}
|
|
5543
|
+
}
|
|
5544
|
+
}
|
|
5545
|
+
var colors6, isMainModule5;
|
|
5546
|
+
var init_template_manager = __esm(() => {
|
|
5547
|
+
init_versioning();
|
|
5548
|
+
colors6 = {
|
|
5549
|
+
red: "\x1B[0;31m",
|
|
5550
|
+
green: "\x1B[0;32m",
|
|
5551
|
+
blue: "\x1B[0;34m",
|
|
5552
|
+
yellow: "\x1B[1;33m",
|
|
5553
|
+
cyan: "\x1B[0;36m",
|
|
5554
|
+
dim: "\x1B[2m",
|
|
5555
|
+
reset: "\x1B[0m"
|
|
5556
|
+
};
|
|
5557
|
+
isMainModule5 = process.argv[1]?.includes("template-manager");
|
|
5558
|
+
if (isMainModule5) {
|
|
5559
|
+
main5().catch(console.error);
|
|
5560
|
+
}
|
|
5561
|
+
});
|
|
5562
|
+
|
|
5413
5563
|
// src/cli/formalconf.tsx
|
|
5414
|
-
import { parseArgs as
|
|
5564
|
+
import { parseArgs as parseArgs6 } from "node:util";
|
|
5415
5565
|
import { useState as useState11, useEffect as useEffect7 } from "react";
|
|
5416
5566
|
import { render, useApp as useApp2, useInput as useInput11 } from "ink";
|
|
5417
5567
|
import { Spinner as Spinner2 } from "@inkjs/ui";
|
|
@@ -5554,7 +5704,7 @@ function StatusIndicator({
|
|
|
5554
5704
|
// package.json
|
|
5555
5705
|
var package_default = {
|
|
5556
5706
|
name: "formalconf",
|
|
5557
|
-
version: "2.0.
|
|
5707
|
+
version: "2.0.20",
|
|
5558
5708
|
description: "Dotfiles management TUI for macOS and Linux - config management, package sync, and theme switching",
|
|
5559
5709
|
type: "module",
|
|
5560
5710
|
main: "./dist/formalconf.js",
|
|
@@ -7778,7 +7928,7 @@ function ThemeMenu({ onBack }) {
|
|
|
7778
7928
|
init_paths();
|
|
7779
7929
|
init_runtime();
|
|
7780
7930
|
import { jsxDEV as jsxDEV20 } from "react/jsx-dev-runtime";
|
|
7781
|
-
function
|
|
7931
|
+
function printHelp2() {
|
|
7782
7932
|
console.log(`
|
|
7783
7933
|
FormalConf - Dotfiles Management TUI
|
|
7784
7934
|
|
|
@@ -7787,6 +7937,7 @@ Usage:
|
|
|
7787
7937
|
formalconf theme <name> Apply a theme (e.g., nord:dark)
|
|
7788
7938
|
formalconf config <cmd> Config management (stow, unstow, status, list)
|
|
7789
7939
|
formalconf pkg-sync [flags] Sync packages from pkg-config.json
|
|
7940
|
+
formalconf template <cmd> Template management (update, list, check)
|
|
7790
7941
|
|
|
7791
7942
|
Options:
|
|
7792
7943
|
-h, --help Show this help message
|
|
@@ -7795,6 +7946,7 @@ Examples:
|
|
|
7795
7946
|
formalconf theme nord:dark
|
|
7796
7947
|
formalconf config stow nvim
|
|
7797
7948
|
formalconf pkg-sync --purge
|
|
7949
|
+
formalconf template update --all
|
|
7798
7950
|
`);
|
|
7799
7951
|
}
|
|
7800
7952
|
var BREADCRUMBS = {
|
|
@@ -7871,8 +8023,8 @@ function App() {
|
|
|
7871
8023
|
]
|
|
7872
8024
|
}, undefined, true, undefined, this);
|
|
7873
8025
|
}
|
|
7874
|
-
async function
|
|
7875
|
-
const { positionals, values } =
|
|
8026
|
+
async function main6() {
|
|
8027
|
+
const { positionals, values } = parseArgs6({
|
|
7876
8028
|
args: process.argv.slice(2),
|
|
7877
8029
|
options: {
|
|
7878
8030
|
help: { type: "boolean", short: "h" }
|
|
@@ -7882,36 +8034,42 @@ async function main5() {
|
|
|
7882
8034
|
});
|
|
7883
8035
|
const [subcommand] = positionals;
|
|
7884
8036
|
if (values.help && !subcommand) {
|
|
7885
|
-
|
|
8037
|
+
printHelp2();
|
|
7886
8038
|
process.exit(0);
|
|
7887
8039
|
}
|
|
7888
8040
|
if (subcommand) {
|
|
7889
8041
|
const scriptMap = {
|
|
7890
8042
|
theme: "set-theme",
|
|
7891
8043
|
config: "config-manager",
|
|
7892
|
-
"pkg-sync": "pkg-sync"
|
|
8044
|
+
"pkg-sync": "pkg-sync",
|
|
8045
|
+
template: "template-manager"
|
|
7893
8046
|
};
|
|
7894
8047
|
const scriptName = scriptMap[subcommand];
|
|
7895
8048
|
if (!scriptName) {
|
|
7896
8049
|
console.error(`Unknown subcommand: ${subcommand}`);
|
|
7897
|
-
|
|
8050
|
+
printHelp2();
|
|
7898
8051
|
process.exit(1);
|
|
7899
8052
|
}
|
|
7900
8053
|
process.argv = [process.argv[0], scriptName, ...process.argv.slice(3)];
|
|
7901
8054
|
switch (subcommand) {
|
|
7902
8055
|
case "theme": {
|
|
7903
|
-
const { main:
|
|
7904
|
-
await
|
|
8056
|
+
const { main: main7 } = await Promise.resolve().then(() => (init_set_theme(), exports_set_theme));
|
|
8057
|
+
await main7();
|
|
7905
8058
|
break;
|
|
7906
8059
|
}
|
|
7907
8060
|
case "config": {
|
|
7908
|
-
const { main:
|
|
7909
|
-
await
|
|
8061
|
+
const { main: main7 } = await Promise.resolve().then(() => (init_config_manager(), exports_config_manager));
|
|
8062
|
+
await main7();
|
|
7910
8063
|
break;
|
|
7911
8064
|
}
|
|
7912
8065
|
case "pkg-sync": {
|
|
7913
|
-
const { main:
|
|
7914
|
-
await
|
|
8066
|
+
const { main: main7 } = await Promise.resolve().then(() => (init_pkg_sync(), exports_pkg_sync));
|
|
8067
|
+
await main7();
|
|
8068
|
+
break;
|
|
8069
|
+
}
|
|
8070
|
+
case "template": {
|
|
8071
|
+
const { main: main7 } = await Promise.resolve().then(() => (init_template_manager(), exports_template_manager));
|
|
8072
|
+
await main7();
|
|
7915
8073
|
break;
|
|
7916
8074
|
}
|
|
7917
8075
|
}
|
|
@@ -7919,4 +8077,4 @@ async function main5() {
|
|
|
7919
8077
|
}
|
|
7920
8078
|
render(/* @__PURE__ */ jsxDEV20(App, {}, undefined, false, undefined, this));
|
|
7921
8079
|
}
|
|
7922
|
-
|
|
8080
|
+
main6();
|
package/package.json
CHANGED