Skip to main content

adding-a-feature

Step-by-step guide for adding a new tool or service to @webiny/stdlib.

ソース情報

リポジトリ
webiny/stdlib
ソースの最終更新活動
2026年7月28日 13:05
検出された SKILL.md の言語
英語
スター
0
フォーク
0

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
adding-a-feature
description
Step-by-step guide for adding a new tool or service to @webiny/stdlib.
context
guides
# Adding a New Tool to @webiny/stdlib This mirrors the "Step-by-step: Adding a New Tool to an Existing Package" section in the repo's `AGENTS.md`, which is the authoritative source — check there if this drifts. First decide which slice the tool belongs in, based on its runtime dependencies: | Uses only JS built-ins / standard lib | → `@webiny/stdlib` root (`src/`) | | Uses `node:*` APIs or Node-only npm packages | → `@webiny/stdlib/node` (`src/node/`) | | Uses `window`, `document`, React, browser APIs | → `@webiny/stdlib/browser` (`src/browser/`) | `src/node/` and `src/browser/` must NOT import from each other. Both may import common code via `~/common/index.js`. Example below: adding `HttpTool` to `@webiny/stdlib/node`. Substitute the appropriate slice and path for your tool. ## Steps 1. **Create the abstraction** at `src/node/features/HttpTool/abstractions/HttpTool.ts`: - Define `interface IHttpTool` with JSDoc on each method. - Export `const HttpTool = createAbstraction<IHttpTool>("Core/HttpTool")`. - Export `namespace HttpTool { export type Interface = IHttpTool }`. 2. **Create the abstraction barrel** at `src/node/features/HttpTool/abstractions/index.ts`: - `export { HttpTool } from "./HttpTool.js";` 3. **Create the implementation** at `src/node/features/HttpTool/HttpTool.ts`: - Rename the token import to avoid a name clash: `import { HttpTool as HttpToolAbstraction } from "./abstractions/HttpTool.js";` - Import cross-slice dependencies via the common barrel: `import { Logger } from "~/common/index.js";` - `class HttpToolImpl implements HttpToolAbstraction.Interface { ... }` - `export const HttpTool = HttpToolAbstraction.createImplementation({ implementation: HttpToolImpl, dependencies: [...] })` - The `dependencies` array order must match the constructor parameter order exactly. 4. **Create the feature** at `src/node/features/HttpTool/feature.ts`: - `export const HttpToolFeature = createFeature({ name: "Core/HttpToolFeature", register(container) { container.register(HttpTool).inSingletonScope(); } })` 5. **Create the feature index** at `src/node/features/HttpTool/index.ts`: - `export { HttpTool } from "./abstractions/index.js";` - `export { HttpToolFeature } from "./feature.js";` - Never re-export the implementation class or the `createImplementation` output. 6. **Create the feature README** at `src/node/features/HttpTool/README.md`: - One-paragraph description — what it does and when to reach for it. - Interface section — the public methods with JSDoc (copy from the abstraction file). - Usage section — two code snippets: DI container wiring, and a `createXxx()` factory function. - Prepend YAML front-matter (`name`, `description`, `context`) so the README is discoverable by the MCP server — see the front-matter block at the top of any existing feature README for the exact shape. - Update the repo root `README.md` table to add a row pointing to the new feature README. 7. **Add to the slice barrel** `src/node/index.ts`: - `export { HttpTool, HttpToolFeature } from "./features/HttpTool/index.js";` 8. **Write tests** at `__tests__/node/HttpTool.test.ts`: - Create a `makeContainer()` helper — see the `testing-patterns` skill. - Cover the happy path and error paths. - Node tests do not need a `// @vitest-environment` directive (only browser tests do). 9. **Run the pre-commit chain** until fully clean: ```sh yarn && yarn adio && yarn format:fix && yarn lint:fix && yarn typecheck && yarn build && yarn test:coverage ``` All steps must pass with zero errors and zero warnings before staging and committing. If any step fails, fix the issue and run the full chain again from the start. ## Conventions to keep in mind throughout - **No default exports.** Always use named exports. - **JSDoc comments are preferred** on interface methods, abstraction types, and public class methods — they're read by both IDE tooling and agents. Don't write comments that just restate the method name. - **Strict TypeScript** — all strict flags in `tsconfig.json` must pass. - **`.js` extensions in package source imports** — under `src/`, `import { Foo } from "./Foo.js"` (not `.ts`); tsgo resolves `.js` to `.ts` at compile time. (Exception: `scripts/`, which runs directly under Node 24 and needs real `.ts` extensions.) - **`node:` prefix for Node built-ins** — `import { readFileSync } from "node:fs"`, never `"fs"`. - **Singletons via DI** — register utils as `.inSingletonScope()` unless there's a reason not to. - **DI token names use `"Domain/ToolName"` format** — `"Core/"` prefix for common utils, `"Node/"` prefix for Node-specific ones. - **Namespace pattern for interface types** — always export `namespace ToolName { export type Interface = IToolName }` alongside the token. See the `di-patterns` skill for the underlying abstraction/implementation/feature mechanics, and AGENTS.md's "Step-by-step: Adding a New Slice to @webiny/stdlib" section if you're adding an entirely new runtime environment rather than a tool within an existing one.
GitHubで見る