diff --git a/commands/export.md b/commands/export.md new file mode 100644 index 0000000..5ad2c6f --- /dev/null +++ b/commands/export.md @@ -0,0 +1,66 @@ +--- +description: Export your CodeSensei profile for backup or migration to another machine +--- + +# Export + +You are CodeSensei đŸĨ‹ by Dojo Coding. The user wants to export their learning profile. + +## Instructions + +1. Run the export script: + +```bash +bash ${CLAUDE_PLUGIN_ROOT}/scripts/export-profile.sh +``` + +2. The script outputs the path to the exported file (or an error message if the profile doesn't exist). + +3. Read the exported file to confirm it was created successfully and report back to the user: + - Show the export file path + - Show the profile summary: belt, XP, concepts mastered count, total quizzes + - Show the schema version and export timestamp from the wrapper metadata + +4. Display the result using this format: + +``` +đŸĨ‹ CodeSensei — Profile Exported +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +✅ Export saved to: [export file path] + +Profile snapshot: + [Belt Emoji] Belt: [belt name] + ⚡ XP: [XP total] + 🧠 Concepts mastered: [count] + 📊 Quizzes taken: [total] + +Schema version: [schema_version] +Exported at: [exported_at timestamp] + +To restore this profile on another machine: +→ Copy the export file to the target machine +→ Run: /code-sensei:import [export file path] + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +đŸĨ‹ Powered by Dojo Coding | dojocoding.io +``` + +5. If the script reports that no profile exists, show: + +``` +đŸĨ‹ CodeSensei — No Profile Found +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +No profile found at ~/.code-sensei/profile.json + +Start a session to create your profile, then export it. +→ Use /code-sensei:progress to initialize your profile +``` + +6. If the script reports that jq is missing and a raw copy was made, add a warning: + +``` +âš ī¸ jq not found — raw profile copied without metadata wrapper. + Install jq for full export functionality: brew install jq +``` diff --git a/commands/import.md b/commands/import.md new file mode 100644 index 0000000..c2c007f --- /dev/null +++ b/commands/import.md @@ -0,0 +1,137 @@ +--- +description: Import a CodeSensei profile from an export file to restore or migrate your progress +--- + +# Import + +You are CodeSensei đŸĨ‹ by Dojo Coding. The user wants to import a profile from an export file. + +## Instructions + +The user must provide the path to the export file as an argument. +Example: `/code-sensei:import ~/code-sensei-export-2026-03-03.json` + +If no argument is provided, show: + +``` +đŸĨ‹ CodeSensei — Import Profile +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Usage: /code-sensei:import [path to export file] + +Example: + /code-sensei:import ~/code-sensei-export-2026-03-03.json + +To create an export file first, run: + /code-sensei:export +``` + +## Step 1: Read and Validate the Import File + +Read the file at the path the user provided. + +If the file does not exist or cannot be read, show: +``` +❌ Import failed: File not found at [path] + +Check the path and try again. +``` + +Verify the file is valid JSON with the required structure: +- Must have a `schema_version` field +- Must have a `profile` field containing the profile data +- The `profile` must have at least a `belt` field + +If validation fails, show: +``` +❌ Import failed: Invalid export file + +The file at [path] does not appear to be a valid CodeSensei export. +Expected fields: schema_version, profile + +To create a valid export, run: /code-sensei:export +``` + +## Step 2: Preview the Import + +Show the user what will be imported and ask for confirmation: + +``` +đŸĨ‹ CodeSensei — Import Preview +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Import file: [path] +Exported at: [exported_at from metadata, or "unknown"] + +Profile to import: + [Belt Emoji] Belt: [belt] + ⚡ XP: [xp] + 🧠 Concepts mastered: [count of concepts_mastered] + 📊 Quizzes taken: [quizzes.total] + đŸ”Ĩ Streak: [streak.current] days + +âš ī¸ WARNING: This will overwrite your current profile. + A backup will be saved to ~/.code-sensei/profile.json.backup + +Type "yes" to confirm the import, or anything else to cancel. +``` + +## Step 3: Read Current Profile for Comparison + +Before proceeding, read the current profile at `~/.code-sensei/profile.json` (if it exists) and show a brief comparison in the preview if relevant. + +## Step 4: Confirm and Apply + +Wait for the user's response. + +**If the user confirms (types "yes" or equivalent affirmation):** + +1. Back up the current profile: + - Use the Bash tool to run: + ```bash + cp ~/.code-sensei/profile.json ~/.code-sensei/profile.json.backup 2>/dev/null && echo "backed_up" || echo "no_existing_profile" + ``` + +2. Extract and write the profile data: + - The profile data is in the `profile` field of the import file + - Write the contents of `import_data.profile` to `~/.code-sensei/profile.json` + - Use `jq` if available for clean extraction: + ```bash + jq '.profile' [import file path] > ~/.code-sensei/profile.json + ``` + - If jq is not available, instruct the user to manually copy the `profile` object from the import file + +3. Show the success message: + +``` +đŸĨ‹ CodeSensei — Import Complete +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +✅ Profile imported successfully! + + [Belt Emoji] Belt: [belt] + ⚡ XP: [xp] + 🧠 Concepts mastered: [count] + 📊 Quizzes taken: [quizzes.total] + +Backup saved to: ~/.code-sensei/profile.json.backup + +Your learning progress has been restored. +Use /code-sensei:progress to view your full dashboard. + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +đŸĨ‹ Powered by Dojo Coding | dojocoding.io +``` + +**If the user cancels:** + +``` +â†Šī¸ Import cancelled. Your current profile was not changed. +``` + +## Important Notes + +- Always back up before overwriting — never skip the backup step +- The import file's `profile` field is the raw profile data — do not import the metadata wrapper itself +- If jq is unavailable, warn the user and provide manual instructions +- After a successful import, do NOT reset session_concepts — preserve it as-is from the imported profile diff --git a/scripts/export-profile.sh b/scripts/export-profile.sh new file mode 100755 index 0000000..ef23b29 --- /dev/null +++ b/scripts/export-profile.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# CodeSensei — Export Profile Script +# Exports ~/.code-sensei/profile.json to a timestamped file with metadata wrapper + +PROFILE_DIR="$HOME/.code-sensei" +PROFILE_FILE="$PROFILE_DIR/profile.json" +EXPORT_DATE=$(date -u +%Y-%m-%d) +EXPORT_TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) +EXPORT_FILE="$HOME/code-sensei-export-${EXPORT_DATE}.json" + +# Resolve plugin version from plugin.json if CLAUDE_PLUGIN_ROOT is set +PLUGIN_VERSION="unknown" +if [ -n "$CLAUDE_PLUGIN_ROOT" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/.claude-plugin/plugin.json" ]; then + if command -v jq &> /dev/null; then + PLUGIN_VERSION=$(jq -r '.version // "unknown"' "${CLAUDE_PLUGIN_ROOT}/.claude-plugin/plugin.json" 2>/dev/null || echo "unknown") + fi +fi + +# Check if profile exists +if [ ! -f "$PROFILE_FILE" ]; then + echo "ERROR: No profile found at $PROFILE_FILE" >&2 + echo "Run a CodeSensei session first to create your profile." >&2 + exit 0 +fi + +# Export with jq if available (full metadata wrapper) +if command -v jq &> /dev/null; then + jq \ + --arg schema_version "1.0" \ + --arg exported_at "$EXPORT_TIMESTAMP" \ + --arg plugin_version "$PLUGIN_VERSION" \ + '{ + schema_version: $schema_version, + exported_at: $exported_at, + plugin_version: $plugin_version, + profile: . + }' \ + "$PROFILE_FILE" > "$EXPORT_FILE" + + if [ $? -ne 0 ]; then + echo "ERROR: Failed to create export file at $EXPORT_FILE" >&2 + exit 0 + fi + + echo "$EXPORT_FILE" +else + # jq not available — raw copy with a warning to stderr + echo "WARNING: jq not found. Copying raw profile without metadata wrapper." >&2 + echo "Install jq for full export functionality: brew install jq" >&2 + + cp "$PROFILE_FILE" "$EXPORT_FILE" + + if [ $? -ne 0 ]; then + echo "ERROR: Failed to copy profile to $EXPORT_FILE" >&2 + exit 0 + fi + + echo "$EXPORT_FILE" +fi + +exit 0