Skip to content

chore: merge the di repository into this monorepo - #30

Closed
btravers wants to merge 30 commits into
mainfrom
merge/di
Closed

chore: merge the di repository into this monorepo#30
btravers wants to merge 30 commits into
mainfrom
merge/di

Conversation

@btravers

Copy link
Copy Markdown
Contributor

Merges btravstack/di into this repo as packages/di, per the decision that start is the stack's aggregator and di is its closest-coupled sibling (mutual 0.x, peer ^0.1.0, effectively one audience).

What moved

  • packages/di — the package, with its full git history (subtree merge; 27 commits reachable through the merge commit). Manifest now names this repo; still published as @btravstack/di, still a peer of the four start packages.
  • examples/hexagonal-order-api / request-scope / plugin-registry — di's consumer examples, indexed in examples/README.md.
  • docs/ — di's VitePress + TypeDoc site, with its toolchain (theme, typedoc + named catalog, vitepress, the typescript-consumer alias for the dual declaration-emit pass, the vite security override) folded into the root catalog.
  • CONTRIBUTING.md / SECURITY.md, the deploy-docs.yml + release.yml workflows and the composite setup action.
  • di's root CLAUDE.md became packages/di/CLAUDE.md (sixth per-package spec file).

Wiring changes

  • @btravstack/di moves from catalog: to workspace:^/workspace:* across all workspaces; the catalog entry is gone.
  • knip.jsonknip.jsonc, carrying di's entries and dropping this repo's dead workspaces block (one checkbox of Mechanical consistency sweep across the packages #27).
  • Changeset config adopts onlyUpdatePeerDependentsWhenOutOfRange — needed now that start packages peer on an in-repo di.
  • di's suite runs under unthrown 5.5.0 (its own repo pinned 5.1.0) and this repo's stricter oxlint set — both green unchanged.

Gate

format ✓ · lint ✓ · typecheck ✓ (26 tasks, incl. di's dual-TS emit pass and the docs build) · knip ✓ · test: 24/25 workspaces green — the one failure is the pre-existing local-only port-9000 probe conflict, unrelated to this PR · build ✓ (6 tasks).

After this lands (separate steps, not in this PR)

  • Enable GitHub Pages on this repo for deploy-docs.yml (di's docs URL moves).
  • Transfer open issues from btravstack/di (e.g. di#9) and archive that repo with a pointer here.

🤖 Generated with Claude Code

btraversand others added 30 commits August 9, 2026 18:54
Set up the repo shell following @btravstack/entity's conventions: pnpm
workspace with the shared @btravstack/* catalog packages (tsconfig,
oxlint, lefthook, commitlint), turbo pipeline, changesets, knip, and CI.
No package yet — packages/* and examples/* are declared as workspace
globs for the di package and its future examples.
Ports declare what an application needs, providers bind a port to a
concrete construction (value, factory, class, or an acquire/release
resource), and modules group providers behind explicit imports/exports.
Every wiring mistake the type system can catch — a missing dependency,
an internal port leaking out of a module, a re-export of something
never imported — is a compile error; a cycle or a duplicate provider is
caught before any factory runs, as a defect via unthrown.
Ported from the reviewed @saas/platform-di implementation (93 tests),
adapted to this repo's layout: runtime tests renamed *.test.ts ->
*.spec.ts per @btravstack/entity's convention, relative imports moved
to .js extensions to match the shared tsconfig's NodeNext resolution,
and interface declarations converted to type aliases per the shared
oxlint config's consistent-type-definitions rule.
Root README pitches the package and links to the package docs, in
entity's style (badges, one-paragraph pitch, worked example). The
package README preserves the platform-di walkthrough — ports, providers,
modules, the construction family — with package names updated for the
published @btravstack/di surface.
Ports named by the application, a private connection pool behind a
public repository, and one application module composed against a
production adapter and an in-memory one — the core story for
@btravstack/di, built as a real workspace package rather than just a
README walkthrough. Includes the compile-time guarantees (port
privacy, the Module.build/Module.scoped gate) pinned in a dedicated
index.test-d.ts, mirroring packages/di's own example.test-d.ts split.
Lifetime management: a connection pool acquired once under
Module.scoped, and a per-request transaction layered over the
already-built parent with Module.forkScope. The spec proves — not
just type-checks — that each request's resource releases before the
next begins, that the parent outlives every fork, and that a fork
resolves its dependency from the parent context rather than a copy
of its own.
Multi-binding: a Port.many health-check registry fed independently by
two modules via Provider.member, collected and run together at the
composition root. The spec proves contributions accumulate across
module boundaries, a failing check comes back as reported data rather
than aborting the run, and the registry is purely additive when a
third module joins.
Indexes the three examples workspace packages, in the style of
btravstack/entity's examples/README.md. Also picks up pnpm-lock.yaml's
update from installing the three new example packages' devDependencies.
…larations
A consumer that exports a port it declares could not emit declarations:
export class OrderRepository extends Port("OrderRepository")<Shape> {}
emits as `declare const OrderRepository_base: <the heritage expression's
type>`, and the emitter can only write that type using names the consumer can
reach. `PortClass`/`ManyPortClass` were not exported from the package index, so
it had none: it expanded the heritage expression down to `PortInstance`'s
`[ID]`/`[SERVICE]`/`[MANY]` keys — module-private `unique symbol`s — and
reported TS4020, "has or is using private name 'ID'". That is the pattern
`packages/di/README.md` teaches on its first page, so it affected essentially
every real consumer.
Exporting the two class *types* is the fix that costs least. The emitter now
stops at `PortClass<"OrderRepository">` (2,683 bytes of consumer declarations
across the reproduction, against 3,545 when only the instance types are
nameable and the construct signature has to be written out), and `port.ts` is
untouched.
The brand symbols stay unexported deliberately. Exporting them also fixes emit,
but a consumer who can name `ID`/`SERVICE` can hand-write
`{ [ID]: "Logger", [SERVICE]: Shape }` and pass it off as a `Logger` — measured,
it type-checks. Naming the class types grants no such thing: the brand keys stay
unreachable, so port identity stays nominal and a port instance stays
unforgeable. As an ambient `export declare const` they have no runtime binding
and rolldown rejects the index re-export outright (MISSING_EXPORT); making them
real `Symbol()` values would add runtime surface to phantom tokens that are
never constructed.
The three example packages carried `declaration: false` in their own tsconfigs
to dodge this. That is legitimate only because they are private, and it is what
kept the repo green while no consumer could build, so it goes with the fix.
`packages/di`'s own checks never emitted a consumer's declarations, so TS4020
could not be seen from inside the repo — the three example packages had turned
`declaration` off, and the library's own `tsc --noEmit` only ever compiles code
that can name `port.ts`'s brand symbols directly.
`examples/hexagonal-order-api/src/emit-guards.ts` is that missing consumer: a
file imported by nothing, which exists to be *compiled*. It names a plain port,
a `Port.many` set port, a port reaching through another port's `ServiceOf`, the
providers and module built on them, and the two factories whose return type is
a port class rather than an instance — the shapes that fail through different
brands, so a fix naming only one of the class types leaves the other broken.
`tsconfig.emit.json` turns `noEmit` back off (TS4020 is raised by the
declaration *emitter*, so a `--noEmit` pass cannot be the whole gate) and the
package's `typecheck` script runs it under both 7.0.2 and a stable-line 5.9.3,
then feeds the emitted `.d.ts` back through the compiler — a dangling reference
in the output is not an emit-time diagnostic and would otherwise ship.
`emit-guards.d.ts` is named explicitly in that last step because nothing imports
it, so it would go unchecked on `index.d.ts` alone.
The `@ts-expect-error` directives in the fixture are the other half: they assert
that `ID`/`SERVICE`/`MANY` are still unreachable and that two structurally
identical ports with different ids still do not unify. An unused directive there
is a failure, not noise — it is the signal that someone bought declaration emit
by widening the export surface far enough to forge a port.
Verified with teeth: reverting the index re-export puts eleven TS4020/TS4023
errors back through this fixture. `knip.jsonc` names it an entry, without which
knip reports it as an unused file.
fix(di): let consumers emit declarations for their own ports
The beet is not totally formed — dome, eyes and smile only, coalescing at the
needle end, one drop already out. Mid-formation is temporal-contract's own
grammar, so the two logos rhyme: the container constructs the dependency, then
injects it. Replaces the socket mark, which the history keeps.
Dependabot groups verbatim (weekly npm + actions); release rides
btravstack/config's reusable workflow after a green CI on main, exactly as the
sibling repos do.
docs: guidance for future Claude Code instances, as CLAUDE.md
docs: the documentation site — vitepress + typedoc, on the entity template
chore: make 0.1.0 the first published version
…go pair
Three things the landing surfaced when di joined it as the fifth panel
(btravstack/btravstack.github.io#43). Closes#6. Closes#7.
**The accent.** `--accent` was `#2A62B8`, the logo's deep blue. The landing
paints each package name in the raw accent against a `#100F12` card, and that
hex measures 3.22 there — the other four packages sit at 5.00–7.25. It is now
`#3E7FD4`, the logo's *lighter* blue: 4.72 on the dark card, 7.10 as darkened
text on white. The original reasoning is untouched and still holds — blue is
plumbing, and the hex is one the mark itself already paints (barrel rim,
plunger, needle hub), so chrome and artwork stay one color.
**The logo pair.** di shipped only `logo.svg`, and it was the one package
without a `logo-{light,dark}` pair. Three of its values read against the canvas
rather than against the artwork, so on a light background the near-white barrel
washed out and the mark read as a floating beet with a blue cap. `logo-dark` is
the existing file unchanged; `logo-light` inverts exactly those three — barrel
`#EAF2FB`→`#2A2730`, plunger `#2A62B8`→`#3E7FD4`, needle `#9FB2C8`→`#5A6675`.
The ticks stay at 50% opacity: 1.89 against the dark barrel versus 1.81 against
the light one, so they read equally faint either way. The hero and the nav logo
now take the pair; `logo.svg` stays the favicon and the JSON-LD mark.
**The theme.** Catalog moves 1.7.0 → 2.0.0, which is where `--pkg-di` lives.
The major is the removal of `--pkg-demesne` / `--pkg-start`; neither is
referenced here, so nothing breaks. pnpm recorded the new version as a pinned
`minimumReleaseAgeExclude` entry — replaced with the unversioned name and the
rationale comment the other repos use, so the next release needs no entry.
Docs build clean: `--accent: #3E7FD4` in the emitted CSS, no `2a62b8` left, all
five `--pkg-*` tokens present and both retired ones gone, and both logo variants
verified in both themes.
`pnpm format --check` failed CI on this file. oxfmt normalises CSS hex values
to lowercase, which is why every sibling site's `--accent` is lowercase and why
this file's own `#2a62b8` was before it changed. The comment's hex follows, so
the file does not mix cases with its own declaration.
Note this is the opposite of the markdown convention: prose in changesets and
`design.md` writes hexes uppercase. Each file type is internally consistent.
Root cause of the miss: the shared pre-commit hook in @btravstack/lefthook
globs `*.{ts,tsx,js,jsx,json,yaml,yml,md}`, which has no `css`, so this file was
never formatted locally — the hook reported three files (config.ts, index.md,
pnpm-workspace.yaml) and skipped this one. CI runs `oxfmt .` over everything.
feat(docs): theme 2.0.0, the lighter blue accent, and a light/dark logo pair
…3100'
git-subtree-dir: .incoming-di
git-subtree-mainline: 245de2e
git-subtree-split: e4ef06e
The subtree's packages/di, three examples and docs workspace move to
their start-side homes; di's root CLAUDE.md becomes packages/di's; the
repo-generic CONTRIBUTING/SECURITY and the deploy-docs/release
workflows come along; duplicated root scaffolding is dropped.
Intermediate state: the catalog entries the moved workspaces need land
in the next commit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The catalog gains the docs toolchain (@btravstack/theme, typedoc + its own
named catalog, vitepress, the typescript-consumer alias) and the vite
override; the docs workspace joins the workspace list; knip.json becomes
knip.jsonc carrying di's entries (and drops this repo's dead workspaces
block — knip's default entry patterns already cover src/main.ts); the
changeset config adopts onlyUpdatePeerDependentsWhenOutOfRange, which
matters now that the start packages peer on an in-repo di.
@btravstack/di moves from catalog: to workspace ranges everywhere; its
published peer range stays ^0.1.0 and its manifest now names this repo.
di's code passes this repo's stricter oxlint set (no-throw,
no-get-or-throw, prefer-ensure) unchanged, and its suite is green under
unthrown 5.5.0 (was 5.1.0 in its own repo).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CopilotAI lite review requested due to automatic review settings August 13, 2026 18:40

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR merges the standalone btravstack/di repository into this monorepo as packages/di, updating workspace wiring so the start kernel and its runtimes consume the in-repo DI package while keeping @btravstack/di published separately (still as a peer). It also brings over di’s consumer examples and documentation site, plus supporting release/docs workflows and repo metadata.

Changes:

  • Add the packages/di workspace (source, tests, type-level tests, package metadata) and switch existing workspaces to depend on it via workspace:* / workspace:^.
  • Add di’s documentation site as a docs/ workspace (TypeDoc + VitePress), with Turbo wiring and deploy workflow.
  • Consolidate repo tooling/config: knip config to .jsonc, changesets config tweak, new contributing/security docs, and supporting GitHub workflows/actions.

Reviewed changes

Copilot reviewed 109 out of 115 changed files in this pull request and generated 9 comments.

Show a summary per file
FileDescription
turbo.jsonAdds a dedicated Turbo build task for the di docs site output.
SECURITY.mdAdds repository security policy for vulnerability reporting.
README.mdUpdates documentation section to include packages/di and the docs site.
pnpm-workspace.yamlAdds docs as a workspace and updates the root catalog/overrides for docs toolchain.
packages/start/package.jsonSwitches @btravstack/di devDependency from catalog: to workspace:^.
packages/start-temporal/package.jsonSwitches @btravstack/di devDependency from catalog: to workspace:^.
packages/start-http/package.jsonSwitches @btravstack/di devDependency from catalog: to workspace:^.
packages/start-amqp/package.jsonSwitches @btravstack/di devDependency from catalog: to workspace:^.
packages/di/vitest.config.tsAdds Vitest config for the di package.
packages/di/tsconfig.test-d.jsonAdds a dedicated tsconfig for *.test-d.ts type-level tests.
packages/di/tsconfig.jsonAdds di package TypeScript build config aligned to repo base config.
packages/di/src/type-assert.tsAdds shared Equal<A,B> type helper for type-level tests.
packages/di/src/scoped.test-d.tsAdds type-level tests for Module.scoped / Scope gating semantics.
packages/di/src/scope.tsAdds the di scope/finaliser implementation (LIFO, swallow/report failures).
packages/di/src/provider.spec.tsAdds runtime tests for provider construction arms and defect handling.
packages/di/src/port.test-d.tsAdds type-level tests for nominal Port identity and ServiceOf.
packages/di/src/port.spec.tsAdds runtime tests for port id and duplicate-id warning behavior.
packages/di/src/many.test-d.tsAdds type-level tests for Port.many and Provider.member typing.
packages/di/src/many.spec.tsAdds runtime tests for set-port accumulation and wiring-defect behavior.
packages/di/src/index.tsDefines di’s public API surface and type-only export decisions.
packages/di/src/fork.test-d.tsAdds type-level tests for Module.forkScope typing and gating.
packages/di/src/fork.spec.tsAdds runtime tests for forked scope teardown isolation vs parent scope.
packages/di/src/example.test-d.tsAdds type-level example asserting module privacy at compile time.
packages/di/src/context.test-d.tsAdds type-level tests for Context variance and access gating.
packages/di/src/context.spec.tsAdds runtime tests for context immutability and unsafeAdd behavior.
packages/di/src/build.test-d.tsAdds type-level tests for Module.build return typing and arity gate.
packages/di/package.jsonAdds the published di package manifest and scripts.
packages/di/LICENSEAdds di’s MIT license file.
packages/di/CLAUDE.mdAdds di-specific spec/guidance file for contributors/agents.
packages/di/CHANGELOG.mdAdds di changelog (0.1.0 initial release).
knip.jsoncAdopts JSONC, adds di/docs-related ignores and a di example entrypoint override.
knip.jsonRemoves old knip config (replaced by knip.jsonc).
examples/request-scope/vitest.config.tsAdds Vitest config for the request-scope example.
examples/request-scope/tsconfig.jsonAdds TS config for the request-scope example.
examples/request-scope/src/index.tsAdds the request-scope example implementation using Module.scoped + forkScope.
examples/request-scope/src/index.spec.tsAdds runtime tests proving lifecycle/release ordering and parent seeding.
examples/request-scope/README.mdAdds documentation for the request-scope example.
examples/request-scope/package.jsonAdds the request-scope example workspace manifest.
examples/README.mdExtends examples index to include the di example family.
examples/plugin-registry/vitest.config.tsAdds Vitest config for the plugin-registry example.
examples/plugin-registry/tsconfig.jsonAdds TS config for the plugin-registry example.
examples/plugin-registry/src/index.tsAdds plugin-registry example showcasing Port.many + Provider.member.
examples/plugin-registry/src/index.spec.tsAdds runtime tests for contribution accumulation and failure folding.
examples/plugin-registry/README.mdAdds documentation for the plugin-registry example.
examples/plugin-registry/package.jsonAdds the plugin-registry example workspace manifest.
examples/order-worker/package.jsonSwitches @btravstack/di dependency to workspace:*.
examples/order-temporal/package.jsonSwitches @btravstack/di dependency to workspace:*.
examples/order-infrastructure/package.jsonSwitches @btravstack/di dependency to workspace:*.
examples/order-application/package.jsonSwitches @btravstack/di dependency to workspace:*.
examples/order-api/package.jsonSwitches @btravstack/di dependency to workspace:*.
examples/order-amqp/package.jsonSwitches @btravstack/di dependency to workspace:*.
examples/hexagonal-order-api/vitest.config.tsAdds Vitest config for the hexagonal-order-api example.
examples/hexagonal-order-api/tsconfig.test-d.jsonAdds dedicated type-test tsconfig for the hexagonal example.
examples/hexagonal-order-api/tsconfig.jsonAdds TS config for the hexagonal example (excludes *.test-d.ts).
examples/hexagonal-order-api/tsconfig.emit.jsonAdds declaration-emit fixture config used to gate TS4020-class issues.
examples/hexagonal-order-api/src/index.tsAdds the hexagonal architecture example implementation.
examples/hexagonal-order-api/src/index.test-d.tsAdds compile-time tests for privacy + Scope gating in the example.
examples/hexagonal-order-api/src/index.spec.tsAdds runtime tests for both production and in-memory compositions.
examples/hexagonal-order-api/README.mdAdds documentation for the hexagonal example.
examples/hexagonal-order-api/package.jsonAdds the hexagonal example workspace manifest and emit/typecheck scripts.
docs/typedoc.jsonAdds TypeDoc config to generate di API docs from source.
docs/reference/wiring-defects.mdAdds reference docs for pre-construction wiring defects and messages.
docs/reference/providers.mdAdds reference docs for Provider construction arms and semantics.
docs/reference/ports.mdAdds reference docs for ports, set ports, ServiceOf, and type-only Scope.
docs/reference/modules.mdAdds reference docs for module structure, channels, and variance rule.
docs/reference/entry-points.mdAdds reference docs for build/scoped/forkScope and the arity gate.
docs/public/logo.svgAdds docs site logo asset.
docs/public/logo-light.svgAdds light-mode logo asset variant.
docs/public/logo-dark.svgAdds dark-mode logo asset variant.
docs/package.jsonAdds docs workspace manifest and build/dev scripts.
docs/index.mdAdds VitePress home page for di docs.
docs/how-to/swap-an-adapter.mdAdds how-to guide for adapter swapping via module seams.
docs/how-to/request-scope.mdAdds how-to guide for per-request scopes via forkScope.
docs/how-to/private-ports.mdAdds how-to guide for module privacy via exports.
docs/how-to/plugin-registry.mdAdds how-to guide for plugin registries via set ports.
docs/how-to/manage-a-resource.mdAdds how-to guide for resource lifetime management via scoped.
docs/explanation/why-di.mdAdds explanation of di’s design motivations and constraints.
docs/explanation/scopes-and-resources.mdAdds explanation of Scope as a phantom debt and teardown guarantees.
docs/explanation/peer-dependencies.mdAdds explanation for unthrown being a peer dependency.
docs/explanation/modules-and-privacy.mdAdds explanation of type-level privacy vs flat runtime map.
docs/explanation/failures-vs-defects.mdAdds explanation of modeled failures vs defects and channel separation.
docs/explanation/compile-time-wiring.mdAdds explanation of Needs propagation and compile-time arity gate.
docs/examples/request-scope.mdAdds docs page for the request-scope example.
docs/examples/plugin-registry.mdAdds docs page for the plugin-registry example.
docs/examples/index.mdAdds docs page indexing di examples and explaining why they’re “tests”.
docs/examples/hexagonal-order-api.mdAdds docs page for the hexagonal-order-api example.
docs/api/index.mdAdds API reference landing page (TypeDoc output linked beneath).
docs/.vitepress/theme/index.tsAdds VitePress theme wiring for docs site.
docs/.vitepress/theme/custom.cssAdds di-specific accent/theming tokens for docs site.
docs/.vitepress/config.tsAdds VitePress site config (nav, sidebar, edit links, social/meta).
CONTRIBUTING.mdAdds contribution guidelines and the repo “gate” commands.
CLAUDE.mdUpdates repo-level authoritative spec to reflect di merge and repo structure.
.gitignoreIgnores VitePress cache and generated TypeDoc output directory.
.github/workflows/release.ymlAdds release workflow chaining off CI success on main.
.github/workflows/deploy-docs.ymlAdds GitHub Pages deploy workflow for docs (TypeDoc + VitePress).
.github/actions/setup/action.ymlAdds composite action for Node+pnpm setup and turbo cache.
.changeset/no-release-first-publish.mdAdds changeset marker for release plumbing without a bump.
.changeset/config.jsonEnables onlyUpdatePeerDependentsWhenOutOfRange experimental option.
Suppressed comments (3)

docs/.vitepress/config.ts:176

  • The docs site social GitHub link still points at btravstack/di. After moving di into this monorepo, it should link to the new location to avoid a stale/archived repo.
 socialLinks: [
{ icon: "github", link: "https://github.com/btravstack/di" },
{ icon: "npm", link: "https://www.npmjs.com/package/@btravstack/di" },
],

docs/.vitepress/config.ts:194

  • The editLink pattern still targets the old btravstack/di repository, so “Edit this page on GitHub” will be broken/misleading after the merge. It should point at this repo’s docs path.
 editLink: {
pattern: "https://github.com/btravstack/di/edit/main/docs/:path",
text: "Edit this page on GitHub",
},

docs/.vitepress/config.ts:304

  • The Organization JSON-LD sameAs still references the old btravstack/di repo. After the move, it should reference the new canonical repository URL.
 "@type": "ImageObject",
url: `${SITE_URL}logo.svg`,
},
sameAs: ["https://github.com/btravstack/di"],
}),

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threadSECURITY.md
Comment on lines +15 to +16
- **GitHub Security Advisories** — [open a private report](https://github.com/btravstack/di/security/advisories/new)
(preferred; keeps the discussion and fix coordination in one place).
Comment threaddocs/index.md
Comment on lines +21 to +23
- theme: alt
text: GitHub
link: https://github.com/btravstack/di
Comment on lines +141 to +144
{
text: "Changelog",
link: "https://github.com/btravstack/di/releases",
},
Comment on lines +8 to +11
Three small packages under
[`examples/`](https://github.com/btravstack/di/tree/main/examples), each
showing a different job `@btravstack/di` does — and, at the same time,
exercising the library end to end from a consumer's own workspace.
Comment on lines +42 to +44
```sh
git clone https://github.com/btravstack/di.git && cd di
pnpm install
Comment on lines +8 to +10
**Source:**
[`examples/hexagonal-order-api`](https://github.com/btravstack/di/tree/main/examples/hexagonal-order-api)

Comment on lines +8 to +10
**Source:**
[`examples/request-scope`](https://github.com/btravstack/di/tree/main/examples/request-scope)

Comment on lines +8 to +10
**Source:**
[`examples/plugin-registry`](https://github.com/btravstack/di/tree/main/examples/plugin-registry)

Comment on lines +84 to +87
sentence, and hovering a large module shows real channel unions. The library
is also deliberately small — one construction family, one module algebra,
three entry points, and [one name per concept](https://github.com/btravstack/di/blob/main/CONTRIBUTING.md).
If you want conditional registration DSLs, interceptors, or property
@btravers

Copy link
Copy Markdown
ContributorAuthor

Closing: decision reversed — di stays in its own repo for now. The merge work is preserved on a local branch and can be revived if the co-design cost ever justifies it.

@btravers
btravers deleted the merge/di branch August 13, 2026 18:48
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@btravers