@monster-orange/den 0.4.12 → 0.4.13
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 +102 -0
- package/README.md +7 -7
- package/docs/distributions.md +146 -10
- package/package.json +1 -1
- package/src/shared/agents/default-pack/be-dev.md +1 -0
- package/src/shared/agents/default-pack/devops.md +1 -0
- package/src/shared/agents/default-pack/fe-dev.md +1 -0
- package/src/shared/agents/default-pack/orchestrator.md +3 -1
- package/src/shared/agents/default-pack/planner.md +1 -0
- package/src/shared/agents/default-pack/reviewer.md +1 -0
- package/src/shared/agents/default-pack/tester.md +16 -0
- package/src/shared/agents/default-pack/ux-designer.md +1 -0
- package/src/shared/agents/den-claude.ts +119 -13
- package/src/shared/agents/permissions.ts +108 -0
- package/src/shared/agents/persona-store.ts +286 -0
- package/src/shared/agents/personas.ts +116 -12
- package/src/shared/agents/records.ts +28 -0
- package/src/shared/agents/roles.ts +288 -0
- package/src/shared/agents/runtime.ts +41 -0
- package/src/shared/den-config.ts +20 -1
- package/src/ui/cli/agent-ops.ts +535 -17
- package/src/ui/cli/agents-command.ts +12 -2
- package/src/ui/cli/env-probe.ts +4 -1
- package/src/ui/mcp/tools.ts +1 -1
- package/src/ui/server/agent-routes.ts +260 -21
- package/src/ui/server/public/agent-start.js +3 -2
- package/src/ui/server/public/agents-page.js +499 -48
- package/src/ui/server/public/agents.html +58 -15
- package/src/ui/server/public/i18n/es.js +120 -0
- package/src/ui/server/public/i18n/ja.js +120 -0
- package/src/ui/server/public/persona-ui.css +539 -0
- package/src/ui/server/public/persona-ui.js +796 -0
- package/src/ui/server/public/settings-page.js +4 -9
- package/src/ui/server/public/settings-registry.js +22 -0
- package/src/ui/server/public/settings.html +1 -0
- package/src/ui/server/public/shell.js +117 -0
- package/src/ui/server/public/topbar.js +2 -2
- package/src/ui/server/route-classes.ts +18 -0
- package/src/ui/server/session-routes.ts +21 -5
- package/src/ui/server/ui-assets.ts +3 -0
|
@@ -148,15 +148,10 @@ export async function mountSettings(deps) {
|
|
|
148
148
|
});
|
|
149
149
|
if (!r.ok) return false;
|
|
150
150
|
const reply = await r.json().catch(() => ({}));
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
"
|
|
155
|
-
"graph",
|
|
156
|
-
"appearance",
|
|
157
|
-
"shell",
|
|
158
|
-
])
|
|
159
|
-
if (reply[k] !== undefined) ctx.data[k] = reply[k];
|
|
151
|
+
// Every setting the reply returns (0.4.13): a fixed list here left a
|
|
152
|
+
// new row's pressed button on its old value until a reload.
|
|
153
|
+
for (const [k, v] of Object.entries(reply))
|
|
154
|
+
if (k !== "ok" && v !== undefined) ctx.data[k] = v;
|
|
160
155
|
return true;
|
|
161
156
|
}
|
|
162
157
|
async function saveWorkspace(patch) {
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
*/
|
|
30
30
|
import { themeNotice, themeOptions } from "./appearance.js";
|
|
31
31
|
import { qrSvg } from "./qr.js";
|
|
32
|
+
import { renderPersonasSettings } from "./persona-ui.js";
|
|
32
33
|
|
|
33
34
|
export const DEN_SETTING_CATEGORIES = [
|
|
34
35
|
{
|
|
@@ -879,6 +880,27 @@ export const DEN_SETTINGS = [
|
|
|
879
880
|
read: () => null,
|
|
880
881
|
},
|
|
881
882
|
|
|
883
|
+
{
|
|
884
|
+
id: "agents.personas",
|
|
885
|
+
category: "agents",
|
|
886
|
+
label: "Personas",
|
|
887
|
+
description:
|
|
888
|
+
"Agent setups you can start from. Built-in ones ship with Den, distribution ones with your distribution, and yours live on this machine. View or Edit, Duplicate, + New persona; only your own can be edited or deleted.",
|
|
889
|
+
keywords: [
|
|
890
|
+
"persona",
|
|
891
|
+
"role",
|
|
892
|
+
"agent",
|
|
893
|
+
"model",
|
|
894
|
+
"version",
|
|
895
|
+
"permission",
|
|
896
|
+
"allowed commands",
|
|
897
|
+
"instructions",
|
|
898
|
+
],
|
|
899
|
+
scope: "user",
|
|
900
|
+
control: { type: "custom", render: renderPersonasSettings },
|
|
901
|
+
read: () => null,
|
|
902
|
+
},
|
|
903
|
+
|
|
882
904
|
// ── Command line ───────────────────────────────────────────────────────
|
|
883
905
|
{
|
|
884
906
|
id: "cli.local_dev",
|
|
@@ -554,6 +554,123 @@
|
|
|
554
554
|
"ag.review": "Review",
|
|
555
555
|
"ag.resumedAll": "Resumed {n} agents",
|
|
556
556
|
"ag.resumedAll.one": "Resumed {n} agent",
|
|
557
|
+
"pe.configFirst": "Fix the config first: the personas are read from it.",
|
|
558
|
+
"ag.new.title": "Start an agent",
|
|
559
|
+
"rt.missingLine": "Not found on this machine:",
|
|
560
|
+
"rt.install": "Install…",
|
|
561
|
+
// The Start dialog and personas (AG-10 to AG-13).
|
|
562
|
+
"ag.new.what": "What's a persona?",
|
|
563
|
+
"ag.new.details": "Details: {n}",
|
|
564
|
+
"ag.new.hide": "Hide details",
|
|
565
|
+
"ag.new.newP": "+ New persona",
|
|
566
|
+
"ag.new.plain": "Plain session",
|
|
567
|
+
"ag.new.plainP": "A terminal in the workspace folder. No agent.",
|
|
568
|
+
"ag.new.task": "First instruction (optional)",
|
|
569
|
+
"ag.new.taskPh":
|
|
570
|
+
"e.g. Take the empty-state story. Match the design and add a test.",
|
|
571
|
+
"ag.new.adv": "Advanced: model and permissions",
|
|
572
|
+
"ag.new.advNote":
|
|
573
|
+
"Defaults come from the persona. Changes here apply to this session only, and the session is marked in the list.",
|
|
574
|
+
"ag.new.model": "Model",
|
|
575
|
+
"ag.new.modelDef": "Persona default ({m})",
|
|
576
|
+
"ag.new.ver": "Version",
|
|
577
|
+
"ag.new.verDef": "Persona default ({v})",
|
|
578
|
+
"ag.new.note":
|
|
579
|
+
"Starts in the workspace folder. It keeps running if you close the pane.",
|
|
580
|
+
"ag.new.started": "Started {p} in {w}",
|
|
581
|
+
"pm.ask": "Ask for everything",
|
|
582
|
+
"pm.edits": "Auto-approve edits in the worktree",
|
|
583
|
+
"pm.all": "Auto-approve all",
|
|
584
|
+
"pm.tag.ask": "asks for all",
|
|
585
|
+
"pm.tag.edits": "auto-approve edits",
|
|
586
|
+
"pm.tag.all": "auto-approve all",
|
|
587
|
+
"ov.runtime": "runtime: {r}",
|
|
588
|
+
"ov.model": "model: {m}",
|
|
589
|
+
"ov.latest": "latest",
|
|
590
|
+
"ov.tools": "custom tools",
|
|
591
|
+
"pe.what":
|
|
592
|
+
"A persona is a saved agent setup: a role, its instructions, a default runtime and model, and what it may do without asking. You can have several with the same role, each with its own name.",
|
|
593
|
+
"pe.preset": "Role preset",
|
|
594
|
+
"pe.extra": "Extra allowed commands",
|
|
595
|
+
"pe.extraS": "extra",
|
|
596
|
+
"pe.extraP":
|
|
597
|
+
"Plain command prefixes, one per line. No patterns or regex. Den translates them for each runtime.",
|
|
598
|
+
"pe.allows": "What this allows on {r}",
|
|
599
|
+
"pe.ns": "not supported on {r}",
|
|
600
|
+
"pe.nsMode": "{r} takes no permission mode from Den yet",
|
|
601
|
+
"pe.nsModel": "{r} takes no model from Den",
|
|
602
|
+
"pe.nsPat": "use a plain prefix, not a pattern",
|
|
603
|
+
"pe.nsBad": "not a plain prefix",
|
|
604
|
+
"pe.badCmd":
|
|
605
|
+
'"{c}" isn\'t a plain command prefix: use letters, digits, single spaces and . _ / : = @ % + , -',
|
|
606
|
+
"pe.raw": "Edit raw runtime config…",
|
|
607
|
+
"pe.rawLater": "Opening a runtime's own config file is coming later.",
|
|
608
|
+
"pe.vendor": "vendor-specific",
|
|
609
|
+
"pe.instr": "Instructions",
|
|
610
|
+
"pe.runtime": "Default runtime",
|
|
611
|
+
"pe.model": "Model",
|
|
612
|
+
"pe.ver": "Version",
|
|
613
|
+
"pe.rtDefault": "the runtime's default",
|
|
614
|
+
"pe.perms": "Permission mode",
|
|
615
|
+
"pe.noneCmd": "none",
|
|
616
|
+
"pe.loading": "Loading…",
|
|
617
|
+
"pe.loadFail": "The personas did not load.",
|
|
618
|
+
"pe.src.builtin": "built-in",
|
|
619
|
+
"pe.src.distribution": "distribution",
|
|
620
|
+
"pe.src.local": "mine",
|
|
621
|
+
"pe.src.hub": "hub",
|
|
622
|
+
"pe.src.builtin.p":
|
|
623
|
+
"Ships with Den. Read-only here; duplicate it to customize.",
|
|
624
|
+
"pe.src.distribution.p":
|
|
625
|
+
"Ships with your distribution. Read-only here; duplicate it to customize.",
|
|
626
|
+
"pe.src.local.p": "Yours, on this machine.",
|
|
627
|
+
"pe.src.hub.p": "Shared through Den Hub. Read-only here.",
|
|
628
|
+
"pe.new": "New persona",
|
|
629
|
+
"pe.dupT": "Duplicate persona",
|
|
630
|
+
"pe.edit": "Edit persona",
|
|
631
|
+
"pe.dup": "Duplicate",
|
|
632
|
+
"pe.editB": "Edit",
|
|
633
|
+
"pe.view": "View",
|
|
634
|
+
"pe.save": "Save persona",
|
|
635
|
+
"pe.del": "Delete",
|
|
636
|
+
"pe.deleted": "Deleted {n}",
|
|
637
|
+
"pe.name": "Name",
|
|
638
|
+
"pe.nameP": "e.g. Rita",
|
|
639
|
+
"pe.role": "Role",
|
|
640
|
+
"pe.roleHelp":
|
|
641
|
+
"A role sets this persona's starting template and lets Den hand work to it. It adds nothing hidden to the instructions.",
|
|
642
|
+
"pe.desc": "One-line description",
|
|
643
|
+
"pe.cat": "Category",
|
|
644
|
+
"pe.copy": "{n} (copy)",
|
|
645
|
+
"pe.saved": "Saved {n}",
|
|
646
|
+
"pe.ro": "Read-only here. Duplicate it to make a copy of your own.",
|
|
647
|
+
"pf.search": "Search personas by name, role or description",
|
|
648
|
+
"pf.cat": "Category",
|
|
649
|
+
"pf.src": "Source",
|
|
650
|
+
"pf.all": "All",
|
|
651
|
+
"pf.none": "No persona matches. Clear the filters or create one.",
|
|
652
|
+
"pf.clear": "Clear filters",
|
|
653
|
+
"cat.engineering": "Engineering",
|
|
654
|
+
"cat.design": "Design",
|
|
655
|
+
"cat.product": "Product",
|
|
656
|
+
"cat.marketing": "Marketing",
|
|
657
|
+
"cat.operations": "Operations",
|
|
658
|
+
"rt.installed": "Installed",
|
|
659
|
+
"rt.missing": "Not installed",
|
|
660
|
+
"rt.notInst": "{r} not installed",
|
|
661
|
+
"rt.later": "later",
|
|
662
|
+
"rt.fallback":
|
|
663
|
+
"{p}'s default runtime, {r}, isn't installed here, so this starts on {f}.",
|
|
664
|
+
"ver.latest": "latest",
|
|
665
|
+
"ver.latestP": "Latest (tracks the newest release)",
|
|
666
|
+
"ver.newer": "newer available",
|
|
667
|
+
"ver.newerP":
|
|
668
|
+
"A newer version of this model is out. This one stays pinned until you change it.",
|
|
669
|
+
"ver.newerOf": "Newer: {v}",
|
|
670
|
+
"ver.use": "Use latest",
|
|
671
|
+
"ver.pinned": "pinned {v}",
|
|
672
|
+
"ver.usedLatest": "{n} now tracks the latest version",
|
|
673
|
+
"set.agents.personas": "Personas",
|
|
557
674
|
// The Agents tab (AG-4a-term, agents-page.js).
|
|
558
675
|
"n.agents": "Agents",
|
|
559
676
|
"kind.agent": "Agent",
|
|
@@ -881,7 +881,7 @@ function paletteItems() {
|
|
|
881
881
|
const base =
|
|
882
882
|
x.kind === "agent" ? x.displayName || (x.persona ?? x.label) : x.label;
|
|
883
883
|
// AG-4b: the session's name (a /rename, or Den's), when it says more.
|
|
884
|
-
const sn = x.kind === "agent" ? (x.
|
|
884
|
+
const sn = x.kind === "agent" ? (x.sessionTitle ?? "").trim() : "";
|
|
885
885
|
const extra =
|
|
886
886
|
sn && sn !== base && sn !== x.persona && sn !== x.label ? sn : "";
|
|
887
887
|
const name = extra ? `${base} · ${extra}` : base;
|
|
@@ -899,7 +899,7 @@ function paletteItems() {
|
|
|
899
899
|
x.label,
|
|
900
900
|
x.persona ?? "",
|
|
901
901
|
x.displayName ?? "",
|
|
902
|
-
x.
|
|
902
|
+
x.sessionTitle ?? "",
|
|
903
903
|
"agents",
|
|
904
904
|
"terminal",
|
|
905
905
|
],
|
|
@@ -148,6 +148,17 @@ export const ROUTES: readonly RouteEntry[] = [
|
|
|
148
148
|
"/api/agents/runtimes",
|
|
149
149
|
"/api/workspaces/:ws/agents",
|
|
150
150
|
].map((p) => R(p)),
|
|
151
|
+
R("/api/personas/:id", "one persona with its instructions (AG-10.6 Details)"),
|
|
152
|
+
M(
|
|
153
|
+
["POST"],
|
|
154
|
+
"/api/personas",
|
|
155
|
+
"New persona: a person's own, in the state dir (AG-10.7); never an agent's token",
|
|
156
|
+
),
|
|
157
|
+
M(
|
|
158
|
+
["POST", "DELETE"],
|
|
159
|
+
"/api/personas/:id",
|
|
160
|
+
"edits or deletes a person's own persona (AG-10.7); never an agent's token",
|
|
161
|
+
),
|
|
151
162
|
R(
|
|
152
163
|
"/api/workspaces/:ws/agents/:id/paths",
|
|
153
164
|
"which paths an agent printed exist in its workspace (stat only, AG-4b)",
|
|
@@ -342,6 +353,11 @@ export const ROUTES: readonly RouteEntry[] = [
|
|
|
342
353
|
"/api/workspaces/:ws/agents",
|
|
343
354
|
"starts an agent: a runtime in a PTY",
|
|
344
355
|
),
|
|
356
|
+
S(
|
|
357
|
+
["POST"],
|
|
358
|
+
"/api/workspaces/:ws/sessions",
|
|
359
|
+
"starts a plain session: the person's login shell in the workspace (AG-10.1)",
|
|
360
|
+
),
|
|
345
361
|
S(
|
|
346
362
|
["POST"],
|
|
347
363
|
"/api/workspaces/:ws/agents/:id/resume",
|
|
@@ -420,6 +436,8 @@ export const REGEX_ROUTES: Readonly<Record<string, readonly string[]>> = {
|
|
|
420
436
|
"/api/workspaces/:ws/agents/:id/paths",
|
|
421
437
|
],
|
|
422
438
|
"agent-routes.ts:RUNTIME_PATH": ["/api/agents/runtimes/:id/path"],
|
|
439
|
+
"agent-routes.ts:PERSONA_PATH": ["/api/personas/:id"],
|
|
440
|
+
"agent-routes.ts:PLAIN_PATH": ["/api/workspaces/:ws/sessions"],
|
|
423
441
|
"session-routes.ts:IO_PATH": ["/api/sessions/:id/io"],
|
|
424
442
|
"github-routes.ts:SIGNIN_PATH": ["/api/github/signin/:id"],
|
|
425
443
|
"github-routes.ts:LINK_PATH": ["/api/web/owner/link/:id"],
|
|
@@ -55,7 +55,8 @@ import { parseSessionName } from "../../shared/sessions/names.js";
|
|
|
55
55
|
import { sessionPaths } from "../../shared/sessions/paths.js";
|
|
56
56
|
import { loadPty, type PtyLoad } from "../../shared/sessions/pty.js";
|
|
57
57
|
import type { SessionInfo } from "../../shared/sessions/types.js";
|
|
58
|
-
import { agentRows, noteEnded } from "../cli/agent-ops.js";
|
|
58
|
+
import { agentRows, newerOf, noteEnded } from "../cli/agent-ops.js";
|
|
59
|
+
import type { Override } from "../../shared/agents/records.js";
|
|
59
60
|
import { state as sessionState } from "../cli/sessions-command.js";
|
|
60
61
|
import { recordAction } from "./audit.js";
|
|
61
62
|
import { sendJson } from "./http-helpers.js";
|
|
@@ -137,10 +138,11 @@ export interface ListedSession {
|
|
|
137
138
|
/** The name a person gave the agent (AG-4b), when one did. */
|
|
138
139
|
displayName?: string;
|
|
139
140
|
/**
|
|
140
|
-
*
|
|
141
|
-
* runtime's (Claude Code's /rename), when there is one.
|
|
141
|
+
* The name its session shows (AG-4b): the latest of Den's rename and the
|
|
142
|
+
* runtime's (Claude Code's /rename), when there is one. Its handle is
|
|
143
|
+
* `name`.
|
|
142
144
|
*/
|
|
143
|
-
|
|
145
|
+
sessionTitle?: string;
|
|
144
146
|
/**
|
|
145
147
|
* What Shift+Enter sends to it (AG-4b, its catalog entry's softNewline):
|
|
146
148
|
* ESC CR unless the runtime says otherwise. A plain session: none (Enter).
|
|
@@ -149,6 +151,15 @@ export interface ListedSession {
|
|
|
149
151
|
persona?: string;
|
|
150
152
|
runtime?: string;
|
|
151
153
|
model?: string;
|
|
154
|
+
/** A pinned model version (AG-12), and the newer one when there is. */
|
|
155
|
+
version?: string;
|
|
156
|
+
newer?: string;
|
|
157
|
+
/** Its permission intent (AG-13): ask, edits, all. */
|
|
158
|
+
permission?: string;
|
|
159
|
+
/** Extra allowed commands it was started with (AG-13.3). */
|
|
160
|
+
allow?: string[];
|
|
161
|
+
/** What it overrides of its persona (AG-10.9): its row's tags. */
|
|
162
|
+
overrides?: Override[];
|
|
152
163
|
cwd?: string;
|
|
153
164
|
/** running, stopping, exited (<code>), stopped, interrupted (AG-14). */
|
|
154
165
|
state: string;
|
|
@@ -208,11 +219,16 @@ export function listedSessions(
|
|
|
208
219
|
label: rec.id,
|
|
209
220
|
agent: rec.id,
|
|
210
221
|
...(rec.displayName ? { displayName: rec.displayName } : {}),
|
|
211
|
-
...(r.
|
|
222
|
+
...(r.sessionTitle ? { sessionTitle: r.sessionTitle } : {}),
|
|
212
223
|
softNewline: softNewlineSeq(getRuntime(rec.runtime)?.catalog),
|
|
213
224
|
persona: rec.persona,
|
|
214
225
|
runtime: rec.runtime,
|
|
215
226
|
...(rec.model ? { model: rec.model } : {}),
|
|
227
|
+
...(rec.version ? { version: rec.version } : {}),
|
|
228
|
+
...newerOf(rec),
|
|
229
|
+
...(rec.permission ? { permission: rec.permission } : {}),
|
|
230
|
+
...(rec.allow?.length ? { allow: [...rec.allow] } : {}),
|
|
231
|
+
...(rec.overrides?.length ? { overrides: [...rec.overrides] } : {}),
|
|
216
232
|
cwd: rec.cwd,
|
|
217
233
|
state: r.state,
|
|
218
234
|
exited: !s || s.exited === true,
|
|
@@ -36,6 +36,9 @@ export const UI_MODULES: readonly string[] = [
|
|
|
36
36
|
"/agents-page.js",
|
|
37
37
|
// The Start agent form's choices, shared by both (AG-10.0).
|
|
38
38
|
"/agent-start.js",
|
|
39
|
+
// AG-10.4-10.7: the persona picker, editor and Settings › Personas.
|
|
40
|
+
"/persona-ui.js",
|
|
41
|
+
"/persona-ui.css",
|
|
39
42
|
// AG-4b: the panes' keys and links (Shift+Enter, ⌃⇧1-3, paths).
|
|
40
43
|
"/term-input.js",
|
|
41
44
|
// SEC-2a: Pair a device's QR code (a tiny encoder of Den's own).
|