NAME
Developer::Dashboard::SKILLS - shipped skill authoring reference for Developer Dashboard
SYNOPSIS
# Read the long-form guide in the repository root
perldoc Developer::Dashboard::SKILLS
Skill lifecycle:
dashboard skills install git@github.com:user/example-skill.git
dashboard skills install /absolute/path/to/example-skill
dashboard skills install --ddfile
dashboard skills install
dashboard skills list
dashboard example-skill.hello arg1 arg2
dashboard skills uninstall example-skill
DESCRIPTION
This module is documentation-first. It exists to ship a human-readable skill authoring reference with the distribution and to keep that installed reference available even when a machine no longer has the source checkout.
Use a skill when you want a Git-backed package that can ship:
isolated CLI commands
skill-local hook files with
RESULT,LAST_RESULT, and explicit[[STOP]]controlbrowser pages rendered from
/app/<repo-name>and/app/<repo-name>/<id>skill-local saved Ajax handlers rendered from
/ajax/<repo-name>/...skill-local public assets rendered from
/js/<repo-name>/...,/css/<repo-name>/..., and/others/<repo-name>/...collectors and indicator definitions in skill-local
config/config.jsonthat join the managed fleet under repo-qualified namesan isolated config, docker, state, logs, system-package, and local dependency root
QUICK START
Create a Git repository with at least:
example-skill/
|-- cli/
| `-- hello
|-- config/
| `-- config.json
`-- dashboards/
`-- welcome
Install it:
# from Git
dashboard skills install file:///absolute/path/to/example-skill
# or from a direct checked-out local repo with .git/ and .env VERSION=...
dashboard skills install /absolute/path/to/example-skill
# or install several sources in one ordered batch
dashboard skills install browser foo/bar git@github.com:user/example-skill.git
# singular skill is an alias for skills management commands
dashboard skill list
Repeated dashboard skills install ... calls reinstall or refresh the isolated installed copy instead of failing on an existing repo name, using rsync when it is available for direct local checkouts and a built-in Perl tree-copy fallback when it is not. Each explicit install, including every source in a multi-source command, also appends the exact source to the home root ~/.developer-dashboard/ddfile unless the same non-comment entry already exists. Bare dashboard skills install reads that root ddfile and reinstalls every listed source, which gives operators one update command for all registered skills. Install prints a progress rundown before long work starts and defaults to a table summary with each skill's .env VERSION before and after the install; first-time installs from that root ddfile still report installed even when the skill ships no .env VERSION metadata. Pass -o json for the raw result payload. dashboard skill is only a singular alias for the skills management command family; installed commands still use the dotted dashboard <skill>.<command> form. If the home runtime already has ~/.developer-dashboard/.gitignore, each install also appends skills/<repo-name>/ without duplicates so cloned skill trees stay out of runtime Git status. An existing ~/.developer-dashboard/.gitiignore spelling is honored for compatibility.
Run an operator manifest install from the current directory:
dashboard skills install --ddfile
If ddfile exists there, each listed source installs into the base home-layer skills root at ~/.developer-dashboard/skills/<repo-name>/ even when the command is run from a deeper child .developer-dashboard/ layer. If ddfile.local exists there, each listed source installs into the current directory's nested skills/<repo-name>/ tree instead. When both manifests are present, ddfile runs first and ddfile.local runs second. Repeated dashboard skills install --ddfile runs also act as reinstall and refresh for existing targets.
Run its command:
dashboard example-skill.hello
Open its bookmark:
/app/example-skill
/app/example-skill/welcome
/ajax/example-skill/status?type=text
/js/example-skill/app.js
LAYOUT
Installed skills live under the active DD-OOP-LAYERS skills roots such as ~/.developer-dashboard/skills/<repo-name>/ or <project>/.developer-dashboard/skills/<repo-name>/. Installing a skill writes into the deepest participating layer. Resolving a skill by repo name also follows DD-OOP-LAYERS, so the deepest matching repo name is the active skill and shadows the same repo name from higher layers.
The prepared layout is:
- cli/
-
Executable skill commands. These are run through
dashboard <repo-name>.<command>and are not installed into the system PATH. Nested skill trees underskills/<repo-name>/cli/also stay reachable through the same dotted syntax across multiple nested levels, soskills/foo/skills/bar/cli/bazis invoked asdashboard <repo-name>.foo.bar.baz. - cli/<command>.d/
-
Executable hook files for a command. They run in sorted order before the main command. Their results are serialized into
RESULT, the immediate previous hook is exposed throughLAST_RESULT, and oversized hook payloads spill intoRESULT_FILEorLAST_RESULT_FILEbefore later skill hook or command execs would hit the kernel arg/env limit. Later hooks stop only when a hook writes[[STOP]]tostderr. Executable .go hooks run throughgo run. Executable .java hooks compile withjavacand then run throughjava. - config/config.json
-
Skill-owned JSON config. Developer Dashboard guarantees the file exists, does not impose a rich schema, and merges it into the effective dashboard config under
_<repo-name>. If the skill declarescollectorsthere, those collectors join the normal managed fleet under names such asexample-skill.status, so serve, restart, stop, prompt rendering, and browser status treat them the same way they treat system-owned collectors. - config/docker/
-
Reserved root for skill-local Docker or Compose files. The dispatcher exposes this path through
DEVELOPER_DASHBOARD_SKILL_DOCKER_ROOT, and docker service lookup includes installed skill docker roots from each participating runtime layer instead of treating the home skill tree as the only skill-docker source. - dashboards/
-
Bookmark instruction files shipped by the skill, including
dashboards/indexfor/app/<repo-name>.Top-level skill routes are:
/app/<repo-name>and/app/<repo-name>/<page>/ajax/<repo-name>/<file>/js/<repo-name>/<file>,/css/<repo-name>/<file>, and/others/<repo-name>/<file>
Nested child skills under
skills/<sub-skill>/extend those same prefixes, for example/app/<repo-name>/<sub-skill>,/ajax/<repo-name>/<sub-skill>/<file>, and/js/<repo-name>/<sub-skill>/<file>.Developer Dashboard resolves the longest installed skill prefix first and, if the skill-local ajax or public asset file does not exist, falls back to the normal nested saved-bookmark file path instead of assuming the leading path segments must always belong to a skill.
-
Skill nav fragments and bookmark pages loaded into the skill app routes. They also join the shared nav strip rendered above normal saved
/app/<page>routes such as/app/index, so multiple installed skills can contribute top-level nav at once. - state/
-
Persistent skill-owned state.
- logs/
-
Persistent skill-owned logs.
- ddfile
-
Optional dependent skill list installed after package managers run.
- ddfile.local
-
Optional local dependent skill list installed after
ddfileinto the same skills root as the current skill install target. - aptfile
-
Optional Debian-family system package declaration. When present, Developer Dashboard checks each listed package first, prints only the missing packages, and installs those through
sudo apt-get install -y. - brewfile
-
Optional macOS Homebrew package declaration. When present, Developer Dashboard prints the requested package list and installs it through
brew install. - package.json
-
Optional Node dependency declaration. When present, Developer Dashboard runs
npm install <dependency-spec...>inside a private dashboard staging workspace and then merges the resulting packages into$HOME/node_modules. - cpanfile
-
Optional shared Perl dependency declaration. When present, Developer Dashboard runs
cpanm --notest -L ~/perl5 --cpanfile cpanfile --installdeps <skill-root>. - cpanfile.local
-
Optional skill-local Perl dependency declaration. When present, Developer Dashboard runs
cpanm --notest -L <skill-root>/perl5 --cpanfile cpanfile.local --installdeps <skill-root>.
SKILL COMMANDS AND HOOKS
Skill commands are file-based commands. Create runnable files such as:
cli/report
cli/report.pl
cli/report.sh
cli/report.ps1
Do not rely on a directory-backed run pattern for skill commands. That pattern belongs to dashboard-wide custom CLI commands under ~/.developer-dashboard/cli/<command>/run or ./.developer-dashboard/cli/<command>/run.
Hook files live under cli/<command>.d/ and:
must be executable to run
run in sorted filename order
have their
stdout,stderr, and exit codes captured intoRESULTexpose the immediate previous hook payload through
LAST_RESULTrun executable .go hooks through
go runcompile executable .java hooks with
javacand then run them throughjavaskip later hooks only when a hook writes
[[STOP]]tostderrdo not treat plain non-zero exit status as an implicit stop
SKILL ENVIRONMENT
Skill hooks and commands currently receive these environment variables:
DEVELOPER_DASHBOARD_SKILL_NAMEDEVELOPER_DASHBOARD_SKILL_ROOTDEVELOPER_DASHBOARD_SKILL_COMMANDDEVELOPER_DASHBOARD_SKILL_CLI_ROOTDEVELOPER_DASHBOARD_SKILL_CONFIG_ROOTDEVELOPER_DASHBOARD_SKILL_DOCKER_ROOTDEVELOPER_DASHBOARD_SKILL_STATE_ROOTDEVELOPER_DASHBOARD_SKILL_LOGS_ROOTDEVELOPER_DASHBOARD_SKILL_LOCAL_ROOTRESULTLAST_RESULTPERL5LIB
If the skill has installed Perl dependencies, PERL5LIB is prefixed with the shared ~/perl5/lib/perl5 tree and then any participating skill-local perl5/lib/perl5 trees from the inherited skill layers.
BOOKMARKS
Skill bookmark files live under dashboards/.
Current route surface:
app index:
/app/<repo-name>app page:
/app/<repo-name>/<id>list bookmarks:
/skill/<repo-name>/bookmarksrender bookmark:
/skill/<repo-name>/bookmarks/<id>
Examples:
/app/example-skill
/app/example-skill/welcome
/skill/example-skill/bookmarks/welcome
/skill/example-skill/bookmarks/nav/help.tt
Important current behavior:
the list route only lists top-level files
nested bookmark files can still be rendered directly when the path is known
the skill app and older compatibility routes are render surfaces, not browser edit/source surfaces
SKILL COLLECTOR FLEET
Skill collectors are declared inside the skill's config/config.json:
{
"collectors": [
{
"name": "status",
"command": "printf 'ok'",
"cwd": "home",
"indicator": {
"label": "Example Skill",
"icon": "E"
}
}
]
}
When that skill is installed, the collector joins the same managed fleet used by the main dashboard config. The runtime qualifies the collector name with the repo name, so the effective collector becomes example-skill.status instead of a bare status. That qualified name is what the collector runner uses for loop metadata, process titles, and managed indicator rows.
Operationally that means:
dashboard servestarts skill collectors together with the system fleetdashboard restartrestarts both the system collectors and the installed skill collectorsdashboard stopstops the whole managed collector fleet, including skillscollector indicator config in the skill file feeds the same prompt and browser status surfaces as system-owned collectors
BOOKMARK LANGUAGE
Bookmark files use the original separator-line syntax with directives such as:
TITLE:ICON:BOOKMARK:NOTE:STASH:HTML:CODE1:and otherCODE*blocks
Rules that matter:
TITLE:sets the browser title and is exposed to templates astitleEarlier
CODE*blocks run before final template renderingReturned hashes merge into stash
Printed
STDOUTbecomes visible runtime outputSTDERRbecomes visible error output---can also act as a section separator
BOOKMARK HELPERS
The bookmark bootstrap exposes:
fetch_value(url, target, options, formatter)stream_value(url, target, options, formatter)stream_data(url, target, options, formatter)
Bookmark pages can also use the built-in /js/jquery.js compatibility shim for $, $(document).ready(...), and $.ajax(...).
For normal saved runtime bookmarks, Ajax(file => 'name', ...) can create stable saved Ajax endpoints. That capability is tied to the saved runtime bookmark path. Skill bookmarks render through the skill route surface, so do not assume stable saved /ajax/<file> handlers there unless you have tested that path explicitly.
NAV AND DASHBOARD-WIDE CLI
Normal runtime bookmarks support shared nav/*.tt fragments above non-nav saved pages. Skill pages auto-load dashboards/nav/* into /app/<repo-name> and /app/<repo-name>/... routes, and the same installed skill nav fragments are also rendered above normal saved /app/<page> routes such as /app/index. Skills can still render files such as dashboards/nav/help.tt directly through /skill/<repo-name>/bookmarks/nav/help.tt.
Dashboard-wide custom CLI hooks are separate from skill hooks. They live under ./.developer-dashboard/cli/<command>.d or ~/.developer-dashboard/cli/<command>.d and are used for normal dashboard <command> commands. They can also use directory-backed run commands, which skill commands do not currently use.
FAQ
Do I need every folder?
No. Use the parts your skill actually needs.
Can a skill expose browser pages?
Yes, through dashboards/ with /app/... routes and the older /skill/.../bookmarks/... route.
Can a skill ship collectors or indicators?
Yes. Declare them in the skill's config/config.json. They join the managed fleet under repo-qualified names such as example-skill.status, and their indicator config participates in the normal prompt and browser status flow.
Can I use isolated Perl dependencies?
Yes. Ship a cpanfile for shared skill dependencies in ~/perl5, and ship a cpanfile.local when that skill also needs a skill-local ./perl5 tree.
Can a skill install system packages first?
Yes. Ship a ddfile for dependent skills, a ddfile.local for dependent skills that must stay at the current install level, an aptfile for Debian-family packages, an apkfile for Alpine packages, a dnfile for Fedora packages, a brewfile for macOS packages, or a package.json for Node dependencies that should land under $HOME/node_modules. The explicit operator manifest order for dashboard skills install --ddfile is the deferred ddfile - ddfile.local> pass, while the automatic per-skill dependency order is aptfile - apkfile -> dnfile -> brewfile -> package.json -> cpanfile -> cpanfile.local -> ddfile -> ddfile.local>.
Where is the long-form guide?
The repository ships a separate skill authoring guide, while the installed distribution keeps this POD available through perldoc.
SEE ALSO
Developer::Dashboard, Developer::Dashboard::SkillManager, Developer::Dashboard::SkillDispatcher
PURPOSE
This module is documentation-only and ships the long-form skill authoring reference inside the installed distribution. It explains the skill directory layout, command and hook model, bookmark routing, isolated dependency root, and environment variables visible to skill commands.
WHY IT EXISTS
It exists because a source-tree-only markdown guide is not enough for tarball and CPAN installs. The skill system needs a shipped manual that survives installation and can be read through perldoc on a machine that does not have the Git checkout.
WHEN TO USE
Use this file when the skill feature gains new layout rules, command semantics, environment variables, or bookmark routing behavior, or when the shipped skill authoring manual needs to stay aligned with the repository's separate skill authoring guide.
HOW TO USE
Treat it as installed reference documentation. Keep its content synchronized with the repository's separate skill authoring guide and focus on explaining how skill authors should structure repos and commands rather than on internal implementation details.
WHAT USES IT
It is used by perldoc Developer::Dashboard::SKILLS, by release metadata checks that compare the shipped docs to the repository skill authoring guide, and by contributors authoring or reviewing dashboard skills.
EXAMPLES
Example 1:
perl -Ilib -MDeveloper::Dashboard::SKILLS -e 1
Do a direct compile-and-load check against the module from a source checkout.
Example 2:
prove -lv t/19-skill-system.t t/20-skill-web-routes.t
Run the focused regression tests that most directly exercise this module's behavior.
Example 3:
HARNESS_PERL_SWITCHES=-MDevel::Cover prove -lr t
Recheck the module under the repository coverage gate rather than relying on a load-only probe.
Example 4:
prove -lr t
Put any module-level change back through the entire repository suite before release.