plugins/lisa-copilot/skills/prd-source-write/SKILL.md
Vendor-neutral wrapper for creating (or idempotently updating) a PRD in the configured PRD source. The PRD-side sibling of lisa:tracker-write. Resolves `source` from .lisa.config.local.json first (then .lisa.config.json — local overrides global) and dispatches to lisa:notion-write-prd, lisa:confluence-write-prd, lisa:github-write-prd, or lisa:linear-write-prd. Callers (notably lisa:research) MUST invoke this skill instead of a vendor PRD writer directly — that is what makes the PRD source switchable per project. Accepts an `initial_role` of `draft` (default) or `ready` so a freshly created PRD either waits for human promotion or is immediately picked up by lisa:intake; and a stable dedupe marker so re-runs reference the existing PRD instead of creating a duplicate. The PRD lives in the source — there is no separate document artifact.
npx skillsauth add codyswanngt/lisa prd-source-writeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Thin dispatcher. Resolves the configured PRD source and delegates to the matching vendor PRD
writer, which owns the concrete create/update, the lifecycle-role application, and the marker-based
dedupe. When the supplied PRD body already contains the canonical ## Lisa Usage ledger, the
vendor writer must preserve that managed section on update instead of dropping it or reformatting it
ad hoc. This skill only routes — it never talks to a source API itself.
See the config-resolution rule for the full configuration schema and the PRD lifecycle roles.
Callers pass a single structured spec:
operation: create_or_update # the only operation; create unless the marker already exists
title: "<PRD title>"
body: "<full PRD markdown — the entire spec>"
initial_role: draft | ready # default: draft. ready = picked up by lisa:intake's PRD scan
dedupe_key: "<stable-key>" # e.g. project-ideation's idea key
marker: "[lisa-project-ideation] idea=<stable-key>" # embedded in the PRD body for dedupe
origin: { tool: project-ideation | research | manual }
source_ref: "<optional existing PRD ref to force an update>"
ideation_ledger_payload: # optional; forwarded unchanged to the vendor writer
selected_marker: "<same value as marker>"
automation_id: "<Codex/Claude automation id or unavailable>"
automation_memory_path: "<path or unavailable>"
repo: "<org>/<repo or detected repo identity>"
prd_ready: true|false
persona_names: ["<derived persona name>"]
persona_evidence_refs: ["<file/doc/table/release ref>"]
selected_idea: "<selected idea title/key>"
rejected_overlap_candidates: ["<issue refs/titles considered and rejected>"]
expected_empirical_verification_artifact: "<artifact ref or unavailable>"
initial_role semantics are uniform across vendors (the role STRINGS resolve per vendor from
config-resolution):
draft (default) → the PRD is created in the source's draft PRD role. It waits for a human
(or a later ready promotion) before any intake claims it.ready → the PRD is created in the source's ready PRD role (prd-ready), so the PRD-side of
lisa:intake / the *-prd-intake scanner auto-claims it on the next cycle.There is no "omitted = legacy behavior" mode (unlike the ticket-side build_ready): there was no
prior PRD-source-write behavior to preserve, so omitted means draft.
Resolve the source. Read .lisa.config.local.json first (if present), then
.lisa.config.json. Local overrides global per key. Use jq — never hand-parse JSON.
local_source=$(jq -r '.source // empty' .lisa.config.local.json 2>/dev/null)
global_source=$(jq -r '.source // empty' .lisa.config.json 2>/dev/null)
source="${local_source:-${global_source}}"
if [ -z "$source" ]; then
echo "Error: 'source' is not set in .lisa.config.json. A PRD source (notion / confluence / github / linear) is required to create a PRD. Run /lisa:setup:notion (or :confluence, :github, :linear)." >&2
exit 1
fi
Validate the value and dispatch (pass the spec verbatim):
notion → confirm notion.workspaceId and notion.prdDatabaseId are present, then invoke
lisa:notion-write-prd.confluence → confirm atlassian.cloudId and (confluence.spaceKey or
confluence.parents.draft/.ready) are present, then invoke lisa:confluence-write-prd.github → confirm github.org and github.repo are present, then invoke
lisa:github-write-prd.linear → confirm linear.workspace (and team for project placement) is present, then invoke
lisa:linear-write-prd.jira → stop and fail loudly: "source=jira is not a supported PRD source — config-resolution defines no JIRA PRD lifecycle roles. Use notion / confluence / github / linear, or set source accordingly." (JIRA is a destination tracker, not a PRD source.)file) → stop and report: "Unknown PRD source '<value>'. Expected one of: notion, confluence, github, linear."Surface the vendor writer's output unchanged. It returns the created/reused PRD ref + URL,
the applied role (draft/ready), the dedupe marker, and whether it was created or reused.
Downstream callers (research, project-ideation) parse this — do not paraphrase.
When ideation_ledger_payload is present, this shim still does not render or interpret it. Forward
the object verbatim to the selected vendor writer so source-specific rendering remains behind the
configured writer and the dispatch layer never bypasses source selection.
*-write-prd skill directly defeats the
per-project source switch (exactly the tracker-write discipline, mirrored).## Lisa Usage section. Writer-specific preservation
and fallback behavior belongs in the vendor writers and follows the usage-accounting contract.{notion, confluence, github, linear}. jira and file fail loudly.ideation_ledger_payload; it is a pass-through payload for
the configured writer.config-resolution per vendor.development
Use Expo DOM components to run web code in a webview on native and as-is on web. Migrate web code to native incrementally.
development
Guidelines for upgrading Expo SDK versions and fixing dependency issues
development
Use when implementing or debugging ANY network request, API call, or data fetching. Covers fetch API, React Query, SWR, error handling, caching, offline support, and Expo Router data loaders (`useLoaderData`).
tools
`@expo/ui/swift-ui` package lets you use SwiftUI Views and modifiers in your app.