Install
$ agentstack add skill-cerb-claude-skills-cerb-dev ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Cerb Core Development
Cerb is a 24-year-old PHP/MySQL helpdesk and workflow automation platform built on the Devblocks framework (not Laravel/Symfony). The codebase is mature and follows consistent patterns throughout.
For directory layout, plugin structure, naming conventions, context system, extension points, template paths, and CSS/SCSS: see references/architecture.md.
Creating a New Record Type
See references/new-record-type.md for the complete step-by-step guide.
Quick summary:
- Add
CREATE TABLEmigration inpatches/11.x/11.2.0.php - Run the generator — writes PHP + template files directly, prints only XML snippets:
``bash python3 .claude/skills/cerb-dev/tools/gen-dao.py \ --plugin-id cerberusweb.core \ --table my_record \ --fields "id bigint unsigned NOT NULL AUTO_INCREMENT, name varchar(255) NOT NULL DEFAULT '', created_at int unsigned NOT NULL DEFAULT 0, updated_at int unsigned NOT NULL DEFAULT 0" \ --acl-write all \ --output-dir features/cerberusweb.core ` --acl-write accepts all (default, anyone) or admin` (admins only).
- Insert the printed
plugin.xmlsnippets (class loader + two extensions) - Insert the printed
strings.xmli18n entries - Customize
// [TODO]sections in the generated PHP for non-standard fields
Common Commands
composer build-css # Rebuild cerb.css from SCSS sources
composer cache-clear # Clear template/cache files
composer test # Run platform tests
cd install/docker && docker compose up # Start local dev environment
docker exec -it cerb-mysql-1 mysql -u root -p cerb # Connect to MySQL (password: s3cr3t)
Related Skills
These skills are always installed alongside this one:
/cerb-docs— look up Cerb documentation, features, configuration, integrations/cerb-automations— write or modify Cerb automations (KATA, commands, triggers, events)/cerb-search— build search queries for any record type
Reference Files
references/architecture.md— directory layout, plugin structure, naming conventions, context system, extension points, template paths, CSS/SCSSreferences/dao-pattern.md— DAO class structure, standardgetContext()tokens (_label,_image_url,record_url), database operations, events/deltas, form handling, migration patchesreferences/extensions.md— card widget, cron job, and search index extension patternsreferences/automation-triggers.md— registering a new automation trigger/event (4 spots: trigger class, plugin.xml, patch INSERT, base_rows.sql) and the per-record-typerecord.bulkUpdatebulk-popup wiring viaCerb\Records\BulkUpdate(getMenuItems / handleBulkPost / createJob +bulk_automations.tplinclude)references/automation-commands.md— adding a new top-level automation command/action (8 spots: Action class, ActionNode registry, grammar list,cerberus.js×2, the two_CerbApplication_KataSchemasschemasautomation()/automationPolicy(),Extension_AutomationTrigger::getAutocompleteSuggestionsArray(), +optional asset-automation build interaction) and the simplerapi.command:sub-command pattern (Extension_AutomationApiCommand+ plugin.xml, no framework edits)references/plugin-xml.md— plugin.xml manifest, extension points, class loaders, options block (avatars,cards,comments, etc.), and the/updaterequirement after editsreferences/new-record-type.md— complete guide for creating a new record typereferences/adding-dao-fields.md— adding fields to an existing DAO/model/contextreferences/peek-edit-patterns.md— Smarty gotchas, checkbox groups, dynamic rows, flat lookup sets, avatar save viaupsertWithImagereferences/avatars.md— context avatars: plugin.xmlavatarsoption,_image_urltoken,DAO_ContextAvatar::upsertWithImage,Controller_Avatars::renderMonogramfor fallbacks, anonymous endpointsreferences/login-flow.md—Page_Loginstate machine,clearAllAssign()gotcha, forced dark mode for login, CSRF fail-closed pattern,getErrorMessagecodesreferences/dark-mode-fouc.md— killing the dark-mode flash-of-white on full-page templates (`): the three layers — **** (dark navigation/canvas backdrop, added toheader.tplapp-wide), inlineHTML,BODY {background-color:rgb(32,32,32)}(hardcoded — the CSS var isn't loaded yet), and the decisive **hide-iframe-until-load** trick (#explorerFrame{visibility:hidden}gated on dark + reveal infuncOnLoadoutside the try) for iframe content whose inner doc (header.tplviaborder.tpl) paints white before itscolor-schemeis read. Only 4 templates emit their own; the rest are fragments wrapped byborder.tpl. Remembercomposer cache-clear`references/scss-build.md—cerb.cssis generated from SCSS; build command (sass --no-source-map cerb.scss …); inline-SVG mixin pattern; custom-button native-chrome reset; the legacy globalBUTTON:hover+button:has(>span.cerb-icons):hovergotcha (they hijack a CerbUI button's color AND background — thebackgroundshorthand resets the fill to transparent → white-on-white in light mode; a filled button's:hovermust re-assert bothbackground-colorandcolor, with a:has(>span.cerb-icons)color variant to beat0,2,2)references/ui-conventions.md— JS/UI rules: AJAX helpers (genericAjaxGet/Post/Popup), confirmation dialogs (CerbUI.Confirmfor new code; legacyconfirmPopup(); never nativeconfirm()), custom-button reset patternreferences/smarty-conventions.md— Smarty 4.x template house-style: never use the@modifier prefix (|@countis a Smarty-2 no-op → write|count); plus the checklist of established rules (no unregistered statics →[16384],{literal}around JS{braces, sanitize-in-PHP +{$x nofilter}, no 4-byte emoji,const/let+nonce, entity-escape `` code samples)references/css-utilities.md— the atomiccerb-u-*utility layer (spacing/flex/text/fs/fw/border/cursor/opacity scales) and the relative grayscale systemcerb-u-{bgg,fgg,bdg}-1..10+ adaptivecerb-u-bgg-hover(aliases the--cerb-color-background-contrast-*vars; N = distance from page background, same in light/dark); the reduce-ad-hoc-CSS methodology (hoist atoms, keep component/stateful rules, migrate grays last), gallery-documentation conventions, and the cascade gotcha (inline `beats a utility at equal specificity). Pairs withPLAN-jquery-ui-to-cerb-ui.md`references/cerb-ui.md— thecerb-ui-*design system (CSS + plain-JSCerbUI.*components): build/loading (dev raw source vs prod minifiedcerb-ui.js,composer build-js/dist), naming + token conventions, chartdata-value*/data-text*namespaces + palettes, component inventory (Page/Header/Panel/Chip/Toggle/Distbar/Legend, Dialog, Confirm); the icon system (.cerb-icons.cerb-icon-*Lucide CSS-mask tinted bycurrentColor,$iconsSCSS map,getCerbIcons()); editor-family internals (keyboard shortcuts viaeditorCore.keysmatched one.codenote.key, undo-safe textarea edits viaexecCommand, the folding model/projection) + a Node pure-logic test-harness how-to; the interactive-SVG viz playbook (CerbUI.Map+ the d3-replacement patterns: lib-as-Node-oracle validation,vector-effect:non-scaling-stroke, per-frame loop gating on zoom-change, capture-phase drag-click suppressor, cooperative wheel gesture-origin tracker, d3-color's Bradford-D50 HCL matrix); live examples = the UI Reference gallery, not this docreferences/cerb-ui-charts.md— theCerbUI.Chartchart family that replaced c3.js/d3.js/the legacy canvas plugin (all deleted): the component inventory (CartesianChartbar/line/spline/area with band+time+linear x, y2, mark-agnostic stacking;PieChart;ScatterChartw/axesIndependent;Gauge;Timeblocks), the shared foundation (chart-core.jsscale.linear/band/time+ticks.linear,num.format/duration/percent,date.strftime,ColorScale), and the chart-KATA engine (chart.php::parse→_toChartConfigemits a CerbUI config — server re-target, no client adapter; ONE sharedchart_kata/render.tplfor all 5 render sites,fmtFor/xFmtFor, custom jQuery stats-table legend,_configToColumnsexport). Plus the hard-won GOTCHAs: SVGfill:contrast-140=BLACK (ramp starts at 150), category axis labels must skip the number formatter (NaN),render()re-bind stacks svg listeners → double drill (remove-then-add), point tooltip hide-on-scroll, rotated-label dynamic bottom margin, legend swatch from_seriesColor, wrap dense chart JS in{literal}, pie has no x-column (each key=a slice); the Node DOM-stub headless harness patternreferences/cerb-ui-toolbar.md— theCerbUI.Toolbarcomponent (successor to the deleted$.fn.cerbToolbar()): the render→enhance contract (ui()->toolbar()->parsethenrender($toolbar,$opts)/fetchemitrender_cerbui.tpl`; host JS doesnew CerbUI.Toolbar(ul, OPTS); OPTS pass through tocerbBotTrigger),e.trigger= sourcecarryingclass="cerb-bot-trigger"(legacydonegates still work), **refresh-aware** rebuild oncerb-toolbar--refreshed, itemdata-*reference (icon/icon_at/class/keyboard/badge/badge_color/toggle); the **reusable SCSS hooks** incerb-ui/_toolbar.scss(@mixin cerb-ui-toolbar-strip/-button/-button-active+ public.cerb-ui-toolbar-strip/-button/-button--active/-config-button), the **hybrid recipe** (wrapper@include cerb-ui-toolbar-strip, buttons@include cerb-ui-toolbar-button, flatten embedded--strip) with the **hover-color specificity gotcha** (hover color MUST live in the mixin, not the globalbutton:has(> span.cerb-icons):hover), the inline **config-gear** + **non-interaction items** (search-buttons viaonSelect+data-badge`) + editor-family bridge patternsreferences/cerb-ui-calendar.md— theCerbUI.Calendarcomponent (inline day/week/month/year calendar): the API (constructor opts, source descriptor{id,label,color,fetch|events,serverShape}, normalized event, methods, DOM events), the pure-logiccalendar-core.js(CerbUI.cal:monthGridCells,dedupeServerEventskeyed oncontext_id+ts_range_start,packColumns,assignLanesfor spanning strips), the DST-safe IANA timezone model (epochParts(sec, ianaName)viaIntl; NEVER a fixed offset — it mis-spans winter all-day events by a day in summer), geometry-in-JS/skin-in-CSS rendering, the widget host (Model_Calendar::displayCerbUiWidget+internal/calendar/widget_cerb_ui.tpl+ thec=ui&a=calendarEventsJsonendpoint, no occlusion) shared by the profile/workspace/card widgets (per-instancedefault_view), the reusablec=uiJSON endpoint pattern (genericAjaxGet('','c=ui&a=…')→Controller_UI::_invokeswitch), the spun-outCerbUI.colorutil (idealTextColor/luminance/contrastRatio), and gotchas (globalBUTTON{height:2.4em}clips content buttons →height:auto; headless DOM-stub + full-ICU tz testing)references/worklist-subtotals.md— adding IAbstractViewSubtotals to View classes; correct value_key routing for subtotal click-to-filterreferences/worklist-quick-search.md— IAbstractViewQuickSearch: TYPEVIRTUAL deep-search for linked records, renderVirtualCriteria, renderCriteriaParam label display; the parameterized metric filter (per-worklist key, e.g.usage:/activity:/records:, used by 11 worklists). Single-source series mapSearchFields_X::getMetricFilterMap()built fromDAO_MetricValue::metricFilterSeries($metric, counter|gauge, [query/unit/default])— one row per series,functionsarray (subtotalssum/count/avg/min/max;series.functionselects, bare = default; counter→sum, gauge→avg-no-sum, duration=counter+unit:ms+default:avg). Shared resolver:getDimensionValuesByMetricQuery(null=invalid / []=empty → both0=1, fail loud),validateMetricQuery(parse-time hint),getMetricFilterSubkeySuggestions(autocomplete). The ViewgetQuickSearchMetricFilterMap($key)hook drives BOTH the marquee error hint (viagetParamsFromQuickSearch) AND thefield:()group-scope autocomplete (noexamplesneeded).OPER_CUSTOMgroup parser; reservedsince/until; all-time default.references/worklist-internals.md— getSearchQueryComponents/getPrimaryKey/getParamsQuery for building batch SQL against a worklist filter without pagingreferences/worklist-sparklines.md— adding an inline async sparkline column to a worklist: sharedDAO_MetricValue::getSparklines()+sparkline_loader.tpl, the per-worklist 5-edit checklist (virtual*_sparklinefield, default column, header switcher + cell,viewSparklinesJsonprofileAction, migration reset), series-spec conventions (counter=count/zero, gauge=avg/carry; bar+line colors)references/worklist-distbar.md— adding an inline async distbar (mini stacked-bar) column: shareddistbar_loader.tpl+CerbUI.Distbar, the per-worklist checklist (batchedgetXCountsForRowsDAO query, virtual*_xfield typedTYPE_VIRTUAL_DISTBARfor the chart-bar-stacked picker icon, default column,viewXJsonprofileAction, cell+loader include), comma-joineddistbar_keys/labels/paletteparams, the optional client-side scope switcher (Open|All, no re-fetch,CerbUI.Switcher+ localStorage), and the color-by-index gotcha (carry each segment's color + pass a visible-only palette so hiding a segment doesn't shift colors)references/view-marquee.md— marqueeAppend (visit-bound), setMarqueeContextCreated/Imported helpers, the cerb-peek-trigger binding gotchareferences/queue-system.md— ExtensionQueueConsumer, publish() shutdown semantics, GETLOCK exactly-once completion hook, INSERT...SELECT bulk producer pattern, queuejobchunk stagingreferences/migration-patch.md— patch conventions: platform vs feature patches, idempotency, prefer raw$dbSQL overDAO_CRUD (events/validation/drift) with the import-helper exceptions, writing blobs to storage from a patch, reimporting automations/packagesreferences/record-changeset.md—record_changesetfield version history:DAO_RecordChangeset::create, the superuser-only diff viewer (usable as an admin-only blob store), and the database storage engine table format (storage_, raw chunked blobs) incl. hand-writing a changeset in pure SQL from a patchreferences/support-center.md— Support Center portal: no-browser-editable-Smarty policy (Twig=untrusted, Smarty=chrome),DAO_CommunityToolPropertyper-portal settings, config-tab render/save,usermeet.sc.controllerendpoints,parseMarkdown, and the portal-readable-by-all-workers ACL gotchareferences/rerun-patch.md— how to force a database patch to re-run in developmentreferences/metrics.md— registering and incrementing metrics; the two metric data queries (metrics.timeseriesfor charts,metrics.subtotalsfor flat range aggregates / threshold filters / tables); the dimension storage gotcha (dimN_value_id= literal id for record/number dims,metric_dimension.idfor text/extension dims)references/kata-autocomplete.md— code-editor KATA autocompletion + validation: the client suggestion map (cerbAutocompleteSuggestions.*incerberus.js, path-keyed, static vs dynamic{type}entries), the dynamic-type catalog +parseCompletionsAJAX contract (c=ui&a=kataSuggestions*→[{caption,snippet,docHTML}]), adding a new dynamic type +/uiendpoint (incl.getKataTokenPath/getKataRowByPathsibling lookups), the_CerbApplication_KataSchemasvalidation schema (incl.attributePatternsfor open maps) +kata()->validate()in a save path, and thecerbCodeEditorAutocompleteKatatpl wiringreferences/database-schema.md— canonical schema reference (cerb.schema.kata), column name lookups, common table timestamp colu
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: cerb
- Source: cerb/claude-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.