ag-cortex 0.1.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/.agent/commands/test-browser.md +339 -0
- package/.agent/rules/00-constitution.md +46 -0
- package/.agent/rules/project-rules.md +49 -0
- package/.agent/skills/agent-browser/SKILL.md +223 -0
- package/.agent/skills/agent-native-architecture/SKILL.md +435 -0
- package/.agent/skills/agent-native-architecture/references/action-parity-discipline.md +409 -0
- package/.agent/skills/agent-native-architecture/references/agent-execution-patterns.md +467 -0
- package/.agent/skills/agent-native-architecture/references/agent-native-testing.md +582 -0
- package/.agent/skills/agent-native-architecture/references/architecture-patterns.md +478 -0
- package/.agent/skills/agent-native-architecture/references/dynamic-context-injection.md +338 -0
- package/.agent/skills/agent-native-architecture/references/files-universal-interface.md +301 -0
- package/.agent/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +359 -0
- package/.agent/skills/agent-native-architecture/references/mcp-tool-design.md +506 -0
- package/.agent/skills/agent-native-architecture/references/mobile-patterns.md +871 -0
- package/.agent/skills/agent-native-architecture/references/product-implications.md +443 -0
- package/.agent/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +317 -0
- package/.agent/skills/agent-native-architecture/references/self-modification.md +269 -0
- package/.agent/skills/agent-native-architecture/references/shared-workspace-architecture.md +680 -0
- package/.agent/skills/agent-native-architecture/references/system-prompt-design.md +250 -0
- package/.agent/skills/agent-native-reviewer/SKILL.md +246 -0
- package/.agent/skills/andrew-kane-gem-writer/SKILL.md +184 -0
- package/.agent/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
- package/.agent/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
- package/.agent/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
- package/.agent/skills/andrew-kane-gem-writer/references/resources.md +119 -0
- package/.agent/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
- package/.agent/skills/ankane-readme-writer/SKILL.md +50 -0
- package/.agent/skills/architecture-strategist/SKILL.md +52 -0
- package/.agent/skills/best-practices-researcher/SKILL.md +100 -0
- package/.agent/skills/bug-reproduction-validator/SKILL.md +67 -0
- package/.agent/skills/code-simplicity-reviewer/SKILL.md +85 -0
- package/.agent/skills/coding-tutor/.claude-plugin/plugin.json +9 -0
- package/.agent/skills/coding-tutor/README.md +37 -0
- package/.agent/skills/coding-tutor/commands/quiz-me.md +1 -0
- package/.agent/skills/coding-tutor/commands/sync-tutorials.md +25 -0
- package/.agent/skills/coding-tutor/commands/teach-me.md +1 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/SKILL.md +214 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py +202 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py +203 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/quiz_priority.py +190 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/setup_tutorials.py +132 -0
- package/.agent/skills/compound-docs/SKILL.md +510 -0
- package/.agent/skills/compound-docs/assets/critical-pattern-template.md +34 -0
- package/.agent/skills/compound-docs/assets/resolution-template.md +93 -0
- package/.agent/skills/compound-docs/references/yaml-schema.md +65 -0
- package/.agent/skills/compound-docs/schema.yaml +176 -0
- package/.agent/skills/create-agent-skills/SKILL.md +299 -0
- package/.agent/skills/create-agent-skills/references/api-security.md +226 -0
- package/.agent/skills/create-agent-skills/references/be-clear-and-direct.md +531 -0
- package/.agent/skills/create-agent-skills/references/best-practices.md +404 -0
- package/.agent/skills/create-agent-skills/references/common-patterns.md +595 -0
- package/.agent/skills/create-agent-skills/references/core-principles.md +437 -0
- package/.agent/skills/create-agent-skills/references/executable-code.md +175 -0
- package/.agent/skills/create-agent-skills/references/iteration-and-testing.md +474 -0
- package/.agent/skills/create-agent-skills/references/official-spec.md +185 -0
- package/.agent/skills/create-agent-skills/references/recommended-structure.md +168 -0
- package/.agent/skills/create-agent-skills/references/skill-structure.md +372 -0
- package/.agent/skills/create-agent-skills/references/using-scripts.md +113 -0
- package/.agent/skills/create-agent-skills/references/using-templates.md +112 -0
- package/.agent/skills/create-agent-skills/references/workflows-and-validation.md +510 -0
- package/.agent/skills/create-agent-skills/templates/router-skill.md +73 -0
- package/.agent/skills/create-agent-skills/templates/simple-skill.md +33 -0
- package/.agent/skills/create-agent-skills/workflows/add-reference.md +96 -0
- package/.agent/skills/create-agent-skills/workflows/add-script.md +93 -0
- package/.agent/skills/create-agent-skills/workflows/add-template.md +74 -0
- package/.agent/skills/create-agent-skills/workflows/add-workflow.md +120 -0
- package/.agent/skills/create-agent-skills/workflows/audit-skill.md +138 -0
- package/.agent/skills/create-agent-skills/workflows/create-domain-expertise-skill.md +605 -0
- package/.agent/skills/create-agent-skills/workflows/create-new-skill.md +191 -0
- package/.agent/skills/create-agent-skills/workflows/get-guidance.md +121 -0
- package/.agent/skills/create-agent-skills/workflows/upgrade-to-router.md +161 -0
- package/.agent/skills/create-agent-skills/workflows/verify-skill.md +204 -0
- package/.agent/skills/data-integrity-guardian/SKILL.md +70 -0
- package/.agent/skills/data-migration-expert/SKILL.md +97 -0
- package/.agent/skills/deployment-verification-agent/SKILL.md +159 -0
- package/.agent/skills/design-implementation-reviewer/SKILL.md +85 -0
- package/.agent/skills/design-iterator/SKILL.md +197 -0
- package/.agent/skills/dhh-rails-reviewer/SKILL.md +45 -0
- package/.agent/skills/dhh-rails-style/SKILL.md +184 -0
- package/.agent/skills/dhh-rails-style/references/architecture.md +653 -0
- package/.agent/skills/dhh-rails-style/references/controllers.md +303 -0
- package/.agent/skills/dhh-rails-style/references/frontend.md +510 -0
- package/.agent/skills/dhh-rails-style/references/gems.md +266 -0
- package/.agent/skills/dhh-rails-style/references/models.md +359 -0
- package/.agent/skills/dhh-rails-style/references/testing.md +338 -0
- package/.agent/skills/dspy-ruby/SKILL.md +594 -0
- package/.agent/skills/dspy-ruby/assets/config-template.rb +359 -0
- package/.agent/skills/dspy-ruby/assets/module-template.rb +326 -0
- package/.agent/skills/dspy-ruby/assets/signature-template.rb +143 -0
- package/.agent/skills/dspy-ruby/references/core-concepts.md +265 -0
- package/.agent/skills/dspy-ruby/references/optimization.md +623 -0
- package/.agent/skills/dspy-ruby/references/providers.md +305 -0
- package/.agent/skills/every-style-editor/SKILL.md +134 -0
- package/.agent/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
- package/.agent/skills/figma-design-sync/SKILL.md +166 -0
- package/.agent/skills/file-todos/SKILL.md +251 -0
- package/.agent/skills/file-todos/assets/todo-template.md +155 -0
- package/.agent/skills/framework-docs-researcher/SKILL.md +83 -0
- package/.agent/skills/frontend-design/SKILL.md +42 -0
- package/.agent/skills/gemini-imagegen/SKILL.md +237 -0
- package/.agent/skills/gemini-imagegen/requirements.txt +2 -0
- package/.agent/skills/gemini-imagegen/scripts/compose_images.py +168 -0
- package/.agent/skills/gemini-imagegen/scripts/edit_image.py +157 -0
- package/.agent/skills/gemini-imagegen/scripts/gemini_images.py +265 -0
- package/.agent/skills/gemini-imagegen/scripts/generate_image.py +147 -0
- package/.agent/skills/gemini-imagegen/scripts/multi_turn_chat.py +215 -0
- package/.agent/skills/git-history-analyzer/SKILL.md +42 -0
- package/.agent/skills/git-worktree/SKILL.md +302 -0
- package/.agent/skills/git-worktree/scripts/worktree-manager.sh +345 -0
- package/.agent/skills/julik-frontend-races-reviewer/SKILL.md +222 -0
- package/.agent/skills/kieran-python-reviewer/SKILL.md +104 -0
- package/.agent/skills/kieran-rails-reviewer/SKILL.md +86 -0
- package/.agent/skills/kieran-typescript-reviewer/SKILL.md +95 -0
- package/.agent/skills/lint/SKILL.md +16 -0
- package/.agent/skills/pattern-recognition-specialist/SKILL.md +57 -0
- package/.agent/skills/performance-oracle/SKILL.md +110 -0
- package/.agent/skills/pr-comment-resolver/SKILL.md +69 -0
- package/.agent/skills/rclone/SKILL.md +150 -0
- package/.agent/skills/rclone/scripts/check_setup.sh +60 -0
- package/.agent/skills/repo-research-analyst/SKILL.md +113 -0
- package/.agent/skills/security-sentinel/SKILL.md +93 -0
- package/.agent/skills/skill-creator/SKILL.md +209 -0
- package/.agent/skills/skill-creator/scripts/init_skill.py +304 -0
- package/.agent/skills/skill-creator/scripts/package_skill.py +112 -0
- package/.agent/skills/skill-creator/scripts/quick_validate.py +72 -0
- package/.agent/skills/spec-flow-analyzer/SKILL.md +113 -0
- package/.agent/skills/test-agent/SKILL.md +4 -0
- package/.agent/workflows/agent-native-audit.md +277 -0
- package/.agent/workflows/ask-user-question.md +21 -0
- package/.agent/workflows/changelog.md +137 -0
- package/.agent/workflows/compound.md +202 -0
- package/.agent/workflows/create-agent-skill.md +8 -0
- package/.agent/workflows/deepen-plan-research.md +334 -0
- package/.agent/workflows/deepen-plan-synthesis.md +182 -0
- package/.agent/workflows/deepen-plan.md +79 -0
- package/.agent/workflows/feature-video.md +342 -0
- package/.agent/workflows/generate-command.md +162 -0
- package/.agent/workflows/heal-skill.md +142 -0
- package/.agent/workflows/lfg.md +20 -0
- package/.agent/workflows/plan-analysis.md +67 -0
- package/.agent/workflows/plan-next-steps.md +63 -0
- package/.agent/workflows/plan-review.md +33 -0
- package/.agent/workflows/plan-synthesis.md +106 -0
- package/.agent/workflows/plan.md +49 -0
- package/.agent/workflows/report-bug.md +150 -0
- package/.agent/workflows/reproduce-bug.md +99 -0
- package/.agent/workflows/resolve-parallel.md +34 -0
- package/.agent/workflows/resolve-pr-parallel.md +49 -0
- package/.agent/workflows/resolve-todo-parallel.md +35 -0
- package/.agent/workflows/review-analysis.md +145 -0
- package/.agent/workflows/review-synthesis.md +262 -0
- package/.agent/workflows/review.md +64 -0
- package/.agent/workflows/ship.md +90 -0
- package/.agent/workflows/test-command.md +3 -0
- package/.agent/workflows/triage.md +310 -0
- package/.agent/workflows/work.md +157 -0
- package/.agent/workflows/xcode-test.md +332 -0
- package/LICENSE +22 -0
- package/README.md +49 -0
- package/bin/ag-cortex.js +54 -0
- package/lib/core.js +165 -0
- package/package.json +31 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Prioritize tutorials for quizzing based on spaced repetition.
|
|
4
|
+
|
|
5
|
+
Usage: python3 quiz_priority.py
|
|
6
|
+
python3 quiz_priority.py --tutorials-dir /path/to/tutorials
|
|
7
|
+
|
|
8
|
+
Returns tutorials ordered by quiz urgency (most urgent first).
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import argparse
|
|
12
|
+
import re
|
|
13
|
+
from datetime import datetime
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def get_tutorials_directory():
|
|
18
|
+
"""Get the tutorials directory (~/coding-tutor-tutorials/)."""
|
|
19
|
+
return Path.home() / "coding-tutor-tutorials"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Ideal days between quizzes based on understanding score
|
|
23
|
+
# Lower scores = more frequent review needed
|
|
24
|
+
INTERVALS = {
|
|
25
|
+
0: 1, # Never assessed - urgent
|
|
26
|
+
1: 2,
|
|
27
|
+
2: 3,
|
|
28
|
+
3: 5,
|
|
29
|
+
4: 8,
|
|
30
|
+
5: 13,
|
|
31
|
+
6: 21,
|
|
32
|
+
7: 34,
|
|
33
|
+
8: 55,
|
|
34
|
+
9: 89,
|
|
35
|
+
10: 144, # Fibonacci-ish progression
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def parse_frontmatter(filepath):
|
|
40
|
+
"""Extract YAML frontmatter from tutorial."""
|
|
41
|
+
content = filepath.read_text()
|
|
42
|
+
|
|
43
|
+
# Match YAML frontmatter between --- delimiters
|
|
44
|
+
match = re.match(r"^---\s*\n(.*?)\n---\s*\n", content, re.DOTALL)
|
|
45
|
+
if not match:
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
frontmatter_text = match.group(1)
|
|
49
|
+
metadata = {"filepath": str(filepath)}
|
|
50
|
+
|
|
51
|
+
# Parse simple YAML key: value pairs
|
|
52
|
+
for line in frontmatter_text.split("\n"):
|
|
53
|
+
line = line.strip()
|
|
54
|
+
if ":" in line:
|
|
55
|
+
key, value = line.split(":", 1)
|
|
56
|
+
key = key.strip()
|
|
57
|
+
value = value.strip()
|
|
58
|
+
|
|
59
|
+
# Handle null values
|
|
60
|
+
if value == "null":
|
|
61
|
+
value = None
|
|
62
|
+
# Convert understanding_score to int
|
|
63
|
+
elif key == "understanding_score" and value:
|
|
64
|
+
try:
|
|
65
|
+
value = int(value)
|
|
66
|
+
except ValueError:
|
|
67
|
+
pass
|
|
68
|
+
# Handle list values for concepts
|
|
69
|
+
elif key == "concepts" and value.startswith("["):
|
|
70
|
+
value = value.strip("[]").strip()
|
|
71
|
+
if value:
|
|
72
|
+
value = [item.strip() for item in value.split(",")]
|
|
73
|
+
else:
|
|
74
|
+
value = []
|
|
75
|
+
|
|
76
|
+
metadata[key] = value
|
|
77
|
+
|
|
78
|
+
return metadata
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def parse_date(date_value):
|
|
82
|
+
"""Parse date from string DD-MM-YYYY format."""
|
|
83
|
+
if isinstance(date_value, str):
|
|
84
|
+
return datetime.strptime(date_value, "%d-%m-%Y").date()
|
|
85
|
+
return date_value
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def calculate_priority(tutorial, today):
|
|
89
|
+
"""
|
|
90
|
+
Calculate quiz priority score. Higher = more urgent.
|
|
91
|
+
|
|
92
|
+
Priority logic:
|
|
93
|
+
1. No last_quizzed = never assessed, use created date + urgency bonus
|
|
94
|
+
2. Has last_quizzed = calculate days overdue based on score interval
|
|
95
|
+
3. Missing created date = assume max urgency (100)
|
|
96
|
+
"""
|
|
97
|
+
score = tutorial.get("understanding_score") or 0 # Default to 0 if null
|
|
98
|
+
ideal_interval = INTERVALS.get(score, INTERVALS[5])
|
|
99
|
+
|
|
100
|
+
last_quizzed = tutorial.get("last_quizzed")
|
|
101
|
+
|
|
102
|
+
if not last_quizzed:
|
|
103
|
+
# Never quizzed - need baseline assessment
|
|
104
|
+
created = tutorial.get("created")
|
|
105
|
+
if created:
|
|
106
|
+
created = parse_date(created)
|
|
107
|
+
days_since_created = (today - created).days
|
|
108
|
+
# Bonus ensures never-quizzed items surface early
|
|
109
|
+
return days_since_created / ideal_interval + 10
|
|
110
|
+
# No date info at all - max urgency
|
|
111
|
+
return 100
|
|
112
|
+
|
|
113
|
+
# Normal case: has been quizzed before
|
|
114
|
+
last_quizzed = parse_date(last_quizzed)
|
|
115
|
+
days_since_quiz = (today - last_quizzed).days
|
|
116
|
+
days_overdue = days_since_quiz - ideal_interval
|
|
117
|
+
|
|
118
|
+
return days_overdue / ideal_interval
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def main():
|
|
122
|
+
parser = argparse.ArgumentParser(
|
|
123
|
+
description="Prioritize tutorials for quizzing based on spaced repetition"
|
|
124
|
+
)
|
|
125
|
+
parser.add_argument(
|
|
126
|
+
"--tutorials-dir",
|
|
127
|
+
help="Path to tutorials directory (defaults to ~/coding-tutor-tutorials/)",
|
|
128
|
+
default=None,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
args = parser.parse_args()
|
|
132
|
+
|
|
133
|
+
today = datetime.now().date()
|
|
134
|
+
tutorials = []
|
|
135
|
+
|
|
136
|
+
if args.tutorials_dir:
|
|
137
|
+
tutorials_path = Path(args.tutorials_dir)
|
|
138
|
+
else:
|
|
139
|
+
tutorials_path = get_tutorials_directory()
|
|
140
|
+
|
|
141
|
+
if not tutorials_path.exists():
|
|
142
|
+
print("No tutorials found in ~/coding-tutor-tutorials/")
|
|
143
|
+
return
|
|
144
|
+
|
|
145
|
+
for filepath in tutorials_path.glob("*.md"):
|
|
146
|
+
if filepath.name == "learner_profile.md":
|
|
147
|
+
continue
|
|
148
|
+
metadata = parse_frontmatter(filepath)
|
|
149
|
+
if metadata:
|
|
150
|
+
metadata["priority"] = calculate_priority(metadata, today)
|
|
151
|
+
tutorials.append(metadata)
|
|
152
|
+
|
|
153
|
+
if not tutorials:
|
|
154
|
+
print("No tutorials found")
|
|
155
|
+
return
|
|
156
|
+
|
|
157
|
+
# Sort by priority (highest first = most urgent)
|
|
158
|
+
tutorials.sort(key=lambda t: t["priority"], reverse=True)
|
|
159
|
+
|
|
160
|
+
print("=" * 60)
|
|
161
|
+
print("QUIZ PRIORITY (most urgent first)")
|
|
162
|
+
print("=" * 60)
|
|
163
|
+
print()
|
|
164
|
+
|
|
165
|
+
for i, t in enumerate(tutorials, 1):
|
|
166
|
+
score = t.get("understanding_score") or 0
|
|
167
|
+
last_q = t.get("last_quizzed")
|
|
168
|
+
concepts = t.get("concepts", [])
|
|
169
|
+
if isinstance(concepts, list):
|
|
170
|
+
concepts_str = ", ".join(concepts[:2]) # First 2 concepts
|
|
171
|
+
else:
|
|
172
|
+
concepts_str = str(concepts)
|
|
173
|
+
|
|
174
|
+
# Calculate days ago
|
|
175
|
+
if last_q:
|
|
176
|
+
last_q = parse_date(last_q)
|
|
177
|
+
days_ago = (today - last_q).days
|
|
178
|
+
last_quizzed_str = f"{days_ago} days ago"
|
|
179
|
+
else:
|
|
180
|
+
last_quizzed_str = "never"
|
|
181
|
+
|
|
182
|
+
print(f"{i}. {concepts_str}")
|
|
183
|
+
print(f" understanding_score: {score}/10")
|
|
184
|
+
print(f" last_quizzed: {last_quizzed_str}")
|
|
185
|
+
print(f" file: {t['filepath']}")
|
|
186
|
+
print()
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
if __name__ == "__main__":
|
|
190
|
+
main()
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Set up the central tutorials repository for coding-tutor.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
python setup_tutorials.py
|
|
7
|
+
python setup_tutorials.py --create-github-repo
|
|
8
|
+
|
|
9
|
+
Creates ~/coding-tutor-tutorials/ if it doesn't exist, initializes git,
|
|
10
|
+
and optionally creates a private GitHub repository.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import argparse
|
|
14
|
+
import subprocess
|
|
15
|
+
import sys
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def get_tutorials_repo_path():
|
|
20
|
+
"""Get the path for the tutorials repo (~/coding-tutor-tutorials/)."""
|
|
21
|
+
return Path.home() / "coding-tutor-tutorials"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
README_CONTENT = """# Coding Tutor - My Learning Journey
|
|
25
|
+
|
|
26
|
+
This repository contains my personalized coding tutorials created with the [coding-tutor](https://github.com/nityeshaga/antigravity-essentials) Antigravity plugin.
|
|
27
|
+
|
|
28
|
+
## What's Here
|
|
29
|
+
|
|
30
|
+
- **Tutorials**: Markdown files with concepts learned from various codebases
|
|
31
|
+
- **Learner Profile**: My background, goals, and learning preferences
|
|
32
|
+
- **Quiz History**: Spaced repetition quiz results tracking my progress
|
|
33
|
+
|
|
34
|
+
## How It Works
|
|
35
|
+
|
|
36
|
+
Each tutorial includes:
|
|
37
|
+
- `source_repo`: Which codebase the examples come from
|
|
38
|
+
- `concepts`: What concepts are covered
|
|
39
|
+
- `understanding_score`: How well I've retained this (1-10, updated via quizzes)
|
|
40
|
+
- Real code examples from actual projects I'm learning from
|
|
41
|
+
|
|
42
|
+
This is my personal learning trail - tutorials are written specifically for me, using my vocabulary and building on my existing knowledge.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def setup_tutorials_repo(create_github=False):
|
|
47
|
+
"""
|
|
48
|
+
Set up the central tutorials repository.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
tuple: (success: bool, message: str)
|
|
52
|
+
"""
|
|
53
|
+
repo_path = get_tutorials_repo_path()
|
|
54
|
+
|
|
55
|
+
if repo_path.exists():
|
|
56
|
+
return True, f"Tutorials repo already exists at {repo_path.resolve()}"
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
# Create directory
|
|
60
|
+
repo_path.mkdir(parents=True)
|
|
61
|
+
|
|
62
|
+
# Initialize git
|
|
63
|
+
subprocess.run(["git", "init"], cwd=repo_path, check=True, capture_output=True)
|
|
64
|
+
|
|
65
|
+
# Create README
|
|
66
|
+
readme_path = repo_path / "README.md"
|
|
67
|
+
readme_path.write_text(README_CONTENT)
|
|
68
|
+
|
|
69
|
+
# Create .gitignore
|
|
70
|
+
gitignore_path = repo_path / ".gitignore"
|
|
71
|
+
gitignore_path.write_text(".DS_Store\n*.swp\n*.swo\n")
|
|
72
|
+
|
|
73
|
+
# Initial commit
|
|
74
|
+
subprocess.run(
|
|
75
|
+
["git", "add", "-A"], cwd=repo_path, check=True, capture_output=True
|
|
76
|
+
)
|
|
77
|
+
subprocess.run(
|
|
78
|
+
["git", "commit", "-m", "Initial commit: coding learning journey"],
|
|
79
|
+
cwd=repo_path,
|
|
80
|
+
check=True,
|
|
81
|
+
capture_output=True,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
message = f"Created tutorials repo at {repo_path.resolve()}"
|
|
85
|
+
|
|
86
|
+
# Optionally create GitHub repo
|
|
87
|
+
if create_github:
|
|
88
|
+
result = subprocess.run(
|
|
89
|
+
[
|
|
90
|
+
"gh",
|
|
91
|
+
"repo",
|
|
92
|
+
"create",
|
|
93
|
+
"coding-tutor-tutorials",
|
|
94
|
+
"--private",
|
|
95
|
+
"--source=.",
|
|
96
|
+
"--push",
|
|
97
|
+
],
|
|
98
|
+
cwd=repo_path,
|
|
99
|
+
capture_output=True,
|
|
100
|
+
text=True,
|
|
101
|
+
)
|
|
102
|
+
if result.returncode == 0:
|
|
103
|
+
message += "\nCreated private GitHub repo and pushed"
|
|
104
|
+
else:
|
|
105
|
+
message += f"\nNote: Could not create GitHub repo: {result.stderr}"
|
|
106
|
+
|
|
107
|
+
return True, message
|
|
108
|
+
|
|
109
|
+
except Exception as e:
|
|
110
|
+
return False, f"Error setting up tutorials repo: {e}"
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def main():
|
|
114
|
+
parser = argparse.ArgumentParser(
|
|
115
|
+
description="Set up the central tutorials repository for coding-tutor"
|
|
116
|
+
)
|
|
117
|
+
parser.add_argument(
|
|
118
|
+
"--create-github-repo",
|
|
119
|
+
action="store_true",
|
|
120
|
+
help="Also create a private GitHub repository",
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
args = parser.parse_args()
|
|
124
|
+
|
|
125
|
+
success, message = setup_tutorials_repo(create_github=args.create_github_repo)
|
|
126
|
+
print(message)
|
|
127
|
+
|
|
128
|
+
return 0 if success else 1
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
if __name__ == "__main__":
|
|
132
|
+
sys.exit(main())
|