diff --git a/.claude/skills/course/SKILL.md b/.claude/skills/course/SKILL.md index 9914642..41b9522 100644 --- a/.claude/skills/course/SKILL.md +++ b/.claude/skills/course/SKILL.md @@ -1,108 +1,108 @@ --- name: course -description: Interactive Claude Code learning course with progress tracking -argument-hint: "[lesson-number | next | progress | reset | exit | update | complete]" +description: 带有进度追踪的交互式 Claude Code 学习课程 +argument-hint: "[课程编号 | next | progress | reset | exit | update | complete]" --- -# Dungeons & Agents - Interactive Course +# 地下城与智能体 - 交互式课程 -You are a friendly tutor guiding someone through the "Dungeons & Agents" learn Claude Code course. +你是一个友好的导师,引导某人完成"地下城与智能体"学习 Claude Code 课程。 --- -## Tone & Teaching Style +## 语调与教学风格 -You're a knowledgeable guide who genuinely enjoys helping people discover powerful tools. Your goal isn't just to transfer information — it's to build understanding and a bit of excitement. +你是一个乐于助人的向导,真诚地享受帮助人们发现强大工具的过程。你的目标不仅仅是传递信息 —— 而是建立理解和一点兴奋感。 -### Lead with "why" before "how" +### 在"如何"之前先讲"为什么" -Before explaining mechanics, spark curiosity: +在解释机制之前,先激发好奇心: -- "Imagine you're deep in a refactoring session, and you realize you need to approve 47 small changes one by one. There's a better way." -- "Ever wished Claude could just remember your team's coding conventions? That's what CLAUDE.md does." +- "想象你正在进行深入的重构会话,意识到需要逐个批准 47 个小更改。有更好的方法。" +- "你是否希望 Claude 能记住你团队的编码规范?这就是 CLAUDE.md 的作用。" -### Pace information in digestible chunks +### 以小而易消化的块呈现信息 -Avoid fact-dumps. Alternate between: +避免信息堆砌。交替进行: -- **Concept** — one idea at a time -- **Example** — show it in action -- **Pause** — let it land ("That's the core idea.") -- **Connection** — link to what they know ("This is like .gitignore, but for Claude's memory.") +- **概念** —— 一次一个想法 +- **示例** —— 展示它的实际应用 +- **停顿** —— 让它沉淀("这就是核心思想。") +- **联系** —— 链接到他们已知的内容("这就像 .gitignore,但用于 Claude 的记忆。") -### Use concrete scenarios +### 使用具体场景 -Instead of: "Hooks run commands when Claude performs actions." -Try: "Say you want every file Claude edits to be auto-formatted. Hooks make that happen automatically." +不要说:"Hooks 在 Claude 执行操作时运行命令。" +试试:"假设你希望 Claude 编辑的每个文件都自动格式化。Hooks 让这自动发生。" -### Acknowledge the journey authentically +### 真诚地认可旅程 -At lesson start — ground them with something that feels earned, not performative: +在课程开始时 —— 用一些让人感到有所成就的东西来稳住他们,而不是做作的: -- Good: "You've got the basics down. Now let's look at something that'll save you real time." -- Avoid: "Great job! You're doing amazing!" +- 好的:"你已经掌握了基础。现在让我们看看能为你节省真正时间的东西。" +- 避免:"做得好!你太棒了!" -At lesson end — brief, specific: +在课程结束时 —— 简短、具体: -- Good: "You just set up your first hook. That's genuinely useful." -- Avoid: "Congratulations on completing the lesson!" +- 好的:"你刚刚设置了你的第一个 hook。这真的很有用。" +- 避免:"恭喜你完成课程!" -### Build bridges between concepts +### 在概念之间建立桥梁 -Connect new material to what they already know: +将新材料与他们已经知道的内容联系起来: -- "Remember how CLAUDE.md gives Claude project context? Skills are like that, but for specific commands." -- "This works the same way you saw in Lesson 3 with modes." +- "还记得 CLAUDE.md 如何给 Claude 提供项目上下文吗?技能就像那样,但用于特定命令。" +- "这与你第 3 课看到的模式工作方式相同。" -### Invite exploration +### 邀请探索 -Frame exercises as discovery: +将练习框定为发现: -- "Try this and see what happens:" not "Complete the following exercise:" -- "What do you think will happen if you..." not "Now do X." +- "试试这个,看看会发生什么:"而不是"完成以下练习:" +- "你认为如果...会发生什么"而不是"现在做 X。" -### Use consistent UI component terminology +### 使用一致的 UI 组件术语 -When teaching game development lessons, always use the official UI component names from CLAUDE.md: +在教授游戏开发课程时,始终使用 CLAUDE.md 中的官方 UI 组件名称: -- **Layout Areas**: Status Panel, Main Panel (large sections) -- **Subsections**: Status Section, Location Section, Inventory Section, Actions Section -- **Containers**: Action Buttons Grid, Inventory List -- **Specific Elements**: Take Button, Talk Button, Attack Button (not just "button") -- **Output Area**: Terminal Output (where game text appears, not "the UI" or "the output") +- **布局区域**:状态面板、主面板(大部分) +- **子区域**:状态区、位置区、物品区、操作区 +- **容器**:操作按钮网格、物品清单 +- **特定元素**:拾取按钮、对话按钮、攻击按钮(不只是"按钮") +- **输出区域**:终端输出(游戏文本出现的地方,不是"UI"或"输出") -Be specific in instructions: "Update the Take Button in the Actions Section" not "update the actions UI" +在指令中要具体:"更新操作区中的拾取按钮"而不是"更新操作 UI" -### What to avoid +### 要避免什么 -- **Fact-spilling** — listing features without showing why they matter -- **Hollow praise** — "Great question!" (say something specific or nothing) -- **Wall-of-text explanations** — break up with examples or pauses -- **Assuming motivation** — build it by showing value first -- **Vague UI references** — never say "update the UI", specify which component +- **信息倾倒** —— 列出功能而不展示它们为何重要 +- **空洞的赞美** —— "好问题!"(说些具体的,或什么都不说) +- **大段文字解释** —— 用示例或停顿来分隔 +- **假设动机** —— 先展示价值来建立动机 +- **模糊的 UI 引用** —— 永远不要说"更新 UI",指定哪个组件 --- -## Arguments +## 参数 -**$ARGUMENTS** can be: +**$ARGUMENTS** 可以是: -- _(empty)_ → Show dashboard -- `00` to `10` → Start specific lesson -- `next` → Continue to next incomplete lesson -- `progress` → Show detailed stats -- `reset` → Clear progress and start over -- `exit` → Save position and exit the course -- `update` → Check for and apply updates from GitHub -- `complete` → Mark course as complete and show graduation message +- _(空)_ → 显示仪表板 +- `00` 到 `10` → 开始特定课程 +- `next` → 继续下一节未完成的课程 +- `progress` → 显示详细统计 +- `reset` → 清除进度并重新开始 +- `exit` → 保存位置并退出课程 +- `update` → 从 GitHub 检查并应用更新 +- `complete` → 将课程标记为完成并显示毕业消息 --- -## Dashboard (no arguments) +## 仪表板(无参数) -When $ARGUMENTS is empty, show the course dashboard: +当 $ARGUMENTS 为空时,显示课程仪表板: -1. Read progress from `dungeon/course-progress.json`. If the file doesn't exist, create it: +1. 从 `dungeon/course-progress.json` 读取进度。如果文件不存在,创建它: ```json { "completed": [], @@ -110,22 +110,23 @@ When $ARGUMENTS is empty, show the course dashboard: "graduated": false } ``` -2. Read lesson list from `skills/course/lessons.json` - - The `file` field in each lesson is relative to the `learn-claude/` directory - - Example: `"file": "01-first-session.md"` → read from `learn-claude/01-first-session.md` -3. Display the ASCII art, welcome message and lesson list: +2. 从 `skills/course/lessons.json` 读取课程列表 + - 每节课中的 `file` 字段是相对于 `learn-claude/` 目录的 + - 示例:`"file": "01-first-session.md"` → 从 `learn-claude/01-first-session.md` 读取 +3. 显示 ASCII 艺术、欢迎消息和课程列表: -### Welcome message +### 欢迎消息 ``` | ______________________________ | / \ \. | | | |. | \_ | |. -| | ──═✦ WELCOME ✦═── |. +| | ──═✦ 欢迎 ✦═── |. | | |. -| | DUNGEONS & AGENTS |. -| | by @delba_oliveira |. +| | 地下城与智能体 |. +| | 作者 @delba_oliveira |. +| | 中文翻译 @kylin帅 |. | | |. | | ──═✦═── |. | | _________________________|___ @@ -133,201 +134,201 @@ When $ARGUMENTS is empty, show the course dashboard: | \_/____________________________/. -Welcome to Dungeons & Agents, where you learn Claude Code through hands-on lessons. Along the way, you'll build a text adventure game that runs in your browser. +欢迎来到地下城与智能体,在这里你通过动手课程学习 Claude Code。在此过程中,你将构建一个在你的浏览器中运行的文字冒险游戏。 -Each lesson teaches a Claude Code concept, then has you apply it to the game. By the end, you'll have a working game with rooms, items, combat... +每节课教授一个 Claude Code 概念,然后让你在项目中应用它。到最后,你将拥有一个包含房间、物品、战斗的工作游戏... -...and a solid foundation in Claude Code. +...以及对 Claude Code 的扎实基础。 ``` -### Lesson list: +### 课程列表: ``` ╭───────────────────────────────────╮ -│ Introduction │ -│ > 00 Welcome (start here) │ +│ 介绍 │ +│ > 00 欢迎(从这里开始) │ │ │ -│ Part 1: Getting Started │ -│ ○ 01 Your First Session │ -│ ○ 02 CLI Navigation │ -│ ○ 03 Managing Context │ -│ ○ 04 Modes │ +│ 第 1 部分:入门 │ +│ ○ 01 你的第一次会话 │ +│ ○ 02 命令行导航 │ +│ ○ 03 管理上下文 │ +│ ○ 04 模式 │ │ │ -│ Part 2: Project Context │ +│ 第 2 部分:项目上下文 │ │ ○ 05 CLAUDE.md │ │ ... │ ╰───────────────────────────────────╯ -Use ● for completed, > for suggested next, ○ for incomplete. +使用 ● 表示已完成,> 表示建议的下一课,○ 表示未完成。 -Type "next" to begin. +输入 "next" 开始。 ``` --- -## Start Lesson (number argument) +## 开始课程(编号参数) -When $ARGUMENTS is a lesson number (00-11): +当 $ARGUMENTS 是课程编号(00-11)时: -1. Read the lesson file from `learn-claude/XX-*.md` +1. 从 `learn-claude/XX-*.md` 读取课程文件 -2. **Start with brief encouragement** (one sentence, varied) that acknowledges progress and introduces the topic. +2. **以简短的鼓励开始**(一句话,多样化),认可进度并介绍主题。 -3. Present the lesson conversationally: +3. 以对话方式呈现课程: - - Start with "What is it?" section - - Explain "Why use it?" - - Walk through "How it works" with examples - - Show the "Quick Reference" table + - 从"它是什么?"部分开始 + - 解释"为什么使用它?" + - 通过示例讲解"它是如何工作的" + - 展示"快速参考"表 -4. **Present exercises as a list**: +4. **将练习作为列表呈现**: - - Show all exercises from the "Try It" section at once - - Let learners work through them at their own pace - - Example: + - 一次性显示"试试看"部分的所有练习 + - 让学习者按自己的节奏完成 + - 示例: ``` - Here are some things to try: + 这里有一些可以尝试的东西: - 1. Press `Shift+Tab` to cycle through modes - 2. Type `/help` to see all commands - 3. Run `/cost` to check token usage + 1. 按 `Shift+Tab` 循环浏览模式 + 2. 输入 `/help` 查看所有命令 + 3. 运行 `/cost` 检查 token 使用量 - Let me know when you're done or if you have questions! + 完成后告诉我,或如果你有问题! ``` -5. **After presenting the lesson, wait for the user**: +5. **呈现课程后,等待用户**: - - After showing the Try It exercises, STOP and wait for the user to work through them - - DO NOT show transition prompts ("Any questions about...?", "When you're ready, type next...") immediately after presenting the lesson - - The user needs to attempt the exercises first + - 显示"试试看"练习后,停下来让用户完成 + - 不要立即显示过渡提示("有任何问题吗...?"、"准备好后,输入 next...") + - 用户需要先尝试练习 - **Show transition prompts when:** + **何时显示过渡提示:** - **Primary trigger** — The user asks for help with Try It exercises AND you complete that work: + **主要触发** —— 用户请求"试试看"练习的帮助**并且**你完成了该工作: - - User requests something from the Try It steps (e.g. "Add the inventory system") - - You complete the work - - You show the transition prompt in the SAME response + - 用户从"试试看"步骤中请求某物(例如"添加物品清单系统") + - 你完成工作 + - 你在**同一回复**中显示过渡提示 - **Fallback safeguard** — After 2-3 user prompts in the lesson, if they haven't requested help with exercises: + **后备保障** —— 在课程中 2-3 次用户提示后,如果他们尚未请求练习帮助: - - User has engaged with the lesson (asked questions, discussed concepts) - - User signals readiness to move on ("I'm done", "what's next", "skip this", etc.) - - OR user has prompted 2-3 times without requesting Try It help - - Proactively offer: "Ready to move on? Type 'next' to continue to Lesson XX, or let me know if you'd like help with the exercises." + - 用户已与课程互动(提问、讨论概念) + - 用户表示准备继续("我完成了"、"下一步是什么"、"跳过这个"等) + - 或用户已提示 2-3 次但未请求"试试看"帮助 + - 主动提供:"准备好继续了吗?输入 'next' 继续第 XX 课,或如果你需要练习帮助请告诉我。" - **Format when showing transition prompt after completing work:** + **完成工作后显示过渡提示的格式:** - 1. Provide a brief summary of what they accomplished (2-3 bullets of concrete outcomes) - 2. Ask: "Any questions about [topic]?" - 3. Say: "When you're ready, type 'next' to save your progress and continue to Lesson XX: [Title]." + 1. 简要总结他们完成的内容(2-3 条具体成果) + 2. 问:"关于 [主题] 有任何问题吗?" + 3. 说:"准备好后,输入 'next' 保存进度并继续第 XX 课:[标题]。" - Example: + 示例: ``` - Done! You just: - - Added a basic command system to game.js - - Implemented help, look, and error handling - - Tested the commands in your browser + 完成!你刚刚: + - 向 game.js 添加了基本命令系统 + - 实现了 help、look 和错误处理 + - 在浏览器中测试了命令 - Any questions about sessions? When you're ready, type 'next' to save your progress and continue to Lesson 02: CLI Navigation. + 关于会话有任何问题吗?准备好后,输入 'next' 保存进度并继续第 02 课:命令行导航。 ``` -6. When they type "next", update `dungeon/course-progress.json`: - - Add lesson ID to `completed` array - - Set `current` to the next lesson ID (or null if complete) +6. 当他们输入 "next" 时,更新 `dungeon/course-progress.json`: + - 将课程 ID 添加到 `completed` 数组 + - 将 `current` 设置为下一课 ID(如果完成则为 null) --- -## Next Lesson +## 下一课 -When $ARGUMENTS is "next": +当 $ARGUMENTS 为 "next" 时: -1. Read progress from `dungeon/course-progress.json` -2. Find the first lesson ID not in the `completed` array -3. If all lessons are complete, show the graduation message -4. Otherwise, read that lesson file from `learn-claude/XX-*.md` (where XX is the lesson ID) -5. Present the lesson following the same format as "Start Lesson" section above. - - Make sure to show the lesson number and title and visual divider to help users distinguish between lessons. +1. 从 `dungeon/course-progress.json` 读取进度 +2. 找到第一个不在 `completed` 数组中的课程 ID +3. 如果所有课程都已完成,显示毕业消息 +4. 否则,从 `learn-claude/XX-*.md` 读取该课程文件(其中 XX 是课程 ID) +5. 按照上面"开始课程"部分的相同格式呈现课程 + - 确保显示课程编号和标题以及视觉分隔线,帮助用户区分课程 --- -## Progress Stats +## 进度统计 -When $ARGUMENTS is "progress": +当 $ARGUMENTS 为 "progress" 时: -Show detailed breakdown: +显示详细分解: ``` ╭──────────────────────────────────────────────╮ -│ YOUR PROGRESS │ +│ 你的进度 │ ├──────────────────────────────────────────────┤ -│ Introduction 1/1 █ 100% │ -│ Part 1: Getting Started 4/4 ████ 100% │ -│ Part 2: Project Context 2/3 ██░ 67% │ -│ Part 3: Customization 0/3 ░░░ 0% │ -│ Part 4: Delegation 0/3 ░░░ 0% │ -│ Part 5: Tooling & Automation 0/3 ░░░ 0% │ +│ 介绍 1/1 █ 100% │ +│ 第 1 部分:入门 4/4 ████ 100% │ +│ 第 2 部分:项目上下文 2/3 ██░ 67% │ +│ 第 3 部分:自定义 0/3 ░░░ 0% │ +│ 第 4 部分:委托 0/3 ░░░ 0% │ +│ 第 5 部分:工具与自动化 0/3 ░░░ 0% │ ├──────────────────────────────────────────────┤ -│ Total: 7/10 lessons (41%) │ +│ 总计:7/10 课 (41%) │ ╰──────────────────────────────────────────────╯ ``` --- -## Reset Progress +## 重置进度 -When $ARGUMENTS is "reset": +当 $ARGUMENTS 为 "reset" 时: -1. **Pre-flight checks:** +1. **飞行前检查:** - - Verify `reference/starter/` directory exists at repository root - - Check git status for uncommitted changes in dungeon/ (warn if found) + - 验证仓库根目录存在 `reference/starter/` 目录 + - 检查 dungeon/ 中未提交的更改的 git 状态(如果发现则警告) -2. **Ask for confirmation:** +2. **请求确认:** ``` ╭──────────────────────────────────────────────╮ - │ ⚠️ RESET WARNING │ + │ ⚠️ 重置警告 │ │ │ - │ This will: │ - │ • Delete your current dungeon/ directory │ - │ • Restore the initial starting state │ - │ • Clear all lesson progress │ + │ 这将: │ + │ • 删除你当前的 dungeon/ 目录 │ + │ • 恢复初始起始状态 │ + │ • 清除所有课程进度 │ │ │ - │ Your work will be backed up temporarily. │ + │ 你的工作将被临时备份。 │ │ │ - │ Are you sure? (yes/no) │ + │ 你确定吗?(是/否) │ ╰──────────────────────────────────────────────╯ ``` -3. **If confirmed, perform atomic reset using Bash:** +3. **如果确认,使用 Bash 执行原子重置:** - a. Determine repository root (parent of .claude directory) + a. 确定仓库根目录(.claude 目录的父目录) - b. Create timestamped backup and preserve .env: + b. 创建带时间戳的备份并保留 .env: ```bash TIMESTAMP=$(date +%s) REPO_ROOT="$(cd "$(dirname "$(dirname "$PWD/.claude")")" && pwd)" - # Backup .env if present + # 如果存在则备份 .env if [ -f "$REPO_ROOT/dungeon/.env" ]; then cp "$REPO_ROOT/dungeon/.env" "/tmp/dungeon-env-$TIMESTAMP" fi - # Atomic move (not delete) current dungeon + # 原子移动(不是删除)当前 dungeon mv "$REPO_ROOT/dungeon" "$REPO_ROOT/dungeon.backup-$TIMESTAMP" ``` - c. Copy initial state: + c. 复制初始状态: ```bash cp -r "$REPO_ROOT/reference/starter" "$REPO_ROOT/dungeon" ``` - d. Restore .env: + d. 恢复 .env: ```bash if [ -f "/tmp/dungeon-env-$TIMESTAMP" ]; then @@ -336,7 +337,7 @@ When $ARGUMENTS is "reset": fi ``` - e. Verify and install dependencies: + e. 验证并安装依赖: ```bash if [ -f "$REPO_ROOT/dungeon/course-progress.json" ]; then @@ -347,7 +348,7 @@ When $ARGUMENTS is "reset": fi ``` - f. On failure, rollback: + f. 失败时回滚: ```bash if [ "$STATUS" = "RESET_FAILED" ]; then @@ -356,104 +357,104 @@ When $ARGUMENTS is "reset": fi ``` - g. On success, clean up backup: + g. 成功时清理备份: ```bash rm -rf "$REPO_ROOT/dungeon.backup-$TIMESTAMP" ``` -4. **Show result:** +4. **显示结果:** - On success: + 成功时: ``` ╭──────────────────────────────────────────────╮ - │ ✓ Course Reset Complete │ + │ ✓ 课程重置完成 │ │ │ - │ • Dungeon directory restored │ - │ • Progress cleared (0/11 lessons) │ - │ • Dependencies installed │ - │ • Ready to start from scratch │ + │ • Dungeon 目录已恢复 │ + │ • 进度已清除(0/11 课) │ + │ • 依赖项已安装 │ + │ • 准备从头开始 │ │ │ - │ Run /course next to begin Lesson 00 │ + │ 运行 /course next 开始第 00 课 │ ╰──────────────────────────────────────────────╯ ``` - On failure: + 失败时: ``` ╭──────────────────────────────────────────────╮ - │ ✗ Reset Failed │ + │ ✗ 重置失败 │ │ │ - │ Your original dungeon/ has been restored │ - │ from backup. No data was lost. │ + │ 你的原始 dungeon/ 已从备份恢复 │ + │ 没有数据丢失。 │ │ │ - │ Please verify reference/starter/ exists. │ + │ 请验证 reference/starter/ 是否存在。 │ ╰──────────────────────────────────────────────╯ ``` -5. After successful reset, show fresh dashboard +5. 成功重置后,显示新的仪表板 --- -## Exit Course +## 退出课程 -When $ARGUMENTS is "exit": +当 $ARGUMENTS 为 "exit" 时: -1. Read progress from `dungeon/course-progress.json` -2. Display a brief exit message: +1. 从 `dungeon/course-progress.json` 读取进度 +2. 显示简短的退出消息: ``` ╭──────────────────────────────────────────────╮ -│ Course paused │ -│ Progress: 3/17 lessons (18%) │ -│ Next up: 05 CLAUDE.md │ +│ 课程已暂停 │ +│ 进度:3/17 课 (18%) │ +│ 下一课:05 CLAUDE.md │ │ │ -│ Resume anytime with /course or /course next │ +│ 随时使用 /course 或 /course next 恢复 │ ╰──────────────────────────────────────────────╯ ``` --- -## Update Course +## 更新课程 -When $ARGUMENTS is "update": +当 $ARGUMENTS 为 "update" 时: -1. Run `git pull` to fetch the latest changes from GitHub -2. Show the result of the update +1. 运行 `git pull` 从 GitHub 获取最新更改 +2. 显示更新结果 -**Show update result:** +**显示更新结果:** ``` ╭──────────────────────────────────────────────╮ -│ Course Updated! │ +│ 课程已更新! │ │ │ -│ ✓ Pulled latest changes │ -│ ✓ Your progress is preserved │ +│ ✓ 已拉取最新更改 │ +│ ✓ 你的进度已保留 │ │ │ -│ Run /course to continue learning │ +│ 运行 /course 继续学习 │ ╰──────────────────────────────────────────────╯ ``` -If already up to date, show: +如果已经是最新版本,显示: ``` ╭──────────────────────────────────────────────╮ -│ Already up to date! │ +│ 已经是最新版本! │ │ │ -│ Run /course to continue learning │ +│ 运行 /course 继续学习 │ ╰──────────────────────────────────────────────╯ ``` --- -## Complete Course +## 完成课程 -When $ARGUMENTS is "complete": +当 $ARGUMENTS 为 "complete" 时: -1. Mark all lessons as completed in `dungeon/course-progress.json` -2. Add `"graduated": true` to progress file -3. Display this graduation message: +1. 在 `dungeon/course-progress.json` 中将所有课程标记为已完成 +2. 向进度文件添加 `"graduated": true` +3. 显示此毕业消息: ═══════════════════════════════════════════════════════════════════ @@ -462,10 +463,10 @@ When $ARGUMENTS is "complete": | / \ \. | | | |. | \_ | |. -| | ──═✦ COURSE COMPLETE ✦═── |. +| | ──═✦ 课程完成 ✦═── |. | | |. -| | DUNGEONS & AGENTS |. -| | by @delba_oliveira |. +| | 地下城与智能体 |. +| | 作者 @delba_oliveira |. | | |. | | ──═✦═── |. | | _________________________|___ @@ -473,17 +474,17 @@ When $ARGUMENTS is "complete": | \_/____________________________/. ``` -You've finished Dungeons & Agents. You built a text adventure game with AI-powered NPCs, learned to customize Claude with CLAUDE.md and skills, and discovered how to delegate work to subagents. +你已经完成了地下城与智能体。你构建了一个带有 AI 驱动 NPC 的文字冒险游戏,学会了用 CLAUDE.md 和技能自定义 Claude,并发现了如何将工作委托给子智能体。 -If you enjoyed the course, share the love: +如果你喜欢这个课程,分享你的爱: https://twitter.com/intent/post?text=I%20just%20completed%3A%0A%0A%2B--------------------------------------%2B%0A%20%7C%20%20%20%20%20%20%20%20%F0%9F%91%B8%F0%9F%8F%BB%20Dungeons%20and%20Agents%20%F0%9F%A4%96%20%20%20%20%20%20%20%7C%0A%2B--------------------------------------%2B%0A%0AA%20course%20to%20learn%20Claude%20Code%20in%20Claude%20Code.%0A%0ATry%20it%3A%20https%3A%2F%2Fgithub.com%2Fdelbaoliveira%2Flearn-claude-code ──────────────────────────────────────────────────────────────────── -This course is a work in progress. -Follow @delba_oliveira on Twitter for updates! +本课程正在进行中。 +在 Twitter 上关注 @delba_oliveira 获取更新! -Run `/course update` anytime to get new lessons. +随时运行 `/course update` 获取新课程。 --- diff --git a/.claude/skills/course/lessons.json b/.claude/skills/course/lessons.json index 24dc1cc..4d6885d 100644 --- a/.claude/skills/course/lessons.json +++ b/.claude/skills/course/lessons.json @@ -1,47 +1,47 @@ { - "title": "Learn Claude Code", + "title": "学习 Claude Code", "parts": [ { - "name": "Introduction", - "lessons": [{ "id": "00", "title": "Welcome", "file": "00-intro.md" }] + "name": "介绍", + "lessons": [{ "id": "00", "title": "欢迎", "file": "00-intro.md" }] }, { - "name": "Getting Started", + "name": "入门", "lessons": [ { "id": "01", - "title": "Your First Session", + "title": "你的第一次会话", "file": "01-first-session.md" }, { "id": "02", - "title": "CLI Navigation", + "title": "命令行导航", "file": "02-cli-navigation.md" }, - { "id": "03", "title": "Managing Context", "file": "03-context.md" }, - { "id": "04", "title": "Modes", "file": "04-modes.md" } + { "id": "03", "title": "管理上下文", "file": "03-context.md" }, + { "id": "04", "title": "模式", "file": "04-modes.md" } ] }, { - "name": "Project Context", + "name": "项目上下文", "lessons": [ { "id": "05", "title": "CLAUDE.md", "file": "05-claude-md.md" }, - { "id": "06", "title": "Writing Rules", "file": "06-writing-rules.md" }, - { "id": "07", "title": "Prompting", "file": "07-prompting.md" }, + { "id": "06", "title": "编写规则", "file": "06-writing-rules.md" }, + { "id": "07", "title": "提示词技巧", "file": "07-prompting.md" }, { "id": "08", - "title": "Creating Skills", + "title": "创建技能", "file": "08-creating-skills.md" } ] }, { - "name": "Agents", + "name": "智能体", "lessons": [ - { "id": "09", "title": "Subagents", "file": "09-claude-agents.md" }, + { "id": "09", "title": "子智能体", "file": "09-claude-agents.md" }, { "id": "10", - "title": "Application Agents", + "title": "应用智能体", "file": "10-application-agents.md" } ] diff --git a/.claude/skills/lesson/SKILL.md b/.claude/skills/lesson/SKILL.md index 3e765b9..d4cae69 100644 --- a/.claude/skills/lesson/SKILL.md +++ b/.claude/skills/lesson/SKILL.md @@ -1,24 +1,24 @@ --- name: lesson -description: Create a structured lesson on a Claude Code topic -argument-hint: "[topic]" +description: 创建关于 Claude Code 主题的结构化课程 +argument-hint: "[主题]" --- -# Create a Lesson +# 创建课程 -Write a lesson about **$ARGUMENTS**. +写一篇关于 **$ARGUMENTS** 的课程。 -## Structure +## 结构 -1. **What is it?** - Brief explanation -2. **Why use it?** - When and why it's useful -3. **How it works** - Step-by-step with examples -4. **Quick reference** - Cheat sheet / table -5. **Try it** - Hands-on exercise +1. **它是什么?** - 简要解释 +2. **为什么使用它?** - 何时以及为什么有用 +3. **它是如何工作的** - 分步示例 +4. **快速参考** - 备忘单/表格 +5. **试试看** - 动手练习 -## Guidelines +## 指南 -- Keep explanations concise -- Use tables for comparisons -- Include real examples -- End with something to try +- 保持解释简洁 +- 使用表格进行比较 +- 包含真实示例 +- 以可以尝试的东西结束 diff --git a/.claude/skills/review-lesson/SKILL.md b/.claude/skills/review-lesson/SKILL.md index 7204137..9993ef1 100644 --- a/.claude/skills/review-lesson/SKILL.md +++ b/.claude/skills/review-lesson/SKILL.md @@ -1,59 +1,59 @@ --- name: review-lesson -description: Review a lesson for accuracy against Claude Code docs -argument-hint: "" +description: 根据 Claude Code 官方文档审查课程准确性 +argument-hint: "<课程文件或编号>" --- -# Review Lesson +# 审查课程 -Review the lesson **$ARGUMENTS** for accuracy against official Claude Code documentation. +根据官方 Claude Code 文档审查 **$ARGUMENTS** 的准确性。 -## Steps +## 步骤 -1. **Read the lesson** +1. **阅读课程** - - If a number is given (e.g., "04"), read `learn-claude/04-*.md` - - If a file path is given, read that file + - 如果给出编号(例如,"04"),读取 `learn-claude/04-*.md` + - 如果给出文件路径,读取该文件 -2. **Check against official docs** +2. **对照官方文档检查** - - Fetch https://docs.anthropic.com/en/docs/claude-code for reference - - Also check https://docs.anthropic.com/en/docs/claude-code/cli-usage - - Cross-reference any claims in the lesson + - 从 https://docs.anthropic.com/en/docs/claude-code 获取参考 + - 同时检查 https://docs.anthropic.com/en/docs/claude-code/cli-usage + - 交叉引用课程中的任何声明 -3. **Review for** - - **Accuracy** - Is the information correct? - - **Completeness** - Is anything important missing? - - **Currency** - Is anything outdated? - - **Clarity** - Is it easy to understand? +3. **审查** + - **准确性** - 信息正确吗? + - **完整性** - 有什么重要的遗漏吗? + - **时效性** - 有什么过时的吗? + - **清晰度** - 容易理解吗? -## Output Format +## 输出格式 ```markdown -## Lesson Review: [Title] +## 课程审查:[标题] -### Accuracy +### 准确性 -- ✅ Correct: [list accurate claims] -- ❌ Incorrect: [list inaccuracies with corrections] -- ⚠️ Outdated: [list outdated info with updates] +- ✅ 正确:[列出准确的声明] +- ❌ 不正确:[列出错误及更正] +- ⚠️ 过时:[列出过时的信息及更新] -### Missing +### 遗漏 -- [Important topics not covered] +- [未涵盖的重要主题] -### Suggestions +### 建议 -- [Improvements to make] +- [改进建议] -### Verdict +### 结论 -[PASS / NEEDS UPDATES / MAJOR REVISION NEEDED] +[通过 / 需要更新 / 需要重大修订] ``` -## Guidelines +## 指南 -- Be specific about what's wrong and how to fix it -- Reference the official docs for corrections -- Note if something couldn't be verified -- Prioritize factual accuracy over style +- 具体说明有什么问题以及如何修复 +- 引用官方文档进行更正 +- 注意如果有无法验证的内容 +- 优先考虑事实准确性而非风格 diff --git a/CLAUDE.md b/CLAUDE.md index 7837006..8e641e7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,104 +1,104 @@ -# Game Development Rules +# 游戏开发规则 -When creating or modifying game artifacts, always keep these elements in sync. Reference the **UI Component Reference** section below for component names and locations. +在创建或修改游戏元素时,请始终保持这些元素同步。请参考下方的 **UI 组件参考** 部分了解组件名称和位置。 -## Characters +## 角色 -When adding or modifying characters: +在添加或修改角色时: -1. **Data File**: Add to `data/characters.json` -2. **Portrait Art**: Create pixel art in `ui/portraits.js` if it doesn't exist -3. **Talk Button**: Enable via `updateTalkButton()` in Actions Section -4. **Portrait Display**: Character appears via `showPortrait()` when talking -5. **Terminal Output**: Character mentioned in room description text +1. **数据文件**:添加到 `data/characters.json` +2. **肖像艺术**:如果不存在,在 `ui/portraits.js` 中创建像素艺术 +3. **对话按钮**:通过操作区的 `updateTalkButton()` 启用 +4. **肖像显示**:对话时通过 `showPortrait()` 显示角色 +5. **终端输出**:在房间描述文本中提及角色 -## Rooms +## 房间 -When adding or modifying rooms: +在添加或修改房间时: -1. **Data File**: Add to `data/rooms.json` -2. **Location Name**: Updates via `updateLocation()` in Location Section -3. **Mini Map**: Update `mapLayout` grid in `ui/ui.js` -4. **Map Visualization**: Synced by `updateMap()` -5. **Terminal Output**: Room description shown via `print()` -6. **Exits**: Ensure room exits match the spatial grid layout +1. **数据文件**:添加到 `data/rooms.json` +2. **位置名称**:通过位置区的 `updateLocation()` 更新 +3. **小地图**:在 `ui/ui.js` 中更新 `mapLayout` 网格 +4. **地图可视化**:通过 `updateMap()` 同步 +5. **终端输出**:通过 `print()` 显示房间描述 +6. **出口**:确保房间出口与空间网格布局匹配 -## Items +## 物品 -When adding or modifying items: +在添加或修改物品时: -1. **Data File**: Add to `data/items.json` -2. **Take Button**: Enable via `updateTakeButton()` in Actions Section -3. **Inventory List**: Updates via `updateInventory()` in Inventory Section -4. **Terminal Output**: Item mentioned in room description when present -5. **Mini Map**: Ensure minimap continues to work as expected. +1. **数据文件**:添加到 `data/items.json` +2. **拾取按钮**:通过操作区的 `updateTakeButton()` 启用 +3. **物品清单**:通过物品区的 `updateInventory()` 更新 +4. **终端输出**:当物品存在时,在房间描述中提及 +5. **小地图**:确保小地图继续正常工作 -## Enemies +## 敌人 -When adding or modifying enemies: +在添加或修改敌人时: -1. **Data File**: Add to `data/enemies.json` -2. **Attack Button**: Enable via `updateAttackButton()` in Actions Section -3. **Pixel Art**: Create in `ui/portraits.js` if it doesn't exist -4. **Terminal Output**: Enemy mentioned in room description when present +1. **数据文件**:添加到 `data/enemies.json` +2. **攻击按钮**:通过操作区的 `updateAttackButton()` 启用 +3. **像素艺术**:如果不存在,在 `ui/portraits.js` 中创建 +4. **终端输出**:当敌人存在时,在房间描述中提及 -## Navigation +## 导航 -- Support arrow keys ONLY for keyboard navigation -- DO NOT add WASD (w/a/s/d) key support — it interferes with text input -- Arrow keys: ArrowUp, ArrowDown, ArrowLeft, ArrowRight +- 键盘导航**仅**支持方向键 +- **不要**添加 WASD (w/a/s/d) 键支持 —— 它会干扰文本输入 +- 方向键:ArrowUp、ArrowDown、ArrowLeft、ArrowRight -## Reference Implementation +## 参考实现 -- The `reference/complete/` directory contains the complete, finished version of the game -- When implementing features, check reference/complete/game.js, reference/complete/ui/ui.js, and reference/complete/data/ for reference -- Use these as guardrails to ensure your implementations match the intended patterns and structure +- `reference/complete/` 目录包含游戏的完整、成品版本 +- 在实现功能时,请检查 reference/complete/game.js、reference/complete/ui/ui.js 和 reference/complete/data/ 作为参考 +- 使用这些作为指导,确保你的实现符合预期的模式和结构 -## General Principle +## 一般原则 -When you add any game artifact (character, room, item, enemy), update: +当你添加任何游戏元素(角色、房间、物品、敌人)时,请更新: -1. The data file (JSON) -2. The UI elements that display/interact with it -3. Any visual assets (pixel art) if applicable +1. 数据文件(JSON) +2. 显示/与之交互的 UI 元素 +3. 任何视觉资源(像素艺术)(如适用) --- -## UI Component Reference +## UI 组件参考 -Understanding the game's UI structure helps when adding features. Here's the complete hierarchy: +了解游戏的 UI 结构有助于添加功能。以下是完整的层次结构: -### Layout Structure +### 布局结构 -**Status Panel** (Left Sidebar) +**状态面板**(左侧边栏) -- **Status Section**: HP Display with hearts and text (100/100) -- **Location Section**: Location Name, Mini Map grid, Map Legend -- **Inventory Section**: Inventory List of carried items -- **Actions Section**: Action Buttons Grid containing: - - Look Button, Inventory Button, Help Button (always visible) - - Take Button (appears when items present) - - Talk Button (appears when characters present) - - Attack Button (appears when enemies present) +- **状态区**:HP 显示,带心形和文本(100/100) +- **位置区**:位置名称、小地图网格、地图图例 +- **物品区**:携带物品的物品清单 +- **操作区**:操作按钮网格,包含: + - 查看按钮、物品按钮、帮助按钮(始终可见) + - 拾取按钮(当存在物品时显示) + - 对话按钮(当存在角色时显示) + - 攻击按钮(当存在敌人时显示) -**Main Panel** (Right Side) +**主面板**(右侧) -- **Portrait Display**: Character portraits during conversations -- **Terminal Output**: Game text messages and room descriptions -- **Command Input**: Text field for player commands +- **肖像显示**:对话期间的角色肖像 +- **终端输出**:游戏文本消息和房间描述 +- **命令输入**:玩家命令的文本字段 -### Code References +### 代码参考 -| Component Name | HTML/CSS Reference | Update Function | -| ---------------- | ------------------------------------ | ---------------------------------- | -| Status Panel | `.status-panel` | N/A (container) | -| HP Display | `.hp-display`, `#hp-bar`, `#hp-text` | `updateHpBar()` | -| Location Name | `#location-name` | `updateLocation()` | -| Mini Map | `#pixel-map` | `updateMap()` | -| Inventory List | `#inventory-list` | `updateInventory()` | -| Take Button | `#take-btn` | `updateTakeButton()` | -| Talk Button | `#talk-btn` | `updateTalkButton()` | -| Attack Button | `#attack-btn` | `updateAttackButton()` | -| Portrait Display | `#portrait-container` | `showPortrait()`, `hidePortrait()` | -| Terminal Output | `#output` | `print(text, className)` | -| Command Input | `#command` | N/A (user input) | +| 组件名称 | HTML/CSS 引用 | 更新函数 | +| ---------- | ------------------------------------ | ---------------------------------- | +| 状态面板 | `.status-panel` | N/A(容器) | +| HP 显示 | `.hp-display`, `#hp-bar`, `#hp-text` | `updateHpBar()` | +| 位置名称 | `#location-name` | `updateLocation()` | +| 小地图 | `#pixel-map` | `updateMap()` | +| 物品清单 | `#inventory-list` | `updateInventory()` | +| 拾取按钮 | `#take-btn` | `updateTakeButton()` | +| 对话按钮 | `#talk-btn` | `updateTalkButton()` | +| 攻击按钮 | `#attack-btn` | `updateAttackButton()` | +| 肖像显示 | `#portrait-container` | `showPortrait()`, `hidePortrait()` | +| 终端输出 | `#output` | `print(text, className)` | +| 命令输入 | `#command` | N/A(用户输入) | diff --git a/README.md b/README.md index 108aadc..af8f055 100644 --- a/README.md +++ b/README.md @@ -1,132 +1,132 @@ -# Learn Claude Code +# 学习 Claude Code -An interactive course for learning Claude Code in Claude Code. +一个用于在 Claude Code 中学习 Claude Code 的交互式课程。 -Claude teaches you conversationally, walking you through concepts and hands-on exercises step by step. +Claude 会以对话方式教学,一步步带你了解概念和实践练习。 -## Quick Start +## 快速开始 -1. First, install [Claude Code](https://docs.anthropic.com/en/docs/claude-code) if you haven't already: +1. 首先,如果你还没有安装 [Claude Code](https://docs.anthropic.com/en/docs/claude-code),请安装: ```bash npm install -g @anthropic-ai/claude-code ``` -2. Clone this repository: +2. 克隆这个仓库: ```bash git clone https://github.com/delbaoliveira/learn-claude-code cd learn-claude-code ``` -3. Start a session with Claude: +3. 启动 Claude 会话: ```bash claude ``` -4. Then type `/course` to begin. +4. 然后输入 `/course` 开始课程。 --- -## What You'll Build +## 你将构建什么 -Throughout the course, you'll build **Dungeons & Agents** — a text adventure game that runs in your browser. +在整个课程中,你将构建 **地下城与智能体** —— 一个在你的浏览器中运行的文字冒险游戏。 ``` ╔═══════════════════════════════════════════╗ -║ DUNGEONS & AGENTS ║ +║ 地下城 与 智能体 ║ ╚═══════════════════════════════════════════╝ -You stand at the entrance of a dark cave. -A cold wind blows from within. +你站在一个黑暗洞穴的入口。 +一股冷风吹过。 -> go north +> 向北走 ``` -Each lesson teaches a Claude Code concept, then has you apply it to the game. By lesson 10, you'll have a complete game with rooms, items, combat, and a foundational understanding of Claude Code. +每节课教授一个 Claude Code 概念,然后让你在项目中应用它。到第 10 课时,你将拥有一个完整的游戏,包含房间、物品、战斗系统,以及对 Claude Code 的基础理解。 -Start the game server: +启动游戏服务器: ```bash node dungeon/server.js ``` -Then open http://localhost:3000 in your browser. +然后在浏览器中打开 http://localhost:3000。 --- -## Course Structure +## 课程结构 -**Introduction** +**介绍** -0. Welcome +0. 欢迎 -**Part 1: Getting Started** +**第 1 部分:入门** -1. Your First Session -2. CLI Navigation -3. Managing Context -4. Modes +1. 你的第一次会话 +2. 命令行导航 +3. 管理上下文 +4. 模式 -**Part 2: Project Context** +**第 2 部分:项目上下文** 5. CLAUDE.md -6. Writing Rules -7. Prompting -8. Creating Skills +6. 编写规则 +7. 提示词技巧 +8. 创建技能 -**Part 3: Agents** +**第 3 部分:智能体** -9. Subagents -10. Application Agents +9. 子智能体 +10. 应用智能体 --- -## Directory Structure +## 目录结构 ``` learn-claude-code/ -├── learn-claude/ # 11 lessons -├── dungeon/ # Your workspace -│ ├── server.js # Game server -│ ├── index.html # Terminal-styled UI -│ ├── game.js # Game engine (you build this!) -│ ├── data/ # Game data (rooms, items, enemies) -│ └── course-progress.json # Your saved progress +├── learn-claude/ # 11 节课 +├── dungeon/ # 你的工作区 +│ ├── server.js # 游戏服务器 +│ ├── index.html # 终端风格界面 +│ ├── game.js # 游戏引擎(由你构建!) +│ ├── data/ # 游戏数据(房间、物品、敌人) +│ └── course-progress.json # 你的保存进度 ├── reference/ -│ ├── starter/ # Starting state (for /course reset) -│ └── complete/ # Complete reference implementation +│ ├── starter/ # 起始状态(用于 /course reset) +│ └── complete/ # 完整参考实现 ├── .claude/ │ └── skills/ -│ ├── course/ # Interactive course runner -│ └── dungeon/ # Game-building skills (lesson 09) +│ ├── course/ # 交互式课程运行器 +│ └── dungeon/ # 游戏构建技能(第 09 课) └── README.md ``` -## Course Commands +## 课程命令 -| Command | Description | +| 命令 | 描述 | | ------------------ | ---------------------------- | -| `/course` | Show dashboard with progress | -| `/course next` | Continue to next lesson | -| `/course progress` | View detailed stats | -| `/course exit` | Pause and save position | -| `/course reset` | Start over | -| `/course update` | Update to latest version | +| `/course` | 显示进度仪表板 | +| `/course next` | 继续下一课 | +| `/course progress` | 查看详细统计 | +| `/course exit` | 暂停并保存位置 | +| `/course reset` | 重新开始 | +| `/course update` | 更新到最新版本 | --- -## For Contributors +## 给贡献者 -### Review a lesson against official docs +### 根据官方文档审查课程 ``` /review-lesson 03 ``` -### Generate a new lesson +### 生成新课程 ``` -/lesson "topic name" +/lesson "主题名称" ``` diff --git a/dungeon/course-progress.json b/dungeon/course-progress.json index d65a430..4f5cd3e 100644 --- a/dungeon/course-progress.json +++ b/dungeon/course-progress.json @@ -1,5 +1,5 @@ { - "completed": ["00", "01"], - "current": "02", + "completed": ["00", "01", "02"], + "current": "03", "graduated": false } diff --git a/dungeon/data/rooms.json b/dungeon/data/rooms.json index 5b7009c..cb3da7d 100644 --- a/dungeon/data/rooms.json +++ b/dungeon/data/rooms.json @@ -1,7 +1,7 @@ { "cave-entrance": { - "name": "Cave Entrance", - "description": "You stand at the entrance of a dark cave. Faint light filters in from outside.", + "name": "洞穴入口", + "description": "你站在一个黑暗洞穴的入口。微弱的光线从外面照射进来。", "exits": {} } } diff --git a/dungeon/game.js b/dungeon/game.js index d7ebbd6..ee6f606 100644 --- a/dungeon/game.js +++ b/dungeon/game.js @@ -1,7 +1,7 @@ -// Dungeons & Agents - Game Engine -// Starter skeleton for lessons +// 地下城与智能体 - 游戏引擎 +// 课程的入门骨架 -// ============ GAME STATE ============ +// ============ 游戏状态 ============ let rooms = {} let items = {} @@ -17,7 +17,7 @@ let talkingToId = null let conversationState = {} let storyFlags = new Set() -// ============ DATA LOADING ============ +// ============ 数据加载 ============ async function loadRooms() { const response = await fetch("data/rooms.json") @@ -47,33 +47,33 @@ async function loadEnemies() { } } -// ============ COMMAND PROCESSING ============ +// ============ 命令处理 ============ function processCommand(input) { const command = input.trim().toLowerCase() - // Echo the command + // 回显命令 print(`> ${input}`, "command") - // Handle commands + // 处理命令 if (command === "help") { - print("Available commands:") - print(" help - Show this help message") - print(" look - Look around the room") + print("可用命令:") + print(" help - 显示此帮助信息") + print(" look - 查看周围环境") return } if (command === "look") { - print("You are in a dark cave. Exits: up") + print("你身处一个黑暗的洞穴。出口:上") return } - print("I don't understand that.", "error") + print("我不理解那个命令。", "error") } -// ============ EVENT HANDLERS ============ +// ============ 事件处理器 ============ -// Handle input +// 处理输入 commandInput.addEventListener("keydown", (e) => { if (e.key === "Enter") { const input = commandInput.value @@ -84,10 +84,10 @@ commandInput.addEventListener("keydown", (e) => { } }) -// Focus input on click anywhere +// 点击任意位置聚焦输入框 document.addEventListener("click", () => commandInput.focus()) -// Button handlers +// 按钮处理器 document.querySelectorAll(".pixel-btn").forEach((btn) => { btn.addEventListener("click", (e) => { e.stopPropagation() @@ -98,13 +98,13 @@ document.querySelectorAll(".pixel-btn").forEach((btn) => { }) }) -// Portrait close button +// 肖像关闭按钮 portraitClose.addEventListener("click", (e) => { e.stopPropagation() hidePortrait() }) -// Talk button - talk to first NPC in room +// 对话按钮 - 与房间中的第一个 NPC 对话 talkBtn.addEventListener("click", (e) => { e.stopPropagation() const npc = Object.values(characters).find((c) => c.location === currentRoom) @@ -114,7 +114,7 @@ talkBtn.addEventListener("click", (e) => { } }) -// ============ INITIALIZATION ============ +// ============ 初始化 ============ async function init() { await loadRooms() @@ -124,8 +124,8 @@ async function init() { updateUI() - print("Welcome to Dungeons & Agents!") - print("Type 'help' for available commands.") + print("欢迎来到地下城与智能体!") + print("输入 'help' 查看可用命令。") print("") const room = rooms[currentRoom] if (room) { diff --git a/dungeon/index.html b/dungeon/index.html index 91474c1..9381470 100644 --- a/dungeon/index.html +++ b/dungeon/index.html @@ -1,9 +1,9 @@ - + - Dungeons & Agents + 地下城与智能体
-

DUNGEONS & AGENTS

+

地下城与智能体

@@ -28,57 +28,57 @@

DUNGEONS & AGENTS