feat(contracts): package ecosystem — CharterPackageDescriptor + config.packages (#90 step 1)#211
Open
stackbilt-admin wants to merge 1 commit into
Open
feat(contracts): package ecosystem — CharterPackageDescriptor + config.packages (#90 step 1)#211stackbilt-admin wants to merge 1 commit into
stackbilt-admin wants to merge 1 commit into
Conversation
…ce + config.packages (#90 step 1) Names and contracts the decentralized package integration pattern for the Charter ecosystem. Step 1 of 5 (#90). Interfaces in @stackbilt/types: - SchemaValidator<T> — structural type satisfied by z.ZodType; lets descriptors declare a Zod config schema without importing Zod into @stackbilt/types (zero-dep constraint) - PackageDoctorCheck — { name, run(config, repoPath) → string | null }; null = pass, string = failure message - CharterPackageDescriptor<C> — the descriptor an ecosystem package ships: name, description, npmPackage, configSchema (SchemaValidator<C>), plus optional scaffoldTemplates, adfModule, doctorChecks, wranglerBindings. Descriptors live in the package repo, NOT in Charter (decentralized). Config extension (CharterConfig.packages): - packages?: Record<string, { enabled: boolean; config?: unknown }> - loadConfig() passes through the field unchanged; per-package config validation is deferred to the descriptor's configSchema at runtime - No default value (absent = no packages managed) Doctor check (charter doctor --adf-only): - When config.packages is non-empty, checks that each enabled package name is resolvable via require.resolve() from cwd (i.e. installed in node_modules) - PASS: all enabled packages installed - WARN: any enabled package missing (→ CI exit 1, "Run: npm install ...") - Absent config.packages → no check emitted (fully opt-in) Tests (9 new assertions across 2 files): - package-descriptor.test.ts: structural type coverage for all 3 interfaces; verifies both minimal and full implementations; safeParse type narrowing - doctor-loc-budget.test.ts: 4 integration tests for doctor packages check (absent config, resolvable built-in passes, missing pkg warns, disabled skipped) Does NOT implement: - Package registry / discovery (packages declare their own descriptors) - charter init package selection prompt (step 2+) - charter scaffold / adf populate integration (step 3+) - Per-package doctorChecks invocation (step 3; interface defined here for contract) Closes #90 (step 1) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Step 1 of #90: names and contracts the decentralized package integration pattern.
New interfaces in
@stackbilt/types(zero-dep, no Zod import):SchemaValidator<T>— structural type satisfied byz.ZodType; packages can declare a Zod config schema without importing Zod into@stackbilt/typesPackageDoctorCheck—{ name, run(config, repoPath) → Promise<string | null> }CharterPackageDescriptor<C>— the descriptor an ecosystem package ships:name,description,npmPackage,configSchema, plus optionalscaffoldTemplates,adfModule,doctorChecks,wranglerBindings. Descriptors live in the package repo, not in Charter (decentralized by design)Config extension (
CharterConfig.packages):packages?: Record<string, { enabled: boolean; config?: unknown }>loadConfig()passes through the field; per-package config validation deferred toconfigSchemaat runtimecharter doctorpackage check:config.packagesis non-empty, verifies each enabled package is resolvable (require.resolve) fromcwdnpm installhint; absent config → no checkOut of scope (steps 2–5)
charter initpackage selection promptcharter scaffold/adf populateintegrationdoctorChecksinvocation (interface defined; wiring is step 3)Test plan
pnpm run build— clean buildpnpm test— 694/694 (9 new: 5 structural type tests, 4 integration doctor tests)charter doctor --adf-onlywithpackages: { path: { enabled: true } }→ PASSpackages: { "@not/installed": { enabled: true } }→ WARN + exit 1Closes #90
🤖 Generated with Claude Code