Skip to content

Navigation Menu

Sign in
Sign up

feat(prompts): let users save their own prompts to the library - #2056

Draft
manzke wants to merge 1 commit into
main from
claude/charming-fermat-t678ey
Draft

feat(prompts): let users save their own prompts to the library #2056
manzke wants to merge 1 commit into
main from
claude/charming-fermat-t678ey

Conversation

@manzke

@manzke manzke commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #1037 ("Support to save a prompt to the prompt library"). Also covers the data-model half of
#1038 (owner, visibility, createdBy/lastModifiedBy tracking) — see scoping note below.

Today contents/prompts/*.json is exclusively an admin-curated resource. This adds a parallel,
user-owned layer: any authenticated (non-anonymous) user can save their own prompt directly from
the Prompts page, mark it private (only them) or shared (every authenticated user), and
edit/delete their own prompts later.

Backend

  • New server/utils/userPromptsStore.js — one JSON file per prompt under
    contents/data/user-prompts/<userId>/<promptId>.json, separate from the admin-curated library
    and not subject to contentAdminAuth. userId (an OIDC subject/local username/LDAP username/proxy
    header value) is treated as untrusted input — validated against the same safe-filename allowlist
    TokenStorageService.js already uses for its per-user token files, then re-checked to stay inside
    its parent directory before any fs call (mirrors that module's existing path-safety pattern).
  • New server/validators/userPromptInputSchema.js — a small Zod schema for the create/update
    payload (name/description/prompt/category/visibility). Deliberately simpler than
    promptConfigSchema.js: no localization, variables, or output schema for v1.
  • New server/routes/userPromptsRoutes.jsGET/POST/PUT/DELETE /api/user-prompts, gated behind
    authenticatedOnly (rejects anonymous sessions) and the existing promptsLibrary feature flag
    (already default-on, so no migration needed). GET returns the caller's own prompts plus every
    other user's shared prompts, each tagged mine: true|false. Ownership on update/delete is
    enforced by construction — the store only ever reads/writes inside the caller's own directory, so
    a promptId belonging to someone else's directory simply 404s.
  • New server/tests/userPromptsStore.test.js — Jest tests covering create/list/update/delete,
    private-vs-shared visibility, and rejection of path-traversal-shaped userId/promptId values.

Frontend

  • New client/src/features/prompts/components/UserPromptFormModal.jsx — create/edit form
    (name/description/prompt/visibility).
  • client/src/features/prompts/pages/PromptsList.jsx — new "Save a new prompt" button (hidden for
    anonymous sessions), own/shared user prompts merged into the existing grid with "Mine"/"Shared"
    badges, and edit/delete controls on the user's own prompt cards.
  • client/src/api/endpoints/prompts.jsfetchUserPrompts/createUserPrompt/updateUserPrompt/
    deleteUserPrompt.
  • New en/de translation strings under pages.promptsList.userPrompts.* and common.saving.

Scoping notes (see docs/prompts.md for the full write-up)

  • User prompts are plain strings (no localization/variables/outputSchema) — intentionally
    simpler than admin-curated prompts for v1.
  • No admin moderation queue for shared prompts in this PR (an open question raised on Support to save a prompt to the prompt library #1037 's
    implementation-plan comment) — flagging as a candidate follow-up, not blocking this slice.
  • Anonymous sessions never see the save button and the API rejects them with 401, consistent with
    authenticatedOnly elsewhere in the codebase.

Test plan

  • New unit tests (server/tests/userPromptsStore.test.js) — 8/8 passing, including
    path-traversal rejection for both userId and promptId.
  • npx eslint on all changed/new files — 0 errors (only pre-existing warnings elsewhere in
    PromptsList.jsx that predate this change).
  • npx prettier --check — clean.
  • Production client build (vite build) succeeds with no errors.
  • Server boots cleanly with the new route registered (node server/server.js, all 4 cluster
    workers ready, migrations unaffected).
  • Manually exercised the full CRUD lifecycle against a running dev server (logged in as the
    local admin per CLAUDE.md): create private → list → update to shared → delete → list empty
    again. Also verified: anonymous GET /api/user-prompts → 401; a path-traversal-shaped
    promptId on DELETE → 400; a request missing name/prompt → 400.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KGoQpnovDaVSVSGA9fsiyX


Generated by Claude Code

Adds user-owned prompts alongside the admin-curated library: any
authenticated (non-anonymous) user can save a prompt as private or
shared, edit/delete their own, and see others' shared prompts.
- New GET/POST/PUT/DELETE /api/user-prompts, storing one JSON file per
 prompt under contents/data/user-prompts/<userId>/<promptId>.json,
 gated behind the existing promptsLibrary feature flag.
- New "Save a new prompt" button + modal on the Prompts page; own/shared
 prompts merge into the existing grid with Mine/Shared badges and
 edit/delete for owned prompts.
- Covers the data-model half of #1038 (owner, visibility, createdBy/
 lastModifiedBy tracking).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KGoQpnovDaVSVSGA9fsiyX 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

api backend documentation Improvements or additions to documentation frontend i18n testing

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Support to save a prompt to the prompt library

2 participants

AltStyle によって変換されたページ (->オリジナル) /