Skip to content

Commit 640affa

Browse files
gitcommit90claude
andcommitted
site+docs: Windows ships day one, and links unfurl as share cards
Windows day-one shipping (v0.0.8 publishes the signed x64 Setup): - /download/windows resolves the newest -windows-x64-setup.exe from the latest GitHub release, same cached resolver as macOS - /docs/install/windows-wsl becomes a real install guide; /docs and /docs/getting-started drop the withheld-until-Authenticode language - README badge row, download links, platform truth table, install section, and not-yet-shipped list updated; manual FAQ says all three platforms, day one - site tests flipped to assert the Windows download exists Social sharing: - hand-drawn 1200x630 Open Graph card (captain, Skipper, the crew, "Intelligence should not be temporary") at /assets/story/og-card.png - full Open Graph + Twitter summary_large_image meta and canonical URLs on the story, manual, terms, and privacy pages - legacy template pages now share the same card instead of the square sailboat logo Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 797714f commit 640affa

10 files changed

Lines changed: 101 additions & 28 deletions

File tree

README.md

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
</p>
1313

1414
<p align="center">
15-
<a href="https://1helm.com/download/macos"><strong>Download for Apple Silicon</strong></a>
15+
<a href="https://1helm.com/download/macos"><strong>Download for Mac</strong></a>
16+
&nbsp;·&nbsp;
17+
<a href="https://1helm.com/download/windows"><strong>for Windows</strong></a>
18+
&nbsp;·&nbsp;
19+
<a href="https://1helm.com/docs/install/linux"><strong>for Linux</strong></a>
1620
&nbsp;·&nbsp;
1721
<a href="https://1helm.com">The story</a>
1822
&nbsp;·&nbsp;
@@ -30,7 +34,7 @@
3034
<code>Self-hosted</code>&nbsp;&nbsp;
3135
<code>Model-agnostic</code>&nbsp;&nbsp;
3236
<code>Signed + notarized</code>&nbsp;&nbsp;
33-
<code>macOS · Linux · Windows soon</code>
37+
<code>macOS · Windows · Linux</code>
3438
</p>
3539

3640
---
@@ -106,7 +110,9 @@ Skipper ─── crosses the boundary ─────────┘
106110
- **The computer, memory, skills, and obligations** belong to the channel and
107111
survive model changes and application restarts.
108112

109-
## Install on Apple Silicon
113+
## Install
114+
115+
On Apple Silicon:
110116

111117
1. [Download the current signed DMG](https://1helm.com/download/macos).
112118
2. Open it and drag **1Helm** to Applications.
@@ -120,11 +126,13 @@ update preserves it — credentials, databases, resident state, files, and
120126
workspaces. Profile → Check for updates asks the Mac running 1Helm—not the
121127
device displaying the web UI—to download and verify the signed update.
122128

123-
Linux hosts use a verified installer that provisions a durable systemd service
124-
with an atomic, digest-verified, health-checked updater — see the
125-
[Linux install guide](https://1helm.com/docs/install/linux). Either way, it
126-
works best on a dedicated machine: your crew works around the clock, and your
127-
everyday computer takes naps.
129+
Windows 11 x64 gets a [signed Setup executable](https://1helm.com/download/windows)
130+
that provisions one private WSL 2 world per channel. Linux hosts use a verified
131+
installer that provisions a durable systemd service with an atomic,
132+
digest-verified, health-checked updater — see the
133+
[Linux install guide](https://1helm.com/docs/install/linux). Whichever platform,
134+
it works best on a dedicated machine: your crew works around the clock, and
135+
your everyday computer takes naps.
128136

129137
## Ready on day one. Specialized by day one hundred.
130138

@@ -221,11 +229,11 @@ and an audit trail. A prompt saying “use this service” is not a connector.
221229
|---|---|
222230
| **Apple Silicon macOS 26** | Native desktop product and real isolated Linux computer per resident (Apple `container machine`, `home-mount=none`). |
223231
| **Linux / CI** | Supported headless systemd host with one unprivileged LXC per resident (subordinate UID/GID mapping, exact ownership checks); CI may select an explicit test backend. |
224-
| **Windows + WSL** | Native x64 Electron and private WSL 2 worlds (Windows-drive mounts and interop disabled) have passed real-host acceptance; the public installer awaits Authenticode signing. |
232+
| **Windows 11 x64** | Native desktop product with one private WSL 2 world per resident (Windows-drive mounts and interop disabled); the signed Setup executable ships with every release. |
225233

226-
Not yet shipped: a signed public Windows installer, a native Linux desktop
227-
shell, mobile clients, a hosted control plane, rich Photon attachment fidelity,
228-
or blind execution of community skills.
234+
Not yet shipped: a native Linux desktop shell, mobile clients, a hosted
235+
control plane, rich Photon attachment fidelity, or blind execution of
236+
community skills.
229237

230238
## Run the source workspace
231239

site/content.mjs

Lines changed: 3 additions & 3 deletions
Large diffs are not rendered by default.

site/manual.html

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
66
<meta name="description" content="The 1Helm ship's manual — quick start, the crew, channels, memory, skills, models and providers, connections, workflows, security, and FAQ.">
7+
<meta property="og:type" content="website">
8+
<meta property="og:site_name" content="1Helm">
9+
<meta property="og:title" content="1Helm — The Ship's Manual">
10+
<meta property="og:description" content="Everything you need to run your helm: quick start, the crew, channels, memory, skills, models, connections, and FAQ.">
11+
<meta property="og:url" content="https://1helm.com/manual">
12+
<meta property="og:image" content="https://1helm.com/assets/story/og-card.png">
13+
<meta property="og:image:width" content="2400">
14+
<meta property="og:image:height" content="1260">
15+
<meta name="twitter:card" content="summary_large_image">
16+
<meta name="twitter:title" content="1Helm — The Ship's Manual">
17+
<meta name="twitter:description" content="Everything you need to run your helm: quick start, the crew, channels, memory, skills, models, connections, and FAQ.">
18+
<meta name="twitter:image" content="https://1helm.com/assets/story/og-card.png">
19+
<link rel="canonical" href="https://1helm.com/manual">
720
<title>1Helm — The Ship's Manual</title>
821
<link rel="icon" type="image/png" href="/assets/story/app-icon.png">
922
<link rel="stylesheet" href="/assets/manual.css">
@@ -200,7 +213,7 @@ <h2><span class="mark">FAQ</span></h2>
200213

201214
<details>
202215
<summary>What operating systems does it run on?</summary>
203-
<p>macOS (signed Apple Silicon app), Linux (systemd install with a verified updater), and Windows via WSL&nbsp;2. Resident computers work the same way on all three — one isolated machine per agent.</p>
216+
<p>All three, day one: macOS (signed Apple Silicon app), Windows 11 (signed x64 installer with one private WSL&nbsp;2 world per agent), and Linux (systemd install with a verified updater). Resident computers work the same way everywhere — one isolated machine per agent.</p>
204217
</details>
205218

206219
<details>

site/privacy.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
66
<meta name="description" content="Privacy policy for 1helm.com and the self-hosted 1Helm software: your workspace lives on your machine.">
7+
<meta property="og:type" content="website">
8+
<meta property="og:site_name" content="1Helm">
9+
<meta property="og:title" content="1Helm — Privacy Policy">
10+
<meta property="og:description" content="1Helm is self-hosted: your workspace lives on your machine. Here's what that means.">
11+
<meta property="og:url" content="https://1helm.com/privacy">
12+
<meta property="og:image" content="https://1helm.com/assets/story/og-card.png">
13+
<meta property="og:image:width" content="2400">
14+
<meta property="og:image:height" content="1260">
15+
<meta name="twitter:card" content="summary_large_image">
16+
<meta name="twitter:title" content="1Helm — Privacy Policy">
17+
<meta name="twitter:description" content="1Helm is self-hosted: your workspace lives on your machine. Here's what that means.">
18+
<meta name="twitter:image" content="https://1helm.com/assets/story/og-card.png">
19+
<link rel="canonical" href="https://1helm.com/privacy">
720
<title>1Helm — Privacy Policy</title>
821
<link rel="icon" type="image/png" href="/assets/story/app-icon.png">
922
<link rel="stylesheet" href="/assets/manual.css">
784 KB
Loading

site/server.mjs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,22 @@ const REPO = "gitcommit90/1Helm";
2626
const RELEASE_PAGE = `https://github.com/${REPO}/releases/latest`;
2727
const RELEASE_CACHE_MS = 10 * 60_000;
2828

29-
let releaseCache = { at: 0, url: "" };
30-
async function latestDmgUrl() {
31-
if (Date.now() - releaseCache.at < RELEASE_CACHE_MS && releaseCache.url) return releaseCache.url;
29+
let releaseCache = { at: 0, assets: null };
30+
async function latestReleaseAssets() {
31+
if (Date.now() - releaseCache.at < RELEASE_CACHE_MS && releaseCache.assets) return releaseCache.assets;
3232
const response = await fetch(`https://api.github.com/repos/${REPO}/releases/latest`, {
3333
headers: { "user-agent": "1helm-site", accept: "application/vnd.github+json" },
3434
signal: AbortSignal.timeout(8000),
3535
});
3636
if (!response.ok) throw new Error(`GitHub API ${response.status}`);
3737
const release = await response.json();
38-
const asset = (release.assets || []).find((entry) => /-arm64\.dmg$/i.test(String(entry.name || "")));
39-
if (!asset?.browser_download_url) throw new Error("no arm64 DMG asset on latest release");
40-
releaseCache = { at: Date.now(), url: asset.browser_download_url };
41-
return releaseCache.url;
38+
releaseCache = { at: Date.now(), assets: release.assets || [] };
39+
return releaseCache.assets;
40+
}
41+
async function latestAssetUrl(pattern) {
42+
const asset = (await latestReleaseAssets()).find((entry) => pattern.test(String(entry.name || "")));
43+
if (!asset?.browser_download_url) throw new Error("no matching asset on latest release");
44+
return asset.browser_download_url;
4245
}
4346

4447
const mime = {
@@ -125,7 +128,13 @@ const server = createServer((req, res) => {
125128
return;
126129
}
127130
if (path === "/download/macos") {
128-
latestDmgUrl()
131+
latestAssetUrl(/-arm64\.dmg$/i)
132+
.then((url) => redirect(res, url))
133+
.catch(() => redirect(res, RELEASE_PAGE));
134+
return;
135+
}
136+
if (path === "/download/windows") {
137+
latestAssetUrl(/-windows-x64-setup\.exe$/i)
129138
.then((url) => redirect(res, url))
130139
.catch(() => redirect(res, RELEASE_PAGE));
131140
return;

site/story.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
66
<meta name="description" content="1Helm turns one computer into your own always-on AI workspace — a crew of resident agents, each with a private computer, durable memory, and real skills, reachable from any device.">
7+
<meta property="og:type" content="website">
8+
<meta property="og:site_name" content="1Helm">
9+
<meta property="og:title" content="1Helm — Intelligence should not be temporary">
10+
<meta property="og:description" content="Give every job a permanent AI crew member with its own computer, real memory, and skills that compound. Self-hosted, open source, model-agnostic.">
11+
<meta property="og:url" content="https://1helm.com/">
12+
<meta property="og:image" content="https://1helm.com/assets/story/og-card.png">
13+
<meta property="og:image:width" content="2400">
14+
<meta property="og:image:height" content="1260">
15+
<meta name="twitter:card" content="summary_large_image">
16+
<meta name="twitter:title" content="1Helm — Intelligence should not be temporary">
17+
<meta name="twitter:description" content="Give every job a permanent AI crew member with its own computer, real memory, and skills that compound. Self-hosted, open source, model-agnostic.">
18+
<meta name="twitter:image" content="https://1helm.com/assets/story/og-card.png">
19+
<link rel="canonical" href="https://1helm.com/">
720
<title>1Helm — Intelligence should not be temporary</title>
821
<link rel="icon" type="image/png" href="/assets/story/app-icon.png">
922
<link rel="stylesheet" href="/assets/story.css">

site/template.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ export function renderPage(page) {
5050
<meta property="og:title" content="${esc(title)}">
5151
<meta property="og:description" content="${esc(page.description)}">
5252
<meta property="og:url" content="${canonical}">
53-
<meta property="og:image" content="https://1helm.com/brand/1helm-sailboat.png">
53+
<meta property="og:image" content="https://1helm.com/assets/story/og-card.png">
54+
<meta name="twitter:image" content="https://1helm.com/assets/story/og-card.png">
5455
<meta name="twitter:card" content="summary_large_image">
5556
<link rel="canonical" href="${canonical}">
5657
<link rel="icon" href="/brand/1helm-sailboat.png" type="image/png">

site/terms.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
66
<meta name="description" content="Terms of service for the 1Helm website and the open-source, self-hosted 1Helm software.">
7+
<meta property="og:type" content="website">
8+
<meta property="og:site_name" content="1Helm">
9+
<meta property="og:title" content="1Helm — Terms of Service">
10+
<meta property="og:description" content="Terms for the 1Helm website and the open-source, self-hosted 1Helm software.">
11+
<meta property="og:url" content="https://1helm.com/terms">
12+
<meta property="og:image" content="https://1helm.com/assets/story/og-card.png">
13+
<meta property="og:image:width" content="2400">
14+
<meta property="og:image:height" content="1260">
15+
<meta name="twitter:card" content="summary_large_image">
16+
<meta name="twitter:title" content="1Helm — Terms of Service">
17+
<meta name="twitter:description" content="Terms for the 1Helm website and the open-source, self-hosted 1Helm software.">
18+
<meta name="twitter:image" content="https://1helm.com/assets/story/og-card.png">
19+
<link rel="canonical" href="https://1helm.com/terms">
720
<title>1Helm — Terms of Service</title>
821
<link rel="icon" type="image/png" href="/assets/story/app-icon.png">
922
<link rel="stylesheet" href="/assets/manual.css">

test/site.mjs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@ test("standalone 1helm.com website serves independent product and documentation
2727
const privacy = await (await fetch(`${base}/privacy`)).text();
2828
assert.match(privacy, /build@1helm\.com/);
2929
assert.match(home, /build@1helm\.com/);
30+
assert.match(home, /og:image/);
31+
assert.match(home, /assets\/story\/og-card\.png/);
3032
for (const path of ["/manual", "/terms", "/privacy", "/product", "/manifesto", "/security", "/faq", "/docs", "/docs/install/macos", "/docs/install/linux", "/docs/install/windows-wsl", "/docs/skills", "/docs/verification", "/docs/connections"]) {
3133
const response = await fetch(base + path); assert.equal(response.status, 200, path);
3234
assert.match(response.headers.get("content-security-policy") || "", /default-src 'self'/);
3335
}
3436
const gettingStarted = await (await fetch(`${base}/docs/getting-started`)).text();
35-
assert.match(gettingStarted, /Windows 11 x64 implementation is accepted.*public Setup executable is withheld.*Authenticode/is);
36-
assert.doesNotMatch(gettingStarted, /On Windows 11 x64, download the signed Setup executable/i);
37+
assert.match(gettingStarted, /On Windows 11 x64, download the signed Setup executable/i);
38+
assert.doesNotMatch(gettingStarted, /withheld/i);
3739
assert.equal((await fetch(`${base}/assets/site.css`)).status, 200);
3840
const windowsIcon = await fetch(`${base}/icons/icon-sailboat.ico`);
3941
assert.equal(windowsIcon.status, 200);
@@ -49,7 +51,8 @@ test("standalone 1helm.com website serves independent product and documentation
4951
assert.equal(download.status, 302);
5052
assert.match(download.headers.get("location") || "", /1Helm-[\d.]+-arm64\.dmg$|\/releases\/latest$/);
5153
const windowsDownload = await fetch(`${base}/download/windows`, { redirect: "manual" });
52-
assert.equal(windowsDownload.status, 404, "the website never advertises a Windows artifact before a signed build exists");
54+
assert.equal(windowsDownload.status, 302);
55+
assert.match(windowsDownload.headers.get("location") || "", /-windows-x64-setup\.exe$|\/releases\/latest$/);
5356
} finally { child.kill("SIGTERM"); await new Promise((resolve) => child.once("exit", resolve)); }
5457
});
5558

0 commit comments

Comments
 (0)