@cat-factory/prompt-fragments

中文文档
1.1.82发布于 2026/11/06TypeScriptES Module构建来源已验证近 30 天下载 7193

Curated, versioned best-practice prompt fragments injected into agent system prompts.

原始使用文档
文档目录6 节
  1. What's here
  2. How it's used
  3. Two-tier bodies: body and brief
  4. Where a brief comes from at run time
  5. Programmatic deployment seams (custom fragments + per-task-…
  6. Adding a collection

@cat-factory/prompt-fragments

The built-in tier of best-practice prompt fragments: small, curated guidance snippets that get folded into an agent's system prompt at run time (composeSystemPrompt). This package is plain, build-static data: no I/O, no framework. It is the source of truth for the shipped defaults and the seed for the tenant-scoped prompt-fragment library.

What's here

  • src/collections/*.ts: fragments authored per topic. Today: node, react, acceptance, design, style, migration, deployment. Each exports an array of PromptFragment. Shipping a collection does NOT put it in front of an agent: a fragment reaches a run only by being SELECTED (a task's fragmentIds, a service frame's serviceFragmentIds, or a task-type default), so appliesTo narrows the management surface rather than gating a dispatch. deployment is opt-in for exactly that reason, and exports DEPLOYMENT_FRAGMENT_IDS so a deployment can name the set in one line.
  • src/index.ts: merges the collections into a single FRAGMENTS registry plus FRAGMENTS_BY_ID and getFragment(id) for O(1) lookup during composition.

A PromptFragment (shape defined in @cat-factory/contracts) carries an id, version, title, optional category, a summary (used by the relevance selector), the body (injected text), an optional condensed brief (see below), and an optional appliesTo hint (blockTypes / agentKinds).

How it's used

  • The Worker serves this catalog read-only at GET /prompt-fragments; the SPA shows it in the per-block fragment picker. GET /api/v1/prompt-fragments is the external counterpart, and answers from the MERGED tenant catalog rather than this pool: identity and metadata only, no body, so a headless caller can pick the standards a task is held to (public API).
  • A block stores selected fragmentIds[]; at run time core composes the chosen bodies into the system prompt. Each standard is folded as its own delimited, title-labelled block (<best-practice-standard id="…" title="…">) rather than one concatenated blob, so an agent can tell the standards apart and cite one by its title (composeSystemPrompt / composeBlockSystemPrompt in @cat-factory/agents). The code + PR review agents additionally report per-standard adherence (a 1–10 rating + related findings) back on the step, surfaced in run details.
  • When the optional library is enabled, this becomes the built-in tier of a three-tier merge (built-in ∪ account ∪ workspace); ids here can be shadowed or suppressed by higher tiers. See ADR 0006.

Two-tier bodies: body and brief

An implementer kind (coder / fixer / ci-fixer / conflict-resolver: the kinds carrying the brief-standards trait) runs a long agentic loop whose system prompt, standards included, is re-sent on every turn. Those kinds fold a fragment's optional brief (the same standard stated tersely) instead of its full body. Reviewer / planner / investigator kinds keep the full text: they run few turns and benefit from it when judging built work.

Two rules govern authoring one:

  • A brief must not drop a rule, only its elaboration. It is the same standard compressed, not a subset: an agent folding the brief is held to everything the body demands.
  • brief travels WITH the body it condenses and is never re-resolved by id downstream. A higher tier that overrides a built-in id supplies its OWN brief (or none), so the override's own text is folded, never the built-in's condensed text over a tenant's standard.

Omitting brief is always safe: the full body is used for every kind, unchanged. Fragments that can reach an implementer kind carry one; the ones scoped to spec-writer / playwright / document-authoring kinds (which are not implementers) deliberately do not.

Every fragment in this package is comfortably under FRAGMENT_BRIEF_MIN_BODY_CHARS, so the auto-condensation below never acts on the shipped catalog: keep it that way by writing a brief by hand when a built-in grows past ~1,500 characters.

Where a brief comes from at run time

The built-in brief above is only the first of three answers. For a fragment resolved through the tenant library (ADR 0006) the resolution order is:

  1. The winning tier's linked brief: a built-in's, or the one a tenant authored on its own managed row (the library editor's short-version field, or a repo-sourced guideline file's brief: frontmatter key).
  2. A model-GENERATED condensation, for a body over FRAGMENT_BRIEF_MIN_BODY_CHARS that has no linked brief. Produced once on the first implementer dispatch that folds it, persisted, and regenerated whenever the body changes: a library edit, a repo resync, or a living document re-resolved at run time.
  3. Nothing: the full body is folded for every kind, which is also where every failure on that path lands (no model wired, an unreadable store, a refused condensation).

Design, decisions and gotchas: docs/initiatives/auto-generated-fragment-briefs.md.

Programmatic deployment seams (custom fragments + per-task-type defaults)

A deployment (local or hosted) extends the fragment behaviour through the app-owned PromptFragmentRegistry (kernel), injected BY REFERENCE into the facade it builds. No fork, no rebuild, no per-workspace UI.

This replaced two MODULE GLOBALS (registerPromptFragment and registerTaskTypeDefaultFragments), and the reason is worth stating because it is invisible from inside this repo. Their correctness depended on every reader resolving the same physical copy of this package. A workspace:* dependency publishes as an EXACT version, so a consumer floating the range onto a newer patch gets TWO copies: the registration lands in one, the server reads the other, and every task of the deployment's operation is seeded with ids that fold nothing. The only signal was one boot warning, which is also the warning a typo produces.

  • Build the registry: promptFragmentRegistryWithBuiltins() (this package) news one carrying the shipped catalog and its built-in per-type defaults; defaultPromptFragmentRegistry() (kernel) news an EMPTY one, which is how a deployment says it wants only its own standards. The built-ins install through the registry's ordinary public methods, so the platform exercises a consumer's own seam on every boot and it cannot rot for consumers only.

  • Add custom fragments to the universal pool: registry.register(fragment) / registry.registerAll(fragments). Every GET /prompt-fragments catalog read and every run-time body lookup then sees them; re-registering an id REPLACES the entry of that id, so a deployment refines a shipped standard in place.

  • Mark fragments as the default for a BUILT-IN task type: registry.registerTaskTypeDefaults(taskType, fragmentIds). Every new task of that type (document, review, feature, …) is then seeded with those fragments onto its own fragmentIds at creation, beside whatever it inherits from its service. Seeding is server-side and authoritative: it applies even for tasks created via the public API with no create-form picker.

    Registering a type REPLACES its built-in set rather than unioning with it. The module-global seam unioned silently, which meant a deployment could not remove a shipped default however it wrote the call. Spread DEFAULT_DOCUMENT_STYLE_FRAGMENT_IDS into your own list to keep both, which says so in the code.

    A deployment's OWN (namespaced) task type does not use this seam. It declares defaultFragmentIds (and conditionalFragmentIds, for standing context that depends on the answers a case supplies) on its own registration, where boot validation can see the ids and warn on one the code pool does not resolve. That declaration is one third of a reusable operation: see backend/docs/reusable-operations.md.

  • A code-registered fragment may NOT carry a documentRef. Every code registration lands on the builtin tier, whose live resolution needs a connection workspace a deployment-wide registration cannot name, so boot REFUSES it (fragment_document_ref_unsupported) rather than carrying it, rendering it as live in the library UI, and ignoring it at run time (which is what it did). Register the body inline, or create the fragment at the ACCOUNT tier with a fetch-via workspace.

// deployment entry, before start()/startLocal()
import { promptFragmentRegistryWithBuiltins } from '@cat-factory/prompt-fragments'

const promptFragmentRegistry = promptFragmentRegistryWithBuiltins()
promptFragmentRegistry.registerAll([
  {
    id: 'org.review-checklist',
    version: '1.0.0',
    title: 'Review checklist',
    summary: 'Our PR review bar.',
    body: '- Check error handling…',
  },
])
// every new REVIEW task starts with this guidance
promptFragmentRegistry.registerTaskTypeDefaults('review', ['org.review-checklist'])

// …and the SAME instance goes into the facade, which is the whole point.
start({ promptFragmentRegistry /* …the rest */ })

In MOTHERSHIP mode the pool is read from the mothership, not from the node's own registry: the standards are org state, and a node one build behind would otherwise fold different guidance than the deployment registered. A failed read THROWS rather than answering with an empty pool, because "the mothership is unreachable" and "this deployment registers no standards" are the same value and opposite facts. Boot warns and names any fragments registered on a mothership-mode node.

Adding a collection

  1. Create src/collections/<topic>.ts and export an array of PromptFragment.
  2. Spread it into FRAGMENTS in src/index.ts.
  3. Keep ids globally unique and stable: blocks persist them, so a renamed id silently drops a selection (unknown ids are skipped, never error).
pnpm --filter @cat-factory/prompt-fragments build       # tsc → dist/
pnpm --filter @cat-factory/prompt-fragments typecheck

版本与发布记录

@cat-factory/prompt-fragments 共发布 453 个版本,首次发布于 2026/06/18;过去 12 个月发布了 453 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.1.82latest2026/11/062 天前
1.1.812026/11/045 天前
1.1.802026/11/045 天前
1.1.792026/11/045 天前
1.1.782026/11/045 天前
1.1.772026/11/045 天前

关于 @cat-factory/prompt-fragments 的常见问题

@cat-factory/prompt-fragments 是什么?

Curated, versioned best-practice prompt fragments injected into agent system prompts.

如何安装 @cat-factory/prompt-fragments?

在项目目录运行 npm install @cat-factory/prompt-fragments,或使用 pnpm add / yarn add / bun add。

@cat-factory/prompt-fragments 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cat-factory/prompt-fragments 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@cat-factory/prompt-fragments 可以商用吗?

@cat-factory/prompt-fragments 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@cat-factory/prompt-fragments 的下载量有多少?

根据 npm 官方下载统计,@cat-factory/prompt-fragments 在 2026/10/09 – 2026/11/07 这 30 天内被下载 7,193 次,日均约 240 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cat-factory/prompt-fragments 还在维护吗?

最新版本 1.1.82 发布于 2026/11/06(2 天前);至今共发布 453 个版本,其中过去 12 个月发布了 453 个;首次发布于 2026/06/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。