@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
@@ -0,0 +1,563 @@
1
+ /*
2
+ * The Start dialog's persona picker, the persona editor and Settings ›
3
+ * Personas (persona-ui.js). Sizes are the Den Shell prototype's
4
+ * (den-merge-notes/shell-proto/den-shell.html: .dlg.wide, .plist, .pr,
5
+ * .pfbar, .pgh, .pmode, .pv, .pdet), its colors mapped onto the theme's
6
+ * tokens (--r-btn is --radius-button). tests/unit/server/
7
+ * start-dialog.browser.test.ts measures them.
8
+ */
9
+
10
+ /* The editor's frame where agents.html's dialog styles aren't loaded. */
11
+ dialog.pe-dlg {
12
+ box-sizing: border-box;
13
+ /* The prototype's base (.app: 14px/1.45): labels, rows and chips take
14
+ their line height from it. */
15
+ font: 14px/1.45 var(--sans);
16
+ width: min(638px, calc(100vw - 32px));
17
+ max-width: none;
18
+ max-height: calc(100vh - 32px);
19
+ overflow-y: auto;
20
+ background: var(--raised);
21
+ color: var(--text);
22
+ border: 1px solid var(--border-strong);
23
+ border-radius: 12px;
24
+ box-shadow: var(--shadow);
25
+ padding: 18px 18px 14px;
26
+ }
27
+ dialog.pe-dlg::backdrop {
28
+ background: rgb(0 0 0 / 0.35);
29
+ }
30
+ .pe-dlg form {
31
+ display: grid;
32
+ grid-template-columns: minmax(0, 1fr);
33
+ gap: 12px;
34
+ }
35
+ .pe-dlg h2 {
36
+ margin: 0;
37
+ font: 600 17px var(--display);
38
+ }
39
+ .pe-dlg p {
40
+ margin: 0;
41
+ color: var(--muted);
42
+ font-size: 13.5px;
43
+ }
44
+ .pe-dlg .help {
45
+ margin: 0;
46
+ font: 12.5px/1.45 var(--sans);
47
+ color: var(--muted);
48
+ }
49
+ .pe-dlg .err {
50
+ margin: 0;
51
+ font: 12.5px/1.45 var(--sans);
52
+ color: var(--bad);
53
+ overflow-wrap: anywhere;
54
+ }
55
+ /* Hidden wins over a field's grid. */
56
+ .pe-dlg [hidden] {
57
+ display: none !important;
58
+ }
59
+ .pe-dlg .btns {
60
+ display: flex;
61
+ gap: 8px;
62
+ align-items: center;
63
+ flex-wrap: wrap;
64
+ /* AG-10.0: the footer stays in sight while the dialog scrolls. */
65
+ position: sticky;
66
+ bottom: -14px;
67
+ margin-bottom: -14px;
68
+ padding-bottom: 14px;
69
+ background: var(--raised);
70
+ }
71
+ .pe-dlg .btns .sp {
72
+ margin-right: auto;
73
+ }
74
+
75
+ /* A field: the 11px mono caps label over its control (.dlg .fld). */
76
+ .pe-dlg .fld {
77
+ display: grid;
78
+ gap: 6px;
79
+ font-size: 13px;
80
+ min-width: 0;
81
+ text-transform: none;
82
+ letter-spacing: 0;
83
+ color: var(--text);
84
+ }
85
+ .pe-dlg .fld > span,
86
+ .pe-dlg .fldh > .k {
87
+ font: 11px/1.45 var(--mono);
88
+ color: var(--faint);
89
+ text-transform: uppercase;
90
+ letter-spacing: 0.07em;
91
+ }
92
+ .pe-dlg .two {
93
+ display: grid;
94
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
95
+ gap: 10px;
96
+ }
97
+ @media (max-width: 520px) {
98
+ .pe-dlg .two {
99
+ grid-template-columns: minmax(0, 1fr);
100
+ }
101
+ }
102
+ .pe-dlg select,
103
+ .pe-dlg input[type="text"],
104
+ .pe-dlg input[type="search"] {
105
+ box-sizing: border-box;
106
+ /* The prototype's controls keep the browser's own line box: 31px for a
107
+ select, 30 for a text field (padding 6, a 1px border). */
108
+ height: 31px;
109
+ width: 100%;
110
+ min-width: 0;
111
+ font: 13px/1.45 var(--sans);
112
+ text-transform: none;
113
+ letter-spacing: 0;
114
+ border: 1px solid var(--border);
115
+ background: var(--bg);
116
+ color: var(--text);
117
+ border-radius: var(--radius-button);
118
+ padding: 6px 8px;
119
+ }
120
+ .pe-dlg textarea {
121
+ box-sizing: border-box;
122
+ width: 100%;
123
+ border: 1px solid var(--border);
124
+ background: var(--bg);
125
+ color: var(--text);
126
+ border-radius: var(--radius-button);
127
+ padding: 8px;
128
+ font: 13px/1.5 var(--sans);
129
+ text-transform: none;
130
+ letter-spacing: 0;
131
+ resize: vertical;
132
+ min-height: 96px;
133
+ }
134
+ .pe-dlg select:disabled,
135
+ .pe-dlg input:disabled,
136
+ .pe-dlg textarea:disabled {
137
+ opacity: 0.75;
138
+ }
139
+ .pe-dlg details {
140
+ border: 1px solid var(--border);
141
+ border-radius: var(--radius-button);
142
+ padding: 8px 10px;
143
+ }
144
+ .pe-dlg details summary {
145
+ cursor: pointer;
146
+ font-size: 13px;
147
+ color: var(--muted);
148
+ }
149
+ .pe-dlg details[open] > summary {
150
+ margin-bottom: 8px;
151
+ }
152
+ .pe-dlg details.xtra {
153
+ padding: 6px 10px;
154
+ }
155
+ .pe-dlg details.xtra textarea {
156
+ display: block;
157
+ margin-bottom: 4px;
158
+ min-height: 64px;
159
+ font: 12px/1.5 var(--mono);
160
+ }
161
+ .pe-dlg .adv-body {
162
+ display: grid;
163
+ gap: 10px;
164
+ }
165
+ .pe-dlg .adv-body > p {
166
+ margin: 0;
167
+ }
168
+ .pe-dlg .pblk {
169
+ display: grid;
170
+ gap: 12px;
171
+ }
172
+
173
+ .helpl {
174
+ font-size: 12px;
175
+ color: var(--faint);
176
+ line-height: 1.4;
177
+ }
178
+ .helpl .mono {
179
+ font: 11.5px/1.4 var(--mono);
180
+ }
181
+ .helpl.warn {
182
+ color: var(--warn);
183
+ }
184
+ .faint {
185
+ color: var(--faint);
186
+ }
187
+ .fldh {
188
+ display: flex;
189
+ align-items: baseline;
190
+ gap: 12px;
191
+ flex-wrap: wrap;
192
+ }
193
+ .fldh .sp {
194
+ margin-left: auto;
195
+ }
196
+ .lnk {
197
+ color: var(--accent-text);
198
+ cursor: pointer;
199
+ font: 12.5px/1.45 var(--sans);
200
+ text-decoration: underline;
201
+ text-transform: none;
202
+ letter-spacing: 0;
203
+ background: none;
204
+ border: 0;
205
+ padding: 0;
206
+ }
207
+ .lnk[aria-disabled="true"] {
208
+ opacity: 0.6;
209
+ cursor: default;
210
+ }
211
+
212
+ /* The filter bar (AG-10.4). */
213
+ .pfbar {
214
+ display: grid;
215
+ gap: 6px;
216
+ }
217
+ .pe-dlg input[type="text"] {
218
+ height: 30px;
219
+ }
220
+ .pfbar input[type="search"] {
221
+ box-sizing: border-box;
222
+ height: 29px;
223
+ width: 100%;
224
+ border: 1px solid var(--border);
225
+ background: var(--bg);
226
+ color: var(--text);
227
+ border-radius: var(--radius-button);
228
+ padding: 6px 10px;
229
+ font: 13px/1.45 var(--sans);
230
+ }
231
+ .pfrow {
232
+ display: flex;
233
+ gap: 4px;
234
+ flex-wrap: wrap;
235
+ align-items: center;
236
+ }
237
+ .pfrow .lab {
238
+ font: 11px/1.45 var(--mono);
239
+ color: var(--faint);
240
+ text-transform: uppercase;
241
+ letter-spacing: 0.06em;
242
+ margin-right: 2px;
243
+ }
244
+ .pfc {
245
+ border: 1px solid var(--border);
246
+ background: var(--surface);
247
+ color: var(--muted);
248
+ border-radius: 999px;
249
+ padding: 1px 10px;
250
+ font: 12.5px/1.45 var(--sans);
251
+ cursor: pointer;
252
+ }
253
+ .pfc[aria-pressed="true"] {
254
+ border-color: var(--accent);
255
+ color: var(--text);
256
+ background: color-mix(in srgb, var(--accent) 14%, transparent);
257
+ }
258
+ .pfc .c {
259
+ color: var(--faint);
260
+ font: 11px/1.45 var(--mono);
261
+ margin-left: 4px;
262
+ }
263
+
264
+ /* The list: radios grouped by category (.plist, .pr, .pgh). */
265
+ .plist {
266
+ display: grid;
267
+ gap: 4px;
268
+ max-height: 260px;
269
+ overflow-y: auto;
270
+ border: 1px solid var(--border);
271
+ border-radius: var(--radius-button);
272
+ padding: 4px;
273
+ background: var(--bg);
274
+ }
275
+ .pr {
276
+ display: grid;
277
+ grid-template-columns: 16px minmax(0, 1fr) auto;
278
+ gap: 0 8px;
279
+ align-items: center;
280
+ width: 100%;
281
+ text-align: left;
282
+ border: 1px solid transparent;
283
+ background: none;
284
+ border-radius: var(--radius-button);
285
+ padding: 6px 8px;
286
+ cursor: pointer;
287
+ color: var(--text);
288
+ font: 13px/1.45 var(--sans);
289
+ text-transform: none;
290
+ letter-spacing: 0;
291
+ }
292
+ .pr:hover {
293
+ background: var(--sunken);
294
+ }
295
+ .pr[aria-checked="true"] {
296
+ border-color: var(--accent);
297
+ background: color-mix(in srgb, var(--accent) 10%, transparent);
298
+ }
299
+ .pr .rd {
300
+ box-sizing: border-box;
301
+ width: 12px;
302
+ height: 12px;
303
+ border-radius: 50%;
304
+ border: 1.5px solid var(--border-strong);
305
+ }
306
+ .pr[aria-checked="true"] .rd {
307
+ border-color: var(--accent);
308
+ background: radial-gradient(var(--accent) 45%, transparent 50%);
309
+ }
310
+ .pr .pn,
311
+ .prow .pn {
312
+ font-weight: 500;
313
+ min-width: 0;
314
+ overflow: hidden;
315
+ text-overflow: ellipsis;
316
+ white-space: nowrap;
317
+ }
318
+ /* Bring in: the title is cut, never its badge ("Agent reviewer"). */
319
+ .pr .pn.pnc {
320
+ display: flex;
321
+ align-items: center;
322
+ gap: 6px;
323
+ }
324
+ .pr .pnc .pt {
325
+ min-width: 0;
326
+ overflow: hidden;
327
+ text-overflow: ellipsis;
328
+ }
329
+ .pr .pnc .tagx {
330
+ flex: none;
331
+ }
332
+ .pr .pn .role,
333
+ .prow .pn .role {
334
+ color: var(--faint);
335
+ font-weight: 400;
336
+ }
337
+ .pr .pd {
338
+ grid-column: 2 / 4;
339
+ font-size: 12.5px;
340
+ color: var(--muted);
341
+ }
342
+ .pgh {
343
+ font: 11px/1.45 var(--mono);
344
+ color: var(--faint);
345
+ text-transform: uppercase;
346
+ letter-spacing: 0.07em;
347
+ padding: 8px 8px 2px;
348
+ display: flex;
349
+ justify-content: space-between;
350
+ }
351
+ .pempty {
352
+ padding: 10px 8px;
353
+ color: var(--muted);
354
+ font-size: 12.5px;
355
+ }
356
+ /* A tag (agents.html's, for the pages that don't have it: Settings). */
357
+ .tagx {
358
+ font: 10px var(--mono);
359
+ color: var(--faint);
360
+ border: 1px dashed var(--border-strong);
361
+ border-radius: 4px;
362
+ padding: 0 4px;
363
+ font-weight: 400;
364
+ white-space: nowrap;
365
+ }
366
+ .tagx.warn {
367
+ color: var(--warn);
368
+ border-color: color-mix(in srgb, var(--warn) 55%, transparent);
369
+ }
370
+ .tagx.src-local {
371
+ color: var(--accent-text);
372
+ border-color: color-mix(in srgb, var(--accent) 50%, transparent);
373
+ }
374
+ .tagx.src-distribution {
375
+ color: var(--muted);
376
+ border-style: solid;
377
+ }
378
+ .tagx.src-hub {
379
+ color: var(--remote, var(--accent-text));
380
+ border-color: color-mix(
381
+ in srgb,
382
+ var(--remote, var(--accent)) 50%,
383
+ transparent
384
+ );
385
+ }
386
+
387
+ /* Details (AG-10.6) and "What's a persona?". */
388
+ .pdet {
389
+ border: 1px solid var(--border);
390
+ border-radius: var(--radius-button);
391
+ background: var(--sunken);
392
+ padding: 10px 12px;
393
+ display: grid;
394
+ gap: 6px;
395
+ font: 12.5px/1.45 var(--sans);
396
+ color: var(--text);
397
+ text-transform: none;
398
+ letter-spacing: 0;
399
+ }
400
+ .pdet .k {
401
+ font: 11px/1.45 var(--mono);
402
+ color: var(--faint);
403
+ text-transform: uppercase;
404
+ letter-spacing: 0.06em;
405
+ }
406
+ .pdet pre {
407
+ margin: 0;
408
+ white-space: pre-wrap;
409
+ overflow-wrap: anywhere;
410
+ font: 12px/1.5 var(--mono);
411
+ color: var(--text);
412
+ max-height: 200px;
413
+ overflow-y: auto;
414
+ }
415
+ .pdet .why {
416
+ color: var(--muted);
417
+ }
418
+ .pdet .mono,
419
+ .pv .mono {
420
+ font-family: var(--mono);
421
+ }
422
+
423
+ /* The permission block (AG-13). */
424
+ .seg.pmode {
425
+ display: grid;
426
+ grid-template-columns: repeat(3, minmax(0, 1fr));
427
+ border: 1px solid var(--border);
428
+ border-radius: var(--radius-button);
429
+ overflow: hidden;
430
+ }
431
+ .seg.pmode button {
432
+ text-align: center;
433
+ background: none;
434
+ border: 0;
435
+ padding: 6px 12px;
436
+ cursor: pointer;
437
+ color: var(--muted);
438
+ font: 13px/1.45 var(--sans);
439
+ }
440
+ .seg.pmode button + button {
441
+ border-left: 1px solid var(--border);
442
+ }
443
+ .seg.pmode button[aria-pressed="true"] {
444
+ background: color-mix(in srgb, var(--accent) 16%, transparent);
445
+ color: var(--text);
446
+ font-weight: 500;
447
+ }
448
+ .seg.pmode button:disabled {
449
+ cursor: default;
450
+ }
451
+ .pchips {
452
+ display: flex;
453
+ flex-wrap: wrap;
454
+ gap: 4px;
455
+ text-transform: none;
456
+ letter-spacing: 0;
457
+ }
458
+ .pchip {
459
+ font: 11.5px/1.45 var(--mono);
460
+ color: var(--text);
461
+ border: 1px solid var(--border);
462
+ border-radius: 999px;
463
+ padding: 0 8px;
464
+ background: var(--surface);
465
+ }
466
+ .pvw {
467
+ display: grid;
468
+ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
469
+ gap: 8px;
470
+ }
471
+ .pv {
472
+ border: 1px solid var(--border);
473
+ border-radius: var(--radius-button);
474
+ background: var(--sunken);
475
+ padding: 8px 10px;
476
+ font: 12.5px/1.45 var(--sans);
477
+ color: var(--text);
478
+ min-width: 0;
479
+ text-transform: none;
480
+ letter-spacing: 0;
481
+ }
482
+ .pv ul {
483
+ margin: 4px 0 0;
484
+ padding-left: 16px;
485
+ display: grid;
486
+ gap: 2px;
487
+ }
488
+ .pv .mono {
489
+ font-size: 11.5px;
490
+ overflow-wrap: anywhere;
491
+ }
492
+ .pv .gone {
493
+ text-decoration: line-through;
494
+ color: var(--faint);
495
+ }
496
+ .pv .src {
497
+ color: var(--faint);
498
+ }
499
+
500
+ /* Settings › Personas. */
501
+ .pe-set {
502
+ display: grid;
503
+ gap: 8px;
504
+ }
505
+ .pe-set .plist {
506
+ max-height: none;
507
+ }
508
+ .prow {
509
+ display: grid;
510
+ grid-template-columns: minmax(0, 1fr) auto;
511
+ gap: 2px 8px;
512
+ padding: 8px 10px;
513
+ border: 1px solid var(--border);
514
+ border-radius: var(--radius-button);
515
+ background: var(--surface);
516
+ font-size: 13px;
517
+ }
518
+ .prow .pd {
519
+ grid-column: 1;
520
+ font-size: 12.5px;
521
+ color: var(--muted);
522
+ }
523
+ .prow .pm {
524
+ grid-column: 1;
525
+ font-size: 12px;
526
+ color: var(--faint);
527
+ }
528
+ .prow .pm .mono {
529
+ font-family: var(--mono);
530
+ }
531
+ .prow .pa {
532
+ grid-column: 2;
533
+ grid-row: 1 / 4;
534
+ display: flex;
535
+ gap: 4px;
536
+ align-items: center;
537
+ flex-wrap: wrap;
538
+ justify-content: flex-end;
539
+ }
540
+ @media (max-width: 520px) {
541
+ .prow {
542
+ grid-template-columns: minmax(0, 1fr);
543
+ }
544
+ .prow .pa {
545
+ grid-column: 1;
546
+ grid-row: auto;
547
+ justify-content: flex-start;
548
+ }
549
+ }
550
+ .den-btn.sm {
551
+ padding: 2px 9px;
552
+ font-size: 12.5px;
553
+ }
554
+
555
+ /* AG-17.1, Bring in: a conversation that can't be picked (open elsewhere,
556
+ or an agent already continues it). */
557
+ .pr[aria-disabled="true"] {
558
+ opacity: 0.6;
559
+ cursor: default;
560
+ }
561
+ .pr[aria-disabled="true"]:hover {
562
+ background: none;
563
+ }