vid-scaffold 1.0.0

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 ADDED
@@ -0,0 +1,133 @@
1
+ # 🎬 vid-scaffold
2
+
3
+ > Scaffold video editing project directory structures — interactively, cross-platform.
4
+
5
+ Works on **Windows**, **macOS**, and **Linux**.
6
+
7
+ ---
8
+
9
+ ## Usage
10
+
11
+ No install needed — just run:
12
+
13
+ ```bash
14
+ npx vid-scaffold
15
+ ```
16
+
17
+ Or install globally:
18
+
19
+ ```bash
20
+ npm install -g vid-scaffold
21
+ vid-scaffold
22
+ ```
23
+
24
+ ---
25
+
26
+ ## What it does
27
+
28
+ Launches an interactive CLI that asks you:
29
+
30
+ 1. **Software** — which NLE you use (sets the project file extension)
31
+ 2. **Project name** — the root folder to create
32
+ 3. **Template** — full, minimal, your saved preset, or customize
33
+ 4. **Customize mode** — pick folders, add your own, drill into nested ones
34
+ 5. **Save as preset** — optionally save your layout for next time
35
+
36
+ ### Supported software
37
+
38
+ | Software | Project file |
39
+ | --------------------- | ------------------------ |
40
+ | Kdenlive | `project.kdenlive` |
41
+ | DaVinci Resolve | `project.drp` |
42
+ | Adobe Premiere Pro | `project.prproj` |
43
+ | Final Cut Pro | `project.fcpbundle` |
44
+ | Shotcut | `project.mlt` |
45
+ | Vegas Pro | `project.veg` |
46
+ | Avid Media Composer | `project.avb` |
47
+ | CapCut / Other / none | _(no file created)_ |
48
+ | Custom | enter your own extension |
49
+
50
+ ### Default "full" structure
51
+
52
+ ```
53
+ my-video-project/
54
+ ├── 01_project/
55
+ │ └── project.kdenlive ← depends on your software choice
56
+ ├── 02_a-roll/
57
+ ├── 03_b-roll/
58
+ ├── 04_music/
59
+ ├── 05_sfx/
60
+ ├── 06_subtitles/
61
+ └── 07_exports/
62
+ ├── drafts/
63
+ ├── final/
64
+ └── shorts/
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Presets
70
+
71
+ Saved presets are stored at:
72
+
73
+ | Platform | Path |
74
+ | ------------- | ------------------------------------------ |
75
+ | macOS / Linux | `~/.vid-scaffold/presets.json` |
76
+ | Windows | `%USERPROFILE%\.vid-scaffold\presets.json` |
77
+
78
+ ---
79
+
80
+ ## Contributing / Development
81
+
82
+ ```bash
83
+ git clone https://github.com/your-username/vid-scaffold
84
+ cd vid-scaffold
85
+ npm install
86
+
87
+ # Compile TypeScript
88
+ npm run build
89
+
90
+ # Run locally
91
+ npm start
92
+
93
+ # Watch mode during development
94
+ npm run dev
95
+ ```
96
+
97
+ ### Project structure
98
+
99
+ ```
100
+ vid-scaffold/
101
+ ├── src-ts/ # TypeScript source
102
+ │ ├── types.ts # Shared interfaces (DirEntry, SoftwareChoice, …)
103
+ │ ├── structure.ts # Default & minimal templates
104
+ │ ├── software.ts # NLE software selection prompt
105
+ │ ├── customize.ts # Interactive folder picker (recursive)
106
+ │ ├── creator.ts # Disk writer + tree printer
107
+ │ ├── presets.ts # Save/load ~/.vid-scaffold/presets.json
108
+ │ └── index.ts # Main orchestrator
109
+ ├── bin-ts/
110
+ │ └── cli.ts # #!/usr/bin/env node entry point
111
+ ├── dist/ # Compiled output (generated — do not edit)
112
+ ├── tsconfig.json
113
+ └── package.json
114
+ ```
115
+
116
+ ### Publishing
117
+
118
+ ```bash
119
+ npm run build # compiles src-ts/ → dist/
120
+ npm publish # ships only the dist/ folder (see .npmignore)
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Requirements
126
+
127
+ - Node.js **18+**
128
+
129
+ ---
130
+
131
+ ## License
132
+
133
+ MIT
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../bin-ts/cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const index_js_1 = require("../src-ts/index.js");
5
+ (0, index_js_1.run)().catch((err) => {
6
+ if (err instanceof Error && err.name === 'ExitPromptError') {
7
+ console.log('\n Cancelled. See you next time! 👋');
8
+ process.exit(0);
9
+ }
10
+ console.error(err);
11
+ process.exit(1);
12
+ });
13
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin-ts/cli.ts"],"names":[],"mappings":";;;AACA,iDAAwC;AAExC,IAAA,cAAG,GAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACzB,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAA;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACnB,CAAC,CAAC,CAAA"}
@@ -0,0 +1,10 @@
1
+ import type { DirEntry } from './types.js';
2
+ /**
3
+ * Recursively create folders (and optional placeholder files) on disk.
4
+ */
5
+ export declare function createStructure(basePath: string, structure: DirEntry[]): Promise<void>;
6
+ /**
7
+ * Build an array of lines that look like `tree` command output.
8
+ */
9
+ export declare function buildTree(structure: DirEntry[], prefix?: string): string[];
10
+ //# sourceMappingURL=creator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"creator.d.ts","sourceRoot":"","sources":["../../src-ts/creator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1C;;GAEG;AACH,wBAAsB,eAAe,CACjC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,QAAQ,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,MAAM,SAAK,GAAG,MAAM,EAAE,CAoBtE"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createStructure = createStructure;
7
+ exports.buildTree = buildTree;
8
+ const path_1 = __importDefault(require("path"));
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ /**
11
+ * Recursively create folders (and optional placeholder files) on disk.
12
+ */
13
+ async function createStructure(basePath, structure) {
14
+ for (const entry of structure) {
15
+ const dirPath = path_1.default.join(basePath, entry.name);
16
+ await fs_extra_1.default.ensureDir(dirPath);
17
+ if (entry.placeholder) {
18
+ const filePath = path_1.default.join(dirPath, entry.placeholder);
19
+ if (!(await fs_extra_1.default.pathExists(filePath))) {
20
+ await fs_extra_1.default.createFile(filePath);
21
+ }
22
+ }
23
+ if (entry.children && entry.children.length > 0) {
24
+ await createStructure(dirPath, entry.children);
25
+ }
26
+ }
27
+ }
28
+ /**
29
+ * Build an array of lines that look like `tree` command output.
30
+ */
31
+ function buildTree(structure, prefix = '') {
32
+ const lines = [];
33
+ structure.forEach((entry, i) => {
34
+ const isLast = i === structure.length - 1;
35
+ const connector = isLast ? '└── ' : '├── ';
36
+ const childPrefix = isLast ? ' ' : '│ ';
37
+ lines.push(prefix + connector + entry.name + '/');
38
+ if (entry.placeholder) {
39
+ lines.push(prefix + childPrefix + '└── ' + entry.placeholder);
40
+ }
41
+ if (entry.children && entry.children.length > 0) {
42
+ lines.push(...buildTree(entry.children, prefix + childPrefix));
43
+ }
44
+ });
45
+ return lines;
46
+ }
47
+ //# sourceMappingURL=creator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"creator.js","sourceRoot":"","sources":["../../src-ts/creator.ts"],"names":[],"mappings":";;;;;AAOA,0CAmBC;AAKD,8BAoBC;AAnDD,gDAAuB;AACvB,wDAAyB;AAGzB;;GAEG;AACI,KAAK,UAAU,eAAe,CACjC,QAAgB,EAChB,SAAqB;IAErB,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QAC/C,MAAM,kBAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;QAE3B,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACpB,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,WAAW,CAAC,CAAA;YACtD,IAAI,CAAC,CAAC,MAAM,kBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;gBACnC,MAAM,kBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;YACjC,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;QAClD,CAAC;IACL,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,SAAqB,EAAE,MAAM,GAAG,EAAE;IACxD,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3B,MAAM,MAAM,GAAG,CAAC,KAAK,SAAS,CAAC,MAAM,GAAG,CAAC,CAAA;QACzC,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;QAC1C,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;QAE5C,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,CAAA;QAEjD,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,CAAA;QACjE,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAA;QAClE,CAAC;IACL,CAAC,CAAC,CAAA;IAEF,OAAO,KAAK,CAAA;AAChB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { DirEntry } from './types.js';
2
+ export declare function runCustomize(): Promise<DirEntry[]>;
3
+ //# sourceMappingURL=customize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customize.d.ts","sourceRoot":"","sources":["../../src-ts/customize.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AA2G1C,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAKxD"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runCustomize = runCustomize;
7
+ const prompts_1 = require("@inquirer/prompts");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const structure_js_1 = require("./structure.js");
10
+ const CREATE_CUSTOM_VALUE = '__CREATE_CUSTOM__';
11
+ /**
12
+ * Prompt the user to select and configure folders at one level of the tree.
13
+ *
14
+ * - "add custom folder" is always the first option
15
+ * - loop: false — no wrap-around at top/bottom
16
+ * - pageSize = full list — never scrolls
17
+ * - every selected folder (default or custom) gets an "add sub-folders?" offer
18
+ */
19
+ async function promptLevel(title, defaultEntries = [], breadcrumb = '') {
20
+ const choices = [
21
+ {
22
+ name: chalk_1.default.yellow('+ add custom folder'),
23
+ value: CREATE_CUSTOM_VALUE,
24
+ checked: false,
25
+ },
26
+ ...defaultEntries.map((e) => ({
27
+ name: e.name,
28
+ value: e.name,
29
+ checked: true,
30
+ })),
31
+ ];
32
+ if (breadcrumb) {
33
+ console.log(chalk_1.default.dim(`\n in: ${breadcrumb}`));
34
+ }
35
+ const selected = await (0, prompts_1.checkbox)({
36
+ message: title,
37
+ choices,
38
+ loop: false,
39
+ pageSize: choices.length + 1,
40
+ instructions: chalk_1.default.dim('space = toggle · a = all · i = invert · enter = confirm'),
41
+ });
42
+ // Gather custom folder names
43
+ const customNames = [];
44
+ if (selected.includes(CREATE_CUSTOM_VALUE)) {
45
+ let keepAdding = true;
46
+ while (keepAdding) {
47
+ const name = await (0, prompts_1.input)({
48
+ message: chalk_1.default.yellow(' Folder name:'),
49
+ validate: (v) => (v.trim() ? true : 'Name cannot be empty'),
50
+ });
51
+ customNames.push(name.trim());
52
+ keepAdding = await (0, prompts_1.confirm)({
53
+ message: chalk_1.default.dim(' Add another custom folder?'),
54
+ default: false,
55
+ });
56
+ }
57
+ }
58
+ // Build result: selected defaults in original order, then custom names
59
+ const result = [];
60
+ for (const val of selected) {
61
+ if (val === CREATE_CUSTOM_VALUE)
62
+ continue;
63
+ const original = defaultEntries.find((e) => e.name === val);
64
+ // Spread to avoid mutating the shared DEFAULT_STRUCTURE constant
65
+ result.push(original ? { ...original } : { name: val });
66
+ }
67
+ for (const name of customNames) {
68
+ result.push({ name });
69
+ }
70
+ // Ask about children for every selected folder
71
+ for (const entry of result) {
72
+ const defaultKids = Array.isArray(entry.children)
73
+ ? entry.children
74
+ : [];
75
+ const hasKids = defaultKids.length > 0;
76
+ const wantChildren = await (0, prompts_1.confirm)({
77
+ message: chalk_1.default.cyan(` ${entry.name}/`) +
78
+ chalk_1.default.dim(hasKids ? ' configure sub-folders?' : ' add sub-folders?'),
79
+ default: hasKids,
80
+ });
81
+ if (wantChildren) {
82
+ const crumb = (breadcrumb ? breadcrumb + entry.name : entry.name) + '/';
83
+ entry.children = await promptLevel(chalk_1.default.bold(` ${entry.name}/`) + chalk_1.default.dim(' — sub-folders'), defaultKids, crumb);
84
+ }
85
+ else {
86
+ delete entry.children;
87
+ }
88
+ }
89
+ return result;
90
+ }
91
+ async function runCustomize() {
92
+ return promptLevel(chalk_1.default.bold(' Choose top-level folders'), structure_js_1.DEFAULT_STRUCTURE);
93
+ }
94
+ //# sourceMappingURL=customize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customize.js","sourceRoot":"","sources":["../../src-ts/customize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function run(): Promise<void>;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src-ts/index.ts"],"names":[],"mappings":"AAwEA,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAqIzC"}
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.run = run;
7
+ const path_1 = __importDefault(require("path"));
8
+ const prompts_1 = require("@inquirer/prompts");
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ const structure_js_1 = require("./structure.js");
11
+ const customize_js_1 = require("./customize.js");
12
+ const creator_js_1 = require("./creator.js");
13
+ const presets_js_1 = require("./presets.js");
14
+ const software_js_1 = require("./software.js");
15
+ // ── Helpers ──────────────────────────────────────────────────────────────────
16
+ function printBanner() {
17
+ console.log('');
18
+ console.log(chalk_1.default.bold.hex('#00d4ff')(' ╔═══════════════════════════════╗'));
19
+ console.log(chalk_1.default.bold.hex('#00d4ff')(' ║') +
20
+ chalk_1.default.bold.white(' 🎬 vid-scaffold v1.0.0 ') +
21
+ chalk_1.default.bold.hex('#00d4ff')('║'));
22
+ console.log(chalk_1.default.bold.hex('#00d4ff')(' ╚═══════════════════════════════╝'));
23
+ console.log(chalk_1.default.dim(' Video editing project scaffold · cross-platform\n'));
24
+ }
25
+ function printTree(projectName, structure) {
26
+ console.log('');
27
+ console.log(chalk_1.default.bold(` ${projectName}/`));
28
+ (0, creator_js_1.buildTree)(structure).forEach((l) => console.log(chalk_1.default.dim(' ') + chalk_1.default.cyan(l)));
29
+ console.log('');
30
+ }
31
+ /**
32
+ * Inject the chosen software's project file extension into the structure.
33
+ * Targets the first folder whose name contains "project", or falls back to
34
+ * the very first folder if none match.
35
+ */
36
+ function applyPlaceholder(structure, software) {
37
+ return structure.map((entry, i) => {
38
+ const e = { ...entry };
39
+ const isProjectFolder = 'placeholder' in e ||
40
+ e.name.toLowerCase().includes('project') ||
41
+ i === 0;
42
+ if (isProjectFolder) {
43
+ if (software.ext) {
44
+ e.placeholder = `project${software.ext}`;
45
+ }
46
+ else {
47
+ delete e.placeholder;
48
+ }
49
+ }
50
+ return e;
51
+ });
52
+ }
53
+ // ── Main ──────────────────────────────────────────────────────────────────────
54
+ async function run() {
55
+ printBanner();
56
+ // 1. Software
57
+ const software = await (0, software_js_1.promptSoftware)();
58
+ // 2. Project name
59
+ const projectName = await (0, prompts_1.input)({
60
+ message: chalk_1.default.bold(' Project name:'),
61
+ default: 'my-video-project',
62
+ validate: (v) => {
63
+ if (!v.trim())
64
+ return 'Project name cannot be empty';
65
+ if (/[<>:"/\\|?*]/.test(v))
66
+ return 'Name contains invalid characters';
67
+ return true;
68
+ },
69
+ });
70
+ // 3. Load presets + build template choices
71
+ const userPresets = await (0, presets_js_1.loadPresets)();
72
+ const presetNames = Object.keys(userPresets);
73
+ const modeChoices = [
74
+ {
75
+ name: chalk_1.default.white('full') +
76
+ chalk_1.default.dim(' — all standard directories'),
77
+ value: 'full',
78
+ },
79
+ {
80
+ name: chalk_1.default.white('minimal') +
81
+ chalk_1.default.dim(' — bare-bones, 3 folders'),
82
+ value: 'minimal',
83
+ },
84
+ ...presetNames.map((p) => ({
85
+ name: chalk_1.default.green(p) + chalk_1.default.dim(' (saved preset)'),
86
+ value: `preset:${p}`,
87
+ })),
88
+ {
89
+ name: chalk_1.default.yellow('customize') +
90
+ chalk_1.default.dim(' — pick exactly what you want'),
91
+ value: 'customize',
92
+ },
93
+ ];
94
+ // 4. Pick template
95
+ const mode = await (0, prompts_1.select)({
96
+ message: chalk_1.default.bold(' Choose a template:'),
97
+ choices: modeChoices,
98
+ loop: false,
99
+ pageSize: modeChoices.length,
100
+ });
101
+ let structure;
102
+ if (mode === 'full') {
103
+ structure = structuredClone(structure_js_1.DEFAULT_STRUCTURE);
104
+ }
105
+ else if (mode === 'minimal') {
106
+ structure = structuredClone(structure_js_1.MINIMAL_STRUCTURE);
107
+ }
108
+ else if (mode.startsWith('preset:')) {
109
+ structure = structuredClone(userPresets[mode.slice(7)]);
110
+ }
111
+ else {
112
+ structure = await (0, customize_js_1.runCustomize)();
113
+ }
114
+ structure = applyPlaceholder(structure, software);
115
+ // 5. Preview + confirm
116
+ printTree(projectName, structure);
117
+ const ok = await (0, prompts_1.confirm)({
118
+ message: chalk_1.default.bold(' Create this structure?'),
119
+ default: true,
120
+ });
121
+ if (!ok) {
122
+ console.log(chalk_1.default.dim('\n Aborted. Nothing was created.\n'));
123
+ return;
124
+ }
125
+ // 6. Create on disk
126
+ const targetPath = path_1.default.resolve(process.cwd(), projectName);
127
+ await (0, creator_js_1.createStructure)(targetPath, structure);
128
+ console.log('');
129
+ console.log(chalk_1.default.bold.green(' ✓ Project created: ') + chalk_1.default.white(targetPath));
130
+ if (software.ext) {
131
+ console.log(chalk_1.default.dim(' ✓ Project file: ') +
132
+ chalk_1.default.white(`project${software.ext}`) +
133
+ chalk_1.default.dim(' inside 01_project/'));
134
+ }
135
+ // 7. Offer to save preset (customize only)
136
+ if (mode === 'customize') {
137
+ console.log('');
138
+ const wantSave = await (0, prompts_1.confirm)({
139
+ message: chalk_1.default.bold(' Save this layout as a global preset?'),
140
+ default: false,
141
+ });
142
+ if (wantSave) {
143
+ const presetName = await (0, prompts_1.input)({
144
+ message: chalk_1.default.bold(' Preset name:'),
145
+ default: 'my-preset',
146
+ validate: (v) => {
147
+ if (!v.trim())
148
+ return 'Preset name cannot be empty';
149
+ if (presetNames.includes(v.trim()))
150
+ return `"${v.trim()}" already exists. Choose a different name.`;
151
+ return true;
152
+ },
153
+ });
154
+ await (0, presets_js_1.savePreset)(presetName.trim(), structure);
155
+ console.log(chalk_1.default.green(`\n ✓ Preset "${presetName.trim()}" saved!`) +
156
+ chalk_1.default.dim(" It'll appear next time you run vid-scaffold."));
157
+ }
158
+ }
159
+ console.log('');
160
+ console.log(chalk_1.default.dim(' Happy editing! 🎞️\n'));
161
+ }
162
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src-ts/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { DirEntry, PresetsFile } from './types.js';
2
+ export declare const CONFIG_DIR: string;
3
+ export declare function loadPresets(): Promise<PresetsFile>;
4
+ export declare function savePreset(name: string, structure: DirEntry[]): Promise<void>;
5
+ export declare function deletePreset(name: string): Promise<void>;
6
+ //# sourceMappingURL=presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src-ts/presets.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAEvD,eAAO,MAAM,UAAU,QAA2C,CAAA;AAGlE,wBAAsB,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CAWxD;AAED,wBAAsB,UAAU,CAC5B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,QAAQ,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9D"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CONFIG_DIR = void 0;
7
+ exports.loadPresets = loadPresets;
8
+ exports.savePreset = savePreset;
9
+ exports.deletePreset = deletePreset;
10
+ const fs_extra_1 = __importDefault(require("fs-extra"));
11
+ const path_1 = __importDefault(require("path"));
12
+ const os_1 = __importDefault(require("os"));
13
+ exports.CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.vid-scaffold');
14
+ const PRESETS_FILE = path_1.default.join(exports.CONFIG_DIR, 'presets.json');
15
+ async function loadPresets() {
16
+ try {
17
+ await fs_extra_1.default.ensureDir(exports.CONFIG_DIR);
18
+ if (await fs_extra_1.default.pathExists(PRESETS_FILE)) {
19
+ return (await fs_extra_1.default.readJson(PRESETS_FILE));
20
+ }
21
+ }
22
+ catch {
23
+ // Corrupted or missing file — return empty
24
+ }
25
+ return {};
26
+ }
27
+ async function savePreset(name, structure) {
28
+ await fs_extra_1.default.ensureDir(exports.CONFIG_DIR);
29
+ const presets = await loadPresets();
30
+ presets[name] = structure;
31
+ await fs_extra_1.default.writeJson(PRESETS_FILE, presets, { spaces: 2 });
32
+ }
33
+ async function deletePreset(name) {
34
+ const presets = await loadPresets();
35
+ delete presets[name];
36
+ await fs_extra_1.default.writeJson(PRESETS_FILE, presets, { spaces: 2 });
37
+ }
38
+ //# sourceMappingURL=presets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.js","sourceRoot":"","sources":["../../src-ts/presets.ts"],"names":[],"mappings":";;;;;;AAQA,kCAWC;AAED,gCAQC;AAED,oCAIC;AAnCD,wDAAyB;AACzB,gDAAuB;AACvB,4CAAmB;AAGN,QAAA,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAA;AAClE,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,kBAAU,EAAE,cAAc,CAAC,CAAA;AAEnD,KAAK,UAAU,WAAW;IAC7B,IAAI,CAAC;QACD,MAAM,kBAAE,CAAC,SAAS,CAAC,kBAAU,CAAC,CAAA;QAC9B,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,MAAM,kBAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAgB,CAAA;QAC3D,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,2CAA2C;IAC/C,CAAC;IAED,OAAO,EAAE,CAAA;AACb,CAAC;AAEM,KAAK,UAAU,UAAU,CAC5B,IAAY,EACZ,SAAqB;IAErB,MAAM,kBAAE,CAAC,SAAS,CAAC,kBAAU,CAAC,CAAA;IAC9B,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAA;IACnC,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,CAAA;IACzB,MAAM,kBAAE,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAA;AAC5D,CAAC;AAEM,KAAK,UAAU,YAAY,CAAC,IAAY;IAC3C,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAA;IACnC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAA;IACpB,MAAM,kBAAE,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAA;AAC5D,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { SoftwareChoice } from './types.js';
2
+ export declare function promptSoftware(): Promise<SoftwareChoice>;
3
+ //# sourceMappingURL=software.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"software.d.ts","sourceRoot":"","sources":["../../src-ts/software.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAqBhD,wBAAsB,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,CAuC9D"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.promptSoftware = promptSoftware;
7
+ const prompts_1 = require("@inquirer/prompts");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const SOFTWARE_LIST = [
10
+ { name: 'Kdenlive', ext: '.kdenlive' },
11
+ { name: 'DaVinci Resolve', ext: '.drp' },
12
+ { name: 'Adobe Premiere Pro', ext: '.prproj' },
13
+ { name: 'Final Cut Pro', ext: '.fcpbundle' },
14
+ { name: 'CapCut', ext: null },
15
+ { name: 'Shotcut', ext: '.mlt' },
16
+ { name: 'Vegas Pro', ext: '.veg' },
17
+ { name: 'Avid Media Composer', ext: '.avb' },
18
+ { name: 'Other / none', ext: null },
19
+ ];
20
+ const CUSTOM_VALUE = '__CUSTOM__';
21
+ async function promptSoftware() {
22
+ const choices = [
23
+ ...SOFTWARE_LIST.map((s) => ({
24
+ name: chalk_1.default.white(s.name) +
25
+ (s.ext
26
+ ? chalk_1.default.dim(` ${s.ext}`)
27
+ : chalk_1.default.dim(' no project file')),
28
+ value: s.name,
29
+ })),
30
+ {
31
+ name: chalk_1.default.italic.dim('+ other (enter extension manually)'),
32
+ value: CUSTOM_VALUE,
33
+ },
34
+ ];
35
+ const picked = await (0, prompts_1.select)({
36
+ message: chalk_1.default.bold(' Which editing software do you use?'),
37
+ choices,
38
+ loop: false,
39
+ pageSize: choices.length,
40
+ });
41
+ if (picked === CUSTOM_VALUE) {
42
+ const raw = await (0, prompts_1.input)({
43
+ message: chalk_1.default.yellow(' Project file extension') +
44
+ chalk_1.default.dim(' (e.g. .myapp — leave blank for none):'),
45
+ });
46
+ const trimmed = raw.trim() || null;
47
+ const ext = trimmed && !trimmed.startsWith('.') ? '.' + trimmed : trimmed;
48
+ return { label: 'Custom', ext };
49
+ }
50
+ const found = SOFTWARE_LIST.find((s) => s.name === picked);
51
+ return { label: picked, ext: found.ext };
52
+ }
53
+ //# sourceMappingURL=software.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"software.js","sourceRoot":"","sources":["../../src-ts/software.ts"],"names":[],"mappings":";;;;;AAuBA,wCAuCC;AA9DD,+CAAiD;AACjD,kDAAyB;AAQzB,MAAM,aAAa,GAAoB;IACnC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE;IACtC,EAAE,IAAI,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,EAAE;IACxC,EAAE,IAAI,EAAE,oBAAoB,EAAE,GAAG,EAAE,SAAS,EAAE;IAC9C,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,EAAE;IAC5C,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE;IAC7B,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE;IAChC,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE;IAClC,EAAE,IAAI,EAAE,qBAAqB,EAAE,GAAG,EAAE,MAAM,EAAE;IAC5C,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,IAAI,EAAE;CACtC,CAAA;AAED,MAAM,YAAY,GAAG,YAAY,CAAA;AAE1B,KAAK,UAAU,cAAc;IAChC,MAAM,OAAO,GAAG;QACZ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACzB,IAAI,EACA,eAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;gBACnB,CAAC,CAAC,CAAC,GAAG;oBACF,CAAC,CAAC,eAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC;oBACzB,CAAC,CAAC,eAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;YACzC,KAAK,EAAE,CAAC,CAAC,IAAI;SAChB,CAAC,CAAC;QACH;YACI,IAAI,EAAE,eAAK,CAAC,MAAM,CAAC,GAAG,CAAC,oCAAoC,CAAC;YAC5D,KAAK,EAAE,YAAY;SACtB;KACJ,CAAA;IAED,MAAM,MAAM,GAAG,MAAM,IAAA,gBAAM,EAAC;QACxB,OAAO,EAAE,eAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC;QAC3D,OAAO;QACP,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,OAAO,CAAC,MAAM;KAC3B,CAAC,CAAA;IAEF,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,MAAM,IAAA,eAAK,EAAC;YACpB,OAAO,EACH,eAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC;gBACxC,eAAK,CAAC,GAAG,CAAC,wCAAwC,CAAC;SAC1D,CAAC,CAAA;QACF,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,CAAA;QAClC,MAAM,GAAG,GACL,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAA;QAEjE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAA;IACnC,CAAC;IAED,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAE,CAAA;IAE3D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAA;AAC5C,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { DirEntry } from './types.js';
2
+ /**
3
+ * Default "full" structure for a video editing project.
4
+ * `placeholder` is null here — it gets filled at runtime based on
5
+ * the user's chosen software (see applyPlaceholder in index.ts).
6
+ */
7
+ export declare const DEFAULT_STRUCTURE: DirEntry[];
8
+ /** Bare-bones three-folder template. */
9
+ export declare const MINIMAL_STRUCTURE: DirEntry[];
10
+ //# sourceMappingURL=structure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structure.d.ts","sourceRoot":"","sources":["../../src-ts/structure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1C;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,QAAQ,EAWvC,CAAA;AAED,wCAAwC;AACxC,eAAO,MAAM,iBAAiB,EAAE,QAAQ,EAIvC,CAAA"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MINIMAL_STRUCTURE = exports.DEFAULT_STRUCTURE = void 0;
4
+ /**
5
+ * Default "full" structure for a video editing project.
6
+ * `placeholder` is null here — it gets filled at runtime based on
7
+ * the user's chosen software (see applyPlaceholder in index.ts).
8
+ */
9
+ exports.DEFAULT_STRUCTURE = [
10
+ { name: '01_project', children: [], placeholder: null },
11
+ { name: '02_a-roll' },
12
+ { name: '03_b-roll' },
13
+ { name: '04_music' },
14
+ { name: '05_sfx' },
15
+ { name: '06_subtitles' },
16
+ {
17
+ name: '07_exports',
18
+ children: [{ name: 'drafts' }, { name: 'final' }, { name: 'shorts' }],
19
+ },
20
+ ];
21
+ /** Bare-bones three-folder template. */
22
+ exports.MINIMAL_STRUCTURE = [
23
+ { name: '01_project', placeholder: null },
24
+ { name: '02_footage' },
25
+ { name: '03_exports', children: [{ name: 'final' }] },
26
+ ];
27
+ //# sourceMappingURL=structure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structure.js","sourceRoot":"","sources":["../../src-ts/structure.ts"],"names":[],"mappings":";;;AAEA;;;;GAIG;AACU,QAAA,iBAAiB,GAAe;IACzC,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE;IACvD,EAAE,IAAI,EAAE,WAAW,EAAE;IACrB,EAAE,IAAI,EAAE,WAAW,EAAE;IACrB,EAAE,IAAI,EAAE,UAAU,EAAE;IACpB,EAAE,IAAI,EAAE,QAAQ,EAAE;IAClB,EAAE,IAAI,EAAE,cAAc,EAAE;IACxB;QACI,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;KACxE;CACJ,CAAA;AAED,wCAAwC;AAC3B,QAAA,iBAAiB,GAAe;IACzC,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE;IACzC,EAAE,IAAI,EAAE,YAAY,EAAE;IACtB,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE;CACxD,CAAA"}
@@ -0,0 +1,17 @@
1
+ /** A single node in the project directory tree. */
2
+ export interface DirEntry {
3
+ /** Folder name (e.g. "01_project") */
4
+ name: string;
5
+ /** Optional file to create inside this folder (e.g. "project.kdenlive") */
6
+ placeholder?: string | null;
7
+ /** Optional sub-directories */
8
+ children?: DirEntry[];
9
+ }
10
+ /** A resolved NLE software choice */
11
+ export interface SoftwareChoice {
12
+ label: string;
13
+ ext: string | null;
14
+ }
15
+ /** User presets stored in ~/.vid-scaffold/presets.json */
16
+ export type PresetsFile = Record<string, DirEntry[]>;
17
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src-ts/types.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,MAAM,WAAW,QAAQ;IACrB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAA;CACxB;AAED,qCAAqC;AACrC,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,0DAA0D;AAC1D,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src-ts/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "vid-scaffold",
3
+ "version": "1.0.0",
4
+ "description": "Scaffold video editing project directory structures interactively",
5
+ "bin": {
6
+ "vid-scaffold": "./dist/bin-ts/cli.js"
7
+ },
8
+ "main": "./dist/src-ts/index.js",
9
+ "types": "./dist/src-ts/index.d.ts",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "dev": "tsc --watch",
16
+ "start": "node dist/bin-ts/cli.js",
17
+ "prepublishOnly": "npm run build",
18
+ "pretty": "prettier --write \"./**/*.{js,jsx,mjs,cjs,ts,tsx,json}\""
19
+ },
20
+ "keywords": [
21
+ "video",
22
+ "editing",
23
+ "scaffold",
24
+ "kdenlive",
25
+ "davinci",
26
+ "premiere",
27
+ "project",
28
+ "structure",
29
+ "cli"
30
+ ],
31
+ "author": "",
32
+ "license": "MIT",
33
+ "engines": {
34
+ "node": ">=18.0.0"
35
+ },
36
+ "dependencies": {
37
+ "@inquirer/prompts": "^7.5.2",
38
+ "chalk": "^4.1.2",
39
+ "fs-extra": "^11.3.0"
40
+ },
41
+ "devDependencies": {
42
+ "@types/fs-extra": "^11.0.4",
43
+ "@types/node": "^22.0.0",
44
+ "prettier": "^3.8.3",
45
+ "typescript": "^6.0.3"
46
+ }
47
+ }