Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ agent-office setup # the first-start walkthrough again

Every option is in [docs/configuration.md](docs/configuration.md). Choosing models and providers per worker is in [docs/agents.md](docs/agents.md).

For a standalone GLB walkthrough and walkability audit, see [the local Town Hall tester](docs/how-it-works.md#town-hall-walkability-tester).

To run it from a clone instead:

```bash
Expand Down
11 changes: 11 additions & 0 deletions docs/how-it-works.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,14 @@ Anyone who can sign in can drive Claude Code, OpenCode, Codex, Grok, Muse, DeepS
- Workers don't inherit the office password or any parent agent-session variables.
- Workers hired by an account run on that account's own sign-ins (`CLAUDE_CONFIG_DIR`, `GH_CONFIG_DIR` and `GIT_CONFIG_GLOBAL` under `.agent-office/homes/<account>/`), and never see the machine's own Claude or GitHub credentials (`ANTHROPIC_API_KEY`, `CLAUDE_CODE_OAUTH_TOKEN`, `GH_TOKEN` and the like are taken out of their environment). But every worker runs as the same OS user, so one person's worker *can* read another person's folder. Per-person sign-ins keep work attributed and plans separate. They don't keep teammates' secrets from each other.
- The picture fetcher (`/api/image`) needs an office session. It fetches any http(s) link it's given, from the office's machine. That gives nobody new reach: anyone signed in can already run `curl` from a shell worker. Pictures are served with a sandboxing `Content-Security-Policy`, so an SVG can't run script on the office's origin.
## Town Hall walkability tester

The standalone walkthrough is available at `/townhall.html` when running the Vite development server. Place
the Blender export at `src/client/public/town-hall-shell.glb`; this project-specific GLB is a local asset and
is not included in the repository. The page builds its Recast navigation mesh from that geometry.

For temporary walkability testing, `WALKABILITY_OPEN_DOORS` in `src/client/townhall.ts` opens named door
panels at runtime before Recast builds navigation. Explicit `SLIDE` names and elevator doors slide; unmarked
`door_leaf` and left/right door-panel names are treated as hinged. Frames, handles, anchors, and other
non-panel objects are left alone, and ambiguous door meshes are logged and left unchanged. This does not
modify the Blender export.
89 changes: 51 additions & 38 deletions package-lock.json

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

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
"license": "MIT",
"dependencies": {
"@lydell/node-pty": "^1.2.0-beta.15",
"@recast-navigation/three": "^0.44.0",
"@xterm/addon-serialize": "^0.14.0",
"@xterm/headless": "^6.0.0",
"recast-navigation": "^0.44.0",
"selfsigned": "^5.5.0",
"ws": "^8.21.3"
},
Expand Down
46 changes: 46 additions & 0 deletions src/client/townhall.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Town Hall Walkthrough</title>
<style>
html, body { margin: 0; height: 100%; overflow: hidden; background: #17202a; }
body { font-family: system-ui, sans-serif; color: #eef4ff; }
canvas { display: block; width: 100%; height: 100%; }
#panel { position: fixed; top: 16px; left: 16px; z-index: 2; width: 340px; max-height: calc(100vh - 32px); overflow: auto; padding: 14px; border-radius: 10px; background: rgba(16,22,32,.94); box-shadow: 0 6px 24px rgba(0,0,0,.35); font-size: 13px; line-height: 1.45; }
#panel strong { display: block; margin-bottom: 8px; }
#run { padding: 8px 10px; border: 0; border-radius: 6px; background: #27c281; color: #07140e; font-weight: 700; cursor: pointer; }
#run:disabled { opacity: .6; cursor: wait; }
#export-report, [data-level] { margin-left: 6px; padding: 8px 10px; border: 0; border-radius: 6px; background: #d7b85d; color: #17130a; font-weight: 700; cursor: pointer; }
#levels { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 10px; }
#levels [data-level] { margin-left: 0; padding: 5px 8px; background: #526176; color: #eef4ff; font-size: 12px; }
#levels [data-active="true"] { background: #78a9ff; color: #07101f; }
#status { margin-top: 10px; }
#report { white-space: pre-wrap; margin: 10px 0 0; color: #c9d7e8; }
#help { margin-top: 10px; color: #aebed1; }
.pass { color: #39e58c; }
.fail { color: #ff6b78; }
</style>
</head>
<body>
<div id="panel">
<strong>Blender Town Hall walkthrough</strong>
<button id="run" type="button">Run exhaustive audit</button>
<button id="overview" type="button" style="margin-left:6px;padding:8px 10px;border:0;border-radius:6px;background:#78a9ff;color:#07101f;font-weight:700;cursor:pointer">View whole building</button>
<button id="export-report" type="button">Export Test Report</button>
<div id="levels" aria-label="Floor isolation">
<button data-level="All" data-active="true" type="button">All</button>
<button data-level="F1" type="button">F1</button>
<button data-level="F2" type="button">F2</button>
<button data-level="F3" type="button">F3</button>
<button data-level="Roof" type="button">Roof</button>
</div>
<div id="status">Loading your Blender building…</div>
<pre id="report"></pre>
<div id="help">Press R to start the exhaustive all-floor audit; press R again to stop it. Use WASD to walk and Space to jump. In first person, drag the mouse or use a two-finger trackpad gesture to look around. Overview: one-finger drag to orbit, pinch or scroll to zoom, and two-finger/right-button drag to pan.</div>
</div>
<canvas id="townhall"></canvas>
<script type="module" src="./townhall.ts"></script>
</body>
</html>
Loading