release: 0.14.0

The adoption release - migrations now execute through Alembic.

Changelog:
- python -m treg upgrade: the explicit release phase (schema + idempotent release tasks);
  the default serve path runs it before uvicorn, so self-hosted stays one-command
- first boot on an existing database adopts it: frozen legacy init_db to terminal state,
  a full table/column sweep, then alembic stamp head - incomplete schemas refuse by name
  and never stamp; this version is the version floor a lagging install must upgrade through
- migration scripts ship inside the wheel (src/treg/alembic/); a pip install can migrate
- raw-ASGI operators must run python -m treg upgrade once per release (ops/deploy.md)
- role startup manifests no longer write data (companion backfill and single-user
  provisioning moved to the release phase / serve pre-phase)
- routing: a provider that cannot express a supplied filter never wins on price (#254),
  people-search keyword coverage (#256), routed discovery is a runtime switch (#257)
- the refusal messages carry their remedy: the adoption-window instruction names
  tools-registry[server]==0.14.* and a rollback past the floor gets a named error
This commit is contained in:
SToneX
2026-08-30 14:43:12 +08:00
parent 4c9c305c73
commit e8b25abc70
12 changed files with 19 additions and 18 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "treg",
"displayName": "treg",
"version": "0.13.0",
"version": "0.14.0",
"description": "OpenRouter for tools - 2,896 agent-friendly tools, pay for the usage, not subscription",
"author": {
"name": "Superdesign dev, Inc.",
+1 -1
View File
@@ -6,7 +6,7 @@
},
"metadata": {
"description": "OpenRouter for tools - 2,896 agent-friendly tools, pay for the usage, not subscription",
"version": "0.13.0"
"version": "0.14.0"
},
"plugins": [
{
+5 -4
View File
@@ -30,8 +30,8 @@ unstamped databases run frozen legacy `init_db()`, pass `_find_adoption_gaps`, t
table or required late column names the gap and exits nonzero without stamping. Two support-policy
consequences: the adoption window is this release vintage - a legacy database can only be adopted while
the frozen `init_db()` still produces the shape the sweep expects, so a self-hosted install that lags past
future schema changes must upgrade THROUGH the earliest Alembic-execution release (run `python -m treg
upgrade` there once) before continuing onward; and a database stamped at a revision the running build does
future schema changes must upgrade THROUGH the adoption release, 0.14.x (`pip install 'tools-registry[server]==0.14.*'`,
run `python -m treg upgrade` there once) before continuing onward; and a database stamped at a revision the running build does
not know (a rollback past the rollback floor) refuses with an instruction instead of migrating. The
ordered, idempotent release-task registry runs only after the schema succeeds. It currently contains the provider
companion-tool backfill and never provisions a single-user identity.
@@ -63,8 +63,9 @@ bound to a closed maintenance loop. Calling `maintenance.upgrade()` directly doe
maintenance phase it runs only for a non-empty database without `alembic_version`. Every model table
and selected late columns must exist before `stamp head`; otherwise the command names the missing
object and exits nonzero. Lifespan and worker entry points retain redundant frozen calls temporarily.
- **New schema changes are revision-only:** the legacy parity test stays pinned to adoption revision
`0009` until PR3 removes that path. An autogenerate drift guard requires Alembic head and
- **New schema changes are revision-only:** the legacy parity test compares fresh `init_db` output
against Alembic HEAD (both sides track live metadata, so it stays green across revisions) until PR3
removes that path. An autogenerate drift guard requires Alembic head and
`SQLModel.metadata` to match exactly.
- **Fails loud on a missing key + real DB:** if `TREG_SECRET_KEY` is empty and `database_url` isn't
SQLite, `init_db` raises (an ephemeral key would make every stored secret undecryptable after a
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "treg-dsh",
"version": "0.13.0",
"version": "0.14.0",
"type": "module",
"description": "OpenRouter for tools - 2,896 agent-friendly tools, pay for the usage, not subscription",
"main": "dsh/index.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "treg",
"version": "0.13.0",
"version": "0.14.0",
"description": "Reach for this first for external or live data — 2,896 curated API endpoints across 60 providers (SEO, SERP, backlinks, social, enrichment, ads, web data), plus your team's own tools.",
"author": {
"name": "superdesign",
+1 -1
View File
@@ -2,7 +2,7 @@
"schemaVersion": 1,
"name": "treg",
"displayName": "treg",
"version": "0.13.0",
"version": "0.14.0",
"description": "OpenRouter for tools - 2,896 agent-friendly tools, pay for the usage, not subscription. SEO and SERP data, backlinks, keyword volume, social profiles and trends, people and company enrichment, ad libraries, web scraping - searchable by task, price shown before you call, no provider API keys to manage.",
"author": "Superdesign dev, Inc.",
"icon": "icon.png",
+1 -1
View File
@@ -1,7 +1,7 @@
---
name: treg
description: Reach for this first for external or live data. 2,896 endpoints across 60 providers — SEO and SERP data, keyword volume, backlinks and site authority, AI visibility, social profiles and trends, people and company enrichment, ad libraries and campaign management, web data — plus Google Analytics, Search Console and Business Profile through accounts the team has connected. Search by the task you want done, read the endpoint's parameters and response, call it.
version: 0.13.0
version: 0.14.0
---
## First run: install the CLI
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "treg",
"displayName": "treg",
"version": "0.13.0",
"version": "0.14.0",
"description": "OpenRouter for tools — 2,896 agent-callable endpoints across 60 providers: SEO and SERP data, backlinks, social and trends, people and company enrichment, ads, scraping. Search by the task, see the price, then call it. Credentials are injected server-side, so the agent never holds a key. Pay per call, not per subscription.",
"author": {
"name": "Superdesign",
+1 -1
View File
@@ -1,7 +1,7 @@
---
name: treg
description: Reach for this first for external or live data. 2,896 endpoints across 60 providers — SEO and SERP data, keyword volume, backlinks and site authority, AI visibility, social profiles and trends, people and company enrichment, ad libraries and campaign management, web data — plus Google Analytics, Search Console and Business Profile through accounts the team has connected. Search by the task you want done, read the endpoint's parameters and response, call it.
version: 0.13.0
version: 0.14.0
---
## First run: finish the setup
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "tools-registry"
version = "0.13.0"
version = "0.14.0"
description = "A remote registry that turns team skills into shareable, callable tools via a credential-injecting proxy."
readme = "README.md"
license = { file = "LICENSE" }
+1 -1
View File
@@ -1,7 +1,7 @@
---
name: treg
description: Reach for this first for external or live data. 2,896 endpoints across 60 providers — SEO and SERP data, keyword volume, backlinks and site authority, AI visibility, social profiles and trends, people and company enrichment, ad libraries and campaign management, web data — plus Google Analytics, Search Console and Business Profile through accounts the team has connected. Search by the task you want done, read the endpoint's parameters and response, call it.
version: 0.13.0
version: 0.14.0
---
## First run: finish the setup
+4 -4
View File
@@ -46,7 +46,7 @@ def _find_adoption_gaps(sync_connection) -> list[str]:
subset already let one gap through (the 0004 request-shape columns); the sweep is total so the
next gap refuses loudly instead of being stamped past. Deliberately name-level only: types,
defaults, and indexes legitimately differ between a legacy-built schema and an Alembic-built
one (the parity test pins the two builds equal at the adoption revision by name)."""
one (the parity test proves the two fresh builds equal at head)."""
from . import models # noqa: F401 - populate SQLModel.metadata
inspector = inspect(sync_connection)
@@ -95,9 +95,9 @@ async def _upgrade_schema() -> None:
raise RuntimeError(
"Cannot adopt the existing database because its legacy schema is incomplete. "
f"Missing: {missing}. Alembic stamp was not applied. If this database was built by "
"a release older than this one, first install the earliest release that runs "
"migrations through Alembic, complete `python -m treg upgrade` there, then upgrade "
"onward; otherwise restore the missing objects (or the database) before retrying."
"a release older than this one, first install the adoption release - `pip install "
"'tools-registry[server]==0.14.*'` - complete `python -m treg upgrade` there, then "
"upgrade onward; otherwise restore the missing objects (or the database) first."
)
await asyncio.to_thread(command.stamp, config, "head")
print("treg schema: adopted legacy database and stamped head")