Files
agentic-dev/packages/core-eslint/rules/feature-must-have-manifest.js
Danijel Martinek f77e6ea881 chore(template): clean-slate template snapshot from bb4a0c7
Curated, product-agnostic snapshot of the post-story-04 tree: demo
content deleted, auth-only reference feature, web-next shell, all gates
green. Product-specific docs, ADRs 027-029, PRDs/epics/archive, editor
library traces, and product naming are curated out; generic template
repairs (coverage provider devDeps, root test:coverage script, live
lint fixes, root-only release-please) are kept. See TEMPLATE.md for
provenance, curation list, and usage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
2026-07-12 20:40:54 +02:00

56 lines
1.6 KiB
JavaScript

import fs from "node:fs";
import {
manifestPathForFeature,
featureRootForFile,
} from "./_manifest-source.js";
/** @type {import("eslint").Rule.RuleModule} */
export default {
meta: {
type: "problem",
docs: {
description:
"Every feature with use-case files must declare a feature.manifest.ts at its src/ root.",
},
schema: [
{
type: "object",
properties: {
repoRoot: { type: "string" },
},
additionalProperties: false,
},
],
messages: {
missingManifest:
"Feature {{feature}} has use cases but no feature.manifest.ts. Run `pnpm turbo gen feature {{feature}}` or scaffold the manifest manually at {{expected}}.",
},
},
create(context) {
const opts = context.options[0] ?? {};
const repoRoot = opts.repoRoot ?? context.cwd ?? process.cwd();
return {
Program(node) {
const filename = context.filename;
const featureRoot = featureRootForFile(filename, repoRoot);
if (!featureRoot) return;
// Only check use-case files
if (
!filename.includes("/application/use-cases/") ||
!filename.endsWith(".use-case.ts")
) {
return;
}
const manifestPath = manifestPathForFeature(featureRoot);
if (fs.existsSync(manifestPath)) return;
const featureName = featureRoot.split("/").pop();
context.report({
node,
messageId: "missingManifest",
data: { feature: featureName, expected: manifestPath },
});
},
};
},
};