{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://dealsage.io/schemas/custom-app-manifest.json", "title": "DealSage custom app manifest (.dealsage/app.json)", "description": "The per-app contract the platform pipeline reads: which app this repo is, which checks to run before a build is published, and which platform objects the app depends on. The pipeline itself is platform-owned (dealsage-platform/ci-actions); this file is owned by the app's team.", "type": "object", "additionalProperties": false, "required": ["appId"], "properties": { "appId": { "type": "string", "description": "The custom_apps.id this repo belongs to. Stamped by provisioning; never edit.", "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" }, "checks": { "type": "array", "description": "Checks the pipeline runs on every push, in order, before building. A failed required check stops the build; results are recorded in DealSage either way.", "items": { "type": "object", "additionalProperties": false, "required": ["id"], "properties": { "id": { "type": "string", "description": "Stable identifier, unique within the app (e.g. typecheck, test, lint).", "pattern": "^[a-z][a-z0-9-]{0,39}$" }, "name": { "type": "string", "description": "Label shown in DealSage. Defaults to the id." }, "run": { "type": "string", "description": "Shell command executed in the repo root. Exactly one of run or uses." }, "uses": { "type": "string", "description": "A platform-provided check to run instead of a command. Known values: conventions (validates this manifest and the repo layout).", "enum": ["conventions"] }, "required": { "type": "boolean", "default": true, "description": "When true, a failure stops the build. When false, the result is recorded and the pipeline continues." }, "timeoutMinutes": { "type": "integer", "minimum": 1, "maximum": 60, "default": 15 } }, "oneOf": [{ "required": ["run"] }, { "required": ["uses"] }] } }, "dependencies": { "type": "object", "description": "Platform objects the app is built against. Recorded with every version so DealSage can flag drift when a dependency changes.", "additionalProperties": false, "properties": { "objectTypes": { "type": "array", "items": { "type": "object", "additionalProperties": false, "required": ["apiName"], "properties": { "apiName": { "type": "string" }, "schemaVersion": { "type": "integer", "minimum": 1, "description": "The schema version the app was written against." } } } } } } } }