Skip to content

Commit c3ea379

Browse files
Copilotpelikhan
andauthored
Fix env.files not populated when selecting folders in VS Code extension (#1915)
* Initial plan * Fix env.files not populated for folder selection in VS Code Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * Fix haiku generation to handle multiple files in environment variable * Refactor type annotations and improve file URI handling in runScriptInternal and VSCodeHost --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Co-authored-by: Peli de Halleux <pelikhan@users.noreply.github.com>
1 parent 66e5c7e commit c3ea379

File tree

5 files changed

+29
-22
lines changed

5 files changed

+29
-22
lines changed

demo/genaisrc/haiku.genai.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
script({ model: "github_copilot_chat:gpt-4.1", metadata: { name: "haiku" } })
2-
$`Write a haiku about ${env.files[0] || "code"}`
2+
$`Write a haiku about ${env.files || "code"}`

packages/api/src/run.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ import {
103103
createGitIgnorer,
104104
resolveRuntimeHost,
105105
} from "@genaiscript/core";
106+
import { fileURLToPath } from "node:url";
106107

107108
const dbg = genaiscriptDebug("run");
108109

@@ -315,10 +316,12 @@ export async function runScriptInternal(
315316
);
316317
files = files.filter((f) => !NEGATIVE_GLOB_REGEX.test(f));
317318
dbg(`files (remaining): %O`, files);
318-
for (let arg of files) {
319+
for (let fileOrUri of files) {
320+
let arg = /^file:\/\//.test(fileOrUri) ? fileURLToPath(fileOrUri) : fileOrUri;
319321
checkCancelled(cancellationToken);
320322
dbg(`resolving ${arg}`);
321323
const stat = await runtimeHost.statFile(arg);
324+
dbg(`stat type: %s`, stat?.type);
322325
if (stat?.type === "file") {
323326
dbg(`file found %s`, arg);
324327
if (ignorer && !ignorer([arg]).length) {
@@ -756,7 +759,7 @@ export async function runScriptInternal(
756759
// Generate title (simple approach for now, can be enhanced with small model later)
757760
const firstLine = result.text.split("\n")[0]?.trim();
758761
const shortContent = firstLine ? firstLine.substring(0, 60) : "";
759-
let title = shortContent ? `${script.id}: ${shortContent}` : `Generated by ${script.id}`;
762+
const title = shortContent ? `${script.id}: ${shortContent}` : `Generated by ${script.id}`;
760763

761764
// TODO: Enhance with small model title generation
762765
// This could be implemented by creating a temporary script and running it with the small model,

packages/vscode/src/servermanager.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export class TerminalServerManager extends EventTarget implements ServerManager
8181
);
8282
}
8383

84-
private dispatchChange() {
84+
private dispatchChange(): void {
8585
this.dispatchEvent(new Event(CHANGE));
8686
}
8787

@@ -91,44 +91,45 @@ export class TerminalServerManager extends EventTarget implements ServerManager
9191
return this._startClientPromise || (this._startClientPromise = this.startClient());
9292
}
9393

94-
get authority() {
94+
get authority(): string {
9595
if (!this._port) return undefined;
9696
return `${SERVER_LOCALHOST}:${this._port}`;
9797
}
9898

99-
get url() {
99+
get url(): string {
100100
return this.state.sessionApiKey
101101
? `${this.authority}?api-key=${encodeURIComponent(this.state.sessionApiKey)}`
102102
: this.authority;
103103
}
104104

105-
get browserUrl() {
105+
get browserUrl(): string {
106106
return this.state.sessionApiKey
107107
? `${this.authority}#api-key=${encodeURIComponent(this.state.sessionApiKey)}`
108108
: this.authority;
109109
}
110110

111-
private async allocatePort() {
111+
private async allocatePort(): Promise<number> {
112112
if (isNaN(this._port)) this._port = await findRandomOpenPort();
113113
return this._port;
114114
}
115115

116-
get version() {
116+
get version(): string {
117117
return this._version;
118118
}
119119

120120
private async startClient(): Promise<VsCodeClient> {
121121
if (this._client) throw new Error("client already started");
122122
await this.allocatePort();
123123
const url = this.url;
124-
const authority = (await vscode.env.asExternalUri(vscode.Uri.parse(this.authority))).toString();
124+
const authorityUri = await vscode.env.asExternalUri(vscode.Uri.parse(this.authority));
125+
const authority = authorityUri.toString();
125126
const externalUrl =
126127
authority +
127128
(this.state.sessionApiKey ? `#api-key=${encodeURIComponent(this.state.sessionApiKey)}` : "");
128129
logInfo(`client url: ${url}`);
129130
logVerbose(`client external url: ${externalUrl}`);
130131
const client = (this._client = new VsCodeClient(url, externalUrl, authority));
131-
client.chatRequest = createChatModelRunner(this.state);
132+
client.chatRequest = createChatModelRunner(this.state);
132133
client.addEventListener(OPEN, async () => {
133134
if (client !== this._client) return;
134135
this._terminalStartAttempts = 0;
@@ -162,7 +163,7 @@ export class TerminalServerManager extends EventTarget implements ServerManager
162163
return this._client;
163164
}
164165

165-
private clearTerminalStartWatcher() {
166+
private clearTerminalStartWatcher(): void {
166167
if (this._terminalStartWatcher) {
167168
// eslint-disable-next-line @typescript-eslint/no-explicit-any
168169
clearTimeout(this._terminalStartWatcher as any);
@@ -300,7 +301,7 @@ export class TerminalServerManager extends EventTarget implements ServerManager
300301
}
301302
}
302303

303-
async close() {
304+
async close(): Promise<void> {
304305
try {
305306
this.status = "stopping";
306307
this._startClientPromise = undefined;
@@ -311,12 +312,12 @@ export class TerminalServerManager extends EventTarget implements ServerManager
311312
}
312313
}
313314

314-
async show(preserveFocus?: boolean) {
315+
async show(preserveFocus?: boolean): Promise<void> {
315316
if (!this._terminal) await this.start();
316317
this._terminal?.show(preserveFocus);
317318
}
318319

319-
private closeTerminal() {
320+
private closeTerminal(): void {
320321
const t = this._terminal;
321322
this._port = undefined;
322323
this._terminal = undefined;
@@ -326,7 +327,7 @@ export class TerminalServerManager extends EventTarget implements ServerManager
326327
if (!this.state.diagnostics) t?.dispose();
327328
}
328329

329-
dispose() {
330+
dispose(): void {
330331
this.close();
331332
}
332333
}

packages/vscode/src/state.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ export class ExtensionState extends EventTarget {
398398
return p;
399399
}
400400

401-
private async uncachedParseWorkspace() {
401+
private async uncachedParseWorkspace(): Promise<void> {
402402
try {
403403
logVerbose(`parse workspace`);
404404
this.dispatchChange();

packages/vscode/src/vshost.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,17 @@ export class VSCodeHost extends EventTarget implements Host {
111111
const uri = this.toProjectFileUri(name);
112112
await vscode.workspace.fs.writeFile(uri, content);
113113
}
114-
private toProjectFileUri(name: string) {
114+
private toProjectFileUri(name: string): vscode.Uri {
115115
const wksrx = /^workspace:\/\//i;
116+
const fileUriRx = /^file:\/\//i;
116117
const uri = wksrx.test(name)
117118
? Utils.joinPath(vscode.workspace.workspaceFolders[0].uri, name.replace(wksrx, ""))
118-
: /^(\/|\w:\\)/i.test(name) ||
119-
name.startsWith(vscode.workspace.workspaceFolders[0].uri.fsPath)
120-
? Uri.file(name)
121-
: Utils.joinPath(vscode.workspace.workspaceFolders[0].uri, name);
119+
: fileUriRx.test(name)
120+
? vscode.Uri.parse(name, true)
121+
: /^(\/|\w:\\)/i.test(name) ||
122+
name.startsWith(vscode.workspace.workspaceFolders[0].uri.fsPath)
123+
? Uri.file(name)
124+
: Utils.joinPath(vscode.workspace.workspaceFolders[0].uri, name);
122125
return uri;
123126
}
124127

0 commit comments

Comments
 (0)