A Git-based CMS for Static Site Generators
This report summarizes scanner evidence for decaporg/decap-cms, a JavaScript project with 19,461 GitHub stars. SynthScan examined 192,476 lines of code across 1043 source files, recording 157 pattern matches distributed across 5 syntactic categories. The legacy adjusted pattern signal is 1.0 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 129 finding(s).
Are imports declared and package/API names verified? 28 finding(s).
Are wrappers, guards, and repeated structures necessary? 108 finding(s).
Which changes need focused human review? 157 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 157 distinct pattern matches across 5 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | cypress/utils/steps.js | 126 | function assertUnpublishedEntryInEditor() { | CODE |
| LOW⚡ | cypress/utils/steps.js | 130 | function assertPublishedEntryInEditor() { | CODE |
| LOW⚡ | cypress/utils/steps.js | 134 | function assertUnpublishedChangesInEditor() { | CODE |
| LOW | cypress/utils/steps.js | 175 | function assertWorkflowStatusInEditor(status) { | CODE |
| LOW⚡ | cypress/utils/steps.js | 230 | function updateWorkflowStatusInEditor(newStatus) { | CODE |
| LOW⚡ | cypress/utils/steps.js | 240 | function publishAndCreateNewEntryInEditor() { | CODE |
| LOW⚡ | cypress/utils/steps.js | 247 | function publishAndDuplicateEntryInEditor(entry) { | CODE |
| LOW | cypress/utils/steps.js | 345 | function createPostPublishAndCreateNew(entry) { | CODE |
| LOW | cypress/utils/steps.js | 356 | function createPostPublishAndDuplicate(entry) { | CODE |
| LOW | cypress/utils/steps.js | 380 | function editPostPublishAndCreateNew(entry1, entry2) { | CODE |
| LOW | cypress/utils/steps.js | 390 | function editPostPublishAndDuplicate(entry1, entry2) { | CODE |
| LOW | cypress/utils/steps.js | 414 | function updateExistingPostAndExit(fromEntry, toEntry) { | CODE |
| LOW | cypress/utils/steps.js | 459 | function validateNestedObjectFields({ limit, author }) { | CODE |
| LOW⚡ | cypress/utils/steps.js | 613 | function validateObjectFieldsAndExit(setting) { | CODE |
| LOW⚡ | cypress/utils/steps.js | 618 | function validateNestedObjectFieldsAndExit(setting) { | CODE |
| LOW⚡ | cypress/utils/steps.js | 623 | function validateListFieldsAndExit(setting) { | CODE |
| LOW⚡ | cypress/utils/steps.js | 628 | function validateNestedListFieldsAndExit(setting) { | CODE |
| LOW⚡ | cypress/utils/steps.js | 633 | function assertFieldValidationError({ message, fieldLabel }) { | CODE |
| LOW | cypress/utils/steps.js | 653 | function assertListControlErrorStatus(colors = ['', ''], alias) { | CODE |
| LOW | packages/decap-cms-media-library-s3/src/index.js | 22 | function getBackendConfigFromWindow() { | CODE |
| LOW | packages/decap-cms-widget-file/src/withFileControl.js | 113 | function SortableMultiImageWrapper({ | CODE |
| LOW | packages/decap/src/dev/middlewares/common/index.ts | 63 | export function registerCommonMiddlewares(app: express.Express, options: Options) { | CODE |
| LOW | packages/decap-cms-lib-util/src/path.ts | 57 | export function fileExtensionWithSeparator(p: string) { | CODE |
| LOW | packages/decap-cms-lib-util/src/API.ts | 356 | export async function throwOnConflictingBranches( | CODE |
| LOW | packages/decap-cms-lib-util/src/git-lfs.ts | 47 | function removeGitAttributesCommentsFromLine(line: string) { | CODE |
| LOW | packages/decap-cms-lib-util/src/git-lfs.ts | 101 | export async function getPointerFileForMediaFileObj( | CODE |
| LOW | packages/decap-cms-lib-util/src/git-lfs.ts | 122 | export async function getLargeMediaFilteredMediaFiles( | CODE |
| LOW | packages/decap-cms-lib-util/src/unsentRequest.js | 6 | function isAbortControllerSupported() { | CODE |
| LOW | …ms-widget-richtext/src/filterInlineEditorComponents.js | 1 | export default function filterInlineEditorComponents(editorComponents) { | CODE |
| LOW | …cap-cms-widget-richtext/src/serializers/slateRemark.js | 245 | function normalizeFlankingWhitespace(nodes) { | CODE |
| LOW | …cap-cms-widget-richtext/src/serializers/slateRemark.js | 262 | function convertInlineAndTextChildren(nodes = []) { | CODE |
| LOW | …chtext/src/serializers/remarkEscapeMarkdownEntities.js | 242 | export default function remarkEscapeMarkdownEntities() { | CODE |
| LOW | …ges/decap-cms-widget-richtext/src/serializers/index.js | 89 | function markdownToRemarkRemoveTokenizers({ inlineTokenizers }) { | CODE |
| LOW | …ms-widget-richtext/src/serializers/remarkShortcodes.js | 68 | export function createRemarkShortcodeStringifier({ plugins }) { | CODE |
| LOW | …ms-widget-richtext/src/serializers/remarkShortcodes.js | 69 | return function remarkStringifyShortcodes() { | CODE |
| LOW | …-richtext/src/serializers/remarkStripTrailingBreaks.js | 12 | export default function remarkStripTrailingBreaks() { | CODE |
| LOW | …ol/components/Toolbar/EditorComponentsToolbarButton.js | 16 | function EditorComponentsToolbarButton({ disabled, editorComponents, allowedEditorComponents, t }) { | CODE |
| LOW | packages/decap-cms-ui-default/src/DropDown/getCoords.js | 17 | function computeCoordsFromPlacement({ reference, target, dropdownPosition }) { | CODE |
| LOW | packages/decap-cms-widget-list/src/typedListHelpers.js | 12 | export function resolveFunctionForTypedField(field) { | CODE |
| LOW | packages/decap-cms-widget-list/src/typedListHelpers.js | 25 | export function getErrorMessageForTypedFieldAndValue(field, value) { | CODE |
| LOW | packages/decap-cms-lib-widgets/src/stringTemplate.ts | 147 | function getExplicitFieldReplacement(key: string, data: Map<string, unknown>) { | CODE |
| LOW | …/blocks/locations/areCurrentAndPreviousBlocksOfType.js | 5 | function areCurrentAndPreviousBlocksOfType(editor, type) { | CODE |
| LOW | …/plugins/blocks/locations/isCursorInNonDefaultBlock.js | 3 | function isCursorInNonDefaultBlock(editor) { | CODE |
| LOW | …ns/blocks/locations/isCursorCollapsedAfterSoftBreak.js | 3 | function isCursorCollapsedAfterSoftBreak(editor) { | CODE |
| LOW | …s/blocks/locations/isCursorAtStartOfNonEmptyHeading.js | 3 | function isCursorAtStartOfNonEmptyHeading(editor) { | CODE |
| LOW | …plugins/blocks/locations/isCursorAtStartOfBlockType.js | 5 | function isCursorAtStartOfBlockType(editor, type) { | CODE |
| LOW | …/plugins/lists/transforms/mergeWithPreviousListItem.js | 5 | function mergeWithPreviousListItem(editor) { | CODE |
| LOW | …plugins/lists/transforms/convertParagraphToListItem.js | 6 | function convertParagraphToListItem(editor) { | CODE |
| LOW | …lists/locations/isSelectionWithinNoninitialListItem.js | 3 | function isSelectionWithinNoninitialListItem(editor) { | CODE |
| LOW | …/lists/locations/isCursorAtNoninitialParagraphStart.js | 3 | function isCursorAtNoninitialParagraphStart(editor) { | CODE |
| LOW | …/plugins/lists/selectors/getListContainedInListItem.js | 5 | function getListContainedInListItem(editor) { | CODE |
| LOW | …cap-cms-widget-markdown/src/serializers/slateRemark.js | 246 | function normalizeFlankingWhitespace(nodes) { | CODE |
| LOW | …cap-cms-widget-markdown/src/serializers/slateRemark.js | 263 | function convertInlineAndTextChildren(nodes = []) { | CODE |
| LOW | …rkdown/src/serializers/remarkEscapeMarkdownEntities.js | 242 | export default function remarkEscapeMarkdownEntities() { | CODE |
| LOW | …ges/decap-cms-widget-markdown/src/serializers/index.js | 88 | function markdownToRemarkRemoveTokenizers({ inlineTokenizers }) { | CODE |
| LOW | …ms-widget-markdown/src/serializers/remarkShortcodes.js | 88 | function createInlineShortcodeTokenizer({ plugins }) { | CODE |
| LOW | …ms-widget-markdown/src/serializers/remarkShortcodes.js | 179 | export function createRemarkShortcodeStringifier({ plugins }) { | CODE |
| LOW | …ms-widget-markdown/src/serializers/remarkShortcodes.js | 180 | return function remarkStringifyShortcodes() { | CODE |
| LOW | …-markdown/src/serializers/remarkStripTrailingBreaks.js | 12 | export default function remarkStripTrailingBreaks() { | CODE |
| LOW | packages/decap-cms-lib-turbo/src/AuthenticationPage.js | 36 | function credentialsFromFlatParams(credentials) { | CODE |
| 48 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | cypress/utils/constants.js | 3 | const setting1 = { limit: 10, author: 'John Doe' }; | CODE |
| LOW | cypress/utils/constants.js | 4 | const setting2 = { name: 'Jane Doe', description: 'description' }; | CODE |
| LOW | …s-backend-forgejo/src/__tests__/implementation.spec.js | 372 | email: 'user@example.com', | CODE |
| LOW | …s-backend-forgejo/src/__tests__/implementation.spec.js | 379 | email: 'user@example.com', | CODE |
| LOW | …ckend-git-gateway/src/__tests__/implementation.spec.js | 16 | email: 'user@example.com', | CODE |
| LOW | …ckend-git-gateway/src/__tests__/implementation.spec.js | 38 | login: 'user@example.com', | CODE |
| LOW | …ckend-git-gateway/src/__tests__/implementation.spec.js | 39 | email: 'user@example.com', | CODE |
| LOW⚡ | …ckend-git-gateway/src/__tests__/implementation.spec.js | 64 | email: 'user@example.com', | CODE |
| LOW⚡ | …ckend-git-gateway/src/__tests__/implementation.spec.js | 72 | login: 'user@example.com', | CODE |
| LOW⚡ | …ckend-git-gateway/src/__tests__/implementation.spec.js | 73 | email: 'user@example.com', | CODE |
| LOW | …ages/decap-cms-backend-azure/src/__tests__/API.spec.ts | 24 | DisplayName: { value: 'Jane Doe' }, | CODE |
| LOW | …ages/decap-cms-backend-azure/src/__tests__/API.spec.ts | 31 | name: 'Jane Doe', | CODE |
| LOW⚡ | …ages/decap-cms-backend-azure/src/__tests__/API.spec.ts | 45 | displayName: 'Jane Doe', | CODE |
| LOW⚡ | …ages/decap-cms-backend-azure/src/__tests__/API.spec.ts | 51 | expect(user.name).toBe('Jane Doe'); | CODE |
| LOW⚡ | …ages/decap-cms-backend-azure/src/__tests__/API.spec.ts | 59 | coreAttributes: { DisplayName: { value: 'Jane Doe' } }, | CODE |
| LOW⚡ | …ages/decap-cms-backend-azure/src/__tests__/API.spec.ts | 64 | expect(user.login).toBe('Jane Doe'); | CODE |
| LOW⚡ | …ages/decap-cms-backend-azure/src/__tests__/API.spec.ts | 71 | coreAttributes: { DisplayName: { value: 'Jane Doe' } }, | CODE |
| LOW | …cms-lib-turbo/src/__tests__/AuthenticationPage.spec.js | 50 | user_email: 'user@example.com', | CODE |
| LOW | packages/decap-cms-core/src/__tests__/backend.spec.js | 1332 | 'The cat sat on the mat. Lorem ipsum dolor sit amet, consectetur adipiscing elit, ' + | CODE |
| LOW | packages/decap-cms-core/src/__tests__/backend.spec.js | 1332 | 'The cat sat on the mat. Lorem ipsum dolor sit amet, consectetur adipiscing elit, ' + | CODE |
| LOW | …es/decap-cms-core/src/lib/__tests__/formatters.spec.js | 271 | authorEmail: 'test-user@example.org', | CODE |
| LOW⚡ | dev-test/index.html | 71 | "---\ntitle: CHAPTER 1. Loomings.\nuuid: aa63577e-14bb-416f-a307-62ecd943055a\nboolean: true\ntext: >-\n | CODE |
| LOW⚡ | dev-test/index.html | 71 | "---\ntitle: CHAPTER 1. Loomings.\nuuid: aa63577e-14bb-416f-a307-62ecd943055a\nboolean: true\ntext: >-\n | CODE |
| LOW | dev-test/index.html | 121 | 'T00:00:00.000Z\n---\n\n# Loren ipsum dolor sit amet', | CODE |
| LOW⚡ | dev-test/backends/test/index.html | 47 | content: "---\ntitle: CHAPTER 1. Loomings.\nuuid: aa63577e-14bb-416f-a307-62ecd943055a\nboolean: true\ntext: >-\ | CODE |
| LOW⚡ | dev-test/backends/test/index.html | 47 | content: "---\ntitle: CHAPTER 1. Loomings.\nuuid: aa63577e-14bb-416f-a307-62ecd943055a\nboolean: true\ntext: >-\ | CODE |
| LOW | dev-test/backends/test/index.html | 78 | content: "---\ntitle: \"This FAQ item # " + i + "\"\ndate: " + dateString + "T00:00:00.000Z\n---\n\n# Loren ipsum | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | cypress/plugins/index.js | 1 | // *********************************************************** | COMMENT |
| LOW | cypress/support/commands.js | 1 | // *********************************************** | COMMENT |
| LOW | cypress/support/e2e.js | 1 | // *********************************************************** | COMMENT |
| LOW | cypress/e2e/markdown_widget_list_spec.js | 341 | // it('affects only selected list items', () => { | COMMENT |
| LOW | cypress/e2e/markdown_widget_list_spec.js | 361 | // <p>baz</p> | COMMENT |
| LOW | cypress/e2e/markdown_widget_list_spec.js | 381 | // .confirmMarkdownEditorContent( | COMMENT |
| LOW | cypress/e2e/markdown_widget_list_spec.js | 401 | // <li> | COMMENT |
| LOW | cypress/e2e/markdown_widget_list_spec.js | 421 | // <p>foo</p> | COMMENT |
| LOW | cypress/e2e/markdown_widget_list_spec.js | 441 | // .confirmMarkdownEditorContent( | COMMENT |
| LOW | cypress/e2e/markdown_widget_list_spec.js | 461 | // `, | COMMENT |
| LOW | cypress/e2e/markdown_widget_list_spec.js | 481 | // </li> | COMMENT |
| LOW | …kages/decap-cms-widget-richtext/src/RichtextPreview.js | 1 | import PropTypes from 'prop-types'; | COMMENT |
| LOW | packages/decap-cms-backend-git-gateway/README.md | 41 | # If you need to customize the authorize or token endpoints for PKCE, do that here | COMMENT |
| LOW | packages/decap-cms-widget-code/data/languages-raw.yml | 1 | # https://github.com/github/linguist/blob/d2e09563c19fe026873289bad3ceb586a1be09d7/lib/linguist/languages.yml | COMMENT |
| LOW | packages/decap-cms-widget-code/data/languages-raw.yml | 21 | # listed alphabetically) | COMMENT |
| LOW | …kages/decap-cms-widget-markdown/src/MarkdownPreview.js | 1 | import { Component } from 'react'; | COMMENT |
| LOW | .github/workflows/publish.yml | 121 | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | dev-test/index.html | 71 | "---\ntitle: CHAPTER 1. Loomings.\nuuid: aa63577e-14bb-416f-a307-62ecd943055a\nboolean: true\ntext: >-\n | CODE |
| MEDIUM⚡ | dev-test/index.html | 71 | "---\ntitle: CHAPTER 1. Loomings.\nuuid: aa63577e-14bb-416f-a307-62ecd943055a\nboolean: true\ntext: >-\n | CODE |
| MEDIUM⚡ | dev-test/backends/test/index.html | 47 | content: "---\ntitle: CHAPTER 1. Loomings.\nuuid: aa63577e-14bb-416f-a307-62ecd943055a\nboolean: true\ntext: >-\ | CODE |
| MEDIUM⚡ | dev-test/backends/test/index.html | 47 | content: "---\ntitle: CHAPTER 1. Loomings.\nuuid: aa63577e-14bb-416f-a307-62ecd943055a\nboolean: true\ntext: >-\ | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL | …i-auth/src/__tests__/NetlifyAuthenticationPage.spec.js | 31 | const errorCallback = window.netlifyIdentity.on.mock.calls.find( | CODE |