{"meta":{"title":"远程会话","intro":"远程会话允许用户通过 Mission Control 从 GitHub Web 和移动设备访问其Copilot会话。 启用后，SDK 会将每个会话连接到任务控制，生成一个 URL，可以作为链接或 QR 码共享。","product":"GitHub Copilot","breadcrumbs":[{"href":"/zh/enterprise-cloud@latest/copilot","title":"GitHub Copilot"},{"href":"/zh/enterprise-cloud@latest/copilot/how-tos","title":"操作方法"},{"href":"/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk","title":"Copilot SDK"},{"href":"/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features","title":"功能"},{"href":"/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features/remote-sessions","title":"远程会话"}],"documentType":"article"},"body":"# 远程会话\n\n远程会话允许用户通过 Mission Control 从 GitHub Web 和移动设备访问其Copilot会话。 启用后，SDK 会将每个会话连接到任务控制，生成一个 URL，可以作为链接或 QR 码共享。\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n有关在 GitHub 托管的计算资源上运行会话的信息，请参阅 [云会话](/zh/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features/cloud-sessions)。\n\n## 先决条件\n\n* 必须对用户进行身份验证（GitHub令牌或登录用户）\n* 会话的工作目录必须是GitHub存储库\n\n## 启用远程会话\n\n### 始终开启（客户端级别）\n\n创建客户端时设置 `enableRemoteSessions: true` 。 GitHub存储库中的每个会话都会自动获取远程 URL。\n\n<!-- tabs:start -->\n\n#### TypeScript\n\n<!-- docs-validate: skip -->\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient({ enableRemoteSessions: true });\nconst session = await client.createSession({\n  workingDirectory: \"/path/to/github-repo\",\n  onPermissionRequest: async () => ({ allowed: true }),\n});\n\nsession.on(\"session.info\", (event) => {\n  if (event.data.infoType === \"remote\") {\n    console.log(\"Remote URL:\", event.data.url);\n  }\n});\n```\n\n#### Python\n\n<!-- docs-validate: skip -->\n\n```python\nfrom copilot import CopilotClient\n\nclient = CopilotClient(enable_remote_sessions=True)\nsession = await client.create_session(\n    working_directory=\"/path/to/github-repo\",\n    on_permission_request=lambda req: {\"allowed\": True},\n)\n\ndef on_event(event):\n    if event.type == \"session.info\" and event.data.info_type == \"remote\":\n        print(f\"Remote URL: {event.data.url}\")\n\nsession.on(on_event)\n```\n\n#### Go\n\n<!-- docs-validate: skip -->\n\n```golang\nclient := copilot.NewClient(&copilot.ClientOptions{EnableRemoteSessions: true})\nsession, _ := client.CreateSession(ctx, &copilot.SessionConfig{\n    WorkingDirectory: \"/path/to/github-repo\",\n    OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {\n        return &rpc.PermissionDecisionApproveOnce{}, nil\n    },\n})\n\nsession.On(func(event copilot.SessionEvent) {\n    if event.Type == \"session.info\" {\n        // Check infoType and extract URL\n    }\n})\n```\n\n#### C\\#\n\n<!-- docs-validate: skip -->\n\n```csharp\nvar client = new CopilotClient(new CopilotClientOptions { EnableRemoteSessions = true });\nvar session = await client.CreateSessionAsync(new SessionConfig\n{\n    WorkingDirectory = \"/path/to/github-repo\",\n    OnPermissionRequest = (req, inv) =>\n        Task.FromResult(PermissionDecision.ApproveOnce()),\n});\n\nsession.On((SessionEvent e) =>\n{\n    if (e is SessionInfoEvent info && info.Data.InfoType == \"remote\")\n    {\n        Console.WriteLine($\"Remote URL: {info.Data.Url}\");\n    }\n});\n```\n\n#### Rust\n\n<!-- docs-validate: skip -->\n\n```rust\nuse github_copilot_sdk::{Client, ClientOptions, SessionConfig};\nuse github_copilot_sdk::handler::PermissionResult;\n\nlet client = Client::start(\n    ClientOptions::new().with_enable_remote_sessions(true)\n).await?;\nlet session = client.create_session(\n    SessionConfig::new(\"/path/to/github-repo\")\n        .with_permission_handler(|_req, _inv| async {\n            Ok(PermissionResult::approve_once())\n        }),\n).await?;\n\nlet mut events = session.subscribe();\nwhile let Ok(event) = events.recv().await {\n    if event.event_type == \"session.info\" {\n        // Check info_type and extract URL\n    }\n}\n```\n\n<!-- tabs:end -->\n\n### 按需（按会话切换）\n\n使用 `session.rpc.remote.enable()` 在会话进行中启动远程访问，并使用 `session.rpc.remote.disable()` 停止远程访问。 这相当于 CLI 的 `/remote on` 和 `/remote off` 命令。\n\n<!-- tabs:start -->\n\n#### TypeScript\n\n<!-- docs-validate: skip -->\n\n```typescript\nconst result = await session.rpc.remote.enable();\nconsole.log(\"Remote URL:\", result.url);\n\n// Later: stop sharing\nawait session.rpc.remote.disable();\n```\n\n#### Python\n\n<!-- docs-validate: skip -->\n\n```python\nresult = await session.rpc.remote.enable()\nprint(f\"Remote URL: {result.url}\")\n\n# Later: stop sharing\nawait session.rpc.remote.disable()\n```\n\n#### Go\n\n<!-- docs-validate: skip -->\n\n```golang\nresult, err := session.RPC.Remote.Enable(ctx)\nif result.URL != nil {\n    fmt.Println(\"Remote URL:\", *result.URL)\n}\n\n// Later: stop sharing\nerr = session.RPC.Remote.Disable(ctx)\n```\n\n#### C\\#\n\n<!-- docs-validate: skip -->\n\n```csharp\nvar result = await session.Rpc.Remote.EnableAsync();\nConsole.WriteLine($\"Remote URL: {result.Url}\");\n\n// Later: stop sharing\nawait session.Rpc.Remote.DisableAsync();\n```\n\n#### Rust\n\n<!-- docs-validate: skip -->\n\n```rust\nlet result = session.rpc().remote().enable().await?;\nif let Some(url) = &result.url {\n    println!(\"Remote URL: {url}\");\n}\n\n// Later: stop sharing\nsession.rpc().remote().disable().await?;\n```\n\n<!-- tabs:end -->\n\n## QR 码生成\n\n远程 URL 可以呈现为 QR 码，以便轻松进行移动访问。 SDK 提供 URL - 使用首选 QR 码库：\n\n* **TypeScript**： [qrcode](https://www.npmjs.com/package/qrcode)\n* **Python**：[qrcode](https://pypi.org/project/qrcode/)\n* **Go**： [go-qrcode](https://github.com/skip2/go-qrcode)\n* **C#**： [QRCoder](https://www.nuget.org/packages/QRCoder)\n* **Rust**： [qrcode](https://crates.io/crates/qrcode)\n\n## 笔记\n\n* 当 SDK 启动运行时（作为子进程或进程内主机）时，客户端 `enableRemoteSessions` 选项适用。 连接到已运行的运行时时，将忽略它。\n* 如果工作目录不是 GitHub 仓库，则会静默跳过远程配置（始终启用模式），或返回错误（按需模式）。\n* 远程会话需要身份验证。 确保 `gitHubToken` 或 `useLoggedInUser` 已配置。"}