Skip to content

Commit e7d0027

Browse files
anthhubclaude
andcommitted
feat: add Chapter 1 demo, VitePress docs site, Codespaces & Jupyter notebook
- Create demo/ with mini-claude scaffolding: types for messages, tools, permissions, and config — TypeScript compiles and runs successfully - Set up VitePress with bilingual (zh-CN/en) docs, sidebar navigation, and GitHub Pages deployment workflow - Add .devcontainer for one-click GitHub Codespaces environment - Add Jupyter notebook (Deno kernel) for interactive Chapter 1 tutorial - Update Chapter 1 docs with "Hands-on Build" section for demo walkthrough - Update Chapter 1 "What's Next" to preview Chapter 2 (Tool implementation) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 51060b8 commit e7d0027

23 files changed

Lines changed: 2633 additions & 28 deletions

.devcontainer/devcontainer.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "Learn Claude Code",
3+
"image": "mcr.microsoft.com/devcontainers/typescript-node:22",
4+
"features": {
5+
"ghcr.io/anthropics/devcontainer-features/bun:1": {},
6+
"ghcr.io/anthropics/devcontainer-features/deno:1": {}
7+
},
8+
"postCreateCommand": "bun install && cd demo && bun install",
9+
"customizations": {
10+
"vscode": {
11+
"extensions": [
12+
"ms-vscode.vscode-typescript-next",
13+
"esbenp.prettier-vscode",
14+
"ms-toolsai.jupyter"
15+
],
16+
"settings": {
17+
"terminal.integrated.defaultProfile.linux": "bash"
18+
}
19+
}
20+
},
21+
"forwardPorts": [5173],
22+
"portsAttributes": {
23+
"5173": { "label": "VitePress Dev", "onAutoForward": "openPreview" }
24+
}
25+
}

.github/workflows/deploy-docs.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Deploy Docs to GitHub Pages
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
concurrency:
14+
group: pages
15+
cancel-in-progress: false
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0
24+
25+
- uses: oven-sh/setup-bun@v2
26+
with:
27+
bun-version: latest
28+
29+
- name: Install dependencies
30+
run: bun install
31+
32+
- name: Build docs
33+
run: bun run docs:build
34+
35+
- uses: actions/upload-pages-artifact@v3
36+
with:
37+
path: docs/.vitepress/dist
38+
39+
deploy:
40+
environment:
41+
name: github-pages
42+
url: ${{ steps.deployment.outputs.page_url }}
43+
needs: build
44+
runs-on: ubuntu-latest
45+
steps:
46+
- name: Deploy to GitHub Pages
47+
id: deployment
48+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ bun.lockb
2727
package-lock.json
2828
yarn.lock
2929

30+
# Demo dependencies (users install locally)
31+
demo/node_modules/
32+
demo/bun.lock
33+
demo/dist/
34+
35+
# VitePress
36+
docs/.vitepress/dist/
37+
docs/.vitepress/cache/
38+
3039
# OS
3140
.DS_Store
3241
.DS_Store?

bun.lock

Lines changed: 347 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

demo/main.ts

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/**
2+
* main.ts - mini-claude 入口文件
3+
*
4+
* 对应真实 Claude Code: src/main.tsx
5+
*
6+
* 当前状态(第 1 章):仅验证类型系统可正常工作
7+
* 后续章节会逐步添加:
8+
* 第 2 章: Tool 接口实现 + 工具注册表
9+
* 第 3 章: Anthropic API 调用 + 流式响应
10+
* 第 4 章: 查询循环(Agentic Loop)
11+
* ...
12+
*/
13+
14+
import {
15+
generateId,
16+
isToolUseBlock,
17+
isTextBlock,
18+
toolToAPIFormat,
19+
DEFAULT_CONFIG,
20+
} from "./types/index.js";
21+
22+
import type {
23+
Message,
24+
UserMessage,
25+
AssistantMessage,
26+
ContentBlock,
27+
Tool,
28+
AppConfig,
29+
} from "./types/index.js";
30+
31+
// ─── 验证类型系统 ────────────────────────────────────────────────────────────
32+
33+
// 构造一条用户消息
34+
const userMsg: UserMessage = {
35+
type: "user",
36+
uuid: generateId(),
37+
message: {
38+
role: "user",
39+
content: "帮我看一下 main.ts 的内容",
40+
},
41+
};
42+
43+
// 构造一条助手消息(模拟 AI 回复,包含工具调用)
44+
const assistantMsg: AssistantMessage = {
45+
type: "assistant",
46+
uuid: generateId(),
47+
message: {
48+
role: "assistant",
49+
content: [
50+
{ type: "text", text: "好的,让我读取这个文件。" },
51+
{
52+
type: "tool_use",
53+
id: "tool_001",
54+
name: "Read",
55+
input: { file_path: "main.ts" },
56+
},
57+
],
58+
model: DEFAULT_CONFIG.model,
59+
stop_reason: "tool_use",
60+
},
61+
};
62+
63+
// 从助手消息中提取工具调用
64+
const toolCalls = assistantMsg.message.content.filter(isToolUseBlock);
65+
66+
// 模拟一个工具定义
67+
const readTool: Tool = {
68+
name: "Read",
69+
description: "读取文件内容",
70+
inputSchema: {
71+
type: "object",
72+
properties: {
73+
file_path: { type: "string", description: "文件的绝对路径" },
74+
},
75+
required: ["file_path"],
76+
},
77+
isReadOnly: true,
78+
async call(input) {
79+
return { content: `[文件内容: ${input.file_path}]` };
80+
},
81+
};
82+
83+
// 转换为 API 格式
84+
const apiTool = toolToAPIFormat(readTool);
85+
86+
// 构建消息历史
87+
const messages: Message[] = [userMsg, assistantMsg];
88+
89+
// ─── 输出验证结果 ─────────────────────────────────────────────────────────
90+
91+
console.log("mini-claude - 类型系统验证");
92+
console.log("=".repeat(40));
93+
console.log();
94+
console.log(`消息历史: ${messages.length} 条`);
95+
console.log(` 用户消息: "${typeof userMsg.message.content === "string" ? userMsg.message.content : "[复合内容]"}"`);
96+
console.log(` 助手消息: ${assistantMsg.message.content.length} 个内容块`);
97+
console.log(` 工具调用: ${toolCalls.length} 个`);
98+
toolCalls.forEach((tc) => {
99+
console.log(` → ${tc.name}(${JSON.stringify(tc.input)})`);
100+
});
101+
console.log();
102+
console.log(`注册工具: ${apiTool.name}`);
103+
console.log(` 描述: ${apiTool.description}`);
104+
console.log(` 参数: ${JSON.stringify(apiTool.input_schema.properties)}`);
105+
console.log(` 只读: ${readTool.isReadOnly}`);
106+
console.log();
107+
console.log(`默认配置:`);
108+
console.log(` 模型: ${DEFAULT_CONFIG.model}`);
109+
console.log(` 最大 Token: ${DEFAULT_CONFIG.maxTokens}`);
110+
console.log(` 权限模式: ${DEFAULT_CONFIG.permissionMode}`);
111+
console.log();
112+
console.log("类型系统验证通过!");
113+
console.log("下一步: 第 2 章 - 实现 Tool 接口和工具注册表");

demo/package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "mini-claude",
3+
"version": "0.1.0",
4+
"description": "A minimal Claude Code clone - built chapter by chapter",
5+
"type": "module",
6+
"scripts": {
7+
"typecheck": "tsc --noEmit",
8+
"start": "bun run main.ts"
9+
},
10+
"dependencies": {
11+
"@anthropic-ai/sdk": "^0.52.0"
12+
},
13+
"devDependencies": {
14+
"@types/bun": "^1.3.11",
15+
"typescript": "^5.7.0"
16+
}
17+
}

demo/tsconfig.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2022",
4+
"module": "ESNext",
5+
"moduleResolution": "bundler",
6+
"esModuleInterop": true,
7+
"strict": true,
8+
"skipLibCheck": true,
9+
"outDir": "dist",
10+
"rootDir": ".",
11+
"types": ["@types/bun"],
12+
"jsx": "react-jsx",
13+
"jsxImportSource": "react"
14+
},
15+
"include": ["**/*.ts", "**/*.tsx"],
16+
"exclude": ["node_modules", "dist"]
17+
}

demo/types/config.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* types/config.ts - 配置类型定义
3+
*
4+
* mini-claude 的运行时配置
5+
*
6+
* 真实 Claude Code 的配置散布在多个地方:
7+
* - CLI 参数(Commander.js)
8+
* - 环境变量
9+
* - ~/.claude/settings.json
10+
* - 项目级 CLAUDE.md
11+
*
12+
* 我们先定义一个简化的统一配置类型
13+
*/
14+
15+
import type { PermissionMode } from "./permissions.js";
16+
17+
/**
18+
* mini-claude 全局配置
19+
*/
20+
export interface AppConfig {
21+
/** Anthropic API Key */
22+
apiKey: string;
23+
24+
/** 使用的模型 ID,默认 claude-sonnet-4-20250514 */
25+
model: string;
26+
27+
/** 最大输出 token 数 */
28+
maxTokens: number;
29+
30+
/** 权限模式 */
31+
permissionMode: PermissionMode;
32+
33+
/** 工作目录 */
34+
cwd: string;
35+
36+
/** 系统提示词(可选追加) */
37+
systemPrompt?: string;
38+
}
39+
40+
/**
41+
* 默认配置
42+
*/
43+
export const DEFAULT_CONFIG: Omit<AppConfig, "apiKey"> = {
44+
model: "claude-sonnet-4-20250514",
45+
maxTokens: 16384,
46+
permissionMode: "default",
47+
cwd: process.cwd(),
48+
};

demo/types/index.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* types/index.ts - 类型统一导出
3+
*
4+
* 其他模块通过 import { ... } from "./types/index.js" 引入所有类型
5+
*/
6+
7+
// 消息类型
8+
export type {
9+
TextBlock,
10+
ToolUseBlock,
11+
ToolResultBlock,
12+
ContentBlock,
13+
UserMessage,
14+
AssistantMessage,
15+
SystemMessage,
16+
Message,
17+
StopReason,
18+
APIMessage,
19+
APIContentBlock,
20+
ToolResult,
21+
} from "./message.js";
22+
23+
export {
24+
generateId,
25+
isToolUseBlock,
26+
isTextBlock,
27+
isAssistantMessage,
28+
isUserMessage,
29+
} from "./message.js";
30+
31+
// 工具类型
32+
export type {
33+
Tool,
34+
JSONSchema,
35+
JSONSchemaProperty,
36+
ToolRegistry,
37+
APIToolDefinition,
38+
} from "./tool.js";
39+
40+
export { toolToAPIFormat } from "./tool.js";
41+
42+
// 权限类型
43+
export type {
44+
PermissionMode,
45+
PermissionBehavior,
46+
PermissionAllowDecision,
47+
PermissionDenyDecision,
48+
PermissionAskDecision,
49+
PermissionDecision,
50+
PermissionRule,
51+
PermissionContext,
52+
CheckPermissionFn,
53+
} from "./permissions.js";
54+
55+
// 配置类型
56+
export type { AppConfig } from "./config.js";
57+
export { DEFAULT_CONFIG } from "./config.js";

0 commit comments

Comments
 (0)