@monster-orange/den 0.4.12 → 0.4.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 (46) hide show
  1. package/CHANGELOG.md +151 -0
  2. package/README.md +7 -7
  3. package/docs/distributions.md +189 -11
  4. package/package.json +1 -1
  5. package/src/shared/agents/conversations.ts +227 -0
  6. package/src/shared/agents/default-pack/be-dev.md +1 -0
  7. package/src/shared/agents/default-pack/devops.md +1 -0
  8. package/src/shared/agents/default-pack/fe-dev.md +1 -0
  9. package/src/shared/agents/default-pack/orchestrator.md +3 -1
  10. package/src/shared/agents/default-pack/planner.md +1 -0
  11. package/src/shared/agents/default-pack/reviewer.md +1 -0
  12. package/src/shared/agents/default-pack/tester.md +16 -0
  13. package/src/shared/agents/default-pack/ux-designer.md +1 -0
  14. package/src/shared/agents/den-claude.ts +128 -13
  15. package/src/shared/agents/permissions.ts +108 -0
  16. package/src/shared/agents/persona-store.ts +286 -0
  17. package/src/shared/agents/personas.ts +116 -12
  18. package/src/shared/agents/records.ts +33 -0
  19. package/src/shared/agents/roles.ts +288 -0
  20. package/src/shared/agents/runtime.ts +50 -0
  21. package/src/shared/den-config.ts +22 -1
  22. package/src/shared/environment-manager/service-runner.ts +31 -12
  23. package/src/shared/environment-manager/workspaces.ts +11 -0
  24. package/src/ui/cli/agent-ops.ts +796 -29
  25. package/src/ui/cli/agents-command.ts +97 -3
  26. package/src/ui/cli/env-probe.ts +4 -1
  27. package/src/ui/mcp/api.ts +12 -1
  28. package/src/ui/mcp/tools.ts +60 -1
  29. package/src/ui/server/agent-resume-grant.ts +35 -0
  30. package/src/ui/server/agent-routes.ts +412 -22
  31. package/src/ui/server/public/agent-start.js +3 -2
  32. package/src/ui/server/public/agents-page.js +693 -49
  33. package/src/ui/server/public/agents.html +76 -15
  34. package/src/ui/server/public/i18n/es.js +143 -0
  35. package/src/ui/server/public/i18n/ja.js +144 -0
  36. package/src/ui/server/public/persona-ui.css +563 -0
  37. package/src/ui/server/public/persona-ui.js +796 -0
  38. package/src/ui/server/public/settings-page.js +4 -9
  39. package/src/ui/server/public/settings-registry.js +22 -0
  40. package/src/ui/server/public/settings.html +1 -0
  41. package/src/ui/server/public/shell.js +140 -0
  42. package/src/ui/server/public/topbar.js +2 -2
  43. package/src/ui/server/request-guard.ts +17 -4
  44. package/src/ui/server/route-classes.ts +31 -0
  45. package/src/ui/server/session-routes.ts +21 -5
  46. package/src/ui/server/ui-assets.ts +3 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,157 @@ All notable changes to Den are documented here. Each release lists the
4
4
  config and manifest changes a distribution must make to move to it under
5
5
  **Migrations**.
6
6
 
7
+ ## [0.4.14] - 2026-11-07
8
+
9
+ ### Added
10
+
11
+ - **Bring in a conversation (AG-17.1).** A Claude Code conversation you
12
+ started in a terminal outside Den, in the workspace's folder or in one
13
+ of its repos' folders (a repo added by path outside it too), can become
14
+ a Den agent. Agents › Bring in lists them, newest first, and asks for a
15
+ persona; Bring in runs `claude --resume <id>` in the folder it ran in,
16
+ with Den's token, MCP, hooks and guards from then on. Den reads only the
17
+ first and last 64 KB of each transcript. A conversation written in the
18
+ last minute is refused: "Still open in another terminal. Close it there
19
+ first". CLI: `agents import -w <ws>` lists, `agents import -w <ws>
20
+ --session <id> --persona <p>` brings one in. MCP `agent_import` is
21
+ opt-in through `mcp.actions`. Routes: `GET
22
+ /api/workspaces/<ws>/conversations`, `POST
23
+ /api/workspaces/<ws>/conversations/<id>/import`. Only den-claude can
24
+ bring one in for now. The dialog asks you to close the
25
+ conversation in any other terminal first.
26
+ - **One persona, several agents (AG-10.10).** Starting a persona that
27
+ already has an agent in the workspace starts another: `be-dev`, then
28
+ `be-dev-2`, `be-dev-3`. A stopped agent's id is never reused by a new
29
+ start, only by its Resume or Start fresh. The Start dialog says the id
30
+ it will use ("Starts as be-dev-2") and takes an optional Name. An id
31
+ that is running is refused, and the dialog offers "Open the running
32
+ one". `--id` stays exact. The start route takes `name`; `GET
33
+ /api/personas?workspace=<ws>` answers `startsAs`; a 409 for a running
34
+ agent carries `running: {id, sessionId}`.
35
+
36
+ ### Changed
37
+
38
+ - Without `--id`, a start of a persona whose agent is stopped in that
39
+ workspace no longer replaces it: it starts `<persona>-2`. To continue
40
+ the stopped one, Resume it or Start fresh on it.
41
+
42
+ ### Fixed
43
+
44
+ - Bring in: a long title no longer cuts off its "Agent …" badge, and each
45
+ "can't bring in a conversation yet" line is its own sentence.
46
+ Its intro names the repos' folders too.
47
+
48
+ - Start › Advanced: the Model select's default reads "Persona default
49
+ (latest)" for a persona with no model of its own; the longer label was
50
+ cut off.
51
+ - An `up` whose service exits at once with an error no longer leaves the
52
+ service listed. The command could exit before Den recorded its process
53
+ group, and then its record stayed.
54
+
55
+ ## [0.4.13] - 2026-11-07
56
+
57
+ ### Added
58
+
59
+ - **The Start dialog.** + Start agent opens the dialog from the Den Shell
60
+ design. Pick a persona from a list you can search, with category and
61
+ source chips (built-in, distribution, mine); with no filter it is grouped
62
+ by category, and Plain session (your shell in the workspace, no agent) is
63
+ pinned last. Each persona shows its one-line description. "What's a
64
+ persona?" explains the idea, and Details shows the instructions, runtime,
65
+ model and version, permission mode and allowed commands. Then Runtime,
66
+ Workspace, an optional first instruction, and a collapsed Advanced
67
+ section: Model and Version, Permission mode, and Extra allowed commands,
68
+ with a preview of exactly what the runtime will be given.
69
+ - **First instruction.** Den types it into the agent's session once the
70
+ session is ready, as a bracketed paste when the runtime asks for one,
71
+ then Enter. It never goes on the command line and is never stored; the
72
+ audit log records its length only.
73
+ - **Your own personas.** + New persona, Duplicate and Edit write personas
74
+ of your own to `<state_dir>/personas/<id>.md` (0600). Settings ›
75
+ Personas lists every persona with the same search and chips: View or
76
+ Edit, Duplicate, Delete (your own only), + New persona. Built-in and
77
+ distribution personas are read-only; Duplicate makes your own copy.
78
+ Routes: `GET /api/personas/<id>`, `POST /api/personas`, `POST` and
79
+ `DELETE /api/personas/<id>`.
80
+ - **Models and versions.** A runtime lists its models (den-claude: opus,
81
+ sonnet and haiku, each "latest" or a pinned version, from a catalog
82
+ shipped with Den). A pinned version runs as `--model <full id>`. A
83
+ persona or session pinned to an older version says "newer available";
84
+ your own persona has Use latest.
85
+ - **Permissions as intent.** Ask for everything, Auto-approve edits in the
86
+ worktree, or Auto-approve all, plus extra allowed commands as plain
87
+ prefixes. den-claude turns them into `--permission-mode` and
88
+ `Bash(<prefix>)` / `Bash(<prefix> *)` allow rules beside Den's deny
89
+ rules. Other runtimes take none from Den yet, and the dialog says "not
90
+ supported on <runtime>" rather than dropping one.
91
+ - **Override tags.** A session started with choices that differ from its
92
+ persona is tagged in the list: "model: haiku", "pinned <version>",
93
+ "auto-approve edits", "custom tools", the runtime. "auto-approve all" is
94
+ always tagged. Start fresh and Relaunch keep the choices.
95
+ - **Roles and categories.** Den's roles are planner, orchestrator, sde,
96
+ reviewer, tester and designer. Each is a template (instructions,
97
+ permission mode, a read-only command preset) that fills in New persona
98
+ without overwriting what you typed, and it adds nothing hidden to a
99
+ prompt. A distribution adds roles and categories (`agents.roles`,
100
+ `agents.categories`) and may extend a Den role's preset, never redefine
101
+ it.
102
+ - **Plain session from the page.** `POST /api/workspaces/<ws>/sessions`
103
+ starts your login shell in the workspace's folder (capped by
104
+ `sessions.max_concurrent`).
105
+ - **A tester persona** in Den's default pack.
106
+
107
+
108
+ ### Changed
109
+
110
+ - `POST /api/workspaces/<ws>/agents` takes `version`, `permission`,
111
+ `allow` and `instruction`, and refuses an unknown field. Each is checked
112
+ against the runtime's catalog: a model or version it doesn't list, a
113
+ mode other than `ask`, `edits` or `all`, or a command that isn't a plain
114
+ prefix (at most 32, 120 characters each) is a 400. An agent's token gets
115
+ 403 on every persona route and on a plain session.
116
+ - The agent record keeps `version`, `permission`, `allow` and `overrides`.
117
+ - A persona's `role` is a role key; a sentence there still reads as its
118
+ description. Personas gain `display_name`, `category`, `version` and
119
+ `allowed_commands`. `permission_mode` takes `ask`, `edits` or `all`
120
+ (Claude Code's own modes still read). `agents personas` shows SOURCE and
121
+ ROLE columns.
122
+ - fe-dev, be-dev and devops are role `sde`; ux-designer is role
123
+ `designer` in category Design.
124
+ - A persona whose runtime isn't installed starts on the first one that is,
125
+ and the Start dialog says so.
126
+ - **`sessionTitle` is the name a session shows.** `agents list --json`,
127
+ `GET /api/sessions` and the start and resume answers (MCP
128
+ `agent_resume`) now carry the resolved name (Den's rename or the
129
+ runtime's, the later) as `sessionTitle`. 0.4.12 called it `sessionName`,
130
+ which is the agent record's session handle (`<dist>-<ws>:<id>`) and has
131
+ been since 0.4.0. Records are unchanged.
132
+
133
+ ### Fixed
134
+
135
+ - **Settings shows a saved choice at once.** Agents tab layout and Open
136
+ file links in saved, but the pressed button stayed on the old value
137
+ until a reload. The page now takes every setting the save returns.
138
+ - **Claude Code's `/rename "x"` shows as x.** Its title keeps the quotes;
139
+ Den drops one pair around the whole name, for display only.
140
+ - **The terminal fit check is exact again.** The browser test compares
141
+ what is left below and beside a terminal with the cell size xterm drew
142
+ with (now on each pane as `data-cell-w` and `data-cell-h`), less than
143
+ one cell, so a missed row fails on any font.
144
+
145
+ ### Migrations
146
+
147
+ - None required. A persona whose `role:` is a sentence keeps working (it
148
+ becomes the description); set `role:` to a role key to give it one.
149
+ - A persona pack may now set `display_name`, `category`, `version` and
150
+ `allowed_commands`. Use `permission_mode: ask | edits | all` for a mode
151
+ every runtime can translate.
152
+ - `agents.roles` and `agents.categories` are new keys of `agents:` in the
153
+ distribution's config (see docs/distributions.md, Personas).
154
+ - Read `sessionTitle`, not `sessionName`, for the name a session shows in
155
+ `agents list --json`, `GET /api/sessions` and the start and resume
156
+ answers. No record needs changing.
157
+
7
158
  ## [0.4.12] - 2026-11-07
8
159
 
9
160
  ### Added
package/README.md CHANGED
@@ -10,8 +10,8 @@
10
10
  </p>
11
11
 
12
12
  <picture>
13
- <source media="(prefers-color-scheme: dark)" srcset="docs/images/0.4.12/hero-dark.png">
14
- <img src="docs/images/0.4.12/hero-light.png" width="100%" alt="Den's Graph page: the demo workspace's services grouped by application, all healthy, with the status chip and the left rail">
13
+ <source media="(prefers-color-scheme: dark)" srcset="docs/images/0.4.14/hero-dark.png">
14
+ <img src="docs/images/0.4.14/hero-light.png" width="100%" alt="Den's Graph page: the demo workspace's services grouped by application, all healthy, with the status chip and the left rail">
15
15
  </picture>
16
16
 
17
17
  ## Set up by your agent
@@ -38,7 +38,7 @@ It doesn't replace your tools. Your repos, Docker, your test runners, your secre
38
38
  yours. Den connects them and turns on good practice from the start.
39
39
 
40
40
  <p align="center">
41
- <img src="docs/images/0.4.12/up.gif" width="100%" alt="make up in the Graph page: every stack down, then demo-api, demo-web and demo-notes come up in dependency order until the status chip reads All 3 healthy">
41
+ <img src="docs/images/0.4.14/up.gif" width="100%" alt="make up in the Graph page: every stack down, then demo-api, demo-web and demo-notes come up in dependency order until the status chip reads All 3 healthy">
42
42
  </p>
43
43
 
44
44
  ## How it helps
@@ -68,10 +68,10 @@ yours. Den connects them and turns on good practice from the start.
68
68
  lives in your own repo.
69
69
 
70
70
  <p align="center">
71
- <img src="docs/images/0.4.12/agents.png" width="49%" alt="The Agents tab: the demo workspace's sessions on the left, and one open in a terminal pane on the right, running demo-api's test and then the service">
72
- <img src="docs/images/0.4.12/workspaces.png" width="49%" alt="The Workspaces page: the demo workspace's repos with their health, mode and Start, Stop, Restart and Logs actions">
73
- <img src="docs/images/0.4.12/status-drawer.png" width="49%" alt="The status drawer: nothing needs attention, and every service in the demo workspace, by application, with its latency">
74
- <img src="docs/images/0.4.12/edge.png" width="49%" alt="The Edge page: the edge container up, its ports and TLS, and every route it serves, Den's own and each stack's, with its upstream">
71
+ <img src="docs/images/0.4.14/agents.png" width="49%" alt="The Agents tab: the demo workspace's sessions on the left, and one open in a terminal pane on the right, running demo-api's test and then the service">
72
+ <img src="docs/images/0.4.14/workspaces.png" width="49%" alt="The Workspaces page: the demo workspace's repos with their health, mode and Start, Stop, Restart and Logs actions">
73
+ <img src="docs/images/0.4.14/status-drawer.png" width="49%" alt="The status drawer: nothing needs attention, and every service in the demo workspace, by application, with its latency">
74
+ <img src="docs/images/0.4.14/edge.png" width="49%" alt="The Edge page: the edge container up, its ports and TLS, and every route it serves, Den's own and each stack's, with its upstream">
75
75
  </p>
76
76
 
77
77
  ## Get started
@@ -1932,6 +1932,13 @@ orchestrator. It is off unless `mcp.actions` names it. A scoped server
1932
1932
  itself. The web server checks the same rule, and the resume route is the
1933
1933
  only agent route an agent's token reaches.
1934
1934
 
1935
+ `agent_import` (AG-17.1) brings in a conversation started outside Den as an
1936
+ agent: with no `session` it lists them, with `session` and `persona` it
1937
+ brings one in (see [Bring in a conversation](#bring-in-a-conversation)). It
1938
+ is off unless `mcp.actions` names it, and a scoped server reaches its own
1939
+ workspace or a granted one. Without it, an agent's token gets 403 on both
1940
+ the list and the import.
1941
+
1935
1942
  ### Guards
1936
1943
 
1937
1944
  - **Lifecycle only, local only.** The service tools run a manifest's `up`,
@@ -2042,6 +2049,8 @@ server scoped to its workspace.
2042
2049
  <cli> agents list -w <ws> [--json]
2043
2050
  <cli> agents stop <id> [-w <ws>]
2044
2051
  <cli> agents resume <id> [-w <ws>]
2052
+ <cli> agents import -w <ws> [--runtime <r>] [--json] # conversations to bring in
2053
+ <cli> agents import -w <ws> --session <id> --persona <p> # bring one in
2045
2054
  <cli> agents personas [--json]
2046
2055
  <cli> agents doctor [-w <ws>] [--json] # can each runtime run here, and why not
2047
2056
  <cli> agents handback-check <file|-> # is a hand-back complete and plain (see Guardrails)
@@ -2052,12 +2061,30 @@ server scoped to its workspace.
2052
2061
  checkout dir (its `directory`, else `den-workspaces/<ws>`), capped by
2053
2062
  `agents.max_concurrent` (agents only: plain sessions never count). The id defaults to the persona's id; an id is
2054
2063
  unique in the distribution, so a second workspace's planner gets
2055
- `planner-<ws>` unless you give `--id`.
2064
+ `planner-<ws>` unless you give `--id`. A persona that already has an
2065
+ agent there, running or stopped, starts another: `planner-2`,
2066
+ `planner-3`. A stopped agent is continued by Resume or Start fresh,
2067
+ never by a new start. `--id` is exact: a running id is refused.
2056
2068
  - The **agent record**, `<stateDir>/agents/<id>.json` (0600), holds its id,
2057
- persona, runtime, model, workspace, cwd, session and times. It never holds
2058
- the environment or the command line. `list` reads it for persona, runtime
2069
+ persona, runtime, model, workspace, cwd, session and times, and what it was
2070
+ started with from the Start dialog: `version` (the model's, "latest" or
2071
+ pinned), `permission` (`ask`, `edits` or `all`), `allow` (extra allowed
2072
+ commands) and `overrides` (which of these differ from its persona). Start
2073
+ fresh and Relaunch keep them. It never holds the environment, the command
2074
+ line or a first instruction. `list` reads it for persona, runtime
2059
2075
  and model; a record whose session has gone is listed as `stopped` (after
2060
2076
  `stop`) or `ended`.
2077
+ - **Two name fields.** In the record, `sessionName` is the session's
2078
+ handle, `<dist>-<ws>:<id>` (what `sessions attach` takes); it has meant
2079
+ that since 0.4.0, and `displayName` is the name a person gave the agent.
2080
+ In `agents list --json`, `GET /api/sessions` and the start and resume
2081
+ answers (MCP `agent_resume`), `sessionTitle` is the name its session
2082
+ shows: the latest of Den's rename and the runtime's own (Claude Code's
2083
+ `/rename`, one pair of surrounding quotes dropped), absent when there is
2084
+ none. The handle there is `name` (`/api/sessions`) or `session` (the
2085
+ start and resume answers). 0.4.12 sent the name shown as `sessionName`;
2086
+ read `sessionTitle` instead. Records are unchanged, so none written
2087
+ before needs migrating.
2061
2088
  - `list` shows agents only: sessions with an agent record. A session from
2062
2089
  `sessions start` is not an agent; `sessions list` shows it.
2063
2090
  - `stop` sends its session TERM and marks it stopped. `resume` works only
@@ -2070,6 +2097,36 @@ server scoped to its workspace.
2070
2097
  exits non-zero, Den prints the exit code and its last lines (at most 10,
2071
2098
  secret-shaped values redacted) and exits 1.
2072
2099
 
2100
+ #### Bring in a conversation
2101
+
2102
+ A conversation you started in a terminal outside Den (Claude Code, in the
2103
+ workspace's folder, a folder inside it, or a folder of one of its repos,
2104
+ a repo added by path outside it too) can become a Den agent. Agents ›
2105
+ **Bring in** lists them, newest first, with the persona list; `agents
2106
+ import -w <ws>` lists them too.
2107
+
2108
+ - Den reads the runtime's own history: Claude Code's
2109
+ `~/.claude/projects/<folder>/<id>.jsonl` (or under `CLAUDE_CONFIG_DIR`).
2110
+ It reads only the first and last 64 KB of each file, for the folder it
2111
+ ran in, its latest `/rename` and its first prompt. It never reads a whole
2112
+ transcript, and it lists at most 50.
2113
+ - Bringing one in runs the runtime's resume (`claude --resume <id>`) in the
2114
+ folder it ran in, as a new agent with the persona you pick. From then on
2115
+ Den's token, MCP config, hooks, guards and audit trail apply. It is an
2116
+ agent like any other: stop, resume, rename. The record notes
2117
+ `broughtInAt`.
2118
+ - **One writer only.** A conversation written in the last minute is taken
2119
+ to be still open in another terminal: "Still open in another terminal.
2120
+ Close it there first" (HTTP 409 `open_elsewhere`). A conversation an
2121
+ agent already continues is refused too (409 `already_agent`).
2122
+ - The agent's id is the persona's, or `<persona>-2`, `-3`… when that is
2123
+ taken; `--id` sets one. An existing agent is never overwritten.
2124
+ - Only den-claude can bring one in for now. Other runtimes say "<runtime>
2125
+ can't bring in a conversation yet".
2126
+ - Routes: `GET /api/workspaces/<ws>/conversations[?runtime=<r>]` and `POST
2127
+ /api/workspaces/<ws>/conversations/<id>/import` `{ persona, runtime?, id?
2128
+ }`. A person's only, unless MCP `agent_import` is opted in.
2129
+
2073
2130
  ### On the Workspaces page
2074
2131
 
2075
2132
  The selected workspace's agents are listed under its repo table, one row
@@ -2104,13 +2161,78 @@ started. The workspace header counts them ("2 agents").
2104
2161
  workspace, and **Open** on a row with a session opens its terminal there.
2105
2162
 
2106
2163
  The routes: `GET /api/workspaces/<ws>/agents`, `POST
2107
- /api/workspaces/<ws>/agents` (`{ persona, runtime?, model?, id? }`), `POST
2108
- /api/workspaces/<ws>/agents/<id>/stop` and `…/resume`, and `GET
2109
- /api/personas` (personas and runtimes). Errors are the usual
2164
+ /api/workspaces/<ws>/agents` (`{ persona, runtime?, model?, version?,
2165
+ permission?, allow?, instruction?, id? }`, see
2166
+ [The Start dialog](#the-start-dialog)), `POST
2167
+ /api/workspaces/<ws>/agents/<id>/stop` and `…/resume`, `POST
2168
+ /api/workspaces/<ws>/sessions` (a plain session), `GET /api/personas`
2169
+ (personas, runtimes with their models and permission translation, roles
2170
+ and categories), and the persona routes under
2171
+ [Personas](#personas). Errors are the usual
2110
2172
  `{ ok: false, error, code, requestId }`: `cap` (429),
2111
2173
  `conflict` (409, e.g. already running, or no resume), `not_found` (404),
2112
2174
  `exited_at_once` (502, with the session's last lines).
2113
2175
 
2176
+ ### The Start dialog
2177
+
2178
+ **+ Start agent** on the Agents tab (or `/agents?start=1`) opens the Start
2179
+ dialog:
2180
+
2181
+ - **Persona**: a list you can search (name, role, description), with
2182
+ category chips (only the categories that have personas) and source chips
2183
+ (built-in, distribution, mine). With no filter set it is grouped by
2184
+ category. Each row is the persona's name ("Rita (reviewer)", else its
2185
+ id), its source badge and its one-line description, and "not installed"
2186
+ when its runtime isn't. **Plain session** is pinned last: your login
2187
+ shell in the workspace's folder, no agent. **What's a persona?** explains
2188
+ the idea; **Details** shows the selected persona's instructions, runtime,
2189
+ model and version, permission mode, role preset and extra commands.
2190
+ **+ New persona**, **Duplicate** and (for your own) **Edit** open the
2191
+ persona editor, and the dialog picks what you saved.
2192
+ - **Runtime** and **Workspace**. Installed runtimes come first; the rest
2193
+ are listed, disabled, and named under the field ("Not found on this
2194
+ machine: …"). A persona whose runtime isn't installed starts on the first
2195
+ one that is, and the dialog says so. The line under the runtime says what
2196
+ will run (see below).
2197
+ - **First instruction** (optional, up to 8000 characters): the agent's
2198
+ first message. Den types it into the agent's session once the session is
2199
+ ready (it has printed and gone quiet, or after 30 s), through the session
2200
+ host, as a bracketed paste when the runtime asked for one, then Enter. It
2201
+ is never a command-line argument and never stored; the audit log records
2202
+ its length only.
2203
+ - **Advanced** (collapsed): **Model** and **Version** (the runtime's own
2204
+ list; "Persona default" first), the **Permission mode** (Ask for
2205
+ everything, Auto-approve edits in the worktree, Auto-approve all), the
2206
+ role's command preset as chips, **Extra allowed commands** (plain command
2207
+ prefixes, one per line, no patterns), and a preview of exactly what the
2208
+ runtime will be given. A command a runtime can't take says "not supported
2209
+ on <runtime>", and a pattern says "use a plain prefix"; neither is ever
2210
+ dropped silently. "Edit raw runtime config…" is not there yet.
2211
+
2212
+ What you change in Advanced applies to that launch only, and the session's
2213
+ row is tagged: "model: haiku", "pinned claude-opus-4-8", "auto-approve
2214
+ edits", "custom tools", the runtime, and always "auto-approve all" for an
2215
+ agent started so. An agent pinned to an older version says "newer
2216
+ available".
2217
+
2218
+ Every field is checked on the server, not only in the page. The model and
2219
+ version must be ones the runtime lists, the permission one of `ask`,
2220
+ `edits` or `all`, and `allow` a list of at most 32 plain prefixes (letters,
2221
+ digits, single spaces and `. _ / : = @ % + , -`, at most 120 characters
2222
+ each). An unknown field is refused. A person's start only: an agent's
2223
+ token gets 403.
2224
+
2225
+ **How each runtime takes the choices.** den-claude (Claude Code): a model is
2226
+ `--model <alias>` (`opus`, `sonnet`, `haiku`), a pinned version is `--model
2227
+ <full id>`. The model list is a catalog shipped with each Den release,
2228
+ because `claude` can't list its models. The permission mode is
2229
+ `--permission-mode` (`default`, `acceptEdits`, `bypassPermissions`), and
2230
+ each command prefix becomes two allow rules, `Bash(<prefix>)` and
2231
+ `Bash(<prefix> *)`, in the agent's settings file beside Den's deny rules
2232
+ (deny wins). Codex CLI, Gemini CLI, Grok Build and generic take no model,
2233
+ mode or commands from Den yet: the dialog says "not supported on <runtime>"
2234
+ and the start is refused if you set one.
2235
+
2114
2236
  ### The Agents tab
2115
2237
 
2116
2238
  "Agents" in the rail (Develop, after Graph) is `/agents`: every session and
@@ -2181,7 +2303,10 @@ agent of the workspaces in view, and their terminals in the browser.
2181
2303
  pane header adds ` · <name>` after the runtime, and the tab, the list and
2182
2304
  ⌘K add it too, when it is not empty and says more than the agent's own
2183
2305
  name or persona. `GET /api/sessions`, `agents list --json` and the start
2184
- and resume answers (MCP `agent_resume`) carry it as `sessionName`.
2306
+ and resume answers (MCP `agent_resume`) carry it as `sessionTitle`
2307
+ (0.4.12: `sessionName`, which is the record's session handle). A
2308
+ `/rename "api spike"` shows as api spike: one pair of quotes around the
2309
+ whole name is dropped, for display only.
2185
2310
  Codex CLI, Gemini CLI and Grok Build have no name of their own yet. A
2186
2311
  catalog entry's `titleFromOsc: true` marks a runtime whose terminal
2187
2312
  title (OSC 0/2) names the session; no built-in runtime sets it, and the
@@ -2386,13 +2511,18 @@ a Claude Code agent file, read as it is, plus a few keys of Den's own:
2386
2511
  ```markdown
2387
2512
  ---
2388
2513
  name: planner # the id (or `id:`; default: the file name)
2389
- description: Writes stories and their acceptance criteria. # or `role:`
2514
+ display_name: Rita # optional; shown as "Rita (reviewer)"
2515
+ role: planner # a role (see Roles); a sentence here is the description
2516
+ category: engineering # see Categories; default: the role's
2517
+ description: Writes stories and their acceptance criteria. # one line
2390
2518
  model: some-model # optional; `inherit` means none
2519
+ version: latest # or a pinned version of the model
2520
+ allowed_commands: [npm test] # extra plain prefixes allowed without asking
2391
2521
  tools: Read, Grep # hints for the runtime; Den restricts nothing with them
2392
2522
  standing: true # starts with its workspace (later slices)
2393
2523
  context: [docs/specs, the design system] # what to read first
2394
2524
  runtime: generic # default den-claude
2395
- permission_mode: plan # den-claude only; default `default`
2525
+ permission_mode: ask # ask, edits or all (Claude Code's own modes still read)
2396
2526
  den_hooks: false # Den's guardrail hooks for this persona (see Guardrails)
2397
2527
  den_instructions: false # Den's shared instructions for this persona
2398
2528
  argv: ["some-cli", "--model", "{model}", "--mcp-config", "{mcp_config}"]
@@ -2402,8 +2532,9 @@ You are the planner. …
2402
2532
  ```
2403
2533
 
2404
2534
  Den ships a default pack: `planner` and `orchestrator` (standing), `fe-dev`,
2405
- `be-dev`, `devops`, `reviewer` and `ux-designer`. Add your own packs, read in
2406
- order after Den's; a persona with the same id replaces the earlier one:
2535
+ `be-dev` and `devops` (role `sde`), `reviewer`, `tester` and `ux-designer`
2536
+ (role `designer`, category Design). Add your own packs, read in order after
2537
+ Den's; a persona with the same id replaces the earlier one:
2407
2538
 
2408
2539
  ```yaml
2409
2540
  agents:
@@ -2416,6 +2547,53 @@ used without converting them. Files without front matter (a README) are
2416
2547
  skipped; two files with one id in a pack, or a pack that isn't a directory,
2417
2548
  are errors naming the file or the key.
2418
2549
 
2550
+ **Your own personas** live in `<stateDir>/personas/<id>.md` (0600), in the
2551
+ same format, read last: one wins over a pack's persona of the same id.
2552
+ Settings › Personas lists every persona with the Start dialog's search and
2553
+ chips: **View** (or **Edit** for your own), **Duplicate**, **Delete** (your
2554
+ own only) and **+ New persona**. A built-in or distribution persona is
2555
+ read-only; Duplicate makes your own copy to edit. "newer available" marks a
2556
+ persona pinned to an older version, with **Use latest** for your own. The
2557
+ routes: `GET /api/personas/<id>` (with its instructions), `POST
2558
+ /api/personas` (new), `POST /api/personas/<id>` (edit; 409 `read_only` for
2559
+ one that isn't yours) and `DELETE /api/personas/<id>`. Each field is
2560
+ checked: the role, category, runtime, model and version must be registered,
2561
+ the description one line of at most 200 characters, the name at most 40,
2562
+ the instructions at most 20000 characters with no control characters but
2563
+ newlines and tabs. An agent's token can't create, change or delete a
2564
+ persona (403); a person sets what agents may do.
2565
+
2566
+ **Roles.** A role is a template and a key: default instructions, a
2567
+ permission mode and a command preset (read-only commands, allowed without
2568
+ asking). Den's roles are `planner`, `orchestrator`, `sde`, `reviewer`,
2569
+ `tester` and `designer`. Picking a role in New persona fills the form in,
2570
+ never over text you typed; a role adds nothing hidden to an agent's prompt.
2571
+ A distribution adds roles, and may extend a Den role's preset but not
2572
+ redefine it:
2573
+
2574
+ ```yaml
2575
+ agents:
2576
+ roles:
2577
+ copywriter:
2578
+ description: Drafts release notes and site copy.
2579
+ instructions: Draft copy in the house voice. Leave drafts for review.
2580
+ mode: ask # ask, edits or all
2581
+ preset: [vale]
2582
+ category: marketing
2583
+ reviewer:
2584
+ preset: [semgrep] # added to Den's preset
2585
+ ```
2586
+
2587
+ **Categories** group personas in the Start list and Settings › Personas.
2588
+ Den's are Engineering, Design, Product, Marketing and Operations; a
2589
+ distribution adds more:
2590
+
2591
+ ```yaml
2592
+ agents:
2593
+ categories:
2594
+ - { id: legal, label: Legal }
2595
+ ```
2596
+
2419
2597
  ### Guardrails: hooks, shared instructions, hand-backs
2420
2598
 
2421
2599
  Every persona in Den's default pack gets two things with no setup: Den's
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monster-orange/den",
3
- "version": "0.4.12",
3
+ "version": "0.4.14",
4
4
  "description": "Den: a local multi-repo dev orchestrator, HTTPS edge and E2E harness",
5
5
  "type": "module",
6
6
  "bin": {