477 Commits

Author SHA1 Message Date
joshua-spacetime 312dfaa4e5 Pipeline wasm module operations (#4973)
# Description of Changes

The equivalent changes as
https://github.com/clockworklabs/SpacetimeDB/pull/4962 but for wasm.

# API and ABI breaking changes

See https://github.com/clockworklabs/SpacetimeDB/pull/4962

# Expected complexity level and risk

4

# Testing

See https://github.com/clockworklabs/SpacetimeDB/pull/4962
2026-05-08 11:28:18 +00:00
John Detter eb11e2f5c4 Version bump 2.2.0 (#4916)
# Description of Changes

<!-- Please describe your change, mention any related tickets, and so on
here. -->

- Bumps version to 2.2.0

# API and ABI breaking changes

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

None

# Expected complexity level and risk

- 1 - this is just a version bump

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] Version number is correct (`2.2.0`)
- [x] BSL license file has been updated with the new date and version
number

---------

Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-04-30 19:24:41 +00:00
John Detter 50f5ed034e spacetime publish --yes now takes optional arguments (#4885)
# Description of Changes

<!-- Please describe your change, mention any related tickets, and so on
here. -->

This was prompted from another request from the discord. Conversation
context:
https://discord.com/channels/1037340874172014652/1138987509834059867/1496964407278698656

We've had the ticket to make `--yes` take an enum value:
https://github.com/clockworklabs/spacetimedb/issues/3784 . Since we can
do this in a non-API/ABI breaking way we're just implementing this
ticket.

*Disclaimer: I used claude to write ~90% of this PR.*

# API and ABI breaking changes

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

None. `--yes` now just takes an optional argument string that we parse,
existing CLI commands that use `--yes` will be unaffected.

# Expected complexity level and risk

1 - This is just modifying the `--yes` argument and I've included tests
in the PR.

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] `spacetime publish --yes` still works as expected
- [x] `spacetime publish --yes=all` does the same thing as `spacetime
publish --yes`
- [x] `spacetime publish --yes=remote` only skips asking if publishing
to a remote server is ok.
- [x] `spacetime publish --yes=remote` only skips asking if publishing
to a remote server is ok.
- [x] `spacetime publish --yes=migrate|remote` skips both the migrate
prompt and the remote server prompt.
- [x] new tests are passing
2026-04-30 01:13:12 +00:00
Ryan 2063a933a9 Rekhoff/reapply update nativeaot llvm infrastructure (#4897)
# Description of Changes

Reapply changes from #4515 after reversion

# API and ABI breaking changes

No API or ABI changes

# Expected complexity level and risk

2 - This PR change itself is trivial, as it just reimplements #4515,
however as #4515 had broken the `quickstart` smoketest, this should be
considered when reviewing this PR.

# Testing

- [X] Tested against `python3 -m smoketests quickstart` locally

---------

Signed-off-by: Ryan <r.ekhoff@clockworklabs.io>
Co-authored-by: Tyler Cloutier <cloutiertyler@aol.com>
Co-authored-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
2026-04-28 06:33:35 +00:00
Zeke Foppa 2e01ce8046 CLI - Hide the --server-issued-login param (#4905)
# Description of Changes

Users have an odd tendency to overuse this param, which is really meant
for testing and some exceptional circumstances.

This PR hides it from the help so that it is less discoverable.

# API and ABI breaking changes

None.

# Expected complexity level and risk

1

# Testing

- [x] Helptext no longer includes `--server-issued-login`

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-04-27 17:11:33 +00:00
Zeke Foppa 70db721c3a Revert breaking PRs (#4881)
# Description of Changes

Revert the following PRs that have caused some breakage:
```
a32cffa76 Finish refactoring out replay (#4850)
d639be0af Replay: some code motion & reuse `ReplayCommittedState` (#4849)
78d6b6f7d Update NativeAOT-LLVM infrastructure to current ABI (#4515)
d5c1738c1 Better module backtraces for panics and whatnot (#577)
6f23b19f3 Wait for database update to become durable (#4846)
81c9eab86 Add `spacetime lock/unlock` to prevent accidental database deletion (#4502)
809aebd7c Move field `replay_table_updated` to `ReplayCommittedState` (#4807)
21b58ef99 Update axum (#2713)
b5cadff7a Extract replay stuff out of `CommittedState`, part 1 (#4804)
```

I also updated the Python smoketests for breakage introduced in
https://github.com/clockworklabs/SpacetimeDB/pull/4502. Reverting that
PR caused conflicts, so this fix is more straightforward.

# API and ABI breaking changes

Maybe kind of, but we haven't released any of these.

# Expected complexity level and risk

1

# Testing

Ask @bfops about testing

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-04-23 14:54:23 -07:00
Tyler Cloutier 78d6b6f7dd Update NativeAOT-LLVM infrastructure to current ABI (#4515)
## Summary

- Update the experimental NativeAOT-LLVM build path
(`EXPERIMENTAL_WASM_AOT=1`) to include all host function imports from
ABI versions 10.0 through 10.4
- Fix the compiler package reference to work on both Windows x64 and
Linux x64 (was hardcoded to Windows only)
- Add a CI smoketest to verify AOT builds work on Linux x64

## Context

See #4514 for the full writeup on the C# AOT situation. The
`wasi-experimental` workload that all C# module builds depend on is
deprecated and removed from .NET 9+. NativeAOT-LLVM is the recommended
path forward for ahead-of-time compilation of C# to WebAssembly.

The existing NativeAOT-LLVM support (added by RReverser in #713) was
stale: missing imports added since then and a Windows-only package
reference.

## Changes

**`SpacetimeDB.Runtime.targets`:**
- Add 10 missing `WasmImport` declarations across spacetime_10.0 through
10.4
- Replace `runtime.win-x64.Microsoft.DotNet.ILCompiler.LLVM` with
`runtime.$(NETCoreSdkPortableRuntimeIdentifier).Microsoft.DotNet.ILCompiler.LLVM`
so it resolves correctly on Linux x64 as well
- Use explicit version strings instead of the `$(SpacetimeNamespace)`
variable

**`ci.yml`:**
- Add AOT build smoketest step in the `csharp-testsuite` job

## Test plan

- [x] CI smoketest passes: `EXPERIMENTAL_WASM_AOT=1 dotnet publish -c
Release` builds successfully on Linux x64
- [ ] Existing C# tests continue to pass (no changes to the default
interpreter path)

---------

Signed-off-by: Ryan <r.ekhoff@clockworklabs.io>
Co-authored-by: Ryan <r.ekhoff@clockworklabs.io>
Co-authored-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
2026-04-21 21:47:16 +00:00
Noa d5c1738c15 Better module backtraces for panics and whatnot (#577)
# Description of Changes


![image](https://github.com/clockworklabs/SpacetimeDB/assets/33094578/9c6356af-9b34-462a-8441-8bd859a73b86)

If these symbols aren't in the stack, it does no processing

# Expected complexity level and risk

1 - it's pretty self-contained, and backwards-compatible with the
existing logs data format

---------

Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-04-21 13:08:57 +00:00
clockwork-labs-bot 81c9eab86c Add spacetime lock/unlock to prevent accidental database deletion (#4502)
## Motivation

Feature request: "Is there any way we can lock a module to prevent it
from being deleted? A bit concerned about some fat finger risk of
accidentally deleting prod."

## Solution

Adds a database lock mechanism. A locked database cannot be deleted
until explicitly unlocked.

### New CLI Commands

```bash
# Lock a database to prevent deletion
spacetime lock my-database

# Attempt to delete a locked database (fails with 403)
spacetime delete my-database
# Error: Database is locked and cannot be deleted. Run \`spacetime unlock\` first.

# Unlock when you actually need to delete
spacetime unlock my-database
spacetime delete my-database
```

Both commands support `--server` and `--no-config` flags, and resolve
the database from `spacetime.json` when no argument is given (same as
`spacetime delete`).

### New HTTP API

- `POST /v1/database/:name_or_identity/lock` -- Lock a database
- `POST /v1/database/:name_or_identity/unlock` -- Unlock a database

Both require the same authorization as `DELETE` (owner only).

### Implementation

- Lock state stored in a separate `database_locks` sled tree in the
standalone control DB (avoids changing the `Database` struct and needing
a data migration)
- `ControlStateReadAccess::is_database_locked()` and
`ControlStateWriteAccess::set_database_lock()` added to the trait
- `delete_database` route checks lock state before proceeding; returns
`403 Forbidden` with a descriptive message if locked
- Locking is idempotent (locking an already-locked database is a no-op,
same for unlock)
- Lock only prevents deletion, not publishing updates

### What is NOT locked

- `spacetime publish` (updating module code) still works on locked
databases
- Only `spacetime delete` is blocked

This matches the intent: protect prod from accidental destruction while
allowing normal deployments.

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-04-20 21:03:15 +00:00
Alessandro Asoni 4df71befc2 Fix spacetime dev bug when running with a project path (#4809)
# Description of Changes

Fixes an issue where running `spacetime dev <database name> --template
chat-react-ts --server maincloud` for an existing database and a new
local project folder would fail with this error:

```sh
  Building...
  Error: Failed to build project

  Caused by:
      Module directory does not exist: '/Users/aasoni/./spacetimedb'. Check your --module-path flag or the module-path setting in spacetime.json.
```

Summary of the bug:
- determine_publish_configs was called at line 373 before the project
existed, storing <cwd>/./spacetimedb as the module path
- After init correctly updated spacetimedb_dir to the new project's
path, a later block (lines 454-468) re-read the stale path from the
early publish config and overwrote the correct value
- The rebuild guard at line 498 never triggered because publish_configs
was non-empty (due to the database name CLI argument)

The fix clears publish_configs at the end of the init block, causing the
rebuild at line 498 to run with the correct, post-init spacetimedb_dir.

# API and ABI breaking changes

No

# Expected complexity level and risk

1

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] Re-ran `spacetime dev` with various flags to confirm they all
still worked
- [x] Verified that the specific error case was fixed
2026-04-15 20:48:54 +00:00
clockwork-labs-bot a7a12092b9 Require confirmation for spacetime delete (#4770)
## Summary
- require an explicit confirmation before `spacetime delete` sends an
irreversible delete request
- preserve `--yes` as the non-interactive override
- add smoketests for aborting on `n`, deleting on `y`, and skipping the
prompt with `--yes`

Closes #4679.

## History note
`spacetime delete` has never required confirmation for ordinary deletes.
The command was added in commit `44df6c6e7` (`Initial commit`,
2023-08-01) without a prompt. Later, commit `a36f7091d` (`[teams 3/5]
API authorization, CLI, smoketests`, 2025-11-11) added a confirmation
flow only for the special case where deleting a database would also
delete its children, but plain deletes still executed immediately until
this change.

## Testing
Added new smoketests

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-04-14 19:17:52 +00:00
clockwork-labs-bot 8801913a8d Show database names in spacetime list (#4769)
## Summary
- add a `db_names` column to `spacetime list`
- keep the database identity column too
- use reverse-DNS lookups to show all known names for each database
- degrade gracefully if a reverse lookup fails instead of failing the
whole command

Closes #1046.

## Notes
I looked at #1072 for prior art. This version is adapted to the current
`spacetime list` implementation and uses the existing
`util::spacetime_reverse_dns` helper rather than calling the endpoint
directly.

If a database has no names, the command prints `(unnamed)`.
If a reverse-DNS lookup fails, the command prints `(lookup failed)` for
that row and warns on stderr.

## Testing
- `cargo check -p spacetimedb-cli`

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-04-14 18:58:21 +00:00
clockwork-labs-bot d3aea49b6e Fix spacetime dev ignoring top-level module-path for generate entries (#4656)
Fixes #4651

When `spacetime.json` has a top-level `module-path` and `generate`
entries:

```json
{
  "module-path": "./server",
  "generate": [
    { "language": "rust", "out-dir": "./game_client/src/bindings" }
  ]
}
```

`spacetime dev` passed the generate entries to `exec_from_entries`
without inheriting the top-level `module-path`. The generate step then
fell back to the hardcoded `spacetimedb` default, failing with:

```
Error: Could not find module source at '.../spacetimedb'.
```

The standalone `spacetime generate` command already handled this
correctly via `collect_all_targets_with_inheritance()` (which merges
entity fields into generate entries), but `spacetime dev` bypassed that
path and read `config.generate` directly.

**Fix**: Inject the top-level `module-path` into generate entries that
do not specify their own, before passing them to `exec_from_entries`.

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-03-21 13:08:43 +00:00
Zeke Foppa 480fd5841a Bump versions to 2.1.0 (#4681)
# Description of Changes

Bump versions to 2.1.0

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing
CI

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-03-20 21:53:51 +00:00
Jason Larabie f8d6d76ee4 Update Unreal SDK to websocket 2.0 (#4497)
# Description of Changes

- Updated the Unreal SDK and generated Unreal bindings for the websocket
2.0 protocol/model
  - Reworked DbConnectionBase to handle the updated message shapes
- Switched subscription handling over to new message types and
QuerySetId
- Updated reducer to ReducerResult, removal of callbacks, and set
reducer flags
  - Added event table support
- Baked in multi-module support replacing [the old
PR](<https://github.com/clockworklabs/SpacetimeDB/pull/3417>)
- Added functionality to generate module support for multiple folders in
the Unreal project (add <module>.Build.cs, <module>.h, <module>.cpp)
using the --module-name
- Add new configuration option for spacetime generate to handle module
prefix
 - Regenerated Unreal Blackholio/TestClient/QuickstartChat bindings
   - Rebuilt Unreal Blackholio's consume entity to use event tables 
 - Updated migration documentation
 - Updated the version bump tool to impact C++

# API and ABI breaking changes

- Unreal websocket/message handling updated to the new protocol
- Unreal generation now expects a real .uproject target and will stop
immediately if project
    metadata is invalid instead of continuing past setup issues.

# Expected complexity level and risk

3 - A large set of changes to update the websocket/message handling
along with heavy codegen changes to handle multi-module support

# Testing

Test coverage of the Unreal SDK will need expansion in a future ticket
once our issues with flakiness on CI is resolved.

- [x] Updated Unreal Blackholio 
- [x] Ran full Unreal SDK test suite
- [x] Built new test project using the new `--module-prefix` 
- [x] Run through Unreal Blackholio (C++ and Blueprint)
- [x] Rebuilt Unreal Blackholio with multi-module, and duplicate
generated module testing side-by-side modules that would overlap

# Review Question(s)
- [x] Updates to `spacetime init` have made the tutorial a little
confusing with pathing for the Unreal Blackholio tutorial. To fix though
we'd have to update all the commands to be more explicit, or update the
tutorial `spacetime init` to use `--project-path .` to keep pathing
simpler, thoughts?

---------

Signed-off-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: Ryan <r.ekhoff@clockworklabs.io>
2026-03-18 21:14:06 +00:00
Tyler Cloutier 53256446d4 spacetime.json updates (#4504)
# Description of Changes

Adds a new reference documentation page for `spacetime.json` and fixes
several bugs where the CLI behavior diverged from the proposal.

**Docs:**
- New page at `/cli-reference/spacetime-json` covering config structure,
field reference, generate configuration, children/inheritance,
`spacetime dev` config, database selection, flag overrides,
`--no-config`, `--env`/environments, config file discovery, and editor
support

**Bug fixes:**
- `generate` was incorrectly inherited by child databases. A child with
a different `module-path` would silently inherit the parent's generate
entries, causing bindings to be written to the wrong output directory.
Generate is now never inherited, matching the proposal.
- The source conflict rule for `module-path`/`bin-path`/`js-path` was
not implemented during inheritance. A child specifying `module-path`
could still inherit `bin-path` from the parent. Now, if a child
specifies any module source, the others are not inherited.
- `--num-replicas` was not marked as a per-database override, so it
could be used with multiple databases selected without error.

# API and ABI breaking changes

None. These are bug fixes aligning the implementation with the intended
behavior from the proposal:
- `generate` inheritance was never documented or intended
- The source conflict rule was specified in the proposal but not
implemented
- `--num-replicas` as per-database is consistent with the other
module-source flags

# Expected complexity level and risk

2 - The changes are small and well-scoped. The generate inheritance fix
simplifies the code (removes a parameter). The source conflict rule adds
a straightforward check during field inheritance. Tests have been
updated to match.

# Testing

- [x] All 136 existing CLI tests pass
- [x] Updated tests for generate non-inheritance behavior
- [x] Docs site builds successfully, page renders in sidebar
- [ ] Manual test: verify a child with a different `module-path` no
longer inherits parent's `generate`
- [ ] Manual test: verify `--num-replicas` errors when multiple
databases are selected

---------

Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Phoebe Goldman <phoebe@clockworklabs.io>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
2026-03-14 20:42:39 +00:00
clockwork-labs-bot c5fa5d6fe7 Fix spacetime login --token falling through to web login (#4579)
## Bug

PR #4367 (login/logout UX overhaul) accidentally removed the early
`return Ok(())` after saving a token via `spacetime login --token`. This
caused the command to fall through into the web login flow
(`spacetimedb_login_and_save`), which fails when no browser or server is
available.

## Impact

All tests that use `spacetime login --token` are broken:
- 4 replication tests (`test_enable_disable_replication`,
`test_enable_replication_on_suspended_database`,
`test_enable_replication_fails_if_not_suspended`, `test_prefer_leader`)
- 5 teams tests (`test_permissions_clear_org`,
`test_permissions_delete_org`,
`test_org_permissions_mut_sql_org_members`,
`test_org_permissions_private_tables`,
`test_permissions_publish_org_members`)

## Fix

One line: restore `return Ok(())` after the `--token` branch.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-03-07 06:06:38 +00:00
clockwork-labs-bot 78c8acd0c9 Improve login/logout CLI UX (#4367)
## Summary

Improves the `spacetime login` and `spacetime logout` UX to behave more
like standard CLI tools.

### `spacetime login`

**Before:** If already logged in, prints "You are already logged in" and
exits. User must manually run `logout` first.

**After:** If already logged in, automatically logs out the previous
session and proceeds with a fresh login. Prints the old identity being
logged out and the new identity on success.

```
$ spacetime login
Logged out of previous session (identity 0xabc...).
Opening https://spacetimedb.com/login/cli?token=... in your browser.
Waiting to hear response from the server...
Logged in with identity 0xdef...
```

### `spacetime logout`

**Before:** No output on success. Hard failure if offline.

**After:**
- Prints confirmation: `Logged out (identity 0xabc...).`
- Prints `You are not logged in.` if already logged out
- Best-effort server-side session invalidation with 5s timeout (prints
warning if offline instead of failing)

### Changes

- `login.rs`: Remove `spacetimedb_token_cached` early-return; instead
log out previous session and proceed. Show identity on login success.
- `logout.rs`: Add identity display, not-logged-in check, 5s timeout for
server call with warning on failure.

Note: This subsumes the offline fix from #4361.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-03-06 00:23:09 +00:00
clockwork-labs-bot 476d15755e spacetime dev - Replace template selection with fuzzy-filterable menu (#4470)
This pull request updates the template system to support richer metadata
and improves the interactive CLI experience for selecting templates. The
main changes are the addition of a `client_framework` field to template
metadata, a refactor of the templates JSON generation and parsing, and a
redesign of the interactive template selection flow to group templates
by language/framework and use fuzzy search for easier navigation.

<img width="407" height="409" alt="image"
src="https://github.com/user-attachments/assets/d3548505-80e8-4778-8bfb-71d5e3fe31e9"
/>

**Template Metadata and Serialization Improvements:**

* Added a new `client_framework` field to all template metadata files
(e.g., `.template.json`) and updated the Rust structs (`TemplateInfo`,
`TemplateDefinition`, etc.) to support this field, enabling more
descriptive and flexible template selection.
[[1]](diffhunk://#diff-5438edbe7b41e3e0a1a62ce0ebde2a833a0441d76c6ffdf16093a3cff258f462R3)
[[2]](diffhunk://#diff-34a44755a07373e9c2872db87a64c3fd752cfee7d8d536045909daf861ea4728R3)
[[3]](diffhunk://#diff-a826c5a2eac977cff44022d72856ec4b1af176ffbb50697f22857e1e3d478aa1R3)
[[4]](diffhunk://#diff-7a21474fbc5bbbd989e89f32aa8dcc25fcc6fe4ac43d418c42b2b38603d21714R3)
[[5]](diffhunk://#diff-d8ee9fd0ef15ed23f0f7f38e556d789bdefc6c37dab67fbfccebc513b9da871cR3)
[[6]](diffhunk://#diff-7224fd4300f9c5af7834ff5989a76a399ce9117c28f5d7e2c1fbd6bdaf45be1bR3)
[[7]](diffhunk://#diff-8b015b0ce6339c444ef5ef4dc5e862275d98967e5c189da37b51bdaa58443606R3)
[[8]](diffhunk://#diff-89e32f7fc9fc42863998d7651bc7fa1fdfb352e8ac3ef45792e3f1374052c9ddR3)
[[9]](diffhunk://#diff-8259d300fda149c968a68989aec2bc2afa479aded649ac6b8d3c4b277f610542R3)
[[10]](diffhunk://#diff-bb8b9202e51fb7038efa2f2bb23872afa02caf71ab3a0fb7f513ca7822c1b8faR3)
[[11]](diffhunk://#diff-18497b72a2306fc2560475e2548cfe1b96b6206c395380437ba1fafefd66e126L199-R221)
[[12]](diffhunk://#diff-18497b72a2306fc2560475e2548cfe1b96b6206c395380437ba1fafefd66e126R279)
* Refactored the templates JSON generation to use `serde` for
serialization, replacing manual string building, and ensured that
optional string fields serialize as empty strings when not present.

**CLI Interactive Template Selection Redesign:**

* Removed the previous "highlights" concept and reworked the interactive
selection to group templates by language/framework combinations, showing
counts and using fuzzy search for easier filtering.
[[1]](diffhunk://#diff-7fcfe09d0f54dde6b2fc0cb2b9ff02ab064add692f5602d6f627fe3840e282caL38-L48)
[[2]](diffhunk://#diff-7fcfe09d0f54dde6b2fc0cb2b9ff02ab064add692f5602d6f627fe3840e282caL772-R833)
[[3]](diffhunk://#diff-7fcfe09d0f54dde6b2fc0cb2b9ff02ab064add692f5602d6f627fe3840e282caL813-L850)
* Updated the selection menus to allow users to pick a
language/framework group, then choose from multiple templates if
available, or opt to clone from GitHub or select "None."
[[1]](diffhunk://#diff-7fcfe09d0f54dde6b2fc0cb2b9ff02ab064add692f5602d6f627fe3840e282caL772-R833)
[[2]](diffhunk://#diff-7fcfe09d0f54dde6b2fc0cb2b9ff02ab064add692f5602d6f627fe3840e282caL813-L850)
* Improved language label formatting for better user experience in the
CLI prompt.

**Codebase Cleanup and API Changes:**

* Removed unused highlight-related structs and logic from the CLI,
simplifying the template fetching API to return only templates.
[[1]](diffhunk://#diff-7fcfe09d0f54dde6b2fc0cb2b9ff02ab064add692f5602d6f627fe3840e282caL38-L48)
[[2]](diffhunk://#diff-7fcfe09d0f54dde6b2fc0cb2b9ff02ab064add692f5602d6f627fe3840e282caL198-R198)
* Updated all template selection logic to use the new API and data
structures.
[[1]](diffhunk://#diff-7fcfe09d0f54dde6b2fc0cb2b9ff02ab064add692f5602d6f627fe3840e282caL683-R679)
[[2]](diffhunk://#diff-7fcfe09d0f54dde6b2fc0cb2b9ff02ab064add692f5602d6f627fe3840e282caL748-R744)

These changes make template selection more intuitive and scalable as
more templates and frameworks are added.

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-03-04 23:44:36 +00:00
Noa e3582131fe Migrate to Rust 2024 (#3802)
# Description of Changes

It'd be best to review this commit-by-commit, and using
[difftastic](https://difftastic.wilfred.me.uk) to easily tell when
changes are minor in terms of syntax but a line based diff doesn't show
that.

# Expected complexity level and risk

3 - edition2024 does bring changes to drop order, which could cause
issues with locks, but I looked through [all of the warnings that
weren't fixed
automatically](https://gistcdn.githack.com/coolreader18/80485ae5c5f82de1784229cce2febb26/raw/ba80f3fecda66ceb34f4f7ad73b98ea02d4893a2/warnings.html)
and couldn't find any issues.

# Testing

n/a; internal code change
2026-03-03 11:06:52 +00:00
clockwork-labs-bot 7470eb23d3 Add --level flag to spacetime logs for filtering by log level (#4362)
Fixes #1972

Adds client-side log level filtering to `spacetime logs`:

- `--level <LEVEL>` / `-l <LEVEL>`: Show only logs at the specified
severity or higher. Valid values: `trace`, `debug`, `info`, `warn`,
`error`, `panic`. Default: show all logs (no filtering).
- `--level-exact`: When combined with `--level`, show only logs at
exactly the specified level.

Severity order (most to least): panic > error > warn > info > debug >
trace.

Examples:
```
spacetime logs mydb --level warn                # Show only warn, error, and panic
spacetime logs mydb --level info                 # Show info and above
spacetime logs mydb --level error --level-exact  # Show only errors
```

Filtering is done client-side.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-03-03 07:02:46 +00:00
John Detter 033c181337 Upgrade prompt is skipped when -y is passed (#4511)
# Description of Changes

<!-- Please describe your change, mention any related tickets, and so on
here. -->

This prompt is now skipped when `-y` is passed:

<img width="1053" height="530" alt="image"
src="https://github.com/user-attachments/assets/7237df85-4a12-4ab7-b377-95abbd0084c2"
/>

# API and ABI breaking changes

None

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

# Expected complexity level and risk

1 - this just skips a prompt in the CLI

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

- [x] publish a 1.0 database to maincloud, then upgrade it to 2.0 and
pass `-y`. You should no longer get the upgrade prompt.
- [x] publish a 1.0 database to maincloud, then upgrade it to 2.0
without passing `-y`. You should still get the upgrade prompt.
2026-03-02 18:28:29 +00:00
clockwork-labs-bot 9fbb322b0b CLI - preserve leading .. in --out-dir paths (#4431)
## Problem

`spacetime generate --out-dir ../frontend-ts-src/module-bindings` was
resolving the path incorrectly, stripping the leading `..` component.
Reported in #4429 via a [user report on
Discord](https://discord.com/channels/1037340874172014652/1475935288919462072/1475935288919462072).

## Root Cause

`normalize_path_lexical()` in `spacetime_config.rs` used
`PathBuf::pop()` to handle `..` components, but `pop()` is a no-op on an
empty `PathBuf`. This silently dropped leading `..` segments:

- Input: `../frontend-ts-src/module-bindings`
- Output: `frontend-ts-src/module-bindings` (wrong — `..` was eaten)

## Fix

Replace the `PathBuf`-based normalization with a `Vec<Component>` stack
approach. `..` only cancels a preceding `Normal` component; otherwise it
is preserved. This correctly handles:

- `../foo` → `../foo` (leading `..` preserved)
- `../../a/b` → `../../a/b` (multiple leading `..` preserved)
- `a/b/../c` → `a/c` (inner `..` still resolves)
- `/home/user/project/../foo` → `/home/user/foo` (absolute paths work)

## Testing

Added `test_normalize_path_preserves_leading_dotdot` covering all edge
cases.

Closes #4429

---------

Co-authored-by: clockwork-labs-bot <bot@clockworklabs.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-02-26 19:54:20 +00:00
Piotr Sarnacki ad26525880 Fix publishing in directories with spaces (#4453)
# Description of Changes

The publish subcommand calls the build subcommand internally. The
build's implementation used to split the arguments by space, which
breaks when a directory contains a space.

# API and ABI breaking changes

-

# Expected complexity level and risk

1

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] Tested locally
- [x] Added a test
2026-02-26 19:29:40 +00:00
clockwork-labs-bot 4375cb81a8 spacetime dev - Print feedback when client process exits (#4469)
The main event loop in `spacetime dev` blocked on file change events
with no periodic check on the client process. If the client exited
(e.g., user pressed Enter in the basic-rs template), `spacetime dev`
gave no feedback at all.

**Fix**: Switch from blocking `recv()` to `recv_timeout(1s)` and check
client process status every second. On exit, prints:

- `Client process exited. File watcher is still active.` (exit code 0)
- `Warning: Client process exited with code N. File watcher is still
active.` (non-zero)

The file watcher continues running so module changes are still detected
and published.

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-02-26 18:31:01 +00:00
clockwork-labs-bot 350066ab4c spacetime dev - Fix file watcher ignoring --module-path / spacetime.json module_path (#4464)
## Summary

Fixes #4443 — `spacetime dev` ignores both `--module-path` CLI flag and
`module-path` in `spacetime.json` for the file watcher, always watching
`<project-path>/spacetimedb/` instead.

## Root Cause

Two bugs:

1. **Config's `module-path` never applied to `spacetimedb_dir`**: When
`spacetime.json` contains `module-path`, the recovery prompt is
correctly skipped (the code checks for its existence), but the value is
never used to update `spacetimedb_dir`. It stays as
`project_dir/spacetimedb`.

2. **Hardcoded fallback in `determine_publish_configs()`**: When there
are no publish targets in config (no `database` key or `children`), the
fallback creates a publish config entry with `module-path:
"spacetimedb"` hardcoded. This propagates to `extract_watch_dirs()`
(file watcher) and the publish loop, overriding any CLI or config value.

## Fix

1. After loading config, resolve `spacetimedb_dir` from config's
`module-path` in `additional_fields` when CLI did not provide
`--module-path`.

2. Pass the resolved `spacetimedb_dir` to `determine_publish_configs()`
as `default_module_path` so the fallback uses the correct path instead
of hardcoding `"spacetimedb"`.

## Testing

- All 5 existing `determine_publish_configs` tests pass
- Added new test
`test_determine_publish_configs_fallback_uses_provided_module_path` that
verifies the fallback uses the provided path

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-02-26 11:06:21 +00:00
clockwork-labs-bot ebea9a4b5c spacetime dev - Improve error when module directory does not exist (#4467)
When `spacetime dev` (or `publish`) cannot find the module directory,
the error was:

```
Error: Failed to build project
Could not detect the language of the module. Are you in a SpacetimeDB project directory?
```

This is confusing because the real problem is the directory does not
exist, not that the language cannot be detected.

Now shows:

```
Module directory does not exist: '/path/to/missing/dir'.
Check your --module-path flag or the module-path setting in spacetime.json.
```

Related to #4443.

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-02-26 08:37:07 +00:00
Piotr Sarnacki 0f0d54b03b Remove source-config field from spacetime.json (#4423)
# Description of Changes

We mistakenly were saving source-config field to the spacetime.json
config file. This commit automatically removes the filed if it's
present. Note that in order to preserve comments that users might have
added we use text based modification, but we validate the resulting JSON
before saving

# Expected complexity level and risk

2

# Testing

I tested locally
2026-02-24 17:27:24 +00:00
Piotr Sarnacki ec434f3f67 Don't save source_config to spacetime.json (#4422)
# Description of Changes

We mistakenly save a struct field that is only for internal usage into
the spacetime.json config file. This PR fixes that.


# Expected complexity level and risk

1
2026-02-24 17:27:13 +00:00
Tyler Cloutier a4d29daec8 Fix spacetime dev template issues and clean up CLI (#4396)
## Summary

Multiple fixes and improvements to `spacetime dev`, `spacetime publish`,
`spacetime init`, and templates:

### CLI fixes
- **Fix `spacetime dev` watch path and .env.local handling** for
templates with a `spacetimedb/` subdirectory
- **Validate package manager availability** before installing
dependencies — re-prompts if the selected PM isn't on PATH
- **Remove JS/TS beta warning** from `spacetime publish`
- **Remove unstable warning** from `spacetime init`
- **Remove unused `spacetime energy` command** (can be re-added later
when properly implemented)
- **Fix `tsc` detection on Windows** — `set_extension(".cmd")` produced
`tsc..cmd` (double dot); fixed to `set_extension("cmd")`
- **Add `typescript` as devDependency** to all server template
`spacetimedb/package.json` files so `tsc` is available during build
- **Strip `\?\` extended-length path prefix** from user-facing output in
both `dev` and `publish` commands (produced by `fs::canonicalize()` on
Windows)
- **Fix publish reporting success when user declines** non-local server
prompt — changed `return Ok(())` to `bail!()` consistent with other
abort cases
- **Forward stdin to client process** in `spacetime dev` so interactive
CLI templates work

### Template fixes
- **Fix Angular template environment variables** — Angular's esbuild
builder doesn't support `import.meta.env`, so we use a dev script to
generate `environment.local.ts` with Angular's native `fileReplacements`
pattern
- **Fix TanStack Start template** — rename `createRouter` to `getRouter`
(v1.121+ breaking change), upgrade to React 19, and add
`@vitejs/plugin-react` for automatic JSX runtime support
- **Fix `moduleResolution` in remix-ts and nextjs-ts** server tsconfigs
— change from `"node"` to `"bundler"` to support subpath exports like
`spacetimedb/server`
- **Fix browser-ts template** — convert from static HTML + IIFE bundle
to standard Vite dev server app so it works with `spacetime dev` and
reads env vars from `.env.local`
- **Add `deno` as devDependency** to deno-ts template (matches how
bun-ts includes bun)
- **Convert basic-ts from empty web app to CLI app** matching basic-rs —
connect, subscribe to person table, print on insert

## Test plan

- [x] `cargo test -p spacetimedb-cli` — all 133 tests pass
- [ ] `spacetime dev --template angular-ts` — verify Angular app
connects with correct database name
- [ ] `spacetime dev --template react-ts` — verify React template still
works
- [ ] `spacetime dev --template tanstack-ts` — verify TanStack Start
template loads without errors
- [ ] `spacetime dev --template remix-ts` — verify Remix template builds
and runs
- [ ] `spacetime dev --template nextjs-ts` — verify Next.js template
still works
- [ ] `spacetime dev --template browser-ts` — verify Vite dev server
starts and app connects
- [ ] `spacetime dev --template bun-ts` — verify Bun CLI template runs
interactively
- [ ] `spacetime dev --template basic-ts` — verify CLI connects and
prints on insert
- [ ] Verify no `\?\` prefix in any displayed paths on Windows
- [ ] Verify no `tsc not found` warning when building server modules
- [ ] Select unavailable package manager at init prompt — verify
re-prompt
- [ ] Decline non-local server prompt — verify clean error instead of
"Published successfully!"

---------

Co-authored-by: Piotr Sarnacki <drogus@gmail.com>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <bot@clockworklabs.com>
2026-02-24 02:39:42 -05:00
clockwork-labs-bot b002158db8 Enable confirmed reads by default (#4390)
## Summary

Enable confirmed reads by default for all WebSocket subscriptions and
SQL queries. This is a 2.0 breaking change that improves data integrity.

### What changed

Previously, subscription updates and SQL results were sent to clients
immediately, before the transaction was confirmed durable. A server
crash could cause clients to have observed data that was lost.

Now the server defaults to `confirmed=true`. Clients receive updates
only after durability is confirmed. This adds a small latency cost but
guarantees that any data a client receives will survive a server
restart.

### Changes

**Server (2 files, 2 lines each):**
- `subscribe.rs`: `SubscribeQueryParams.confirmed` defaults to `true`
- `database.rs`: `SqlQueryParams.confirmed` defaults to `true`

**Documentation:**
- Migration guide updated with "Confirmed Reads Enabled by Default"
section
- Added to overview list and quick migration checklist

### Opt-out

Clients can opt out by explicitly passing `?confirmed=false` in the
WebSocket URL or using `.withConfirmedReads(false)` /
`.WithConfirmedReads(false)` / `.with_confirmed_reads(false)` in SDKs.

### Smoketest impact

Smoketests that don't explicitly pass `--confirmed` will now get
confirmed reads via the server default. This should not cause failures
-- confirmed reads only add a small wait for durability confirmation
before sending results. The `confirmed_reads.py` smoketest explicitly
passes `--confirmed` and continues to work as before.

### SDK impact

No SDK changes needed. SDKs only send the `confirmed` query parameter
when explicitly set by the user. When not set, the server default
applies -- which is now `true`.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <bot@clockworklabs.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-02-24 02:27:42 +00:00
Jason Larabie e476668b3a C++ Quickstart - spacetime dev not working (#4414)
# Description of Changes
Updated the /templates/basic-cpp to target Rust 2.0.* and add
pre-generated bindings as the updated `spacetime dev` seems to require
that.

# API and ABI breaking changes

N/A 

# Expected complexity level and risk

1 - Template only change

# Testing

- [x] Was able to use `spacetimedb-cli.exe dev --template basic-cpp`
2026-02-24 00:05:10 +00:00
Phoebe Goldman 0f8bff5f01 sql_parts does not conflict with interactive in CLI sql subcommand (#4402)
# Description of Changes

With the introduction of `spacetime.json`, our arg parsing has gotten
more complex, and in particular, we now use the `sql_parts` argument to
pass the database name rather than a separate positional arg, to support
eliding the database name. This means that there is a case where both
`sql_parts` and `interactive` will be supplied, so they cannot be marked
as conflicting.

# API and ABI breaking changes

N/a

# Expected complexity level and risk

1

# Testing

- [x] Manually ran `spacetime sql --interactive my-database`, which
worked locally with this patch.
2026-02-23 20:47:26 +00:00
clockwork-labs-bot 3b48c4bee5 Fix spacetime logout failing when offline (#4361)
Fixes #2437

`spacetime logout` previously required a network connection to the auth
server, making it impossible to log out (and thus log in with a
different method) when offline.

This change makes the server-side session invalidation best-effort: if
the auth server is unreachable, a warning is printed but local
credentials are still cleared. This allows offline development workflows
like `spacetime login --server-issued-login local`.

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-02-23 18:07:52 +00:00
Piotr Sarnacki 19cc87ebfa Allow skipping DB if the config file is available (#4358)
# Description of Changes

This PR introduces a possibility to skip passing a DB name to various
commands if there is a config file with one database defined

# API and ABI breaking changes

This changes the behaviour of several CLI commands:

  1. call
  2. subscribe
  3. sql
  4. describe
  5. logs
  6. delete

# Expected complexity level and risk

4 - it's tricky to get all of the combinations of CLI arguments right

# Testing

I've tested the simplest cases manually.

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: = <cloutiertyler@gmail.com>
2026-02-20 17:48:54 +00:00
Tyler Cloutier b2bb2180c5 Fix spacetime dev watch filtering and improve quickstart copy-paste experience (#4317)
## Summary
- Fix `spacetime dev` failing on C# projects by watching the module
directory itself instead of hardcoded `spacetimedb_dir/src/` (which
doesn't exist for C# templates)
- Add layered file-watch filtering to avoid triggering rebuilds on build
artifacts:
1. Always-ignore dirs (`target/`, `bin/`, `obj/`, `node_modules/`, etc.)
  2. Always-watch exceptions (`.env.local`, `spacetime.*.local.json`)
  3. `.gitignore` rules from global, project, and module levels
- Suppress init's generic "Next steps" message when called from
`spacetime dev`, print a dev-appropriate `cd` hint instead when a new
project is created in a subdirectory
- Update 12 quickstart docs to tell users to open a new terminal and `cd
my-spacetime-app` before running CLI commands

## Test plan
- [x] `cargo build -p spacetimedb-cli` compiles successfully
- [ ] `spacetime dev --template basic-cs` no longer errors with "Input
watch path is neither a file nor a directory"
- [ ] Modifying a `.cs` file in `spacetimedb/` triggers a rebuild
- [ ] Build artifacts in `obj/`/`bin/` do not trigger rebuilds
- [ ] Rust projects (`spacetimedb/src/` exists) continue to work as
before
- [ ] `spacetime dev --template basic-cs` from a non-project directory
prints the "Tip: cd" hint, not the generic "Next steps"
- [ ] `spacetime init` standalone still prints "Next steps" as before

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-02-19 23:12:34 +00:00
Piotr Sarnacki 1a0e36e3a9 Warn about publishing DBs from non-local/non-dev spacetime.json in dev (#4350)
# Description of Changes

At the moment, we warn about using a database with a name from
`spacetime.json` in `dev`, but it only checks the root database. This PR
adds support for children, too.

# Expected complexity level and risk

2

# Testing

- [x] Added automated tests
- [x] Tested locally

With the following configs:

```json
# spacetime.json
{
  "server": "maincloud",
  "module-path": "./spacetimedb",
  "database": "main",
  "children": [{
    "database": "foo",
    "module-path": "foo"
  }, {
    "database": "bar",
    "module-path": "bar"
  }]
}
```

```json
# spacetime.local.json
{
  "children": [
    {
      "database": "foo-local"
    }
  ],
  "database": "main"
}
```

This is the output of `spacetime dev`:

```
✓ Using configuration from ./spacetime.json, ./spacetime.local.json

Starting development mode...
Databases: main, foo-local, bar
Watching for changes in 3 directories:
  - /Users/drogus/code/clockwork/spacetime-config-test/my-spacetime-app/spacetimedb
  - /Users/drogus/code/clockwork/spacetime-config-test/my-spacetime-app/foo
  - /Users/drogus/code/clockwork/spacetime-config-test/my-spacetime-app/bar
Warning: You are trying to publish databases in dev mode that were defined in the main spacetime.json file: bar
Do you want to proceed? [Y/n]
```

---------

Signed-off-by: Piotr Sarnacki <drogus@gmail.com>
Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
2026-02-19 22:34:36 +00:00
Piotr Sarnacki d9a1ce8153 Fix publishing and generating from subdirs if config is present (#4351)
# Description of Changes

When config is present and no explicit `module-path` has been passed, we
should be resolving paths from the config and defaults relative to the
config file

# Expected complexity level and risk

2

# Testing

- [x] Tested locally
2026-02-19 19:37:20 +00:00
Ryan 1d48c08f46 Update to generated C# template package version (#4349)
# Description of Issue

When you run `spacetime dev --template basic-cs` and give it the default
inputs, the `.csproj` files it generates use the package versions of
`1.*` rather than `2.*`.
The relative path locations are:
* `.\my-spacetime-app\client.csproj`
* `.\my-spacetime-app\spacetimedb\StdbModule.csproj`
This is deceptive because in `.\SpacetimeDB\templates\basic-cs`, each
file has a `2.0.*` for the package versions.

This issue results in an error when trying to use a C# template, as
specific 2.0 features are not properly detected.

This happens because:
1. When you run `spacetime dev` outside an existing project, the dev
subcommand notices the missing spacetimedb/ directory and internally
calls `init::exec_with_options` with your requested template
(`basic-cs`) to scaffold a project first. That logic lives in
`crates/cli/src/subcommands/dev.rs` and triggers whenever `dev` is asked
to initialize a template before continuing.
2. The template assets under `templates/basic-cs` indeed still contain
`2.0.*` package references, but after the embedded files are copied, the
initializer runs `update_csproj_client_to_nuget` and
`update_csproj_server_to_nuget`. These functions rewrite the first
`.csproj` they find in the client/server directories to depend on NuGet
packages rather than local project references.
3. Both helpers call `get_spacetimedb_csharp_runtime_version()` /
`get_spacetimedb_csharp_clientsdk_version()`, and those helpers
currently hard-code `"1.*"` as the version string.

That’s why your freshly generated `client.csproj` and
`spacetimedb/StdbModule.csproj` end up with `1.*` package versions even
though the template files started at `2.0.*`

# Description of Changes

Updates the `get_spacetimedb_csharp_runtime_version()` and
`get_spacetimedb_csharp_clientsdk_version()` functions to return `2.*`

# API and ABI breaking changes

No API/ABI changes

# Expected complexity level and risk

1 - Low

# Testing

- [X] Ran `spacetime dev --template basic-cs` locally and confirmed
`.csproj` files generate with `2.*` package versions.
2026-02-19 18:21:57 +00:00
Piotr Sarnacki 39bf47e025 spacetime.json related fixes and improvements (#4332)
# Description of Changes

This PR fixes a bunch of issues and brings some improvements related to
`spacetime.json` config file

# API and ABI breaking changes

-

# Expected complexity level and risk

3

This PR is changing several places that are called during many of the
CLI commands.

# Testing

- [x] Added some automated tests
- [ ] Tested locally
2026-02-18 22:54:56 +00:00
Noa 6622e2f975 [TS] better build followup (#4334)
# Description of Changes

Forgot to push something for #4330, whoops. Now it will actually give
the output in that PR.

# Testing

- [x] Already tested.
2026-02-18 04:34:43 +00:00
Noa 0799becfc5 Improve spacetime build for typescript (#4330)
# Description of Changes

This fixes the confusing error encountered by @gefjon:

```
$ spacetime publish -s local --module-path spacetimedb --no-config event-table-test-ts
Rolldown warning: Could not resolve 'spacetimedb/server' in spacetimedb/src/index.ts
Error: Your module doesn't import the `spacetimedb/server` package at all - this is likely a mistake, as your module will not be able to interface with the SpacetimeDB host.
```
After:
```
[UNRESOLVED_IMPORT] Error: Could not resolve 'spacetimedb/server' in src/index.ts
   ╭─[ src/index.ts:1:47 ]
   │
 1 │ import { schema, table, t, SenderError } from 'spacetimedb/server';
   │                                               ──────────┬─────────  
   │                                                         ╰─────────── Module not found.
   │ 
   │ Help: You may have forgotten to install dependencies with your package manager.
───╯
```

And also runs `tsc`, so that modules with type errors aren't silently
published. Perhaps we want a `--skip-tsc` so that people can run anyway
and get runtime errors?


# Expected complexity level and risk

2

# Testing

- [x] Ensured that tsc and rolldown errors are properly emitted.
2026-02-18 00:02:44 +00:00
Piotr Sarnacki 4c962b9170 spacetime.json config implementation (#4199)
# Description of Changes

This PR implements support for the `spacetime.json` configuration file
that can be used to set up common `generate` and `publish` targets. An
example of `spacetime.json` could look like this:

```
{
  "dev_run": "pnpm dev",
  "generate": [
    { "out-dir": "./foobar", "module-path": "region-module", "language": "c-sharp" },
    { "out-dir": "./global", "module-path": "global-module", "language": "c-sharp" },
  ],
  "publish": {
    "database": "bitcraft",
    "module-path": "spacetimedb",
    "server": "local",
    "children": [
      { "database": "region-1", "module-path": "region-module", server: "local" },
      { "database": "region-2", "module-path": "region-module", server: "local" }
    ]
  }
}
```

With this config, running `spacetime generate` without any arguments
would generate bindings for two targets: `region-module` and
`global-module`. `spacetime publish` without any arguments would publish
three modules, starting from the parent: `bitcraft`, `region-1`, and
`region-2`. On top of that, the command `pnpm dev` would be executed
when using `spacetime dev`.

It is also possible to pass additional command line arguments when
calling the `publish` and `generate` commands, but there are certain
limitations. There is a special case when passing either a module path
to generate or a module name to publish. Doing that will filter out
entries in the config file that do not match. For example, running:

```
spacetime generate --project-path global-module
```

would only generate bindings for the second entry in the `generate`
list.

In a similar fashion, running:

```
spacetime publish region-1
```

would only publish the child database with the name `region-1`

Passing other existing arguments is also possible, but not all of the
arguments are available for multiple configs. For example, when running
`spacetime publish --server maincloud`, the publish command would be
applied to all of the modules listed in the config file, but the
`server` value from the command line arguments would take precedence.
Running with arguments like `--bin-path` would, however, would throw an
error as `--bin-path` makes sense only in a context of a specific
module, thus this wouldn't work: `spacetime publish --bin-path
spacetimedb/target/debug/bitcraft.wasm`. I will throw an error unless
there is only one entry to process, thus `spacetime publish --bin-path
spacetimedb/target/debug/bitcraft.wasm bitcraft` would work, as it
filters the publish targets to one entry.

# API and ABI breaking changes

None

# Expected complexity level and risk

3

The config file in itself is not overly complex, but when coupled with
the CLI it is somewhat tricky to get right. There are also some changes
that I had to make to how clap arguments are validated - because the
values can now come from both the config file and the clap config, we
can't use some of the built-in validations like `required`, or at least
I haven't found a clean way to do so.

# Testing

I've added some automated tests, but more tests and manual testing is
coming.

---------

Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: bradleyshep <148254416+bradleyshep@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: = <cloutiertyler@gmail.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
2026-02-15 23:22:44 +00:00
Noa c044d96a7a [TS] schema() takes an object (#4273)
# Description of Changes

Implements the rest of the casing proposal.

# Expected complexity level and risk

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [ ] <!-- maybe a test you want to do -->
- [ ] <!-- maybe a test you want a reviewer to do, so they can check it
off when they're satisfied. -->
2026-02-13 07:53:42 +00:00
Tyler Cloutier 184d4e9d3f Implement server-side support for the v2 websocket protocol (#4213)
# Description of Changes

This adds the v2 websocket protocol and adds support on the server side.
For context on many of the changes/decisions, you can look at the
discussion on https://github.com/clockworklabs/SpacetimeDB/pull/4023.

To restate some of the key changes:
- The reducer event information is no longer sent with transaction
updates (because we don't want to broadcast reducer call information
anymore).
- If a client calls a reducer, they are sent a `ReducerResult` which
includes the outcome of the reducer call and and related row updates for
queries that the client is subscribed to.
- We no longer dedupe queries that appear in multiple query sets for the
same client. This is because we are moving toward per-query storage.
- Related to that, Unsubscribe requests have an option to send the
related rows. We need this for now, since clients don't have per-query
storage implemented yet.
 - We don't have the json format in v2.

Notes for reviewers:
- This moves around the messages in
`crates/client-api-messages/src/websocket` (into `common`, `v1`, and
`v2`), and this renaming of existing messages adds a lot of noise to the
PR.
- In many places, I chose to duplicate a lot of code to have a v1
version and a v2 version. I went with this to make it easier to remove
the v1 version in the future (hopefully we can just fully delete most of
the v1 functions).
- `module_subscription_manager.rs` has probably has the biggest changes,
since we now track queries by query_set_id, and we get to remove some
complexity of v1's FormatSwitch.

<!-- Please describe your change, mention any related tickets, and so on
here. -->

# API and ABI breaking changes

The v1 protocol still works, though we won't send the reducer event info
for v10 modules.

# Expected complexity level and risk

4. This touches a lot of places.

# Testing

Unit testing is pretty minimal for the new code paths. I've done some
manual e2e testing with the typescript quickstart, and this has been
tested with a different branch implementing the v2 rust client.

---------

Co-authored-by: Phoebe Goldman <phoebe@goldman-tribe.org>
Co-authored-by: Jeffrey Dallatezza <jeffreydallatezza@gmail.com>
2026-02-12 20:39:26 +00:00
John Detter 50295ac865 Version upgrade to 2.0 (#4252)
# Description of Changes

<!-- Please describe your change, mention any related tickets, and so on
here. -->

- Version upgrade to 2.0.

# API and ABI breaking changes

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

# Expected complexity level and risk

1 - this is just a version bump

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] License file has been updated
- [x] CI passing

---------

Signed-off-by: John Detter <4099508+jdetter@users.noreply.github.com>
2026-02-12 16:25:49 +00:00
Noa 253095aab5 Bump rolldown to 1.0.0-rc.3 (#4259)
# Description of Changes

Rolldown likely [won't release 1.0 until after vite
8.0](https://voidzero.dev/posts/announcing-rolldown-rc), but I figure we
should keep up to date somewhat and switch from the beta to the rc.

# Expected complexity level and risk

1

# Testing

- [x] `spacetime build` with typescript modules still works.

---------

Signed-off-by: Noa <coolreader18@gmail.com>
2026-02-12 09:01:39 +00:00
Noa 7677b5478f [TS] Export reducers, etc from a module (#4220)
# Description of Changes

Haven't changed `schema()` to accept an object yet, maybe that's for a
followup?

Now everything exported from the module must be exported from the
typescript module.

# Expected complexity level and risk

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [ ] <!-- maybe a test you want to do -->
- [ ] <!-- maybe a test you want a reviewer to do, so they can check it
off when they're satisfied. -->
2026-02-11 22:45:36 +00:00
Jason Larabie c59ee1ddc3 [2.0 Breaking] Add --include-private and default private tables to not generate (#4241)
# Description of Changes
Updated the codegen table/function iteration functions to take in a
parameter to check visibility in all locations for the supported
languages.
- Updated the util.rs functions for iterating tables/functions to check
for a CodegenVisibility enum (IncludePrivate, or OnlyPublic)
- Added a new CodegenOptions struct to pass around the CodegenVisibility
and future flags, defaulted visibility to OnlyPublic
- Updated the CLI to return a list of all private tables not included
(added a TODO to check the --include-private opt):
```bash
Optimising module with wasm-opt...
Build finished successfully.
Skipping private tables during codegen: secret_note, secret_order, secret_person.
Generate finished successfully.
```

# API and ABI breaking changes

Technically API breaking as the private tables will no longer be
available. (GitHub labels are not working at the moment)

# Expected complexity level and risk

1 - Simple change the testing took longer

# Testing

Turns out when you remove private tables you invalidate most of the
module_bindings across the system!

- [x] Rust test SDK for all languages
- [x] C# SDK tests
- [x] C# dotnet tests
- [x] Updated and checked snap files
- [x] Updated Blackholio (Unreal + Unity) module_bindings and tested
- [x] Ran Unreal SDK tests

---------

Signed-off-by: Jason Larabie <jason@clockworklabs.io>
2026-02-12 03:08:54 +00:00
joshua-spacetime e1769b5a24 Add warning prompt for 1.0 -> 2.0 module upgrade path (#4247)
# Description of Changes

Adds a warning prompt for 1.0 -> 2.0 module upgrade path.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

This patch checks a wasm module binary compiled with pre-2.0 bindings
into source control. A smoketest was added that first publishes the the
pre-compiled module and then publishes a new module using the 2.0
bindings in its place.
2026-02-11 18:56:08 +00:00