jekyll-theme-zer0 1.28.0 → 1.30.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1143 -13
- data/_data/README.md +2 -0
- data/_data/ai.yml +5 -3
- data/_data/ai_pricing.yml +36 -0
- data/_data/backlog.yml +507 -2
- data/_data/consumers.yml +157 -9
- data/_data/features.yml +303 -20
- data/_data/feedback_types.yml +17 -12
- data/_data/i18n/fr.yml +12 -7
- data/_data/i18n/manifest.yml +39 -12
- data/_data/ingredient_densities.yml +122 -0
- data/_data/landing.yml +5 -2
- data/_data/navigation/main.yml +16 -0
- data/_data/navigation/quickstart.yml +4 -0
- data/_data/recipe_courses.yml +64 -0
- data/_data/site_builder.yml +874 -0
- data/_data/theme-manifest.yml +160 -124
- data/_data/ui-text.yml +26 -0
- data/_includes/README.md +26 -2
- data/_includes/analytics/posthog.html +2 -2
- data/_includes/components/admin-links.html +2 -2
- data/_includes/components/admin-tabs.html +2 -2
- data/_includes/components/ai-chat.html +14 -11
- data/_includes/components/analytics-dashboard.html +8 -8
- data/_includes/components/author-bio.html +1 -1
- data/_includes/components/author-card.html +10 -2
- data/_includes/components/author-eeat.html +4 -4
- data/_includes/components/background-customizer.html +10 -10
- data/_includes/components/background-image.html +114 -0
- data/_includes/components/background-settings.html +28 -15
- data/_includes/components/collection-manager.html +5 -5
- data/_includes/components/component-showcase.html +13 -13
- data/_includes/components/config-editor.html +12 -12
- data/_includes/components/config-viewer.html +8 -8
- data/_includes/components/cookie-consent.html +15 -15
- data/_includes/components/cta-button.html +7 -2
- data/_includes/components/dev-shortcuts.html +7 -7
- data/_includes/components/env-dashboard.html +8 -8
- data/_includes/components/env-switcher.html +9 -9
- data/_includes/components/feature-card.html +2 -2
- data/_includes/components/halfmoon.html +2 -2
- data/_includes/components/info-section.html +42 -37
- data/_includes/components/js-cdn.html +15 -15
- data/_includes/components/language-toggle.html +168 -21
- data/_includes/components/mermaid.html +72 -435
- data/_includes/components/nanobar.html +5 -5
- data/_includes/components/nav-editor.html +2 -2
- data/_includes/components/nav-export.html +2 -2
- data/_includes/components/nav-overview.html +2 -2
- data/_includes/components/page-feedback.html +45 -30
- data/_includes/components/page-views-init.html +55 -0
- data/_includes/components/page-views.html +33 -0
- data/_includes/components/post-card.html +22 -22
- data/_includes/components/post-type-badge.html +2 -2
- data/_includes/components/powered-by.html +2 -2
- data/_includes/components/preview-image.html +6 -0
- data/_includes/components/quick-index.html +2 -2
- data/_includes/components/recipe-card.html +67 -0
- data/_includes/components/recipe-duration.html +50 -0
- data/_includes/components/recipe-grams.html +58 -0
- data/_includes/components/recipe-index.html +96 -0
- data/_includes/components/recipe-ingredients.html +90 -0
- data/_includes/components/recipe-meta.html +96 -0
- data/_includes/components/recipe-nutrition.html +57 -0
- data/_includes/components/recipe-qty.html +73 -0
- data/_includes/components/recipe-ratio.html +151 -0
- data/_includes/components/recipe-scaler.html +73 -0
- data/_includes/components/recipe-steps.html +86 -0
- data/_includes/components/recipe-temp.html +45 -0
- data/_includes/components/search-modal.html +29 -4
- data/_includes/components/searchbar.html +2 -2
- data/_includes/components/shortcuts-modal.html +3 -0
- data/_includes/components/svg-background.html +2 -2
- data/_includes/components/theme-customizer.html +2 -2
- data/_includes/components/theme-info.html +14 -7
- data/_includes/components/theme-preview-gallery.html +22 -22
- data/_includes/content/giscus.html +2 -2
- data/_includes/content/intro.html +8 -8
- data/_includes/content/jsonld-faq.html +2 -2
- data/_includes/content/jsonld-software.html +24 -5
- data/_includes/content/seo.html +4 -4
- data/_includes/content/sitemap.html +27 -27
- data/_includes/content/toc.html +183 -183
- data/_includes/core/branding.html +6 -6
- data/_includes/core/console-capture.html +32 -74
- data/_includes/core/favicon.html +49 -7
- data/_includes/core/footer-fabs.html +17 -3
- data/_includes/core/footer.html +49 -34
- data/_includes/core/head.html +110 -86
- data/_includes/core/header.html +76 -54
- data/_includes/docs/bootstrap-docs.html +8 -8
- data/_includes/landing/landing-install-cards.html +2 -2
- data/_includes/landing/landing-quick-links.html +1 -1
- data/_includes/navigation/admin-nav.html +2 -2
- data/_includes/navigation/nav-tree.html +8 -8
- data/_includes/navigation/navbar.html +12 -12
- data/_includes/navigation/section-sidebar.html +109 -27
- data/_includes/navigation/sidebar-config.html +36 -2
- data/_includes/navigation/sidebar-left.html +17 -16
- data/_includes/navigation/sidebar-right.html +8 -7
- data/_includes/obsidian/full-graph.html +2 -2
- data/_includes/setup/claude-session.html +72 -0
- data/_includes/setup/prereq-checklist.html +90 -0
- data/_includes/setup/wizard.html +924 -222
- data/_includes/stats/stats-categories.html +8 -8
- data/_includes/stats/stats-header.html +14 -14
- data/_includes/stats/stats-metrics.html +14 -14
- data/_includes/stats/stats-no-data.html +12 -12
- data/_includes/stats/stats-overview.html +6 -6
- data/_includes/stats/stats-tags.html +8 -8
- data/_layouts/404.html +38 -24
- data/_layouts/README.md +2 -0
- data/_layouts/admin.html +24 -24
- data/_layouts/article.html +43 -33
- data/_layouts/author.html +20 -20
- data/_layouts/authors.html +2 -2
- data/_layouts/book-abc.html +12 -12
- data/_layouts/book-story.html +15 -15
- data/_layouts/book.html +12 -12
- data/_layouts/collection.html +33 -33
- data/_layouts/cookbook.html +88 -0
- data/_layouts/default.html +31 -28
- data/_layouts/home.html +23 -23
- data/_layouts/index.html +10 -10
- data/_layouts/landing.html +17 -17
- data/_layouts/news.html +44 -44
- data/_layouts/note.html +38 -38
- data/_layouts/notebook.html +34 -34
- data/_layouts/recipe.html +274 -0
- data/_layouts/root.html +92 -55
- data/_layouts/section.html +62 -33
- data/_layouts/setup.html +3 -3
- data/_layouts/sitemap-collection.html +49 -49
- data/_layouts/stats.html +40 -40
- data/_layouts/tag.html +12 -12
- data/_layouts/welcome.html +21 -21
- data/_sass/components/_callout.scss +1 -1
- data/_sass/components/_footer.scss +37 -1
- data/_sass/components/_mermaid.scss +375 -0
- data/_sass/components/_page-views.scss +36 -0
- data/_sass/components/_recipe.scss +506 -0
- data/_sass/components/_setup-wizard.scss +764 -0
- data/_sass/components/_ui-enhancements.scss +6 -6
- data/_sass/core/_navbar.scss +261 -46
- data/_sass/layouts/_landing.scss +2 -2
- data/_sass/layouts/_navbar-extras.scss +14 -4
- data/_sass/tokens/_color.scss +6 -0
- data/_sass/tokens/_index.scss +2 -0
- data/_sass/tokens/_radius.scss +21 -0
- data/_sass/tokens/_typography.scss +4 -0
- data/_sass/utilities/_focus.scss +14 -0
- data/assets/css/main.scss +4 -0
- data/assets/js/ai-chat.js +47 -5
- data/assets/js/fleet-feedback-capture.js +124 -0
- data/assets/js/fleet-feedback.js +853 -0
- data/assets/js/mermaid-diagrams.js +1267 -0
- data/assets/js/modules/navigation/config.js +9 -6
- data/assets/js/modules/navigation/navbar.js +55 -0
- data/assets/js/modules/navigation/scroll-spy.js +315 -80
- data/assets/js/modules/theme/appearance.js +8 -2
- data/assets/js/obsidian-wiki-links.js +8 -3
- data/assets/js/page-feedback.js +125 -192
- data/assets/js/page-views.js +372 -0
- data/assets/js/recipe-scaler.js +501 -0
- data/assets/js/search-modal.js +36 -0
- data/assets/js/setup-wizard.js +2279 -226
- data/assets/js/site-builder.js +1834 -0
- data/assets/js/ui-enhancements.js +11 -3
- data/scripts/README.md +44 -0
- data/scripts/ai/README.md +38 -0
- data/scripts/ai/api_call.rb +124 -0
- data/scripts/ai/usage.rb +314 -0
- data/scripts/ai/usage_report.rb +225 -0
- data/scripts/bin/audit-consumer +39 -7
- data/scripts/bin/giscus-discussions +213 -14
- data/scripts/bin/manifest +35 -12
- data/scripts/ci/agent_review_result.py +164 -0
- data/scripts/ci/test_agent_review_result.py +172 -0
- data/scripts/ci/test_visual_evidence_autogen.py +341 -0
- data/scripts/ci/visual_evidence_autogen.py +1060 -0
- data/scripts/content-review.rb +20 -1
- data/scripts/design-system-check.rb +170 -0
- data/scripts/lib/audit.sh +42 -2
- data/scripts/lint-liquid-raw.rb +137 -0
- data/scripts/test/integration/mermaid +22 -8
- data/scripts/test/lib/run_tests.sh +3 -1
- data/scripts/test/lib/test_agent_review_result.sh +27 -0
- data/scripts/test/lib/test_visual_evidence_autogen.sh +24 -0
- data/scripts/translate.rb +94 -16
- metadata +48 -2
data/assets/js/ai-chat.js
CHANGED
|
@@ -28,8 +28,10 @@
|
|
|
28
28
|
* the tool_result back, and continues the loop.
|
|
29
29
|
*
|
|
30
30
|
* Security:
|
|
31
|
-
* - Proxy mode (recommended) keeps the
|
|
32
|
-
* server-side; the browser only ever talks to the same-origin proxy
|
|
31
|
+
* - Proxy mode (recommended) keeps the provider key and GitHub token
|
|
32
|
+
* server-side; the browser only ever talks to the same-origin proxy,
|
|
33
|
+
* which answers with Claude or Grok (the reply is always Anthropic
|
|
34
|
+
* Messages SSE — the proxy translates for xAI).
|
|
33
35
|
* - Direct mode sends x-api-key from the page and requires the
|
|
34
36
|
* anthropic-dangerous-direct-browser-access header — local dev only.
|
|
35
37
|
* - GitHub "url" mode never touches a token: it opens pre-filled
|
|
@@ -586,14 +588,53 @@
|
|
|
586
588
|
|
|
587
589
|
// URL mode: open a pre-filled github.com form — the user submits it
|
|
588
590
|
// with their own account, so no token is ever needed in the browser.
|
|
589
|
-
|
|
590
|
-
|
|
591
|
+
//
|
|
592
|
+
// The URL is composed by the shared fleet builder (FleetFeedbackCore, in
|
|
593
|
+
// assets/js/fleet-feedback.js) when the page-feedback widget is enabled,
|
|
594
|
+
// which is what removed the THIRD hand-rolled issue-URL builder in this
|
|
595
|
+
// theme. Two things come with it: the same `<!-- fleet-feedback v1 -->`
|
|
596
|
+
// marker the issue pipeline reads, and a real over-budget path — this used
|
|
597
|
+
// to `.slice(0, 6000)` the body, silently dropping whatever Claude had
|
|
598
|
+
// written past that point, with nobody the wiser.
|
|
591
599
|
var body = String(inputData.body);
|
|
592
600
|
if (meta.page_url && body.indexOf(meta.page_url) === -1) {
|
|
593
601
|
body += '\n\n---\nPage: ' + meta.page_url;
|
|
594
602
|
}
|
|
595
|
-
params.set('body', body.slice(0, 6000));
|
|
596
603
|
var labels = mergedLabels(inputData.labels);
|
|
604
|
+
var title = String(inputData.title).slice(0, 256);
|
|
605
|
+
var FF = window.FleetFeedbackCore;
|
|
606
|
+
|
|
607
|
+
if (FF) {
|
|
608
|
+
var issue = {
|
|
609
|
+
title: title,
|
|
610
|
+
// The chat writes prose, not a capture, so it fills the description
|
|
611
|
+
// slot whole; only the footer is contributed by the contract.
|
|
612
|
+
sections: {
|
|
613
|
+
description: body,
|
|
614
|
+
footer: '---\n_Filed from ' + (meta.page_url || location.href) +
|
|
615
|
+
' via the AI chat assistant (fleet-feedback v' + FF.VERSION + ')._\n' +
|
|
616
|
+
'<!-- fleet-feedback v1 type=chat -->'
|
|
617
|
+
},
|
|
618
|
+
labels: labels,
|
|
619
|
+
assignees: []
|
|
620
|
+
};
|
|
621
|
+
var built = FF.buildUrl(issue, { repo: CONFIG.github.repository });
|
|
622
|
+
var win = window.open(built.url, '_blank', 'noopener');
|
|
623
|
+
if (!win) {
|
|
624
|
+
return toolResult(block.id, 'The browser blocked the pop-up, so no issue form opened. Ask the user to allow pop-ups for this site and try again.', true);
|
|
625
|
+
}
|
|
626
|
+
if (built.overBudget && navigator.clipboard && navigator.clipboard.writeText) {
|
|
627
|
+
navigator.clipboard.writeText(built.fullBody).catch(function () {});
|
|
628
|
+
return toolResult(block.id, 'A pre-filled GitHub issue form was opened in a new browser tab. The report was too long for the URL, so the full text was copied to the user clipboard — tell them to paste it over the pre-filled body before submitting.');
|
|
629
|
+
}
|
|
630
|
+
return toolResult(block.id, 'A pre-filled GitHub issue form was opened in a new browser tab. The user reviews and submits it there (a GitHub account is required).');
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// No page-feedback widget on this site, so the shared builder is not
|
|
634
|
+
// loaded. Compose the URL directly; the body is capped rather than trimmed.
|
|
635
|
+
var params = new URLSearchParams();
|
|
636
|
+
params.set('title', title);
|
|
637
|
+
params.set('body', body.slice(0, 6000));
|
|
597
638
|
if (labels.length) params.set('labels', labels.join(','));
|
|
598
639
|
window.open('https://github.com/' + CONFIG.github.repository + '/issues/new?' + params.toString(), '_blank', 'noopener');
|
|
599
640
|
return toolResult(block.id, 'A pre-filled GitHub issue form was opened in a new browser tab. The user reviews and submits it there (a GitHub account is required).');
|
|
@@ -735,6 +776,7 @@
|
|
|
735
776
|
var accumulated = '';
|
|
736
777
|
var payload = {
|
|
737
778
|
model: CONFIG.model,
|
|
779
|
+
provider: CONFIG.provider || 'anthropic', // honoured by the proxy only when that provider has a key
|
|
738
780
|
max_tokens: CONFIG.maxTokens,
|
|
739
781
|
system: buildSystemPrompt(meta),
|
|
740
782
|
messages: history.slice(),
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* fleet-feedback capture v0.2.0 — the early console/error ring buffer.
|
|
3
|
+
* Source: bamr87/bamr87 templates/feedback/ (spec: specs/FEEDBACK.md, UPS-FB-04).
|
|
4
|
+
*
|
|
5
|
+
* Load this FIRST — before any other script, as high in <head> as you can get
|
|
6
|
+
* it — so the errors that happen during page load are in the buffer by the time
|
|
7
|
+
* a reader opens the feedback dialog. fleet-feedback.js installs the same
|
|
8
|
+
* buffer if this file is absent, but by then the interesting failures have
|
|
9
|
+
* already happened silently.
|
|
10
|
+
*
|
|
11
|
+
* <script src="/assets/js/fleet-feedback-capture.js"></script> <!-- Jekyll/Django -->
|
|
12
|
+
* <Script src="/fleet-feedback-capture.js" strategy="beforeInteractive" /> <!-- Next.js -->
|
|
13
|
+
*
|
|
14
|
+
* Small enough to inline verbatim into a <script> tag when a extra request
|
|
15
|
+
* costs more than the bytes (the Jekyll adapter does exactly that).
|
|
16
|
+
*
|
|
17
|
+
* Contract — window.__fleetFeedback:
|
|
18
|
+
* logs [{ t: ISO-8601, level: 'warn'|'error'|'net', msg: string }]
|
|
19
|
+
* limit ring size (default 40)
|
|
20
|
+
* installed true once the hooks are in place; a second load is a no-op
|
|
21
|
+
* version kit version that installed it
|
|
22
|
+
* breadcrumb(level, message) push a structured entry (fetch wrappers use this)
|
|
23
|
+
* snapshot() a copy of the buffer, newest last
|
|
24
|
+
* clear() empty it
|
|
25
|
+
*
|
|
26
|
+
* Privacy: in-memory only. Never persisted, never transmitted, never read until
|
|
27
|
+
* the reader opens the dialog, previews the lines, and submits. Every entry is
|
|
28
|
+
* redacted (bearer tokens, API keys, JWTs, email addresses) and truncated.
|
|
29
|
+
*/
|
|
30
|
+
/* fleet-feedback:capture:begin — byte-identical in fleet-feedback.js (tests/contract.test.mjs asserts it) */
|
|
31
|
+
(function (root) {
|
|
32
|
+
'use strict';
|
|
33
|
+
|
|
34
|
+
var VERSION = '0.2.0';
|
|
35
|
+
var LIMIT = 40;
|
|
36
|
+
var MAX_ENTRY = 600;
|
|
37
|
+
|
|
38
|
+
var g = (root.__fleetFeedback = root.__fleetFeedback || {
|
|
39
|
+
logs: [],
|
|
40
|
+
limit: LIMIT,
|
|
41
|
+
installed: false,
|
|
42
|
+
version: VERSION
|
|
43
|
+
});
|
|
44
|
+
if (g.installed) { return; }
|
|
45
|
+
|
|
46
|
+
// Secrets end up in console output far more often than anyone expects — an
|
|
47
|
+
// Authorization header logged by a fetch wrapper, a signed URL in a 403, a
|
|
48
|
+
// user's address in a validation message. Redact BEFORE the line enters the
|
|
49
|
+
// buffer, so it can never be previewed, copied, or filed.
|
|
50
|
+
var SCRUB = [
|
|
51
|
+
// The credential can carry a scheme word of its own ("Authorization: Bearer
|
|
52
|
+
// <token>"), and a rule that stops at the scheme leaves the secret in the
|
|
53
|
+
// buffer — which is exactly what the first version of this did.
|
|
54
|
+
[/\b(authorization|proxy-authorization|bearer|token|api[-_]?key|access[-_]?token|refresh[-_]?token|client[-_]?secret|secret|password|passwd)(\s*[:=]\s*|\s+)((?:bearer|basic|digest|token)\s+)?([^\s,;"'&]{6,})/gi, '$1$2$3***'],
|
|
55
|
+
[/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]+/g, '***jwt***'],
|
|
56
|
+
[/\bgh[pousr]_[A-Za-z0-9]{16,}/g, '***github-token***'],
|
|
57
|
+
[/\bsk-[A-Za-z0-9_-]{16,}/g, '***api-key***'],
|
|
58
|
+
[/\b[\w.+-]+@[\w-]+\.[\w.-]{2,}\b/g, '***@***']
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
function redact(text) {
|
|
62
|
+
var out = String(text == null ? '' : text);
|
|
63
|
+
for (var i = 0; i < SCRUB.length; i++) {
|
|
64
|
+
out = out.replace(SCRUB[i][0], SCRUB[i][1]);
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function stringify(value) {
|
|
70
|
+
if (typeof value === 'string') { return value; }
|
|
71
|
+
if (value instanceof Error) {
|
|
72
|
+
return (value.name || 'Error') + ': ' + (value.message || '') +
|
|
73
|
+
(value.stack ? '\n' + String(value.stack).split('\n').slice(1, 4).join('\n') : '');
|
|
74
|
+
}
|
|
75
|
+
try { return JSON.stringify(value); } catch (e) { return String(value); }
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function push(level, parts) {
|
|
79
|
+
try {
|
|
80
|
+
var line = redact(parts.map(stringify).join(' '));
|
|
81
|
+
if (line.length > MAX_ENTRY) { line = line.slice(0, MAX_ENTRY) + '…'; }
|
|
82
|
+
g.logs.push({ t: new Date().toISOString(), level: level, msg: line });
|
|
83
|
+
while (g.logs.length > g.limit) { g.logs.shift(); }
|
|
84
|
+
} catch (e) { /* capture must never break the page it is watching */ }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Only warn/error are hooked. console.log is noise at this budget — 40 lines
|
|
88
|
+
// of debug chatter push the actual failure out of a ring this size.
|
|
89
|
+
if (root.console) {
|
|
90
|
+
['warn', 'error'].forEach(function (level) {
|
|
91
|
+
var original = root.console[level];
|
|
92
|
+
root.console[level] = function () {
|
|
93
|
+
push(level, Array.prototype.slice.call(arguments));
|
|
94
|
+
if (original) { return original.apply(root.console, arguments); }
|
|
95
|
+
};
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (root.addEventListener) {
|
|
100
|
+
root.addEventListener('error', function (e) {
|
|
101
|
+
if (!e) { return; }
|
|
102
|
+
var where = e.filename ? ' (' + e.filename + ':' + (e.lineno || 0) + ':' + (e.colno || 0) + ')' : '';
|
|
103
|
+
push('error', [(e.message || 'Uncaught error') + where]);
|
|
104
|
+
});
|
|
105
|
+
root.addEventListener('unhandledrejection', function (e) {
|
|
106
|
+
var reason = e && e.reason;
|
|
107
|
+
push('error', ['Unhandled promise rejection:', reason && reason.message ? reason.message : reason]);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
g.version = VERSION;
|
|
112
|
+
g.installed = true;
|
|
113
|
+
g.redact = redact;
|
|
114
|
+
/**
|
|
115
|
+
* Push a structured entry. An app's fetch wrapper calls this on a failed
|
|
116
|
+
* request so the report carries the API call that broke, not just the
|
|
117
|
+
* exception it surfaced as:
|
|
118
|
+
* FF.breadcrumb('net', 'GET /api/analysis → 502 (1243ms) req=abc123')
|
|
119
|
+
*/
|
|
120
|
+
g.breadcrumb = function (level, message) { push(level || 'net', [message]); };
|
|
121
|
+
g.snapshot = function () { return g.logs.slice(); };
|
|
122
|
+
g.clear = function () { g.logs.length = 0; };
|
|
123
|
+
})(typeof window !== 'undefined' ? window : globalThis);
|
|
124
|
+
/* fleet-feedback:capture:end */
|