dsh-zen-remote 1.0.2 → 1.1.0
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/AGENTS.md +9 -1
- package/README.md +56 -16
- package/docs/interface.md +69 -6
- package/docs/remote-access.en.md +7 -5
- package/docs/remote-access.md +8 -6
- package/dsh-push.mjs +272 -64
- package/lib/client.js +550 -28
- package/lib/lan-gate-server.cjs +7 -1
- package/lib/types/client/MobileHome.d.ts.map +1 -1
- package/lib/types/client/MobileSessionHeader.d.ts +1 -1
- package/lib/types/client/MobileSessionHeader.d.ts.map +1 -1
- package/lib/types/client/MobileSessionInfo.d.ts.map +1 -1
- package/lib/types/client/effects/modal-back.d.ts +22 -0
- package/lib/types/client/effects/modal-back.d.ts.map +1 -0
- package/lib/types/client/history-nav.d.ts +49 -0
- package/lib/types/client/history-nav.d.ts.map +1 -0
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +4 -2
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/styles/base.css.d.ts +1 -1
- package/lib/types/client/styles/base.css.d.ts.map +1 -1
- package/lib/types/client/styles/chips.css.d.ts +1 -1
- package/lib/types/client/styles/chips.css.d.ts.map +1 -1
- package/lib/types/client/styles/compat.css.d.ts +1 -1
- package/lib/types/client/styles/compat.css.d.ts.map +1 -1
- package/lib/types/client/styles/composer.css.d.ts +1 -1
- package/lib/types/client/styles/composer.css.d.ts.map +1 -1
- package/lib/types/client/styles/content.css.d.ts +1 -1
- package/lib/types/client/styles/content.css.d.ts.map +1 -1
- package/lib/types/client/styles/header.css.d.ts +1 -1
- package/lib/types/client/styles/header.css.d.ts.map +1 -1
- package/lib/types/client/styles/home.css.d.ts +1 -1
- package/lib/types/client/styles/home.css.d.ts.map +1 -1
- package/llms.txt +1 -1
- package/package.json +23 -21
- package/pwa/inject.js +1 -0
- package/scripts/sync-doc-version.mjs +83 -0
- package/src/client/MobileHome.tsx +17 -1
- package/src/client/MobileSessionHeader.tsx +134 -1
- package/src/client/MobileSessionInfo.tsx +38 -8
- package/src/client/effects/modal-back.ts +98 -0
- package/src/client/history-nav.ts +121 -0
- package/src/client/index.tsx +2 -0
- package/src/client/locales.ts +8 -4
- package/src/client/styles/base.css.ts +6 -0
- package/src/client/styles/chips.css.ts +4 -1
- package/src/client/styles/compat.css.ts +8 -1
- package/src/client/styles/composer.css.ts +25 -0
- package/src/client/styles/content.css.ts +24 -0
- package/src/client/styles/header.css.ts +123 -0
- package/src/client/styles/home.css.ts +19 -10
|
@@ -24,6 +24,7 @@ export const HEADER_CSS = `/* ---------- session header five-piece reflow (< 768
|
|
|
24
24
|
list in misc.css.ts. */
|
|
25
25
|
[data-mobile-nav="header-back"],
|
|
26
26
|
[data-mobile-nav="header-viewrow"],
|
|
27
|
+
[data-mobile-nav="header-activity"],
|
|
27
28
|
[data-mobile-nav="header-info"],
|
|
28
29
|
[data-mobile-nav="header-workbench"],
|
|
29
30
|
/* The workbench close pill's default-hidden used to live in compat.css.ts —
|
|
@@ -266,6 +267,48 @@ export const HEADER_CSS = `/* ---------- session header five-piece reflow (< 768
|
|
|
266
267
|
[data-phase] header [data-slot="conversation.session.header.utilities"] > * {
|
|
267
268
|
display: none !important;
|
|
268
269
|
}
|
|
270
|
+
/* Native background-task / subagent entries: kept mounted, but parked as
|
|
271
|
+
ZERO-WIDTH INVISIBLE ANCHORS at the right end of the view-switch band.
|
|
272
|
+
Our activity pill is the visible control and forwards the tap to the
|
|
273
|
+
official trigger, so the official popover — a child of this root — still
|
|
274
|
+
mounts and positions from here.
|
|
275
|
+
|
|
276
|
+
Why not just leave them visible in the header: each is ~103px wide while
|
|
277
|
+
headerActions' grid column is 92px, and flex children that cannot shrink
|
|
278
|
+
simply overflow — measured at 375px the subagent entry ran x=60..163
|
|
279
|
+
straight across the centred title at x=100..275.
|
|
280
|
+
|
|
281
|
+
Why not display:none them either: the menu lives inside the root, so
|
|
282
|
+
hiding the root takes the popover with it and the pill would have
|
|
283
|
+
nothing to open. Hide the TRIGGER (below) and keep the root as a box. */
|
|
284
|
+
[data-phase] header [data-slot="conversation.session.header.actions"] > [class$="_root"]:has(> button[class$="_trigger"]) {
|
|
285
|
+
display: block !important;
|
|
286
|
+
position: absolute !important;
|
|
287
|
+
right: 0 !important;
|
|
288
|
+
top: 100% !important;
|
|
289
|
+
width: 0 !important;
|
|
290
|
+
height: 28px !important;
|
|
291
|
+
overflow: visible !important;
|
|
292
|
+
order: 0 !important;
|
|
293
|
+
}
|
|
294
|
+
/* The official trigger never shows — the pill replaced it. Programmatic
|
|
295
|
+
.click() still reaches React's handler on a display:none button. */
|
|
296
|
+
[data-phase] header [data-slot="conversation.session.header.actions"] > [class$="_root"] > button[class$="_trigger"] {
|
|
297
|
+
display: none !important;
|
|
298
|
+
}
|
|
299
|
+
/* Anchor the popover to the RIGHT edge and clamp it to the viewport. The
|
|
300
|
+
root now sits at the right edge with zero width, so the official
|
|
301
|
+
\`left: 0\` would start the 336px panel off-screen; layout.css.ts's
|
|
302
|
+
\`left: 8px\` re-anchor was written for a viewport-width containing block
|
|
303
|
+
that this element is not. Right-anchoring is the one that holds for both
|
|
304
|
+
(2026-08-20: the old pairing put the panel 29px past the right edge). */
|
|
305
|
+
[data-phase] header [data-slot="conversation.session.header.actions"] [class$="_menu"] {
|
|
306
|
+
left: auto !important;
|
|
307
|
+
right: 0 !important;
|
|
308
|
+
width: min(336px, calc(100vw - 32px)) !important;
|
|
309
|
+
max-width: none !important;
|
|
310
|
+
max-height: min(420px, calc(100dvh - 140px)) !important;
|
|
311
|
+
}
|
|
269
312
|
/* The agent-preset mode badge specifically survives the blanket hide
|
|
270
313
|
above: layout.css.ts's shared <=1023px block targets it directly
|
|
271
314
|
(header [class$="_label"]:has(> svg) { display: block !important }),
|
|
@@ -283,6 +326,12 @@ export const HEADER_CSS = `/* ---------- session header five-piece reflow (< 768
|
|
|
283
326
|
[data-phase] header [data-slot="conversation.session.header.actions"] > [data-mobile-nav="header-viewrow"] {
|
|
284
327
|
display: flex !important;
|
|
285
328
|
}
|
|
329
|
+
/* Our own chip lives in the same slot, so the blanket hide above swallows
|
|
330
|
+
it unless it is named here too (it was, on the first build: the chip
|
|
331
|
+
rendered with the right counts and painted nothing). */
|
|
332
|
+
[data-phase] header [data-slot="conversation.session.header.actions"] > [data-mobile-nav="header-activity"] {
|
|
333
|
+
display: inline-flex !important;
|
|
334
|
+
}
|
|
286
335
|
[data-phase] header [data-slot="conversation.session.header.utilities"] > [data-mobile-nav="header-info"],
|
|
287
336
|
[data-phase] header [data-slot="conversation.session.header.utilities"] > [data-mobile-nav="header-workbench"] {
|
|
288
337
|
display: inline-flex !important;
|
|
@@ -360,6 +409,80 @@ export const HEADER_CSS = `/* ---------- session header five-piece reflow (< 768
|
|
|
360
409
|
display:contents on titleCluster does not break that search — so
|
|
361
410
|
top:100% sits directly under the title regardless of the title row's
|
|
362
411
|
actual height, with no hardcoded offset to keep in sync. */
|
|
412
|
+
/* Activity chip (subagents / background tasks) rides the right end of the
|
|
413
|
+
same band. It is a SIBLING of the switch button, not a child — that
|
|
414
|
+
button spans the full row, so nesting would make every tap on the chip
|
|
415
|
+
switch views too — and it shares titleRow as its containing block, so
|
|
416
|
+
top:100% lands both on the same 28px line. z-index puts it above the
|
|
417
|
+
row it overlaps. */
|
|
418
|
+
[data-mobile-nav="header-activity"] {
|
|
419
|
+
position: absolute;
|
|
420
|
+
right: 0;
|
|
421
|
+
top: 100%;
|
|
422
|
+
z-index: 1;
|
|
423
|
+
display: inline-flex;
|
|
424
|
+
align-items: center;
|
|
425
|
+
gap: 9px;
|
|
426
|
+
height: 28px;
|
|
427
|
+
padding: 0 2px 0 10px;
|
|
428
|
+
border: none;
|
|
429
|
+
background: transparent;
|
|
430
|
+
color: var(--dsw-alias-label-secondary, rgba(0, 0, 0, .5));
|
|
431
|
+
font-family: inherit;
|
|
432
|
+
cursor: pointer;
|
|
433
|
+
touch-action: manipulation;
|
|
434
|
+
-webkit-tap-highlight-color: transparent;
|
|
435
|
+
}
|
|
436
|
+
[data-mobile-nav="activity-pill"] {
|
|
437
|
+
display: inline-flex;
|
|
438
|
+
align-items: center;
|
|
439
|
+
gap: 3px;
|
|
440
|
+
height: 28px;
|
|
441
|
+
padding: 0;
|
|
442
|
+
border: none;
|
|
443
|
+
background: transparent;
|
|
444
|
+
color: inherit;
|
|
445
|
+
font-family: inherit;
|
|
446
|
+
font-size: 12px;
|
|
447
|
+
line-height: 18px;
|
|
448
|
+
cursor: pointer;
|
|
449
|
+
touch-action: manipulation;
|
|
450
|
+
-webkit-tap-highlight-color: transparent;
|
|
451
|
+
}
|
|
452
|
+
[data-mobile-nav="activity-pill"]:active {
|
|
453
|
+
opacity: .55;
|
|
454
|
+
}
|
|
455
|
+
[data-mobile-nav="activity-count"] {
|
|
456
|
+
font-variant-numeric: tabular-nums;
|
|
457
|
+
}
|
|
458
|
+
/* Steady green = everything settled. */
|
|
459
|
+
[data-mobile-nav="activity-dot"] {
|
|
460
|
+
display: block;
|
|
461
|
+
width: 6px;
|
|
462
|
+
height: 6px;
|
|
463
|
+
margin-left: 1px;
|
|
464
|
+
border-radius: 50%;
|
|
465
|
+
background: var(--dsw-alias-state-success-primary, #16a34a);
|
|
466
|
+
}
|
|
467
|
+
/* A job that failed or was killed is not a success — never paint it green. */
|
|
468
|
+
[data-activity-state="warning"] [data-mobile-nav="activity-dot"] {
|
|
469
|
+
background: var(--dsw-alias-state-warn-primary, #d97706);
|
|
470
|
+
}
|
|
471
|
+
/* Pulsing blue = still running. Same state palette as the session dot. */
|
|
472
|
+
[data-activity-state="running"] [data-mobile-nav="activity-dot"] {
|
|
473
|
+
background: var(--dsw-alias-state-business-primary, #4f6ef7);
|
|
474
|
+
animation: dsh-zen-activity-pulse 1.4s ease-in-out infinite;
|
|
475
|
+
}
|
|
476
|
+
@keyframes dsh-zen-activity-pulse {
|
|
477
|
+
0%, 100% { opacity: 1; transform: scale(1); }
|
|
478
|
+
50% { opacity: .45; transform: scale(.72); }
|
|
479
|
+
}
|
|
480
|
+
@media (prefers-reduced-motion: reduce) {
|
|
481
|
+
[data-activity-state="running"] [data-mobile-nav="activity-dot"] {
|
|
482
|
+
animation: none;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
363
486
|
[data-mobile-nav="header-viewrow"] {
|
|
364
487
|
position: absolute;
|
|
365
488
|
left: 0;
|
|
@@ -101,14 +101,19 @@ export const HOME_CSS = `/* ---------- phone app shell (< 768px) ---------- */
|
|
|
101
101
|
values, not source-read guesses, are what actually matter here —
|
|
102
102
|
--dsw-alias-bg-base/-layer-1/-layer-2 all resolve to the exact same
|
|
103
103
|
color in the LIGHT theme (neutral-bluish-00, i.e. plain white); they
|
|
104
|
-
only diverge in dark mode.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
104
|
+
only diverge in dark mode.
|
|
105
|
+
|
|
106
|
+
2026-08-20: the page and the CARDS swapped tokens. This surface used
|
|
107
|
+
to be --dsw-specific-sidebar-fill, which made the list page a
|
|
108
|
+
different shade from the session page — measured on-device in dark
|
|
109
|
+
theme, rgb(27,27,28) here against rgb(21,21,23) there, a visible step
|
|
110
|
+
every time you opened a session. The page now takes bg-base, the same
|
|
111
|
+
token the session page and <body> resolve to, so the two screens are
|
|
112
|
+
literally the same colour; the cards took sidebar-fill in exchange, so
|
|
113
|
+
the contrast that separates a row from the page is preserved — it
|
|
114
|
+
just runs the other way (raised card on a base page, the more
|
|
115
|
+
conventional reading of the two anyway). */
|
|
116
|
+
background: var(--dsw-alias-bg-base, #ffffff);
|
|
112
117
|
color: var(--dsw-alias-label-primary, inherit);
|
|
113
118
|
padding-top: var(--mnav-sat);
|
|
114
119
|
transform: translateX(0);
|
|
@@ -226,7 +231,10 @@ export const HOME_CSS = `/* ---------- phone app shell (< 768px) ---------- */
|
|
|
226
231
|
padding: 14px 16px;
|
|
227
232
|
border: none;
|
|
228
233
|
border-radius: 22px;
|
|
229
|
-
|
|
234
|
+
/* The page's old colour (see the swap note on [data-mobile-nav="home"]):
|
|
235
|
+
differs from bg-base in BOTH themes, and is the token
|
|
236
|
+
dsh-better-sidebar's panel already uses for a secondary surface. */
|
|
237
|
+
background: var(--dsw-specific-sidebar-fill, #f5f5f5);
|
|
230
238
|
color: inherit;
|
|
231
239
|
font-family: inherit;
|
|
232
240
|
text-align: left;
|
|
@@ -329,7 +337,8 @@ export const HOME_CSS = `/* ---------- phone app shell (< 768px) ---------- */
|
|
|
329
337
|
margin: 12px 16px;
|
|
330
338
|
padding: 48px 24px;
|
|
331
339
|
border-radius: 22px;
|
|
332
|
-
|
|
340
|
+
/* Stands in for the rows, so it carries the rows' surface. */
|
|
341
|
+
background: var(--dsw-specific-sidebar-fill, #f5f5f5);
|
|
333
342
|
color: var(--dsw-alias-label-secondary, rgba(0, 0, 0, .5));
|
|
334
343
|
font-size: 15px;
|
|
335
344
|
text-align: center;
|