Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ pubspec.lock
app_data/

# FVM Version Cache
.fvm/
.fvm/

# Claude Code local data
.claude/worktrees/
.claude/settings.local.json
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@
* [Release] `start`: fix the length limit of the release notes in the form. The limit is enforced by alex now, instead of the `maxlength` attribute: a browser counts a newline as CRLF (2 characters), so a note with N newlines was cut N characters earlier than the store allows, and it was impossible to type anything while the counter still showed a value below the limit. The counter shows the number of characters as the store counts them, and it's highlighted if the value is longer than the limit.
* **Fixed**: alex hangs if a command it runs asks for an input. For example, `alex code gen` stopped with no output when `fvm` asked to install a missing Flutter SDK. Such a question can't be answered anyway, because the command gets a pipe instead of the terminal, so its input is closed right after the start now, and the command fails with its own message instead of hanging.
* **Fixed**: the output of a command could be lost, so a failed command could be reported without its error message. Now alex waits for the output to be fully read before it handles the result.
* [Code] New command `check`: runs the quality gates - analyze, tests and (optionally, with the `--build` flag) a debug build of the platform target. Output of the commands is filtered from noise, a short verdict is printed for each gate. Exit code is `0` if all gates passed, `10` if analyze failed, `11` if tests failed, `12` if build failed. Flags `--analyze-only`, `--test-only` and `--fail-fast` are supported, arguments after `--` are passed to the test command. Build target and additional noise patterns can be defined with the new `code.check` config section.
* [Common] New `--format=json` option (supported by `code check`, `info`, `agents` and `l10n check_translations` commands): a command prints a single JSON object with a machine readable report in the standard output, all other messages - including the update banner - go to the error output.
* [Agents] New command group `agents` with the `guide` subcommand: prints a short guide of alex for an AI agent or a script - the rules (config discovery, machine readable output, exit codes, interactive commands) and all commands with their options and exit codes. The guide is generated from the commands tree of the installed version, so it can't get outdated. Supports a command path argument to print a part of it (`alex agents guide l10n`) and `--format=json` for a structured index.
* [Agents] New command `agents init`: adds or updates the alex section in the agent instructions of the project (`CLAUDE.md`, `AGENTS.md` and alike), so an agent learns about alex from the file it reads first. The section describes the project (package, FVM, locales, l10n paths, branches) and the commands to use with their exit codes, and is generated from the alex config, `pubspec.yaml` and the commands tree. Only the content between the `<!-- alex:begin -->` and `<!-- alex:end -->` markers is changed. Files are taken from the new `agents.files` config option, the `--file` (`-f`) option, or `CLAUDE.md`/`AGENTS.md` if they exist. With the `--check` flag nothing is changed and the command fails with exit code `10` if some file is missing or outdated.
* [Common] New `--non-interactive` flag for every command that can ask a question in the standard input (`feature finish`, `pubspec update`, `custom add`). With the flag a command fails with an explanation of the option to pass instead of waiting for an answer that a script can't give. `feature finish` checks everything it would ask about before it starts, so it fails before the branch is merged, not after.
* [Feature] `finish`: new `--section` option (`added`, `fixed` or `pre-release`) to define the section of `CHANGELOG.md` for the entry, instead of choosing it interactively. Default is `added`, as for an empty answer.
* **Fixed** [Feature] `finish`: the command looped forever asking for an issue id when there was no input at all (a closed stdin in a script). Now it fails with a message.
* [L10n] `check_translations`: new `--format=json` option - a single JSON object with the result of every check (a stable `id`, the title, the status, and the problems with locales and keys for the failed ones) is printed in the standard output, so CI or an AI agent doesn't have to parse the human readable report. The list of files changed after `pub get` is reported in JSON too - both when it fails the command and when it's just a warning, so CI can see that the dependencies are not in sync.
* [Common] `--format=json`: an error object (with `ok: false`, the exit code and the message) is printed in the standard output for any failure - not only when a command has finished with a result. It covers an error of a command, a failure of the arguments parsing and a failure before the command is started, so a script always gets a JSON object to parse.
* [Info] New command `alex info` (alias `alex facts`): prints the facts about the project - package and version, path to the alex config, packages of a multi-package project, Flutter version pinned with FVM, locales (by the ARB files) and localization paths, git branches. Supports `--format=json`, so a script or an AI agent can get all of it with a single call instead of reading several files.

## 1.14.0

Expand Down
187 changes: 187 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,24 @@ $ alex f f -i{issueId} -c"Some new feature"

It's important to use double quote (`"`) on Windows, but on macOS or Linux you can also use a single quote (`'`).

The section of `CHANGELOG.md` can be passed with `--section` (`added` by default,
also `fixed` and `pre-release`), so nothing has to be answered interactively:

```bash
$ alex f f -i{issueId} -c"Some new feature" --section=fixed
```

For scripts and CI add `--non-interactive`: the command checks that everything it would
ask about is provided and fails with an explanation **before** it changes anything,
instead of waiting for an answer that will never come.

```bash
$ alex f f --non-interactive -i{issueId} -c"Some new feature"
```

The flag is supported by every command that can ask a question - they are marked
`[INTERACTIVE]` in `alex agents guide`.

### l10n

Work with localization files.
Expand Down Expand Up @@ -323,6 +341,34 @@ $ alex l10n check --print-changed-files --fail-on-changed-files
* `--fail-on-changed-files` — exit with code `11` instead of printing a warning,
so CI can rely on the exit code instead of parsing the output.

For a machine readable report (for CI or an AI agent) use `--format=json`: a single JSON
object with the result of every check is printed in the standard output, all other
messages go to the error output.

```bash
$ alex l10n check_translations --format=json
```

```json
{
"alex": "1.15.0",
"command": "l10n check_translations",
"ok": false,
"exitCode": 10,
"summary": "1 of 6 checks failed",
"checks": [
{"id": "arb_untranslated", "title": "All strings have translation in ARB", "ok": true},
{"id": "xml_duplicates", "title": "No duplicated keys in XML", "ok": false,
"message": "Duplicated keys found in XML",
"problems": [{"locale": "ru", "unexpectedKeys": ["some_key"]}]}
]
}
```

Every check has a stable `id`, so a script can react to a particular problem
without parsing the human readable output. If some files were changed after `pub get`,
then they are listed in the `changedFiles` field - even when it's only a warning.

#### Import translations from XML

It's for working with translations from Google Play.
Expand Down Expand Up @@ -382,6 +428,63 @@ Generate `JsonSerializable` and other.
$ alex code gen
```

#### Check code quality

Run the quality gates: analyze, tests and (optionally) a debug build of the platform target.
Output of the commands is filtered from noise (update banners, dependency resolution
chatter, deprecation notices of third-party plugins), a short verdict is printed for each gate.

```bash
$ alex code check
```

```bash
$ alex code check --analyze-only # fast inner loop check
$ alex code check --build # also compile the platform target
$ alex code check --fail-fast # stop on the first failed gate
$ alex code check -- test/some_test.dart # args after `--` are passed to the test command
```

Exit code is `0` if all gates passed, `10` if analyze failed, `11` if tests failed,
`12` if build failed. Other exit codes are used for errors.

For a machine readable report (useful for CI and for AI agents) use `--format=json`:
a single JSON object is printed in the standard output, all other messages go to the
error output.

```bash
$ alex code check --format=json
```

```json
{
"alex": "1.15.0",
"command": "code check",
"ok": false,
"exitCode": 11,
"summary": "analyze: no issues | test: 61 passed, 1 failed | build: skipped",
"gates": [
{"name": "analyze", "status": "passed", "summary": "no issues", "durationMs": 1109,
"count": 0, "errors": 0, "warnings": 0, "infos": 0, "issues": []},
{"name": "test", "status": "failed", "summary": "61 passed, 1 failed", "durationMs": 25350,
"passed": 61, "failed": 1, "skipped": 0, "total": 62, "completed": true,
"failures": [{"name": "should work", "suite": "test/a_test.dart", "message": "Expected: ..."}]},
{"name": "build", "status": "skipped", "summary": "skipped"}
]
}
```

Build target and additional noise patterns can be defined in the config:

```yaml
code:
check:
# ios (default on macOS) | apk (default on other platforms) | appbundle | web | macos
build_target: ios
# additional regular expressions of the output lines to hide
noise: [ 'some_noisy_plugin' ]
```

### Pubspec

Work with pubspec and dependencies.
Expand Down Expand Up @@ -802,6 +905,90 @@ This will show:

See `alex_custom_commands.yaml.example` in the repository for more examples.

### Info

Print the facts about the project: package and version, path to the alex config,
packages of a multi-package project, Flutter version pinned with FVM, locales and
localization paths, git branches.

```bash
$ alex info
```

Everything is taken from the alex config and the project files, so a script or an AI
agent can get all of it with a single call instead of reading several files:

```bash
$ alex info --format=json
```

### Agents

Support of AI agents and scripts.

#### Guide for an agent

Print a short guide of alex: what it is, the rules (config discovery, machine readable
output, exit codes, which commands are interactive) and all commands with their options
and exit codes.

```bash
$ alex agents guide
```

The guide is generated from the commands tree of the installed version, so it always
matches the tool and can't get outdated. Pass a command path to print the guide for one
command or a group only, and `--format=json` to get a structured index instead of
Markdown:

```bash
$ alex agents guide l10n
$ alex agents guide code check --format=json
```

The recommended way to use it with an AI agent is to mention it in the `CLAUDE.md` /
`AGENTS.md` of the project, so the agent runs `alex agents guide` instead of guessing
the commands from a hand written and possibly outdated description.

#### Init agent instructions

Add or update the alex section in the agent instructions of the project
(`CLAUDE.md`, `AGENTS.md` and alike), so an agent learns about alex from the file it
reads first:

```bash
$ alex agents init
```

The section describes the project - package and version, FVM, locales and l10n paths,
git branches - and the commands an agent should use with their exit codes. Everything is
taken from the alex config, `pubspec.yaml` and the commands tree, so the section can be
regenerated at any time.

The section is wrapped in the `<!-- alex:begin -->` / `<!-- alex:end -->` markers and
nothing outside of them is changed, so the command is safe to run on a file written by
a human, and safe to run again after the project has changed.

By default the files are taken from the `agents.files` config option, or `CLAUDE.md` and
`AGENTS.md` if they exist (a symlink between them is resolved, so the section is not
written twice), otherwise `AGENTS.md` is created. You can pass the files explicitly:

```bash
$ alex agents init -f CLAUDE.md -f .claude/profile/shared.md
```

```yaml
agents:
files: [ 'CLAUDE.md', '.claude/profile/shared.md' ]
```

For CI: `--check` changes nothing and fails with exit code `10` if some file is missing
or its section is outdated.

```bash
$ alex agents init --check
```

## Problem solving

### Command not found
Expand Down
16 changes: 16 additions & 0 deletions alex.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ code:
# `--workspace` flag instead of per-package. Set to false to disable.
use_workspace: true

# Quality gates (alex code check)
check:
# Target of the build gate (used with the --build flag):
# ios | apk | appbundle | web | macos.
# If not defined - ios is used on macOS and apk on other platforms.
build_target:
# Additional patterns (regular expressions) of the output lines
# that should be hidden as noise.
noise: []

# Application build settings (alex release start --local)
build:
# Name for build artifact files.
Expand All @@ -43,6 +53,12 @@ scripts:
ci:
enabled: true

# AI agents support (alex agents)
agents:
# Files with the agent instructions to update by `alex agents init`.
# If not defined - CLAUDE.md and AGENTS.md are used, if they exist.
files: []

# GIT settings
git:
branches:
Expand Down
Loading
Loading