feat: deterministic full-namespace TypeScript layout with self-cleaning incremental builds - #237
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a deterministic and self-cleaning TypeScript output layout (ADR-0025), where generated files are mapped to their full kebab-cased C# namespaces to ensure path stability, and incremental builds automatically prune orphaned files and empty directories. The review feedback is highly valuable, pointing out a potential NullReferenceException when reading older cache files that lack the 'OutputHashes' property, as well as robustness and platform-specific path comparison issues in the empty directory pruning logic.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Pull request overview
This PR changes Metano’s TypeScript target to emit files at deterministic, full-namespace paths (no common-prefix stripping), updates internal import semantics to always reference defining files directly (never namespace barrels), and adds self-cleaning incremental builds that prune orphaned generated outputs based on the cache manifest.
Changes:
- Switch TS output layout to full C# namespace → nested kebab-case folders; add a layout fingerprint token (
layout=full-namespace-v1) to invalidate stale caches. - Update internal generated-to-generated imports to target files directly (
./filesame-ns,#/full/ns/filecross-ns), decoupling correctness from barrel emission and avoiding ESM cycles. - Update tests, docs/ADR/specs, and all JS sample targets to match the new layout + import contracts (including
package.json#exportssubpaths).
Reviewed changes
Copilot reviewed 169 out of 247 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Metano.Tests/UsingAliasImportTests.cs | Updates expected TS output paths under app/… for full-namespace layout. |
| tests/Metano.Tests/TypeGuardTranspileTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/ThrowExpressionTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/TargetSpecificNamingTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/SwitchPatternTranspileTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/StaticExtensionMemberTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/PrimaryCtorParamCoverageTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/PrimaryConstructorCaptureTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/ParamsParameterTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/OutputLayoutTests.cs | Adds tests pinning full-namespace output layout + leaf-barrel behavior. |
| tests/Metano.Tests/NullConditionalInvokeTests.cs | Updates expected generated file locations under app/app.ts. |
| tests/Metano.Tests/NullableTranspileTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/NamespaceBarrelsTranspileTests.cs | Updates namespace-barrel assertions to reflect full-namespace layout and new aggregation shape. |
| tests/Metano.Tests/NamedArgumentReorderTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/ModuleEntryPointTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/MethodOverloadTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/LambdaTranspileTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/JsonSerializerContextTests.cs | Updates expected generated file locations under test-app/…. |
| tests/Metano.Tests/InternalMemberEmissionTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/InterfaceTranspileTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/InterfaceInheritanceTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/InheritanceTranspileTests.cs | Updates expected generated file locations and import expectations for full-namespace layout. |
| tests/Metano.Tests/ImportContractTests.cs | Adds tests pinning the internal direct-file import contract. |
| tests/Metano.Tests/ImportAliasTests.cs | Updates relative import path expectations to reference defining files (not barrels). |
| tests/Metano.Tests/GenericTranspileTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/Frontend/CSharpSourceFrontendTests.cs | Updates frontend expectations: LocalRootNamespace now empty under full-namespace layout. |
| tests/Metano.Tests/ForEachTranspileTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/ExternalMappingTranspileTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/ExtensionPropertySetterTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/ExtensionCallSiteTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/ExceptionTranspileTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/EndToEndOutputTests.cs | Updates pinned output and cross-package import paths to new full-namespace barrel paths. |
| tests/Metano.Tests/DeterministicLayoutScenarioTests.cs | Adds scenario tests reproducing the reported stale/orphan + unstable-layout issue. |
| tests/Metano.Tests/DelegateTypeAliasTests.cs | Updates expected generated file locations and cross-package import paths. |
| tests/Metano.Tests/DelegateEventTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/DefaultParameterValueTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/CtorFieldEmissionTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/CrossPackageImportTests.cs | Updates cross-package import expectations to include full-namespace leaf-barrel subpaths. |
| tests/Metano.Tests/ConstructorOverloadTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/ClassInheritanceTests.cs | Updates expected generated file locations under app/…. |
| tests/Metano.Tests/AssemblyTranspileTests.cs | Updates expected generated file locations under app/…. |
| targets/js/sample-todo/test/todo-list.test.ts | Updates #/… imports to include the sample’s full-namespace subpath. |
| targets/js/sample-todo/src/sample-todo/todo-list.ts | Adds/updates generated sample code under full-namespace directory layout. |
| targets/js/sample-todo/src/sample-todo/todo-item.ts | Adds/updates generated sample code under full-namespace directory layout. |
| targets/js/sample-todo/src/sample-todo/priority.ts | Adds/updates generated sample code under full-namespace directory layout. |
| targets/js/sample-todo/src/sample-todo/json-context.ts | Adds/updates generated sample code under full-namespace directory layout. |
| targets/js/sample-todo/src/sample-todo/index.ts | Adds leaf barrel for the sample’s namespace directory. |
| targets/js/sample-todo/package.json | Updates exports to a namespaced subpath (./sample-todo). |
| targets/js/sample-todo-service/test/routes.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-todo-service/test/json-context.test.ts | Updates imports to match new exports subpath and full-namespace paths. |
| targets/js/sample-todo-service/test/guards.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-todo-service/test/events.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-todo-service/src/sample-todo/service/todos.ts | Updates cross-package import to new sample-todo/sample-todo subpath export. |
| targets/js/sample-todo-service/src/sample-todo/service/json-context.ts | Updates cross-package import to new sample-todo/sample-todo subpath export. |
| targets/js/sample-todo-service/src/sample-todo/service/index.ts | Adds leaf barrel for the service namespace directory. |
| targets/js/sample-todo-service/src/sample-todo/service/events.ts | Adds/updates generated event types + guards under full-namespace layout. |
| targets/js/sample-todo-service/src/program.ts | Updates internal import path to full-namespace subpath. |
| targets/js/sample-solid-ui/test/components.test.ts | Updates test imports to match full-namespace directory layout. |
| targets/js/sample-solid-ui/src/sample-solid-ui/ui/index.ts | Adds leaf barrel for UI namespace directory. |
| targets/js/sample-solid-ui/src/sample-solid-ui/ui/counter.tsx | Adds/updates generated component under full-namespace layout. |
| targets/js/sample-solid-ui/src/sample-solid-ui/ui/counter-list.tsx | Adds/updates generated component under full-namespace layout. |
| targets/js/sample-solid-ui/src/sample-solid-ui/ui/counter-group.tsx | Adds/updates generated component under full-namespace layout. |
| targets/js/sample-solid-ui/src/program.tsx | Updates internal import path to full-namespace subpath. |
| targets/js/sample-queryable-sqlite/test/product-demo.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-queryable-sqlite/src/sample-queryable-sqlite/provider/sqlite-translator.ts | Extends translator param-name scanning for new ExprTree kinds and errors for unsupported kinds. |
| targets/js/sample-queryable-sqlite/src/sample-queryable-sqlite/provider/schema.sql | Adds sample schema asset under the sample namespace directory. |
| targets/js/sample-queryable-sqlite/src/sample-queryable-sqlite/provider/product-demo.ts | Updates internal type import to full-namespace path. |
| targets/js/sample-queryable-sqlite/src/sample-queryable-sqlite/provider/index.ts | Adds provider leaf barrel under full-namespace layout. |
| targets/js/sample-queryable-sqlite/src/sample-queryable-sqlite/provider/i-product-repository.ts | Updates internal type import to full-namespace path. |
| targets/js/sample-queryable-sqlite/src/sample-queryable-sqlite/provider/db.ts | Updates internal type import to full-namespace path. |
| targets/js/sample-queryable-sqlite/src/sample-queryable-sqlite/provider/bun-sqlite-product-repository.ts | Updates internal imports to full-namespace paths. |
| targets/js/sample-queryable-sqlite/src/sample-queryable-sqlite/product.ts | Adds/updates generated product model under full-namespace layout. |
| targets/js/sample-queryable-sqlite/src/sample-queryable-sqlite/main.ts | Updates internal imports to full-namespace paths. |
| targets/js/sample-queryable-sqlite/src/sample-queryable-sqlite/index.ts | Adds sample leaf barrel under full-namespace layout. |
| targets/js/sample-queryable-sqlite/package.json | Updates main/start/exports to full-namespace subpaths. |
| targets/js/sample-queryable-arrays/test/array-provider.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-queryable-arrays/src/sample-queryable-arrays/user.ts | Adds/updates generated model under full-namespace layout. |
| targets/js/sample-queryable-arrays/src/sample-queryable-arrays/user-queries.ts | Adds/updates generated query helpers under full-namespace layout. |
| targets/js/sample-queryable-arrays/src/sample-queryable-arrays/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-queryable-arrays/package.json | Updates exports to a namespaced subpath (./sample-queryable-arrays). |
| targets/js/sample-operator-overloading/test/money.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-operator-overloading/src/sample-operator-overloading/no-same-money-currency-exception.ts | Adds/updates generated exception under full-namespace layout. |
| targets/js/sample-operator-overloading/src/sample-operator-overloading/money.ts | Adds/updates generated model under full-namespace layout. |
| targets/js/sample-operator-overloading/src/sample-operator-overloading/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-operator-overloading/src/sample-operator-overloading/currency.ts | Adds/updates generated enum under full-namespace layout. |
| targets/js/sample-operator-overloading/src/program.ts | Updates internal imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/shared-kernel/user-id.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/shared-kernel/page-result.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/shared-kernel/page-request.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/shared-kernel/operation-result.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/planning/domain/sprint.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/namespace-barrels.test.ts | Updates root aggregation barrel usage to the new root namespace tree shape. |
| targets/js/sample-issue-tracker/test/json-context.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/issues/domain/issue.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/issues/domain/issue-workflow.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/issues/domain/issue-workflow-matrix.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/issues/domain/issue-status.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/issues/domain/issue-mutations.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/issues/domain/issue-id.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/issues/domain/comment.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/issues/application/issue-service.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/issues/application/issue-service-workflows.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/issues/application/issue-queries.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/issues/application/issue-queries-edges.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/issues/application/in-memory-issue-repository.test.ts | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/test/helpers.ts | Updates helper imports to full-namespace subpaths. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/shared-kernel/user-id.ts | Adds/updates generated types under full-namespace layout. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/shared-kernel/page-result.ts | Adds/updates generated types under full-namespace layout. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/shared-kernel/page-request.ts | Adds/updates generated types under full-namespace layout. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/shared-kernel/operation-result.ts | Adds/updates generated types under full-namespace layout. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/shared-kernel/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/planning/domain/sprint.ts | Updates internal imports to full-namespace paths. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/planning/domain/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/json-context.ts | Updates internal imports to full-namespace paths. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/domain/issue.ts | Updates internal imports to full-namespace paths. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/domain/issue-workflow.ts | Adds/updates generated type under full-namespace layout. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/domain/issue-type.ts | Adds/updates generated type under full-namespace layout. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/domain/issue-status.ts | Adds/updates generated type under full-namespace layout. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/domain/issue-snapshot.ts | Updates internal imports to full-namespace paths. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/domain/issue-priority.ts | Adds/updates generated type under full-namespace layout. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/domain/issue-id.ts | Adds/updates generated type under full-namespace layout. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/domain/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/domain/comment.ts | Updates internal imports to full-namespace paths. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/application/issue-service.ts | Updates imports to direct-file full-namespace paths. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/application/issue-queries.ts | Updates imports to direct-file full-namespace paths. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/application/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/application/in-memory-issue-repository.ts | Updates imports to direct-file full-namespace paths. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/issues/application/i-issue-repository.ts | Relocates interface under full-namespace layout and updates imports accordingly. |
| targets/js/sample-issue-tracker/src/sample-issue-tracker/index.ts | Adds sample leaf barrel under full-namespace layout. |
| targets/js/sample-issue-tracker/src/issues/application/i-issue-repository.ts | Removes legacy pre-full-namespace path. |
| targets/js/sample-issue-tracker/src/index.ts | Updates root aggregation barrel to mirror full namespace rooted at package namespace. |
| targets/js/sample-issue-tracker/package.json | Updates exports to include full-namespace subpaths while retaining root barrel. |
| targets/js/sample-counter-v5/src/views/app-view.tsx | Updates #/… imports to full-namespace subpaths. |
| targets/js/sample-counter-v5/src/sample-counter-v5/stores/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v5/src/sample-counter-v5/stores/counter-store.ts | Updates internal imports to full-namespace paths. |
| targets/js/sample-counter-v5/src/sample-counter-v5/models/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v5/src/sample-counter-v5/models/counter.ts | Adds/updates generated model under full-namespace layout. |
| targets/js/sample-counter-v5/package.json | Updates exports to full-namespace subpaths. |
| targets/js/sample-counter-v5/lib/views/app-view.jsx | Updates compiled output imports to full-namespace subpaths. |
| targets/js/sample-counter-v5/lib/sample-counter-v5/stores/index.js | Updates compiled output layout to full-namespace structure. |
| targets/js/sample-counter-v5/lib/sample-counter-v5/stores/counter-store.js | Updates compiled output imports to full-namespace subpaths. |
| targets/js/sample-counter-v5/lib/sample-counter-v5/models/index.js | Updates compiled output layout to full-namespace structure. |
| targets/js/sample-counter-v5/lib/sample-counter-v5/models/counter.js | Updates compiled output layout to full-namespace structure. |
| targets/js/sample-counter-v4/src/sample-counter-v4/mvu/ui.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v4/src/sample-counter-v4/mvu/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v4/src/sample-counter-v4/mvu/dom-props.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v4/src/sample-counter-v4/mvu/button-props.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v4/src/sample-counter-v4/models/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v4/src/sample-counter-v4/models/counter.ts | Adds/updates generated model under full-namespace layout. |
| targets/js/sample-counter-v4/src/sample-counter-v4/inferno/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v4/src/sample-counter-v4/inferno/empty-props.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v4/src/sample-counter-v4/inferno/dom-extensions.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v4/src/sample-counter-v4/components/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v4/src/sample-counter-v4/components/counter-app.ts | Updates imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v4/src/program.ts | Updates imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/mvu/ui.js | Updates compiled output for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/mvu/ui.d.ts | Updates compiled typings for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/mvu/index.js | Updates compiled output for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/mvu/index.d.ts | Updates compiled typings for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/mvu/dom-props.js | Updates compiled output for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/mvu/dom-props.d.ts | Updates compiled typings for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/mvu/button-props.js | Updates compiled output for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/mvu/button-props.d.ts | Updates compiled typings for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/models/index.js | Updates compiled output for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/models/index.d.ts | Updates compiled typings for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/models/counter.js | Updates compiled output for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/models/counter.d.ts | Updates compiled typings for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/inferno/index.js | Updates compiled output for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/inferno/index.d.ts | Updates compiled typings for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/inferno/empty-props.js | Updates compiled output for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/inferno/empty-props.d.ts | Updates compiled typings for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/inferno/dom-extensions.js | Updates compiled output for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/inferno/dom-extensions.d.ts | Updates compiled typings for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/components/index.js | Updates compiled output for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/components/index.d.ts | Updates compiled typings for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/components/counter-app.js | Updates compiled output for full-namespace layout. |
| targets/js/sample-counter-v4/lib/sample-counter-v4/components/counter-app.d.ts | Updates compiled typings for full-namespace layout. |
| targets/js/sample-counter-v4/lib/program.js | Updates compiled entrypoint imports for full-namespace layout. |
| targets/js/sample-counter-v3/src/sample-counter-v3/mvu/widgets/text.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v3/src/sample-counter-v3/mvu/widgets/row.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v3/src/sample-counter-v3/mvu/widgets/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v3/src/sample-counter-v3/mvu/widgets/heading.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v3/src/sample-counter-v3/mvu/widgets/column.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v3/src/sample-counter-v3/mvu/widgets/button.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v3/src/sample-counter-v3/mvu/widget.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v3/src/sample-counter-v3/mvu/ui.ts | Updates widget imports to direct-file paths. |
| targets/js/sample-counter-v3/src/sample-counter-v3/mvu/stateful-widget.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v3/src/sample-counter-v3/mvu/state-holder.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v3/src/sample-counter-v3/mvu/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v3/src/sample-counter-v3/mvu/build-context.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v3/src/sample-counter-v3/mvu/app.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v3/src/sample-counter-v3/models/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v3/src/sample-counter-v3/models/counter.ts | Adds/updates generated model under full-namespace layout. |
| targets/js/sample-counter-v3/src/sample-counter-v3/components/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v3/src/sample-counter-v3/components/counter-app.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v3/src/program.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v2/src/sample-counter-v2/mvu/widgets/text.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v2/src/sample-counter-v2/mvu/widgets/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v2/src/sample-counter-v2/mvu/widgets/column.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v2/src/sample-counter-v2/mvu/widgets/button.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v2/src/sample-counter-v2/mvu/view-fn.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v2/src/sample-counter-v2/mvu/state-holder.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v2/src/sample-counter-v2/mvu/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v2/src/sample-counter-v2/mvu/i-widget.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v2/src/sample-counter-v2/mvu/app.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v2/src/sample-counter-v2/models/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v2/src/sample-counter-v2/models/counter.ts | Adds/updates generated model under full-namespace layout. |
| targets/js/sample-counter-v2/src/program.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v1/src/sample-counter-v1/views/renderer.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v1/src/sample-counter-v1/views/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v1/src/sample-counter-v1/views/i-view.ts | Adds/updates generated code under full-namespace layout. |
| targets/js/sample-counter-v1/src/sample-counter-v1/views/counter-view.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v1/src/sample-counter-v1/presenters/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v1/src/sample-counter-v1/presenters/i-counter-view.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v1/src/sample-counter-v1/presenters/counter-presenter.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/sample-counter-v1/src/sample-counter-v1/models/index.ts | Adds leaf barrel under full-namespace layout. |
| targets/js/sample-counter-v1/src/sample-counter-v1/models/counter.ts | Adds/updates generated model under full-namespace layout. |
| targets/js/sample-counter-v1/src/program.ts | Updates internal imports to direct-file full-namespace paths. |
| targets/js/hello-world/lib/program.js | Updates compiled output under new directive/header conventions. |
| src/Metano.Compiler/IR/IrCompilation.cs | Updates documentation for LocalRootNamespace semantics under the new layout policy. |
| src/Metano.Compiler/CSharpSourceFrontend.cs | Sets LocalRootNamespace to empty and removes local root namespace computation for TS layout. |
| src/Metano.Compiler/Caching/CacheKeyBuilder.cs | Exposes path-safety helper for pruning and documents deletion safety. |
| src/Metano.Compiler.TypeScript/TypeScriptTarget.cs | Adds layout=full-namespace-v1 into cache fingerprint. |
| src/Metano.Compiler.TypeScript/Transformation/TypeTransformer.cs | Forces empty root stripping for cross-package path computation under full-namespace layout. |
| src/Metano.Compiler.TypeScript/Transformation/PathNaming.cs | Changes internal imports to target defining files directly (not barrels). |
| src/Metano.Compiler.TypeScript/Commands.cs | Documents --no-cache interaction with orphan pruning and --clean. |
| src/Metano.Compiler.TypeScript/Bridge/IrToTsTypeMapper.cs | Aligns cross-package subpath computation with full-namespace layout. |
| src/Metano.Build/build/Metano.Build.targets | Documents reduced need for MetanoClean due to self-pruning incremental outputs. |
| specs/005-deterministic-output-layout/quickstart.md | Adds end-to-end validation steps for deterministic layout + pruning + import contract. |
| specs/005-deterministic-output-layout/data-model.md | Defines the conceptual entities/contracts behind deterministic layout and pruning. |
| specs/005-deterministic-output-layout/contracts/pruning-contract.md | Adds normative pruning contract documentation. |
| specs/005-deterministic-output-layout/contracts/path-mapping.md | Adds normative type→path mapping contract documentation. |
| specs/005-deterministic-output-layout/contracts/import-contract.md | Adds normative internal/external import contract documentation. |
| specs/005-deterministic-output-layout/checklists/requirements.md | Captures spec readiness checklist for this feature. |
| specs/001-project-baseline-evolution/baseline/feature-support-matrix.md | Updates baseline matrix to reflect new layout + pruning guarantees. |
| docs/cross-package.md | Updates cross-package import documentation for full-namespace layout and internal direct-file imports. |
| docs/adr/0025-full-namespace-output-layout.md | Adds ADR describing the decision and its consequences. |
| CLAUDE.md | Updates active feature plan pointer to spec 005. |
| .specify/feature.json | Points Spec Kit feature directory to spec 005. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 145ec48ffe
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ental builds Map each generated type to its complete kebab-cased C# namespace under the package root instead of stripping a longest-common-prefix "root namespace". The prior layout was data-dependent: adding or removing a sibling type in another namespace silently relocated unrelated files, and orphaned outputs were never deleted - together masking broken imports (a consumer's `../contracts` resolving only through a stale barrel). - The path is now a pure function of a type's own namespace (no stripping), stable across the type set; local and cross-package converge. - Internal generated-to-generated references import the defining file directly, never a barrel - structurally avoiding ESM cycles and decoupling internal correctness from barrel emission. - Per-namespace leaf barrels stay always-on; the root aggregation barrel (`--namespace-barrels`) stays opt-in and now mirrors the full hierarchy. - Incremental builds self-prune: orphaned generated files and emptied directories are removed by reconciling the cache manifest, restricted to transpiler-owned paths and guarded against path traversal; skipped on a cache hit / --no-cache / --clean and only after a successful emit. - A layout-version token in the cache fingerprint invalidates stale caches on upgrade. Spec under specs/005-deterministic-output-layout; rationale in ADR-0025.
…e layout Regenerate every C#-backed sample under the new full-namespace layout and re-point hand-written consumers (bun tests, app entries) at the full-namespace subpaths. Update the SampleIssueTracker namespace-barrels test for the now package-rooted aggregation tree, and rebuild the metano-runtime dist that several samples build against. All regenerated samples build, and every sample that ships bun tests is green. HelloWorld's pre-existing vite-scaffolding build failure is unrelated and untouched.
Samples were regenerated and verified green (12/13; HelloWorld's pre-existing vite-scaffolding failure is unrelated), so T012/T024 are done, not blocked.
…space layout Add feature-support-matrix rows tracing the full-namespace layout and orphan pruning to ADR-0025 with code+test references, and update the cross-package import-resolution guide for full-namespace paths, internal direct-file imports, and the opt-in (non-tree-shakable) root aggregation barrel. Closes feature 005 documentation debt (T026/T027).
…ailures Address PR review feedback on the pruning step: - Guard `previous?.OutputHashes` directly so pruning never depends on the cache structural-validity contract (defensive; TryRead already rejects manifests without OutputHashes). - Make the empty-directory probe best-effort: catch I/O and access failures from `Directory.EnumerateFileSystemEntries` instead of letting them abort an otherwise successful build. - Compare output-tree paths with the host filesystem's case sensitivity so the empty-directory walk is correct on case-insensitive Windows/macOS.
… is removed When an emit produces zero files (the last [Transpile] type was removed), the TypeScript CLI skipped the package.json reconciliation, leaving exports that advertise subpaths whose barrels were just pruned. Run the reconciliation on an empty output set too, but only when a package.json already exists - so stale transpiler exports are pruned without scaffolding package.json for a project that never produced output. Addresses PR review feedback.
1cd9868 to
f9530f7
Compare
Problem
Generated TypeScript paths were unstable and stale-prone, masking broken imports (observed in a real consumer: a hand-written
import { UserProfile } from \"../contracts\"resolved only through a stale orphan barrel; a clean rebuild broke it). Two root causes:What changed
Vigiata.Contracts.Profiles.UserProfileDto→vigiata/contracts/profiles/user-profile.ts). The path is now a pure function of the type's own namespace — stable across the type set; local and cross-package converge. Confined to the TS adapter (Dart untouched).--namespace-barrels) stays opt-in because it defeats tree-shaking, and now mirrors the full C# hierarchy.--no-cache/--clean. Alayout=full-namespace-v1fingerprint token invalidates stale caches on upgrade.Verification
OutputLayoutTests,ImportContractTests,DeterministicLayoutScenarioTests,Caching/OrphanPruningTests) + the layout churn across existing assertions.HelloWorld's pre-existing vite-scaffolding build failure is unrelated and untouched.Docs & traceability
Spec:
specs/005-deterministic-output-layout/. Rationale:docs/adr/0025-full-namespace-output-layout.md(supersedes ADR-0006 layout). Baseline matrix + cross-package guide updated.Follow-up (out of scope)
Downstream consumers (e.g. the Vigiata project) regenerate to the new layout once they consume the updated Metano, and update root-level imports (
../contracts) to the namespace subpath (or enable--namespace-barrels).