Skip to content

Commit

Permalink
vscode-lib: expose vscode API via global
Browse files Browse the repository at this point in the history
Currently vscode doesn't support dynamic imports, so it isn't possible
for a javascript provider to opt-in to more advanced user experience via
the vscode APIs.

Until we can more easily opt-in to vscode support, we expose the vscode
API via node's global object. We want to see what sort of APIs get used
from vscode in providers, and will then likely evolve a first class
editor abstraction.
  • Loading branch information
keegancsmith committed Jun 27, 2024
1 parent 0b8b5d9 commit b9c1231
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 4 deletions.
2 changes: 1 addition & 1 deletion client/vscode-lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openctx/vscode-lib",
"version": "0.0.11",
"version": "0.0.12",
"description": "OpenCtx library for VS Code extensions",
"license": "Apache-2.0",
"repository": {
Expand Down
3 changes: 3 additions & 0 deletions client/vscode-lib/src/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { ImportedProviderConfiguration } from '@openctx/client/src/configur
import { type Observable, combineLatest, from, isObservable, map, mergeMap, of } from 'rxjs'
import * as vscode from 'vscode'
import { getClientConfiguration } from './configuration.js'
import { initializeOpenCtxGlobal } from './global.js'
import { type ExtensionApiForTesting, createApiForTesting } from './testing.js'
import { createCodeLensProvider } from './ui/editor/codeLens.js'
import { createHoverProvider } from './ui/editor/hover.js'
Expand Down Expand Up @@ -61,6 +62,8 @@ export function createController({
apiForTesting: ExtensionApiForTesting
disposable: vscode.Disposable
} {
initializeOpenCtxGlobal()

const disposables: vscode.Disposable[] = []

const globalConfigurationChanges = observeWorkspaceConfigurationChanges('openctx')
Expand Down
23 changes: 23 additions & 0 deletions client/vscode-lib/src/global.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as vscode from 'vscode'

// dynamic imports don't work in node + vscode due to
// https://github.com/microsoft/vscode-loader/issues/36
//
// So vscode-lib sets a global so providers can optionally access vscode APIs.

interface Global {
openctx?: {
vscode?: typeof vscode
}
}

export function initializeOpenCtxGlobal() {
initializeGlobal(global as Global)
}

function initializeGlobal(global: Global) {
if (!global.openctx) {
global.openctx = { vscode }
}
global.openctx.vscode = vscode
}
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions provider/linear-issues/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ async function getAccessToken(settings: Settings): Promise<string> {
return userCredentials.access_token
}

const vscodeAccessToken = await getAccessTokenLinearConnect()
if (vscodeAccessToken) {
return vscodeAccessToken
}

throw new Error(
'must provide a Linear user credentials path in the `userCredentialsPath` settings field or an accessToken in the linearClientOptions'
)
Expand Down Expand Up @@ -157,6 +162,53 @@ async function linearApiRequest(
return json
}

const LINEAR_AUTHENTICATION_EXTENSION_ID = 'linear.linear-connect'
const LINEAR_AUTHENTICATION_PROVIDER_ID = 'linear'
const LINEAR_AUTHENTICATION_SCOPES = ['read']

function vscodeAPI() {
// dynamic imports don't work in node + vscode due
// https://github.com/microsoft/vscode-loader/issues/36 vscode-lib however
// will sneakily set the vscode import to a global for us.
if (!('openctx' in global)) {
return undefined
}
const openctx = (global as any).openctx
if (!openctx.vscode) {
return undefined
}
return openctx.vscode as typeof import('vscode')
}

async function getAccessTokenLinearConnect(): Promise<string | undefined> {
const vscode = vscodeAPI()
if (!vscode) {
return undefined
}

const ext = vscode.extensions.getExtension(LINEAR_AUTHENTICATION_EXTENSION_ID)
if (!ext) {
vscode.window.showWarningMessage(
'Cody requires the Linear Connect extension to be installed and activated.'
)
await vscode.commands.executeCommand('workbench.extensions.action.showExtensionsWithIds', [
[LINEAR_AUTHENTICATION_EXTENSION_ID],
])
}

const session = await vscode.authentication.getSession(
LINEAR_AUTHENTICATION_PROVIDER_ID,
LINEAR_AUTHENTICATION_SCOPES,
{ createIfNone: true }
)

if (!session) {
throw new Error(`We weren't able to log you into Linear when trying to open the issue.`)
}

return session.accessToken
}

function parseIssueIDFromURL(urlStr: string): string | undefined {
const url = new URL(urlStr)
if (!url.hostname.endsWith('linear.app')) {
Expand Down
7 changes: 4 additions & 3 deletions provider/linear-issues/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openctx/provider-linear-issues",
"version": "0.0.3",
"version": "0.0.4",
"description": "Linear Issues context for code AI and editors (OpenCtx provider)",
"license": "Apache-2.0",
"repository": {
Expand All @@ -19,7 +19,7 @@
"scripts": {
"build": "tsc --build",
"bundle:watch": "pnpm run bundle --watch",
"bundle": "esbuild --main-fields=module,main --log-level=error --platform=node --bundle --format=esm --outfile=dist/bundle.js index.ts",
"bundle": "esbuild --main-fields=module,main --external:vscode --log-level=error --platform=node --bundle --format=esm --outfile=dist/bundle.js index.ts",
"prepublishOnly": "tsc --build --clean && pnpm run --silent bundle",
"test": "vitest",
"auth": "node --no-warnings=ExperimentalWarning --es-module-specifier-resolution=node --loader ts-node/esm/transpile-only auth.ts"
Expand All @@ -32,6 +32,7 @@
"server-destroy": "^1.0.1"
},
"devDependencies": {
"@types/server-destroy": "^1.0.3"
"@types/server-destroy": "^1.0.3",
"@types/vscode": "^1.85.0"
}
}

0 comments on commit b9c1231

Please sign in to comment.