Skip to content

Commit 944a373

Browse files
committed
Prepare GABS 1.0.7 release
1 parent 8d6e715 commit 944a373

28 files changed

Lines changed: 1828 additions & 593 deletions

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ variables first:
2727
- `GABP_SERVER_PORT`
2828
- `GABP_TOKEN`
2929
- `GABS_GAME_ID`
30-
- `GABS_BRIDGE_PATH` as fallback/debug metadata only
30+
- `GABS_BRIDGE_PATH` as endpoint-cache/debug metadata only
3131

3232
`runtime.json` belongs to GABS ownership coordination. Game-side bridge code
3333
must ignore it.

README.md

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,10 @@ If your client disconnects after `tools/list` because it rejects a public tool's
117117
[Configuration Guide](docs/CONFIGURATION.md). Mirrored game tools are discovered
118118
through `games_tool_names` and are not advertised in the public `tools/list`
119119
response.
120-
If a game or bridge starts slowly, you can also tune startup waits with the
121-
`timeouts.startup` section described in the
122-
[Configuration Guide](docs/CONFIGURATION.md).
120+
If a game or bridge starts slowly, tune the total background connection budget
121+
with the `timeouts.startup` section described in the
122+
[Configuration Guide](docs/CONFIGURATION.md). `games_start` still returns after a
123+
bounded initial wait so MCP clients do not time out while the game keeps loading.
123124

124125
### 4. Try these prompts
125126

@@ -136,14 +137,23 @@ If you want a download-to-working walkthrough, use the
136137
- **Steam/Epic stopping**: use the real game process name, not the launcher
137138
name.
138139
- **More than one AI session**: that is fine. GABS coordinates ownership per
139-
game so two live sessions do not both launch or attach to the same game by
140-
accident.
141-
- **Game bridge cannot find bridge config**: the game-side bridge should first read
142-
`GABP_SERVER_PORT`, `GABP_TOKEN`, and `GABS_GAME_ID`, and only fall back to
143-
`GABS_BRIDGE_PATH` or `~/.gabs/<gameId>/bridge.json`.
140+
game with a short active-owner lease. You can hop between live sessions:
141+
`games_connect` takes over naturally after the previous session goes idle,
142+
while active game-bound calls are still protected from competing sessions.
143+
- **Game bridge cannot find GABP configuration**: the game-side bridge should read
144+
`GABP_SERVER_PORT`, `GABP_TOKEN`, and `GABS_GAME_ID` from its process
145+
environment. The `bridge.json` file is GABS' endpoint cache/debug artifact,
146+
not runtime input for game-side bridge code.
147+
- **Stopped game still has `bridge.json`**: this is normal. Treat it as an
148+
endpoint cache/debug artifact, not a recovery target.
149+
- **Start says the endpoint cache port is already in use**: use
150+
`games_connect` if an existing game-side bridge owns that endpoint. Use
151+
`games_start` with `resetEndpoint: true` only after confirming the cache
152+
should be rotated for a new process.
144153
- **Confusing bridge state**: start with `games_status`. It compares the
145-
runtime file, bridge file, passive listener evidence, and process environment
146-
where the OS allows it, then returns diagnosis details and next actions.
154+
runtime state and process environment where the OS allows it. If a launcher
155+
reused old GABP environment, GABS can connect through the running process
156+
endpoint with `games_connect`.
147157

148158
## How It Works
149159

@@ -229,10 +239,8 @@ Want your game to work with GABS? Add GABP support to your game-side bridge:
229239
- `GABS_GAME_ID` - Your game's identifier
230240
- `GABP_SERVER_PORT` - Port your game-side bridge should listen on
231241
- `GABP_TOKEN` - Authentication token for GABS connections
232-
- `GABS_BRIDGE_PATH` - Optional `bridge.json` fallback/debug path
233-
Environment values are authoritative when present. `bridge.json` is a
234-
fallback/debug file so agents can recover or inspect state, not an override
235-
for fresh `GABP_*` values.
242+
The `bridge.json` file is GABS' endpoint cache/debug artifact. Do not read
243+
it as game-side runtime configuration.
236244
2. **Start a local GABP server** to listen for GABS connections (your game-side bridge = server, GABS = client)
237245
3. **Implement the current GABP runtime methods** (`session/hello`, `tools/list`, `tools/call`) or use the official `gabp-runtime` library so your schemas match what GABS expects
238246
- For GABP v1.1 bridges, advertise optional attention support through capabilities before exposing `attention/current`, `attention/ack`, and the attention lifecycle channels

docs/AI_CLIENT_SETUP.md

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,9 @@ args = ["server"]
138138
On Windows, use the full path to `gabs.exe`.
139139

140140
Each live Codex session starts its own stdio GABS process. That is normal.
141-
GABS coordinates ownership per game so two live AI sessions do not both launch
142-
or attach to the same game by accident.
141+
GABS coordinates ownership per game with a short active-owner lease. You can
142+
hop between live sessions: `games_connect` takes over once the previous session
143+
is idle, while active game-bound calls are protected from competing sessions.
143144

144145
### Generic MCP Clients
145146

@@ -231,9 +232,9 @@ Once your AI client is connected, try prompts like:
231232
- "Show the status of all games"
232233
- "Reconnect to AdventureGame and list its tools"
233234

234-
If you have more than one live GABS session, the second session will not launch
235-
or connect to the same game again by default. To intentionally move ownership
236-
to the current session, use:
235+
If you have more than one live GABS session, use `games_connect` in the session
236+
you want to continue from. It will take ownership when the previous session's
237+
active lease is idle. To override an actively owned game immediately, use:
237238

238239
```json
239240
{
@@ -257,15 +258,17 @@ Per-game runtime files live under:
257258
- `~/.gabs/<gameId>/bridge.json`
258259
- `~/.gabs/<gameId>/runtime.json`
259260

260-
`bridge.json` is fallback/debug bridge metadata. The game-side bridge should prefer
261-
`GABP_SERVER_PORT`, `GABP_TOKEN`, and `GABS_GAME_ID` from its process
262-
environment when those values exist. `runtime.json` is internal ownership
263-
tracking used by GABS itself.
261+
`bridge.json` is GABS' endpoint cache/debug artifact. The game-side bridge
262+
should read `GABP_SERVER_PORT`, `GABP_TOKEN`, and `GABS_GAME_ID` from its
263+
process environment. `runtime.json` is internal ownership tracking used by GABS
264+
itself.
264265

265266
If these files look confusing, call `games_status` before editing them by hand.
266-
The structured `diagnostics` field reports stale runtime files, stale bridge
267-
files, passively detected orphan listeners, missing bridge files, and launcher
268-
environment mismatches, with `nextActions` for recovery.
267+
The structured `diagnostics` field reports runtime ownership and process
268+
environment readability with `nextActions` for recovery. Do not inspect or edit
269+
`bridge.json` as a recovery step; use `games_connect` for an already-running
270+
endpoint or `games_start` with `resetEndpoint: true` only after confirming the
271+
endpoint cache should be rotated.
269272

270273
## Troubleshooting
271274

@@ -286,20 +289,13 @@ gabs games show <game-id>
286289
Launcher-based games such as Steam and Epic titles need the actual game process
287290
name, not just the launcher.
288291

289-
### A Bridge Cannot Find `bridge.json`
292+
### A Bridge Cannot Find Configuration
290293

291-
Make sure the game-side bridge first checks the environment variables:
294+
Make sure the game-side bridge checks the environment variables:
292295

293296
- `GABP_SERVER_PORT`
294297
- `GABP_TOKEN`
295298
- `GABS_GAME_ID`
296299

297-
and only falls back to:
298-
299-
- `~/.gabs/<gameId>/bridge.json`
300-
301-
or the `GABS_BRIDGE_PATH` environment variable when present.
302-
303-
Do not patch game-side bridge code to prefer `bridge.json` over present `GABP_*`
304-
environment variables. That can make an old bridge file win over the actual
305-
running process state.
300+
Do not patch game-side bridge code to read `bridge.json`. That can make GABS'
301+
endpoint cache win over the actual running process state.

docs/AI_DYNAMIC_TOOLS_FAQ.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -188,21 +188,31 @@ console.log("Here are all available tools..."); // Group by game instead!
188188
3. **Discovery APIs**: `games_tool_names` and `games_tool_detail` provide structured exploration
189189
4. **Status Awareness**: AI can check game state before tool usage
190190
5. **Mirror System**: Automatic GABP→MCP tool conversion
191-
6. **Session Ownership Guardrails**: Duplicate `games_start` and `games_connect`
192-
requests return quickly instead of racing a second live GABS session
191+
6. **Session Ownership Guardrails**: Duplicate `games_start`, active
192+
`games_connect`, and game-bound calls return quickly instead of racing a
193+
second live GABS session
193194

194195
## What About Multiple GABS Sessions?
195196

196197
This matters in the real world because developers often have more than one AI
197198
session open.
198199

199-
- If one live GABS session already owns a running or starting game,
200+
- If one live GABS session actively owns a running or starting game,
200201
`games_start` returns quickly instead of launching a duplicate process
201202
- `games_connect` also returns quickly instead of hanging on a competing bridge
202-
connection
203-
- `games_status` can report that another GABS session owns the process
204-
- If takeover is intentional, `games_connect {"gameId": "adventure",
205-
"forceTakeover": true}` moves ownership to the current session
203+
connection while the active owner lease is still open
204+
- once the previous session is idle, `games_connect` moves ownership to the
205+
current session without `forceTakeover`
206+
- game-bound calls from old sessions are blocked while another active owner
207+
holds the lease
208+
- `games_status` can report that another GABS session owns the process and show
209+
the lease expiry
210+
- if `games_start` reports `endpoint_cache_in_use`, use `games_connect` to
211+
attach to the already-listening endpoint or `resetEndpoint: true` only after
212+
confirming the endpoint cache should be rotated
213+
- if takeover is intentional before the active lease expires,
214+
`games_connect {"gameId": "adventure", "forceTakeover": true}` moves
215+
ownership to the current session
206216

207217
### Current State
208218
- **Stable public tool list is live**: mirrored game tools no longer require

docs/CONFIGURATION.md

Lines changed: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -72,21 +72,23 @@ Most users can skip this section.
7272

7373
GABS uses local-only GABP communication for security and simplicity.
7474

75-
When you start a game, GABS passes bridge configuration to the game-side bridge through:
75+
When you start a game, GABS passes GABP connection data to the game-side bridge through:
7676

7777
1. Environment variables: `GABP_SERVER_PORT`, `GABP_TOKEN`, `GABS_GAME_ID`
78-
2. A bridge file fallback: `~/.gabs/{gameId}/bridge.json`
7978

80-
The environment variables are authoritative when present. `bridge.json` is a
81-
fallback/debug artifact for reconnects and diagnostics; game-side bridge code
82-
should not let a stale bridge file override fresh `GABP_*` environment values.
79+
The `bridge.json` file is GABS' endpoint cache/debug artifact. Game-side bridge
80+
code should not read it as runtime configuration or use it as a fallback for
81+
missing `GABP_*` environment values.
8382

8483
In the GABP layer, your game-side bridge listens for the connection and GABS connects
8584
to it.
8685

8786
GABS also keeps an internal ownership record at `~/.gabs/{gameId}/runtime.json`
88-
so separate GABS sessions do not accidentally launch or attach to the same game
89-
at the same time. Game integrations should ignore `runtime.json`; it is for GABS itself.
87+
so separate GABS sessions do not accidentally launch or drive the same game at
88+
the same time. Ownership is an expiring active-use lease, so you can hop
89+
between live AI sessions by using `games_connect` after the previous session
90+
goes idle. Game integrations should ignore `runtime.json`; it is for GABS
91+
itself.
9092

9193
## Managing Your Games
9294

@@ -184,9 +186,8 @@ not passed to the game in this mode. Put launch options such as
184186

185187
In launcher-driven setups, an already-running platform launcher process can
186188
prevent GABS from proving that new environment variables reached the real game
187-
process. `games_status` reports this as bridge-state diagnostics, including
188-
stale launcher environment when the process `GABP_*` values disagree with
189-
`bridge.json`. For deterministic env and argument control, use `DirectPath` or
189+
process. `games_status` reports whether the real game process environment is
190+
readable. For deterministic env and argument control, use `DirectPath` or
190191
`CustomCommand`.
191192

192193
### EpicAppId
@@ -223,35 +224,40 @@ GABS uses local-only GABP communication.
223224
### Local Communication (Current Implementation)
224225
- GABS connects to game integrations on localhost (`127.0.0.1`) only
225226
- Each game gets a unique port and token
226-
- Bridge configuration is also written to `~/.gabs/{gameId}/bridge.json`
227+
- GABS may write `~/.gabs/{gameId}/bridge.json` as an endpoint cache/debug artifact
227228

228229
### Bridge Configuration
229-
When you start a game, GABS creates a bridge configuration file that looks like this:
230+
When you start a game, GABS sends GABP configuration through environment
231+
variables:
230232

231-
```json
232-
{
233-
"port": 49234,
234-
"token": "a1b2c3d4e5f6...",
235-
"gameId": "factory"
236-
}
237-
```
233+
- `GABP_SERVER_PORT`
234+
- `GABP_TOKEN`
235+
- `GABS_GAME_ID`
238236

239-
Game integrations can read this file, but environment variables remain the preferred source.
237+
Game integrations should read these environment variables directly.
240238

241239
## Shared Runtime Ownership
242240

243241
When a game is already starting or running, GABS writes a per-game
244-
`runtime.json` file so other live GABS sessions can see that the game already
245-
has an owner.
242+
`runtime.json` file so other live GABS sessions can see whether the game
243+
currently has an active owner.
246244

247245
- A second `games.start` returns immediately with "already starting" or
248246
"already running" instead of launching a second copy
249-
- A second `games.connect` also returns immediately instead of waiting for a
250-
competing bridge connection
251-
- `games.status` can report that another GABS session owns the process
247+
- `games.connect` takes ownership naturally once the previous owner's lease is
248+
idle
249+
- `games.connect` returns immediately with an active-owner result when another
250+
session is still inside its lease
251+
- game-bound tool calls also check the lease before touching the bridge
252+
- `games.status` reports the runtime owner, lease expiry, and bridge diagnostics
252253

253-
If you intentionally want a different GABS session to take over a running game,
254-
use `games.connect` with `forceTakeover: true`.
254+
If you intentionally want a different GABS session to take over before the
255+
active lease expires, use `games.connect` with `forceTakeover: true`.
256+
257+
If `games.start` reports `endpoint_cache_in_use`, the cached port is already
258+
listening. Use `games.connect` if an already-running bridge owns that endpoint.
259+
Use `games.start` with `resetEndpoint: true` only after confirming the cached
260+
endpoint should be rotated for a new process.
255261

256262
## Tool Normalization Configuration
257263

@@ -325,25 +331,36 @@ tool metadata, including output schema information, remains available through
325331
## Startup Timeout Configuration
326332

327333
If your game takes longer to appear in the process list or longer for its GABP
328-
game-side bridge to start listening, you can override the startup waits in
329-
`~/.gabs/config.json`.
334+
game-side bridge to start listening, you can override the startup process wait
335+
and connection budget in `~/.gabs/config.json`.
330336

331337
### Startup Timeout Options
332338

333339
The `timeouts.startup` section supports these options:
334340

335341
- **`processStartSeconds`** (integer): How long GABS waits for the launched game
336342
process to become detectable in the OS process list (default: `10`)
337-
- **`gabpConnectSeconds`** (integer): How long `games.start` waits for the
338-
game's GABP server to become available before returning control to you
339-
(default: `60`). You can also pass a one-off `timeout` argument to
340-
`games_start` for unusually slow bridge startup without changing the
341-
saved configuration.
342-
343-
`games_start` only waits for the GABP handshake. Mirroring the connected bridge's
344-
full tool list can continue briefly in the background. The public `tools/list`
345-
response stays stable, and known startup commands can be sent immediately
346-
through `games_call_tool` while discovery tools refresh.
343+
- **`gabpConnectSeconds`** (integer): The total connection budget for the game
344+
GABP server to become available (default: `60`). `games_start` waits only for
345+
a bounded initial slice of that budget, returns before MCP clients hit their
346+
own tool-call timeout, and continues connecting in the background. You can
347+
also pass a one-off `timeout` argument to `games_start` for unusually slow
348+
bridge startup without changing the saved configuration.
349+
350+
The `timeouts.session` section supports:
351+
352+
- **`ownerLeaseSeconds`** (integer): How long an idle GABS session remains the
353+
active runtime owner after a normal game-bound action (default: `30`). Long
354+
game-bound calls extend the lease to cover their requested timeout plus a
355+
small safety margin, so this value controls roaming between idle sessions,
356+
not the maximum duration of a running command.
357+
358+
`games_start` only waits for an initial GABP handshake window. If the game is
359+
still loading, GABS keeps trying in the background for the remaining startup
360+
budget. Mirroring the connected bridge's full tool list can continue briefly in
361+
the background. The public `tools/list` response stays stable, and known startup
362+
commands can be sent immediately through `games_call_tool` while discovery tools
363+
refresh.
347364

348365
### Example Configuration
349366

@@ -354,6 +371,9 @@ through `games_call_tool` while discovery tools refresh.
354371
"startup": {
355372
"processStartSeconds": 20,
356373
"gabpConnectSeconds": 120
374+
},
375+
"session": {
376+
"ownerLeaseSeconds": 30
357377
}
358378
},
359379
"games": {
@@ -426,10 +446,10 @@ mandatory.
426446
1. Make sure your game-side bridge supports GABP
427447
2. Check that the game-side bridge is listening on the right port
428448
3. Verify the game-side bridge is using `GABP_SERVER_PORT`, `GABP_TOKEN`, and `GABS_GAME_ID`
429-
from the environment or `bridge.json`
449+
from the environment
430450
4. Run `games_status` and inspect `diagnostics.code`, `diagnostics.message`,
431-
and `nextActions`; it can identify stale runtime state, stale bridge files,
432-
passively detected orphan listeners, and launcher environment mismatches.
451+
and `nextActions`; it can identify stale runtime state, runtime ownership,
452+
and whether the real game process environment is readable.
433453

434454
### "Configuration not found"
435455
The config file is created automatically when you add your first game. If it's missing, run `gabs games add` to create a new one.

0 commit comments

Comments
 (0)