@techwavedev/agi-agent-kit 1.1.7 ā 1.2.7
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/CHANGELOG.md +142 -1
- package/README.md +195 -15
- package/bin/init.js +154 -5
- package/package.json +6 -3
- package/templates/base/AGENTS.md +54 -23
- package/templates/base/README.md +327 -0
- package/templates/base/directives/memory_integration.md +95 -0
- package/templates/base/execution/memory_manager.py +309 -0
- package/templates/base/execution/session_boot.py +218 -0
- package/templates/base/execution/session_init.py +320 -0
- package/templates/base/requirements.txt +45 -6
- package/templates/base/skill-creator/SKILL_skillcreator.md +3 -3
- package/templates/skills/knowledge/design-md/README.md +0 -0
- package/templates/skills/knowledge/design-md/SKILL.md +0 -0
- package/templates/skills/knowledge/design-md/examples/DESIGN.md +0 -0
- package/templates/skills/knowledge/intelligent-routing/SKILL.md +237 -164
- package/templates/skills/knowledge/notebooklm-rag/SKILL.md +216 -0
- package/templates/skills/knowledge/notebooklm-rag/requirements.txt +9 -0
- package/templates/skills/knowledge/notebooklm-rag/scripts/ask_question.py +237 -0
- package/templates/skills/knowledge/notebooklm-rag/scripts/auth_manager.py +307 -0
- package/templates/skills/knowledge/notebooklm-rag/scripts/browser_utils.py +101 -0
- package/templates/skills/knowledge/notebooklm-rag/scripts/cleanup_manager.py +87 -0
- package/templates/skills/knowledge/notebooklm-rag/scripts/config.py +45 -0
- package/templates/skills/knowledge/notebooklm-rag/scripts/notebook_manager.py +334 -0
- package/templates/skills/knowledge/notebooklm-rag/scripts/run.py +92 -0
- package/templates/skills/knowledge/notebooklm-rag/scripts/setup_environment.py +68 -0
- package/templates/skills/knowledge/parallel-agents/SKILL.md +345 -73
- package/templates/skills/knowledge/plugin-discovery/SKILL.md +581 -0
- package/templates/skills/knowledge/plugin-discovery/scripts/platform_setup.py +1083 -0
- package/templates/skills/knowledge/react-components/README.md +0 -0
- package/templates/skills/knowledge/react-components/SKILL.md +0 -0
- package/templates/skills/knowledge/react-components/examples/gold-standard-card.tsx +0 -0
- package/templates/skills/knowledge/react-components/package-lock.json +0 -0
- package/templates/skills/knowledge/react-components/package.json +0 -0
- package/templates/skills/knowledge/react-components/resources/architecture-checklist.md +0 -0
- package/templates/skills/knowledge/react-components/resources/component-template.tsx +0 -0
- package/templates/skills/knowledge/react-components/resources/stitch-api-reference.md +0 -0
- package/templates/skills/knowledge/react-components/resources/style-guide.json +0 -0
- package/templates/skills/knowledge/react-components/scripts/validate.js +0 -0
- package/templates/skills/knowledge/self-update/SKILL.md +0 -0
- package/templates/skills/knowledge/self-update/scripts/update_kit.py +0 -0
- package/templates/skills/knowledge/stitch-loop/README.md +0 -0
- package/templates/skills/knowledge/stitch-loop/SKILL.md +3 -3
- package/templates/skills/knowledge/stitch-loop/examples/SITE.md +0 -0
- package/templates/skills/knowledge/stitch-loop/examples/next-prompt.md +0 -0
- package/templates/skills/knowledge/stitch-loop/resources/baton-schema.md +0 -0
- package/templates/skills/knowledge/stitch-loop/resources/site-template.md +0 -0
- package/templates/skills/stitch-loop/SKILL.md +3 -3
- package/templates/skills/core/qdrant-memory/scripts/__pycache__/embedding_utils.cpython-314.pyc +0 -0
- package/templates/skills/core/qdrant-memory/scripts/__pycache__/init_collection.cpython-314.pyc +0 -0
- package/templates/skills/knowledge/SKILLS_CATALOG.md +0 -796
- package/templates/skills/knowledge/jira/scripts/__pycache__/jira_client.cpython-314.pyc +0 -0
- package/templates/skills/knowledge/notebooklm-mcp/SKILL.md +0 -71
- package/templates/skills/knowledge/notebooklm-mcp/assets/example_asset.txt +0 -24
- package/templates/skills/knowledge/notebooklm-mcp/references/api_reference.md +0 -34
- package/templates/skills/knowledge/notebooklm-mcp/scripts/example.py +0 -19
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Notebook Library Management for NotebookLM RAG Skill
|
|
4
|
+
Manages a library of NotebookLM notebooks with metadata
|
|
5
|
+
Adapted from PleasePrompto/notebooklm-skill (MIT License)
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import argparse
|
|
10
|
+
import os
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Dict, List, Optional, Any
|
|
13
|
+
from datetime import datetime
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class NotebookLibrary:
|
|
17
|
+
"""Manages a collection of NotebookLM notebooks with metadata"""
|
|
18
|
+
|
|
19
|
+
def __init__(self):
|
|
20
|
+
"""Initialize the notebook library"""
|
|
21
|
+
skill_dir = Path(__file__).parent.parent
|
|
22
|
+
self.data_dir = skill_dir / "data"
|
|
23
|
+
self.data_dir.mkdir(parents=True, exist_ok=True)
|
|
24
|
+
|
|
25
|
+
self.library_file = self.data_dir / "library.json"
|
|
26
|
+
self.notebooks: Dict[str, Dict[str, Any]] = {}
|
|
27
|
+
self.active_notebook_id: Optional[str] = None
|
|
28
|
+
|
|
29
|
+
self._load_library()
|
|
30
|
+
|
|
31
|
+
def _load_library(self):
|
|
32
|
+
"""Load library from disk"""
|
|
33
|
+
if self.library_file.exists():
|
|
34
|
+
try:
|
|
35
|
+
with open(self.library_file, 'r') as f:
|
|
36
|
+
data = json.load(f)
|
|
37
|
+
self.notebooks = data.get('notebooks', {})
|
|
38
|
+
self.active_notebook_id = data.get('active_notebook_id')
|
|
39
|
+
print(f"š Loaded library with {len(self.notebooks)} notebooks")
|
|
40
|
+
except Exception as e:
|
|
41
|
+
print(f"ā ļø Error loading library: {e}")
|
|
42
|
+
self.notebooks = {}
|
|
43
|
+
self.active_notebook_id = None
|
|
44
|
+
else:
|
|
45
|
+
self._save_library()
|
|
46
|
+
|
|
47
|
+
def _save_library(self):
|
|
48
|
+
"""Save library to disk"""
|
|
49
|
+
try:
|
|
50
|
+
data = {
|
|
51
|
+
'notebooks': self.notebooks,
|
|
52
|
+
'active_notebook_id': self.active_notebook_id,
|
|
53
|
+
'updated_at': datetime.now().isoformat()
|
|
54
|
+
}
|
|
55
|
+
with open(self.library_file, 'w') as f:
|
|
56
|
+
json.dump(data, f, indent=2)
|
|
57
|
+
except Exception as e:
|
|
58
|
+
print(f"ā Error saving library: {e}")
|
|
59
|
+
|
|
60
|
+
def add_notebook(
|
|
61
|
+
self,
|
|
62
|
+
url: str,
|
|
63
|
+
name: str,
|
|
64
|
+
description: str,
|
|
65
|
+
topics: List[str],
|
|
66
|
+
content_types: Optional[List[str]] = None,
|
|
67
|
+
use_cases: Optional[List[str]] = None,
|
|
68
|
+
tags: Optional[List[str]] = None
|
|
69
|
+
) -> Dict[str, Any]:
|
|
70
|
+
"""Add a new notebook to the library"""
|
|
71
|
+
notebook_id = name.lower().replace(' ', '-').replace('_', '-')
|
|
72
|
+
|
|
73
|
+
if notebook_id in self.notebooks:
|
|
74
|
+
raise ValueError(f"Notebook with ID '{notebook_id}' already exists")
|
|
75
|
+
|
|
76
|
+
notebook = {
|
|
77
|
+
'id': notebook_id,
|
|
78
|
+
'url': url,
|
|
79
|
+
'name': name,
|
|
80
|
+
'description': description,
|
|
81
|
+
'topics': topics,
|
|
82
|
+
'content_types': content_types or [],
|
|
83
|
+
'use_cases': use_cases or [],
|
|
84
|
+
'tags': tags or [],
|
|
85
|
+
'created_at': datetime.now().isoformat(),
|
|
86
|
+
'updated_at': datetime.now().isoformat(),
|
|
87
|
+
'use_count': 0,
|
|
88
|
+
'last_used': None
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
self.notebooks[notebook_id] = notebook
|
|
92
|
+
|
|
93
|
+
if len(self.notebooks) == 1:
|
|
94
|
+
self.active_notebook_id = notebook_id
|
|
95
|
+
|
|
96
|
+
self._save_library()
|
|
97
|
+
|
|
98
|
+
print(f"ā
Added notebook: {name} ({notebook_id})")
|
|
99
|
+
return notebook
|
|
100
|
+
|
|
101
|
+
def remove_notebook(self, notebook_id: str) -> bool:
|
|
102
|
+
"""Remove a notebook from the library"""
|
|
103
|
+
if notebook_id in self.notebooks:
|
|
104
|
+
del self.notebooks[notebook_id]
|
|
105
|
+
|
|
106
|
+
if self.active_notebook_id == notebook_id:
|
|
107
|
+
self.active_notebook_id = None
|
|
108
|
+
if self.notebooks:
|
|
109
|
+
self.active_notebook_id = list(self.notebooks.keys())[0]
|
|
110
|
+
|
|
111
|
+
self._save_library()
|
|
112
|
+
print(f"ā
Removed notebook: {notebook_id}")
|
|
113
|
+
return True
|
|
114
|
+
|
|
115
|
+
print(f"ā ļø Notebook not found: {notebook_id}")
|
|
116
|
+
return False
|
|
117
|
+
|
|
118
|
+
def update_notebook(
|
|
119
|
+
self,
|
|
120
|
+
notebook_id: str,
|
|
121
|
+
name: Optional[str] = None,
|
|
122
|
+
description: Optional[str] = None,
|
|
123
|
+
topics: Optional[List[str]] = None,
|
|
124
|
+
content_types: Optional[List[str]] = None,
|
|
125
|
+
use_cases: Optional[List[str]] = None,
|
|
126
|
+
tags: Optional[List[str]] = None,
|
|
127
|
+
url: Optional[str] = None
|
|
128
|
+
) -> Dict[str, Any]:
|
|
129
|
+
"""Update notebook metadata"""
|
|
130
|
+
if notebook_id not in self.notebooks:
|
|
131
|
+
raise ValueError(f"Notebook not found: {notebook_id}")
|
|
132
|
+
|
|
133
|
+
notebook = self.notebooks[notebook_id]
|
|
134
|
+
|
|
135
|
+
if name is not None:
|
|
136
|
+
notebook['name'] = name
|
|
137
|
+
if description is not None:
|
|
138
|
+
notebook['description'] = description
|
|
139
|
+
if topics is not None:
|
|
140
|
+
notebook['topics'] = topics
|
|
141
|
+
if content_types is not None:
|
|
142
|
+
notebook['content_types'] = content_types
|
|
143
|
+
if use_cases is not None:
|
|
144
|
+
notebook['use_cases'] = use_cases
|
|
145
|
+
if tags is not None:
|
|
146
|
+
notebook['tags'] = tags
|
|
147
|
+
if url is not None:
|
|
148
|
+
notebook['url'] = url
|
|
149
|
+
|
|
150
|
+
notebook['updated_at'] = datetime.now().isoformat()
|
|
151
|
+
|
|
152
|
+
self._save_library()
|
|
153
|
+
print(f"ā
Updated notebook: {notebook['name']}")
|
|
154
|
+
return notebook
|
|
155
|
+
|
|
156
|
+
def get_notebook(self, notebook_id: str) -> Optional[Dict[str, Any]]:
|
|
157
|
+
"""Get a specific notebook by ID"""
|
|
158
|
+
return self.notebooks.get(notebook_id)
|
|
159
|
+
|
|
160
|
+
def list_notebooks(self) -> List[Dict[str, Any]]:
|
|
161
|
+
"""List all notebooks in the library"""
|
|
162
|
+
return list(self.notebooks.values())
|
|
163
|
+
|
|
164
|
+
def search_notebooks(self, query: str) -> List[Dict[str, Any]]:
|
|
165
|
+
"""Search notebooks by query"""
|
|
166
|
+
query_lower = query.lower()
|
|
167
|
+
results = []
|
|
168
|
+
|
|
169
|
+
for notebook in self.notebooks.values():
|
|
170
|
+
searchable = [
|
|
171
|
+
notebook['name'].lower(),
|
|
172
|
+
notebook['description'].lower(),
|
|
173
|
+
' '.join(notebook['topics']).lower(),
|
|
174
|
+
' '.join(notebook['tags']).lower(),
|
|
175
|
+
' '.join(notebook.get('use_cases', [])).lower()
|
|
176
|
+
]
|
|
177
|
+
|
|
178
|
+
if any(query_lower in field for field in searchable):
|
|
179
|
+
results.append(notebook)
|
|
180
|
+
|
|
181
|
+
return results
|
|
182
|
+
|
|
183
|
+
def select_notebook(self, notebook_id: str) -> Dict[str, Any]:
|
|
184
|
+
"""Set a notebook as active"""
|
|
185
|
+
if notebook_id not in self.notebooks:
|
|
186
|
+
raise ValueError(f"Notebook not found: {notebook_id}")
|
|
187
|
+
|
|
188
|
+
self.active_notebook_id = notebook_id
|
|
189
|
+
self._save_library()
|
|
190
|
+
|
|
191
|
+
notebook = self.notebooks[notebook_id]
|
|
192
|
+
print(f"ā
Activated notebook: {notebook['name']}")
|
|
193
|
+
return notebook
|
|
194
|
+
|
|
195
|
+
def get_active_notebook(self) -> Optional[Dict[str, Any]]:
|
|
196
|
+
"""Get the currently active notebook"""
|
|
197
|
+
if self.active_notebook_id:
|
|
198
|
+
return self.notebooks.get(self.active_notebook_id)
|
|
199
|
+
return None
|
|
200
|
+
|
|
201
|
+
def increment_use_count(self, notebook_id: str) -> Dict[str, Any]:
|
|
202
|
+
"""Increment usage counter for a notebook"""
|
|
203
|
+
if notebook_id not in self.notebooks:
|
|
204
|
+
raise ValueError(f"Notebook not found: {notebook_id}")
|
|
205
|
+
|
|
206
|
+
notebook = self.notebooks[notebook_id]
|
|
207
|
+
notebook['use_count'] += 1
|
|
208
|
+
notebook['last_used'] = datetime.now().isoformat()
|
|
209
|
+
|
|
210
|
+
self._save_library()
|
|
211
|
+
return notebook
|
|
212
|
+
|
|
213
|
+
def get_stats(self) -> Dict[str, Any]:
|
|
214
|
+
"""Get library statistics"""
|
|
215
|
+
total_notebooks = len(self.notebooks)
|
|
216
|
+
total_topics = set()
|
|
217
|
+
total_use_count = 0
|
|
218
|
+
|
|
219
|
+
for notebook in self.notebooks.values():
|
|
220
|
+
total_topics.update(notebook['topics'])
|
|
221
|
+
total_use_count += notebook['use_count']
|
|
222
|
+
|
|
223
|
+
most_used = None
|
|
224
|
+
if self.notebooks:
|
|
225
|
+
most_used = max(
|
|
226
|
+
self.notebooks.values(),
|
|
227
|
+
key=lambda n: n['use_count']
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
'total_notebooks': total_notebooks,
|
|
232
|
+
'total_topics': len(total_topics),
|
|
233
|
+
'total_use_count': total_use_count,
|
|
234
|
+
'active_notebook': self.get_active_notebook(),
|
|
235
|
+
'most_used_notebook': most_used,
|
|
236
|
+
'library_path': str(self.library_file)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def main():
|
|
241
|
+
"""Command-line interface for notebook management"""
|
|
242
|
+
parser = argparse.ArgumentParser(description='Manage NotebookLM library')
|
|
243
|
+
|
|
244
|
+
subparsers = parser.add_subparsers(dest='command', help='Commands')
|
|
245
|
+
|
|
246
|
+
add_parser = subparsers.add_parser('add', help='Add a notebook')
|
|
247
|
+
add_parser.add_argument('--url', required=True, help='NotebookLM URL')
|
|
248
|
+
add_parser.add_argument('--name', required=True, help='Display name')
|
|
249
|
+
add_parser.add_argument('--description', required=True, help='Description')
|
|
250
|
+
add_parser.add_argument('--topics', required=True, help='Comma-separated topics')
|
|
251
|
+
add_parser.add_argument('--use-cases', help='Comma-separated use cases')
|
|
252
|
+
add_parser.add_argument('--tags', help='Comma-separated tags')
|
|
253
|
+
|
|
254
|
+
subparsers.add_parser('list', help='List all notebooks')
|
|
255
|
+
|
|
256
|
+
search_parser = subparsers.add_parser('search', help='Search notebooks')
|
|
257
|
+
search_parser.add_argument('--query', required=True, help='Search query')
|
|
258
|
+
|
|
259
|
+
activate_parser = subparsers.add_parser('activate', help='Set active notebook')
|
|
260
|
+
activate_parser.add_argument('--id', required=True, help='Notebook ID')
|
|
261
|
+
|
|
262
|
+
remove_parser = subparsers.add_parser('remove', help='Remove a notebook')
|
|
263
|
+
remove_parser.add_argument('--id', required=True, help='Notebook ID')
|
|
264
|
+
|
|
265
|
+
subparsers.add_parser('stats', help='Show library statistics')
|
|
266
|
+
|
|
267
|
+
args = parser.parse_args()
|
|
268
|
+
|
|
269
|
+
library = NotebookLibrary()
|
|
270
|
+
|
|
271
|
+
if args.command == 'add':
|
|
272
|
+
topics = [t.strip() for t in args.topics.split(',')]
|
|
273
|
+
use_cases = [u.strip() for u in args.use_cases.split(',')] if args.use_cases else None
|
|
274
|
+
tags = [t.strip() for t in args.tags.split(',')] if args.tags else None
|
|
275
|
+
|
|
276
|
+
notebook = library.add_notebook(
|
|
277
|
+
url=args.url,
|
|
278
|
+
name=args.name,
|
|
279
|
+
description=args.description,
|
|
280
|
+
topics=topics,
|
|
281
|
+
use_cases=use_cases,
|
|
282
|
+
tags=tags
|
|
283
|
+
)
|
|
284
|
+
print(json.dumps(notebook, indent=2))
|
|
285
|
+
|
|
286
|
+
elif args.command == 'list':
|
|
287
|
+
notebooks = library.list_notebooks()
|
|
288
|
+
if notebooks:
|
|
289
|
+
print("\nš Notebook Library:")
|
|
290
|
+
for notebook in notebooks:
|
|
291
|
+
active = " [ACTIVE]" if notebook['id'] == library.active_notebook_id else ""
|
|
292
|
+
print(f"\n š {notebook['name']}{active}")
|
|
293
|
+
print(f" ID: {notebook['id']}")
|
|
294
|
+
print(f" Topics: {', '.join(notebook['topics'])}")
|
|
295
|
+
print(f" Uses: {notebook['use_count']}")
|
|
296
|
+
else:
|
|
297
|
+
print("š Library is empty. Add notebooks with: notebook_manager.py add")
|
|
298
|
+
|
|
299
|
+
elif args.command == 'search':
|
|
300
|
+
results = library.search_notebooks(args.query)
|
|
301
|
+
if results:
|
|
302
|
+
print(f"\nš Found {len(results)} notebooks:")
|
|
303
|
+
for notebook in results:
|
|
304
|
+
print(f"\n š {notebook['name']} ({notebook['id']})")
|
|
305
|
+
print(f" {notebook['description']}")
|
|
306
|
+
else:
|
|
307
|
+
print(f"š No notebooks found for: {args.query}")
|
|
308
|
+
|
|
309
|
+
elif args.command == 'activate':
|
|
310
|
+
notebook = library.select_notebook(args.id)
|
|
311
|
+
print(f"Now using: {notebook['name']}")
|
|
312
|
+
|
|
313
|
+
elif args.command == 'remove':
|
|
314
|
+
if library.remove_notebook(args.id):
|
|
315
|
+
print("Notebook removed from library")
|
|
316
|
+
|
|
317
|
+
elif args.command == 'stats':
|
|
318
|
+
stats = library.get_stats()
|
|
319
|
+
print("\nš Library Statistics:")
|
|
320
|
+
print(f" Total notebooks: {stats['total_notebooks']}")
|
|
321
|
+
print(f" Total topics: {stats['total_topics']}")
|
|
322
|
+
print(f" Total uses: {stats['total_use_count']}")
|
|
323
|
+
if stats['active_notebook']:
|
|
324
|
+
print(f" Active: {stats['active_notebook']['name']}")
|
|
325
|
+
if stats['most_used_notebook']:
|
|
326
|
+
print(f" Most used: {stats['most_used_notebook']['name']} ({stats['most_used_notebook']['use_count']} uses)")
|
|
327
|
+
print(f" Library path: {stats['library_path']}")
|
|
328
|
+
|
|
329
|
+
else:
|
|
330
|
+
parser.print_help()
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
if __name__ == "__main__":
|
|
334
|
+
main()
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Universal runner for NotebookLM RAG skill scripts
|
|
4
|
+
Ensures all scripts run with the correct virtual environment
|
|
5
|
+
Adapted from PleasePrompto/notebooklm-skill (MIT License)
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
import subprocess
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_venv_python():
|
|
15
|
+
"""Get the virtual environment Python executable"""
|
|
16
|
+
skill_dir = Path(__file__).parent.parent
|
|
17
|
+
venv_dir = skill_dir / ".venv"
|
|
18
|
+
|
|
19
|
+
if os.name == 'nt': # Windows
|
|
20
|
+
venv_python = venv_dir / "Scripts" / "python.exe"
|
|
21
|
+
else: # Unix/Linux/Mac
|
|
22
|
+
venv_python = venv_dir / "bin" / "python"
|
|
23
|
+
|
|
24
|
+
return venv_python
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def ensure_venv():
|
|
28
|
+
"""Ensure virtual environment exists"""
|
|
29
|
+
skill_dir = Path(__file__).parent.parent
|
|
30
|
+
venv_dir = skill_dir / ".venv"
|
|
31
|
+
setup_script = skill_dir / "scripts" / "setup_environment.py"
|
|
32
|
+
|
|
33
|
+
if not venv_dir.exists():
|
|
34
|
+
print("š§ First-time setup: Creating virtual environment...")
|
|
35
|
+
print(" This may take a minute...")
|
|
36
|
+
|
|
37
|
+
result = subprocess.run([sys.executable, str(setup_script)])
|
|
38
|
+
if result.returncode != 0:
|
|
39
|
+
print("ā Failed to set up environment")
|
|
40
|
+
sys.exit(1)
|
|
41
|
+
|
|
42
|
+
print("ā
Environment ready!")
|
|
43
|
+
|
|
44
|
+
return get_venv_python()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def main():
|
|
48
|
+
"""Main runner"""
|
|
49
|
+
if len(sys.argv) < 2:
|
|
50
|
+
print("Usage: python run.py <script_name> [args...]")
|
|
51
|
+
print("\nAvailable scripts:")
|
|
52
|
+
print(" ask_question.py - Query NotebookLM")
|
|
53
|
+
print(" notebook_manager.py - Manage notebook library")
|
|
54
|
+
print(" auth_manager.py - Handle authentication")
|
|
55
|
+
print(" cleanup_manager.py - Clean up skill data")
|
|
56
|
+
sys.exit(1)
|
|
57
|
+
|
|
58
|
+
script_name = sys.argv[1]
|
|
59
|
+
script_args = sys.argv[2:]
|
|
60
|
+
|
|
61
|
+
if script_name.startswith('scripts/'):
|
|
62
|
+
script_name = script_name[8:]
|
|
63
|
+
|
|
64
|
+
if not script_name.endswith('.py'):
|
|
65
|
+
script_name += '.py'
|
|
66
|
+
|
|
67
|
+
skill_dir = Path(__file__).parent.parent
|
|
68
|
+
script_path = skill_dir / "scripts" / script_name
|
|
69
|
+
|
|
70
|
+
if not script_path.exists():
|
|
71
|
+
print(f"ā Script not found: {script_name}")
|
|
72
|
+
print(f" Skill directory: {skill_dir}")
|
|
73
|
+
print(f" Looked for: {script_path}")
|
|
74
|
+
sys.exit(1)
|
|
75
|
+
|
|
76
|
+
venv_python = ensure_venv()
|
|
77
|
+
|
|
78
|
+
cmd = [str(venv_python), str(script_path)] + script_args
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
result = subprocess.run(cmd)
|
|
82
|
+
sys.exit(result.returncode)
|
|
83
|
+
except KeyboardInterrupt:
|
|
84
|
+
print("\nā ļø Interrupted by user")
|
|
85
|
+
sys.exit(130)
|
|
86
|
+
except Exception as e:
|
|
87
|
+
print(f"ā Error: {e}")
|
|
88
|
+
sys.exit(1)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
if __name__ == "__main__":
|
|
92
|
+
main()
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Environment Setup for NotebookLM RAG Skill
|
|
4
|
+
Creates virtual environment and installs dependencies
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
9
|
+
import subprocess
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def main():
|
|
14
|
+
skill_dir = Path(__file__).parent.parent
|
|
15
|
+
venv_dir = skill_dir / ".venv"
|
|
16
|
+
requirements_file = skill_dir / "requirements.txt"
|
|
17
|
+
|
|
18
|
+
print("š§ Setting up NotebookLM RAG environment...")
|
|
19
|
+
|
|
20
|
+
# Create venv
|
|
21
|
+
print(" š¦ Creating virtual environment...")
|
|
22
|
+
subprocess.run([sys.executable, "-m", "venv", str(venv_dir)], check=True)
|
|
23
|
+
|
|
24
|
+
# Get venv python
|
|
25
|
+
if os.name == 'nt':
|
|
26
|
+
venv_python = venv_dir / "Scripts" / "python.exe"
|
|
27
|
+
venv_pip = venv_dir / "Scripts" / "pip.exe"
|
|
28
|
+
else:
|
|
29
|
+
venv_python = venv_dir / "bin" / "python"
|
|
30
|
+
venv_pip = venv_dir / "bin" / "pip"
|
|
31
|
+
|
|
32
|
+
# Upgrade pip
|
|
33
|
+
print(" š¦ Upgrading pip...")
|
|
34
|
+
subprocess.run([str(venv_python), "-m", "pip", "install", "--upgrade", "pip"],
|
|
35
|
+
capture_output=True)
|
|
36
|
+
|
|
37
|
+
# Install requirements
|
|
38
|
+
if requirements_file.exists():
|
|
39
|
+
print(" š¦ Installing dependencies...")
|
|
40
|
+
result = subprocess.run(
|
|
41
|
+
[str(venv_pip), "install", "-r", str(requirements_file)],
|
|
42
|
+
capture_output=True, text=True
|
|
43
|
+
)
|
|
44
|
+
if result.returncode != 0:
|
|
45
|
+
print(f" ā Failed to install dependencies: {result.stderr}")
|
|
46
|
+
sys.exit(1)
|
|
47
|
+
else:
|
|
48
|
+
print(" š¦ Installing patchright and python-dotenv...")
|
|
49
|
+
subprocess.run(
|
|
50
|
+
[str(venv_pip), "install", "patchright==1.55.2", "python-dotenv==1.0.0"],
|
|
51
|
+
capture_output=True
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# Install Chrome for Patchright
|
|
55
|
+
print(" š Installing Chrome browser...")
|
|
56
|
+
result = subprocess.run(
|
|
57
|
+
[str(venv_python), "-m", "patchright", "install", "chrome"],
|
|
58
|
+
capture_output=True, text=True
|
|
59
|
+
)
|
|
60
|
+
if result.returncode != 0:
|
|
61
|
+
print(f" ā ļø Chrome install issue (may already be available): {result.stderr[:200]}")
|
|
62
|
+
|
|
63
|
+
print(" ā
Environment setup complete!")
|
|
64
|
+
return 0
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if __name__ == "__main__":
|
|
68
|
+
sys.exit(main())
|