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: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ That build:
`config/*.js` files `welcome.htm` loads directly)
- copies and minifies the xterm vendor assets
- bundles the TUI and shared config into `dist/js/tui.bundle.js`
- retains the original runtime bundle in `dist/js/app.bundle.js`
- builds the runtime bundle, then serves it and the three xterm scripts under
content-hashed names in `dist/static/` (rewriting `dist/index.html` to
match) so `_headers` can cache them immutably
- emits a minified lazy-load asset for the RickRoll animation
- generates the crawlable surface and `dist/index.html` (see below)

Expand Down
25 changes: 25 additions & 0 deletions _headers
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Cache policy for Netlify. Without this file everything is served with
# max-age=0, so every image, the video, and xterm.js were revalidated on every
# visit. Paths are matched top to bottom; the most specific rule wins.

# Fingerprinted copies of the homepage scripts (scripts/build-assets.js writes
# them as static/<name>.<hash>.js and rewrites index.html to match). A changed
# file gets a new name, so these can be cached forever.
/static/*
Cache-Control: public, max-age=31536000, immutable

# Logos, portraits, and the video change rarely and under the same name, so a
# week bounds how stale a replaced logo can be.
/images/*
Cache-Control: public, max-age=604800
/videos/*
Cache-Control: public, max-age=604800

# Unfingerprinted scripts and styles loaded by name (lazy loaders, welcome.htm,
# tui.html). An hour keeps repeat visits cheap without pinning a stale build.
/js/*
Cache-Control: public, max-age=3600
/css/*
Cache-Control: public, max-age=3600
/config/*
Cache-Control: public, max-age=3600
40 changes: 33 additions & 7 deletions config/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -678,17 +678,28 @@ const commands = {
term.stylePrint("Coming soon! ;)");
},

eval: function (args) {
term.stylePrint(
"please instead build a webstore with macros. in the meantime, the result is: " +
eval(args.join(" "))
);
},

test: function () {
_rickRoll();
},

// ── claude ──────────────────────────────────────────────────────────────────
// Looks like launching the Claude Code CLI, then declines to be one.
claude: function () {
const clay = (text) => `\x1b[38;5;209m${text}\x1b[0;38m`;
const dim = (text) => `\x1b[2m${text}\x1b[0;38m`;
const cwd = "/" + term.cwd.replaceAll("~", `home/${term.user}`);

_claudeBox([
`${clay("✻")} Welcome to Claude Code!`,
"",
" /help for help, /status for your current setup",
"",
` cwd: ${cwd}`,
]);
term.writeln("");
term.stylePrint(`${dim("※ Tip:")} We're not paying for your Claude tokens!`);
},

// ── Upgrade ─────────────────────────────────────────────────────────────────

// Animated sequence that "upgrades" the terminal to fund version 4.0.
Expand Down Expand Up @@ -946,6 +957,21 @@ function _filesHere() {
return _DIRS[term.cwd].filter((e) => e != "README.md" || term.user == "root");
}

// Draws a rounded box like the Claude Code welcome banner. Lines are padded
// to the box width; ANSI colour codes are ignored when measuring.
function _claudeBox(lines) {
const visible = (s) => s.replace(/\x1b\[[0-9;]*m/g, "").length;
const inner = Math.max(
Math.min(term.cols, 76) - 4,
...lines.map((l) => visible(l) + 1)
);
term.writeln(`╭${"─".repeat(inner + 2)}╮`);
for (const line of lines) {
term.writeln(`│ ${line}${" ".repeat(Math.max(0, inner - visible(line)))} │`);
}
term.writeln(`╰${"─".repeat(inner + 2)}╯`);
}

// ── Aliases ───────────────────────────────────────────────────────────────────
// Simple one-to-one redirects. Each alias forwards its args to the target
// command. Chains are fine — ge → great_expectations → superconductive.
Expand Down
21 changes: 11 additions & 10 deletions config/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@
// the browser's HTML entity encoding/decoding is what necessitates the
// replaceAll() calls in getFileContents().
//
// Remote files (README.md, welcome.htm) are fetched from GitHub on first load
// and inserted into the DOM the same way. Local files are inserted directly.
// Remote files (README.md, welcome.htm) are fetched from this origin the first
// time a command needs them and inserted into the DOM the same way. Local
// files are inserted directly.

// Files with hardcoded content that don't need to be fetched.
const _LOCAL_FILES = {
"id_rsa": "Nice try!",
};

// Files fetched from GitHub at startup. The key is used as the DOM element ID.
// Files fetched on demand. The key is used as the DOM element ID. Both are
// served from dist/ (the build copies README.md there), so they match the
// deployed commit and need no cross-origin request to GitHub.
const _REMOTE_FILES = {
"README.md": "https://raw.githubusercontent.com/rootvc/cli-website/main/README.md",
"welcome.htm": "https://raw.githubusercontent.com/rootvc/cli-website/main/welcome.htm",
"README.md": "/README.md",
"welcome.htm": "/welcome.htm",
};

// Combined map of all known files (used by `find`).
Expand Down Expand Up @@ -53,12 +56,10 @@ for (const [key, values] of Object.entries(_DIRS)) {
}
}

// Called at terminal init to populate the DOM with file content.
// Called at terminal init to populate the DOM with the inline files. Remote
// files are not fetched here: `cat`/`grep` await ensureFileLoaded first, so
// fetching them for every visitor only paid for the rare visitor who reads them.
function preloadFiles() {
for (const name of Object.keys(_REMOTE_FILES)) {
_loadFile(name);
}

for (const [name, content] of Object.entries(_LOCAL_FILES)) {
_insertFileToDOM(name, content);
}
Expand Down
1 change: 1 addition & 0 deletions config/help.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const help = {
"%locate%": "physical address",
"%www%": "plain-text version of this site",
"%jobs%": "check out our job openings",
"%claude%": "launch Claude Code",
"%test%": "do not use",
"%upgrade%": "upgrade to the latest version of Root Ventures",
"%other%": "try your fav commands (e.g. %ls%, %groups%, %su%)",
Expand Down
87 changes: 79 additions & 8 deletions config/portfolio.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ const portfolio = {

seam: {
name: "Seam",
url: "https://getseam.com",
url: "https://www.seam.co",
description: "Seam provides an API for managing building systems.",
},

Expand Down Expand Up @@ -226,11 +226,12 @@ const portfolio = {
"Righthook reduces the time and cost required to develop autonomous vehicles.",
},

sixwheel: {
name: "SixWheel",
url: "https://sixwheel.com",
// Formerly SixWheel.
revoy: {
name: "Revoy",
url: "https://www.revoy.com",
description:
"SixWheel brings autonomy and electrification to long haul trucking operations.",
"Revoy electrifies long haul trucking with an autonomous EV unit that rides between tractor and trailer.",
},

radical: {
Expand Down Expand Up @@ -421,11 +422,12 @@ const portfolio = {
"Loopwork is building the next generation of agents.",
},

// Formerly Feather (feather.solutions). Slug kept so /#tldr-feather resolves.
feather: {
name: "Feather",
url: "https://feather.solutions/",
name: "Finite Systems",
url: "https://finitesystems.com",
description:
"Feather provides FEA that runs in the browser.",
"Finite Systems is an applied research lab building the future of engineering tools, starting with FEA that runs in the browser.",
},

vibe_robotics: {
Expand Down Expand Up @@ -468,6 +470,75 @@ const portfolio = {
url: "https://fabro.sh/",
description:
"Lithos Computer, founded by Bryan Helmkamp, makes Fabro, a workflow harness that runs coding agents through deterministic graphs instead of a chat loop.",
},

lark: {
name: "Lark",
url: "https://lark.aero",
description: "Lark builds test tools for aerospace.",
},

flight_science: {
name: "Flight Science",
url: "https://flightscience.ai",
description:
"Flight Science is an AI aviation operations platform that helps airline dispatchers and pilots optimize fuel, avoid turbulence, and stay on time.",
},

maia: {
name: "MAIA Analytics",
url: "https://maia-analytics.com",
description:
"MAIA Analytics lets anyone query location data in plain language instead of GIS tooling.",
},

zep: {
name: "Zep",
url: "https://www.getzep.com",
description:
"Zep is a memory layer that gives AI agents persistent, structured memory across sessions.",
},

indices: {
name: "Indices",
url: "https://indices.io",
description:
"Indices turns any website into a reliable API.",
},

volund: {
name: "Volund",
url: "https://www.volundmfg.com",
description:
"Volund designs and manufactures small jet engines from first principles.",
},

lightmill: {
name: "Lightmill Systems",
url: "https://lightmill.us",
description:
"Lightmill Systems is pioneering large-format laser milling, a new way to produce precision metal parts.",
},

hexagon: {
name: "Hexagon Labs",
url: "https://joinhexagon.com",
description:
"Hexagon Labs builds Milo, an autonomous AI operating system that puts agents to work across enterprise tools and data.",
},

manzano: {
name: "Manzano Systems",
url: "https://www.manzanosystems.com",
description:
"Manzano Systems shrinks the room-sized laser systems that control quantum computers onto manufacturable photonic chips.",
},

westmag: {
name: "Western Magnetics",
url: "https://www.westmag.com",
description:
"Western Magnetics designs and manufactures electric motors for drones and actuators for robots, built with US and allied supply chains.",
}
};

Expand Down
3 changes: 0 additions & 3 deletions css/styles.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
@import url(https://fonts.googleapis.com/css?family=Abel|Source+Code+Pro&display=swap);

body, html {
height: 100%;
overflow: hidden;
}

body {
background-color: #2c2c2c;
font-family: "Abel";
margin: 0;
}

Expand Down
Binary file modified images/allspice.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/aperture.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/aperturedata.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/deepweave.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/determinate.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/digichem.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/dusty.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/feather.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/flight_science.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/fudge.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/ground_control.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/hexagon.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/illoca.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/indices.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/integrated.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/kayhan.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/kodra.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/lark.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/latent.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/lightmill.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/lithos.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/loombotic.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/loopwork.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/maia.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/manzano.jpg
Binary file modified images/oma_fertility.jpg
Binary file modified images/patterns.jpg
Binary file modified images/phyagents.jpg
Binary file modified images/quilter.jpg
Binary file added images/revoy.jpg
Binary file removed images/sixwheel.jpg
Diff not rendered.
Binary file modified images/stellar.jpg
Binary file modified images/subtrace.jpg
Binary file modified images/supertokens.jpg
Binary file modified images/vibe_robotics.jpg
Binary file added images/volund.jpg
Binary file added images/westmag.jpg
Binary file added images/zep.jpg
1 change: 0 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
and search engines discount display:none text. -->
<h1 class="visually-hidden">Root Ventures | Seeding bold engineers</h1>
<h2 class="visually-hidden">Seed stage venture capital firm investing in deep tech. San Francisco, CA</h2>
<img id="logo" src = "images/logo.png" alt="Root Ventures" style="display: none;"/>
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-TQ954FQ"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
Expand Down
6 changes: 5 additions & 1 deletion js/ascii-art.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ function _queueASCIIArtWork(task, timeout = 1000) {
}
}

// Warms the art a visitor is likely to ask for first: the firm logo and the
// team. Portfolio logos are deliberately not here — there are ~70 of them,
// several megabytes in total, and `tldr <company>` already awaits its own
// image via preloadCommandAssets before rendering, so preloading them only
// cost every visitor the download and the dithering work.
function preloadASCIIArt() {
if (asciiArtPreloadPromise) {
return asciiArtPreloadPromise;
Expand All @@ -77,7 +82,6 @@ function preloadASCIIArt() {
const specs = [
_getASCIIArtSpec("rootvc-square"),
...Object.keys(team).map((person) => _getASCIIArtSpec(person)),
...Object.keys(portfolio).map((company) => _getASCIIArtSpec(company)),
].filter(Boolean);

asciiArtPreloadPromise = window
Expand Down
2 changes: 1 addition & 1 deletion js/geo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function buildGeoPage() {
const whois = document.getElementById("whois");
whois.innerHTML = whoisRoot.split(" Try")[0];
whois.textContent = firm.blurb;

const portfolioTable = document.getElementById("portfolio");
const sortedPortfolioKeys = Object.keys(portfolio).sort((a, b) =>
Expand Down
Loading
Loading