(opus) in brackets, instead of a bare CLI default: brackets mean «nobody chose it here, and this is what
the session will run on». griglia:check prints it the same way ({agent: claude, model: (opus)}).agent_default_model / agent_default_effort (GRIGLIA_AGENT_DEFAULT_MODEL,
GRIGLIA_AGENT_DEFAULT_EFFORT, same shape as agent_models): tell the board which value the agent CLI —
or the worker, through GRIGLIA_WORKER_MODEL/GRIGLIA_WORKER_EFFORT — already starts with, and it names it
everywhere. A caption only: the board never sends it, so each worker keeps its own default. A value the
agent no longer offers is ignored.Full changelog: https://github.com/alle80/griglia/compare/v0.94.0...v0.95.0
GRIGLIA_TRANSPORT now defaults to auto:
sync-context.py, sync-skills.py, claude-tokens.py, agent-status.py and the persistent worker
(--transport auto|docker|local, printed at startup) probe $GRIGLIA_CONTAINER once and, when no daemon or
no container answers, run php artisan from the project root. A machine that serves Laravel with
composer dev, Apache or nginx needs no configuration at all, instead of failing with «Cannot connect to the
Docker daemon»; GRIGLIA_TRANSPORT=docker|local still pins the choice. Every failure now prints the
transport in use and the variable that changes it.griglia:auto-archive needs, caches, assets and live updates outside a container.Full changelog: https://github.com/alle80/griglia/compare/v0.93.0...v0.94.0
GRIGLIA_AGENT_MODELS="claude:opus,sonnet;codex:gpt-5", GRIGLIA_AGENT_EFFORTS="low,medium,high" —
and a list picks its default while any task overrides it, from the badge under its title or from the commands
of its modal, next to the agent. The effective value is always visible: on the row, in the modal, and next to
the title in griglia:check ({agent: claude, model: opus, effort: high}). The persistent worker reads it
from --worker-json and passes it to the CLI, falling back to its own --model/--effort. Without the two
variables nothing changes: no selector, and every session keeps the CLI's default.Full changelog: https://github.com/alle80/griglia/compare/v0.92.1...v0.93.0
griglia:check --agent= and griglia:watch --agent= now match the configured
agents by key or label, in any case (Claude Code, Claude, CLAUDE → claude), and an agent nobody
configured stops the command with the list of the real ones. Before, an unrecognised text ran as itself and
the ownership guard compared it with the resolved owner, so every task was refused with a message where the
two agents looked like the same one («belongs to agent «Claude», you are «claude»»). On a board with a
single agent the option is now decoration instead of a refusal. A label stored where a key belongs
(todos.agent / checklists.agent) resolves to its agent as well, instead of falling back to the default.Full changelog: https://github.com/alle80/griglia/compare/v0.92.0...v0.92.1
griglia:check and griglia:watch now cover
every list of the agent-list owner that holds a task marked open to work (or working, or waiting for an
answer). Those tasks are listed last, under 📋 List «…», after the agent list and the started plans, and
--take / --done / --ask accept their ids. Before, a green dot outside the agent list and outside a
plan was invisible to the agent: the user waited for work nobody could see. Foreign lists never show more
than what was opened for the agent, --all included, and a list with nothing open stays out of the output.Full changelog: https://github.com/alle80/griglia/compare/v0.91.4...v0.92.0
python3 throughout agent instructions, installation guides, worker examples and cron snippets, so commands do not depend on executable file permissions.Full changelog: https://github.com/alle80/griglia/compare/v0.91.3...v0.91.4
Full changelog: https://github.com/alle80/griglia/compare/v0.91.2...v0.91.3
claude -p …, codex exec …) for scripts and cron, and a persistent worker — with what all
three need and why the working directory decides whether the agent sees the board.cd + CLI command and the first message to send, then points at the new page for the other two ways.Full changelog: https://github.com/alle80/griglia/compare/v0.91.1...v0.91.2
dashboard_route path (/dashboard by default) — the very path Breeze and Jetstream give their own
dashboard. In a host application that owns it, the package route never wins and the tab framed the
host's page. The URL is now built from the package's own board route (griglia.home, falling back to
griglia.dashboard when the home route is off), which no host path can shadow, and it is exposed as
Alle80\Griglia\Support\Board::url().dashboard_route no longer governs the side tab: setting it to null drops the legacy redirect only,
and the tab keeps pointing at the board. show_dashboard_tab in /settings remains its off switch;
with no board route at all there is nothing to frame and the tab is not rendered.Full changelog: https://github.com/alle80/griglia/compare/v0.91.0...v0.91.1
Alle80\Griglia\Http\Middleware\InjectBoardTab, is pushed into the web group and splices the
slide-out tab into every HTML response just before </body>, the way laravel-debugbar injects its bar:
the board is one click away from anywhere in your app, with nothing to add to your layouts. It stays out
of everything that is not a full page (JSON/AJAX, redirects, downloads, streamed and binary responses,
Livewire /livewire/update, Turbo frames, Inertia visits), out of the package pages — whose layout
prints the tab already, so it is never doubled — and out of the pages of a visitor who may not open the
board (same verdict as the route guard, now readable as GrigliaAccess::allows()).inject_tab_except: paths where the tab must not be injected, as Request::is globs matched
against the path and against the route name (default: an empty list, i.e. inject everywhere). The
show_dashboard_tab switch in /settings still turns the tab off everywhere.griglia.css nor Alpine. Its rules left resources/css/griglia.css (they
had a single consumer) and the desktop-only rule is a media query instead of the Tailwind utilities
hidden lg:block, which a host app may not have built.Full changelog: https://github.com/alle80/griglia/compare/v0.90.1...v0.91.0
composer require. It opens with a
copy-paste short version, then explains the two steps that were missing: publishing config/griglia.php
with a table of the keys that matter on day one (table_prefix — to be decided before the first
migrate — user_model, mode, route_prefix, dashboard_route, agent_list, agent_name,
agents/agent_key, attachments_disk), with two ready .env blocks and the cached-configuration
gotcha, and generating the instruction files the agent reads (AGENTS.md, CLAUDE.md, GEMINI.md).vendor:publish --tag=griglia-scripts, scripts/sync-context.py --backup (originals kept in
docs/context-originals/) — and how to undo: --restore and the «Generate instruction files from the
board» switch on /context./context is named as the UI names it.Full changelog: https://github.com/alle80/griglia/compare/v0.90.0...v0.90.1
checklists, todos, ingredients,
attachments, questions, context_groups and context_blocks become griglia_checklists,
griglia_todos, … so an installation no longer squats generic names in the host database. migrate
renames the existing tables in place, data and foreign keys included; nothing else to do.griglia.table_prefix (GRIGLIA_TABLE_PREFIX, default griglia_): set it to '' to keep the
historical unprefixed names. Alle80\Griglia\Support\Tables resolves every table through it, and the
models follow via the HasPrefixedTable trait.settings (spatie/laravel-settings),
notifications (Laravel) and the push subscriptions (webpush) — are deliberately not prefixed: those
libraries look their tables up through their own configuration.assertDatabaseHas('todos', …)) must use
the new names, or Tables::name('todos'). Eloquent, the components and the commands need no change.Full changelog: https://github.com/alle80/griglia/compare/v0.89.21...v0.90.0
.html URLs), instead of producing the nonexistent /features/index/.Full changelog: https://github.com/alle80/griglia/compare/v0.89.20...v0.89.21
tests badge is green again. v0.89.19 was tagged without regenerating the link block at the end
of this file, so ReleaseProcessTest failed on master and on every fresh clone — the first thing an
external contributor runs (composer qa) came back red for a reason that had nothing to do with their
change. The block is regenerated, and the release procedure now refreshes it before tagging instead of
trusting a manual step.composer qa survives being run twice. The suite leaves the Testbench skeleton without this package, so
the next composer docs:check answered There are no commands defined in the "griglia" namespace; it now
rebuilds the manifest first. The mirror image of the same state made PHPStan report three errors CI never
sees, because Larastan analyses a skeleton that registers the package: those three exceptions are now
tolerated in either state (reportUnmatched: false) instead of failing the run.Route [login] not defined (EN+IT). Installing the package into a Laravel application
that has no authentication at all and opening / answers 500, because server mode redirects to a login
route that does not exist. The page, the installation tutorial and the README requirements now name the
symptom and the two ways out: add a login flow, or GRIGLIA_MODE=local on a trusted machine.private_vulnerability_reporting is part of .github/repository.json and of repo-metadata.php, so the
private reporting channel that SECURITY.md and the issue templates point at is checked like the other
repository metadata instead of depending on a switch somebody remembered to flip.Full changelog: https://github.com/alle80/griglia/compare/v0.89.19...v0.89.20
--help texts included. Only text changed: no behaviour, no renamed symbol. The user-visible strings stay
where they belong, in resources/lang, translated on purpose.scripts/agent-status.py sends English window labels (5 hours, 7 days) and the board translates the keys
it knows (five_hour, seven_day, seven_day_opus, seven_day_sonnet, primary, secondary), so
/agents reads the same as before in Italian while the collector stays language-neutral. An unknown key
still falls back to the label in the snapshot.scripts/sync-context.py writes an English header in the generated instruction files. It recognises the
header of older releases too, so an upgrade does not mistake a generated CLAUDE.md for a hand-written one.scripts/builtin-skills.json describes the built-in skills in English, like every skill read from disk.QualityStandardsTest fails on the first Italian word found in a comment of src/, scripts/, tests/,
the views or the stylesheets — the rule the contributing guide already stated now has a check behind it.Full changelog: https://github.com/alle80/griglia/compare/v0.89.18...v0.89.19
docs/architecture.md, EN+IT): the task cycle as a Mermaid state diagram — every
arrow with the command that moves it, from --take to --approve — plus the tables behind it: what lives
in each directory of src/, which table holds what, which columns you write and which ones the agent
writes, the three chains (depends_on_id, parent_id, review_of_id), the middleware chain of a request,
the broadcast path, and the line between config/griglia.php and the settings in the database. It closes
with what is deliberately absent: no HTTP API, no machine tokens, no webhooks, no MCP.docs/roadmap.md, EN+IT) in three parts and with no dates: what already works, what comes
next (quality gate, first contact, griglia:install, zero-config access, task history, stuck tasks and
griglia:doctor, export/import with a versioned --json, file and link attachments, keyboard shortcuts,
the road to 1.0), and what is out of scope by choice — teams, PM fields, HTTP API/webhooks/MCP, chat
channels, PWA and offline, a login of its own — each with the reason behind the decision.pymdownx.superfences custom fence), documented for
contributors in Building this site.ArchitectureAndRoadmapTest: the diagram draws every state and every command that moves it, the page names
every table the migrations really create and every directory of the source, the roadmap keeps its three
answers apart and says where each closed branch stands, both pages are in the nav and in the README, and
none of their links points at a file that is not there.Full changelog: https://github.com/alle80/griglia/compare/v0.89.17...v0.89.18
docs/glossary.md, EN+IT): the sub-task seen from the
code — the Ingredient model, the ingredients table, the IngredientModal component — plus a headword
for the agent and its key, and one for a style next to the theme it goes beyond. The seven states
are now a table with the same dot icons the board draws, instead of a sentence.docs/faq.md, EN+IT), grouped under Before you install, Using
the board and Working with agents: why the first griglia:check says there is nothing to do (the task
is still waiting, or it is outside the agent_list), whether the agent can keep working unattended
(persistent workers), how the board reaches you when it asks or finishes (bell, Web Push, mail and the
notify_on_* settings), and what it costs in tokens — plus the ⚡ optimization settings that lower it.FaqAndGlossaryTest: both pages exist in both languages with the same questions, the glossary defines
every word the interface uses and shows every state icon, the two pages are in the nav and in the README,
and none of their links points at a file that is not there.Full changelog: https://github.com/alle80/griglia/compare/v0.89.16...v0.89.17
docs/configuration/extending.md, EN+IT,
in the nav and in the README). One working example per seam: publishing the views
(vendor:publish --tag=griglia-views, which overrides the Blade components too, file by file), publishing
the strings, adding a third board language (lang/vendor/griglia/<locale>/t.php — the selector in
Settings picks it up by itself), generic themes, a dedicated style with its own Livewire component and
its #[Layout], the settings skin (Themes::registerStyle / registerSkin), listening to
TodoChanged, the access hooks (canAccessGriglia, canManageGriglia, GRIGLIA_USER_MODEL) and taking
over the routes (register_routes).ExtensionPointsTest runs those recipes instead of trusting them: a published view really does win over
the package one, a published translation merges key by key (what you leave out keeps following the
package), a brand new locale really does show up in Locale::available() and in the settings selector,
and a registered style really does get its route and its skin.--tl-* variables grouped by what they paint, and a four-step walkthrough of the sample pack — which is now
linked (resources/themes/pollon) instead of merely mentioned, with its theme.json and theme.css shown.Full changelog: https://github.com/alle80/griglia/compare/v0.89.15...v0.89.16
.github/repository.json holds the description, the
homepage, the topics and the feature switches of alle80/griglia, and
.github/scripts/repo-metadata.php compares them with the live repository (--apply writes them).
Metadata that lives only in a settings page drifts unnoticed; now a diff shows it and
RepositoryMetadataTest fails when the file, composer.json and the documentation stop agreeing.docs/images/social-preview.png, 1280×640): the card GitHub shows when the
repository is shared, and the og:image of every page of the documentation site. overrides/main.html
now writes the Open Graph and Twitter card tags — title and description follow the page and the language,
so a link to the site stops rendering as a bare URL.CONTRIBUTING.md say so.composer.json gains homepage and a support block (issues, forum, source,
docs, security policy), so the package page points somewhere.composer.json keywords cover what the package is (task-board,
coding-agent, ai-agents, laravel-package, kanban).Full changelog: https://github.com/alle80/griglia/compare/v0.89.14...v0.89.15
0.x version number
promises (a minor may break, a patch never does), what counts as public surface and therefore breaking,
how deprecations are announced, which versions are supported, and the four manual steps of cutting a
release before GitHub takes over. README.md, CONTRIBUTING.md, the Development, Contributing and
Upgrading pages point at it instead of restating a piece of it each..github/workflows/release.yml): pushing a
vX.Y.Z tag publishes a release whose notes are the section that version already has here, followed by a
compare link. A tag whose version has no section fails the workflow instead of publishing an empty release,
and re-running the workflow by hand on an existing tag refreshes its notes. The 210 tags released before
this one were backfilled the same way, and the two tags that never had an entry — 0.12.1 and 0.54.1 —
were written from their commits so that every tag is described here..github/scripts/changelog-notes.php — the one place that reads this file: the notes of a version
(changelog-notes.php 0.89.12), the version released before it (--previous), its date (--date), and
the whole [x.y.z]: …/compare/… block that closes the file (--links).[Unreleased]
one still compared from v0.88.11, so most version headings rendered as plain bracketed text. The block is
generated now, and ReleaseProcessTest fails when it no longer matches.Full changelog: https://github.com/alle80/griglia/compare/v0.89.13...v0.89.14
Full changelog: https://github.com/alle80/griglia/compare/v0.89.12...v0.89.13
CONTRIBUTING.md, the Contributing page and the Development page link it.composer qa — one command for the whole gate (lint, test, docs:check), in the order CI runs it
and with nothing but PHP and Composer required. New scripts alongside it: format (applies Pint instead of
reporting), test:coverage (needs pcov or xdebug; report in build/coverage), docs:check (the generated
reference pages still match the code) and docs:build (the strict bilingual site). Every script now carries
a description, so composer run --list explains itself..github/dependabot.yml) — grouped weekly pull requests for the development toolchain and
for the GitHub Actions, monthly ones for the front-end toolchain. Runtime constraints are deliberately
excluded: they are wide ranges the host application resolves, and narrowing one would be a breaking change.tests.yml declares a read-only token, adds workflow_dispatch, and cancels a run superseded by a new push
on the same branch — never on master, where every commit keeps a verdict of its own.reportUnmatchedIgnoredErrors: true), which is what the
documentation already claimed. Three entries that no longer matched anything were removed, one of them for a
file deleted long ago; the analysis stays green at level 5 without a baseline.QualityStandardsTest guards the setup itself: the Composer scripts and their descriptions, what qa runs,
the workflow jobs and permissions, the Dependabot ecosystems, the presence of the page in both languages and
in the navigation, and that no ignore entry excuses a file that no longer exists.Full changelog: https://github.com/alle80/griglia/compare/v0.89.11...v0.89.12
Full changelog: https://github.com/alle80/griglia/compare/v0.89.10...v0.89.11
.github/ISSUE_TEMPLATE/ (bug report, idea or feature request, documentation
problem, question), a config.yml that disables blank issues and points a vulnerability to private
reporting and a first question to the FAQ, and a .github/PULL_REQUEST_TEMPLATE.md with the problem/what
changed/how you tested it sections and the contribution checklist. The bug form asks for the versions, the
mode and a reproduction; the idea form makes the scope and the two constraints (vendor-neutral agent
contract, AI optional and off by default) explicit before the code is written. The Contributing page in
both languages and CONTRIBUTING.md describe the forms, and IssueTemplatesTest guards their structure,
their labels and the checklist they share with the documentation.Full changelog: https://github.com/alle80/griglia/compare/v0.89.9...v0.89.10
CODE_OF_CONDUCT.md at the root of the repository (where GitHub looks for it, with the
reporting address filled in and a section on what it means with a single maintainer), and a new
documentation page in English and Italian — why a standard text, where it applies and where it does not,
what is and is not a conduct problem in a review, how a report is handled and in how long, and the full
text included from the root file. README.md, CONTRIBUTING.md, GOVERNANCE.md and the Contributing and
Governance pages link it, and CodeOfConductTest guards the file, the links, the reporting contact and the
navigation entry.Full changelog: https://github.com/alle80/griglia/compare/v0.89.8...v0.89.9
griglia:check, while the user guide stays focused
on connecting and using an agent.Full changelog: https://github.com/alle80/griglia/compare/v0.89.7...v0.89.8
CONTRIBUTING.md at the root of the repository (where GitHub looks for it
in the issue and pull request forms) with the one-minute setup and the short version of the rules, and a
rewritten Contributing page (docs/contributing/contributing.md) in English and Italian: ways to contribute,
what to do before writing code, what a bug report and a proposal must contain, the code/tests/translations/
documentation/changelog requirements, commit and branch conventions, a pull request checklist, what CI runs
and what happens after the review, agent-written contributions, expected conduct, license and security. The
README and GOVERNANCE.md now link the root file, and ContributingTest guards the files, the links and
the essentials of the page.Full changelog: https://github.com/alle80/griglia/compare/v0.89.6...v0.89.7
Full changelog: https://github.com/alle80/griglia/compare/v0.89.5...v0.89.6
0.x is.Checklist, Todo, Ingredient).Full changelog: https://github.com/alle80/griglia/compare/v0.89.4...v0.89.5
GOVERNANCE.md link it, and the broken LICENSE.md link in the README now points at LICENSE.Full changelog: https://github.com/alle80/griglia/compare/v0.89.3...v0.89.4
How can I help you explore Laravel packages today?