Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
139 commits
Select commit Hold shift + click to select a range
ed348e3
basic scaffolding
stevensJourney Feb 2, 2026
2e6fa58
confg templates
stevensJourney Feb 3, 2026
73763b2
Schema packages. Improve templates. WIP link commands.
stevensJourney Feb 3, 2026
f8021ca
wip: linking
stevensJourney Feb 3, 2026
16352ad
unify config types
stevensJourney Feb 3, 2026
63eebde
Command structures and implement deploy command
stevensJourney Feb 4, 2026
ec8d323
Add destroy and stop command implementation
stevensJourney Feb 4, 2026
77cc382
fetch and pull cloud config commands
stevensJourney Feb 4, 2026
a066fd7
Improvements from testing deploy workflow
stevensJourney Feb 5, 2026
0def649
Add multiple options for specifying cloud instance
stevensJourney Feb 5, 2026
23ad67e
Various command improvements. cloud Token and schema generation comma…
stevensJourney Feb 5, 2026
5d9a090
wip: shared commands
stevensJourney Feb 6, 2026
14d3e51
Help groups for CLI command flags. Unify linking resolve patterns. Up…
stevensJourney Feb 6, 2026
51bd353
validation commands
stevensJourney Feb 6, 2026
5a916c1
update docs
stevensJourney Feb 6, 2026
874e4d4
Support for naming and creating cloud instances
stevensJourney Feb 6, 2026
78fcb42
cleanup token input
stevensJourney Feb 6, 2026
321591c
update commands' descriptions
stevensJourney Feb 6, 2026
4d76397
strategic command shuffle
stevensJourney Feb 6, 2026
873d463
cli plugin framework. Docker deploy for self hosting example plugin.
stevensJourney Feb 6, 2026
a13c9f8
monorepo structure
stevensJourney Feb 6, 2026
69c3250
add usage docs for docker
stevensJourney Feb 6, 2026
5ec0fe3
wip: update docker templates
stevensJourney Feb 9, 2026
8a70580
docker plugin templating improvements
stevensJourney Feb 9, 2026
40a92b4
update workspace layout
stevensJourney Feb 9, 2026
78cc6d3
cleanup templates
stevensJourney Feb 9, 2026
35d2983
update readme
stevensJourney Feb 9, 2026
2798d21
formatting
stevensJourney Feb 9, 2026
68104f7
cleanup cloud commands
stevensJourney Feb 9, 2026
ec8180f
add colour to logs
stevensJourney Feb 9, 2026
756db05
update packages
stevensJourney Feb 9, 2026
90164bc
update start command docs
stevensJourney Feb 9, 2026
e6df80f
colourize errors. Add some basic examples
stevensJourney Feb 10, 2026
deface8
pretty format client errors
stevensJourney Feb 10, 2026
4ed581b
fix cloud deploy command failure. use micro web sdk client.
stevensJourney Feb 11, 2026
78f1c48
styled errors
stevensJourney Feb 11, 2026
bd40e12
cleanup logs - format command strings to standout
stevensJourney Feb 11, 2026
f8ed092
update fetch status command
stevensJourney Feb 11, 2026
b6face2
update examples with readmes
stevensJourney Feb 11, 2026
7c13bdc
Add basic node.js example app
stevensJourney Feb 11, 2026
a7a91fc
update docs
stevensJourney Feb 11, 2026
885dd0b
share code with core-api
stevensJourney Feb 11, 2026
604cab3
use relative paths for Docker
stevensJourney Feb 11, 2026
34e0ade
specify docker project name in compose projects
stevensJourney Feb 11, 2026
59edbca
accounts client and list instances command
stevensJourney Feb 12, 2026
5030b44
cleanup project loading
stevensJourney Feb 12, 2026
30720bb
cleanup token storage. Improve login command.
stevensJourney Feb 12, 2026
e517f95
wip: browser based PAT for login
stevensJourney Feb 16, 2026
cc979fa
improve config pull output
stevensJourney Feb 16, 2026
91e7667
improve schemas and config validation
stevensJourney Feb 16, 2026
758cf7e
update readmes
stevensJourney Feb 16, 2026
5781534
split init commands. Add interactivity to docker configure
stevensJourney Feb 16, 2026
b7aee18
refactor: rename link.yaml to cli.yaml
stevensJourney Feb 16, 2026
aef9ced
clean login command
stevensJourney Feb 16, 2026
4506cdc
Add ability to configure custom YAML tags for VSCode.
stevensJourney Feb 16, 2026
89aeec9
show progress during validations. neaten init commad logs.
stevensJourney Feb 17, 2026
25faae9
add more usage docs. refactor command name to powersync pull instance
stevensJourney Feb 17, 2026
c3a19f4
default org-id for PAT tokens with single org
stevensJourney Feb 17, 2026
e8aea02
readme cleanup
stevensJourney Feb 17, 2026
fe892ac
fallback login token to prompt if dashboard cannot send it
stevensJourney Feb 17, 2026
66a7fb5
improve PAT login with encryption for edge cases.
stevensJourney Feb 18, 2026
3d1a218
respond with html for long
stevensJourney Feb 19, 2026
4de930f
feat: migration of sync rules
stevensJourney Feb 19, 2026
ef7bac7
remove service-schema override
stevensJourney Feb 19, 2026
22d410c
less colour is more colour
stevensJourney Feb 19, 2026
0c60b99
rename sync rules to sync config. Add command for only deploying sync…
stevensJourney Feb 19, 2026
e082df0
YAML language server templating
stevensJourney Feb 19, 2026
23aff77
More token storage options.
stevensJourney Feb 19, 2026
a239df9
minor log cleanup
stevensJourney Feb 20, 2026
c837230
remove pnpm overrides
stevensJourney Feb 20, 2026
9d1a14d
formatting
stevensJourney Feb 20, 2026
1cc41b8
use single pnpm version
stevensJourney Feb 20, 2026
50d9ef1
remove local override
stevensJourney Feb 20, 2026
ae2f997
fix prettier ignore
stevensJourney Feb 20, 2026
770426c
pretty lint
stevensJourney Feb 20, 2026
6d1cd26
more cleanup
stevensJourney Feb 20, 2026
dce470e
cleanup
stevensJourney Feb 20, 2026
9e54182
try fix windows
stevensJourney Feb 20, 2026
39ac48a
tests for login command
stevensJourney Feb 20, 2026
bcf14bc
Add example commands
stevensJourney Feb 20, 2026
a2929c0
cleanup template config
stevensJourney Feb 20, 2026
9fd74e8
Merge branch 'init' into sync-rules-migrate
stevensJourney Feb 20, 2026
d61e2bc
update sync stream defaults
stevensJourney Feb 20, 2026
921e61b
formatting
stevensJourney Feb 20, 2026
054fadf
lint
stevensJourney Feb 20, 2026
50a45f6
update readme
stevensJourney Feb 20, 2026
caebe3f
Update cli/src/api/write-vscode-settings-for-yaml-env.ts
stevensJourney Feb 23, 2026
dccb61d
pr feedback items
stevensJourney Feb 23, 2026
d6f249f
Merge branch 'init' of github.com:powersync-ja/temp-cli into init
stevensJourney Feb 23, 2026
8429145
lint
stevensJourney Feb 23, 2026
2f6af9f
cleanup
stevensJourney Feb 23, 2026
f86df4e
ensure directory is required for multiple directories
stevensJourney Feb 23, 2026
e16a941
update sync config examples to edition 3
stevensJourney Feb 23, 2026
e729d8e
remove debug_api from templates
stevensJourney Feb 23, 2026
4c5bbaf
list is_provisioned in instance statuses. Wait for destroy and stop c…
stevensJourney Feb 24, 2026
34cef60
document oclif plugins
stevensJourney Feb 24, 2026
1c140ba
update templates in order to create cloud instances without replicati…
stevensJourney Feb 24, 2026
9a4bcd1
update instance status data_queries to used_for_replication
stevensJourney Feb 24, 2026
7cfd2e9
update validate message.
stevensJourney Feb 24, 2026
89385b8
update validation messages. refresh unit tests
stevensJourney Feb 24, 2026
4a5d932
fix tests
stevensJourney Feb 24, 2026
8665efe
husky lint
stevensJourney Feb 24, 2026
23d5999
more husky
stevensJourney Feb 24, 2026
3c4329d
update docs to refer to powersync docker command and topic - not plugin
stevensJourney Feb 24, 2026
78c4f15
wip: cleanup commands and topics
stevensJourney Feb 24, 2026
a6c1f0a
add autocomplete
stevensJourney Feb 24, 2026
1ba7179
add commands plugin
stevensJourney Feb 25, 2026
c35a15d
rename sync.yaml to sync-config.yaml
stevensJourney Feb 25, 2026
d952cca
update package name
stevensJourney Feb 25, 2026
268e879
add install instructions to readme
stevensJourney Feb 25, 2026
2188bef
update build script
stevensJourney Feb 25, 2026
11eb305
fix login command when pasting a PAT
stevensJourney Feb 25, 2026
b88dbe6
cleanup flag resolution order
stevensJourney Feb 25, 2026
80560f9
cleanup login command
stevensJourney Feb 25, 2026
d33535d
add ability to deploy only service config changes (no sync config)
stevensJourney Feb 25, 2026
7e1c365
cleanup deploy logging
stevensJourney Feb 25, 2026
4844ba2
Polish the yaml templates (#5)
benitav Feb 25, 2026
fe6fc60
fix format
stevensJourney Feb 25, 2026
38d88b5
Merge branch 'init' of github.com:powersync-ja/temp-cli into init
stevensJourney Feb 25, 2026
04019b7
fix tests
stevensJourney Feb 25, 2026
72f6b7f
fix typo
stevensJourney Feb 25, 2026
7f986e7
add note about cloud secrets
stevensJourney Feb 26, 2026
e29b1c5
allow linking if project directory does not exist
stevensJourney Feb 26, 2026
58d23b7
add powersync status alias
stevensJourney Feb 26, 2026
64e25ec
add objectId validation, and org - project existance checks
stevensJourney Feb 26, 2026
0653202
remove unknown error code.
stevensJourney Feb 26, 2026
1d87c0d
rename TOKEN to PS_ADMIN_TOKEN
stevensJourney Feb 26, 2026
9ff2af3
fix format
stevensJourney Feb 26, 2026
05177fb
assign project for self hosted commands
stevensJourney Feb 26, 2026
96cdb73
fix filename casing
stevensJourney Feb 26, 2026
2e60a40
fix order of spreading default options.
stevensJourney Feb 26, 2026
a10ed87
fix: destroy command should call destroyInstance
stevensJourney Feb 26, 2026
2d0b2a2
fix: docker typo
stevensJourney Feb 26, 2026
adc5964
temp move
stevensJourney Feb 26, 2026
6a4d1f4
move op
stevensJourney Feb 26, 2026
6a68eba
cleanup powersync status examples
stevensJourney Mar 1, 2026
a9d08d3
feedback from AI review
stevensJourney Mar 1, 2026
7ec5ee8
cleanup
stevensJourney Mar 1, 2026
baedce2
disable publishing, just in case
stevensJourney Mar 2, 2026
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
3 changes: 3 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
layout node
use node
[ -f .env ] && dotenv
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* text=auto eol=lf
*.cmd text eol=crlf
*.bat text eol=crlf
60 changes: 60 additions & 0 deletions .github/workflows/onPushToMain.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: release on push to main

on:
push:
branches: [main]

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- name: Check if CLI version already exists
id: version-check
run: |
package_version=$(node -p "require('./cli/package.json').version")
exists=$(gh api repos/${{ github.repository }}/releases/tags/v$package_version >/dev/null 2>&1 && echo "true" || echo "")

if [ -n "$exists" ];
then
echo "Version v$package_version already exists"
echo "::warning file=cli/package.json,line=1::Version v$package_version already exists - no release will be created."
echo "skipped=true" >> $GITHUB_OUTPUT
else
echo "Version v$package_version does not exist. Creating release..."
echo "skipped=false" >> $GITHUB_OUTPUT
echo "tag=v$package_version" >> $GITHUB_OUTPUT
fi
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
- name: Setup git
if: ${{ steps.version-check.outputs.skipped == 'false' }}
run: |
git config --global user.email ${{ secrets.GH_EMAIL }}
git config --global user.name ${{ secrets.GH_USERNAME }}
- name: Generate OCLIF README (cli)
if: ${{ steps.version-check.outputs.skipped == 'false' }}
run: |
pnpm run build
cd cli && pnpm exec oclif readme
cd ..
if [ -n "$(git status --porcelain)" ]; then
git add .
git commit -am "chore: update README.md"
git push -u origin ${{ github.ref_name }}
fi
- name: Create GitHub Release
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5
if: ${{ steps.version-check.outputs.skipped == 'false' }}
with:
name: ${{ steps.version-check.outputs.tag }}
tag: ${{ steps.version-check.outputs.tag }}
commit: ${{ github.ref_name }}
token: ${{ secrets.GH_TOKEN }}
skipIfReleaseExists: true
22 changes: 22 additions & 0 deletions .github/workflows/onRelease.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: publish on release

on:
release:
types: [released]

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm run build
# - name: Publish @powersync/cli to npm
# run: pnpm publish -- --no-git-checks --access public
# env:
# NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
26 changes: 26 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: tests

on:
push:
branches-ignore: [main]

jobs:
unit-tests:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node_version: [24]
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- name: Check formatting
run: pnpm exec prettier --check .
- run: pnpm run build
- run: pnpm run test
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,12 @@ dist
# Vite logs files
vite.config.js.timestamp-*
vite.config.ts.timestamp-*

# Playground for testing cli commands
playground/

# PNPM
.pnpm-store/

# MacOS
.DS_Store
17 changes: 17 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/sh
set -e

if git diff --cached --quiet --diff-filter=ACMR; then
exit 0
fi

git diff --cached --name-only -z --diff-filter=ACMR \
| xargs -0 pnpm prettier --write --ignore-unknown

if git diff --cached --name-only --diff-filter=ACMR -- '*.js' '*.cjs' '*.mjs' '*.ts' '*.tsx' | grep -q .; then
git diff --cached --name-only -z --diff-filter=ACMR -- '*.js' '*.cjs' '*.mjs' '*.ts' '*.tsx' \
| xargs -0 pnpm eslint --fix
fi

git diff --cached --name-only -z --diff-filter=ACMR \
| xargs -0 git add --
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pnpm-lock.yaml
**/pnpm-lock.yaml
**/*.json
10 changes: 10 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"bracketSameLine": true,
"useTabs": false,
"endOfLine": "lf",
"printWidth": 120,
"trailingComma": "none"
}
22 changes: 22 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Agent Guidelines

## Environment Variables

- Do not read `process.env` directly in application code.
- Use typed env helpers (for example, `env` from `@powersync/cli-core`) so environment access is centralized and testable.
- Keep environment resolution logic in one place; command and service code should consume resolved values.

## Testing Environment Behavior

- Prefer mocking env helpers/modules in tests instead of relying on direct `process.env` reads in production code.
- Tests may set temporary env values when needed, but should primarily validate behavior through mocked env access points.
- Reset env-related mocks/state between tests to avoid leakage.

## File Naming Conventions

- Choose the filename based on the file's primary responsibility so agents can infer intent without opening the file.
- If the main export is a class or a type/interface, the filename must exactly match that export name (for example, `ServiceCloudConfig.ts`, `AccountsHubClientSDKClient.ts`).
- Use this class/type naming rule even if the file also contains small helper functions; the primary exported symbol takes precedence.
- If the file's purpose is utility logic (single function or a group of helper methods), use action-style kebab-case names in the form `do-this-action.ts` (for example, `ensure-service-type.ts`, `resolve-config-path.ts`).
- Utility filenames should describe what the code does, not what it is. Prefer verb-led names such as `load-*`, `parse-*`, `validate-*`, `write-*`, `ensure-*`.
- Avoid generic utility names like `helpers.ts`, `utils.ts`, or `common.ts` unless the file is intentionally a broad shared entry point.
84 changes: 84 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# PowerSync CLI

Monorepo for the PowerSync CLI and related tooling. Built with [pnpm](https://pnpm.io) workspaces and [OCLIF](https://oclif.io).

## Requirements

- **Node**: LTS v24+ (see [.nvmrc](./.nvmrc); use `nvm use` to switch)
- **Package manager**: pnpm

## Monorepo structure

The workspace is split into the main CLI, shared **packages**, and optional **plugins**:

| Package | Path | Description |
| ---------------------------------------------------- | -------------------- | ---------------------------------------------------------------------------------- |
| [**@powersync/cli**](./cli) | `cli/` | Main CLI — manage instances, config, sync config, cloud and self-hosted |
| [**@powersync/cli-core**](./packages/cli-core) | `packages/cli-core/` | Core types and base commands shared by the CLI and plugins |
| [**@powersync/cli-schemas**](./packages/schemas) | `packages/schemas/` | Shared config schemas (cli.yaml, service.yaml, etc.) |
| [**@powersync/cli-plugin-docker**](./plugins/docker) | `plugins/docker/` | Docker plugin — self-hosted PowerSync with Compose (configure, reset, start, stop) |

```
├── cli/ # @powersync/cli — main CLI (commands, cloud/self-hosted, templates)
├── packages/
│ ├── cli-core/ # @powersync/cli-core — base commands & YAML utils (used by CLI + plugins)
│ └── schemas/ # @powersync/cli-schemas — config validation (LinkConfig, CLIConfig)
├── plugins/
│ └── docker/ # @powersync/cli-plugin-docker — docker configure, reset, start, stop
├── examples/ # Sample projects initialized with the CLI (see examples/README.md)
│ ├── cloud/
│ └── self-hosted/
└── docs/
├── usage.md # General CLI usage (Cloud, self-hosted, linking, auth)
└── usage-docker.md # Docker plugin (configure, reset, start, stop, templates)
```

- **cli** depends on **cli-core**, **cli-schemas**, and **@powersync/cli-plugin-docker**. It loads the docker plugin and re-exports base command types from cli-core.
- **plugin-docker** (in **plugins/docker**) depends on **cli-core** and **cli-schemas**. No dependency on the CLI package.
- **cli-core** depends on **schemas**. It provides `SelfHostedInstanceCommand`, YAML helpers (`!env`), and shared types for plugins.

Workspace roots are listed in [pnpm-workspace.yaml](./pnpm-workspace.yaml): `cli`, `packages/*`, `plugins/*`.

## OCLIF plugins

We rely on standard [OCLIF plugin loading](https://oclif.io/docs/plugins/) so plugins can register new commands or hook into command execution. The main CLI ships with a Docker plugin under [plugins/docker](./plugins/docker), and any other OCLIF-compatible plugin can be installed the same way.

For PowerSync-specific plugins, the optional [@powersync/cli-core](./packages/cli-core) package exposes base command helpers and shared types. The Docker plugin consumes these helpers and adds Docker-focused commands as a reference implementation.

Users can manage their own installed plugins dynamically at runtime. Run `powersync plugins --help` for install, uninstall, and inspection options.

## Getting started

```bash
nvm use # use Node from .nvmrc (optional)
pnpm install
pnpm build
```

Run the CLI from the repo root:

```bash
powersync --help
```

### Self-hosted with Docker

From the repo root, create the Docker layout and run the stack:

```bash
powersync docker configure
powersync docker start
```

See [plugins/docker](./plugins/docker/README.md) and [docs/usage-docker.md](./docs/usage-docker.md) for details.

## Examples

The [**examples/**](./examples) folder contains basic projects initialized with the CLI. See [examples/README.md](./examples/README.md) for the full list and links to each example's README.

## Documentation

- [**Usage**](./docs/usage.md) — How the CLI works: Cloud and self-hosted, linking, auth, supplying instance info
- [**Usage (Docker)**](./docs/usage-docker.md) — Docker plugin: configure, reset, start, stop, templates, flags
- [**CLI documentation conventions**](./docs/cli-documentation-conventions.md) — How we document commands (description, summary, examples, flags, topics)
- [CLI package README](./cli/README.md) — Install, usage, and command reference
5 changes: 5 additions & 0 deletions cli/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/dist
/tmp
oclif.manifest.json


1 change: 1 addition & 0 deletions cli/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"../.prettierrc.json"
Loading