Soul is the frontend repository for soul.hagicode.com.
The current default homepage is the builder-first HagiSoul experience for creating, sharing, and browsing Souls.
- Builder-first default homepage: the default route opens the Soul Builder workbench directly
- Multilingual UI shell: the site header, drawers, builder panels, feedback, and accessibility labels now support
zh-CN,zh-Hant,ja-JP,ko-KR,de-DE,fr-FR,es-ES,pt-BR,ru-RU, anden-US; the public footer and promotion surface are owned by the shared Hagilight components - Locale bootstrap and persistence: the app restores the last saved
soul.locale, and on first load without a saved preference it mapsnavigator.languageinto the closest supported locale - Editor-style homepage shell: the central workbench stays visible while the left rail exposes separate
Base roleandExpressiondrawers - Single-drawer lifecycle: only one slot drawer can stay open at a time; clicking the active slot, the overlay, or pressing
Esccloses it - Local reference materials: build-time snapshots are generated from
repos/web/docsbase-role and expression catalogs - Soul-local extensions: additional expression rules may be appended inside this repo when product needs move faster than the upstream docs
- Optional remote enhancement: the runtime tries to read official inspiration cards from
/api/soul-marketplace/items; when it fails, the UI falls back to local sample cards - Copyable preview output: the current Soul preview can be copied directly once the required slots are filled
- Runtime locale switching is exposed from
src/components/site/SiteHeader.tsxthrough a visible multi-locale switcher near the theme toggle - The selected locale is persisted under the
soul.localebrowser storage key - YAML files in
src/i18n/locales-source/are the source of truth for system-owned UI copy - Generated TypeScript modules in
src/i18n/resources/are runtime artifacts and must not be hand-edited npm run dev,npm run build, andnpm run testprepare generated i18n resources before Astro, TypeScript, or Vitest consumes them- Use
npm run i18n:generateafter editing YAML andnpm run i18n:checkbefore committing translation changes - Detailed maintainer workflow is documented in
docs/i18n-hagi18n.md - Local reference materials now ship with bilingual fragment overlays, so base-role cards, expression-rule cards, and local fallback inspiration cards follow the active locale
- Official remote inspiration cards keep their upstream display names, but the Builder adds best-effort English summaries and slot content when the related local catalogs have translations
- User-authored draft text is never rewritten during runtime locale switches; only future material selections use the current locale
- The homepage keeps the
SiteHeader -> HomeEditorShellshell while the shared HagilightFooterandPromotoBannerare mounted from the Astro host (src/pages/index.astro) around the hydrated React island - The footer is
@hagicode/hagilight/Footer, which adds thePowered By hagilight@<version>attribution, theBranch/Commit/Builtline, and the sitemap and RSS links - The Astro host renders the shared footer once for the default locale and a
<template>per secondary locale, then coordinates the live footer and banner locale through adocument.documentElementlangobserver so runtime language switches stay in sync src/components/site/site-links.tsmaintains docs, website, GitHub, Discord, QQ group, email, and filing constants so link destinations stay centralized; the community and filing destinations are passed to the shared footer'slinksoption- Link destinations and filing records are assumed to match the already-published entries in
repos/siteandrepos/docs; this repo copies the structure and constants without depending on cross-repo runtime modules - The shared footer displays
闽ICP备2026004153号-1and闽公网安备35011102351148号, and both filing links keep safe external-link attributes through the Hagilight footer's filing section - The header is responsible for brand copy, site navigation, locale switching, and theme switching, but not Builder-internal actions such as preview copy or drawer lifecycle
@hagicode/hagilightand@hagicode/hagilight-coreare pinned to the same exact version (0.9.5) indevDependencies; the Soul tests read that pin frompackage.jsonastro.config.mjsregistershagilightFavicon()andhagilight()with their default options. A build generatesdist/robots.txt(which points tositemap-index.xml),dist/sitemap-index.xmlwith its child sitemap, and the feedsdist/rss.xmlanddist/rss.en.xml. The feeds are valid and currently contain no items- The shared HagiCode favicon is emitted by Astro from the package asset and linked in
src/pages/index.astro, becausehagilightFavicon()writes to the Astro config head and this page does not render it public/llms.txtis the hand-written file and is kept. The pinned@hagicode/hagilight0.9.5 does not generatellms.txt, so there is no generated file to replace it; revisit it when the pin moves to a version that generates one- Removed from
public/:robots.txt,sitemap.xml,favicon.icoandfavicon.svg./sitemap.xmlno longer exists; crawlers reach the sitemap throughrobots.txtat/sitemap-index.xml - The static head comes from
SEOHead: canonical, description, Open Graph and Twitter title/description, and theWebApplicationJSON-LD. Keywords,theme-color,author,robots,og:type/og:url/og:site_name/og:locale, andtwitter:cardare passed through itsheadprop - 51LA is loaded by
Analytics51LAinsrc/pages/index.astro, in production builds only.VITE_51LA_IDoverrides the default site ID, and that ID is used for bothidandck. The local 51LA bootstrap (src/lib/analytics) and the legacy promotion loader (src/lib/promote-loader.ts) are removed - Click tracking uses
gaEventAttributes()from@hagicode/hagilight-core/analytics-events:- header navigation links report at location
soul_header, with the link's stable id as the label (discordis reported ascommunity) - the hero documentation call to action reports at location
soul_herowith the labeldocs - in-page anchors such as
#home-workbenchare not tagged; the shared footer and banner report their own links
- header navigation links report at location
scripts/verify-ga-build.mjsruns afterastro build. It fails when the built homepage has more than one Google Analytics loader,gtag('config'), click-listener script, 51LA loader or initialization, promotion banner, or visible footer; when the footer lacks the attribution or build labels; or when a footer RSS link does not resolve to a published file
src/pages/HomePage.tsx: homepage composition root that maintains the localized slot registry and drawer content mappingsrc/components/home/HomeEditorShell.tsx: editor-style homepage shell that arranges the central workbench, slot rails, and drawer containersrc/components/home/HomeSlotRail.tsx: slot entry renderer for naming, active state, hover state, recommended state, and disabled statesrc/components/home/HomeContextDrawer.tsx: shared drawer lifecycle wrapper for overlay, close button, andEscdismissalsrc/components/builder/PreviewPanel.tsx: central workbench surface that always shows the preview and copy actionsrc/components/builder/MaterialLibraryPanel.tsx: drawer-ready material picker for theBase roleandExpressionselection flows
src/hooks/use-soul-builder.ts: domain state and side effects, including material loading, slot aggregation, preview compilation, copy behavior, and locale-safe feedback descriptorssrc/hooks/use-home-editor-state.ts: presentation state, includingactiveSlot,drawerSide,drawerOpen, and default focus behavior- Drawer state is not persisted and does not write directly into
SoulBuilderDraft - Closing a drawer does not mutate current content; only explicit Builder actions such as selecting materials, editing slots, or copying preview text trigger state changes or side effects
- Remote inspiration failures do not block homepage rendering; the core Builder flow continues on top of local snapshots
- Base roles:
repos/web/docs/50组SOUL.md核心Catalog(风格差异化+高辨识度+强适配性).md - Expression rules:
repos/web/docs/10组正交维度Catalog2(可与50组主Catalog交叉生成500个独家人设).md - Soul-local expression overrides:
scripts/reference-material-overrides.mjs - Official inspiration contract reference:
repos/web/src/services/soulMarketplaceApi.ts - Official combination rule reference:
repos/hagicode-core/src/PCode.Application/SoulMarketplace/catalog-sources.json
- Generation script:
scripts/generate-reference-materials.mjs - Generated output:
src/data/reference-materials.generated.ts - Sync command:
npm run materials:sync- Hero SOUL 模板的 canonical 输出位于
src/data/generated/agent-templates/。 - 生成命令是
npm run sync:agent-templates,脚本入口是scripts/generate-agent-templates.mjs。 - 输出内容固定包含
index.json与templates/*.json,并带有styleType、soul、tags与tagGroups。 repos/index会镜像这些 JSON 到/agent-templates/soul/**,因此 SOUL 模板正文应继续在本仓库维护,而不是在 Index 发布镜像里手工修改。
src/pages/HomePage.tsx: Builder homepage composition rootsrc/components/home/: homepage editor shell, slot rail, and drawer primitivessrc/components/builder/: material library and preview surfacesrc/components/site/SiteHeader.tsx: site navigation, locale switcher, and theme togglesrc/components/site/site-links.ts: site link and filing registrysrc/components/SoulApp.tsx: Astro React island that hydrates the existing SPAsrc/pages/index.astro: Astro host that mounts the shared Hagilight footer and bannersrc/i18n/: locale bootstrap, persistence helpers, translation resources, and translation helperssrc/lib/builder/: domain types, material repository, preview compilation, and copy-related logicsrc/data/reference-materials.generated.ts: reference material snapshotsrc/test/: Vitest setup
npm install
npm run devThe app starts with the local Astro development server.
npm run lint
npm run test
npm run build
npm run previewnpm run build runs scripts/verify-ga-build.mjs after the Astro build, so a duplicated analytics loader, banner or footer fails the build.
- Authoritative workflow:
.github/workflows/soul-deploy-gh-pages.yml - Production source of truth: the
gh-pagesbranch, published only after the build job validates the Astro build - Published payload contract: branch root
esa.jsoncplusdist/ - Required GitHub permissions: the deploy job needs
contents: write - Required hosting setting: the production host must read
gh-pages/esa.jsoncand servegh-pages/dist/ - First deploy checks: confirm the workflow uploaded
esa.jsoncanddist/, then verifyhttps://soul.hagicode.com - Rollback path: revert the source change or rerun deployment from an older commit so CI republishes the earlier snapshot
- The homepage must load without a backend; the core workflow can run entirely on local snapshots
- Official inspiration cards are an enhancement; failures cannot block homepage rendering
- Copy requires both the base-role slot and expression slot to contain content
- Theme switching currently changes visual state only and is still not persisted
- Locale preference is stored locally in the browser and is currently Soul-specific rather than shared across other HagiCode properties
- If public site links or filing information change, the static configuration in this repo should be updated to match