Initial upload with CI/CD workflow
Some checks failed
CI / test (push) Has been cancelled

This commit is contained in:
2026-02-05 19:31:34 +00:00
parent 0364943af6
commit 887f546362

226
src/index.ts Normal file
View File

@@ -0,0 +1,226 @@
#!/usr/bin/env node
import { Command } from 'commander';
import { fileUtils } from './utils/fileUtils';
import {
saveLayout,
restoreLayout,
listLayouts,
importLayout,
exportLayout,
syncLayouts,
manageTemplates,
deleteLayout,
} from './commands';
const program = new Command();
program.name('terminal-layout-sync').description('CLI tool for saving, restoring, and syncing terminal workspace layouts').version('1.0.0');
program.hook('preAction', async () => {
await fileUtils.initialize().catch(() => {});
});
program
.command('save')
.description('Save current terminal layout to a config file')
.alias('s')
.option('-n, --name <name>', 'Layout name')
.option('-t, --terminal <type>', 'Terminal type (tmux, screen, iterm2)')
.option('-s, --session <name>', 'Session name to capture')
.option('-f, --format <format>', 'Output format (json, yaml)', 'json')
.option('-d, --description <desc>', 'Layout description')
.option('--tags <tags>', 'Tags (comma-separated)')
.action(async (options) => {
try {
await saveLayout({
name: options.name,
terminal: options.terminal as 'tmux' | 'screen' | 'iterm2' | 'unknown',
session: options.session,
format: options.format,
description: options.description,
tags: options.tags?.split(',').map((t: string) => t.trim()),
});
} catch (error) {
console.error('Error saving layout:', (error as Error).message);
process.exit(1);
}
});
program
.command('restore')
.description('Restore a saved layout to a terminal session')
.alias('r')
.argument('[name]', 'Layout name')
.option('-s, --session <name>', 'Session name to restore to')
.option('-a, --attach', 'Show attach command after restore')
.option('--dry-run', 'Show commands without executing')
.action(async (name, options) => {
try {
await restoreLayout({
name,
session: options.session,
attach: options.attach,
dryRun: options.dryRun,
});
} catch (error) {
console.error('Error restoring layout:', (error as Error).message);
process.exit(1);
}
});
program
.command('list')
.description('List all saved layouts')
.alias('ls')
.option('-f, --format <format>', 'Output format (table, json)', 'table')
.option('-v, --verbose', 'Show verbose output')
.action(async (options) => {
try {
await listLayouts({
format: options.format,
verbose: options.verbose,
});
} catch (error) {
console.error('Error listing layouts:', (error as Error).message);
process.exit(1);
}
});
program
.command('import')
.description('Import a layout from an external file')
.alias('i')
.argument('<file>', 'File to import')
.option('-n, --name <name>', 'Layout name after import')
.action(async (file, options) => {
try {
await importLayout({
file,
name: options.name,
});
} catch (error) {
console.error('Error importing layout:', (error as Error).message);
process.exit(1);
}
});
program
.command('export')
.description('Export a layout to an external file')
.alias('e')
.argument('[name]', 'Layout name to export')
.option('-o, --output <path>', 'Output file path')
.option('-f, --format <format>', 'Output format (json, yaml)')
.action(async (name, options) => {
try {
await exportLayout({
name,
output: options.output,
format: options.format,
});
} catch (error) {
console.error('Error exporting layout:', (error as Error).message);
process.exit(1);
}
});
program
.command('delete')
.description('Delete a saved layout')
.alias('rm')
.argument('[name]', 'Layout name to delete')
.option('-f, --force', 'Skip confirmation')
.action(async (name, options) => {
try {
await deleteLayout({
name,
force: options.force,
});
} catch (error) {
console.error('Error deleting layout:', (error as Error).message);
process.exit(1);
}
});
program
.command('sync')
.description('Sync layouts with git repository')
.option('--init', 'Initialize git repository')
.option('--remote <url>', 'Remote repository URL')
.option('--branch <name>', 'Branch name', 'main')
.option('--push', 'Push changes to remote')
.option('--pull', 'Pull changes from remote')
.option('-m, --message <msg>', 'Commit message')
.action(async (options) => {
try {
await syncLayouts({
init: options.init,
remote: options.remote,
branch: options.branch,
push: options.push,
pull: options.pull,
message: options.message,
});
} catch (error) {
console.error('Error syncing layouts:', (error as Error).message);
process.exit(1);
}
});
program
.command('template')
.description('Manage layout templates')
.alias('tpl')
.option('--list', 'List all templates')
.option('--create', 'Create a new template')
.option('--delete <name>', 'Delete a template')
.option('--apply <name>', 'Apply a template')
.option('--var <values>', 'Template variables (key=value)')
.action(async (options) => {
try {
const variables: Record<string, string> = {};
if (options.var) {
for (const v of options.var) {
const [key, value] = v.split('=');
if (key && value) {
variables[key] = value;
}
}
}
await manageTemplates({
name: options.delete || options.apply,
list: options.list,
create: options.create,
delete: !!options.delete,
apply: options.apply,
variables,
});
} catch (error) {
console.error('Error managing templates:', (error as Error).message);
process.exit(1);
}
});
program
.command('info')
.description('Show information about the CLI')
.action(async () => {
console.log('Terminal Layout Sync CLI');
console.log('Version: 1.0.0');
console.log('');
console.log('Commands:');
console.log(' save - Save current terminal layout');
console.log(' restore - Restore a saved layout');
console.log(' list - List all saved layouts');
console.log(' import - Import layout from file');
console.log(' export - Export layout to file');
console.log(' delete - Delete a layout');
console.log(' sync - Sync with git repository');
console.log(' template - Manage templates');
console.log('');
console.log('For more information, use: terminal-layout-sync <command> --help');
});
program.parse();