@collective-intelligence/lint

中文文档
0.2.4发布于 2026/11/07TypeScriptES Module近 30 天下载 3089

Oxlint plugin with the Collective Intelligence lint rules: package boundaries and solution package layout.

原始使用文档
文档目录10 节
  1. Install
  2. Use
  3. All rules
  4. Selected rules
  5. Agent skill
  6. Rules
  7. Package boundaries
  8. Solution layout
  9. Effect convention
  10. Adding a rule

@collective-intelligence/lint

The Collective Intelligence lint rules, as one Oxlint plugin. Every CI lint rule lives in this package. The plugin is named ci-solution, so each rule is enabled as ci-solution/<rule>.

Install

bun add -d oxlint @collective-intelligence/lint

The plugin needs oxlint 1.82.0 or later.

Use

All rules

Extend the recommended config in oxlint.config.ts. It loads the plugin and enables every rule as an error:

import { recommended } from "@collective-intelligence/lint"
import { defineConfig } from "oxlint"

export default defineConfig({
  extends: [recommended]
})

To change one rule, set it after the extend:

export default defineConfig({
  extends: [recommended],
  rules: { "ci-solution/subpath-index": "warn" }
})

Selected rules

Load the plugin and enable only the rules you want:

import { defineConfig } from "oxlint"

export default defineConfig({
  jsPlugins: ["@collective-intelligence/lint"],
  rules: {
    "ci-solution/package-entrypoint": "error",
    "ci-solution/subpath-imports": "error"
  }
})

A JSON config works the same way:

{
  "jsPlugins": ["@collective-intelligence/lint"],
  "rules": { "ci-solution/package-entrypoint": "error" }
}

The RuleName type lists every rule name.

Agent skill

The package ships the agent skill ci-solution-structure at skills/ci-solution-structure/SKILL.md. In a Harness Intelligence repository, the collective-intelligence pack installs the skill and adds the plugin with ci-solution/package-entrypoint to the managed lint config.

Rules

RuleEnforcesGroup
ci-solution/package-entrypointAn import of another package targets an entrypoint declared in its package.json exports.Package boundaries
ci-solution/subpath-importsImports between subpath folders follow the allowed direction.Solution layout
ci-solution/subpath-entrypointAn import from another subpath folder targets the folder or its index file.Solution layout
ci-solution/subpath-indexEvery subpath folder has an index.ts or index.tsx.Solution layout
ci-solution/effect-subpathAn SDK Effect API comes from the SDK's /effect subpath; removed SDK paths are reported.Effect convention
ci-solution/no-run-in-viewA view module calls no fetch and runs no Effect.Effect convention
ci-solution/effect-actorsXState side-effect actors are fromEffect actors.Effect convention
ci-solution/effect-writesNo module takes TanStack Query useMutation; writes run in fromEffect actors.Effect convention

Package boundaries

A workspace holds packages that import each other. These rules keep each package behind its declared public entrypoints.

package-entrypoint

Import another package through its root (@scope/pkg) or a subpath listed in its package.json exports (@scope/pkg/views). * patterns and null exclusions follow Node resolution. The rule finds the package through node_modules from the importing file, so workspace packages must be linked by the package manager.

import { invoiceTotal } from "@acme/billing" // valid
import { invoiceTable } from "@acme/billing/views" // valid when "./views" is exported
import { rate } from "@acme/billing/src/domain/rates" // reported
import { rate } from "../../billing/src/domain/rates" // reported: relative path into another package

A package without an exports field accepts every subpath except src/. Packages that cannot be found are not checked.

Solution layout

A solution package can split its sources into subpath folders:

src/
  ci/        Collective Intelligence entity and capability declarations
  domain/    domain model, free of runtime concerns
  api/       API contracts
  server/    server handlers and runtime wiring
  headless/  UI state without rendering
  views/     rendered UI

These rules keep those folders apart.

subpath-imports

FolderMust not import
domain/server/, views/, headless/, ci/
ci/views/, headless/
headless/server/
views/server/
api/no limit
server/no limit

The rule checks relative imports and imports through the package's own name (@acme/billing/server from src/views/).

subpath-entrypoint

An import from another subpath folder targets the folder or its index file. Imports inside one subpath folder are free.

// src/views/table.ts
import { invoiceTotal } from "../domain" // valid
import { invoiceTotal } from "../domain/index.ts" // valid
import { rate } from "../domain/rates" // reported

subpath-index

Every subpath folder under src/ has an index.ts or index.tsx entrypoint. The rule reports each file in a folder that has neither.

Effect convention

An app keeps its side effects in XState machines: each side effect is a fromEffect actor, views read data through TanStack Query, and writes refresh those reads through the SDK QueryCache. These rules check the parts of that convention that imports and calls show.

effect-subpath

A Collective Intelligence SDK (@collective-intelligence/*) exposes its Effect API at <sdk>/effect and <sdk>/effect/<adapter>. The rule reports an SDK path that names Effect elsewhere: a <sdk>-effect package, or an effect segment below another subpath. It also reports each SDK path that the release after 0.2.0 removes, with its replacement:

Removed pathReplacement
@collective-intelligence/external-apps-server-sdk/runtime/effect@collective-intelligence/external-apps-server-sdk/effect
@collective-intelligence/external-apps-server-sdk/persistence/drizzle/effect@collective-intelligence/external-apps-server-sdk/effect; layerNodePostgres and NodePostgresLayerOptions from @collective-intelligence/external-apps-server-sdk/effect/node-postgres
@collective-intelligence/external-apps-server-sdk/runtime/next@collective-intelligence/external-apps-server-sdk/next
@collective-intelligence/extensions-sdk-backend-effect@collective-intelligence/extensions-sdk-backend/effect
import { CiClient } from "@collective-intelligence/external-apps-client-sdk/effect" // valid
import { createClient } from "@collective-intelligence/external-apps-client-sdk" // valid
import { Realtime } from "@collective-intelligence/external-apps-client-sdk/realtime/effect" // reported
import { CiRuntime } from "@collective-intelligence/external-apps-server-sdk/runtime/effect" // reported: removed

no-run-in-view

A view module is a .tsx or .jsx file, or a file in the views/ subpath of a solution package. The rule reports a call of the global fetch (also globalThis.fetch and window.fetch) and each use of an Effect run function (runPromise, runSync, runFork and the other run* functions of Effect and ManagedRuntime):

  • a read from any object, called or passed as a value: Effect.runPromise(x), runtime.runSync(x), x.pipe(Effect.runPromise);
  • a key in a destructuring pattern: const { runFork } = runtime;
  • a named import from effect, effect/* or @effect/*: import { runPromise } from "effect/Effect".

A constant name in brackets or quotes counts too: window["fetch"](url), Effect[`runSync`](x) and const { "runFork": fork } = runtime are reported. A local binding named fetch, globalThis or window, a method such as cache.fetch, a name in brackets that only runtime gives (Effect[key]) and an object literal key such as { runPromise: run } are not reported. To allow the calls in view tests, turn the rule off for the test files in an overrides entry.

effect-actors

The rule reports each fromPromise, fromCallback, fromObservable and fromEventObservable that an import, a re-export or a namespace import (XState.fromPromise, XState["fromPromise"], const { fromPromise } = XState) takes from xstate or xstate/*. Make side-effect actors with fromEffect from @collective-intelligence/external-apps-client-sdk-react/effect in a detached app, or from @collective-intelligence/extensions-sdk-frontend-react/effect in a hosted Studio Widget. Machines and fromTransition actors have no side effects and are not reported. A local name that shadows the namespace import, such as a parameter named XState, is not reported.

effect-writes

The rule reports each useMutation that an import, a re-export or a namespace import (ReactQuery.useMutation, ReactQuery["useMutation"], const { useMutation } = ReactQuery) takes from @tanstack/react-query. Write through a fromEffect actor from @collective-intelligence/external-apps-client-sdk-react/effect in a detached app, or from @collective-intelligence/extensions-sdk-frontend-react/effect in a hosted Studio Widget; after the write, the actor refreshes reads through the QueryCache of the same entrypoint (invalidate, setData).

The rule checks every module. useMutation runs only during a React render, so a module that takes it is a view, a hook or a helper of one of them.

useQuery and the other reads are not reported, and neither are useMutationState and useIsMutating: they only read the state of a useMutation. A useMutation from another library, such as @apollo/client, is not reported. The entity hooks of @collective-intelligence/external-apps-client-sdk-react/resources (useEntityCreate, useEntityUpdate, useEntityDelete) are not reported: the SDK writes and refreshes its own entity reads.

The rule checks no query key. An app that builds the SDK's "ci-entities" key by hand, for example in invalidateQueries, is not reported: the SDK owns that key for its entity reads but exports no key or refresh function for them yet, so a report would have no supported fix.

Adding a rule

Each rule is a plain Oxlint rule in its own folder, src/rules/<rule>/:

  1. Write src/rules/<rule>/<rule>.ts. Export a LintRule (src/rule.ts) with:

    • group: the rule group in the table above (add a group to RuleGroup when no group fits);
    • rule: the rule from defineRule of @oxlint/plugins, with a messages entry in meta for each finding. src/rule.ts holds the shared helpers: moduleSpecifiers builds a visitor that checks every module specifier, staticPropertyName reads a constant property name, and declaredVariable finds the variable that a name refers to.

    A rule reads the workspace through src/workspace/: packageOf and installedPackage find package manifests, declaresEntrypoint checks exports, and layoutFile finds the subpath of a file.

  2. Add one line to the registry, src/rules/index.ts. The plugin, the recommended config and the RuleName type follow from it.

  3. Write src/rules/<rule>/<rule>.test.ts against the fixture workspace in test/fixtures/workspace/, and add fixture files for the new cases. Add the new diagnostics to the expectations of src/index.test.ts.

  4. Add the rule to the table above, and to CHANGELOG.md.

Oxlint calls rule visitors synchronously, so a rule reads files with the synchronous node:fs API: it cannot wait for a promise or a timer. The workspace lookups cache each folder they visit, so each package.json is read once per plugin load.

版本与发布记录

@collective-intelligence/lint 共发布 15 个版本,首次发布于 2026/10/28;过去 12 个月发布了 15 个版本。

版本发布日期距今
0.2.4latest2026/11/073 天前
0.2.32026/11/063 天前
0.2.22026/11/064 天前
0.2.12026/11/055 天前
0.2.02026/11/055 天前
0.1.282026/11/046 天前

关于 @collective-intelligence/lint 的常见问题

@collective-intelligence/lint 是什么?

Oxlint plugin with the Collective Intelligence lint rules: package boundaries and solution package layout.

如何安装 @collective-intelligence/lint?

在项目目录运行 npm install @collective-intelligence/lint,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:oxlint(>=1.82.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@collective-intelligence/lint 支持 TypeScript 吗?

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

@collective-intelligence/lint 支持 ESM 还是 CommonJS?

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

@collective-intelligence/lint 可以商用吗?

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

@collective-intelligence/lint 的下载量有多少?

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

@collective-intelligence/lint 还在维护吗?

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