Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9babcbc
ci: remove Dependabot version updates
oddessentials Nov 6, 2026
d3a9129
fix(deps): update ws to 8.22.1 and markdown-it to 15.0.3
oddessentials Nov 6, 2026
096c534
fix(deps): update the Yard engine to three r187
oddessentials Nov 6, 2026
9472d42
ci: update the release tooling lockfile for audit fixes
oddessentials Nov 6, 2026
66985b1
fix: draw the Grove Yard's install button as live text, like the Play…
oddessentials Nov 6, 2026
7614c56
feat: add a Play now button for Agent Guild: Arena to the Guild Yard
oddessentials Nov 6, 2026
6591361
feat: add an Install now button for Agent Guild: Builders to the Prof…
oddessentials Nov 6, 2026
e64538a
feat: replace a Yard's surroundings with a world file
oddessentials Nov 6, 2026
1a383c6
fix: call the Yard's Builders link Build a world
oddessentials Nov 6, 2026
4ca4273
fix: offer Replace only where a manager can install a world
oddessentials Nov 6, 2026
41e5ae0
fix: keep worlds valid when a tool's hall is added
oddessentials Nov 6, 2026
3f27acd
test: check the Yard's world spot with all three of its buttons
oddessentials Nov 6, 2026
b57c2ae
feat: offer the Yard's games and companions on the Terminal AI Chat card
oddessentials Nov 6, 2026
4cabe41
fix: name the games on Orbital's game menu button
oddessentials Nov 6, 2026
c63b698
fix: keep the Yard's world state true when a load or file operation i…
oddessentials Nov 6, 2026
ef7d3b4
fix: read the Grove button's own state instead of a shared helper
oddessentials Nov 6, 2026
18f0006
test: run only the dialog check's own engine in each CI job
oddessentials Nov 6, 2026
3a13aa5
fix: accept only the sky Builders writes, and keep the card's game me…
oddessentials Nov 7, 2026
430223f
fix: keep an open card menu in view when the window resizes
oddessentials Nov 7, 2026
a45bdef
feat: stamp BETA on the Professional Yard's Builders button
oddessentials Nov 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions .github/dependabot.yml

This file was deleted.

78 changes: 39 additions & 39 deletions .github/release/package-lock.json

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

8 changes: 6 additions & 2 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ All paths are under `/api/v1`.
| GET | `/remote-access` | | `{ remoteAccess }`: `revision`, `mode`, `busy`, `pending`, `problem` and connection details. `url` is the active address. `candidate` is the address enabling would use with Tailscale's current settings, `{ url, existing, remembered, standardUrl? }`: `remembered` when it is the address used before, and `standardUrl` when `standard: true` would choose another. |
| POST | `/remote-access/check` | | `{ remoteAccess }` after refreshing Tailscale's status. |
| PUT | `/remote-access` | `{ revision, action, adopt?, hosts?, origins? }` | `202`. `action` is `enable` (`adopt: true` manages a matching existing route; `standard: true`, only while remote access is off, skips the remembered address and takes port 443, else the next free port), `disable`, `custom` (with `hosts` and `origins`) or `forget` (leave an inactive route awaiting cleanup in Tailscale). Poll until `busy` is null and read `problem`. 409 `stale_settings` for an old `revision`. Needs the API token. Revoked WebSockets close with code 4403; their terminals keep running. |
| GET | `/folders?path=` | | `{ path, parent, home, segments, roots, entries, truncated, note }`: the subfolders of `path` (blank or `~` for the home folder). `entries` are `{ name, path, hidden }`. A missing `path` lists the nearest folder above it and names the requested path in `note`. |
| GET | `/folders?path=&files=` | | `{ path, parent, home, segments, roots, entries, truncated, note }`: the subfolders of `path` (blank or `~` for the home folder). `entries` are `{ name, path, hidden }`. A missing `path` lists the nearest folder above it and names the requested path in `note`. `files=agworld` adds `files`, the world files in that folder, each `{ name, path }`. |
| POST | `/folders` | `{ path, name }` | 201 with the `GET /folders` listing of the new folder `name`, made inside `path`. |
| GET | `/autostart` | | `{ autostart: { available, enabled, reason, note?, lastRun?, log? } }`: whether the manager starts when the user signs in. `reason` says why it is unavailable. `lastRun` is null or `{ at, outcome }`. On Linux outside WSL it also has `mode` (`off`, `sign-in`, `boot` or `both`) and `boot`, the systemd service's `{ available, enabled, reason, note, user, linger, state, commands }`. |
| PUT | `/autostart` | `{ enabled }` or `{ mode }` | `{ autostart }` as above. `mode` (`off`, `sign-in` or `boot`) makes that the one way the manager starts; `boot` is offered only on Linux with systemd. |
Expand Down Expand Up @@ -666,6 +666,9 @@ All paths are under `/api/v1`.
| GET | `/yard-art` | | `{ yardArt }`: the Yard's art. `state` is `ready`, `missing`, `downloading` (with `received` bytes), `installing`, `failed` or `unavailable` (each with `error`), or `cancelled`; `size` is the pack's size in bytes. A checkout serves `web/yard/assets` and is always `ready`. `/yard/assets/` answers 404 until the art is `ready`. |
| POST | `/yard-art/download` | | `202 { yardArt }`: starts the one download of the art pack named by the package, unless it is running or installed. Progress and the outcome arrive as `yard-art.updated`. |
| POST | `/yard-art/cancel` | | `{ yardArt }`: stops the download for every client; the state becomes `cancelled`. |
| GET | `/yard-worlds` | | `{ yardWorlds }`: the world replacing each Yard, by skin. A world is `{ title, revision, lights }`, or `{ title, problem }` when it cannot be used, in which case the Yard shows its original. A Yard with no entry shows its original. |
| PUT | `/yard-worlds/:skin` | `{ path }` | `{ yardWorlds }`: checks the `.agworld` file at `path` on the manager's computer and makes it this Yard's world, replacing any before it. 400 `world_invalid` says what is wrong and leaves the Yard unchanged; 404 `unknown_yard`; 409 `world_busy` while another install runs; 409 `worlds_unsupported` without a data folder; 500 `world_unwritable`. Its plates and skies are served at `/yard/worlds/:skin/:file`. |
| DELETE | `/yard-worlds/:skin` | | `{ yardWorlds }`: deletes this Yard's world, so it shows its original. |
| POST | `/companion/install` | | `201 { session }`: starts a session that downloads the latest Grove Companion, checks its signature, installs it and starts it. 400 `companion_unsupported` unless the manager runs on Windows or macOS; 409 `install_in_progress` while one runs. |
| POST | `/yard/fireworks` | | `{ ok, pages }`: fireworks over the Yard of every open page, sent as `yard.fireworks`. `pages` is how many pages were listening. |
| GET | `/changelog` | | `{ refreshing, okAt, error, releases }`: Agent Guild's own releases, newest first, each `{ version, url, publishedAt, sections: [{ title, changes }] }`, where `title` may be null and a change is a list of text runs. A `changelog.updated` event follows a refresh. |
Expand Down Expand Up @@ -743,14 +746,15 @@ but `{ type: "ping" }`, which the manager answers with `{ type: "pong" }`.

| Message | Meaning |
| --- | --- |
| `{ type: "hello", version, pid, platform, startedAt, launcher, folderOpener, remoteAccess, upgrade, yardArt, sessions, heartbeat, notesRevision, notesUnreadable }` | Sent first: the manager (as in `/info`), the full session list and the notepad's revision. |
| `{ type: "hello", version, pid, platform, startedAt, launcher, folderOpener, remoteAccess, upgrade, yardArt, yardWorlds, sessions, heartbeat, notesRevision, notesUnreadable }` | Sent first: the manager (as in `/info`), the full session list and the notepad's revision. |
| `{ type: "session.created", session }` | A session was started by any client. |
| `{ type: "session.updated", session }` | Status, activity, agents, name or size changed. |
| `{ type: "session.removed", sessionId }` | A session was removed. |
| `{ type: "providers.updated", providers, revision }` | The provider list changed. |
| `{ type: "environment.updated", environment }` | An environment check started or finished. |
| `{ type: "news.updated" }` | Fetch `/news` again. |
| `{ type: "yard-art.updated", yardArt }` | The Yard's art changed state or made download progress, as in `/yard-art`. |
| `{ type: "yard-worlds.updated", yardWorlds }` | A Yard's world was replaced or deleted, as in `/yard-worlds`. |
| `{ type: "yard.fireworks" }` | Fireworks over the Yard, when it is on show. |
| `{ type: "changelog.updated" }` | Fetch `/changelog` again. |
| `{ type: "github.updated" }` | Fetch `/github` again. |
Expand Down
4 changes: 2 additions & 2 deletions docs/yard/fixture.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { randomBytes } from 'node:crypto';
import { fileURLToPath } from 'node:url';
import { createManagerServer } from '../../src/manager/server.mjs';

export async function startFixture({port=0,yardArt}={}) {
export async function startFixture({port=0,yardArt,yardWorlds}={}) {
const calls=[],data=new Map(),terminals=new Map();
let next=16;
const now=()=>new Date().toISOString();
Expand Down Expand Up @@ -96,7 +96,7 @@ export async function startFixture({port=0,yardArt}={}) {
agents:i===0?[{id:'a1',name:'Explorer',status:'working',detail:'Reading the project'},{id:'a2',name:'Reviewer',status:'waiting',detail:'Waiting for input'}]:i===1?[{id:'a3',name:'Designer',status:'working'}]:[],
shells:i===4?[{id:'sh1'}]:[]},false));
const token=randomBytes(24).toString('hex');
const api=createManagerServer({manager,registry,usage,history,modelStats,news,changelog,github,selfUpdate,token,port,webDir:fileURLToPath(new URL('../../web',import.meta.url)),version:'1.0.0',...(yardArt?{yardArt}:{}),
const api=createManagerServer({manager,registry,usage,history,modelStats,news,changelog,github,selfUpdate,token,port,webDir:fileURLToPath(new URL('../../web',import.meta.url)),version:'1.0.0',...(yardArt?{yardArt}:{}),...(yardWorlds?{yardWorlds}:{}),
onShutdownRequest:({restart})=>{calls.push(['shutdown',restart]);manager.emit('event',{type:'manager.stopped',remaining:0,restart});if(restart){data.clear();manager.closing=false;setTimeout(()=>manager.emit('event',{type:'hello',version:'1.1.0',pid:process.pid,sessions:[],upgrade:null}),100);}}
});
await api.listen();
Expand Down
Loading
Loading