Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/CodySwannGT/expostarter --skill lisa-notion-write-prd명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | lisa-notion-write-prd |
| description | Creates or idempotently updates… |
| allowed-tools | ["Skill","Bash"] |
Create (or update) a PRD page in the configured Notion PRD database. Invoked by
lisa-prd-source-write when source = notion; do not call directly from a vendor-neutral caller.
All Notion operations go through lisa-notion-access (the access chokepoint) — never curl the
Notion API or call a mcp__*notion* tool yourself.
$ARGUMENTS carries the lisa-prd-source-write spec: title, body (full PRD markdown),
initial_role (draft | ready, default draft), dedupe_key, marker, optional source_ref.
read_g() { local lv gv; lv=$(jq -r "$1 // empty" .lisa.config.local.json 2>/dev/null); gv=$(jq -r "$1 // empty" .lisa.config.json 2>/dev/null); echo "${lv:-${gv:-$2}}"; }
PRD_DB=$(read_g '.notion.prdDatabaseId' '')
[ -z "$PRD_DB" ] && { echo "Error: notion.prdDatabaseId not set in .lisa.config.json."; exit 1; }
STATUS_PROP=$(read_g '.notion.statusProperty' 'Status')
# Resolve the FULL PRD Status vocabulary from config (never hard-code) so the past-ready check is
# correct even when a project renamed any Status value.
DRAFT=$(read_g '.notion.values.draft' 'Draft')
READY=$(read_g '.notion.values.ready' 'Ready')
IN_REVIEW=$(read_g '.notion.values.in_review' 'In Review')
BLOCKED=$(read_g '.notion.values.blocked' 'Blocked')
TICKETED=$(read_g '.notion.values.ticketed' 'Ticketed')
SHIPPED=$(read_g '.notion.values.shipped' 'Shipped')
VERIFIED=$(read_g '.notion.values.verified' 'Verified')
# "Progressed past ready" set (never down-rank): the resolved in_review/blocked/ticketed/shipped/verified.
PROGRESSED=("$IN_REVIEW" "$BLOCKED" "$TICKETED" "$SHIPPED" "$VERIFIED")
Resolve the target Status value from initial_role: ready → $READY, otherwise $DRAFT.
The marker is embedded in the page (as the first body block). Find an existing PRD page in the DB
carrying it — match the marker, never the title:
lisa-notion-access operation: search query: "<marker>" (Notion indexes page content).$PRD_DB. If source_ref was passed, target that page
directly and skip the search.Markdown → Notion blocks (conversion boundary). Convert the PRD markdown to Notion block objects:
#/##/### → heading_1/2/3, paragraphs → paragraph, -/* → bulleted_list_item, 1. →
numbered_list_item, fenced code → code. The Notion API caps a single request at 100 blocks
and ~2000 characters of rich text per block: split long paragraphs across blocks, and if the PRD
exceeds 100 blocks, create the page with the first ≤100 blocks then add the remainder with batched
operation: append-blocks calls (≤100 each). When the MCP substrate is active, create-page may
accept the markdown content directly (it performs this conversion) — prefer that; the explicit block
conversion is the curl-substrate path.
Marker + usage-ledger preservation (both paths). The page must always carry exactly one
marker. On CREATE the marker is the first body block; on UPDATE never remove it. Never write a markerless body. Never write a markerless page. If the existing page content already contains the canonical managed ## Lisa Usage section, preserve that section when regenerating the page body unless the caller intentionally supplied an updated canonical section; use the shared lisa-usage-accounting serializer/merge path rather than freehand block edits to ledger rows.
CREATE:
<!-- $MARKER -->), then the converted PRD blocks.lisa-notion-access operation: create-page with:
{ "parent_database_id": "<PRD_DB>",
"properties": { "<title-prop>": { "title": [{ "text": { "content": "<TITLE>" } }] },
"<STATUS_PROP>": { "status": { "name": "<ROLE_VALUE>" } } },
"children": [ <marker block>, <PRD body blocks> ] }
Use the DB's actual title property name (read it via operation: read-database id: <PRD_DB> if
unknown) and the correct property type for $STATUS_PROP (status vs ).UPDATE (existing page or source_ref):
lisa-notion-access operation: write-page payload: { "id": "<page-id>", "properties": { "<STATUS_PROP>": { "status": { "name": "<ROLE_VALUE>" } } } } — unless the page's current Status is in the resolved ${PROGRESSED[@]} set (already past ready), in which case leave the Status and report reused (already past ready).operation: archive-page is page-level, so for blocks delete via the blocks API through
notion-access or, where block deletion isn't available, replace their text in place) and
operation: append-blocks the regenerated blocks. Do not duplicate the whole spec as a dated
note, and never drop the marker or an existing managed ## Lisa Usage section.ref: "<notion-page-id>"
url: "<page url>"
role: draft | ready # (or the page's current Status role when reused past ready)
marker: "<MARKER>"
outcome: created | reused
lisa-notion-access; never touch the Notion API/MCP directly.## Lisa Usage section on update; never append a second usage
section or silently drop ledger rows.ready.notion.statusProperty, notion.values.*) — never
hardcode value names.select