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
44 changes: 44 additions & 0 deletions apps/shipyard/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

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

# env files (can opt-in for committing if needed)
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

# fumadocs
.source
27 changes: 27 additions & 0 deletions apps/shipyard/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# shipyard

Shipyard's website and docs at [coss.com/shipyard](https://coss.com/shipyard):
the landing page, and the docs at `/shipyard/docs` on the same Fumadocs setup
as coss ui's.

- `app/page.tsx`, `app/landing.css`: the landing page, as it was at
berthd.app. The harbour at the top is dithered on a canvas and comes alive
at night (`public/assets/harbour.js`, `hero-loop.js`); the chapters' loops
and line scenes load once the page has painted (`clips.js`,
`scenes.css`/`scenes.json`). `components/landing/runtime.tsx` brings them
in. The page keeps its own type (Inter, JetBrains Mono, in `fonts/`) and
tokens; the header, the rails and the docs are coss's.
- `content/docs/`: the docs, moved here from the `cosscom/shipyard`
repository's `docs/` folder. `components/docs/` are its own pieces
(callouts, the stage, the path of cards, screenshots in `public/shots/`,
diagrams and the line scenes); `lib/rehype-reference.ts` makes the
reference tables linkable.
- The app's downloads, the live demo (`berthd.app/demo/`), the box's
install line (`berthd.app/install`), the plugin listing and the
**Review in Shipyard** bounce page stay on berthd.app: they are built and
published from the `cosscom/shipyard` repository.

```sh
bun install
bun run dev --filter=shipyard # http://localhost:4100/shipyard
```
50 changes: 50 additions & 0 deletions apps/shipyard/app/api/raw/[...slug]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import fs from "node:fs/promises";
import path from "node:path";
import { type NextRequest, NextResponse } from "next/server";

export async function GET(
_request: NextRequest,
{ params }: { params: Promise<{ slug: string[] }> },
) {
const { slug } = await params;

// Construct the file path from the slug
// If we have ['docs', 'filename'], look in (root) directory
let filePath: string;
if (slug.length === 2 && slug[0] === "docs") {
filePath = path.join(
process.cwd(),
"content",
"docs",
"(root)",
slug[1] || "",
);
} else {
filePath = path.join(process.cwd(), "content", ...slug);
}

// Check for both .mdx and .md extensions
const mdxPath = filePath.endsWith(".mdx") ? filePath : `${filePath}.mdx`;
const mdPath = filePath.endsWith(".md") ? filePath : `${filePath}.md`;

try {
let content: string;

// Try .mdx first, then .md
try {
content = await fs.readFile(mdxPath, "utf-8");
} catch {
content = await fs.readFile(mdPath, "utf-8");
}

// Return raw markdown with appropriate headers
return new NextResponse(content, {
headers: {
"Cache-Control": "public, max-age=3600",
"Content-Type": "text/plain; charset=utf-8",
},
});
} catch {
return NextResponse.json({ error: "File not found" }, { status: 404 });
}
}
Binary file added apps/shipyard/app/apple-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading