diff --git a/.changeset/collections-studio-gaps.md b/.changeset/collections-studio-gaps.md deleted file mode 100644 index dc96626f..00000000 --- a/.changeset/collections-studio-gaps.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@cloudhal/cli": patch ---- - -Studio (RFC-0040 §4): a collection's settings get a Comments section (saved in the site's comment settings), the site overview lists recent content across every collection, and entries open at `/sites//collections//` — the old `/articles/` links redirect there. The command palette goes to each collection. diff --git a/.changeset/typed-fields-contract.md b/.changeset/typed-fields-contract.md deleted file mode 100644 index 7f324071..00000000 --- a/.changeset/typed-fields-contract.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@cloudhal/core-contracts": minor -"@cloudhal/core-ts": minor ---- - -Typed custom fields, step 1 (RFC-0041 / ADR-0043). `Site.collections..fields` takes an ordered list of 1–30 field definitions in nine types (`text`, `richText`, `number`, `boolean`, `date`, `datetime`, `url`, `image`, `select`), discriminated by `type`, each with per-locale labels, `localized` and (except `boolean`) `requiredToPublish`. The new `@cloudhal/core-ts/fields` subpath (Worker-safe, eval-free) checks definitions (reserved keys, unique keys and options, 30 per collection, 200 per site, 256 KB of collection settings, the plain-edit guard), checks values through ADR-0030's `validateProps` (only changed values; unknown keys refused once a collection has definitions; 256 KB per entry), checks `requiredToPublish`, emits the JSON Schema agents receive (strict-mode safe), and resolves values across translations (`resolveFields`). Nothing reads it yet: the store, API, MCP, Studio and renderer adopt it in later steps, so nothing changes for existing sites. diff --git a/.changeset/typed-fields-mcp.md b/.changeset/typed-fields-mcp.md deleted file mode 100644 index 9d9e1a87..00000000 --- a/.changeset/typed-fields-mcp.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@cloudhal/mcp-server": minor ---- - -Typed custom fields, step 4 (RFC-0041 §8 / ADR-0043): MCP. - -- **`list_collections`** returns each collection's field definitions (`fields`) and `fieldsSchema`, the JSON Schema of an entry's values with labels and help in the asked `locale` (default: the site's). -- **`create_entry` / `update_entry`** check field values in `precheck` with the store's checker (changed keys only, unknown keys, a translation's copy of a non-localized value, `requiredToPublish` for review and published, image and `asset:` references), so a refused call never reaches a person; each issue keeps its path (`fields/startsAt/at`). `update_entry` takes `fields` as a merge patch (`null` removes a key), and its approval names typed changes readably ("Starts at (startsAt) → 5 Nov 2026 19:30 Istanbul", option labels, values quoted and truncated). -- **`update_collection`** takes `fields` (the whole list) for free definition edits; changes that could lose values are refused with `field_change_needs_operation`, naming the operation tool. -- **New tools `rename_field`, `change_field_type`, `set_field_localized`, `remove_field`** (`site:write` + `content:write`): always a person holding `site:settings`, in every mode including `bypass`; the approval shows the dry run (entries touched, values moved, converted or cleared, samples), `dryRun: true` reports without asking, and a call that would clear values without `onInvalid: "clear"` is refused before anyone is asked. A run that stops at its budget answers `done: false` with an `operationId`; calling the same tool again with it continues the operation after a new approval. -- Hints for every field error code, and server instructions telling agents to read `fieldsSchema` before writing entries and to use the operation tools for risky changes. diff --git a/.changeset/typed-fields-operations.md b/.changeset/typed-fields-operations.md deleted file mode 100644 index eeea3b51..00000000 --- a/.changeset/typed-fields-operations.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@cloudhal/core-ts": minor -"@cloudhal/api": minor -"@cloudhal/cli": minor ---- - -Typed custom fields, step 3 (RFC-0041 §6 / ADR-0043): field operations. - -- **`runFieldOperation` / `continueFieldOperation` / `revertFieldOperation` / `fieldOperationStatus`** in `@cloudhal/core-ts` run `rename_field`, `change_field_type`, `set_field_localized` and `remove_field`: a dry run (entries touched, values moved, converted, cleared, removed, unchanged and unconvertible, per locale, with samples), a `before …` snapshot whose id is the operation id, the new definition with its `migration` marker (phase A), entries rewritten in guarded batches of 200 that resume after an interruption (phase B), the marker dropped once nothing is pending (phase C) and an `after` snapshot. Only the draft graph changes. A type change follows a closed conversion table (`convertFieldValue`, exported from `@cloudhal/core-ts/fields`) and refuses values it cannot convert (`field_values_unconvertible`) unless `onInvalid: "clear"`. One operation per collection at a time (`operation_in_progress`). Reverting restores the earlier definition and the entries nobody edited since, and converts edited ones back. -- **Readers stay consistent mid-run:** `resolveFields` converts values still in the old type, and a field being removed reads as gone; a person's entry write during an operation goes through the marker, so edits and the operation converge. -- **Translations:** changing only non-localized field values of an original no longer marks its translations stale (their recorded source hash follows, in the same batch); operations keep fresh translations fresh. -- **API:** `POST /api/sites/:id/collections/:key/fields/operations` (`dryRun`, `?continue=`), `GET …/:operationId`, `POST …/:operationId/revert` (`site:settings` and `content:write`), and the same under `/api/admin` with the deployment token. -- **CLI:** `cloudhal fields rename|retype|localize|remove|continue|revert [--dry-run] [--remote]`; the dry run also lists theme files that read the field directly. diff --git a/.changeset/typed-fields-renderer.md b/.changeset/typed-fields-renderer.md deleted file mode 100644 index bd991c15..00000000 --- a/.changeset/typed-fields-renderer.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@cloudhal/astro-renderer": minor -"@cloudhal/core-ts": minor -"@cloudhal/cli": minor ---- - -Typed custom fields, step 6 (RFC-0041 §9 / ADR-0043): renderer and themes. Additive only: `entry.fields` still means exactly what is stored, and themes copied before this release build and render as before (a frozen 0.4.0 theme joins the compat test). - -- **`GraphSource.entryFields(entry, options?)`** on live and snapshot sources (and `entryFields(source, entry, options?)` from `@cloudhal/astro-renderer/fields` for any source): an entry's typed fields as a theme draws them, by key in definition order. Values are resolved by the language rules (a translation's empty localized field reads the original's, `fromOriginal`; non-localized fields come from the translation group's original; language editions own their values), labelled in the page's language and made safe: rich text as HTML from the article body's markdown pipeline (raw HTML escaped, `safeHref` on links), URLs through `safeHref` (dropped when unsafe), images as `` attributes with the asset's alt in the page's language, everything else as formatted text. Also `renderFields`, `hasShownFields`, and `resolveFields`, `formatFieldValue`, `fieldLabel`, `fieldHelp`, `optionLabel` re-exported. -- **`formatFieldValue(value, def, { locale, defaultLocale?, timeZone?, words? })`** in `@cloudhal/core-ts/fields`: a value as plain text with `Intl` (numbers, dates that never shift a day, instants in their own zone, option labels as a list, yes/no words). -- **`EntryFields.astro`** in `@cloudhal/astro-renderer/components`: a plain, unstyled `
` of the fields that have a value, with `data-field` / `data-type` hooks for themes; nothing at all when none has one. -- **Blog starter:** articles of collections with fields show a "Details" list under the cover (English, Turkish and Japanese words). Entries of collections without definitions render byte for byte as before. -- New guide: `docs/guides/fields.md` (defining fields in Studio, MCP, the API and the CLI; operations; languages; theme API; security). diff --git a/.changeset/typed-fields-store.md b/.changeset/typed-fields-store.md deleted file mode 100644 index 68113a75..00000000 --- a/.changeset/typed-fields-store.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@cloudhal/core-ts": minor -"@cloudhal/api": minor ---- - -Typed custom fields, step 2 (RFC-0041 / ADR-0043): the store and the API enforce field definitions. - -- **Site writes** (`updateSite`, `createSite`, `PUT /api/sites/:id/collections/:key`, dry run included) check definitions: reserved (`field_key_reserved`) and duplicate keys or options, `minimum` above `maximum`, 30 fields per collection and 200 per site (`too_many_fields`), 256 KB of collection settings (`too_large`). A plain edit never loses a value: changing a field's `type`, `localized` or `multiple`, or dropping a key or a select option that an entry still holds, is refused with `409 field_change_needs_operation`, naming the field operation to use. Other site writes do not re-run the checks. -- **Entry writes** check only the field values that changed: `422 invalid_fields`, `unknown_field` (a new key without a definition, once the collection has definitions; stored unknown keys are kept), `field_not_localized` (a translation's own copy of a non-localized value) and `required_field` (review or published without a `requiredToPublish` value; drafts save freely). `fields` is capped at 256 KB per entry in every collection when it changes (`too_large`). Image values must be image assets of the site, and image and rich-text asset references are recorded in `asset_refs` under `fields.`, so a used file cannot be deleted. Every refusal lists its problems with paths in `details.issues` (`fields/startsAt/at`). -- **API inputs** remove a key with `null` in a collection that has definitions. Collections without definitions keep `fields` as any JSON, exactly as before. -- **Search**: `text` and `richText` fields marked `searchable` add their words to the entry's search text at the next publish (off by default; sites without searchable fields index byte for byte as before). -- `refuseFieldIssues` and `fieldRefusalCode` are exported from `@cloudhal/core-ts/fields`. diff --git a/.changeset/typed-fields-studio.md b/.changeset/typed-fields-studio.md deleted file mode 100644 index 4d9de478..00000000 --- a/.changeset/typed-fields-studio.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@cloudhal/cli": minor ---- - -Typed custom fields, step 5 (RFC-0041 §7 / ADR-0043): Studio. - -- **Entry editor › Fields:** collections with field definitions get a "Fields" card in the entry editor (loaded only for them), one control per type — text, rich text (the body editor), number, yes/no, date, date and time in its own zone, link, image (the media picker) and choice (one or several). Labels and help follow the Studio language, required fields say "Needed to publish", and the API's issues show on their field. On a translation, shared (non-localized) fields are read-only with the original's value and a link to it; empty per-language fields show the original's value as their placeholder. Values save with the entry. -- **Collection settings › Fields:** a builder to add fields (the key follows the label until saved), reorder them and edit labels, help, limits and options, saved together. Renaming, changing a type or the languages of a saved field, and removing one open a dialog that runs the dry run first (entries changed, values moved, converted or cleared, per language, examples, a note about themes), needs confirmation — and an explicit opt-in to clear values that cannot be converted — then runs the operation to the end and offers Revert. A running operation shows its progress and can be continued. Only people who may change site settings edit fields; others see them read-only. -- Activity and Approvals name the collection and field tools, field operations that convert or remove values ask for confirmation before approval, and every field error code reads as a sentence in the Studio language. New words live in a lazy `fields` namespace (drafts in every language, awaiting review). diff --git a/packages/agent-runtime/CHANGELOG.md b/packages/agent-runtime/CHANGELOG.md index 0c124215..a5f0907d 100644 --- a/packages/agent-runtime/CHANGELOG.md +++ b/packages/agent-runtime/CHANGELOG.md @@ -1,5 +1,13 @@ # @cloudhal/agent-runtime +## 0.5.0 + +### Patch Changes + +- Updated dependencies [672b993] + - @cloudhal/core-contracts@0.5.0 + - @cloudhal/storage@0.5.0 + ## 0.4.0 ### Patch Changes diff --git a/packages/agent-runtime/package.json b/packages/agent-runtime/package.json index b0295c0f..3eb393b2 100644 --- a/packages/agent-runtime/package.json +++ b/packages/agent-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/agent-runtime", - "version": "0.4.0", + "version": "0.5.0", "description": "Cloudhal agent runtime: policy engine (actors, scopes, approvals), skill loader, audit log", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/analytics/CHANGELOG.md b/packages/analytics/CHANGELOG.md index dc25b36e..3551d898 100644 --- a/packages/analytics/CHANGELOG.md +++ b/packages/analytics/CHANGELOG.md @@ -1,5 +1,13 @@ # @cloudhal/analytics +## 0.5.0 + +### Patch Changes + +- Updated dependencies [672b993] + - @cloudhal/core-contracts@0.5.0 + - @cloudhal/storage@0.5.0 + ## 0.4.0 ### Patch Changes diff --git a/packages/analytics/package.json b/packages/analytics/package.json index e8f01719..14d2b721 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/analytics", - "version": "0.4.0", + "version": "0.5.0", "description": "Cloudhal site analytics (RFC-0006): query model, classifiers, beacon handler, SQLite/D1 store, daily rollups and Workers Analytics Engine adapters. Worker-safe.", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md index 72db8590..a49e2b72 100644 --- a/packages/api/CHANGELOG.md +++ b/packages/api/CHANGELOG.md @@ -1,5 +1,41 @@ # @cloudhal/api +## 0.5.0 + +### Minor Changes + +- cc263c3: Typed custom fields, step 3 (RFC-0041 §6 / ADR-0043): field operations. + + - **`runFieldOperation` / `continueFieldOperation` / `revertFieldOperation` / `fieldOperationStatus`** in `@cloudhal/core-ts` run `rename_field`, `change_field_type`, `set_field_localized` and `remove_field`: a dry run (entries touched, values moved, converted, cleared, removed, unchanged and unconvertible, per locale, with samples), a `before …` snapshot whose id is the operation id, the new definition with its `migration` marker (phase A), entries rewritten in guarded batches of 200 that resume after an interruption (phase B), the marker dropped once nothing is pending (phase C) and an `after` snapshot. Only the draft graph changes. A type change follows a closed conversion table (`convertFieldValue`, exported from `@cloudhal/core-ts/fields`) and refuses values it cannot convert (`field_values_unconvertible`) unless `onInvalid: "clear"`. One operation per collection at a time (`operation_in_progress`). Reverting restores the earlier definition and the entries nobody edited since, and converts edited ones back. + - **Readers stay consistent mid-run:** `resolveFields` converts values still in the old type, and a field being removed reads as gone; a person's entry write during an operation goes through the marker, so edits and the operation converge. + - **Translations:** changing only non-localized field values of an original no longer marks its translations stale (their recorded source hash follows, in the same batch); operations keep fresh translations fresh. + - **API:** `POST /api/sites/:id/collections/:key/fields/operations` (`dryRun`, `?continue=`), `GET …/:operationId`, `POST …/:operationId/revert` (`site:settings` and `content:write`), and the same under `/api/admin` with the deployment token. + - **CLI:** `cloudhal fields rename|retype|localize|remove|continue|revert [--dry-run] [--remote]`; the dry run also lists theme files that read the field directly. +- bd5af88: Typed custom fields, step 2 (RFC-0041 / ADR-0043): the store and the API enforce field definitions. + + - **Site writes** (`updateSite`, `createSite`, `PUT /api/sites/:id/collections/:key`, dry run included) check definitions: reserved (`field_key_reserved`) and duplicate keys or options, `minimum` above `maximum`, 30 fields per collection and 200 per site (`too_many_fields`), 256 KB of collection settings (`too_large`). A plain edit never loses a value: changing a field's `type`, `localized` or `multiple`, or dropping a key or a select option that an entry still holds, is refused with `409 field_change_needs_operation`, naming the field operation to use. Other site writes do not re-run the checks. + - **Entry writes** check only the field values that changed: `422 invalid_fields`, `unknown_field` (a new key without a definition, once the collection has definitions; stored unknown keys are kept), `field_not_localized` (a translation's own copy of a non-localized value) and `required_field` (review or published without a `requiredToPublish` value; drafts save freely). `fields` is capped at 256 KB per entry in every collection when it changes (`too_large`). Image values must be image assets of the site, and image and rich-text asset references are recorded in `asset_refs` under `fields.`, so a used file cannot be deleted. Every refusal lists its problems with paths in `details.issues` (`fields/startsAt/at`). + - **API inputs** remove a key with `null` in a collection that has definitions. Collections without definitions keep `fields` as any JSON, exactly as before. + - **Search**: `text` and `richText` fields marked `searchable` add their words to the entry's search text at the next publish (off by default; sites without searchable fields index byte for byte as before). + - `refuseFieldIssues` and `fieldRefusalCode` are exported from `@cloudhal/core-ts/fields`. + +### Patch Changes + +- Updated dependencies [672b993] +- Updated dependencies [9d04a37] +- Updated dependencies [cc263c3] +- Updated dependencies [92d3362] +- Updated dependencies [bd5af88] + - @cloudhal/core-contracts@0.5.0 + - @cloudhal/core-ts@0.5.0 + - @cloudhal/mcp-server@0.5.0 + - @cloudhal/astro-renderer@0.5.0 + - @cloudhal/agent-runtime@0.5.0 + - @cloudhal/analytics@0.5.0 + - @cloudhal/comments@0.5.0 + - @cloudhal/schedules@0.5.0 + - @cloudhal/storage@0.5.0 + ## 0.4.0 ### Minor Changes diff --git a/packages/api/package.json b/packages/api/package.json index 99235918..106bb4fa 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/api", - "version": "0.4.0", + "version": "0.5.0", "description": "Cloudhal HTTP API (Hono): sites, pages, entries, snapshots, auth — runs on Node and Cloudflare Workers", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/astro-renderer/CHANGELOG.md b/packages/astro-renderer/CHANGELOG.md index 5d87e9db..047e1dd9 100644 --- a/packages/astro-renderer/CHANGELOG.md +++ b/packages/astro-renderer/CHANGELOG.md @@ -1,5 +1,29 @@ # @cloudhal/astro-renderer +## 0.5.0 + +### Minor Changes + +- 92d3362: Typed custom fields, step 6 (RFC-0041 §9 / ADR-0043): renderer and themes. Additive only: `entry.fields` still means exactly what is stored, and themes copied before this release build and render as before (a frozen 0.4.0 theme joins the compat test). + + - **`GraphSource.entryFields(entry, options?)`** on live and snapshot sources (and `entryFields(source, entry, options?)` from `@cloudhal/astro-renderer/fields` for any source): an entry's typed fields as a theme draws them, by key in definition order. Values are resolved by the language rules (a translation's empty localized field reads the original's, `fromOriginal`; non-localized fields come from the translation group's original; language editions own their values), labelled in the page's language and made safe: rich text as HTML from the article body's markdown pipeline (raw HTML escaped, `safeHref` on links), URLs through `safeHref` (dropped when unsafe), images as `` attributes with the asset's alt in the page's language, everything else as formatted text. Also `renderFields`, `hasShownFields`, and `resolveFields`, `formatFieldValue`, `fieldLabel`, `fieldHelp`, `optionLabel` re-exported. + - **`formatFieldValue(value, def, { locale, defaultLocale?, timeZone?, words? })`** in `@cloudhal/core-ts/fields`: a value as plain text with `Intl` (numbers, dates that never shift a day, instants in their own zone, option labels as a list, yes/no words). + - **`EntryFields.astro`** in `@cloudhal/astro-renderer/components`: a plain, unstyled `
` of the fields that have a value, with `data-field` / `data-type` hooks for themes; nothing at all when none has one. + - **Blog starter:** articles of collections with fields show a "Details" list under the cover (English, Turkish and Japanese words). Entries of collections without definitions render byte for byte as before. + - New guide: `docs/guides/fields.md` (defining fields in Studio, MCP, the API and the CLI; operations; languages; theme API; security). + +### Patch Changes + +- Updated dependencies [672b993] +- Updated dependencies [cc263c3] +- Updated dependencies [92d3362] +- Updated dependencies [bd5af88] + - @cloudhal/core-contracts@0.5.0 + - @cloudhal/core-ts@0.5.0 + - @cloudhal/analytics@0.5.0 + - @cloudhal/comments@0.5.0 + - @cloudhal/storage@0.5.0 + ## 0.4.0 ### Minor Changes diff --git a/packages/astro-renderer/package.json b/packages/astro-renderer/package.json index 32720b69..36d9d6e1 100644 --- a/packages/astro-renderer/package.json +++ b/packages/astro-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/astro-renderer", - "version": "0.4.0", + "version": "0.5.0", "description": "Render a Cloudhal Site Graph with Astro: data sources (live/snapshot), section components and the cloudhal() integration", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index b2cbcc59..cd620012 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,48 @@ # @cloudhal/cli +## 0.5.0 + +### Minor Changes + +- cc263c3: Typed custom fields, step 3 (RFC-0041 §6 / ADR-0043): field operations. + + - **`runFieldOperation` / `continueFieldOperation` / `revertFieldOperation` / `fieldOperationStatus`** in `@cloudhal/core-ts` run `rename_field`, `change_field_type`, `set_field_localized` and `remove_field`: a dry run (entries touched, values moved, converted, cleared, removed, unchanged and unconvertible, per locale, with samples), a `before …` snapshot whose id is the operation id, the new definition with its `migration` marker (phase A), entries rewritten in guarded batches of 200 that resume after an interruption (phase B), the marker dropped once nothing is pending (phase C) and an `after` snapshot. Only the draft graph changes. A type change follows a closed conversion table (`convertFieldValue`, exported from `@cloudhal/core-ts/fields`) and refuses values it cannot convert (`field_values_unconvertible`) unless `onInvalid: "clear"`. One operation per collection at a time (`operation_in_progress`). Reverting restores the earlier definition and the entries nobody edited since, and converts edited ones back. + - **Readers stay consistent mid-run:** `resolveFields` converts values still in the old type, and a field being removed reads as gone; a person's entry write during an operation goes through the marker, so edits and the operation converge. + - **Translations:** changing only non-localized field values of an original no longer marks its translations stale (their recorded source hash follows, in the same batch); operations keep fresh translations fresh. + - **API:** `POST /api/sites/:id/collections/:key/fields/operations` (`dryRun`, `?continue=`), `GET …/:operationId`, `POST …/:operationId/revert` (`site:settings` and `content:write`), and the same under `/api/admin` with the deployment token. + - **CLI:** `cloudhal fields rename|retype|localize|remove|continue|revert [--dry-run] [--remote]`; the dry run also lists theme files that read the field directly. +- 92d3362: Typed custom fields, step 6 (RFC-0041 §9 / ADR-0043): renderer and themes. Additive only: `entry.fields` still means exactly what is stored, and themes copied before this release build and render as before (a frozen 0.4.0 theme joins the compat test). + + - **`GraphSource.entryFields(entry, options?)`** on live and snapshot sources (and `entryFields(source, entry, options?)` from `@cloudhal/astro-renderer/fields` for any source): an entry's typed fields as a theme draws them, by key in definition order. Values are resolved by the language rules (a translation's empty localized field reads the original's, `fromOriginal`; non-localized fields come from the translation group's original; language editions own their values), labelled in the page's language and made safe: rich text as HTML from the article body's markdown pipeline (raw HTML escaped, `safeHref` on links), URLs through `safeHref` (dropped when unsafe), images as `` attributes with the asset's alt in the page's language, everything else as formatted text. Also `renderFields`, `hasShownFields`, and `resolveFields`, `formatFieldValue`, `fieldLabel`, `fieldHelp`, `optionLabel` re-exported. + - **`formatFieldValue(value, def, { locale, defaultLocale?, timeZone?, words? })`** in `@cloudhal/core-ts/fields`: a value as plain text with `Intl` (numbers, dates that never shift a day, instants in their own zone, option labels as a list, yes/no words). + - **`EntryFields.astro`** in `@cloudhal/astro-renderer/components`: a plain, unstyled `
` of the fields that have a value, with `data-field` / `data-type` hooks for themes; nothing at all when none has one. + - **Blog starter:** articles of collections with fields show a "Details" list under the cover (English, Turkish and Japanese words). Entries of collections without definitions render byte for byte as before. + - New guide: `docs/guides/fields.md` (defining fields in Studio, MCP, the API and the CLI; operations; languages; theme API; security). +- 05274d3: Typed custom fields, step 5 (RFC-0041 §7 / ADR-0043): Studio. + + - **Entry editor › Fields:** collections with field definitions get a "Fields" card in the entry editor (loaded only for them), one control per type — text, rich text (the body editor), number, yes/no, date, date and time in its own zone, link, image (the media picker) and choice (one or several). Labels and help follow the Studio language, required fields say "Needed to publish", and the API's issues show on their field. On a translation, shared (non-localized) fields are read-only with the original's value and a link to it; empty per-language fields show the original's value as their placeholder. Values save with the entry. + - **Collection settings › Fields:** a builder to add fields (the key follows the label until saved), reorder them and edit labels, help, limits and options, saved together. Renaming, changing a type or the languages of a saved field, and removing one open a dialog that runs the dry run first (entries changed, values moved, converted or cleared, per language, examples, a note about themes), needs confirmation — and an explicit opt-in to clear values that cannot be converted — then runs the operation to the end and offers Revert. A running operation shows its progress and can be continued. Only people who may change site settings edit fields; others see them read-only. + - Activity and Approvals name the collection and field tools, field operations that convert or remove values ask for confirmation before approval, and every field error code reads as a sentence in the Studio language. New words live in a lazy `fields` namespace (drafts in every language, awaiting review). + +### Patch Changes + +- 0ba1e01: Studio (RFC-0040 §4): a collection's settings get a Comments section (saved in the site's comment settings), the site overview lists recent content across every collection, and entries open at `/sites//collections//` — the old `/articles/` links redirect there. The command palette goes to each collection. +- Updated dependencies [672b993] +- Updated dependencies [9d04a37] +- Updated dependencies [cc263c3] +- Updated dependencies [92d3362] +- Updated dependencies [bd5af88] + - @cloudhal/core-contracts@0.5.0 + - @cloudhal/core-ts@0.5.0 + - @cloudhal/mcp-server@0.5.0 + - @cloudhal/api@0.5.0 + - @cloudhal/agent-runtime@0.5.0 + - @cloudhal/analytics@0.5.0 + - @cloudhal/comments@0.5.0 + - @cloudhal/schedules@0.5.0 + - @cloudhal/storage@0.5.0 + - @cloudhal/cloudflare@0.5.0 + ## 0.4.0 ### Minor Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 5db2c51f..a8679a06 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/cli", - "version": "0.4.0", + "version": "0.5.0", "description": "cloudhal — create, run and build Cloudhal sites locally", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/cloudflare/CHANGELOG.md b/packages/cloudflare/CHANGELOG.md index 7dfd9ed5..39d03462 100644 --- a/packages/cloudflare/CHANGELOG.md +++ b/packages/cloudflare/CHANGELOG.md @@ -1,5 +1,23 @@ # @cloudhal/cloudflare +## 0.5.0 + +### Patch Changes + +- Updated dependencies [672b993] +- Updated dependencies [9d04a37] +- Updated dependencies [cc263c3] +- Updated dependencies [92d3362] +- Updated dependencies [bd5af88] + - @cloudhal/core-ts@0.5.0 + - @cloudhal/mcp-server@0.5.0 + - @cloudhal/api@0.5.0 + - @cloudhal/agent-runtime@0.5.0 + - @cloudhal/analytics@0.5.0 + - @cloudhal/comments@0.5.0 + - @cloudhal/schedules@0.5.0 + - @cloudhal/storage@0.5.0 + ## 0.4.0 ### Patch Changes diff --git a/packages/cloudflare/package.json b/packages/cloudflare/package.json index 85063d64..2495f193 100644 --- a/packages/cloudflare/package.json +++ b/packages/cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/cloudflare", - "version": "0.4.0", + "version": "0.5.0", "description": "Cloudhal on Cloudflare: the admin Worker (API, auth, MCP, Studio) over D1 + R2", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/comments/CHANGELOG.md b/packages/comments/CHANGELOG.md index c105dd88..2ac22ca7 100644 --- a/packages/comments/CHANGELOG.md +++ b/packages/comments/CHANGELOG.md @@ -1,5 +1,17 @@ # @cloudhal/comments +## 0.5.0 + +### Patch Changes + +- Updated dependencies [672b993] +- Updated dependencies [cc263c3] +- Updated dependencies [92d3362] +- Updated dependencies [bd5af88] + - @cloudhal/core-contracts@0.5.0 + - @cloudhal/core-ts@0.5.0 + - @cloudhal/storage@0.5.0 + ## 0.4.0 ### Patch Changes diff --git a/packages/comments/package.json b/packages/comments/package.json index 25e4acd4..0423b228 100644 --- a/packages/comments/package.json +++ b/packages/comments/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/comments", - "version": "0.4.0", + "version": "0.5.0", "description": "Cloudhal reader comments (RFC-0007): settings and thread state, text normalising and content rules, linkify, first-party proof of work, the submission pipeline, purge planner, retention plan and the SQLite/D1 store. Worker-safe.", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/core-contracts/CHANGELOG.md b/packages/core-contracts/CHANGELOG.md index b51b89cf..8491409b 100644 --- a/packages/core-contracts/CHANGELOG.md +++ b/packages/core-contracts/CHANGELOG.md @@ -1,5 +1,11 @@ # @cloudhal/core-contracts +## 0.5.0 + +### Minor Changes + +- 672b993: Typed custom fields, step 1 (RFC-0041 / ADR-0043). `Site.collections..fields` takes an ordered list of 1–30 field definitions in nine types (`text`, `richText`, `number`, `boolean`, `date`, `datetime`, `url`, `image`, `select`), discriminated by `type`, each with per-locale labels, `localized` and (except `boolean`) `requiredToPublish`. The new `@cloudhal/core-ts/fields` subpath (Worker-safe, eval-free) checks definitions (reserved keys, unique keys and options, 30 per collection, 200 per site, 256 KB of collection settings, the plain-edit guard), checks values through ADR-0030's `validateProps` (only changed values; unknown keys refused once a collection has definitions; 256 KB per entry), checks `requiredToPublish`, emits the JSON Schema agents receive (strict-mode safe), and resolves values across translations (`resolveFields`). Nothing reads it yet: the store, API, MCP, Studio and renderer adopt it in later steps, so nothing changes for existing sites. + ## 0.4.0 ### Minor Changes diff --git a/packages/core-contracts/package.json b/packages/core-contracts/package.json index cff9e72e..497b7f68 100644 --- a/packages/core-contracts/package.json +++ b/packages/core-contracts/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/core-contracts", - "version": "0.4.0", + "version": "0.5.0", "description": "Cloudhal domain contracts: JSON Schema source of truth plus generated TypeScript types", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/core-ts/CHANGELOG.md b/packages/core-ts/CHANGELOG.md index 05081066..a55da022 100644 --- a/packages/core-ts/CHANGELOG.md +++ b/packages/core-ts/CHANGELOG.md @@ -1,5 +1,39 @@ # @cloudhal/core-ts +## 0.5.0 + +### Minor Changes + +- 672b993: Typed custom fields, step 1 (RFC-0041 / ADR-0043). `Site.collections..fields` takes an ordered list of 1–30 field definitions in nine types (`text`, `richText`, `number`, `boolean`, `date`, `datetime`, `url`, `image`, `select`), discriminated by `type`, each with per-locale labels, `localized` and (except `boolean`) `requiredToPublish`. The new `@cloudhal/core-ts/fields` subpath (Worker-safe, eval-free) checks definitions (reserved keys, unique keys and options, 30 per collection, 200 per site, 256 KB of collection settings, the plain-edit guard), checks values through ADR-0030's `validateProps` (only changed values; unknown keys refused once a collection has definitions; 256 KB per entry), checks `requiredToPublish`, emits the JSON Schema agents receive (strict-mode safe), and resolves values across translations (`resolveFields`). Nothing reads it yet: the store, API, MCP, Studio and renderer adopt it in later steps, so nothing changes for existing sites. +- cc263c3: Typed custom fields, step 3 (RFC-0041 §6 / ADR-0043): field operations. + + - **`runFieldOperation` / `continueFieldOperation` / `revertFieldOperation` / `fieldOperationStatus`** in `@cloudhal/core-ts` run `rename_field`, `change_field_type`, `set_field_localized` and `remove_field`: a dry run (entries touched, values moved, converted, cleared, removed, unchanged and unconvertible, per locale, with samples), a `before …` snapshot whose id is the operation id, the new definition with its `migration` marker (phase A), entries rewritten in guarded batches of 200 that resume after an interruption (phase B), the marker dropped once nothing is pending (phase C) and an `after` snapshot. Only the draft graph changes. A type change follows a closed conversion table (`convertFieldValue`, exported from `@cloudhal/core-ts/fields`) and refuses values it cannot convert (`field_values_unconvertible`) unless `onInvalid: "clear"`. One operation per collection at a time (`operation_in_progress`). Reverting restores the earlier definition and the entries nobody edited since, and converts edited ones back. + - **Readers stay consistent mid-run:** `resolveFields` converts values still in the old type, and a field being removed reads as gone; a person's entry write during an operation goes through the marker, so edits and the operation converge. + - **Translations:** changing only non-localized field values of an original no longer marks its translations stale (their recorded source hash follows, in the same batch); operations keep fresh translations fresh. + - **API:** `POST /api/sites/:id/collections/:key/fields/operations` (`dryRun`, `?continue=`), `GET …/:operationId`, `POST …/:operationId/revert` (`site:settings` and `content:write`), and the same under `/api/admin` with the deployment token. + - **CLI:** `cloudhal fields rename|retype|localize|remove|continue|revert [--dry-run] [--remote]`; the dry run also lists theme files that read the field directly. +- 92d3362: Typed custom fields, step 6 (RFC-0041 §9 / ADR-0043): renderer and themes. Additive only: `entry.fields` still means exactly what is stored, and themes copied before this release build and render as before (a frozen 0.4.0 theme joins the compat test). + + - **`GraphSource.entryFields(entry, options?)`** on live and snapshot sources (and `entryFields(source, entry, options?)` from `@cloudhal/astro-renderer/fields` for any source): an entry's typed fields as a theme draws them, by key in definition order. Values are resolved by the language rules (a translation's empty localized field reads the original's, `fromOriginal`; non-localized fields come from the translation group's original; language editions own their values), labelled in the page's language and made safe: rich text as HTML from the article body's markdown pipeline (raw HTML escaped, `safeHref` on links), URLs through `safeHref` (dropped when unsafe), images as `` attributes with the asset's alt in the page's language, everything else as formatted text. Also `renderFields`, `hasShownFields`, and `resolveFields`, `formatFieldValue`, `fieldLabel`, `fieldHelp`, `optionLabel` re-exported. + - **`formatFieldValue(value, def, { locale, defaultLocale?, timeZone?, words? })`** in `@cloudhal/core-ts/fields`: a value as plain text with `Intl` (numbers, dates that never shift a day, instants in their own zone, option labels as a list, yes/no words). + - **`EntryFields.astro`** in `@cloudhal/astro-renderer/components`: a plain, unstyled `
` of the fields that have a value, with `data-field` / `data-type` hooks for themes; nothing at all when none has one. + - **Blog starter:** articles of collections with fields show a "Details" list under the cover (English, Turkish and Japanese words). Entries of collections without definitions render byte for byte as before. + - New guide: `docs/guides/fields.md` (defining fields in Studio, MCP, the API and the CLI; operations; languages; theme API; security). +- bd5af88: Typed custom fields, step 2 (RFC-0041 / ADR-0043): the store and the API enforce field definitions. + + - **Site writes** (`updateSite`, `createSite`, `PUT /api/sites/:id/collections/:key`, dry run included) check definitions: reserved (`field_key_reserved`) and duplicate keys or options, `minimum` above `maximum`, 30 fields per collection and 200 per site (`too_many_fields`), 256 KB of collection settings (`too_large`). A plain edit never loses a value: changing a field's `type`, `localized` or `multiple`, or dropping a key or a select option that an entry still holds, is refused with `409 field_change_needs_operation`, naming the field operation to use. Other site writes do not re-run the checks. + - **Entry writes** check only the field values that changed: `422 invalid_fields`, `unknown_field` (a new key without a definition, once the collection has definitions; stored unknown keys are kept), `field_not_localized` (a translation's own copy of a non-localized value) and `required_field` (review or published without a `requiredToPublish` value; drafts save freely). `fields` is capped at 256 KB per entry in every collection when it changes (`too_large`). Image values must be image assets of the site, and image and rich-text asset references are recorded in `asset_refs` under `fields.`, so a used file cannot be deleted. Every refusal lists its problems with paths in `details.issues` (`fields/startsAt/at`). + - **API inputs** remove a key with `null` in a collection that has definitions. Collections without definitions keep `fields` as any JSON, exactly as before. + - **Search**: `text` and `richText` fields marked `searchable` add their words to the entry's search text at the next publish (off by default; sites without searchable fields index byte for byte as before). + - `refuseFieldIssues` and `fieldRefusalCode` are exported from `@cloudhal/core-ts/fields`. + +### Patch Changes + +- Updated dependencies [672b993] + - @cloudhal/core-contracts@0.5.0 + - @cloudhal/schedules@0.5.0 + - @cloudhal/storage@0.5.0 + ## 0.4.0 ### Minor Changes diff --git a/packages/core-ts/package.json b/packages/core-ts/package.json index 78322dc3..111185ac 100644 --- a/packages/core-ts/package.json +++ b/packages/core-ts/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/core-ts", - "version": "0.4.0", + "version": "0.5.0", "description": "Cloudhal Site Graph core (TypeScript): load/save nodes with optimistic locking, snapshots, diff, publish and rollback; taxonomies, terms, redirects and menus", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/create-cloudhal/CHANGELOG.md b/packages/create-cloudhal/CHANGELOG.md index 9d56c5cf..486d647f 100644 --- a/packages/create-cloudhal/CHANGELOG.md +++ b/packages/create-cloudhal/CHANGELOG.md @@ -1,5 +1,15 @@ # create-cloudhal +## 0.5.0 + +### Patch Changes + +- Updated dependencies [0ba1e01] +- Updated dependencies [cc263c3] +- Updated dependencies [92d3362] +- Updated dependencies [05274d3] + - @cloudhal/cli@0.5.0 + ## 0.4.0 ### Patch Changes diff --git a/packages/create-cloudhal/package.json b/packages/create-cloudhal/package.json index 3e0c12ce..06c8e09f 100644 --- a/packages/create-cloudhal/package.json +++ b/packages/create-cloudhal/package.json @@ -1,6 +1,6 @@ { "name": "create-cloudhal", - "version": "0.4.0", + "version": "0.5.0", "description": "Create a Cloudhal site: npm create cloudhal@latest", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/mcp-server/CHANGELOG.md b/packages/mcp-server/CHANGELOG.md index 748a8c49..10a7923e 100644 --- a/packages/mcp-server/CHANGELOG.md +++ b/packages/mcp-server/CHANGELOG.md @@ -1,5 +1,32 @@ # @cloudhal/mcp-server +## 0.5.0 + +### Minor Changes + +- 9d04a37: Typed custom fields, step 4 (RFC-0041 §8 / ADR-0043): MCP. + + - **`list_collections`** returns each collection's field definitions (`fields`) and `fieldsSchema`, the JSON Schema of an entry's values with labels and help in the asked `locale` (default: the site's). + - **`create_entry` / `update_entry`** check field values in `precheck` with the store's checker (changed keys only, unknown keys, a translation's copy of a non-localized value, `requiredToPublish` for review and published, image and `asset:` references), so a refused call never reaches a person; each issue keeps its path (`fields/startsAt/at`). `update_entry` takes `fields` as a merge patch (`null` removes a key), and its approval names typed changes readably ("Starts at (startsAt) → 5 Nov 2026 19:30 Istanbul", option labels, values quoted and truncated). + - **`update_collection`** takes `fields` (the whole list) for free definition edits; changes that could lose values are refused with `field_change_needs_operation`, naming the operation tool. + - **New tools `rename_field`, `change_field_type`, `set_field_localized`, `remove_field`** (`site:write` + `content:write`): always a person holding `site:settings`, in every mode including `bypass`; the approval shows the dry run (entries touched, values moved, converted or cleared, samples), `dryRun: true` reports without asking, and a call that would clear values without `onInvalid: "clear"` is refused before anyone is asked. A run that stops at its budget answers `done: false` with an `operationId`; calling the same tool again with it continues the operation after a new approval. + - Hints for every field error code, and server instructions telling agents to read `fieldsSchema` before writing entries and to use the operation tools for risky changes. + +### Patch Changes + +- Updated dependencies [672b993] +- Updated dependencies [cc263c3] +- Updated dependencies [92d3362] +- Updated dependencies [bd5af88] + - @cloudhal/core-contracts@0.5.0 + - @cloudhal/core-ts@0.5.0 + - @cloudhal/astro-renderer@0.5.0 + - @cloudhal/agent-runtime@0.5.0 + - @cloudhal/analytics@0.5.0 + - @cloudhal/comments@0.5.0 + - @cloudhal/schedules@0.5.0 + - @cloudhal/storage@0.5.0 + ## 0.4.0 ### Minor Changes diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index a13edbdc..3cbb1b67 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/mcp-server", - "version": "0.4.0", + "version": "0.5.0", "description": "Cloudhal MCP server: semantic site tools (pages, articles, snapshots, preview, publish) governed by the policy engine", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/schedules/CHANGELOG.md b/packages/schedules/CHANGELOG.md index cae5ffdb..9764e815 100644 --- a/packages/schedules/CHANGELOG.md +++ b/packages/schedules/CHANGELOG.md @@ -1,5 +1,13 @@ # @cloudhal/schedules +## 0.5.0 + +### Patch Changes + +- Updated dependencies [672b993] + - @cloudhal/core-contracts@0.5.0 + - @cloudhal/storage@0.5.0 + ## 0.4.0 ### Patch Changes diff --git a/packages/schedules/package.json b/packages/schedules/package.json index ea1d7fbf..055956d4 100644 --- a/packages/schedules/package.json +++ b/packages/schedules/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/schedules", - "version": "0.4.0", + "version": "0.5.0", "description": "Cloudhal schedules (RFC-0008): the time model, the RRULE subset and its sentences, releases (pin, closure, rl1: hash, compose, conflicts, state machine), automation and run state, taint and budget accounting, the Scheduler and runDue, and the SQLite/D1 store. Worker-safe.", "license": "Apache-2.0", "homepage": "https://cloudhal.dev", diff --git a/packages/storage/CHANGELOG.md b/packages/storage/CHANGELOG.md index a65ac2cb..30f8b79b 100644 --- a/packages/storage/CHANGELOG.md +++ b/packages/storage/CHANGELOG.md @@ -1,5 +1,12 @@ # @cloudhal/storage +## 0.5.0 + +### Patch Changes + +- Updated dependencies [672b993] + - @cloudhal/core-contracts@0.5.0 + ## 0.4.0 ### Patch Changes diff --git a/packages/storage/package.json b/packages/storage/package.json index dac77d27..520a5218 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -1,6 +1,6 @@ { "name": "@cloudhal/storage", - "version": "0.4.0", + "version": "0.5.0", "description": "Cloudhal storage interfaces (SQL driver, blob store) with Cloudflare D1/R2/Durable Object SQLite and local SQLite/filesystem adapters", "license": "Apache-2.0", "homepage": "https://cloudhal.dev",