
Nav Onboard
- 2 installs
- 32 repo stars
- Updated January 23, 2026
- dkyazzentwatwa/supernavigator
Provides interactive learn-by-doing onboarding for SuperNavigator with a quick-start or full-education flow.
About
Provides interactive, hands-on onboarding where users complete real tasks to learn SuperNavigator workflows. A developer uses it when new to the tool.
- Interactive learn-by-doing onboarding for SuperNavigator
- Offers a 15-min quick start or 45-min full education flow
Nav Onboard by the numbers
- 2 all-time installs (skills.sh)
- Ranked #1,287 of 1,879 Documentation skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/dkyazzentwatwa/supernavigator --skill nav-onboardAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2 |
|---|---|
| repo stars | ★ 32 |
| Last updated | January 23, 2026 |
| Repository | dkyazzentwatwa/supernavigator ↗ |
What it does
Provides interactive learn-by-doing onboarding for SuperNavigator with a quick-start or full-education flow.
Files
Navigator Onboarding Skill
Interactive, hands-on learning experience for Navigator. Users complete actual tasks to learn workflows, not just read documentation.
When to Invoke
Invoke this skill when the user:
- Says "onboard me", "teach me Navigator"
- Says "how do I use Navigator", "Navigator tutorial"
- Says "learn Navigator", "new to Navigator"
- Asks "what skills should I use"
- Says "help me get started with Navigator"
- First time using Navigator after init
DO NOT invoke if:
- User is asking about a specific skill (invoke that skill instead)
- User already completed onboarding (
.agent/onboarding/.completedexists) - User explicitly asks to skip onboarding
Two Learning Flows
Quick Start (~15 min)
For users who want to be productive fast:
- 4 essential skills with hands-on practice
- Generates personalized workflow guide
- Minimal philosophy, maximum doing
Full Education (~45 min)
For users who want comprehensive understanding:
- Philosophy primer (context efficiency principles)
- All 5 essential skills with practice
- Project-specific development skills
- Complete workflow mastery
Execution Steps
Step 1: Check Previous Onboarding
if [ -f ".agent/onboarding/.completed" ]; then
echo "COMPLETED"
else
echo "NOT_COMPLETED"
fiIf completed: Ask if user wants to re-do onboarding or just view their workflow guide.
Step 2: Analyze Project
Run project analyzer to detect tech stack:
python3 skills/nav-onboard/functions/project_analyzer.pyOutput structure:
{
"project_name": "my-app",
"project_type": "fullstack",
"frontend_framework": "Next.js",
"backend_framework": "Express",
"database": "PostgreSQL",
"testing_framework": "Jest",
"has_navigator": true
}Step 3: Generate Skill Recommendations
Run skill recommender based on project analysis:
python3 skills/nav-onboard/functions/skill_recommender.pyOutput structure:
{
"essential_skills": ["nav-start", "nav-marker", "nav-task", "nav-sop", "nav-compact"],
"recommended_skills": ["frontend-component", "backend-endpoint"],
"optional_skills": ["visual-regression", "product-design"],
"workflow_order": ["nav-start", "nav-task", "frontend-component", "nav-sop", "nav-marker", "nav-compact"]
}Step 4: Present Flow Choice
Show detection results and ask user to choose flow:
Navigator Onboarding
I've analyzed your project:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Project: [project_name]
Type: [project_type]
Stack: [tech_stack]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Based on your project, I recommend these skills:
Essential (all projects):
1. nav-start - Start sessions efficiently
2. nav-marker - Save progress checkpoints
3. nav-task - Document what you build
4. nav-sop - Capture solutions for reuse
5. nav-compact - Clear context without losing work
For your [project_type] project:
6. [recommended_skill_1] - [description]
7. [recommended_skill_2] - [description]
Choose your learning path:
[Q] Quick Start (~15 min)
Learn 4 essential skills with hands-on practice
Get productive immediately
[F] Full Education (~45 min)
Complete Navigator mastery
Philosophy + all relevant skills + practice
Your choice [Q/F]:Step 5: Initialize Progress Tracking
Create onboarding directory and progress file:
mkdir -p .agent/onboarding# Run progress_tracker.py init
python3 skills/nav-onboard/functions/progress_tracker.py init [flow_type] [project_type]Creates .agent/onboarding/PROGRESS.md:
# Navigator Onboarding Progress
**Started**: [date]
**Flow**: Quick Start | Full Education
**Project**: [name] ([type])
---
## Essential Skills
| # | Skill | Status | Completed | Notes |
|---|-------|--------|-----------|-------|
| 1 | nav-start | pending | - | - |
| 2 | nav-marker | pending | - | - |
| 3 | nav-task | pending | - | - |
| 4 | nav-sop | pending | - | - |
| 5 | nav-compact | pending | - | - |
## Development Skills
| # | Skill | Status | Completed | Notes |
|---|-------|--------|-----------|-------|
| 6 | [skill] | pending | - | - |
---
**Progress**: 0/[total] (0%)
**Next Task**: nav-start
*Last Updated: [timestamp]*Step 6: Execute Learning Tasks
For each skill in the curriculum, follow this pattern:
6.1: Present Task
Read the learning task file and present to user:
cat skills/nav-onboard/learning-tasks/[task-file].mdPresent in this format:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
TASK [N]/[TOTAL]: [Skill Name]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[Task description and context]
DO THIS NOW:
━━━━━━━━━━━
Type: "[exact command to type]"
WHAT SHOULD HAPPEN:
━━━━━━━━━━━━━━━━━━━
[Expected output description]
Ready? Type the command above, then say "done" when complete.6.2: Wait for User Action
User types the command (e.g., "Start my Navigator session").
The relevant skill executes automatically.
User says "done" or similar when ready to continue.
6.3: Validate Completion
Run task validator:
python3 skills/nav-onboard/functions/task_validator.py [skill_name]Validation checks per skill:
nav-start: User confirmation (session displayed)nav-marker: File exists in.agent/.context-markers/nav-task: File exists in.agent/tasks/nav-sop: File exists in.agent/sops/nav-compact:.activefile exists in.context-markers/
6.4: Update Progress
python3 skills/nav-onboard/functions/progress_tracker.py update [skill_name] completed "[notes]"6.5: Show Progress and Continue
✅ Task Complete: [skill_name]
Progress: [N]/[TOTAL] ([percentage]%)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[progress bar visualization]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PRO TIP:
[Skill-specific best practice]
Next up: [next_skill_name]
Continue? [Y/n]Step 7: Generate Personalized Workflow
After all tasks complete, generate workflow guide:
python3 skills/nav-onboard/functions/workflow_generator.pyCreates .agent/onboarding/MY-WORKFLOW.md with:
- Project-specific workflow diagram
- Daily workflow checklist
- Quick reference table with all skill triggers
- Best practices for user's stack
Step 8: Completion Summary
Mark onboarding complete and show summary:
touch .agent/onboarding/.completed
echo "[date]" > .agent/onboarding/.completed━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎉 NAVIGATOR ONBOARDING COMPLETE!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
You've learned:
✅ nav-start - Start sessions efficiently
✅ nav-marker - Save progress checkpoints
✅ nav-task - Document implementations
✅ nav-sop - Capture solutions
✅ nav-compact - Manage context
✅ [dev skills] - Build [project_type] features
Your personalized workflow:
📄 .agent/onboarding/MY-WORKFLOW.md
Quick Reference:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
| Action | Say This |
|---------------------|----------------------------------|
| Start session | "Start my Navigator session" |
| Save progress | "Create checkpoint [name]" |
| Document feature | "Create task doc for [feature]" |
| Capture solution | "Create SOP for [issue]" |
| Clear context | "Clear context and preserve" |
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
What's Next?
1. Start your first real session: "Start my Navigator session"
2. Keep MY-WORKFLOW.md open as reference
3. Create markers before breaks
4. Document what you build
Happy coding! 🚀Learning Tasks Reference
Essential Skills (All Projects)
| Order | Skill | Task File | What User Does | Validation |
|---|---|---|---|---|
| 1 | nav-start | 01-nav-start.md | "Start my Navigator session" | Session summary displayed |
| 2 | nav-marker | 02-nav-marker.md | "Create checkpoint learning-test" | File in .context-markers/ |
| 3 | nav-task | 03-nav-task.md | "Create task doc for learning-feature" | File in .agent/tasks/ |
| 4 | nav-sop | 04-nav-sop.md | "Create SOP for learning-debugging" | File in .agent/sops/ |
| 5 | nav-compact | 05-nav-compact.md | "Clear context and preserve markers" | .active file created |
Development Skills (Project-Specific)
| Project Type | Skill | Task File |
|---|---|---|
| Frontend | frontend-component | 06-frontend-component.md |
| Frontend | frontend-test | 07-frontend-test.md |
| Backend | backend-endpoint | 06-backend-endpoint.md |
| Backend | backend-test | 07-backend-test.md |
| Fullstack | Both frontend + backend skills | Sequential |
Quick Start Curriculum
Tasks 1-4 only: 1. nav-start (3 min) 2. nav-marker (3 min) 3. nav-task (4 min) 4. One dev skill matching project (5 min)
Total: ~15 minutes
Full Education Curriculum
Part 1: Philosophy (5 min)
- Read
.agent/philosophy/CONTEXT-EFFICIENCY.md - Understand why Navigator exists
- Key principle: load what you need, when you need it
Part 2: Session Management (10 min)
- Task 1: nav-start
- Task 2: nav-marker
- Task 5: nav-compact
Part 3: Documentation (10 min)
- Task 3: nav-task
- Task 4: nav-sop
Part 4: Development Skills (15-20 min)
- Project-specific skills
- Hands-on practice with real components/endpoints
Part 5: Summary (5 min)
- Generate MY-WORKFLOW.md
- Review quick reference
- Next steps
Total: ~45 minutes
Predefined Functions
project_analyzer.py
Extends nav-init/functions/project_detector.py with:
- Project type classification (frontend/backend/fullstack)
- Database detection
- Testing framework detection
- Navigator status check
skill_recommender.py
Maps project analysis to skill recommendations:
- Essential skills (always included)
- Recommended skills (based on project type)
- Optional skills (advanced features)
- Workflow order (suggested sequence)
progress_tracker.py
Manages .agent/onboarding/PROGRESS.md:
- Initialize progress file
- Update task status
- Calculate completion percentage
- Determine next task
task_validator.py
Validates task completion:
- File existence checks
- Content validation
- User confirmation prompts
workflow_generator.py
Generates .agent/onboarding/MY-WORKFLOW.md:
- Project-specific workflow
- Daily checklist
- Quick reference table
- Best practices
Error Handling
Navigator Not Initialized
⚠️ Navigator not initialized in this project.
Run nav-init first, then come back to onboarding.
Would you like to initialize Navigator now? [Y/n]Task Validation Failed
⚠️ Couldn't verify task completion.
Expected: [what should exist]
Found: [what was found]
Options:
1. Retry the task
2. Skip this task
3. Mark as complete anyway
Your choice [1-3]:User Wants to Skip
Skipping [skill_name].
Note: You can always learn this skill later by saying:
"Teach me [skill_name]"
Continuing to next task...Success Criteria
Onboarding is successful when:
- [ ] User completed at least 3 essential skill tasks
- [ ]
.agent/onboarding/PROGRESS.mdshows progress - [ ]
.agent/onboarding/MY-WORKFLOW.mdgenerated - [ ]
.agent/onboarding/.completedmarker created - [ ] User knows how to start sessions and save progress
Notes
- Real files created during onboarding (not sandboxed)
- Files created can be deleted later if unwanted
- Progress persists across sessions
- Can re-run onboarding anytime (asks to overwrite)
- Learning tasks designed for 3-5 minutes each
#!/usr/bin/env python3
"""
Progress tracking for Navigator onboarding.
Manages .agent/onboarding/PROGRESS.md to track learning completion.
"""
import json
import os
import sys
from datetime import datetime
from pathlib import Path
from typing import Dict, List, Optional
def init_progress(
project_dir: str,
flow_type: str,
project_type: str,
project_name: str,
skills: Dict
) -> str:
"""
Initialize progress tracking file.
Args:
project_dir: Project directory path
flow_type: "quick_start" or "full_education"
project_type: Detected project type
project_name: Project name
skills: Skill recommendations from skill_recommender
Returns:
Path to created progress file
"""
onboarding_dir = Path(project_dir) / ".agent" / "onboarding"
onboarding_dir.mkdir(parents=True, exist_ok=True)
progress_file = onboarding_dir / "PROGRESS.md"
# Determine curriculum based on flow
if flow_type == "quick_start":
essential = ["nav-start", "nav-marker", "nav-task"]
development = skills.get("recommended_skills", [])[:1] # Just first dev skill
else: # full_education
essential = skills.get("essential_skills", [])
development = skills.get("recommended_skills", [])
# Build progress table
essential_rows = []
for i, skill in enumerate(essential, 1):
essential_rows.append(f"| {i} | {skill} | pending | - | - |")
dev_rows = []
for i, skill in enumerate(development, len(essential) + 1):
dev_rows.append(f"| {i} | {skill} | pending | - | - |")
total_skills = len(essential) + len(development)
# Format flow name
flow_name = "Quick Start" if flow_type == "quick_start" else "Full Education"
content = f"""# Navigator Onboarding Progress
**Started**: {datetime.now().strftime("%Y-%m-%d %H:%M")}
**Flow**: {flow_name}
**Project**: {project_name} ({project_type})
---
## Essential Skills
| # | Skill | Status | Completed | Notes |
|---|-------|--------|-----------|-------|
{chr(10).join(essential_rows)}
## Development Skills
| # | Skill | Status | Completed | Notes |
|---|-------|--------|-----------|-------|
{chr(10).join(dev_rows) if dev_rows else "| - | (none for this flow) | - | - | - |"}
---
**Progress**: 0/{total_skills} (0%)
**Next Task**: {essential[0] if essential else "complete"}
*Last Updated: {datetime.now().strftime("%Y-%m-%d %H:%M")}*
"""
progress_file.write_text(content)
# Also save structured data for programmatic access
data_file = onboarding_dir / ".progress-data.json"
data = {
"started": datetime.now().isoformat(),
"flow_type": flow_type,
"project_type": project_type,
"project_name": project_name,
"essential_skills": essential,
"development_skills": development,
"progress": {skill: {"status": "pending", "completed": None, "notes": ""} for skill in essential + development},
"total": total_skills,
"completed": 0,
}
data_file.write_text(json.dumps(data, indent=2))
return str(progress_file)
def update_progress(
project_dir: str,
skill_name: str,
status: str,
notes: str = ""
) -> Dict:
"""
Update progress for a specific skill.
Args:
project_dir: Project directory path
skill_name: Name of skill to update
status: "pending", "in_progress", or "completed"
notes: Optional notes about completion
Returns:
Updated progress summary
"""
onboarding_dir = Path(project_dir) / ".agent" / "onboarding"
data_file = onboarding_dir / ".progress-data.json"
if not data_file.exists():
return {"error": "Progress not initialized. Run init first."}
data = json.loads(data_file.read_text())
if skill_name not in data["progress"]:
return {"error": f"Unknown skill: {skill_name}"}
# Update skill status
data["progress"][skill_name]["status"] = status
if status == "completed":
data["progress"][skill_name]["completed"] = datetime.now().strftime("%Y-%m-%d %H:%M")
data["completed"] = sum(1 for s in data["progress"].values() if s["status"] == "completed")
if notes:
data["progress"][skill_name]["notes"] = notes
# Save updated data
data_file.write_text(json.dumps(data, indent=2))
# Regenerate markdown
_regenerate_markdown(onboarding_dir, data)
return {
"skill": skill_name,
"status": status,
"completed": data["completed"],
"total": data["total"],
"percentage": round(data["completed"] / data["total"] * 100) if data["total"] > 0 else 0,
"next_task": get_next_task(project_dir),
}
def get_progress(project_dir: str) -> Dict:
"""
Get current progress summary.
Args:
project_dir: Project directory path
Returns:
Progress summary dictionary
"""
onboarding_dir = Path(project_dir) / ".agent" / "onboarding"
data_file = onboarding_dir / ".progress-data.json"
if not data_file.exists():
return {"initialized": False}
data = json.loads(data_file.read_text())
return {
"initialized": True,
"flow_type": data["flow_type"],
"project_type": data["project_type"],
"completed": data["completed"],
"total": data["total"],
"percentage": round(data["completed"] / data["total"] * 100) if data["total"] > 0 else 0,
"skills": data["progress"],
"next_task": get_next_task(project_dir),
}
def get_next_task(project_dir: str) -> Optional[str]:
"""
Determine the next task to complete.
Args:
project_dir: Project directory path
Returns:
Next skill name or None if complete
"""
onboarding_dir = Path(project_dir) / ".agent" / "onboarding"
data_file = onboarding_dir / ".progress-data.json"
if not data_file.exists():
return None
data = json.loads(data_file.read_text())
# Find first non-completed skill in order
all_skills = data["essential_skills"] + data["development_skills"]
for skill in all_skills:
if data["progress"][skill]["status"] != "completed":
return skill
return None
def _regenerate_markdown(onboarding_dir: Path, data: Dict) -> None:
"""Regenerate PROGRESS.md from data."""
progress_file = onboarding_dir / "PROGRESS.md"
# Build tables
essential_rows = []
for i, skill in enumerate(data["essential_skills"], 1):
p = data["progress"][skill]
status_icon = {"pending": "pending", "in_progress": "in_progress", "completed": "completed"}[p["status"]]
completed = p["completed"] or "-"
notes = p["notes"] or "-"
essential_rows.append(f"| {i} | {skill} | {status_icon} | {completed} | {notes} |")
dev_rows = []
for i, skill in enumerate(data["development_skills"], len(data["essential_skills"]) + 1):
p = data["progress"][skill]
status_icon = {"pending": "pending", "in_progress": "in_progress", "completed": "completed"}[p["status"]]
completed = p["completed"] or "-"
notes = p["notes"] or "-"
dev_rows.append(f"| {i} | {skill} | {status_icon} | {completed} | {notes} |")
percentage = round(data["completed"] / data["total"] * 100) if data["total"] > 0 else 0
next_task = get_next_task(str(onboarding_dir.parent.parent)) or "complete"
flow_name = "Quick Start" if data["flow_type"] == "quick_start" else "Full Education"
content = f"""# Navigator Onboarding Progress
**Started**: {data["started"][:16].replace("T", " ")}
**Flow**: {flow_name}
**Project**: {data["project_name"]} ({data["project_type"]})
---
## Essential Skills
| # | Skill | Status | Completed | Notes |
|---|-------|--------|-----------|-------|
{chr(10).join(essential_rows)}
## Development Skills
| # | Skill | Status | Completed | Notes |
|---|-------|--------|-----------|-------|
{chr(10).join(dev_rows) if dev_rows else "| - | (none for this flow) | - | - | - |"}
---
**Progress**: {data["completed"]}/{data["total"]} ({percentage}%)
**Next Task**: {next_task}
*Last Updated: {datetime.now().strftime("%Y-%m-%d %H:%M")}*
"""
progress_file.write_text(content)
def format_progress_bar(completed: int, total: int, width: int = 30) -> str:
"""Generate ASCII progress bar."""
if total == 0:
return "[" + " " * width + "]"
filled = int(width * completed / total)
empty = width - filled
return "[" + "=" * filled + " " * empty + "]"
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: progress_tracker.py <command> [args]")
print("Commands: init, update, get, next")
sys.exit(1)
command = sys.argv[1]
if command == "init":
# init <project_dir> <flow_type> <project_type> <project_name> <skills_json>
if len(sys.argv) < 7:
print("Usage: progress_tracker.py init <project_dir> <flow_type> <project_type> <project_name> <skills_json>")
sys.exit(1)
result = init_progress(
sys.argv[2],
sys.argv[3],
sys.argv[4],
sys.argv[5],
json.loads(sys.argv[6])
)
print(result)
elif command == "update":
# update <project_dir> <skill_name> <status> [notes]
if len(sys.argv) < 5:
print("Usage: progress_tracker.py update <project_dir> <skill_name> <status> [notes]")
sys.exit(1)
notes = sys.argv[5] if len(sys.argv) > 5 else ""
result = update_progress(sys.argv[2], sys.argv[3], sys.argv[4], notes)
print(json.dumps(result, indent=2))
elif command == "get":
# get <project_dir>
if len(sys.argv) < 3:
print("Usage: progress_tracker.py get <project_dir>")
sys.exit(1)
result = get_progress(sys.argv[2])
print(json.dumps(result, indent=2))
elif command == "next":
# next <project_dir>
if len(sys.argv) < 3:
print("Usage: progress_tracker.py next <project_dir>")
sys.exit(1)
result = get_next_task(sys.argv[2])
print(result or "complete")
else:
print(f"Unknown command: {command}")
sys.exit(1)
#!/usr/bin/env python3
"""
Extended project analysis for Navigator onboarding.
Detects project type, frameworks, database, and testing setup
to recommend appropriate skills and workflow.
"""
import json
import os
import re
from pathlib import Path
from typing import Dict, List, Optional
def analyze_project(cwd: str = ".") -> Dict:
"""
Comprehensive project analysis for onboarding recommendations.
Args:
cwd: Current working directory (default: ".")
Returns:
Dictionary with project analysis results
"""
cwd_path = Path(cwd).resolve()
result = {
"project_name": cwd_path.name,
"project_type": "unknown",
"frontend_framework": None,
"backend_framework": None,
"database": None,
"orm": None,
"testing_framework": None,
"has_navigator": False,
"has_storybook": False,
"has_figma_mcp": False,
"detected_from": [],
"confidence": 0.0,
}
# Check Navigator status
result["has_navigator"] = (cwd_path / ".agent").exists()
# Analyze different config files
_analyze_package_json(cwd_path, result)
_analyze_pyproject_toml(cwd_path, result)
_analyze_go_mod(cwd_path, result)
_analyze_cargo_toml(cwd_path, result)
_analyze_composer_json(cwd_path, result)
_analyze_gemfile(cwd_path, result)
# Detect Storybook
result["has_storybook"] = (cwd_path / ".storybook").exists()
# Detect Figma MCP (check Claude settings)
result["has_figma_mcp"] = _check_figma_mcp()
# Determine project type
result["project_type"] = _classify_project_type(result)
# Calculate confidence
result["confidence"] = _calculate_confidence(result)
return result
def _analyze_package_json(cwd: Path, result: Dict) -> None:
"""Analyze package.json for Node.js/JavaScript projects."""
package_json = cwd / "package.json"
if not package_json.exists():
return
try:
with open(package_json) as f:
data = json.load(f)
result["project_name"] = data.get("name", result["project_name"])
result["detected_from"].append("package.json")
deps = {**data.get("dependencies", {}), **data.get("devDependencies", {})}
# Frontend frameworks
if "next" in deps:
result["frontend_framework"] = "Next.js"
elif "react" in deps:
result["frontend_framework"] = "React"
elif "vue" in deps:
result["frontend_framework"] = "Vue"
elif "@angular/core" in deps:
result["frontend_framework"] = "Angular"
elif "svelte" in deps:
result["frontend_framework"] = "Svelte"
# Backend frameworks (Node.js)
if "express" in deps:
result["backend_framework"] = "Express"
elif "fastify" in deps:
result["backend_framework"] = "Fastify"
elif "@nestjs/core" in deps:
result["backend_framework"] = "NestJS"
elif "koa" in deps:
result["backend_framework"] = "Koa"
elif "hono" in deps:
result["backend_framework"] = "Hono"
# Database/ORM
if "prisma" in deps or "@prisma/client" in deps:
result["orm"] = "Prisma"
if "mongoose" in deps:
result["database"] = "MongoDB"
result["orm"] = "Mongoose"
if "pg" in deps:
result["database"] = "PostgreSQL"
if "mysql2" in deps or "mysql" in deps:
result["database"] = "MySQL"
if "drizzle-orm" in deps:
result["orm"] = "Drizzle"
if "typeorm" in deps:
result["orm"] = "TypeORM"
if "sequelize" in deps:
result["orm"] = "Sequelize"
# Testing
if "jest" in deps:
result["testing_framework"] = "Jest"
if "@testing-library/react" in deps:
result["testing_framework"] = "Jest + React Testing Library"
elif "vitest" in deps:
result["testing_framework"] = "Vitest"
elif "mocha" in deps:
result["testing_framework"] = "Mocha"
elif "playwright" in deps:
result["testing_framework"] = "Playwright"
elif "cypress" in deps:
result["testing_framework"] = "Cypress"
# Storybook
if "@storybook/react" in deps or "@storybook/vue" in deps:
result["has_storybook"] = True
except (json.JSONDecodeError, IOError):
pass
def _analyze_pyproject_toml(cwd: Path, result: Dict) -> None:
"""Analyze pyproject.toml for Python projects."""
pyproject = cwd / "pyproject.toml"
if not pyproject.exists():
return
try:
content = pyproject.read_text().lower()
result["detected_from"].append("pyproject.toml")
# Extract name
name_match = re.search(r'name\s*=\s*["\']([^"\']+)["\']', content)
if name_match and not result["project_name"]:
result["project_name"] = name_match.group(1)
# Backend frameworks
if "fastapi" in content:
result["backend_framework"] = "FastAPI"
elif "django" in content:
result["backend_framework"] = "Django"
elif "flask" in content:
result["backend_framework"] = "Flask"
elif "starlette" in content:
result["backend_framework"] = "Starlette"
# ORM/Database
if "sqlalchemy" in content:
result["orm"] = "SQLAlchemy"
if "sqlmodel" in content:
result["orm"] = "SQLModel"
if "tortoise-orm" in content:
result["orm"] = "Tortoise ORM"
if "psycopg" in content or "asyncpg" in content:
result["database"] = "PostgreSQL"
if "pymysql" in content:
result["database"] = "MySQL"
if "pymongo" in content:
result["database"] = "MongoDB"
# Testing
if "pytest" in content:
result["testing_framework"] = "Pytest"
except IOError:
pass
def _analyze_go_mod(cwd: Path, result: Dict) -> None:
"""Analyze go.mod for Go projects."""
go_mod = cwd / "go.mod"
if not go_mod.exists():
return
try:
content = go_mod.read_text()
result["detected_from"].append("go.mod")
# Extract module name
module_match = re.search(r'module\s+([^\s]+)', content)
if module_match:
result["project_name"] = module_match.group(1).split("/")[-1]
# Backend frameworks
if "gin-gonic/gin" in content:
result["backend_framework"] = "Gin"
elif "gofiber/fiber" in content:
result["backend_framework"] = "Fiber"
elif "labstack/echo" in content:
result["backend_framework"] = "Echo"
elif "go-chi/chi" in content:
result["backend_framework"] = "Chi"
# ORM/Database
if "gorm.io/gorm" in content:
result["orm"] = "GORM"
if "sqlc" in content:
result["orm"] = "sqlc"
if "lib/pq" in content or "jackc/pgx" in content:
result["database"] = "PostgreSQL"
if "go-sql-driver/mysql" in content:
result["database"] = "MySQL"
except IOError:
pass
def _analyze_cargo_toml(cwd: Path, result: Dict) -> None:
"""Analyze Cargo.toml for Rust projects."""
cargo_toml = cwd / "Cargo.toml"
if not cargo_toml.exists():
return
try:
content = cargo_toml.read_text()
result["detected_from"].append("Cargo.toml")
# Extract name
name_match = re.search(r'name\s*=\s*["\']([^"\']+)["\']', content)
if name_match:
result["project_name"] = name_match.group(1)
# Backend frameworks
if "actix-web" in content:
result["backend_framework"] = "Actix Web"
elif "rocket" in content:
result["backend_framework"] = "Rocket"
elif "axum" in content:
result["backend_framework"] = "Axum"
elif "warp" in content:
result["backend_framework"] = "Warp"
# ORM/Database
if "diesel" in content:
result["orm"] = "Diesel"
elif "sqlx" in content:
result["orm"] = "SQLx"
elif "sea-orm" in content:
result["orm"] = "SeaORM"
except IOError:
pass
def _analyze_composer_json(cwd: Path, result: Dict) -> None:
"""Analyze composer.json for PHP projects."""
composer_json = cwd / "composer.json"
if not composer_json.exists():
return
try:
with open(composer_json) as f:
data = json.load(f)
result["detected_from"].append("composer.json")
name = data.get("name", "")
if name:
result["project_name"] = name.split("/")[-1]
deps = {**data.get("require", {}), **data.get("require-dev", {})}
deps_str = " ".join(deps.keys()).lower()
if "laravel" in deps_str:
result["backend_framework"] = "Laravel"
elif "symfony" in deps_str:
result["backend_framework"] = "Symfony"
if "doctrine" in deps_str:
result["orm"] = "Doctrine"
if "eloquent" in deps_str:
result["orm"] = "Eloquent"
if "phpunit" in deps_str:
result["testing_framework"] = "PHPUnit"
except (json.JSONDecodeError, IOError):
pass
def _analyze_gemfile(cwd: Path, result: Dict) -> None:
"""Analyze Gemfile for Ruby projects."""
gemfile = cwd / "Gemfile"
if not gemfile.exists():
return
try:
content = gemfile.read_text().lower()
result["detected_from"].append("Gemfile")
if "rails" in content:
result["backend_framework"] = "Ruby on Rails"
elif "sinatra" in content:
result["backend_framework"] = "Sinatra"
if "activerecord" in content or "rails" in content:
result["orm"] = "ActiveRecord"
if "rspec" in content:
result["testing_framework"] = "RSpec"
elif "minitest" in content:
result["testing_framework"] = "Minitest"
except IOError:
pass
def _check_figma_mcp() -> bool:
"""Check if Figma MCP is configured in Claude settings."""
# Check common Claude config locations
config_paths = [
Path.home() / ".claude" / "settings.json",
Path.home() / ".config" / "claude" / "settings.json",
]
for config_path in config_paths:
if config_path.exists():
try:
with open(config_path) as f:
config = json.load(f)
mcp_servers = config.get("mcpServers", {})
return "figma" in str(mcp_servers).lower()
except (json.JSONDecodeError, IOError):
pass
return False
def _classify_project_type(result: Dict) -> str:
"""Classify project as frontend, backend, fullstack, or unknown."""
has_frontend = result["frontend_framework"] is not None
has_backend = result["backend_framework"] is not None
if has_frontend and has_backend:
return "fullstack"
elif has_frontend:
return "frontend"
elif has_backend:
return "backend"
elif result["detected_from"]:
# Has config files but couldn't determine type
return "library"
else:
return "unknown"
def _calculate_confidence(result: Dict) -> float:
"""Calculate confidence score based on detection completeness."""
score = 0.0
# Base score for having any detection
if result["detected_from"]:
score += 0.3
# Framework detection
if result["frontend_framework"]:
score += 0.2
if result["backend_framework"]:
score += 0.2
# Additional context
if result["database"] or result["orm"]:
score += 0.15
if result["testing_framework"]:
score += 0.1
if result["has_navigator"]:
score += 0.05
return min(score, 1.0)
def format_tech_stack(result: Dict) -> str:
"""Format detected technologies as readable string."""
parts = []
if result["frontend_framework"]:
parts.append(result["frontend_framework"])
if result["backend_framework"]:
parts.append(result["backend_framework"])
if result["orm"]:
parts.append(result["orm"])
elif result["database"]:
parts.append(result["database"])
if result["testing_framework"]:
parts.append(result["testing_framework"])
return ", ".join(parts) if parts else "Unknown"
if __name__ == "__main__":
import sys
cwd = sys.argv[1] if len(sys.argv) > 1 else "."
result = analyze_project(cwd)
result["tech_stack"] = format_tech_stack(result)
print(json.dumps(result, indent=2))
#!/usr/bin/env python3
"""
Skill recommendation engine for Navigator onboarding.
Maps project analysis to recommended skills and workflow order.
"""
import json
import sys
from typing import Dict, List
# Skill definitions with metadata
SKILLS = {
# Essential skills (all projects)
"nav-start": {
"name": "nav-start",
"description": "Start sessions efficiently with context loading",
"category": "essential",
"project_types": ["all"],
"workflow_position": 1,
"time_savings": "92%",
"triggers": ["Start my Navigator session"],
},
"nav-marker": {
"name": "nav-marker",
"description": "Save progress checkpoints before breaks",
"category": "essential",
"project_types": ["all"],
"workflow_position": 5,
"time_savings": "97%",
"triggers": ["Create checkpoint [name]", "Save my progress"],
},
"nav-task": {
"name": "nav-task",
"description": "Document what you build for future reference",
"category": "essential",
"project_types": ["all"],
"workflow_position": 2,
"time_savings": "80%",
"triggers": ["Create task doc for [feature]", "Archive TASK-XX"],
},
"nav-sop": {
"name": "nav-sop",
"description": "Capture solutions for reuse",
"category": "essential",
"project_types": ["all"],
"workflow_position": 4,
"time_savings": "85%",
"triggers": ["Create SOP for [issue]", "Document this solution"],
},
"nav-compact": {
"name": "nav-compact",
"description": "Clear context without losing work",
"category": "essential",
"project_types": ["all"],
"workflow_position": 6,
"time_savings": "90%",
"triggers": ["Clear context and preserve markers"],
},
# Frontend skills
"frontend-component": {
"name": "frontend-component",
"description": "Generate React/Vue components with tests",
"category": "development",
"project_types": ["frontend", "fullstack"],
"workflow_position": 3,
"time_savings": "70%",
"triggers": ["Create component [name]", "Add component [name]"],
"frameworks": ["React", "Next.js", "Vue", "Angular", "Svelte"],
},
"frontend-test": {
"name": "frontend-test",
"description": "Generate component tests with RTL",
"category": "development",
"project_types": ["frontend", "fullstack"],
"workflow_position": 3.5,
"time_savings": "65%",
"triggers": ["Test this component", "Write component test"],
},
"visual-regression": {
"name": "visual-regression",
"description": "Setup Storybook + visual regression testing",
"category": "optional",
"project_types": ["frontend", "fullstack"],
"workflow_position": 3.7,
"time_savings": "96%",
"triggers": ["Set up visual regression", "Add Chromatic tests"],
"requires": ["has_storybook"],
},
"product-design": {
"name": "product-design",
"description": "Automate design handoff from Figma",
"category": "optional",
"project_types": ["frontend", "fullstack"],
"workflow_position": 2.5,
"time_savings": "95%",
"triggers": ["Review this Figma design", "Design handoff"],
"requires": ["has_figma_mcp"],
},
# Backend skills
"backend-endpoint": {
"name": "backend-endpoint",
"description": "Create API endpoints with validation",
"category": "development",
"project_types": ["backend", "fullstack"],
"workflow_position": 3,
"time_savings": "70%",
"triggers": ["Add endpoint [path]", "Create API [name]"],
},
"backend-test": {
"name": "backend-test",
"description": "Generate backend tests with mocks",
"category": "development",
"project_types": ["backend", "fullstack"],
"workflow_position": 3.5,
"time_savings": "65%",
"triggers": ["Write test for [function]", "Add test [name]"],
},
"database-migration": {
"name": "database-migration",
"description": "Create migrations with rollback",
"category": "development",
"project_types": ["backend", "fullstack"],
"workflow_position": 2.8,
"time_savings": "60%",
"triggers": ["Create migration [name]", "Add table [name]"],
"requires": ["database"],
},
# Advanced skills
"nav-skill-creator": {
"name": "nav-skill-creator",
"description": "Create custom skills for your workflow",
"category": "advanced",
"project_types": ["all"],
"workflow_position": 7,
"time_savings": "80%",
"triggers": ["Create a skill for [workflow]"],
},
}
def recommend_skills(project_analysis: Dict) -> Dict:
"""
Generate skill recommendations based on project analysis.
Args:
project_analysis: Output from project_analyzer.py
Returns:
Dictionary with skill recommendations and workflow order
"""
project_type = project_analysis.get("project_type", "unknown")
essential = []
recommended = []
optional = []
for skill_id, skill in SKILLS.items():
# Check project type compatibility
skill_types = skill["project_types"]
if "all" not in skill_types and project_type not in skill_types:
continue
# Check requirements
requirements = skill.get("requires", [])
meets_requirements = True
for req in requirements:
if req == "has_storybook" and not project_analysis.get("has_storybook"):
meets_requirements = False
elif req == "has_figma_mcp" and not project_analysis.get("has_figma_mcp"):
meets_requirements = False
elif req == "database" and not project_analysis.get("database"):
meets_requirements = False
# Categorize skill
category = skill["category"]
skill_info = {
"id": skill_id,
"name": skill["name"],
"description": skill["description"],
"triggers": skill["triggers"],
"time_savings": skill["time_savings"],
"workflow_position": skill["workflow_position"],
}
if category == "essential":
essential.append(skill_info)
elif category == "development" and meets_requirements:
recommended.append(skill_info)
elif category == "optional" and meets_requirements:
optional.append(skill_info)
elif category == "advanced":
optional.append(skill_info)
# Sort by workflow position
essential.sort(key=lambda x: x["workflow_position"])
recommended.sort(key=lambda x: x["workflow_position"])
optional.sort(key=lambda x: x["workflow_position"])
# Generate workflow order
all_skills = essential + recommended
all_skills.sort(key=lambda x: x["workflow_position"])
workflow_order = [s["id"] for s in all_skills]
return {
"project_type": project_type,
"essential_skills": [s["id"] for s in essential],
"recommended_skills": [s["id"] for s in recommended],
"optional_skills": [s["id"] for s in optional],
"workflow_order": workflow_order,
"skill_details": {
"essential": essential,
"recommended": recommended,
"optional": optional,
},
"curriculum": {
"quick_start": _generate_quick_start_curriculum(essential, recommended),
"full_education": _generate_full_curriculum(essential, recommended, optional),
},
}
def _generate_quick_start_curriculum(essential: List[Dict], recommended: List[Dict]) -> List[Dict]:
"""Generate Quick Start curriculum (4 skills, 15 min)."""
curriculum = []
# First 3 essential skills
essential_subset = ["nav-start", "nav-marker", "nav-task"]
for skill in essential:
if skill["id"] in essential_subset:
curriculum.append({
"skill": skill["id"],
"estimated_time": "3 min",
"task_file": f"{len(curriculum) + 1:02d}-{skill['id']}.md",
})
# One dev skill if available
if recommended:
dev_skill = recommended[0]
curriculum.append({
"skill": dev_skill["id"],
"estimated_time": "5 min",
"task_file": f"{len(curriculum) + 1:02d}-{dev_skill['id']}.md",
})
return curriculum
def _generate_full_curriculum(
essential: List[Dict], recommended: List[Dict], optional: List[Dict]
) -> List[Dict]:
"""Generate Full Education curriculum (~45 min)."""
curriculum = []
# Philosophy section
curriculum.append({
"section": "Philosophy",
"skill": None,
"estimated_time": "5 min",
"description": "Read context efficiency principles",
"file": ".agent/philosophy/CONTEXT-EFFICIENCY.md",
})
# All essential skills
for i, skill in enumerate(essential):
curriculum.append({
"section": "Essential",
"skill": skill["id"],
"estimated_time": "3 min",
"task_file": f"{i + 1:02d}-{skill['id']}.md",
})
# All recommended skills
for i, skill in enumerate(recommended):
curriculum.append({
"section": "Development",
"skill": skill["id"],
"estimated_time": "5 min",
"task_file": f"0{len(essential) + i + 1}-{skill['id']}.md",
})
# Summary
curriculum.append({
"section": "Summary",
"skill": None,
"estimated_time": "5 min",
"description": "Generate personalized workflow guide",
})
return curriculum
def format_recommendations(recommendations: Dict) -> str:
"""Format recommendations for display."""
lines = []
lines.append(f"Project Type: {recommendations['project_type']}")
lines.append("")
lines.append("Essential Skills:")
for skill in recommendations["skill_details"]["essential"]:
lines.append(f" - {skill['name']}: {skill['description']}")
lines.append("")
lines.append("Recommended Skills:")
for skill in recommendations["skill_details"]["recommended"]:
lines.append(f" - {skill['name']}: {skill['description']}")
if recommendations["skill_details"]["optional"]:
lines.append("")
lines.append("Optional Skills:")
for skill in recommendations["skill_details"]["optional"]:
lines.append(f" - {skill['name']}: {skill['description']}")
lines.append("")
lines.append(f"Workflow Order: {' -> '.join(recommendations['workflow_order'])}")
return "\n".join(lines)
if __name__ == "__main__":
# Read project analysis from stdin or file
if len(sys.argv) > 1:
with open(sys.argv[1]) as f:
project_analysis = json.load(f)
else:
project_analysis = json.load(sys.stdin)
recommendations = recommend_skills(project_analysis)
print(json.dumps(recommendations, indent=2))
#!/usr/bin/env python3
"""
Task validation for Navigator onboarding.
Validates whether learning tasks have been completed.
"""
import json
import os
import sys
from datetime import datetime, timedelta
from pathlib import Path
from typing import Dict, List, Optional
def validate_task(project_dir: str, skill_name: str) -> Dict:
"""
Validate if a learning task has been completed.
Args:
project_dir: Project directory path
skill_name: Name of skill to validate
Returns:
Validation result dictionary
"""
validators = {
"nav-start": _validate_nav_start,
"nav-marker": _validate_nav_marker,
"nav-task": _validate_nav_task,
"nav-sop": _validate_nav_sop,
"nav-compact": _validate_nav_compact,
"frontend-component": _validate_frontend_component,
"backend-endpoint": _validate_backend_endpoint,
"frontend-test": _validate_frontend_test,
"backend-test": _validate_backend_test,
"database-migration": _validate_database_migration,
}
validator = validators.get(skill_name)
if not validator:
return {
"valid": False,
"method": "unknown",
"reason": f"No validator for skill: {skill_name}",
"suggestion": "Mark as complete manually if you've done the task",
}
return validator(Path(project_dir))
def _validate_nav_start(project_dir: Path) -> Dict:
"""
Validate nav-start task.
Since session start is conversational, we rely on user confirmation.
"""
return {
"valid": True,
"method": "user_confirmation",
"message": "Session start validated via user confirmation",
"note": "nav-start is conversational - no file artifacts to check",
}
def _validate_nav_marker(project_dir: Path) -> Dict:
"""
Validate nav-marker task.
Checks for marker file containing 'learning' in the name.
"""
markers_dir = project_dir / ".agent" / ".context-markers"
if not markers_dir.exists():
return {
"valid": False,
"method": "file_check",
"reason": "No .context-markers directory found",
"suggestion": "Create a marker with: 'Create checkpoint learning-test'",
}
# Look for learning-related marker
markers = list(markers_dir.glob("*.md"))
learning_markers = [m for m in markers if "learning" in m.stem.lower()]
if learning_markers:
# Check if recently created (within last hour)
recent = [m for m in learning_markers if _is_recent(m)]
if recent:
return {
"valid": True,
"method": "file_check",
"marker_file": str(recent[0]),
"message": f"Found learning marker: {recent[0].name}",
}
else:
return {
"valid": True,
"method": "file_check",
"marker_file": str(learning_markers[0]),
"message": f"Found learning marker (older): {learning_markers[0].name}",
"note": "Marker exists but was created earlier",
}
# Check for any recent marker
recent_markers = [m for m in markers if _is_recent(m)]
if recent_markers:
return {
"valid": True,
"method": "file_check",
"marker_file": str(recent_markers[0]),
"message": f"Found recent marker: {recent_markers[0].name}",
"note": "No 'learning' marker, but recent marker found",
}
return {
"valid": False,
"method": "file_check",
"reason": "No learning marker found",
"suggestion": "Create a marker with: 'Create checkpoint learning-test'",
}
def _validate_nav_task(project_dir: Path) -> Dict:
"""
Validate nav-task task.
Checks for task file containing 'learning' in the name.
"""
tasks_dir = project_dir / ".agent" / "tasks"
if not tasks_dir.exists():
return {
"valid": False,
"method": "file_check",
"reason": "No tasks directory found",
"suggestion": "Create a task with: 'Create task doc for learning-feature'",
}
# Look for learning-related task
tasks = list(tasks_dir.glob("*.md"))
learning_tasks = [t for t in tasks if "learning" in t.stem.lower()]
if learning_tasks:
return {
"valid": True,
"method": "file_check",
"task_file": str(learning_tasks[0]),
"message": f"Found learning task: {learning_tasks[0].name}",
}
# Check for any recent task
recent_tasks = [t for t in tasks if _is_recent(t)]
if recent_tasks:
return {
"valid": True,
"method": "file_check",
"task_file": str(recent_tasks[0]),
"message": f"Found recent task: {recent_tasks[0].name}",
"note": "No 'learning' task, but recent task found",
}
return {
"valid": False,
"method": "file_check",
"reason": "No learning task found",
"suggestion": "Create a task with: 'Create task doc for learning-feature'",
}
def _validate_nav_sop(project_dir: Path) -> Dict:
"""
Validate nav-sop task.
Checks for SOP file in any category.
"""
sops_dir = project_dir / ".agent" / "sops"
if not sops_dir.exists():
return {
"valid": False,
"method": "file_check",
"reason": "No sops directory found",
"suggestion": "Create an SOP with: 'Create SOP for debugging test-failures'",
}
# Look in all SOP categories
categories = ["debugging", "integrations", "development", "deployment"]
all_sops = []
for category in categories:
category_dir = sops_dir / category
if category_dir.exists():
all_sops.extend(list(category_dir.glob("*.md")))
if not all_sops:
return {
"valid": False,
"method": "file_check",
"reason": "No SOP files found",
"suggestion": "Create an SOP with: 'Create SOP for debugging test-failures'",
}
# Look for learning-related or recent SOP
learning_sops = [s for s in all_sops if "learning" in s.stem.lower() or "test" in s.stem.lower()]
if learning_sops:
return {
"valid": True,
"method": "file_check",
"sop_file": str(learning_sops[0]),
"message": f"Found SOP: {learning_sops[0].name}",
}
recent_sops = [s for s in all_sops if _is_recent(s)]
if recent_sops:
return {
"valid": True,
"method": "file_check",
"sop_file": str(recent_sops[0]),
"message": f"Found recent SOP: {recent_sops[0].name}",
}
# Any SOP counts
return {
"valid": True,
"method": "file_check",
"sop_file": str(all_sops[0]),
"message": f"Found SOP: {all_sops[0].name}",
"note": "Using existing SOP (not from learning task)",
}
def _validate_nav_compact(project_dir: Path) -> Dict:
"""
Validate nav-compact task.
Checks for .active file in context-markers.
"""
markers_dir = project_dir / ".agent" / ".context-markers"
active_file = markers_dir / ".active"
if active_file.exists():
return {
"valid": True,
"method": "file_check",
"active_file": str(active_file),
"message": "Compact initiated - .active marker set",
}
# Check for any recent marker that might indicate compact was run
if markers_dir.exists():
markers = list(markers_dir.glob("*.md"))
compact_markers = [m for m in markers if "compact" in m.stem.lower()]
if compact_markers:
return {
"valid": True,
"method": "file_check",
"marker_file": str(compact_markers[0]),
"message": "Found compact marker (may have been restored already)",
}
return {
"valid": False,
"method": "file_check",
"reason": "No .active marker file found",
"suggestion": "Run compact with: 'Clear context and preserve markers'",
}
def _validate_frontend_component(project_dir: Path) -> Dict:
"""
Validate frontend-component task.
Checks for component files with 'onboarding' or 'demo' in name.
"""
# Common component directories
search_dirs = [
project_dir / "src" / "components",
project_dir / "components",
project_dir / "app" / "components",
project_dir / "src",
]
for search_dir in search_dirs:
if not search_dir.exists():
continue
# Look for onboarding/demo related files
for pattern in ["**/[Oo]nboarding*", "**/[Dd]emo*"]:
matches = list(search_dir.glob(pattern))
if matches:
return {
"valid": True,
"method": "file_check",
"component_path": str(matches[0]),
"message": f"Found component: {matches[0].name}",
}
return {
"valid": False,
"method": "file_check",
"reason": "No onboarding/demo component found",
"suggestion": "Create component with: 'Create component OnboardingDemo'",
}
def _validate_backend_endpoint(project_dir: Path) -> Dict:
"""
Validate backend-endpoint task.
Checks for route/endpoint files with 'onboarding' or 'demo' in name.
"""
# Common route directories
search_dirs = [
project_dir / "src" / "routes",
project_dir / "src" / "api",
project_dir / "routes",
project_dir / "api",
project_dir / "app" / "api",
]
for search_dir in search_dirs:
if not search_dir.exists():
continue
# Look for onboarding/demo related files
for pattern in ["**/[Oo]nboarding*", "**/[Dd]emo*"]:
matches = list(search_dir.glob(pattern))
if matches:
return {
"valid": True,
"method": "file_check",
"endpoint_path": str(matches[0]),
"message": f"Found endpoint: {matches[0].name}",
}
return {
"valid": False,
"method": "file_check",
"reason": "No onboarding/demo endpoint found",
"suggestion": "Create endpoint with: 'Add endpoint /api/onboarding-demo'",
}
def _validate_frontend_test(project_dir: Path) -> Dict:
"""Validate frontend-test task."""
return _validate_test_file(project_dir, "frontend")
def _validate_backend_test(project_dir: Path) -> Dict:
"""Validate backend-test task."""
return _validate_test_file(project_dir, "backend")
def _validate_test_file(project_dir: Path, test_type: str) -> Dict:
"""Generic test file validation."""
# Look for test files
patterns = ["**/*.test.ts", "**/*.test.tsx", "**/*.test.js", "**/*.spec.ts", "**/*_test.py", "**/*_test.go"]
for pattern in patterns:
matches = list(project_dir.glob(pattern))
recent = [m for m in matches if _is_recent(m)]
if recent:
return {
"valid": True,
"method": "file_check",
"test_file": str(recent[0]),
"message": f"Found recent test: {recent[0].name}",
}
return {
"valid": True,
"method": "user_confirmation",
"message": f"Test validation relies on user confirmation",
"note": "No recent test files found, but task may still be complete",
}
def _validate_database_migration(project_dir: Path) -> Dict:
"""Validate database-migration task."""
# Common migration directories
migration_dirs = [
project_dir / "prisma" / "migrations",
project_dir / "migrations",
project_dir / "db" / "migrations",
project_dir / "alembic" / "versions",
]
for migration_dir in migration_dirs:
if migration_dir.exists():
migrations = list(migration_dir.glob("*"))
recent = [m for m in migrations if _is_recent(m)]
if recent:
return {
"valid": True,
"method": "file_check",
"migration_path": str(recent[0]),
"message": f"Found recent migration: {recent[0].name}",
}
return {
"valid": True,
"method": "user_confirmation",
"message": "Migration validation relies on user confirmation",
"note": "No recent migrations found, but task may still be complete",
}
def _is_recent(path: Path, hours: int = 1) -> bool:
"""Check if file was modified within the last N hours."""
try:
mtime = datetime.fromtimestamp(path.stat().st_mtime)
return datetime.now() - mtime < timedelta(hours=hours)
except (OSError, ValueError):
return False
if __name__ == "__main__":
if len(sys.argv) < 3:
print("Usage: task_validator.py <project_dir> <skill_name>")
sys.exit(1)
result = validate_task(sys.argv[1], sys.argv[2])
print(json.dumps(result, indent=2))
#!/usr/bin/env python3
"""
Personalized workflow generator for Navigator onboarding.
Generates .agent/onboarding/MY-WORKFLOW.md based on project analysis
and skill recommendations.
"""
import json
import sys
from datetime import datetime
from pathlib import Path
from typing import Dict, List
def generate_workflow(
project_dir: str,
project_analysis: Dict,
skill_recommendations: Dict
) -> str:
"""
Generate personalized workflow guide.
Args:
project_dir: Project directory path
project_analysis: Output from project_analyzer.py
skill_recommendations: Output from skill_recommender.py
Returns:
Path to generated workflow file
"""
onboarding_dir = Path(project_dir) / ".agent" / "onboarding"
onboarding_dir.mkdir(parents=True, exist_ok=True)
workflow_file = onboarding_dir / "MY-WORKFLOW.md"
# Extract info
project_name = project_analysis.get("project_name", "Unknown")
project_type = project_analysis.get("project_type", "unknown")
tech_stack = _format_tech_stack(project_analysis)
essential = skill_recommendations.get("skill_details", {}).get("essential", [])
recommended = skill_recommendations.get("skill_details", {}).get("recommended", [])
optional = skill_recommendations.get("skill_details", {}).get("optional", [])
workflow_order = skill_recommendations.get("workflow_order", [])
# Generate sections
workflow_diagram = _generate_workflow_diagram(project_type, workflow_order)
daily_workflow = _generate_daily_workflow(project_type, recommended)
skills_table = _generate_skills_table(essential, recommended, optional)
quick_reference = _generate_quick_reference(essential, recommended)
content = f"""# My Navigator Workflow
**Generated**: {datetime.now().strftime("%Y-%m-%d %H:%M")}
**Project**: {project_name}
**Type**: {project_type.title()}
**Stack**: {tech_stack}
---
## Workflow Diagram
{workflow_diagram}
---
## Daily Workflow
{daily_workflow}
---
## Skills Reference
{skills_table}
---
## Quick Reference
{quick_reference}
---
## Tips for {project_type.title()} Projects
{_generate_tips(project_type, project_analysis)}
---
## Next Steps
1. **Start every session** with: "Start my Navigator session"
2. **Create checkpoints** before breaks: "Create checkpoint [name]"
3. **Document features** when complete: "Archive TASK-XX"
4. **Capture solutions** after debugging: "Create SOP for [issue]"
5. **Clear context** when switching tasks: "Clear context and preserve"
---
*This workflow was personalized for your {project_type} project.*
*Update as your needs evolve.*
**Navigator Version**: 4.6.0
"""
workflow_file.write_text(content)
return str(workflow_file)
def _format_tech_stack(analysis: Dict) -> str:
"""Format tech stack from analysis."""
parts = []
if analysis.get("frontend_framework"):
parts.append(analysis["frontend_framework"])
if analysis.get("backend_framework"):
parts.append(analysis["backend_framework"])
if analysis.get("orm"):
parts.append(analysis["orm"])
elif analysis.get("database"):
parts.append(analysis["database"])
if analysis.get("testing_framework"):
parts.append(analysis["testing_framework"])
return ", ".join(parts) if parts else "Not detected"
def _generate_workflow_diagram(project_type: str, workflow_order: List[str]) -> str:
"""Generate ASCII workflow diagram."""
if project_type == "frontend":
return """```
SESSION START
│
▼
┌─────────────┐
│ nav-start │ "Start my Navigator session"
└──────┬──────┘
│
▼
┌─────────────────────┐
│ Load task doc │ (if continuing work)
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ frontend-component │ "Create component [name]"
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ frontend-test │ "Test this component"
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ nav-task │ "Archive TASK-XX"
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ nav-sop │ (if solved issue)
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ nav-marker │ "Create checkpoint [name]"
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ nav-compact │ (when switching tasks)
└─────────────────────┘
```"""
elif project_type == "backend":
return """```
SESSION START
│
▼
┌─────────────┐
│ nav-start │ "Start my Navigator session"
└──────┬──────┘
│
▼
┌─────────────────────┐
│ Load task doc │ (if continuing work)
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ backend-endpoint │ "Add endpoint [path]"
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ backend-test │ "Write test for [function]"
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ database-migration │ (if schema changes)
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ nav-task │ "Archive TASK-XX"
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ nav-marker │ "Create checkpoint [name]"
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ nav-compact │ (when switching tasks)
└─────────────────────┘
```"""
else: # fullstack or unknown
return """```
SESSION START
│
▼
┌─────────────┐
│ nav-start │ "Start my Navigator session"
└──────┬──────┘
│
▼
┌─────────────────────┐
│ Load task doc │ (if continuing work)
└──────┬──────────────┘
│
├────────────────────────┐
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│frontend-component│ │ backend-endpoint │
└───────┬──────────┘ └────────┬─────────┘
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ frontend-test │ │ backend-test │
└───────┬──────────┘ └────────┬─────────┘
│ │
└───────────┬───────────┘
│
▼
┌─────────────────────┐
│ nav-task │ "Archive TASK-XX"
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ nav-marker │ "Create checkpoint"
└──────┬──────────────┘
│
▼
┌─────────────────────┐
│ nav-compact │ (when switching)
└─────────────────────┘
```"""
def _generate_daily_workflow(project_type: str, recommended: List[Dict]) -> str:
"""Generate daily workflow checklist."""
dev_skills = [s["name"] for s in recommended[:2]] if recommended else ["development skills"]
dev_skills_str = ", ".join(dev_skills)
return f"""### Morning Routine
1. **Start session**: "Start my Navigator session"
2. **Check tasks**: Review `.agent/tasks/` index for current work
3. **Load context**: Read relevant task documentation
### During Development
4. **Use dev skills**: {dev_skills_str}
5. **Create checkpoints**: Before breaks or risky changes
6. **Document decisions**: Update task doc with technical choices
### After Completing Work
7. **Archive task**: "Archive TASK-XX documentation"
8. **Capture solutions**: "Create SOP for [solved issue]"
9. **Final checkpoint**: "Create checkpoint [feature-name]-complete"
### End of Session
10. **Clear context**: "Clear context and preserve markers" (if switching tasks)
11. **Or keep context**: If continuing same work tomorrow"""
def _generate_skills_table(
essential: List[Dict],
recommended: List[Dict],
optional: List[Dict]
) -> str:
"""Generate skills reference tables."""
sections = []
# Essential skills
sections.append("### Essential Skills (Use Daily)\n")
sections.append("| Skill | Description | Trigger |")
sections.append("|-------|-------------|---------|")
for skill in essential:
trigger = skill.get("triggers", [""])[0]
sections.append(f"| {skill['name']} | {skill['description']} | \"{trigger}\" |")
# Recommended skills
if recommended:
sections.append("\n### Development Skills (Use When Building)\n")
sections.append("| Skill | Description | Trigger |")
sections.append("|-------|-------------|---------|")
for skill in recommended:
trigger = skill.get("triggers", [""])[0]
sections.append(f"| {skill['name']} | {skill['description']} | \"{trigger}\" |")
# Optional skills
if optional:
sections.append("\n### Optional Skills (Advanced)\n")
sections.append("| Skill | Description | Trigger |")
sections.append("|-------|-------------|---------|")
for skill in optional:
trigger = skill.get("triggers", [""])[0]
sections.append(f"| {skill['name']} | {skill['description']} | \"{trigger}\" |")
return "\n".join(sections)
def _generate_quick_reference(essential: List[Dict], recommended: List[Dict]) -> str:
"""Generate quick reference table."""
lines = [
"| Action | Say This |",
"|--------|----------|",
"| Start session | \"Start my Navigator session\" |",
"| Save progress | \"Create checkpoint [name]\" |",
"| Document feature | \"Create task doc for [feature]\" |",
"| Archive feature | \"Archive TASK-XX documentation\" |",
"| Capture solution | \"Create SOP for [issue]\" |",
"| Clear context | \"Clear context and preserve markers\" |",
]
# Add first recommended skill
if recommended:
skill = recommended[0]
trigger = skill.get("triggers", [""])[0]
lines.append(f"| {skill['description'][:30]} | \"{trigger}\" |")
return "\n".join(lines)
def _generate_tips(project_type: str, analysis: Dict) -> str:
"""Generate project-type specific tips."""
tips = []
if project_type == "frontend":
tips.extend([
"- Use `frontend-component` to maintain consistent component structure",
"- Create markers before CSS refactoring (easy to mess up)",
"- SOPs are great for browser compatibility fixes",
])
if analysis.get("has_storybook"):
tips.append("- Consider `visual-regression` for UI consistency")
if analysis.get("has_figma_mcp"):
tips.append("- Use `product-design` for design handoff automation")
elif project_type == "backend":
tips.extend([
"- Use `backend-endpoint` for consistent API structure",
"- Create SOPs for auth flows and edge cases",
"- Document database decisions in task docs",
])
if analysis.get("database"):
tips.append(f"- Use `database-migration` for {analysis['database']} schema changes")
elif project_type == "fullstack":
tips.extend([
"- Balance frontend and backend work in single sessions",
"- Create task docs that span both layers",
"- SOPs for API contract changes are invaluable",
"- Compact between frontend and backend focus switches",
])
else:
tips.extend([
"- Use task docs to capture library/package decisions",
"- SOPs for build and publish workflows",
"- Markers before major refactors",
])
return "\n".join(tips)
if __name__ == "__main__":
if len(sys.argv) < 4:
print("Usage: workflow_generator.py <project_dir> <analysis_json> <recommendations_json>")
sys.exit(1)
project_dir = sys.argv[1]
# Load analysis and recommendations
with open(sys.argv[2]) as f:
analysis = json.load(f)
with open(sys.argv[3]) as f:
recommendations = json.load(f)
result = generate_workflow(project_dir, analysis, recommendations)
print(result)
Learning Task 1: Starting Navigator Sessions
Skill: nav-start Time: 3-5 minutes Difficulty: Beginner
Why This Matters
Every Navigator session begins with nav-start. It loads the documentation index (~2k tokens) instead of all documentation at once (~150k tokens). This is the foundation of Navigator's 92% token reduction.
The Task
Step 1: Start Your Session
DO THIS NOW:
Type: "Start my Navigator session"Step 2: Observe What Happens
WHAT SHOULD HAPPEN:
1. Navigator loads DEVELOPMENT-README.md (the index) 2. Session summary appears showing:
- Documentation structure
- Token usage (should be <15k)
- Available task context
You should see something like:
Navigator Session Started
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Project: [your-project-name]
Documentation loaded: DEVELOPMENT-README.md
Token usage: ~12k (vs 150k loading everything)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━Step 3: Understand the Index
NOTICE:
- The index shows WHAT documentation exists
- It does NOT load all the documentation
- You request specific docs when needed
This is lazy loading - the core of Navigator.
Validation
This task is complete when:
- [ ] Session started with "Start my Navigator session"
- [ ] DEVELOPMENT-README.md loaded
- [ ] You see the documentation index structure
Pro Tip
Always start sessions with this command. It sets up efficient context loading for everything else you do. Without it, you'll miss Navigator's benefits.
What You Learned
1. Navigator loads an INDEX, not everything 2. ~2k tokens for index vs ~150k loading all docs 3. Request specific docs as needed (lazy loading)
---
When done, say "done" to continue to the next task.
Learning Task 2: Creating Context Markers
Skill: nav-marker Time: 3-5 minutes Difficulty: Beginner
Why This Matters
Context markers are "save points" for your AI sessions. When you take a break or clear context, the marker preserves what you were working on. A 130k token conversation compresses to ~3k tokens - 97% reduction.
The Task
Step 1: Create a Marker
DO THIS NOW:
Type: "Create checkpoint learning-test"Step 2: Observe What Happens
WHAT SHOULD HAPPEN:
1. System creates marker file in .agent/.context-markers/ 2. Marker captures:
- What you were working on
- Files you modified (if any)
- Technical decisions made
- Next steps
You should see:
✅ Context marker created!
Marker: learning-test
File: .agent/.context-markers/[timestamp]_learning-test.md
Size: ~2-3 KB
This marker captures:
- Session summary
- Current focus
- Next steps
To restore later: "Load marker learning-test"Step 3: Verify the Marker
DO THIS:
Ask: "Show me the marker file that was just created"You should see structured content:
- Conversation Summary
- Files Modified
- Current Focus
- Technical Decisions
- Next Steps
Validation
This task is complete when:
- [ ] Marker created with "Create checkpoint learning-test"
- [ ] File exists in
.agent/.context-markers/ - [ ] Marker contains session summary
Automatic check: File .agent/.context-markers/*learning-test*.md exists.
Pro Tip
Create markers:
- Before breaks (lunch, EOD)
- Before risky refactors
- At milestones (feature complete)
- Before clearing context
Good names: before-refactor, auth-complete, eod-friday Bad names: temp, test1, asdf
What You Learned
1. Markers compress 130k → 3k tokens (97% reduction) 2. They preserve context across sessions 3. Create them before breaks and risky changes
---
When done, say "done" to continue to the next task.
Learning Task 3: Documenting What You Build
Skill: nav-task Time: 4-5 minutes Difficulty: Beginner
Why This Matters
Task documentation captures WHAT you build - implementation plans, technical decisions, and outcomes. This becomes your project's knowledge base. Future sessions can load relevant task docs instead of re-explaining everything.
The Task
Step 1: Create a Task Document
DO THIS NOW:
Type: "Create task doc for learning-feature"Step 2: Observe What Happens
WHAT SHOULD HAPPEN:
1. Task ID generated (TASK-XX format) 2. Template created in .agent/tasks/ 3. Navigator index updated with reference
You should see:
✅ Task document created!
Task: TASK-XX-learning-feature
File: .agent/tasks/TASK-XX-learning-feature.md
Template includes:
- Problem Statement
- Implementation Plan
- Technical Decisions
- Success Criteria
Fill this in as you implement the feature.Step 3: Review the Template
DO THIS:
Ask: "Show me the task document that was created"The template has sections for:
- Context: Why this feature exists
- Implementation Plan: Steps to build it
- Technical Decisions: Architecture choices
- Files Modified: What changed
- Success Criteria: How to verify completion
Step 4: Understand the Workflow
Task docs have two phases: 1. Planning: Create doc when starting feature 2. Archiving: Update doc when feature complete
The archive captures what was ACTUALLY built vs what was planned.
Validation
This task is complete when:
- [ ] Task doc created with "Create task doc for learning-feature"
- [ ] File exists in
.agent/tasks/ - [ ] Template structure visible
Automatic check: File .agent/tasks/*learning-feature*.md exists.
Pro Tip
Task docs answer: "What did we build and why?"
When returning to a feature months later: 1. nav-start loads the index 2. Find relevant TASK-XX in index 3. Load just that task doc (~3k tokens) 4. Full context without re-explaining
This is much more efficient than:
- Searching through git history
- Re-reading all source files
- Asking "what was the original plan?"
What You Learned
1. Task docs capture implementation knowledge 2. Created at start (planning) and updated at end (archiving) 3. Future sessions load task docs for context
---
When done, say "done" to continue to the next task.
Learning Task 4: Capturing Solutions for Reuse
Skill: nav-sop Time: 4-5 minutes Difficulty: Beginner
Why This Matters
SOPs (Standard Operating Procedures) capture HOW to solve problems. When you debug a tricky issue, the SOP ensures you never waste time solving it again. This is institutional knowledge that compounds over time.
The Task
Step 1: Create an SOP
DO THIS NOW:
Type: "Create SOP for debugging test-failures"Step 2: Observe What Happens
WHAT SHOULD HAPPEN:
1. SOP file created in .agent/sops/debugging/ 2. Template includes problem, solution, prevention 3. Categories: debugging, integrations, development, deployment
You should see:
✅ SOP created!
SOP: debugging-test-failures
File: .agent/sops/debugging/test-failures.md
Category: debugging
Template includes:
- Problem Description
- Root Cause
- Solution Steps
- Prevention ChecklistStep 3: Review the Template
DO THIS:
Ask: "Show me the SOP that was created"The SOP template has:
- Problem: What went wrong
- Symptoms: How it manifests
- Root Cause: Why it happened
- Solution: Step-by-step fix
- Prevention: How to avoid recurrence
Step 4: Understand SOP Categories
SOPs are organized by type:
debugging/- Bug fixes and troubleshootingintegrations/- Third-party service setupdevelopment/- Coding workflows and patternsdeployment/- Release and infrastructure
Validation
This task is complete when:
- [ ] SOP created with "Create SOP for debugging test-failures"
- [ ] File exists in
.agent/sops/debugging/ - [ ] Template structure visible
Automatic check: File in .agent/sops/*/ exists.
Pro Tip
The best time to create an SOP is RIGHT AFTER solving a problem:
- Context is fresh
- Solution is validated
- Details are accurate
Future you (or teammates) will thank you when:
- Same error appears 6 months later
- New team member hits the same issue
- You forgot the obscure fix
SOP vs Task Doc:
- Task: What we built (the feature)
- SOP: How we solved problems (the knowledge)
What You Learned
1. SOPs capture problem-solving knowledge 2. Create them immediately after solving issues 3. Categories help organize by type (debugging, integrations, etc.)
---
When done, say "done" to continue to the next task.
Learning Task 5: Managing Context Efficiently
Skill: nav-compact Time: 3-5 minutes Difficulty: Beginner
Why This Matters
Context windows fill up. When they do, AI starts forgetting, hallucinating, or crashes. Compact clears context while preserving progress via markers. This is how you maintain efficiency across long sessions.
The Task
Step 1: Initiate Compact
DO THIS NOW:
Type: "Clear context and preserve markers"Step 2: Observe What Happens
WHAT SHOULD HAPPEN:
1. Automatic marker created (preserves current state) 2. .active file set (for auto-restore next session) 3. Instructions for manual clear provided
You should see:
✅ Ready to compact!
Marker created: before-compact-[timestamp]
Location: .agent/.context-markers/
Active marker set: ✅ (will auto-restore next session)
To complete compact:
1. Start a new conversation (or use /clear)
2. Say "Start my Navigator session"
3. Marker will auto-restore your context
Your progress is preserved in the marker.Step 3: Understand the Process
IMPORTANT: Claude cannot clear conversation programmatically.
The compact workflow: 1. nav-compact creates marker + sets .active 2. YOU start new conversation (or /clear) 3. Next nav-start detects .active marker 4. Offers to restore your context
Step 4: (Optional) Complete the Compact
If you want to practice the full cycle:
1. Start a new conversation 2. Type: "Start my Navigator session" 3. See the auto-restore offer 4. Confirm to load your marker
Validation
This task is complete when:
- [ ] Compact initiated with "Clear context and preserve markers"
- [ ] Marker created automatically
- [ ]
.activefile set for auto-restore
Automatic check: File .agent/.context-markers/.active exists.
Pro Tip
When to compact:
- After completing isolated feature (switch to new work)
- When context feels "heavy" (many files loaded)
- After debugging session (clear noise)
- Before major topic change
When NOT to compact:
- Mid-feature implementation
- While debugging (need context)
- When files from current work are still needed
The flow:
Start session → Work → Marker → Compact → New session → Auto-restore → ContinueWhat You Learned
1. Compact clears context while preserving progress 2. Markers auto-restore on next session 3. Use after completing work units, not mid-work
---
When done, say "done" to continue to the next task.
Learning Task 6: Using Development Skills
Skill: Project-specific (frontend-component, backend-endpoint, etc.) Time: 5-7 minutes Difficulty: Intermediate
Why This Matters
Development skills generate boilerplate code following your project's patterns. Instead of writing everything from scratch, you describe what you need and Navigator creates consistent, tested code.
The Task
Based on your project type, complete ONE of these:
---
Option A: Frontend Projects (React/Vue/Angular)
DO THIS NOW:
Type: "Create component OnboardingDemo"WHAT SHOULD HAPPEN: 1. Component file created with TypeScript 2. Test file generated 3. Styles scaffolded (CSS modules, styled-components, or Tailwind)
You should see files like:
src/components/OnboardingDemo/
├── OnboardingDemo.tsx
├── OnboardingDemo.test.tsx
├── OnboardingDemo.styles.ts (or .module.css)
└── index.ts---
Option B: Backend Projects (Express/FastAPI/Go)
DO THIS NOW:
Type: "Add endpoint /api/onboarding-demo"WHAT SHOULD HAPPEN: 1. Route handler created 2. Validation schema generated 3. Test file scaffolded
You should see files like:
src/routes/onboarding-demo.ts (or .py)
src/routes/onboarding-demo.test.ts---
Option C: Fullstack Projects
Choose either Option A or B based on what you're working on.
---
Option D: Other Project Types
If your project doesn't match above:
Type: "Show me available Navigator skills"Review what skills are available for your stack.
Validation
This task is complete when:
- [ ] Component OR endpoint created
- [ ] Files generated match project patterns
- [ ] You understand how the skill works
Note: File locations depend on your project structure.
Pro Tip
Development skills learn from your project:
- Detect TypeScript vs JavaScript
- Match existing file structure
- Use project's testing library
- Follow your naming conventions
The generated code is a starting point - customize as needed.
Workflow integration:
nav-start → Load task doc → Use dev skills → nav-task archive → nav-marker → nav-compactWhat You Learned
1. Dev skills generate consistent boilerplate 2. They detect your project patterns 3. Files are customizable starting points
---
When done, say "done" to continue.
You've completed all learning tasks! Navigator will now generate your personalized workflow guide.
Navigator Onboarding Progress
Started: ${START_DATE} Flow: ${FLOW_TYPE} Project: ${PROJECT_NAME} (${PROJECT_TYPE})
---
Essential Skills
| # | Skill | Status | Completed | Notes |
|---|
${ESSENTIAL_SKILLS_ROWS}
Development Skills
| # | Skill | Status | Completed | Notes |
|---|
${DEV_SKILLS_ROWS}
---
Progress: ${COMPLETED}/${TOTAL} (${PERCENTAGE}%) Next Task: ${NEXT_TASK}
Last Updated: ${LAST_UPDATED}
My Navigator Workflow
Generated: ${DATE} Project: ${PROJECT_NAME} Type: ${PROJECT_TYPE} Stack: ${TECH_STACK}
---
Workflow Diagram
${WORKFLOW_DIAGRAM}
---
Daily Workflow
Morning Routine
1. Start session: "Start my Navigator session" 2. Check tasks: Review .agent/tasks/ index for current work 3. Load context: Read relevant task documentation
During Development
4. Use dev skills: ${DEV_SKILLS} 5. Create checkpoints: Before breaks or risky changes 6. Document decisions: Update task doc with technical choices
After Completing Work
7. Archive task: "Archive TASK-XX documentation" 8. Capture solutions: "Create SOP for [solved issue]" 9. Final checkpoint: "Create checkpoint [feature-name]-complete"
End of Session
10. Clear context: "Clear context and preserve markers" (if switching tasks) 11. Or keep context: If continuing same work tomorrow
---
Skills Reference
Essential Skills (Use Daily)
| Skill | Description | Trigger |
|---|
${ESSENTIAL_SKILLS_TABLE}
Development Skills (Use When Building)
| Skill | Description | Trigger |
|---|
${DEV_SKILLS_TABLE}
Optional Skills (Advanced)
| Skill | Description | Trigger |
|---|
${OPTIONAL_SKILLS_TABLE}
---
Quick Reference
| Action | Say This |
|---|---|
| Start session | "Start my Navigator session" |
| Save progress | "Create checkpoint [name]" |
| Document feature | "Create task doc for [feature]" |
| Archive feature | "Archive TASK-XX documentation" |
| Capture solution | "Create SOP for [issue]" |
| Clear context | "Clear context and preserve markers" |
---
Tips for ${PROJECT_TYPE} Projects
${PROJECT_TIPS}
---
Next Steps
1. Start every session with: "Start my Navigator session" 2. Create checkpoints before breaks: "Create checkpoint [name]" 3. Document features when complete: "Archive TASK-XX" 4. Capture solutions after debugging: "Create SOP for [issue]" 5. Clear context when switching tasks: "Clear context and preserve"
---
This workflow was personalized for your ${PROJECT_TYPE} project. Update as your needs evolve.
Navigator Version: ${NAVIGATOR_VERSION}