-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup_workspace.py
More file actions
executable file
·342 lines (284 loc) · 12.2 KB
/
setup_workspace.py
File metadata and controls
executable file
·342 lines (284 loc) · 12.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
#!/usr/bin/env python3
"""
Clean, modular workspace setup for Graph My Mind.
Creates a workspace with event capture hooks and knowledge tracking files.
"""
import os
import shutil
import json
import argparse
import subprocess
from pathlib import Path
# Get the directory containing this script for template access
SCRIPT_DIR = Path(__file__).parent
TEMPLATES_DIR = SCRIPT_DIR / 'templates'
def load_template(template_name, replacements=None):
"""Load a template file and apply replacements."""
template_path = TEMPLATES_DIR / template_name
if not template_path.exists():
raise FileNotFoundError(f"Template {template_name} not found in {TEMPLATES_DIR}")
content = template_path.read_text()
if replacements:
for key, value in replacements.items():
content = content.replace(key, value)
return content
def create_claude_directory(workspace_path, topic=None):
"""Create .claude directory with hooks, commands, and settings."""
claude_dir = workspace_path / '.claude'
claude_dir.mkdir(exist_ok=True)
hooks_dir = claude_dir / 'hooks'
hooks_dir.mkdir(exist_ok=True)
commands_dir = claude_dir / 'commands'
commands_dir.mkdir(exist_ok=True)
created_files = []
# Create capture_events.py hook
hook_content = load_template('capture_events.py')
hook_path = hooks_dir / 'capture_events.py'
hook_path.write_text(hook_content)
hook_path.chmod(0o755)
created_files.append(f"Hook: {hook_path.relative_to(workspace_path)}")
# Create settings.json
settings_content = load_template('settings.json')
settings_path = claude_dir / 'settings.json'
settings_path.write_text(settings_content)
created_files.append(f"Settings: {settings_path.relative_to(workspace_path)}")
# Create study::init command
study_content = load_template('study_init.md')
study_path = commands_dir / 'study::init.md'
study_path.write_text(study_content)
created_files.append(f"Command: {study_path.relative_to(workspace_path)}")
# Create CLAUDE.md
claude_md_content = load_template('claude_md.md')
if topic:
claude_md_content = claude_md_content.replace(
"# Pedagogy Mode - Learning System",
f"# Pedagogy Mode - Learning System\n\n**Current Topic**: {topic}"
)
claude_md_path = claude_dir / 'CLAUDE.md'
claude_md_path.write_text(claude_md_content)
created_files.append(f"Instructions: {claude_md_path.relative_to(workspace_path)}")
return created_files
def create_knowledge_files(workspace_path, topic=None):
"""Create initial knowledge tracking files."""
created_files = []
# Create kb directory
kb_dir = workspace_path / 'kb'
kb_dir.mkdir(exist_ok=True)
created_files.append(f"Knowledge base: {kb_dir.relative_to(workspace_path)}/")
# Create claude_knowledge_graph.mmd
if topic:
claude_graph_content = f"""graph TD
%% Knowledge structure will be built during research
%% Focus: Domain concepts and relationships, not workflow
"""
else:
claude_graph_content = """graph TD
%% Will be populated with actual domain knowledge
%% Focus: What to learn, not how to learn it
"""
claude_graph_path = workspace_path / 'claude_knowledge_graph.mmd'
claude_graph_path.write_text(claude_graph_content)
created_files.append(f"Claude knowledge: {claude_graph_path.relative_to(workspace_path)}")
user_graph_content = """graph TD
%% Tracks user's actual knowledge and understanding
%% Not learning intentions or workflow states
"""
user_graph_path = workspace_path / 'user_knowledge_graph.mmd'
user_graph_path.write_text(user_graph_content)
created_files.append(f"User knowledge: {user_graph_path.relative_to(workspace_path)}")
# Create user.json
user_data = {
"name": "",
"learning_goals": [topic] if topic else [],
"current_topic": topic or "",
"knowledge_level": "beginner",
"learning_style": "visual",
"progress": {
"concepts_learned": [],
"concepts_in_progress": [],
"last_session": "",
"total_sessions": 0
},
"preferences": {
"detail_level": "moderate",
"pace": "adaptive",
"examples": True
},
"workflow_state": {
"current_phase": "setup" if not topic else "ready_for_research",
"next_action": "Start research" if topic else "Define learning topic",
"research_status": "pending" if topic else "not_started",
"teaching_status": "not_started",
"last_activity": "workspace_created",
"session_goals": []
},
"learning_journey": {
"started_at": "",
"milestones": [],
"challenges_faced": [],
"breakthroughs": [],
"reflection_notes": []
}
}
user_json_path = workspace_path / 'user.json'
user_json_path.write_text(json.dumps(user_data, indent=2))
created_files.append(f"User profile: {user_json_path.relative_to(workspace_path)}")
return created_files
def setup_workspace(directory_name, topic=None):
"""Set up a complete learning workspace."""
print(f"Setting up pedagogy workspace: workspaces/{directory_name}")
if topic:
print(f"Learning topic: {topic}")
# Create main directory inside workspaces folder
workspace_path = Path('workspaces') / directory_name
workspace_path.mkdir(parents=True, exist_ok=True)
created_files = []
print(" Creating Claude Code configuration...")
claude_files = create_claude_directory(workspace_path, topic)
created_files.extend(claude_files)
print(" Creating knowledge tracking files...")
knowledge_files = create_knowledge_files(workspace_path, topic)
created_files.extend(knowledge_files)
return workspace_path, created_files
def verify_setup(workspace_path):
"""Verify that all components were created correctly."""
required_files = [
'.claude/hooks/capture_events.py',
'.claude/commands/study::init.md',
'.claude/settings.json',
'.claude/CLAUDE.md',
'claude_knowledge_graph.mmd',
'user_knowledge_graph.mmd',
'user.json',
'kb'
]
missing_files = []
for file_path in required_files:
full_path = workspace_path / file_path
if not full_path.exists():
missing_files.append(file_path)
return len(missing_files) == 0, missing_files
def test_hook_execution(workspace_path):
"""Test that the hook executes properly."""
try:
import subprocess
hook_path = workspace_path / '.claude/hooks/capture_events.py'
test_input = '{"session_id":"test-setup"}'
result = subprocess.run(
['python3', str(hook_path)],
input=test_input,
capture_output=True,
text=True,
timeout=5
)
return result.returncode == 0, result.stdout, result.stderr
except Exception as e:
return False, "", str(e)
def main():
parser = argparse.ArgumentParser(
description='Set up a pedagogy learning workspace with event capture and knowledge tracking'
)
parser.add_argument(
'-d', '--directory',
default='learning-workspace',
help='Directory name for the workspace (default: learning-workspace)'
)
parser.add_argument(
'-t', '--topic',
help='Learning topic to focus on (optional)'
)
args = parser.parse_args()
try:
# Check if templates directory exists
if not TEMPLATES_DIR.exists():
print(f"Error: Templates directory not found at {TEMPLATES_DIR}")
print("Make sure you're running this script from the long_context_pedagogy directory")
return 1
# Set up workspace
workspace_path, created_files = setup_workspace(args.directory, args.topic)
print(f"\n✅ Workspace setup complete: {workspace_path.absolute()}")
print(f"\nCreated files:")
for file_info in created_files:
print(f" ✓ {file_info}")
# Verify setup
print(f"\nVerifying setup:")
setup_ok, missing_files = verify_setup(workspace_path)
if setup_ok:
print(" ✓ All required files created")
else:
print(" ✗ Missing files:")
for missing in missing_files:
print(f" - {missing}")
return 1
# Test hook execution
print(f"\nTesting hook execution:")
hook_ok, stdout, stderr = test_hook_execution(workspace_path)
if hook_ok:
print(" ✓ Hook execution successful")
else:
print(" ✗ Hook execution failed")
if stderr:
print(f" Error: {stderr}")
return 1
# Automatically trigger research if topic is provided
if args.topic:
print(f"\n🚀 Automatically starting research for '{args.topic}'...")
print(f"⏱️ IMPORTANT: Comprehensive research takes 20-30 minutes to complete")
print(f"⏱️ This includes multi-agent analysis and knowledge graph synthesis")
print(f"⏱️ The process will run until completion - please be patient!")
print(f"📊 Monitor progress at: http://localhost:3001")
try:
# Change to workspace directory and run Claude
study_prompt = f"/study::init {args.topic}"
claude_cmd = [
'claude',
'-p', study_prompt,
'--dangerously-skip-permissions'
]
print(f"\n Running: {' '.join(claude_cmd)}")
print(f" In directory: {workspace_path.absolute()}")
print(f" Starting comprehensive research... (this will take 20-30 minutes)")
# Run without timeout to allow full research completion
result = subprocess.run(
claude_cmd,
cwd=workspace_path,
capture_output=True,
text=True
# No timeout - let research complete naturally
)
if result.returncode == 0:
print(" ✅ Comprehensive research completed successfully!")
print(" 📊 View results at: http://localhost:3001")
print(" 🎓 Knowledge graphs have been populated with research findings")
else:
print(" ⚠️ Research completed with issues:")
if result.stderr:
print(f" {result.stderr}")
print(" 📊 Check http://localhost:3001 for partial results")
print(" You can re-run research manually:")
print(f" cd workspaces/{args.directory}")
print(f" claude -p '/study::init {args.topic}'")
except Exception as e:
print(f" ⚠️ Could not start research: {e}")
print(" You can manually start research:")
print(f" cd workspaces/{args.directory}")
print(f" claude -p '/study::init {args.topic}'")
print(f" Expected duration: 20-30 minutes for comprehensive research")
# Success message
print(f"\n" + "="*60)
print(f"🎓 Pedagogy workspace ready!")
print(f"="*60)
if not args.topic:
print(f"\nTo start learning:")
print(f" cd workspaces/{args.directory}")
print(f" claude -p '/study::init your-topic-here'")
print(f"\nTo monitor progress:")
print(f" # Start the pedagogy server first")
print(f" npm start")
print(f" # Then open: http://localhost:3001")
return 0
except Exception as e:
print(f"Error setting up workspace: {e}")
return 1
if __name__ == '__main__':
exit(main())