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
2 changes: 2 additions & 0 deletions .claude/skills/architecture/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
name: architecture
description: Review and propose system architecture decisions, generate ADRs.
metadata:
internal: true
---

# Architecture Skill
Expand Down
4 changes: 3 additions & 1 deletion .claude/skills/bugfix/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
name: bugfix
description: Diagnose and fix bugs with a 4-stage workflow: gather info, diagnose, fix, test, validate & review.
description: "Diagnose and fix bugs with a 4-stage workflow: gather info, diagnose, fix, test, validate & review."
metadata:
internal: true
---

# Bugfix Skill
Expand Down
4 changes: 3 additions & 1 deletion .claude/skills/create-feature/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
name: create-feature
description: Implement new features end-to-end: gather info, plan, implement, test, validate, review.
description: "Implement new features end-to-end: gather info, plan, implement, test, validate, review."
metadata:
internal: true
---

# Create Feature Skill
Expand Down
2 changes: 2 additions & 0 deletions .claude/skills/create-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ name: create-pr
description: Generate a PR description for the current branch and save it to temp/pr-description.md. Analyzes commits against the base branch and fills in the project PR template exactly.
argument-hint: "[base-branch]"
allowed-tools: Bash, Read, Write
metadata:
internal: true
---

# Create PR Skill
Expand Down
2 changes: 2 additions & 0 deletions .claude/skills/update-docs/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
name: update-docs
description: Update project documentation when code changes occur.
metadata:
internal: true
---

# Update Docs Skill
Expand Down
2 changes: 2 additions & 0 deletions .claude/skills/write-test-e2e/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
name: write-test-e2e
description: Write end-to-end tests for PostKit CLI using testcontainers and black-box testing.
metadata:
internal: true
---

# Write E2E Tests Skill
Expand Down
2 changes: 2 additions & 0 deletions .claude/skills/write-test-unit/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
name: write-test-unit
description: Write unit tests for PostKit CLI using Vitest with proper mocking patterns.
metadata:
internal: true
---

# Write Unit Tests Skill
Expand Down
67 changes: 55 additions & 12 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ PostKit files are split between committed (shared with team) and gitignored (use
- `assertLocalConnection(session, spinner)` (`utils/session.ts`) - Tests local DB connection from session; throws if unreachable
- `resolveApplyTarget(target?)` (`utils/apply-target.ts`) - Resolves `"local"` or `"remote"` apply target; used by infra and seed commands
- `readJsonFile<T>(path)` / `writeJsonFile(path, data)` (`utils/json-file.ts`) - Typed JSON helpers used by remotes and committed migration tracking
- `scaffoldDbInfra()` (`services/scaffold.ts`) - Scaffolds `db/infra/001_roles.sql`+`002_schemas.sql`; runs on both full `postkit init` and `init db`. `scaffoldStorageMigration()` scaffolds the `storage.migrations` bootstrap migration; full `postkit init` only. Both are idempotent (safe to call multiple times, never overwrite)
- `getBlockingPendingCommittedMigrations()` (`utils/committed.ts`) - Like `getPendingCommittedMigrations()` but excludes entries with `blocksSessionStart: false` (e.g. the storage.migrations bootstrap). Used by `db start`'s pending-migrations guard so a brand-new project's first session isn't blocked by a migration nobody has deployed yet; `db deploy`/`db status` still use the unfiltered lookup so it's deployed and listed normally

### Stack Module Architecture

Expand Down Expand Up @@ -197,10 +199,13 @@ The `stack` module manages a local backend service stack (Postgres, Keycloak, Po
- `importRealmTemplate(config, spinner?)` (`services/realm-init.ts`) — Cleans realm JSON and imports via `keycloak-config-cli` container
- `cleanRealmTemplate(raw, realmName)` (`services/realm-init.ts`) — Strips builtins, injects JWT Role Mapper

**`postkit init` scaffold additions:**
**`postkit init [module]` scaffold additions:**
- No `module` argument scaffolds everything (db + auth + stack), unchanged from before scoping existed. Passing `db`, `auth`, or `stack` scaffolds only that module — see `initCommand()`/`initModuleCommand()` in `cli/src/commands/init.ts`
- Scoped runs never re-prompt for or overwrite an existing `postkit.config.json`/`postkit.secrets.json` — they create those files (always with the full db+auth+stack shape, since the db/auth config loaders throw on a missing section) only if missing, and otherwise reuse the existing project name
- Prompts for project name → generates `<name>_<8hexchars>`, stored as `name` in `postkit.config.json`
- Creates `db/infra/001_roles.sql` (anon, authenticated, service_role, app_user, authenticator roles)
- Creates `db/infra/002_schemas.sql` (public, auth, storage schemas)
- Full init only (not `init db`): scaffolds a `storage.migrations` bootstrap migration (`.postkit/db/migrations/00000000000001_create_storage_migrations_table.sql`, tracked in `committed.json`) — a migration-tracking table expected by a self-hosted storage service (e.g. Supabase storage-api) run against the `storage` schema; delete the file + its `committed.json` entry if you don't run one
- Copies vendor provider JARs to `.postkit/auth/providers/`
- Scaffolds realm template at `.postkit/auth/realm/postkit.json`

Expand Down Expand Up @@ -274,6 +279,15 @@ Remotes are managed via utilities in `modules/db/utils/remotes.ts`:
- **tsx** for development mode (direct TS execution without building)
- Output goes to `dist/` with a shebang banner for CLI execution

## Project Init Commands Reference

| Command | Purpose |
|---------|---------|
| `postkit init` | Scaffold the entire project: db + auth + stack |
| `postkit init db` | Scaffold only the db module (`.postkit/db/`, `db/infra/*.sql`) — does not scaffold the `storage.migrations` bootstrap migration, which is full-init only |
| `postkit init auth` | Scaffold only the auth module (`.postkit/auth/`, Keycloak provider sync, realm template) |
| `postkit init stack` | Scaffold only the stack module (`.postkit/stack/`) |

## Database Module Commands Reference

| Command | Purpose |
Expand Down Expand Up @@ -370,10 +384,10 @@ PostKit ships with Claude Code agent skills that teach AI assistants how to work

### Skill Anatomy

Each skill lives in its own directory under `agent/skills/`:
Each skill lives in its own directory under `skills/`:

```
agent/skills/
skills/
├── postkit-migrate/
│ └── SKILL.md # Frontmatter (name, description, allowed-tools) + markdown instructions
├── postkit-setup/
Expand Down Expand Up @@ -409,19 +423,24 @@ Use the [skills CLI](https://github.com/vercel-labs/skills) to install PostKit s

```bash
# Install all PostKit skills (interactive)
npx skills add appritechnologies/Postkit
npx skills add postkitstack/Postkit

# List available skills first
npx skills add appritechnologies/Postkit --list
npx skills add postkitstack/Postkit --list

# Install specific skills only
npx skills add appritechnologies/Postkit --skill postkit-migrate --skill postkit-schema
npx skills add postkitstack/Postkit --skill postkit-migrate --skill postkit-schema

# Install for a specific agent (e.g., Claude Code)
npx skills add appritechnologies/Postkit -a claude-code

# Non-interactive (CI/CD friendly)
npx skills add appritechnologies/Postkit --all -y
npx skills add postkitstack/Postkit -a claude-code

# Non-interactive (CI/CD friendly) — name each skill explicitly.
# Avoid `--all`: it expands to every skill *and* every agent, and it
# bypasses the internal-skill filter, so it also pulls PostKit's own
# repo-maintenance skills into your project.
npx skills add postkitstack/Postkit -y --agent claude-code \
--skill postkit-migrate --skill postkit-setup \
--skill postkit-schema --skill postkit-auth
```

The CLI auto-detects which coding agents you have installed and places skills in the correct directory for each agent. By default, skills are symlinked (single source of truth, easy to update). Use `--copy` for independent copies.
Expand All @@ -440,7 +459,7 @@ npx skills update postkit-auth # Update a specific skill

### Adding a New Skill

Create `agent/skills/<skill-name>/SKILL.md`:
For a **public** skill (one PostKit users install), create `skills/<skill-name>/SKILL.md`. For internal contributor tooling, use `.claude/skills/` instead and read [Public vs Internal Skills](#public-vs-internal-skills) first.

```yaml
---
Expand All @@ -453,7 +472,7 @@ allowed-tools: Bash(postkit *)
Skills can optionally include bundled resources for more complex workflows:

```
agent/skills/<skill-name>/
skills/<skill-name>/
├── SKILL.md # Required — skill instructions
├── scripts/ # Optional — executable scripts for repetitive tasks
├── references/ # Optional — reference docs loaded into context as needed
Expand All @@ -462,6 +481,28 @@ agent/skills/<skill-name>/

When a skill grows beyond ~500 lines, split domain-specific content into `references/` files and point to them from SKILL.md.

### Public vs Internal Skills

Two kinds of skills live in this repo, and the split is load-bearing for packaging:

| Location | Kind | Shipped by `npx skills add` |
|----------|------|-----------------------------|
| `skills/` | Public — for people *using* PostKit | Yes |
| `.claude/skills/` | Internal — for people *developing* PostKit | No |

`skills/` is a directory the skills CLI searches by default; `agent/skills/` is **not**, which is why public skills live at `skills/`.

`.claude/skills/` is also a directory the CLI searches, so every internal skill must carry:

```yaml
metadata:
internal: true
```

Without it, contributor tooling (`/bugfix`, `/create-pr`, …) gets installed into end users' projects. The flag hides the skill from discovery, `--list`, and interactive install; Claude Code ignores the field and loads the skill locally as normal. Contributors can still fetch internal skills with `INSTALL_INTERNAL_SKILLS=1` or an explicit `--skill <name>`.

Descriptions containing `: ` (colon-space) **must be quoted** — unquoted, YAML parses them as a nested mapping and the skills CLI skips the file with a parse error.

## Important Notes

- All paths in `common/config.ts` are resolved relative to either `cliRoot` (the CLI installation) or `projectRoot` (where the user runs commands).
Expand All @@ -486,6 +527,8 @@ Skills are invoked via `/<skill-name>` in Claude Code. Agents are sub-processes

### Skills Registry

These are **internal** skills — they live in `.claude/skills/` and must each carry `metadata: internal: true` so they are not shipped to end users. See [Public vs Internal Skills](#public-vs-internal-skills).

| Skill | Invocation | Purpose | Sub-Agents |
|-------|-----------|---------|------------|
| create-pr | `/create-pr` | Generate PR description to `temp/pr-description.md` | — |
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ PostKit brings together the following components:

## PostKit CLI

The PostKit CLI (`@appritech/postkit`) is the developer toolkit for working with the PostKit stack. It provides safe database migrations, auth management, and project scaffolding.
The PostKit CLI (`@postkitstack/postkit`) is the developer toolkit for working with the PostKit stack. It provides safe database migrations, auth management, and project scaffolding.

**Documentation:** [https://docs.postkitstack.com/](https://docs.postkitstack.com/)

### Quick Start

```bash
# Install the CLI
npm install -g @appritech/postkit
npm install -g @postkitstack/postkit

# Initialize a new project
postkit init
Expand Down Expand Up @@ -81,15 +81,15 @@ No restart needed — Claude Code picks up changes automatically.

Full documentation is available at [docs.postkitstack.com](https://docs.postkitstack.com/).

For more help, see [Troubleshooting](https://docs.postkitstack.com/docs/modules/db/troubleshooting) or open an issue on [GitHub](https://github.com/appritechnologies/postkit/issues).
For more help, see [Troubleshooting](https://docs.postkitstack.com/docs/modules/db/troubleshooting) or open an issue on [GitHub](https://github.com/postkitstack/Postkit/issues).

## Links

- **CLI Tool**: [cli/README.md](cli/README.md)
- **npm Package**: https://www.npmjs.com/package/@appritech/postkit
- **npm Package**: https://www.npmjs.com/package/@postkitstack/postkit
- **Documentation**: https://docs.postkitstack.com/
- **GitHub**: https://github.com/appritechnologies/postkit
- **Issues**: https://github.com/appritechnologies/postkit/issues
- **GitHub**: https://github.com/postkitstack/Postkit
- **Issues**: https://github.com/postkitstack/Postkit/issues

## License

Expand Down
16 changes: 8 additions & 8 deletions cli/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# @appritech/postkit
# @postkitstack/postkit

> Developer toolkit for database migrations and backend automation

**Note:** This tool is still under development and not recommended for production use. APIs may change between versions.

[![npm version](https://badge.fury.io/js/@appritech/postkit.svg)](https://www.npmjs.com/package/@appritech/postkit)
[![License](https://img.shields.io/npm/l/@appritech/postkit.svg)](LICENSE)
[![npm version](https://badge.fury.io/js/%40postkitstack%2Fpostkit.svg)](https://www.npmjs.com/package/@postkitstack/postkit)
[![License](https://img.shields.io/npm/l/@postkitstack/postkit.svg)](LICENSE)

PostKit CLI is a modular toolkit for backend development with the Appri stack. It provides safe database migrations, auth management, and more.

Expand All @@ -16,7 +16,7 @@ PostKit CLI is a modular toolkit for backend development with the Appri stack. I
### Installation

```bash
npm install -g @appritech/postkit
npm install -g @postkitstack/postkit
```

### Requirements
Expand Down Expand Up @@ -186,14 +186,14 @@ postkit db commit
postkit db deploy --remote staging
```

For more help, see [Troubleshooting](https://docs.postkitstack.com/docs/modules/db/troubleshooting) or open an issue on [GitHub](https://github.com/appritechnologies/postkit/issues).
For more help, see [Troubleshooting](https://docs.postkitstack.com/docs/modules/db/troubleshooting) or open an issue on [GitHub](https://github.com/postkitstack/Postkit/issues).

## 🔗 Links

- **npm Package**: https://www.npmjs.com/package/@appritech/postkit
- **npm Package**: https://www.npmjs.com/package/@postkitstack/postkit
- **Documentation**: https://docs.postkitstack.com/
- **GitHub**: https://github.com/appritechnologies/postkit
- **Issues**: https://github.com/appritechnologies/postkit/issues
- **GitHub**: https://github.com/postkitstack/Postkit
- **Issues**: https://github.com/postkitstack/Postkit/issues

## 📜 License

Expand Down
4 changes: 4 additions & 0 deletions cli/docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ PostKit is a modular CLI toolkit built with **TypeScript** and **Node.js** that
└───────────────────────────────────────────────────────────────────────┘
```

**`postkit init [module]`** scaffolds the project. With no argument it scaffolds everything (db + auth + stack) in one pass — the original, unchanged behavior. Passing `db`, `auth`, or `stack` scopes the run to just that module (`cli/src/commands/init.ts`): scoped runs never re-prompt for or overwrite an existing `postkit.config.json`, only creating it — with the full db+auth+stack shape, since the db/auth config loaders throw on a missing section — if it doesn't exist yet, and reusing the existing project name otherwise.

---

## Module System
Expand Down Expand Up @@ -354,3 +356,5 @@ PostKit files in `.postkit/` are split between gitignored (ephemeral/user-specif
- `.postkit/auth/providers/`
- `.postkit/stack/`
- `postkit.secrets.json`

Full `postkit init` (not the scoped `init db`) also scaffolds a committed bootstrap migration at `.postkit/db/migrations/00000000000001_create_storage_migrations_table.sql`, creating a `storage.migrations` tracking table for a self-hosted storage service (e.g. Supabase storage-api) run against the `storage` schema. It's registered in `committed.json` like any other migration — delete both the file and its `committed.json` entry if you don't run one.
5 changes: 5 additions & 0 deletions cli/docs/db.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,17 @@ PostKit files in `.postkit/db/` are split between gitignored (ephemeral) and com
│ └── 20250131_*.sql
├── committed.json # COMMITTED — migrations tracking index (shared)
└── migrations/ # COMMITTED — committed migrations (for deploy)
├── 00000000000001_create_storage_migrations_table.sql # scaffolded by init — see below
├── 20250130_add_users.sql
└── 20250131_add_posts.sql
```

`postkit init` adds only the ephemeral paths to `.gitignore` (`.postkit/db/session.json`, `.postkit/db/plan.sql`, `.postkit/db/schema.sql`, `.postkit/db/session/`). The `migrations/` directory and `committed.json` are committed to git and shared across the team.

Full `postkit init` (not the scoped `init db`) always scaffolds `00000000000001_create_storage_migrations_table.sql` — a committed migration creating a `storage.migrations` tracking table for a self-hosted storage service (e.g. Supabase storage-api) run against the `storage` schema. If your project doesn't run one, delete the file and its entry in `committed.json`.

This migration is registered with `blocksSessionStart: false`, so it does **not** count toward `db start`'s "pending committed migrations" guard — a brand-new project can run `db start` immediately without deploying it first. `db deploy` and `db status` are unaffected and still treat it as a normal pending migration to deploy/list.

---

## 🚀 Commands
Expand Down
5 changes: 5 additions & 0 deletions cli/docs/e2e-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,11 @@ Tests infrastructure SQL (roles) and seed data management. Grant permissions are
| `db status` in empty dir | CLI prevents running before init |
| `init --force` | Creates complete project scaffold |
| `init --force` re-init | Force flag allows re-initialization |
| `init bogus --force` | Unknown module name rejected cleanly, no files created |
| `init db --force` | Scopes scaffold to `.postkit/db/`, `db/infra/*.sql` only (no storage.migrations — full-init only) |
| `init auth --force` after `init db` | Adds only auth files; reuses the existing project name |
| `init stack --force` | Scopes scaffold to `.postkit/stack/` only |
| `init db --force` twice | Idempotent — no duplicate committed migrations or gitignore lines |

### Remote Management (`remote-management.test.ts`)

Expand Down
4 changes: 2 additions & 2 deletions cli/docs/stack.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,15 @@ Keycloak provider JARs are mounted at `/opt/keycloak/providers` inside the conta

**Destination:** `.postkit/auth/providers/` — gitignored, rebuilt by `postkit init`.

If you add or update a project provider, re-run `postkit init` to sync the new JAR, then restart the stack.
If you add or update a project provider, re-run `postkit init` (or the auth-only `postkit init auth`) to sync the new JAR, then restart the stack.

---

## 🏰 Realm Template + JWT Role Mapper

On the first `stack up` (when `is_initial=true`), PostKit imports a Keycloak realm template.

The template path is configured via `stack.keycloak.realmTemplate` (default: `.postkit/auth/realm/postkit.json`). Scaffolded automatically by `postkit init`.
The template path is configured via `stack.keycloak.realmTemplate` (default: `.postkit/auth/realm/postkit.json`). Scaffolded automatically by `postkit init` (or the auth-only `postkit init auth`).

Before importing, `cleanRealmTemplate()` transforms the raw template JSON:

Expand Down
8 changes: 4 additions & 4 deletions cli/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@appritech/postkit",
"version": "1.3.1",
"name": "@postkitstack/postkit",
"version": "1.3.2",
"description": "PostKit - Developer toolkit for database management and more",
"type": "module",
"main": "dist/index.js",
Expand Down Expand Up @@ -46,11 +46,11 @@
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/appritechnologies/postkit.git"
"url": "https://github.com/postkitstack/Postkit.git"
},
"homepage": "https://github.com/appritechnologies/postkit#readme",
"homepage": "https://github.com/postkitstack/Postkit#readme",
"bugs": {
"url": "https://github.com/appritechnologies/postkit/issues"
"url": "https://github.com/postkitstack/Postkit/issues"
},
"dependencies": {
"chalk": "^5.3.0",
Expand Down
Loading