@forgrit/shared

中文文档
0.3.0发布于 2026/09/26MITTypeScriptESM + CJS零依赖近 30 天下载 2847

ForGrit的三套回放(Software Foundry, Software Orchestrator, Workforce)的跨柱共享基础设施:一个散列链式的证据分类账和韧性原始(retry,断路器,速率限制器).

中文使用文档
文档目录15 节
  1. 什么不属于这里
  2. 目的
  3. 子路径导出
  4. @forgrit/shared/design-system
  5. @forgrit/shared/engineering-contract
  6. @forgrit/shared/evidence
  7. @forgrit/shared/resilience
  8. 安装
  9. 发展
  10. 核查
  11. 排雷中心/发改委
  12. 发布政策
  13. 兄弟姐妹项目
  14. 使用量
  15. 许可证

@ forgrit/ 共享

跨支柱合同和软件创始人、软件Orchestrator和劳动力使用的复原力原始.

状态 : 活动内部软件包( E)0.3.0 在清单中,尚未公布 0.2.0· 运行时间 : 节点.js 20+- 拥有者 : @forgrit-legacy (法语) • 妇女 CI: 爱奇艺 默认分支管道

什么不属于这里

这个一揽子方案范围很广,只是跨repo基础设施,而不是一个倾倒地。 明确排除在外(见 docs/superpowers/plans/2026-08-17-software-foundry-rename-and-shared-package.md充分推理的全球制约因素:

  • 软件 Orchestrator的实际管弦乐智能(mission-control, (中文(简体) ), kernel, (中文(简体) ), planner, (中文(简体) ), execution, (中文(简体) ), brain, (中文(简体) ), repository-* 模块)
  • 软件创始公司的产品引擎(blueprint, (中文(简体) ), codegen-types, (中文(简体) ), debugger, (中文(简体) ), design-*, (中文(简体) ), shared/contracts-prompt(中文(简体) )
  • B. 职工队伍的员工-治理模式Principal, (中文(简体) ), RoleCard, (中文(简体) ), authorize()(中文(简体) )
  • 仓库情报"冻结五"合同(图)Snapshot编号 :Finding编号 :Metric编号 :Relationship编号 :Insight) ——在其自身的阶段性促进规则后入门,尚未就绪
  • software-orchestrator/modules/orchestrator/connector-runtime/RetryPolicy.ts 或者说 RateLimiter.ts 作为要复制的来源材料( 双方都知道编译- 错误; 此软件包的) resilience 模块使用其设计理念,而不是其代码)

目的

这个软件包是 不是倾倒场 用于通用代码。 它只容纳基础设施类型和原始:

  • 消耗于 不止一个兄弟重播 (基金会、兽医或劳动力)
  • 携带交叉重排的不变量(例如证据分类账记录结构)
  • 不属于任何单一支柱的代码库

所有新的出口都需要有证据表明至少有两个消费者有这种需要.

子路径导出

@forgrit/shared/design-system

ForGrit设计接通管道:Claude设计套件的不可改变的牵引修改, 角色合同.

潜行路线是什么

导入这是什么
@forgrit/shared/design-system/css/tokens.css简单的 CSS : :root 财务报告和审定财务报表 .dark 自定义属性, 无框架 .
@forgrit/shared/design-system/css/tailwind4.css同样的同物加一尾风4 @theme inline 块形别名.
@forgrit/shared/design-system/tailwind3-preset尾风3预设—— theme.extend,其价值为 var(--token) 参考文献.
@forgrit/shared/design-system/tokens.json每一个发射的指使作为数据,有一个 $generated 来源字符串 .
@forgrit/shared/design-system/tokens与打入的 TypeScript 常数相同, DS。 。 。 .
@forgrit/shared/design-system/contract74个作用合同—— ROLES, (中文(简体) ), ROLE_IDS, (中文(简体) ), getRole, (中文(简体) ), assertKnownRole。 。 。 .
@forgrit/shared/design-system/adapters/contractadaptTokenSystem ——设计总监给角色合同的标语.
@forgrit/shared/design-systemDESIGN_SYSTEM_SCHEMA_VERSION 和共享类型.
forgrit-ds (单位:千美元)bin(中文(简体) )国家行动倡议: pull --seal, (中文(简体) ), diff, (中文(简体) ), emit, (中文(简体) ), sync, (中文(简体) ), check, (中文(简体) ), report, (中文(简体) ), assert-publishable。 。 。 .

每个生成的文件都带有相同的一行标题—— @generated by @forgrit/shared/design-system <version> from <family>/<revision> sha256:<contentHash> – 在 CSS 注释中, TypeScript 注释或 JSON $generated 字段,所以任何寄存器中的任何动画名称都包含它来自的修订.

修订模式

修订是一次写而从未重写过的目录 : src/design-system/revisions/<family>/r<NNN>/,握取的字节(colors_and_type.css, (中文(简体) ), _ds_manifest.json)和a 数据 revision.json 谁 contentHash 是一个SHA -256 上面的峡谷JSON 排序 [{path, sha256}] 文件显示 —— 设计 - 公司规则, 所以修正的散列 这里和那里都是一样的. CURRENT 是一个单行文件,命名软件包生成的修订版,以及 design-sync.jsonl 是一个仅作为附件的来回记录 push, (中文(简体) ), pull, (中文(简体) ), validate, (中文(简体) ), reject, (中文(简体) ), seal。 。 。 . pull --seal 记录 pull (从拉出自己的) .pull.json (收条)和 seal; 传出 check 从检出记录中运行 validate。每个步骤每次修改和内容散列都会被记录一次,所以在任何一天重新运行它都无任何附加,对修改的散列有不同意见的行会被拒绝而不是附加. 重运行 pull --seal 在相同的字节中键出0并写出无;在密封的正文中新字节被拒绝。 更改已封存的修订版的字节被 revision-immutability 而不是由审查员.

CURRENT 名称 r001,从克洛德设计:出处提取的第一修订版 design-sync父关 r000,于2026-09-25被美国 设计同步运行本,这也记录了拉力是如何进行的。 它的样式表仍然带有工具包本身的行距注释("从web/src/app/globals.cs和布局.tsx中摘录");出处是这些字节从哪里拉出,而不是工具包的作者先取出值的地方. r000 留在树上,字节换字节不变,作为 r001父亲 它只是暂时的:其出处是: local-copy,意思是字节是用手复制而不是取出. forgrit-ds assert-publishable (哪个) prepublishOnly 运行时拒绝发布 CURRENT 名称 a local-copy 修订,以及 emit, (中文(简体) ), sync 财务报告和审定财务报表 check 拒绝一个,除非 --allow-local-copy 通过. report 故意不——描述一棵树的漂移就是漂移报告的目的,不管修改的出处是什么.

修订字节按设计是公开的. 在已出版的套装内装有密封的修改船,所以当套装出版时,一个中的所有东西都是世界可读的. 设计标志是预定的有效载荷;修订目录中没有任何其他内容.

消费者流动

npx forgrit-ds sync --root /path/to/consumer-repo   # write the generated files
npx forgrit-ds check --root /path/to/consumer-repo  # byte-diff them, and run all seven gates

sync 将 profile 目标写入消费者树中——生成的文件 承诺 给消费者寄存器,所以一个建筑从来不取决于 这个软件包已经运行. check 将相同的目标再生入内存,并用磁盘上的东西来比作它们,这就是消费者的CI应该运行的来证明没有人手编辑出一个生成的代币. 命令都没有在目标列表之外写任何东西.

可选约束行仅在修改作者时才出出. --ember-strong 编辑 --ember-fill* 三合会是 optional 因为 r000 从来没有写过. r001 是否为 -- --ember-strong #B84C00 (单位:千美元)#FF6A00 内 .dark, (中文(简体) ), --ember-fill #B84C00, (中文(简体) ), --ember-fill-hover #C25000, (中文(简体) ), --ember-fill-active #A34400 - 所以,现在包 释放出所有四个 与工具包自己的价值。 规则仍然决定了删除这些内容的修订将会发生什么: 对 具有价值——合同从 color.brand ——并排放回落将发表 #FF6A00 以一个名字 修改从来没有写。 这会非常有害: #FF6A00 在白色上测量2.87:1,在体积上没有达到WCAG AA,这就是为什么这个包是自己的 --ember-fill 实值 #B84C00。因此,一个可选行,其价值来自合同倒置,但被跳过,并且只释放出修改本身所撰写的价值.

漂流

forgrit-ds report --root <foundryRoot> [--orchestrator-root <dir>] 在两个主题中,将消费者声明反对运出的修订的定制财产分类。 运出货物的测量结果 r001 发生在 docs/design-system/drift-r001.md; 较早的计量比对 r000 留在原点 docs/design-system/drift-r000.md。 。 。 .

未涵盖(延迟)

0阶段停在可复制的代号管上. 没错 没有 做以下任何一件事,他们中没有一个被它所阻挡:

  • 从修订版中再生成光栅资产
  • cI 中的视觉基线
  • 重新构建消费者的阴影 oklch() 脚手架插入工具包值
  • 宣传 rgb()编号 :hsl()编号 :oklch() 从咨询到门的值格式图示
  • 航运 woff2 软件包中的字体二进制
  • forGrit 应用程序的溢价主题( 今天只使用公司)
  • 打开一个版本列 DesignCapsuleVersion 编号 : FrozenScreen
  • 页:1 apps/api 预览道
  • CI 边从运行中的应用程序提取令牌
  • DTCG (中文(简体) )design-tokens.json)出口
  • 自动出版——手册

@forgrit/shared/engineering-contract

客户控制飞机和劳动力共用的版本授权有效载荷 软件Orchestrator的呼叫者. parseExecutionTicket() 未信任的验证 解码输入,拒绝未知字段(包括原始证书),执行 发行方/主要配对和到期,并返回防御投影.

签字核查、非ce/免疫力持续、储存库摘要 重算和证书中介仍然是接受人的责任 共享包定义了可互操作的有效载荷,而不是假装计划 验证是认证.

@forgrit/shared/evidence

用于记录系统决定和副作用的散列分类账。 每个记录都存储着SHA -256散列 超乎其前身的散列 所以编辑任何历史记录 verifyChain 报告具体位置.

这给你什么,它没有

精确地说出担保财产,因为担保的形状决定了该分类账在何处值得部署:

  • 散地无取取取. 这里没有签名 没有HMAC,没有钥匙,没有签名——只有SHA-256在犬科序列化上.
  • 记录并非不可改变. 它们都是普通的JavaScript对象. readonly 出现在数组中 参数 并限制此软件包本身的功能; 它不会冻结呼叫者持有的任何东西.
  • 它检测到部分编辑. 一个演员重写一个存储的唱片——或几个——而留下剩下的则被抓住:重编的散列车不再匹配了,而后来的每一次都会被捕获 prevHash 链接是错误的.
  • 它没有停止一个完整的重写. 一个可以改写的演员 整体 被存储的分类账可以从编辑中重算出每条散列向前并产生一个可以验证干净的链. 这样一个作家在一条没有钥匙的链条中,没有什么是无法复制的.

所以这是篡改 -明显 而不是一个签名计划。 其真实价值来自于将它与一个仅能限制谁可以重写历史的附加存储层相配:存储层使批发重写变得硬化,而链条则使得任何小于批发重写的东西都可见. 它本身就是一个腐败探测器.

变化因素

  • seq 是0指数化的. 链子上的第一个事件是 seq: 0 与 prevHash: GENESIS_HASH;以后的每个事件都有 seq === previous.seq + 1 财务报告和审定财务报表 prevHash === previous.hash。 。 。 .
  • 散列预想是一个清晰的,版本化的字段投影 —— 说 v, (中文(简体) ), seq, (中文(简体) ), prevHash, (中文(简体) ), type, (中文(简体) ), subjectId, (中文(简体) ), actorId, (中文(简体) ), payload, (中文(简体) ), observedAt ——无论呼叫者通过什么,从不分散. 存储记录上的额外字段(一行代号,一ORM自有的列)不在链条的保护范围外,不能扰动重算的散列. HASH_VERSION 因此,未来改变投影是可以区分的,而不是沉默的不相容的.
  • payload 一定是JSON安全. appendEvent 掷出 InvalidEvidenceEventError 价值,其冠状会失去—— Date, (中文(简体) ), Map, (中文(简体) ), Set, (中文(简体) ), RegExp, (中文(简体) ), Error,类实例, NaN编号 :Infinity, (中文(简体) ), bigint。先转换 : date.toISOString(), (中文(简体) ), Object.fromEntries(map), (中文(简体) ), { name, message } 对于一个错误。 这是故意的:a Date 用于序列化为 {}因此,有两张记录 时间戳相距数十年的花销相同.
import { appendEvent, verifyChain, type EvidenceEvent } from '@forgrit/shared/evidence';

let chain: EvidenceEvent[] = [];

// A null head starts a chain: seq 0, prevHash = GENESIS_HASH.
chain = [...chain, appendEvent(null, {
  type: 'mission.completed', subjectId: 'mission-1', actorId: 'employee-1',
  payload: { outcome: 'success' }, observedAt: new Date().toISOString(),
})];

// Afterwards, pass the head — just `{ seq, hash }`, not the whole history, so a
// database-backed caller appends after reading a single row. An EvidenceEvent
// satisfies that shape, so the previous event can be handed over directly.
chain = [...chain, appendEvent(chain[chain.length - 1], {
  type: 'mission.archived', subjectId: 'mission-1', actorId: 'employee-1',
  payload: { reason: 'completed' }, observedAt: new Date().toISOString(),
})];

verifyChain(chain); // { valid: true, length: 2 }

校验长分类账中间的一页,而不是装入全部:

verifyChain(pageOfRows, {
  expectedFirstSeq: 1000,
  expectedFirstPrevHash: lastRowOfPreviousPage.hash,
});

没有选择, verifyChain 锚在 seq: 0 编号 : GENESIS_HASH 并验证整个链条.

@forgrit/shared/resilience

分布式系统的回弹原生:用指数回放,断路器再试,并用符号-bucket速率限制器.

import { withRetry, CircuitBreaker, isTransientError } from '@forgrit/shared/resilience';

const breaker = new CircuitBreaker({ name: 'external-api', failureThreshold: 5 });

async function callApi(): Promise<Response> {
  return breaker.execute(() =>
    withRetry(() => fetch('https://api.example.com'), { maxAttempts: 3 }),
  );
}

重试分类. withRetry 重试什么 isTransientError 接受: ECONNREFUSED, (中文(简体) ), ECONNRESET, (中文(简体) ), ETIMEDOUT, (中文(简体) ), ENOTFOUND, (中文(简体) ), EAI_AGAIN它读取一个结构化的 error.code 首先倒回消息文本,但只有代码处于机器写出的位置——所以 new Error('user typed ETIMEDOUT into the form') 实值 没有 作为网络超时处理。 它也走着 cause 链条(和 AggregateError.errors),这就是使 fetch 工作上的例子: 节点抛出 TypeError: fetch failed 并输入真实的网络错误 cause中,只检查消息就找不到它.

ENOMEM 财务报告和审定财务报表 ENOSPC 故意的 故意的 没有 重试——内存和磁盘耗尽并不清楚,因为一个呼叫者再次尝试,重试会给一个已经出资源的主机加载.

供应 isRetryable 来为自己的错误分类。 这个 替换 内置检查而不是扩展; 呼叫 isTransientError 在你的上游 保持两个:

await withRetry(fn, {
  isRetryable: (error) => isTransientError(error) || isRateLimited(error),
});

电路断路器探测器限制 . 虽然 HALF_OPEN破解者最多承认 halfOpenMaxProbes 一次呼叫( 默认 : halfOpenSuccessThreshold),以及 canExecute() 返回时 false 直到电路转换 计数是探测器 飞行中 - 获准和尚未通过 recordSuccess编号 :recordFailure。 。 。 .

已知限制 : 探测器从不结算(呼叫者从不报告其结果——例如,它悬挂时不超时——)将固定其位置。 如果探测器够用 halfOpenMaxProbes电路被接入 HALF_OPEN 无限期地,没有基于时间的恢复——只是明确 reset() 释出. 给每个你驾驶的探测器 通过突破器 自己的时间,所以它总是解决.

安装

npm install @forgrit/shared

发展

使用节点.js 20或后. 在修改前安装锁定的开发依赖 :

npm ci

使用特性分支并打开合并请求,而不是直接推动到 main。见 捐款额 用于贡献工作流程.

核查

在打开合并请求前运行完整的本地门 :

npm run build
npm test
npm pack --dry-run

排雷中心/发改委

这个 默认分支管道 验证包件的构建和测试. 它不发布软件包.

发布政策

出版仍然是手工的。 维护者使用 npm pack --dry-run 财务报告和审定财务报表 仅在要求的验证成功后公布.

兄弟姐妹项目

使用量

每个子路径可独立导入 :

// Import from design-system subpath
import { DESIGN_SYSTEM_SCHEMA_VERSION } from '@forgrit/shared/design-system';
import { ROLES, getRole } from '@forgrit/shared/design-system/contract';
import { DS } from '@forgrit/shared/design-system/tokens';
import '@forgrit/shared/design-system/css/tokens.css';

// Import from evidence subpath
import { /* ... */ } from '@forgrit/shared/evidence';

// Import from resilience subpath
import { /* ... */ } from '@forgrit/shared/resilience';

// Import from engineering-contract subpath
import { parseExecutionTicket } from '@forgrit/shared/engineering-contract';

没有根导出: 上面的每个入口都是子路径, 所以 require('@forgrit/shared') 失败 ERR_PACKAGE_PATH_NOT_EXPORTED 根据设计.

许可证

麻省理工学院——见 自由主义。 。 。 .

版本与发布记录

@forgrit/shared 共发布 3 个版本,首次发布于 2026/08/17;过去 12 个月发布了 3 个版本。

版本发布日期距今
0.3.0latest2026/09/261 个月前
0.2.02026/08/192 个月前
0.1.02026/08/172 个月前

关于 @forgrit/shared 的常见问题

@forgrit/shared 是什么?

ForGrit的三套回放(Software Foundry, Software Orchestrator, Workforce)的跨柱共享基础设施:一个散列链式的证据分类账和韧性原始(retry,断路器,速率限制器).

如何安装 @forgrit/shared?

在项目目录运行 npm install @forgrit/shared,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 forgrit-ds,可以用 npx forgrit-ds 直接运行。

@forgrit/shared 支持 TypeScript 吗?

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

@forgrit/shared 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@forgrit/shared 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@forgrit/shared 可以商用吗?

@forgrit/shared 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@forgrit/shared 的下载量有多少?

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

@forgrit/shared 还在维护吗?

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