@hagicode/hagilight-starlight 0.3.1 → 0.3.2-dev.57.1.ee1f17e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/AIDisclosureNotice.astro +1 -1
  2. package/ArticlePromotion.astro +1 -1
  3. package/ContentLayoutToggle.astro +2 -2
  4. package/Footer.astro +10 -2
  5. package/Header.astro +1 -1
  6. package/LanguageChooser.astro +2 -2
  7. package/MarkdownContent.astro +2 -2
  8. package/NotFoundHero.astro +1 -1
  9. package/PromotoFooter.astro +1 -1
  10. package/SEOHead.astro +2 -4
  11. package/dist/ai-disclosures.d.ts +31 -0
  12. package/dist/ai-disclosures.js +105 -0
  13. package/dist/article-promotion.d.ts +15 -0
  14. package/dist/article-promotion.js +134 -0
  15. package/dist/content-width-i18n.d.ts +6 -0
  16. package/dist/content-width-i18n.js +15 -0
  17. package/dist/content-width.d.ts +5 -0
  18. package/dist/content-width.js +42 -0
  19. package/dist/index.d.ts +58 -0
  20. package/dist/index.js +490 -0
  21. package/dist/language-routing.d.ts +18 -0
  22. package/dist/language-routing.js +95 -0
  23. package/dist/locales.d.ts +48 -0
  24. package/dist/locales.js +13 -0
  25. package/dist/not-found.d.ts +9 -0
  26. package/dist/not-found.js +28 -0
  27. package/dist/rss-renderer.d.ts +14 -0
  28. package/dist/rss-renderer.js +30 -0
  29. package/dist/rss-utils.d.ts +27 -0
  30. package/dist/rss-utils.js +65 -0
  31. package/dist/schema.d.ts +32 -0
  32. package/dist/schema.js +25 -0
  33. package/dist/seo-utils.d.ts +74 -0
  34. package/dist/seo-utils.js +219 -0
  35. package/package.json +22 -27
  36. package/rss.[language].xml.ts +1 -1
  37. package/rss.xml.ts +1 -1
  38. package/ai-disclosure-schema.d.ts +0 -8
  39. package/ai-disclosure-schema.mjs +0 -9
  40. package/ai-disclosures.mjs +0 -108
  41. package/article-promotion-schema.d.ts +0 -7
  42. package/article-promotion-schema.mjs +0 -8
  43. package/article-promotion.mjs +0 -138
  44. package/content-width-i18n.mjs +0 -16
  45. package/content-width.mjs +0 -46
  46. package/index.d.ts +0 -17
  47. package/index.mjs +0 -535
  48. package/language-routing.mjs +0 -109
  49. package/locales.d.ts +0 -8
  50. package/locales.mjs +0 -14
  51. package/not-found.mjs +0 -33
  52. package/rss-renderer.mjs +0 -31
  53. package/rss-schema.d.ts +0 -7
  54. package/rss-schema.mjs +0 -8
  55. package/rss-utils.mjs +0 -62
  56. package/seo-schema.d.ts +0 -5
  57. package/seo-schema.mjs +0 -5
  58. package/seo-utils.mjs +0 -266
@@ -1,5 +1,5 @@
1
1
  ---
2
- import { getAIDisclosureCopy } from './ai-disclosures.mjs';
2
+ import { getAIDisclosureCopy } from './dist/ai-disclosures.js';
3
3
  const { kind, lang, sourceHref } = Astro.props;
4
4
  const copy = getAIDisclosureCopy(lang);
5
5
  ---
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  import heroImage from './assets/light-main.png';
3
- import { getArticlePromotionCopy } from './article-promotion.mjs';
3
+ import { getArticlePromotionCopy } from './dist/article-promotion.js';
4
4
 
5
5
  const { lang } = Astro.props;
6
6
  const copy = getArticlePromotionCopy(lang);
@@ -1,5 +1,5 @@
1
1
  ---
2
- import { getContentWidthLabels } from './content-width-i18n.mjs';
2
+ import { getContentWidthLabels } from './dist/content-width-i18n.js';
3
3
  const { lang } = Astro.locals.starlightRoute;
4
4
  const labels = getContentWidthLabels(lang);
5
5
  ---
@@ -18,7 +18,7 @@ const labels = getContentWidthLabels(lang);
18
18
  restoreContentWidth,
19
19
  setContentWidth,
20
20
  synchronizeContentWidthFromStorage,
21
- } from './content-width.mjs';
21
+ } from './dist/content-width.js';
22
22
 
23
23
  const root = document.documentElement;
24
24
  restoreContentWidth(root);
package/Footer.astro CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- import Copyright from '@hagicode/hagilight/Copyright';
2
+ import Copyright from '@hagicode/hagilight-core/Copyright';
3
3
  import DefaultFooter from '@astrojs/starlight/components/Footer.astro';
4
- import { resolveSiteLinks, type SiteLinksOptions } from '@hagicode/hagilight/site-links';
4
+ import { resolveSiteLinks, type SiteLinksOptions } from '@hagicode/hagilight-core/links';
5
5
 
6
6
  interface Props {
7
7
  locale?: string;
@@ -17,8 +17,16 @@ const {
17
17
  rssLocaleFeedUrls,
18
18
  } = Astro.props;
19
19
  const currentLanguage = Astro.locals?.starlightRoute?.lang;
20
+ const sitemapOverride = links?.overrides?.sitemap;
20
21
  const resolvedLinks = resolveSiteLinks(currentLanguage ?? locale, {
21
22
  ...links,
23
+ overrides: {
24
+ ...links?.overrides,
25
+ sitemap: {
26
+ ...sitemapOverride,
27
+ href: sitemapOverride?.href ?? `${import.meta.env.BASE_URL}sitemap-index.xml`,
28
+ },
29
+ },
22
30
  ...(rssFeedUrl === undefined ? {} : { rssFeedUrl }),
23
31
  ...(currentLanguage && rssLocaleFeedUrls?.[currentLanguage]
24
32
  ? { rssLocaleFeedUrl: rssLocaleFeedUrls[currentLanguage] }
package/Header.astro CHANGED
@@ -4,7 +4,7 @@ import Search from 'virtual:starlight/components/Search';
4
4
  import SiteTitle from 'virtual:starlight/components/SiteTitle';
5
5
  import SocialIcons from 'virtual:starlight/components/SocialIcons';
6
6
  import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
7
- import { resolveSiteLinks, type SiteLinksOptions } from '@hagicode/hagilight/site-links';
7
+ import { resolveSiteLinks, type SiteLinksOptions } from '@hagicode/hagilight-core/links';
8
8
  import LanguageChooser from './LanguageChooser.astro';
9
9
 
10
10
  interface Props {
@@ -4,7 +4,7 @@ import context from 'virtual:starlight/project-context';
4
4
  import {
5
5
  buildLocaleNavigationTarget,
6
6
  getConfiguredLanguageOptions,
7
- } from './language-routing.mjs';
7
+ } from './dist/language-routing.js';
8
8
 
9
9
  const currentLocale = Astro.locals.starlightRoute.locale ?? config.defaultLocale?.locale ?? 'root';
10
10
  const options = getConfiguredLanguageOptions(config.locales, currentLocale);
@@ -101,7 +101,7 @@ const navigationOptions = options.map((option) => ({
101
101
  import {
102
102
  getKeyboardTargetIndex,
103
103
  persistStarlightLocaleSelection,
104
- } from './language-routing.mjs';
104
+ } from './dist/language-routing.js';
105
105
 
106
106
  class HagilightLanguageChooser extends HTMLElement {
107
107
  connectedCallback() {
@@ -7,8 +7,8 @@ import {
7
7
  getSourcePath,
8
8
  isTranslationLocale,
9
9
  resolveAIDisclosureFlags,
10
- } from './ai-disclosures.mjs';
11
- import { resolveArticlePromotion } from './article-promotion.mjs';
10
+ } from './dist/ai-disclosures.js';
11
+ import { resolveArticlePromotion } from './dist/article-promotion.js';
12
12
 
13
13
  const {
14
14
  aiDisclosures = { isAITranslation: false, isAIAuthor: false, sourceLocale: 'root' },
@@ -5,7 +5,7 @@ import {
5
5
  getNotFoundHomeHref,
6
6
  getNotFoundHomeLabel,
7
7
  isNotFoundEntry,
8
- } from './not-found.mjs';
8
+ } from './dist/not-found.js';
9
9
 
10
10
  const route = Astro.locals.starlightRoute;
11
11
  const isNotFound = isNotFoundEntry(route.entry.id);
@@ -1,5 +1,5 @@
1
1
  ---
2
- import PromotoBanner from '@hagicode/hagilight/PromotoBanner';
2
+ import PromotoBanner from '@hagicode/hagilight-core/PromotoBanner';
3
3
  import Footer from './Footer.astro';
4
4
  ---
5
5
 
package/SEOHead.astro CHANGED
@@ -1,14 +1,12 @@
1
1
  ---
2
2
  import { getCollection } from 'astro:content';
3
+ import { composeSeoHead, resolveSeoMetadata, serializeJsonLd } from '@hagicode/hagilight-core/seo';
3
4
  import {
4
5
  buildStructuredData,
5
- composeSeoHead,
6
6
  createPublishedDocsLookup,
7
7
  filterPublishedLocaleAlternates,
8
- resolveSeoMetadata,
9
8
  resolveSeoPage,
10
- serializeJsonLd,
11
- } from './seo-utils.mjs';
9
+ } from './dist/seo-utils.js';
12
10
 
13
11
  const { options } = Astro.props;
14
12
  const route = Astro.locals.starlightRoute;
@@ -0,0 +1,31 @@
1
+ export interface AIDisclosureCopy {
2
+ author: string;
3
+ translation: string;
4
+ source: string;
5
+ }
6
+ export interface AIDisclosureFlags {
7
+ isAITranslation: boolean;
8
+ isAIAuthor: boolean;
9
+ }
10
+ export interface AIDisclosureDefaults extends AIDisclosureFlags {
11
+ /** Locale route key of the original-language content, `root` by default. */
12
+ sourceLocale: string;
13
+ }
14
+ export declare const COPY: Readonly<Record<string, AIDisclosureCopy>>;
15
+ export declare function resolveAIDisclosureFlags(frontmatter: Partial<Record<keyof AIDisclosureFlags, unknown>>, defaults: AIDisclosureFlags): AIDisclosureFlags;
16
+ export declare function getAIDisclosureCopy(lang: string | undefined): AIDisclosureCopy;
17
+ export declare function getSourceEntryId(routeId: string, currentLocale: string | undefined, sourceLocale: string): string;
18
+ export declare function normalizeDocsEntryId(id: string): string;
19
+ export interface SourcePathOptions {
20
+ docs: readonly {
21
+ id: string;
22
+ }[];
23
+ routeId: string;
24
+ currentLocale: string | undefined;
25
+ sourceLocale: string;
26
+ pathname: string;
27
+ baseUrl: string;
28
+ }
29
+ export declare function getSourcePath({ docs, routeId, currentLocale, sourceLocale, pathname, baseUrl, }: SourcePathOptions): string | undefined;
30
+ export declare function isTranslationLocale(locale: string | undefined, sourceLocale: string): boolean;
31
+ export declare function buildSourcePathname(pathname: string, baseUrl: string, currentLocale: string | undefined, sourceLocale: string): string;
@@ -0,0 +1,105 @@
1
+ export const COPY = {
2
+ 'de-DE': {
3
+ author: 'Dieser Inhalt wurde mit KI-Unterstützung erstellt. Bitte prüfen Sie wichtige Angaben.',
4
+ translation: 'Dieser Beitrag wurde mit KI übersetzt.',
5
+ source: 'Original ansehen',
6
+ },
7
+ 'en-US': {
8
+ author: 'This content was created with AI assistance. Please verify important details.',
9
+ translation: 'This post was translated with AI.',
10
+ source: 'View source',
11
+ },
12
+ 'es-ES': {
13
+ author: 'Este contenido se creó con ayuda de IA. Verifica los detalles importantes.',
14
+ translation: 'Esta publicación se tradujo con IA.',
15
+ source: 'Ver original',
16
+ },
17
+ 'fr-FR': {
18
+ author: 'Ce contenu a été créé avec l’aide de l’IA. Vérifiez les informations importantes.',
19
+ translation: 'Cet article a été traduit avec l’IA.',
20
+ source: 'Voir la source',
21
+ },
22
+ 'ja-JP': {
23
+ author: 'この記事は AI の支援を受けて作成されました。重要な情報はご確認ください。',
24
+ translation: 'この記事は AI によって翻訳されました。',
25
+ source: '原文を見る',
26
+ },
27
+ 'ko-KR': {
28
+ author: '이 콘텐츠는 AI의 도움을 받아 작성되었습니다. 중요한 세부 정보는 확인해 주세요.',
29
+ translation: '이 게시물은 AI로 번역되었습니다.',
30
+ source: '원문 보기',
31
+ },
32
+ 'pt-BR': {
33
+ author: 'Este conteúdo foi criado com auxílio de IA. Confira os detalhes importantes.',
34
+ translation: 'Esta publicação foi traduzida com IA.',
35
+ source: 'Ver original',
36
+ },
37
+ 'ru-RU': {
38
+ author: 'Этот материал создан с помощью ИИ. Проверьте важные сведения.',
39
+ translation: 'Эта публикация переведена с помощью ИИ.',
40
+ source: 'Открыть оригинал',
41
+ },
42
+ 'zh-CN': {
43
+ author: '本文内容由 AI 辅助创作。请核实重要信息。',
44
+ translation: '本文由 AI 翻译。',
45
+ source: '查看原文',
46
+ },
47
+ 'zh-Hant': {
48
+ author: '本文內容由 AI 輔助創作。請核實重要資訊。',
49
+ translation: '本文由 AI 翻譯。',
50
+ source: '查看原文',
51
+ },
52
+ };
53
+ export function resolveAIDisclosureFlags(frontmatter, defaults) {
54
+ for (const key of ['isAITranslation', 'isAIAuthor']) {
55
+ if (frontmatter[key] !== undefined && typeof frontmatter[key] !== 'boolean') {
56
+ throw new TypeError(`Hagilight frontmatter ${key} must be a boolean.`);
57
+ }
58
+ if (typeof defaults[key] !== 'boolean') {
59
+ throw new TypeError(`Hagilight aiDisclosures ${key} default must be a boolean.`);
60
+ }
61
+ }
62
+ return {
63
+ isAITranslation: frontmatter.isAITranslation ?? defaults.isAITranslation,
64
+ isAIAuthor: frontmatter.isAIAuthor ?? defaults.isAIAuthor,
65
+ };
66
+ }
67
+ export function getAIDisclosureCopy(lang) {
68
+ const exact = lang === undefined ? undefined : COPY[lang];
69
+ if (exact)
70
+ return exact;
71
+ const language = lang?.split('-')[0];
72
+ return (language === undefined ? undefined : COPY[language]) ?? COPY['en-US'];
73
+ }
74
+ export function getSourceEntryId(routeId, currentLocale, sourceLocale) {
75
+ const prefix = currentLocale && currentLocale !== 'root' ? `${currentLocale}/` : '';
76
+ const routeSlug = prefix && routeId.startsWith(prefix) ? routeId.slice(prefix.length) : routeId;
77
+ if (sourceLocale === 'root')
78
+ return routeSlug === 'index' ? '' : routeSlug;
79
+ return `${sourceLocale}/${routeSlug || 'index'}`;
80
+ }
81
+ export function normalizeDocsEntryId(id) {
82
+ return id === 'index' ? '' : id;
83
+ }
84
+ export function getSourcePath({ docs, routeId, currentLocale, sourceLocale, pathname, baseUrl, }) {
85
+ const sourceId = getSourceEntryId(routeId, currentLocale, sourceLocale);
86
+ if (!docs.some((entry) => normalizeDocsEntryId(entry.id) === sourceId))
87
+ return undefined;
88
+ return buildSourcePathname(pathname, baseUrl, currentLocale, sourceLocale);
89
+ }
90
+ export function isTranslationLocale(locale, sourceLocale) {
91
+ return (locale ?? 'root') !== sourceLocale;
92
+ }
93
+ export function buildSourcePathname(pathname, baseUrl, currentLocale, sourceLocale) {
94
+ const basePath = new URL(baseUrl, 'https://hagilight.invalid').pathname;
95
+ const normalizedBase = basePath.endsWith('/') ? basePath : `${basePath}/`;
96
+ const relativePath = pathname.startsWith(normalizedBase)
97
+ ? pathname.slice(normalizedBase.length)
98
+ : pathname.startsWith('/') ? pathname.slice(1) : pathname;
99
+ const segments = relativePath.split('/');
100
+ if (currentLocale && currentLocale !== 'root' && segments[0] === currentLocale)
101
+ segments.shift();
102
+ if (sourceLocale !== 'root')
103
+ segments.unshift(sourceLocale);
104
+ return `${normalizedBase}${segments.join('/')}`;
105
+ }
@@ -0,0 +1,15 @@
1
+ export interface ArticlePromotionFeature {
2
+ label: string;
3
+ description: string;
4
+ }
5
+ export interface ArticlePromotionCopy {
6
+ title: string;
7
+ lead: string;
8
+ subheadline: string;
9
+ imageAlt: string;
10
+ features: readonly ArticlePromotionFeature[];
11
+ visitLabel: string;
12
+ }
13
+ export declare const COPY: Readonly<Record<string, ArticlePromotionCopy>>;
14
+ export declare function resolveArticlePromotion(frontmatterValue: unknown, siteDefault?: boolean): boolean;
15
+ export declare function getArticlePromotionCopy(lang: string | undefined): ArticlePromotionCopy;
@@ -0,0 +1,134 @@
1
+ export const COPY = {
2
+ 'zh-CN': {
3
+ title: 'HagiCode',
4
+ lead: 'HagiCode 是一套智能体编码工作台:结构化工作流、多 Agent 并行执行与 Hero Dungeon 视图,把想法变成真正交付的软件。',
5
+ subheadline: '让想法更快变成好用的软件,让智能编码更聪明、更高效,也更有趣。',
6
+ imageAlt: 'HagiCode 浅色主题主界面截图',
7
+ features: [
8
+ { label: 'Smart', description: '结构化工作流将意图转化为从想法到交付的可执行路径。' },
9
+ { label: 'Efficient', description: '多 Agent 工作流让调研、实现与审阅并行推进。' },
10
+ { label: 'Fun', description: 'Hero Dungeon 让长时间编码协作更直观、更有参与感。' },
11
+ ],
12
+ visitLabel: '访问 HagiCode',
13
+ },
14
+ 'en-US': {
15
+ title: 'HagiCode',
16
+ lead: 'HagiCode is an agentic coding workspace: structured workflows, multi-agent execution, and Hero Dungeon views turn ideas into shipped software.',
17
+ subheadline: 'Turn ideas into polished, usable software with a smarter, faster, and more enjoyable agentic coding workflow.',
18
+ imageAlt: 'HagiCode light theme main interface screenshot',
19
+ features: [
20
+ { label: 'Smart', description: 'Structured workflows turn intent into an executable path from idea to shipped change.' },
21
+ { label: 'Efficient', description: 'Multi-agent workflows keep research, implementation, and review moving in parallel.' },
22
+ { label: 'Fun', description: 'Hero Dungeon interfaces make long coding sessions visual, collaborative, and rewarding.' },
23
+ ],
24
+ visitLabel: 'Visit HagiCode',
25
+ },
26
+ 'zh-Hant': {
27
+ title: 'HagiCode',
28
+ lead: 'HagiCode 是智慧代理程式開發工作台,結合結構化工作流程、多代理程式執行與 Hero Dungeon 介面,將想法化為交付成果。',
29
+ subheadline: '以更聰明、更快速且更有趣的智慧代理程式工作流程,打造實用的軟體。',
30
+ imageAlt: 'HagiCode 淺色主題介面畫面',
31
+ features: [
32
+ { label: 'Smart', description: '結構化流程將意圖轉化為從構想到交付的可執行步驟。' },
33
+ { label: 'Efficient', description: '多代理程式工作流程讓研究、實作與審查並行進行。' },
34
+ { label: 'Fun', description: 'Hero Dungeon 讓長時間的程式協作更直覺、更有參與感。' },
35
+ ],
36
+ visitLabel: '造訪 HagiCode',
37
+ },
38
+ 'ja-JP': {
39
+ title: 'HagiCode',
40
+ lead: 'HagiCode は構造化ワークフロー、マルチエージェント実行、Hero Dungeon ビューを備えたエージェント型コーディングワークスペースです。',
41
+ subheadline: 'よりスマートで速く、楽しいエージェント型ワークフローで、使いやすいソフトウェアを形にします。',
42
+ imageAlt: 'HagiCode ライトテーマのメイン画面',
43
+ features: [
44
+ { label: 'Smart', description: '構造化ワークフローは意図をアイデアから変更のリリースまで実行可能な道筋にします。' },
45
+ { label: 'Efficient', description: 'マルチエージェントのワークフローで調査、実装、レビューを並行して進めます。' },
46
+ { label: 'Fun', description: 'Hero Dungeon により長時間のコーディングを視覚的で協力的な体験にします。' },
47
+ ],
48
+ visitLabel: 'HagiCode を見る',
49
+ },
50
+ 'ko-KR': {
51
+ title: 'HagiCode',
52
+ lead: 'HagiCode는 구조화된 워크플로, 다중 에이전트 실행, Hero Dungeon 뷰를 갖춘 에이전트 코딩 작업 공간입니다.',
53
+ subheadline: '더 스마트하고 빠르며 즐거운 에이전트 워크플로로 유용한 소프트웨어를 만드세요.',
54
+ imageAlt: 'HagiCode 라이트 테마 메인 화면',
55
+ features: [
56
+ { label: 'Smart', description: '구조화된 워크플로는 의도를 아이디어부터 배포까지 실행 가능한 경로로 바꿉니다.' },
57
+ { label: 'Efficient', description: '다중 에이전트 워크플로로 조사, 구현, 검토를 병렬로 진행합니다.' },
58
+ { label: 'Fun', description: 'Hero Dungeon은 긴 코딩 세션을 시각적이고 협업적인 경험으로 만듭니다.' },
59
+ ],
60
+ visitLabel: 'HagiCode 방문',
61
+ },
62
+ 'de-DE': {
63
+ title: 'HagiCode',
64
+ lead: 'HagiCode ist ein agentischer Coding-Arbeitsplatz mit strukturierten Workflows, Multi-Agent-Ausführung und Hero-Dungeon-Ansichten.',
65
+ subheadline: 'Mit einem intelligenteren, schnelleren und unterhaltsameren agentischen Workflow wird aus Ideen nutzbare Software.',
66
+ imageAlt: 'HagiCode-Hauptoberfläche im hellen Design',
67
+ features: [
68
+ { label: 'Smart', description: 'Strukturierte Workflows machen aus Absichten einen umsetzbaren Weg von der Idee bis zur Auslieferung.' },
69
+ { label: 'Efficient', description: 'Multi-Agent-Workflows führen Recherche, Umsetzung und Prüfung parallel aus.' },
70
+ { label: 'Fun', description: 'Hero Dungeon macht lange Coding-Sitzungen anschaulich und gemeinschaftlich.' },
71
+ ],
72
+ visitLabel: 'HagiCode besuchen',
73
+ },
74
+ 'fr-FR': {
75
+ title: 'HagiCode',
76
+ lead: 'HagiCode est un espace de développement agentique qui associe workflows structurés, exécution multi-agent et vues Hero Dungeon.',
77
+ subheadline: 'Transformez vos idées en logiciels utiles grâce à un workflow agentique plus intelligent, rapide et agréable.',
78
+ imageAlt: 'Interface principale de HagiCode en thème clair',
79
+ features: [
80
+ { label: 'Smart', description: 'Des workflows structurés transforment une intention en parcours exécutable, de l’idée à la livraison.' },
81
+ { label: 'Efficient', description: 'Les workflows multi-agents font avancer recherche, réalisation et revue en parallèle.' },
82
+ { label: 'Fun', description: 'Hero Dungeon rend les longues sessions de code plus visuelles et collaboratives.' },
83
+ ],
84
+ visitLabel: 'Visiter HagiCode',
85
+ },
86
+ 'es-ES': {
87
+ title: 'HagiCode',
88
+ lead: 'HagiCode es un espacio de trabajo de programación con agentes, flujos estructurados, ejecución multiagente y vistas de Hero Dungeon.',
89
+ subheadline: 'Convierte ideas en software útil con un flujo de trabajo con agentes más inteligente, rápido y ameno.',
90
+ imageAlt: 'Interfaz principal de HagiCode con tema claro',
91
+ features: [
92
+ { label: 'Smart', description: 'Los flujos estructurados convierten la intención en un itinerario ejecutable desde la idea hasta la entrega.' },
93
+ { label: 'Efficient', description: 'Los flujos multiagente permiten avanzar en paralelo con la investigación, implementación y revisión.' },
94
+ { label: 'Fun', description: 'Hero Dungeon hace que las largas sesiones de programación sean visuales y colaborativas.' },
95
+ ],
96
+ visitLabel: 'Visitar HagiCode',
97
+ },
98
+ 'pt-BR': {
99
+ title: 'HagiCode',
100
+ lead: 'HagiCode é um ambiente de programação com agentes, fluxos estruturados, execução multiagente e visualizações Hero Dungeon.',
101
+ subheadline: 'Transforme ideias em software útil com um fluxo de trabalho com agentes mais inteligente, rápido e agradável.',
102
+ imageAlt: 'Interface principal do HagiCode no tema claro',
103
+ features: [
104
+ { label: 'Smart', description: 'Fluxos estruturados transformam intenções em um caminho executável da ideia à entrega.' },
105
+ { label: 'Efficient', description: 'Fluxos multiagente mantêm pesquisa, implementação e revisão em andamento simultaneamente.' },
106
+ { label: 'Fun', description: 'O Hero Dungeon torna longas sessões de programação mais visuais e colaborativas.' },
107
+ ],
108
+ visitLabel: 'Acessar HagiCode',
109
+ },
110
+ 'ru-RU': {
111
+ title: 'HagiCode',
112
+ lead: 'HagiCode — агентная среда разработки со структурированными процессами, параллельным выполнением несколькими агентами и интерфейсами Hero Dungeon.',
113
+ subheadline: 'Превращайте идеи в полезное ПО с более умным, быстрым и увлекательным агентным рабочим процессом.',
114
+ imageAlt: 'Главный экран HagiCode в светлой теме',
115
+ features: [
116
+ { label: 'Smart', description: 'Структурированные процессы превращают намерение в исполнимый путь от идеи до готового изменения.' },
117
+ { label: 'Efficient', description: 'Мультиагентные процессы параллельно продвигают исследование, реализацию и проверку.' },
118
+ { label: 'Fun', description: 'Hero Dungeon делает длительную совместную разработку наглядной и увлекательной.' },
119
+ ],
120
+ visitLabel: 'Перейти на HagiCode',
121
+ },
122
+ };
123
+ export function resolveArticlePromotion(frontmatterValue, siteDefault = true) {
124
+ if (typeof siteDefault !== 'boolean') {
125
+ throw new TypeError('Hagilight hagicodePromotion enabled default must be a boolean.');
126
+ }
127
+ if (frontmatterValue !== undefined && typeof frontmatterValue !== 'boolean') {
128
+ throw new TypeError('Hagilight frontmatter hagicodePromotion must be a boolean.');
129
+ }
130
+ return frontmatterValue ?? siteDefault;
131
+ }
132
+ export function getArticlePromotionCopy(lang) {
133
+ return (lang === undefined ? undefined : COPY[lang]) ?? COPY['en-US'];
134
+ }
@@ -0,0 +1,6 @@
1
+ export interface ContentWidthLabels {
2
+ group: string;
3
+ wide: string;
4
+ narrow: string;
5
+ }
6
+ export declare function getContentWidthLabels(lang: string | undefined): ContentWidthLabels;
@@ -0,0 +1,15 @@
1
+ const labels = {
2
+ 'de-DE': { group: 'Inhaltsbreite', wide: 'Breit', narrow: 'Schmal' },
3
+ 'en-US': { group: 'Content width', wide: 'Wide', narrow: 'Narrow' },
4
+ 'es-ES': { group: 'Ancho del contenido', wide: 'Ancho', narrow: 'Estrecho' },
5
+ 'fr-FR': { group: 'Largeur du contenu', wide: 'Large', narrow: 'Étroit' },
6
+ 'ja-JP': { group: 'コンテンツ幅', wide: '広い', narrow: '狭い' },
7
+ 'ko-KR': { group: '콘텐츠 너비', wide: '넓게', narrow: '좁게' },
8
+ 'pt-BR': { group: 'Largura do conteúdo', wide: 'Ampla', narrow: 'Estreita' },
9
+ 'ru-RU': { group: 'Ширина содержимого', wide: 'Широкая', narrow: 'Узкая' },
10
+ 'zh-CN': { group: '内容宽度', wide: '宽', narrow: '窄' },
11
+ 'zh-Hant': { group: '內容寬度', wide: '寬', narrow: '窄' },
12
+ };
13
+ export function getContentWidthLabels(lang) {
14
+ return (lang === undefined ? undefined : labels[lang]) ?? labels['en-US'];
15
+ }
@@ -0,0 +1,5 @@
1
+ export type ContentWidthMode = 'wide' | 'narrow';
2
+ export declare const STORAGE_KEY = "hagilight-content-width";
3
+ export declare function restoreContentWidth(root?: HTMLElement): ContentWidthMode;
4
+ export declare function setContentWidth(mode: ContentWidthMode, root?: HTMLElement): void;
5
+ export declare function synchronizeContentWidthFromStorage(event: Pick<StorageEvent, 'key' | 'newValue'>, root?: HTMLElement): void;
@@ -0,0 +1,42 @@
1
+ export const STORAGE_KEY = 'hagilight-content-width';
2
+ const VALID_MODES = new Set(['wide', 'narrow']);
3
+ function normalizeMode(value) {
4
+ return VALID_MODES.has(value) ? value : 'wide';
5
+ }
6
+ function synchronizeButtons(root, mode) {
7
+ root.querySelectorAll('[data-hagilight-content-width-choice]').forEach((button) => {
8
+ button.setAttribute('aria-pressed', String(button.dataset.hagilightContentWidthChoice === mode));
9
+ });
10
+ }
11
+ export function restoreContentWidth(root = document.documentElement) {
12
+ let mode = 'wide';
13
+ try {
14
+ mode = normalizeMode(globalThis.localStorage.getItem(STORAGE_KEY));
15
+ }
16
+ catch {
17
+ mode = 'wide';
18
+ }
19
+ root.dataset.hagilightContentWidth = mode;
20
+ synchronizeButtons(root, mode);
21
+ return mode;
22
+ }
23
+ export function setContentWidth(mode, root = document.documentElement) {
24
+ if (!VALID_MODES.has(mode)) {
25
+ throw new TypeError('Hagilight content width must be "wide" or "narrow".');
26
+ }
27
+ root.dataset.hagilightContentWidth = mode;
28
+ synchronizeButtons(root, mode);
29
+ try {
30
+ globalThis.localStorage.setItem(STORAGE_KEY, mode);
31
+ }
32
+ catch {
33
+ return;
34
+ }
35
+ }
36
+ export function synchronizeContentWidthFromStorage(event, root = document.documentElement) {
37
+ if (event.key !== STORAGE_KEY && event.key !== null)
38
+ return;
39
+ const mode = normalizeMode(event.newValue);
40
+ root.dataset.hagilightContentWidth = mode;
41
+ synchronizeButtons(root, mode);
42
+ }
@@ -0,0 +1,58 @@
1
+ import type { StarlightPlugin } from '@astrojs/starlight/types';
2
+ import type { SiteLinksOptions } from '@hagicode/hagilight-core/links';
3
+ import type { AIDisclosureDefaults } from './ai-disclosures.js';
4
+ import { type RssContentOptions } from './rss-utils.js';
5
+ import { type SeoOrganization } from './seo-utils.js';
6
+ export interface HagilightToggleOptions {
7
+ enabled?: boolean;
8
+ }
9
+ export interface HagilightGoogleAnalyticsOptions {
10
+ /** Defaults to `true` when the provider options are omitted, otherwise to whether `measurementId` is set. */
11
+ enabled?: boolean;
12
+ /** Google Analytics 4 measurement ID such as `G-ABC123`. */
13
+ measurementId?: `G-${string}`;
14
+ }
15
+ export interface HagilightFiftyOneLaOptions {
16
+ /** Defaults to `true` when the provider options are omitted, otherwise to whether `siteId` is set. */
17
+ enabled?: boolean;
18
+ siteId?: string;
19
+ }
20
+ export interface HagilightAnalyticsOptions {
21
+ googleAnalytics?: HagilightGoogleAnalyticsOptions;
22
+ fiftyOneLa?: HagilightFiftyOneLaOptions;
23
+ }
24
+ export interface HagilightSeoOptions {
25
+ /** Replace Starlight's Head with Hagilight SEO metadata. Defaults to `true`; requires Astro `site`. */
26
+ enabled?: boolean;
27
+ title?: string;
28
+ description?: string;
29
+ /** Absolute HTTP(S) URL or site-root path of the default sharing image. */
30
+ image?: string;
31
+ organization?: SeoOrganization;
32
+ }
33
+ export interface HagilightRssOptions extends RssContentOptions {
34
+ /** Generate `/rss.xml` and localized feeds. Defaults to `true`; requires Astro `site`. */
35
+ enabled?: boolean;
36
+ }
37
+ export interface HagilightContentComponentsOptions {
38
+ pageTitle?: boolean;
39
+ markdownContent?: boolean;
40
+ }
41
+ export type HagilightAIDisclosureOptions = Partial<AIDisclosureDefaults>;
42
+ export interface HagilightStarlightOptions {
43
+ header?: HagilightToggleOptions;
44
+ notFoundPage?: HagilightToggleOptions;
45
+ rss?: HagilightRssOptions;
46
+ analytics?: HagilightAnalyticsOptions;
47
+ seo?: HagilightSeoOptions;
48
+ contentComponents?: HagilightContentComponentsOptions;
49
+ aiDisclosures?: HagilightAIDisclosureOptions;
50
+ /** End-of-article HagiCode introduction. */
51
+ hagicodePromotion?: HagilightToggleOptions;
52
+ /** Floating promotion banner rendered after the footer. */
53
+ promoto?: HagilightToggleOptions;
54
+ /** Header and footer link customization passed to `resolveSiteLinks`. */
55
+ links?: SiteLinksOptions;
56
+ }
57
+ /** Starlight plugin that applies HagiCode header, footer, content, SEO, RSS, and analytics customizations. */
58
+ export default function hagilight(options?: HagilightStarlightOptions): StarlightPlugin;