diff --git a/CHANGELOG.md b/CHANGELOG.md index 06bd42a..d9e5230 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file. ### Changed +- Move image sources and actors into a dedicated Runa Activity Bar sidebar, + with the source file tree first and both views visible by default. - Remove the VS Code Add Source Folder to Workspace command; image files are accessed exclusively through the automatic image-source Explorer view. - Show the image's editable virtual `source` filesystem automatically in the diff --git a/README.md b/README.md index 751dad0..de2c542 100644 --- a/README.md +++ b/README.md @@ -168,12 +168,13 @@ the runtime contract. With Node.js 22+ and npm installed, run `npm --prefix vscode ci`. In VS Code, open this repository and launch **Run Runa Extension** from Run and Debug (F5). Start `mise run start`, then use **Runa: Connect to Local Image** -in the Extension Development Host. The **Runa Actors** view in Explorer lists +in the Extension Development Host. Open the **Runa** Activity Bar sidebar. +Its **Actors** view lists actors created through the REPL or another client. Click an actor to inspect it. Server notifications automatically refresh the tree and open snapshots; **Runa: Refresh Image** is also available on demand. -The **Runa Image Sources** Explorer view automatically shows the image's virtual +The **Image Sources** view in the Runa sidebar automatically shows the image's virtual filesystem beneath **source**, including `actors/counter.rn`, without adding a workspace folder. Open a file and save edits to update the image without committing. Right-click a source file to **Spawn** (null state) or **Spawn with diff --git a/docs/protocol.md b/docs/protocol.md index dc72be4..4fd780c 100644 --- a/docs/protocol.md +++ b/docs/protocol.md @@ -141,7 +141,7 @@ The stdio transport and child-process client have been removed. The TypeScript VS Code client issues `list_actors`, `inspect_actor`, source file/version-control operations, `spawn`, `send`, `tick`, and `system`. VS Code automatically displays writable image files under a `source` directory -in its image-source Explorer tree, without modifying workspace folders, +in its dedicated Runa sidebar's source tree, without modifying workspace folders, and caches read-only commit documents by connection, path, and revision. It preserves i64 inputs and bounds the complete outgoing envelope as well as incoming messages. It enforces loopback endpoints, bounded UTF-8 text messages, diff --git a/vscode/README.md b/vscode/README.md index 248d5bf..ce9bdc7 100644 --- a/vscode/README.md +++ b/vscode/README.md @@ -24,11 +24,11 @@ In that host: 1. Run **Runa: Connect to Local Image**. The default is `127.0.0.1:3737`; `runa.address` changes the suggested endpoint. -2. The **Runa Image Sources** Explorer view automatically shows the image's +2. Open **Runa** in the Activity Bar. Its **Image Sources** view automatically shows the image's `source` directory (see [Image source files](#image-source-files)). Right-click a `.rn` file and choose **Spawn** (initial state `null`) or **Spawn with State...** (enter JSON in the input field, for example `0` for - `actors/counter`). **Runa: Spawn Actor** in **Runa Actors** prompts for a source + `actors/counter`). **Runa: Spawn Actor** in **Actors** prompts for a source path and state. The command reports and returns the new actor reference. Mailbox capacity is 64. 3. Click an actor or run **Runa: Inspect Actor** to open its JSON snapshot. @@ -98,13 +98,18 @@ in the Runa output channel and an error notification; commands are never retried ## Image source files -The image owns actor source text. On connect, **Runa Image Sources** automatically +The dedicated **Runa** Activity Bar sidebar contains **Image Sources** first, +followed by **Actors**. Both views are visible by default and do not require +an open workspace. The source tree uses native VS Code tree items, file icons, +directory expansion, editor opening, and file context menus. + +The image owns actor source text. On connect, **Image Sources** automatically shows its virtual filesystem beneath `source` (`runa-image:///source`). No workspace changes, folder prompt, or extension restart is required. Opening a file reads it from the image; saving writes back to the image. The extension never adds image folders to the workspace. VS Code's public API does not support overlaying virtual files onto the built-in workspace file tree, -so image files appear in their own Explorer view backed by the filesystem provider. +so image files appear in the Runa sidebar's source tree backed by the filesystem provider. Directories are derived from source paths: `actors/counter` appears as `source/actors/counter.rn`. Source paths are canonical and exclude the `source/` prefix and `.rn` suffix. diff --git a/vscode/integration/host.ts b/vscode/integration/host.ts index d645339..2352ae5 100644 --- a/vscode/integration/host.ts +++ b/vscode/integration/host.ts @@ -7,6 +7,22 @@ export async function run(): Promise { const image = await startImage(); const folders = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.toString()); try { + const extension = vscode.extensions.all.find( + (candidate) => candidate.packageJSON.name === "runa", + ); + assert.ok(extension); + const contributions = extension.packageJSON.contributes; + assert.ok( + contributions.viewsContainers.activitybar.some( + (container: { id: string }) => container.id === "runa", + ), + ); + assert.deepEqual( + contributions.views.runa.map((view: { id: string }) => view.id), + ["runa.sources", "runa.actors"], + ); + assert.equal(contributions.views.explorer, undefined); + await vscode.commands.executeCommand("workbench.view.extension.runa"); await vscode.commands.executeCommand("runa.connect", image.address); assert.ok(!(await vscode.commands.getCommands(true)).includes("runa.addSourceFolder")); assert.deepEqual( @@ -308,7 +324,7 @@ async function editSources(address: string): Promise { await vscode.commands.executeCommand("runa.connect", address); assert.equal( vscode.workspace.workspaceFolders?.filter((candidate) => candidate.uri.scheme === "runa-image") - .length, + .length ?? 0, 0, ); const reopened = await vscode.commands.executeCommand( diff --git a/vscode/package.json b/vscode/package.json index 3c87a86..3477b17 100644 --- a/vscode/package.json +++ b/vscode/package.json @@ -153,15 +153,26 @@ "icon": "$(inspect)" } ], - "views": { - "explorer": [ + "viewsContainers": { + "activitybar": [ { - "id": "runa.actors", - "name": "Runa Actors" - }, + "id": "runa", + "title": "Runa", + "icon": "resources/runa.svg" + } + ] + }, + "views": { + "runa": [ { "id": "runa.sources", - "name": "Runa Image Sources" + "name": "Image Sources", + "visibility": "visible" + }, + { + "id": "runa.actors", + "name": "Actors", + "visibility": "visible" } ] }, diff --git a/vscode/resources/runa.svg b/vscode/resources/runa.svg new file mode 100644 index 0000000..e421e3d --- /dev/null +++ b/vscode/resources/runa.svg @@ -0,0 +1,3 @@ + + + diff --git a/vscode/scripts/test-host.cjs b/vscode/scripts/test-host.cjs index 8f21bfb..5498418 100644 --- a/vscode/scripts/test-host.cjs +++ b/vscode/scripts/test-host.cjs @@ -1,23 +1,12 @@ const path = require("node:path"); -const fs = require("node:fs"); const { runTests } = require("@vscode/test-electron"); -// Adding the image source folder to an empty or single-folder window restarts the -// extension host, so tests start in a multi-root workspace with one local folder. -const root = path.resolve(__dirname, ".."); -const workspaceFile = path.join(root, ".vscode-test", "runa-host.code-workspace"); -fs.mkdirSync(path.dirname(workspaceFile), { recursive: true }); -fs.writeFileSync( - workspaceFile, - JSON.stringify({ folders: [{ path: path.join(root, "integration") }] }, null, 2), -); - runTests({ version: "1.96.4", extensionDevelopmentPath: path.resolve(__dirname, ".."), extensionTestsPath: path.resolve(__dirname, "../out/integration/host.js"), launchArgs: [ - workspaceFile, + "--new-window", "--disable-gpu", "--no-sandbox", "--skip-welcome",