zidane 6.3.6 → 6.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{acp-Xkhrpx8r.js → acp-CAX3tOEY.js} +2 -2
- package/dist/{acp-Xkhrpx8r.js.map → acp-CAX3tOEY.js.map} +1 -1
- package/dist/acp-cli.js +2 -2
- package/dist/acp.js +1 -1
- package/dist/{agent-xjMzFclr.js → agent-Emjeo5Ad.js} +2 -2
- package/dist/{agent-xjMzFclr.js.map → agent-Emjeo5Ad.js.map} +1 -1
- package/dist/agent.js +1 -1
- package/dist/chat.d.ts +46 -2
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +3 -3
- package/dist/{context-transport-O-oQHwhP.js → context-transport-3b0qpM2m.js} +3 -3
- package/dist/{context-transport-O-oQHwhP.js.map → context-transport-3b0qpM2m.js.map} +1 -1
- package/dist/extensions.js +1 -1
- package/dist/headless.js +1 -1
- package/dist/index.js +3 -3
- package/dist/{login-DZHMF7Gl.js → login-C41DcRK-.js} +2 -2
- package/dist/{login-DZHMF7Gl.js.map → login-C41DcRK-.js.map} +1 -1
- package/dist/{mcp-B5iXOceC.js → mcp-8bEHU4WB.js} +3 -3
- package/dist/{mcp-B5iXOceC.js.map → mcp-8bEHU4WB.js.map} +1 -1
- package/dist/mcp.js +1 -1
- package/dist/presets.js +1 -1
- package/dist/{stdio-BsB0QEE9.js → stdio-BKFpPNvX.js} +2 -2
- package/dist/{stdio-BsB0QEE9.js.map → stdio-BKFpPNvX.js.map} +1 -1
- package/dist/{stdio-loader-p7qCIzPS.js → stdio-loader-DFDpBwwI.js} +2 -2
- package/dist/{stdio-loader-p7qCIzPS.js.map → stdio-loader-DFDpBwwI.js.map} +1 -1
- package/dist/tools.js +1 -1
- package/dist/{transcript-anchors-Bsmm4435.js → transcript-anchors-DhBTqTyc.js} +81 -7
- package/dist/{transcript-anchors-Bsmm4435.js.map → transcript-anchors-DhBTqTyc.js.map} +1 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +257 -101
- package/dist/tui.js.map +1 -1
- package/docs/CHAT.md +3 -1
- package/docs/TUI.md +2 -2
- package/package.json +1 -1
package/docs/CHAT.md
CHANGED
|
@@ -148,7 +148,7 @@ The table below indexes every named export; sections further down dive into the
|
|
|
148
148
|
| `model-catalog` | Cross-provider unified model picker assembly — `buildModelCatalog`, `filterModelCatalog`, `indexOfEntry`, `CatalogEntry`. |
|
|
149
149
|
| `model-chain` | Ordered model fallback chains (pure helpers behind the picker's multi-select + the host's run-option assembly) — `ModelChainEntry`, `toggleChainEntry`, `chainPositionOf`, `chainsEqual`, `filterChainFallbacks`, `restoreChainFallbacks`, `sanitizeModelChain`, `providerKeySetChanged`, `buildRunModel`. |
|
|
150
150
|
| `oauth` | `runOAuthLogin(descriptor, { onUrl, onPrompt, onProgress, signal })` + `supportsOAuth(descriptor)` + `oauthUsesManualCodePaste(descriptor)` — AI-provider OAuth (distinct from MCP OAuth). |
|
|
151
|
-
| `oauth-redirect` | `fetchOAuthRedirect(pastedUrl)` — SSH escape hatch. Validates `pasted` is a loopback URL, fires a GET so the in-process callback server (pi-ai's or `startOAuthCallback`'s) receives the request through its normal handler. Used by the TUI to accept a redirect-URL paste when the browser couldn't reach the callback server directly. |
|
|
151
|
+
| `oauth-redirect` | `fetchOAuthRedirect(pastedUrl, { authUrl? })` — SSH escape hatch. Validates `pasted` is a loopback URL, fires a GET so the in-process callback server (pi-ai's or `startOAuthCallback`'s) receives the request through its normal handler. Used by the TUI to accept a redirect-URL paste when the browser couldn't reach the callback server directly. `normalizeRedirectPaste(pasted, authUrl)` widens what counts as a paste (bare code / query / path); `redirectUriFromAuthUrl(authUrl)` reads back the loopback callback the request was minted with, which the TUI also displays. |
|
|
152
152
|
| `path-display` | `formatPathForCwd(projectRel, projectRoot, cwd)` — rewrites a project-root-relative path (as emitted by `listProjectFiles`) into the form the agent's CWD-resolving tools actually find. Wired into `createFilesCompletionProvider({ formatPath })` by the TUI shell. |
|
|
153
153
|
| `project-root` | `findGitRoot(cwd)` — walks upward looking for `.git`, returns absolute path or `null`. Used for session scope tagging + export anchors. |
|
|
154
154
|
| `prompt-segments` | `splitPromptSegments(text, refs)` → `PromptSegment[]`. GUI maps the same segments to inline-block chip pills. |
|
|
@@ -1362,6 +1362,8 @@ if (supportsOAuth(descriptor)) {
|
|
|
1362
1362
|
|
|
1363
1363
|
**SSH paste-back.** When the user runs zidane over SSH (or behind a firewall that blocks loopback), the browser-side redirect to `http://127.0.0.1:<port>/callback?...` can't reach the remote callback server. `fetchOAuthRedirect(pastedUrl)` is the escape hatch: hand it the URL the browser ended up at and it fires a GET from inside the agent process. The request hits pi-ai's still-running server through the same handler a real browser would have, `waitForCode` resolves, and `runOAuthLogin` continues uninterrupted — no `onPrompt` call needed. The TUI wires this into a paste input next to the auth URL on every OAuth surface (AI providers + MCP).
|
|
1364
1364
|
|
|
1365
|
+
Pass the authorization URL along (`fetchOAuthRedirect(pasted, { authUrl })`) and partial pastes work too: `normalizeRedirectPaste(pasted, authUrl)` completes a bare `code`, a `?code=…&state=…` query, or a `/callback?…` path against the `redirect_uri` the request was minted with (`redirectUriFromAuthUrl`), reusing the `state` from the authorization URL when the paste has none. Absolute URLs are passed through untouched so a mistaken non-loopback paste still hits the SSRF guard instead of being rewritten into a request against our own callback server.
|
|
1366
|
+
|
|
1365
1367
|
### MCP-server OAuth
|
|
1366
1368
|
|
|
1367
1369
|
Streamable-HTTP and SSE MCP servers can require OAuth 2.1 (Linear, Sentry, the Anthropic-hosted catalog). Wired through the SDK's `OAuthClientProvider` interface — `zidane/chat` provides the persistence half (`McpCredentialStore` + `createFileMcpCredentialStore`), `zidane/mcp` provides the SDK-protocol half (`McpOAuthProvider`).
|
package/docs/TUI.md
CHANGED
|
@@ -503,7 +503,7 @@ Interactive login flow (triggered by `ctrl+L` on a needs-auth row in `SettingsMo
|
|
|
503
503
|
1. App calls `loginMcpServer(config, { store, hooks, signal })` from `zidane/mcp`.
|
|
504
504
|
2. `startOAuthCallback` spawns a loopback `127.0.0.1` HTTP listener on a random port.
|
|
505
505
|
3. `McpOAuthProvider` is built with `redirectUri` pointing at the loopback; `client.connect()` triggers `redirectToAuthorization` which fires `mcp:auth:url` (the modal renders the URL via `<McpAuthorizingPanel>` — `tryOpenBrowser` opens it automatically).
|
|
506
|
-
4. SDK throws `UnauthorizedError`; we wait on the callback for the `?code=...` redirect. The same `<McpAuthorizingPanel>` includes a paste-back input
|
|
506
|
+
4. SDK throws `UnauthorizedError`; we wait on the callback for the `?code=...` redirect. The same `<McpAuthorizingPanel>` includes a paste-back input (step 2 of the panel) — submitting pipes the value through `fetchOAuthRedirect`, which `fetch()`s the loopback callback URL from inside the agent process and lands a `?code=...` on the listener exactly like a real browser would. This unblocks SSH sessions where the loopback redirect can't reach the remote server directly. The panel prints the exact `redirect_uri` the request was minted with (`redirectUriFromAuthUrl`) so there's no guessing about which address to copy out of the browser's URL bar, and it force-focuses the input on mount — `focused` as a prop alone leaves keys with whichever field owned focus before the takeover mounted.
|
|
507
507
|
5. `transport.finishAuth(code)` exchanges the code for tokens; `provider.saveTokens` persists via `createFileMcpCredentialStore(userDir)`.
|
|
508
508
|
6. Reconnect with the new tokens; `client.listTools()` returns the catalog.
|
|
509
509
|
7. App rebuilds the active agent so the now-authenticated server connects on the next run.
|
|
@@ -516,7 +516,7 @@ Interactive login flow (triggered by `ctrl+L` on a needs-auth row in `SettingsMo
|
|
|
516
516
|
|
|
517
517
|
1. **Pick provider** — every entry in `config.providers`. Methods column derives from `supportsOAuth(descriptor)`.
|
|
518
518
|
2. **Pick method** — API key or OAuth (gated on `descriptor.oauthProvider`).
|
|
519
|
-
3. **Enter API key** → writes via `setProviderCredential(dataDir, descriptor, { kind: 'apikey', value })` and seeds `process.env[descriptor.envKey]`, OR **OAuth running** → `runOAuthLogin(descriptor, { onUrl, onPrompt, onProgress, signal })`. The URL is surfaced via `<OAuthAuthBlock>`
|
|
519
|
+
3. **Enter API key** → writes via `setProviderCredential(dataDir, descriptor, { kind: 'apikey', value })` and seeds `process.env[descriptor.envKey]`, OR **OAuth running** → `runOAuthLogin(descriptor, { onUrl, onPrompt, onProgress, signal })`. The URL is surfaced via `<OAuthAuthBlock>` — two clickable buttons (`ctrl+b` open in browser, `ctrl+y` copy the URL), the full URL in a framed panel with its own `[copy]` button and chunked into per-row hyperlinks, and a paste-back input. Submitting the input either resolves a pending pi-ai `onPrompt` (providers with `usesCallbackServer: false`, e.g. Anthropic Claude Pro/Max) or, when no prompt is pending, fires the pasted URL through `fetchOAuthRedirect` so the loopback callback server completes through its normal path — the SSH escape hatch. The screen pre-flips its spinner copy via `oauthUsesManualCodePaste(descriptor)` so the manual-paste providers say "paste the code below" before pi-ai actually prompts.
|
|
520
520
|
|
|
521
521
|
A pre-existing user picker (when at least one provider is already authed) lists current credentials plus a `+ add or re-configure` entry that opens the wizard with a `← back` affordance. Esc on the wizard bails to the picker (or exits the TUI on a true first launch).
|
|
522
522
|
|