ddcore 0.15
0.15.1 — 2026-09-18
Added
ddcore initwrites adocker-compose.ymlthat runs PostgreSQL with the user, password, database and port in the DSN, sodocker compose up -dgives a new project its database. It writes the file only for a DSN on this machine, and leaves an existingcompose.yaml,compose.yml,docker-compose.yamlordocker-compose.ymlalone.ddcore init --name <n> --db-port <p>builds the DSNpostgres://n:n@localhost:p/n?sslmode=disable, so you no longer have to type it out.--dsnstill points at an existing database, and it cannot be combined with the two new flags.ddcore initalso writes the project'sREADME.md(setup, commands, MCP),AGENTS.mdwith the conventions for coding agents (CLAUDE.mdis a symlink to it), a.mcp.jsonthat registersddcore mcp, and a.gitignorethat keeps.env,.ddcore/anddata/out. It never overwrites an existing file. Its closing message lists every step up toddcore user passwd Adminand the URL.ddcore new-appwritesversion: "0.1.0"and addcorerange for the running minor release (>=0.15.0 <0.16.0on 0.15.x) intoddcore.app.ts. A build that is not a release leaves the range commented out.
Changed
- Without
--dsnor--name,ddcore initnow names the database, user and password after the directory (for examplemy-shopbecomesmy_shop) instead ofddcore. ddcore new-appno longer writesapps/<app>/CLAUDE.md. The guide now lives once, at the project root, asAGENTS.md. Existing apps keep their file.
Fixed
- The
ddcore runninglog line reports the configured publicurlinstead of alwayshttp://localhost:<port>; the local address moved to alistenfield.
0.15.0 — 2026-09-17
Added
Release awareness: this file now ships inside the binary and is served as the MCP resource
ddcore://changelog. Thewhats_newtool returns the part of it above the running version, together with the newest published release.ddcore doctorasks GitHub for the newest published release and warns when the binary is behind it, so--strictfails on a stale one. It asks at most once an hour, stays silent when it cannot reach GitHub or when the binary is not a release, and is skipped by--no-update-checkfor one run orDDCORE_UPDATE_CHECK=offfor every run.Backup, restore and maintenance (PRD-01, PRD-02):
ddcore backupwrites one checksummed archive of the database, stored files, configuration and versions, with optional S3 upload and retention.ddcore restoreverifies the archive, restores it into an isolated target, migrates, and times each phase.--smokeadds a check pass.ddcore maintenance on|offpauses writes and jobs on every process and shows a Desk banner.DDCORE_DATA_DIRoverridesdataDir.ops.backupMaxAgeHourswarns on a stale backup.
S3-compatible file storage (PRD-05):
DDCORE_STORAGE=s3withDDCORE_S3_*(AWS, R2, MinIO, B2) beside the defaultlocalbackend under<dataDir>/files.file_urlis the only name on both; a download is permission-checked by the server and then streamed, or redirected to a short-lived presigned URL; deleting a File or its document removes the bytes after commit, and a failed upload removes what it wrote. Mail, export and the CLI read through the store. See storage.Document sharing (SEC-03): the Core
Document ShareDocType grants one userread,writeorshareon one document, given by someone holding theshareright and capped by their own write. A share stands in for a missing role grant on reads, lists, counts, link search, saves,dbSet, attachments, versions and comments, print, SSE and notifications, while controller hooks, workflowallowEditand docstatus still apply. Override security scope lifts the recipient's User Permission scopes for the granted rights only. Renames move shares and deletions remove them; every grant, change and revocation is an audit event./api/shares/*,ddcore.share.*and a Desk sidebar section. See sharing.Global search (OPS-08): a Mod+K palette in the desk and
GET /api/search/global, matching the title and search fields of every DocType the user can list, with roles, scopes, shares and field levels applied.globalSearchon a DocType opts it in or out. Core log DocTypes are opted out.Kanban and Gantt list views (OPS-08) through
defineListView({ kanban, gantt }). Dragging a Kanban card saves its Select field.Single sign-on through OpenID Connect (SEC-05, partial): Google, PocketID or any OIDC provider, configured with
DDCORE_OIDC_*in.env. It signs in existing Users only, linked by a verified e-mail address.auth.passwordLogin: falseinddcore.jsonleaves single sign-on as the only way in, except for Admin. See authentication.Core/app compatibility contract (PRD-07):
defineApp({ ddcore: "<range>" })declares the ddcore releases an app supports, and a binary outside the range refuses to load it.ddcore doctorand the export manifest report each app's version and range.
Breaking
A binary older than the one that last ran
migrateon a database now refuses to open it, naming the core or app version that is older. Roll forward, or pass--allow-older-binary(DDCORE_ALLOW_OLDER_BINARY=1) when the migrations since were expand-only. Databases migrated before this release have no ledger row and are not checked until their nextmigrate.storage.Storehas a newListmethod; an embedder with its own store must implement it.An app whose
versionis not a version —"1","1.0"and"1.0.0"are all fine,"beta"and"1.0.0-rc.1"are not — no longer loads. Fix the value or remove it.
Fixed
^and~with an abbreviated version now bound what the author left out, as npm does:^0is every0.x,^0.0every0.0.x, and~1every1.x. The spelt-out forms are unchanged.- A job whose write is refused by maintenance mode goes back to the queue without consuming an attempt and without an Error Log row, instead of failing — on its last attempt it used to die of a pause that was nobody's fault.
- Global search applies its five-hits-per-DocType cap after ranking, so an exact match is no longer lost behind more recently modified rows, and
%and_in the search text now match themselves instead of acting as wildcards. - A
migraterun by a build with no release version (adevbinary) no longer replaces the ledger's core version, which silently disarmed the rollback guard for every later binary. ddcore.share.*refuses a right it does not know (override_scopeforoverrideScope) with the same417as the endpoint, rather than dropping it and granting a share without it.- Single sign-on clears the client address's failed attempts on a successful sign-in, as a password sign-in does, and a failure on the server's own side is reported as
sso_error=serverrather than blamed on the provider. --allow-older-binary=trueis accepted; only the bare flag used to be.ddcore doctorreports a rollback refusal as its own critical instead of "the apps could not be loaded", and prints an S3 bucket with no prefix without a trailing slash.ddcore restorewarns when it stops after the database was replaced: the target keeps the restored database and stays paused.- A list view listed in
viewsbut never configured no longer shows a button that falls back to the table.