Skip to content

Commit d0386d0

Browse files
committed
resolve conflict
2 parents ac8d5fd + a001bea commit d0386d0

File tree

8 files changed

+125
-24
lines changed

8 files changed

+125
-24
lines changed

.prettierrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
],
1010
"options": {
1111
"printWidth": 80,
12-
"proseWrap": "always"
12+
"proseWrap": "preserve"
1313
}
1414
}
1515
]

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
## Unreleased
44

5+
## [v1.6.0](https://github.com/coder/vscode-coder/releases/tag/v1.6.0) (2025-04-01)
6+
7+
### Added
8+
9+
- Add support for Coder inbox.
10+
11+
## [v1.5.0](https://github.com/coder/vscode-coder/releases/tag/v1.5.0) (2025-03-20)
12+
13+
### Fixed
14+
15+
- Fixed regression where autostart needed to be disabled.
16+
517
### Changed
618

719
- Make the MS Remote SSH extension part of an extension pack rather than a hard dependency, to enable

README.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Coder Remote
22

33
[![Visual Studio Marketplace](https://vsmarketplacebadges.dev/version/coder.coder-remote.svg)](https://marketplace.visualstudio.com/items?itemName=coder.coder-remote)
4+
[![Open VSX Version](https://img.shields.io/open-vsx/v/coder/coder-remote)](https://open-vsx.org/extension/coder/coder-remote)
45
[!["Join us on
56
Discord"](https://badgen.net/discord/online-members/coder)](https://coder.com/chat?utm_source=github.com/coder/vscode-coder&utm_medium=github&utm_campaign=readme.md)
67

@@ -13,11 +14,11 @@ workspaces with a single click.
1314
- Works in air-gapped or restricted networks. Just connect to your Coder
1415
deployment!
1516
- Supports multiple editors: VS Code, Cursor, and Windsurf.
16-
> [!NOTE]
17-
> The extension builds on VSCode provided implementations of SSH. Make sure
18-
> you have the correct ssh extension installed for your editor
19-
> (ms-vscode-remote.remote-ssh or codeium.windsurf-remote-openssh for
20-
> windsurf)
17+
18+
> [!NOTE]
19+
> The extension builds on VS Code-provided implementations of SSH. Make
20+
> sure you have the correct SSH extension installed for your editor
21+
> (`ms-vscode-remote.remote-ssh` or `codeium.windsurf-remote-openssh` for Windsurf).
2122
2223
![Demo](https://github.com/coder/vscode-coder/raw/main/demo.gif?raw=true)
2324

@@ -26,19 +27,18 @@ workspaces with a single click.
2627
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press
2728
enter.
2829

29-
```text
30+
```shell
3031
ext install coder.coder-remote
3132
```
3233

3334
Alternatively, manually install the VSIX from the
3435
[latest release](https://github.com/coder/vscode-coder/releases/latest).
3536

36-
#### Variables Reference
37+
### Variables Reference
3738

38-
Coder uses
39-
${userHome} from VS Code's
39+
Coder uses `${userHome}` from VS Code's
4040
[variables reference](https://code.visualstudio.com/docs/editor/variables-reference).
41-
Use this when formatting paths in the Coder extension settings rather than ~ or
42-
$HOME.
41+
Use this when formatting paths in the Coder extension settings rather than `~`
42+
or `$HOME`.
4343

4444
Example: ${userHome}/foo/bar.baz

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"displayName": "Coder",
55
"description": "Open any workspace with a single click.",
66
"repository": "https://github.com/coder/vscode-coder",
7-
"version": "1.4.2",
7+
"version": "1.6.0",
88
"engines": {
99
"vscode": "^1.73.0"
1010
},
@@ -328,7 +328,7 @@
328328
"webpack-cli": "^5.1.4"
329329
},
330330
"dependencies": {
331-
"axios": "1.7.7",
331+
"axios": "1.8.4",
332332
"date-fns": "^3.6.0",
333333
"eventsource": "^3.0.5",
334334
"find-process": "^1.4.7",

src/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export function needToken(): boolean {
2828
/**
2929
* Create a new agent based off the current settings.
3030
*/
31-
async function createHttpAgent(): Promise<ProxyAgent> {
31+
export async function createHttpAgent(): Promise<ProxyAgent> {
3232
const cfg = vscode.workspace.getConfiguration()
3333
const insecure = Boolean(cfg.get("coder.insecure"))
3434
const certFile = expandPath(String(cfg.get("coder.tlsCertFile") ?? "").trim())

src/inbox.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { Api } from "coder/site/src/api/api"
2+
import { Workspace, GetInboxNotificationResponse } from "coder/site/src/api/typesGenerated"
3+
import { ProxyAgent } from "proxy-agent"
4+
import * as vscode from "vscode"
5+
import { WebSocket } from "ws"
6+
import { errToStr } from "./api-helper"
7+
import { type Storage } from "./storage"
8+
9+
// These are the template IDs of our notifications.
10+
// Maybe in the future we should avoid hardcoding
11+
// these in both coderd and here.
12+
const TEMPLATE_WORKSPACE_OUT_OF_MEMORY = "a9d027b4-ac49-4fb1-9f6d-45af15f64e7a"
13+
const TEMPLATE_WORKSPACE_OUT_OF_DISK = "f047f6a3-5713-40f7-85aa-0394cce9fa3a"
14+
15+
export class Inbox implements vscode.Disposable {
16+
readonly #storage: Storage
17+
#disposed = false
18+
#socket: WebSocket
19+
20+
constructor(workspace: Workspace, httpAgent: ProxyAgent, restClient: Api, storage: Storage) {
21+
this.#storage = storage
22+
23+
const baseUrlRaw = restClient.getAxiosInstance().defaults.baseURL
24+
if (!baseUrlRaw) {
25+
throw new Error("No base URL set on REST client")
26+
}
27+
28+
const watchTemplates = [TEMPLATE_WORKSPACE_OUT_OF_DISK, TEMPLATE_WORKSPACE_OUT_OF_MEMORY]
29+
const watchTemplatesParam = encodeURIComponent(watchTemplates.join(","))
30+
31+
const watchTargets = [workspace.id]
32+
const watchTargetsParam = encodeURIComponent(watchTargets.join(","))
33+
34+
// We shouldn't need to worry about this throwing. Whilst `baseURL` could
35+
// be an invalid URL, that would've caused issues before we got to here.
36+
const baseUrl = new URL(baseUrlRaw)
37+
const socketProto = baseUrl.protocol === "https:" ? "wss:" : "ws:"
38+
const socketUrl = `${socketProto}//${baseUrl.host}/api/v2/notifications/inbox/watch?format=plaintext&templates=${watchTemplatesParam}&targets=${watchTargetsParam}`
39+
40+
const coderSessionTokenHeader = "Coder-Session-Token"
41+
this.#socket = new WebSocket(new URL(socketUrl), {
42+
followRedirects: true,
43+
agent: httpAgent,
44+
headers: {
45+
[coderSessionTokenHeader]: restClient.getAxiosInstance().defaults.headers.common[coderSessionTokenHeader] as
46+
| string
47+
| undefined,
48+
},
49+
})
50+
51+
this.#socket.on("open", () => {
52+
this.#storage.writeToCoderOutputChannel("Listening to Coder Inbox")
53+
})
54+
55+
this.#socket.on("error", (error) => {
56+
this.notifyError(error)
57+
this.dispose()
58+
})
59+
60+
this.#socket.on("message", (data) => {
61+
try {
62+
const inboxMessage = JSON.parse(data.toString()) as GetInboxNotificationResponse
63+
64+
vscode.window.showInformationMessage(inboxMessage.notification.title)
65+
} catch (error) {
66+
this.notifyError(error)
67+
}
68+
})
69+
}
70+
71+
dispose() {
72+
if (!this.#disposed) {
73+
this.#storage.writeToCoderOutputChannel("No longer listening to Coder Inbox")
74+
this.#socket.close()
75+
this.#disposed = true
76+
}
77+
}
78+
79+
private notifyError(error: unknown) {
80+
const message = errToStr(error, "Got empty error while monitoring Coder Inbox")
81+
this.#storage.writeToCoderOutputChannel(message)
82+
}
83+
}

src/remote.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ import * as path from "path"
99
import prettyBytes from "pretty-bytes"
1010
import * as semver from "semver"
1111
import * as vscode from "vscode"
12-
import { makeCoderSdk, needToken, startWorkspaceIfStoppedOrFailed, waitForBuild } from "./api"
12+
import { createHttpAgent, makeCoderSdk, needToken, startWorkspaceIfStoppedOrFailed, waitForBuild } from "./api"
1313
import { extractAgents } from "./api-helper"
1414
import * as cli from "./cliManager"
1515
import { Commands } from "./commands"
1616
import { featureSetForVersion, FeatureSet } from "./featureSet"
1717
import { getHeaderCommand } from "./headers"
18+
import { Inbox } from "./inbox"
1819
import { SSHConfig, SSHValues, mergeSSHConfigValues } from "./sshConfig"
1920
import { computeSSHProperties, sshSupportsSetEnv } from "./sshSupport"
2021
import { Storage } from "./storage"
@@ -403,6 +404,11 @@ export class Remote {
403404
disposables.push(monitor)
404405
disposables.push(monitor.onChange.event((w) => (this.commands.workspace = w)))
405406

407+
// Watch coder inbox for messages
408+
const httpAgent = await createHttpAgent()
409+
const inbox = new Inbox(workspace, httpAgent, workspaceRestClient, this.storage)
410+
disposables.push(inbox)
411+
406412
// Wait for the agent to connect.
407413
if (agent.status === "connecting") {
408414
this.storage.writeToCoderOutputChannel(`Waiting for ${workspaceName}/${agent.name}...`)
@@ -627,7 +633,7 @@ export class Remote {
627633
const proxyCommand = featureSet.wildcardSSH
628634
? `${escape(binaryPath)}${headerArg} --global-config ${escape(
629635
path.dirname(this.storage.getSessionTokenPath(label)),
630-
)} ssh --stdio --usage-app=vscode --network-info-dir ${escape(this.storage.getNetworkInfoPath())}${await this.formatLogArg(logDir)} --ssh-host-prefix ${hostPrefix} %h`
636+
)} ssh --stdio --usage-app=vscode --disable-autostart --network-info-dir ${escape(this.storage.getNetworkInfoPath())}${await this.formatLogArg(logDir)} --ssh-host-prefix ${hostPrefix} %h`
631637
: `${escape(binaryPath)}${headerArg} vscodessh --network-info-dir ${escape(
632638
this.storage.getNetworkInfoPath(),
633639
)}${await this.formatLogArg(logDir)} --session-token-file ${escape(this.storage.getSessionTokenPath(label))} --url-file ${escape(

yarn.lock

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,10 +1200,10 @@ available-typed-arrays@^1.0.7:
12001200
dependencies:
12011201
possible-typed-array-names "^1.0.0"
12021202

1203-
axios@1.7.7:
1204-
version "1.7.7"
1205-
resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f"
1206-
integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==
1203+
axios@1.8.4:
1204+
version "1.8.4"
1205+
resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.4.tgz#78990bb4bc63d2cae072952d374835950a82f447"
1206+
integrity sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==
12071207
dependencies:
12081208
follow-redirects "^1.15.6"
12091209
form-data "^4.0.0"
@@ -5986,9 +5986,9 @@ tapable@^2.1.1, tapable@^2.2.0:
59865986
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
59875987

59885988
tar-fs@^2.0.0:
5989-
version "2.1.1"
5990-
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784"
5991-
integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==
5989+
version "2.1.2"
5990+
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.2.tgz#425f154f3404cb16cb8ff6e671d45ab2ed9596c5"
5991+
integrity sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==
59925992
dependencies:
59935993
chownr "^1.1.1"
59945994
mkdirp-classic "^0.5.2"

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy