Skip to content

feat(contracts): package ecosystem — CharterPackageDescriptor + config.packages (#90 step 1)#211

Merged
stackbilt-admin merged 1 commit into
mainfrom
feat/package-ecosystem-contract
Jun 12, 2026
Merged

feat(contracts): package ecosystem — CharterPackageDescriptor + config.packages (#90 step 1)#211
stackbilt-admin merged 1 commit into
mainfrom
feat/package-ecosystem-contract

Conversation

@stackbilt-admin

Copy link
Copy Markdown
Member

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 by z.ZodType; packages can declare a Zod config schema without importing Zod into @stackbilt/types
  • PackageDoctorCheck{ name, run(config, repoPath) → Promise<string | null> }
  • CharterPackageDescriptor<C> — the descriptor an ecosystem package ships: name, description, npmPackage, configSchema, plus optional scaffoldTemplates, 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 to configSchema at runtime
  • No default — fully opt-in

charter doctor package check:

  • When config.packages is non-empty, verifies each enabled package is resolvable (require.resolve) from cwd
  • PASS → all installed; WARN → missing package + npm install hint; absent config → no check

Out of scope (steps 2–5)

  • Package registry / discovery (packages declare their own descriptors)
  • charter init package selection prompt
  • charter scaffold / adf populate integration
  • Per-package doctorChecks invocation (interface defined; wiring is step 3)

Test plan

  • pnpm run build — clean build
  • pnpm test — 694/694 (9 new: 5 structural type tests, 4 integration doctor tests)
  • charter doctor --adf-only with packages: { path: { enabled: true } } → PASS
  • Same with packages: { "@not/installed": { enabled: true } } → WARN + exit 1

Closes #90

🤖 Generated with Claude Code

…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>
@stackbilt-admin stackbilt-admin merged commit 38643bb into main Jun 12, 2026
5 checks passed
@stackbilt-admin stackbilt-admin deleted the feat/package-ecosystem-contract branch June 12, 2026 09:59
Sign up for free to 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.

feat: package ecosystem — configurable dependency orchestration via charter config

1 participant