{
  "schemaVersion": 1,
  "sensitiveFieldsExcluded": true,
  "generatedAt": "1970-01-01T00:00:00.000Z",
  "packageName": "@happyvertical/smrt-prompts",
  "packageVersion": "0.51.10",
  "sourceManifestPath": "dist/manifest.json",
  "agentDocPath": "AGENTS.md",
  "sourceHashes": {
    "manifest": "ea4a06b3e7d151d36ffb413cfbe9c7617ecfbf36dc3df54fc05e0aa6cc6637a1",
    "packageJson": "eee8c30c3ba2406eccf1d77da07aa78d7cd237d973c68a383332f58d0ae1d24d",
    "agents": "f273f3ce4ed80310d9afdea484314a455a4f7927f79ad8d92a4dff37c20233fa"
  },
  "exports": [
    ".",
    "./manifest",
    "./manifest.json"
  ],
  "dependencies": {
    "@happyvertical/smrt-config": "workspace:*",
    "@happyvertical/smrt-core": "workspace:*",
    "@happyvertical/smrt-tenancy": "workspace:*",
    "@happyvertical/sql": "catalog:",
    "@happyvertical/smrt-vitest": "workspace:*",
    "@types/node": "24.13.2",
    "typescript": "5.9.3",
    "vite": "8.1.4",
    "vitest": "4.1.10"
  },
  "smrtDependencies": [
    "@happyvertical/smrt-config",
    "@happyvertical/smrt-core",
    "@happyvertical/smrt-tenancy",
    "@happyvertical/smrt-vitest"
  ],
  "sdkDependencies": [
    "@happyvertical/sql"
  ],
  "tags": [
    "ai",
    "configuration",
    "cross-package",
    "multi-tenancy",
    "prompts",
    "smrt"
  ],
  "risks": [
    "sensitive-fields-excluded"
  ],
  "objects": [
    {
      "name": "PromptOverride",
      "qualifiedName": "@happyvertical/smrt-prompts:PromptOverride",
      "collection": "promptoverrides",
      "tableName": "_smrt_prompt_overrides",
      "packageName": "@happyvertical/smrt-prompts",
      "extends": "SmrtObject",
      "fields": [
        {
          "name": "key",
          "type": "text",
          "required": true,
          "columnType": "TEXT",
          "default": ""
        },
        {
          "name": "tenantId",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "template",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "profile",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "model",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "params",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        }
      ],
      "relationships": [],
      "methods": [
        "delete",
        "getParams",
        "save",
        "setParams",
        "toPromptLayer"
      ],
      "methodSignatures": [
        {
          "name": "delete",
          "async": true,
          "returns": "Promise<void>"
        },
        {
          "name": "getParams",
          "returns": "PromptParams"
        },
        {
          "name": "save",
          "async": true,
          "returns": "Promise<this>"
        },
        {
          "name": "setParams",
          "params": [
            "params: PromptParams | null"
          ],
          "returns": "void"
        },
        {
          "name": "toPromptLayer",
          "returns": "PromptLayer"
        }
      ],
      "conflictColumns": [
        "key",
        "context"
      ],
      "surfaces": [
        {
          "kind": "api",
          "name": "promptoverrides.list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride",
          "path": "/promptoverrides",
          "method": "GET"
        },
        {
          "kind": "api",
          "name": "promptoverrides.get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride",
          "path": "/promptoverrides/[id]",
          "method": "GET"
        },
        {
          "kind": "api",
          "name": "promptoverrides.create",
          "operation": "create",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride",
          "path": "/promptoverrides",
          "method": "POST"
        },
        {
          "kind": "api",
          "name": "promptoverrides.update",
          "operation": "update",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride",
          "path": "/promptoverrides/[id]",
          "method": "PATCH"
        },
        {
          "kind": "api",
          "name": "promptoverrides.delete",
          "operation": "delete",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride",
          "path": "/promptoverrides/[id]",
          "method": "DELETE"
        },
        {
          "kind": "cli",
          "name": "promptoverride_list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride"
        },
        {
          "kind": "cli",
          "name": "promptoverride_get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride"
        },
        {
          "kind": "cli",
          "name": "promptoverride_create",
          "operation": "create",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride"
        },
        {
          "kind": "cli",
          "name": "promptoverride_update",
          "operation": "update",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride"
        },
        {
          "kind": "cli",
          "name": "promptoverride_delete",
          "operation": "delete",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride"
        }
      ],
      "withheldSurfaces": [
        {
          "kind": "api",
          "operation": "getParams",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride"
        },
        {
          "kind": "api",
          "operation": "save",
          "code": "lifecycle-method",
          "reason": "`save` is a framework lifecycle method, not a distinct operation",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride"
        },
        {
          "kind": "api",
          "operation": "setParams",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride"
        },
        {
          "kind": "api",
          "operation": "toPromptLayer",
          "code": "not-included",
          "reason": "not listed in api.include",
          "objectName": "@happyvertical/smrt-prompts:PromptOverride"
        }
      ],
      "relationshipFeatures": [
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    },
    {
      "name": "PromptOverrideCollection",
      "qualifiedName": "@happyvertical/smrt-prompts:PromptOverrideCollection",
      "collection": "promptoverrides",
      "tableName": "_smrt_prompt_overrides",
      "packageName": "@happyvertical/smrt-prompts",
      "extends": "SmrtCollection",
      "fields": [],
      "relationships": [],
      "methods": [
        "getAppOverride",
        "getResolutionLayers",
        "getTenantOverride"
      ],
      "methodSignatures": [
        {
          "name": "getAppOverride",
          "async": true,
          "params": [
            "key: string",
            "options?: object"
          ],
          "returns": "Promise<PromptOverride | null>"
        },
        {
          "name": "getResolutionLayers",
          "async": true,
          "params": [
            "key: string",
            "tenantId?: string | null",
            "options?: object"
          ],
          "returns": "Promise<object>"
        },
        {
          "name": "getTenantOverride",
          "async": true,
          "params": [
            "key: string",
            "tenantId: string",
            "options?: object"
          ],
          "returns": "Promise<PromptOverride | null>"
        }
      ],
      "surfaces": [
        {
          "kind": "api",
          "name": "promptoverrides.getAppOverride",
          "operation": "getAppOverride",
          "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection",
          "path": "/promptoverrides/getAppOverride",
          "method": "POST"
        },
        {
          "kind": "api",
          "name": "promptoverrides.getTenantOverride",
          "operation": "getTenantOverride",
          "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection",
          "path": "/promptoverrides/getTenantOverride",
          "method": "POST"
        },
        {
          "kind": "api",
          "name": "promptoverrides.getResolutionLayers",
          "operation": "getResolutionLayers",
          "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection",
          "path": "/promptoverrides/getResolutionLayers",
          "method": "POST"
        },
        {
          "kind": "cli",
          "name": "promptoverridecollection_getAppOverride",
          "operation": "getAppOverride",
          "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection"
        },
        {
          "kind": "cli",
          "name": "promptoverridecollection_getTenantOverride",
          "operation": "getTenantOverride",
          "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection"
        },
        {
          "kind": "cli",
          "name": "promptoverridecollection_getResolutionLayers",
          "operation": "getResolutionLayers",
          "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection"
        },
        {
          "kind": "mcp",
          "name": "promptoverridecollection_getappoverride",
          "operation": "getAppOverride",
          "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection"
        },
        {
          "kind": "mcp",
          "name": "promptoverridecollection_gettenantoverride",
          "operation": "getTenantOverride",
          "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection"
        },
        {
          "kind": "mcp",
          "name": "promptoverridecollection_getresolutionlayers",
          "operation": "getResolutionLayers",
          "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection"
        }
      ],
      "relationshipFeatures": [
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    }
  ],
  "surfaces": [
    {
      "kind": "api",
      "name": "promptoverrides.list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-prompts:PromptOverride",
      "path": "/promptoverrides",
      "method": "GET"
    },
    {
      "kind": "api",
      "name": "promptoverrides.get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-prompts:PromptOverride",
      "path": "/promptoverrides/[id]",
      "method": "GET"
    },
    {
      "kind": "api",
      "name": "promptoverrides.create",
      "operation": "create",
      "objectName": "@happyvertical/smrt-prompts:PromptOverride",
      "path": "/promptoverrides",
      "method": "POST"
    },
    {
      "kind": "api",
      "name": "promptoverrides.update",
      "operation": "update",
      "objectName": "@happyvertical/smrt-prompts:PromptOverride",
      "path": "/promptoverrides/[id]",
      "method": "PATCH"
    },
    {
      "kind": "api",
      "name": "promptoverrides.delete",
      "operation": "delete",
      "objectName": "@happyvertical/smrt-prompts:PromptOverride",
      "path": "/promptoverrides/[id]",
      "method": "DELETE"
    },
    {
      "kind": "cli",
      "name": "promptoverride_list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-prompts:PromptOverride"
    },
    {
      "kind": "cli",
      "name": "promptoverride_get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-prompts:PromptOverride"
    },
    {
      "kind": "cli",
      "name": "promptoverride_create",
      "operation": "create",
      "objectName": "@happyvertical/smrt-prompts:PromptOverride"
    },
    {
      "kind": "cli",
      "name": "promptoverride_update",
      "operation": "update",
      "objectName": "@happyvertical/smrt-prompts:PromptOverride"
    },
    {
      "kind": "cli",
      "name": "promptoverride_delete",
      "operation": "delete",
      "objectName": "@happyvertical/smrt-prompts:PromptOverride"
    },
    {
      "kind": "api",
      "name": "promptoverrides.getAppOverride",
      "operation": "getAppOverride",
      "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection",
      "path": "/promptoverrides/getAppOverride",
      "method": "POST"
    },
    {
      "kind": "api",
      "name": "promptoverrides.getTenantOverride",
      "operation": "getTenantOverride",
      "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection",
      "path": "/promptoverrides/getTenantOverride",
      "method": "POST"
    },
    {
      "kind": "api",
      "name": "promptoverrides.getResolutionLayers",
      "operation": "getResolutionLayers",
      "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection",
      "path": "/promptoverrides/getResolutionLayers",
      "method": "POST"
    },
    {
      "kind": "cli",
      "name": "promptoverridecollection_getAppOverride",
      "operation": "getAppOverride",
      "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection"
    },
    {
      "kind": "cli",
      "name": "promptoverridecollection_getTenantOverride",
      "operation": "getTenantOverride",
      "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection"
    },
    {
      "kind": "cli",
      "name": "promptoverridecollection_getResolutionLayers",
      "operation": "getResolutionLayers",
      "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection"
    },
    {
      "kind": "mcp",
      "name": "promptoverridecollection_getappoverride",
      "operation": "getAppOverride",
      "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection"
    },
    {
      "kind": "mcp",
      "name": "promptoverridecollection_gettenantoverride",
      "operation": "getTenantOverride",
      "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection"
    },
    {
      "kind": "mcp",
      "name": "promptoverridecollection_getresolutionlayers",
      "operation": "getResolutionLayers",
      "objectName": "@happyvertical/smrt-prompts:PromptOverrideCollection"
    }
  ],
  "prompts": [
    {
      "filePath": "src/index.ts"
    },
    {
      "filePath": "src/prompt-registry.ts"
    },
    {
      "filePath": "src/prompt-resolver.test.ts"
    }
  ],
  "relationshipsV2": {
    "foreignKeyFields": 0,
    "crossPackageRefFields": 0,
    "junctionCollections": 0,
    "hierarchicalObjects": 0,
    "polymorphicAssociations": 0,
    "uuidColumns": 2
  },
  "agentDoc": "# smrt-prompts\n\nSMRT prompt registry and tenant-aware prompt override package. Code defines defaults; config layers and DB-stored overrides personalize at app and tenant levels.\n\n## Core pieces\n\n- `definePrompt()` registers code defaults in a global process registry (`globalThis.__smrtPromptRegistry`)\n- `resolvePrompt()` merges code defaults, file/config overrides (via `@happyvertical/smrt-config`), stored app-level overrides, stored tenant-level overrides, and a runtime override\n- `PromptOverride` (`_smrt_prompt_overrides` table) stores partial app-level and tenant-level overrides with write-time validation\n- `PromptOverrideCollection` exposes the standard SmrtCollection CRUD surface\n\n## Resolution layers (priority low → high)\n\n1. Code default — registered via `definePrompt({ key, template, ai })`\n2. File/config override — `getPackageConfig<PromptPackageConfig>('prompts', defaults)`\n3. App-level stored override — `PromptOverride` row with `tenantId = null`\n4. Tenant-level stored override — `PromptOverride` row with current tenant\n5. Runtime override — passed to `resolvePrompt({ overrides })`\n\nEach layer can override any subset of fields (template, profile, model, params). Inheritance is field-by-field.\n\n## Conventions\n\n- **Namespace prompt keys** by package or domain: `projects.issue.incorporateFeedback`, `content.summarize.headline`\n- **Stored overrides use nullable fields** so inheritance stays field-by-field — null means \"use the lower layer\"\n- **Provider selection is indirect** in v1: prompts select named profiles, and profiles resolve to provider/model in `smrt-config`\n- **`editable` flags are enforced on `PromptOverride.save()`** — definitions can lock specific fields against tenant override\n\n## Caching\n\n`resolvePrompt()` results are cached per `(key, tenantId)` with a TTL. The cache is invalidated on `PromptOverride.save()` and `.delete()`. Use `clearPromptCache()` for manual invalidation in tests.\n\n**A monotonic per-`(db, key)` invalidation generation guards the cache write.**\nA resolution captures `getPromptCacheGeneration(key, db)` before its\nasynchronous layer loads and hands it back to `setCachedPromptBase()`; a\nconcurrent `save()` / `delete()` bumps the generation and the in-flight\nresolution is then refused the cache write instead of repopulating the key it\njust invalidated with the pre-write value. Without it, \"a stale entry is never\nserved after a write\" held only until a read raced a write, and then failed for\nthe full 30s TTL (a raced `delete()` resurrected the deleted override).\nGenerations are tracked per `(db, key)`, not per tenant, because an app-level\nrow is inherited by every tenant. `clearPromptCache()` raises a single floor\n(`clearedThrough`) rather than resetting or per-key bumping: a key that has\nnever been invalidated has no map entry and reads as generation 0, so a per-key\nbump cannot reach it and a resolution that started before the clear would write\nits pre-clear value back. `smrt-languages` carries the same mechanism, keyed\nadditionally by locale. `smrt-playbooks` has the generation but not the floor\n(#2716).\n\n## Related\n\n- `@happyvertical/smrt-languages` — parallel package for language strings (uses the same architecture pattern)\n- `@happyvertical/smrt-features` — parallel package for feature flags\n"
}