Skip to content
Closed
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: 2 additions & 2 deletions .claude/commands/ci.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: "Run the pre-PR gate — scripts/ci-local.sh, 43 ci-local gates, PASS/FAIL table. Mandatory before a PR. Iterate with bun test --parallel --changed instead."
description: "Run the pre-PR gate — scripts/ci-local.sh, 44 ci-local gates, PASS/FAIL table. Mandatory before a PR. Iterate with bun test --parallel --changed instead."
---

Run the same checks CI runs. This must pass before opening a PR.
Expand Down Expand Up @@ -138,7 +138,7 @@ pass); `CI_LOCAL_NO_NET=1` skips the two npm-registry gates for offline runs;
It is a **superset of the historic /ci list** — it adds the drift gates real CI
runs that the old /ci skipped (so you stop discovering them only after a push).
The roster is `GATE_NAMES` in `scripts/ci-local.sh`, which is the authority; all
43 ci-local gates, in run order:
44 ci-local gates, in run order:
`type`, `lint`, `lint-type-aware` (oxlint `--type-aware` via tsgolint — the
promoted type-aware rules at `error`; permanent `warn` residuals don't fail it),
`syncpack`, `dockerfile-bun-pins`, `dockerfile-workspace`,
Expand Down
2 changes: 2 additions & 0 deletions .claude/research/launch/blog-intro.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
> **Superseded by docs/prd/launch-cycle.md (2026-09-03).** This draft describes a text-to-SQL product under an MIT license and must not be reused; the launch post is `apps/www/src/app/blog/a-name-on-every-fact` and the Show HN body is written from the PRD.

# Why We Built Atlas: Text-to-SQL Is a Feature, Not a Product

Every data-heavy application eventually gets the same feature request: "Can I just ask a question about my data?" Sales teams want pipeline numbers without opening a BI tool. Support teams want to look up customer metrics mid-conversation. Product managers want to check engagement data without waiting for an analyst.
Expand Down
2 changes: 2 additions & 0 deletions .claude/research/launch/show-hn.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
> **Superseded by docs/prd/launch-cycle.md (2026-09-03).** This draft describes a text-to-SQL product under an MIT license and must not be reused; the launch post is `apps/www/src/app/blog/a-name-on-every-fact` and the Show HN body is written from the PRD.

# Show HN: Atlas -- Open-source text-to-SQL agent you can embed in any app

Atlas is an open-source (MIT) text-to-SQL agent that deploys as an API server and embeds into any application. Drop in a `<script>` tag or React component and your users can query their data in plain English.
Expand Down
2 changes: 1 addition & 1 deletion .claude/rules/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ paths:
- [ ] **`bun test --parallel`, never bare `bun test`** — `--parallel` implies `--isolate`: a fresh global + module registry per file. Bare `bun test` shares one global across every file, so a suite can pass on state a sibling left behind. Single file OK: `bun test path/to/file.test.ts`
- [ ] **Never `--no-isolate`** — it buys speed by letting a worker keep one global across the files it runs. `agent-compaction.test.ts` already leaks module state across same-process runs (false-fails under `--rerun-each`, passes 12/12 under `--parallel`), so this would make that class routine
- [ ] **Use `--changed` for local loops** — `cd packages/api && bun test --parallel --changed=origin/main`. ⚠️ **Do NOT run the full `bun run test` locally** — it is a whole-suite `--parallel` run, one worker per core, and CLAUDE.md already makes **remote CI on the PR the gate** rather than any local full run. `.claude/hooks/guard-bun-test.sh` refuses the whole-suite shapes at the tool boundary so this cannot be reached by habit
- [ ] **Pre-PR gates via `/ci`** — runs `scripts/ci-local.sh`: 43 ci-local gates (stage 0 type-check → stage 1 parallel checks: lint, type-aware lint, syncpack, template/schema/openapi/auth-md drift, ee-imports, twenty-resolver, migration-rename discipline, published-symbols, … → stage 2 full test suite via `bun test --parallel`). All must pass; the `/ci` skill carries the authoritative gate list and count. ⚠️ **Without `TEST_DATABASE_URL` the `test` gate now reports `DECLINED`, not PASS (#5410)** — every `*-pg.test.ts` self-skips, so a bare local run cannot be a clean pre-PR pass
- [ ] **Pre-PR gates via `/ci`** — runs `scripts/ci-local.sh`: 44 ci-local gates (stage 0 type-check → stage 1 parallel checks: lint, type-aware lint, syncpack, template/schema/openapi/auth-md drift, ee-imports, twenty-resolver, migration-rename discipline, published-symbols, … → stage 2 full test suite via `bun test --parallel`). All must pass; the `/ci` skill carries the authoritative gate list and count. ⚠️ **Without `TEST_DATABASE_URL` the `test` gate now reports `DECLINED`, not PASS (#5410)** — every `*-pg.test.ts` self-skips, so a bare local run cannot be a clean pre-PR pass
- [ ] **Mock all exports** when using `mock.module()`; use `createConnectionMock()` for connection mocks (never inline)
- [ ] **Tests are self-contained** — No top-level `process.env.X =` or `process.chdir(...)`; `??=` hoist permitted for import-time env reads
- [ ] **A mutation TABLE is GENERATED, never hand-typed** — a "MUTATIONS THIS CATCHES" table is a pointer to `packages/api/scripts/mutations/<name>.md`, rendered from `<name>.mutations.ts` by `scripts/mutate.ts`. Never edit a cell; regenerate. `scripts/check-mutation-tables.sh` is the gate, and it globs the directory. `-pg` specs need `TEST_DATABASE_URL` or the runner aborts on a deflated baseline. (A caveated prose count about ANOTHER suite — `vocabulary-pg.test.ts`'s "measured ONCE, at #5051" sibling list — is not a table and is not a violation; don't "fix" it by deleting it)
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,9 @@ jobs:
- name: Adversarial fixtures for the plugin-count gate (#4066)
run: bash scripts/__tests__/check-plugin-count.test.sh

- name: Check the launch sentence renders verbatim on every surface (#5606)
run: bash scripts/check-launch-sentence.sh

- name: Check boot-loaded plugins ↔ api Dockerfile wiring lockstep (#4880)
run: bun scripts/check-plugin-lockstep.ts

Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ These hold everywhere. The rest of this file is orientation, not rules.

### Tests
- **`bun test --parallel`, never bare `bun test`** — `--parallel` implies `--isolate`: a fresh global + module registry per file. Bare `bun test` shares one global across every file and will pass on state a sibling left behind. Single file OK: `bun test path/to/file.test.ts`. ⚠️ **Never `--no-isolate`** — it trades that isolation for speed, and at least one suite (`agent-compaction.test.ts`) leaks module state across same-process runs today
- **Remote CI on the PR is the gate, not a local `/ci`** — push, open the PR as a **draft**, and let `ci.yml` run (~4 min, parallel) while you review. The local pre-flight is the cheap subset: `cd packages/api && bun test --parallel --changed=origin/main`, plus `bun run lint`, `bun run type` and `bun run lint:type-aware`. **`lint:type-aware` is on that list because it is its own CI-blocking job and costs ~11s** — leaving it off is what let a single type-aware diagnostic red-flag two CI jobs on #5083 *after* the pre-flight came back clean. Run the full `scripts/ci-local.sh` (43 ci-local gates, ~25 min, serial, rewrites source in place for the mutation gate) only when remote CI is broken or when you reshaped something `mutation-tables` anchors on. **Not "before tagging a release" — that clause is gone (#5410):** the local wrapper does not go green on an unchanged tree, so requiring it blocked every release including ones already serving prod. Remote CI on the tagged SHA is the release gate; local `/ci` is advisory. ⚠️ And without `TEST_DATABASE_URL` the local run self-skips all 104 real-Postgres suites — 1,432 assertions when last measured (2026-08-24, at 87 suites) — so it now reports `DECLINED`/exit 3 rather than a green that verified none of them
- **Remote CI on the PR is the gate, not a local `/ci`** — push, open the PR as a **draft**, and let `ci.yml` run (~4 min, parallel) while you review. The local pre-flight is the cheap subset: `cd packages/api && bun test --parallel --changed=origin/main`, plus `bun run lint`, `bun run type` and `bun run lint:type-aware`. **`lint:type-aware` is on that list because it is its own CI-blocking job and costs ~11s** — leaving it off is what let a single type-aware diagnostic red-flag two CI jobs on #5083 *after* the pre-flight came back clean. Run the full `scripts/ci-local.sh` (44 ci-local gates, ~25 min, serial, rewrites source in place for the mutation gate) only when remote CI is broken or when you reshaped something `mutation-tables` anchors on. **Not "before tagging a release" — that clause is gone (#5410):** the local wrapper does not go green on an unchanged tree, so requiring it blocked every release including ones already serving prod. Remote CI on the tagged SHA is the release gate; local `/ci` is advisory. ⚠️ And without `TEST_DATABASE_URL` the local run self-skips all 104 real-Postgres suites — 1,432 assertions when last measured (2026-08-24, at 87 suites) — so it now reports `DECLINED`/exit 3 rather than a green that verified none of them

### Merge discipline
Rationale + override rules: [docs/development/branch-protection.md](docs/development/branch-protection.md). These are workflow rules — no file-read triggers them, so they stay here:
Expand Down
25 changes: 14 additions & 11 deletions apps/www/public/llms.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
# Atlas

> Deploy-anywhere text-to-SQL data analyst agent. Open-source under AGPL-3.0.
> Atlas is the company facts your AI agents can trust: every one carries its source, its date, and the name of the person who approved it. Open source, runs in your VPC.

Atlas connects to your database, auto-generates a YAML semantic layer from your schema, and lets an AI agent query your data in plain English. It validates every query (read-only, AST-parsed, table-whitelisted) and returns structured results with charts and narrative.
To connect an AI agent to Atlas, run this in a terminal. It configures Claude Desktop, Cursor or Continue (or prints a config block for any other MCP client with `--client generic`) against the hosted NovaMart demo, with no account and no email:

```bash
bunx @useatlas/mcp init --hosted --demo --write
```

Then ask: "What is NovaMart's return window?" The answer names who said it, where and when, marks that a person approved it before it counted, and surfaces the contradiction between Finance and Support without picking a side. Full guide: https://docs.useatlas.dev/guides/mcp. Machine-readable docs: https://docs.useatlas.dev/llms.txt.

Three kinds of thing live in the Atlas, and every answer says which it is drawing on: **Surveyed** (read live from the company's own data through a semantic layer, SELECT-only, validated seven ways — it cannot go stale), **Attested** (extracted from something someone wrote, then approved by a named person who is on the record), and **On the record** (the raw source, unedited). Surveyed outranks Attested wherever they overlap. Contradictions are shown with both sources; Atlas picks neither. The complete Atlas runs self-hosted under AGPL-3.0; hosted Atlas is in the US, with EU and APAC regions built and brought online on request.

## Core capabilities

- **Text-to-SQL agent**: Multi-step reasoning powered by Vercel AI SDK. Explores schema, writes validated SQL, runs Python analysis, returns charts and narrative.
- **Semantic layer**: YAML-based entity definitions with auto-profiling, glossary terms, metrics, joins, and LLM enrichment. Versioned in git, reviewed in PRs.
- **8 databases**: PostgreSQL, MySQL, ClickHouse, Snowflake, DuckDB, BigQuery, Salesforce, Elasticsearch/OpenSearch.
- **6 LLM providers**: Anthropic, OpenAI, AWS Bedrock, Ollama, OpenAI-compatible (vLLM, TGI, LiteLLM), AI Gateway.
- **24 plugins**: Datasource adapters, sandbox backends (nsjail, E2B, Daytona, Vercel sandbox), interaction channels, action triggers, context providers. Extensible via Plugin SDK.
- **9+ integration channels**: Slack, Microsoft Teams, Discord, Email, Google Chat, Telegram, GitHub, Linear, WhatsApp, plus webhooks.
- **Embeddable**: Script tag widget, React component (`@useatlas/react`), TypeScript SDK (`@useatlas/sdk`), headless API.
- **MCP server**: Works with Claude Desktop, Cursor, and any MCP-compatible client.
- **Dynamic learning**: Learns query patterns over time. Stored as auditable YAML, not opaque embeddings.
- **The Company Atlas**: facts extracted from what the company already says (chat, transcripts, mail), each approved by a named person before it counts, carrying its source and date; contradictions surfaced with both sources; a coverage page that marks what nobody has surveyed.
- **The analyst (Surveyed tier)**: a YAML semantic layer you author — entities, joins, glossary terms, pinned metrics — and an agent that writes validated, read-only SQL against it and returns rows, charts and narrative.
- **Agent-native**: an MCP server (hosted over OAuth 2.1, self-hosted over stdio) for Claude Desktop, Cursor, Continue and any MCP client; a TypeScript SDK; an embeddable React component and script-tag widget; chat-platform adapters.
- **Datasources, LLM providers, plugins and integrations**: the full inventories live in the docs — https://docs.useatlas.dev/getting-started/connect-your-data, https://docs.useatlas.dev/guides/model-routing, https://docs.useatlas.dev/plugins/authoring-guide, https://docs.useatlas.dev/guides/integrations.

## Security

Expand Down
Loading