Files
agentic-dev/packages/core-shared/src/conformance/define-feature.ts
Danijel Martinek 0ee0355f5e feat(core-shared): add analyticsEvents field to UseCaseManifest
Add optional `analyticsEvents?: readonly string[]` to `UseCaseManifest`
in `define-feature.ts` so manifests can declare which analytics events a
use case emits. Field defaults to absent (treated as []) — all existing
manifests remain valid without changes.

Update the feature generator template to emit `analyticsEvents: []` so
newly scaffolded features are analytics-declaration-ready from day one.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 11:57:49 +00:00

47 lines
1.7 KiB
TypeScript

import type { CoverageManifest } from "./coverage";
/**
* Per-use-case manifest entry. Declares what the use case does at the contract
* level: whether it mutates state, what audit events it emits, what cross-feature
* events it publishes or consumes. The conformance system reads these to
* derive binding-slot types and to verify code against manifest declarations.
*/
export type UseCaseManifest = {
readonly mutates: boolean;
readonly audits: readonly string[];
readonly publishes: readonly string[];
readonly consumes: readonly string[];
readonly analyticsEvents?: readonly string[];
};
/**
* The feature-level manifest. One per feature package, conventionally exported
* as `<featureName>Manifest` from `src/feature.manifest.ts`.
*
* `coverage` is optional for backward compatibility — features without a
* declared coverage section fall back to `DEFAULT_COVERAGE_BANDS` via
* `getCoverageBands(manifest)` (see `./coverage.ts`).
*/
export type FeatureManifest = {
readonly name: string;
readonly requiredCores: readonly string[];
readonly useCases: { readonly [k: string]: UseCaseManifest };
readonly realtimeChannels: readonly string[];
readonly jobs: readonly string[];
readonly coverage?: CoverageManifest;
};
/**
* Identity helper that exists purely to widen the input type to satisfy
* `FeatureManifest` while preserving the literal types of the `as const`
* input. Downstream types (`ProductionUseCase<I, O, M>`) consume the
* preserved literals to derive binding-slot brand requirements.
*
* Usage:
*
* export const authManifest = defineFeature({ name: "auth", ... } as const);
*/
export function defineFeature<const M extends FeatureManifest>(manifest: M): M {
return manifest;
}