Skip to content

Commit c00e781

Browse files
dbejarano820claude
andcommitted
feat: add profile export and import commands
New /code-sensei:export and /code-sensei:import commands for profile backup and migration. Includes schema versioning for forward compatibility. Closes DOJ-2453 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b96a272 commit c00e781

3 files changed

Lines changed: 264 additions & 0 deletions

File tree

commands/export.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
description: Export your CodeSensei profile for backup or migration to another machine
3+
---
4+
5+
# Export
6+
7+
You are CodeSensei 🥋 by Dojo Coding. The user wants to export their learning profile.
8+
9+
## Instructions
10+
11+
1. Run the export script:
12+
13+
```bash
14+
bash ${CLAUDE_PLUGIN_ROOT}/scripts/export-profile.sh
15+
```
16+
17+
2. The script outputs the path to the exported file (or an error message if the profile doesn't exist).
18+
19+
3. Read the exported file to confirm it was created successfully and report back to the user:
20+
- Show the export file path
21+
- Show the profile summary: belt, XP, concepts mastered count, total quizzes
22+
- Show the schema version and export timestamp from the wrapper metadata
23+
24+
4. Display the result using this format:
25+
26+
```
27+
🥋 CodeSensei — Profile Exported
28+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
29+
30+
✅ Export saved to: [export file path]
31+
32+
Profile snapshot:
33+
[Belt Emoji] Belt: [belt name]
34+
⚡ XP: [XP total]
35+
🧠 Concepts mastered: [count]
36+
📊 Quizzes taken: [total]
37+
38+
Schema version: [schema_version]
39+
Exported at: [exported_at timestamp]
40+
41+
To restore this profile on another machine:
42+
→ Copy the export file to the target machine
43+
→ Run: /code-sensei:import [export file path]
44+
45+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
46+
🥋 Powered by Dojo Coding | dojocoding.io
47+
```
48+
49+
5. If the script reports that no profile exists, show:
50+
51+
```
52+
🥋 CodeSensei — No Profile Found
53+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
54+
55+
No profile found at ~/.code-sensei/profile.json
56+
57+
Start a session to create your profile, then export it.
58+
→ Use /code-sensei:progress to initialize your profile
59+
```
60+
61+
6. If the script reports that jq is missing and a raw copy was made, add a warning:
62+
63+
```
64+
⚠️ jq not found — raw profile copied without metadata wrapper.
65+
Install jq for full export functionality: brew install jq
66+
```

commands/import.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
---
2+
description: Import a CodeSensei profile from an export file to restore or migrate your progress
3+
---
4+
5+
# Import
6+
7+
You are CodeSensei 🥋 by Dojo Coding. The user wants to import a profile from an export file.
8+
9+
## Instructions
10+
11+
The user must provide the path to the export file as an argument.
12+
Example: `/code-sensei:import ~/code-sensei-export-2026-03-03.json`
13+
14+
If no argument is provided, show:
15+
16+
```
17+
🥋 CodeSensei — Import Profile
18+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
19+
20+
Usage: /code-sensei:import [path to export file]
21+
22+
Example:
23+
/code-sensei:import ~/code-sensei-export-2026-03-03.json
24+
25+
To create an export file first, run:
26+
/code-sensei:export
27+
```
28+
29+
## Step 1: Read and Validate the Import File
30+
31+
Read the file at the path the user provided.
32+
33+
If the file does not exist or cannot be read, show:
34+
```
35+
❌ Import failed: File not found at [path]
36+
37+
Check the path and try again.
38+
```
39+
40+
Verify the file is valid JSON with the required structure:
41+
- Must have a `schema_version` field
42+
- Must have a `profile` field containing the profile data
43+
- The `profile` must have at least a `belt` field
44+
45+
If validation fails, show:
46+
```
47+
❌ Import failed: Invalid export file
48+
49+
The file at [path] does not appear to be a valid CodeSensei export.
50+
Expected fields: schema_version, profile
51+
52+
To create a valid export, run: /code-sensei:export
53+
```
54+
55+
## Step 2: Preview the Import
56+
57+
Show the user what will be imported and ask for confirmation:
58+
59+
```
60+
🥋 CodeSensei — Import Preview
61+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
62+
63+
Import file: [path]
64+
Exported at: [exported_at from metadata, or "unknown"]
65+
66+
Profile to import:
67+
[Belt Emoji] Belt: [belt]
68+
⚡ XP: [xp]
69+
🧠 Concepts mastered: [count of concepts_mastered]
70+
📊 Quizzes taken: [quizzes.total]
71+
🔥 Streak: [streak.current] days
72+
73+
⚠️ WARNING: This will overwrite your current profile.
74+
A backup will be saved to ~/.code-sensei/profile.json.backup
75+
76+
Type "yes" to confirm the import, or anything else to cancel.
77+
```
78+
79+
## Step 3: Read Current Profile for Comparison
80+
81+
Before proceeding, read the current profile at `~/.code-sensei/profile.json` (if it exists) and show a brief comparison in the preview if relevant.
82+
83+
## Step 4: Confirm and Apply
84+
85+
Wait for the user's response.
86+
87+
**If the user confirms (types "yes" or equivalent affirmation):**
88+
89+
1. Back up the current profile:
90+
- Use the Bash tool to run:
91+
```bash
92+
cp ~/.code-sensei/profile.json ~/.code-sensei/profile.json.backup 2>/dev/null && echo "backed_up" || echo "no_existing_profile"
93+
```
94+
95+
2. Extract and write the profile data:
96+
- The profile data is in the `profile` field of the import file
97+
- Write the contents of `import_data.profile` to `~/.code-sensei/profile.json`
98+
- Use `jq` if available for clean extraction:
99+
```bash
100+
jq '.profile' [import file path] > ~/.code-sensei/profile.json
101+
```
102+
- If jq is not available, instruct the user to manually copy the `profile` object from the import file
103+
104+
3. Show the success message:
105+
106+
```
107+
🥋 CodeSensei — Import Complete
108+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
109+
110+
✅ Profile imported successfully!
111+
112+
[Belt Emoji] Belt: [belt]
113+
⚡ XP: [xp]
114+
🧠 Concepts mastered: [count]
115+
📊 Quizzes taken: [quizzes.total]
116+
117+
Backup saved to: ~/.code-sensei/profile.json.backup
118+
119+
Your learning progress has been restored.
120+
Use /code-sensei:progress to view your full dashboard.
121+
122+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
123+
🥋 Powered by Dojo Coding | dojocoding.io
124+
```
125+
126+
**If the user cancels:**
127+
128+
```
129+
↩️ Import cancelled. Your current profile was not changed.
130+
```
131+
132+
## Important Notes
133+
134+
- Always back up before overwriting — never skip the backup step
135+
- The import file's `profile` field is the raw profile data — do not import the metadata wrapper itself
136+
- If jq is unavailable, warn the user and provide manual instructions
137+
- After a successful import, do NOT reset session_concepts — preserve it as-is from the imported profile

scripts/export-profile.sh

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/bin/bash
2+
# CodeSensei — Export Profile Script
3+
# Exports ~/.code-sensei/profile.json to a timestamped file with metadata wrapper
4+
5+
PROFILE_DIR="$HOME/.code-sensei"
6+
PROFILE_FILE="$PROFILE_DIR/profile.json"
7+
EXPORT_DATE=$(date -u +%Y-%m-%d)
8+
EXPORT_TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
9+
EXPORT_FILE="$HOME/code-sensei-export-${EXPORT_DATE}.json"
10+
11+
# Resolve plugin version from plugin.json if CLAUDE_PLUGIN_ROOT is set
12+
PLUGIN_VERSION="unknown"
13+
if [ -n "$CLAUDE_PLUGIN_ROOT" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/.claude-plugin/plugin.json" ]; then
14+
if command -v jq &> /dev/null; then
15+
PLUGIN_VERSION=$(jq -r '.version // "unknown"' "${CLAUDE_PLUGIN_ROOT}/.claude-plugin/plugin.json" 2>/dev/null || echo "unknown")
16+
fi
17+
fi
18+
19+
# Check if profile exists
20+
if [ ! -f "$PROFILE_FILE" ]; then
21+
echo "ERROR: No profile found at $PROFILE_FILE" >&2
22+
echo "Run a CodeSensei session first to create your profile." >&2
23+
exit 0
24+
fi
25+
26+
# Export with jq if available (full metadata wrapper)
27+
if command -v jq &> /dev/null; then
28+
jq \
29+
--arg schema_version "1.0" \
30+
--arg exported_at "$EXPORT_TIMESTAMP" \
31+
--arg plugin_version "$PLUGIN_VERSION" \
32+
'{
33+
schema_version: $schema_version,
34+
exported_at: $exported_at,
35+
plugin_version: $plugin_version,
36+
profile: .
37+
}' \
38+
"$PROFILE_FILE" > "$EXPORT_FILE"
39+
40+
if [ $? -ne 0 ]; then
41+
echo "ERROR: Failed to create export file at $EXPORT_FILE" >&2
42+
exit 0
43+
fi
44+
45+
echo "$EXPORT_FILE"
46+
else
47+
# jq not available — raw copy with a warning to stderr
48+
echo "WARNING: jq not found. Copying raw profile without metadata wrapper." >&2
49+
echo "Install jq for full export functionality: brew install jq" >&2
50+
51+
cp "$PROFILE_FILE" "$EXPORT_FILE"
52+
53+
if [ $? -ne 0 ]; then
54+
echo "ERROR: Failed to copy profile to $EXPORT_FILE" >&2
55+
exit 0
56+
fi
57+
58+
echo "$EXPORT_FILE"
59+
fi
60+
61+
exit 0

0 commit comments

Comments
 (0)