From project-toolkit
Migrates markdown session logs to JSON format via Python CLI. Use for PRs with embedded Markdown logs, batch historical conversions, or fixing regex-based validation failures.
npx claudepluginhub rjmurillo/ai-agents --plugin project-toolkitThis skill uses the workspace's default tool permissions.
Converts markdown session logs to JSON format for deterministic validation.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Converts markdown session logs to JSON format for deterministic validation.
# Migrate single file
python3 .claude/skills/session-migration/scripts/convert_session_to_json.py ".agents/sessions/2026-01-09-session-385.md"
# Migrate all sessions in directory
python3 .claude/skills/session-migration/scripts/convert_session_to_json.py ".agents/sessions/"
# Dry run to preview changes
python3 .claude/skills/session-migration/scripts/convert_session_to_json.py ".agents/sessions/" --dry-run
# Force overwrite existing JSON
python3 .claude/skills/session-migration/scripts/convert_session_to_json.py ".agents/sessions/" --force
Use this skill when:
migrate session logs - Convert markdown to JSONconvert sessions to JSON - Format migrationPR has old markdown sessions - In-flight PR migrationsession validation failing - Regex issues with markdown formatbatch migrate sessions - Historical log conversionUse this skill when:
Use session-init instead when:
Use session-log-fixer instead when:
Markdown session logs required fragile regex patterns to validate:
**Branch**: vs Branch: vs Starting Branch:JSON provides:
JSON sessions follow the schema at:
.agents/schemas/session-log.schema.json
JSON sessions are validated by:
scripts/validate_session_json.py
┌─────────────────────────────────────────────────────────┐
│ 1. INPUT │
│ Markdown session log (.md) │
│ OR directory of .md files │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 2. PARSE │
│ • Extract session number from filename │
│ • Extract date from filename │
│ • Find branch, commit, objective in content │
│ • Parse checklist tables for completion status │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 3. TRANSFORM │
│ • Build session object (number, date, branch, etc.) │
│ • Build protocolCompliance object │
│ • Map checkbox [x] to complete: true │
│ • Extract evidence from table cells │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 4. OUTPUT │
│ Write .json file alongside .md │
│ (same name, different extension) │
└─────────────────────────────────────────────────────────┘
{
"session": {
"number": 385,
"date": "2026-01-09",
"branch": "feat/session-init-skill",
"startingCommit": "abc1234",
"objective": "Session protocol validation improvements"
},
"protocolCompliance": {
"sessionStart": {
"serenaActivated": { "level": "MUST", "complete": true, "evidence": "Tool output" },
"handoffRead": { "level": "MUST", "complete": true, "evidence": "Content in context" }
},
"sessionEnd": {
"checklistComplete": { "level": "MUST", "complete": true, "evidence": "All [x] checked" },
"validationPassed": { "level": "MUST", "complete": true, "evidence": "Exit code 0" }
}
},
"workLog": [],
"endingCommit": "",
"nextSteps": []
}
| Parameter | Type | Required | Description |
|---|---|---|---|
-Path | string | Yes | Path to .md file or directory |
-Force | switch | No | Overwrite existing .json files |
-DryRun | switch | No | Preview without writing files |
The script returns an array of migrated file paths (string[]) and prints a summary:
=== Migration Summary ===
Migrated: 356
Skipped (JSON exists): 0
Failed: 0
| Code | Meaning | Action |
|---|---|---|
0 | Success | All files migrated or skipped (expected behavior) |
1 | Failure | One or more files failed migration (check error output) |
The script prints migration summary and returns exit code 0 on success, 1 on failure.
For PRs with in-flight markdown sessions:
Check for markdown sessions in PR:
git diff origin/main --name-only | grep -E '\.agents/sessions/.*\.md$'
Run migration:
python3 .claude/skills/session-migration/scripts/convert_session_to_json.py ".agents/sessions/"
Validate migrated sessions:
for f in .agents/sessions/*.json; do python3 scripts/validate_session_json.py "$f"; done
Commit both formats (for transition period):
git add .agents/sessions/*.json
git commit -m "chore(session): migrate session logs to JSON format"
The migration script maps markdown checklist patterns to JSON keys.
| Regex Pattern | JSON Key | Level |
|---|---|---|
activate_project | serenaActivated | MUST |
initial_instructions | serenaInstructions | MUST |
HANDOFF\.md | handoffRead | MUST |
Create.*session.*log|session.*log.*exist|this.*file | sessionLogCreated | MUST |
skill.*script | skillScriptsListed | MUST |
usage-mandatory | usageMandatoryRead | MUST |
CONSTRAINTS | constraintsRead | MUST |
memor | memoriesLoaded | MUST |
verify.*branch|branch.*verif|declare.*branch | branchVerified | MUST |
not.*main|Confirm.*main | notOnMain | MUST |
git.*status | gitStatusVerified | SHOULD |
starting.*commit|Note.*commit | startingCommitNoted | SHOULD |
| Regex Pattern | JSON Key | Level |
|---|---|---|
Complete.*session.*log|session.*log.*complete|all.*section | checklistComplete | MUST |
HANDOFF.*read-only|Update.*HANDOFF | handoffPreserved | MUST |
Serena.*memory|Update.*memory|memory.*updat | serenaMemoryUpdated | MUST |
markdownlint|markdown.*lint|Run.*lint | markdownLintRun | MUST |
Commit.*change|change.*commit | changesCommitted | MUST |
Validate.*Session|validation.*pass|Route.*qa | validationPassed | MUST |
PROJECT-PLAN|task.*checkbox | tasksUpdated | SHOULD |
retrospective | retrospectiveInvoked | SHOULD |
| Avoid | Why | Instead |
|---|---|---|
| Manually converting markdown to JSON | Error-prone, misses edge cases | Use convert_session_to_json.py script |
| Deleting markdown files after migration | May need originals for reference | Keep both during transition period |
| Skipping validation after migration | Migrated JSON may still be incomplete | Always validate with validate_session_json.py |
Migrating without -DryRun first | Cannot preview changes | Use -DryRun to preview, then run for real |
After migration:
validate_session_json.pyUse -Force to overwrite:
python3 .claude/skills/session-migration/scripts/convert_session_to_json.py ".agents/sessions/" --force
Expected for genuinely incomplete sessions. The migration preserves the actual state of checkboxes. Review failed sessions manually.
If a checklist item isn't detected, the markdown format may be non-standard. The script uses flexible regex but edge cases exist. Update the _find_checklist_item function patterns if needed.
Converts markdown session logs to JSON format.
python3 .claude/skills/session-migration/scripts/convert_session_to_json.py <input-file> [--output <output-file>]
| Skill | Purpose |
|---|---|
| session-init | Create new sessions in JSON format |
| session-log-fixer | Fix validation failures |
| Resource | Location | Purpose |
|---|---|---|
| JSON Schema | .agents/schemas/session-log.schema.json | Defines required structure |
| JSON Validator | scripts/validate_session_json.py | Validates migrated JSON files |
| Legacy Validator | scripts/validate_session_json.py | Validates markdown (deprecated) |