@monster-orange/den 0.4.18 → 0.4.19
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/CHANGELOG.md +134 -0
- package/README.md +14 -13
- package/docs/distributions.md +99 -24
- package/docs/reference.md +1 -1
- package/package.json +2 -1
- package/skills/install-den/SKILL.md +35 -75
- package/src/shared/agents/den-claude.ts +40 -6
- package/src/shared/agents/guardrails/stop-hook.ts +30 -4
- package/src/shared/agents/guardrails.ts +40 -4
- package/src/shared/agents/handback.ts +22 -4
- package/src/shared/agents/personas.ts +32 -5
- package/src/shared/agents/runtime.ts +8 -0
- package/src/shared/agents/server-agent.ts +57 -0
- package/src/shared/agents/server-pack/server.md +45 -0
- package/src/shared/environment-manager/workspaces.ts +4 -0
- package/src/ui/cli/agent-ops.ts +41 -6
- package/src/ui/cli/create.ts +2 -2
- package/src/ui/cli/index.ts +1 -1
- package/src/ui/cli/repo-command.ts +8 -1
- package/src/ui/cli/repo-detect.ts +58 -0
- package/src/ui/cli/server-agent-ops.ts +411 -0
- package/src/ui/mcp/server.ts +29 -12
- package/src/ui/mcp/tools.ts +4 -2
- package/src/ui/server/agent-routes.ts +1 -1
- package/src/ui/server/held-actions.ts +35 -7
- package/src/ui/server/index.ts +20 -5
- package/src/ui/server/public/agents-page.js +10 -1
- package/src/ui/server/public/error-page.js +39 -1
- package/src/ui/server/public/graph.css +21 -0
- package/src/ui/server/public/graph.js +49 -6
- package/src/ui/server/public/header.js +29 -7
- package/src/ui/server/public/i18n/es.js +37 -0
- package/src/ui/server/public/i18n/ja.js +39 -0
- package/src/ui/server/public/local-dev.html +22 -1
- package/src/ui/server/public/persona-ui.css +6 -0
- package/src/ui/server/public/server-agent-page.js +415 -0
- package/src/ui/server/public/server-agent.html +222 -0
- package/src/ui/server/public/shell.js +66 -6
- package/src/ui/server/public/svc-panel.js +27 -14
- package/src/ui/server/public/topbar.js +13 -1
- package/src/ui/server/route-classes.ts +21 -0
- package/src/ui/server/server-agent-routes.ts +176 -0
- package/src/ui/server/session-routes.ts +12 -1
- package/src/ui/server/ui-assets.ts +2 -0
- package/src/ui/server/workspace-routes.ts +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,140 @@ 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.19] - 2026-11-08
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **The server agent (ON-6).** Every Den has its own agent, named after the
|
|
12
|
+
distribution ("Acme agent"), for anything about the server itself: set it
|
|
13
|
+
up, add a repo, fix a failing service, change a setting, explain what's
|
|
14
|
+
running. It belongs to no workspace. It is a normal Den agent underneath
|
|
15
|
+
(record, session, Resume, rotation, hooks), with Den's persona `server`
|
|
16
|
+
and the plain-writing rule, in a reserved scope, `den-server`.
|
|
17
|
+
- It acts only through Den's MCP, which serves it the whole Den. Each
|
|
18
|
+
write (`workspace_create`, `repo_add`, `service_try`) is held for the
|
|
19
|
+
person's Allow, so it only reads until they allow one. It starts in an
|
|
20
|
+
empty folder of its own (`<state_dir>/server-agent`).
|
|
21
|
+
- A fresh Den's first page (`/`, while no workspace has a repo) is that
|
|
22
|
+
agent in a terminal framed as the page, with Open in Agents. With an
|
|
23
|
+
installed runtime that carries Den's tools, it starts by itself, with
|
|
24
|
+
"Let's set up <name>. Where are your repos?", with the folder above the
|
|
25
|
+
Den's as the default, in its first turn. With none, the page shows how
|
|
26
|
+
to install one and the manual path for this Den, from its folder:
|
|
27
|
+
`cd <dir>` → `./bin/<cli> repo add <path>` → `./bin/<cli> up`.
|
|
28
|
+
- After setup it is in the rail (`/server-agent`), ⌘K has "Ask <name>",
|
|
29
|
+
and Agents lists it first, under "Server".
|
|
30
|
+
- Its runtime: the page's Runs on picker (`agents.server_runtime` in
|
|
31
|
+
`config/local/user.yml`), else the first installed one with Den's tools.
|
|
32
|
+
- Its model: the page's Model picker beside it (`agents.server_model`),
|
|
33
|
+
with only the runtime's own models, else Sonnet when the runtime has it.
|
|
34
|
+
A new model takes effect at the next start (a fresh conversation).
|
|
35
|
+
- Den's own MCP tools run without Claude Code's own prompt, for this
|
|
36
|
+
agent only (`mcp__<server>` in its settings file's `permissions.allow`).
|
|
37
|
+
Reads just run; each write still waits for the person's Allow in the
|
|
38
|
+
browser, so it asks once. The org's immediate actions (`mcp.actions`)
|
|
39
|
+
still ask in the terminal (`permissions.ask`). Workspace agents are
|
|
40
|
+
unchanged.
|
|
41
|
+
- On a fresh Den, one line above its terminal: "Claude asks whether to
|
|
42
|
+
trust this folder. Choose Yes." Den doesn't answer Claude's folder-trust
|
|
43
|
+
prompt for the person.
|
|
44
|
+
- `GET /api/server-agent`, `POST /api/server-agent/start`,
|
|
45
|
+
`POST /api/server-agent/runtime` and `POST /api/server-agent/model`.
|
|
46
|
+
Only a person starts it or picks its runtime or model: an agent's token
|
|
47
|
+
or claim gets 403.
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- **The install-den skill does three things only (ON-1, slimmed).** It
|
|
52
|
+
installs Den after checking Node and git, helps pick its name and folder
|
|
53
|
+
(default `~/<name>`), then runs `web up` and hands over the one-time link
|
|
54
|
+
from `web claim-link`: "Den's own agent takes it from there." It no
|
|
55
|
+
longer adds repos, starts services or connects itself to Den's MCP.
|
|
56
|
+
- **`npx @monster-orange/den@latest create`.** The skill, the README, the
|
|
57
|
+
docs, `create`'s own `fix` lines and `--help` name `@latest`. A bare name
|
|
58
|
+
could reuse an older Den cached in `~/.npm/_npx`.
|
|
59
|
+
- **workspace_create makes the workspace active.** On the person's Allow,
|
|
60
|
+
the MCP's `workspace_create` creates the workspace and activates it, so
|
|
61
|
+
`service_try` can start its services. `service_try` on a workspace that
|
|
62
|
+
isn't active says so in the browser ("Start <service> (this activates
|
|
63
|
+
<workspace>)") and does both on the one Allow. Before, the server agent
|
|
64
|
+
was refused with "Workspace is not active", and nothing it could call
|
|
65
|
+
activated one. `<cli> workspace create` is unchanged.
|
|
66
|
+
- **The drafted manifest has a health URL when the dev server's port is
|
|
67
|
+
known.** `manifest_draft` and `repo add` draft
|
|
68
|
+
`health: { local: { url: http://localhost:<port>/ } }` when the start
|
|
69
|
+
script names a port (`--port`, `-p`, `PORT=`) or runs a dev server with a
|
|
70
|
+
fixed default (Vite 5173, Next 3000, Angular 4200, and a few
|
|
71
|
+
more). So the service gets a health check and Visit ↗. `--health` still
|
|
72
|
+
wins. With no port, nothing is guessed.
|
|
73
|
+
- **The ON-4 dry run follows the two agents:** install, the setup link, the
|
|
74
|
+
fresh first page, then the server agent's MCP calls, with `repo_add` and
|
|
75
|
+
`service_try` each allowed from the signed-in browser. It now asserts 5
|
|
76
|
+
minutes or less.
|
|
77
|
+
- **An accessibility check runs with the tests.** axe-core (WCAG 2.0 and
|
|
78
|
+
2.1 A and AA, plus best practice) scans the rail, an open pinned-service
|
|
79
|
+
panel, the Start agent dialog and the server agent's page, in light and
|
|
80
|
+
dark, at 1440×900 and 390×844. Any violation fails it.
|
|
81
|
+
|
|
82
|
+
### Fixed
|
|
83
|
+
|
|
84
|
+
- **No Stop hook error at the end of setup.** The server agent was given the build agents' hand-back template, so
|
|
85
|
+
after the service came up it wrote a hand-back, and Den's Stop hook sent it back because a decision didn't end in
|
|
86
|
+
"?". The person saw "Stop hook error" and waited a turn. The server agent now has no hand-back template, and its
|
|
87
|
+
Stop hook skips the hand-back check. It still asks it to explain every ID, and session rotation is unchanged.
|
|
88
|
+
|
|
89
|
+
- **The Stop hook no longer flags Den's own name.** A Den whose name looks
|
|
90
|
+
like an ID (`t2` → "T2") had the server agent's first greeting rejected
|
|
91
|
+
("'T2' is not explained"), and the person saw "Stop hook error". Den now
|
|
92
|
+
tells the hook the ID-shaped words in its own title and the workspace's
|
|
93
|
+
name (`--known`), and it never flags those. Any other bare ID is still
|
|
94
|
+
flagged.
|
|
95
|
+
- **No What's new over a brand-new Den.** On a fresh Den (no repo in any
|
|
96
|
+
workspace yet, the server agent page's `fresh`) the release notes no
|
|
97
|
+
longer open by themselves over the agent and the approvals. That version
|
|
98
|
+
counts as seen. `/api/server-info` has `fresh`.
|
|
99
|
+
- **The "log in here" line shows on every fresh run.** The server agent
|
|
100
|
+
page chose the line from the runtime picker's runtime, which can read
|
|
101
|
+
none (or another one) while the agent runs. It now uses the runtime the
|
|
102
|
+
agent runs on (`runningRuntime`, from its record). And a start that isn't
|
|
103
|
+
running yet when the page reads it back is read again, a second apart, so
|
|
104
|
+
the terminal and its lines come up without a reload.
|
|
105
|
+
- **The Graph's empty View says where a service is.** With the View on a
|
|
106
|
+
workspace with no services (right after onboarding), Open in Graph for
|
|
107
|
+
a service in another workspace showed "No services in workspace" only.
|
|
108
|
+
It now also says "<service> is in <workspace>, outside this View." with
|
|
109
|
+
Show <workspace>, the same line as over a drawn graph.
|
|
110
|
+
- **Open Terminal on Windows.** On the signed-out page it did nothing on Windows. Windows has no `ssh://` app by default, so
|
|
111
|
+
there the link is gone and the ssh command is the step: "Open Windows Terminal or PowerShell, paste this, and press
|
|
112
|
+
Enter." Elsewhere, if the page still has focus 2 seconds after the click, it says "Nothing opened? Copy the command
|
|
113
|
+
below and paste it into your terminal app." The command and its copy button always show.
|
|
114
|
+
|
|
115
|
+
- **No "down" flash after Start.** Starting a dev server from the
|
|
116
|
+
pinned-service panel showed "starting…", then "down: fetch failed" for
|
|
117
|
+
a second or two, then up. The server's ready event ended "starting…",
|
|
118
|
+
and the header's next health paint still held the service's down result
|
|
119
|
+
from before Start. Now, while a Start or Restart is in flight, a down
|
|
120
|
+
reads "starting…" until the first up or the 120 s timeout. The ready
|
|
121
|
+
event ends it only when health already says up.
|
|
122
|
+
- **Open in Graph says when a service is outside the View.** With the View
|
|
123
|
+
on one workspace, Open in Graph for a service in another landed on a
|
|
124
|
+
Graph without its card. Now the Graph says "<service> is in
|
|
125
|
+
<workspace>, outside this View." with a Show <workspace> button. The
|
|
126
|
+
button switches the View the way the top bar does, then focuses the
|
|
127
|
+
card. The View never switches by itself.
|
|
128
|
+
- **The phone drawer keeps the rail a nav.** Under 720 px, ☰ made the
|
|
129
|
+
rail's `<nav>` itself a dialog, which a nav may not be. The dialog is
|
|
130
|
+
now a box around the rail ("Pages"); focus, Tab, Esc and the scrim work
|
|
131
|
+
as before.
|
|
132
|
+
- **The chosen persona's role and tag are readable.** On the chosen row's
|
|
133
|
+
tint, in light, they were 4.49:1, under 4.5:1. They read in the muted
|
|
134
|
+
colour there now.
|
|
135
|
+
|
|
136
|
+
### Migrations
|
|
137
|
+
|
|
138
|
+
- No workspace may be named `den-server`: creating one is refused. Rename a
|
|
139
|
+
workspace with that name before moving to 0.4.19.
|
|
140
|
+
|
|
7
141
|
## [0.4.18] - 2026-11-08
|
|
8
142
|
|
|
9
143
|
### 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.
|
|
14
|
-
<img src="docs/images/0.4.
|
|
13
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/images/0.4.19/hero-dark.png">
|
|
14
|
+
<img src="docs/images/0.4.19/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
|
|
@@ -22,11 +22,12 @@ Paste this line into your coding agent (Claude Code, Codex, Gemini, Grok, …):
|
|
|
22
22
|
Set up Den for me by following https://raw.githubusercontent.com/Monster-Orange/den/main/skills/install-den/SKILL.md
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
The agent follows the [install-den skill](skills/install-den/SKILL.md). It
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
The agent follows the [install-den skill](skills/install-den/SKILL.md). It checks Node and git, installs Den,
|
|
26
|
+
asks you its name and folder, starts it, and hands you a one-time link. Open it: your Den's own agent takes it
|
|
27
|
+
from there. That agent finds your repos, adds them without changing them and starts one, and each change waits
|
|
28
|
+
for you to allow it in the browser. Neither agent asks for a password in chat, edits your repos or sends anything
|
|
29
|
+
off your machine. Every step answers in JSON and is safe to re-run: see
|
|
30
|
+
[Set up by your agent](docs/distributions.md#set-up-by-your-agent) and [The server agent](docs/distributions.md#the-server-agent).
|
|
30
31
|
|
|
31
32
|
## What Den is
|
|
32
33
|
|
|
@@ -38,7 +39,7 @@ It doesn't replace your tools. Your repos, Docker, your test runners, your secre
|
|
|
38
39
|
yours. Den connects them and turns on good practice from the start.
|
|
39
40
|
|
|
40
41
|
<p align="center">
|
|
41
|
-
<img src="docs/images/0.4.
|
|
42
|
+
<img src="docs/images/0.4.19/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
43
|
</p>
|
|
43
44
|
|
|
44
45
|
## How it helps
|
|
@@ -68,10 +69,10 @@ yours. Den connects them and turns on good practice from the start.
|
|
|
68
69
|
lives in your own repo.
|
|
69
70
|
|
|
70
71
|
<p align="center">
|
|
71
|
-
<img src="docs/images/0.4.
|
|
72
|
-
<img src="docs/images/0.4.
|
|
73
|
-
<img src="docs/images/0.4.
|
|
74
|
-
<img src="docs/images/0.4.
|
|
72
|
+
<img src="docs/images/0.4.19/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">
|
|
73
|
+
<img src="docs/images/0.4.19/workspaces.png" width="49%" alt="The Workspaces page: the demo workspace's repos with their health, mode and Start, Stop, Restart and Logs actions">
|
|
74
|
+
<img src="docs/images/0.4.19/status-drawer.png" width="49%" alt="The status drawer: nothing needs attention, and every service in the demo workspace, by application, with its latency">
|
|
75
|
+
<img src="docs/images/0.4.19/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
76
|
</p>
|
|
76
77
|
|
|
77
78
|
## Get started
|
|
@@ -79,7 +80,7 @@ yours. Den connects them and turns on good practice from the start.
|
|
|
79
80
|
You need Node 22.13 or later, and Docker for anything that runs in containers. mkcert is only needed if you want Den to issue local HTTPS certificates.
|
|
80
81
|
|
|
81
82
|
```sh
|
|
82
|
-
npx @monster-orange/den create acme # your own Den, named after your product
|
|
83
|
+
npx @monster-orange/den@latest create acme # your own Den, named after your product
|
|
83
84
|
cd acme && npm install
|
|
84
85
|
./bin/acme register ../shop-api # add a repo (repeat for each one)
|
|
85
86
|
./bin/acme up # start everything, in order
|
package/docs/distributions.md
CHANGED
|
@@ -19,8 +19,8 @@ Den's own checkout is itself a distribution, named `den`.
|
|
|
19
19
|
## Create one
|
|
20
20
|
|
|
21
21
|
```sh
|
|
22
|
-
npx @monster-orange/den create acme # writes ./acme
|
|
23
|
-
npx @monster-orange/den create acme ~/src/acme-dev --title "Acme Dev"
|
|
22
|
+
npx @monster-orange/den@latest create acme # writes ./acme
|
|
23
|
+
npx @monster-orange/den@latest create acme ~/src/acme-dev --title "Acme Dev"
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
From a Den checkout, `./bin/den create acme ../acme` does the same.
|
|
@@ -72,26 +72,33 @@ Set up Den for me by following https://raw.githubusercontent.com/Monster-Orange/
|
|
|
72
72
|
|
|
73
73
|
That file is the install-den skill, also in the package at
|
|
74
74
|
`skills/install-den/SKILL.md`: plain Markdown any agent can follow, with
|
|
75
|
-
Claude skill front matter. `den --help` prints the line. The skill
|
|
76
|
-
|
|
75
|
+
Claude skill front matter. `den --help` prints the line. The skill does three
|
|
76
|
+
things only: it installs Den (after checking Node and git), helps the person
|
|
77
|
+
pick its name and folder (default `~/<name>`), then runs `web up` and hands
|
|
78
|
+
over the one-time link from `web claim-link`: "Den's own agent takes it from
|
|
79
|
+
there." It adds no repo and creates no workspace: that is
|
|
80
|
+
[the server agent](#the-server-agent)'s job. Every command below also stays a
|
|
81
|
+
person's own: `npm i -g @monster-orange/den` → `den create <name>` →
|
|
82
|
+
`<cli> repo add` → `<cli> up` skips both agents. The skill runs the first
|
|
83
|
+
of the commands below, and the server agent the rest through MCP. Each one takes `--json`, never prompts, and is safe to
|
|
77
84
|
re-run. With `--json`, stdout carries exactly one JSON object and the
|
|
78
85
|
command's log goes to stderr. When `ok` is false the object says why
|
|
79
86
|
(`error`) and carries either a command the agent can run (`fix`) or a
|
|
80
87
|
question for the person (`ask`, sometimes with `choices`).
|
|
81
88
|
|
|
82
|
-
| Step
|
|
83
|
-
|
|
|
84
|
-
| `npx @monster-orange/den create <name> [dir] --yes --json` | `{ ok, dir, cli, existed, files, port, portPicked?, next }` |
|
|
85
|
-
| `<cli> repo add <path\|git-url> --json`
|
|
86
|
-
| `<cli> repo detect <folder> --json`
|
|
87
|
-
| `<cli> repo add <path> --dry-run --json`
|
|
88
|
-
| `<cli> onboard status --json`
|
|
89
|
-
| `<cli> up <repo> --json`
|
|
90
|
-
| `<cli> web up --no-open --json`
|
|
91
|
-
| `<cli> doctor --json`
|
|
92
|
-
| `<cli> mcp connect --runtime <runtime> --json`
|
|
93
|
-
| `<cli> down <repo> --json`
|
|
94
|
-
| `<cli> web down --json`
|
|
89
|
+
| Step | Answers |
|
|
90
|
+
| ----------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
91
|
+
| `npx @monster-orange/den@latest create <name> [dir] --yes --json` | `{ ok, dir, cli, existed, files, port, portPicked?, next }` |
|
|
92
|
+
| `<cli> repo add <path\|git-url> --json` | `{ ok, existed, repo, workspace, mode, path, manifest, services, next }` |
|
|
93
|
+
| `<cli> repo detect <folder> --json` | `{ ok, path, repos, workspaces, truncated, skipped, rule, next }` |
|
|
94
|
+
| `<cli> repo add <path> --dry-run --json` | `{ ok, dryRun, repo, workspace, path, manifest, draft, validation, next }` |
|
|
95
|
+
| `<cli> onboard status --json` | `{ ok, checks: [{ id, status, detail, fix?, ask? }], next }` |
|
|
96
|
+
| `<cli> up <repo> --json` | `{ ok, workspace, services: [{ address, result, health, detail? }], next }` |
|
|
97
|
+
| `<cli> web up --no-open --json` | `{ ok, url, port, version? }` |
|
|
98
|
+
| `<cli> doctor --json` | `{ ok, checks: [{ id, status, detail, url?, port?, fix?, ask? }] }` |
|
|
99
|
+
| `<cli> mcp connect --runtime <runtime> --json` | `{ ok, server, clients: [{ id, ok, said, file?, changed? }], restart, web }` |
|
|
100
|
+
| `<cli> down <repo> --json` | `{ ok, workspace, services, all? }` |
|
|
101
|
+
| `<cli> web down --json` | `{ ok, url, port, running, stopped }` |
|
|
95
102
|
|
|
96
103
|
### repo add
|
|
97
104
|
|
|
@@ -119,7 +126,12 @@ question for the person (`ask`, sometimes with `choices`).
|
|
|
119
126
|
the answer has `ask` and `choices`, nothing is written, and a re-run names
|
|
120
127
|
the command with `--run "<cmd>"`. A Makefile `test` target or a
|
|
121
128
|
`package.json` `test` script becomes the repo's `tests.unit`.
|
|
122
|
-
`--health <url>` adds an HTTP health check.
|
|
129
|
+
`--health <url>` adds an HTTP health check. Without it, when the start
|
|
130
|
+
script names a port (`--port`, `-p`, `PORT=`) or runs a dev server with a
|
|
131
|
+
fixed default port (Vite 5173, Next 3000, Angular 4200,
|
|
132
|
+
Gatsby 8000, webpack-dev-server 8080), the side-car gets
|
|
133
|
+
`http://localhost:<port>/` as its health URL, so the service has Visit ↗.
|
|
134
|
+
No port: no health URL is guessed.
|
|
123
135
|
- The workspace is `-w <workspace>` (made and activated if it doesn't exist),
|
|
124
136
|
else the focused one, else a new `default` workspace.
|
|
125
137
|
- The same repo again answers `ok` with `existed: true`. A different repo
|
|
@@ -184,11 +196,11 @@ token (an MCP server outside an agent's session, or anything else on this
|
|
|
184
196
|
machine) reads "Something on this machine (no agent identity) wants to:",
|
|
185
197
|
with "If you didn't ask an agent to do this, Deny." under it.
|
|
186
198
|
|
|
187
|
-
| MCP tool | What Allow runs
|
|
188
|
-
| ------------------ |
|
|
189
|
-
| `workspace_create` | The Workspaces page's create: an empty workspace
|
|
190
|
-
| `repo_add` | `repo add <path> --json`, a local folder inside home
|
|
191
|
-
| `service_try` | `up` for one service, as the Services page's Start does |
|
|
199
|
+
| MCP tool | What Allow runs |
|
|
200
|
+
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
201
|
+
| `workspace_create` | The Workspaces page's create: an empty workspace, made active |
|
|
202
|
+
| `repo_add` | `repo add <path> --json`, a local folder inside home |
|
|
203
|
+
| `service_try` | `up` for one service, as the Services page's Start does; an inactive workspace is activated first ("Start <service> (this activates <workspace>)") |
|
|
192
204
|
|
|
193
205
|
- **Den writes the dialog.** Its line and its Review come from the action
|
|
194
206
|
and its arguments, never from the agent. `repo_add`'s Review is its dry
|
|
@@ -1609,7 +1621,12 @@ user, and the CLI does that for you:
|
|
|
1609
1621
|
the 10 minutes, and an expired code is a click away from a new one.
|
|
1610
1622
|
From a computer with SSH access to it, the page gives the one-liner
|
|
1611
1623
|
(`ssh <host> '<cli> web approve <code>'`) and, when the host is a name,
|
|
1612
|
-
an Open Terminal (`ssh://`) link
|
|
1624
|
+
an Open Terminal (`ssh://`) link. On Windows, which has no `ssh://`
|
|
1625
|
+
app by default, there is no link: the one-liner is the step, with
|
|
1626
|
+
"Open Windows Terminal or PowerShell, paste this, and press Enter."
|
|
1627
|
+
Elsewhere, if the page still has focus 2 seconds after a click on Open
|
|
1628
|
+
Terminal (no app took the link), it says "Nothing opened? Copy the
|
|
1629
|
+
command below and paste it into your terminal app.";
|
|
1613
1630
|
- **Other ways**, collapsed: the one-time link with
|
|
1614
1631
|
`web login --origin`.
|
|
1615
1632
|
|
|
@@ -2261,6 +2278,64 @@ start` and `<cli> doctor` say why den-pty is unavailable.
|
|
|
2261
2278
|
limit) is refused with that reason; point `<PREFIX>_HOME` somewhere
|
|
2262
2279
|
shorter.
|
|
2263
2280
|
|
|
2281
|
+
## The server agent
|
|
2282
|
+
|
|
2283
|
+
Every Den has its own agent, named after the distribution ("Acme agent"),
|
|
2284
|
+
for anything about the server itself: set it up, add a repo, fix a failing
|
|
2285
|
+
service, change a setting, explain what's running. It belongs to no
|
|
2286
|
+
workspace. It is a normal Den agent underneath (its record, its session,
|
|
2287
|
+
Resume after a restart, rotation and Den's hooks), with Den's persona
|
|
2288
|
+
`server` and the plain-writing rule, in a reserved scope, `den-server`: no
|
|
2289
|
+
workspace may take that name.
|
|
2290
|
+
|
|
2291
|
+
- **It acts only through Den's MCP.** Its MCP server
|
|
2292
|
+
(`<cli> mcp --workspace den-server --actor agent:server`) serves the whole
|
|
2293
|
+
Den, not one workspace, so it may use the onboarding tools a workspace's
|
|
2294
|
+
agent is refused. Every write (`workspace_create`, `repo_add`,
|
|
2295
|
+
`service_try`) is [held for the person](#onboarding-writes-held-for-the-person):
|
|
2296
|
+
until they allow one in the browser, it only reads. It starts in an empty
|
|
2297
|
+
folder of its own (`<state_dir>/server-agent`), with no checkout to edit,
|
|
2298
|
+
and its runtime asks before every command (`permission_mode: ask`).
|
|
2299
|
+
Den's own MCP tools are the exception, for this agent only: its settings
|
|
2300
|
+
file allows `mcp__<server>` (the `--mcp-config` server), so reads just
|
|
2301
|
+
run and each write asks once, in the browser. The org's immediate actions
|
|
2302
|
+
(`mcp.actions`) stay in `permissions.ask`. On a fresh Den the page says
|
|
2303
|
+
above its terminal: "Claude asks whether to trust this folder. Choose
|
|
2304
|
+
Yes." Den doesn't answer that prompt for the person.
|
|
2305
|
+
- **Where it lives.** On a fresh Den (no repo in any workspace yet), the
|
|
2306
|
+
first page, `/`, is that agent in a terminal framed as the page, with
|
|
2307
|
+
Open in Agents as the way out. After setup it is one click away in the
|
|
2308
|
+
rail ("Acme agent", `/server-agent`), and ⌘K has "Ask Acme". Agents lists
|
|
2309
|
+
it first, under "Server", not under a workspace.
|
|
2310
|
+
- **Its onboarding:** `onboard_status`, then "Let's set up Acme. Where are
|
|
2311
|
+
your repos? I'll look in <the folder above the Den's> unless you name
|
|
2312
|
+
another folder." in its first turn, `repos_detect` and suggested workspaces, `workspace_create`,
|
|
2313
|
+
`manifest_draft` and `repo_add` for each repo, `service_try` (and
|
|
2314
|
+
`doctor` when it fails), then "Here's what's running, and three things to
|
|
2315
|
+
try next."
|
|
2316
|
+
- **What runs it.** A catalog runtime that is installed and carries Den's
|
|
2317
|
+
tools: the person's choice (`agents.server_runtime` in
|
|
2318
|
+
`config/local/user.yml`, set from the page's Runs on picker), else the
|
|
2319
|
+
first one found. Den can tell a runtime is installed, not that it is
|
|
2320
|
+
logged in: one that isn't asks in its own terminal, on the page. On a
|
|
2321
|
+
fresh Den with such a runtime it starts by itself, once per page load;
|
|
2322
|
+
after setup it starts only from its Start button. With no runtime, the
|
|
2323
|
+
page shows how to install one and the manual path for this Den, from its
|
|
2324
|
+
folder: `cd <dir>`, `./bin/<cli> repo add <path>`, `./bin/<cli> up`.
|
|
2325
|
+
- **Its model.** The page's Model picker, beside Runs on, offers the
|
|
2326
|
+
runtime's own models (`agents.server_model`). With none saved, Sonnet
|
|
2327
|
+
when the runtime has it, else the runtime's default. A new model starts
|
|
2328
|
+
a fresh conversation at the next start.
|
|
2329
|
+
- **Only a person starts it or picks its runtime or model.** An agent's token, or a
|
|
2330
|
+
request claiming to be an agent, is refused (403).
|
|
2331
|
+
|
|
2332
|
+
| Route | What it does |
|
|
2333
|
+
| -------------------------------- | --------------------------------------------------------------------------- |
|
|
2334
|
+
| `GET /api/server-agent` | Its name, runtime (or none), state, session, fresh, manual |
|
|
2335
|
+
| `POST /api/server-agent/start` | `{ runtime? }`: start it, or resume or relaunch it |
|
|
2336
|
+
| `POST /api/server-agent/runtime` | `{ runtime: id \| null }`: the person's choice of runtime |
|
|
2337
|
+
| `POST /api/server-agent/model` | `{ model: id \| null }`: the person's choice of model, one of the runtime's |
|
|
2338
|
+
|
|
2264
2339
|
## Agents
|
|
2265
2340
|
|
|
2266
2341
|
An agent is a **persona** (who) in a **workspace** (where), run by a
|
package/docs/reference.md
CHANGED
|
@@ -7,7 +7,7 @@ The technical reference that used to be the README. It will be split into separa
|
|
|
7
7
|
1. **Create** a distribution named after your product:
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
-
npx @monster-orange/den create acme # → ./acme
|
|
10
|
+
npx @monster-orange/den@latest create acme # → ./acme
|
|
11
11
|
cd acme && npm install
|
|
12
12
|
```
|
|
13
13
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monster-orange/den",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.19",
|
|
4
4
|
"description": "Den: a local multi-repo dev orchestrator, HTTPS edge and E2E harness",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -90,6 +90,7 @@
|
|
|
90
90
|
"@types/semver": "7.7.1",
|
|
91
91
|
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
92
92
|
"@typescript-eslint/parser": "^7.18.0",
|
|
93
|
+
"axe-core": "4.10.3",
|
|
93
94
|
"eslint": "^8.56.0",
|
|
94
95
|
"husky": "^8.0.3",
|
|
95
96
|
"jest": "^29.7.0",
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: install-den
|
|
3
|
-
description: Install
|
|
3
|
+
description: Install Den, Monster Orange's local dev orchestrator, and hand the person over to Den's own agent, in five minutes. Use when the person says "set up Den", "install Den", "get me started with Den", or pastes a link to this file.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Install Den
|
|
7
7
|
|
|
8
|
-
You are
|
|
9
|
-
|
|
8
|
+
You are installing Den on this person's machine. Den runs their repos locally and shows them in a browser. Your job
|
|
9
|
+
is short: install it, name it, start it, and hand over the link. **Den's own agent takes it from there.** It adds
|
|
10
|
+
their repos and starts their services, with the person allowing each change in the browser.
|
|
11
|
+
|
|
12
|
+
You do three things only. You don't add repos or create workspaces: those are Den's own agent's job. Keep your
|
|
13
|
+
messages short and plain.
|
|
10
14
|
|
|
11
15
|
## Hard rules
|
|
12
16
|
|
|
13
17
|
- **Never ask for a token, password or secret in chat.** If a step needs one, tell the person which command to run
|
|
14
18
|
themselves.
|
|
15
|
-
- **Never edit the person's repos.**
|
|
16
|
-
- **Send nothing off this machine.** No uploads, no telemetry
|
|
17
|
-
|
|
18
|
-
- **
|
|
19
|
-
own prompt (in the terminal or the browser), and the person types it there.
|
|
19
|
+
- **Never edit the person's repos.** Don't touch them at all.
|
|
20
|
+
- **Send nothing off this machine.** No uploads, no telemetry. The only download is Den from npm.
|
|
21
|
+
- **Sudo is the person's job.** Never run `sudo` yourself.
|
|
22
|
+
- **Never open the setup link yourself**, and never fetch it. It signs in one browser, once. Give it to the person.
|
|
20
23
|
- Every step below is safe to re-run. If you are unsure whether a step ran, run it again.
|
|
21
24
|
|
|
22
|
-
## 1.
|
|
25
|
+
## 1. Install Den, after checking Node and git
|
|
23
26
|
|
|
24
27
|
Run these and read the results. Don't install anything without saying so first.
|
|
25
28
|
|
|
@@ -27,88 +30,45 @@ Run these and read the results. Don't install anything without saying so first.
|
|
|
27
30
|
(for example `brew install node`, or `nvm install 22`).
|
|
28
31
|
2. `npm --version`: needs 9 or later. It comes with Node.
|
|
29
32
|
3. `git --version`: needs to be there.
|
|
30
|
-
4. `docker info`: only matters if the repo runs in containers (it has a `docker-compose.yml` or `compose.yaml`).
|
|
31
|
-
If Docker is needed and not running, ask them to start it.
|
|
32
33
|
|
|
33
34
|
If anything is missing, stop here, tell them what and how to fix it, and wait.
|
|
34
35
|
|
|
35
|
-
## 2.
|
|
36
|
-
|
|
37
|
-
Ask them together, each with a default, so the person can just say "yes":
|
|
36
|
+
## 2. Pick the folder and the name
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
2. **Which repo should we start with?** Default: the folder you're in now. A local path or a git URL.
|
|
41
|
-
3. **What should we call your Den?** Default: `den`. Lowercase letters, numbers and dashes. This also becomes the
|
|
42
|
-
command name, so `acme` gives you `./bin/acme`.
|
|
38
|
+
Ask both together, each with a default, so the person can just say "yes":
|
|
43
39
|
|
|
44
|
-
|
|
40
|
+
1. **What should we call your Den?** Default: `den`. Lowercase letters, numbers and dashes. This also becomes its
|
|
41
|
+
command, so `acme` gives you `./bin/acme`.
|
|
42
|
+
2. **Where should it live?** Default: `~/<name>`. It must be a new or empty folder.
|
|
45
43
|
|
|
46
|
-
|
|
44
|
+
Below, `<name>` is the name and `<dir>` the folder.
|
|
47
45
|
|
|
48
46
|
Every Den command below takes `--json`. It then prints one JSON object on stdout and its log on stderr. Read `ok`
|
|
49
47
|
first. When `ok` is false, the object says why (`error`) and either a command to run (`fix`) or a question for the
|
|
50
|
-
person (`ask
|
|
48
|
+
person (`ask`).
|
|
51
49
|
|
|
52
|
-
1. `npx @monster-orange/den create <name> <dir> --yes --json`. It answers `{ok, dir, cli, existed, port
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
(`portPicked`). Remember the port for the hand-back.
|
|
50
|
+
1. `npx @monster-orange/den@latest create <name> <dir> --yes --json`. It answers `{ok, dir, cli, existed, port}`. If the
|
|
51
|
+
folder already holds this Den, it answers `ok` with `existed: true` and changes nothing. When another Den already
|
|
52
|
+
uses the usual port, it picks the next free one and says so (`portPicked`).
|
|
56
53
|
2. `cd <dir> && npm install`
|
|
57
54
|
3. From here on, the Den command is `./bin/<name>`, run from `<dir>`.
|
|
58
55
|
|
|
59
|
-
##
|
|
60
|
-
|
|
61
|
-
1. `./bin/<name>
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
`./bin/<name> repo add <repo> --run "<their command>" --json`.
|
|
71
|
-
3. The answer names the repo (`repo`), the workspace it joined (`workspace`) and where its manifest is (`manifest`).
|
|
72
|
-
A workspace is Den's name for a set of repos that run together. The first one is called `default`.
|
|
73
|
-
|
|
74
|
-
## 5. Start it and check it
|
|
75
|
-
|
|
76
|
-
1. `./bin/<name> up <repo> --json`. `<repo>` is the `repo` value from step 4. Each service comes back with a
|
|
77
|
-
`result` (`started` or `already-running`) and a `health` (`ok`, or `unknown` when it has no health check).
|
|
78
|
-
2. `./bin/<name> web up --no-open --json`. This starts the browser UI, and answers `{ok, url, port}`. The MCP server
|
|
79
|
-
reads through it.
|
|
80
|
-
3. `./bin/<name> doctor --json`. Each check comes back as `ok`, `warn` or `fail`. The checks are Node, git, Docker
|
|
81
|
-
(only if a repo needs it), the web server (with its `url` and `port`) and Den's MCP. Fix every `fail` before you hand back.
|
|
82
|
-
|
|
83
|
-
## 6. Connect yourself to Den's MCP
|
|
84
|
-
|
|
85
|
-
1. `./bin/<name> mcp connect --runtime <you> --json`. `<you>` is `claude`, `codex`, `gemini` or `grok`. For any other
|
|
86
|
-
agent, `./bin/<name> mcp config` prints the JSON to add by hand.
|
|
87
|
-
2. `./bin/<name> mcp clients` shows whether you are connected.
|
|
88
|
-
3. If the answer has `restart: true`, you load the new MCP server only when you start again. Tell the person to
|
|
89
|
-
restart you once.
|
|
90
|
-
|
|
91
|
-
## 7. Hand back
|
|
92
|
-
|
|
93
|
-
Tell the person, in a few short sentences. Explain every name you use the first time (for example, "a workspace is a
|
|
94
|
-
set of repos that run together").
|
|
95
|
-
|
|
96
|
-
- **Open:** the `url` from `web up` or from the doctor's `web` check, for example `http://localhost:<port>`. Never
|
|
97
|
-
assume a port: use the one Den gave you.
|
|
98
|
-
- **What's running:** each service from `up`, and whether it's healthy.
|
|
99
|
-
- **Your Den:** where it lives (`<dir>`) and its command (`./bin/<name>`).
|
|
100
|
-
- **Decisions, if any:** as numbered yes/no questions, for example "1. Restart me now so I can use Den's tools?"
|
|
101
|
-
- **Three next things we can do together:**
|
|
102
|
-
1. Add another repo.
|
|
103
|
-
2. Look at a service's logs, or run its tests.
|
|
104
|
-
3. Start an agent session on this repo from the browser.
|
|
56
|
+
## 3. Start the web server and hand over the link
|
|
57
|
+
|
|
58
|
+
1. `./bin/<name> web up --no-open --json`. It answers `{ok, url, port}`.
|
|
59
|
+
2. `./bin/<name> web claim-link --json`. It answers `{url, expiresAt}`: a one-time setup link that signs the
|
|
60
|
+
person's browser in, so they can allow Den's agent's changes. It lasts 30 minutes and works once.
|
|
61
|
+
3. Hand over, in a few short sentences:
|
|
62
|
+
- **Open** the `url` from `claim-link`, in your browser on this machine. "Den's own agent takes it from there."
|
|
63
|
+
- **Your Den** lives in `<dir>`, and its command is `./bin/<name>`.
|
|
64
|
+
- If the link has expired, run `./bin/<name> web claim-link` yourself for a new one.
|
|
65
|
+
|
|
66
|
+
That's all. Don't go on to add repos.
|
|
105
67
|
|
|
106
68
|
## When something fails
|
|
107
69
|
|
|
108
70
|
1. Read the JSON. If it has `fix`, run that command, then re-run the step that failed.
|
|
109
|
-
2. If it has `ask`, the person has to decide or act
|
|
110
|
-
question, show any `choices` numbered, and wait.
|
|
71
|
+
2. If it has `ask`, the person has to decide or act. Ask them the question, show any `choices` numbered, and wait.
|
|
111
72
|
3. If there is neither, ask the person **one** clear question, with your best guess as the default.
|
|
112
|
-
4.
|
|
113
|
-
5. If you're stuck after two tries, stop. Tell them what you ran, what it said, and where Den writes its logs
|
|
73
|
+
4. If you're stuck after two tries, stop. Tell them what you ran, what it said, and where Den writes its logs
|
|
114
74
|
(`~/.<name>/`), so they can get help.
|