ai-startup-skills
创业公司做 AI 产品的 7 步 Agent Skill 合集:验证 → BP → 政策 → 路演 → 获客 → 定价 → 注册。
Translation pending
Hendingar frå lokale kalendrar samla i éi liste. Vi seier kvar dei kjem frå og når vi henta dei sist. Gratis, utan reklame.
Translation pending
OtherTypeScript · SvelteGitHub @HendingarAvailability needs another checkOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Open-source, crowdsourced event aggregation for local communities across Europe. No ads, no payments, no lock-in.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Open-source event aggregation for local communities across Europe.
Every community has vibrant local events — pub concerts, theatre, farm tours, kulturhus
gatherings, workshops, meetups. Finding them means trawling a dozen Facebook pages,
Instagram accounts and scattered websites. hendingar.no aims to be the single, open place
those events live.
Crowdsourced, geotagged, free forever. Think Lu.ma without the payments, the ads, or the
lock-in — community-owned infrastructure for public-good information.Read the full README ↗Open-source event aggregation for local communities across Europe.
Every community has vibrant local events — pub concerts, theatre, farm tours, kulturhus gatherings, workshops, meetups. Finding them means trawling a dozen Facebook pages, Instagram accounts and scattered websites. hendingar.no aims to be the single, open place those events live.
Crowdsourced, geotagged, free forever. Think Lu.ma without the payments, the ads, or the lock-in — community-owned infrastructure for public-good information.
Status: early development. Not ready for production use. Dev site: https://dev.hendingar.no · Started February 2026
/datasamling
is a public status board: every source, how it is collected, how often, and what the last run did
— and, since the same page was silent about the half of the pipeline that judges, what each of
the six checks has actually decided, how sure it was, and what the two that call a model costhttps://hendingar.no/mcp, so Claude, ChatGPT or Cursor can answer "what's on" from the listing,
with links and sources (ADR 0024)Scope discipline is a feature. hendingar.no is deliberately not:
A ticketing or payments platform — no checkout, no fees, no rent extraction. Link out to wherever tickets actually live.
A social network — no follows, no feeds, no engagement metrics, no notifications designed to pull you back in.
An ad platform — no ads and no data sales, ever. There is one analytics tracker: a
d8a collector, so we can tell whether anybody is reading this and whether it
sends them anywhere. It runs cookieless — we deny analytics_storage before the tracker
starts, so it writes nothing to your browser and cannot recognise you on a second visit. No
Google-owned script runs in the page, nothing follows you to another site, and there is no
advertising profile — but a third party does receive a page view and an IP, and saying "no
tracking" while that is true would be a lie.
Six events, and this is the whole list (app/src/lib/analytics.ts):
| Event | What it carries |
|---|---|
page_view | the page's URL and title |
view_event | event id, category, source, how many days ahead |
select_content | event id, category, which listing it was opened from |
click | the host a link went to, and whether it was a ticket or a source |
add_to_calendar | event id |
submit_result | how it was sent in, and which of the five outcomes |
Every parameter is a fact about the event, never about the reader. No search terms, no filter choices, no scroll depth, no time on page, nothing joinable back to a person. Those are the engagement metrics named two bullets up, and a non-goal is only worth having if it holds when it is inconvenient.
Automated browsers are not counted, and are not blocked either. A month of the dashboard,
filtered to the United States, was 501 page views of headless Chrome out of cloud datacentres,
in sessions exactly an hour long. The site still serves every one of those requests — an event
index that turns crawlers away has failed at its job — but reporting them makes the numbers
answer a different question from the one they are for. The filter is client-side and honest
about its limits (isAutomatedBrowser): a scraper that patches still gets
counted, and nothing running in the page can do anything about that.
Open submission invites spam, duplicates and junk. Rather than gate contributions behind accounts, every incoming event runs through six checks before it goes live. Four are rules — code with the same answer every time. Two ask a language model, because they need judgement:
| Check | How | What it asks |
|---|---|---|
| Plausibility | model | Is this a real event, or spam / a test / an ad? |
| Duplicate | rule + shortlist | Does it already exist, across venue, time and title variants? |
| Normalisation | rule | Are time, place and required fields present and well-formed? |
| Coverage | rule | Is it in a municipality we publish? |
| Categorisation | model | Does the category match the content? |
| Corroboration | rule | Can it be confirmed against a cited source? |
Coverage is the newest, and it exists because we got it wrong. A concert in Grieghallen, Bergen was submitted, passed every check — correctly; it is a real, well-formed, correctly categorised concert — and went live on a calendar for Sunnhordland, because not one of the five questions was "where is this". It has three answers rather than two: a covered place publishes, a different municipality is refused, and nothing stated is a question sent back to the sender rather than a refusal, because most people leave the kommune box empty and their events are local anyway. See ADR 0015.
A unanimous confident pass publishes immediately. Everything else is decided the same moment, with
one of five outcomes — approved, duplicate, shady, declined or contributed — because there
is no queue and nobody in it. The person who sent it in is the one who can fix it: they see which
check stopped it and why, and can correct it in /kø and send it again. A submission nobody comes
back to is deleted after 48 hours, and revising it starts that clock over.
A duplicate is an invitation, not a refusal. The events we already hold are mostly imported, and imported rows are thin — no poster, one citation, a deliberately vague category, because copying what a calendar publishes is honest and guessing at what it does not is not. So when a submission turns out to be about an event we have, the sender is offered the useful answer instead of the door: their poster, source link, ticket link, end time or description fills whatever that row is missing, they are credited on it, and no second listing appears. Only gaps are filled — a field that holds something keeps it — which is what makes it safe to let an anonymous browser write to a live page at all. See ADR 0014.
Nothing is deleted on a model's say-so while it can still be corrected: a rejected submission is stored as rejected, so a wrong call is recoverable and repeat spam has something to match against. See ADR 0012.
Every check's verdict, confidence and reasoning is stored and shown to the submitter, in Nynorsk. The reasoning is the product, not a debug log.
Two ways to submit. Upload an image — a poster on a noticeboard, a screenshot of a Facebook event, an advert in the paper — and we read the event out of it and hand you a filled-in suggestion. You review and correct it before anything is sent, and the image is downscaled in your browser, stripped of location data, read once and never stored. Or fill the form in yourself; it works without JavaScript.
Extraction is transcription, not writing, so it is pinned as close to deterministic as the API allows: temperature 0, a fixed seed, and a strict JSON schema. Two people photographing the same poster should get the same suggestion.
One API key, and it is optional. The service that calls models runs on its own managed
identity against an account with key authentication disabled — see
ADR 0008. The exception is TypeSafe's Jev, which
ranks /haugen and offers no keyless auth: its key is a secret on that one internal service and
nowhere else, and without it the page falls back to matching text. See
ADR 0022.
| Phase | ||
|---|---|---|
| 1 — Hello World | ✅ Done | SvelteKit + TypeScript, serverless on Scaleway, PostgreSQL, Woodpecker CI/CD |
| 2 — MVP | 🚧 Now | Submission form, listing + map view, search & filtering, categories, agentic verification |
| 3 — Community | ⏳ Planned | Optional accounts, moderation tooling, RSS/iCal, notifications |
Coverage today: Stord, Bømlo and Fitjar — the three municipalities in
packages/core/src/coverage.ts, which is what the coverage check enforces and the only thing that
decides where a submission can be. Bergen and Haugalandet were once written here as pilot regions
and were never covered by a source or a check; saying so cost a real submitter their event. Outward
from Sunnhordland, then across the EU — one municipality at a time, each added to that list.
Two areas we may build, on one condition — never as a commercial offering:
The line is not whether these exist but how they are obtained: earned or given, never bought. No pay-to-rank, no sponsored placement, no paid tier that unlocks them. If a feature only makes sense with a price attached, it doesn't belong here.
App: SvelteKit (TypeScript, strict) · remote functions for all client↔server calls · UnoCSS · open-source mapping (MapLibre-class, still undecided) Data: PostgreSQL + PostGIS · Drizzle for schema, types and migrations · Zod validation shared between the app and the importers Infra: Azure Container Apps (scales to zero) · Azure Database for PostgreSQL Flexible Server · Azure Container Registry · Bicep · GitHub Actions with OIDC — no stored cloud credentials
Chosen for cost, independence and — unusually — for how quickly the codebase can tell you that
you're wrong, since much of this is built with coding agents. One command (pnpm verify) is the
whole truth; types cross every boundary; each fact has exactly one source. The reasoning behind each
choice is in docs/decisions/.
Infrastructure for development is sponsored by Nordlo.
Requires Node.js 22+, pnpm 11+, and Apple's container
(brew install container) for the local database — no Docker.
git clone https://github.com/Hendingar/hendingar.no
cd hendingar.no
pnpm install
pnpm db:up # starts Postgres+PostGIS, and creates .env on first run
pnpm db:migrate
pnpm db:seed # a couple of events to look at
pnpm dev # http://localhost:5173
pnpm verify # typecheck, lint, test — run this before opening a PR
Postgres listens on 5433, not 5432, because 5432 is so often already taken and the collision shows up as a baffling authentication error against someone else's database.
Useful: pnpm db:psql, pnpm db:logs, pnpm db:reset (wipes and re-migrates; refuses to run
against anything that isn't localhost).
The container, the volume and the ports above are global to your machine, so a second worktree
running pnpm db:reset wipes the first one's database and a second pnpm dev cannot have :5173.
./.superset/setup.sh gives a worktree its own database container and its own ports, writes them
into that worktree's .env, and takes about twenty seconds; ./.superset/teardown.sh removes
them again. pnpm db:ls shows every local database and which worktree claims it, and
pnpm db:reap removes the ones nothing claims any more. Superset runs both automatically when you create and delete a
workspace, but neither script needs it — they are plain shell.
Architectural decisions are recorded in docs/decisions/ — worth a skim before
proposing a change to the stack. CLAUDE.md is the working contract for both humans and agents.
This is a community project and contributions are welcome — code, docs, design, bug reports, or event data for your own region.
Priority areas for Phase 2: submission form and validation, map view with clustering, search and filter UI, event detail pages, and the moderation queue.
Start here: CONTRIBUTING.md
Know a local calendar we should be importing from? That's the single most useful thing you can contribute — see docs/event-sources.md and open a source request.
Why open source? Local event information is public-good infrastructure. It shouldn't be controlled by for-profit platforms that optimise for engagement over community value.
Why EU-hosted? Your data should sit under strong privacy law, not a transfer agreement.
Why no payments? Events bring people together. That shouldn't be a toll booth.
Why crowdsourced? Local communities know their events best. We build the platform; you bring the knowledge.
GNU AGPL-3.0. Copyleft that reaches across the network: run a modified hendingar.no as a service and you must publish your changes. The platform stays community-owned by construction.
hendingar = "events" in Norwegian — nynorsk, to be precise. 🇳🇴
navigator.webdriverA walled garden — accounts stay optional, and everything is exportable. Leaving is easy by design.