From 4f17b1779d4966cbc1e7fd45081fe6faef6bb8cf Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 21:20:06 -0800 Subject: [PATCH 01/14] Update client initialization and session creation syntax in documentation --- docs/debugging.md | 2 +- docs/getting-started.md | 28 ++- docs/guides/session-persistence.md | 11 +- docs/guides/skills.md | 324 +++++++++++++++++++++++++++++ docs/mcp/overview.md | 4 +- 5 files changed, 353 insertions(+), 16 deletions(-) create mode 100644 docs/guides/skills.md diff --git a/docs/debugging.md b/docs/debugging.md index dffd85a3..80f9935b 100644 --- a/docs/debugging.md +++ b/docs/debugging.md @@ -36,7 +36,7 @@ const client = new CopilotClient({ ```python from copilot import CopilotClient -client = CopilotClient(log_level="debug") +client = CopilotClient({"log_level": "debug"}) ``` diff --git a/docs/getting-started.md b/docs/getting-started.md index 7aea1e06..54912c2d 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -162,6 +162,7 @@ Create `main.go`: package main import ( + "context" "fmt" "log" "os" @@ -170,18 +171,19 @@ import ( ) func main() { + ctx := context.Background() client := copilot.NewClient(nil) if err := client.Start(); err != nil { log.Fatal(err) } defer client.Stop() - session, err := client.CreateSession(&copilot.SessionConfig{Model: "gpt-4.1"}) + session, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-4.1"}) if err != nil { log.Fatal(err) } - response, err := session.SendAndWait(copilot.MessageOptions{Prompt: "What is 2 + 2?"}, 0) + response, err := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "What is 2 + 2?"}) if err != nil { log.Fatal(err) } @@ -312,6 +314,7 @@ Update `main.go`: package main import ( + "context" "fmt" "log" "os" @@ -320,13 +323,14 @@ import ( ) func main() { + ctx := context.Background() client := copilot.NewClient(nil) if err := client.Start(); err != nil { log.Fatal(err) } defer client.Stop() - session, err := client.CreateSession(&copilot.SessionConfig{ + session, err := client.CreateSession(ctx, &copilot.SessionConfig{ Model: "gpt-4.1", Streaming: true, }) @@ -344,7 +348,7 @@ func main() { } }) - _, err = session.SendAndWait(copilot.MessageOptions{Prompt: "Tell me a short joke"}, 0) + _, err = session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Tell me a short joke"}) if err != nil { log.Fatal(err) } @@ -513,6 +517,7 @@ Update `main.go`: package main import ( + "context" "fmt" "log" "math/rand" @@ -534,6 +539,8 @@ type WeatherResult struct { } func main() { + ctx := context.Background() + // Define a tool that Copilot can call getWeather := copilot.DefineTool( "get_weather", @@ -557,7 +564,7 @@ func main() { } defer client.Stop() - session, err := client.CreateSession(&copilot.SessionConfig{ + session, err := client.CreateSession(ctx, &copilot.SessionConfig{ Model: "gpt-4.1", Streaming: true, Tools: []copilot.Tool{getWeather}, @@ -575,9 +582,9 @@ func main() { } }) - _, err = session.SendAndWait(copilot.MessageOptions{ + _, err = session.SendAndWait(ctx, copilot.MessageOptions{ Prompt: "What's the weather like in Seattle and Tokyo?", - }, 0) + }) if err != nil { log.Fatal(err) } @@ -796,6 +803,7 @@ package main import ( "bufio" + "context" "fmt" "log" "math/rand" @@ -816,6 +824,8 @@ type WeatherResult struct { } func main() { + ctx := context.Background() + getWeather := copilot.DefineTool( "get_weather", "Get the current weather for a city", @@ -837,7 +847,7 @@ func main() { } defer client.Stop() - session, err := client.CreateSession(&copilot.SessionConfig{ + session, err := client.CreateSession(ctx, &copilot.SessionConfig{ Model: "gpt-4.1", Streaming: true, Tools: []copilot.Tool{getWeather}, @@ -872,7 +882,7 @@ func main() { } fmt.Print("Assistant: ") - _, err = session.SendAndWait(copilot.MessageOptions{Prompt: input}, 0) + _, err = session.SendAndWait(ctx, copilot.MessageOptions{Prompt: input}) if err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) break diff --git a/docs/guides/session-persistence.md b/docs/guides/session-persistence.md index 4586201e..faf0e007 100644 --- a/docs/guides/session-persistence.md +++ b/docs/guides/session-persistence.md @@ -49,12 +49,13 @@ await session.sendAndWait({ prompt: "Analyze my codebase" }); from copilot import CopilotClient client = CopilotClient() +await client.start() # Create a session with a meaningful ID -session = await client.create_session( - session_id="user-123-task-456", - model="gpt-5.2-codex", -) +session = await client.create_session({ + "session_id": "user-123-task-456", + "model": "gpt-5.2-codex", +}) # Do some work... await session.send_and_wait({"prompt": "Analyze my codebase"}) @@ -87,7 +88,7 @@ using GitHub.Copilot.SDK; var client = new CopilotClient(); // Create a session with a meaningful ID -var session = await client.CreateSessionAsync(new CreateSessionOptions +var session = await client.CreateSessionAsync(new SessionConfig { SessionId = "user-123-task-456", Model = "gpt-5.2-codex", diff --git a/docs/guides/skills.md b/docs/guides/skills.md new file mode 100644 index 00000000..5ebcfac5 --- /dev/null +++ b/docs/guides/skills.md @@ -0,0 +1,324 @@ +# Custom Skills + +Skills are reusable collections of prompts, tools, and configuration that extend Copilot's capabilities. Load skills from directories to give Copilot specialized abilities for specific domains or workflows. + +## Overview + +A skill is a directory containing: +- **Prompt files** - Instructions that guide Copilot's behavior +- **Tool definitions** - Custom tools the skill provides +- **Configuration** - Metadata about the skill + +Skills allow you to: +- Package domain expertise into reusable modules +- Share specialized behaviors across projects +- Organize complex agent configurations +- Enable/disable capabilities per session + +## Loading Skills + +Specify directories containing skills when creating a session: + +
+Node.js / TypeScript + +```typescript +import { CopilotClient } from "@github/copilot-sdk"; + +const client = new CopilotClient(); +const session = await client.createSession({ + model: "gpt-4.1", + skillDirectories: [ + "./skills/code-review", + "./skills/documentation", + "~/.copilot/skills", // User-level skills + ], +}); + +// Copilot now has access to skills in those directories +await session.sendAndWait({ prompt: "Review this code for security issues" }); +``` + +
+ +
+Python + +```python +from copilot import CopilotClient + +async def main(): + client = CopilotClient() + await client.start() + + session = await client.create_session({ + "model": "gpt-4.1", + "skill_directories": [ + "./skills/code-review", + "./skills/documentation", + "~/.copilot/skills", # User-level skills + ], + }) + + # Copilot now has access to skills in those directories + await session.send_and_wait({"prompt": "Review this code for security issues"}) + + await client.stop() +``` + +
+ +
+Go + +```go +package main + +import ( + "context" + "log" + copilot "github.com/github/copilot-sdk/go" +) + +func main() { + client := copilot.NewClient(nil) + if err := client.Start(); err != nil { + log.Fatal(err) + } + defer client.Stop() + + session, err := client.CreateSession(context.Background(), &copilot.SessionConfig{ + Model: "gpt-4.1", + SkillDirectories: []string{ + "./skills/code-review", + "./skills/documentation", + "~/.copilot/skills", // User-level skills + }, + }) + if err != nil { + log.Fatal(err) + } + + // Copilot now has access to skills in those directories + _, err = session.SendAndWait(context.Background(), copilot.MessageOptions{ + Prompt: "Review this code for security issues", + }) + if err != nil { + log.Fatal(err) + } +} +``` + +
+ +
+.NET + +```csharp +using GitHub.Copilot.SDK; + +await using var client = new CopilotClient(); +await using var session = await client.CreateSessionAsync(new SessionConfig +{ + Model = "gpt-4.1", + SkillDirectories = new List + { + "./skills/code-review", + "./skills/documentation", + "~/.copilot/skills", // User-level skills + }, +}); + +// Copilot now has access to skills in those directories +await session.SendAndWaitAsync(new MessageOptions +{ + Prompt = "Review this code for security issues" +}); +``` + +
+ +## Disabling Skills + +Disable specific skills while keeping others active: + +
+Node.js / TypeScript + +```typescript +const session = await client.createSession({ + skillDirectories: ["./skills"], + disabledSkills: ["experimental-feature", "deprecated-tool"], +}); +``` + +
+ +
+Python + +```python +session = await client.create_session({ + "skill_directories": ["./skills"], + "disabled_skills": ["experimental-feature", "deprecated-tool"], +}) +``` + +
+ +
+Go + +```go +session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{ + SkillDirectories: []string{"./skills"}, + DisabledSkills: []string{"experimental-feature", "deprecated-tool"}, +}) +``` + +
+ +
+.NET + +```csharp +var session = await client.CreateSessionAsync(new SessionConfig +{ + SkillDirectories = new List { "./skills" }, + DisabledSkills = new List { "experimental-feature", "deprecated-tool" }, +}); +``` + +
+ +## Skill Directory Structure + +A typical skill directory contains: + +``` +skills/ +└── code-review/ + ├── skill.json # Skill metadata and configuration + ├── prompts/ + │ ├── system.md # System prompt additions + │ └── examples.md # Few-shot examples + └── tools/ + └── lint.json # Tool definitions +``` + +### skill.json + +The skill manifest file: + +```json +{ + "name": "code-review", + "displayName": "Code Review Assistant", + "description": "Specialized code review capabilities", + "version": "1.0.0", + "author": "Your Team", + "prompts": ["prompts/system.md"], + "tools": ["tools/lint.json"] +} +``` + +### Prompt Files + +Markdown files that provide context to Copilot: + +```markdown + +# Code Review Guidelines + +When reviewing code, always check for: + +1. **Security vulnerabilities** - SQL injection, XSS, etc. +2. **Performance issues** - N+1 queries, memory leaks +3. **Code style** - Consistent formatting, naming conventions +4. **Test coverage** - Are critical paths tested? + +Provide specific line-number references and suggested fixes. +``` + +## Configuration Options + +### SessionConfig Skill Fields + +| Language | Field | Type | Description | +|----------|-------|------|-------------| +| Node.js | `skillDirectories` | `string[]` | Directories to load skills from | +| Node.js | `disabledSkills` | `string[]` | Skills to disable | +| Python | `skill_directories` | `list[str]` | Directories to load skills from | +| Python | `disabled_skills` | `list[str]` | Skills to disable | +| Go | `SkillDirectories` | `[]string` | Directories to load skills from | +| Go | `DisabledSkills` | `[]string` | Skills to disable | +| .NET | `SkillDirectories` | `List` | Directories to load skills from | +| .NET | `DisabledSkills` | `List` | Skills to disable | + +## Best Practices + +1. **Organize by domain** - Group related skills together (e.g., `skills/security/`, `skills/testing/`) + +2. **Version your skills** - Include version numbers in `skill.json` for compatibility tracking + +3. **Document dependencies** - Note any tools or MCP servers a skill requires + +4. **Test skills in isolation** - Verify skills work before combining them + +5. **Use relative paths** - Keep skills portable across environments + +## Combining with Other Features + +### Skills + Custom Agents + +Skills work alongside custom agents: + +```typescript +const session = await client.createSession({ + skillDirectories: ["./skills/security"], + customAgents: [{ + name: "security-auditor", + description: "Security-focused code reviewer", + prompt: "Focus on OWASP Top 10 vulnerabilities", + }], +}); +``` + +### Skills + MCP Servers + +Skills can complement MCP server capabilities: + +```typescript +const session = await client.createSession({ + skillDirectories: ["./skills/database"], + mcpServers: { + postgres: { + type: "local", + command: "npx", + args: ["-y", "@modelcontextprotocol/server-postgres"], + tools: ["*"], + }, + }, +}); +``` + +## Troubleshooting + +### Skills Not Loading + +1. **Check path exists** - Verify the directory path is correct +2. **Check permissions** - Ensure the SDK can read the directory +3. **Validate skill.json** - Check for JSON syntax errors +4. **Enable debug logging** - Set `logLevel: "debug"` to see skill loading logs + +### Skill Conflicts + +If multiple skills define the same tool: +- Later directories in the array take precedence +- Use `disabledSkills` to exclude conflicting skills + +## See Also + +- [Custom Agents](../getting-started.md#create-custom-agents) - Define specialized AI personas +- [Custom Tools](../getting-started.md#step-4-add-a-custom-tool) - Build your own tools +- [MCP Servers](../mcp/overview.md) - Connect external tool providers diff --git a/docs/mcp/overview.md b/docs/mcp/overview.md index ed8eaa5e..c0b0e52e 100644 --- a/docs/mcp/overview.md +++ b/docs/mcp/overview.md @@ -104,18 +104,20 @@ asyncio.run(main()) package main import ( + "context" "log" copilot "github.com/github/copilot-sdk/go" ) func main() { + ctx := context.Background() client := copilot.NewClient(nil) if err := client.Start(); err != nil { log.Fatal(err) } defer client.Stop() - session, err := client.CreateSession(&copilot.SessionConfig{ + session, err := client.CreateSession(ctx, &copilot.SessionConfig{ Model: "gpt-5", MCPServers: map[string]copilot.MCPServerConfig{ "my-local-server": { From bb705f3391814daa8fc0edc6260df26167ab28a0 Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 21:28:22 -0800 Subject: [PATCH 02/14] Update client initialization syntax in documentation and enhance event subscription methods --- docs/debugging.md | 4 +- docs/getting-started.md | 102 ++++++++++++++++++++++++++++ docs/hooks/error-handling.md | 15 ++-- docs/hooks/user-prompt-submitted.md | 10 +-- docs/mcp/overview.md | 9 +-- 5 files changed, 121 insertions(+), 19 deletions(-) diff --git a/docs/debugging.md b/docs/debugging.md index 80f9935b..1586418f 100644 --- a/docs/debugging.md +++ b/docs/debugging.md @@ -161,7 +161,7 @@ var client = new CopilotClient(new CopilotClientOptions Python ```python - client = CopilotClient(cli_path="/usr/local/bin/copilot") + client = CopilotClient({"cli_path": "/usr/local/bin/copilot"}) ``` @@ -214,7 +214,7 @@ var client = new CopilotClient(new CopilotClientOptions ```python import os - client = CopilotClient(github_token=os.environ.get("GITHUB_TOKEN")) + client = CopilotClient({"github_token": os.environ.get("GITHUB_TOKEN")}) ``` diff --git a/docs/getting-started.md b/docs/getting-started.md index 54912c2d..411bdbef 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -393,6 +393,108 @@ await session.SendAndWaitAsync(new MessageOptions { Prompt = "Tell me a short jo Run the code again. You'll see the response appear word by word. +### Event Subscription Methods + +The SDK provides three methods for subscribing to session events: + +| Method | Description | +|--------|-------------| +| `on(handler)` | Subscribe to all events; returns unsubscribe function | +| `on(eventType, handler)` | Subscribe to specific event type; returns unsubscribe function | +| `once(eventType, handler)` | Subscribe to next occurrence only; auto-unsubscribes after firing | + +
+Node.js / TypeScript + +```typescript +// Subscribe to all events +const unsubscribeAll = session.on((event) => { + console.log("Event:", event.type); +}); + +// Subscribe to specific event type +const unsubscribeIdle = session.on("session.idle", (event) => { + console.log("Session is idle"); +}); + +// Subscribe to next occurrence only (auto-unsubscribes) +session.once("assistant.message", (event) => { + console.log("First message:", event.data.content); +}); + +// Later, to unsubscribe: +unsubscribeAll(); +unsubscribeIdle(); +``` + +
+ +
+Python + +```python +# Subscribe to all events +unsubscribe_all = session.on(lambda event: print(f"Event: {event.type}")) + +# Subscribe to specific event type +unsubscribe_idle = session.on("session.idle", lambda event: print("Session is idle")) + +# Subscribe to next occurrence only (auto-unsubscribes) +session.once("assistant.message", lambda event: print(f"First message: {event.data.content}")) + +# Later, to unsubscribe: +unsubscribe_all() +unsubscribe_idle() +``` + +
+ +
+Go + +```go +// Subscribe to all events +unsubscribeAll := session.On(func(event copilot.SessionEvent) { + fmt.Println("Event:", event.Type) +}) + +// Subscribe to specific event type +unsubscribeIdle := session.OnType("session.idle", func(event copilot.SessionEvent) { + fmt.Println("Session is idle") +}) + +// Subscribe to next occurrence only (auto-unsubscribes) +session.Once("assistant.message", func(event copilot.SessionEvent) { + fmt.Println("First message:", *event.Data.Content) +}) + +// Later, to unsubscribe: +unsubscribeAll() +unsubscribeIdle() +``` + +
+ +
+.NET + +```csharp +// Subscribe to all events +var unsubscribeAll = session.On(ev => Console.WriteLine($"Event: {ev.Type}")); + +// Subscribe to specific event type +var unsubscribeIdle = session.On(ev => Console.WriteLine("Session is idle")); + +// Subscribe to next occurrence only (auto-unsubscribes) +session.Once(ev => Console.WriteLine($"First message: {ev.Data.Content}")); + +// Later, to unsubscribe: +unsubscribeAll(); +unsubscribeIdle(); +``` + +
+ ## Step 4: Add a Custom Tool Now for the powerful part. Let's give Copilot the ability to call your code by defining a custom tool. We'll create a simple weather lookup tool. diff --git a/docs/hooks/error-handling.md b/docs/hooks/error-handling.md index 572455b1..04f70bc6 100644 --- a/docs/hooks/error-handling.md +++ b/docs/hooks/error-handling.md @@ -105,7 +105,7 @@ const session = await client.createSession({ ```python async def on_error_occurred(input_data, invocation): print(f"[{invocation['session_id']}] Error: {input_data['error']}") - print(f" Context: {input_data['error_context']}") + print(f" Context: {input_data['errorContext']}") print(f" Recoverable: {input_data['recoverable']}") return None @@ -145,11 +145,8 @@ var session = await client.CreateSessionAsync(new SessionConfig OnErrorOccurred = (input, invocation) => { Console.Error.WriteLine($"[{invocation.SessionId}] Error: {input.Error}"); - Console.Error.WriteLine($" Type: {input.ErrorType}"); - if (!string.IsNullOrEmpty(input.Stack)) - { - Console.Error.WriteLine($" Stack: {input.Stack}"); - } + Console.Error.WriteLine($" Context: {input.ErrorContext}"); + Console.Error.WriteLine($" Recoverable: {input.Recoverable}"); return Task.FromResult(null); }, }, @@ -169,11 +166,11 @@ const session = await client.createSession({ captureException(new Error(input.error), { tags: { sessionId: invocation.sessionId, - errorType: input.errorType, + errorContext: input.errorContext, }, extra: { - stack: input.stack, - context: input.context, + error: input.error, + recoverable: input.recoverable, cwd: input.cwd, }, }); diff --git a/docs/hooks/user-prompt-submitted.md b/docs/hooks/user-prompt-submitted.md index af013022..801f8e57 100644 --- a/docs/hooks/user-prompt-submitted.md +++ b/docs/hooks/user-prompt-submitted.md @@ -205,9 +205,10 @@ const session = await client.createSession({ onUserPromptSubmitted: async (input) => { for (const pattern of BLOCKED_PATTERNS) { if (pattern.test(input.prompt)) { + // Replace the prompt with a warning message return { - reject: true, - rejectReason: "Please don't include sensitive credentials in your prompts. Use environment variables instead.", + modifiedPrompt: "[Content blocked: Please don't include sensitive credentials in your prompts. Use environment variables instead.]", + suppressOutput: true, }; } } @@ -226,9 +227,10 @@ const session = await client.createSession({ hooks: { onUserPromptSubmitted: async (input) => { if (input.prompt.length > MAX_PROMPT_LENGTH) { + // Truncate the prompt and add context return { - reject: true, - rejectReason: `Prompt too long (${input.prompt.length} chars). Maximum allowed: ${MAX_PROMPT_LENGTH} chars. Please shorten your request.`, + modifiedPrompt: input.prompt.substring(0, MAX_PROMPT_LENGTH), + additionalContext: `Note: The original prompt was ${input.prompt.length} characters and was truncated to ${MAX_PROMPT_LENGTH} characters.`, }; } return null; diff --git a/docs/mcp/overview.md b/docs/mcp/overview.md index c0b0e52e..d626f679 100644 --- a/docs/mcp/overview.md +++ b/docs/mcp/overview.md @@ -117,14 +117,15 @@ func main() { } defer client.Stop() + // MCPServerConfig is map[string]any for flexibility session, err := client.CreateSession(ctx, &copilot.SessionConfig{ Model: "gpt-5", MCPServers: map[string]copilot.MCPServerConfig{ "my-local-server": { - Type: "local", - Command: "node", - Args: []string{"./mcp-server.js"}, - Tools: []string{"*"}, + "type": "local", + "command": "node", + "args": []string{"./mcp-server.js"}, + "tools": []string{"*"}, }, }, }) From 1f57169bb7747c04c0323ee7247e2a01201a2f25 Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 21:35:13 -0800 Subject: [PATCH 03/14] Refactor error handling messages and improve documentation links --- docs/hooks/error-handling.md | 44 ++-- docs/hooks/overview.md | 2 +- scripts/docs-validation/extract.ts | 329 +++++++++++++++++++++++++++++ 3 files changed, 351 insertions(+), 24 deletions(-) create mode 100644 scripts/docs-validation/extract.ts diff --git a/docs/hooks/error-handling.md b/docs/hooks/error-handling.md index 04f70bc6..b37ea7a5 100644 --- a/docs/hooks/error-handling.md +++ b/docs/hooks/error-handling.md @@ -185,20 +185,20 @@ const session = await client.createSession({ ```typescript const ERROR_MESSAGES: Record = { - "rate_limit": "Too many requests. Please wait a moment and try again.", - "auth_failed": "Authentication failed. Please check your credentials.", - "network_error": "Network connection issue. Please check your internet connection.", - "timeout": "Request timed out. Try breaking your request into smaller parts.", + "model_call": "There was an issue communicating with the AI model. Please try again.", + "tool_execution": "A tool failed to execute. Please check your inputs and try again.", + "system": "A system error occurred. Please try again later.", + "user_input": "There was an issue with your input. Please check and try again.", }; const session = await client.createSession({ hooks: { onErrorOccurred: async (input) => { - const friendlyMessage = ERROR_MESSAGES[input.errorType]; + const friendlyMessage = ERROR_MESSAGES[input.errorContext]; if (friendlyMessage) { return { - modifiedMessage: friendlyMessage, + userNotification: friendlyMessage, }; } @@ -211,17 +211,13 @@ const session = await client.createSession({ ### Suppress Non-Critical Errors ```typescript -const SUPPRESSED_ERRORS = [ - "tool_not_found", - "file_not_found", -]; - const session = await client.createSession({ hooks: { onErrorOccurred: async (input) => { - if (SUPPRESSED_ERRORS.includes(input.errorType)) { - console.log(`Suppressed error: ${input.errorType}`); - return { suppressError: true }; + // Suppress tool execution errors that are recoverable + if (input.errorContext === "tool_execution" && input.recoverable) { + console.log(`Suppressed recoverable error: ${input.error}`); + return { suppressOutput: true }; } return null; }, @@ -235,9 +231,9 @@ const session = await client.createSession({ const session = await client.createSession({ hooks: { onErrorOccurred: async (input) => { - if (input.errorType === "tool_execution_failed") { + if (input.errorContext === "tool_execution") { return { - additionalContext: ` + userNotification: ` The tool failed. Here are some recovery suggestions: - Check if required dependencies are installed - Verify file paths are correct @@ -246,9 +242,11 @@ The tool failed. Here are some recovery suggestions: }; } - if (input.errorType === "rate_limit") { + if (input.errorContext === "model_call" && input.error.includes("rate")) { return { - additionalContext: "Rate limit hit. Waiting before retry.", + errorHandling: "retry", + retryCount: 3, + userNotification: "Rate limit hit. Retrying...", }; } @@ -272,7 +270,7 @@ const errorStats = new Map(); const session = await client.createSession({ hooks: { onErrorOccurred: async (input, invocation) => { - const key = `${input.errorType}:${input.error.substring(0, 50)}`; + const key = `${input.errorContext}:${input.error.substring(0, 50)}`; const existing = errorStats.get(key) || { count: 0, @@ -300,17 +298,17 @@ const session = await client.createSession({ ### Alert on Critical Errors ```typescript -const CRITICAL_ERRORS = ["auth_failed", "api_error", "system_error"]; +const CRITICAL_CONTEXTS = ["system", "model_call"]; const session = await client.createSession({ hooks: { onErrorOccurred: async (input, invocation) => { - if (CRITICAL_ERRORS.includes(input.errorType)) { + if (CRITICAL_CONTEXTS.includes(input.errorContext) && !input.recoverable) { await sendAlert({ level: "critical", message: `Critical error in session ${invocation.sessionId}`, error: input.error, - type: input.errorType, + context: input.errorContext, timestamp: new Date(input.timestamp).toISOString(), }); } @@ -347,7 +345,7 @@ const session = await client.createSession({ console.error(`Error in session ${invocation.sessionId}:`); console.error(` Error: ${input.error}`); - console.error(` Type: ${input.errorType}`); + console.error(` Context: ${input.errorContext}`); if (ctx?.lastTool) { console.error(` Last tool: ${ctx.lastTool}`); } diff --git a/docs/hooks/overview.md b/docs/hooks/overview.md index be04b417..68f2e5d8 100644 --- a/docs/hooks/overview.md +++ b/docs/hooks/overview.md @@ -231,5 +231,5 @@ const session = await client.createSession({ ## See Also - [Getting Started Guide](../getting-started.md) -- [Custom Tools](../getting-started.md#step-4-add-custom-tools) +- [Custom Tools](../getting-started.md#step-4-add-a-custom-tool) - [Debugging Guide](../debugging.md) diff --git a/scripts/docs-validation/extract.ts b/scripts/docs-validation/extract.ts new file mode 100644 index 00000000..d4b7cf05 --- /dev/null +++ b/scripts/docs-validation/extract.ts @@ -0,0 +1,329 @@ +/** + * Extracts code blocks from markdown documentation files. + * Outputs individual files for validation by language-specific tools. + */ + +import * as fs from "fs"; +import * as path from "path"; +import { glob } from "glob"; + +const DOCS_DIR = path.resolve(import.meta.dirname, "../../docs"); +const OUTPUT_DIR = path.resolve(import.meta.dirname, "../../docs/.validation"); + +// Map markdown language tags to our canonical names +const LANGUAGE_MAP: Record = { + typescript: "typescript", + ts: "typescript", + javascript: "typescript", // Treat JS as TS for validation + js: "typescript", + python: "python", + py: "python", + go: "go", + golang: "go", + csharp: "csharp", + "c#": "csharp", + cs: "csharp", +}; + +interface CodeBlock { + language: string; + code: string; + file: string; + line: number; + skip: boolean; + wrapAsync: boolean; +} + +interface ExtractionManifest { + extractedAt: string; + blocks: { + id: string; + sourceFile: string; + sourceLine: number; + language: string; + outputFile: string; + }[]; +} + +function parseMarkdownCodeBlocks( + content: string, + filePath: string +): CodeBlock[] { + const blocks: CodeBlock[] = []; + const lines = content.split("\n"); + + let inCodeBlock = false; + let currentLang = ""; + let currentCode: string[] = []; + let blockStartLine = 0; + let skipNext = false; + let wrapAsync = false; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + + // Check for validation directives + if (line.includes("")) { + skipNext = true; + continue; + } + if (line.includes("")) { + wrapAsync = true; + continue; + } + + // Start of code block + if (!inCodeBlock && line.startsWith("```")) { + const lang = line.slice(3).trim().toLowerCase(); + if (lang && LANGUAGE_MAP[lang]) { + inCodeBlock = true; + currentLang = LANGUAGE_MAP[lang]; + currentCode = []; + blockStartLine = i + 1; // 1-indexed line number + } + continue; + } + + // End of code block + if (inCodeBlock && line.startsWith("```")) { + blocks.push({ + language: currentLang, + code: currentCode.join("\n"), + file: filePath, + line: blockStartLine, + skip: skipNext, + wrapAsync: wrapAsync, + }); + inCodeBlock = false; + currentLang = ""; + currentCode = []; + skipNext = false; + wrapAsync = false; + continue; + } + + // Inside code block + if (inCodeBlock) { + currentCode.push(line); + } + } + + return blocks; +} + +function generateFileName( + block: CodeBlock, + index: number, + langCounts: Map +): string { + const count = langCounts.get(block.language) || 0; + langCounts.set(block.language, count + 1); + + const sourceBasename = path.basename(block.file, ".md"); + const ext = getExtension(block.language); + + return `${sourceBasename}_${count}${ext}`; +} + +function getExtension(language: string): string { + switch (language) { + case "typescript": + return ".ts"; + case "python": + return ".py"; + case "go": + return ".go"; + case "csharp": + return ".cs"; + default: + return ".txt"; + } +} + +function wrapCodeForValidation(block: CodeBlock): string { + let code = block.code; + + // Python: wrap in async main if needed + if (block.language === "python" && block.wrapAsync) { + const indented = code + .split("\n") + .map((l) => " " + l) + .join("\n"); + code = `import asyncio\n\nasync def main():\n${indented}\n\nasyncio.run(main())`; + } + + // Go: ensure package declaration + if (block.language === "go" && !code.includes("package ")) { + code = `package main\n\n${code}`; + } + + // Go: add main function if missing and has statements outside functions + if (block.language === "go" && !code.includes("func main()")) { + // Check if code has statements that need to be in main + const hasStatements = /^[a-z]/.test(code.trim().split("\n").pop() || ""); + if (hasStatements) { + // This is a snippet, wrap it + const lines = code.split("\n"); + const packageLine = lines.find((l) => l.startsWith("package ")) || ""; + const imports = lines.filter( + (l) => l.startsWith("import ") || l.startsWith('import (') + ); + const rest = lines.filter( + (l) => + !l.startsWith("package ") && + !l.startsWith("import ") && + !l.startsWith("import (") && + !l.startsWith(")") && + !l.startsWith("\t") // import block lines + ); + + // Only wrap if there are loose statements (not type/func definitions) + const hasLooseStatements = rest.some( + (l) => + l.trim() && + !l.startsWith("type ") && + !l.startsWith("func ") && + !l.startsWith("//") && + !l.startsWith("var ") && + !l.startsWith("const ") + ); + + if (!hasLooseStatements) { + // Code has proper structure, just ensure it has a main + code = code + "\n\nfunc main() {}"; + } + } + } + + // C#: wrap in minimal structure if needed + if (block.language === "csharp") { + // Check if it's a complete file (has namespace or class) + const hasStructure = + code.includes("namespace ") || + code.includes("class ") || + code.includes("record "); + if (!hasStructure) { + // Top-level statements are fine in modern C#, just ensure usings are at top + } + } + + return code; +} + +async function main() { + console.log("📖 Extracting code blocks from documentation...\n"); + + // Clean output directory + if (fs.existsSync(OUTPUT_DIR)) { + fs.rmSync(OUTPUT_DIR, { recursive: true }); + } + fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + + // Create language subdirectories + for (const lang of ["typescript", "python", "go", "csharp"]) { + fs.mkdirSync(path.join(OUTPUT_DIR, lang), { recursive: true }); + } + + // Find all markdown files + const mdFiles = await glob("**/*.md", { + cwd: DOCS_DIR, + ignore: [".validation/**", "node_modules/**", "IMPROVEMENT_PLAN.md"], + }); + + console.log(`Found ${mdFiles.length} markdown files\n`); + + const manifest: ExtractionManifest = { + extractedAt: new Date().toISOString(), + blocks: [], + }; + + const langCounts = new Map(); + let totalBlocks = 0; + let skippedBlocks = 0; + + for (const mdFile of mdFiles) { + const fullPath = path.join(DOCS_DIR, mdFile); + const content = fs.readFileSync(fullPath, "utf-8"); + const blocks = parseMarkdownCodeBlocks(content, mdFile); + + for (const block of blocks) { + if (block.skip) { + skippedBlocks++; + continue; + } + + // Skip empty or trivial blocks + if (block.code.trim().length < 10) { + continue; + } + + const fileName = generateFileName(block, totalBlocks, langCounts); + const outputPath = path.join(OUTPUT_DIR, block.language, fileName); + + const wrappedCode = wrapCodeForValidation(block); + + // Add source location comment + const sourceComment = getSourceComment( + block.language, + block.file, + block.line + ); + const finalCode = sourceComment + "\n" + wrappedCode; + + fs.writeFileSync(outputPath, finalCode); + + manifest.blocks.push({ + id: `${block.language}/${fileName}`, + sourceFile: block.file, + sourceLine: block.line, + language: block.language, + outputFile: `${block.language}/${fileName}`, + }); + + totalBlocks++; + } + } + + // Write manifest + fs.writeFileSync( + path.join(OUTPUT_DIR, "manifest.json"), + JSON.stringify(manifest, null, 2) + ); + + // Summary + console.log("Extraction complete!\n"); + console.log(" Language Count"); + console.log(" ─────────────────────"); + for (const [lang, count] of langCounts) { + console.log(` ${lang.padEnd(14)} ${count}`); + } + console.log(" ─────────────────────"); + console.log(` Total ${totalBlocks}`); + if (skippedBlocks > 0) { + console.log(` Skipped ${skippedBlocks}`); + } + console.log(`\nOutput: ${OUTPUT_DIR}`); +} + +function getSourceComment( + language: string, + file: string, + line: number +): string { + const location = `Source: ${file}:${line}`; + switch (language) { + case "typescript": + case "go": + case "csharp": + return `// ${location}`; + case "python": + return `# ${location}`; + default: + return `// ${location}`; + } +} + +main().catch((err) => { + console.error("Extraction failed:", err); + process.exit(1); +}); From a5794fe84f7885424178d2065d2b018364dce7c7 Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 21:45:43 -0800 Subject: [PATCH 04/14] Update context usage in session management examples across documentation --- docs/auth/byok.md | 7 +-- docs/getting-started.md | 69 +++++++++++++++--------------- docs/guides/session-persistence.md | 11 +++-- docs/guides/skills.md | 5 ++- docs/hooks/overview.md | 1 + docs/mcp/overview.md | 1 - 6 files changed, 50 insertions(+), 44 deletions(-) diff --git a/docs/auth/byok.md b/docs/auth/byok.md index 05256e97..356b653c 100644 --- a/docs/auth/byok.md +++ b/docs/auth/byok.md @@ -104,13 +104,14 @@ import ( ) func main() { + ctx := context.Background() client := copilot.NewClient(nil) if err := client.Start(); err != nil { panic(err) } defer client.Stop() - session, err := client.CreateSession(context.Background(), &copilot.SessionConfig{ + session, err := client.CreateSession(ctx, &copilot.SessionConfig{ Model: "gpt-5.2-codex", // Your deployment name Provider: &copilot.ProviderConfig{ Type: "openai", @@ -123,9 +124,9 @@ func main() { panic(err) } - response, err := session.SendAndWait(copilot.MessageOptions{ + response, err := session.SendAndWait(ctx, copilot.MessageOptions{ Prompt: "What is 2+2?", - }, 0) + }) if err != nil { panic(err) } diff --git a/docs/getting-started.md b/docs/getting-started.md index 411bdbef..166608ad 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -395,13 +395,12 @@ Run the code again. You'll see the response appear word by word. ### Event Subscription Methods -The SDK provides three methods for subscribing to session events: +The SDK provides methods for subscribing to session events: | Method | Description | |--------|-------------| | `on(handler)` | Subscribe to all events; returns unsubscribe function | -| `on(eventType, handler)` | Subscribe to specific event type; returns unsubscribe function | -| `once(eventType, handler)` | Subscribe to next occurrence only; auto-unsubscribes after firing | +| `on(eventType, handler)` | Subscribe to specific event type (Node.js/TypeScript only); returns unsubscribe function |
Node.js / TypeScript @@ -417,11 +416,6 @@ const unsubscribeIdle = session.on("session.idle", (event) => { console.log("Session is idle"); }); -// Subscribe to next occurrence only (auto-unsubscribes) -session.once("assistant.message", (event) => { - console.log("First message:", event.data.content); -}); - // Later, to unsubscribe: unsubscribeAll(); unsubscribeIdle(); @@ -434,17 +428,19 @@ unsubscribeIdle(); ```python # Subscribe to all events -unsubscribe_all = session.on(lambda event: print(f"Event: {event.type}")) +unsubscribe = session.on(lambda event: print(f"Event: {event.type}")) -# Subscribe to specific event type -unsubscribe_idle = session.on("session.idle", lambda event: print("Session is idle")) +# Filter by event type in your handler +def handle_event(event): + if event.type == SessionEventType.SESSION_IDLE: + print("Session is idle") + elif event.type == SessionEventType.ASSISTANT_MESSAGE: + print(f"Message: {event.data.content}") -# Subscribe to next occurrence only (auto-unsubscribes) -session.once("assistant.message", lambda event: print(f"First message: {event.data.content}")) +unsubscribe = session.on(handle_event) # Later, to unsubscribe: -unsubscribe_all() -unsubscribe_idle() +unsubscribe() ```
@@ -454,23 +450,21 @@ unsubscribe_idle() ```go // Subscribe to all events -unsubscribeAll := session.On(func(event copilot.SessionEvent) { +unsubscribe := session.On(func(event copilot.SessionEvent) { fmt.Println("Event:", event.Type) }) -// Subscribe to specific event type -unsubscribeIdle := session.OnType("session.idle", func(event copilot.SessionEvent) { - fmt.Println("Session is idle") -}) - -// Subscribe to next occurrence only (auto-unsubscribes) -session.Once("assistant.message", func(event copilot.SessionEvent) { - fmt.Println("First message:", *event.Data.Content) +// Filter by event type in your handler +session.On(func(event copilot.SessionEvent) { + if event.Type == "session.idle" { + fmt.Println("Session is idle") + } else if event.Type == "assistant.message" { + fmt.Println("Message:", *event.Data.Content) + } }) // Later, to unsubscribe: -unsubscribeAll() -unsubscribeIdle() +unsubscribe() ``` @@ -480,17 +474,24 @@ unsubscribeIdle() ```csharp // Subscribe to all events -var unsubscribeAll = session.On(ev => Console.WriteLine($"Event: {ev.Type}")); - -// Subscribe to specific event type -var unsubscribeIdle = session.On(ev => Console.WriteLine("Session is idle")); +var unsubscribe = session.On(ev => Console.WriteLine($"Event: {ev.Type}")); -// Subscribe to next occurrence only (auto-unsubscribes) -session.Once(ev => Console.WriteLine($"First message: {ev.Data.Content}")); +// Filter by event type using pattern matching +session.On(ev => +{ + switch (ev) + { + case SessionIdleEvent: + Console.WriteLine("Session is idle"); + break; + case AssistantMessageEvent msg: + Console.WriteLine($"Message: {msg.Data.Content}"); + break; + } +}); // Later, to unsubscribe: -unsubscribeAll(); -unsubscribeIdle(); +unsubscribe.Dispose(); ``` diff --git a/docs/guides/session-persistence.md b/docs/guides/session-persistence.md index faf0e007..a37a381b 100644 --- a/docs/guides/session-persistence.md +++ b/docs/guides/session-persistence.md @@ -66,16 +66,17 @@ await session.send_and_wait({"prompt": "Analyze my codebase"}) ### Go ```go +ctx := context.Background() client := copilot.NewClient(nil) // Create a session with a meaningful ID -session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{ +session, _ := client.CreateSession(ctx, &copilot.SessionConfig{ SessionID: "user-123-task-456", Model: "gpt-5.2-codex", }) // Do some work... -session.SendAndWait(context.Background(), copilot.MessageOptions{Prompt: "Analyze my codebase"}) +session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Analyze my codebase"}) // Session state is automatically persisted ``` @@ -141,11 +142,13 @@ await session.send_and_wait({"prompt": "What did we discuss earlier?"}) ### Go ```go +ctx := context.Background() + // Resume from a different client instance (or after restart) -session, _ := client.ResumeSession(context.Background(), "user-123-task-456", nil) +session, _ := client.ResumeSession(ctx, "user-123-task-456", nil) // Continue where you left off -session.SendAndWait(context.Background(), copilot.MessageOptions{Prompt: "What did we discuss earlier?"}) +session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "What did we discuss earlier?"}) ``` ### C# (.NET) diff --git a/docs/guides/skills.md b/docs/guides/skills.md index 5ebcfac5..4830a656 100644 --- a/docs/guides/skills.md +++ b/docs/guides/skills.md @@ -81,13 +81,14 @@ import ( ) func main() { + ctx := context.Background() client := copilot.NewClient(nil) if err := client.Start(); err != nil { log.Fatal(err) } defer client.Stop() - session, err := client.CreateSession(context.Background(), &copilot.SessionConfig{ + session, err := client.CreateSession(ctx, &copilot.SessionConfig{ Model: "gpt-4.1", SkillDirectories: []string{ "./skills/code-review", @@ -100,7 +101,7 @@ func main() { } // Copilot now has access to skills in those directories - _, err = session.SendAndWait(context.Background(), copilot.MessageOptions{ + _, err = session.SendAndWait(ctx, copilot.MessageOptions{ Prompt: "Review this code for security issues", }) if err != nil { diff --git a/docs/hooks/overview.md b/docs/hooks/overview.md index 68f2e5d8..a51ef046 100644 --- a/docs/hooks/overview.md +++ b/docs/hooks/overview.md @@ -57,6 +57,7 @@ from copilot import CopilotClient async def main(): client = CopilotClient() + await client.start() async def on_pre_tool_use(input_data, invocation): print(f"Tool called: {input_data['toolName']}") diff --git a/docs/mcp/overview.md b/docs/mcp/overview.md index d626f679..b6f1b786 100644 --- a/docs/mcp/overview.md +++ b/docs/mcp/overview.md @@ -168,7 +168,6 @@ import { CopilotClient } from "@github/copilot-sdk"; async function main() { const client = new CopilotClient(); - await client.start(); // Create session with filesystem MCP server const session = await client.createSession({ From a7218dbfc385195fca03824d3be6c973ef0be4c5 Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 21:50:11 -0800 Subject: [PATCH 05/14] Add documentation code validation system - Add scripts/docs-validation/ tooling to extract and validate code blocks - Extract code from markdown and validate with language-specific compilers - TypeScript: tsc --noEmit type checking - Python: py_compile + mypy for syntax and type checking - Go: go build for compilation checking - C#: dotnet build for compilation checking - Add GitHub Actions workflow (.github/workflows/docs-validation.yml) - Runs on PRs touching docs/ or SDK source files - Parallel validation jobs for each language - Add justfile tasks: validate-docs, validate-docs-ts, etc. - Fix Go docs: client.Start() -> client.Start(ctx) - All 157 code blocks now pass validation --- .github/workflows/docs-validation.yml | 178 ++++ docs/.gitignore | 2 + docs/auth/byok.md | 4 +- docs/auth/index.md | 3 + docs/debugging.md | 2 + docs/getting-started.md | 12 +- docs/guides/session-persistence.md | 2 + docs/guides/skills.md | 3 +- docs/hooks/error-handling.md | 2 + docs/hooks/post-tool-use.md | 2 + docs/hooks/pre-tool-use.md | 2 + docs/hooks/session-lifecycle.md | 2 + docs/hooks/user-prompt-submitted.md | 2 + docs/mcp/debugging.md | 1 + docs/mcp/overview.md | 3 +- justfile | 33 + scripts/docs-validation/.gitignore | 1 + scripts/docs-validation/extract.ts | 85 +- scripts/docs-validation/package-lock.json | 1016 +++++++++++++++++++++ scripts/docs-validation/package.json | 19 + scripts/docs-validation/validate.ts | 433 +++++++++ 21 files changed, 1792 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/docs-validation.yml create mode 100644 docs/.gitignore create mode 100644 scripts/docs-validation/.gitignore create mode 100644 scripts/docs-validation/package-lock.json create mode 100644 scripts/docs-validation/package.json create mode 100644 scripts/docs-validation/validate.ts diff --git a/.github/workflows/docs-validation.yml b/.github/workflows/docs-validation.yml new file mode 100644 index 00000000..814e1456 --- /dev/null +++ b/.github/workflows/docs-validation.yml @@ -0,0 +1,178 @@ +name: "Documentation Validation" + +on: + pull_request: + paths: + - 'docs/**' + - 'nodejs/src/**' + - 'python/copilot/**' + - 'go/**/*.go' + - 'dotnet/src/**' + - 'scripts/docs-validation/**' + - '.github/workflows/docs-validation.yml' + workflow_dispatch: + merge_group: + +permissions: + contents: read + +jobs: + extract: + name: "Extract Code Blocks" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: "npm" + cache-dependency-path: "scripts/docs-validation/package-lock.json" + + - name: Install extraction dependencies + working-directory: scripts/docs-validation + run: npm ci + + - name: Extract code blocks + working-directory: scripts/docs-validation + run: npm run extract + + - name: Upload extracted code + uses: actions/upload-artifact@v4 + with: + name: extracted-code + path: docs/.validation/ + retention-days: 1 + + validate-typescript: + name: "Validate TypeScript" + needs: extract + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: "npm" + cache-dependency-path: "nodejs/package-lock.json" + + - name: Install SDK dependencies + working-directory: nodejs + run: npm ci --ignore-scripts + + - name: Install validation dependencies + working-directory: scripts/docs-validation + run: npm ci + + - name: Download extracted code + uses: actions/download-artifact@v4 + with: + name: extracted-code + path: docs/.validation/ + + - name: Validate TypeScript + working-directory: scripts/docs-validation + run: npm run validate:ts + + validate-python: + name: "Validate Python" + needs: extract + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install uv + uses: astral-sh/setup-uv@v5 + + - name: Install SDK dependencies + working-directory: python + run: uv sync + + - name: Install mypy + run: pip install mypy + + - name: Install validation dependencies + working-directory: scripts/docs-validation + run: npm ci + + - uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Download extracted code + uses: actions/download-artifact@v4 + with: + name: extracted-code + path: docs/.validation/ + + - name: Validate Python + working-directory: scripts/docs-validation + run: npm run validate:py + + validate-go: + name: "Validate Go" + needs: extract + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: "1.23" + cache-dependency-path: "go/go.sum" + + - uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Install validation dependencies + working-directory: scripts/docs-validation + run: npm ci + + - name: Download extracted code + uses: actions/download-artifact@v4 + with: + name: extracted-code + path: docs/.validation/ + + - name: Validate Go + working-directory: scripts/docs-validation + run: npm run validate:go + + validate-csharp: + name: "Validate C#" + needs: extract + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: "8.0.x" + + - uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Install validation dependencies + working-directory: scripts/docs-validation + run: npm ci + + - name: Download extracted code + uses: actions/download-artifact@v4 + with: + name: extracted-code + path: docs/.validation/ + + - name: Restore SDK dependencies + working-directory: dotnet + run: dotnet restore + + - name: Validate C# + working-directory: scripts/docs-validation + run: npm run validate:cs diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..2d253c5a --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,2 @@ +# Extracted code for validation (generated) +.validation/ diff --git a/docs/auth/byok.md b/docs/auth/byok.md index 356b653c..6c836743 100644 --- a/docs/auth/byok.md +++ b/docs/auth/byok.md @@ -106,7 +106,7 @@ import ( func main() { ctx := context.Background() client := copilot.NewClient(nil) - if err := client.Start(); err != nil { + if err := client.Start(ctx); err != nil { panic(err) } defer client.Stop() @@ -326,6 +326,7 @@ const session = await client.createSession({ For Azure OpenAI endpoints (`*.openai.azure.com`), use the correct type: + ```typescript // ❌ Wrong: Using "openai" type with native Azure endpoint provider: { @@ -342,6 +343,7 @@ provider: { However, if your Azure AI Foundry deployment provides an OpenAI-compatible endpoint path (e.g., `/openai/v1/`), use `type: "openai"`: + ```typescript // ✅ Correct: OpenAI-compatible Azure AI Foundry endpoint provider: { diff --git a/docs/auth/index.md b/docs/auth/index.md index ffd47625..c4befccf 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -50,6 +50,7 @@ await client.start()
Go + ```go import copilot "github.com/github/copilot-sdk/go" @@ -119,6 +120,7 @@ await client.start()
Go + ```go import copilot "github.com/github/copilot-sdk/go" @@ -262,6 +264,7 @@ client = CopilotClient({
Go + ```go client := copilot.NewClient(&copilot.ClientOptions{ UseLoggedInUser: copilot.Bool(false), // Only use explicit tokens diff --git a/docs/debugging.md b/docs/debugging.md index 1586418f..6bb40d64 100644 --- a/docs/debugging.md +++ b/docs/debugging.md @@ -44,6 +44,7 @@ client = CopilotClient({"log_level": "debug"})
Go + ```go import copilot "github.com/github/copilot-sdk/go" @@ -108,6 +109,7 @@ const client = new CopilotClient({
Go + ```go // The Go SDK does not currently support passing extra CLI arguments. // For custom log directories, run the CLI manually with --log-dir diff --git a/docs/getting-started.md b/docs/getting-started.md index 166608ad..34caa7dd 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -173,7 +173,7 @@ import ( func main() { ctx := context.Background() client := copilot.NewClient(nil) - if err := client.Start(); err != nil { + if err := client.Start(ctx); err != nil { log.Fatal(err) } defer client.Stop() @@ -325,7 +325,7 @@ import ( func main() { ctx := context.Background() client := copilot.NewClient(nil) - if err := client.Start(); err != nil { + if err := client.Start(ctx); err != nil { log.Fatal(err) } defer client.Stop() @@ -448,6 +448,7 @@ unsubscribe()
Go + ```go // Subscribe to all events unsubscribe := session.On(func(event copilot.SessionEvent) { @@ -662,7 +663,7 @@ func main() { ) client := copilot.NewClient(nil) - if err := client.Start(); err != nil { + if err := client.Start(ctx); err != nil { log.Fatal(err) } defer client.Stop() @@ -945,7 +946,7 @@ func main() { ) client := copilot.NewClient(nil) - if err := client.Start(); err != nil { + if err := client.Start(ctx); err != nil { log.Fatal(err) } defer client.Stop() @@ -1224,6 +1225,7 @@ session = await client.create_session()
Go + ```go import copilot "github.com/github/copilot-sdk/go" @@ -1231,7 +1233,7 @@ client := copilot.NewClient(&copilot.ClientOptions{ CLIUrl: "localhost:4321", }) -if err := client.Start(); err != nil { +if err := client.Start(ctx); err != nil { log.Fatal(err) } defer client.Stop() diff --git a/docs/guides/session-persistence.md b/docs/guides/session-persistence.md index a37a381b..c1abb28f 100644 --- a/docs/guides/session-persistence.md +++ b/docs/guides/session-persistence.md @@ -65,6 +65,7 @@ await session.send_and_wait({"prompt": "Analyze my codebase"}) ### Go + ```go ctx := context.Background() client := copilot.NewClient(nil) @@ -141,6 +142,7 @@ await session.send_and_wait({"prompt": "What did we discuss earlier?"}) ### Go + ```go ctx := context.Background() diff --git a/docs/guides/skills.md b/docs/guides/skills.md index 4830a656..273ce97c 100644 --- a/docs/guides/skills.md +++ b/docs/guides/skills.md @@ -83,7 +83,7 @@ import ( func main() { ctx := context.Background() client := copilot.NewClient(nil) - if err := client.Start(); err != nil { + if err := client.Start(ctx); err != nil { log.Fatal(err) } defer client.Stop() @@ -170,6 +170,7 @@ session = await client.create_session({
Go + ```go session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{ SkillDirectories: []string{"./skills"}, diff --git a/docs/hooks/error-handling.md b/docs/hooks/error-handling.md index b37ea7a5..f406626d 100644 --- a/docs/hooks/error-handling.md +++ b/docs/hooks/error-handling.md @@ -36,6 +36,7 @@ ErrorOccurredHandler = Callable[
Go + ```go type ErrorOccurredHandler func( input ErrorOccurredHookInput, @@ -119,6 +120,7 @@ session = await client.create_session({
Go + ```go session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{ Hooks: &copilot.SessionHooks{ diff --git a/docs/hooks/post-tool-use.md b/docs/hooks/post-tool-use.md index ecaf41ae..06e1dd17 100644 --- a/docs/hooks/post-tool-use.md +++ b/docs/hooks/post-tool-use.md @@ -36,6 +36,7 @@ PostToolUseHandler = Callable[
Go + ```go type PostToolUseHandler func( input PostToolUseHookInput, @@ -118,6 +119,7 @@ session = await client.create_session({
Go + ```go session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{ Hooks: &copilot.SessionHooks{ diff --git a/docs/hooks/pre-tool-use.md b/docs/hooks/pre-tool-use.md index 43bb63be..d0c9ceb1 100644 --- a/docs/hooks/pre-tool-use.md +++ b/docs/hooks/pre-tool-use.md @@ -36,6 +36,7 @@ PreToolUseHandler = Callable[
Go + ```go type PreToolUseHandler func( input PreToolUseHookInput, @@ -125,6 +126,7 @@ session = await client.create_session({
Go + ```go session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{ Hooks: &copilot.SessionHooks{ diff --git a/docs/hooks/session-lifecycle.md b/docs/hooks/session-lifecycle.md index a1187cba..dcfd9544 100644 --- a/docs/hooks/session-lifecycle.md +++ b/docs/hooks/session-lifecycle.md @@ -40,6 +40,7 @@ SessionStartHandler = Callable[
Go + ```go type SessionStartHandler func( input SessionStartHookInput, @@ -216,6 +217,7 @@ SessionEndHandler = Callable[
Go + ```go type SessionEndHandler func( input SessionEndHookInput, diff --git a/docs/hooks/user-prompt-submitted.md b/docs/hooks/user-prompt-submitted.md index 801f8e57..9b88e299 100644 --- a/docs/hooks/user-prompt-submitted.md +++ b/docs/hooks/user-prompt-submitted.md @@ -36,6 +36,7 @@ UserPromptSubmittedHandler = Callable[
Go + ```go type UserPromptSubmittedHandler func( input UserPromptSubmittedHookInput, @@ -112,6 +113,7 @@ session = await client.create_session({
Go + ```go session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{ Hooks: &copilot.SessionHooks{ diff --git a/docs/mcp/debugging.md b/docs/mcp/debugging.md index 34e22a19..9027616a 100644 --- a/docs/mcp/debugging.md +++ b/docs/mcp/debugging.md @@ -302,6 +302,7 @@ xattr -d com.apple.quarantine /path/to/mcp-server #### Homebrew Paths + ```typescript // GUI apps may not have /opt/homebrew in PATH mcpServers: { diff --git a/docs/mcp/overview.md b/docs/mcp/overview.md index b6f1b786..1ee147b6 100644 --- a/docs/mcp/overview.md +++ b/docs/mcp/overview.md @@ -112,7 +112,7 @@ import ( func main() { ctx := context.Background() client := copilot.NewClient(nil) - if err := client.Start(); err != nil { + if err := client.Start(ctx); err != nil { log.Fatal(err) } defer client.Stop() @@ -132,6 +132,7 @@ func main() { if err != nil { log.Fatal(err) } + defer session.Destroy() // Use the session... } diff --git a/justfile b/justfile index 8b1af30c..8cf72c73 100644 --- a/justfile +++ b/justfile @@ -84,3 +84,36 @@ install: playground: @echo "=== Starting SDK Playground ===" @cd demos/playground && npm install && npm start + +# Validate documentation code examples +validate-docs: validate-docs-extract validate-docs-check + +# Extract code blocks from documentation +validate-docs-extract: + @echo "=== Extracting documentation code blocks ===" + @cd scripts/docs-validation && npm ci --silent && npm run extract + +# Validate all extracted code blocks +validate-docs-check: + @echo "=== Validating documentation code blocks ===" + @cd scripts/docs-validation && npm run validate + +# Validate only TypeScript documentation examples +validate-docs-ts: + @echo "=== Validating TypeScript documentation ===" + @cd scripts/docs-validation && npm run validate:ts + +# Validate only Python documentation examples +validate-docs-py: + @echo "=== Validating Python documentation ===" + @cd scripts/docs-validation && npm run validate:py + +# Validate only Go documentation examples +validate-docs-go: + @echo "=== Validating Go documentation ===" + @cd scripts/docs-validation && npm run validate:go + +# Validate only C# documentation examples +validate-docs-cs: + @echo "=== Validating C# documentation ===" + @cd scripts/docs-validation && npm run validate:cs diff --git a/scripts/docs-validation/.gitignore b/scripts/docs-validation/.gitignore new file mode 100644 index 00000000..c2658d7d --- /dev/null +++ b/scripts/docs-validation/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/scripts/docs-validation/extract.ts b/scripts/docs-validation/extract.ts index d4b7cf05..a12099b9 100644 --- a/scripts/docs-validation/extract.ts +++ b/scripts/docs-validation/extract.ts @@ -140,16 +140,81 @@ function getExtension(language: string): string { } } +/** + * Detect code fragments that can't be validated as standalone files. + * These are typically partial snippets showing configuration options + * or code that's meant to be part of a larger context. + */ +function shouldSkipFragment(block: CodeBlock): boolean { + const code = block.code.trim(); + + // TypeScript/JavaScript: Skip bare object literals (config snippets) + if (block.language === "typescript") { + // Starts with property: value pattern (e.g., "provider: {") + if (/^[a-zA-Z_]+\s*:\s*[\{\[]/.test(code)) { + return true; + } + // Starts with just an object/array that's not assigned + if (/^\{[\s\S]*\}$/.test(code) && !code.includes("import ") && !code.includes("export ")) { + return true; + } + } + + // Go: Skip fragments that are just type definitions without package + if (block.language === "go") { + // Function signatures without bodies (interface definitions shown in docs) + if (/^func\s+\w+\([^)]*\)\s*\([^)]*\)\s*$/.test(code)) { + return true; + } + } + + return false; +} + function wrapCodeForValidation(block: CodeBlock): string { let code = block.code; - // Python: wrap in async main if needed - if (block.language === "python" && block.wrapAsync) { - const indented = code - .split("\n") - .map((l) => " " + l) - .join("\n"); - code = `import asyncio\n\nasync def main():\n${indented}\n\nasyncio.run(main())`; + // Python: auto-detect async code and wrap if needed + if (block.language === "python") { + const hasAwait = /\bawait\b/.test(code); + const hasAsyncDef = /\basync\s+def\b/.test(code); + + // Check if await is used outside of any async def + // Simple heuristic: if await appears at column 0 or after assignment at column 0 + const lines = code.split("\n"); + let awaitOutsideFunction = false; + let inAsyncFunction = false; + let indentLevel = 0; + + for (const line of lines) { + const trimmed = line.trimStart(); + const leadingSpaces = line.length - trimmed.length; + + // Track if we're in an async function + if (trimmed.startsWith("async def ")) { + inAsyncFunction = true; + indentLevel = leadingSpaces; + } else if (inAsyncFunction && leadingSpaces <= indentLevel && trimmed && !trimmed.startsWith("#")) { + // Dedented back, we're out of the function + inAsyncFunction = false; + } + + // Check for await outside function + if (trimmed.includes("await ") && !inAsyncFunction) { + awaitOutsideFunction = true; + break; + } + } + + const needsWrap = block.wrapAsync || awaitOutsideFunction || (hasAwait && !hasAsyncDef); + + if (needsWrap) { + const indented = code + .split("\n") + .map((l) => " " + l) + .join("\n"); + code = `import asyncio\n\nasync def main():\n${indented}\n\nasyncio.run(main())`; + } } // Go: ensure package declaration @@ -257,6 +322,12 @@ async function main() { continue; } + // Skip incomplete code fragments that can't be validated standalone + if (shouldSkipFragment(block)) { + skippedBlocks++; + continue; + } + const fileName = generateFileName(block, totalBlocks, langCounts); const outputPath = path.join(OUTPUT_DIR, block.language, fileName); diff --git a/scripts/docs-validation/package-lock.json b/scripts/docs-validation/package-lock.json new file mode 100644 index 00000000..aa37d5df --- /dev/null +++ b/scripts/docs-validation/package-lock.json @@ -0,0 +1,1016 @@ +{ + "name": "docs-validation", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "docs-validation", + "version": "1.0.0", + "dependencies": { + "glob": "^11.0.0", + "tsx": "^4.19.0", + "typescript": "^5.7.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", + "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.1.tgz", + "integrity": "sha512-EoY1N2xCn44xU6750Sx7OjOIT59FkmstNc3X6y5xpz7D5cBtZRe/3pSlTkDJgqsOk3WwZPkWfonhhUJfttQo3w==", + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "BlueOak-1.0.0", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/lru-cache": { + "version": "11.2.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", + "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/minimatch": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.2.tgz", + "integrity": "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/scripts/docs-validation/package.json b/scripts/docs-validation/package.json new file mode 100644 index 00000000..976df1de --- /dev/null +++ b/scripts/docs-validation/package.json @@ -0,0 +1,19 @@ +{ + "name": "docs-validation", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "extract": "tsx extract.ts", + "validate": "tsx validate.ts", + "validate:ts": "tsx validate.ts --lang typescript", + "validate:py": "tsx validate.ts --lang python", + "validate:go": "tsx validate.ts --lang go", + "validate:cs": "tsx validate.ts --lang csharp" + }, + "dependencies": { + "glob": "^11.0.0", + "tsx": "^4.19.0", + "typescript": "^5.7.0" + } +} diff --git a/scripts/docs-validation/validate.ts b/scripts/docs-validation/validate.ts new file mode 100644 index 00000000..56db66ec --- /dev/null +++ b/scripts/docs-validation/validate.ts @@ -0,0 +1,433 @@ +/** + * Validates extracted documentation code blocks. + * Runs language-specific type/compile checks. + */ + +import * as fs from "fs"; +import * as path from "path"; +import { execSync, spawn } from "child_process"; +import { glob } from "glob"; + +const ROOT_DIR = path.resolve(import.meta.dirname, "../.."); +const VALIDATION_DIR = path.join(ROOT_DIR, "docs/.validation"); + +interface ValidationResult { + file: string; + sourceFile: string; + sourceLine: number; + success: boolean; + errors: string[]; +} + +interface Manifest { + blocks: { + id: string; + sourceFile: string; + sourceLine: number; + language: string; + outputFile: string; + }[]; +} + +function loadManifest(): Manifest { + const manifestPath = path.join(VALIDATION_DIR, "manifest.json"); + if (!fs.existsSync(manifestPath)) { + console.error( + "❌ No manifest found. Run extraction first: npm run extract" + ); + process.exit(1); + } + return JSON.parse(fs.readFileSync(manifestPath, "utf-8")); +} + +async function validateTypeScript(): Promise { + const results: ValidationResult[] = []; + const tsDir = path.join(VALIDATION_DIR, "typescript"); + const manifest = loadManifest(); + + if (!fs.existsSync(tsDir)) { + console.log(" No TypeScript files to validate"); + return results; + } + + // Create a temporary tsconfig for validation + const tsconfig = { + compilerOptions: { + target: "ES2022", + module: "NodeNext", + moduleResolution: "NodeNext", + strict: true, + skipLibCheck: true, + noEmit: true, + esModuleInterop: true, + allowSyntheticDefaultImports: true, + resolveJsonModule: true, + types: ["node"], + paths: { + "@github/copilot-sdk": [path.join(ROOT_DIR, "nodejs/src/index.ts")], + }, + }, + include: ["./**/*.ts"], + }; + + const tsconfigPath = path.join(tsDir, "tsconfig.json"); + fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2)); + + try { + // Run tsc + const tscPath = path.join(ROOT_DIR, "nodejs/node_modules/.bin/tsc"); + execSync(`${tscPath} --project ${tsconfigPath} 2>&1`, { + encoding: "utf-8", + cwd: tsDir, + }); + + // All files passed + const files = await glob("*.ts", { cwd: tsDir }); + for (const file of files) { + if (file === "tsconfig.json") continue; + const block = manifest.blocks.find( + (b) => b.outputFile === `typescript/${file}` + ); + results.push({ + file: `typescript/${file}`, + sourceFile: block?.sourceFile || "unknown", + sourceLine: block?.sourceLine || 0, + success: true, + errors: [], + }); + } + } catch (err: any) { + // Parse tsc output for errors + const output = err.stdout || err.message || ""; + const errorLines = output.split("\n"); + + // Group errors by file + const fileErrors = new Map(); + let currentFile = ""; + + for (const line of errorLines) { + const match = line.match(/^(.+\.ts)\((\d+),(\d+)\): error/); + if (match) { + currentFile = match[1]; + if (!fileErrors.has(currentFile)) { + fileErrors.set(currentFile, []); + } + fileErrors.get(currentFile)!.push(line); + } else if (currentFile && line.trim()) { + fileErrors.get(currentFile)?.push(line); + } + } + + // Create results + const files = await glob("*.ts", { cwd: tsDir }); + for (const file of files) { + if (file === "tsconfig.json") continue; + const fullPath = path.join(tsDir, file); + const block = manifest.blocks.find( + (b) => b.outputFile === `typescript/${file}` + ); + const errors = fileErrors.get(fullPath) || fileErrors.get(file) || []; + + results.push({ + file: `typescript/${file}`, + sourceFile: block?.sourceFile || "unknown", + sourceLine: block?.sourceLine || 0, + success: errors.length === 0, + errors, + }); + } + } + + return results; +} + +async function validatePython(): Promise { + const results: ValidationResult[] = []; + const pyDir = path.join(VALIDATION_DIR, "python"); + const manifest = loadManifest(); + + if (!fs.existsSync(pyDir)) { + console.log(" No Python files to validate"); + return results; + } + + const files = await glob("*.py", { cwd: pyDir }); + + for (const file of files) { + const fullPath = path.join(pyDir, file); + const block = manifest.blocks.find( + (b) => b.outputFile === `python/${file}` + ); + const errors: string[] = []; + + // Syntax check with py_compile + try { + execSync(`python3 -m py_compile "${fullPath}" 2>&1`, { + encoding: "utf-8", + }); + } catch (err: any) { + errors.push(err.stdout || err.message || "Syntax error"); + } + + // Type check with mypy (if available) + if (errors.length === 0) { + try { + execSync( + `python3 -m mypy "${fullPath}" --ignore-missing-imports --no-error-summary 2>&1`, + { encoding: "utf-8" } + ); + } catch (err: any) { + const output = err.stdout || err.message || ""; + // Filter out "Success" messages and notes + const typeErrors = output + .split("\n") + .filter( + (l: string) => + l.includes(": error:") && + !l.includes("Cannot find implementation") + ); + if (typeErrors.length > 0) { + errors.push(...typeErrors); + } + } + } + + results.push({ + file: `python/${file}`, + sourceFile: block?.sourceFile || "unknown", + sourceLine: block?.sourceLine || 0, + success: errors.length === 0, + errors, + }); + } + + return results; +} + +async function validateGo(): Promise { + const results: ValidationResult[] = []; + const goDir = path.join(VALIDATION_DIR, "go"); + const manifest = loadManifest(); + + if (!fs.existsSync(goDir)) { + console.log(" No Go files to validate"); + return results; + } + + // Create a go.mod for the validation directory + const goMod = `module docs-validation + +go 1.21 + +require github.com/github/copilot-sdk/go v0.0.0 + +replace github.com/github/copilot-sdk/go => ${path.join(ROOT_DIR, "go")} +`; + fs.writeFileSync(path.join(goDir, "go.mod"), goMod); + + // Run go mod tidy to fetch dependencies + try { + execSync(`go mod tidy 2>&1`, { + encoding: "utf-8", + cwd: goDir, + env: { ...process.env, GO111MODULE: "on" }, + }); + } catch (err: any) { + // go mod tidy might fail if there are syntax errors, continue anyway + } + + const files = await glob("*.go", { cwd: goDir }); + + // Try to compile each file individually + for (const file of files) { + const fullPath = path.join(goDir, file); + const block = manifest.blocks.find((b) => b.outputFile === `go/${file}`); + const errors: string[] = []; + + try { + // Use go vet for syntax and basic checks + execSync(`go build -o /dev/null "${fullPath}" 2>&1`, { + encoding: "utf-8", + cwd: goDir, + env: { ...process.env, GO111MODULE: "on" }, + }); + } catch (err: any) { + const output = err.stdout || err.stderr || err.message || ""; + errors.push( + ...output.split("\n").filter((l: string) => l.trim() && !l.startsWith("#")) + ); + } + + results.push({ + file: `go/${file}`, + sourceFile: block?.sourceFile || "unknown", + sourceLine: block?.sourceLine || 0, + success: errors.length === 0, + errors, + }); + } + + return results; +} + +async function validateCSharp(): Promise { + const results: ValidationResult[] = []; + const csDir = path.join(VALIDATION_DIR, "csharp"); + const manifest = loadManifest(); + + if (!fs.existsSync(csDir)) { + console.log(" No C# files to validate"); + return results; + } + + // Create a minimal csproj for validation + const csproj = ` + + Library + net8.0 + enable + enable + CS8019;CS0168;CS0219 + + + + +`; + + fs.writeFileSync(path.join(csDir, "DocsValidation.csproj"), csproj); + + const files = await glob("*.cs", { cwd: csDir }); + + // Compile all files together + try { + execSync(`dotnet build "${path.join(csDir, "DocsValidation.csproj")}" 2>&1`, { + encoding: "utf-8", + cwd: csDir, + }); + + // All files passed + for (const file of files) { + const block = manifest.blocks.find( + (b) => b.outputFile === `csharp/${file}` + ); + results.push({ + file: `csharp/${file}`, + sourceFile: block?.sourceFile || "unknown", + sourceLine: block?.sourceLine || 0, + success: true, + errors: [], + }); + } + } catch (err: any) { + const output = err.stdout || err.stderr || err.message || ""; + + // Parse errors by file + const fileErrors = new Map(); + + for (const line of output.split("\n")) { + const match = line.match(/([^/\\]+\.cs)\((\d+),(\d+)\): error/); + if (match) { + const fileName = match[1]; + if (!fileErrors.has(fileName)) { + fileErrors.set(fileName, []); + } + fileErrors.get(fileName)!.push(line); + } + } + + for (const file of files) { + const block = manifest.blocks.find( + (b) => b.outputFile === `csharp/${file}` + ); + const errors = fileErrors.get(file) || []; + + results.push({ + file: `csharp/${file}`, + sourceFile: block?.sourceFile || "unknown", + sourceLine: block?.sourceLine || 0, + success: errors.length === 0, + errors, + }); + } + } + + return results; +} + +function printResults(results: ValidationResult[], language: string): number { + const failed = results.filter((r) => !r.success); + const passed = results.filter((r) => r.success); + + if (failed.length === 0) { + console.log(` ✅ ${passed.length} files passed`); + return 0; + } + + console.log(` ❌ ${failed.length} failed, ${passed.length} passed\n`); + + for (const result of failed) { + console.log(` ┌─ ${result.sourceFile}:${result.sourceLine}`); + console.log(` │ Extracted to: ${result.file}`); + for (const error of result.errors.slice(0, 5)) { + console.log(` │ ${error}`); + } + if (result.errors.length > 5) { + console.log(` │ ... and ${result.errors.length - 5} more errors`); + } + console.log(` └─`); + } + + return failed.length; +} + +async function main() { + const args = process.argv.slice(2); + const langArg = args.find((a) => a.startsWith("--lang=")); + const targetLang = langArg?.split("=")[1]; + + console.log("🔍 Validating documentation code blocks...\n"); + + if (!fs.existsSync(VALIDATION_DIR)) { + console.error("❌ No extracted code found. Run extraction first:"); + console.error(" npm run extract"); + process.exit(1); + } + + let totalFailed = 0; + + const validators: [string, () => Promise][] = [ + ["TypeScript", validateTypeScript], + ["Python", validatePython], + ["Go", validateGo], + ["C#", validateCSharp], + ]; + + for (const [name, validator] of validators) { + const langKey = name.toLowerCase().replace("#", "sharp"); + if (targetLang && langKey !== targetLang) continue; + + console.log(`\n${name}:`); + const results = await validator(); + totalFailed += printResults(results, name); + } + + console.log("\n" + "─".repeat(40)); + + if (totalFailed > 0) { + console.log(`\n❌ Validation failed: ${totalFailed} file(s) have errors`); + console.log("\nTo fix:"); + console.log(" 1. Check the error messages above"); + console.log(" 2. Update the code blocks in the markdown files"); + console.log(" 3. Re-run: npm run validate"); + console.log("\nTo skip a code block, add before it:"); + console.log(" "); + process.exit(1); + } + + console.log("\n✅ All documentation code blocks are valid!"); +} + +main().catch((err) => { + console.error("Validation failed:", err); + process.exit(1); +}); From 7eed004ed868529a8ba561c5ee6f2b7a6017464e Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 21:53:07 -0800 Subject: [PATCH 06/14] Simplify docs validation workflow - Remove separate extract job and artifact upload/download - Each language job now extracts and validates independently - Jobs run in parallel without dependencies - Remove docs/.gitignore (no longer needed) --- .github/workflows/docs-validation.yml | 95 +- docs/.gitignore | 2 - docs/.validation/csharp/DocsValidation.csproj | 12 + docs/.validation/csharp/byok_29.cs | 21 + docs/.validation/csharp/debugging_10.cs | 9 + docs/.validation/csharp/debugging_6.cs | 16 + docs/.validation/csharp/debugging_7.cs | 5 + docs/.validation/csharp/debugging_9.cs | 20 + docs/.validation/csharp/error-handling_20.cs | 4 + docs/.validation/csharp/error-handling_21.cs | 14 + docs/.validation/csharp/getting-started_0.cs | 8 + docs/.validation/csharp/getting-started_1.cs | 24 + docs/.validation/csharp/getting-started_2.cs | 20 + docs/.validation/csharp/getting-started_3.cs | 44 + docs/.validation/csharp/getting-started_4.cs | 55 + docs/.validation/csharp/getting-started_5.cs | 12 + docs/.validation/csharp/index_26.cs | 5 + docs/.validation/csharp/index_27.cs | 8 + docs/.validation/csharp/index_28.cs | 5 + docs/.validation/csharp/overview_19.cs | 29 + docs/.validation/csharp/overview_8.cs | 18 + docs/.validation/csharp/post-tool-use_17.cs | 4 + docs/.validation/csharp/post-tool-use_18.cs | 14 + docs/.validation/csharp/pre-tool-use_15.cs | 4 + docs/.validation/csharp/pre-tool-use_16.cs | 15 + .../csharp/session-lifecycle_13.cs | 4 + .../csharp/session-lifecycle_14.cs | 4 + .../csharp/session-persistence_24.cs | 16 + .../csharp/session-persistence_25.cs | 6 + docs/.validation/csharp/skills_22.cs | 20 + docs/.validation/csharp/skills_23.cs | 6 + .../csharp/user-prompt-submitted_11.cs | 4 + .../csharp/user-prompt-submitted_12.cs | 12 + docs/.validation/go/byok_7.go | 40 + docs/.validation/go/getting-started_0.go | 33 + docs/.validation/go/getting-started_1.go | 44 + docs/.validation/go/getting-started_2.go | 77 ++ docs/.validation/go/getting-started_3.go | 95 ++ docs/.validation/go/go.mod | 9 + docs/.validation/go/go.sum | 4 + docs/.validation/go/overview_4.go | 36 + docs/.validation/go/overview_5.go | 33 + docs/.validation/go/skills_6.go | 37 + docs/.validation/manifest.json | 1104 +++++++++++++++++ .../__pycache__/byok_31.cpython-314.pyc | Bin 0 -> 2044 bytes .../__pycache__/debugging_6.cpython-314.pyc | Bin 0 -> 282 bytes .../__pycache__/debugging_7.cpython-314.pyc | Bin 0 -> 173 bytes .../error-handling_20.cpython-314.pyc | Bin 0 -> 376 bytes .../error-handling_21.cpython-314.pyc | Bin 0 -> 1042 bytes .../getting-started_0.cpython-314.pyc | Bin 0 -> 1047 bytes .../getting-started_1.cpython-314.pyc | Bin 0 -> 1753 bytes .../getting-started_2.cpython-314.pyc | Bin 0 -> 1005 bytes .../getting-started_3.cpython-314.pyc | Bin 0 -> 3303 bytes .../getting-started_4.cpython-314.pyc | Bin 0 -> 3707 bytes .../getting-started_5.cpython-314.pyc | Bin 0 -> 717 bytes .../__pycache__/index_27.cpython-314.pyc | Bin 0 -> 537 bytes .../__pycache__/index_28.cpython-314.pyc | Bin 0 -> 628 bytes .../__pycache__/index_29.cpython-314.pyc | Bin 0 -> 537 bytes .../__pycache__/index_30.cpython-314.pyc | Bin 0 -> 251 bytes .../__pycache__/overview_19.cpython-314.pyc | Bin 0 -> 1698 bytes .../__pycache__/overview_8.cpython-314.pyc | Bin 0 -> 1492 bytes .../post-tool-use_17.cpython-314.pyc | Bin 0 -> 369 bytes .../post-tool-use_18.cpython-314.pyc | Bin 0 -> 1028 bytes .../pre-tool-use_15.cpython-314.pyc | Bin 0 -> 365 bytes .../pre-tool-use_16.cpython-314.pyc | Bin 0 -> 975 bytes .../session-lifecycle_11.cpython-314.pyc | Bin 0 -> 376 bytes .../session-lifecycle_12.cpython-314.pyc | Bin 0 -> 1326 bytes .../session-lifecycle_13.cpython-314.pyc | Bin 0 -> 370 bytes .../session-lifecycle_14.cpython-314.pyc | Bin 0 -> 1494 bytes .../session-persistence_24.cpython-314.pyc | Bin 0 -> 915 bytes .../session-persistence_25.cpython-314.pyc | Bin 0 -> 690 bytes .../session-persistence_26.cpython-314.pyc | Bin 0 -> 744 bytes .../__pycache__/skills_22.cpython-314.pyc | Bin 0 -> 977 bytes .../__pycache__/skills_23.cpython-314.pyc | Bin 0 -> 620 bytes .../user-prompt-submitted_10.cpython-314.pyc | Bin 0 -> 878 bytes .../user-prompt-submitted_9.cpython-314.pyc | Bin 0 -> 400 bytes docs/.validation/python/byok_31.py | 38 + docs/.validation/python/debugging_6.py | 4 + docs/.validation/python/debugging_7.py | 4 + docs/.validation/python/error-handling_20.py | 5 + docs/.validation/python/error-handling_21.py | 15 + docs/.validation/python/getting-started_0.py | 16 + docs/.validation/python/getting-started_1.py | 30 + docs/.validation/python/getting-started_2.py | 15 + docs/.validation/python/getting-started_3.py | 49 + docs/.validation/python/getting-started_4.py | 56 + docs/.validation/python/getting-started_5.py | 16 + docs/.validation/python/index_27.py | 11 + docs/.validation/python/index_28.py | 13 + docs/.validation/python/index_29.py | 11 + docs/.validation/python/index_30.py | 4 + docs/.validation/python/overview_19.py | 30 + docs/.validation/python/overview_8.py | 39 + docs/.validation/python/post-tool-use_17.py | 5 + docs/.validation/python/post-tool-use_18.py | 15 + docs/.validation/python/pre-tool-use_15.py | 5 + docs/.validation/python/pre-tool-use_16.py | 14 + .../python/session-lifecycle_11.py | 5 + .../python/session-lifecycle_12.py | 22 + .../python/session-lifecycle_13.py | 5 + .../python/session-lifecycle_14.py | 31 + .../python/session-persistence_24.py | 21 + .../python/session-persistence_25.py | 11 + .../python/session-persistence_26.py | 9 + docs/.validation/python/skills_22.py | 20 + docs/.validation/python/skills_23.py | 10 + .../python/user-prompt-submitted_10.py | 13 + .../python/user-prompt-submitted_9.py | 5 + docs/.validation/typescript/byok_85.ts | 22 + docs/.validation/typescript/byok_86.ts | 11 + .../typescript/compatibility_15.ts | 13 + .../typescript/compatibility_16.ts | 7 + .../typescript/compatibility_17.ts | 8 + docs/.validation/typescript/debugging_10.ts | 4 + docs/.validation/typescript/debugging_11.ts | 4 + docs/.validation/typescript/debugging_12.ts | 5 + docs/.validation/typescript/debugging_13.ts | 4 + docs/.validation/typescript/debugging_14.ts | 8 + docs/.validation/typescript/debugging_9.ts | 6 + .../typescript/error-handling_57.ts | 5 + .../typescript/error-handling_58.ts | 11 + .../typescript/error-handling_59.ts | 22 + .../typescript/error-handling_60.ts | 23 + .../typescript/error-handling_61.ts | 13 + .../typescript/error-handling_62.ts | 27 + .../typescript/error-handling_63.ts | 35 + .../typescript/error-handling_64.ts | 20 + .../typescript/error-handling_65.ts | 36 + .../typescript/getting-started_0.ts | 11 + .../typescript/getting-started_1.ts | 21 + .../typescript/getting-started_2.ts | 14 + .../typescript/getting-started_3.ts | 44 + .../typescript/getting-started_4.ts | 56 + .../typescript/getting-started_5.ts | 9 + .../typescript/getting-started_6.ts | 9 + .../typescript/getting-started_7.ts | 6 + .../typescript/getting-started_8.ts | 10 + docs/.validation/typescript/index_81.ts | 5 + docs/.validation/typescript/index_82.ts | 7 + docs/.validation/typescript/index_83.ts | 5 + docs/.validation/typescript/index_84.ts | 4 + docs/.validation/typescript/overview_18.ts | 26 + docs/.validation/typescript/overview_19.ts | 32 + docs/.validation/typescript/overview_53.ts | 21 + docs/.validation/typescript/overview_54.ts | 13 + docs/.validation/typescript/overview_55.ts | 16 + docs/.validation/typescript/overview_56.ts | 11 + .../typescript/post-tool-use_45.ts | 5 + .../typescript/post-tool-use_46.ts | 11 + .../typescript/post-tool-use_47.ts | 24 + .../typescript/post-tool-use_48.ts | 22 + .../typescript/post-tool-use_49.ts | 22 + .../typescript/post-tool-use_50.ts | 18 + .../typescript/post-tool-use_51.ts | 31 + .../typescript/post-tool-use_52.ts | 23 + .../.validation/typescript/pre-tool-use_38.ts | 5 + .../.validation/typescript/pre-tool-use_39.ts | 10 + .../.validation/typescript/pre-tool-use_40.ts | 16 + .../.validation/typescript/pre-tool-use_41.ts | 19 + .../.validation/typescript/pre-tool-use_42.ts | 23 + .../.validation/typescript/pre-tool-use_43.ts | 13 + .../.validation/typescript/pre-tool-use_44.ts | 14 + .../typescript/session-lifecycle_29.ts | 5 + .../typescript/session-lifecycle_30.ts | 18 + .../typescript/session-lifecycle_31.ts | 20 + .../typescript/session-lifecycle_32.ts | 24 + .../typescript/session-lifecycle_33.ts | 5 + .../typescript/session-lifecycle_34.ts | 24 + .../typescript/session-lifecycle_35.ts | 25 + .../typescript/session-lifecycle_36.ts | 16 + .../typescript/session-lifecycle_37.ts | 37 + .../typescript/session-persistence_70.ts | 16 + .../typescript/session-persistence_71.ts | 6 + .../typescript/session-persistence_72.ts | 22 + .../typescript/session-persistence_73.ts | 8 + .../typescript/session-persistence_74.ts | 7 + .../typescript/session-persistence_75.ts | 16 + .../typescript/session-persistence_76.ts | 12 + .../typescript/session-persistence_77.ts | 4 + .../typescript/session-persistence_78.ts | 16 + .../typescript/session-persistence_79.ts | 9 + .../typescript/session-persistence_80.ts | 29 + docs/.validation/typescript/skills_66.ts | 15 + docs/.validation/typescript/skills_67.ts | 5 + docs/.validation/typescript/skills_68.ts | 9 + docs/.validation/typescript/skills_69.ts | 12 + docs/.validation/typescript/tsconfig.json | 24 + .../typescript/user-prompt-submitted_20.ts | 5 + .../typescript/user-prompt-submitted_21.ts | 9 + .../typescript/user-prompt-submitted_22.ts | 16 + .../typescript/user-prompt-submitted_23.ts | 23 + .../typescript/user-prompt-submitted_24.ts | 23 + .../typescript/user-prompt-submitted_25.ts | 17 + .../typescript/user-prompt-submitted_26.ts | 30 + .../typescript/user-prompt-submitted_27.ts | 27 + .../typescript/user-prompt-submitted_28.ts | 32 + 196 files changed, 3943 insertions(+), 77 deletions(-) delete mode 100644 docs/.gitignore create mode 100644 docs/.validation/csharp/DocsValidation.csproj create mode 100644 docs/.validation/csharp/byok_29.cs create mode 100644 docs/.validation/csharp/debugging_10.cs create mode 100644 docs/.validation/csharp/debugging_6.cs create mode 100644 docs/.validation/csharp/debugging_7.cs create mode 100644 docs/.validation/csharp/debugging_9.cs create mode 100644 docs/.validation/csharp/error-handling_20.cs create mode 100644 docs/.validation/csharp/error-handling_21.cs create mode 100644 docs/.validation/csharp/getting-started_0.cs create mode 100644 docs/.validation/csharp/getting-started_1.cs create mode 100644 docs/.validation/csharp/getting-started_2.cs create mode 100644 docs/.validation/csharp/getting-started_3.cs create mode 100644 docs/.validation/csharp/getting-started_4.cs create mode 100644 docs/.validation/csharp/getting-started_5.cs create mode 100644 docs/.validation/csharp/index_26.cs create mode 100644 docs/.validation/csharp/index_27.cs create mode 100644 docs/.validation/csharp/index_28.cs create mode 100644 docs/.validation/csharp/overview_19.cs create mode 100644 docs/.validation/csharp/overview_8.cs create mode 100644 docs/.validation/csharp/post-tool-use_17.cs create mode 100644 docs/.validation/csharp/post-tool-use_18.cs create mode 100644 docs/.validation/csharp/pre-tool-use_15.cs create mode 100644 docs/.validation/csharp/pre-tool-use_16.cs create mode 100644 docs/.validation/csharp/session-lifecycle_13.cs create mode 100644 docs/.validation/csharp/session-lifecycle_14.cs create mode 100644 docs/.validation/csharp/session-persistence_24.cs create mode 100644 docs/.validation/csharp/session-persistence_25.cs create mode 100644 docs/.validation/csharp/skills_22.cs create mode 100644 docs/.validation/csharp/skills_23.cs create mode 100644 docs/.validation/csharp/user-prompt-submitted_11.cs create mode 100644 docs/.validation/csharp/user-prompt-submitted_12.cs create mode 100644 docs/.validation/go/byok_7.go create mode 100644 docs/.validation/go/getting-started_0.go create mode 100644 docs/.validation/go/getting-started_1.go create mode 100644 docs/.validation/go/getting-started_2.go create mode 100644 docs/.validation/go/getting-started_3.go create mode 100644 docs/.validation/go/go.mod create mode 100644 docs/.validation/go/go.sum create mode 100644 docs/.validation/go/overview_4.go create mode 100644 docs/.validation/go/overview_5.go create mode 100644 docs/.validation/go/skills_6.go create mode 100644 docs/.validation/manifest.json create mode 100644 docs/.validation/python/__pycache__/byok_31.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/debugging_6.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/debugging_7.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/error-handling_20.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/error-handling_21.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/getting-started_0.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/getting-started_1.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/getting-started_2.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/getting-started_3.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/getting-started_4.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/getting-started_5.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/index_27.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/index_28.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/index_29.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/index_30.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/overview_19.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/overview_8.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/post-tool-use_17.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/post-tool-use_18.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/pre-tool-use_15.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/pre-tool-use_16.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/session-lifecycle_11.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/session-lifecycle_12.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/session-lifecycle_13.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/session-lifecycle_14.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/session-persistence_24.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/session-persistence_25.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/session-persistence_26.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/skills_22.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/skills_23.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/user-prompt-submitted_10.cpython-314.pyc create mode 100644 docs/.validation/python/__pycache__/user-prompt-submitted_9.cpython-314.pyc create mode 100644 docs/.validation/python/byok_31.py create mode 100644 docs/.validation/python/debugging_6.py create mode 100644 docs/.validation/python/debugging_7.py create mode 100644 docs/.validation/python/error-handling_20.py create mode 100644 docs/.validation/python/error-handling_21.py create mode 100644 docs/.validation/python/getting-started_0.py create mode 100644 docs/.validation/python/getting-started_1.py create mode 100644 docs/.validation/python/getting-started_2.py create mode 100644 docs/.validation/python/getting-started_3.py create mode 100644 docs/.validation/python/getting-started_4.py create mode 100644 docs/.validation/python/getting-started_5.py create mode 100644 docs/.validation/python/index_27.py create mode 100644 docs/.validation/python/index_28.py create mode 100644 docs/.validation/python/index_29.py create mode 100644 docs/.validation/python/index_30.py create mode 100644 docs/.validation/python/overview_19.py create mode 100644 docs/.validation/python/overview_8.py create mode 100644 docs/.validation/python/post-tool-use_17.py create mode 100644 docs/.validation/python/post-tool-use_18.py create mode 100644 docs/.validation/python/pre-tool-use_15.py create mode 100644 docs/.validation/python/pre-tool-use_16.py create mode 100644 docs/.validation/python/session-lifecycle_11.py create mode 100644 docs/.validation/python/session-lifecycle_12.py create mode 100644 docs/.validation/python/session-lifecycle_13.py create mode 100644 docs/.validation/python/session-lifecycle_14.py create mode 100644 docs/.validation/python/session-persistence_24.py create mode 100644 docs/.validation/python/session-persistence_25.py create mode 100644 docs/.validation/python/session-persistence_26.py create mode 100644 docs/.validation/python/skills_22.py create mode 100644 docs/.validation/python/skills_23.py create mode 100644 docs/.validation/python/user-prompt-submitted_10.py create mode 100644 docs/.validation/python/user-prompt-submitted_9.py create mode 100644 docs/.validation/typescript/byok_85.ts create mode 100644 docs/.validation/typescript/byok_86.ts create mode 100644 docs/.validation/typescript/compatibility_15.ts create mode 100644 docs/.validation/typescript/compatibility_16.ts create mode 100644 docs/.validation/typescript/compatibility_17.ts create mode 100644 docs/.validation/typescript/debugging_10.ts create mode 100644 docs/.validation/typescript/debugging_11.ts create mode 100644 docs/.validation/typescript/debugging_12.ts create mode 100644 docs/.validation/typescript/debugging_13.ts create mode 100644 docs/.validation/typescript/debugging_14.ts create mode 100644 docs/.validation/typescript/debugging_9.ts create mode 100644 docs/.validation/typescript/error-handling_57.ts create mode 100644 docs/.validation/typescript/error-handling_58.ts create mode 100644 docs/.validation/typescript/error-handling_59.ts create mode 100644 docs/.validation/typescript/error-handling_60.ts create mode 100644 docs/.validation/typescript/error-handling_61.ts create mode 100644 docs/.validation/typescript/error-handling_62.ts create mode 100644 docs/.validation/typescript/error-handling_63.ts create mode 100644 docs/.validation/typescript/error-handling_64.ts create mode 100644 docs/.validation/typescript/error-handling_65.ts create mode 100644 docs/.validation/typescript/getting-started_0.ts create mode 100644 docs/.validation/typescript/getting-started_1.ts create mode 100644 docs/.validation/typescript/getting-started_2.ts create mode 100644 docs/.validation/typescript/getting-started_3.ts create mode 100644 docs/.validation/typescript/getting-started_4.ts create mode 100644 docs/.validation/typescript/getting-started_5.ts create mode 100644 docs/.validation/typescript/getting-started_6.ts create mode 100644 docs/.validation/typescript/getting-started_7.ts create mode 100644 docs/.validation/typescript/getting-started_8.ts create mode 100644 docs/.validation/typescript/index_81.ts create mode 100644 docs/.validation/typescript/index_82.ts create mode 100644 docs/.validation/typescript/index_83.ts create mode 100644 docs/.validation/typescript/index_84.ts create mode 100644 docs/.validation/typescript/overview_18.ts create mode 100644 docs/.validation/typescript/overview_19.ts create mode 100644 docs/.validation/typescript/overview_53.ts create mode 100644 docs/.validation/typescript/overview_54.ts create mode 100644 docs/.validation/typescript/overview_55.ts create mode 100644 docs/.validation/typescript/overview_56.ts create mode 100644 docs/.validation/typescript/post-tool-use_45.ts create mode 100644 docs/.validation/typescript/post-tool-use_46.ts create mode 100644 docs/.validation/typescript/post-tool-use_47.ts create mode 100644 docs/.validation/typescript/post-tool-use_48.ts create mode 100644 docs/.validation/typescript/post-tool-use_49.ts create mode 100644 docs/.validation/typescript/post-tool-use_50.ts create mode 100644 docs/.validation/typescript/post-tool-use_51.ts create mode 100644 docs/.validation/typescript/post-tool-use_52.ts create mode 100644 docs/.validation/typescript/pre-tool-use_38.ts create mode 100644 docs/.validation/typescript/pre-tool-use_39.ts create mode 100644 docs/.validation/typescript/pre-tool-use_40.ts create mode 100644 docs/.validation/typescript/pre-tool-use_41.ts create mode 100644 docs/.validation/typescript/pre-tool-use_42.ts create mode 100644 docs/.validation/typescript/pre-tool-use_43.ts create mode 100644 docs/.validation/typescript/pre-tool-use_44.ts create mode 100644 docs/.validation/typescript/session-lifecycle_29.ts create mode 100644 docs/.validation/typescript/session-lifecycle_30.ts create mode 100644 docs/.validation/typescript/session-lifecycle_31.ts create mode 100644 docs/.validation/typescript/session-lifecycle_32.ts create mode 100644 docs/.validation/typescript/session-lifecycle_33.ts create mode 100644 docs/.validation/typescript/session-lifecycle_34.ts create mode 100644 docs/.validation/typescript/session-lifecycle_35.ts create mode 100644 docs/.validation/typescript/session-lifecycle_36.ts create mode 100644 docs/.validation/typescript/session-lifecycle_37.ts create mode 100644 docs/.validation/typescript/session-persistence_70.ts create mode 100644 docs/.validation/typescript/session-persistence_71.ts create mode 100644 docs/.validation/typescript/session-persistence_72.ts create mode 100644 docs/.validation/typescript/session-persistence_73.ts create mode 100644 docs/.validation/typescript/session-persistence_74.ts create mode 100644 docs/.validation/typescript/session-persistence_75.ts create mode 100644 docs/.validation/typescript/session-persistence_76.ts create mode 100644 docs/.validation/typescript/session-persistence_77.ts create mode 100644 docs/.validation/typescript/session-persistence_78.ts create mode 100644 docs/.validation/typescript/session-persistence_79.ts create mode 100644 docs/.validation/typescript/session-persistence_80.ts create mode 100644 docs/.validation/typescript/skills_66.ts create mode 100644 docs/.validation/typescript/skills_67.ts create mode 100644 docs/.validation/typescript/skills_68.ts create mode 100644 docs/.validation/typescript/skills_69.ts create mode 100644 docs/.validation/typescript/tsconfig.json create mode 100644 docs/.validation/typescript/user-prompt-submitted_20.ts create mode 100644 docs/.validation/typescript/user-prompt-submitted_21.ts create mode 100644 docs/.validation/typescript/user-prompt-submitted_22.ts create mode 100644 docs/.validation/typescript/user-prompt-submitted_23.ts create mode 100644 docs/.validation/typescript/user-prompt-submitted_24.ts create mode 100644 docs/.validation/typescript/user-prompt-submitted_25.ts create mode 100644 docs/.validation/typescript/user-prompt-submitted_26.ts create mode 100644 docs/.validation/typescript/user-prompt-submitted_27.ts create mode 100644 docs/.validation/typescript/user-prompt-submitted_28.ts diff --git a/.github/workflows/docs-validation.yml b/.github/workflows/docs-validation.yml index 814e1456..210a7dd7 100644 --- a/.github/workflows/docs-validation.yml +++ b/.github/workflows/docs-validation.yml @@ -17,36 +17,8 @@ permissions: contents: read jobs: - extract: - name: "Extract Code Blocks" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: "npm" - cache-dependency-path: "scripts/docs-validation/package-lock.json" - - - name: Install extraction dependencies - working-directory: scripts/docs-validation - run: npm ci - - - name: Extract code blocks - working-directory: scripts/docs-validation - run: npm run extract - - - name: Upload extracted code - uses: actions/upload-artifact@v4 - with: - name: extracted-code - path: docs/.validation/ - retention-days: 1 - validate-typescript: name: "Validate TypeScript" - needs: extract runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -65,23 +37,20 @@ jobs: working-directory: scripts/docs-validation run: npm ci - - name: Download extracted code - uses: actions/download-artifact@v4 - with: - name: extracted-code - path: docs/.validation/ - - - name: Validate TypeScript + - name: Extract and validate TypeScript working-directory: scripts/docs-validation - run: npm run validate:ts + run: npm run extract && npm run validate:ts validate-python: name: "Validate Python" - needs: extract runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - uses: actions/setup-python@v5 with: python-version: "3.12" @@ -100,79 +69,55 @@ jobs: working-directory: scripts/docs-validation run: npm ci - - uses: actions/setup-node@v4 - with: - node-version: 22 - - - name: Download extracted code - uses: actions/download-artifact@v4 - with: - name: extracted-code - path: docs/.validation/ - - - name: Validate Python + - name: Extract and validate Python working-directory: scripts/docs-validation - run: npm run validate:py + run: npm run extract && npm run validate:py validate-go: name: "Validate Go" - needs: extract runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - uses: actions/setup-go@v5 with: go-version: "1.23" cache-dependency-path: "go/go.sum" - - uses: actions/setup-node@v4 - with: - node-version: 22 - - name: Install validation dependencies working-directory: scripts/docs-validation run: npm ci - - name: Download extracted code - uses: actions/download-artifact@v4 - with: - name: extracted-code - path: docs/.validation/ - - - name: Validate Go + - name: Extract and validate Go working-directory: scripts/docs-validation - run: npm run validate:go + run: npm run extract && npm run validate:go validate-csharp: name: "Validate C#" - needs: extract runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v4 - with: - dotnet-version: "8.0.x" - - uses: actions/setup-node@v4 with: node-version: 22 + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: "8.0.x" + - name: Install validation dependencies working-directory: scripts/docs-validation run: npm ci - - name: Download extracted code - uses: actions/download-artifact@v4 - with: - name: extracted-code - path: docs/.validation/ - - name: Restore SDK dependencies working-directory: dotnet run: dotnet restore - - name: Validate C# + - name: Extract and validate C# working-directory: scripts/docs-validation - run: npm run validate:cs + run: npm run extract && npm run validate:cs diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 2d253c5a..00000000 --- a/docs/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Extracted code for validation (generated) -.validation/ diff --git a/docs/.validation/csharp/DocsValidation.csproj b/docs/.validation/csharp/DocsValidation.csproj new file mode 100644 index 00000000..026e7b55 --- /dev/null +++ b/docs/.validation/csharp/DocsValidation.csproj @@ -0,0 +1,12 @@ + + + Library + net8.0 + enable + enable + CS8019;CS0168;CS0219 + + + + + \ No newline at end of file diff --git a/docs/.validation/csharp/byok_29.cs b/docs/.validation/csharp/byok_29.cs new file mode 100644 index 00000000..f0cd4022 --- /dev/null +++ b/docs/.validation/csharp/byok_29.cs @@ -0,0 +1,21 @@ +// Source: auth/byok.md:143 +using GitHub.Copilot.SDK; + +await using var client = new CopilotClient(); +await using var session = await client.CreateSessionAsync(new SessionConfig +{ + Model = "gpt-5.2-codex", // Your deployment name + Provider = new ProviderConfig + { + Type = "openai", + BaseUrl = "https://your-resource.openai.azure.com/openai/v1/", + WireApi = "responses", // Use "completions" for older models + ApiKey = Environment.GetEnvironmentVariable("FOUNDRY_API_KEY"), + }, +}); + +var response = await session.SendAndWaitAsync(new MessageOptions +{ + Prompt = "What is 2+2?", +}); +Console.WriteLine(response?.Data.Content); \ No newline at end of file diff --git a/docs/.validation/csharp/debugging_10.cs b/docs/.validation/csharp/debugging_10.cs new file mode 100644 index 00000000..8052fc64 --- /dev/null +++ b/docs/.validation/csharp/debugging_10.cs @@ -0,0 +1,9 @@ +// Source: mcp/debugging.md:269 +// Windows needs cmd /c for npx +["filesystem"] = new McpLocalServerConfig +{ + Type = "local", + Command = "cmd", + Args = new List { "/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "C:\\allowed\\path" }, + Tools = new List { "*" }, +} \ No newline at end of file diff --git a/docs/.validation/csharp/debugging_6.cs b/docs/.validation/csharp/debugging_6.cs new file mode 100644 index 00000000..c9d5ad2a --- /dev/null +++ b/docs/.validation/csharp/debugging_6.cs @@ -0,0 +1,16 @@ +// Source: debugging.md:61 +using GitHub.Copilot.SDK; +using Microsoft.Extensions.Logging; + +// Using ILogger +var loggerFactory = LoggerFactory.Create(builder => +{ + builder.SetMinimumLevel(LogLevel.Debug); + builder.AddConsole(); +}); + +var client = new CopilotClient(new CopilotClientOptions +{ + LogLevel = "debug", + Logger = loggerFactory.CreateLogger() +}); \ No newline at end of file diff --git a/docs/.validation/csharp/debugging_7.cs b/docs/.validation/csharp/debugging_7.cs new file mode 100644 index 00000000..ecc7c654 --- /dev/null +++ b/docs/.validation/csharp/debugging_7.cs @@ -0,0 +1,5 @@ +// Source: debugging.md:124 +var client = new CopilotClient(new CopilotClientOptions +{ + CliArgs = new[] { "--log-dir", "/path/to/logs" } +}); \ No newline at end of file diff --git a/docs/.validation/csharp/debugging_9.cs b/docs/.validation/csharp/debugging_9.cs new file mode 100644 index 00000000..03063bf6 --- /dev/null +++ b/docs/.validation/csharp/debugging_9.cs @@ -0,0 +1,20 @@ +// Source: mcp/debugging.md:245 +// Correct configuration for .NET exe +["my-dotnet-server"] = new McpLocalServerConfig +{ + Type = "local", + Command = @"C:\Tools\MyServer\MyServer.exe", // Full path with .exe + Args = new List(), + Cwd = @"C:\Tools\MyServer", // Set working directory + Tools = new List { "*" }, +} + +// For dotnet tool (DLL) +["my-dotnet-tool"] = new McpLocalServerConfig +{ + Type = "local", + Command = "dotnet", + Args = new List { @"C:\Tools\MyTool\MyTool.dll" }, + Cwd = @"C:\Tools\MyTool", + Tools = new List { "*" }, +} \ No newline at end of file diff --git a/docs/.validation/csharp/error-handling_20.cs b/docs/.validation/csharp/error-handling_20.cs new file mode 100644 index 00000000..efb63a56 --- /dev/null +++ b/docs/.validation/csharp/error-handling_20.cs @@ -0,0 +1,4 @@ +// Source: hooks/error-handling.md:52 +public delegate Task ErrorOccurredHandler( + ErrorOccurredHookInput input, + HookInvocation invocation); \ No newline at end of file diff --git a/docs/.validation/csharp/error-handling_21.cs b/docs/.validation/csharp/error-handling_21.cs new file mode 100644 index 00000000..1e86ee8a --- /dev/null +++ b/docs/.validation/csharp/error-handling_21.cs @@ -0,0 +1,14 @@ +// Source: hooks/error-handling.md:142 +var session = await client.CreateSessionAsync(new SessionConfig +{ + Hooks = new SessionHooks + { + OnErrorOccurred = (input, invocation) => + { + Console.Error.WriteLine($"[{invocation.SessionId}] Error: {input.Error}"); + Console.Error.WriteLine($" Context: {input.ErrorContext}"); + Console.Error.WriteLine($" Recoverable: {input.Recoverable}"); + return Task.FromResult(null); + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/csharp/getting-started_0.cs b/docs/.validation/csharp/getting-started_0.cs new file mode 100644 index 00000000..d6b93384 --- /dev/null +++ b/docs/.validation/csharp/getting-started_0.cs @@ -0,0 +1,8 @@ +// Source: getting-started.md:209 +using GitHub.Copilot.SDK; + +await using var client = new CopilotClient(); +await using var session = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-4.1" }); + +var response = await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 2 + 2?" }); +Console.WriteLine(response?.Data.Content); \ No newline at end of file diff --git a/docs/.validation/csharp/getting-started_1.cs b/docs/.validation/csharp/getting-started_1.cs new file mode 100644 index 00000000..e7a3fc91 --- /dev/null +++ b/docs/.validation/csharp/getting-started_1.cs @@ -0,0 +1,24 @@ +// Source: getting-started.md:366 +using GitHub.Copilot.SDK; + +await using var client = new CopilotClient(); +await using var session = await client.CreateSessionAsync(new SessionConfig +{ + Model = "gpt-4.1", + Streaming = true, +}); + +// Listen for response chunks +session.On(ev => +{ + if (ev is AssistantMessageDeltaEvent deltaEvent) + { + Console.Write(deltaEvent.Data.DeltaContent); + } + if (ev is SessionIdleEvent) + { + Console.WriteLine(); + } +}); + +await session.SendAndWaitAsync(new MessageOptions { Prompt = "Tell me a short joke" }); \ No newline at end of file diff --git a/docs/.validation/csharp/getting-started_2.cs b/docs/.validation/csharp/getting-started_2.cs new file mode 100644 index 00000000..628616d4 --- /dev/null +++ b/docs/.validation/csharp/getting-started_2.cs @@ -0,0 +1,20 @@ +// Source: getting-started.md:476 +// Subscribe to all events +var unsubscribe = session.On(ev => Console.WriteLine($"Event: {ev.Type}")); + +// Filter by event type using pattern matching +session.On(ev => +{ + switch (ev) + { + case SessionIdleEvent: + Console.WriteLine("Session is idle"); + break; + case AssistantMessageEvent msg: + Console.WriteLine($"Message: {msg.Data.Content}"); + break; + } +}); + +// Later, to unsubscribe: +unsubscribe.Dispose(); \ No newline at end of file diff --git a/docs/.validation/csharp/getting-started_3.cs b/docs/.validation/csharp/getting-started_3.cs new file mode 100644 index 00000000..44302592 --- /dev/null +++ b/docs/.validation/csharp/getting-started_3.cs @@ -0,0 +1,44 @@ +// Source: getting-started.md:706 +using GitHub.Copilot.SDK; +using Microsoft.Extensions.AI; +using System.ComponentModel; + +await using var client = new CopilotClient(); + +// Define a tool that Copilot can call +var getWeather = AIFunctionFactory.Create( + ([Description("The city name")] string city) => + { + // In a real app, you'd call a weather API here + var conditions = new[] { "sunny", "cloudy", "rainy", "partly cloudy" }; + var temp = Random.Shared.Next(50, 80); + var condition = conditions[Random.Shared.Next(conditions.Length)]; + return new { city, temperature = $"{temp}°F", condition }; + }, + "get_weather", + "Get the current weather for a city" +); + +await using var session = await client.CreateSessionAsync(new SessionConfig +{ + Model = "gpt-4.1", + Streaming = true, + Tools = [getWeather], +}); + +session.On(ev => +{ + if (ev is AssistantMessageDeltaEvent deltaEvent) + { + Console.Write(deltaEvent.Data.DeltaContent); + } + if (ev is SessionIdleEvent) + { + Console.WriteLine(); + } +}); + +await session.SendAndWaitAsync(new MessageOptions +{ + Prompt = "What's the weather like in Seattle and Tokyo?", +}); \ No newline at end of file diff --git a/docs/.validation/csharp/getting-started_4.cs b/docs/.validation/csharp/getting-started_4.cs new file mode 100644 index 00000000..2448e0b4 --- /dev/null +++ b/docs/.validation/csharp/getting-started_4.cs @@ -0,0 +1,55 @@ +// Source: getting-started.md:1015 +using GitHub.Copilot.SDK; +using Microsoft.Extensions.AI; +using System.ComponentModel; + +// Define the weather tool using AIFunctionFactory +var getWeather = AIFunctionFactory.Create( + ([Description("The city name")] string city) => + { + var conditions = new[] { "sunny", "cloudy", "rainy", "partly cloudy" }; + var temp = Random.Shared.Next(50, 80); + var condition = conditions[Random.Shared.Next(conditions.Length)]; + return new { city, temperature = $"{temp}°F", condition }; + }, + "get_weather", + "Get the current weather for a city"); + +await using var client = new CopilotClient(); +await using var session = await client.CreateSessionAsync(new SessionConfig +{ + Model = "gpt-4.1", + Streaming = true, + Tools = [getWeather] +}); + +// Listen for response chunks +session.On(ev => +{ + if (ev is AssistantMessageDeltaEvent deltaEvent) + { + Console.Write(deltaEvent.Data.DeltaContent); + } + if (ev is SessionIdleEvent) + { + Console.WriteLine(); + } +}); + +Console.WriteLine("🌤️ Weather Assistant (type 'exit' to quit)"); +Console.WriteLine(" Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'\n"); + +while (true) +{ + Console.Write("You: "); + var input = Console.ReadLine(); + + if (string.IsNullOrEmpty(input) || input.Equals("exit", StringComparison.OrdinalIgnoreCase)) + { + break; + } + + Console.Write("Assistant: "); + await session.SendAndWaitAsync(new MessageOptions { Prompt = input }); + Console.WriteLine("\n"); +} \ No newline at end of file diff --git a/docs/.validation/csharp/getting-started_5.cs b/docs/.validation/csharp/getting-started_5.cs new file mode 100644 index 00000000..8ff516ba --- /dev/null +++ b/docs/.validation/csharp/getting-started_5.cs @@ -0,0 +1,12 @@ +// Source: getting-started.md:1251 +using GitHub.Copilot.SDK; + +using var client = new CopilotClient(new CopilotClientOptions +{ + CliUrl = "localhost:4321", + UseStdio = false +}); + +// Use the client normally +await using var session = await client.CreateSessionAsync(); +// ... \ No newline at end of file diff --git a/docs/.validation/csharp/index_26.cs b/docs/.validation/csharp/index_26.cs new file mode 100644 index 00000000..12f21643 --- /dev/null +++ b/docs/.validation/csharp/index_26.cs @@ -0,0 +1,5 @@ +// Source: auth/index.md:66 +using GitHub.Copilot.SDK; + +// Default: uses logged-in user credentials +await using var client = new CopilotClient(); \ No newline at end of file diff --git a/docs/.validation/csharp/index_27.cs b/docs/.validation/csharp/index_27.cs new file mode 100644 index 00000000..69c4f9eb --- /dev/null +++ b/docs/.validation/csharp/index_27.cs @@ -0,0 +1,8 @@ +// Source: auth/index.md:138 +using GitHub.Copilot.SDK; + +await using var client = new CopilotClient(new CopilotClientOptions +{ + GithubToken = userAccessToken, // Token from OAuth flow + UseLoggedInUser = false, // Don't use stored CLI credentials +}); \ No newline at end of file diff --git a/docs/.validation/csharp/index_28.cs b/docs/.validation/csharp/index_28.cs new file mode 100644 index 00000000..f809c65d --- /dev/null +++ b/docs/.validation/csharp/index_28.cs @@ -0,0 +1,5 @@ +// Source: auth/index.md:279 +await using var client = new CopilotClient(new CopilotClientOptions +{ + UseLoggedInUser = false, // Only use explicit tokens +}); \ No newline at end of file diff --git a/docs/.validation/csharp/overview_19.cs b/docs/.validation/csharp/overview_19.cs new file mode 100644 index 00000000..7b68796e --- /dev/null +++ b/docs/.validation/csharp/overview_19.cs @@ -0,0 +1,29 @@ +// Source: hooks/overview.md:127 +using GitHub.Copilot.SDK; + +var client = new CopilotClient(); + +var session = await client.CreateSessionAsync(new SessionConfig +{ + Hooks = new SessionHooks + { + OnPreToolUse = (input, invocation) => + { + Console.WriteLine($"Tool called: {input.ToolName}"); + return Task.FromResult( + new PreToolUseHookOutput { PermissionDecision = "allow" } + ); + }, + OnPostToolUse = (input, invocation) => + { + Console.WriteLine($"Tool result: {input.ToolResult}"); + return Task.FromResult(null); + }, + OnSessionStart = (input, invocation) => + { + return Task.FromResult( + new SessionStartHookOutput { AdditionalContext = "User prefers concise answers." } + ); + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/csharp/overview_8.cs b/docs/.validation/csharp/overview_8.cs new file mode 100644 index 00000000..196591cd --- /dev/null +++ b/docs/.validation/csharp/overview_8.cs @@ -0,0 +1,18 @@ +// Source: mcp/overview.md:143 +using GitHub.Copilot.SDK; + +await using var client = new CopilotClient(); +await using var session = await client.CreateSessionAsync(new SessionConfig +{ + Model = "gpt-5", + McpServers = new Dictionary + { + ["my-local-server"] = new McpLocalServerConfig + { + Type = "local", + Command = "node", + Args = new[] { "./mcp-server.js" }, + Tools = new[] { "*" }, + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/csharp/post-tool-use_17.cs b/docs/.validation/csharp/post-tool-use_17.cs new file mode 100644 index 00000000..2a55ed99 --- /dev/null +++ b/docs/.validation/csharp/post-tool-use_17.cs @@ -0,0 +1,4 @@ +// Source: hooks/post-tool-use.md:52 +public delegate Task PostToolUseHandler( + PostToolUseHookInput input, + HookInvocation invocation); \ No newline at end of file diff --git a/docs/.validation/csharp/post-tool-use_18.cs b/docs/.validation/csharp/post-tool-use_18.cs new file mode 100644 index 00000000..7435800d --- /dev/null +++ b/docs/.validation/csharp/post-tool-use_18.cs @@ -0,0 +1,14 @@ +// Source: hooks/post-tool-use.md:141 +var session = await client.CreateSessionAsync(new SessionConfig +{ + Hooks = new SessionHooks + { + OnPostToolUse = (input, invocation) => + { + Console.WriteLine($"[{invocation.SessionId}] Tool: {input.ToolName}"); + Console.WriteLine($" Args: {input.ToolArgs}"); + Console.WriteLine($" Result: {input.ToolResult}"); + return Task.FromResult(null); + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/csharp/pre-tool-use_15.cs b/docs/.validation/csharp/pre-tool-use_15.cs new file mode 100644 index 00000000..5f692774 --- /dev/null +++ b/docs/.validation/csharp/pre-tool-use_15.cs @@ -0,0 +1,4 @@ +// Source: hooks/pre-tool-use.md:52 +public delegate Task PreToolUseHandler( + PreToolUseHookInput input, + HookInvocation invocation); \ No newline at end of file diff --git a/docs/.validation/csharp/pre-tool-use_16.cs b/docs/.validation/csharp/pre-tool-use_16.cs new file mode 100644 index 00000000..f5401e5b --- /dev/null +++ b/docs/.validation/csharp/pre-tool-use_16.cs @@ -0,0 +1,15 @@ +// Source: hooks/pre-tool-use.md:149 +var session = await client.CreateSessionAsync(new SessionConfig +{ + Hooks = new SessionHooks + { + OnPreToolUse = (input, invocation) => + { + Console.WriteLine($"[{invocation.SessionId}] Calling {input.ToolName}"); + Console.WriteLine($" Args: {input.ToolArgs}"); + return Task.FromResult( + new PreToolUseHookOutput { PermissionDecision = "allow" } + ); + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/csharp/session-lifecycle_13.cs b/docs/.validation/csharp/session-lifecycle_13.cs new file mode 100644 index 00000000..68268922 --- /dev/null +++ b/docs/.validation/csharp/session-lifecycle_13.cs @@ -0,0 +1,4 @@ +// Source: hooks/session-lifecycle.md:56 +public delegate Task SessionStartHandler( + SessionStartHookInput input, + HookInvocation invocation); \ No newline at end of file diff --git a/docs/.validation/csharp/session-lifecycle_14.cs b/docs/.validation/csharp/session-lifecycle_14.cs new file mode 100644 index 00000000..0783ad30 --- /dev/null +++ b/docs/.validation/csharp/session-lifecycle_14.cs @@ -0,0 +1,4 @@ +// Source: hooks/session-lifecycle.md:233 +public delegate Task SessionEndHandler( + SessionEndHookInput input, + HookInvocation invocation); \ No newline at end of file diff --git a/docs/.validation/csharp/session-persistence_24.cs b/docs/.validation/csharp/session-persistence_24.cs new file mode 100644 index 00000000..fdc0b5f4 --- /dev/null +++ b/docs/.validation/csharp/session-persistence_24.cs @@ -0,0 +1,16 @@ +// Source: guides/session-persistence.md:87 +using GitHub.Copilot.SDK; + +var client = new CopilotClient(); + +// Create a session with a meaningful ID +var session = await client.CreateSessionAsync(new SessionConfig +{ + SessionId = "user-123-task-456", + Model = "gpt-5.2-codex", +}); + +// Do some work... +await session.SendAndWaitAsync(new MessageOptions { Prompt = "Analyze my codebase" }); + +// Session state is automatically persisted \ No newline at end of file diff --git a/docs/.validation/csharp/session-persistence_25.cs b/docs/.validation/csharp/session-persistence_25.cs new file mode 100644 index 00000000..54ec1f16 --- /dev/null +++ b/docs/.validation/csharp/session-persistence_25.cs @@ -0,0 +1,6 @@ +// Source: guides/session-persistence.md:158 +// Resume from a different client instance (or after restart) +var session = await client.ResumeSessionAsync("user-123-task-456"); + +// Continue where you left off +await session.SendAndWaitAsync(new MessageOptions { Prompt = "What did we discuss earlier?" }); \ No newline at end of file diff --git a/docs/.validation/csharp/skills_22.cs b/docs/.validation/csharp/skills_22.cs new file mode 100644 index 00000000..74ab5ce0 --- /dev/null +++ b/docs/.validation/csharp/skills_22.cs @@ -0,0 +1,20 @@ +// Source: guides/skills.md:118 +using GitHub.Copilot.SDK; + +await using var client = new CopilotClient(); +await using var session = await client.CreateSessionAsync(new SessionConfig +{ + Model = "gpt-4.1", + SkillDirectories = new List + { + "./skills/code-review", + "./skills/documentation", + "~/.copilot/skills", // User-level skills + }, +}); + +// Copilot now has access to skills in those directories +await session.SendAndWaitAsync(new MessageOptions +{ + Prompt = "Review this code for security issues" +}); \ No newline at end of file diff --git a/docs/.validation/csharp/skills_23.cs b/docs/.validation/csharp/skills_23.cs new file mode 100644 index 00000000..b644d890 --- /dev/null +++ b/docs/.validation/csharp/skills_23.cs @@ -0,0 +1,6 @@ +// Source: guides/skills.md:186 +var session = await client.CreateSessionAsync(new SessionConfig +{ + SkillDirectories = new List { "./skills" }, + DisabledSkills = new List { "experimental-feature", "deprecated-tool" }, +}); \ No newline at end of file diff --git a/docs/.validation/csharp/user-prompt-submitted_11.cs b/docs/.validation/csharp/user-prompt-submitted_11.cs new file mode 100644 index 00000000..22c97566 --- /dev/null +++ b/docs/.validation/csharp/user-prompt-submitted_11.cs @@ -0,0 +1,4 @@ +// Source: hooks/user-prompt-submitted.md:52 +public delegate Task UserPromptSubmittedHandler( + UserPromptSubmittedHookInput input, + HookInvocation invocation); \ No newline at end of file diff --git a/docs/.validation/csharp/user-prompt-submitted_12.cs b/docs/.validation/csharp/user-prompt-submitted_12.cs new file mode 100644 index 00000000..72d7cbb2 --- /dev/null +++ b/docs/.validation/csharp/user-prompt-submitted_12.cs @@ -0,0 +1,12 @@ +// Source: hooks/user-prompt-submitted.md:133 +var session = await client.CreateSessionAsync(new SessionConfig +{ + Hooks = new SessionHooks + { + OnUserPromptSubmitted = (input, invocation) => + { + Console.WriteLine($"[{invocation.SessionId}] User: {input.Prompt}"); + return Task.FromResult(null); + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/go/byok_7.go b/docs/.validation/go/byok_7.go new file mode 100644 index 00000000..fd4d6eb2 --- /dev/null +++ b/docs/.validation/go/byok_7.go @@ -0,0 +1,40 @@ +// Source: auth/byok.md:96 +package main + +import ( + "context" + "fmt" + "os" + copilot "github.com/github/copilot-sdk/go" +) + +func main() { + ctx := context.Background() + client := copilot.NewClient(nil) + if err := client.Start(ctx); err != nil { + panic(err) + } + defer client.Stop() + + session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + Model: "gpt-5.2-codex", // Your deployment name + Provider: &copilot.ProviderConfig{ + Type: "openai", + BaseURL: "https://your-resource.openai.azure.com/openai/v1/", + WireApi: "responses", // Use "completions" for older models + APIKey: os.Getenv("FOUNDRY_API_KEY"), + }, + }) + if err != nil { + panic(err) + } + + response, err := session.SendAndWait(ctx, copilot.MessageOptions{ + Prompt: "What is 2+2?", + }) + if err != nil { + panic(err) + } + + fmt.Println(*response.Data.Content) +} \ No newline at end of file diff --git a/docs/.validation/go/getting-started_0.go b/docs/.validation/go/getting-started_0.go new file mode 100644 index 00000000..78daf3fb --- /dev/null +++ b/docs/.validation/go/getting-started_0.go @@ -0,0 +1,33 @@ +// Source: getting-started.md:161 +package main + +import ( + "context" + "fmt" + "log" + "os" + + copilot "github.com/github/copilot-sdk/go" +) + +func main() { + ctx := context.Background() + client := copilot.NewClient(nil) + if err := client.Start(ctx); err != nil { + log.Fatal(err) + } + defer client.Stop() + + session, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-4.1"}) + if err != nil { + log.Fatal(err) + } + + response, err := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "What is 2 + 2?"}) + if err != nil { + log.Fatal(err) + } + + fmt.Println(*response.Data.Content) + os.Exit(0) +} \ No newline at end of file diff --git a/docs/.validation/go/getting-started_1.go b/docs/.validation/go/getting-started_1.go new file mode 100644 index 00000000..5212d578 --- /dev/null +++ b/docs/.validation/go/getting-started_1.go @@ -0,0 +1,44 @@ +// Source: getting-started.md:313 +package main + +import ( + "context" + "fmt" + "log" + "os" + + copilot "github.com/github/copilot-sdk/go" +) + +func main() { + ctx := context.Background() + client := copilot.NewClient(nil) + if err := client.Start(ctx); err != nil { + log.Fatal(err) + } + defer client.Stop() + + session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + Model: "gpt-4.1", + Streaming: true, + }) + if err != nil { + log.Fatal(err) + } + + // Listen for response chunks + session.On(func(event copilot.SessionEvent) { + if event.Type == "assistant.message_delta" { + fmt.Print(*event.Data.DeltaContent) + } + if event.Type == "session.idle" { + fmt.Println() + } + }) + + _, err = session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Tell me a short joke"}) + if err != nil { + log.Fatal(err) + } + os.Exit(0) +} \ No newline at end of file diff --git a/docs/.validation/go/getting-started_2.go b/docs/.validation/go/getting-started_2.go new file mode 100644 index 00000000..17f4248a --- /dev/null +++ b/docs/.validation/go/getting-started_2.go @@ -0,0 +1,77 @@ +// Source: getting-started.md:620 +package main + +import ( + "context" + "fmt" + "log" + "math/rand" + "os" + + copilot "github.com/github/copilot-sdk/go" +) + +// Define the parameter type +type WeatherParams struct { + City string `json:"city" jsonschema:"The city name"` +} + +// Define the return type +type WeatherResult struct { + City string `json:"city"` + Temperature string `json:"temperature"` + Condition string `json:"condition"` +} + +func main() { + ctx := context.Background() + + // Define a tool that Copilot can call + getWeather := copilot.DefineTool( + "get_weather", + "Get the current weather for a city", + func(params WeatherParams, inv copilot.ToolInvocation) (WeatherResult, error) { + // In a real app, you'd call a weather API here + conditions := []string{"sunny", "cloudy", "rainy", "partly cloudy"} + temp := rand.Intn(30) + 50 + condition := conditions[rand.Intn(len(conditions))] + return WeatherResult{ + City: params.City, + Temperature: fmt.Sprintf("%d°F", temp), + Condition: condition, + }, nil + }, + ) + + client := copilot.NewClient(nil) + if err := client.Start(ctx); err != nil { + log.Fatal(err) + } + defer client.Stop() + + session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + Model: "gpt-4.1", + Streaming: true, + Tools: []copilot.Tool{getWeather}, + }) + if err != nil { + log.Fatal(err) + } + + session.On(func(event copilot.SessionEvent) { + if event.Type == "assistant.message_delta" { + fmt.Print(*event.Data.DeltaContent) + } + if event.Type == "session.idle" { + fmt.Println() + } + }) + + _, err = session.SendAndWait(ctx, copilot.MessageOptions{ + Prompt: "What's the weather like in Seattle and Tokyo?", + }) + if err != nil { + log.Fatal(err) + } + os.Exit(0) +} \ No newline at end of file diff --git a/docs/.validation/go/getting-started_3.go b/docs/.validation/go/getting-started_3.go new file mode 100644 index 00000000..ed35860b --- /dev/null +++ b/docs/.validation/go/getting-started_3.go @@ -0,0 +1,95 @@ +// Source: getting-started.md:905 +package main + +import ( + "bufio" + "context" + "fmt" + "log" + "math/rand" + "os" + "strings" + + copilot "github.com/github/copilot-sdk/go" +) + +type WeatherParams struct { + City string `json:"city" jsonschema:"The city name"` +} + +type WeatherResult struct { + City string `json:"city"` + Temperature string `json:"temperature"` + Condition string `json:"condition"` +} + +func main() { + ctx := context.Background() + + getWeather := copilot.DefineTool( + "get_weather", + "Get the current weather for a city", + func(params WeatherParams, inv copilot.ToolInvocation) (WeatherResult, error) { + conditions := []string{"sunny", "cloudy", "rainy", "partly cloudy"} + temp := rand.Intn(30) + 50 + condition := conditions[rand.Intn(len(conditions))] + return WeatherResult{ + City: params.City, + Temperature: fmt.Sprintf("%d°F", temp), + Condition: condition, + }, nil + }, + ) + + client := copilot.NewClient(nil) + if err := client.Start(ctx); err != nil { + log.Fatal(err) + } + defer client.Stop() + + session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + Model: "gpt-4.1", + Streaming: true, + Tools: []copilot.Tool{getWeather}, + }) + if err != nil { + log.Fatal(err) + } + + session.On(func(event copilot.SessionEvent) { + if event.Type == "assistant.message_delta" { + if event.Data.DeltaContent != nil { + fmt.Print(*event.Data.DeltaContent) + } + } + if event.Type == "session.idle" { + fmt.Println() + } + }) + + fmt.Println("🌤️ Weather Assistant (type 'exit' to quit)") + fmt.Println(" Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'\n") + + scanner := bufio.NewScanner(os.Stdin) + for { + fmt.Print("You: ") + if !scanner.Scan() { + break + } + input := scanner.Text() + if strings.ToLower(input) == "exit" { + break + } + + fmt.Print("Assistant: ") + _, err = session.SendAndWait(ctx, copilot.MessageOptions{Prompt: input}) + if err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + break + } + fmt.Println() + } + if err := scanner.Err(); err != nil { + fmt.Fprintf(os.Stderr, "Input error: %v\n", err) + } +} \ No newline at end of file diff --git a/docs/.validation/go/go.mod b/docs/.validation/go/go.mod new file mode 100644 index 00000000..17738113 --- /dev/null +++ b/docs/.validation/go/go.mod @@ -0,0 +1,9 @@ +module docs-validation + +go 1.24 + +require github.com/github/copilot-sdk/go v0.0.0 + +require github.com/google/jsonschema-go v0.4.2 // indirect + +replace github.com/github/copilot-sdk/go => /Users/patrick/projects/copilot-sdk/go diff --git a/docs/.validation/go/go.sum b/docs/.validation/go/go.sum new file mode 100644 index 00000000..6e171099 --- /dev/null +++ b/docs/.validation/go/go.sum @@ -0,0 +1,4 @@ +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= +github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= diff --git a/docs/.validation/go/overview_4.go b/docs/.validation/go/overview_4.go new file mode 100644 index 00000000..a0798915 --- /dev/null +++ b/docs/.validation/go/overview_4.go @@ -0,0 +1,36 @@ +// Source: mcp/overview.md:103 +package main + +import ( + "context" + "log" + copilot "github.com/github/copilot-sdk/go" +) + +func main() { + ctx := context.Background() + client := copilot.NewClient(nil) + if err := client.Start(ctx); err != nil { + log.Fatal(err) + } + defer client.Stop() + + // MCPServerConfig is map[string]any for flexibility + session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + Model: "gpt-5", + MCPServers: map[string]copilot.MCPServerConfig{ + "my-local-server": { + "type": "local", + "command": "node", + "args": []string{"./mcp-server.js"}, + "tools": []string{"*"}, + }, + }, + }) + if err != nil { + log.Fatal(err) + } + defer session.Destroy() + + // Use the session... +} \ No newline at end of file diff --git a/docs/.validation/go/overview_5.go b/docs/.validation/go/overview_5.go new file mode 100644 index 00000000..0bba16ca --- /dev/null +++ b/docs/.validation/go/overview_5.go @@ -0,0 +1,33 @@ +// Source: hooks/overview.md:87 +package main + +import ( + "context" + "fmt" + copilot "github.com/github/copilot-sdk/go" +) + +func main() { + client := copilot.NewClient(nil) + + session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{ + Hooks: &copilot.SessionHooks{ + OnPreToolUse: func(input copilot.PreToolUseHookInput, inv copilot.HookInvocation) (*copilot.PreToolUseHookOutput, error) { + fmt.Printf("Tool called: %s\n", input.ToolName) + return &copilot.PreToolUseHookOutput{ + PermissionDecision: "allow", + }, nil + }, + OnPostToolUse: func(input copilot.PostToolUseHookInput, inv copilot.HookInvocation) (*copilot.PostToolUseHookOutput, error) { + fmt.Printf("Tool result: %v\n", input.ToolResult) + return nil, nil + }, + OnSessionStart: func(input copilot.SessionStartHookInput, inv copilot.HookInvocation) (*copilot.SessionStartHookOutput, error) { + return &copilot.SessionStartHookOutput{ + AdditionalContext: "User prefers concise answers.", + }, nil + }, + }, + }) + _ = session +} \ No newline at end of file diff --git a/docs/.validation/go/skills_6.go b/docs/.validation/go/skills_6.go new file mode 100644 index 00000000..8655edf5 --- /dev/null +++ b/docs/.validation/go/skills_6.go @@ -0,0 +1,37 @@ +// Source: guides/skills.md:74 +package main + +import ( + "context" + "log" + copilot "github.com/github/copilot-sdk/go" +) + +func main() { + ctx := context.Background() + client := copilot.NewClient(nil) + if err := client.Start(ctx); err != nil { + log.Fatal(err) + } + defer client.Stop() + + session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + Model: "gpt-4.1", + SkillDirectories: []string{ + "./skills/code-review", + "./skills/documentation", + "~/.copilot/skills", // User-level skills + }, + }) + if err != nil { + log.Fatal(err) + } + + // Copilot now has access to skills in those directories + _, err = session.SendAndWait(ctx, copilot.MessageOptions{ + Prompt: "Review this code for security issues", + }) + if err != nil { + log.Fatal(err) + } +} \ No newline at end of file diff --git a/docs/.validation/manifest.json b/docs/.validation/manifest.json new file mode 100644 index 00000000..c0e970da --- /dev/null +++ b/docs/.validation/manifest.json @@ -0,0 +1,1104 @@ +{ + "extractedAt": "2026-02-04T05:48:40.133Z", + "blocks": [ + { + "id": "typescript/getting-started_0.ts", + "sourceFile": "getting-started.md", + "sourceLine": 104, + "language": "typescript", + "outputFile": "typescript/getting-started_0.ts" + }, + { + "id": "python/getting-started_0.py", + "sourceFile": "getting-started.md", + "sourceLine": 130, + "language": "python", + "outputFile": "python/getting-started_0.py" + }, + { + "id": "go/getting-started_0.go", + "sourceFile": "getting-started.md", + "sourceLine": 161, + "language": "go", + "outputFile": "go/getting-started_0.go" + }, + { + "id": "csharp/getting-started_0.cs", + "sourceFile": "getting-started.md", + "sourceLine": 209, + "language": "csharp", + "outputFile": "csharp/getting-started_0.cs" + }, + { + "id": "typescript/getting-started_1.ts", + "sourceFile": "getting-started.md", + "sourceLine": 244, + "language": "typescript", + "outputFile": "typescript/getting-started_1.ts" + }, + { + "id": "python/getting-started_1.py", + "sourceFile": "getting-started.md", + "sourceLine": 274, + "language": "python", + "outputFile": "python/getting-started_1.py" + }, + { + "id": "go/getting-started_1.go", + "sourceFile": "getting-started.md", + "sourceLine": 313, + "language": "go", + "outputFile": "go/getting-started_1.go" + }, + { + "id": "csharp/getting-started_1.cs", + "sourceFile": "getting-started.md", + "sourceLine": 366, + "language": "csharp", + "outputFile": "csharp/getting-started_1.cs" + }, + { + "id": "typescript/getting-started_2.ts", + "sourceFile": "getting-started.md", + "sourceLine": 408, + "language": "typescript", + "outputFile": "typescript/getting-started_2.ts" + }, + { + "id": "python/getting-started_2.py", + "sourceFile": "getting-started.md", + "sourceLine": 429, + "language": "python", + "outputFile": "python/getting-started_2.py" + }, + { + "id": "csharp/getting-started_2.cs", + "sourceFile": "getting-started.md", + "sourceLine": 476, + "language": "csharp", + "outputFile": "csharp/getting-started_2.cs" + }, + { + "id": "typescript/getting-started_3.ts", + "sourceFile": "getting-started.md", + "sourceLine": 509, + "language": "typescript", + "outputFile": "typescript/getting-started_3.ts" + }, + { + "id": "python/getting-started_3.py", + "sourceFile": "getting-started.md", + "sourceLine": 562, + "language": "python", + "outputFile": "python/getting-started_3.py" + }, + { + "id": "go/getting-started_2.go", + "sourceFile": "getting-started.md", + "sourceLine": 620, + "language": "go", + "outputFile": "go/getting-started_2.go" + }, + { + "id": "csharp/getting-started_3.cs", + "sourceFile": "getting-started.md", + "sourceLine": 706, + "language": "csharp", + "outputFile": "csharp/getting-started_3.cs" + }, + { + "id": "typescript/getting-started_4.ts", + "sourceFile": "getting-started.md", + "sourceLine": 763, + "language": "typescript", + "outputFile": "typescript/getting-started_4.ts" + }, + { + "id": "python/getting-started_4.py", + "sourceFile": "getting-started.md", + "sourceLine": 834, + "language": "python", + "outputFile": "python/getting-started_4.py" + }, + { + "id": "go/getting-started_3.go", + "sourceFile": "getting-started.md", + "sourceLine": 905, + "language": "go", + "outputFile": "go/getting-started_3.go" + }, + { + "id": "csharp/getting-started_4.cs", + "sourceFile": "getting-started.md", + "sourceLine": 1015, + "language": "csharp", + "outputFile": "csharp/getting-started_4.cs" + }, + { + "id": "typescript/getting-started_5.ts", + "sourceFile": "getting-started.md", + "sourceLine": 1126, + "language": "typescript", + "outputFile": "typescript/getting-started_5.ts" + }, + { + "id": "typescript/getting-started_6.ts", + "sourceFile": "getting-started.md", + "sourceLine": 1143, + "language": "typescript", + "outputFile": "typescript/getting-started_6.ts" + }, + { + "id": "typescript/getting-started_7.ts", + "sourceFile": "getting-started.md", + "sourceLine": 1158, + "language": "typescript", + "outputFile": "typescript/getting-started_7.ts" + }, + { + "id": "typescript/getting-started_8.ts", + "sourceFile": "getting-started.md", + "sourceLine": 1193, + "language": "typescript", + "outputFile": "typescript/getting-started_8.ts" + }, + { + "id": "python/getting-started_5.py", + "sourceFile": "getting-started.md", + "sourceLine": 1210, + "language": "python", + "outputFile": "python/getting-started_5.py" + }, + { + "id": "csharp/getting-started_5.cs", + "sourceFile": "getting-started.md", + "sourceLine": 1251, + "language": "csharp", + "outputFile": "csharp/getting-started_5.cs" + }, + { + "id": "typescript/debugging_9.ts", + "sourceFile": "debugging.md", + "sourceLine": 23, + "language": "typescript", + "outputFile": "typescript/debugging_9.ts" + }, + { + "id": "python/debugging_6.py", + "sourceFile": "debugging.md", + "sourceLine": 36, + "language": "python", + "outputFile": "python/debugging_6.py" + }, + { + "id": "csharp/debugging_6.cs", + "sourceFile": "debugging.md", + "sourceLine": 61, + "language": "csharp", + "outputFile": "csharp/debugging_6.cs" + }, + { + "id": "typescript/debugging_10.ts", + "sourceFile": "debugging.md", + "sourceLine": 88, + "language": "typescript", + "outputFile": "typescript/debugging_10.ts" + }, + { + "id": "python/debugging_7.py", + "sourceFile": "debugging.md", + "sourceLine": 99, + "language": "python", + "outputFile": "python/debugging_7.py" + }, + { + "id": "csharp/debugging_7.cs", + "sourceFile": "debugging.md", + "sourceLine": 124, + "language": "csharp", + "outputFile": "csharp/debugging_7.cs" + }, + { + "id": "typescript/debugging_11.ts", + "sourceFile": "debugging.md", + "sourceLine": 326, + "language": "typescript", + "outputFile": "typescript/debugging_11.ts" + }, + { + "id": "typescript/debugging_12.ts", + "sourceFile": "debugging.md", + "sourceLine": 333, + "language": "typescript", + "outputFile": "typescript/debugging_12.ts" + }, + { + "id": "typescript/debugging_13.ts", + "sourceFile": "debugging.md", + "sourceLine": 341, + "language": "typescript", + "outputFile": "typescript/debugging_13.ts" + }, + { + "id": "typescript/debugging_14.ts", + "sourceFile": "debugging.md", + "sourceLine": 416, + "language": "typescript", + "outputFile": "typescript/debugging_14.ts" + }, + { + "id": "typescript/compatibility_15.ts", + "sourceFile": "compatibility.md", + "sourceLine": 129, + "language": "typescript", + "outputFile": "typescript/compatibility_15.ts" + }, + { + "id": "typescript/compatibility_16.ts", + "sourceFile": "compatibility.md", + "sourceLine": 148, + "language": "typescript", + "outputFile": "typescript/compatibility_16.ts" + }, + { + "id": "typescript/compatibility_17.ts", + "sourceFile": "compatibility.md", + "sourceLine": 161, + "language": "typescript", + "outputFile": "typescript/compatibility_17.ts" + }, + { + "id": "typescript/overview_18.ts", + "sourceFile": "mcp/overview.md", + "sourceLine": 30, + "language": "typescript", + "outputFile": "typescript/overview_18.ts" + }, + { + "id": "python/overview_8.py", + "sourceFile": "mcp/overview.md", + "sourceLine": 60, + "language": "python", + "outputFile": "python/overview_8.py" + }, + { + "id": "go/overview_4.go", + "sourceFile": "mcp/overview.md", + "sourceLine": 103, + "language": "go", + "outputFile": "go/overview_4.go" + }, + { + "id": "csharp/overview_8.cs", + "sourceFile": "mcp/overview.md", + "sourceLine": 143, + "language": "csharp", + "outputFile": "csharp/overview_8.cs" + }, + { + "id": "typescript/overview_19.ts", + "sourceFile": "mcp/overview.md", + "sourceLine": 167, + "language": "typescript", + "outputFile": "typescript/overview_19.ts" + }, + { + "id": "csharp/debugging_9.cs", + "sourceFile": "mcp/debugging.md", + "sourceLine": 245, + "language": "csharp", + "outputFile": "csharp/debugging_9.cs" + }, + { + "id": "csharp/debugging_10.cs", + "sourceFile": "mcp/debugging.md", + "sourceLine": 269, + "language": "csharp", + "outputFile": "csharp/debugging_10.cs" + }, + { + "id": "typescript/user-prompt-submitted_20.ts", + "sourceFile": "hooks/user-prompt-submitted.md", + "sourceLine": 15, + "language": "typescript", + "outputFile": "typescript/user-prompt-submitted_20.ts" + }, + { + "id": "python/user-prompt-submitted_9.py", + "sourceFile": "hooks/user-prompt-submitted.md", + "sourceLine": 27, + "language": "python", + "outputFile": "python/user-prompt-submitted_9.py" + }, + { + "id": "csharp/user-prompt-submitted_11.cs", + "sourceFile": "hooks/user-prompt-submitted.md", + "sourceLine": 52, + "language": "csharp", + "outputFile": "csharp/user-prompt-submitted_11.cs" + }, + { + "id": "typescript/user-prompt-submitted_21.ts", + "sourceFile": "hooks/user-prompt-submitted.md", + "sourceLine": 85, + "language": "typescript", + "outputFile": "typescript/user-prompt-submitted_21.ts" + }, + { + "id": "python/user-prompt-submitted_10.py", + "sourceFile": "hooks/user-prompt-submitted.md", + "sourceLine": 101, + "language": "python", + "outputFile": "python/user-prompt-submitted_10.py" + }, + { + "id": "csharp/user-prompt-submitted_12.cs", + "sourceFile": "hooks/user-prompt-submitted.md", + "sourceLine": 133, + "language": "csharp", + "outputFile": "csharp/user-prompt-submitted_12.cs" + }, + { + "id": "typescript/user-prompt-submitted_22.ts", + "sourceFile": "hooks/user-prompt-submitted.md", + "sourceLine": 151, + "language": "typescript", + "outputFile": "typescript/user-prompt-submitted_22.ts" + }, + { + "id": "typescript/user-prompt-submitted_23.ts", + "sourceFile": "hooks/user-prompt-submitted.md", + "sourceLine": 171, + "language": "typescript", + "outputFile": "typescript/user-prompt-submitted_23.ts" + }, + { + "id": "typescript/user-prompt-submitted_24.ts", + "sourceFile": "hooks/user-prompt-submitted.md", + "sourceLine": 198, + "language": "typescript", + "outputFile": "typescript/user-prompt-submitted_24.ts" + }, + { + "id": "typescript/user-prompt-submitted_25.ts", + "sourceFile": "hooks/user-prompt-submitted.md", + "sourceLine": 225, + "language": "typescript", + "outputFile": "typescript/user-prompt-submitted_25.ts" + }, + { + "id": "typescript/user-prompt-submitted_26.ts", + "sourceFile": "hooks/user-prompt-submitted.md", + "sourceLine": 246, + "language": "typescript", + "outputFile": "typescript/user-prompt-submitted_26.ts" + }, + { + "id": "typescript/user-prompt-submitted_27.ts", + "sourceFile": "hooks/user-prompt-submitted.md", + "sourceLine": 280, + "language": "typescript", + "outputFile": "typescript/user-prompt-submitted_27.ts" + }, + { + "id": "typescript/user-prompt-submitted_28.ts", + "sourceFile": "hooks/user-prompt-submitted.md", + "sourceLine": 311, + "language": "typescript", + "outputFile": "typescript/user-prompt-submitted_28.ts" + }, + { + "id": "typescript/session-lifecycle_29.ts", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 19, + "language": "typescript", + "outputFile": "typescript/session-lifecycle_29.ts" + }, + { + "id": "python/session-lifecycle_11.py", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 31, + "language": "python", + "outputFile": "python/session-lifecycle_11.py" + }, + { + "id": "csharp/session-lifecycle_13.cs", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 56, + "language": "csharp", + "outputFile": "csharp/session-lifecycle_13.cs" + }, + { + "id": "typescript/session-lifecycle_30.ts", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 87, + "language": "typescript", + "outputFile": "typescript/session-lifecycle_30.ts" + }, + { + "id": "python/session-lifecycle_12.py", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 112, + "language": "python", + "outputFile": "python/session-lifecycle_12.py" + }, + { + "id": "typescript/session-lifecycle_31.ts", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 135, + "language": "typescript", + "outputFile": "typescript/session-lifecycle_31.ts" + }, + { + "id": "typescript/session-lifecycle_32.ts", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 159, + "language": "typescript", + "outputFile": "typescript/session-lifecycle_32.ts" + }, + { + "id": "typescript/session-lifecycle_33.ts", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 196, + "language": "typescript", + "outputFile": "typescript/session-lifecycle_33.ts" + }, + { + "id": "python/session-lifecycle_13.py", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 208, + "language": "python", + "outputFile": "python/session-lifecycle_13.py" + }, + { + "id": "csharp/session-lifecycle_14.cs", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 233, + "language": "csharp", + "outputFile": "csharp/session-lifecycle_14.cs" + }, + { + "id": "typescript/session-lifecycle_34.ts", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 276, + "language": "typescript", + "outputFile": "typescript/session-lifecycle_34.ts" + }, + { + "id": "python/session-lifecycle_14.py", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 307, + "language": "python", + "outputFile": "python/session-lifecycle_14.py" + }, + { + "id": "typescript/session-lifecycle_35.ts", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 339, + "language": "typescript", + "outputFile": "typescript/session-lifecycle_35.ts" + }, + { + "id": "typescript/session-lifecycle_36.ts", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 368, + "language": "typescript", + "outputFile": "typescript/session-lifecycle_36.ts" + }, + { + "id": "typescript/session-lifecycle_37.ts", + "sourceFile": "hooks/session-lifecycle.md", + "sourceLine": 388, + "language": "typescript", + "outputFile": "typescript/session-lifecycle_37.ts" + }, + { + "id": "typescript/pre-tool-use_38.ts", + "sourceFile": "hooks/pre-tool-use.md", + "sourceLine": 15, + "language": "typescript", + "outputFile": "typescript/pre-tool-use_38.ts" + }, + { + "id": "python/pre-tool-use_15.py", + "sourceFile": "hooks/pre-tool-use.md", + "sourceLine": 27, + "language": "python", + "outputFile": "python/pre-tool-use_15.py" + }, + { + "id": "csharp/pre-tool-use_15.cs", + "sourceFile": "hooks/pre-tool-use.md", + "sourceLine": 52, + "language": "csharp", + "outputFile": "csharp/pre-tool-use_15.cs" + }, + { + "id": "typescript/pre-tool-use_39.ts", + "sourceFile": "hooks/pre-tool-use.md", + "sourceLine": 96, + "language": "typescript", + "outputFile": "typescript/pre-tool-use_39.ts" + }, + { + "id": "python/pre-tool-use_16.py", + "sourceFile": "hooks/pre-tool-use.md", + "sourceLine": 113, + "language": "python", + "outputFile": "python/pre-tool-use_16.py" + }, + { + "id": "csharp/pre-tool-use_16.cs", + "sourceFile": "hooks/pre-tool-use.md", + "sourceLine": 149, + "language": "csharp", + "outputFile": "csharp/pre-tool-use_16.cs" + }, + { + "id": "typescript/pre-tool-use_40.ts", + "sourceFile": "hooks/pre-tool-use.md", + "sourceLine": 170, + "language": "typescript", + "outputFile": "typescript/pre-tool-use_40.ts" + }, + { + "id": "typescript/pre-tool-use_41.ts", + "sourceFile": "hooks/pre-tool-use.md", + "sourceLine": 190, + "language": "typescript", + "outputFile": "typescript/pre-tool-use_41.ts" + }, + { + "id": "typescript/pre-tool-use_42.ts", + "sourceFile": "hooks/pre-tool-use.md", + "sourceLine": 213, + "language": "typescript", + "outputFile": "typescript/pre-tool-use_42.ts" + }, + { + "id": "typescript/pre-tool-use_43.ts", + "sourceFile": "hooks/pre-tool-use.md", + "sourceLine": 240, + "language": "typescript", + "outputFile": "typescript/pre-tool-use_43.ts" + }, + { + "id": "typescript/pre-tool-use_44.ts", + "sourceFile": "hooks/pre-tool-use.md", + "sourceLine": 257, + "language": "typescript", + "outputFile": "typescript/pre-tool-use_44.ts" + }, + { + "id": "typescript/post-tool-use_45.ts", + "sourceFile": "hooks/post-tool-use.md", + "sourceLine": 15, + "language": "typescript", + "outputFile": "typescript/post-tool-use_45.ts" + }, + { + "id": "python/post-tool-use_17.py", + "sourceFile": "hooks/post-tool-use.md", + "sourceLine": 27, + "language": "python", + "outputFile": "python/post-tool-use_17.py" + }, + { + "id": "csharp/post-tool-use_17.cs", + "sourceFile": "hooks/post-tool-use.md", + "sourceLine": 52, + "language": "csharp", + "outputFile": "csharp/post-tool-use_17.cs" + }, + { + "id": "typescript/post-tool-use_46.ts", + "sourceFile": "hooks/post-tool-use.md", + "sourceLine": 87, + "language": "typescript", + "outputFile": "typescript/post-tool-use_46.ts" + }, + { + "id": "python/post-tool-use_18.py", + "sourceFile": "hooks/post-tool-use.md", + "sourceLine": 105, + "language": "python", + "outputFile": "python/post-tool-use_18.py" + }, + { + "id": "csharp/post-tool-use_18.cs", + "sourceFile": "hooks/post-tool-use.md", + "sourceLine": 141, + "language": "csharp", + "outputFile": "csharp/post-tool-use_18.cs" + }, + { + "id": "typescript/post-tool-use_47.ts", + "sourceFile": "hooks/post-tool-use.md", + "sourceLine": 161, + "language": "typescript", + "outputFile": "typescript/post-tool-use_47.ts" + }, + { + "id": "typescript/post-tool-use_48.ts", + "sourceFile": "hooks/post-tool-use.md", + "sourceLine": 189, + "language": "typescript", + "outputFile": "typescript/post-tool-use_48.ts" + }, + { + "id": "typescript/post-tool-use_49.ts", + "sourceFile": "hooks/post-tool-use.md", + "sourceLine": 215, + "language": "typescript", + "outputFile": "typescript/post-tool-use_49.ts" + }, + { + "id": "typescript/post-tool-use_50.ts", + "sourceFile": "hooks/post-tool-use.md", + "sourceLine": 241, + "language": "typescript", + "outputFile": "typescript/post-tool-use_50.ts" + }, + { + "id": "typescript/post-tool-use_51.ts", + "sourceFile": "hooks/post-tool-use.md", + "sourceLine": 263, + "language": "typescript", + "outputFile": "typescript/post-tool-use_51.ts" + }, + { + "id": "typescript/post-tool-use_52.ts", + "sourceFile": "hooks/post-tool-use.md", + "sourceLine": 298, + "language": "typescript", + "outputFile": "typescript/post-tool-use_52.ts" + }, + { + "id": "typescript/overview_53.ts", + "sourceFile": "hooks/overview.md", + "sourceLine": 27, + "language": "typescript", + "outputFile": "typescript/overview_53.ts" + }, + { + "id": "python/overview_19.py", + "sourceFile": "hooks/overview.md", + "sourceLine": 55, + "language": "python", + "outputFile": "python/overview_19.py" + }, + { + "id": "go/overview_5.go", + "sourceFile": "hooks/overview.md", + "sourceLine": 87, + "language": "go", + "outputFile": "go/overview_5.go" + }, + { + "id": "csharp/overview_19.cs", + "sourceFile": "hooks/overview.md", + "sourceLine": 127, + "language": "csharp", + "outputFile": "csharp/overview_19.cs" + }, + { + "id": "typescript/overview_54.ts", + "sourceFile": "hooks/overview.md", + "sourceLine": 174, + "language": "typescript", + "outputFile": "typescript/overview_54.ts" + }, + { + "id": "typescript/overview_55.ts", + "sourceFile": "hooks/overview.md", + "sourceLine": 191, + "language": "typescript", + "outputFile": "typescript/overview_55.ts" + }, + { + "id": "typescript/overview_56.ts", + "sourceFile": "hooks/overview.md", + "sourceLine": 211, + "language": "typescript", + "outputFile": "typescript/overview_56.ts" + }, + { + "id": "typescript/error-handling_57.ts", + "sourceFile": "hooks/error-handling.md", + "sourceLine": 15, + "language": "typescript", + "outputFile": "typescript/error-handling_57.ts" + }, + { + "id": "python/error-handling_20.py", + "sourceFile": "hooks/error-handling.md", + "sourceLine": 27, + "language": "python", + "outputFile": "python/error-handling_20.py" + }, + { + "id": "csharp/error-handling_20.cs", + "sourceFile": "hooks/error-handling.md", + "sourceLine": 52, + "language": "csharp", + "outputFile": "csharp/error-handling_20.cs" + }, + { + "id": "typescript/error-handling_58.ts", + "sourceFile": "hooks/error-handling.md", + "sourceLine": 88, + "language": "typescript", + "outputFile": "typescript/error-handling_58.ts" + }, + { + "id": "python/error-handling_21.py", + "sourceFile": "hooks/error-handling.md", + "sourceLine": 106, + "language": "python", + "outputFile": "python/error-handling_21.py" + }, + { + "id": "csharp/error-handling_21.cs", + "sourceFile": "hooks/error-handling.md", + "sourceLine": 142, + "language": "csharp", + "outputFile": "csharp/error-handling_21.cs" + }, + { + "id": "typescript/error-handling_59.ts", + "sourceFile": "hooks/error-handling.md", + "sourceLine": 162, + "language": "typescript", + "outputFile": "typescript/error-handling_59.ts" + }, + { + "id": "typescript/error-handling_60.ts", + "sourceFile": "hooks/error-handling.md", + "sourceLine": 188, + "language": "typescript", + "outputFile": "typescript/error-handling_60.ts" + }, + { + "id": "typescript/error-handling_61.ts", + "sourceFile": "hooks/error-handling.md", + "sourceLine": 215, + "language": "typescript", + "outputFile": "typescript/error-handling_61.ts" + }, + { + "id": "typescript/error-handling_62.ts", + "sourceFile": "hooks/error-handling.md", + "sourceLine": 232, + "language": "typescript", + "outputFile": "typescript/error-handling_62.ts" + }, + { + "id": "typescript/error-handling_63.ts", + "sourceFile": "hooks/error-handling.md", + "sourceLine": 263, + "language": "typescript", + "outputFile": "typescript/error-handling_63.ts" + }, + { + "id": "typescript/error-handling_64.ts", + "sourceFile": "hooks/error-handling.md", + "sourceLine": 302, + "language": "typescript", + "outputFile": "typescript/error-handling_64.ts" + }, + { + "id": "typescript/error-handling_65.ts", + "sourceFile": "hooks/error-handling.md", + "sourceLine": 326, + "language": "typescript", + "outputFile": "typescript/error-handling_65.ts" + }, + { + "id": "typescript/skills_66.ts", + "sourceFile": "guides/skills.md", + "sourceLine": 25, + "language": "typescript", + "outputFile": "typescript/skills_66.ts" + }, + { + "id": "python/skills_22.py", + "sourceFile": "guides/skills.md", + "sourceLine": 47, + "language": "python", + "outputFile": "python/skills_22.py" + }, + { + "id": "go/skills_6.go", + "sourceFile": "guides/skills.md", + "sourceLine": 74, + "language": "go", + "outputFile": "go/skills_6.go" + }, + { + "id": "csharp/skills_22.cs", + "sourceFile": "guides/skills.md", + "sourceLine": 118, + "language": "csharp", + "outputFile": "csharp/skills_22.cs" + }, + { + "id": "typescript/skills_67.ts", + "sourceFile": "guides/skills.md", + "sourceLine": 149, + "language": "typescript", + "outputFile": "typescript/skills_67.ts" + }, + { + "id": "python/skills_23.py", + "sourceFile": "guides/skills.md", + "sourceLine": 161, + "language": "python", + "outputFile": "python/skills_23.py" + }, + { + "id": "csharp/skills_23.cs", + "sourceFile": "guides/skills.md", + "sourceLine": 186, + "language": "csharp", + "outputFile": "csharp/skills_23.cs" + }, + { + "id": "typescript/skills_68.ts", + "sourceFile": "guides/skills.md", + "sourceLine": 278, + "language": "typescript", + "outputFile": "typescript/skills_68.ts" + }, + { + "id": "typescript/skills_69.ts", + "sourceFile": "guides/skills.md", + "sourceLine": 293, + "language": "typescript", + "outputFile": "typescript/skills_69.ts" + }, + { + "id": "typescript/session-persistence_70.ts", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 28, + "language": "typescript", + "outputFile": "typescript/session-persistence_70.ts" + }, + { + "id": "python/session-persistence_24.py", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 48, + "language": "python", + "outputFile": "python/session-persistence_24.py" + }, + { + "id": "csharp/session-persistence_24.cs", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 87, + "language": "csharp", + "outputFile": "csharp/session-persistence_24.cs" + }, + { + "id": "typescript/session-persistence_71.ts", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 125, + "language": "typescript", + "outputFile": "typescript/session-persistence_71.ts" + }, + { + "id": "python/session-persistence_25.py", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 135, + "language": "python", + "outputFile": "python/session-persistence_25.py" + }, + { + "id": "csharp/session-persistence_25.cs", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 158, + "language": "csharp", + "outputFile": "csharp/session-persistence_25.cs" + }, + { + "id": "typescript/session-persistence_72.ts", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 170, + "language": "typescript", + "outputFile": "typescript/session-persistence_72.ts" + }, + { + "id": "typescript/session-persistence_73.ts", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 238, + "language": "typescript", + "outputFile": "typescript/session-persistence_73.ts" + }, + { + "id": "python/session-persistence_26.py", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 248, + "language": "python", + "outputFile": "python/session-persistence_26.py" + }, + { + "id": "typescript/session-persistence_74.ts", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 263, + "language": "typescript", + "outputFile": "typescript/session-persistence_74.ts" + }, + { + "id": "typescript/session-persistence_75.ts", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 274, + "language": "typescript", + "outputFile": "typescript/session-persistence_75.ts" + }, + { + "id": "typescript/session-persistence_76.ts", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 296, + "language": "typescript", + "outputFile": "typescript/session-persistence_76.ts" + }, + { + "id": "typescript/session-persistence_77.ts", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 321, + "language": "typescript", + "outputFile": "typescript/session-persistence_77.ts" + }, + { + "id": "typescript/session-persistence_78.ts", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 366, + "language": "typescript", + "outputFile": "typescript/session-persistence_78.ts" + }, + { + "id": "typescript/session-persistence_79.ts", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 428, + "language": "typescript", + "outputFile": "typescript/session-persistence_79.ts" + }, + { + "id": "typescript/session-persistence_80.ts", + "sourceFile": "guides/session-persistence.md", + "sourceLine": 454, + "language": "typescript", + "outputFile": "typescript/session-persistence_80.ts" + }, + { + "id": "typescript/index_81.ts", + "sourceFile": "auth/index.md", + "sourceLine": 28, + "language": "typescript", + "outputFile": "typescript/index_81.ts" + }, + { + "id": "python/index_27.py", + "sourceFile": "auth/index.md", + "sourceLine": 40, + "language": "python", + "outputFile": "python/index_27.py" + }, + { + "id": "csharp/index_26.cs", + "sourceFile": "auth/index.md", + "sourceLine": 66, + "language": "csharp", + "outputFile": "csharp/index_26.cs" + }, + { + "id": "typescript/index_82.ts", + "sourceFile": "auth/index.md", + "sourceLine": 94, + "language": "typescript", + "outputFile": "typescript/index_82.ts" + }, + { + "id": "python/index_28.py", + "sourceFile": "auth/index.md", + "sourceLine": 108, + "language": "python", + "outputFile": "python/index_28.py" + }, + { + "id": "csharp/index_27.cs", + "sourceFile": "auth/index.md", + "sourceLine": 138, + "language": "csharp", + "outputFile": "csharp/index_27.cs" + }, + { + "id": "typescript/index_83.ts", + "sourceFile": "auth/index.md", + "sourceLine": 183, + "language": "typescript", + "outputFile": "typescript/index_83.ts" + }, + { + "id": "python/index_29.py", + "sourceFile": "auth/index.md", + "sourceLine": 195, + "language": "python", + "outputFile": "python/index_29.py" + }, + { + "id": "typescript/index_84.ts", + "sourceFile": "auth/index.md", + "sourceLine": 245, + "language": "typescript", + "outputFile": "typescript/index_84.ts" + }, + { + "id": "python/index_30.py", + "sourceFile": "auth/index.md", + "sourceLine": 256, + "language": "python", + "outputFile": "python/index_30.py" + }, + { + "id": "csharp/index_28.cs", + "sourceFile": "auth/index.md", + "sourceLine": 279, + "language": "csharp", + "outputFile": "csharp/index_28.cs" + }, + { + "id": "python/byok_31.py", + "sourceFile": "auth/byok.md", + "sourceLine": 22, + "language": "python", + "outputFile": "python/byok_31.py" + }, + { + "id": "typescript/byok_85.ts", + "sourceFile": "auth/byok.md", + "sourceLine": 67, + "language": "typescript", + "outputFile": "typescript/byok_85.ts" + }, + { + "id": "go/byok_7.go", + "sourceFile": "auth/byok.md", + "sourceLine": 96, + "language": "go", + "outputFile": "go/byok_7.go" + }, + { + "id": "csharp/byok_29.cs", + "sourceFile": "auth/byok.md", + "sourceLine": 143, + "language": "csharp", + "outputFile": "csharp/byok_29.cs" + }, + { + "id": "typescript/byok_86.ts", + "sourceFile": "auth/byok.md", + "sourceLine": 312, + "language": "typescript", + "outputFile": "typescript/byok_86.ts" + } + ] +} \ No newline at end of file diff --git a/docs/.validation/python/__pycache__/byok_31.cpython-314.pyc b/docs/.validation/python/__pycache__/byok_31.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1fb38c297fe3133eaad185ead252794a21724d6e GIT binary patch literal 2044 zcmb7F&2JM&6rb_V+8ck7gd`3ai1|vjgm@bVL#Cv@}D}<4S(s*5ax;C)Etn!hoc1W~j0-&^s_UydH!UZXfD_UCeCeMvZDLG>uZQ z_vTTr_6(BI4fuWw7r05@4^hCMZ}vv87uh3oGLd=NJL9c?mwmDzx6BB2Jyq>@U8`}~ ze|YDXMIw@?-l68)7M^KzH^uhXG`4zda?{)(mID!#6)ev*PPH|;f;!#E1AD@$?eBWX zK{+Jh|Ei`3UEork@2>iv&f!$#z5G#X$NTupXg~6y$)_-vVahOvVfMmoJ<91=3{O#h z&dg}peCV3x_8*NW`c+VGQNgm!1wEtLl(;!dquv^*sBl$rwDi24rNT|!*3ycl(-wfD zWg3p=P#@^&SuIDmji0|bH6~w5pGuuge{%Yg+Q1pq&(OuXyFq~r;{rnvNX;V!IBgy> z`sj0nGW!tPg=QM4gY^xBZLLT(P_|{OpB>ya&;Iwxi>rB|>RsppP6f6i)}{I>*CMm% zBA0Jd97lIt#c<7%3w?N0Gi;iYHlBKw|uFgtuY&SI3btJX+bo4u!St(d$4l9h9>1G}0tXVZfNaVtj!(@59Ccg-of5g*Q)s*-h1#_M*5J7)sO+XAWt zT9<~3L*+npB@iw3Bvu277s0lB2bT}sKU8i%u+o0uS@2*b)V_4Nc)1+fy%O5}aL;N; zssvk?CW;f^oLlEm_`?l|g{T(_p0nJ1@U!cR8`GUwqAxKjhHM5A%0uUDmxfhaQ(P^* z**Mx($JVFk$4*bCFUphDV*>UxV?nn~13>8H3{^KNf4bT*57>yK85v4$D!NO38O?ER zGY3Z3v_wL^YW0DozRe6ayOcJ&$qsw;W3kxBb{8v%u-@1rh%M~nuRz|ufmifJXy;eyNC5LY_Him>foPeo|21l#XTRDxZr-6GHjfl9FRTYEWw zKVRB6_;cjQS_|LlU*m;7?*W>@Pz2$XXEb!Mo?a zJonYDRnlGYx3Q!Tgop7`WZViE~b7YF^1L&Yb-8_?*3*8b zx7d>*YKoYFdTy~LgO#pi_zW`QmY05LacWVqenDbMQD$bb(C6 literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/debugging_7.cpython-314.pyc b/docs/.validation/python/__pycache__/debugging_7.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b328107924eb572c8773417b3235fe56ff5b5de GIT binary patch literal 173 zcmdPqlZt2KczG$)vkyYXf(+3Vi4mKGb1Bo5i^hl005jUqW}N^ literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/error-handling_20.cpython-314.pyc b/docs/.validation/python/__pycache__/error-handling_20.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b6e6b04a14007199cc89e146d6e8e8d9c39da72 GIT binary patch literal 376 zcmdPq^pv<7j=%>kci^DlFCnqr}C-s(?Yf({tk$-Y>X;D#XibsBawr5^JX~``< z2(v6dIk6-&KkpW&V|ij`30R9bh8F+Q5|ADdREfmAl$_L}l?b{D^o+O*EIKz> hcrWm&u3)*!r*oA>7bwfB_m!Dhg6R^2ND(JcJpdrnYGD8X literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/error-handling_21.cpython-314.pyc b/docs/.validation/python/__pycache__/error-handling_21.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..483fd621ecc41de10efb38821f81ffd7c6ca288c GIT binary patch literal 1042 zcmZ`&%}*0i5TCc(c1v5@07Xkr5gzdMI^y51PLK)B32-o^ z9*prq;)Ns83*J0>^iNn5>c>XCaN>s4#Bg)AwD>*An>Qc7`FOLlsc3x&kY0Z->R$-J zj;GYfR~5=vP*{U|Ad^wBLFQV(CbKYE^Vjfrx4|rFgPy9T2Qzw?>*#PN zr8`WcOtKW4>gs}IQFC5XZ6>LvrRPn%i{%!ioT)M?y`g$G2|L`FN73H@~)t;6+_j{N&%Or1>+@@5eA3FgM*7^u8`M; p=n1rWyUk7`+v5o#I}qLX)e&Lu7?9xOa54Pk+S42Fpotzw#1CQ+>s0^% literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/getting-started_0.cpython-314.pyc b/docs/.validation/python/__pycache__/getting-started_0.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..431757c4c161fb15430bbd65457990afa8f149f9 GIT binary patch literal 1047 zcmaJ=%}*0S6rbtN(o$&aM@wr%WRZ)dw5tU1LTD@oNLr~p0kc0bB zf*d)$#1<>gTB;SD43Yu+|L4OKcXa?m4H|1QqjVDk6 zEyDdXToI;3KU9Hu@jTAe3b^2ru?zEJmW5|<-s{Gm%YslK|H<;qw!5)2o_urEu6-u+ zoqyYog?v#7oY@e-B%QV1rdPtJQ^YR0#*;KX^X6x#b44@V@ zl~Gwedle~KT9QkqO6BwurL03AKp|VJYyrf)#+Yu*r z(!Uew-^|sA$Lq<7-AJwx%2jedNc*ds8>wol;qTe;_k1SO0aQ#@leJWXL_d+}NeGG8 zz6Ud3L%9aG0he6*C;B1_12fdCC ze&Detk2^dea<4*H4OKUtNjLwQ=Bk?C$_0DHc#BS<7qTw{EM=>%+1e-)k<6Z3x zNr`%J=^;f(A;PR#1&D(k3d+(b! zJK7cSAsD|LZ0TVEq1Sxl46&u0d;v-o-A4+}Alj6eV%WPfuA2fCBHSiq#G4Y8B1jQK zh`R5gY?lMnkt67ydjw6i3=_DifDgWmV$vJFU5sHCNE@bJHfXx6YZVHHo}5OAZd7I; zz&^ieYQ+|WE!?nv3-jb70K9}EknBG z&}HO73#%}1!Mp@ho)mN(^DZ)J-6(10N1kPqj!(p|vI~S-n!2u6mh;6ng%FGr*9Y@t z8mv`L&G`(_lFKn>o!)T_AV2vWp^}2o5L)6FW{<4b(K<5wj^ZGm+&STB@9Hpzw#ffQ z>2**#(xK3%xMOZ>r|SElZEP!ceF3|^e#h8B=>b!p!VKKFI{KNtm0^lCeRV^w83&#>A3JRTh9NqiUgOR46Ywe;dz!nBN4tw>3t*nDu~q_mbO z8AXzaKTyj$M1x0{FgNK6h-HmZXpC_}Rf}q+!qvFB$>bHaQYvc&I|>_ISM^GKx@;8H zGPxc<{f+ZY?!!_=`~IHYYunfA;aDS_tc8wy*s}>-;jrD^3eCUf4uv{-Nwbq z+QrGbJoTS%b$R%-`&2DFRrkY@-Y0X%0+K&Ife47Xp|Ew6J__cwayh!LMb#)-F)SKg zHP*D4+v4raB)bsSRfLYGT7fiwG0bIDSb%7iQUNL}JXCecL_!TSCNOu={vk0>>#W5u znsBgaG-?GosK^?c+`a?`SJWW^WS}47l#ggy$xTa=8HTV z*c(mmMN_}~(hV`aC#DYpe{_3vXS^YXUW%dP50Ml;76IpY7)dkuFER8FNkd9o!>K;} z45$3!PeY*nicW6e$8f4!d_Eom{e_5Az2XbW!}S2>Yq!1j@-^mV9+hlXin?L( z7t1`Y9%_;sZSCUAT1B&f-%`9qTC-J%-TgLEOt3a8KO-vyC`}T*)9_o`C~McPD`4ZT rOSp0*V2od*u0N6Q0F4}=Pv46Dc;G0Gu=lZl%fCIdbK?)xXXE?}#=K?T literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/getting-started_2.cpython-314.pyc b/docs/.validation/python/__pycache__/getting-started_2.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bac8d7c31ac6396617054ed3fdc569c2111e8d75 GIT binary patch literal 1005 zcmah|K~EDw6n?uc-4>Pw6Kg|5LX81Zq^xN;2q7dy8bczrX{+%7smtyL7Rv5sW{P1? z)q{o;9`WSGgWT|>Kcfu|kcpo32Y~zmXLehZhQxPxJM-T6zM1#F+51X=FEIP|_TsMIiwsbTe`_^cS}(-i7I)2u7eN-h*^V zZ?pK}F!TJh%PezsSh>m-;W-pUA9KygkQF=pj7{*Q+>U9J*;HDjJub3rLc?U&H4g>a zWAY507FcoJ~_FSk)cZsyZZtjV;x1bgWM8XjRM5h~?O-yGu6M zXWb;kvez@1Xo#3bB|GKr(&$`O+g>xYc@$+Q@FwtW=IZdN_W9LO?W_02JE}G^k6Po4 zmn;r9_x;N+VZCxlm#tj&U*L1%ft9O~tJKDu7Fed*6 zT?ZHB>wCWYSE1k*f$rWw$;6mVHD%$HWmHWsw#)+Bx;dN5rzON&q=RjYFKU_TNaa$l zR9bqPuPiM-$ss;wdTW72O67%oxw6cX3y*U&%mmY@q&qfYnxh^D3xr2}HdNlwY<6PB ze-UVqg(4imhhB#>Nq*suv;XokcN5noozRgoAde=-9NcX5-o#){(Vl z`sW{l4-Bpso!fSdTGgCKaaPP9Eav~ic}Nh1^9T&w+27pTYz{3RE4g~#??_m9a4xr_ T2gAq8SiSEe0)qUu-{<@T`&Gmf literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/getting-started_3.cpython-314.pyc b/docs/.validation/python/__pycache__/getting-started_3.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f59f1ae24d958249bcc8b1f87cab94f8107ecf62 GIT binary patch literal 3303 zcmahLT~i##ab`d6j{AT^;!}m-KqWa>n7c$mvdWTiz#u+?;Id$xID)P9-6B?6cGt6W zR*vN1f>WgsRYg=PRUvsv{3gHYArE=9^a~)S0v<~hRs5vN3kX#yeoN0RhfY^=rK`5L zXS!#myQjOSd+QTX1n~FAtJZ&1gudZ}3cy&v!58o=qXnelaYTbZrdW(6D#2eGm&X*U zba9?Mu8xIhNYKi7cq~FAf>y`t#-cPj7NfB))Qq~37HUOWcs|-M2glI(d?5v`v`xz59>s$VynukS_`+5W>_xhwaE$2LnJD;H!B=v4+4mF)Ftp7tJeR8P=qVWmKI*=ddP&Z4nyM6dImGG@_}XXNV<7 zP5Oap&?S@P3}P(%D{ss$nJLFuHdF3m3g%OJi>Q*3{T6D?h!WKVIERTW# zdG3KjF9;pErw`5mx{S+c4lPI*e~nN9W;@W2@ePJNzyQv0bQi05)e$`$AM#H zpAzsz2u@lyC`;&i-Zp%{VCAW<`&_iA%yQZHeUtcE&!EK0-^_Z%y)>)e;HS5()R-9pjkG@SBr(XbCW4Z6N) z5ue%+7mlmzBn-<*Js{Rtb>3pp$-~-aFdx*j^14C6>W_-l^kEt#j~tXYZClsVm^8v3 zKEIS7l4E?&x(X7ix55ZiFQc!L&6_s9384ARtT>{Y3rQ(l$fqi(ctb|Ke)Xr3p(G&IN0s)24aCsitmr)YQ%vUpC8L!CP- zY08|El~1AbvV|dURln#sr65RR)LiyVVt|v(B2T-A_ph+Jyz3M!9`9*|oPtRf%G++S zP+}@EET^=R0Pj+}lnQ1+NCaGn7*4@mW?}xf915$JTq|#;Rl+?Q2t|+f_L;&DC#Qku z^BR681t9K&#UR1-!-7HjfY-o#7PYryx zRT`AvFq-@rzG?V+;ERhetD9mf)GX6p319bUUw`HYtPaYuX)HtCoMkG1!~9ngh044fCQ5rbilM|KTVyw~;rPT?iA z1}dHup045XVU>Nn>ehg;5AFx-<3(1$%N_Y$@Gp(0(lJOb=m-c8Io3KjGc!IjJ2*9~ zUmcm585|wahesx72jQVC`7Gqqf?K3ay+tf)LWwk}!4hzD)X*VWDb#JIF4{$ZiN$AN z`S|pdK0Z7-!c>nymcx6in!E!M_4G`Tzwsp~0q|T220O6~RU>oRcJqeq4`ix&J)obz z0H}<1W68U3uf4t9p5AF6+-e`(jtxGFH{6|Ao7jnWY{fe^-v7&ofBJCeChxwv_U4_;j?%WN zv^{A$vD1{^YD(`$8rIu)BgfZgf%-%5`pLbp(i=KJN^|%HQX0bL(Pwd0ZQ83xYW()Z zuO@!;%Wb9ONwje%+O-w!+KnVPj}7k0Qa3D-Vz5L~!+Qcn5LDFOwca~@J4)+6l-B)T zq_*!Xu;qRy2<=CZ+V-tK0$Q$i4xPY%#Y4xG&rSjLK*2*z$^$jS>2r9fMS0NQ3iQJm z9%@q_#>1R$!W_2<+{SS_$-;(Ta`Ki-z6YC<^MF|Runh}*pEw+4MA;xb^;xPicinXO z3uYEFhb|7n&JTh=;*|=913eGn1vco9L@&di72$LylcGaf_)xSiJn>lMa?o)NkZBn5 z`tSb~(4LGj{sz^5jS^p@=wsCV7@dBM-uV|g{XB&6RlHt$4o%Qi3{H{~o9*vxHr> z%)Fj6X-`hq3Lrcl$&!8SUoS(a`ZeIEchUCe7Sj~#eRwX}0)R?FE!zpmx7 znQiwXzOvcq20#T{O(2S81hxrMZa*^71P_{F+2d+Pg)#IKEOVfnpL%7U`o<9T%L2&h zwW9+Xy`ZUdN+T(isMFR=dwNQf40T$Q%t;CGQbwmmiJHT1VYY;`f{HS2W(zq6!!7R@)Ley9 zr6`j+v1ktB!Y~zu_~3IAfyu7kcHd;d$iTNXpgxGFXB3r!*6$XmW&s*FHw~20aydnb zVNwleSj;IuC41PJ0e5mluZ10mUP50-YZhA1E=7k+z0aBaA0blXa?Z4Z4a#v)AOwPR zdkjdb6CH#d_u>F}1t>3azl_I$QXaBrocYrk2@iw*scX#e(iFqqoQ7(+fp>e?%Fk4(3r=~Bza!O zWAKW{xDe#I*E}*m#wWNobez*Myj#I47)G%iBqG(O^BPgXNLqnCyD#tc+kuQ}WOWwr zF`l#m()MO@W+7X&1)}OkaV8AbrMaS1#sZTQa9*MsS##R@kXX=oL8 z-M{IcZ=HYlf!I>&U5)PlWBB*s`Ku42vC`m5XwU85`D1r`@1D4~_in?zUwl5eAdW2X zBR^Qoir15Yq=+*BZ4N&`jw26)>C28Bcazg*(#}I#N-=xw8g5b_Kr*@t^bc`~8y12P z4#4jgs%_t}WGizrFAL+FPL1OP=elzDIeE;=QQk9#Q|v+R8e1XIjK)QmDEr*gc3}Nm z*n{XG8fPYUh8%Dyc`nVRSR&XpTrK6`>lYz0gPj`Cxq)$(C!CSm=R#X+ilvNQLl)he zno%03>UWW0D~Hlt0=rzht+7L&u*=nq&R#_*jZz1He4Z=$k57`JkoeH>L->6vp>Y<` z&hVlv_^kmv*oe*^MMy`TTqDvk@Fn5bd)^anxD|vdXBmSx#fFh)+(@-VS zw!kX3wIf}y*kK80RvF*vfAVD~`PczxJVkgC-ch^X5M#2^W?h9@0Tqw1v zwTnS$%c}q9mj4ka(At1?*)N7!W#cJyD}+4b>G&{5$ zYFG?4%)kBdr9WL-Zalu&czh{zVh8PEsA*k5p|`M89ty00t$qC4zy0g8IZ3K?N>UPf zHYmbS3}0qeklM8mb=uCFr1uLtjm-=}5=@igDXIO!luFwzr+&J+`Ji3UTAlw^VG({ScI@xgsQ-L z89S1JsD%c`D)*L7^0hstVGDV}a=M@!d2ooo?|gqBAttefoOw+nK&kfr%A> z)$oB^N~wP(7@a#hd-PU(nXg;m>mKhru)Hs}xG%Qiuex2o;@^8a4bUHs+-_X+@khKH zh_CTIM|_p9H1IUU3C(LkB!q4Z{c7muFPHd+@A$w%uxp7wy~=&h!N{723+!2~ zZ<@dMm!_LTYkm~kzbqbH6c0WS8}IC265Cfo)!+HWx!`PY*eqP??E7bj zQMB$E!ht<@sCtcq_226e6zE#_BBAaFD+~HxZ|beacW}>1{;zESeZk|NH~24v1cQ%@ zJ)P)FloVleU&Os({(k5s2ET%PtN8n``WXBMW^!y>`}4&tJODjI zSj{W9tWJB$D!t=vn}Ol2n`D*6_IH(=;BEp*&-uS#T>=2igz>j1@(l`qgMyDx z%OiB?5jy=3bm$q6@i~0E2nK}}Z0HFu)Sq6$-OoI%wcFs3=gl<-d>U!Nb!+_?VgC*B Px;Wc=tN$U|>)icc7-cZE literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/getting-started_5.cpython-314.pyc b/docs/.validation/python/__pycache__/getting-started_5.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8638472f2691d251cd4aa756770a914450f0cf85 GIT binary patch literal 717 zcmZ`%O>fgc5S_KxaoP|=)S!mXrUVXF(pW%xL4XvBS`bwgS)#WRS+>=>b!}^Rg9xW6 z98lE*H+}+$f4~XEKPW;X$Wjler`}R>;>I|Q)e|G_n~#0-W^8R$%TEK^=fl4DfB+mN zNosTwj2>aogBM_ury#(TWTso{$K$byPGZQ#MGd6_It)QquM_pUzwXlWxlZuSic`Ri+aS(o)ZOY4ksS zB$>1VDy&||lUJBRwo zUi=xtG5+#Hdh2)o@~>>+V5TyZrK_0{NSfMP9%dj{cvsu2?bipibU;g3xOiny)V~+? zAI0iGtM*q;R8TIRWZ-=5FP}rb{>|nT`9PWq{Wy!!7t&PeR~4ggDnZocShaXJu)T1+ zM=Y~W@CioP2`q;YXYcQZPRDm2vI3^b6XMqphB6`K2(&+RiqwWBAlbLMes1sa{_;&|H#0l$z1?BwwM-glJ-oKq8^!mqh?d$zH@dR4;e(nKiEW`j**UpQPCz9~7gs)oBT(xmbNK+dhL?&g!3Pchs?L5TK$~cvG)ph( z;hX$*zFl}$#~#(OA2CFvRxXdXIH%qv^E6YCG)2R;nAdd*6n^I3Lx*UN0Uo=fH6*Nl4*5YBcX2CY#K|EMV6>2F9_GDeQyGuIFc6XVXNOKGE zAf*Sd{tJTM{X>eDfgYr%-hw%K^G%!82m8JEX20)ykC}({+6-WPKO3>v1mIjZWf;?9 z@*ImHyaS)S0ttTQCP=aaTjl?fk9iSx$ReyxPgc=U$6Zt|flDuRvl(eD!@}YNev=I0 z9x}^0FG+#jHahy1xBn*j)Hl3J>06L(vSpW6|8qHi9ei`20vwVd-7shL9_A9*uwk_+ zBd*0OsBwv^t>pzvbGeqXB$H~k%j8~vH;{QR$<$n5Bte>YyGb0dEWnO;HeEy6(Upkn zpiO@yxjYt9JX;xpC5T zPo4SC$=Iax)&ywX9(KkKR2!d`kCu;HKaJ*z(flK{!RSGod?hQ!H@i(-s_aka%(&X#Q9hqRgYdAcYeTi IehnFa0dsqccK`qY literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/index_29.cpython-314.pyc b/docs/.validation/python/__pycache__/index_29.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55b68f0bba56a74226498aaab6d20054ef5dc96c GIT binary patch literal 537 zcmY*WO-sW-5S?k#533D=2P-1B77x+dfapOG4=R3uh!pf>m5>D7T9dH5N_#8yAku?B zLNERUe~73AJbCiuM^E0Iw2k1xzM0v1@9hpdt7Xza>*2M_z>EPcaV_%)>(eWC450BqzH@dR4;e(nKiE<$_IPUpQPCz9~7gP7R-XRmYOT=v&MQ`_!;K zOBkgKv&L*wGS4;qhCHFbT-&K1&o7nyMxdUV%;f{*8eS@L1n)Hbt2+Ia0ByW|+}wCc z58o88i|x|0ntfEWKVpbTt$Y!0aYnsM7HOs+X^MtxF|X?sDE!>LhYrzzrwD@7@|kC! p*PIouQ5k-Rm>~F65b+JPZ#9l%pBiB5YOpnUz24qoZP`!hr{ literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/overview_19.cpython-314.pyc b/docs/.validation/python/__pycache__/overview_19.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f1b3fe02ea50827690a6789ecb38dab8328dcc1 GIT binary patch literal 1698 zcmb7EPjk~&5PwgSE%{HJ*iIWKB(O%+W(a7o`qDY$e zNpirRb~@b|?c05C-|qf)_vv_M zD2af6f4*%z;1PPklpYC@u>S=JTj)Ea;1%Q|g&RXIzJ@OK&U^N-meDm_Mhnr-0uF^D z+?+ub{v}iET67vL9Pl0Z_KyKm@iZzPL^_XcTtp3g60?Y=()mc9%^MyK{gJj@F4Tx0W1bd5tLX1EAa-Whz(xmW!$U8pif6o&10gKW)q|uJfS}+L6Fp;u(rBLR1%rekO&Llb7VXy1727sTnrfPQYq8`@E~s^N zP4{z-PSy-c4cj`WYX)2W7?{}`yV#F8#IW35&QBVa({`IJ)m53iZfmLwmXxJCJL_MN zzo9yzvZK1h&{k!K*f(^|rLq?GXpXj4<(92cxw@{J2DpLCva{)4hs9pk$-1F$G(SFF zbvFHB+iE&QZ?X)VZL0gn*Hpu*)=Y?L(zDfmZNNAM`OqW4UcxN>na=+5^}P@8fBR(m zlvh6OHjZ#RB}ElInim`bfM%)21p6C zI$KqFM8!OUas~y{pqv(SOmH- z(GQw6GMKd-2q9<%=IdaBI6telS_bQzYA)NBtKW2QO|h<*pjqET^Glj-!TjhY)uJ1q zS9kvfA=QIvYf@JwuK!;M`>gW}VKze889nM%&U^V4FTE0>iit3@*KK>1k`b^Xql}FM zt8jiSjF-`fuDW_N@>_}faV_|R4BYU=$bzsTp>bd(Mq6R41l9^a*WVDPiOhNx*k7y* z&$1ufE&dqqWJZ5BZ<}|lr_!V+P3{R?;^dyhB?@~IPF%pJUmyy_x{|4J|{wokL4`{3~7>7JjRM z^iaY}S>a(qWO5b*uR{^U=s^acDjX@n#SkDHfYRpyxNw&p1<*4f1Yn*EM_vo>#ULKr z-xleeTYef1o^JZ}@M}@`-@} literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/overview_8.cpython-314.pyc b/docs/.validation/python/__pycache__/overview_8.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..69aa04e73612b4e61e420976b0d8d984fa2402ea GIT binary patch literal 1492 zcmZ`(%TF6e7@ygP*BJaL@e5MoCC(wXu{V`M^PnV(0|8V-(5T^1B}JR{7B;bWSG!}V z9aTc~&>{}Wsq!&B_CM&A`~{|}iZyB^q?~dyrBd5lzg^pHnx-SoH{av;J?5K7ArcND z7(cw+HSz*NuRLKeK=#M!3M@P5GeqzbqTb3a;YE&e8ASLLqWlB28th}=SSHZ}eiB{o zYcAs+13oy5a>8p*T*+Y;zHQk?)uOknhHg@=5BHZi(63;g?t=4qlz}4d_rsvS1KVf~ zt@3ZW_4q;J1w_yzuz!Jf_+>E!Q2;Og7f&$Z2u}nek^qrNkPMMf36o(mLc$6r5fUXa z@*ZeL$r(i=alj==lB7tQjFE9b_*O+wIE5Q*_U+s@Uc;->J93{T?<@F!y}0{B1D`c+ z)jzO-+*?;i{w;gbAez75=sWCv)!Q|~0ii6C(DJu1KZSV<=EyW};M~Lt6KhsQuQtUE zn--_pa80w(?Eh6%J`>rC`@Owz1cO*JblU^nQdWiml^Ho&Q* z{1c;OHyE#*TTGmrFW*~$08U+JytZ9w4waOC9wt)Ds=5s4nM946Zq=!Asg4i}Y#4O2 z{*Vcql-i81JJsfSk9DsrifS9Bo>}YNwi1-%WmcH9sjC&JpM`JLp)kj2s?@N|X0)uU zj_$}8o_uomW5l*|eEmHe4##8nUBnaAV~KgD%z|%BDq)&kfCYc5^|;yOK;F=Zme&s24$k{7$#*xMWw3OD3d~5Cb-nHb36-Z{>xy} zz&q&Zu5FnhdO2iSW=qOF=#Hz{Ds>F)u>zGo(lzQT{oNMb%44NsX|7V*QmY2!fhv^V zK`0iS-j<i@-g5(ut*7*;c~C zOn0L}Ins@zFo?-k0POA5jAyyqF5YOLz1hchhs0E*J2sjQb;U#>aEcNM>35WfN;?bP z5=u@SCGv-fd?y%dk6!8W+!P?VBp|q$w6pkI0EwY*E

p6^}xh!%*fYK|Y3!6!r@H z#Umm0qmVk8MdH|r00B=*;Byi}V){>a9yY&wu6z?e$K@-+ceB79oWtd7!a-)- literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/post-tool-use_17.cpython-314.pyc b/docs/.validation/python/__pycache__/post-tool-use_17.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..434cdcc349906d4f310b977af35ab5ba5d6d5fda GIT binary patch literal 369 zcmdPq^pv<7j=%>kci^DlFCnqr}C-s&{Kz?yaNPd1!XmP4Xetx!RUO{QeEj|dd zEI&E1Br`wn7N=u*VrB_ggD9E?|I!kW4k2XW#JrT8)S{IPpFwW9<*yGkyQo;dAhDz< zGdWwopeR2pHMyi%KRLf3Gbg`9w>TwRKP5l8SYNL!F()$xY^8odWl2VUo_+z)dAcP) z_vw}vr^Xwa>lIYq;;_lhPbtkwwJYKVn$HNt#o9pP12ZEd;{#FI8?2Hu>@Kiq-C*Ip fz^A+*-&5TDoXM_HC4u*g@GB8FsH*$ONlA%p~DBqFY)DhCBOO}CLk**1M$B6}k1 z!5A+jUN{oH=*=U4Mom~h8a;91hOCL<<~-OEB|1sx&HUbP=J(#@H6=F00B!es**G8o z`z#48R12y%FxZ4Appe_(g2J_dOO{|h*bn%)_P`S9flLj_U`J-%SlJ6n{(vP}jrqXB z7(BWNv~2ZD7M$2%`z|G%-JP@vrne^iH%89vA4 z{>h9WGx~p~BJ{$^+3S4r*pE@2Qo}0bjC@I0k{(!=IU)Iii)&V0(@TORO*>C%fU&p~ zlO#o_Mbkwz#+avBHc9-j?HC0&$@wv(U>Dt7UUgL#uUnexq6}r@>g)6G$q%XSP}x>p z$Iw<~+p$)3&84zt*@kJk12n%X=PixO>2=jKuniW=_J+I67K^$AOn0D2_1xfi+TQRl z;1w92V|Wg6|MHq@6w;F>Dw}jFeSV+45PBco0ltlILc>fc_hH1~T=sdwWaW_L@K z%&a$j#}nuFgu9F&YK-jBQWsn3b+!uQTI`BYVQ=*T$A(8o|Eh z>G-sW6Ir&bRqBX{WN|JL%{26a>x-JBtFE4_jX%kqF#KpOKbeyxISp9mhuBS=1cvO_ zpkwIRp^vywIPo(MtzDlJ$&ZQT7opK>zUuXjdQD@8JeP`8foqNa0^pv<7j=%>kci^DlFCnqr}C-s(aKv8N)etu49ajHjtezs>`L21b?J_xfc zKRK}^Ge7SZr(=0yW(iom2&#Jj(h`scK_t<{yp){OqLmDvK@Pd)rw=r_s93)sv7{(7 zIa|M=C_gJTxujS>Ilmw?C%;6uI3-&@B|o`XU#~1NCo=_Xp?*PSNk)DiP;shm3D9x6 zrNyc7hNgN2mA5!-a`RJ4b5iY!xPitq0&%f6kodsN$jJCWMCJyo#0iWrim(iH+EA|X);M1z%VA_oPV&2|F=+uhC17KIb3 z2V=aDc;QI&qBp&H^e3zdD4FPqlQ*O$hMR9n3(8C8&6_vh_uiW~FOzIe0LrHyW%`i- z9Ed|*Vl|_38;wnP0tUGYAsA8zgk%xs>i2a#?!B-`dSRsI8NrA`dXU)%n*387a+c6_ ziKFoxSLG3^D~Q|#13JKmg*pP}Al6g1&VdZnz z-q>t3dOu3$cGU+0pl)~V+}rEaqf6JLE;LvUwcU^>t-v-zJ6~(KCRGt!shz7`NvDG((s)c%9<-w=qOvhmqRJylj_bb@ z(0=(_oA#wm+gDRjYu`>jY8gG0rA$Kwq;};GNGYW}^Gj^UtO=>*bcVdaDSWGBh$eHz zWb3X)y=r_e2POACR1gLyxz&lHS1395WFUr63?}PFbtn@;4j_3HQ;Ble21I?)SZ;hd N^=kSnTnsu9@fSwG;2Qt{ literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/session-lifecycle_11.cpython-314.pyc b/docs/.validation/python/__pycache__/session-lifecycle_11.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b60894683fa36ee00df5f17ae55a227245335a0a GIT binary patch literal 376 zcmdPq^pv<7j=%>kci^DlFCnqr}C-s(SaB6XJW`169Nn%lnM}B^`XI?>R$t^wz zvn)S3u>>f4i_@_@F|!1$LkwMqe`yIwi!h3KVqQv4YSBuD&miaA3f2!TPAw|dFGwsY z%1qAIFDS~-N=+^))=$na$jr$v(JfBN)=$Y#F4os8OU%hk0b8nHP+5|ZpQm38aiMNb zW?E`;WpYkxyrH39LFFwDo80`A(wtPgB5t4^j6hth4J1A=Gcqzh5R<#XDmBCJ0*m$y i7TybdDho=k@@ZdX(E-Y`>V9Qr7H7J|AY8-=R1W}RqiY8M literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/session-lifecycle_12.cpython-314.pyc b/docs/.validation/python/__pycache__/session-lifecycle_12.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d226459f7bd11aa1956bb9576e36ce7397103bf7 GIT binary patch literal 1326 zcmZ8h&u`RL5Pr{IuZ{Ot(rh+#QHV*>sN0Y=2}zKu6bV8>l|qy{kOK-`S+*f2j&1pQ zf!!0@9-!)_6+LjOPX*2~q8k#^p+KtmpZSezl;AmLmc94oyoN!!08h;0n z_wfUMLy(b=HGT$(Xd}JC+qjZ4pu2%c;5~+?`w~=-b+=zD0{$JW;nU>-8fBs99eDpx zEVU#g>{DoWP$eLR_mK$(Dop>cLQWGkX@}E}y^jVi8Dg2CSQcWrp;&%N++y<^l4SZS z%pCe(iTf`!rEQB4+jA8vlb%z*50_rqpERzR-p*+hY#uFzE2@U7;g;s@Rx%LuD+{;F=file)?>-uf$Q-w;2-z>%X zE#26MjB=p6U;;qo{a)y5FVf7#IL5`K!c)NyY&WE1rWFEBtxs2D>{K9OVEX`)ZP%}d zHB%3D=HK-Uot00s3EXyXd4!$R+?+zU)$7Cxi0bRG-Pl+AAfg(cZ#!PNK+JvB^bDd_ z@9K^XZ-sZMek0ri)1TpjW8bojhT&MX#igp>pd+4JOXeGomYzI-X;jx7D8?b@tHXJA zg5(EKui)GNTgrVWJt;rkXn(jE9bbC($>ELPr1ocDMr&H6ZAbZQe@fS1PM&#IKK#7B zc=3W8lrSFBuVkeUxkvk}TOnxn(r*s~67TLwuo{`jvT9 z*z>%75)>h|S>b5faBK^XCT|3m9$HEF6)r|lu|EyME})_WV_;~C%_Lw~jQxp_bD&uJ zZ@7#g|64}mC!QB8zZWYb+_?A_aRsq;$uB7{5UIH>nXU Xc4iTl9%fpZZ!Ud%`7bmUoCL&wI+iw$ literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/session-lifecycle_13.cpython-314.pyc b/docs/.validation/python/__pycache__/session-lifecycle_13.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d822139ab0a9084bb0107ddf99ede423b8d5a767 GIT binary patch literal 370 zcmdPq^pv<7j=%>kci^DlFCnqr}C-s(aaB6XJW`3S)UW!M4ezs>`L21b?J_xfc zKRK}kD0hp~u{<%e1gu^JRlR>{2}pw=l4xRHN=|CgN`}uMhujL*4=qkDD%LMZEGf!N z&eks|%FjwoE-BVe&M(N!$uH3@PRZ6!$xklU*DFiR$xH!Ts9#W7l98XMUkq`ZZcb)e zYI0?APHMcNv0g#tEe@O9{FKt1RJ$T>pdE}rT&xWwJ}@&fGCmNIxxp$iL+=8M<_#9! g3w%loLay>@US-h&%Cc&IWo8y-y2Kz@#0gXn03+UK#Q*>R literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/session-lifecycle_14.cpython-314.pyc b/docs/.validation/python/__pycache__/session-lifecycle_14.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06d46a489fc6bc09ac54dc283d6e97f0412a77de GIT binary patch literal 1494 zcmZ`&O>7%g5T3U`_Qp0g)N#_dCUyxjxJ|qi+%|2aLMqyds)T4GEL5enR_ldsV|!Qc zZ6YFp6eS0WxFB)yF~@L&6FJfw$3)=9tb{m}OK&cwYI9@WuI(m4Jn7AwH#2W$_M2}{ z$6ty7uI)e8t)E1INBq)XQcvk#L1hi@fJQz57c^lMTyh)c`~H4Bo+sfpISHknr9=WH zi!UdjAU@{TIiu(Gk1)y&+}#xvy7(Gov62e5SQg(Q8jM0salqG!uaiap85i@|@6n|R znpg%+Dic*uNx%Me(Byj<{W)0^Z^{vH1WlfRFx(8C6)jQ-8Nz`){Hwmh-93k5h6Ej9 zPMA!;h*}WJL?Z_+d30*R1o#<6Z^*UkCUf<=<3*Usm}NIAR(0-sM8S(#4QJV{RCQP9 z`igDnF8aM>KM>zhx8i4D{3G-EHE%)vn3yPS>5q1l6U`f&U$io%UFGcWiR3=xAa0C|kweH1q0vY7IVyc* z7o_Tm=1>+UeMSdCACf!Zh>HWJXmB*MCX~g1 zGY6-siv5a5xswI#SROPwQ2vuwF7;T2><`$M4cJCQ_=xfpo>E<=!R#YuqgtV+&X5P8 z;G9FMh@Y9R7pJCS(`uz|^3gL-bZn;}Q-!DDm?FalgrNy;j6HTqq$t}y#OAG!$C7><92ofMeyzE%#JkrR1)Ojr%F^F z{wEEo6MMsj-Qhx8Nwj0*JGr;ou}rhkk;P+?jwqiFbwN&rpMjhRuU~({kA22l-I%&S zejw+iAHx?2jy9~b)rMi&eoarL%MHr^t}bo}T2f}}c6GUCUZy#;@xO$k#b3q literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/session-persistence_24.cpython-314.pyc b/docs/.validation/python/__pycache__/session-persistence_24.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..386ac8aaf52390ba735184a9f1337309bac11ffb GIT binary patch literal 915 zcmZ`&%}*0i5TDomDhn-Yiy{zPJ|u2nyAg^fLu_k66GECMaKmQZZgipDUH3hd_SE3P z5Dxk$nCQj-z$^bjQDey_91JIJ#U6+^XG?2>(U;6`W_Et_@!n)-q7fPJd_LZ_gb=_< z;PejPHQHG;>hJ^#H|61C$LxB_1g z3ZfS3&G&bv8(I(L`~HzB6~Y?%Ul!gnGzk){ETT-J$P1iBls*sN6%^t}a*k`29hNIw zrp;D;nVOVZj$O1$wX56I^whg^^D5KnmYQC;=L;35WR`1@XD(A0Qgf<-?v5|Io>OsI zEtawMaDI`b@JOT!5^O@mRb+e@XTEv@7jR7<_o%T`Hecqz@T zvgfF}#Z(t7Sd^KzVHW4oDYxqL72UGEL2MGtN?#zH;`WdE+dm>B`^Eawk$mOt?B48t zs>u&G_~DiaL!-^Oau`>R!tus+#KCuomcY%3ZQzEabKnN0`f_Uk`mZ(R#G#ycKirsk z&`4&!%GoBL{laI@Vj$c+6Onf|078!ZqVw2wcRX{4d?1+#{^J;02S74Y`~evW>`{`L z<`2fCz@8!jP6w!PzNFKtZCFm{20rI)+n=C~)xe7)_~HAwzU{KP=*7_u{sVdop~VqG eP9XY|kB}T`O#lhM>EG?&d$_;!9b#S#DZc?t)XpgY literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/session-persistence_25.cpython-314.pyc b/docs/.validation/python/__pycache__/session-persistence_25.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f437b63b1322556d781631c17c3029e127ba17a GIT binary patch literal 690 zcmZ`$&ubG=5T4iF{4k+gv;nmgv(eL9(#1CMWD^y!)Pxciq8Dpeb|3UL$?o#ri#0uk z2#WY8=)tT1fO_*^NG%vx@Ki6orRL<#SWob9BN@Omu*eQbuofv2EE0_>3jlxAN_s2EuuCvSkEoJGm56JczT#!K|+ zD}?LVIe@2e4I0Xv&WQ!F>Nct#V8;tGQ0j>c1n?LdiFxCkSPPb7lK)Npds_06F7^cF#akPjMQMw6u~fdj8zuwpcLRB}`efghy31VskYW%{PY9jbyu&E38cLXS zka;rHI2FAvZ3!v_^Sy9UP|t1I=!Z6w1_@KMiiobHhfTAIONANOk~61m;<^LsNMSmD zz&gGx3b$>#z9Y=_=XQs=wnSAk=*xW!GpS;L3QS1qIkdG=UJv@A+O?U-qn{j|THHlA z!z2I9t&DTVan2as+&als##&{tJxN0L(m0bp&g4H_8LjP%^hYO|+E}f9Q)}lbSgM{U zAyFs4#VU#nuihi%9obUfuORtEs_N$ylCJ~-uaL4u-*cG%cXO!lp7#-^I0pOzLYThO t_1#{FR`?R8(E-FYgo#23IR)*Pnjm#D(SW31XNTE058gif4$EA_mOtR+n$`dS literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/session-persistence_26.cpython-314.pyc b/docs/.validation/python/__pycache__/session-persistence_26.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c855724f7b10fb3cb51da82af5cf721346801b62 GIT binary patch literal 744 zcmYjP&1=*^6n~Rs*LJ^H741R6ZiT{9w~?|G!Q#nF5JUrA5Y~o}jC9=HB+SgVtX@L# z;IXJ+4<7cY;L(GBMxhrO^wd*tl|{VzCP`Z#y!U?d=6%gCS!vWOfb#v<9$O*+$NF$4 zRsm*r5TvjLE^$DDYb=0kF2JxU$#c>I*K$i;BhQtFOKwBEe4>w!1MCP|wUkj!)Y%4_ z6nd~_+Zk_09>e5(H?y*qKOJ58;IZ3E0b1KI? zY7=D&$IzEQrJP9uwg7aA{^LZ90+@L#~-rL zmn@F#WFoiG2`U60I|+7RLeeOp-rD+VGEp_p^P?!1zNDVVt2jziCt7Gy_zMQP`&*k& z;#9k@x%(!v;0%)>DCpA|N~jr8E`k*LX9Pn3JnP9h(gnG+pj)7BQIQxusDTSTl3Ak$ zYbB(QDAH*g%4CsLmSiK^Ho2b3^%p`iF(RZtN`ziwd3llRKSW&)IMwefSU}$S6^v&O zZ6iqGXY=ZZhaa7H&ihA4&BfID(YW^Z*}i`;zyEsLnmW__hgJK~vUyFnDeZa3{u70Svf#%dCgd9WlkEO|;gT}3c O-Ou%-`ubiaEB*(Qd87~k literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/skills_22.cpython-314.pyc b/docs/.validation/python/__pycache__/skills_22.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da3b38ba24430954c36438fabd1d2c2eb9c63e25 GIT binary patch literal 977 zcmZ`%Pfrs;6rX8lyI3v%thSU$SMaha-HnI`gGeeyFd>MG5)Z~^vt4DN?QUkKAU&7{ zPlSVh1U&i;yqSK3qKA@=CK%&^8(0(L&9_S{2?;NGe`epb;daxu>8Lpu?aSZiXpV<#|sk zIR(2|m0!9dJFZ>#`uHj>7V`zlY)d$d+T4q{%qh8|dd;xcsJ*U;Wy%!`V9E=JDcrUy zjEW6~a$d2y8m`7QJt)F;KPk%sRQ2-z-GXCPO3)rtP^Vn&d#!8Mao5@~RbqY%Jc$dF z39s8?wkhm9w>bxZ7vpxhkT*fsO)5OXh2yFrFJc8f_vCgS_eV!jyjlGTw;9)6Q!r|+ z>hPEqc$!Zx7?mt9tm;6C>)M)Gq=kT$?rw->r`#r#9~;x$4Ud#eT4p^^mVojam;;!i zud&p2zIJ~v+WU5NYjj&{l4OG<_v5K%T-}YUdtE*62KKrJe<3myJ(T23q=n>5@*gDk z$hDcnI6B|ojHY*^>78UF^QfU1U!sdmve+Pt`%p2nmD$cVN#Zj}99==uz!3r1Q5;E+ z@pqE=%kKe+&7r#(@8H}m^4^a=;oJnNqZEYo6wXbO`e4G3$8c_n)NjasJb`^X8Q3Y` z&Z}WhZvRN|`@uUupcd3etQ(BibsI*dQnc@|i?H-Zn#aH#hB3xJ(beCi7bjUi?EC{g Cu;X6< literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/skills_23.cpython-314.pyc b/docs/.validation/python/__pycache__/skills_23.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3b5f253e10fdbbaacaac485c7dbb963fcc812999 GIT binary patch literal 620 zcmX|8&ubGw6n>N0WY@MPh!N2$ZS83Z*@c?oMLdYM3Z;|A8*;!^LrOBzp zgNXk?&wBDd@Xv@BErXtV>Mfdsh!@}HM+f%%zW3hu=FQI3%2yWv*O#9I{tx*)59Z67 ziSc6;C-4da@*Fe-g`1$s0qo7|b3gJL9FR3=%rXr!6)V`e4lcdO!`*0BosfGIu3IprDBW1azfepnKMS?wQQOa?XyH+mABl`7 zLf2K?_G1w#-#ZEu9)}vY@w1+OgET!>bK}03^^DaCc`EaV%b!3!K)Aq*`%%69z3P6g zx@XSvY3p?V%(*qZvoUNu9WHN;inLZ51HEDY0a~#K+rM)9tCp~Luv#M@iEDkbYs96- z4plFWxR?wuRCd$PFh(25D+tDU*b#9zVUJ`5!~ECOU4#)Ogq%b9w`CD~v;@R?w>VgQ O|K!8gH@Gg#==cv}bdw4I literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/user-prompt-submitted_10.cpython-314.pyc b/docs/.validation/python/__pycache__/user-prompt-submitted_10.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..02c03ced9ce59bbd75fbe47f3c3dbc775feb542d GIT binary patch literal 878 zcmZ`%%}*0S6o0eZb~gn|C?G~-EMS@}g{~hMjUgP20YTD`O~6FKX5DVW&~|sTGbP}O zl!Gx|NW6H~i{3o)XVgUenCOWUH>4(pn{V1~jR#*cZ{El6z2BRUT&gb#C#!W&UBe=lvI-_KNyIS^mb!_^ZL+H_#gh;aOC1LdmJ&Br zN{pDJbc+GQ0IzU0mr%7?*E+KT@~;w$OkVhl@5M8(V*h_**JBYko-Z~IEuOd_k42KX zj8We!($X`1J+s2x@J>b~g3zx9ykHO!4?^m3LlH^p1vOqQ+1!@)mhadc3z-}?n-vdD zS;CU)3#9nMV04`{{bQ>;`rOTNR*{FYsz*anNuV25wuR>RV%Hs=(pJ*`sC z-BR(|)qJoc&f{=0Uu@@#-Mq+FZR+J`DmY1n&F24ylkdh1RLA&Y-}SzIvOn>9?Jzyj z7|6Z5{bBK7`*8Yx_P$on$g$50;6ToH9(KDZ8>;sN^80iV`3CrNi*WFGI%1A>*sw-$+k3 z@^g)W`4d&iC7PfNYrjG1*Xr{><#xv881+n!yunZMR?87X6`IX#gT z25oYErs|h!6?Zlq!I=Cv>=LRIl@M|SsneK7w39Rt{drHl=f%C3bDv=_Jco!su%61C literal 0 HcmV?d00001 diff --git a/docs/.validation/python/__pycache__/user-prompt-submitted_9.cpython-314.pyc b/docs/.validation/python/__pycache__/user-prompt-submitted_9.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7bb92042a3216787cc617ebfc9ecab469375eebd GIT binary patch literal 400 zcmdPq^pv<7j=%>kci^DlFCnqr}C-s(0XmM&$Kv8~fK}m3FQf_8RNotBmetx!R zUO{QeEj|ddEI&E1Br`wn7N=u*VrB_gqbv@M{-q@#ol@AO6Z2AXQj1nHda2YXgZ7%#4hT4`fwuuqrOF nyTD>}gN643pZ1EBt9(XRS&V_QtR`QXndO)+F-R400@VWmjD&TN literal 0 HcmV?d00001 diff --git a/docs/.validation/python/byok_31.py b/docs/.validation/python/byok_31.py new file mode 100644 index 00000000..a96e316b --- /dev/null +++ b/docs/.validation/python/byok_31.py @@ -0,0 +1,38 @@ +# Source: auth/byok.md:22 +import asyncio +import os +from copilot import CopilotClient + +FOUNDRY_MODEL_URL = "https://your-resource.openai.azure.com/openai/v1/" +# Set FOUNDRY_API_KEY environment variable + +async def main(): + client = CopilotClient() + await client.start() + + session = await client.create_session({ + "model": "gpt-5.2-codex", # Your deployment name + "provider": { + "type": "openai", + "base_url": FOUNDRY_MODEL_URL, + "wire_api": "responses", # Use "completions" for older models + "api_key": os.environ["FOUNDRY_API_KEY"], + }, + }) + + done = asyncio.Event() + + def on_event(event): + if event.type.value == "assistant.message": + print(event.data.content) + elif event.type.value == "session.idle": + done.set() + + session.on(on_event) + await session.send({"prompt": "What is 2+2?"}) + await done.wait() + + await session.destroy() + await client.stop() + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/debugging_6.py b/docs/.validation/python/debugging_6.py new file mode 100644 index 00000000..8a334ed9 --- /dev/null +++ b/docs/.validation/python/debugging_6.py @@ -0,0 +1,4 @@ +# Source: debugging.md:36 +from copilot import CopilotClient + +client = CopilotClient({"log_level": "debug"}) \ No newline at end of file diff --git a/docs/.validation/python/debugging_7.py b/docs/.validation/python/debugging_7.py new file mode 100644 index 00000000..79225854 --- /dev/null +++ b/docs/.validation/python/debugging_7.py @@ -0,0 +1,4 @@ +# Source: debugging.md:99 +# The Python SDK does not currently support passing extra CLI arguments. +# Logs are written to the default location or can be configured via +# the CLI when running in server mode. \ No newline at end of file diff --git a/docs/.validation/python/error-handling_20.py b/docs/.validation/python/error-handling_20.py new file mode 100644 index 00000000..7159e470 --- /dev/null +++ b/docs/.validation/python/error-handling_20.py @@ -0,0 +1,5 @@ +# Source: hooks/error-handling.md:27 +ErrorOccurredHandler = Callable[ + [ErrorOccurredHookInput, HookInvocation], + Awaitable[ErrorOccurredHookOutput | None] +] \ No newline at end of file diff --git a/docs/.validation/python/error-handling_21.py b/docs/.validation/python/error-handling_21.py new file mode 100644 index 00000000..b2d142d0 --- /dev/null +++ b/docs/.validation/python/error-handling_21.py @@ -0,0 +1,15 @@ +# Source: hooks/error-handling.md:106 +import asyncio + +async def main(): + async def on_error_occurred(input_data, invocation): + print(f"[{invocation['session_id']}] Error: {input_data['error']}") + print(f" Context: {input_data['errorContext']}") + print(f" Recoverable: {input_data['recoverable']}") + return None + + session = await client.create_session({ + "hooks": {"on_error_occurred": on_error_occurred} + }) + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/getting-started_0.py b/docs/.validation/python/getting-started_0.py new file mode 100644 index 00000000..90679d38 --- /dev/null +++ b/docs/.validation/python/getting-started_0.py @@ -0,0 +1,16 @@ +# Source: getting-started.md:130 +import asyncio +from copilot import CopilotClient + +async def main(): + client = CopilotClient() + await client.start() + + session = await client.create_session({"model": "gpt-4.1"}) + response = await session.send_and_wait({"prompt": "What is 2 + 2?"}) + + print(response.data.content) + + await client.stop() + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/getting-started_1.py b/docs/.validation/python/getting-started_1.py new file mode 100644 index 00000000..cf5748cb --- /dev/null +++ b/docs/.validation/python/getting-started_1.py @@ -0,0 +1,30 @@ +# Source: getting-started.md:274 +import asyncio +import sys +from copilot import CopilotClient +from copilot.generated.session_events import SessionEventType + +async def main(): + client = CopilotClient() + await client.start() + + session = await client.create_session({ + "model": "gpt-4.1", + "streaming": True, + }) + + # Listen for response chunks + def handle_event(event): + if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA: + sys.stdout.write(event.data.delta_content) + sys.stdout.flush() + if event.type == SessionEventType.SESSION_IDLE: + print() # New line when done + + session.on(handle_event) + + await session.send_and_wait({"prompt": "Tell me a short joke"}) + + await client.stop() + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/getting-started_2.py b/docs/.validation/python/getting-started_2.py new file mode 100644 index 00000000..f81b403b --- /dev/null +++ b/docs/.validation/python/getting-started_2.py @@ -0,0 +1,15 @@ +# Source: getting-started.md:429 +# Subscribe to all events +unsubscribe = session.on(lambda event: print(f"Event: {event.type}")) + +# Filter by event type in your handler +def handle_event(event): + if event.type == SessionEventType.SESSION_IDLE: + print("Session is idle") + elif event.type == SessionEventType.ASSISTANT_MESSAGE: + print(f"Message: {event.data.content}") + +unsubscribe = session.on(handle_event) + +# Later, to unsubscribe: +unsubscribe() \ No newline at end of file diff --git a/docs/.validation/python/getting-started_3.py b/docs/.validation/python/getting-started_3.py new file mode 100644 index 00000000..3c255d89 --- /dev/null +++ b/docs/.validation/python/getting-started_3.py @@ -0,0 +1,49 @@ +# Source: getting-started.md:562 +import asyncio +import random +import sys +from copilot import CopilotClient +from copilot.tools import define_tool +from copilot.generated.session_events import SessionEventType +from pydantic import BaseModel, Field + +# Define the parameters for the tool using Pydantic +class GetWeatherParams(BaseModel): + city: str = Field(description="The name of the city to get weather for") + +# Define a tool that Copilot can call +@define_tool(description="Get the current weather for a city") +async def get_weather(params: GetWeatherParams) -> dict: + city = params.city + # In a real app, you'd call a weather API here + conditions = ["sunny", "cloudy", "rainy", "partly cloudy"] + temp = random.randint(50, 80) + condition = random.choice(conditions) + return {"city": city, "temperature": f"{temp}°F", "condition": condition} + +async def main(): + client = CopilotClient() + await client.start() + + session = await client.create_session({ + "model": "gpt-4.1", + "streaming": True, + "tools": [get_weather], + }) + + def handle_event(event): + if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA: + sys.stdout.write(event.data.delta_content) + sys.stdout.flush() + if event.type == SessionEventType.SESSION_IDLE: + print() + + session.on(handle_event) + + await session.send_and_wait({ + "prompt": "What's the weather like in Seattle and Tokyo?" + }) + + await client.stop() + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/getting-started_4.py b/docs/.validation/python/getting-started_4.py new file mode 100644 index 00000000..2fc68796 --- /dev/null +++ b/docs/.validation/python/getting-started_4.py @@ -0,0 +1,56 @@ +# Source: getting-started.md:834 +import asyncio +import random +import sys +from copilot import CopilotClient +from copilot.tools import define_tool +from copilot.generated.session_events import SessionEventType +from pydantic import BaseModel, Field + +class GetWeatherParams(BaseModel): + city: str = Field(description="The name of the city to get weather for") + +@define_tool(description="Get the current weather for a city") +async def get_weather(params: GetWeatherParams) -> dict: + city = params.city + conditions = ["sunny", "cloudy", "rainy", "partly cloudy"] + temp = random.randint(50, 80) + condition = random.choice(conditions) + return {"city": city, "temperature": f"{temp}°F", "condition": condition} + +async def main(): + client = CopilotClient() + await client.start() + + session = await client.create_session({ + "model": "gpt-4.1", + "streaming": True, + "tools": [get_weather], + }) + + def handle_event(event): + if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA: + sys.stdout.write(event.data.delta_content) + sys.stdout.flush() + + session.on(handle_event) + + print("🌤️ Weather Assistant (type 'exit' to quit)") + print(" Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'\n") + + while True: + try: + user_input = input("You: ") + except EOFError: + break + + if user_input.lower() == "exit": + break + + sys.stdout.write("Assistant: ") + await session.send_and_wait({"prompt": user_input}) + print("\n") + + await client.stop() + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/getting-started_5.py b/docs/.validation/python/getting-started_5.py new file mode 100644 index 00000000..8b405cd2 --- /dev/null +++ b/docs/.validation/python/getting-started_5.py @@ -0,0 +1,16 @@ +# Source: getting-started.md:1210 +import asyncio + +async def main(): + from copilot import CopilotClient + + client = CopilotClient({ + "cli_url": "localhost:4321" + }) + await client.start() + + # Use the client normally + session = await client.create_session() + # ... + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/index_27.py b/docs/.validation/python/index_27.py new file mode 100644 index 00000000..c644ba60 --- /dev/null +++ b/docs/.validation/python/index_27.py @@ -0,0 +1,11 @@ +# Source: auth/index.md:40 +import asyncio + +async def main(): + from copilot import CopilotClient + + # Default: uses logged-in user credentials + client = CopilotClient() + await client.start() + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/index_28.py b/docs/.validation/python/index_28.py new file mode 100644 index 00000000..1721ece4 --- /dev/null +++ b/docs/.validation/python/index_28.py @@ -0,0 +1,13 @@ +# Source: auth/index.md:108 +import asyncio + +async def main(): + from copilot import CopilotClient + + client = CopilotClient({ + "github_token": user_access_token, # Token from OAuth flow + "use_logged_in_user": False, # Don't use stored CLI credentials + }) + await client.start() + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/index_29.py b/docs/.validation/python/index_29.py new file mode 100644 index 00000000..1da4e053 --- /dev/null +++ b/docs/.validation/python/index_29.py @@ -0,0 +1,11 @@ +# Source: auth/index.md:195 +import asyncio + +async def main(): + from copilot import CopilotClient + + # Token is read from environment variable automatically + client = CopilotClient() + await client.start() + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/index_30.py b/docs/.validation/python/index_30.py new file mode 100644 index 00000000..fa48bc2d --- /dev/null +++ b/docs/.validation/python/index_30.py @@ -0,0 +1,4 @@ +# Source: auth/index.md:256 +client = CopilotClient({ + "use_logged_in_user": False, # Only use explicit tokens +}) \ No newline at end of file diff --git a/docs/.validation/python/overview_19.py b/docs/.validation/python/overview_19.py new file mode 100644 index 00000000..8e9f4ee2 --- /dev/null +++ b/docs/.validation/python/overview_19.py @@ -0,0 +1,30 @@ +# Source: hooks/overview.md:55 +import asyncio + +async def main(): + from copilot import CopilotClient + + async def main(): + client = CopilotClient() + await client.start() + + async def on_pre_tool_use(input_data, invocation): + print(f"Tool called: {input_data['toolName']}") + return {"permissionDecision": "allow"} + + async def on_post_tool_use(input_data, invocation): + print(f"Tool result: {input_data['toolResult']}") + return None + + async def on_session_start(input_data, invocation): + return {"additionalContext": "User prefers concise answers."} + + session = await client.create_session({ + "hooks": { + "on_pre_tool_use": on_pre_tool_use, + "on_post_tool_use": on_post_tool_use, + "on_session_start": on_session_start, + } + }) + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/overview_8.py b/docs/.validation/python/overview_8.py new file mode 100644 index 00000000..55285ce0 --- /dev/null +++ b/docs/.validation/python/overview_8.py @@ -0,0 +1,39 @@ +# Source: mcp/overview.md:60 +import asyncio +from copilot import CopilotClient + +async def main(): + client = CopilotClient() + await client.start() + + session = await client.create_session({ + "model": "gpt-5", + "mcp_servers": { + # Local MCP server (stdio) + "my-local-server": { + "type": "local", + "command": "python", + "args": ["./mcp_server.py"], + "env": {"DEBUG": "true"}, + "cwd": "./servers", + "tools": ["*"], + "timeout": 30000, + }, + # Remote MCP server (HTTP) + "github": { + "type": "http", + "url": "https://api.githubcopilot.com/mcp/", + "headers": {"Authorization": "Bearer ${TOKEN}"}, + "tools": ["*"], + }, + }, + }) + + response = await session.send_and_wait({ + "prompt": "List my recent GitHub notifications" + }) + print(response.data.content) + + await client.stop() + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/post-tool-use_17.py b/docs/.validation/python/post-tool-use_17.py new file mode 100644 index 00000000..45c3ec84 --- /dev/null +++ b/docs/.validation/python/post-tool-use_17.py @@ -0,0 +1,5 @@ +# Source: hooks/post-tool-use.md:27 +PostToolUseHandler = Callable[ + [PostToolUseHookInput, HookInvocation], + Awaitable[PostToolUseHookOutput | None] +] \ No newline at end of file diff --git a/docs/.validation/python/post-tool-use_18.py b/docs/.validation/python/post-tool-use_18.py new file mode 100644 index 00000000..589c9a0b --- /dev/null +++ b/docs/.validation/python/post-tool-use_18.py @@ -0,0 +1,15 @@ +# Source: hooks/post-tool-use.md:105 +import asyncio + +async def main(): + async def on_post_tool_use(input_data, invocation): + print(f"[{invocation['session_id']}] Tool: {input_data['toolName']}") + print(f" Args: {input_data['toolArgs']}") + print(f" Result: {input_data['toolResult']}") + return None # Pass through unchanged + + session = await client.create_session({ + "hooks": {"on_post_tool_use": on_post_tool_use} + }) + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/pre-tool-use_15.py b/docs/.validation/python/pre-tool-use_15.py new file mode 100644 index 00000000..29c0c82b --- /dev/null +++ b/docs/.validation/python/pre-tool-use_15.py @@ -0,0 +1,5 @@ +# Source: hooks/pre-tool-use.md:27 +PreToolUseHandler = Callable[ + [PreToolUseHookInput, HookInvocation], + Awaitable[PreToolUseHookOutput | None] +] \ No newline at end of file diff --git a/docs/.validation/python/pre-tool-use_16.py b/docs/.validation/python/pre-tool-use_16.py new file mode 100644 index 00000000..e39784af --- /dev/null +++ b/docs/.validation/python/pre-tool-use_16.py @@ -0,0 +1,14 @@ +# Source: hooks/pre-tool-use.md:113 +import asyncio + +async def main(): + async def on_pre_tool_use(input_data, invocation): + print(f"[{invocation['session_id']}] Calling {input_data['toolName']}") + print(f" Args: {input_data['toolArgs']}") + return {"permissionDecision": "allow"} + + session = await client.create_session({ + "hooks": {"on_pre_tool_use": on_pre_tool_use} + }) + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/session-lifecycle_11.py b/docs/.validation/python/session-lifecycle_11.py new file mode 100644 index 00000000..b72d0676 --- /dev/null +++ b/docs/.validation/python/session-lifecycle_11.py @@ -0,0 +1,5 @@ +# Source: hooks/session-lifecycle.md:31 +SessionStartHandler = Callable[ + [SessionStartHookInput, HookInvocation], + Awaitable[SessionStartHookOutput | None] +] \ No newline at end of file diff --git a/docs/.validation/python/session-lifecycle_12.py b/docs/.validation/python/session-lifecycle_12.py new file mode 100644 index 00000000..1ff60a18 --- /dev/null +++ b/docs/.validation/python/session-lifecycle_12.py @@ -0,0 +1,22 @@ +# Source: hooks/session-lifecycle.md:112 +import asyncio + +async def main(): + async def on_session_start(input_data, invocation): + print(f"Session {invocation['session_id']} started ({input_data['source']})") + + project_info = await detect_project_type(input_data["cwd"]) + + return { + "additionalContext": f""" + This is a {project_info['type']} project. + Main language: {project_info['language']} + Package manager: {project_info['packageManager']} + """.strip() + } + + session = await client.create_session({ + "hooks": {"on_session_start": on_session_start} + }) + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/session-lifecycle_13.py b/docs/.validation/python/session-lifecycle_13.py new file mode 100644 index 00000000..c010feef --- /dev/null +++ b/docs/.validation/python/session-lifecycle_13.py @@ -0,0 +1,5 @@ +# Source: hooks/session-lifecycle.md:208 +SessionEndHandler = Callable[ + [SessionEndHookInput, HookInvocation], + Awaitable[SessionEndHookOutput | None] +] \ No newline at end of file diff --git a/docs/.validation/python/session-lifecycle_14.py b/docs/.validation/python/session-lifecycle_14.py new file mode 100644 index 00000000..1947157b --- /dev/null +++ b/docs/.validation/python/session-lifecycle_14.py @@ -0,0 +1,31 @@ +# Source: hooks/session-lifecycle.md:307 +import asyncio + +async def main(): + session_start_times = {} + + async def on_session_start(input_data, invocation): + session_start_times[invocation["session_id"]] = input_data["timestamp"] + return None + + async def on_session_end(input_data, invocation): + start_time = session_start_times.get(invocation["session_id"]) + duration = input_data["timestamp"] - start_time if start_time else 0 + + await record_metrics({ + "session_id": invocation["session_id"], + "duration": duration, + "end_reason": input_data["reason"], + }) + + session_start_times.pop(invocation["session_id"], None) + return None + + session = await client.create_session({ + "hooks": { + "on_session_start": on_session_start, + "on_session_end": on_session_end, + } + }) + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/session-persistence_24.py b/docs/.validation/python/session-persistence_24.py new file mode 100644 index 00000000..8e3bbf55 --- /dev/null +++ b/docs/.validation/python/session-persistence_24.py @@ -0,0 +1,21 @@ +# Source: guides/session-persistence.md:48 +import asyncio + +async def main(): + from copilot import CopilotClient + + client = CopilotClient() + await client.start() + + # Create a session with a meaningful ID + session = await client.create_session({ + "session_id": "user-123-task-456", + "model": "gpt-5.2-codex", + }) + + # Do some work... + await session.send_and_wait({"prompt": "Analyze my codebase"}) + + # Session state is automatically persisted + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/session-persistence_25.py b/docs/.validation/python/session-persistence_25.py new file mode 100644 index 00000000..b8e9ff05 --- /dev/null +++ b/docs/.validation/python/session-persistence_25.py @@ -0,0 +1,11 @@ +# Source: guides/session-persistence.md:135 +import asyncio + +async def main(): + # Resume from a different client instance (or after restart) + session = await client.resume_session("user-123-task-456") + + # Continue where you left off + await session.send_and_wait({"prompt": "What did we discuss earlier?"}) + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/session-persistence_26.py b/docs/.validation/python/session-persistence_26.py new file mode 100644 index 00000000..e26712c0 --- /dev/null +++ b/docs/.validation/python/session-persistence_26.py @@ -0,0 +1,9 @@ +# Source: guides/session-persistence.md:248 +import time + +def create_session_id(user_id: str, task_type: str) -> str: + timestamp = int(time.time()) + return f"{user_id}-{task_type}-{timestamp}" + +session_id = create_session_id("alice", "code-review") +# → "alice-code-review-1706932800" \ No newline at end of file diff --git a/docs/.validation/python/skills_22.py b/docs/.validation/python/skills_22.py new file mode 100644 index 00000000..35154bb5 --- /dev/null +++ b/docs/.validation/python/skills_22.py @@ -0,0 +1,20 @@ +# Source: guides/skills.md:47 +from copilot import CopilotClient + +async def main(): + client = CopilotClient() + await client.start() + + session = await client.create_session({ + "model": "gpt-4.1", + "skill_directories": [ + "./skills/code-review", + "./skills/documentation", + "~/.copilot/skills", # User-level skills + ], + }) + + # Copilot now has access to skills in those directories + await session.send_and_wait({"prompt": "Review this code for security issues"}) + + await client.stop() \ No newline at end of file diff --git a/docs/.validation/python/skills_23.py b/docs/.validation/python/skills_23.py new file mode 100644 index 00000000..cb0d4dfc --- /dev/null +++ b/docs/.validation/python/skills_23.py @@ -0,0 +1,10 @@ +# Source: guides/skills.md:161 +import asyncio + +async def main(): + session = await client.create_session({ + "skill_directories": ["./skills"], + "disabled_skills": ["experimental-feature", "deprecated-tool"], + }) + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/user-prompt-submitted_10.py b/docs/.validation/python/user-prompt-submitted_10.py new file mode 100644 index 00000000..02fde460 --- /dev/null +++ b/docs/.validation/python/user-prompt-submitted_10.py @@ -0,0 +1,13 @@ +# Source: hooks/user-prompt-submitted.md:101 +import asyncio + +async def main(): + async def on_user_prompt_submitted(input_data, invocation): + print(f"[{invocation['session_id']}] User: {input_data['prompt']}") + return None + + session = await client.create_session({ + "hooks": {"on_user_prompt_submitted": on_user_prompt_submitted} + }) + +asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/user-prompt-submitted_9.py b/docs/.validation/python/user-prompt-submitted_9.py new file mode 100644 index 00000000..9c6283a7 --- /dev/null +++ b/docs/.validation/python/user-prompt-submitted_9.py @@ -0,0 +1,5 @@ +# Source: hooks/user-prompt-submitted.md:27 +UserPromptSubmittedHandler = Callable[ + [UserPromptSubmittedHookInput, HookInvocation], + Awaitable[UserPromptSubmittedHookOutput | None] +] \ No newline at end of file diff --git a/docs/.validation/typescript/byok_85.ts b/docs/.validation/typescript/byok_85.ts new file mode 100644 index 00000000..a8dbc9b8 --- /dev/null +++ b/docs/.validation/typescript/byok_85.ts @@ -0,0 +1,22 @@ +// Source: auth/byok.md:67 +import { CopilotClient } from "@github/copilot-sdk"; + +const FOUNDRY_MODEL_URL = "https://your-resource.openai.azure.com/openai/v1/"; + +const client = new CopilotClient(); +const session = await client.createSession({ + model: "gpt-5.2-codex", // Your deployment name + provider: { + type: "openai", + baseUrl: FOUNDRY_MODEL_URL, + wireApi: "responses", // Use "completions" for older models + apiKey: process.env.FOUNDRY_API_KEY, + }, +}); + +session.on("assistant.message", (event) => { + console.log(event.data.content); +}); + +await session.sendAndWait({ prompt: "What is 2+2?" }); +await client.stop(); \ No newline at end of file diff --git a/docs/.validation/typescript/byok_86.ts b/docs/.validation/typescript/byok_86.ts new file mode 100644 index 00000000..71c202cf --- /dev/null +++ b/docs/.validation/typescript/byok_86.ts @@ -0,0 +1,11 @@ +// Source: auth/byok.md:312 +// ❌ Error: Model required with custom provider +const session = await client.createSession({ + provider: { type: "openai", baseUrl: "..." }, +}); + +// ✅ Correct: Model specified +const session = await client.createSession({ + model: "gpt-4", // Required! + provider: { type: "openai", baseUrl: "..." }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/compatibility_15.ts b/docs/.validation/typescript/compatibility_15.ts new file mode 100644 index 00000000..490750e6 --- /dev/null +++ b/docs/.validation/typescript/compatibility_15.ts @@ -0,0 +1,13 @@ +// Source: compatibility.md:129 +const session = await client.createSession({ + onPermissionRequest: async (request) => { + // Auto-approve everything (equivalent to --yolo) + return { approved: true }; + + // Or implement custom logic + if (request.kind === "shell") { + return { approved: request.command.startsWith("git") }; + } + return { approved: true }; + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/compatibility_16.ts b/docs/.validation/typescript/compatibility_16.ts new file mode 100644 index 00000000..36525f41 --- /dev/null +++ b/docs/.validation/typescript/compatibility_16.ts @@ -0,0 +1,7 @@ +// Source: compatibility.md:148 +session.on("assistant.usage", (event) => { + console.log("Tokens used:", { + input: event.data.inputTokens, + output: event.data.outputTokens, + }); +}); \ No newline at end of file diff --git a/docs/.validation/typescript/compatibility_17.ts b/docs/.validation/typescript/compatibility_17.ts new file mode 100644 index 00000000..334f6427 --- /dev/null +++ b/docs/.validation/typescript/compatibility_17.ts @@ -0,0 +1,8 @@ +// Source: compatibility.md:161 +const session = await client.createSession({ + infiniteSessions: { + enabled: true, + backgroundCompactionThreshold: 0.80, // Start background compaction at 80% context utilization + bufferExhaustionThreshold: 0.95, // Block and compact at 95% context utilization + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/debugging_10.ts b/docs/.validation/typescript/debugging_10.ts new file mode 100644 index 00000000..42068478 --- /dev/null +++ b/docs/.validation/typescript/debugging_10.ts @@ -0,0 +1,4 @@ +// Source: debugging.md:88 +const client = new CopilotClient({ + cliArgs: ["--log-dir", "/path/to/logs"], +}); \ No newline at end of file diff --git a/docs/.validation/typescript/debugging_11.ts b/docs/.validation/typescript/debugging_11.ts new file mode 100644 index 00000000..bf4c26ca --- /dev/null +++ b/docs/.validation/typescript/debugging_11.ts @@ -0,0 +1,4 @@ +// Source: debugging.md:326 +const client = new CopilotClient({ + useStdio: true, // This is the default +}); \ No newline at end of file diff --git a/docs/.validation/typescript/debugging_12.ts b/docs/.validation/typescript/debugging_12.ts new file mode 100644 index 00000000..4dcb52c9 --- /dev/null +++ b/docs/.validation/typescript/debugging_12.ts @@ -0,0 +1,5 @@ +// Source: debugging.md:333 +const client = new CopilotClient({ + useStdio: false, + port: 8080, // Or 0 for random port +}); \ No newline at end of file diff --git a/docs/.validation/typescript/debugging_13.ts b/docs/.validation/typescript/debugging_13.ts new file mode 100644 index 00000000..7a6bc2ff --- /dev/null +++ b/docs/.validation/typescript/debugging_13.ts @@ -0,0 +1,4 @@ +// Source: debugging.md:341 +const client = new CopilotClient({ + cliUrl: "localhost:8080", // Connect to running server +}); \ No newline at end of file diff --git a/docs/.validation/typescript/debugging_14.ts b/docs/.validation/typescript/debugging_14.ts new file mode 100644 index 00000000..cf61210a --- /dev/null +++ b/docs/.validation/typescript/debugging_14.ts @@ -0,0 +1,8 @@ +// Source: debugging.md:416 +session.on("tool.execution_error", (event) => { + console.error("Tool error:", event.data); +}); + +session.on("error", (event) => { + console.error("Session error:", event.data); +}); \ No newline at end of file diff --git a/docs/.validation/typescript/debugging_9.ts b/docs/.validation/typescript/debugging_9.ts new file mode 100644 index 00000000..fb746265 --- /dev/null +++ b/docs/.validation/typescript/debugging_9.ts @@ -0,0 +1,6 @@ +// Source: debugging.md:23 +import { CopilotClient } from "@github/copilot-sdk"; + +const client = new CopilotClient({ + logLevel: "debug", // Options: "none", "error", "warning", "info", "debug", "all" +}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_57.ts b/docs/.validation/typescript/error-handling_57.ts new file mode 100644 index 00000000..fc5626bf --- /dev/null +++ b/docs/.validation/typescript/error-handling_57.ts @@ -0,0 +1,5 @@ +// Source: hooks/error-handling.md:15 +type ErrorOccurredHandler = ( + input: ErrorOccurredHookInput, + invocation: HookInvocation +) => Promise; \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_58.ts b/docs/.validation/typescript/error-handling_58.ts new file mode 100644 index 00000000..14e67079 --- /dev/null +++ b/docs/.validation/typescript/error-handling_58.ts @@ -0,0 +1,11 @@ +// Source: hooks/error-handling.md:88 +const session = await client.createSession({ + hooks: { + onErrorOccurred: async (input, invocation) => { + console.error(`[${invocation.sessionId}] Error: ${input.error}`); + console.error(` Context: ${input.errorContext}`); + console.error(` Recoverable: ${input.recoverable}`); + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_59.ts b/docs/.validation/typescript/error-handling_59.ts new file mode 100644 index 00000000..80e2ea8a --- /dev/null +++ b/docs/.validation/typescript/error-handling_59.ts @@ -0,0 +1,22 @@ +// Source: hooks/error-handling.md:162 +import { captureException } from "@sentry/node"; // or your monitoring service + +const session = await client.createSession({ + hooks: { + onErrorOccurred: async (input, invocation) => { + captureException(new Error(input.error), { + tags: { + sessionId: invocation.sessionId, + errorContext: input.errorContext, + }, + extra: { + error: input.error, + recoverable: input.recoverable, + cwd: input.cwd, + }, + }); + + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_60.ts b/docs/.validation/typescript/error-handling_60.ts new file mode 100644 index 00000000..768e5ed2 --- /dev/null +++ b/docs/.validation/typescript/error-handling_60.ts @@ -0,0 +1,23 @@ +// Source: hooks/error-handling.md:188 +const ERROR_MESSAGES: Record = { + "model_call": "There was an issue communicating with the AI model. Please try again.", + "tool_execution": "A tool failed to execute. Please check your inputs and try again.", + "system": "A system error occurred. Please try again later.", + "user_input": "There was an issue with your input. Please check and try again.", +}; + +const session = await client.createSession({ + hooks: { + onErrorOccurred: async (input) => { + const friendlyMessage = ERROR_MESSAGES[input.errorContext]; + + if (friendlyMessage) { + return { + userNotification: friendlyMessage, + }; + } + + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_61.ts b/docs/.validation/typescript/error-handling_61.ts new file mode 100644 index 00000000..ba3f2067 --- /dev/null +++ b/docs/.validation/typescript/error-handling_61.ts @@ -0,0 +1,13 @@ +// Source: hooks/error-handling.md:215 +const session = await client.createSession({ + hooks: { + onErrorOccurred: async (input) => { + // Suppress tool execution errors that are recoverable + if (input.errorContext === "tool_execution" && input.recoverable) { + console.log(`Suppressed recoverable error: ${input.error}`); + return { suppressOutput: true }; + } + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_62.ts b/docs/.validation/typescript/error-handling_62.ts new file mode 100644 index 00000000..e81a93a9 --- /dev/null +++ b/docs/.validation/typescript/error-handling_62.ts @@ -0,0 +1,27 @@ +// Source: hooks/error-handling.md:232 +const session = await client.createSession({ + hooks: { + onErrorOccurred: async (input) => { + if (input.errorContext === "tool_execution") { + return { + userNotification: ` +The tool failed. Here are some recovery suggestions: +- Check if required dependencies are installed +- Verify file paths are correct +- Try a simpler approach + `.trim(), + }; + } + + if (input.errorContext === "model_call" && input.error.includes("rate")) { + return { + errorHandling: "retry", + retryCount: 3, + userNotification: "Rate limit hit. Retrying...", + }; + } + + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_63.ts b/docs/.validation/typescript/error-handling_63.ts new file mode 100644 index 00000000..4b353e26 --- /dev/null +++ b/docs/.validation/typescript/error-handling_63.ts @@ -0,0 +1,35 @@ +// Source: hooks/error-handling.md:263 +interface ErrorStats { + count: number; + lastOccurred: number; + contexts: string[]; +} + +const errorStats = new Map(); + +const session = await client.createSession({ + hooks: { + onErrorOccurred: async (input, invocation) => { + const key = `${input.errorContext}:${input.error.substring(0, 50)}`; + + const existing = errorStats.get(key) || { + count: 0, + lastOccurred: 0, + contexts: [], + }; + + existing.count++; + existing.lastOccurred = input.timestamp; + existing.contexts.push(invocation.sessionId); + + errorStats.set(key, existing); + + // Alert if error is recurring + if (existing.count >= 5) { + console.warn(`Recurring error detected: ${key} (${existing.count} times)`); + } + + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_64.ts b/docs/.validation/typescript/error-handling_64.ts new file mode 100644 index 00000000..7f41f5a4 --- /dev/null +++ b/docs/.validation/typescript/error-handling_64.ts @@ -0,0 +1,20 @@ +// Source: hooks/error-handling.md:302 +const CRITICAL_CONTEXTS = ["system", "model_call"]; + +const session = await client.createSession({ + hooks: { + onErrorOccurred: async (input, invocation) => { + if (CRITICAL_CONTEXTS.includes(input.errorContext) && !input.recoverable) { + await sendAlert({ + level: "critical", + message: `Critical error in session ${invocation.sessionId}`, + error: input.error, + context: input.errorContext, + timestamp: new Date(input.timestamp).toISOString(), + }); + } + + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_65.ts b/docs/.validation/typescript/error-handling_65.ts new file mode 100644 index 00000000..25c3b169 --- /dev/null +++ b/docs/.validation/typescript/error-handling_65.ts @@ -0,0 +1,36 @@ +// Source: hooks/error-handling.md:326 +const sessionContext = new Map(); + +const session = await client.createSession({ + hooks: { + onPreToolUse: async (input, invocation) => { + const ctx = sessionContext.get(invocation.sessionId) || {}; + ctx.lastTool = input.toolName; + sessionContext.set(invocation.sessionId, ctx); + return { permissionDecision: "allow" }; + }, + + onUserPromptSubmitted: async (input, invocation) => { + const ctx = sessionContext.get(invocation.sessionId) || {}; + ctx.lastPrompt = input.prompt.substring(0, 100); + sessionContext.set(invocation.sessionId, ctx); + return null; + }, + + onErrorOccurred: async (input, invocation) => { + const ctx = sessionContext.get(invocation.sessionId); + + console.error(`Error in session ${invocation.sessionId}:`); + console.error(` Error: ${input.error}`); + console.error(` Context: ${input.errorContext}`); + if (ctx?.lastTool) { + console.error(` Last tool: ${ctx.lastTool}`); + } + if (ctx?.lastPrompt) { + console.error(` Last prompt: ${ctx.lastPrompt}...`); + } + + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_0.ts b/docs/.validation/typescript/getting-started_0.ts new file mode 100644 index 00000000..093de6f0 --- /dev/null +++ b/docs/.validation/typescript/getting-started_0.ts @@ -0,0 +1,11 @@ +// Source: getting-started.md:104 +import { CopilotClient } from "@github/copilot-sdk"; + +const client = new CopilotClient(); +const session = await client.createSession({ model: "gpt-4.1" }); + +const response = await session.sendAndWait({ prompt: "What is 2 + 2?" }); +console.log(response?.data.content); + +await client.stop(); +process.exit(0); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_1.ts b/docs/.validation/typescript/getting-started_1.ts new file mode 100644 index 00000000..ac83e867 --- /dev/null +++ b/docs/.validation/typescript/getting-started_1.ts @@ -0,0 +1,21 @@ +// Source: getting-started.md:244 +import { CopilotClient } from "@github/copilot-sdk"; + +const client = new CopilotClient(); +const session = await client.createSession({ + model: "gpt-4.1", + streaming: true, +}); + +// Listen for response chunks +session.on("assistant.message_delta", (event) => { + process.stdout.write(event.data.deltaContent); +}); +session.on("session.idle", () => { + console.log(); // New line when done +}); + +await session.sendAndWait({ prompt: "Tell me a short joke" }); + +await client.stop(); +process.exit(0); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_2.ts b/docs/.validation/typescript/getting-started_2.ts new file mode 100644 index 00000000..00c20924 --- /dev/null +++ b/docs/.validation/typescript/getting-started_2.ts @@ -0,0 +1,14 @@ +// Source: getting-started.md:408 +// Subscribe to all events +const unsubscribeAll = session.on((event) => { + console.log("Event:", event.type); +}); + +// Subscribe to specific event type +const unsubscribeIdle = session.on("session.idle", (event) => { + console.log("Session is idle"); +}); + +// Later, to unsubscribe: +unsubscribeAll(); +unsubscribeIdle(); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_3.ts b/docs/.validation/typescript/getting-started_3.ts new file mode 100644 index 00000000..44ea1144 --- /dev/null +++ b/docs/.validation/typescript/getting-started_3.ts @@ -0,0 +1,44 @@ +// Source: getting-started.md:509 +import { CopilotClient, defineTool } from "@github/copilot-sdk"; + +// Define a tool that Copilot can call +const getWeather = defineTool("get_weather", { + description: "Get the current weather for a city", + parameters: { + type: "object", + properties: { + city: { type: "string", description: "The city name" }, + }, + required: ["city"], + }, + handler: async (args: { city: string }) => { + const { city } = args; + // In a real app, you'd call a weather API here + const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"]; + const temp = Math.floor(Math.random() * 30) + 50; + const condition = conditions[Math.floor(Math.random() * conditions.length)]; + return { city, temperature: `${temp}°F`, condition }; + }, +}); + +const client = new CopilotClient(); +const session = await client.createSession({ + model: "gpt-4.1", + streaming: true, + tools: [getWeather], +}); + +session.on("assistant.message_delta", (event) => { + process.stdout.write(event.data.deltaContent); +}); + +session.on("session.idle", () => { + console.log(); // New line when done +}); + +await session.sendAndWait({ + prompt: "What's the weather like in Seattle and Tokyo?", +}); + +await client.stop(); +process.exit(0); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_4.ts b/docs/.validation/typescript/getting-started_4.ts new file mode 100644 index 00000000..4f5d34b0 --- /dev/null +++ b/docs/.validation/typescript/getting-started_4.ts @@ -0,0 +1,56 @@ +// Source: getting-started.md:763 +import { CopilotClient, defineTool } from "@github/copilot-sdk"; +import * as readline from "readline"; + +const getWeather = defineTool("get_weather", { + description: "Get the current weather for a city", + parameters: { + type: "object", + properties: { + city: { type: "string", description: "The city name" }, + }, + required: ["city"], + }, + handler: async ({ city }) => { + const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"]; + const temp = Math.floor(Math.random() * 30) + 50; + const condition = conditions[Math.floor(Math.random() * conditions.length)]; + return { city, temperature: `${temp}°F`, condition }; + }, +}); + +const client = new CopilotClient(); +const session = await client.createSession({ + model: "gpt-4.1", + streaming: true, + tools: [getWeather], +}); + +session.on("assistant.message_delta", (event) => { + process.stdout.write(event.data.deltaContent); +}); + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}); + +console.log("🌤️ Weather Assistant (type 'exit' to quit)"); +console.log(" Try: 'What's the weather in Paris?'\n"); + +const prompt = () => { + rl.question("You: ", async (input) => { + if (input.toLowerCase() === "exit") { + await client.stop(); + rl.close(); + return; + } + + process.stdout.write("Assistant: "); + await session.sendAndWait({ prompt: input }); + console.log("\n"); + prompt(); + }); +}; + +prompt(); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_5.ts b/docs/.validation/typescript/getting-started_5.ts new file mode 100644 index 00000000..edb59327 --- /dev/null +++ b/docs/.validation/typescript/getting-started_5.ts @@ -0,0 +1,9 @@ +// Source: getting-started.md:1126 +const session = await client.createSession({ + mcpServers: { + github: { + type: "http", + url: "https://api.githubcopilot.com/mcp/", + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_6.ts b/docs/.validation/typescript/getting-started_6.ts new file mode 100644 index 00000000..729ec618 --- /dev/null +++ b/docs/.validation/typescript/getting-started_6.ts @@ -0,0 +1,9 @@ +// Source: getting-started.md:1143 +const session = await client.createSession({ + customAgents: [{ + name: "pr-reviewer", + displayName: "PR Reviewer", + description: "Reviews pull requests for best practices", + prompt: "You are an expert code reviewer. Focus on security, performance, and maintainability.", + }], +}); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_7.ts b/docs/.validation/typescript/getting-started_7.ts new file mode 100644 index 00000000..69199497 --- /dev/null +++ b/docs/.validation/typescript/getting-started_7.ts @@ -0,0 +1,6 @@ +// Source: getting-started.md:1158 +const session = await client.createSession({ + systemMessage: { + content: "You are a helpful assistant for our engineering team. Always be concise.", + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_8.ts b/docs/.validation/typescript/getting-started_8.ts new file mode 100644 index 00000000..27f32acd --- /dev/null +++ b/docs/.validation/typescript/getting-started_8.ts @@ -0,0 +1,10 @@ +// Source: getting-started.md:1193 +import { CopilotClient } from "@github/copilot-sdk"; + +const client = new CopilotClient({ + cliUrl: "localhost:4321" +}); + +// Use the client normally +const session = await client.createSession(); +// ... \ No newline at end of file diff --git a/docs/.validation/typescript/index_81.ts b/docs/.validation/typescript/index_81.ts new file mode 100644 index 00000000..3310fff9 --- /dev/null +++ b/docs/.validation/typescript/index_81.ts @@ -0,0 +1,5 @@ +// Source: auth/index.md:28 +import { CopilotClient } from "@github/copilot-sdk"; + +// Default: uses logged-in user credentials +const client = new CopilotClient(); \ No newline at end of file diff --git a/docs/.validation/typescript/index_82.ts b/docs/.validation/typescript/index_82.ts new file mode 100644 index 00000000..6023c8df --- /dev/null +++ b/docs/.validation/typescript/index_82.ts @@ -0,0 +1,7 @@ +// Source: auth/index.md:94 +import { CopilotClient } from "@github/copilot-sdk"; + +const client = new CopilotClient({ + githubToken: userAccessToken, // Token from OAuth flow + useLoggedInUser: false, // Don't use stored CLI credentials +}); \ No newline at end of file diff --git a/docs/.validation/typescript/index_83.ts b/docs/.validation/typescript/index_83.ts new file mode 100644 index 00000000..a4f9e1ab --- /dev/null +++ b/docs/.validation/typescript/index_83.ts @@ -0,0 +1,5 @@ +// Source: auth/index.md:183 +import { CopilotClient } from "@github/copilot-sdk"; + +// Token is read from environment variable automatically +const client = new CopilotClient(); \ No newline at end of file diff --git a/docs/.validation/typescript/index_84.ts b/docs/.validation/typescript/index_84.ts new file mode 100644 index 00000000..929e35f1 --- /dev/null +++ b/docs/.validation/typescript/index_84.ts @@ -0,0 +1,4 @@ +// Source: auth/index.md:245 +const client = new CopilotClient({ + useLoggedInUser: false, // Only use explicit tokens +}); \ No newline at end of file diff --git a/docs/.validation/typescript/overview_18.ts b/docs/.validation/typescript/overview_18.ts new file mode 100644 index 00000000..3f1d02e5 --- /dev/null +++ b/docs/.validation/typescript/overview_18.ts @@ -0,0 +1,26 @@ +// Source: mcp/overview.md:30 +import { CopilotClient } from "@github/copilot-sdk"; + +const client = new CopilotClient(); +const session = await client.createSession({ + model: "gpt-5", + mcpServers: { + // Local MCP server (stdio) + "my-local-server": { + type: "local", + command: "node", + args: ["./mcp-server.js"], + env: { DEBUG: "true" }, + cwd: "./servers", + tools: ["*"], // "*" = all tools, [] = none, or list specific tools + timeout: 30000, + }, + // Remote MCP server (HTTP) + "github": { + type: "http", + url: "https://api.githubcopilot.com/mcp/", + headers: { "Authorization": "Bearer ${TOKEN}" }, + tools: ["*"], + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/overview_19.ts b/docs/.validation/typescript/overview_19.ts new file mode 100644 index 00000000..f2a09bc2 --- /dev/null +++ b/docs/.validation/typescript/overview_19.ts @@ -0,0 +1,32 @@ +// Source: mcp/overview.md:167 +import { CopilotClient } from "@github/copilot-sdk"; + +async function main() { + const client = new CopilotClient(); + + // Create session with filesystem MCP server + const session = await client.createSession({ + mcpServers: { + filesystem: { + type: "local", + command: "npx", + args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"], + tools: ["*"], + }, + }, + }); + + console.log("Session created:", session.sessionId); + + // The model can now use filesystem tools + const result = await session.sendAndWait({ + prompt: "List the files in the allowed directory", + }); + + console.log("Response:", result?.data?.content); + + await session.destroy(); + await client.stop(); +} + +main(); \ No newline at end of file diff --git a/docs/.validation/typescript/overview_53.ts b/docs/.validation/typescript/overview_53.ts new file mode 100644 index 00000000..85c61fd8 --- /dev/null +++ b/docs/.validation/typescript/overview_53.ts @@ -0,0 +1,21 @@ +// Source: hooks/overview.md:27 +import { CopilotClient } from "@github/copilot-sdk"; + +const client = new CopilotClient(); + +const session = await client.createSession({ + hooks: { + onPreToolUse: async (input) => { + console.log(`Tool called: ${input.toolName}`); + // Allow all tools + return { permissionDecision: "allow" }; + }, + onPostToolUse: async (input) => { + console.log(`Tool result: ${JSON.stringify(input.toolResult)}`); + return null; // No modifications + }, + onSessionStart: async (input) => { + return { additionalContext: "User prefers concise answers." }; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/overview_54.ts b/docs/.validation/typescript/overview_54.ts new file mode 100644 index 00000000..b69196b4 --- /dev/null +++ b/docs/.validation/typescript/overview_54.ts @@ -0,0 +1,13 @@ +// Source: hooks/overview.md:174 +const session = await client.createSession({ + hooks: { + onPreToolUse: async (input) => { + console.log(`[${new Date().toISOString()}] Tool: ${input.toolName}, Args: ${JSON.stringify(input.toolArgs)}`); + return { permissionDecision: "allow" }; + }, + onPostToolUse: async (input) => { + console.log(`[${new Date().toISOString()}] Result: ${JSON.stringify(input.toolResult)}`); + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/overview_55.ts b/docs/.validation/typescript/overview_55.ts new file mode 100644 index 00000000..9e69489d --- /dev/null +++ b/docs/.validation/typescript/overview_55.ts @@ -0,0 +1,16 @@ +// Source: hooks/overview.md:191 +const BLOCKED_TOOLS = ["shell", "bash", "exec"]; + +const session = await client.createSession({ + hooks: { + onPreToolUse: async (input) => { + if (BLOCKED_TOOLS.includes(input.toolName)) { + return { + permissionDecision: "deny", + permissionDecisionReason: "Shell access is not permitted", + }; + } + return { permissionDecision: "allow" }; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/overview_56.ts b/docs/.validation/typescript/overview_56.ts new file mode 100644 index 00000000..78fd4a32 --- /dev/null +++ b/docs/.validation/typescript/overview_56.ts @@ -0,0 +1,11 @@ +// Source: hooks/overview.md:211 +const session = await client.createSession({ + hooks: { + onSessionStart: async () => { + const userPrefs = await loadUserPreferences(); + return { + additionalContext: `User preferences: ${JSON.stringify(userPrefs)}`, + }; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_45.ts b/docs/.validation/typescript/post-tool-use_45.ts new file mode 100644 index 00000000..face85d3 --- /dev/null +++ b/docs/.validation/typescript/post-tool-use_45.ts @@ -0,0 +1,5 @@ +// Source: hooks/post-tool-use.md:15 +type PostToolUseHandler = ( + input: PostToolUseHookInput, + invocation: HookInvocation +) => Promise; \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_46.ts b/docs/.validation/typescript/post-tool-use_46.ts new file mode 100644 index 00000000..338cb1f4 --- /dev/null +++ b/docs/.validation/typescript/post-tool-use_46.ts @@ -0,0 +1,11 @@ +// Source: hooks/post-tool-use.md:87 +const session = await client.createSession({ + hooks: { + onPostToolUse: async (input, invocation) => { + console.log(`[${invocation.sessionId}] Tool: ${input.toolName}`); + console.log(` Args: ${JSON.stringify(input.toolArgs)}`); + console.log(` Result: ${JSON.stringify(input.toolResult)}`); + return null; // Pass through unchanged + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_47.ts b/docs/.validation/typescript/post-tool-use_47.ts new file mode 100644 index 00000000..99774d3f --- /dev/null +++ b/docs/.validation/typescript/post-tool-use_47.ts @@ -0,0 +1,24 @@ +// Source: hooks/post-tool-use.md:161 +const SENSITIVE_PATTERNS = [ + /api[_-]?key["\s:=]+["']?[\w-]+["']?/gi, + /password["\s:=]+["']?[\w-]+["']?/gi, + /secret["\s:=]+["']?[\w-]+["']?/gi, +]; + +const session = await client.createSession({ + hooks: { + onPostToolUse: async (input) => { + if (typeof input.toolResult === "string") { + let redacted = input.toolResult; + for (const pattern of SENSITIVE_PATTERNS) { + redacted = redacted.replace(pattern, "[REDACTED]"); + } + + if (redacted !== input.toolResult) { + return { modifiedResult: redacted }; + } + } + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_48.ts b/docs/.validation/typescript/post-tool-use_48.ts new file mode 100644 index 00000000..dac41628 --- /dev/null +++ b/docs/.validation/typescript/post-tool-use_48.ts @@ -0,0 +1,22 @@ +// Source: hooks/post-tool-use.md:189 +const MAX_RESULT_LENGTH = 10000; + +const session = await client.createSession({ + hooks: { + onPostToolUse: async (input) => { + const resultStr = JSON.stringify(input.toolResult); + + if (resultStr.length > MAX_RESULT_LENGTH) { + return { + modifiedResult: { + truncated: true, + originalLength: resultStr.length, + content: resultStr.substring(0, MAX_RESULT_LENGTH) + "...", + }, + additionalContext: `Note: Result was truncated from ${resultStr.length} to ${MAX_RESULT_LENGTH} characters.`, + }; + } + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_49.ts b/docs/.validation/typescript/post-tool-use_49.ts new file mode 100644 index 00000000..fd4b6cdc --- /dev/null +++ b/docs/.validation/typescript/post-tool-use_49.ts @@ -0,0 +1,22 @@ +// Source: hooks/post-tool-use.md:215 +const session = await client.createSession({ + hooks: { + onPostToolUse: async (input) => { + // If a file read returned an error, add helpful context + if (input.toolName === "read_file" && input.toolResult?.error) { + return { + additionalContext: "Tip: If the file doesn't exist, consider creating it or checking the path.", + }; + } + + // If shell command failed, add debugging hint + if (input.toolName === "shell" && input.toolResult?.exitCode !== 0) { + return { + additionalContext: "The command failed. Check if required dependencies are installed.", + }; + } + + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_50.ts b/docs/.validation/typescript/post-tool-use_50.ts new file mode 100644 index 00000000..68191840 --- /dev/null +++ b/docs/.validation/typescript/post-tool-use_50.ts @@ -0,0 +1,18 @@ +// Source: hooks/post-tool-use.md:241 +const session = await client.createSession({ + hooks: { + onPostToolUse: async (input) => { + if (input.toolResult?.error && input.toolResult?.stack) { + // Remove internal stack trace details + return { + modifiedResult: { + error: input.toolResult.error, + // Keep only first 3 lines of stack + stack: input.toolResult.stack.split("\n").slice(0, 3).join("\n"), + }, + }; + } + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_51.ts b/docs/.validation/typescript/post-tool-use_51.ts new file mode 100644 index 00000000..8a504df5 --- /dev/null +++ b/docs/.validation/typescript/post-tool-use_51.ts @@ -0,0 +1,31 @@ +// Source: hooks/post-tool-use.md:263 +interface AuditEntry { + timestamp: number; + sessionId: string; + toolName: string; + args: unknown; + result: unknown; + success: boolean; +} + +const auditLog: AuditEntry[] = []; + +const session = await client.createSession({ + hooks: { + onPostToolUse: async (input, invocation) => { + auditLog.push({ + timestamp: input.timestamp, + sessionId: invocation.sessionId, + toolName: input.toolName, + args: input.toolArgs, + result: input.toolResult, + success: !input.toolResult?.error, + }); + + // Optionally persist to database/file + await saveAuditLog(auditLog); + + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_52.ts b/docs/.validation/typescript/post-tool-use_52.ts new file mode 100644 index 00000000..bf2737a1 --- /dev/null +++ b/docs/.validation/typescript/post-tool-use_52.ts @@ -0,0 +1,23 @@ +// Source: hooks/post-tool-use.md:298 +const NOISY_TOOLS = ["list_directory", "search_codebase"]; + +const session = await client.createSession({ + hooks: { + onPostToolUse: async (input) => { + if (NOISY_TOOLS.includes(input.toolName)) { + // Summarize instead of showing full result + const items = Array.isArray(input.toolResult) + ? input.toolResult + : input.toolResult?.items || []; + + return { + modifiedResult: { + summary: `Found ${items.length} items`, + firstFew: items.slice(0, 5), + }, + }; + } + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_38.ts b/docs/.validation/typescript/pre-tool-use_38.ts new file mode 100644 index 00000000..5b185598 --- /dev/null +++ b/docs/.validation/typescript/pre-tool-use_38.ts @@ -0,0 +1,5 @@ +// Source: hooks/pre-tool-use.md:15 +type PreToolUseHandler = ( + input: PreToolUseHookInput, + invocation: HookInvocation +) => Promise; \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_39.ts b/docs/.validation/typescript/pre-tool-use_39.ts new file mode 100644 index 00000000..3d18fcc4 --- /dev/null +++ b/docs/.validation/typescript/pre-tool-use_39.ts @@ -0,0 +1,10 @@ +// Source: hooks/pre-tool-use.md:96 +const session = await client.createSession({ + hooks: { + onPreToolUse: async (input, invocation) => { + console.log(`[${invocation.sessionId}] Calling ${input.toolName}`); + console.log(` Args: ${JSON.stringify(input.toolArgs)}`); + return { permissionDecision: "allow" }; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_40.ts b/docs/.validation/typescript/pre-tool-use_40.ts new file mode 100644 index 00000000..68d9ccba --- /dev/null +++ b/docs/.validation/typescript/pre-tool-use_40.ts @@ -0,0 +1,16 @@ +// Source: hooks/pre-tool-use.md:170 +const BLOCKED_TOOLS = ["shell", "bash", "write_file", "delete_file"]; + +const session = await client.createSession({ + hooks: { + onPreToolUse: async (input) => { + if (BLOCKED_TOOLS.includes(input.toolName)) { + return { + permissionDecision: "deny", + permissionDecisionReason: `Tool '${input.toolName}' is not permitted in this environment`, + }; + } + return { permissionDecision: "allow" }; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_41.ts b/docs/.validation/typescript/pre-tool-use_41.ts new file mode 100644 index 00000000..9627d149 --- /dev/null +++ b/docs/.validation/typescript/pre-tool-use_41.ts @@ -0,0 +1,19 @@ +// Source: hooks/pre-tool-use.md:190 +const session = await client.createSession({ + hooks: { + onPreToolUse: async (input) => { + // Add a default timeout to all shell commands + if (input.toolName === "shell" && input.toolArgs) { + const args = input.toolArgs as { command: string; timeout?: number }; + return { + permissionDecision: "allow", + modifiedArgs: { + ...args, + timeout: args.timeout ?? 30000, // Default 30s timeout + }, + }; + } + return { permissionDecision: "allow" }; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_42.ts b/docs/.validation/typescript/pre-tool-use_42.ts new file mode 100644 index 00000000..5ead8f9c --- /dev/null +++ b/docs/.validation/typescript/pre-tool-use_42.ts @@ -0,0 +1,23 @@ +// Source: hooks/pre-tool-use.md:213 +const ALLOWED_DIRECTORIES = ["/home/user/projects", "/tmp"]; + +const session = await client.createSession({ + hooks: { + onPreToolUse: async (input) => { + if (input.toolName === "read_file" || input.toolName === "write_file") { + const args = input.toolArgs as { path: string }; + const isAllowed = ALLOWED_DIRECTORIES.some(dir => + args.path.startsWith(dir) + ); + + if (!isAllowed) { + return { + permissionDecision: "deny", + permissionDecisionReason: `Access to '${args.path}' is not permitted. Allowed directories: ${ALLOWED_DIRECTORIES.join(", ")}`, + }; + } + } + return { permissionDecision: "allow" }; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_43.ts b/docs/.validation/typescript/pre-tool-use_43.ts new file mode 100644 index 00000000..4ce2f562 --- /dev/null +++ b/docs/.validation/typescript/pre-tool-use_43.ts @@ -0,0 +1,13 @@ +// Source: hooks/pre-tool-use.md:240 +const VERBOSE_TOOLS = ["list_directory", "search_files"]; + +const session = await client.createSession({ + hooks: { + onPreToolUse: async (input) => { + return { + permissionDecision: "allow", + suppressOutput: VERBOSE_TOOLS.includes(input.toolName), + }; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_44.ts b/docs/.validation/typescript/pre-tool-use_44.ts new file mode 100644 index 00000000..005d8ad6 --- /dev/null +++ b/docs/.validation/typescript/pre-tool-use_44.ts @@ -0,0 +1,14 @@ +// Source: hooks/pre-tool-use.md:257 +const session = await client.createSession({ + hooks: { + onPreToolUse: async (input) => { + if (input.toolName === "query_database") { + return { + permissionDecision: "allow", + additionalContext: "Remember: This database uses PostgreSQL syntax. Always use parameterized queries.", + }; + } + return { permissionDecision: "allow" }; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_29.ts b/docs/.validation/typescript/session-lifecycle_29.ts new file mode 100644 index 00000000..d6e6688a --- /dev/null +++ b/docs/.validation/typescript/session-lifecycle_29.ts @@ -0,0 +1,5 @@ +// Source: hooks/session-lifecycle.md:19 +type SessionStartHandler = ( + input: SessionStartHookInput, + invocation: HookInvocation +) => Promise; \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_30.ts b/docs/.validation/typescript/session-lifecycle_30.ts new file mode 100644 index 00000000..3e416c4c --- /dev/null +++ b/docs/.validation/typescript/session-lifecycle_30.ts @@ -0,0 +1,18 @@ +// Source: hooks/session-lifecycle.md:87 +const session = await client.createSession({ + hooks: { + onSessionStart: async (input, invocation) => { + console.log(`Session ${invocation.sessionId} started (${input.source})`); + + const projectInfo = await detectProjectType(input.cwd); + + return { + additionalContext: ` +This is a ${projectInfo.type} project. +Main language: ${projectInfo.language} +Package manager: ${projectInfo.packageManager} + `.trim(), + }; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_31.ts b/docs/.validation/typescript/session-lifecycle_31.ts new file mode 100644 index 00000000..7072a436 --- /dev/null +++ b/docs/.validation/typescript/session-lifecycle_31.ts @@ -0,0 +1,20 @@ +// Source: hooks/session-lifecycle.md:135 +const session = await client.createSession({ + hooks: { + onSessionStart: async (input, invocation) => { + if (input.source === "resume") { + // Load previous session state + const previousState = await loadSessionState(invocation.sessionId); + + return { + additionalContext: ` +Session resumed. Previous context: +- Last topic: ${previousState.lastTopic} +- Open files: ${previousState.openFiles.join(", ")} + `.trim(), + }; + } + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_32.ts b/docs/.validation/typescript/session-lifecycle_32.ts new file mode 100644 index 00000000..dd32855e --- /dev/null +++ b/docs/.validation/typescript/session-lifecycle_32.ts @@ -0,0 +1,24 @@ +// Source: hooks/session-lifecycle.md:159 +const session = await client.createSession({ + hooks: { + onSessionStart: async () => { + const preferences = await loadUserPreferences(); + + const contextParts = []; + + if (preferences.language) { + contextParts.push(`Preferred language: ${preferences.language}`); + } + if (preferences.codeStyle) { + contextParts.push(`Code style: ${preferences.codeStyle}`); + } + if (preferences.verbosity === "concise") { + contextParts.push("Keep responses brief and to the point."); + } + + return { + additionalContext: contextParts.join("\n"), + }; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_33.ts b/docs/.validation/typescript/session-lifecycle_33.ts new file mode 100644 index 00000000..1c5d136a --- /dev/null +++ b/docs/.validation/typescript/session-lifecycle_33.ts @@ -0,0 +1,5 @@ +// Source: hooks/session-lifecycle.md:196 +type SessionEndHandler = ( + input: SessionEndHookInput, + invocation: HookInvocation +) => Promise; \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_34.ts b/docs/.validation/typescript/session-lifecycle_34.ts new file mode 100644 index 00000000..910071d9 --- /dev/null +++ b/docs/.validation/typescript/session-lifecycle_34.ts @@ -0,0 +1,24 @@ +// Source: hooks/session-lifecycle.md:276 +const sessionStartTimes = new Map(); + +const session = await client.createSession({ + hooks: { + onSessionStart: async (input, invocation) => { + sessionStartTimes.set(invocation.sessionId, input.timestamp); + return null; + }, + onSessionEnd: async (input, invocation) => { + const startTime = sessionStartTimes.get(invocation.sessionId); + const duration = startTime ? input.timestamp - startTime : 0; + + await recordMetrics({ + sessionId: invocation.sessionId, + duration, + endReason: input.reason, + }); + + sessionStartTimes.delete(invocation.sessionId); + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_35.ts b/docs/.validation/typescript/session-lifecycle_35.ts new file mode 100644 index 00000000..689c910d --- /dev/null +++ b/docs/.validation/typescript/session-lifecycle_35.ts @@ -0,0 +1,25 @@ +// Source: hooks/session-lifecycle.md:339 +const sessionResources = new Map(); + +const session = await client.createSession({ + hooks: { + onSessionStart: async (input, invocation) => { + sessionResources.set(invocation.sessionId, { tempFiles: [] }); + return null; + }, + onSessionEnd: async (input, invocation) => { + const resources = sessionResources.get(invocation.sessionId); + + if (resources) { + // Clean up temp files + for (const file of resources.tempFiles) { + await fs.unlink(file).catch(() => {}); + } + sessionResources.delete(invocation.sessionId); + } + + console.log(`Session ${invocation.sessionId} ended: ${input.reason}`); + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_36.ts b/docs/.validation/typescript/session-lifecycle_36.ts new file mode 100644 index 00000000..d8fe6d8b --- /dev/null +++ b/docs/.validation/typescript/session-lifecycle_36.ts @@ -0,0 +1,16 @@ +// Source: hooks/session-lifecycle.md:368 +const session = await client.createSession({ + hooks: { + onSessionEnd: async (input, invocation) => { + if (input.reason !== "error") { + // Save state for potential resume + await saveSessionState(invocation.sessionId, { + endTime: input.timestamp, + cwd: input.cwd, + reason: input.reason, + }); + } + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_37.ts b/docs/.validation/typescript/session-lifecycle_37.ts new file mode 100644 index 00000000..ee628dcf --- /dev/null +++ b/docs/.validation/typescript/session-lifecycle_37.ts @@ -0,0 +1,37 @@ +// Source: hooks/session-lifecycle.md:388 +const sessionData: Record = {}; + +const session = await client.createSession({ + hooks: { + onSessionStart: async (input, invocation) => { + sessionData[invocation.sessionId] = { + prompts: 0, + tools: 0, + startTime: input.timestamp + }; + return null; + }, + onUserPromptSubmitted: async (_, invocation) => { + sessionData[invocation.sessionId].prompts++; + return null; + }, + onPreToolUse: async (_, invocation) => { + sessionData[invocation.sessionId].tools++; + return { permissionDecision: "allow" }; + }, + onSessionEnd: async (input, invocation) => { + const data = sessionData[invocation.sessionId]; + console.log(` +Session Summary: + ID: ${invocation.sessionId} + Duration: ${(input.timestamp - data.startTime) / 1000}s + Prompts: ${data.prompts} + Tool calls: ${data.tools} + End reason: ${input.reason} + `.trim()); + + delete sessionData[invocation.sessionId]; + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_70.ts b/docs/.validation/typescript/session-persistence_70.ts new file mode 100644 index 00000000..f652780e --- /dev/null +++ b/docs/.validation/typescript/session-persistence_70.ts @@ -0,0 +1,16 @@ +// Source: guides/session-persistence.md:28 +import { CopilotClient } from "@github/copilot-sdk"; + +const client = new CopilotClient(); + +// Create a session with a meaningful ID +const session = await client.createSession({ + sessionId: "user-123-task-456", + model: "gpt-5.2-codex", +}); + +// Do some work... +await session.sendAndWait({ prompt: "Analyze my codebase" }); + +// Session state is automatically persisted +// You can safely close the client \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_71.ts b/docs/.validation/typescript/session-persistence_71.ts new file mode 100644 index 00000000..b19acb83 --- /dev/null +++ b/docs/.validation/typescript/session-persistence_71.ts @@ -0,0 +1,6 @@ +// Source: guides/session-persistence.md:125 +// Resume from a different client instance (or after restart) +const session = await client.resumeSession("user-123-task-456"); + +// Continue where you left off +await session.sendAndWait({ prompt: "What did we discuss earlier?" }); \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_72.ts b/docs/.validation/typescript/session-persistence_72.ts new file mode 100644 index 00000000..8b2d1dbd --- /dev/null +++ b/docs/.validation/typescript/session-persistence_72.ts @@ -0,0 +1,22 @@ +// Source: guides/session-persistence.md:170 +// Original session with BYOK +const session = await client.createSession({ + sessionId: "user-123-task-456", + model: "gpt-5.2-codex", + provider: { + type: "azure", + endpoint: "https://my-resource.openai.azure.com", + apiKey: process.env.AZURE_OPENAI_KEY, + deploymentId: "my-gpt-deployment", + }, +}); + +// When resuming, you MUST re-provide the provider config +const resumed = await client.resumeSession("user-123-task-456", { + provider: { + type: "azure", + endpoint: "https://my-resource.openai.azure.com", + apiKey: process.env.AZURE_OPENAI_KEY, // Required again + deploymentId: "my-gpt-deployment", + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_73.ts b/docs/.validation/typescript/session-persistence_73.ts new file mode 100644 index 00000000..57141bbf --- /dev/null +++ b/docs/.validation/typescript/session-persistence_73.ts @@ -0,0 +1,8 @@ +// Source: guides/session-persistence.md:238 +function createSessionId(userId: string, taskType: string): string { + const timestamp = Date.now(); + return `${userId}-${taskType}-${timestamp}`; +} + +const sessionId = createSessionId("alice", "code-review"); +// → "alice-code-review-1706932800000" \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_74.ts b/docs/.validation/typescript/session-persistence_74.ts new file mode 100644 index 00000000..fede2a9e --- /dev/null +++ b/docs/.validation/typescript/session-persistence_74.ts @@ -0,0 +1,7 @@ +// Source: guides/session-persistence.md:263 +const sessions = await client.listSessions(); +console.log(`Found ${sessions.length} sessions`); + +for (const session of sessions) { + console.log(`- ${session.sessionId} (created: ${session.createdAt})`); +} \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_75.ts b/docs/.validation/typescript/session-persistence_75.ts new file mode 100644 index 00000000..64766a53 --- /dev/null +++ b/docs/.validation/typescript/session-persistence_75.ts @@ -0,0 +1,16 @@ +// Source: guides/session-persistence.md:274 +async function cleanupExpiredSessions(maxAgeMs: number) { + const sessions = await client.listSessions(); + const now = Date.now(); + + for (const session of sessions) { + const age = now - new Date(session.createdAt).getTime(); + if (age > maxAgeMs) { + await client.deleteSession(session.sessionId); + console.log(`Deleted expired session: ${session.sessionId}`); + } + } +} + +// Clean up sessions older than 24 hours +await cleanupExpiredSessions(24 * 60 * 60 * 1000); \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_76.ts b/docs/.validation/typescript/session-persistence_76.ts new file mode 100644 index 00000000..8ed1b832 --- /dev/null +++ b/docs/.validation/typescript/session-persistence_76.ts @@ -0,0 +1,12 @@ +// Source: guides/session-persistence.md:296 +try { + // Do work... + await session.sendAndWait({ prompt: "Complete the task" }); + + // Task complete - clean up + await session.destroy(); +} catch (error) { + // Clean up even on error + await session.destroy(); + throw error; +} \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_77.ts b/docs/.validation/typescript/session-persistence_77.ts new file mode 100644 index 00000000..92216451 --- /dev/null +++ b/docs/.validation/typescript/session-persistence_77.ts @@ -0,0 +1,4 @@ +// Source: guides/session-persistence.md:321 +session.on("session.idle", (event) => { + console.log(`Session idle for ${event.idleDurationMs}ms`); +}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_78.ts b/docs/.validation/typescript/session-persistence_78.ts new file mode 100644 index 00000000..bd5b5496 --- /dev/null +++ b/docs/.validation/typescript/session-persistence_78.ts @@ -0,0 +1,16 @@ +// Source: guides/session-persistence.md:366 +// Application-level access control for shared CLI +async function resumeSessionWithAuth( + client: CopilotClient, + sessionId: string, + currentUserId: string +): Promise { + // Parse user from session ID + const [sessionUserId] = sessionId.split("-"); + + if (sessionUserId !== currentUserId) { + throw new Error("Access denied: session belongs to another user"); + } + + return client.resumeSession(sessionId); +} \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_79.ts b/docs/.validation/typescript/session-persistence_79.ts new file mode 100644 index 00000000..874e5a10 --- /dev/null +++ b/docs/.validation/typescript/session-persistence_79.ts @@ -0,0 +1,9 @@ +// Source: guides/session-persistence.md:428 +const session = await client.createSession({ + sessionId: "long-workflow-123", + infiniteSessions: { + enabled: true, + backgroundCompactionThreshold: 0.80, // Start compaction at 80% context + bufferExhaustionThreshold: 0.95, // Block at 95% if needed + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_80.ts b/docs/.validation/typescript/session-persistence_80.ts new file mode 100644 index 00000000..3bf30312 --- /dev/null +++ b/docs/.validation/typescript/session-persistence_80.ts @@ -0,0 +1,29 @@ +// Source: guides/session-persistence.md:454 +// Option 1: Application-level locking with Redis +import Redis from "ioredis"; + +const redis = new Redis(); + +async function withSessionLock( + sessionId: string, + fn: () => Promise +): Promise { + const lockKey = `session-lock:${sessionId}`; + const acquired = await redis.set(lockKey, "locked", "NX", "EX", 300); + + if (!acquired) { + throw new Error("Session is in use by another client"); + } + + try { + return await fn(); + } finally { + await redis.del(lockKey); + } +} + +// Usage +await withSessionLock("user-123-task-456", async () => { + const session = await client.resumeSession("user-123-task-456"); + await session.sendAndWait({ prompt: "Continue the task" }); +}); \ No newline at end of file diff --git a/docs/.validation/typescript/skills_66.ts b/docs/.validation/typescript/skills_66.ts new file mode 100644 index 00000000..98aec20c --- /dev/null +++ b/docs/.validation/typescript/skills_66.ts @@ -0,0 +1,15 @@ +// Source: guides/skills.md:25 +import { CopilotClient } from "@github/copilot-sdk"; + +const client = new CopilotClient(); +const session = await client.createSession({ + model: "gpt-4.1", + skillDirectories: [ + "./skills/code-review", + "./skills/documentation", + "~/.copilot/skills", // User-level skills + ], +}); + +// Copilot now has access to skills in those directories +await session.sendAndWait({ prompt: "Review this code for security issues" }); \ No newline at end of file diff --git a/docs/.validation/typescript/skills_67.ts b/docs/.validation/typescript/skills_67.ts new file mode 100644 index 00000000..0d2e9861 --- /dev/null +++ b/docs/.validation/typescript/skills_67.ts @@ -0,0 +1,5 @@ +// Source: guides/skills.md:149 +const session = await client.createSession({ + skillDirectories: ["./skills"], + disabledSkills: ["experimental-feature", "deprecated-tool"], +}); \ No newline at end of file diff --git a/docs/.validation/typescript/skills_68.ts b/docs/.validation/typescript/skills_68.ts new file mode 100644 index 00000000..eb452d1b --- /dev/null +++ b/docs/.validation/typescript/skills_68.ts @@ -0,0 +1,9 @@ +// Source: guides/skills.md:278 +const session = await client.createSession({ + skillDirectories: ["./skills/security"], + customAgents: [{ + name: "security-auditor", + description: "Security-focused code reviewer", + prompt: "Focus on OWASP Top 10 vulnerabilities", + }], +}); \ No newline at end of file diff --git a/docs/.validation/typescript/skills_69.ts b/docs/.validation/typescript/skills_69.ts new file mode 100644 index 00000000..dcb81878 --- /dev/null +++ b/docs/.validation/typescript/skills_69.ts @@ -0,0 +1,12 @@ +// Source: guides/skills.md:293 +const session = await client.createSession({ + skillDirectories: ["./skills/database"], + mcpServers: { + postgres: { + type: "local", + command: "npx", + args: ["-y", "@modelcontextprotocol/server-postgres"], + tools: ["*"], + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/tsconfig.json b/docs/.validation/typescript/tsconfig.json new file mode 100644 index 00000000..cb428310 --- /dev/null +++ b/docs/.validation/typescript/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "types": [ + "node" + ], + "paths": { + "@github/copilot-sdk": [ + "/Users/patrick/projects/copilot-sdk/nodejs/src/index.ts" + ] + } + }, + "include": [ + "./**/*.ts" + ] +} \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_20.ts b/docs/.validation/typescript/user-prompt-submitted_20.ts new file mode 100644 index 00000000..668ce7ad --- /dev/null +++ b/docs/.validation/typescript/user-prompt-submitted_20.ts @@ -0,0 +1,5 @@ +// Source: hooks/user-prompt-submitted.md:15 +type UserPromptSubmittedHandler = ( + input: UserPromptSubmittedHookInput, + invocation: HookInvocation +) => Promise; \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_21.ts b/docs/.validation/typescript/user-prompt-submitted_21.ts new file mode 100644 index 00000000..b895ff0e --- /dev/null +++ b/docs/.validation/typescript/user-prompt-submitted_21.ts @@ -0,0 +1,9 @@ +// Source: hooks/user-prompt-submitted.md:85 +const session = await client.createSession({ + hooks: { + onUserPromptSubmitted: async (input, invocation) => { + console.log(`[${invocation.sessionId}] User: ${input.prompt}`); + return null; // Pass through unchanged + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_22.ts b/docs/.validation/typescript/user-prompt-submitted_22.ts new file mode 100644 index 00000000..f375bab3 --- /dev/null +++ b/docs/.validation/typescript/user-prompt-submitted_22.ts @@ -0,0 +1,16 @@ +// Source: hooks/user-prompt-submitted.md:151 +const session = await client.createSession({ + hooks: { + onUserPromptSubmitted: async (input) => { + const projectInfo = await getProjectInfo(); + + return { + additionalContext: ` +Project: ${projectInfo.name} +Language: ${projectInfo.language} +Framework: ${projectInfo.framework} + `.trim(), + }; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_23.ts b/docs/.validation/typescript/user-prompt-submitted_23.ts new file mode 100644 index 00000000..800f8d23 --- /dev/null +++ b/docs/.validation/typescript/user-prompt-submitted_23.ts @@ -0,0 +1,23 @@ +// Source: hooks/user-prompt-submitted.md:171 +const SHORTCUTS: Record = { + "/fix": "Please fix the errors in the code", + "/explain": "Please explain this code in detail", + "/test": "Please write unit tests for this code", + "/refactor": "Please refactor this code to improve readability and maintainability", +}; + +const session = await client.createSession({ + hooks: { + onUserPromptSubmitted: async (input) => { + for (const [shortcut, expansion] of Object.entries(SHORTCUTS)) { + if (input.prompt.startsWith(shortcut)) { + const rest = input.prompt.slice(shortcut.length).trim(); + return { + modifiedPrompt: `${expansion}${rest ? `: ${rest}` : ""}`, + }; + } + } + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_24.ts b/docs/.validation/typescript/user-prompt-submitted_24.ts new file mode 100644 index 00000000..d8c1cd69 --- /dev/null +++ b/docs/.validation/typescript/user-prompt-submitted_24.ts @@ -0,0 +1,23 @@ +// Source: hooks/user-prompt-submitted.md:198 +const BLOCKED_PATTERNS = [ + /password\s*[:=]/i, + /api[_-]?key\s*[:=]/i, + /secret\s*[:=]/i, +]; + +const session = await client.createSession({ + hooks: { + onUserPromptSubmitted: async (input) => { + for (const pattern of BLOCKED_PATTERNS) { + if (pattern.test(input.prompt)) { + // Replace the prompt with a warning message + return { + modifiedPrompt: "[Content blocked: Please don't include sensitive credentials in your prompts. Use environment variables instead.]", + suppressOutput: true, + }; + } + } + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_25.ts b/docs/.validation/typescript/user-prompt-submitted_25.ts new file mode 100644 index 00000000..1fe0a560 --- /dev/null +++ b/docs/.validation/typescript/user-prompt-submitted_25.ts @@ -0,0 +1,17 @@ +// Source: hooks/user-prompt-submitted.md:225 +const MAX_PROMPT_LENGTH = 10000; + +const session = await client.createSession({ + hooks: { + onUserPromptSubmitted: async (input) => { + if (input.prompt.length > MAX_PROMPT_LENGTH) { + // Truncate the prompt and add context + return { + modifiedPrompt: input.prompt.substring(0, MAX_PROMPT_LENGTH), + additionalContext: `Note: The original prompt was ${input.prompt.length} characters and was truncated to ${MAX_PROMPT_LENGTH} characters.`, + }; + } + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_26.ts b/docs/.validation/typescript/user-prompt-submitted_26.ts new file mode 100644 index 00000000..a89b2b71 --- /dev/null +++ b/docs/.validation/typescript/user-prompt-submitted_26.ts @@ -0,0 +1,30 @@ +// Source: hooks/user-prompt-submitted.md:246 +interface UserPreferences { + codeStyle: "concise" | "verbose"; + preferredLanguage: string; + experienceLevel: "beginner" | "intermediate" | "expert"; +} + +const session = await client.createSession({ + hooks: { + onUserPromptSubmitted: async (input) => { + const prefs: UserPreferences = await loadUserPreferences(); + + const contextParts = []; + + if (prefs.codeStyle === "concise") { + contextParts.push("User prefers concise code with minimal comments."); + } else { + contextParts.push("User prefers verbose code with detailed comments."); + } + + if (prefs.experienceLevel === "beginner") { + contextParts.push("Explain concepts in simple terms."); + } + + return { + additionalContext: contextParts.join(" "), + }; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_27.ts b/docs/.validation/typescript/user-prompt-submitted_27.ts new file mode 100644 index 00000000..2d2e93fb --- /dev/null +++ b/docs/.validation/typescript/user-prompt-submitted_27.ts @@ -0,0 +1,27 @@ +// Source: hooks/user-prompt-submitted.md:280 +const promptTimestamps: number[] = []; +const RATE_LIMIT = 10; // prompts +const RATE_WINDOW = 60000; // 1 minute + +const session = await client.createSession({ + hooks: { + onUserPromptSubmitted: async (input) => { + const now = Date.now(); + + // Remove timestamps outside the window + while (promptTimestamps.length > 0 && promptTimestamps[0] < now - RATE_WINDOW) { + promptTimestamps.shift(); + } + + if (promptTimestamps.length >= RATE_LIMIT) { + return { + reject: true, + rejectReason: `Rate limit exceeded. Please wait before sending more prompts.`, + }; + } + + promptTimestamps.push(now); + return null; + }, + }, +}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_28.ts b/docs/.validation/typescript/user-prompt-submitted_28.ts new file mode 100644 index 00000000..271d6feb --- /dev/null +++ b/docs/.validation/typescript/user-prompt-submitted_28.ts @@ -0,0 +1,32 @@ +// Source: hooks/user-prompt-submitted.md:311 +const TEMPLATES: Record string> = { + "bug:": (desc) => `I found a bug: ${desc} + +Please help me: +1. Understand why this is happening +2. Suggest a fix +3. Explain how to prevent similar bugs`, + + "feature:": (desc) => `I want to implement this feature: ${desc} + +Please: +1. Outline the implementation approach +2. Identify potential challenges +3. Provide sample code`, +}; + +const session = await client.createSession({ + hooks: { + onUserPromptSubmitted: async (input) => { + for (const [prefix, template] of Object.entries(TEMPLATES)) { + if (input.prompt.toLowerCase().startsWith(prefix)) { + const args = input.prompt.slice(prefix.length).trim(); + return { + modifiedPrompt: template(args), + }; + } + } + return null; + }, + }, +}); \ No newline at end of file From 5ed65a9da6063eb0d173c67ce892a26a32c75ab0 Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 21:53:21 -0800 Subject: [PATCH 07/14] Remove accidentally committed .validation directory --- docs/.validation/csharp/DocsValidation.csproj | 12 - docs/.validation/csharp/byok_29.cs | 21 - docs/.validation/csharp/debugging_10.cs | 9 - docs/.validation/csharp/debugging_6.cs | 16 - docs/.validation/csharp/debugging_7.cs | 5 - docs/.validation/csharp/debugging_9.cs | 20 - docs/.validation/csharp/error-handling_20.cs | 4 - docs/.validation/csharp/error-handling_21.cs | 14 - docs/.validation/csharp/getting-started_0.cs | 8 - docs/.validation/csharp/getting-started_1.cs | 24 - docs/.validation/csharp/getting-started_2.cs | 20 - docs/.validation/csharp/getting-started_3.cs | 44 - docs/.validation/csharp/getting-started_4.cs | 55 - docs/.validation/csharp/getting-started_5.cs | 12 - docs/.validation/csharp/index_26.cs | 5 - docs/.validation/csharp/index_27.cs | 8 - docs/.validation/csharp/index_28.cs | 5 - docs/.validation/csharp/overview_19.cs | 29 - docs/.validation/csharp/overview_8.cs | 18 - docs/.validation/csharp/post-tool-use_17.cs | 4 - docs/.validation/csharp/post-tool-use_18.cs | 14 - docs/.validation/csharp/pre-tool-use_15.cs | 4 - docs/.validation/csharp/pre-tool-use_16.cs | 15 - .../csharp/session-lifecycle_13.cs | 4 - .../csharp/session-lifecycle_14.cs | 4 - .../csharp/session-persistence_24.cs | 16 - .../csharp/session-persistence_25.cs | 6 - docs/.validation/csharp/skills_22.cs | 20 - docs/.validation/csharp/skills_23.cs | 6 - .../csharp/user-prompt-submitted_11.cs | 4 - .../csharp/user-prompt-submitted_12.cs | 12 - docs/.validation/go/byok_7.go | 40 - docs/.validation/go/getting-started_0.go | 33 - docs/.validation/go/getting-started_1.go | 44 - docs/.validation/go/getting-started_2.go | 77 -- docs/.validation/go/getting-started_3.go | 95 -- docs/.validation/go/go.mod | 9 - docs/.validation/go/go.sum | 4 - docs/.validation/go/overview_4.go | 36 - docs/.validation/go/overview_5.go | 33 - docs/.validation/go/skills_6.go | 37 - docs/.validation/manifest.json | 1104 ----------------- .../__pycache__/byok_31.cpython-314.pyc | Bin 2044 -> 0 bytes .../__pycache__/debugging_6.cpython-314.pyc | Bin 282 -> 0 bytes .../__pycache__/debugging_7.cpython-314.pyc | Bin 173 -> 0 bytes .../error-handling_20.cpython-314.pyc | Bin 376 -> 0 bytes .../error-handling_21.cpython-314.pyc | Bin 1042 -> 0 bytes .../getting-started_0.cpython-314.pyc | Bin 1047 -> 0 bytes .../getting-started_1.cpython-314.pyc | Bin 1753 -> 0 bytes .../getting-started_2.cpython-314.pyc | Bin 1005 -> 0 bytes .../getting-started_3.cpython-314.pyc | Bin 3303 -> 0 bytes .../getting-started_4.cpython-314.pyc | Bin 3707 -> 0 bytes .../getting-started_5.cpython-314.pyc | Bin 717 -> 0 bytes .../__pycache__/index_27.cpython-314.pyc | Bin 537 -> 0 bytes .../__pycache__/index_28.cpython-314.pyc | Bin 628 -> 0 bytes .../__pycache__/index_29.cpython-314.pyc | Bin 537 -> 0 bytes .../__pycache__/index_30.cpython-314.pyc | Bin 251 -> 0 bytes .../__pycache__/overview_19.cpython-314.pyc | Bin 1698 -> 0 bytes .../__pycache__/overview_8.cpython-314.pyc | Bin 1492 -> 0 bytes .../post-tool-use_17.cpython-314.pyc | Bin 369 -> 0 bytes .../post-tool-use_18.cpython-314.pyc | Bin 1028 -> 0 bytes .../pre-tool-use_15.cpython-314.pyc | Bin 365 -> 0 bytes .../pre-tool-use_16.cpython-314.pyc | Bin 975 -> 0 bytes .../session-lifecycle_11.cpython-314.pyc | Bin 376 -> 0 bytes .../session-lifecycle_12.cpython-314.pyc | Bin 1326 -> 0 bytes .../session-lifecycle_13.cpython-314.pyc | Bin 370 -> 0 bytes .../session-lifecycle_14.cpython-314.pyc | Bin 1494 -> 0 bytes .../session-persistence_24.cpython-314.pyc | Bin 915 -> 0 bytes .../session-persistence_25.cpython-314.pyc | Bin 690 -> 0 bytes .../session-persistence_26.cpython-314.pyc | Bin 744 -> 0 bytes .../__pycache__/skills_22.cpython-314.pyc | Bin 977 -> 0 bytes .../__pycache__/skills_23.cpython-314.pyc | Bin 620 -> 0 bytes .../user-prompt-submitted_10.cpython-314.pyc | Bin 878 -> 0 bytes .../user-prompt-submitted_9.cpython-314.pyc | Bin 400 -> 0 bytes docs/.validation/python/byok_31.py | 38 - docs/.validation/python/debugging_6.py | 4 - docs/.validation/python/debugging_7.py | 4 - docs/.validation/python/error-handling_20.py | 5 - docs/.validation/python/error-handling_21.py | 15 - docs/.validation/python/getting-started_0.py | 16 - docs/.validation/python/getting-started_1.py | 30 - docs/.validation/python/getting-started_2.py | 15 - docs/.validation/python/getting-started_3.py | 49 - docs/.validation/python/getting-started_4.py | 56 - docs/.validation/python/getting-started_5.py | 16 - docs/.validation/python/index_27.py | 11 - docs/.validation/python/index_28.py | 13 - docs/.validation/python/index_29.py | 11 - docs/.validation/python/index_30.py | 4 - docs/.validation/python/overview_19.py | 30 - docs/.validation/python/overview_8.py | 39 - docs/.validation/python/post-tool-use_17.py | 5 - docs/.validation/python/post-tool-use_18.py | 15 - docs/.validation/python/pre-tool-use_15.py | 5 - docs/.validation/python/pre-tool-use_16.py | 14 - .../python/session-lifecycle_11.py | 5 - .../python/session-lifecycle_12.py | 22 - .../python/session-lifecycle_13.py | 5 - .../python/session-lifecycle_14.py | 31 - .../python/session-persistence_24.py | 21 - .../python/session-persistence_25.py | 11 - .../python/session-persistence_26.py | 9 - docs/.validation/python/skills_22.py | 20 - docs/.validation/python/skills_23.py | 10 - .../python/user-prompt-submitted_10.py | 13 - .../python/user-prompt-submitted_9.py | 5 - docs/.validation/typescript/byok_85.ts | 22 - docs/.validation/typescript/byok_86.ts | 11 - .../typescript/compatibility_15.ts | 13 - .../typescript/compatibility_16.ts | 7 - .../typescript/compatibility_17.ts | 8 - docs/.validation/typescript/debugging_10.ts | 4 - docs/.validation/typescript/debugging_11.ts | 4 - docs/.validation/typescript/debugging_12.ts | 5 - docs/.validation/typescript/debugging_13.ts | 4 - docs/.validation/typescript/debugging_14.ts | 8 - docs/.validation/typescript/debugging_9.ts | 6 - .../typescript/error-handling_57.ts | 5 - .../typescript/error-handling_58.ts | 11 - .../typescript/error-handling_59.ts | 22 - .../typescript/error-handling_60.ts | 23 - .../typescript/error-handling_61.ts | 13 - .../typescript/error-handling_62.ts | 27 - .../typescript/error-handling_63.ts | 35 - .../typescript/error-handling_64.ts | 20 - .../typescript/error-handling_65.ts | 36 - .../typescript/getting-started_0.ts | 11 - .../typescript/getting-started_1.ts | 21 - .../typescript/getting-started_2.ts | 14 - .../typescript/getting-started_3.ts | 44 - .../typescript/getting-started_4.ts | 56 - .../typescript/getting-started_5.ts | 9 - .../typescript/getting-started_6.ts | 9 - .../typescript/getting-started_7.ts | 6 - .../typescript/getting-started_8.ts | 10 - docs/.validation/typescript/index_81.ts | 5 - docs/.validation/typescript/index_82.ts | 7 - docs/.validation/typescript/index_83.ts | 5 - docs/.validation/typescript/index_84.ts | 4 - docs/.validation/typescript/overview_18.ts | 26 - docs/.validation/typescript/overview_19.ts | 32 - docs/.validation/typescript/overview_53.ts | 21 - docs/.validation/typescript/overview_54.ts | 13 - docs/.validation/typescript/overview_55.ts | 16 - docs/.validation/typescript/overview_56.ts | 11 - .../typescript/post-tool-use_45.ts | 5 - .../typescript/post-tool-use_46.ts | 11 - .../typescript/post-tool-use_47.ts | 24 - .../typescript/post-tool-use_48.ts | 22 - .../typescript/post-tool-use_49.ts | 22 - .../typescript/post-tool-use_50.ts | 18 - .../typescript/post-tool-use_51.ts | 31 - .../typescript/post-tool-use_52.ts | 23 - .../.validation/typescript/pre-tool-use_38.ts | 5 - .../.validation/typescript/pre-tool-use_39.ts | 10 - .../.validation/typescript/pre-tool-use_40.ts | 16 - .../.validation/typescript/pre-tool-use_41.ts | 19 - .../.validation/typescript/pre-tool-use_42.ts | 23 - .../.validation/typescript/pre-tool-use_43.ts | 13 - .../.validation/typescript/pre-tool-use_44.ts | 14 - .../typescript/session-lifecycle_29.ts | 5 - .../typescript/session-lifecycle_30.ts | 18 - .../typescript/session-lifecycle_31.ts | 20 - .../typescript/session-lifecycle_32.ts | 24 - .../typescript/session-lifecycle_33.ts | 5 - .../typescript/session-lifecycle_34.ts | 24 - .../typescript/session-lifecycle_35.ts | 25 - .../typescript/session-lifecycle_36.ts | 16 - .../typescript/session-lifecycle_37.ts | 37 - .../typescript/session-persistence_70.ts | 16 - .../typescript/session-persistence_71.ts | 6 - .../typescript/session-persistence_72.ts | 22 - .../typescript/session-persistence_73.ts | 8 - .../typescript/session-persistence_74.ts | 7 - .../typescript/session-persistence_75.ts | 16 - .../typescript/session-persistence_76.ts | 12 - .../typescript/session-persistence_77.ts | 4 - .../typescript/session-persistence_78.ts | 16 - .../typescript/session-persistence_79.ts | 9 - .../typescript/session-persistence_80.ts | 29 - docs/.validation/typescript/skills_66.ts | 15 - docs/.validation/typescript/skills_67.ts | 5 - docs/.validation/typescript/skills_68.ts | 9 - docs/.validation/typescript/skills_69.ts | 12 - docs/.validation/typescript/tsconfig.json | 24 - .../typescript/user-prompt-submitted_20.ts | 5 - .../typescript/user-prompt-submitted_21.ts | 9 - .../typescript/user-prompt-submitted_22.ts | 16 - .../typescript/user-prompt-submitted_23.ts | 23 - .../typescript/user-prompt-submitted_24.ts | 23 - .../typescript/user-prompt-submitted_25.ts | 17 - .../typescript/user-prompt-submitted_26.ts | 30 - .../typescript/user-prompt-submitted_27.ts | 27 - .../typescript/user-prompt-submitted_28.ts | 32 - 194 files changed, 3923 deletions(-) delete mode 100644 docs/.validation/csharp/DocsValidation.csproj delete mode 100644 docs/.validation/csharp/byok_29.cs delete mode 100644 docs/.validation/csharp/debugging_10.cs delete mode 100644 docs/.validation/csharp/debugging_6.cs delete mode 100644 docs/.validation/csharp/debugging_7.cs delete mode 100644 docs/.validation/csharp/debugging_9.cs delete mode 100644 docs/.validation/csharp/error-handling_20.cs delete mode 100644 docs/.validation/csharp/error-handling_21.cs delete mode 100644 docs/.validation/csharp/getting-started_0.cs delete mode 100644 docs/.validation/csharp/getting-started_1.cs delete mode 100644 docs/.validation/csharp/getting-started_2.cs delete mode 100644 docs/.validation/csharp/getting-started_3.cs delete mode 100644 docs/.validation/csharp/getting-started_4.cs delete mode 100644 docs/.validation/csharp/getting-started_5.cs delete mode 100644 docs/.validation/csharp/index_26.cs delete mode 100644 docs/.validation/csharp/index_27.cs delete mode 100644 docs/.validation/csharp/index_28.cs delete mode 100644 docs/.validation/csharp/overview_19.cs delete mode 100644 docs/.validation/csharp/overview_8.cs delete mode 100644 docs/.validation/csharp/post-tool-use_17.cs delete mode 100644 docs/.validation/csharp/post-tool-use_18.cs delete mode 100644 docs/.validation/csharp/pre-tool-use_15.cs delete mode 100644 docs/.validation/csharp/pre-tool-use_16.cs delete mode 100644 docs/.validation/csharp/session-lifecycle_13.cs delete mode 100644 docs/.validation/csharp/session-lifecycle_14.cs delete mode 100644 docs/.validation/csharp/session-persistence_24.cs delete mode 100644 docs/.validation/csharp/session-persistence_25.cs delete mode 100644 docs/.validation/csharp/skills_22.cs delete mode 100644 docs/.validation/csharp/skills_23.cs delete mode 100644 docs/.validation/csharp/user-prompt-submitted_11.cs delete mode 100644 docs/.validation/csharp/user-prompt-submitted_12.cs delete mode 100644 docs/.validation/go/byok_7.go delete mode 100644 docs/.validation/go/getting-started_0.go delete mode 100644 docs/.validation/go/getting-started_1.go delete mode 100644 docs/.validation/go/getting-started_2.go delete mode 100644 docs/.validation/go/getting-started_3.go delete mode 100644 docs/.validation/go/go.mod delete mode 100644 docs/.validation/go/go.sum delete mode 100644 docs/.validation/go/overview_4.go delete mode 100644 docs/.validation/go/overview_5.go delete mode 100644 docs/.validation/go/skills_6.go delete mode 100644 docs/.validation/manifest.json delete mode 100644 docs/.validation/python/__pycache__/byok_31.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/debugging_6.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/debugging_7.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/error-handling_20.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/error-handling_21.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/getting-started_0.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/getting-started_1.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/getting-started_2.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/getting-started_3.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/getting-started_4.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/getting-started_5.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/index_27.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/index_28.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/index_29.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/index_30.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/overview_19.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/overview_8.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/post-tool-use_17.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/post-tool-use_18.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/pre-tool-use_15.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/pre-tool-use_16.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/session-lifecycle_11.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/session-lifecycle_12.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/session-lifecycle_13.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/session-lifecycle_14.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/session-persistence_24.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/session-persistence_25.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/session-persistence_26.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/skills_22.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/skills_23.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/user-prompt-submitted_10.cpython-314.pyc delete mode 100644 docs/.validation/python/__pycache__/user-prompt-submitted_9.cpython-314.pyc delete mode 100644 docs/.validation/python/byok_31.py delete mode 100644 docs/.validation/python/debugging_6.py delete mode 100644 docs/.validation/python/debugging_7.py delete mode 100644 docs/.validation/python/error-handling_20.py delete mode 100644 docs/.validation/python/error-handling_21.py delete mode 100644 docs/.validation/python/getting-started_0.py delete mode 100644 docs/.validation/python/getting-started_1.py delete mode 100644 docs/.validation/python/getting-started_2.py delete mode 100644 docs/.validation/python/getting-started_3.py delete mode 100644 docs/.validation/python/getting-started_4.py delete mode 100644 docs/.validation/python/getting-started_5.py delete mode 100644 docs/.validation/python/index_27.py delete mode 100644 docs/.validation/python/index_28.py delete mode 100644 docs/.validation/python/index_29.py delete mode 100644 docs/.validation/python/index_30.py delete mode 100644 docs/.validation/python/overview_19.py delete mode 100644 docs/.validation/python/overview_8.py delete mode 100644 docs/.validation/python/post-tool-use_17.py delete mode 100644 docs/.validation/python/post-tool-use_18.py delete mode 100644 docs/.validation/python/pre-tool-use_15.py delete mode 100644 docs/.validation/python/pre-tool-use_16.py delete mode 100644 docs/.validation/python/session-lifecycle_11.py delete mode 100644 docs/.validation/python/session-lifecycle_12.py delete mode 100644 docs/.validation/python/session-lifecycle_13.py delete mode 100644 docs/.validation/python/session-lifecycle_14.py delete mode 100644 docs/.validation/python/session-persistence_24.py delete mode 100644 docs/.validation/python/session-persistence_25.py delete mode 100644 docs/.validation/python/session-persistence_26.py delete mode 100644 docs/.validation/python/skills_22.py delete mode 100644 docs/.validation/python/skills_23.py delete mode 100644 docs/.validation/python/user-prompt-submitted_10.py delete mode 100644 docs/.validation/python/user-prompt-submitted_9.py delete mode 100644 docs/.validation/typescript/byok_85.ts delete mode 100644 docs/.validation/typescript/byok_86.ts delete mode 100644 docs/.validation/typescript/compatibility_15.ts delete mode 100644 docs/.validation/typescript/compatibility_16.ts delete mode 100644 docs/.validation/typescript/compatibility_17.ts delete mode 100644 docs/.validation/typescript/debugging_10.ts delete mode 100644 docs/.validation/typescript/debugging_11.ts delete mode 100644 docs/.validation/typescript/debugging_12.ts delete mode 100644 docs/.validation/typescript/debugging_13.ts delete mode 100644 docs/.validation/typescript/debugging_14.ts delete mode 100644 docs/.validation/typescript/debugging_9.ts delete mode 100644 docs/.validation/typescript/error-handling_57.ts delete mode 100644 docs/.validation/typescript/error-handling_58.ts delete mode 100644 docs/.validation/typescript/error-handling_59.ts delete mode 100644 docs/.validation/typescript/error-handling_60.ts delete mode 100644 docs/.validation/typescript/error-handling_61.ts delete mode 100644 docs/.validation/typescript/error-handling_62.ts delete mode 100644 docs/.validation/typescript/error-handling_63.ts delete mode 100644 docs/.validation/typescript/error-handling_64.ts delete mode 100644 docs/.validation/typescript/error-handling_65.ts delete mode 100644 docs/.validation/typescript/getting-started_0.ts delete mode 100644 docs/.validation/typescript/getting-started_1.ts delete mode 100644 docs/.validation/typescript/getting-started_2.ts delete mode 100644 docs/.validation/typescript/getting-started_3.ts delete mode 100644 docs/.validation/typescript/getting-started_4.ts delete mode 100644 docs/.validation/typescript/getting-started_5.ts delete mode 100644 docs/.validation/typescript/getting-started_6.ts delete mode 100644 docs/.validation/typescript/getting-started_7.ts delete mode 100644 docs/.validation/typescript/getting-started_8.ts delete mode 100644 docs/.validation/typescript/index_81.ts delete mode 100644 docs/.validation/typescript/index_82.ts delete mode 100644 docs/.validation/typescript/index_83.ts delete mode 100644 docs/.validation/typescript/index_84.ts delete mode 100644 docs/.validation/typescript/overview_18.ts delete mode 100644 docs/.validation/typescript/overview_19.ts delete mode 100644 docs/.validation/typescript/overview_53.ts delete mode 100644 docs/.validation/typescript/overview_54.ts delete mode 100644 docs/.validation/typescript/overview_55.ts delete mode 100644 docs/.validation/typescript/overview_56.ts delete mode 100644 docs/.validation/typescript/post-tool-use_45.ts delete mode 100644 docs/.validation/typescript/post-tool-use_46.ts delete mode 100644 docs/.validation/typescript/post-tool-use_47.ts delete mode 100644 docs/.validation/typescript/post-tool-use_48.ts delete mode 100644 docs/.validation/typescript/post-tool-use_49.ts delete mode 100644 docs/.validation/typescript/post-tool-use_50.ts delete mode 100644 docs/.validation/typescript/post-tool-use_51.ts delete mode 100644 docs/.validation/typescript/post-tool-use_52.ts delete mode 100644 docs/.validation/typescript/pre-tool-use_38.ts delete mode 100644 docs/.validation/typescript/pre-tool-use_39.ts delete mode 100644 docs/.validation/typescript/pre-tool-use_40.ts delete mode 100644 docs/.validation/typescript/pre-tool-use_41.ts delete mode 100644 docs/.validation/typescript/pre-tool-use_42.ts delete mode 100644 docs/.validation/typescript/pre-tool-use_43.ts delete mode 100644 docs/.validation/typescript/pre-tool-use_44.ts delete mode 100644 docs/.validation/typescript/session-lifecycle_29.ts delete mode 100644 docs/.validation/typescript/session-lifecycle_30.ts delete mode 100644 docs/.validation/typescript/session-lifecycle_31.ts delete mode 100644 docs/.validation/typescript/session-lifecycle_32.ts delete mode 100644 docs/.validation/typescript/session-lifecycle_33.ts delete mode 100644 docs/.validation/typescript/session-lifecycle_34.ts delete mode 100644 docs/.validation/typescript/session-lifecycle_35.ts delete mode 100644 docs/.validation/typescript/session-lifecycle_36.ts delete mode 100644 docs/.validation/typescript/session-lifecycle_37.ts delete mode 100644 docs/.validation/typescript/session-persistence_70.ts delete mode 100644 docs/.validation/typescript/session-persistence_71.ts delete mode 100644 docs/.validation/typescript/session-persistence_72.ts delete mode 100644 docs/.validation/typescript/session-persistence_73.ts delete mode 100644 docs/.validation/typescript/session-persistence_74.ts delete mode 100644 docs/.validation/typescript/session-persistence_75.ts delete mode 100644 docs/.validation/typescript/session-persistence_76.ts delete mode 100644 docs/.validation/typescript/session-persistence_77.ts delete mode 100644 docs/.validation/typescript/session-persistence_78.ts delete mode 100644 docs/.validation/typescript/session-persistence_79.ts delete mode 100644 docs/.validation/typescript/session-persistence_80.ts delete mode 100644 docs/.validation/typescript/skills_66.ts delete mode 100644 docs/.validation/typescript/skills_67.ts delete mode 100644 docs/.validation/typescript/skills_68.ts delete mode 100644 docs/.validation/typescript/skills_69.ts delete mode 100644 docs/.validation/typescript/tsconfig.json delete mode 100644 docs/.validation/typescript/user-prompt-submitted_20.ts delete mode 100644 docs/.validation/typescript/user-prompt-submitted_21.ts delete mode 100644 docs/.validation/typescript/user-prompt-submitted_22.ts delete mode 100644 docs/.validation/typescript/user-prompt-submitted_23.ts delete mode 100644 docs/.validation/typescript/user-prompt-submitted_24.ts delete mode 100644 docs/.validation/typescript/user-prompt-submitted_25.ts delete mode 100644 docs/.validation/typescript/user-prompt-submitted_26.ts delete mode 100644 docs/.validation/typescript/user-prompt-submitted_27.ts delete mode 100644 docs/.validation/typescript/user-prompt-submitted_28.ts diff --git a/docs/.validation/csharp/DocsValidation.csproj b/docs/.validation/csharp/DocsValidation.csproj deleted file mode 100644 index 026e7b55..00000000 --- a/docs/.validation/csharp/DocsValidation.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - Library - net8.0 - enable - enable - CS8019;CS0168;CS0219 - - - - - \ No newline at end of file diff --git a/docs/.validation/csharp/byok_29.cs b/docs/.validation/csharp/byok_29.cs deleted file mode 100644 index f0cd4022..00000000 --- a/docs/.validation/csharp/byok_29.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Source: auth/byok.md:143 -using GitHub.Copilot.SDK; - -await using var client = new CopilotClient(); -await using var session = await client.CreateSessionAsync(new SessionConfig -{ - Model = "gpt-5.2-codex", // Your deployment name - Provider = new ProviderConfig - { - Type = "openai", - BaseUrl = "https://your-resource.openai.azure.com/openai/v1/", - WireApi = "responses", // Use "completions" for older models - ApiKey = Environment.GetEnvironmentVariable("FOUNDRY_API_KEY"), - }, -}); - -var response = await session.SendAndWaitAsync(new MessageOptions -{ - Prompt = "What is 2+2?", -}); -Console.WriteLine(response?.Data.Content); \ No newline at end of file diff --git a/docs/.validation/csharp/debugging_10.cs b/docs/.validation/csharp/debugging_10.cs deleted file mode 100644 index 8052fc64..00000000 --- a/docs/.validation/csharp/debugging_10.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Source: mcp/debugging.md:269 -// Windows needs cmd /c for npx -["filesystem"] = new McpLocalServerConfig -{ - Type = "local", - Command = "cmd", - Args = new List { "/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "C:\\allowed\\path" }, - Tools = new List { "*" }, -} \ No newline at end of file diff --git a/docs/.validation/csharp/debugging_6.cs b/docs/.validation/csharp/debugging_6.cs deleted file mode 100644 index c9d5ad2a..00000000 --- a/docs/.validation/csharp/debugging_6.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Source: debugging.md:61 -using GitHub.Copilot.SDK; -using Microsoft.Extensions.Logging; - -// Using ILogger -var loggerFactory = LoggerFactory.Create(builder => -{ - builder.SetMinimumLevel(LogLevel.Debug); - builder.AddConsole(); -}); - -var client = new CopilotClient(new CopilotClientOptions -{ - LogLevel = "debug", - Logger = loggerFactory.CreateLogger() -}); \ No newline at end of file diff --git a/docs/.validation/csharp/debugging_7.cs b/docs/.validation/csharp/debugging_7.cs deleted file mode 100644 index ecc7c654..00000000 --- a/docs/.validation/csharp/debugging_7.cs +++ /dev/null @@ -1,5 +0,0 @@ -// Source: debugging.md:124 -var client = new CopilotClient(new CopilotClientOptions -{ - CliArgs = new[] { "--log-dir", "/path/to/logs" } -}); \ No newline at end of file diff --git a/docs/.validation/csharp/debugging_9.cs b/docs/.validation/csharp/debugging_9.cs deleted file mode 100644 index 03063bf6..00000000 --- a/docs/.validation/csharp/debugging_9.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Source: mcp/debugging.md:245 -// Correct configuration for .NET exe -["my-dotnet-server"] = new McpLocalServerConfig -{ - Type = "local", - Command = @"C:\Tools\MyServer\MyServer.exe", // Full path with .exe - Args = new List(), - Cwd = @"C:\Tools\MyServer", // Set working directory - Tools = new List { "*" }, -} - -// For dotnet tool (DLL) -["my-dotnet-tool"] = new McpLocalServerConfig -{ - Type = "local", - Command = "dotnet", - Args = new List { @"C:\Tools\MyTool\MyTool.dll" }, - Cwd = @"C:\Tools\MyTool", - Tools = new List { "*" }, -} \ No newline at end of file diff --git a/docs/.validation/csharp/error-handling_20.cs b/docs/.validation/csharp/error-handling_20.cs deleted file mode 100644 index efb63a56..00000000 --- a/docs/.validation/csharp/error-handling_20.cs +++ /dev/null @@ -1,4 +0,0 @@ -// Source: hooks/error-handling.md:52 -public delegate Task ErrorOccurredHandler( - ErrorOccurredHookInput input, - HookInvocation invocation); \ No newline at end of file diff --git a/docs/.validation/csharp/error-handling_21.cs b/docs/.validation/csharp/error-handling_21.cs deleted file mode 100644 index 1e86ee8a..00000000 --- a/docs/.validation/csharp/error-handling_21.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Source: hooks/error-handling.md:142 -var session = await client.CreateSessionAsync(new SessionConfig -{ - Hooks = new SessionHooks - { - OnErrorOccurred = (input, invocation) => - { - Console.Error.WriteLine($"[{invocation.SessionId}] Error: {input.Error}"); - Console.Error.WriteLine($" Context: {input.ErrorContext}"); - Console.Error.WriteLine($" Recoverable: {input.Recoverable}"); - return Task.FromResult(null); - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/csharp/getting-started_0.cs b/docs/.validation/csharp/getting-started_0.cs deleted file mode 100644 index d6b93384..00000000 --- a/docs/.validation/csharp/getting-started_0.cs +++ /dev/null @@ -1,8 +0,0 @@ -// Source: getting-started.md:209 -using GitHub.Copilot.SDK; - -await using var client = new CopilotClient(); -await using var session = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-4.1" }); - -var response = await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 2 + 2?" }); -Console.WriteLine(response?.Data.Content); \ No newline at end of file diff --git a/docs/.validation/csharp/getting-started_1.cs b/docs/.validation/csharp/getting-started_1.cs deleted file mode 100644 index e7a3fc91..00000000 --- a/docs/.validation/csharp/getting-started_1.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Source: getting-started.md:366 -using GitHub.Copilot.SDK; - -await using var client = new CopilotClient(); -await using var session = await client.CreateSessionAsync(new SessionConfig -{ - Model = "gpt-4.1", - Streaming = true, -}); - -// Listen for response chunks -session.On(ev => -{ - if (ev is AssistantMessageDeltaEvent deltaEvent) - { - Console.Write(deltaEvent.Data.DeltaContent); - } - if (ev is SessionIdleEvent) - { - Console.WriteLine(); - } -}); - -await session.SendAndWaitAsync(new MessageOptions { Prompt = "Tell me a short joke" }); \ No newline at end of file diff --git a/docs/.validation/csharp/getting-started_2.cs b/docs/.validation/csharp/getting-started_2.cs deleted file mode 100644 index 628616d4..00000000 --- a/docs/.validation/csharp/getting-started_2.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Source: getting-started.md:476 -// Subscribe to all events -var unsubscribe = session.On(ev => Console.WriteLine($"Event: {ev.Type}")); - -// Filter by event type using pattern matching -session.On(ev => -{ - switch (ev) - { - case SessionIdleEvent: - Console.WriteLine("Session is idle"); - break; - case AssistantMessageEvent msg: - Console.WriteLine($"Message: {msg.Data.Content}"); - break; - } -}); - -// Later, to unsubscribe: -unsubscribe.Dispose(); \ No newline at end of file diff --git a/docs/.validation/csharp/getting-started_3.cs b/docs/.validation/csharp/getting-started_3.cs deleted file mode 100644 index 44302592..00000000 --- a/docs/.validation/csharp/getting-started_3.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Source: getting-started.md:706 -using GitHub.Copilot.SDK; -using Microsoft.Extensions.AI; -using System.ComponentModel; - -await using var client = new CopilotClient(); - -// Define a tool that Copilot can call -var getWeather = AIFunctionFactory.Create( - ([Description("The city name")] string city) => - { - // In a real app, you'd call a weather API here - var conditions = new[] { "sunny", "cloudy", "rainy", "partly cloudy" }; - var temp = Random.Shared.Next(50, 80); - var condition = conditions[Random.Shared.Next(conditions.Length)]; - return new { city, temperature = $"{temp}°F", condition }; - }, - "get_weather", - "Get the current weather for a city" -); - -await using var session = await client.CreateSessionAsync(new SessionConfig -{ - Model = "gpt-4.1", - Streaming = true, - Tools = [getWeather], -}); - -session.On(ev => -{ - if (ev is AssistantMessageDeltaEvent deltaEvent) - { - Console.Write(deltaEvent.Data.DeltaContent); - } - if (ev is SessionIdleEvent) - { - Console.WriteLine(); - } -}); - -await session.SendAndWaitAsync(new MessageOptions -{ - Prompt = "What's the weather like in Seattle and Tokyo?", -}); \ No newline at end of file diff --git a/docs/.validation/csharp/getting-started_4.cs b/docs/.validation/csharp/getting-started_4.cs deleted file mode 100644 index 2448e0b4..00000000 --- a/docs/.validation/csharp/getting-started_4.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Source: getting-started.md:1015 -using GitHub.Copilot.SDK; -using Microsoft.Extensions.AI; -using System.ComponentModel; - -// Define the weather tool using AIFunctionFactory -var getWeather = AIFunctionFactory.Create( - ([Description("The city name")] string city) => - { - var conditions = new[] { "sunny", "cloudy", "rainy", "partly cloudy" }; - var temp = Random.Shared.Next(50, 80); - var condition = conditions[Random.Shared.Next(conditions.Length)]; - return new { city, temperature = $"{temp}°F", condition }; - }, - "get_weather", - "Get the current weather for a city"); - -await using var client = new CopilotClient(); -await using var session = await client.CreateSessionAsync(new SessionConfig -{ - Model = "gpt-4.1", - Streaming = true, - Tools = [getWeather] -}); - -// Listen for response chunks -session.On(ev => -{ - if (ev is AssistantMessageDeltaEvent deltaEvent) - { - Console.Write(deltaEvent.Data.DeltaContent); - } - if (ev is SessionIdleEvent) - { - Console.WriteLine(); - } -}); - -Console.WriteLine("🌤️ Weather Assistant (type 'exit' to quit)"); -Console.WriteLine(" Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'\n"); - -while (true) -{ - Console.Write("You: "); - var input = Console.ReadLine(); - - if (string.IsNullOrEmpty(input) || input.Equals("exit", StringComparison.OrdinalIgnoreCase)) - { - break; - } - - Console.Write("Assistant: "); - await session.SendAndWaitAsync(new MessageOptions { Prompt = input }); - Console.WriteLine("\n"); -} \ No newline at end of file diff --git a/docs/.validation/csharp/getting-started_5.cs b/docs/.validation/csharp/getting-started_5.cs deleted file mode 100644 index 8ff516ba..00000000 --- a/docs/.validation/csharp/getting-started_5.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Source: getting-started.md:1251 -using GitHub.Copilot.SDK; - -using var client = new CopilotClient(new CopilotClientOptions -{ - CliUrl = "localhost:4321", - UseStdio = false -}); - -// Use the client normally -await using var session = await client.CreateSessionAsync(); -// ... \ No newline at end of file diff --git a/docs/.validation/csharp/index_26.cs b/docs/.validation/csharp/index_26.cs deleted file mode 100644 index 12f21643..00000000 --- a/docs/.validation/csharp/index_26.cs +++ /dev/null @@ -1,5 +0,0 @@ -// Source: auth/index.md:66 -using GitHub.Copilot.SDK; - -// Default: uses logged-in user credentials -await using var client = new CopilotClient(); \ No newline at end of file diff --git a/docs/.validation/csharp/index_27.cs b/docs/.validation/csharp/index_27.cs deleted file mode 100644 index 69c4f9eb..00000000 --- a/docs/.validation/csharp/index_27.cs +++ /dev/null @@ -1,8 +0,0 @@ -// Source: auth/index.md:138 -using GitHub.Copilot.SDK; - -await using var client = new CopilotClient(new CopilotClientOptions -{ - GithubToken = userAccessToken, // Token from OAuth flow - UseLoggedInUser = false, // Don't use stored CLI credentials -}); \ No newline at end of file diff --git a/docs/.validation/csharp/index_28.cs b/docs/.validation/csharp/index_28.cs deleted file mode 100644 index f809c65d..00000000 --- a/docs/.validation/csharp/index_28.cs +++ /dev/null @@ -1,5 +0,0 @@ -// Source: auth/index.md:279 -await using var client = new CopilotClient(new CopilotClientOptions -{ - UseLoggedInUser = false, // Only use explicit tokens -}); \ No newline at end of file diff --git a/docs/.validation/csharp/overview_19.cs b/docs/.validation/csharp/overview_19.cs deleted file mode 100644 index 7b68796e..00000000 --- a/docs/.validation/csharp/overview_19.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Source: hooks/overview.md:127 -using GitHub.Copilot.SDK; - -var client = new CopilotClient(); - -var session = await client.CreateSessionAsync(new SessionConfig -{ - Hooks = new SessionHooks - { - OnPreToolUse = (input, invocation) => - { - Console.WriteLine($"Tool called: {input.ToolName}"); - return Task.FromResult( - new PreToolUseHookOutput { PermissionDecision = "allow" } - ); - }, - OnPostToolUse = (input, invocation) => - { - Console.WriteLine($"Tool result: {input.ToolResult}"); - return Task.FromResult(null); - }, - OnSessionStart = (input, invocation) => - { - return Task.FromResult( - new SessionStartHookOutput { AdditionalContext = "User prefers concise answers." } - ); - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/csharp/overview_8.cs b/docs/.validation/csharp/overview_8.cs deleted file mode 100644 index 196591cd..00000000 --- a/docs/.validation/csharp/overview_8.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Source: mcp/overview.md:143 -using GitHub.Copilot.SDK; - -await using var client = new CopilotClient(); -await using var session = await client.CreateSessionAsync(new SessionConfig -{ - Model = "gpt-5", - McpServers = new Dictionary - { - ["my-local-server"] = new McpLocalServerConfig - { - Type = "local", - Command = "node", - Args = new[] { "./mcp-server.js" }, - Tools = new[] { "*" }, - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/csharp/post-tool-use_17.cs b/docs/.validation/csharp/post-tool-use_17.cs deleted file mode 100644 index 2a55ed99..00000000 --- a/docs/.validation/csharp/post-tool-use_17.cs +++ /dev/null @@ -1,4 +0,0 @@ -// Source: hooks/post-tool-use.md:52 -public delegate Task PostToolUseHandler( - PostToolUseHookInput input, - HookInvocation invocation); \ No newline at end of file diff --git a/docs/.validation/csharp/post-tool-use_18.cs b/docs/.validation/csharp/post-tool-use_18.cs deleted file mode 100644 index 7435800d..00000000 --- a/docs/.validation/csharp/post-tool-use_18.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Source: hooks/post-tool-use.md:141 -var session = await client.CreateSessionAsync(new SessionConfig -{ - Hooks = new SessionHooks - { - OnPostToolUse = (input, invocation) => - { - Console.WriteLine($"[{invocation.SessionId}] Tool: {input.ToolName}"); - Console.WriteLine($" Args: {input.ToolArgs}"); - Console.WriteLine($" Result: {input.ToolResult}"); - return Task.FromResult(null); - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/csharp/pre-tool-use_15.cs b/docs/.validation/csharp/pre-tool-use_15.cs deleted file mode 100644 index 5f692774..00000000 --- a/docs/.validation/csharp/pre-tool-use_15.cs +++ /dev/null @@ -1,4 +0,0 @@ -// Source: hooks/pre-tool-use.md:52 -public delegate Task PreToolUseHandler( - PreToolUseHookInput input, - HookInvocation invocation); \ No newline at end of file diff --git a/docs/.validation/csharp/pre-tool-use_16.cs b/docs/.validation/csharp/pre-tool-use_16.cs deleted file mode 100644 index f5401e5b..00000000 --- a/docs/.validation/csharp/pre-tool-use_16.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Source: hooks/pre-tool-use.md:149 -var session = await client.CreateSessionAsync(new SessionConfig -{ - Hooks = new SessionHooks - { - OnPreToolUse = (input, invocation) => - { - Console.WriteLine($"[{invocation.SessionId}] Calling {input.ToolName}"); - Console.WriteLine($" Args: {input.ToolArgs}"); - return Task.FromResult( - new PreToolUseHookOutput { PermissionDecision = "allow" } - ); - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/csharp/session-lifecycle_13.cs b/docs/.validation/csharp/session-lifecycle_13.cs deleted file mode 100644 index 68268922..00000000 --- a/docs/.validation/csharp/session-lifecycle_13.cs +++ /dev/null @@ -1,4 +0,0 @@ -// Source: hooks/session-lifecycle.md:56 -public delegate Task SessionStartHandler( - SessionStartHookInput input, - HookInvocation invocation); \ No newline at end of file diff --git a/docs/.validation/csharp/session-lifecycle_14.cs b/docs/.validation/csharp/session-lifecycle_14.cs deleted file mode 100644 index 0783ad30..00000000 --- a/docs/.validation/csharp/session-lifecycle_14.cs +++ /dev/null @@ -1,4 +0,0 @@ -// Source: hooks/session-lifecycle.md:233 -public delegate Task SessionEndHandler( - SessionEndHookInput input, - HookInvocation invocation); \ No newline at end of file diff --git a/docs/.validation/csharp/session-persistence_24.cs b/docs/.validation/csharp/session-persistence_24.cs deleted file mode 100644 index fdc0b5f4..00000000 --- a/docs/.validation/csharp/session-persistence_24.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Source: guides/session-persistence.md:87 -using GitHub.Copilot.SDK; - -var client = new CopilotClient(); - -// Create a session with a meaningful ID -var session = await client.CreateSessionAsync(new SessionConfig -{ - SessionId = "user-123-task-456", - Model = "gpt-5.2-codex", -}); - -// Do some work... -await session.SendAndWaitAsync(new MessageOptions { Prompt = "Analyze my codebase" }); - -// Session state is automatically persisted \ No newline at end of file diff --git a/docs/.validation/csharp/session-persistence_25.cs b/docs/.validation/csharp/session-persistence_25.cs deleted file mode 100644 index 54ec1f16..00000000 --- a/docs/.validation/csharp/session-persistence_25.cs +++ /dev/null @@ -1,6 +0,0 @@ -// Source: guides/session-persistence.md:158 -// Resume from a different client instance (or after restart) -var session = await client.ResumeSessionAsync("user-123-task-456"); - -// Continue where you left off -await session.SendAndWaitAsync(new MessageOptions { Prompt = "What did we discuss earlier?" }); \ No newline at end of file diff --git a/docs/.validation/csharp/skills_22.cs b/docs/.validation/csharp/skills_22.cs deleted file mode 100644 index 74ab5ce0..00000000 --- a/docs/.validation/csharp/skills_22.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Source: guides/skills.md:118 -using GitHub.Copilot.SDK; - -await using var client = new CopilotClient(); -await using var session = await client.CreateSessionAsync(new SessionConfig -{ - Model = "gpt-4.1", - SkillDirectories = new List - { - "./skills/code-review", - "./skills/documentation", - "~/.copilot/skills", // User-level skills - }, -}); - -// Copilot now has access to skills in those directories -await session.SendAndWaitAsync(new MessageOptions -{ - Prompt = "Review this code for security issues" -}); \ No newline at end of file diff --git a/docs/.validation/csharp/skills_23.cs b/docs/.validation/csharp/skills_23.cs deleted file mode 100644 index b644d890..00000000 --- a/docs/.validation/csharp/skills_23.cs +++ /dev/null @@ -1,6 +0,0 @@ -// Source: guides/skills.md:186 -var session = await client.CreateSessionAsync(new SessionConfig -{ - SkillDirectories = new List { "./skills" }, - DisabledSkills = new List { "experimental-feature", "deprecated-tool" }, -}); \ No newline at end of file diff --git a/docs/.validation/csharp/user-prompt-submitted_11.cs b/docs/.validation/csharp/user-prompt-submitted_11.cs deleted file mode 100644 index 22c97566..00000000 --- a/docs/.validation/csharp/user-prompt-submitted_11.cs +++ /dev/null @@ -1,4 +0,0 @@ -// Source: hooks/user-prompt-submitted.md:52 -public delegate Task UserPromptSubmittedHandler( - UserPromptSubmittedHookInput input, - HookInvocation invocation); \ No newline at end of file diff --git a/docs/.validation/csharp/user-prompt-submitted_12.cs b/docs/.validation/csharp/user-prompt-submitted_12.cs deleted file mode 100644 index 72d7cbb2..00000000 --- a/docs/.validation/csharp/user-prompt-submitted_12.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Source: hooks/user-prompt-submitted.md:133 -var session = await client.CreateSessionAsync(new SessionConfig -{ - Hooks = new SessionHooks - { - OnUserPromptSubmitted = (input, invocation) => - { - Console.WriteLine($"[{invocation.SessionId}] User: {input.Prompt}"); - return Task.FromResult(null); - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/go/byok_7.go b/docs/.validation/go/byok_7.go deleted file mode 100644 index fd4d6eb2..00000000 --- a/docs/.validation/go/byok_7.go +++ /dev/null @@ -1,40 +0,0 @@ -// Source: auth/byok.md:96 -package main - -import ( - "context" - "fmt" - "os" - copilot "github.com/github/copilot-sdk/go" -) - -func main() { - ctx := context.Background() - client := copilot.NewClient(nil) - if err := client.Start(ctx); err != nil { - panic(err) - } - defer client.Stop() - - session, err := client.CreateSession(ctx, &copilot.SessionConfig{ - Model: "gpt-5.2-codex", // Your deployment name - Provider: &copilot.ProviderConfig{ - Type: "openai", - BaseURL: "https://your-resource.openai.azure.com/openai/v1/", - WireApi: "responses", // Use "completions" for older models - APIKey: os.Getenv("FOUNDRY_API_KEY"), - }, - }) - if err != nil { - panic(err) - } - - response, err := session.SendAndWait(ctx, copilot.MessageOptions{ - Prompt: "What is 2+2?", - }) - if err != nil { - panic(err) - } - - fmt.Println(*response.Data.Content) -} \ No newline at end of file diff --git a/docs/.validation/go/getting-started_0.go b/docs/.validation/go/getting-started_0.go deleted file mode 100644 index 78daf3fb..00000000 --- a/docs/.validation/go/getting-started_0.go +++ /dev/null @@ -1,33 +0,0 @@ -// Source: getting-started.md:161 -package main - -import ( - "context" - "fmt" - "log" - "os" - - copilot "github.com/github/copilot-sdk/go" -) - -func main() { - ctx := context.Background() - client := copilot.NewClient(nil) - if err := client.Start(ctx); err != nil { - log.Fatal(err) - } - defer client.Stop() - - session, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-4.1"}) - if err != nil { - log.Fatal(err) - } - - response, err := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "What is 2 + 2?"}) - if err != nil { - log.Fatal(err) - } - - fmt.Println(*response.Data.Content) - os.Exit(0) -} \ No newline at end of file diff --git a/docs/.validation/go/getting-started_1.go b/docs/.validation/go/getting-started_1.go deleted file mode 100644 index 5212d578..00000000 --- a/docs/.validation/go/getting-started_1.go +++ /dev/null @@ -1,44 +0,0 @@ -// Source: getting-started.md:313 -package main - -import ( - "context" - "fmt" - "log" - "os" - - copilot "github.com/github/copilot-sdk/go" -) - -func main() { - ctx := context.Background() - client := copilot.NewClient(nil) - if err := client.Start(ctx); err != nil { - log.Fatal(err) - } - defer client.Stop() - - session, err := client.CreateSession(ctx, &copilot.SessionConfig{ - Model: "gpt-4.1", - Streaming: true, - }) - if err != nil { - log.Fatal(err) - } - - // Listen for response chunks - session.On(func(event copilot.SessionEvent) { - if event.Type == "assistant.message_delta" { - fmt.Print(*event.Data.DeltaContent) - } - if event.Type == "session.idle" { - fmt.Println() - } - }) - - _, err = session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Tell me a short joke"}) - if err != nil { - log.Fatal(err) - } - os.Exit(0) -} \ No newline at end of file diff --git a/docs/.validation/go/getting-started_2.go b/docs/.validation/go/getting-started_2.go deleted file mode 100644 index 17f4248a..00000000 --- a/docs/.validation/go/getting-started_2.go +++ /dev/null @@ -1,77 +0,0 @@ -// Source: getting-started.md:620 -package main - -import ( - "context" - "fmt" - "log" - "math/rand" - "os" - - copilot "github.com/github/copilot-sdk/go" -) - -// Define the parameter type -type WeatherParams struct { - City string `json:"city" jsonschema:"The city name"` -} - -// Define the return type -type WeatherResult struct { - City string `json:"city"` - Temperature string `json:"temperature"` - Condition string `json:"condition"` -} - -func main() { - ctx := context.Background() - - // Define a tool that Copilot can call - getWeather := copilot.DefineTool( - "get_weather", - "Get the current weather for a city", - func(params WeatherParams, inv copilot.ToolInvocation) (WeatherResult, error) { - // In a real app, you'd call a weather API here - conditions := []string{"sunny", "cloudy", "rainy", "partly cloudy"} - temp := rand.Intn(30) + 50 - condition := conditions[rand.Intn(len(conditions))] - return WeatherResult{ - City: params.City, - Temperature: fmt.Sprintf("%d°F", temp), - Condition: condition, - }, nil - }, - ) - - client := copilot.NewClient(nil) - if err := client.Start(ctx); err != nil { - log.Fatal(err) - } - defer client.Stop() - - session, err := client.CreateSession(ctx, &copilot.SessionConfig{ - Model: "gpt-4.1", - Streaming: true, - Tools: []copilot.Tool{getWeather}, - }) - if err != nil { - log.Fatal(err) - } - - session.On(func(event copilot.SessionEvent) { - if event.Type == "assistant.message_delta" { - fmt.Print(*event.Data.DeltaContent) - } - if event.Type == "session.idle" { - fmt.Println() - } - }) - - _, err = session.SendAndWait(ctx, copilot.MessageOptions{ - Prompt: "What's the weather like in Seattle and Tokyo?", - }) - if err != nil { - log.Fatal(err) - } - os.Exit(0) -} \ No newline at end of file diff --git a/docs/.validation/go/getting-started_3.go b/docs/.validation/go/getting-started_3.go deleted file mode 100644 index ed35860b..00000000 --- a/docs/.validation/go/getting-started_3.go +++ /dev/null @@ -1,95 +0,0 @@ -// Source: getting-started.md:905 -package main - -import ( - "bufio" - "context" - "fmt" - "log" - "math/rand" - "os" - "strings" - - copilot "github.com/github/copilot-sdk/go" -) - -type WeatherParams struct { - City string `json:"city" jsonschema:"The city name"` -} - -type WeatherResult struct { - City string `json:"city"` - Temperature string `json:"temperature"` - Condition string `json:"condition"` -} - -func main() { - ctx := context.Background() - - getWeather := copilot.DefineTool( - "get_weather", - "Get the current weather for a city", - func(params WeatherParams, inv copilot.ToolInvocation) (WeatherResult, error) { - conditions := []string{"sunny", "cloudy", "rainy", "partly cloudy"} - temp := rand.Intn(30) + 50 - condition := conditions[rand.Intn(len(conditions))] - return WeatherResult{ - City: params.City, - Temperature: fmt.Sprintf("%d°F", temp), - Condition: condition, - }, nil - }, - ) - - client := copilot.NewClient(nil) - if err := client.Start(ctx); err != nil { - log.Fatal(err) - } - defer client.Stop() - - session, err := client.CreateSession(ctx, &copilot.SessionConfig{ - Model: "gpt-4.1", - Streaming: true, - Tools: []copilot.Tool{getWeather}, - }) - if err != nil { - log.Fatal(err) - } - - session.On(func(event copilot.SessionEvent) { - if event.Type == "assistant.message_delta" { - if event.Data.DeltaContent != nil { - fmt.Print(*event.Data.DeltaContent) - } - } - if event.Type == "session.idle" { - fmt.Println() - } - }) - - fmt.Println("🌤️ Weather Assistant (type 'exit' to quit)") - fmt.Println(" Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'\n") - - scanner := bufio.NewScanner(os.Stdin) - for { - fmt.Print("You: ") - if !scanner.Scan() { - break - } - input := scanner.Text() - if strings.ToLower(input) == "exit" { - break - } - - fmt.Print("Assistant: ") - _, err = session.SendAndWait(ctx, copilot.MessageOptions{Prompt: input}) - if err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - break - } - fmt.Println() - } - if err := scanner.Err(); err != nil { - fmt.Fprintf(os.Stderr, "Input error: %v\n", err) - } -} \ No newline at end of file diff --git a/docs/.validation/go/go.mod b/docs/.validation/go/go.mod deleted file mode 100644 index 17738113..00000000 --- a/docs/.validation/go/go.mod +++ /dev/null @@ -1,9 +0,0 @@ -module docs-validation - -go 1.24 - -require github.com/github/copilot-sdk/go v0.0.0 - -require github.com/google/jsonschema-go v0.4.2 // indirect - -replace github.com/github/copilot-sdk/go => /Users/patrick/projects/copilot-sdk/go diff --git a/docs/.validation/go/go.sum b/docs/.validation/go/go.sum deleted file mode 100644 index 6e171099..00000000 --- a/docs/.validation/go/go.sum +++ /dev/null @@ -1,4 +0,0 @@ -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= -github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= diff --git a/docs/.validation/go/overview_4.go b/docs/.validation/go/overview_4.go deleted file mode 100644 index a0798915..00000000 --- a/docs/.validation/go/overview_4.go +++ /dev/null @@ -1,36 +0,0 @@ -// Source: mcp/overview.md:103 -package main - -import ( - "context" - "log" - copilot "github.com/github/copilot-sdk/go" -) - -func main() { - ctx := context.Background() - client := copilot.NewClient(nil) - if err := client.Start(ctx); err != nil { - log.Fatal(err) - } - defer client.Stop() - - // MCPServerConfig is map[string]any for flexibility - session, err := client.CreateSession(ctx, &copilot.SessionConfig{ - Model: "gpt-5", - MCPServers: map[string]copilot.MCPServerConfig{ - "my-local-server": { - "type": "local", - "command": "node", - "args": []string{"./mcp-server.js"}, - "tools": []string{"*"}, - }, - }, - }) - if err != nil { - log.Fatal(err) - } - defer session.Destroy() - - // Use the session... -} \ No newline at end of file diff --git a/docs/.validation/go/overview_5.go b/docs/.validation/go/overview_5.go deleted file mode 100644 index 0bba16ca..00000000 --- a/docs/.validation/go/overview_5.go +++ /dev/null @@ -1,33 +0,0 @@ -// Source: hooks/overview.md:87 -package main - -import ( - "context" - "fmt" - copilot "github.com/github/copilot-sdk/go" -) - -func main() { - client := copilot.NewClient(nil) - - session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{ - Hooks: &copilot.SessionHooks{ - OnPreToolUse: func(input copilot.PreToolUseHookInput, inv copilot.HookInvocation) (*copilot.PreToolUseHookOutput, error) { - fmt.Printf("Tool called: %s\n", input.ToolName) - return &copilot.PreToolUseHookOutput{ - PermissionDecision: "allow", - }, nil - }, - OnPostToolUse: func(input copilot.PostToolUseHookInput, inv copilot.HookInvocation) (*copilot.PostToolUseHookOutput, error) { - fmt.Printf("Tool result: %v\n", input.ToolResult) - return nil, nil - }, - OnSessionStart: func(input copilot.SessionStartHookInput, inv copilot.HookInvocation) (*copilot.SessionStartHookOutput, error) { - return &copilot.SessionStartHookOutput{ - AdditionalContext: "User prefers concise answers.", - }, nil - }, - }, - }) - _ = session -} \ No newline at end of file diff --git a/docs/.validation/go/skills_6.go b/docs/.validation/go/skills_6.go deleted file mode 100644 index 8655edf5..00000000 --- a/docs/.validation/go/skills_6.go +++ /dev/null @@ -1,37 +0,0 @@ -// Source: guides/skills.md:74 -package main - -import ( - "context" - "log" - copilot "github.com/github/copilot-sdk/go" -) - -func main() { - ctx := context.Background() - client := copilot.NewClient(nil) - if err := client.Start(ctx); err != nil { - log.Fatal(err) - } - defer client.Stop() - - session, err := client.CreateSession(ctx, &copilot.SessionConfig{ - Model: "gpt-4.1", - SkillDirectories: []string{ - "./skills/code-review", - "./skills/documentation", - "~/.copilot/skills", // User-level skills - }, - }) - if err != nil { - log.Fatal(err) - } - - // Copilot now has access to skills in those directories - _, err = session.SendAndWait(ctx, copilot.MessageOptions{ - Prompt: "Review this code for security issues", - }) - if err != nil { - log.Fatal(err) - } -} \ No newline at end of file diff --git a/docs/.validation/manifest.json b/docs/.validation/manifest.json deleted file mode 100644 index c0e970da..00000000 --- a/docs/.validation/manifest.json +++ /dev/null @@ -1,1104 +0,0 @@ -{ - "extractedAt": "2026-02-04T05:48:40.133Z", - "blocks": [ - { - "id": "typescript/getting-started_0.ts", - "sourceFile": "getting-started.md", - "sourceLine": 104, - "language": "typescript", - "outputFile": "typescript/getting-started_0.ts" - }, - { - "id": "python/getting-started_0.py", - "sourceFile": "getting-started.md", - "sourceLine": 130, - "language": "python", - "outputFile": "python/getting-started_0.py" - }, - { - "id": "go/getting-started_0.go", - "sourceFile": "getting-started.md", - "sourceLine": 161, - "language": "go", - "outputFile": "go/getting-started_0.go" - }, - { - "id": "csharp/getting-started_0.cs", - "sourceFile": "getting-started.md", - "sourceLine": 209, - "language": "csharp", - "outputFile": "csharp/getting-started_0.cs" - }, - { - "id": "typescript/getting-started_1.ts", - "sourceFile": "getting-started.md", - "sourceLine": 244, - "language": "typescript", - "outputFile": "typescript/getting-started_1.ts" - }, - { - "id": "python/getting-started_1.py", - "sourceFile": "getting-started.md", - "sourceLine": 274, - "language": "python", - "outputFile": "python/getting-started_1.py" - }, - { - "id": "go/getting-started_1.go", - "sourceFile": "getting-started.md", - "sourceLine": 313, - "language": "go", - "outputFile": "go/getting-started_1.go" - }, - { - "id": "csharp/getting-started_1.cs", - "sourceFile": "getting-started.md", - "sourceLine": 366, - "language": "csharp", - "outputFile": "csharp/getting-started_1.cs" - }, - { - "id": "typescript/getting-started_2.ts", - "sourceFile": "getting-started.md", - "sourceLine": 408, - "language": "typescript", - "outputFile": "typescript/getting-started_2.ts" - }, - { - "id": "python/getting-started_2.py", - "sourceFile": "getting-started.md", - "sourceLine": 429, - "language": "python", - "outputFile": "python/getting-started_2.py" - }, - { - "id": "csharp/getting-started_2.cs", - "sourceFile": "getting-started.md", - "sourceLine": 476, - "language": "csharp", - "outputFile": "csharp/getting-started_2.cs" - }, - { - "id": "typescript/getting-started_3.ts", - "sourceFile": "getting-started.md", - "sourceLine": 509, - "language": "typescript", - "outputFile": "typescript/getting-started_3.ts" - }, - { - "id": "python/getting-started_3.py", - "sourceFile": "getting-started.md", - "sourceLine": 562, - "language": "python", - "outputFile": "python/getting-started_3.py" - }, - { - "id": "go/getting-started_2.go", - "sourceFile": "getting-started.md", - "sourceLine": 620, - "language": "go", - "outputFile": "go/getting-started_2.go" - }, - { - "id": "csharp/getting-started_3.cs", - "sourceFile": "getting-started.md", - "sourceLine": 706, - "language": "csharp", - "outputFile": "csharp/getting-started_3.cs" - }, - { - "id": "typescript/getting-started_4.ts", - "sourceFile": "getting-started.md", - "sourceLine": 763, - "language": "typescript", - "outputFile": "typescript/getting-started_4.ts" - }, - { - "id": "python/getting-started_4.py", - "sourceFile": "getting-started.md", - "sourceLine": 834, - "language": "python", - "outputFile": "python/getting-started_4.py" - }, - { - "id": "go/getting-started_3.go", - "sourceFile": "getting-started.md", - "sourceLine": 905, - "language": "go", - "outputFile": "go/getting-started_3.go" - }, - { - "id": "csharp/getting-started_4.cs", - "sourceFile": "getting-started.md", - "sourceLine": 1015, - "language": "csharp", - "outputFile": "csharp/getting-started_4.cs" - }, - { - "id": "typescript/getting-started_5.ts", - "sourceFile": "getting-started.md", - "sourceLine": 1126, - "language": "typescript", - "outputFile": "typescript/getting-started_5.ts" - }, - { - "id": "typescript/getting-started_6.ts", - "sourceFile": "getting-started.md", - "sourceLine": 1143, - "language": "typescript", - "outputFile": "typescript/getting-started_6.ts" - }, - { - "id": "typescript/getting-started_7.ts", - "sourceFile": "getting-started.md", - "sourceLine": 1158, - "language": "typescript", - "outputFile": "typescript/getting-started_7.ts" - }, - { - "id": "typescript/getting-started_8.ts", - "sourceFile": "getting-started.md", - "sourceLine": 1193, - "language": "typescript", - "outputFile": "typescript/getting-started_8.ts" - }, - { - "id": "python/getting-started_5.py", - "sourceFile": "getting-started.md", - "sourceLine": 1210, - "language": "python", - "outputFile": "python/getting-started_5.py" - }, - { - "id": "csharp/getting-started_5.cs", - "sourceFile": "getting-started.md", - "sourceLine": 1251, - "language": "csharp", - "outputFile": "csharp/getting-started_5.cs" - }, - { - "id": "typescript/debugging_9.ts", - "sourceFile": "debugging.md", - "sourceLine": 23, - "language": "typescript", - "outputFile": "typescript/debugging_9.ts" - }, - { - "id": "python/debugging_6.py", - "sourceFile": "debugging.md", - "sourceLine": 36, - "language": "python", - "outputFile": "python/debugging_6.py" - }, - { - "id": "csharp/debugging_6.cs", - "sourceFile": "debugging.md", - "sourceLine": 61, - "language": "csharp", - "outputFile": "csharp/debugging_6.cs" - }, - { - "id": "typescript/debugging_10.ts", - "sourceFile": "debugging.md", - "sourceLine": 88, - "language": "typescript", - "outputFile": "typescript/debugging_10.ts" - }, - { - "id": "python/debugging_7.py", - "sourceFile": "debugging.md", - "sourceLine": 99, - "language": "python", - "outputFile": "python/debugging_7.py" - }, - { - "id": "csharp/debugging_7.cs", - "sourceFile": "debugging.md", - "sourceLine": 124, - "language": "csharp", - "outputFile": "csharp/debugging_7.cs" - }, - { - "id": "typescript/debugging_11.ts", - "sourceFile": "debugging.md", - "sourceLine": 326, - "language": "typescript", - "outputFile": "typescript/debugging_11.ts" - }, - { - "id": "typescript/debugging_12.ts", - "sourceFile": "debugging.md", - "sourceLine": 333, - "language": "typescript", - "outputFile": "typescript/debugging_12.ts" - }, - { - "id": "typescript/debugging_13.ts", - "sourceFile": "debugging.md", - "sourceLine": 341, - "language": "typescript", - "outputFile": "typescript/debugging_13.ts" - }, - { - "id": "typescript/debugging_14.ts", - "sourceFile": "debugging.md", - "sourceLine": 416, - "language": "typescript", - "outputFile": "typescript/debugging_14.ts" - }, - { - "id": "typescript/compatibility_15.ts", - "sourceFile": "compatibility.md", - "sourceLine": 129, - "language": "typescript", - "outputFile": "typescript/compatibility_15.ts" - }, - { - "id": "typescript/compatibility_16.ts", - "sourceFile": "compatibility.md", - "sourceLine": 148, - "language": "typescript", - "outputFile": "typescript/compatibility_16.ts" - }, - { - "id": "typescript/compatibility_17.ts", - "sourceFile": "compatibility.md", - "sourceLine": 161, - "language": "typescript", - "outputFile": "typescript/compatibility_17.ts" - }, - { - "id": "typescript/overview_18.ts", - "sourceFile": "mcp/overview.md", - "sourceLine": 30, - "language": "typescript", - "outputFile": "typescript/overview_18.ts" - }, - { - "id": "python/overview_8.py", - "sourceFile": "mcp/overview.md", - "sourceLine": 60, - "language": "python", - "outputFile": "python/overview_8.py" - }, - { - "id": "go/overview_4.go", - "sourceFile": "mcp/overview.md", - "sourceLine": 103, - "language": "go", - "outputFile": "go/overview_4.go" - }, - { - "id": "csharp/overview_8.cs", - "sourceFile": "mcp/overview.md", - "sourceLine": 143, - "language": "csharp", - "outputFile": "csharp/overview_8.cs" - }, - { - "id": "typescript/overview_19.ts", - "sourceFile": "mcp/overview.md", - "sourceLine": 167, - "language": "typescript", - "outputFile": "typescript/overview_19.ts" - }, - { - "id": "csharp/debugging_9.cs", - "sourceFile": "mcp/debugging.md", - "sourceLine": 245, - "language": "csharp", - "outputFile": "csharp/debugging_9.cs" - }, - { - "id": "csharp/debugging_10.cs", - "sourceFile": "mcp/debugging.md", - "sourceLine": 269, - "language": "csharp", - "outputFile": "csharp/debugging_10.cs" - }, - { - "id": "typescript/user-prompt-submitted_20.ts", - "sourceFile": "hooks/user-prompt-submitted.md", - "sourceLine": 15, - "language": "typescript", - "outputFile": "typescript/user-prompt-submitted_20.ts" - }, - { - "id": "python/user-prompt-submitted_9.py", - "sourceFile": "hooks/user-prompt-submitted.md", - "sourceLine": 27, - "language": "python", - "outputFile": "python/user-prompt-submitted_9.py" - }, - { - "id": "csharp/user-prompt-submitted_11.cs", - "sourceFile": "hooks/user-prompt-submitted.md", - "sourceLine": 52, - "language": "csharp", - "outputFile": "csharp/user-prompt-submitted_11.cs" - }, - { - "id": "typescript/user-prompt-submitted_21.ts", - "sourceFile": "hooks/user-prompt-submitted.md", - "sourceLine": 85, - "language": "typescript", - "outputFile": "typescript/user-prompt-submitted_21.ts" - }, - { - "id": "python/user-prompt-submitted_10.py", - "sourceFile": "hooks/user-prompt-submitted.md", - "sourceLine": 101, - "language": "python", - "outputFile": "python/user-prompt-submitted_10.py" - }, - { - "id": "csharp/user-prompt-submitted_12.cs", - "sourceFile": "hooks/user-prompt-submitted.md", - "sourceLine": 133, - "language": "csharp", - "outputFile": "csharp/user-prompt-submitted_12.cs" - }, - { - "id": "typescript/user-prompt-submitted_22.ts", - "sourceFile": "hooks/user-prompt-submitted.md", - "sourceLine": 151, - "language": "typescript", - "outputFile": "typescript/user-prompt-submitted_22.ts" - }, - { - "id": "typescript/user-prompt-submitted_23.ts", - "sourceFile": "hooks/user-prompt-submitted.md", - "sourceLine": 171, - "language": "typescript", - "outputFile": "typescript/user-prompt-submitted_23.ts" - }, - { - "id": "typescript/user-prompt-submitted_24.ts", - "sourceFile": "hooks/user-prompt-submitted.md", - "sourceLine": 198, - "language": "typescript", - "outputFile": "typescript/user-prompt-submitted_24.ts" - }, - { - "id": "typescript/user-prompt-submitted_25.ts", - "sourceFile": "hooks/user-prompt-submitted.md", - "sourceLine": 225, - "language": "typescript", - "outputFile": "typescript/user-prompt-submitted_25.ts" - }, - { - "id": "typescript/user-prompt-submitted_26.ts", - "sourceFile": "hooks/user-prompt-submitted.md", - "sourceLine": 246, - "language": "typescript", - "outputFile": "typescript/user-prompt-submitted_26.ts" - }, - { - "id": "typescript/user-prompt-submitted_27.ts", - "sourceFile": "hooks/user-prompt-submitted.md", - "sourceLine": 280, - "language": "typescript", - "outputFile": "typescript/user-prompt-submitted_27.ts" - }, - { - "id": "typescript/user-prompt-submitted_28.ts", - "sourceFile": "hooks/user-prompt-submitted.md", - "sourceLine": 311, - "language": "typescript", - "outputFile": "typescript/user-prompt-submitted_28.ts" - }, - { - "id": "typescript/session-lifecycle_29.ts", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 19, - "language": "typescript", - "outputFile": "typescript/session-lifecycle_29.ts" - }, - { - "id": "python/session-lifecycle_11.py", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 31, - "language": "python", - "outputFile": "python/session-lifecycle_11.py" - }, - { - "id": "csharp/session-lifecycle_13.cs", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 56, - "language": "csharp", - "outputFile": "csharp/session-lifecycle_13.cs" - }, - { - "id": "typescript/session-lifecycle_30.ts", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 87, - "language": "typescript", - "outputFile": "typescript/session-lifecycle_30.ts" - }, - { - "id": "python/session-lifecycle_12.py", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 112, - "language": "python", - "outputFile": "python/session-lifecycle_12.py" - }, - { - "id": "typescript/session-lifecycle_31.ts", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 135, - "language": "typescript", - "outputFile": "typescript/session-lifecycle_31.ts" - }, - { - "id": "typescript/session-lifecycle_32.ts", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 159, - "language": "typescript", - "outputFile": "typescript/session-lifecycle_32.ts" - }, - { - "id": "typescript/session-lifecycle_33.ts", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 196, - "language": "typescript", - "outputFile": "typescript/session-lifecycle_33.ts" - }, - { - "id": "python/session-lifecycle_13.py", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 208, - "language": "python", - "outputFile": "python/session-lifecycle_13.py" - }, - { - "id": "csharp/session-lifecycle_14.cs", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 233, - "language": "csharp", - "outputFile": "csharp/session-lifecycle_14.cs" - }, - { - "id": "typescript/session-lifecycle_34.ts", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 276, - "language": "typescript", - "outputFile": "typescript/session-lifecycle_34.ts" - }, - { - "id": "python/session-lifecycle_14.py", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 307, - "language": "python", - "outputFile": "python/session-lifecycle_14.py" - }, - { - "id": "typescript/session-lifecycle_35.ts", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 339, - "language": "typescript", - "outputFile": "typescript/session-lifecycle_35.ts" - }, - { - "id": "typescript/session-lifecycle_36.ts", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 368, - "language": "typescript", - "outputFile": "typescript/session-lifecycle_36.ts" - }, - { - "id": "typescript/session-lifecycle_37.ts", - "sourceFile": "hooks/session-lifecycle.md", - "sourceLine": 388, - "language": "typescript", - "outputFile": "typescript/session-lifecycle_37.ts" - }, - { - "id": "typescript/pre-tool-use_38.ts", - "sourceFile": "hooks/pre-tool-use.md", - "sourceLine": 15, - "language": "typescript", - "outputFile": "typescript/pre-tool-use_38.ts" - }, - { - "id": "python/pre-tool-use_15.py", - "sourceFile": "hooks/pre-tool-use.md", - "sourceLine": 27, - "language": "python", - "outputFile": "python/pre-tool-use_15.py" - }, - { - "id": "csharp/pre-tool-use_15.cs", - "sourceFile": "hooks/pre-tool-use.md", - "sourceLine": 52, - "language": "csharp", - "outputFile": "csharp/pre-tool-use_15.cs" - }, - { - "id": "typescript/pre-tool-use_39.ts", - "sourceFile": "hooks/pre-tool-use.md", - "sourceLine": 96, - "language": "typescript", - "outputFile": "typescript/pre-tool-use_39.ts" - }, - { - "id": "python/pre-tool-use_16.py", - "sourceFile": "hooks/pre-tool-use.md", - "sourceLine": 113, - "language": "python", - "outputFile": "python/pre-tool-use_16.py" - }, - { - "id": "csharp/pre-tool-use_16.cs", - "sourceFile": "hooks/pre-tool-use.md", - "sourceLine": 149, - "language": "csharp", - "outputFile": "csharp/pre-tool-use_16.cs" - }, - { - "id": "typescript/pre-tool-use_40.ts", - "sourceFile": "hooks/pre-tool-use.md", - "sourceLine": 170, - "language": "typescript", - "outputFile": "typescript/pre-tool-use_40.ts" - }, - { - "id": "typescript/pre-tool-use_41.ts", - "sourceFile": "hooks/pre-tool-use.md", - "sourceLine": 190, - "language": "typescript", - "outputFile": "typescript/pre-tool-use_41.ts" - }, - { - "id": "typescript/pre-tool-use_42.ts", - "sourceFile": "hooks/pre-tool-use.md", - "sourceLine": 213, - "language": "typescript", - "outputFile": "typescript/pre-tool-use_42.ts" - }, - { - "id": "typescript/pre-tool-use_43.ts", - "sourceFile": "hooks/pre-tool-use.md", - "sourceLine": 240, - "language": "typescript", - "outputFile": "typescript/pre-tool-use_43.ts" - }, - { - "id": "typescript/pre-tool-use_44.ts", - "sourceFile": "hooks/pre-tool-use.md", - "sourceLine": 257, - "language": "typescript", - "outputFile": "typescript/pre-tool-use_44.ts" - }, - { - "id": "typescript/post-tool-use_45.ts", - "sourceFile": "hooks/post-tool-use.md", - "sourceLine": 15, - "language": "typescript", - "outputFile": "typescript/post-tool-use_45.ts" - }, - { - "id": "python/post-tool-use_17.py", - "sourceFile": "hooks/post-tool-use.md", - "sourceLine": 27, - "language": "python", - "outputFile": "python/post-tool-use_17.py" - }, - { - "id": "csharp/post-tool-use_17.cs", - "sourceFile": "hooks/post-tool-use.md", - "sourceLine": 52, - "language": "csharp", - "outputFile": "csharp/post-tool-use_17.cs" - }, - { - "id": "typescript/post-tool-use_46.ts", - "sourceFile": "hooks/post-tool-use.md", - "sourceLine": 87, - "language": "typescript", - "outputFile": "typescript/post-tool-use_46.ts" - }, - { - "id": "python/post-tool-use_18.py", - "sourceFile": "hooks/post-tool-use.md", - "sourceLine": 105, - "language": "python", - "outputFile": "python/post-tool-use_18.py" - }, - { - "id": "csharp/post-tool-use_18.cs", - "sourceFile": "hooks/post-tool-use.md", - "sourceLine": 141, - "language": "csharp", - "outputFile": "csharp/post-tool-use_18.cs" - }, - { - "id": "typescript/post-tool-use_47.ts", - "sourceFile": "hooks/post-tool-use.md", - "sourceLine": 161, - "language": "typescript", - "outputFile": "typescript/post-tool-use_47.ts" - }, - { - "id": "typescript/post-tool-use_48.ts", - "sourceFile": "hooks/post-tool-use.md", - "sourceLine": 189, - "language": "typescript", - "outputFile": "typescript/post-tool-use_48.ts" - }, - { - "id": "typescript/post-tool-use_49.ts", - "sourceFile": "hooks/post-tool-use.md", - "sourceLine": 215, - "language": "typescript", - "outputFile": "typescript/post-tool-use_49.ts" - }, - { - "id": "typescript/post-tool-use_50.ts", - "sourceFile": "hooks/post-tool-use.md", - "sourceLine": 241, - "language": "typescript", - "outputFile": "typescript/post-tool-use_50.ts" - }, - { - "id": "typescript/post-tool-use_51.ts", - "sourceFile": "hooks/post-tool-use.md", - "sourceLine": 263, - "language": "typescript", - "outputFile": "typescript/post-tool-use_51.ts" - }, - { - "id": "typescript/post-tool-use_52.ts", - "sourceFile": "hooks/post-tool-use.md", - "sourceLine": 298, - "language": "typescript", - "outputFile": "typescript/post-tool-use_52.ts" - }, - { - "id": "typescript/overview_53.ts", - "sourceFile": "hooks/overview.md", - "sourceLine": 27, - "language": "typescript", - "outputFile": "typescript/overview_53.ts" - }, - { - "id": "python/overview_19.py", - "sourceFile": "hooks/overview.md", - "sourceLine": 55, - "language": "python", - "outputFile": "python/overview_19.py" - }, - { - "id": "go/overview_5.go", - "sourceFile": "hooks/overview.md", - "sourceLine": 87, - "language": "go", - "outputFile": "go/overview_5.go" - }, - { - "id": "csharp/overview_19.cs", - "sourceFile": "hooks/overview.md", - "sourceLine": 127, - "language": "csharp", - "outputFile": "csharp/overview_19.cs" - }, - { - "id": "typescript/overview_54.ts", - "sourceFile": "hooks/overview.md", - "sourceLine": 174, - "language": "typescript", - "outputFile": "typescript/overview_54.ts" - }, - { - "id": "typescript/overview_55.ts", - "sourceFile": "hooks/overview.md", - "sourceLine": 191, - "language": "typescript", - "outputFile": "typescript/overview_55.ts" - }, - { - "id": "typescript/overview_56.ts", - "sourceFile": "hooks/overview.md", - "sourceLine": 211, - "language": "typescript", - "outputFile": "typescript/overview_56.ts" - }, - { - "id": "typescript/error-handling_57.ts", - "sourceFile": "hooks/error-handling.md", - "sourceLine": 15, - "language": "typescript", - "outputFile": "typescript/error-handling_57.ts" - }, - { - "id": "python/error-handling_20.py", - "sourceFile": "hooks/error-handling.md", - "sourceLine": 27, - "language": "python", - "outputFile": "python/error-handling_20.py" - }, - { - "id": "csharp/error-handling_20.cs", - "sourceFile": "hooks/error-handling.md", - "sourceLine": 52, - "language": "csharp", - "outputFile": "csharp/error-handling_20.cs" - }, - { - "id": "typescript/error-handling_58.ts", - "sourceFile": "hooks/error-handling.md", - "sourceLine": 88, - "language": "typescript", - "outputFile": "typescript/error-handling_58.ts" - }, - { - "id": "python/error-handling_21.py", - "sourceFile": "hooks/error-handling.md", - "sourceLine": 106, - "language": "python", - "outputFile": "python/error-handling_21.py" - }, - { - "id": "csharp/error-handling_21.cs", - "sourceFile": "hooks/error-handling.md", - "sourceLine": 142, - "language": "csharp", - "outputFile": "csharp/error-handling_21.cs" - }, - { - "id": "typescript/error-handling_59.ts", - "sourceFile": "hooks/error-handling.md", - "sourceLine": 162, - "language": "typescript", - "outputFile": "typescript/error-handling_59.ts" - }, - { - "id": "typescript/error-handling_60.ts", - "sourceFile": "hooks/error-handling.md", - "sourceLine": 188, - "language": "typescript", - "outputFile": "typescript/error-handling_60.ts" - }, - { - "id": "typescript/error-handling_61.ts", - "sourceFile": "hooks/error-handling.md", - "sourceLine": 215, - "language": "typescript", - "outputFile": "typescript/error-handling_61.ts" - }, - { - "id": "typescript/error-handling_62.ts", - "sourceFile": "hooks/error-handling.md", - "sourceLine": 232, - "language": "typescript", - "outputFile": "typescript/error-handling_62.ts" - }, - { - "id": "typescript/error-handling_63.ts", - "sourceFile": "hooks/error-handling.md", - "sourceLine": 263, - "language": "typescript", - "outputFile": "typescript/error-handling_63.ts" - }, - { - "id": "typescript/error-handling_64.ts", - "sourceFile": "hooks/error-handling.md", - "sourceLine": 302, - "language": "typescript", - "outputFile": "typescript/error-handling_64.ts" - }, - { - "id": "typescript/error-handling_65.ts", - "sourceFile": "hooks/error-handling.md", - "sourceLine": 326, - "language": "typescript", - "outputFile": "typescript/error-handling_65.ts" - }, - { - "id": "typescript/skills_66.ts", - "sourceFile": "guides/skills.md", - "sourceLine": 25, - "language": "typescript", - "outputFile": "typescript/skills_66.ts" - }, - { - "id": "python/skills_22.py", - "sourceFile": "guides/skills.md", - "sourceLine": 47, - "language": "python", - "outputFile": "python/skills_22.py" - }, - { - "id": "go/skills_6.go", - "sourceFile": "guides/skills.md", - "sourceLine": 74, - "language": "go", - "outputFile": "go/skills_6.go" - }, - { - "id": "csharp/skills_22.cs", - "sourceFile": "guides/skills.md", - "sourceLine": 118, - "language": "csharp", - "outputFile": "csharp/skills_22.cs" - }, - { - "id": "typescript/skills_67.ts", - "sourceFile": "guides/skills.md", - "sourceLine": 149, - "language": "typescript", - "outputFile": "typescript/skills_67.ts" - }, - { - "id": "python/skills_23.py", - "sourceFile": "guides/skills.md", - "sourceLine": 161, - "language": "python", - "outputFile": "python/skills_23.py" - }, - { - "id": "csharp/skills_23.cs", - "sourceFile": "guides/skills.md", - "sourceLine": 186, - "language": "csharp", - "outputFile": "csharp/skills_23.cs" - }, - { - "id": "typescript/skills_68.ts", - "sourceFile": "guides/skills.md", - "sourceLine": 278, - "language": "typescript", - "outputFile": "typescript/skills_68.ts" - }, - { - "id": "typescript/skills_69.ts", - "sourceFile": "guides/skills.md", - "sourceLine": 293, - "language": "typescript", - "outputFile": "typescript/skills_69.ts" - }, - { - "id": "typescript/session-persistence_70.ts", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 28, - "language": "typescript", - "outputFile": "typescript/session-persistence_70.ts" - }, - { - "id": "python/session-persistence_24.py", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 48, - "language": "python", - "outputFile": "python/session-persistence_24.py" - }, - { - "id": "csharp/session-persistence_24.cs", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 87, - "language": "csharp", - "outputFile": "csharp/session-persistence_24.cs" - }, - { - "id": "typescript/session-persistence_71.ts", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 125, - "language": "typescript", - "outputFile": "typescript/session-persistence_71.ts" - }, - { - "id": "python/session-persistence_25.py", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 135, - "language": "python", - "outputFile": "python/session-persistence_25.py" - }, - { - "id": "csharp/session-persistence_25.cs", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 158, - "language": "csharp", - "outputFile": "csharp/session-persistence_25.cs" - }, - { - "id": "typescript/session-persistence_72.ts", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 170, - "language": "typescript", - "outputFile": "typescript/session-persistence_72.ts" - }, - { - "id": "typescript/session-persistence_73.ts", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 238, - "language": "typescript", - "outputFile": "typescript/session-persistence_73.ts" - }, - { - "id": "python/session-persistence_26.py", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 248, - "language": "python", - "outputFile": "python/session-persistence_26.py" - }, - { - "id": "typescript/session-persistence_74.ts", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 263, - "language": "typescript", - "outputFile": "typescript/session-persistence_74.ts" - }, - { - "id": "typescript/session-persistence_75.ts", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 274, - "language": "typescript", - "outputFile": "typescript/session-persistence_75.ts" - }, - { - "id": "typescript/session-persistence_76.ts", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 296, - "language": "typescript", - "outputFile": "typescript/session-persistence_76.ts" - }, - { - "id": "typescript/session-persistence_77.ts", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 321, - "language": "typescript", - "outputFile": "typescript/session-persistence_77.ts" - }, - { - "id": "typescript/session-persistence_78.ts", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 366, - "language": "typescript", - "outputFile": "typescript/session-persistence_78.ts" - }, - { - "id": "typescript/session-persistence_79.ts", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 428, - "language": "typescript", - "outputFile": "typescript/session-persistence_79.ts" - }, - { - "id": "typescript/session-persistence_80.ts", - "sourceFile": "guides/session-persistence.md", - "sourceLine": 454, - "language": "typescript", - "outputFile": "typescript/session-persistence_80.ts" - }, - { - "id": "typescript/index_81.ts", - "sourceFile": "auth/index.md", - "sourceLine": 28, - "language": "typescript", - "outputFile": "typescript/index_81.ts" - }, - { - "id": "python/index_27.py", - "sourceFile": "auth/index.md", - "sourceLine": 40, - "language": "python", - "outputFile": "python/index_27.py" - }, - { - "id": "csharp/index_26.cs", - "sourceFile": "auth/index.md", - "sourceLine": 66, - "language": "csharp", - "outputFile": "csharp/index_26.cs" - }, - { - "id": "typescript/index_82.ts", - "sourceFile": "auth/index.md", - "sourceLine": 94, - "language": "typescript", - "outputFile": "typescript/index_82.ts" - }, - { - "id": "python/index_28.py", - "sourceFile": "auth/index.md", - "sourceLine": 108, - "language": "python", - "outputFile": "python/index_28.py" - }, - { - "id": "csharp/index_27.cs", - "sourceFile": "auth/index.md", - "sourceLine": 138, - "language": "csharp", - "outputFile": "csharp/index_27.cs" - }, - { - "id": "typescript/index_83.ts", - "sourceFile": "auth/index.md", - "sourceLine": 183, - "language": "typescript", - "outputFile": "typescript/index_83.ts" - }, - { - "id": "python/index_29.py", - "sourceFile": "auth/index.md", - "sourceLine": 195, - "language": "python", - "outputFile": "python/index_29.py" - }, - { - "id": "typescript/index_84.ts", - "sourceFile": "auth/index.md", - "sourceLine": 245, - "language": "typescript", - "outputFile": "typescript/index_84.ts" - }, - { - "id": "python/index_30.py", - "sourceFile": "auth/index.md", - "sourceLine": 256, - "language": "python", - "outputFile": "python/index_30.py" - }, - { - "id": "csharp/index_28.cs", - "sourceFile": "auth/index.md", - "sourceLine": 279, - "language": "csharp", - "outputFile": "csharp/index_28.cs" - }, - { - "id": "python/byok_31.py", - "sourceFile": "auth/byok.md", - "sourceLine": 22, - "language": "python", - "outputFile": "python/byok_31.py" - }, - { - "id": "typescript/byok_85.ts", - "sourceFile": "auth/byok.md", - "sourceLine": 67, - "language": "typescript", - "outputFile": "typescript/byok_85.ts" - }, - { - "id": "go/byok_7.go", - "sourceFile": "auth/byok.md", - "sourceLine": 96, - "language": "go", - "outputFile": "go/byok_7.go" - }, - { - "id": "csharp/byok_29.cs", - "sourceFile": "auth/byok.md", - "sourceLine": 143, - "language": "csharp", - "outputFile": "csharp/byok_29.cs" - }, - { - "id": "typescript/byok_86.ts", - "sourceFile": "auth/byok.md", - "sourceLine": 312, - "language": "typescript", - "outputFile": "typescript/byok_86.ts" - } - ] -} \ No newline at end of file diff --git a/docs/.validation/python/__pycache__/byok_31.cpython-314.pyc b/docs/.validation/python/__pycache__/byok_31.cpython-314.pyc deleted file mode 100644 index 1fb38c297fe3133eaad185ead252794a21724d6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2044 zcmb7F&2JM&6rb_V+8ck7gd`3ai1|vjgm@bVL#Cv@}D}<4S(s*5ax;C)Etn!hoc1W~j0-&^s_UydH!UZXfD_UCeCeMvZDLG>uZQ z_vTTr_6(BI4fuWw7r05@4^hCMZ}vv87uh3oGLd=NJL9c?mwmDzx6BB2Jyq>@U8`}~ ze|YDXMIw@?-l68)7M^KzH^uhXG`4zda?{)(mID!#6)ev*PPH|;f;!#E1AD@$?eBWX zK{+Jh|Ei`3UEork@2>iv&f!$#z5G#X$NTupXg~6y$)_-vVahOvVfMmoJ<91=3{O#h z&dg}peCV3x_8*NW`c+VGQNgm!1wEtLl(;!dquv^*sBl$rwDi24rNT|!*3ycl(-wfD zWg3p=P#@^&SuIDmji0|bH6~w5pGuuge{%Yg+Q1pq&(OuXyFq~r;{rnvNX;V!IBgy> z`sj0nGW!tPg=QM4gY^xBZLLT(P_|{OpB>ya&;Iwxi>rB|>RsppP6f6i)}{I>*CMm% zBA0Jd97lIt#c<7%3w?N0Gi;iYHlBKw|uFgtuY&SI3btJX+bo4u!St(d$4l9h9>1G}0tXVZfNaVtj!(@59Ccg-of5g*Q)s*-h1#_M*5J7)sO+XAWt zT9<~3L*+npB@iw3Bvu277s0lB2bT}sKU8i%u+o0uS@2*b)V_4Nc)1+fy%O5}aL;N; zssvk?CW;f^oLlEm_`?l|g{T(_p0nJ1@U!cR8`GUwqAxKjhHM5A%0uUDmxfhaQ(P^* z**Mx($JVFk$4*bCFUphDV*>UxV?nn~13>8H3{^KNf4bT*57>yK85v4$D!NO38O?ER zGY3Z3v_wL^YW0DozRe6ayOcJ&$qsw;W3kxBb{8v%u-@1rh%M~nuRz|ufmifJXy;eyNC5LY_Him>foPeo|21l#XTRDxZr-6GHjfl9FRTYEWw zKVRB6_;cjQS_|LlU*m;7?*W>@Pz2$XXEb!Mo?a zJonYDRnlGYx3Q!Tgop7`WZViE~b7YF^1L&Yb-8_?*3*8b zx7d>*YKoYFdTy~LgO#pi_zW`QmY05LacWVqenDbMQD$bb(C6 diff --git a/docs/.validation/python/__pycache__/debugging_7.cpython-314.pyc b/docs/.validation/python/__pycache__/debugging_7.cpython-314.pyc deleted file mode 100644 index 7b328107924eb572c8773417b3235fe56ff5b5de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmdPqlZt2KczG$)vkyYXf(+3Vi4mKGb1Bo5i^hl005jUqW}N^ diff --git a/docs/.validation/python/__pycache__/error-handling_20.cpython-314.pyc b/docs/.validation/python/__pycache__/error-handling_20.cpython-314.pyc deleted file mode 100644 index 8b6e6b04a14007199cc89e146d6e8e8d9c39da72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 376 zcmdPq^pv<7j=%>kci^DlFCnqr}C-s(?Yf({tk$-Y>X;D#XibsBawr5^JX~``< z2(v6dIk6-&KkpW&V|ij`30R9bh8F+Q5|ADdREfmAl$_L}l?b{D^o+O*EIKz> hcrWm&u3)*!r*oA>7bwfB_m!Dhg6R^2ND(JcJpdrnYGD8X diff --git a/docs/.validation/python/__pycache__/error-handling_21.cpython-314.pyc b/docs/.validation/python/__pycache__/error-handling_21.cpython-314.pyc deleted file mode 100644 index 483fd621ecc41de10efb38821f81ffd7c6ca288c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1042 zcmZ`&%}*0i5TCc(c1v5@07Xkr5gzdMI^y51PLK)B32-o^ z9*prq;)Ns83*J0>^iNn5>c>XCaN>s4#Bg)AwD>*An>Qc7`FOLlsc3x&kY0Z->R$-J zj;GYfR~5=vP*{U|Ad^wBLFQV(CbKYE^Vjfrx4|rFgPy9T2Qzw?>*#PN zr8`WcOtKW4>gs}IQFC5XZ6>LvrRPn%i{%!ioT)M?y`g$G2|L`FN73H@~)t;6+_j{N&%Or1>+@@5eA3FgM*7^u8`M; p=n1rWyUk7`+v5o#I}qLX)e&Lu7?9xOa54Pk+S42Fpotzw#1CQ+>s0^% diff --git a/docs/.validation/python/__pycache__/getting-started_0.cpython-314.pyc b/docs/.validation/python/__pycache__/getting-started_0.cpython-314.pyc deleted file mode 100644 index 431757c4c161fb15430bbd65457990afa8f149f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1047 zcmaJ=%}*0S6rbtN(o$&aM@wr%WRZ)dw5tU1LTD@oNLr~p0kc0bB zf*d)$#1<>gTB;SD43Yu+|L4OKcXa?m4H|1QqjVDk6 zEyDdXToI;3KU9Hu@jTAe3b^2ru?zEJmW5|<-s{Gm%YslK|H<;qw!5)2o_urEu6-u+ zoqyYog?v#7oY@e-B%QV1rdPtJQ^YR0#*;KX^X6x#b44@V@ zl~Gwedle~KT9QkqO6BwurL03AKp|VJYyrf)#+Yu*r z(!Uew-^|sA$Lq<7-AJwx%2jedNc*ds8>wol;qTe;_k1SO0aQ#@leJWXL_d+}NeGG8 zz6Ud3L%9aG0he6*C;B1_12fdCC ze&Detk2^dea<4*H4OKUtNjLwQ=Bk?C$_0DHc#BS<7qTw{EM=>%+1e-)k<6Z3x zNr`%J=^;f(A;PR#1&D(k3d+(b! zJK7cSAsD|LZ0TVEq1Sxl46&u0d;v-o-A4+}Alj6eV%WPfuA2fCBHSiq#G4Y8B1jQK zh`R5gY?lMnkt67ydjw6i3=_DifDgWmV$vJFU5sHCNE@bJHfXx6YZVHHo}5OAZd7I; zz&^ieYQ+|WE!?nv3-jb70K9}EknBG z&}HO73#%}1!Mp@ho)mN(^DZ)J-6(10N1kPqj!(p|vI~S-n!2u6mh;6ng%FGr*9Y@t z8mv`L&G`(_lFKn>o!)T_AV2vWp^}2o5L)6FW{<4b(K<5wj^ZGm+&STB@9Hpzw#ffQ z>2**#(xK3%xMOZ>r|SElZEP!ceF3|^e#h8B=>b!p!VKKFI{KNtm0^lCeRV^w83&#>A3JRTh9NqiUgOR46Ywe;dz!nBN4tw>3t*nDu~q_mbO z8AXzaKTyj$M1x0{FgNK6h-HmZXpC_}Rf}q+!qvFB$>bHaQYvc&I|>_ISM^GKx@;8H zGPxc<{f+ZY?!!_=`~IHYYunfA;aDS_tc8wy*s}>-;jrD^3eCUf4uv{-Nwbq z+QrGbJoTS%b$R%-`&2DFRrkY@-Y0X%0+K&Ife47Xp|Ew6J__cwayh!LMb#)-F)SKg zHP*D4+v4raB)bsSRfLYGT7fiwG0bIDSb%7iQUNL}JXCecL_!TSCNOu={vk0>>#W5u znsBgaG-?GosK^?c+`a?`SJWW^WS}47l#ggy$xTa=8HTV z*c(mmMN_}~(hV`aC#DYpe{_3vXS^YXUW%dP50Ml;76IpY7)dkuFER8FNkd9o!>K;} z45$3!PeY*nicW6e$8f4!d_Eom{e_5Az2XbW!}S2>Yq!1j@-^mV9+hlXin?L( z7t1`Y9%_;sZSCUAT1B&f-%`9qTC-J%-TgLEOt3a8KO-vyC`}T*)9_o`C~McPD`4ZT rOSp0*V2od*u0N6Q0F4}=Pv46Dc;G0Gu=lZl%fCIdbK?)xXXE?}#=K?T diff --git a/docs/.validation/python/__pycache__/getting-started_2.cpython-314.pyc b/docs/.validation/python/__pycache__/getting-started_2.cpython-314.pyc deleted file mode 100644 index bac8d7c31ac6396617054ed3fdc569c2111e8d75..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1005 zcmah|K~EDw6n?uc-4>Pw6Kg|5LX81Zq^xN;2q7dy8bczrX{+%7smtyL7Rv5sW{P1? z)q{o;9`WSGgWT|>Kcfu|kcpo32Y~zmXLehZhQxPxJM-T6zM1#F+51X=FEIP|_TsMIiwsbTe`_^cS}(-i7I)2u7eN-h*^V zZ?pK}F!TJh%PezsSh>m-;W-pUA9KygkQF=pj7{*Q+>U9J*;HDjJub3rLc?U&H4g>a zWAY507FcoJ~_FSk)cZsyZZtjV;x1bgWM8XjRM5h~?O-yGu6M zXWb;kvez@1Xo#3bB|GKr(&$`O+g>xYc@$+Q@FwtW=IZdN_W9LO?W_02JE}G^k6Po4 zmn;r9_x;N+VZCxlm#tj&U*L1%ft9O~tJKDu7Fed*6 zT?ZHB>wCWYSE1k*f$rWw$;6mVHD%$HWmHWsw#)+Bx;dN5rzON&q=RjYFKU_TNaa$l zR9bqPuPiM-$ss;wdTW72O67%oxw6cX3y*U&%mmY@q&qfYnxh^D3xr2}HdNlwY<6PB ze-UVqg(4imhhB#>Nq*suv;XokcN5noozRgoAde=-9NcX5-o#){(Vl z`sW{l4-Bpso!fSdTGgCKaaPP9Eav~ic}Nh1^9T&w+27pTYz{3RE4g~#??_m9a4xr_ T2gAq8SiSEe0)qUu-{<@T`&Gmf diff --git a/docs/.validation/python/__pycache__/getting-started_3.cpython-314.pyc b/docs/.validation/python/__pycache__/getting-started_3.cpython-314.pyc deleted file mode 100644 index f59f1ae24d958249bcc8b1f87cab94f8107ecf62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3303 zcmahLT~i##ab`d6j{AT^;!}m-KqWa>n7c$mvdWTiz#u+?;Id$xID)P9-6B?6cGt6W zR*vN1f>WgsRYg=PRUvsv{3gHYArE=9^a~)S0v<~hRs5vN3kX#yeoN0RhfY^=rK`5L zXS!#myQjOSd+QTX1n~FAtJZ&1gudZ}3cy&v!58o=qXnelaYTbZrdW(6D#2eGm&X*U zba9?Mu8xIhNYKi7cq~FAf>y`t#-cPj7NfB))Qq~37HUOWcs|-M2glI(d?5v`v`xz59>s$VynukS_`+5W>_xhwaE$2LnJD;H!B=v4+4mF)Ftp7tJeR8P=qVWmKI*=ddP&Z4nyM6dImGG@_}XXNV<7 zP5Oap&?S@P3}P(%D{ss$nJLFuHdF3m3g%OJi>Q*3{T6D?h!WKVIERTW# zdG3KjF9;pErw`5mx{S+c4lPI*e~nN9W;@W2@ePJNzyQv0bQi05)e$`$AM#H zpAzsz2u@lyC`;&i-Zp%{VCAW<`&_iA%yQZHeUtcE&!EK0-^_Z%y)>)e;HS5()R-9pjkG@SBr(XbCW4Z6N) z5ue%+7mlmzBn-<*Js{Rtb>3pp$-~-aFdx*j^14C6>W_-l^kEt#j~tXYZClsVm^8v3 zKEIS7l4E?&x(X7ix55ZiFQc!L&6_s9384ARtT>{Y3rQ(l$fqi(ctb|Ke)Xr3p(G&IN0s)24aCsitmr)YQ%vUpC8L!CP- zY08|El~1AbvV|dURln#sr65RR)LiyVVt|v(B2T-A_ph+Jyz3M!9`9*|oPtRf%G++S zP+}@EET^=R0Pj+}lnQ1+NCaGn7*4@mW?}xf915$JTq|#;Rl+?Q2t|+f_L;&DC#Qku z^BR681t9K&#UR1-!-7HjfY-o#7PYryx zRT`AvFq-@rzG?V+;ERhetD9mf)GX6p319bUUw`HYtPaYuX)HtCoMkG1!~9ngh044fCQ5rbilM|KTVyw~;rPT?iA z1}dHup045XVU>Nn>ehg;5AFx-<3(1$%N_Y$@Gp(0(lJOb=m-c8Io3KjGc!IjJ2*9~ zUmcm585|wahesx72jQVC`7Gqqf?K3ay+tf)LWwk}!4hzD)X*VWDb#JIF4{$ZiN$AN z`S|pdK0Z7-!c>nymcx6in!E!M_4G`Tzwsp~0q|T220O6~RU>oRcJqeq4`ix&J)obz z0H}<1W68U3uf4t9p5AF6+-e`(jtxGFH{6|Ao7jnWY{fe^-v7&ofBJCeChxwv_U4_;j?%WN zv^{A$vD1{^YD(`$8rIu)BgfZgf%-%5`pLbp(i=KJN^|%HQX0bL(Pwd0ZQ83xYW()Z zuO@!;%Wb9ONwje%+O-w!+KnVPj}7k0Qa3D-Vz5L~!+Qcn5LDFOwca~@J4)+6l-B)T zq_*!Xu;qRy2<=CZ+V-tK0$Q$i4xPY%#Y4xG&rSjLK*2*z$^$jS>2r9fMS0NQ3iQJm z9%@q_#>1R$!W_2<+{SS_$-;(Ta`Ki-z6YC<^MF|Runh}*pEw+4MA;xb^;xPicinXO z3uYEFhb|7n&JTh=;*|=913eGn1vco9L@&di72$LylcGaf_)xSiJn>lMa?o)NkZBn5 z`tSb~(4LGj{sz^5jS^p@=wsCV7@dBM-uV|g{XB&6RlHt$4o%Qi3{H{~o9*vxHr> z%)Fj6X-`hq3Lrcl$&!8SUoS(a`ZeIEchUCe7Sj~#eRwX}0)R?FE!zpmx7 znQiwXzOvcq20#T{O(2S81hxrMZa*^71P_{F+2d+Pg)#IKEOVfnpL%7U`o<9T%L2&h zwW9+Xy`ZUdN+T(isMFR=dwNQf40T$Q%t;CGQbwmmiJHT1VYY;`f{HS2W(zq6!!7R@)Ley9 zr6`j+v1ktB!Y~zu_~3IAfyu7kcHd;d$iTNXpgxGFXB3r!*6$XmW&s*FHw~20aydnb zVNwleSj;IuC41PJ0e5mluZ10mUP50-YZhA1E=7k+z0aBaA0blXa?Z4Z4a#v)AOwPR zdkjdb6CH#d_u>F}1t>3azl_I$QXaBrocYrk2@iw*scX#e(iFqqoQ7(+fp>e?%Fk4(3r=~Bza!O zWAKW{xDe#I*E}*m#wWNobez*Myj#I47)G%iBqG(O^BPgXNLqnCyD#tc+kuQ}WOWwr zF`l#m()MO@W+7X&1)}OkaV8AbrMaS1#sZTQa9*MsS##R@kXX=oL8 z-M{IcZ=HYlf!I>&U5)PlWBB*s`Ku42vC`m5XwU85`D1r`@1D4~_in?zUwl5eAdW2X zBR^Qoir15Yq=+*BZ4N&`jw26)>C28Bcazg*(#}I#N-=xw8g5b_Kr*@t^bc`~8y12P z4#4jgs%_t}WGizrFAL+FPL1OP=elzDIeE;=QQk9#Q|v+R8e1XIjK)QmDEr*gc3}Nm z*n{XG8fPYUh8%Dyc`nVRSR&XpTrK6`>lYz0gPj`Cxq)$(C!CSm=R#X+ilvNQLl)he zno%03>UWW0D~Hlt0=rzht+7L&u*=nq&R#_*jZz1He4Z=$k57`JkoeH>L->6vp>Y<` z&hVlv_^kmv*oe*^MMy`TTqDvk@Fn5bd)^anxD|vdXBmSx#fFh)+(@-VS zw!kX3wIf}y*kK80RvF*vfAVD~`PczxJVkgC-ch^X5M#2^W?h9@0Tqw1v zwTnS$%c}q9mj4ka(At1?*)N7!W#cJyD}+4b>G&{5$ zYFG?4%)kBdr9WL-Zalu&czh{zVh8PEsA*k5p|`M89ty00t$qC4zy0g8IZ3K?N>UPf zHYmbS3}0qeklM8mb=uCFr1uLtjm-=}5=@igDXIO!luFwzr+&J+`Ji3UTAlw^VG({ScI@xgsQ-L z89S1JsD%c`D)*L7^0hstVGDV}a=M@!d2ooo?|gqBAttefoOw+nK&kfr%A> z)$oB^N~wP(7@a#hd-PU(nXg;m>mKhru)Hs}xG%Qiuex2o;@^8a4bUHs+-_X+@khKH zh_CTIM|_p9H1IUU3C(LkB!q4Z{c7muFPHd+@A$w%uxp7wy~=&h!N{723+!2~ zZ<@dMm!_LTYkm~kzbqbH6c0WS8}IC265Cfo)!+HWx!`PY*eqP??E7bj zQMB$E!ht<@sCtcq_226e6zE#_BBAaFD+~HxZ|beacW}>1{;zESeZk|NH~24v1cQ%@ zJ)P)FloVleU&Os({(k5s2ET%PtN8n``WXBMW^!y>`}4&tJODjI zSj{W9tWJB$D!t=vn}Ol2n`D*6_IH(=;BEp*&-uS#T>=2igz>j1@(l`qgMyDx z%OiB?5jy=3bm$q6@i~0E2nK}}Z0HFu)Sq6$-OoI%wcFs3=gl<-d>U!Nb!+_?VgC*B Px;Wc=tN$U|>)icc7-cZE diff --git a/docs/.validation/python/__pycache__/getting-started_5.cpython-314.pyc b/docs/.validation/python/__pycache__/getting-started_5.cpython-314.pyc deleted file mode 100644 index 8638472f2691d251cd4aa756770a914450f0cf85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 717 zcmZ`%O>fgc5S_KxaoP|=)S!mXrUVXF(pW%xL4XvBS`bwgS)#WRS+>=>b!}^Rg9xW6 z98lE*H+}+$f4~XEKPW;X$Wjler`}R>;>I|Q)e|G_n~#0-W^8R$%TEK^=fl4DfB+mN zNosTwj2>aogBM_ury#(TWTso{$K$byPGZQ#MGd6_It)QquM_pUzwXlWxlZuSic`Ri+aS(o)ZOY4ksS zB$>1VDy&||lUJBRwo zUi=xtG5+#Hdh2)o@~>>+V5TyZrK_0{NSfMP9%dj{cvsu2?bipibU;g3xOiny)V~+? zAI0iGtM*q;R8TIRWZ-=5FP}rb{>|nT`9PWq{Wy!!7t&PeR~4ggDnZocShaXJu)T1+ zM=Y~W@CioP2`q;YXYcQZPRDm2vI3^b6XMqphB6`K2(&+RiqwWBAlbLMes1sa{_;&|H#0l$z1?BwwM-glJ-oKq8^!mqh?d$zH@dR4;e(nKiEW`j**UpQPCz9~7gs)oBT(xmbNK+dhL?&g!3Pchs?L5TK$~cvG)ph( z;hX$*zFl}$#~#(OA2CFvRxXdXIH%qv^E6YCG)2R;nAdd*6n^I3Lx*UN0Uo=fH6*Nl4*5YBcX2CY#K|EMV6>2F9_GDeQyGuIFc6XVXNOKGE zAf*Sd{tJTM{X>eDfgYr%-hw%K^G%!82m8JEX20)ykC}({+6-WPKO3>v1mIjZWf;?9 z@*ImHyaS)S0ttTQCP=aaTjl?fk9iSx$ReyxPgc=U$6Zt|flDuRvl(eD!@}YNev=I0 z9x}^0FG+#jHahy1xBn*j)Hl3J>06L(vSpW6|8qHi9ei`20vwVd-7shL9_A9*uwk_+ zBd*0OsBwv^t>pzvbGeqXB$H~k%j8~vH;{QR$<$n5Bte>YyGb0dEWnO;HeEy6(Upkn zpiO@yxjYt9JX;xpC5T zPo4SC$=Iax)&ywX9(KkKR2!d`kCu;HKaJ*z(flK{!RSGod?hQ!H@i(-s_aka%(&X#Q9hqRgYdAcYeTi IehnFa0dsqccK`qY diff --git a/docs/.validation/python/__pycache__/index_29.cpython-314.pyc b/docs/.validation/python/__pycache__/index_29.cpython-314.pyc deleted file mode 100644 index 55b68f0bba56a74226498aaab6d20054ef5dc96c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 537 zcmY*WO-sW-5S?k#533D=2P-1B77x+dfapOG4=R3uh!pf>m5>D7T9dH5N_#8yAku?B zLNERUe~73AJbCiuM^E0Iw2k1xzM0v1@9hpdt7Xza>*2M_z>EPcaV_%)>(eWC450BqzH@dR4;e(nKiE<$_IPUpQPCz9~7gP7R-XRmYOT=v&MQ`_!;K zOBkgKv&L*wGS4;qhCHFbT-&K1&o7nyMxdUV%;f{*8eS@L1n)Hbt2+Ia0ByW|+}wCc z58o88i|x|0ntfEWKVpbTt$Y!0aYnsM7HOs+X^MtxF|X?sDE!>LhYrzzrwD@7@|kC! p*PIouQ5k-Rm>~F65b+JPZ#9l%pBiB5YOpnUz24qoZP`!hr{ diff --git a/docs/.validation/python/__pycache__/overview_19.cpython-314.pyc b/docs/.validation/python/__pycache__/overview_19.cpython-314.pyc deleted file mode 100644 index 0f1b3fe02ea50827690a6789ecb38dab8328dcc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1698 zcmb7EPjk~&5PwgSE%{HJ*iIWKB(O%+W(a7o`qDY$e zNpirRb~@b|?c05C-|qf)_vv_M zD2af6f4*%z;1PPklpYC@u>S=JTj)Ea;1%Q|g&RXIzJ@OK&U^N-meDm_Mhnr-0uF^D z+?+ub{v}iET67vL9Pl0Z_KyKm@iZzPL^_XcTtp3g60?Y=()mc9%^MyK{gJj@F4Tx0W1bd5tLX1EAa-Whz(xmW!$U8pif6o&10gKW)q|uJfS}+L6Fp;u(rBLR1%rekO&Llb7VXy1727sTnrfPQYq8`@E~s^N zP4{z-PSy-c4cj`WYX)2W7?{}`yV#F8#IW35&QBVa({`IJ)m53iZfmLwmXxJCJL_MN zzo9yzvZK1h&{k!K*f(^|rLq?GXpXj4<(92cxw@{J2DpLCva{)4hs9pk$-1F$G(SFF zbvFHB+iE&QZ?X)VZL0gn*Hpu*)=Y?L(zDfmZNNAM`OqW4UcxN>na=+5^}P@8fBR(m zlvh6OHjZ#RB}ElInim`bfM%)21p6C zI$KqFM8!OUas~y{pqv(SOmH- z(GQw6GMKd-2q9<%=IdaBI6telS_bQzYA)NBtKW2QO|h<*pjqET^Glj-!TjhY)uJ1q zS9kvfA=QIvYf@JwuK!;M`>gW}VKze889nM%&U^V4FTE0>iit3@*KK>1k`b^Xql}FM zt8jiSjF-`fuDW_N@>_}faV_|R4BYU=$bzsTp>bd(Mq6R41l9^a*WVDPiOhNx*k7y* z&$1ufE&dqqWJZ5BZ<}|lr_!V+P3{R?;^dyhB?@~IPF%pJUmyy_x{|4J|{wokL4`{3~7>7JjRM z^iaY}S>a(qWO5b*uR{^U=s^acDjX@n#SkDHfYRpyxNw&p1<*4f1Yn*EM_vo>#ULKr z-xleeTYef1o^JZ}@M}@`-@} diff --git a/docs/.validation/python/__pycache__/overview_8.cpython-314.pyc b/docs/.validation/python/__pycache__/overview_8.cpython-314.pyc deleted file mode 100644 index 69aa04e73612b4e61e420976b0d8d984fa2402ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1492 zcmZ`(%TF6e7@ygP*BJaL@e5MoCC(wXu{V`M^PnV(0|8V-(5T^1B}JR{7B;bWSG!}V z9aTc~&>{}Wsq!&B_CM&A`~{|}iZyB^q?~dyrBd5lzg^pHnx-SoH{av;J?5K7ArcND z7(cw+HSz*NuRLKeK=#M!3M@P5GeqzbqTb3a;YE&e8ASLLqWlB28th}=SSHZ}eiB{o zYcAs+13oy5a>8p*T*+Y;zHQk?)uOknhHg@=5BHZi(63;g?t=4qlz}4d_rsvS1KVf~ zt@3ZW_4q;J1w_yzuz!Jf_+>E!Q2;Og7f&$Z2u}nek^qrNkPMMf36o(mLc$6r5fUXa z@*ZeL$r(i=alj==lB7tQjFE9b_*O+wIE5Q*_U+s@Uc;->J93{T?<@F!y}0{B1D`c+ z)jzO-+*?;i{w;gbAez75=sWCv)!Q|~0ii6C(DJu1KZSV<=EyW};M~Lt6KhsQuQtUE zn--_pa80w(?Eh6%J`>rC`@Owz1cO*JblU^nQdWiml^Ho&Q* z{1c;OHyE#*TTGmrFW*~$08U+JytZ9w4waOC9wt)Ds=5s4nM946Zq=!Asg4i}Y#4O2 z{*Vcql-i81JJsfSk9DsrifS9Bo>}YNwi1-%WmcH9sjC&JpM`JLp)kj2s?@N|X0)uU zj_$}8o_uomW5l*|eEmHe4##8nUBnaAV~KgD%z|%BDq)&kfCYc5^|;yOK;F=Zme&s24$k{7$#*xMWw3OD3d~5Cb-nHb36-Z{>xy} zz&q&Zu5FnhdO2iSW=qOF=#Hz{Ds>F)u>zGo(lzQT{oNMb%44NsX|7V*QmY2!fhv^V zK`0iS-j<i@-g5(ut*7*;c~C zOn0L}Ins@zFo?-k0POA5jAyyqF5YOLz1hchhs0E*J2sjQb;U#>aEcNM>35WfN;?bP z5=u@SCGv-fd?y%dk6!8W+!P?VBp|q$w6pkI0EwY*E

p6^}xh!%*fYK|Y3!6!r@H z#Umm0qmVk8MdH|r00B=*;Byi}V){>a9yY&wu6z?e$K@-+ceB79oWtd7!a-)- diff --git a/docs/.validation/python/__pycache__/post-tool-use_17.cpython-314.pyc b/docs/.validation/python/__pycache__/post-tool-use_17.cpython-314.pyc deleted file mode 100644 index 434cdcc349906d4f310b977af35ab5ba5d6d5fda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 369 zcmdPq^pv<7j=%>kci^DlFCnqr}C-s&{Kz?yaNPd1!XmP4Xetx!RUO{QeEj|dd zEI&E1Br`wn7N=u*VrB_ggD9E?|I!kW4k2XW#JrT8)S{IPpFwW9<*yGkyQo;dAhDz< zGdWwopeR2pHMyi%KRLf3Gbg`9w>TwRKP5l8SYNL!F()$xY^8odWl2VUo_+z)dAcP) z_vw}vr^Xwa>lIYq;;_lhPbtkwwJYKVn$HNt#o9pP12ZEd;{#FI8?2Hu>@Kiq-C*Ip fz^A+*-&5TDoXM_HC4u*g@GB8FsH*$ONlA%p~DBqFY)DhCBOO}CLk**1M$B6}k1 z!5A+jUN{oH=*=U4Mom~h8a;91hOCL<<~-OEB|1sx&HUbP=J(#@H6=F00B!es**G8o z`z#48R12y%FxZ4Appe_(g2J_dOO{|h*bn%)_P`S9flLj_U`J-%SlJ6n{(vP}jrqXB z7(BWNv~2ZD7M$2%`z|G%-JP@vrne^iH%89vA4 z{>h9WGx~p~BJ{$^+3S4r*pE@2Qo}0bjC@I0k{(!=IU)Iii)&V0(@TORO*>C%fU&p~ zlO#o_Mbkwz#+avBHc9-j?HC0&$@wv(U>Dt7UUgL#uUnexq6}r@>g)6G$q%XSP}x>p z$Iw<~+p$)3&84zt*@kJk12n%X=PixO>2=jKuniW=_J+I67K^$AOn0D2_1xfi+TQRl z;1w92V|Wg6|MHq@6w;F>Dw}jFeSV+45PBco0ltlILc>fc_hH1~T=sdwWaW_L@K z%&a$j#}nuFgu9F&YK-jBQWsn3b+!uQTI`BYVQ=*T$A(8o|Eh z>G-sW6Ir&bRqBX{WN|JL%{26a>x-JBtFE4_jX%kqF#KpOKbeyxISp9mhuBS=1cvO_ zpkwIRp^vywIPo(MtzDlJ$&ZQT7opK>zUuXjdQD@8JeP`8foqNa0^pv<7j=%>kci^DlFCnqr}C-s(aKv8N)etu49ajHjtezs>`L21b?J_xfc zKRK}^Ge7SZr(=0yW(iom2&#Jj(h`scK_t<{yp){OqLmDvK@Pd)rw=r_s93)sv7{(7 zIa|M=C_gJTxujS>Ilmw?C%;6uI3-&@B|o`XU#~1NCo=_Xp?*PSNk)DiP;shm3D9x6 zrNyc7hNgN2mA5!-a`RJ4b5iY!xPitq0&%f6kodsN$jJCWMCJyo#0iWrim(iH+EA|X);M1z%VA_oPV&2|F=+uhC17KIb3 z2V=aDc;QI&qBp&H^e3zdD4FPqlQ*O$hMR9n3(8C8&6_vh_uiW~FOzIe0LrHyW%`i- z9Ed|*Vl|_38;wnP0tUGYAsA8zgk%xs>i2a#?!B-`dSRsI8NrA`dXU)%n*387a+c6_ ziKFoxSLG3^D~Q|#13JKmg*pP}Al6g1&VdZnz z-q>t3dOu3$cGU+0pl)~V+}rEaqf6JLE;LvUwcU^>t-v-zJ6~(KCRGt!shz7`NvDG((s)c%9<-w=qOvhmqRJylj_bb@ z(0=(_oA#wm+gDRjYu`>jY8gG0rA$Kwq;};GNGYW}^Gj^UtO=>*bcVdaDSWGBh$eHz zWb3X)y=r_e2POACR1gLyxz&lHS1395WFUr63?}PFbtn@;4j_3HQ;Ble21I?)SZ;hd N^=kSnTnsu9@fSwG;2Qt{ diff --git a/docs/.validation/python/__pycache__/session-lifecycle_11.cpython-314.pyc b/docs/.validation/python/__pycache__/session-lifecycle_11.cpython-314.pyc deleted file mode 100644 index b60894683fa36ee00df5f17ae55a227245335a0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 376 zcmdPq^pv<7j=%>kci^DlFCnqr}C-s(SaB6XJW`169Nn%lnM}B^`XI?>R$t^wz zvn)S3u>>f4i_@_@F|!1$LkwMqe`yIwi!h3KVqQv4YSBuD&miaA3f2!TPAw|dFGwsY z%1qAIFDS~-N=+^))=$na$jr$v(JfBN)=$Y#F4os8OU%hk0b8nHP+5|ZpQm38aiMNb zW?E`;WpYkxyrH39LFFwDo80`A(wtPgB5t4^j6hth4J1A=Gcqzh5R<#XDmBCJ0*m$y i7TybdDho=k@@ZdX(E-Y`>V9Qr7H7J|AY8-=R1W}RqiY8M diff --git a/docs/.validation/python/__pycache__/session-lifecycle_12.cpython-314.pyc b/docs/.validation/python/__pycache__/session-lifecycle_12.cpython-314.pyc deleted file mode 100644 index d226459f7bd11aa1956bb9576e36ce7397103bf7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1326 zcmZ8h&u`RL5Pr{IuZ{Ot(rh+#QHV*>sN0Y=2}zKu6bV8>l|qy{kOK-`S+*f2j&1pQ zf!!0@9-!)_6+LjOPX*2~q8k#^p+KtmpZSezl;AmLmc94oyoN!!08h;0n z_wfUMLy(b=HGT$(Xd}JC+qjZ4pu2%c;5~+?`w~=-b+=zD0{$JW;nU>-8fBs99eDpx zEVU#g>{DoWP$eLR_mK$(Dop>cLQWGkX@}E}y^jVi8Dg2CSQcWrp;&%N++y<^l4SZS z%pCe(iTf`!rEQB4+jA8vlb%z*50_rqpERzR-p*+hY#uFzE2@U7;g;s@Rx%LuD+{;F=file)?>-uf$Q-w;2-z>%X zE#26MjB=p6U;;qo{a)y5FVf7#IL5`K!c)NyY&WE1rWFEBtxs2D>{K9OVEX`)ZP%}d zHB%3D=HK-Uot00s3EXyXd4!$R+?+zU)$7Cxi0bRG-Pl+AAfg(cZ#!PNK+JvB^bDd_ z@9K^XZ-sZMek0ri)1TpjW8bojhT&MX#igp>pd+4JOXeGomYzI-X;jx7D8?b@tHXJA zg5(EKui)GNTgrVWJt;rkXn(jE9bbC($>ELPr1ocDMr&H6ZAbZQe@fS1PM&#IKK#7B zc=3W8lrSFBuVkeUxkvk}TOnxn(r*s~67TLwuo{`jvT9 z*z>%75)>h|S>b5faBK^XCT|3m9$HEF6)r|lu|EyME})_WV_;~C%_Lw~jQxp_bD&uJ zZ@7#g|64}mC!QB8zZWYb+_?A_aRsq;$uB7{5UIH>nXU Xc4iTl9%fpZZ!Ud%`7bmUoCL&wI+iw$ diff --git a/docs/.validation/python/__pycache__/session-lifecycle_13.cpython-314.pyc b/docs/.validation/python/__pycache__/session-lifecycle_13.cpython-314.pyc deleted file mode 100644 index d822139ab0a9084bb0107ddf99ede423b8d5a767..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 370 zcmdPq^pv<7j=%>kci^DlFCnqr}C-s(aaB6XJW`3S)UW!M4ezs>`L21b?J_xfc zKRK}kD0hp~u{<%e1gu^JRlR>{2}pw=l4xRHN=|CgN`}uMhujL*4=qkDD%LMZEGf!N z&eks|%FjwoE-BVe&M(N!$uH3@PRZ6!$xklU*DFiR$xH!Ts9#W7l98XMUkq`ZZcb)e zYI0?APHMcNv0g#tEe@O9{FKt1RJ$T>pdE}rT&xWwJ}@&fGCmNIxxp$iL+=8M<_#9! g3w%loLay>@US-h&%Cc&IWo8y-y2Kz@#0gXn03+UK#Q*>R diff --git a/docs/.validation/python/__pycache__/session-lifecycle_14.cpython-314.pyc b/docs/.validation/python/__pycache__/session-lifecycle_14.cpython-314.pyc deleted file mode 100644 index 06d46a489fc6bc09ac54dc283d6e97f0412a77de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1494 zcmZ`&O>7%g5T3U`_Qp0g)N#_dCUyxjxJ|qi+%|2aLMqyds)T4GEL5enR_ldsV|!Qc zZ6YFp6eS0WxFB)yF~@L&6FJfw$3)=9tb{m}OK&cwYI9@WuI(m4Jn7AwH#2W$_M2}{ z$6ty7uI)e8t)E1INBq)XQcvk#L1hi@fJQz57c^lMTyh)c`~H4Bo+sfpISHknr9=WH zi!UdjAU@{TIiu(Gk1)y&+}#xvy7(Gov62e5SQg(Q8jM0salqG!uaiap85i@|@6n|R znpg%+Dic*uNx%Me(Byj<{W)0^Z^{vH1WlfRFx(8C6)jQ-8Nz`){Hwmh-93k5h6Ej9 zPMA!;h*}WJL?Z_+d30*R1o#<6Z^*UkCUf<=<3*Usm}NIAR(0-sM8S(#4QJV{RCQP9 z`igDnF8aM>KM>zhx8i4D{3G-EHE%)vn3yPS>5q1l6U`f&U$io%UFGcWiR3=xAa0C|kweH1q0vY7IVyc* z7o_Tm=1>+UeMSdCACf!Zh>HWJXmB*MCX~g1 zGY6-siv5a5xswI#SROPwQ2vuwF7;T2><`$M4cJCQ_=xfpo>E<=!R#YuqgtV+&X5P8 z;G9FMh@Y9R7pJCS(`uz|^3gL-bZn;}Q-!DDm?FalgrNy;j6HTqq$t}y#OAG!$C7><92ofMeyzE%#JkrR1)Ojr%F^F z{wEEo6MMsj-Qhx8Nwj0*JGr;ou}rhkk;P+?jwqiFbwN&rpMjhRuU~({kA22l-I%&S zejw+iAHx?2jy9~b)rMi&eoarL%MHr^t}bo}T2f}}c6GUCUZy#;@xO$k#b3q diff --git a/docs/.validation/python/__pycache__/session-persistence_24.cpython-314.pyc b/docs/.validation/python/__pycache__/session-persistence_24.cpython-314.pyc deleted file mode 100644 index 386ac8aaf52390ba735184a9f1337309bac11ffb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 915 zcmZ`&%}*0i5TDomDhn-Yiy{zPJ|u2nyAg^fLu_k66GECMaKmQZZgipDUH3hd_SE3P z5Dxk$nCQj-z$^bjQDey_91JIJ#U6+^XG?2>(U;6`W_Et_@!n)-q7fPJd_LZ_gb=_< z;PejPHQHG;>hJ^#H|61C$LxB_1g z3ZfS3&G&bv8(I(L`~HzB6~Y?%Ul!gnGzk){ETT-J$P1iBls*sN6%^t}a*k`29hNIw zrp;D;nVOVZj$O1$wX56I^whg^^D5KnmYQC;=L;35WR`1@XD(A0Qgf<-?v5|Io>OsI zEtawMaDI`b@JOT!5^O@mRb+e@XTEv@7jR7<_o%T`Hecqz@T zvgfF}#Z(t7Sd^KzVHW4oDYxqL72UGEL2MGtN?#zH;`WdE+dm>B`^Eawk$mOt?B48t zs>u&G_~DiaL!-^Oau`>R!tus+#KCuomcY%3ZQzEabKnN0`f_Uk`mZ(R#G#ycKirsk z&`4&!%GoBL{laI@Vj$c+6Onf|078!ZqVw2wcRX{4d?1+#{^J;02S74Y`~evW>`{`L z<`2fCz@8!jP6w!PzNFKtZCFm{20rI)+n=C~)xe7)_~HAwzU{KP=*7_u{sVdop~VqG eP9XY|kB}T`O#lhM>EG?&d$_;!9b#S#DZc?t)XpgY diff --git a/docs/.validation/python/__pycache__/session-persistence_25.cpython-314.pyc b/docs/.validation/python/__pycache__/session-persistence_25.cpython-314.pyc deleted file mode 100644 index 8f437b63b1322556d781631c17c3029e127ba17a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 690 zcmZ`$&ubG=5T4iF{4k+gv;nmgv(eL9(#1CMWD^y!)Pxciq8Dpeb|3UL$?o#ri#0uk z2#WY8=)tT1fO_*^NG%vx@Ki6orRL<#SWob9BN@Omu*eQbuofv2EE0_>3jlxAN_s2EuuCvSkEoJGm56JczT#!K|+ zD}?LVIe@2e4I0Xv&WQ!F>Nct#V8;tGQ0j>c1n?LdiFxCkSPPb7lK)Npds_06F7^cF#akPjMQMw6u~fdj8zuwpcLRB}`efghy31VskYW%{PY9jbyu&E38cLXS zka;rHI2FAvZ3!v_^Sy9UP|t1I=!Z6w1_@KMiiobHhfTAIONANOk~61m;<^LsNMSmD zz&gGx3b$>#z9Y=_=XQs=wnSAk=*xW!GpS;L3QS1qIkdG=UJv@A+O?U-qn{j|THHlA z!z2I9t&DTVan2as+&als##&{tJxN0L(m0bp&g4H_8LjP%^hYO|+E}f9Q)}lbSgM{U zAyFs4#VU#nuihi%9obUfuORtEs_N$ylCJ~-uaL4u-*cG%cXO!lp7#-^I0pOzLYThO t_1#{FR`?R8(E-FYgo#23IR)*Pnjm#D(SW31XNTE058gif4$EA_mOtR+n$`dS diff --git a/docs/.validation/python/__pycache__/session-persistence_26.cpython-314.pyc b/docs/.validation/python/__pycache__/session-persistence_26.cpython-314.pyc deleted file mode 100644 index c855724f7b10fb3cb51da82af5cf721346801b62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 744 zcmYjP&1=*^6n~Rs*LJ^H741R6ZiT{9w~?|G!Q#nF5JUrA5Y~o}jC9=HB+SgVtX@L# z;IXJ+4<7cY;L(GBMxhrO^wd*tl|{VzCP`Z#y!U?d=6%gCS!vWOfb#v<9$O*+$NF$4 zRsm*r5TvjLE^$DDYb=0kF2JxU$#c>I*K$i;BhQtFOKwBEe4>w!1MCP|wUkj!)Y%4_ z6nd~_+Zk_09>e5(H?y*qKOJ58;IZ3E0b1KI? zY7=D&$IzEQrJP9uwg7aA{^LZ90+@L#~-rL zmn@F#WFoiG2`U60I|+7RLeeOp-rD+VGEp_p^P?!1zNDVVt2jziCt7Gy_zMQP`&*k& z;#9k@x%(!v;0%)>DCpA|N~jr8E`k*LX9Pn3JnP9h(gnG+pj)7BQIQxusDTSTl3Ak$ zYbB(QDAH*g%4CsLmSiK^Ho2b3^%p`iF(RZtN`ziwd3llRKSW&)IMwefSU}$S6^v&O zZ6iqGXY=ZZhaa7H&ihA4&BfID(YW^Z*}i`;zyEsLnmW__hgJK~vUyFnDeZa3{u70Svf#%dCgd9WlkEO|;gT}3c O-Ou%-`ubiaEB*(Qd87~k diff --git a/docs/.validation/python/__pycache__/skills_22.cpython-314.pyc b/docs/.validation/python/__pycache__/skills_22.cpython-314.pyc deleted file mode 100644 index da3b38ba24430954c36438fabd1d2c2eb9c63e25..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 977 zcmZ`%Pfrs;6rX8lyI3v%thSU$SMaha-HnI`gGeeyFd>MG5)Z~^vt4DN?QUkKAU&7{ zPlSVh1U&i;yqSK3qKA@=CK%&^8(0(L&9_S{2?;NGe`epb;daxu>8Lpu?aSZiXpV<#|sk zIR(2|m0!9dJFZ>#`uHj>7V`zlY)d$d+T4q{%qh8|dd;xcsJ*U;Wy%!`V9E=JDcrUy zjEW6~a$d2y8m`7QJt)F;KPk%sRQ2-z-GXCPO3)rtP^Vn&d#!8Mao5@~RbqY%Jc$dF z39s8?wkhm9w>bxZ7vpxhkT*fsO)5OXh2yFrFJc8f_vCgS_eV!jyjlGTw;9)6Q!r|+ z>hPEqc$!Zx7?mt9tm;6C>)M)Gq=kT$?rw->r`#r#9~;x$4Ud#eT4p^^mVojam;;!i zud&p2zIJ~v+WU5NYjj&{l4OG<_v5K%T-}YUdtE*62KKrJe<3myJ(T23q=n>5@*gDk z$hDcnI6B|ojHY*^>78UF^QfU1U!sdmve+Pt`%p2nmD$cVN#Zj}99==uz!3r1Q5;E+ z@pqE=%kKe+&7r#(@8H}m^4^a=;oJnNqZEYo6wXbO`e4G3$8c_n)NjasJb`^X8Q3Y` z&Z}WhZvRN|`@uUupcd3etQ(BibsI*dQnc@|i?H-Zn#aH#hB3xJ(beCi7bjUi?EC{g Cu;X6< diff --git a/docs/.validation/python/__pycache__/skills_23.cpython-314.pyc b/docs/.validation/python/__pycache__/skills_23.cpython-314.pyc deleted file mode 100644 index 3b5f253e10fdbbaacaac485c7dbb963fcc812999..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 620 zcmX|8&ubGw6n>N0WY@MPh!N2$ZS83Z*@c?oMLdYM3Z;|A8*;!^LrOBzp zgNXk?&wBDd@Xv@BErXtV>Mfdsh!@}HM+f%%zW3hu=FQI3%2yWv*O#9I{tx*)59Z67 ziSc6;C-4da@*Fe-g`1$s0qo7|b3gJL9FR3=%rXr!6)V`e4lcdO!`*0BosfGIu3IprDBW1azfepnKMS?wQQOa?XyH+mABl`7 zLf2K?_G1w#-#ZEu9)}vY@w1+OgET!>bK}03^^DaCc`EaV%b!3!K)Aq*`%%69z3P6g zx@XSvY3p?V%(*qZvoUNu9WHN;inLZ51HEDY0a~#K+rM)9tCp~Luv#M@iEDkbYs96- z4plFWxR?wuRCd$PFh(25D+tDU*b#9zVUJ`5!~ECOU4#)Ogq%b9w`CD~v;@R?w>VgQ O|K!8gH@Gg#==cv}bdw4I diff --git a/docs/.validation/python/__pycache__/user-prompt-submitted_10.cpython-314.pyc b/docs/.validation/python/__pycache__/user-prompt-submitted_10.cpython-314.pyc deleted file mode 100644 index 02c03ced9ce59bbd75fbe47f3c3dbc775feb542d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 878 zcmZ`%%}*0S6o0eZb~gn|C?G~-EMS@}g{~hMjUgP20YTD`O~6FKX5DVW&~|sTGbP}O zl!Gx|NW6H~i{3o)XVgUenCOWUH>4(pn{V1~jR#*cZ{El6z2BRUT&gb#C#!W&UBe=lvI-_KNyIS^mb!_^ZL+H_#gh;aOC1LdmJ&Br zN{pDJbc+GQ0IzU0mr%7?*E+KT@~;w$OkVhl@5M8(V*h_**JBYko-Z~IEuOd_k42KX zj8We!($X`1J+s2x@J>b~g3zx9ykHO!4?^m3LlH^p1vOqQ+1!@)mhadc3z-}?n-vdD zS;CU)3#9nMV04`{{bQ>;`rOTNR*{FYsz*anNuV25wuR>RV%Hs=(pJ*`sC z-BR(|)qJoc&f{=0Uu@@#-Mq+FZR+J`DmY1n&F24ylkdh1RLA&Y-}SzIvOn>9?Jzyj z7|6Z5{bBK7`*8Yx_P$on$g$50;6ToH9(KDZ8>;sN^80iV`3CrNi*WFGI%1A>*sw-$+k3 z@^g)W`4d&iC7PfNYrjG1*Xr{><#xv881+n!yunZMR?87X6`IX#gT z25oYErs|h!6?Zlq!I=Cv>=LRIl@M|SsneK7w39Rt{drHl=f%C3bDv=_Jco!su%61C diff --git a/docs/.validation/python/__pycache__/user-prompt-submitted_9.cpython-314.pyc b/docs/.validation/python/__pycache__/user-prompt-submitted_9.cpython-314.pyc deleted file mode 100644 index 7bb92042a3216787cc617ebfc9ecab469375eebd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 400 zcmdPq^pv<7j=%>kci^DlFCnqr}C-s(0XmM&$Kv8~fK}m3FQf_8RNotBmetx!R zUO{QeEj|ddEI&E1Br`wn7N=u*VrB_gqbv@M{-q@#ol@AO6Z2AXQj1nHda2YXgZ7%#4hT4`fwuuqrOF nyTD>}gN643pZ1EBt9(XRS&V_QtR`QXndO)+F-R400@VWmjD&TN diff --git a/docs/.validation/python/byok_31.py b/docs/.validation/python/byok_31.py deleted file mode 100644 index a96e316b..00000000 --- a/docs/.validation/python/byok_31.py +++ /dev/null @@ -1,38 +0,0 @@ -# Source: auth/byok.md:22 -import asyncio -import os -from copilot import CopilotClient - -FOUNDRY_MODEL_URL = "https://your-resource.openai.azure.com/openai/v1/" -# Set FOUNDRY_API_KEY environment variable - -async def main(): - client = CopilotClient() - await client.start() - - session = await client.create_session({ - "model": "gpt-5.2-codex", # Your deployment name - "provider": { - "type": "openai", - "base_url": FOUNDRY_MODEL_URL, - "wire_api": "responses", # Use "completions" for older models - "api_key": os.environ["FOUNDRY_API_KEY"], - }, - }) - - done = asyncio.Event() - - def on_event(event): - if event.type.value == "assistant.message": - print(event.data.content) - elif event.type.value == "session.idle": - done.set() - - session.on(on_event) - await session.send({"prompt": "What is 2+2?"}) - await done.wait() - - await session.destroy() - await client.stop() - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/debugging_6.py b/docs/.validation/python/debugging_6.py deleted file mode 100644 index 8a334ed9..00000000 --- a/docs/.validation/python/debugging_6.py +++ /dev/null @@ -1,4 +0,0 @@ -# Source: debugging.md:36 -from copilot import CopilotClient - -client = CopilotClient({"log_level": "debug"}) \ No newline at end of file diff --git a/docs/.validation/python/debugging_7.py b/docs/.validation/python/debugging_7.py deleted file mode 100644 index 79225854..00000000 --- a/docs/.validation/python/debugging_7.py +++ /dev/null @@ -1,4 +0,0 @@ -# Source: debugging.md:99 -# The Python SDK does not currently support passing extra CLI arguments. -# Logs are written to the default location or can be configured via -# the CLI when running in server mode. \ No newline at end of file diff --git a/docs/.validation/python/error-handling_20.py b/docs/.validation/python/error-handling_20.py deleted file mode 100644 index 7159e470..00000000 --- a/docs/.validation/python/error-handling_20.py +++ /dev/null @@ -1,5 +0,0 @@ -# Source: hooks/error-handling.md:27 -ErrorOccurredHandler = Callable[ - [ErrorOccurredHookInput, HookInvocation], - Awaitable[ErrorOccurredHookOutput | None] -] \ No newline at end of file diff --git a/docs/.validation/python/error-handling_21.py b/docs/.validation/python/error-handling_21.py deleted file mode 100644 index b2d142d0..00000000 --- a/docs/.validation/python/error-handling_21.py +++ /dev/null @@ -1,15 +0,0 @@ -# Source: hooks/error-handling.md:106 -import asyncio - -async def main(): - async def on_error_occurred(input_data, invocation): - print(f"[{invocation['session_id']}] Error: {input_data['error']}") - print(f" Context: {input_data['errorContext']}") - print(f" Recoverable: {input_data['recoverable']}") - return None - - session = await client.create_session({ - "hooks": {"on_error_occurred": on_error_occurred} - }) - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/getting-started_0.py b/docs/.validation/python/getting-started_0.py deleted file mode 100644 index 90679d38..00000000 --- a/docs/.validation/python/getting-started_0.py +++ /dev/null @@ -1,16 +0,0 @@ -# Source: getting-started.md:130 -import asyncio -from copilot import CopilotClient - -async def main(): - client = CopilotClient() - await client.start() - - session = await client.create_session({"model": "gpt-4.1"}) - response = await session.send_and_wait({"prompt": "What is 2 + 2?"}) - - print(response.data.content) - - await client.stop() - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/getting-started_1.py b/docs/.validation/python/getting-started_1.py deleted file mode 100644 index cf5748cb..00000000 --- a/docs/.validation/python/getting-started_1.py +++ /dev/null @@ -1,30 +0,0 @@ -# Source: getting-started.md:274 -import asyncio -import sys -from copilot import CopilotClient -from copilot.generated.session_events import SessionEventType - -async def main(): - client = CopilotClient() - await client.start() - - session = await client.create_session({ - "model": "gpt-4.1", - "streaming": True, - }) - - # Listen for response chunks - def handle_event(event): - if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA: - sys.stdout.write(event.data.delta_content) - sys.stdout.flush() - if event.type == SessionEventType.SESSION_IDLE: - print() # New line when done - - session.on(handle_event) - - await session.send_and_wait({"prompt": "Tell me a short joke"}) - - await client.stop() - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/getting-started_2.py b/docs/.validation/python/getting-started_2.py deleted file mode 100644 index f81b403b..00000000 --- a/docs/.validation/python/getting-started_2.py +++ /dev/null @@ -1,15 +0,0 @@ -# Source: getting-started.md:429 -# Subscribe to all events -unsubscribe = session.on(lambda event: print(f"Event: {event.type}")) - -# Filter by event type in your handler -def handle_event(event): - if event.type == SessionEventType.SESSION_IDLE: - print("Session is idle") - elif event.type == SessionEventType.ASSISTANT_MESSAGE: - print(f"Message: {event.data.content}") - -unsubscribe = session.on(handle_event) - -# Later, to unsubscribe: -unsubscribe() \ No newline at end of file diff --git a/docs/.validation/python/getting-started_3.py b/docs/.validation/python/getting-started_3.py deleted file mode 100644 index 3c255d89..00000000 --- a/docs/.validation/python/getting-started_3.py +++ /dev/null @@ -1,49 +0,0 @@ -# Source: getting-started.md:562 -import asyncio -import random -import sys -from copilot import CopilotClient -from copilot.tools import define_tool -from copilot.generated.session_events import SessionEventType -from pydantic import BaseModel, Field - -# Define the parameters for the tool using Pydantic -class GetWeatherParams(BaseModel): - city: str = Field(description="The name of the city to get weather for") - -# Define a tool that Copilot can call -@define_tool(description="Get the current weather for a city") -async def get_weather(params: GetWeatherParams) -> dict: - city = params.city - # In a real app, you'd call a weather API here - conditions = ["sunny", "cloudy", "rainy", "partly cloudy"] - temp = random.randint(50, 80) - condition = random.choice(conditions) - return {"city": city, "temperature": f"{temp}°F", "condition": condition} - -async def main(): - client = CopilotClient() - await client.start() - - session = await client.create_session({ - "model": "gpt-4.1", - "streaming": True, - "tools": [get_weather], - }) - - def handle_event(event): - if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA: - sys.stdout.write(event.data.delta_content) - sys.stdout.flush() - if event.type == SessionEventType.SESSION_IDLE: - print() - - session.on(handle_event) - - await session.send_and_wait({ - "prompt": "What's the weather like in Seattle and Tokyo?" - }) - - await client.stop() - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/getting-started_4.py b/docs/.validation/python/getting-started_4.py deleted file mode 100644 index 2fc68796..00000000 --- a/docs/.validation/python/getting-started_4.py +++ /dev/null @@ -1,56 +0,0 @@ -# Source: getting-started.md:834 -import asyncio -import random -import sys -from copilot import CopilotClient -from copilot.tools import define_tool -from copilot.generated.session_events import SessionEventType -from pydantic import BaseModel, Field - -class GetWeatherParams(BaseModel): - city: str = Field(description="The name of the city to get weather for") - -@define_tool(description="Get the current weather for a city") -async def get_weather(params: GetWeatherParams) -> dict: - city = params.city - conditions = ["sunny", "cloudy", "rainy", "partly cloudy"] - temp = random.randint(50, 80) - condition = random.choice(conditions) - return {"city": city, "temperature": f"{temp}°F", "condition": condition} - -async def main(): - client = CopilotClient() - await client.start() - - session = await client.create_session({ - "model": "gpt-4.1", - "streaming": True, - "tools": [get_weather], - }) - - def handle_event(event): - if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA: - sys.stdout.write(event.data.delta_content) - sys.stdout.flush() - - session.on(handle_event) - - print("🌤️ Weather Assistant (type 'exit' to quit)") - print(" Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'\n") - - while True: - try: - user_input = input("You: ") - except EOFError: - break - - if user_input.lower() == "exit": - break - - sys.stdout.write("Assistant: ") - await session.send_and_wait({"prompt": user_input}) - print("\n") - - await client.stop() - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/getting-started_5.py b/docs/.validation/python/getting-started_5.py deleted file mode 100644 index 8b405cd2..00000000 --- a/docs/.validation/python/getting-started_5.py +++ /dev/null @@ -1,16 +0,0 @@ -# Source: getting-started.md:1210 -import asyncio - -async def main(): - from copilot import CopilotClient - - client = CopilotClient({ - "cli_url": "localhost:4321" - }) - await client.start() - - # Use the client normally - session = await client.create_session() - # ... - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/index_27.py b/docs/.validation/python/index_27.py deleted file mode 100644 index c644ba60..00000000 --- a/docs/.validation/python/index_27.py +++ /dev/null @@ -1,11 +0,0 @@ -# Source: auth/index.md:40 -import asyncio - -async def main(): - from copilot import CopilotClient - - # Default: uses logged-in user credentials - client = CopilotClient() - await client.start() - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/index_28.py b/docs/.validation/python/index_28.py deleted file mode 100644 index 1721ece4..00000000 --- a/docs/.validation/python/index_28.py +++ /dev/null @@ -1,13 +0,0 @@ -# Source: auth/index.md:108 -import asyncio - -async def main(): - from copilot import CopilotClient - - client = CopilotClient({ - "github_token": user_access_token, # Token from OAuth flow - "use_logged_in_user": False, # Don't use stored CLI credentials - }) - await client.start() - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/index_29.py b/docs/.validation/python/index_29.py deleted file mode 100644 index 1da4e053..00000000 --- a/docs/.validation/python/index_29.py +++ /dev/null @@ -1,11 +0,0 @@ -# Source: auth/index.md:195 -import asyncio - -async def main(): - from copilot import CopilotClient - - # Token is read from environment variable automatically - client = CopilotClient() - await client.start() - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/index_30.py b/docs/.validation/python/index_30.py deleted file mode 100644 index fa48bc2d..00000000 --- a/docs/.validation/python/index_30.py +++ /dev/null @@ -1,4 +0,0 @@ -# Source: auth/index.md:256 -client = CopilotClient({ - "use_logged_in_user": False, # Only use explicit tokens -}) \ No newline at end of file diff --git a/docs/.validation/python/overview_19.py b/docs/.validation/python/overview_19.py deleted file mode 100644 index 8e9f4ee2..00000000 --- a/docs/.validation/python/overview_19.py +++ /dev/null @@ -1,30 +0,0 @@ -# Source: hooks/overview.md:55 -import asyncio - -async def main(): - from copilot import CopilotClient - - async def main(): - client = CopilotClient() - await client.start() - - async def on_pre_tool_use(input_data, invocation): - print(f"Tool called: {input_data['toolName']}") - return {"permissionDecision": "allow"} - - async def on_post_tool_use(input_data, invocation): - print(f"Tool result: {input_data['toolResult']}") - return None - - async def on_session_start(input_data, invocation): - return {"additionalContext": "User prefers concise answers."} - - session = await client.create_session({ - "hooks": { - "on_pre_tool_use": on_pre_tool_use, - "on_post_tool_use": on_post_tool_use, - "on_session_start": on_session_start, - } - }) - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/overview_8.py b/docs/.validation/python/overview_8.py deleted file mode 100644 index 55285ce0..00000000 --- a/docs/.validation/python/overview_8.py +++ /dev/null @@ -1,39 +0,0 @@ -# Source: mcp/overview.md:60 -import asyncio -from copilot import CopilotClient - -async def main(): - client = CopilotClient() - await client.start() - - session = await client.create_session({ - "model": "gpt-5", - "mcp_servers": { - # Local MCP server (stdio) - "my-local-server": { - "type": "local", - "command": "python", - "args": ["./mcp_server.py"], - "env": {"DEBUG": "true"}, - "cwd": "./servers", - "tools": ["*"], - "timeout": 30000, - }, - # Remote MCP server (HTTP) - "github": { - "type": "http", - "url": "https://api.githubcopilot.com/mcp/", - "headers": {"Authorization": "Bearer ${TOKEN}"}, - "tools": ["*"], - }, - }, - }) - - response = await session.send_and_wait({ - "prompt": "List my recent GitHub notifications" - }) - print(response.data.content) - - await client.stop() - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/post-tool-use_17.py b/docs/.validation/python/post-tool-use_17.py deleted file mode 100644 index 45c3ec84..00000000 --- a/docs/.validation/python/post-tool-use_17.py +++ /dev/null @@ -1,5 +0,0 @@ -# Source: hooks/post-tool-use.md:27 -PostToolUseHandler = Callable[ - [PostToolUseHookInput, HookInvocation], - Awaitable[PostToolUseHookOutput | None] -] \ No newline at end of file diff --git a/docs/.validation/python/post-tool-use_18.py b/docs/.validation/python/post-tool-use_18.py deleted file mode 100644 index 589c9a0b..00000000 --- a/docs/.validation/python/post-tool-use_18.py +++ /dev/null @@ -1,15 +0,0 @@ -# Source: hooks/post-tool-use.md:105 -import asyncio - -async def main(): - async def on_post_tool_use(input_data, invocation): - print(f"[{invocation['session_id']}] Tool: {input_data['toolName']}") - print(f" Args: {input_data['toolArgs']}") - print(f" Result: {input_data['toolResult']}") - return None # Pass through unchanged - - session = await client.create_session({ - "hooks": {"on_post_tool_use": on_post_tool_use} - }) - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/pre-tool-use_15.py b/docs/.validation/python/pre-tool-use_15.py deleted file mode 100644 index 29c0c82b..00000000 --- a/docs/.validation/python/pre-tool-use_15.py +++ /dev/null @@ -1,5 +0,0 @@ -# Source: hooks/pre-tool-use.md:27 -PreToolUseHandler = Callable[ - [PreToolUseHookInput, HookInvocation], - Awaitable[PreToolUseHookOutput | None] -] \ No newline at end of file diff --git a/docs/.validation/python/pre-tool-use_16.py b/docs/.validation/python/pre-tool-use_16.py deleted file mode 100644 index e39784af..00000000 --- a/docs/.validation/python/pre-tool-use_16.py +++ /dev/null @@ -1,14 +0,0 @@ -# Source: hooks/pre-tool-use.md:113 -import asyncio - -async def main(): - async def on_pre_tool_use(input_data, invocation): - print(f"[{invocation['session_id']}] Calling {input_data['toolName']}") - print(f" Args: {input_data['toolArgs']}") - return {"permissionDecision": "allow"} - - session = await client.create_session({ - "hooks": {"on_pre_tool_use": on_pre_tool_use} - }) - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/session-lifecycle_11.py b/docs/.validation/python/session-lifecycle_11.py deleted file mode 100644 index b72d0676..00000000 --- a/docs/.validation/python/session-lifecycle_11.py +++ /dev/null @@ -1,5 +0,0 @@ -# Source: hooks/session-lifecycle.md:31 -SessionStartHandler = Callable[ - [SessionStartHookInput, HookInvocation], - Awaitable[SessionStartHookOutput | None] -] \ No newline at end of file diff --git a/docs/.validation/python/session-lifecycle_12.py b/docs/.validation/python/session-lifecycle_12.py deleted file mode 100644 index 1ff60a18..00000000 --- a/docs/.validation/python/session-lifecycle_12.py +++ /dev/null @@ -1,22 +0,0 @@ -# Source: hooks/session-lifecycle.md:112 -import asyncio - -async def main(): - async def on_session_start(input_data, invocation): - print(f"Session {invocation['session_id']} started ({input_data['source']})") - - project_info = await detect_project_type(input_data["cwd"]) - - return { - "additionalContext": f""" - This is a {project_info['type']} project. - Main language: {project_info['language']} - Package manager: {project_info['packageManager']} - """.strip() - } - - session = await client.create_session({ - "hooks": {"on_session_start": on_session_start} - }) - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/session-lifecycle_13.py b/docs/.validation/python/session-lifecycle_13.py deleted file mode 100644 index c010feef..00000000 --- a/docs/.validation/python/session-lifecycle_13.py +++ /dev/null @@ -1,5 +0,0 @@ -# Source: hooks/session-lifecycle.md:208 -SessionEndHandler = Callable[ - [SessionEndHookInput, HookInvocation], - Awaitable[SessionEndHookOutput | None] -] \ No newline at end of file diff --git a/docs/.validation/python/session-lifecycle_14.py b/docs/.validation/python/session-lifecycle_14.py deleted file mode 100644 index 1947157b..00000000 --- a/docs/.validation/python/session-lifecycle_14.py +++ /dev/null @@ -1,31 +0,0 @@ -# Source: hooks/session-lifecycle.md:307 -import asyncio - -async def main(): - session_start_times = {} - - async def on_session_start(input_data, invocation): - session_start_times[invocation["session_id"]] = input_data["timestamp"] - return None - - async def on_session_end(input_data, invocation): - start_time = session_start_times.get(invocation["session_id"]) - duration = input_data["timestamp"] - start_time if start_time else 0 - - await record_metrics({ - "session_id": invocation["session_id"], - "duration": duration, - "end_reason": input_data["reason"], - }) - - session_start_times.pop(invocation["session_id"], None) - return None - - session = await client.create_session({ - "hooks": { - "on_session_start": on_session_start, - "on_session_end": on_session_end, - } - }) - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/session-persistence_24.py b/docs/.validation/python/session-persistence_24.py deleted file mode 100644 index 8e3bbf55..00000000 --- a/docs/.validation/python/session-persistence_24.py +++ /dev/null @@ -1,21 +0,0 @@ -# Source: guides/session-persistence.md:48 -import asyncio - -async def main(): - from copilot import CopilotClient - - client = CopilotClient() - await client.start() - - # Create a session with a meaningful ID - session = await client.create_session({ - "session_id": "user-123-task-456", - "model": "gpt-5.2-codex", - }) - - # Do some work... - await session.send_and_wait({"prompt": "Analyze my codebase"}) - - # Session state is automatically persisted - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/session-persistence_25.py b/docs/.validation/python/session-persistence_25.py deleted file mode 100644 index b8e9ff05..00000000 --- a/docs/.validation/python/session-persistence_25.py +++ /dev/null @@ -1,11 +0,0 @@ -# Source: guides/session-persistence.md:135 -import asyncio - -async def main(): - # Resume from a different client instance (or after restart) - session = await client.resume_session("user-123-task-456") - - # Continue where you left off - await session.send_and_wait({"prompt": "What did we discuss earlier?"}) - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/session-persistence_26.py b/docs/.validation/python/session-persistence_26.py deleted file mode 100644 index e26712c0..00000000 --- a/docs/.validation/python/session-persistence_26.py +++ /dev/null @@ -1,9 +0,0 @@ -# Source: guides/session-persistence.md:248 -import time - -def create_session_id(user_id: str, task_type: str) -> str: - timestamp = int(time.time()) - return f"{user_id}-{task_type}-{timestamp}" - -session_id = create_session_id("alice", "code-review") -# → "alice-code-review-1706932800" \ No newline at end of file diff --git a/docs/.validation/python/skills_22.py b/docs/.validation/python/skills_22.py deleted file mode 100644 index 35154bb5..00000000 --- a/docs/.validation/python/skills_22.py +++ /dev/null @@ -1,20 +0,0 @@ -# Source: guides/skills.md:47 -from copilot import CopilotClient - -async def main(): - client = CopilotClient() - await client.start() - - session = await client.create_session({ - "model": "gpt-4.1", - "skill_directories": [ - "./skills/code-review", - "./skills/documentation", - "~/.copilot/skills", # User-level skills - ], - }) - - # Copilot now has access to skills in those directories - await session.send_and_wait({"prompt": "Review this code for security issues"}) - - await client.stop() \ No newline at end of file diff --git a/docs/.validation/python/skills_23.py b/docs/.validation/python/skills_23.py deleted file mode 100644 index cb0d4dfc..00000000 --- a/docs/.validation/python/skills_23.py +++ /dev/null @@ -1,10 +0,0 @@ -# Source: guides/skills.md:161 -import asyncio - -async def main(): - session = await client.create_session({ - "skill_directories": ["./skills"], - "disabled_skills": ["experimental-feature", "deprecated-tool"], - }) - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/user-prompt-submitted_10.py b/docs/.validation/python/user-prompt-submitted_10.py deleted file mode 100644 index 02fde460..00000000 --- a/docs/.validation/python/user-prompt-submitted_10.py +++ /dev/null @@ -1,13 +0,0 @@ -# Source: hooks/user-prompt-submitted.md:101 -import asyncio - -async def main(): - async def on_user_prompt_submitted(input_data, invocation): - print(f"[{invocation['session_id']}] User: {input_data['prompt']}") - return None - - session = await client.create_session({ - "hooks": {"on_user_prompt_submitted": on_user_prompt_submitted} - }) - -asyncio.run(main()) \ No newline at end of file diff --git a/docs/.validation/python/user-prompt-submitted_9.py b/docs/.validation/python/user-prompt-submitted_9.py deleted file mode 100644 index 9c6283a7..00000000 --- a/docs/.validation/python/user-prompt-submitted_9.py +++ /dev/null @@ -1,5 +0,0 @@ -# Source: hooks/user-prompt-submitted.md:27 -UserPromptSubmittedHandler = Callable[ - [UserPromptSubmittedHookInput, HookInvocation], - Awaitable[UserPromptSubmittedHookOutput | None] -] \ No newline at end of file diff --git a/docs/.validation/typescript/byok_85.ts b/docs/.validation/typescript/byok_85.ts deleted file mode 100644 index a8dbc9b8..00000000 --- a/docs/.validation/typescript/byok_85.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Source: auth/byok.md:67 -import { CopilotClient } from "@github/copilot-sdk"; - -const FOUNDRY_MODEL_URL = "https://your-resource.openai.azure.com/openai/v1/"; - -const client = new CopilotClient(); -const session = await client.createSession({ - model: "gpt-5.2-codex", // Your deployment name - provider: { - type: "openai", - baseUrl: FOUNDRY_MODEL_URL, - wireApi: "responses", // Use "completions" for older models - apiKey: process.env.FOUNDRY_API_KEY, - }, -}); - -session.on("assistant.message", (event) => { - console.log(event.data.content); -}); - -await session.sendAndWait({ prompt: "What is 2+2?" }); -await client.stop(); \ No newline at end of file diff --git a/docs/.validation/typescript/byok_86.ts b/docs/.validation/typescript/byok_86.ts deleted file mode 100644 index 71c202cf..00000000 --- a/docs/.validation/typescript/byok_86.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Source: auth/byok.md:312 -// ❌ Error: Model required with custom provider -const session = await client.createSession({ - provider: { type: "openai", baseUrl: "..." }, -}); - -// ✅ Correct: Model specified -const session = await client.createSession({ - model: "gpt-4", // Required! - provider: { type: "openai", baseUrl: "..." }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/compatibility_15.ts b/docs/.validation/typescript/compatibility_15.ts deleted file mode 100644 index 490750e6..00000000 --- a/docs/.validation/typescript/compatibility_15.ts +++ /dev/null @@ -1,13 +0,0 @@ -// Source: compatibility.md:129 -const session = await client.createSession({ - onPermissionRequest: async (request) => { - // Auto-approve everything (equivalent to --yolo) - return { approved: true }; - - // Or implement custom logic - if (request.kind === "shell") { - return { approved: request.command.startsWith("git") }; - } - return { approved: true }; - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/compatibility_16.ts b/docs/.validation/typescript/compatibility_16.ts deleted file mode 100644 index 36525f41..00000000 --- a/docs/.validation/typescript/compatibility_16.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Source: compatibility.md:148 -session.on("assistant.usage", (event) => { - console.log("Tokens used:", { - input: event.data.inputTokens, - output: event.data.outputTokens, - }); -}); \ No newline at end of file diff --git a/docs/.validation/typescript/compatibility_17.ts b/docs/.validation/typescript/compatibility_17.ts deleted file mode 100644 index 334f6427..00000000 --- a/docs/.validation/typescript/compatibility_17.ts +++ /dev/null @@ -1,8 +0,0 @@ -// Source: compatibility.md:161 -const session = await client.createSession({ - infiniteSessions: { - enabled: true, - backgroundCompactionThreshold: 0.80, // Start background compaction at 80% context utilization - bufferExhaustionThreshold: 0.95, // Block and compact at 95% context utilization - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/debugging_10.ts b/docs/.validation/typescript/debugging_10.ts deleted file mode 100644 index 42068478..00000000 --- a/docs/.validation/typescript/debugging_10.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Source: debugging.md:88 -const client = new CopilotClient({ - cliArgs: ["--log-dir", "/path/to/logs"], -}); \ No newline at end of file diff --git a/docs/.validation/typescript/debugging_11.ts b/docs/.validation/typescript/debugging_11.ts deleted file mode 100644 index bf4c26ca..00000000 --- a/docs/.validation/typescript/debugging_11.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Source: debugging.md:326 -const client = new CopilotClient({ - useStdio: true, // This is the default -}); \ No newline at end of file diff --git a/docs/.validation/typescript/debugging_12.ts b/docs/.validation/typescript/debugging_12.ts deleted file mode 100644 index 4dcb52c9..00000000 --- a/docs/.validation/typescript/debugging_12.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Source: debugging.md:333 -const client = new CopilotClient({ - useStdio: false, - port: 8080, // Or 0 for random port -}); \ No newline at end of file diff --git a/docs/.validation/typescript/debugging_13.ts b/docs/.validation/typescript/debugging_13.ts deleted file mode 100644 index 7a6bc2ff..00000000 --- a/docs/.validation/typescript/debugging_13.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Source: debugging.md:341 -const client = new CopilotClient({ - cliUrl: "localhost:8080", // Connect to running server -}); \ No newline at end of file diff --git a/docs/.validation/typescript/debugging_14.ts b/docs/.validation/typescript/debugging_14.ts deleted file mode 100644 index cf61210a..00000000 --- a/docs/.validation/typescript/debugging_14.ts +++ /dev/null @@ -1,8 +0,0 @@ -// Source: debugging.md:416 -session.on("tool.execution_error", (event) => { - console.error("Tool error:", event.data); -}); - -session.on("error", (event) => { - console.error("Session error:", event.data); -}); \ No newline at end of file diff --git a/docs/.validation/typescript/debugging_9.ts b/docs/.validation/typescript/debugging_9.ts deleted file mode 100644 index fb746265..00000000 --- a/docs/.validation/typescript/debugging_9.ts +++ /dev/null @@ -1,6 +0,0 @@ -// Source: debugging.md:23 -import { CopilotClient } from "@github/copilot-sdk"; - -const client = new CopilotClient({ - logLevel: "debug", // Options: "none", "error", "warning", "info", "debug", "all" -}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_57.ts b/docs/.validation/typescript/error-handling_57.ts deleted file mode 100644 index fc5626bf..00000000 --- a/docs/.validation/typescript/error-handling_57.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Source: hooks/error-handling.md:15 -type ErrorOccurredHandler = ( - input: ErrorOccurredHookInput, - invocation: HookInvocation -) => Promise; \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_58.ts b/docs/.validation/typescript/error-handling_58.ts deleted file mode 100644 index 14e67079..00000000 --- a/docs/.validation/typescript/error-handling_58.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Source: hooks/error-handling.md:88 -const session = await client.createSession({ - hooks: { - onErrorOccurred: async (input, invocation) => { - console.error(`[${invocation.sessionId}] Error: ${input.error}`); - console.error(` Context: ${input.errorContext}`); - console.error(` Recoverable: ${input.recoverable}`); - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_59.ts b/docs/.validation/typescript/error-handling_59.ts deleted file mode 100644 index 80e2ea8a..00000000 --- a/docs/.validation/typescript/error-handling_59.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Source: hooks/error-handling.md:162 -import { captureException } from "@sentry/node"; // or your monitoring service - -const session = await client.createSession({ - hooks: { - onErrorOccurred: async (input, invocation) => { - captureException(new Error(input.error), { - tags: { - sessionId: invocation.sessionId, - errorContext: input.errorContext, - }, - extra: { - error: input.error, - recoverable: input.recoverable, - cwd: input.cwd, - }, - }); - - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_60.ts b/docs/.validation/typescript/error-handling_60.ts deleted file mode 100644 index 768e5ed2..00000000 --- a/docs/.validation/typescript/error-handling_60.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Source: hooks/error-handling.md:188 -const ERROR_MESSAGES: Record = { - "model_call": "There was an issue communicating with the AI model. Please try again.", - "tool_execution": "A tool failed to execute. Please check your inputs and try again.", - "system": "A system error occurred. Please try again later.", - "user_input": "There was an issue with your input. Please check and try again.", -}; - -const session = await client.createSession({ - hooks: { - onErrorOccurred: async (input) => { - const friendlyMessage = ERROR_MESSAGES[input.errorContext]; - - if (friendlyMessage) { - return { - userNotification: friendlyMessage, - }; - } - - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_61.ts b/docs/.validation/typescript/error-handling_61.ts deleted file mode 100644 index ba3f2067..00000000 --- a/docs/.validation/typescript/error-handling_61.ts +++ /dev/null @@ -1,13 +0,0 @@ -// Source: hooks/error-handling.md:215 -const session = await client.createSession({ - hooks: { - onErrorOccurred: async (input) => { - // Suppress tool execution errors that are recoverable - if (input.errorContext === "tool_execution" && input.recoverable) { - console.log(`Suppressed recoverable error: ${input.error}`); - return { suppressOutput: true }; - } - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_62.ts b/docs/.validation/typescript/error-handling_62.ts deleted file mode 100644 index e81a93a9..00000000 --- a/docs/.validation/typescript/error-handling_62.ts +++ /dev/null @@ -1,27 +0,0 @@ -// Source: hooks/error-handling.md:232 -const session = await client.createSession({ - hooks: { - onErrorOccurred: async (input) => { - if (input.errorContext === "tool_execution") { - return { - userNotification: ` -The tool failed. Here are some recovery suggestions: -- Check if required dependencies are installed -- Verify file paths are correct -- Try a simpler approach - `.trim(), - }; - } - - if (input.errorContext === "model_call" && input.error.includes("rate")) { - return { - errorHandling: "retry", - retryCount: 3, - userNotification: "Rate limit hit. Retrying...", - }; - } - - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_63.ts b/docs/.validation/typescript/error-handling_63.ts deleted file mode 100644 index 4b353e26..00000000 --- a/docs/.validation/typescript/error-handling_63.ts +++ /dev/null @@ -1,35 +0,0 @@ -// Source: hooks/error-handling.md:263 -interface ErrorStats { - count: number; - lastOccurred: number; - contexts: string[]; -} - -const errorStats = new Map(); - -const session = await client.createSession({ - hooks: { - onErrorOccurred: async (input, invocation) => { - const key = `${input.errorContext}:${input.error.substring(0, 50)}`; - - const existing = errorStats.get(key) || { - count: 0, - lastOccurred: 0, - contexts: [], - }; - - existing.count++; - existing.lastOccurred = input.timestamp; - existing.contexts.push(invocation.sessionId); - - errorStats.set(key, existing); - - // Alert if error is recurring - if (existing.count >= 5) { - console.warn(`Recurring error detected: ${key} (${existing.count} times)`); - } - - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_64.ts b/docs/.validation/typescript/error-handling_64.ts deleted file mode 100644 index 7f41f5a4..00000000 --- a/docs/.validation/typescript/error-handling_64.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Source: hooks/error-handling.md:302 -const CRITICAL_CONTEXTS = ["system", "model_call"]; - -const session = await client.createSession({ - hooks: { - onErrorOccurred: async (input, invocation) => { - if (CRITICAL_CONTEXTS.includes(input.errorContext) && !input.recoverable) { - await sendAlert({ - level: "critical", - message: `Critical error in session ${invocation.sessionId}`, - error: input.error, - context: input.errorContext, - timestamp: new Date(input.timestamp).toISOString(), - }); - } - - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/error-handling_65.ts b/docs/.validation/typescript/error-handling_65.ts deleted file mode 100644 index 25c3b169..00000000 --- a/docs/.validation/typescript/error-handling_65.ts +++ /dev/null @@ -1,36 +0,0 @@ -// Source: hooks/error-handling.md:326 -const sessionContext = new Map(); - -const session = await client.createSession({ - hooks: { - onPreToolUse: async (input, invocation) => { - const ctx = sessionContext.get(invocation.sessionId) || {}; - ctx.lastTool = input.toolName; - sessionContext.set(invocation.sessionId, ctx); - return { permissionDecision: "allow" }; - }, - - onUserPromptSubmitted: async (input, invocation) => { - const ctx = sessionContext.get(invocation.sessionId) || {}; - ctx.lastPrompt = input.prompt.substring(0, 100); - sessionContext.set(invocation.sessionId, ctx); - return null; - }, - - onErrorOccurred: async (input, invocation) => { - const ctx = sessionContext.get(invocation.sessionId); - - console.error(`Error in session ${invocation.sessionId}:`); - console.error(` Error: ${input.error}`); - console.error(` Context: ${input.errorContext}`); - if (ctx?.lastTool) { - console.error(` Last tool: ${ctx.lastTool}`); - } - if (ctx?.lastPrompt) { - console.error(` Last prompt: ${ctx.lastPrompt}...`); - } - - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_0.ts b/docs/.validation/typescript/getting-started_0.ts deleted file mode 100644 index 093de6f0..00000000 --- a/docs/.validation/typescript/getting-started_0.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Source: getting-started.md:104 -import { CopilotClient } from "@github/copilot-sdk"; - -const client = new CopilotClient(); -const session = await client.createSession({ model: "gpt-4.1" }); - -const response = await session.sendAndWait({ prompt: "What is 2 + 2?" }); -console.log(response?.data.content); - -await client.stop(); -process.exit(0); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_1.ts b/docs/.validation/typescript/getting-started_1.ts deleted file mode 100644 index ac83e867..00000000 --- a/docs/.validation/typescript/getting-started_1.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Source: getting-started.md:244 -import { CopilotClient } from "@github/copilot-sdk"; - -const client = new CopilotClient(); -const session = await client.createSession({ - model: "gpt-4.1", - streaming: true, -}); - -// Listen for response chunks -session.on("assistant.message_delta", (event) => { - process.stdout.write(event.data.deltaContent); -}); -session.on("session.idle", () => { - console.log(); // New line when done -}); - -await session.sendAndWait({ prompt: "Tell me a short joke" }); - -await client.stop(); -process.exit(0); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_2.ts b/docs/.validation/typescript/getting-started_2.ts deleted file mode 100644 index 00c20924..00000000 --- a/docs/.validation/typescript/getting-started_2.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Source: getting-started.md:408 -// Subscribe to all events -const unsubscribeAll = session.on((event) => { - console.log("Event:", event.type); -}); - -// Subscribe to specific event type -const unsubscribeIdle = session.on("session.idle", (event) => { - console.log("Session is idle"); -}); - -// Later, to unsubscribe: -unsubscribeAll(); -unsubscribeIdle(); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_3.ts b/docs/.validation/typescript/getting-started_3.ts deleted file mode 100644 index 44ea1144..00000000 --- a/docs/.validation/typescript/getting-started_3.ts +++ /dev/null @@ -1,44 +0,0 @@ -// Source: getting-started.md:509 -import { CopilotClient, defineTool } from "@github/copilot-sdk"; - -// Define a tool that Copilot can call -const getWeather = defineTool("get_weather", { - description: "Get the current weather for a city", - parameters: { - type: "object", - properties: { - city: { type: "string", description: "The city name" }, - }, - required: ["city"], - }, - handler: async (args: { city: string }) => { - const { city } = args; - // In a real app, you'd call a weather API here - const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"]; - const temp = Math.floor(Math.random() * 30) + 50; - const condition = conditions[Math.floor(Math.random() * conditions.length)]; - return { city, temperature: `${temp}°F`, condition }; - }, -}); - -const client = new CopilotClient(); -const session = await client.createSession({ - model: "gpt-4.1", - streaming: true, - tools: [getWeather], -}); - -session.on("assistant.message_delta", (event) => { - process.stdout.write(event.data.deltaContent); -}); - -session.on("session.idle", () => { - console.log(); // New line when done -}); - -await session.sendAndWait({ - prompt: "What's the weather like in Seattle and Tokyo?", -}); - -await client.stop(); -process.exit(0); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_4.ts b/docs/.validation/typescript/getting-started_4.ts deleted file mode 100644 index 4f5d34b0..00000000 --- a/docs/.validation/typescript/getting-started_4.ts +++ /dev/null @@ -1,56 +0,0 @@ -// Source: getting-started.md:763 -import { CopilotClient, defineTool } from "@github/copilot-sdk"; -import * as readline from "readline"; - -const getWeather = defineTool("get_weather", { - description: "Get the current weather for a city", - parameters: { - type: "object", - properties: { - city: { type: "string", description: "The city name" }, - }, - required: ["city"], - }, - handler: async ({ city }) => { - const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"]; - const temp = Math.floor(Math.random() * 30) + 50; - const condition = conditions[Math.floor(Math.random() * conditions.length)]; - return { city, temperature: `${temp}°F`, condition }; - }, -}); - -const client = new CopilotClient(); -const session = await client.createSession({ - model: "gpt-4.1", - streaming: true, - tools: [getWeather], -}); - -session.on("assistant.message_delta", (event) => { - process.stdout.write(event.data.deltaContent); -}); - -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, -}); - -console.log("🌤️ Weather Assistant (type 'exit' to quit)"); -console.log(" Try: 'What's the weather in Paris?'\n"); - -const prompt = () => { - rl.question("You: ", async (input) => { - if (input.toLowerCase() === "exit") { - await client.stop(); - rl.close(); - return; - } - - process.stdout.write("Assistant: "); - await session.sendAndWait({ prompt: input }); - console.log("\n"); - prompt(); - }); -}; - -prompt(); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_5.ts b/docs/.validation/typescript/getting-started_5.ts deleted file mode 100644 index edb59327..00000000 --- a/docs/.validation/typescript/getting-started_5.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Source: getting-started.md:1126 -const session = await client.createSession({ - mcpServers: { - github: { - type: "http", - url: "https://api.githubcopilot.com/mcp/", - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_6.ts b/docs/.validation/typescript/getting-started_6.ts deleted file mode 100644 index 729ec618..00000000 --- a/docs/.validation/typescript/getting-started_6.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Source: getting-started.md:1143 -const session = await client.createSession({ - customAgents: [{ - name: "pr-reviewer", - displayName: "PR Reviewer", - description: "Reviews pull requests for best practices", - prompt: "You are an expert code reviewer. Focus on security, performance, and maintainability.", - }], -}); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_7.ts b/docs/.validation/typescript/getting-started_7.ts deleted file mode 100644 index 69199497..00000000 --- a/docs/.validation/typescript/getting-started_7.ts +++ /dev/null @@ -1,6 +0,0 @@ -// Source: getting-started.md:1158 -const session = await client.createSession({ - systemMessage: { - content: "You are a helpful assistant for our engineering team. Always be concise.", - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/getting-started_8.ts b/docs/.validation/typescript/getting-started_8.ts deleted file mode 100644 index 27f32acd..00000000 --- a/docs/.validation/typescript/getting-started_8.ts +++ /dev/null @@ -1,10 +0,0 @@ -// Source: getting-started.md:1193 -import { CopilotClient } from "@github/copilot-sdk"; - -const client = new CopilotClient({ - cliUrl: "localhost:4321" -}); - -// Use the client normally -const session = await client.createSession(); -// ... \ No newline at end of file diff --git a/docs/.validation/typescript/index_81.ts b/docs/.validation/typescript/index_81.ts deleted file mode 100644 index 3310fff9..00000000 --- a/docs/.validation/typescript/index_81.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Source: auth/index.md:28 -import { CopilotClient } from "@github/copilot-sdk"; - -// Default: uses logged-in user credentials -const client = new CopilotClient(); \ No newline at end of file diff --git a/docs/.validation/typescript/index_82.ts b/docs/.validation/typescript/index_82.ts deleted file mode 100644 index 6023c8df..00000000 --- a/docs/.validation/typescript/index_82.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Source: auth/index.md:94 -import { CopilotClient } from "@github/copilot-sdk"; - -const client = new CopilotClient({ - githubToken: userAccessToken, // Token from OAuth flow - useLoggedInUser: false, // Don't use stored CLI credentials -}); \ No newline at end of file diff --git a/docs/.validation/typescript/index_83.ts b/docs/.validation/typescript/index_83.ts deleted file mode 100644 index a4f9e1ab..00000000 --- a/docs/.validation/typescript/index_83.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Source: auth/index.md:183 -import { CopilotClient } from "@github/copilot-sdk"; - -// Token is read from environment variable automatically -const client = new CopilotClient(); \ No newline at end of file diff --git a/docs/.validation/typescript/index_84.ts b/docs/.validation/typescript/index_84.ts deleted file mode 100644 index 929e35f1..00000000 --- a/docs/.validation/typescript/index_84.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Source: auth/index.md:245 -const client = new CopilotClient({ - useLoggedInUser: false, // Only use explicit tokens -}); \ No newline at end of file diff --git a/docs/.validation/typescript/overview_18.ts b/docs/.validation/typescript/overview_18.ts deleted file mode 100644 index 3f1d02e5..00000000 --- a/docs/.validation/typescript/overview_18.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Source: mcp/overview.md:30 -import { CopilotClient } from "@github/copilot-sdk"; - -const client = new CopilotClient(); -const session = await client.createSession({ - model: "gpt-5", - mcpServers: { - // Local MCP server (stdio) - "my-local-server": { - type: "local", - command: "node", - args: ["./mcp-server.js"], - env: { DEBUG: "true" }, - cwd: "./servers", - tools: ["*"], // "*" = all tools, [] = none, or list specific tools - timeout: 30000, - }, - // Remote MCP server (HTTP) - "github": { - type: "http", - url: "https://api.githubcopilot.com/mcp/", - headers: { "Authorization": "Bearer ${TOKEN}" }, - tools: ["*"], - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/overview_19.ts b/docs/.validation/typescript/overview_19.ts deleted file mode 100644 index f2a09bc2..00000000 --- a/docs/.validation/typescript/overview_19.ts +++ /dev/null @@ -1,32 +0,0 @@ -// Source: mcp/overview.md:167 -import { CopilotClient } from "@github/copilot-sdk"; - -async function main() { - const client = new CopilotClient(); - - // Create session with filesystem MCP server - const session = await client.createSession({ - mcpServers: { - filesystem: { - type: "local", - command: "npx", - args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"], - tools: ["*"], - }, - }, - }); - - console.log("Session created:", session.sessionId); - - // The model can now use filesystem tools - const result = await session.sendAndWait({ - prompt: "List the files in the allowed directory", - }); - - console.log("Response:", result?.data?.content); - - await session.destroy(); - await client.stop(); -} - -main(); \ No newline at end of file diff --git a/docs/.validation/typescript/overview_53.ts b/docs/.validation/typescript/overview_53.ts deleted file mode 100644 index 85c61fd8..00000000 --- a/docs/.validation/typescript/overview_53.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Source: hooks/overview.md:27 -import { CopilotClient } from "@github/copilot-sdk"; - -const client = new CopilotClient(); - -const session = await client.createSession({ - hooks: { - onPreToolUse: async (input) => { - console.log(`Tool called: ${input.toolName}`); - // Allow all tools - return { permissionDecision: "allow" }; - }, - onPostToolUse: async (input) => { - console.log(`Tool result: ${JSON.stringify(input.toolResult)}`); - return null; // No modifications - }, - onSessionStart: async (input) => { - return { additionalContext: "User prefers concise answers." }; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/overview_54.ts b/docs/.validation/typescript/overview_54.ts deleted file mode 100644 index b69196b4..00000000 --- a/docs/.validation/typescript/overview_54.ts +++ /dev/null @@ -1,13 +0,0 @@ -// Source: hooks/overview.md:174 -const session = await client.createSession({ - hooks: { - onPreToolUse: async (input) => { - console.log(`[${new Date().toISOString()}] Tool: ${input.toolName}, Args: ${JSON.stringify(input.toolArgs)}`); - return { permissionDecision: "allow" }; - }, - onPostToolUse: async (input) => { - console.log(`[${new Date().toISOString()}] Result: ${JSON.stringify(input.toolResult)}`); - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/overview_55.ts b/docs/.validation/typescript/overview_55.ts deleted file mode 100644 index 9e69489d..00000000 --- a/docs/.validation/typescript/overview_55.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Source: hooks/overview.md:191 -const BLOCKED_TOOLS = ["shell", "bash", "exec"]; - -const session = await client.createSession({ - hooks: { - onPreToolUse: async (input) => { - if (BLOCKED_TOOLS.includes(input.toolName)) { - return { - permissionDecision: "deny", - permissionDecisionReason: "Shell access is not permitted", - }; - } - return { permissionDecision: "allow" }; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/overview_56.ts b/docs/.validation/typescript/overview_56.ts deleted file mode 100644 index 78fd4a32..00000000 --- a/docs/.validation/typescript/overview_56.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Source: hooks/overview.md:211 -const session = await client.createSession({ - hooks: { - onSessionStart: async () => { - const userPrefs = await loadUserPreferences(); - return { - additionalContext: `User preferences: ${JSON.stringify(userPrefs)}`, - }; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_45.ts b/docs/.validation/typescript/post-tool-use_45.ts deleted file mode 100644 index face85d3..00000000 --- a/docs/.validation/typescript/post-tool-use_45.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Source: hooks/post-tool-use.md:15 -type PostToolUseHandler = ( - input: PostToolUseHookInput, - invocation: HookInvocation -) => Promise; \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_46.ts b/docs/.validation/typescript/post-tool-use_46.ts deleted file mode 100644 index 338cb1f4..00000000 --- a/docs/.validation/typescript/post-tool-use_46.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Source: hooks/post-tool-use.md:87 -const session = await client.createSession({ - hooks: { - onPostToolUse: async (input, invocation) => { - console.log(`[${invocation.sessionId}] Tool: ${input.toolName}`); - console.log(` Args: ${JSON.stringify(input.toolArgs)}`); - console.log(` Result: ${JSON.stringify(input.toolResult)}`); - return null; // Pass through unchanged - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_47.ts b/docs/.validation/typescript/post-tool-use_47.ts deleted file mode 100644 index 99774d3f..00000000 --- a/docs/.validation/typescript/post-tool-use_47.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Source: hooks/post-tool-use.md:161 -const SENSITIVE_PATTERNS = [ - /api[_-]?key["\s:=]+["']?[\w-]+["']?/gi, - /password["\s:=]+["']?[\w-]+["']?/gi, - /secret["\s:=]+["']?[\w-]+["']?/gi, -]; - -const session = await client.createSession({ - hooks: { - onPostToolUse: async (input) => { - if (typeof input.toolResult === "string") { - let redacted = input.toolResult; - for (const pattern of SENSITIVE_PATTERNS) { - redacted = redacted.replace(pattern, "[REDACTED]"); - } - - if (redacted !== input.toolResult) { - return { modifiedResult: redacted }; - } - } - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_48.ts b/docs/.validation/typescript/post-tool-use_48.ts deleted file mode 100644 index dac41628..00000000 --- a/docs/.validation/typescript/post-tool-use_48.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Source: hooks/post-tool-use.md:189 -const MAX_RESULT_LENGTH = 10000; - -const session = await client.createSession({ - hooks: { - onPostToolUse: async (input) => { - const resultStr = JSON.stringify(input.toolResult); - - if (resultStr.length > MAX_RESULT_LENGTH) { - return { - modifiedResult: { - truncated: true, - originalLength: resultStr.length, - content: resultStr.substring(0, MAX_RESULT_LENGTH) + "...", - }, - additionalContext: `Note: Result was truncated from ${resultStr.length} to ${MAX_RESULT_LENGTH} characters.`, - }; - } - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_49.ts b/docs/.validation/typescript/post-tool-use_49.ts deleted file mode 100644 index fd4b6cdc..00000000 --- a/docs/.validation/typescript/post-tool-use_49.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Source: hooks/post-tool-use.md:215 -const session = await client.createSession({ - hooks: { - onPostToolUse: async (input) => { - // If a file read returned an error, add helpful context - if (input.toolName === "read_file" && input.toolResult?.error) { - return { - additionalContext: "Tip: If the file doesn't exist, consider creating it or checking the path.", - }; - } - - // If shell command failed, add debugging hint - if (input.toolName === "shell" && input.toolResult?.exitCode !== 0) { - return { - additionalContext: "The command failed. Check if required dependencies are installed.", - }; - } - - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_50.ts b/docs/.validation/typescript/post-tool-use_50.ts deleted file mode 100644 index 68191840..00000000 --- a/docs/.validation/typescript/post-tool-use_50.ts +++ /dev/null @@ -1,18 +0,0 @@ -// Source: hooks/post-tool-use.md:241 -const session = await client.createSession({ - hooks: { - onPostToolUse: async (input) => { - if (input.toolResult?.error && input.toolResult?.stack) { - // Remove internal stack trace details - return { - modifiedResult: { - error: input.toolResult.error, - // Keep only first 3 lines of stack - stack: input.toolResult.stack.split("\n").slice(0, 3).join("\n"), - }, - }; - } - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_51.ts b/docs/.validation/typescript/post-tool-use_51.ts deleted file mode 100644 index 8a504df5..00000000 --- a/docs/.validation/typescript/post-tool-use_51.ts +++ /dev/null @@ -1,31 +0,0 @@ -// Source: hooks/post-tool-use.md:263 -interface AuditEntry { - timestamp: number; - sessionId: string; - toolName: string; - args: unknown; - result: unknown; - success: boolean; -} - -const auditLog: AuditEntry[] = []; - -const session = await client.createSession({ - hooks: { - onPostToolUse: async (input, invocation) => { - auditLog.push({ - timestamp: input.timestamp, - sessionId: invocation.sessionId, - toolName: input.toolName, - args: input.toolArgs, - result: input.toolResult, - success: !input.toolResult?.error, - }); - - // Optionally persist to database/file - await saveAuditLog(auditLog); - - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/post-tool-use_52.ts b/docs/.validation/typescript/post-tool-use_52.ts deleted file mode 100644 index bf2737a1..00000000 --- a/docs/.validation/typescript/post-tool-use_52.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Source: hooks/post-tool-use.md:298 -const NOISY_TOOLS = ["list_directory", "search_codebase"]; - -const session = await client.createSession({ - hooks: { - onPostToolUse: async (input) => { - if (NOISY_TOOLS.includes(input.toolName)) { - // Summarize instead of showing full result - const items = Array.isArray(input.toolResult) - ? input.toolResult - : input.toolResult?.items || []; - - return { - modifiedResult: { - summary: `Found ${items.length} items`, - firstFew: items.slice(0, 5), - }, - }; - } - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_38.ts b/docs/.validation/typescript/pre-tool-use_38.ts deleted file mode 100644 index 5b185598..00000000 --- a/docs/.validation/typescript/pre-tool-use_38.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Source: hooks/pre-tool-use.md:15 -type PreToolUseHandler = ( - input: PreToolUseHookInput, - invocation: HookInvocation -) => Promise; \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_39.ts b/docs/.validation/typescript/pre-tool-use_39.ts deleted file mode 100644 index 3d18fcc4..00000000 --- a/docs/.validation/typescript/pre-tool-use_39.ts +++ /dev/null @@ -1,10 +0,0 @@ -// Source: hooks/pre-tool-use.md:96 -const session = await client.createSession({ - hooks: { - onPreToolUse: async (input, invocation) => { - console.log(`[${invocation.sessionId}] Calling ${input.toolName}`); - console.log(` Args: ${JSON.stringify(input.toolArgs)}`); - return { permissionDecision: "allow" }; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_40.ts b/docs/.validation/typescript/pre-tool-use_40.ts deleted file mode 100644 index 68d9ccba..00000000 --- a/docs/.validation/typescript/pre-tool-use_40.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Source: hooks/pre-tool-use.md:170 -const BLOCKED_TOOLS = ["shell", "bash", "write_file", "delete_file"]; - -const session = await client.createSession({ - hooks: { - onPreToolUse: async (input) => { - if (BLOCKED_TOOLS.includes(input.toolName)) { - return { - permissionDecision: "deny", - permissionDecisionReason: `Tool '${input.toolName}' is not permitted in this environment`, - }; - } - return { permissionDecision: "allow" }; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_41.ts b/docs/.validation/typescript/pre-tool-use_41.ts deleted file mode 100644 index 9627d149..00000000 --- a/docs/.validation/typescript/pre-tool-use_41.ts +++ /dev/null @@ -1,19 +0,0 @@ -// Source: hooks/pre-tool-use.md:190 -const session = await client.createSession({ - hooks: { - onPreToolUse: async (input) => { - // Add a default timeout to all shell commands - if (input.toolName === "shell" && input.toolArgs) { - const args = input.toolArgs as { command: string; timeout?: number }; - return { - permissionDecision: "allow", - modifiedArgs: { - ...args, - timeout: args.timeout ?? 30000, // Default 30s timeout - }, - }; - } - return { permissionDecision: "allow" }; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_42.ts b/docs/.validation/typescript/pre-tool-use_42.ts deleted file mode 100644 index 5ead8f9c..00000000 --- a/docs/.validation/typescript/pre-tool-use_42.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Source: hooks/pre-tool-use.md:213 -const ALLOWED_DIRECTORIES = ["/home/user/projects", "/tmp"]; - -const session = await client.createSession({ - hooks: { - onPreToolUse: async (input) => { - if (input.toolName === "read_file" || input.toolName === "write_file") { - const args = input.toolArgs as { path: string }; - const isAllowed = ALLOWED_DIRECTORIES.some(dir => - args.path.startsWith(dir) - ); - - if (!isAllowed) { - return { - permissionDecision: "deny", - permissionDecisionReason: `Access to '${args.path}' is not permitted. Allowed directories: ${ALLOWED_DIRECTORIES.join(", ")}`, - }; - } - } - return { permissionDecision: "allow" }; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_43.ts b/docs/.validation/typescript/pre-tool-use_43.ts deleted file mode 100644 index 4ce2f562..00000000 --- a/docs/.validation/typescript/pre-tool-use_43.ts +++ /dev/null @@ -1,13 +0,0 @@ -// Source: hooks/pre-tool-use.md:240 -const VERBOSE_TOOLS = ["list_directory", "search_files"]; - -const session = await client.createSession({ - hooks: { - onPreToolUse: async (input) => { - return { - permissionDecision: "allow", - suppressOutput: VERBOSE_TOOLS.includes(input.toolName), - }; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/pre-tool-use_44.ts b/docs/.validation/typescript/pre-tool-use_44.ts deleted file mode 100644 index 005d8ad6..00000000 --- a/docs/.validation/typescript/pre-tool-use_44.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Source: hooks/pre-tool-use.md:257 -const session = await client.createSession({ - hooks: { - onPreToolUse: async (input) => { - if (input.toolName === "query_database") { - return { - permissionDecision: "allow", - additionalContext: "Remember: This database uses PostgreSQL syntax. Always use parameterized queries.", - }; - } - return { permissionDecision: "allow" }; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_29.ts b/docs/.validation/typescript/session-lifecycle_29.ts deleted file mode 100644 index d6e6688a..00000000 --- a/docs/.validation/typescript/session-lifecycle_29.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Source: hooks/session-lifecycle.md:19 -type SessionStartHandler = ( - input: SessionStartHookInput, - invocation: HookInvocation -) => Promise; \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_30.ts b/docs/.validation/typescript/session-lifecycle_30.ts deleted file mode 100644 index 3e416c4c..00000000 --- a/docs/.validation/typescript/session-lifecycle_30.ts +++ /dev/null @@ -1,18 +0,0 @@ -// Source: hooks/session-lifecycle.md:87 -const session = await client.createSession({ - hooks: { - onSessionStart: async (input, invocation) => { - console.log(`Session ${invocation.sessionId} started (${input.source})`); - - const projectInfo = await detectProjectType(input.cwd); - - return { - additionalContext: ` -This is a ${projectInfo.type} project. -Main language: ${projectInfo.language} -Package manager: ${projectInfo.packageManager} - `.trim(), - }; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_31.ts b/docs/.validation/typescript/session-lifecycle_31.ts deleted file mode 100644 index 7072a436..00000000 --- a/docs/.validation/typescript/session-lifecycle_31.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Source: hooks/session-lifecycle.md:135 -const session = await client.createSession({ - hooks: { - onSessionStart: async (input, invocation) => { - if (input.source === "resume") { - // Load previous session state - const previousState = await loadSessionState(invocation.sessionId); - - return { - additionalContext: ` -Session resumed. Previous context: -- Last topic: ${previousState.lastTopic} -- Open files: ${previousState.openFiles.join(", ")} - `.trim(), - }; - } - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_32.ts b/docs/.validation/typescript/session-lifecycle_32.ts deleted file mode 100644 index dd32855e..00000000 --- a/docs/.validation/typescript/session-lifecycle_32.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Source: hooks/session-lifecycle.md:159 -const session = await client.createSession({ - hooks: { - onSessionStart: async () => { - const preferences = await loadUserPreferences(); - - const contextParts = []; - - if (preferences.language) { - contextParts.push(`Preferred language: ${preferences.language}`); - } - if (preferences.codeStyle) { - contextParts.push(`Code style: ${preferences.codeStyle}`); - } - if (preferences.verbosity === "concise") { - contextParts.push("Keep responses brief and to the point."); - } - - return { - additionalContext: contextParts.join("\n"), - }; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_33.ts b/docs/.validation/typescript/session-lifecycle_33.ts deleted file mode 100644 index 1c5d136a..00000000 --- a/docs/.validation/typescript/session-lifecycle_33.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Source: hooks/session-lifecycle.md:196 -type SessionEndHandler = ( - input: SessionEndHookInput, - invocation: HookInvocation -) => Promise; \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_34.ts b/docs/.validation/typescript/session-lifecycle_34.ts deleted file mode 100644 index 910071d9..00000000 --- a/docs/.validation/typescript/session-lifecycle_34.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Source: hooks/session-lifecycle.md:276 -const sessionStartTimes = new Map(); - -const session = await client.createSession({ - hooks: { - onSessionStart: async (input, invocation) => { - sessionStartTimes.set(invocation.sessionId, input.timestamp); - return null; - }, - onSessionEnd: async (input, invocation) => { - const startTime = sessionStartTimes.get(invocation.sessionId); - const duration = startTime ? input.timestamp - startTime : 0; - - await recordMetrics({ - sessionId: invocation.sessionId, - duration, - endReason: input.reason, - }); - - sessionStartTimes.delete(invocation.sessionId); - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_35.ts b/docs/.validation/typescript/session-lifecycle_35.ts deleted file mode 100644 index 689c910d..00000000 --- a/docs/.validation/typescript/session-lifecycle_35.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Source: hooks/session-lifecycle.md:339 -const sessionResources = new Map(); - -const session = await client.createSession({ - hooks: { - onSessionStart: async (input, invocation) => { - sessionResources.set(invocation.sessionId, { tempFiles: [] }); - return null; - }, - onSessionEnd: async (input, invocation) => { - const resources = sessionResources.get(invocation.sessionId); - - if (resources) { - // Clean up temp files - for (const file of resources.tempFiles) { - await fs.unlink(file).catch(() => {}); - } - sessionResources.delete(invocation.sessionId); - } - - console.log(`Session ${invocation.sessionId} ended: ${input.reason}`); - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_36.ts b/docs/.validation/typescript/session-lifecycle_36.ts deleted file mode 100644 index d8fe6d8b..00000000 --- a/docs/.validation/typescript/session-lifecycle_36.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Source: hooks/session-lifecycle.md:368 -const session = await client.createSession({ - hooks: { - onSessionEnd: async (input, invocation) => { - if (input.reason !== "error") { - // Save state for potential resume - await saveSessionState(invocation.sessionId, { - endTime: input.timestamp, - cwd: input.cwd, - reason: input.reason, - }); - } - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-lifecycle_37.ts b/docs/.validation/typescript/session-lifecycle_37.ts deleted file mode 100644 index ee628dcf..00000000 --- a/docs/.validation/typescript/session-lifecycle_37.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Source: hooks/session-lifecycle.md:388 -const sessionData: Record = {}; - -const session = await client.createSession({ - hooks: { - onSessionStart: async (input, invocation) => { - sessionData[invocation.sessionId] = { - prompts: 0, - tools: 0, - startTime: input.timestamp - }; - return null; - }, - onUserPromptSubmitted: async (_, invocation) => { - sessionData[invocation.sessionId].prompts++; - return null; - }, - onPreToolUse: async (_, invocation) => { - sessionData[invocation.sessionId].tools++; - return { permissionDecision: "allow" }; - }, - onSessionEnd: async (input, invocation) => { - const data = sessionData[invocation.sessionId]; - console.log(` -Session Summary: - ID: ${invocation.sessionId} - Duration: ${(input.timestamp - data.startTime) / 1000}s - Prompts: ${data.prompts} - Tool calls: ${data.tools} - End reason: ${input.reason} - `.trim()); - - delete sessionData[invocation.sessionId]; - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_70.ts b/docs/.validation/typescript/session-persistence_70.ts deleted file mode 100644 index f652780e..00000000 --- a/docs/.validation/typescript/session-persistence_70.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Source: guides/session-persistence.md:28 -import { CopilotClient } from "@github/copilot-sdk"; - -const client = new CopilotClient(); - -// Create a session with a meaningful ID -const session = await client.createSession({ - sessionId: "user-123-task-456", - model: "gpt-5.2-codex", -}); - -// Do some work... -await session.sendAndWait({ prompt: "Analyze my codebase" }); - -// Session state is automatically persisted -// You can safely close the client \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_71.ts b/docs/.validation/typescript/session-persistence_71.ts deleted file mode 100644 index b19acb83..00000000 --- a/docs/.validation/typescript/session-persistence_71.ts +++ /dev/null @@ -1,6 +0,0 @@ -// Source: guides/session-persistence.md:125 -// Resume from a different client instance (or after restart) -const session = await client.resumeSession("user-123-task-456"); - -// Continue where you left off -await session.sendAndWait({ prompt: "What did we discuss earlier?" }); \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_72.ts b/docs/.validation/typescript/session-persistence_72.ts deleted file mode 100644 index 8b2d1dbd..00000000 --- a/docs/.validation/typescript/session-persistence_72.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Source: guides/session-persistence.md:170 -// Original session with BYOK -const session = await client.createSession({ - sessionId: "user-123-task-456", - model: "gpt-5.2-codex", - provider: { - type: "azure", - endpoint: "https://my-resource.openai.azure.com", - apiKey: process.env.AZURE_OPENAI_KEY, - deploymentId: "my-gpt-deployment", - }, -}); - -// When resuming, you MUST re-provide the provider config -const resumed = await client.resumeSession("user-123-task-456", { - provider: { - type: "azure", - endpoint: "https://my-resource.openai.azure.com", - apiKey: process.env.AZURE_OPENAI_KEY, // Required again - deploymentId: "my-gpt-deployment", - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_73.ts b/docs/.validation/typescript/session-persistence_73.ts deleted file mode 100644 index 57141bbf..00000000 --- a/docs/.validation/typescript/session-persistence_73.ts +++ /dev/null @@ -1,8 +0,0 @@ -// Source: guides/session-persistence.md:238 -function createSessionId(userId: string, taskType: string): string { - const timestamp = Date.now(); - return `${userId}-${taskType}-${timestamp}`; -} - -const sessionId = createSessionId("alice", "code-review"); -// → "alice-code-review-1706932800000" \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_74.ts b/docs/.validation/typescript/session-persistence_74.ts deleted file mode 100644 index fede2a9e..00000000 --- a/docs/.validation/typescript/session-persistence_74.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Source: guides/session-persistence.md:263 -const sessions = await client.listSessions(); -console.log(`Found ${sessions.length} sessions`); - -for (const session of sessions) { - console.log(`- ${session.sessionId} (created: ${session.createdAt})`); -} \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_75.ts b/docs/.validation/typescript/session-persistence_75.ts deleted file mode 100644 index 64766a53..00000000 --- a/docs/.validation/typescript/session-persistence_75.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Source: guides/session-persistence.md:274 -async function cleanupExpiredSessions(maxAgeMs: number) { - const sessions = await client.listSessions(); - const now = Date.now(); - - for (const session of sessions) { - const age = now - new Date(session.createdAt).getTime(); - if (age > maxAgeMs) { - await client.deleteSession(session.sessionId); - console.log(`Deleted expired session: ${session.sessionId}`); - } - } -} - -// Clean up sessions older than 24 hours -await cleanupExpiredSessions(24 * 60 * 60 * 1000); \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_76.ts b/docs/.validation/typescript/session-persistence_76.ts deleted file mode 100644 index 8ed1b832..00000000 --- a/docs/.validation/typescript/session-persistence_76.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Source: guides/session-persistence.md:296 -try { - // Do work... - await session.sendAndWait({ prompt: "Complete the task" }); - - // Task complete - clean up - await session.destroy(); -} catch (error) { - // Clean up even on error - await session.destroy(); - throw error; -} \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_77.ts b/docs/.validation/typescript/session-persistence_77.ts deleted file mode 100644 index 92216451..00000000 --- a/docs/.validation/typescript/session-persistence_77.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Source: guides/session-persistence.md:321 -session.on("session.idle", (event) => { - console.log(`Session idle for ${event.idleDurationMs}ms`); -}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_78.ts b/docs/.validation/typescript/session-persistence_78.ts deleted file mode 100644 index bd5b5496..00000000 --- a/docs/.validation/typescript/session-persistence_78.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Source: guides/session-persistence.md:366 -// Application-level access control for shared CLI -async function resumeSessionWithAuth( - client: CopilotClient, - sessionId: string, - currentUserId: string -): Promise { - // Parse user from session ID - const [sessionUserId] = sessionId.split("-"); - - if (sessionUserId !== currentUserId) { - throw new Error("Access denied: session belongs to another user"); - } - - return client.resumeSession(sessionId); -} \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_79.ts b/docs/.validation/typescript/session-persistence_79.ts deleted file mode 100644 index 874e5a10..00000000 --- a/docs/.validation/typescript/session-persistence_79.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Source: guides/session-persistence.md:428 -const session = await client.createSession({ - sessionId: "long-workflow-123", - infiniteSessions: { - enabled: true, - backgroundCompactionThreshold: 0.80, // Start compaction at 80% context - bufferExhaustionThreshold: 0.95, // Block at 95% if needed - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/session-persistence_80.ts b/docs/.validation/typescript/session-persistence_80.ts deleted file mode 100644 index 3bf30312..00000000 --- a/docs/.validation/typescript/session-persistence_80.ts +++ /dev/null @@ -1,29 +0,0 @@ -// Source: guides/session-persistence.md:454 -// Option 1: Application-level locking with Redis -import Redis from "ioredis"; - -const redis = new Redis(); - -async function withSessionLock( - sessionId: string, - fn: () => Promise -): Promise { - const lockKey = `session-lock:${sessionId}`; - const acquired = await redis.set(lockKey, "locked", "NX", "EX", 300); - - if (!acquired) { - throw new Error("Session is in use by another client"); - } - - try { - return await fn(); - } finally { - await redis.del(lockKey); - } -} - -// Usage -await withSessionLock("user-123-task-456", async () => { - const session = await client.resumeSession("user-123-task-456"); - await session.sendAndWait({ prompt: "Continue the task" }); -}); \ No newline at end of file diff --git a/docs/.validation/typescript/skills_66.ts b/docs/.validation/typescript/skills_66.ts deleted file mode 100644 index 98aec20c..00000000 --- a/docs/.validation/typescript/skills_66.ts +++ /dev/null @@ -1,15 +0,0 @@ -// Source: guides/skills.md:25 -import { CopilotClient } from "@github/copilot-sdk"; - -const client = new CopilotClient(); -const session = await client.createSession({ - model: "gpt-4.1", - skillDirectories: [ - "./skills/code-review", - "./skills/documentation", - "~/.copilot/skills", // User-level skills - ], -}); - -// Copilot now has access to skills in those directories -await session.sendAndWait({ prompt: "Review this code for security issues" }); \ No newline at end of file diff --git a/docs/.validation/typescript/skills_67.ts b/docs/.validation/typescript/skills_67.ts deleted file mode 100644 index 0d2e9861..00000000 --- a/docs/.validation/typescript/skills_67.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Source: guides/skills.md:149 -const session = await client.createSession({ - skillDirectories: ["./skills"], - disabledSkills: ["experimental-feature", "deprecated-tool"], -}); \ No newline at end of file diff --git a/docs/.validation/typescript/skills_68.ts b/docs/.validation/typescript/skills_68.ts deleted file mode 100644 index eb452d1b..00000000 --- a/docs/.validation/typescript/skills_68.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Source: guides/skills.md:278 -const session = await client.createSession({ - skillDirectories: ["./skills/security"], - customAgents: [{ - name: "security-auditor", - description: "Security-focused code reviewer", - prompt: "Focus on OWASP Top 10 vulnerabilities", - }], -}); \ No newline at end of file diff --git a/docs/.validation/typescript/skills_69.ts b/docs/.validation/typescript/skills_69.ts deleted file mode 100644 index dcb81878..00000000 --- a/docs/.validation/typescript/skills_69.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Source: guides/skills.md:293 -const session = await client.createSession({ - skillDirectories: ["./skills/database"], - mcpServers: { - postgres: { - type: "local", - command: "npx", - args: ["-y", "@modelcontextprotocol/server-postgres"], - tools: ["*"], - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/tsconfig.json b/docs/.validation/typescript/tsconfig.json deleted file mode 100644 index cb428310..00000000 --- a/docs/.validation/typescript/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2022", - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true, - "skipLibCheck": true, - "noEmit": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "resolveJsonModule": true, - "types": [ - "node" - ], - "paths": { - "@github/copilot-sdk": [ - "/Users/patrick/projects/copilot-sdk/nodejs/src/index.ts" - ] - } - }, - "include": [ - "./**/*.ts" - ] -} \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_20.ts b/docs/.validation/typescript/user-prompt-submitted_20.ts deleted file mode 100644 index 668ce7ad..00000000 --- a/docs/.validation/typescript/user-prompt-submitted_20.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Source: hooks/user-prompt-submitted.md:15 -type UserPromptSubmittedHandler = ( - input: UserPromptSubmittedHookInput, - invocation: HookInvocation -) => Promise; \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_21.ts b/docs/.validation/typescript/user-prompt-submitted_21.ts deleted file mode 100644 index b895ff0e..00000000 --- a/docs/.validation/typescript/user-prompt-submitted_21.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Source: hooks/user-prompt-submitted.md:85 -const session = await client.createSession({ - hooks: { - onUserPromptSubmitted: async (input, invocation) => { - console.log(`[${invocation.sessionId}] User: ${input.prompt}`); - return null; // Pass through unchanged - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_22.ts b/docs/.validation/typescript/user-prompt-submitted_22.ts deleted file mode 100644 index f375bab3..00000000 --- a/docs/.validation/typescript/user-prompt-submitted_22.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Source: hooks/user-prompt-submitted.md:151 -const session = await client.createSession({ - hooks: { - onUserPromptSubmitted: async (input) => { - const projectInfo = await getProjectInfo(); - - return { - additionalContext: ` -Project: ${projectInfo.name} -Language: ${projectInfo.language} -Framework: ${projectInfo.framework} - `.trim(), - }; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_23.ts b/docs/.validation/typescript/user-prompt-submitted_23.ts deleted file mode 100644 index 800f8d23..00000000 --- a/docs/.validation/typescript/user-prompt-submitted_23.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Source: hooks/user-prompt-submitted.md:171 -const SHORTCUTS: Record = { - "/fix": "Please fix the errors in the code", - "/explain": "Please explain this code in detail", - "/test": "Please write unit tests for this code", - "/refactor": "Please refactor this code to improve readability and maintainability", -}; - -const session = await client.createSession({ - hooks: { - onUserPromptSubmitted: async (input) => { - for (const [shortcut, expansion] of Object.entries(SHORTCUTS)) { - if (input.prompt.startsWith(shortcut)) { - const rest = input.prompt.slice(shortcut.length).trim(); - return { - modifiedPrompt: `${expansion}${rest ? `: ${rest}` : ""}`, - }; - } - } - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_24.ts b/docs/.validation/typescript/user-prompt-submitted_24.ts deleted file mode 100644 index d8c1cd69..00000000 --- a/docs/.validation/typescript/user-prompt-submitted_24.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Source: hooks/user-prompt-submitted.md:198 -const BLOCKED_PATTERNS = [ - /password\s*[:=]/i, - /api[_-]?key\s*[:=]/i, - /secret\s*[:=]/i, -]; - -const session = await client.createSession({ - hooks: { - onUserPromptSubmitted: async (input) => { - for (const pattern of BLOCKED_PATTERNS) { - if (pattern.test(input.prompt)) { - // Replace the prompt with a warning message - return { - modifiedPrompt: "[Content blocked: Please don't include sensitive credentials in your prompts. Use environment variables instead.]", - suppressOutput: true, - }; - } - } - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_25.ts b/docs/.validation/typescript/user-prompt-submitted_25.ts deleted file mode 100644 index 1fe0a560..00000000 --- a/docs/.validation/typescript/user-prompt-submitted_25.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Source: hooks/user-prompt-submitted.md:225 -const MAX_PROMPT_LENGTH = 10000; - -const session = await client.createSession({ - hooks: { - onUserPromptSubmitted: async (input) => { - if (input.prompt.length > MAX_PROMPT_LENGTH) { - // Truncate the prompt and add context - return { - modifiedPrompt: input.prompt.substring(0, MAX_PROMPT_LENGTH), - additionalContext: `Note: The original prompt was ${input.prompt.length} characters and was truncated to ${MAX_PROMPT_LENGTH} characters.`, - }; - } - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_26.ts b/docs/.validation/typescript/user-prompt-submitted_26.ts deleted file mode 100644 index a89b2b71..00000000 --- a/docs/.validation/typescript/user-prompt-submitted_26.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Source: hooks/user-prompt-submitted.md:246 -interface UserPreferences { - codeStyle: "concise" | "verbose"; - preferredLanguage: string; - experienceLevel: "beginner" | "intermediate" | "expert"; -} - -const session = await client.createSession({ - hooks: { - onUserPromptSubmitted: async (input) => { - const prefs: UserPreferences = await loadUserPreferences(); - - const contextParts = []; - - if (prefs.codeStyle === "concise") { - contextParts.push("User prefers concise code with minimal comments."); - } else { - contextParts.push("User prefers verbose code with detailed comments."); - } - - if (prefs.experienceLevel === "beginner") { - contextParts.push("Explain concepts in simple terms."); - } - - return { - additionalContext: contextParts.join(" "), - }; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_27.ts b/docs/.validation/typescript/user-prompt-submitted_27.ts deleted file mode 100644 index 2d2e93fb..00000000 --- a/docs/.validation/typescript/user-prompt-submitted_27.ts +++ /dev/null @@ -1,27 +0,0 @@ -// Source: hooks/user-prompt-submitted.md:280 -const promptTimestamps: number[] = []; -const RATE_LIMIT = 10; // prompts -const RATE_WINDOW = 60000; // 1 minute - -const session = await client.createSession({ - hooks: { - onUserPromptSubmitted: async (input) => { - const now = Date.now(); - - // Remove timestamps outside the window - while (promptTimestamps.length > 0 && promptTimestamps[0] < now - RATE_WINDOW) { - promptTimestamps.shift(); - } - - if (promptTimestamps.length >= RATE_LIMIT) { - return { - reject: true, - rejectReason: `Rate limit exceeded. Please wait before sending more prompts.`, - }; - } - - promptTimestamps.push(now); - return null; - }, - }, -}); \ No newline at end of file diff --git a/docs/.validation/typescript/user-prompt-submitted_28.ts b/docs/.validation/typescript/user-prompt-submitted_28.ts deleted file mode 100644 index 271d6feb..00000000 --- a/docs/.validation/typescript/user-prompt-submitted_28.ts +++ /dev/null @@ -1,32 +0,0 @@ -// Source: hooks/user-prompt-submitted.md:311 -const TEMPLATES: Record string> = { - "bug:": (desc) => `I found a bug: ${desc} - -Please help me: -1. Understand why this is happening -2. Suggest a fix -3. Explain how to prevent similar bugs`, - - "feature:": (desc) => `I want to implement this feature: ${desc} - -Please: -1. Outline the implementation approach -2. Identify potential challenges -3. Provide sample code`, -}; - -const session = await client.createSession({ - hooks: { - onUserPromptSubmitted: async (input) => { - for (const [prefix, template] of Object.entries(TEMPLATES)) { - if (input.prompt.toLowerCase().startsWith(prefix)) { - const args = input.prompt.slice(prefix.length).trim(); - return { - modifiedPrompt: template(args), - }; - } - } - return null; - }, - }, -}); \ No newline at end of file From f64f065fdc62dba11357454c67d0f6b19a0d146f Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 21:53:31 -0800 Subject: [PATCH 08/14] Add docs/.validation to gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..9ec30582 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ + +# Documentation validation output +docs/.validation/ From e9b9775c576d6e6a4c96e7056eff3b51531b01c6 Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 21:55:44 -0800 Subject: [PATCH 09/14] Update CreateSession call to include context parameter --- docs/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index 34caa7dd..247497b5 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1239,7 +1239,7 @@ if err := client.Start(ctx); err != nil { defer client.Stop() // Use the client normally -session, err := client.CreateSession() +session, err := client.CreateSession(ctx, nil) // ... ``` From 8830b9dc5ce5403158f07b326374500a033431db Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 21:58:35 -0800 Subject: [PATCH 10/14] Fix CI failures: add skip markers for type signatures and partial snippets - Add skip markers to Python type signature definitions (hooks) - Add skip markers to C# partial config snippets (mcp/debugging.md) - Add skip markers to Python snippets using undefined variables --- docs/auth/index.md | 1 + docs/getting-started.md | 1 + docs/hooks/error-handling.md | 1 + docs/hooks/post-tool-use.md | 1 + docs/hooks/pre-tool-use.md | 1 + docs/hooks/session-lifecycle.md | 2 ++ docs/hooks/user-prompt-submitted.md | 1 + docs/mcp/debugging.md | 2 ++ 8 files changed, 10 insertions(+) diff --git a/docs/auth/index.md b/docs/auth/index.md index c4befccf..ff193cfd 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -253,6 +253,7 @@ const client = new CopilotClient({

Python + ```python client = CopilotClient({ "use_logged_in_user": False, # Only use explicit tokens diff --git a/docs/getting-started.md b/docs/getting-started.md index 247497b5..5c5975d5 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -426,6 +426,7 @@ unsubscribeIdle();
Python + ```python # Subscribe to all events unsubscribe = session.on(lambda event: print(f"Event: {event.type}")) diff --git a/docs/hooks/error-handling.md b/docs/hooks/error-handling.md index f406626d..3fb98bb4 100644 --- a/docs/hooks/error-handling.md +++ b/docs/hooks/error-handling.md @@ -24,6 +24,7 @@ type ErrorOccurredHandler = (
Python + ```python ErrorOccurredHandler = Callable[ [ErrorOccurredHookInput, HookInvocation], diff --git a/docs/hooks/post-tool-use.md b/docs/hooks/post-tool-use.md index 06e1dd17..a740bd74 100644 --- a/docs/hooks/post-tool-use.md +++ b/docs/hooks/post-tool-use.md @@ -24,6 +24,7 @@ type PostToolUseHandler = (
Python + ```python PostToolUseHandler = Callable[ [PostToolUseHookInput, HookInvocation], diff --git a/docs/hooks/pre-tool-use.md b/docs/hooks/pre-tool-use.md index d0c9ceb1..80095222 100644 --- a/docs/hooks/pre-tool-use.md +++ b/docs/hooks/pre-tool-use.md @@ -24,6 +24,7 @@ type PreToolUseHandler = (
Python + ```python PreToolUseHandler = Callable[ [PreToolUseHookInput, HookInvocation], diff --git a/docs/hooks/session-lifecycle.md b/docs/hooks/session-lifecycle.md index dcfd9544..73a03a11 100644 --- a/docs/hooks/session-lifecycle.md +++ b/docs/hooks/session-lifecycle.md @@ -28,6 +28,7 @@ type SessionStartHandler = (
Python + ```python SessionStartHandler = Callable[ [SessionStartHookInput, HookInvocation], @@ -205,6 +206,7 @@ type SessionEndHandler = (
Python + ```python SessionEndHandler = Callable[ [SessionEndHookInput, HookInvocation], diff --git a/docs/hooks/user-prompt-submitted.md b/docs/hooks/user-prompt-submitted.md index 9b88e299..f162ec57 100644 --- a/docs/hooks/user-prompt-submitted.md +++ b/docs/hooks/user-prompt-submitted.md @@ -24,6 +24,7 @@ type UserPromptSubmittedHandler = (
Python + ```python UserPromptSubmittedHandler = Callable[ [UserPromptSubmittedHookInput, HookInvocation], diff --git a/docs/mcp/debugging.md b/docs/mcp/debugging.md index 9027616a..5ca51d1e 100644 --- a/docs/mcp/debugging.md +++ b/docs/mcp/debugging.md @@ -242,6 +242,7 @@ cd /expected/working/dir #### .NET Console Apps / Tools + ```csharp // Correct configuration for .NET exe ["my-dotnet-server"] = new McpLocalServerConfig @@ -266,6 +267,7 @@ cd /expected/working/dir #### NPX Commands + ```csharp // Windows needs cmd /c for npx ["filesystem"] = new McpLocalServerConfig From 6ca8a2cefdfd17d9ef73003a92bea9853ccf1e23 Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 21:59:52 -0800 Subject: [PATCH 11/14] Add GitHub Actions job summary for docs validation Shows a summary table in the PR with: - Pass/fail status per language - Total code blocks validated - Details of any failures --- scripts/docs-validation/validate.ts | 53 ++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/scripts/docs-validation/validate.ts b/scripts/docs-validation/validate.ts index 56db66ec..109430c8 100644 --- a/scripts/docs-validation/validate.ts +++ b/scripts/docs-validation/validate.ts @@ -354,13 +354,13 @@ async function validateCSharp(): Promise { return results; } -function printResults(results: ValidationResult[], language: string): number { +function printResults(results: ValidationResult[], language: string): { failed: number; passed: number; failures: ValidationResult[] } { const failed = results.filter((r) => !r.success); const passed = results.filter((r) => r.success); if (failed.length === 0) { console.log(` ✅ ${passed.length} files passed`); - return 0; + return { failed: 0, passed: passed.length, failures: [] }; } console.log(` ❌ ${failed.length} failed, ${passed.length} passed\n`); @@ -377,7 +377,46 @@ function printResults(results: ValidationResult[], language: string): number { console.log(` └─`); } - return failed.length; + return { failed: failed.length, passed: passed.length, failures: failed }; +} + +function writeGitHubSummary(summaryData: { language: string; passed: number; failed: number; failures: ValidationResult[] }[]) { + const summaryFile = process.env.GITHUB_STEP_SUMMARY; + if (!summaryFile) return; + + const totalPassed = summaryData.reduce((sum, d) => sum + d.passed, 0); + const totalFailed = summaryData.reduce((sum, d) => sum + d.failed, 0); + const allPassed = totalFailed === 0; + + let summary = `## 📖 Documentation Validation Results\n\n`; + + if (allPassed) { + summary += `✅ **All ${totalPassed} code blocks passed validation**\n\n`; + } else { + summary += `❌ **${totalFailed} failures** out of ${totalPassed + totalFailed} code blocks\n\n`; + } + + summary += `| Language | Status | Passed | Failed |\n`; + summary += `|----------|--------|--------|--------|\n`; + + for (const { language, passed, failed } of summaryData) { + const status = failed === 0 ? "✅" : "❌"; + summary += `| ${language} | ${status} | ${passed} | ${failed} |\n`; + } + + if (totalFailed > 0) { + summary += `\n### Failures\n\n`; + for (const { language, failures } of summaryData) { + if (failures.length === 0) continue; + summary += `#### ${language}\n\n`; + for (const f of failures) { + summary += `- **${f.sourceFile}:${f.sourceLine}**\n`; + summary += ` \`\`\`\n ${f.errors.slice(0, 3).join("\n ")}\n \`\`\`\n`; + } + } + } + + fs.appendFileSync(summaryFile, summary); } async function main() { @@ -394,6 +433,7 @@ async function main() { } let totalFailed = 0; + const summaryData: { language: string; passed: number; failed: number; failures: ValidationResult[] }[] = []; const validators: [string, () => Promise][] = [ ["TypeScript", validateTypeScript], @@ -408,9 +448,14 @@ async function main() { console.log(`\n${name}:`); const results = await validator(); - totalFailed += printResults(results, name); + const { failed, passed, failures } = printResults(results, name); + totalFailed += failed; + summaryData.push({ language: name, passed, failed, failures }); } + // Write GitHub Actions summary + writeGitHubSummary(summaryData); + console.log("\n" + "─".repeat(40)); if (totalFailed > 0) { From 52c4a6dc57dc414669d54fc14e854e10933d3a54 Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 22:09:23 -0800 Subject: [PATCH 12/14] Fix C# docs validation by wrapping code in classes The C# documentation validation was failing because: 1. Multiple files had top-level statements (C# only allows one per project) 2. Some snippets were missing the 'using GitHub.Copilot.SDK;' directive This fix: - Wraps C# code snippets without class/namespace in unique static classes - Preserves existing using directives and adds SDK using if missing - Detects async code (await keyword) and creates async Main methods - Skips wrapping for code that already has structure (classes, namespaces, delegates) --- scripts/docs-validation/extract.ts | 59 ++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/scripts/docs-validation/extract.ts b/scripts/docs-validation/extract.ts index a12099b9..2fc48d82 100644 --- a/scripts/docs-validation/extract.ts +++ b/scripts/docs-validation/extract.ts @@ -260,15 +260,68 @@ function wrapCodeForValidation(block: CodeBlock): string { } } - // C#: wrap in minimal structure if needed + // C#: wrap in a class to avoid top-level statements conflicts + // (C# only allows one file with top-level statements per project) if (block.language === "csharp") { // Check if it's a complete file (has namespace or class) const hasStructure = code.includes("namespace ") || code.includes("class ") || - code.includes("record "); + code.includes("record ") || + code.includes("public delegate "); + if (!hasStructure) { - // Top-level statements are fine in modern C#, just ensure usings are at top + // Extract any existing using statements + const lines = code.split("\n"); + const usings: string[] = []; + const rest: string[] = []; + + for (const line of lines) { + if (line.trim().startsWith("using ") && line.trim().endsWith(";")) { + usings.push(line); + } else { + rest.push(line); + } + } + + // Always ensure SDK using is present + if (!usings.some(u => u.includes("GitHub.Copilot.SDK"))) { + usings.push("using GitHub.Copilot.SDK;"); + } + + // Generate a unique class name based on block location + const className = `ValidationClass_${block.file.replace(/[^a-zA-Z0-9]/g, "_")}_${block.line}`; + + // Wrap in async method to support await + const hasAwait = code.includes("await "); + const indentedCode = rest.map(l => " " + l).join("\n"); + + if (hasAwait) { + code = `${usings.join("\n")} + +public static class ${className} +{ + public static async Task Main() + { +${indentedCode} + } +}`; + } else { + code = `${usings.join("\n")} + +public static class ${className} +{ + public static void Main() + { +${indentedCode} + } +}`; + } + } else { + // Has structure, but may still need using directive + if (!code.includes("using GitHub.Copilot.SDK;")) { + code = "using GitHub.Copilot.SDK;\n" + code; + } } } From d40b96261d38a53e1074b6943cb5cd84eae67dc1 Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 22:14:08 -0800 Subject: [PATCH 13/14] Add skip markers for docs validation in hook documentation --- docs/hooks/error-handling.md | 2 ++ docs/hooks/post-tool-use.md | 2 ++ docs/hooks/pre-tool-use.md | 2 ++ docs/hooks/session-lifecycle.md | 2 ++ docs/hooks/user-prompt-submitted.md | 2 ++ 5 files changed, 10 insertions(+) diff --git a/docs/hooks/error-handling.md b/docs/hooks/error-handling.md index 3fb98bb4..b7f5e4c1 100644 --- a/docs/hooks/error-handling.md +++ b/docs/hooks/error-handling.md @@ -12,6 +12,7 @@ The `onErrorOccurred` hook is called when errors occur during session execution.
Node.js / TypeScript + ```typescript type ErrorOccurredHandler = ( input: ErrorOccurredHookInput, @@ -50,6 +51,7 @@ type ErrorOccurredHandler func(
.NET + ```csharp public delegate Task ErrorOccurredHandler( ErrorOccurredHookInput input, diff --git a/docs/hooks/post-tool-use.md b/docs/hooks/post-tool-use.md index a740bd74..85aa9d5b 100644 --- a/docs/hooks/post-tool-use.md +++ b/docs/hooks/post-tool-use.md @@ -12,6 +12,7 @@ The `onPostToolUse` hook is called **after** a tool executes. Use it to:
Node.js / TypeScript + ```typescript type PostToolUseHandler = ( input: PostToolUseHookInput, @@ -50,6 +51,7 @@ type PostToolUseHandler func(
.NET + ```csharp public delegate Task PostToolUseHandler( PostToolUseHookInput input, diff --git a/docs/hooks/pre-tool-use.md b/docs/hooks/pre-tool-use.md index 80095222..10673261 100644 --- a/docs/hooks/pre-tool-use.md +++ b/docs/hooks/pre-tool-use.md @@ -12,6 +12,7 @@ The `onPreToolUse` hook is called **before** a tool executes. Use it to:
Node.js / TypeScript + ```typescript type PreToolUseHandler = ( input: PreToolUseHookInput, @@ -50,6 +51,7 @@ type PreToolUseHandler func(
.NET + ```csharp public delegate Task PreToolUseHandler( PreToolUseHookInput input, diff --git a/docs/hooks/session-lifecycle.md b/docs/hooks/session-lifecycle.md index 73a03a11..74f4666f 100644 --- a/docs/hooks/session-lifecycle.md +++ b/docs/hooks/session-lifecycle.md @@ -16,6 +16,7 @@ The `onSessionStart` hook is called when a session begins (new or resumed).
Node.js / TypeScript + ```typescript type SessionStartHandler = ( input: SessionStartHookInput, @@ -54,6 +55,7 @@ type SessionStartHandler func(
.NET + ```csharp public delegate Task SessionStartHandler( SessionStartHookInput input, diff --git a/docs/hooks/user-prompt-submitted.md b/docs/hooks/user-prompt-submitted.md index f162ec57..cf876df6 100644 --- a/docs/hooks/user-prompt-submitted.md +++ b/docs/hooks/user-prompt-submitted.md @@ -12,6 +12,7 @@ The `onUserPromptSubmitted` hook is called when a user submits a message. Use it
Node.js / TypeScript + ```typescript type UserPromptSubmittedHandler = ( input: UserPromptSubmittedHookInput, @@ -50,6 +51,7 @@ type UserPromptSubmittedHandler func(
.NET + ```csharp public delegate Task UserPromptSubmittedHandler( UserPromptSubmittedHookInput input, From e7cbab87b8469c84385ee696491528c81a134c1c Mon Sep 17 00:00:00 2001 From: Patrick Nikoletich Date: Tue, 3 Feb 2026 22:19:32 -0800 Subject: [PATCH 14/14] Add skip markers for partial C# code snippets These code snippets are intentionally partial - they show specific configurations assuming a 'client' or 'session' variable already exists. The validation cannot compile them standalone, so they're skipped. Also fixed mcp/overview.md to use List instead of string[] to match the actual SDK types. --- docs/auth/index.md | 1 + docs/debugging.md | 1 + docs/getting-started.md | 1 + docs/guides/session-persistence.md | 1 + docs/guides/skills.md | 1 + docs/hooks/error-handling.md | 1 + docs/hooks/post-tool-use.md | 1 + docs/hooks/pre-tool-use.md | 1 + docs/hooks/user-prompt-submitted.md | 1 + docs/mcp/overview.md | 4 ++-- 10 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/auth/index.md b/docs/auth/index.md index ff193cfd..9fc65fe2 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -135,6 +135,7 @@ client := copilot.NewClient(&copilot.ClientOptions{
.NET + ```csharp using GitHub.Copilot.SDK; diff --git a/docs/debugging.md b/docs/debugging.md index 6bb40d64..6183cccd 100644 --- a/docs/debugging.md +++ b/docs/debugging.md @@ -58,6 +58,7 @@ client := copilot.NewClient(&copilot.ClientOptions{
.NET + ```csharp using GitHub.Copilot.SDK; using Microsoft.Extensions.Logging; diff --git a/docs/getting-started.md b/docs/getting-started.md index 5c5975d5..f615e923 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -474,6 +474,7 @@ unsubscribe()
.NET + ```csharp // Subscribe to all events var unsubscribe = session.On(ev => Console.WriteLine($"Event: {ev.Type}")); diff --git a/docs/guides/session-persistence.md b/docs/guides/session-persistence.md index c1abb28f..7c16c53a 100644 --- a/docs/guides/session-persistence.md +++ b/docs/guides/session-persistence.md @@ -155,6 +155,7 @@ session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "What did we discuss ear ### C# (.NET) + ```csharp // Resume from a different client instance (or after restart) var session = await client.ResumeSessionAsync("user-123-task-456"); diff --git a/docs/guides/skills.md b/docs/guides/skills.md index 273ce97c..e17a6209 100644 --- a/docs/guides/skills.md +++ b/docs/guides/skills.md @@ -183,6 +183,7 @@ session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{
.NET + ```csharp var session = await client.CreateSessionAsync(new SessionConfig { diff --git a/docs/hooks/error-handling.md b/docs/hooks/error-handling.md index b7f5e4c1..0f705868 100644 --- a/docs/hooks/error-handling.md +++ b/docs/hooks/error-handling.md @@ -142,6 +142,7 @@ session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{
.NET + ```csharp var session = await client.CreateSessionAsync(new SessionConfig { diff --git a/docs/hooks/post-tool-use.md b/docs/hooks/post-tool-use.md index 85aa9d5b..0021e20a 100644 --- a/docs/hooks/post-tool-use.md +++ b/docs/hooks/post-tool-use.md @@ -141,6 +141,7 @@ session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{
.NET + ```csharp var session = await client.CreateSessionAsync(new SessionConfig { diff --git a/docs/hooks/pre-tool-use.md b/docs/hooks/pre-tool-use.md index 10673261..ac12df4f 100644 --- a/docs/hooks/pre-tool-use.md +++ b/docs/hooks/pre-tool-use.md @@ -149,6 +149,7 @@ session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{
.NET + ```csharp var session = await client.CreateSessionAsync(new SessionConfig { diff --git a/docs/hooks/user-prompt-submitted.md b/docs/hooks/user-prompt-submitted.md index cf876df6..3205b95c 100644 --- a/docs/hooks/user-prompt-submitted.md +++ b/docs/hooks/user-prompt-submitted.md @@ -133,6 +133,7 @@ session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{
.NET + ```csharp var session = await client.CreateSessionAsync(new SessionConfig { diff --git a/docs/mcp/overview.md b/docs/mcp/overview.md index 1ee147b6..aa2fba66 100644 --- a/docs/mcp/overview.md +++ b/docs/mcp/overview.md @@ -153,8 +153,8 @@ await using var session = await client.CreateSessionAsync(new SessionConfig { Type = "local", Command = "node", - Args = new[] { "./mcp-server.js" }, - Tools = new[] { "*" }, + Args = new List { "./mcp-server.js" }, + Tools = new List { "*" }, }, }, });