github / github/app

Allow Canvas extensions to open or focus an existing local session

未关闭
#3,030 0 条评论 3 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
没有语言数据
星标
2.1k
派生
153
PR 合并指标
30 天内没有已合并 PR

描述

### Feature summary

Expose a capability-gated App host API, callable by a Canvas extension process, that opens or focuses an existing local Copilot runtime session in Chat View and reports when the transition is complete.

### What problem are you trying to solve?

I am building a Canvas extension that visualizes a tree of forked local Copilot sessions.

The extension currently reaches the server-scoped `sessions.fork` RPC through an untyped/private connection because `joinSession()` returns a `CopilotSession` whose typed `session.rpc` does not expose `sessions.*`. When the fork succeeds, the extension receives the child runtime session ID.

The Canvas needs to support two workflows:

1. Automatically enter a newly created child session.
2. Let the user select an existing branch and click **Open Chat**.

There is currently no documented Canvas extension or App host API that switches Copilot App Chat View to that runtime session.

The available alternatives do not provide this behavior:

- `CopilotClient.setForegroundSessionId(runtimeSessionId)` is documented only for a client connected to a TUI started with `--ui-server`; it is not available through `joinSession()` and is not an App host navigation contract.
- The server-scoped `sessions.open({ kind: "resume", sessionId: runtimeSessionId })` loads or reattaches runtime state, but it is not exposed by the typed `CopilotSession.rpc` returned from `joinSession()` and does not promise an App Chat View transition.
- Attempting to execute the `resume` command through `session.rpc.commands.execute(...)` failed in App 1.0.80. This is observed behavior, not a documented statement that the App owns or does not own that command.
- `session.rpc.commands.enqueue({ command: `/resume ${runtimeSessionId}` })` reports queue acceptance only; it does not report command execution or Chat View completion.
- `session.send()` sends a user turn to the joined session's fixed `sessionId`. It has no target-session argument and should not be used as a navigation workaround.
- GitHub documents `ghapp://sessions/SESSION_ID` for an app-local workspace or session, but the public documentation does not state whether an ID returned by `sessions.fork` is directly resolvable by that link. Canvas also exposes no documented host operation for dispatching the deep link.

The documented deterministic handoff is to ask the user to run `copilot --resume SESSION-ID` in a terminal, or `/resume SESSION-ID` inside an interactive Copilot CLI session. I found no documented Canvas/App host API that performs the equivalent App Chat View transition.

### Proposed solution

Add a capability-gated extension-process API that resolves a local runtime session and opens or focuses it in the corresponding App Chat View.

A possible contract:

```js
if (session.capabilities.ui?.openLocalSession) {
const result = await session.ui.openLocalSession({
runtimeSessionId,
focus: true,
});
}
```

Example result:

```js
{
status: "opened" | "focused" | "already_focused",
runtimeSessionId,
appSessionId?: string
}
```

The operation should:

- Resolve only after Chat View displays the target transcript and is ready for user input.
- Create, adopt, or resolve an App session record when the host requires one; do not require a separate `appSessionId` unless the App actually uses a distinct identifier.
- Return typed failures such as `not_found`, `in_use`, `unsupported`, and `denied`.
- Be advertised through host capabilities before the Canvas renders navigation controls.
- Restrict access to local sessions available to the current user.
- Allow the host to request user confirmation when appropriate.
- Define lifecycle behavior when changing the foreground session reloads or disconnects the source extension, so completion remains observable.

Navigation should remain separate from message sending.

### Workflow impact

This would let Canvas extensions implement reliable **Open Chat** and **Fork and open** actions.

It would benefit session visualizers, task boards, workflow canvases, and other extensions that represent local sessions. It would remove the need to use synthetic user messages, guessed deep links, or fire-and-forget `/resume` commands as navigation workarounds.

This request is specifically about App navigation. A supported extension API for creating or forking runtime sessions is a separate concern.

### Installation context

User-scoped Canvas extension registered through `joinSession({ canvases: [...] })` in a local branch workspace.

Observed with GitHub Copilot App / CLI 1.0.80 on Windows.

### Additional context

This is related to #1284, which proposes a broader bridge from Canvas extensions to App host capabilities. This request is intentionally narrower: resolve a local runtime session ID, open or focus it in Chat View, and report completion.

Relevant contracts and documentation:

- Canvas lifecycle: https://github.com/github/copilot-sdk/blob/ea41dadb199725766d5097f4592c17be3200035f/nodejs/src/canvas.ts#L15-L24
- Foreground session API: https://github.com/github/copilot-sdk/blob/ea41dadb199725766d5097f4592c17be3200035f/nodejs/src/client.ts#L2294-L2348
- Extension `joinSession()`: https://github.com/github/copilot-sdk/blob/ea41dadb199725766d5097f4592c17be3200035f/nodejs/src/extension.ts#L96-L137
- App deep links: https://docs.github.com/en/copilot/how-tos/github-copilot-app/open-with-deep-links#available-app-links
- CLI session resume: https://docs.github.com/en/copilot/how-tos/copilot-cli/use-copilot-cli/chronicle#resuming-a-previous-session

贡献指南

打开贡献指南

调研方向

先从 nodejs/src/canvas.ts、nodejs/src/client.ts 和 nodejs/src/extension.ts 中引用的契约开始,然后跟踪 Canvas 的能力如何到达 App 宿主。定义 issue 中描述的导航生命周期、能力门控、结果状态、失败情况和完成行为。当一个有文档说明的 API 能够打开或聚焦本地 runtime 会话,并可靠地报告 Chat View 何时就绪时,即视为完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
javascript, node.js
领域
api, desktop, developer-experience
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
活跃
描述清晰度
基本清楚
新手友好度
32/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。