feat: add a dedicated Runa sidebar
Move the image source tree and actor view into a Runa Activity Bar container with sources first. Verify both views and image editing in an empty VS Code window without workspace folders. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
f1a2aab789
commit
7e3af6e501
|
|
@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
### Changed
|
### 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
|
- Remove the VS Code Add Source Folder to Workspace command; image files are
|
||||||
accessed exclusively through the automatic image-source Explorer view.
|
accessed exclusively through the automatic image-source Explorer view.
|
||||||
- Show the image's editable virtual `source` filesystem automatically in the
|
- Show the image's editable virtual `source` filesystem automatically in the
|
||||||
|
|
|
||||||
|
|
@ -168,12 +168,13 @@ the runtime contract.
|
||||||
With Node.js 22+ and npm installed, run `npm --prefix vscode ci`. In VS Code,
|
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
|
open this repository and launch **Run Runa Extension** from Run and Debug
|
||||||
(F5). Start `mise run start`, then use **Runa: Connect to Local Image**
|
(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
|
actors created through the REPL or another client. Click an actor to inspect
|
||||||
it. Server notifications automatically refresh the tree and open snapshots;
|
it. Server notifications automatically refresh the tree and open snapshots;
|
||||||
**Runa: Refresh Image** is also available on demand.
|
**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
|
filesystem beneath **source**, including `actors/counter.rn`, without adding a
|
||||||
workspace folder. Open a file and save edits to update the image without
|
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
|
committing. Right-click a source file to **Spawn** (null state) or **Spawn with
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ The stdio transport and child-process client have been removed.
|
||||||
The TypeScript VS Code client issues `list_actors`, `inspect_actor`,
|
The TypeScript VS Code client issues `list_actors`, `inspect_actor`,
|
||||||
source file/version-control operations, `spawn`, `send`, `tick`, and `system`.
|
source file/version-control operations, `spawn`, `send`, `tick`, and `system`.
|
||||||
VS Code automatically displays writable image files under a `source` directory
|
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.
|
and caches read-only commit documents by connection, path, and revision.
|
||||||
It preserves i64 inputs and bounds the complete outgoing envelope as well as
|
It preserves i64 inputs and bounds the complete outgoing envelope as well as
|
||||||
incoming messages. It enforces loopback endpoints, bounded UTF-8 text messages,
|
incoming messages. It enforces loopback endpoints, bounded UTF-8 text messages,
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,11 @@ In that host:
|
||||||
|
|
||||||
1. Run **Runa: Connect to Local Image**. The default is `127.0.0.1:3737`;
|
1. Run **Runa: Connect to Local Image**. The default is `127.0.0.1:3737`;
|
||||||
`runa.address` changes the suggested endpoint.
|
`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)).
|
`source` directory (see [Image source files](#image-source-files)).
|
||||||
Right-click a `.rn` file and choose **Spawn** (initial state `null`) or
|
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
|
**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.
|
path and state. The command reports and returns the new actor reference.
|
||||||
Mailbox capacity is 64.
|
Mailbox capacity is 64.
|
||||||
3. Click an actor or run **Runa: Inspect Actor** to open its JSON snapshot.
|
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
|
## 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://<endpoint>/source`).
|
shows its virtual filesystem beneath `source` (`runa-image://<endpoint>/source`).
|
||||||
No workspace changes, folder prompt, or extension restart is required.
|
No workspace changes, folder prompt, or extension restart is required.
|
||||||
Opening a file reads it from the image; saving writes back to the image.
|
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
|
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,
|
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
|
Directories are derived from
|
||||||
source paths: `actors/counter` appears as `source/actors/counter.rn`. Source
|
source paths: `actors/counter` appears as `source/actors/counter.rn`. Source
|
||||||
paths are canonical and exclude the `source/` prefix and `.rn` suffix.
|
paths are canonical and exclude the `source/` prefix and `.rn` suffix.
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,22 @@ export async function run(): Promise<void> {
|
||||||
const image = await startImage();
|
const image = await startImage();
|
||||||
const folders = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.toString());
|
const folders = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.toString());
|
||||||
try {
|
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);
|
await vscode.commands.executeCommand("runa.connect", image.address);
|
||||||
assert.ok(!(await vscode.commands.getCommands(true)).includes("runa.addSourceFolder"));
|
assert.ok(!(await vscode.commands.getCommands(true)).includes("runa.addSourceFolder"));
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
|
|
@ -308,7 +324,7 @@ async function editSources(address: string): Promise<void> {
|
||||||
await vscode.commands.executeCommand("runa.connect", address);
|
await vscode.commands.executeCommand("runa.connect", address);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
vscode.workspace.workspaceFolders?.filter((candidate) => candidate.uri.scheme === "runa-image")
|
vscode.workspace.workspaceFolders?.filter((candidate) => candidate.uri.scheme === "runa-image")
|
||||||
.length,
|
.length ?? 0,
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
const reopened = await vscode.commands.executeCommand<string>(
|
const reopened = await vscode.commands.executeCommand<string>(
|
||||||
|
|
|
||||||
|
|
@ -153,15 +153,26 @@
|
||||||
"icon": "$(inspect)"
|
"icon": "$(inspect)"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"views": {
|
"viewsContainers": {
|
||||||
"explorer": [
|
"activitybar": [
|
||||||
{
|
{
|
||||||
"id": "runa.actors",
|
"id": "runa",
|
||||||
"name": "Runa Actors"
|
"title": "Runa",
|
||||||
},
|
"icon": "resources/runa.svg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"views": {
|
||||||
|
"runa": [
|
||||||
{
|
{
|
||||||
"id": "runa.sources",
|
"id": "runa.sources",
|
||||||
"name": "Runa Image Sources"
|
"name": "Image Sources",
|
||||||
|
"visibility": "visible"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "runa.actors",
|
||||||
|
"name": "Actors",
|
||||||
|
"visibility": "visible"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#C5C5C5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M7 21V3l10 6-10 5 10 7"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 223 B |
|
|
@ -1,23 +1,12 @@
|
||||||
const path = require("node:path");
|
const path = require("node:path");
|
||||||
const fs = require("node:fs");
|
|
||||||
const { runTests } = require("@vscode/test-electron");
|
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({
|
runTests({
|
||||||
version: "1.96.4",
|
version: "1.96.4",
|
||||||
extensionDevelopmentPath: path.resolve(__dirname, ".."),
|
extensionDevelopmentPath: path.resolve(__dirname, ".."),
|
||||||
extensionTestsPath: path.resolve(__dirname, "../out/integration/host.js"),
|
extensionTestsPath: path.resolve(__dirname, "../out/integration/host.js"),
|
||||||
launchArgs: [
|
launchArgs: [
|
||||||
workspaceFile,
|
"--new-window",
|
||||||
"--disable-gpu",
|
"--disable-gpu",
|
||||||
"--no-sandbox",
|
"--no-sandbox",
|
||||||
"--skip-welcome",
|
"--skip-welcome",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue