{
  "drawnFrom": {
    "commit": "d533189ffb6e2b2addd2103950bdb23c6612f305",
    "date": "2026-10-12T17:44:49+02:00",
    "repo": "michaelvanhoutte/cockpit"
  },
  "context": {
    "cockpit": {
      "name": "Cockpit",
      "summary": "Unified inbox and dashboards, one Worker per environment on Cloudflare serving the API, live updates and the app.",
      "runs": "production · staging"
    },
    "people": [
      {
        "name": "People in a workspace",
        "detail": "browser, installed PWA, share sheet"
      },
      {
        "name": "Guest",
        "detail": "demo sign-in, reset every night"
      },
      {
        "name": "Admin and operator",
        "detail": "admin pages, backup and restore"
      },
      {
        "name": "AI agents",
        "detail": "Claude.ai, Claude Code over MCP"
      }
    ],
    "services": [
      {
        "name": "Google",
        "detail": "sign-in, Gmail API"
      },
      {
        "name": "Microsoft",
        "detail": "Entra sign-in, Teams via Bot Framework"
      },
      {
        "name": "Anthropic",
        "detail": "Claude API reads captured notes"
      },
      {
        "name": "Cloudflare Workers AI",
        "detail": "embeddings, notes that repeat"
      },
      {
        "name": "GitHub",
        "detail": "code, CI, deploys, report pages"
      }
    ]
  },
  "modules": {
    "layers": [
      {
        "title": "Web app",
        "note": "Served by the Worker as static assets; it talks to the API over HTTP and live updates, in the shapes of packages/shared.",
        "undescribed": false,
        "areas": [
          {
            "path": "apps/web/src",
            "name": "web",
            "description": "The React app: router, pages, panels, Inbox, Capture and its offline outbox, item form, settings and connections.",
            "role": "core",
            "state": "described",
            "files": 155,
            "breaches": []
          }
        ]
      },
      {
        "title": "API",
        "note": "One Cloudflare Worker. worker.ts dispatches fetch, queue and scheduled; the Hono app handles requests.",
        "undescribed": false,
        "areas": [
          {
            "path": "apps/api/src/http",
            "name": "http",
            "description": "The Hono app: every route, request validation, error-to-status mapping and the live-update stream.",
            "role": "core",
            "state": "described",
            "files": 1,
            "breaches": []
          },
          {
            "path": "apps/api/src/auth",
            "name": "auth",
            "description": "Sign-in with OIDC, sessions, the gate in front of every route, operator and admin access, attachment links.",
            "role": "core",
            "state": "described",
            "files": 13,
            "breaches": []
          },
          {
            "path": "apps/api/src/mcp",
            "name": "mcp",
            "description": "The MCP server at /mcp: OAuth for connected apps, consent, grants and the create_item tool.",
            "role": "core",
            "state": "described",
            "files": 7,
            "breaches": []
          },
          {
            "path": "apps/api/src/jobs",
            "name": "jobs",
            "description": "The queue consumer that cleans up and reads captured notes, and the nightly scheduled work.",
            "role": "core",
            "state": "described",
            "files": 5,
            "breaches": []
          },
          {
            "path": "apps/api/src/engines",
            "name": "engines",
            "description": "Claude Code, the one outbound engine: the trigger check, the fire request, its refusal wording and reading a hook, reached only through engines/list.ts.",
            "role": "core",
            "state": "described",
            "files": 3,
            "breaches": []
          },
          {
            "path": "apps/api/src/ai",
            "name": "ai",
            "description": "The Claude layer behind a project-owned interface: prompts that clean up a note and choose a panel.",
            "role": "core",
            "state": "described",
            "files": 4,
            "breaches": []
          },
          {
            "path": "apps/api/src/embeddings",
            "name": "embeddings",
            "description": "Reads what a note means with Workers AI, so a note that repeats another can be flagged.",
            "role": "core",
            "state": "described",
            "files": 1,
            "breaches": []
          },
          {
            "path": "apps/api/src/gateway",
            "name": "gateway",
            "description": "Makes and retries every paid provider call, and records each attempt in D1 for 12 months.",
            "role": "core",
            "state": "described",
            "files": 3,
            "breaches": []
          },
          {
            "path": "apps/api/src/accounts",
            "name": "accounts",
            "description": "The AccountStore Durable Object, one per account: its SQLite schema, change log, command service, backup and restore.",
            "role": "core",
            "state": "described",
            "files": 26,
            "breaches": []
          },
          {
            "path": "apps/api/src/domain",
            "name": "domain",
            "description": "The account data model as plain code: items, panels, dashboards, filings, workspaces and the histories behind them.",
            "role": "core",
            "state": "described",
            "files": 18,
            "breaches": []
          },
          {
            "path": "apps/api/src/db",
            "name": "db",
            "description": "The register in D1 (accounts, users, sign-ins, connector directory): its Drizzle schema and client.",
            "role": "core",
            "state": "described",
            "files": 2,
            "breaches": []
          },
          {
            "path": "apps/api/src/connectors",
            "name": "connectors",
            "description": "The composition root where the core meets connectors, with the host connectors run against and the credential crypto.",
            "role": "core",
            "state": "described",
            "files": 7,
            "breaches": []
          },
          {
            "path": "apps/api/src/*",
            "name": "env.ts, worker.ts",
            "description": "The Worker entry points (worker.ts, index.ts), its bindings type (env.ts) and the share target.",
            "role": "core",
            "state": "described",
            "files": 4,
            "breaches": []
          }
        ]
      },
      {
        "title": "Packages",
        "note": "Shared by the web app and the API.",
        "undescribed": false,
        "areas": [
          {
            "path": "packages/shared",
            "name": "shared",
            "description": "The contract between web and API: domain types, Zod schemas, command definitions and API shapes.",
            "role": "core",
            "state": "described",
            "files": 27,
            "breaches": []
          },
          {
            "path": "packages/connector-sdk",
            "name": "connector-sdk",
            "description": "The connector SPI: what a connector is and the only capabilities the host offers it.",
            "role": "core",
            "state": "described",
            "files": 1,
            "breaches": []
          },
          {
            "path": "packages/config",
            "name": "config",
            "description": "Shared tsconfig and formatting config for the monorepo; no code runs from it.",
            "role": "other",
            "state": "described",
            "files": 1,
            "breaches": []
          }
        ]
      },
      {
        "title": "Connector packages",
        "note": "A connector imports the connector SDK and nothing else of ours.",
        "undescribed": false,
        "areas": [
          {
            "path": "packages/connectors/teams",
            "name": "connectors/teams",
            "description": "The Microsoft Teams connector: a Save to Cockpit message action, verified as a genuine Bot Framework call.",
            "role": "connector",
            "state": "described",
            "files": 5,
            "breaches": [
              {
                "file": "vitest.config.ts",
                "import": "../../../scripts/lib/vitest-session-reporter.mjs"
              },
              {
                "file": "vitest.contract.config.ts",
                "import": "../../../scripts/lib/vitest-session-reporter.mjs"
              }
            ]
          },
          {
            "path": "packages/connectors/gmail",
            "name": "connectors/gmail",
            "description": "The Gmail connector: conversations labelled Cockpit, or starred, arrive as Tasks, and their label or star follows the Task.",
            "role": "connector",
            "state": "described",
            "files": 8,
            "breaches": [
              {
                "file": "vitest.config.ts",
                "import": "../../../scripts/lib/vitest-session-reporter.mjs"
              },
              {
                "file": "vitest.contract.config.ts",
                "import": "../../../scripts/lib/vitest-session-reporter.mjs"
              }
            ]
          }
        ]
      }
    ],
    "connectors": [
      {
        "id": "gmail",
        "name": "Gmail",
        "package": {
          "path": "packages/connectors/gmail",
          "state": "present"
        },
        "inCore": []
      },
      {
        "id": "claude-code",
        "name": "Claude Code",
        "package": null,
        "inCore": [
          {
            "area": "apps/web/src",
            "files": [
              "components/ConnectClaudeCode.tsx"
            ]
          },
          {
            "area": "apps/api/src/engines",
            "files": [
              "claude-code-hooks.ts",
              "claude-code.ts"
            ]
          }
        ]
      },
      {
        "id": "teams",
        "name": "Microsoft Teams",
        "package": {
          "path": "packages/connectors/teams",
          "state": "present"
        },
        "inCore": []
      }
    ],
    "releasedOnItsOwn": [
      {
        "name": "Teams app",
        "path": "packages/connectors/teams/teams-app",
        "description": "Its manifest, zipped and uploaded to Teams by hand.",
        "state": "present"
      }
    ],
    "workers": [
      {
        "name": "cockpit",
        "main": "src/worker.ts",
        "environments": [
          "production",
          "staging",
          "local"
        ],
        "areas": [
          "apps/web/src",
          "apps/api/src/http",
          "apps/api/src/auth",
          "apps/api/src/mcp",
          "apps/api/src/jobs",
          "apps/api/src/engines",
          "apps/api/src/ai",
          "apps/api/src/embeddings",
          "apps/api/src/gateway",
          "apps/api/src/accounts",
          "apps/api/src/domain",
          "apps/api/src/db",
          "apps/api/src/connectors",
          "apps/api/src/*",
          "packages/shared",
          "packages/connector-sdk",
          "packages/connectors/teams",
          "packages/connectors/gmail"
        ]
      }
    ],
    "counts": {
      "areas": 19,
      "undescribed": 0,
      "gone": 0,
      "connectorFilesInCore": 3,
      "connectorBreaches": 2
    }
  },
  "dependencies": {
    "areas": [
      {
        "path": "apps/web/src",
        "name": "web",
        "muted": false,
        "lines": 37714
      },
      {
        "path": "apps/api/src/http",
        "name": "http",
        "muted": false,
        "lines": 2640
      },
      {
        "path": "apps/api/src/mcp",
        "name": "mcp",
        "muted": false,
        "lines": 1011
      },
      {
        "path": "apps/api/src/jobs",
        "name": "jobs",
        "muted": false,
        "lines": 1811
      },
      {
        "path": "apps/api/src/engines",
        "name": "engines",
        "muted": false,
        "lines": 310
      },
      {
        "path": "apps/api/src/connectors",
        "name": "connectors",
        "muted": false,
        "lines": 1118
      },
      {
        "path": "apps/api/src/auth",
        "name": "auth",
        "muted": false,
        "lines": 2248
      },
      {
        "path": "apps/api/src/ai",
        "name": "ai",
        "muted": false,
        "lines": 1166
      },
      {
        "path": "apps/api/src/accounts",
        "name": "accounts",
        "muted": false,
        "lines": 18529
      },
      {
        "path": "apps/api/src/embeddings",
        "name": "embeddings",
        "muted": false,
        "lines": 219
      },
      {
        "path": "apps/api/src/gateway",
        "name": "gateway",
        "muted": false,
        "lines": 317
      },
      {
        "path": "apps/api/src/domain",
        "name": "domain",
        "muted": false,
        "lines": 2419
      },
      {
        "path": "apps/api/src/db",
        "name": "db",
        "muted": false,
        "lines": 398
      },
      {
        "path": "packages/connectors/teams",
        "name": "connectors/teams",
        "muted": false,
        "lines": 600
      },
      {
        "path": "packages/connectors/gmail",
        "name": "connectors/gmail",
        "muted": false,
        "lines": 1288
      },
      {
        "path": "packages/connector-sdk",
        "name": "connector-sdk",
        "muted": false,
        "lines": 385
      },
      {
        "path": "packages/shared",
        "name": "shared",
        "muted": false,
        "lines": 3498
      },
      {
        "path": "packages/config",
        "name": "config",
        "muted": false,
        "lines": 7
      },
      {
        "path": "apps/api/src/*",
        "name": "env.ts, worker.ts",
        "muted": true,
        "lines": 404
      }
    ],
    "cells": [
      {
        "from": "apps/web/src",
        "to": "packages/shared",
        "files": 67,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/http",
        "to": "apps/api/src/mcp",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/http",
        "to": "apps/api/src/jobs",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/http",
        "to": "apps/api/src/engines",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/http",
        "to": "apps/api/src/connectors",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/http",
        "to": "apps/api/src/auth",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/http",
        "to": "apps/api/src/accounts",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/http",
        "to": "apps/api/src/gateway",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/http",
        "to": "apps/api/src/domain",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/http",
        "to": "packages/shared",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/http",
        "to": "apps/api/src/*",
        "files": 1,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/mcp",
        "to": "apps/api/src/jobs",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/mcp",
        "to": "apps/api/src/auth",
        "files": 4,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/mcp",
        "to": "apps/api/src/accounts",
        "files": 2,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/mcp",
        "to": "apps/api/src/domain",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/mcp",
        "to": "apps/api/src/db",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/mcp",
        "to": "packages/shared",
        "files": 3,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/mcp",
        "to": "apps/api/src/*",
        "files": 6,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/jobs",
        "to": "apps/api/src/connectors",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/jobs",
        "to": "apps/api/src/auth",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/jobs",
        "to": "apps/api/src/ai",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/jobs",
        "to": "apps/api/src/accounts",
        "files": 5,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/jobs",
        "to": "apps/api/src/embeddings",
        "files": 2,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/jobs",
        "to": "apps/api/src/gateway",
        "files": 2,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/jobs",
        "to": "apps/api/src/domain",
        "files": 3,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/jobs",
        "to": "packages/shared",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/jobs",
        "to": "apps/api/src/*",
        "files": 5,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/engines",
        "to": "apps/api/src/auth",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/engines",
        "to": "apps/api/src/gateway",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/engines",
        "to": "packages/shared",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/connectors",
        "to": "apps/api/src/auth",
        "files": 2,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/connectors",
        "to": "apps/api/src/accounts",
        "files": 3,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/connectors",
        "to": "apps/api/src/domain",
        "files": 2,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/connectors",
        "to": "apps/api/src/db",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/connectors",
        "to": "packages/connectors/teams",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/connectors",
        "to": "packages/connectors/gmail",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/connectors",
        "to": "packages/connector-sdk",
        "files": 5,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/connectors",
        "to": "apps/api/src/*",
        "files": 6,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/auth",
        "to": "apps/api/src/accounts",
        "files": 3,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/auth",
        "to": "apps/api/src/db",
        "files": 2,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/auth",
        "to": "packages/shared",
        "files": 2,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/auth",
        "to": "apps/api/src/*",
        "files": 5,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/ai",
        "to": "apps/api/src/gateway",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/ai",
        "to": "apps/api/src/domain",
        "files": 3,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/ai",
        "to": "packages/shared",
        "files": 2,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/ai",
        "to": "apps/api/src/*",
        "files": 1,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/accounts",
        "to": "apps/api/src/embeddings",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/accounts",
        "to": "apps/api/src/domain",
        "files": 9,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/accounts",
        "to": "apps/api/src/db",
        "files": 2,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/accounts",
        "to": "packages/connector-sdk",
        "files": 6,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/accounts",
        "to": "packages/shared",
        "files": 14,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/accounts",
        "to": "apps/api/src/*",
        "files": 5,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/embeddings",
        "to": "apps/api/src/gateway",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/embeddings",
        "to": "apps/api/src/*",
        "files": 1,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/gateway",
        "to": "packages/shared",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/gateway",
        "to": "apps/api/src/*",
        "files": 2,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/domain",
        "to": "packages/shared",
        "files": 12,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/db",
        "to": "packages/shared",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "packages/connectors/teams",
        "to": "packages/connector-sdk",
        "files": 3,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "packages/connectors/gmail",
        "to": "packages/connector-sdk",
        "files": 4,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "packages/connector-sdk",
        "to": "packages/shared",
        "files": 1,
        "kind": "downward",
        "cycle": false
      },
      {
        "from": "apps/api/src/*",
        "to": "apps/api/src/http",
        "files": 1,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/*",
        "to": "apps/api/src/mcp",
        "files": 1,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/*",
        "to": "apps/api/src/jobs",
        "files": 2,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/*",
        "to": "apps/api/src/connectors",
        "files": 1,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/*",
        "to": "apps/api/src/auth",
        "files": 1,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/*",
        "to": "apps/api/src/accounts",
        "files": 2,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/*",
        "to": "packages/connector-sdk",
        "files": 1,
        "kind": "muted"
      },
      {
        "from": "apps/api/src/*",
        "to": "packages/shared",
        "files": 2,
        "kind": "muted"
      }
    ],
    "cyclePairs": [],
    "undecidedPairs": [],
    "order": {
      "method": "exact",
      "areas": 18,
      "limit": 18,
      "upwardFiles": 0
    }
  },
  "deployment": {
    "pages": {
      "workflow": "publish.yml",
      "reports": [
        {
          "artifact": "test-explorer-report",
          "path": "/"
        },
        {
          "artifact": "ci-stability-report",
          "path": "/stability/"
        },
        {
          "artifact": "cycle-time-report",
          "path": "/cycle-time/"
        },
        {
          "artifact": "test-selection-report",
          "path": "/selection/"
        },
        {
          "artifact": "architecture-report",
          "path": "/architecture/"
        }
      ]
    },
    "environments": [
      {
        "name": "production",
        "kind": "production",
        "worker": "cockpit",
        "main": "src/worker.ts",
        "resources": [
          {
            "kind": "D1 database",
            "binding": "DB",
            "name": "cockpit",
            "inherited": false
          },
          {
            "kind": "R2 bucket",
            "binding": "ATTACHMENTS",
            "name": "cockpit-attachments",
            "inherited": false
          },
          {
            "kind": "KV namespace",
            "binding": "OAUTH_KV",
            "name": "c2a6d73caf0d43bfac75e175516e4df1",
            "inherited": false
          },
          {
            "kind": "Durable Object",
            "binding": "ACCOUNT",
            "name": "AccountStore",
            "inherited": false
          },
          {
            "kind": "Queue, producer",
            "binding": "ENRICHMENT",
            "name": "cockpit-enrichment",
            "inherited": false
          },
          {
            "kind": "Queue, consumer",
            "binding": null,
            "name": "cockpit-enrichment",
            "inherited": false
          },
          {
            "kind": "Workers AI",
            "binding": "AI",
            "name": null,
            "inherited": false
          },
          {
            "kind": "Static assets",
            "binding": "ASSETS",
            "name": "../web/dist",
            "inherited": false
          },
          {
            "kind": "Cron trigger",
            "binding": null,
            "name": "0 3 * * *",
            "inherited": false
          }
        ],
        "deployedBy": [
          "deploy-harness-monitor.yml",
          "deploy-production.yml"
        ]
      },
      {
        "name": "staging",
        "kind": "staging",
        "worker": "cockpit-staging",
        "main": "src/worker.ts",
        "resources": [
          {
            "kind": "D1 database",
            "binding": "DB",
            "name": "cockpit-staging",
            "inherited": false
          },
          {
            "kind": "R2 bucket",
            "binding": "ATTACHMENTS",
            "name": "cockpit-attachments-staging",
            "inherited": false
          },
          {
            "kind": "KV namespace",
            "binding": "OAUTH_KV",
            "name": "40afd4f58c914507b7047737ee4d75bc",
            "inherited": false
          },
          {
            "kind": "Durable Object",
            "binding": "ACCOUNT",
            "name": "AccountStore",
            "inherited": false
          },
          {
            "kind": "Queue, producer",
            "binding": "ENRICHMENT",
            "name": "cockpit-enrichment-staging",
            "inherited": false
          },
          {
            "kind": "Queue, consumer",
            "binding": null,
            "name": "cockpit-enrichment-staging",
            "inherited": false
          },
          {
            "kind": "Workers AI",
            "binding": "AI",
            "name": null,
            "inherited": false
          },
          {
            "kind": "Static assets",
            "binding": "ASSETS",
            "name": "../web/dist",
            "inherited": true
          },
          {
            "kind": "Cron trigger",
            "binding": null,
            "name": "0 3 * * *",
            "inherited": true
          }
        ],
        "deployedBy": [
          "deploy-staging.yml"
        ]
      },
      {
        "name": "local",
        "kind": "local development",
        "worker": "cockpit-local",
        "main": "src/worker.ts",
        "resources": [
          {
            "kind": "D1 database",
            "binding": "DB",
            "name": "cockpit",
            "inherited": false
          },
          {
            "kind": "R2 bucket",
            "binding": "ATTACHMENTS",
            "name": "cockpit-attachments",
            "inherited": false
          },
          {
            "kind": "KV namespace",
            "binding": "OAUTH_KV",
            "name": "cockpit-oauth-local",
            "inherited": false
          },
          {
            "kind": "Durable Object",
            "binding": "ACCOUNT",
            "name": "AccountStore",
            "inherited": false
          },
          {
            "kind": "Queue, producer",
            "binding": "ENRICHMENT",
            "name": "cockpit-enrichment",
            "inherited": false
          },
          {
            "kind": "Queue, consumer",
            "binding": null,
            "name": "cockpit-enrichment",
            "inherited": false
          },
          {
            "kind": "Static assets",
            "binding": "ASSETS",
            "name": "../web/dist",
            "inherited": true
          },
          {
            "kind": "Cron trigger",
            "binding": null,
            "name": "0 3 * * *",
            "inherited": true
          }
        ],
        "deployedBy": []
      }
    ],
    "workflows": [
      {
        "file": "ci.yml",
        "name": "CI",
        "starts": [
          {
            "event": "push",
            "text": "every merge"
          },
          {
            "event": "pull_request",
            "text": "every pull request"
          }
        ],
        "calledBy": [],
        "deploys": []
      },
      {
        "file": "claude.yml",
        "name": "Claude Code",
        "starts": [
          {
            "event": "issue_comment",
            "text": "issue comment"
          },
          {
            "event": "pull_request_review_comment",
            "text": "pull request review comment"
          },
          {
            "event": "issues",
            "text": "issues"
          },
          {
            "event": "pull_request_review",
            "text": "pull request review"
          }
        ],
        "calledBy": [],
        "deploys": []
      },
      {
        "file": "codeql.yml",
        "name": "CodeQL",
        "starts": [
          {
            "event": "push",
            "text": "every merge"
          },
          {
            "event": "schedule",
            "text": "every Monday at 03:00 UTC",
            "cron": "0 3 * * 1"
          }
        ],
        "calledBy": [],
        "deploys": []
      },
      {
        "file": "contract.yml",
        "name": "Contract",
        "starts": [
          {
            "event": "pull_request",
            "text": "every pull request"
          },
          {
            "event": "schedule",
            "text": "every Monday at 03:00 UTC",
            "cron": "0 3 * * 1"
          },
          {
            "event": "workflow_dispatch",
            "text": "by hand",
            "inputs": []
          }
        ],
        "calledBy": [],
        "deploys": []
      },
      {
        "file": "deploy-harness-monitor.yml",
        "name": "Deploy Harness Monitor",
        "starts": [
          {
            "event": "push",
            "text": "every merge"
          },
          {
            "event": "workflow_dispatch",
            "text": "by hand",
            "inputs": []
          }
        ],
        "calledBy": [],
        "deploys": [
          {
            "environment": "production",
            "declared": true
          }
        ]
      },
      {
        "file": "deploy-production.yml",
        "name": "Promote to production",
        "starts": [
          {
            "event": "workflow_dispatch",
            "text": "by hand",
            "inputs": [
              "sha"
            ]
          }
        ],
        "calledBy": [],
        "deploys": [
          {
            "environment": "production",
            "declared": true
          }
        ]
      },
      {
        "file": "deploy-staging.yml",
        "name": "Deploy staging",
        "starts": [
          {
            "event": "push",
            "text": "every merge"
          },
          {
            "event": "workflow_dispatch",
            "text": "by hand",
            "inputs": []
          }
        ],
        "calledBy": [],
        "deploys": [
          {
            "environment": "staging",
            "declared": true
          }
        ]
      },
      {
        "file": "nightly.yml",
        "name": "Nightly",
        "starts": [
          {
            "event": "schedule",
            "text": "every night at 04:17 UTC",
            "cron": "17 4 * * *"
          },
          {
            "event": "workflow_dispatch",
            "text": "by hand",
            "inputs": []
          }
        ],
        "calledBy": [],
        "deploys": []
      },
      {
        "file": "publish.yml",
        "name": "Publish",
        "starts": [
          {
            "event": "workflow_call",
            "text": "called by ci.yml, nightly.yml"
          }
        ],
        "calledBy": [
          "ci.yml",
          "nightly.yml"
        ],
        "deploys": []
      }
    ]
  }
}