Skip to content

feat(vscode): configure remote gRPC daemon address - #105

Open
cidrblock wants to merge 5 commits into
redhat-developer:mainfrom
cidrblock:feat/vscode-remote-grpc-address
Open

feat(vscode): configure remote gRPC daemon address#105
cidrblock wants to merge 5 commits into
redhat-developer:mainfrom
cidrblock:feat/vscode-remote-grpc-address

Conversation

@cidrblock

@cidrblock cidrblock commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add VS Code settings so the Abbenay extension can attach to a remote/container daemon over gRPC (host:port, typically :50051) with TLS, CA, and consumer token support
  • When abbenay.daemonAddress is unset, keep existing local IPC detection + SEA/PATH auto-start
  • Reject HTTP dashboard port :8787 (IPv4 and IPv6), URL userinfo, and strip accidental schemes (http(s), grpc, tcp)
  • Coalesce reconnects on settings/token changes; keep connection mode from settings after a failed remote attach
  • Bump js-yaml to 4.3.1 (GHSA-5p4m-2wfm-xmqj)

Changes

  • New settings: abbenay.daemonAddress, daemonTls, daemonCaPath, daemonSslTargetName, daemonTokenEnv
  • Commands: Abbenay: Set/Clear Daemon Token (SecretStorage → x-abbenay-token)
  • DaemonClient remote TCP+TLS path; channel cleanup on failed connect; sticky-address fix for remote→local
  • Open Dashboard uses the remote host on :8787 when a remote gRPC address is configured
  • README / CHANGELOG + unit tests for connection-config

Test plan

  • cd packages/vscode && npm run lint
  • cd packages/vscode && npm test (41 passing)
  • Manual: local mode (empty daemonAddress) still auto-starts / attaches to local daemon
  • Manual: container with -p 50051:50051 + --grpc-tls, set address/CA/token, verify status shows remote:… (tls) and chat works
  • Manual: clear daemonAddress and confirm reconnect returns to local IPC

Allow the extension to attach to a container or TCP Abbenay daemon via
abbenay.daemonAddress (TLS/CA/token), while keeping local IPC auto-start
when unset. Reject HTTP :8787 and URL userinfo; coalesce reconnects.

Also bump js-yaml to 4.3.1 (GHSA-5p4m-2wfm-xmqj).
Copilot AI lite review requested due to automatic review settings August 9, 2026 14:35
@github-actions github-actions Bot added the feat label Aug 9, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds VS Code extension support for connecting to a remote/container Abbenay daemon over gRPC (host:port) with TLS/CA and consumer token support, while preserving existing local IPC auto-start behavior when unset.

Changes:

  • Introduces new abbenay.daemon* settings, token commands backed by VS Code SecretStorage, and reconnect-on-settings/token-change behavior.
  • Implements remote TCP+TLS connection path in DaemonClient, including optional CA loading and x-abbenay-token metadata attachment.
  • Updates docs/changelog and adds unit tests for connection configuration and dashboard URL derivation.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/vscode/src/test/extension.test.ts Extends smoke tests to include new commands and default settings.
packages/vscode/src/test/daemon/connection-config.test.ts Adds unit tests for address normalization, config reading, token resolution, and dashboard URL derivation.
packages/vscode/src/extension.ts Adds connection/reconnect orchestration, SecretStorage-backed token commands, and remote-aware dashboard URL handling.
packages/vscode/src/daemon/index.ts Documents new remote/container connection option.
packages/vscode/src/daemon/connection-config.ts Implements normalization + config resolution for local vs remote daemon connection settings.
packages/vscode/src/daemon/client.ts Adds remote gRPC connection with TLS/CA and token metadata; improves connect/cleanup/reset behavior.
packages/vscode/README.md Documents new settings, token commands, and remote/container setup guidance.
packages/vscode/package.json Contributes new settings and token commands to VS Code extension manifest.
packages/vscode/CHANGELOG.md Notes remote gRPC support and token handling in release notes.
packages/daemon/package.json Bumps js-yaml to ^4.3.1.
package-lock.json Lockfile updates reflecting dependency/version changes.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/vscode/src/test/daemon/connection-config.test.ts
Comment thread packages/vscode/src/daemon/connection-config.ts
Share port validation across IPv4/hostname and bracket IPv6 paths so
[::1]:8787 is rejected like 127.0.0.1:8787. Strengthen normalize tests
for userinfo and the IPv6 dashboard footgun.
Copilot AI review requested due to automatic review settings August 9, 2026 15:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated no new comments.

Suppressed comments (3)

packages/vscode/src/daemon/client.ts:288

  • In DaemonClient.connect(), the catch block resets connectionMode to "local" even when the current settings indicate a remote connection attempt. This makes downstream status/error messages (e.g., daemonStatus) misleading after a failed remote connect; the client should retain the mode derived from settings and only clear transport state.
    } catch (err) {
      await this.closeChannelOnly();
      this.connectionMode = 'local';
      this.address = DEFAULT_DAEMON_ADDRESS;
      throw err;

packages/vscode/src/daemon/connection-config.ts:43

  • normalizeDaemonAddress() only strips http/https schemes; other pasted URL schemes like "grpc://" or "tcp://" will be treated as part of the hostname and later fail in channel creation. Since the function is intended to accept accidental URL forms, strip any RFC3986-style scheme prefix, not just http(s).
  // Accept accidental URL forms; gRPC wants host:port.
  value = value.replace(/^https?:\/\//i, '');
  // Drop path/query if pasted as a URL.

packages/vscode/src/test/daemon/connection-config.test.ts:30

  • The normalizeDaemonAddress test suite claims to cover stripping URL schemes, but it doesn't currently include a non-http(s) scheme example. Adding a "grpc://" case will prevent regressions if scheme handling is broadened.
    assert.strictEqual(normalizeDaemonAddress('  127.0.0.1:50051  '), '127.0.0.1:50051');
    assert.strictEqual(normalizeDaemonAddress('http://127.0.0.1:50051'), '127.0.0.1:50051');
    assert.strictEqual(normalizeDaemonAddress('https://host:50051/path'), 'host:50051');
    assert.strictEqual(normalizeDaemonAddress('[::1]:50051'), '[::1]:50051');
    assert.strictEqual(normalizeDaemonAddress(''), undefined);

Strip any URL scheme (grpc/tcp/http) when normalizing daemonAddress,
keep connectionMode from settings after a failed remote attach, and
cover grpc:// / tcp:// in unit tests.
Copilot AI review requested due to automatic review settings August 9, 2026 15:24
@cidrblock

Copy link
Copy Markdown
Collaborator Author

Addressed Copilot’s suppressed follow-ups from the post-c019ad6 re-review in bde73cb:

  1. Failed remote connect modeconnectionMode now stays derived from settings (no longer forced to local in the connect catch).
  2. Scheme strippingnormalizeDaemonAddress strips any RFC3986-style scheme (grpc://, tcp://, http(s)://, …).
  3. Tests — added grpc:// / tcp:// coverage alongside the earlier [::1]:8787 / userinfo cases.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated no new comments.

Suppressed comments (1)

packages/vscode/src/daemon/client.ts:911

  • initializeDaemon() now calls client.close() in the catch path. DaemonClient.close() resets connectionMode/address to local defaults, which defeats the “keep connection mode from settings after a failed remote attach” behavior (errors/status will read as local after a timeout/failed remote connect).

Consider using a cleanup path that only closes the channel/client without resetting the mode/address (e.g., add a dedicated public cleanup method or an optional parameter to close() to avoid resetting state on failed initialization).

  } catch (err) {
    // Roll back half-open channel if connect raced past the deadline.
    await client.close().catch(() => {});
    throw err;

Use disposeTransport() in initializeDaemon's catch path so a failed or
timed-out attach does not reset connectionMode/address to local defaults.
@cidrblock

Copy link
Copy Markdown
Collaborator Author

Follow-up to Copilot’s suppressed note on initializeDaemon cleanup: init failure/timeout now calls disposeTransport() instead of close(), so connection mode from settings is preserved. Fixed in 3868d83.

Copilot AI review requested due to automatic review settings August 9, 2026 15:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.

Comment thread packages/vscode/src/daemon/client.ts

@sudhirverma sudhirverma left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified: lint clean, tsc compile clean, unit-test logic reviewed in depth (couldn't run full vscode-test e2e locally — no Electron in this sandbox).

Solid PR — clean separation in connection-config.ts (well-tested edge cases: :8787 rejection for IPv4/IPv6, userinfo stripping, scheme stripping, token precedence), good security instincts (token never logged, SecretStorage preferred), and the connect/reconnect state machine in client.ts/extension.ts correctly handles failed-attach and rapid setting-change cases (matches the 3 follow-up hardening commits in this PR's history).

Non-blocking nitpicks for a future pass:

  1. normalizeDaemonAddress's explicit unix: prefix check is effectively dead for unix:///path — the URL-scheme-strip regex consumes unix:// first; it still ends up rejected via slash-truncation, just not through the path the comment implies.
  2. TLS without daemonCaPath silently falls back to the system trust store (warning-only log) — a self-signed container cert will fail with a possibly-unclear gRPC error rather than an upfront actionable message.
  3. setDaemonToken/clearDaemonToken trigger a reconnect even in local mode, where the setting is unused.
  4. openDashboard: fallbackUrl derived from daemonAddress always wins over the daemon's own startWebServer response URL when remote — fine for the common case, could diverge if the daemon binds a different interface.

LGTM to merge.

@Hrithik-Gavankar
Hrithik-Gavankar self-requested a review August 10, 2026 14:05

@Hrithik-Gavankar Hrithik-Gavankar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes LGTM!

Copilot AI review requested due to automatic review settings August 10, 2026 14:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants