@oddessentials/agent-guild 1.9.1 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,34 +1,23 @@
1
- <p align="center">
2
- <img src="docs/images/banner.webp" alt="Agent Guild: Work hard, play hard. An agentic UI that enhances instead of hinders." width="100%">
3
- </p>
1
+ <h1 align="center">Agent Guild</h1>
4
2
 
5
3
  <p align="center">
6
4
  <a href="https://www.npmjs.com/package/@oddessentials/agent-guild"><img src="https://img.shields.io/npm/v/@oddessentials/agent-guild?color=7c5cff&label=npm" alt="npm version"></a>
7
5
  <a href="https://github.com/oddessentials/agent-guild/actions/workflows/release.yml"><img src="https://img.shields.io/github/actions/workflow/status/oddessentials/agent-guild/release.yml?branch=main&label=release" alt="Release status"></a>
8
6
  <img src="https://img.shields.io/badge/platforms-Windows%20%7C%20macOS%20%7C%20Linux-e8c47c" alt="Windows, macOS and Linux">
9
7
  <img src="https://img.shields.io/node/v/@oddessentials/agent-guild?color=4cc38a" alt="Node.js version">
10
- <a href="https://www.youtube.com/watch?v=ziT62WtXQ1M"><img src="https://img.shields.io/badge/trailer-watch%20on%20YouTube-e5534b?logo=youtube&logoColor=white" alt="Watch the Agent Guild trailer on YouTube"></a>
11
- <a href="https://agentguild.oddessentials.ai/"><img src="https://img.shields.io/badge/Agent%20Guild%3A%20World-coming%20soon%20to%20Steam-1b2838?logo=steam&logoColor=white" alt="Agent Guild: World, coming soon to Steam"></a>
12
- <a href="https://oddessentials.ai/donate/?ref=agent-guild"><img src="https://img.shields.io/badge/support-buy%20the%20lab%20a%20beer-f2a93b" alt="Support Agent Guild: buy the lab a beer"></a>
13
- </p>
14
-
15
- <p align="center">
16
- <picture>
17
- <source media="(prefers-reduced-motion: reduce)" srcset="docs/images/yard-still.webp">
18
- <img src="docs/images/yard-clip.webp" alt="Seven coding-agent sessions as characters in the Guild Yard: they leave the plaza for their tools' halls and get to work, then a double-click on one opens Claude Code's real terminal, with its three helper agents" width="100%">
19
- </picture>
20
8
  </p>
21
9
 
22
- **Every coding agent you run becomes a character in a 3D world, and stays a
23
- real terminal one double-click away.**
10
+ **Run Claude Code, Codex CLI, Antigravity CLI, Grok Build, Docker Agent and
11
+ your own shells side by side in real terminals. Pick the same live sessions up
12
+ from your phone, VS Code or any browser. Free, on Windows, macOS and Linux.**
24
13
 
25
- **Agent Guild** runs Claude Code, Codex CLI, Antigravity CLI, Grok Build,
26
- Docker Agent and your own shell side by side, in real terminals, from one
27
- local web page, or from your phone over Tailscale.
28
- Close the page whenever you like; the sessions keep running.
14
+ Agent Guild is a small manager that runs on your computer and serves one
15
+ local web page. Close the page whenever you like; the sessions keep running.
29
16
 
30
- [Try the demo](https://oddessentials.github.io/agent-guild/) in your browser
31
- (simulated, nothing installed) or [watch the trailer](https://www.youtube.com/watch?v=ziT62WtXQ1M).
17
+ <picture>
18
+ <source media="(prefers-color-scheme: light)" srcset="docs/images/overview-light.webp">
19
+ <img src="docs/images/overview-dark.webp" alt="Agent Guild with one card per coding tool and six sessions at work">
20
+ </picture>
32
21
 
33
22
  ## Quick start
34
23
 
@@ -41,13 +30,48 @@ agent-guild
41
30
 
42
31
  The page opens in your browser. Press **New** on a tool's card to start a
43
32
  session. Sign in to each tool inside its first session, as you would in any
44
- terminal.
45
-
46
- **[Agent Guild for VS Code](https://marketplace.visualstudio.com/items?itemName=OddEssentials.agent-guild)**
47
- opens the same page in an editor tab. Editors that install from Open VSX get it
48
- [there](https://open-vsx.org/extension/OddEssentials/agent-guild).
49
-
50
- | Requirement | |
33
+ terminal. To look around first, [try the demo](https://oddessentials.github.io/agent-guild/)
34
+ (simulated, nothing installed) or [watch the trailer](https://www.youtube.com/watch?v=_vQuW0v-uMY).
35
+
36
+ ## Why Agent Guild
37
+
38
+ * **The real CLIs, unchanged.** Each session is the tool itself in a real
39
+ terminal, not a chat copy of it. Whatever sign-in the tool uses works: a
40
+ subscription, an API key, Amazon Bedrock or your own gateway.
41
+ * **Every agent in one place.** Claude Code, Codex CLI, Antigravity CLI, Grok
42
+ Build, Docker Agent, any shell, and tmux or herdr sessions, each card
43
+ showing its helper agents and model, with usage meters for Claude Code and
44
+ Codex CLI.
45
+ * **The same session on every screen.** Any browser, a phone over
46
+ [Tailscale](#remote-access-with-tailscale) with touch keys, VS Code, and
47
+ apps for iPhone, iPad and Vision Pro (beta) and
48
+ [Android](https://github.com/oddessentials/agent-guild-android/releases/latest).
49
+ Apple Watch and Meta Ray-Ban Display list your sessions and read a
50
+ session's last answer aloud.
51
+ * **Native on Windows.** No WSL. Also macOS, Linux, and headless Linux
52
+ servers over SSH.
53
+ * **Nothing in between.** No account and no relay server: the manager
54
+ listens on `127.0.0.1`, and other devices reach it through your own
55
+ Tailscale network or reverse proxy. See [Privacy](#privacy).
56
+
57
+ ### How it compares
58
+
59
+ | | Agent Guild | tmux over SSH | Claude Code Remote Control |
60
+ | --- | --- | --- | --- |
61
+ | Agents | Any CLI, side by side | Any CLI | Claude Code |
62
+ | On a phone | The real terminal in a web page or app, with touch keys | An SSH app | A chat view in the Claude app |
63
+ | Sign-in | Whatever the tool uses | Whatever the tool uses | Pro, Max, Team or Enterprise; [not API keys, Bedrock or a gateway](https://code.claude.com/docs/en/remote-control) |
64
+ | Windows without WSL | Yes | No | Yes |
65
+
66
+ **Not yet:** push notifications. Phones and the Apple apps reconnect when you
67
+ open them again; the sessions keep running on the computer in the meantime.
68
+
69
+ **License:** open source under the [GNU AGPL 3.0](LICENSE). Free for
70
+ personal and commercial use.
71
+
72
+ ## Requirements
73
+
74
+ | | |
51
75
  | --- | --- |
52
76
  | Node.js | 22 or newer |
53
77
  | Windows | 10 version 1809 or later, x64 or arm64. No WSL needed. |
@@ -60,15 +84,9 @@ missing tool shows **Install** on its card; Antigravity CLI, which is not on
60
84
  npm, shows its install command instead. For Docker Agent, see
61
85
  [Docker Agent](#docker-agent).
62
86
 
63
- <picture>
64
- <source media="(prefers-color-scheme: light)" srcset="docs/images/overview-light.webp">
65
- <img src="docs/images/overview-dark.webp" alt="Agent Guild with one card per coding tool and six sessions at work">
66
- </picture>
67
-
68
- **[Agent Guild: World](https://agentguild.oddessentials.ai/)**, coming soon to
69
- Steam, is the premium 3D window onto the same sessions: six worlds to roam
70
- with a free camera, Steam Workshop crews and companions, and controller
71
- support, on Windows, macOS and Linux. Agent Guild and its Yard stay free.
87
+ **[Agent Guild for VS Code](https://marketplace.visualstudio.com/items?itemName=OddEssentials.agent-guild)**
88
+ opens the same page in an editor tab. Editors that install from Open VSX get it
89
+ [there](https://open-vsx.org/extension/OddEssentials/agent-guild).
72
90
 
73
91
  ## Setup
74
92
 
@@ -193,7 +211,15 @@ The first Claude Code usage meter may ask for access to the
193
211
 
194
212
  <img src="docs/images/workspace.webp" alt="Two terminals side by side with the GitHub panel showing the workflow runs of the focused terminal's repository">
195
213
 
196
- <img src="docs/images/yard.webp" alt="The Yard in the Professional skin: a 3D campus with a building for each coding tool, its sessions' characters outside, and the roster and inspector beside it">
214
+ ### The Yard
215
+
216
+ For fun, the Yard shows your tools and sessions as a 3D world, one for each
217
+ skin. A double-click on a character opens its real terminal.
218
+
219
+ <picture>
220
+ <source media="(prefers-reduced-motion: reduce)" srcset="docs/images/yard-still.webp">
221
+ <img src="docs/images/yard-clip.webp" alt="Seven coding-agent sessions as characters in the Guild Yard: they leave the plaza for their tools' halls and get to work, then a double-click on one opens Claude Code's real terminal, with its three helper agents" width="100%">
222
+ </picture>
197
223
 
198
224
  <table>
199
225
  <tr>
@@ -257,6 +283,13 @@ Failed news, model list and release checks retry after 10 minutes.
257
283
  * [Skins](docs/SKINS.md): make your own look
258
284
  * [Contributing](CONTRIBUTING.md)
259
285
 
286
+ ## Agent Guild: World
287
+
288
+ [Agent Guild: World](https://agentguild.oddessentials.ai/), coming soon to
289
+ Steam, is a separate, premium 3D window onto the same sessions: six worlds to
290
+ roam with a free camera, Steam Workshop crews and companions, and controller
291
+ support, on Windows, macOS and Linux. Agent Guild and its Yard stay free.
292
+
260
293
  ## Support
261
294
 
262
295
  Agent Guild is free to use. If it saves you time,
@@ -265,4 +298,5 @@ tax-deductible donation, and it changes nothing about the software.
265
298
 
266
299
  ## License
267
300
 
268
- See [LICENSE](LICENSE).
301
+ Copyright (c) 2026 Odd Essentials. Licensed under the
302
+ [GNU Affero General Public License 3.0](LICENSE).
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@oddessentials/agent-guild",
3
- "version": "1.9.1",
3
+ "version": "1.10.0",
4
4
  "description": "Launch and watch AI coding-assistant terminal sessions from one local web page. A bundled session manager owns the terminals so the page can close and reconnect.",
5
- "license": "SEE LICENSE IN LICENSE",
5
+ "license": "AGPL-3.0-only",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/oddessentials/agent-guild.git"
package/web/app.js CHANGED
@@ -3414,10 +3414,10 @@ function closeNews() {
3414
3414
  if ($('news').open) $('news').close();
3415
3415
  }
3416
3416
 
3417
- // Trailers and tutorials ship in web/videos.json, oldest first, and the page lists tutorials first. Nothing
3417
+ // Videos ship in web/videos.json, oldest first, and the page groups them like the channel's playlists. Nothing
3418
3418
  // reaches YouTube until the dialog opens, and a video plays only once YouTube's image server has answered for
3419
3419
  // its poster.
3420
- const VIDEO_CATEGORIES = { tutorials: ['Tutorials', 'Tutorial'], trailers: ['Trailers', 'Trailer'] };
3420
+ const VIDEO_CATEGORIES = { tutorials: ['Tutorials', 'Tutorial'], trailers: ['Trailers', 'Trailer'], world: ['World', 'World'] };
3421
3421
  const VIDEO_ID = /^[\w-]{11}$/;
3422
3422
  const videosView = { list: [], filter: 'all', selected: null, play: false, poster: 0, opener: null };
3423
3423
 
@@ -3441,8 +3441,22 @@ function videoDate(video) {
3441
3441
  return Number.isNaN(date.getTime()) ? '' : date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });
3442
3442
  }
3443
3443
 
3444
- function videoMeta(video) {
3445
- return [VIDEO_CATEGORIES[video.category][1], videoDate(video)].filter(Boolean).join(' · ');
3444
+ function videoLength(video) {
3445
+ const seconds = video.duration;
3446
+ if (!Number.isInteger(seconds) || seconds <= 0) return '';
3447
+ const [h, m, s] = [Math.floor(seconds / 3600), Math.floor(seconds / 60) % 60, seconds % 60];
3448
+ return [...(h ? [h, String(m).padStart(2, '0')] : [m]), String(s).padStart(2, '0')].join(':');
3449
+ }
3450
+
3451
+ function videoLengthWords(video) {
3452
+ const seconds = video.duration;
3453
+ if (!videoLength(video) || !Intl.DurationFormat) return videoLength(video);
3454
+ return new Intl.DurationFormat(undefined, { style: 'long' })
3455
+ .format({ hours: Math.floor(seconds / 3600), minutes: Math.floor(seconds / 60) % 60, seconds: seconds % 60 });
3456
+ }
3457
+
3458
+ function videoMeta(video, length = false) {
3459
+ return [VIDEO_CATEGORIES[video.category][1], length && videoLength(video), videoDate(video)].filter(Boolean).join(' · ');
3446
3460
  }
3447
3461
 
3448
3462
  function shownVideos() {
@@ -3464,21 +3478,30 @@ function renderVideoFilters() {
3464
3478
  }));
3465
3479
  }
3466
3480
 
3481
+ function videoItem(video) {
3482
+ const thumb = el('img', 'videos-thumb');
3483
+ thumb.alt = '';
3484
+ thumb.loading = 'lazy';
3485
+ thumb.src = `https://i.ytimg.com/vi/${video.id}/mqdefault.jpg`;
3486
+ thumb.addEventListener('error', () => { thumb.hidden = true; }, { once: true });
3487
+ const length = videoLength(video) ? el('span', 'videos-length', videoLength(video)) : null;
3488
+ length?.setAttribute('aria-hidden', 'true');
3489
+ const item = el('button', 'videos-item', el('span', 'videos-frame', thumb, length),
3490
+ el('span', 'videos-item-text', el('span', 'videos-item-title', video.title),
3491
+ length && el('span', 'visually-hidden', `, ${videoLengthWords(video)}, `), el('span', 'news-meta', videoMeta(video))));
3492
+ item.type = 'button';
3493
+ item.dataset.id = video.id;
3494
+ item.addEventListener('click', () => selectVideo(video, true));
3495
+ if (video === videosView.selected) item.setAttribute('aria-current', 'true');
3496
+ return el('li', null, item);
3497
+ }
3498
+
3467
3499
  function renderVideoList() {
3468
- $('videos-list').replaceChildren(...shownVideos().map((video) => {
3469
- const thumb = el('img', 'videos-thumb');
3470
- thumb.alt = '';
3471
- thumb.loading = 'lazy';
3472
- thumb.src = `https://i.ytimg.com/vi/${video.id}/mqdefault.jpg`;
3473
- thumb.addEventListener('error', () => { thumb.hidden = true; }, { once: true });
3474
- const item = el('button', 'videos-item', el('span', 'videos-frame', thumb),
3475
- el('span', 'videos-item-text', el('span', 'videos-item-title', video.title), el('span', 'news-meta', videoMeta(video))));
3476
- item.type = 'button';
3477
- item.dataset.id = video.id;
3478
- item.addEventListener('click', () => selectVideo(video, true));
3479
- if (video === videosView.selected) item.setAttribute('aria-current', 'true');
3480
- return el('li', null, item);
3481
- }));
3500
+ const shown = shownVideos();
3501
+ const groups = Object.keys(VIDEO_CATEGORIES).map((id) => [id, shown.filter((video) => video.category === id)]).filter(([, videos]) => videos.length);
3502
+ $('videos-list').replaceChildren(...groups.map(([id, videos]) => el('li', 'videos-group',
3503
+ groups.length > 1 && el('h3', 'videos-group-title', VIDEO_CATEGORIES[id][0]),
3504
+ el('ol', 'videos-group-list', ...videos.map(videoItem)))));
3482
3505
  }
3483
3506
 
3484
3507
  function stopVideo() {
@@ -3494,7 +3517,7 @@ function selectVideo(video, play) {
3494
3517
  else item.removeAttribute('aria-current');
3495
3518
  }
3496
3519
  $('videos-now').textContent = video.title;
3497
- $('videos-meta').textContent = videoMeta(video);
3520
+ $('videos-meta').textContent = videoMeta(video, true);
3498
3521
  $('videos-youtube').href = `https://www.youtube.com/watch?v=${video.id}`;
3499
3522
  $('videos-play').setAttribute('aria-label', `Play ${video.title}`);
3500
3523
  const request = ++videosView.poster;
package/web/host.js CHANGED
@@ -7,6 +7,7 @@ export const framed = typeof window !== 'undefined' && window.parent !== window;
7
7
  const app = typeof window !== 'undefined' && !framed ? appHost() : null;
8
8
  const hosted = framed || Boolean(app);
9
9
  export const compact = hosted && document.documentElement?.dataset.layout === 'compact';
10
+ const expandable = hosted && document.documentElement?.dataset.expand !== 'none';
10
11
 
11
12
  /** The app's message channel, or null. */
12
13
  function appHost() {
@@ -48,7 +49,7 @@ export function announceReady(version) {
48
49
  }
49
50
 
50
51
  export function expand(session) {
51
- if (hosted) post(session ? { type: 'expand', session } : { type: 'expand' });
52
+ if (expandable) post(session ? { type: 'expand', session } : { type: 'expand' });
52
53
  }
53
54
 
54
55
  let showView = null;
package/web/index.html CHANGED
@@ -575,7 +575,7 @@
575
575
  <div class="models-bar">
576
576
  <div class="models-heading">
577
577
  <h2 id="videos-title">Videos</h2>
578
- <p id="videos-sub" class="sub"></p>
578
+ <p class="sub"><span id="videos-sub"></span> · <a id="videos-channel" class="console-link" href="https://www.youtube.com/@Agent-Guild" target="_blank" rel="noopener noreferrer" aria-description="Opens in a new tab">@Agent-Guild on YouTube</a></p>
579
579
  </div>
580
580
  <button id="videos-close" class="btn" type="button">Close</button>
581
581
  </div>
package/web/styles.css CHANGED
@@ -758,7 +758,7 @@ body:has(#app[hidden]):has(#auth[hidden]):has(#stopped[hidden])::after {
758
758
  .models-body { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 14px 14px; }
759
759
  .remote-access { width: min(560px, calc(100vw - 24px)); max-height: calc(100dvh - 24px); }
760
760
  .videos { width: min(1120px, calc(100vw - 32px)); }
761
- .videos-body { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) 320px; }
761
+ .videos-body { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) min(320px, 45%); }
762
762
  .videos-stage { display: grid; align-content: start; gap: 12px; min-width: 0; padding: 16px; }
763
763
  /* The player keeps 16:9 and gives way to the bar and caption on short windows. */
764
764
  .videos-screen {
@@ -785,7 +785,9 @@ body:has(#app[hidden]):has(#auth[hidden]):has(#stopped[hidden])::after {
785
785
  .videos-caption h3 { margin: 0; font-size: 1rem; overflow-wrap: anywhere; }
786
786
  .videos-caption .news-meta { margin: 3px 0 0; }
787
787
  .videos-nav { display: flex; flex-direction: column; min-height: 0; overflow: auto; border-left: 1px solid var(--border); }
788
- .videos-list { list-style: none; margin: 0; padding: 8px; display: grid; gap: 2px; }
788
+ .videos-list, .videos-group-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
789
+ .videos-list { padding: 8px; gap: 10px; }
790
+ .videos-group-title { margin: 4px 6px; color: var(--muted); font-size: 0.72rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
789
791
  .videos-item {
790
792
  display: grid; grid-template-columns: 128px minmax(0, 1fr); align-items: center; gap: 12px; width: 100%; padding: 6px;
791
793
  border: 0; border-radius: calc(var(--radius) - 2px); background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer;
@@ -793,11 +795,15 @@ body:has(#app[hidden]):has(#auth[hidden]):has(#stopped[hidden])::after {
793
795
  .videos-item:hover, .videos-item[aria-current="true"] { background: var(--surface-2); }
794
796
  .videos-item[aria-current="true"] .videos-frame { outline: 2px solid var(--accent); outline-offset: 1px; }
795
797
  .videos-item:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
796
- .videos-frame { display: block; aspect-ratio: 16 / 9; overflow: hidden; border-radius: 4px; background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--border); }
798
+ .videos-frame { position: relative; display: block; aspect-ratio: 16 / 9; overflow: hidden; border-radius: 4px; background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--border); }
797
799
  .videos-thumb { display: block; width: 100%; height: 100%; object-fit: cover; }
800
+ .videos-length {
801
+ position: absolute; right: 4px; bottom: 4px; padding: 1px 4px; border-radius: 3px;
802
+ background: rgba(0, 0, 0, 0.78); color: #fff; font-size: 0.68rem; font-weight: 600; line-height: 1.3; font-variant-numeric: tabular-nums;
803
+ }
798
804
  .videos-item-title { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; font-size: 0.85rem; font-weight: 600; line-height: 1.3; }
799
805
  .videos-item .news-meta { display: block; margin-top: 3px; white-space: normal; }
800
- @media (max-width: 900px) {
806
+ @media (max-width: 900px) and (orientation: portrait) {
801
807
  .videos-body { display: flex; flex-direction: column; }
802
808
  .videos-stage { flex: none; }
803
809
  .videos-nav { flex: 1 1 auto; border-left: 0; border-top: 1px solid var(--border); }
package/web/theme.js CHANGED
@@ -47,6 +47,7 @@
47
47
  var asked = params.get('view');
48
48
  if (params.get('layout') === 'compact') {
49
49
  document.documentElement.dataset.layout = 'compact';
50
+ if (params.get('expand') === 'none') document.documentElement.dataset.expand = 'none';
50
51
  view = 'yard';
51
52
  if (skins.some(function (s) { return s.id === params.get('skin'); })) skin = params.get('skin');
52
53
  if (params.get('theme') === 'light' || params.get('theme') === 'dark') theme = params.get('theme');
package/web/videos.json CHANGED
@@ -1,10 +1,16 @@
1
1
  {
2
2
  "videos": [
3
- { "id": "ziT62WtXQ1M", "title": "Agent Guild Trailer", "category": "trailers", "published": "2026-10-01" },
4
- { "id": "Zttp-vs_6z0", "title": "Agent Guild - The Yard Update v0.38.0", "category": "trailers", "published": "2026-10-07" },
5
- { "id": "mEEI3cuOGzU", "title": "Docker-Agent Joins Agent Guild v0.47.0", "category": "trailers", "published": "2026-10-09" },
6
- { "id": "XPSRCpiHokk", "title": "01 - Installation (Windows)", "category": "tutorials", "published": "2026-10-11" },
7
- { "id": "5DRFbKgGoUk", "title": "01 - Installation (Linux Headless)", "category": "tutorials", "published": "2026-10-11" },
8
- { "id": "QXIH4pv8CDk", "title": "02 - Claude and Codex Install", "category": "tutorials", "published": "2026-10-11" }
3
+ { "id": "xQ0cBp1wqhA", "title": "Run Them All: Launch Trailer (v0.1.0)", "category": "trailers", "published": "2026-10-01", "duration": 90 },
4
+ { "id": "5Pg85-_TvRI", "title": "The Yard Update (v0.38.0)", "category": "trailers", "published": "2026-10-07", "duration": 29 },
5
+ { "id": "C4aAHThCOeo", "title": "Docker Agent Joins the Guild (v0.47.0)", "category": "trailers", "published": "2026-10-09", "duration": 27 },
6
+ { "id": "unHsaXn4VL4", "title": "Install Agent Guild on Windows (Tutorial 1)", "category": "tutorials", "published": "2026-10-11", "duration": 153 },
7
+ { "id": "yPnUo7-cpHo", "title": "Add Claude Code and Codex (Tutorial 2)", "category": "tutorials", "published": "2026-10-11", "duration": 125 },
8
+ { "id": "OJ1n184WVc4", "title": "Run Agent Guild on a Headless Linux Server", "category": "tutorials", "published": "2026-10-11", "duration": 172 },
9
+ { "id": "n4uXFv6Xgcw", "title": "Agent Guild: World Official Trailer", "category": "world", "published": "2026-10-18", "duration": 62 },
10
+ { "id": "_vQuW0v-uMY", "title": "Built for Builders: Official Trailer", "category": "trailers", "published": "2026-10-23", "duration": 75 },
11
+ { "id": "qykaJBmkcM8", "title": "Quests and Glory: The Guild Board and Achievements", "category": "world", "published": "2026-10-23", "duration": 39 },
12
+ { "id": "tsrkFwj5cgQ", "title": "Use Agent Guild From Your Phone or Anywhere", "category": "tutorials", "published": "2026-10-23", "duration": 263 },
13
+ { "id": "nwAssNU0OVM", "title": "Happy Thanksgiving! New Workshop Pieces", "category": "world", "published": "2026-10-24", "duration": 43 },
14
+ { "id": "buiktzLc5yU", "title": "Everywhere: Official Trailer", "category": "trailers", "published": "2026-10-25", "duration": 92 }
9
15
  ]
10
16
  }