Unrestricted Open-source alternative to AI video platforms — Free AI image & video generation studio with 600+ models (Flux, Midjourney, Kling, Sora, Veo). No content filters. Self-hosted, MIT licensed.
This report summarizes scanner evidence for Anil-matcha/Open-Generative-AI, a JavaScript project with 30,020 GitHub stars. SynthScan examined 72,785 lines of code across 200 source files, recording 317 pattern matches distributed across 7 syntactic categories. The legacy adjusted pattern signal is 11.5 (Moderate 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.
Can maintainers explain intent, assumptions, and trade-offs? 73 finding(s).
Are imports declared and package/API names verified? 16 finding(s).
Are wrappers, guards, and repeated structures necessary? 292 finding(s).
Which changes need focused human review? 317 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 317 distinct pattern matches across 7 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 |
|---|---|---|---|---|
| MEDIUM | scripts/test_minimax_provider.js | 21 | // ── 1. Model registration check ────────────────────────────────────────────── | COMMENT |
| MEDIUM | scripts/test_minimax_provider.js | 89 | // ── 2. models_dump.json check ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | scripts/test_minimax_provider.js | 103 | // ── 3. Live API smoke test (optional) ──────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/ImageStudio.jsx | 1005 | // ── Prompt / upload state ─────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/ImageStudio.jsx | 1011 | // ── UI state ──────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/ImageStudio.jsx | 1018 | // ── Canvas / history state ────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 64 | // ─── helpers ──────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 83 | // ─── UploadButton (inline picker) ─────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 627 | // ─── ModelDropdown ──────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 942 | // ─── SimpleDropdown ─────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 967 | // ─── Main Component ─────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 988 | // ── Model state ───────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1040 | // ── Refs ──────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1047 | // ── Close dropdown on outside click ───────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1059 | // ── Persistence: Load ──────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1094 | // ── Adjust height on load ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1095 | // ── Persistence: Save ──────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1186 | // ── Handle Dropped Files ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1197 | // ── Derived: current model lists & helpers ─────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1272 | // ── Textarea auto-resize ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1273 | // ── Upload picker callbacks ────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1312 | // ── Model selection ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1325 | // ── History helpers ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1337 | // ── View state ───────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1356 | // ── Generation ─────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ImageStudio.jsx | 1466 | // ── Render ─────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/AudioStudio.jsx | 550 | // ── Mode & model state ────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/AudioStudio.jsx | 570 | // ── Generation state ────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/AudioStudio.jsx | 577 | // ── History state ──────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/AudioStudio.jsx | 584 | // ── Initialize params when model changes ────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/AudioStudio.jsx | 599 | // ── Persistence: Load ──────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/AudioStudio.jsx | 617 | // ── Persistence: Save ──────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/AudioStudio.jsx | 637 | // ── Handle Dropped Files ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/AudioStudio.jsx | 675 | // ── History helpers ───────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ClippingStudio.jsx | 228 | // ── Clipping Parameters State ─────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/ClippingStudio.jsx | 248 | // ── Generation State ───────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/ClippingStudio.jsx | 255 | // ── Output State ───────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/ClippingStudio.jsx | 260 | // ── History State ──────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ClippingStudio.jsx | 303 | // ── Load Persistent State from localStorage ────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ClippingStudio.jsx | 321 | // ── Save Persistent State to localStorage ─────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ClippingStudio.jsx | 341 | // ── Handle Dropped Files ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ClippingStudio.jsx | 371 | // ── Highlight Seeking Helper ───────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ClippingStudio.jsx | 387 | // ── Copy Link & Download Helpers ───────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/ClippingStudio.jsx | 492 | // ── Dispatch Run / Call submitAndPoll ──────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/LipSyncStudio.jsx | 421 | // ── Prompt ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/LipSyncStudio.jsx | 424 | // ── Generation / UI state ─────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/LipSyncStudio.jsx | 431 | // ── History ───────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/LipSyncStudio.jsx | 437 | // ── Dropdown state ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/LipSyncStudio.jsx | 443 | // ── Video ref for result ──────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | packages/studio/src/components/LipSyncStudio.jsx | 447 | // ── Persistence: Load ──────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/LipSyncStudio.jsx | 391 | // ── Mode & model state ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/LipSyncStudio.jsx | 403 | // ── Upload state ──────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/LipSyncStudio.jsx | 481 | // ── Persistence: Save ──────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/LipSyncStudio.jsx | 518 | // ── Derived model info ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/LipSyncStudio.jsx | 524 | // ── Sync model when mode changes ──────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/LipSyncStudio.jsx | 535 | // ── Upload handlers ───────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/LipSyncStudio.jsx | 621 | // ── Handle Dropped Files ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/LipSyncStudio.jsx | 641 | // ── Mode toggle ───────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/LipSyncStudio.jsx | 668 | // ── Model selection ───────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/studio/src/components/LipSyncStudio.jsx | 679 | // ── History helpers ───────────────────────────────────────────────────── | COMMENT |
| 168 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/test_minimax_provider.js | 118 | async function testMiniMaxImageGeneration() { | CODE |
| LOW | packages/studio/src/muapi.js | 35 | function includeRequiredArrayDefaults(model, payload) { | CODE |
| LOW | packages/studio/src/muapi.js | 55 | function normalizePredictionResult(submitData, result, outputUrl) { | CODE |
| LOW | packages/studio/src/muapi.js | 200 | export async function generateMarketingStudioAd(apiKey, params) { | CODE |
| LOW | packages/studio/src/videoToolCapabilities.js | 532 | export function isContinuationSourceModel(modelOrId, sourceModelId) { | CODE |
| LOW | packages/studio/src/videoToolCapabilities.js | 598 | export function resolveVideoUploadTransition({ | CODE |
| LOW⚡ | packages/studio/src/videoToolCapabilities.js | 624 | export function getVideoToolOptionDefinitions(model) { | CODE |
| LOW⚡ | packages/studio/src/videoToolCapabilities.js | 633 | export function getDefaultVideoToolOptions(model) { | CODE |
| LOW⚡ | packages/studio/src/videoToolCapabilities.js | 641 | export function serializeVideoToolOptions(model, values = {}) { | CODE |
| LOW | packages/studio/src/videoToolCapabilities.js | 655 | function getVideoToolPayloadDefaults(model) { | CODE |
| LOW | packages/studio/src/videoToolCapabilities.js | 716 | function resolveContinuationRequestId(entry) { | CODE |
| LOW | packages/studio/src/videoToolCapabilities.js | 727 | export function getCompatibleContinuationSources(modelOrId, history = []) { | CODE |
| LOW | packages/studio/src/modelParameters.js | 30 | export function getSupplementalModelInputs(model) { | CODE |
| LOW | packages/studio/src/modelParameters.js | 102 | export function createModelParameterValues(model, previousValues = {}) { | CODE |
| LOW | packages/studio/src/modelParameters.js | 114 | export function mergeModelParameterValues(model, previousValues = {}) { | CODE |
| LOW | packages/studio/src/modelParameters.js | 118 | export function buildSupplementalInputPayload(model, values = {}) { | CODE |
| LOW⚡ | packages/studio/src/groupedVideoParameters.js | 83 | export function planGroupedVideoSelection(options) { | CODE |
| LOW⚡ | packages/studio/src/groupedVideoParameters.js | 92 | export function getGroupedVideoResolutionOptions(familyId, ...args) { | CODE |
| LOW⚡ | packages/studio/src/groupedVideoParameters.js | 96 | export function getGroupedVideoSelectionAdjustments(options) { | CODE |
| LOW | packages/studio/src/seedanceParameters.js | 23 | function followsSourceVideoResolution(modelId) { | CODE |
| LOW | packages/studio/src/seedanceParameters.js | 86 | export function getSeedanceSelectionAdjustments({ | CODE |
| LOW | packages/studio/src/seedanceParameters.js | 255 | export function migrateSeedanceResolutionSelection(modelId, resolution) { | CODE |
| LOW | packages/studio/src/seedanceParameters.js | 269 | export function getSeedanceResolutionOptions( | CODE |
| LOW | packages/studio/src/imageInputContracts.js | 18 | export function normalizePrimaryImageUrls(imagesList, imageUrl) { | CODE |
| LOW | packages/studio/src/imageInputContracts.js | 102 | export function getImageInputValidationError( | CODE |
| LOW | packages/studio/src/videoModelParameters.js | 30 | export function matchingVideoParameterValue(options, value) { | CODE |
| LOW | packages/studio/src/modelCapabilities.js | 89 | export function getModelMediaCapabilities(model) { | CODE |
| LOW | packages/studio/src/seedanceModels.js | 157 | export function getSeedanceEndpointResolution(modelId) { | CODE |
| LOW | packages/studio/src/seedanceModels.js | 178 | export function getSeedanceToolConfiguration(modelId) { | CODE |
| LOW | packages/studio/src/seedanceModels.js | 295 | export function getSeedanceVariantOptions(familyId, workflowId = null, currentModelId = null) { | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 164 | export function getVideoWorkflowControlState(workflowFamilyOrId, variantId = null) { | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 189 | export function getVideoWorkflowControlLabel(workflow) { | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 232 | function variantCompatibilityTokens(variantId) { | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 279 | function resolveGroupedWorkflowVariant( | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 311 | export function resolveVideoWorkflowVariant( | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 362 | export function resolvePersistedVideoWorkflowSelection( | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 398 | export function getVideoWorkflowMediaConfig(model, workflowId) { | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 509 | export function getVideoWorkflowMediaSlots(model, workflowId) { | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 759 | export function migrateVideoWorkflowMediaDrafts(drafts) { | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 832 | export function projectVideoWorkflowMedia(model, workflowId, media = {}) { | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 841 | export function getVideoWorkflowMediaAdjustments(currentModel, nextModel, workflowId, media) { | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 857 | export function getVideoWorkflowSlotRemaining(slot, media = {}) { | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 871 | export function legacyVideoMediaToWorkflowDraft(model, workflowId, media = {}) { | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 891 | export function validateVideoWorkflowMedia(workflowId, media = {}, model = null) { | CODE |
| LOW | packages/studio/src/videoWorkflows.js | 939 | export function buildVideoWorkflowMediaParams(model, workflowId, media = {}) { | CODE |
| LOW | packages/studio/src/minimaxParameters.js | 30 | export function getMiniMaxResolutionOptions(familyId, workflowId = null, currentModelId = null, nativeResolution) { | CODE |
| LOW⚡ | packages/studio/src/groupedVideoModels.js | 33 | export function getGroupedVideoConfiguration(modelId) { | CODE |
| LOW⚡ | packages/studio/src/groupedVideoModels.js | 41 | export function resolveGroupedVideoVariant(options) { | CODE |
| LOW⚡ | packages/studio/src/groupedVideoModels.js | 45 | export function getGroupedVideoVariantOptions(familyId, workflowId, modelId) { | CODE |
| LOW | packages/studio/src/groupedVideoRegistry.js | 10 | export function createGroupedVideoRegistry({ facetOptions, facetLabels, registerVariants }) { | CODE |
| LOW | packages/studio/src/modelFamilies.js | 523 | function getPickerEntryByVariantId(catalog, variantId) { | CODE |
| LOW | packages/studio/src/modelFamilies.js | 820 | function buildVideoModelMenuEntries() { | CODE |
| LOW | packages/studio/src/nativeVideoParameters.js | 16 | export function createNativeVideoParameters({ getConfiguration, resolveVariant, getResolutionVariants }) { | CODE |
| LOW | packages/studio/src/videoMediaInputs.js | 37 | export function normalizeImageAttachments(profile, attachments) { | CODE |
| LOW | packages/studio/src/videoMediaInputs.js | 64 | export function reconcileImageAttachments( | CODE |
| LOW | packages/studio/src/utils/generationLifecycle.js | 20 | export function appendGenerationRefundNotice(message, error) { | CODE |
| LOW | packages/studio/src/components/MotionControlStudio.jsx | 214 | function CharacterImagesMediaButton({ | CODE |
| LOW | …ckages/studio/src/components/prompt/PromptComposer.jsx | 64 | export function promptMediaButtonClassName({ | CODE |
| LOW | electron/lib/localInferenceAssets.js | 3 | function pickBinaryAssetForPlatform({ platform, arch, zipNames }) { | CODE |
| LOW | electron/lib/localInferenceAssets.js | 41 | function getBundledBinaryResourceDir({ resourcesPath, platform, arch }) { | CODE |
| 4 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | messages/zh/common.json | 63 | "placeholder": "在此粘贴您的密钥...", | CODE |
| LOW | messages/en/common.json | 63 | "placeholder": "Paste your key here...", | CODE |
| LOW | packages/studio/src/messages/zh/cinemaStudio.json | 39 | "placeholder": "描述你的电影场景...", | CODE |
| LOW | packages/studio/src/messages/zh/videoStudio.json | 12 | "placeholder": "搜索模型..." | CODE |
| LOW | packages/studio/src/messages/zh/lipSyncStudio.json | 23 | "placeholder": "描述说话风格..." | CODE |
| LOW | packages/studio/src/messages/zh/marketingStudio.json | 14 | "placeholder": "描述您的广告脚本... 使用 @image1 表示产品,@image2 表示形象。" | CODE |
| LOW | packages/studio/src/messages/zh/layersStudio.json | 107 | "placeholder": "输入文字修改提示词...", | CODE |
| LOW | packages/studio/src/messages/zh/aiInfluencerStudio.json | 51 | "placeholder": "添加更多细节…例如霓虹赛博朋克灯光、戏剧性阴影" | CODE |
| LOW | packages/studio/src/messages/zh/vibeMotionStudio.json | 37 | "placeholder": { | CODE |
| LOW | packages/studio/src/messages/en/cinemaStudio.json | 39 | "placeholder": "Describe your cinema scene...", | CODE |
| LOW | packages/studio/src/messages/en/videoStudio.json | 12 | "placeholder": "Search models..." | CODE |
| LOW | packages/studio/src/messages/en/lipSyncStudio.json | 23 | "placeholder": "Describe speech style..." | CODE |
| LOW | packages/studio/src/messages/en/marketingStudio.json | 14 | "placeholder": "Describe your ad script... Use @image1 for product, @image2 for avatar." | CODE |
| LOW | packages/studio/src/messages/en/layersStudio.json | 107 | "placeholder": "Enter text modification prompt...", | CODE |
| LOW | packages/studio/src/messages/en/aiInfluencerStudio.json | 51 | "placeholder": "Add extra details… e.g. neon cyberpunk lighting, dramatic shadows" | CODE |
| LOW | packages/studio/src/messages/en/vibeMotionStudio.json | 37 | "placeholder": { | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | packages/studio/src/components/AppsStudio.jsx | 106 | { thumbnail: "https://cdn.muapi.ai/apps/Social_Post.webp", name: "Social Post", description: "AI-generated social medi | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | packages/studio/src/i18nUtils.js | 1 | // Tiny, dependency-free locale-copy resolver shared by every Studio | COMMENT |
| LOW | lib/locales.js | 1 | // Locale registry for the standalone Open Generative AI studio app. | COMMENT |
| LOW | electron/lib/wan2gpProvider.js | 1 | // Wan2GP provider — video (and large image) models from https://github.com/deepbeepmeep/Wan2GP. | COMMENT |
| LOW | src/lib/models.js | 1 | // Single source of truth lives in the studio workspace package. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/lib/muapi.js | 73 | // Step 1: Submit the task | COMMENT |
| LOW | src/lib/muapi.js | 102 | // Step 2: Poll for results | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/lib/muapi.js | 73 | // Step 1: Submit the task | COMMENT |
| LOW | src/lib/muapi.js | 102 | // Step 2: Poll for results | COMMENT |