agents-city 0.3.0-beta.21 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/README.es.md +310 -70
  3. package/README.md +297 -69
  4. package/bin/agents-city.js +3 -0
  5. package/bin/doctor +3 -0
  6. package/bin/hall.html +164 -24
  7. package/bin/navegador.mjs +415 -0
  8. package/bin/serve.py +383 -127
  9. package/bin/shortcut +3 -0
  10. package/bin/test +5 -2
  11. package/bin/test-actualiza.py +130 -0
  12. package/bin/test-atajos.py +301 -0
  13. package/bin/test-busca.py +216 -0
  14. package/bin/test-cage.py +170 -2
  15. package/bin/test-card.py +2 -2
  16. package/bin/test-cities.py +45 -0
  17. package/bin/test-contracts.py +12 -5
  18. package/bin/test-doctor.py +33 -0
  19. package/bin/test-navegador.py +164 -0
  20. package/bin/test-seat.py +245 -25
  21. package/bin/test-serve.py +214 -9
  22. package/bin/test-workspace.py +63 -0
  23. package/bin/testlib.py +23 -0
  24. package/bin/update +3 -0
  25. package/city/web/dist/city.js +47 -47
  26. package/city/web/dist/index.html +1 -1
  27. package/city/web/dist-hall/hall.js +2193 -174
  28. package/city/web/src/bienvenida.ts +686 -0
  29. package/city/web/src/es.ts +180 -0
  30. package/city/web/src/hall.ts +520 -168
  31. package/city/web/src/idioma.ts +86 -0
  32. package/city/web/src/main.ts +27 -0
  33. package/city/web/src/motores.ts +54 -0
  34. package/docs/agents-first.md +8 -1
  35. package/docs/security.md +46 -12
  36. package/docs/testing.md +1 -1
  37. package/package.json +1 -1
  38. package/plugin/.claude-plugin/plugin.json +1 -1
  39. package/plugin/channel/bus.js +1 -1
  40. package/plugin/channel/bus.ts +1 -1
  41. package/plugin/channel/runtime/codex.ts +1 -1
  42. package/plugin/channel/runtime-gateway.js +1 -1
  43. package/plugin/scripts/actualiza.py +198 -0
  44. package/plugin/scripts/atajos.py +506 -0
  45. package/plugin/scripts/busca.py +436 -0
  46. package/plugin/scripts/cage.py +266 -26
  47. package/plugin/scripts/capabilities.py +17 -10
  48. package/plugin/scripts/card.py +10 -0
  49. package/plugin/scripts/cities.py +34 -0
  50. package/plugin/scripts/city-session.sh +33 -7
  51. package/plugin/scripts/doctor.py +122 -0
  52. package/plugin/scripts/find-repos.sh +12 -105
  53. package/plugin/scripts/read-card.py +6 -2
  54. package/plugin/scripts/report.py +5 -6
  55. package/plugin/scripts/reset.py +50 -14
  56. package/plugin/scripts/seat.py +445 -103
  57. package/plugin/scripts/workspace.py +197 -0
package/README.md CHANGED
@@ -5,6 +5,14 @@
5
5
  **Run several autonomous agent cities on one machine, and connect only the
6
6
  cities that should talk.**
7
7
 
8
+ ```bash
9
+ npm install -g agents-city
10
+ agents-city
11
+ ```
12
+
13
+ That is the whole installation. The second command opens the town hall in your
14
+ browser and walks you through creating your first city.
15
+
8
16
  Agents City is a local-first, multi-model orchestrator for repository work. Each
9
17
  city has its own identity, domain, chair seat, goal, repo support agents,
10
18
  editable knowledge, live-recognised skills, and explicit roads to other cities.
@@ -85,53 +93,66 @@ The important boundaries are:
85
93
 
86
94
  ## Quick start
87
95
 
88
- ### Right now: the real npm experience without publishing
89
-
90
- Packing first matters: this tests the exact file list a person would receive
91
- from npm, not the whole checkout.
96
+ ### Install from npm
92
97
 
93
98
  ```bash
94
- cd /path/to/agents-city
95
- npm pack
96
- npm install -g ./agents-city-0.3.0-beta.21.tgz
99
+ npm install -g agents-city
97
100
  agents-city --version
98
- agents-city seat
99
101
  ```
100
102
 
101
- You do not need to run `npm publish`. The installation is global only for your
102
- currently active Node installation.
103
+ This is `0.x` on purpose: the commands are usable today, and the file formats
104
+ and APIs can still change between minor versions. Nothing here pretends to be
105
+ frozen yet.
103
106
 
104
- ### Registry installation once available
107
+ You need Node.js 22+, Python 3 and tmux; the
108
+ [requirements table](#base-requirements) has the details, and `agents-city seat`
109
+ offers to install tmux when it is missing. Nothing is installed system-wide
110
+ beyond the npm global folder of your active Node installation.
105
111
 
106
- Check availability and dist-tags first:
112
+ ### Try it without installing anything
107
113
 
108
114
  ```bash
109
- npm view agents-city dist-tags --json
115
+ npx agents-city
110
116
  ```
111
117
 
112
- If it returns `E404`, use the local tarball in the previous section. Once the
113
- registry shows a `beta` dist-tag, install it with:
118
+ `npx` downloads the package into its cache, runs it, and leaves your global npm
119
+ folder untouched the fastest way to see whether this is for you.
120
+
121
+ ### Then: the Hall, or the terminal
114
122
 
115
123
  ```bash
116
- npm install -g agents-city@beta
117
- agents-city --version
118
- agents-city seat
124
+ agents-city # the town hall in your browser (same as: agents-city hall)
125
+ agents-city seat # the terminal wizard, if you prefer not to leave the shell
119
126
  ```
120
127
 
121
- Use `@beta` while this is a prerelease. Bare `npm install -g agents-city` should
122
- be reserved for the future stable release carrying the `latest` tag.
128
+ The Hall listens on `127.0.0.1`, chooses a free port, and opens the browser. You
129
+ can create or select a city, edit its configuration, tune each agent's engine
130
+ and watch the live map there. The Hall and the CLI use the same underlying
131
+ modules, so neither is the "lesser" path.
123
132
 
124
- ### Open the Hall instead of the terminal wizard
133
+ ### Update, or remove
125
134
 
126
135
  ```bash
127
- agents-city
128
- # equivalent to:
129
- agents-city hall
136
+ npm install -g agents-city # update to the newest release
137
+ npm uninstall -g agents-city # remove the program
130
138
  ```
131
139
 
132
- The Hall listens on `127.0.0.1`, chooses a free port, and opens the browser. You
133
- can create or select a city and edit its configuration there. The Hall and CLI
134
- use the same underlying modules.
140
+ Uninstalling leaves `~/.agents-city`, your cities and your repositories exactly
141
+ where they are: the program is not your data.
142
+
143
+ ### Install from a source checkout instead
144
+
145
+ For contributors, and for anyone who wants to read the code before running it.
146
+ Packing first is the honest test: it exercises the exact file list a person
147
+ receives from npm, not your whole working copy.
148
+
149
+ ```bash
150
+ git clone https://github.com/jlcases/agents-city.git
151
+ cd agents-city
152
+ npm pack
153
+ npm install -g ./agents-city-*.tgz
154
+ agents-city --version
155
+ ```
135
156
 
136
157
  ## Requirements and installation
137
158
 
@@ -146,6 +167,7 @@ use the same underlying modules.
146
167
  | tmux | one window per seat/repo; `seat` tries to install it when missing |
147
168
  | macOS or Linux | natively supported platforms |
148
169
  | WSL | required on Windows because native Windows has no bash/tmux |
170
+ | bubblewrap | optional, Linux only: it IS the cage there. Without it agents run uncaged — see [the cage](#the-cage-the-broker-and-the-audit-chain) |
149
171
 
150
172
  Each runtime also needs its own installed and authenticated CLI. Agents City
151
173
  does not bundle or replace Claude, Codex, OpenCode, or Kimi accounts.
@@ -172,15 +194,19 @@ onboarding, Agents City uses the separate `gh` CLI:
172
194
 
173
195
  `gh` is not bundled inside the Agents City npm package.
174
196
 
175
- ### Update a local installation
197
+ ### Update an installation
176
198
 
177
199
  ```bash
178
- cd /path/to/agents-city
179
- npm pack
180
- npm install -g ./agents-city-0.3.0-beta.21.tgz
200
+ npm install -g agents-city # from the registry
181
201
  agents-city --version
182
202
  ```
183
203
 
204
+ From a source checkout, pack and install the tarball instead:
205
+
206
+ ```bash
207
+ cd /path/to/agents-city && npm pack && npm install -g ./agents-city-*.tgz
208
+ ```
209
+
184
210
  Already-running sessions retain the code loaded in memory. To apply the new
185
211
  version to one city:
186
212
 
@@ -204,7 +230,7 @@ restart one specific city.
204
230
 
205
231
  ## First run, step by step
206
232
 
207
- `agents-city seat` creates `home` when no city exists and asks for five decisions.
233
+ `agents-city seat` creates `home` when no city exists and asks seven questions.
208
234
 
209
235
  ### 1. Work domain
210
236
 
@@ -228,22 +254,39 @@ built-in options are:
228
254
  This is the responsibility of the city lead. It is not the city name or runtime.
229
255
  The seat remains chair even when you choose `blank`.
230
256
 
231
- ### 3. Repositories and each agent's role
232
-
233
- You can read repositories from disk, your GitHub account, or a GitHub
234
- organisation. Each selected local repo receives:
235
-
236
- - a tmux window;
237
- - a private bus actor;
238
- - its repository as working directory;
239
- - an explicit operating role;
240
- - the skills its runtime can already discover there.
241
-
242
- A repo role may come from another domain. For example, a software city can give
243
- `po` to its product repo, `seo` to a portfolio, and `data-engineer` to a
244
- pipeline. None becomes chair.
245
-
246
- Selecting zero repos is also valid: the city opens with only its seat.
257
+ ### 3. The agents, one at a time
258
+
259
+ This is the city itself, and it is a loop rather than a list of folders to tick.
260
+ Each agent is asked for in full, and then you are asked for another, until you
261
+ say the city is complete:
262
+
263
+ 1. **Its name** — what you call it in its window, on the map, and on the bus.
264
+ 2. **The kind of work it does** — `code`, `knowledge` or `coordinator`. This is
265
+ not a permission: it decides how its house grows on the map, so a person
266
+ whose work is documents is not measured in pull requests.
267
+ 3. **Its role** — its specialty, from this city's domain or another one. A
268
+ software city can give `po` to a product agent, `seo` to a portfolio one and
269
+ `data-engineer` to a pipeline. None becomes chair.
270
+ 4. **Everything it works on** — any number of repositories (read from disk, your
271
+ GitHub account, or an organisation) *plus* any number of document folders.
272
+ One agent may answer for three services and a handbook at once, and an agent
273
+ with no git anywhere is a first-class agent. They are mounted inside its
274
+ workspace, not turned into separate agents.
275
+ 5. **What runs it** — Claude with a model and effort of its own, or Codex,
276
+ OpenCode, Kimi, or an explicit terminal fallback.
277
+ 6. **The skills it starts with** — a skill folder or `.zip` installed into that
278
+ agent's own home. Only offered for engines that read skills; an agent on
279
+ Codex is told its engine ignores them instead of being sold something that
280
+ does nothing.
281
+
282
+ Each agent then receives a tmux window, a private bus actor, its workspace as
283
+ working directory, and the skills its runtime can already discover in what it
284
+ mounts.
285
+
286
+ Saying the city has no agents is also valid: it opens with only its seat, and
287
+ roads connect it to other cities.
288
+
289
+ Change the roster any time with `agents-city seat --agents`.
247
290
 
248
291
  ### 4. Goal
249
292
 
@@ -259,19 +302,49 @@ A goal may be quantitative or qualitative. It stores:
259
302
 
260
303
  You may skip it and configure it later with `agents-city seat --goal`.
261
304
 
262
- ### 5. Runtime for each window
263
-
264
- Pressing Enter keeps Claude everywhere. You may instead choose per window:
305
+ ### 5. Runtime for your own chair
265
306
 
266
- - Claude and, optionally, model/effort;
267
- - Codex;
268
- - OpenCode;
269
- - Kimi;
270
- - an unknown command through the explicit terminal fallback.
307
+ Every agent's engine was decided on the agent itself, in question 3. What is
308
+ left is your own window — the one that holds the chair role, the `/city:`
309
+ commands and the plugin. Pressing Enter keeps it on your Claude; you may instead
310
+ choose Claude with a model and effort, Codex, OpenCode, Kimi, or an unknown
311
+ command through the explicit terminal fallback.
271
312
 
272
313
  Persistent choices live in the owner card. `seat --model` and `--effort` are
273
314
  one-launch overrides only.
274
315
 
316
+ ### 6. Whether your chair asks permission
317
+
318
+ Per city, in `city.yml` as `seat_yolo`. Locally the seat is your own hands on
319
+ your own machine, so asking you for permission in your own chair is a choice,
320
+ not a law. Agent windows keep their own cage either way, and launching with
321
+ `--no-yolo` still brakes the whole session, seat included.
322
+
323
+ ### 7. The city on your desktop
324
+
325
+ Offered once, when the city is new: a real desktop shortcut carrying the city's
326
+ name and an icon coloured from its own identity — a macOS `.app` bundle or a
327
+ Linux `.desktop` entry. Double-click it and the city opens.
328
+
329
+ It runs the same line you would type, so it is a labelled button on the front
330
+ door rather than a second way in. Add or remove one any time:
331
+
332
+ ```bash
333
+ agents-city shortcut # this city, on your desktop
334
+ agents-city shortcut home --hall # a door that opens the map instead
335
+ agents-city shortcut --remove # take it off again
336
+ agents-city shortcut --to ~/bin # somewhere other than the desktop
337
+ ```
338
+
339
+ **On Windows** the city lives inside WSL, and a `~/Desktop` in WSL is the Linux
340
+ home's desktop — which nobody ever looks at. So the shortcut is written to the
341
+ **Windows** desktop instead, asked of Windows itself rather than guessed from a
342
+ username (a desktop redirected to OneDrive or a domain profile is not under
343
+ `C:\Users\<name>\Desktop`). It is a real `.lnk`, built through Windows' own
344
+ PowerShell so it can carry an `.ico`, and it launches `wsl.exe` running the same
345
+ command in a login shell. Where interop is unavailable, a double-clickable
346
+ `.cmd` is written instead — same door, plain icon.
347
+
275
348
  ### What gets created
276
349
 
277
350
  ```text
@@ -415,8 +488,10 @@ agents-city cities
415
488
  agents-city road
416
489
  agents-city bus
417
490
  agents-city committee
491
+ agents-city agents
418
492
  agents-city skills
419
493
  agents-city city
494
+ agents-city shortcut
420
495
  agents-city demo
421
496
  agents-city report
422
497
  agents-city tokens
@@ -424,6 +499,8 @@ agents-city logs
424
499
  agents-city benchmark
425
500
  agents-city reset
426
501
  agents-city exit
502
+ agents-city doctor
503
+ agents-city update
427
504
  agents-city test
428
505
  ```
429
506
 
@@ -473,6 +550,12 @@ spectator token rotates with the hub, accepts only an origin on this computer,
473
550
  and is read-only: the browser cannot direct the committee. `Ctrl-c` stops the
474
551
  Hall.
475
552
 
553
+ Two buttons sit under the brand: **day/night**, and **ES/EN**. The Hall speaks
554
+ Spanish and English, starting in the browser's own language and remembering an
555
+ explicit choice. Translations are keyed by the English sentence, so anything not
556
+ yet translated falls back to readable English rather than to an identifier — new
557
+ strings are never blocked on a translation pass.
558
+
476
559
  ### `agents-city setup`
477
560
 
478
561
  Creates or selects a city and opens the Hall; `--tui` hands the flow to `seat`.
@@ -712,6 +795,30 @@ skills/*/SKILL.md
712
795
  Actual invocation depends on the runtime. Agents City advertises the capability
713
796
  for the member and lets the provider enforce its own discovery and use rules.
714
797
 
798
+ ### `agents-city agents`
799
+
800
+ Lists this city's agents and manages what each one works on. An agent's mounts
801
+ are symlinks inside its workspace, so this is the terminal equivalent of the
802
+ Hall's **works on** row and of question 3 of the wizard.
803
+
804
+ ```bash
805
+ agents-city agents list --card ~/.agents-city/alice/home/alice.md --data ~/.agents-city/alice/home
806
+ agents-city agents mounts --agent urgencias --data ~/.agents-city/alice/home
807
+ agents-city agents mount --agent urgencias --src ~/documents/handbook --data …
808
+ agents-city agents unmount --agent urgencias --name handbook --data …
809
+ ```
810
+
811
+ | Command | Effect |
812
+ |---|---|
813
+ | `list` | every agent: name, slug, role, runtime, kind, working directory |
814
+ | `mounts` | one agent's mounts, as label and real target |
815
+ | `mount --src PATH` | mount a repo, a worktree or a folder of documents |
816
+ | `unmount --name LABEL` | remove that mount; the folder itself is untouched |
817
+ | `sync` / `sync-all` | rebuild the workspaces from the card, as the launcher does |
818
+
819
+ Unmounting removes a symlink and a card key. It never deletes what the link
820
+ pointed at.
821
+
715
822
  ### `agents-city city`
716
823
 
717
824
  Opens one city's local map without starting an agent session.
@@ -738,6 +845,45 @@ control) toggles fullscreen, and the Hall's live rail is resizable by dragging
738
845
  its edge. The full contract is in
739
846
  [docs/map-live-layers.md](docs/map-live-layers.md).
740
847
 
848
+ ### `agents-city shortcut`
849
+
850
+ Puts a city on your desktop: its name, an icon coloured from its own identity,
851
+ and a double-click that opens it.
852
+
853
+ ```bash
854
+ agents-city shortcut # the selected city
855
+ agents-city shortcut product # a specific one
856
+ agents-city shortcut --hall # a door that opens the map instead of the seat
857
+ agents-city shortcut --remove # take it off the desktop
858
+ agents-city shortcut --to ~/bin # write it somewhere else
859
+ ```
860
+
861
+ | Option | Effect |
862
+ |---|---|
863
+ | `--hall` | the shortcut opens the browser map instead of the tmux city |
864
+ | `--remove` | remove this city's shortcut |
865
+ | `--to DIR` | write it into another folder than the desktop |
866
+
867
+ What gets written depends on the desktop, and each is a real one rather than a
868
+ script pretending:
869
+
870
+ | Platform | Shortcut | Icon |
871
+ |---|---|---|
872
+ | macOS | `.app` bundle running the city in Terminal | `.icns`, built with the system's `iconutil` |
873
+ | Linux | `.desktop` entry, marked trusted where `gio` exists | `.png` under `XDG_DATA_HOME` |
874
+ | Windows (WSL) | `.lnk` on the **Windows** desktop, launching `wsl.exe` | `.ico`, when PowerShell interop is reachable |
875
+
876
+ All of them run the same line you would type, so the shortcut is a labelled
877
+ button on the front door rather than a second way in. The icon is generated
878
+ without any image library: a PNG written by hand, wrapped as `.ico` for Windows
879
+ and converted by `iconutil` for macOS.
880
+
881
+ On Windows the city lives inside WSL, and a `~/Desktop` there is the Linux
882
+ home's desktop that nobody looks at — so the Windows desktop is asked of Windows
883
+ itself, never assembled from a username, because a desktop redirected to OneDrive
884
+ or a domain profile is not under `C:\Users\<name>\Desktop`. Without interop a
885
+ double-clickable `.cmd` is written instead: same door, plain icon.
886
+
741
887
  ### `agents-city demo`
742
888
 
743
889
  Opens one fictional, disposable demo city in the complete Hall. The map owns
@@ -905,13 +1051,21 @@ benchmark; by itself it proves neither higher answer quality nor a SOTA claim.
905
1051
 
906
1052
  ### `agents-city reset`
907
1053
 
908
- Resets **one** managed city while preserving its stable identity and repositories.
1054
+ Resets managed cities while preserving their stable identity and repositories.
909
1055
 
910
1056
  ```bash
911
- agents-city reset product --dry-run
1057
+ agents-city reset product --dry-run # show every effect, change nothing
912
1058
  agents-city reset product
1059
+ agents-city reset product client-a # several, space separated
1060
+ agents-city reset all # every city this owner has
913
1061
  ```
914
1062
 
1063
+ One unknown name aborts the **whole** run before anything is touched: resetting
1064
+ three cities and then stopping on a typo is the worst outcome a destructive
1065
+ command can have. The Hall has the same thing as a button, in **Cities** — it
1066
+ first shows what disappears, what survives and where the copy lands, and asks
1067
+ you to type the city's name.
1068
+
915
1069
  The reset plan:
916
1070
 
917
1071
  1. verifies the target is a managed city, not an arbitrary path;
@@ -942,6 +1096,41 @@ Hall may stay up. Without a city, it shows or closes everything managed by
942
1096
  Agents City. A tmux session may contain unsaved work, so dry-run is the safe way
943
1097
  to confirm scope.
944
1098
 
1099
+ ### `agents-city doctor`
1100
+
1101
+ Checks this machine and says which part is missing, in one screen.
1102
+
1103
+ ```bash
1104
+ agents-city doctor
1105
+ ```
1106
+
1107
+ It reports the tools it needs (python3, tmux, bash, git, node, and `gh` as
1108
+ optional), which agent runtimes are installed, **which cage this kernel gives
1109
+ you** — seatbelt, bubblewrap, or none and why — the selected city and its card,
1110
+ whether the Hall bundle is built, and whether a newer version is published. It
1111
+ exits non-zero when something is broken, so it works in a script too.
1112
+
1113
+ Passed a config file instead, it keeps its older job: detect an old config
1114
+ shape, explain it, and migrate it with `--fix` (leaving a backup).
1115
+
1116
+ ### `agents-city update`
1117
+
1118
+ ```bash
1119
+ agents-city update # install the newest published version
1120
+ agents-city update --check # only ask: installed vs published
1121
+ agents-city update --tag beta # follow a dist-tag
1122
+ ```
1123
+
1124
+ The check is **one GET to the public npm registry**, cached for a day under
1125
+ `~/.agents-city/.runtime/`. Nothing about your machine is sent — no identifier,
1126
+ no counter, no telemetry — and `CITY_UPDATE_CHECK=0` switches it off entirely.
1127
+ It runs only where you deliberately opened something: `doctor`, `update`, and
1128
+ the Hall (which shows one line when a release is out). A plain
1129
+ `agents-city cities` never touches the network.
1130
+
1131
+ Installed from a git checkout, `update` refuses and tells you the command that
1132
+ fits your install instead of running `npm install -g` over your working copy.
1133
+
945
1134
  ### `agents-city test`
946
1135
 
947
1136
  Runs checkout tests. With no arguments it runs every suite; with names it runs
@@ -1194,7 +1383,7 @@ it never gains authority to command a local repo directly.
1194
1383
  ```bash
1195
1384
  cd /path/to/agents-city
1196
1385
  npm pack
1197
- npm install -g ./agents-city-0.3.0-beta.21.tgz
1386
+ npm install -g ./agents-city-*.tgz
1198
1387
  agents-city seat
1199
1388
  ```
1200
1389
 
@@ -1466,7 +1655,7 @@ authentication failure is not counted as a fast sample.
1466
1655
  ```bash
1467
1656
  cd /path/to/agents-city
1468
1657
  npm pack
1469
- npm install -g ./agents-city-0.3.0-beta.21.tgz
1658
+ npm install -g ./agents-city-*.tgz
1470
1659
  agents-city --version
1471
1660
  agents-city exit product --dry-run
1472
1661
  agents-city exit product
@@ -1586,7 +1775,7 @@ message lifetime. `bus inbox` consumes `road-inbox`, not append-only history.
1586
1775
  | `AGENTS_CITY_USER` | resolved local identity | force an owner for tests/migrations |
1587
1776
  | `AGENTS_CITY_DATA` | selected city | force a city folder from an outside terminal |
1588
1777
  | `CITY_CODE_DIR` | `~/codigo` | destination for accepted GitHub clones |
1589
- | `CITY_SEARCH_IN` | common home roots | colon-separated roots for local repo search |
1778
+ | `CITY_SEARCH_IN` | common home roots | colon-separated roots to search (`;` also accepted, for Windows) |
1590
1779
  | `CITY_SEARCH_DEPTH` | `4` | maximum depth of that search |
1591
1780
  | `AGENTS_CITY_ORG` | empty | filter repositories by organisation; empty means all |
1592
1781
  | `CITY_SETTLE` | `8` | initial Claude startup wait in seconds |
@@ -1596,6 +1785,12 @@ message lifetime. `bus inbox` consumes `road-inbox`, not append-only history.
1596
1785
  | `AGENTS_CITY_URL` | `CITY_BUS_URL` | reporting/map endpoint when separate |
1597
1786
  | `CITY_DIR` | `~/.claude/channels/city-bus` | compatibility folder for `.env` and hooks |
1598
1787
  | `CITY_HOOKS` | `city` | `everywhere` runs the conscience hooks in every Claude session, not only city runtimes |
1788
+ | `CITY_DESKTOP` | `~/Desktop`, or the Windows desktop under WSL | where `agents-city shortcut` writes |
1789
+ | `CITY_CAGE` | `1` | `0` launches every window uncaged |
1790
+ | `CITY_CAGE_DENY` | empty | extra colon-separated paths to seal |
1791
+ | `CITY_CAGE_ALLOW_WRITE` | empty | extra colon-separated paths to keep writable |
1792
+ | `CITY_UPDATE_CHECK` | `1` | `0` never asks npm whether a newer version exists |
1793
+ | `CITY_CAGE_BWRAP` | probed | `1`/`0` answers "can this Linux build a namespace?" without probing; the launcher sets it once per city |
1599
1794
 
1600
1795
  Examples:
1601
1796
 
@@ -1611,10 +1806,27 @@ agents-city cities create lab
1611
1806
  CITY_SETTLE=0 CITY_STAGGER=0 agents-city seat --city product
1612
1807
  ```
1613
1808
 
1614
- The local repository index is cached for one day at
1615
- `$XDG_CACHE_HOME/agents-city/repos.tsv` or `~/.cache/agents-city/repos.tsv`. The
1616
- Hall offers a refresh. From a terminal, if you change `CITY_SEARCH_IN` while the
1617
- cache is still valid, remove **only that index file** and repeat `seat --repos`.
1809
+ ### What a house can be given to work on
1810
+
1811
+ `plugin/scripts/busca.py` walks your disk once and indexes three kinds of place:
1812
+
1813
+ * **repositories** — named by their `origin` remote, not by the folder they sit
1814
+ in, so a clone is findable by the name you would say out loud;
1815
+ * **worktrees** — a linked worktree is the folder an isolated agent actually
1816
+ works in, and it is listed as `repo@branch`, a distinct thing to pick;
1817
+ * **folders of documents** — a directory with writing in it and no git anywhere,
1818
+ which is what a `knowledge` agent mounts.
1819
+
1820
+ It reads `.git/config` and `HEAD` directly rather than running `git` once per
1821
+ repository, so a full scan finishes while somebody is looking at the screen, and
1822
+ it runs anywhere Python does — macOS, Linux and Windows alike. The guide and the
1823
+ Hall search this index; `plugin/scripts/find-repos.sh` is a thin shim over it for
1824
+ shell callers, printing the git half only.
1825
+
1826
+ The index is cached for one day at `$XDG_CACHE_HOME/agents-city/lugares.tsv` or
1827
+ `~/.cache/agents-city/lugares.tsv`. Both the Hall's house form and the seat offer
1828
+ a refresh; from a terminal, `busca.py --refresh` rebuilds it, which is also what
1829
+ you want after changing `CITY_SEARCH_IN` while the cache is still valid.
1618
1830
 
1619
1831
  Transport setting precedence is:
1620
1832
 
@@ -1656,7 +1868,8 @@ but "do not ask" and "touch everything" are different axes, and only the first
1656
1868
  one is yolo. On macOS Claude, OpenCode and Kimi repo windows launch inside a
1657
1869
  generated seatbelt profile: writes land only in their own repo and runtime state, and the files
1658
1870
  that turn a prompt injection into a credential theft (`~/.ssh`,
1659
- `~/.git-credentials`, `~/.aws`, gh and cloud configs, remote road tokens) are
1871
+ `~/.git-credentials`, `~/.aws`, gh and cloud configs, remote road tokens, and
1872
+ Claude Code's own `~/.claude/.credentials.json`) are
1660
1873
  sealed at the kernel — reads and writes, children and grandchildren included.
1661
1874
  The agent is never asked anything; forbidden paths simply do not exist for it.
1662
1875
  Codex instead applies its native `workspace-write` sandbox and is not wrapped
@@ -1664,6 +1877,21 @@ in seatbelt: MCP workers such as `node_repl` apply their own sandbox, and macOS
1664
1877
  rejects that operation inside an already-caged process. `CITY_CAGE=0`
1665
1878
  deliberately disables the applicable confinement layer.
1666
1879
 
1880
+ **On Linux the cage is bubblewrap.** The seal is built the way Linux builds
1881
+ these — a mount namespace where the sealed paths are simply not mounted, so
1882
+ `~/.ssh` inside the cage is an empty directory and `~/.git-credentials` reads as
1883
+ nothing. Same promise as the seatbelt, different mechanism, and `bin/test-cage.py`
1884
+ proves it against a real namespace on every Linux CI run: the planted key is
1885
+ unreadable, the repo stays writable, a write into a sealed directory never
1886
+ reaches the disk, and a grandchild process cannot escape.
1887
+
1888
+ It needs `bubblewrap` installed (`apt install bubblewrap`) and unprivileged user
1889
+ namespaces enabled — Agents City checks that bwrap can really build one rather
1890
+ than trusting that the binary exists, and a machine where it cannot says so and
1891
+ launches uncaged, exactly as before. There is no confinement on other platforms:
1892
+ without a cage, run agents over work you would be comfortable running a script
1893
+ over.
1894
+
1667
1895
  Because a caged window cannot read the `gh` token, PRs and pushes go through
1668
1896
  an opt-in credential broker (`CITY_BROKER=1`): a small owner-side process that
1669
1897
  holds the credentials, accepts per-window tokens bound to a single repo,
@@ -1837,8 +2065,8 @@ agents-city seat --repos
1837
2065
  ```
1838
2066
 
1839
2067
  Discovery requires `.git` (a directory or worktree file) and an `origin` remote.
1840
- If roots just changed, refresh in the Hall or remove only
1841
- `~/.cache/agents-city/repos.tsv`. `AGENTS_CITY_ORG` may be filtering the repo;
2068
+ If roots just changed, use the house form's **Search again**, or run
2069
+ `plugin/scripts/busca.py --refresh`. `AGENTS_CITY_ORG` may be filtering the repo;
1842
2070
  leave it empty to index every remote.
1843
2071
 
1844
2072
  ### GitHub does not show private repos or organisations
@@ -1964,7 +2192,7 @@ npm pack --dry-run
1964
2192
  npm pack
1965
2193
 
1966
2194
  CITY_TEST_PREFIX="$(mktemp -d)"
1967
- npm install -g --prefix "$CITY_TEST_PREFIX" ./agents-city-0.3.0-beta.21.tgz
2195
+ npm install -g --prefix "$CITY_TEST_PREFIX" ./agents-city-*.tgz
1968
2196
  "$CITY_TEST_PREFIX/bin/agents-city" --version
1969
2197
  "$CITY_TEST_PREFIX/bin/agents-city" --help
1970
2198
  ```
@@ -32,11 +32,14 @@ const ORDENES = {
32
32
  reset: { que: ['bin/reset'], di: 'reset one city to onboarding, recoverably' },
33
33
  skills: { que: ['bin/skills'], di: 'recognise the skills installed in each repo' },
34
34
  city: { que: ['bin/city'], di: 'draw your city' },
35
+ shortcut: { que: ['bin/shortcut'], di: 'put a city on your desktop: icon, name, double-click' },
35
36
  demo: { que: ['bin/demo'], di: 'Aurora Games — see it working, no account' },
36
37
  setup: { que: ['bin/setup.py'], di: 'create or open a personal city' },
37
38
  report: { que: ['bin/report.py'], di: 'report growth from your folders' },
38
39
  tokens: { que: ['bin/tokens.py'], di: 'report token spend' },
39
40
  exit: { que: ['bin/exit'], di: 'close the day — every session and agent, or one city' },
41
+ doctor: { que: ['bin/doctor'], di: 'check this machine: tools, runtimes, cage, city, version' },
42
+ update: { que: ['bin/update'], di: 'install the newest published version (--check just asks)' },
40
43
  test: { que: ['bin/test'], di: 'every check in the repo' },
41
44
  };
42
45
 
package/bin/doctor ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+ # Check this machine: tools, runtimes, the cage, the city, and the version.
3
+ exec python3 "$(cd "$(dirname "$0")/../plugin/scripts" && pwd)/doctor.py" "$@"