Skip to content

Commit 2cfde9c

Browse files
committed
chore: unblock CI lint, add MIT LICENSE, humanize README copy
- Fix biome formatter complaints across 6 web files (long string joins, one-line JSX, array inlining) so `pnpm lint` is green. - Suppress biome's noDangerouslySetInnerHtml on the JSON-LD <script> in root layout with a justified biome-ignore: the payload is a static object we control and every '<' is escaped to '\u003c', so no tag can close the script tag early. - Add MIT LICENSE at repo root covering the whole repository. - Update the README license badge + section to reflect plain MIT everywhere; drop the old "packages-only MIT, rest source-available" hedge now that the project is fully open-source. - Tighten README copy in TL;DR, the self-host note, "why star this", and the license blurb — fewer throat-clearings, more contractions, stronger hooks.
1 parent 601ecb6 commit 2cfde9c

8 files changed

Lines changed: 79 additions & 155 deletions

File tree

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Devansh Tiwari
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Serialized writes. Idempotent retries. Typed TypeScript SDKs, generated live fro
1515
[![CI](https://img.shields.io/github/actions/workflow/status/Devansh-365/sheetforge/ci.yml?branch=main&style=for-the-badge&logo=githubactions&logoColor=white&label=CI&labelColor=0c0c0e&color=22c55e)](https://github.com/Devansh-365/sheetforge/actions)
1616
[![Stars](https://img.shields.io/github/stars/Devansh-365/sheetforge?style=for-the-badge&logo=github&logoColor=white&labelColor=0c0c0e&color=22c55e)](https://github.com/Devansh-365/sheetforge/stargazers)
1717
[![Issues](https://img.shields.io/github/issues/Devansh-365/sheetforge?style=for-the-badge&logo=github&logoColor=white&labelColor=0c0c0e&color=22c55e)](https://github.com/Devansh-365/sheetforge/issues)
18-
[![License](https://img.shields.io/badge/packages-MIT-0c0c0e?style=for-the-badge&labelColor=22c55e)](#license)
18+
[![License](https://img.shields.io/badge/license-MIT-0c0c0e?style=for-the-badge&labelColor=22c55e)](./LICENSE)
1919
[![Self-host](https://img.shields.io/badge/status-self--host%20only-22c55e?style=for-the-badge&labelColor=0c0c0e)](#status-self-host-only-for-now)
2020
[![PRs welcome](https://img.shields.io/badge/PRs-welcome-0c0c0e?style=for-the-badge&labelColor=22c55e)](#contributing)
2121

@@ -33,7 +33,7 @@ Serialized writes. Idempotent retries. Typed TypeScript SDKs, generated live fro
3333
>
3434
> The landing site at **[sheetforge.dev](https://sheetforge.dev)** is live, but the backend is **not yet hosted**. To use sheetforge today, clone the repo and run the full stack locally — `pnpm dev` boots the Next.js dashboard, Hono API, and the queue worker on your own machine. A managed/hosted SaaS is on the roadmap; the MIT-licensed OSS core (`packages/queue`, `packages/codegen`, `packages/sdk-ts`) will stay free forever. See the [self-host quickstart](#quickstart) below.
3535
36-
> **TL;DR.** The Google Sheets API drops rows under concurrent writes. Every "Sheets as a backend" wrapper you have tried (SheetDB, Sheety, NoCodeAPI) forwards your POST straight to `values.append` and inherits the bug. **sheetforge** wraps every write in a per-sheet queue fenced by a Postgres advisory lock. 50 parallel POSTs → 50 ordered rows, retry-safe by key. And because the sheet's header row is the schema, it generates a typed TypeScript SDK you commit to your repo.
36+
> **TL;DR.** The Google Sheets API drops rows under concurrent writes. Every "Sheets as a backend" wrapper (SheetDB, Sheety, NoCodeAPI) forwards your POST straight to `values.append` and inherits the bug. **sheetforge** wraps every write in a per-sheet queue fenced by a Postgres advisory lock: 50 parallel writes, 50 ordered rows, retry-safe by key. And because your header row is the schema, you get a typed TypeScript SDK you can commit alongside the call sites.
3737
3838
## The problem
3939

@@ -87,9 +87,9 @@ await Promise.all([
8787
| Hosted SaaS (sign up, skip local infra) | ⏳ planned after V1 stabilizes |
8888
| OSS core (`packages/queue`, `packages/codegen`, `packages/sdk-ts`) | ✅ MIT, free forever |
8989

90-
**What this means for you.** If you land on the marketing site today and hit "Sign in", that flow only works against an API *you* run — the hosted endpoint isn't up yet. To try the product, clone this repo, follow the [quickstart](#quickstart), and the dashboard at `http://localhost:3000` gives you the whole experience (OAuth, sheet connect, typed SDK download).
90+
**What this means for you.** The "Sign in" button on [sheetforge.dev](https://sheetforge.dev) points at an API *you* run — there's no hosted endpoint yet. Clone the repo, follow the [quickstart](#quickstart), and `http://localhost:3000` gives you the full flow: OAuth, sheet connect, typed SDK download.
9191

92-
I'll update this section the moment the hosted API is live. Star the repo to get notified.
92+
I'll flip this section the moment the hosted API is live. Star the repo if you want the ping.
9393

9494
## Quickstart
9595

@@ -337,7 +337,7 @@ See the `good-first-queue-hack` and `sdk-codegen` labels if you want to help pul
337337

338338
## Why star this
339339

340-
Most "Sheets as a backend" tools wrap a broken primitive. sheetforge fixes the primitive and hands you a typed client on the way out. If you have ever shipped a form on Sheets and watched rows go missing during a launch, starring this is the cheapest vote for correctness I can ask for.
340+
Most "Sheets as a backend" tools wrap a broken primitive. sheetforge fixes the primitive, then hands you a typed client on the way out. If you've ever shipped a form on Sheets and watched rows vanish mid-launch, a star is the cheapest vote for correctness you can cast.
341341

342342
## Contributing
343343

@@ -361,7 +361,7 @@ Issues and discussions are open. I answer them.
361361

362362
## License
363363

364-
`packages/queue`, `packages/codegen`, and `packages/sdk-ts` are **MIT** once the V0 concurrency acceptance demo passes. The apps and slices are **source-available** (all-rights-reserved pre-launch, source-available after). See [`LICENSE`](./LICENSE) once it lands.
364+
[MIT](./LICENSE). Clone, fork, self-host, ship — no strings. When the hosted SaaS lands it'll run on the same MIT core; the managed service is the product, the code stays free.
365365

366366
<br />
367367

apps/web/src/app/app/layout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ export default function DashboardLayout({
7575
aria-hidden="true"
7676
/>
7777
<span>
78-
sheetforge is self-host only for now — the dashboard talks to your
79-
own API. Hosted SaaS is on the way.{' '}
78+
sheetforge is self-host only for now — the dashboard talks to your own API. Hosted
79+
SaaS is on the way.{' '}
8080
<a
8181
href="https://github.com/Devansh-365/sheetforge#quickstart"
8282
target="_blank"

apps/web/src/app/layout.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ const ibmPlexMono = IBM_Plex_Mono({
99
});
1010

1111
const SITE_URL = 'https://sheetforge.dev';
12-
const title =
13-
'sheetforge — Google Sheets as a backend that actually behaves like one';
12+
const title = 'sheetforge — Google Sheets as a backend that actually behaves like one';
1413
const description =
1514
'Open-source, race-condition-safe Google Sheets backend. 1000 concurrent writes, 1000 ordered rows. Typed TypeScript & Python SDKs generated from your sheet headers. Self-host today — hosted SaaS coming soon.';
1615

@@ -125,10 +124,7 @@ const jsonLd = {
125124
name: 'sheetforge',
126125
url: SITE_URL,
127126
logo: `${SITE_URL}/icon`,
128-
sameAs: [
129-
'https://github.com/Devansh-365/sheetforge',
130-
'https://github.com/Devansh-365',
131-
],
127+
sameAs: ['https://github.com/Devansh-365/sheetforge', 'https://github.com/Devansh-365'],
132128
},
133129
{
134130
'@type': 'WebSite',
@@ -214,6 +210,7 @@ export default function RootLayout({
214210
<head>
215211
<script
216212
type="application/ld+json"
213+
// biome-ignore lint/security/noDangerouslySetInnerHtml: JSON-LD is a static object we control, and `<` is escaped to `\u003c` so no tag can close the <script> early.
217214
dangerouslySetInnerHTML={{
218215
__html: JSON.stringify(jsonLd).replace(/</g, '\\u003c'),
219216
}}

apps/web/src/app/manifest.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ export default function manifest(): MetadataRoute.Manifest {
44
return {
55
name: 'sheetforge',
66
short_name: 'sheetforge',
7-
description:
8-
'Race-condition-safe Google Sheets backend with typed TypeScript/Python SDKs.',
7+
description: 'Race-condition-safe Google Sheets backend with typed TypeScript/Python SDKs.',
98
start_url: '/',
109
display: 'standalone',
1110
background_color: '#0c0c0e',

apps/web/src/app/opengraph-image.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { ImageResponse } from 'next/og';
22

33
export const runtime = 'edge';
4-
export const alt =
5-
'sheetforge — Google Sheets as a backend that actually behaves like one';
4+
export const alt = 'sheetforge — Google Sheets as a backend that actually behaves like one';
65
export const size = { width: 1200, height: 630 };
76
export const contentType = 'image/png';
87

@@ -110,9 +109,7 @@ export default function OgImage() {
110109
1000 concurrent writes · 1000 ordered rows · 0 collisions
111110
</span>
112111
</span>
113-
<span style={{ color: '#4ade80' }}>
114-
github.com/Devansh-365/sheetforge
115-
</span>
112+
<span style={{ color: '#4ade80' }}>github.com/Devansh-365/sheetforge</span>
116113
</div>
117114
</div>,
118115
{

0 commit comments

Comments
 (0)