{"_id":"@semeno/core","_rev":"2-8a7d5ff2941492099fddc55fbe5f0173","name":"@semeno/core","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@semeno/core","version":"0.1.0","keywords":["seed","seeding","fixtures","scenarios","database","cli","agent"],"license":"MIT","_id":"@semeno/core@0.1.0","maintainers":[{"name":"vparys","email":"vojtech.parys@gmail.com"}],"homepage":"https://github.com/contember/semeno#readme","bugs":{"url":"https://github.com/contember/semeno/issues"},"bin":{"semeno":"bin/semeno.ts"},"dist":{"shasum":"5ab8e96542359d5236e66f26bd021c8c95926d38","tarball":"https://registry.npmjs.org/@semeno/core/-/core-0.1.0.tgz","fileCount":13,"integrity":"sha512-vCb+hr8Ua47RSbkfmRnqQW1BhDGMChzyYixJH4Bp8ckn0P8TWWm+yut0cKA6vvauh84OF5W/VdVZdZzXy6mDyw==","signatures":[{"sig":"MEQCIE7URdTTnC520nLLBnerfEawkdN18RUga4WHM7aVpHF8AiA91eM4GLzerLgnZBvL2mZzqeOlk/tegdxHNIpC2TvmuA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":51810},"type":"module","engines":{"bun":">=1.1.0"},"exports":{".":"./src/index.ts"},"gitHead":"95b4862213c7c28b76ba147fee22bbb87f21e966","scripts":{"lint":"oxlint src bin tests","test":"bun test","typecheck":"tsc --noEmit"},"_npmUser":{"name":"vparys","email":"vojtech.parys@gmail.com"},"repository":{"url":"git+https://github.com/contember/semeno.git","type":"git"},"_npmVersion":"10.9.0","description":"Seed scenario manager — named, idempotent, scoped, dependency-aware database seeds with an agent-friendly CLI","directories":{},"_nodeVersion":"22.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxlint":"^1.0.0","@types/bun":"^1.2.0","typescript":"^5.7.0"},"_npmOperationalInternal":{"tmp":"tmp/core_0.1.0_1781091294858_0.1589181779218729","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@semeno/core","version":"0.1.1","description":"Seed scenario manager — named, idempotent, scoped, dependency-aware database seeds with an agent-friendly CLI","keywords":["seed","seeding","fixtures","scenarios","database","cli","agent"],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/contember/semeno.git"},"publishConfig":{"access":"public"},"type":"module","bin":{"semeno":"bin/semeno.ts"},"exports":{".":"./src/index.ts"},"engines":{"bun":">=1.1.0"},"scripts":{"test":"bun test","lint":"oxlint src bin tests","typecheck":"tsc --noEmit"},"devDependencies":{"@types/bun":"^1.2.0","oxlint":"^1.0.0","typescript":"^5.7.0"},"gitHead":"4059be0b2619d125405dbd0a8e525f304a54eb79","_id":"@semeno/core@0.1.1","bugs":{"url":"https://github.com/contember/semeno/issues"},"homepage":"https://github.com/contember/semeno#readme","_nodeVersion":"24.16.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-fQjP1+03n2ZZEdWUG6zxPypYQBcG29XKQNMjioMnT0qGgr552AYHSN3714uyp59qQPU1OzzBDhcORu/83Ez6gw==","shasum":"5af6559889d936689f7b65ad04bb7dd0fbf36968","tarball":"https://registry.npmjs.org/@semeno/core/-/core-0.1.1.tgz","fileCount":13,"unpackedSize":52139,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@semeno%2fcore@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDWHWsb8Dee4cze9OwjwiQ/OPKXZ0kV5CGrKrDOU9C6OAIgMNttKcE+hDQux378PG0mjg2eTmcR4ncYDBygZW8gCfE="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:9d6d8d5a-c1d3-4496-8e00-1860fa398d47"}},"directories":{},"maintainers":[{"name":"vparys","email":"vojtech.parys@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/core_0.1.1_1781161411192_0.879265390373904"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-10T11:34:54.643Z","modified":"2026-06-11T07:03:31.670Z","0.1.0":"2026-06-10T11:34:55.009Z","0.1.1":"2026-06-11T07:03:31.373Z"},"bugs":{"url":"https://github.com/contember/semeno/issues"},"license":"MIT","homepage":"https://github.com/contember/semeno#readme","keywords":["seed","seeding","fixtures","scenarios","database","cli","agent"],"repository":{"type":"git","url":"git+https://github.com/contember/semeno.git"},"description":"Seed scenario manager — named, idempotent, scoped, dependency-aware database seeds with an agent-friendly CLI","maintainers":[{"name":"vparys","email":"vojtech.parys@gmail.com"}],"readme":"# semeno 🌱\n\nSeed scenario manager — named, idempotent, scoped, dependency-aware\ndatabase seeds with an agent-friendly CLI.\n\n`semeno` is the framework around your seeds, not your database client.\nYou bring the clients (any ORM, GraphQL API, plain SQL); semeno gives\nevery project the same vocabulary and tooling:\n\n- **Named seeds** with two kinds: `foundational` (reference data the app\n  needs) and `scenario` (a complete demo state for QA, E2E suites or AI\n  agents, with a `reset` hook).\n- **Scopes** — tag seeds by business stream (`edu`, `crm`, …) and run\n  just one stream: `semeno run all --scope edu`.\n- **Dependencies** — seeds declare `dependsOn`; the CLI resolves the\n  transitive closure and runs it in topological order. CI shrinks from a\n  hand-maintained list of invocations to one command.\n- **Targets** — named environments (local/staging/prod) with secrets\n  resolved from env vars and typed confirmation before touching anything\n  protected.\n- **Agent-friendly** — `--json` everywhere, self-describing seeds,\n  `plan`/`validate` commands, and a Claude Code skill installed by\n  `semeno init` that teaches agents the seed contract.\n\nRequires [Bun](https://bun.sh) (the config is TypeScript, imported natively).\n\n## Quick start\n\n```bash\nbun add -d @semeno/core\nbunx semeno init          # scaffolds semeno.config.ts, seeds/, .claude/skills/semeno/\nbunx semeno list\nbunx semeno run example-seed\n```\n\n## The seed contract\n\n```ts\n// seeds/approved-program.ts\nimport { seedHelper } from '@semeno/core'\nimport type { SeedContext } from '../semeno.config'\n\nconst defineSeed = seedHelper<SeedContext>()\n\nexport const approvedProgram = defineSeed({\n\tname: 'approved-program',\n\tkind: 'scenario',\n\tscope: 'edu',\n\tdependsOn: ['initial-data'],\n\trequires: ['content', 'rpc'],\n\tdescription: 'Approved education program with one open session. '\n\t\t+ 'State the exact end state here — humans and agents pick seeds by this text.',\n\trun: async ctx => { /* idempotent writes via ctx clients */ },\n\treset: async ctx => { /* delete own artefacts, dependency order */ },\n})\n```\n\n`run` must be idempotent — safe to re-run on an already-seeded database.\n`reset` removes only this seed's artefacts. Deterministic IDs (e.g. a\n`5eed…` UUID prefix) make both easy and the rows recognizable.\n\n## The config\n\n```ts\n// semeno.config.ts\nimport { defineConfig } from '@semeno/core'\n\nexport type SeedContext = { content: MyClient; rpc: (m: string, i: unknown) => Promise<unknown> }\n\nexport default defineConfig<SeedContext>({\n\tscopes: ['edu', 'crm'],\n\tseeds: [initialData, approvedProgram /* … */],\n\ttargets: {\n\t\tlocal: {\n\t\t\tendpoints: { content: 'http://localhost:1481/content/app/live', rpc: 'http://localhost:5173/rpc' },\n\t\t\tsecrets: { token: '0000…' },                  // inline only for local dev\n\t\t},\n\t\tstaging: {\n\t\t\tendpoints: { content: 'https://engine.staging.example.com/content/app/live', rpc: 'https://api.staging.example.com/rpc' },\n\t\t\tsecretsFromEnv: { token: 'SEED_STAGING_TOKEN' }, // env var NAME, resolved lazily\n\t\t},\n\t},\n\tcreateContext: target => ({\n\t\tcontent: new MyClient(target.endpoints.content!, target.secrets.token!),\n\t\trpc: makeRpc(target.endpoints.rpc!, target.secrets.token!),\n\t}),\n})\n```\n\nTargets whose endpoints are not all localhost are **protected** by\ndefault: `run`/`reset` print the URLs the selected seeds touch and ask\nyou to type the target name. `--yes` skips the prompt (CI).\n\n## CLI\n\n```\nsemeno list [--scope <s>] [--json]          list seeds, grouped by kind + scope\nsemeno info <name> [--json]                 description, deps, dependents\nsemeno plan [name…|all] [--json]            execution order, nothing runs\nsemeno run  [name…|all] [flags]             apply (deps first, topological)\nsemeno reset <name…|all> [flags]            tear down (reverse order, deps untouched)\nsemeno validate [--strict] [--json]         cycles, unknown deps, undeclared scopes…\nsemeno init [--force|--skill-only]          scaffold project files + agent skill\n```\n\nSelection: `--scope <s>` (shared scope-less seeds always match),\n`--no-deps`, `--reset` (tear the requested seeds down before the run —\npulled-in dependencies are never reset), `--dry-run`.\nTargets: `--target <name>`, `--endpoint k=url`, `--setting k=v`,\n`--secret k=v`, `--yes`.\n\n`run --json` streams JSONL events (`seed:start`, `seed:done`,\n`seed:skip`, `seed:error`) followed by a summary document. Exit codes:\n`0` ok, `1` failure, `2` usage error.\n\n## CI\n\nOne line replaces a hand-ordered list of seed invocations:\n\n```yaml\n- run: bunx semeno run all --scope edu --yes\n```\n\nDependencies guarantee the order; idempotency guarantees re-runs are safe.\n\n## For AI agents\n\n`semeno init` installs `.claude/skills/semeno/SKILL.md` into the host\nproject — the authoring guide (contract, patterns, verification loop).\nAgents orient with `list --json`, `info <name> --json` and `plan --json`\ninstead of reading seed implementations.\n\n## Programmatic API\n\nEverything the CLI does is exported from `@semeno/core`: `defineConfig`,\n`defineSeed`, `seedHelper`, `planRun`, `executePlan`, `validateConfig`,\n`resolveTarget`, `loadConfig`, …\n\n## License\n\nMIT\n","readmeFilename":"README.md"}