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
23 changes: 22 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,33 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
# The test suite runs on Bun, but users run the published CLI on Node.
- uses: actions/setup-node@v7
with:
node-version: "24"
- run: bun install --frozen-lockfile
- run: bun run check
- run: bun prettier --check .
- run: bun test tests/unit/ tests/e2e/
- run: bun run build
- run: bun run docs:build

# Installs the real tarball and loads a config in a CommonJS project —
# the default `npm init` layout, where Node's type stripping treats a
# `.ts` config as CommonJS and its `import` line fails to parse.
- name: Smoke-test the package on Node
run: |
set -euo pipefail
npm pack --pack-destination "$RUNNER_TEMP"
mkdir -p "$RUNNER_TEMP/smoke/src"
cd "$RUNNER_TEMP/smoke"
npm init -y > /dev/null
npm install "$RUNNER_TEMP"/srcpack-*.tgz > /dev/null
echo 'export const x = 1;' > src/index.ts
printf 'import { defineConfig } from "srcpack";\nexport default defineConfig({ bundles: { app: "src/**/*" } });\n' > srcpack.config.mts
./node_modules/.bin/srcpack --dry-run | tee out.txt
grep -q 'src/index.ts' out.txt
45 changes: 45 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Docs ship with the release, not with every push, so the site always
# describes the version on npm. Use workflow_dispatch for typo fixes.
name: Docs

on:
release:
types: [published]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: false

jobs:
deploy:
# A prerelease is not what `npm install srcpack` gives you, so it must not
# rewrite the site. Manual dispatch carries no release payload and so passes.
if: github.event_name == 'workflow_dispatch' || !github.event.release.prerelease
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deploy.outputs.page_url }}
steps:
- uses: actions/checkout@v7
with:
# VitePress reads "Last updated" and sitemap <lastmod> from per-file git
# history. The default shallow clone dates every page to the release
# commit, so all timestamps collapse to one.
fetch-depth: 0
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bun run docs:build
- uses: actions/configure-pages@v6
- uses: actions/upload-pages-artifact@v5
with:
path: .vitepress/dist
- id: deploy
uses: actions/deploy-pages@v5
5 changes: 3 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ jobs:
id-token: write
contents: read
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- uses: actions/setup-node@v6
- uses: actions/setup-node@v7
with:
# Stay on LTS for the publish job; v26 becomes LTS 2026-10-28.
node-version: "24"
registry-url: "https://registry.npmjs.org"
- run: bun install --frozen-lockfile
Expand Down
15 changes: 14 additions & 1 deletion .vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export default defineConfig({
description: "Context bundler for LLM work",

head: [
["link", { rel: "icon", href: "/srcpack/favicon.ico" }],
// Point at files that exist in public/ — there is no favicon.ico
["link", { rel: "icon", type: "image/svg+xml", href: "/srcpack/logo.svg" }],
["link", { rel: "icon", type: "image/png", href: "/srcpack/logo.png" }],
["meta", { name: "theme-color", content: "#5f67ee" }],
["meta", { property: "og:type", content: "website" }],
["meta", { property: "og:site_name", content: "Srcpack" }],
Expand Down Expand Up @@ -79,6 +81,7 @@ export default defineConfig({
nav: [
{ text: "Home", link: "/" },
{ text: "Guide", link: "/getting-started" },
{ text: "Decisions", link: "/adr/" },
],

sidebar: [
Expand All @@ -92,6 +95,16 @@ export default defineConfig({
{ text: "Google Drive Upload", link: "/upload" },
],
},
{
text: "Architecture Decisions",
items: [
{ text: "Overview", link: "/adr/" },
{
text: "001 — git: source tokens",
link: "/adr/001-git-source-tokens",
},
],
},
],

outline: {
Expand Down
18 changes: 12 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Zero-config CLI for bundling code into LLM-optimized context files.

**Requirements:** Node.js 20+ or Bun
**Requirements:** Node.js 22.18+ or Bun

## Quick Start

Expand All @@ -17,7 +17,7 @@ LLM context fails when codebases are large, noisy, or poorly organized. Srcpack

## Configuration

Create `srcpack.config.ts` in your project root:
Create `srcpack.config.ts` in your project root (use `srcpack.config.mts` if your `package.json` lacks `"type": "module"` — `srcpack init` picks the right one):

```typescript
import { defineConfig } from "srcpack";
Expand Down Expand Up @@ -55,7 +55,7 @@ Or add to `package.json`:
| `bundles` | — | Named bundles with glob patterns |
| `upload` | — | Upload destination(s) |

\*`emptyOutDir` defaults to `true` when `outDir` is inside project root. When `outDir` is outside root, a warning is emitted unless explicitly set.
\*`emptyOutDir` defaults to `true` when `outDir` is inside project root. When `outDir` is outside root, a warning is emitted unless explicitly set. Emptying happens only on a full run, so `npx srcpack web` leaves other bundles in place.

### Bundle Config

Expand All @@ -69,6 +69,9 @@ Or add to `package.json`:
// Force-include gitignored files (+ prefix)
["docs/**/*", "+docs/**/*.local.md"]

// Changed files instead of a glob (git: prefix)
["git:staged", "!bun.lock"]

// Full options
{
include: "src/**/*",
Expand All @@ -80,15 +83,15 @@ Or add to `package.json`:

Patterns follow glob syntax. Prefix with `!` to exclude, `+` to force-include (bypasses `.gitignore`). Binary files are excluded.

A pattern can also name a set of changed files: `git:staged`, `git:unstaged`, `git:untracked`, `git:dirty`, or `git:<rev>` (e.g. `git:main`, `git:HEAD~3`). Deleted files are skipped, and `git:<rev>` compares against the merge base so a stale branch still reports only your own changes. See [Git sources](https://kriasoft.com/srcpack/configuration#git-sources-git-prefix).

### Google Drive Upload

To upload bundles to Google Drive, add OAuth credentials to your config:

```typescript
export default defineConfig({
bundles: {
/* ... */
},
bundles: {/* ... */},
upload: {
provider: "gdrive",
folderId: "1ABC...", // Google Drive folder ID (from URL)
Expand Down Expand Up @@ -134,6 +137,9 @@ export function utils() {
```bash
npx srcpack # Bundle all, upload if configured
npx srcpack web api # Bundle specific bundles only
npx srcpack --staged # Bundle staged changes (no config needed)
npx srcpack --dirty # Bundle staged + unstaged + untracked
npx srcpack --since main # Bundle changes since main
npx srcpack --dry-run # Preview without writing files
npx srcpack --emptyOutDir # Empty output directory before bundling
npx srcpack --no-emptyOutDir # Keep existing files in output directory
Expand Down
Loading