utakata 1.7.1
utakata: ^1.7.1 copied to clipboard
A Dart CLI tool for building Flutter apps with pluggable architecture templates (Clean Architecture, MVVM, and more), designed for human and AI agent collaboration.
Changelog #
1.7.1 #
- fix(message):
utakata message adddocumented--external-idas the deduplication key but never looked at it, so onlyimportactually deduplicated. Re-running an external import tool therefore doubled every message it fed throughadd(attachments, typically, since those cannot go through the JSONL path) while theimporthalf stayed correct — the record count grew on every run.addnow skips when a record with the sameexternal_idalready exists, reporting the existing ID and exiting 0 so repeated runs stay idempotent. Without--external-idthe behavior is unchanged: identical entries are still allowed, because a client really can send the same sentence twice. - docs: New
doc/skills/utakata-migration/SKILL.md— a hand-distributed skill for adapting a project that predates utakata. It is deliberately not generated byclaude init, because it is needed before utakata is installed. It covers whatdoc/names are reserved (and, more usefully, that everything else can stay put), thatdoc initnever overwrites, thatdoctor --migratealready handles the legacyAI/anddoc/loglayouts, and the trap that an existing.claude/settings.jsonis protected — so utakata's hooks and permissions are silently not added and must be merged by hand. - fix(message):
message import --format jsonldid not normalize timestamps carrying an offset orZto local time, so the same instant produced a different day in the record ID — and a different month file — depending on whether it arrived throughimportor throughadd. 1.6.0 fixed this foraddandlog; the JSONL import path was missed.
1.7.0 #
- feat(impl):
utakata implnow tracks a plan on two axes — implementation (todo → in_progress → review → done) and verification (todo → in_progress → review → done, plusnot_requiredto say testing is deliberately unnecessary). A single lane mixing the two could not tell "implemented, not yet tested" from "in review", nor express a test failure sending work back. New transitions:impl start/impl review(in_progresswas previously unreachable from the CLI at all) andimpl test start|review|done|todo|skip. Going backwards is allowed — a failing test legitimately returns a plan toin_progress— but the verification axis cannot advance until implementation isdone. - feat(impl): Plan files now live in lane directories derived from those two axes (
doc/impl/1_todo/…7_done/, plus the existingarchive/), and a transition moves the file for you. The frontmatter stays the single source of truth and the directory is derived from it, so a plan can never be in two states at once;utakata impl sync [--dry-run]puts hand-moved files back, andutakata doctorreports any drift. Newutakata impl boardprints the lanes and regeneratesdoc/preview/impl_board.md, which every state-changing command now refreshes.impl listgains--status/--test/--lane/--json. - feat(enforcement):
enforcement.impl_plan: "on"is wired at last.apply --scope featureandfeature addrefuse to scaffold a feature that has no plan yet — per feature, so the rest still generate and only the skipped ones set exit 1 — and features already on disk are never gated. Since the CLI cannot gate code written by hand,utakata doctoradditionally reports features that have an implementation but no plan. - note:
enforcement.impl_plannow defaults tooff. It was parsed with a default ofonbefore, but nothing acted on it; wiring the gate without flipping the default would have stoppedapplyfor every existing project on upgrade. Turn it on explicitly when you want the gate.utakata feature addis gated the same wayapplyis. - fix(impl): Archiving a plan used to free its ID for reuse (
listAllnever looked insidearchive/), so the nextimpl newcould mint aPLAN-NNNNthat already existed — confirmed on a real run. IDs are now taken from the maximum across every lane includingarchive/. - refactor(impl):
verification.static/on_device(written but never updated by any command) are folded into thetest:block. Old plans keep working:status: draftreads astodo, the legacyverificationmap maps onto the test axis, and flatdoc/impl/*.mdfiles are still found — runutakata impl syncto move them into lanes. - fix(impl): Hardening from the adversarial review. Lane moves refuse to overwrite an occupied destination (a plain
renamesilently destroyed the file already there — reachable whenever a duplicate ID exists, which 1.6.x could produce);impl syncskips and reports those instead, exiting 1. Feature names are validated, soimpl new "../../x"can no longer write outsidedoc/impl/and clobber an unrelated file, and they are snake_cased likefeature adddoes so the enforcement gate matches. The scan is recursive (a plan filed underarchive/2026/used to be invisible to ID assignment) and no longer dies on one unparseable plan; unreadable plans and duplicate IDs are reported bydoctorand still consume their ID. Frontmatter values are escaped properly — a--reasoncontaining a quote or backslash previously produced YAML the CLI itself could not read back.doc/implis built withp.join, so lane comparison works on Windows. - fix(impl): Moving backwards now clears what no longer holds:
completed_onwhen leavingdone,static/on_devicewhen testing is sent back, andskip_reasonwhen leavingnot_required(copyWithtreated null as "keep", so stale values lingered in the frontmatter and on the board). - fix(doctor): New diagnostics go through
CliMessagesinstead of hardcoded Japanese,enforcementkeys and values are validated (a typo silently disabled the gate), and autakata-impl-flowskill left over from an older version is reported —claude initnever overwrites it, so an upgraded project would keep teaching the AI the old lifecycle. - docs: New
doc/impl-plan.md(utakata doc show impl) covering the two axes, lane derivation, the full command set, and the enforcement gate;enforcement.impl_plangraduates from the reserved-keys table indoc/utakata-yaml.md; the generatedutakata-impl-flowskill now teaches the real lifecycle instead ofnew → done → archive.
1.6.0 #
- feat(message): New
utakata message— a fourth record stream for the verbatim correspondence you exchange with a client (doc/records/messages/YYYY-MM.jsonl, append-only). Kept separate fromlogon purpose: the raw text is the primary evidence of what was actually said, so it is stored unmodified (no[REDACTED]masking, unlike session import) and never rewritten, whilelogstays a searchable human summary.addrecords one message (body from arguments or stdin);import --format jsonl|mdbulk-loads existing threads, keyed onexternal_id— synthesized from the source's content and ordering when the source has none — so re-running an export never doubles up, yet a phrase repeated in a thread is kept as the separate message it is;list/show/render/linkquery it, regeneratedoc/preview/messages/, and attach a log or agreement reference without touching the body (linkmerges into the raw line and replaces the file atomically, so unknown fields and unparseable lines survive). Exposed to MCP asmessage_queryonly whenrecords.agent_read.messagesis enabled — otherwise the tool is not listed, and calling it by name is refused before any record is read. - feat(records): New
records.agent_write: none | append | full(defaultnone= current behavior) controls what an AI agent may write todoc/records/, andutakata claude initnow generates.claude/settings.json,CLAUDE.mdand the client-context skill accordingly (they used to state "AI never writes" unconditionally). The useful middle setting isappend: file writes stay denied, but the append commands are allowed viaBash(utakata log add:*)and friends — so an agent can add entries while ID assignment and schema validation always run, and past records remain structurally unmodifiable. In those modes the generated settings also exportUTAKATA_ACTOR=agent:claude, so agent-written entries are labelled inrecorded_by.full(direct edits) is meant for your own projects;utakata doctorflags it, warns on a misspelledrecordskey or value (which would otherwise silently fall back tonone), and detects when a utakata-generated.claude/settings.jsonno longer matches the configured mode. - refactor(status):
status --write-reportnow writesdoc/preview/project_status.{yaml,md}instead ofAI/snapshots/— the last generated artifact still landing in the legacy layout, whichdoctor --migratedeletes as a derived artifact, soAI/kept reappearing in migrated projects. The unusedcurrent_structure.yamlwriter is gone (checkderives that every run).doctorreports a leftoverAI/snapshots/and notes it is safe to delete. - fix(cli): Input-validation failures (a future
--at, an unknown--direction) printed a raw Dart stack trace instead of a message, becauseArgumentErroris anErrorrather than anExceptionand the base command only caught the latter. They now print just the message and exit 64; the MCP server, which had the same gap, no longer dies on a bad argument. - fix(records): ID assignment now takes the highest existing sequence rather than the record count, in both
messageandlog— with a record deleted by hand, the next entry used to reuse an ID already in the file. Timestamps carrying an offset orZare normalized to local time, so--at "…+09:00"no longer lands in the previous day's ID and month file. Malformed rows are skipped with a count instead of taking the whole read down, and a repeatedly-read corrupt line is no longer appended to.corruptagain on every read. - fix(status):
project_statusreported the specification and structure-plan documents by looking for them underAI/specs/— they now resolve underdoc/first (the legacy path remains a fallback), and the architecture id is read fromutakata.yamlbeforeplan.yaml. - docs: New
doc/records.md(utakata doc show records) covering the four record streams, themessageworkflow, and theagent_writepolicy;doc/utakata-yaml.mddocumentsrecords.agent_write/agent_read(previously listed under reserved-but-unwired keys).
1.5.1 #
- fix(create):
utakata createwrote version ranges into the generated pubspec.yaml unquoted (drift_dev: >=2.25.0 <2.28.2), which is invalid YAML —>starts a block scalar — so the very firstflutter pub/build_runnerrun crashed with "Expected comment or line break". Values that are not safe YAML plain scalars are now double-quoted. If you hit this with 1.5.0, quote thedrift_dev:line in the generated pubspec.yaml by hand (or re-runcreatewith 1.5.1).
1.5.0 #
-
feat(imports) (#20): New
utakata imports— a deterministic import-health audit of dependency direction, not just file placement. Two declarations drive it:- Internal deps —
arch_definition.yamlgainsimport_rules: a layer dependency graph (layers:— "this layer may see these layers", the own layer always allowed; 4 lines describe Clean Architecture) plus optional per-directory refinements (dirs:, longest match wins) where a layer's default is too loose (states, atoms, data sources…). Paths belonging to no layer (core/,main.dart— where composition roots live) are exempt; audit scope islib/features/. - External deps — packages are managed in
dependencies/*.yamlas version + placement (layers:per package: where it may be imported;[]= build-time only; omitted = unconstrained). Only declared packages are judged — anything outside the stack is allowed. The samecore_stack.yamlfeedsutakata create's initial pubspec, so version and placement can't drift apart.
Directive extraction is lexical (comments/strings ignored, all branches of conditional imports audited);
package:<your app>/...resolves as internal. Violations exit 1;--jsonfor CI and AI agents; architectures without rules are skipped with a notice. New doc topic:utakata doc show imports. - Internal deps —
-
refactor(arch):
arch_definition.yamlslimmed to structure only (clean_architecture: 589 → 320 lines). Per-layer guide entries now carry justlayer_path/title/do/dont—apply_to,detail_content_pathandnaming_patternare derived by convention, and the hand-writtenallowed_imports/forbidden_importsexample lists are gone:guide show's constraint section is now generated fromimport_rules+ placements (single source of truth; an adversarial review had found 7 contradictions between the examples and the rules). Inlinedependencies:/dev_dependencies:moved out todependencies/core_stack.yaml(which had already drifted from the inline copy). The old formats (v1internal:/external:rules, full guide entries, inline dependencies) still parse — existing ejected local definitions keep working. -
feat(apply) (#19):
applynow creates the filescheckrequires as empty files (derived from the exact sameExpectedStructure, never overwriting anything), soplan.yamldeterministically controls file existence, not just naming.--dry-runlists the would-be-created files; layers opted out with[]and layers with non-deterministic naming are untouched. -
feat(plan) (#16):
plan expandwrites full filenames with extension (todo_entity.dartinstead oftodo) intolayers:, sharing the same name derivation ascheck/apply— the plan is now WYSIWYG-editable. Deterministic fixed-name rules are expanded too. Bare item names remain valid when written by hand. -
fix(vault) (#18): a relative
vault.pathnow resolves against the config file that declares it — projectutakata.yaml→ project root,~/.utakata/config.yaml→~/.utakata/— instead of the process working directory (which made behavior depend on where you ran the command from). Absolute paths and~expansion are unchanged.
1.4.0 #
- feat(templates) (#15): The package now bundles only what commands need at runtime —
arch_definition.yaml+skills/per architecture (44KB, down from 628KB). Reading material (layer guides, principles, dependency notes) is fetched on demand from the official utakata_arch_lib at a version-pinned tag, cached under~/.utakata/cache/(one fetch, then silent). Structural commands (create/apply/check/feature add) never touch the network; only guide reads do, and when offline they degrade gracefully: a clear stderr notice plus the summary embedded inarch_definition.yaml(do/don't lists, naming rules) instead of the full guide body.utakata arch getwith noknowledge_repoconfigured now pre-warms this cache (useful before going offline). - feat(apply) (#13):
apply/feature addno longer write per-directory GUIDE.md files intolib/features/— the last hold-out against the reference-only knowledge principle. Guides are read viaguide show/guide for <file>/ MCPguide_get. Existing GUIDE.md files are left untouched (they may be hand-edited);utakata doctorreports how many remain and notes they are safe to delete if unmodified. - fix(i18n): 18 command/subcommand descriptions (
claude,skills,vault,doc show/list,plan expand/add/remove,guide for,arch get,agree correct/reflect,log import) and their flag help texts were hardcoded in Japanese and leaked into English--helpoutput; all now go throughCliMessages. Three stale descriptions that referenced deleted files/commands (plan→ feature_request.yaml,diff→ plan_architecture.yaml,feature→ bulk-generate) were rewritten.
1.3.0 #
- feat(vault): New
vault:config — a reference to a personal knowledge repo of client-facing know-how (how to obtain an Apple Developer account, what Firebase costs, whether a LINE channel needs review). Distinct fromknowledge_repo, which holds architecture knowledge.path(a local clone) takes precedence overurl, because a vault is something you keep writing yourself and round-tripping through push/fetch on every edit is impractical;urlsupports private repos via your existing git auth. - feat(config): New global config
~/.utakata/config.yaml, same schema as a project'sutakata.yaml. A vault spans all client projects, so it belongs there; a project'sutakata.yamlstill overrides it. - feat(vault): New
utakata vault list|show|get, plus MCP toolsvault_list/vault_get. Root-levelREADME.md/CLAUDE.md/_*.mdare treated as repo scaffolding and hidden from the listing, while nestedREADME.mdfiles (e.g.Google/GCP/README.mdholding shared prerequisites) are real entries. Reads are confined to the vault root. - feat(claude): New generated skill
utakata-client-explainer— writes client-facing explanations from the vault instead of from memory, checks each entry's recorded verification date before quoting prices or review requirements, never writes to the vault, and leaves sending and logging (log add,agree add) to the human.
1.2.0 #
- docs: New
doc/reference for the two config files —doc/plan-yaml.md(doc/specs/plan.yaml: features, entities, per-layerlayers:declarations, and how item names map to filenames) anddoc/utakata-yaml.md(utakata.yaml: architecture resolution order,knowledge_repo,skillssync rules,team). Keys that are parsed but not yet wired to behavior (enforcement.impl_plan,records.git,lang,baseline) are documented as reserved rather than claimed as working. - feat(doc): New
utakata doc show <config|plan|index>andutakata doc list— the bundled reference is readable from inside any project, so it always matches the installed version. Also exposed as the MCPdoc_gettool, and referenced from the generatedutakata-structureskill andCLAUDE.md("don't guess the YAML — runutakata doc show plan").
1.1.0 #
- feat(plan) (#12):
plan.yamlfeatures gain an optionallayers:map, so declaring a feature no longer means every layer is planned. Keyed by architecture layer path (architecture-agnostic):- key omitted — unchanged behavior: derive the expected files from
entities(auto-generation stays the baseline) - list of items — only those files are required, even in layers whose naming is free-form (e.g.
1_domain/3_usecases: [get_todo, save_todo]requiresget_todo_usecase.dart/save_todo_usecase.dart). An item ending in.dartis taken as a literal filename - empty list
[]— that layer is not applicable: it is neither required nor generated, and a parent path opts out its whole subtree (e.g.4_presentation/1_widgets: [])
- key omitted — unchanged behavior: derive the expected files from
- feat(plan): New
utakata plan expand [--dry-run] [--feature <name>]— materializes the auto-derived per-layer lists intoplan.yaml(block style, comments preserved) so they can be edited by hand. Layers whose naming is non-deterministic are deliberately left out rather than written as[], since an empty list means "not applicable"; add those withplan add. Already-declared layers are never overwritten. - feat(plan): New
utakata plan add <feature> <layer> <item...>andutakata plan remove <feature> <layer> <item>— format-preserving per-item editing for AI agents and scripts. - feat(apply):
applyskips layers declared as not applicable instead of recreating their directories.
1.0.2 #
- fix(doc) (#14):
utakata doc initnow generatesdoc/specs/plan.yaml. Previously it created an emptydoc/specs/directory, socheck/applyfailed with "plan.yaml not found" immediately after init — the documented quick-start flow did not work.doc initis now file-wise idempotent: it fills in whatever is missing (including a deletedplan.yamlin an already-initialized project) and never overwrites existing files. - fix(arch) (#11):
guide list/show/ejectignoredproject.architectureinutakata.yamland always usedclean_architecture, so an MVVM project got Clean Architecture guides. Architecture resolution is now centralized in a singleArchitectureResolver(explicit--arch→utakata.yaml→plan.yaml→clean_architecture) and applied consistently toguide list/show/eject,feature add --arch, and the MCPguide_gettool (which had the same defect while its siblingguide_for_fileresolved correctly).
1.0.1 #
- feat(claude): New
utakata claude init [--force]— adds or repairs the Claude Code integration (.claude/skills+agent+settings,.mcp.json,CLAUDE.md) in an existing project, so it's no longer only available atcreatetime. Default mode writes missing files only (existing files, including user-edited skills, are untouched);--forceregenerates everything includingCLAUDE.md. - fix(skills):
doc init's commentedskills:example suggestedutakata-structure, which is a create-generated generic skill, not an architecture skill — following the example madeskills syncreport not-found. The example now shows a real architecture skill id, and the not-found warning lists the architecture's actually-available skill ids.
1.0.0 #
First public release. utakata is now a project orchestrator for client + developer + AI-agent collaboration on Flutter apps: a master config (utakata.yaml) with team roles, an intent-level plan (doc/specs/plan.yaml), one-pass structural checking, human-write-only client records with agreement tracking, reference-only knowledge synced from utakata_arch_lib (optionally overridden per-project and SHA-pinned via utakata.lock), and first-class Claude Code integration (hooks, managed skills, CLAUDE.md, and a read-only MCP server). The 0.6.0–0.17.0 entries below are the unreleased development milestones that make up this release.
0.17.0 #
- feat(log): New
utakata log import claude-session [--list|--last|--session <id>] [--full] [-y]— human-driven import of Claude Code session transcripts intodoc/records/sessions/<date>_<id>.jsonl(normalized{ts, role, text, session, seq}schema) with a Markdown preview underdoc/preview/sessions/. Defaults keep only user/assistant text (thinking, tool calls, and subagent sidechains excluded;--fulladds thinking and tool names, never tool results). Secret-looking content (API keys, bearer tokens, private keys, AWS keys, env assignments) is replaced with[REDACTED]and counted, and an interactive preview/confirmation guards every import. The AI-side deny rules ondoc/records/**continue to apply — importing is a human action.
0.16.0 #
- feat(guide): New
utakata guide for <file> [--json]— deterministically resolves the layer guide for a file path underlib/features/(permission and direct layouts, deepest guide wins). Intended as fix-context for lint errors: pass the reported file, get the guide to follow. - feat(mcp): Two new read-only tools —
guide_for_file(same resolution over MCP) andconfig_get(returnsutakata.yamlincludingteam, so an agent can learn who decides what without reading files).
0.15.0 #
- feat(skills): New
utakata skills sync [--force]— syncs the architecture's bundled SKILLs listed underskills:inutakata.yamlinto.claude/skills/, with a managed marker (<!-- utakata:managed from=<arch>/<id> hash=... -->). Conflict rules: files without the marker (human-created) are never touched, even with--force; unmodified managed files are updated in place; human-edited managed files are skipped unless--force. Delisted managed skills are reported as removal candidates but never auto-deleted.
0.14.0 #
- feat(arch): New
utakata arch get [--update]— fetches the opt-inproject.knowledge_repodeclared inutakata.yaml(git, depth-1) into~/.utakata/cache/knowledge/, materializes it into the bundled-template layout, and pins the resolved commit SHA inutakata.lock. Idempotent while the lock and cache are valid;--updatere-resolves the ref and reports the SHA change. - feat(resolution): Template/guide/architecture resolution now goes local override → locked remote cache (only when
knowledge_repois configured) → bundled templates. Projects withoutknowledge_repobehave exactly as before, fully offline.arch listmerges bundled and remote-cached architectures (remote wins on id conflict).
0.13.0 #
- refactor(templates): Bundled templates are now synced from utakata_arch_lib via
tool/sync_arch_lib.dart(single source of truth). New bundle layout:architectures/<id>/{arch_definition.yaml, principles/, layers/, dependencies/, skills/}— the legacyAI/and.agent/trees are gone. - refactor(create): Generated projects no longer receive a copy of the knowledge tree (
AI/). Knowledge is reference-only:utakata guide show/ejectand the MCPguide_gettool resolve it from the bundle (or, later, a fetched knowledge repo). Projects now consist of the Flutter app +doc/+utakata.yaml+.claude/+CLAUDE.mdonly. - chore(templates):
.tmplfiles are abolished.feature add/applyscaffold directories and dynamically generated GUIDE.md fromarch_definition.yaml; local.tmploverrides in a project'sAI/architecture/features/still work. The last bundled script (build_native_ios.sh) is no longer shipped.
0.12.0 #
- feat(config):
utakata.yamlis now the project's master config (schema: 1), parsed by every command. New optional sections:project.knowledge_repo(opt-in remote knowledge repo, used from 0.14.0),skills(list synced by the upcomingskills sync), andteam(client/developer/ai_agents roles). - feat(config):
project.architectureinutakata.yamlnow takes precedence overdoc/specs/plan.yaml; a stderr warning is printed when both are explicitly set and disagree. - feat(claude):
utakata createnow also generates a project-levelCLAUDE.md— with a "who decides what" team-roles section whenteam:is defined — pointing the agent atdoc/summary.md,doc/specs/plan.yaml, and the read-onlydoc/records/. An existingCLAUDE.mdis never overwritten. - feat(doctor):
utakata doctorvalidatesutakata.yaml(unknown top-level keys, unsupported futureschema). - feat(doc):
utakata doc initwrites the new master-config template with commentedteam:/skills:/knowledge_repo:examples.
0.11.0 #
- feat(mcp): New
utakata mcp— stateless stdio JSON-RPC 2.0 MCP server (hand-rolled, no external SDK dependency). Exposes 6 read-only tools:structure_get,check_run,plan_get,log_query,agreements_query,guide_get. No write tools are exposed (AI stays read-only for records; see 0.8.0). - chore: Removed the deprecated
scan,validate,feature init,corecommands and their aliases.diffremains as a permanent alias forcheck(kept for compatibility with existing implementation-plan documents that reference "utakata diff"). - chore(templates): Stopped bundling
.agent/and the deprecatedAI/scripts/*.sh(superseded by CLI commands since 0.5.x) in generated projects;AI/scripts/build/build_native_ios.shis kept as it has no CLI equivalent.
0.10.0 #
- feat(guide): New
utakata guide list/show/eject— browse an architecture's layer guides and copy one locally to start customizing (single-file copy with an origin comment; no hash/manifest tracking). - feat(arch):
arch createrenamed toarch eject;arch createkept as a deprecated alias. - feat(claude):
utakata createnow also generates.mcp.jsonand.claude/(settings.json with SessionStart/PostToolUse/Stop hooks and deny rules fordoc/records/**, two skills, one agent). - feat(feature): New
feature add <name> --template <id>— applies a feature preset (permission + entities) from amanifest.yaml, resolved from the project or~/.utakata/feature_templates/. No preset content (auth/payment/etc.) ships yet — the mechanism only.
0.9.0 #
- feat(agree): New
agree add/status/correct/reflect/list— append-only agreement tracking (doc/records/agreements.jsonl). Corrections create a new entry and mark the originalsupersededrather than rewriting it. - feat(impl): New
impl new/list/done/archive— feature implementation plan lifecycle (doc/impl/PLAN-NNNN_{feature}.md, frontmatter-only machine state, free-form Markdown body). - feat(summary): New
utakata summary— regenerates the<!-- utakata:begin agreements -->marker section ofdoc/summary.mdfrom the agreement ledger (title/items/status/amount/sources, and a total for agreed client amounts), leaving hand-written sections untouched.
0.8.0 #
- feat(log): New
utakata log add/show/render— structured client conversation log (doc/records/log/YYYY-MM.jsonl, append-only, human-write-only).log renderregenerates a per-day Markdown preview with ID anchors. - feat(doc): New
utakata doc init— creates thedoc/workspace (specs/records/preview/impl/knowledge/archive) +utakata.yamlahead ofcreate, for the pre-contract phase. - feat(doctor): New
utakata doctor [--migrate]— diagnoses the project and migrates the legacyAI/-based layout (and a real project's ad-hocdoc/layout) to the new one. Dry-run by default with a confirmation prompt.
0.7.0 #
- refactor(check): New canonical structure model (
StructurePath/StructureNode/ExpectedStructure/CheckReport) replaces the separatediff/validatescans.NameRuleMatcherresolves naming rules by path-segment suffix instead of substring.contains(), fixing a real bug where a parent directory's naming rule leaked into its ownexceptions/subdirectory. Directories where a naming rule can't produce a deterministic filename (e.g.3_usecases/) now allow any file matching the rule's regex instead of always flagging it as extra. - feat(plan): New intent-level
doc/specs/plan.yaml(schema: 1, supports multipleentitiesper feature) replaces the generatedplan_architecture.yaml. Falls back read-only to the legacyAI/specs/feature_request.yamlifplan.yamldoesn't exist yet. - feat(check):
checknow supports--jsonand--file <path>. - feat(apply): New
apply [--scope all|feature|core] [--dry-run]consolidatesfeature init+coreon the same expected-structure modelcheckuses. - feat(plan): New
plan adoptdetects features present inlib/features/but missing fromplan.yamland appends them (format-preserving, viapackage:yaml_edit) after confirmation. - chore:
scan,diff,validate,feature init,corebecome deprecated aliases delegating tocheck/apply(still functional, print a warning).
0.6.0 #
- fix: Removed all silent
catch (_)blocks in favor of typed exception handling;getAll()now warns to stderr on broken architecture definitions instead of silently skipping them. - fix:
YamlDataSource.parse()now throws on malformed YAML instead of returningnull(previously conflated "missing" and "malformed"). - perf:
flutterexecutable resolution is now lazy (on first use) instead of at startup, so commands that don't needflutter(plan,check,status --brief, ...) no longer fail when it's not onPATH. - fix(status):
flutter analyzeis now scoped tolib/andtest/(previously the whole project, including noise frombuild/). - refactor: Unified four divergent, disagreeing
_toSnakeCase/_toPascalCase/_toCamelCaseimplementations into a singleCaseConverterservice. - chore:
lib/src/version.g.dartis now generated frompubspec.yaml(tool/generate_version.dart) instead of hardcoded incommand_runner.dart. - chore: Removed the unused
iopackage dependency and four exception classes that were never thrown.
0.5.8 #
- fix(diff): Flattened
directpermission group inplanFeaturesto align with the actual physical file structure inlib/features/which does not nest direct features under adirectfolder.
0.5.7 #
- fix(version): Fixed hardcoded version display in
utakata --version— now correctly shows the current version - feat(status):
utakata statusnow also generatesAI/snapshots/preview/project_status.mdMarkdown preview - docs: Added English
README.md, renamed original toREADME_ja.md
0.5.6 #
- feat(status):
utakata statusnow also generatesAI/snapshots/preview/project_status.md— a human-readable Markdown preview of the project status with ✅/❌ icons, tables, and feature count
0.5.5 #
- feat(core): New
utakata corecommand — generates Core directory structure dynamically fromarch_definition.yamlcore_modules(replaces hardcodedgenerate_core.sh) - feat(core):
--archoption to specify architecture (auto-detects fromfeature_request.yamlif omitted) - feat(status):
utakata statusnow scans the project and writes real-time data toAI/snapshots/project_status.yaml— tracksproject.name/version,flutter,coremodules,entry_points,documents, andfeatures.count - refactor(status): Core modules in
project_status.yamlare now dynamically generated fromarch_definition.yamlinstead of hardcoded - chore(template): Removed unused legacy files
actual_architecture.yaml,change_history.yamland their previews from bothclean_architectureandmvvmtemplates
0.5.4 #
- fix(diff): Fixed root key mismatch between
plan_architecture.yaml(hasfeatures:root) andscanFeaturesStructure(returns contents directly) —utakata diff/utakata checkwere falsely reportingfeaturesas Missing and permission folders as Extra - fix(validate): Applied the same root key extraction fix to
utakata validatedirectory structure comparison
0.5.3 #
- feat(template/mvvm): Expanded MVVM (3-layer) architecture template to match
clean_architecturecompleteness — added GUIDE.md for all 8 layer directories (1_model/{entities,repositories,services,exceptions},2_viewmodel/{states,notifiers},3_view/{widgets,screens}) - feat(template/mvvm): Added full architecture guides (
guides/README.md,arch_summary.md,directory_structure_and_naming_rules.md,common/collaboration.md,dependencies/core_stack.yaml+.md) - feat(template/mvvm): Added Core layer guides (
core/core_architecture.md,routing/,theme/,di/,api/) with MVVM-specific DI guidance - feat(template/mvvm): Added
entry_point_guide.mdformain.dart/app.dartsetup - feat(template/mvvm): Added
AI/specs/templates (feature_request.yaml,structure_plan.md,application_specification.md) matching clean_architecture format - feat(template/mvvm): Copied
AI/scripts/,AI/snapshots/,AI/logs/from clean_architecture - feat(template/mvvm): Added
.agent/directory with rules, skills, workflows — all content adapted for MVVM (3-layer Model→ViewModel→View ordering, DI incore/di/, Service instead of UseCase, Screen instead of Page) - refactor(template/mvvm): Enriched
arch_definition.yamlguides section withapply_to,detail_content_path,do_list,dont_list,allowed_imports,forbidden_importsfor all 9 layer guides
0.5.2 #
- feat(verify): Switched verification commands (
utakata diff,utakata check,utakata validate,utakata status) to use real-time directory scanning instead of reading saved snapshot files. They now scan disk changes dynamically and auto-updatecurrent_structure.yamlin the background (no longer requiring manualutakata scanbefore diff/check). - refactor(plan): Reverted plan architecture structure back to nested
features.{permission}.{featureName}format to completely align with physical folder structure, resolving false validation errors when permission folders are present.
0.5.1 #
- fix(plan): Corrected
feature_request.yamltemplate file in clean_architecture. Changedfeaturesdefault from[](List) to{}(Map) and updated the commented example to Map format to align withutakata planparser expectations (was failing withplanMissingFeaturesKeyexception). - feat(feature): Skip placeholder
.dartfiles generation duringutakata feature addandutakata feature init. Now only architecture directory structure andGUIDE.mdfiles are generated, avoiding template boilerplates.
0.5.0 #
- feat(multi-arch):
utakata plannow dynamically generates architecture plans fromarch_definition.yaml— no longer hardcoded to Clean Architecture - feat(multi-arch): Added
architecturefield tofeature_request.yaml(project.architecturefor project default, per-feature override also supported) - feat(template): Added MVVM (3-layer) as a built-in architecture template (
1_model/2_viewmodel/3_view) - feat(diff):
utakata diffnow compares file names (__files__) when present inplan_architecture.yaml, enabling file-level progress tracking - feat(validate):
utakata validateauto-detectsarchitectureIdfromfeature_request.yaml(--archflag still available for override) - fix(validate): Exclude
.freezed.dart/.g.dartgenerated files from naming rule validation - fix(validate): Skip
exceptions/subdirectories from parent naming rule matching (was causing false positives) - fix(validate): Skip
__files__key in directory structure comparison (was reporting 67+ false Extra violations) - fix(diff): Smart
__files__comparison — only compare file names when plan explicitly defines them; ignore extra files not in plan - refactor(plan): Flat output format (
features.{name}) instead of permission-grouped (features.{perm}.{name}) - refactor(init):
feature initreadspermissionandarchitectureIdfromfeature_request.yamlinstead of plan structure - fix(naming): Relaxed
1_localdata source pattern from_local_data_source.dartto_data_source.dart(directory already implies locality) - fix(naming):
{feature}placeholder inarch_definition.yamldescriptionfor application/presentation layer files (state, providers, notifiers, pages)
0.4.0 #
- feat(template): Restructured
AI/directory — introducedAI/architecture/to consolidate all architecture-specific resources (guides, features, core, arch_definition.yaml) - feat(template): Unified GUIDE.md and
.tmpltemplates — each layer directory now contains both the implementation guide and code template side by side - feat(template): Moved
arch_definition.yamlandfeatures/intoAI/architecture/for cleaner separation of architecture-dependent vs generic resources - feat(create): Use
flutter create --emptyfor clean project generation without boilerplate comments - refactor(template): Flattened
guides/architectures/clean_architecture/→architecture/guides/to eliminate redundant nesting - chore: Cleared legacy
change_history.yamltemplate data
0.3.5 #
- fix: Added missing
.agent/andAI/template files tolib/src/templates/architectures/clean_architecture/so they correctly generate in new projects. - fix: Fixed the success message of
utakata createcommand.
0.3.4 #
- fix: Fixed
ArchitectureNotFoundExceptionwhen running from a global pub activation. Switched toIsolate.resolvePackageUrifor robust template path resolution instead of relying onPlatform.scriptwhich varies between Dart versions.
0.3.3 #
- feat(ux): Replaced the CLI brand header with a high-quality 3D ASCII art logo (ANSI Shadow font) for better cross-terminal rendering without distortions.
0.3.2 #
- fix: Resolve correct package template path when installed via
dart pub global activate(was failing withArchitectureNotFoundExceptiondue tosnapshots/directory inPlatform.script)
0.3.1 #
- feat(ux): Display
utakata codebrand header (ASCII art, bright cyan) on startup when no command is specified
0.3.0 #
- breaking: Rebranded from
utakata(v0.2.0) to theutakatapackage under the utakata code brand - feat: Architecture-agnostic design — no longer hardcoded to Clean Architecture; architecture is defined by
arch_definition.yaml - feat(validate): New
utakata validatecommand — detects naming rule violations and directory structure violations based onarch_definition.yaml - feat(validate): Naming rules defined per-layer in
arch_definition.yaml(naming_rules:section) - feat:
arch_definition.yamlnow supportsguides_path:field — directs users to the correct documentation on violation - feat(create): Generated projects now include
.agent/andAI/guides/architectures/with architecture-specific guides - feat(i18n): Full internationalization — all CLI messages support English and Japanese via
MessagesResolver - refactor: Monorepo structure — CLI moved to
packages/utakata_code/under theutakatarepository - docs: README rewritten in English;
README_ja.mdadded for Japanese documentation
0.2.0 #
- refactor: Extract common YAML utilities (
YamlUtils) — eliminates duplicated_toYaml/_yamlToMdlogic acrosssnapshotandplancommands - refactor: Extract
StringUtils.toPascalCase()— removes duplicate implementations ingenerateandfeaturecommands - refactor: Add
ProjectPathsconstants class — centralizes all hardcoded path strings (AI/specs/,AI/snapshots/,lib/features/) in one place - refactor: Introduce
BaseCommandbase class — unifies error handling and blank-line output across all commands - fix(status): Replace fragile self-process re-execution (
Platform.script) with directDiffCommand.checkDiff()API call - refactor(feature): Split
FeatureGenerator(393 lines) into per-layer generators (DomainLayerGenerator,InfrastructureLayerGenerator,ApplicationLayerGenerator,PresentationLayerGenerator) - refactor: Replace
uri.pathSegmentspath extraction withp.basename()for safety and consistency - rename:
snapshot→scan— clearer intent for scanning the current directory structure - rename:
generate→sync— better describes propagating Entity changes to each layer - rename:
validate→check— shorter and more intuitive
0.1.4 #
- feat: Add
utakata feature initsubcommand — bulk-generates all features defined inAI/specs/plan_architecture.yamlat once - feat: Support
--dry-runflag forfeature initto preview targets without writing files
0.1.3 #
- fix(windows): Add
runInShell: trueto allProcess.run/Process.startcalls to support Windows whereflutterisflutter.bat
0.1.2 #
- fix: Replace LICENSE file with the full GNU GPL v3 text for proper pub.dev recognition
- fix: Change pubspec.yaml description to English to comply with pub.dev scoring
- docs: Rewrite README.md in English; add README_ja.md for Japanese documentation
- feat: Add
example/main.dartfor pub.dev example score
0.1.1 #
- fix: Change
feature_request.yamltemplate from List format to Map format (fixes parse error inplancommand) - feat: Add optional Core layer configuration items as Map-format templates (all commented out by default)
0.1.0 #
- feat: Migrate all major features to a Dart-based CLI (
utakata) - feat(create): Initialize Flutter projects with incremental dependency setup and Core package scaffolding
- feat(feature add): Generate 4-layer directory structure and files based on Permission / Entity / Feature configuration
- feat(generate): Auto-regenerate Domain / Infrastructure layer code from Freezed (v3) Entity field changes
- feat(plan & snapshot & diff): Define ideal architecture from
feature_request.yamland detect/verify diff against the actual project structure - feat(validate & status): Add directory structure health checks and project analysis reporting
- feat(AI Tooling): Output workflow and guideline templates enabling AI agents to develop without architectural drift