All notable changes to Marko are documented in this file.
The format follows Keep a Changelog and the project follows Semantic Versioning. While Marko is in 0.x, the API may change between minor versions.
Entries from 0.4.0 onward are generated automatically by bin/release.sh from merged PR titles and labels (see .github/release.yml). Earlier entries were backfilled from GitHub Releases. The full list of changes for any version is also available at https://github.com/marko-php/marko/releases.
- feat: surface Claude Code multi-instance config-isolation tip on devai:install by @markshust in #143
- feat: add /release skill for version assessment and release execution by @markshust in #146
- fix: support union-typed entity columns via explicit Column type by @TuVanDev in #145
- docs: correct module/plugin naming convention in skills by @markshust in #142
- docs: correct multi-instance MCP guidance to lead with per-project scoping by @markshust in #144
- ci: gate every PR on tests, lint, and static analysis by @markshust in #147
- @TuVanDev made their first contribution in #145
- feat: make a fresh skeleton work with zero bootstrapping by @markshust in #139
- feat: self-refreshing mcp/lsp code index by @markshust in #141
- fix: show devai:install prompt text and stream live progress by @markshust in #138
- fix: prevent devai:install composer hang on invisible prompt by @markshust in #140
- fix: remove orphaned devai bootstrap shim from skeleton src by @markshust in #137
- feat(devai): offer to install a docs search driver during devai:install by @markshust in #133
- feat: add marko/testing as a skeleton dev dependency by @markshust in #134
- feat: warm caches on install and add MCP handshake timeout by @markshust in #135
- docs: clarify discovery cache vs code index and when a reindex is needed by @markshust in #136
- ci: retry split-repo pushes on concurrent ref-lock by @markshust in #131
- chore: remove deprecated marko/docs-vec driver in favor of docs-fts by @markshust in #132
- feat: tier 1 — close six critical/high security audit findings by @markshust in #116
- feat: tier 2 — fix ten high-severity correctness defects by @markshust in #117
- feat: tier 3 — fix twenty medium-severity defects by @markshust in #118
- feat: tier 4 — eliminate N+1 query loops on hot paths by @markshust in #119
- feat: tier 5 — harden twenty-four low-severity gaps by @markshust in #120
- feat: compiled discovery cache (+ recovered tier2 tokenizer prerequisite) by @markshust in #121
- feat: make devai guideline files marker-based and fully user-overridable by @markshust in #124
- fix: ship a correct .gitignore to generated projects by @markshust in #123
- fix(marko-skills): derive scaffold vendor from project dir, never marko by @markshust in #126
- fix(docs-fts): sanitize natural-language queries into safe FTS5 expressions by @markshust in #127
- fix(docs-vec): make the hybrid driver buildable and runnable on stock PHP by @markshust in #130
- docs: catalog 0.8.0 packages in main README by @markshust in #110
- docs: document GitHub Actions version convention by @markshust in #113
- docs: add audit remediation implementation plans by @markshust in #114
- docs: fold remaining audit findings into remediation plans by @markshust in #115
- docs: document devai marker-based override model in agent docs by @markshust in #125
- docs: improve search_docs ranking for module-system and config queries by @markshust in #129
- ci: add README package catalog drift check by @markshust in #111
- ci: bump actions/checkout to v6 in readme drift check by @markshust in #112
- chore: migrate hcf pipeline to agent frontmatter and prune stray docs by @markshust in #122
- feat: add marko/codeindexer (with interface subtraction) by @markshust in #97
- feat: add marko/claude-plugins by @markshust in #99
- feat: add marko/docs (documentation search contract) by @markshust in #100
- feat: add marko/docs-markdown (docs content as a module) by @markshust in #101
- feat: add marko/lsp by @markshust in #102
- feat: add marko/docs-fts + marko/docs-vec (docs search drivers) by @markshust in #103
- feat: add marko/mcp (PersistLastErrorPlugin + LastErrorTool dropped, Runtime/Contracts flattened) by @markshust in #104
- feat: add marko/devai (4 marker interfaces collapsed into single install()) by @markshust in #105
- fix: raise memory_limit in composer test scripts by @markshust in #107
- fix: raise memory_limit in release.sh test invocation by @markshust in #108
- fix: raise memory_limit in IntegrationVerificationTest pest subprocesses by @markshust in #109
- docs: add marko/codeindexer reference page + fix README doc link by @markshust in #98
- docs: widen sidebar + fix Claude Code install method + clarify MCP verification by @markshust in #106
- rename: rate-limiting → ratelimiter and dev-server → devserver by @markshust in #96
- feat: extract admin-panel templates into engine-specific sibling packages by @markshust in #94
- feat(database): add selectRaw, whereRaw, and orderByRaw to QueryBuilderInterface by @michalbiarda in #78
- feat(core): allow packages to declare global middleware in module.php by @michalbiarda in #80
- feat(database-readwrite): add marko/database-readwrite package by @markshust in #86
- feat: add Twig template engine driver as sibling to Latte by @markshust in #88
- feat: centralize driver registries with known-drivers.php pattern by @markshust in #91
- fix(docs): resolve expressive-code build warnings for latte and env by @markshust in #83
- fix: point split workflow at MARKO_BUILD_PAT secret by @markshust in #84
- fix: drop workflow-file PUT that 404s on freshly created split repos by @markshust in #87
- fix: harden 0.7.0 release (lint config, test fixes, dep refresh) by @markshust in #95
- docs: document boot-callback dialect override pattern for postgres-wire-compatible databases by @markshust in #85
- refactor(view): align ViewInterface bindings with Marko's simple-binding preference by @markshust in #90
- refactor(view): drop mutual conflict; align with multi-driver pattern by @markshust in #92
- fix(database): use SchemaRegistry in DiffCommand and MigrateCommand for extender merge by @michalbiarda in #67
- fix(database-pgsql): normalise jsonb → json in introspector type map by @michalbiarda in #69
- fix(database-pgsql): JSON-encode array bindings before passing to PDO by @michalbiarda in #72
- fix(database): link entity extenders at boot so companions hydrate during HTTP requests by @michalbiarda in #74
- fix(database-mysql): JSON-encode array bindings before passing to PDO by @markshust in #82
- feat(page-cache): full-page HTTP cache with file driver, tag invalidation, and entity bridge by @michalbiarda in #58
- feat(routing): memoize RouteMatcher and share one instance with Router by @markshust in #62
- feat: extend existing entity tables via #[Table(extends:)] by @markshust in #64
- fix(tests): align RepoManagementScriptsTest with batched gh repo list by @markshust in #60
- fix: auto-create missing split repos and cancel superseded runs by @markshust in #65
- chore(release): batch split-repo lookup and auto-create from release.sh by @markshust in #56
- @michalbiarda made their first contribution in #58
- feat: Add marko/inertia-react package by @ps-carvalho in #51
- feat: Add marko/inertia-vue package by @ps-carvalho in #52
- feat: Add marko/inertia-svelte package by @ps-carvalho in #53
- fix(tests): eliminate uniqid() parallel-flake and PHP 8.5 setAccessible() deprecation by @markshust in #55
- chore: sort root composer.json replace and autoload-dev alphabetically by @markshust in #54
- fix: harden release pipeline (deterministic changelog, self-healing Packagist) by @markshust in #50
- fix: push main before generating release notes by @markshust in #49
- feat: close database layer gaps for 1.0 by @markshust in #40
- feat: Add marko/vite package by @ps-carvalho in #42
- feat: add marko/debugbar package by @ps-carvalho in #43
- feat: Add marko/inertia package by @ps-carvalho in #47
- docs: use composer test for faster local test runs by @markshust in #38
- docs: document integration-destructive group and run it in release script by @markshust in #39
- docs: expand PR review process with package-PR checklist by @markshust in #46
- refactor: preference discovery and class extraction logic by @iamlasse in #44
- refactor: offload plugin discovery to PluginDiscovery class by @iamlasse in #45
- feat: add CHANGELOG.md with release-script automation by @markshust in #48
save()silently skipped update for entities inserted in the same request (#37)
- Fix database config examples to use flat format (#33)
- Add intro video to README after Why Marko section (#34)
- Fix code-standards violations across tutorials and guides (#35)
- Auto-convert camelCase property names to snake_case column names (#30)
- Add
route:listCLI command tomarko/routing(#25) - Add
doc-updaterto post-implementation pipeline (#26) - Add ORM relationships, collections, and query specifications (#28)
- Allow overriding host for dev server up (#11)
- Optional TLS for database connections (#6)
- Use DI container to instantiate layout components (#29)
- Add layout package to README, remove blog reference (#23)
- Add issue type to bug report and feature request templates (#19)
- Attribute-driven layout system (#20)
- Issue template dropdown validation errors (#16)
- Restore package options to issue template dropdowns (#22)
- Remove
marko/blogpackage from framework (#21)
- Derive repo from git remote for
gh release create(#14) - Replace
PluginProxywith generated interceptor classes (#15)
- Preload project autoloader in
bin(#10) - Add missing
QueryBuilderFactoryInterfaceimplementation inmarko/database-mysql(#7)
- Integrate plugin interception into container resolution (#12)
- Add PR review process guide (#13)
- fix(split): notify Packagist after tag push to prevent missed updates by @markshust in #2
- feat(release-workflow): add automated release workflow and contribution conventions by @markshust in #5
Initial public-ready release. Improved first-application guide flow and clarity, added marko open command, and clarified app/foo directory creation.
Standardized NoDriverException across all interface packages. Each interface package ships its own NoDriverException with a DRIVER_PACKAGES constant listing known implementations; the container detects and throws these specific exceptions instead of the generic BindingException.
First tagged release. Established integration-destructive test group with --parallel execution to prevent OOM, and configured the release script to exclude that group during normal test runs.