Files
commandkit/docs/roadmap/modules.md

18 KiB

Optional integration modules

Status: module boundary accepted in ADR 0010; consumer API and internal backend design finalized, with both composition questions resolved. The staged implementation plan is complete; no module extraction has begun. ReleaseKit v0.4.0 provides module-release support; CommandKit adoption is pending.

Purpose and authority

Make CommandKit useful to consumers that use both ConfigKit and PromptKit, ConfigKit alone, or neither library. Consumers using only CommandKit's core should acquire neither ConfigKit nor PromptKit through CommandKit's package or module dependencies. ConfigKit-only consumers should not acquire PromptKit.

This roadmap records the targeted end state, selected module layout, and delivery boundaries. The implementation plan owns the ordered steps and validation needed to reach this target. The finalized registration API owns the selected declarations, installation semantics, and representative consumer examples. The finalized registration backend design owns internal structure, shared installation/execution mechanics, and the resolved composition decisions. These documents describe the implementation target. ADR 0010 owns the accepted module boundary and convenient registration principles; it partially supersedes ADR 0003, whose remaining principles still apply. ADR 0011 records the finalized registration and invocation-lifetime decisions. The architecture policy is aligned with those decisions. GoDoc, the CLI reference, and the consumer guide describe the prototype baseline; they do not make its incidental API shapes compatibility requirements for this sprint.

Organizing principle: design the final API

Give the existing prototype implementation zero deference when selecting the final API, as directed for this transition. Core v0.1.0 has since been published; preserve that release and prepare the incompatible replacement as a fresh minor release under the release policy. Publication does not change the selected API or require compatibility wrappers for this sprint. The goal is the best, simplest, most coherent API for the accepted responsibilities and representative consumers, not the smallest diff or a mechanically relocated prototype. Accepted architectural decisions and explicitly selected behavior remain requirements; prototype declarations, helpers, bookkeeping, and tests do not independently establish contracts.

Complete the transition in one sprint. No backward-compatibility wrappers, deprecation period, or migration bridge is needed. Intermediate commits need not build or pass tests; do not add temporary machinery merely to make them do so. Validate the complete target state before release. Reuse existing code where it serves that design, and refactor, replace, or remove it where it does not.

Current baseline

At the start of this roadmap, CommandKit has one Go module and one supported public root package. It requires ConfigKit v0.5.0 and PromptKit v0.12.0 and declares Go 1.26.0. Its internal Cobra adapter implements routing and parsing.

The root combines core command infrastructure with configuration and PromptKit inspection. Coupling extends beyond constructors:

  • NewConfigKitScope accepts ConfigKit results and maps their diagnostics.
  • Core Diagnostic.Severity currently uses ConfigKit's public severity type; moving inspection handlers alone will not remove that dependency.
  • SourceReader returns ConfigKit source records; ExplanationReader accepts ConfigKit paths and returns ConfigKit explanations.
  • PromptKitSuite callbacks return PromptKit inspection types.
  • NewPromptKitScope adapts engine configuration into the configuration suite.
  • Standard handlers share root-private helpers and state. For example, configuration registration accesses the application's registry and records whether the suite has already been installed.

The internal overview describes the implemented inventory. The maintained examples and integration tests currently belong to the root module. ReleaseKit v0.3.0 is also selected there as a Go tool dependency; the release procedure assumes one module and one version tag.

Optional command registration currently controls behavior, not dependencies. Moving integration code into packages sharing the root go.mod would separate compiled imports but retain integration requirements in the module graph. Go's module graph rules explain that distinction.

Targeted end state

Provide three consumer modules in this repository with dependencies directed toward the core. Keep the core at gitea.maximumdirect.net/eric/CommandKit and give each integration its own go.mod:

Directory Module path Package name
Repository root gitea.maximumdirect.net/eric/CommandKit commandkit
integrations/ckconfig gitea.maximumdirect.net/eric/CommandKit/integrations/ckconfig ckconfig
integrations/ckprompt gitea.maximumdirect.net/eric/CommandKit/integrations/ckprompt ckprompt

The integrations/ grouping keeps optional modules together as their number grows; the anticipated three to ten integrations are planning context, not a limit or delivery commitment. Distinct package names avoid requiring local aliases when these integrations are imported alongside ConfigKit and PromptKit. Separate module files establish dependency isolation; directory naming alone does not. The shared repository requires explicit multi-module testing and publication orchestration.

Module Responsibility Integration dependencies
Core Application construction, command/group registration, typed bindings, dispatch, help/version, common grammar, outcomes, and diagnostics Neither ConfigKit nor PromptKit
ConfigKit integration Standard configuration family, scope composition, reports, and ConfigKit adapters Core and ConfigKit; no PromptKit
PromptKit integration Named prompt/profile inspection and the PromptKit configuration-scope adapter Core, PromptKit, and the ConfigKit integration

The core remains an opinionated command library with its existing internal Cobra boundary. The dependency goal is independence from ConfigKit and PromptKit, not a standard-library-only implementation.

Integrations remain maintained parts of CommandKit. They install commands into the same application through supported public core operations and follow its grammar, help, invocation, and outcome conventions. Applications retain domain commands, acquisition, runtime construction, streams, and process exit.

The selected configuration boundary moves the existing ConfigKit-shaped contracts with their handlers into the ConfigKit integration. Only ConfigKit support is needed for now; a generic configuration interface is outside this migration. The PromptKit integration may depend on the ConfigKit integration, consistent with PromptKit's own ConfigKit dependency. Document that relationship in consumer guidance: ckprompt depends on ckconfig.

This boundary preserves one configuration suite into which applications compose app, promptkit, and other supported scopes. PromptKit configuration inspection and named-definition inspection remain independently selectable. A module dependency does not automatically install a command family.

Core public signatures and implementation imports contain no ConfigKit or PromptKit types. Integration-specific types and helpers move to their owning modules. Do not retain root forwarding wrappers that restore those imports. Shared helpers stay private unless a concrete cross-module interaction needs a supported contract; extraction is not a reason to expose every existing helper.

Preserve explicitly selected operator behavior: command vocabulary, selection and scope semantics, native reports, diagnostics, error identity, outcomes, and help without provider acquisition. Identify and decide any changes to selected CLI behavior separately. Do not preserve accidental prototype behavior or Go API shapes merely because they already exist.

Selected API and release principles

  • Use the finalized uniform registration API. Applications and integrations produce captured core command declarations and install them through core New or App.Register; construction errors are retained for installation-time validation. Integration factories provide complete families and focused conveniences. The API document owns exact signatures and the input/shared-state separation.
  • Follow the selected namespace lifetime and reconciliation requirements. Built-in help/version remain reserved; optional integration roots are owned when their real family is installed. ADR 0011 and the architecture policy now record that lifetime; implementation remains pending.
  • Use the finalized internal registration and execution design. Built-ins, application commands, and integration families share one installation path and typed compiler. Captured metadata and invocation state have distinct owners; the backend document defines the capture, binding, routing, and presentation mechanics without adding another integration installation API.
  • Apply the resolved unused-binding validation boundary and scope-error handoff. The registration API incorporates the selected runnable-parent and scope-error attachment declarations. No absence-validation overload is selected.
  • Core diagnostics use a small CommandKit-owned severity type. Upstream diagnostic conversion belongs in the integrations, preserving selected classification, delivery, and error semantics without copying ConfigKit's wider data model into the core.
  • Version the modules independently according to their own changes and the release policy. Do not require integration version numbers to match either the core or upstream dependency versions. Record selected dependencies in go.mod and explain relevant upstream adoption in module release notes. Coordinate publication when changes span modules; independent versions do not imply an exhaustive compatibility matrix.

Selected multi-module release approach

Adopt ReleaseKit v0.4.0 with module-release support. This is a planned tooling upgrade from the current v0.3.0 baseline, not an implemented CommandKit capability. Use ReleaseKit's public contracts for checking and publishing one explicitly selected module per invocation; do not build a separate CommandKit publication engine or temporary compatibility path.

Use one shared launcher with small per-module profiles. Each profile selects its repository-relative module directory and product identity; each invocation supplies that module's independently selected semantic version. ReleaseKit owns module-tag derivation, selected-module validation, repository publication guards, and publication outcomes. Root releases use unprefixed tags. Nested releases use their Go module-subdirectory prefixes, and notes belong at <module-directory>/docs/releases/<version>.md. Source and licensing links use the complete Git tag, while note titles identify the product and semantic version.

Run the selected module's standard suite once with workspace mode disabled and prepared dependencies. Repository cleanliness, branch, candidate commit, and endpoint guards remain repository-wide. A root-module release does not implicitly validate independently released nested modules; composition checks are selected deliberately where needed. Keep successful source-tag publication as completion, without CI, hosted delivery, proxy-availability, or installation gates.

CommandKit's preferred shared file inputs are repository-root COPYRIGHT, LICENSE, and docs/oss/attribution.md, when present, rather than the entire root docs/ tree. Use v0.4.0's validation.shared_files field to select those three files explicitly, as documented by ReleaseKit. Shared inputs affect enabled file checks, not Go suite scope; resolving references does not add surrounding directories to the inputs.

Keep module selection and profile lookup repository-relative, module-owned validation settings and product-command execution module-relative, and diagnostic paths repository-relative. Use the provided repository context for shared scripts. The released profile and CLI contracts govern profile fields, command syntax, module context, and shared-file selection. The implementation plan specifies their adoption; no separate publication engine is needed. Nested-module artifact builds, hosted delivery, and batch publication are not needed for CommandKit's source-only releases.

Consumer examples and validation target

Three maintained public consumers demonstrate the final API:

Adoption path Example home Required evidence
Core only examples/core Typed commands/groups, presence, help/version; no optional-library imports or module requirements
ConfigKit only integrations/ckconfig/examples/simple Focused AppCommand convenience and standard config reports; no PromptKit imports or module requirements
ConfigKit and PromptKit integrations/ckprompt/examples/composed Combined configuration scopes, typed applicable selectors, independent scope inputs, shared state, named definition inspection, and an application-owned command

Tests, fixtures, and benchmarks belong to the module owning their contracts. Mixed suites are split by responsibility; root tests and examples cannot reintroduce optional integration dependencies. Public composition checks belong in the PromptKit integration. Relevant existing coverage is retained or rewritten for selected behavior rather than incidental prototype API shapes.

Validation addresses package imports and each independently selected module graph, including transitive and tool requirements. Core-only consumers exclude both owning libraries and integrations; ConfigKit-only consumers exclude PromptKit and its integration. Root go test ./... alone cannot validate nested modules. The three modules' suites and representative public consumers provide composition evidence without an exhaustive historical compatibility matrix.

Local workspace composition supports development; distributed manifests contain versioned inter-module requirements, without filesystem replacements or committed workspace files. Workspace-off prepublication checks against local intended source establish wiring and isolation, not published-version availability. Released consumers resolve actual independently released versions without adjacent checkouts or consumer replacements. The implementation plan defines the prepublication checks and ordered release handoff.

Documentation and distribution target

Implemented GoDoc owns exact exports and error/lifetime semantics. The consumer guide and READMEs present the final imports and optional-module selection directly; maintained examples demonstrate it. The CLI reference retains selected operator behavior, with registration/ownership prose matching the implemented API. Internal inventory and contributor navigation describe implemented owners and validation. No separate downstream prototype migration guide is required.

Each integration distributes a module-local README, project grant, complete license texts, applicable attribution and required notices, and module-local release notes. Required licensing material remains available in that module's Go source distribution rather than only through an outside-module local link. The existing grant and separately licensed material retain their terms. Repository attribution can retain factual entries for integration material while module-local notices identify applicable components.

Modules use independent versions. The planned core replacement is v0.2.0; ckconfig and ckprompt initially use v0.1.0. Their dependency requirements express that relationship explicitly. The already published root v0.1.0 and its note remain intact. If a planned version is occupied before preparation, select a fresh appropriate version under the release policy. Core publication precedes ckconfig, which precedes ckprompt; actual released dependencies and corresponding sums are prepared for each candidate. Source-only publication still completes at successful tag publication, without proxy-availability or installation gates.

The release procedure and CommandKit-specific release-policy adaptations describe selected-module publication, independent versions, semantic-version note paths, full-tag links and recovery identity, and the root shared-file selection. Release profiles and launcher use released ReleaseKit contracts; additional delivery services and permanent migration gates are outside the target.

Implementation status

ADR/architecture alignment, public API design, and internal backend design are complete. Module extraction, code refactoring, maintained consumers, validation, current documentation, and multi-module tooling adoption are not implemented. The 16-stage implementation plan owns the sequence and completion evidence. Earlier accepted ADR decision text remains intact.

Scope and follow-up

This work changes packaging and integration boundaries. It does not select a new backend, concurrent-dispatch contract, dynamic plugin system, or replacement configuration engine. It does not lower the existing Go minimum.

Keep the PromptKit v0.13.0 and ConfigKit v0.6.0 adoption identifiable as a separate change after extraction unless an implementation dependency justifies combining them. Catalogs and requirement discovery are subsequent integration features. Semantic comparison retains the upstream-contract dependency recorded in deferred work. None is needed to demonstrate module isolation.