Skip to content
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 52 additions & 5 deletions .agents/skills/docs-conventions/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ description: Use when writing or reviewing Flet documentation, including Python

Use **Google style** docstrings with sections: `Args:`, `Returns:`, `Raises:`, `Note:`, `Example:`, `Warning:`.

### Cross-references (reST roles)
### Cross-references

#### reST roles

Use reST roles in Python docstrings. CrocoDocs renders them as links in the API docs.
Prefer these in docstrings. CrocoDocs renders them as links in
the API docs and they keep authoring terse when the auto-derived label is acceptable.

**Supported roles:** `:class:`, `:attr:`, `:meth:`, `:func:`, `:data:`, `:mod:`

Expand All @@ -20,9 +23,9 @@ Use reST roles in Python docstrings. CrocoDocs renders them as links in the API
If a parent is a :class:`~flet.ResponsiveRow`, this property determines
how many virtual columns the control spans.

See :attr:`value` for the current selection.
See :attr:`value` or :attr:`flet.Text.size` for the current selection.

Calls :meth:`~flet.Page.update` after modifying controls.
Calls :meth:`flet.Page.update` after modifying controls.
"""
```

Expand All @@ -38,6 +41,48 @@ Calls :meth:`~flet.Page.update` after modifying controls.
- Custom labels like `:class:`my label <flet.Page>`` — the label is always auto-derived from the target
- Roles for symbols not in CrocoDocs API data degrade to inline code

#### CrocoDocs xrefs

Use the xref syntax when the displayed text must differ from the symbol target or when
explicitly required by user. This is especially useful in docs-only strings such as the
`docs_reason` parameter of `@deprecated`, extracted validation messages, or short admonition text
where you want:

- inline-code labels with punctuation, such as ``new_func()`` or `local_position.x`,
- plain-language labels that do not match the target exactly,
- explicit full targets in the link destination for clarity.

Syntax:

```python
"""
Use [`Page.update()`][flet.Page.update] after mutating controls.
Use [`local_position.x`][flet.DragTargetEvent.local_position] instead.
See [the move callback][flet.DragTarget.on_move] for continuous updates.
"""
```

Rules:

- In `docs_reason`, prefer using CrocoDocs xrefs over reST roles.
- For same-class targets, prefer the current-class shorthands:
`[(c)]` for the current class, `[(c).]` for a member whose name matches the label,
and `[(c).member_name]` for an explicit same-class member target.
- Use full symbol targets for symbols outside the current class, for example `flet.IconButton` or `flet.Page.update`.
- Put the exact display text you want in the first `[]`.
- For methods, include `()` in the label when desired, but not in the target: ``[`Page.update()`][flet.Page.update]``.
- Use xrefs when reST role labels are too rigid; otherwise prefer reST roles in regular docstrings.

Same-class examples:

```python
"""
Use [`value`][(c).] instead.
Use [`value.y`][(c).value] for target-relative coordinates instead.
See [`ExampleControl`][(c)] for the replacement API.
"""
```

### Admonitions in docstrings

Google-style section headers render as Docusaurus admonitions:
Expand All @@ -56,7 +101,9 @@ Example:
"""
```

Supported kinds: `Note`, `Warning`, `Danger`, `Tip`, `Info`. Unsupported kinds (e.g. `Limitation`, `Example`) are normalized to `note`. Empty admonitions are skipped.
Supported kinds: `Note`, `Warning`, `Danger`, `Tip`, `Info`.
Unsupported kinds (e.g. `Limitation`, `Example`) are normalized to `note`.
Empty admonitions are skipped.

## Markdown Docs

Expand Down
122 changes: 89 additions & 33 deletions .agents/skills/flet-deprecation/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,9 @@ Do not use this skill for non-deprecation validation logic; use

## Source Of Truth

- Runtime decorators and warning helpers:
`sdk/python/packages/flet/src/flet/utils/deprecated.py`
- Field-level deprecation rule:
`sdk/python/packages/flet/src/flet/utils/validation.py` (`V.deprecated`)
- Docs extraction/labeling extension:
`sdk/python/packages/flet/src/flet/utils/griffe_deprecations.py`
- Runtime decorators and warning helpers: `sdk/python/packages/flet/src/flet/utils/deprecated.py`
- Field-level deprecation rule: `sdk/python/packages/flet/src/flet/utils/validation.py` (`V.deprecated`)
- Docs extraction/labeling extension: `sdk/python/packages/flet/src/flet/utils/griffe_deprecations.py`

## Deprecation Decision Order

Expand Down Expand Up @@ -50,45 +47,69 @@ Removal phase:
- Example: deprecated in `0.82.0` -> remove in `0.85.0`.
- Use that policy to set `delete_version` unless there is an approved exception.

## Target Release Audit

When working on a release for `{new_version}`, treat deprecations with
`delete_version == {new_version}` as mandatory audit items.

- Scan Python packages for `@deprecated(...)`, `@deprecated_class(...)`,
and `V.deprecated(...)` entries whose `delete_version` equals `{new_version}`.
- Recommended check command:
`rg -n 'delete_version\\s*=\\s*"{new_version}"|delete_version\\s*=\\s*\\x27{new_version}\\x27' -S sdk/python/packages`
- Treat every match as release-relevant work, not informational output.
- If matches are found, summarize the findings first and ask the human for approval
before editing files or making removals.
- For each match, decide whether the deprecated API must be removed now,
whether a prior removal was missed, or whether the deprecation timeline is incorrect.
- If removal is due, make the code, docs, and changelog updates in the same change.
- After the cleanup edits are ready, summarize the resulting diff and ask the human
for approval before creating a commit.
- Once commit approval is received, batch all confirmed `{new_version}` cleanup
edits into one grouped commit instead of splitting them across multiple commits.
Use commit message format: `release: remove deprecated APIs for {new_version}`
- Do not consider the release prep complete while unresolved `{new_version}` removals remain.

## Authoring Rules

1. Always set `version`.
2. Set `delete_version` using the 3-minor policy by default.
3. Keep `reason` plain text for runtime warnings.
4. Use `docs_reason` for docs-only markdown/xref text.
5. Prefer explicit replacement names in reasons.
4. Use `docs_reason` for docs-only markdown text and always write cross-references there as CrocoDocs xrefs.
5. When a replacement exists, name that replacement API explicitly in `reason` and `docs_reason`.

### Field Pattern

```python
from typing import Annotated, Optional
from flet.utils.validation import V

old_prop: Annotated[
Optional[str],
V.deprecated(
"new_prop",
version="0.17.0",
delete_version="0.18.0",
reason="Use new_prop instead.",
docs_reason="Use [`new_prop`][(c).] instead.",
),
] = None
class ExampleControl:
old_prop: Annotated[
Optional[str],
V.deprecated(
"new_prop",
version="0.17.0",
delete_version="0.20.0",
reason="Use new_prop instead.",
docs_reason="Use [`new_prop`][(c).] or [`new_prop`][flet.ExampleControl.new_prop] or :attr:`new_prop` or instead.",
),
] = None
```

### Function/Method Pattern

```python
from flet.utils.deprecated import deprecated

@deprecated(
reason="Use new_func instead.",
docs_reason="Use [`new_func()`][(m).new_func] instead.",
version="0.17.0",
delete_version="0.18.0",
)
def old_func():
...
class ExampleControl:
@deprecated(
reason="Use new_func instead.",
docs_reason="Use [`new_func()`][(c).new_func] or :meth:`new_func` instead.",
version="0.17.0",
delete_version="0.20.0",
)
def old_func(self):
...
```

### Class/Control Pattern
Expand All @@ -98,22 +119,57 @@ from flet.utils.deprecated import deprecated_class

@deprecated_class(
reason="Use NewControl instead.",
docs_reason="Use [`NewControl`][flet.] instead.",
docs_reason="Use [`NewControl`][flet.NewControl] or :class:`~flet.NewControl` instead.",
version="0.17.0",
delete_version="0.18.0",
delete_version="0.20.0",
)
class OldControl:
...
```

### Deprecated Property Pattern

```python
from flet.utils.deprecated import deprecated

class ExampleControl:
@property
@deprecated(
reason="Use new_value instead.",
docs_reason="Use [`new_value`][(c).] or :attr:`new_value` instead.",
version="0.17.0",
delete_version="0.20.0",
)
def value(self):
...
```

## `reason` vs `docs_reason`

- Runtime warnings always use `reason`.
- Docs admonitions prefer `docs_reason`; fallback is `reason`.
- Keep markdown/xref out of `reason` to avoid noisy runtime output.

For cross-reference shape rules, follow:
[`docs-cross-referencing`](../docs-cross-referencing/SKILL.md)
### Cross-reference Rule Inside `docs_reason`

Always use CrocoDocs xrefs in `docs_reason`, unless the user explicitly asks for a
different format, e.g. reST.

Reason:

- `docs_reason` often needs custom labels such as ``new_func()``, `local_position.x` or plain text.
- xrefs keep the display text fully under author control.
- same-class shorthands keep current-class references short and readable.
- full targets remain useful for cross-class destinations.

Examples:

- same-class member: ``Use [`new_value`][(c).] instead.``
- same-class custom label: ``Use [`local_position.x`][(c).local_position] for target-relative coordinates instead.``
- method xref: ``Call [`Page.update()`][flet.Page.update] after mutating controls.``
- plain-text label xref: ``See [the move callback][flet.DragTarget.on_move] for continuous updates.``

For cross-reference syntax rules, follow: [`docs-conventions`](../docs-conventions/SKILL.md)

## Docs Behavior Expectations

Expand All @@ -129,8 +185,7 @@ is a special case not covered by the extension.
When adding/changing deprecations, include tests for:
- runtime warning text (`reason`, versions, optional delete version),
- docs-only preference (`docs_reason` overrides `reason` in docs),
- docs rendering extraction for the used pattern (`V.deprecated`,
`@deprecated`, `@deprecated_class`),
- docs rendering extraction for the used pattern (`V.deprecated`, `@deprecated`, `@deprecated_class`, deprecated properties),
- label presence (`deprecated`) in docs extraction tests.

Prefer:
Expand All @@ -144,4 +199,5 @@ Prefer:
- Forgetting `delete_version` when a removal target is already known.
- Adding old/new value-copy logic in Python for rename migrations.
- Duplicating deprecation warnings in multiple lifecycle hooks manually.
- Broken crossref targets in `docs_reason` (for example malformed `[(c).]` links).
- Broken crossref targets in `docs_reason`.
- Using a full target for a same-class replacement when `(c)` shorthand would be clearer.
31 changes: 12 additions & 19 deletions .agents/skills/prepare-flet-release/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ description: Use when asked to prepare new Flet release by bumping versions and

## Related Skills

Use [`flet-deprecation`](../flet-deprecation/SKILL.md) when release prep includes:
Always use [`flet-deprecation`](../flet-deprecation/SKILL.md) during release prep
to audit deprecations for the target version. Also use it when release prep includes:
- adding new deprecations in this release,
- removing APIs whose `delete_version` equals this release version,
- auditing changelog entries that mention deprecations/removals.

Use [`write-changelog-entry`](../write-changelog-entry/SKILL.md) for drafting or refining individual changelog items.
That skill is the source of truth for item wording, scope selection, and what should or should not be mentioned in a single entry.

## Steps

* Take latest Flet release version from the repo and
Expand All @@ -23,24 +27,13 @@ Use [`flet-deprecation`](../flet-deprecation/SKILL.md) when release prep include
* Pull the latest `main` and create a new branch named `prepare-release-{new_version}` from `main`.
* Set new version in packages/flet/pubspec.yaml.
* Run pub get in /client dir to refresh pubspec.lock with new version.
* Add a new entry into packages/flet/CHANGELOG.md from a git log since the last release. Go through all commits and collect all mentioned issues and pull requests. There could be several issues done in a single PR (commit) - group them by creating a single descriptive change/fix/feature item and put all issues and PR links in `[#<issue_number>](<issue_url>)` format in braces next to it. Do not add chore/trivial/duplicate items.
Every changelog item must include both related issue link(s) and PR link(s) when available (issue first, PR second). If no issue exists, include PR link(s) only.
Also include issue-only items when a change was done via direct commit without PR (for example, an issue referenced in commit context but no PR exists).
Every changelog item must include author attribution as plain text, not a Markdown link: `by @<github_login>`.
Place attribution at the end of each item after links, for example:
`* Added feature X ([#123](...), [#456](...)) by @contributor.`
Use PR author login for PR-based items. For issue-only direct-commit items, use the commit author GitHub login if available.
If one item groups multiple PRs by different authors, attribute all relevant authors:
`by @user1, @user2`.
Ensure that all inferred PRs and issues in the changelog have `{version}` milestone attached on GitHub.
If a related issue or PR is missing the `{version}` milestone, update the milestone on GitHub and keep the link in the changelog; do not omit issue links just because milestone metadata is missing.
As it's a Flutter package prefer items having changes on Flutter side.
* Add a new entry into /CHANGELOG.md. Do not add chore/trivial/duplicate items, add "worth while" items with related issue or PR.
Every changelog item must include both related issue link(s) and PR link(s) when available (issue first, PR second). If no issue exists, include PR link(s) only.
Also include issue-only items when a change was done via direct commit without PR (for example, an issue referenced in commit context but no PR exists).
Every changelog item must include author attribution as plain text, not a Markdown link: `by @<github_login>`.
Use PR author login for PR-based items. For issue-only direct-commit items, use the commit author GitHub login if available.
If a related issue or PR is missing the `{version}` milestone, update the milestone on GitHub and keep the link in the changelog; do not omit issue links just because milestone metadata is missing.
* Add new entries into `packages/flet/CHANGELOG.md` and `/CHANGELOG.md` from the git log since the last release.
* Use [`write-changelog-entry`](../write-changelog-entry/SKILL.md) for every individual item.
* Build the candidate set from relevant commits, PRs, and issues since the last release.
* Ensure that all inferred PRs and issues in the changelog have the `{version}` milestone attached on GitHub.
* If a related issue or PR is missing the `{version}` milestone, update the milestone on GitHub and keep the link in the changelog.
* When selecting candidates for `packages/flet/CHANGELOG.md`, prefer items with meaningful Flutter-side impact.
* When selecting candidates for `sdk/python/packages/*/CHANGELOG.md`, prefer published Python-facing changes; do not include extension-internal Flutter implementation work unless it materially changes user-visible Python behavior.
* Scan all changelogs for `Unreleased` sections, not only the root ones:
* `/CHANGELOG.md`
* `packages/flet/CHANGELOG.md`
Expand Down
Loading
Loading