From 2b47ddc12350b62a8283a73ae05a001caec63ebd Mon Sep 17 00:00:00 2001 From: Fabian Rodriguez Date: Mon, 13 Apr 2026 12:14:41 +0200 Subject: [PATCH 1/3] feat(prompts): add basic hub + prompt overview with markdown support --- app/_assets/entrypoints/hub.js | 50 ++++++++--- app/_data/schemas/frontmatter/base.json | 2 +- app/_includes/cards/prompt.html | 22 +++++ app/_includes/checkbox.html | 3 + app/_includes/product_icon.html | 6 ++ app/_includes/prompts/overview.md | 16 ++++ app/_layouts/prompts/overview.html | 5 ++ .../generators/data/search_tags/base.rb | 3 +- .../generators/data/search_tags/prompt.rb | 12 +++ app/_plugins/generators/data/title/base.rb | 2 + app/_plugins/generators/data/title/prompt.rb | 19 ++++ app/_plugins/generators/prompts.rb | 12 +++ app/_plugins/generators/prompts/generator.rb | 41 +++++++++ app/_plugins/generators/prompts/pages/base.rb | 49 ++++++++++ .../generators/prompts/pages/overview.rb | 25 ++++++ app/_plugins/generators/prompts/prompt.rb | 43 +++++++++ app/_prompts/debugging.yaml | 11 +++ app/_prompts/security.yaml | 12 +++ app/prompts.html | 89 +++++++++++++++++++ jekyll-dev.yml | 1 + 20 files changed, 407 insertions(+), 16 deletions(-) create mode 100644 app/_includes/cards/prompt.html create mode 100644 app/_includes/product_icon.html create mode 100644 app/_includes/prompts/overview.md create mode 100644 app/_layouts/prompts/overview.html create mode 100644 app/_plugins/generators/data/search_tags/prompt.rb create mode 100644 app/_plugins/generators/data/title/prompt.rb create mode 100644 app/_plugins/generators/prompts.rb create mode 100644 app/_plugins/generators/prompts/generator.rb create mode 100644 app/_plugins/generators/prompts/pages/base.rb create mode 100644 app/_plugins/generators/prompts/pages/overview.rb create mode 100644 app/_plugins/generators/prompts/prompt.rb create mode 100644 app/_prompts/debugging.yaml create mode 100644 app/_prompts/security.yaml create mode 100644 app/prompts.html diff --git a/app/_assets/entrypoints/hub.js b/app/_assets/entrypoints/hub.js index a9da8d984f..101e1410bb 100644 --- a/app/_assets/entrypoints/hub.js +++ b/app/_assets/entrypoints/hub.js @@ -11,18 +11,19 @@ class Hub { this.areFiltersOpen = false; this.deploymentTopologies = this.filters.querySelectorAll( - 'input[name="deployment-topology"]' + 'input[name="deployment-topology"]', ); this.tiers = this.filters.querySelectorAll('input[name="tier"]'); this.categories = this.filters.querySelectorAll('input[name="category"]'); this.support = this.filters.querySelectorAll('input[name="support"]'); this.trustedContent = this.filters.querySelectorAll( - 'input[name="trusted-content"]' + 'input[name="trusted-content"]', ); this.phases = this.filters.querySelectorAll('input[name="phase"]'); this.policyTargets = this.filters.querySelectorAll( - 'input[name="policy-target"]' + 'input[name="policy-target"]', ); + this.products = this.filters.querySelectorAll('input[name="product"]'); this.deploymentValues = []; this.categoryValues = []; @@ -31,6 +32,7 @@ class Hub { this.tierValues = []; this.phaseValues = []; this.policyTargetValues = []; + this.productValues = []; this.typingTimer; this.typeInterval = 400; @@ -48,6 +50,7 @@ class Hub { ...this.tiers, ...this.phases, ...this.policyTargets, + ...this.products, ]; checkboxes.forEach((checkbox) => { checkbox.addEventListener("change", () => this.onChange()); @@ -77,7 +80,7 @@ class Hub { this.seeResults.addEventListener("click", () => this.toggleDrawer()); this.toggleFiltersDrawer.addEventListener("click", () => - this.toggleDrawer() + this.toggleDrawer(), ); } @@ -95,6 +98,7 @@ class Hub { this.trustedContentValues = this.getValues(this.trustedContent); this.phaseValues = this.getValues(this.phases); this.policyTargetValues = this.getValues(this.policyTargets); + this.productValues = this.getValues(this.products); this.updateURL(); this.scrollCardsIntoView(); @@ -119,24 +123,24 @@ class Hub { const matchesDeploymentTopology = this.matchesFilter( plugin, this.deploymentTopologies, - "deploymentTopology" + "deploymentTopology", ); const matchesCategory = this.matchesFilter( plugin, this.categories, - "category" + "category", ); const matchesSupport = this.matchesFilter( plugin, this.support, - "support" + "support", ); const matchesTrustedContent = this.matchesFilter( plugin, this.trustedContent, - "trustedContent" + "trustedContent", ); const matchesPhases = this.matchesFilter(plugin, this.phases, "phases"); @@ -144,11 +148,17 @@ class Hub { const matchesPolicyTarget = this.matchesFilter( plugin, this.policyTargets, - "policyTarget" + "policyTarget", ); const matchesTier = this.matchesFilter(plugin, this.tiers, "tier"); + const matchesProducts = this.matchesFilter( + plugin, + this.products, + "products", + ); + const matchesText = this.matchesQuery(plugin); const showPlugin = @@ -159,6 +169,7 @@ class Hub { matchesTier && matchesPhases && matchesPolicyTarget && + matchesProducts && matchesText; plugin.classList.toggle("hidden", !showPlugin); @@ -172,7 +183,7 @@ class Hub { this.categories.forEach((cat) => { const category = document.getElementById(cat.value); const showCategory = category.querySelectorAll( - '[data-card="plugin"]:not(.hidden)' + '[data-card="plugin"]:not(.hidden)', ).length; category.classList.toggle("hidden", !showCategory); @@ -183,7 +194,7 @@ class Hub { const thirdParty = document.getElementById("third-party"); if (thirdParty) { const showThirdParty = thirdParty.querySelectorAll( - '[data-card="plugin"]:not(.hidden)' + '[data-card="plugin"]:not(.hidden)', ).length; thirdParty.classList.toggle("hidden", !showThirdParty); @@ -220,7 +231,7 @@ class Hub { params.delete("deployment-topology"); if (this.deploymentValues.length > 0) { this.deploymentValues.forEach((value) => - params.append("deployment-topology", value) + params.append("deployment-topology", value), ); } @@ -237,7 +248,7 @@ class Hub { params.delete("trusted-content"); if (this.trustedContentValues.length > 0) { this.trustedContentValues.forEach((value) => - params.append("trusted-content", value) + params.append("trusted-content", value), ); } @@ -260,10 +271,15 @@ class Hub { params.delete("policy-target"); if (this.policyTargetValues.length > 0) { this.policyTargetValues.forEach((value) => - params.append("policy-target", value) + params.append("policy-target", value), ); } + params.delete("product"); + if (this.productValues.length > 0) { + this.productValues.forEach((value) => params.append("product", value)); + } + let newUrl = window.location.pathname; if (params.size > 0) { newUrl += "?" + params.toString(); @@ -309,6 +325,11 @@ class Hub { checkbox.checked = policyTargetValues.includes(checkbox.value); }); + const productValues = params.getAll("product") || []; + this.products.forEach((checkbox) => { + checkbox.checked = productValues.includes(checkbox.value); + }); + const termsValue = params.get("terms") || ""; this.textInput.value = decodeURIComponent(termsValue); @@ -320,6 +341,7 @@ class Hub { tierValues.length || phaseValues.length || policyTargetValues.length || + productValues.length || termsValue ) { this.onChange(); diff --git a/app/_data/schemas/frontmatter/base.json b/app/_data/schemas/frontmatter/base.json index 2e9e2f68a7..795113ed2d 100644 --- a/app/_data/schemas/frontmatter/base.json +++ b/app/_data/schemas/frontmatter/base.json @@ -18,7 +18,7 @@ }, "content_type": { "type": "string", - "enum": ["landing_page", "how_to", "reference", "concept", "plugin", "plugin_example", "api", "policy", "support"] + "enum": ["landing_page", "how_to", "reference", "concept", "plugin", "plugin_example", "api", "policy", "support", "prompt"] }, "description": { "type": "string" diff --git a/app/_includes/cards/prompt.html b/app/_includes/cards/prompt.html new file mode 100644 index 0000000000..99c5e44213 --- /dev/null +++ b/app/_includes/cards/prompt.html @@ -0,0 +1,22 @@ +{% assign prompt = include.prompt %} +
+ +
+

{{ prompt.title | liquify }}

+ +

+ {{ prompt.description | liquify }} +

+ +
+ {% for product in prompt.products %} + {% include_cached product_icon.html product=product %} + {% endfor %} +
+
+
+
\ No newline at end of file diff --git a/app/_includes/checkbox.html b/app/_includes/checkbox.html index 1dbe68f8a6..581a819580 100644 --- a/app/_includes/checkbox.html +++ b/app/_includes/checkbox.html @@ -1,6 +1,9 @@
{% endif %} @@ -49,5 +51,5 @@ - {% endif %} +{% endif %} \ No newline at end of file diff --git a/app/_plugins/converters/syntax_highlight.rb b/app/_plugins/converters/syntax_highlight.rb index e5d63646ca..db66015168 100644 --- a/app/_plugins/converters/syntax_highlight.rb +++ b/app/_plugins/converters/syntax_highlight.rb @@ -17,13 +17,15 @@ def render_shiki(el, _indent) # rubocop:disable Metrics/AbcSize,Metrics/MethodLe id = SecureRandom.uuid snippet = CodeHighlighter.new.highlight(code, language, id) + Liquid::Template.parse(template, { line_numbers: true }).render( { 'codeblock' => { 'copy' => copy, 'css_classes' => el.attr['class'], 'collapsible' => el.attr.fetch('class', '').include?('collapsible'), - 'render_header' => !data['data-file'].nil?, + 'ask_kai' => ask_kai(data, code), + 'render_header' => !data['data-file'].nil? || !ask_kai(data, code).nil?, 'id' => id, 'data' => data, 'snippet' => snippet @@ -54,6 +56,12 @@ def data_attributes(attr) data[key] = value if key.start_with?('data-') end end + + def ask_kai(data, code) + return nil if data['data-ask-kai'].nil? + + "https://cloud.konghq.com/?agent=true&agent-prompt=#{URI.encode_www_form_component(code)}" + end end end end From 1db06840a6754165bb53f543046af2f1b4000651 Mon Sep 17 00:00:00 2001 From: Fabian Rodriguez Date: Mon, 13 Apr 2026 20:05:03 +0200 Subject: [PATCH 3/3] fix(prompt): index page and update prompt styles --- app/_includes/syntax_highlighting.html | 24 ++++++++++++++++-------- app/prompts.html | 4 ++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/app/_includes/syntax_highlighting.html b/app/_includes/syntax_highlighting.html index 98c186dfae..896f76d946 100644 --- a/app/_includes/syntax_highlighting.html +++ b/app/_includes/syntax_highlighting.html @@ -14,21 +14,26 @@ {% for data in codeblock.data %}{{ data[0] }}="{{ data[1] }}" {% endfor %} > {% if codeblock.render_header %} - {% if codeblock.data['data-file'] %}
-
{{codeblock.data['data-file']}}
-
- {% endif %} - {% if codeblock.ask_kai %} - {% endif %} {% assign show_inline_actions = false %} {% if codeblock.render_header == false and codeblock.copy %}{% assign show_inline_actions = true %}{% endif %} @@ -44,6 +49,9 @@ {% endif %} + {% if codeblock.copy %} + {{copy}} + {% endif %} {% endif %} diff --git a/app/prompts.html b/app/prompts.html index 037cbdb63b..674aebcb22 100644 --- a/app/prompts.html +++ b/app/prompts.html @@ -76,11 +76,11 @@
- {%- for prompt in site.data.prompts %}
+ {% for prompt in site.data.prompts %} {% include cards/prompt.html prompt=prompt %} + {% endfor %}
- {% endfor %}