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.
- package/.claude-plugin/marketplace.json +1 -1
- package/README.es.md +310 -70
- package/README.md +297 -69
- package/bin/agents-city.js +3 -0
- package/bin/doctor +3 -0
- package/bin/hall.html +164 -24
- package/bin/navegador.mjs +415 -0
- package/bin/serve.py +383 -127
- package/bin/shortcut +3 -0
- package/bin/test +5 -2
- package/bin/test-actualiza.py +130 -0
- package/bin/test-atajos.py +301 -0
- package/bin/test-busca.py +216 -0
- package/bin/test-cage.py +170 -2
- package/bin/test-card.py +2 -2
- package/bin/test-cities.py +45 -0
- package/bin/test-contracts.py +12 -5
- package/bin/test-doctor.py +33 -0
- package/bin/test-navegador.py +164 -0
- package/bin/test-seat.py +245 -25
- package/bin/test-serve.py +214 -9
- package/bin/test-workspace.py +63 -0
- package/bin/testlib.py +23 -0
- package/bin/update +3 -0
- package/city/web/dist/city.js +47 -47
- package/city/web/dist/index.html +1 -1
- package/city/web/dist-hall/hall.js +2193 -174
- package/city/web/src/bienvenida.ts +686 -0
- package/city/web/src/es.ts +180 -0
- package/city/web/src/hall.ts +520 -168
- package/city/web/src/idioma.ts +86 -0
- package/city/web/src/main.ts +27 -0
- package/city/web/src/motores.ts +54 -0
- package/docs/agents-first.md +8 -1
- package/docs/security.md +46 -12
- package/docs/testing.md +1 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/channel/bus.js +1 -1
- package/plugin/channel/bus.ts +1 -1
- package/plugin/channel/runtime/codex.ts +1 -1
- package/plugin/channel/runtime-gateway.js +1 -1
- package/plugin/scripts/actualiza.py +198 -0
- package/plugin/scripts/atajos.py +506 -0
- package/plugin/scripts/busca.py +436 -0
- package/plugin/scripts/cage.py +266 -26
- package/plugin/scripts/capabilities.py +17 -10
- package/plugin/scripts/card.py +10 -0
- package/plugin/scripts/cities.py +34 -0
- package/plugin/scripts/city-session.sh +33 -7
- package/plugin/scripts/doctor.py +122 -0
- package/plugin/scripts/find-repos.sh +12 -105
- package/plugin/scripts/read-card.py +6 -2
- package/plugin/scripts/report.py +5 -6
- package/plugin/scripts/reset.py +50 -14
- package/plugin/scripts/seat.py +445 -103
- 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
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
102
|
-
|
|
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
|
-
|
|
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
|
-
|
|
112
|
+
### Try it without installing anything
|
|
107
113
|
|
|
108
114
|
```bash
|
|
109
|
-
|
|
115
|
+
npx agents-city
|
|
110
116
|
```
|
|
111
117
|
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
|
|
117
|
-
agents-city
|
|
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
|
-
|
|
122
|
-
|
|
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
|
-
###
|
|
133
|
+
### Update, or remove
|
|
125
134
|
|
|
126
135
|
```bash
|
|
127
|
-
agents-city
|
|
128
|
-
#
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
|
197
|
+
### Update an installation
|
|
176
198
|
|
|
177
199
|
```bash
|
|
178
|
-
|
|
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
|
|
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.
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
`
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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
|
|
263
|
-
|
|
264
|
-
Pressing Enter keeps Claude everywhere. You may instead choose per window:
|
|
305
|
+
### 5. Runtime for your own chair
|
|
265
306
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
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
|
|
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,
|
|
1841
|
-
|
|
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
|
|
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
|
```
|
package/bin/agents-city.js
CHANGED
|
@@ -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