Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions site-src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ npx wrangler pages deploy site --project-name askkey --branch main \
Wrangler reads a Cloudflare API token with Pages write access from `CLOUDFLARE_API_TOKEN` and the account from `CLOUDFLARE_ACCOUNT_ID`. Never put the token in a file, an argument or a log.

Before deploying, run `npm run stamp` in `how/` if any CSS or JS changed, so pages never pair with a cached old file, and check both pages in a browser.

## Search and sharing

`site/robots.txt` points crawlers to `site/sitemap.xml`; update its `lastmod` dates when the pages change. `site/_headers` sets Cloudflare Pages response headers: the `askkey.pages.dev` mirror is marked `noindex`, hashed stylesheets, scripts and fonts are cached for a year, and pictures for a week. Each page carries its canonical URL, `hreflang` alternates, Open Graph and X card tags with its own share image (`site/assets/og-*.jpg`), and `SoftwareApplication` structured data.
2 changes: 1 addition & 1 deletion site-src/how/stamp.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { readFileSync, writeFileSync } from "node:fs";
const site = new URL("../../site/", import.meta.url);
const files = ["style.css", "motion.js", "how/how.css", "how/how.js"];
const hash = Object.fromEntries(files.map((f) => [f, createHash("sha256").update(readFileSync(new URL(f, site))).digest("hex").slice(0, 10)]));
for (const page of ["index.html", "zh/index.html"]) {
for (const page of ["index.html", "zh/index.html", "404.html"]) {
const url = new URL(page, site);
let html = readFileSync(url, "utf8");
for (const f of files) {
Expand Down
2 changes: 1 addition & 1 deletion site/404.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<title>页面不存在 · Page not found — Ask Key</title>
<meta name="robots" content="noindex">
<link rel="icon" href="/assets/favicon-64.png" type="image/png">
<link rel="stylesheet" href="/style.css">
<link rel="stylesheet" href="/style.css?v=6a97785f0c">
<style>
.lost { min-height: 100svh; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 22px; padding: 48px var(--gutter); text-align: center; }
.lost img { width: 72px; height: 72px; }
Expand Down
25 changes: 25 additions & 0 deletions site/_headers
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Cloudflare Pages response headers.

# The pages.dev address is a mirror of askkey.sudohg.com; keep it out of
# search results so the custom domain is the only one indexed.
https://askkey.pages.dev/*
X-Robots-Tag: noindex

# Stylesheets and scripts are linked with a content hash (?v=…), so a
# changed file always has a new URL and the old one can be kept forever.
/style.css
Cache-Control: public, max-age=31536000, immutable
/motion.js
Cache-Control: public, max-age=31536000, immutable
/how/how.css
Cache-Control: public, max-age=31536000, immutable
/how/how.js
Cache-Control: public, max-age=31536000, immutable
/fonts/*
Cache-Control: public, max-age=31536000, immutable

# Pictures keep their names when they change, so cache them for a week.
/assets/*
Cache-Control: public, max-age=604800
/how/img/*
Cache-Control: public, max-age=604800
Binary file added site/favicon.ico
Binary file not shown.
39 changes: 38 additions & 1 deletion site/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,26 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ask Key — the Mac key manager for AI</title>
<meta name="description" content="Ask Key is the Mac key manager for AI. Your AI agents look up the keys they need without you pointing the way; everyday keys pass while sensitive ones wait for your approval; keys go only to the program, never to the AI. Free and open source.">
<meta name="description" content="Ask Key, the free Mac key manager for AI. Agents find keys themselves, sensitive ones wait for your approval, and keys go only to the program, never to the AI.">
<link rel="canonical" href="https://askkey.sudohg.com/">
<link rel="alternate" hreflang="en" href="https://askkey.sudohg.com/">
<link rel="alternate" hreflang="zh-Hans" href="https://askkey.sudohg.com/zh/">
<link rel="alternate" hreflang="x-default" href="https://askkey.sudohg.com/">
<meta property="og:title" content="Ask Key — the Mac key manager for AI">
<meta property="og:description" content="The Mac key manager for AI. AI agents find keys themselves, sensitive ones wait for your approval, and keys go only to the program, never to the AI.">
<meta property="og:url" content="https://askkey.sudohg.com/">
<meta property="og:type" content="website">
<meta property="og:site_name" content="Ask Key">
<meta property="og:locale" content="en_US">
<meta property="og:locale:alternate" content="zh_CN">
<meta property="og:image" content="https://askkey.sudohg.com/assets/og-en.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="Ask Key: No key leaves without your seal. The Mac key manager for AI.">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image:alt" content="Ask Key: No key leaves without your seal. The Mac key manager for AI.">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" type="image/png" href="/assets/favicon-64.png">
<link rel="apple-touch-icon" href="/assets/apple-touch-icon.png">
<link rel="preload" href="/assets/hero-desk.jpg" as="image">
Expand All @@ -26,6 +32,37 @@
<link rel="stylesheet" href="/how/how.css?v=68de86ac7c">
<script type="module" src="/how/how.js?v=28dba282cc"></script>
<script src="/motion.js?v=09073b35d1" defer></script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Ask Key",
"alternateName": "请旨",
"url": "https://askkey.sudohg.com/",
"description": "The Mac key manager for AI: agents find the keys they need, everyday keys pass, sensitive ones wait for your approval, and keys go only to the program, never to the AI.",
"inLanguage": "en",
"applicationCategory": "DeveloperApplication",
"operatingSystem": "macOS 14 or later (Apple silicon)",
"isAccessibleForFree": true,
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
},
"downloadUrl": "https://github.com/sudoHG/AskKey/releases/latest/download/AskKey.dmg",
"license": "https://github.com/sudoHG/AskKey/blob/main/LICENSE",
"image": "https://askkey.sudohg.com/assets/icon-256.png",
"screenshot": "https://askkey.sudohg.com/assets/og-en.jpg",
"sameAs": [
"https://github.com/sudoHG/AskKey"
],
"author": {
"@type": "Person",
"name": "sudoHG",
"url": "https://github.com/sudoHG"
}
}
</script>
</head>
<body>
<header class="hero">
Expand Down
4 changes: 4 additions & 0 deletions site/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
User-agent: *
Allow: /

Sitemap: https://askkey.sudohg.com/sitemap.xml
17 changes: 17 additions & 0 deletions site/sitemap.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>https://askkey.sudohg.com/</loc>
<lastmod>2026-10-13</lastmod>
<xhtml:link rel="alternate" hreflang="en" href="https://askkey.sudohg.com/"/>
<xhtml:link rel="alternate" hreflang="zh-Hans" href="https://askkey.sudohg.com/zh/"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://askkey.sudohg.com/"/>
</url>
<url>
<loc>https://askkey.sudohg.com/zh/</loc>
<lastmod>2026-10-13</lastmod>
<xhtml:link rel="alternate" hreflang="en" href="https://askkey.sudohg.com/"/>
<xhtml:link rel="alternate" hreflang="zh-Hans" href="https://askkey.sudohg.com/zh/"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://askkey.sudohg.com/"/>
</url>
</urlset>
37 changes: 37 additions & 0 deletions site/zh/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,60 @@
<link rel="canonical" href="https://askkey.sudohg.com/zh/">
<link rel="alternate" hreflang="en" href="https://askkey.sudohg.com/">
<link rel="alternate" hreflang="zh-Hans" href="https://askkey.sudohg.com/zh/">
<link rel="alternate" hreflang="x-default" href="https://askkey.sudohg.com/">
<meta property="og:title" content="请旨 Ask Key:给 AI 用的 Mac 密钥管家">
<meta property="og:description" content="给 AI 用的 Mac 密钥管家。AI 自己找得到密钥;普通密钥直接放行,敏感密钥由你审批;密钥只交给目标程序,AI 看不到明文。">
<meta property="og:url" content="https://askkey.sudohg.com/zh/">
<meta property="og:type" content="website">
<meta property="og:site_name" content="请旨 Ask Key">
<meta property="og:locale" content="zh_CN">
<meta property="og:locale:alternate" content="en_US">
<meta property="og:image" content="https://askkey.sudohg.com/assets/og-zh.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="请旨 Ask Key:取用密钥,先来请旨。给 AI 用的 Mac 密钥管家。">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image:alt" content="请旨 Ask Key:取用密钥,先来请旨。给 AI 用的 Mac 密钥管家。">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" type="image/png" href="/assets/favicon-64.png">
<link rel="apple-touch-icon" href="/assets/apple-touch-icon.png">
<link rel="preload" href="/assets/hero-desk.jpg" as="image">
<link rel="stylesheet" href="/style.css?v=6a97785f0c">
<link rel="stylesheet" href="/how/how.css?v=68de86ac7c">
<script type="module" src="/how/how.js?v=28dba282cc"></script>
<script src="/motion.js?v=09073b35d1" defer></script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Ask Key",
"alternateName": "请旨",
"url": "https://askkey.sudohg.com/zh/",
"description": "给 AI 用的 Mac 密钥管家:AI 自己找得到密钥,普通密钥直接放行,敏感密钥由你审批,密钥只交给目标程序,AI 看不到明文。",
"inLanguage": "zh-Hans",
"applicationCategory": "DeveloperApplication",
"operatingSystem": "macOS 14 or later (Apple silicon)",
"isAccessibleForFree": true,
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
},
"downloadUrl": "https://github.com/sudoHG/AskKey/releases/latest/download/AskKey.dmg",
"license": "https://github.com/sudoHG/AskKey/blob/main/LICENSE",
"image": "https://askkey.sudohg.com/assets/icon-256.png",
"screenshot": "https://askkey.sudohg.com/assets/og-zh.jpg",
"sameAs": [
"https://github.com/sudoHG/AskKey"
],
"author": {
"@type": "Person",
"name": "sudoHG",
"url": "https://github.com/sudoHG"
}
}
</script>
</head>
<body>
<header class="hero">
Expand Down
Loading