pilotswarm 0.5.12 → 0.5.14

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 (42) hide show
  1. package/README.md +230 -7
  2. package/mcp/README.md +13 -1
  3. package/mcp/dist/src/context.d.ts +13 -0
  4. package/mcp/dist/src/context.d.ts.map +1 -1
  5. package/mcp/dist/src/context.js +20 -0
  6. package/mcp/dist/src/context.js.map +1 -1
  7. package/mcp/dist/src/tools/capabilities.d.ts +3 -0
  8. package/mcp/dist/src/tools/capabilities.d.ts.map +1 -1
  9. package/mcp/dist/src/tools/capabilities.js +8 -0
  10. package/mcp/dist/src/tools/capabilities.js.map +1 -1
  11. package/mcp/dist/src/tools/sessions.d.ts.map +1 -1
  12. package/mcp/dist/src/tools/sessions.js +114 -0
  13. package/mcp/dist/src/tools/sessions.js.map +1 -1
  14. package/package.json +3 -2
  15. package/tui/src/app.js +19 -2
  16. package/tui/src/auth/cli.js +13 -0
  17. package/tui/src/node-sdk-transport.js +53 -8
  18. package/tui/tui-splash-mobile.txt +5 -7
  19. package/tui/tui-splash.txt +13 -9
  20. package/ui/core/src/commands.js +2 -0
  21. package/ui/core/src/controller.js +275 -6
  22. package/ui/core/src/history.js +19 -1
  23. package/ui/core/src/reducer.js +4 -0
  24. package/ui/core/src/selectors.js +139 -14
  25. package/ui/core/src/themes/helpers.js +4 -0
  26. package/ui/react/src/components.js +95 -6
  27. package/ui/react/src/web-app.js +555 -117
  28. package/web/api/router.js +7 -6
  29. package/web/api/ws.js +9 -0
  30. package/web/auth/index.js +5 -0
  31. package/web/auth/providers/dev.js +119 -0
  32. package/web/authz.js +142 -0
  33. package/web/dist/assets/index-BnxC8cNG.js +24 -0
  34. package/web/dist/assets/{index-oldX95Tp.css → index-Bx6KHIaj.css} +1 -1
  35. package/web/dist/assets/pilotswarm-NE7H63ha.js +90 -0
  36. package/web/dist/assets/react-l0sNRNKZ.js +1 -0
  37. package/web/dist/index.html +3 -4
  38. package/web/runtime.js +453 -9
  39. package/web/server.js +2 -2
  40. package/web/dist/assets/index-CJJRJUex.js +0 -24
  41. package/web/dist/assets/pilotswarm-DRs6o-lA.js +0 -90
  42. package/web/dist/assets/react-C9iQPS2h.js +0 -1
package/README.md CHANGED
@@ -7,22 +7,242 @@ surface of a [PilotSwarm](https://github.com/affandar/pilotswarm) deployment:
7
7
  |---|---|
8
8
  | `pilotswarm` | Terminal UI. `pilotswarm remote --api-url <portal-url>` attaches to any deployment (auto Entra sign-in); `pilotswarm local` runs an embedded dev stack. `pilotswarm-cli` is an alias. |
9
9
  | `pilotswarm-web` | The portal server: hosts the browser UI **and** the deployment's Web API (`/api/v1` + `/api/v1/ws`) — the single integration surface every client rides. |
10
- | `pilotswarm-mcp` | MCP server exposing PilotSwarm sessions/facts/models to Claude Desktop, Cursor, or any MCP client. `--api-url <portal-url>` is the supported mode. |
10
+ | `pilotswarm-mcp` | MCP server exposing PilotSwarm sessions/facts/models to Claude Code, Claude Desktop, Copilot CLI, VS Code, Cursor, or any MCP client. |
11
+
12
+ Requires **Node 24+**. Everything below assumes you already have a deployment's
13
+ portal URL — that URL is the only thing you need to configure.
14
+
15
+ ---
16
+
17
+ ## Quickstart
18
+
19
+ ### 1. Install
11
20
 
12
21
  ```bash
13
22
  npm install -g pilotswarm
23
+ ```
24
+
25
+ (Or skip the install and prefix every command with `npx -p pilotswarm`.)
26
+
27
+ ### 2. Sign in to a deployment
28
+
29
+ ```bash
30
+ pilotswarm auth login --api-url https://portal.example.com
31
+ ```
32
+
33
+ This opens your browser for Entra sign-in and caches the token under
34
+ `~/.config/pilotswarm/auth/<origin>.json`. **Every surface in this package —
35
+ the TUI and the MCP server — reads that same cache**, so you sign in once per
36
+ deployment, not once per client.
14
37
 
15
- # attach the TUI to a deployment the URL is the only credential you need
38
+ If the deployment has auth disabled, the command simply tells you so and there
39
+ is nothing to do.
40
+
41
+ ```bash
42
+ pilotswarm auth status --api-url https://portal.example.com # who am I, is the token still good
43
+ pilotswarm auth logout --api-url https://portal.example.com # drop cached tokens for that origin
44
+ ```
45
+
46
+ On a headless box (no browser), add `--device-code` to use the device-code flow
47
+ instead — but note many corporate tenants block device code via Conditional
48
+ Access.
49
+
50
+ ### 3. Run the TUI
51
+
52
+ ```bash
16
53
  pilotswarm remote --api-url https://portal.example.com
54
+ ```
17
55
 
18
- # host a portal (needs worker-side env: DATABASE_URL etc.)
19
- pilotswarm-web --plugin ./plugin
56
+ The `remote` positional is required — `--api-url` without it is an error,
57
+ because bare `pilotswarm` means *local* mode. You can drop the flag entirely by
58
+ setting `PILOTSWARM_API_URL`, or by putting it in a `.env.remote` file next to
59
+ you (remote mode auto-loads `.env.remote`; local mode auto-loads `.env`):
60
+
61
+ ```bash
62
+ export PILOTSWARM_API_URL=https://portal.example.com
63
+ pilotswarm remote
64
+ ```
65
+
66
+ Step 2 is optional in practice: the TUI runs the same sign-in lazily on start
67
+ if no cached token is found. Running `auth login` first just gets the browser
68
+ dance out of the way before the full-screen UI takes over your terminal, and it
69
+ is what makes the MCP servers below work without any further setup.
70
+
71
+ Useful TUI flags: `-m, --model <name>` (initial model), `-p, --plugin <dir>`
72
+ (plugin directory), `-e, --env <file>` (env file), `-h, --help`.
73
+
74
+ ---
75
+
76
+ ## Connect your AI assistant (MCP)
77
+
78
+ `pilotswarm-mcp` is a local, stdio MCP server: your assistant spawns it as a
79
+ child process, and it calls the deployment's Web API **as you**, reusing the
80
+ token cached by `pilotswarm auth login`. Nothing extra is deployed, and no
81
+ secret goes into the config file — just the URL.
82
+
83
+ ```
84
+ MCP host (Claude Code / Claude Desktop / Copilot CLI / VS Code)
85
+ └─ spawns → pilotswarm-mcp (local, stdio)
86
+ └─ HTTPS → https://portal.example.com/api/v1
87
+ (your identity; your role decides your tool surface)
88
+ ```
89
+
90
+ Your Entra app role gates the surface: admin-only tools (embedder start/stop,
91
+ `facts_admin`, `restart_system_session`, graph-namespace writes) register only
92
+ for admin credentials.
93
+
94
+ On shared deployments, sessions are owner-scoped. Owners can open a whole
95
+ session tree as read/write or grant a named teammate targeted read/write access;
96
+ management, deletion, and sharing remain owner/admin operations. The portal,
97
+ TUI, Web API, WebSocket stream, and MCP server enforce the same rules. See the
98
+ [security and sharing guide](https://github.com/affandar/pilotswarm/blob/main/docs/user-guide/security-and-sharing.md).
99
+
100
+ ### Claude Code
101
+
102
+ ```bash
103
+ claude mcp add pilotswarm -- npx -y -p pilotswarm pilotswarm-mcp \
104
+ --api-url https://portal.example.com
105
+ ```
106
+
107
+ Or check a `.mcp.json` into the project root so your whole team gets it:
108
+
109
+ ```json
110
+ {
111
+ "mcpServers": {
112
+ "pilotswarm": {
113
+ "type": "stdio",
114
+ "command": "npx",
115
+ "args": ["-y", "-p", "pilotswarm", "pilotswarm-mcp",
116
+ "--api-url", "https://portal.example.com"]
117
+ }
118
+ }
119
+ }
120
+ ```
121
+
122
+ ### Claude Desktop
123
+
124
+ Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
125
+ or `%APPDATA%\Claude\claude_desktop_config.json` (Windows), then restart the
126
+ app:
20
127
 
21
- # expose a deployment to an MCP client
22
- pilotswarm-mcp --api-url https://portal.example.com
128
+ ```json
129
+ {
130
+ "mcpServers": {
131
+ "pilotswarm": {
132
+ "command": "npx",
133
+ "args": ["-y", "-p", "pilotswarm", "pilotswarm-mcp",
134
+ "--api-url", "https://portal.example.com"]
135
+ }
136
+ }
137
+ }
23
138
  ```
24
139
 
25
- Library surfaces (used by the shipped UIs; importable for custom hosts):
140
+ ### GitHub Copilot CLI
141
+
142
+ Write `.copilot/mcp-config.json` in the repo (or `~/.copilot/mcp-config.json`
143
+ to have it everywhere):
144
+
145
+ ```json
146
+ {
147
+ "mcpServers": {
148
+ "pilotswarm": {
149
+ "type": "stdio",
150
+ "command": "npx",
151
+ "args": ["-y", "-p", "pilotswarm", "pilotswarm-mcp",
152
+ "--api-url", "https://portal.example.com"]
153
+ }
154
+ }
155
+ }
156
+ ```
157
+
158
+ ### VS Code (Copilot)
159
+
160
+ Add `.vscode/mcp.json` to the workspace — note the key is `servers`, not
161
+ `mcpServers`. The server then shows up in agent mode's tool picker:
162
+
163
+ ```json
164
+ {
165
+ "servers": {
166
+ "pilotswarm": {
167
+ "type": "stdio",
168
+ "command": "npx",
169
+ "args": ["-y", "-p", "pilotswarm", "pilotswarm-mcp",
170
+ "--api-url", "https://portal.example.com"]
171
+ }
172
+ }
173
+ }
174
+ ```
175
+
176
+ ### Cursor
177
+
178
+ Same shape as Claude Desktop, in `~/.cursor/mcp.json` (or **Settings → MCP**).
179
+
180
+ ### Check that it worked
181
+
182
+ Ask your assistant to call `get_capabilities`. You should get back
183
+ `mode: "web"`, your `admin` flag, and the deployment's facts/graph flags. Then
184
+ `list_sessions` for a fleet view, and `create_session` → `send_and_wait` to
185
+ drive one.
186
+
187
+ If it fails to start, run the same command by hand — the error is much easier
188
+ to read outside the MCP host:
189
+
190
+ ```bash
191
+ npx -y -p pilotswarm pilotswarm-mcp --api-url https://portal.example.com --log-level info
192
+ ```
193
+
194
+ The usual cause is a missing or expired token: re-run
195
+ `pilotswarm auth login --api-url <url>`.
196
+
197
+ ### Non-interactive credentials (CI, service principals, containers)
198
+
199
+ There is no browser to sign in with, so hand the server a bearer token
200
+ directly:
201
+
202
+ ```bash
203
+ PILOTSWARM_API_TOKEN=<token> npx -y -p pilotswarm pilotswarm-mcp \
204
+ --api-url https://portal.example.com
205
+ ```
206
+
207
+ ### Remote / shared MCP over HTTP
208
+
209
+ For a shared endpoint rather than a per-user child process, run the server with
210
+ the HTTP transport and a bearer key clients must present:
211
+
212
+ ```bash
213
+ PILOTSWARM_MCP_KEY=your-secret-key npx -y -p pilotswarm pilotswarm-mcp \
214
+ --transport http --port 3100 --api-url https://portal.example.com
215
+ ```
216
+
217
+ Clients then point at `http://your-host:3100/mcp` with an
218
+ `Authorization: Bearer ${PILOTSWARM_MCP_KEY}` header. Read the
219
+ [security model](https://github.com/affandar/pilotswarm/blob/main/packages/app/mcp/README.md#security-model)
220
+ before exposing this beyond localhost: the key is shared, and every client
221
+ behind it has the full scope of the deployment.
222
+
223
+ Full tool catalog, resources, and every flag:
224
+ [MCP server README](https://github.com/affandar/pilotswarm/blob/main/packages/app/mcp/README.md).
225
+
226
+ ---
227
+
228
+ ## Other surfaces
229
+
230
+ **Run everything locally** (embedded workers, no deployment, no auth) — the fast
231
+ way to try PilotSwarm or develop a plugin:
232
+
233
+ ```bash
234
+ pilotswarm local # bare `pilotswarm` does the same
235
+ pilotswarm local -p ./plugin -n 4
236
+ ```
237
+
238
+ **Host a portal** — serves the browser UI and the Web API that every client
239
+ above rides on. Needs worker-side env (`DATABASE_URL`, model providers, …):
240
+
241
+ ```bash
242
+ pilotswarm-web --plugin ./plugin
243
+ ```
244
+
245
+ **Library surfaces** (used by the shipped UIs; importable for custom hosts):
26
246
 
27
247
  - `pilotswarm/ui-core` — framework-free UI controller/state/selectors
28
248
  - `pilotswarm/ui-react` — the shared React composition (Ink + DOM)
@@ -33,7 +253,10 @@ Building an app or service instead of a UI? You want
33
253
  [`pilotswarm-sdk`](https://www.npmjs.com/package/pilotswarm-sdk) — including
34
254
  its zero-dependency wire client at `pilotswarm-sdk/api`.
35
255
 
256
+ ---
257
+
36
258
  Docs: [Quick Start](https://github.com/affandar/pilotswarm/blob/main/docs/quickstart/docker.md) ·
37
259
  [User Guide](https://github.com/affandar/pilotswarm/blob/main/docs/user-guide/README.md) ·
260
+ [MCP Setup](https://github.com/affandar/pilotswarm/blob/main/docs/user-guide/mcp-local-setup.md) ·
38
261
  [Web API Reference](https://github.com/affandar/pilotswarm/blob/main/docs/api/reference.md) ·
39
262
  [Architecture / Layering](https://github.com/affandar/pilotswarm/blob/main/docs/architecture/layering.md)
package/mcp/README.md CHANGED
@@ -39,7 +39,7 @@ Each client below shows both **Stdio** (local, recommended) and **HTTP** (remote
39
39
 
40
40
  ### GitHub Copilot CLI
41
41
 
42
- Add to your `.mcp.json` (project root or `~/.copilot/`):
42
+ Add to `.copilot/mcp-config.json` (repo-scoped) or `~/.copilot/mcp-config.json` (global):
43
43
 
44
44
  **Stdio (local):**
45
45
 
@@ -380,6 +380,12 @@ with `get_capabilities` to see the shape of this server.
380
380
  | `list_sessions` | Discovery — list all sessions with status, model, agent info, and parent/child relationships; keyset pagination via `limit`/`cursor`/`include_deleted` |
381
381
  | `get_session_detail` | Discovery — get detailed info for a session including status, context usage, cron state, and pending questions |
382
382
  | `get_session_events` | Discovery — CMS event stream with `after_seq` forward paging, `before_seq` history paging, `event_types` server-side filter, and long-poll support |
383
+ | `get_session_access` | Effective caller access, visibility, relation, and owner for one session tree |
384
+ | `set_session_visibility` | Set `private`, `shared_read`, or `shared_write` on an owned session tree |
385
+ | `grant_session_share` / `revoke_session_share` | Owner/admin targeted read/write grant management |
386
+ | `list_session_shares` | Owner/admin listing of targeted grants on a session tree |
387
+ | `list_known_users` | Bounded member directory used to resolve a grantee; helper only, not an allowlist |
388
+ | `list_authz_audit` | Owner audit for one session or admin fleet-wide authorization audit |
383
389
 
384
390
  ### Turn & Queue Control
385
391
 
@@ -464,6 +470,12 @@ External clients **cannot** spawn, message, or cancel a sub-agent. Calling a rem
464
470
 
465
471
  Top-level session control (`create_session`, `send_message`, `delete_session`, etc.) is unaffected by this boundary — those tools remain on the external surface.
466
472
 
473
+ Session visibility still applies to every MCP operation. A server running with
474
+ `--api-url` acts as the cached Entra principal from `pilotswarm auth login` (or
475
+ the supplied bearer token): unreadable sessions are absent/not-found, writes
476
+ require owner/admin, `shared_write`, or a targeted write grant, and sharing
477
+ metadata is owner/admin only.
478
+
467
479
  ### Agent Management
468
480
 
469
481
  | Tool | Description |
@@ -34,6 +34,19 @@ export interface ServerContext {
34
34
  * [admin]-tagged tools register iff true.
35
35
  */
36
36
  admin: boolean;
37
+ /**
38
+ * The caller's normalized role (`admin` | `user` | `anonymous` | null),
39
+ * and the deployment's ownership/visibility posture. Web mode reads these
40
+ * from /auth/me and /bootstrap; direct mode is privileged (`admin`) with
41
+ * enforcement off. Surfaced by get_capabilities so an agent can explain a
42
+ * refusal instead of retrying blindly.
43
+ */
44
+ role: string | null;
45
+ authz: {
46
+ ownershipEnforced: boolean;
47
+ defaultVisibility: string;
48
+ systemVisibility: string;
49
+ };
37
50
  /** True when running over the Web API (`--api-url`); false in direct mode. */
38
51
  webMode: boolean;
39
52
  models: ModelProviderRegistry | null;
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,0BAA0B,EAQ1B,qBAAqB,EAErB,cAAc,EACd,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,IAAI,EAAE,0BAA0B,CAAC;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB;;;;;OAKG;IACH,aAAa,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC;;;;;OAKG;IACH,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB;;;;;OAKG;IACH,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IACtB;;;;;;OAMG;IACH,KAAK,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE;;;;;;OAMG;IACH,gBAAgB,EAAE,WAAW,EAAE,CAAC;IAChC;;;;;OAKG;IACH,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B;;;;;OAKG;IACH,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACjC,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,CA6KtF"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,0BAA0B,EAQ1B,qBAAqB,EAErB,cAAc,EACd,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,IAAI,EAAE,0BAA0B,CAAC;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB;;;;;OAKG;IACH,aAAa,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC;;;;;OAKG;IACH,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB;;;;;OAKG;IACH,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IACtB;;;;;;OAMG;IACH,KAAK,EAAE,OAAO,CAAC;IACf;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE;QAAE,iBAAiB,EAAE,OAAO,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3F,8EAA8E;IAC9E,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE;;;;;;OAMG;IACH,gBAAgB,EAAE,WAAW,EAAE,CAAC;IAChC;;;;;OAKG;IACH,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B;;;;;OAKG;IACH,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACjC,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,CAiMtF"}
@@ -8,6 +8,8 @@ export async function createContext(opts) {
8
8
  let graph = null;
9
9
  let api = null;
10
10
  let admin = false;
11
+ let ctxRole = null;
12
+ let ctxAuthz = { ownershipEnforced: false, defaultVisibility: "private", systemVisibility: "read" };
11
13
  let webAgents = null;
12
14
  if (opts.apiUrl) {
13
15
  // Web API mode (supported): no database credentials in this process.
@@ -34,10 +36,25 @@ export async function createContext(opts) {
34
36
  const me = await api.getAuthContext();
35
37
  const role = me?.authorization?.role;
36
38
  admin = role === "admin" || role === "anonymous";
39
+ ctxRole = typeof role === "string" ? role : null;
37
40
  }
38
41
  catch {
39
42
  admin = false;
40
43
  }
44
+ // Ownership/visibility posture from /bootstrap (security model).
45
+ try {
46
+ const boot = await api.getBootstrap();
47
+ if (boot?.authz && typeof boot.authz === "object") {
48
+ ctxAuthz = {
49
+ ownershipEnforced: Boolean(boot.authz.ownershipEnforced),
50
+ defaultVisibility: String(boot.authz.defaultVisibility || "private"),
51
+ systemVisibility: String(boot.authz.systemVisibility || "read"),
52
+ };
53
+ }
54
+ }
55
+ catch {
56
+ // leave defaults
57
+ }
41
58
  // Registered agents: the deployment's creatable-agent catalog is the
42
59
  // truth in web mode — local plugin dirs may diverge from what
43
60
  // createSessionForAgent will accept.
@@ -61,6 +78,7 @@ export async function createContext(opts) {
61
78
  // Direct mode (internal/testing): straight to the datastore. A
62
79
  // process holding DATABASE_URL is definitionally privileged.
63
80
  admin = true;
81
+ ctxRole = "admin";
64
82
  client = new PilotSwarmClient({ store: opts.store });
65
83
  await client.start();
66
84
  mgmt = new PilotSwarmManagementClient({ store: opts.store });
@@ -166,6 +184,8 @@ export async function createContext(opts) {
166
184
  graph,
167
185
  api,
168
186
  admin,
187
+ role: ctxRole,
188
+ authz: ctxAuthz,
169
189
  webMode: Boolean(opts.apiUrl),
170
190
  models,
171
191
  skills,
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,9 @@ import type { ServerContext } from "../context.js";
12
12
  export declare function buildCapabilities(ctx: ServerContext): {
13
13
  mode: string;
14
14
  admin: boolean;
15
+ role: string | null;
16
+ ownership_enforced: boolean;
17
+ default_visibility: string;
15
18
  facts: {
16
19
  search: boolean;
17
20
  embedder: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../src/tools/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa;;;;;;;;;;;;;EAiBnD;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,QA0C5E"}
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../src/tools/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa;;;;;;;;;;;;;;;;EAyBnD;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,QA0C5E"}
@@ -12,6 +12,14 @@ export function buildCapabilities(ctx) {
12
12
  return {
13
13
  mode: ctx.webMode ? "web" : "direct",
14
14
  admin: ctx.admin,
15
+ // Ownership/visibility posture (security model): the caller's role and
16
+ // whether the deployment enforces per-user session access. When
17
+ // ownership_enforced is true, list_sessions returns only sessions you
18
+ // can read and a send/read to another user's private session is
19
+ // refused with the reason in the error.
20
+ role: ctx.role ?? null,
21
+ ownership_enforced: ctx.authz?.ownershipEnforced ?? false,
22
+ default_visibility: ctx.authz?.defaultVisibility ?? "private",
15
23
  facts: {
16
24
  search: Boolean(ctx.enhancedFacts?.capabilities.search),
17
25
  embedder: Boolean(ctx.enhancedFacts?.capabilities.embedder),
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../../src/tools/capabilities.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEhE;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAkB;IAChD,OAAO;QACH,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;QACpC,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,KAAK,EAAE;YACH,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,MAAM,CAAC;YACvD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,QAAQ,CAAC;SAC9D;QACD,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;QACzB,qEAAqE;QACrE,8BAA8B;QAC9B,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,OAAQ,GAAG,CAAC,KAAa,CAAC,mBAAmB,KAAK,UAAU,CAAC;QACpG,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,OAAQ,GAAG,CAAC,KAAa,CAAC,UAAU,KAAK,UAAU,CAAC;QACtF,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO;QACrD,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM;QACjC,iBAAiB,EAAE,GAAG,CAAC,gBAAgB,CAAC,MAAM;KACjD,CAAC;AACN,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,GAAkB;IACzE,MAAM,CAAC,YAAY,CACf,kBAAkB,EAClB;QACI,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACP,oGAAoG;cAClG,sGAAsG;cACtG,qGAAqG;cACrG,gDAAgD;QACtD,WAAW,EAAE,EAAE;KAClB,EACD,cAAc,CAAC,KAAK,IAAI,EAAE;QACtB,gEAAgE;QAChE,iEAAiE;QACjE,+DAA+D;QAC/D,kEAAkE;QAClE,iDAAiD;QACjD,IAAI,eAAe,GAAkB,IAAI,CAAC;QAC1C,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,IAAI,CAAC;gBACD,MAAM,CAAC,GAAQ,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;gBACpD,eAAe,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC;YACnF,CAAC;YAAC,MAAM,CAAC;gBACL,eAAe,GAAG,IAAI,CAAC;YAC3B,CAAC;QACL,CAAC;QACD,IAAI,YAAY,GAAkB,IAAI,CAAC;QACvC,IAAI,CAAC;YACD,YAAY,GAAG,GAAG,CAAC,MAAM;gBACrB,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC;gBACnC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACL,YAAY,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,OAAO,UAAU,CAAC;YACd,GAAG,iBAAiB,CAAC,GAAG,CAAC;YACzB,gBAAgB,EAAE,eAAe;YACjC,aAAa,EAAE,YAAY;SAC9B,CAAC,CAAC;IACP,CAAC,CAAC,CACL,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../../src/tools/capabilities.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/tools/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAOnD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,QAgrBzE"}
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/tools/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAOnD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,QAmzBzE"}
@@ -334,6 +334,120 @@ export function registerSessionTools(server, ctx) {
334
334
  };
335
335
  }
336
336
  });
337
+ // ── Session sharing (security model) ─────────────────────────────
338
+ // Owner-or-admin operations; the server enforces and returns the authz
339
+ // reason in the error when refused. Registered for all callers.
340
+ // Web mode: dispatch through the API (server enforces). Direct mode
341
+ // (admin/test-only): call the management client with POSITIONAL args —
342
+ // its signatures are (sessionId, …), not a single params object.
343
+ const callShare = async (op, params, positional) => {
344
+ if (ctx.api)
345
+ return ctx.api.call(op, params);
346
+ return ctx.mgmt[op]?.(...positional);
347
+ };
348
+ const shareError = (err, session_id) => ({
349
+ content: [{ type: "text", text: JSON.stringify({ error: err instanceof Error ? err.message : String(err), session_id }) }],
350
+ isError: true,
351
+ });
352
+ server.registerTool("set_session_visibility", {
353
+ title: "Set Session Visibility",
354
+ description: "Set the sharing level of a session's tree (owner or admin only): "
355
+ + "'private' (only owner + admins), 'shared_read' (every user can view), "
356
+ + "'shared_write' (every user can view and send). Applies to the whole sub-agent tree.",
357
+ inputSchema: {
358
+ session_id: sessionIdShape().describe("Session whose tree visibility to set"),
359
+ visibility: z.enum(["private", "shared_read", "shared_write"]).describe("New visibility level"),
360
+ },
361
+ }, async ({ session_id, visibility }) => {
362
+ try {
363
+ await callShare("setSessionVisibility", { sessionId: session_id, visibility }, [session_id, visibility]);
364
+ return { content: [{ type: "text", text: JSON.stringify({ session_id, visibility }) }] };
365
+ }
366
+ catch (err) {
367
+ return shareError(err, session_id);
368
+ }
369
+ });
370
+ server.registerTool("grant_session_share", {
371
+ title: "Grant Session Share",
372
+ description: "Grant a specific user read or write access to a session's tree (owner or admin only). "
373
+ + "Refused with the reason in the error if you are not the owner/admin, or on a system session. "
374
+ + "The grantee does NOT need to have signed in yet: list_known_users is only a lookup helper. "
375
+ + "If the grantee's stable subject is unknown, pass their EMAIL as the subject — the grant "
376
+ + "binds automatically the first time they sign in.",
377
+ inputSchema: {
378
+ session_id: sessionIdShape().describe("Session whose tree to share"),
379
+ provider: z.string().describe("Grantee auth provider (e.g. 'entra', 'dev')"),
380
+ subject: z.string().describe("Grantee stable subject id, or their email if they have never signed in"),
381
+ access: z.enum(["read", "write"]).describe("Access level to grant"),
382
+ email: z.string().nullish().describe("Optional grantee email for display"),
383
+ display_name: z.string().nullish().describe("Optional grantee display name"),
384
+ },
385
+ }, async ({ session_id, provider, subject, access, email, display_name }) => {
386
+ try {
387
+ const grantee = { provider, subject, email: email ?? null, displayName: display_name ?? null };
388
+ await callShare("grantSessionShare", { sessionId: session_id, user: grantee, access }, [session_id, grantee, access]);
389
+ return { content: [{ type: "text", text: JSON.stringify({ session_id, granted: { provider, subject, access } }) }] };
390
+ }
391
+ catch (err) {
392
+ return shareError(err, session_id);
393
+ }
394
+ });
395
+ server.registerTool("revoke_session_share", {
396
+ title: "Revoke Session Share",
397
+ description: "Revoke a user's targeted share on a session's tree (owner or admin only).",
398
+ inputSchema: {
399
+ session_id: sessionIdShape().describe("Session whose share to revoke"),
400
+ provider: z.string().describe("Grantee auth provider"),
401
+ subject: z.string().describe("Grantee stable subject id"),
402
+ },
403
+ }, async ({ session_id, provider, subject }) => {
404
+ try {
405
+ await callShare("revokeSessionShare", { sessionId: session_id, user: { provider, subject } }, [session_id, { provider, subject }]);
406
+ return { content: [{ type: "text", text: JSON.stringify({ session_id, revoked: { provider, subject } }) }] };
407
+ }
408
+ catch (err) {
409
+ return shareError(err, session_id);
410
+ }
411
+ });
412
+ server.registerTool("list_session_shares", {
413
+ title: "List Session Shares",
414
+ description: "List the targeted user grants on a session's tree (owner or admin only).",
415
+ inputSchema: {
416
+ session_id: sessionIdShape().describe("Session whose shares to list"),
417
+ },
418
+ }, async ({ session_id }) => {
419
+ try {
420
+ const shares = await callShare("listSessionShares", { sessionId: session_id }, [session_id]);
421
+ return { content: [{ type: "text", text: JSON.stringify({ session_id, shares: shares ?? [] }) }] };
422
+ }
423
+ catch (err) {
424
+ return shareError(err, session_id);
425
+ }
426
+ });
427
+ server.registerTool("list_known_users", {
428
+ title: "List Known Users",
429
+ description: "Directory of users who have signed in at least once (provider, subject, email, display name) — "
430
+ + "a HELPER for resolving a grantee's stable subject by name/email before grant_session_share. "
431
+ + "It is NOT an allowlist: grants may target someone who is not in this directory — even someone "
432
+ + "who has never signed in. For such users pass their email as the subject; the grant binds "
433
+ + "automatically when they first sign in.",
434
+ inputSchema: {
435
+ limit: z.number().int().min(1).max(2000).nullish().describe("Max entries to return (default 500)"),
436
+ },
437
+ }, async ({ limit }) => {
438
+ try {
439
+ const users = ctx.api
440
+ ? await ctx.api.call("listKnownUsers", limit != null ? { limit } : {})
441
+ : await ctx.mgmt.listKnownUsers?.(limit != null ? { limit } : undefined);
442
+ return { content: [{ type: "text", text: JSON.stringify({ users: users ?? [] }) }] };
443
+ }
444
+ catch (err) {
445
+ return {
446
+ content: [{ type: "text", text: JSON.stringify({ error: err instanceof Error ? err.message : String(err) }) }],
447
+ isError: true,
448
+ };
449
+ }
450
+ });
337
451
  // 7. list_sessions — List all sessions with status
338
452
  server.registerTool("list_sessions", {
339
453
  title: "List Sessions",