Files
Claude c46ce8dba7 feat(templates): save the Assembler's negative template
Migration 019 adds an optional `negative_template` column to `templates`
(row-level, no schema bump). NULL marks a template saved before
negatives existed. The repository, importer (add, replace with
COALESCE, undo), templates API and TS types carry it, and the manager's
template editor gets a Negative template field.
2026-09-30 09:22:47 +00:00

33 lines
1.3 KiB
Python

"""Migration 019 -- negative_template column on saved prompt templates.
Send-to-negative gives the PromptAssembler a second box, the negative
template (``$vars`` plus the reserved ``$negatives`` slot). A saved
template stores both boxes, so ``templates`` gains ``negative_template``
(TEXT, nullable, no default).
NULL is meaningful: a template saved before this migration has no
negative, and loading it leaves the Assembler's negative box as it was
instead of blanking it. A template saved afterwards stores a string,
even an empty one, so loading it sets the box.
Row-level column, not a payload shape: no ``schema_version`` bump.
Idempotent: the ALTER is gated on ``PRAGMA table_info``. The migration
runner's version table is the primary re-run guard; the column check
exists for test fixtures that rewind ``migrations``.
"""
from __future__ import annotations
import sqlite3
def _has_column(conn: sqlite3.Connection, table: str, column: str) -> bool:
cur = conn.execute(f"PRAGMA table_info({table});")
return any(row[1] == column for row in cur.fetchall())
def up(conn: sqlite3.Connection) -> None:
with conn:
if not _has_column(conn, "templates", "negative_template"):
conn.execute("ALTER TABLE templates ADD COLUMN negative_template TEXT;")