Developer-Dashboard
view release on metacpan or search on metacpan
```
The generated shell helper keeps the same bookmark-aware `cdr`, `dd_cdr`, `d2`, and
`which_dir` functions across all supported shells. `cdr` first tries a saved
alias, then falls back to an AND-matched directory search beneath the alias
root or the current directory depending on whether that first argument was a
known alias. One match changes directory, multiple matches print the list, and
`which_dir` prints the same selected target or match list without changing
directory. The shell-smoke regression coverage also compares those printed
paths by canonical identity, so macOS `/var/...` and `/private/var/...`
aliases do not fail equivalent `pwd` / `which_dir` checks. Bash still uses `\j` for job counts, zsh refreshes `PS1` through a
`precmd` hook with `${#jobstates}`, POSIX `sh` falls back to a prompt command
that does not depend on bash-only prompt escapes, and PowerShell installs a
`prompt` function instead of using the POSIX `PS1` variable.
`d2` is the short shell shortcut for `dashboard`, so after loading the
bootstrap you can run `d2 version`, `d2 doctor`, or `d2 docker compose ps`
without typing the full command name each time.
The same generated bootstrap also wires live tab completion for `dashboard`
and `d2`. Bash registers `_dashboard_complete`, zsh registers
`_dashboard_complete_zsh`, and PowerShell registers `Register-ArgumentCompleter`
for both command names. Completion candidates come from the live runtime
instead of a hardcoded shell list, so built-in commands, layered custom CLI
commands, and installed dotted skill commands all show up in suggestions.
For bash, the generated helper captures completion payloads first instead of
relying on process substitution, which keeps completion responsive on macOS
and inside packaged install-test shells.
The generated bootstrap also wires `cdr`, `dd_cdr`, and `which_dir`
completion. The first argument suggests saved aliases plus matching directory
names beneath the current directory, and later arguments suggest matching
directory basenames beneath the resolved alias root or current directory
without crashing when one subtree is not readable.
For the POSIX shell bootstrap, the generated helper now decodes its JSON
payloads through the same Perl interpreter that generated the shell fragment
instead of a bare `perl -MJSON::XS ...` call. That keeps `cdr` and
`which_dir` stable on macOS installs where `/usr/bin/perl` and a user-local
`~/perl5` XS stack do not belong to the same Perl build. The generated `d2`
shortcut re-enters the `dashboard` script directly instead of hardcoding the
current Perl binary path, so the shortcut still works when the bootstrap is
loaded by a shell whose preferred Perl lives somewhere else.
On Windows, `dashboard shell` auto-selects PowerShell by default, and
interpreter-backed runtime entrypoints such as collector `command` strings,
trusted command actions, saved Ajax files, custom CLI commands, hook files,
and update scripts now resolve `.ps1`, `.cmd`, `.bat`, and `.pl` runners
without assuming `sh` or `bash`. That keeps Strawberry Perl installs usable
without requiring a Unix shell just to load the dashboard runtime.
The checked-in Windows verification assets follow the same layered approach:
fast forced-Windows unit coverage in `t/`, a real Strawberry Perl host smoke in
`integration/windows/run-strawberry-smoke.ps1`, and a host-side rerun helper in
`integration/windows/run-host-windows-smoke.sh` that delegates to
`integration/windows/run-qemu-windows-smoke.sh` for release-grade Windows
compatibility claims. The supported baseline on Windows is PowerShell plus
Strawberry Perl. Git Bash is optional. Scoop is optional. They are setup
helpers, not runtime requirements for the installed `dashboard` command. In
the Dockur-backed path, the launcher stages the Strawberry Perl MSI from the
Linux host into the OEM bundle and can keep multiple retained Windows guests
alive on configurable host web/RDP ports while it reruns the same smoke.
### Browser Access Model
The browser security model follows the original local-first trust concept:
- requests from loopback with a loopback host, such as `127.0.0.1`, `::1`, or `localhost`, are treated as local admin
- requests from loopback with a hostname listed under `web.ssl_subject_alt_names` are also treated as local admin
- requests from non-loopback IPs are treated as helper access
- outsider requests return `401` without a login page until at least one helper user exists
- after a helper user exists, outsider requests receive the helper login page
- helper sessions are file-backed, bound to the originating remote address, and expire automatically
- helper passwords must be at least 8 characters long
The editor and rendered pages also include a shared top chrome with share/source links on the left and the original status-plus-alias indicator strip on the right, refreshed from `/system/status`. That top-right area also includes the local username,...
The displayed address is discovered from the machine interfaces, preferring a VPN-style address when one is active, and the date/time is refreshed in the browser with JavaScript.
`dashboard serve --no-indicators` and `dashboard serve --no-indicator` clear that whole top-right browser-only area without changing the terminal prompt or `/system/status`.
The bookmark editor also follows the old auto-submit flow, so the form submits when the textarea changes and loses focus instead of showing a manual update button.
For saved bookmark files, that browser save posts back to the named
`/app/<id>/edit` route and keeps the Play link on `/app/<id>` instead of a
transient `token=` URL, so updates still work while transient URLs are
disabled.
Bookmark parsing also treats a standalone `---` line as a section
break, preventing pasted prose after a code block from being compiled into the
saved `CODE*` body.
Saved bookmark loads now also normalize malformed bookmark icon bytes from older files before the
browser sees them. Broken section glyphs fall back to `â`, broken item-icon
glyphs fall back to `ð·ï¸`, and common damaged joined emoji sequences such as
`ð§âð»` are repaired so edit and play routes stop showing Unicode replacement
boxes from older bookmark files.
- helper access requires a login backed by local file-based user and session records
This keeps the fast path for loopback-local access while making non-loopback or shared access explicit.
The default web bind is `0.0.0.0:7890`. Trust is still decided from the request origin and host header, not from the listen address.
`DD-OOP-LAYERS` comparisons normalize canonical path identities, so symlinked
aliases such as macOS `/var/...` versus `/private/var/...` do not break layer
discovery, deepest-layer writes, or layered bookmark/nav lookup.
The same portability rule now also applies to the shell-helper and
`locate_dirs_under` regression suites, so equivalent temp roots are compared
by real path identity instead of raw string spelling.
### Runtime Lifecycle
- `dashboard serve` starts the web service in the background by default
- `dashboard serve` starts the configured collector loops alongside the web service, so a plain serve keeps collectors and the web runtime under the same lifecycle action
- `dashboard serve --foreground` keeps the web service attached to the terminal
- `dashboard serve --ssl` enables HTTPS in Starman with the generated local certificate and key, keeps that certificate on a browser-correct SAN profile covering localhost, loopback IPs, the concrete non-wildcard bind host, and any configured `web.ss...
- `dashboard serve --no-editor` and `dashboard serve --no-endit` keep the browser in read-only mode by hiding Share, Play, and View Source chrome, denying `/app/<id>/edit`, `/app/<id>/source`, and bookmark-save POST routes with `403`, and persisting ...
- `dashboard serve --no-indicators` and `dashboard serve --no-indicator` keep normal page rendering and left-side page chrome intact while clearing the whole top-right browser-only chrome area, including the status strip, username, host or IP link, a...
- `dashboard serve logs` prints the combined Dancer2 and Starman runtime log captured in the dashboard log file, `dashboard serve logs -n 100` starts from the last 100 lines, and `dashboard serve logs -f` follows appended output live
- `dashboard serve workers N` saves the default Starman worker count and starts the web service immediately when it is currently stopped; `--host HOST` and `--port PORT` can steer that auto-start path, and `dashboard serve --workers N` or `dashboard ...
- `dashboard stop` stops both the web service and managed collector loops and, on an interactive terminal, prints the full stop task board on `stderr` before work starts so each shutdown step becomes visible instead of silent waiting
- `dashboard restart` stops both, starts configured collector loops again, then starts the web service, and only reports success after the replacement collector loops and web runtime become visible and survive a short post-ready confirmation window, ...
- web shutdown and duplicate detection do not trust pid files alone; they validate managed processes by environment marker or process title and use a `pkill`-style scan fallback when needed
### Environment Customization
After installing with `cpanm`, the runtime can be customized with these environment variables:
( run in 2.289 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )