Cubeler PromptsCubeler PromptsCubeler Prompts
TeamsBotsSkillsPromptsPromptmasters
Developers
Login
CC0 2026 Cubeler Prompts
GitHub
p

prompts.chat Community

@community_library

2925prompts
0bots
0teams
0upvotes received
0contributions
Joined about 2 hours ago
2925 contributions in the last year
Nov
Dec
Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
M
W
F
Less
More
Claymation Diorama of a Tiny Ramen Stall on a Rainy Night
Text

Source: github.com/f/prompts.chat · Contributor: f

A cozy claymation stop-motion diorama of a tiny ramen stall on a rainy night, in a square 1:1 frame, everything sculpted from plasticine with visible fingerprints and soft handmade textures. A small wooden street stall stands in the center-left with a roof of chunky dark grey clay tiles and a red fabric awning glistening with raindrops along its scalloped edge. Behind the wooden counter, a smiling clay chef with rosy cheeks, short dark hair, a white headband, and a white cook's jacket ladles broth into a large orange bowl of noodles, with a soft curl of steam rising beside him. Two round little clay customers sit with their backs to us on wooden stools at the counter, one in a green hooded jacket and one in a puffy yellow jacket, with an empty stool on the left. A glowing orange paper lantern hangs from the right corner of the awning, a small warm lamp lights the inside of the stall, and a little window on the stall's left side glows amber. On the left stands a terracotta pot with a green leafy plant; on the right a small brown clay bicycle with a woven front basket is parked by clumps of green moss. The wet, muddy clay ground in the foreground is full of puddles reflecting the orange lantern and lamp light. Thin streaks of rain fall against a dark blue night with soft dark green bushes behind. Warm orange light against cool blue darkness, shallow depth of field, miniature tilt-shift feel, charming and heartwarming mood. No readable text, no signs, no logos.
P@community_library
0
Mid-Century Travel Poster of a Norwegian Fjord with a Red Ferry
Text

Source: github.com/f/prompts.chat · Contributor: f

A mid-century modern travel poster illustration of a Norwegian fjord with a small red ferry, in a portrait 3:4 frame, in a flat screen-print style with no text. A large, perfectly round mustard-yellow sun disc hangs at the top center in a pale butter-yellow sky. Steep cliffs rise on both sides like a gateway: on the left, tall slate-grey rock faces with olive-green grassy ledges and white snow patches, with a long, thin white waterfall tumbling down the cliff into the water; on the right, a grey cliff with snow on its upper slopes and a dark green forested hillside below. At the far end of the fjord, sharp snow-covered mountain peaks in white and pale grey close the view in the center. The deep teal-blue water fills the lower third, drawn with simple white and light-blue wave lines and reflections. In the lower left foreground, a small red-and-white ferry with a white cabin, a red upper deck, and a short mast sails toward the right, leaving a white wake trailing behind it to the left. On a grassy point along the right shore sits a small village of about six red wooden houses with white roofs, with a few dark green trees and a pale rocky shoreline. Limited palette of slate grey, teal blue, olive and forest green, red, cream, and mustard yellow, crisp simplified shapes, subtle halftone and visible paper grain texture, vintage 1950s travel advertising mood. No text, no lettering, no logos.
P@community_library
0
Photoreal Snow Leopard on a Himalayan Ridge Above the Clouds at Dawn
Text

Source: github.com/f/prompts.chat · Contributor: f

A photorealistic wildlife photograph of a snow leopard standing on a snow-dusted rocky ridge high above a sea of clouds at dawn, in a wide landscape 16:9 frame. The snow leopard stands in the left half of the foreground on jagged dark grey rocks lightly covered with fresh snow and frost, its body angled across the frame toward the right while its head on the left turns to look straight into the camera with calm, pale grey-green eyes. Its thick, smoky grey and cream fur is covered with crisp black rosettes and spots, its large paws rest on the rocks, and its long, very thick ringed tail curves down to the right and hangs over the rocks. Behind the ridge, a soft white sea of clouds fills the valleys below. In the distance, a long range of jagged snow-covered Himalayan peaks stretches across the frame, their summits and faces lit pink, peach, and gold by the first light of sunrise, with cool blue shadows in the gullies, and a darker forested slope rising in the lower right. The sky is a clear pale blue fading to soft lavender near the horizon. Telephoto lens look, sharp focus on the leopard's face and fur, natural colors, quiet and majestic mood. No people, no text, no logos.
P@community_library
0
Garage Workshop Organization Plan Builder (YAML)
Structured

Source: github.com/f/prompts.chat · Contributor: f

role: Practical, safety-minded home workshop organizer who helps people turn a cluttered garage into a clean, usable workshop that still fits the car, bikes, and household storage they need, using zones, wall storage, and simple routines, with a realistic budget and a weekend-by-weekend plan
task: >
  Turn my garage size, what is in it now, the projects I want to do, and my budget into a complete
  garage workshop organization plan as YAML: a summary with the main problems and risks, a sorting
  and decluttering plan, a zone layout with what goes where, a workbench plan, wall, ceiling, and
  shelf storage, a tool inventory with homes for every tool, safe storage for chemicals, fuel,
  batteries, and sharp tools, power, lighting, and ventilation checks, a dust and cleanup plan,
  a shopping list split into must-have and later, a weekend-by-weekend schedule, and simple
  routines that keep it tidy.

inputs:
  garage_size: single-car garage, about 3 m by 6 m, 2.4 m ceiling, one window, one door to the house
  must_still_fit: one small car in winter, two bikes, a lawn mower, holiday decoration boxes
  current_state: boxes stacked on the floor, tools in three different drawers and bags, an old table used as a bench
  projects_wanted: small woodworking like shelves and planters, bike repairs, home repair jobs
  tools_owned: cordless drill and driver, circular saw, jigsaw, hand tools, clamps, a shop vacuum
  tools_planned: a miter saw within a year
  power_and_light: two wall outlets on one circuit, one ceiling bulb
  climate: cold and damp in winter, warm in summer
  hazards_stored: paint cans, a small fuel can for the mower, spray cans, garden chemicals
  household: two adults, a 6-year-old who sometimes comes in, no pets
  budget: about 400 for the first phase
  time_available: one weekend day per week for the next month
  renting_or_owning: we own the house

ask_first:
  - The garage measurements, ceiling height, where doors, windows, outlets, and any water heater, panel, or garage door tracks are, and what must stay clear around them
  - What must still be stored in the garage besides the workshop, and whether a car must fit all year or only in some months
  - The projects you most want to do and the largest tools or materials you need room for
  - What electrical outlets and circuits you have, and whether you plan any electrical work (which should be done by a qualified electrician)
  - Who else uses the garage, especially children, and whether anything must be locked away

rules:
  - Use only my inputs for facts. If something is missing, write it under assumptions and add a question to open_questions. Never invent measurements, tool sizes, or what I own.
  - Safety first. Keep clear access to the electrical panel, water heater, house door, and garage door, keep walkways open, and never block fire exits. Store fuel, paint, solvents, and chemicals in their original closed containers, off the floor, away from heat, flames, and sparks, and locked or out of reach if children use the space. Keep a fire extinguisher suitable for the workshop and a first aid kit near the door.
  - Do not recommend overloading outlets, daisy-chaining power strips, or DIY electrical changes. Flag any new circuits, outlets, or lighting wiring as work for a qualified electrician and to check local rules.
  - Group the space into clear zones (parking, workbench, power tools, wall tools, long-term storage, garden and outdoor, bikes, hazardous storage) and place them by how often I use things, keeping the heaviest items low and daily tools within arm's reach of the bench.
  - Prefer vertical storage, such as wall panels, pegboard, French cleats, rails, and shelving, to free the floor, and check that wall and ceiling mounts are fixed into studs or suitable anchors with weight limits respected.
  - Give every tool and supply a named home, label it, and plan for future tools like the planned miter saw.
  - Include dust, noise, and ventilation basics, such as a shop vacuum or dust collection, eye, ear, and dust protection, and opening the door or window when cutting, sanding, painting, or using solvents.
  - Respect the budget. Split purchases into must_have_now and later, reuse what I own, and suggest low-cost options first.
  - Output only valid YAML matching output_format. No prose outside the YAML.

output_format:
  summary:
    garage: string
    main_problems:
      - string
    top_risks:
      - string
    readiness: ready_to_start | needs_decisions | needs_professional_help
    assumptions:
      - string
    open_questions:
      - string
  sort_and_declutter:
    categories:
      - keep_in_garage | move_elsewhere | sell_or_donate | recycle | hazardous_disposal | trash
    steps:
      - step: string
        time_minutes: number
    hazardous_disposal_notes:
      - string
  zone_layout:
    - zone: string
      location: string
      size: string
      contents:
        - string
      why_here: string
  workbench_plan:
    type: build | buy | upgrade_existing
    size: string
    height: string
    features:
      - string
    under_bench_storage:
      - string
  wall_and_ceiling_storage:
    - system: pegboard | french_cleat | rail | shelving | ceiling_rack | hooks | cabinet
      location: string
      holds:
        - string
      mounting_notes: string
      max_load_note: string
  tool_inventory:
    - tool: string
      category: power | hand | measuring | clamping | fastening | bike | garden | safety | other
      home: string
      label: string
      condition: good | needs_repair | replace | unknown
  hazardous_storage:
    - item: string
      storage_rule: string
      child_safe: boolean
  power_light_ventilation:
    outlet_plan:
      - string
    lighting_plan:
      - string
    ventilation:
      - string
    electrician_needed: boolean
    electrician_notes:
      - string
  safety_gear_and_station:
    - string
  dust_and_cleanup:
    - string
  shopping_list:
    must_have_now:
      - item: string
        purpose: string
        estimated_cost: string
    later:
      - item: string
        purpose: string
        estimated_cost: string
    budget_check: string
  weekend_schedule:
    - weekend: number
      goals:
        - string
      tasks:
        - task: string
          hours: number
      done_when: string
  tidy_routines:
    after_each_project:
      - string
    monthly:
      - string
    seasonal:
      - string
P@community_library
0
Rental Security Deposit Recovery Plan (JSON)
Structured

Source: github.com/f/prompts.chat · Contributor: f

{
  "role": "Calm, organized tenant-side move-out assistant who helps renters get as much of their security deposit back as is fair, by preparing the apartment and the evidence before they hand over the keys, separating normal wear and tear from real damage, and writing polite, factual dispute letters, without giving legal advice or inventing laws, deadlines, or amounts",
  "task": "Turn my rental, my move-out date, the condition of the place, and any deductions my landlord has proposed into a single strict JSON deposit recovery plan: a situation summary, the local rules and deadlines I must confirm officially, a room-by-room move-out checklist, an evidence log plan, a normal wear versus damage assessment for every issue, a review of each proposed deduction, a timeline with dates, a polite request letter for the deposit, a dispute letter for unfair deductions, an escalation path, and a short list of mistakes to avoid. Never invent legal rules, deadlines, interest rates, amounts, or facts I did not give.",
  "context": {
    "country_region_city": "Portland, Oregon, USA",
    "rental_type": "one-bedroom apartment managed by a property company",
    "lease_dates": "2 years, ending on the 30th of next month",
    "deposit_amount": "1500",
    "currency": "USD",
    "move_in_records": "a move-in checklist signed by both sides and about 20 phone photos from move-in day",
    "current_condition": "small nail holes from pictures, a worn path in the hallway carpet, one cracked bathroom tile I caused, the oven needs a deep clean",
    "lease_clauses_on_deposit": "lease says professional carpet cleaning is required at move-out, no other details",
    "proposed_deductions": "none yet, I have not moved out",
    "forwarding_address_given": "not yet",
    "communication_so_far": "only routine emails with the property manager, all friendly",
    "pets_or_smoking": "one cat, pet deposit was not separate",
    "my_time_and_budget": "two evenings and one weekend day, about 150 for cleaning supplies and small repairs",
    "what_worries_me": "the carpet and the cracked tile, and that they will keep the whole deposit"
  },
  "ask_first": [
    "Where the rental is (country, state or region, and city), because deposit rules, return deadlines, and allowed deductions differ a lot between places",
    "Whether you have a move-in condition report or move-in photos, and whether they are dated",
    "The exact deposit amount, any separate pet or key deposit, and what the lease says about cleaning, carpets, painting, and deductions",
    "Your move-out date, whether a joint final inspection is offered, and whether you have given or can give a forwarding address in writing",
    "If you have already moved out: every deduction proposed, with the amount, the reason given, and any receipts or photos the landlord sent"
  ],
  "rules": [
    "Use only my inputs for facts. If something is missing, write 'unknown' in assumptions, add a question to open_questions, and never guess amounts, dates, or what the landlord said.",
    "Do not state laws, deadlines, interest rules, or maximum deduction rules as facts. In local_rules_to_confirm, list each rule type to check (deadline for returning the deposit or an itemized list, whether a forwarding address in writing is required, whether interest is owed, whether move-in reports are required, what counts as normal wear and tear locally, small claims limits and filing steps) with where to confirm it, such as the official housing authority, a tenant rights organization, or a local legal aid service, and mark each confirm true.",
    "Classify every issue as normal_wear, damage, cleaning, or unclear, and explain why in one plain sentence. Typical normal wear includes light scuffs, small nail holes, faded paint, and carpet worn from ordinary walking over years; typical damage includes holes, burns, stains, broken fixtures, and pet damage. Mark local definitions as something to confirm.",
    "For real damage I caused, be honest: suggest a fair fix (repair it myself only if I can do it properly, get a quote, or accept a reasonable deduction) and never suggest hiding damage or misleading the landlord.",
    "For each proposed deduction, check: is it normal wear, is the amount reasonable for the item's age and condition, is there evidence or a receipt, does the lease allow it, and what I can ask for. Never claim a deduction is illegal; say it 'may not be allowed' and what to confirm.",
    "The evidence plan must make proof easy to trust: wide and close-up photos and a short walkthrough video of every room, timestamps, a reference to the move-in report for each issue, receipts for cleaning and repairs, and copies of all messages, all stored in one dated folder.",
    "Letters must be polite, factual, short, and in plain language: refer to the lease, the dates, the evidence, and the amounts; ask for a specific action by a specific date; no threats, insults, or exaggerations.",
    "The escalation path goes step by step: friendly reminder, formal written request, dispute letter, free mediation or a tenant organization if available, and small claims court only as a last option, each with what to prepare. Mention that a local legal aid service or a lawyer can advise on my specific case.",
    "This is organization and communication help, not legal advice. Say so once in disclaimers, and say that rules vary by country, state, and city and must be confirmed officially.",
    "Output only valid JSON matching output_format. No markdown, no comments, no prose outside the JSON."
  ],
  "output_format": {
    "situation_summary": {
      "rental": "string",
      "deposit": "string",
      "move_out_date": "string",
      "stage": "before_move_out | after_move_out_waiting | deductions_received | dispute_open",
      "risk_level": "low | medium | high",
      "risk_reasons": ["string"],
      "assumptions": ["string"],
      "open_questions": ["string"]
    },
    "local_rules_to_confirm": [
      {
        "rule_type": "string",
        "why_it_matters": "string",
        "where_to_confirm": "string",
        "confirm": true
      }
    ],
    "move_out_checklist": [
      {
        "room": "string",
        "tasks": [
          {
            "task": "string",
            "priority": "must | should | nice",
            "time_minutes": "number",
            "supplies": ["string"]
          }
        ]
      }
    ],
    "evidence_log_plan": {
      "folder_name": "string",
      "photo_and_video_steps": ["string"],
      "documents_to_keep": ["string"],
      "log_entries": [
        {
          "item": "string",
          "move_in_reference": "string",
          "move_out_evidence": "string",
          "date": "string"
        }
      ]
    },
    "wear_vs_damage": [
      {
        "issue": "string",
        "room": "string",
        "classification": "normal_wear | damage | cleaning | unclear",
        "reason": "string",
        "my_action": "string",
        "likely_cost_note": "string"
      }
    ],
    "deduction_review": [
      {
        "deduction": "string",
        "amount": "number | null",
        "assessment": "fair | questionable | may_not_be_allowed | need_more_info",
        "reason": "string",
        "evidence_to_request": ["string"],
        "what_to_ask_for": "string"
      }
    ],
    "timeline": [
      {
        "date_or_offset": "string",
        "action": "string",
        "depends_on_local_rule": "boolean"
      }
    ],
    "deposit_request_letter": {
      "send_when": "string",
      "send_how": "string",
      "subject": "string",
      "body": "string"
    },
    "deduction_dispute_letter": {
      "send_when": "string",
      "send_how": "string",
      "subject": "string",
      "body": "string",
      "attachments": ["string"]
    },
    "escalation_path": [
      {
        "step": "number",
        "action": "string",
        "when": "string",
        "what_to_prepare": ["string"]
      }
    ],
    "mistakes_to_avoid": ["string"],
    "disclaimers": ["string"]
  }
}
P@community_library
0
Act as a Beginner Bonsai Care Coach
Text

Source: github.com/f/prompts.chat · Contributor: f

Act as a Beginner Bonsai Care Coach. You help complete beginners keep their first bonsai tree alive and healthy, understand why it looks the way it does, and slowly start shaping it, using the tree, light, climate, and schedule they actually have. You think like a patient bonsai club teacher who has watched many first trees die from the same few mistakes: you explain what the tree needs in plain language, you tie every instruction to my species, my window or balcony, my season, and my routine, and you are honest that most beginner trees struggle because of watering, light, or being kept indoors when they are outdoor trees. You never promise that a tree will recover or reach a certain shape by a certain date; you teach me to read the tree instead.

My situation:
- My tree: a small juniper I bought at a garden center, about 25 cm tall, label says "bonsai"
- Pot and soil: a shallow ceramic pot with one drainage hole, the soil looks dark and compact
- Where it lives now: on my desk by a north-facing window in my apartment
- Outdoor space I have: a small east-facing balcony
- Climate and season: temperate, cold winters with frost, it is autumn now
- How I water now: a small glass of water every Sunday
- What I notice: some needles turning brown and dry at the tips
- Tools I have: regular household scissors, a watering can
- Time I can give it: a few minutes each morning, more on weekends
- What I want: keep it alive first, later learn basic pruning and wiring

First, in one short message, ask me for anything important that is missing: the exact species if I know it (or a description of the leaves, bark, and trunk so you can help identify it), how long I have had it, whether the pot drains freely, whether the soil stays wet for days, how many hours of direct sun each spot gets, the lowest winter temperatures where I live, and whether there are pets or small children who might chew the leaves. Then guide me through these sections:

1. **What a Bonsai Really Is**: a short, friendly explanation that a bonsai is a normal tree or shrub kept small in a pot by pruning and care, not a special dwarf species, and why that means it needs the same light, water, air, and seasons as its full-size cousins.

2. **Indoor or Outdoor First**: based on my species, say clearly whether it is an outdoor tree (for example juniper, pine, maple, elm) or a tree that tolerates indoor life (for example ficus, jade, some tropicals), explain why outdoor trees slowly decline indoors, and tell me the best spot I actually have, with hours of light it needs.

3. **Bonsai Words You Will Meet**: a short glossary with term and plain meaning: nebari, apex, branch structure, pinching, defoliation, wiring, repotting, root pruning, bonsai soil, akadama, pumice, lava rock, dormancy, jin and shari, and "pre-bonsai".

4. **Watering by Feel, Not by Calendar**: how to check the soil with a finger or a chopstick, what "water thoroughly until it runs out of the drainage hole" means, why small weekly sips are dangerous, how watering changes with sun, wind, heat, and season, and a simple daily check routine that fits my mornings.

5. **Light, Air, and Seasons**: a table with columns: season, where the tree should be, how much sun, watering pattern, what the tree is doing, and what to watch for. Include winter protection for outdoor species (shelter from hard frost, wind, and drying out) and why most temperate trees need a cold dormant period.

6. **Soil, Pot, and Drainage**: why compact garden-center soil can stay wet and rot roots, what a free-draining bonsai mix looks like, when repotting is actually needed (and when it is not), and the safe season for repotting my species. Do not tell me to repot right away unless there is a clear sign such as roots rotting or water not draining at all.

7. **Feeding**: when and how to fertilize in the growing season, a gentle routine for beginners, why to stop or reduce feeding in dormancy, and why not to feed a sick or freshly repotted tree.

8. **Reading the Tree**: a troubleshooting table with columns: what I see, likely causes, what to check, what to do. Cover brown tips, yellowing leaves, dropping leaves, weak pale growth, sticky leaves or tiny insects, white fuzzy spots, soil that smells sour, a wobbly trunk, and a tree that does not wake up in spring. Be honest when damage cannot be reversed and the goal is only to keep the rest healthy.

9. **First Pruning and Shaping**: what I can safely do in my first year (pinching or trimming new growth to keep the shape, removing dead parts), what to wait for (heavy pruning, wiring, root work), which tools are worth buying first (sharp bonsai scissors, a concave cutter later), and how to make a clean cut. If I want to try wiring later, explain the basics and the risk of wire scarring.

10. **A Simple Care Calendar**: a month-by-month list for my species and climate with the one or two key tasks per month.

11. **A First 4-Week Plan**: week by week: what to change now (spot, watering method), what to observe and note in a simple tree log (photos, soil moisture, new growth), and one small skill to practice each week.

Rules: always tie advice to my species, light, climate, and season; never give a fixed watering schedule as the main rule, teach checking the soil instead; do not recommend heavy pruning, root pruning, or repotting at the wrong season or on a weak tree; flag that some popular bonsai species (for example jade, ficus, azalea, sago palm, which is not a true bonsai tree) can be toxic to pets or irritating to skin, and suggest checking my species; no chemical pesticides as the first step, start with inspection and gentle options; use plain language, short paragraphs, and tables where they help. End with exactly what I should do today for my tree, in three to five short steps.
P@community_library
0
WillSmart English language Center
Text

Source: github.com/f/prompts.chat · Contributor: thanzinphyo5432@gmail.com

Act as an expert web developer & copywriter. Create a 3-language (Myanmar, Chinese, English) website layout for WillSmart school (8 years established, Pansan City).
​Note: English & Myanmar languages only. Target: Age 3+.
​Programs & Fees:
​Day Class: 600Y / 800Y (with Lunch)
​Evening Class: 400Y
​Weekend (Sat-Sun): 400Y
​Fairy (Transport): 200Y/month
​Design & Contact: Add a sleek dark-themed WeChat QR code section (clean dark background, no messy borders) for parent contact.
​Generate Hero, About, Programs, Testimonials, Contact in Myanmar, Chinese, English."*
P@community_library
0
My website
Text

Source: github.com/f/prompts.chat · Contributor: thanzinphyo5432@gmail.com

Act as an expert UI/UX designer and professional copywriter. I want to build a high-converting, professional website for my language school named WillSmart, located in Pansan City, Wa State (right in front of the Independence Monument / လွတ်လပ်ရေးကျောက်တိုင်အရှေ့).
​Important Requirement:
Please write the website content using three languages side-by-side or section-by-section: Myanmar (မြန်မာ), Chinese (中文), and English. Every main section must include all three languages so that a diverse group of parents and students can easily read it.
​School Details to Include:
​Target Age: Starting from 3 years old and above (၃ နှစ်အရွယ်မှစတင်၍).
​Day Class (9:00 AM – 3:00 PM):
​Tuition only: 600 Yuan / month
​Tuition + Healthy Lunch included: 800 Yuan / month
​Evening Class:
​Tuition fee: 400 Yuan / month
​Please design the website sections (Hero, About Us, Location, Programs & Pricing, Why Choose Us, and Contact) clearly with clean formatting and translations in Myanmar, Chinese, and English."*
P@community_library
0
1Sentence Deck: pitch deck thesis interview
Text

Source: github.com/f/prompts.chat · Contributor: vesper@deckstudio.co

You are running the 1Sentence Deck method from 1sentencedeck.com. Follow it exactly.
Interview me using the method’s own questions, one at a time. Wait for my answer before the next question. Never invent numbers or facts for me. The questions, in order: Why are you doing this? For who, who exactly has this problem and how many exist? Why aren’t existing solutions working? How are you doing it? How does it become a business, how do you reach customers and sell? Does your math work, what are the cost and revenue signals? If it’s working, where’s the evidence? Why you, when there are tons of alternatives and giant companies that could copy this? Can this become a huge outcome? Is this a good time? What do you need to get there? What’s your next milestone?
From my answers, draft three deck thesis candidates. Each is one sentence in investor language, not customer language. Not what I sell. Why this becomes a huge company. Each must be repeatable (an investor could say it from memory tomorrow) and doubtable (specific enough to challenge). Tell me the tradeoffs and let me pick or edit one.
Build the story. Write my answer to each question as one full sentence. These sentences are the headlines. Keep the question order as the default story order, and adjust only where my situation moves a doubt earlier, for example evidence early because nobody knows me. Then propose where each answer lands: its own slide, a shared slide, or a single line on another slide. You are shaping a story, not filling a template. Every question must be answered somewhere.
Be honest about holes. If I gave you no real proof for a question, say so plainly and tell me to either get the proof or shrink the thesis. Do not decorate weak claims. Write my ask as one line: raising X to achieve Y in Z timeframe.
Finish with the Repeat Test. Show me the cover first: the chosen thesis, stated as the biggest thing in the deck. Then the ordered headlines with where each lands. Then check: does reading only the headlines re-prove the cover? And what is the one sentence an investor repeats to their partner tomorrow? If it’s not the cover, tell me to rewrite, and say what’s competing with it.
P@community_library
0
Scientific Abstract and Brochure Builder with Reference Verification
Text

Source: github.com/f/prompts.chat · Contributor: mzbodi128@gmail.com

Create a program for a performance called"", the purpose of which is to help create and verify scientific abstracts and manuals*input :product type> subject>brochure//number of tests:15-25-33-45-100//enter the design sample file*all M must be adhered to in the attached form colors font type that night //first reference //second reference///the first step of the tool performs a reference scan at the bottom of the page makes sure that the selected topic is part of the ideas of the reference//step the second took the main topic from the first reference and expanded through the second reference *with the attachment of all the attachments and illustrations related to the specific topic//reformulating the topic in a human format, not a tool, then the output in the form of a high-quality DVD and format
P@community_library
0
modern acrylic signage
Text

Source: github.com/f/prompts.chat · Contributor: 2mikister

Act as an interior designer and visualization art director. 
Beside the door, put the logo in modern acrylic signage (transparent, and it has its own coloring). Do not change the picture; just put the signage in a modern way
P@community_library
0
Claude prompt: 11-second premium product film for an AI tool (16:9)
Text

Source: github.com/f/prompts.chat · Contributor: admin@drillup.io

Build an 11-second motion design product film in 16:9 (1920x1080, 30 fps) for my AI tool name, which what_it_does.
Build it as one HTML page with one animation timeline, so I can export it as an MP4.

Look: soft grey-green background, cream paper sheets, a dark green app panel, and gold as the only signal colour, used like a highlighter pen.

Text builds word by word: "problem" / "name [does step 1], [step 2], and [step 3]." / "claim."
Scene 1: a stack of paper sheets with the problem line on top.
Scene 2: one line on a sheet gets marked in gold and lifts off as a strip.
Scene 3: one camera move to the app panel. The strip lands there as a card.
Scene 4: the card opens and shows the better version: result.
Scene 5: a gold marker stroke draws the logo. Name and claim appear.

Rules: one object carries the story from start to end. Only one camera travel. Every move is eased.
P@community_library
0
Claude prompt: 11-second product film in a warm map style (16:9)
Text

Source: github.com/f/prompts.chat · Contributor: admin@drillup.io

Build an 11-second motion design product film in 16:9 (1920x1080, 30 fps) for my product name, which what_it_does.
Build it as one HTML page with HTML, CSS and inline SVG only (no photos), on one animation timeline, so I can export it as an MP4.

Look: a warm map seen from above. Sand-coloured ground with soft contour lines, dark brown type, and ONE signal colour hex for small things only.

Text builds word by word: "problem_in_one_sentence" / "name what_it_does_in_one_sentence." / "claim."
Scene 1: low, angled view of the map while the problem appears.
Scene 2: the camera rises to a top view in the same place. Areas light up one after another.
Scene 3: one camera move to a second place. A dark panel shows the result: result.
Scene 4: one area turns into the logo. Name and claim appear.

Rules: only one camera travel in the whole film. Words grow up from their baseline. Nothing moves linearly.
P@community_library
0
Claude prompt: 14-second product film for an invoicing app (16:9)
Text

Source: github.com/f/prompts.chat · Contributor: admin@drillup.io

Build a 14-second motion design product film in 16:9 (1920x1080, 30 fps) for my app name, which what_it_does.
Build it as one HTML page with one animation timeline, so I can export it as an MP4.

Look: light grey-green background with a soft grid, white cards with thin borders, one brand colour hex, one clean sans-serif font.

The text builds word by word: "hook_question" / "name step_1, step_2, and step_3 for you." / "result."
Scene 1: the hook question, big and centred.
Scenes 2 to 4: one card shows each step. The card from one step becomes the object of the next step.
Scene 5: the result with a small "done" stamp.
Scene 6: logo, name and "tagline".

Rules: the camera never stands still. Every move is eased. Key words are in the brand colour, the rest stays dark.
P@community_library
0
Claude prompt: 3D film as one endless camera zoom (9:16)
Text

Source: github.com/f/prompts.chat · Contributor: admin@drillup.io

Build a 13-second vertical 3D film (1080x1920, 30 fps) for brand, which what_it_does_in_one_sentence.
Build it as one web page with real-time 3D and a single animation timeline, so I can export it as an MP4.

Idea: one single camera flight with no cuts. Every world sits inside an object of the world before.
World 1 (0 to 4 s): a desk in a warm retro look. The camera moves slowly towards a monitor.
World 2 (4 to 8 s): the camera flies through the monitor screen and lands in a small room built from product_detail.
World 3 (8 to 11.5 s): the camera dives into one object in that room and finds the result: result.
End (11.5 to 13 s): the logo of brand as a 3D object, with the line "call_to_action".

Rules: the camera never stops and never cuts. Soft depth of field, light film grain. Simple, clear shapes that are easy to recognise.
P@community_library
0
Claude prompt: 10-second app ad for Reels and TikTok (9:16)
Text

Source: github.com/f/prompts.chat · Contributor: admin@drillup.io

Build a 10-second vertical motion design ad (1080x1920, 30 fps) for my app app_name, which what_it_does_in_one_sentence.
Build it as one HTML page with a single animation timeline, so I can export it as an MP4.

Look: very clean and friendly, bright background, rounded cards, one accent colour hex, large type that is easy to read on a phone.

Scene 1 (0 to 2.4 s): the hook "[HOOK, max 6 words]" builds word by word in the upper third. Each word rises with a soft overshoot.
Scene 2 (2.4 to 5.5 s): a phone screen slides up. It shows the main step of the app: [MAIN STEP, e.g. a receipt is read and split into names].
Scene 3 (5.5 to 8 s): the result pops in as small cards, one after another: result.
Scene 4 (8 to 10 s): app icon, name and "call_to_action".

Rules: keep all text inside the safe area (no text in the top 250 px or bottom 350 px). The camera keeps moving gently. One object carries the story from start to end.
P@community_library
0
Claude prompt: 12-second SaaS product film in 16:9
Text

Source: github.com/f/prompts.chat · Contributor: admin@drillup.io

Build a 12-second motion design product film in 16:9 (1920x1080, 30 fps) for my software product name, which what_it_does_in_one_sentence.
Build it as one HTML page with a single animation timeline, so I can export it as an MP4.

Look: light background, one accent colour hex, one clean sans-serif font, soft shadows, lots of white space.

Scene 1 (0 to 2.4 s): the headline "headline" builds word by word. Each word rises 18 px with a soft overshoot. Only the key word is in the accent colour.
Scene 2 (2.4 to 6 s): a small product card appears. Data rows from different tools slide in one after another.
Scene 3 (6 to 9.5 s): the rows merge into one clean table. One number counts up to result.
Scene 4 (9.5 to 12 s): end card with logo, name and the line "call_to_action".

Rules: the camera never stands still and moves on one continuous path. One object carries the story from the first second to the end card. Every movement is eased, nothing moves linearly.
P@community_library
0
The Summer Detour: 15-Second Nostalgic Anime Countryside Short (16:9 Video)
Text

Source: github.com/f/prompts.chat · Contributor: f

TITLE

THE SUMMER DETOUR

Create a 15-second cinematic nostalgic anime animation in 16:9 landscape format.

REFERENCE

Use the uploaded storyboard as the main visual reference. Follow its 8 shots in order.

Keep the girl, bicycle, clothes, soda bottle, rice fields, river, train, and sunlight consistent throughout.

Do not add characters, change locations unexpectedly, or introduce fantasy elements.

SUBJECTS

Girl: Original 13-year-old Japanese girl with shoulder-length dark brown hair, brown eyes, cream blouse, faded navy skirt, white socks, brown shoes, and canvas shoulder bag.

Bicycle: Vintage mint-green city bicycle with a silver handlebar, brown saddle, front wire basket, and black tires.

Props: One clear glass lemon soda bottle, initially in the basket and later held by the girl.

Train: Small cream-and-orange two-car local passenger train.

ENVIRONMENT

Peaceful Japanese countryside in late summer. Narrow roads, bright green rice paddies, traditional wooden houses, hanging wind chimes, grassy riverbanks, distant railway bridge, green mountains, and large white summer clouds.

Warm late-afternoon sunlight with gentle natural shadows. No sunset or dramatic lighting changes.

STYLE

Premium cinematic 2D anime with beautiful hand-painted backgrounds, soft cel shading, clean linework, natural colors, gentle environmental animation, and expressive but restrained character acting.

Create a calm, nostalgic feeling of an ordinary childhood summer afternoon.

Avoid photorealism, 3D CGI, neon lighting, excessive effects, and artificial camera movement.

AUDIO

No music or dialogue.

Natural countryside ambience only: cicadas, birds, soft wind, bicycle wheels, wind chimes, flowing river water, soda bottle sounds, and a distant passing train.

Keep the soundscape gentle, atmospheric, and continuous.

CAMERA AND FRAMING

16:9 cinematic framing. Smooth tracking shots, intimate close-ups, slow camera movements, and beautiful landscape compositions.

Use natural shot transitions and consistent sunlight.

SHOT-BY-SHOT TIMELINE

SHOT 1 (00:00-00:01.5) - THE SUMMER ROAD

Wide cinematic shot of a peaceful countryside road surrounded by lush rice fields. The girl pedals her mint-green bicycle slowly toward the distant mountains. Her hair moves gently in the warm breeze. Camera tracks smoothly behind her.

SFX: cicadas, gentle wind, bicycle tires.

SHOT 2 (00:01.5-00:03) - LITTLE DETAILS

Low close-up beside the bicycle. The wheels turn smoothly as sunlight flickers between the spokes. Tall grass and tiny wildflowers sway along the roadside. Camera follows the moving wheels with shallow depth of field.

SFX: rolling tires, grass rustling, summer insects.

SHOT 3 (00:03-00:05) - THE OPEN FIELDS

Beautiful side-tracking shot of the girl cycling beside endless green rice paddies. Enormous fluffy white clouds drift slowly above the distant mountains. Her skirt and hair move naturally in the breeze. Bright sunlight fills the landscape.

SFX: wind through rice fields, distant birds, bicycle chain.

SHOT 4 (00:05-00:06.5) - THE WIND CHIME

The girl cycles past a small traditional wooden house. Camera briefly follows a glass wind chime hanging beneath the roof as it sways gently. Sunlight reflects through the glass while the girl continues down the road in the background.

SFX: delicate wind chime, cicadas, soft bicycle movement.

SHOT 5 (00:06.5-00:08.5) - THE RIVERBANK

Wide shot of a quiet grassy riverbank. The girl arrives, stops her bicycle beside a shady tree, lowers its kickstand, and sits down on the grass. Sunlight sparkles across the flowing river. Camera slowly moves closer.

SFX: bicycle stopping, soft footsteps, flowing water.

SHOT 6 (00:08.5-00:10) - A SUMMER SIP

Intimate medium close-up. The girl takes the lemon soda bottle from her bicycle basket, opens it, and takes a refreshing sip while sitting in the grass. Tiny bubbles rise through the clear glass. She smiles peacefully.

SFX: bottle opening, gentle fizz, summer breeze.

SHOT 7 (00:10-00:12) - THE PASSING TRAIN

Cinematic medium-wide shot from behind the girl's shoulder. A cream-and-orange local train travels slowly across the distant railway bridge above the river. The girl watches quietly as sunlight glows across the passing carriages.

SFX: soft distant train wheels, river water, cicadas.

SHOT 8 (00:12-00:15) - THE SUMMER MEMORY (SIGNATURE MOMENT)

The camera slowly rises above the grassy riverbank into a magnificent aerial panorama. Reveal the winding blue river, endless green rice paddies, scattered countryside houses, distant mountains, and the small train continuing across the bridge.

The girl remains a tiny peaceful figure beside her parked bicycle beneath the tree.

The huge blue summer sky and beautiful white clouds dominate the final composition.

Camera movement gradually slows and settles into a breathtaking wide shot. Hold until the end.

SFX: warm countryside breeze, distant train fading away, gentle cicadas.

ENERGY ARC

Act 1 (0-5s): Freedom. Slow cycling, warm sunlight, peaceful summer landscapes.

Act 2 (5-10s): Stillness. Wind chimes, riverbank, a quiet moment with cold soda.

Act 3 (10-15s): Nostalgia. Passing train, expansive countryside reveal, and a peaceful ending.

FINAL REQUIREMENTS

Maintain consistent character proportions, outfit, bicycle design, train appearance, and geography.

Use smooth hand-drawn anime motion, believable cycling physics, gentle wind animation, and natural water movement.

No additional people, duplicated objects, character morphing, flickering, subtitles, logos, text overlays, or watermarks.

The final video should feel like a beautiful, soothing memory of a summer afternoon.
P@community_library
0
Nostalgic Anime Development Board: Character Sheet + 8-Frame Storyboard (The Summer Detour)
Text

Source: github.com/f/prompts.chat · Contributor: f

Create one vertical anime development board for an original 15-second short film titled "The Summer Detour".

The output must be one combined image with 2 sections:

Character design sheet

Cinematic storyboard page

STYLE:

Beautiful nostalgic 2D anime, hand-painted countryside backgrounds, clean anime linework, soft cel shading, lush green scenery, warm summer afternoon sunlight, gentle shadows, and bright blue skies with fluffy clouds.

Professional anime production board with red storyboard borders, blue camera arrows, small handwritten camera notes, and beautifully illustrated keyframes.

SECTION A: CHARACTER DESIGN

Main girl: An original 13-year-old Japanese girl with shoulder-length dark brown hair, soft brown eyes, and a gentle, cheerful expression.

Outfit: cream short-sleeved blouse, faded navy skirt, white socks, brown shoes, and a small canvas shoulder bag.

Personality: calm, curious, thoughtful, and quietly happy.

Show front, side, three-quarter, and back views, plus smiling, thoughtful, relaxed, and surprised expressions.

Include cycling, sitting, and looking toward the horizon poses.

BICYCLE:

Vintage mint-green city bicycle with a silver handlebar, brown saddle, small front wire basket, and simple black tires. A clear glass bottle of lemon soda sits securely inside the basket.

Keep the bicycle's design consistent in every frame.

SECTION B: STORYBOARD

Create 8 storyboard frames in a clean grid, each using 16:9 cinematic framing.

Keep the girl, bicycle, countryside, and lighting consistent.

Story beats:

Wide opening shot of the girl cycling along a peaceful countryside road surrounded by green rice fields.

Beautiful close-up of bicycle wheels turning beside swaying grass, sunlight sparkling through the spokes.

Side-tracking shot as she cycles past expansive rice paddies beneath enormous fluffy summer clouds.

She passes a small traditional house with hanging wind chimes gently swaying in the breeze.

She reaches a quiet grassy riverbank, stops, and parks her bicycle beside a tree.

Sitting in the grass, she opens her cold lemon soda and takes a refreshing sip.

A small cream-and-orange local train crosses a distant bridge over the river. She watches it with a gentle smile.

Spectacular wide ending shot: the camera rises to reveal the winding river, endless green fields, distant mountains, passing train, and girl resting beside her bicycle under a magnificent summer sky.

ENVIRONMENT:

Peaceful rural Japanese countryside, vibrant rice paddies, narrow asphalt roads, traditional wooden houses, wind chimes, wildflowers, a clear river, an old railway bridge, distant green mountains, and beautiful summer clouds.

Bright late-afternoon sunlight throughout.

FINAL GOAL:

Create a beautiful nostalgic anime film development board with soothing countryside scenery, authentic everyday moments, natural cinematic movement, consistent character design, and a breathtaking peaceful ending.
P@community_library
0
Korean Slice-of-Life Comedy: A Woman and Her Tiger-Hat Cat (16:9 Video)
Text

Source: github.com/f/prompts.chat · Contributor: f

Create a cinematic, ultra-realistic Korean-style short video featuring a young East Asian woman with a short black bob haircut and bangs, wearing a dark brown hoodie and casual pants. The video combines adorable animal moments, unexpected comedy, and cozy everyday life, with realistic physics, expressive characters, and professional cinematic camera work.

Scene 1 – A Funny Day at the Playground:
In a modern residential apartment playground, a young woman stands beside a cute gray tabby cat wearing an adorable tiger-striped animal hat. A large yellow helium balloon floats above the cat, creating a funny and unexpected situation. The woman holds a smartphone near her ear while managing the situation. Capture the cat's curious expressions and the woman's natural reactions with soft daylight, realistic fur details, and a cinematic shallow depth of field.

Scene 2 – The Unexpected Accident:
The woman walks near the playground while the cat and its leash move around her feet. In a sudden, funny moment, she loses her balance and falls onto the soft sandy ground. The cat remains surprisingly calm and curious, creating a humorous contrast. Use dynamic camera angles, natural body movements, realistic physics, and smooth cinematic transitions.

Scene 3 – The Cat's Adventure:
Show the adorable tabby cat wearing its miniature tiger hat as it walks around the playground. The yellow balloon and leash create playful visual moments. Capture close-ups of the cat's face, whiskers, paws, and fluffy striped fur. Include wide shots of the playground, apartment buildings, benches, and surrounding greenery.

Scene 4 – A Cozy Evening:
Transition to a peaceful residential courtyard during the evening golden hour. Warm lights glow through the apartment windows as the camera captures a quiet outdoor moment with a small fluffy dog wearing a blue ribbon. Use soft background bokeh, natural environmental details, and a warm cinematic atmosphere.

Scene 5 – A Funny Dinner at Home:
Inside a cozy, warmly lit modern kitchen, the same young woman sits at a wooden dining table filled with Korean-style home-cooked dishes, rice bowls, and small plates of side dishes. She eats with chopsticks while the adorable miniature cat, still wearing its tiger-striped hat, sits beside her at the table. The cat makes cute, expressive movements and watches the food with curiosity. The woman suddenly notices something unexpected and turns toward the cat with a surprised, confused expression. End with a charming comedic moment that highlights their playful relationship.

Visual Style: Ultra-realistic cinematic photography, Korean slice-of-life aesthetic, 4K resolution, natural skin texture, highly detailed animal fur, expressive facial reactions, realistic lighting, smooth camera movements, shallow depth of field, soft daylight, warm evening tones, and professional film-quality color grading.

Camera Direction: A combination of medium shots, wide establishing shots, low-angle animal shots, detailed close-ups, gentle tracking movements, and smooth cinematic transitions.

Mood: Cute, funny, heartwarming, slightly chaotic, and wholesome.

Important Consistency Rules: Keep the woman's facial appearance, short black bob hairstyle, bangs, and brown outfit consistent throughout the video. Maintain the same gray tabby cat and its tiger-striped hat in every scene where it appears. Ensure realistic animal anatomy, natural movements, consistent character appearances, and believable interactions between the characters.

Output: A high-quality cinematic short film in 16:9 aspect ratio, with realistic motion, detailed environments, expressive storytelling, and no artificial-looking animation.
P@community_library
0
Browser Extension taste
Text

Source: github.com/f/prompts.chat · Contributor: f

# Browser Extension taste of a cross-browser extension developer
- Build on Manifest V3 and plan around service workers that can be stopped at any time. Confidence: 0.95
- Use a framework like WXT or Plasmo with TypeScript and Vite to handle builds, reloads and cross-browser manifests. Confidence: 0.80
- Request the fewest permissions possible, and prefer activeTab and optional_permissions over broad host access. Confidence: 0.95
- Never request the all_urls host permission unless the core feature truly needs every site. Confidence: 0.90
- Keep no important state in service worker globals and persist it with chrome.storage instead. Confidence: 0.95
- Use chrome.storage.session for temporary secrets and chrome.storage.local or sync for user settings, with a typed wrapper and defaults. Confidence: 0.85
- Use chrome.alarms for scheduled work instead of setInterval in the background. Confidence: 0.90
- Register all event listeners at the top level of the service worker so they survive restarts. Confidence: 0.90
- Keep content scripts small and inject them programmatically with chrome.scripting when possible. Confidence: 0.85
- Isolate injected UI in a Shadow DOM so page styles and extension styles cannot collide. Confidence: 0.90
- Treat every message from content scripts and web pages as untrusted and validate it with a schema. Confidence: 0.95
- Define message types in one shared module and use typed request and response helpers for runtime messaging. Confidence: 0.85
- Never inject remote code or use eval, and keep a strict Content Security Policy. Confidence: 0.95
- Use declarativeNetRequest for blocking or modifying requests instead of trying to intercept them in code. Confidence: 0.85
- Use the webextension-polyfill or a framework layer so the same code runs on Chrome, Firefox, Edge and Safari. Confidence: 0.80
- Collect as little user data as possible and explain clearly in the store listing what is stored and why. Confidence: 0.90
- Handle install and update events to migrate stored settings between versions. Confidence: 0.85
- Test popup and options pages as normal web UI, and run end-to-end tests with Playwright loading the unpacked extension. Confidence: 0.80
- Automate builds, version bumps and store uploads in CI, with one zip artifact per browser. Confidence: 0.80
- Keep the popup fast by loading heavy data lazily and showing cached state first. Confidence: 0.80
- Write a short permission justification for each permission before submitting to the store. Confidence: 0.85
P@community_library
0
Rails App taste
Text

Source: github.com/f/prompts.chat · Contributor: f

# Rails App taste of a pragmatic Ruby on Rails developer
- Start new apps on the latest Rails with PostgreSQL, and stick to the defaults unless there is a clear reason to swap a piece out. Confidence: 0.90
- Keep controllers thin and RESTful, adding new resources like SessionsController or ArchivesController instead of custom actions. Confidence: 0.90
- Put domain logic in models and plain Ruby objects under app/models, and reach for service objects only when a workflow spans many models. Confidence: 0.75
- Use concerns sparingly and only for behavior that is genuinely shared, not to hide a bloated model. Confidence: 0.75
- Prefer Hotwire with Turbo and Stimulus for interactivity before adding a separate JavaScript SPA. Confidence: 0.85
- Validate data in the model and back it with database constraints like NOT NULL, unique indexes and foreign keys. Confidence: 0.95
- Write reversible migrations, add indexes concurrently on large tables, and never edit a migration that has already run in production. Confidence: 0.90
- Keep callbacks for simple data normalization and move side effects like emails and API calls into explicit jobs. Confidence: 0.85
- Run background work with Active Job on Solid Queue or Sidekiq, and keep every job idempotent and safe to retry. Confidence: 0.90
- Pass record IDs to jobs, not whole objects, and reload the record inside the job. Confidence: 0.85
- Catch N+1 queries with strict_loading or the Bullet gem, and fix them with includes or preload. Confidence: 0.90
- Use strong parameters everywhere and never pass params straight into update or create. Confidence: 0.95
- Store secrets in encrypted credentials or environment variables, never in committed YAML files. Confidence: 0.95
- Test with Minitest or RSpec, leaning on model and request tests, with a few system tests for critical flows. Confidence: 0.80
- Use fixtures or lean factories, and avoid deep factory chains that create half the database per test. Confidence: 0.75
- Lint with RuboCop using the rubocop-rails-omakase config or a small agreed set of rules, enforced in CI. Confidence: 0.80
- Scan for security issues with Brakeman and bundler-audit on every pull request. Confidence: 0.90
- Cache expensive views with fragment caching and cache keys based on updated_at, using Solid Cache or Redis. Confidence: 0.80
- Use scopes and query objects for reusable queries instead of long chains repeated across controllers. Confidence: 0.80
- Keep gems few and well maintained, and upgrade Rails one minor version at a time with deprecation warnings fixed first. Confidence: 0.85
- Deploy with Kamal or a managed platform using a Docker image built in CI, and run migrations as a separate release step. Confidence: 0.80
- Use Active Record encryption for sensitive columns like tokens and personal data. Confidence: 0.80
P@community_library
0
Authentication taste
Text

Source: github.com/f/prompts.chat · Contributor: f

# Authentication taste of a security-minded backend engineer
- Use a well-maintained auth library or provider instead of hand-rolling login, sessions and token handling. Confidence: 0.95
- Hash passwords with Argon2id, or bcrypt with a cost of at least 12, and never with a plain fast hash like SHA-256. Confidence: 0.95
- Prefer server-side sessions in HttpOnly, Secure, SameSite=Lax cookies for first-party web apps over JWTs in localStorage. Confidence: 0.90
- Use short-lived access tokens with rotating refresh tokens when you truly need stateless tokens for APIs or mobile clients. Confidence: 0.85
- Detect refresh token reuse and revoke the whole token family when it happens. Confidence: 0.85
- Regenerate the session ID on login, logout and privilege changes to prevent session fixation. Confidence: 0.95
- Offer passkeys (WebAuthn) as a first-class sign-in method, not only as a second factor. Confidence: 0.80
- Support TOTP or passkeys for MFA and treat SMS codes as a last-resort fallback. Confidence: 0.85
- Rate limit login, signup and password reset per account and per IP, with exponential backoff instead of hard permanent lockouts. Confidence: 0.90
- Return the same generic message for unknown email and wrong password so accounts cannot be enumerated. Confidence: 0.90
- Make password reset and magic link tokens single-use, random, hashed at rest and expiring within 15 to 60 minutes. Confidence: 0.95
- Check passwords against known breached lists and drop arbitrary composition rules like "one symbol required". Confidence: 0.85
- Use OAuth 2.1 Authorization Code with PKCE for every client, and never the implicit flow. Confidence: 0.95
- Validate the state and nonce parameters on every OAuth and OIDC callback. Confidence: 0.95
- Link social logins to existing accounts only after the provider returns a verified email. Confidence: 0.90
- Keep authentication (who you are) separate from authorization (what you can do) and check permissions on the server for every request. Confidence: 0.95
- Re-ask for credentials or a passkey before sensitive actions like changing email, password or payout details. Confidence: 0.85
- Notify users by email on new device sign-ins, password changes and MFA changes. Confidence: 0.80
- Let users see and revoke their active sessions from account settings. Confidence: 0.80
- Log auth events with user ID, IP and user agent, but never log passwords, tokens or reset links. Confidence: 0.95
- Protect cookie-based state-changing requests with SameSite cookies plus CSRF tokens or Origin header checks. Confidence: 0.90
- Store signing keys in a secrets manager and support key rotation with a kid header from day one. Confidence: 0.85
- Write integration tests for the unhappy paths: expired tokens, revoked sessions, replayed links and wrong tenants. Confidence: 0.85
P@community_library
0
Time Zone Meeting Slot Finder
Text

Source: github.com/f/prompts.chat · Contributor: f

---
name: time-zone-meeting-slot-finder
description: Finds fair meeting times for distributed teams. Takes each participant's IANA time zone, working days and hours, how far they will stretch, holidays and blocked time, then lists every slot in a date range in each person's local time, handles daylight-saving switches that happen on different weekends, and picks a rotating series so the same people do not always take the early or late call. Includes a stdlib Python zoneinfo script with --self-test.
---

# Time Zone Meeting Slot Finder

You help distributed teams pick meeting times that are possible for everyone required and fair over time. You work in each person's own local time on the actual dates (never with "LA is 9 hours behind Berlin" rules of thumb, which are wrong for weeks every spring and autumn), show the trade-offs openly, and rotate the inconvenient slots instead of always putting them on the same people.

## Files in this skill

- `scripts/slot_finder.py` - reads a team CSV and optional blocked-time CSV, evaluates every slot on a grid over the date range in each participant's local time (Python zoneinfo), ranks slots by who is missing and how much stretch they need, reports DST changes in the range, and can pick a fair rotating series (Python 3.9+ standard library only)
- `references/dst-and-time-zone-pitfalls.md` - DST dates by region, zones that do not switch, half-hour zones, weekends that are not Sat-Sun, abbreviations to avoid, and how calendar invites behave across a switch
- `references/fairness-and-rotation.md` - the pain-point model, how the rotation chooses, when to split a meeting or go async instead, and how to explain the choice to the team
- `templates/slot-proposal.md` - the proposal to send to the team
- `examples/team.csv` - five people in Los Angeles, New York, Berlin, Istanbul and Kolkata (one optional)
- `examples/blocked.csv` - a public holiday, a dentist appointment, a board review and a day of leave

## Workflow

### 1. Collect the facts
For each participant: name, IANA zone (city based, e.g. `America/Los_Angeles`, never "PST"), working days (Mon-Fri, or Sun-Thu in much of the Middle East), working hours, how many hours they are willing to start earlier or finish later, and whether they are required. Also the date range, meeting length, how often it repeats, known holidays and blocked times (in that person's local time). Ask rather than guess zones from a city that has several (e.g. a "Mexico" team member).

### 2. Run the finder
```
python3 scripts/slot_finder.py --team examples/team.csv --blocked examples/blocked.csv --start 2026-10-26 --end 2026-11-20 --days Tue,Wed,Thu --series 4
python3 scripts/slot_finder.py --team team.csv --start 2026-11-02 --end 2026-11-06 --duration 30 --step 15 --top 5
python3 scripts/slot_finder.py --team team.csv --start 2026-11-02 --end 2026-11-27 --series 8 --every day --ref-zone Europe/Berlin --json
python3 scripts/slot_finder.py --self-test
```
Dates (`--start`, `--end`, `--days`) are read in `--ref-zone` (default UTC). Exit 0 means slots were found, 1 means no slot works for every required person, 2 means bad input (unknown zone, bad time, missing column).

### 3. Read the result
- **DST changes in range** come first: if any zone switches inside the range, the same UTC time lands an hour earlier or later for those people afterwards. Propose slots per period, not one UTC time for the whole range.
- **Best slots** are ranked by: optional people missing, then the worst single person's stretch, then total stretch.
- **Rotating series** picks one meeting per week (or per day) to keep the worst cumulative inconvenience as low as possible, then spreads it. The summary shows how often each person met in hours, stretched or missed.
- If there is no slot, say why (who blocks whom) and offer options: more stretch from volunteers, a shorter meeting, making someone optional, two regional meetings, or async updates.

### 4. Deliver
Fill `templates/slot-proposal.md`: the recommendation with every person's local time and weekday, the DST note, the rotation table, alternatives, and the open questions. Send invites from a calendar with a real zone (the organizer's IANA zone), not "UTC" unless the team agreed, and say which zone anchors the series.

## Example result
Five people, 2026-10-26 to 2026-11-20, Tue-Thu, 60 minutes, series of 4 weekly meetings. Europe left summer time on 25 October and the US on 1 November, so in the week of 26 October New York is only 5 hours behind Berlin instead of 6. Week 1: 13:30 UTC (Ana 06:30 in Los Angeles, a stretch; Priya 19:00 in Kolkata, a stretch; everyone else in hours). After the US change, two weeks at 16:00 UTC (Ana 08:00 in hours, Eva 17:00-18:00 stretch, Bilal 19:00-20:00 stretch) and one at 14:30 UTC (Ana stretches again). Bilal is blocked on 29 October (Republic Day). Priya (optional, +05:30) can join only before the US change; the proposal adds a recorded summary for her and suggests an Asia-friendly slot once a month.

## Rules

- Always use IANA zone names and compute local times per date; never apply fixed offsets across a DST boundary.
- Show every participant's local time and weekday for each proposal, since the date can differ (Kolkata evening, Los Angeles morning).
- Nobody is scheduled outside the stretch they agreed to; ask before assuming someone will take a 06:00 or 22:00 call.
- Rotate inconvenience and show the tally; if one person always loses, say so and suggest a structural fix (split, async, rotate the meeting owner).
- Respect weekends, public holidays and blocked time in the person's own calendar and zone.
- Keep the recommendation short; put the full table in an appendix.
FILE:references/dst-and-time-zone-pitfalls.md
# DST and time zone pitfalls

## Use IANA zone names
- `America/New_York`, `Europe/Berlin`, `Asia/Kolkata`, `Australia/Sydney`. They carry the full history and future rules of that region.
- Avoid abbreviations: "EST", "CST", "IST" and "BST" are ambiguous (IST = India, Ireland or Israel; CST = US Central, China or Cuba) and the zoneinfo entries named EST or MST are fixed offsets with no DST. The script warns on names without a "/".
- Avoid fixed offsets like UTC+1 for people: offsets change twice a year in many places.
- Pick the city that shares the person's rules: Arizona (`America/Phoenix`) has no DST; most of Mexico dropped DST in 2022; `America/Sao_Paulo` dropped DST in 2019.
- Keep the zone database current (`tzdata`); governments change rules with a few weeks' notice.

## DST dates (2026, check each year)
| Region | Summer time starts | Ends | Note |
|---|---|---|---|
| US and Canada (most) | 2nd Sunday of March (2026-03-08) | 1st Sunday of November (2026-11-01) | local 02:00 |
| EU, UK | last Sunday of March (2026-03-29) | last Sunday of October (2026-10-25) | 01:00 UTC, all at once |
| Australia (south-east), New Zealand | first Sunday of October / last Sunday of September | first Sunday of April | southern hemisphere: opposite season |
| No DST | Turkey (UTC+3), India (+05:30), China, Japan, Singapore, UAE, most of Africa, Arizona | | |

So there are two "gap" periods each year when the US-Europe difference is one hour smaller than usual: about 3 weeks in March and 1 week at the end of October / start of November. Recurring meetings anchored in one region move by an hour for the other during those weeks.

## Offsets that are not whole hours
- India +05:30, Iran +03:30, Nepal +05:45, Newfoundland -03:30 (-02:30 in summer), South Australia +09:30/+10:30, Chatham Islands +12:45. A grid on the hour in UTC lands on :30 or :45 for these people; the script evaluates in 5-minute chunks so these are exact.

## Weekends and working days
- Sun-Thu working weeks: e.g. Israel; Fri-Sat weekends in several Gulf countries, while the UAE moved to Mon-Fri (with a half Friday) in 2022. Ask each person.
- Public holidays differ per country and per region (Bavaria vs Berlin, US states). Add them to the blocked file in local dates.
- A Monday 08:00 slot in Los Angeles is Monday evening in India but already Tuesday morning in Sydney or Auckland. Always show the weekday per person.

## DST on the switch day itself
- Spring forward: local times between 02:00 and 03:00 (US) do not exist; autumn back: 01:00-02:00 happens twice. Avoid scheduling in those hours on switch days; the script works on UTC instants so it never produces an invalid time, but humans reading "01:30" on that day can be confused.

## Calendar invites across a switch
- A recurring invite is anchored to the organizer's zone. A 10:00 New York weekly meeting stays at 10:00 in New York and moves for Berlin during the gap weeks.
- If the series must stay fair for both sides, anchor it in UTC deliberately and tell everyone, or plan the gap weeks explicitly.
- Check the invite's zone after creating it (some tools default to the device zone or to "floating" time).
FILE:references/fairness-and-rotation.md
# Fairness and rotation

## Pain-point model used by the script
| Situation for one person in one meeting | Points |
|---|---|
| Entirely inside their working hours | 0 |
| Partly or fully in their stretch window (before or after work, as much as they agreed to) | 2 per hour of stretch, pro rata (30 min = 1) |
| Outside the stretch window, on a non-working day, or during blocked time | cannot attend (slot invalid if they are required) |
| Optional person who cannot attend (rotation tally only) | 3 |

Ranking of single slots: fewest optional people missing, then the lowest worst-off person, then the lowest total.

Rotation (`--series N`): greedily adds one meeting at a time, at most one per ISO week (`--every week`, default) or per date (`--every day`), choosing the slot that keeps the highest cumulative score lowest, then the sum of squared cumulative scores (which spreads pain instead of concentrating it), then fewer people missing. The summary table shows per person: meetings in hours, stretched, missed, total points.

The weights are a model, not a truth. Adjust them with the team: an early start may cost a parent more than a late finish, a 22:00 call costs more than 18:30. Change stretch windows per person to reflect what they actually accept.

## Make the trade-offs visible
- Show each person's local time and weekday for each option.
- Show the rotation tally, so that "Bilal stretches 3 of 4 times" is a visible decision, not an accident.
- Ask people to set their own stretch windows; never assume someone will take a 06:30 call because they did it once.

## When no fair slot exists
- Shorten the meeting: 30 minutes often fits where 60 does not.
- Make people optional and record the meeting with written notes and a decision log.
- Split by region (Americas + Europe, Europe + Asia) with one person bridging, and rotate the bridge.
- Alternate two time slots week by week (e.g. 14:00 UTC and 07:00 UTC) so each side gets the convenient one half the time.
- Go async: written updates, recorded demos, decisions in a doc with a deadline in everyone's local time.

## Checklist before sending
- Every required person is in hours or in their agreed stretch for every meeting in the series.
- Holidays and leave in each country are in the blocked file.
- DST changes in the range are named, and the series accounts for them.
- The invite is created in the agreed anchor zone; times in the message are given per person.
- There is a review date (e.g. after the next DST change) to rotate again.
FILE:templates/slot-proposal.md
# Meeting time proposal: <meeting name>

**Who:** <Ana (Los Angeles), Dana (New York), Eva (Berlin), Bilal (Istanbul), Priya (Kolkata, optional)>
**Length / cadence:** <60 min weekly, Tue-Thu>   **Range checked:** <2026-10-26 to 2026-11-20>
**Anchor zone for the invite:** <UTC / organizer's zone>

## Recommendation
| Week | Start (UTC) | Ana | Dana | Eva | Bilal | Priya |
|---|---|---|---|---|---|---|
| <Oct 26> | <Tue 13:30> | <Tue 06:30 (stretch)> | <09:30> | <14:30> | <16:30> | <19:00 (stretch)> |
| <Nov 2> | <Wed 16:00> | <08:00> | <11:00> | <17:00 (stretch)> | <19:00 (stretch)> | <cannot (21:30)> |

## Daylight saving
- <Europe left summer time on Oct 25, the US on Nov 1: during the week of Oct 26 New York is 5 h behind Berlin instead of 6, so the slot moves by an hour from Nov 2>

## Fairness over the series
| Name | In hours | Stretch | Missed | Points |
|---|---|---|---|---|
| <Ana> | <2> | <2> | <0> | <4> |

<One sentence on who carries the most and what we do about it (e.g. Priya: recorded summary + an Asia-friendly slot monthly).>

## Alternatives
1. <30-minute version at 15:00 UTC: everyone in hours except ...>
2. <alternate two slots week by week>

## Blocked dates taken into account
- <Oct 29: Republic Day, Turkey (Bilal)>

## Please confirm
- <your stretch window is still right>
- <holidays or leave in this range we missed>
FILE:examples/team.csv
name,zone,work_start,work_end,days,flex_before,flex_after,required
Ana,America/Los_Angeles,08:00,16:30,Mon-Fri,1.5,1,yes
Dana,America/New_York,08:30,17:00,Mon-Fri,1,1,yes
Eva,Europe/Berlin,09:00,17:30,Mon-Fri,1,1.5,yes
Bilal,Europe/Istanbul,09:00,18:00,Mon-Fri,0,2,yes
Priya,Asia/Kolkata,10:00,18:30,Mon-Fri,0,2,no
FILE:examples/blocked.csv
name,date,start,end,reason
Bilal,2026-10-29,,,Republic Day (public holiday in Turkey)
Dana,2026-11-03,10:00,11:30,dentist
Eva,2026-11-05,15:30,17:30,quarterly board review
Priya,2026-11-06,,,leave
FILE:scripts/slot_finder.py
#!/usr/bin/env python3
"""Time zone meeting slot finder (Python 3.9+ standard library: zoneinfo).

Given participants with IANA time zones, working days and hours (plus how far each one
is willing to stretch before or after work), finds meeting slots over a date range,
ranks them by fairness, and can pick a rotating series so the same people do not take
the early or late call every time. Each slot is evaluated in every participant's own
local time on that date, so daylight-saving transitions inside the range (Europe and
the US switch on different weekends) are handled automatically and reported.

Pain points per participant and meeting: 0 inside working hours, 2 per hour inside the
stretch ("flex") window before or after work, unavailable beyond that, on non-working
days or during blocked time. Missing an optional participant counts as 3 pain points
for them in the rotation tally.

Usage:
  python3 slot_finder.py --team team.csv --start 2026-10-26 --end 2026-11-06
        [--duration 60] [--step 30] [--blocked blocked.csv] [--days Tue,Wed,Thu]
        [--ref-zone UTC] [--top 10] [--series N [--every week|day]] [--json]
  python3 slot_finder.py --self-test
team.csv columns: name, zone, work_start, work_end, days (Mon-Fri or Sun-Thu or
Mon,Wed,Fri), flex_before, flex_after (hours, optional), required (yes/no, optional).
work_end earlier than work_start means a shift that runs past midnight.
blocked.csv columns: name, date (participant's local date), start, end (empty = all day), reason.
Exit codes: 0 = slots found, 1 = no slot where all required participants can attend,
2 = bad input (unknown time zone, bad time, missing file or column).
"""
import argparse, csv, datetime as dt, io, json, sys
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError

DAY_NAMES = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
CHUNK = 5  # minutes; fine enough for +05:30 and +05:45 zones
FLEX_PAIN_PER_HOUR = 2
MISSED_PAIN = 3


class InputError(Exception):
    pass


def parse_days(s):
    s = (s or "Mon-Fri").strip()
    out = set()
    for part in s.replace(" ", "").split(","):
        if not part:
            continue
        if "-" in part:
            a, b = part.split("-", 1)
            i, j = day_index(a), day_index(b)
            k = i
            while True:
                out.add(k)
                if k == j:
                    break
                k = (k + 1) % 7
        else:
            out.add(day_index(part))
    return out


def day_index(name):
    n = name.strip()[:3].title()
    if n not in DAY_NAMES:
        raise InputError(f"unknown day '{name}' (use Mon..Sun)")
    return DAY_NAMES.index(n)


def parse_hm(s, what):
    try:
        h, m = s.strip().split(":")
        h, m = int(h), int(m)
        if not (0 <= h <= 24 and 0 <= m < 60) or (h == 24 and m):
            raise ValueError
        return h * 60 + m
    except (ValueError, AttributeError):
        raise InputError(f"bad time '{s}' for {what} (use HH:MM, 24-hour)")


def load_zone(name, who, warnings):
    name = (name or "").strip()
    try:
        z = ZoneInfo(name)
    except (ZoneInfoNotFoundError, ValueError):
        raise InputError(f"unknown time zone '{name}' for {who}: use an IANA name such as America/New_York, Europe/Berlin, Asia/Kolkata (pip install tzdata if the system has no zone database)")
    if "/" not in name and name not in ("UTC", "Etc/UTC"):
        warnings.append(f"{who}: '{name}' is an abbreviation or legacy zone with fixed rules; use the city-based IANA name (e.g. America/New_York, not EST) so daylight saving is right")
    return z


def read_team(text, warnings):
    rows = list(csv.DictReader(io.StringIO(text.lstrip("\ufeff"))))
    if not rows:
        raise InputError("team file has no rows")
    for col in ("name", "zone", "work_start", "work_end"):
        if col not in rows[0]:
            raise InputError(f"team file is missing column '{col}'")
    team = []
    for r in rows:
        who = (r.get("name") or "").strip()
        if not who:
            continue
        p = {"name": who, "zone_name": r["zone"].strip(), "zone": load_zone(r["zone"], who, warnings),
             "start": parse_hm(r["work_start"], who + " work_start"), "end": parse_hm(r["work_end"], who + " work_end"),
             "days": parse_days(r.get("days")),
             "flex_before": int(round(float(r.get("flex_before") or 0) * 60)),
             "flex_after": int(round(float(r.get("flex_after") or 0) * 60)),
             "required": (r.get("required") or "yes").strip().lower() not in ("no", "n", "false", "0", "optional"),
             "blocked": []}
        if p["start"] == p["end"]:
            raise InputError(f"{who}: work_start equals work_end")
        team.append(p)
    names = [p["name"] for p in team]
    if len(set(names)) != len(names):
        raise InputError("duplicate participant names in team file")
    return team


def read_blocked(text, team):
    byname = {p["name"].lower(): p for p in team}
    for r in csv.DictReader(io.StringIO(text.lstrip("\ufeff"))):
        who = (r.get("name") or "").strip()
        if not who:
            continue
        p = byname.get(who.lower())
        if not p:
            raise InputError(f"blocked time for unknown participant '{who}'")
        try:
            d = dt.date.fromisoformat(r["date"].strip())
        except (ValueError, KeyError):
            raise InputError(f"bad date in blocked file for {who}: {r.get('date')}")
        s, e = (r.get("start") or "").strip(), (r.get("end") or "").strip()
        a = dt.datetime.combine(d, dt.time()) + dt.timedelta(minutes=parse_hm(s, who + " blocked start") if s else 0)
        b = dt.datetime.combine(d, dt.time()) + dt.timedelta(minutes=parse_hm(e, who + " blocked end") if e else 1440)
        p["blocked"].append((a, b, (r.get("reason") or "").strip()))


def classify(p, local):
    """local: naive local datetime. Return 'core', 'flex' or None (unavailable)."""
    best = None
    for back in (0, 1):
        d = local.date() - dt.timedelta(days=back)
        if d.weekday() not in p["days"]:
            continue
        base = dt.datetime.combine(d, dt.time())
        cs = base + dt.timedelta(minutes=p["start"])
        ce = base + dt.timedelta(minutes=p["end"] + (1440 if p["end"] <= p["start"] else 0))
        if cs <= local < ce:
            return "core"
        if cs - dt.timedelta(minutes=p["flex_before"]) <= local < ce + dt.timedelta(minutes=p["flex_after"]):
            best = "flex"
    return best


def evaluate(p, start_utc, minutes):
    """Return (status, pain, local_start, local_end, reason). status in core, flex, out."""
    flex_min = 0
    reason = ""
    for k in range(0, minutes, CHUNK):
        t = (start_utc + dt.timedelta(minutes=k)).astimezone(p["zone"]).replace(tzinfo=None)
        c = classify(p, t)
        if c is None:
            reason = "outside hours" if t.date().weekday() in p["days"] or classify_day_any(p, t) else "day off"
            return "out", 0.0, *local_span(p, start_utc, minutes), reason
        for a, b, why in p["blocked"]:
            if a <= t < b:
                return "out", 0.0, *local_span(p, start_utc, minutes), f"blocked: {why}" if why else "blocked"
        if c == "flex":
            flex_min += CHUNK
    pain = round(flex_min / 60 * FLEX_PAIN_PER_HOUR, 2)
    return ("flex" if flex_min else "core"), pain, *local_span(p, start_utc, minutes), ""


def classify_day_any(p, t):
    return (t.date() - dt.timedelta(days=1)).weekday() in p["days"] and p["end"] <= p["start"]


def local_span(p, start_utc, minutes):
    a = start_utc.astimezone(p["zone"])
    b = (start_utc + dt.timedelta(minutes=minutes)).astimezone(p["zone"])
    return a, b


def dst_changes(team, start, end):
    out = []
    seen = set()
    for p in team:
        if p["zone_name"] in seen:
            continue
        seen.add(p["zone_name"])
        z = p["zone"]
        t = dt.datetime.combine(start - dt.timedelta(days=1), dt.time(), tzinfo=dt.timezone.utc)
        stop = dt.datetime.combine(end + dt.timedelta(days=2), dt.time(), tzinfo=dt.timezone.utc)
        prev = t.astimezone(z).utcoffset()
        while t < stop:
            t2 = t + dt.timedelta(minutes=30)
            off = t2.astimezone(z).utcoffset()
            if off != prev:
                loc = t2.astimezone(z)
                out.append({"zone": p["zone_name"], "utc": t2.strftime("%Y-%m-%d %H:%M UTC"),
                            "local": loc.strftime("%Y-%m-%d %H:%M %Z"), "from": fmt_off(prev), "to": fmt_off(off)})
                prev = off
            t = t2
    return out


def fmt_off(td):
    m = int(td.total_seconds() // 60)
    s = "+" if m >= 0 else "-"
    m = abs(m)
    return f"UTC{s}{m // 60:02d}:{m % 60:02d}"


def find_slots(team, start, end, duration, step, ref_zone, only_days=None):
    """start/end: dates in ref_zone (inclusive). Returns list of slot dicts."""
    slots = []
    t = dt.datetime.combine(start, dt.time(), tzinfo=ref_zone).astimezone(dt.timezone.utc)
    stop = dt.datetime.combine(end + dt.timedelta(days=1), dt.time(), tzinfo=ref_zone).astimezone(dt.timezone.utc)
    t = t.replace(minute=(t.minute // step) * step if step < 60 else 0, second=0, microsecond=0)
    while t + dt.timedelta(minutes=duration) <= stop:
        ref_local = t.astimezone(ref_zone)
        if only_days is None or ref_local.weekday() in only_days:
            per, ok = {}, True
            for p in team:
                st, pain, a, b, why = evaluate(p, t, duration)
                per[p["name"]] = {"status": st, "pain": pain, "local_start": a, "local_end": b, "reason": why}
                if st == "out" and p["required"]:
                    ok = False
                    break
            if ok:
                missing = [p["name"] for p in team if per[p["name"]]["status"] == "out"]
                pains = [per[p["name"]]["pain"] for p in team]
                slots.append({"utc": t, "per": per, "missing": missing, "total_pain": round(sum(pains), 2),
                              "max_pain": max(pains)})
        t += dt.timedelta(minutes=step)
    return slots


def rank(slots):
    return sorted(slots, key=lambda s: (len(s["missing"]), s["max_pain"], s["total_pain"], s["utc"]))


def period_key(s, ref_zone, every):
    d = s["utc"].astimezone(ref_zone).date()
    return d.isocalendar()[:2] if every == "week" else d


def pick_series(slots, team, n, ref_zone, every="week"):
    """Greedy fair rotation: n slots, at most one per ref-zone ISO week (every="week") or
    per date (every="day"), minimising the worst cumulative pain, then the sum of squared
    cumulative pain, then missed people."""
    cum = {p["name"]: 0.0 for p in team}
    chosen, used_dates = [], set()
    for _ in range(n):
        best, best_key = None, None
        for s in slots:
            d = period_key(s, ref_zone, every)
            if d in used_dates:
                continue
            new = {k: cum[k] + (MISSED_PAIN if s["per"][k]["status"] == "out" else s["per"][k]["pain"]) for k in cum}
            key = (round(max(new.values()), 2), round(sum(v * v for v in new.values()), 2), len(s["missing"]), s["total_pain"], s["utc"])
            if best_key is None or key < best_key:
                best, best_key = s, key
        if best is None:
            break
        chosen.append(best)
        used_dates.add(period_key(best, ref_zone, every))
        for k in cum:
            cum[k] += MISSED_PAIN if best["per"][k]["status"] == "out" else best["per"][k]["pain"]
    chosen.sort(key=lambda s: s["utc"])
    return chosen, cum


def cell(info):
    a, b = info["local_start"], info["local_end"]
    txt = f"{DAY_NAMES[a.weekday()]} {a:%H:%M}-{b:%H:%M}"
    if info["status"] == "flex":
        txt += f" (stretch, {info['pain']:g})"
    elif info["status"] == "out":
        txt += f" (cannot: {info['reason']})"
    return txt


def table(slots, team, ref_zone):
    head = ["#", f"Start ({ref_zone.key})"] + [f"{p['name']} ({p['zone_name']})" for p in team] + ["Pain total/max", "Missing"]
    out = ["| " + " | ".join(head) + " |", "|" + "---|" * len(head)]
    for i, s in enumerate(slots, 1):
        r = s["utc"].astimezone(ref_zone)
        row = [str(i), f"{DAY_NAMES[r.weekday()]} {r:%Y-%m-%d %H:%M}"] + [cell(s["per"][p["name"]]) for p in team] + \
              [f"{s['total_pain']:g}/{s['max_pain']:g}", ", ".join(s["missing"]) or "-"]
        out.append("| " + " | ".join(row) + " |")
    return out


def report(team, slots, args, ref_zone, warnings, changes, series=None, cum=None):
    out = [f"# Meeting slots {args['start']} to {args['end']} ({args['duration']} min, dates in {ref_zone.key})", ""]
    for w in warnings:
        out.append(f"> WARNING: {w}")
    if warnings:
        out.append("")
    out.append("## Participants")
    out.append("| Name | Zone | Hours (local) | Days | Stretch before/after | Required |")
    out.append("|---|---|---|---|---|---|")
    for p in team:
        days = ",".join(DAY_NAMES[d] for d in sorted(p["days"]))
        out.append(f"| {p['name']} | {p['zone_name']} | {p['start'] // 60:02d}:{p['start'] % 60:02d}-{p['end'] // 60:02d}:{p['end'] % 60:02d} | {days} | {p['flex_before'] / 60:g}h / {p['flex_after'] / 60:g}h | {'yes' if p['required'] else 'no'} |")
    out += ["", "## Daylight saving changes in range"]
    if changes:
        for c in changes:
            out.append(f"- {c['zone']}: {c['from']} -> {c['to']} at {c['local']} ({c['utc']}); the same UTC time moves by an hour locally after this")
    else:
        out.append("- none")
    out.append("")
    if not slots:
        out.append("No slot found where every required participant is available. Options: allow more stretch hours, make someone optional, shorten the meeting, split into two regional meetings, or go async.")
        return "\n".join(out)
    if series:
        out += [f"## Rotating series ({len(series)} meetings, fairest combination found by greedy rotation)", ""] + table(series, team, ref_zone)
        out += ["", "| Name | In hours | Stretch | Missed | Pain total |", "|---|---|---|---|---|"]
        for p in team:
            st = [s["per"][p["name"]]["status"] for s in series]
            out.append(f"| {p['name']} | {st.count('core')} | {st.count('flex')} | {st.count('out')} | {cum[p['name']]:g} |")
        out.append("")
    top = rank(slots)[:args["top"]]
    out += [f"## Best {len(top)} of {len(slots)} possible slots", ""] + table(top, team, ref_zone)
    out += ["", f"Pain: 0 inside working hours, {FLEX_PAIN_PER_HOUR} per hour of stretch, {MISSED_PAIN} for an optional person who cannot attend (rotation only)."]
    return "\n".join(out)


def to_json(team, slots, series, cum, changes, warnings, ref_zone, top):
    def enc(s):
        return {"start_utc": s["utc"].strftime("%Y-%m-%dT%H:%MZ"), "start_ref": s["utc"].astimezone(ref_zone).isoformat(),
                "total_pain": s["total_pain"], "max_pain": s["max_pain"], "missing": s["missing"],
                "participants": {k: {"status": v["status"], "pain": v["pain"], "local_start": v["local_start"].isoformat(),
                                     "local_end": v["local_end"].isoformat(), "reason": v["reason"]} for k, v in s["per"].items()}}
    return {"warnings": warnings, "dst_changes": changes, "slot_count": len(slots),
            "best": [enc(s) for s in rank(slots)[:top]], "series": [enc(s) for s in series or []], "series_pain": cum or {}}


def run(team_text, start, end, duration=60, step=30, blocked_text=None, ref="UTC", top=10, series=0, only_days=None, every="week"):
    warnings = []
    team = read_team(team_text, warnings)
    if blocked_text:
        read_blocked(blocked_text, team)
    ref_zone = load_zone(ref, "--ref-zone", warnings)
    if end < start:
        raise InputError("--end is before --start")
    if duration % CHUNK or step % CHUNK or duration <= 0 or step <= 0:
        raise InputError(f"--duration and --step must be positive multiples of {CHUNK} minutes")
    slots = find_slots(team, start, end, duration, step, ref_zone, only_days)
    chosen, cum = pick_series(slots, team, series, ref_zone, every) if series else (None, None)
    changes = dst_changes(team, start, end)
    return team, slots, chosen, cum, changes, warnings, ref_zone


def self_test():
    T = "name,zone,work_start,work_end,days,flex_before,flex_after,required\n"
    D = dt.date
    passed, total = 0, 0

    def check(name, cond):
        nonlocal passed, total
        total += 1
        passed += bool(cond)
        print(("PASS " if cond else "FAIL ") + name)

    team, slots, *_ = run(T + "A,Europe/Berlin,09:00,17:00,Mon-Fri,0,0,yes\nB,Europe/London,09:00,17:00,Mon-Fri,0,0,yes\n", D(2026, 11, 2), D(2026, 11, 2))
    check("Berlin+London overlap is 09:00-16:00 UTC (13 one-hour starts on the 30-min grid)", len(slots) == 13 and slots[0]["utc"].hour == 9 and slots[-1]["utc"].hour == 15)
    check("all in-hours slots have zero pain", all(s["total_pain"] == 0 for s in slots))
    team, slots, *_ = run(T + "A,America/Los_Angeles,09:00,17:00,Mon-Fri,0,0,yes\nB,Asia/Kolkata,09:00,18:00,Mon-Fri,0,0,yes\n", D(2026, 11, 2), D(2026, 11, 6))
    check("LA and Kolkata without stretch: no slot", not slots)
    team, slots, *_ = run(T + "A,America/Los_Angeles,09:00,17:00,Mon-Fri,2,0,yes\nB,Asia/Kolkata,09:00,18:00,Mon-Fri,0,3,yes\n", D(2026, 11, 2), D(2026, 11, 6), duration=30)
    check("with 2h/3h stretch: only 30-min slots (15:00 UTC) exist and all carry pain", slots and all(s["total_pain"] > 0 for s in slots))
    s0 = rank(slots)[0]
    check("half-hour zone: Kolkata local minutes end in :30", s0["per"]["B"]["local_start"].minute == 30)
    team, slots, *_ = run(T + "A,Europe/Berlin,09:00,17:00,Mon-Fri,0,0,yes\nB,America/New_York,09:00,17:00,Mon-Fri,0,0,yes\n", D(2026, 10, 26), D(2026, 10, 26))
    first = slots[0]["utc"]
    check("Berlin-NY in the gap week (EU back on CET, US still EDT): overlap 13:00-16:00 UTC", first.hour == 13 and slots[-1]["utc"].hour == 15)
    team, slots2, *_ = run(T + "A,Europe/Berlin,09:00,17:00,Mon-Fri,0,0,yes\nB,America/New_York,09:00,17:00,Mon-Fri,0,0,yes\n", D(2026, 11, 2), D(2026, 11, 2))
    check("after US DST end: overlap starts 14:00 UTC", slots2[0]["utc"].hour == 14)
    *_, changes, w, rz = run(T + "A,Europe/Berlin,09:00,17:00,Mon-Fri,0,0,yes\nB,America/New_York,09:00,17:00,Mon-Fri,0,0,yes\n", D(2026, 10, 24), D(2026, 11, 3))
    zones = {c["zone"]: c for c in changes}
    check("DST changes found: Berlin 2026-10-25 and New York 2026-11-01", "2026-10-25" in zones.get("Europe/Berlin", {}).get("local", "") and "2026-11-01" in zones.get("America/New_York", {}).get("local", ""))
    team, slots, *_ = run(T + "A,Asia/Dubai,09:00,17:00,Sun-Thu,0,0,yes\nB,Europe/London,09:00,17:00,Mon-Fri,0,0,yes\n", D(2026, 11, 6), D(2026, 11, 8))
    check("Sun-Thu vs Mon-Fri: no Fri/Sat/Sun slot", not slots)
    team, slots, *_ = run(T + "A,Asia/Dubai,09:00,17:00,Sun-Thu,0,0,yes\nB,Europe/London,09:00,17:00,Mon-Fri,0,0,yes\n", D(2026, 11, 9), D(2026, 11, 9))
    check("Sun-Thu vs Mon-Fri: Monday works", bool(slots))
    team, slots, *_ = run(T + "A,Europe/Berlin,09:00,17:00,Mon-Fri,0,0,yes\nB,Europe/Paris,09:00,17:00,Mon-Fri,0,0,no\n", D(2026, 11, 2), D(2026, 11, 2),
                          blocked_text="name,date,start,end,reason\nB,2026-11-02,,,holiday\n")
    check("optional person blocked all day: slots still found, B missing", slots and all(s["missing"] == ["B"] for s in slots))
    check("blocked reason shown", slots and "holiday" in slots[0]["per"]["B"]["reason"])
    team, slots, *_ = run(T + "A,Europe/Berlin,09:00,17:00,Mon-Fri,0,0,yes\nB,Europe/Paris,09:00,17:00,Mon-Fri,0,0,yes\n", D(2026, 11, 2), D(2026, 11, 2),
                          blocked_text="name,date,start,end,reason\nB,2026-11-02,10:00,12:00,dentist\n")
    check("required person blocked 10-12 local: no slot overlaps 09:00-11:00 UTC", slots and not any(dt.time(8, 30) < s["utc"].time() < dt.time(11, 0) for s in slots))
    team, slots, *_ = run(T + "N,Europe/Berlin,22:00,06:00,Mon-Fri,0,0,yes\n", D(2026, 11, 3), D(2026, 11, 3))
    hours = sorted({s["utc"].hour for s in slots})
    check("overnight shift 22:00-06:00 Berlin (UTC+1): starts 00:00-04:00 and 21:00-23:00 UTC", hours == [0, 1, 2, 3, 4, 21, 22, 23])
    w = []
    load_zone("EST", "X", w)
    check("abbreviation zone gives a warning", w and "abbreviation" in w[0])
    try:
        load_zone("Mars/Olympus", "X", [])
        ok = False
    except InputError as e:
        ok = "unknown time zone" in str(e)
    check("unknown zone is an input error", ok)
    try:
        parse_hm("9am", "x")
        ok = False
    except InputError:
        ok = True
    check("bad time is an input error", ok)
    check("day ranges wrap: Fri-Mon", parse_days("Fri-Mon") == {4, 5, 6, 0})
    team3 = T + "A,America/Los_Angeles,09:00,17:00,Mon-Fri,2,0,yes\nB,Europe/Istanbul,09:00,18:00,Mon-Fri,0,2,yes\n"
    team, slots, chosen, cum, *_ = run(team3, D(2026, 11, 2), D(2026, 11, 6), series=4, every="day")
    st = {k: sum(1 for s in chosen if s["per"][k]["status"] == "flex") for k in ("A", "B")}
    check("series of 4 on 4 different dates", len(chosen) == 4 and len({s["utc"].date() for s in chosen}) == 4)
    check("rotation shares the stretch: both A and B stretch at least once", st["A"] >= 1 and st["B"] >= 1)
    check("rotation pain is balanced (difference <= 2 points)", abs(cum["A"] - cum["B"]) <= 2)
    team, slots, chosen, cum, *_ = run(team3, D(2026, 10, 26), D(2026, 11, 20), series=4)
    check("weekly series: one meeting in each of 4 ISO weeks", len({s["utc"].isocalendar()[1] for s in chosen}) == 4)
    team, slots, *_ = run(T + "A,Europe/Berlin,09:00,17:00,Mon-Fri,0,0,yes\n", D(2026, 11, 2), D(2026, 11, 6), only_days={1, 3})
    check("--days Tue,Thu filters candidate days", slots and {s["utc"].weekday() for s in slots} == {1, 3})
    team, slots, ch, cum, changes, w, rz = run(T + "A,Europe/Berlin,09:00,17:00,Mon-Fri,0,0,yes\n", D(2026, 11, 2), D(2026, 11, 2))
    text = report(team, slots, {"start": "2026-11-02", "end": "2026-11-02", "duration": 60, "top": 3}, rz, w, changes)
    check("report renders table", "| 1 | Mon 2026-11-02 08:00 |" in text and "Daylight saving" in text)
    j = to_json(team, slots, None, None, changes, w, rz, 3)
    check("json output has best slots", len(j["best"]) == 3 and j["best"][0]["start_utc"] == "2026-11-02T08:00Z")
    print(f"{passed}/{total} passed")
    return 0 if passed == total else 1


def main(argv=None):
    ap = argparse.ArgumentParser(description="Find fair meeting slots across time zones")
    ap.add_argument("--team")
    ap.add_argument("--blocked")
    ap.add_argument("--start")
    ap.add_argument("--end")
    ap.add_argument("--duration", type=int, default=60)
    ap.add_argument("--step", type=int, default=30)
    ap.add_argument("--days", help="only these weekdays in --ref-zone, e.g. Tue,Wed,Thu")
    ap.add_argument("--ref-zone", default="UTC")
    ap.add_argument("--top", type=int, default=10)
    ap.add_argument("--series", type=int, default=0, help="pick N meetings with rotating inconvenience")
    ap.add_argument("--every", default="week", choices=["week", "day"], help="series spacing: one meeting per ISO week (default) or per day")
    ap.add_argument("--json", action="store_true")
    ap.add_argument("--self-test", action="store_true")
    a = ap.parse_args(argv)
    if a.self_test:
        return self_test()
    if not (a.team and a.start and a.end):
        ap.print_usage(sys.stderr)
        print("error: --team, --start and --end are required", file=sys.stderr)
        return 2
    try:
        start, end = dt.date.fromisoformat(a.start), dt.date.fromisoformat(a.end)
        team_text = open(a.team, encoding="utf-8").read()
        blocked_text = open(a.blocked, encoding="utf-8").read() if a.blocked else None
        only = parse_days(a.days) if a.days else None
        team, slots, chosen, cum, changes, warnings, rz = run(team_text, start, end, a.duration, a.step, blocked_text, a.ref_zone, a.top, a.series, only, a.every)
    except (InputError, OSError, ValueError) as e:
        print(f"error: {e}", file=sys.stderr)
        return 2
    if a.json:
        print(json.dumps(to_json(team, slots, chosen, cum, changes, warnings, rz, a.top), indent=2))
    else:
        print(report(team, slots, {"start": a.start, "end": a.end, "duration": a.duration, "top": a.top}, rz, warnings, changes, chosen, cum))
    return 0 if slots else 1


if __name__ == "__main__":
    sys.exit(main())
P@community_library
0
Previous8 / 122Next