@aurelienbn/ agentlint-plugin-xstate (英语)
XState v5和v6 alpha的7个代理林特评论(与 @xstate/effect:每个演员都有主人公,每个失败的路径,每个坚持的快照一个版本.
v6 支持被选中
[email protected]财务报告和审定财务报表@xstate/[email protected];α APIs可以在发行间移动.
[尖叫声] 需要引擎
@aurelienbbn/agentlint>=0.3.0 <0.9.0作为同伴. 证据。 。 。 .
oxlint-plugin-xstate mechanical, setup-aware checks
agentlint-plugin-xstate review questions a linter can't decide ◀── you are here
eslint-plugin-xstate doesn't analyse setup().createMachine() machines
快开始
agentlint init --preset "@aurelienbbn/agentlint-plugin-xstate#starterPreset"
agentlint rules test
agentlint rules scan --review
agentlint next --format json
init 保存已有的配置并打印安装命令;从未安装. 要求前校正绑定 agentlint check --all。 。 。 .
import { defineConfig } from "@aurelienbbn/agentlint";
import { xstatePreset } from "@aurelienbbn/agentlint-plugin-xstate";
export default defineConfig({ extends: [xstatePreset] });
规则
| 规则 | xstatePreset | starterPreset | 权力 | 标准折返 | 探测器 | 跳过测试 |
|---|---|---|---|---|---|---|
actor-cleanup | ✅ | ✅ | 代理人 | 3个 | 2个 | ✅ |
machine-failure-coverage | ✅ | ✅ | 代理人 | 3个 | 3个 | |
derived-boolean-context | ✅ | 代理人 | 3个 | 3个 | ||
spawned-actor-release | ✅ | 代理人 | 2 国 家 | 2个 | ✅ | |
persisted-snapshot-compat | ✅ | 代理人 | 2 国 家 | 1个 | ✅ | |
spawn-id-collision | ✅ | 代理人 | 1个 | 1个 | ||
effect-actor-observed | ✅ | 代理人 | 1个 | 1个 |
预设忽略 **/*.d.ts。跳过测试=排除 **/*.{test,spec}.*; 重新组合 exclude 以审查测试. QQ 提出的修订修改了指南,并可能报告更多网站(v6拼写):早期的接受需要重新审查.
createMachine({ invoke: { src: load } }); // ❌ machine-failure-coverage: no onError
const actor = createActor(machine); // ❌ actor-cleanup: who stops it?
setup({}).createMachine({ entry: spawnChild("sync", { id: "sync" }) }); // ❌ spawned-actor-release: paired stopChild?
save(actor.getPersistedSnapshot()); // ❌ persisted-snapshot-compat
setup({}).createMachine({ context: { isLoading: false } }); // ❌ derived-boolean-context
// v6 alpha / @xstate/effect
createMachine({
on: {
ADD: (_, enq) => {
enq.spawn("todo", { id: "todo" });
},
},
}); // ❌ spawn-id-collision, spawned-actor-release
const actor = yield * createEffectActor(machine); // ❌ effect-actor-observed: nothing joins or waits on it
每个规则都输出一个 defineX(options) 工厂在它的默认实例之外. setup().createMachine() 生成一个发现,而不是两个: createMachine 呼叫( 赤裸, 有链条) setup(...),或存储的设置结果).
machine-failure-coverage:每个援引,每个产卵
createMachine({ invoke: { src: "load", onError: {} } }); // ❌ fires: empty onError
createMachine({ invoke: { src: "load", onError: "failed" }, entry: spawnChild("sync", { id: "sync" }) }); // ❌ fires: spawn, no xstate.error
createMachine({ invoke: { src: load, onError: "error" } }); // ✅ silent
每起火灾 invoke 没有真实的 onError (按援引情况审查;v6) createInvoke({...}) 和附件状态的 onError 覆盖) spawnChild(...) 编号 : enq.spawn(...) 编号 : spawn(...) 没有演员- 错误处理: 根 onError (v6),一个 xstate.error.actor 过渡,或 subscribeTo(ref, { error }). v6 逻辑创建者(createAsyncLogic, (中文(简体) ), createCallbackLogic,(......)和 fromEffect* 计为失败源 。 每个版本的指导不同: v6 onError 恢复动作和产子出错,v5没有. 全机倒置仍为承诺/召回逻辑,两者均无. onSnapshot 不是一个失败路径; 纯机器不需要一个捏造的错误状态.
选项 : machineDefinitionPattern, (中文(简体) ), invokeMarkerPattern, (中文(简体) ), errorHandlingMarkerPattern, (中文(简体) ), spawnCallPattern, (中文(简体) ), spawnErrorMarkerPattern。 。 。 .
actor-cleanup:谁创造了一个演员就阻止它
着火了 createActor(...) 财务报告和审定财务报表 system.createActor(...)· ; createEffectActor(...) (按效力范围拥有)和 createActorAtoms(...) (由原子登记处拥有) 得到他们自己的信息。 注射或父母拥有的行为者不必停下来.
- 退出动作不会运行在外部
stop()(v5和v6); 清扫生活于fromCallback编号 :createCallbackLogic或自动终止信号 - 反应所有权通过
useActorRef编号 :useMachine编号 :createActorContext - 未订阅: 放松一次
stop()已被证明
选项 : actorStartPattern。 。 。 .
spawned-actor-release: 每个机器定义一次
createMachine({ on: { ADD: { actions: assign({ ref: ({ spawn }) => spawn(todoMachine) }) } } }); // ❌ fires
setup({}).createMachine({ entry: spawnChild("sync", { id: "sync" }) }); // ❌ fires, once
const child = spawn("git", ["status"]);
assign({ ref: child }); // ✅ silent: not a machine
每个机器定义一次起火(createMachine, (中文(简体) ), setup(...) 编号 : setupEffect(...) 编号 : system.setup(...) .createMachine一个存储的设置, createStateConfig包含 spawnChild(...) 编号 : enqueue.spawnChild(...)时,v6 enq.spawn(...),或已调整结构 spawn(...) (五级) assign,v5/v6上下文厂). 法官把每个产卵配上可伸展的 stopChild 编号 : enq.stop(ref) 并拒绝从上下文删除(v6:返回上下文补丁),或处理自我补全、列表删除的过渡。 受约束的父母 - 生活演员通过 与约束声明。 仅审查快取: 跨过渡对接不合成.
选项 : machineCalleePattern, (中文(简体) ), spawnChildCallPattern。 。 。 .
persisted-snapshot-compat: 存储状态超过其写入器
createActor(machine, { snapshot: JSON.parse(raw) }); // ❌ fires
useMachine(machine, { snapshot }); // ❌ fires
createActor(machine, { input: { id } }); // ✅ silent
render(view, { snapshot: actor.getSnapshot() }); // ✅ silent: not an actor call
着火了 getPersistedSnapshot() 继续 createActor 编号 : useActor 编号 : useMachine 编号 : useActorRef 带有 snapshot 键。 只审查快取:存储代码和上下文类型横跨文件. 法官检查:
- 已版本存储( v6: 机器)
version+ 键machineVersions()迁移; v5快照在 v6 不恢复) - 恢复回到新角色:不相容的快照输出状态
'error'它不会扔,所以try/catch单枪匹马一无所获 - 持续
getPersistedSnapshot()永远getSnapshot()· ;@xstate/effect演员还不能恢复 - 上下文为 JSON 序列
- 不依赖重播的输入动作
- 演员
src名称
选项 : persistCalleePattern, (中文(简体) ), restoreCalleePattern (两者都根据被调用文本进行测试).
derived-boolean-context: 旗帜和状态镜像
createMachine({});
assign({ canSubmit: true }); // ❌ fires
setup({ types: { context: {} as { status: "idle" | "loading" } } }).createMachine({}); // ❌ fires
createMachine({});
assign({ count: 1 }); // ✅ silent
createMachine({ context: { status: initialStatus, items: [] } }); // ✅ silent: not a literal
着火了 assign(...), (中文(简体) ), enqueue.assign(...)设置 <x>.assign(...), v6 上下文补丁(a) context 由处理器返回或设置在静态过渡对象上,初始 context 页:1 createMachine 配置,以及 types.context /v6 数据 schemas.context (一旦双方宣布同一字段) can|is|has* 旗帜和 status|state|step|phase|mode 字段中含有字符串字符或字符串结合。 复议迅速,不是判决:仅点名不能确定可衍生性.
选项 : contextFlagPattern, (中文(简体) ), stateMirrorPattern, (中文(简体) ), machineFilePattern (对照文件来源进行测试;将规则打开机器文件).
spawn-id-collision: 可重复的事件, 固定的 id
createMachine({
on: {
ADD: (_, enq) => {
enq.spawn("todo", { id: "todo" });
},
},
}); // ❌ fires
createMachine({
on: {
ADD: ({ event }, enq) => {
enq.spawn("todo", { id: `todo-${event.id}` });
},
},
}); // ✅ silent
着火了 enq.spawn, (中文(简体) ), spawnChild 编号 : enqueue.spawnChild,或结构调整 spawn 有固定字符串 id 在一个 on.<EVENT> 处理者。 喷出 entry, (中文(简体) ), after,或者上下文厂保持沉默。 第二起事件产下第二个孩子在同一id下:v6错误父母,v5孤儿第一个孩子. 法官接受每个孩子的ID,一个相同过渡中的老人的停站,或者证明该事件在孩子活着的时候不能重复.
选项 : spawnChildCallPattern。 。 。 .
effect-actor-observed: 未读的 Effect 演员无声失败
const actor = yield * createEffectActor(machine); // ❌ fires: never joined, waited on, or returned
const actor = yield * createEffectActor(machine);
return yield * waitFor(actor, (s) => s.matches("done"), { timeout: "5 seconds" }); // ✅ silent
着火了 createEffectActor(...) 绑定在文件从未传递到的变量上 join, (中文(简体) ), waitFor,或 snapshots (也通过) pipe,从不订阅,从不返回. emitted 不计数:只是演员出错时结束. 不受限制的创建, 如 Layer.effect(...) 保持安静.
选项 : effectActorCalleePattern, (中文(简体) ), observerNames。 。 。 .
Agentlint规则合同
| 事实 | 细节 |
|---|---|
| 规则形状 | lifecycle, (中文(简体) ), standard (订正), detector (版本), binding (id, 权威, 范围, 实质性选项) |
| 编译 | defineConfig({ extends: [preset] }) 或者说 defineConfig({ rules: [configuredRule] }); 重复使用需要不同的绑定标识 |
| 权力 | 默认允许代理接受;存储器所有者选择范围,并可以向 human |
| 接受结论 | 需要匹配当前证据 财务报告和审定财务报表 权力 |
| 固定装置 | @aurelienbbn/agentlint/testing 使用真实解析器运行嵌入式活性/静态固定装置 |
登记的合同库存
从软件包导出 pnpm catalog. 规则特定选项和限制在上文和源测试中都有描述.
| 规则/检查 | 触发或审查范围 |
|---|---|
actor-cleanup | 旗下演员创作站点需要生命周期清理审查. |
derived-boolean-context | Flags 上下文写 (v5 指定 (), v6 返回上下文补丁) 和上下文声明以缓存有限状态的可用布尔语或字符串- enum 副本 . |
effect-actor-observed | 旗子 @ xstate/ effect actors 绑定在创建效果Actor (.) 上, 文件从不通过加入、 等待、 快照或订阅来读取其结果 . |
machine-failure-coverage | 旗下援引演员没有真正在Error过渡,产入演员没有演员-error处理故障路径审查. |
persisted-snapshot-compat | 坚持或恢复如此存储状态的演员快照的旗帜站点将接受审查,以进行版本化、倒置和可序列性. |
spawn-id-collision | 旗帜在事件处理器内用固定的ID来产出,重复的事件在同一ID下产出第二个孩子. |
spawned-actor-release | 旗子机器的定义 产出演员 所以每个产出 都经过审查 相匹配的停止和回推去除. |
信用概念
- 由Sandro Maglione(启发、独立重新执行)自动操作
贷项
starterPreset 登机:由Peter O'Malley拆卸而来的概念灵感;没有复制代码或指南.