diff --git a/.claude/skills/file-operations/SKILL.md b/.claude/skills/file-operations/SKILL.md index 587b160d..98864e3f 100644 --- a/.claude/skills/file-operations/SKILL.md +++ b/.claude/skills/file-operations/SKILL.md @@ -1,105 +1,11 @@ --- name: file-operations -description: File operations and HTTP request standards for StackOne SDK +description: HTTP request standards for StackOne SDK --- -# File Operations and HTTP Standards +# HTTP Request Standards -This skill provides guidance on file operations and HTTP request patterns in the StackOne SDK. - -## Using File Utilities - -When working with files and directories, use the utilities from `src/utils/file.ts` instead of direct `fs`/`path` operations. - -### Available Utilities - -Import the required utilities: -```typescript -import { - isBase64, - isValidFilePath, - readFileAsBase64, - extractFileInfo, - directoryExists, - listFilesInDirectory, - readJsonFile, - getFileNameWithoutExtension, - joinPaths, -} from '../utils/file'; -``` - -### Utility Functions - -- **`isBase64(str: string): boolean`** - Check if a string is base64 encoded -- **`isValidFilePath(filePath: string): boolean`** - Check if a file path is valid and the file exists -- **`readFileAsBase64(filePath: string): string`** - Read a file and return its contents as base64 -- **`extractFileInfo(filePath: string)`** - Extract file name and extension from a path -- **`directoryExists(dirPath: string): boolean`** - Check if a directory exists -- **`listFilesInDirectory(dirPath: string, filter?: (file: string) => boolean): string[]`** - List files in a directory with optional filtering -- **`readJsonFile(filePath: string): T`** - Read and parse a JSON file with type safety -- **`getFileNameWithoutExtension(filePath: string): string`** - Get file name without extension -- **`joinPaths(...segments: string[]): string`** - Join path segments safely - -### Benefits - -- Consistent error handling across the codebase -- Type safety with generics -- Centralized file operations -- Easier to test and mock -- Prevents direct fs/path dependency scatter - -### Examples - -**Bad - Direct fs/path usage**: -```typescript -import fs from 'node:fs'; -import path from 'node:path'; - -function processJsonFile(filePath: string) { - if (fs.existsSync(filePath)) { - const content = fs.readFileSync(filePath, 'utf-8'); - const data = JSON.parse(content); - return data; - } - throw new Error(`File not found: ${filePath}`); -} -``` - -**Good - Using file utilities**: -```typescript -import { isValidFilePath, readJsonFile } from '../utils/file'; - -function processJsonFile(filePath: string): T { - if (isValidFilePath(filePath)) { - return readJsonFile(filePath); - } - throw new Error(`File not found: ${filePath}`); -} -``` - -**Bad - Direct directory operations**: -```typescript -import * as fs from 'node:fs'; - -function getJsonFiles(dirPath: string): string[] { - if (fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) { - return fs.readdirSync(dirPath).filter(file => file.endsWith('.json')); - } - return []; -} -``` - -**Good - Using file utilities**: -```typescript -import { directoryExists, listFilesInDirectory } from '../utils/file'; - -function getJsonFiles(dirPath: string): string[] { - if (directoryExists(dirPath)) { - return listFilesInDirectory(dirPath, file => file.endsWith('.json')); - } - return []; -} -``` +This skill provides guidance on HTTP request patterns in the StackOne SDK. ## Native Fetch API Standards @@ -213,16 +119,9 @@ async function getProtectedData(token: string): Promise { } ``` -## When to Use Direct fs/path - -Only use direct `fs`/`path` operations when: -- The utility function doesn't exist for your use case -- You have a specific performance requirement -- Document why you're bypassing the utilities - ## When to Use Direct HTTP Clients -Only use specialized HTTP clients when: +Only use specialised HTTP clients when: - You need advanced features not covered by fetch (e.g., interceptors, retries) - You're integrating with a framework that requires it - Document why you're not using native fetch diff --git a/.cursor/rules/file-utils.mdc b/.cursor/rules/file-utils.mdc deleted file mode 100644 index 9d1bb5a8..00000000 --- a/.cursor/rules/file-utils.mdc +++ /dev/null @@ -1,111 +0,0 @@ ---- -description: Standards for using file utilities in the StackOne repository -globs: *.ts -alwaysApply: false ---- - # File Utilities Standards - -Standards for using file utilities in the StackOne repository. - - -name: file_utils_standards -description: Standards for using file utilities from the file.ts module instead of direct fs/path operations - -filters: - - type: path - pattern: "^src/.*\\.ts$" - -actions: - - type: suggest - message: | - When working with files and directories: - - 1. Use the file utilities from `src/utils/file.ts`: - - Import the required utilities: `import { ... } from './utils/file'` - - Do not use fs/path modules directly unless absolutely necessary - - 2. Available utilities: - - `isBase64(str)`: Check if a string is base64 encoded - - `isValidFilePath(filePath)`: Check if a file path is valid and the file exists - - `readFileAsBase64(filePath)`: Read a file and return its contents as a base64 string - - `extractFileInfo(filePath)`: Extract file name and extension from a path - - `directoryExists(dirPath)`: Check if a directory exists - - `listFilesInDirectory(dirPath, filter?)`: List files in a directory with optional filtering - - `readJsonFile(filePath)`: Read and parse a JSON file with type safety - - `getFileNameWithoutExtension(filePath)`: Get file name without extension - - `joinPaths(...segments)`: Join path segments safely - - 3. Benefits of using these utilities: - - Consistent error handling - - Type safety - - Centralized file operations - - Easier testing and mocking - -examples: - - input: | - import fs from 'node:fs'; - import path from 'node:path'; - - function processJsonFile(filePath: string) { - if (fs.existsSync(filePath)) { - const content = fs.readFileSync(filePath, 'utf-8'); - const data = JSON.parse(content); - return data; - } - throw new Error(`File not found: ${filePath}`); - } - output: | - import { isValidFilePath, readJsonFile } from '../utils/file'; - - function processJsonFile(filePath: string): T { - if (isValidFilePath(filePath)) { - return readJsonFile(filePath); - } - throw new Error(`File not found: ${filePath}`); - } - - - input: | - import * as fs from 'node:fs'; - import * as path from 'node:path'; - - function getFilesInDirectory(dirPath: string) { - if (fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) { - return fs.readdirSync(dirPath).filter(file => file.endsWith('.json')); - } - return []; - } - output: | - import { directoryExists, listFilesInDirectory } from '../utils/file'; - - function getFilesInDirectory(dirPath: string): string[] { - if (directoryExists(dirPath)) { - return listFilesInDirectory(dirPath, file => file.endsWith('.json')); - } - return []; - } - - - input: | - import fs from 'node:fs'; - import path from 'node:path'; - - function getFileNameWithoutExt(filePath: string): string { - const fileName = path.basename(filePath); - const dotIndex = fileName.lastIndexOf('.'); - return dotIndex === -1 ? fileName : fileName.substring(0, dotIndex); - } - output: | - import { getFileNameWithoutExtension } from '../utils/file'; - - function getFileNameWithoutExt(filePath: string): string { - return getFileNameWithoutExtension(filePath); - } - -metadata: - priority: high - version: 1.0 - tags: - - files - - directories - - utilities - - standards - \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index 700aa90b..79ca638f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -42,12 +42,10 @@ See the **typescript-patterns** skill for TypeScript best practices: Refer to `.claude/skills/typescript-patterns/SKILL.md` for complete details. -## File Operations and HTTP Standards +## HTTP Standards -See the **file-operations** skill for file and HTTP guidance: -- Using `src/utils/file.ts` utilities instead of direct fs/path +See the **file-operations** skill for HTTP guidance: - Native fetch API standards and error handling -- Type-safe file operations - Common HTTP request patterns Refer to `.claude/skills/file-operations/SKILL.md` for complete details. diff --git a/examples/package.json b/examples/package.json index 2e69435d..a920acda 100644 --- a/examples/package.json +++ b/examples/package.json @@ -13,7 +13,6 @@ "@ai-sdk/openai": "catalog:dev", "@types/node": "catalog:dev", "ai": "catalog:peer", - "nano-spawn": "catalog:dev", "openai": "catalog:peer" }, "devEngines": { diff --git a/knip.config.ts b/knip.config.ts new file mode 100644 index 00000000..e3caa829 --- /dev/null +++ b/knip.config.ts @@ -0,0 +1,19 @@ +import type { KnipConfig } from 'knip' + +export default { + workspaces: { + '.': { + entry: ['src/index.ts', 'mocks/**/*.ts'], + project: ['src/**/*.ts', 'mocks/**/*.ts'] + }, + examples: { + entry: ['*.ts'], + project: ['*.ts'] + } + }, + ignore: ['**/*.test.ts', '**/*.spec.ts', '**/*.test-d.ts'], + ignoreBinaries: ['only-allow'], + rules: { + optionalPeerDependencies: 'off' + } +} satisfies KnipConfig diff --git a/lefthook.yaml b/lefthook.yaml index e8bed457..756c2606 100644 --- a/lefthook.yaml +++ b/lefthook.yaml @@ -8,3 +8,7 @@ pre-commit: glob: "*.{ts,tsx,js,jsx,mts,cts,json,jsonc,yaml,yml,md}" run: pnpm biome check --no-errors-on-unmatched --write {staged_files} stage_fixed: true + knip: + glob: "*.{ts,tsx,js,jsx,mts,cts}" + run: pnpm run format:knip + stage_fixed: true diff --git a/package.json b/package.json index c3f2c27f..591d1c60 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,12 @@ ], "scripts": { "build": "tsdown", - "format": "biome format --write .", - "lint": "biome check .", + "format": "pnpm --no-bail --aggregate-output run '/^format:/'", + "format:biome": "biome format --write .", + "format:knip": "knip --fix --no-exit-code", + "lint": "pnpm --no-bail --aggregate-output run '/^lint:/'", + "lint:biome": "biome check .", + "lint:knip": "knip", "preinstall": "npx only-allow pnpm", "prepack": "npm pkg delete scripts.preinstall && pnpm run build", "test": "pnpm --no-bail --aggregate-output run '/^test:/'", @@ -36,7 +40,6 @@ "json-schema": "catalog:prod" }, "devDependencies": { - "@ai-sdk/openai": "catalog:dev", "@ai-sdk/provider-utils": "catalog:dev", "@biomejs/biome": "catalog:dev", "@hono/mcp": "catalog:dev", @@ -45,8 +48,8 @@ "@typescript/native-preview": "catalog:dev", "@vitest/coverage-v8": "catalog:dev", "ai": "catalog:peer", - "fs-fixture": "catalog:dev", "hono": "catalog:dev", + "knip": "catalog:dev", "lefthook": "catalog:dev", "msw": "catalog:dev", "openai": "catalog:peer", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ae0fe891..981f2994 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -30,21 +30,18 @@ catalogs: '@vitest/coverage-v8': specifier: ^3.2.4 version: 3.2.4 - fs-fixture: - specifier: ^2.8.1 - version: 2.11.0 hono: specifier: ^4.9.10 version: 4.10.7 + knip: + specifier: ^5.72.0 + version: 5.72.0 lefthook: specifier: ^2.0.8 version: 2.0.8 msw: specifier: ^2.10.4 version: 2.12.3 - nano-spawn: - specifier: ^2.0.0 - version: 2.0.0 publint: specifier: ^0.3.12 version: 0.3.15 @@ -98,9 +95,6 @@ importers: specifier: catalog:prod version: 0.4.0 devDependencies: - '@ai-sdk/openai': - specifier: catalog:dev - version: 2.0.76(zod@3.25.76) '@ai-sdk/provider-utils': specifier: catalog:dev version: 3.0.18(zod@3.25.76) @@ -125,12 +119,12 @@ importers: ai: specifier: catalog:peer version: 5.0.106(zod@3.25.76) - fs-fixture: - specifier: catalog:dev - version: 2.11.0 hono: specifier: catalog:dev version: 4.10.7 + knip: + specifier: catalog:dev + version: 5.72.0(@types/node@22.19.1)(typescript@5.9.3) lefthook: specifier: catalog:dev version: 2.0.8 @@ -148,7 +142,7 @@ importers: version: 0.3.15 tsdown: specifier: catalog:dev - version: 0.15.12(@typescript/native-preview@7.0.0-dev.20251202.1)(publint@0.3.15)(typescript@5.9.3)(unplugin-unused@0.5.6) + version: 0.15.12(@typescript/native-preview@7.0.0-dev.20251202.1)(oxc-resolver@11.15.0)(publint@0.3.15)(typescript@5.9.3)(unplugin-unused@0.5.6) type-fest: specifier: catalog:dev version: 4.41.0 @@ -173,22 +167,19 @@ importers: devDependencies: '@ai-sdk/openai': specifier: catalog:dev - version: 2.0.76(zod@3.25.76) + version: 2.0.76(zod@4.1.13) '@types/node': specifier: catalog:dev version: 22.19.1 ai: specifier: catalog:peer - version: 5.0.106(zod@3.25.76) - nano-spawn: - specifier: catalog:dev - version: 2.0.0 + version: 5.0.106(zod@4.1.13) node: specifier: runtime:^24.11.0 version: runtime:24.11.1 openai: specifier: catalog:peer - version: 6.9.1(zod@3.25.76) + version: 6.9.1(zod@4.1.13) packages: @@ -703,6 +694,18 @@ packages: '@napi-rs/wasm-runtime@1.1.0': resolution: {integrity: sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==} + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + '@open-draft/deferred-promise@2.2.0': resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} @@ -723,6 +726,114 @@ packages: '@oxc-project/types@0.95.0': resolution: {integrity: sha512-vACy7vhpMPhjEJhULNxrdR0D943TkA/MigMpJCHmBHvMXxRStRi/dPtTlfQ3uDwWSzRpT8z+7ImjZVf8JWBocQ==} + '@oxc-resolver/binding-android-arm-eabi@11.15.0': + resolution: {integrity: sha512-Q+lWuFfq7whNelNJIP1dhXaVz4zO9Tu77GcQHyxDWh3MaCoO2Bisphgzmsh4ZoUe2zIchQh6OvQL99GlWHg9Tw==} + cpu: [arm] + os: [android] + + '@oxc-resolver/binding-android-arm64@11.15.0': + resolution: {integrity: sha512-vbdBttesHR0W1oJaxgWVTboyMUuu+VnPsHXJ6jrXf4czELzB6GIg5DrmlyhAmFBhjwov+yJH/DfTnHS+2sDgOw==} + cpu: [arm64] + os: [android] + + '@oxc-resolver/binding-darwin-arm64@11.15.0': + resolution: {integrity: sha512-R67lsOe1UzNjqVBCwCZX1rlItTsj/cVtBw4Uy19CvTicqEWvwaTn8t34zLD75LQwDDPCY3C8n7NbD+LIdw+ZoA==} + cpu: [arm64] + os: [darwin] + + '@oxc-resolver/binding-darwin-x64@11.15.0': + resolution: {integrity: sha512-77mya5F8WV0EtCxI0MlVZcqkYlaQpfNwl/tZlfg4jRsoLpFbaTeWv75hFm6TE84WULVlJtSgvf7DhoWBxp9+ZQ==} + cpu: [x64] + os: [darwin] + + '@oxc-resolver/binding-freebsd-x64@11.15.0': + resolution: {integrity: sha512-X1Sz7m5PC+6D3KWIDXMUtux+0Imj6HfHGdBStSvgdI60OravzI1t83eyn6eN0LPTrynuPrUgjk7tOnOsBzSWHw==} + cpu: [x64] + os: [freebsd] + + '@oxc-resolver/binding-linux-arm-gnueabihf@11.15.0': + resolution: {integrity: sha512-L1x/wCaIRre+18I4cH/lTqSAymlV0k4HqfSYNNuI9oeL28Ks86lI6O5VfYL6sxxWYgjuWB98gNGo7tq7d4GarQ==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm-musleabihf@11.15.0': + resolution: {integrity: sha512-abGXd/zMGa0tH8nKlAXdOnRy4G7jZmkU0J85kMKWns161bxIgGn/j7zxqh3DKEW98wAzzU9GofZMJ0P5YCVPVw==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm64-gnu@11.15.0': + resolution: {integrity: sha512-SVjjjtMW66Mza76PBGJLqB0KKyFTBnxmtDXLJPbL6ZPGSctcXVmujz7/WAc0rb9m2oV0cHQTtVjnq6orQnI/jg==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-arm64-musl@11.15.0': + resolution: {integrity: sha512-JDv2/AycPF2qgzEiDeMJCcSzKNDm3KxNg0KKWipoKEMDFqfM7LxNwwSVyAOGmrYlE4l3dg290hOMsr9xG7jv9g==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-ppc64-gnu@11.15.0': + resolution: {integrity: sha512-zbu9FhvBLW4KJxo7ElFvZWbSt4vP685Qc/Gyk/Ns3g2gR9qh2qWXouH8PWySy+Ko/qJ42+HJCLg+ZNcxikERfg==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-riscv64-gnu@11.15.0': + resolution: {integrity: sha512-Kfleehe6B09C2qCnyIU01xLFqFXCHI4ylzkicfX/89j+gNHh9xyNdpEvit88Kq6i5tTGdavVnM6DQfOE2qNtlg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-riscv64-musl@11.15.0': + resolution: {integrity: sha512-J7LPiEt27Tpm8P+qURDwNc8q45+n+mWgyys4/V6r5A8v5gDentHRGUx3iVk5NxdKhgoGulrzQocPTZVosq25Eg==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-s390x-gnu@11.15.0': + resolution: {integrity: sha512-+8/d2tAScPjVJNyqa7GPGnqleTB/XW9dZJQ2D/oIM3wpH3TG+DaFEXBbk4QFJ9K9AUGBhvQvWU2mQyhK/yYn3Q==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-gnu@11.15.0': + resolution: {integrity: sha512-xtvSzH7Nr5MCZI2FKImmOdTl9kzuQ51RPyLh451tvD2qnkg3BaqI9Ox78bTk57YJhlXPuxWSOL5aZhKAc9J6qg==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-musl@11.15.0': + resolution: {integrity: sha512-14YL1zuXj06+/tqsuUZuzL0T425WA/I4nSVN1kBXeC5WHxem6lQ+2HGvG+crjeJEqHgZUT62YIgj88W+8E7eyg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-openharmony-arm64@11.15.0': + resolution: {integrity: sha512-/7Qli+1Wk93coxnrQaU8ySlICYN8HsgyIrzqjgIkQEpI//9eUeaeIHZptNl2fMvBGeXa7k2QgLbRNaBRgpnvMw==} + cpu: [arm64] + os: [openharmony] + + '@oxc-resolver/binding-wasm32-wasi@11.15.0': + resolution: {integrity: sha512-q5rn2eIMQLuc/AVGR2rQKb2EVlgreATGG8xXg8f4XbbYCVgpxaq+dgMbiPStyNywW1MH8VU2T09UEm30UtOQvg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-resolver/binding-win32-arm64-msvc@11.15.0': + resolution: {integrity: sha512-yCAh2RWjU/8wWTxQDgGPgzV9QBv0/Ojb5ej1c/58iOjyTuy/J1ZQtYi2SpULjKmwIxLJdTiCHpMilauWimE31w==} + cpu: [arm64] + os: [win32] + + '@oxc-resolver/binding-win32-ia32-msvc@11.15.0': + resolution: {integrity: sha512-lmXKb6lvA6M6QIbtYfgjd+AryJqExZVSY2bfECC18OPu7Lv1mHFF171Mai5l9hG3r4IhHPPIwT10EHoilSCYeA==} + cpu: [ia32] + os: [win32] + + '@oxc-resolver/binding-win32-x64-msvc@11.15.0': + resolution: {integrity: sha512-HZsfne0s/tGOcJK9ZdTGxsNU2P/dH0Shf0jqrPvsC6wX0Wk+6AyhSpHFLQCnLOuFQiHHU0ePfM8iYsoJb5hHpQ==} + cpu: [x64] + os: [win32] + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -1096,6 +1207,9 @@ packages: resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} engines: {node: '>=14'} + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -1120,6 +1234,10 @@ packages: brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -1316,9 +1434,19 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fd-package-json@2.0.0: + resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==} + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1328,6 +1456,10 @@ packages: picomatch: optional: true + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + finalhandler@2.1.1: resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} engines: {node: '>= 18.0.0'} @@ -1336,6 +1468,11 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} + formatly@0.3.0: + resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==} + engines: {node: '>=18.3.0'} + hasBin: true + forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -1344,10 +1481,6 @@ packages: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} - fs-fixture@2.11.0: - resolution: {integrity: sha512-elzOu5Ru04qPSBT344kngxx1bpq3RbpznEyjTcn+NHI2nvzwDcGt2zde/a6LBmF5SJtgSYBGHAPnel6S1IefeA==} - engines: {node: '>=18.0.0'} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1371,6 +1504,10 @@ packages: get-tsconfig@4.13.0: resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + glob@10.5.0: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} hasBin: true @@ -1423,13 +1560,25 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + is-node-process@1.2.0: resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} @@ -1465,6 +1614,10 @@ packages: js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -1476,6 +1629,14 @@ packages: json-schema@0.4.0: resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + knip@5.72.0: + resolution: {integrity: sha512-rlyoXI8FcggNtM/QXd/GW0sbsYvNuA/zPXt7bsuVi6kVQogY2PDCr81bPpzNnl0CP8AkFm2Z2plVeL5QQSis2w==} + engines: {node: '>=18.18.0'} + hasBin: true + peerDependencies: + '@types/node': '>=18' + typescript: '>=5.0.4 <7' + lefthook-darwin-arm64@2.0.8: resolution: {integrity: sha512-Nu52qmqhSP+DKKuKYKDkMkPbgvgTZv+ueEo1LVXidTcgxEwvrbe2balcdqdulQTsPfYtm3pCPvv8ikalHrH+Qg==} cpu: [arm64] @@ -1558,6 +1719,14 @@ packages: resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} engines: {node: '>=18'} + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + mime-db@1.54.0: resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} @@ -1570,6 +1739,9 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} @@ -1595,10 +1767,6 @@ packages: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} - nano-spawn@2.0.0: - resolution: {integrity: sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==} - engines: {node: '>=20.17'} - nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -1731,6 +1899,9 @@ packages: outvariant@1.4.3: resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + oxc-resolver@11.15.0: + resolution: {integrity: sha512-Hk2J8QMYwmIO9XTCUiOH00+Xk2/+aBxRUnhrSlANDyCnLYc32R1WSIq1sU2yEdlqd53FfMpPEpnBYIKQMzliJw==} + package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} @@ -1765,6 +1936,10 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + picomatch@4.0.3: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} @@ -1796,6 +1971,9 @@ packages: quansync@0.3.0: resolution: {integrity: sha512-dr5GyvHkdDbrAeXyl0MGi/jWKM6+/lZbNFVe+Ff7ivJi4RVry7O091VfXT/wuAVcF3FwNr86nwZVdxx8nELb2w==} + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -1822,6 +2000,10 @@ packages: rettime@0.7.0: resolution: {integrity: sha512-LPRKoHnLKd/r3dVxcwO7vhCW+orkOGj9ViueosEBK6ie89CijnfRlhaDhHq/3Hxu4CkWQtxwlBG0mzTQY6uQjw==} + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rolldown-plugin-dts@0.17.8: resolution: {integrity: sha512-76EEBlhF00yeY6M7VpMkWKI4r9WjuoMiOGey7j4D6zf3m0BR+ZrrY9hvSXdueJ3ljxSLq4DJBKFpX/X9+L7EKw==} engines: {node: '>=20.19.0'} @@ -1855,6 +2037,9 @@ packages: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} @@ -1909,6 +2094,10 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + smol-toml@1.5.2: + resolution: {integrity: sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ==} + engines: {node: '>= 18'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -1942,6 +2131,10 @@ packages: resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} + strip-json-comments@5.0.3: + resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} + engines: {node: '>=14.16'} + strip-literal@3.1.0: resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} @@ -1990,6 +2183,10 @@ packages: resolution: {integrity: sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==} hasBin: true + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} @@ -2153,6 +2350,10 @@ packages: jsdom: optional: true + walk-up-path@4.0.0: + resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} + engines: {node: 20 || >=22} + webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} @@ -2210,6 +2411,9 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.1.13: + resolution: {integrity: sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==} + snapshots: '@ai-sdk/gateway@2.0.18(zod@3.25.76)': @@ -2219,11 +2423,18 @@ snapshots: '@vercel/oidc': 3.0.5 zod: 3.25.76 - '@ai-sdk/openai@2.0.76(zod@3.25.76)': + '@ai-sdk/gateway@2.0.18(zod@4.1.13)': dependencies: '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.18(zod@3.25.76) - zod: 3.25.76 + '@ai-sdk/provider-utils': 3.0.18(zod@4.1.13) + '@vercel/oidc': 3.0.5 + zod: 4.1.13 + + '@ai-sdk/openai@2.0.76(zod@4.1.13)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.18(zod@4.1.13) + zod: 4.1.13 '@ai-sdk/provider-utils@3.0.18(zod@3.25.76)': dependencies: @@ -2232,6 +2443,13 @@ snapshots: eventsource-parser: 3.0.6 zod: 3.25.76 + '@ai-sdk/provider-utils@3.0.18(zod@4.1.13)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@standard-schema/spec': 1.0.0 + eventsource-parser: 3.0.6 + zod: 4.1.13 + '@ai-sdk/provider@2.0.0': dependencies: json-schema: 0.4.0 @@ -2569,6 +2787,18 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + '@open-draft/deferred-promise@2.2.0': {} '@open-draft/logger@0.3.0': @@ -2584,6 +2814,68 @@ snapshots: '@oxc-project/types@0.95.0': {} + '@oxc-resolver/binding-android-arm-eabi@11.15.0': + optional: true + + '@oxc-resolver/binding-android-arm64@11.15.0': + optional: true + + '@oxc-resolver/binding-darwin-arm64@11.15.0': + optional: true + + '@oxc-resolver/binding-darwin-x64@11.15.0': + optional: true + + '@oxc-resolver/binding-freebsd-x64@11.15.0': + optional: true + + '@oxc-resolver/binding-linux-arm-gnueabihf@11.15.0': + optional: true + + '@oxc-resolver/binding-linux-arm-musleabihf@11.15.0': + optional: true + + '@oxc-resolver/binding-linux-arm64-gnu@11.15.0': + optional: true + + '@oxc-resolver/binding-linux-arm64-musl@11.15.0': + optional: true + + '@oxc-resolver/binding-linux-ppc64-gnu@11.15.0': + optional: true + + '@oxc-resolver/binding-linux-riscv64-gnu@11.15.0': + optional: true + + '@oxc-resolver/binding-linux-riscv64-musl@11.15.0': + optional: true + + '@oxc-resolver/binding-linux-s390x-gnu@11.15.0': + optional: true + + '@oxc-resolver/binding-linux-x64-gnu@11.15.0': + optional: true + + '@oxc-resolver/binding-linux-x64-musl@11.15.0': + optional: true + + '@oxc-resolver/binding-openharmony-arm64@11.15.0': + optional: true + + '@oxc-resolver/binding-wasm32-wasi@11.15.0': + dependencies: + '@napi-rs/wasm-runtime': 1.1.0 + optional: true + + '@oxc-resolver/binding-win32-arm64-msvc@11.15.0': + optional: true + + '@oxc-resolver/binding-win32-ia32-msvc@11.15.0': + optional: true + + '@oxc-resolver/binding-win32-x64-msvc@11.15.0': + optional: true + '@pkgjs/parseargs@0.11.0': optional: true @@ -2839,6 +3131,14 @@ snapshots: '@opentelemetry/api': 1.9.0 zod: 3.25.76 + ai@5.0.106(zod@4.1.13): + dependencies: + '@ai-sdk/gateway': 2.0.18(zod@4.1.13) + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.18(zod@4.1.13) + '@opentelemetry/api': 1.9.0 + zod: 4.1.13 + ajv-formats@3.0.1(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 @@ -2862,6 +3162,8 @@ snapshots: ansis@4.2.0: {} + argparse@2.0.1: {} + assertion-error@2.0.1: {} ast-kit@2.2.0: @@ -2897,6 +3199,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + bytes@3.1.2: {} cac@6.7.14: {} @@ -2972,7 +3278,9 @@ snapshots: diff@8.0.2: {} - dts-resolver@2.1.3: {} + dts-resolver@2.1.3(oxc-resolver@11.15.0): + optionalDependencies: + oxc-resolver: 11.15.0 dunder-proto@1.0.1: dependencies: @@ -3120,12 +3428,32 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-uri@3.1.0: {} + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fd-package-json@2.0.0: + dependencies: + walk-up-path: 4.0.0 + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + finalhandler@2.1.1: dependencies: debug: 4.4.3 @@ -3142,12 +3470,14 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + formatly@0.3.0: + dependencies: + fd-package-json: 2.0.0 + forwarded@0.2.0: {} fresh@2.0.0: {} - fs-fixture@2.11.0: {} - fsevents@2.3.3: optional: true @@ -3177,6 +3507,10 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + glob@10.5.0: dependencies: foreground-child: 3.3.1 @@ -3222,10 +3556,18 @@ snapshots: ipaddr.js@1.9.1: {} + is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + is-node-process@1.2.0: {} + is-number@7.0.0: {} + is-promise@4.0.0: {} isexe@2.0.0: {} @@ -3263,12 +3605,33 @@ snapshots: js-tokens@9.0.1: {} + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + jsesc@3.1.0: {} json-schema-traverse@1.0.0: {} json-schema@0.4.0: {} + knip@5.72.0(@types/node@22.19.1)(typescript@5.9.3): + dependencies: + '@nodelib/fs.walk': 1.2.8 + '@types/node': 22.19.1 + fast-glob: 3.3.3 + formatly: 0.3.0 + jiti: 2.6.1 + js-yaml: 4.1.1 + minimist: 1.2.8 + oxc-resolver: 11.15.0 + picocolors: 1.1.1 + picomatch: 4.0.3 + smol-toml: 1.5.2 + strip-json-comments: 5.0.3 + typescript: 5.9.3 + zod: 4.1.13 + lefthook-darwin-arm64@2.0.8: optional: true @@ -3336,6 +3699,13 @@ snapshots: merge-descriptors@2.0.0: {} + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + mime-db@1.54.0: {} mime-types@3.0.2: @@ -3346,6 +3716,8 @@ snapshots: dependencies: brace-expansion: 2.0.2 + minimist@1.2.8: {} + minipass@7.1.2: {} mri@1.2.0: {} @@ -3379,8 +3751,6 @@ snapshots: mute-stream@2.0.0: {} - nano-spawn@2.0.0: {} - nanoid@3.3.11: {} negotiator@1.0.0: {} @@ -3405,8 +3775,35 @@ snapshots: optionalDependencies: zod: 3.25.76 + openai@6.9.1(zod@4.1.13): + optionalDependencies: + zod: 4.1.13 + outvariant@1.4.3: {} + oxc-resolver@11.15.0: + optionalDependencies: + '@oxc-resolver/binding-android-arm-eabi': 11.15.0 + '@oxc-resolver/binding-android-arm64': 11.15.0 + '@oxc-resolver/binding-darwin-arm64': 11.15.0 + '@oxc-resolver/binding-darwin-x64': 11.15.0 + '@oxc-resolver/binding-freebsd-x64': 11.15.0 + '@oxc-resolver/binding-linux-arm-gnueabihf': 11.15.0 + '@oxc-resolver/binding-linux-arm-musleabihf': 11.15.0 + '@oxc-resolver/binding-linux-arm64-gnu': 11.15.0 + '@oxc-resolver/binding-linux-arm64-musl': 11.15.0 + '@oxc-resolver/binding-linux-ppc64-gnu': 11.15.0 + '@oxc-resolver/binding-linux-riscv64-gnu': 11.15.0 + '@oxc-resolver/binding-linux-riscv64-musl': 11.15.0 + '@oxc-resolver/binding-linux-s390x-gnu': 11.15.0 + '@oxc-resolver/binding-linux-x64-gnu': 11.15.0 + '@oxc-resolver/binding-linux-x64-musl': 11.15.0 + '@oxc-resolver/binding-openharmony-arm64': 11.15.0 + '@oxc-resolver/binding-wasm32-wasi': 11.15.0 + '@oxc-resolver/binding-win32-arm64-msvc': 11.15.0 + '@oxc-resolver/binding-win32-ia32-msvc': 11.15.0 + '@oxc-resolver/binding-win32-x64-msvc': 11.15.0 + package-json-from-dist@1.0.1: {} package-manager-detector@1.6.0: {} @@ -3430,6 +3827,8 @@ snapshots: picocolors@1.1.1: {} + picomatch@2.3.1: {} + picomatch@4.0.3: {} pkce-challenge@5.0.1: {} @@ -3460,6 +3859,8 @@ snapshots: quansync@0.3.0: {} + queue-microtask@1.2.3: {} + range-parser@1.2.1: {} raw-body@3.0.2: @@ -3479,14 +3880,16 @@ snapshots: rettime@0.7.0: {} - rolldown-plugin-dts@0.17.8(@typescript/native-preview@7.0.0-dev.20251202.1)(rolldown@1.0.0-beta.45)(typescript@5.9.3): + reusify@1.1.0: {} + + rolldown-plugin-dts@0.17.8(@typescript/native-preview@7.0.0-dev.20251202.1)(oxc-resolver@11.15.0)(rolldown@1.0.0-beta.45)(typescript@5.9.3): dependencies: '@babel/generator': 7.28.5 '@babel/parser': 7.28.5 '@babel/types': 7.28.5 ast-kit: 2.2.0 birpc: 2.9.0 - dts-resolver: 2.1.3 + dts-resolver: 2.1.3(oxc-resolver@11.15.0) get-tsconfig: 4.13.0 magic-string: 0.30.21 obug: 2.1.1 @@ -3555,6 +3958,10 @@ snapshots: transitivePeerDependencies: - supports-color + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + sade@1.8.1: dependencies: mri: 1.2.0 @@ -3628,6 +4035,8 @@ snapshots: signal-exit@4.1.0: {} + smol-toml@1.5.2: {} + source-map-js@1.2.1: {} stackback@0.0.2: {} @@ -3658,6 +4067,8 @@ snapshots: dependencies: ansi-regex: 6.2.2 + strip-json-comments@5.0.3: {} + strip-literal@3.1.0: dependencies: js-tokens: 9.0.1 @@ -3697,6 +4108,10 @@ snapshots: dependencies: tldts-core: 7.0.19 + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + toidentifier@1.0.1: {} tough-cookie@6.0.0: @@ -3705,7 +4120,7 @@ snapshots: tree-kill@1.2.2: {} - tsdown@0.15.12(@typescript/native-preview@7.0.0-dev.20251202.1)(publint@0.3.15)(typescript@5.9.3)(unplugin-unused@0.5.6): + tsdown@0.15.12(@typescript/native-preview@7.0.0-dev.20251202.1)(oxc-resolver@11.15.0)(publint@0.3.15)(typescript@5.9.3)(unplugin-unused@0.5.6): dependencies: ansis: 4.2.0 cac: 6.7.14 @@ -3715,7 +4130,7 @@ snapshots: empathic: 2.0.0 hookable: 5.5.3 rolldown: 1.0.0-beta.45 - rolldown-plugin-dts: 0.17.8(@typescript/native-preview@7.0.0-dev.20251202.1)(rolldown@1.0.0-beta.45)(typescript@5.9.3) + rolldown-plugin-dts: 0.17.8(@typescript/native-preview@7.0.0-dev.20251202.1)(oxc-resolver@11.15.0)(rolldown@1.0.0-beta.45)(typescript@5.9.3) semver: 7.7.3 tinyexec: 1.0.2 tinyglobby: 0.2.15 @@ -3869,6 +4284,8 @@ snapshots: - tsx - yaml + walk-up-path@4.0.0: {} + webpack-virtual-modules@0.6.2: {} which@2.0.2: @@ -3924,3 +4341,5 @@ snapshots: zod: 3.25.76 zod@3.25.76: {} + + zod@4.1.13: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 621d3073..0353d210 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -14,11 +14,10 @@ catalogs: '@types/node': ^22.13.5 '@typescript/native-preview': ^7.0.0-dev.20251202.1 '@vitest/coverage-v8': ^3.2.4 - fs-fixture: ^2.8.1 hono: ^4.9.10 + knip: ^5.72.0 lefthook: ^2.0.8 msw: ^2.10.4 - nano-spawn: ^2.0.0 publint: ^0.3.12 tsdown: ^0.15.9 type-fest: ^4.41.0 diff --git a/src/rpc-client.ts b/src/rpc-client.ts index 2c5370b9..8607a87b 100644 --- a/src/rpc-client.ts +++ b/src/rpc-client.ts @@ -16,7 +16,7 @@ const rpcActionRequestSchema = z.object({ /** * RPC action request payload */ -export type RpcActionRequest = z.infer; +type RpcActionRequest = z.infer; /** * Zod schema for RPC action response data @@ -44,11 +44,6 @@ const rpcActionResponseSchema = z }) .passthrough(); -/** - * RPC action response data type - can be object, array of objects, or null - */ -export type RpcActionResponseData = z.infer; - /** * RPC action response from the StackOne API * Contains known fields (data, next) plus any additional fields from the connector @@ -69,7 +64,7 @@ const rpcClientConfigSchema = z.object({ /** * Configuration for the RPC client */ -export type RpcClientConfig = z.infer; +type RpcClientConfig = z.infer; /** * Custom RPC client for StackOne API. diff --git a/src/tool.ts b/src/tool.ts index f1a67123..f5ce84cf 100644 --- a/src/tool.ts +++ b/src/tool.ts @@ -520,7 +520,7 @@ async function initializeOramaDb(tools: BaseTool[]): Promise { return oramaDb; } -export function metaSearchTools( +function metaSearchTools( oramaDb: OramaDb, tfidfIndex: TfidfIndex, allTools: BaseTool[], @@ -655,7 +655,7 @@ function clamp01(x: number): number { return x < 0 ? 0 : x > 1 ? 1 : x; } -export function metaExecuteTool(tools: Tools): BaseTool { +function metaExecuteTool(tools: Tools): BaseTool { const name = 'meta_execute_tool' as const; const description = 'Executes a specific tool by name with the provided parameters. Use this after discovering tools with meta_search_tools.' as const; diff --git a/src/toolsets/index.ts b/src/toolsets/index.ts index 4545723f..9a82fac6 100644 --- a/src/toolsets/index.ts +++ b/src/toolsets/index.ts @@ -1,6 +1,5 @@ // Export base toolset types and classes export { - ToolSet, ToolSetConfigError, ToolSetError, ToolSetLoadError, diff --git a/src/toolsets/stackone.ts b/src/toolsets/stackone.ts index d60fcb8b..91597c12 100644 --- a/src/toolsets/stackone.ts +++ b/src/toolsets/stackone.ts @@ -15,7 +15,7 @@ export interface StackOneToolSetConfig extends BaseToolSetConfig { /** * Options for filtering tools when fetching from MCP */ -export interface FetchToolsOptions { +interface FetchToolsOptions { /** * Filter tools by account IDs * Only tools available on these accounts will be returned @@ -40,7 +40,7 @@ export interface FetchToolsOptions { /** * Configuration for workflow */ -export interface WorkflowConfig { +interface WorkflowConfig { key: string; input: string; model: string; diff --git a/src/types.ts b/src/types.ts index f8644f1b..4ab22949 100644 --- a/src/types.ts +++ b/src/types.ts @@ -14,7 +14,7 @@ export type JsonDict = Record; /** * HTTP headers type */ -export type Headers = Record; +type Headers = Record; /** * JSON Schema properties type @@ -24,7 +24,7 @@ export type JsonSchemaProperties = Record; /** * JSON Schema type */ -export type JsonSchemaType = JSONSchema7['type']; +type JsonSchemaType = JSONSchema7['type']; /** * EXPERIMENTAL: Function to override the tool schema at creation time @@ -57,7 +57,7 @@ export type ParameterLocation = ValueOf; /** * Configuration for executing a tool against an API endpoint */ -export interface HttpExecuteParameter { +interface HttpExecuteParameter { name: string; location: ParameterLocation; type: JsonSchemaType; diff --git a/src/utils/file.ts b/src/utils/file.ts deleted file mode 100644 index 253fd728..00000000 --- a/src/utils/file.ts +++ /dev/null @@ -1,133 +0,0 @@ -import fs from 'node:fs'; -import path from 'node:path'; -import { StackOneError } from './errors'; - -/** - * Utilities for handling file operations - */ - -/** - * Check if a string is base64 encoded - */ -export function isBase64(str: string): boolean { - if (typeof str !== 'string') { - return false; - } - - // Check if it's a data URL - if (str.startsWith('data:')) { - return true; - } - - // Check if it's a base64 string - try { - // Regular expression for base64 format - const base64Regex = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/; - return base64Regex.test(str); - } catch (_e) { - return false; - } -} - -/** - * Check if value is a valid file path and the file exists - */ -export function isValidFilePath(filePath: string): boolean { - if (typeof filePath !== 'string' || filePath.startsWith('data:') || isBase64(filePath)) { - return false; - } - - // Check if the file exists - return fs.existsSync(filePath); -} - -/** - * Read a file and return its contents as a base64 string - */ -export function readFileAsBase64(filePath: string): string { - // Check if the file exists - if (!fs.existsSync(filePath)) { - throw new StackOneError(`File not found: ${filePath}`); - } - - // Read the file and convert to base64 - const fileContent = fs.readFileSync(filePath); - return fileContent.toString('base64'); -} - -/** - * Extract information from a file path - */ -export function extractFileInfo(filePath: string): { - fileName: string; - extension: string | null; -} { - // Extract filename from the file path - const fileName = path.basename(filePath); - - // Extract file extension if it exists - let extension = null; - if (fileName.includes('.')) { - extension = fileName.split('.').pop()?.toLowerCase() || null; - } - - return { fileName, extension }; -} - -/** - * Check if a directory exists - */ -export function directoryExists(dirPath: string): boolean { - try { - return fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory(); - } catch (_e) { - return false; - } -} - -/** - * List all files in a directory with an optional filter - */ -export function listFilesInDirectory( - dirPath: string, - filter?: (fileName: string) => boolean -): string[] { - if (!directoryExists(dirPath)) { - return []; - } - - const files = fs.readdirSync(dirPath); - return filter ? files.filter(filter) : files; -} - -/** - * Read and parse a JSON file - */ -export function readJsonFile(filePath: string): T { - if (!isValidFilePath(filePath)) { - throw new StackOneError(`JSON file not found: ${filePath}`); - } - - try { - const content = fs.readFileSync(filePath, 'utf-8'); - return JSON.parse(content) as T; - } catch (error) { - throw new StackOneError('Error parsing JSON file', { cause: error }); - } -} - -/** - * Get the file name without extension - */ -export function getFileNameWithoutExtension(filePath: string): string { - const fileName = path.basename(filePath); - const dotIndex = fileName.lastIndexOf('.'); - return dotIndex === -1 ? fileName : fileName.substring(0, dotIndex); -} - -/** - * Join path segments safely - */ -export function joinPaths(...segments: string[]): string { - return path.join(...segments); -} diff --git a/src/utils/schema.ts b/src/utils/schema.ts deleted file mode 100644 index 5f87a073..00000000 --- a/src/utils/schema.ts +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Safely removes a property from a JSON Schema object - * This function uses type assertions to satisfy both TypeScript type checking - * and linter preferences (using undefined assignment over delete operator) - * - * @param obj The object containing JSON Schema properties - * @param key The key of the property to remove - */ -export const removeJsonSchemaProperty = (obj: Record, key: string): void => { - if (obj && key in obj) { - obj[key] = undefined as unknown as T; - } -}; - -/** - * Creates a new object without the specified property - * This is an alternative to removeJsonSchemaProperty when you want to avoid - * modifying the original object - * - * @param obj The object containing JSON Schema properties - * @param key The key of the property to remove - * @returns A new object without the specified property - */ -export const withoutJsonSchemaProperty = ( - obj: Record, - key: string -): Record => { - if (!obj || !(key in obj)) { - return obj; - } - - // Create a shallow copy of the object - const result: Record = { ...obj }; - - // Remove the property - removeJsonSchemaProperty(result, key); - - return result; -}; diff --git a/src/utils/tfidf-index.ts b/src/utils/tfidf-index.ts index 137cac92..f7a1ee5c 100644 --- a/src/utils/tfidf-index.ts +++ b/src/utils/tfidf-index.ts @@ -4,12 +4,12 @@ * strips punctuation, removes a small stopword set, and builds a sparse index. */ -export interface TfidfDocument { +interface TfidfDocument { id: string; text: string; } -export interface TfidfResult { +interface TfidfResult { id: string; score: number; // cosine similarity (0..1) }