S

SideButton Dashboard Knowledge Module

SideButton Dashboard Skills Management — Knowledge Module

SideButton Dashboard knowledge module — UI selectors, data model, and page states documenting Skills Management.

Available free v0.4.0 Browser
$ sidebutton install sidebutton-dashboard
Download ZIP

Skills Management

What This Is

The Skills page is the primary management interface for installed skill packs. It displays all skill packs as expandable cards showing their roles, modules, and workflows. Users can toggle individual roles ON/OFF, expand packs to browse modules and run workflows, install new packs (via Library redirect), uninstall packs, and reload all skill data. User Actions (custom workflows from the /actions directory) appear as a separate section.

The Module Detail View (/skills/{domain}/{module}) is a dedicated sub-page that shows a module's skill documentation status, full workflow list with run buttons, associated roles, and recent execution history.

URL Patterns

ViewURLNotes
Skills List/skillsMain list of all installed skill packs + user actions
Skill Detail/skills/{domain}Same SkillsView component, auto-expands the specified pack
Module Detail/skills/{domain}/{module}Module-level detail: skill doc, workflows, roles, recent runs

Legacy redirects: /actions/skills, /actions/{id}/skills

Page Structure — Skills List (/skills)

+--[Header: "Skills" + "+ Install" button + Reload icon]--+
|                                                          |
|  [Skill Pack Card 1]                                     |
|    pack-icon + Title + domain·version·counts + badge     |
|    Chevron (expand/collapse)                             |
|    [Expanded: Roles section (h4)]                        |
|      role-dot + role-name + ON/OFF toggle-btn            |
|    [Expanded: Modules section (h4)]                      |
|      module-header (button) → module-name + count        |
|      [Expanded module: module-skill-doc + workflow-list] |
|        workflow-item: wf-name + ▶ play button            |
|    [pack-actions: View Run Logs + Uninstall]             |
|                                                          |
|  [Skill Pack Card 2...]                                  |
|                                                          |
|  [User Actions Card (.pack-card.user-actions)]           |
|    ⚡ icon + "User Actions" + action count               |
|    [Expanded: workflow-list with ▶ + 🗑 per action]     |
|                                                          |
+----------------------------------------------------------+

Page Structure — Module Detail (/skills/{domain}/{module})

+--[Header: Back to Dashboard + H1 displayName + domain]--+
|                                                          |
|  [Skill Context section]       (only if hasSkillDoc)     |
|    context-card: "_skill.md" + description               |
|                                                          |
|  [Workflows section]                                     |
|    list-card with list-row items:                        |
|      row-id (monospace) + row-title + ▶ Run button       |
|                                                          |
|  [Roles section]               (only if hasRoles.length) |
|    list-card with list-row items:                        |
|      role filename + ".md"                               |
|                                                          |
|  [Recent Runs section]         (only if recentRuns > 0)  |
|    list-card with clickable list-row items:              |
|      status-icon (✓/✗/—) + workflow_id + time + duration|
|                                                          |
+----------------------------------------------------------+

Key Elements — Skills List

Header

ElementSelectorNotes
Page titleheading "Skills"H1 in page header
Install buttonbutton "+ Install".btn.btn-secondary. Navigates to Library page
Reload buttonbutton (SVG icon only).btn.btn-ghost. Calls /api/reload, refreshes all data

Skill Pack Card

ElementSelectorNotes
Pack card.pack-cardContainer for each skill pack
Pack header.pack-headerClickable div — toggles expansion. Hover changes background
Pack icon.pack-iconPackage emoji (📦)
Pack titleh3 inside .pack-infoPack display name (title field, falls back to name)
Pack metadata.pack-meta"{domain} · v{version} · {N} modules · {N} workflows · {N} roles". Separator is · (U+00B7 middle dot)
Toggle badge.toggle-badgeON (green, .on) / OFF (gray, .off) / PARTIAL (amber, .partial). Click toggles ALL roles
Chevron.chevronSVG arrow, gains .expanded class when open → rotate(180deg)

Role List (inside expanded pack)

ElementSelectorNotes
Section headingh4 "Roles"Inside .pack-section. Uppercase, small caps style
Role item.role-itemRow container per role
Role dot.role-dot8px circle. Green (.enabled) when role.enabled !== false, gray otherwise
Role name.role-nameText label, flex-1
Role toggle.toggle-btn"ON" (green, .on) or "OFF" (gray). Click calls PUT /api/context/roles/{filename} then reloads

Module List (inside expanded pack)

ElementSelectorNotes
Section headingh4 "Modules"Inside .pack-section
Module item.module-itemWrapper per module
Module header.module-header<button> element — clickable, toggles module expansion
Module chevron.chevron inside .module-header14px, gains .expanded when module is open
Module name.module-nameDisplay name, flex-1
Module workflow count.module-count"{N} workflow" or "{N} workflows" (pluralized)
Skill doc indicator.module-skill-docOnly shown when mod.hasSkillDoc is true. Text: "_skill.md: {displayName} — selectors, data model, states"

Workflow List (inside expanded module)

ElementSelectorNotes
Workflow item.workflow-itemRow container. Hover shows surface background
Workflow name.wf-nameWorkflow title (wf.title)
Play buttonbutton.btn.btn-sm"▶" text only (no "Play" label). Runs runWorkflow(wf.id, {}) then navigates to Execution view

Pack Footer Actions

ElementSelectorNotes
Footer container.pack-actionsFlex row at bottom of expanded pack body. Has top border
View Run Logsbutton "View Run Logs".btn.btn-ghost.btn-sm. Navigates to run logs view
Uninstallbutton "Uninstall".btn.btn-danger.btn-sm. Triggers browser confirm() dialog

User Actions Section

ElementSelectorNotes
User Actions card.pack-card.user-actionsSeparate card, only rendered when userActions.length > 0
Icon.pack-iconLightning bolt emoji (⚡)
Titleh3 "User Actions"Inside .pack-info
Metadata.pack-meta"Custom workflows from /actions directory · {N} actions"
Action play buttonbutton.btn.btn-sm"▶" — runs the action workflow
Action delete buttonbutton.btn.btn-sm.btn-ghost"🗑" — triggers confirm() dialog then calls deleteAction(action.id)
Actions container.wf-actionsFlex row wrapping play + delete buttons

Empty State

ElementSelectorNotes
Empty card.empty-cardShown when $skillPacks.length === 0
Messageh3 "No Skill Packs Installed"Heading inside .empty-card
Descriptionp"Install a skill pack from the Library to get domain-specific modules, workflows, and roles."
Install CTAbutton "Go to Library".btn.btn-primary. Navigates to /library

Loading State

ElementSelectorNotes
Loading text.loadingCentered. Text is "Loading skills..." (not just "Loading...")

Key Elements — Module Detail View

Header (Module Detail)

ElementSelectorNotes
Back button.back-btn"← Back to Dashboard" with SVG arrow icon. Calls navigateBack()
Module title.header-title h1Module displayName, 24px bold
Domain label.header-domainDomain string from $viewState.selectedSkillDomain, secondary color

Skill Context Section

ElementSelectorNotes
Sectionsection.section with h2 "Skill Context"Only rendered when mod.hasSkillDoc is true
Context card.context-cardFlex row, card background, bordered
File label.context-file"_skill.md" in monospace bold
Description.context-desc"Selectors, data model, states, gotchas" in secondary color

Workflows Section

ElementSelectorNotes
Sectionsection.section with h2 "Workflows ({N})"Always rendered when module is found
List container.list-cardCard with border, overflow hidden
Workflow row.list-rowFlex row, bottom-bordered. Last row has no border
Workflow ID.row-idMonospace, min-width: 120px, muted color
Workflow title.row-title14px, primary text color
Run button.run-btn"▶ Run" text. On hover turns primary color. Calls runWorkflow(wf.id, {})

Roles Section

ElementSelectorNotes
Sectionsection.section with h2 "Roles"Only rendered when mod.hasRoles.length > 0
Role row.list-rowEach role filename displayed as "{role}.md"
Role text.row-titleRole filename string with .md suffix appended

Recent Runs Section

ElementSelectorNotes
Sectionsection.section with h2 "Recent Runs"Only rendered when recentRuns.length > 0
Run row.list-row.clickableClickable — navigates to Run Log Detail via navigateToRunLogDetail(run.id)
Status icon.status-icon"✓" (green, .success) / "✗" (red, .failed) / "—" (neutral)
Workflow ID.row-titleShows run.workflow_id
Run meta.row-metaFlex row with time-ago and formatted duration
Time agospan inside .row-metae.g., "5m ago", "2h ago", "1d ago", "just now"
Durationspan inside .row-metae.g., "430ms", "12s", "2m 5s"

Loading States (Module Detail)

StateElementNotes
Loading.loading text "Loading module..."While fetching module data
Not found.loading text "Module not found"When module path not found in results

Data Model

Skill Pack (InstalledPack)

FieldTypeNotes
namestringPack identifier (e.g., "sidebutton-dashboard")
domainstringDomain pattern (e.g., "test-app.venmate.net")
titlestringDisplay name (falls back to name if absent)
versionstringSemver (e.g., "2.0.0")

Skill Pack Detail (SkillPackDetail)

FieldTypeNotes
rolesRoleContext[]Array of role objects (see below)
workflowCountnumberTotal workflow count across all modules

Role Context (RoleContext)

FieldTypeNotes
filenamestringRole file basename (used in API path)
namestringDisplay name
matchstringURL/domain match pattern
enabledbooleantrue = active. Treated as true when enabled !== false (undefined → enabled)
bodystringRole prompt body content

Skill Module (SkillModule)

FieldTypeNotes
namestringModule identifier (used as path segment)
pathstringFull path used to match module in fetchSkillModules results
displayNamestringHuman-readable name shown in UI
workflowCountnumberCount of workflows in this module
workflowsarray{ id: string, title: string }[] — full workflow list
hasSkillDocbooleanWhether a _skill.md exists for this module
hasRolesstring[]Array of role filenames associated with this module (empty array = no roles)

User Action (Action)

FieldTypeNotes
idstringAction identifier (used as workflow_id when running)
titlestringDisplay name shown in UI
descriptionstringOptional description
paramsarrayParameter definitions

Run Log Metadata (RunLogMetadata)

FieldTypeNotes
idstringUnique run identifier
workflow_idstringID of the workflow that ran
statusstring"success" / "failed" / other
timestampstringISO timestamp string
duration_msnumberExecution duration in milliseconds

States

Skills List States

StateTriggerVisual Indicator
LoadingInitial data fetch.loading with "Loading skills..." centered
DefaultLoad complete, packs installedPack cards collapsed, metadata visible
Expanded packClick .pack-headerChevron rotates 180°, roles + modules sections visible
Expanded moduleClick .module-header buttonModule chevron rotates, skill doc indicator + workflow list visible
All roles ONAll roles enabled in packGreen "ON" badge (.toggle-badge.on)
All roles OFFAll roles disabledGray "OFF" badge (.toggle-badge.off)
Partial rolesMix of enabled/disabledAmber "PARTIAL" badge (.toggle-badge.partial)
No rolesPack has zero rolesBadge defaults to "OFF" state
Empty$skillPacks.length === 0.empty-card with "Go to Library" CTA
Running workflowClick play buttonNavigates to Execution view

Module Detail States

StateTriggerVisual Indicator
LoadingFetching module data"Loading module..." centered in .loading
Module not foundPath not matched in results"Module not found" centered in .loading
Loaded — with skill docmod.hasSkillDoc === trueSkill Context section rendered
Loaded — no skill docmod.hasSkillDoc === falseSkill Context section absent
Has rolesmod.hasRoles.length > 0Roles section rendered
Has recent runsAt least one matching run in last 50 logsRecent Runs section rendered
No recent runsNo matching runsRecent Runs section absent entirely
Running workflowClick "▶ Run"Navigates to Execution view
Navigating to runClick run rowNavigates to Run Log Detail view

Toggle Badge Colors

StateCSS ClassBackgroundText ColorNotes
ON.toggle-badge.onvar(--color-success-light)var(--color-success)All roles enabled
OFF.toggle-badge.offvar(--color-border)var(--color-text-muted)All roles disabled or zero roles
PARTIAL.toggle-badge.partial#fef3c7 (hardcoded)#d97706 (hardcoded)Mix of enabled/disabled. NOT using CSS variable

Common Tasks

  1. View installed skill packs: Navigate to /skills. Cards show pack name, domain, version, module/workflow/role counts
  2. Expand skill pack details: Click .pack-header → roles and modules sections appear
  3. Toggle all roles in pack: Click ON/OFF/PARTIAL badge → toggles ALL roles to opposite state (OFF→all on, ON or PARTIAL→all off)
  4. Toggle individual role: Expand pack → find role → click .toggle-btn
  5. Browse module workflows: Expand pack → click .module-header button → workflow list visible
  6. Run a workflow from pack: Expand pack → expand module → click "▶" play button → navigates to Execution view
  7. View module detail: Navigate to /skills/{domain}/{module} — shows skill doc status, full workflow list, roles, recent runs
  8. Run a workflow from module detail: Click "▶ Run" button in workflow row
  9. Navigate to a run log: Click a Recent Runs row → navigates to Run Log Detail
  10. Install new pack: Click "+ Install" → redirects to Library page
  11. Uninstall pack: Expand pack → click "Uninstall" in .pack-actions → confirm browser dialog
  12. Reload all data: Click reload icon in header → all packs/roles/workflows refreshed from disk
  13. View run logs: Click "View Run Logs" in .pack-actions → navigates to run logs view
  14. Delete user action: Expand User Actions → click "🗑" on action → confirm browser dialog

Tips

  • Toggle badge aggregate logic: ON = all roles enabled, OFF = all disabled OR pack has no roles, PARTIAL = mix. One click on the badge toggles all roles in the pack
  • Pack detail vs. Skills list: /skills/{domain} uses the same SkillsView component but auto-expands the named pack — it is NOT the same as ModuleDetailView
  • Module detail is a separate view: /skills/{domain}/{module} renders ModuleDetailView.svelte, not SkillsView
  • Recent runs are filtered: Module detail loads last 50 run logs globally, then filters to those whose workflow_id matches one of the module's workflows. Only the first 10 matches are shown
  • Module matching by path: ModuleDetailView calls fetchSkillModules(domain) and finds the module where m.path === $viewState.selectedModulePath
  • User Actions only show when non-empty: The .pack-card.user-actions section is conditionally rendered; it does not appear at all when there are zero user actions
  • hasRoles is an array, not a boolean: Unlike hasSkillDoc (boolean), mod.hasRoles is a string[] of role filenames. Condition is .length > 0
  • Reload is global: The reload button calls /api/reload which re-reads all skill files, roles, and workflows from disk

Gotchas

  • Uninstall uses browser confirm(): Native browser dialog — cannot be intercepted by snapshot/click alone. Needs browser dialog event handling or page.on('dialog', ...) in automation
  • Delete action also uses confirm(): Same native dialog pattern as Uninstall — dialog text is Delete "{action.title}"?
  • Role enabled defaults to true: The condition role.enabled !== false means a role with enabled: undefined is treated as enabled. Only explicit false disables it
  • Pack toggle logic: OFF → enable all; ON → disable all; PARTIAL → disable all. There is no "enable all" path from PARTIAL
  • PARTIAL badge uses hardcoded amber: background: #fef3c7; color: #d97706 — not var(--color-warning). Cannot be overridden via CSS variable
  • Expand state is component-local: Expanding/collapsing packs and modules is stored in component $state — resets on any navigation away from /skills
  • Module detail routing caveat: Navigating directly to /skills/{domain}/{module} in the browser address bar returns a 404 JSON response from the server. Must navigate via in-app (click or navigate() from within the SPA)
  • Module detail back button: .back-btn calls navigateBack() — goes to whatever the previous view was, not necessarily /skills
  • Reload triggers full data refetch: After reloadAll(), loadData() is called again fetching all packs and their details in parallel. If any pack detail fails, it is silently skipped (logged to console only)
  • Play button in SkillsView has no label: The "▶" run button in the pack card workflow list has NO text label. The "▶ Run" label only appears in ModuleDetailView