videonut 1.1.0 โ 1.2.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/CONTRIBUTING.md +54 -0
- package/README.md +152 -145
- package/package.json +6 -1
- package/setup.js +300 -0
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Contributing to VideoNut
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to VideoNut! ๐ฌ
|
|
4
|
+
|
|
5
|
+
## How to Contribute
|
|
6
|
+
|
|
7
|
+
### 1. Fork & Clone
|
|
8
|
+
```bash
|
|
9
|
+
git clone https://github.com/YOUR-USERNAME/videonut.git
|
|
10
|
+
cd videonut
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### 2. Create a Branch
|
|
14
|
+
```bash
|
|
15
|
+
git checkout -b feature/your-feature-name
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### 3. Make Changes
|
|
19
|
+
- Follow existing code style
|
|
20
|
+
- Update documentation if needed
|
|
21
|
+
- Test your changes
|
|
22
|
+
|
|
23
|
+
### 4. Submit PR
|
|
24
|
+
```bash
|
|
25
|
+
git push origin feature/your-feature-name
|
|
26
|
+
```
|
|
27
|
+
Then open a Pull Request on GitHub.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Areas We Need Help
|
|
32
|
+
|
|
33
|
+
| Area | Description | Skills Needed |
|
|
34
|
+
|------|-------------|---------------|
|
|
35
|
+
| ๐ **Translations** | Translate agents to other languages | Any language |
|
|
36
|
+
| ๐จ **Web Dashboard** | Create UI for non-CLI users | React, Vue, HTML |
|
|
37
|
+
| ๐ **Integrations** | Connect with video editors | Python, APIs |
|
|
38
|
+
| ๐ **Analytics** | Usage tracking & reporting | Python, data |
|
|
39
|
+
| ๐งช **Testing** | Write tests for agents | Python, Jest |
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Code of Conduct
|
|
44
|
+
|
|
45
|
+
Be respectful, inclusive, and constructive. We're all here to build something cool.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Questions?
|
|
50
|
+
|
|
51
|
+
- Open an [Issue](https://github.com/konda-vamshi-krishna/videonut/issues)
|
|
52
|
+
- Email: vamshikrishna131437@gmail.com
|
|
53
|
+
|
|
54
|
+
Thank you! โญ
|
package/README.md
CHANGED
|
@@ -1,140 +1,165 @@
|
|
|
1
1
|
# ๐ฌ VideoNut
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
<div align="center">
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+

|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
### ๐ Create Professional YouTube Documentaries with AI Agents
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/videonut)
|
|
10
|
+
[](https://github.com/konda-vamshi-krishna/videonut)
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
[](https://nodejs.org)
|
|
13
|
+
|
|
14
|
+
**10 Specialized AI Agents** | **Multi-CLI Support** | **Zero Manual Research** | **Production-Ready Assets**
|
|
15
|
+
|
|
16
|
+
[๐ฆ Install](#-quick-install) โข [๐ฏ Quick Start](#-quick-start) โข [๐ค Agents](#-meet-the-agents) โข [๐ Docs](#-documentation) โข [๐ค Contribute](#-contributing)
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## โก One Command Setup
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx videonut init
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
> **That's it!** This automatically installs Python, FFmpeg, Gemini CLI, and all dependencies.
|
|
13
29
|
|
|
14
30
|
---
|
|
15
31
|
|
|
16
|
-
##
|
|
32
|
+
## ๐ฏ What is VideoNut?
|
|
17
33
|
|
|
18
|
-
VideoNut
|
|
34
|
+
VideoNut transforms your ideas into **production-ready YouTube documentaries** using 10 specialized AI agents:
|
|
19
35
|
|
|
20
36
|
```
|
|
21
|
-
๐ก Topic Scout โ ๐ฏ Prompt โ ๐ต๏ธ Investigator โ โ๏ธ Scriptwriter โ ๐ฌ Director
|
|
37
|
+
๐ก Topic Scout โ ๐ฏ Prompt โ ๐ต๏ธ Investigator โ โ๏ธ Scriptwriter โ ๐ฌ Director
|
|
38
|
+
โ
|
|
39
|
+
๐ฆ
Scavenger โ ๐พ Archivist โ ๐ง EIC โ ๐จ Thumbnail โ ๐ SEO
|
|
22
40
|
```
|
|
23
41
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
42
|
+
### What You Get:
|
|
43
|
+
| Output | Description |
|
|
44
|
+
|--------|-------------|
|
|
45
|
+
| ๐ **Research Dossier** | Fully sourced facts with YouTube video timestamps |
|
|
46
|
+
| โ๏ธ **Complete Script** | Word-count matched narration for your target duration |
|
|
47
|
+
| ๐ฌ **Visual Direction** | Shot-by-shot guide with asset links |
|
|
48
|
+
| ๐ฆ **Downloaded Assets** | Video clips, screenshots, PDFs ready for editing |
|
|
49
|
+
| ๐จ **Thumbnail Prompts** | AI image generation prompts for click-worthy thumbnails |
|
|
50
|
+
| ๐ **SEO Package** | Optimized titles, descriptions, tags for YouTube |
|
|
29
51
|
|
|
30
52
|
---
|
|
31
53
|
|
|
32
|
-
## ๐ฆ
|
|
54
|
+
## ๐ฆ Quick Install
|
|
33
55
|
|
|
34
|
-
###
|
|
35
|
-
|
|
36
|
-
npx videonut init
|
|
37
|
-
```
|
|
56
|
+
### Prerequisites
|
|
57
|
+
- **Node.js 16+** - [Download here](https://nodejs.org)
|
|
38
58
|
|
|
39
|
-
### Option
|
|
59
|
+
### Option 1: NPX (Recommended)
|
|
40
60
|
```bash
|
|
41
|
-
|
|
42
|
-
|
|
61
|
+
mkdir my-documentary
|
|
62
|
+
cd my-documentary
|
|
63
|
+
npx videonut init
|
|
43
64
|
```
|
|
44
65
|
|
|
45
|
-
### Option
|
|
66
|
+
### Option 2: Clone from GitHub
|
|
46
67
|
```bash
|
|
47
|
-
git clone https://github.com/
|
|
68
|
+
git clone https://github.com/konda-vamshi-krishna/videonut.git
|
|
48
69
|
cd videonut
|
|
49
|
-
npm
|
|
70
|
+
npm run setup
|
|
50
71
|
```
|
|
51
72
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
## ๐ ๏ธ Requirements
|
|
73
|
+
Both methods automatically install:
|
|
74
|
+
- โ
Python (if not installed)
|
|
55
75
|
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
|
|
59
|
-
- [Qwen CLI](https://github.com/QwenLM/qwen-cli)
|
|
60
|
-
- [Claude Code](https://claude.ai/code)
|
|
76
|
+
- โ
FFmpeg & FFprobe
|
|
77
|
+
- โ
Gemini CLI (or your choice)
|
|
78
|
+
- โ
All Python dependencies
|
|
61
79
|
|
|
62
80
|
---
|
|
63
81
|
|
|
64
|
-
##
|
|
82
|
+
## ๐ Quick Start
|
|
83
|
+
|
|
84
|
+
After installation, open your AI CLI and run:
|
|
65
85
|
|
|
66
|
-
### 1. Start with Topic Scout
|
|
67
86
|
```bash
|
|
68
|
-
#
|
|
87
|
+
# Start with Gemini CLI
|
|
88
|
+
gemini
|
|
89
|
+
|
|
90
|
+
# Then run your first agent
|
|
69
91
|
/topic_scout
|
|
70
|
-
# or
|
|
71
|
-
/scout
|
|
72
92
|
```
|
|
73
93
|
|
|
74
|
-
###
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
|
79
|
-
|
|
|
80
|
-
|
|
|
81
|
-
|
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
94
|
+
### Agent Pipeline
|
|
95
|
+
|
|
96
|
+
| # | Agent | Command | What It Does |
|
|
97
|
+
|---|-------|---------|--------------|
|
|
98
|
+
| 1 | ๐ก **Topic Scout** | `/topic_scout` | Find trending topics, create project |
|
|
99
|
+
| 2 | ๐ฏ **Prompt** | `/prompt` | Generate research questions |
|
|
100
|
+
| 3 | ๐ต๏ธ **Investigator** | `/investigator` | Deep research with sources |
|
|
101
|
+
| 4 | โ๏ธ **Scriptwriter** | `/scriptwriter` | Write narration script |
|
|
102
|
+
| 5 | ๐ฌ **Director** | `/director` | Create visual directions |
|
|
103
|
+
| 6 | ๐ฆ
**Scavenger** | `/scavenger` | Find and verify assets |
|
|
104
|
+
| 7 | ๐พ **Archivist** | `/archivist` | Download all assets |
|
|
105
|
+
| 8 | ๐ง **EIC** | `/eic` | Final quality review |
|
|
106
|
+
| 9 | ๐จ **Thumbnail** | `/thumbnail` | Generate thumbnail prompts |
|
|
107
|
+
| 10 | ๐ **SEO** | `/seo` | YouTube optimization |
|
|
87
108
|
|
|
88
109
|
---
|
|
89
110
|
|
|
90
111
|
## ๐ค Meet the Agents
|
|
91
112
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
|
96
|
-
|
|
97
|
-
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
|
109
|
-
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
<details>
|
|
114
|
+
<summary><b>๐ก Research Team</b></summary>
|
|
115
|
+
|
|
116
|
+
| Agent | Persona | What They Do |
|
|
117
|
+
|-------|---------|--------------|
|
|
118
|
+
| **Scout** | Trend Hunter | Finds viral topics, checks YouTube competition |
|
|
119
|
+
| **Prompt** | Research Architect | Creates focused research questions |
|
|
120
|
+
| **Sherlock** | Investigator | Deep research with YouTube video timestamps |
|
|
121
|
+
|
|
122
|
+
</details>
|
|
123
|
+
|
|
124
|
+
<details>
|
|
125
|
+
<summary><b>๐ฌ Creative Team</b></summary>
|
|
126
|
+
|
|
127
|
+
| Agent | Persona | What They Do |
|
|
128
|
+
|-------|---------|--------------|
|
|
129
|
+
| **Sorkin** | Scriptwriter | Word-count matched scripts with hooks |
|
|
130
|
+
| **Spielberg** | Director | Visual directions with source links |
|
|
131
|
+
| **Canvas** | Thumbnail Designer | Click-worthy thumbnail AI prompts |
|
|
132
|
+
| **Ranker** | SEO Expert | YouTube-optimized metadata |
|
|
133
|
+
|
|
134
|
+
</details>
|
|
135
|
+
|
|
136
|
+
<details>
|
|
137
|
+
<summary><b>๐ง Technical Team</b></summary>
|
|
138
|
+
|
|
139
|
+
| Agent | Persona | What They Do |
|
|
140
|
+
|-------|---------|--------------|
|
|
141
|
+
| **Hunter** | Scavenger | URL verification, timestamp extraction |
|
|
142
|
+
| **Vault** | Archivist | Downloads clips, screenshots, transcripts |
|
|
143
|
+
| **Chief** | Editor-in-Chief | 10-phase deep audit, catches every mistake |
|
|
144
|
+
|
|
145
|
+
</details>
|
|
117
146
|
|
|
118
147
|
---
|
|
119
148
|
|
|
120
|
-
## ๐
|
|
149
|
+
## ๐ Output Structure
|
|
121
150
|
|
|
122
151
|
```
|
|
123
|
-
|
|
124
|
-
โโโ topic_brief.md
|
|
125
|
-
โโโ
|
|
126
|
-
โโโ
|
|
127
|
-
โโโ
|
|
128
|
-
โโโ
|
|
129
|
-
โโโ
|
|
130
|
-
โโโ
|
|
131
|
-
โโโ asset_manifest.md # All assets with URLs
|
|
132
|
-
โโโ assets/ # Downloaded files
|
|
133
|
-
โ โโโ 001_intro.mp4
|
|
152
|
+
my-documentary/
|
|
153
|
+
โโโ ๐ topic_brief.md # Topic and angle
|
|
154
|
+
โโโ ๐ truth_dossier.md # Research with sources
|
|
155
|
+
โโโ โ๏ธ voice_script.md # Narration script
|
|
156
|
+
โโโ ๐ฌ master_script.md # Script + Visuals
|
|
157
|
+
โโโ ๐ฆ asset_manifest.md # All asset URLs
|
|
158
|
+
โโโ ๐ assets/ # Downloaded files
|
|
159
|
+
โ โโโ 001_clip.mp4
|
|
134
160
|
โ โโโ 002_chart.png
|
|
135
161
|
โ โโโ ...
|
|
136
|
-
|
|
137
|
-
โโโ review_report.md # Final review
|
|
162
|
+
โโโ โ
review_report.md # Final review
|
|
138
163
|
```
|
|
139
164
|
|
|
140
165
|
---
|
|
@@ -144,88 +169,70 @@ your-project/
|
|
|
144
169
|
Edit `config.yaml` to customize:
|
|
145
170
|
|
|
146
171
|
```yaml
|
|
147
|
-
# Video Production Settings
|
|
148
172
|
target_duration: 30 # Minutes
|
|
149
173
|
video_format: "investigative" # investigative, explainer, documentary
|
|
150
|
-
|
|
151
|
-
# Localization
|
|
152
174
|
audio_language: "English"
|
|
153
|
-
scope: "national" # international, national, regional
|
|
154
175
|
country: "India"
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
# Focus
|
|
158
|
-
industry_tag: "political" # political, finance, crime, tech, etc.
|
|
176
|
+
industry_tag: "political" # political, finance, crime, tech
|
|
159
177
|
```
|
|
160
178
|
|
|
161
179
|
---
|
|
162
180
|
|
|
163
|
-
## ๐
|
|
181
|
+
## ๐ Why VideoNut?
|
|
164
182
|
|
|
165
|
-
|
|
166
|
-
|
|
183
|
+
| Feature | VideoNut | Manual Process |
|
|
184
|
+
|---------|----------|----------------|
|
|
185
|
+
| Research Time | ~30 mins | 8+ hours |
|
|
186
|
+
| Script Writing | Auto-generated | Manual |
|
|
187
|
+
| Asset Finding | Verified URLs | Hunt & Hope |
|
|
188
|
+
| Downloads | One-click | Individual |
|
|
189
|
+
| Quality Check | 10-phase audit | Self-review |
|
|
167
190
|
|
|
168
|
-
|
|
169
|
-
Automatically extracts timestamps from YouTube videos using caption analysis.
|
|
191
|
+
---
|
|
170
192
|
|
|
171
|
-
|
|
172
|
-
- Downloads only the relevant 30-second clips, not full videos
|
|
173
|
-
- Screenshots articles with highlighted quotes
|
|
174
|
-
- PDF page extraction with keyword search
|
|
193
|
+
## ๐ค Contributing
|
|
175
194
|
|
|
176
|
-
|
|
177
|
-
EIC agent performs 10-phase deep audit:
|
|
178
|
-
- URL verification
|
|
179
|
-
- Timestamp validation
|
|
180
|
-
- Cross-reference checks
|
|
181
|
-
- Word count compliance
|
|
195
|
+
We welcome contributions! Check out our [Contributing Guide](CONTRIBUTING.md).
|
|
182
196
|
|
|
183
|
-
###
|
|
184
|
-
|
|
197
|
+
### Areas We Need Help:
|
|
198
|
+
- ๐ **Translations** - Agents in other languages
|
|
199
|
+
- ๐จ **UI Dashboard** - Web interface for non-CLI users
|
|
200
|
+
- ๐ **Integrations** - Video editing software plugins
|
|
201
|
+
- ๐ **Analytics** - Usage tracking and reporting
|
|
185
202
|
|
|
186
203
|
---
|
|
187
204
|
|
|
188
|
-
##
|
|
189
|
-
|
|
190
|
-
We welcome contributions! Here's how:
|
|
191
|
-
|
|
192
|
-
1. Fork the repository
|
|
193
|
-
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
194
|
-
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
195
|
-
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
196
|
-
5. Open a Pull Request
|
|
205
|
+
## ๐ Documentation
|
|
197
206
|
|
|
198
|
-
|
|
199
|
-
-
|
|
200
|
-
-
|
|
201
|
-
- ๐ Integration with video editing software
|
|
202
|
-
- ๐ Analytics and reporting
|
|
207
|
+
- [๐ User Guide](USER_GUIDE.md)
|
|
208
|
+
- [๐ Agent Lifecycle](docs/LIFECYCLE.md)
|
|
209
|
+
- [๐ Audit Report](docs/AUDIT_REPORT.md)
|
|
203
210
|
|
|
204
211
|
---
|
|
205
212
|
|
|
206
213
|
## ๐ License
|
|
207
214
|
|
|
208
|
-
MIT License -
|
|
215
|
+
MIT License - Free for personal and commercial use.
|
|
209
216
|
|
|
210
217
|
---
|
|
211
218
|
|
|
212
|
-
##
|
|
219
|
+
## ๐จโ๐ป Author
|
|
213
220
|
|
|
214
|
-
|
|
215
|
-
- Email: vamshikrishna131437@gmail.com
|
|
216
|
-
- GitHub: [@vamshikrishna131437](https://github.com/vamshikrishna131437)
|
|
221
|
+
<div align="center">
|
|
217
222
|
|
|
218
|
-
|
|
223
|
+
**Vamshi Krishna Konda**
|
|
219
224
|
|
|
220
|
-
|
|
225
|
+
[](https://github.com/konda-vamshi-krishna)
|
|
226
|
+
[](mailto:vamshikrishna131437@gmail.com)
|
|
221
227
|
|
|
222
|
-
|
|
223
|
-
- Google Gemini CLI team
|
|
224
|
-
- Qwen team
|
|
225
|
-
- Anthropic Claude team
|
|
228
|
+
</div>
|
|
226
229
|
|
|
227
230
|
---
|
|
228
231
|
|
|
229
|
-
<
|
|
230
|
-
|
|
231
|
-
|
|
232
|
+
<div align="center">
|
|
233
|
+
|
|
234
|
+
### โญ Star this repo if VideoNut helps you create better content!
|
|
235
|
+
|
|
236
|
+
**[๐ฆ npm](https://www.npmjs.com/package/videonut)** โข **[๐ป GitHub](https://github.com/konda-vamshi-krishna/videonut)** โข **[๐ Issues](https://github.com/konda-vamshi-krishna/videonut/issues)**
|
|
237
|
+
|
|
238
|
+
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "videonut",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "AI-powered YouTube documentary production pipeline with 10 specialized agents for research, scripting, and asset management",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"youtube",
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
"type": "git",
|
|
29
29
|
"url": "git+https://github.com/konda-vamshi-krishna/videonut.git"
|
|
30
30
|
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"setup": "node setup.js"
|
|
33
|
+
},
|
|
31
34
|
"bin": {
|
|
32
35
|
"videonut": "./bin/videonut.js"
|
|
33
36
|
},
|
|
@@ -46,12 +49,14 @@
|
|
|
46
49
|
".claude/",
|
|
47
50
|
".antigravity/",
|
|
48
51
|
"bin/",
|
|
52
|
+
"setup.js",
|
|
49
53
|
"config.yaml",
|
|
50
54
|
"requirements.txt",
|
|
51
55
|
"workflow_orchestrator.py",
|
|
52
56
|
"file_validator.py",
|
|
53
57
|
"README.md",
|
|
54
58
|
"USER_GUIDE.md",
|
|
59
|
+
"CONTRIBUTING.md",
|
|
55
60
|
"LICENSE"
|
|
56
61
|
],
|
|
57
62
|
"engines": {
|
package/setup.js
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* VideoNut Setup Script
|
|
5
|
+
* Run this after cloning from GitHub to install all dependencies
|
|
6
|
+
*
|
|
7
|
+
* Usage: node setup.js
|
|
8
|
+
* Or: npm run setup
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const { execSync, spawn } = require('child_process');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const https = require('https');
|
|
15
|
+
const readline = require('readline');
|
|
16
|
+
|
|
17
|
+
// Colors for console
|
|
18
|
+
const colors = {
|
|
19
|
+
reset: '\x1b[0m',
|
|
20
|
+
bright: '\x1b[1m',
|
|
21
|
+
green: '\x1b[32m',
|
|
22
|
+
yellow: '\x1b[33m',
|
|
23
|
+
red: '\x1b[31m',
|
|
24
|
+
cyan: '\x1b[36m'
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function log(msg, color = 'reset') {
|
|
28
|
+
console.log(`${colors[color]}${msg}${colors.reset}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function header(msg) {
|
|
32
|
+
console.log('\n' + 'โ'.repeat(60));
|
|
33
|
+
log(`๐ฌ ${msg}`, 'bright');
|
|
34
|
+
console.log('โ'.repeat(60) + '\n');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function success(msg) { log(`โ
${msg}`, 'green'); }
|
|
38
|
+
function warning(msg) { log(`โ ๏ธ ${msg}`, 'yellow'); }
|
|
39
|
+
function error(msg) { log(`โ ${msg}`, 'red'); }
|
|
40
|
+
function info(msg) { log(`โน๏ธ ${msg}`, 'cyan'); }
|
|
41
|
+
function progress(msg) { process.stdout.write(`\rโณ ${msg}`); }
|
|
42
|
+
|
|
43
|
+
function commandExists(cmd) {
|
|
44
|
+
try {
|
|
45
|
+
const isWindows = process.platform === 'win32';
|
|
46
|
+
const checkCmd = isWindows ? `where ${cmd}` : `which ${cmd}`;
|
|
47
|
+
execSync(checkCmd, { stdio: 'pipe' });
|
|
48
|
+
return true;
|
|
49
|
+
} catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function ask(question) {
|
|
55
|
+
const rl = readline.createInterface({
|
|
56
|
+
input: process.stdin,
|
|
57
|
+
output: process.stdout
|
|
58
|
+
});
|
|
59
|
+
return new Promise(resolve => {
|
|
60
|
+
rl.question(question, answer => {
|
|
61
|
+
rl.close();
|
|
62
|
+
resolve(answer.trim());
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function downloadFile(url, dest, description = 'Downloading') {
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
const request = (currentUrl) => {
|
|
70
|
+
const protocol = currentUrl.startsWith('https') ? require('https') : require('http');
|
|
71
|
+
protocol.get(currentUrl, response => {
|
|
72
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
73
|
+
request(response.headers.location);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (response.statusCode !== 200) {
|
|
77
|
+
reject(new Error(`Download failed: ${response.statusCode}`));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const totalSize = parseInt(response.headers['content-length'], 10);
|
|
82
|
+
let downloadedSize = 0;
|
|
83
|
+
const file = fs.createWriteStream(dest);
|
|
84
|
+
|
|
85
|
+
response.on('data', chunk => {
|
|
86
|
+
downloadedSize += chunk.length;
|
|
87
|
+
if (totalSize) {
|
|
88
|
+
const percent = Math.round((downloadedSize / totalSize) * 100);
|
|
89
|
+
const mb = (downloadedSize / 1024 / 1024).toFixed(1);
|
|
90
|
+
const totalMb = (totalSize / 1024 / 1024).toFixed(1);
|
|
91
|
+
progress(`${description}: ${mb}MB / ${totalMb}MB (${percent}%)`);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
response.pipe(file);
|
|
96
|
+
file.on('finish', () => {
|
|
97
|
+
file.close();
|
|
98
|
+
console.log('');
|
|
99
|
+
resolve();
|
|
100
|
+
});
|
|
101
|
+
file.on('error', reject);
|
|
102
|
+
}).on('error', reject);
|
|
103
|
+
};
|
|
104
|
+
request(url);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function extractZip(zipPath, destDir) {
|
|
109
|
+
const isWindows = process.platform === 'win32';
|
|
110
|
+
if (isWindows) {
|
|
111
|
+
execSync(`powershell -Command "Expand-Archive -Path '${zipPath}' -DestinationPath '${destDir}' -Force"`, { stdio: 'pipe' });
|
|
112
|
+
} else {
|
|
113
|
+
execSync(`unzip -o "${zipPath}" -d "${destDir}"`, { stdio: 'pipe' });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function main() {
|
|
118
|
+
const projectDir = path.resolve(__dirname);
|
|
119
|
+
const isWindows = process.platform === 'win32';
|
|
120
|
+
|
|
121
|
+
header('VideoNut Setup - GitHub Clone Edition');
|
|
122
|
+
info(`Setting up in: ${projectDir}\n`);
|
|
123
|
+
|
|
124
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
125
|
+
// STEP 1: Check/Install Python
|
|
126
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
127
|
+
header('Step 1/4: Checking Python');
|
|
128
|
+
|
|
129
|
+
let pythonCmd = null;
|
|
130
|
+
|
|
131
|
+
if (commandExists('python3')) {
|
|
132
|
+
pythonCmd = 'python3';
|
|
133
|
+
success('Found Python3');
|
|
134
|
+
} else if (commandExists('python')) {
|
|
135
|
+
pythonCmd = 'python';
|
|
136
|
+
success('Found Python');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!pythonCmd && isWindows) {
|
|
140
|
+
info('Python not found. Downloading embedded Python...');
|
|
141
|
+
|
|
142
|
+
const pythonDir = path.join(projectDir, 'python');
|
|
143
|
+
const pythonVersion = '3.12.1';
|
|
144
|
+
const pythonZipUrl = `https://www.python.org/ftp/python/${pythonVersion}/python-${pythonVersion}-embed-amd64.zip`;
|
|
145
|
+
const pythonZipPath = path.join(projectDir, 'python.zip');
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
fs.mkdirSync(pythonDir, { recursive: true });
|
|
149
|
+
await downloadFile(pythonZipUrl, pythonZipPath, 'Downloading Python');
|
|
150
|
+
|
|
151
|
+
info('Extracting Python...');
|
|
152
|
+
await extractZip(pythonZipPath, pythonDir);
|
|
153
|
+
fs.unlinkSync(pythonZipPath);
|
|
154
|
+
|
|
155
|
+
// Download get-pip.py
|
|
156
|
+
const getPipPath = path.join(pythonDir, 'get-pip.py');
|
|
157
|
+
await downloadFile('https://bootstrap.pypa.io/get-pip.py', getPipPath, 'Downloading pip');
|
|
158
|
+
|
|
159
|
+
// Enable pip
|
|
160
|
+
const pthFile = path.join(pythonDir, 'python312._pth');
|
|
161
|
+
if (fs.existsSync(pthFile)) {
|
|
162
|
+
let content = fs.readFileSync(pthFile, 'utf8');
|
|
163
|
+
content = content.replace('#import site', 'import site');
|
|
164
|
+
fs.writeFileSync(pthFile, content);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Install pip
|
|
168
|
+
info('Installing pip...');
|
|
169
|
+
execSync(`"${path.join(pythonDir, 'python.exe')}" "${getPipPath}"`, { stdio: 'inherit' });
|
|
170
|
+
|
|
171
|
+
pythonCmd = path.join(pythonDir, 'python.exe');
|
|
172
|
+
success('Python installed locally!');
|
|
173
|
+
} catch (e) {
|
|
174
|
+
warning(`Could not auto-install Python: ${e.message}`);
|
|
175
|
+
console.log('Please install Python from: https://python.org/downloads');
|
|
176
|
+
}
|
|
177
|
+
} else if (!pythonCmd) {
|
|
178
|
+
warning('Python not found. Please install manually.');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
182
|
+
// STEP 2: Check/Install FFmpeg
|
|
183
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
184
|
+
header('Step 2/4: Checking FFmpeg');
|
|
185
|
+
|
|
186
|
+
const toolsBinDir = path.join(projectDir, 'tools', 'bin');
|
|
187
|
+
const ffmpegPath = path.join(toolsBinDir, isWindows ? 'ffmpeg.exe' : 'ffmpeg');
|
|
188
|
+
const ffprobePath = path.join(toolsBinDir, isWindows ? 'ffprobe.exe' : 'ffprobe');
|
|
189
|
+
|
|
190
|
+
if (fs.existsSync(ffmpegPath) && fs.existsSync(ffprobePath)) {
|
|
191
|
+
success('FFmpeg already in tools/bin/');
|
|
192
|
+
} else if (commandExists('ffmpeg')) {
|
|
193
|
+
success('FFmpeg found in system PATH');
|
|
194
|
+
} else if (isWindows) {
|
|
195
|
+
info('Downloading FFmpeg...');
|
|
196
|
+
|
|
197
|
+
const ffmpegUrl = 'https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip';
|
|
198
|
+
const ffmpegZipPath = path.join(projectDir, 'ffmpeg.zip');
|
|
199
|
+
const ffmpegTempDir = path.join(projectDir, 'ffmpeg_temp');
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
fs.mkdirSync(toolsBinDir, { recursive: true });
|
|
203
|
+
await downloadFile(ffmpegUrl, ffmpegZipPath, 'Downloading FFmpeg');
|
|
204
|
+
|
|
205
|
+
info('Extracting FFmpeg...');
|
|
206
|
+
fs.mkdirSync(ffmpegTempDir, { recursive: true });
|
|
207
|
+
await extractZip(ffmpegZipPath, ffmpegTempDir);
|
|
208
|
+
|
|
209
|
+
// Find and copy ffmpeg binaries
|
|
210
|
+
const dirs = fs.readdirSync(ffmpegTempDir);
|
|
211
|
+
const ffmpegDir = dirs.find(d => d.startsWith('ffmpeg'));
|
|
212
|
+
if (ffmpegDir) {
|
|
213
|
+
const binDir = path.join(ffmpegTempDir, ffmpegDir, 'bin');
|
|
214
|
+
if (fs.existsSync(path.join(binDir, 'ffmpeg.exe'))) {
|
|
215
|
+
fs.copyFileSync(path.join(binDir, 'ffmpeg.exe'), ffmpegPath);
|
|
216
|
+
fs.copyFileSync(path.join(binDir, 'ffprobe.exe'), ffprobePath);
|
|
217
|
+
success('FFmpeg installed to tools/bin/');
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Cleanup
|
|
222
|
+
fs.unlinkSync(ffmpegZipPath);
|
|
223
|
+
fs.rmSync(ffmpegTempDir, { recursive: true, force: true });
|
|
224
|
+
} catch (e) {
|
|
225
|
+
warning(`Could not auto-install FFmpeg: ${e.message}`);
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
warning('FFmpeg not found. Install with: brew install ffmpeg (Mac) or apt install ffmpeg (Linux)');
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
232
|
+
// STEP 3: Install Python Requirements
|
|
233
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
234
|
+
header('Step 3/4: Installing Python Libraries');
|
|
235
|
+
|
|
236
|
+
if (pythonCmd) {
|
|
237
|
+
const reqPath = path.join(projectDir, 'requirements.txt');
|
|
238
|
+
if (fs.existsSync(reqPath)) {
|
|
239
|
+
try {
|
|
240
|
+
info('Installing Python requirements...');
|
|
241
|
+
execSync(`"${pythonCmd}" -m pip install -r "${reqPath}"`, { stdio: 'inherit' });
|
|
242
|
+
success('Python requirements installed!');
|
|
243
|
+
} catch (e) {
|
|
244
|
+
warning('Could not install requirements. Try: pip install -r requirements.txt');
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
250
|
+
// STEP 4: Check/Install AI CLI
|
|
251
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
252
|
+
header('Step 4/4: Checking AI CLI');
|
|
253
|
+
|
|
254
|
+
const hasGemini = commandExists('gemini');
|
|
255
|
+
const hasQwen = commandExists('qwen');
|
|
256
|
+
const hasClaude = commandExists('claude');
|
|
257
|
+
|
|
258
|
+
if (hasGemini || hasQwen || hasClaude) {
|
|
259
|
+
if (hasGemini) success('Gemini CLI found');
|
|
260
|
+
if (hasQwen) success('Qwen CLI found');
|
|
261
|
+
if (hasClaude) success('Claude CLI found');
|
|
262
|
+
} else {
|
|
263
|
+
warning('No AI CLI found.');
|
|
264
|
+
console.log('\nWould you like to install Gemini CLI?');
|
|
265
|
+
const answer = await ask('Install Gemini CLI? [Y/n]: ');
|
|
266
|
+
|
|
267
|
+
if (answer.toLowerCase() !== 'n') {
|
|
268
|
+
try {
|
|
269
|
+
info('Installing Gemini CLI globally...');
|
|
270
|
+
execSync('npm install -g @anthropic-ai/claude-code', { stdio: 'inherit' });
|
|
271
|
+
success('Gemini CLI installed!');
|
|
272
|
+
} catch (e) {
|
|
273
|
+
warning('Could not install CLI. Please install manually.');
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
279
|
+
// DONE!
|
|
280
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
281
|
+
header('๐ Setup Complete!');
|
|
282
|
+
|
|
283
|
+
console.log('๐ Your project is ready:');
|
|
284
|
+
console.log(` ${projectDir}/`);
|
|
285
|
+
console.log(' โโโ agents/ (AI agent prompts)');
|
|
286
|
+
console.log(' โโโ tools/ (downloaders, validators)');
|
|
287
|
+
console.log(' โโโ .gemini/ (CLI commands)');
|
|
288
|
+
console.log(' โโโ Projects/ (create this for your work)');
|
|
289
|
+
|
|
290
|
+
console.log('\n๐ Quick Start:');
|
|
291
|
+
console.log(' 1. Run: gemini (or your preferred CLI)');
|
|
292
|
+
console.log(' 2. Type: /topic_scout');
|
|
293
|
+
console.log(' 3. Follow the agent pipeline!');
|
|
294
|
+
|
|
295
|
+
console.log('\n' + 'โ'.repeat(60));
|
|
296
|
+
log('๐ฌ Happy Documentary Making!', 'bright');
|
|
297
|
+
console.log('โ'.repeat(60) + '\n');
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
main().catch(console.error);
|