CoOp:Anything
Search any game and see how much of it you can play with friends: every co-op mod, its stage, quality and community rating.
השחמט היפני, בעברית ומאפס. חוקים בסיסיים בשיעורים קצרים ואינטראקטיביים, בחינם ובלי הרשמה, וקהילה ישראלית של שחקני שוגי.
Translation pending
GamesTypeScript · AstroGitHub @EnterDeEtherOnlineOwner 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
שוגי ישראל — shogi.co.il
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗שוגי ישראל — shogi.co.il
The Hebrew home of shogi in Israel: a free rules course and the community hub.
Astro static site, deployed by Vercel on every push to main.
src/content/rules/ (file name = slug, e.g. 02-how-pieces-move.mdx).astro.config.mjs keeps out only lessons whose MDX is missing).MDX components available in lessons: <Step> (board beside its text), <Board sfen highlight zones reveal caption />, <Task answer hint>, <Note title>, <Term id first>, <Notation>, <Piece> (a kanji or letter inside a piece shape; use it wherever a piece label sits next to its name).
The header (desktop bar and phone panel) and the footer site map are drawn from src/lib/nav.ts.
Add a link to the right section there. An internal link shows only once its page exists in src/pages/,
so a slot for a page still being built can wait in the list and appears when the page lands.
Sections: "למדו לשחק" (lessons only), "שחקו", "הכירו את השוגי" (background reading), "כלים", "קהילה". Each section's blurb and links also draw the "מה יש באתר" cards on the home page. A section with a single live link shows as a plain link in the menu.
Every page is in sitemap-index.xml unless it sets noindex on <Base>.
A small (?) after a word the visitor may not know opens a one-line explanation with a link to the full page. Phones tap, computers point or click, keyboards use Enter and Esc.
The text of every tip is in src/lib/info-tips.ts (the header comment says how to write one). Use <InfoTip id="rank" /> (src/components/InfoTip.astro) in a page, or tipEl('rank') (src/lib/info-tip-dom.ts) inside el(...) in a screen drawn by script. src/scripts/info-tips.ts does the opening for the whole page, and the styles are at the end of src/styles/global.css.
Never put a tip inside a link, a button or a <summary>. test/info-tips.test.ts checks the texts, their links and where tips are used.
A page's link preview (og:image) is public/og/<path with dashes>.png when that file exists (/rules/03-promotion/ → rules-03-promotion.png), otherwise public/og/default.png.
The cards are written in src/lib/og-cards.ts (text, seal kanji, board). After changing one, or after adding a lesson, run npm run og (needs Playwright's Chromium) and commit the new images.
JSON-LD (site name on the home page, the course on /rules/, breadcrumbs inside /rules/, /learn/ and /tsume/) comes from src/lib/seo.ts.
dir="rtl"; the board is always dir="ltr" and never mirrors (file 9 left, file 1 right, rank 1 top).76), moves P-76; always inside <bdi dir="ltr">./privacy/ says what each collects.Email [email protected], or Instagram @shogi.israel.
The address lives in CONTACT_EMAIL in src/lib/contact.ts (re-exported from src/lib/nav.ts). Security issues: see SECURITY.md.
The contact form on /about/#contact (src/components/ContactForm.astro) posts to the Vercel Function api/contact.ts,
which checks the fields (src/lib/contact.ts) and emails them to CONTACT_EMAIL through Resend, with Reply-To set to the sender.
It needs RESEND_API_KEY in the Vercel project's environment variables (a Resend key with sending access for shogi.co.il).
Without it the form answers with an error and links to the email address.
npm install
npm run dev
/learn/)Engine ported from Lishogi's Learn module; details and file-by-file changes in src/learn/README.md.
Credit (also on the site's credits page):
src/learn/sound.ts plays every sound on the site with Web Audio (no Lishogi sounds: their sound sets are not free to reuse). The board sound is Dean's own recording of a shogi piece (public/sounds/piece.wav, 0.24 s, recorded 2026-10-27); captures, drops, promotions and check are built from it. Lessons, puzzles, games and the points toast use synthesized koto, hyoshigi and rin sounds. One setting (learn.prefs: sound, vol (default 0.8) and a switch per kind, sndBoard, sndGame, sndLessons, sndProgress, sndUi, on this device; controls in src/learn/sound-prefs.ts) in the board's cog wheel and on /account/ controls all of it; buttons, menus and switches tick (loaded on every page from Base.astro), and the first tap unlocks audio on phones; nothing plays before the visitor's first tap, on page load, or in a background tab.
/account/)Optional accounts on Supabase: email + password (confirmed by email; no Google/SSO), a public nickname, and progress that follows the account. Off until the keys exist: without them the site builds exactly as before, with no account link.
NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY (or set PUBLIC_SUPABASE_URL / PUBLIC_SUPABASE_ANON_KEY).supabase/migrations/0001_accounts.sql once (tables profiles, progress, games, with row-level security, and delete_my_account()), then 0002_community_counts.sql (the totals on /community/; counts only, callable signed out), then 0004_profiles_public_columns.sql (signed-out visitors see only nicknames and ratings), then 0005_notifications.sql (site news for the bell, and the opt-in email settings with proof of consent), then 0006_progress_upsert.sql (lets the progress upsert set user_id; without it every progress save fails), then 0007_admin_reports.sql (owner reports) and 0008_tighten_grants.sql (drops delete rights nobody uses). supabase/tests/rls.sql checks the rules.https://shogi.co.il, redirect URLs https://shogi.co.il/account/ and https://*-enterdeether.vercel.app/account/. Emails: paste supabase/templates/confirm-signup.html, reset-password.html, change-email.html and reauthentication.html into those four templates. The sign-up email carries both a 6-digit code ({{ .Token }}, typed on /account/ so the sign-in stays in the visitor's browser) and the confirmation link; keep Email OTP length at 6. The reset email links to {{ .SiteURL }}/account/?token_hash={{ .TokenHash }}&type=recovery (not {{ .ConfirmationURL }}), so it works in any browser, including when the reset was asked for from the iPhone home-screen app. Passwords (Authentication → Providers → Email): minimum length 8, required characters "No required characters" (the site itself asks for a letter, Hebrew or English, and a digit; Supabase's own option counts only English letters). If Supabase's option is stricter, /account/ explains its weak_password reasons. "Secure password change" may stay on: the page then asks for the emailed code (reauthenticate()). Before launch, set a custom SMTP sender: Supabase's built-in one sends only a few emails an hour.src/lib/account-config.ts (is it on), src/lib/account.ts (client, sign-in, sync), src/lib/progress-sync.ts (merge rules, tested). Lessons and the rules course fire / ; the sync merges (best score per level, union of finished lessons) and fires .<meta> (Astro security.csp in astro.config.mjs): scripts only from this site (inline ones pinned by hash), network only to this site and Supabase, no plugins, no foreign forms. vercel.json adds HSTS, no framing (clickjacking), nosniff, a strict referrer and a closed Permissions-Policy.supabase/tests/rls.sql checks this against the real database (run as postgres; it rolls back). Run it after every migration.src/lib/account-config.ts, overridable with PUBLIC_TURNSTILE_SITE_KEY) (the secret key lives only in Supabase → Attack Protection)./kif/)src/lib/kif.ts is the one KIF module for the site: makeKif() writes a game (start SFEN + USI moves) as a
Lishogi-compatible UTF-8 KIF, parseKif() reads one back (Shift_JIS files too, via readKifFile()), plus
downloadKif(), copyText() and LISHOGI_IMPORT_URL. Any page that plays a game should export through it.
/kif/ is the Hebrew guide to the format with a KIF viewer (src/components/KifViewer.astro). Tests: test/kif.test.ts.
progress-changedprogress-resetprogress-syncedsrc/lib/inbox.ts (a new rank, the next course step, the puzzle of the week and a streak warning, a stage left half-way, a game left open on this device), plus site news from the notices table. To post news, add a row in Supabase → Table editor → notices (title, optional body and url, optional ends_at). Read marks and the on/off switches on /account/#notifications sync with the progress (SyncedProgress.inbox)./account/#notifications (the weekly one also as an unticked box on the sign-up form). api/notify.ts runs daily from Vercel Cron (vercel.json, 17:00 UTC) and sends through Resend; the rules (at most one in 6 days, never Friday/Saturday, "come back" at 14 and 45 days then stop) are in src/lib/notify.ts. Every email carries a signed one-click unsubscribe (api/unsubscribe.ts, also as List-Unsubscribe headers). Env: CRON_SECRET (Vercel sends it to the cron, and it signs the unsubscribe links), plus the existing RESEND_API_KEY, SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY. Optional: a Resend webhook for email.bounced / email.complained to https://shogi.co.il/api/resend-webhook with its signing secret in RESEND_WEBHOOK_SECRET, which pauses nudges for that address. Check who is due without sending: curl -H "Authorization: Bearer $CRON_SECRET" "https://shogi.co.il/api/notify?dry=1"; send yourself one now: ...?user=<your user id>.api/admin-report.ts emails each new sign-up (the database pings it when a nickname is picked, migration 0007_admin_reports.sql; the ping carries no data and a fake one sends nothing), and every morning a daily report (Sundays also a weekly one) from Vercel Cron (06:00 UTC): sign-ups, who played, who moved up, one line per player by nickname, and a few insights. Changes come from a daily snapshot per player (admin_snapshots, server-only). Env: ADMIN_REPORT_EMAIL (the address, set in Vercel only) plus the ones above. Preview without sending: curl -H "Authorization: Bearer $CRON_SECRET" "https://shogi.co.il/api/admin-report?dry=1"; send this week's report now: ...?kind=weekly.syncGames() sends the device's finished games (shogi-il.play.history) to games after each shogi-il:game-end and on sign-in, deduped by the game's id; the account page counts them. profiles.rating is server-only, for future leaderboards.