diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 724034d..fd00236 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -53,11 +53,11 @@ jobs:
- name: Cache OpenRA engine
uses: actions/cache@v4
with:
- path: command-and-clanker/engine
- key: openra-engine-${{ runner.os }}-${{ hashFiles('command-and-clanker/mod.config') }}
+ path: command-and-combobulate/engine
+ key: openra-engine-${{ runner.os }}-${{ hashFiles('command-and-combobulate/mod.config') }}
restore-keys: |
openra-engine-${{ runner.os }}-
- name: Build mod
- working-directory: command-and-clanker
+ working-directory: command-and-combobulate
run: make
diff --git a/.gitignore b/.gitignore
index ab3f2d3..0e7850a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,4 @@ dist/
.vite/
*.log
.DS_Store
-.clanker-cache.json
+.combobulate-cache.json
diff --git a/AGENTS.md b/AGENTS.md
index 31b910f..6ca39ed 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -6,7 +6,7 @@ conventions an agent needs to make changes safely.
## What this repo is
-Command & Clanker visualises an AI agent's tool calls as an
+Command & Combobulate visualises an AI agent's tool calls as an
[OpenRA](https://www.openra.net) real-time strategy game. The agent's terminal
is a building, files are smaller buildings inside folder compounds, and every
read/write/run shows up as a unit moving on the map.
@@ -17,13 +17,13 @@ It ships as two cooperating pieces that talk over WebSocket and HTTP on
- **`server/`** — a Node backend. Hosts real PTYs via `node-pty`, ingests tool
events posted by the agent adapters, builds a world model, and streams it to
connected game clients.
-- **`command-and-clanker/`** — an OpenRA Mod SDK mod. A C# client connects to
+- **`command-and-combobulate/`** — an OpenRA Mod SDK mod. A C# client connects to
the backend, receives world updates, and renders them through the OpenRA
engine.
The agent adapters in `integrations/` are the third leg: shims for Claude Code
and Codex that POST tool calls to the backend, but only when launched from
-inside an in-game terminal (detected via the `CLANKER_SESSION` env var).
+inside an in-game terminal (detected via the `COMBOBULATE_SESSION` env var).
## Layout
@@ -45,10 +45,10 @@ inside an in-game terminal (detected via the `CLANKER_SESSION` env var).
Tests sit next to sources as `*.test.ts`.
- `shared/` — types shared between the backend and the adapters
(`proc-types.ts`, `types.ts`).
-- `command-and-clanker/` — the OpenRA mod. Contains an OpenRA SDK scaffold
+- `command-and-combobulate/` — the OpenRA mod. Contains an OpenRA SDK scaffold
plus:
- - `mods/clanker/` — yaml rules, art, maps, and other mod data.
- - `OpenRA.Mods.Clanker/` — C# traits and widgets specific to this mod.
+ - `mods/combobulate/` — yaml rules, art, maps, and other mod data.
+ - `OpenRA.Mods.Combobulate/` — C# traits and widgets specific to this mod.
- `engine/` — fetched OpenRA engine (not checked in; populated by
`fetch-engine.sh` / `make`).
- `integrations/` — per-agent adapters wired up by `bun run setup`.
@@ -70,7 +70,7 @@ The split between Node and Bun is deliberate and load-bearing:
- TypeScript is executed via Node's `--experimental-strip-types`; there is no
separate build step for the backend. `bun run typecheck` runs `tsc --noEmit`.
- The OpenRA mod builds with .NET 8 (or Mono) via `make` inside
- `command-and-clanker/`. The first build fetches and compiles the pinned
+ `command-and-combobulate/`. The first build fetches and compiles the pinned
engine and takes several minutes.
- `mise.toml` pins Bun and Node versions.
@@ -86,7 +86,7 @@ Run from the repo root unless noted:
- `bun test` — run all `*.test.ts` files.
- `bun run game` — build the mod and launch the game (also starts a backend).
-Mod-only flow (from `command-and-clanker/`):
+Mod-only flow (from `command-and-combobulate/`):
- `make` — fetch the engine on first run, then build the mod.
- `./launch-game.sh` / `./launch-dedicated.sh` — launch the game / a dedicated
@@ -102,12 +102,12 @@ Mod-only flow (from `command-and-clanker/`):
is the canonical example: events in, world state out, no I/O.
- Co-locate tests with the code they cover (`foo.ts` + `foo.test.ts`).
- The OpenRA mod follows OpenRA's own conventions for yaml rules and C#
- traits. When in doubt, mirror an existing trait in `OpenRA.Mods.Clanker/`
- or an existing rule in `mods/clanker/`.
-- Mod assets (sprites, palettes, maps) live under `mods/clanker/`. Generated
- files under `command-and-clanker/engine/` and `bin/` are not checked in.
-- Adapters in `integrations/` must stay silent outside a Command & Clanker
- session — gate all reporting on `CLANKER_SESSION`.
+ traits. When in doubt, mirror an existing trait in `OpenRA.Mods.Combobulate/`
+ or an existing rule in `mods/combobulate/`.
+- Mod assets (sprites, palettes, maps) live under `mods/combobulate/`. Generated
+ files under `command-and-combobulate/engine/` and `bin/` are not checked in.
+- Adapters in `integrations/` must stay silent outside a Command & Combobulate
+ session — gate all reporting on `COMBOBULATE_SESSION`.
## Engineering standards
@@ -125,8 +125,8 @@ Mod-only flow (from `command-and-clanker/`):
## Things to avoid
-- Do not commit anything under `command-and-clanker/engine/`,
- `command-and-clanker/bin/`, or `.clanker-cache.json` — these are
+- Do not commit anything under `command-and-combobulate/engine/`,
+ `command-and-combobulate/bin/`, or `.combobulate-cache.json` — these are
build/runtime artefacts.
- Do not switch the backend off Node, or the test runner off Bun.
- Do not add comments that restate what the code does; follow the
diff --git a/README.md b/README.md
index ee4e6e3..ff8750f 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-# Command & Clanker
-
+# Command & Combobulate
+
@@ -14,7 +14,7 @@ It is two pieces:
- **`server/`** — a small Node backend. Agent adapters POST their tool calls to it,
and it hosts the real terminals (`node-pty`). It streams a live world and terminal
I/O over WebSocket.
-- **`command-and-clanker/`** — an [OpenRA Mod SDK](https://github.com/OpenRA/OpenRAModSDK)
+- **`command-and-combobulate/`** — an [OpenRA Mod SDK](https://github.com/OpenRA/OpenRAModSDK)
mod that connects to the backend and renders that world inside the OpenRA engine.
## Prerequisites
@@ -37,7 +37,7 @@ In a second shell, build and launch the mod. The first `make` fetches the pinned
OpenRA engine and builds it (a few minutes):
```sh
-cd command-and-clanker
+cd command-and-combobulate
make # fetch engine + build the mod
./launch-game.sh # launch
```
@@ -54,7 +54,7 @@ claude # also: codex
The agent appears as a unit and starts working the map. Scout outward to reveal
what other agents are doing. The adapters only report from inside a Command &
-Clanker terminal (where `CLANKER_SESSION` is injected), so they stay quiet
+Combobulate terminal (where `COMBOBULATE_SESSION` is injected), so they stay quiet
everywhere else.
## What you see
@@ -71,8 +71,8 @@ everywhere else.
## Layout
- `server/` — the backend (event ingest + PTY hosting).
-- `command-and-clanker/` — the OpenRA mod: SDK scaffold, `mods/clanker/` (yaml,
- art, maps) and `OpenRA.Mods.Clanker/` (C# traits and widgets).
+- `command-and-combobulate/` — the OpenRA mod: SDK scaffold, `mods/combobulate/` (yaml,
+ art, maps) and `OpenRA.Mods.Combobulate/` (C# traits and widgets).
- `integrations/` — the Claude and Codex adapters installed by `bun run setup`.
- `docs/` — design notes.
diff --git a/assets/loadscreen.png b/assets/loadscreen.png
new file mode 100644
index 0000000..ab8606f
Binary files /dev/null and b/assets/loadscreen.png differ
diff --git a/command-and-clanker/mods/clanker/fluent/clanker.ftl b/command-and-clanker/mods/clanker/fluent/clanker.ftl
deleted file mode 100644
index 11110e3..0000000
--- a/command-and-clanker/mods/clanker/fluent/clanker.ftl
+++ /dev/null
@@ -1,8 +0,0 @@
-clanker-mod-title = Command & Clanker
-clanker-mod-windowtitle = Command & Clanker
-loadscreen-loading = Comboluating..., Summoning subagents..., Compacting context..., Warming the prompt cache..., Reticulating splines..., Negotiating with the rate limiter..., Spinning up PTYs..., Aligning the clankers..., Tokenizing the vibes..., Deploying robots...
-button-clanker-launch = Start Clanking
-button-clanker-quit = Quit
-actor-clanker-terminal =
- .name = Terminal
- .description = Spawns a Command & Clanker agent terminal.
diff --git a/command-and-clanker/mods/clanker/rules/world.yaml b/command-and-clanker/mods/clanker/rules/world.yaml
deleted file mode 100644
index 8bcea3c..0000000
--- a/command-and-clanker/mods/clanker/rules/world.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-World:
- ClankerBridge:
- ClankerSidebarLoader:
- LoadWidgetAtGameStart:
- ShellmapRoot: CLANKER_MAINMENU
- MapOptions:
- TechLevel: unrestricted
diff --git a/command-and-clanker/mods/clanker/uibits/clanker-loadscreen-2x.png b/command-and-clanker/mods/clanker/uibits/clanker-loadscreen-2x.png
deleted file mode 100644
index f6edc57..0000000
Binary files a/command-and-clanker/mods/clanker/uibits/clanker-loadscreen-2x.png and /dev/null differ
diff --git a/command-and-clanker/mods/clanker/uibits/clanker-loadscreen-3x.png b/command-and-clanker/mods/clanker/uibits/clanker-loadscreen-3x.png
deleted file mode 100644
index a93e362..0000000
Binary files a/command-and-clanker/mods/clanker/uibits/clanker-loadscreen-3x.png and /dev/null differ
diff --git a/command-and-clanker/mods/clanker/uibits/clanker-loadscreen.png b/command-and-clanker/mods/clanker/uibits/clanker-loadscreen.png
deleted file mode 100644
index 0013684..0000000
Binary files a/command-and-clanker/mods/clanker/uibits/clanker-loadscreen.png and /dev/null differ
diff --git a/command-and-clanker/package.json b/command-and-clanker/package.json
deleted file mode 100644
index c012046..0000000
--- a/command-and-clanker/package.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "command-and-clanker-mod",
- "version": "0.1.0",
- "private": true,
- "description": "Command & Clanker OpenRA mod (built on the OpenRA Mod SDK).",
- "scripts": {
- "build": "make",
- "launch": "./launch-game.sh",
- "game": "make && ./launch-game.sh",
- "utility": "./utility.sh clanker"
- }
-}
diff --git a/command-and-clanker/.editorconfig b/command-and-combobulate/.editorconfig
similarity index 100%
rename from command-and-clanker/.editorconfig
rename to command-and-combobulate/.editorconfig
diff --git a/command-and-clanker/.gitattributes b/command-and-combobulate/.gitattributes
similarity index 100%
rename from command-and-clanker/.gitattributes
rename to command-and-combobulate/.gitattributes
diff --git a/command-and-clanker/.gitignore b/command-and-combobulate/.gitignore
similarity index 100%
rename from command-and-clanker/.gitignore
rename to command-and-combobulate/.gitignore
diff --git a/command-and-clanker/.vscode/extensions.json b/command-and-combobulate/.vscode/extensions.json
similarity index 100%
rename from command-and-clanker/.vscode/extensions.json
rename to command-and-combobulate/.vscode/extensions.json
diff --git a/command-and-clanker/.vscode/launch.json b/command-and-combobulate/.vscode/launch.json
similarity index 100%
rename from command-and-clanker/.vscode/launch.json
rename to command-and-combobulate/.vscode/launch.json
diff --git a/command-and-clanker/.vscode/tasks.json b/command-and-combobulate/.vscode/tasks.json
similarity index 100%
rename from command-and-clanker/.vscode/tasks.json
rename to command-and-combobulate/.vscode/tasks.json
diff --git a/command-and-clanker/COPYING b/command-and-combobulate/COPYING
similarity index 100%
rename from command-and-clanker/COPYING
rename to command-and-combobulate/COPYING
diff --git a/command-and-clanker/CommandAndClanker.sln b/command-and-combobulate/CommandAndCombobulate.sln
similarity index 95%
rename from command-and-clanker/CommandAndClanker.sln
rename to command-and-combobulate/CommandAndCombobulate.sln
index a1df25f..00216a1 100644
--- a/command-and-clanker/CommandAndClanker.sln
+++ b/command-and-combobulate/CommandAndCombobulate.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRA.Mods.Clanker", "OpenRA.Mods.Clanker\OpenRA.Mods.Clanker.csproj", "{4E5B38F7-4E99-4C92-BB39-9100CC7F3829}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRA.Mods.Combobulate", "OpenRA.Mods.Combobulate\OpenRA.Mods.Combobulate.csproj", "{4E5B38F7-4E99-4C92-BB39-9100CC7F3829}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRA.Game", "engine\OpenRA.Game\OpenRA.Game.csproj", "{0DFB103F-2962-400F-8C6D-E2C28CCBA633}"
EndProject
diff --git a/command-and-clanker/Makefile b/command-and-combobulate/Makefile
similarity index 100%
rename from command-and-clanker/Makefile
rename to command-and-combobulate/Makefile
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/ClankerBackend.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/CombobulateBackend.cs
similarity index 92%
rename from command-and-clanker/OpenRA.Mods.Clanker/ClankerBackend.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/CombobulateBackend.cs
index cf20192..d32c347 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/ClankerBackend.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/CombobulateBackend.cs
@@ -5,13 +5,13 @@
using System.Threading.Tasks;
using OpenRA.Support;
-namespace OpenRA.Mods.Clanker
+namespace OpenRA.Mods.Combobulate
{
- // Fire-and-forget JSON POSTs to the Command & Clanker backend. Called from the
+ // Fire-and-forget JSON POSTs to the Command & Combobulate backend. Called from the
// game thread; the request runs on a background task so it never stalls a tick.
// Anything that changes the world comes back over the bridge's /live stream,
// so callers do not await a response.
- public static class ClankerBackend
+ public static class CombobulateBackend
{
public static string BaseUrl = "http://127.0.0.1:3001";
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/ClankerLoadScreen.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/CombobulateLoadScreen.cs
similarity index 95%
rename from command-and-clanker/OpenRA.Mods.Clanker/ClankerLoadScreen.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/CombobulateLoadScreen.cs
index 22f2f41..fa7e9ed 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/ClankerLoadScreen.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/CombobulateLoadScreen.cs
@@ -4,14 +4,14 @@
using OpenRA.Mods.Common.LoadScreens;
using OpenRA.Primitives;
-namespace OpenRA.Mods.Clanker
+namespace OpenRA.Mods.Combobulate
{
// Draws a single image centered on screen plus the loadscreen-loading phrases.
// Unlike LogoStripeLoadScreen (which tiles a "stripe" region across the full
// width and so mangles a plain banner), this shows the image exactly once.
// Image size defaults to 512x256 and can be overridden with Width/Height in
// the LoadScreen block.
- public sealed class ClankerLoadScreen : SheetLoadScreen
+ public sealed class CombobulateLoadScreen : SheetLoadScreen
{
[FluentReference]
const string Loading = "loadscreen-loading";
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/MapCoords.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/MapCoords.cs
similarity index 91%
rename from command-and-clanker/OpenRA.Mods.Clanker/MapCoords.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/MapCoords.cs
index 5dd3e32..2eb813b 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/MapCoords.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/MapCoords.cs
@@ -1,6 +1,6 @@
-using OpenRA.Mods.Clanker.Protocol;
+using OpenRA.Mods.Combobulate.Protocol;
-namespace OpenRA.Mods.Clanker
+namespace OpenRA.Mods.Combobulate
{
// Translates the backend's unbounded tile grid (Region.origin / fileArea,
// laid out by the spiral slot allocator in server/world-builder.ts) onto a
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/OpenRA.Mods.Clanker.csproj b/command-and-combobulate/OpenRA.Mods.Combobulate/OpenRA.Mods.Combobulate.csproj
similarity index 100%
rename from command-and-clanker/OpenRA.Mods.Clanker/OpenRA.Mods.Clanker.csproj
rename to command-and-combobulate/OpenRA.Mods.Combobulate/OpenRA.Mods.Combobulate.csproj
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/Protocol/LiveMessage.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/Protocol/LiveMessage.cs
similarity index 97%
rename from command-and-clanker/OpenRA.Mods.Clanker/Protocol/LiveMessage.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/Protocol/LiveMessage.cs
index 88d57ca..656dad5 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/Protocol/LiveMessage.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/Protocol/LiveMessage.cs
@@ -2,9 +2,9 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace OpenRA.Mods.Clanker.Protocol
+namespace OpenRA.Mods.Combobulate.Protocol
{
- // Mirrors the wire format the Command & Clanker backend broadcasts over
+ // Mirrors the wire format the Command & Combobulate backend broadcasts over
// WS /live (see the LiveMessage union in shared/proc-types.ts). One inbound
// frame is one of three kinds: a full world snapshot ("world-delta"), the
// current agents ("agents"), or the files each folder has touched ("files").
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerBridge.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateBridge.cs
similarity index 93%
rename from command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerBridge.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateBridge.cs
index 5e71947..8f7e690 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerBridge.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateBridge.cs
@@ -8,7 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using OpenRA.Graphics;
-using OpenRA.Mods.Clanker.Protocol;
+using OpenRA.Mods.Combobulate.Protocol;
using OpenRA.Mods.Common;
using OpenRA.Mods.Common.Activities;
using OpenRA.Mods.Common.Effects;
@@ -17,13 +17,13 @@
using OpenRA.Primitives;
using OpenRA.Traits;
-namespace OpenRA.Mods.Clanker.Traits
+namespace OpenRA.Mods.Combobulate.Traits
{
[TraitLocation(SystemActors.World)]
- [Desc("Connects to the Command & Clanker backend over WebSocket and renders",
+ [Desc("Connects to the Command & Combobulate backend over WebSocket and renders",
"its live world (terminal islands, folder regions, and the files agents",
"touch) as actors and resources on the map.")]
- public class ClankerBridgeInfo : TraitInfo
+ public class CombobulateBridgeInfo : TraitInfo
{
[Desc("Backend WebSocket endpoint for the live world stream.")]
public readonly string LiveUrl = "ws://127.0.0.1:3001/live";
@@ -33,7 +33,7 @@ public class ClankerBridgeInfo : TraitInfo
[ActorReference]
[Desc("Actor spawned for each terminal island.")]
- public readonly string TerminalActor = "clanker.terminal";
+ public readonly string TerminalActor = "combobulate.terminal";
[Desc("Wall actors placed around folder perimeters, chosen by nesting depth",
"(level 0 = outermost). The last entry covers any deeper level.")]
@@ -41,28 +41,28 @@ public class ClankerBridgeInfo : TraitInfo
[ActorReference]
[Desc("Wall actor for a folder's top-left corner; it carries the folder name label.")]
- public readonly string FolderLabelWall = "clanker.folderwall";
+ public readonly string FolderLabelWall = "combobulate.folderwall";
[ActorReference]
[Desc("Civilian building actors placed inside a folder, one per file an agent",
"touches; the variant is chosen by file extension so similar files match.")]
public readonly string[] FileActors =
{
- "clanker.file1", "clanker.file2", "clanker.file3",
- "clanker.file4", "clanker.file5", "clanker.file6", "clanker.file7",
+ "combobulate.file1", "combobulate.file2", "combobulate.file3",
+ "combobulate.file4", "combobulate.file5", "combobulate.file6", "combobulate.file7",
};
[ActorReference]
[Desc("Unit spawned for each agent (Claude / default), homed on its terminal island.")]
- public readonly string AgentActor = "clanker.agent";
+ public readonly string AgentActor = "combobulate.agent";
[ActorReference]
[Desc("Unit for codex agents.")]
- public readonly string CodexAgentActor = "clanker.agent.codex";
+ public readonly string CodexAgentActor = "combobulate.agent.codex";
[ActorReference]
[Desc("Unit spawned for each subagent.")]
- public readonly string SubagentActor = "clanker.subagent";
+ public readonly string SubagentActor = "combobulate.subagent";
[ActorReference]
[Desc("Transient machines spawned at an action site, one per verb, that",
@@ -87,25 +87,25 @@ public class ClankerBridgeInfo : TraitInfo
"until they are scouted.")]
public readonly string OwnerPlayer = "Neutral";
- public override object Create(ActorInitializer init) { return new ClankerBridge(this); }
+ public override object Create(ActorInitializer init) { return new CombobulateBridge(this); }
}
// The background thread only ever touches the ConcurrentQueue; every World,
// Actor, Map, and resource access happens on the game thread inside ITick and
// the AddFrameEndTask it schedules. That boundary is what keeps the bridge safe.
- public class ClankerBridge : IWorldLoaded, ITick, INotifyActorDisposing, IRenderAnnotations
+ public class CombobulateBridge : IWorldLoaded, ITick, INotifyActorDisposing, IRenderAnnotations
{
- readonly ClankerBridgeInfo info;
+ readonly CombobulateBridgeInfo info;
readonly ConcurrentQueue inbox = new();
readonly Dictionary islands = new();
- readonly Dictionary islandRefs = new();
+ readonly Dictionary islandRefs = new();
readonly Dictionary> folderWalls = new();
readonly Dictionary folderRegions = new();
readonly Dictionary> placedFiles = new();
readonly Dictionary agents = new();
readonly Dictionary agentHome = new();
readonly Dictionary agentTarget = new();
- readonly Dictionary agentLabels = new();
+ readonly Dictionary agentLabels = new();
// Current action key (verb|path) per agent: spawn the verb machine once
// when this changes. The agent's start state (ok null) is collapsed into
// the completion server-side before broadcast, so keying on ok would
@@ -119,11 +119,11 @@ public class ClankerBridge : IWorldLoaded, ITick, INotifyActorDisposing, IRender
CancellationTokenSource termCts;
string streamedId;
- volatile ClankerTermGrid termGrid;
+ volatile CombobulateTermGrid termGrid;
readonly ConcurrentQueue termSend = new();
// The selected terminal's resolved screen, repainted by the terminal widget.
- public ClankerTermGrid TerminalGrid => termGrid;
+ public CombobulateTermGrid TerminalGrid => termGrid;
// The id of the terminal currently mirrored, or null when none is selected.
public string StreamedTerminal => streamedId;
@@ -149,7 +149,7 @@ public class ClankerBridge : IWorldLoaded, ITick, INotifyActorDisposing, IRender
MapCoords coords;
CancellationTokenSource cts;
- public ClankerBridge(ClankerBridgeInfo info)
+ public CombobulateBridge(CombobulateBridgeInfo info)
{
this.info = info;
}
@@ -158,7 +158,7 @@ void IWorldLoaded.WorldLoaded(World w, WorldRenderer wr)
{
world = w;
owner = FindOwner(w);
- ClankerBackend.BaseUrl = info.HttpUrl;
+ CombobulateBackend.BaseUrl = info.HttpUrl;
var bounds = w.Map.Bounds;
// Anchor the agent world just south-east of the commander's base (top-left)
@@ -198,7 +198,7 @@ public void RegisterPlayerTerminal(string id, Actor actor)
return;
islands[id] = actor;
- islandRefs[id] = actor.TraitOrDefault();
+ islandRefs[id] = actor.TraitOrDefault();
}
async Task RunSocketLoop(CancellationToken ct)
@@ -291,10 +291,10 @@ void ApplyRegions(World w, List regions)
[
new LocationInit(cell),
new OwnerInit(owner),
- new ClankerTerminalRefInit(region.Path),
+ new CombobulateTerminalRefInit(region.Path),
]);
islands[region.Path] = island;
- islandRefs[region.Path] = island.TraitOrDefault();
+ islandRefs[region.Path] = island.TraitOrDefault();
}
}
}
@@ -375,7 +375,7 @@ List BuildFolderWalls(World w, Region region)
if (isLabelCorner)
{
- var label = actor.TraitOrDefault();
+ var label = actor.TraitOrDefault();
if (label != null)
label.Label = name;
}
@@ -432,7 +432,7 @@ void UpdateTerminalLabel(string terminal, double? fraction, string message)
if (!islands.TryGetValue(terminal, out var island) || !island.IsInWorld)
return;
- var label = island.TraitOrDefault();
+ var label = island.TraitOrDefault();
if (label == null)
return;
@@ -643,7 +643,7 @@ void ApplyFiles(World w, List files)
new LocationInit(cells[chosen]),
new OwnerInit(owner),
]);
- var label = building.TraitOrDefault();
+ var label = building.TraitOrDefault();
if (label != null)
label.Label = FileLabel(entry);
placed[entry.Path] = building;
@@ -693,11 +693,11 @@ string FileActorForRole(string role)
{
switch (role)
{
- case "test": return "clanker.file.test";
- case "config": return "clanker.file.config";
- case "manifest": return "clanker.file.manifest";
- case "docs": return "clanker.file.docs";
- case "build": return "clanker.file.build";
+ case "test": return "combobulate.file.test";
+ case "config": return "combobulate.file.config";
+ case "manifest": return "combobulate.file.manifest";
+ case "docs": return "combobulate.file.docs";
+ case "build": return "combobulate.file.build";
case "source": return info.FileActors[0];
default: return info.FileActors[Math.Min(1, info.FileActors.Length - 1)];
}
@@ -772,7 +772,7 @@ void ApplyAgents(World w, List snapshots)
agents[snap.Id] = unit;
agentHome[snap.Id] = home;
agentTarget[snap.Id] = home;
- agentLabels[snap.Id] = unit.TraitOrDefault();
+ agentLabels[snap.Id] = unit.TraitOrDefault();
}
if (!unit.IsInWorld)
@@ -980,10 +980,10 @@ public void SendComposed(string text)
if (boundId == AllTerminals)
{
foreach (var id in TerminalIds)
- ClankerBackend.Post("/agent/ask", new { terminal = id, text });
+ CombobulateBackend.Post("/agent/ask", new { terminal = id, text });
}
else if (!string.IsNullOrEmpty(boundId))
- ClankerBackend.Post("/agent/ask", new { terminal = boundId, text });
+ CombobulateBackend.Post("/agent/ask", new { terminal = boundId, text });
}
// Queue raw keystrokes for the selected terminal's PTY (e.g. "\r", "\x03").
@@ -1069,7 +1069,7 @@ void ParseGrid(string json)
foreach (var l in linesEl.EnumerateArray())
lines[i++] = l.GetString() ?? "";
- termGrid = new ClankerTermGrid
+ termGrid = new CombobulateTermGrid
{
Cols = root.GetProperty("cols").GetInt32(),
Rows = root.GetProperty("rows").GetInt32(),
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerBuiltTerminal.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateBuiltTerminal.cs
similarity index 54%
rename from command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerBuiltTerminal.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateBuiltTerminal.cs
index 8cd9e07..9c3968d 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerBuiltTerminal.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateBuiltTerminal.cs
@@ -1,31 +1,31 @@
using OpenRA.Traits;
-namespace OpenRA.Mods.Clanker.Traits
+namespace OpenRA.Mods.Combobulate.Traits
{
[Desc("On a player-built Terminal building, asks the backend to create a",
"terminal and claims the returned id so this building becomes that",
"terminal's island. Bridge-spawned islands already carry an id and are",
"left alone.")]
- public class ClankerBuiltTerminalInfo : TraitInfo, Requires
+ public class CombobulateBuiltTerminalInfo : TraitInfo, Requires
{
- public override object Create(ActorInitializer init) { return new ClankerBuiltTerminal(); }
+ public override object Create(ActorInitializer init) { return new CombobulateBuiltTerminal(); }
}
- public class ClankerBuiltTerminal : INotifyAddedToWorld
+ public class CombobulateBuiltTerminal : INotifyAddedToWorld
{
void INotifyAddedToWorld.AddedToWorld(Actor self)
{
- var termRef = self.Trait();
+ var termRef = self.Trait();
if (!string.IsNullOrEmpty(termRef.TerminalId))
return;
- ClankerBackend.PostForId("/term/new", new { cols = 80, rows = 24 }, id =>
+ CombobulateBackend.PostForId("/term/new", new { cols = 80, rows = 24 }, id =>
{
if (!self.IsInWorld)
return;
termRef.TerminalId = id;
- self.World.WorldActor.TraitOrDefault()?.RegisterPlayerTerminal(id, self);
+ self.World.WorldActor.TraitOrDefault()?.RegisterPlayerTerminal(id, self);
});
}
}
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerLabel.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateLabel.cs
similarity index 76%
rename from command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerLabel.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateLabel.cs
index 0a305fd..6754b58 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerLabel.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateLabel.cs
@@ -5,18 +5,18 @@
using OpenRA.Primitives;
using OpenRA.Traits;
-namespace OpenRA.Mods.Clanker.Traits
+namespace OpenRA.Mods.Combobulate.Traits
{
- [Desc("Floating text over a clanker agent unit, set at runtime by ClankerBridge",
+ [Desc("Floating text over a combobulate agent unit, set at runtime by CombobulateBridge",
"to show what the agent is doing right now (READ / WRITE / RUN).")]
- public class ClankerLabelInfo : WithDecorationBaseInfo
+ public class CombobulateLabelInfo : WithDecorationBaseInfo
{
public readonly string Font = "TinyBold";
[Desc("Text colour.")]
public readonly Color Color = Color.White;
- public override object Create(ActorInitializer init) { return new ClankerLabel(init.Self, this); }
+ public override object Create(ActorInitializer init) { return new CombobulateLabel(init.Self, this); }
public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
{
@@ -27,11 +27,11 @@ public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
}
}
- public class ClankerLabel : WithDecorationBase
+ public class CombobulateLabel : WithDecorationBase
{
readonly SpriteFont font;
- // Written by ClankerBridge on the game thread; read here when rendering.
+ // Written by CombobulateBridge on the game thread; read here when rendering.
// A torn read of a string reference is harmless, so no synchronization.
public string Label = "";
@@ -39,7 +39,7 @@ public class ClankerLabel : WithDecorationBase
// as it fills); falls back to the actor's configured colour when null.
public Color? LabelColor = null;
- public ClankerLabel(Actor self, ClankerLabelInfo info)
+ public CombobulateLabel(Actor self, CombobulateLabelInfo info)
: base(self, info)
{
font = Game.Renderer.Fonts[info.Font];
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerSidebarLoader.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateSidebarLoader.cs
similarity index 60%
rename from command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerSidebarLoader.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateSidebarLoader.cs
index fa0c5d9..0860cb3 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerSidebarLoader.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateSidebarLoader.cs
@@ -2,23 +2,23 @@
using OpenRA.Traits;
using OpenRA.Widgets;
-namespace OpenRA.Mods.Clanker.Traits
+namespace OpenRA.Mods.Combobulate.Traits
{
[TraitLocation(SystemActors.World)]
- [Desc("Loads the Command & Clanker interactive terminal panel into the ingame UI when a game starts.")]
- public class ClankerSidebarLoaderInfo : TraitInfo
+ [Desc("Loads the Command & Combobulate interactive terminal panel into the ingame UI when a game starts.")]
+ public class CombobulateSidebarLoaderInfo : TraitInfo
{
[Desc("Interactive terminal panel to load into the UI root.")]
- public readonly string TerminalWidget = "CLANKER_TERMINAL";
+ public readonly string TerminalWidget = "COMBOBULATE_TERMINAL";
- public override object Create(ActorInitializer init) { return new ClankerSidebarLoader(this); }
+ public override object Create(ActorInitializer init) { return new CombobulateSidebarLoader(this); }
}
- public class ClankerSidebarLoader : IWorldLoaded
+ public class CombobulateSidebarLoader : IWorldLoaded
{
- readonly ClankerSidebarLoaderInfo info;
+ readonly CombobulateSidebarLoaderInfo info;
- public ClankerSidebarLoader(ClankerSidebarLoaderInfo info)
+ public CombobulateSidebarLoader(CombobulateSidebarLoaderInfo info)
{
this.info = info;
}
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerTermGrid.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateTermGrid.cs
similarity index 84%
rename from command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerTermGrid.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateTermGrid.cs
index 2b10883..3d5e080 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerTermGrid.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateTermGrid.cs
@@ -1,9 +1,9 @@
-namespace OpenRA.Mods.Clanker.Traits
+namespace OpenRA.Mods.Combobulate.Traits
{
// An immutable snapshot of a terminal's resolved screen, produced by the
// bridge from /termview frames and read by the terminal widget. Replaced
// wholesale on each frame so readers never see a half-updated grid.
- public sealed class ClankerTermGrid
+ public sealed class CombobulateTermGrid
{
public string[] Lines { get; init; } = System.Array.Empty();
public int Cols { get; init; }
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerTerminalRef.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateTerminalRef.cs
similarity index 58%
rename from command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerTerminalRef.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateTerminalRef.cs
index 44aa1e3..38cb669 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/Traits/ClankerTerminalRef.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/Traits/CombobulateTerminalRef.cs
@@ -1,34 +1,34 @@
using System.Collections.Generic;
using OpenRA.Traits;
-namespace OpenRA.Mods.Clanker.Traits
+namespace OpenRA.Mods.Combobulate.Traits
{
[Desc("Marks a terminal-island building with its backend terminal id and the",
"agent's recent action log, so the sidebar can read them when it is selected.")]
- public class ClankerTerminalRefInfo : TraitInfo
+ public class CombobulateTerminalRefInfo : TraitInfo
{
- public override object Create(ActorInitializer init) { return new ClankerTerminalRef(init); }
+ public override object Create(ActorInitializer init) { return new CombobulateTerminalRef(init); }
}
- public class ClankerTerminalRef
+ public class CombobulateTerminalRef
{
// Settable so a player-built Terminal can claim its id after the backend
// assigns one; bridge-spawned islands get it from the init.
public string TerminalId { get; set; }
- // Set by ClankerBridge on the game thread; read by the sidebar logic.
+ // Set by CombobulateBridge on the game thread; read by the sidebar logic.
public IReadOnlyList Recent = new List();
// A short description of what the agent is doing right now (or "idle").
public string Activity = "idle";
- public ClankerTerminalRef(ActorInitializer init)
+ public CombobulateTerminalRef(ActorInitializer init)
{
- TerminalId = init.GetValue("");
+ TerminalId = init.GetValue("");
}
}
- public class ClankerTerminalRefInit(string value) : ValueActorInit(value), ISingleInstanceInit
+ public class CombobulateTerminalRefInit(string value) : ValueActorInit(value), ISingleInstanceInit
{
}
}
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/UtilityCommands/CreateCanvasMapCommand.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/UtilityCommands/CreateCanvasMapCommand.cs
similarity index 86%
rename from command-and-clanker/OpenRA.Mods.Clanker/UtilityCommands/CreateCanvasMapCommand.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/UtilityCommands/CreateCanvasMapCommand.cs
index e434d84..de93f13 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/UtilityCommands/CreateCanvasMapCommand.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/UtilityCommands/CreateCanvasMapCommand.cs
@@ -3,9 +3,9 @@
using OpenRA.FileSystem;
using OpenRA.Primitives;
-namespace OpenRA.Mods.Clanker.UtilityCommands
+namespace OpenRA.Mods.Combobulate.UtilityCommands
{
- // One-shot generator for the Command & Clanker canvas: a flat, open map made
+ // One-shot generator for the Command & Combobulate canvas: a flat, open map made
// entirely of clear terrain, so the live world (islands, walled folders, and
// agent units) sits on ground we control instead of fighting an RA map's
// pre-built walls, water, and ore.
@@ -19,7 +19,7 @@ bool IUtilityCommand.ValidateArguments(string[] args)
}
[Desc("OUTPUTDIR [SIZE]",
- "Create a flat, open Command & Clanker canvas map (all clear terrain) at OUTPUTDIR.")]
+ "Create a flat, open Command & Combobulate canvas map (all clear terrain) at OUTPUTDIR.")]
void IUtilityCommand.Run(Utility utility, string[] args)
{
// PlayerReference's default Color reads Game.ModData, so it must be set.
@@ -31,8 +31,8 @@ void IUtilityCommand.Run(Utility utility, string[] args)
var map = new Map(modData, terrain, new Size(size + 2, size + maxHeight + 2))
{
- Title = "Clanker Canvas",
- Author = "Command & Clanker",
+ Title = "Combobulate Canvas",
+ Author = "Command & Combobulate",
RequiresMod = modData.Manifest.Id,
};
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/Widgets/ClankerTerminalWidget.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/Widgets/CombobulateTerminalWidget.cs
similarity index 89%
rename from command-and-clanker/OpenRA.Mods.Clanker/Widgets/ClankerTerminalWidget.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/Widgets/CombobulateTerminalWidget.cs
index 38651da..2f2559b 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/Widgets/ClankerTerminalWidget.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/Widgets/CombobulateTerminalWidget.cs
@@ -1,34 +1,34 @@
using System;
-using OpenRA.Mods.Clanker.Traits;
+using OpenRA.Mods.Combobulate.Traits;
using OpenRA.Mods.Common.Widgets;
using OpenRA.Primitives;
using OpenRA.Widgets;
-namespace OpenRA.Mods.Clanker.Widgets
+namespace OpenRA.Mods.Combobulate.Widgets
{
// A live, interactive terminal view. The backend resolves the PTY into a
- // screen grid (see ClankerBridge.TerminalGrid); this widget paints each cell
+ // screen grid (see CombobulateBridge.TerminalGrid); this widget paints each cell
// at a fixed advance and forwards keystrokes back to the PTY. It is invisible
// until a terminal island is selected, and follows the selection itself.
//
// The cell size is measured from the font: for a monospace font every glyph
// advance is identical, so column positions stay perfectly aligned.
- public class ClankerTerminalWidget : Widget
+ public class CombobulateTerminalWidget : Widget
{
- public readonly string Font = "ClankerTerm";
+ public readonly string Font = "CombobulateTerm";
public readonly int LineGap = 2;
public readonly int Padding = 6;
public readonly Color Background = Color.FromArgb(235, 12, 14, 16);
public readonly Color Foreground = Color.FromArgb(220, 220, 220);
- readonly ClankerBridge bridge;
+ readonly CombobulateBridge bridge;
int lastResizeCols;
int lastResizeRows;
[ObjectCreator.UseCtor]
- public ClankerTerminalWidget(World world)
+ public CombobulateTerminalWidget(World world)
{
- bridge = world.WorldActor.TraitOrDefault();
+ bridge = world.WorldActor.TraitOrDefault();
}
// Pixel size of one character cell, taken from the font's own metrics.
@@ -44,7 +44,7 @@ public override void Tick()
if (bridge == null)
return;
- // The panel binding is driven by ClankerTerminalLogic; here we only keep
+ // The panel binding is driven by CombobulateTerminalLogic; here we only keep
// the streamed PTY sized to the grid. With no streamed terminal (the
// panel is dismissed or showing the All view) there is nothing to size.
if (string.IsNullOrEmpty(bridge.StreamedTerminal))
@@ -85,7 +85,7 @@ public override void Draw()
var oy = rb.Y + Padding;
// The All view has no single PTY to mirror; show what the composer targets.
- if (bridge.BoundTerminal == ClankerBridge.AllTerminals)
+ if (bridge.BoundTerminal == CombobulateBridge.AllTerminals)
{
font.DrawTextWithContrast(
$"All terminals — input broadcasts to {bridge.TerminalIds.Count} agent(s)",
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/Widgets/Logic/ClankerMenuLogic.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/Widgets/Logic/CombobulateMenuLogic.cs
similarity index 58%
rename from command-and-clanker/OpenRA.Mods.Clanker/Widgets/Logic/ClankerMenuLogic.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/Widgets/Logic/CombobulateMenuLogic.cs
index 5a50edc..f4ea0a3 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/Widgets/Logic/ClankerMenuLogic.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/Widgets/Logic/CombobulateMenuLogic.cs
@@ -1,17 +1,17 @@
using OpenRA.Mods.Common.Widgets;
using OpenRA.Widgets;
-namespace OpenRA.Mods.Clanker.Widgets.Logic
+namespace OpenRA.Mods.Combobulate.Widgets.Logic
{
- // The Command & Clanker shell menu: one button that boots straight into the
+ // The Command & Combobulate shell menu: one button that boots straight into the
// canvas map (no lobby), plus Quit. Replaces the stock main menu via the
// world's LoadWidgetAtGameStart.ShellmapRoot override.
- public class ClankerMenuLogic : ChromeLogic
+ public class CombobulateMenuLogic : ChromeLogic
{
[ObjectCreator.UseCtor]
- public ClankerMenuLogic(Widget widget)
+ public CombobulateMenuLogic(Widget widget)
{
- widget.Get("LAUNCH").OnClick = () => Game.LoadMap("clanker-canvas");
+ widget.Get("LAUNCH").OnClick = () => Game.LoadMap("combobulate-canvas");
widget.Get("QUIT").OnClick = Game.Exit;
}
}
diff --git a/command-and-clanker/OpenRA.Mods.Clanker/Widgets/Logic/ClankerTerminalLogic.cs b/command-and-combobulate/OpenRA.Mods.Combobulate/Widgets/Logic/CombobulateTerminalLogic.cs
similarity index 81%
rename from command-and-clanker/OpenRA.Mods.Clanker/Widgets/Logic/ClankerTerminalLogic.cs
rename to command-and-combobulate/OpenRA.Mods.Combobulate/Widgets/Logic/CombobulateTerminalLogic.cs
index 547c3b7..851eaa5 100644
--- a/command-and-clanker/OpenRA.Mods.Clanker/Widgets/Logic/ClankerTerminalLogic.cs
+++ b/command-and-combobulate/OpenRA.Mods.Combobulate/Widgets/Logic/CombobulateTerminalLogic.cs
@@ -1,26 +1,26 @@
-using OpenRA.Mods.Clanker.Traits;
+using OpenRA.Mods.Combobulate.Traits;
using OpenRA.Mods.Common.Widgets;
using OpenRA.Widgets;
-namespace OpenRA.Mods.Clanker.Widgets.Logic
+namespace OpenRA.Mods.Combobulate.Widgets.Logic
{
// Wires the native-chrome controls around the terminal grid: a button that
// cycles which terminal the panel mirrors (t1 -> ... -> All), a composer that
// sends a typed line to the bound agent(s), and a close button that dismisses
- // the panel. The grid itself is painted by ClankerTerminalWidget; this logic
+ // the panel. The grid itself is painted by CombobulateTerminalWidget; this logic
// only drives the chrome and reconciles it with the map selection.
- public class ClankerTerminalLogic : ChromeLogic
+ public class CombobulateTerminalLogic : ChromeLogic
{
readonly World world;
- readonly ClankerBridge bridge;
+ readonly CombobulateBridge bridge;
readonly Widget panel;
string lastSelection;
[ObjectCreator.UseCtor]
- public ClankerTerminalLogic(Widget widget, World world)
+ public CombobulateTerminalLogic(Widget widget, World world)
{
this.world = world;
- bridge = world.WorldActor.TraitOrDefault();
+ bridge = world.WorldActor.TraitOrDefault();
panel = widget.Get("PANEL");
@@ -31,7 +31,7 @@ public ClankerTerminalLogic(Widget widget, World world)
if (string.IsNullOrEmpty(bound))
return "—";
- return bound == ClankerBridge.AllTerminals ? "All" : bound;
+ return bound == CombobulateBridge.AllTerminals ? "All" : bound;
};
mode.OnClick = () => bridge?.CycleBoundTerminal();
@@ -91,7 +91,7 @@ string SelectedTerminal()
if (!a.IsInWorld)
continue;
- var r = a.TraitOrDefault();
+ var r = a.TraitOrDefault();
if (r != null)
return r.TerminalId;
}
diff --git a/command-and-clanker/fetch-engine.sh b/command-and-combobulate/fetch-engine.sh
similarity index 100%
rename from command-and-clanker/fetch-engine.sh
rename to command-and-combobulate/fetch-engine.sh
diff --git a/command-and-clanker/launch-dedicated.cmd b/command-and-combobulate/launch-dedicated.cmd
similarity index 100%
rename from command-and-clanker/launch-dedicated.cmd
rename to command-and-combobulate/launch-dedicated.cmd
diff --git a/command-and-clanker/launch-dedicated.sh b/command-and-combobulate/launch-dedicated.sh
similarity index 100%
rename from command-and-clanker/launch-dedicated.sh
rename to command-and-combobulate/launch-dedicated.sh
diff --git a/command-and-clanker/launch-game.cmd b/command-and-combobulate/launch-game.cmd
similarity index 100%
rename from command-and-clanker/launch-game.cmd
rename to command-and-combobulate/launch-game.cmd
diff --git a/command-and-clanker/launch-game.sh b/command-and-combobulate/launch-game.sh
similarity index 100%
rename from command-and-clanker/launch-game.sh
rename to command-and-combobulate/launch-game.sh
diff --git a/command-and-clanker/make.cmd b/command-and-combobulate/make.cmd
similarity index 100%
rename from command-and-clanker/make.cmd
rename to command-and-combobulate/make.cmd
diff --git a/command-and-clanker/make.ps1 b/command-and-combobulate/make.ps1
similarity index 100%
rename from command-and-clanker/make.ps1
rename to command-and-combobulate/make.ps1
diff --git a/command-and-clanker/mod.config b/command-and-combobulate/mod.config
similarity index 97%
rename from command-and-clanker/mod.config
rename to command-and-combobulate/mod.config
index 35351c3..7082731 100644
--- a/command-and-clanker/mod.config
+++ b/command-and-combobulate/mod.config
@@ -6,7 +6,7 @@
# The id of the mod packaged by this project.
# This must exist as a directory in the mods directory and should not contain spaces.
-MOD_ID="clanker"
+MOD_ID="combobulate"
# The OpenRA engine version to use for this project.
ENGINE_VERSION="playtest-20260222"
@@ -21,7 +21,7 @@ ENGINE_VERSION="playtest-20260222"
# - Windows installers will be named as {PACKAGING_INSTALLER_NAME}-{TAG}.exe
# - macOS installers will be named as {PACKAGING_INSTALLER_NAME}-{TAG}.dmg
# - Linux .appimages will be named as {PACKAGING_INSTALLER_NAME}-${TAG}.AppImage
-PACKAGING_INSTALLER_NAME="CommandAndClanker"
+PACKAGING_INSTALLER_NAME="CommandAndCombobulate"
# The human-readable name for this project.
# This is used in:
@@ -35,7 +35,7 @@ PACKAGING_INSTALLER_NAME="CommandAndClanker"
# - Windows desktop shortcut
# - Windows "Programs and Features" list
# - Linux launcher shortcut
-PACKAGING_DISPLAY_NAME="Command & Clanker"
+PACKAGING_DISPLAY_NAME="Command & Combobulate"
# The URL for the project homepage.
# This is used in:
diff --git a/command-and-clanker/mods/clanker/chrome/clanker-mainmenu.yaml b/command-and-combobulate/mods/combobulate/chrome/combobulate-mainmenu.yaml
similarity index 76%
rename from command-and-clanker/mods/clanker/chrome/clanker-mainmenu.yaml
rename to command-and-combobulate/mods/combobulate/chrome/combobulate-mainmenu.yaml
index 4681a78..1871bce 100644
--- a/command-and-clanker/mods/clanker/chrome/clanker-mainmenu.yaml
+++ b/command-and-combobulate/mods/combobulate/chrome/combobulate-mainmenu.yaml
@@ -1,5 +1,5 @@
-Container@CLANKER_MAINMENU:
- Logic: ClankerMenuLogic
+Container@COMBOBULATE_MAINMENU:
+ Logic: CombobulateMenuLogic
Width: WINDOW_WIDTH
Height: WINDOW_HEIGHT
Children:
@@ -17,17 +17,17 @@ Container@CLANKER_MAINMENU:
Height: 30
Font: BigBold
Align: Center
- Text: clanker-mod-title
+ Text: combobulate-mod-title
Button@LAUNCH:
X: (PARENT_WIDTH - WIDTH) / 2
Y: 96
Width: 280
Height: 44
Font: Bold
- Text: button-clanker-launch
+ Text: button-combobulate-launch
Button@QUIT:
X: (PARENT_WIDTH - WIDTH) / 2
Y: 152
Width: 280
Height: 34
- Text: button-clanker-quit
+ Text: button-combobulate-quit
diff --git a/command-and-clanker/mods/clanker/chrome/clanker-terminal.yaml b/command-and-combobulate/mods/combobulate/chrome/combobulate-terminal.yaml
similarity index 85%
rename from command-and-clanker/mods/clanker/chrome/clanker-terminal.yaml
rename to command-and-combobulate/mods/combobulate/chrome/combobulate-terminal.yaml
index 47cad87..d8b1b14 100644
--- a/command-and-clanker/mods/clanker/chrome/clanker-terminal.yaml
+++ b/command-and-combobulate/mods/combobulate/chrome/combobulate-terminal.yaml
@@ -1,5 +1,5 @@
-Container@CLANKER_TERMINAL:
- Logic: ClankerTerminalLogic
+Container@COMBOBULATE_TERMINAL:
+ Logic: CombobulateTerminalLogic
X: 12
Y: WINDOW_HEIGHT - HEIGHT - 12
Width: 732
@@ -10,12 +10,12 @@ Container@CLANKER_TERMINAL:
Height: PARENT_HEIGHT
Background: dialog
Children:
- ClankerTerminal@GRID:
+ CombobulateTerminal@GRID:
X: 9
Y: 9
Width: PARENT_WIDTH - 18
Height: PARENT_HEIGHT - 52
- Font: ClankerTerm
+ Font: CombobulateTerm
Padding: 6
LineGap: 2
Button@TERM_MODE:
diff --git a/command-and-combobulate/mods/combobulate/fluent/combobulate.ftl b/command-and-combobulate/mods/combobulate/fluent/combobulate.ftl
new file mode 100644
index 0000000..6fda983
--- /dev/null
+++ b/command-and-combobulate/mods/combobulate/fluent/combobulate.ftl
@@ -0,0 +1,8 @@
+combobulate-mod-title = Command & Combobulate
+combobulate-mod-windowtitle = Command & Combobulate
+loadscreen-loading = Comboluating..., Summoning subagents..., Compacting context..., Warming the prompt cache..., Reticulating splines..., Negotiating with the rate limiter..., Spinning up PTYs..., Aligning the combobulates..., Tokenizing the vibes..., Deploying robots...
+button-combobulate-launch = Start Combobulating
+button-combobulate-quit = Quit
+actor-combobulate-terminal =
+ .name = Terminal
+ .description = Spawns a Command & Combobulate agent terminal.
diff --git a/command-and-clanker/mods/clanker/fonts/DejaVuSansMono.ttf b/command-and-combobulate/mods/combobulate/fonts/DejaVuSansMono.ttf
similarity index 100%
rename from command-and-clanker/mods/clanker/fonts/DejaVuSansMono.ttf
rename to command-and-combobulate/mods/combobulate/fonts/DejaVuSansMono.ttf
diff --git a/command-and-clanker/mods/clanker/maps/clanker-canvas/map.bin b/command-and-combobulate/mods/combobulate/maps/combobulate-canvas/map.bin
similarity index 100%
rename from command-and-clanker/mods/clanker/maps/clanker-canvas/map.bin
rename to command-and-combobulate/mods/combobulate/maps/combobulate-canvas/map.bin
diff --git a/command-and-clanker/mods/clanker/maps/clanker-canvas/map.png b/command-and-combobulate/mods/combobulate/maps/combobulate-canvas/map.png
similarity index 100%
rename from command-and-clanker/mods/clanker/maps/clanker-canvas/map.png
rename to command-and-combobulate/mods/combobulate/maps/combobulate-canvas/map.png
diff --git a/command-and-clanker/mods/clanker/maps/clanker-canvas/map.yaml b/command-and-combobulate/mods/combobulate/maps/combobulate-canvas/map.yaml
similarity index 94%
rename from command-and-clanker/mods/clanker/maps/clanker-canvas/map.yaml
rename to command-and-combobulate/mods/combobulate/maps/combobulate-canvas/map.yaml
index 8486c4c..3b5e830 100644
--- a/command-and-clanker/mods/clanker/maps/clanker-canvas/map.yaml
+++ b/command-and-combobulate/mods/combobulate/maps/combobulate-canvas/map.yaml
@@ -1,10 +1,10 @@
MapFormat: 12
-RequiresMod: clanker
+RequiresMod: combobulate
-Title: Clanker Canvas
+Title: Combobulate Canvas
-Author: Command & Clanker
+Author: Command & Combobulate
Tileset: TEMPERAT
diff --git a/command-and-clanker/mods/clanker/mod.yaml b/command-and-combobulate/mods/combobulate/mod.yaml
similarity index 92%
rename from command-and-clanker/mods/clanker/mod.yaml
rename to command-and-combobulate/mods/combobulate/mod.yaml
index 293d3cd..b863150 100644
--- a/command-and-clanker/mods/clanker/mod.yaml
+++ b/command-and-combobulate/mods/combobulate/mod.yaml
@@ -1,9 +1,9 @@
Metadata:
- Title: clanker-mod-title
+ Title: combobulate-mod-title
Version: 0.0.1
Website: https://www.openra.net
WebIcon32: https://www.openra.net/images/icons/ra_32x32.png
- WindowTitle: clanker-mod-windowtitle
+ WindowTitle: combobulate-mod-windowtitle
PackageFormats: Mix
@@ -11,7 +11,7 @@ FileSystem: ContentInstallerFileSystem
SystemPackages:
^EngineDir
^EngineDir|mods/ra: ra
- $clanker: clanker
+ $combobulate: combobulate
^EngineDir|mods/common: common
~^SupportDir|Content/ra/v2/: content
common|scripts
@@ -68,7 +68,7 @@ FileSystem: ContentInstallerFileSystem
ContentInstallerMod: ra-content
MapFolders:
- clanker|maps: System
+ combobulate|maps: System
ra|maps: System
~^SupportDir|maps/ra/{DEV_VERSION}: User
@@ -89,8 +89,8 @@ Rules:
ra|rules/ships.yaml
ra|rules/fakes.yaml
ra|rules/map-generators.yaml
- clanker|rules/world.yaml
- clanker|rules/actors.yaml
+ combobulate|rules/world.yaml
+ combobulate|rules/actors.yaml
Sequences:
ra|sequences/ships.yaml
@@ -113,7 +113,7 @@ Cursors:
Chrome:
ra|chrome.yaml
-Assemblies: OpenRA.Mods.Common.dll, OpenRA.Mods.Cnc.dll, OpenRA.Mods.Clanker.dll
+Assemblies: OpenRA.Mods.Common.dll, OpenRA.Mods.Cnc.dll, OpenRA.Mods.Combobulate.dll
ChromeLayout:
common|chrome/ingame.yaml
@@ -170,8 +170,8 @@ ChromeLayout:
common|chrome/editor.yaml
common|chrome/playerprofile.yaml
common|chrome/text-notifications.yaml
- clanker|chrome/clanker-terminal.yaml
- clanker|chrome/clanker-mainmenu.yaml
+ combobulate|chrome/combobulate-terminal.yaml
+ combobulate|chrome/combobulate-mainmenu.yaml
FluentMessages:
common|fluent/common.ftl
@@ -182,7 +182,7 @@ FluentMessages:
ra|fluent/chrome.ftl
ra|fluent/hotkeys.ftl
ra|fluent/rules.ftl
- clanker|fluent/clanker.ftl
+ combobulate|fluent/combobulate.ftl
AllowUnusedFluentMessagesInExternalPackages: true
@@ -214,10 +214,10 @@ Hotkeys:
common|hotkeys/control-groups.yaml
ra|hotkeys.yaml
-LoadScreen: ClankerLoadScreen
- Image: clanker|uibits/clanker-loadscreen.png
- Image2x: clanker|uibits/clanker-loadscreen-2x.png
- Image3x: clanker|uibits/clanker-loadscreen-3x.png
+LoadScreen: CombobulateLoadScreen
+ Image: combobulate|uibits/combobulate-loadscreen.png
+ Image2x: combobulate|uibits/combobulate-loadscreen-2x.png
+ Image3x: combobulate|uibits/combobulate-loadscreen-3x.png
ServerTraits:
LobbyCommands
@@ -262,8 +262,8 @@ Fonts:
Font: ra|ZoodRangmah.ttf
Size: 48
Ascender: 26
- ClankerTerm:
- Font: clanker|fonts/DejaVuSansMono.ttf
+ CombobulateTerm:
+ Font: combobulate|fonts/DejaVuSansMono.ttf
Size: 14
Ascender: 11
diff --git a/command-and-clanker/mods/clanker/rules/actors.yaml b/command-and-combobulate/mods/combobulate/rules/actors.yaml
similarity index 83%
rename from command-and-clanker/mods/clanker/rules/actors.yaml
rename to command-and-combobulate/mods/combobulate/rules/actors.yaml
index 33c56db..5ac13dc 100644
--- a/command-and-clanker/mods/clanker/rules/actors.yaml
+++ b/command-and-combobulate/mods/combobulate/rules/actors.yaml
@@ -1,7 +1,7 @@
-clanker.terminal:
+combobulate.terminal:
Inherits: PDOX
# RenderSprites.Image defaults to the actor name, so without this override
- # the engine looks for sequences under `clanker.terminal` instead of `pdox`
+ # the engine looks for sequences under `combobulate.terminal` instead of `pdox`
# and the production palette crashes refreshing the cameo.
RenderSprites:
Image: pdox
@@ -12,11 +12,11 @@ clanker.terminal:
# is always available and uncapped.
Prerequisites: ~techlevel.infonly
BuildLimit: 0
- Description: actor-clanker-terminal.description
+ Description: actor-combobulate-terminal.description
Valued:
Cost: 100
Tooltip:
- Name: actor-clanker-terminal.name
+ Name: actor-combobulate-terminal.name
# PDOX draws -200 power and hosts the Chronosphere superweapon. Strip both
# so the Terminal is a plain building.
Power:
@@ -28,28 +28,28 @@ clanker.terminal:
-ProvidesPrerequisite@germanstructure:
-ProvidesPrerequisite@buildingname:
-MustBeDestroyed:
- ClankerTerminalRef:
- ClankerBuiltTerminal:
+ CombobulateTerminalRef:
+ CombobulateBuiltTerminal:
# Context-window readout over the terminal; the bridge sets the text and
# reddens it as the agent's context fills (the base browns out).
- ClankerLabel:
+ CombobulateLabel:
Font: Bold
Position: Top
ValidRelationships: Ally, Neutral, Enemy
Color: 9EE6A0
-clanker.folderwall:
+combobulate.folderwall:
Inherits: SBAG
RenderSprites:
Image: sbag
Interactable:
- ClankerLabel:
+ CombobulateLabel:
Font: Bold
Position: Top
ValidRelationships: Ally, Neutral, Enemy
Color: FFFFAA
-clanker.agent:
+combobulate.agent:
Inherits: HELI
RenderSprites:
Image: heli
@@ -62,106 +62,106 @@ clanker.agent:
-Buildable:
Aircraft:
Speed: 170
- ClankerLabel:
+ CombobulateLabel:
Position: Top
ValidRelationships: Ally, Neutral, Enemy
Color: FFE066
-clanker.agent.codex:
+combobulate.agent.codex:
Inherits: ARTY
RenderSprites:
Image: arty
Mobile:
Speed: 170
- ClankerLabel:
+ CombobulateLabel:
Position: Top
ValidRelationships: Ally, Neutral, Enemy
Color: FF99CC
-clanker.subagent:
+combobulate.subagent:
Inherits: E1
RenderSprites:
Image: e1
Mobile:
Speed: 120
- ClankerLabel:
+ CombobulateLabel:
Position: Top
ValidRelationships: Ally, Neutral, Enemy
Color: FFE066
# One small civilian house per touched file. The label (file name + size) shows
# only while the house is selected, so the commander clicks one to inspect it.
-clanker.file1:
+combobulate.file1:
Inherits: V05
RenderSprites:
Image: v05
- ClankerLabel:
+ CombobulateLabel:
Font: TinyBold
Position: Top
RequiresSelection: true
ValidRelationships: Ally, Neutral, Enemy
Color: FFFFFF
-clanker.file2:
+combobulate.file2:
Inherits: V06
RenderSprites:
Image: v06
- ClankerLabel:
+ CombobulateLabel:
Font: TinyBold
Position: Top
RequiresSelection: true
ValidRelationships: Ally, Neutral, Enemy
Color: FFFFFF
-clanker.file3:
+combobulate.file3:
Inherits: V07
RenderSprites:
Image: v07
- ClankerLabel:
+ CombobulateLabel:
Font: TinyBold
Position: Top
RequiresSelection: true
ValidRelationships: Ally, Neutral, Enemy
Color: FFFFFF
-clanker.file4:
+combobulate.file4:
Inherits: V08
RenderSprites:
Image: v08
- ClankerLabel:
+ CombobulateLabel:
Font: TinyBold
Position: Top
RequiresSelection: true
ValidRelationships: Ally, Neutral, Enemy
Color: FFFFFF
-clanker.file5:
+combobulate.file5:
Inherits: V09
RenderSprites:
Image: v09
- ClankerLabel:
+ CombobulateLabel:
Font: TinyBold
Position: Top
RequiresSelection: true
ValidRelationships: Ally, Neutral, Enemy
Color: FFFFFF
-clanker.file6:
+combobulate.file6:
Inherits: V10
RenderSprites:
Image: v10
- ClankerLabel:
+ CombobulateLabel:
Font: TinyBold
Position: Top
RequiresSelection: true
ValidRelationships: Ally, Neutral, Enemy
Color: FFFFFF
-clanker.file7:
+combobulate.file7:
Inherits: V11
RenderSprites:
Image: v11
- ClankerLabel:
+ CombobulateLabel:
Font: TinyBold
Position: Top
RequiresSelection: true
@@ -173,68 +173,68 @@ clanker.file7:
# radar dome for docs, a silo for build output. They are spawned as inert
# neutral decorations: Buildable is dropped (no production here) and Power is
# zeroed so they do not perturb a power grid.
-clanker.file.test:
+combobulate.file.test:
Inherits: TENT
RenderSprites:
Image: tent
-Buildable:
- ClankerLabel:
+ CombobulateLabel:
Font: TinyBold
Position: Top
RequiresSelection: true
ValidRelationships: Ally, Neutral, Enemy
Color: FFFFFF
-clanker.file.config:
+combobulate.file.config:
Inherits: POWR
RenderSprites:
Image: powr
-Buildable:
Power:
Amount: 0
- ClankerLabel:
+ CombobulateLabel:
Font: TinyBold
Position: Top
RequiresSelection: true
ValidRelationships: Ally, Neutral, Enemy
Color: FFFFFF
-clanker.file.manifest:
+combobulate.file.manifest:
Inherits: ATEK
RenderSprites:
Image: atek
-Buildable:
Power:
Amount: 0
- ClankerLabel:
+ CombobulateLabel:
Font: TinyBold
Position: Top
RequiresSelection: true
ValidRelationships: Ally, Neutral, Enemy
Color: FFFFFF
-clanker.file.docs:
+combobulate.file.docs:
Inherits: DOME
RenderSprites:
Image: dome
-Buildable:
Power:
Amount: 0
- ClankerLabel:
+ CombobulateLabel:
Font: TinyBold
Position: Top
RequiresSelection: true
ValidRelationships: Ally, Neutral, Enemy
Color: FFFFFF
-clanker.file.build:
+combobulate.file.build:
Inherits: SILO
RenderSprites:
Image: silo
-Buildable:
Power:
Amount: 0
- ClankerLabel:
+ CombobulateLabel:
Font: TinyBold
Position: Top
RequiresSelection: true
diff --git a/command-and-combobulate/mods/combobulate/rules/world.yaml b/command-and-combobulate/mods/combobulate/rules/world.yaml
new file mode 100644
index 0000000..3c15116
--- /dev/null
+++ b/command-and-combobulate/mods/combobulate/rules/world.yaml
@@ -0,0 +1,7 @@
+World:
+ CombobulateBridge:
+ CombobulateSidebarLoader:
+ LoadWidgetAtGameStart:
+ ShellmapRoot: COMBOBULATE_MAINMENU
+ MapOptions:
+ TechLevel: unrestricted
diff --git a/command-and-clanker/mods/clanker/uibits/README.md b/command-and-combobulate/mods/combobulate/uibits/README.md
similarity index 75%
rename from command-and-clanker/mods/clanker/uibits/README.md
rename to command-and-combobulate/mods/combobulate/uibits/README.md
index ba5d22d..97d1cf3 100644
--- a/command-and-clanker/mods/clanker/uibits/README.md
+++ b/command-and-combobulate/mods/combobulate/uibits/README.md
@@ -6,8 +6,8 @@ below and the game picks them up on next launch — no code changes needed.
## Load screen (banner logo)
A centered banner on the loading screen (dark background + animated stripe +
the loading phrases). Wide 2:1 banner, PNG, transparent or dark background.
-- `clanker-loadscreen.png` — 512x256
-- `clanker-loadscreen-2x.png` — 1024x512
-- `clanker-loadscreen-3x.png` — 2048x1024
+- `combobulate-loadscreen.png` — 512x256
+- `combobulate-loadscreen-2x.png` — 1024x512
+- `combobulate-loadscreen-3x.png` — 2048x1024
(The committed files are dark placeholders; overwrite them with real art.)
diff --git a/command-and-combobulate/mods/combobulate/uibits/combobulate-loadscreen-2x.png b/command-and-combobulate/mods/combobulate/uibits/combobulate-loadscreen-2x.png
new file mode 100644
index 0000000..ab8606f
Binary files /dev/null and b/command-and-combobulate/mods/combobulate/uibits/combobulate-loadscreen-2x.png differ
diff --git a/command-and-combobulate/mods/combobulate/uibits/combobulate-loadscreen-3x.png b/command-and-combobulate/mods/combobulate/uibits/combobulate-loadscreen-3x.png
new file mode 100644
index 0000000..53123e1
Binary files /dev/null and b/command-and-combobulate/mods/combobulate/uibits/combobulate-loadscreen-3x.png differ
diff --git a/command-and-combobulate/mods/combobulate/uibits/combobulate-loadscreen.png b/command-and-combobulate/mods/combobulate/uibits/combobulate-loadscreen.png
new file mode 100644
index 0000000..a2af692
Binary files /dev/null and b/command-and-combobulate/mods/combobulate/uibits/combobulate-loadscreen.png differ
diff --git a/command-and-clanker/omnisharp.json b/command-and-combobulate/omnisharp.json
similarity index 100%
rename from command-and-clanker/omnisharp.json
rename to command-and-combobulate/omnisharp.json
diff --git a/command-and-combobulate/package.json b/command-and-combobulate/package.json
new file mode 100644
index 0000000..8b1413b
--- /dev/null
+++ b/command-and-combobulate/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "command-and-combobulate-mod",
+ "version": "0.1.0",
+ "private": true,
+ "description": "Command & Combobulate OpenRA mod (built on the OpenRA Mod SDK).",
+ "scripts": {
+ "build": "make",
+ "launch": "./launch-game.sh",
+ "game": "make && ./launch-game.sh",
+ "utility": "./utility.sh combobulate"
+ }
+}
diff --git a/command-and-clanker/packaging/artwork/icon_1024x1024.png b/command-and-combobulate/packaging/artwork/icon_1024x1024.png
similarity index 100%
rename from command-and-clanker/packaging/artwork/icon_1024x1024.png
rename to command-and-combobulate/packaging/artwork/icon_1024x1024.png
diff --git a/command-and-clanker/packaging/artwork/icon_128x128.png b/command-and-combobulate/packaging/artwork/icon_128x128.png
similarity index 100%
rename from command-and-clanker/packaging/artwork/icon_128x128.png
rename to command-and-combobulate/packaging/artwork/icon_128x128.png
diff --git a/command-and-clanker/packaging/artwork/icon_16x16.png b/command-and-combobulate/packaging/artwork/icon_16x16.png
similarity index 100%
rename from command-and-clanker/packaging/artwork/icon_16x16.png
rename to command-and-combobulate/packaging/artwork/icon_16x16.png
diff --git a/command-and-clanker/packaging/artwork/icon_24x24.png b/command-and-combobulate/packaging/artwork/icon_24x24.png
similarity index 100%
rename from command-and-clanker/packaging/artwork/icon_24x24.png
rename to command-and-combobulate/packaging/artwork/icon_24x24.png
diff --git a/command-and-clanker/packaging/artwork/icon_256x256.png b/command-and-combobulate/packaging/artwork/icon_256x256.png
similarity index 100%
rename from command-and-clanker/packaging/artwork/icon_256x256.png
rename to command-and-combobulate/packaging/artwork/icon_256x256.png
diff --git a/command-and-clanker/packaging/artwork/icon_32x32.png b/command-and-combobulate/packaging/artwork/icon_32x32.png
similarity index 100%
rename from command-and-clanker/packaging/artwork/icon_32x32.png
rename to command-and-combobulate/packaging/artwork/icon_32x32.png
diff --git a/command-and-clanker/packaging/artwork/icon_48x48.png b/command-and-combobulate/packaging/artwork/icon_48x48.png
similarity index 100%
rename from command-and-clanker/packaging/artwork/icon_48x48.png
rename to command-and-combobulate/packaging/artwork/icon_48x48.png
diff --git a/command-and-clanker/packaging/artwork/icon_512x512.png b/command-and-combobulate/packaging/artwork/icon_512x512.png
similarity index 100%
rename from command-and-clanker/packaging/artwork/icon_512x512.png
rename to command-and-combobulate/packaging/artwork/icon_512x512.png
diff --git a/command-and-clanker/packaging/artwork/icon_64x64.png b/command-and-combobulate/packaging/artwork/icon_64x64.png
similarity index 100%
rename from command-and-clanker/packaging/artwork/icon_64x64.png
rename to command-and-combobulate/packaging/artwork/icon_64x64.png
diff --git a/command-and-clanker/packaging/artwork/macos-background-2x.png b/command-and-combobulate/packaging/artwork/macos-background-2x.png
similarity index 100%
rename from command-and-clanker/packaging/artwork/macos-background-2x.png
rename to command-and-combobulate/packaging/artwork/macos-background-2x.png
diff --git a/command-and-clanker/packaging/artwork/macos-background.png b/command-and-combobulate/packaging/artwork/macos-background.png
similarity index 100%
rename from command-and-clanker/packaging/artwork/macos-background.png
rename to command-and-combobulate/packaging/artwork/macos-background.png
diff --git a/command-and-clanker/packaging/functions.sh b/command-and-combobulate/packaging/functions.sh
similarity index 100%
rename from command-and-clanker/packaging/functions.sh
rename to command-and-combobulate/packaging/functions.sh
diff --git a/command-and-clanker/packaging/linux/buildpackage.sh b/command-and-combobulate/packaging/linux/buildpackage.sh
similarity index 100%
rename from command-and-clanker/packaging/linux/buildpackage.sh
rename to command-and-combobulate/packaging/linux/buildpackage.sh
diff --git a/command-and-clanker/packaging/macos/buildpackage.sh b/command-and-combobulate/packaging/macos/buildpackage.sh
similarity index 100%
rename from command-and-clanker/packaging/macos/buildpackage.sh
rename to command-and-combobulate/packaging/macos/buildpackage.sh
diff --git a/command-and-clanker/packaging/package-all.sh b/command-and-combobulate/packaging/package-all.sh
similarity index 100%
rename from command-and-clanker/packaging/package-all.sh
rename to command-and-combobulate/packaging/package-all.sh
diff --git a/command-and-clanker/packaging/windows/buildpackage.nsi b/command-and-combobulate/packaging/windows/buildpackage.nsi
similarity index 100%
rename from command-and-clanker/packaging/windows/buildpackage.nsi
rename to command-and-combobulate/packaging/windows/buildpackage.nsi
diff --git a/command-and-clanker/packaging/windows/buildpackage.sh b/command-and-combobulate/packaging/windows/buildpackage.sh
similarity index 100%
rename from command-and-clanker/packaging/windows/buildpackage.sh
rename to command-and-combobulate/packaging/windows/buildpackage.sh
diff --git a/command-and-clanker/utility.cmd b/command-and-combobulate/utility.cmd
similarity index 100%
rename from command-and-clanker/utility.cmd
rename to command-and-combobulate/utility.cmd
diff --git a/command-and-clanker/utility.sh b/command-and-combobulate/utility.sh
similarity index 100%
rename from command-and-clanker/utility.sh
rename to command-and-combobulate/utility.sh
diff --git a/docs/architecture.md b/docs/architecture.md
index 0ebfb35..a73d3a9 100644
--- a/docs/architecture.md
+++ b/docs/architecture.md
@@ -1,37 +1,37 @@
# Architecture
-Command & Clanker is two pieces: a Node **backend** that ingests agent activity and
+Command & Combobulate is two pieces: a Node **backend** that ingests agent activity and
owns the real terminals, and an **OpenRA mod** that renders that activity inside the
OpenRA engine. The world is event-driven — agents report their tool calls; nothing
scrapes `/proc`.
```
- Agent (Claude Code, Codex) in a Command & Clanker terminal
+ Agent (Claude Code, Codex) in a Command & Combobulate terminal
| adapter POSTs tool calls / lifecycle events
v
Node backend (server/)
- POST /ingest: normalize agent events -> agents + folder regions
- world builder: terminal + folder regions (a directory forest)
- - TerminalManager: real PTYs via node-pty; injects CLANKER_* into the shell;
+ - TerminalManager: real PTYs via node-pty; injects COMBOBULATE_* into the shell;
a headless xterm resolves each PTY into a screen grid
|
WebSocket: /live (agents + world deltas + files) and /termview (screen grids)
v
- OpenRA mod (command-and-clanker/)
- - ClankerBridge (world trait): connect on a background thread, apply deltas
+ OpenRA mod (command-and-combobulate/)
+ - CombobulateBridge (world trait): connect on a background thread, apply deltas
on the game thread -> terminal buildings, folder walls, file buildings,
agent units, fog
- - ClankerTerminalWidget: a live, interactive terminal panel
+ - CombobulateTerminalWidget: a live, interactive terminal panel
- Start menu: "Start Clanking" boots straight into the canvas map
```
## How an agent reaches the map
-Building a Terminal spawns a shell with `CLANKER_SESSION` (the terminal id),
-`CLANKER_INGEST` (the ingest URL), and `CLANKER_TOKEN`. An agent launched there runs
-a Command & Clanker adapter (see `integrations/`) that POSTs each tool call to
+Building a Terminal spawns a shell with `COMBOBULATE_SESSION` (the terminal id),
+`COMBOBULATE_INGEST` (the ingest URL), and `COMBOBULATE_TOKEN`. An agent launched there runs
+a Command & Combobulate adapter (see `integrations/`) that POSTs each tool call to
`/ingest`, authorized by the token and tagged with the session via
-`X-Clanker-Session` (and the tool via `X-Clanker-Tool`).
+`X-Combobulate-Session` (and the tool via `X-Combobulate-Tool`).
## Filesystem → map
@@ -101,10 +101,10 @@ Two layers of placement caching keep the map calm:
fills the gap nearest the origin instead of pushing everything outward.
- Inside a folder, child order is `dirs.sort()` and the grid shape is a
function of the child count, so adding a child only reshapes that subtree.
-- The mod (`ClankerBridge`) lays files inside `fileArea` keyed by stable rows
+- The mod (`CombobulateBridge`) lays files inside `fileArea` keyed by stable rows
so an evicted file's neighbours do not slide.
-Cache state is persisted to `.clanker-cache.json` (`server/persistence.ts`)
+Cache state is persisted to `.combobulate-cache.json` (`server/persistence.ts`)
so slots survive a backend restart.
### Wire-level summary
@@ -145,7 +145,7 @@ TTL eviction + terminal sync). It holds no domain logic of its own.
- **World builder** (`server/world-builder.ts`): a pure function of the live
terminals and touched folders, producing terminal regions and a nested folder
forest. `WorldService` (`server/world-service.ts`) wraps it with the
- `PlacementCache` (`server/persistence.ts`, `.clanker-cache.json`) that keeps
+ `PlacementCache` (`server/persistence.ts`, `.combobulate-cache.json`) that keeps
positions stable across restarts.
- **Broadcaster** (`server/live.ts`): owns the connected `/live` clients and
turns registry/world state into the `agents`, `world-delta`, and `files` wire
@@ -158,7 +158,7 @@ TTL eviction + terminal sync). It holds no domain logic of its own.
### HTTP / WebSocket surface
-- `POST /ingest` — agent events (token in `Authorization`, ids in `X-Clanker-*`).
+- `POST /ingest` — agent events (token in `Authorization`, ids in `X-Combobulate-*`).
- `GET /world` — one-shot world snapshot.
- `POST /term/new`, `POST /term/kill` — terminal lifecycle.
- `WS /term?id=` — raw PTY byte stream (`{i}` input, `{r:[c,r]}` resize).
@@ -166,23 +166,23 @@ TTL eviction + terminal sync). It holds no domain logic of its own.
- `POST /agent/freeze|unfreeze|interrupt|ask` — drive the agent's process.
- `WS /live` — `agents`, `world-delta`, and `files` on each tick and on change.
-## OpenRA mod (command-and-clanker/)
+## OpenRA mod (command-and-combobulate/)
Built on the OpenRA Mod SDK: `make` fetches the pinned engine (`mod.config`
-`ENGINE_VERSION`) and builds `OpenRA.Mods.Clanker` against it.
+`ENGINE_VERSION`) and builds `OpenRA.Mods.Combobulate` against it.
-- **ClankerBridge** (`Traits/ClankerBridge.cs`, on the World actor): runs the
+- **CombobulateBridge** (`Traits/CombobulateBridge.cs`, on the World actor): runs the
`/live` WebSocket on a background thread that only enqueues messages; all
World/Actor/resource changes happen on the game thread via `AddFrameEndTask`.
It turns regions into terminal buildings and folder walls (laid out as a stable
nested compounds), files into fog-hidden civilian buildings, and agents into units that drive to
the folder they are working in. It also consumes `/termview` and forwards
keystrokes back to the PTY.
-- **ClankerTerminalWidget** (`Widgets/`): paints the screen grid in a monospace
+- **CombobulateTerminalWidget** (`Widgets/`): paints the screen grid in a monospace
font and routes keystrokes to the selected terminal — a live, interactive
terminal inside the game.
-- **Mod files** (`mods/clanker/`): rules, sequences, chrome, fluent, and the
- `clanker-canvas` sandbox map; reuses OpenRA's Red Alert art.
+- **Mod files** (`mods/combobulate/`): rules, sequences, chrome, fluent, and the
+ `combobulate-canvas` sandbox map; reuses OpenRA's Red Alert art.
## Wire shapes
@@ -217,12 +217,12 @@ type AgentSnapshot = {
```
These TS wire types live in `shared/proc-types.ts` and `shared/types.ts` and are
-hand-mirrored in the C# mod's `OpenRA.Mods.Clanker/Protocol/LiveMessage.cs`.
+hand-mirrored in the C# mod's `OpenRA.Mods.Combobulate/Protocol/LiveMessage.cs`.
`shared/wire-contract.test.ts` fails the test run if the two ever drift.
## Determinism
Folder and terminal positions are deterministic: the backend's `PlacementCache`
-assigns stable slots (persisted to `.clanker-cache.json`), and the mod lays
+assigns stable slots (persisted to `.combobulate-cache.json`), and the mod lays
folders out as a stable indented tree keyed by recycled rows, so the map does not
reshuffle as folders come and go.
diff --git a/integrations/claude/.claude-plugin/marketplace.json b/integrations/claude/.claude-plugin/marketplace.json
index aed5c59..3fc98fe 100644
--- a/integrations/claude/.claude-plugin/marketplace.json
+++ b/integrations/claude/.claude-plugin/marketplace.json
@@ -1,11 +1,11 @@
{
- "name": "clanker",
- "owner": { "name": "Command & Clanker" },
+ "name": "combobulate",
+ "owner": { "name": "Command & Combobulate" },
"plugins": [
{
- "name": "clanker",
- "source": "./clanker",
- "description": "Stream Claude Code tool calls and subagents to the Command & Clanker map."
+ "name": "combobulate",
+ "source": "./combobulate",
+ "description": "Stream Claude Code tool calls and subagents to the Command & Combobulate map."
}
]
}
diff --git a/integrations/claude/README.md b/integrations/claude/README.md
index f678b0f..987f319 100644
--- a/integrations/claude/README.md
+++ b/integrations/claude/README.md
@@ -1,35 +1,35 @@
-# Command & Clanker adapter for Claude Code
+# Command & Combobulate adapter for Claude Code
This plugin streams every Claude Code tool call and subagent event to a
-running Command & Clanker server (`POST /ingest`), so the agent's activity is rendered on
+running Command & Combobulate server (`POST /ingest`), so the agent's activity is rendered on
the map. It is the event source that replaces `/proc` scraping.
## How it ties to a terminal island
-When you build a terminal inside Command & Clanker, the server injects three env vars into
+When you build a terminal inside Command & Combobulate, the server injects three env vars into
that shell:
-- `CLANKER_SESSION` — the terminal island id (e.g. `t1`)
-- `CLANKER_INGEST` — the ingest URL (default `http://127.0.0.1:3001/ingest`)
-- `CLANKER_TOKEN` — a per-run token authorizing the endpoint
+- `COMBOBULATE_SESSION` — the terminal island id (e.g. `t1`)
+- `COMBOBULATE_INGEST` — the ingest URL (default `http://127.0.0.1:3001/ingest`)
+- `COMBOBULATE_TOKEN` — a per-run token authorizing the endpoint
-The hooks send `CLANKER_SESSION` and `CLANKER_TOKEN` as headers, so the server knows
-which island the events belong to. Run Claude Code **inside an Command & Clanker terminal**
+The hooks send `COMBOBULATE_SESSION` and `COMBOBULATE_TOKEN` as headers, so the server knows
+which island the events belong to. Run Claude Code **inside an Command & Combobulate terminal**
and its reads/writes/subagents animate on that terminal's island.
## Install
From the repo, run `bun run setup` once: it merges these hooks (as an absolute
command path) into `~/.claude/settings.json`, so any `claude` launched inside an
-Command & Clanker terminal reports automatically. The hook is gated on `CLANKER_SESSION` and
+Command & Combobulate terminal reports automatically. The hook is gated on `COMBOBULATE_SESSION` and
runs with `curl --max-time 1`, so it is silent and non-blocking everywhere else.
-No-install alternative: the Command & Clanker terminal injects `CLANKER_PATH` (this plugin's
-directory), so you can run `claude --plugin-dir $CLANKER_PATH` instead.
+No-install alternative: the Command & Combobulate terminal injects `COMBOBULATE_PATH` (this plugin's
+directory), so you can run `claude --plugin-dir $COMBOBULATE_PATH` instead.
To share it as a plugin, this directory's parent carries a
`.claude-plugin/marketplace.json`; add it with
-`/plugin marketplace add /integrations/claude` and install `clanker`.
+`/plugin marketplace add /integrations/claude` and install `combobulate`.
## Events sent
@@ -38,5 +38,5 @@ The server reads `tool_name` + `tool_input.file_path` to decide which folder a
robot walks to (read vs write), and uses `agent_id` to distinguish subagents.
> Note: the ingest URL is currently hardcoded to port 3001 in `hooks.json`. If
-> you run the Command & Clanker server on another port, edit the `url` fields (the installer
+> you run the Command & Combobulate server on another port, edit the `url` fields (the installer
> will template this later).
diff --git a/integrations/claude/clanker/.claude-plugin/plugin.json b/integrations/claude/clanker/.claude-plugin/plugin.json
deleted file mode 100644
index 717957e..0000000
--- a/integrations/claude/clanker/.claude-plugin/plugin.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "clanker",
- "description": "Stream Claude Code tool calls and subagent activity to the Command & Clanker map.",
- "version": "0.1.0",
- "author": { "name": "Command & Clanker" }
-}
diff --git a/integrations/claude/clanker/clanker-hook.sh b/integrations/claude/clanker/clanker-hook.sh
deleted file mode 100755
index b9672e1..0000000
--- a/integrations/claude/clanker/clanker-hook.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env bash
-# Command & Clanker hook: forward this tool/lifecycle event to the map. The tool
-# name is the first argument, so each agent's adapter tags itself (claude, codex).
-# Only acts inside a Command & Clanker terminal (CLANKER_SESSION is injected
-# there), and is fast and silent so it never blocks the agent — safe to install
-# globally.
-[ -z "$CLANKER_SESSION" ] && exit 0
-[ -z "$CLANKER_INGEST" ] && exit 0
-tool="${1:-claude}"
-curl -s --max-time 1 -X POST "$CLANKER_INGEST" \
- -H "content-type: application/json" \
- -H "authorization: Bearer ${CLANKER_TOKEN}" \
- -H "x-clanker-session: ${CLANKER_SESSION}" \
- -H "x-clanker-tool: ${tool}" \
- --data-binary @- >/dev/null 2>&1 || true
-exit 0
diff --git a/integrations/claude/combobulate/.claude-plugin/plugin.json b/integrations/claude/combobulate/.claude-plugin/plugin.json
new file mode 100644
index 0000000..2958e7d
--- /dev/null
+++ b/integrations/claude/combobulate/.claude-plugin/plugin.json
@@ -0,0 +1,6 @@
+{
+ "name": "combobulate",
+ "description": "Stream Claude Code tool calls and subagent activity to the Command & Combobulate map.",
+ "version": "0.1.0",
+ "author": { "name": "Command & Combobulate" }
+}
diff --git a/integrations/claude/combobulate/combobulate-hook.sh b/integrations/claude/combobulate/combobulate-hook.sh
new file mode 100755
index 0000000..8e8479c
--- /dev/null
+++ b/integrations/claude/combobulate/combobulate-hook.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+# Command & Combobulate hook: forward this tool/lifecycle event to the map. The tool
+# name is the first argument, so each agent's adapter tags itself (claude, codex).
+# Only acts inside a Command & Combobulate terminal (COMBOBULATE_SESSION is injected
+# there), and is fast and silent so it never blocks the agent — safe to install
+# globally.
+[ -z "$COMBOBULATE_SESSION" ] && exit 0
+[ -z "$COMBOBULATE_INGEST" ] && exit 0
+tool="${1:-claude}"
+curl -s --max-time 1 -X POST "$COMBOBULATE_INGEST" \
+ -H "content-type: application/json" \
+ -H "authorization: Bearer ${COMBOBULATE_TOKEN}" \
+ -H "x-combobulate-session: ${COMBOBULATE_SESSION}" \
+ -H "x-combobulate-tool: ${tool}" \
+ --data-binary @- >/dev/null 2>&1 || true
+exit 0
diff --git a/integrations/claude/clanker/hooks/hooks.json b/integrations/claude/combobulate/hooks/hooks.json
similarity index 69%
rename from integrations/claude/clanker/hooks/hooks.json
rename to integrations/claude/combobulate/hooks/hooks.json
index 40cf7ac..b1ee590 100644
--- a/integrations/claude/clanker/hooks/hooks.json
+++ b/integrations/claude/combobulate/hooks/hooks.json
@@ -1,19 +1,19 @@
{
"hooks": {
"SessionStart": [
- { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/clanker-hook.sh claude" }] }
+ { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/combobulate-hook.sh claude" }] }
],
"SessionEnd": [
- { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/clanker-hook.sh claude" }] }
+ { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/combobulate-hook.sh claude" }] }
],
"PostToolUse": [
- { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/clanker-hook.sh claude" }] }
+ { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/combobulate-hook.sh claude" }] }
],
"SubagentStart": [
- { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/clanker-hook.sh claude" }] }
+ { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/combobulate-hook.sh claude" }] }
],
"SubagentStop": [
- { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/clanker-hook.sh claude" }] }
+ { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/combobulate-hook.sh claude" }] }
]
}
}
diff --git a/integrations/codex/.agents/plugins/marketplace.json b/integrations/codex/.agents/plugins/marketplace.json
index cdb34f7..9536500 100644
--- a/integrations/codex/.agents/plugins/marketplace.json
+++ b/integrations/codex/.agents/plugins/marketplace.json
@@ -1,10 +1,10 @@
{
- "name": "clanker",
- "interface": { "displayName": "Command & Clanker" },
+ "name": "combobulate",
+ "interface": { "displayName": "Command & Combobulate" },
"plugins": [
{
- "name": "clanker",
- "source": { "source": "local", "path": "./plugins/clanker" },
+ "name": "combobulate",
+ "source": { "source": "local", "path": "./plugins/combobulate" },
"policy": { "installation": "AVAILABLE", "authentication": "ON_INSTALL" },
"category": "Coding"
}
diff --git a/integrations/codex/plugins/clanker/clanker-hook.sh b/integrations/codex/plugins/clanker/clanker-hook.sh
deleted file mode 100755
index b9672e1..0000000
--- a/integrations/codex/plugins/clanker/clanker-hook.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env bash
-# Command & Clanker hook: forward this tool/lifecycle event to the map. The tool
-# name is the first argument, so each agent's adapter tags itself (claude, codex).
-# Only acts inside a Command & Clanker terminal (CLANKER_SESSION is injected
-# there), and is fast and silent so it never blocks the agent — safe to install
-# globally.
-[ -z "$CLANKER_SESSION" ] && exit 0
-[ -z "$CLANKER_INGEST" ] && exit 0
-tool="${1:-claude}"
-curl -s --max-time 1 -X POST "$CLANKER_INGEST" \
- -H "content-type: application/json" \
- -H "authorization: Bearer ${CLANKER_TOKEN}" \
- -H "x-clanker-session: ${CLANKER_SESSION}" \
- -H "x-clanker-tool: ${tool}" \
- --data-binary @- >/dev/null 2>&1 || true
-exit 0
diff --git a/integrations/codex/plugins/clanker/.codex-plugin/plugin.json b/integrations/codex/plugins/combobulate/.codex-plugin/plugin.json
similarity index 53%
rename from integrations/codex/plugins/clanker/.codex-plugin/plugin.json
rename to integrations/codex/plugins/combobulate/.codex-plugin/plugin.json
index d4076f6..5527727 100644
--- a/integrations/codex/plugins/clanker/.codex-plugin/plugin.json
+++ b/integrations/codex/plugins/combobulate/.codex-plugin/plugin.json
@@ -1,7 +1,7 @@
{
- "name": "clanker",
- "description": "Stream Codex tool calls and lifecycle events to the Command & Clanker map.",
+ "name": "combobulate",
+ "description": "Stream Codex tool calls and lifecycle events to the Command & Combobulate map.",
"version": "0.1.0",
"hooks": "./hooks/hooks.json",
- "author": { "name": "Command & Clanker" }
+ "author": { "name": "Command & Combobulate" }
}
diff --git a/integrations/codex/plugins/combobulate/combobulate-hook.sh b/integrations/codex/plugins/combobulate/combobulate-hook.sh
new file mode 100755
index 0000000..8e8479c
--- /dev/null
+++ b/integrations/codex/plugins/combobulate/combobulate-hook.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+# Command & Combobulate hook: forward this tool/lifecycle event to the map. The tool
+# name is the first argument, so each agent's adapter tags itself (claude, codex).
+# Only acts inside a Command & Combobulate terminal (COMBOBULATE_SESSION is injected
+# there), and is fast and silent so it never blocks the agent — safe to install
+# globally.
+[ -z "$COMBOBULATE_SESSION" ] && exit 0
+[ -z "$COMBOBULATE_INGEST" ] && exit 0
+tool="${1:-claude}"
+curl -s --max-time 1 -X POST "$COMBOBULATE_INGEST" \
+ -H "content-type: application/json" \
+ -H "authorization: Bearer ${COMBOBULATE_TOKEN}" \
+ -H "x-combobulate-session: ${COMBOBULATE_SESSION}" \
+ -H "x-combobulate-tool: ${tool}" \
+ --data-binary @- >/dev/null 2>&1 || true
+exit 0
diff --git a/integrations/codex/plugins/clanker/hooks/hooks.json b/integrations/codex/plugins/combobulate/hooks/hooks.json
similarity index 70%
rename from integrations/codex/plugins/clanker/hooks/hooks.json
rename to integrations/codex/plugins/combobulate/hooks/hooks.json
index 5d5799f..7aa8dfd 100644
--- a/integrations/codex/plugins/clanker/hooks/hooks.json
+++ b/integrations/codex/plugins/combobulate/hooks/hooks.json
@@ -1,13 +1,13 @@
{
"hooks": {
"SessionStart": [
- { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/clanker-hook.sh codex" }] }
+ { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/combobulate-hook.sh codex" }] }
],
"SessionEnd": [
- { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/clanker-hook.sh codex" }] }
+ { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/combobulate-hook.sh codex" }] }
],
"PostToolUse": [
- { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/clanker-hook.sh codex" }] }
+ { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/combobulate-hook.sh codex" }] }
]
}
}
diff --git a/package.json b/package.json
index 9483ff4..a11e19b 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "name": "command-and-clanker",
+ "name": "command-and-combobulate",
"version": "0.0.4",
"private": true,
"type": "module",
@@ -7,7 +7,7 @@
"dev": "node --experimental-strip-types --disable-warning=ExperimentalWarning --watch server/index.ts",
"start": "node --experimental-strip-types --disable-warning=ExperimentalWarning server/index.ts",
"setup": "node --experimental-strip-types --disable-warning=ExperimentalWarning scripts/install.ts",
- "game": "cd command-and-clanker && make && ./launch-game.sh",
+ "game": "cd command-and-combobulate && make && ./launch-game.sh",
"typecheck": "tsc --noEmit",
"test": "bun test"
},
diff --git a/scripts/install.ts b/scripts/install.ts
index 8461ba3..7f7963a 100644
--- a/scripts/install.ts
+++ b/scripts/install.ts
@@ -1,6 +1,6 @@
-// `bun run setup` — wire the Command & Clanker adapters into the agent CLIs so
+// `bun run setup` — wire the Command & Combobulate adapters into the agent CLIs so
// you do not have to pass plugin paths by hand. Every adapter only does anything
-// inside a Command & Clanker terminal (where CLANKER_SESSION is injected), so this
+// inside a Command & Combobulate terminal (where COMBOBULATE_SESSION is injected), so this
// is safe to run once globally. Idempotent.
//
// claude — a hook in ~/.claude/settings.json.
@@ -12,9 +12,9 @@ import { dirname, join, resolve } from "node:path";
import { spawnSync } from "node:child_process";
const repo = resolve(import.meta.dirname, "..");
-const claudeHook = resolve(repo, "integrations/claude/clanker/clanker-hook.sh");
+const claudeHook = resolve(repo, "integrations/claude/combobulate/combobulate-hook.sh");
const codexMarketplace = resolve(repo, "integrations/codex");
-const codexHook = resolve(repo, "integrations/codex/plugins/clanker/clanker-hook.sh");
+const codexHook = resolve(repo, "integrations/codex/plugins/combobulate/combobulate-hook.sh");
const home = homedir();
const CLAUDE_EVENTS = [
@@ -26,9 +26,9 @@ const CLAUDE_EVENTS = [
];
// Hook commands left by this or a previous install. Re-running setup strips
-// these before re-adding, so entries never stack. "aiso-hook.sh" is the
-// pre-rebrand name and is cleaned up here too.
-const STALE_HOOK_NAMES = ["clanker-hook.sh", "aiso-hook.sh"];
+// these before re-adding, so entries never stack. "clanker-hook.sh" and
+// "aiso-hook.sh" are earlier pre-rebrand names and are cleaned up here too.
+const STALE_HOOK_NAMES = ["combobulate-hook.sh", "clanker-hook.sh", "aiso-hook.sh"];
function has(cmd: string): boolean {
return spawnSync("sh", ["-c", `command -v ${cmd}`], { stdio: "ignore" }).status === 0;
@@ -68,20 +68,20 @@ async function installCodex(): Promise {
stdio: "ignore",
timeout: 30000,
});
- spawnSync("codex", ["plugin", "add", "clanker@clanker"], {
+ spawnSync("codex", ["plugin", "add", "combobulate@combobulate"], {
stdio: "ignore",
timeout: 30000,
});
- return "added clanker@clanker (trust its hooks in Codex on first use)";
+ return "added combobulate@combobulate (trust its hooks in Codex on first use)";
}
const claude = await installClaude();
const codex = await installCodex();
-console.log("Command & Clanker adapters installed:");
+console.log("Command & Combobulate adapters installed:");
console.log(` Claude hooks -> ${claude}`);
console.log(` Codex plugin -> ${codex}`);
console.log(
- "They only report inside Command & Clanker terminals (CLANKER_SESSION is",
+ "They only report inside Command & Combobulate terminals (COMBOBULATE_SESSION is",
);
console.log("injected there), so they stay quiet everywhere else. Run an agent and watch the map.");
diff --git a/server/files.test.ts b/server/files.test.ts
index bbaf0f1..1e3f4af 100644
--- a/server/files.test.ts
+++ b/server/files.test.ts
@@ -83,7 +83,7 @@ describe("FileRegistry", () => {
describe("FileRegistry size", () => {
let dir: string;
beforeAll(() => {
- dir = mkdtempSync(join(tmpdir(), "clanker-files-"));
+ dir = mkdtempSync(join(tmpdir(), "combobulate-files-"));
});
afterAll(() => {
rmSync(dir, { recursive: true, force: true });
diff --git a/server/http.test.ts b/server/http.test.ts
index a51211e..f90b5f1 100644
--- a/server/http.test.ts
+++ b/server/http.test.ts
@@ -50,7 +50,7 @@ function harness(terminals?: Partial): HttpDeps {
{ refs: () => [] } as unknown as TerminalManager,
workDirs,
emptyCache(),
- "/tmp/clanker-http-test-cache.json",
+ "/tmp/combobulate-http-test-cache.json",
);
return {
ingestToken: TOKEN,
@@ -90,8 +90,8 @@ describe("http /ingest auth", () => {
fakeReq("POST", "/ingest", {
headers: {
authorization: `Bearer ${TOKEN}`,
- "x-clanker-session": "t1",
- "x-clanker-tool": "claude",
+ "x-combobulate-session": "t1",
+ "x-combobulate-tool": "claude",
},
body: JSON.stringify({ hook_event_name: "SessionStart" }),
}),
diff --git a/server/http.ts b/server/http.ts
index 4780aa1..8fb3d7b 100644
--- a/server/http.ts
+++ b/server/http.ts
@@ -57,22 +57,22 @@ export function createHttpHandler(deps: HttpDeps) {
if (req.headers["authorization"] !== `Bearer ${ingestToken}`) {
return sendJson(res, 401, { ok: false });
}
- const session = String(req.headers["x-clanker-session"] ?? "");
- const tool = String(req.headers["x-clanker-tool"] ?? "claude");
+ const session = String(req.headers["x-combobulate-session"] ?? "");
+ const tool = String(req.headers["x-combobulate-tool"] ?? "claude");
let body: ClaudeHook = {};
try {
body = parseHook(await readBody(req)) ?? {};
} catch {
/* ignore malformed */
}
- if (process.env.CLANKER_DEBUG_INGEST) {
+ if (process.env.COMBOBULATE_DEBUG_INGEST) {
console.log(
`[ingest] tool=${tool} session=${session} body=${JSON.stringify(body)}`,
);
}
if (session) {
sessions.handle(session, tool, body);
- if (process.env.CLANKER_DEBUG_INGEST) {
+ if (process.env.COMBOBULATE_DEBUG_INGEST) {
const a = agents.get(session);
const sub = body.agent_id ? agents.get(subId(session, body.agent_id)) : null;
const target = sub ?? a;
diff --git a/server/index.ts b/server/index.ts
index 2ed8cf3..360a9ad 100644
--- a/server/index.ts
+++ b/server/index.ts
@@ -17,13 +17,13 @@ const PORT = Number(process.env.TTY_API_PORT ?? 3001);
const TICK_MS = 1000;
const ACTIVITY_TTL_MS = 6000;
const CACHE_PATH =
- process.env.CLANKER_CACHE ?? join(process.cwd(), ".clanker-cache.json");
-const INGEST_TOKEN = process.env.CLANKER_TOKEN ?? randomUUID();
+ process.env.COMBOBULATE_CACHE ?? join(process.cwd(), ".combobulate-cache.json");
+const INGEST_TOKEN = process.env.COMBOBULATE_TOKEN ?? randomUUID();
-// Absolute path to the Claude plugin dir, injected as CLANKER_PATH and used as
-// `claude --plugin-dir $CLANKER_PATH`.
+// Absolute path to the Claude plugin dir, injected as COMBOBULATE_PATH and used as
+// `claude --plugin-dir $COMBOBULATE_PATH`.
const INTEGRATIONS = resolve(import.meta.dirname, "..", "integrations");
-const PLUGIN_DIR = resolve(INTEGRATIONS, "claude", "clanker");
+const PLUGIN_DIR = resolve(INTEGRATIONS, "claude", "combobulate");
const placements = await loadCache(CACHE_PATH);
const knownTerminals = new Set();
diff --git a/server/ingest.test.ts b/server/ingest.test.ts
index bd8324f..dad60b0 100644
--- a/server/ingest.test.ts
+++ b/server/ingest.test.ts
@@ -20,7 +20,7 @@ function harness() {
return { agents, transcripts, ingest, dirty: () => dirty };
}
-const MAIN = "/tmp/clanker-test-main.jsonl";
+const MAIN = "/tmp/combobulate-test-main.jsonl";
describe("Ingest session lifecycle", () => {
test("SessionStart creates a main agent", () => {
diff --git a/server/live.test.ts b/server/live.test.ts
index 6d6bf18..7d2cfe3 100644
--- a/server/live.test.ts
+++ b/server/live.test.ts
@@ -26,7 +26,7 @@ function harness() {
{ refs: () => [] } as unknown as TerminalManager,
new WorkDirTracker(),
emptyCache(),
- "/tmp/clanker-live-test-cache.json",
+ "/tmp/combobulate-live-test-cache.json",
);
return { agents, files, broadcaster: new Broadcaster(agents, files, worldService) };
}
diff --git a/server/persistence.test.ts b/server/persistence.test.ts
index 9d1856c..082e163 100644
--- a/server/persistence.test.ts
+++ b/server/persistence.test.ts
@@ -7,14 +7,14 @@ import { buildWorld, emptyCache, type TerminalInfo } from "./world-builder.ts";
const term = (id: string): TerminalInfo => ({ id, label: id });
-const path = join(tmpdir(), `clanker-cache-${process.pid}-${Date.now()}.json`);
+const path = join(tmpdir(), `combobulate-cache-${process.pid}-${Date.now()}.json`);
afterEach(async () => {
await rm(path, { force: true });
});
test("returns an empty cache when the file is missing", async () => {
- const cache = await loadCache(join(tmpdir(), "clanker-does-not-exist.json"));
+ const cache = await loadCache(join(tmpdir(), "combobulate-does-not-exist.json"));
expect(cache.region.size).toBe(0);
expect(cache.building.size).toBe(0);
expect(cache.freeRegionSlots).toEqual([]);
diff --git a/server/terminals.ts b/server/terminals.ts
index c67da9a..7f9ec7e 100644
--- a/server/terminals.ts
+++ b/server/terminals.ts
@@ -173,10 +173,10 @@ export class TerminalManager {
// The agent's adapter reads these to tag its events with this island and
// reach the ingest endpoint.
const env = {
- CLANKER_SESSION: id,
- CLANKER_INGEST: this.ingest.url,
- CLANKER_TOKEN: this.ingest.token,
- CLANKER_PATH: this.ingest.pluginDir,
+ COMBOBULATE_SESSION: id,
+ COMBOBULATE_INGEST: this.ingest.url,
+ COMBOBULATE_TOKEN: this.ingest.token,
+ COMBOBULATE_PATH: this.ingest.pluginDir,
};
this.terminals.set(
id,
diff --git a/server/transcript-tailer.test.ts b/server/transcript-tailer.test.ts
index 9ee669a..5f3338c 100644
--- a/server/transcript-tailer.test.ts
+++ b/server/transcript-tailer.test.ts
@@ -8,7 +8,7 @@ let dir: string;
let path: string;
beforeEach(() => {
- dir = mkdtempSync(join(tmpdir(), "clanker-tail-"));
+ dir = mkdtempSync(join(tmpdir(), "combobulate-tail-"));
path = join(dir, "session.jsonl");
});
diff --git a/server/world-service.test.ts b/server/world-service.test.ts
index ab2c992..f93c502 100644
--- a/server/world-service.test.ts
+++ b/server/world-service.test.ts
@@ -17,7 +17,7 @@ function fakeTerminals(refs: { id: string; pid: number }[]): TerminalManager {
describe("WorldService", () => {
let dir: string;
beforeAll(() => {
- dir = mkdtempSync(join(tmpdir(), "clanker-world-"));
+ dir = mkdtempSync(join(tmpdir(), "combobulate-world-"));
});
afterAll(() => {
rmSync(dir, { recursive: true, force: true });
diff --git a/shared/wire-contract.test.ts b/shared/wire-contract.test.ts
index d0c2a97..89925be 100644
--- a/shared/wire-contract.test.ts
+++ b/shared/wire-contract.test.ts
@@ -10,7 +10,7 @@ import type { AgentSnapshot, FileActivity, FileEntry, FolderFiles } from "./proc
// C# [JsonPropertyName] is added (and vice versa).
const LIVE_MESSAGE_CS = resolve(
import.meta.dir,
- "../command-and-clanker/OpenRA.Mods.Clanker/Protocol/LiveMessage.cs",
+ "../command-and-combobulate/OpenRA.Mods.Combobulate/Protocol/LiveMessage.cs",
);
// Parse the C# model into { className: [jsonPropertyName, ...] } by reading the