, etc.) and does NOT defend against argument injection. A\npayload like `params => ['-r --some-flag /etc/passwd']` would still split\nacross addit\n[…]\nrg-injection token quoting and the allow-list deny/empty/allow paths\n(`ExecuteTaskTest.php`). Refresh the docs section to describe the new\nescaping primitive and the production allow-list requirement.", "is_bot": false, "headline": "Harden ExecuteTask with per-arg escapeshellarg and allow-list (#485)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-05-02T14:36:55Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "34e805092aa7b1f472f21f9711fe6df232654425", "body": "Using 'escape' => false also disables HTML escaping of attributes (URL, classes, title), not just the title text. The narrower 'escapeTitle' => false keeps attribute escaping on while still allowing the icon HTML in the title.", "is_bot": false, "headline": "Use escapeTitle instead of escape in pagination element (#483)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-04-30T23:07:42Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "64c95715882c02f8756c8d6be20e1d5d569829bd", "body": "The legacy raw-serialized branch in EmailTask::run() previously called unserialize() without an allowed_classes restriction, so a queue job whose 'class' was a Message subclass but whose 'settings' string contained a different gadget-chain class would deserialize that gadget. Anyone who can enqueue \n[…]\ninto RCE.\n\nPin the deserialization to the same Message subclass that was already validated for instantiation. Modern app code that passes settings as an array via EmailTask::serialize() is unaffected.", "is_bot": false, "headline": "Restrict unserialize to the configured Message class (#484)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-04-30T23:07:30Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "53865a78d0acf43a1e40e23e1d72429ba2b66d2e", "body": null, "is_bot": false, "headline": "Use ServerRequest import in app.example.php (CS fix)", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-04-30T15:52:41Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "7c0e6b45b5e678671faf2422d236aaf266d60b97", "body": null, "is_bot": false, "headline": "Document Queue.adminAccess in app.example.php", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-04-30T15:17:09Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "19d73a87dc6fb8bf7ea7e90e8a2ca5942902cbe1", "body": "The Queue admin UI can trigger jobs (via AddFromBackendInterface tasks),\nreset / remove queued jobs, and terminate workers. Accidental exposure\nis operational damage waiting to happen.\n\nMirror the captcha plugin's \"fail closed\" pattern: the host app MUST\nconfigure Queue.adminAccess as a Closure that\n[…]\nan\n example role-based gate.\n\nBackwards-incompatible: existing installs that just relied on host\nAppController gating will 403 until they add a Closure. Migration is\none line in config/bootstrap.php.", "is_bot": false, "headline": "Default-deny admin access via Queue.adminAccess Closure (#481)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-04-30T13:43:24Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "72e35b0213067db0819da22ca5dd33a135158c8f", "body": "* Sweep stale queue_processes rows on worker startup\n\nWorkers that die without graceful shutdown (SIGKILL, OOM, container\nrestart, anything that bypasses the SIGTERM handler) leave their\nqueue_processes row behind with terminate=0. Without intervention these\nghost rows accumulate and count toward Qu\n[…]\nat.\n\nRemoving both keeps the cleanup discipline clear (one canonical sweep\npoint per worker lifecycle) and saves a couple of needless DELETE\nqueries per worker. No behaviour change for the happy path.", "is_bot": false, "headline": "Sweep stale queue_processes rows on worker startup (#480)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-04-30T11:23:28Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "0e8126f22e31f54d6aa1d41afa86cfeffe32d2cc", "body": null, "is_bot": false, "headline": "Adjust CS badge", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-04-28T16:58:43Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "39cf2e7a79ebea4b6aef6d8741a0865f916d4d38", "body": "* Add Queue.workerLifetimeJitter config to stagger worker shutdowns\n\nEach worker picks a random offset in [0, workerLifetimeJitter] at startup\nand adds it to its effective lifetime. Prevents thundering-herd restarts\nwhen a fleet of workers (e.g. ECS/Kubernetes tasks) is spawned at the\nsame instant a\n[…]\nainst a legacy CakePHP 2.x fork) by\nRommel Penaflor (@xrompdev) in #475; ported to the modern processor.\n\n* Add workerLifetimeJitter to app.example.php\n\n* Align worker lifetime jitter with PHP timeout", "is_bot": false, "headline": "Add Queue.workerLifetimeJitter to stagger worker shutdowns (#476)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-04-27T13:13:33Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "0294a066343ea79dd2c9daabd5688ee28b094de2", "body": "* Move mobile-nav background to CSS class (strict-CSP)\n\nDrops the inline `style=\"background: linear-gradient(...)\"` attribute on the\nmobile offcanvas in favour of a `.queue-mobile-nav-bg` class that reuses the\nexisting `--queue-sidebar-bg` custom property. Removes the\n`style-src 'unsafe-inline'` req\n[…]\n's existing nonced `\u003cscript>`\n reads them and assigns to `el.style` (JS-driven style mutation is not\n subject to `style-src 'unsafe-inline'`).\n\nTemplates now contain zero inline `style=` attributes.", "is_bot": false, "headline": "Move mobile-nav background to CSS class (strict-CSP) (#479)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-04-26T22:29:25Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "ef13c13820f29c7a2cd1a52d2a3132f1a019a108", "body": "- Add nonce attribute to inline \u003cscript> blocks (layout, stats chart)\n- Replace postLink+confirm with postButton+data-confirm-message across\n all admin templates to eliminate inline onclick handlers that CSP\n blocks without unsafe-inline / unsafe-hashes\n- JS delegate in the layout already intercep\n[…]\nnts and replicates the confirmation UX\n\nThis lets the admin UI work under a strict script-src CSP\n(e.g. \"script-src 'self' 'nonce-X' 'unsafe-eval'\") without needing\n'unsafe-inline' or 'unsafe-hashes'.", "is_bot": false, "headline": "Refactor admin UI to be CSP-compatible (#477)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-04-22T23:10:45Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "bd2ccf02e194a688f6007225b21bd6146bb8ff3c", "body": "AddInterface::add() returns void and may silently skip queuing a job\nwhen required configuration is missing — most notably EmailTask, which\ndoes nothing when Config.adminEmail is not set.\n\nPreviously the controller showed a green success flash regardless,\nmaking it look like the admin UI had queued \n[…]\n't.\n\nNow we count QueuedJobs before/after invoking the task. If the count\ndid not increase, we show an error flash pointing the operator at the\nlikely config gap, instead of falsely reporting success.", "is_bot": false, "headline": "Fix silent no-op in Queue::addJob when task does not queue a job (#478)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-04-22T23:10:32Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "54105129a38ced1ce5f0b4ac601a35a00b42ebd0", "body": "… (#474)\n\n* Fix EmailTask undefined-method errors for serialized Message settings\n\nKeys coming from Message::__serialize()/jsonSerialize (htmlMessage,\ntextMessage, appCharset) don't map to set\u003cProp>() methods on Mailer or\nMessage, so passing them via queued JSON payloads failed with\n'Call to undefin\n[…]\nblem as the address maps: string keys would otherwise be\ninterpreted as named arguments when the generic loop spreads them into\n`setHeaders()`. Forward the map as a single positional argument instead.", "is_bot": false, "headline": "Fix EmailTask undefined-method errors for serialized Message settings…", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-04-17T18:05:18Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "6eda87a2320430787169c0b90b02d76bba817a31", "body": "…472)\n\n* Fix EmailTask named-parameter error for associative address arrays\n\nPHP 8 treats string keys in the argument array of call_user_func_array()\nas named parameters, so queued payloads with an associative email => name\nmap for to/from/cc/bcc/replyTo would fail with 'Unknown named parameter'.\n\nRoute address setters through a helper that unpacks list-shaped values\npositionally (preserving the prior behavior) and forwards associative\nmaps as a single positional argument.\n\n* Fix CS", "is_bot": false, "headline": "Fix EmailTask named-parameter error for associative address arrays (#…", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-04-17T14:00:30Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "a534d1f8e8d6478dc374025c0bba59a48be9876f", "body": null, "is_bot": false, "headline": "Fix pre element overflow in standalone layout", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-04-02T14:53:55Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "08ba64b9b3f97460cef364a04ce3b3c47adb2d28", "body": "Sets explicit Bootstrap 5 templates to avoid app/Tools templates\naffecting the standalone admin layout.", "is_bot": false, "headline": "Make pagination element fully standalone.", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-28T14:12:15Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "5cea4b0241cc0cc29670ebfd2fc3348f9c53325f", "body": "Extract flash rendering logic into flash/flash.php element for cleaner\nlayout code and easier maintenance.", "is_bot": false, "headline": "Refactor flash rendering to use dedicated element.", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-28T13:45:29Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "2a37a1145bd7ce55814a0f62f6ae8346ab1332c9", "body": null, "is_bot": false, "headline": "Fix datetime fields.", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-28T13:38:28Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "58c2bf6ca258839195e5407b0afb07b1f2c24157", "body": null, "is_bot": false, "headline": "Fix datetime fields.", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-28T13:24:12Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "697206e83ee638c69ddc05f2e5795a0366c47261", "body": "When invalid JSON is submitted via the data edit form, the\nJsonableBehavior threw a TypeError because json_decode returned null\nbut the return type was array.\n\nChanges:\n- Update _fromJson() to throw InvalidArgumentException with a\n descriptive error message instead of TypeError\n- Catch the exceptio\n[…]\nlid input so they can fix it\n- Add data_string virtual property annotation to QueuedJob entity\n- Add test for invalid JSON handling\n- Fix PHPStan errors: handle nullable description() in example tasks", "is_bot": false, "headline": "Fix TypeError when editing queued job with invalid JSON payload (#468)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-03-28T12:57:06Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "ba99af3b86fbb258e45950d79b201c5bd7b9cf59", "body": null, "is_bot": false, "headline": "Fix PHPStan errors: add type annotations for list query results (#467)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-03-19T20:47:46Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "6ab3291329a62e91f22b173dfa75cfbe9dc70e86", "body": null, "is_bot": false, "headline": "Fix PHPStan errors for nullable description passed to io->out()", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-18T23:03:14Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "4de7db1a840a109a67bcae4fb9a8d7cf6f58a05a", "body": null, "is_bot": false, "headline": "Add descr.", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-18T22:52:36Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "1d41261d6067f91a7ccb54dbebcf82a61d9bcc2d", "body": null, "is_bot": false, "headline": "Add 'standalone-ui' to composer.json keywords", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-03-18T20:49:14Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "c63f624f7a5e1b51830ea1fb891c9f1a6878b488", "body": "* Add multi-connection support for multiple databases\n\nAdd support for running queue workers and admin interface across\nmultiple database connections (e.g., primary and secondary databases).\n\nFeatures:\n- Configure connections via Queue.connections array in config\n- Connection switcher dropdown in ad\n[…]\nion to persist connection choice across requests\n- Query param ?connection=xxx sets session value\n- Connection switcher redirects to dashboard to avoid 404s\n- Fix CS issue with RuntimeException import", "is_bot": false, "headline": "Add multi-connection support for multiple databases (#465)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-03-18T17:52:40Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "9f240b75ecc795c8f20df0b60bfde19898611058", "body": null, "is_bot": false, "headline": "Fix Icon helper loading - only load if Templating plugin available", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-18T17:05:12Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "3eb9ec48861b7be437658b65473c1e4c11d96306", "body": null, "is_bot": false, "headline": "Add fallbacks for Tools/Shim helpers when plugins not loaded", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-18T17:03:01Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "8781022aa908e0e1ee9490abcec358fc45ad0e0b", "body": null, "is_bot": false, "headline": "Add pagination element fallback when Tools plugin is not loaded", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-18T16:58:10Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "43291e8fb11e93f086e02f55250d71129d85bcfd", "body": null, "is_bot": false, "headline": "Add standalone option to app.example.php", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-18T16:44:35Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "6639108fbfee7d23b5c5e821496b013c84e4f17f", "body": null, "is_bot": false, "headline": "Document Queue.standalone config option", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-18T16:42:11Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "54097a4ea4632e7d07b921b52e95824b2e8913c9", "body": "By default, QueueAppController extends App\\Controller\\AppController\nto inherit app authentication, components, and configuration (BC).\n\nSet `Queue.standalone` to `true` for an isolated admin that doesn't\ndepend on the host app's AppController setup.", "is_bot": false, "headline": "Restore AppController extension with standalone opt-in (#464)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-03-18T16:40:53Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "241f31d400c7521bebc7d9dd3f775e084d663ccb", "body": "* Add heatmap analytics for job activity visualization\n\n- Add getHeatmapData() method to QueuedJobsTable for aggregating jobs by day/hour\n- Add heatmap action to QueuedJobsController with filters for metric, days, and job type\n- Add heatmapColor() helper method for color gradient\n- Create heatmap te\n[…]\nd in layout)\n- Use expr() instead of deprecated newExpr()\n- Add comprehensive tests for getHeatmapData() method\n- Add tests for heatmapColor() helper method\n- Add controller tests for heatmap() action", "is_bot": false, "headline": "Add heatmap analytics for job activity visualization (#463)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-03-18T05:05:50Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "320c07b3183a6dedc99c312dcf38f5a255181011", "body": "- Add isRestarted() helper method to detect jobs that were manually reset\n (have attempts but no failure_message)\n- Show \"Restarted\" badge (info/cyan) in all templates between Requeued and Running\n- Previously these jobs incorrectly showed as \"Running\"\n- Add comprehensive tests for isRestarted()", "is_bot": false, "headline": "Add Restarted status for manually reset jobs", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-18T04:31:25Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "0b50781e66dd6f375a0a5db2651acb1df7c562f5", "body": "* Add modern isolated admin dashboard with Bootstrap 5\n\n- Create QueueAppController as isolated base for admin controllers\n- Add queue.php layout with Bootstrap 5.3.3 and Font Awesome 6.7.2 via CDN\n- Add reusable elements: sidebar, stats_card, status_badge, flash messages\n- Update admin templates wi\n[…]\nove dashboard stats display\n\n- Reorder stats cards: Scheduled → Pending → Running → Failed\n (follows job lifecycle chronologically)\n- Add safeguard against negative pendingJobs count with max(0, ...)", "is_bot": false, "headline": "Add modern isolated admin dashboard with Bootstrap 5 (#461)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-03-18T04:14:08Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "1baab99eeb73f77553bce89bbdf0e293cae01a2e", "body": "The duration() method is specific to the Tools TimeHelper. Applications\nnot using the Tools plugin would get a fatal error. This adds a\nmethod_exists check with a fallback to PHP's DateInterval::format().\n\nPort of #462 to master.", "is_bot": false, "headline": "Add runtime fallback for Tools Time->duration() method", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-17T21:51:39Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "32de0da594563ffd7ebd31d42ae80cba8b4e3796", "body": null, "is_bot": false, "headline": "Fix CS", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-17T19:57:52Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "e60221ff99cdf3a202e9d9c56776200adf35391e", "body": "JsonableBehavior now uses Queue\\Database\\Type\\ArrayType instead of\nShim\\Database\\Type\\ArrayType, removing the undocumented dependency\non dereuromark/cakephp-shim.", "is_bot": false, "headline": "Add local ArrayType to remove hidden Shim plugin dependency", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-17T19:53:28Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "f58ec4d15c378e33b716cf1c17b92288c7e65796", "body": "- relLengthOfTime() falls back to timeAgoInWords() from CakePHP core\n- Format->ok() calls now use Queue.ok element which has built-in fallback", "is_bot": false, "headline": "Add runtime fallbacks for Tools plugin dependencies in admin templates", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-17T19:49:19Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "465fa28eb73022edad5378a0d56281329735824f", "body": null, "is_bot": false, "headline": "Enable phpcs cache for faster subsequent runs", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-15T15:35:52Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "8dc1db72045b6a563b4ebe9af5dbab50072773f8", "body": null, "is_bot": false, "headline": "Improve composer.json metadata", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-13T14:51:21Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "b4ad201c5705d06f12efa1b0cdb0cba66aff07bd", "body": null, "is_bot": false, "headline": "Add admin-panel keyword", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-03-13T14:43:43Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "0a52e9cc962f3325da79106670a92cd62e352453", "body": null, "is_bot": false, "headline": "Fix PHPStan type errors with entity annotations", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-02-28T00:02:48Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "474b5622a107772921159b0611d31c822ee41479", "body": null, "is_bot": false, "headline": "Allow PHPUnit 13", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-02-06T23:54:07Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "fab07eea73cd9e5744c7913b898e32ec8795989c", "body": "- cakephp-tools ^3.12.0: fixes Message::addAttachment() signature\n incompatibility with CakePHP 5.3\n- friendsofcake/search ^7.7.0: fixes searchManager/isSearch/searchParams\n behavior call deprecations on CakePHP 5.3", "is_bot": false, "headline": "Bump minimum cakephp-tools and search plugin versions (#460)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-01-31T04:41:29Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "7d7da44c7e5b0228bf936efda7829d10367b7745", "body": null, "is_bot": false, "headline": "Upgrade migrations dev dep", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-01-31T04:14:55Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "798f9afb1f1247e3175a4f8018c0372416e096b0", "body": "* Auto-detect captureOutput based on output column existence\n\nInstead of requiring explicit `Queue.captureOutput` configuration,\nthe Processor now auto-detects whether to capture output by checking\nif the `output` column exists on the `queued_jobs` table.\n\nExplicit config still takes precedence. The\n[…]\ntest\n\nWrap getSchema()->hasColumn() in try/catch to handle mock tables in tests\n(and any edge case in production). Suppress E_USER_DEPRECATED in\nInfoCommandTest that deliberately uses old config keys.", "is_bot": false, "headline": "Auto-detect captureOutput based on output column existence (#459)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-01-29T17:56:25Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "b8b9e5d6cb4f99170c0547457f706f124cd25f40", "body": "* Add optional output capture for queue jobs\n\nIntroduce a new `Queue.captureOutput` config option that, when enabled,\ncaptures task stdout/stderr output and stores it in a new `output` text\ncolumn on the `queued_jobs` table. This allows reviewing job output in\nthe admin panel after execution, which \n[…]\nemory\n\nWorkerCommand.php:\n- Fix defaultName() collision with JobCommand (was 'queue job',\n now 'queue worker')\n\nQueueProcessesTable.php:\n- Sanitize PID/signal as integers in terminateProcess() exec()", "is_bot": false, "headline": "Add optional output capture for queue jobs (#458) - fix edge case issues", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-01-29T10:37:06Z", "body_truncated": true, "is_coding_agent": false }, { "oid": "d8fd7254593dbdacede4952e1197ab3cff8b3de7", "body": null, "is_bot": false, "headline": "Update brick/varexporter version requirement", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-01-28T05:12:47Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "f8a4435f12ea4c6ece94579dfeb51520242cc712", "body": null, "is_bot": false, "headline": "Raise PHP Min Version", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-01-28T05:02:40Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "1418afb3860c5b2f153aa57005e98c41187b6aee", "body": "Add generic events for queue job lifecycle:\n- Queue.Job.created: when job is added to queue\n- Queue.Job.started: when job processing starts\n- Queue.Job.completed: when job completes successfully\n- Queue.Job.failed: when job fails\n\nAdd CakeSentryEventBridge listener that bridges these events to\nCakeSentry.Queue.* events for lordsimal/cakephp-sentry integration.\nUsers can enable it with: EventManager::instance()->on(new CakeSentryEventBridge())", "is_bot": false, "headline": "Add Queue.Job.* lifecycle events with optional Sentry bridge. (#453)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-01-11T03:10:38Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "3800ca14b53ee82f13dba8ee08aedbe970f44e30", "body": "varexporter v7", "is_bot": false, "headline": "Merge pull request #457 from dereuromark/fix-docs-syntax", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-01-07T00:42:03Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "726c675e53f9c2c4bba2165948b9fc0415657947", "body": null, "is_bot": false, "headline": "varexporter v7", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-01-07T00:35:20Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "2e46f97519a39848a7c2519a6b51118fbe6dff20", "body": "Fix missing semicolons in configuration.md examples", "is_bot": false, "headline": "Merge pull request #456 from dereuromark/fix-docs-syntax", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-01-04T05:01:27Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "31e29f7d9c84ed84a10e8d90b30bccaaff807be0", "body": null, "is_bot": false, "headline": "Fix missing semicolons in configuration.md examples", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-01-04T04:59:21Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "e1c944f36cc9f255b3a0c4910e8c9e59de454a87", "body": "…time\n\nAdd real-time progress documentation with Mercure/FrankenPHP", "is_bot": false, "headline": "Merge pull request #451 from dereuromark/docs/frankenphp-mercure-real…", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-01-04T02:32:16Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "6fccb5b13f37bd14ad4af0571d934a3d0aa1135c", "body": "Add getDescription() to all commands", "is_bot": false, "headline": "Merge pull request #455 from dereuromark/add-command-descriptions", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-01-04T02:30:41Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "514ee88233de0f2ded727c513ce5a560d23a9ef7", "body": null, "is_bot": false, "headline": "Add getDescription() to all commands", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-01-04T02:19:54Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "b74d00be179ab07d0373553ec162a98320b40a1e", "body": "Make Icon configuration optional with text fallback", "is_bot": false, "headline": "Merge pull request #454 from dereuromark/feature/optional-icon-config", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2026-01-01T16:54:32Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "99731ec588af6be75106336bbe934707ede71f85", "body": "- Conditionally load Icon helper only when Icon.sets is configured\n- Add icon element with text fallback for when icons are not configured\n- Update templates to use the icon element\n\nThe backend UI now works without Icon.sets configured, showing text\nlabels like [View], [Edit], [Del] instead of icons.", "is_bot": false, "headline": "Make Icon configuration optional with text fallback", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2026-01-01T16:48:13Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "4bd3f8bb801e32fde5ba5d8d1f2eb4072c4ad9d0", "body": "Documents the PID 1 issue when running queue workers in Docker containers\nand provides solutions using stable hostnames and startup cleanup commands.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)", "is_bot": false, "headline": "Add Docker/docker-compose deployment documentation", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2025-12-20T01:04:17Z", "body_truncated": false, "is_coding_agent": true }, { "oid": "e447805c1e945c58c03d3d4d02e14acb01c67e61", "body": "Instead of warning when a task timeout exceeds the requeue timeout,\nautomatically cap it to prevent duplicate execution.", "is_bot": false, "headline": "Auto-cap task timeout to defaultRequeueTimeout.", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2025-12-19T22:17:13Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "18ac9872d9ff331513de2109ed49e76cdb6b503e", "body": null, "is_bot": false, "headline": "Allow config overwrite on vendor tasks.", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2025-12-19T22:12:27Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "ef5ac978c5adc028a2794cc831902d1dd7ec4c15", "body": "Documents how to display live queue job progress in the browser using:\n- Mercure protocol with Server-Sent Events\n- FrankenPHP with built-in Mercure hub\n- Example queue task with progress publishing\n- Controller and template examples\n- Production deployment with systemd/supervisor\n- Worker scaling configuration", "is_bot": false, "headline": "Add real-time progress documentation with Mercure/FrankenPHP", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2025-12-19T18:51:00Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "ce69d1fff33dc784bc5c43ee83c199def0489f62", "body": null, "is_bot": false, "headline": "Add readable config ints.", "author_name": "mscherer", "author_login": "dereuromark", "committed_at": "2025-12-11T19:55:01Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "486dce3ddf5026d2c2f75f951d522f9cc6d7d14e", "body": "Support both the legacy queue_phinxlog table (Migrations plugin 4.x)\nand the new cake_migrations table (Migrations plugin 5.x).\n\nThe migration now checks if cake_migrations exists and uses it with\nthe plugin column filter, otherwise falls back to queue_phinxlog.", "is_bot": false, "headline": "Add support for unified cake_migrations table (#450)", "author_name": "Mark Scherer", "author_login": "dereuromark", "committed_at": "2025-12-11T19:49:05Z", "body_truncated": false, "is_coding_agent": false } ], "releases_count": 100, "commits_last_year": 145, "latest_release_at": "2026-06-06T20:11:41Z", "latest_release_tag": "8.15.1", "releases_from_tags": false, "days_since_last_push": 0, "active_weeks_last_year": 32, "days_since_latest_release": 56, "mean_days_between_releases": 9 }, "community": { "has_readme": true, "has_license": true, "has_description": true, "has_contributing": true, "health_percentage": 57, "has_issue_template": false, "has_code_of_conduct": false, "has_pull_request_template": false }, "ecosystem": { "packages": [ { "name": "dereuromark/cakephp-queue", "exists": true, "license": "MIT", "keywords": [ "queue", "cakephp", "background", "async", "jobs", "admin-panel", "workers", "deferred tasks", "standalone-ui" ], "ecosystem": "packagist", "matches_repo": true, "registry_url": "https://packagist.org/packages/dereuromark/cakephp-queue", "is_deprecated": false, "latest_version": "8.15.1", "repository_url": "https://github.com/dereuromark/cakephp-queue", "versions_count": 136, "total_downloads": 997463, "dependents_count": 16, "deprecation_note": null, "maintainers_count": null, "monthly_downloads": 38799, "first_published_at": null, "latest_published_at": "2026-06-06T16:09:37Z", "latest_version_yanked": null, "days_since_latest_publish": 56 } ] }, "popularity": { "forks": 138, "stars": 308, "watchers": 19, "fork_history": { "days": [ { "date": "2013-01-25", "count": 1 }, { "date": "2013-07-05", "count": 1 }, { "date": "2013-12-27", "count": 1 }, { "date": "2014-02-13", "count": 1 }, { "date": "2014-03-19", "count": 1 }, { "date": "2014-04-16", "count": 1 }, { "date": "2014-06-22", "count": 1 }, { "date": "2014-07-16", "count": 1 }, { "date": "2014-08-05", "count": 1 }, { "date": "2014-09-02", "count": 1 }, { "date": "2014-12-11", "count": 1 }, { "date": "2015-02-16", "count": 1 }, { "date": "2015-02-17", "count": 1 }, { "date": "2015-02-19", "count": 1 }, { "date": "2015-02-23", "count": 1 }, { "date": "2015-03-16", "count": 1 }, { "date": "2015-05-10", "count": 1 }, { "date": "2015-06-15", "count": 1 }, { "date": "2015-07-08", "count": 1 }, { "date": "2015-07-31", "count": 1 }, { "date": "2015-08-04", "count": 1 }, { "date": "2015-08-07", "count": 1 }, { "date": "2015-08-12", "count": 1 }, { "date": "2015-08-16", "count": 1 }, { "date": "2015-08-22", "count": 1 }, { "date": "2015-11-18", "count": 1 }, { "date": "2015-12-28", "count": 1 }, { "date": "2016-01-05", "count": 1 }, { "date": "2016-01-07", "count": 1 }, { "date": "2016-01-22", "count": 1 }, { "date": "2016-01-24", "count": 1 }, { "date": "2016-01-25", "count": 1 }, { "date": "2016-02-18", "count": 1 }, { "date": "2016-03-12", "count": 1 }, { "date": "2016-03-17", "count": 1 }, { "date": "2016-04-07", "count": 1 }, { "date": "2016-04-20", "count": 1 }, { "date": "2016-04-27", "count": 1 }, { "date": "2016-04-30", "count": 1 }, { "date": "2016-06-17", "count": 1 }, { "date": "2016-07-08", "count": 1 }, { "date": "2016-08-05", "count": 1 }, { "date": "2016-08-12", "count": 1 }, { "date": "2016-08-17", "count": 1 }, { "date": "2016-09-02", "count": 1 }, { "date": "2016-10-14", "count": 1 }, { "date": "2016-10-22", "count": 1 }, { "date": "2016-11-16", "count": 1 }, { "date": "2016-12-01", "count": 1 }, { "date": "2016-12-28", "count": 1 }, { "date": "2017-01-09", "count": 1 }, { "date": "2017-03-15", "count": 1 }, { "date": "2017-03-20", "count": 1 }, { "date": "2017-04-10", "count": 1 }, { "date": "2017-04-26", "count": 1 }, { "date": "2017-04-27", "count": 1 }, { "date": "2017-05-29", "count": 1 }, { "date": "2017-06-01", "count": 1 }, { "date": "2017-06-30", "count": 1 }, { "date": "2017-07-03", "count": 1 }, { "date": "2017-07-10", "count": 1 }, { "date": "2017-10-04", "count": 1 }, { "date": "2017-10-20", "count": 1 }, { "date": "2018-03-01", "count": 1 }, { "date": "2018-03-14", "count": 1 }, { "date": "2018-04-30", "count": 1 }, { "date": "2018-05-06", "count": 1 }, { "date": "2018-06-19", "count": 1 }, { "date": "2018-08-10", "count": 1 }, { "date": "2018-09-07", "count": 1 }, { "date": "2018-11-14", "count": 2 }, { "date": "2018-11-29", "count": 1 }, { "date": "2018-12-28", "count": 1 }, { "date": "2019-01-15", "count": 1 }, { "date": "2019-02-09", "count": 1 }, { "date": "2019-03-04", "count": 1 }, { "date": "2019-03-15", "count": 1 }, { "date": "2019-04-22", "count": 1 }, { "date": "2019-05-10", "count": 1 }, { "date": "2019-05-12", "count": 1 }, { "date": "2019-06-25", "count": 1 }, { "date": "2019-07-11", "count": 1 }, { "date": "2019-08-01", "count": 1 }, { "date": "2019-08-13", "count": 1 }, { "date": "2019-09-09", "count": 1 }, { "date": "2019-12-09", "count": 1 }, { "date": "2019-12-12", "count": 1 }, { "date": "2019-12-29", "count": 1 }, { "date": "2020-01-03", "count": 1 }, { "date": "2020-01-23", "count": 1 }, { "date": "2020-06-08", "count": 1 }, { "date": "2020-06-22", "count": 1 }, { "date": "2020-09-08", "count": 1 }, { "date": "2020-10-21", "count": 1 }, { "date": "2021-01-26", "count": 1 }, { "date": "2021-05-24", "count": 1 }, { "date": "2021-06-30", "count": 1 }, { "date": "2021-07-07", "count": 1 }, { "date": "2021-07-14", "count": 1 }, { "date": "2021-10-10", "count": 1 }, { "date": "2021-12-22", "count": 1 }, { "date": "2022-01-02", "count": 1 }, { "date": "2022-01-12", "count": 1 }, { "date": "2022-03-16", "count": 1 }, { "date": "2022-03-21", "count": 1 }, { "date": "2022-04-15", "count": 1 }, { "date": "2022-05-20", "count": 1 }, { "date": "2022-08-18", "count": 1 }, { "date": "2022-08-19", "count": 1 }, { "date": "2022-08-22", "count": 1 }, { "date": "2022-10-18", "count": 1 }, { "date": "2022-10-25", "count": 1 }, { "date": "2022-11-02", "count": 1 }, { "date": "2022-12-18", "count": 1 }, { "date": "2023-01-03", "count": 1 }, { "date": "2023-01-09", "count": 1 }, { "date": "2023-02-09", "count": 1 }, { "date": "2023-02-14", "count": 1 }, { "date": "2023-02-23", "count": 1 }, { "date": "2023-04-03", "count": 1 }, { "date": "2023-07-20", "count": 1 }, { "date": "2023-09-13", "count": 1 }, { "date": "2024-05-06", "count": 1 }, { "date": "2024-06-21", "count": 1 }, { "date": "2024-09-19", "count": 1 }, { "date": "2024-10-24", "count": 1 }, { "date": "2025-03-18", "count": 1 }, { "date": "2025-05-07", "count": 1 }, { "date": "2025-08-23", "count": 1 }, { "date": "2025-11-22", "count": 1 }, { "date": "2026-03-31", "count": 1 }, { "date": "2026-06-14", "count": 1 }, { "date": "2026-07-15", "count": 1 } ], "complete": true, "collected": 134, "total_forks": 138 }, "star_history": null, "open_issues_and_prs": 0 }, "ai_readiness": { "has_nix": false, "example_dirs": [], "has_llms_txt": false, "has_dockerfile": false, "has_mcp_signal": false, "bootstrap_files": [], "api_schema_files": [], "has_devcontainer": false, "typecheck_configs": [], "toolchain_manifests": [], "largest_source_bytes": 37884, "source_files_sampled": 161, "oversized_source_files": 0, "agent_instruction_files": [], "agent_instruction_max_bytes": null }, "dependencies": { "manifests": [ "composer.json", "docs/package.json" ], "advisories": { "error": null, "scope": "repository_graph", "source": "osv", "findings": [ { "name": "vite", "direct": false, "version": "5.4.21", "severity": "high", "ecosystem": "npm", "cvss_score": 7.5, "advisory_ids": [ "GHSA-4w7w-66w2-5vf9", "GHSA-fx2h-pf6j-xcff", "GHSA-v6wh-96g9-6wx3" ], "fixed_version": "8.0.16", "advisory_count": 3, "oldest_advisory_days": 117 }, { "name": "esbuild", "direct": false, "version": "0.21.5", "severity": "moderate", "ecosystem": "npm", "cvss_score": 5.3, "advisory_ids": [ "GHSA-67mh-4wv8-2f99" ], "fixed_version": "0.25.0", "advisory_count": 1, "oldest_advisory_days": 537 } ], "collected": true, "malicious": [], "truncated": false, "by_severity": { "high": 1, "moderate": 1 }, "advisory_count": 4, "affected_count": 2, "assessed_count": 173, "malicious_count": 0, "assessed_package": null, "unassessed_count": 13, "direct_affected_count": 0 }, "ecosystems": [ "npm", "packagist" ], "dependencies": [ { "name": "brick/varexporter", "manifest": "composer.json", "ecosystem": "packagist", "version_constraint": "^0.5.0 || ^0.6.0 || ^0.7.0" }, { "name": "cakephp/cakephp", "manifest": "composer.json", "ecosystem": "packagist", "version_constraint": "^5.1.1" } ], "all_dependencies": { "error": null, "source": "github-sbom", "packages": [ { "name": "brick/varexporter", "direct": true, "version": null, "ecosystem": "packagist" }, { "name": "cakephp/cakephp", "direct": true, "version": null, "ecosystem": "packagist" }, { "name": "@algolia/abtesting", "direct": false, "version": "1.18.0", "ecosystem": "npm" }, { "name": "@algolia/autocomplete-core", "direct": false, "version": "1.17.7", "ecosystem": "npm" }, { "name": "@algolia/autocomplete-plugin-algolia-insights", "direct": false, "version": "1.17.7", "ecosystem": "npm" }, { "name": "@algolia/autocomplete-preset-algolia", "direct": false, "version": "1.17.7", "ecosystem": "npm" }, { "name": "@algolia/autocomplete-shared", "direct": false, "version": "1.17.7", "ecosystem": "npm" }, { "name": "@algolia/client-abtesting", "direct": false, "version": "5.52.0", "ecosystem": "npm" }, { "name": "@algolia/client-analytics", "direct": false, "version": "5.52.0", "ecosystem": "npm" }, { "name": "@algolia/client-common", "direct": false, "version": "5.52.0", "ecosystem": "npm" }, { "name": "@algolia/client-insights", "direct": false, "version": "5.52.0", "ecosystem": "npm" }, { "name": "@algolia/client-personalization", "direct": false, "version": "5.52.0", "ecosystem": "npm" }, { "name": "@algolia/client-query-suggestions", "direct": false, "version": "5.52.0", "ecosystem": "npm" }, { "name": "@algolia/client-search", "direct": false, "version": "5.52.0", "ecosystem": "npm" }, { "name": "@algolia/ingestion", "direct": false, "version": "1.52.0", "ecosystem": "npm" }, { "name": "@algolia/monitoring", "direct": false, "version": "1.52.0", "ecosystem": "npm" }, { "name": "@algolia/recommend", "direct": false, "version": "5.52.0", "ecosystem": "npm" }, { "name": "@algolia/requester-browser-xhr", "direct": false, "version": "5.52.0", "ecosystem": "npm" }, { "name": "@algolia/requester-fetch", "direct": false, "version": "5.52.0", "ecosystem": "npm" }, { "name": "@algolia/requester-node-http", "direct": false, "version": "5.52.0", "ecosystem": "npm" }, { "name": "@babel/helper-string-parser", "direct": false, "version": "7.27.1", "ecosystem": "npm" }, { "name": "@babel/helper-validator-identifier", "direct": false, "version": "7.28.5", "ecosystem": "npm" }, { "name": "@babel/parser", "direct": false, "version": "7.29.3", "ecosystem": "npm" }, { "name": "@babel/types", "direct": false, "version": "7.29.0", "ecosystem": "npm" }, { "name": "@docsearch/css", "direct": false, "version": "3.8.2", "ecosystem": "npm" }, { "name": "@docsearch/js", "direct": false, "version": "3.8.2", "ecosystem": "npm" }, { "name": "@docsearch/react", "direct": false, "version": "3.8.2", "ecosystem": "npm" }, { "name": "@esbuild/aix-ppc64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/android-arm", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/android-arm64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/android-x64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/darwin-arm64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/darwin-x64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/freebsd-arm64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/freebsd-x64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/linux-arm", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/linux-arm64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/linux-ia32", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/linux-loong64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/linux-mips64el", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/linux-ppc64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/linux-riscv64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/linux-s390x", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/linux-x64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/netbsd-x64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/openbsd-x64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/sunos-x64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/win32-arm64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/win32-ia32", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@esbuild/win32-x64", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "@iconify-json/simple-icons", "direct": false, "version": "1.2.80", "ecosystem": "npm" }, { "name": "@iconify/types", "direct": false, "version": "2.0.0", "ecosystem": "npm" }, { "name": "@jridgewell/sourcemap-codec", "direct": false, "version": "1.5.5", "ecosystem": "npm" }, { "name": "@rollup/rollup-android-arm-eabi", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-android-arm64", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-darwin-arm64", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-darwin-x64", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-freebsd-arm64", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-freebsd-x64", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-linux-arm-gnueabihf", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-linux-arm-musleabihf", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-linux-arm64-gnu", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-linux-arm64-musl", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-linux-loong64-gnu", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-linux-loong64-musl", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-linux-ppc64-gnu", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-linux-ppc64-musl", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-linux-riscv64-gnu", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-linux-riscv64-musl", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-linux-s390x-gnu", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-linux-x64-gnu", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-linux-x64-musl", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-openbsd-x64", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-openharmony-arm64", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-win32-arm64-msvc", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-win32-ia32-msvc", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-win32-x64-gnu", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@rollup/rollup-win32-x64-msvc", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "@shikijs/core", "direct": false, "version": "2.5.0", "ecosystem": "npm" }, { "name": "@shikijs/engine-javascript", "direct": false, "version": "2.5.0", "ecosystem": "npm" }, { "name": "@shikijs/engine-oniguruma", "direct": false, "version": "2.5.0", "ecosystem": "npm" }, { "name": "@shikijs/langs", "direct": false, "version": "2.5.0", "ecosystem": "npm" }, { "name": "@shikijs/themes", "direct": false, "version": "2.5.0", "ecosystem": "npm" }, { "name": "@shikijs/transformers", "direct": false, "version": "2.5.0", "ecosystem": "npm" }, { "name": "@shikijs/types", "direct": false, "version": "2.5.0", "ecosystem": "npm" }, { "name": "@shikijs/vscode-textmate", "direct": false, "version": "10.0.2", "ecosystem": "npm" }, { "name": "@types/estree", "direct": false, "version": "1.0.8", "ecosystem": "npm" }, { "name": "@types/hast", "direct": false, "version": "3.0.4", "ecosystem": "npm" }, { "name": "@types/linkify-it", "direct": false, "version": "5.0.0", "ecosystem": "npm" }, { "name": "@types/markdown-it", "direct": false, "version": "14.1.2", "ecosystem": "npm" }, { "name": "@types/mdast", "direct": false, "version": "4.0.4", "ecosystem": "npm" }, { "name": "@types/mdurl", "direct": false, "version": "2.0.0", "ecosystem": "npm" }, { "name": "@types/unist", "direct": false, "version": "3.0.3", "ecosystem": "npm" }, { "name": "@types/web-bluetooth", "direct": false, "version": "0.0.21", "ecosystem": "npm" }, { "name": "@ungap/structured-clone", "direct": false, "version": "1.3.0", "ecosystem": "npm" }, { "name": "@vitejs/plugin-vue", "direct": false, "version": "5.2.4", "ecosystem": "npm" }, { "name": "@vue/compiler-core", "direct": false, "version": "3.5.33", "ecosystem": "npm" }, { "name": "@vue/compiler-dom", "direct": false, "version": "3.5.33", "ecosystem": "npm" }, { "name": "@vue/compiler-sfc", "direct": false, "version": "3.5.33", "ecosystem": "npm" }, { "name": "@vue/compiler-ssr", "direct": false, "version": "3.5.33", "ecosystem": "npm" }, { "name": "@vue/devtools-api", "direct": false, "version": "7.7.9", "ecosystem": "npm" }, { "name": "@vue/devtools-kit", "direct": false, "version": "7.7.9", "ecosystem": "npm" }, { "name": "@vue/devtools-shared", "direct": false, "version": "7.7.9", "ecosystem": "npm" }, { "name": "@vue/reactivity", "direct": false, "version": "3.5.33", "ecosystem": "npm" }, { "name": "@vue/runtime-core", "direct": false, "version": "3.5.33", "ecosystem": "npm" }, { "name": "@vue/runtime-dom", "direct": false, "version": "3.5.33", "ecosystem": "npm" }, { "name": "@vue/server-renderer", "direct": false, "version": "3.5.33", "ecosystem": "npm" }, { "name": "@vue/shared", "direct": false, "version": "3.5.33", "ecosystem": "npm" }, { "name": "@vueuse/core", "direct": false, "version": "12.8.2", "ecosystem": "npm" }, { "name": "@vueuse/integrations", "direct": false, "version": "12.8.2", "ecosystem": "npm" }, { "name": "@vueuse/metadata", "direct": false, "version": "12.8.2", "ecosystem": "npm" }, { "name": "@vueuse/shared", "direct": false, "version": "12.8.2", "ecosystem": "npm" }, { "name": "algoliasearch", "direct": false, "version": "5.52.0", "ecosystem": "npm" }, { "name": "birpc", "direct": false, "version": "2.9.0", "ecosystem": "npm" }, { "name": "ccount", "direct": false, "version": "2.0.1", "ecosystem": "npm" }, { "name": "character-entities-html4", "direct": false, "version": "2.1.0", "ecosystem": "npm" }, { "name": "character-entities-legacy", "direct": false, "version": "3.0.0", "ecosystem": "npm" }, { "name": "comma-separated-tokens", "direct": false, "version": "2.0.3", "ecosystem": "npm" }, { "name": "copy-anything", "direct": false, "version": "4.0.5", "ecosystem": "npm" }, { "name": "csstype", "direct": false, "version": "3.2.3", "ecosystem": "npm" }, { "name": "dequal", "direct": false, "version": "2.0.3", "ecosystem": "npm" }, { "name": "devlop", "direct": false, "version": "1.1.0", "ecosystem": "npm" }, { "name": "emoji-regex-xs", "direct": false, "version": "1.0.0", "ecosystem": "npm" }, { "name": "entities", "direct": false, "version": "7.0.1", "ecosystem": "npm" }, { "name": "esbuild", "direct": false, "version": "0.21.5", "ecosystem": "npm" }, { "name": "estree-walker", "direct": false, "version": "2.0.2", "ecosystem": "npm" }, { "name": "focus-trap", "direct": false, "version": "7.8.0", "ecosystem": "npm" }, { "name": "fsevents", "direct": false, "version": "2.3.3", "ecosystem": "npm" }, { "name": "hast-util-to-html", "direct": false, "version": "9.0.5", "ecosystem": "npm" }, { "name": "hast-util-whitespace", "direct": false, "version": "3.0.0", "ecosystem": "npm" }, { "name": "hookable", "direct": false, "version": "5.5.3", "ecosystem": "npm" }, { "name": "html-void-elements", "direct": false, "version": "3.0.0", "ecosystem": "npm" }, { "name": "is-what", "direct": false, "version": "5.5.0", "ecosystem": "npm" }, { "name": "magic-string", "direct": false, "version": "0.30.21", "ecosystem": "npm" }, { "name": "mark.js", "direct": false, "version": "8.11.1", "ecosystem": "npm" }, { "name": "mdast-util-to-hast", "direct": false, "version": "13.2.1", "ecosystem": "npm" }, { "name": "micromark-util-character", "direct": false, "version": "2.1.1", "ecosystem": "npm" }, { "name": "micromark-util-encode", "direct": false, "version": "2.0.1", "ecosystem": "npm" }, { "name": "micromark-util-sanitize-uri", "direct": false, "version": "2.0.1", "ecosystem": "npm" }, { "name": "micromark-util-symbol", "direct": false, "version": "2.0.1", "ecosystem": "npm" }, { "name": "micromark-util-types", "direct": false, "version": "2.0.2", "ecosystem": "npm" }, { "name": "minisearch", "direct": false, "version": "7.2.0", "ecosystem": "npm" }, { "name": "mitt", "direct": false, "version": "3.0.1", "ecosystem": "npm" }, { "name": "nanoid", "direct": false, "version": "3.3.16", "ecosystem": "npm" }, { "name": "oniguruma-to-es", "direct": false, "version": "3.1.1", "ecosystem": "npm" }, { "name": "perfect-debounce", "direct": false, "version": "1.0.0", "ecosystem": "npm" }, { "name": "picocolors", "direct": false, "version": "1.1.1", "ecosystem": "npm" }, { "name": "postcss", "direct": false, "version": "8.5.25", "ecosystem": "npm" }, { "name": "preact", "direct": false, "version": "10.29.1", "ecosystem": "npm" }, { "name": "property-information", "direct": false, "version": "7.1.0", "ecosystem": "npm" }, { "name": "regex", "direct": false, "version": "6.1.0", "ecosystem": "npm" }, { "name": "regex-recursion", "direct": false, "version": "6.0.2", "ecosystem": "npm" }, { "name": "regex-utilities", "direct": false, "version": "2.3.0", "ecosystem": "npm" }, { "name": "rfdc", "direct": false, "version": "1.4.1", "ecosystem": "npm" }, { "name": "rollup", "direct": false, "version": "4.60.2", "ecosystem": "npm" }, { "name": "search-insights", "direct": false, "version": "2.17.3", "ecosystem": "npm" }, { "name": "shiki", "direct": false, "version": "2.5.0", "ecosystem": "npm" }, { "name": "source-map-js", "direct": false, "version": "1.2.1", "ecosystem": "npm" }, { "name": "space-separated-tokens", "direct": false, "version": "2.0.2", "ecosystem": "npm" }, { "name": "speakingurl", "direct": false, "version": "14.0.1", "ecosystem": "npm" }, { "name": "stringify-entities", "direct": false, "version": "4.0.4", "ecosystem": "npm" }, { "name": "superjson", "direct": false, "version": "2.2.6", "ecosystem": "npm" }, { "name": "tabbable", "direct": false, "version": "6.4.0", "ecosystem": "npm" }, { "name": "trim-lines", "direct": false, "version": "3.0.1", "ecosystem": "npm" }, { "name": "unist-util-is", "direct": false, "version": "6.0.1", "ecosystem": "npm" }, { "name": "unist-util-position", "direct": false, "version": "5.0.0", "ecosystem": "npm" }, { "name": "unist-util-stringify-position", "direct": false, "version": "4.0.0", "ecosystem": "npm" }, { "name": "unist-util-visit", "direct": false, "version": "5.1.0", "ecosystem": "npm" }, { "name": "unist-util-visit-parents", "direct": false, "version": "6.0.2", "ecosystem": "npm" }, { "name": "vfile", "direct": false, "version": "6.0.3", "ecosystem": "npm" }, { "name": "vfile-message", "direct": false, "version": "4.0.3", "ecosystem": "npm" }, { "name": "vite", "direct": false, "version": "5.4.21", "ecosystem": "npm" }, { "name": "vitepress", "direct": false, "version": "1.6.4", "ecosystem": "npm" }, { "name": "vue", "direct": false, "version": "3.5.33", "ecosystem": "npm" }, { "name": "zwitch", "direct": false, "version": "2.0.4", "ecosystem": "npm" }, { "name": "cakedc/cakephp-phpstan", "direct": false, "version": null, "ecosystem": "packagist" }, { "name": "cakephp/bake", "direct": false, "version": null, "ecosystem": "packagist" }, { "name": "cakephp/migrations", "direct": false, "version": null, "ecosystem": "packagist" }, { "name": "dereuromark/cakephp-dto", "direct": false, "version": null, "ecosystem": "packagist" }, { "name": "dereuromark/cakephp-ide-helper", "direct": false, "version": null, "ecosystem": "packagist" }, { "name": "dereuromark/cakephp-templating", "direct": false, "version": null, "ecosystem": "packagist" }, { "name": "dereuromark/cakephp-tools", "direct": false, "version": null, "ecosystem": "packagist" }, { "name": "fig-r/psr2r-sniffer", "direct": false, "version": null, "ecosystem": "packagist" }, { "name": "friendsofcake/search", "direct": false, "version": null, "ecosystem": "packagist" }, { "name": "php", "direct": false, "version": null, "ecosystem": "packagist" }, { "name": "phpunit/phpunit", "direct": false, "version": null, "ecosystem": "packagist" } ], "collected": true, "truncated": false, "total_count": 186, "direct_count": 2, "indirect_count": 184 } }, "maintainership": { "issues": { "open_prs": 0, "merged_prs": 270, "open_issues": 0, "closed_ratio": 1, "closed_issues": 202, "closed_unmerged_prs": 39 }, "bus_factor": 1, "bot_contributors": 1, "top_contributors": [ { "type": "User", "login": "dereuromark", "commits": 909, "avatar_url": "https://avatars.githubusercontent.com/u/39854?v=4" }, { "type": "User", "login": "LordSimal", "commits": 46, "avatar_url": "https://avatars.githubusercontent.com/u/9105243?v=4" }, { "type": "User", "login": "MSeven", "commits": 37, "avatar_url": "https://avatars.githubusercontent.com/u/31497?v=4" }, { "type": "User", "login": "inoas", "commits": 17, "avatar_url": "https://avatars.githubusercontent.com/u/20972207?v=4" }, { "type": "User", "login": "houseoftech", "commits": 14, "avatar_url": "https://avatars.githubusercontent.com/u/297458?v=4" }, { "type": "User", "login": "Graziel", "commits": 12, "avatar_url": "https://avatars.githubusercontent.com/u/5963584?v=4" }, { "type": "User", "login": "jiru", "commits": 11, "avatar_url": "https://avatars.githubusercontent.com/u/5107734?v=4" }, { "type": "User", "login": "challgren", "commits": 9, "avatar_url": "https://avatars.githubusercontent.com/u/88909?v=4" }, { "type": "User", "login": "stmeyer", "commits": 9, "avatar_url": "https://avatars.githubusercontent.com/u/10654545?v=4" }, { "type": "User", "login": "netstyler", "commits": 8, "avatar_url": "https://avatars.githubusercontent.com/u/319755?v=4" } ], "contributors_sampled": 56, "top_contributor_share": 0.784 }, "quality_signals": { "has_ci": true, "has_tests": true, "ci_workflows": [ "ci.yml", "deploy-docs.yml" ], "has_docs_dir": true, "linter_configs": [ "phpcs.xml", "phpstan.neon" ], "has_editorconfig": true, "has_linter_config": true, "has_precommit_config": false }, "security_signals": { "lockfiles": [ "package-lock.json" ], "scorecard": { "checks": [ { "name": "Binary-Artifacts", "score": 10, "reason": "no binaries found in the repo", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts" }, { "name": "Branch-Protection", "score": 1, "reason": "branch protection is not maximal on development and all release branches", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection" }, { "name": "CI-Tests", "score": 10, "reason": "19 out of 19 merged PRs checked by a CI test -- score normalized to 10", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests" }, { "name": "CII-Best-Practices", "score": 0, "reason": "no effort to earn an OpenSSF best practices badge detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices" }, { "name": "Code-Review", "score": 0, "reason": "Found 0/29 approved changesets -- score normalized to 0", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review" }, { "name": "Contributors", "score": 10, "reason": "project has 13 contributing companies or organizations", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors" }, { "name": "Dangerous-Workflow", "score": null, "reason": "no workflows found", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow" }, { "name": "Dependency-Update-Tool", "score": 10, "reason": "update tool detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool" }, { "name": "Fuzzing", "score": 0, "reason": "project is not fuzzed", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing" }, { "name": "License", "score": 10, "reason": "license file detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license" }, { "name": "Maintained", "score": 10, "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained" }, { "name": "Packaging", "score": null, "reason": "packaging workflow not detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging" }, { "name": "Pinned-Dependencies", "score": null, "reason": "no dependencies found", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies" }, { "name": "SAST", "score": 0, "reason": "SAST tool is not run on all commits -- score normalized to 0", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast" }, { "name": "Security-Policy", "score": 0, "reason": "security policy file not detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy" }, { "name": "Signed-Releases", "score": null, "reason": "no releases found", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases" }, { "name": "Token-Permissions", "score": null, "reason": "No tokens found", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions" }, { "name": "Vulnerabilities", "score": 6, "reason": "4 existing vulnerabilities detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities" } ], "commit": "2c1a1bfc69ccb44b62f7f2e2b60f53d4dc2a5399", "ran_at": "2026-08-02T12:02:31Z", "aggregate_score": 5, "scorecard_version": "v5.5.0" }, "has_codeql_workflow": false, "has_security_policy": false, "has_dependabot_config": false }, "contribution_flow": { "collected": true, "ci_last_run_at": "2026-08-02T11:55:11Z", "oldest_open_prs": [], "last_merged_pr_at": "2026-08-02T11:53:58Z", "ci_last_conclusion": "FAILURE", "oldest_open_issues": [] } }, "config": { "disabled_metrics": [], "disabled_categories": [], "disabled_components": {} }, "source": { "url": "https://github.com/dereuromark/cakephp-queue", "host": "github.com", "name": "cakephp-queue", "owner": "dereuromark" }, "metrics": { "overall": { "key": "overall", "band": "excellent", "name": "Overall health", "note": "The weighted overall 76 is calibrated to 90 on the published index scale (record calibration 2026-08-02).", "notes": [ { "code": "overall_calibration", "params": { "raw": 76, "calibrated": 90, "calibration": "2026-08-02" } } ], "value": 90, "inputs": { "security": 60, "vitality": 92, "community": 68, "governance": 68, "calibration": "2026-08-02", "engineering": 94, "ai_readiness": 51, "weighted_overall_raw": 76 }, "components": [] }, "categories": [ { "key": "vitality", "band": "excellent", "name": "Vitality", "value": 92, "weight": 0.21, "metrics": [ { "key": "development_activity", "band": "excellent", "name": "Development activity", "note": null, "notes": [], "value": 86, "inputs": { "commits_last_year": 145, "human_commit_share": 0.99, "days_since_last_push": 0, "active_weeks_last_year": 32 }, "components": [ { "key": "push_recency", "name": "Push recency", "detail": "last push 0 days ago", "points": 36, "status": "met", "details": [ { "code": "push_recency", "params": { "days": 0 } } ], "max_points": 36 }, { "key": "commit_cadence", "name": "Commit cadence", "detail": "32/52 weeks with commits", "points": 22.2, "status": "partial", "details": [ { "code": "commit_cadence_weeks", "params": { "weeks": 32 } } ], "max_points": 36 }, { "key": "commit_volume", "name": "Commit volume", "detail": "145 commits in the last year", "points": 18, "status": "met", "details": [ { "code": "commits_last_year", "params": { "count": 145 } } ], "max_points": 18 }, { "key": "openssf_scorecard_maintained", "name": "OpenSSF Scorecard: Maintained", "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10", "points": 10, "status": "met", "details": [], "max_points": 10 } ] }, { "key": "release_discipline", "band": "exceptional", "name": "Release discipline", "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.", "notes": [ { "code": "excluded_no_data", "params": { "components": [ "openssf_scorecard_signed_releases" ] } }, { "code": "weights_renormalized", "params": {} } ], "value": 100, "inputs": { "releases_count": 100, "latest_release_tag": "8.15.1", "releases_from_tags": false, "days_since_latest_release": 56, "mean_days_between_releases": 9 }, "components": [ { "key": "ships_releases", "name": "Ships releases", "detail": "100 releases published", "points": 27, "status": "met", "details": [ { "code": "releases_published", "params": { "count": 100 } } ], "max_points": 27 }, { "key": "release_recency", "name": "Release recency", "detail": "latest release 56 days ago", "points": 36, "status": "met", "details": [ { "code": "release_recency", "params": { "days": 56 } } ], "max_points": 36 }, { "key": "release_cadence", "name": "Release cadence", "detail": "a release every ~9 days", "points": 27, "status": "met", "details": [ { "code": "release_cadence", "params": { "gap": 9 } } ], "max_points": 27 }, { "key": "openssf_scorecard_signed_releases", "name": "OpenSSF Scorecard: Signed-Releases", "detail": "no releases found", "points": 0, "status": "excluded", "details": [ { "code": "no_data", "params": {} } ], "max_points": 10 } ] }, { "key": "abandonment", "band": "exceptional", "name": "Abandonment", "note": null, "notes": [], "value": 100, "inputs": { "cap": null, "state": "maintained", "guards": [], "signals": [], "red_flag": false, "multiplier_pct": 100, "declared_reason": null, "unverified_reason": null, "unanswered_open_prs": null, "unanswered_open_issues": null, "days_since_last_merged_pr": null, "days_since_last_human_commit": 35, "days_since_last_human_commit_is_floor": false }, "components": [ { "key": "project_is_still_maintained", "name": "Project is still maintained", "detail": "last human commit 35 days ago", "points": 100, "status": "met", "details": [ { "code": "abandonment_maintained", "params": { "days": 35 } } ], "max_points": 100 } ] } ], "description": "Is the project alive — is code being written and are releases shipping?" }, { "key": "community", "band": "good", "name": "Community & Adoption", "value": 68, "weight": 0.17, "metrics": [ { "key": "popularity", "band": "good", "name": "Popularity & adoption", "note": null, "notes": [], "value": 65, "inputs": { "forks": 138, "stars": 308, "watchers": 19, "growth_state": "unverified", "growth_factor_pct": 100, "growth_unverified_reason": "no_history" }, "components": [ { "key": "stars", "name": "Stars", "detail": "308 stars", "points": 40.3, "status": "partial", "details": [ { "code": "stars", "params": { "count": 308 } } ], "max_points": 60 }, { "key": "forks", "name": "Forks", "detail": "138 forks", "points": 17.8, "status": "partial", "details": [ { "code": "forks", "params": { "count": 138 } } ], "max_points": 25 }, { "key": "watchers", "name": "Watchers", "detail": "19 watchers", "points": 7, "status": "partial", "details": [ { "code": "watchers", "params": { "count": 19 } } ], "max_points": 15 } ] }, { "key": "community_health", "band": "good", "name": "Community health", "note": null, "notes": [], "value": 70, "inputs": { "has_readme": true, "has_license": true, "readme_badges": null, "has_contributing": true, "has_issue_template": false, "has_code_of_conduct": false, "readme_badge_services": [], "has_pull_request_template": false }, "components": [ { "key": "readme", "name": "README", "detail": null, "points": 22.5, "status": "met", "details": [], "max_points": 22.5 }, { "key": "license", "name": "License", "detail": "recognized license (MIT)", "points": 22.5, "status": "met", "details": [ { "code": "license_standard", "params": {} }, { "code": "license_spdx", "params": { "spdx": "MIT" } } ], "max_points": 22.5 }, { "key": "contributing_guide", "name": "CONTRIBUTING guide", "detail": null, "points": 18, "status": "met", "details": [], "max_points": 18 }, { "key": "code_of_conduct", "name": "Code of conduct", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 13.5 }, { "key": "issue_template", "name": "Issue template", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 7.2 }, { "key": "pr_template", "name": "PR template", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 6.3 } ] }, { "key": "ecosystem_adoption", "band": "good", "name": "Ecosystem adoption (downloads)", "note": null, "notes": [], "value": 69, "inputs": { "packages": [ "dereuromark/cakephp-queue" ], "dependents": 16, "ecosystems": "packagist", "total_downloads": 997463, "monthly_downloads": 38799 }, "components": [ { "key": "monthly_downloads", "name": "Monthly downloads", "detail": "38,799 downloads/month across packagist", "points": 61.2, "status": "partial", "details": [ { "code": "downloads_monthly", "params": { "count": 38799, "ecosystems": "packagist" } } ], "max_points": 80 }, { "key": "registry_dependents", "name": "Registry dependents", "detail": "16 packages depend on it", "points": 8.2, "status": "partial", "details": [ { "code": "registry_dependents", "params": { "count": 16 } } ], "max_points": 20 } ] } ], "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?" }, { "key": "governance", "band": "good", "name": "Sustainability & Governance", "value": 68, "weight": 0.23, "metrics": [ { "key": "maintainer_resilience", "band": "weak", "name": "Maintainer resilience (bus factor)", "note": null, "notes": [], "value": 37, "inputs": { "bus_factor": 1, "contributors_sampled": 56, "top_contributor_share": 0.784 }, "components": [ { "key": "bus_factor", "name": "Bus factor", "detail": "1 contributor(s) cover half of all commits", "points": 9, "status": "partial", "details": [ { "code": "bus_factor", "params": { "count": 1 } } ], "max_points": 54 }, { "key": "commit_distribution", "name": "Commit distribution", "detail": "top contributor authored 78% of commits", "points": 4.9, "status": "partial", "details": [ { "code": "top_contributor_share", "params": { "share": 78 } } ], "max_points": 22.5 }, { "key": "contributor_breadth", "name": "Contributor breadth", "detail": "56 contributors", "points": 13.5, "status": "met", "details": [ { "code": "contributors_sampled", "params": { "count": 56 } } ], "max_points": 13.5 }, { "key": "openssf_scorecard_contributors", "name": "OpenSSF Scorecard: Contributors", "detail": "project has 13 contributing companies or organizations", "points": 10, "status": "met", "details": [], "max_points": 10 } ] }, { "key": "responsiveness", "band": "good", "name": "Issue & PR responsiveness", "note": "Excluded from scoring (no data or not applicable): Newcomer PR acceptance. Remaining weights renormalized.", "notes": [ { "code": "excluded_no_data", "params": { "components": [ "newcomer_pr_acceptance" ] } }, { "code": "weights_renormalized", "params": {} } ], "value": 78, "inputs": { "merged_prs": 270, "open_issues": 0, "closed_issues": 202, "prs_merged_7d": null, "prs_decided_7d": null, "prs_merged_30d": null, "prs_decided_30d": null, "issue_closed_ratio": 1, "closed_unmerged_prs": 39, "first_time_authors_30d": null, "first_time_prs_merged_30d": null, "first_time_prs_decided_30d": null }, "components": [ { "key": "issue_resolution", "name": "Issue resolution", "detail": "100% of issues closed", "points": 42, "status": "met", "details": [ { "code": "issues_closed_share", "params": { "share": 100 } } ], "max_points": 42 }, { "key": "pr_acceptance", "name": "PR acceptance", "detail": "270/309 decided PRs merged", "points": 26.2, "status": "partial", "details": [ { "code": "decided_prs_merged", "params": { "merged": 270, "decided": 309 } } ], "max_points": 30 }, { "key": "newcomer_pr_acceptance", "name": "Newcomer PR acceptance", "detail": "no first-time contributor's PR decided in 30d", "points": 0, "status": "excluded", "details": [ { "code": "no_newcomer_prs", "params": { "days": 30 } } ], "max_points": 13 }, { "key": "openssf_scorecard_code_review", "name": "OpenSSF Scorecard: Code-Review", "detail": "Found 0/29 approved changesets -- score normalized to 0", "points": 0, "status": "missed", "details": [], "max_points": 15 } ] }, { "key": "stewardship", "band": "good", "name": "Ownership & stewardship", "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.", "notes": [ { "code": "excluded_no_data", "params": { "components": [ "verified_domain" ] } }, { "code": "weights_renormalized", "params": {} } ], "value": 70, "inputs": { "followers": 748, "owner_type": "User", "is_verified": null, "owner_login": "dereuromark", "public_repos": 123, "account_age_days": 6442 }, "components": [ { "key": "ownership_backing", "name": "Ownership backing", "detail": "personal (user) account", "points": 10, "status": "partial", "details": [ { "code": "owner_personal", "params": {} } ], "max_points": 30 }, { "key": "verified_domain", "name": "Verified domain", "detail": "not applicable to user accounts", "points": 0, "status": "excluded", "details": [ { "code": "not_applicable_to_user_accounts", "params": {} } ], "max_points": 20 }, { "key": "owner_reach", "name": "Owner reach", "detail": "748 followers of dereuromark", "points": 20.7, "status": "partial", "details": [ { "code": "owner_followers", "params": { "count": 748, "login": "dereuromark" } } ], "max_points": 25 }, { "key": "track_record", "name": "Track record", "detail": "123 public repos, account ~17 yr old", "points": 25, "status": "met", "details": [ { "code": "public_repos", "params": { "count": 123 } }, { "code": "account_age_years", "params": { "years": 17 } } ], "max_points": 25 } ] }, { "key": "package_maintenance", "band": "exceptional", "name": "Package maintenance", "note": null, "notes": [], "value": 100, "inputs": { "packages": [ "dereuromark/cakephp-queue" ], "ecosystems": "packagist", "any_deprecated": false, "min_days_since_publish": 56 }, "components": [ { "key": "published_resolvable", "name": "Published & resolvable", "detail": "1 package(s) on packagist", "points": 25, "status": "met", "details": [ { "code": "packages_published", "params": { "count": 1, "ecosystems": "packagist" } } ], "max_points": 25 }, { "key": "publish_recency", "name": "Publish recency", "detail": "latest publish 56 days ago", "points": 35, "status": "met", "details": [ { "code": "publish_recency", "params": { "days": 56 } } ], "max_points": 35 }, { "key": "version_history", "name": "Version history", "detail": "136 published versions", "points": 20, "status": "met", "details": [ { "code": "published_versions", "params": { "count": 136 } } ], "max_points": 20 }, { "key": "not_deprecated", "name": "Not deprecated", "detail": "active, not deprecated or yanked", "points": 20, "status": "met", "details": [ { "code": "package_not_deprecated", "params": {} } ], "max_points": 20 } ] } ], "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?" }, { "key": "engineering", "band": "exceptional", "name": "Engineering Quality", "value": 94, "weight": 0.19, "metrics": [ { "key": "engineering_practices", "band": "excellent", "name": "Engineering practices", "note": null, "notes": [], "value": 90, "inputs": { "has_ci": true, "has_tests": true, "has_editorconfig": true, "has_linter_config": true, "has_precommit_config": false }, "components": [ { "key": "ci_workflows", "name": "CI workflows", "detail": "2 workflow(s)", "points": 24, "status": "met", "details": [ { "code": "ci_workflows", "params": { "count": 2 } } ], "max_points": 24 }, { "key": "tests_present", "name": "Tests present", "detail": null, "points": 24, "status": "met", "details": [], "max_points": 24 }, { "key": "linter_config", "name": "Linter config", "detail": "phpcs.xml, phpstan.neon", "points": 16, "status": "met", "details": [ { "code": "file_list", "params": { "files": "phpcs.xml, phpstan.neon" } } ], "max_points": 16 }, { "key": "pre_commit_hooks", "name": "Pre-commit hooks", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 9.6 }, { "key": "editorconfig", "name": ".editorconfig", "detail": null, "points": 6.4, "status": "met", "details": [], "max_points": 6.4 }, { "key": "openssf_scorecard_ci_tests", "name": "OpenSSF Scorecard: CI-Tests", "detail": "19 out of 19 merged PRs checked by a CI test -- score normalized to 10", "points": 20, "status": "met", "details": [], "max_points": 20 } ] }, { "key": "documentation", "band": "exceptional", "name": "Documentation", "note": null, "notes": [], "value": 100, "inputs": { "topics": [ "asynchronous", "background-jobs", "cronjob", "queue", "cakephp", "cakephp-plugin", "php" ], "has_wiki": true, "homepage": "https://dereuromark.github.io/cakephp-queue/", "has_readme": true, "has_docs_dir": true, "has_description": true }, "components": [ { "key": "readme", "name": "README", "detail": null, "points": 30, "status": "met", "details": [], "max_points": 30 }, { "key": "documentation_directory", "name": "Documentation directory", "detail": null, "points": 25, "status": "met", "details": [], "max_points": 25 }, { "key": "documentation_homepage_site", "name": "Documentation / homepage site", "detail": "https://dereuromark.github.io/cakephp-queue/", "points": 15, "status": "met", "details": [], "max_points": 15 }, { "key": "repository_description", "name": "Repository description", "detail": null, "points": 10, "status": "met", "details": [], "max_points": 10 }, { "key": "topics", "name": "Topics", "detail": "7 topics", "points": 10, "status": "met", "details": [ { "code": "topics_count", "params": { "count": 7 } } ], "max_points": 10 }, { "key": "wiki", "name": "Wiki", "detail": null, "points": 10, "status": "met", "details": [], "max_points": 10 } ] } ], "description": "Are baseline engineering and documentation practices in place?" }, { "key": "security", "band": "moderate", "name": "Security", "value": 60, "weight": 0.16, "metrics": [ { "key": "security_posture", "band": "moderate", "name": "Security posture", "note": "Excluded from scoring (no data or not applicable): Dangerous-Workflow, Packaging, Pinned-Dependencies, Signed-Releases, Token-Permissions. Remaining weights renormalized.", "notes": [ { "code": "excluded_no_data", "params": { "components": [ "dangerous_workflow", "packaging", "pinned_dependencies", "signed_releases", "token_permissions" ] } }, { "code": "weights_renormalized", "params": {} } ], "value": 50, "inputs": { "source": "openssf_scorecard", "checks_evaluated": 13, "scorecard_version": "v5.5.0", "checks_inconclusive": 5, "scorecard_aggregate": 5 }, "components": [ { "key": "binary_artifacts", "name": "Binary-Artifacts", "detail": "no binaries found in the repo", "points": 7.5, "status": "met", "details": [], "max_points": 7.5 }, { "key": "branch_protection", "name": "Branch-Protection", "detail": "branch protection is not maximal on development and all release branches", "points": 0.8, "status": "partial", "details": [], "max_points": 7.5 }, { "key": "ci_tests", "name": "CI-Tests", "detail": "19 out of 19 merged PRs checked by a CI test -- score normalized to 10", "points": 2.5, "status": "met", "details": [], "max_points": 2.5 }, { "key": "cii_best_practices", "name": "CII-Best-Practices", "detail": "no effort to earn an OpenSSF best practices badge detected", "points": 0, "status": "missed", "details": [], "max_points": 2.5 }, { "key": "code_review", "name": "Code-Review", "detail": "Found 0/29 approved changesets -- score normalized to 0", "points": 0, "status": "missed", "details": [], "max_points": 7.5 }, { "key": "contributors", "name": "Contributors", "detail": "project has 13 contributing companies or organizations", "points": 2.5, "status": "met", "details": [], "max_points": 2.5 }, { "key": "dangerous_workflow", "name": "Dangerous-Workflow", "detail": "no workflows found", "points": 0, "status": "excluded", "details": [ { "code": "no_data", "params": {} } ], "max_points": 10 }, { "key": "dependency_update_tool", "name": "Dependency-Update-Tool", "detail": "update tool detected", "points": 7.5, "status": "met", "details": [], "max_points": 7.5 }, { "key": "fuzzing", "name": "Fuzzing", "detail": "project is not fuzzed", "points": 0, "status": "missed", "details": [], "max_points": 5 }, { "key": "license", "name": "License", "detail": "license file detected", "points": 2.5, "status": "met", "details": [], "max_points": 2.5 }, { "key": "maintained", "name": "Maintained", "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10", "points": 7.5, "status": "met", "details": [], "max_points": 7.5 }, { "key": "packaging", "name": "Packaging", "detail": "packaging workflow not detected", "points": 0, "status": "excluded", "details": [ { "code": "no_data", "params": {} } ], "max_points": 5 }, { "key": "pinned_dependencies", "name": "Pinned-Dependencies", "detail": "no dependencies found", "points": 0, "status": "excluded", "details": [ { "code": "no_data", "params": {} } ], "max_points": 5 }, { "key": "sast", "name": "SAST", "detail": "SAST tool is not run on all commits -- score normalized to 0", "points": 0, "status": "missed", "details": [], "max_points": 5 }, { "key": "security_policy", "name": "Security-Policy", "detail": "security policy file not detected", "points": 0, "status": "missed", "details": [], "max_points": 5 }, { "key": "signed_releases", "name": "Signed-Releases", "detail": "no releases found", "points": 0, "status": "excluded", "details": [ { "code": "no_data", "params": {} } ], "max_points": 7.5 }, { "key": "token_permissions", "name": "Token-Permissions", "detail": "No tokens found", "points": 0, "status": "excluded", "details": [ { "code": "no_data", "params": {} } ], "max_points": 7.5 }, { "key": "vulnerabilities", "name": "Vulnerabilities", "detail": "4 existing vulnerabilities detected", "points": 4.5, "status": "partial", "details": [], "max_points": 7.5 } ] }, { "key": "dependency_advisories", "band": "exceptional", "name": "Dependency advisories", "note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories, No advisories left outstanding. Remaining weights renormalized. Matched 173 resolved dependencies against OSV; 13 could not be assessed (no resolved version, an unsupported ecosystem, or beyond the reported package list). This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.", "notes": [ { "code": "excluded_no_data", "params": { "components": [ "indirect_dependencies_free_of_known_advisories", "no_advisories_left_outstanding" ] } }, { "code": "weights_renormalized", "params": {} }, { "code": "advisories_scope_repository", "params": { "assessed": 173 } }, { "code": "advisories_unassessed", "params": { "count": 13 } }, { "code": "advisories_repo_graph_caveat", "params": {} }, { "code": "advisories_reachability", "params": {} } ], "value": 100, "inputs": { "source": "osv", "advisories": 4, "affected_packages": 2, "assessed_packages": 173, "unassessed_packages": 13, "affected_by_severity": "high 1, moderate 1", "direct_affected_packages": 0 }, "components": [ { "key": "direct_dependencies_free_of_known_advisories", "name": "Direct dependencies free of known advisories", "detail": "no direct dependency carries a known advisory", "points": 35, "status": "met", "details": [ { "code": "no_direct_advisories", "params": {} } ], "max_points": 35 }, { "key": "indirect_dependencies_free_of_known_advisories", "name": "Indirect dependencies free of known advisories", "detail": "transitive set not separable from development and test dependencies in this scope", "points": 0, "status": "excluded", "details": [ { "code": "advisories_scope_not_separable", "params": {} } ], "max_points": 25 }, { "key": "no_advisories_left_outstanding", "name": "No advisories left outstanding", "detail": "no advisory carries a publication date", "points": 0, "status": "excluded", "details": [ { "code": "advisories_no_publication_date", "params": {} } ], "max_points": 40 } ] }, { "key": "malicious_dependencies", "band": "exceptional", "name": "Malicious dependencies", "note": null, "notes": [], "value": 100, "inputs": { "source": "osv", "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored", "packages": [], "red_flag": false, "assessed_packages": 173, "malicious_packages": 0, "direct_malicious_packages": 0, "withdrawn_malicious_packages": 0, "installable_malicious_packages": 0 }, "components": [ { "key": "no_dependency_reported_as_a_malicious_package", "name": "No dependency reported as a malicious package", "detail": "no dependency is reported as a malicious package", "points": 100, "status": "met", "details": [ { "code": "no_malicious_dependencies", "params": {} } ], "max_points": 100 } ] }, { "key": "high_risk_jurisdiction_exposure", "band": "exceptional", "name": "High-Risk Jurisdiction Exposure", "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.", "notes": [ { "code": "jurisdiction_evidence_limits", "params": {} } ], "value": 100, "inputs": { "meaning": "self-published location evidence; not nationality or citizenship", "red_flag": false, "exposures": [], "policy_countries": [ "Russia", "Iran", "North Korea" ], "commit_weight_rule": { "min_commits": 50, "min_commit_share": 0.1 }, "review_only_matches": 0, "below_threshold_exposures": [], "assessed_self_published_locations": 13 }, "components": [ { "key": "policy_exposure_multiplier", "name": "Policy exposure multiplier", "detail": "no confirmed policy-scope location match", "points": 100, "status": "met", "details": [ { "code": "jurisdiction_no_match", "params": {} } ], "max_points": 100 } ] } ], "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?" }, { "key": "ai_readiness", "band": "moderate", "name": "AI Readiness", "value": 51, "weight": 0.04, "metrics": [ { "key": "ai_agent_context", "band": "weak", "name": "Agent context & guidance", "note": null, "notes": [], "value": 36, "inputs": { "has_llms_txt": false, "legible_history_share": 0.677, "agent_instruction_files": [], "agent_instruction_max_bytes": null }, "components": [ { "key": "agent_instructions", "name": "Agent instructions", "detail": "no CLAUDE.md / AGENTS.md / editor rules", "points": 0, "status": "missed", "details": [ { "code": "no_agent_instructions", "params": {} } ], "max_points": 45 }, { "key": "machine_readable_docs_llms_txt", "name": "Machine-readable docs (llms.txt)", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 15 }, { "key": "legible_commit_history", "name": "Legible commit history", "detail": "67 of 99 human commits state their intent (structured subject or explanatory body)", "points": 36.1, "status": "partial", "details": [ { "code": "legible_history", "params": { "legible": 67, "sampled": 99 } } ], "max_points": 40 } ] }, { "key": "ai_verify_loop", "band": "moderate", "name": "Verify loop (build / test / typecheck)", "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Pinned-Dependencies. Remaining weights renormalized.", "notes": [ { "code": "excluded_no_data", "params": { "components": [ "openssf_scorecard_pinned_dependencies" ] } }, { "code": "weights_renormalized", "params": {} } ], "value": 61, "inputs": { "has_nix": false, "has_tests": true, "lockfiles": [ "package-lock.json" ], "has_dockerfile": false, "typed_language": false, "bootstrap_files": [], "has_devcontainer": false, "has_linter_config": true, "typecheck_configs": [], "agent_commit_share": 0.02, "toolchain_manifests": [], "dependency_bot_commit_share": 0.01 }, "components": [ { "key": "one_command_bootstrap", "name": "One-command bootstrap", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 18 }, { "key": "automated_tests", "name": "Automated tests", "detail": null, "points": 22, "status": "met", "details": [], "max_points": 22 }, { "key": "lint_format_config", "name": "Lint / format config", "detail": "phpcs.xml, phpstan.neon", "points": 11, "status": "met", "details": [ { "code": "file_list", "params": { "files": "phpcs.xml, phpstan.neon" } } ], "max_points": 11 }, { "key": "static_type_checking", "name": "Static type checking", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 11 }, { "key": "reproducible_environment", "name": "Reproducible environment", "detail": "lockfile", "points": 10, "status": "met", "details": [ { "code": "file_list", "params": { "files": "lockfile" } } ], "max_points": 10 }, { "key": "demonstrated_agent_practice", "name": "Demonstrated agent practice", "detail": "2 of the last 100 commits agent-authored or agent-credited", "points": 4, "status": "partial", "details": [ { "code": "agent_authored_commits", "params": { "count": 2, "sampled": 100 } } ], "max_points": 10 }, { "key": "automated_maintenance", "name": "Automated maintenance", "detail": "1 of the last 100 commits are automated dependency updates", "points": 8, "status": "met", "details": [ { "code": "dependency_bot_commits", "params": { "count": 1, "sampled": 100 } } ], "max_points": 8 }, { "key": "openssf_scorecard_pinned_dependencies", "name": "OpenSSF Scorecard: Pinned-Dependencies", "detail": "no dependencies found", "points": 0, "status": "excluded", "details": [ { "code": "no_data", "params": {} } ], "max_points": 10 } ] }, { "key": "ai_code_legibility", "band": "moderate", "name": "Code legibility for models", "note": null, "notes": [], "value": 55, "inputs": { "primary_language": "PHP", "largest_source_bytes": 37884, "source_files_sampled": 161, "oversized_source_files": 0 }, "components": [ { "key": "type_checkable_code", "name": "Type-checkable code", "detail": "PHP without a type-check config", "points": 0, "status": "missed", "details": [ { "code": "no_typecheck_config_language", "params": { "language": "PHP" } } ], "max_points": 45 }, { "key": "manageable_file_sizes", "name": "Manageable file sizes", "detail": "0/161 source files over 60KB", "points": 55, "status": "met", "details": [ { "code": "oversized_source_files", "params": { "kb": 60, "sampled": 161, "oversized": 0 } } ], "max_points": 55 } ] } ], "description": "How well is the repo equipped to be developed and maintained with AI coding agents? Carries a deliberately small weight: agent tooling is a real maintenance signal, but its absence must never gate the top of the scale (calibration saturates at raw 91, so 100/100 remains reachable with AI Readiness at zero)." } ], "classification": { "labels": [ "library" ], "scores": { "plugin": 2, "web-ui": 2, "library": 6 }, "primary": "library", "evidence": [ { "tier": "distribution", "label": "library", "source": "registry:packagist", "weight": 6 }, { "tier": "description", "label": "plugin", "source": "description:plugin", "weight": 2 }, { "tier": "tags", "label": "web-ui", "source": "tag:admin-panel", "weight": 2 } ], "artifacts": [], "confidence": "medium", "host_extension": false, "runs_as_process": false, "consumed_by_code": true }, "metrics_version": "2.3.1" }, "warnings": [ "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token" ], "report_type": "repository", "generated_at": "2026-08-02T12:02:54.849037Z", "schema_version": "0.27.0", "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/d/dereuromark/cakephp-queue.svg", "full_name": "dereuromark/cakephp-queue", "license_state": "standard", "license_spdx": "MIT" }, "repoMeta": null, "notFound": false, "related": [ { "id": 8646, "full_name": "taskforcesh/bullmq", "url": "https://github.com/taskforcesh/bullmq", "description": "BullMQ - Message Queue and Batch processing for NodeJS, Python, Elixir and PHP based on Redis", "ecosystem": "npm", "ecosystems": [ "npm", "hex", "crates", "pypi", "packagist" ], "primary_language": "TypeScript", "languages": [ "TypeScript", "Rust", "Elixir" ], "topics": [ "background-jobs", "nodejs", "queue", "redis", "typescript", "python", "elixir", "php", "bull", "bullmq", "queues", "jobs", "worker", "job", "background", "asynchronous", "database" ], "license_spdx": "MIT", "license_state": "standard", "stars": 9127, "forks": 654, "watchers": 36, "monthly_downloads": 26974786, "latest_score": 97, "latest_band": "exceptional", "latest_scanned_at": "2026-07-16T00:14:54.282663Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 3436, "full_name": "Sylius/Sylius", "url": "https://github.com/Sylius/Sylius", "description": "Headless open-source eCommerce platform on top of PHP/Symfony/API Platform", "ecosystem": "packagist", "ecosystems": [ "packagist", "npm" ], "primary_language": "PHP", "languages": [ "PHP" ], "topics": [ "api", "api-ecommerce", "ecommerce", "ecommerce-platform", "framework", "hacktoberfest", "headless", "headless-ecommerce", "php", "rest-api", "restful-api", "shop", "shopping-cart", "sylius", "symfony", "symfony-bundle" ], "license_spdx": "MIT", "license_state": "standard", "stars": 8505, "forks": 2161, "watchers": 257, "monthly_downloads": 120034, "latest_score": 98, "latest_band": "exceptional", "latest_scanned_at": "2026-07-14T10:23:48.536599Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 10334, "full_name": "symfony/symfony", "url": "https://github.com/symfony/symfony", "description": "The Symfony PHP framework", "ecosystem": "packagist", "ecosystems": [ "packagist" ], "primary_language": "PHP", "languages": [ "PHP" ], "topics": [ "framework", "php", "symfony", "symfony-bundle", "bundle", "php-framework", "hacktoberfest", "dev" ], "license_spdx": "MIT", "license_state": "standard", "stars": 31107, "forks": 9850, "watchers": 1040, "monthly_downloads": 261266, "latest_score": 97, "latest_band": "exceptional", "latest_scanned_at": "2026-07-22T00:57:57.157500Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "organic", "abandonment_state": "maintained", "red_flags": [], "badge_url": "" }, { "id": 4590, "full_name": "infection/infection", "url": "https://github.com/infection/infection", "description": "PHP Mutation Testing library", "ecosystem": "packagist", "ecosystems": [ "packagist" ], "primary_language": "PHP", "languages": [ "PHP" ], "topics": [ "ast", "coverage", "infection", "mutant", "mutation", "mutation-analysis", "mutation-testing", "php", "test-framework", "testing" ], "license_spdx": "BSD-3-Clause", "license_state": "standard", "stars": 2222, "forks": 186, "watchers": 29, "monthly_downloads": 979245, "latest_score": 97, "latest_band": "exceptional", "latest_scanned_at": "2026-07-14T16:43:17.758015Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 8573, "full_name": "Dependabot/dependabot-core", "url": "https://github.com/Dependabot/dependabot-core", "description": "🤖 Dependabot's core logic for creating update PRs.", "ecosystem": "rubygems", "ecosystems": [ "rubygems" ], "primary_language": "Ruby", "languages": [ "Ruby", "C#" ], "topics": [ "elixir", "ruby", "php", "python", "javascript", "java", "rust", "dotnet", "go", "elm", "terraform", "dependencies", "docker", "pnpm", "rubygems" ], "license_spdx": "MIT", "license_state": "standard", "stars": 5683, "forks": 1451, "watchers": 111, "monthly_downloads": null, "latest_score": 98, "latest_band": "exceptional", "latest_scanned_at": "2026-07-16T00:08:15.011461Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 30, "full_name": "fastapi/fastapi", "url": "https://github.com/fastapi/fastapi", "description": "FastAPI framework, high performance, easy to learn, fast to code, ready for production", "ecosystem": "pypi", "ecosystems": [ "pypi" ], "primary_language": "Python", "languages": [ "Python" ], "topics": [ "python", "json", "swagger-ui", "redoc", "starlette", "openapi", "api", "openapi3", "framework", "async", "asyncio", "uvicorn", "python3", "python-types", "pydantic", "json-schema", "fastapi", "swagger", "rest", "web" ], "license_spdx": "MIT", "license_state": "standard", "stars": 100763, "forks": 9660, "watchers": 756, "monthly_downloads": 510759380, "latest_score": 97, "latest_band": "exceptional", "latest_scanned_at": "2026-07-22T17:10:27.311813Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "maintained", "red_flags": [], "badge_url": "" } ] } }
公开记录
软件健康报告模式 0.27.0 · 指标 2.3.1 · 2026-08-02 12:02 UTC

dereuromark / cakephp-queue

Queue plugin for CakePHP - simple, pure PHP and without dependencies.

PHPMIT★ 308 星标⑂ 138 复刻始于 2011年10月在 GitHub 上查看 ↗
类型如何判定

dereuromark/cakephp-queue 的健康指数为 100 分中的 90 分,处于「优秀」区间。 其得分最高的类别是Engineering Quality(94/100),最低的是AI Readiness(51/100)。 最近一次更新在今天。 近期的大部分工作由 1 位贡献者完成。

90
总分 / 100
优秀

软件健康指数

指标归入加权类别,统一采用 1–100 量表。总体分先取类别加权平均,再依据公开记录的分布进行校准,使各等级具有百分位含义;当公开证据触发高风险司法辖区政策时,评级会按政策调整,并设置 34(存在风险)的上限。

90
卓越93-100公开记录中的最高层级(约前 5%);基本满足所有检验标准
优秀80-92各方面均表现强劲;仅有少量不足
良好65-79健康;不足之处有限且可控
中等50-64可接受,但存在明显不足;建议进行审查
薄弱35-49多个领域存在实质性薄弱环节
存在风险20-34存在重大薄弱环节;采用时应保持审慎
危急1-19问题严重(项目被弃置、仅有单一维护者、缺乏基本工程规范)
活力社区与采用可持续性与治理工程质量安全AI 就绪度

评分画像

每条轴代表一个类别。形状比平均值更重要——健康的对象会填满整个图形,而“一峰一谷”式画像意味着某一维度的优势正掩盖另一维度的风险。

加权总体分 76 经校准后在公布的指数量表上为 90(记录校准 2026-08-02)。

所有权

Mark Scherer个人账户
748 关注者123 个公开仓库始于 2008年12月Available as (Cake)PHP expert

该仓库由个人账户拥有。相较于组织支持的项目,单一所有者项目的延续性风险更高。

软件包生态系统

注册表软件包版本月下载量版本数最近发布标签
Packagistdereuromark/cakephp-queue8.15.138,79913656 天前queuecakephpbackgroundasyncjobsadmin-panelworkersdeferred-tasksstandalone-ui

按类别列示的指标

活力

项目是否仍有生命——是否仍在编写代码,是否仍在发布版本?

92优秀 · 占总体的 21%
评分方式
36/36推送新近度 — 最近一次推送于 0 天前
22.2/36提交节奏 — 52 周中有 32 周有提交
18/18提交量 — 最近一年 145 次提交
10/10OpenSSF Scorecard:Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
所用输入
commits_last_year145
human_commit_share0.99
days_since_last_push0
active_weeks_last_year32

发布纪律

100卓越
评分方式
27/27有发布版本 — 已发布 100 个发布版本
36/36发布时效 — 最近一次发布版本于 56 天前
27/27发布节奏 — 约每 9 天发布一次
0/10OpenSSF Scorecard:Signed-Releases — 无数据
所用输入
releases_count100
latest_release_tag8.15.1
releases_from_tags
days_since_latest_release56
mean_days_between_releases9
已排除计分(无数据或不适用):OpenSSF Scorecard:Signed-Releases。 其余权重已重新归一化。

社区与采用

项目是否拥有用户、下载量与关注度,并具备欢迎贡献者参与的配置?

68良好 · 占总体的 17%
评分方式
40.3/60星标 — 308 个星标
17.8/25复刻 — 138 个复刻
7/15关注者 — 19 位关注者
所用输入
forks138
stars308
watchers19
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history

社区健康

70良好
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(MIT)
18/18CONTRIBUTING 指南
0/13.5行为准则
0/7.2议题模板
0/6.3PR 模板
所用输入
has_readme
has_license
readme_badges
has_contributing
has_issue_template
has_code_of_conduct
readme_badge_services
has_pull_request_template
评分方式
61.2/80月度下载量 — packagist 合计每月 38,799 次下载
8.2/20注册表被依赖数 — 16 个软件包依赖它
所用输入
packagesdereuromark/cakephp-queue
dependents16
ecosystemspackagist
total_downloads997,463
monthly_downloads38,799

可持续性与治理

项目能否在其成员之外延续——巴士系数、响应能力、由谁支持,以及软件包的维护状况?

68良好 · 占总体的 23%
评分方式
9/54巴士系数 — 1 位贡献者贡献了半数提交
4.9/22.5提交分布 — 头号贡献者编写了 78% 的提交
13.5/13.5贡献者广度 — 56 位贡献者
10/10OpenSSF Scorecard:Contributors — project has 13 contributing companies or organizations
所用输入
bus_factor1
contributors_sampled56
top_contributor_share0.784
评分方式
42/42议题解决 — 100% 的议题已关闭
26.2/30PR 接受 — 已裁定的 PR 中 270/309 已合并
0/13Newcomer PR acceptance — 30 天内没有首次贡献者的 PR 得到裁决
0/15OpenSSF Scorecard:Code-Review — Found 0/29 approved changesets -- score normalized to 0
所用输入
merged_prs270
open_issues0
closed_issues202
prs_merged_7d
prs_decided_7d
prs_merged_30d
prs_decided_30d
issue_closed_ratio1
closed_unmerged_prs39
first_time_authors_30d
first_time_prs_merged_30d
first_time_prs_decided_30d
已排除计分(无数据或不适用):newcomer_pr_acceptance。 其余权重已重新归一化。
评分方式
10/30所有权背书 — 个人(用户)账户
0/20已验证域名 — 不适用于个人账户
20.7/25所有者影响力 — dereuromark 有 748 位关注者
25/25既往记录 — 123 个公开仓库,账户约 17 年
所用输入
followers748
owner_typeUser
is_verified
owner_logindereuromark
public_repos123
account_age_days6,442
已排除计分(无数据或不适用):已验证域名。 其余权重已重新归一化。
评分方式
25/25已发布且可解析 — packagist 上有 1 个软件包
35/35发布时效 — 最近一次发布于 56 天前
20/20版本历史 — 136 个已发布版本
20/20未被弃用 — 活跃,未被弃用或撤回
所用输入
packagesdereuromark/cakephp-queue
ecosystemspackagist
any_deprecated
min_days_since_publish56

工程质量

基础的工程与文档实践是否到位?

94卓越 · 占总体的 19%

工程实践

90优秀
评分方式
24/24CI 工作流 — 2 个工作流
24/24存在测试
16/16Linter 配置 — phpcs.xml, phpstan.neon
0/9.6Pre-commit 钩子
6.4/6.4.editorconfig
20/20OpenSSF Scorecard:CI-Tests — 19 out of 19 merged PRs checked by a CI test -- score normalized to 10
所用输入
has_ci
has_tests
has_editorconfig
has_linter_config
has_precommit_config

文档

100卓越
评分方式
30/30README
25/25文档目录
15/15文档 / 主页站点 — https://dereuromark.github.io/cakephp-queue/
10/10仓库描述
10/10主题标签 — 7 个主题标签
10/10Wiki
所用输入
topicsasynchronous, background-jobs, cronjob, queue, cakephp, cakephp-plugin, php
has_wiki
homepagehttps://dereuromark.github.io/cakephp-queue/
has_readme
has_docs_dir
has_description

安全

可见的安全与供应链实践是否稳固,且不存在未解决的高风险司法辖区暴露?

60中等 · 占总体的 16%

安全态势

50中等
评分方式
7.5/7.5Binary-Artifacts — no binaries found in the repo
0.8/7.5Branch-Protection — branch protection is not maximal on development and all release branches
2.5/2.5CI-Tests — 19 out of 19 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/29 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 13 contributing companies or organizations
0/10Dangerous-Workflow — 无数据
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5许可证 — license file detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — 无数据
0/5Pinned-Dependencies — 无数据
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — 无数据
0/7.5Token-Permissions — 无数据
4.5/7.5Vulnerabilities — 4 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated13
scorecard_versionv5.5.0
checks_inconclusive5
scorecard_aggregate5
已排除计分(无数据或不适用):dangerous_workflow, packaging, pinned_dependencies, signed_releases, token_permissions。 其余权重已重新归一化。
评分方式
35/35直接依赖不含已知公告 — 没有直接依赖携带已知公告
0/25间接依赖不含已知公告 — 在此范围内,传递依赖集合无法与开发和测试依赖区分
0/40没有长期未处理的公告 — 没有公告带有发布日期
所用输入
sourceosv
advisories4
affected_packages2
assessed_packages173
unassessed_packages13
affected_by_severityhigh 1, moderate 1
direct_affected_packages0
已排除计分(无数据或不适用):间接依赖不含已知公告, 没有长期未处理的公告。 其余权重已重新归一化。 已将 173 个已解析依赖与 OSV 比对。 有 13 项无法评估——没有已解析的版本、生态系统不受支持,或超出所报告的软件包清单。 该仓库未发布任何索引可解析的软件包,因此改为评估仓库依赖图。该图将开发与测试版本固定同交付的依赖混在一起,因此仅对声明的运行时依赖计分;传递性发现仅作为背景信息列出,不计入评分。 未对可达性进行分析。

AI 就绪度

该仓库在多大程度上具备与 AI 编码代理协同开发与维护的条件?权重刻意设小(4%):代理工具链是一项真实的维护信号,但完全不具备的仓库仍可达到 100/100。

51中等 · 占总体的 4%
评分方式
0/45代理指令 — 没有 CLAUDE.md / AGENTS.md / 编辑器规则
0/15机器可读文档(llms.txt)
36.1/40可读的提交历史 — 99 次人类提交中有 67 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.677
agent_instruction_files
agent_instruction_max_bytes
评分方式
0/18一条命令的引导启动
22/22自动化测试
11/11Lint / 格式化配置 — phpcs.xml, phpstan.neon
0/11静态类型检查
10/10可复现环境 — lockfile
4/10已体现的代理实践 — 最近 100 次提交中有 2 次由代理编写或署名代理
8/8自动化维护 — 最近 100 次提交中有 1 次为自动依赖更新
0/10OpenSSF Scorecard:Pinned-Dependencies — 无数据
所用输入
has_nix
has_tests
lockfilespackage-lock.json
has_dockerfile
typed_language
bootstrap_files
has_devcontainer
has_linter_config
typecheck_configs
agent_commit_share0.02
toolchain_manifests
dependency_bot_commit_share0.01
已排除计分(无数据或不适用):OpenSSF Scorecard:Pinned-Dependencies。 其余权重已重新归一化。
评分方式
0/45可类型检查的代码 — PHP,未配置类型检查
55/55可控的文件大小 — 采样的 161 个源文件中有 0 个超过 60KB
所用输入
primary_languagePHP
largest_source_bytes37,884
source_files_sampled161
oversized_source_files0

关键数据

308GitHub 星标
56贡献者
145最近 12 个月提交数
0距最近推送天数
100发布版本数
1巴士系数(bus factor)
0开放议题
npm, Packagist软件包生态系统数

数据采集警告

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token

更多细节

Star 与 Fork 历史 0 ★ / 138 ⇿
0Star
138Fork
100发布

每颗 star 和每个 fork 的添加时间,来自 GitHub 并按天汇总。累计增长位于其构成来源——每日新增——的正上方,二者可相互对照:稳定的自然增长与短暂的突增形态截然不同。当这一差别可被衡量时,它会作为增长真实性予以报告。

025507510012515013432013-012019-102026-07
主版本 5次版本 36修订 52

每个点涵盖 13 天。

OpenSSF Scorecard 5.0 / 10
5.0综合

来自开源项目 OpenSSF Scorecard 的独立、工具无关的安全评估。每项检查奖励的是安全实践本身,而非特定供应商的工具。Scorecard 无法判定的检查项标记为 不适用,并从安全评分中剔除(绝不按零分计)。Scorecard v5.5.0 · 2026-08-02 12:02 UTC

10Binary-Artifactsno binaries found in the repo
1Branch-Protectionbranch protection is not maximal on development and all release branches
10CI-Tests19 out of 19 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/29 approved changesets -- score normalized to 0
10Contributorsproject has 13 contributing companies or organizations
不适用Dangerous-Workflowno workflows found
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
不适用Packagingpackaging workflow not detected
不适用Pinned-Dependenciesno dependencies found
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
不适用Signed-Releasesno releases found
不适用Token-PermissionsNo tokens found
6Vulnerabilities4 existing vulnerabilities detected
直接依赖 2
注册表软件包版本约束清单文件
Packagistbrick/varexporter^0.5.0 || ^0.6.0 || ^0.7.0composer.json
Packagistcakephp/cakephp^5.1.1composer.json
全部依赖 186

来自 GitHub 依赖图的完整解析依赖集合:2 个直接依赖与 184 个间接(传递)软件包。仓库提交锁文件时,传递闭包才是完整的。

注册表软件包版本关系
Packagistbrick/varexporter直接
Packagistcakephp/cakephp直接
npm@algolia/abtesting1.18.0间接
npm@algolia/autocomplete-core1.17.7间接
npm@algolia/autocomplete-plugin-algolia-insights1.17.7间接
npm@algolia/autocomplete-preset-algolia1.17.7间接
npm@algolia/autocomplete-shared1.17.7间接
npm@algolia/client-abtesting5.52.0间接
npm@algolia/client-analytics5.52.0间接
npm@algolia/client-common5.52.0间接
npm@algolia/client-insights5.52.0间接
npm@algolia/client-personalization5.52.0间接
npm@algolia/client-query-suggestions5.52.0间接
npm@algolia/client-search5.52.0间接
npm@algolia/ingestion1.52.0间接
npm@algolia/monitoring1.52.0间接
npm@algolia/recommend5.52.0间接
npm@algolia/requester-browser-xhr5.52.0间接
npm@algolia/requester-fetch5.52.0间接
npm@algolia/requester-node-http5.52.0间接
npm@babel/helper-string-parser7.27.1间接
npm@babel/helper-validator-identifier7.28.5间接
npm@babel/parser7.29.3间接
npm@babel/types7.29.0间接
npm@docsearch/css3.8.2间接
npm@docsearch/js3.8.2间接
npm@docsearch/react3.8.2间接
npm@esbuild/aix-ppc640.21.5间接
npm@esbuild/android-arm0.21.5间接
npm@esbuild/android-arm640.21.5间接
npm@esbuild/android-x640.21.5间接
npm@esbuild/darwin-arm640.21.5间接
npm@esbuild/darwin-x640.21.5间接
npm@esbuild/freebsd-arm640.21.5间接
npm@esbuild/freebsd-x640.21.5间接
npm@esbuild/linux-arm0.21.5间接
npm@esbuild/linux-arm640.21.5间接
npm@esbuild/linux-ia320.21.5间接
npm@esbuild/linux-loong640.21.5间接
npm@esbuild/linux-mips64el0.21.5间接
npm@esbuild/linux-ppc640.21.5间接
npm@esbuild/linux-riscv640.21.5间接
npm@esbuild/linux-s390x0.21.5间接
npm@esbuild/linux-x640.21.5间接
npm@esbuild/netbsd-x640.21.5间接
npm@esbuild/openbsd-x640.21.5间接
npm@esbuild/sunos-x640.21.5间接
npm@esbuild/win32-arm640.21.5间接
npm@esbuild/win32-ia320.21.5间接
npm@esbuild/win32-x640.21.5间接
npm@iconify-json/simple-icons1.2.80间接
npm@iconify/types2.0.0间接
npm@jridgewell/sourcemap-codec1.5.5间接
npm@rollup/rollup-android-arm-eabi4.60.2间接
npm@rollup/rollup-android-arm644.60.2间接
npm@rollup/rollup-darwin-arm644.60.2间接
npm@rollup/rollup-darwin-x644.60.2间接
npm@rollup/rollup-freebsd-arm644.60.2间接
npm@rollup/rollup-freebsd-x644.60.2间接
npm@rollup/rollup-linux-arm-gnueabihf4.60.2间接
npm@rollup/rollup-linux-arm-musleabihf4.60.2间接
npm@rollup/rollup-linux-arm64-gnu4.60.2间接
npm@rollup/rollup-linux-arm64-musl4.60.2间接
npm@rollup/rollup-linux-loong64-gnu4.60.2间接
npm@rollup/rollup-linux-loong64-musl4.60.2间接
npm@rollup/rollup-linux-ppc64-gnu4.60.2间接
npm@rollup/rollup-linux-ppc64-musl4.60.2间接
npm@rollup/rollup-linux-riscv64-gnu4.60.2间接
npm@rollup/rollup-linux-riscv64-musl4.60.2间接
npm@rollup/rollup-linux-s390x-gnu4.60.2间接
npm@rollup/rollup-linux-x64-gnu4.60.2间接
npm@rollup/rollup-linux-x64-musl4.60.2间接
npm@rollup/rollup-openbsd-x644.60.2间接
npm@rollup/rollup-openharmony-arm644.60.2间接
npm@rollup/rollup-win32-arm64-msvc4.60.2间接
npm@rollup/rollup-win32-ia32-msvc4.60.2间接
npm@rollup/rollup-win32-x64-gnu4.60.2间接
npm@rollup/rollup-win32-x64-msvc4.60.2间接
npm@shikijs/core2.5.0间接
npm@shikijs/engine-javascript2.5.0间接
npm@shikijs/engine-oniguruma2.5.0间接
npm@shikijs/langs2.5.0间接
npm@shikijs/themes2.5.0间接
npm@shikijs/transformers2.5.0间接
npm@shikijs/types2.5.0间接
npm@shikijs/vscode-textmate10.0.2间接
npm@types/estree1.0.8间接
npm@types/hast3.0.4间接
npm@types/linkify-it5.0.0间接
npm@types/markdown-it14.1.2间接
npm@types/mdast4.0.4间接
npm@types/mdurl2.0.0间接
npm@types/unist3.0.3间接
npm@types/web-bluetooth0.0.21间接
npm@ungap/structured-clone1.3.0间接
npm@vitejs/plugin-vue5.2.4间接
npm@vue/compiler-core3.5.33间接
npm@vue/compiler-dom3.5.33间接
npm@vue/compiler-sfc3.5.33间接
npm@vue/compiler-ssr3.5.33间接
npm@vue/devtools-api7.7.9间接
npm@vue/devtools-kit7.7.9间接
npm@vue/devtools-shared7.7.9间接
npm@vue/reactivity3.5.33间接
npm@vue/runtime-core3.5.33间接
npm@vue/runtime-dom3.5.33间接
npm@vue/server-renderer3.5.33间接
npm@vue/shared3.5.33间接
npm@vueuse/core12.8.2间接
npm@vueuse/integrations12.8.2间接
npm@vueuse/metadata12.8.2间接
npm@vueuse/shared12.8.2间接
npmalgoliasearch5.52.0间接
npmbirpc2.9.0间接
npmccount2.0.1间接
npmcharacter-entities-html42.1.0间接
npmcharacter-entities-legacy3.0.0间接
npmcomma-separated-tokens2.0.3间接
npmcopy-anything4.0.5间接
npmcsstype3.2.3间接
npmdequal2.0.3间接
npmdevlop1.1.0间接
npmemoji-regex-xs1.0.0间接
npmentities7.0.1间接
npmesbuild0.21.5间接
npmestree-walker2.0.2间接
npmfocus-trap7.8.0间接
npmfsevents2.3.3间接
npmhast-util-to-html9.0.5间接
npmhast-util-whitespace3.0.0间接
npmhookable5.5.3间接
npmhtml-void-elements3.0.0间接
npmis-what5.5.0间接
npmmagic-string0.30.21间接
npmmark.js8.11.1间接
npmmdast-util-to-hast13.2.1间接
npmmicromark-util-character2.1.1间接
npmmicromark-util-encode2.0.1间接
npmmicromark-util-sanitize-uri2.0.1间接
npmmicromark-util-symbol2.0.1间接
npmmicromark-util-types2.0.2间接
npmminisearch7.2.0间接
npmmitt3.0.1间接
npmnanoid3.3.16间接
npmoniguruma-to-es3.1.1间接
npmperfect-debounce1.0.0间接
npmpicocolors1.1.1间接
npmpostcss8.5.25间接
npmpreact10.29.1间接
npmproperty-information7.1.0间接
npmregex6.1.0间接
npmregex-recursion6.0.2间接
npmregex-utilities2.3.0间接
npmrfdc1.4.1间接
npmrollup4.60.2间接
npmsearch-insights2.17.3间接
npmshiki2.5.0间接
npmsource-map-js1.2.1间接
npmspace-separated-tokens2.0.2间接
npmspeakingurl14.0.1间接
npmstringify-entities4.0.4间接
npmsuperjson2.2.6间接
npmtabbable6.4.0间接
npmtrim-lines3.0.1间接
npmunist-util-is6.0.1间接
npmunist-util-position5.0.0间接
npmunist-util-stringify-position4.0.0间接
npmunist-util-visit5.1.0间接
npmunist-util-visit-parents6.0.2间接
npmvfile6.0.3间接
npmvfile-message4.0.3间接
npmvite5.4.21间接
npmvitepress1.6.4间接
npmvue3.5.33间接
npmzwitch2.0.4间接
Packagistcakedc/cakephp-phpstan间接
Packagistcakephp/bake间接
Packagistcakephp/migrations间接
Packagistdereuromark/cakephp-dto间接
Packagistdereuromark/cakephp-ide-helper间接
Packagistdereuromark/cakephp-templating间接
Packagistdereuromark/cakephp-tools间接
Packagistfig-r/psr2r-sniffer间接
Packagistfriendsofcake/search间接
Packagistphp间接
Packagistphpunit/phpunit间接
依赖安全公告 2

该仓库未发布可被索引解析的包,因此评估的是其自身的依赖图——共 173 个包,其中也包含从不交付的开发与测试版本固定:2 个存在已知公告,0 个为直接依赖。 有 13 个无法评估——没有已解析的版本、生态系统不受支持,或不在所列包清单之内。

软件包版本关系严重程度公告数修复版本
vite5.4.21间接38.0.16
esbuild0.21.5间接10.25.0

公告表示依赖图中记录的版本落入某条公告的受影响范围。可达性未经分析,且依赖图包含开发与测试的版本固定——某项发现可能只涉及工具链而非交付的软件。

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [
        "asynchronous",
        "background-jobs",
        "cronjob",
        "queue",
        "cakephp",
        "cakephp-plugin",
        "php"
      ],
      "is_fork": false,
      "size_kb": 2208,
      "has_wiki": true,
      "homepage": "https://dereuromark.github.io/cakephp-queue/",
      "languages": {
        "PHP": 558960,
        "Twig": 696
      },
      "pushed_at": "2026-08-02T11:54:00Z",
      "created_at": "2011-10-09T17:09:44Z",
      "owner_type": "User",
      "updated_at": "2026-08-02T11:54:14Z",
      "description": "Queue plugin for CakePHP - simple, pure PHP and without dependencies.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "master",
      "license_spdx_raw": "MIT",
      "primary_language": "PHP",
      "significant_languages": [
        "PHP"
      ]
    },
    "owner": {
      "blog": "https://www.dereuromark.de/",
      "name": "Mark Scherer",
      "type": "User",
      "login": "dereuromark",
      "company": "Available as (Cake)PHP expert",
      "location": "Berlin",
      "followers": 748,
      "avatar_url": "https://avatars.githubusercontent.com/u/39854?v=4",
      "created_at": "2008-12-11T16:33:44Z",
      "is_verified": null,
      "public_repos": 123,
      "account_age_days": 6442
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "8.15.1",
          "kind": "patch",
          "published_at": "2026-06-06T20:11:41Z"
        },
        {
          "tag": "8.15.0",
          "kind": "minor",
          "published_at": "2026-05-28T16:52:06Z"
        },
        {
          "tag": "8.14.0",
          "kind": "minor",
          "published_at": "2026-05-14T02:02:30Z"
        },
        {
          "tag": "8.13.0",
          "kind": "minor",
          "published_at": "2026-05-03T15:51:13Z"
        },
        {
          "tag": "8.12.0",
          "kind": "minor",
          "published_at": "2026-04-30T15:54:40Z"
        },
        {
          "tag": "8.11.0",
          "kind": "minor",
          "published_at": "2026-04-27T13:24:49Z"
        },
        {
          "tag": "8.10.2",
          "kind": "patch",
          "published_at": "2026-04-17T18:51:24Z"
        },
        {
          "tag": "8.10.1",
          "kind": "patch",
          "published_at": "2026-04-17T14:33:22Z"
        },
        {
          "tag": "8.10.0",
          "kind": "minor",
          "published_at": "2026-04-02T14:57:18Z"
        },
        {
          "tag": "8.9.1",
          "kind": "patch",
          "published_at": "2026-03-17T21:54:32Z"
        },
        {
          "tag": "8.9.0",
          "kind": "minor",
          "published_at": "2026-01-29T18:35:58Z"
        },
        {
          "tag": "8.8.0",
          "kind": "minor",
          "published_at": "2026-01-11T03:11:38Z"
        },
        {
          "tag": "8.7.0",
          "kind": "minor",
          "published_at": "2026-01-04T04:45:56Z"
        },
        {
          "tag": "8.6.2",
          "kind": "patch",
          "published_at": "2025-12-20T00:09:56Z"
        },
        {
          "tag": "8.6.1",
          "kind": "patch",
          "published_at": "2025-11-22T10:00:44Z"
        },
        {
          "tag": "8.6.0",
          "kind": "minor",
          "published_at": "2025-11-21T15:18:10Z"
        },
        {
          "tag": "8.5.2",
          "kind": "patch",
          "published_at": "2025-11-10T21:05:18Z"
        },
        {
          "tag": "8.5.1",
          "kind": "patch",
          "published_at": "2025-10-30T21:10:11Z"
        },
        {
          "tag": "6.9.3",
          "kind": "patch",
          "published_at": "2025-09-12T11:49:35Z"
        },
        {
          "tag": "8.5.0",
          "kind": "minor",
          "published_at": "2025-09-16T12:05:29Z"
        },
        {
          "tag": "8.4.0",
          "kind": "minor",
          "published_at": "2025-08-16T22:36:19Z"
        },
        {
          "tag": "8.3.1",
          "kind": "patch",
          "published_at": "2025-08-08T18:50:50Z"
        },
        {
          "tag": "8.3.0",
          "kind": "minor",
          "published_at": "2025-06-12T11:33:54Z"
        },
        {
          "tag": "6.9.2",
          "kind": "patch",
          "published_at": "2025-05-08T01:33:17Z"
        },
        {
          "tag": "8.2.4",
          "kind": "patch",
          "published_at": "2025-05-01T10:45:12Z"
        },
        {
          "tag": "8.2.3",
          "kind": "patch",
          "published_at": "2025-03-21T12:09:25Z"
        },
        {
          "tag": "8.2.2",
          "kind": "patch",
          "published_at": "2025-03-12T01:04:40Z"
        },
        {
          "tag": "8.2.1",
          "kind": "patch",
          "published_at": "2025-03-10T02:30:11Z"
        },
        {
          "tag": "8.2.0",
          "kind": "minor",
          "published_at": "2024-11-18T14:22:50Z"
        },
        {
          "tag": "8.1.1",
          "kind": "patch",
          "published_at": "2024-07-18T13:24:42Z"
        },
        {
          "tag": "8.1.0",
          "kind": "minor",
          "published_at": "2024-07-03T10:36:33Z"
        },
        {
          "tag": "8.0.0",
          "kind": "major",
          "published_at": "2024-03-11T22:47:54Z"
        },
        {
          "tag": "7.2.3",
          "kind": "patch",
          "published_at": "2024-03-09T16:24:55Z"
        },
        {
          "tag": "8.0.0-RC",
          "kind": "prerelease",
          "published_at": "2024-03-07T22:50:18Z"
        },
        {
          "tag": "7.2.2",
          "kind": "patch",
          "published_at": "2024-03-06T15:12:44Z"
        },
        {
          "tag": "7.2.1",
          "kind": "patch",
          "published_at": "2024-02-23T18:14:29Z"
        },
        {
          "tag": "7.2.0",
          "kind": "minor",
          "published_at": "2024-02-07T23:33:42Z"
        },
        {
          "tag": "7.1.3",
          "kind": "patch",
          "published_at": "2024-01-23T06:24:07Z"
        },
        {
          "tag": "7.1.2",
          "kind": "patch",
          "published_at": "2023-12-11T22:25:37Z"
        },
        {
          "tag": "6.9.1",
          "kind": "patch",
          "published_at": "2023-12-04T22:17:08Z"
        },
        {
          "tag": "7.1.1",
          "kind": "patch",
          "published_at": "2023-12-02T23:58:44Z"
        },
        {
          "tag": "6.9.0",
          "kind": "minor",
          "published_at": "2023-11-28T12:34:29Z"
        },
        {
          "tag": "7.1.0",
          "kind": "minor",
          "published_at": "2023-11-28T19:26:57Z"
        },
        {
          "tag": "7.0.1",
          "kind": "patch",
          "published_at": "2023-11-27T20:47:02Z"
        },
        {
          "tag": "6.8.0",
          "kind": "minor",
          "published_at": "2023-10-25T17:33:50Z"
        },
        {
          "tag": "7.0.0",
          "kind": "major",
          "published_at": "2023-10-30T10:41:58Z"
        },
        {
          "tag": "7.0.0-RC",
          "kind": "prerelease",
          "published_at": "2023-09-28T21:44:57Z"
        },
        {
          "tag": "6.7.2",
          "kind": "patch",
          "published_at": "2023-09-10T08:43:21Z"
        },
        {
          "tag": "6.7.1",
          "kind": "patch",
          "published_at": "2023-06-19T12:27:57Z"
        },
        {
          "tag": "6.7.0",
          "kind": "minor",
          "published_at": "2023-04-23T23:08:00Z"
        },
        {
          "tag": "6.6.2",
          "kind": "patch",
          "published_at": "2023-03-27T14:39:59Z"
        },
        {
          "tag": "6.6.1",
          "kind": "patch",
          "published_at": "2023-03-12T15:03:49Z"
        },
        {
          "tag": "6.6.0",
          "kind": "minor",
          "published_at": "2023-01-04T17:22:52Z"
        },
        {
          "tag": "6.5.0",
          "kind": "minor",
          "published_at": "2022-10-14T22:04:47Z"
        },
        {
          "tag": "6.4.4",
          "kind": "patch",
          "published_at": "2022-10-13T10:31:35Z"
        },
        {
          "tag": "6.4.3",
          "kind": "patch",
          "published_at": "2022-08-19T11:49:48Z"
        },
        {
          "tag": "6.4.2",
          "kind": "patch",
          "published_at": "2022-08-18T20:22:20Z"
        },
        {
          "tag": "6.4.1",
          "kind": "patch",
          "published_at": "2022-06-22T12:01:50Z"
        },
        {
          "tag": "6.4.0",
          "kind": "minor",
          "published_at": "2022-06-16T19:51:18Z"
        },
        {
          "tag": "6.3.2",
          "kind": "patch",
          "published_at": "2022-05-03T11:07:00Z"
        },
        {
          "tag": "6.3.1",
          "kind": "patch",
          "published_at": "2022-03-10T13:32:52Z"
        },
        {
          "tag": "6.3.0",
          "kind": "minor",
          "published_at": "2022-03-02T14:07:13Z"
        },
        {
          "tag": "6.2.2",
          "kind": "patch",
          "published_at": "2022-01-16T15:06:52Z"
        },
        {
          "tag": "6.2.1",
          "kind": "patch",
          "published_at": "2021-11-17T15:45:47Z"
        },
        {
          "tag": "6.2.0",
          "kind": "minor",
          "published_at": "2021-11-11T14:34:25Z"
        },
        {
          "tag": "6.1.0",
          "kind": "minor",
          "published_at": "2021-10-27T06:34:47Z"
        },
        {
          "tag": "6.0.2",
          "kind": "patch",
          "published_at": "2021-09-14T18:38:02Z"
        },
        {
          "tag": "6.0.1",
          "kind": "patch",
          "published_at": "2021-07-12T09:04:32Z"
        },
        {
          "tag": "6.0.0",
          "kind": "major",
          "published_at": "2021-07-11T10:48:28Z"
        },
        {
          "tag": "6.0.0-beta",
          "kind": "prerelease",
          "published_at": "2021-07-04T12:04:29Z"
        },
        {
          "tag": "6.0.0-alpha",
          "kind": "prerelease",
          "published_at": "2021-06-13T15:09:11Z"
        },
        {
          "tag": "4.4.1",
          "kind": "patch",
          "published_at": "2023-01-03T14:16:51Z"
        },
        {
          "tag": "5.4.0",
          "kind": "minor",
          "published_at": "2021-05-18T22:24:02Z"
        },
        {
          "tag": "5.3.0",
          "kind": "minor",
          "published_at": "2021-02-18T12:23:24Z"
        },
        {
          "tag": "5.2.1",
          "kind": "patch",
          "published_at": "2020-12-17T13:25:43Z"
        },
        {
          "tag": "5.2.0",
          "kind": "minor",
          "published_at": "2020-12-02T12:59:14Z"
        },
        {
          "tag": "5.1.0",
          "kind": "minor",
          "published_at": "2020-10-12T16:40:46Z"
        },
        {
          "tag": "5.0.3",
          "kind": "patch",
          "published_at": "2020-07-19T14:23:07Z"
        },
        {
          "tag": "5.0.2",
          "kind": "patch",
          "published_at": "2020-04-24T01:20:06Z"
        },
        {
          "tag": "5.0.1",
          "kind": "patch",
          "published_at": "2020-04-17T19:04:55Z"
        },
        {
          "tag": "5.0.0",
          "kind": "major",
          "published_at": "2020-04-13T21:34:45Z"
        },
        {
          "tag": "4.4.0",
          "kind": "minor",
          "published_at": "2020-03-07T15:52:48Z"
        },
        {
          "tag": "4.3.1",
          "kind": "patch",
          "published_at": "2020-03-05T22:21:12Z"
        },
        {
          "tag": "5.0.0-rc",
          "kind": "prerelease",
          "published_at": "2020-01-17T17:06:28Z"
        },
        {
          "tag": "4.3.0",
          "kind": "minor",
          "published_at": "2020-01-17T17:02:44Z"
        },
        {
          "tag": "4.2.3",
          "kind": "patch",
          "published_at": "2020-01-15T02:18:39Z"
        },
        {
          "tag": "5.0.0-beta",
          "kind": "prerelease",
          "published_at": "2019-12-28T00:57:15Z"
        },
        {
          "tag": "4.2.2",
          "kind": "patch",
          "published_at": "2019-12-23T14:46:46Z"
        },
        {
          "tag": "4.2.1",
          "kind": "patch",
          "published_at": "2019-11-28T00:42:43Z"
        },
        {
          "tag": "4.2.0",
          "kind": "minor",
          "published_at": "2019-10-31T09:22:55Z"
        },
        {
          "tag": "4.1.1",
          "kind": "patch",
          "published_at": "2019-10-30T14:25:45Z"
        },
        {
          "tag": "4.1.0",
          "kind": "minor",
          "published_at": "2019-09-12T10:37:27Z"
        },
        {
          "tag": "4.0.1",
          "kind": "patch",
          "published_at": "2019-08-07T11:36:53Z"
        },
        {
          "tag": "4.0.0",
          "kind": "major",
          "published_at": "2019-08-02T08:55:06Z"
        },
        {
          "tag": "4.0.0-RC",
          "kind": "prerelease",
          "published_at": "2019-07-23T22:12:05Z"
        },
        {
          "tag": "3.16.2",
          "kind": "patch",
          "published_at": "2019-04-08T12:30:23Z"
        },
        {
          "tag": "3.16.1",
          "kind": "patch",
          "published_at": "2019-03-25T18:21:02Z"
        },
        {
          "tag": "3.16.0",
          "kind": "minor",
          "published_at": "2019-03-20T20:22:01Z"
        },
        {
          "tag": "3.15.1",
          "kind": "patch",
          "published_at": "2019-03-13T15:06:22Z"
        },
        {
          "tag": "3.15.0",
          "kind": "minor",
          "published_at": "2019-03-08T14:05:22Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "2c1a1bfc69ccb44b62f7f2e2b60f53d4dc2a5399",
          "body": "Bumps [postcss](https://github.com/postcss/postcss) from 8.5.13 to 8.5.25.\n- [Release notes](https://github.com/postcss/postcss/releases)\n- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/postcss/postcss/compare/8.5.13...8.5.25)\n\n---\nupdated-depe\n[…]\nss\n  dependency-version: 8.5.25\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump postcss from 8.5.13 to 8.5.25 in /docs (#512)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-08-02T11:53:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "585681d0b4d81df9628b302f0cb68210cffa7f19",
          "body": null,
          "is_bot": false,
          "headline": "Fix PHPStan annotations for CakePHP 5.4 (#511)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-06-28T10:32:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "595f7b5e38f16123bb3e86e9780854d3fb453fd7",
          "body": "actions/cache@v1-v4 declare Node 20, which GitHub now deprecates and\nforce-runs on Node 24. v5 is Node 24 native and removes the warning.",
          "is_bot": false,
          "headline": "CI: bump actions/cache to v5 (Node 24)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-06-28T09:41:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "64fe313969d3017ab8709e2f9b29a78aa75c4da0",
          "body": "…#508)\n\n* Truncate failure_message so recording a large failure cannot crash the worker\n\nmarkJobFailed() stored the failure message and captured output verbatim into the\nfailure_message / output TEXT columns. A failure larger than the column (e.g. a\ndatabase error that echoes a huge multi-row query)\n[…]\norts an error on the dynamic $this->$action() call,\nso the @phpstan-ignore-next-line became an unmatched (failing) ignore. Cast the\nresult to int to satisfy the declared return type without an ignore.",
          "is_bot": false,
          "headline": "Truncate failure_message so a large failure cannot crash the worker (…",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-06-06T16:09:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "981b67f18bba9fb88edd7705470026af06a4fcdb",
          "body": "…rted label (#507)\n\n* Label dashboard Failed card as Requeued/Failed\n\nThe card counts every unfinished job with a failure_message, which includes\nstill-retrying (requeued, attempts <= retries) jobs as well as terminally\nfailed/aborted ones. The label now reflects both so a job on attempt 1/2 is\nnot \n[…]\nelper, the Restarted branch in failureStatus()\n(returns null now for a running job with no failure), and the Restarted badge\nbranches in the admin templates. Such jobs now correctly render as Running.",
          "is_bot": false,
          "headline": "Dashboard status clarity: Requeued/Failed card + drop ambiguous Resta…",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-28T16:48:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f607a614b63bdc4e7ed0d2852737f99babdb9e1a",
          "body": "… aborted exclusion (#506)\n\n- getLength() now reuses pendingConditions() so it excludes terminally\n  aborted jobs, matching getPendingCount()/getPendingStats(). This fixes\n  the admin \"Pending Jobs (new/current)\" card header showing a count that\n  the (aborted-aware) pending list below it did not co\n[…]\nd stat-card count.\n- Dashboard Scheduled/Pending/Running/Failed stat cards now link to the\n  job index filtered by the matching status, so they are clickable and\n  land on exactly the jobs they count.",
          "is_bot": false,
          "headline": "Link dashboard stat cards to filtered job lists; align getLength with…",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-28T16:35:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b27c1804201a28672b545c19231e61d51024b3e9",
          "body": "* Exclude aborted jobs from pending count and stats\n\ngetPendingCount() and getPendingStats() counted jobs that had exhausted\ntheir retries (status = aborted) even though they are terminal and will\nnever run again. That inflated the admin pending total and any external\ncaller. They now exclude status\n[…]\nk).\n- reset() now clears status so a reset job loses its terminal aborted\n  state and counts as pending and gets picked up again.\n\n* Order union type hint as object|array|null to satisfy psr2r-sniffer",
          "is_bot": false,
          "headline": "Exclude aborted jobs from pending count and stats (#505)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-28T16:12:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4b4b9346e8b60ebf1bd637c111794f5dc55e4180",
          "body": "… (#504)\n\nA job with `completed IS NULL` is treated as queued/in-progress by\nisQueued(), the admin \"in_progress\" filter, and the status badge. That\nconflates three different things: pending, actively running, and\npermanently failed. Once a job exhausts its retries it will never run\nagain, yet it kee\n[…]\nble failures are untouched: while attempts remain the job is\ngenuinely in flight and still counts as queued, so there is no early\nre-dispatch or pile-up. flushFailedJobs() continues to prune old rows.",
          "is_bot": false,
          "headline": "Persist terminal \"aborted\" state so dead jobs stop counting as queued…",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-28T13:41:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "25b2c0825ab2a9c48fe3d09f3f478eb932a2a78f",
          "body": null,
          "is_bot": false,
          "headline": "Add sort direction indicators to admin tables",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-26T21:13:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "907be37d6f7fc3848f271da225da16b7f7faf824",
          "body": "* Bump dto to v3\n\n* Keep dto interface optional at runtime\n\n* Conflict with old dto major",
          "is_bot": false,
          "headline": "Bump dto to v3 (#502)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-25T23:24:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c941aea0fcaa33579415a4de415bccc4438e5307",
          "body": "* Run PHPCS cleanup\n\n* Address queue review follow-ups\n\n* Remove stale queue results annotation\n\n* Restore !empty ternary in queue cleanup\n\n* Fix queue rebase marker\n\n* Fix queue review follow-up\n\n* Fix queue process status typing",
          "is_bot": false,
          "headline": "Apply conservative Rector cleanup (#501)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-25T13:52:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d01d1a4f90082772efb8a7f9a4b225870877adec",
          "body": "* Apply conservative Rector cleanup\n\n* Run PHPCS cleanup\n\n* Restore safe typed property checks\n\n* Restore compact() for matching view vars\n\n* Address queue review follow-ups\n\n* Restore compact() for matching view vars\n\n* Fix queue cleanup regressions\n\n* Fix queue static analysis types",
          "is_bot": false,
          "headline": "Apply conservative Rector cleanup (#500)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-25T12:02:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "07370531a2de90f09b6f6044da17f151ae5a9c35",
          "body": "Point readers to https://toolbox.dereuromark.de/dbml so they can convert this\nDBML snapshot into the migration or raw SQL they need for their own app.",
          "is_bot": false,
          "headline": "Link the DBML converter in the schema snapshot",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-23T15:54:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9ba2e7706199c6af81a884f67bfd0d4c4b3b5ad4",
          "body": "Hand-maintained DBML snapshot of the plugin's migration schema under\nresources/schema/schema.dbml — paste into dbdiagram.io to view/diagram.\nMirrors the snapshot already shipped by cakephp-workflow.",
          "is_bot": false,
          "headline": "Add DBML database schema snapshot",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-23T12:54:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c0ca5b238b9535811fb8d7520e443b6fb25fbaa6",
          "body": null,
          "is_bot": false,
          "headline": "Move CONTRIBUTING.md to .github/ and refresh",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-22T18:51:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cb477f86f9986a62a1a485ac72839e7aee8f4fcf",
          "body": "- Set cleanUrls so doc pages drop the .html suffix (works on GitHub Pages)\n- Bump deploy-docs actions to the Node 24 majors ahead of the Node 20\n  runner removal (checkout v6, setup-node v6, configure-pages v6,\n  upload-pages-artifact v5, deploy-pages v5)",
          "is_bot": false,
          "headline": "Enable clean docs URLs and update deploy actions to Node 24",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-21T17:24:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8f673503e841e7af3952d1af9c66c6ecb94ffea2",
          "body": null,
          "is_bot": false,
          "headline": "Document missing configuration keys in config/app.example.php",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-21T12:54:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d777481281aaea61d674c690ead6d2b74e7fcc75",
          "body": "The dashboard banner now distinguishes three states instead of two:\n\n- green Queue Running  (heartbeat < dashboardIdleAfter, 60s default)\n- yellow Queue Idle    (heartbeat >= dashboardIdleAfter, or no heartbeat\n                        and no backlog)\n- red Queue Stalled    (heartbeat >= dashboardSta\n[…]\n\nbanner to unrelated semantics. Installations with unusual cron cadence\n(e.g. slow exitwhennothingtodo cron) should raise dashboardStalledAfter\npast the cron interval to avoid false-red between ticks.",
          "is_bot": false,
          "headline": "Add red 'stalled' status to admin dashboard banner (#499)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-14T00:50:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "06abf178962758584c0fc0f330fac16880ca164a",
          "body": "When a fan-out dispatcher enqueues per-tenant work on every cron tick,\nplain `createJob()` happily inserts a duplicate row even if the previous\ntick's job for the same tenant is still pending or stuck. The result is\na slow accumulation of identical pending jobs -- in one observed case,\n5876 stuck `V\n[…]\nse that, but it requires a migration and a decision on how callers\nshould opt in per-table -- out of scope for this PR. The 99%\neffectiveness already kills the slow-buildup scenario this is built\nfor.",
          "is_bot": false,
          "headline": "Add createJob(unique: true) for fan-out dedup (#498)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-13T17:17:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c575000df6f14cd749e5f70e184c68b61aca60e7",
          "body": "…s (#497)\n\n* Cap admin dashboard pending/scheduled details to avoid OOM on backlogs\n\nThe admin index unconditionally materialised every pending and every\nscheduled queued_jobs row, then passed both arrays to the view. With a\nrealistic backlog (thousands of unfetched pending jobs) the response\nballoo\n[…]\ntus=scheduled, matching the existing search-collection\nfilter names. Lands you exactly on the rows the truncated list\nrepresents instead of the full mixed list of completed + failed +\nrunning entries.",
          "is_bot": false,
          "headline": "Cap admin dashboard pending/scheduled details to avoid OOM on backlog…",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-13T16:41:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5854c7980797296b7bdc2ed932675ab64660a6e4",
          "body": "… doc (#496)\n\nTwo correctness bugs from the source-grounded review plus the ops-first\ndocumentation strategic item.\n\n1. Processor::captureOutput() cached the auto-detected schema result for\n   the lifetime of the worker. A long-running worker started before\n   `bin/cake migrations migrate` added the\n[…]\ns\n   you add columns without restarting workers), multi-server pitfalls,\n   and common task-author traps. Linked from /guide/ and the sidebar.\n\nphpunit (186/186 + 7 skipped), phpstan, phpcs all clean.",
          "is_bot": false,
          "headline": "Fix captureOutput stale cache, ExecuteTask path tokenization; add ops…",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-13T16:32:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "06c5d48806b0292bf77f93bedeb62fe68c6f15de",
          "body": "The page-header pattern (title + action buttons in\n`d-flex justify-content-between align-items-center`) pushed buttons\noff-viewport on phones because no wrap was allowed. Wrap on viewports\n< sm so buttons fall to a new row instead of being clipped.",
          "is_bot": false,
          "headline": "Make page-header row wrap on phones so action buttons stay on-screen",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-11T23:38:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c9ad7b0feed5d8057ad23baf9d252e5104e50001",
          "body": "The default Bootstrap 5 placeholder color (--bs-secondary-color, ~#757575)\nis dark enough to look like real field values. Override to the gray-500\ntoken so empty fields read clearly as placeholders.",
          "is_bot": false,
          "headline": "Lighten form placeholder color so it's not mistaken for real content",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-11T22:01:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d3ad8f49d7b1d7f09a22d67bdc0aff09592fd205",
          "body": null,
          "is_bot": false,
          "headline": "Fix CS.",
          "author_name": "Mark",
          "author_login": "dereuromark",
          "committed_at": "2026-05-09T18:47:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a6d22e4de12ca5a1551901db697da05a69e040a6",
          "body": "Packagist already shows the GitHub repo under Source; the homepage\nfield is more useful pointing at the dedicated docs site.",
          "is_bot": false,
          "headline": "Point composer.json homepage at the VitePress docs site",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-09T13:42:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b4122ef21203c608d922af648e77f923a03399ea",
          "body": "…ue index (#495)\n\ntestAddDoesNotEvictRecentRowOnSamePidServer was asserting QueryException,\nwhich fired before #494 because the unique (pid, server) index rejected\nthe second insert. With the unique constraint dropped, the second insert\nsucceeds, so the test premise no longer holds and master CI fai\n[…]\n same (pid, server), assert the\npre-existing fresh row still exists. Coverage of the threshold check\nis preserved; the duplicate-allowed behavior is already covered by\ntestAddAllowsDuplicatePidServer.",
          "is_bot": false,
          "headline": "Fix eviction-guard test premise after dropping the (pid, server) uniq…",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-08T15:19:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0e93a9be6e858d78d05b6929a84dea64ec44e9df",
          "body": "…(#494)\n\nPID is not a stable worker identity. The OS recycles low PIDs across\ncontainer restarts, and the unique index on (pid, server) collides\nwhenever a containerized worker is replaced before its row is cleaned.\nworkerkey is already a UUID-style hash generated per process - the\ncorrect identity,\n[…]\niew:\n- Should worker end / kill accept --workerkey as an alternative to\n  PID for precise targeting?\n- Can the eviction logic added in PR #493 be removed once this lands,\n  or kept as belt-and-braces?",
          "is_bot": false,
          "headline": "Drop (pid, server) unique index; use workerkey as canonical identity …",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-08T15:04:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "85dbb81746ff691b914df23a191a073e29ec1a0d",
          "body": "Adds Queue.staleHeartbeatThreshold config (default 90s).\nQueueProcessesTable::add() now evicts a stale (pid, server) row whose\nmodified is older than the threshold *before* attempting the insert.\n\nFixes the crash loop seen on container restarts (FrankenPHP / Docker),\nwhere killed workers leave orpha\n[…]\neTimeout\n(default 10min): that one governs in-flight job requeueing and is\ndeliberately long; workers heartbeat far more often, so a row not\nrefreshed in 90s almost certainly belongs to a dead worker.",
          "is_bot": false,
          "headline": "Auto-evict stale queue_processes rows on worker startup (#493)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-08T15:03:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1f88ba5659fae73873d1040d7b18230cbfa066ef",
          "body": "… (#492)\n\nWhen a containerized worker is killed (SIGKILL, container restart) the\nqueue_processes row survives with a recent modified timestamp. The default\nheartbeat-based cleanEndedProcesses() considers the row \"still alive\" and\nkeeps it. The new worker, getting the same recycled PID, then crash-loops\non the unique (pid, server) index.\n\nThe --force flag wipes every queue_processes row in one shot so an operator\ncan recover without manual SQL.",
          "is_bot": false,
          "headline": "Add --force flag to queue worker clean for container-restart recovery…",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-08T14:50:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "637807436ab19eb01eaad85390a93c0e223a1e70",
          "body": "* Suppress idle-poll heartbeat unless verbose\n\nThe worker loop printed three lines every sleeptime() interval on an\nidle queue: a timestamped \"Looking for Job ...\", \"nothing to do,\nsleeping.\", and a horizontal-rule separator. On a mostly-idle worker\nthis fills logs and stdout with steady-state noise\n[…]\n-only steady-state output. Switch to the always-on\nevent lines that prove the same thing: \"terminating.\" for the empty-\nqueue worker loop, and \"Running Job of type \\\"Foo\\\"\" for the\njob-execution path.",
          "is_bot": false,
          "headline": "Suppress idle-poll heartbeat unless verbose (#491)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-06T22:20:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b724aaa51d13cf964e731657f8d3bae2241e38d9",
          "body": "Reads Queue.adminBackUrl + optional Queue.adminBackLabel (defaults to\n\"Back to App\"). Mirrors the same pattern in cakephp-audit-stash,\ncakephp-bouncer, cakephp-databaselog so apps can wire all four with one\nconsistent config shape.",
          "is_bot": false,
          "headline": "Add configurable Back-to-App link to admin header",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-04T12:30:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e0b5e0f0a538d8342593c6ec6a0f963148e90501",
          "body": "- Reorganize docs/ into guide/, tasks/, admin/, reference/ with kebab-case file names\n- Add VitePress config with sidebar nav, local search, sitemap, lastUpdated, brand-colored theme, and SVG logo\n- Add GitHub Pages deploy workflow building from docs/ on push to master\n- Move CONTRIBUTING.md back to\n[…]\noot for GitHub auto-link\n- Add docs URL to composer.json support metadata\n- Update root README.md to point to https://dereuromark.github.io/cakephp-queue/\n\nCo-authored-by: Mark <dereuromark@gmail.com>",
          "is_bot": false,
          "headline": "Migrate docs to VitePress (#489)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-04T02:48:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8c3a746ceea3a8bdfccf68ce5e701ac221cd1a8a",
          "body": "Re-extract resources/locales/queue.pot via cake i18n extract against the\ncurrent src/ and templates/. The committed POT had 110 msgids; current source\nhas 244 — 134 strings added in newer code that translators had no entry for.\n\nDrop the per-string \"#: ./src/...\" location comments from the previous\n\n[…]\ngenerations stay\ntidy (a single line move no longer reshuffles every entry's `#:` line). No\ncode changes — the plugin already uses __d('queue', ...) consistently\nthroughout (361 calls, single domain).",
          "is_bot": false,
          "headline": "Refresh queue.pot from current source (#488)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-04T02:16:49Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8a7c89c8ef6c06d4aa020be7088e3bbaec88c7a9",
          "body": "Switched the Paginator nav titles from escapeTitle => false to\nescape => false. PaginatorHelper only honors the escape option —\nescapeTitle is silently ignored — so the FontAwesome <i> tags fell back\nto the default escaped path and rendered as literal HTML text.\n\nVerified in cakephp/cakephp PaginatorHelper: prev/next/first/last/sort\nall use only the escape option, with no narrower title-only equivalent.",
          "is_bot": false,
          "headline": "Fix pagination icons rendering as raw text (#487)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-03T15:47:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "22cbe5b74a0c8c7ccd8179beb8328b15c834d6dd",
          "body": "Add the new allow-list config option to config/app.example.php (the\ncanonical inventory of Queue.* knobs) so users wiring up the plugin\ndiscover that production needs it.\n\nAdd an upgrading-doc subsection covering both the per-token\nescapeshellarg switch (callers with multi-token single-param entries\nmust split them) and the production allow-list requirement.",
          "is_bot": false,
          "headline": "Document Queue.executeAllowedCommands and ExecuteTask BC change (#486)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-02T14:42:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6443a03ab93a24840da0311cf922e04099469a26",
          "body": "The ExecuteTask previously concatenated `command` and each `params` entry\nthrough `escapeshellcmd()`, which only neutralizes shell metacharacters\n(`; & | $`, etc.) and does NOT defend against argument injection. A\npayload like `params => ['-r --some-flag /etc/passwd']` would still split\nacross addit\n[…]\nrg-injection token quoting and the allow-list deny/empty/allow paths\n(`ExecuteTaskTest.php`). Refresh the docs section to describe the new\nescaping primitive and the production allow-list requirement.",
          "is_bot": false,
          "headline": "Harden ExecuteTask with per-arg escapeshellarg and allow-list (#485)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-05-02T14:36:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "34e805092aa7b1f472f21f9711fe6df232654425",
          "body": "Using 'escape' => false also disables HTML escaping of attributes (URL, classes, title), not just the title text. The narrower 'escapeTitle' => false keeps attribute escaping on while still allowing the icon HTML in the title.",
          "is_bot": false,
          "headline": "Use escapeTitle instead of escape in pagination element (#483)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-30T23:07:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "64c95715882c02f8756c8d6be20e1d5d569829bd",
          "body": "The legacy raw-serialized branch in EmailTask::run() previously called unserialize() without an allowed_classes restriction, so a queue job whose 'class' was a Message subclass but whose 'settings' string contained a different gadget-chain class would deserialize that gadget. Anyone who can enqueue \n[…]\ninto RCE.\n\nPin the deserialization to the same Message subclass that was already validated for instantiation. Modern app code that passes settings as an array via EmailTask::serialize() is unaffected.",
          "is_bot": false,
          "headline": "Restrict unserialize to the configured Message class (#484)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-30T23:07:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "53865a78d0acf43a1e40e23e1d72429ba2b66d2e",
          "body": null,
          "is_bot": false,
          "headline": "Use ServerRequest import in app.example.php (CS fix)",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-30T15:52:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7c0e6b45b5e678671faf2422d236aaf266d60b97",
          "body": null,
          "is_bot": false,
          "headline": "Document Queue.adminAccess in app.example.php",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-30T15:17:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "19d73a87dc6fb8bf7ea7e90e8a2ca5942902cbe1",
          "body": "The Queue admin UI can trigger jobs (via AddFromBackendInterface tasks),\nreset / remove queued jobs, and terminate workers. Accidental exposure\nis operational damage waiting to happen.\n\nMirror the captcha plugin's \"fail closed\" pattern: the host app MUST\nconfigure Queue.adminAccess as a Closure that\n[…]\nan\n  example role-based gate.\n\nBackwards-incompatible: existing installs that just relied on host\nAppController gating will 403 until they add a Closure. Migration is\none line in config/bootstrap.php.",
          "is_bot": false,
          "headline": "Default-deny admin access via Queue.adminAccess Closure (#481)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-30T13:43:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "72e35b0213067db0819da22ca5dd33a135158c8f",
          "body": "* Sweep stale queue_processes rows on worker startup\n\nWorkers that die without graceful shutdown (SIGKILL, OOM, container\nrestart, anything that bypasses the SIGTERM handler) leave their\nqueue_processes row behind with terminate=0. Without intervention these\nghost rows accumulate and count toward Qu\n[…]\nat.\n\nRemoving both keeps the cleanup discipline clear (one canonical sweep\npoint per worker lifecycle) and saves a couple of needless DELETE\nqueries per worker. No behaviour change for the happy path.",
          "is_bot": false,
          "headline": "Sweep stale queue_processes rows on worker startup (#480)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-30T11:23:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0e8126f22e31f54d6aa1d41afa86cfeffe32d2cc",
          "body": null,
          "is_bot": false,
          "headline": "Adjust CS badge",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-28T16:58:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "39cf2e7a79ebea4b6aef6d8741a0865f916d4d38",
          "body": "* Add Queue.workerLifetimeJitter config to stagger worker shutdowns\n\nEach worker picks a random offset in [0, workerLifetimeJitter] at startup\nand adds it to its effective lifetime. Prevents thundering-herd restarts\nwhen a fleet of workers (e.g. ECS/Kubernetes tasks) is spawned at the\nsame instant a\n[…]\nainst a legacy CakePHP 2.x fork) by\nRommel Penaflor (@xrompdev) in #475; ported to the modern processor.\n\n* Add workerLifetimeJitter to app.example.php\n\n* Align worker lifetime jitter with PHP timeout",
          "is_bot": false,
          "headline": "Add Queue.workerLifetimeJitter to stagger worker shutdowns (#476)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-27T13:13:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0294a066343ea79dd2c9daabd5688ee28b094de2",
          "body": "* Move mobile-nav background to CSS class (strict-CSP)\n\nDrops the inline `style=\"background: linear-gradient(...)\"` attribute on the\nmobile offcanvas in favour of a `.queue-mobile-nav-bg` class that reuses the\nexisting `--queue-sidebar-bg` custom property. Removes the\n`style-src 'unsafe-inline'` req\n[…]\n's existing nonced `<script>`\n  reads them and assigns to `el.style` (JS-driven style mutation is not\n  subject to `style-src 'unsafe-inline'`).\n\nTemplates now contain zero inline `style=` attributes.",
          "is_bot": false,
          "headline": "Move mobile-nav background to CSS class (strict-CSP) (#479)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-26T22:29:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ef13c13820f29c7a2cd1a52d2a3132f1a019a108",
          "body": "- Add nonce attribute to inline <script> blocks (layout, stats chart)\n- Replace postLink+confirm with postButton+data-confirm-message across\n  all admin templates to eliminate inline onclick handlers that CSP\n  blocks without unsafe-inline / unsafe-hashes\n- JS delegate in the layout already intercep\n[…]\nnts and replicates the confirmation UX\n\nThis lets the admin UI work under a strict script-src CSP\n(e.g. \"script-src 'self' 'nonce-X' 'unsafe-eval'\") without needing\n'unsafe-inline' or 'unsafe-hashes'.",
          "is_bot": false,
          "headline": "Refactor admin UI to be CSP-compatible (#477)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-22T23:10:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bd2ccf02e194a688f6007225b21bd6146bb8ff3c",
          "body": "AddInterface::add() returns void and may silently skip queuing a job\nwhen required configuration is missing — most notably EmailTask, which\ndoes nothing when Config.adminEmail is not set.\n\nPreviously the controller showed a green success flash regardless,\nmaking it look like the admin UI had queued \n[…]\n't.\n\nNow we count QueuedJobs before/after invoking the task. If the count\ndid not increase, we show an error flash pointing the operator at the\nlikely config gap, instead of falsely reporting success.",
          "is_bot": false,
          "headline": "Fix silent no-op in Queue::addJob when task does not queue a job (#478)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-22T23:10:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "54105129a38ced1ce5f0b4ac601a35a00b42ebd0",
          "body": "… (#474)\n\n* Fix EmailTask undefined-method errors for serialized Message settings\n\nKeys coming from Message::__serialize()/jsonSerialize (htmlMessage,\ntextMessage, appCharset) don't map to set<Prop>() methods on Mailer or\nMessage, so passing them via queued JSON payloads failed with\n'Call to undefin\n[…]\nblem as the address maps: string keys would otherwise be\ninterpreted as named arguments when the generic loop spreads them into\n`setHeaders()`. Forward the map as a single positional argument instead.",
          "is_bot": false,
          "headline": "Fix EmailTask undefined-method errors for serialized Message settings…",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-17T18:05:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6eda87a2320430787169c0b90b02d76bba817a31",
          "body": "…472)\n\n* Fix EmailTask named-parameter error for associative address arrays\n\nPHP 8 treats string keys in the argument array of call_user_func_array()\nas named parameters, so queued payloads with an associative email => name\nmap for to/from/cc/bcc/replyTo would fail with 'Unknown named parameter'.\n\nRoute address setters through a helper that unpacks list-shaped values\npositionally (preserving the prior behavior) and forwards associative\nmaps as a single positional argument.\n\n* Fix CS",
          "is_bot": false,
          "headline": "Fix EmailTask named-parameter error for associative address arrays (#…",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-17T14:00:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a534d1f8e8d6478dc374025c0bba59a48be9876f",
          "body": null,
          "is_bot": false,
          "headline": "Fix pre element overflow in standalone layout",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-04-02T14:53:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "08ba64b9b3f97460cef364a04ce3b3c47adb2d28",
          "body": "Sets explicit Bootstrap 5 templates to avoid app/Tools templates\naffecting the standalone admin layout.",
          "is_bot": false,
          "headline": "Make pagination element fully standalone.",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-28T14:12:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5cea4b0241cc0cc29670ebfd2fc3348f9c53325f",
          "body": "Extract flash rendering logic into flash/flash.php element for cleaner\nlayout code and easier maintenance.",
          "is_bot": false,
          "headline": "Refactor flash rendering to use dedicated element.",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-28T13:45:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2a37a1145bd7ce55814a0f62f6ae8346ab1332c9",
          "body": null,
          "is_bot": false,
          "headline": "Fix datetime fields.",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-28T13:38:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "58c2bf6ca258839195e5407b0afb07b1f2c24157",
          "body": null,
          "is_bot": false,
          "headline": "Fix datetime fields.",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-28T13:24:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "697206e83ee638c69ddc05f2e5795a0366c47261",
          "body": "When invalid JSON is submitted via the data edit form, the\nJsonableBehavior threw a TypeError because json_decode returned null\nbut the return type was array.\n\nChanges:\n- Update _fromJson() to throw InvalidArgumentException with a\n  descriptive error message instead of TypeError\n- Catch the exceptio\n[…]\nlid input so they can fix it\n- Add data_string virtual property annotation to QueuedJob entity\n- Add test for invalid JSON handling\n- Fix PHPStan errors: handle nullable description() in example tasks",
          "is_bot": false,
          "headline": "Fix TypeError when editing queued job with invalid JSON payload (#468)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-28T12:57:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ba99af3b86fbb258e45950d79b201c5bd7b9cf59",
          "body": null,
          "is_bot": false,
          "headline": "Fix PHPStan errors: add type annotations for list query results (#467)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-19T20:47:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6ab3291329a62e91f22b173dfa75cfbe9dc70e86",
          "body": null,
          "is_bot": false,
          "headline": "Fix PHPStan errors for nullable description passed to io->out()",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-18T23:03:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4de7db1a840a109a67bcae4fb9a8d7cf6f58a05a",
          "body": null,
          "is_bot": false,
          "headline": "Add descr.",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-18T22:52:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1d41261d6067f91a7ccb54dbebcf82a61d9bcc2d",
          "body": null,
          "is_bot": false,
          "headline": "Add 'standalone-ui' to composer.json keywords",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-18T20:49:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c63f624f7a5e1b51830ea1fb891c9f1a6878b488",
          "body": "* Add multi-connection support for multiple databases\n\nAdd support for running queue workers and admin interface across\nmultiple database connections (e.g., primary and secondary databases).\n\nFeatures:\n- Configure connections via Queue.connections array in config\n- Connection switcher dropdown in ad\n[…]\nion to persist connection choice across requests\n- Query param ?connection=xxx sets session value\n- Connection switcher redirects to dashboard to avoid 404s\n- Fix CS issue with RuntimeException import",
          "is_bot": false,
          "headline": "Add multi-connection support for multiple databases (#465)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-18T17:52:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9f240b75ecc795c8f20df0b60bfde19898611058",
          "body": null,
          "is_bot": false,
          "headline": "Fix Icon helper loading - only load if Templating plugin available",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-18T17:05:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3eb9ec48861b7be437658b65473c1e4c11d96306",
          "body": null,
          "is_bot": false,
          "headline": "Add fallbacks for Tools/Shim helpers when plugins not loaded",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-18T17:03:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8781022aa908e0e1ee9490abcec358fc45ad0e0b",
          "body": null,
          "is_bot": false,
          "headline": "Add pagination element fallback when Tools plugin is not loaded",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-18T16:58:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "43291e8fb11e93f086e02f55250d71129d85bcfd",
          "body": null,
          "is_bot": false,
          "headline": "Add standalone option to app.example.php",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-18T16:44:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6639108fbfee7d23b5c5e821496b013c84e4f17f",
          "body": null,
          "is_bot": false,
          "headline": "Document Queue.standalone config option",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-18T16:42:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "54097a4ea4632e7d07b921b52e95824b2e8913c9",
          "body": "By default, QueueAppController extends App\\Controller\\AppController\nto inherit app authentication, components, and configuration (BC).\n\nSet `Queue.standalone` to `true` for an isolated admin that doesn't\ndepend on the host app's AppController setup.",
          "is_bot": false,
          "headline": "Restore AppController extension with standalone opt-in (#464)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-18T16:40:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "241f31d400c7521bebc7d9dd3f775e084d663ccb",
          "body": "* Add heatmap analytics for job activity visualization\n\n- Add getHeatmapData() method to QueuedJobsTable for aggregating jobs by day/hour\n- Add heatmap action to QueuedJobsController with filters for metric, days, and job type\n- Add heatmapColor() helper method for color gradient\n- Create heatmap te\n[…]\nd in layout)\n- Use expr() instead of deprecated newExpr()\n- Add comprehensive tests for getHeatmapData() method\n- Add tests for heatmapColor() helper method\n- Add controller tests for heatmap() action",
          "is_bot": false,
          "headline": "Add heatmap analytics for job activity visualization (#463)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-18T05:05:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "320c07b3183a6dedc99c312dcf38f5a255181011",
          "body": "- Add isRestarted() helper method to detect jobs that were manually reset\n  (have attempts but no failure_message)\n- Show \"Restarted\" badge (info/cyan) in all templates between Requeued and Running\n- Previously these jobs incorrectly showed as \"Running\"\n- Add comprehensive tests for isRestarted()",
          "is_bot": false,
          "headline": "Add Restarted status for manually reset jobs",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-18T04:31:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0b50781e66dd6f375a0a5db2651acb1df7c562f5",
          "body": "* Add modern isolated admin dashboard with Bootstrap 5\n\n- Create QueueAppController as isolated base for admin controllers\n- Add queue.php layout with Bootstrap 5.3.3 and Font Awesome 6.7.2 via CDN\n- Add reusable elements: sidebar, stats_card, status_badge, flash messages\n- Update admin templates wi\n[…]\nove dashboard stats display\n\n- Reorder stats cards: Scheduled → Pending → Running → Failed\n  (follows job lifecycle chronologically)\n- Add safeguard against negative pendingJobs count with max(0, ...)",
          "is_bot": false,
          "headline": "Add modern isolated admin dashboard with Bootstrap 5 (#461)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-18T04:14:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1baab99eeb73f77553bce89bbdf0e293cae01a2e",
          "body": "The duration() method is specific to the Tools TimeHelper. Applications\nnot using the Tools plugin would get a fatal error. This adds a\nmethod_exists check with a fallback to PHP's DateInterval::format().\n\nPort of #462 to master.",
          "is_bot": false,
          "headline": "Add runtime fallback for Tools Time->duration() method",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-17T21:51:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "32de0da594563ffd7ebd31d42ae80cba8b4e3796",
          "body": null,
          "is_bot": false,
          "headline": "Fix CS",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-17T19:57:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e60221ff99cdf3a202e9d9c56776200adf35391e",
          "body": "JsonableBehavior now uses Queue\\Database\\Type\\ArrayType instead of\nShim\\Database\\Type\\ArrayType, removing the undocumented dependency\non dereuromark/cakephp-shim.",
          "is_bot": false,
          "headline": "Add local ArrayType to remove hidden Shim plugin dependency",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-17T19:53:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f58ec4d15c378e33b716cf1c17b92288c7e65796",
          "body": "- relLengthOfTime() falls back to timeAgoInWords() from CakePHP core\n- Format->ok() calls now use Queue.ok element which has built-in fallback",
          "is_bot": false,
          "headline": "Add runtime fallbacks for Tools plugin dependencies in admin templates",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-17T19:49:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "465fa28eb73022edad5378a0d56281329735824f",
          "body": null,
          "is_bot": false,
          "headline": "Enable phpcs cache for faster subsequent runs",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-15T15:35:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8dc1db72045b6a563b4ebe9af5dbab50072773f8",
          "body": null,
          "is_bot": false,
          "headline": "Improve composer.json metadata",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-13T14:51:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b4ad201c5705d06f12efa1b0cdb0cba66aff07bd",
          "body": null,
          "is_bot": false,
          "headline": "Add admin-panel keyword",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-03-13T14:43:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0a52e9cc962f3325da79106670a92cd62e352453",
          "body": null,
          "is_bot": false,
          "headline": "Fix PHPStan type errors with entity annotations",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-02-28T00:02:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "474b5622a107772921159b0611d31c822ee41479",
          "body": null,
          "is_bot": false,
          "headline": "Allow PHPUnit 13",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-02-06T23:54:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fab07eea73cd9e5744c7913b898e32ec8795989c",
          "body": "- cakephp-tools ^3.12.0: fixes Message::addAttachment() signature\n  incompatibility with CakePHP 5.3\n- friendsofcake/search ^7.7.0: fixes searchManager/isSearch/searchParams\n  behavior call deprecations on CakePHP 5.3",
          "is_bot": false,
          "headline": "Bump minimum cakephp-tools and search plugin versions (#460)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-31T04:41:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7d7da44c7e5b0228bf936efda7829d10367b7745",
          "body": null,
          "is_bot": false,
          "headline": "Upgrade migrations dev dep",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-31T04:14:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "798f9afb1f1247e3175a4f8018c0372416e096b0",
          "body": "* Auto-detect captureOutput based on output column existence\n\nInstead of requiring explicit `Queue.captureOutput` configuration,\nthe Processor now auto-detects whether to capture output by checking\nif the `output` column exists on the `queued_jobs` table.\n\nExplicit config still takes precedence. The\n[…]\ntest\n\nWrap getSchema()->hasColumn() in try/catch to handle mock tables in tests\n(and any edge case in production). Suppress E_USER_DEPRECATED in\nInfoCommandTest that deliberately uses old config keys.",
          "is_bot": false,
          "headline": "Auto-detect captureOutput based on output column existence (#459)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-29T17:56:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b8b9e5d6cb4f99170c0547457f706f124cd25f40",
          "body": "* Add optional output capture for queue jobs\n\nIntroduce a new `Queue.captureOutput` config option that, when enabled,\ncaptures task stdout/stderr output and stores it in a new `output` text\ncolumn on the `queued_jobs` table. This allows reviewing job output in\nthe admin panel after execution, which \n[…]\nemory\n\nWorkerCommand.php:\n- Fix defaultName() collision with JobCommand (was 'queue job',\n  now 'queue worker')\n\nQueueProcessesTable.php:\n- Sanitize PID/signal as integers in terminateProcess() exec()",
          "is_bot": false,
          "headline": "Add optional output capture for queue jobs (#458) - fix edge case issues",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-29T10:37:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d8fd7254593dbdacede4952e1197ab3cff8b3de7",
          "body": null,
          "is_bot": false,
          "headline": "Update brick/varexporter version requirement",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-28T05:12:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f8a4435f12ea4c6ece94579dfeb51520242cc712",
          "body": null,
          "is_bot": false,
          "headline": "Raise PHP Min Version",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-28T05:02:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1418afb3860c5b2f153aa57005e98c41187b6aee",
          "body": "Add generic events for queue job lifecycle:\n- Queue.Job.created: when job is added to queue\n- Queue.Job.started: when job processing starts\n- Queue.Job.completed: when job completes successfully\n- Queue.Job.failed: when job fails\n\nAdd CakeSentryEventBridge listener that bridges these events to\nCakeSentry.Queue.* events for lordsimal/cakephp-sentry integration.\nUsers can enable it with: EventManager::instance()->on(new CakeSentryEventBridge())",
          "is_bot": false,
          "headline": "Add Queue.Job.* lifecycle events with optional Sentry bridge. (#453)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-11T03:10:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3800ca14b53ee82f13dba8ee08aedbe970f44e30",
          "body": "varexporter v7",
          "is_bot": false,
          "headline": "Merge pull request #457 from dereuromark/fix-docs-syntax",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-07T00:42:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "726c675e53f9c2c4bba2165948b9fc0415657947",
          "body": null,
          "is_bot": false,
          "headline": "varexporter v7",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-07T00:35:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2e46f97519a39848a7c2519a6b51118fbe6dff20",
          "body": "Fix missing semicolons in configuration.md examples",
          "is_bot": false,
          "headline": "Merge pull request #456 from dereuromark/fix-docs-syntax",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-04T05:01:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "31e29f7d9c84ed84a10e8d90b30bccaaff807be0",
          "body": null,
          "is_bot": false,
          "headline": "Fix missing semicolons in configuration.md examples",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-04T04:59:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e1c944f36cc9f255b3a0c4910e8c9e59de454a87",
          "body": "…time\n\nAdd real-time progress documentation with Mercure/FrankenPHP",
          "is_bot": false,
          "headline": "Merge pull request #451 from dereuromark/docs/frankenphp-mercure-real…",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-04T02:32:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6fccb5b13f37bd14ad4af0571d934a3d0aa1135c",
          "body": "Add getDescription() to all commands",
          "is_bot": false,
          "headline": "Merge pull request #455 from dereuromark/add-command-descriptions",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-04T02:30:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "514ee88233de0f2ded727c513ce5a560d23a9ef7",
          "body": null,
          "is_bot": false,
          "headline": "Add getDescription() to all commands",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-04T02:19:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b74d00be179ab07d0373553ec162a98320b40a1e",
          "body": "Make Icon configuration optional with text fallback",
          "is_bot": false,
          "headline": "Merge pull request #454 from dereuromark/feature/optional-icon-config",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-01T16:54:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "99731ec588af6be75106336bbe934707ede71f85",
          "body": "- Conditionally load Icon helper only when Icon.sets is configured\n- Add icon element with text fallback for when icons are not configured\n- Update templates to use the icon element\n\nThe backend UI now works without Icon.sets configured, showing text\nlabels like [View], [Edit], [Del] instead of icons.",
          "is_bot": false,
          "headline": "Make Icon configuration optional with text fallback",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2026-01-01T16:48:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4bd3f8bb801e32fde5ba5d8d1f2eb4072c4ad9d0",
          "body": "Documents the PID 1 issue when running queue workers in Docker containers\nand provides solutions using stable hostnames and startup cleanup commands.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)",
          "is_bot": false,
          "headline": "Add Docker/docker-compose deployment documentation",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2025-12-20T01:04:17Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e447805c1e945c58c03d3d4d02e14acb01c67e61",
          "body": "Instead of warning when a task timeout exceeds the requeue timeout,\nautomatically cap it to prevent duplicate execution.",
          "is_bot": false,
          "headline": "Auto-cap task timeout to defaultRequeueTimeout.",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2025-12-19T22:17:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "18ac9872d9ff331513de2109ed49e76cdb6b503e",
          "body": null,
          "is_bot": false,
          "headline": "Allow config overwrite on vendor tasks.",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2025-12-19T22:12:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ef5ac978c5adc028a2794cc831902d1dd7ec4c15",
          "body": "Documents how to display live queue job progress in the browser using:\n- Mercure protocol with Server-Sent Events\n- FrankenPHP with built-in Mercure hub\n- Example queue task with progress publishing\n- Controller and template examples\n- Production deployment with systemd/supervisor\n- Worker scaling configuration",
          "is_bot": false,
          "headline": "Add real-time progress documentation with Mercure/FrankenPHP",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2025-12-19T18:51:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ce69d1fff33dc784bc5c43ee83c199def0489f62",
          "body": null,
          "is_bot": false,
          "headline": "Add readable config ints.",
          "author_name": "mscherer",
          "author_login": "dereuromark",
          "committed_at": "2025-12-11T19:55:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "486dce3ddf5026d2c2f75f951d522f9cc6d7d14e",
          "body": "Support both the legacy queue_phinxlog table (Migrations plugin 4.x)\nand the new cake_migrations table (Migrations plugin 5.x).\n\nThe migration now checks if cake_migrations exists and uses it with\nthe plugin column filter, otherwise falls back to queue_phinxlog.",
          "is_bot": false,
          "headline": "Add support for unified cake_migrations table (#450)",
          "author_name": "Mark Scherer",
          "author_login": "dereuromark",
          "committed_at": "2025-12-11T19:49:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 100,
      "commits_last_year": 145,
      "latest_release_at": "2026-06-06T20:11:41Z",
      "latest_release_tag": "8.15.1",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 32,
      "days_since_latest_release": 56,
      "mean_days_between_releases": 9
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 57,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "dereuromark/cakephp-queue",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "queue",
            "cakephp",
            "background",
            "async",
            "jobs",
            "admin-panel",
            "workers",
            "deferred tasks",
            "standalone-ui"
          ],
          "ecosystem": "packagist",
          "matches_repo": true,
          "registry_url": "https://packagist.org/packages/dereuromark/cakephp-queue",
          "is_deprecated": false,
          "latest_version": "8.15.1",
          "repository_url": "https://github.com/dereuromark/cakephp-queue",
          "versions_count": 136,
          "total_downloads": 997463,
          "dependents_count": 16,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 38799,
          "first_published_at": null,
          "latest_published_at": "2026-06-06T16:09:37Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 56
        }
      ]
    },
    "popularity": {
      "forks": 138,
      "stars": 308,
      "watchers": 19,
      "fork_history": {
        "days": [
          {
            "date": "2013-01-25",
            "count": 1
          },
          {
            "date": "2013-07-05",
            "count": 1
          },
          {
            "date": "2013-12-27",
            "count": 1
          },
          {
            "date": "2014-02-13",
            "count": 1
          },
          {
            "date": "2014-03-19",
            "count": 1
          },
          {
            "date": "2014-04-16",
            "count": 1
          },
          {
            "date": "2014-06-22",
            "count": 1
          },
          {
            "date": "2014-07-16",
            "count": 1
          },
          {
            "date": "2014-08-05",
            "count": 1
          },
          {
            "date": "2014-09-02",
            "count": 1
          },
          {
            "date": "2014-12-11",
            "count": 1
          },
          {
            "date": "2015-02-16",
            "count": 1
          },
          {
            "date": "2015-02-17",
            "count": 1
          },
          {
            "date": "2015-02-19",
            "count": 1
          },
          {
            "date": "2015-02-23",
            "count": 1
          },
          {
            "date": "2015-03-16",
            "count": 1
          },
          {
            "date": "2015-05-10",
            "count": 1
          },
          {
            "date": "2015-06-15",
            "count": 1
          },
          {
            "date": "2015-07-08",
            "count": 1
          },
          {
            "date": "2015-07-31",
            "count": 1
          },
          {
            "date": "2015-08-04",
            "count": 1
          },
          {
            "date": "2015-08-07",
            "count": 1
          },
          {
            "date": "2015-08-12",
            "count": 1
          },
          {
            "date": "2015-08-16",
            "count": 1
          },
          {
            "date": "2015-08-22",
            "count": 1
          },
          {
            "date": "2015-11-18",
            "count": 1
          },
          {
            "date": "2015-12-28",
            "count": 1
          },
          {
            "date": "2016-01-05",
            "count": 1
          },
          {
            "date": "2016-01-07",
            "count": 1
          },
          {
            "date": "2016-01-22",
            "count": 1
          },
          {
            "date": "2016-01-24",
            "count": 1
          },
          {
            "date": "2016-01-25",
            "count": 1
          },
          {
            "date": "2016-02-18",
            "count": 1
          },
          {
            "date": "2016-03-12",
            "count": 1
          },
          {
            "date": "2016-03-17",
            "count": 1
          },
          {
            "date": "2016-04-07",
            "count": 1
          },
          {
            "date": "2016-04-20",
            "count": 1
          },
          {
            "date": "2016-04-27",
            "count": 1
          },
          {
            "date": "2016-04-30",
            "count": 1
          },
          {
            "date": "2016-06-17",
            "count": 1
          },
          {
            "date": "2016-07-08",
            "count": 1
          },
          {
            "date": "2016-08-05",
            "count": 1
          },
          {
            "date": "2016-08-12",
            "count": 1
          },
          {
            "date": "2016-08-17",
            "count": 1
          },
          {
            "date": "2016-09-02",
            "count": 1
          },
          {
            "date": "2016-10-14",
            "count": 1
          },
          {
            "date": "2016-10-22",
            "count": 1
          },
          {
            "date": "2016-11-16",
            "count": 1
          },
          {
            "date": "2016-12-01",
            "count": 1
          },
          {
            "date": "2016-12-28",
            "count": 1
          },
          {
            "date": "2017-01-09",
            "count": 1
          },
          {
            "date": "2017-03-15",
            "count": 1
          },
          {
            "date": "2017-03-20",
            "count": 1
          },
          {
            "date": "2017-04-10",
            "count": 1
          },
          {
            "date": "2017-04-26",
            "count": 1
          },
          {
            "date": "2017-04-27",
            "count": 1
          },
          {
            "date": "2017-05-29",
            "count": 1
          },
          {
            "date": "2017-06-01",
            "count": 1
          },
          {
            "date": "2017-06-30",
            "count": 1
          },
          {
            "date": "2017-07-03",
            "count": 1
          },
          {
            "date": "2017-07-10",
            "count": 1
          },
          {
            "date": "2017-10-04",
            "count": 1
          },
          {
            "date": "2017-10-20",
            "count": 1
          },
          {
            "date": "2018-03-01",
            "count": 1
          },
          {
            "date": "2018-03-14",
            "count": 1
          },
          {
            "date": "2018-04-30",
            "count": 1
          },
          {
            "date": "2018-05-06",
            "count": 1
          },
          {
            "date": "2018-06-19",
            "count": 1
          },
          {
            "date": "2018-08-10",
            "count": 1
          },
          {
            "date": "2018-09-07",
            "count": 1
          },
          {
            "date": "2018-11-14",
            "count": 2
          },
          {
            "date": "2018-11-29",
            "count": 1
          },
          {
            "date": "2018-12-28",
            "count": 1
          },
          {
            "date": "2019-01-15",
            "count": 1
          },
          {
            "date": "2019-02-09",
            "count": 1
          },
          {
            "date": "2019-03-04",
            "count": 1
          },
          {
            "date": "2019-03-15",
            "count": 1
          },
          {
            "date": "2019-04-22",
            "count": 1
          },
          {
            "date": "2019-05-10",
            "count": 1
          },
          {
            "date": "2019-05-12",
            "count": 1
          },
          {
            "date": "2019-06-25",
            "count": 1
          },
          {
            "date": "2019-07-11",
            "count": 1
          },
          {
            "date": "2019-08-01",
            "count": 1
          },
          {
            "date": "2019-08-13",
            "count": 1
          },
          {
            "date": "2019-09-09",
            "count": 1
          },
          {
            "date": "2019-12-09",
            "count": 1
          },
          {
            "date": "2019-12-12",
            "count": 1
          },
          {
            "date": "2019-12-29",
            "count": 1
          },
          {
            "date": "2020-01-03",
            "count": 1
          },
          {
            "date": "2020-01-23",
            "count": 1
          },
          {
            "date": "2020-06-08",
            "count": 1
          },
          {
            "date": "2020-06-22",
            "count": 1
          },
          {
            "date": "2020-09-08",
            "count": 1
          },
          {
            "date": "2020-10-21",
            "count": 1
          },
          {
            "date": "2021-01-26",
            "count": 1
          },
          {
            "date": "2021-05-24",
            "count": 1
          },
          {
            "date": "2021-06-30",
            "count": 1
          },
          {
            "date": "2021-07-07",
            "count": 1
          },
          {
            "date": "2021-07-14",
            "count": 1
          },
          {
            "date": "2021-10-10",
            "count": 1
          },
          {
            "date": "2021-12-22",
            "count": 1
          },
          {
            "date": "2022-01-02",
            "count": 1
          },
          {
            "date": "2022-01-12",
            "count": 1
          },
          {
            "date": "2022-03-16",
            "count": 1
          },
          {
            "date": "2022-03-21",
            "count": 1
          },
          {
            "date": "2022-04-15",
            "count": 1
          },
          {
            "date": "2022-05-20",
            "count": 1
          },
          {
            "date": "2022-08-18",
            "count": 1
          },
          {
            "date": "2022-08-19",
            "count": 1
          },
          {
            "date": "2022-08-22",
            "count": 1
          },
          {
            "date": "2022-10-18",
            "count": 1
          },
          {
            "date": "2022-10-25",
            "count": 1
          },
          {
            "date": "2022-11-02",
            "count": 1
          },
          {
            "date": "2022-12-18",
            "count": 1
          },
          {
            "date": "2023-01-03",
            "count": 1
          },
          {
            "date": "2023-01-09",
            "count": 1
          },
          {
            "date": "2023-02-09",
            "count": 1
          },
          {
            "date": "2023-02-14",
            "count": 1
          },
          {
            "date": "2023-02-23",
            "count": 1
          },
          {
            "date": "2023-04-03",
            "count": 1
          },
          {
            "date": "2023-07-20",
            "count": 1
          },
          {
            "date": "2023-09-13",
            "count": 1
          },
          {
            "date": "2024-05-06",
            "count": 1
          },
          {
            "date": "2024-06-21",
            "count": 1
          },
          {
            "date": "2024-09-19",
            "count": 1
          },
          {
            "date": "2024-10-24",
            "count": 1
          },
          {
            "date": "2025-03-18",
            "count": 1
          },
          {
            "date": "2025-05-07",
            "count": 1
          },
          {
            "date": "2025-08-23",
            "count": 1
          },
          {
            "date": "2025-11-22",
            "count": 1
          },
          {
            "date": "2026-03-31",
            "count": 1
          },
          {
            "date": "2026-06-14",
            "count": 1
          },
          {
            "date": "2026-07-15",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 134,
        "total_forks": 138
      },
      "star_history": null,
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 37884,
      "source_files_sampled": 161,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "composer.json",
        "docs/package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "repository_graph",
        "source": "osv",
        "findings": [
          {
            "name": "vite",
            "direct": false,
            "version": "5.4.21",
            "severity": "high",
            "ecosystem": "npm",
            "cvss_score": 7.5,
            "advisory_ids": [
              "GHSA-4w7w-66w2-5vf9",
              "GHSA-fx2h-pf6j-xcff",
              "GHSA-v6wh-96g9-6wx3"
            ],
            "fixed_version": "8.0.16",
            "advisory_count": 3,
            "oldest_advisory_days": 117
          },
          {
            "name": "esbuild",
            "direct": false,
            "version": "0.21.5",
            "severity": "moderate",
            "ecosystem": "npm",
            "cvss_score": 5.3,
            "advisory_ids": [
              "GHSA-67mh-4wv8-2f99"
            ],
            "fixed_version": "0.25.0",
            "advisory_count": 1,
            "oldest_advisory_days": 537
          }
        ],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {
          "high": 1,
          "moderate": 1
        },
        "advisory_count": 4,
        "affected_count": 2,
        "assessed_count": 173,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 13,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm",
        "packagist"
      ],
      "dependencies": [
        {
          "name": "brick/varexporter",
          "manifest": "composer.json",
          "ecosystem": "packagist",
          "version_constraint": "^0.5.0 || ^0.6.0 || ^0.7.0"
        },
        {
          "name": "cakephp/cakephp",
          "manifest": "composer.json",
          "ecosystem": "packagist",
          "version_constraint": "^5.1.1"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "brick/varexporter",
            "direct": true,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "cakephp/cakephp",
            "direct": true,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "@algolia/abtesting",
            "direct": false,
            "version": "1.18.0",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/autocomplete-core",
            "direct": false,
            "version": "1.17.7",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/autocomplete-plugin-algolia-insights",
            "direct": false,
            "version": "1.17.7",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/autocomplete-preset-algolia",
            "direct": false,
            "version": "1.17.7",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/autocomplete-shared",
            "direct": false,
            "version": "1.17.7",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/client-abtesting",
            "direct": false,
            "version": "5.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/client-analytics",
            "direct": false,
            "version": "5.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/client-common",
            "direct": false,
            "version": "5.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/client-insights",
            "direct": false,
            "version": "5.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/client-personalization",
            "direct": false,
            "version": "5.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/client-query-suggestions",
            "direct": false,
            "version": "5.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/client-search",
            "direct": false,
            "version": "5.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/ingestion",
            "direct": false,
            "version": "1.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/monitoring",
            "direct": false,
            "version": "1.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/recommend",
            "direct": false,
            "version": "5.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/requester-browser-xhr",
            "direct": false,
            "version": "5.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/requester-fetch",
            "direct": false,
            "version": "5.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "@algolia/requester-node-http",
            "direct": false,
            "version": "5.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "@babel/helper-string-parser",
            "direct": false,
            "version": "7.27.1",
            "ecosystem": "npm"
          },
          {
            "name": "@babel/helper-validator-identifier",
            "direct": false,
            "version": "7.28.5",
            "ecosystem": "npm"
          },
          {
            "name": "@babel/parser",
            "direct": false,
            "version": "7.29.3",
            "ecosystem": "npm"
          },
          {
            "name": "@babel/types",
            "direct": false,
            "version": "7.29.0",
            "ecosystem": "npm"
          },
          {
            "name": "@docsearch/css",
            "direct": false,
            "version": "3.8.2",
            "ecosystem": "npm"
          },
          {
            "name": "@docsearch/js",
            "direct": false,
            "version": "3.8.2",
            "ecosystem": "npm"
          },
          {
            "name": "@docsearch/react",
            "direct": false,
            "version": "3.8.2",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/aix-ppc64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/android-arm",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/android-arm64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/android-x64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/darwin-arm64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/darwin-x64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/freebsd-arm64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/freebsd-x64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/linux-arm",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/linux-arm64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/linux-ia32",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/linux-loong64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/linux-mips64el",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/linux-ppc64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/linux-riscv64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/linux-s390x",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/linux-x64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/netbsd-x64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/openbsd-x64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/sunos-x64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/win32-arm64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/win32-ia32",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@esbuild/win32-x64",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "@iconify-json/simple-icons",
            "direct": false,
            "version": "1.2.80",
            "ecosystem": "npm"
          },
          {
            "name": "@iconify/types",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "@jridgewell/sourcemap-codec",
            "direct": false,
            "version": "1.5.5",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-android-arm-eabi",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-android-arm64",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-darwin-arm64",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-darwin-x64",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-freebsd-arm64",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-freebsd-x64",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-arm-gnueabihf",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-arm-musleabihf",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-arm64-gnu",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-arm64-musl",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-loong64-gnu",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-loong64-musl",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-ppc64-gnu",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-ppc64-musl",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-riscv64-gnu",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-riscv64-musl",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-s390x-gnu",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-x64-gnu",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-x64-musl",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-openbsd-x64",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-openharmony-arm64",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-win32-arm64-msvc",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-win32-ia32-msvc",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-win32-x64-gnu",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-win32-x64-msvc",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "@shikijs/core",
            "direct": false,
            "version": "2.5.0",
            "ecosystem": "npm"
          },
          {
            "name": "@shikijs/engine-javascript",
            "direct": false,
            "version": "2.5.0",
            "ecosystem": "npm"
          },
          {
            "name": "@shikijs/engine-oniguruma",
            "direct": false,
            "version": "2.5.0",
            "ecosystem": "npm"
          },
          {
            "name": "@shikijs/langs",
            "direct": false,
            "version": "2.5.0",
            "ecosystem": "npm"
          },
          {
            "name": "@shikijs/themes",
            "direct": false,
            "version": "2.5.0",
            "ecosystem": "npm"
          },
          {
            "name": "@shikijs/transformers",
            "direct": false,
            "version": "2.5.0",
            "ecosystem": "npm"
          },
          {
            "name": "@shikijs/types",
            "direct": false,
            "version": "2.5.0",
            "ecosystem": "npm"
          },
          {
            "name": "@shikijs/vscode-textmate",
            "direct": false,
            "version": "10.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@types/estree",
            "direct": false,
            "version": "1.0.8",
            "ecosystem": "npm"
          },
          {
            "name": "@types/hast",
            "direct": false,
            "version": "3.0.4",
            "ecosystem": "npm"
          },
          {
            "name": "@types/linkify-it",
            "direct": false,
            "version": "5.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "@types/markdown-it",
            "direct": false,
            "version": "14.1.2",
            "ecosystem": "npm"
          },
          {
            "name": "@types/mdast",
            "direct": false,
            "version": "4.0.4",
            "ecosystem": "npm"
          },
          {
            "name": "@types/mdurl",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "@types/unist",
            "direct": false,
            "version": "3.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "@types/web-bluetooth",
            "direct": false,
            "version": "0.0.21",
            "ecosystem": "npm"
          },
          {
            "name": "@ungap/structured-clone",
            "direct": false,
            "version": "1.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "@vitejs/plugin-vue",
            "direct": false,
            "version": "5.2.4",
            "ecosystem": "npm"
          },
          {
            "name": "@vue/compiler-core",
            "direct": false,
            "version": "3.5.33",
            "ecosystem": "npm"
          },
          {
            "name": "@vue/compiler-dom",
            "direct": false,
            "version": "3.5.33",
            "ecosystem": "npm"
          },
          {
            "name": "@vue/compiler-sfc",
            "direct": false,
            "version": "3.5.33",
            "ecosystem": "npm"
          },
          {
            "name": "@vue/compiler-ssr",
            "direct": false,
            "version": "3.5.33",
            "ecosystem": "npm"
          },
          {
            "name": "@vue/devtools-api",
            "direct": false,
            "version": "7.7.9",
            "ecosystem": "npm"
          },
          {
            "name": "@vue/devtools-kit",
            "direct": false,
            "version": "7.7.9",
            "ecosystem": "npm"
          },
          {
            "name": "@vue/devtools-shared",
            "direct": false,
            "version": "7.7.9",
            "ecosystem": "npm"
          },
          {
            "name": "@vue/reactivity",
            "direct": false,
            "version": "3.5.33",
            "ecosystem": "npm"
          },
          {
            "name": "@vue/runtime-core",
            "direct": false,
            "version": "3.5.33",
            "ecosystem": "npm"
          },
          {
            "name": "@vue/runtime-dom",
            "direct": false,
            "version": "3.5.33",
            "ecosystem": "npm"
          },
          {
            "name": "@vue/server-renderer",
            "direct": false,
            "version": "3.5.33",
            "ecosystem": "npm"
          },
          {
            "name": "@vue/shared",
            "direct": false,
            "version": "3.5.33",
            "ecosystem": "npm"
          },
          {
            "name": "@vueuse/core",
            "direct": false,
            "version": "12.8.2",
            "ecosystem": "npm"
          },
          {
            "name": "@vueuse/integrations",
            "direct": false,
            "version": "12.8.2",
            "ecosystem": "npm"
          },
          {
            "name": "@vueuse/metadata",
            "direct": false,
            "version": "12.8.2",
            "ecosystem": "npm"
          },
          {
            "name": "@vueuse/shared",
            "direct": false,
            "version": "12.8.2",
            "ecosystem": "npm"
          },
          {
            "name": "algoliasearch",
            "direct": false,
            "version": "5.52.0",
            "ecosystem": "npm"
          },
          {
            "name": "birpc",
            "direct": false,
            "version": "2.9.0",
            "ecosystem": "npm"
          },
          {
            "name": "ccount",
            "direct": false,
            "version": "2.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "character-entities-html4",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "character-entities-legacy",
            "direct": false,
            "version": "3.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "comma-separated-tokens",
            "direct": false,
            "version": "2.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "copy-anything",
            "direct": false,
            "version": "4.0.5",
            "ecosystem": "npm"
          },
          {
            "name": "csstype",
            "direct": false,
            "version": "3.2.3",
            "ecosystem": "npm"
          },
          {
            "name": "dequal",
            "direct": false,
            "version": "2.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "devlop",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "emoji-regex-xs",
            "direct": false,
            "version": "1.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "entities",
            "direct": false,
            "version": "7.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "esbuild",
            "direct": false,
            "version": "0.21.5",
            "ecosystem": "npm"
          },
          {
            "name": "estree-walker",
            "direct": false,
            "version": "2.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "focus-trap",
            "direct": false,
            "version": "7.8.0",
            "ecosystem": "npm"
          },
          {
            "name": "fsevents",
            "direct": false,
            "version": "2.3.3",
            "ecosystem": "npm"
          },
          {
            "name": "hast-util-to-html",
            "direct": false,
            "version": "9.0.5",
            "ecosystem": "npm"
          },
          {
            "name": "hast-util-whitespace",
            "direct": false,
            "version": "3.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "hookable",
            "direct": false,
            "version": "5.5.3",
            "ecosystem": "npm"
          },
          {
            "name": "html-void-elements",
            "direct": false,
            "version": "3.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "is-what",
            "direct": false,
            "version": "5.5.0",
            "ecosystem": "npm"
          },
          {
            "name": "magic-string",
            "direct": false,
            "version": "0.30.21",
            "ecosystem": "npm"
          },
          {
            "name": "mark.js",
            "direct": false,
            "version": "8.11.1",
            "ecosystem": "npm"
          },
          {
            "name": "mdast-util-to-hast",
            "direct": false,
            "version": "13.2.1",
            "ecosystem": "npm"
          },
          {
            "name": "micromark-util-character",
            "direct": false,
            "version": "2.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "micromark-util-encode",
            "direct": false,
            "version": "2.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "micromark-util-sanitize-uri",
            "direct": false,
            "version": "2.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "micromark-util-symbol",
            "direct": false,
            "version": "2.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "micromark-util-types",
            "direct": false,
            "version": "2.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "minisearch",
            "direct": false,
            "version": "7.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "mitt",
            "direct": false,
            "version": "3.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "nanoid",
            "direct": false,
            "version": "3.3.16",
            "ecosystem": "npm"
          },
          {
            "name": "oniguruma-to-es",
            "direct": false,
            "version": "3.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "perfect-debounce",
            "direct": false,
            "version": "1.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "picocolors",
            "direct": false,
            "version": "1.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "postcss",
            "direct": false,
            "version": "8.5.25",
            "ecosystem": "npm"
          },
          {
            "name": "preact",
            "direct": false,
            "version": "10.29.1",
            "ecosystem": "npm"
          },
          {
            "name": "property-information",
            "direct": false,
            "version": "7.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "regex",
            "direct": false,
            "version": "6.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "regex-recursion",
            "direct": false,
            "version": "6.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "regex-utilities",
            "direct": false,
            "version": "2.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "rfdc",
            "direct": false,
            "version": "1.4.1",
            "ecosystem": "npm"
          },
          {
            "name": "rollup",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "npm"
          },
          {
            "name": "search-insights",
            "direct": false,
            "version": "2.17.3",
            "ecosystem": "npm"
          },
          {
            "name": "shiki",
            "direct": false,
            "version": "2.5.0",
            "ecosystem": "npm"
          },
          {
            "name": "source-map-js",
            "direct": false,
            "version": "1.2.1",
            "ecosystem": "npm"
          },
          {
            "name": "space-separated-tokens",
            "direct": false,
            "version": "2.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "speakingurl",
            "direct": false,
            "version": "14.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "stringify-entities",
            "direct": false,
            "version": "4.0.4",
            "ecosystem": "npm"
          },
          {
            "name": "superjson",
            "direct": false,
            "version": "2.2.6",
            "ecosystem": "npm"
          },
          {
            "name": "tabbable",
            "direct": false,
            "version": "6.4.0",
            "ecosystem": "npm"
          },
          {
            "name": "trim-lines",
            "direct": false,
            "version": "3.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "unist-util-is",
            "direct": false,
            "version": "6.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "unist-util-position",
            "direct": false,
            "version": "5.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "unist-util-stringify-position",
            "direct": false,
            "version": "4.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "unist-util-visit",
            "direct": false,
            "version": "5.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "unist-util-visit-parents",
            "direct": false,
            "version": "6.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "vfile",
            "direct": false,
            "version": "6.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "vfile-message",
            "direct": false,
            "version": "4.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "vite",
            "direct": false,
            "version": "5.4.21",
            "ecosystem": "npm"
          },
          {
            "name": "vitepress",
            "direct": false,
            "version": "1.6.4",
            "ecosystem": "npm"
          },
          {
            "name": "vue",
            "direct": false,
            "version": "3.5.33",
            "ecosystem": "npm"
          },
          {
            "name": "zwitch",
            "direct": false,
            "version": "2.0.4",
            "ecosystem": "npm"
          },
          {
            "name": "cakedc/cakephp-phpstan",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "cakephp/bake",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "cakephp/migrations",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "dereuromark/cakephp-dto",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "dereuromark/cakephp-ide-helper",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "dereuromark/cakephp-templating",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "dereuromark/cakephp-tools",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "fig-r/psr2r-sniffer",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "friendsofcake/search",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "php",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          },
          {
            "name": "phpunit/phpunit",
            "direct": false,
            "version": null,
            "ecosystem": "packagist"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 186,
        "direct_count": 2,
        "indirect_count": 184
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 270,
        "open_issues": 0,
        "closed_ratio": 1,
        "closed_issues": 202,
        "closed_unmerged_prs": 39
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "dereuromark",
          "commits": 909,
          "avatar_url": "https://avatars.githubusercontent.com/u/39854?v=4"
        },
        {
          "type": "User",
          "login": "LordSimal",
          "commits": 46,
          "avatar_url": "https://avatars.githubusercontent.com/u/9105243?v=4"
        },
        {
          "type": "User",
          "login": "MSeven",
          "commits": 37,
          "avatar_url": "https://avatars.githubusercontent.com/u/31497?v=4"
        },
        {
          "type": "User",
          "login": "inoas",
          "commits": 17,
          "avatar_url": "https://avatars.githubusercontent.com/u/20972207?v=4"
        },
        {
          "type": "User",
          "login": "houseoftech",
          "commits": 14,
          "avatar_url": "https://avatars.githubusercontent.com/u/297458?v=4"
        },
        {
          "type": "User",
          "login": "Graziel",
          "commits": 12,
          "avatar_url": "https://avatars.githubusercontent.com/u/5963584?v=4"
        },
        {
          "type": "User",
          "login": "jiru",
          "commits": 11,
          "avatar_url": "https://avatars.githubusercontent.com/u/5107734?v=4"
        },
        {
          "type": "User",
          "login": "challgren",
          "commits": 9,
          "avatar_url": "https://avatars.githubusercontent.com/u/88909?v=4"
        },
        {
          "type": "User",
          "login": "stmeyer",
          "commits": 9,
          "avatar_url": "https://avatars.githubusercontent.com/u/10654545?v=4"
        },
        {
          "type": "User",
          "login": "netstyler",
          "commits": 8,
          "avatar_url": "https://avatars.githubusercontent.com/u/319755?v=4"
        }
      ],
      "contributors_sampled": 56,
      "top_contributor_share": 0.784
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "deploy-docs.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [
        "phpcs.xml",
        "phpstan.neon"
      ],
      "has_editorconfig": true,
      "has_linter_config": true,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 1,
            "reason": "branch protection is not maximal on development and all release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "19 out of 19 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/29 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 13 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": null,
            "reason": "no workflows found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 10,
            "reason": "update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": null,
            "reason": "no dependencies found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": null,
            "reason": "No tokens found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 6,
            "reason": "4 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "2c1a1bfc69ccb44b62f7f2e2b60f53d4dc2a5399",
        "ran_at": "2026-08-02T12:02:31Z",
        "aggregate_score": 5,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-08-02T11:55:11Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-08-02T11:53:58Z",
      "ci_last_conclusion": "FAILURE",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/dereuromark/cakephp-queue",
    "host": "github.com",
    "name": "cakephp-queue",
    "owner": "dereuromark"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "excellent",
      "name": "Overall health",
      "note": "The weighted overall 76 is calibrated to 90 on the published index scale (record calibration 2026-08-02).",
      "notes": [
        {
          "code": "overall_calibration",
          "params": {
            "raw": 76,
            "calibrated": 90,
            "calibration": "2026-08-02"
          }
        }
      ],
      "value": 90,
      "inputs": {
        "security": 60,
        "vitality": 92,
        "community": 68,
        "governance": 68,
        "calibration": "2026-08-02",
        "engineering": 94,
        "ai_readiness": 51,
        "weighted_overall_raw": 76
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "excellent",
        "name": "Vitality",
        "value": 92,
        "weight": 0.21,
        "metrics": [
          {
            "key": "development_activity",
            "band": "excellent",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 86,
            "inputs": {
              "commits_last_year": 145,
              "human_commit_share": 0.99,
              "days_since_last_push": 0,
              "active_weeks_last_year": 32
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "32/52 weeks with commits",
                "points": 22.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 32
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "145 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 145
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "exceptional",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 100,
              "latest_release_tag": "8.15.1",
              "releases_from_tags": false,
              "days_since_latest_release": 56,
              "mean_days_between_releases": 9
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "100 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 100
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 56 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 56
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~9 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 9
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "exceptional",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 35,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 35 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 35
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "good",
        "name": "Community & Adoption",
        "value": 68,
        "weight": 0.17,
        "metrics": [
          {
            "key": "popularity",
            "band": "good",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "forks": 138,
              "stars": 308,
              "watchers": 19,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "308 stars",
                "points": 40.3,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 308
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "138 forks",
                "points": 17.8,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 138
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "19 watchers",
                "points": 7,
                "status": "partial",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 19
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "readme_badges": null,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "readme_badge_services": [],
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "good",
            "name": "Ecosystem adoption (downloads)",
            "note": null,
            "notes": [],
            "value": 69,
            "inputs": {
              "packages": [
                "dereuromark/cakephp-queue"
              ],
              "dependents": 16,
              "ecosystems": "packagist",
              "total_downloads": 997463,
              "monthly_downloads": 38799
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "38,799 downloads/month across packagist",
                "points": 61.2,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 38799,
                      "ecosystems": "packagist"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "16 packages depend on it",
                "points": 8.2,
                "status": "partial",
                "details": [
                  {
                    "code": "registry_dependents",
                    "params": {
                      "count": 16
                    }
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "good",
        "name": "Sustainability & Governance",
        "value": 68,
        "weight": 0.23,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "weak",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 37,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 56,
              "top_contributor_share": 0.784
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 78% of commits",
                "points": 4.9,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 78
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "56 contributors",
                "points": 13.5,
                "status": "met",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 56
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 13 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Newcomer PR acceptance. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "newcomer_pr_acceptance"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 78,
            "inputs": {
              "merged_prs": 270,
              "open_issues": 0,
              "closed_issues": 202,
              "prs_merged_7d": null,
              "prs_decided_7d": null,
              "prs_merged_30d": null,
              "prs_decided_30d": null,
              "issue_closed_ratio": 1,
              "closed_unmerged_prs": 39,
              "first_time_authors_30d": null,
              "first_time_prs_merged_30d": null,
              "first_time_prs_decided_30d": null
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "100% of issues closed",
                "points": 42,
                "status": "met",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 42
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "270/309 decided PRs merged",
                "points": 26.2,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 270,
                      "decided": 309
                    }
                  }
                ],
                "max_points": 30
              },
              {
                "key": "newcomer_pr_acceptance",
                "name": "Newcomer PR acceptance",
                "detail": "no first-time contributor's PR decided in 30d",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_newcomer_prs",
                    "params": {
                      "days": 30
                    }
                  }
                ],
                "max_points": 13
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/29 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "good",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 70,
            "inputs": {
              "followers": 748,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "dereuromark",
              "public_repos": 123,
              "account_age_days": 6442
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "748 followers of dereuromark",
                "points": 20.7,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 748,
                      "login": "dereuromark"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "123 public repos, account ~17 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 123
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 17
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "exceptional",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "dereuromark/cakephp-queue"
              ],
              "ecosystems": "packagist",
              "any_deprecated": false,
              "min_days_since_publish": 56
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on packagist",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "packagist"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 56 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 56
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "136 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 136
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "exceptional",
        "name": "Engineering Quality",
        "value": 94,
        "weight": 0.19,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "excellent",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": true,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "2 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": "phpcs.xml, phpstan.neon",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "phpcs.xml, phpstan.neon"
                    }
                  }
                ],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 6.4,
                "status": "met",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "19 out of 19 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "exceptional",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "topics": [
                "asynchronous",
                "background-jobs",
                "cronjob",
                "queue",
                "cakephp",
                "cakephp-plugin",
                "php"
              ],
              "has_wiki": true,
              "homepage": "https://dereuromark.github.io/cakephp-queue/",
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://dereuromark.github.io/cakephp-queue/",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "7 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 7
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 60,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Dangerous-Workflow, Packaging, Pinned-Dependencies, Signed-Releases, Token-Permissions. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "dangerous_workflow",
                    "packaging",
                    "pinned_dependencies",
                    "signed_releases",
                    "token_permissions"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 50,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 13,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 5,
              "scorecard_aggregate": 5
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection is not maximal on development and all release branches",
                "points": 0.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "19 out of 19 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/29 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 13 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no workflows found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "update tool detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "no dependencies found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "No tokens found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "4 existing vulnerabilities detected",
                "points": 4.5,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "exceptional",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories, No advisories left outstanding. Remaining weights renormalized. Matched 173 resolved dependencies against OSV; 13 could not be assessed (no resolved version, an unsupported ecosystem, or beyond the reported package list). This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "indirect_dependencies_free_of_known_advisories",
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_repository",
                "params": {
                  "assessed": 173
                }
              },
              {
                "code": "advisories_unassessed",
                "params": {
                  "count": 13
                }
              },
              {
                "code": "advisories_repo_graph_caveat",
                "params": {}
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 4,
              "affected_packages": 2,
              "assessed_packages": 173,
              "unassessed_packages": 13,
              "affected_by_severity": "high 1, moderate 1",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "transitive set not separable from development and test dependencies in this scope",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_scope_not_separable",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory carries a publication date",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_no_publication_date",
                    "params": {}
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "exceptional",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 173,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "exceptional",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "commit_weight_rule": {
                "min_commits": 50,
                "min_commit_share": 0.1
              },
              "review_only_matches": 0,
              "below_threshold_exposures": [],
              "assessed_self_published_locations": 13
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 51,
        "weight": 0.04,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "weak",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 36,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.677,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "67 of 99 human commits state their intent (structured subject or explanatory body)",
                "points": 36.1,
                "status": "partial",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 67,
                      "sampled": 99
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Pinned-Dependencies. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_pinned_dependencies"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 61,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [],
              "agent_commit_share": 0.02,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0.01
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": "phpcs.xml, phpstan.neon",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "phpcs.xml, phpstan.neon"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "2 of the last 100 commits agent-authored or agent-credited",
                "points": 4,
                "status": "partial",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 2,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "1 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 1,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "no dependencies found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "moderate",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "primary_language": "PHP",
              "largest_source_bytes": 37884,
              "source_files_sampled": 161,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "PHP without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "PHP"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/161 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 161,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? Carries a deliberately small weight: agent tooling is a real maintenance signal, but its absence must never gate the top of the scale (calibration saturates at raw 91, so 100/100 remains reachable with AI Readiness at zero)."
      }
    ],
    "classification": {
      "labels": [
        "library"
      ],
      "scores": {
        "plugin": 2,
        "web-ui": 2,
        "library": 6
      },
      "primary": "library",
      "evidence": [
        {
          "tier": "distribution",
          "label": "library",
          "source": "registry:packagist",
          "weight": 6
        },
        {
          "tier": "description",
          "label": "plugin",
          "source": "description:plugin",
          "weight": 2
        },
        {
          "tier": "tags",
          "label": "web-ui",
          "source": "tag:admin-panel",
          "weight": 2
        }
      ],
      "artifacts": [],
      "confidence": "medium",
      "host_extension": false,
      "runs_as_process": false,
      "consumed_by_code": true
    },
    "metrics_version": "2.3.1"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token"
  ],
  "report_type": "repository",
  "generated_at": "2026-08-02T12:02:54.849037Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/d/dereuromark/cakephp-queue.svg",
  "full_name": "dereuromark/cakephp-queue",
  "license_state": "standard",
  "license_spdx": "MIT"
}

评分是信号,而非担保。 评分反映的是 GitHub 上公开可见的实践——不是代码审计,也不是安全保证。

缺失数据将被剔除并重新归一化权重,绝不按零分计。方法论已版本化并公开:指标 v2.3.1、模式 v0.27.0—— 完整方法论 · 指标知识库.

单项结果在整体记录中的位置: 汇总统计Packagist.