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
2 changes: 1 addition & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["@caplets/landing"]
"ignore": ["@caplets/landing", "@caplets/docs"]
}
5 changes: 5 additions & 0 deletions .changeset/fresh-rings-attach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@caplets/core": minor
---

Add remote attach URL configuration and update the native remote attach flow.
1 change: 1 addition & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
- .github/workflows/deploy.yml
- alchemy.run.ts
- apps/**
- infra/**
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pr-preview-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
- .github/workflows/pr-preview-deploy.yml
- alchemy.run.ts
- apps/**
- infra/**
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml
Expand Down
2 changes: 2 additions & 0 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ The system is product-first: precise, calm, capable. It should feel like an expe

The physical scene is a developer reviewing an agent setup at a desk during focused work, with docs, terminal output, and a browser open side by side. The theme stays light and warm because this surface is read for long stretches, compared with documentation, and used during configuration rather than incident response.

The public landing page may invert into a dark aperture treatment for the hero, benchmark proof, and route-map storytelling. That exception is campaign art direction, not the default product UI theme: keep it precise, sparse, and tied to the capability-exposure metaphor rather than neon terminal cosplay.

**Key Characteristics:**

- Warm light surfaces with ink-like text and a rare ember accent.
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

<p>
<a href="https://caplets.dev"><strong>caplets.dev</strong></a>
·
<a href="https://docs.caplets.dev"><strong>docs.caplets.dev</strong></a>
</p>
</div>

Expand All @@ -38,6 +40,8 @@ Caplets can wrap:

## Quick Start

Full setup and configuration docs are available at [docs.caplets.dev](https://docs.caplets.dev/).

Install the CLI and wire it into your agent:

```sh
Expand Down Expand Up @@ -170,6 +174,7 @@ tokens than direct vanilla MCP. Live runs are model- and environment-dependent;
deterministic benchmark is the reproducible claim.

See [docs/benchmarks/coding-agent.md](https://github.com/spiritledsoftware/caplets/blob/main/docs/benchmarks/coding-agent.md) for methodology and reproduction commands.
See [docs.caplets.dev/changelog](https://docs.caplets.dev/changelog/) for public release notes.

## Repository

Expand Down Expand Up @@ -200,6 +205,7 @@ Package map:
- `packages/pi` - native Pi extension
- `packages/benchmarks` - deterministic and opt-in live benchmarks
- `apps/landing` - public site at `caplets.dev`
- `apps/docs` - public docs site at `docs.caplets.dev`

Long-lived docs:

Expand Down
26 changes: 17 additions & 9 deletions alchemy.run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,28 @@ const app = await alchemy("caplets", {
password: process.env.ALCHEMY_PASSWORD!,
});

const { landingPageDomain, landingPageUrl } = buildAlchemyDomains(app.stage, { local: app.local });
const { docsPageDomain, docsPageUrl, landingPageDomain, landingPageUrl } = buildAlchemyDomains(
app.stage,
{ local: app.local },
);
export const landingPage = await Astro("landing-page", {
cwd: "apps/landing",
dev: {
command: "pnpm run dev" + (process.env.SSH_CONNECTION ? " --host 0.0.0.0" : ""),
},
domains: [landingPageDomain, `www.${landingPageDomain}`],
});
export const docsPage = await Astro("docs-page", {
cwd: "apps/docs",
dev: {
command: "pnpm run dev -- --port 4322" + (process.env.SSH_CONNECTION ? " --host 0.0.0.0" : ""),
},
domains: [docsPageDomain],
});

console.log({
"Landing Page URL": landingPageUrl,
"Docs Page URL": docsPageUrl,
});

const [repositoryOwnerFromSlug, repositoryNameFromSlug] =
Expand All @@ -35,20 +46,17 @@ if (pullRequestNumber) {
throw new Error("Missing GitHub repository metadata for preview comment.");
}

const shortSha = process.env.GITHUB_SHA?.slice(0, 7) ?? "unknown";
await GitHubComment("preview-comment", {
owner: repositoryOwner,
repository: repositoryName,
issueNumber: pullRequestNumber,
body: `## 🚀 Preview Deployed

Your changes have been deployed to a preview environment:

**🌐 Landing Page:** ${landingPageUrl}
body: `## Preview Deployed

Built from commit ${process.env.GITHUB_SHA?.slice(0, 7) ?? "unknown"}
Landing: ${landingPageUrl}
Docs: ${docsPageUrl}

---
<sub>🤖 This comment updates automatically with each push.</sub>`,
Built from commit ${shortSha}`,
});
}

Expand Down
21 changes: 21 additions & 0 deletions apps/docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# build output
dist/
# generated types
.astro/

# dependencies
node_modules/

# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*


# environment variables
.env
.env.production

# macOS-specific files
.DS_Store
25 changes: 25 additions & 0 deletions apps/docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Caplets Docs

Astro Starlight documentation site for [docs.caplets.dev](https://docs.caplets.dev).

Public docs live in `apps/docs/src/content/docs`. Root `docs/` is internal maintainer
documentation and is not routed into this site.

Generated reference pages and the public changelog come from:

- `schemas/caplets-config.schema.json`
- `schemas/caplet.schema.json`
- `packages/core/src/code-mode/runtime-api.d.ts`
- `CHANGELOG.md`

## Commands

Run from the repository root:

```sh
pnpm docs:generate
pnpm docs:check
pnpm --filter @caplets/docs dev -- --port 4322
pnpm --filter @caplets/docs typecheck
pnpm --filter @caplets/docs build
```
64 changes: 64 additions & 0 deletions apps/docs/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// @ts-check
import starlight from "@astrojs/starlight";
import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "astro/config";

export default defineConfig({
site: "https://docs.caplets.dev",
integrations: [
starlight({
title: "Caplets Docs",
logo: {
src: "./src/assets/caplets-icon.png",
alt: "Caplets",
},
social: [
{
icon: "github",
label: "GitHub",
href: "https://github.com/spiritledsoftware/caplets",
},
],
customCss: ["./src/styles/global.css"],
components: {
ThemeProvider: "./src/components/CapletsThemeProvider.astro",
ThemeSelect: "./src/components/CapletsThemeSelect.astro",
},
editLink: {
baseUrl: "https://github.com/spiritledsoftware/caplets/edit/main/apps/docs/",
},
sidebar: [
{
label: "Get Started",
items: [
{ label: "Start here", link: "/" },
{ label: "Install", link: "/install/" },
{ label: "Configuration", link: "/configuration/" },
],
},
{
label: "Use Caplets",
items: [
{ label: "Code Mode", link: "/code-mode/" },
{ label: "Add capabilities", link: "/capabilities/" },
{ label: "Agent integrations", link: "/agent-integrations/" },
{ label: "Remote attach", link: "/remote-attach/" },
{ label: "Troubleshooting", link: "/troubleshooting/" },
],
},
{
label: "Reference",
items: [
{ label: "Configuration schema", link: "/reference/config/" },
{ label: "Code Mode API", link: "/reference/code-mode-api/" },
{ label: "Caplet files", link: "/reference/caplet-files/" },
{ label: "Changelog", link: "/changelog/" },
],
},
],
}),
],
vite: {
plugins: [tailwindcss()],
},
});
28 changes: 28 additions & 0 deletions apps/docs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "@caplets/docs",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"astro": "astro",
"build": "astro build",
"dev": "astro dev",
"preview": "astro preview",
"typecheck": "astro check"
},
"dependencies": {
"@astrojs/check": "^0.9.9",
"@astrojs/starlight": "^0.40.0",
"@tailwindcss/vite": "^4.3.1",
"astro": "^6.4.6",
"sharp": "^0.34.5",
"tailwindcss": "^4.3.1",
"typescript": "^6.0.3"
},
"devDependencies": {
"vite": "^7.3.5"
},
"engines": {
"node": ">=24"
}
}
1 change: 1 addition & 0 deletions apps/docs/public/favicon.svg
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 apps/docs/src/assets/caplets-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 53 additions & 0 deletions apps/docs/src/components/CapletsThemeProvider.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{/* This is intentionally inlined to avoid FOUC. */}
<script is:inline>
window.StarlightThemeProvider = (() => {
const storedTheme =
typeof localStorage !== "undefined" && localStorage.getItem("starlight-theme");
const parseTheme = (theme) =>
theme === "dark" || theme === "auto" || theme === "light" ? theme : "light";
const theme = parseTheme(storedTheme);
const resolvedTheme =
theme === "auto"
? window.matchMedia("(prefers-color-scheme: light)").matches
? "light"
: "dark"
: theme;
document.documentElement.dataset.theme = resolvedTheme;
return {
updatePickers(theme = storedTheme || "light") {
theme = parseTheme(theme);
document.querySelectorAll("starlight-theme-select").forEach((picker) => {
const select = picker.querySelector("select");
if (select) select.value = theme;
/** @type {HTMLTemplateElement | null} */
const tmpl = document.querySelector(`#theme-icons`);
const newIcon = tmpl && tmpl.content.querySelector("." + theme);
if (newIcon) {
Comment thread
coderabbitai[bot] marked this conversation as resolved.
const oldIcon = picker.querySelector("svg.label-icon");
if (oldIcon) {
oldIcon.replaceChildren(...newIcon.cloneNode(true).childNodes);
}
}
});
},
};
})();
</script>

<template id="theme-icons">
<svg aria-hidden="true" class="light" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path
d="M5 12a1 1 0 0 0-1-1H3a1 1 0 0 0 0 2h1a1 1 0 0 0 1-1Zm.64 5-.71.71a1 1 0 0 0 1.41 1.41l.71-.71A1 1 0 0 0 5.64 17ZM12 5a1 1 0 0 0 1-1V3a1 1 0 0 0-2 0v1a1 1 0 0 0 1 1Zm5.66 2.34a1 1 0 0 0 .7-.29l.71-.71a1 1 0 1 0-1.41-1.41l-.66.71a1 1 0 0 0 0 1.41 1 1 0 0 0 .66.29ZM21 11h-1a1 1 0 0 0 0 2h1a1 1 0 0 0 0-2Zm-9 7.5a1 1 0 0 0-1 1V21a1 1 0 0 0 2 0v-1.5a1 1 0 0 0-1-1ZM12 7a5 5 0 1 0 0 10 5 5 0 0 0 0-10Z"
/>
</svg>
<svg aria-hidden="true" class="dark" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path
d="M21.64 13a1 1 0 0 0-1.05-.14 8.05 8.05 0 0 1-3.37.73 8.15 8.15 0 0 1-8.14-8.1 8.6 8.6 0 0 1 .25-2A1 1 0 0 0 8 2.36a10.14 10.14 0 1 0 14 11.69 1 1 0 0 0-.36-1.05Z"
/>
</svg>
<svg aria-hidden="true" class="auto" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path
d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"
/>
</svg>
</template>
Loading